static dma_addr_t pcibr_dmatrans_direct32(struct pcidev_info * info, uint64_t paddr, size_t req_size, uint64_t flags) { struct pcidev_info *pcidev_info = info->pdi_host_pcidev_info; struct pcibus_info *pcibus_info = (struct pcibus_info *)pcidev_info-> pdi_pcibus_info; uint64_t xio_addr; uint64_t xio_base; uint64_t offset; uint64_t endoff; if (IS_PCIX(pcibus_info)) { return 0; } xio_addr = IS_PIC_SOFT(pcibus_info) ? PHYS_TO_DMA(paddr) : PHYS_TO_TIODMA(paddr); xio_base = pcibus_info->pbi_dir_xbase; offset = xio_addr - xio_base; endoff = req_size + offset; if ((req_size > (1ULL << 31)) || /* Too Big */ (xio_addr < xio_base) || /* Out of range for mappings */ (endoff > (1ULL << 31))) { /* Too Big */ return 0; } return PCI32_DIRECT_BASE | offset; }
static dma_addr_t pcibr_dmatrans_direct64(struct pcidev_info * info, uint64_t paddr, uint64_t dma_attributes) { struct pcibus_info *pcibus_info = (struct pcibus_info *) ((info->pdi_host_pcidev_info)->pdi_pcibus_info); uint64_t pci_addr; /* Translate to Crosstalk View of Physical Address */ pci_addr = (IS_PIC_SOFT(pcibus_info) ? PHYS_TO_DMA(paddr) : PHYS_TO_TIODMA(paddr)) | dma_attributes; /* Handle Bus mode */ if (IS_PCIX(pcibus_info)) pci_addr &= ~PCI64_ATTR_PREF; /* Handle Bridge Chipset differences */ if (IS_PIC_SOFT(pcibus_info)) { pci_addr |= ((uint64_t) pcibus_info-> pbi_hub_xid << PIC_PCI64_ATTR_TARG_SHFT); } else pci_addr |= TIOCP_PCI64_CMDTYPE_MEM; /* If PCI mode, func zero uses VCHAN0, every other func uses VCHAN1 */ if (!IS_PCIX(pcibus_info) && PCI_FUNC(info->pdi_linux_pcidev->devfn)) pci_addr |= PCI64_ATTR_VIRTUAL; return pci_addr; }
static dma_addr_t pcibr_dmatrans_direct32(struct pcidev_info * info, u64 paddr, size_t req_size, u64 flags, int dma_flags) { struct pcidev_info *pcidev_info = info->pdi_host_pcidev_info; struct pcibus_info *pcibus_info = (struct pcibus_info *)pcidev_info-> pdi_pcibus_info; u64 xio_addr; u64 xio_base; u64 offset; u64 endoff; if (IS_PCIX(pcibus_info)) { return 0; } if (dma_flags & SN_DMA_MSI) return 0; if (SN_DMA_ADDRTYPE(dma_flags) == SN_DMA_ADDR_PHYS) xio_addr = IS_PIC_SOFT(pcibus_info) ? PHYS_TO_DMA(paddr) : PHYS_TO_TIODMA(paddr); else xio_addr = paddr; xio_base = pcibus_info->pbi_dir_xbase; offset = xio_addr - xio_base; endoff = req_size + offset; if ((req_size > (1ULL << 31)) || /* Too Big */ (xio_addr < xio_base) || /* Out of range for mappings */ (endoff > (1ULL << 31))) { /* Too Big */ return 0; } return PCI32_DIRECT_BASE | offset; }
static dma_addr_t pcibr_dmatrans_direct64(struct pcidev_info * info, u64 paddr, u64 dma_attributes, int dma_flags) { struct pcibus_info *pcibus_info = (struct pcibus_info *) ((info->pdi_host_pcidev_info)->pdi_pcibus_info); u64 pci_addr; if (SN_DMA_ADDRTYPE(dma_flags) == SN_DMA_ADDR_PHYS) pci_addr = IS_PIC_SOFT(pcibus_info) ? PHYS_TO_DMA(paddr) : PHYS_TO_TIODMA(paddr); else pci_addr = paddr; pci_addr |= dma_attributes; if (IS_PCIX(pcibus_info)) pci_addr &= ~PCI64_ATTR_PREF; if (IS_PIC_SOFT(pcibus_info)) { pci_addr |= ((u64) pcibus_info-> pbi_hub_xid << PIC_PCI64_ATTR_TARG_SHFT); } else pci_addr |= (dma_flags & SN_DMA_MSI) ? TIOCP_PCI64_CMDTYPE_MSI : TIOCP_PCI64_CMDTYPE_MEM; if (!IS_PCIX(pcibus_info) && PCI_FUNC(info->pdi_linux_pcidev->devfn)) pci_addr |= PCI64_ATTR_VIRTUAL; return pci_addr; }
static dma_addr_t pcibr_dmamap_ate32(struct pcidev_info *info, uint64_t paddr, size_t req_size, uint64_t flags) { struct pcidev_info *pcidev_info = info->pdi_host_pcidev_info; struct pcibus_info *pcibus_info = (struct pcibus_info *)pcidev_info-> pdi_pcibus_info; uint8_t internal_device = (PCI_SLOT(pcidev_info->pdi_host_pcidev_info-> pdi_linux_pcidev->devfn)) - 1; int ate_count; int ate_index; uint64_t ate_flags = flags | PCI32_ATE_V; uint64_t ate; uint64_t pci_addr; uint64_t xio_addr; uint64_t offset; /* PIC in PCI-X mode does not supports 32bit PageMap mode */ if (IS_PIC_SOFT(pcibus_info) && IS_PCIX(pcibus_info)) { return 0; } /* Calculate the number of ATEs needed. */ if (!(MINIMAL_ATE_FLAG(paddr, req_size))) { ate_count = IOPG((IOPGSIZE - 1) /* worst case start offset */ +req_size /* max mapping bytes */ - 1) + 1; /* round UP */ } else { /* assume requested target is page aligned */ ate_count = IOPG(req_size /* max mapping bytes */ - 1) + 1; /* round UP */ } /* Get the number of ATEs required. */ ate_index = pcibr_ate_alloc(pcibus_info, ate_count); if (ate_index < 0) return 0; /* In PCI-X mode, Prefetch not supported */ if (IS_PCIX(pcibus_info)) ate_flags &= ~(PCI32_ATE_PREF); xio_addr = IS_PIC_SOFT(pcibus_info) ? PHYS_TO_DMA(paddr) : PHYS_TO_TIODMA(paddr); offset = IOPGOFF(xio_addr); ate = ate_flags | (xio_addr - offset); /* If PIC, put the targetid in the ATE */ if (IS_PIC_SOFT(pcibus_info)) { ate |= (pcibus_info->pbi_hub_xid << PIC_ATE_TARGETID_SHFT); } ate_write(pcibus_info, ate_index, ate_count, ate); /* * Set up the DMA mapped Address. */ pci_addr = PCI32_MAPPED_BASE + offset + IOPGSIZE * ate_index; /* * If swap was set in device in pcibr_endian_set() * we need to turn swapping on. */ if (pcibus_info->pbi_devreg[internal_device] & PCIBR_DEV_SWAP_DIR) ATE_SWAP_ON(pci_addr); return pci_addr; }
static dma_addr_t pcibr_dmamap_ate32(struct pcidev_info *info, u64 paddr, size_t req_size, u64 flags, int dma_flags) { struct pcidev_info *pcidev_info = info->pdi_host_pcidev_info; struct pcibus_info *pcibus_info = (struct pcibus_info *)pcidev_info-> pdi_pcibus_info; u8 internal_device = (PCI_SLOT(pcidev_info->pdi_host_pcidev_info-> pdi_linux_pcidev->devfn)) - 1; int ate_count; int ate_index; u64 ate_flags = flags | PCI32_ATE_V; u64 ate; u64 pci_addr; u64 xio_addr; u64 offset; if (IS_PIC_SOFT(pcibus_info) && IS_PCIX(pcibus_info)) { return 0; } if (!(MINIMAL_ATE_FLAG(paddr, req_size))) { ate_count = IOPG((IOPGSIZE - 1) +req_size - 1) + 1; } else { ate_count = IOPG(req_size - 1) + 1; } ate_index = pcibr_ate_alloc(pcibus_info, ate_count); if (ate_index < 0) return 0; if (IS_PCIX(pcibus_info)) ate_flags &= ~(PCI32_ATE_PREF); if (SN_DMA_ADDRTYPE(dma_flags == SN_DMA_ADDR_PHYS)) xio_addr = IS_PIC_SOFT(pcibus_info) ? PHYS_TO_DMA(paddr) : PHYS_TO_TIODMA(paddr); else xio_addr = paddr; offset = IOPGOFF(xio_addr); ate = ate_flags | (xio_addr - offset); if (IS_PIC_SOFT(pcibus_info)) { ate |= (pcibus_info->pbi_hub_xid << PIC_ATE_TARGETID_SHFT); } if (dma_flags & SN_DMA_MSI) { ate |= PCI32_ATE_MSI; if (IS_TIOCP_SOFT(pcibus_info)) ate |= PCI32_ATE_PIO; } ate_write(pcibus_info, ate_index, ate_count, ate); pci_addr = PCI32_MAPPED_BASE + offset + IOPGSIZE * ate_index; if (pcibus_info->pbi_devreg[internal_device] & PCIBR_DEV_SWAP_DIR) ATE_SWAP_ON(pci_addr); return pci_addr; }