From c4c3f3ffd590c40c9d3faaa248c2f7be54b1fd4d Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Thu, 7 Aug 2003 09:38:44 -0700 Subject: [PATCH] [PATCH] ia64: sn2 pci fixes (among others) sn2 still doesn't use ACPI to describe PCI busses on the system (I'm working on it), so we have to do it the old fashioned way. This patch also includes a few other fixes. --- arch/ia64/sn/io/hwgfs/interface.c | 5 +- arch/ia64/sn/io/machvec/pci.c | 86 ++--------- arch/ia64/sn/io/machvec/pci_bus_cvlink.c | 151 +++++++------------- arch/ia64/sn/io/platform_init/sgi_io_init.c | 31 +--- arch/ia64/sn/kernel/sn2/cache.c | 6 + include/asm-ia64/sn/hcl.h | 1 + 6 files changed, 76 insertions(+), 204 deletions(-) diff --git a/arch/ia64/sn/io/hwgfs/interface.c b/arch/ia64/sn/io/hwgfs/interface.c index dda279d7851d9..6ff6da81160a2 100644 --- a/arch/ia64/sn/io/hwgfs/interface.c +++ b/arch/ia64/sn/io/hwgfs/interface.c @@ -40,15 +40,12 @@ #include #include #include +#include #include extern struct vfsmount *hwgfs_vfsmount; -/* TODO: Move this to some .h file or, more likely, use a slightly - different interface from lookup_create. */ -extern struct dentry *lookup_create(struct nameidata *nd, int is_dir); - static int walk_parents_mkdir( const char **path, diff --git a/arch/ia64/sn/io/machvec/pci.c b/arch/ia64/sn/io/machvec/pci.c index 6eba9885d782d..f391222452ee6 100644 --- a/arch/ia64/sn/io/machvec/pci.c +++ b/arch/ia64/sn/io/machvec/pci.c @@ -30,17 +30,13 @@ #include #include -#ifdef DEBUG_CONFIG -#define DBG(x...) printk(x) -#else -#define DBG(x...) -#endif - - - +/* + * These routines are only used during sn_pci_init for probing each bus, and + * can probably be removed with a little more cleanup now that the SAL routines + * work on sn2. + */ #ifdef CONFIG_PCI -extern vertex_hdl_t pci_bus_to_vertex(unsigned char); extern vertex_hdl_t devfn_to_vertex(unsigned char bus, unsigned char devfn); int sn_read_config(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *val) @@ -49,10 +45,12 @@ int sn_read_config(struct pci_bus *bus, unsigned int devfn, int where, int size, vertex_hdl_t device_vertex; device_vertex = devfn_to_vertex(bus->number, devfn); + if (!device_vertex) return PCIBIOS_DEVICE_NOT_FOUND; - res = pciio_config_get(device_vertex, (unsigned) where, size); - *val = (unsigned int) res; + + res = pciio_config_get(device_vertex, (unsigned)where, size); + *val = (u32)res; return PCIBIOS_SUCCESSFUL; } @@ -61,79 +59,21 @@ int sn_write_config(struct pci_bus *bus, unsigned int devfn, int where, int size vertex_hdl_t device_vertex; device_vertex = devfn_to_vertex(bus->number, devfn); + if (!device_vertex) return PCIBIOS_DEVICE_NOT_FOUND; - pciio_config_set( device_vertex, (unsigned)where, size, (uint64_t) val); + + pciio_config_set(device_vertex, (unsigned)where, size, (uint64_t)val); return PCIBIOS_SUCCESSFUL; } struct pci_ops sn_pci_ops = { .read = sn_read_config, - .write = sn_write_config + .write = sn_write_config, }; -/* - * sn_pci_find_bios - SNIA64 pci_find_bios() platform specific code. - */ -void __init -sn_pci_find_bios(void) -{ - extern struct pci_ops *pci_root_ops; - /* - * Go initialize our IO Infrastructure .. - */ - extern void sgi_master_io_infr_init(void); - - sgi_master_io_infr_init(); - - /* sn_io_infrastructure_init(); */ - pci_root_ops = &sn_pci_ops; -} - -void -pci_fixup_ioc3(struct pci_dev *d) -{ - int i; - unsigned int size; - - /* IOC3 only decodes 0x20 bytes of the config space, reading - * beyond that is relatively benign but writing beyond that - * (especially the base address registers) will shut down the - * pci bus...so avoid doing so. - * NOTE: this means we can't program the intr_pin into the device, - * currently we hack this with special code in - * sgi_pci_intr_support() - */ - DBG("pci_fixup_ioc3: Fixing base addresses for ioc3 device %s\n", d->slot_name); - - /* I happen to know from the spec that the ioc3 needs only 0xfffff - * The standard pci trick of writing ~0 to the baddr and seeing - * what comes back doesn't work with the ioc3 - */ - size = 0xfffff; - d->resource[0].end = (unsigned long) d->resource[0].start + (unsigned long) size; - - /* - * Zero out the resource structure .. because we did not go through - * the normal PCI Infrastructure Init, garbbage are left in these - * fileds. - */ - for (i = 1; i <= PCI_ROM_RESOURCE; i++) { - d->resource[i].start = 0UL; - d->resource[i].end = 0UL; - d->resource[i].flags = 0UL; - } - - d->subsystem_vendor = 0; - d->subsystem_device = 0; - -} - #else -void sn_pci_find_bios(void) {} -void pci_fixup_ioc3(struct pci_dev *d) {} struct list_head pci_root_buses; struct list_head pci_root_buses; struct list_head pci_devices; - #endif /* CONFIG_PCI */ diff --git a/arch/ia64/sn/io/machvec/pci_bus_cvlink.c b/arch/ia64/sn/io/machvec/pci_bus_cvlink.c index 51e53d0d4193d..455b5884fee63 100644 --- a/arch/ia64/sn/io/machvec/pci_bus_cvlink.c +++ b/arch/ia64/sn/io/machvec/pci_bus_cvlink.c @@ -411,34 +411,6 @@ sn_dma_flush_init(unsigned long start, unsigned long end, int idx, int pin, int } } -/* - * Most drivers currently do not properly tell the arch specific pci dma - * interfaces whether they can handle A64. Here is where we privately - * keep track of this. - */ -static void __init -set_sn_pci64(struct pci_dev *dev) -{ - unsigned short vendor = dev->vendor; - unsigned short device = dev->device; - - if (vendor == PCI_VENDOR_ID_QLOGIC) { - if ((device == PCI_DEVICE_ID_QLOGIC_ISP2100) || - (device == PCI_DEVICE_ID_QLOGIC_ISP2200)) { - SET_PCIA64(dev); - return; - } - } - - if (vendor == PCI_VENDOR_ID_SGI) { - if (device == PCI_DEVICE_ID_SGI_IOC3) { - SET_PCIA64(dev); - return; - } - } - -} - /* * sn_pci_fixup() - This routine is called when platform_pci_fixup() is * invoked at the end of pcibios_init() to link the Linux pci @@ -455,10 +427,9 @@ sn_pci_fixup(int arg) struct sn_widget_sysdata *widget_sysdata; struct sn_device_sysdata *device_sysdata; pciio_intr_t intr_handle; - int cpuid, bit; + int cpuid; vertex_hdl_t device_vertex; pciio_intr_line_t lines; - extern void sn_pci_find_bios(void); extern int numnodes; int cnode; @@ -466,8 +437,11 @@ sn_pci_fixup(int arg) #ifdef CONFIG_PROC_FS extern void register_sn_procfs(void); #endif - - sn_pci_find_bios(); + extern void irix_io_init(void); + + init_hcl(); + irix_io_init(); + for (cnode = 0; cnode < numnodes; cnode++) { extern void intr_init_vecblk(nodepda_t *npda, cnodeid_t, int); intr_init_vecblk(NODEPDA(cnode), cnode, 0); @@ -512,32 +486,25 @@ sn_pci_fixup(int arg) unsigned int irq; int idx; u16 cmd; - vertex_hdl_t vhdl; unsigned long size; extern int bit_pos_to_irq(int); - if (device_dev->vendor == PCI_VENDOR_ID_SGI && - device_dev->device == PCI_DEVICE_ID_SGI_IOC3) { - extern void pci_fixup_ioc3(struct pci_dev *d); - pci_fixup_ioc3(device_dev); - } - /* Set the device vertex */ device_sysdata = kmalloc(sizeof(struct sn_device_sysdata), - GFP_KERNEL); + GFP_KERNEL); device_sysdata->vhdl = devfn_to_vertex(device_dev->bus->number, device_dev->devfn); device_sysdata->isa64 = 0; - /* - * Set the xbridge Device(X) Write Buffer Flush and Xbow Flush - * register addresses. - */ - (void) set_flush_addresses(device_dev, device_sysdata); + device_vertex = device_sysdata->vhdl; device_dev->sysdata = (void *) device_sysdata; - set_sn_pci64(device_dev); set_isPIC(device_sysdata); + /* + * Set the xbridge Device(X) Write Buffer Flush and Xbow Flush + * register addresses. + */ + set_flush_addresses(device_dev, device_sysdata); pci_read_config_word(device_dev, PCI_COMMAND, &cmd); /* @@ -546,13 +513,12 @@ sn_pci_fixup(int arg) * read from the card and it was set in the card by our * Infrastructure .. */ - vhdl = device_sysdata->vhdl; for (idx = 0; idx < PCI_ROM_RESOURCE; idx++) { size = 0; size = device_dev->resource[idx].end - device_dev->resource[idx].start; if (size) { - device_dev->resource[idx].start = (unsigned long)pciio_pio_addr(vhdl, 0, PCIIO_SPACE_WIN(idx), 0, size, 0, (IS_PIC_DEVICE(device_dev)) ? 0 : PCIIO_BYTE_STREAM); + device_dev->resource[idx].start = (unsigned long)pciio_pio_addr(device_vertex, 0, PCIIO_SPACE_WIN(idx), 0, size, 0, (IS_PIC_DEVICE(device_dev)) ? 0 : PCIIO_BYTE_STREAM); device_dev->resource[idx].start |= __IA64_UNCACHED_OFFSET; } else @@ -567,28 +533,6 @@ sn_pci_fixup(int arg) if (device_dev->resource[idx].flags & IORESOURCE_MEM) cmd |= PCI_COMMAND_MEMORY; } -#if 0 - /* - * Software WAR for a Software BUG. - * This is only temporary. - * See PV 872791 - */ - - /* - * Now handle the ROM resource .. - */ - size = device_dev->resource[PCI_ROM_RESOURCE].end - - device_dev->resource[PCI_ROM_RESOURCE].start; - - if (size) { - device_dev->resource[PCI_ROM_RESOURCE].start = - (unsigned long) pciio_pio_addr(vhdl, 0, PCIIO_SPACE_ROM, 0, - size, 0, (IS_PIC_DEVICE(device_dev)) ? 0 : PCIIO_BYTE_STREAM); - device_dev->resource[PCI_ROM_RESOURCE].start |= __IA64_UNCACHED_OFFSET; - device_dev->resource[PCI_ROM_RESOURCE].end = - device_dev->resource[PCI_ROM_RESOURCE].start + size; - } -#endif /* * Update the Command Word on the Card. @@ -596,16 +540,10 @@ sn_pci_fixup(int arg) cmd |= PCI_COMMAND_MASTER; /* If the device doesn't support */ /* bit gets dropped .. no harm */ pci_write_config_word(device_dev, PCI_COMMAND, cmd); - - pci_read_config_byte(device_dev, PCI_INTERRUPT_PIN, (unsigned char *)&lines); - if (device_dev->vendor == PCI_VENDOR_ID_SGI && - device_dev->device == PCI_DEVICE_ID_SGI_IOC3 ) { - lines = 1; - } - - device_sysdata = (struct sn_device_sysdata *)device_dev->sysdata; - device_vertex = device_sysdata->vhdl; - + + pci_read_config_byte(device_dev, PCI_INTERRUPT_PIN, + (unsigned char *)&lines); + irqpdaindr->current = device_dev; intr_handle = pciio_intr_alloc(device_vertex, NULL, lines, device_vertex); @@ -622,7 +560,8 @@ sn_pci_fixup(int arg) size = device_dev->resource[idx].end - device_dev->resource[idx].start; - if (size == 0) continue; + if (size == 0) + continue; for (i=0; i<8; i++) { if (ibits & (1 << i) ) { @@ -636,22 +575,6 @@ sn_pci_fixup(int arg) } } -#ifdef ajmtestintr - { - int slot = PCI_SLOT(device_dev->devfn); - static int timer_set = 0; - pcibr_intr_t pcibr_intr = (pcibr_intr_t)intr_handle; - pcibr_soft_t pcibr_soft = pcibr_intr->bi_soft; - extern void intr_test_handle_intr(int, void*, struct pt_regs *); - - if (!timer_set) { - intr_test_set_timer(); - timer_set = 1; - } - intr_test_register_irq(irq, pcibr_soft, slot); - request_irq(irq, intr_test_handle_intr,0,NULL, NULL); - } -#endif } /* @@ -928,3 +851,37 @@ pci_bus_to_hcl_cvlink(void) return(0); } + +/* + * Ugly hack to get PCI setup until we have a proper ACPI namespace. + */ +extern struct pci_ops sn_pci_ops; +int __init +sn_pci_init (void) +{ +# define PCI_BUSES_TO_SCAN 256 + int i = 0; + struct pci_controller *controller; + + /* + * set pci_raw_ops, etc. + */ + sn_pci_fixup(0); + + controller = kmalloc(sizeof(struct pci_controller), GFP_KERNEL); + if (controller) { + memset(controller, 0, sizeof(struct pci_controller)); + /* just allocate some devices and fill in the pci_dev structs */ + for (i = 0; i < PCI_BUSES_TO_SCAN; i++) + pci_scan_bus(i, &sn_pci_ops, controller); + } + + /* + * actually find devices and fill in hwgraph structs + */ + sn_pci_fixup(1); + + return 0; +} + +subsys_initcall(sn_pci_init); diff --git a/arch/ia64/sn/io/platform_init/sgi_io_init.c b/arch/ia64/sn/io/platform_init/sgi_io_init.c index 3583456b1ccc3..6a8992849777f 100644 --- a/arch/ia64/sn/io/platform_init/sgi_io_init.c +++ b/arch/ia64/sn/io/platform_init/sgi_io_init.c @@ -9,15 +9,13 @@ #include #include #include +#include #include #include #include #include #include #include -#include - -extern int init_hcl(void); /* * per_hub_init @@ -80,30 +78,3 @@ per_hub_init(cnodeid_t cnode) /* Initialize error interrupts for this hub. */ hub_error_init(cnode); } - -/* - * This routine is responsible for the setup of all the IRIX hwgraph style - * stuff that's been pulled into linux. It's called by sn_pci_find_bios which - * is called just before the generic Linux PCI layer does its probing (by - * platform_pci_fixup aka sn_pci_fixup). - * - * It is very IMPORTANT that this call is only made by the Master CPU! - * - */ - -void -sgi_master_io_infr_init(void) -{ - extern void irix_io_init(void); - - init_hcl(); /* Sets up the hwgraph compatibility layer with devfs */ - irix_io_init(); /* Do IRIX Compatibility IO Init */ - -#ifdef CONFIG_KDB - { - extern void kdba_io_init(void); - kdba_io_init(); - } -#endif - -} diff --git a/arch/ia64/sn/kernel/sn2/cache.c b/arch/ia64/sn/kernel/sn2/cache.c index a67432ee7f6db..0bd4443e0dad8 100644 --- a/arch/ia64/sn/kernel/sn2/cache.c +++ b/arch/ia64/sn/kernel/sn2/cache.c @@ -26,6 +26,12 @@ void sn_flush_all_caches(long flush_addr, long bytes) { flush_icache_range(flush_addr, flush_addr+bytes); + /* + * The last call may have returned before the caches + * were actually flushed, so we call it again to make + * sure. + */ + flush_icache_range(flush_addr, flush_addr+bytes); mb(); } EXPORT_SYMBOL(sn_flush_all_caches); diff --git a/include/asm-ia64/sn/hcl.h b/include/asm-ia64/sn/hcl.h index a935e7b761ab7..4e571362db74f 100644 --- a/include/asm-ia64/sn/hcl.h +++ b/include/asm-ia64/sn/hcl.h @@ -105,5 +105,6 @@ extern int hwgraph_info_remove_LBL(vertex_hdl_t, char *, arbitrary_info_t *); extern char * vertex_to_name(vertex_hdl_t, char *, uint); extern graph_error_t hwgraph_vertex_unref(vertex_hdl_t); +extern int init_hcl(void); #endif /* _ASM_IA64_SN_HCL_H */ -- 2.53.0