X-Git-Url: http://ftp.safe.ca/?a=blobdiff_plain;f=block%2Fbsg.c;h=8917c5174dc2646c5ad8d4d67eb67529a98783f5;hb=bcc5c7d2b692e5319db00b0dd020ce98723103b1;hp=d60eee54940554f9c168c22c7a722900be84595b;hpb=a6ce22a5f61ba838b43763bf1e5be399f9dee4d0;p=safe%2Fjmp%2Flinux-2.6 diff --git a/block/bsg.c b/block/bsg.c index d60eee5..8917c51 100644 --- a/block/bsg.c +++ b/block/bsg.c @@ -1,5 +1,5 @@ /* - * bsg.c - block layer implementation of the sg v3 interface + * bsg.c - block layer implementation of the sg v4 interface * * Copyright (C) 2004 Jens Axboe SUSE Labs * Copyright (C) 2004 Peter M. Jones @@ -279,6 +279,7 @@ bsg_map_hdr(struct bsg_device *bd, struct sg_io_v4 *hdr) goto out; } rq->next_rq = next_rq; + next_rq->cmd_type = rq->cmd_type; dxferp = (void*)(unsigned long)hdr->din_xferp; ret = blk_rq_map_user(q, next_rq, dxferp, hdr->din_xfer_len); @@ -421,7 +422,6 @@ static int blk_complete_sgv4_hdr_rq(struct request *rq, struct sg_io_v4 *hdr, hdr->info = 0; if (hdr->device_status || hdr->transport_status || hdr->driver_status) hdr->info |= SG_INFO_CHECK; - hdr->din_resid = rq->data_len; hdr->response_len = 0; if (rq->sense_len && hdr->response) { @@ -437,9 +437,23 @@ static int blk_complete_sgv4_hdr_rq(struct request *rq, struct sg_io_v4 *hdr, } if (rq->next_rq) { + hdr->dout_resid = rq->data_len; + hdr->din_resid = rq->next_rq->data_len; blk_rq_unmap_user(bidi_bio); blk_put_request(rq->next_rq); - } + } else if (rq_data_dir(rq) == READ) + hdr->din_resid = rq->data_len; + else + 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_put_request(rq); @@ -833,6 +847,7 @@ static long bsg_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { struct bsg_device *bd = file->private_data; int __user *uarg = (int __user *) arg; + int ret; switch (cmd) { /* @@ -885,12 +900,12 @@ static long bsg_ioctl(struct file *file, unsigned int cmd, unsigned long arg) if (rq->next_rq) bidi_bio = rq->next_rq->bio; 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))) return -EFAULT; - return 0; + return ret; } /* * block device ioctls @@ -904,7 +919,7 @@ static long bsg_ioctl(struct file *file, unsigned int cmd, unsigned long arg) } } -static struct file_operations bsg_fops = { +static const struct file_operations bsg_fops = { .read = bsg_read, .write = bsg_write, .poll = bsg_poll, @@ -1006,10 +1021,7 @@ unlock: } EXPORT_SYMBOL_GPL(bsg_register_queue); -static struct cdev bsg_cdev = { - .kobj = {.name = "bsg", }, - .owner = THIS_MODULE, -}; +static struct cdev bsg_cdev; static int __init bsg_init(void) {