Merge branch 'upstream-linus' of master.kernel.org:/pub/scm/linux/kernel/git/jgarzik...
[cascardo/linux.git] / drivers / scsi / scsi_lib.c
index b6e6d80..61fdaf0 100644 (file)
 #define SG_MEMPOOL_NR          ARRAY_SIZE(scsi_sg_pools)
 #define SG_MEMPOOL_SIZE                2
 
+/*
+ * The maximum number of SG segments that we will put inside a scatterlist
+ * (unless chaining is used). Should ideally fit inside a single page, to
+ * avoid a higher order allocation.
+ */
+#define SCSI_MAX_SG_SEGMENTS   128
+
 struct scsi_host_sg_pool {
        size_t          size;
        char            *name;
@@ -45,9 +52,15 @@ struct scsi_host_sg_pool {
 static struct scsi_host_sg_pool scsi_sg_pools[] = {
        SP(8),
        SP(16),
+#if (SCSI_MAX_SG_SEGMENTS > 16)
        SP(32),
+#if (SCSI_MAX_SG_SEGMENTS > 32)
        SP(64),
+#if (SCSI_MAX_SG_SEGMENTS > 64)
        SP(128),
+#endif
+#endif
+#endif
 };
 #undef SP
 
@@ -282,7 +295,7 @@ static int scsi_req_map_sg(struct request *rq, struct scatterlist *sgl,
        int i, err, nr_vecs = 0;
 
        for_each_sg(sgl, sg, nsegs, i) {
-               page = sg->page;
+               page = sg_page(sg);
                off = sg->offset;
                len = sg->length;
                data_len += len;
@@ -684,13 +697,6 @@ static struct scsi_cmnd *scsi_end_request(struct scsi_cmnd *cmd, int uptodate,
        return NULL;
 }
 
-/*
- * The maximum number of SG segments that we will put inside a scatterlist
- * (unless chaining is used). Should ideally fit inside a single page, to
- * avoid a higher order allocation.
- */
-#define SCSI_MAX_SG_SEGMENTS   128
-
 /*
  * Like SCSI_MAX_SG_SEGMENTS, but for archs that have sg chaining. This limit
  * is totally arbitrary, a setting of 2048 will get you at least 8mb ios.
@@ -708,15 +714,21 @@ static inline unsigned int scsi_sgtable_index(unsigned short nents)
        case 9 ... 16:
                index = 1;
                break;
+#if (SCSI_MAX_SG_SEGMENTS > 16)
        case 17 ... 32:
                index = 2;
                break;
+#if (SCSI_MAX_SG_SEGMENTS > 32)
        case 33 ... 64:
                index = 3;
                break;
-       case 65 ... SCSI_MAX_SG_SEGMENTS:
+#if (SCSI_MAX_SG_SEGMENTS > 64)
+       case 65 ... 128:
                index = 4;
                break;
+#endif
+#endif
+#endif
        default:
                printk(KERN_ERR "scsi: bad segment count=%d\n", nents);
                BUG();
@@ -752,15 +764,13 @@ struct scatterlist *scsi_alloc_sgtable(struct scsi_cmnd *cmd, gfp_t gfp_mask)
                if (unlikely(!sgl))
                        goto enomem;
 
-               memset(sgl, 0, sizeof(*sgl) * sgp->size);
+               sg_init_table(sgl, sgp->size);
 
                /*
                 * first loop through, set initial index and return value
                 */
-               if (!ret) {
-                       cmd->sglist_len = index;
+               if (!ret)
                        ret = sgl;
-               }
 
                /*
                 * chain previous sglist, if any. we know the previous
@@ -770,6 +780,13 @@ struct scatterlist *scsi_alloc_sgtable(struct scsi_cmnd *cmd, gfp_t gfp_mask)
                if (prev)
                        sg_chain(prev, SCSI_MAX_SG_SEGMENTS, sgl);
 
+               /*
+                * if we have nothing left, mark the last segment as
+                * end-of-list
+                */
+               if (!left)
+                       sg_mark_end(sgl, this);
+
                /*
                 * don't allow subsequent mempool allocs to sleep, it would
                 * violate the mempool principle.
@@ -813,8 +830,6 @@ void scsi_free_sgtable(struct scsi_cmnd *cmd)
        struct scatterlist *sgl = cmd->request_buffer;
        struct scsi_host_sg_pool *sgp;
 
-       BUG_ON(cmd->sglist_len >= SG_MEMPOOL_NR);
-
        /*
         * if this is the biggest size sglist, check if we have
         * chained parts we need to free
@@ -849,9 +864,10 @@ void scsi_free_sgtable(struct scsi_cmnd *cmd)
                 * Restore original, will be freed below
                 */
                sgl = cmd->request_buffer;
-       }
+               sgp = scsi_sg_pools + SG_MEMPOOL_NR - 1;
+       } else
+               sgp = scsi_sg_pools + scsi_sgtable_index(cmd->__use_sg);
 
-       sgp = scsi_sg_pools + cmd->sglist_len;
        mempool_free(sgl, sgp->pool);
 }
 
@@ -2344,7 +2360,7 @@ void *scsi_kmap_atomic_sg(struct scatterlist *sgl, int sg_count,
        *offset = *offset - len_complete + sg->offset;
 
        /* Assumption: contiguous pages can be accessed as "page + i" */
-       page = nth_page(sg->page, (*offset >> PAGE_SHIFT));
+       page = nth_page(sg_page(sg), (*offset >> PAGE_SHIFT));
        *offset &= ~PAGE_MASK;
 
        /* Bytes in this sg-entry from *offset to the end of the page */