ia64: Fix resource assignment for root busses
[safe/jmp/linux-2.6] / block / scsi_ioctl.c
index ee9c67d..5f8e798 100644 (file)
@@ -75,7 +75,7 @@ static int sg_set_timeout(struct request_queue *q, int __user *p)
 
 static int sg_get_reserved_size(struct request_queue *q, int __user *p)
 {
-       unsigned val = min(q->sg_reserved_size, q->max_sectors << 9);
+       unsigned val = min(q->sg_reserved_size, queue_max_sectors(q) << 9);
 
        return put_user(val, p);
 }
@@ -89,8 +89,8 @@ static int sg_set_reserved_size(struct request_queue *q, int __user *p)
 
        if (size < 0)
                return -EINVAL;
-       if (size > (q->max_sectors << 9))
-               size = q->max_sectors << 9;
+       if (size > (queue_max_sectors(q) << 9))
+               size = queue_max_sectors(q) << 9;
 
        q->sg_reserved_size = size;
        return 0;
@@ -214,17 +214,6 @@ static int blk_fill_sghdr_rq(struct request_queue *q, struct request *rq,
        return 0;
 }
 
-/*
- * unmap a request that was previously mapped to this sg_io_hdr. handles
- * both sg and non-sg sg_io_hdr.
- */
-static int blk_unmap_sghdr_rq(struct request *rq, struct sg_io_hdr *hdr)
-{
-       blk_rq_unmap_user(rq->bio);
-       blk_put_request(rq);
-       return 0;
-}
-
 static int blk_complete_sghdr_rq(struct request *rq, struct sg_io_hdr *hdr,
                                 struct bio *bio)
 {
@@ -241,7 +230,7 @@ static int blk_complete_sghdr_rq(struct request *rq, struct sg_io_hdr *hdr,
        hdr->info = 0;
        if (hdr->masked_status || hdr->host_status || hdr->driver_status)
                hdr->info |= SG_INFO_CHECK;
-       hdr->resid = rq->data_len;
+       hdr->resid = rq->resid_len;
        hdr->sb_len_wr = 0;
 
        if (rq->sense_len && hdr->sbp) {
@@ -253,12 +242,12 @@ static int blk_complete_sghdr_rq(struct request *rq, struct sg_io_hdr *hdr,
                        ret = -EFAULT;
        }
 
-       rq->bio = bio;
-       r = blk_unmap_sghdr_rq(rq, hdr);
-       if (ret)
-               r = ret;
+       r = blk_rq_unmap_user(bio);
+       if (!ret)
+               ret = r;
+       blk_put_request(rq);
 
-       return r;
+       return ret;
 }
 
 static int sg_io(struct request_queue *q, struct gendisk *bd_disk,
@@ -275,7 +264,7 @@ static int sg_io(struct request_queue *q, struct gendisk *bd_disk,
        if (hdr->cmd_len > BLK_MAX_CDB)
                return -EINVAL;
 
-       if (hdr->dxfer_len > (q->max_hw_sectors << 9))
+       if (hdr->dxfer_len > (queue_max_hw_sectors(q) << 9))
                return -EIO;
 
        if (hdr->dxfer_len)
@@ -301,6 +290,7 @@ static int sg_io(struct request_queue *q, struct gendisk *bd_disk,
 
        if (hdr->iovec_count) {
                const int size = sizeof(struct sg_iovec) * hdr->iovec_count;
+               size_t iov_data_len;
                struct sg_iovec *iov;
 
                iov = kmalloc(size, GFP_KERNEL);
@@ -315,8 +305,18 @@ static int sg_io(struct request_queue *q, struct gendisk *bd_disk,
                        goto out;
                }
 
+               /* SG_IO howto says that the shorter of the two wins */
+               iov_data_len = iov_length((struct iovec *)iov,
+                                         hdr->iovec_count);
+               if (hdr->dxfer_len < iov_data_len) {
+                       hdr->iovec_count = iov_shorten((struct iovec *)iov,
+                                                      hdr->iovec_count,
+                                                      hdr->dxfer_len);
+                       iov_data_len = hdr->dxfer_len;
+               }
+
                ret = blk_rq_map_user_iov(q, rq, NULL, iov, hdr->iovec_count,
-                                         hdr->dxfer_len, GFP_KERNEL);
+                                         iov_data_len, GFP_KERNEL);
                kfree(iov);
        } else if (hdr->dxfer_len)
                ret = blk_rq_map_user(q, rq, NULL, hdr->dxferp, hdr->dxfer_len,
@@ -500,9 +500,6 @@ static int __blk_send_generic(struct request_queue *q, struct gendisk *bd_disk,
 
        rq = blk_get_request(q, WRITE, __GFP_WAIT);
        rq->cmd_type = REQ_TYPE_BLOCK_PC;
-       rq->data = NULL;
-       rq->data_len = 0;
-       rq->extra_len = 0;
        rq->timeout = BLK_DEFAULT_SG_TIMEOUT;
        rq->cmd[0] = cmd;
        rq->cmd[4] = data;