diff options
author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-10-16 13:09:16 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-10-16 13:09:16 -0400 |
commit | 92d15c2ccbb3e31a3fc71ad28fdb55e1319383c0 (patch) | |
tree | 8d83c0dc3c6b935d8367e331872f242b742f0a8a /arch | |
parent | f20bf6125605acbbc7eb8c9420d7221c91aa83eb (diff) | |
parent | 644bd2f048972d75eb1979b1fdca257d528ce687 (diff) |
Merge branch 'for-linus' of git://git.kernel.dk/data/git/linux-2.6-block
* 'for-linus' of git://git.kernel.dk/data/git/linux-2.6-block: (63 commits)
Fix memory leak in dm-crypt
SPARC64: sg chaining support
SPARC: sg chaining support
PPC: sg chaining support
PS3: sg chaining support
IA64: sg chaining support
x86-64: enable sg chaining
x86-64: update pci-gart iommu to sg helpers
x86-64: update nommu to sg helpers
x86-64: update calgary iommu to sg helpers
swiotlb: sg chaining support
i386: enable sg chaining
i386 dma_map_sg: convert to using sg helpers
mmc: need to zero sglist on init
Panic in blk_rq_map_sg() from CCISS driver
remove sglist_len
remove blk_queue_max_phys_segments in libata
revert sg segment size ifdefs
Fixup u14-34f ENABLE_SG_CHAINING
qla1280: enable use_sg_chaining option
...
Diffstat (limited to 'arch')
-rw-r--r-- | arch/ia64/hp/common/sba_iommu.c | 14 | ||||
-rw-r--r-- | arch/ia64/hp/sim/simscsi.c | 1 | ||||
-rw-r--r-- | arch/ia64/sn/pci/pci_dma.c | 11 | ||||
-rw-r--r-- | arch/powerpc/kernel/dma_64.c | 5 | ||||
-rw-r--r-- | arch/powerpc/kernel/ibmebus.c | 11 | ||||
-rw-r--r-- | arch/powerpc/kernel/iommu.c | 23 | ||||
-rw-r--r-- | arch/powerpc/platforms/ps3/system-bus.c | 7 | ||||
-rw-r--r-- | arch/sparc/kernel/ioport.c | 25 | ||||
-rw-r--r-- | arch/sparc/mm/io-unit.c | 12 | ||||
-rw-r--r-- | arch/sparc/mm/iommu.c | 10 | ||||
-rw-r--r-- | arch/sparc/mm/sun4c.c | 10 | ||||
-rw-r--r-- | arch/sparc64/kernel/iommu.c | 39 | ||||
-rw-r--r-- | arch/sparc64/kernel/pci_sun4v.c | 32 | ||||
-rw-r--r-- | arch/x86/kernel/pci-calgary_64.c | 24 | ||||
-rw-r--r-- | arch/x86/kernel/pci-gart_64.c | 65 | ||||
-rw-r--r-- | arch/x86/kernel/pci-nommu_64.c | 5 |
16 files changed, 167 insertions, 127 deletions
diff --git a/arch/ia64/hp/common/sba_iommu.c b/arch/ia64/hp/common/sba_iommu.c index e980e7aa2306..4338f4123f31 100644 --- a/arch/ia64/hp/common/sba_iommu.c +++ b/arch/ia64/hp/common/sba_iommu.c | |||
@@ -396,7 +396,7 @@ sba_dump_sg( struct ioc *ioc, struct scatterlist *startsg, int nents) | |||
396 | printk(KERN_DEBUG " %d : DMA %08lx/%05x CPU %p\n", nents, | 396 | printk(KERN_DEBUG " %d : DMA %08lx/%05x CPU %p\n", nents, |
397 | startsg->dma_address, startsg->dma_length, | 397 | startsg->dma_address, startsg->dma_length, |
398 | sba_sg_address(startsg)); | 398 | sba_sg_address(startsg)); |
399 | startsg++; | 399 | startsg = sg_next(startsg); |
400 | } | 400 | } |
401 | } | 401 | } |
402 | 402 | ||
@@ -409,7 +409,7 @@ sba_check_sg( struct ioc *ioc, struct scatterlist *startsg, int nents) | |||
409 | while (the_nents-- > 0) { | 409 | while (the_nents-- > 0) { |
410 | if (sba_sg_address(the_sg) == 0x0UL) | 410 | if (sba_sg_address(the_sg) == 0x0UL) |
411 | sba_dump_sg(NULL, startsg, nents); | 411 | sba_dump_sg(NULL, startsg, nents); |
412 | the_sg++; | 412 | the_sg = sg_next(the_sg); |
413 | } | 413 | } |
414 | } | 414 | } |
415 | 415 | ||
@@ -1201,7 +1201,7 @@ sba_fill_pdir( | |||
1201 | u32 pide = startsg->dma_address & ~PIDE_FLAG; | 1201 | u32 pide = startsg->dma_address & ~PIDE_FLAG; |
1202 | dma_offset = (unsigned long) pide & ~iovp_mask; | 1202 | dma_offset = (unsigned long) pide & ~iovp_mask; |
1203 | startsg->dma_address = 0; | 1203 | startsg->dma_address = 0; |
1204 | dma_sg++; | 1204 | dma_sg = sg_next(dma_sg); |
1205 | dma_sg->dma_address = pide | ioc->ibase; | 1205 | dma_sg->dma_address = pide | ioc->ibase; |
1206 | pdirp = &(ioc->pdir_base[pide >> iovp_shift]); | 1206 | pdirp = &(ioc->pdir_base[pide >> iovp_shift]); |
1207 | n_mappings++; | 1207 | n_mappings++; |
@@ -1228,7 +1228,7 @@ sba_fill_pdir( | |||
1228 | pdirp++; | 1228 | pdirp++; |
1229 | } while (cnt > 0); | 1229 | } while (cnt > 0); |
1230 | } | 1230 | } |
1231 | startsg++; | 1231 | startsg = sg_next(startsg); |
1232 | } | 1232 | } |
1233 | /* force pdir update */ | 1233 | /* force pdir update */ |
1234 | wmb(); | 1234 | wmb(); |
@@ -1297,7 +1297,7 @@ sba_coalesce_chunks( struct ioc *ioc, | |||
1297 | while (--nents > 0) { | 1297 | while (--nents > 0) { |
1298 | unsigned long vaddr; /* tmp */ | 1298 | unsigned long vaddr; /* tmp */ |
1299 | 1299 | ||
1300 | startsg++; | 1300 | startsg = sg_next(startsg); |
1301 | 1301 | ||
1302 | /* PARANOID */ | 1302 | /* PARANOID */ |
1303 | startsg->dma_address = startsg->dma_length = 0; | 1303 | startsg->dma_address = startsg->dma_length = 0; |
@@ -1407,7 +1407,7 @@ int sba_map_sg(struct device *dev, struct scatterlist *sglist, int nents, int di | |||
1407 | #ifdef ALLOW_IOV_BYPASS_SG | 1407 | #ifdef ALLOW_IOV_BYPASS_SG |
1408 | ASSERT(to_pci_dev(dev)->dma_mask); | 1408 | ASSERT(to_pci_dev(dev)->dma_mask); |
1409 | if (likely((ioc->dma_mask & ~to_pci_dev(dev)->dma_mask) == 0)) { | 1409 | if (likely((ioc->dma_mask & ~to_pci_dev(dev)->dma_mask) == 0)) { |
1410 | for (sg = sglist ; filled < nents ; filled++, sg++){ | 1410 | for_each_sg(sglist, sg, nents, filled) { |
1411 | sg->dma_length = sg->length; | 1411 | sg->dma_length = sg->length; |
1412 | sg->dma_address = virt_to_phys(sba_sg_address(sg)); | 1412 | sg->dma_address = virt_to_phys(sba_sg_address(sg)); |
1413 | } | 1413 | } |
@@ -1501,7 +1501,7 @@ void sba_unmap_sg (struct device *dev, struct scatterlist *sglist, int nents, in | |||
1501 | while (nents && sglist->dma_length) { | 1501 | while (nents && sglist->dma_length) { |
1502 | 1502 | ||
1503 | sba_unmap_single(dev, sglist->dma_address, sglist->dma_length, dir); | 1503 | sba_unmap_single(dev, sglist->dma_address, sglist->dma_length, dir); |
1504 | sglist++; | 1504 | sglist = sg_next(sglist); |
1505 | nents--; | 1505 | nents--; |
1506 | } | 1506 | } |
1507 | 1507 | ||
diff --git a/arch/ia64/hp/sim/simscsi.c b/arch/ia64/hp/sim/simscsi.c index d62fa76e5a7d..a3a558a06757 100644 --- a/arch/ia64/hp/sim/simscsi.c +++ b/arch/ia64/hp/sim/simscsi.c | |||
@@ -360,6 +360,7 @@ static struct scsi_host_template driver_template = { | |||
360 | .max_sectors = 1024, | 360 | .max_sectors = 1024, |
361 | .cmd_per_lun = SIMSCSI_REQ_QUEUE_LEN, | 361 | .cmd_per_lun = SIMSCSI_REQ_QUEUE_LEN, |
362 | .use_clustering = DISABLE_CLUSTERING, | 362 | .use_clustering = DISABLE_CLUSTERING, |
363 | .use_sg_chaining = ENABLE_SG_CHAINING, | ||
363 | }; | 364 | }; |
364 | 365 | ||
365 | static int __init | 366 | static int __init |
diff --git a/arch/ia64/sn/pci/pci_dma.c b/arch/ia64/sn/pci/pci_dma.c index d79ddacfba2d..ecd8a52b9b9e 100644 --- a/arch/ia64/sn/pci/pci_dma.c +++ b/arch/ia64/sn/pci/pci_dma.c | |||
@@ -218,16 +218,17 @@ EXPORT_SYMBOL(sn_dma_unmap_single); | |||
218 | * | 218 | * |
219 | * Unmap a set of streaming mode DMA translations. | 219 | * Unmap a set of streaming mode DMA translations. |
220 | */ | 220 | */ |
221 | void sn_dma_unmap_sg(struct device *dev, struct scatterlist *sg, | 221 | void sn_dma_unmap_sg(struct device *dev, struct scatterlist *sgl, |
222 | int nhwentries, int direction) | 222 | int nhwentries, int direction) |
223 | { | 223 | { |
224 | int i; | 224 | int i; |
225 | struct pci_dev *pdev = to_pci_dev(dev); | 225 | struct pci_dev *pdev = to_pci_dev(dev); |
226 | struct sn_pcibus_provider *provider = SN_PCIDEV_BUSPROVIDER(pdev); | 226 | struct sn_pcibus_provider *provider = SN_PCIDEV_BUSPROVIDER(pdev); |
227 | struct scatterlist *sg; | ||
227 | 228 | ||
228 | BUG_ON(dev->bus != &pci_bus_type); | 229 | BUG_ON(dev->bus != &pci_bus_type); |
229 | 230 | ||
230 | for (i = 0; i < nhwentries; i++, sg++) { | 231 | for_each_sg(sgl, sg, nhwentries, i) { |
231 | provider->dma_unmap(pdev, sg->dma_address, direction); | 232 | provider->dma_unmap(pdev, sg->dma_address, direction); |
232 | sg->dma_address = (dma_addr_t) NULL; | 233 | sg->dma_address = (dma_addr_t) NULL; |
233 | sg->dma_length = 0; | 234 | sg->dma_length = 0; |
@@ -244,11 +245,11 @@ EXPORT_SYMBOL(sn_dma_unmap_sg); | |||
244 | * | 245 | * |
245 | * Maps each entry of @sg for DMA. | 246 | * Maps each entry of @sg for DMA. |
246 | */ | 247 | */ |
247 | int sn_dma_map_sg(struct device *dev, struct scatterlist *sg, int nhwentries, | 248 | int sn_dma_map_sg(struct device *dev, struct scatterlist *sgl, int nhwentries, |
248 | int direction) | 249 | int direction) |
249 | { | 250 | { |
250 | unsigned long phys_addr; | 251 | unsigned long phys_addr; |
251 | struct scatterlist *saved_sg = sg; | 252 | struct scatterlist *saved_sg = sgl, *sg; |
252 | struct pci_dev *pdev = to_pci_dev(dev); | 253 | struct pci_dev *pdev = to_pci_dev(dev); |
253 | struct sn_pcibus_provider *provider = SN_PCIDEV_BUSPROVIDER(pdev); | 254 | struct sn_pcibus_provider *provider = SN_PCIDEV_BUSPROVIDER(pdev); |
254 | int i; | 255 | int i; |
@@ -258,7 +259,7 @@ int sn_dma_map_sg(struct device *dev, struct scatterlist *sg, int nhwentries, | |||
258 | /* | 259 | /* |
259 | * Setup a DMA address for each entry in the scatterlist. | 260 | * Setup a DMA address for each entry in the scatterlist. |
260 | */ | 261 | */ |
261 | for (i = 0; i < nhwentries; i++, sg++) { | 262 | for_each_sg(sgl, sg, nhwentries, i) { |
262 | phys_addr = SG_ENT_PHYS_ADDRESS(sg); | 263 | phys_addr = SG_ENT_PHYS_ADDRESS(sg); |
263 | sg->dma_address = provider->dma_map(pdev, | 264 | sg->dma_address = provider->dma_map(pdev, |
264 | phys_addr, sg->length, | 265 | phys_addr, sg->length, |
diff --git a/arch/powerpc/kernel/dma_64.c b/arch/powerpc/kernel/dma_64.c index 7b0e754383cf..9001104b56b0 100644 --- a/arch/powerpc/kernel/dma_64.c +++ b/arch/powerpc/kernel/dma_64.c | |||
@@ -154,12 +154,13 @@ static void dma_direct_unmap_single(struct device *dev, dma_addr_t dma_addr, | |||
154 | { | 154 | { |
155 | } | 155 | } |
156 | 156 | ||
157 | static int dma_direct_map_sg(struct device *dev, struct scatterlist *sg, | 157 | static int dma_direct_map_sg(struct device *dev, struct scatterlist *sgl, |
158 | int nents, enum dma_data_direction direction) | 158 | int nents, enum dma_data_direction direction) |
159 | { | 159 | { |
160 | struct scatterlist *sg; | ||
160 | int i; | 161 | int i; |
161 | 162 | ||
162 | for (i = 0; i < nents; i++, sg++) { | 163 | for_each_sg(sgl, sg, nents, i) { |
163 | sg->dma_address = (page_to_phys(sg->page) + sg->offset) | | 164 | sg->dma_address = (page_to_phys(sg->page) + sg->offset) | |
164 | dma_direct_offset; | 165 | dma_direct_offset; |
165 | sg->dma_length = sg->length; | 166 | sg->dma_length = sg->length; |
diff --git a/arch/powerpc/kernel/ibmebus.c b/arch/powerpc/kernel/ibmebus.c index 53bf64623bd8..2e16ca5778a3 100644 --- a/arch/powerpc/kernel/ibmebus.c +++ b/arch/powerpc/kernel/ibmebus.c | |||
@@ -87,15 +87,16 @@ static void ibmebus_unmap_single(struct device *dev, | |||
87 | } | 87 | } |
88 | 88 | ||
89 | static int ibmebus_map_sg(struct device *dev, | 89 | static int ibmebus_map_sg(struct device *dev, |
90 | struct scatterlist *sg, | 90 | struct scatterlist *sgl, |
91 | int nents, enum dma_data_direction direction) | 91 | int nents, enum dma_data_direction direction) |
92 | { | 92 | { |
93 | struct scatterlist *sg; | ||
93 | int i; | 94 | int i; |
94 | 95 | ||
95 | for (i = 0; i < nents; i++) { | 96 | for_each_sg(sgl, sg, nents, i) { |
96 | sg[i].dma_address = (dma_addr_t)page_address(sg[i].page) | 97 | sg->dma_address = (dma_addr_t)page_address(sg->page) |
97 | + sg[i].offset; | 98 | + sg->offset; |
98 | sg[i].dma_length = sg[i].length; | 99 | sg->dma_length = sg->length; |
99 | } | 100 | } |
100 | 101 | ||
101 | return nents; | 102 | return nents; |
diff --git a/arch/powerpc/kernel/iommu.c b/arch/powerpc/kernel/iommu.c index e4ec6eee81a8..306a6f75b6c5 100644 --- a/arch/powerpc/kernel/iommu.c +++ b/arch/powerpc/kernel/iommu.c | |||
@@ -277,7 +277,7 @@ int iommu_map_sg(struct iommu_table *tbl, struct scatterlist *sglist, | |||
277 | dma_addr_t dma_next = 0, dma_addr; | 277 | dma_addr_t dma_next = 0, dma_addr; |
278 | unsigned long flags; | 278 | unsigned long flags; |
279 | struct scatterlist *s, *outs, *segstart; | 279 | struct scatterlist *s, *outs, *segstart; |
280 | int outcount, incount; | 280 | int outcount, incount, i; |
281 | unsigned long handle; | 281 | unsigned long handle; |
282 | 282 | ||
283 | BUG_ON(direction == DMA_NONE); | 283 | BUG_ON(direction == DMA_NONE); |
@@ -297,7 +297,7 @@ int iommu_map_sg(struct iommu_table *tbl, struct scatterlist *sglist, | |||
297 | 297 | ||
298 | spin_lock_irqsave(&(tbl->it_lock), flags); | 298 | spin_lock_irqsave(&(tbl->it_lock), flags); |
299 | 299 | ||
300 | for (s = outs; nelems; nelems--, s++) { | 300 | for_each_sg(sglist, s, nelems, i) { |
301 | unsigned long vaddr, npages, entry, slen; | 301 | unsigned long vaddr, npages, entry, slen; |
302 | 302 | ||
303 | slen = s->length; | 303 | slen = s->length; |
@@ -341,7 +341,8 @@ int iommu_map_sg(struct iommu_table *tbl, struct scatterlist *sglist, | |||
341 | if (novmerge || (dma_addr != dma_next)) { | 341 | if (novmerge || (dma_addr != dma_next)) { |
342 | /* Can't merge: create a new segment */ | 342 | /* Can't merge: create a new segment */ |
343 | segstart = s; | 343 | segstart = s; |
344 | outcount++; outs++; | 344 | outcount++; |
345 | outs = sg_next(outs); | ||
345 | DBG(" can't merge, new segment.\n"); | 346 | DBG(" can't merge, new segment.\n"); |
346 | } else { | 347 | } else { |
347 | outs->dma_length += s->length; | 348 | outs->dma_length += s->length; |
@@ -374,7 +375,7 @@ int iommu_map_sg(struct iommu_table *tbl, struct scatterlist *sglist, | |||
374 | * next entry of the sglist if we didn't fill the list completely | 375 | * next entry of the sglist if we didn't fill the list completely |
375 | */ | 376 | */ |
376 | if (outcount < incount) { | 377 | if (outcount < incount) { |
377 | outs++; | 378 | outs = sg_next(outs); |
378 | outs->dma_address = DMA_ERROR_CODE; | 379 | outs->dma_address = DMA_ERROR_CODE; |
379 | outs->dma_length = 0; | 380 | outs->dma_length = 0; |
380 | } | 381 | } |
@@ -385,7 +386,7 @@ int iommu_map_sg(struct iommu_table *tbl, struct scatterlist *sglist, | |||
385 | return outcount; | 386 | return outcount; |
386 | 387 | ||
387 | failure: | 388 | failure: |
388 | for (s = &sglist[0]; s <= outs; s++) { | 389 | for_each_sg(sglist, s, nelems, i) { |
389 | if (s->dma_length != 0) { | 390 | if (s->dma_length != 0) { |
390 | unsigned long vaddr, npages; | 391 | unsigned long vaddr, npages; |
391 | 392 | ||
@@ -395,6 +396,8 @@ int iommu_map_sg(struct iommu_table *tbl, struct scatterlist *sglist, | |||
395 | s->dma_address = DMA_ERROR_CODE; | 396 | s->dma_address = DMA_ERROR_CODE; |
396 | s->dma_length = 0; | 397 | s->dma_length = 0; |
397 | } | 398 | } |
399 | if (s == outs) | ||
400 | break; | ||
398 | } | 401 | } |
399 | spin_unlock_irqrestore(&(tbl->it_lock), flags); | 402 | spin_unlock_irqrestore(&(tbl->it_lock), flags); |
400 | return 0; | 403 | return 0; |
@@ -404,6 +407,7 @@ int iommu_map_sg(struct iommu_table *tbl, struct scatterlist *sglist, | |||
404 | void iommu_unmap_sg(struct iommu_table *tbl, struct scatterlist *sglist, | 407 | void iommu_unmap_sg(struct iommu_table *tbl, struct scatterlist *sglist, |
405 | int nelems, enum dma_data_direction direction) | 408 | int nelems, enum dma_data_direction direction) |
406 | { | 409 | { |
410 | struct scatterlist *sg; | ||
407 | unsigned long flags; | 411 | unsigned long flags; |
408 | 412 | ||
409 | BUG_ON(direction == DMA_NONE); | 413 | BUG_ON(direction == DMA_NONE); |
@@ -413,15 +417,16 @@ void iommu_unmap_sg(struct iommu_table *tbl, struct scatterlist *sglist, | |||
413 | 417 | ||
414 | spin_lock_irqsave(&(tbl->it_lock), flags); | 418 | spin_lock_irqsave(&(tbl->it_lock), flags); |
415 | 419 | ||
420 | sg = sglist; | ||
416 | while (nelems--) { | 421 | while (nelems--) { |
417 | unsigned int npages; | 422 | unsigned int npages; |
418 | dma_addr_t dma_handle = sglist->dma_address; | 423 | dma_addr_t dma_handle = sg->dma_address; |
419 | 424 | ||
420 | if (sglist->dma_length == 0) | 425 | if (sg->dma_length == 0) |
421 | break; | 426 | break; |
422 | npages = iommu_num_pages(dma_handle,sglist->dma_length); | 427 | npages = iommu_num_pages(dma_handle, sg->dma_length); |
423 | __iommu_free(tbl, dma_handle, npages); | 428 | __iommu_free(tbl, dma_handle, npages); |
424 | sglist++; | 429 | sg = sg_next(sg); |
425 | } | 430 | } |
426 | 431 | ||
427 | /* Flush/invalidate TLBs if necessary. As for iommu_free(), we | 432 | /* Flush/invalidate TLBs if necessary. As for iommu_free(), we |
diff --git a/arch/powerpc/platforms/ps3/system-bus.c b/arch/powerpc/platforms/ps3/system-bus.c index 190ff4b59a55..07e64b48e7fc 100644 --- a/arch/powerpc/platforms/ps3/system-bus.c +++ b/arch/powerpc/platforms/ps3/system-bus.c | |||
@@ -616,17 +616,18 @@ static void ps3_unmap_single(struct device *_dev, dma_addr_t dma_addr, | |||
616 | } | 616 | } |
617 | } | 617 | } |
618 | 618 | ||
619 | static int ps3_sb_map_sg(struct device *_dev, struct scatterlist *sg, int nents, | 619 | static int ps3_sb_map_sg(struct device *_dev, struct scatterlist *sgl, |
620 | enum dma_data_direction direction) | 620 | int nents, enum dma_data_direction direction) |
621 | { | 621 | { |
622 | #if defined(CONFIG_PS3_DYNAMIC_DMA) | 622 | #if defined(CONFIG_PS3_DYNAMIC_DMA) |
623 | BUG_ON("do"); | 623 | BUG_ON("do"); |
624 | return -EPERM; | 624 | return -EPERM; |
625 | #else | 625 | #else |
626 | struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev); | 626 | struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev); |
627 | struct scatterlist *sg; | ||
627 | int i; | 628 | int i; |
628 | 629 | ||
629 | for (i = 0; i < nents; i++, sg++) { | 630 | for_each_sg(sgl, sg, nents, i) { |
630 | int result = ps3_dma_map(dev->d_region, | 631 | int result = ps3_dma_map(dev->d_region, |
631 | page_to_phys(sg->page) + sg->offset, sg->length, | 632 | page_to_phys(sg->page) + sg->offset, sg->length, |
632 | &sg->dma_address, 0); | 633 | &sg->dma_address, 0); |
diff --git a/arch/sparc/kernel/ioport.c b/arch/sparc/kernel/ioport.c index 62182d2d7b0d..9c3ed88853f3 100644 --- a/arch/sparc/kernel/ioport.c +++ b/arch/sparc/kernel/ioport.c | |||
@@ -35,6 +35,7 @@ | |||
35 | #include <linux/slab.h> | 35 | #include <linux/slab.h> |
36 | #include <linux/pci.h> /* struct pci_dev */ | 36 | #include <linux/pci.h> /* struct pci_dev */ |
37 | #include <linux/proc_fs.h> | 37 | #include <linux/proc_fs.h> |
38 | #include <linux/scatterlist.h> | ||
38 | 39 | ||
39 | #include <asm/io.h> | 40 | #include <asm/io.h> |
40 | #include <asm/vaddrs.h> | 41 | #include <asm/vaddrs.h> |
@@ -717,19 +718,19 @@ void pci_unmap_page(struct pci_dev *hwdev, | |||
717 | * Device ownership issues as mentioned above for pci_map_single are | 718 | * Device ownership issues as mentioned above for pci_map_single are |
718 | * the same here. | 719 | * the same here. |
719 | */ | 720 | */ |
720 | int pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sg, int nents, | 721 | int pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sgl, int nents, |
721 | int direction) | 722 | int direction) |
722 | { | 723 | { |
724 | struct scatterlist *sg; | ||
723 | int n; | 725 | int n; |
724 | 726 | ||
725 | BUG_ON(direction == PCI_DMA_NONE); | 727 | BUG_ON(direction == PCI_DMA_NONE); |
726 | /* IIep is write-through, not flushing. */ | 728 | /* IIep is write-through, not flushing. */ |
727 | for (n = 0; n < nents; n++) { | 729 | for_each_sg(sgl, sg, nents, n) { |
728 | BUG_ON(page_address(sg->page) == NULL); | 730 | BUG_ON(page_address(sg->page) == NULL); |
729 | sg->dvma_address = | 731 | sg->dvma_address = |
730 | virt_to_phys(page_address(sg->page)) + sg->offset; | 732 | virt_to_phys(page_address(sg->page)) + sg->offset; |
731 | sg->dvma_length = sg->length; | 733 | sg->dvma_length = sg->length; |
732 | sg++; | ||
733 | } | 734 | } |
734 | return nents; | 735 | return nents; |
735 | } | 736 | } |
@@ -738,19 +739,19 @@ int pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sg, int nents, | |||
738 | * Again, cpu read rules concerning calls here are the same as for | 739 | * Again, cpu read rules concerning calls here are the same as for |
739 | * pci_unmap_single() above. | 740 | * pci_unmap_single() above. |
740 | */ | 741 | */ |
741 | void pci_unmap_sg(struct pci_dev *hwdev, struct scatterlist *sg, int nents, | 742 | void pci_unmap_sg(struct pci_dev *hwdev, struct scatterlist *sgl, int nents, |
742 | int direction) | 743 | int direction) |
743 | { | 744 | { |
745 | struct scatterlist *sg; | ||
744 | int n; | 746 | int n; |
745 | 747 | ||
746 | BUG_ON(direction == PCI_DMA_NONE); | 748 | BUG_ON(direction == PCI_DMA_NONE); |
747 | if (direction != PCI_DMA_TODEVICE) { | 749 | if (direction != PCI_DMA_TODEVICE) { |
748 | for (n = 0; n < nents; n++) { | 750 | for_each_sg(sgl, sg, nents, n) { |
749 | BUG_ON(page_address(sg->page) == NULL); | 751 | BUG_ON(page_address(sg->page) == NULL); |
750 | mmu_inval_dma_area( | 752 | mmu_inval_dma_area( |
751 | (unsigned long) page_address(sg->page), | 753 | (unsigned long) page_address(sg->page), |
752 | (sg->length + PAGE_SIZE-1) & PAGE_MASK); | 754 | (sg->length + PAGE_SIZE-1) & PAGE_MASK); |
753 | sg++; | ||
754 | } | 755 | } |
755 | } | 756 | } |
756 | } | 757 | } |
@@ -789,34 +790,34 @@ void pci_dma_sync_single_for_device(struct pci_dev *hwdev, dma_addr_t ba, size_t | |||
789 | * The same as pci_dma_sync_single_* but for a scatter-gather list, | 790 | * The same as pci_dma_sync_single_* but for a scatter-gather list, |
790 | * same rules and usage. | 791 | * same rules and usage. |
791 | */ | 792 | */ |
792 | void pci_dma_sync_sg_for_cpu(struct pci_dev *hwdev, struct scatterlist *sg, int nents, int direction) | 793 | void pci_dma_sync_sg_for_cpu(struct pci_dev *hwdev, struct scatterlist *sgl, int nents, int direction) |
793 | { | 794 | { |
795 | struct scatterlist *sg; | ||
794 | int n; | 796 | int n; |
795 | 797 | ||
796 | BUG_ON(direction == PCI_DMA_NONE); | 798 | BUG_ON(direction == PCI_DMA_NONE); |
797 | if (direction != PCI_DMA_TODEVICE) { | 799 | if (direction != PCI_DMA_TODEVICE) { |
798 | for (n = 0; n < nents; n++) { | 800 | for_each_sg(sgl, sg, nents, n) { |
799 | BUG_ON(page_address(sg->page) == NULL); | 801 | BUG_ON(page_address(sg->page) == NULL); |
800 | mmu_inval_dma_area( | 802 | mmu_inval_dma_area( |
801 | (unsigned long) page_address(sg->page), | 803 | (unsigned long) page_address(sg->page), |
802 | (sg->length + PAGE_SIZE-1) & PAGE_MASK); | 804 | (sg->length + PAGE_SIZE-1) & PAGE_MASK); |
803 | sg++; | ||
804 | } | 805 | } |
805 | } | 806 | } |
806 | } | 807 | } |
807 | 808 | ||
808 | void pci_dma_sync_sg_for_device(struct pci_dev *hwdev, struct scatterlist *sg, int nents, int direction) | 809 | void pci_dma_sync_sg_for_device(struct pci_dev *hwdev, struct scatterlist *sgl, int nents, int direction) |
809 | { | 810 | { |
811 | struct scatterlist *sg; | ||
810 | int n; | 812 | int n; |
811 | 813 | ||
812 | BUG_ON(direction == PCI_DMA_NONE); | 814 | BUG_ON(direction == PCI_DMA_NONE); |
813 | if (direction != PCI_DMA_TODEVICE) { | 815 | if (direction != PCI_DMA_TODEVICE) { |
814 | for (n = 0; n < nents; n++) { | 816 | for_each_sg(sgl, sg, nents, n) { |
815 | BUG_ON(page_address(sg->page) == NULL); | 817 | BUG_ON(page_address(sg->page) == NULL); |
816 | mmu_inval_dma_area( | 818 | mmu_inval_dma_area( |
817 | (unsigned long) page_address(sg->page), | 819 | (unsigned long) page_address(sg->page), |
818 | (sg->length + PAGE_SIZE-1) & PAGE_MASK); | 820 | (sg->length + PAGE_SIZE-1) & PAGE_MASK); |
819 | sg++; | ||
820 | } | 821 | } |
821 | } | 822 | } |
822 | } | 823 | } |
diff --git a/arch/sparc/mm/io-unit.c b/arch/sparc/mm/io-unit.c index 7c89893b1fe8..375b4db63704 100644 --- a/arch/sparc/mm/io-unit.c +++ b/arch/sparc/mm/io-unit.c | |||
@@ -11,8 +11,8 @@ | |||
11 | #include <linux/mm.h> | 11 | #include <linux/mm.h> |
12 | #include <linux/highmem.h> /* pte_offset_map => kmap_atomic */ | 12 | #include <linux/highmem.h> /* pte_offset_map => kmap_atomic */ |
13 | #include <linux/bitops.h> | 13 | #include <linux/bitops.h> |
14 | #include <linux/scatterlist.h> | ||
14 | 15 | ||
15 | #include <asm/scatterlist.h> | ||
16 | #include <asm/pgalloc.h> | 16 | #include <asm/pgalloc.h> |
17 | #include <asm/pgtable.h> | 17 | #include <asm/pgtable.h> |
18 | #include <asm/sbus.h> | 18 | #include <asm/sbus.h> |
@@ -144,8 +144,9 @@ static void iounit_get_scsi_sgl(struct scatterlist *sg, int sz, struct sbus_bus | |||
144 | spin_lock_irqsave(&iounit->lock, flags); | 144 | spin_lock_irqsave(&iounit->lock, flags); |
145 | while (sz != 0) { | 145 | while (sz != 0) { |
146 | --sz; | 146 | --sz; |
147 | sg[sz].dvma_address = iounit_get_area(iounit, (unsigned long)page_address(sg[sz].page) + sg[sz].offset, sg[sz].length); | 147 | sg->dvma_address = iounit_get_area(iounit, (unsigned long)page_address(sg->page) + sg->offset, sg->length); |
148 | sg[sz].dvma_length = sg[sz].length; | 148 | sg->dvma_length = sg->length; |
149 | sg = sg_next(sg); | ||
149 | } | 150 | } |
150 | spin_unlock_irqrestore(&iounit->lock, flags); | 151 | spin_unlock_irqrestore(&iounit->lock, flags); |
151 | } | 152 | } |
@@ -173,11 +174,12 @@ static void iounit_release_scsi_sgl(struct scatterlist *sg, int sz, struct sbus_ | |||
173 | spin_lock_irqsave(&iounit->lock, flags); | 174 | spin_lock_irqsave(&iounit->lock, flags); |
174 | while (sz != 0) { | 175 | while (sz != 0) { |
175 | --sz; | 176 | --sz; |
176 | len = ((sg[sz].dvma_address & ~PAGE_MASK) + sg[sz].length + (PAGE_SIZE-1)) >> PAGE_SHIFT; | 177 | len = ((sg->dvma_address & ~PAGE_MASK) + sg->length + (PAGE_SIZE-1)) >> PAGE_SHIFT; |
177 | vaddr = (sg[sz].dvma_address - IOUNIT_DMA_BASE) >> PAGE_SHIFT; | 178 | vaddr = (sg->dvma_address - IOUNIT_DMA_BASE) >> PAGE_SHIFT; |
178 | IOD(("iounit_release %08lx-%08lx\n", (long)vaddr, (long)len+vaddr)); | 179 | IOD(("iounit_release %08lx-%08lx\n", (long)vaddr, (long)len+vaddr)); |
179 | for (len += vaddr; vaddr < len; vaddr++) | 180 | for (len += vaddr; vaddr < len; vaddr++) |
180 | clear_bit(vaddr, iounit->bmap); | 181 | clear_bit(vaddr, iounit->bmap); |
182 | sg = sg_next(sg); | ||
181 | } | 183 | } |
182 | spin_unlock_irqrestore(&iounit->lock, flags); | 184 | spin_unlock_irqrestore(&iounit->lock, flags); |
183 | } | 185 | } |
diff --git a/arch/sparc/mm/iommu.c b/arch/sparc/mm/iommu.c index 52e907af9d29..283656d9f6ea 100644 --- a/arch/sparc/mm/iommu.c +++ b/arch/sparc/mm/iommu.c | |||
@@ -12,8 +12,8 @@ | |||
12 | #include <linux/mm.h> | 12 | #include <linux/mm.h> |
13 | #include <linux/slab.h> | 13 | #include <linux/slab.h> |
14 | #include <linux/highmem.h> /* pte_offset_map => kmap_atomic */ | 14 | #include <linux/highmem.h> /* pte_offset_map => kmap_atomic */ |
15 | #include <linux/scatterlist.h> | ||
15 | 16 | ||
16 | #include <asm/scatterlist.h> | ||
17 | #include <asm/pgalloc.h> | 17 | #include <asm/pgalloc.h> |
18 | #include <asm/pgtable.h> | 18 | #include <asm/pgtable.h> |
19 | #include <asm/sbus.h> | 19 | #include <asm/sbus.h> |
@@ -240,7 +240,7 @@ static void iommu_get_scsi_sgl_noflush(struct scatterlist *sg, int sz, struct sb | |||
240 | n = (sg->length + sg->offset + PAGE_SIZE-1) >> PAGE_SHIFT; | 240 | n = (sg->length + sg->offset + PAGE_SIZE-1) >> PAGE_SHIFT; |
241 | sg->dvma_address = iommu_get_one(sg->page, n, sbus) + sg->offset; | 241 | sg->dvma_address = iommu_get_one(sg->page, n, sbus) + sg->offset; |
242 | sg->dvma_length = (__u32) sg->length; | 242 | sg->dvma_length = (__u32) sg->length; |
243 | sg++; | 243 | sg = sg_next(sg); |
244 | } | 244 | } |
245 | } | 245 | } |
246 | 246 | ||
@@ -254,7 +254,7 @@ static void iommu_get_scsi_sgl_gflush(struct scatterlist *sg, int sz, struct sbu | |||
254 | n = (sg->length + sg->offset + PAGE_SIZE-1) >> PAGE_SHIFT; | 254 | n = (sg->length + sg->offset + PAGE_SIZE-1) >> PAGE_SHIFT; |
255 | sg->dvma_address = iommu_get_one(sg->page, n, sbus) + sg->offset; | 255 | sg->dvma_address = iommu_get_one(sg->page, n, sbus) + sg->offset; |
256 | sg->dvma_length = (__u32) sg->length; | 256 | sg->dvma_length = (__u32) sg->length; |
257 | sg++; | 257 | sg = sg_next(sg); |
258 | } | 258 | } |
259 | } | 259 | } |
260 | 260 | ||
@@ -285,7 +285,7 @@ static void iommu_get_scsi_sgl_pflush(struct scatterlist *sg, int sz, struct sbu | |||
285 | 285 | ||
286 | sg->dvma_address = iommu_get_one(sg->page, n, sbus) + sg->offset; | 286 | sg->dvma_address = iommu_get_one(sg->page, n, sbus) + sg->offset; |
287 | sg->dvma_length = (__u32) sg->length; | 287 | sg->dvma_length = (__u32) sg->length; |
288 | sg++; | 288 | sg = sg_next(sg); |
289 | } | 289 | } |
290 | } | 290 | } |
291 | 291 | ||
@@ -325,7 +325,7 @@ static void iommu_release_scsi_sgl(struct scatterlist *sg, int sz, struct sbus_b | |||
325 | n = (sg->length + sg->offset + PAGE_SIZE-1) >> PAGE_SHIFT; | 325 | n = (sg->length + sg->offset + PAGE_SIZE-1) >> PAGE_SHIFT; |
326 | iommu_release_one(sg->dvma_address & PAGE_MASK, n, sbus); | 326 | iommu_release_one(sg->dvma_address & PAGE_MASK, n, sbus); |
327 | sg->dvma_address = 0x21212121; | 327 | sg->dvma_address = 0x21212121; |
328 | sg++; | 328 | sg = sg_next(sg); |
329 | } | 329 | } |
330 | } | 330 | } |
331 | 331 | ||
diff --git a/arch/sparc/mm/sun4c.c b/arch/sparc/mm/sun4c.c index 005a3e72d4f2..ee6708fc4492 100644 --- a/arch/sparc/mm/sun4c.c +++ b/arch/sparc/mm/sun4c.c | |||
@@ -17,8 +17,8 @@ | |||
17 | #include <linux/highmem.h> | 17 | #include <linux/highmem.h> |
18 | #include <linux/fs.h> | 18 | #include <linux/fs.h> |
19 | #include <linux/seq_file.h> | 19 | #include <linux/seq_file.h> |
20 | #include <linux/scatterlist.h> | ||
20 | 21 | ||
21 | #include <asm/scatterlist.h> | ||
22 | #include <asm/page.h> | 22 | #include <asm/page.h> |
23 | #include <asm/pgalloc.h> | 23 | #include <asm/pgalloc.h> |
24 | #include <asm/pgtable.h> | 24 | #include <asm/pgtable.h> |
@@ -1228,8 +1228,9 @@ static void sun4c_get_scsi_sgl(struct scatterlist *sg, int sz, struct sbus_bus * | |||
1228 | { | 1228 | { |
1229 | while (sz != 0) { | 1229 | while (sz != 0) { |
1230 | --sz; | 1230 | --sz; |
1231 | sg[sz].dvma_address = (__u32)sun4c_lockarea(page_address(sg[sz].page) + sg[sz].offset, sg[sz].length); | 1231 | sg->dvma_address = (__u32)sun4c_lockarea(page_address(sg->page) + sg->offset, sg->length); |
1232 | sg[sz].dvma_length = sg[sz].length; | 1232 | sg->dvma_length = sg->length; |
1233 | sg = sg_next(sg); | ||
1233 | } | 1234 | } |
1234 | } | 1235 | } |
1235 | 1236 | ||
@@ -1244,7 +1245,8 @@ static void sun4c_release_scsi_sgl(struct scatterlist *sg, int sz, struct sbus_b | |||
1244 | { | 1245 | { |
1245 | while (sz != 0) { | 1246 | while (sz != 0) { |
1246 | --sz; | 1247 | --sz; |
1247 | sun4c_unlockarea((char *)sg[sz].dvma_address, sg[sz].length); | 1248 | sun4c_unlockarea((char *)sg->dvma_address, sg->length); |
1249 | sg = sg_next(sg); | ||
1248 | } | 1250 | } |
1249 | } | 1251 | } |
1250 | 1252 | ||
diff --git a/arch/sparc64/kernel/iommu.c b/arch/sparc64/kernel/iommu.c index b35a62167e9c..db3ffcf7a120 100644 --- a/arch/sparc64/kernel/iommu.c +++ b/arch/sparc64/kernel/iommu.c | |||
@@ -10,6 +10,7 @@ | |||
10 | #include <linux/device.h> | 10 | #include <linux/device.h> |
11 | #include <linux/dma-mapping.h> | 11 | #include <linux/dma-mapping.h> |
12 | #include <linux/errno.h> | 12 | #include <linux/errno.h> |
13 | #include <linux/scatterlist.h> | ||
13 | 14 | ||
14 | #ifdef CONFIG_PCI | 15 | #ifdef CONFIG_PCI |
15 | #include <linux/pci.h> | 16 | #include <linux/pci.h> |
@@ -480,7 +481,7 @@ static inline void fill_sg(iopte_t *iopte, struct scatterlist *sg, | |||
480 | unsigned long iopte_protection) | 481 | unsigned long iopte_protection) |
481 | { | 482 | { |
482 | struct scatterlist *dma_sg = sg; | 483 | struct scatterlist *dma_sg = sg; |
483 | struct scatterlist *sg_end = sg + nelems; | 484 | struct scatterlist *sg_end = sg_last(sg, nelems); |
484 | int i; | 485 | int i; |
485 | 486 | ||
486 | for (i = 0; i < nused; i++) { | 487 | for (i = 0; i < nused; i++) { |
@@ -515,7 +516,7 @@ static inline void fill_sg(iopte_t *iopte, struct scatterlist *sg, | |||
515 | len -= (IO_PAGE_SIZE - (tmp & (IO_PAGE_SIZE - 1UL))); | 516 | len -= (IO_PAGE_SIZE - (tmp & (IO_PAGE_SIZE - 1UL))); |
516 | break; | 517 | break; |
517 | } | 518 | } |
518 | sg++; | 519 | sg = sg_next(sg); |
519 | } | 520 | } |
520 | 521 | ||
521 | pteval = iopte_protection | (pteval & IOPTE_PAGE); | 522 | pteval = iopte_protection | (pteval & IOPTE_PAGE); |
@@ -528,24 +529,24 @@ static inline void fill_sg(iopte_t *iopte, struct scatterlist *sg, | |||
528 | } | 529 | } |
529 | 530 | ||
530 | pteval = (pteval & IOPTE_PAGE) + len; | 531 | pteval = (pteval & IOPTE_PAGE) + len; |
531 | sg++; | 532 | sg = sg_next(sg); |
532 | 533 | ||
533 | /* Skip over any tail mappings we've fully mapped, | 534 | /* Skip over any tail mappings we've fully mapped, |
534 | * adjusting pteval along the way. Stop when we | 535 | * adjusting pteval along the way. Stop when we |
535 | * detect a page crossing event. | 536 | * detect a page crossing event. |
536 | */ | 537 | */ |
537 | while (sg < sg_end && | 538 | while (sg != sg_end && |
538 | (pteval << (64 - IO_PAGE_SHIFT)) != 0UL && | 539 | (pteval << (64 - IO_PAGE_SHIFT)) != 0UL && |
539 | (pteval == SG_ENT_PHYS_ADDRESS(sg)) && | 540 | (pteval == SG_ENT_PHYS_ADDRESS(sg)) && |
540 | ((pteval ^ | 541 | ((pteval ^ |
541 | (SG_ENT_PHYS_ADDRESS(sg) + sg->length - 1UL)) >> IO_PAGE_SHIFT) == 0UL) { | 542 | (SG_ENT_PHYS_ADDRESS(sg) + sg->length - 1UL)) >> IO_PAGE_SHIFT) == 0UL) { |
542 | pteval += sg->length; | 543 | pteval += sg->length; |
543 | sg++; | 544 | sg = sg_next(sg); |
544 | } | 545 | } |
545 | if ((pteval << (64 - IO_PAGE_SHIFT)) == 0UL) | 546 | if ((pteval << (64 - IO_PAGE_SHIFT)) == 0UL) |
546 | pteval = ~0UL; | 547 | pteval = ~0UL; |
547 | } while (dma_npages != 0); | 548 | } while (dma_npages != 0); |
548 | dma_sg++; | 549 | dma_sg = sg_next(dma_sg); |
549 | } | 550 | } |
550 | } | 551 | } |
551 | 552 | ||
@@ -606,7 +607,7 @@ static int dma_4u_map_sg(struct device *dev, struct scatterlist *sglist, | |||
606 | sgtmp = sglist; | 607 | sgtmp = sglist; |
607 | while (used && sgtmp->dma_length) { | 608 | while (used && sgtmp->dma_length) { |
608 | sgtmp->dma_address += dma_base; | 609 | sgtmp->dma_address += dma_base; |
609 | sgtmp++; | 610 | sgtmp = sg_next(sgtmp); |
610 | used--; | 611 | used--; |
611 | } | 612 | } |
612 | used = nelems - used; | 613 | used = nelems - used; |
@@ -642,6 +643,7 @@ static void dma_4u_unmap_sg(struct device *dev, struct scatterlist *sglist, | |||
642 | struct strbuf *strbuf; | 643 | struct strbuf *strbuf; |
643 | iopte_t *base; | 644 | iopte_t *base; |
644 | unsigned long flags, ctx, i, npages; | 645 | unsigned long flags, ctx, i, npages; |
646 | struct scatterlist *sg, *sgprv; | ||
645 | u32 bus_addr; | 647 | u32 bus_addr; |
646 | 648 | ||
647 | if (unlikely(direction == DMA_NONE)) { | 649 | if (unlikely(direction == DMA_NONE)) { |
@@ -654,11 +656,14 @@ static void dma_4u_unmap_sg(struct device *dev, struct scatterlist *sglist, | |||
654 | 656 | ||
655 | bus_addr = sglist->dma_address & IO_PAGE_MASK; | 657 | bus_addr = sglist->dma_address & IO_PAGE_MASK; |
656 | 658 | ||
657 | for (i = 1; i < nelems; i++) | 659 | sgprv = NULL; |
658 | if (sglist[i].dma_length == 0) | 660 | for_each_sg(sglist, sg, nelems, i) { |
661 | if (sg->dma_length == 0) | ||
659 | break; | 662 | break; |
660 | i--; | 663 | sgprv = sg; |
661 | npages = (IO_PAGE_ALIGN(sglist[i].dma_address + sglist[i].dma_length) - | 664 | } |
665 | |||
666 | npages = (IO_PAGE_ALIGN(sgprv->dma_address + sgprv->dma_length) - | ||
662 | bus_addr) >> IO_PAGE_SHIFT; | 667 | bus_addr) >> IO_PAGE_SHIFT; |
663 | 668 | ||
664 | base = iommu->page_table + | 669 | base = iommu->page_table + |
@@ -730,6 +735,7 @@ static void dma_4u_sync_sg_for_cpu(struct device *dev, | |||
730 | struct iommu *iommu; | 735 | struct iommu *iommu; |
731 | struct strbuf *strbuf; | 736 | struct strbuf *strbuf; |
732 | unsigned long flags, ctx, npages, i; | 737 | unsigned long flags, ctx, npages, i; |
738 | struct scatterlist *sg, *sgprv; | ||
733 | u32 bus_addr; | 739 | u32 bus_addr; |
734 | 740 | ||
735 | iommu = dev->archdata.iommu; | 741 | iommu = dev->archdata.iommu; |
@@ -753,11 +759,14 @@ static void dma_4u_sync_sg_for_cpu(struct device *dev, | |||
753 | 759 | ||
754 | /* Step 2: Kick data out of streaming buffers. */ | 760 | /* Step 2: Kick data out of streaming buffers. */ |
755 | bus_addr = sglist[0].dma_address & IO_PAGE_MASK; | 761 | bus_addr = sglist[0].dma_address & IO_PAGE_MASK; |
756 | for(i = 1; i < nelems; i++) | 762 | sgprv = NULL; |
757 | if (!sglist[i].dma_length) | 763 | for_each_sg(sglist, sg, nelems, i) { |
764 | if (sg->dma_length == 0) | ||
758 | break; | 765 | break; |
759 | i--; | 766 | sgprv = sg; |
760 | npages = (IO_PAGE_ALIGN(sglist[i].dma_address + sglist[i].dma_length) | 767 | } |
768 | |||
769 | npages = (IO_PAGE_ALIGN(sgprv->dma_address + sgprv->dma_length) | ||
761 | - bus_addr) >> IO_PAGE_SHIFT; | 770 | - bus_addr) >> IO_PAGE_SHIFT; |
762 | strbuf_flush(strbuf, iommu, bus_addr, ctx, npages, direction); | 771 | strbuf_flush(strbuf, iommu, bus_addr, ctx, npages, direction); |
763 | 772 | ||
diff --git a/arch/sparc64/kernel/pci_sun4v.c b/arch/sparc64/kernel/pci_sun4v.c index 95de1444ee67..cacacfae5451 100644 --- a/arch/sparc64/kernel/pci_sun4v.c +++ b/arch/sparc64/kernel/pci_sun4v.c | |||
@@ -13,6 +13,7 @@ | |||
13 | #include <linux/irq.h> | 13 | #include <linux/irq.h> |
14 | #include <linux/msi.h> | 14 | #include <linux/msi.h> |
15 | #include <linux/log2.h> | 15 | #include <linux/log2.h> |
16 | #include <linux/scatterlist.h> | ||
16 | 17 | ||
17 | #include <asm/iommu.h> | 18 | #include <asm/iommu.h> |
18 | #include <asm/irq.h> | 19 | #include <asm/irq.h> |
@@ -373,7 +374,7 @@ static inline long fill_sg(long entry, struct device *dev, | |||
373 | int nused, int nelems, unsigned long prot) | 374 | int nused, int nelems, unsigned long prot) |
374 | { | 375 | { |
375 | struct scatterlist *dma_sg = sg; | 376 | struct scatterlist *dma_sg = sg; |
376 | struct scatterlist *sg_end = sg + nelems; | 377 | struct scatterlist *sg_end = sg_last(sg, nelems); |
377 | unsigned long flags; | 378 | unsigned long flags; |
378 | int i; | 379 | int i; |
379 | 380 | ||
@@ -413,7 +414,7 @@ static inline long fill_sg(long entry, struct device *dev, | |||
413 | len -= (IO_PAGE_SIZE - (tmp & (IO_PAGE_SIZE - 1UL))); | 414 | len -= (IO_PAGE_SIZE - (tmp & (IO_PAGE_SIZE - 1UL))); |
414 | break; | 415 | break; |
415 | } | 416 | } |
416 | sg++; | 417 | sg = sg_next(sg); |
417 | } | 418 | } |
418 | 419 | ||
419 | pteval = (pteval & IOPTE_PAGE); | 420 | pteval = (pteval & IOPTE_PAGE); |
@@ -431,24 +432,25 @@ static inline long fill_sg(long entry, struct device *dev, | |||
431 | } | 432 | } |
432 | 433 | ||
433 | pteval = (pteval & IOPTE_PAGE) + len; | 434 | pteval = (pteval & IOPTE_PAGE) + len; |
434 | sg++; | 435 | sg = sg_next(sg); |
435 | 436 | ||
436 | /* Skip over any tail mappings we've fully mapped, | 437 | /* Skip over any tail mappings we've fully mapped, |
437 | * adjusting pteval along the way. Stop when we | 438 | * adjusting pteval along the way. Stop when we |
438 | * detect a page crossing event. | 439 | * detect a page crossing event. |
439 | */ | 440 | */ |
440 | while (sg < sg_end && | 441 | while ((pteval << (64 - IO_PAGE_SHIFT)) != 0UL && |
441 | (pteval << (64 - IO_PAGE_SHIFT)) != 0UL && | ||
442 | (pteval == SG_ENT_PHYS_ADDRESS(sg)) && | 442 | (pteval == SG_ENT_PHYS_ADDRESS(sg)) && |
443 | ((pteval ^ | 443 | ((pteval ^ |
444 | (SG_ENT_PHYS_ADDRESS(sg) + sg->length - 1UL)) >> IO_PAGE_SHIFT) == 0UL) { | 444 | (SG_ENT_PHYS_ADDRESS(sg) + sg->length - 1UL)) >> IO_PAGE_SHIFT) == 0UL) { |
445 | pteval += sg->length; | 445 | pteval += sg->length; |
446 | sg++; | 446 | if (sg == sg_end) |
447 | break; | ||
448 | sg = sg_next(sg); | ||
447 | } | 449 | } |
448 | if ((pteval << (64 - IO_PAGE_SHIFT)) == 0UL) | 450 | if ((pteval << (64 - IO_PAGE_SHIFT)) == 0UL) |
449 | pteval = ~0UL; | 451 | pteval = ~0UL; |
450 | } while (dma_npages != 0); | 452 | } while (dma_npages != 0); |
451 | dma_sg++; | 453 | dma_sg = sg_next(dma_sg); |
452 | } | 454 | } |
453 | 455 | ||
454 | if (unlikely(iommu_batch_end() < 0L)) | 456 | if (unlikely(iommu_batch_end() < 0L)) |
@@ -510,7 +512,7 @@ static int dma_4v_map_sg(struct device *dev, struct scatterlist *sglist, | |||
510 | sgtmp = sglist; | 512 | sgtmp = sglist; |
511 | while (used && sgtmp->dma_length) { | 513 | while (used && sgtmp->dma_length) { |
512 | sgtmp->dma_address += dma_base; | 514 | sgtmp->dma_address += dma_base; |
513 | sgtmp++; | 515 | sgtmp = sg_next(sgtmp); |
514 | used--; | 516 | used--; |
515 | } | 517 | } |
516 | used = nelems - used; | 518 | used = nelems - used; |
@@ -545,6 +547,7 @@ static void dma_4v_unmap_sg(struct device *dev, struct scatterlist *sglist, | |||
545 | struct pci_pbm_info *pbm; | 547 | struct pci_pbm_info *pbm; |
546 | struct iommu *iommu; | 548 | struct iommu *iommu; |
547 | unsigned long flags, i, npages; | 549 | unsigned long flags, i, npages; |
550 | struct scatterlist *sg, *sgprv; | ||
548 | long entry; | 551 | long entry; |
549 | u32 devhandle, bus_addr; | 552 | u32 devhandle, bus_addr; |
550 | 553 | ||
@@ -558,12 +561,15 @@ static void dma_4v_unmap_sg(struct device *dev, struct scatterlist *sglist, | |||
558 | devhandle = pbm->devhandle; | 561 | devhandle = pbm->devhandle; |
559 | 562 | ||
560 | bus_addr = sglist->dma_address & IO_PAGE_MASK; | 563 | bus_addr = sglist->dma_address & IO_PAGE_MASK; |
561 | 564 | sgprv = NULL; | |
562 | for (i = 1; i < nelems; i++) | 565 | for_each_sg(sglist, sg, nelems, i) { |
563 | if (sglist[i].dma_length == 0) | 566 | if (sg->dma_length == 0) |
564 | break; | 567 | break; |
565 | i--; | 568 | |
566 | npages = (IO_PAGE_ALIGN(sglist[i].dma_address + sglist[i].dma_length) - | 569 | sgprv = sg; |
570 | } | ||
571 | |||
572 | npages = (IO_PAGE_ALIGN(sgprv->dma_address + sgprv->dma_length) - | ||
567 | bus_addr) >> IO_PAGE_SHIFT; | 573 | bus_addr) >> IO_PAGE_SHIFT; |
568 | 574 | ||
569 | entry = ((bus_addr - iommu->page_table_map_base) >> IO_PAGE_SHIFT); | 575 | entry = ((bus_addr - iommu->page_table_map_base) >> IO_PAGE_SHIFT); |
diff --git a/arch/x86/kernel/pci-calgary_64.c b/arch/x86/kernel/pci-calgary_64.c index 71da01e73f03..a50b787b3bfa 100644 --- a/arch/x86/kernel/pci-calgary_64.c +++ b/arch/x86/kernel/pci-calgary_64.c | |||
@@ -35,6 +35,7 @@ | |||
35 | #include <linux/pci_ids.h> | 35 | #include <linux/pci_ids.h> |
36 | #include <linux/pci.h> | 36 | #include <linux/pci.h> |
37 | #include <linux/delay.h> | 37 | #include <linux/delay.h> |
38 | #include <linux/scatterlist.h> | ||
38 | #include <asm/iommu.h> | 39 | #include <asm/iommu.h> |
39 | #include <asm/calgary.h> | 40 | #include <asm/calgary.h> |
40 | #include <asm/tce.h> | 41 | #include <asm/tce.h> |
@@ -384,31 +385,32 @@ static void calgary_unmap_sg(struct device *dev, | |||
384 | struct scatterlist *sglist, int nelems, int direction) | 385 | struct scatterlist *sglist, int nelems, int direction) |
385 | { | 386 | { |
386 | struct iommu_table *tbl = find_iommu_table(dev); | 387 | struct iommu_table *tbl = find_iommu_table(dev); |
388 | struct scatterlist *s; | ||
389 | int i; | ||
387 | 390 | ||
388 | if (!translate_phb(to_pci_dev(dev))) | 391 | if (!translate_phb(to_pci_dev(dev))) |
389 | return; | 392 | return; |
390 | 393 | ||
391 | while (nelems--) { | 394 | for_each_sg(sglist, s, nelems, i) { |
392 | unsigned int npages; | 395 | unsigned int npages; |
393 | dma_addr_t dma = sglist->dma_address; | 396 | dma_addr_t dma = s->dma_address; |
394 | unsigned int dmalen = sglist->dma_length; | 397 | unsigned int dmalen = s->dma_length; |
395 | 398 | ||
396 | if (dmalen == 0) | 399 | if (dmalen == 0) |
397 | break; | 400 | break; |
398 | 401 | ||
399 | npages = num_dma_pages(dma, dmalen); | 402 | npages = num_dma_pages(dma, dmalen); |
400 | iommu_free(tbl, dma, npages); | 403 | iommu_free(tbl, dma, npages); |
401 | sglist++; | ||
402 | } | 404 | } |
403 | } | 405 | } |
404 | 406 | ||
405 | static int calgary_nontranslate_map_sg(struct device* dev, | 407 | static int calgary_nontranslate_map_sg(struct device* dev, |
406 | struct scatterlist *sg, int nelems, int direction) | 408 | struct scatterlist *sg, int nelems, int direction) |
407 | { | 409 | { |
410 | struct scatterlist *s; | ||
408 | int i; | 411 | int i; |
409 | 412 | ||
410 | for (i = 0; i < nelems; i++ ) { | 413 | for_each_sg(sg, s, nelems, i) { |
411 | struct scatterlist *s = &sg[i]; | ||
412 | BUG_ON(!s->page); | 414 | BUG_ON(!s->page); |
413 | s->dma_address = virt_to_bus(page_address(s->page) +s->offset); | 415 | s->dma_address = virt_to_bus(page_address(s->page) +s->offset); |
414 | s->dma_length = s->length; | 416 | s->dma_length = s->length; |
@@ -420,6 +422,7 @@ static int calgary_map_sg(struct device *dev, struct scatterlist *sg, | |||
420 | int nelems, int direction) | 422 | int nelems, int direction) |
421 | { | 423 | { |
422 | struct iommu_table *tbl = find_iommu_table(dev); | 424 | struct iommu_table *tbl = find_iommu_table(dev); |
425 | struct scatterlist *s; | ||
423 | unsigned long vaddr; | 426 | unsigned long vaddr; |
424 | unsigned int npages; | 427 | unsigned int npages; |
425 | unsigned long entry; | 428 | unsigned long entry; |
@@ -428,8 +431,7 @@ static int calgary_map_sg(struct device *dev, struct scatterlist *sg, | |||
428 | if (!translate_phb(to_pci_dev(dev))) | 431 | if (!translate_phb(to_pci_dev(dev))) |
429 | return calgary_nontranslate_map_sg(dev, sg, nelems, direction); | 432 | return calgary_nontranslate_map_sg(dev, sg, nelems, direction); |
430 | 433 | ||
431 | for (i = 0; i < nelems; i++ ) { | 434 | for_each_sg(sg, s, nelems, i) { |
432 | struct scatterlist *s = &sg[i]; | ||
433 | BUG_ON(!s->page); | 435 | BUG_ON(!s->page); |
434 | 436 | ||
435 | vaddr = (unsigned long)page_address(s->page) + s->offset; | 437 | vaddr = (unsigned long)page_address(s->page) + s->offset; |
@@ -454,9 +456,9 @@ static int calgary_map_sg(struct device *dev, struct scatterlist *sg, | |||
454 | return nelems; | 456 | return nelems; |
455 | error: | 457 | error: |
456 | calgary_unmap_sg(dev, sg, nelems, direction); | 458 | calgary_unmap_sg(dev, sg, nelems, direction); |
457 | for (i = 0; i < nelems; i++) { | 459 | for_each_sg(sg, s, nelems, i) { |
458 | sg[i].dma_address = bad_dma_address; | 460 | sg->dma_address = bad_dma_address; |
459 | sg[i].dma_length = 0; | 461 | sg->dma_length = 0; |
460 | } | 462 | } |
461 | return 0; | 463 | return 0; |
462 | } | 464 | } |
diff --git a/arch/x86/kernel/pci-gart_64.c b/arch/x86/kernel/pci-gart_64.c index 4918c575d582..cfcc84e6c350 100644 --- a/arch/x86/kernel/pci-gart_64.c +++ b/arch/x86/kernel/pci-gart_64.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <linux/interrupt.h> | 23 | #include <linux/interrupt.h> |
24 | #include <linux/bitops.h> | 24 | #include <linux/bitops.h> |
25 | #include <linux/kdebug.h> | 25 | #include <linux/kdebug.h> |
26 | #include <linux/scatterlist.h> | ||
26 | #include <asm/atomic.h> | 27 | #include <asm/atomic.h> |
27 | #include <asm/io.h> | 28 | #include <asm/io.h> |
28 | #include <asm/mtrr.h> | 29 | #include <asm/mtrr.h> |
@@ -278,10 +279,10 @@ static void gart_unmap_single(struct device *dev, dma_addr_t dma_addr, | |||
278 | */ | 279 | */ |
279 | static void gart_unmap_sg(struct device *dev, struct scatterlist *sg, int nents, int dir) | 280 | static void gart_unmap_sg(struct device *dev, struct scatterlist *sg, int nents, int dir) |
280 | { | 281 | { |
282 | struct scatterlist *s; | ||
281 | int i; | 283 | int i; |
282 | 284 | ||
283 | for (i = 0; i < nents; i++) { | 285 | for_each_sg(sg, s, nents, i) { |
284 | struct scatterlist *s = &sg[i]; | ||
285 | if (!s->dma_length || !s->length) | 286 | if (!s->dma_length || !s->length) |
286 | break; | 287 | break; |
287 | gart_unmap_single(dev, s->dma_address, s->dma_length, dir); | 288 | gart_unmap_single(dev, s->dma_address, s->dma_length, dir); |
@@ -292,14 +293,14 @@ static void gart_unmap_sg(struct device *dev, struct scatterlist *sg, int nents, | |||
292 | static int dma_map_sg_nonforce(struct device *dev, struct scatterlist *sg, | 293 | static int dma_map_sg_nonforce(struct device *dev, struct scatterlist *sg, |
293 | int nents, int dir) | 294 | int nents, int dir) |
294 | { | 295 | { |
296 | struct scatterlist *s; | ||
295 | int i; | 297 | int i; |
296 | 298 | ||
297 | #ifdef CONFIG_IOMMU_DEBUG | 299 | #ifdef CONFIG_IOMMU_DEBUG |
298 | printk(KERN_DEBUG "dma_map_sg overflow\n"); | 300 | printk(KERN_DEBUG "dma_map_sg overflow\n"); |
299 | #endif | 301 | #endif |
300 | 302 | ||
301 | for (i = 0; i < nents; i++ ) { | 303 | for_each_sg(sg, s, nents, i) { |
302 | struct scatterlist *s = &sg[i]; | ||
303 | unsigned long addr = page_to_phys(s->page) + s->offset; | 304 | unsigned long addr = page_to_phys(s->page) + s->offset; |
304 | if (nonforced_iommu(dev, addr, s->length)) { | 305 | if (nonforced_iommu(dev, addr, s->length)) { |
305 | addr = dma_map_area(dev, addr, s->length, dir); | 306 | addr = dma_map_area(dev, addr, s->length, dir); |
@@ -319,23 +320,23 @@ static int dma_map_sg_nonforce(struct device *dev, struct scatterlist *sg, | |||
319 | } | 320 | } |
320 | 321 | ||
321 | /* Map multiple scatterlist entries continuous into the first. */ | 322 | /* Map multiple scatterlist entries continuous into the first. */ |
322 | static int __dma_map_cont(struct scatterlist *sg, int start, int stopat, | 323 | static int __dma_map_cont(struct scatterlist *start, int nelems, |
323 | struct scatterlist *sout, unsigned long pages) | 324 | struct scatterlist *sout, unsigned long pages) |
324 | { | 325 | { |
325 | unsigned long iommu_start = alloc_iommu(pages); | 326 | unsigned long iommu_start = alloc_iommu(pages); |
326 | unsigned long iommu_page = iommu_start; | 327 | unsigned long iommu_page = iommu_start; |
328 | struct scatterlist *s; | ||
327 | int i; | 329 | int i; |
328 | 330 | ||
329 | if (iommu_start == -1) | 331 | if (iommu_start == -1) |
330 | return -1; | 332 | return -1; |
331 | 333 | ||
332 | for (i = start; i < stopat; i++) { | 334 | for_each_sg(start, s, nelems, i) { |
333 | struct scatterlist *s = &sg[i]; | ||
334 | unsigned long pages, addr; | 335 | unsigned long pages, addr; |
335 | unsigned long phys_addr = s->dma_address; | 336 | unsigned long phys_addr = s->dma_address; |
336 | 337 | ||
337 | BUG_ON(i > start && s->offset); | 338 | BUG_ON(s != start && s->offset); |
338 | if (i == start) { | 339 | if (s == start) { |
339 | *sout = *s; | 340 | *sout = *s; |
340 | sout->dma_address = iommu_bus_base; | 341 | sout->dma_address = iommu_bus_base; |
341 | sout->dma_address += iommu_page*PAGE_SIZE + s->offset; | 342 | sout->dma_address += iommu_page*PAGE_SIZE + s->offset; |
@@ -357,17 +358,17 @@ static int __dma_map_cont(struct scatterlist *sg, int start, int stopat, | |||
357 | return 0; | 358 | return 0; |
358 | } | 359 | } |
359 | 360 | ||
360 | static inline int dma_map_cont(struct scatterlist *sg, int start, int stopat, | 361 | static inline int dma_map_cont(struct scatterlist *start, int nelems, |
361 | struct scatterlist *sout, | 362 | struct scatterlist *sout, |
362 | unsigned long pages, int need) | 363 | unsigned long pages, int need) |
363 | { | 364 | { |
364 | if (!need) { | 365 | if (!need) { |
365 | BUG_ON(stopat - start != 1); | 366 | BUG_ON(nelems != 1); |
366 | *sout = sg[start]; | 367 | *sout = *start; |
367 | sout->dma_length = sg[start].length; | 368 | sout->dma_length = start->length; |
368 | return 0; | 369 | return 0; |
369 | } | 370 | } |
370 | return __dma_map_cont(sg, start, stopat, sout, pages); | 371 | return __dma_map_cont(start, nelems, sout, pages); |
371 | } | 372 | } |
372 | 373 | ||
373 | /* | 374 | /* |
@@ -381,6 +382,7 @@ int gart_map_sg(struct device *dev, struct scatterlist *sg, int nents, int dir) | |||
381 | int start; | 382 | int start; |
382 | unsigned long pages = 0; | 383 | unsigned long pages = 0; |
383 | int need = 0, nextneed; | 384 | int need = 0, nextneed; |
385 | struct scatterlist *s, *ps, *start_sg, *sgmap; | ||
384 | 386 | ||
385 | if (nents == 0) | 387 | if (nents == 0) |
386 | return 0; | 388 | return 0; |
@@ -390,8 +392,9 @@ int gart_map_sg(struct device *dev, struct scatterlist *sg, int nents, int dir) | |||
390 | 392 | ||
391 | out = 0; | 393 | out = 0; |
392 | start = 0; | 394 | start = 0; |
393 | for (i = 0; i < nents; i++) { | 395 | start_sg = sgmap = sg; |
394 | struct scatterlist *s = &sg[i]; | 396 | ps = NULL; /* shut up gcc */ |
397 | for_each_sg(sg, s, nents, i) { | ||
395 | dma_addr_t addr = page_to_phys(s->page) + s->offset; | 398 | dma_addr_t addr = page_to_phys(s->page) + s->offset; |
396 | s->dma_address = addr; | 399 | s->dma_address = addr; |
397 | BUG_ON(s->length == 0); | 400 | BUG_ON(s->length == 0); |
@@ -400,29 +403,33 @@ int gart_map_sg(struct device *dev, struct scatterlist *sg, int nents, int dir) | |||
400 | 403 | ||
401 | /* Handle the previous not yet processed entries */ | 404 | /* Handle the previous not yet processed entries */ |
402 | if (i > start) { | 405 | if (i > start) { |
403 | struct scatterlist *ps = &sg[i-1]; | ||
404 | /* Can only merge when the last chunk ends on a page | 406 | /* Can only merge when the last chunk ends on a page |
405 | boundary and the new one doesn't have an offset. */ | 407 | boundary and the new one doesn't have an offset. */ |
406 | if (!iommu_merge || !nextneed || !need || s->offset || | 408 | if (!iommu_merge || !nextneed || !need || s->offset || |
407 | (ps->offset + ps->length) % PAGE_SIZE) { | 409 | (ps->offset + ps->length) % PAGE_SIZE) { |
408 | if (dma_map_cont(sg, start, i, sg+out, pages, | 410 | if (dma_map_cont(start_sg, i - start, sgmap, |
409 | need) < 0) | 411 | pages, need) < 0) |
410 | goto error; | 412 | goto error; |
411 | out++; | 413 | out++; |
414 | sgmap = sg_next(sgmap); | ||
412 | pages = 0; | 415 | pages = 0; |
413 | start = i; | 416 | start = i; |
417 | start_sg = s; | ||
414 | } | 418 | } |
415 | } | 419 | } |
416 | 420 | ||
417 | need = nextneed; | 421 | need = nextneed; |
418 | pages += to_pages(s->offset, s->length); | 422 | pages += to_pages(s->offset, s->length); |
423 | ps = s; | ||
419 | } | 424 | } |
420 | if (dma_map_cont(sg, start, i, sg+out, pages, need) < 0) | 425 | if (dma_map_cont(start_sg, i - start, sgmap, pages, need) < 0) |
421 | goto error; | 426 | goto error; |
422 | out++; | 427 | out++; |
423 | flush_gart(); | 428 | flush_gart(); |
424 | if (out < nents) | 429 | if (out < nents) { |
425 | sg[out].dma_length = 0; | 430 | sgmap = sg_next(sgmap); |
431 | sgmap->dma_length = 0; | ||
432 | } | ||
426 | return out; | 433 | return out; |
427 | 434 | ||
428 | error: | 435 | error: |
@@ -437,8 +444,8 @@ error: | |||
437 | if (panic_on_overflow) | 444 | if (panic_on_overflow) |
438 | panic("dma_map_sg: overflow on %lu pages\n", pages); | 445 | panic("dma_map_sg: overflow on %lu pages\n", pages); |
439 | iommu_full(dev, pages << PAGE_SHIFT, dir); | 446 | iommu_full(dev, pages << PAGE_SHIFT, dir); |
440 | for (i = 0; i < nents; i++) | 447 | for_each_sg(sg, s, nents, i) |
441 | sg[i].dma_address = bad_dma_address; | 448 | s->dma_address = bad_dma_address; |
442 | return 0; | 449 | return 0; |
443 | } | 450 | } |
444 | 451 | ||
diff --git a/arch/x86/kernel/pci-nommu_64.c b/arch/x86/kernel/pci-nommu_64.c index 2a34c6c025a9..e85d4360360c 100644 --- a/arch/x86/kernel/pci-nommu_64.c +++ b/arch/x86/kernel/pci-nommu_64.c | |||
@@ -5,6 +5,7 @@ | |||
5 | #include <linux/pci.h> | 5 | #include <linux/pci.h> |
6 | #include <linux/string.h> | 6 | #include <linux/string.h> |
7 | #include <linux/dma-mapping.h> | 7 | #include <linux/dma-mapping.h> |
8 | #include <linux/scatterlist.h> | ||
8 | 9 | ||
9 | #include <asm/iommu.h> | 10 | #include <asm/iommu.h> |
10 | #include <asm/processor.h> | 11 | #include <asm/processor.h> |
@@ -57,10 +58,10 @@ static void nommu_unmap_single(struct device *dev, dma_addr_t addr,size_t size, | |||
57 | static int nommu_map_sg(struct device *hwdev, struct scatterlist *sg, | 58 | static int nommu_map_sg(struct device *hwdev, struct scatterlist *sg, |
58 | int nents, int direction) | 59 | int nents, int direction) |
59 | { | 60 | { |
61 | struct scatterlist *s; | ||
60 | int i; | 62 | int i; |
61 | 63 | ||
62 | for (i = 0; i < nents; i++ ) { | 64 | for_each_sg(sg, s, nents, i) { |
63 | struct scatterlist *s = &sg[i]; | ||
64 | BUG_ON(!s->page); | 65 | BUG_ON(!s->page); |
65 | s->dma_address = virt_to_bus(page_address(s->page) +s->offset); | 66 | s->dma_address = virt_to_bus(page_address(s->page) +s->offset); |
66 | if (!check_addr("map_sg", hwdev, s->dma_address, s->length)) | 67 | if (!check_addr("map_sg", hwdev, s->dma_address, s->length)) |