diff options
| author | James Bottomley <jejb@mulgrave.(none)> | 2004-12-23 01:01:49 -0600 |
|---|---|---|
| committer | James Bottomley <jejb@mulgrave.(none)> | 2004-12-23 01:01:49 -0600 |
| commit | f5cf12230f9b850ef9d74bba6edefc734fe4f232 (patch) | |
| tree | b68317bbf4b1a73e5431b2f25644b662a1ac5b79 /include | |
| parent | 3e54f826a3c33510595ac9153f103508a3a6ce6b (diff) | |
SCSI: add queue_type entry in sysfs
This adds an extra attribute to tell you what type of queueing the
driver is using: none, simple or ordered. If the driver supplies the
change_queue_type API, you can also alter this (which would allow the
turning on or off of TCQ).
I also fixed the change_queue_depth not to allow the user to go below
one.
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'include')
| -rw-r--r-- | include/scsi/scsi_host.h | 14 | ||||
| -rw-r--r-- | include/scsi/scsi_tcq.h | 52 |
2 files changed, 58 insertions, 8 deletions
diff --git a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h index 59c7e45d3409..a22a274fbd7a 100644 --- a/include/scsi/scsi_host.h +++ b/include/scsi/scsi_host.h @@ -228,13 +228,23 @@ struct scsi_host_template { int (* change_queue_depth)(struct scsi_device *, int); /* + * fill in this function to allow the changing of tag types + * (this also allows the enabling/disabling of tag command + * queueing). An error should only be returned if something + * went wrong in the driver while trying to set the tag type. + * If the driver doesn't support the requested tag type, then + * it should set the closest type it does support without + * returning an error. Returns the actual tag type set. + */ + int (* change_queue_type)(struct scsi_device *, int); + + /* * This function determines the bios parameters for a given * harddisk. These tend to be numbers that are made up by * the host adapter. Parameters: * size, device, list (heads, sectors, cylinders) * - * Status: OPTIONAL - */ + * Status: OPTIONAL */ int (* bios_param)(struct scsi_device *, struct block_device *, sector_t, int []); diff --git a/include/scsi/scsi_tcq.h b/include/scsi/scsi_tcq.h index 78039d0f1a57..e47e36a4ef49 100644 --- a/include/scsi/scsi_tcq.h +++ b/include/scsi/scsi_tcq.h @@ -13,6 +13,43 @@ #define SCSI_NO_TAG (-1) /* identify no tag in use */ + +/** + * scsi_get_tag_type - get the type of tag the device supports + * @sdev: the scsi device + * + * Notes: + * If the drive only supports simple tags, returns MSG_SIMPLE_TAG + * if it supports all tag types, returns MSG_ORDERED_TAG. + */ +static inline int scsi_get_tag_type(struct scsi_device *sdev) +{ + if (!sdev->tagged_supported) + return 0; + if (sdev->ordered_tags) + return MSG_ORDERED_TAG; + if (sdev->simple_tags) + return MSG_SIMPLE_TAG; + return 0; +} + +static inline void scsi_set_tag_type(struct scsi_device *sdev, int tag) +{ + switch (tag) { + case MSG_ORDERED_TAG: + sdev->ordered_tags = 1; + /* fall through */ + case MSG_SIMPLE_TAG: + sdev->simple_tags = 1; + break; + case 0: + /* fall through */ + default: + sdev->ordered_tags = 0; + sdev->simple_tags = 0; + break; + } +} /** * scsi_activate_tcq - turn on tag command queueing * @SDpnt: device to turn on TCQ for @@ -25,11 +62,13 @@ **/ static inline void scsi_activate_tcq(struct scsi_device *sdev, int depth) { - if (sdev->tagged_supported) { - if (!blk_queue_tagged(sdev->request_queue)) - blk_queue_init_tags(sdev->request_queue, depth, NULL); - scsi_adjust_queue_depth(sdev, MSG_ORDERED_TAG, depth); - } + if (!sdev->tagged_supported) + return; + + if (!blk_queue_tagged(sdev->request_queue)) + blk_queue_init_tags(sdev->request_queue, depth, NULL); + + scsi_adjust_queue_depth(sdev, scsi_get_tag_type(sdev), depth); } /** @@ -56,9 +95,10 @@ static inline void scsi_deactivate_tcq(struct scsi_device *sdev, int depth) static inline int scsi_populate_tag_msg(struct scsi_cmnd *cmd, char *msg) { struct request *req = cmd->request; + struct scsi_device *sdev = cmd->device; if (blk_rq_tagged(req)) { - if (req->flags & REQ_HARDBARRIER) + if (sdev->ordered_tags && req->flags & REQ_HARDBARRIER) *msg++ = MSG_ORDERED_TAG; else *msg++ = MSG_SIMPLE_TAG; |
