]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/scsi/sg.c
sg: remove unnecessary blk_rq_unmap_user
[linux-2.6-omap-h63xx.git] / drivers / scsi / sg.c
index 9a56c0d320bfcfb0c8055e66e45ec85940fa39fd..ba9b9bbd4e7385e8d83f3ed4f4a1151b96ab3a1f 100644 (file)
@@ -188,8 +188,6 @@ static ssize_t sg_new_write(Sg_fd *sfp, struct file *file,
                        int read_only, Sg_request **o_srp);
 static int sg_common_write(Sg_fd * sfp, Sg_request * srp,
                           unsigned char *cmnd, int timeout, int blocking);
-static int sg_write_xfer(Sg_request * srp);
-static int sg_read_xfer(Sg_request * srp);
 static int sg_read_oxfer(Sg_request * srp, char __user *outp, int num_read_xfer);
 static void sg_remove_scat(Sg_scatter_hold * schp);
 static void sg_build_reserve(Sg_fd * sfp, int req_size);
@@ -202,7 +200,6 @@ static Sg_request *sg_get_rq_mark(Sg_fd * sfp, int pack_id);
 static Sg_request *sg_add_request(Sg_fd * sfp);
 static int sg_remove_request(Sg_fd * sfp, Sg_request * srp);
 static int sg_res_in_use(Sg_fd * sfp);
-static int sg_build_direct(Sg_request * srp, Sg_fd * sfp, int dxfer_len);
 static Sg_device *sg_get_dev(int dev);
 #ifdef CONFIG_SCSI_PROC_FS
 static int sg_last_dev(void);
@@ -525,8 +522,7 @@ sg_new_read(Sg_fd * sfp, char __user *buf, size_t count, Sg_request * srp)
                err = -EFAULT;
                goto err_out;
        }
-       err = sg_read_xfer(srp);
-      err_out:
+err_out:
        sg_finish_rem_req(srp);
        return (0 == err) ? count : err;
 }
@@ -737,11 +733,6 @@ sg_common_write(Sg_fd * sfp, Sg_request * srp,
                sg_finish_rem_req(srp);
                return k;       /* probably out of space --> ENOMEM */
        }
-       if ((k = sg_write_xfer(srp))) {
-               SCSI_LOG_TIMEOUT(1, printk("sg_common_write: write_xfer, bad address\n"));
-               sg_finish_rem_req(srp);
-               return k;
-       }
        if (sdp->detached) {
                sg_finish_rem_req(srp);
                return -ENODEV;
@@ -1628,16 +1619,17 @@ exit_sg(void)
 
 static int sg_start_req(Sg_request *srp, unsigned char *cmd)
 {
-       int res = 0;
+       int res;
        struct request *rq;
        Sg_fd *sfp = srp->parentfp;
        sg_io_hdr_t *hp = &srp->header;
        int dxfer_len = (int) hp->dxfer_len;
        int dxfer_dir = hp->dxfer_direction;
+       unsigned int iov_count = hp->iovec_count;
        Sg_scatter_hold *req_schp = &srp->data;
        Sg_scatter_hold *rsv_schp = &sfp->reserve;
        struct request_queue *q = sfp->parentdp->device->request_queue;
-       struct rq_map_data map_data;
+       struct rq_map_data *md, map_data;
        int rw = hp->dxfer_direction == SG_DXFER_TO_DEV ? WRITE : READ;
 
        SCSI_LOG_TIMEOUT(4, printk(KERN_INFO "sg_start_req: dxfer_len=%d\n",
@@ -1660,38 +1652,43 @@ static int sg_start_req(Sg_request *srp, unsigned char *cmd)
        if ((dxfer_len <= 0) || (dxfer_dir == SG_DXFER_NONE))
                return 0;
 
-       if (sg_allow_dio && (hp->flags & SG_FLAG_DIRECT_IO) &&
-           (dxfer_dir != SG_DXFER_UNKNOWN) && (0 == hp->iovec_count) &&
-           (!sfp->parentdp->device->host->unchecked_isa_dma) &&
+       if (sg_allow_dio && hp->flags & SG_FLAG_DIRECT_IO &&
+           dxfer_dir != SG_DXFER_UNKNOWN && !iov_count &&
+           !sfp->parentdp->device->host->unchecked_isa_dma &&
            blk_rq_aligned(q, hp->dxferp, dxfer_len))
-               return sg_build_direct(srp, sfp, dxfer_len);
+               md = NULL;
+       else
+               md = &map_data;
 
-       if ((!sg_res_in_use(sfp)) && (dxfer_len <= rsv_schp->bufflen))
-               sg_link_reserve(sfp, srp, dxfer_len);
+       if (md) {
+               if (!sg_res_in_use(sfp) && dxfer_len <= rsv_schp->bufflen)
+                       sg_link_reserve(sfp, srp, dxfer_len);
+               else {
+                       res = sg_build_indirect(req_schp, sfp, dxfer_len);
+                       if (res)
+                               return res;
+               }
+
+               md->pages = req_schp->pages;
+               md->page_order = req_schp->page_order;
+               md->nr_entries = req_schp->k_use_sg;
+       }
+
+       if (iov_count)
+               res = blk_rq_map_user_iov(q, rq, md, hp->dxferp, iov_count,
+                                         hp->dxfer_len, GFP_ATOMIC);
        else
-               res = sg_build_indirect(req_schp, sfp, dxfer_len);
+               res = blk_rq_map_user(q, rq, md, hp->dxferp,
+                                     hp->dxfer_len, GFP_ATOMIC);
 
        if (!res) {
-               struct request *rq = srp->rq;
-               Sg_scatter_hold *schp = &srp->data;
-               int iovec_count = (int) hp->iovec_count;
-
-               map_data.pages = schp->pages;
-               map_data.page_order = schp->page_order;
-               map_data.nr_entries = schp->k_use_sg;
-
-               if (iovec_count)
-                       res = blk_rq_map_user_iov(q, rq, &map_data, hp->dxferp,
-                                                 iovec_count,
-                                                 hp->dxfer_len, GFP_ATOMIC);
-               else
-                       res = blk_rq_map_user(q, rq, &map_data, hp->dxferp,
-                                             hp->dxfer_len, GFP_ATOMIC);
+               srp->bio = rq->bio;
 
-               if (!res)
-                       srp->bio = rq->bio;
+               if (!md) {
+                       req_schp->dio_in_use = 1;
+                       hp->info |= SG_INFO_DIRECT_IO;
+               }
        }
-
        return res;
 }
 
@@ -1730,25 +1727,6 @@ sg_build_sgat(Sg_scatter_hold * schp, const Sg_fd * sfp, int tablesize)
        return tablesize;       /* number of scat_gath elements allocated */
 }
 
-/* Returns: -ve -> error, 0 -> done, 1 -> try indirect */
-static int
-sg_build_direct(Sg_request * srp, Sg_fd * sfp, int dxfer_len)
-{
-       sg_io_hdr_t *hp = &srp->header;
-       Sg_scatter_hold *schp = &srp->data;
-       int res;
-       struct request *rq = srp->rq;
-       struct request_queue *q = sfp->parentdp->device->request_queue;
-
-       res = blk_rq_map_user(q, rq, NULL, hp->dxferp, dxfer_len, GFP_ATOMIC);
-       if (res)
-               return res;
-       srp->bio = rq->bio;
-       schp->dio_in_use = 1;
-       hp->info |= SG_INFO_DIRECT_IO;
-       return 0;
-}
-
 static int
 sg_build_indirect(Sg_scatter_hold * schp, Sg_fd * sfp, int buff_size)
 {
@@ -1830,32 +1808,6 @@ out:
        return -ENOMEM;
 }
 
-static int
-sg_write_xfer(Sg_request * srp)
-{
-       sg_io_hdr_t *hp = &srp->header;
-       Sg_scatter_hold *schp = &srp->data;
-       int num_xfer = 0;
-       int dxfer_dir = hp->dxfer_direction;
-       int new_interface = ('\0' == hp->interface_id) ? 0 : 1;
-
-       if ((SG_DXFER_UNKNOWN == dxfer_dir) || (SG_DXFER_TO_DEV == dxfer_dir) ||
-           (SG_DXFER_TO_FROM_DEV == dxfer_dir)) {
-               num_xfer = (int) (new_interface ? hp->dxfer_len : hp->flags);
-               if (schp->bufflen < num_xfer)
-                       num_xfer = schp->bufflen;
-       }
-       if ((num_xfer <= 0) || (schp->dio_in_use) ||
-           (new_interface
-            && ((SG_FLAG_NO_DXFER | SG_FLAG_MMAP_IO) & hp->flags)))
-               return 0;
-
-       SCSI_LOG_TIMEOUT(4, printk("sg_write_xfer: num_xfer=%d, k_use_sg=%d\n",
-                         num_xfer, schp->k_use_sg));
-
-       return 0;
-}
-
 static void
 sg_remove_scat(Sg_scatter_hold * schp)
 {
@@ -1877,31 +1829,6 @@ sg_remove_scat(Sg_scatter_hold * schp)
        memset(schp, 0, sizeof (*schp));
 }
 
-static int
-sg_read_xfer(Sg_request * srp)
-{
-       sg_io_hdr_t *hp = &srp->header;
-       Sg_scatter_hold *schp = &srp->data;
-       int num_xfer = 0;
-       int dxfer_dir = hp->dxfer_direction;
-       int new_interface = ('\0' == hp->interface_id) ? 0 : 1;
-
-       if ((SG_DXFER_UNKNOWN == dxfer_dir) || (SG_DXFER_FROM_DEV == dxfer_dir)
-           || (SG_DXFER_TO_FROM_DEV == dxfer_dir)) {
-               num_xfer = hp->dxfer_len;
-               if (schp->bufflen < num_xfer)
-                       num_xfer = schp->bufflen;
-       }
-       if ((num_xfer <= 0) || (schp->dio_in_use) ||
-           (new_interface
-            && ((SG_FLAG_NO_DXFER | SG_FLAG_MMAP_IO) & hp->flags)))
-               return 0;
-
-       SCSI_LOG_TIMEOUT(4, printk("sg_read_xfer: num_xfer=%d, iovec_count=%d, k_use_sg=%d\n",
-                         num_xfer, (int)hp->iovec_count, schp->k_use_sg));
-       return 0;
-}
-
 static int
 sg_read_oxfer(Sg_request * srp, char __user *outp, int num_read_xfer)
 {
@@ -1913,9 +1840,6 @@ sg_read_oxfer(Sg_request * srp, char __user *outp, int num_read_xfer)
        if ((!outp) || (num_read_xfer <= 0))
                return 0;
 
-       blk_rq_unmap_user(srp->bio);
-       srp->bio = NULL;
-
        num = 1 << (PAGE_SHIFT + schp->page_order);
        for (k = 0; k < schp->k_use_sg && schp->pages[k]; k++) {
                if (num > num_read_xfer) {