Commit 7bd1c365fd124624191d49dcc1eb9759d6017ec3
Committed by
Jesse Barnes
1 parent
549e15611b
Exists in
master
and in
4 other branches
x86/PCI: Add option to not assign BAR's if not already assigned
The Linux kernel assigns BARs that a BIOS did not assign, most likely to handle broken BIOSes that didn't enumerate the devices correctly. On UV the BIOS purposely doesn't assign I/O BARs for certain devices/ drivers we know don't use them (examples, LSI SAS, Qlogic FC, ...). We purposely don't assign these I/O BARs because I/O Space is a very limited resource. There is only 64k of I/O Space, and in a PCIe topology that space gets divided up into 4k chucks (this is due to the fact that a pci-to-pci bridge's I/O decoder is aligned at 4k)... Thus a system can have at most 16 cards with I/O BARs: (64k / 4k = 16) SGI needs to scale to >16 devices with I/O BARs. So by not assigning I/O BARs on devices we know don't use them, we can do that (iff the kernel doesn't go and assign these BARs that the BIOS purposely didn't assign). This patch will not assign a resource to a device BAR if that BAR was not assigned by the BIOS, and the kernel cmdline option 'pci=nobar' was specified. This patch is closely modeled after the 'pci=norom' option that currently exists in the tree. Signed-off-by: Mike Habeck <habeck@sgi.com> Signed-off-by: Mike Travis <travis@sgi.com> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Showing 3 changed files with 23 additions and 0 deletions Side-by-side Diff
Documentation/kernel-parameters.txt
... | ... | @@ -1970,6 +1970,8 @@ |
1970 | 1970 | norom [X86] Do not assign address space to |
1971 | 1971 | expansion ROMs that do not already have |
1972 | 1972 | BIOS assigned address ranges. |
1973 | + nobar [X86] Do not assign address space to the | |
1974 | + BARs that weren't assigned by the BIOS. | |
1973 | 1975 | irqmask=0xMMMM [X86] Set a bit mask of IRQs allowed to be |
1974 | 1976 | assigned automatically to PCI devices. You can |
1975 | 1977 | make the kernel exclude IRQs of your ISA cards |
arch/x86/include/asm/pci_x86.h
arch/x86/pci/common.c
... | ... | @@ -125,7 +125,24 @@ |
125 | 125 | static void __devinit pcibios_fixup_device_resources(struct pci_dev *dev) |
126 | 126 | { |
127 | 127 | struct resource *rom_r = &dev->resource[PCI_ROM_RESOURCE]; |
128 | + struct resource *bar_r; | |
129 | + int bar; | |
128 | 130 | |
131 | + if (pci_probe & PCI_NOASSIGN_BARS) { | |
132 | + /* | |
133 | + * If the BIOS did not assign the BAR, zero out the | |
134 | + * resource so the kernel doesn't attmept to assign | |
135 | + * it later on in pci_assign_unassigned_resources | |
136 | + */ | |
137 | + for (bar = 0; bar <= PCI_STD_RESOURCE_END; bar++) { | |
138 | + bar_r = &dev->resource[bar]; | |
139 | + if (bar_r->start == 0 && bar_r->end != 0) { | |
140 | + bar_r->flags = 0; | |
141 | + bar_r->end = 0; | |
142 | + } | |
143 | + } | |
144 | + } | |
145 | + | |
129 | 146 | if (pci_probe & PCI_NOASSIGN_ROMS) { |
130 | 147 | if (rom_r->parent) |
131 | 148 | return; |
... | ... | @@ -508,6 +525,9 @@ |
508 | 525 | return NULL; |
509 | 526 | } else if (!strcmp(str, "norom")) { |
510 | 527 | pci_probe |= PCI_NOASSIGN_ROMS; |
528 | + return NULL; | |
529 | + } else if (!strcmp(str, "nobar")) { | |
530 | + pci_probe |= PCI_NOASSIGN_BARS; | |
511 | 531 | return NULL; |
512 | 532 | } else if (!strcmp(str, "assign-busses")) { |
513 | 533 | pci_probe |= PCI_ASSIGN_ALL_BUSSES; |