diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/powerpc/include/asm/iommu.h | 15 | ||||
-rw-r--r-- | arch/powerpc/kernel/dma-iommu.c | 34 | ||||
-rw-r--r-- | arch/powerpc/kernel/ibmebus.c | 27 | ||||
-rw-r--r-- | arch/powerpc/kernel/iommu.c | 22 | ||||
-rw-r--r-- | arch/powerpc/kernel/vio.c | 25 | ||||
-rw-r--r-- | arch/powerpc/platforms/cell/iommu.c | 37 | ||||
-rw-r--r-- | arch/powerpc/platforms/iseries/iommu.c | 7 | ||||
-rw-r--r-- | arch/powerpc/platforms/ps3/system-bus.c | 36 |
8 files changed, 104 insertions, 99 deletions
diff --git a/arch/powerpc/include/asm/iommu.h b/arch/powerpc/include/asm/iommu.h index 51ecfef8d843..7464c0daddd1 100644 --- a/arch/powerpc/include/asm/iommu.h +++ b/arch/powerpc/include/asm/iommu.h | |||
@@ -92,13 +92,14 @@ extern void *iommu_alloc_coherent(struct device *dev, struct iommu_table *tbl, | |||
92 | unsigned long mask, gfp_t flag, int node); | 92 | unsigned long mask, gfp_t flag, int node); |
93 | extern void iommu_free_coherent(struct iommu_table *tbl, size_t size, | 93 | extern void iommu_free_coherent(struct iommu_table *tbl, size_t size, |
94 | void *vaddr, dma_addr_t dma_handle); | 94 | void *vaddr, dma_addr_t dma_handle); |
95 | extern dma_addr_t iommu_map_single(struct device *dev, struct iommu_table *tbl, | 95 | extern dma_addr_t iommu_map_page(struct device *dev, struct iommu_table *tbl, |
96 | void *vaddr, size_t size, unsigned long mask, | 96 | struct page *page, unsigned long offset, |
97 | enum dma_data_direction direction, | 97 | size_t size, unsigned long mask, |
98 | struct dma_attrs *attrs); | 98 | enum dma_data_direction direction, |
99 | extern void iommu_unmap_single(struct iommu_table *tbl, dma_addr_t dma_handle, | 99 | struct dma_attrs *attrs); |
100 | size_t size, enum dma_data_direction direction, | 100 | extern void iommu_unmap_page(struct iommu_table *tbl, dma_addr_t dma_handle, |
101 | struct dma_attrs *attrs); | 101 | size_t size, enum dma_data_direction direction, |
102 | struct dma_attrs *attrs); | ||
102 | 103 | ||
103 | extern void iommu_init_early_pSeries(void); | 104 | extern void iommu_init_early_pSeries(void); |
104 | extern void iommu_init_early_iSeries(void); | 105 | extern void iommu_init_early_iSeries(void); |
diff --git a/arch/powerpc/kernel/dma-iommu.c b/arch/powerpc/kernel/dma-iommu.c index 49248f89ce23..14183af1b3fb 100644 --- a/arch/powerpc/kernel/dma-iommu.c +++ b/arch/powerpc/kernel/dma-iommu.c | |||
@@ -30,28 +30,26 @@ static void dma_iommu_free_coherent(struct device *dev, size_t size, | |||
30 | } | 30 | } |
31 | 31 | ||
32 | /* Creates TCEs for a user provided buffer. The user buffer must be | 32 | /* Creates TCEs for a user provided buffer. The user buffer must be |
33 | * contiguous real kernel storage (not vmalloc). The address of the buffer | 33 | * contiguous real kernel storage (not vmalloc). The address passed here |
34 | * passed here is the kernel (virtual) address of the buffer. The buffer | 34 | * comprises a page address and offset into that page. The dma_addr_t |
35 | * need not be page aligned, the dma_addr_t returned will point to the same | 35 | * returned will point to the same byte within the page as was passed in. |
36 | * byte within the page as vaddr. | ||
37 | */ | 36 | */ |
38 | static dma_addr_t dma_iommu_map_single(struct device *dev, void *vaddr, | 37 | static dma_addr_t dma_iommu_map_page(struct device *dev, struct page *page, |
39 | size_t size, | 38 | unsigned long offset, size_t size, |
40 | enum dma_data_direction direction, | 39 | enum dma_data_direction direction, |
41 | struct dma_attrs *attrs) | 40 | struct dma_attrs *attrs) |
42 | { | 41 | { |
43 | return iommu_map_single(dev, dev->archdata.dma_data, vaddr, size, | 42 | return iommu_map_page(dev, dev->archdata.dma_data, page, offset, size, |
44 | device_to_mask(dev), direction, attrs); | 43 | device_to_mask(dev), direction, attrs); |
45 | } | 44 | } |
46 | 45 | ||
47 | 46 | ||
48 | static void dma_iommu_unmap_single(struct device *dev, dma_addr_t dma_handle, | 47 | static void dma_iommu_unmap_page(struct device *dev, dma_addr_t dma_handle, |
49 | size_t size, | 48 | size_t size, enum dma_data_direction direction, |
50 | enum dma_data_direction direction, | 49 | struct dma_attrs *attrs) |
51 | struct dma_attrs *attrs) | ||
52 | { | 50 | { |
53 | iommu_unmap_single(dev->archdata.dma_data, dma_handle, size, direction, | 51 | iommu_unmap_page(dev->archdata.dma_data, dma_handle, size, direction, |
54 | attrs); | 52 | attrs); |
55 | } | 53 | } |
56 | 54 | ||
57 | 55 | ||
@@ -94,10 +92,10 @@ static int dma_iommu_dma_supported(struct device *dev, u64 mask) | |||
94 | struct dma_mapping_ops dma_iommu_ops = { | 92 | struct dma_mapping_ops dma_iommu_ops = { |
95 | .alloc_coherent = dma_iommu_alloc_coherent, | 93 | .alloc_coherent = dma_iommu_alloc_coherent, |
96 | .free_coherent = dma_iommu_free_coherent, | 94 | .free_coherent = dma_iommu_free_coherent, |
97 | .map_single = dma_iommu_map_single, | ||
98 | .unmap_single = dma_iommu_unmap_single, | ||
99 | .map_sg = dma_iommu_map_sg, | 95 | .map_sg = dma_iommu_map_sg, |
100 | .unmap_sg = dma_iommu_unmap_sg, | 96 | .unmap_sg = dma_iommu_unmap_sg, |
101 | .dma_supported = dma_iommu_dma_supported, | 97 | .dma_supported = dma_iommu_dma_supported, |
98 | .map_page = dma_iommu_map_page, | ||
99 | .unmap_page = dma_iommu_unmap_page, | ||
102 | }; | 100 | }; |
103 | EXPORT_SYMBOL(dma_iommu_ops); | 101 | EXPORT_SYMBOL(dma_iommu_ops); |
diff --git a/arch/powerpc/kernel/ibmebus.c b/arch/powerpc/kernel/ibmebus.c index a06362223f8d..64299d28f364 100644 --- a/arch/powerpc/kernel/ibmebus.c +++ b/arch/powerpc/kernel/ibmebus.c | |||
@@ -79,20 +79,21 @@ static void ibmebus_free_coherent(struct device *dev, | |||
79 | kfree(vaddr); | 79 | kfree(vaddr); |
80 | } | 80 | } |
81 | 81 | ||
82 | static dma_addr_t ibmebus_map_single(struct device *dev, | 82 | static dma_addr_t ibmebus_map_page(struct device *dev, |
83 | void *ptr, | 83 | struct page *page, |
84 | size_t size, | 84 | unsigned long offset, |
85 | enum dma_data_direction direction, | 85 | size_t size, |
86 | struct dma_attrs *attrs) | 86 | enum dma_data_direction direction, |
87 | struct dma_attrs *attrs) | ||
87 | { | 88 | { |
88 | return (dma_addr_t)(ptr); | 89 | return (dma_addr_t)(page_address(page) + offset); |
89 | } | 90 | } |
90 | 91 | ||
91 | static void ibmebus_unmap_single(struct device *dev, | 92 | static void ibmebus_unmap_page(struct device *dev, |
92 | dma_addr_t dma_addr, | 93 | dma_addr_t dma_addr, |
93 | size_t size, | 94 | size_t size, |
94 | enum dma_data_direction direction, | 95 | enum dma_data_direction direction, |
95 | struct dma_attrs *attrs) | 96 | struct dma_attrs *attrs) |
96 | { | 97 | { |
97 | return; | 98 | return; |
98 | } | 99 | } |
@@ -129,11 +130,11 @@ static int ibmebus_dma_supported(struct device *dev, u64 mask) | |||
129 | static struct dma_mapping_ops ibmebus_dma_ops = { | 130 | static struct dma_mapping_ops ibmebus_dma_ops = { |
130 | .alloc_coherent = ibmebus_alloc_coherent, | 131 | .alloc_coherent = ibmebus_alloc_coherent, |
131 | .free_coherent = ibmebus_free_coherent, | 132 | .free_coherent = ibmebus_free_coherent, |
132 | .map_single = ibmebus_map_single, | ||
133 | .unmap_single = ibmebus_unmap_single, | ||
134 | .map_sg = ibmebus_map_sg, | 133 | .map_sg = ibmebus_map_sg, |
135 | .unmap_sg = ibmebus_unmap_sg, | 134 | .unmap_sg = ibmebus_unmap_sg, |
136 | .dma_supported = ibmebus_dma_supported, | 135 | .dma_supported = ibmebus_dma_supported, |
136 | .map_page = ibmebus_map_page, | ||
137 | .unmap_page = ibmebus_unmap_page, | ||
137 | }; | 138 | }; |
138 | 139 | ||
139 | static int ibmebus_match_path(struct device *dev, void *data) | 140 | static int ibmebus_match_path(struct device *dev, void *data) |
diff --git a/arch/powerpc/kernel/iommu.c b/arch/powerpc/kernel/iommu.c index 45f47c97fd14..1bfa706b96e7 100644 --- a/arch/powerpc/kernel/iommu.c +++ b/arch/powerpc/kernel/iommu.c | |||
@@ -565,21 +565,23 @@ void iommu_free_table(struct iommu_table *tbl, const char *node_name) | |||
565 | } | 565 | } |
566 | 566 | ||
567 | /* Creates TCEs for a user provided buffer. The user buffer must be | 567 | /* Creates TCEs for a user provided buffer. The user buffer must be |
568 | * contiguous real kernel storage (not vmalloc). The address of the buffer | 568 | * contiguous real kernel storage (not vmalloc). The address passed here |
569 | * passed here is the kernel (virtual) address of the buffer. The buffer | 569 | * comprises a page address and offset into that page. The dma_addr_t |
570 | * need not be page aligned, the dma_addr_t returned will point to the same | 570 | * returned will point to the same byte within the page as was passed in. |
571 | * byte within the page as vaddr. | ||
572 | */ | 571 | */ |
573 | dma_addr_t iommu_map_single(struct device *dev, struct iommu_table *tbl, | 572 | dma_addr_t iommu_map_page(struct device *dev, struct iommu_table *tbl, |
574 | void *vaddr, size_t size, unsigned long mask, | 573 | struct page *page, unsigned long offset, size_t size, |
575 | enum dma_data_direction direction, struct dma_attrs *attrs) | 574 | unsigned long mask, enum dma_data_direction direction, |
575 | struct dma_attrs *attrs) | ||
576 | { | 576 | { |
577 | dma_addr_t dma_handle = DMA_ERROR_CODE; | 577 | dma_addr_t dma_handle = DMA_ERROR_CODE; |
578 | void *vaddr; | ||
578 | unsigned long uaddr; | 579 | unsigned long uaddr; |
579 | unsigned int npages, align; | 580 | unsigned int npages, align; |
580 | 581 | ||
581 | BUG_ON(direction == DMA_NONE); | 582 | BUG_ON(direction == DMA_NONE); |
582 | 583 | ||
584 | vaddr = page_address(page) + offset; | ||
583 | uaddr = (unsigned long)vaddr; | 585 | uaddr = (unsigned long)vaddr; |
584 | npages = iommu_num_pages(uaddr, size, IOMMU_PAGE_SIZE); | 586 | npages = iommu_num_pages(uaddr, size, IOMMU_PAGE_SIZE); |
585 | 587 | ||
@@ -605,9 +607,9 @@ dma_addr_t iommu_map_single(struct device *dev, struct iommu_table *tbl, | |||
605 | return dma_handle; | 607 | return dma_handle; |
606 | } | 608 | } |
607 | 609 | ||
608 | void iommu_unmap_single(struct iommu_table *tbl, dma_addr_t dma_handle, | 610 | void iommu_unmap_page(struct iommu_table *tbl, dma_addr_t dma_handle, |
609 | size_t size, enum dma_data_direction direction, | 611 | size_t size, enum dma_data_direction direction, |
610 | struct dma_attrs *attrs) | 612 | struct dma_attrs *attrs) |
611 | { | 613 | { |
612 | unsigned int npages; | 614 | unsigned int npages; |
613 | 615 | ||
diff --git a/arch/powerpc/kernel/vio.c b/arch/powerpc/kernel/vio.c index 434c92a85c03..a11e6bc59b30 100644 --- a/arch/powerpc/kernel/vio.c +++ b/arch/powerpc/kernel/vio.c | |||
@@ -516,10 +516,10 @@ static void vio_dma_iommu_free_coherent(struct device *dev, size_t size, | |||
516 | vio_cmo_dealloc(viodev, roundup(size, IOMMU_PAGE_SIZE)); | 516 | vio_cmo_dealloc(viodev, roundup(size, IOMMU_PAGE_SIZE)); |
517 | } | 517 | } |
518 | 518 | ||
519 | static dma_addr_t vio_dma_iommu_map_single(struct device *dev, void *vaddr, | 519 | static dma_addr_t vio_dma_iommu_map_page(struct device *dev, struct page *page, |
520 | size_t size, | 520 | unsigned long offset, size_t size, |
521 | enum dma_data_direction direction, | 521 | enum dma_data_direction direction, |
522 | struct dma_attrs *attrs) | 522 | struct dma_attrs *attrs) |
523 | { | 523 | { |
524 | struct vio_dev *viodev = to_vio_dev(dev); | 524 | struct vio_dev *viodev = to_vio_dev(dev); |
525 | dma_addr_t ret = DMA_ERROR_CODE; | 525 | dma_addr_t ret = DMA_ERROR_CODE; |
@@ -529,7 +529,7 @@ static dma_addr_t vio_dma_iommu_map_single(struct device *dev, void *vaddr, | |||
529 | return ret; | 529 | return ret; |
530 | } | 530 | } |
531 | 531 | ||
532 | ret = dma_iommu_ops.map_single(dev, vaddr, size, direction, attrs); | 532 | ret = dma_iommu_ops.map_page(dev, page, offset, size, direction, attrs); |
533 | if (unlikely(dma_mapping_error(dev, ret))) { | 533 | if (unlikely(dma_mapping_error(dev, ret))) { |
534 | vio_cmo_dealloc(viodev, roundup(size, IOMMU_PAGE_SIZE)); | 534 | vio_cmo_dealloc(viodev, roundup(size, IOMMU_PAGE_SIZE)); |
535 | atomic_inc(&viodev->cmo.allocs_failed); | 535 | atomic_inc(&viodev->cmo.allocs_failed); |
@@ -538,14 +538,14 @@ static dma_addr_t vio_dma_iommu_map_single(struct device *dev, void *vaddr, | |||
538 | return ret; | 538 | return ret; |
539 | } | 539 | } |
540 | 540 | ||
541 | static void vio_dma_iommu_unmap_single(struct device *dev, | 541 | static void vio_dma_iommu_unmap_page(struct device *dev, dma_addr_t dma_handle, |
542 | dma_addr_t dma_handle, size_t size, | 542 | size_t size, |
543 | enum dma_data_direction direction, | 543 | enum dma_data_direction direction, |
544 | struct dma_attrs *attrs) | 544 | struct dma_attrs *attrs) |
545 | { | 545 | { |
546 | struct vio_dev *viodev = to_vio_dev(dev); | 546 | struct vio_dev *viodev = to_vio_dev(dev); |
547 | 547 | ||
548 | dma_iommu_ops.unmap_single(dev, dma_handle, size, direction, attrs); | 548 | dma_iommu_ops.unmap_page(dev, dma_handle, size, direction, attrs); |
549 | 549 | ||
550 | vio_cmo_dealloc(viodev, roundup(size, IOMMU_PAGE_SIZE)); | 550 | vio_cmo_dealloc(viodev, roundup(size, IOMMU_PAGE_SIZE)); |
551 | } | 551 | } |
@@ -603,10 +603,11 @@ static void vio_dma_iommu_unmap_sg(struct device *dev, | |||
603 | struct dma_mapping_ops vio_dma_mapping_ops = { | 603 | struct dma_mapping_ops vio_dma_mapping_ops = { |
604 | .alloc_coherent = vio_dma_iommu_alloc_coherent, | 604 | .alloc_coherent = vio_dma_iommu_alloc_coherent, |
605 | .free_coherent = vio_dma_iommu_free_coherent, | 605 | .free_coherent = vio_dma_iommu_free_coherent, |
606 | .map_single = vio_dma_iommu_map_single, | ||
607 | .unmap_single = vio_dma_iommu_unmap_single, | ||
608 | .map_sg = vio_dma_iommu_map_sg, | 606 | .map_sg = vio_dma_iommu_map_sg, |
609 | .unmap_sg = vio_dma_iommu_unmap_sg, | 607 | .unmap_sg = vio_dma_iommu_unmap_sg, |
608 | .map_page = vio_dma_iommu_map_page, | ||
609 | .unmap_page = vio_dma_iommu_unmap_page, | ||
610 | |||
610 | }; | 611 | }; |
611 | 612 | ||
612 | /** | 613 | /** |
diff --git a/arch/powerpc/platforms/cell/iommu.c b/arch/powerpc/platforms/cell/iommu.c index ef92e7146215..3168272ab0d7 100644 --- a/arch/powerpc/platforms/cell/iommu.c +++ b/arch/powerpc/platforms/cell/iommu.c | |||
@@ -593,31 +593,30 @@ static void dma_fixed_free_coherent(struct device *dev, size_t size, | |||
593 | dma_direct_ops.free_coherent(dev, size, vaddr, dma_handle); | 593 | dma_direct_ops.free_coherent(dev, size, vaddr, dma_handle); |
594 | } | 594 | } |
595 | 595 | ||
596 | static dma_addr_t dma_fixed_map_single(struct device *dev, void *ptr, | 596 | static dma_addr_t dma_fixed_map_page(struct device *dev, struct page *page, |
597 | size_t size, | 597 | unsigned long offset, size_t size, |
598 | enum dma_data_direction direction, | 598 | enum dma_data_direction direction, |
599 | struct dma_attrs *attrs) | 599 | struct dma_attrs *attrs) |
600 | { | 600 | { |
601 | if (iommu_fixed_is_weak == dma_get_attr(DMA_ATTR_WEAK_ORDERING, attrs)) | 601 | if (iommu_fixed_is_weak == dma_get_attr(DMA_ATTR_WEAK_ORDERING, attrs)) |
602 | return dma_direct_ops.map_single(dev, ptr, size, direction, | 602 | return dma_direct_ops.map_page(dev, page, offset, size, |
603 | attrs); | 603 | direction, attrs); |
604 | else | 604 | else |
605 | return iommu_map_single(dev, cell_get_iommu_table(dev), ptr, | 605 | return iommu_map_page(dev, cell_get_iommu_table(dev), page, |
606 | size, device_to_mask(dev), direction, | 606 | offset, size, device_to_mask(dev), |
607 | attrs); | 607 | direction, attrs); |
608 | } | 608 | } |
609 | 609 | ||
610 | static void dma_fixed_unmap_single(struct device *dev, dma_addr_t dma_addr, | 610 | static void dma_fixed_unmap_page(struct device *dev, dma_addr_t dma_addr, |
611 | size_t size, | 611 | size_t size, enum dma_data_direction direction, |
612 | enum dma_data_direction direction, | 612 | struct dma_attrs *attrs) |
613 | struct dma_attrs *attrs) | ||
614 | { | 613 | { |
615 | if (iommu_fixed_is_weak == dma_get_attr(DMA_ATTR_WEAK_ORDERING, attrs)) | 614 | if (iommu_fixed_is_weak == dma_get_attr(DMA_ATTR_WEAK_ORDERING, attrs)) |
616 | dma_direct_ops.unmap_single(dev, dma_addr, size, direction, | 615 | dma_direct_ops.unmap_page(dev, dma_addr, size, direction, |
617 | attrs); | 616 | attrs); |
618 | else | 617 | else |
619 | iommu_unmap_single(cell_get_iommu_table(dev), dma_addr, size, | 618 | iommu_unmap_page(cell_get_iommu_table(dev), dma_addr, size, |
620 | direction, attrs); | 619 | direction, attrs); |
621 | } | 620 | } |
622 | 621 | ||
623 | static int dma_fixed_map_sg(struct device *dev, struct scatterlist *sg, | 622 | static int dma_fixed_map_sg(struct device *dev, struct scatterlist *sg, |
@@ -652,12 +651,12 @@ static int dma_set_mask_and_switch(struct device *dev, u64 dma_mask); | |||
652 | struct dma_mapping_ops dma_iommu_fixed_ops = { | 651 | struct dma_mapping_ops dma_iommu_fixed_ops = { |
653 | .alloc_coherent = dma_fixed_alloc_coherent, | 652 | .alloc_coherent = dma_fixed_alloc_coherent, |
654 | .free_coherent = dma_fixed_free_coherent, | 653 | .free_coherent = dma_fixed_free_coherent, |
655 | .map_single = dma_fixed_map_single, | ||
656 | .unmap_single = dma_fixed_unmap_single, | ||
657 | .map_sg = dma_fixed_map_sg, | 654 | .map_sg = dma_fixed_map_sg, |
658 | .unmap_sg = dma_fixed_unmap_sg, | 655 | .unmap_sg = dma_fixed_unmap_sg, |
659 | .dma_supported = dma_fixed_dma_supported, | 656 | .dma_supported = dma_fixed_dma_supported, |
660 | .set_dma_mask = dma_set_mask_and_switch, | 657 | .set_dma_mask = dma_set_mask_and_switch, |
658 | .map_page = dma_fixed_map_page, | ||
659 | .unmap_page = dma_fixed_unmap_page, | ||
661 | }; | 660 | }; |
662 | 661 | ||
663 | static void cell_dma_dev_setup_fixed(struct device *dev); | 662 | static void cell_dma_dev_setup_fixed(struct device *dev); |
diff --git a/arch/powerpc/platforms/iseries/iommu.c b/arch/powerpc/platforms/iseries/iommu.c index bb464d1211b2..bbe828f1b885 100644 --- a/arch/powerpc/platforms/iseries/iommu.c +++ b/arch/powerpc/platforms/iseries/iommu.c | |||
@@ -215,14 +215,15 @@ EXPORT_SYMBOL_GPL(iseries_hv_free); | |||
215 | dma_addr_t iseries_hv_map(void *vaddr, size_t size, | 215 | dma_addr_t iseries_hv_map(void *vaddr, size_t size, |
216 | enum dma_data_direction direction) | 216 | enum dma_data_direction direction) |
217 | { | 217 | { |
218 | return iommu_map_single(NULL, &vio_iommu_table, vaddr, size, | 218 | return iommu_map_page(NULL, &vio_iommu_table, virt_to_page(vaddr), |
219 | DMA_32BIT_MASK, direction, NULL); | 219 | (unsigned long)vaddr % PAGE_SIZE, size, |
220 | DMA_32BIT_MASK, direction, NULL); | ||
220 | } | 221 | } |
221 | 222 | ||
222 | void iseries_hv_unmap(dma_addr_t dma_handle, size_t size, | 223 | void iseries_hv_unmap(dma_addr_t dma_handle, size_t size, |
223 | enum dma_data_direction direction) | 224 | enum dma_data_direction direction) |
224 | { | 225 | { |
225 | iommu_unmap_single(&vio_iommu_table, dma_handle, size, direction, NULL); | 226 | iommu_unmap_page(&vio_iommu_table, dma_handle, size, direction, NULL); |
226 | } | 227 | } |
227 | 228 | ||
228 | void __init iommu_vio_init(void) | 229 | void __init iommu_vio_init(void) |
diff --git a/arch/powerpc/platforms/ps3/system-bus.c b/arch/powerpc/platforms/ps3/system-bus.c index a789bf58ca8b..661e9f77ebf6 100644 --- a/arch/powerpc/platforms/ps3/system-bus.c +++ b/arch/powerpc/platforms/ps3/system-bus.c | |||
@@ -555,18 +555,19 @@ static void ps3_free_coherent(struct device *_dev, size_t size, void *vaddr, | |||
555 | } | 555 | } |
556 | 556 | ||
557 | /* Creates TCEs for a user provided buffer. The user buffer must be | 557 | /* Creates TCEs for a user provided buffer. The user buffer must be |
558 | * contiguous real kernel storage (not vmalloc). The address of the buffer | 558 | * contiguous real kernel storage (not vmalloc). The address passed here |
559 | * passed here is the kernel (virtual) address of the buffer. The buffer | 559 | * comprises a page address and offset into that page. The dma_addr_t |
560 | * need not be page aligned, the dma_addr_t returned will point to the same | 560 | * returned will point to the same byte within the page as was passed in. |
561 | * byte within the page as vaddr. | ||
562 | */ | 561 | */ |
563 | 562 | ||
564 | static dma_addr_t ps3_sb_map_single(struct device *_dev, void *ptr, size_t size, | 563 | static dma_addr_t ps3_sb_map_page(struct device *_dev, struct page *page, |
565 | enum dma_data_direction direction, struct dma_attrs *attrs) | 564 | unsigned long offset, size_t size, enum dma_data_direction direction, |
565 | struct dma_attrs *attrs) | ||
566 | { | 566 | { |
567 | struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev); | 567 | struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev); |
568 | int result; | 568 | int result; |
569 | unsigned long bus_addr; | 569 | unsigned long bus_addr; |
570 | void *ptr = page_address(page) + offset; | ||
570 | 571 | ||
571 | result = ps3_dma_map(dev->d_region, (unsigned long)ptr, size, | 572 | result = ps3_dma_map(dev->d_region, (unsigned long)ptr, size, |
572 | &bus_addr, | 573 | &bus_addr, |
@@ -580,15 +581,16 @@ static dma_addr_t ps3_sb_map_single(struct device *_dev, void *ptr, size_t size, | |||
580 | return bus_addr; | 581 | return bus_addr; |
581 | } | 582 | } |
582 | 583 | ||
583 | static dma_addr_t ps3_ioc0_map_single(struct device *_dev, void *ptr, | 584 | static dma_addr_t ps3_ioc0_map_page(struct device *_dev, struct page *page, |
584 | size_t size, | 585 | unsigned long offset, size_t size, |
585 | enum dma_data_direction direction, | 586 | enum dma_data_direction direction, |
586 | struct dma_attrs *attrs) | 587 | struct dma_attrs *attrs) |
587 | { | 588 | { |
588 | struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev); | 589 | struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev); |
589 | int result; | 590 | int result; |
590 | unsigned long bus_addr; | 591 | unsigned long bus_addr; |
591 | u64 iopte_flag; | 592 | u64 iopte_flag; |
593 | void *ptr = page_address(page) + offset; | ||
592 | 594 | ||
593 | iopte_flag = IOPTE_M; | 595 | iopte_flag = IOPTE_M; |
594 | switch (direction) { | 596 | switch (direction) { |
@@ -615,7 +617,7 @@ static dma_addr_t ps3_ioc0_map_single(struct device *_dev, void *ptr, | |||
615 | return bus_addr; | 617 | return bus_addr; |
616 | } | 618 | } |
617 | 619 | ||
618 | static void ps3_unmap_single(struct device *_dev, dma_addr_t dma_addr, | 620 | static void ps3_unmap_page(struct device *_dev, dma_addr_t dma_addr, |
619 | size_t size, enum dma_data_direction direction, struct dma_attrs *attrs) | 621 | size_t size, enum dma_data_direction direction, struct dma_attrs *attrs) |
620 | { | 622 | { |
621 | struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev); | 623 | struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev); |
@@ -689,21 +691,21 @@ static int ps3_dma_supported(struct device *_dev, u64 mask) | |||
689 | static struct dma_mapping_ops ps3_sb_dma_ops = { | 691 | static struct dma_mapping_ops ps3_sb_dma_ops = { |
690 | .alloc_coherent = ps3_alloc_coherent, | 692 | .alloc_coherent = ps3_alloc_coherent, |
691 | .free_coherent = ps3_free_coherent, | 693 | .free_coherent = ps3_free_coherent, |
692 | .map_single = ps3_sb_map_single, | ||
693 | .unmap_single = ps3_unmap_single, | ||
694 | .map_sg = ps3_sb_map_sg, | 694 | .map_sg = ps3_sb_map_sg, |
695 | .unmap_sg = ps3_sb_unmap_sg, | 695 | .unmap_sg = ps3_sb_unmap_sg, |
696 | .dma_supported = ps3_dma_supported | 696 | .dma_supported = ps3_dma_supported, |
697 | .map_page = ps3_sb_map_page, | ||
698 | .unmap_page = ps3_unmap_page, | ||
697 | }; | 699 | }; |
698 | 700 | ||
699 | static struct dma_mapping_ops ps3_ioc0_dma_ops = { | 701 | static struct dma_mapping_ops ps3_ioc0_dma_ops = { |
700 | .alloc_coherent = ps3_alloc_coherent, | 702 | .alloc_coherent = ps3_alloc_coherent, |
701 | .free_coherent = ps3_free_coherent, | 703 | .free_coherent = ps3_free_coherent, |
702 | .map_single = ps3_ioc0_map_single, | ||
703 | .unmap_single = ps3_unmap_single, | ||
704 | .map_sg = ps3_ioc0_map_sg, | 704 | .map_sg = ps3_ioc0_map_sg, |
705 | .unmap_sg = ps3_ioc0_unmap_sg, | 705 | .unmap_sg = ps3_ioc0_unmap_sg, |
706 | .dma_supported = ps3_dma_supported | 706 | .dma_supported = ps3_dma_supported, |
707 | .map_page = ps3_ioc0_map_page, | ||
708 | .unmap_page = ps3_unmap_page, | ||
707 | }; | 709 | }; |
708 | 710 | ||
709 | /** | 711 | /** |