diff options
Diffstat (limited to 'block')
-rw-r--r-- | block/bsg.c | 14 | ||||
-rw-r--r-- | block/ll_rw_blk.c | 24 |
2 files changed, 36 insertions, 2 deletions
diff --git a/block/bsg.c b/block/bsg.c index 8e181ab3afb..69b0a9d3330 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, 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); @@ -837,6 +846,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) { /* @@ -889,12 +899,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 diff --git a/block/ll_rw_blk.c b/block/ll_rw_blk.c index 5ccec8aa964..3d0422f4845 100644 --- a/block/ll_rw_blk.c +++ b/block/ll_rw_blk.c @@ -760,6 +760,30 @@ void blk_queue_dma_alignment(struct request_queue *q, int mask) EXPORT_SYMBOL(blk_queue_dma_alignment); /** + * blk_queue_update_dma_alignment - update dma length and memory alignment + * @q: the request queue for the device + * @mask: alignment mask + * + * description: + * update required memory and length aligment for direct dma transactions. + * If the requested alignment is larger than the current alignment, then + * the current queue alignment is updated to the new value, otherwise it + * is left alone. The design of this is to allow multiple objects + * (driver, device, transport etc) to set their respective + * alignments without having them interfere. + * + **/ +void blk_queue_update_dma_alignment(struct request_queue *q, int mask) +{ + BUG_ON(mask > PAGE_SIZE); + + if (mask > q->dma_alignment) + q->dma_alignment = mask; +} + +EXPORT_SYMBOL(blk_queue_update_dma_alignment); + +/** * blk_queue_find_tag - find a request by its tag and queue * @q: The request queue for the device * @tag: The tag of the request |