diff options
Diffstat (limited to 'arch/ia64/sn/pci')
| -rw-r--r-- | arch/ia64/sn/pci/Makefile | 2 | ||||
| -rw-r--r-- | arch/ia64/sn/pci/pci_dma.c | 194 | ||||
| -rw-r--r-- | arch/ia64/sn/pci/pcibr/Makefile | 2 | ||||
| -rw-r--r-- | arch/ia64/sn/pci/pcibr/pcibr_ate.c | 12 | ||||
| -rw-r--r-- | arch/ia64/sn/pci/pcibr/pcibr_dma.c | 26 | ||||
| -rw-r--r-- | arch/ia64/sn/pci/pcibr/pcibr_provider.c | 51 | ||||
| -rw-r--r-- | arch/ia64/sn/pci/tioca_provider.c | 63 | ||||
| -rw-r--r-- | arch/ia64/sn/pci/tioce_provider.c | 120 |
8 files changed, 256 insertions, 214 deletions
diff --git a/arch/ia64/sn/pci/Makefile b/arch/ia64/sn/pci/Makefile index c6946784a6a..df2a9014542 100644 --- a/arch/ia64/sn/pci/Makefile +++ b/arch/ia64/sn/pci/Makefile @@ -7,6 +7,6 @@ # # Makefile for the sn pci general routines. -CPPFLAGS += -I$(srctree)/arch/ia64/sn/include +ccflags-y := -Iarch/ia64/sn/include obj-y := pci_dma.o tioca_provider.o tioce_provider.o pcibr/ diff --git a/arch/ia64/sn/pci/pci_dma.c b/arch/ia64/sn/pci/pci_dma.c index 7a291a27151..d0853e8e862 100644 --- a/arch/ia64/sn/pci/pci_dma.c +++ b/arch/ia64/sn/pci/pci_dma.c @@ -9,14 +9,16 @@ * a description of how these routines should be used. */ +#include <linux/gfp.h> #include <linux/module.h> +#include <linux/dma-mapping.h> #include <asm/dma.h> #include <asm/sn/intr.h> #include <asm/sn/pcibus_provider_defs.h> #include <asm/sn/pcidev.h> #include <asm/sn/sn_sal.h> -#define SG_ENT_VIRT_ADDRESS(sg) (page_address((sg)->page) + (sg)->offset) +#define SG_ENT_VIRT_ADDRESS(sg) (sg_virt((sg))) #define SG_ENT_PHYS_ADDRESS(SG) virt_to_phys(SG_ENT_VIRT_ADDRESS(SG)) /** @@ -30,15 +32,14 @@ * this function. Of course, SN only supports devices that have 32 or more * address bits when using the PMU. */ -int sn_dma_supported(struct device *dev, u64 mask) +static int sn_dma_supported(struct device *dev, u64 mask) { - BUG_ON(dev->bus != &pci_bus_type); + BUG_ON(!dev_is_pci(dev)); if (mask < 0x7fffffff) return 0; return 1; } -EXPORT_SYMBOL(sn_dma_supported); /** * sn_dma_set_mask - set the DMA mask @@ -49,7 +50,7 @@ EXPORT_SYMBOL(sn_dma_supported); */ int sn_dma_set_mask(struct device *dev, u64 dma_mask) { - BUG_ON(dev->bus != &pci_bus_type); + BUG_ON(!dev_is_pci(dev)); if (!sn_dma_supported(dev, dma_mask)) return 0; @@ -74,8 +75,9 @@ EXPORT_SYMBOL(sn_dma_set_mask); * queue for a SCSI controller). See Documentation/DMA-API.txt for * more information. */ -void *sn_dma_alloc_coherent(struct device *dev, size_t size, - dma_addr_t * dma_handle, gfp_t flags) +static void *sn_dma_alloc_coherent(struct device *dev, size_t size, + dma_addr_t * dma_handle, gfp_t flags, + struct dma_attrs *attrs) { void *cpuaddr; unsigned long phys_addr; @@ -83,14 +85,15 @@ void *sn_dma_alloc_coherent(struct device *dev, size_t size, struct pci_dev *pdev = to_pci_dev(dev); struct sn_pcibus_provider *provider = SN_PCIDEV_BUSPROVIDER(pdev); - BUG_ON(dev->bus != &pci_bus_type); + BUG_ON(!dev_is_pci(dev)); /* * Allocate the memory. */ node = pcibus_to_node(pdev->bus); if (likely(node >=0)) { - struct page *p = alloc_pages_node(node, flags, get_order(size)); + struct page *p = alloc_pages_exact_node(node, + flags, get_order(size)); if (likely(p)) cpuaddr = page_address(p); @@ -116,14 +119,13 @@ void *sn_dma_alloc_coherent(struct device *dev, size_t size, *dma_handle = provider->dma_map_consistent(pdev, phys_addr, size, SN_DMA_ADDR_PHYS); if (!*dma_handle) { - printk(KERN_ERR "%s: out of ATEs\n", __FUNCTION__); + printk(KERN_ERR "%s: out of ATEs\n", __func__); free_pages((unsigned long)cpuaddr, get_order(size)); return NULL; } return cpuaddr; } -EXPORT_SYMBOL(sn_dma_alloc_coherent); /** * sn_pci_free_coherent - free memory associated with coherent DMAable region @@ -135,25 +137,25 @@ EXPORT_SYMBOL(sn_dma_alloc_coherent); * Frees the memory allocated by dma_alloc_coherent(), potentially unmapping * any associated IOMMU mappings. */ -void sn_dma_free_coherent(struct device *dev, size_t size, void *cpu_addr, - dma_addr_t dma_handle) +static void sn_dma_free_coherent(struct device *dev, size_t size, void *cpu_addr, + dma_addr_t dma_handle, struct dma_attrs *attrs) { struct pci_dev *pdev = to_pci_dev(dev); struct sn_pcibus_provider *provider = SN_PCIDEV_BUSPROVIDER(pdev); - BUG_ON(dev->bus != &pci_bus_type); + BUG_ON(!dev_is_pci(dev)); provider->dma_unmap(pdev, dma_handle, 0); free_pages((unsigned long)cpu_addr, get_order(size)); } -EXPORT_SYMBOL(sn_dma_free_coherent); /** - * sn_dma_map_single - map a single page for DMA + * sn_dma_map_single_attrs - map a single page for DMA * @dev: device to map for * @cpu_addr: kernel virtual address of the region to map * @size: size of the region * @direction: DMA direction + * @attrs: optional dma attributes * * Map the region pointed to by @cpu_addr for DMA and return the * DMA address. @@ -163,51 +165,68 @@ EXPORT_SYMBOL(sn_dma_free_coherent); * no way of saving the dmamap handle from the alloc to later free * (which is pretty much unacceptable). * + * mappings with the DMA_ATTR_WRITE_BARRIER get mapped with + * dma_map_consistent() so that writes force a flush of pending DMA. + * (See "SGI Altix Architecture Considerations for Linux Device Drivers", + * Document Number: 007-4763-001) + * * TODO: simplify our interface; * figure out how to save dmamap handle so can use two step. */ -dma_addr_t sn_dma_map_single(struct device *dev, void *cpu_addr, size_t size, - int direction) +static dma_addr_t sn_dma_map_page(struct device *dev, struct page *page, + unsigned long offset, size_t size, + enum dma_data_direction dir, + struct dma_attrs *attrs) { + void *cpu_addr = page_address(page) + offset; dma_addr_t dma_addr; unsigned long phys_addr; struct pci_dev *pdev = to_pci_dev(dev); struct sn_pcibus_provider *provider = SN_PCIDEV_BUSPROVIDER(pdev); + int dmabarr; + + dmabarr = dma_get_attr(DMA_ATTR_WRITE_BARRIER, attrs); - BUG_ON(dev->bus != &pci_bus_type); + BUG_ON(!dev_is_pci(dev)); phys_addr = __pa(cpu_addr); - dma_addr = provider->dma_map(pdev, phys_addr, size, SN_DMA_ADDR_PHYS); + if (dmabarr) + dma_addr = provider->dma_map_consistent(pdev, phys_addr, + size, SN_DMA_ADDR_PHYS); + else + dma_addr = provider->dma_map(pdev, phys_addr, size, + SN_DMA_ADDR_PHYS); + if (!dma_addr) { - printk(KERN_ERR "%s: out of ATEs\n", __FUNCTION__); + printk(KERN_ERR "%s: out of ATEs\n", __func__); return 0; } return dma_addr; } -EXPORT_SYMBOL(sn_dma_map_single); /** - * sn_dma_unmap_single - unamp a DMA mapped page + * sn_dma_unmap_single_attrs - unamp a DMA mapped page * @dev: device to sync * @dma_addr: DMA address to sync * @size: size of region * @direction: DMA direction + * @attrs: optional dma attributes * * This routine is supposed to sync the DMA region specified * by @dma_handle into the coherence domain. On SN, we're always cache * coherent, so we just need to free any ATEs associated with this mapping. */ -void sn_dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size, - int direction) +static void sn_dma_unmap_page(struct device *dev, dma_addr_t dma_addr, + size_t size, enum dma_data_direction dir, + struct dma_attrs *attrs) { struct pci_dev *pdev = to_pci_dev(dev); struct sn_pcibus_provider *provider = SN_PCIDEV_BUSPROVIDER(pdev); - BUG_ON(dev->bus != &pci_bus_type); + BUG_ON(!dev_is_pci(dev)); - provider->dma_unmap(pdev, dma_addr, direction); + provider->dma_unmap(pdev, dma_addr, dir); } -EXPORT_SYMBOL(sn_dma_unmap_single); /** * sn_dma_unmap_sg - unmap a DMA scatterlist @@ -215,25 +234,27 @@ EXPORT_SYMBOL(sn_dma_unmap_single); * @sg: scatterlist to unmap * @nhwentries: number of scatterlist entries * @direction: DMA direction + * @attrs: optional dma attributes * * Unmap a set of streaming mode DMA translations. */ -void sn_dma_unmap_sg(struct device *dev, struct scatterlist *sg, - int nhwentries, int direction) +static void sn_dma_unmap_sg(struct device *dev, struct scatterlist *sgl, + int nhwentries, enum dma_data_direction dir, + struct dma_attrs *attrs) { int i; struct pci_dev *pdev = to_pci_dev(dev); struct sn_pcibus_provider *provider = SN_PCIDEV_BUSPROVIDER(pdev); + struct scatterlist *sg; - BUG_ON(dev->bus != &pci_bus_type); + BUG_ON(!dev_is_pci(dev)); - for (i = 0; i < nhwentries; i++, sg++) { - provider->dma_unmap(pdev, sg->dma_address, direction); + for_each_sg(sgl, sg, nhwentries, i) { + provider->dma_unmap(pdev, sg->dma_address, dir); sg->dma_address = (dma_addr_t) NULL; sg->dma_length = 0; } } -EXPORT_SYMBOL(sn_dma_unmap_sg); /** * sn_dma_map_sg - map a scatterlist for DMA @@ -241,37 +262,55 @@ EXPORT_SYMBOL(sn_dma_unmap_sg); * @sg: scatterlist to map * @nhwentries: number of entries * @direction: direction of the DMA transaction + * @attrs: optional dma attributes + * + * mappings with the DMA_ATTR_WRITE_BARRIER get mapped with + * dma_map_consistent() so that writes force a flush of pending DMA. + * (See "SGI Altix Architecture Considerations for Linux Device Drivers", + * Document Number: 007-4763-001) * * Maps each entry of @sg for DMA. */ -int sn_dma_map_sg(struct device *dev, struct scatterlist *sg, int nhwentries, - int direction) +static int sn_dma_map_sg(struct device *dev, struct scatterlist *sgl, + int nhwentries, enum dma_data_direction dir, + struct dma_attrs *attrs) { unsigned long phys_addr; - struct scatterlist *saved_sg = sg; + struct scatterlist *saved_sg = sgl, *sg; struct pci_dev *pdev = to_pci_dev(dev); struct sn_pcibus_provider *provider = SN_PCIDEV_BUSPROVIDER(pdev); int i; + int dmabarr; + + dmabarr = dma_get_attr(DMA_ATTR_WRITE_BARRIER, attrs); - BUG_ON(dev->bus != &pci_bus_type); + BUG_ON(!dev_is_pci(dev)); /* * Setup a DMA address for each entry in the scatterlist. */ - for (i = 0; i < nhwentries; i++, sg++) { + for_each_sg(sgl, sg, nhwentries, i) { + dma_addr_t dma_addr; phys_addr = SG_ENT_PHYS_ADDRESS(sg); - sg->dma_address = provider->dma_map(pdev, - phys_addr, sg->length, - SN_DMA_ADDR_PHYS); + if (dmabarr) + dma_addr = provider->dma_map_consistent(pdev, + phys_addr, + sg->length, + SN_DMA_ADDR_PHYS); + else + dma_addr = provider->dma_map(pdev, phys_addr, + sg->length, + SN_DMA_ADDR_PHYS); + sg->dma_address = dma_addr; if (!sg->dma_address) { - printk(KERN_ERR "%s: out of ATEs\n", __FUNCTION__); + printk(KERN_ERR "%s: out of ATEs\n", __func__); /* * Free any successfully allocated entries. */ if (i > 0) - sn_dma_unmap_sg(dev, saved_sg, i, direction); + sn_dma_unmap_sg(dev, saved_sg, i, dir, attrs); return 0; } @@ -280,41 +319,42 @@ int sn_dma_map_sg(struct device *dev, struct scatterlist *sg, int nhwentries, return nhwentries; } -EXPORT_SYMBOL(sn_dma_map_sg); -void sn_dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle, - size_t size, int direction) +static void sn_dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle, + size_t size, enum dma_data_direction dir) { - BUG_ON(dev->bus != &pci_bus_type); + BUG_ON(!dev_is_pci(dev)); } -EXPORT_SYMBOL(sn_dma_sync_single_for_cpu); -void sn_dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle, - size_t size, int direction) +static void sn_dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle, + size_t size, + enum dma_data_direction dir) { - BUG_ON(dev->bus != &pci_bus_type); + BUG_ON(!dev_is_pci(dev)); } -EXPORT_SYMBOL(sn_dma_sync_single_for_device); -void sn_dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, - int nelems, int direction) +static void sn_dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, + int nelems, enum dma_data_direction dir) { - BUG_ON(dev->bus != &pci_bus_type); + BUG_ON(!dev_is_pci(dev)); } -EXPORT_SYMBOL(sn_dma_sync_sg_for_cpu); -void sn_dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, - int nelems, int direction) +static void sn_dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, + int nelems, enum dma_data_direction dir) { - BUG_ON(dev->bus != &pci_bus_type); + BUG_ON(!dev_is_pci(dev)); } -EXPORT_SYMBOL(sn_dma_sync_sg_for_device); -int sn_dma_mapping_error(dma_addr_t dma_addr) +static int sn_dma_mapping_error(struct device *dev, dma_addr_t dma_addr) { return 0; } -EXPORT_SYMBOL(sn_dma_mapping_error); + +u64 sn_dma_get_required_mask(struct device *dev) +{ + return DMA_BIT_MASK(64); +} +EXPORT_SYMBOL_GPL(sn_dma_get_required_mask); char *sn_pci_get_legacy_mem(struct pci_bus *bus) { @@ -333,7 +373,7 @@ int sn_pci_legacy_read(struct pci_bus *bus, u16 port, u32 *val, u8 size) /* * First, try the SN_SAL_IOIF_PCI_SAFE SAL call which can work * around hw issues at the pci bus level. SGI proms older than - * 4.10 don't implment this. + * 4.10 don't implement this. */ SAL_CALL(isrv, SN_SAL_IOIF_PCI_SAFE, @@ -348,7 +388,7 @@ int sn_pci_legacy_read(struct pci_bus *bus, u16 port, u32 *val, u8 size) /* * If the above failed, retry using the SAL_PROBE call which should * be present in all proms (but which cannot work round PCI chipset - * bugs). This code is retained for compatability with old + * bugs). This code is retained for compatibility with old * pre-4.10 proms, and should be removed at some point in the future. */ @@ -379,7 +419,7 @@ int sn_pci_legacy_write(struct pci_bus *bus, u16 port, u32 val, u8 size) /* * First, try the SN_SAL_IOIF_PCI_SAFE SAL call which can work * around hw issues at the pci bus level. SGI proms older than - * 4.10 don't implment this. + * 4.10 don't implement this. */ SAL_CALL(isrv, SN_SAL_IOIF_PCI_SAFE, @@ -394,7 +434,7 @@ int sn_pci_legacy_write(struct pci_bus *bus, u16 port, u32 val, u8 size) /* * If the above failed, retry using the SAL_PROBE call which should * be present in all proms (but which cannot work round PCI chipset - * bugs). This code is retained for compatability with old + * bugs). This code is retained for compatibility with old * pre-4.10 proms, and should be removed at some point in the future. */ @@ -425,3 +465,23 @@ int sn_pci_legacy_write(struct pci_bus *bus, u16 port, u32 val, u8 size) out: return ret; } + +static struct dma_map_ops sn_dma_ops = { + .alloc = sn_dma_alloc_coherent, + .free = sn_dma_free_coherent, + .map_page = sn_dma_map_page, + .unmap_page = sn_dma_unmap_page, + .map_sg = sn_dma_map_sg, + .unmap_sg = sn_dma_unmap_sg, + .sync_single_for_cpu = sn_dma_sync_single_for_cpu, + .sync_sg_for_cpu = sn_dma_sync_sg_for_cpu, + .sync_single_for_device = sn_dma_sync_single_for_device, + .sync_sg_for_device = sn_dma_sync_sg_for_device, + .mapping_error = sn_dma_mapping_error, + .dma_supported = sn_dma_supported, +}; + +void sn_dma_init(void) +{ + dma_ops = &sn_dma_ops; +} diff --git a/arch/ia64/sn/pci/pcibr/Makefile b/arch/ia64/sn/pci/pcibr/Makefile index 3b403ea456f..396bcae3630 100644 --- a/arch/ia64/sn/pci/pcibr/Makefile +++ b/arch/ia64/sn/pci/pcibr/Makefile @@ -7,7 +7,7 @@ # # Makefile for the sn2 io routines. -CPPFLAGS += -I$(srctree)/arch/ia64/sn/include +ccflags-y := -Iarch/ia64/sn/include obj-y += pcibr_dma.o pcibr_reg.o \ pcibr_ate.o pcibr_provider.o diff --git a/arch/ia64/sn/pci/pcibr/pcibr_ate.c b/arch/ia64/sn/pci/pcibr/pcibr_ate.c index 1f0253bfe0a..5bc34eac9e0 100644 --- a/arch/ia64/sn/pci/pcibr/pcibr_ate.c +++ b/arch/ia64/sn/pci/pcibr/pcibr_ate.c @@ -30,7 +30,7 @@ static void mark_ate(struct ate_resource *ate_resource, int start, int number, /* * find_free_ate: Find the first free ate index starting from the given - * index for the desired consequtive count. + * index for the desired consecutive count. */ static int find_free_ate(struct ate_resource *ate_resource, int start, int count) @@ -54,6 +54,8 @@ static int find_free_ate(struct ate_resource *ate_resource, int start, break; } } + if (i >= ate_resource->num_ate) + return -1; } else index++; /* Try next ate */ } @@ -88,7 +90,7 @@ static inline int alloc_ate_resource(struct ate_resource *ate_resource, return -1; /* - * Find the required number of free consequtive ates. + * Find the required number of free consecutive ates. */ start_index = find_free_ate(ate_resource, ate_resource->lowest_free_index, @@ -105,7 +107,7 @@ static inline int alloc_ate_resource(struct ate_resource *ate_resource, /* * Allocate "count" contiguous Bridge Address Translation Entries * on the specified bridge to be used for PCI to XTALK mappings. - * Indices in rm map range from 1..num_entries. Indicies returned + * Indices in rm map range from 1..num_entries. Indices returned * to caller range from 0..num_entries-1. * * Return the start index on success, -1 on failure. @@ -126,7 +128,7 @@ int pcibr_ate_alloc(struct pcibus_info *pcibus_info, int count) * Setup an Address Translation Entry as specified. Use either the Bridge * internal maps or the external map RAM, as appropriate. */ -static inline u64 *pcibr_ate_addr(struct pcibus_info *pcibus_info, +static inline u64 __iomem *pcibr_ate_addr(struct pcibus_info *pcibus_info, int ate_index) { if (ate_index < pcibus_info->pbi_int_ate_size) { @@ -160,7 +162,7 @@ void pcibr_ate_free(struct pcibus_info *pcibus_info, int index) volatile u64 ate; int count; - u64 flags; + unsigned long flags; if (pcibr_invalidate_ate) { /* For debugging purposes, clear the valid bit in the ATE */ diff --git a/arch/ia64/sn/pci/pcibr/pcibr_dma.c b/arch/ia64/sn/pci/pcibr/pcibr_dma.c index a86c7b94596..1e863b277ac 100644 --- a/arch/ia64/sn/pci/pcibr/pcibr_dma.c +++ b/arch/ia64/sn/pci/pcibr/pcibr_dma.c @@ -8,6 +8,7 @@ #include <linux/types.h> #include <linux/pci.h> +#include <linux/export.h> #include <asm/sn/addrs.h> #include <asm/sn/geo.h> #include <asm/sn/pcibr_provider.h> @@ -96,10 +97,14 @@ pcibr_dmamap_ate32(struct pcidev_info *info, } /* - * If we're mapping for MSI, set the MSI bit in the ATE + * If we're mapping for MSI, set the MSI bit in the ATE. If it's a + * TIOCP based pci bus, we also need to set the PIO bit in the ATE. */ - if (dma_flags & SN_DMA_MSI) + 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); @@ -131,11 +136,10 @@ pcibr_dmatrans_direct64(struct pcidev_info * info, u64 paddr, 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) | dma_attributes; + PHYS_TO_TIODMA(paddr); else - pci_addr = IS_PIC_SOFT(pcibus_info) ? - paddr : - paddr | dma_attributes; + pci_addr = paddr; + pci_addr |= dma_attributes; /* Handle Bus mode */ if (IS_PCIX(pcibus_info)) @@ -197,7 +201,7 @@ pcibr_dmatrans_direct32(struct pcidev_info * info, } /* - * Wrapper routine for free'ing DMA maps + * Wrapper routine for freeing DMA maps * DMA mappings for Direct 64 and 32 do not have any DMA maps. */ void @@ -224,7 +228,7 @@ pcibr_dma_unmap(struct pci_dev *hwdev, dma_addr_t dma_handle, int direction) * after doing the read. For PIC this routine then forces a fake interrupt * on another line, which is logically associated with the slot that the PIO * is addressed to. It then spins while watching the memory location that - * the interrupt is targetted to. When the interrupt response arrives, we + * the interrupt is targeted to. When the interrupt response arrives, we * are sure that the DMA has landed in memory and it is safe for the driver * to proceed. For TIOCP use the Device(x) Write Request Buffer Flush * Bridge register since it ensures the data has entered the coherence domain, @@ -237,7 +241,7 @@ void sn_dma_flush(u64 addr) int is_tio; int wid_num; int i, j; - u64 flags; + unsigned long flags; u64 itte; struct hubdev_info *hubinfo; struct sn_flush_device_kernel *p; @@ -253,9 +257,7 @@ void sn_dma_flush(u64 addr) hubinfo = (NODEPDA(nasid_to_cnodeid(nasid)))->pdinfo; - if (!hubinfo) { - BUG(); - } + BUG_ON(!hubinfo); flush_nasid_list = &hubinfo->hdi_flush_nasid_list; if (flush_nasid_list->widget_p == NULL) diff --git a/arch/ia64/sn/pci/pcibr/pcibr_provider.c b/arch/ia64/sn/pci/pcibr/pcibr_provider.c index 838c93c9a16..8dbbef4a4f4 100644 --- a/arch/ia64/sn/pci/pcibr/pcibr_provider.c +++ b/arch/ia64/sn/pci/pcibr/pcibr_provider.c @@ -3,24 +3,28 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 2001-2004 Silicon Graphics, Inc. All rights reserved. + * Copyright (C) 2001-2004, 2006 Silicon Graphics, Inc. All rights reserved. */ #include <linux/interrupt.h> #include <linux/types.h> +#include <linux/slab.h> #include <linux/pci.h> +#include <linux/export.h> #include <asm/sn/addrs.h> #include <asm/sn/geo.h> #include <asm/sn/pcibr_provider.h> #include <asm/sn/pcibus_provider_defs.h> #include <asm/sn/pcidev.h> #include <asm/sn/sn_sal.h> +#include <asm/sn/pic.h> #include <asm/sn/sn2/sn_hwperf.h> #include "xtalk/xwidgetdev.h" #include "xtalk/hubdev.h" int -sal_pcibr_slot_enable(struct pcibus_info *soft, int device, void *resp) +sal_pcibr_slot_enable(struct pcibus_info *soft, int device, void *resp, + char **ssdt) { struct ia64_sal_retval ret_stuff; u64 busnum; @@ -32,7 +36,8 @@ sal_pcibr_slot_enable(struct pcibus_info *soft, int device, void *resp) segment = soft->pbi_buscommon.bs_persist_segment; busnum = soft->pbi_buscommon.bs_persist_busnum; SAL_CALL_NOLOCK(ret_stuff, (u64) SN_SAL_IOIF_SLOT_ENABLE, segment, - busnum, (u64) device, (u64) resp, 0, 0, 0); + busnum, (u64) device, (u64) resp, (u64)ia64_tpa(ssdt), + 0, 0); return (int)ret_stuff.v0; } @@ -76,8 +81,8 @@ static int sal_pcibr_error_interrupt(struct pcibus_info *soft) u16 sn_ioboard_to_pci_bus(struct pci_bus *pci_bus) { - s64 rc; - u16 ioboard; + long rc; + u16 uninitialized_var(ioboard); /* GCC be quiet */ nasid_t nasid = NASID_GET(SN_PCIBUS_BUSSOFT(pci_bus)->bs_base); rc = ia64_sn_sysctl_ioboard_get(nasid, &ioboard); @@ -95,13 +100,13 @@ u16 sn_ioboard_to_pci_bus(struct pci_bus *pci_bus) * bridge sends an error interrupt. */ static irqreturn_t -pcibr_error_intr_handler(int irq, void *arg, struct pt_regs *regs) +pcibr_error_intr_handler(int irq, void *arg) { - struct pcibus_info *soft = (struct pcibus_info *)arg; + struct pcibus_info *soft = arg; - if (sal_pcibr_error_interrupt(soft) < 0) { + if (sal_pcibr_error_interrupt(soft) < 0) panic("pcibr_error_intr_handler(): Fatal Bridge Error"); - } + return IRQ_HANDLED; } @@ -109,7 +114,6 @@ void * pcibr_bus_fixup(struct pcibus_bussoft *prom_bussoft, struct pci_controller *controller) { int nasid, cnode, j; - cnodeid_t near_cnode; struct hubdev_info *hubdev_info; struct pcibus_info *soft; struct sn_flush_device_kernel *sn_flush_device_kernel; @@ -123,26 +127,27 @@ pcibr_bus_fixup(struct pcibus_bussoft *prom_bussoft, struct pci_controller *cont * Allocate kernel bus soft and copy from prom. */ - soft = kmalloc(sizeof(struct pcibus_info), GFP_KERNEL); + soft = kmemdup(prom_bussoft, sizeof(struct pcibus_info), GFP_KERNEL); if (!soft) { return NULL; } - memcpy(soft, prom_bussoft, sizeof(struct pcibus_info)); - soft->pbi_buscommon.bs_base = - (((u64) soft->pbi_buscommon. - bs_base << 4) >> 4) | __IA64_UNCACHED_OFFSET; + soft->pbi_buscommon.bs_base = (unsigned long) + ioremap(REGION_OFFSET(soft->pbi_buscommon.bs_base), + sizeof(struct pic)); spin_lock_init(&soft->pbi_lock); /* * register the bridge's error interrupt handler */ - if (request_irq(SGI_PCIASIC_ERROR, (void *)pcibr_error_intr_handler, + if (request_irq(SGI_PCIASIC_ERROR, pcibr_error_intr_handler, IRQF_SHARED, "PCIBR error", (void *)(soft))) { printk(KERN_WARNING "pcibr cannot allocate interrupt for error handler\n"); } + irq_set_handler(SGI_PCIASIC_ERROR, handle_level_irq); + sn_set_err_irq_affinity(SGI_PCIASIC_ERROR); /* * Update the Bridge with the "kernel" pagesize @@ -186,20 +191,6 @@ pcibr_bus_fixup(struct pcibus_bussoft *prom_bussoft, struct pci_controller *cont return NULL; } - if (prom_bussoft->bs_asic_type == PCIIO_ASIC_TYPE_TIOCP) { - /* TIO PCI Bridge: find nearest node with CPUs */ - int e = sn_hwperf_get_nearest_node(cnode, NULL, &near_cnode); - - if (e < 0) { - near_cnode = (cnodeid_t)-1; /* use any node */ - printk(KERN_WARNING "pcibr_bus_fixup: failed to find " - "near node with CPUs to TIO node %d, err=%d\n", - cnode, e); - } - controller->node = near_cnode; - } - else - controller->node = cnode; return soft; } diff --git a/arch/ia64/sn/pci/tioca_provider.c b/arch/ia64/sn/pci/tioca_provider.c index c36b0f5affb..a70b11fd57d 100644 --- a/arch/ia64/sn/pci/tioca_provider.c +++ b/arch/ia64/sn/pci/tioca_provider.c @@ -9,6 +9,9 @@ #include <linux/types.h> #include <linux/interrupt.h> #include <linux/pci.h> +#include <linux/bitmap.h> +#include <linux/slab.h> +#include <linux/export.h> #include <asm/sn/sn_sal.h> #include <asm/sn/addrs.h> #include <asm/sn/io.h> @@ -88,7 +91,7 @@ tioca_gart_init(struct tioca_kernel *tioca_kern) break; default: printk(KERN_ERR "%s: Invalid CA_APERATURE_SIZE " - "0x%lx\n", __FUNCTION__, (ulong) CA_APERATURE_SIZE); + "0x%lx\n", __func__, (ulong) CA_APERATURE_SIZE); return -1; } @@ -123,8 +126,8 @@ tioca_gart_init(struct tioca_kernel *tioca_kern) if (!tmp) { printk(KERN_ERR "%s: Could not allocate " - "%lu bytes (order %d) for GART\n", - __FUNCTION__, + "%llu bytes (order %d) for GART\n", + __func__, tioca_kern->ca_gart_size, get_order(tioca_kern->ca_gart_size)); return -ENOMEM; @@ -223,7 +226,7 @@ tioca_fastwrite_enable(struct tioca_kernel *tioca_kern) /* * Scan all vga controllers on this bus making sure they all - * suport FW. If not, return. + * support FW. If not, return. */ list_for_each_entry(pdev, tioca_kern->ca_devices, bus_list) { @@ -341,15 +344,15 @@ tioca_dma_d48(struct pci_dev *pdev, u64 paddr) if (node_upper > 64) { printk(KERN_ERR "%s: coretalk addr 0x%p node id out " - "of range\n", __FUNCTION__, (void *)ct_addr); + "of range\n", __func__, (void *)ct_addr); return 0; } agp_dma_extn = __sn_readq_relaxed(&ca_base->ca_agp_dma_addr_extn); if (node_upper != (agp_dma_extn >> CA_AGP_DMA_NODE_ID_SHFT)) { printk(KERN_ERR "%s: coretalk upper node (%u) " - "mismatch with ca_agp_dma_addr_extn (%lu)\n", - __FUNCTION__, + "mismatch with ca_agp_dma_addr_extn (%llu)\n", + __func__, node_upper, (agp_dma_extn >> CA_AGP_DMA_NODE_ID_SHFT)); return 0; } @@ -364,12 +367,12 @@ tioca_dma_d48(struct pci_dev *pdev, u64 paddr) * @req_size: len (bytes) to map * * Map @paddr into CA address space using the GART mechanism. The mapped - * dma_addr_t is guarenteed to be contiguous in CA bus space. + * dma_addr_t is guaranteed to be contiguous in CA bus space. */ static dma_addr_t -tioca_dma_mapped(struct pci_dev *pdev, u64 paddr, size_t req_size) +tioca_dma_mapped(struct pci_dev *pdev, unsigned long paddr, size_t req_size) { - int i, ps, ps_shift, entry, entries, mapsize, last_entry; + int ps, ps_shift, entry, entries, mapsize; u64 xio_addr, end_xio_addr; struct tioca_common *tioca_common; struct tioca_kernel *tioca_kern; @@ -410,21 +413,13 @@ tioca_dma_mapped(struct pci_dev *pdev, u64 paddr, size_t req_size) map = tioca_kern->ca_pcigart_pagemap; mapsize = tioca_kern->ca_pcigart_entries; - entry = find_first_zero_bit(map, mapsize); - while (entry < mapsize) { - last_entry = find_next_bit(map, mapsize, entry); - - if (last_entry - entry >= entries) - break; - - entry = find_next_zero_bit(map, mapsize, last_entry); - } - - if (entry > mapsize) + entry = bitmap_find_next_zero_area(map, mapsize, 0, entries, 0); + if (entry >= mapsize) { + kfree(ca_dmamap); goto map_return; + } - for (i = 0; i < entries; i++) - set_bit(entry + i, map); + bitmap_set(map, entry, entries); bus_addr = tioca_kern->ca_pciap_base + (entry * ps); @@ -515,7 +510,7 @@ tioca_dma_unmap(struct pci_dev *pdev, dma_addr_t bus_addr, int dir) * use the GART mapped mode. */ static u64 -tioca_dma_map(struct pci_dev *pdev, u64 paddr, size_t byte_count, int dma_flags) +tioca_dma_map(struct pci_dev *pdev, unsigned long paddr, size_t byte_count, int dma_flags) { u64 mapaddr; @@ -526,7 +521,7 @@ tioca_dma_map(struct pci_dev *pdev, u64 paddr, size_t byte_count, int dma_flags) return 0; /* - * If card is 64 or 48 bit addresable, use a direct mapping. 32 + * If card is 64 or 48 bit addressable, use a direct mapping. 32 * bit direct is so restrictive w.r.t. where the memory resides that * we don't use it even though CA has some support. */ @@ -550,13 +545,12 @@ tioca_dma_map(struct pci_dev *pdev, u64 paddr, size_t byte_count, int dma_flags) * tioca_error_intr_handler - SGI TIO CA error interrupt handler * @irq: unused * @arg: pointer to tioca_common struct for the given CA - * @pt: unused * * Handle a CA error interrupt. Simply a wrapper around a SAL call which * defers processing to the SGI prom. */ static irqreturn_t -tioca_error_intr_handler(int irq, void *arg, struct pt_regs *pt) +tioca_error_intr_handler(int irq, void *arg) { struct tioca_common *soft = arg; struct ia64_sal_retval ret_stuff; @@ -598,7 +592,7 @@ tioca_bus_fixup(struct pcibus_bussoft *prom_bussoft, struct pci_controller *cont if (is_shub1() && sn_sal_rev() < 0x0406) { printk (KERN_ERR "%s: SGI prom rev 4.06 or greater required " - "for tioca support\n", __FUNCTION__); + "for tioca support\n", __func__); return NULL; } @@ -606,12 +600,14 @@ tioca_bus_fixup(struct pcibus_bussoft *prom_bussoft, struct pci_controller *cont * Allocate kernel bus soft and copy from prom. */ - tioca_common = kzalloc(sizeof(struct tioca_common), GFP_KERNEL); + tioca_common = kmemdup(prom_bussoft, sizeof(struct tioca_common), + GFP_KERNEL); if (!tioca_common) return NULL; - memcpy(tioca_common, prom_bussoft, sizeof(struct tioca_common)); - tioca_common->ca_common.bs_base |= __IA64_UNCACHED_OFFSET; + tioca_common->ca_common.bs_base = (unsigned long) + ioremap(REGION_OFFSET(tioca_common->ca_common.bs_base), + sizeof(struct tioca_common)); /* init kernel-private area */ @@ -650,9 +646,12 @@ tioca_bus_fixup(struct pcibus_bussoft *prom_bussoft, struct pci_controller *cont printk(KERN_WARNING "%s: Unable to get irq %d. " "Error interrupts won't be routed for TIOCA bus %d\n", - __FUNCTION__, SGI_TIOCA_ERROR, + __func__, SGI_TIOCA_ERROR, (int)tioca_common->ca_common.bs_persist_busnum); + irq_set_handler(SGI_TIOCA_ERROR, handle_level_irq); + sn_set_err_irq_affinity(SGI_TIOCA_ERROR); + /* Setup locality information */ controller->node = tioca_kern->ca_closest_node; return tioca_common; diff --git a/arch/ia64/sn/pci/tioce_provider.c b/arch/ia64/sn/pci/tioce_provider.c index af7171adcd2..46d3df4b03a 100644 --- a/arch/ia64/sn/pci/tioce_provider.c +++ b/arch/ia64/sn/pci/tioce_provider.c @@ -8,6 +8,7 @@ #include <linux/types.h> #include <linux/interrupt.h> +#include <linux/slab.h> #include <linux/pci.h> #include <asm/sn/sn_sal.h> #include <asm/sn/addrs.h> @@ -15,7 +16,6 @@ #include <asm/sn/pcidev.h> #include <asm/sn/pcibus_provider_defs.h> #include <asm/sn/tioce_provider.h> -#include <asm/sn/sn2/sn_hwperf.h> /* * 1/26/2006 @@ -42,7 +42,7 @@ * } else * do desired mmr access * - * According to hw, we can use reads instead of writes to the above addres + * According to hw, we can use reads instead of writes to the above address * * Note this WAR can only to be used for accessing internal MMR's in the * TIOCE Coretalk Address Range 0x0 - 0x07ff_ffff. This includes the @@ -53,7 +53,7 @@ */ static void inline -tioce_mmr_war_pre(struct tioce_kernel *kern, void *mmr_addr) +tioce_mmr_war_pre(struct tioce_kernel *kern, void __iomem *mmr_addr) { u64 mmr_base; u64 mmr_offset; @@ -62,7 +62,7 @@ tioce_mmr_war_pre(struct tioce_kernel *kern, void *mmr_addr) return; mmr_base = kern->ce_common->ce_pcibus.bs_base; - mmr_offset = (u64)mmr_addr - mmr_base; + mmr_offset = (unsigned long)mmr_addr - mmr_base; if (mmr_offset < 0x45000) { u64 mmr_war_offset; @@ -79,7 +79,7 @@ tioce_mmr_war_pre(struct tioce_kernel *kern, void *mmr_addr) } static void inline -tioce_mmr_war_post(struct tioce_kernel *kern, void *mmr_addr) +tioce_mmr_war_post(struct tioce_kernel *kern, void __iomem *mmr_addr) { u64 mmr_base; u64 mmr_offset; @@ -88,7 +88,7 @@ tioce_mmr_war_post(struct tioce_kernel *kern, void *mmr_addr) return; mmr_base = kern->ce_common->ce_pcibus.bs_base; - mmr_offset = (u64)mmr_addr - mmr_base; + mmr_offset = (unsigned long)mmr_addr - mmr_base; if (mmr_offset < 0x45000) { if (mmr_offset == 0x100) @@ -223,7 +223,7 @@ tioce_dma_d64(unsigned long ct_addr, int dma_flags) * @pci_dev. */ static inline void -pcidev_to_tioce(struct pci_dev *pdev, struct tioce **base, +pcidev_to_tioce(struct pci_dev *pdev, struct tioce __iomem **base, struct tioce_kernel **kernel, int *port) { struct pcidev_info *pcidev_info; @@ -235,7 +235,7 @@ pcidev_to_tioce(struct pci_dev *pdev, struct tioce **base, ce_kernel = (struct tioce_kernel *)ce_common->ce_kernel_private; if (base) - *base = (struct tioce *)ce_common->ce_pcibus.bs_base; + *base = (struct tioce __iomem *)ce_common->ce_pcibus.bs_base; if (kernel) *kernel = ce_kernel; @@ -257,9 +257,9 @@ pcidev_to_tioce(struct pci_dev *pdev, struct tioce **base, * @ct_addr: the coretalk address to map * @len: number of bytes to map * - * Given the addressing type, set up various paramaters that define the + * Given the addressing type, set up various parameters that define the * ATE pool to use. Search for a contiguous block of entries to cover the - * length, and if enough resources exist, fill in the ATE's and construct a + * length, and if enough resources exist, fill in the ATEs and construct a * tioce_dmamap struct to track the mapping. */ static u64 @@ -275,13 +275,13 @@ tioce_alloc_map(struct tioce_kernel *ce_kern, int type, int port, u64 pagesize; int msi_capable, msi_wanted; u64 *ate_shadow; - u64 *ate_reg; + u64 __iomem *ate_reg; u64 addr; - struct tioce *ce_mmr; + struct tioce __iomem *ce_mmr; u64 bus_base; struct tioce_dmamap *map; - ce_mmr = (struct tioce *)ce_kern->ce_common->ce_pcibus.bs_base; + ce_mmr = (struct tioce __iomem *)ce_kern->ce_common->ce_pcibus.bs_base; switch (type) { case TIOCE_ATE_M32: @@ -386,7 +386,7 @@ tioce_dma_d32(struct pci_dev *pdev, u64 ct_addr, int dma_flags) { int dma_ok; int port; - struct tioce *ce_mmr; + struct tioce __iomem *ce_mmr; struct tioce_kernel *ce_kern; u64 ct_upper; u64 ct_lower; @@ -461,7 +461,7 @@ tioce_dma_unmap(struct pci_dev *pdev, dma_addr_t bus_addr, int dir) int i; int port; struct tioce_kernel *ce_kern; - struct tioce *ce_mmr; + struct tioce __iomem *ce_mmr; unsigned long flags; bus_addr = tioce_dma_barrier(bus_addr, 0); @@ -494,8 +494,8 @@ tioce_dma_unmap(struct pci_dev *pdev, dma_addr_t bus_addr, int dir) if (&map->ce_dmamap_list == &ce_kern->ce_dmamap_list) { printk(KERN_WARNING - "%s: %s - no map found for bus_addr 0x%lx\n", - __FUNCTION__, pci_name(pdev), bus_addr); + "%s: %s - no map found for bus_addr 0x%llx\n", + __func__, pci_name(pdev), bus_addr); } else if (--map->refcnt == 0) { for (i = 0; i < map->ate_count; i++) { map->ate_shadow[i] = 0; @@ -582,8 +582,8 @@ tioce_do_dma_map(struct pci_dev *pdev, u64 paddr, size_t byte_count, */ if (!mapaddr && !barrier && dma_mask >= 0xffffffffffUL) { /* - * We have two options for 40-bit mappings: 16GB "super" ATE's - * and 64MB "regular" ATE's. We'll try both if needed for a + * We have two options for 40-bit mappings: 16GB "super" ATEs + * and 64MB "regular" ATEs. We'll try both if needed for a * given mapping but which one we try first depends on the * size. For requests >64MB, prefer to use a super page with * regular as the fallback. Otherwise, try in the reverse order. @@ -643,7 +643,7 @@ dma_map_done: * in the address. */ static u64 -tioce_dma(struct pci_dev *pdev, u64 paddr, size_t byte_count, int dma_flags) +tioce_dma(struct pci_dev *pdev, unsigned long paddr, size_t byte_count, int dma_flags) { return tioce_do_dma_map(pdev, paddr, byte_count, 0, dma_flags); } @@ -656,8 +656,9 @@ tioce_dma(struct pci_dev *pdev, u64 paddr, size_t byte_count, int dma_flags) * * Simply call tioce_do_dma_map() to create a map with the barrier bit set * in the address. - */ static u64 -tioce_dma_consistent(struct pci_dev *pdev, u64 paddr, size_t byte_count, int dma_flags) + */ +static u64 +tioce_dma_consistent(struct pci_dev *pdev, unsigned long paddr, size_t byte_count, int dma_flags) { return tioce_do_dma_map(pdev, paddr, byte_count, 1, dma_flags); } @@ -666,12 +667,12 @@ tioce_dma_consistent(struct pci_dev *pdev, u64 paddr, size_t byte_count, int dma * tioce_error_intr_handler - SGI TIO CE error interrupt handler * @irq: unused * @arg: pointer to tioce_common struct for the given CE - * @pt: unused * * Handle a CE error interrupt. Simply a wrapper around a SAL call which * defers processing to the SGI prom. - */ static irqreturn_t -tioce_error_intr_handler(int irq, void *arg, struct pt_regs *pt) + */ +static irqreturn_t +tioce_error_intr_handler(int irq, void *arg) { struct tioce_common *soft = arg; struct ia64_sal_retval ret_stuff; @@ -689,8 +690,8 @@ tioce_error_intr_handler(int irq, void *arg, struct pt_regs *pt) } /** - * tioce_reserve_m32 - reserve M32 ate's for the indicated address range - * @tioce_kernel: TIOCE context to reserve ate's for + * tioce_reserve_m32 - reserve M32 ATEs for the indicated address range + * @tioce_kernel: TIOCE context to reserve ATEs for * @base: starting bus address to reserve * @limit: last bus address to reserve * @@ -701,9 +702,9 @@ static void tioce_reserve_m32(struct tioce_kernel *ce_kern, u64 base, u64 limit) { int ate_index, last_ate, ps; - struct tioce *ce_mmr; + struct tioce __iomem *ce_mmr; - ce_mmr = (struct tioce *)ce_kern->ce_common->ce_pcibus.bs_base; + ce_mmr = (struct tioce __iomem *)ce_kern->ce_common->ce_pcibus.bs_base; ps = ce_kern->ce_ate3240_pagesize; ate_index = ATE_PAGE(base, ps); last_ate = ate_index + ATE_NPAGES(base, limit-base+1, ps) - 1; @@ -737,7 +738,7 @@ tioce_kern_init(struct tioce_common *tioce_common) int dev; u32 tmp; unsigned int seg, bus; - struct tioce *tioce_mmr; + struct tioce __iomem *tioce_mmr; struct tioce_kernel *tioce_kern; tioce_kern = kzalloc(sizeof(struct tioce_kernel), GFP_KERNEL); @@ -754,21 +755,21 @@ tioce_kern_init(struct tioce_common *tioce_common) * Determine the secondary bus number of the port2 logical PPB. * This is used to decide whether a given pci device resides on * port1 or port2. Note: We don't have enough plumbing set up - * here to use pci_read_config_xxx() so use the raw_pci_ops vector. + * here to use pci_read_config_xxx() so use raw_pci_read(). */ seg = tioce_common->ce_pcibus.bs_persist_segment; bus = tioce_common->ce_pcibus.bs_persist_busnum; - raw_pci_ops->read(seg, bus, PCI_DEVFN(2, 0), PCI_SECONDARY_BUS, 1,&tmp); + raw_pci_read(seg, bus, PCI_DEVFN(2, 0), PCI_SECONDARY_BUS, 1,&tmp); tioce_kern->ce_port1_secondary = (u8) tmp; /* * Set PMU pagesize to the largest size available, and zero out - * the ate's. + * the ATEs. */ - tioce_mmr = (struct tioce *)tioce_common->ce_pcibus.bs_base; + tioce_mmr = (struct tioce __iomem *)tioce_common->ce_pcibus.bs_base; tioce_mmr_clri(tioce_kern, &tioce_mmr->ce_ure_page_map, CE_URE_PAGESIZE_MASK); tioce_mmr_seti(tioce_kern, &tioce_mmr->ce_ure_page_map, @@ -786,7 +787,7 @@ tioce_kern_init(struct tioce_common *tioce_common) } /* - * Reserve ATE's corresponding to reserved address ranges. These + * Reserve ATEs corresponding to reserved address ranges. These * include: * * Memory space covered by each PPB mem base/limit register @@ -801,11 +802,11 @@ tioce_kern_init(struct tioce_common *tioce_common) /* mem base/limit */ - raw_pci_ops->read(seg, bus, PCI_DEVFN(dev, 0), + raw_pci_read(seg, bus, PCI_DEVFN(dev, 0), PCI_MEMORY_BASE, 2, &tmp); base = (u64)tmp << 16; - raw_pci_ops->read(seg, bus, PCI_DEVFN(dev, 0), + raw_pci_read(seg, bus, PCI_DEVFN(dev, 0), PCI_MEMORY_LIMIT, 2, &tmp); limit = (u64)tmp << 16; limit |= 0xfffffUL; @@ -819,21 +820,21 @@ tioce_kern_init(struct tioce_common *tioce_common) * attributes. */ - raw_pci_ops->read(seg, bus, PCI_DEVFN(dev, 0), + raw_pci_read(seg, bus, PCI_DEVFN(dev, 0), PCI_PREF_MEMORY_BASE, 2, &tmp); base = ((u64)tmp & PCI_PREF_RANGE_MASK) << 16; - raw_pci_ops->read(seg, bus, PCI_DEVFN(dev, 0), + raw_pci_read(seg, bus, PCI_DEVFN(dev, 0), PCI_PREF_BASE_UPPER32, 4, &tmp); base |= (u64)tmp << 32; - raw_pci_ops->read(seg, bus, PCI_DEVFN(dev, 0), + raw_pci_read(seg, bus, PCI_DEVFN(dev, 0), PCI_PREF_MEMORY_LIMIT, 2, &tmp); limit = ((u64)tmp & PCI_PREF_RANGE_MASK) << 16; limit |= 0xfffffUL; - raw_pci_ops->read(seg, bus, PCI_DEVFN(dev, 0), + raw_pci_read(seg, bus, PCI_DEVFN(dev, 0), PCI_PREF_LIMIT_UPPER32, 4, &tmp); limit |= (u64)tmp << 32; @@ -859,7 +860,7 @@ tioce_force_interrupt(struct sn_irq_info *sn_irq_info) struct pcidev_info *pcidev_info; struct tioce_common *ce_common; struct tioce_kernel *ce_kern; - struct tioce *ce_mmr; + struct tioce __iomem *ce_mmr; u64 force_int_val; if (!sn_irq_info->irq_bridge) @@ -873,7 +874,7 @@ tioce_force_interrupt(struct sn_irq_info *sn_irq_info) return; ce_common = (struct tioce_common *)pcidev_info->pdi_pcibus_info; - ce_mmr = (struct tioce *)ce_common->ce_pcibus.bs_base; + ce_mmr = (struct tioce __iomem *)ce_common->ce_pcibus.bs_base; ce_kern = (struct tioce_kernel *)ce_common->ce_kernel_private; /* @@ -954,7 +955,7 @@ tioce_target_interrupt(struct sn_irq_info *sn_irq_info) struct pcidev_info *pcidev_info; struct tioce_common *ce_common; struct tioce_kernel *ce_kern; - struct tioce *ce_mmr; + struct tioce __iomem *ce_mmr; int bit; u64 vector; @@ -963,7 +964,7 @@ tioce_target_interrupt(struct sn_irq_info *sn_irq_info) return; ce_common = (struct tioce_common *)pcidev_info->pdi_pcibus_info; - ce_mmr = (struct tioce *)ce_common->ce_pcibus.bs_base; + ce_mmr = (struct tioce __iomem *)ce_common->ce_pcibus.bs_base; ce_kern = (struct tioce_kernel *)ce_common->ce_kernel_private; bit = sn_irq_info->irq_int_bit; @@ -991,11 +992,9 @@ tioce_target_interrupt(struct sn_irq_info *sn_irq_info) static void * tioce_bus_fixup(struct pcibus_bussoft *prom_bussoft, struct pci_controller *controller) { - int my_nasid; - cnodeid_t my_cnode, mem_cnode; struct tioce_common *tioce_common; struct tioce_kernel *tioce_kern; - struct tioce *tioce_mmr; + struct tioce __iomem *tioce_mmr; /* * Allocate kernel bus soft and copy from prom. @@ -1006,7 +1005,9 @@ tioce_bus_fixup(struct pcibus_bussoft *prom_bussoft, struct pci_controller *cont return NULL; memcpy(tioce_common, prom_bussoft, sizeof(struct tioce_common)); - tioce_common->ce_pcibus.bs_base |= __IA64_UNCACHED_OFFSET; + tioce_common->ce_pcibus.bs_base = (unsigned long) + ioremap(REGION_OFFSET(tioce_common->ce_pcibus.bs_base), + sizeof(struct tioce_common)); tioce_kern = tioce_kern_init(tioce_common); if (tioce_kern == NULL) { @@ -1019,7 +1020,7 @@ tioce_bus_fixup(struct pcibus_bussoft *prom_bussoft, struct pci_controller *cont * interrupt handler. */ - tioce_mmr = (struct tioce *)tioce_common->ce_pcibus.bs_base; + tioce_mmr = (struct tioce __iomem *)tioce_common->ce_pcibus.bs_base; tioce_mmr_seti(tioce_kern, &tioce_mmr->ce_adm_int_status_alias, ~0ULL); tioce_mmr_seti(tioce_kern, &tioce_mmr->ce_adm_error_summary_alias, ~0ULL); @@ -1032,25 +1033,12 @@ tioce_bus_fixup(struct pcibus_bussoft *prom_bussoft, struct pci_controller *cont "%s: Unable to get irq %d. " "Error interrupts won't be routed for " "TIOCE bus %04x:%02x\n", - __FUNCTION__, SGI_PCIASIC_ERROR, + __func__, SGI_PCIASIC_ERROR, tioce_common->ce_pcibus.bs_persist_segment, tioce_common->ce_pcibus.bs_persist_busnum); - /* - * identify closest nasid for memory allocations - */ - - my_nasid = NASID_GET(tioce_common->ce_pcibus.bs_base); - my_cnode = nasid_to_cnodeid(my_nasid); - - if (sn_hwperf_get_nearest_node(my_cnode, &mem_cnode, NULL) < 0) { - printk(KERN_WARNING "tioce_bus_fixup: failed to find " - "closest node with MEM to TIO node %d\n", my_cnode); - mem_cnode = (cnodeid_t)-1; /* use any node */ - } - - controller->node = mem_cnode; - + irq_set_handler(SGI_PCIASIC_ERROR, handle_level_irq); + sn_set_err_irq_affinity(SGI_PCIASIC_ERROR); return tioce_common; } |
