|
|
1.1 ! root 1: /*====================================================================== ! 2: ! 3: Kernel fixups for PCI device support ! 4: ! 5: pci_fixup.c 1.33 2002/10/12 19:02:59 ! 6: ! 7: PCI bus fixups: various bits of code that don't really belong in ! 8: the PCMCIA subsystem, but may or may not be available from the ! 9: kernel, depending on kernel version. The basic idea is to make ! 10: 2.0.* and 2.2.* kernels look like they have the 2.3.* features. ! 11: ! 12: ======================================================================*/ ! 13: ! 14: #define __NO_VERSION__ ! 15: ! 16: #include <linux/module.h> ! 17: #include <linux/kernel.h> ! 18: #include <linux/slab.h> ! 19: #include <linux/pci.h> ! 20: #include <asm/io.h> ! 21: ! 22: /* We use these for setting up CardBus bridges */ ! 23: #include "yenta.h" ! 24: #include "i82365.h" ! 25: ! 26: #define VERSION KERNEL_VERSION ! 27: #if (LINUX_VERSION_CODE < VERSION(2,3,24)) ! 28: ! 29: /* Default memory base addresses for CardBus controllers */ ! 30: static u_int cb_mem_base[] = { 0x0, 0x68000000, 0xf8000000 }; ! 31: MODULE_PARM(cb_mem_base, "i"); ! 32: ! 33: /* PCI bus number overrides for CardBus controllers */ ! 34: #define INT_MODULE_PARM(n, v) static int n = v; MODULE_PARM(n, "i") ! 35: INT_MODULE_PARM(cb_bus_base, 0); ! 36: INT_MODULE_PARM(cb_bus_step, 2); ! 37: INT_MODULE_PARM(cb_pci_irq, 0); ! 38: ! 39: #endif ! 40: ! 41: /* (exported) mask of interrupts reserved for PCI devices */ ! 42: u32 pci_irq_mask = 0; ! 43: ! 44: /*====================================================================== ! 45: ! 46: Basic PCI services missing from older kernels: device lookup, etc ! 47: ! 48: ======================================================================*/ ! 49: ! 50: #if (LINUX_VERSION_CODE < VERSION(2,1,0)) ! 51: #ifndef MACH ! 52: /* Already defined in drivers/pci/pci.c. */ ! 53: struct pci_dev *pci_devices = NULL; ! 54: #endif ! 55: struct pci_bus pci_root = { ! 56: parent: NULL, ! 57: children: NULL, ! 58: next: NULL, ! 59: self: NULL, ! 60: devices: NULL, ! 61: number: 0 ! 62: }; ! 63: #endif ! 64: ! 65: #if (LINUX_VERSION_CODE < VERSION(2,1,93)) ! 66: ! 67: struct pci_dev *pci_find_slot(u_int bus, u_int devfn) ! 68: { ! 69: struct pci_dev *dev; ! 70: for (dev = pci_devices; dev; dev = dev->next) ! 71: if ((dev->devfn == devfn) && (bus == dev->bus->number)) ! 72: return dev; ! 73: #if (LINUX_VERSION_CODE > VERSION(2,1,0)) ! 74: return NULL; ! 75: #else ! 76: { ! 77: struct pci_bus *b; ! 78: u8 hdr; ! 79: u32 id, class; ! 80: ! 81: if (pcibios_read_config_byte(bus, devfn & ~7, PCI_HEADER_TYPE, &hdr)) ! 82: return NULL; ! 83: if (PCI_FUNC(devfn) && !(hdr & 0x80)) ! 84: return NULL; ! 85: pcibios_read_config_dword(bus, devfn, PCI_VENDOR_ID, &id); ! 86: if ((id == 0) || (id == 0xffffffff)) ! 87: return NULL; ! 88: dev = kmalloc(sizeof *dev, GFP_ATOMIC); ! 89: if (!dev) ! 90: return NULL; ! 91: memset(dev, 0, sizeof *dev); ! 92: dev->devfn = devfn; ! 93: pcibios_read_config_byte(bus, devfn, PCI_INTERRUPT_LINE, &dev->irq); ! 94: dev->vendor = id & 0xffff; ! 95: dev->device = id >> 16; ! 96: pcibios_read_config_dword(bus, devfn, PCI_CLASS_REVISION, &class); ! 97: if (dev->irq == 255) ! 98: dev->irq = 0; ! 99: dev->class = class >> 8; ! 100: for (b = &pci_root; b; b = b->next) ! 101: if (b->number == bus) break; ! 102: if (!b) { ! 103: b = kmalloc(sizeof *b, GFP_ATOMIC); ! 104: if (!b) { ! 105: kfree(dev); ! 106: return NULL; ! 107: } ! 108: memset(b, 0, sizeof *b); ! 109: b->number = bus; ! 110: b->next = pci_root.next; ! 111: pci_root.next = b; ! 112: } ! 113: dev->bus = b; ! 114: return dev; ! 115: } ! 116: #endif ! 117: } ! 118: ! 119: struct pci_dev *pci_find_class(u_int class, struct pci_dev *from) ! 120: { ! 121: static u16 index = 0; ! 122: u8 bus, devfn; ! 123: if (from == NULL) ! 124: index = 0; ! 125: if (pcibios_find_class(class, index++, &bus, &devfn) == 0) ! 126: return pci_find_slot(bus, devfn); ! 127: else ! 128: return NULL; ! 129: } ! 130: ! 131: #endif /* (LINUX_VERSION_CODE < VERSION(2,1,93)) */ ! 132: ! 133: /*====================================================================== ! 134: ! 135: PCI Interrupt Routing Table parser ! 136: ! 137: This only needs to be done once per boot: we scan the BIOS for ! 138: the routing table, and then look for devices that have interrupt ! 139: assignments that the kernel doesn't know about. If we find any, ! 140: we update their pci_dev structures and write the PCI interrupt ! 141: line registers. ! 142: ! 143: ======================================================================*/ ! 144: ! 145: #if (LINUX_VERSION_CODE < VERSION(2,3,24)) && defined(__i386__) ! 146: ! 147: #pragma pack(1) ! 148: ! 149: struct slot_entry { ! 150: u8 bus, devfn; ! 151: struct pirq_pin { ! 152: u8 link; ! 153: u16 irq_map; ! 154: } pin[4]; ! 155: u8 slot; ! 156: u8 reserved; ! 157: }; ! 158: ! 159: struct routing_table { ! 160: u32 signature; ! 161: u8 minor, major; ! 162: u16 size; ! 163: u8 bus, devfn; ! 164: u16 pci_mask; ! 165: u32 compat; ! 166: u32 miniport; ! 167: u8 reserved[11]; ! 168: u8 checksum; ! 169: struct slot_entry entry[0]; ! 170: }; ! 171: ! 172: #pragma pack() ! 173: ! 174: /* ! 175: The meaning of the link bytes in the routing table is vendor ! 176: specific. We need code to get and set the routing information. ! 177: */ ! 178: ! 179: static u8 pIIx_link(struct pci_dev *router, u8 link) ! 180: { ! 181: u8 pirq; ! 182: /* link should be 0x60, 0x61, 0x62, 0x63 */ ! 183: pci_read_config_byte(router, link, &pirq); ! 184: return (pirq < 16) ? pirq : 0; ! 185: } ! 186: ! 187: static void pIIx_init(struct pci_dev *router, u8 link, u8 irq) ! 188: { ! 189: pci_write_config_byte(router, link, irq); ! 190: } ! 191: ! 192: static u8 via_link(struct pci_dev *router, u8 link) ! 193: { ! 194: u8 pirq = 0; ! 195: /* link should be 1, 2, 3, 5 */ ! 196: if (link < 6) ! 197: pci_read_config_byte(router, 0x55 + (link>>1), &pirq); ! 198: return (link & 1) ? (pirq >> 4) : (pirq & 15); ! 199: } ! 200: ! 201: static void via_init(struct pci_dev *router, u8 link, u8 irq) ! 202: { ! 203: u8 pirq; ! 204: pci_read_config_byte(router, 0x55 + (link>>1), &pirq); ! 205: pirq &= (link & 1) ? 0x0f : 0xf0; ! 206: pirq |= (link & 1) ? (irq << 4) : (irq & 15); ! 207: pci_write_config_byte(router, 0x55 + (link>>1), pirq); ! 208: } ! 209: ! 210: static u8 opti_link(struct pci_dev *router, u8 link) ! 211: { ! 212: u8 pirq = 0; ! 213: /* link should be 0x02, 0x12, 0x22, 0x32 */ ! 214: if ((link & 0xcf) == 0x02) ! 215: pci_read_config_byte(router, 0xb8 + (link >> 5), &pirq); ! 216: return (link & 0x10) ? (pirq >> 4) : (pirq & 15); ! 217: } ! 218: ! 219: static void opti_init(struct pci_dev *router, u8 link, u8 irq) ! 220: { ! 221: u8 pirq; ! 222: pci_read_config_byte(router, 0xb8 + (link >> 5), &pirq); ! 223: pirq &= (link & 0x10) ? 0x0f : 0xf0; ! 224: pirq |= (link & 0x10) ? (irq << 4) : (irq & 15); ! 225: pci_write_config_byte(router, 0xb8 + (link >> 5), pirq); ! 226: } ! 227: ! 228: static u8 ali_link(struct pci_dev *router, u8 link) ! 229: { ! 230: /* No, you're not dreaming */ ! 231: static const u8 map[] = ! 232: { 0, 9, 3, 10, 4, 5, 7, 6, 1, 11, 0, 12, 0, 14, 0, 15 }; ! 233: u8 pirq; ! 234: /* link should be 0x01..0x08 */ ! 235: pci_read_config_byte(router, 0x48 + ((link-1)>>1), &pirq); ! 236: return (link & 1) ? map[pirq&15] : map[pirq>>4]; ! 237: } ! 238: ! 239: static void ali_init(struct pci_dev *router, u8 link, u8 irq) ! 240: { ! 241: /* Inverse of map in ali_link */ ! 242: static const u8 map[] = ! 243: { 0, 8, 0, 2, 4, 5, 7, 6, 0, 1, 3, 9, 11, 0, 13, 15 }; ! 244: u8 pirq; ! 245: pci_read_config_byte(router, 0x48 + ((link-1)>>1), &pirq); ! 246: pirq &= (link & 1) ? 0x0f : 0xf0; ! 247: pirq |= (link & 1) ? (map[irq] << 4) : (map[irq] & 15); ! 248: pci_write_config_byte(router, 0x48 + ((link-1)>>1), pirq); ! 249: } ! 250: ! 251: static u8 cyrix_link(struct pci_dev *router, u8 link) ! 252: { ! 253: u8 pirq; ! 254: /* link should be 1, 2, 3, 4 */ ! 255: link--; ! 256: pci_read_config_byte(router, 0x5c + (link>>1), &pirq); ! 257: return ((link & 1) ? pirq >> 4 : pirq & 15); ! 258: } ! 259: ! 260: static void cyrix_init(struct pci_dev *router, u8 link, u8 irq) ! 261: { ! 262: u8 pirq; ! 263: link--; ! 264: pci_read_config_byte(router, 0x5c + (link>>1), &pirq); ! 265: pirq &= (link & 1) ? 0x0f : 0xf0; ! 266: pirq |= (link & 1) ? (irq << 4) : (irq & 15); ! 267: pci_write_config_byte(router, 0x5c + (link>>1), pirq); ! 268: } ! 269: ! 270: /* ! 271: A table of all the PCI interrupt routers for which we know how to ! 272: interpret the link bytes. ! 273: */ ! 274: ! 275: #ifndef PCI_DEVICE_ID_INTEL_82371FB_0 ! 276: #define PCI_DEVICE_ID_INTEL_82371FB_0 0x122e ! 277: #endif ! 278: #ifndef PCI_DEVICE_ID_INTEL_82371SB_0 ! 279: #define PCI_DEVICE_ID_INTEL_82371SB_0 0x7000 ! 280: #endif ! 281: #ifndef PCI_DEVICE_ID_INTEL_82371AB_0 ! 282: #define PCI_DEVICE_ID_INTEL_82371AB_0 0x7110 ! 283: #endif ! 284: #ifndef PCI_DEVICE_ID_INTEL_82443MX_1 ! 285: #define PCI_DEVICE_ID_INTEL_82443MX_1 0x7198 ! 286: #endif ! 287: #ifndef PCI_DEVICE_ID_INTEL_82443MX_1 ! 288: #define PCI_DEVICE_ID_INTEL_82443MX_1 0x7198 ! 289: #endif ! 290: #ifndef PCI_DEVICE_ID_INTEL_82801AA_0 ! 291: #define PCI_DEVICE_ID_INTEL_82801AA_0 0x2410 ! 292: #endif ! 293: #ifndef PCI_DEVICE_ID_INTEL_82801AB_0 ! 294: #define PCI_DEVICE_ID_INTEL_82801AB_0 0x2420 ! 295: #endif ! 296: #ifndef PCI_DEVICE_ID_INTEL_82801BA_0 ! 297: #define PCI_DEVICE_ID_INTEL_82801BA_0 0x2440 ! 298: #endif ! 299: #ifndef PCI_DEVICE_ID_INTEL_82801BAM_0 ! 300: #define PCI_DEVICE_ID_INTEL_82801BAM_0 0x244c ! 301: #endif ! 302: #ifndef PCI_DEVICE_ID_VIA_82C586_0 ! 303: #define PCI_DEVICE_ID_VIA_82C586_0 0x0586 ! 304: #endif ! 305: #ifndef PCI_DEVICE_ID_VIA_82C596 ! 306: #define PCI_DEVICE_ID_VIA_82C596 0x0596 ! 307: #endif ! 308: #ifndef PCI_DEVICE_ID_VIA_82C686 ! 309: #define PCI_DEVICE_ID_VIA_82C686 0x0686 ! 310: #endif ! 311: #ifndef PCI_DEVICE_ID_SI ! 312: #define PCI_DEVICE_ID_SI 0x1039 ! 313: #endif ! 314: #ifndef PCI_DEVICE_ID_SI_503 ! 315: #define PCI_DEVICE_ID_SI_503 0x0008 ! 316: #endif ! 317: #ifndef PCI_DEVICE_ID_SI_496 ! 318: #define PCI_DEVICE_ID_SI_496 0x0496 ! 319: #endif ! 320: ! 321: #define ID(a,b) PCI_VENDOR_ID_##a,PCI_DEVICE_ID_##a##_##b ! 322: ! 323: struct router { ! 324: u16 vendor, device; ! 325: u8 (*xlate)(struct pci_dev *, u8); ! 326: void (*init)(struct pci_dev *, u8, u8); ! 327: } router_table[] = { ! 328: { ID(INTEL, 82371FB_0), &pIIx_link, &pIIx_init }, ! 329: { ID(INTEL, 82371SB_0), &pIIx_link, &pIIx_init }, ! 330: { ID(INTEL, 82371AB_0), &pIIx_link, &pIIx_init }, ! 331: { ID(INTEL, 82443MX_1), &pIIx_link, &pIIx_init }, ! 332: { ID(INTEL, 82801AA_0), &pIIx_link, &pIIx_init }, ! 333: { ID(INTEL, 82801AB_0), &pIIx_link, &pIIx_init }, ! 334: { ID(INTEL, 82801BA_0), &pIIx_link, &pIIx_init }, ! 335: { ID(INTEL, 82801BAM_0), &pIIx_link, &pIIx_init }, ! 336: { ID(VIA, 82C586_0), &via_link, &via_init }, ! 337: { ID(VIA, 82C596), &via_link, &via_init }, ! 338: { ID(VIA, 82C686), &via_link, &via_init }, ! 339: { ID(OPTI, 82C700), &opti_link, &opti_init }, ! 340: { ID(AL, M1533), &ali_link, &ali_init }, ! 341: { ID(SI, 503), &pIIx_link, &pIIx_init }, ! 342: { ID(SI, 496), &pIIx_link, &pIIx_init }, ! 343: { ID(CYRIX, 5530_LEGACY), &cyrix_link, &cyrix_init } ! 344: }; ! 345: #define ROUTER_COUNT (sizeof(router_table)/sizeof(router_table[0])) ! 346: ! 347: /* Global variables for current interrupt routing table */ ! 348: static struct routing_table *pirq = NULL; ! 349: static struct pci_dev *router_dev = NULL; ! 350: static struct router *router_info = NULL; ! 351: ! 352: #ifndef __va ! 353: #define __va(x) (x) ! 354: #endif ! 355: ! 356: static void scan_pirq_table(void) ! 357: { ! 358: struct routing_table *r; ! 359: struct pci_dev *router, *dev; ! 360: u8 pin, fn, *p; ! 361: int i, j; ! 362: struct slot_entry *e; ! 363: ! 364: /* Scan the BIOS for the routing table signature */ ! 365: for (p = (u8 *)__va(0xf0000); p < (u8 *)__va(0xfffff); p += 16) ! 366: if ((p[0] == '$') && (p[1] == 'P') && ! 367: (p[2] == 'I') && (p[3] == 'R')) break; ! 368: if (p >= (u8 *)__va(0xfffff)) ! 369: return; ! 370: ! 371: pirq = r = (struct routing_table *)p; ! 372: printk(KERN_INFO "PCI routing table version %d.%d at %#06x\n", ! 373: r->major, r->minor, (u32)r & 0xfffff); ! 374: for (i = j = 0; i < 16; i++) ! 375: j += (r->pci_mask >> i) & 1; ! 376: if (j > 4) ! 377: printk(KERN_NOTICE " bogus PCI irq mask %#04x!\n", ! 378: r->pci_mask); ! 379: else ! 380: pci_irq_mask |= r->pci_mask; ! 381: ! 382: router_dev = router = pci_find_slot(r->bus, r->devfn); ! 383: if (router) { ! 384: for (i = 0; i < ROUTER_COUNT; i++) { ! 385: if ((router->vendor == router_table[i].vendor) && ! 386: (router->device == router_table[i].device)) ! 387: break; ! 388: if (((r->compat & 0xffff) == router_table[i].vendor) && ! 389: ((r->compat >> 16) == router_table[i].device)) ! 390: break; ! 391: } ! 392: if (i == ROUTER_COUNT) ! 393: printk(KERN_INFO " unknown PCI interrupt router %04x:%04x\n", ! 394: router->vendor, router->device); ! 395: else ! 396: router_info = &router_table[i]; ! 397: } ! 398: ! 399: for (e = r->entry; (u8 *)e < p+r->size; e++) { ! 400: for (fn = 0; fn < 8; fn++) { ! 401: dev = pci_find_slot(e->bus, e->devfn | fn); ! 402: if ((dev == NULL) || (dev->irq != 0)) continue; ! 403: pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin); ! 404: if ((pin == 0) || (pin == 255)) continue; ! 405: if (router_info) { ! 406: dev->irq = router_info->xlate(router, e->pin[pin-1].link); ! 407: } else { ! 408: /* Fallback: see if only one irq possible */ ! 409: int map = e->pin[pin-1].irq_map; ! 410: if (map && (!(map & (map-1)))) ! 411: dev->irq = ffs(map)-1; ! 412: } ! 413: if (dev->irq) { ! 414: printk(KERN_INFO " %02x:%02x.%1x -> irq %d\n", ! 415: e->bus, PCI_SLOT(dev->devfn), ! 416: PCI_FUNC(dev->devfn), dev->irq); ! 417: pci_write_config_byte(dev, PCI_INTERRUPT_LINE, ! 418: dev->irq); ! 419: } ! 420: } ! 421: } ! 422: } ! 423: ! 424: #endif /* (LINUX_VERSION_CODE < VERSION(2,3,24)) && defined(__i386__) */ ! 425: ! 426: /*====================================================================== ! 427: ! 428: PCI device enabler ! 429: ! 430: This is not at all generic... it is mostly a hack to correctly ! 431: configure CardBus bridges. ! 432: ! 433: ======================================================================*/ ! 434: ! 435: #if (LINUX_VERSION_CODE < VERSION(2,3,24)) ! 436: ! 437: static int check_cb_mapping(u_int phys) ! 438: { ! 439: /* A few sanity checks to validate the bridge mapping */ ! 440: char *virt = ioremap(phys, 0x1000); ! 441: int ret = ((readb(virt+0x800+I365_IDENT) & 0x70) || ! 442: (readb(virt+0x800+I365_CSC) && ! 443: readb(virt+0x800+I365_CSC) && ! 444: readb(virt+0x800+I365_CSC))); ! 445: int state = readl(virt+CB_SOCKET_STATE) >> 16; ! 446: ret |= (state & ~0x3000) || !(state & 0x3000); ! 447: ret |= readl(virt+CB_SOCKET_FORCE); ! 448: iounmap(virt); ! 449: return ret; ! 450: } ! 451: ! 452: static void setup_cb_bridge(struct pci_dev *dev) ! 453: { ! 454: u8 bus, sub; ! 455: u32 phys; ! 456: int i; ! 457: ! 458: /* This is nasty, but where else can we put it? */ ! 459: if (PCI_FUNC(dev->devfn) == 0) { ! 460: struct pci_dev *sib; ! 461: sib = pci_find_slot(dev->bus->number, dev->devfn+1); ! 462: if (sib) { ! 463: u8 a, b; ! 464: u32 c, d; ! 465: /* Check for bad PCI bus numbering */ ! 466: pci_read_config_byte(dev, CB_CARDBUS_BUS, &a); ! 467: pci_read_config_byte(sib, CB_CARDBUS_BUS, &b); ! 468: if (a == b) { ! 469: pci_write_config_byte(dev, CB_CARDBUS_BUS, 0); ! 470: pci_write_config_byte(sib, CB_CARDBUS_BUS, 0); ! 471: } ! 472: /* check for bad register mapping */ ! 473: pci_read_config_dword(dev, PCI_BASE_ADDRESS_0, &c); ! 474: pci_read_config_dword(sib, PCI_BASE_ADDRESS_0, &d); ! 475: if ((c != 0) && (c == d)) { ! 476: pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, 0); ! 477: pci_write_config_dword(sib, PCI_BASE_ADDRESS_0, 0); ! 478: } ! 479: } ! 480: } ! 481: ! 482: /* Assign PCI bus numbers, if needed */ ! 483: pci_read_config_byte(dev, CB_CARDBUS_BUS, &bus); ! 484: pci_read_config_byte(dev, CB_SUBORD_BUS, &sub); ! 485: if ((cb_bus_base > 0) || (bus == 0)) { ! 486: if (cb_bus_base <= 0) cb_bus_base = 0x20; ! 487: bus = cb_bus_base; ! 488: sub = cb_bus_base+cb_bus_step; ! 489: cb_bus_base += cb_bus_step+1; ! 490: pci_write_config_byte(dev, CB_CARDBUS_BUS, bus); ! 491: pci_write_config_byte(dev, CB_SUBORD_BUS, sub); ! 492: } ! 493: ! 494: /* Create pci_bus structure for the CardBus, if needed */ ! 495: { ! 496: struct pci_bus *child, *parent = dev->bus; ! 497: for (child = parent->children; child; child = child->next) ! 498: if (child->number == bus) break; ! 499: if (!child) { ! 500: child = kmalloc(sizeof(struct pci_bus), GFP_KERNEL); ! 501: memset(child, 0, sizeof(struct pci_bus)); ! 502: child->self = dev; ! 503: child->primary = bus; ! 504: child->number = child->secondary = bus; ! 505: child->subordinate = sub; ! 506: child->parent = parent; ! 507: #if (LINUX_VERSION_CODE >= VERSION(2,3,15)) ! 508: child->ops = parent->ops; ! 509: #endif ! 510: child->next = parent->children; ! 511: parent->children = child; ! 512: } ! 513: } ! 514: ! 515: /* Map the CardBus bridge registers, if needed */ ! 516: pci_write_config_dword(dev, CB_LEGACY_MODE_BASE, 0); ! 517: pci_read_config_dword(dev, PCI_BASE_ADDRESS_0, &phys); ! 518: if ((phys == 0) || (cb_mem_base[0] != 0)) { ! 519: /* Make sure the bridge is awake so we can test it */ ! 520: pci_set_power_state(dev, 0); ! 521: for (i = 0; i < sizeof(cb_mem_base)/sizeof(u_int); i++) { ! 522: phys = cb_mem_base[i]; ! 523: if (phys == 0) continue; ! 524: pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, phys); ! 525: if ((i == 0) || (check_cb_mapping(phys) == 0)) break; ! 526: } ! 527: if (i == sizeof(cb_mem_base)/sizeof(u_int)) { ! 528: pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, 0); ! 529: } else { ! 530: cb_mem_base[0] = cb_mem_base[i] + 0x1000; ! 531: } ! 532: } ! 533: } ! 534: ! 535: #ifdef __i386__ ! 536: ! 537: static u8 pirq_init(struct pci_dev *router, struct pirq_pin *pin) ! 538: { ! 539: u16 map = pin->irq_map; ! 540: u8 irq = 0; ! 541: if (pirq->pci_mask) ! 542: map &= pirq->pci_mask; ! 543: if (cb_pci_irq) ! 544: map = 1<<cb_pci_irq; ! 545: /* Be conservative: only init irq if the mask is unambiguous */ ! 546: if (map && (!(map & (map-1)))) { ! 547: irq = ffs(map)-1; ! 548: router_info->init(router, pin->link, irq); ! 549: pci_irq_mask |= (1<<irq); ! 550: } ! 551: return irq; ! 552: } ! 553: ! 554: static void setup_cb_bridge_irq(struct pci_dev *dev) ! 555: { ! 556: struct slot_entry *e; ! 557: u8 pin; ! 558: u32 phys; ! 559: char *virt; ! 560: ! 561: pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin); ! 562: pci_read_config_dword(dev, PCI_BASE_ADDRESS_0, &phys); ! 563: if (!pin || !phys) ! 564: return; ! 565: virt = ioremap(phys, 0x1000); ! 566: if (virt) { ! 567: /* Disable any pending interrupt sources */ ! 568: writel(0, virt+CB_SOCKET_MASK); ! 569: writel(-1, virt+CB_SOCKET_EVENT); ! 570: iounmap(virt); ! 571: } ! 572: for (e = pirq->entry; (u8 *)e < (u8 *)pirq + pirq->size; e++) { ! 573: if ((e->bus != dev->bus->number) || ! 574: (e->devfn != (dev->devfn & ~7))) ! 575: continue; ! 576: dev->irq = pirq_init(router_dev, &e->pin[pin-1]); ! 577: pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq); ! 578: break; ! 579: } ! 580: } ! 581: ! 582: #endif ! 583: ! 584: int pci_enable_device(struct pci_dev *dev) ! 585: { ! 586: if ((dev->class >> 8) == PCI_CLASS_BRIDGE_CARDBUS) { ! 587: setup_cb_bridge(dev); ! 588: } ! 589: #ifdef __i386__ ! 590: /* In certain cases, if the interrupt can be deduced, but was ! 591: unrouted when the pirq table was scanned, we'll try to set it ! 592: up now. */ ! 593: if (!dev->irq && pirq && (router_info) && ! 594: ((dev->class >> 8) == PCI_CLASS_BRIDGE_CARDBUS)) { ! 595: setup_cb_bridge_irq(dev); ! 596: } ! 597: #endif ! 598: return 0; ! 599: } ! 600: ! 601: int pci_set_power_state(struct pci_dev *dev, int state) ! 602: { ! 603: u16 tmp, cmd; ! 604: u32 base, bus; ! 605: u8 a, b, pmcs; ! 606: pci_read_config_byte(dev, PCI_STATUS, &a); ! 607: if (a & PCI_STATUS_CAPLIST) { ! 608: pci_read_config_byte(dev, PCI_CB_CAPABILITY_POINTER, &b); ! 609: while (b != 0) { ! 610: pci_read_config_byte(dev, b+PCI_CAPABILITY_ID, &a); ! 611: if (a == PCI_CAPABILITY_PM) { ! 612: pmcs = b + PCI_PM_CONTROL_STATUS; ! 613: /* Make sure we're in D0 state */ ! 614: pci_read_config_word(dev, pmcs, &tmp); ! 615: if (!(tmp & PCI_PMCS_PWR_STATE_MASK)) break; ! 616: pci_read_config_dword(dev, PCI_BASE_ADDRESS_0, &base); ! 617: pci_read_config_dword(dev, CB_PRIMARY_BUS, &bus); ! 618: pci_read_config_word(dev, PCI_COMMAND, &cmd); ! 619: pci_write_config_word(dev, pmcs, PCI_PMCS_PWR_STATE_D0); ! 620: pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, base); ! 621: pci_write_config_dword(dev, CB_PRIMARY_BUS, bus); ! 622: pci_write_config_word(dev, PCI_COMMAND, cmd); ! 623: break; ! 624: } ! 625: pci_read_config_byte(dev, b+PCI_NEXT_CAPABILITY, &b); ! 626: } ! 627: } ! 628: return 0; ! 629: } ! 630: ! 631: #endif /* (LINUX_VERSION_CODE < VERSION(2,3,24)) */ ! 632: ! 633: /*====================================================================== ! 634: ! 635: General setup and cleanup entry points ! 636: ! 637: ======================================================================*/ ! 638: ! 639: void pci_fixup_init(void) ! 640: { ! 641: struct pci_dev *p; ! 642: ! 643: #if (LINUX_VERSION_CODE < VERSION(2,3,24)) && defined(__i386__) ! 644: scan_pirq_table(); ! 645: pci_for_each_dev(p) ! 646: if (((p->class >> 8) == PCI_CLASS_BRIDGE_CARDBUS) && ! 647: (p->irq == 0)) break; ! 648: if (p && !pirq) ! 649: printk(KERN_INFO "No PCI interrupt routing table!\n"); ! 650: if (!pirq && cb_pci_irq) ! 651: printk(KERN_INFO "cb_pci_irq will be ignored.\n"); ! 652: #endif ! 653: ! 654: pci_for_each_dev(p) ! 655: pci_irq_mask |= (1<<p->irq); ! 656: ! 657: #ifdef __alpha__ ! 658: #define PIC 0x4d0 ! 659: pci_irq_mask |= inb(PIC) | (inb(PIC+1) << 8); ! 660: #endif ! 661: } ! 662: ! 663: void pci_fixup_done(void) ! 664: { ! 665: #if (LINUX_VERSION_CODE < VERSION(2,1,0)) ! 666: struct pci_dev *d, *dn; ! 667: struct pci_bus *b, *bn; ! 668: for (d = pci_devices; d; d = dn) { ! 669: dn = d->next; ! 670: kfree(d); ! 671: } ! 672: for (b = pci_root.next; b; b = bn) { ! 673: bn = b->next; ! 674: kfree(b); ! 675: } ! 676: #endif ! 677: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.