From: Pete P. <pp...@us...> - 2001-11-27 00:29:31
|
Update of /cvsroot/linux-mips/linux/arch/mips/kernel In directory usw-pr-cvs1:/tmp/cvs-serv24629/arch/mips/kernel Modified Files: pci_auto.c Log Message: * Don't update BAR if we've exceeded the PCI IO or MEM (depending on BAR type) window * support non contiguous IO and MEM windows Index: pci_auto.c =================================================================== RCS file: /cvsroot/linux-mips/linux/arch/mips/kernel/pci_auto.c,v retrieving revision 1.3 retrieving revision 1.4 diff -u -d -r1.3 -r1.4 --- pci_auto.c 2001/10/27 21:08:08 1.3 +++ pci_auto.c 2001/11/27 00:29:25 1.4 @@ -86,6 +86,9 @@ EARLY_PCI_OP(write, word, u16) EARLY_PCI_OP(write, dword, u32) +static struct resource *io_resource_inuse; +static struct resource *mem_resource_inuse; + static u32 pciauto_lower_iospc; static u32 pciauto_upper_iospc; @@ -129,6 +132,7 @@ if (!(bar_response & 0xffff0000)) bar_response |= 0xffff0000; +retry: /* Check the BAR type and set our address mask */ if (bar_response & PCI_BASE_ADDRESS_SPACE) { addr_mask = PCI_BASE_ADDRESS_IO_MASK; @@ -146,12 +150,40 @@ DBG(" Mem"); } + /* Calculate requested size */ bar_size = ~(bar_response & addr_mask) + 1; /* Allocate a base address */ bar_value = ((*lower_limit - 1) & ~(bar_size - 1)) + bar_size; + if ((bar_value + bar_size) > *upper_limit) { + if (bar_response & PCI_BASE_ADDRESS_SPACE) { + if (io_resource_inuse->child) { + io_resource_inuse = + io_resource_inuse->child; + pciauto_lower_iospc = + io_resource_inuse->start; + pciauto_upper_iospc = + io_resource_inuse->end + 1; + goto retry; + } + + } else { + if (mem_resource_inuse->child) { + mem_resource_inuse = + mem_resource_inuse->child; + pciauto_lower_memspc = + mem_resource_inuse->start; + pciauto_upper_memspc = + mem_resource_inuse->end + 1; + goto retry; + } + } + DBG(" unavailable -- skipping\n"); + continue; + } + /* Write it out and update our limit */ early_write_config_dword(hose, top_bus, current_bus, pci_devfn, bar, bar_value); @@ -346,13 +378,17 @@ pciauto_assign_resources(int busno, struct pci_channel *hose) { /* setup resource limits */ - pciauto_lower_iospc = hose->io_resource->start; - pciauto_upper_iospc = hose->io_resource->end + 1; - pciauto_lower_memspc = hose->mem_resource->start; - pciauto_upper_memspc = hose->mem_resource->end + 1; + io_resource_inuse = hose->io_resource; + mem_resource_inuse = hose->mem_resource; + + pciauto_lower_iospc = io_resource_inuse->start; + pciauto_upper_iospc = io_resource_inuse->end + 1; + pciauto_lower_memspc = mem_resource_inuse->start; + pciauto_upper_memspc = mem_resource_inuse->end + 1; DBG("Autoconfig PCI channel 0x%p\n", hose); - DBG("Scanning bus %.2x, I/O 0x%.8x, Mem 0x%.8x\n", - busno, pciauto_lower_iospc, pciauto_lower_memspc); + DBG("Scanning bus %.2x, I/O 0x%.8x:0x%.8x, Mem 0x%.8x:0x%.8x\n", + busno, pciauto_lower_iospc, pciauto_upper_iospc, + pciauto_lower_memspc, pciauto_upper_memspc); return pciauto_bus_scan(hose, busno, busno); } |