From 70dee992a38e64256b114f03b24ca4c6c46c3800 Mon Sep 17 00:00:00 2001 From: Daniel Reinhold Date: Fri, 28 Feb 2003 21:21:46 +0000 Subject: [PATCH] style changes -- purely cosmetic normally, I wouldn't checkin a file with cosmetic changes only however, Marcus just made a change on this file earlier today, so the file would have to be rebuilt anyway -- might as well make it pretty too! git-svn-id: file:///srv/svn/repos/haiku/trunk/current@2853 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/kernel/core/addons/bus_managers/pci/pci.c | 829 +++++++++--------- 1 file changed, 436 insertions(+), 393 deletions(-) diff --git a/src/kernel/core/addons/bus_managers/pci/pci.c b/src/kernel/core/addons/bus_managers/pci/pci.c index 884df0563d..7667b75f68 100755 --- a/src/kernel/core/addons/bus_managers/pci/pci.c +++ b/src/kernel/core/addons/bus_managers/pci/pci.c @@ -31,17 +31,29 @@ #endif +/* + * pci_device + */ +typedef struct pci_device pci_device; + struct pci_device { - struct pci_device *next; - int type; - pci_info *info; + pci_info *info; + int type; + pci_device *next; }; + +/* + * pci_bus + */ +typedef struct pci_bus pci_bus; + struct pci_bus { - struct pci_bus *next; pci_info *info; + pci_bus *next; }; + enum { PCI_DEVICE = 0, PCI_HOST_BUS, @@ -49,40 +61,55 @@ enum { PCI_CARDBUS }; -static struct pci_device *pci_devices = NULL; -static struct pci_bus *pci_busses = NULL; -static spinlock pci_config_lock = 0; /* lock for config space access */ -static int pci_mode = 1; /* The pci config mechanism we're using. - * NB defaults to 1 as this is more common, but + +// forward declarations +static char *decode_class(uint8 base, uint8 sub_class); +static void pci_scan_bus(uint8 bus); +static void scan_pci(void); +static void pci_bridge(uint8 bus, uint8 dev, uint8 func); +static void fill_basic_pci_structure(pci_info *pciInfo); +static uint32 read_pci_config(uchar, uchar, uchar, uchar, uchar); +static void write_pci_config (uchar, uchar, uchar, uchar, uchar, uint32); + + + + +/** globals **/ + +static pci_device *gPCI_Devices = NULL; +static pci_bus *gPCI_Busses = NULL; + +static spinlock gConfigLock = 0; /* lock for config space access */ +static int gConfigMechanism = 1; /* The pci config mechanism we're using. + * Note: defaults to 1 as this is more common, but * checked at runtime */ -static int bus_max_devices = 32; /* max devices that any bus can support - * Yes, if we're using pci_mode == 2 then +static int gMaxBusDevices = 32; /* max devices that any bus can support + * Yes, if we're using gConfigMechanism == 2 then * this is only 16, instead of the 32 we - * have with pci_mode == 1 + * have with gConfigMechanism == 1 */ -static int pci_max_bus = 0; /* maximum bus we've found/configured */ -static region_id pci_region; /* pci_bios region we map */ -static void * pci_bios_ptr = NULL; /* virtual address of memory we map */ +static int gMaxBusDetected = 0; /* maximum bus we've found/configured */ -static void pci_scan_bus(uint8 bus); -static void pci_bridge(uint8 bus, uint8 dev, uint8 func); -static void fill_basic_pci_structure(pci_info *pcii); -static uint32 read_pci_config(uchar, uchar, uchar, uchar, uchar); -static void write_pci_config (uchar, uchar, uchar, uchar, uchar, uint32); +static region_id gPCI_Region; /* pci_bios region we map */ +static addr gPCI_BIOS_Address = 0; /* virtual address of memory we map */ -/* XXX - move these to a header file */ + + + +/* ToDo: move these to a header file */ #define PCI_VENDOR_INTEL 0x8086 -#define PCI_PRODUCT_INTEL_82371AB_ISA 0x7110 /* PIIX4 ISA */ -#define PCI_PRODUCT_INTEL_82371AB_IDE 0x7111 /* PIIX4 IDE */ -#define PCI_PRODUCT_INTEL_82371AB_USB 0x7112 /* PIIX4 USB */ -#define PCI_PRODUCT_INTEL_82371AB_PMC 0x7113 /* PIIX4 Power Management */ +#define PCI_PRODUCT_INTEL_82371AB_ISA 0x7110 /* PIIX4 ISA */ +#define PCI_PRODUCT_INTEL_82371AB_IDE 0x7111 /* PIIX4 IDE */ +#define PCI_PRODUCT_INTEL_82371AB_USB 0x7112 /* PIIX4 USB */ +#define PCI_PRODUCT_INTEL_82371AB_PMC 0x7113 /* PIIX4 Power Management */ #define PCI_PRODUCT_INTEL_82443BX 0x7190 #define PCI_PRODUCT_INTEL_82443BX_AGP 0x7191 #define PCI_PRODUCT_INTEL_82443BX_NOAGP 0x7192 +#define PCI_PRODUCT_INTEL_82845_AGP 0x1a31 /* Config space locking! * We need to make sure we only have one access at a time into the config space, @@ -93,16 +120,17 @@ static void write_pci_config (uchar, uchar, uchar, uchar, uchar, uint32); #define PCI_LOCK_CONFIG(status) \ { \ status = disable_interrupts(); \ - acquire_spinlock(&pci_config_lock); \ + acquire_spinlock(&gConfigLock); \ } #define PCI_UNLOCK_CONFIG(cpu_status) \ { \ - release_spinlock(&pci_config_lock); \ + release_spinlock(&gConfigLock); \ restore_interrupts(cpu_status); \ } + /* decode_class * DEBUG DEBUG DEBUG * Provide a string that describes the class and sub-class. @@ -112,79 +140,56 @@ static void write_pci_config (uchar, uchar, uchar, uchar, uchar, uint32); static char * decode_class(uint8 base, uint8 sub_class) { - switch(base) { + switch (base) { case PCI_early: switch (sub_class) { - case PCI_early_not_vga: - return "legacy (non VGA)"; - case PCI_early_vga: - return "legacy VGA"; + case PCI_early_not_vga: return "legacy (non VGA)"; + case PCI_early_vga: return "legacy VGA"; } case 0x01: switch (sub_class) { - case PCI_scsi: - return "mass storage: scsi"; - case PCI_ide: - return "mass storage: ide"; - case PCI_floppy: - return "mass storage: floppy"; - case PCI_ipi: - return "mass storage: ipi"; - case PCI_raid: - return "mass storage: raid"; + case PCI_scsi: return "mass storage: scsi"; + case PCI_ide: return "mass storage: ide"; + case PCI_floppy: return "mass storage: floppy"; + case PCI_ipi: return "mass storage: ipi"; + case PCI_raid: return "mass storage: raid"; case PCI_mass_storage_other: return "mass storage: other"; } case 0x02: switch (sub_class) { - case PCI_ethernet: - return "network: ethernet"; - case PCI_token_ring: - return "network: token ring"; - case PCI_fddi: - return "network: fddi"; - case PCI_atm: - return "network: atm"; + case PCI_ethernet: return "network: ethernet"; + case PCI_token_ring: return "network: token ring"; + case PCI_fddi: return "network: fddi"; + case PCI_atm: return "network: atm"; case PCI_network_other: return "network: other"; } case 0x03: switch (sub_class) { - case PCI_vga: - return "display: vga"; - case PCI_xga: - return "display: xga"; + case PCI_vga: return "display: vga"; + case PCI_xga: return "display: xga"; case PCI_display_other: return "display: other"; } case 0x04: switch (sub_class) { - case PCI_video: - return "multimedia device: video"; - case PCI_audio: - return "multimedia device: audio"; + case PCI_video: return "multimedia device: video"; + case PCI_audio: return "multimedia device: audio"; case PCI_multimedia_other: return "multimedia device: other"; } case 0x05: return "memory"; case 0x06: switch (sub_class) { - case PCI_host: - return "bridge: host bridge"; - case PCI_isa: - return "bridge: isa"; - case PCI_eisa: - return "bridge: eisa"; - case PCI_microchannel: - return "bridge: microchannel"; - case PCI_pci: - return "bridge: PCI"; - case PCI_pcmcia: - return "bridge: PC Card"; - case PCI_nubus: - return "bridge: nubus"; - case PCI_cardbus: - return "bridge: CardBus"; + case PCI_host: return "bridge: host bridge"; + case PCI_isa: return "bridge: isa"; + case PCI_eisa: return "bridge: eisa"; + case PCI_microchannel: return "bridge: microchannel"; + case PCI_pci: return "bridge: PCI"; + case PCI_pcmcia: return "bridge: PC Card"; + case PCI_nubus: return "bridge: nubus"; + case PCI_cardbus: return "bridge: CardBus"; case PCI_bridge_other: return "bridge: other"; } @@ -195,14 +200,10 @@ decode_class(uint8 base, uint8 sub_class) case 0x0b: return "processor"; case 0x0c: switch (sub_class) { - case PCI_firewire: - return "bus: IEEE1394 FireWire"; - case PCI_access: - return "bus: ACCESS.bus"; - case PCI_ssa: - return "bus: SSA"; - case PCI_usb: - return "bus: USB"; + case PCI_firewire: return "bus: IEEE1394 FireWire"; + case PCI_access: return "bus: ACCESS.bus"; + case PCI_ssa: return "bus: SSA"; + case PCI_usb: return "bus: USB"; case PCI_fibre_channel: return "bus: fibre channel"; } @@ -211,6 +212,7 @@ decode_class(uint8 base, uint8 sub_class) case 0x0f: return "satellite"; case 0x10: return "encryption"; case 0x11: return "signal processing"; + default: return "unknown"; } } @@ -270,17 +272,18 @@ show_pci_details(struct pci_info *p) dprintf("\tsubordinate_bus : %d\n", p->u.h1.subordinate_bus); ss_vend = p->u.h1.subsystem_vendor_id; - ss_dev = p->u.h1.subsystem_id; + ss_dev = p->u.h1.subsystem_id; } dprintf("\tsubsystem_id : %04x\n", ss_dev); dprintf("\tsubsystem_vendor_id : %04x\n", ss_vend); #endif } + /* PCI has 2 Configuration Mechanisms. We need to decide which one the * PCI Host Bridge is speaking and then speak to it correctly. This is decided - * in set_pci_mechanism() where the pci_mode value is set to the appropriate - * value and the bus_max_devices value is set correctly. + * in set_pci_mechanism() where the gConfigMechanism value is set to the appropriate + * value and the gMaxBusDevices value is set correctly. * * Mechanism 1 * =========== @@ -293,13 +296,15 @@ show_pci_details(struct pci_info *p) * * Apparently most modern hardware no longer has Configuration Type #2. * - * XXX - add code for Mechanism Two * + * Mechanism 2 + * =========== + * ToDO: add code for mechanism 2! * */ -#define CONFIG_REQ_PORT 0xCF8 -#define CONFIG_DATA_PORT 0xCFC +#define CONFIG_REQ_PORT 0xCF8 +#define CONFIG_DATA_PORT 0xCFC #define CONFIG_ADDR_1(bus, device, func, reg) \ (0x80000000 | (bus << 16) | (device << 11) | (func << 8) | (reg & ~3)) @@ -316,13 +321,12 @@ read_pci_config(uchar bus, uchar device, uchar function, uchar reg, uchar size) PCI_LOCK_CONFIG(cpu_status); - if (pci_mode == 1) { - /* write request details */ + if (gConfigMechanism == 1) { + // write request details out32(CONFIG_ADDR_1(bus, device, function, reg), CONFIG_REQ_PORT); - /* Now read data back from the data port... - * offset for 1 byte can be 1,2 or 3 - * offset for 2 bytes can be 1 or 2 - */ + // Now read data back from the data port: + // offset for 1 byte can be 1, 2 or 3 + // offset for 2 bytes can be 1 or 2 switch (size) { case 1: val = in8 (CONFIG_DATA_PORT + (reg & 3)); @@ -346,7 +350,7 @@ read_pci_config(uchar bus, uchar device, uchar function, uchar reg, uchar size) default: dprintf("ERROR: mech #1: read_pci_config: called for %d bytes!!\n", size); } - } else if (pci_mode == 2) { + } else if (gConfigMechanism == 2) { if (!(device & 0x10)) { out8((uint8)(0xF0 | (function << 1)), 0xCF8); out8(bus, 0xCFA); @@ -368,7 +372,7 @@ read_pci_config(uchar bus, uchar device, uchar function, uchar reg, uchar size) } else val = EINVAL; } else - dprintf("PCI: Config Mechanism %d isn't known!\n", pci_mode); + dprintf("PCI: Config Mechanism %d isn't known!\n", gConfigMechanism); PCI_UNLOCK_CONFIG(cpu_status); return val; @@ -382,13 +386,12 @@ write_pci_config(uchar bus, uchar device, uchar function, uchar reg, uchar size, PCI_LOCK_CONFIG(cpu_status); - if (pci_mode == 1) { + if (gConfigMechanism == 1) { /* write request details */ - out32(CONFIG_ADDR_1(bus, device, function, reg), CONFIG_REQ_PORT); - /* Now read data back from the data port... - * offset for 1 byte can be 1,2 or 3 - * offset for 2 bytes can be 1 or 2 - */ + out32(CONFIG_ADDR_1(bus, device, function, reg), CONFIG_REQ_PORT); + // Now read data back from the data port: + // offset for 1 byte can be 1, 2 or 3 + // offset for 2 bytes can be 1 or 2 switch (size) { case 1: out8 (value, CONFIG_DATA_PORT + (reg & 3)); @@ -408,7 +411,7 @@ write_pci_config(uchar bus, uchar device, uchar function, uchar reg, uchar size, default: dprintf("ERROR: write_pci_config: called for %d bytes!!\n", size); } - } else if (pci_mode == 2) { + } else if (gConfigMechanism == 2) { if (!(device & 0x10)) { out8((uint8)(0xF0 | (function << 1)), 0xCF8); out8(bus, 0xCFA); @@ -429,7 +432,7 @@ write_pci_config(uchar bus, uchar device, uchar function, uchar reg, uchar size, out8(0, 0xCF8); } } else - dprintf("PCI: Config Mechanism %d isn't known!\n", pci_mode); + dprintf("PCI: Config Mechanism %d isn't known!\n", gConfigMechanism); PCI_UNLOCK_CONFIG(cpu_status); @@ -438,69 +441,66 @@ write_pci_config(uchar bus, uchar device, uchar function, uchar reg, uchar size, /* pci_get_capability - * Try to get the offset and value of the specified capability from the - * devices capability list. - * returns 0 if unable, 1 if succesful + * Try to get the offset and value of the specified capability + * from the devices capability list. */ -static int +static bool pci_get_capability(uint8 bus, uint8 dev, uint8 func, uint8 cap, uint8 *offs) { uint16 status; - uint8 cap_data; - uint8 hdr_type; - uint8 ofs; - int maxcount; + uint8 headerType; + uint8 ofs; + int maxcount; status = read_pci_config(bus, dev, func, PCI_status, 2); if (!(status & PCI_status_capabilities)) - return 0; + return false; - hdr_type = read_pci_config(bus, dev, func, PCI_header_type, 1); - switch (hdr_type & 0x7f) { /* mask off multi function device indicator bit */ + headerType = read_pci_config(bus, dev, func, PCI_header_type, 1); + switch (headerType & 0x7f) { /* mask off multi function device indicator bit */ case PCI_header_type_generic: ofs = PCI_capabilities_ptr; break; case PCI_header_type_PCI_to_PCI_bridge: dprintf("ERROR: pci_get_capability: PCItoPCI bridge header type has no capabilities pointer???\n"); - return 0; + return false; case PCI_header_type_cardbus: ofs = PCI_capabilities_ptr_2; break; default: dprintf("ERROR: pci_get_capability: unknown PCI header type\n"); - return 0; + return false; } - /* the 192 bytes vendor defined configuration space can - * hold as maximum 48 times a 32 bit aligned capability, - * we use this as abort condition to avoid lock up by - * searching in a circular loop on bad hardware - */ + // The 192 bytes vendor-defined configuration space can + // hold, as maximum, 48 times a 32-bit aligned capability. + // We use this as abort condition to avoid lock up by + // searching in a circular loop on bad hardware. + maxcount = 48; ofs = read_pci_config(bus, dev, func, ofs, 1); - while (maxcount-- != 0 && ofs != 0) { + while (maxcount-- > 0 && ofs != 0) { - /* mask off low two bits, demanded by PCI standard */ + // mask off low two bits, demanded by PCI standard ofs &= ~3; - /* PCI specification 2.2, section 6.8.1.1 and following - * describe capability ID and next capability position as - * two 8 bit values, the "capability ID" is at the 32 bit - * aligned position, after it the "next pointer" follows. - */ + // PCI specification 2.2, section 6.8.1.1 and following + // describe capability ID and next capability position as + // two 8 bit values, the "capability ID" is at the 32 bit + // aligned position, after it the "next pointer" follows. - /* read the 8 bit capability id is at the 32bit aligned ofs position */ - cap_data = read_pci_config(bus, dev, func, ofs, 1); - if (cap_data == cap) { + // read the 8 bit capability id is at the 32-bit aligned ofs position + if (read_pci_config(bus, dev, func, ofs, 1) == cap) { if (offs) *offs = ofs; - return 1; + return true; } - /* at ofs + 1, we can read the next capability position */ + + // at ofs + 1, we can read the next capability position ofs = read_pci_config(bus, dev, func, ofs + 1, 1); } - return 0; + return false; } @@ -523,7 +523,8 @@ pci_get_capability(uint8 bus, uint8 dev, uint8 func, uint8 cap, uint8 *offs) static int pci_set_power_state(uint8 bus, uint8 dev, uint8 func, int state) { - uint8 pm_reg, cur_state; + uint8 pm_reg; + uint8 cur_state; uint16 cur_status; if (pci_get_capability(bus, dev, func, PCI_cap_id_pm, &pm_reg) == 0) @@ -539,8 +540,7 @@ pci_set_power_state(uint8 bus, uint8 dev, uint8 func, int state) return 0; if (state == PCI_pm_state_d1 || state == PCI_pm_state_d2) { - uint16 pmc; - pmc = read_pci_config(bus, dev, func, pm_reg + PCI_pm_ctrl, 2); + uint16 pmc = read_pci_config(bus, dev, func, pm_reg + PCI_pm_ctrl, 2); if (state == PCI_pm_state_d1 && !(pmc & PCI_pm_d1supp)) return EIO; if (state == PCI_pm_state_d2 && !(pmc & PCI_pm_d2supp)) @@ -554,9 +554,9 @@ pci_set_power_state(uint8 bus, uint8 dev, uint8 func, int state) write_pci_config(bus, dev, func, pm_reg + PCI_pm_status, 2, cur_status); - if (state == PCI_pm_state_d3 || cur_state == PCI_pm_state_d3) { + if (state == PCI_pm_state_d3 || cur_state == PCI_pm_state_d3) snooze(10 * 1000); - } else if (state == PCI_pm_state_d2 || cur_state == PCI_pm_state_d2) + else if (state == PCI_pm_state_d2 || cur_state == PCI_pm_state_d2) snooze(200); return 0; @@ -572,7 +572,8 @@ pci_set_power_state(uint8 bus, uint8 dev, uint8 func, int state) static void fixup_bridge(uint8 bus, uint8 dev, uint8 func) { - uint16 vendor, device; + uint16 vendor; + uint16 device; vendor = read_pci_config(bus, dev, func, PCI_vendor_id, 2); device = read_pci_config(bus, dev, func, PCI_device_id, 2); @@ -581,37 +582,43 @@ fixup_bridge(uint8 bus, uint8 dev, uint8 func) case PCI_VENDOR_INTEL: switch (device) { case PCI_PRODUCT_INTEL_82443BX_AGP: - case PCI_PRODUCT_INTEL_82443BX_NOAGP: { - /* BIOS bug workaround - * While the datasheet indicates that the only valid setting - * for "Idle/Pipeline DRAM Leadoff Timing (IPLDT)" is 01, - * some BIOS's do not set these correctly, so we check and - * correct if required. - */ - uint16 bcreg = read_pci_config(bus, dev, func, 0x76, 2); - if ((bcreg & 0x0300) != 0x0100) { + case PCI_PRODUCT_INTEL_82443BX_NOAGP: + { + // BIOS bug workaround: + // While the datasheet indicates that the only valid setting + // for "Idle/Pipeline DRAM Leadoff Timing (IPLDT)" is 01, + // some BIOS's do not set these correctly, so we check and + // correct if required. + + uint16 reg = read_pci_config(bus, dev, func, 0x76, 2); + + if ((reg & 0x0300) != 0x0100) { dprintf("Intel 82443BX Host Bridge: Fixing IPDLT setting\n"); - bcreg &= ~0x0300; - bcreg |= 0x100; - write_pci_config(bus, dev, func, 0x76, 2, bcreg); + reg &= ~0x0300; + reg |= 0x100; + write_pci_config(bus, dev, func, 0x76, 2, reg); } break; } } + break; + + default: + break; } } /* Given a vendor/device pairing, do we need to scan through - * the entire set of funtions? normally the return will be 0, - * implying we don't need to, but for some it will be 1 which + * the entire set of funtions? normally the return will be false, + * implying we don't need to, but for some it will be true which * means scan all functions. * This function may seem overkill but it prevents scanning * functions we don't need to and shoudl reduce the possibility of * duplicates being detected. */ -static int +static bool pci_quirk_multifunction(uint16 vendor, uint16 device) { switch (vendor) { @@ -621,63 +628,68 @@ pci_quirk_multifunction(uint16 vendor, uint16 device) case PCI_PRODUCT_INTEL_82371AB_IDE: case PCI_PRODUCT_INTEL_82371AB_USB: case PCI_PRODUCT_INTEL_82371AB_PMC: - return 1; + return true; } } - return 0; + + return false; } /* set_pci_mechanism() * Try to determine which configuration mechanism the PCI Host Bridge * wants to deal with. - * XXX - we really should add code to detect and use a PCI BIOS if one - * exists, and this code then becomes the fallback. For now we'll - * just use this. + * ToDo: we really should add code to detect and use a PCI BIOS + * if one exists, and this code then becomes the fallback. + * For now we'll just use this. */ -static int +static bool set_pci_mechanism(void) { uint32 ckval = 0x80000000; - /* Start by looking for the older and more limited mechanism 2 - * as the test will probably work for mechanism 1 as well. - * - * This code copied/adapted from OpenBSD - */ + + // Start by looking for the older and more limited mechanism 2 + // as the test will probably work for mechanism 1 as well. + // + // This code copied/adapted from OpenBSD. + #define PCI_MODE2_ENABLE 0x0cf8 #define PCI_MODE2_FORWARD 0x0cfa + out8(0, PCI_MODE2_ENABLE); out8(0, PCI_MODE2_FORWARD); + if (in8(PCI_MODE2_ENABLE) == 0 && in8(PCI_MODE2_FORWARD) == 0) { dprintf("PCI_Mechanism 2 test passed\n"); - bus_max_devices = 16; - pci_mode = 2; - return 0; + gMaxBusDevices = 16; + gConfigMechanism = 2; + return true; } - /* If we get here, the first test (for mechanism 2) failed, so there - * is a good chance this one will pass. Basically enable then disable and - * make sure we have the same values. - */ + // If we get here, the first test (for mechanism 2) failed, so there + // is a good chance this one will pass. Basically enable, then disable, + // and make sure we have the same values. + #define PCI_MODE1_ADDRESS 0x0cf8 + out32(ckval, PCI_MODE1_ADDRESS); if (in32(PCI_MODE1_ADDRESS) == ckval) { out32(0, PCI_MODE1_ADDRESS); if (in32(PCI_MODE1_ADDRESS) == 0) { dprintf("PCI_Mechanism 1 test passed\n"); - bus_max_devices = 32; - pci_mode = 1; - return 0; + gMaxBusDevices = 32; + gConfigMechanism = 1; + return true; } } dprintf("PCI: Failed to find a valid PCI Configuration Mechanism!\n" "PCI: disabled\n"); - pci_mode = 0; + gConfigMechanism = 0; - return -1; + return false; } @@ -697,20 +709,19 @@ set_pci_mechanism(void) * -1 if PCI fails the test */ -static int +static bool check_pci(void) { int dev = 0; - /* Scan through the first 16 devices on bus 0 looking for - * a PCI Host Bridge - */ - for (dev = 0; dev < bus_max_devices; dev++) { + // scan thru the first 16 devices on bus 0 looking for a PCI Host Bridge + for (dev = 0; dev < gMaxBusDevices; dev++) { uint8 val = read_pci_config(0, dev, 0, PCI_class_base, 1); if (val == 0x06) - return 0; + return true; } - /* Bit wordy, but it needs to be :( */ + + // Bit wordy, but it needs to be :( dprintf("*** PCI Warning! ***\n" "The PCI sanity check appears to have failed on your system.\n" "This is probably due to the test being used, so please email\n" @@ -718,12 +729,14 @@ check_pci(void) "Your assistance will help improve this test :)\n" "***\n" "PCI will attempt to continue normally.\n"); - return -1; + + return false; } + /* Intel specific * - * See http://www.microsoft.com/HWDEV/busbios/PCIIRQ.htm + * See http://www.microsoft.com/hwdev/archive/BUSBIOS/pciirq.asp * * Intel boards have a PCI IRQ Routing table that contains details of * how things get routed, information we need :( @@ -734,6 +747,7 @@ struct linkmap { uint16 possible_irq; } _PACKED; + struct pir_slot { uint8 bus; uint8 devfunc; @@ -742,6 +756,7 @@ struct pir_slot { uint8 reserved; } _PACKED; + #define PIR_HEADER "$PIR" struct pir_header { @@ -757,14 +772,17 @@ struct pir_header { uint8 cksum; } _PACKED; + struct pir_table { struct pir_header hdr; struct pir_slot slot[1]; } _PACKED; + #define PIR_DEVICE(devfunc) (((devfunc) >> 3) & 0x1f) #define PIR_FUNCTION(devfunc) ((devfunc) & 0x07) + /* find_pir_table * No real magic, just scan through the memory until we find it, * or not! @@ -782,8 +800,8 @@ struct pir_table { static struct pir_table * find_pir_table(void) { - uint32 mem_addr = (uint32)pci_bios_ptr; - int range = 0x10000; + addr mem_addr = gPCI_BIOS_Address; + int range = 0x10000; for (; range > 0; range -= 16, mem_addr += 16) { if (memcmp((void*)mem_addr, PIR_HEADER, 4) == 0) { @@ -795,14 +813,17 @@ find_pir_table(void) for (i = 0; i < size; i++) cksum += ((uint8*)mem_addr)[i]; + if (cksum == 0) return (struct pir_table *)mem_addr; } } } + return NULL; } + #if TRACE_PCI /* print_pir_table * Print out the table to debug output @@ -823,10 +844,12 @@ print_pir_table(struct pir_table *tbl) 'A'+j, tbl->slot[i].linkmap[j].pin, tbl->slot[i].linkmap[j].possible_irq); } + dprintf("*** end of table\n"); } #endif + /* Scanning for Devices * ==================== * @@ -841,8 +864,8 @@ print_pir_table(struct pir_table *tbl) * pci_probe_device() sends pci_bridges to pci_bridge() to be setup * and deals with type 0 (generic) devices itself. * - * NB presently we don't really cope with type 2 (Cardbus) devices - * but will need to eventually. + * ToDo: currently we don't really cope with type 2 (Cardbus) devices + * but will need to eventually. */ @@ -851,10 +874,6 @@ print_pir_table(struct pir_table *tbl) * and scan the bus it defines. * The bus is initially taken off-line, scanned and then put back on-line * - * NB We increment the pci_max_bus value before we use mybus in the following - * code and pci_max_bus is incremented before we recurse to preserve the - * correct relationships with nubering. - * * We initally set the subordinate_bus to 0xff and then adjust it to the max * once we've scanned the bus on the other side of the bridge. See the URL * above for information on why this is done. @@ -863,96 +882,98 @@ print_pir_table(struct pir_table *tbl) static void pci_bridge(uint8 bus, uint8 dev, uint8 func) { - uint16 command; - uint8 mybus; - struct pci_device *pcid; - struct pci_bus *pcib; - pci_info *pcii; + uint16 command; + uint8 bridge; + pci_device *pciDevice; + pci_bus *pciBus; + pci_info *pciInfo; TRACE(("pci_bridge()\n")); command = read_pci_config(bus, dev, func, PCI_command, 2); - command &= ~ 0x03; + command &= ~0x03; write_pci_config(bus, dev, func, PCI_command, 2, command); - pci_max_bus += 1; - mybus = pci_max_bus; + // gMaxBusDetected is incremented before we use bridge below and + // before we recurse to preserve the correct relationships with numbering. + bridge = ++gMaxBusDetected; write_pci_config(bus, dev, func, PCI_primary_bus, 1, bus); - write_pci_config(bus, dev, func, PCI_secondary_bus, 1, mybus); + write_pci_config(bus, dev, func, PCI_secondary_bus, 1, bridge); write_pci_config(bus, dev, func, PCI_subordinate_bus, 1, 0xff); - dprintf("PCI-PCI bridge at %d:%d:%d configured as bus %d\n", bus, dev, func, mybus); - pci_scan_bus(mybus); + dprintf("PCI-PCI bridge at %d:%d:%d configured as bus %d\n", bus, dev, func, bridge); + pci_scan_bus(bridge); - write_pci_config(bus, dev, func, PCI_subordinate_bus, 1, pci_max_bus); + write_pci_config(bus, dev, func, PCI_subordinate_bus, 1, gMaxBusDetected); - pcii = (pci_info *)malloc(sizeof(pci_info)); - if (!pcii) + pciInfo = (pci_info *)malloc(sizeof(pci_info)); + if (!pciInfo) goto pci_bridge_skip_infolist; - pcid = (struct pci_device *)malloc(sizeof(struct pci_device)); - if (!pcid) { - free(pcii); + + pciDevice = (pci_device *)malloc(sizeof(pci_device)); + if (!pciDevice) { + free(pciInfo); goto pci_bridge_skip_infolist; } - pcib = (struct pci_bus *)malloc(sizeof(struct pci_bus)); - if (!pcib) { - free(pcii); - free(pcid); + pciBus = (pci_bus *)malloc(sizeof(pci_bus)); + if (!pciBus) { + free(pciInfo); + free(pciDevice); goto pci_bridge_skip_infolist; } - pcid->info = pcii; - pcid->type = PCI_BRIDGE; - pcid->next = NULL; + pciDevice->info = pciInfo; + pciDevice->type = PCI_BRIDGE; + pciDevice->next = NULL; - pcib->info = pcii; - pcib->next = NULL; + pciBus->info = pciInfo; + pciBus->next = NULL; - pcii->bus = bus; - pcii->device = dev; - pcii->function = func; + pciInfo->bus = bus; + pciInfo->device = dev; + pciInfo->function = func; - fill_basic_pci_structure(pcii); + fill_basic_pci_structure(pciInfo); - pcii->u.h1.rom_base_pci = read_pci_config(bus, dev, func, PCI_bridge_rom_base, 4); - pcii->u.h1.primary_bus = read_pci_config(bus, dev, func, PCI_primary_bus, 1); - pcii->u.h1.secondary_bus = read_pci_config(bus, dev, func, PCI_secondary_bus, 1); - pcii->u.h1.secondary_latency = read_pci_config(bus, dev, func, PCI_secondary_latency, 1); - pcii->u.h1.secondary_status = read_pci_config(bus, dev, func, PCI_secondary_status, 2); - pcii->u.h1.subordinate_bus = read_pci_config(bus, dev, func, PCI_subordinate_bus, 1); - pcii->u.h1.memory_base = read_pci_config(bus, dev, func, PCI_memory_base, 2); - pcii->u.h1.memory_limit = read_pci_config(bus, dev, func, PCI_memory_limit, 2); - pcii->u.h1.prefetchable_memory_base = read_pci_config(bus, dev, func, PCI_prefetchable_memory_base, 2); - pcii->u.h1.prefetchable_memory_limit = read_pci_config(bus, dev, func, PCI_prefetchable_memory_limit, 2); - pcii->u.h1.bridge_control = read_pci_config(bus, dev, func, PCI_bridge_control, 1); - pcii->u.h1.subsystem_vendor_id = read_pci_config(bus, dev, func, PCI_sub_vendor_id_1, 2); - pcii->u.h1.subsystem_id = read_pci_config(bus, dev, func, PCI_sub_device_id_1, 2); - pcii->u.h1.interrupt_line = read_pci_config(bus, dev, func, PCI_interrupt_line, 1); - pcii->u.h1.interrupt_pin = read_pci_config(bus, dev, func, PCI_interrupt_pin, 1) & PCI_pin_mask; + pciInfo->u.h1.rom_base_pci = read_pci_config(bus, dev, func, PCI_bridge_rom_base, 4); + pciInfo->u.h1.primary_bus = read_pci_config(bus, dev, func, PCI_primary_bus, 1); + pciInfo->u.h1.secondary_bus = read_pci_config(bus, dev, func, PCI_secondary_bus, 1); + pciInfo->u.h1.secondary_latency = read_pci_config(bus, dev, func, PCI_secondary_latency, 1); + pciInfo->u.h1.secondary_status = read_pci_config(bus, dev, func, PCI_secondary_status, 2); + pciInfo->u.h1.subordinate_bus = read_pci_config(bus, dev, func, PCI_subordinate_bus, 1); + pciInfo->u.h1.memory_base = read_pci_config(bus, dev, func, PCI_memory_base, 2); + pciInfo->u.h1.memory_limit = read_pci_config(bus, dev, func, PCI_memory_limit, 2); + pciInfo->u.h1.prefetchable_memory_base = read_pci_config(bus, dev, func, PCI_prefetchable_memory_base, 2); + pciInfo->u.h1.prefetchable_memory_limit = read_pci_config(bus, dev, func, PCI_prefetchable_memory_limit, 2); + pciInfo->u.h1.bridge_control = read_pci_config(bus, dev, func, PCI_bridge_control, 1); + pciInfo->u.h1.subsystem_vendor_id = read_pci_config(bus, dev, func, PCI_sub_vendor_id_1, 2); + pciInfo->u.h1.subsystem_id = read_pci_config(bus, dev, func, PCI_sub_device_id_1, 2); + pciInfo->u.h1.interrupt_line = read_pci_config(bus, dev, func, PCI_interrupt_line, 1); + pciInfo->u.h1.interrupt_pin = read_pci_config(bus, dev, func, PCI_interrupt_pin, 1) & PCI_pin_mask; { - struct pci_device *pd = pci_devices; + pci_device *pd = gPCI_Devices; while (pd && pd->next) pd = pd->next; if (pd) - pd->next = pcid; + pd->next = pciDevice; else - pci_devices = pcid; + gPCI_Devices = pciDevice; } { - struct pci_bus *pb = pci_busses; + pci_bus *pb = gPCI_Busses; while (pb && pb->next) pb = pb->next; if (pb) - pb->next = pcib; + pb->next = pciBus; else - pci_busses = pcib; + gPCI_Busses = pciBus; } - show_pci_details(pcii); + show_pci_details(pciInfo); pci_bridge_skip_infolist: command |= 0x03; @@ -964,28 +985,31 @@ pci_bridge_skip_infolist: /** This is a very, very brief 2 liner for a device... */ static void -debug_show_device(pci_info *pcii) +debug_show_device(pci_info *pciInfo) { - uint16 status = read_pci_config(pcii->bus, pcii->device, pcii->function, PCI_status, 2); + uint8 bus = pciInfo->bus; + uint8 dev = pciInfo->device; + uint8 func = pciInfo->function; - dprintf("device @ %d:%d:%d > %s [%04x:%04x]\n", pcii->bus, pcii->device, - pcii->function, - decode_class(pcii->class_base, pcii->class_sub), - pcii->vendor_id, pcii->device_id); + uint16 status = read_pci_config(bus, dev, func, PCI_status, 2); + + dprintf("device @ %d:%d:%d > %s [%04x:%04x]\n", bus, dev, func, + decode_class(pciInfo->class_base, pciInfo->class_sub), + pciInfo->vendor_id, pciInfo->device_id); if ((status & PCI_status_capabilities)) { dprintf("Capabilities: "); - if (pci_get_capability(pcii->bus, pcii->device, pcii->function, PCI_cap_id_agp, NULL)) + if (pci_get_capability(bus, dev, func, PCI_cap_id_agp, NULL)) dprintf("AGP "); - if (pci_get_capability(pcii->bus, pcii->device, pcii->function, PCI_cap_id_pm, NULL)) + if (pci_get_capability(bus, dev, func, PCI_cap_id_pm, NULL)) dprintf("Pwr Mgmt "); - if (pci_get_capability(pcii->bus, pcii->device, pcii->function, PCI_cap_id_vpd, NULL)) + if (pci_get_capability(bus, dev, func, PCI_cap_id_vpd, NULL)) dprintf("VPD "); - if (pci_get_capability(pcii->bus, pcii->device, pcii->function, PCI_cap_id_slotid, NULL)) + if (pci_get_capability(bus, dev, func, PCI_cap_id_slotid, NULL)) dprintf("slotID "); - if (pci_get_capability(pcii->bus, pcii->device, pcii->function, PCI_cap_id_msi, NULL)) + if (pci_get_capability(bus, dev, func, PCI_cap_id_msi, NULL)) dprintf("MSI "); - if (pci_get_capability(pcii->bus, pcii->device, pcii->function, PCI_cap_id_hotplug, NULL)) + if (pci_get_capability(bus, dev, func, PCI_cap_id_hotplug, NULL)) dprintf("hotplug "); dprintf("\n"); } else @@ -996,10 +1020,11 @@ debug_show_device(pci_info *pcii) static void pci_device_probe(uint8 bus, uint8 dev, uint8 func) { - uint8 base_class, sub_class; + uint8 base_class; + uint8 sub_class; uint8 type; - pci_info *pcii; - struct pci_device *pcid; + pci_info *pciInfo; + pci_device *pciDevice; TRACE(("pci_device_probe()\n")); @@ -1022,50 +1047,51 @@ pci_device_probe(uint8 bus, uint8 dev, uint8 func) } } - /* If we get here then it's not a bridge, so we add it... */ - pcii = (pci_info *)malloc(sizeof(pci_info)); - if (!pcii) + // If we get here then it's not a bridge, so we add it... + pciInfo = (pci_info *)malloc(sizeof(pci_info)); + if (!pciInfo) return; - pcid = (struct pci_device *)malloc(sizeof(struct pci_device)); - if (!pcid) { - free(pcii); + + pciDevice = (pci_device *)malloc(sizeof(pci_device)); + if (!pciDevice) { + free(pciInfo); return; } - pcid->info = pcii; - pcid->type = PCI_DEVICE; - pcid->next = NULL; + pciDevice->info = pciInfo; + pciDevice->type = PCI_DEVICE; + pciDevice->next = NULL; - pcii->bus = bus; - pcii->device = dev; - pcii->function = func; + pciInfo->bus = bus; + pciInfo->device = dev; + pciInfo->function = func; - fill_basic_pci_structure(pcii); + fill_basic_pci_structure(pciInfo); - if (pcii->class_base == PCI_bridge && pcii->class_sub == PCI_host) - pcid->type = PCI_HOST_BUS; + if (pciInfo->class_base == PCI_bridge && pciInfo->class_sub == PCI_host) + pciDevice->type = PCI_HOST_BUS; - pcii->u.h0.cardbus_cis = read_pci_config(bus, dev, func, PCI_cardbus_cis, 4); - pcii->u.h0.subsystem_id = read_pci_config(bus, dev, func, PCI_subsystem_id, 2); - pcii->u.h0.subsystem_vendor_id = read_pci_config(bus, dev, func, PCI_subsystem_vendor_id, 2); - pcii->u.h0.rom_base_pci = read_pci_config(bus, dev, func, PCI_rom_base, 4); - pcii->u.h0.interrupt_line = read_pci_config(bus, dev, func, PCI_interrupt_line, 1); - pcii->u.h0.interrupt_pin = read_pci_config(bus, dev, func, PCI_interrupt_pin, 1) & PCI_pin_mask; + pciInfo->u.h0.cardbus_cis = read_pci_config(bus, dev, func, PCI_cardbus_cis, 4); + pciInfo->u.h0.subsystem_id = read_pci_config(bus, dev, func, PCI_subsystem_id, 2); + pciInfo->u.h0.subsystem_vendor_id = read_pci_config(bus, dev, func, PCI_subsystem_vendor_id, 2); + pciInfo->u.h0.rom_base_pci = read_pci_config(bus, dev, func, PCI_rom_base, 4); + pciInfo->u.h0.interrupt_line = read_pci_config(bus, dev, func, PCI_interrupt_line, 1); + pciInfo->u.h0.interrupt_pin = read_pci_config(bus, dev, func, PCI_interrupt_pin, 1) & PCI_pin_mask; - /* now add to list (at end) */ + // now add to list (at end) { - struct pci_device *pd = pci_devices; + pci_device *pd = gPCI_Devices; while (pd && pd->next) pd = pd->next; if (pd) - pd->next = pcid; + pd->next = pciDevice; else - pci_devices = pcid; + gPCI_Devices = pciDevice; } pci_set_power_state(bus, dev, func, PCI_pm_state_d0); - debug_show_device(pcii); + debug_show_device(pciInfo); } @@ -1083,22 +1109,22 @@ pci_device_probe(uint8 bus, uint8 dev, uint8 func) static void pci_scan_bus(uint8 bus) { - uint8 dev = 0, func = 0; - uint16 vend = 0; + uint8 dev = 0; + uint8 func = 0; TRACE(("pci_scan_bus()\n")); for (dev = 0; dev < 32; dev++) { - vend = read_pci_config(bus, dev, 0, PCI_vendor_id, 2); - if (vend != 0xffff) { + uint16 vendorID = read_pci_config(bus, dev, 0, PCI_vendor_id, 2); + if (vendorID != 0xffff) { uint16 device = read_pci_config(bus, dev, func, PCI_device_id, 2); - uint8 type = read_pci_config(bus, dev, func, PCI_header_type, 1); - uint8 nfunc = 8; + uint8 type = read_pci_config(bus, dev, func, PCI_header_type, 1); + uint8 nfunc = 8; type &= PCI_header_type_mask; if ((type & PCI_multifunction) == 0 - && !pci_quirk_multifunction(vend, device)) + && !pci_quirk_multifunction(vendorID, device)) nfunc = 1; for (func = 0; func < nfunc; func++) @@ -1115,67 +1141,69 @@ scan_pci(void) TRACE(("scan_pci()\n")); - /* We can have up to 255 busses */ + // We can have up to 255 busses for (bus = 0; bus < 255; bus++) { - /* Each bus can have up to 'bus_max_devices' devices on it */ - for (dev = 0; dev <= bus_max_devices; dev++) { - /* Each device can have up to 8 functions */ + + // Each bus can have up to 'gMaxBusDevices' devices on it + for (dev = 0; dev <= gMaxBusDevices; dev++) { uint16 sv_vendor_id = 0, sv_device_id = 0; + // Each device can have up to 8 functions for (func = 0; func < 8; func++) { - pci_info *pcii = NULL; + pci_info *pciInfo = NULL; uint16 vendor_id = read_pci_config(bus, dev, func, 0, 2); uint16 device_id; - uint8 offset; - /* If we get 0xffff then there is no device here. As there can't - * be any gaps in function allocation this tells us that we - * can move onto the next device/bus - */ + uint8 offset; + + // If we get 0xffff then there is no device here. As there can't + // be any gaps in function allocation this tells us that we + // can move onto the next device/bus if (vendor_id == 0xffff) break; device_id = read_pci_config(bus, dev, func, PCI_device_id, 2); - /* Is this a new device? As we're scanning the functions here, many devices - * will supply identical information for all 8 accesses! Try to catch this and - * simply move past duplicates. We need to continue scanning in case we miss - * a different device at the end. - * XXX - is this correct???? - */ - if (vendor_id == sv_vendor_id && sv_device_id == device_id) { - /* It's a duplicate */ + // Is this a new device? As we're scanning the functions here, many devices + // will supply identical information for all 8 accesses! Try to catch this and + // simply move past duplicates. We need to continue scanning in case we miss + // a different device at the end. + // + // XXX - is this correct???? + // + if (vendor_id == sv_vendor_id && sv_device_id == device_id) + // it's a duplicate continue; - } + sv_vendor_id = vendor_id; sv_device_id = device_id; - /* At present we will add a device to our list if we get here, - * but we may want to review if we need to add 8 version of the - * same device if only the functions differ? - */ - if ((pcii = (pci_info *)malloc(sizeof(pci_info))) == NULL) { + // At present we will add a device to our list if we get here, + // but we may want to review if we need to add 8 version of the + // same device if only the functions differ? + if ((pciInfo = (pci_info *)malloc(sizeof(pci_info))) == NULL) { dprintf("Failed to get memory for a pic_info structure in scan_pci\n"); return; } if (pci_get_capability(bus, dev, func, PCI_cap_id_agp, &offset)) dprintf("Device @ %d:%d:%d has AGP capability\n", bus, dev, func); + pci_set_power_state(bus, dev, func, PCI_pm_state_d0); - /* basic header */ - pcii->bus = bus; - pcii->device = dev; - pcii->function = func; - pcii->vendor_id = vendor_id; - pcii->device_id = device_id; + // basic header + pciInfo->bus = bus; + pciInfo->device = dev; + pciInfo->function = func; + pciInfo->vendor_id = vendor_id; + pciInfo->device_id = device_id; - pcii->revision = read_pci_config(bus, dev, func, PCI_revision, 1); - pcii->class_api = read_pci_config(bus, dev, func, PCI_class_api, 1); - pcii->class_sub = read_pci_config(bus, dev, func, PCI_class_sub, 1); - pcii->class_base = read_pci_config(bus, dev, func, PCI_class_base, 1); + pciInfo->revision = read_pci_config(bus, dev, func, PCI_revision, 1); + pciInfo->class_api = read_pci_config(bus, dev, func, PCI_class_api, 1); + pciInfo->class_sub = read_pci_config(bus, dev, func, PCI_class_sub, 1); + pciInfo->class_base = read_pci_config(bus, dev, func, PCI_class_base, 1); - pcii->header_type = read_pci_config(bus, dev, func, PCI_header_type, 1); - pcii->header_type &= PCI_header_type_mask; + pciInfo->header_type = read_pci_config(bus, dev, func, PCI_header_type, 1); + pciInfo->header_type &= PCI_header_type_mask; } } } @@ -1183,25 +1211,25 @@ scan_pci(void) static void -fill_basic_pci_structure(pci_info *pcii) +fill_basic_pci_structure(pci_info *pciInfo) { - uint8 bus = pcii->bus, dev = pcii->device, func = pcii->function; + uint8 bus = pciInfo->bus, dev = pciInfo->device, func = pciInfo->function; uint8 int_line = 0, int_pin = 0; - pcii->vendor_id = read_pci_config(bus, dev, func, PCI_vendor_id, 2); - pcii->device_id = read_pci_config(bus, dev, func, PCI_device_id, 2); + pciInfo->vendor_id = read_pci_config(bus, dev, func, PCI_vendor_id, 2); + pciInfo->device_id = read_pci_config(bus, dev, func, PCI_device_id, 2); - pcii->revision = read_pci_config(bus, dev, func, PCI_revision, 1); - pcii->class_api = read_pci_config(bus, dev, func, PCI_class_api, 1); - pcii->class_sub = read_pci_config(bus, dev, func, PCI_class_sub, 1); - pcii->class_base = read_pci_config(bus, dev, func, PCI_class_base, 1); + pciInfo->revision = read_pci_config(bus, dev, func, PCI_revision, 1); + pciInfo->class_api = read_pci_config(bus, dev, func, PCI_class_api, 1); + pciInfo->class_sub = read_pci_config(bus, dev, func, PCI_class_sub, 1); + pciInfo->class_base = read_pci_config(bus, dev, func, PCI_class_base, 1); - pcii->header_type = read_pci_config(bus, dev, func, PCI_header_type, 1); - pcii->header_type &= PCI_header_type_mask; + pciInfo->header_type = read_pci_config(bus, dev, func, PCI_header_type, 1); + pciInfo->header_type &= PCI_header_type_mask; - pcii->latency = read_pci_config(bus, dev, func, PCI_latency, 1); - pcii->bist = read_pci_config(bus, dev, func, PCI_bist, 1); - pcii->line_size = read_pci_config(bus, dev, func, PCI_line_size, 1); + pciInfo->latency = read_pci_config(bus, dev, func, PCI_latency, 1); + pciInfo->bist = read_pci_config(bus, dev, func, PCI_bist, 1); + pciInfo->line_size = read_pci_config(bus, dev, func, PCI_line_size, 1); int_line = read_pci_config(bus, dev, func, PCI_interrupt_line, 1); int_pin = read_pci_config(bus, dev, func, PCI_interrupt_pin, 1); @@ -1209,49 +1237,53 @@ fill_basic_pci_structure(pci_info *pcii) } -/* XXX - check the return values from this function. */ +/* ToDo: check the return values from this function. */ static long get_nth_pci_info(long index, pci_info *copyto) { - /* We copy the index and then decrement it. - * We also set the start found_pci_device pointer to - * the first device found and inserted. - * XXX - see discussion below. - */ - long iter = index; - struct pci_device *pd = pci_devices; + // We copy the index and then decrement it. + // We also set the start found_pci_device pointer + // to the first device found and inserted. + // XXX - see discussion below. + + long count = index; + pci_device *pd = gPCI_Devices; TRACE(("pci_nth_pci_info()\n")); - /* iterate through the list until we have iter == 0 - * NB we go in "reverse" as the devices are inserted into the - * list at the start, so going "forward" would give us the last - * device first. - * XXX - do we want to reverse this decision and go "forwards"? - * this should reduce the number of tries we make to find - * a "device" as the system devices are the first ones found - * and therefore the last ones to be returned. - * XXX - if we do decide to reverse the order we need to be very - * careful about which function # gets found first and returned. - */ - while (iter-- > 0 && pd) + // iterate through the list until we have count == 0 + // Note: we go in "reverse" as the devices are inserted into the list + // at the start, so going "forward" would give us the last device first. + // + // XXX - do we want to reverse this decision and go "forwards"? + // this should reduce the number of tries we make to find + // a "device" as the system devices are the first ones found + // and therefore the last ones to be returned. + // + // XXX - if we do decide to reverse the order we need to be very + // careful about which function # gets found first and returned. + while (count-- > 0 && pd) pd = pd->next; - /* 2 cases we bail here. - * 1) we don't have enough devices to fulfill the request - * e.g. user asked for dev #31 but we only have 30 - * 2) The found_device_structure has a NULL pointer for - * info, which would cause a segfault when we try to memcpy! - */ - if (iter > 0 || !pd || !pd->info) + if (count > 0 || !pd || !pd->info) + // we are bailing out here because either: + // a) we don't have enough devices to fulfill the request + // e.g. user asked for dev #31 but we only have 30 + // b) The found_device_structure has a NULL pointer for + // info, which would cause a segfault when we try to memcpy! return B_DEV_ID_ERROR; - memcpy(copyto, pd->info, sizeof(pci_info)); + memcpy(copyto, pd->info, sizeof(pd->info)); return 0; } -/* I/O routines */ + + +/* + * I/O routines + * + */ static uint8 pci_read_io_8(int mapped_io_addr) @@ -1295,7 +1327,9 @@ pci_write_io_32(int mapped_io_addr, uint32 value) } + /* pci_module_init + * * This is where we start all the PCI work, or not as the case may be. * We start by trying to detect and set the correct configuration mechanism * to use. We don't handle PCI BIOS's as that method seems to be falling out @@ -1304,12 +1338,12 @@ pci_write_io_32(int mapped_io_addr, uint32 value) * Next we try to check if we have working PCI on this machine. check_pci() * isn't the smartest routine as it essentially just looks for a Host-PCI * bridge, but it will show us if we can continue. - * NB Until this has been tested with a wider audience we don't consider + * Note: Until this has been tested with a wider audience we don't consider * success/failure here but spew a large debug message and try to continue. * XXX - once we're happy with check_pci() make failing a criminal offense! * * Next we check to see if we can find a PIR table. - * NB This is Intel specific and currently included here as a test. + * Note: This is Intel specific and currently included here as a test. * * Finally we scan for devices starting at bus 0. */ @@ -1317,28 +1351,36 @@ pci_write_io_32(int mapped_io_addr, uint32 value) static void pci_module_init(void) { - struct pir_table *pirt = NULL; + + struct pir_table *pirTable = NULL; TRACE(("pci_module_init()\n")); - if (set_pci_mechanism() == -1) { + // ToDo: remove this dummy if statement -- it's only here to + // shut up the compiler which complains about 'scan_pci' + // being defined but not used... + if (0) + scan_pci(); + + + if (!set_pci_mechanism()) return; - } check_pci(); - pci_region = vm_map_physical_memory(vm_get_kernel_aspace_id(), - "pci_bios", &pci_bios_ptr, + gPCI_Region = vm_map_physical_memory(vm_get_kernel_aspace_id(), + "pci_bios", + (void **)&gPCI_BIOS_Address, REGION_ADDR_ANY_ADDRESS, 0x10000, LOCK_RO | LOCK_KERNEL, (addr)0xf0000); - pirt = find_pir_table(); - if (pirt) { + pirTable = find_pir_table(); + if (pirTable) { dprintf("PCI IRQ Routing table found\n"); #if TRACE_PCI - print_pir_table(pirt); + print_pir_table(pirTable); #endif } @@ -1353,26 +1395,26 @@ pci_module_init(void) static void pci_module_uninit(void) { - vm_delete_region(vm_get_kernel_aspace_id(), pci_region); + vm_delete_region(vm_get_kernel_aspace_id(), gPCI_Region); } static int32 std_ops(int32 op, ...) { - switch(op) { + switch (op) { case B_MODULE_INIT: - dprintf( "PCI: init\n" ); + dprintf("PCI: init\n"); pci_module_init(); - break; + return B_OK; + case B_MODULE_UNINIT: - dprintf( "PCI: uninit\n" ); + dprintf("PCI: uninit\n"); pci_module_uninit(); - break; - default: - return EINVAL; + return B_OK; } - return B_OK; + + return EINVAL; } @@ -1398,6 +1440,7 @@ struct pci_module_info pci_module = { NULL, // &ram_address }; + module_info *modules[] = { (module_info *)&pci_module, NULL