Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v3.14 175 lines 4.2 kB view raw
1#ifndef _SCSI_SCSI_TCQ_H 2#define _SCSI_SCSI_TCQ_H 3 4#include <linux/blkdev.h> 5#include <scsi/scsi_cmnd.h> 6#include <scsi/scsi_device.h> 7#include <scsi/scsi_host.h> 8 9#define MSG_SIMPLE_TAG 0x20 10#define MSG_HEAD_TAG 0x21 11#define MSG_ORDERED_TAG 0x22 12#define MSG_ACA_TAG 0x24 /* unsupported */ 13 14#define SCSI_NO_TAG (-1) /* identify no tag in use */ 15 16 17#ifdef CONFIG_BLOCK 18 19/** 20 * scsi_get_tag_type - get the type of tag the device supports 21 * @sdev: the scsi device 22 * 23 * Notes: 24 * If the drive only supports simple tags, returns MSG_SIMPLE_TAG 25 * if it supports all tag types, returns MSG_ORDERED_TAG. 26 */ 27static inline int scsi_get_tag_type(struct scsi_device *sdev) 28{ 29 if (!sdev->tagged_supported) 30 return 0; 31 if (sdev->ordered_tags) 32 return MSG_ORDERED_TAG; 33 if (sdev->simple_tags) 34 return MSG_SIMPLE_TAG; 35 return 0; 36} 37 38static inline void scsi_set_tag_type(struct scsi_device *sdev, int tag) 39{ 40 switch (tag) { 41 case MSG_ORDERED_TAG: 42 sdev->ordered_tags = 1; 43 /* fall through */ 44 case MSG_SIMPLE_TAG: 45 sdev->simple_tags = 1; 46 break; 47 case 0: 48 /* fall through */ 49 default: 50 sdev->ordered_tags = 0; 51 sdev->simple_tags = 0; 52 break; 53 } 54} 55/** 56 * scsi_activate_tcq - turn on tag command queueing 57 * @SDpnt: device to turn on TCQ for 58 * @depth: queue depth 59 * 60 * Notes: 61 * Eventually, I hope depth would be the maximum depth 62 * the device could cope with and the real queue depth 63 * would be adjustable from 0 to depth. 64 **/ 65static inline void scsi_activate_tcq(struct scsi_device *sdev, int depth) 66{ 67 if (!sdev->tagged_supported) 68 return; 69 70 if (!blk_queue_tagged(sdev->request_queue)) 71 blk_queue_init_tags(sdev->request_queue, depth, 72 sdev->host->bqt); 73 74 scsi_adjust_queue_depth(sdev, scsi_get_tag_type(sdev), depth); 75} 76 77/** 78 * scsi_deactivate_tcq - turn off tag command queueing 79 * @SDpnt: device to turn off TCQ for 80 **/ 81static inline void scsi_deactivate_tcq(struct scsi_device *sdev, int depth) 82{ 83 if (blk_queue_tagged(sdev->request_queue)) 84 blk_queue_free_tags(sdev->request_queue); 85 scsi_adjust_queue_depth(sdev, 0, depth); 86} 87 88/** 89 * scsi_populate_tag_msg - place a tag message in a buffer 90 * @SCpnt: pointer to the Scsi_Cmnd for the tag 91 * @msg: pointer to the area to place the tag 92 * 93 * Notes: 94 * designed to create the correct type of tag message for the 95 * particular request. Returns the size of the tag message. 96 * May return 0 if TCQ is disabled for this device. 97 **/ 98static inline int scsi_populate_tag_msg(struct scsi_cmnd *cmd, char *msg) 99{ 100 struct request *req = cmd->request; 101 102 if (blk_rq_tagged(req)) { 103 *msg++ = MSG_SIMPLE_TAG; 104 *msg++ = req->tag; 105 return 2; 106 } 107 108 return 0; 109} 110 111/** 112 * scsi_find_tag - find a tagged command by device 113 * @SDpnt: pointer to the ScSI device 114 * @tag: the tag number 115 * 116 * Notes: 117 * Only works with tags allocated by the generic blk layer. 118 **/ 119static inline struct scsi_cmnd *scsi_find_tag(struct scsi_device *sdev, int tag) 120{ 121 122 struct request *req; 123 124 if (tag != SCSI_NO_TAG) { 125 req = blk_queue_find_tag(sdev->request_queue, tag); 126 return req ? (struct scsi_cmnd *)req->special : NULL; 127 } 128 129 /* single command, look in space */ 130 return sdev->current_cmnd; 131} 132 133/** 134 * scsi_init_shared_tag_map - create a shared tag map 135 * @shost: the host to share the tag map among all devices 136 * @depth: the total depth of the map 137 */ 138static inline int scsi_init_shared_tag_map(struct Scsi_Host *shost, int depth) 139{ 140 /* 141 * If the shared tag map isn't already initialized, do it now. 142 * This saves callers from having to check ->bqt when setting up 143 * devices on the shared host (for libata) 144 */ 145 if (!shost->bqt) { 146 shost->bqt = blk_init_tags(depth); 147 if (!shost->bqt) 148 return -ENOMEM; 149 } 150 151 return 0; 152} 153 154/** 155 * scsi_host_find_tag - find the tagged command by host 156 * @shost: pointer to scsi_host 157 * @tag: tag of the scsi_cmnd 158 * 159 * Notes: 160 * Only works with tags allocated by the generic blk layer. 161 **/ 162static inline struct scsi_cmnd *scsi_host_find_tag(struct Scsi_Host *shost, 163 int tag) 164{ 165 struct request *req; 166 167 if (tag != SCSI_NO_TAG) { 168 req = blk_map_queue_find_tag(shost->bqt, tag); 169 return req ? (struct scsi_cmnd *)req->special : NULL; 170 } 171 return NULL; 172} 173 174#endif /* CONFIG_BLOCK */ 175#endif /* _SCSI_SCSI_TCQ_H */