1/* 2 * Low-Level PCI Support for PC 3 * 4 * (c) 1999--2000 Martin Mares <mj@ucw.cz> 5 */ 6 7#include <linux/sched.h> 8#include <linux/pci.h> 9#include <linux/ioport.h> 10#include <linux/init.h> 11#include <linux/dmi.h> 12 13#include <asm/acpi.h> 14#include <asm/segment.h> 15#include <asm/io.h> 16#include <asm/smp.h> 17 18#include "pci.h" 19 20unsigned int pci_probe = PCI_PROBE_BIOS | PCI_PROBE_CONF1 | PCI_PROBE_CONF2 | 21 PCI_PROBE_MMCONF; 22 23static int pci_bf_sort; 24int pci_routeirq; 25int pcibios_last_bus = -1; 26unsigned long pirq_table_addr; 27struct pci_bus *pci_root_bus; 28struct pci_raw_ops *raw_pci_ops; 29 30static int pci_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *value) 31{ 32 return raw_pci_ops->read(0, bus->number, devfn, where, size, value); 33} 34 35static int pci_write(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 value) 36{ 37 return raw_pci_ops->write(0, bus->number, devfn, where, size, value); 38} 39 40struct pci_ops pci_root_ops = { 41 .read = pci_read, 42 .write = pci_write, 43}; 44 45/* 46 * legacy, numa, and acpi all want to call pcibios_scan_root 47 * from their initcalls. This flag prevents that. 48 */ 49int pcibios_scanned; 50 51/* 52 * This interrupt-safe spinlock protects all accesses to PCI 53 * configuration space. 54 */ 55DEFINE_SPINLOCK(pci_config_lock); 56 57/* 58 * Several buggy motherboards address only 16 devices and mirror 59 * them to next 16 IDs. We try to detect this `feature' on all 60 * primary buses (those containing host bridges as they are 61 * expected to be unique) and remove the ghost devices. 62 */ 63 64static void __devinit pcibios_fixup_ghosts(struct pci_bus *b) 65{ 66 struct list_head *ln, *mn; 67 struct pci_dev *d, *e; 68 int mirror = PCI_DEVFN(16,0); 69 int seen_host_bridge = 0; 70 int i; 71 72 DBG("PCI: Scanning for ghost devices on bus %d\n", b->number); 73 list_for_each(ln, &b->devices) { 74 d = pci_dev_b(ln); 75 if ((d->class >> 8) == PCI_CLASS_BRIDGE_HOST) 76 seen_host_bridge++; 77 for (mn=ln->next; mn != &b->devices; mn=mn->next) { 78 e = pci_dev_b(mn); 79 if (e->devfn != d->devfn + mirror || 80 e->vendor != d->vendor || 81 e->device != d->device || 82 e->class != d->class) 83 continue; 84 for(i=0; i<PCI_NUM_RESOURCES; i++) 85 if (e->resource[i].start != d->resource[i].start || 86 e->resource[i].end != d->resource[i].end || 87 e->resource[i].flags != d->resource[i].flags) 88 continue; 89 break; 90 } 91 if (mn == &b->devices) 92 return; 93 } 94 if (!seen_host_bridge) 95 return; 96 printk(KERN_WARNING "PCI: Ignoring ghost devices on bus %02x\n", b->number); 97 98 ln = &b->devices; 99 while (ln->next != &b->devices) { 100 d = pci_dev_b(ln->next); 101 if (d->devfn >= mirror) { 102 list_del(&d->global_list); 103 list_del(&d->bus_list); 104 kfree(d); 105 } else 106 ln = ln->next; 107 } 108} 109 110/* 111 * Called after each bus is probed, but before its children 112 * are examined. 113 */ 114 115void __devinit pcibios_fixup_bus(struct pci_bus *b) 116{ 117 pcibios_fixup_ghosts(b); 118 pci_read_bridge_bases(b); 119} 120 121/* 122 * Only use DMI information to set this if nothing was passed 123 * on the kernel command line (which was parsed earlier). 124 */ 125 126static int __devinit set_bf_sort(struct dmi_system_id *d) 127{ 128 if (pci_bf_sort == pci_bf_sort_default) { 129 pci_bf_sort = pci_dmi_bf; 130 printk(KERN_INFO "PCI: %s detected, enabling pci=bfsort.\n", d->ident); 131 } 132 return 0; 133} 134 135/* 136 * Enable renumbering of PCI bus# ranges to reach all PCI busses (Cardbus) 137 */ 138#ifdef __i386__ 139static int __devinit assign_all_busses(struct dmi_system_id *d) 140{ 141 pci_probe |= PCI_ASSIGN_ALL_BUSSES; 142 printk(KERN_INFO "%s detected: enabling PCI bus# renumbering" 143 " (pci=assign-busses)\n", d->ident); 144 return 0; 145} 146#endif 147 148static struct dmi_system_id __devinitdata pciprobe_dmi_table[] = { 149#ifdef __i386__ 150/* 151 * Laptops which need pci=assign-busses to see Cardbus cards 152 */ 153 { 154 .callback = assign_all_busses, 155 .ident = "Samsung X20 Laptop", 156 .matches = { 157 DMI_MATCH(DMI_SYS_VENDOR, "Samsung Electronics"), 158 DMI_MATCH(DMI_PRODUCT_NAME, "SX20S"), 159 }, 160 }, 161#endif /* __i386__ */ 162 { 163 .callback = set_bf_sort, 164 .ident = "Dell PowerEdge 1950", 165 .matches = { 166 DMI_MATCH(DMI_SYS_VENDOR, "Dell"), 167 DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge 1950"), 168 }, 169 }, 170 { 171 .callback = set_bf_sort, 172 .ident = "Dell PowerEdge 1955", 173 .matches = { 174 DMI_MATCH(DMI_SYS_VENDOR, "Dell"), 175 DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge 1955"), 176 }, 177 }, 178 { 179 .callback = set_bf_sort, 180 .ident = "Dell PowerEdge 2900", 181 .matches = { 182 DMI_MATCH(DMI_SYS_VENDOR, "Dell"), 183 DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge 2900"), 184 }, 185 }, 186 { 187 .callback = set_bf_sort, 188 .ident = "Dell PowerEdge 2950", 189 .matches = { 190 DMI_MATCH(DMI_SYS_VENDOR, "Dell"), 191 DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge 2950"), 192 }, 193 }, 194 { 195 .callback = set_bf_sort, 196 .ident = "Dell PowerEdge R900", 197 .matches = { 198 DMI_MATCH(DMI_SYS_VENDOR, "Dell"), 199 DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge R900"), 200 }, 201 }, 202 { 203 .callback = set_bf_sort, 204 .ident = "HP ProLiant BL20p G3", 205 .matches = { 206 DMI_MATCH(DMI_SYS_VENDOR, "HP"), 207 DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL20p G3"), 208 }, 209 }, 210 { 211 .callback = set_bf_sort, 212 .ident = "HP ProLiant BL20p G4", 213 .matches = { 214 DMI_MATCH(DMI_SYS_VENDOR, "HP"), 215 DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL20p G4"), 216 }, 217 }, 218 { 219 .callback = set_bf_sort, 220 .ident = "HP ProLiant BL30p G1", 221 .matches = { 222 DMI_MATCH(DMI_SYS_VENDOR, "HP"), 223 DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL30p G1"), 224 }, 225 }, 226 { 227 .callback = set_bf_sort, 228 .ident = "HP ProLiant BL25p G1", 229 .matches = { 230 DMI_MATCH(DMI_SYS_VENDOR, "HP"), 231 DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL25p G1"), 232 }, 233 }, 234 { 235 .callback = set_bf_sort, 236 .ident = "HP ProLiant BL35p G1", 237 .matches = { 238 DMI_MATCH(DMI_SYS_VENDOR, "HP"), 239 DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL35p G1"), 240 }, 241 }, 242 { 243 .callback = set_bf_sort, 244 .ident = "HP ProLiant BL45p G1", 245 .matches = { 246 DMI_MATCH(DMI_SYS_VENDOR, "HP"), 247 DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL45p G1"), 248 }, 249 }, 250 { 251 .callback = set_bf_sort, 252 .ident = "HP ProLiant BL45p G2", 253 .matches = { 254 DMI_MATCH(DMI_SYS_VENDOR, "HP"), 255 DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL45p G2"), 256 }, 257 }, 258 { 259 .callback = set_bf_sort, 260 .ident = "HP ProLiant BL460c G1", 261 .matches = { 262 DMI_MATCH(DMI_SYS_VENDOR, "HP"), 263 DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL460c G1"), 264 }, 265 }, 266 { 267 .callback = set_bf_sort, 268 .ident = "HP ProLiant BL465c G1", 269 .matches = { 270 DMI_MATCH(DMI_SYS_VENDOR, "HP"), 271 DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL465c G1"), 272 }, 273 }, 274 { 275 .callback = set_bf_sort, 276 .ident = "HP ProLiant BL480c G1", 277 .matches = { 278 DMI_MATCH(DMI_SYS_VENDOR, "HP"), 279 DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL480c G1"), 280 }, 281 }, 282 { 283 .callback = set_bf_sort, 284 .ident = "HP ProLiant BL685c G1", 285 .matches = { 286 DMI_MATCH(DMI_SYS_VENDOR, "HP"), 287 DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL685c G1"), 288 }, 289 }, 290 {} 291}; 292 293struct pci_bus * __devinit pcibios_scan_root(int busnum) 294{ 295 struct pci_bus *bus = NULL; 296 297 dmi_check_system(pciprobe_dmi_table); 298 299 while ((bus = pci_find_next_bus(bus)) != NULL) { 300 if (bus->number == busnum) { 301 /* Already scanned */ 302 return bus; 303 } 304 } 305 306 printk(KERN_DEBUG "PCI: Probing PCI hardware (bus %02x)\n", busnum); 307 308 return pci_scan_bus_parented(NULL, busnum, &pci_root_ops, NULL); 309} 310 311extern u8 pci_cache_line_size; 312 313static int __init pcibios_init(void) 314{ 315 struct cpuinfo_x86 *c = &boot_cpu_data; 316 317 if (!raw_pci_ops) { 318 printk(KERN_WARNING "PCI: System does not support PCI\n"); 319 return 0; 320 } 321 322 /* 323 * Assume PCI cacheline size of 32 bytes for all x86s except K7/K8 324 * and P4. It's also good for 386/486s (which actually have 16) 325 * as quite a few PCI devices do not support smaller values. 326 */ 327 pci_cache_line_size = 32 >> 2; 328 if (c->x86 >= 6 && c->x86_vendor == X86_VENDOR_AMD) 329 pci_cache_line_size = 64 >> 2; /* K7 & K8 */ 330 else if (c->x86 > 6 && c->x86_vendor == X86_VENDOR_INTEL) 331 pci_cache_line_size = 128 >> 2; /* P4 */ 332 333 pcibios_resource_survey(); 334 335 if (pci_bf_sort >= pci_force_bf) 336 pci_sort_breadthfirst(); 337#ifdef CONFIG_PCI_BIOS 338 if ((pci_probe & PCI_BIOS_SORT) && !(pci_probe & PCI_NO_SORT)) 339 pcibios_sort(); 340#endif 341 return 0; 342} 343 344subsys_initcall(pcibios_init); 345 346char * __devinit pcibios_setup(char *str) 347{ 348 if (!strcmp(str, "off")) { 349 pci_probe = 0; 350 return NULL; 351 } else if (!strcmp(str, "bfsort")) { 352 pci_bf_sort = pci_force_bf; 353 return NULL; 354 } else if (!strcmp(str, "nobfsort")) { 355 pci_bf_sort = pci_force_nobf; 356 return NULL; 357 } 358#ifdef CONFIG_PCI_BIOS 359 else if (!strcmp(str, "bios")) { 360 pci_probe = PCI_PROBE_BIOS; 361 return NULL; 362 } else if (!strcmp(str, "nobios")) { 363 pci_probe &= ~PCI_PROBE_BIOS; 364 return NULL; 365 } else if (!strcmp(str, "nosort")) { 366 pci_probe |= PCI_NO_SORT; 367 return NULL; 368 } else if (!strcmp(str, "biosirq")) { 369 pci_probe |= PCI_BIOS_IRQ_SCAN; 370 return NULL; 371 } else if (!strncmp(str, "pirqaddr=", 9)) { 372 pirq_table_addr = simple_strtoul(str+9, NULL, 0); 373 return NULL; 374 } 375#endif 376#ifdef CONFIG_PCI_DIRECT 377 else if (!strcmp(str, "conf1")) { 378 pci_probe = PCI_PROBE_CONF1 | PCI_NO_CHECKS; 379 return NULL; 380 } 381 else if (!strcmp(str, "conf2")) { 382 pci_probe = PCI_PROBE_CONF2 | PCI_NO_CHECKS; 383 return NULL; 384 } 385#endif 386#ifdef CONFIG_PCI_MMCONFIG 387 else if (!strcmp(str, "nommconf")) { 388 pci_probe &= ~PCI_PROBE_MMCONF; 389 return NULL; 390 } 391#endif 392 else if (!strcmp(str, "noacpi")) { 393 acpi_noirq_set(); 394 return NULL; 395 } 396 else if (!strcmp(str, "noearly")) { 397 pci_probe |= PCI_PROBE_NOEARLY; 398 return NULL; 399 } 400#ifndef CONFIG_X86_VISWS 401 else if (!strcmp(str, "usepirqmask")) { 402 pci_probe |= PCI_USE_PIRQ_MASK; 403 return NULL; 404 } else if (!strncmp(str, "irqmask=", 8)) { 405 pcibios_irq_mask = simple_strtol(str+8, NULL, 0); 406 return NULL; 407 } else if (!strncmp(str, "lastbus=", 8)) { 408 pcibios_last_bus = simple_strtol(str+8, NULL, 0); 409 return NULL; 410 } 411#endif 412 else if (!strcmp(str, "rom")) { 413 pci_probe |= PCI_ASSIGN_ROMS; 414 return NULL; 415 } else if (!strcmp(str, "assign-busses")) { 416 pci_probe |= PCI_ASSIGN_ALL_BUSSES; 417 return NULL; 418 } else if (!strcmp(str, "routeirq")) { 419 pci_routeirq = 1; 420 return NULL; 421 } 422 return str; 423} 424 425unsigned int pcibios_assign_all_busses(void) 426{ 427 return (pci_probe & PCI_ASSIGN_ALL_BUSSES) ? 1 : 0; 428} 429 430int pcibios_enable_device(struct pci_dev *dev, int mask) 431{ 432 int err; 433 434 if ((err = pcibios_enable_resources(dev, mask)) < 0) 435 return err; 436 437 if (!dev->msi_enabled) 438 return pcibios_enable_irq(dev); 439 return 0; 440} 441 442void pcibios_disable_device (struct pci_dev *dev) 443{ 444 if (!dev->msi_enabled && pcibios_disable_irq) 445 pcibios_disable_irq(dev); 446} 447