diff -urN 2.3.22/arch/alpha/kernel/core_mcpcia.c 2.3.22-alphapci/arch/alpha/kernel/core_mcpcia.c --- 2.3.22/arch/alpha/kernel/core_mcpcia.c Tue Oct 12 02:40:34 1999 +++ 2.3.22-alphapci/arch/alpha/kernel/core_mcpcia.c Thu Oct 21 03:55:30 1999 @@ -205,7 +205,7 @@ static int mcpcia_read_config_byte(struct pci_dev *dev, int where, u8 *value) { - struct pci_controler *hose = dev->sysdata ? : probing_hose; + struct pci_controler *hose = dev->sysdata; unsigned long addr, w; unsigned char type1; @@ -221,7 +221,7 @@ static int mcpcia_read_config_word(struct pci_dev *dev, int where, u16 *value) { - struct pci_controler *hose = dev->sysdata ? : probing_hose; + struct pci_controler *hose = dev->sysdata; unsigned long addr, w; unsigned char type1; @@ -237,7 +237,7 @@ static int mcpcia_read_config_dword(struct pci_dev *dev, int where, u32 *value) { - struct pci_controler *hose = dev->sysdata ? : probing_hose; + struct pci_controler *hose = dev->sysdata; unsigned long addr; unsigned char type1; @@ -252,7 +252,7 @@ static int mcpcia_write_config(struct pci_dev *dev, int where, u32 value, long mask) { - struct pci_controler *hose = dev->sysdata ? : probing_hose; + struct pci_controler *hose = dev->sysdata; unsigned long addr; unsigned char type1; diff -urN 2.3.22/arch/alpha/kernel/core_tsunami.c 2.3.22-alphapci/arch/alpha/kernel/core_tsunami.c --- 2.3.22/arch/alpha/kernel/core_tsunami.c Tue Oct 12 02:40:34 1999 +++ 2.3.22-alphapci/arch/alpha/kernel/core_tsunami.c Thu Oct 21 17:27:37 1999 @@ -84,7 +84,7 @@ mk_conf_addr(struct pci_dev *dev, int where, unsigned long *pci_addr, unsigned char *type1) { - struct pci_controler *hose = dev->sysdata ? : probing_hose; + struct pci_controler *hose = dev->sysdata; unsigned long addr; u8 bus = dev->bus->number; u8 device_fn = dev->devfn; @@ -154,6 +154,7 @@ return PCIBIOS_DEVICE_NOT_FOUND; __kernel_stb(value, *(vucp)addr); + mb(); return PCIBIOS_SUCCESSFUL; } @@ -167,6 +168,7 @@ return PCIBIOS_DEVICE_NOT_FOUND; __kernel_stw(value, *(vusp)addr); + mb(); return PCIBIOS_SUCCESSFUL; } @@ -180,6 +182,7 @@ return PCIBIOS_DEVICE_NOT_FOUND; *(vuip)addr = value; + mb(); return PCIBIOS_SUCCESSFUL; } @@ -259,15 +262,22 @@ hose->index = index; hose->io_space->start = TSUNAMI_IO(index) - TSUNAMI_IO_BIAS; - hose->io_space->end = hose->io_space->start + 0xffff; + hose->io_space->end = hose->io_space->start + TSUNAMI_IO_SPACE; hose->io_space->name = pci_io_names[index]; + hose->io_space->flags = IORESOURCE_IO; hose->mem_space->start = TSUNAMI_MEM(index) - TSUNAMI_MEM_BIAS; + /* the IOMEM address space is larger than 32bit but most pci + cars doesn't support 64bit address space so we stick with + 32bit here (see the TSUNAMI_MEM_SPACE define). */ hose->mem_space->end = hose->mem_space->start + 0xffffffff; hose->mem_space->name = pci_mem_names[index]; + hose->mem_space->flags = IORESOURCE_MEM; - request_resource(&ioport_resource, hose->io_space); - request_resource(&iomem_resource, hose->mem_space); + if (request_resource(&ioport_resource, hose->io_space) < 0) + printk(KERN_ERR "failed to request IO on hose %d", index); + if (request_resource(&iomem_resource, hose->mem_space) < 0) + printk(KERN_ERR "failed to request IOMEM on hose %d", index); /* * Set up the PCI->physical memory translation windows. diff -urN 2.3.22/arch/alpha/kernel/pci.c 2.3.22-alphapci/arch/alpha/kernel/pci.c --- 2.3.22/arch/alpha/kernel/pci.c Tue Oct 12 02:40:34 1999 +++ 2.3.22-alphapci/arch/alpha/kernel/pci.c Fri Oct 22 21:31:50 1999 @@ -10,6 +10,7 @@ #include #include #include +#include #include #include "proto.h" @@ -36,7 +37,6 @@ */ struct pci_controler *hose_head, **hose_tail = &hose_head; -struct pci_controler *probing_hose; /* * Quirks. @@ -62,24 +62,93 @@ { 0 } }; +#define MAX(val1, val2) ((val1) > (val2) ? (val1) : (val2)) +#define ALIGN(val,align) (((val) + ((align) - 1)) & ~((align) - 1)) +#define KB 1024 +#define MB (1024*KB) +#define GB (1024*MB) +unsigned long resource_fixup(struct pci_dev * dev, struct resource * res, + unsigned long start, unsigned long size) +{ + unsigned long alignto; + + if (res->flags & IORESOURCE_IO) + { + /* + * Aligning to 0x800 rather than the minimum base of + * 0x400 is an attempt to avoid having devices in + * any 0x?C?? range, which is where the de4x5 driver + * probes for EISA cards. + * + * Adaptecs, especially, resent such intrusions. + */ + alignto = MAX(0x800, size); + start = ALIGN(start, alignto); + } + else if (res->flags & IORESOURCE_MEM) + { + /* + * The following holds at least for the Low Cost + * Alpha implementation of the PCI interface: + * + * In sparse memory address space, the first + * octant (16MB) of every 128MB segment is + * aliased to the very first 16 MB of the + * address space (i.e., it aliases the ISA + * memory address space). Thus, we try to + * avoid allocating PCI devices in that range. + * Can be allocated in 2nd-7th octant only. + * Devices that need more than 112MB of + * address space must be accessed through + * dense memory space only! + */ + /* align to multiple of size of minimum base */ + alignto = MAX(0x1000, size); + start = ALIGN(start, alignto); + if (size > 7 * 16*MB) + printk(KERN_WARNING "PCI: dev %s " + "requests 0x%ld bytes of contiguous" + " address space---don't use sparse" + " memory accesses on this device!!\n", + dev->name, size); + else + { + if (((start / (16*MB)) & 0x7) == 0) { + start &= ~(128*MB - 1); + start += 16*MB; + start = ALIGN(start, alignto); + } + if (start/(128*MB) != (start + size)/(128*MB)) { + start &= ~(128*MB - 1); + start += (128 + 16)*MB; + start = ALIGN(start, alignto); + } + } + } + + return start; +} +#undef MAX +#undef ALIGN +#undef KB +#undef MB +#undef GB /* * Pre-layout host-independant device initialization. */ static void __init -pcibios_assign_special(void) +pcibios_assign_special(struct pci_dev * dev) { - struct pci_dev *dev; - int i; - /* The first three resources of an IDE controler are often magic, so leave them unchanged. This is true, for instance, of the Contaq 82C693 as seen on SX164 and DP264. */ - for (dev = pci_devices; dev; dev = dev->next) { - if (dev->class >> 8 != PCI_CLASS_STORAGE_IDE) - continue; + if (dev->class >> 8 == PCI_CLASS_STORAGE_IDE) + { + int i; + /* Resource 1 of IDE controller is the address of HD_CMD register which actually occupies a single byte (0x3f6 for ide0) in reported 0x3f4-3f7 range. We have to fix @@ -87,10 +156,9 @@ controller. */ dev->resource[1].start += 2; dev->resource[1].end = dev->resource[1].start; - for (i = 0; i < PCI_NUM_RESOURCES; i++) { - if (dev->resource[i].flags) + for (i = 0; i < PCI_NUM_RESOURCES; i++) + if (dev->resource[i].flags && dev->resource[i].start) pci_claim_resource(dev, i); - } } } @@ -110,31 +178,63 @@ } void __init +pcibios_fixup_resource(struct resource *res, struct resource *root) +{ + res->start += root->start; + res->end += root->start; +} + +void __init +pcibios_fixup_device_resources(struct pci_dev *dev, struct pci_bus *bus) +{ + /* Update device resources. */ + + int i; + + for (i = 0; i < PCI_NUM_RESOURCES; i++) { + if (!dev->resource[i].start) + continue; + if (dev->resource[i].flags & IORESOURCE_IO) + pcibios_fixup_resource(&dev->resource[i], + bus->resource[0]); + else if (dev->resource[i].flags & IORESOURCE_MEM) + pcibios_fixup_resource(&dev->resource[i], + bus->resource[1]); + } + pcibios_assign_special(dev); +} + +void __init pcibios_fixup_bus(struct pci_bus *bus) { /* Propogate hose info into the subordinate devices. */ - struct pci_controler *hose = probing_hose; + struct pci_controler *hose = (struct pci_controler *) bus->sysdata; struct pci_dev *dev; bus->resource[0] = hose->io_space; bus->resource[1] = hose->mem_space; for (dev = bus->devices; dev; dev = dev->sibling) - dev->sysdata = hose; + if ((dev->class >> 8) != PCI_CLASS_BRIDGE_PCI) + pcibios_fixup_device_resources(dev, bus); } void __init pcibios_update_resource(struct pci_dev *dev, struct resource *root, struct resource *res, int resource) { - unsigned long where, size; - u32 reg; + int where; + u32 reg; - where = PCI_BASE_ADDRESS_0 + (resource * 4); - size = res->end - res->start; - pci_read_config_dword(dev, where, ®); - reg = (reg & size) | (((u32)(res->start - root->start)) & ~size); - pci_write_config_dword(dev, where, reg); + where = PCI_BASE_ADDRESS_0 + (resource * 4); + reg = (res->start - root->start) | (res->flags & 0xf); + pci_write_config_dword(dev, where, reg); + if ((res->flags & (PCI_BASE_ADDRESS_SPACE | PCI_BASE_ADDRESS_MEM_TYPE_MASK)) + == (PCI_BASE_ADDRESS_SPACE_MEMORY | PCI_BASE_ADDRESS_MEM_TYPE_64)) + { + pci_write_config_dword(dev, where+4, 0); + printk(KERN_WARNING "PCI: dev %s type 64-bit\n", dev->name); + } /* ??? FIXME -- record old value for shutdown. */ } @@ -170,6 +270,15 @@ } void __init +pcibios_fixup_pbus_ranges(struct pci_bus * bus, struct pbus_set_ranges_data * ranges) +{ + ranges->io_start -= bus->resource[0]->start; + ranges->io_end -= bus->resource[0]->start; + ranges->mem_start -= bus->resource[1]->start; + ranges->mem_end -= bus->resource[1]->start; +} + +void __init common_init_pci(void) { struct pci_controler *hose; @@ -180,15 +289,12 @@ for (next_busno = 0, hose = hose_head; hose; hose = hose->next) { hose->first_busno = next_busno; hose->last_busno = 0xff; - probing_hose = hose; bus = pci_scan_bus(next_busno, alpha_mv.pci_ops, hose); hose->bus = bus; next_busno = hose->last_busno = bus->subordinate; next_busno += 1; } - probing_hose = NULL; - pcibios_assign_special(); pci_assign_unassigned_resources(alpha_mv.min_io_address, alpha_mv.min_mem_address); pci_fixup_irqs(alpha_mv.pci_swizzle, alpha_mv.pci_map_irq); diff -urN 2.3.22/arch/alpha/kernel/pci_impl.h 2.3.22-alphapci/arch/alpha/kernel/pci_impl.h --- 2.3.22/arch/alpha/kernel/pci_impl.h Tue Sep 14 14:35:30 1999 +++ 2.3.22-alphapci/arch/alpha/kernel/pci_impl.h Thu Oct 21 03:54:44 1999 @@ -125,7 +125,6 @@ /* The hose list. */ extern struct pci_controler *hose_head, **hose_tail; -extern struct pci_controler *probing_hose; extern void common_init_pci(void); extern u8 common_swizzle(struct pci_dev *, u8 *); diff -urN 2.3.22/arch/i386/kernel/pci-i386.c 2.3.22-alphapci/arch/i386/kernel/pci-i386.c --- 2.3.22/arch/i386/kernel/pci-i386.c Tue Oct 12 02:40:34 1999 +++ 2.3.22-alphapci/arch/i386/kernel/pci-i386.c Fri Oct 22 21:47:14 1999 @@ -122,12 +122,12 @@ printk(KERN_ERR "PCI: I/O Region %s/%d too large (%ld bytes)\n", dev->slot_name, i, size); return -EFBIG; } - if (allocate_resource(pr, r, size, 0x1000, ~0, 1024)) { + if (allocate_resource(pr, r, size, 0x1000, ~0, 1024, dev)) { printk(KERN_ERR "PCI: Allocation of I/O region %s/%d (%ld bytes) failed\n", dev->slot_name, i, size); return -EBUSY; } } else { - if (allocate_resource(pr, r, size, 0x10000000, ~0, size)) { + if (allocate_resource(pr, r, size, 0x10000000, ~0, size, dev)) { printk(KERN_ERR "PCI: Allocation of memory region %s/%d (%ld bytes) failed\n", dev->slot_name, i, size); return -EBUSY; } @@ -309,4 +309,10 @@ pcibios_allocate_resources(0); pcibios_allocate_resources(1); pcibios_assign_resources(); +} + +unsigned long resource_fixup(struct pci_dev * dev, struct resource * res, + unsigned long start, unsigned long size) +{ + return start; } diff -urN 2.3.22/drivers/pci/pci.c 2.3.22-alphapci/drivers/pci/pci.c --- 2.3.22/drivers/pci/pci.c Tue Oct 12 02:40:34 1999 +++ 2.3.22-alphapci/drivers/pci/pci.c Thu Oct 21 03:52:13 1999 @@ -379,6 +379,7 @@ dev = dev_cache; memset(dev, 0, sizeof(*dev)); dev->bus = bus; + dev->sysdata = bus->sysdata; dev->devfn = devfn; if (pci_read_config_byte(dev, PCI_HEADER_TYPE, &hdr_type)) @@ -498,6 +499,7 @@ child->self = dev; child->parent = bus; child->ops = bus->ops; + child->sysdata = bus->sysdata; /* * Set up the primary, secondary and subordinate diff -urN 2.3.22/drivers/pci/setup.c 2.3.22-alphapci/drivers/pci/setup.c --- 2.3.22/drivers/pci/setup.c Tue Oct 12 02:40:34 1999 +++ 2.3.22-alphapci/drivers/pci/setup.c Fri Oct 22 21:50:59 1999 @@ -33,15 +33,8 @@ int err; err = -EINVAL; - if (root != NULL) { - /* If `dev' is on a secondary pci bus, `root' may not be - at the origin. In that case, adjust the resource into - range. */ - res->start += root->start; - res->end += root->start; - + if (root != NULL) err = request_resource(root, res); - } if (err) { printk(KERN_ERR "PCI: Address space collision on region %d " "of device %s\n", resource, dev->name); @@ -89,7 +82,7 @@ DBGC((" for root[%lx:%lx] min[%lx] size[%lx]\n", root->start, root->end, min, size)); - if (allocate_resource(root, res, size, min, -1, size) < 0) { + if (allocate_resource(root, res, size, min, -1, size, dev) < 0) { printk(KERN_ERR "PCI: Failed to allocate resource %d for %s\n", i, dev->name); @@ -148,13 +141,6 @@ pdev_assign_unassigned_resources(dev, min_io, min_mem); } -struct pbus_set_ranges_data -{ - int found_vga; - unsigned int io_start, io_end; - unsigned int mem_start, mem_end; -}; - #define ROUND_UP(x, a) (((x) + (a) - 1) & ~((a) - 1)) #define ROUND_DOWN(x, a) ((x) & ~((a) - 1)) @@ -166,7 +152,7 @@ struct pci_dev *dev; inner.found_vga = 0; - inner.mem_start = inner.io_start = ~0; + inner.mem_start = inner.io_start = ~0UL; inner.mem_end = inner.io_end = 0; /* Collect information about how our direct children are layed out. */ @@ -200,6 +186,8 @@ inner.mem_start = ROUND_DOWN(inner.mem_start, 1*1024*1024); inner.mem_end = ROUND_UP(inner.mem_end, 1*1024*1024); + + pcibios_fixup_pbus_ranges(bus, &inner); /* Configure the bridge, if possible. */ if (bus->self) { diff -urN 2.3.22/drivers/video/tgafb.c 2.3.22-alphapci/drivers/video/tgafb.c --- 2.3.22/drivers/video/tgafb.c Tue Sep 14 14:35:13 1999 +++ 2.3.22-alphapci/drivers/video/tgafb.c Tue Oct 19 19:00:13 1999 @@ -937,7 +937,7 @@ static void tgafb_set_disp(const void *fb_par, struct display *disp, struct fb_info_gen *info) { - disp->screen_base = ioremap(fb_info.tga_fb_base); + disp->screen_base = ioremap(fb_info.tga_fb_base, 0); switch (fb_info.tga_type) { #ifdef FBCON_HAS_CFB8 case 0: /* 8-plane */ diff -urN 2.3.22/include/asm-alpha/core_tsunami.h 2.3.22-alphapci/include/asm-alpha/core_tsunami.h --- 2.3.22/include/asm-alpha/core_tsunami.h Tue Oct 12 18:16:42 1999 +++ 2.3.22-alphapci/include/asm-alpha/core_tsunami.h Thu Oct 21 17:25:02 1999 @@ -291,6 +291,9 @@ #define TSUNAMI_IO_BIAS TSUNAMI_IO(0) #define TSUNAMI_MEM_BIAS TSUNAMI_MEM(0) +/* The IO address space is larger than 0xffff */ +#define TSUNAMI_IO_SPACE (TSUNAMI_CONF(0) - TSUNAMI_IO(0)) +#define TSUNAMI_MEM_SPACE (_TSUNAMI_IACK_SC(0) - TSUNAMI_MEM(0)) /* * Data structure for handling TSUNAMI machine checks: diff -urN 2.3.22/include/asm-alpha/pgtable.h 2.3.22-alphapci/include/asm-alpha/pgtable.h --- 2.3.22/include/asm-alpha/pgtable.h Tue Oct 19 03:16:25 1999 +++ 2.3.22-alphapci/include/asm-alpha/pgtable.h Fri Oct 22 21:25:54 1999 @@ -622,6 +622,6 @@ #define kern_addr_valid(addr) (1) #define io_remap_page_range(start, busaddr, size, prot) \ - remap_page_range(start, virt_to_phys(__ioremap(busaddr)), size, prot) + remap_page_range(start, virt_to_phys(__ioremap(busaddr), 0), size, prot) #endif /* _ALPHA_PGTABLE_H */ diff -urN 2.3.22/include/linux/ioport.h 2.3.22-alphapci/include/linux/ioport.h --- 2.3.22/include/linux/ioport.h Tue Sep 14 14:35:32 1999 +++ 2.3.22-alphapci/include/linux/ioport.h Fri Oct 22 21:25:50 1999 @@ -80,10 +80,11 @@ extern int request_resource(struct resource *root, struct resource *new); extern int release_resource(struct resource *new); +struct pci_dev; extern int allocate_resource(struct resource *root, struct resource *new, unsigned long size, unsigned long min, unsigned long max, - unsigned long align); + unsigned long align, struct pci_dev *); /* Convenience shorthand with allocation */ #define request_region(start,n,name) __request_region(&ioport_resource, (start), (n), (name)) @@ -106,5 +107,8 @@ #define HAVE_AUTOIRQ extern void autoirq_setup(int waittime); extern int autoirq_report(int waittime); + +extern unsigned long resource_fixup(struct pci_dev *, struct resource *, + unsigned long, unsigned long); #endif /* _LINUX_IOPORT_H */ diff -urN 2.3.22/include/linux/pci.h 2.3.22-alphapci/include/linux/pci.h --- 2.3.22/include/linux/pci.h Fri Oct 22 17:06:36 1999 +++ 2.3.22-alphapci/include/linux/pci.h Fri Oct 22 21:41:26 1999 @@ -404,8 +404,16 @@ int (*write_dword)(struct pci_dev *, int where, u32 val); }; +struct pbus_set_ranges_data +{ + int found_vga; + unsigned long io_start, io_end; + unsigned long mem_start, mem_end; +}; + void pcibios_init(void); void pcibios_fixup_bus(struct pci_bus *); +void pcibios_fixup_pbus_ranges(struct pci_bus *, struct pbus_set_ranges_data *); char *pcibios_setup (char *str); void pcibios_update_resource(struct pci_dev *, struct resource *, diff -urN 2.3.22/kernel/resource.c 2.3.22-alphapci/kernel/resource.c --- 2.3.22/kernel/resource.c Tue Sep 14 14:35:58 1999 +++ 2.3.22-alphapci/kernel/resource.c Fri Oct 22 21:25:06 1999 @@ -126,7 +126,7 @@ static int find_resource(struct resource *root, struct resource *new, unsigned long size, unsigned long min, unsigned long max, - unsigned long align) + unsigned long align, struct pci_dev * dev) { struct resource *this = root->child; unsigned long start, end; @@ -142,6 +142,7 @@ if (end > max) end = max; start = (start + align - 1) & ~(align - 1); + start = resource_fixup (dev, new, start, size); if (start < end && end - start + 1 >= size) { new->start = start; new->end = start + size - 1; @@ -161,12 +162,12 @@ int allocate_resource(struct resource *root, struct resource *new, unsigned long size, unsigned long min, unsigned long max, - unsigned long align) + unsigned long align, struct pci_dev * dev) { int err; write_lock(&resource_lock); - err = find_resource(root, new, size, min, max, align); + err = find_resource(root, new, size, min, max, align, dev); if (err >= 0 && __request_resource(root, new)) err = -EBUSY; write_unlock(&resource_lock);