aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorJens Axboe <jens.axboe@oracle.com>2007-05-14 09:44:38 -0400
committerJens Axboe <jens.axboe@oracle.com>2007-10-16 05:27:32 -0400
commit0912a5db0ea45d8aef3ee99a882e093285e32c3c (patch)
treeeef222f8bce729c7bf0fa988e0c77918032f55a3 /arch
parent78bdc3106a877cfa50439fa66b52acbc4e7868df (diff)
SPARC: sg chaining support
This updates the sparc iommu/pci dma mappers to sg chaining. Acked-by: David S. Miller <davem@davemloft.net> Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
Diffstat (limited to 'arch')
-rw-r--r--arch/sparc/kernel/ioport.c25
-rw-r--r--arch/sparc/mm/io-unit.c12
-rw-r--r--arch/sparc/mm/iommu.c10
-rw-r--r--arch/sparc/mm/sun4c.c10
4 files changed, 31 insertions, 26 deletions
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 */
720int pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sg, int nents, 721int 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 */
741void pci_unmap_sg(struct pci_dev *hwdev, struct scatterlist *sg, int nents, 742void 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 */
792void pci_dma_sync_sg_for_cpu(struct pci_dev *hwdev, struct scatterlist *sg, int nents, int direction) 793void 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
808void pci_dma_sync_sg_for_device(struct pci_dev *hwdev, struct scatterlist *sg, int nents, int direction) 809void 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