Commit 2d507a01 authored by James Bottomley's avatar James Bottomley

[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: default avatarFUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@HansenPartnership.com>
parent 2d4b63e1
...@@ -445,6 +445,15 @@ static int blk_complete_sgv4_hdr_rq(struct request *rq, struct sg_io_v4 *hdr, ...@@ -445,6 +445,15 @@ static int blk_complete_sgv4_hdr_rq(struct request *rq, struct sg_io_v4 *hdr,
else else
hdr->dout_resid = rq->data_len; hdr->dout_resid = rq->data_len;
/*
* If the request generated a negative error number, return it
* (providing we aren't already returning an error); if it's
* just a protocol response (i.e. non negative), that gets
* processed above.
*/
if (!ret && rq->errors < 0)
ret = rq->errors;
blk_rq_unmap_user(bio); blk_rq_unmap_user(bio);
blk_put_request(rq); blk_put_request(rq);
...@@ -837,6 +846,7 @@ static long bsg_ioctl(struct file *file, unsigned int cmd, unsigned long arg) ...@@ -837,6 +846,7 @@ static long bsg_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{ {
struct bsg_device *bd = file->private_data; struct bsg_device *bd = file->private_data;
int __user *uarg = (int __user *) arg; int __user *uarg = (int __user *) arg;
int ret;
switch (cmd) { switch (cmd) {
/* /*
...@@ -889,12 +899,12 @@ static long bsg_ioctl(struct file *file, unsigned int cmd, unsigned long arg) ...@@ -889,12 +899,12 @@ static long bsg_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
if (rq->next_rq) if (rq->next_rq)
bidi_bio = rq->next_rq->bio; bidi_bio = rq->next_rq->bio;
blk_execute_rq(bd->queue, NULL, rq, 0); blk_execute_rq(bd->queue, NULL, rq, 0);
blk_complete_sgv4_hdr_rq(rq, &hdr, bio, bidi_bio); ret = blk_complete_sgv4_hdr_rq(rq, &hdr, bio, bidi_bio);
if (copy_to_user(uarg, &hdr, sizeof(hdr))) if (copy_to_user(uarg, &hdr, sizeof(hdr)))
return -EFAULT; return -EFAULT;
return 0; return ret;
} }
/* /*
* block device ioctls * block device ioctls
......
...@@ -173,6 +173,7 @@ static void sas_smp_request(struct request_queue *q, struct Scsi_Host *shost, ...@@ -173,6 +173,7 @@ static void sas_smp_request(struct request_queue *q, struct Scsi_Host *shost,
handler = to_sas_internal(shost->transportt)->f->smp_handler; handler = to_sas_internal(shost->transportt)->f->smp_handler;
ret = handler(shost, rphy, req); ret = handler(shost, rphy, req);
req->errors = ret;
spin_lock_irq(q->queue_lock); spin_lock_irq(q->queue_lock);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment