From 5e2a06489e4d4d85ca4ca20af23f213e95c2fbeb Mon Sep 17 00:00:00 2001
From: David Miller <davem@davemloft.net>
Date: Wed, 24 Oct 2007 08:44:21 +0200
Subject: SG build fix

Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Jens Axboe <axboe@carl.home.kernel.dk>
---
 arch/sparc64/kernel/iommu_common.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/sparc64/kernel/iommu_common.c b/arch/sparc64/kernel/iommu_common.c
index b70324e0d83..efd5dff85f6 100644
--- a/arch/sparc64/kernel/iommu_common.c
+++ b/arch/sparc64/kernel/iommu_common.c
@@ -234,7 +234,7 @@ unsigned long prepare_sg(struct scatterlist *sg, int nents)
 	dma_sg->dma_length = dent_len;
 
 	if (dma_sg != sg) {
-		dma_sg = next_sg(dma_sg);
+		dma_sg = sg_next(dma_sg);
 		dma_sg->dma_length = 0;
 	}
 
-- 
cgit v1.2.3-18-g5258


From de58d942924d431c1c2144ece35b0b9aceadaf2c Mon Sep 17 00:00:00 2001
From: Heiko Carstens <heiko.carstens@de.ibm.com>
Date: Wed, 24 Oct 2007 08:45:35 +0200
Subject: sg: add missing sg_init_table calls to zfcp

kernel BUG at include/linux/scatterlist.h:50!
illegal operation: 0001 [#1]
[...]
Call Trace:
([<000000000026f184>] zfcp_ns_gid_pn_request+0x4c/0x2a0)
 [<0000000000276dd4>] zfcp_erp_strategy_do_action+0x1410/0x1938
 [<0000000000278412>] zfcp_erp_thread+0x4fa/0x1430
 [<000000000001990a>] kernel_thread_starter+0x6/0xc
 [<0000000000019904>] kernel_thread_starter+0x0/0xc

Cc: Swen Schillig <swen@vnet.ibm.com>
Cc: Christof Schmitt <christof.schmitt@de.ibm.com>
Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: Jens Axboe <axboe@carl.home.kernel.dk>
---
 drivers/s390/scsi/zfcp_aux.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/s390/scsi/zfcp_aux.c b/drivers/s390/scsi/zfcp_aux.c
index fd5d0c1570d..d9e7be97976 100644
--- a/drivers/s390/scsi/zfcp_aux.c
+++ b/drivers/s390/scsi/zfcp_aux.c
@@ -1518,6 +1518,8 @@ zfcp_gid_pn_buffers_alloc(struct zfcp_gid_pn_data **gid_pn, mempool_t *pool)
                 return -ENOMEM;
 
 	memset(data, 0, sizeof(*data));
+	sg_init_table(&data->req , 1);
+	sg_init_table(&data->resp , 1);
         data->ct.req = &data->req;
         data->ct.resp = &data->resp;
 	data->ct.req_count = data->ct.resp_count = 1;
-- 
cgit v1.2.3-18-g5258


From d91c5e8839791b27672277e81451873499bc517e Mon Sep 17 00:00:00 2001
From: David Miller <davem@davemloft.net>
Date: Wed, 24 Oct 2007 08:46:01 +0200
Subject: More SG build fixes

Signed-off-by: Jens Axboe <axboe@carl.home.kernel.dk>
---
 arch/sparc64/kernel/ldc.c | 2 +-
 drivers/block/sunvdc.c    | 1 +
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/arch/sparc64/kernel/ldc.c b/arch/sparc64/kernel/ldc.c
index c8313cb60f0..217478a9412 100644
--- a/arch/sparc64/kernel/ldc.c
+++ b/arch/sparc64/kernel/ldc.c
@@ -2121,7 +2121,7 @@ int ldc_map_sg(struct ldc_channel *lp,
 	state.nc = 0;
 
 	for (i = 0; i < num_sg; i++)
-		fill_cookies(&state, page_to_pfn(sg[i].page) << PAGE_SHIFT,
+		fill_cookies(&state, page_to_pfn(sg_page(&sg[i])) << PAGE_SHIFT,
 			     sg[i].offset, sg[i].length);
 
 	return state.nc;
diff --git a/drivers/block/sunvdc.c b/drivers/block/sunvdc.c
index 7276f7d207c..fac4c6cd04f 100644
--- a/drivers/block/sunvdc.c
+++ b/drivers/block/sunvdc.c
@@ -15,6 +15,7 @@
 #include <linux/delay.h>
 #include <linux/init.h>
 #include <linux/list.h>
+#include <linux/scatterlist.h>
 
 #include <asm/vio.h>
 #include <asm/ldc.h>
-- 
cgit v1.2.3-18-g5258


From 5a1cb47ff4c3fbc8ebdb53c3e4f2a1dec466b339 Mon Sep 17 00:00:00 2001
From: Geert Uytterhoeven <geert@linux-m68k.org>
Date: Wed, 24 Oct 2007 08:55:40 +0200
Subject: m68k: sg fallout

Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
Signed-off-by: Jens Axboe <axboe@carl.home.kernel.dk>
---
 arch/m68k/kernel/dma.c               | 2 +-
 drivers/scsi/atari_NCR5380.c         | 5 ++---
 drivers/scsi/sun3x_esp.c             | 4 ++--
 net/ieee80211/ieee80211_crypt_tkip.c | 2 +-
 net/ieee80211/ieee80211_crypt_wep.c  | 2 +-
 5 files changed, 7 insertions(+), 8 deletions(-)

diff --git a/arch/m68k/kernel/dma.c b/arch/m68k/kernel/dma.c
index ef490e1ce60..6f8c080dd9f 100644
--- a/arch/m68k/kernel/dma.c
+++ b/arch/m68k/kernel/dma.c
@@ -9,10 +9,10 @@
 #include <linux/dma-mapping.h>
 #include <linux/device.h>
 #include <linux/kernel.h>
+#include <linux/scatterlist.h>
 #include <linux/vmalloc.h>
 
 #include <asm/pgalloc.h>
-#include <asm/scatterlist.h>
 
 void *dma_alloc_coherent(struct device *dev, size_t size,
 			 dma_addr_t *handle, gfp_t flag)
diff --git a/drivers/scsi/atari_NCR5380.c b/drivers/scsi/atari_NCR5380.c
index d1780980fb2..a9680b5e8ac 100644
--- a/drivers/scsi/atari_NCR5380.c
+++ b/drivers/scsi/atari_NCR5380.c
@@ -477,10 +477,9 @@ static void merge_contiguous_buffers(Scsi_Cmnd *cmd)
 
 	for (endaddr = virt_to_phys(cmd->SCp.ptr + cmd->SCp.this_residual - 1) + 1;
 	     cmd->SCp.buffers_residual &&
-	     virt_to_phys(page_address(cmd->SCp.buffer[1].page) +
-			  cmd->SCp.buffer[1].offset) == endaddr;) {
+	     virt_to_phys(sg_virt(&cmd->SCp.buffer[1])) == endaddr;) {
 		MER_PRINTK("VTOP(%p) == %08lx -> merging\n",
-			   page_address(cmd->SCp.buffer[1].page), endaddr);
+			   page_address(sg_page(&cmd->SCp.buffer[1])), endaddr);
 #if (NDEBUG & NDEBUG_MERGING)
 		++cnt;
 #endif
diff --git a/drivers/scsi/sun3x_esp.c b/drivers/scsi/sun3x_esp.c
index 80fb3f88af2..1bc41907a03 100644
--- a/drivers/scsi/sun3x_esp.c
+++ b/drivers/scsi/sun3x_esp.c
@@ -332,8 +332,8 @@ static void dma_mmu_get_scsi_sgl (struct NCR_ESP *esp, Scsi_Cmnd *sp)
     struct scatterlist *sg = sp->SCp.buffer;
 
     while (sz >= 0) {
-	    sg[sz].dma_address = dvma_map((unsigned long)page_address(sg[sz].page) +
-					   sg[sz].offset, sg[sz].length);
+	    sg[sz].dma_address = dvma_map((unsigned long)sg_virt(&sg[sz]),
+					  sg[sz].length);
 	    sz--;
     }
     sp->SCp.ptr=(char *)((unsigned long)sp->SCp.buffer->dma_address);
diff --git a/net/ieee80211/ieee80211_crypt_tkip.c b/net/ieee80211/ieee80211_crypt_tkip.c
index 811777682e2..74d017520a2 100644
--- a/net/ieee80211/ieee80211_crypt_tkip.c
+++ b/net/ieee80211/ieee80211_crypt_tkip.c
@@ -25,7 +25,7 @@
 #include <net/ieee80211.h>
 
 #include <linux/crypto.h>
-#include <asm/scatterlist.h>
+#include <linux/scatterlist.h>
 #include <linux/crc32.h>
 
 MODULE_AUTHOR("Jouni Malinen");
diff --git a/net/ieee80211/ieee80211_crypt_wep.c b/net/ieee80211/ieee80211_crypt_wep.c
index 9693429489e..866fc04c44f 100644
--- a/net/ieee80211/ieee80211_crypt_wep.c
+++ b/net/ieee80211/ieee80211_crypt_wep.c
@@ -22,7 +22,7 @@
 #include <net/ieee80211.h>
 
 #include <linux/crypto.h>
-#include <asm/scatterlist.h>
+#include <linux/scatterlist.h>
 #include <linux/crc32.h>
 
 MODULE_AUTHOR("Jouni Malinen");
-- 
cgit v1.2.3-18-g5258


From bd6dee6f30a0f6943df190b387b5f8fe98a848f3 Mon Sep 17 00:00:00 2001
From: Jens Axboe <jens.axboe@oracle.com>
Date: Wed, 24 Oct 2007 09:01:09 +0200
Subject: mmc: sg fallout

Do a full scan of the directory to try and be a bit more proactive,
instead of waiting for things to break.

Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
---
 drivers/mmc/host/au1xmmc.c | 2 +-
 drivers/mmc/host/mmci.c    | 6 +++---
 drivers/mmc/host/pxamci.c  | 1 -
 drivers/mmc/host/sdhci.c   | 2 --
 drivers/mmc/host/wbsd.c    | 2 +-
 5 files changed, 5 insertions(+), 8 deletions(-)

diff --git a/drivers/mmc/host/au1xmmc.c b/drivers/mmc/host/au1xmmc.c
index bcbb6d247bf..c77fadc0dfa 100644
--- a/drivers/mmc/host/au1xmmc.c
+++ b/drivers/mmc/host/au1xmmc.c
@@ -40,13 +40,13 @@
 #include <linux/mm.h>
 #include <linux/interrupt.h>
 #include <linux/dma-mapping.h>
+#include <scatterlist/scatterlist.h>
 
 #include <linux/mmc/host.h>
 #include <asm/io.h>
 #include <asm/mach-au1x00/au1000.h>
 #include <asm/mach-au1x00/au1xxx_dbdma.h>
 #include <asm/mach-au1x00/au1100_mmc.h>
-#include <asm/scatterlist.h>
 
 #include <au1xxx.h>
 #include "au1xmmc.h"
diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index d0eb0a2abf4..95244a7e735 100644
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -20,11 +20,11 @@
 #include <linux/mmc/host.h>
 #include <linux/amba/bus.h>
 #include <linux/clk.h>
+#include <linux/scatterlist.h>
 
 #include <asm/cacheflush.h>
 #include <asm/div64.h>
 #include <asm/io.h>
-#include <asm/scatterlist.h>
 #include <asm/sizes.h>
 #include <asm/mach/mmc.h>
 
@@ -167,7 +167,7 @@ mmci_data_irq(struct mmci_host *host, struct mmc_data *data,
 		 * partially written to a page is properly coherent.
 		 */
 		if (host->sg_len && data->flags & MMC_DATA_READ)
-			flush_dcache_page(host->sg_ptr->page);
+			flush_dcache_page(sg_page(host->sg_ptr));
 	}
 	if (status & MCI_DATAEND) {
 		mmci_stop_data(host);
@@ -319,7 +319,7 @@ static irqreturn_t mmci_pio_irq(int irq, void *dev_id)
 		 * page, ensure that the data cache is coherent.
 		 */
 		if (status & MCI_RXACTIVE)
-			flush_dcache_page(host->sg_ptr->page);
+			flush_dcache_page(sg_page(host->sg_ptr));
 
 		if (!mmci_next_sg(host))
 			break;
diff --git a/drivers/mmc/host/pxamci.c b/drivers/mmc/host/pxamci.c
index 0601e01aa2c..a25ee71998a 100644
--- a/drivers/mmc/host/pxamci.c
+++ b/drivers/mmc/host/pxamci.c
@@ -29,7 +29,6 @@
 
 #include <asm/dma.h>
 #include <asm/io.h>
-#include <asm/scatterlist.h>
 #include <asm/sizes.h>
 
 #include <asm/arch/pxa-regs.h>
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index d7c5b94d8c5..6b80bf77a4e 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -17,8 +17,6 @@
 
 #include <linux/mmc/host.h>
 
-#include <asm/scatterlist.h>
-
 #include "sdhci.h"
 
 #define DRIVER_NAME "sdhci"
diff --git a/drivers/mmc/host/wbsd.c b/drivers/mmc/host/wbsd.c
index fa4c8c53cc7..4d5f3742187 100644
--- a/drivers/mmc/host/wbsd.c
+++ b/drivers/mmc/host/wbsd.c
@@ -33,10 +33,10 @@
 #include <linux/pnp.h>
 #include <linux/highmem.h>
 #include <linux/mmc/host.h>
+#include <linux/scatterlist.h>
 
 #include <asm/io.h>
 #include <asm/dma.h>
-#include <asm/scatterlist.h>
 
 #include "wbsd.h"
 
-- 
cgit v1.2.3-18-g5258


From 18ccc4194389c6edc78ede76ada3bf753525b11c Mon Sep 17 00:00:00 2001
From: Haavard Skinnemoen <hskinnemoen@atmel.com>
Date: Wed, 24 Oct 2007 10:16:02 +0200
Subject: AVR32: Fix sg_page breakage
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

The latest sg changes introduce the following build errors on AVR32:

include/asm/dma-mapping.h: In function ‘dma_map_sg’:
include/asm/dma-mapping.h:220: error: implicit declaration of function ‘sg_page’
include/asm/dma-mapping.h:220: error: invalid operands to binary -
include/asm/dma-mapping.h:221: error: implicit declaration of function ‘sg_virt’
include/asm/dma-mapping.h:221: warning: assignment makes pointer from integer without a cast
include/asm/dma-mapping.h: In function ‘dma_sync_sg_for_device’:
include/asm/dma-mapping.h:330: warning: passing argument 2 of ‘dma_cache_sync’ makes pointer from integer without a cast

Fix it by including the correct header file, i.e. linux/scatterlist.h
instead of asm/scatterlist.h.

Signed-off-by: Haavard Skinnemoen <hskinnemoen@atmel.com>
---
 include/asm-avr32/dma-mapping.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/asm-avr32/dma-mapping.h b/include/asm-avr32/dma-mapping.h
index a7131630c05..57dc672bab8 100644
--- a/include/asm-avr32/dma-mapping.h
+++ b/include/asm-avr32/dma-mapping.h
@@ -3,7 +3,7 @@
 
 #include <linux/mm.h>
 #include <linux/device.h>
-#include <asm/scatterlist.h>
+#include <linux/scatterlist.h>
 #include <asm/processor.h>
 #include <asm/cacheflush.h>
 #include <asm/io.h>
-- 
cgit v1.2.3-18-g5258


From 642f149031d70415d9318b919d50b71e4724adbd Mon Sep 17 00:00:00 2001
From: Jens Axboe <jens.axboe@oracle.com>
Date: Wed, 24 Oct 2007 11:20:47 +0200
Subject: SG: Change sg_set_page() to take length and offset argument

Most drivers need to set length and offset as well, so may as well fold
those three lines into one.

Add sg_assign_page() for those two locations that only needed to set
the page, where the offset/length is set outside of the function context.

Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
---
 block/ll_rw_blk.c                           |  4 +--
 crypto/hmac.c                               |  3 +--
 drivers/ata/libata-core.c                   |  4 +--
 drivers/block/cryptoloop.c                  |  9 ++-----
 drivers/block/ub.c                          |  9 +++----
 drivers/ieee1394/dma.c                      |  4 +--
 drivers/infiniband/core/umem.c              |  4 +--
 drivers/infiniband/hw/mthca/mthca_memfree.c |  9 +++----
 drivers/md/dm-crypt.c                       |  8 ++----
 drivers/media/common/saa7146_core.c         |  3 +--
 drivers/media/video/ivtv/ivtv-udma.c        |  6 ++---
 drivers/media/video/videobuf-dma-sg.c       | 10 +++-----
 drivers/net/mlx4/icm.c                      |  4 +--
 drivers/s390/scsi/zfcp_aux.c                | 10 +++-----
 drivers/s390/scsi/zfcp_def.h                |  3 +--
 drivers/s390/scsi/zfcp_erp.c                |  7 ++---
 drivers/scsi/ipr.c                          |  2 +-
 drivers/scsi/iscsi_tcp.c                    |  4 +--
 drivers/scsi/osst.c                         |  6 ++---
 drivers/scsi/sg.c                           | 13 +++-------
 drivers/scsi/st.c                           | 14 ++++------
 fs/ecryptfs/crypto.c                        | 23 +++++------------
 include/asm-frv/scatterlist.h               |  3 +--
 include/linux/scatterlist.h                 | 40 +++++++++++++++++++++--------
 net/core/skbuff.c                           |  9 +++----
 net/ieee80211/ieee80211_crypt_tkip.c        |  9 ++-----
 net/sctp/auth.c                             |  4 +--
 net/sctp/sm_make_chunk.c                    |  8 ++----
 net/sunrpc/auth_gss/gss_krb5_crypto.c       | 14 +++++-----
 net/sunrpc/xdr.c                            |  4 +--
 net/xfrm/xfrm_algo.c                        |  9 +++----
 31 files changed, 98 insertions(+), 161 deletions(-)

diff --git a/block/ll_rw_blk.c b/block/ll_rw_blk.c
index de5ba479c22..b01dee3ae7f 100644
--- a/block/ll_rw_blk.c
+++ b/block/ll_rw_blk.c
@@ -1366,9 +1366,7 @@ new_segment:
 				sg = sg_next(sg);
 			}
 
-			sg_set_page(sg, bvec->bv_page);
-			sg->length = nbytes;
-			sg->offset = bvec->bv_offset;
+			sg_set_page(sg, bvec->bv_page, nbytes, bvec->bv_offset);
 			nsegs++;
 		}
 		bvprv = bvec;
diff --git a/crypto/hmac.c b/crypto/hmac.c
index e4eb6ac53b5..6691981bda1 100644
--- a/crypto/hmac.c
+++ b/crypto/hmac.c
@@ -160,8 +160,7 @@ static int hmac_digest(struct hash_desc *pdesc, struct scatterlist *sg,
 
 	sg_set_buf(sg1, ipad, bs);
 
-	sg_set_page(&sg[1], (void *) sg);
-	sg1[1].length = 0;
+	sg_set_page(&sg[1], (void *) sg, 0, 0);
 	sg_set_buf(sg2, opad, bs + ds);
 
 	err = crypto_hash_digest(&desc, sg1, nbytes + bs, digest);
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index 2d147b51c97..b5f7c591306 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -4689,8 +4689,8 @@ static int ata_sg_setup(struct ata_queued_cmd *qc)
 		 * data in this function or read data in ata_sg_clean.
 		 */
 		offset = lsg->offset + lsg->length - qc->pad_len;
-		sg_set_page(psg, nth_page(sg_page(lsg), offset >> PAGE_SHIFT));
-		psg->offset = offset_in_page(offset);
+		sg_set_page(psg, nth_page(sg_page(lsg), offset >> PAGE_SHIFT),
+				qc->pad_len, offset_in_page(offset));
 
 		if (qc->tf.flags & ATA_TFLAG_WRITE) {
 			void *addr = kmap_atomic(sg_page(psg), KM_IRQ0);
diff --git a/drivers/block/cryptoloop.c b/drivers/block/cryptoloop.c
index 1b58b010797..241167878ed 100644
--- a/drivers/block/cryptoloop.c
+++ b/drivers/block/cryptoloop.c
@@ -150,13 +150,8 @@ cryptoloop_transfer(struct loop_device *lo, int cmd,
 		u32 iv[4] = { 0, };
 		iv[0] = cpu_to_le32(IV & 0xffffffff);
 
-		sg_set_page(&sg_in, in_page);
-		sg_in.offset = in_offs;
-		sg_in.length = sz;
-
-		sg_set_page(&sg_out, out_page);
-		sg_out.offset = out_offs;
-		sg_out.length = sz;
+		sg_set_page(&sg_in, in_page, sz, in_offs);
+		sg_set_page(&sg_out, out_page, sz, out_offs);
 
 		desc.info = iv;
 		err = encdecfunc(&desc, &sg_out, &sg_in, sz);
diff --git a/drivers/block/ub.c b/drivers/block/ub.c
index 14143f2c484..5e740e14ab3 100644
--- a/drivers/block/ub.c
+++ b/drivers/block/ub.c
@@ -1428,9 +1428,8 @@ static void ub_state_sense(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
 	scmd->state = UB_CMDST_INIT;
 	scmd->nsg = 1;
 	sg = &scmd->sgv[0];
-	sg_set_page(sg, virt_to_page(sc->top_sense));
-	sg->offset = (unsigned long)sc->top_sense & (PAGE_SIZE-1);
-	sg->length = UB_SENSE_SIZE;
+	sg_set_page(sg, virt_to_page(sc->top_sense), UB_SENSE_SIZE,
+			(unsigned long)sc->top_sense & (PAGE_SIZE-1));
 	scmd->len = UB_SENSE_SIZE;
 	scmd->lun = cmd->lun;
 	scmd->done = ub_top_sense_done;
@@ -1864,9 +1863,7 @@ static int ub_sync_read_cap(struct ub_dev *sc, struct ub_lun *lun,
 	cmd->state = UB_CMDST_INIT;
 	cmd->nsg = 1;
 	sg = &cmd->sgv[0];
-	sg_set_page(sg, virt_to_page(p));
-	sg->offset = (unsigned long)p & (PAGE_SIZE-1);
-	sg->length = 8;
+	sg_set_page(sg, virt_to_page(p), 8, (unsigned long)p & (PAGE_SIZE-1));
 	cmd->len = 8;
 	cmd->lun = lun;
 	cmd->done = ub_probe_done;
diff --git a/drivers/ieee1394/dma.c b/drivers/ieee1394/dma.c
index 3051e312fdc..f5f4983dfbf 100644
--- a/drivers/ieee1394/dma.c
+++ b/drivers/ieee1394/dma.c
@@ -111,8 +111,8 @@ int dma_region_alloc(struct dma_region *dma, unsigned long n_bytes,
 		unsigned long va =
 		    (unsigned long)dma->kvirt + (i << PAGE_SHIFT);
 
-		sg_set_page(&dma->sglist[i], vmalloc_to_page((void *)va));
-		dma->sglist[i].length = PAGE_SIZE;
+		sg_set_page(&dma->sglist[i], vmalloc_to_page((void *)va),
+				PAGE_SIZE, 0);
 	}
 
 	/* map sglist to the IOMMU */
diff --git a/drivers/infiniband/core/umem.c b/drivers/infiniband/core/umem.c
index 14159ff2940..4e3128ff73c 100644
--- a/drivers/infiniband/core/umem.c
+++ b/drivers/infiniband/core/umem.c
@@ -171,9 +171,7 @@ struct ib_umem *ib_umem_get(struct ib_ucontext *context, unsigned long addr,
 				if (vma_list &&
 				    !is_vm_hugetlb_page(vma_list[i + off]))
 					umem->hugetlb = 0;
-				sg_set_page(&chunk->page_list[i], page_list[i + off]);
-				chunk->page_list[i].offset = 0;
-				chunk->page_list[i].length = PAGE_SIZE;
+				sg_set_page(&chunk->page_list[i], page_list[i + off], PAGE_SIZE, 0);
 			}
 
 			chunk->nmap = ib_dma_map_sg(context->device,
diff --git a/drivers/infiniband/hw/mthca/mthca_memfree.c b/drivers/infiniband/hw/mthca/mthca_memfree.c
index 007b38157fc..1f4d27d7c16 100644
--- a/drivers/infiniband/hw/mthca/mthca_memfree.c
+++ b/drivers/infiniband/hw/mthca/mthca_memfree.c
@@ -113,9 +113,7 @@ static int mthca_alloc_icm_pages(struct scatterlist *mem, int order, gfp_t gfp_m
 	if (!page)
 		return -ENOMEM;
 
-	sg_set_page(mem, page);
-	mem->length = PAGE_SIZE << order;
-	mem->offset = 0;
+	sg_set_page(mem, page, PAGE_SIZE << order, 0);
 	return 0;
 }
 
@@ -481,9 +479,8 @@ int mthca_map_user_db(struct mthca_dev *dev, struct mthca_uar *uar,
 	if (ret < 0)
 		goto out;
 
-	sg_set_page(&db_tab->page[i].mem, pages[0]);
-	db_tab->page[i].mem.length = MTHCA_ICM_PAGE_SIZE;
-	db_tab->page[i].mem.offset = uaddr & ~PAGE_MASK;
+	sg_set_page(&db_tab->page[i].mem, pages[0], MTHCA_ICM_PAGE_SIZE,
+			uaddr & ~PAGE_MASK);
 
 	ret = pci_map_sg(dev->pdev, &db_tab->page[i].mem, 1, PCI_DMA_TODEVICE);
 	if (ret < 0) {
diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c
index ac54f697c50..1c159ac68c9 100644
--- a/drivers/md/dm-crypt.c
+++ b/drivers/md/dm-crypt.c
@@ -351,14 +351,10 @@ static int crypt_convert(struct crypt_config *cc,
 		struct scatterlist sg_in, sg_out;
 
 		sg_init_table(&sg_in, 1);
-		sg_set_page(&sg_in, bv_in->bv_page);
-		sg_in.offset = bv_in->bv_offset + ctx->offset_in;
-		sg_in.length = 1 << SECTOR_SHIFT;
+		sg_set_page(&sg_in, bv_in->bv_page, 1 << SECTOR_SHIFT, bv_in->bv_offset + ctx->offset_in);
 
 		sg_init_table(&sg_out, 1);
-		sg_set_page(&sg_out, bv_out->bv_page);
-		sg_out.offset = bv_out->bv_offset + ctx->offset_out;
-		sg_out.length = 1 << SECTOR_SHIFT;
+		sg_set_page(&sg_out, bv_out->bv_page, 1 << SECTOR_SHIFT, bv_out->bv_offset + ctx->offset_out);
 
 		ctx->offset_in += sg_in.length;
 		if (ctx->offset_in >= bv_in->bv_len) {
diff --git a/drivers/media/common/saa7146_core.c b/drivers/media/common/saa7146_core.c
index 2b1f8b4be00..cb034ead95a 100644
--- a/drivers/media/common/saa7146_core.c
+++ b/drivers/media/common/saa7146_core.c
@@ -118,8 +118,7 @@ static struct scatterlist* vmalloc_to_sg(unsigned char *virt, int nr_pages)
 		if (NULL == pg)
 			goto err;
 		BUG_ON(PageHighMem(pg));
-		sg_set_page(&sglist[i], pg);
-		sglist[i].length = PAGE_SIZE;
+		sg_set_page(&sglist[i], pg, PAGE_SIZE, 0);
 	}
 	return sglist;
 
diff --git a/drivers/media/video/ivtv/ivtv-udma.c b/drivers/media/video/ivtv/ivtv-udma.c
index 912b424e520..460db03b0ba 100644
--- a/drivers/media/video/ivtv/ivtv-udma.c
+++ b/drivers/media/video/ivtv/ivtv-udma.c
@@ -49,8 +49,6 @@ int ivtv_udma_fill_sg_list (struct ivtv_user_dma *dma, struct ivtv_dma_page_info
 		unsigned int len = (i == dma_page->page_count - 1) ?
 			dma_page->tail : PAGE_SIZE - offset;
 
-		dma->SGlist[map_offset].length = len;
-		dma->SGlist[map_offset].offset = offset;
 		if (PageHighMem(dma->map[map_offset])) {
 			void *src;
 
@@ -63,10 +61,10 @@ int ivtv_udma_fill_sg_list (struct ivtv_user_dma *dma, struct ivtv_dma_page_info
 			memcpy(page_address(dma->bouncemap[map_offset]) + offset, src, len);
 			kunmap_atomic(src, KM_BOUNCE_READ);
 			local_irq_restore(flags);
-			sg_set_page(&dma->SGlist[map_offset], dma->bouncemap[map_offset]);
+			sg_set_page(&dma->SGlist[map_offset], dma->bouncemap[map_offset], len, offset);
 		}
 		else {
-			sg_set_page(&dma->SGlist[map_offset], dma->map[map_offset]);
+			sg_set_page(&dma->SGlist[map_offset], dma->map[map_offset], len, offset);
 		}
 		offset = 0;
 		map_offset++;
diff --git a/drivers/media/video/videobuf-dma-sg.c b/drivers/media/video/videobuf-dma-sg.c
index 9ab94a749d8..44ee408e145 100644
--- a/drivers/media/video/videobuf-dma-sg.c
+++ b/drivers/media/video/videobuf-dma-sg.c
@@ -67,8 +67,7 @@ videobuf_vmalloc_to_sg(unsigned char *virt, int nr_pages)
 		if (NULL == pg)
 			goto err;
 		BUG_ON(PageHighMem(pg));
-		sg_set_page(&sglist[i], pg);
-		sglist[i].length = PAGE_SIZE;
+		sg_set_page(&sglist[i], pg, PAGE_SIZE, 0);
 	}
 	return sglist;
 
@@ -95,16 +94,13 @@ videobuf_pages_to_sg(struct page **pages, int nr_pages, int offset)
 	if (PageHighMem(pages[0]))
 		/* DMA to highmem pages might not work */
 		goto highmem;
-	sg_set_page(&sglist[0], pages[0]);
-	sglist[0].offset = offset;
-	sglist[0].length = PAGE_SIZE - offset;
+	sg_set_page(&sglist[0], pages[0], PAGE_SIZE - offset, offset);
 	for (i = 1; i < nr_pages; i++) {
 		if (NULL == pages[i])
 			goto nopage;
 		if (PageHighMem(pages[i]))
 			goto highmem;
-		sg_set_page(&sglist[i], pages[i]);
-		sglist[i].length = PAGE_SIZE;
+		sg_set_page(&sglist[i], pages[i], PAGE_SIZE, 0);
 	}
 	return sglist;
 
diff --git a/drivers/net/mlx4/icm.c b/drivers/net/mlx4/icm.c
index 887633b207d..2a5bef6388f 100644
--- a/drivers/net/mlx4/icm.c
+++ b/drivers/net/mlx4/icm.c
@@ -101,9 +101,7 @@ static int mlx4_alloc_icm_pages(struct scatterlist *mem, int order, gfp_t gfp_ma
 	if (!page)
 		return -ENOMEM;
 
-	sg_set_page(mem, page);
-	mem->length = PAGE_SIZE << order;
-	mem->offset = 0;
+	sg_set_page(mem, page, PAGE_SIZE << order, 0);
 	return 0;
 }
 
diff --git a/drivers/s390/scsi/zfcp_aux.c b/drivers/s390/scsi/zfcp_aux.c
index d9e7be97976..00118499018 100644
--- a/drivers/s390/scsi/zfcp_aux.c
+++ b/drivers/s390/scsi/zfcp_aux.c
@@ -562,8 +562,6 @@ zfcp_sg_list_alloc(struct zfcp_sg_list *sg_list, size_t size)
 	sg_init_table(sg_list->sg, sg_list->count);
 
 	for (i = 0, sg = sg_list->sg; i < sg_list->count; i++, sg++) {
-		sg->length = min(size, PAGE_SIZE);
-		sg->offset = 0;
 		address = (void *) get_zeroed_page(GFP_KERNEL);
 		if (address == NULL) {
 			sg_list->count = i;
@@ -571,7 +569,7 @@ zfcp_sg_list_alloc(struct zfcp_sg_list *sg_list, size_t size)
 			retval = -ENOMEM;
 			goto out;
 		}
-		zfcp_address_to_sg(address, sg);
+		zfcp_address_to_sg(address, sg, min(size, PAGE_SIZE));
 		size -= sg->length;
 	}
 
@@ -1523,10 +1521,8 @@ zfcp_gid_pn_buffers_alloc(struct zfcp_gid_pn_data **gid_pn, mempool_t *pool)
         data->ct.req = &data->req;
         data->ct.resp = &data->resp;
 	data->ct.req_count = data->ct.resp_count = 1;
-	zfcp_address_to_sg(&data->ct_iu_req, &data->req);
-        zfcp_address_to_sg(&data->ct_iu_resp, &data->resp);
-        data->req.length = sizeof(struct ct_iu_gid_pn_req);
-        data->resp.length = sizeof(struct ct_iu_gid_pn_resp);
+	zfcp_address_to_sg(&data->ct_iu_req, &data->req, sizeof(struct ct_iu_gid_pn_req));
+        zfcp_address_to_sg(&data->ct_iu_resp, &data->resp, sizeof(struct ct_iu_gid_pn_resp));
 
 	*gid_pn = data;
 	return 0;
diff --git a/drivers/s390/scsi/zfcp_def.h b/drivers/s390/scsi/zfcp_def.h
index 326e7ee232c..0754542978b 100644
--- a/drivers/s390/scsi/zfcp_def.h
+++ b/drivers/s390/scsi/zfcp_def.h
@@ -74,8 +74,7 @@ zfcp_sg_to_address(struct scatterlist *list)
 static inline void
 zfcp_address_to_sg(void *address, struct scatterlist *list)
 {
-	sg_set_page(list, virt_to_page(address));
-	list->offset = ((unsigned long) address) & (PAGE_SIZE - 1);
+	sg_set_buf(list, address, 0);
 }
 
 #define REQUEST_LIST_SIZE 128
diff --git a/drivers/s390/scsi/zfcp_erp.c b/drivers/s390/scsi/zfcp_erp.c
index 9438d0b2879..5552b755c08 100644
--- a/drivers/s390/scsi/zfcp_erp.c
+++ b/drivers/s390/scsi/zfcp_erp.c
@@ -322,9 +322,9 @@ zfcp_erp_adisc(struct zfcp_port *port)
 	if (address == NULL)
 		goto nomem;
 
-	zfcp_address_to_sg(address, send_els->req);
+	zfcp_address_to_sg(address, send_els->req, sizeof(struct zfcp_ls_adisc));
 	address += PAGE_SIZE >> 1;
-	zfcp_address_to_sg(address, send_els->resp);
+	zfcp_address_to_sg(address, send_els->resp, sizeof(struct zfcp_ls_adisc_acc));
 	send_els->req_count = send_els->resp_count = 1;
 
 	send_els->adapter = adapter;
@@ -336,9 +336,6 @@ zfcp_erp_adisc(struct zfcp_port *port)
 	adisc = zfcp_sg_to_address(send_els->req);
 	send_els->ls_code = adisc->code = ZFCP_LS_ADISC;
 
-	send_els->req->length = sizeof(struct zfcp_ls_adisc);
-	send_els->resp->length = sizeof(struct zfcp_ls_adisc_acc);
-
 	/* acc. to FC-FS, hard_nport_id in ADISC should not be set for ports
 	   without FC-AL-2 capability, so we don't set it */
 	adisc->wwpn = fc_host_port_name(adapter->scsi_host);
diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c
index 439b97a6a26..0841df01bc1 100644
--- a/drivers/scsi/ipr.c
+++ b/drivers/scsi/ipr.c
@@ -2890,7 +2890,7 @@ static struct ipr_sglist *ipr_alloc_ucode_buffer(int buf_len)
 			return NULL;
 		}
 
-		sg_set_page(&scatterlist[i], page);
+		sg_set_page(&scatterlist[i], page, 0, 0);
 	}
 
 	return sglist;
diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c
index 6ce4109efdf..097a136398c 100644
--- a/drivers/scsi/iscsi_tcp.c
+++ b/drivers/scsi/iscsi_tcp.c
@@ -79,9 +79,7 @@ static inline void
 iscsi_buf_init_sg(struct iscsi_buf *ibuf, struct scatterlist *sg)
 {
 	sg_init_table(&ibuf->sg, 1);
-	sg_set_page(&ibuf->sg, sg_page(sg));
-	ibuf->sg.offset = sg->offset;
-	ibuf->sg.length = sg->length;
+	sg_set_page(&ibuf->sg, sg_page(sg), sg->length, sg->offset);
 	/*
 	 * Fastpath: sg element fits into single page
 	 */
diff --git a/drivers/scsi/osst.c b/drivers/scsi/osst.c
index 1c5c4b68f20..4652ad22516 100644
--- a/drivers/scsi/osst.c
+++ b/drivers/scsi/osst.c
@@ -5256,8 +5256,7 @@ static int enlarge_buffer(struct osst_buffer *STbuffer, int need_dma)
 
 		STbuffer->sg[0].offset = 0;
 		if (page != NULL) {
-		    sg_set_page(&STbuffer->sg[0], page);
-		    STbuffer->sg[0].length = b_size;
+		    sg_set_page(&STbuffer->sg[0], page, b_size, 0);
 		    STbuffer->b_data = page_address(page);
 		    break;
 		}
@@ -5285,8 +5284,7 @@ static int enlarge_buffer(struct osst_buffer *STbuffer, int need_dma)
 			normalize_buffer(STbuffer);
 			return 0;
 		}
-		sg_set_page(&STbuffer->sg[segs], page);
-		STbuffer->sg[segs].length = (OS_FRAME_SIZE - got <= PAGE_SIZE / 2) ? (OS_FRAME_SIZE - got) : b_size;
+		sg_set_page(&STbuffer->sg[segs], page, (OS_FRAME_SIZE - got <= PAGE_SIZE / 2) ? (OS_FRAME_SIZE - got) : b_size, 0);
 		got += STbuffer->sg[segs].length;
 		STbuffer->buffer_size = got;
 		STbuffer->sg_segs = ++segs;
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
index cc197100284..b5fa4f09138 100644
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -1717,16 +1717,12 @@ st_map_user_pages(struct scatterlist *sgl, const unsigned int max_pages,
 		   goto out_unlock; */
         }
 
-	sg_set_page(sgl, pages[0]);
-	sgl[0].offset = uaddr & ~PAGE_MASK;
+	sg_set_page(sgl, pages[0], 0, uaddr & ~PAGE_MASK);
 	if (nr_pages > 1) {
 		sgl[0].length = PAGE_SIZE - sgl[0].offset;
 		count -= sgl[0].length;
-		for (i=1; i < nr_pages ; i++) {
-			sg_set_page(&sgl[i], pages[i]);
-			sgl[i].length = count < PAGE_SIZE ? count : PAGE_SIZE;
-			count -= PAGE_SIZE;
-		}
+		for (i=1; i < nr_pages ; i++)
+			sg_set_page(&sgl[i], pages[i], count < PAGE_SIZE ? count : PAGE_SIZE, 0);
 	}
 	else {
 		sgl[0].length = count;
@@ -1854,8 +1850,7 @@ sg_build_indirect(Sg_scatter_hold * schp, Sg_fd * sfp, int buff_size)
 				scatter_elem_sz_prev = ret_sz;
 			}
 		}
-		sg_set_page(sg, p);
-		sg->length = (ret_sz > num) ? num : ret_sz;
+		sg_set_page(sg, p, (ret_sz > num) ? num : ret_sz, 0);
 
 		SCSI_LOG_TIMEOUT(5, printk("sg_build_indirect: k=%d, num=%d, "
 				 "ret_sz=%d\n", k, num, ret_sz));
diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c
index ce69b9efc10..98dfd6ea209 100644
--- a/drivers/scsi/st.c
+++ b/drivers/scsi/st.c
@@ -3797,13 +3797,11 @@ static void buf_to_sg(struct st_buffer *STbp, unsigned int length)
 	sg = &(STbp->sg[0]);
 	frp = STbp->frp;
 	for (i=count=0; count < length; i++) {
-		sg_set_page(&sg[i], frp[i].page);
 		if (length - count > frp[i].length)
-			sg[i].length = frp[i].length;
+			sg_set_page(&sg[i], frp[i].page, frp[i].length, 0);
 		else
-			sg[i].length = length - count;
+			sg_set_page(&sg[i], frp[i].page, length - count, 0);
 		count += sg[i].length;
-		sg[i].offset = 0;
 	}
 	STbp->sg_segs = i;
 	STbp->frp_sg_current = length;
@@ -4446,15 +4444,13 @@ static int sgl_map_user_pages(struct scatterlist *sgl, const unsigned int max_pa
         }
 
 	/* Populate the scatter/gather list */
-	sg_set_page(&sgl[0], pages[0]);
-	sgl[0].offset = uaddr & ~PAGE_MASK;
+	sg_set_page(&sgl[0], pages[0], 0, uaddr & ~PAGE_MASK);
 	if (nr_pages > 1) {
 		sgl[0].length = PAGE_SIZE - sgl[0].offset;
 		count -= sgl[0].length;
 		for (i=1; i < nr_pages ; i++) {
-			sg_set_page(&sgl[i], pages[i]);;
-			sgl[i].offset = 0;
-			sgl[i].length = count < PAGE_SIZE ? count : PAGE_SIZE;
+			sg_set_page(&sgl[i], pages[i],
+				    count < PAGE_SIZE ? count : PAGE_SIZE, 0);;
 			count -= PAGE_SIZE;
 		}
 	}
diff --git a/fs/ecryptfs/crypto.c b/fs/ecryptfs/crypto.c
index 0a9882edf56..7a472b12999 100644
--- a/fs/ecryptfs/crypto.c
+++ b/fs/ecryptfs/crypto.c
@@ -282,10 +282,8 @@ int virt_to_scatterlist(const void *addr, int size, struct scatterlist *sg,
 	while (size > 0 && i < sg_size) {
 		pg = virt_to_page(addr);
 		offset = offset_in_page(addr);
-		if (sg) {
-			sg_set_page(&sg[i], pg);
-			sg[i].offset = offset;
-		}
+		if (sg)
+			sg_set_page(&sg[i], pg, 0, offset);
 		remainder_of_page = PAGE_CACHE_SIZE - offset;
 		if (size >= remainder_of_page) {
 			if (sg)
@@ -716,12 +714,8 @@ ecryptfs_encrypt_page_offset(struct ecryptfs_crypt_stat *crypt_stat,
 	sg_init_table(&src_sg, 1);
 	sg_init_table(&dst_sg, 1);
 
-	sg_set_page(&src_sg, src_page);
-	src_sg.offset = src_offset;
-	src_sg.length = size;
-	sg_set_page(&dst_sg, dst_page);
-	dst_sg.offset = dst_offset;
-	dst_sg.length = size;
+	sg_set_page(&src_sg, src_page, size, src_offset);
+	sg_set_page(&dst_sg, dst_page, size, dst_offset);
 	return encrypt_scatterlist(crypt_stat, &dst_sg, &src_sg, size, iv);
 }
 
@@ -746,14 +740,11 @@ ecryptfs_decrypt_page_offset(struct ecryptfs_crypt_stat *crypt_stat,
 	struct scatterlist src_sg, dst_sg;
 
 	sg_init_table(&src_sg, 1);
+	sg_set_page(&src_sg, src_page, size, src_offset);
+
 	sg_init_table(&dst_sg, 1);
+	sg_set_page(&dst_sg, dst_page, size, dst_offset);
 
-	sg_set_page(&src_sg, src_page);
-	src_sg.offset = src_offset;
-	src_sg.length = size;
-	sg_set_page(&dst_sg, dst_page);
-	dst_sg.offset = dst_offset;
-	dst_sg.length = size;
 	return decrypt_scatterlist(crypt_stat, &dst_sg, &src_sg, size, iv);
 }
 
diff --git a/include/asm-frv/scatterlist.h b/include/asm-frv/scatterlist.h
index 99ba76edc42..2e7143b5a7a 100644
--- a/include/asm-frv/scatterlist.h
+++ b/include/asm-frv/scatterlist.h
@@ -16,8 +16,7 @@
  *
  * can be rewritten as
  *
- * sg_set_page(virt_to_page(some_ptr));
- * sg->offset = (unsigned long) some_ptr & ~PAGE_MASK;
+ * sg_set_buf(sg, some_ptr, length);
  *
  * and that's it. There's no excuse for not highmem enabling YOUR driver. /jens
  */
diff --git a/include/linux/scatterlist.h b/include/linux/scatterlist.h
index df7ddcee7c4..809b2ac2e37 100644
--- a/include/linux/scatterlist.h
+++ b/include/linux/scatterlist.h
@@ -26,18 +26,16 @@
 #define SG_MAGIC	0x87654321
 
 /**
- * sg_set_page - Set sg entry to point at given page
- * @sg:		 SG entry
- * @page:	 The page
+ * sg_assign_page - Assign a given page to an SG entry
+ * @sg:		    SG entry
+ * @page:	    The page
  *
  * Description:
- *   Use this function to set an sg entry pointing at a page, never assign
- *   the page directly. We encode sg table information in the lower bits
- *   of the page pointer. See sg_page() for looking up the page belonging
- *   to an sg entry.
+ *   Assign page to sg entry. Also see sg_set_page(), the most commonly used
+ *   variant.
  *
  **/
-static inline void sg_set_page(struct scatterlist *sg, struct page *page)
+static inline void sg_assign_page(struct scatterlist *sg, struct page *page)
 {
 	unsigned long page_link = sg->page_link & 0x3;
 
@@ -52,6 +50,28 @@ static inline void sg_set_page(struct scatterlist *sg, struct page *page)
 	sg->page_link = page_link | (unsigned long) page;
 }
 
+/**
+ * sg_set_page - Set sg entry to point at given page
+ * @sg:		 SG entry
+ * @page:	 The page
+ * @len:	 Length of data
+ * @offset:	 Offset into page
+ *
+ * Description:
+ *   Use this function to set an sg entry pointing at a page, never assign
+ *   the page directly. We encode sg table information in the lower bits
+ *   of the page pointer. See sg_page() for looking up the page belonging
+ *   to an sg entry.
+ *
+ **/
+static inline void sg_set_page(struct scatterlist *sg, struct page *page,
+			       unsigned int len, unsigned int offset)
+{
+	sg_assign_page(sg, page);
+	sg->offset = offset;
+	sg->length = len;
+}
+
 #define sg_page(sg)	((struct page *) ((sg)->page_link & ~0x3))
 
 /**
@@ -64,9 +84,7 @@ static inline void sg_set_page(struct scatterlist *sg, struct page *page)
 static inline void sg_set_buf(struct scatterlist *sg, const void *buf,
 			      unsigned int buflen)
 {
-	sg_set_page(sg, virt_to_page(buf));
-	sg->offset = offset_in_page(buf);
-	sg->length = buflen;
+	sg_set_page(sg, virt_to_page(buf), buflen, offset_in_page(buf));
 }
 
 /*
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 4e2c84fcf27..7b7c6c44c2d 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -2045,9 +2045,7 @@ skb_to_sgvec(struct sk_buff *skb, struct scatterlist *sg, int offset, int len)
 	if (copy > 0) {
 		if (copy > len)
 			copy = len;
-		sg_set_page(&sg[elt], virt_to_page(skb->data + offset));
-		sg[elt].offset = (unsigned long)(skb->data + offset) % PAGE_SIZE;
-		sg[elt].length = copy;
+		sg_set_buf(sg, skb->data + offset, copy);
 		elt++;
 		if ((len -= copy) == 0)
 			return elt;
@@ -2065,9 +2063,8 @@ skb_to_sgvec(struct sk_buff *skb, struct scatterlist *sg, int offset, int len)
 
 			if (copy > len)
 				copy = len;
-			sg_set_page(&sg[elt], frag->page);
-			sg[elt].offset = frag->page_offset+offset-start;
-			sg[elt].length = copy;
+			sg_set_page(&sg[elt], frag->page, copy,
+					frag->page_offset+offset-start);
 			elt++;
 			if (!(len -= copy))
 				return elt;
diff --git a/net/ieee80211/ieee80211_crypt_tkip.c b/net/ieee80211/ieee80211_crypt_tkip.c
index 74d017520a2..4cce3534e40 100644
--- a/net/ieee80211/ieee80211_crypt_tkip.c
+++ b/net/ieee80211/ieee80211_crypt_tkip.c
@@ -537,13 +537,8 @@ static int michael_mic(struct crypto_hash *tfm_michael, u8 * key, u8 * hdr,
 		return -1;
 	}
 	sg_init_table(sg, 2);
-	sg_set_page(&sg[0], virt_to_page(hdr));
-	sg[0].offset = offset_in_page(hdr);
-	sg[0].length = 16;
-
-	sg_set_page(&sg[1], virt_to_page(data));
-	sg[1].offset = offset_in_page(data);
-	sg[1].length = data_len;
+	sg_set_buf(&sg[0], hdr, 16);
+	sg_set_buf(&sg[1], data, data_len);
 
 	if (crypto_hash_setkey(tfm_michael, key, 8))
 		return -1;
diff --git a/net/sctp/auth.c b/net/sctp/auth.c
index cbd64b216cc..621113a109b 100644
--- a/net/sctp/auth.c
+++ b/net/sctp/auth.c
@@ -727,9 +727,7 @@ void sctp_auth_calculate_hmac(const struct sctp_association *asoc,
 	/* set up scatter list */
 	end = skb_tail_pointer(skb);
 	sg_init_table(&sg, 1);
-	sg_set_page(&sg, virt_to_page(auth));
-	sg.offset = (unsigned long)(auth) % PAGE_SIZE;
-	sg.length = end - (unsigned char *)auth;
+	sg_set_buf(&sg, auth, end - (unsigned char *)auth);
 
 	desc.tfm = asoc->ep->auth_hmacs[hmac_id];
 	desc.flags = 0;
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
index 658476c4d58..c055212875f 100644
--- a/net/sctp/sm_make_chunk.c
+++ b/net/sctp/sm_make_chunk.c
@@ -1514,9 +1514,7 @@ static sctp_cookie_param_t *sctp_pack_cookie(const struct sctp_endpoint *ep,
 
 		/* Sign the message.  */
 		sg_init_table(&sg, 1);
-		sg_set_page(&sg, virt_to_page(&cookie->c));
-		sg.offset = (unsigned long)(&cookie->c) % PAGE_SIZE;
-		sg.length = bodysize;
+		sg_set_buf(&sg, &cookie->c, bodysize);
 		keylen = SCTP_SECRET_SIZE;
 		key = (char *)ep->secret_key[ep->current_key];
 		desc.tfm = sctp_sk(ep->base.sk)->hmac;
@@ -1587,9 +1585,7 @@ struct sctp_association *sctp_unpack_cookie(
 	/* Check the signature.  */
 	keylen = SCTP_SECRET_SIZE;
 	sg_init_table(&sg, 1);
-	sg_set_page(&sg, virt_to_page(bear_cookie));
-	sg.offset = (unsigned long)(bear_cookie) % PAGE_SIZE;
-	sg.length = bodysize;
+	sg_set_buf(&sg, bear_cookie, bodysize);
 	key = (char *)ep->secret_key[ep->current_key];
 	desc.tfm = sctp_sk(ep->base.sk)->hmac;
 	desc.flags = 0;
diff --git a/net/sunrpc/auth_gss/gss_krb5_crypto.c b/net/sunrpc/auth_gss/gss_krb5_crypto.c
index 32be431affc..24711be4b2d 100644
--- a/net/sunrpc/auth_gss/gss_krb5_crypto.c
+++ b/net/sunrpc/auth_gss/gss_krb5_crypto.c
@@ -199,7 +199,7 @@ encryptor(struct scatterlist *sg, void *data)
 	} else {
 		in_page = sg_page(sg);
 	}
-	sg_set_page(&desc->infrags[desc->fragno], in_page);
+	sg_assign_page(&desc->infrags[desc->fragno], in_page);
 	desc->fragno++;
 	desc->fraglen += sg->length;
 	desc->pos += sg->length;
@@ -215,11 +215,10 @@ encryptor(struct scatterlist *sg, void *data)
 	if (ret)
 		return ret;
 	if (fraglen) {
-		sg_set_page(&desc->outfrags[0], sg_page(sg));
-		desc->outfrags[0].offset = sg->offset + sg->length - fraglen;
-		desc->outfrags[0].length = fraglen;
+		sg_set_page(&desc->outfrags[0], sg_page(sg), fraglen,
+				sg->offset + sg->length - fraglen);
 		desc->infrags[0] = desc->outfrags[0];
-		sg_set_page(&desc->infrags[0], in_page);
+		sg_assign_page(&desc->infrags[0], in_page);
 		desc->fragno = 1;
 		desc->fraglen = fraglen;
 	} else {
@@ -287,9 +286,8 @@ decryptor(struct scatterlist *sg, void *data)
 	if (ret)
 		return ret;
 	if (fraglen) {
-		sg_set_page(&desc->frags[0], sg_page(sg));
-		desc->frags[0].offset = sg->offset + sg->length - fraglen;
-		desc->frags[0].length = fraglen;
+		sg_set_page(&desc->frags[0], sg_page(sg), fraglen,
+				sg->offset + sg->length - fraglen);
 		desc->fragno = 1;
 		desc->fraglen = fraglen;
 	} else {
diff --git a/net/sunrpc/xdr.c b/net/sunrpc/xdr.c
index 3d1f7cdf9dd..f38dac30481 100644
--- a/net/sunrpc/xdr.c
+++ b/net/sunrpc/xdr.c
@@ -1059,9 +1059,7 @@ xdr_process_buf(struct xdr_buf *buf, unsigned int offset, unsigned int len,
 		do {
 			if (thislen > page_len)
 				thislen = page_len;
-			sg_set_page(sg, buf->pages[i]);
-			sg->offset = page_offset;
-			sg->length = thislen;
+			sg_set_page(sg, buf->pages[i], thislen, page_offset);
 			ret = actor(sg, data);
 			if (ret)
 				goto out;
diff --git a/net/xfrm/xfrm_algo.c b/net/xfrm/xfrm_algo.c
index 313d4bed3aa..fa45989a716 100644
--- a/net/xfrm/xfrm_algo.c
+++ b/net/xfrm/xfrm_algo.c
@@ -553,9 +553,7 @@ int skb_icv_walk(const struct sk_buff *skb, struct hash_desc *desc,
 		if (copy > len)
 			copy = len;
 
-		sg_set_page(&sg, virt_to_page(skb->data + offset));
-		sg.offset = (unsigned long)(skb->data + offset) % PAGE_SIZE;
-		sg.length = copy;
+		sg_set_buf(&sg, skb->data + offset, copy);
 
 		err = icv_update(desc, &sg, copy);
 		if (unlikely(err))
@@ -578,9 +576,8 @@ int skb_icv_walk(const struct sk_buff *skb, struct hash_desc *desc,
 			if (copy > len)
 				copy = len;
 
-			sg_set_page(&sg, frag->page);
-			sg.offset = frag->page_offset + offset-start;
-			sg.length = copy;
+			sg_set_page(&sg, frag->page, copy,
+					frag->page_offset + offset-start);
 
 			err = icv_update(desc, &sg, copy);
 			if (unlikely(err))
-- 
cgit v1.2.3-18-g5258


From 23464ffa47689e46985fb10ae9e34bbc9e83f387 Mon Sep 17 00:00:00 2001
From: WANG Cong <xiyou.wangcong@gmail.com>
Date: Wed, 24 Oct 2007 13:07:11 +0200
Subject: arch/um/drivers/ubd_kern.c: fix a building error

Fix this uml building error:
arch/um/drivers/ubd_kern.c: In function 'do_ubd_request':
arch/um/drivers/ubd_kern.c:1118: error: implicit declaration of function
'sg_page'
arch/um/drivers/ubd_kern.c:1118: warning: passing argument 6 of
'prepare_request' makes pointer from integer without a cast
make[1]: *** [arch/um/drivers/ubd_kern.o] Error 1
make: *** [arch/um/drivers] Error 2

Signed-off-by: WANG Cong <xiyou.wangcong@gmail.com>

Add sg_init_table() call as well.

Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
---
 arch/um/drivers/ubd_kern.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c
index 3a8cd3dfb51..e184b44b101 100644
--- a/arch/um/drivers/ubd_kern.c
+++ b/arch/um/drivers/ubd_kern.c
@@ -35,6 +35,7 @@
 #include "linux/genhd.h"
 #include "linux/spinlock.h"
 #include "linux/platform_device.h"
+#include "linux/scatterlist.h"
 #include "asm/segment.h"
 #include "asm/uaccess.h"
 #include "asm/irq.h"
@@ -704,6 +705,7 @@ static int ubd_add(int n, char **error_out)
 	ubd_dev->size = ROUND_BLOCK(ubd_dev->size);
 
 	INIT_LIST_HEAD(&ubd_dev->restart);
+	sg_init_table(&ubd_dev->sg, MAX_SG);
 
 	err = -ENOMEM;
 	ubd_dev->queue = blk_init_queue(do_ubd_request, &ubd_dev->lock);
-- 
cgit v1.2.3-18-g5258


From 3d1266c7042e696704e22085a0f55c714bc06194 Mon Sep 17 00:00:00 2001
From: Jens Axboe <jens.axboe@oracle.com>
Date: Wed, 24 Oct 2007 13:21:21 +0200
Subject: SG: audit of drivers that use blk_rq_map_sg()

They need to properly init the sg table, or blk_rq_map_sg() will
complain if CONFIG_DEBUG_SG is set.

Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
---
 drivers/block/virtio_blk.c      | 10 ++++++----
 drivers/cdrom/viocd.c           |  3 ++-
 drivers/message/i2o/i2o_block.c |  1 +
 3 files changed, 9 insertions(+), 5 deletions(-)

diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c
index a901eee64ba..3cf7129d83e 100644
--- a/drivers/block/virtio_blk.c
+++ b/drivers/block/virtio_blk.c
@@ -4,7 +4,9 @@
 #include <linux/hdreg.h>
 #include <linux/virtio.h>
 #include <linux/virtio_blk.h>
-#include <linux/virtio_blk.h>
+#include <linux/scatterlist.h>
+
+#define VIRTIO_MAX_SG	(3+MAX_PHYS_SEGMENTS)
 
 static unsigned char virtblk_index = 'a';
 struct virtio_blk
@@ -23,7 +25,7 @@ struct virtio_blk
 	mempool_t *pool;
 
 	/* Scatterlist: can be too big for stack. */
-	struct scatterlist sg[3+MAX_PHYS_SEGMENTS];
+	struct scatterlist sg[VIRTIO_MAX_SG];
 };
 
 struct virtblk_req
@@ -94,8 +96,8 @@ static bool do_req(struct request_queue *q, struct virtio_blk *vblk,
 	if (blk_barrier_rq(vbr->req))
 		vbr->out_hdr.type |= VIRTIO_BLK_T_BARRIER;
 
-	/* We have to zero this, otherwise blk_rq_map_sg gets upset. */
-	memset(vblk->sg, 0, sizeof(vblk->sg));
+	/* This init could be done at vblk creation time */
+	sg_init_table(vblk->sg, VIRTIO_MAX_SG);
 	sg_set_buf(&vblk->sg[0], &vbr->out_hdr, sizeof(vbr->out_hdr));
 	num = blk_rq_map_sg(q, vbr->req, vblk->sg+1);
 	sg_set_buf(&vblk->sg[num+1], &vbr->in_hdr, sizeof(vbr->in_hdr));
diff --git a/drivers/cdrom/viocd.c b/drivers/cdrom/viocd.c
index 880b5dce3a6..d8bb44b98a6 100644
--- a/drivers/cdrom/viocd.c
+++ b/drivers/cdrom/viocd.c
@@ -41,9 +41,9 @@
 #include <linux/completion.h>
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
+#include <linux/scatterlist.h>
 
 #include <asm/vio.h>
-#include <asm/scatterlist.h>
 #include <asm/iseries/hv_types.h>
 #include <asm/iseries/hv_lp_event.h>
 #include <asm/iseries/vio.h>
@@ -258,6 +258,7 @@ static int send_request(struct request *req)
 		cmd = viomajorsubtype_cdio | viocdwrite;
 	}
 
+	sg_init_table(&sg, 1);
         if (blk_rq_map_sg(req->q, req, &sg) == 0) {
 		printk(VIOCD_KERN_WARNING
 				"error setting up scatter/gather list\n");
diff --git a/drivers/message/i2o/i2o_block.c b/drivers/message/i2o/i2o_block.c
index d602ba6d541..682406168de 100644
--- a/drivers/message/i2o/i2o_block.c
+++ b/drivers/message/i2o/i2o_block.c
@@ -284,6 +284,7 @@ static inline struct i2o_block_request *i2o_block_request_alloc(void)
 		return ERR_PTR(-ENOMEM);
 
 	INIT_LIST_HEAD(&ireq->queue);
+	sg_init_table(ireq->sg_table, I2O_MAX_PHYS_SEGMENTS);
 
 	return ireq;
 };
-- 
cgit v1.2.3-18-g5258


From 8c7837c4f5cf177729297ba3fef1ec62f50f499b Mon Sep 17 00:00:00 2001
From: Jens Axboe <jens.axboe@oracle.com>
Date: Wed, 24 Oct 2007 13:28:40 +0200
Subject: xtensa: dma-mapping.h is using linux/scatterlist.h functions, so
 include it

It's currently using asm/scatterlist.h, but that is not enough.

Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
---
 include/asm-xtensa/dma-mapping.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/asm-xtensa/dma-mapping.h b/include/asm-xtensa/dma-mapping.h
index 8bd9d2c02a2..3c7d537dd15 100644
--- a/include/asm-xtensa/dma-mapping.h
+++ b/include/asm-xtensa/dma-mapping.h
@@ -11,10 +11,10 @@
 #ifndef _XTENSA_DMA_MAPPING_H
 #define _XTENSA_DMA_MAPPING_H
 
-#include <asm/scatterlist.h>
 #include <asm/cache.h>
 #include <asm/io.h>
 #include <linux/mm.h>
+#include <linux/scatterlist.h>
 
 /*
  * DMA-consistent mapping functions.
-- 
cgit v1.2.3-18-g5258


From 82861924a5f26208c8421a799a4e8724d48eb560 Mon Sep 17 00:00:00 2001
From: Adrian Bunk <bunk@kernel.org>
Date: Wed, 24 Oct 2007 14:09:25 +0200
Subject: blackfin: fix sg fallout

Signed-off-by: Adrian Bunk <bunk@kernel.org>
Signed-off-by: Jens Axboe <axboe@carl.home.kernel.dk>
---
 arch/blackfin/kernel/dma-mapping.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/blackfin/kernel/dma-mapping.c b/arch/blackfin/kernel/dma-mapping.c
index a16cb03c529..d6b61d56b65 100644
--- a/arch/blackfin/kernel/dma-mapping.c
+++ b/arch/blackfin/kernel/dma-mapping.c
@@ -35,6 +35,7 @@
 #include <linux/device.h>
 #include <linux/dma-mapping.h>
 #include <linux/io.h>
+#include <linux/scatterlist.h>
 #include <asm/cacheflush.h>
 #include <asm/bfin-global.h>
 
-- 
cgit v1.2.3-18-g5258


From e88a39dee10d3a506ed8c4ba78cde0dd76a6fc83 Mon Sep 17 00:00:00 2001
From: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
Date: Thu, 25 Oct 2007 09:13:32 +0200
Subject: x86: pci-gart fix

map_sg could copy the last sg element to another position (if merging
some elements). It breaks sg chaining. This copies only
dma_address/length instead of the whole sg element.

Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
---
 arch/x86/kernel/pci-gart_64.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/arch/x86/kernel/pci-gart_64.c b/arch/x86/kernel/pci-gart_64.c
index c56e9ee6496..ae7e0161ce4 100644
--- a/arch/x86/kernel/pci-gart_64.c
+++ b/arch/x86/kernel/pci-gart_64.c
@@ -338,7 +338,6 @@ static int __dma_map_cont(struct scatterlist *start, int nelems,
 		
 		BUG_ON(s != start && s->offset);
 		if (s == start) {
-			*sout = *s; 
 			sout->dma_address = iommu_bus_base;
 			sout->dma_address += iommu_page*PAGE_SIZE + s->offset;
 			sout->dma_length = s->length;
@@ -365,7 +364,7 @@ static inline int dma_map_cont(struct scatterlist *start, int nelems,
 {
 	if (!need) {
 		BUG_ON(nelems != 1);
-		*sout = *start;
+		sout->dma_address = start->dma_address;
 		sout->dma_length = start->length;
 		return 0;
 	}
-- 
cgit v1.2.3-18-g5258


From 4f33a9d9a416313f0ecf6e6953d205385a431cd5 Mon Sep 17 00:00:00 2001
From: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
Date: Thu, 25 Oct 2007 09:17:03 +0200
Subject: ub: add sg_init_table for sense and read capacity commands

Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
---
 drivers/block/ub.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/block/ub.c b/drivers/block/ub.c
index 5e740e14ab3..08e909dc794 100644
--- a/drivers/block/ub.c
+++ b/drivers/block/ub.c
@@ -1428,6 +1428,7 @@ static void ub_state_sense(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
 	scmd->state = UB_CMDST_INIT;
 	scmd->nsg = 1;
 	sg = &scmd->sgv[0];
+	sg_init_table(sg, UB_MAX_REQ_SG);
 	sg_set_page(sg, virt_to_page(sc->top_sense), UB_SENSE_SIZE,
 			(unsigned long)sc->top_sense & (PAGE_SIZE-1));
 	scmd->len = UB_SENSE_SIZE;
@@ -1863,6 +1864,7 @@ static int ub_sync_read_cap(struct ub_dev *sc, struct ub_lun *lun,
 	cmd->state = UB_CMDST_INIT;
 	cmd->nsg = 1;
 	sg = &cmd->sgv[0];
+	sg_init_table(sg, UB_MAX_REQ_SG);
 	sg_set_page(sg, virt_to_page(p), 8, (unsigned long)p & (PAGE_SIZE-1));
 	cmd->len = 8;
 	cmd->lun = lun;
-- 
cgit v1.2.3-18-g5258


From 85cdffcde0b6b831a06422413300d0f5c0e608c3 Mon Sep 17 00:00:00 2001
From: Hugh Dickins <hugh@veritas.com>
Date: Thu, 25 Oct 2007 09:55:05 +0200
Subject: fix sg_phys to use dma_addr_t

x86_32 CONFIG_HIGHMEM64G with 5GB RAM hung when booting, after issuing
some "request_module: runaway loop modprobe binfmt-0000" messages in
trying to exec /sbin/init.

The binprm buf doesn't see the right ".ELF" header because sg_phys()
is providing the wrong physical addresses for high pages: a 32-bit
unsigned long is too small in this case, we need to use dma_addr_t.

Signed-off-by: Hugh Dickins <hugh@veritas.com>
Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
---
 include/linux/scatterlist.h | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/include/linux/scatterlist.h b/include/linux/scatterlist.h
index 809b2ac2e37..45712317138 100644
--- a/include/linux/scatterlist.h
+++ b/include/linux/scatterlist.h
@@ -1,6 +1,7 @@
 #ifndef _LINUX_SCATTERLIST_H
 #define _LINUX_SCATTERLIST_H
 
+#include <asm/types.h>
 #include <asm/scatterlist.h>
 #include <linux/mm.h>
 #include <linux/string.h>
@@ -255,7 +256,7 @@ static inline void sg_init_table(struct scatterlist *sgl, unsigned int nents)
  *   on the sg page.
  *
  **/
-static inline unsigned long sg_phys(struct scatterlist *sg)
+static inline dma_addr_t sg_phys(struct scatterlist *sg)
 {
 	return page_to_phys(sg_page(sg)) + sg->offset;
 }
-- 
cgit v1.2.3-18-g5258