aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Bottomley <James.Bottomley@HansenPartnership.com>2007-12-29 11:59:53 -0500
committerJames Bottomley <James.Bottomley@HansenPartnership.com>2008-01-11 19:29:13 -0500
commit2d507a01dac338831266b44ccbb01c69e84606ed (patch)
treeec59ce6bc1ec86e93d1683107d41b5dbce0b370a
parent2d4b63e1505b317d4253cee3f2970792ec6d41cb (diff)
[SCSI] libsas, bsg: pass errors through correctly
Currently in BSG, errors returned in req->errors aren't passed back to the calling programme (either via SG_IO or via read/write). Fix this, while preserving the SCSI convention of returning status in req->errors. Now update libsas to return errors correctly instead of to ignore them. Acked-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
-rw-r--r--block/bsg.c14
-rw-r--r--drivers/scsi/scsi_transport_sas.c1
2 files changed, 13 insertions, 2 deletions
diff --git a/block/bsg.c b/block/bsg.c
index 8e181ab3afb9..69b0a9d33306 100644
--- a/block/bsg.c
+++ b/block/bsg.c
@@ -445,6 +445,15 @@ static int blk_complete_sgv4_hdr_rq(struct request *rq, struct sg_io_v4 *hdr,
445 else 445 else
446 hdr->dout_resid = rq->data_len; 446 hdr->dout_resid = rq->data_len;
447 447
448 /*
449 * If the request generated a negative error number, return it
450 * (providing we aren't already returning an error); if it's
451 * just a protocol response (i.e. non negative), that gets
452 * processed above.
453 */
454 if (!ret && rq->errors < 0)
455 ret = rq->errors;
456
448 blk_rq_unmap_user(bio); 457 blk_rq_unmap_user(bio);
449 blk_put_request(rq); 458 blk_put_request(rq);
450 459
@@ -837,6 +846,7 @@ static long bsg_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
837{ 846{
838 struct bsg_device *bd = file->private_data; 847 struct bsg_device *bd = file->private_data;
839 int __user *uarg = (int __user *) arg; 848 int __user *uarg = (int __user *) arg;
849 int ret;
840 850
841 switch (cmd) { 851 switch (cmd) {
842 /* 852 /*
@@ -889,12 +899,12 @@ static long bsg_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
889 if (rq->next_rq) 899 if (rq->next_rq)
890 bidi_bio = rq->next_rq->bio; 900 bidi_bio = rq->next_rq->bio;
891 blk_execute_rq(bd->queue, NULL, rq, 0); 901 blk_execute_rq(bd->queue, NULL, rq, 0);
892 blk_complete_sgv4_hdr_rq(rq, &hdr, bio, bidi_bio); 902 ret = blk_complete_sgv4_hdr_rq(rq, &hdr, bio, bidi_bio);
893 903
894 if (copy_to_user(uarg, &hdr, sizeof(hdr))) 904 if (copy_to_user(uarg, &hdr, sizeof(hdr)))
895 return -EFAULT; 905 return -EFAULT;
896 906
897 return 0; 907 return ret;
898 } 908 }
899 /* 909 /*
900 * block device ioctls 910 * block device ioctls
diff --git a/drivers/scsi/scsi_transport_sas.c b/drivers/scsi/scsi_transport_sas.c
index 87e786daa713..f2149d0bb999 100644
--- a/drivers/scsi/scsi_transport_sas.c
+++ b/drivers/scsi/scsi_transport_sas.c
@@ -173,6 +173,7 @@ static void sas_smp_request(struct request_queue *q, struct Scsi_Host *shost,
173 173
174 handler = to_sas_internal(shost->transportt)->f->smp_handler; 174 handler = to_sas_internal(shost->transportt)->f->smp_handler;
175 ret = handler(shost, rphy, req); 175 ret = handler(shost, rphy, req);
176 req->errors = ret;
176 177
177 spin_lock_irq(q->queue_lock); 178 spin_lock_irq(q->queue_lock);
178 179