From 645ce10ed49ccf0d6a53f2a5f07f09cd41f17d23 Mon Sep 17 00:00:00 2001 From: stefan Date: Sat, 27 Nov 2010 17:28:32 +0000 Subject: [PATCH] - cleanup pci code - add function to determine the iobase address and the irq number of a specific device git-svn-id: http://svn.lfbs.rwth-aachen.de/svn/scc/trunk/MetalSVM@291 315a16e6-25f9-4109-90ae-ca3045a26c18 --- arch/x86/include/asm/pci.h | 13 ++++++ arch/x86/kernel/pci.c | 84 +++++++++++++++++++++++--------------- arch/x86/kernel/pcihdr.h | 4 +- 3 files changed, 64 insertions(+), 37 deletions(-) diff --git a/arch/x86/include/asm/pci.h b/arch/x86/include/asm/pci.h index a8f70e00..4fa0c07d 100644 --- a/arch/x86/include/asm/pci.h +++ b/arch/x86/include/asm/pci.h @@ -24,7 +24,20 @@ extern "C" { #endif +/* + * initialize the pci environment + */ int pci_init(void); + +/* + * determins the iobase address and the interrupt number + * of a specific device + */ +int pci_get_device_info(uint32_t vendor_id, uint32_t device_id, uint32_t* iobase, uint32_t* irq); + +/* + * prints informations of existing pci adapter + */ int print_pci_adapters(void); #ifdef __cplusplus diff --git a/arch/x86/kernel/pci.c b/arch/x86/kernel/pci.c index d8232e5b..e51d7fa1 100644 --- a/arch/x86/kernel/pci.c +++ b/arch/x86/kernel/pci.c @@ -19,6 +19,7 @@ #include #include +#include #include #include @@ -42,23 +43,22 @@ #define PHYS_IO_MEM_START 0 #define PCI_MEM 0 #define PCI_INTA 0 -#define PCI_NSLOTS 22 -#define PCI_NBUS 0 +#define PCI_NSLOTS 22 +#define PCI_NBUS 0 -#define PCI_CONF_ADDR_REG 0xcf8 -#define PCI_CONF_FRWD_REG 0xcf8 -#define PCI_CONF_DATA_REG 0xcfc +#define PCI_CONF_ADDR_REG 0xcf8 +#define PCI_CONF_FRWD_REG 0xcf8 +#define PCI_CONF_DATA_REG 0xcfc -#define PCI_IO_CONF_START 0xc000 +#define PCI_IO_CONF_START 0xc000 -#define MAX_BUS 16 -#define MAX_SLOTS 32 +#define MAX_BUS 16 +#define MAX_SLOTS 32 -static int mechanism = 0; -static int initialized = 0; -static int adapters[MAX_BUS][MAX_SLOTS]; +static uint32_t mechanism = 0; +static uint32_t adapters[MAX_BUS][MAX_SLOTS] = {[0 ... MAX_BUS-1][0 ... MAX_SLOTS-1] = -1}; -static void pci_conf_write(int bus, int slot, int off, int val) +static void pci_conf_write(uint32_t bus, uint32_t slot, uint32_t off, uint32_t val) { if (mechanism == 1) { outportl(PCI_CONF_FRWD_REG, bus); @@ -71,9 +71,9 @@ static void pci_conf_write(int bus, int slot, int off, int val) } } -static int pci_conf_read(int bus, int slot, int off) +static uint32_t pci_conf_read(uint32_t bus, uint32_t slot, uint32_t off) { - unsigned int data = -1; + uint32_t data = -1; outportl(PCI_CONF_ADDR_REG, (0x80000000 | (bus << 16) | (slot << 11) | off)); @@ -84,27 +84,23 @@ static int pci_conf_read(int bus, int slot, int off) outportl(PCI_CONF_ADDR_REG, 0xf0); data = inportl(PCI_IO_CONF_START | (slot << 8) | off); if (data == 0xffffffff) - return (data); + return data; if (!mechanism) mechanism = 1; } else if (!mechanism) mechanism = 2; - return (data); + return data; } -static int pci_what_irq(int bus, int slot, int intx) +static inline uint32_t pci_what_irq(uint32_t bus, uint32_t slot) { return pci_conf_read(bus, slot, PCI_CFIT) & 0xff; } -static int find_pci_adapters(void) +int pci_init(void) { - int slot, bus; - - if (initialized) - return 0; - initialized = 1; + uint32_t slot, bus; for (bus = 0; bus < MAX_BUS; bus++) for (slot = 0; slot < MAX_SLOTS; slot++) @@ -113,19 +109,39 @@ static int find_pci_adapters(void) return 0; } -int pci_init(void) +int pci_get_device_info(uint32_t vendor_id, uint32_t device_id, uint32_t* iobase, uint32_t* irq) { - memset(adapters, -1, MAX_BUS*MAX_SLOTS*sizeof(int)); - return find_pci_adapters(); + uint32_t slot, bus; + + if (!iobase || !irq) + return -EINVAL; + + if (!mechanism) + pci_init(); + + for (bus = 0; bus < MAX_BUS; bus++) { + for (slot = 0; slot < MAX_SLOTS; slot++) { + if (adapters[bus][slot] != -1) { + if (((adapters[bus][slot] & 0xffff) == vendor_id) && + (((adapters[bus][slot] & 0xffff0000) >> 16) == device_id)) { + *iobase = pci_conf_read(bus, slot, PCI_CBIO); + *irq = pci_what_irq(bus, slot); + return 0; + } + } + } + } + + return -EINVAL; } int print_pci_adapters(void) { - int slot, bus; - int i, counter = 0; + uint32_t slot, bus; + uint32_t i, counter = 0; - if (!initialized) - return -1; + if (!mechanism) + pci_init(); for (bus = 0; bus < MAX_BUS; bus++) { for (slot = 0; slot < MAX_SLOTS; slot++) { @@ -136,16 +152,16 @@ int print_pci_adapters(void) counter, adapters[bus][slot] & 0xffff, (adapters[bus][slot] & 0xffff0000) >> 16); - for (i = 0; i < PCI_VENTABLE_LEN; i++) { + for (i=0; i> 16) == PciDevTable[i].DevId) { kprintf diff --git a/arch/x86/kernel/pcihdr.h b/arch/x86/kernel/pcihdr.h index c5f6f7a1..1a5ebaaa 100644 --- a/arch/x86/kernel/pcihdr.h +++ b/arch/x86/kernel/pcihdr.h @@ -1267,7 +1267,7 @@ static const PCI_DEVTABLE PciDevTable [] = { 0x10E8, 0x811A, "PCI-DSlink", "PCI-IEEE1355-DS-DE interface" } , { 0x10EB, 0x0101, "3GA", "64 bit graphics processor" } , { 0x10EC, 0x8029, "RTL8029", "NE2000 compatible Ethernet" } , - { 0x10ec, 8139, "RTL8139", "Fast ethernet" } , + { 0x10ec, 0x8139, "RTL8139", "Fast ethernet" } , { 0x10ED, 0x7310, "V7310", "VGA Video Overlay Adapter" } , { 0x10F0, 0xA800, "VCL-P", "Graphics board" } , { 0x10F0, 0xB300, "VCL-M", "graphics board" } , @@ -1833,5 +1833,3 @@ static const char * PciDevSelFlags [] = // Use this value for loop control during searching: #define PCI_DEVSELFLAGS_LEN (sizeof(PciDevSelFlags)/sizeof(char *)) - -