summaryrefslogtreecommitdiff
path: root/drivers/scsi/sg.c
diff options
context:
space:
mode:
authorDouglas Gilbert <dgilbert@interlog.com>2014-06-04 18:58:30 +0400
committerChristoph Hellwig <hch@lst.de>2014-07-18 00:07:34 +0400
commit16070cc189c5e343696c29c8cff779e692cfcb8d (patch)
tree00edc84093c62557235b118fe8e3e28441c07dce /drivers/scsi/sg.c
parent65c26a0f39695ba01d9693754f27ca76cc8a3ab5 (diff)
downloadlinux-16070cc189c5e343696c29c8cff779e692cfcb8d.tar.xz
sg: add SG_FLAG_Q_AT_TAIL flag
When the SG_IO ioctl was copied into the block layer and later into the bsg driver, subtle differences emerged. One difference is the way injected commands are queued through the block layer (i.e. this is not SCSI device queueing nor SATA NCQ). Summarizing: - SG_IO in the block layer: blk_exec*(at_head=false) - sg SG_IO: at_head=true - bsg SG_IO: at_head=true Some time ago Boaz Harrosh introduced a sg v4 flag called BSG_FLAG_Q_AT_TAIL to override the bsg driver default. This patch does the equivalent for the sg driver. ChangeLog: Introduce SG_FLAG_Q_AT_TAIL flag to cause commands to be injected into the block layer with at_head=false. Signed-off-by: Douglas Gilbert <dgilbert@interlog.com> Reviewed-by: Mike Christie <michaelc@cs.wisc.edu> Reviewed-by: Ewan D. Milne <emilne@redhat.com> Signed-off-by: Christoph Hellwig <hch@lst.de>
Diffstat (limited to 'drivers/scsi/sg.c')
-rw-r--r--drivers/scsi/sg.c9
1 files changed, 7 insertions, 2 deletions
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
index 37fb44b0074b..32425ac61096 100644
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -741,7 +741,7 @@ static int
sg_common_write(Sg_fd * sfp, Sg_request * srp,
unsigned char *cmnd, int timeout, int blocking)
{
- int k, data_dir;
+ int k, data_dir, at_head;
Sg_device *sdp = sfp->parentdp;
sg_io_hdr_t *hp = &srp->header;
@@ -785,11 +785,16 @@ sg_common_write(Sg_fd * sfp, Sg_request * srp,
break;
}
hp->duration = jiffies_to_msecs(jiffies);
+ if (hp->interface_id != '\0' && /* v3 (or later) interface */
+ (SG_FLAG_Q_AT_TAIL & hp->flags))
+ at_head = 0;
+ else
+ at_head = 1;
srp->rq->timeout = timeout;
kref_get(&sfp->f_ref); /* sg_rq_end_io() does kref_put(). */
blk_execute_rq_nowait(sdp->device->request_queue, sdp->disk,
- srp->rq, 1, sg_rq_end_io);
+ srp->rq, at_head, sg_rq_end_io);
return 0;
}