aboutsummaryrefslogtreecommitdiffstats
path: root/arch/alpha/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'arch/alpha/kernel')
-rw-r--r--arch/alpha/kernel/pci-noop.c4
-rw-r--r--arch/alpha/kernel/pci_iommu.c24
-rw-r--r--arch/alpha/kernel/setup.c1
-rw-r--r--arch/alpha/kernel/systbls.S2
4 files changed, 21 insertions, 10 deletions
diff --git a/arch/alpha/kernel/pci-noop.c b/arch/alpha/kernel/pci-noop.c
index 468b76ce66a1..8ac08311f5a5 100644
--- a/arch/alpha/kernel/pci-noop.c
+++ b/arch/alpha/kernel/pci-noop.c
@@ -165,7 +165,7 @@ dma_alloc_coherent(struct device *dev, size_t size,
165 ret = (void *)__get_free_pages(gfp, get_order(size)); 165 ret = (void *)__get_free_pages(gfp, get_order(size));
166 if (ret) { 166 if (ret) {
167 memset(ret, 0, size); 167 memset(ret, 0, size);
168 *dma_handle = virt_to_bus(ret); 168 *dma_handle = virt_to_phys(ret);
169 } 169 }
170 return ret; 170 return ret;
171} 171}
@@ -184,7 +184,7 @@ dma_map_sg(struct device *dev, struct scatterlist *sgl, int nents,
184 184
185 BUG_ON(!sg_page(sg)); 185 BUG_ON(!sg_page(sg));
186 va = sg_virt(sg); 186 va = sg_virt(sg);
187 sg_dma_address(sg) = (dma_addr_t)virt_to_bus(va); 187 sg_dma_address(sg) = (dma_addr_t)virt_to_phys(va);
188 sg_dma_len(sg) = sg->length; 188 sg_dma_len(sg) = sg->length;
189 } 189 }
190 190
diff --git a/arch/alpha/kernel/pci_iommu.c b/arch/alpha/kernel/pci_iommu.c
index 2d00a08d3f08..26d3789dfdd0 100644
--- a/arch/alpha/kernel/pci_iommu.c
+++ b/arch/alpha/kernel/pci_iommu.c
@@ -9,6 +9,7 @@
9#include <linux/bootmem.h> 9#include <linux/bootmem.h>
10#include <linux/scatterlist.h> 10#include <linux/scatterlist.h>
11#include <linux/log2.h> 11#include <linux/log2.h>
12#include <linux/dma-mapping.h>
12 13
13#include <asm/io.h> 14#include <asm/io.h>
14#include <asm/hwrpb.h> 15#include <asm/hwrpb.h>
@@ -470,22 +471,29 @@ EXPORT_SYMBOL(pci_free_consistent);
470#define SG_ENT_PHYS_ADDRESS(SG) __pa(SG_ENT_VIRT_ADDRESS(SG)) 471#define SG_ENT_PHYS_ADDRESS(SG) __pa(SG_ENT_VIRT_ADDRESS(SG))
471 472
472static void 473static void
473sg_classify(struct scatterlist *sg, struct scatterlist *end, int virt_ok) 474sg_classify(struct device *dev, struct scatterlist *sg, struct scatterlist *end,
475 int virt_ok)
474{ 476{
475 unsigned long next_paddr; 477 unsigned long next_paddr;
476 struct scatterlist *leader; 478 struct scatterlist *leader;
477 long leader_flag, leader_length; 479 long leader_flag, leader_length;
480 unsigned int max_seg_size;
478 481
479 leader = sg; 482 leader = sg;
480 leader_flag = 0; 483 leader_flag = 0;
481 leader_length = leader->length; 484 leader_length = leader->length;
482 next_paddr = SG_ENT_PHYS_ADDRESS(leader) + leader_length; 485 next_paddr = SG_ENT_PHYS_ADDRESS(leader) + leader_length;
483 486
487 /* we will not marge sg without device. */
488 max_seg_size = dev ? dma_get_max_seg_size(dev) : 0;
484 for (++sg; sg < end; ++sg) { 489 for (++sg; sg < end; ++sg) {
485 unsigned long addr, len; 490 unsigned long addr, len;
486 addr = SG_ENT_PHYS_ADDRESS(sg); 491 addr = SG_ENT_PHYS_ADDRESS(sg);
487 len = sg->length; 492 len = sg->length;
488 493
494 if (leader_length + len > max_seg_size)
495 goto new_segment;
496
489 if (next_paddr == addr) { 497 if (next_paddr == addr) {
490 sg->dma_address = -1; 498 sg->dma_address = -1;
491 leader_length += len; 499 leader_length += len;
@@ -494,6 +502,7 @@ sg_classify(struct scatterlist *sg, struct scatterlist *end, int virt_ok)
494 leader_flag = 1; 502 leader_flag = 1;
495 leader_length += len; 503 leader_length += len;
496 } else { 504 } else {
505new_segment:
497 leader->dma_address = leader_flag; 506 leader->dma_address = leader_flag;
498 leader->dma_length = leader_length; 507 leader->dma_length = leader_length;
499 leader = sg; 508 leader = sg;
@@ -512,7 +521,7 @@ sg_classify(struct scatterlist *sg, struct scatterlist *end, int virt_ok)
512 in the blanks. */ 521 in the blanks. */
513 522
514static int 523static int
515sg_fill(struct scatterlist *leader, struct scatterlist *end, 524sg_fill(struct device *dev, struct scatterlist *leader, struct scatterlist *end,
516 struct scatterlist *out, struct pci_iommu_arena *arena, 525 struct scatterlist *out, struct pci_iommu_arena *arena,
517 dma_addr_t max_dma, int dac_allowed) 526 dma_addr_t max_dma, int dac_allowed)
518{ 527{
@@ -562,8 +571,8 @@ sg_fill(struct scatterlist *leader, struct scatterlist *end,
562 571
563 /* Otherwise, break up the remaining virtually contiguous 572 /* Otherwise, break up the remaining virtually contiguous
564 hunks into individual direct maps and retry. */ 573 hunks into individual direct maps and retry. */
565 sg_classify(leader, end, 0); 574 sg_classify(dev, leader, end, 0);
566 return sg_fill(leader, end, out, arena, max_dma, dac_allowed); 575 return sg_fill(dev, leader, end, out, arena, max_dma, dac_allowed);
567 } 576 }
568 577
569 out->dma_address = arena->dma_base + dma_ofs*PAGE_SIZE + paddr; 578 out->dma_address = arena->dma_base + dma_ofs*PAGE_SIZE + paddr;
@@ -619,12 +628,15 @@ pci_map_sg(struct pci_dev *pdev, struct scatterlist *sg, int nents,
619 struct pci_iommu_arena *arena; 628 struct pci_iommu_arena *arena;
620 dma_addr_t max_dma; 629 dma_addr_t max_dma;
621 int dac_allowed; 630 int dac_allowed;
631 struct device *dev;
622 632
623 if (direction == PCI_DMA_NONE) 633 if (direction == PCI_DMA_NONE)
624 BUG(); 634 BUG();
625 635
626 dac_allowed = pdev ? pci_dac_dma_supported(pdev, pdev->dma_mask) : 0; 636 dac_allowed = pdev ? pci_dac_dma_supported(pdev, pdev->dma_mask) : 0;
627 637
638 dev = pdev ? &pdev->dev : NULL;
639
628 /* Fast path single entry scatterlists. */ 640 /* Fast path single entry scatterlists. */
629 if (nents == 1) { 641 if (nents == 1) {
630 sg->dma_length = sg->length; 642 sg->dma_length = sg->length;
@@ -638,7 +650,7 @@ pci_map_sg(struct pci_dev *pdev, struct scatterlist *sg, int nents,
638 end = sg + nents; 650 end = sg + nents;
639 651
640 /* First, prepare information about the entries. */ 652 /* First, prepare information about the entries. */
641 sg_classify(sg, end, alpha_mv.mv_pci_tbi != 0); 653 sg_classify(dev, sg, end, alpha_mv.mv_pci_tbi != 0);
642 654
643 /* Second, figure out where we're going to map things. */ 655 /* Second, figure out where we're going to map things. */
644 if (alpha_mv.mv_pci_tbi) { 656 if (alpha_mv.mv_pci_tbi) {
@@ -658,7 +670,7 @@ pci_map_sg(struct pci_dev *pdev, struct scatterlist *sg, int nents,
658 for (out = sg; sg < end; ++sg) { 670 for (out = sg; sg < end; ++sg) {
659 if ((int) sg->dma_address < 0) 671 if ((int) sg->dma_address < 0)
660 continue; 672 continue;
661 if (sg_fill(sg, end, out, arena, max_dma, dac_allowed) < 0) 673 if (sg_fill(dev, sg, end, out, arena, max_dma, dac_allowed) < 0)
662 goto error; 674 goto error;
663 out++; 675 out++;
664 } 676 }
diff --git a/arch/alpha/kernel/setup.c b/arch/alpha/kernel/setup.c
index bd5e68cd61e8..beff6297f788 100644
--- a/arch/alpha/kernel/setup.c
+++ b/arch/alpha/kernel/setup.c
@@ -58,7 +58,6 @@ static struct notifier_block alpha_panic_block = {
58#include <asm/system.h> 58#include <asm/system.h>
59#include <asm/hwrpb.h> 59#include <asm/hwrpb.h>
60#include <asm/dma.h> 60#include <asm/dma.h>
61#include <asm/io.h>
62#include <asm/mmu_context.h> 61#include <asm/mmu_context.h>
63#include <asm/console.h> 62#include <asm/console.h>
64 63
diff --git a/arch/alpha/kernel/systbls.S b/arch/alpha/kernel/systbls.S
index 79de99e32c35..ba914af18c4f 100644
--- a/arch/alpha/kernel/systbls.S
+++ b/arch/alpha/kernel/systbls.S
@@ -495,7 +495,7 @@ sys_call_table:
495 .quad sys_epoll_pwait 495 .quad sys_epoll_pwait
496 .quad sys_utimensat /* 475 */ 496 .quad sys_utimensat /* 475 */
497 .quad sys_signalfd 497 .quad sys_signalfd
498 .quad sys_timerfd 498 .quad sys_ni_syscall
499 .quad sys_eventfd 499 .quad sys_eventfd
500 500
501 .size sys_call_table, . - sys_call_table 501 .size sys_call_table, . - sys_call_table