diff --git a/drivers/block/cciss_scsi.c b/drivers/block/cciss_scsi.c
--- a/drivers/block/cciss_scsi.c
+++ b/drivers/block/cciss_scsi.c
@@ -1191,28 +1191,28 @@ cciss_scatter_gather(struct pci_dev *pde
 		struct scsi_cmnd *cmd)
 {
 	unsigned int len;
-	struct scatterlist *sg;
+	struct sg_ring *sg;
 	__u64 addr64;
-	int use_sg, i;
+	int count = 0, i;
 
-	BUG_ON(scsi_sg_count(cmd) > MAXSGENTRIES);
-
-	use_sg = scsi_dma_map(cmd);
-	if (use_sg) {	/* not too many addrs? */
-		scsi_for_each_sg(cmd, sg, use_sg, i) {
-			addr64 = (__u64) sg_dma_address(sg);
-			len  = sg_dma_len(sg);
+	if (scsi_dma_map(cmd) > 0) {	/* not too many addrs? */
+		sg_ring_for_each(cmd->sg, sg, i) {
+			addr64 = (__u64) sg_dma_address(&sg->sg[i]);
+			len  = sg_dma_len(&sg->sg[i]);
 			cp->SG[i].Addr.lower =
 				(__u32) (addr64 & (__u64) 0x00000000FFFFFFFF);
 			cp->SG[i].Addr.upper =
 				(__u32) ((addr64 >> 32) & (__u64) 0x00000000FFFFFFFF);
 			cp->SG[i].Len = len;
 			cp->SG[i].Ext = 0;  // we are not chaining
+			count++;
 		}
 	}
 
-	cp->Header.SGList = (__u8) use_sg;   /* no. SGs contig in this cmd */
-	cp->Header.SGTotal = (__u16) use_sg; /* total sgs in this cmd list */
+	cp->Header.SGList = (__u8) count;   /* no. SGs contig in this cmd */
+	cp->Header.SGTotal = (__u16) count; /* total sgs in this cmd list */
+
+	BUG_ON(count > MAXSGENTRIES);
 	return;
 }
 
diff --git a/drivers/scsi/a100u2w.c b/drivers/scsi/a100u2w.c
--- a/drivers/scsi/a100u2w.c
+++ b/drivers/scsi/a100u2w.c
@@ -859,7 +859,7 @@ static void inia100_build_scb(struct orc
 	scb->reserved1 = 0;
 	scb->sg_len = 0;
 
-	scb->xferlen = (u32) scsi_bufflen(cmd);
+	scb->xferlen = (u32) cmd->request_length;
 	sgent = (struct orc_sgent *) & escb->sglist[0];
 
 	count_sg = scsi_dma_map(cmd);
@@ -868,9 +868,9 @@ static void inia100_build_scb(struct orc
 	/* Build the scatter gather lists */
 	if (count_sg) {
 		scb->sg_len = (u32) (count_sg * 8);
-		scsi_for_each_sg(cmd, sg, count_sg, i) {
-			sgent->base = (u32) sg_dma_address(sg);
-			sgent->length = (u32) sg_dma_len(sg);
+		sg_ring_for_each(cmd->sg, sg, i) {
+			sgent->base = (u32) sg_dma_address(&sg->sg[i]);
+			sgent->length = (u32) sg_dma_len(&sg->sg[i]);
 			sgent++;
 		}
 	} else {
diff --git a/drivers/scsi/aic7xxx/aic79xx_osm.c b/drivers/scsi/aic7xxx/aic79xx_osm.c
--- a/drivers/scsi/aic7xxx/aic79xx_osm.c
+++ b/drivers/scsi/aic7xxx/aic79xx_osm.c
@@ -1490,19 +1490,19 @@ ahd_linux_run_command(struct ahd_softc *
 	BUG_ON(nseg < 0);
 	if (nseg > 0) {
 		void *sg = scb->sg_list;
-		struct scatterlist *cur_seg;
+		struct sg_ring *cur_sgr;
 		int i;
 
 		scb->platform_data->xfer_len = 0;
 
-		scsi_for_each_sg(cmd, cur_seg, nseg, i) {
+		sg_ring_for_each(cmd->sg, cur_sgr, i) {
 			dma_addr_t addr;
 			bus_size_t len;
 
-			addr = sg_dma_address(cur_seg);
-			len = sg_dma_len(cur_seg);
+			addr = sg_dma_address(&cur_sgr->sg[i]);
+			len = sg_dma_len(&cur_sgr->sg[i]);
 			scb->platform_data->xfer_len += len;
-			sg = ahd_sg_setup(ahd, scb, sg, addr, len,
+			sg = ahd_sg_setup(ahd, scb, &cur_sgr->sg[i], addr, len,
 					  i == (nseg - 1));
 		}
 	}
diff --git a/drivers/scsi/aic7xxx_old.c b/drivers/scsi/aic7xxx_old.c
--- a/drivers/scsi/aic7xxx_old.c
+++ b/drivers/scsi/aic7xxx_old.c
@@ -10211,7 +10211,7 @@ static void aic7xxx_buildscb(struct aic7
      * differences and the kernel SG list uses virtual addresses where
      * we need physical addresses.
      */
-    int i;
+    int i, idx;
 
     scb->sg_length = 0;
 
@@ -10223,16 +10223,17 @@ static void aic7xxx_buildscb(struct aic7
      * entry in both places, but now we download the address of
      * scb->sg_list[1] instead of 0 to the sg pointer in the hscb.
      */
-    scsi_for_each_sg(cmd, sg, use_sg, i) {
-      unsigned int len = sg_dma_len(sg);
-      scb->sg_list[i].address = cpu_to_le32(sg_dma_address(sg));
-      scb->sg_list[i].length = cpu_to_le32(len);
+    idx = 0;
+    sg_ring_for_each(cmd->sg, sg, i) {
+      unsigned int len = sg_dma_len(&sg->sg[i]);
+      scb->sg_list[idx].address = cpu_to_le32(sg_dma_address(&sg->sg[i]));
+      scb->sg_list[idx++].length = cpu_to_le32(len);
       scb->sg_length += len;
     }
     /* Copy the first SG into the data pointer area. */
     hscb->data_pointer = scb->sg_list[0].address;
     hscb->data_count = scb->sg_list[0].length;
-    scb->sg_count = i;
+    scb->sg_count = idx;
     hscb->SG_segment_count = i;
     hscb->SG_list_pointer = cpu_to_le32(SCB_DMA_ADDR(scb, &scb->sg_list[1]));
   } else {
diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c
--- a/drivers/scsi/atp870u.c
+++ b/drivers/scsi/atp870u.c
@@ -471,11 +471,14 @@ go_42:
 			/*
 			 *	Complete the command
 			 */
-			if (workreq->use_sg) {
-				pci_unmap_sg(dev->pdev,
-					(struct scatterlist *)workreq->request_buffer,
-					workreq->use_sg,
-					workreq->sc_data_direction);
+			if (workreq->sg) {
+				struct sg_ring *sg;
+
+				for (sg = workreq->sg; sg;
+				     sg = sg_ring_next(sg, workreq->sg))
+					pci_unmap_sg(dev->pdev, sg->sg,
+						     sg->num,
+						     workreq->sc_data_direction);
 			} else if (workreq->request_bufflen &&
 					workreq->sc_data_direction != DMA_NONE) {
 				pci_unmap_single(dev->pdev,
@@ -722,7 +725,7 @@ static void send_s870(struct atp_unit *d
 	unsigned short int tmpcip, w;
 	unsigned long l, bttl = 0;
 	unsigned int workport;
-	struct scatterlist *sgpnt;
+	struct sg_ring *sg;
 	unsigned long  sg_count;
 
 	if (dev->in_snd[c] != 0) {
@@ -855,22 +858,23 @@ oktosend:
 	/*
 	 *	Figure out the transfer size
 	 */
-	if (workreq->use_sg) {
+	if (workreq->sg) {
 #ifdef ED_DBGP
 		printk("Using SGL\n");
 #endif		
 		l = 0;
-		
-		sgpnt = (struct scatterlist *) workreq->request_buffer;
-		sg_count = pci_map_sg(dev->pdev, sgpnt, workreq->use_sg,
-	   			workreq->sc_data_direction);		
-		
-		for (i = 0; i < workreq->use_sg; i++) {
-			if (sgpnt[i].length == 0 || workreq->use_sg > ATP870U_SCATTER) {
-				panic("Foooooooood fight!");
+		sg_count = 0;
+		for (sg = workreq->sg; sg; sg = sg_ring_next(sg, workreq->sg)) {
+			sg_count += pci_map_sg(dev->pdev, sg->sg, sg->num,
+					       workreq->sc_data_direction);
+			for (i = 0; i < sg->num; i++) {
+				if (sg->sg[i].length == 0)
+					panic("Foooooooood fight!");
+				l += sgpnt[i].length;
 			}
-			l += sgpnt[i].length;
 		}
+		if (sg_ring_num(workreq->sg) > ATP870U_SCATTER)
+			panic("Foooooooood fight II!");
 #ifdef ED_DBGP		
 		printk( "send_s870: workreq->use_sg %d, sg_count %d l %8ld\n", workreq->use_sg, sg_count, l);
 #endif
@@ -938,12 +942,11 @@ oktosend:
 	 *	a linear chain.
 	 */
 
-	if (workreq->use_sg) {
-		sgpnt = (struct scatterlist *) workreq->request_buffer;
+	if (workreq->sg) {
 		i = 0;
-		for (j = 0; j < workreq->use_sg; j++) {
-			bttl = sg_dma_address(&sgpnt[j]);
-			l=sg_dma_len(&sgpnt[j]);
+		sg_ring_for_each(workreq->sg, sg, j) {
+			bttl = sg_dma_address(&sg->sg[j]);
+			l=sg_dma_len(&sg->sg[j]);
 #ifdef ED_DBGP		
 		printk("1. bttl %x, l %x\n",bttl, l);
 #endif			
diff --git a/drivers/scsi/dc395x.c b/drivers/scsi/dc395x.c
--- a/drivers/scsi/dc395x.c
+++ b/drivers/scsi/dc395x.c
@@ -1010,9 +1010,9 @@ static void build_srb(struct scsi_cmnd *
 			   cmd->bufflen, scsi_sglist(cmd), scsi_sg_count(cmd),
 			   srb->segment_x[0].address);
 	} else {
-		int i;
-		u32 reqlen = scsi_bufflen(cmd);
-		struct scatterlist *sg;
+		int i, idx;
+		u32 reqlen = cmd->request_length;
+		struct sg_ring *sg;
 		struct SGentry *sgp = srb->segment_x;
 
 		srb->sg_count = nseg;
@@ -1022,12 +1022,13 @@ static void build_srb(struct scsi_cmnd *
 			   reqlen, scsi_sglist(cmd), scsi_sg_count(cmd),
 			   srb->sg_count);
 
-		scsi_for_each_sg(cmd, sg, srb->sg_count, i) {
-			u32 busaddr = (u32)sg_dma_address(sg);
-			u32 seglen = (u32)sg->length;
+		sg_ring_for_each(cmd->sg, sg, idx) {
+			u32 busaddr = (u32)sg_dma_address(&sg->sg[idx]);
+			u32 seglen = (u32)sg->sg[idx].length;
 			sgp[i].address = busaddr;
 			sgp[i].length = seglen;
 			srb->total_xfer_length += seglen;
+			i++;
 		}
 		sgp += srb->sg_count - 1;
 
@@ -2146,7 +2147,7 @@ static void data_out_phase0(struct Adapt
 			sg_update_list(srb, d_left_counter);
 			/* KG: Most ugly hack! Apparently, this works around a chip bug */
 			if ((srb->segment_x[srb->sg_index].length ==
-			     diff && scsi_sg_count(srb->cmd))
+			     diff && srb->cmd->sg)
 			    || ((oldxferred & ~PAGE_MASK) ==
 				(PAGE_SIZE - diff))
 			    ) {
@@ -2281,8 +2282,8 @@ static void data_in_phase0(struct Adapte
 				local_irq_save(flags);
 				/* Assumption: it's inside one page as it's at most 4 bytes and
 				   I just assume it's on a 4-byte boundary */
-				base = scsi_kmap_atomic_sg(scsi_sglist(srb->cmd),
-							   srb->sg_count, &offset, &len);
+				base = scsi_kmap_atomic_sg(srb->cmd->sg,
+							   &offset, &len);
 				virt = base + offset;
 
 				left_io -= len;
@@ -2498,8 +2499,8 @@ static void data_io_transfer(struct Adap
 
 				local_irq_save(flags);
 				/* Again, max 4 bytes */
-				base = scsi_kmap_atomic_sg(scsi_sglist(srb->cmd),
-							   srb->sg_count, &offset, &len);
+				base = scsi_kmap_atomic_sg(srb->cmd->sg,
+							   &offset, &len);
 				virt = base + offset;
 
 				left_io -= len;
@@ -3451,9 +3452,11 @@ static void srb_done(struct AdapterCtlBl
 		}
 	}
 
-	if (dir != PCI_DMA_NONE && scsi_sg_count(cmd))
-		pci_dma_sync_sg_for_cpu(acb->dev, scsi_sglist(cmd),
-					scsi_sg_count(cmd), dir);
+	if (dir != PCI_DMA_NONE && cmd->sg) {
+		struct sg_ring *sg;
+		for (sg = cmd->sg; sg; sg = sg_ring_next(sg, cmd->sg))
+			pci_dma_sync_sg_for_cpu(acb->dev, sg->sg, sg->num, dir);
+	}
 
 	ckc_only = 0;
 /* Check Error Conditions */
@@ -3463,11 +3466,10 @@ static void srb_done(struct AdapterCtlBl
 		unsigned char *base = NULL;
 		struct ScsiInqData *ptr;
 		unsigned long flags = 0;
-		struct scatterlist* sg = scsi_sglist(cmd);
 		size_t offset = 0, len = sizeof(struct ScsiInqData);
 
 		local_irq_save(flags);
-		base = scsi_kmap_atomic_sg(sg, scsi_sg_count(cmd), &offset, &len);
+		base = scsi_kmap_atomic_sg(sg, cmd->sg, &offset, &len);
 		ptr = (struct ScsiInqData *)(base + offset);
 
 		if (!ckc_only && (cmd->result & RES_DID) == 0
diff --git a/drivers/scsi/dpt_i2o.c b/drivers/scsi/dpt_i2o.c
--- a/drivers/scsi/dpt_i2o.c
+++ b/drivers/scsi/dpt_i2o.c
@@ -2082,7 +2082,7 @@ static s32 adpt_scsi_to_i2o(adpt_hba* pH
 	s32 rcode;
 
 	memset(msg, 0 , sizeof(msg));
-	len = scsi_bufflen(cmd);
+	len = cmd->request_len;
 	direction = 0x00000000;	
 	
 	scsidir = 0x00000000;			// DATA NO XFER
@@ -2144,15 +2144,16 @@ static s32 adpt_scsi_to_i2o(adpt_hba* pH
 	BUG_ON(nseg < 0);
 	if (nseg) {
 		struct scatterlist *sg;
+		unsigned int i;
 
 		len = 0;
-		scsi_for_each_sg(cmd, sg, nseg, i) {
-			*mptr++ = direction|0x10000000|sg_dma_len(sg);
-			len+=sg_dma_len(sg);
-			*mptr++ = sg_dma_address(sg);
+		sg_ring_for_each(cmd->sg, sg, i) {
+			*mptr++ = direction|0x10000000|sg_dma_len(&sg->sg[i]);
+			len+=sg_dma_len(&sg->sg[i]);
+			*mptr++ = sg_dma_address(&sg->sg[i]);
 			/* Make this an end of list */
 			if (i == nseg - 1)
-				mptr[-2] = direction|0xD0000000|sg_dma_len(sg);
+				mptr[-2] = direction|0xD0000000|sg_dma_len(&sg->sg[i]);
 		}
 		reqlen = mptr - msg;
 		*lenptr = len;
diff --git a/drivers/scsi/eata.c b/drivers/scsi/eata.c
--- a/drivers/scsi/eata.c
+++ b/drivers/scsi/eata.c
@@ -1610,9 +1610,9 @@ static int eata2x_detect(struct scsi_hos
 
 static void map_dma(unsigned int i, struct hostdata *ha)
 {
-	unsigned int k, pci_dir;
+	unsigned int k, idx, pci_dir;
 	int count;
-	struct scatterlist *sg;
+	struct sg_ring *sg;
 	struct mscp *cpp;
 	struct scsi_cmnd *SCpnt;
 
@@ -1629,17 +1629,18 @@ static void map_dma(unsigned int i, stru
 
 	count = scsi_dma_map(SCpnt);
 	BUG_ON(count < 0);
-	scsi_for_each_sg(SCpnt, sg, count, k) {
-		cpp->sglist[k].address = H2DEV(sg_dma_address(sg));
-		cpp->sglist[k].num_bytes = H2DEV(sg_dma_len(sg));
+	k = 0;
+	sg_ring_for_each(SCpnt->sg, sg, idx) {
+		cpp->sglist[k].address = H2DEV(sg_dma_address(&sg->sg[idx]));
+		cpp->sglist[k].num_bytes = H2DEV(sg_dma_len(&sg->sg[idx]));
+		k++;
 	}
 
 	cpp->sg = 1;
 	cpp->data_address = H2DEV(pci_map_single(ha->pdev, cpp->sglist,
-						 scsi_sg_count(SCpnt) *
-						 sizeof(struct sg_list),
+						 k * sizeof(struct sg_list),
 						 pci_dir));
-	cpp->data_len = H2DEV((scsi_sg_count(SCpnt) * sizeof(struct sg_list)));
+	cpp->data_len = H2DEV((k * sizeof(struct sg_list)));
 }
 
 static void unmap_dma(unsigned int i, struct hostdata *ha)
@@ -1681,9 +1682,12 @@ static void sync_dma(unsigned int i, str
 					    DEV2H(cpp->sense_len),
 					    PCI_DMA_FROMDEVICE);
 
-	if (scsi_sg_count(SCpnt))
-		pci_dma_sync_sg_for_cpu(ha->pdev, scsi_sglist(SCpnt),
-					scsi_sg_count(SCpnt), pci_dir);
+	if (SCpnt->sg) {
+		struct sg_ring *sg;
+		for (sg = SCpnt->sg; sg; sg = sg_ring_next(sg, SCpnt->sg))
+			pci_dma_sync_sg_for_cpu(ha->pdev, sg->sg, sg->num,
+						pci_dir);
+	}
 
 	if (!DEV2H(cpp->data_len))
 		pci_dir = PCI_DMA_BIDIRECTIONAL;
diff --git a/drivers/scsi/gdth.c b/drivers/scsi/gdth.c
--- a/drivers/scsi/gdth.c
+++ b/drivers/scsi/gdth.c
@@ -2359,33 +2359,34 @@ static void gdth_copy_internal_data(gdth
 {
     ushort cpcount,i, max_sg = gdth_sg_count(scp);
     ushort cpsum,cpnow;
-    struct scatterlist *sl;
+    struct sg_ring *sg;
     char *address;
 
     cpcount = min_t(ushort, count, gdth_bufflen(scp));
 
     if (cpcount) {
         cpsum=0;
-        scsi_for_each_sg(scp, sl, max_sg, i) {
+	sg_ring_for_each(scp->sg, sg, i) {
             unsigned long flags;
-            cpnow = (ushort)sl->length;
+            cpnow = (ushort)sg->sg[i].length;
             TRACE(("copy_internal() now %d sum %d count %d %d\n",
                           cpnow, cpsum, cpcount, gdth_bufflen(scp)));
             if (cpsum+cpnow > cpcount) 
                 cpnow = cpcount - cpsum;
             cpsum += cpnow;
-            if (!sg_page(sl)) {
+            if (!sg_page(&sg->sg[i])) {
                 printk("GDT-HA %d: invalid sc/gt element in gdth_copy_internal_data()\n",
                        ha->hanum);
                 return;
             }
             local_irq_save(flags);
-            address = kmap_atomic(sg_page(sl), KM_BIO_SRC_IRQ) + sl->offset;
+            address = kmap_atomic(sg_page(&sg->sg[i]), KM_BIO_SRC_IRQ) 
+		    + sg->sg[i].offset;
             if (to_buffer)
                 memcpy(buffer, address, cpnow);
             else
                 memcpy(address, buffer, cpnow);
-            flush_dcache_page(sg_page(sl));
+            flush_dcache_page(sg_page(&sg->sg[i]));
             kunmap_atomic(address, KM_BIO_SRC_IRQ);
             local_irq_restore(flags);
             if (cpsum == cpcount)
@@ -2602,31 +2603,38 @@ static int gdth_fill_cache_cmd(gdth_ha_s
             sgcnt = pci_map_sg(ha->pdev, gdth_sglist(scp), gdth_sg_count(scp),
                                cmndinfo->dma_dir);
             if (mode64) {
-                struct scatterlist *sl;
+                struct sg_ring *sg;
+		unsigned int idx;
 
                 cmdp->u.cache64.DestAddr= (ulong64)-1;
                 cmdp->u.cache64.sg_canz = sgcnt;
-                scsi_for_each_sg(scp, sl, sgcnt, i) {
-                    cmdp->u.cache64.sg_lst[i].sg_ptr = sg_dma_address(sl);
+		i = 0;
+		sg_ring_for_each(scp->sg, sg, idx) {
+                    cmdp->u.cache64.sg_lst[i].sg_ptr =
+			    sg_dma_address(&sg->sg[idx]);
 #ifdef GDTH_DMA_STATISTICS
                     if (cmdp->u.cache64.sg_lst[i].sg_ptr > (ulong64)0xffffffff)
                         ha->dma64_cnt++;
                     else
                         ha->dma32_cnt++;
 #endif
-                    cmdp->u.cache64.sg_lst[i].sg_len = sg_dma_len(sl);
-                }
-            } else {
-                struct scatterlist *sl;
+                    cmdp->u.cache64.sg_lst[i].sg_len = sg_dma_len(&sg->sg[idx]);
+		    i++;
+                }
+            } else {
+                struct sg_ring *sg;
+		unsigned int idx;
 
                 cmdp->u.cache.DestAddr= 0xffffffff;
                 cmdp->u.cache.sg_canz = sgcnt;
-                scsi_for_each_sg(scp, sl, sgcnt, i) {
-                    cmdp->u.cache.sg_lst[i].sg_ptr = sg_dma_address(sl);
+		i = 0;
+                sg_ring_for_each(scp->sg, sg, idx) {
+                    cmdp->u.cache.sg_lst[i].sg_ptr = sg_dma_address(&sg->sg[idx]);
 #ifdef GDTH_DMA_STATISTICS
                     ha->dma32_cnt++;
 #endif
-                    cmdp->u.cache.sg_lst[i].sg_len = sg_dma_len(sl);
+                    cmdp->u.cache.sg_lst[i].sg_len = sg_dma_len(&sg->sg[idx]);
+		    i++;
                 }
             }
 
@@ -2777,31 +2785,37 @@ static int gdth_fill_raw_cmd(gdth_ha_str
             sgcnt = pci_map_sg(ha->pdev, gdth_sglist(scp), gdth_sg_count(scp),
                                cmndinfo->dma_dir);
             if (mode64) {
-                struct scatterlist *sl;
+                struct sg_ring *sg;
+		unsigned int idx;
 
                 cmdp->u.raw64.sdata = (ulong64)-1;
                 cmdp->u.raw64.sg_ranz = sgcnt;
-                scsi_for_each_sg(scp, sl, sgcnt, i) {
-                    cmdp->u.raw64.sg_lst[i].sg_ptr = sg_dma_address(sl);
+		i = 0;
+                sg_ring_for_each(scp->sg, sg, idx) {
+                    cmdp->u.raw64.sg_lst[i].sg_ptr = sg_dma_address(&sg->sg[idx]);
 #ifdef GDTH_DMA_STATISTICS
                     if (cmdp->u.raw64.sg_lst[i].sg_ptr > (ulong64)0xffffffff)
                         ha->dma64_cnt++;
                     else
                         ha->dma32_cnt++;
 #endif
-                    cmdp->u.raw64.sg_lst[i].sg_len = sg_dma_len(sl);
-                }
-            } else {
-                struct scatterlist *sl;
+                    cmdp->u.raw64.sg_lst[i].sg_len = sg_dma_len(&sg->sg[idx]);
+		    i++;
+                }
+            } else {
+                struct sg_ring *sg;
+		unsigned int idx;
 
                 cmdp->u.raw.sdata = 0xffffffff;
                 cmdp->u.raw.sg_ranz = sgcnt;
-                scsi_for_each_sg(scp, sl, sgcnt, i) {
-                    cmdp->u.raw.sg_lst[i].sg_ptr = sg_dma_address(sl);
+		i = 0;
+                sg_ring_for_each(scp->sg, sg, idx) {
+                    cmdp->u.raw.sg_lst[i].sg_ptr = sg_dma_address(&sg->sg[idx]);
 #ifdef GDTH_DMA_STATISTICS
                     ha->dma32_cnt++;
 #endif
-                    cmdp->u.raw.sg_lst[i].sg_len = sg_dma_len(sl);
+                    cmdp->u.raw.sg_lst[i].sg_len = sg_dma_len(&sg->sg[idx]);
+		    i++;
                 }
             }
 
@@ -4034,9 +4048,9 @@ static int gdth_queuecommand(struct scsi
     gdth_update_timeout(scp, scp->timeout_per_command * 6);
     cmndinfo->priority = DEFAULT_PRI;
 
-    gdth_set_bufflen(scp, scsi_bufflen(scp));
-    gdth_set_sg_count(scp, scsi_sg_count(scp));
-    gdth_set_sglist(scp, scsi_sglist(scp));
+    gdth_set_bufflen(scp, scp->request_length);
+    gdth_set_sg_count(scp, scp->sg ? sg_ring_num(scp->sg) : 0);
+    gdth_set_sglist(scp, scp->sg);
 
     return __gdth_queuecommand(ha, scp, cmndinfo);
 }
diff --git a/drivers/scsi/initio.c b/drivers/scsi/initio.c
--- a/drivers/scsi/initio.c
+++ b/drivers/scsi/initio.c
@@ -2561,7 +2561,7 @@ static irqreturn_t i91u_intr(int irqno, 
 
 static void initio_build_scb(struct initio_host * host, struct scsi_ctrl_blk * cblk, struct scsi_cmnd * cmnd)
 {				/* Create corresponding SCB     */
-	struct scatterlist *sglist;
+	struct sg_ring *sgr;
 	struct sg_entry *sg;		/* Pointer to SG list           */
 	int i, nseg;
 	long total_len;
@@ -2613,13 +2613,13 @@ static void initio_build_scb(struct init
 		cblk->flags |= SCF_SG;	/* Turn on SG list flag       */
 		total_len = 0;
 		sg = &cblk->sglist[0];
-		scsi_for_each_sg(cmnd, sglist, cblk->sglen, i) {
-			sg->data = cpu_to_le32((u32)sg_dma_address(sglist));
-			total_len += sg->len = cpu_to_le32((u32)sg_dma_len(sglist));
+		sg_ring_for_each(cmnd->sg, sgr, i) {
+			sg->data = cpu_to_le32((u32)sg_dma_address(&sgr->sg[i]));
+			total_len += sg->len = cpu_to_le32((u32)sg_dma_len(&sgr->sg[i]));
 		}
 
-		cblk->buflen = (scsi_bufflen(cmnd) > total_len) ?
-			total_len : scsi_bufflen(cmnd);
+		cblk->buflen = (cmnd->request_length > total_len) ?
+			total_len : cmnd->request_length;
 	} else {	/* No data transfer required */
 		cblk->buflen = 0;
 		cblk->sglen = 0;
@@ -2742,7 +2742,7 @@ static void i91u_unmap_scb(struct pci_de
 	}
 
 	/* request buffer */
-	if (scsi_sg_count(cmnd)) {
+	if (cmnd->sg) {
 		dma_unmap_single(&pci_dev->dev, cmnd->SCp.dma_handle,
 				 sizeof(struct sg_entry) * TOTAL_SG_ENTRY,
 				 DMA_BIDIRECTIONAL);
diff --git a/drivers/scsi/megaraid.c b/drivers/scsi/megaraid.c
--- a/drivers/scsi/megaraid.c
+++ b/drivers/scsi/megaraid.c
@@ -657,7 +657,7 @@ mega_build_cmd(adapter_t *adapter, Scsi_
 			char *buf;
 			struct scatterlist *sg;
 
-			sg = scsi_sglist(cmd);
+			sg = &cmd->sg->sg[0];
 			buf = kmap_atomic(sg_page(sg), KM_IRQ0) + sg->offset;
 
 			memset(buf, 0, cmd->cmnd[4]);
@@ -1541,7 +1541,7 @@ mega_cmd_done(adapter_t *adapter, u8 com
 		islogical = adapter->logdrv_chan[cmd->device->channel];
 		if( cmd->cmnd[0] == INQUIRY && !islogical ) {
 
-			sgl = scsi_sglist(cmd);
+			sgl = &cmd->sg->sg[0];
 			if( sg_page(sgl) ) {
 				c = *(unsigned char *) sg_virt(&sgl[0]);
 			} else {
@@ -1734,7 +1734,7 @@ mega_build_sglist(adapter_t *adapter, sc
 	struct scatterlist *sg;
 	Scsi_Cmnd	*cmd;
 	int	sgcnt;
-	int	idx;
+	int	i, idx;
 
 	cmd = scb->cmd;
 
@@ -1751,22 +1751,24 @@ mega_build_sglist(adapter_t *adapter, sc
 
 	*len = 0;
 
-	if (scsi_sg_count(cmd) == 1 && !adapter->has_64bit_addr) {
-		sg = scsi_sglist(cmd);
+	if (sg_ring_num(cmd->sg) == 1 && !adapter->has_64bit_addr) {
+		sg = &cmd->sg->sg[0];
 		scb->dma_h_bulkdata = sg_dma_address(sg);
 		*buf = (u32)scb->dma_h_bulkdata;
 		*len = sg_dma_len(sg);
 		return 0;
 	}
 
-	scsi_for_each_sg(cmd, sg, sgcnt, idx) {
+	idx = 0;
+	sg_ring_for_each(cmd->sg, sg, i) {
 		if (adapter->has_64bit_addr) {
-			scb->sgl64[idx].address = sg_dma_address(sg);
-			*len += scb->sgl64[idx].length = sg_dma_len(sg);
+			scb->sgl64[idx].address = sg_dma_address(&sg->sg[i]);
+			*len += scb->sgl64[idx].length = sg_dma_len(&sg->sg[i]);
 		} else {
-			scb->sgl[idx].address = sg_dma_address(sg);
-			*len += scb->sgl[idx].length = sg_dma_len(sg);
-		}
+			scb->sgl[idx].address = sg_dma_address(&sg->sg[i]);
+			*len += scb->sgl[idx].length = sg_dma_len(&sg->sg[i]);
+		}
+		idx++;
 	}
 
 	/* Reset pointer and length fields */
diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c
--- a/drivers/scsi/scsi.c
+++ b/drivers/scsi/scsi.c
@@ -369,7 +369,7 @@ void scsi_log_send(struct scsi_cmnd *cmd
 			if (level > 3) {
 				printk(KERN_INFO "buffer = 0x%p, bufflen = %d,"
 				       " queuecommand 0x%p\n",
-					scsi_sglist(cmd), scsi_bufflen(cmd),
+					cmd->sg, cmd->request_bufflen,
 					cmd->device->host->hostt->queuecommand);
 
 			}
diff --git a/drivers/scsi/tmscsim.c b/drivers/scsi/tmscsim.c
--- a/drivers/scsi/tmscsim.c
+++ b/drivers/scsi/tmscsim.c
@@ -454,7 +454,7 @@ static int dc390_pci_map (struct dc390_s
 			error = 1;
 		DEBUG1(printk("%s(): Mapped sense buffer %p at %x\n", __FUNCTION__, pcmd->sense_buffer, cmdp->saved_dma_handle));
 	/* Map SG list */
-	} else if (scsi_sg_count(pcmd)) {
+	} else if (pcmd->sg) {
 		int nseg;
 
 		nseg = scsi_dma_map(pcmd);
diff --git a/drivers/scsi/tmscsim.h b/drivers/scsi/tmscsim.h
--- a/drivers/scsi/tmscsim.h
+++ b/drivers/scsi/tmscsim.h
@@ -31,9 +31,9 @@ struct dc390_srb	*pNextSRB;
 struct dc390_srb	*pNextSRB;
 struct dc390_dcb	*pSRBDCB;
 struct scsi_cmnd	*pcmd;
-struct scatterlist	*pSegmentList;
+struct sg_ring		*pSegmentRing;
 
-struct scatterlist Segmentx;	/* make a one entry of S/G list table */
+DECLARE_SG_RING(Segmentx, 1);	/* make a one entry of S/G list table */
 
 unsigned long	SGBusAddr;	/*;a segment starting address as seen by AM53C974A
 				  in CPU endianness. We're only getting 32-bit bus
