.max_sectors            = 1024,
        .cmd_per_lun            = SIMSCSI_REQ_QUEUE_LEN,
        .use_clustering         = DISABLE_CLUSTERING,
-       .use_sg_chaining        = ENABLE_SG_CHAINING,
 };
 
 static int __init
 
        .this_id                        = -1,
        .cmd_per_lun                    = SRP_SQ_SIZE,
        .use_clustering                 = ENABLE_CLUSTERING,
-       .use_sg_chaining                = ENABLE_SG_CHAINING,
        .shost_attrs                    = srp_host_attrs
 };
 
 
        .max_sectors            = TW_MAX_SECTORS,
        .cmd_per_lun            = TW_MAX_CMDS_PER_LUN,
        .use_clustering         = ENABLE_CLUSTERING,
-       .use_sg_chaining        = ENABLE_SG_CHAINING,
        .shost_attrs            = twa_host_attrs,
        .emulated               = 1
 };
 
        .max_sectors            = TW_MAX_SECTORS,
        .cmd_per_lun            = TW_MAX_CMDS_PER_LUN,  
        .use_clustering         = ENABLE_CLUSTERING,
-       .use_sg_chaining        = ENABLE_SG_CHAINING,
        .shost_attrs            = tw_host_attrs,
        .emulated               = 1
 };
 
        .unchecked_isa_dma = 1,
        .max_sectors = 128,
        .use_clustering = ENABLE_CLUSTERING,
-       .use_sg_chaining = ENABLE_SG_CHAINING,
 };
 
 /*
 
      .cmd_per_lun              = 1                     /* commands per lun */, 
      .unchecked_isa_dma        = 1                     /* unchecked_isa_dma */,
      .use_clustering           = ENABLE_CLUSTERING,
-     .use_sg_chaining           = ENABLE_SG_CHAINING,
 };
 
 #include "scsi_module.c"
 
        .sg_tablesize           = SG_ALL,
        .cmd_per_lun            = 1,
        .use_clustering         = ENABLE_CLUSTERING,
-       .use_sg_chaining        = ENABLE_SG_CHAINING,
 };
 
 static int __devinit inia100_probe_one(struct pci_dev *pdev,
 
        .cmd_per_lun                    = AAC_NUM_IO_FIB,
 #endif
        .use_clustering                 = ENABLE_CLUSTERING,
-       .use_sg_chaining                = ENABLE_SG_CHAINING,
        .emulated                       = 1,
 };
 
 
        .sg_tablesize     = AHA1740_SCATTER,
        .cmd_per_lun      = AHA1740_CMDLUN,
        .use_clustering   = ENABLE_CLUSTERING,
-       .use_sg_chaining  = ENABLE_SG_CHAINING,
        .eh_abort_handler = aha1740_eh_abort_handler,
 };
 
 
        .max_sectors            = 8192,
        .cmd_per_lun            = 2,
        .use_clustering         = ENABLE_CLUSTERING,
-       .use_sg_chaining        = ENABLE_SG_CHAINING,
        .slave_alloc            = ahd_linux_slave_alloc,
        .slave_configure        = ahd_linux_slave_configure,
        .target_alloc           = ahd_linux_target_alloc,
 
        .max_sectors            = 8192,
        .cmd_per_lun            = 2,
        .use_clustering         = ENABLE_CLUSTERING,
-       .use_sg_chaining        = ENABLE_SG_CHAINING,
        .slave_alloc            = ahc_linux_slave_alloc,
        .slave_configure        = ahc_linux_slave_configure,
        .target_alloc           = ahc_linux_target_alloc,
 
        .max_sectors            = 2048,
        .cmd_per_lun            = 3,
        .use_clustering         = ENABLE_CLUSTERING,
-       .use_sg_chaining        = ENABLE_SG_CHAINING,
 };
 
 #include "scsi_module.c"
 
        .max_sectors            = ARCMSR_MAX_XFER_SECTORS,
        .cmd_per_lun            = ARCMSR_MAX_CMD_PERLUN,
        .use_clustering         = ENABLE_CLUSTERING,
-       .use_sg_chaining        = ENABLE_SG_CHAINING,
        .shost_attrs            = arcmsr_host_attrs,
 };
 #ifdef CONFIG_SCSI_ARCMSR_AER
 
        .eh_bus_reset_handler   = dc395x_eh_bus_reset,
        .unchecked_isa_dma      = 0,
        .use_clustering         = DISABLE_CLUSTERING,
-       .use_sg_chaining        = ENABLE_SG_CHAINING,
 };
 
 
 
        .this_id                = 7,
        .cmd_per_lun            = 1,
        .use_clustering         = ENABLE_CLUSTERING,
-       .use_sg_chaining        = ENABLE_SG_CHAINING,
 };
 #include "scsi_module.c"
 MODULE_LICENSE("GPL");
 
        .this_id = 7,
        .unchecked_isa_dma = 1,
        .use_clustering = ENABLE_CLUSTERING,
-       .use_sg_chaining = ENABLE_SG_CHAINING,
 };
 
 #if !defined(__BIG_ENDIAN_BITFIELD) && !defined(__LITTLE_ENDIAN_BITFIELD)
 
        shost->use_clustering = sht->use_clustering;
        shost->ordered_tag = sht->ordered_tag;
        shost->active_mode = sht->supported_mode;
-       shost->use_sg_chaining = sht->use_sg_chaining;
 
        if (sht->supported_mode == MODE_UNKNOWN)
                /* means we didn't set it ... default to INITIATOR */
 
        .unchecked_isa_dma          = 0,
        .emulated                   = 0,
        .use_clustering             = ENABLE_CLUSTERING,
-       .use_sg_chaining            = ENABLE_SG_CHAINING,
        .proc_name                  = driver_name,
        .shost_attrs                = hptiop_attrs,
        .this_id                    = -1,
 
           .sg_tablesize   = 16,
           .cmd_per_lun    = 1,
           .use_clustering = ENABLE_CLUSTERING,
-          .use_sg_chaining = ENABLE_SG_CHAINING,
 };
 
 static int ibmmca_probe(struct device *dev)
 
        .this_id = -1,
        .sg_tablesize = SG_ALL,
        .use_clustering = ENABLE_CLUSTERING,
-       .use_sg_chaining = ENABLE_SG_CHAINING,
        .shost_attrs = ibmvscsi_attrs,
 };
 
 
        .sg_tablesize           = SG_ALL,
        .cmd_per_lun            = 1,
        .use_clustering         = ENABLE_CLUSTERING,
-       .use_sg_chaining        = ENABLE_SG_CHAINING,
 };
 
 static int initio_probe_one(struct pci_dev *pdev,
 
        .eh_device_reset_handler= iscsi_eh_device_reset,
        .eh_host_reset_handler  = iscsi_eh_host_reset,
        .use_clustering         = DISABLE_CLUSTERING,
-       .use_sg_chaining        = ENABLE_SG_CHAINING,
        .slave_configure        = iscsi_tcp_slave_configure,
        .proc_name              = "iscsi_tcp",
        .this_id                = -1,
 
        .scan_finished          = lpfc_scan_finished,
        .this_id                = -1,
        .sg_tablesize           = LPFC_DEFAULT_SG_SEG_CNT,
-       .use_sg_chaining        = ENABLE_SG_CHAINING,
        .cmd_per_lun            = LPFC_CMD_PER_LUN,
        .use_clustering         = ENABLE_CLUSTERING,
        .shost_attrs            = lpfc_hba_attrs,
        .sg_tablesize           = LPFC_DEFAULT_SG_SEG_CNT,
        .cmd_per_lun            = LPFC_CMD_PER_LUN,
        .use_clustering         = ENABLE_CLUSTERING,
-       .use_sg_chaining        = ENABLE_SG_CHAINING,
        .shost_attrs            = lpfc_vport_attrs,
        .max_sectors            = 0xFFFF,
 };
 
        .sg_tablesize   = SG_ALL,
        .cmd_per_lun    = 1,
        .use_clustering = DISABLE_CLUSTERING,
-       .use_sg_chaining = ENABLE_SG_CHAINING,
 };
 
 static int mac53c94_probe(struct macio_dev *mdev, const struct of_device_id *match)
 
        .sg_tablesize                   = MAX_SGLIST,
        .cmd_per_lun                    = DEF_CMD_PER_LUN,
        .use_clustering                 = ENABLE_CLUSTERING,
-       .use_sg_chaining                = ENABLE_SG_CHAINING,
        .eh_abort_handler               = megaraid_abort,
        .eh_device_reset_handler        = megaraid_reset,
        .eh_bus_reset_handler           = megaraid_reset,
 
        .eh_host_reset_handler          = megaraid_reset_handler,
        .change_queue_depth             = megaraid_change_queue_depth,
        .use_clustering                 = ENABLE_CLUSTERING,
-       .use_sg_chaining                = ENABLE_SG_CHAINING,
        .sdev_attrs                     = megaraid_sdev_attrs,
        .shost_attrs                    = megaraid_shost_attrs,
 };
 
        .eh_timed_out = megasas_reset_timer,
        .bios_param = megasas_bios_param,
        .use_clustering = ENABLE_CLUSTERING,
-       .use_sg_chaining = ENABLE_SG_CHAINING,
 };
 
 /**
 
        .sg_tablesize                   = SG_ALL,
        .cmd_per_lun                    = 2,
        .use_clustering                 = DISABLE_CLUSTERING,
-       .use_sg_chaining                = ENABLE_SG_CHAINING,
 };
 
 static int mesh_probe(struct macio_dev *mdev, const struct of_device_id *match)
 
        .cmd_per_lun                    = 1,
        .this_id                        = NSP32_HOST_SCSIID,
        .use_clustering                 = DISABLE_CLUSTERING,
-       .use_sg_chaining                = ENABLE_SG_CHAINING,
        .eh_abort_handler               = nsp32_eh_abort,
        .eh_bus_reset_handler           = nsp32_eh_bus_reset,
        .eh_host_reset_handler          = nsp32_eh_host_reset,
 
      .sg_tablesize             = 32,
      .cmd_per_lun              = 1,
      .use_clustering           = ENABLE_CLUSTERING,
-     .use_sg_chaining          = ENABLE_SG_CHAINING,
      .shost_attrs              = SYM53C500_shost_attrs
 };
 
 
        .sg_tablesize           = SG_ALL,
        .cmd_per_lun            = 1,
        .use_clustering         = ENABLE_CLUSTERING,
-       .use_sg_chaining        = ENABLE_SG_CHAINING,
 };
 
 
 
        .this_id                = -1,
        .cmd_per_lun            = 3,
        .use_clustering         = ENABLE_CLUSTERING,
-       .use_sg_chaining        = ENABLE_SG_CHAINING,
        .sg_tablesize           = SG_ALL,
 
        /*
        .this_id                = -1,
        .cmd_per_lun            = 3,
        .use_clustering         = ENABLE_CLUSTERING,
-       .use_sg_chaining        = ENABLE_SG_CHAINING,
        .sg_tablesize           = SG_ALL,
 
        .max_sectors            = 0xFFFF,
 
        .this_id                = -1,
        .cmd_per_lun            = 3,
        .use_clustering         = ENABLE_CLUSTERING,
-       .use_sg_chaining        = ENABLE_SG_CHAINING,
        .sg_tablesize           = SG_ALL,
 
        .max_sectors            = 0xFFFF,
 
        .sg_tablesize           = SG_ALL,
        .cmd_per_lun            = 1,
        .use_clustering         = DISABLE_CLUSTERING,
-       .use_sg_chaining        = ENABLE_SG_CHAINING,
 };
 
 static __init int qlogicfas_init(void)
 
  */
 
 #include <linux/bio.h>
+#include <linux/bitops.h>
 #include <linux/blkdev.h>
 #include <linux/completion.h>
 #include <linux/kernel.h>
 #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;
        mempool_t       *pool;
 };
 
-#define SP(x) { x, "sgpool-" #x }
+#define SP(x) { x, "sgpool-" __stringify(x) }
+#if (SCSI_MAX_SG_SEGMENTS < 32)
+#error SCSI_MAX_SG_SEGMENTS is too small (must be 32 or greater)
+#endif
 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),
+       SP(32),
 #if (SCSI_MAX_SG_SEGMENTS > 64)
+       SP(64),
+#if (SCSI_MAX_SG_SEGMENTS > 128)
        SP(128),
+#if (SCSI_MAX_SG_SEGMENTS > 256)
+#error SCSI_MAX_SG_SEGMENTS is too large (256 MAX)
 #endif
 #endif
 #endif
+#endif
+       SP(SCSI_MAX_SG_SEGMENTS)
 };
 #undef SP
 
        return NULL;
 }
 
-/*
- * 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.
- */
-#define SCSI_MAX_SG_CHAIN_SEGMENTS     2048
-
 static inline unsigned int scsi_sgtable_index(unsigned short nents)
 {
        unsigned int index;
 
-       switch (nents) {
-       case 1 ... 8:
+       BUG_ON(nents > SCSI_MAX_SG_SEGMENTS);
+
+       if (nents <= 8)
                index = 0;
-               break;
-       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;
-#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();
-       }
+       else
+               index = get_count_order(nents) - 3;
 
        return index;
 }
         * this limit is imposed by hardware restrictions
         */
        blk_queue_max_hw_segments(q, shost->sg_tablesize);
-
-       /*
-        * In the future, sg chaining support will be mandatory and this
-        * ifdef can then go away. Right now we don't have all archs
-        * converted, so better keep it safe.
-        */
-#ifdef ARCH_HAS_SG_CHAIN
-       if (shost->use_sg_chaining)
-               blk_queue_max_phys_segments(q, SCSI_MAX_SG_CHAIN_SEGMENTS);
-       else
-               blk_queue_max_phys_segments(q, SCSI_MAX_SG_SEGMENTS);
-#else
-       blk_queue_max_phys_segments(q, SCSI_MAX_SG_SEGMENTS);
-#endif
+       blk_queue_max_phys_segments(q, SCSI_MAX_SG_CHAIN_SEGMENTS);
 
        blk_queue_max_sectors(q, shost->max_sectors);
        blk_queue_bounce_limit(q, scsi_calculate_bounce_limit(shost));
 
        .this_id                        = -1,
        .sg_tablesize                   = ST_MAX_SG,
        .cmd_per_lun                    = ST_CMD_PER_LUN,
-       .use_sg_chaining                = ENABLE_SG_CHAINING,
 };
 
 static int stex_set_dma_mask(struct pci_dev * pdev)
 
        .cmd_per_lun =          1,
        .unchecked_isa_dma =    1,
        .use_clustering =       ENABLE_CLUSTERING,
-       .use_sg_chaining =      ENABLE_SG_CHAINING,
 };
 #include "scsi_module.c"
 
        .eh_host_reset_handler  = sym53c8xx_eh_host_reset_handler,
        .this_id                = 7,
        .use_clustering         = ENABLE_CLUSTERING,
-       .use_sg_chaining        = ENABLE_SG_CHAINING,
        .max_sectors            = 0xFFFF,
 #ifdef SYM_LINUX_PROC_INFO_SUPPORT
        .proc_info              = sym53c8xx_proc_info,
 
                 .this_id                 = 7,
                 .unchecked_isa_dma       = 1,
                 .use_clustering          = ENABLE_CLUSTERING,
-                .use_sg_chaining         = ENABLE_SG_CHAINING,
                 };
 
 #if !defined(__BIG_ENDIAN_BITFIELD) && !defined(__LITTLE_ENDIAN_BITFIELD)
 
        .cmd_per_lun       = ULTRASTOR_MAX_CMDS_PER_LUN,
        .unchecked_isa_dma = 1,
        .use_clustering    = ENABLE_CLUSTERING,
-       .use_sg_chaining   = ENABLE_SG_CHAINING,
 };
 #include "scsi_module.c"
 
        .cmd_per_lun            = 1,
        .unchecked_isa_dma      = 1,
        .use_clustering         = ENABLE_CLUSTERING,
-       .use_sg_chaining        = ENABLE_SG_CHAINING,
 };
 
 #include "scsi_module.c"
 
 
 #include <linux/types.h>
 
+/*
+ * 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.  We could define this
+ * to SG_MAX_SINGLE_ALLOC to pack correctly at the highest order.  The
+ * minimum value is 32
+ */
+#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.
+ */
+#ifdef ARCH_HAS_SG_CHAIN
+#define SCSI_MAX_SG_CHAIN_SEGMENTS     2048
+#else
+#define SCSI_MAX_SG_CHAIN_SEGMENTS     SCSI_MAX_SG_SEGMENTS
+#endif
+
 /*
  *     SCSI command lengths
  */
 
 #define DISABLE_CLUSTERING 0
 #define ENABLE_CLUSTERING 1
 
-#define DISABLE_SG_CHAINING 0
-#define ENABLE_SG_CHAINING 1
-
 enum scsi_eh_timer_return {
        EH_NOT_HANDLED,
        EH_HANDLED,
         */
        unsigned ordered_tag:1;
 
-       /*
-        * true if the low-level driver can support sg chaining. this
-        * will be removed eventually when all the drivers are
-        * converted to support sg chaining.
-        *
-        * Status: OBSOLETE
-        */
-       unsigned use_sg_chaining:1;
-
        /*
         * Countdown for host blocking with no commands outstanding
         */
        unsigned unchecked_isa_dma:1;
        unsigned use_clustering:1;
        unsigned use_blk_tcq:1;
-       unsigned use_sg_chaining:1;
 
        /*
         * Host has requested that no further requests come through for the