--- linux/drivers/pcmcia/yenta.c.bridge Sat Aug 10 20:30:35 2002 +++ linux/drivers/pcmcia/yenta.c Mon Aug 12 14:00:38 2002 @@ -706,7 +706,8 @@ static int yenta_suspend(pci_socket_t *s static void yenta_allocate_res(pci_socket_t *socket, int nr, unsigned type) { - struct pci_bus *bus; + struct pci_bus *bus, *parent; + struct pci_dev *bridge; struct resource *root, *res; u32 start, end; u32 align, size, min, max; @@ -739,17 +740,43 @@ static void yenta_allocate_res(pci_socke return; } - align = size = 4*1024*1024; - min = PCIBIOS_MIN_MEM; max = ~0U; if (type & IORESOURCE_IO) { align = 1024; size = 256; min = 0x4000; max = 0xffff; } + else { + align = size = 4*1024*1024; + min = PCIBIOS_MIN_MEM; + max = ~0U; + } - if (allocate_resource(root, res, size, min, max, align, NULL, NULL) < 0) + + /* We check if we are behind an Intel 82801BAM/CAM PCI bridge + which is a transparent bridge for us. We just allocate + resources from its parent. */ + parent = bus->parent; + if (parent != NULL) { + bridge = parent->self; + if (bridge != NULL + && (bridge->class >> 8) == PCI_CLASS_BRIDGE_PCI + && bridge->vendor == PCI_VENDOR_ID_INTEL + && bridge->device >= PCI_DEVICE_ID_INTEL_82801BA_0 + && bridge->device <= PCI_DEVICE_ID_INTEL_82801BA_11) { + res->name = bridge->subordinate->name; + root = pci_find_parent_resource(bridge, res); + } + } + + if (allocate_resource(root, res, size, min, max, align, NULL, NULL) < 0) { + printk (KERN_NOTICE "PCI: CardBus bridge (%04x:%04x, %04x:%04x): Failed to allocate %s resource: %d bytes!\n", + socket->dev->vendor, socket->dev->device, + socket->dev->subsystem_vendor, + socket->dev->subsystem_device, + (type & IORESOURCE_IO) ? "I/O" : "memory", size); return; + } config_writel(socket, offset, res->start); config_writel(socket, offset+4, res->end);