From 3e01fbad6853b465064e78fd1b0b24bb557a24d6 Mon Sep 17 00:00:00 2001 From: Stefan Lankes Date: Thu, 26 Jul 2012 09:07:20 +0200 Subject: [PATCH] add a more flexible interface to determine PCI information => now, we determine also the size of the IO address space --- arch/x86/include/asm/pci.h | 11 ++++++++--- arch/x86/kernel/pci.c | 26 ++++++++++++++++++++++---- 2 files changed, 30 insertions(+), 7 deletions(-) diff --git a/arch/x86/include/asm/pci.h b/arch/x86/include/asm/pci.h index 9afcd43e..18ec69f0 100644 --- a/arch/x86/include/asm/pci.h +++ b/arch/x86/include/asm/pci.h @@ -33,6 +33,12 @@ extern "C" { #endif +typedef struct { + uint32_t base[6]; + uint32_t size[6]; + uint32_t irq; +} pci_info_t; + /** @brief Initialize the PCI environment */ int pci_init(void); @@ -41,14 +47,13 @@ int pci_init(void); * * @param vendor_id The device's vendor ID * @param device_id the device's ID - * @param iobase Pointer to a 4 byte variable where the determined IObase address will be stored - * @param irq Pointer to a 4 byte variable where the determined IRQ number will be stored + * @param info Pointer to the record pci_info_t where among other the IObase address will be stored * * @return * - 0 on success * - -EINVAL (-22) on failure */ -int pci_get_device_info(uint32_t vendor_id, uint32_t device_id, uint32_t* iobase, uint32_t* irq); +int pci_get_device_info(uint32_t vendor_id, uint32_t device_id, pci_info_t* info); /** @brief Print information of existing pci adapters * diff --git a/arch/x86/kernel/pci.c b/arch/x86/kernel/pci.c index a5c0d00c..10efba7b 100644 --- a/arch/x86/kernel/pci.c +++ b/arch/x86/kernel/pci.c @@ -103,6 +103,23 @@ static inline uint32_t pci_what_iobase(uint32_t bus, uint32_t slot) return pci_conf_read(bus, slot, PCI_CBIO) & 0xFFFFFFFC; } +static inline uint32_t pci_what_size(uint32_t bus, uint32_t slot) +{ + uint32_t tmp, ret; + + // backup the original value + tmp = pci_conf_read(bus, slot, PCI_CBIO); + + // determine size + pci_conf_write(bus, slot, PCI_CBIO, 0xFFFFFFFF); + ret = ~pci_conf_read(bus, slot, PCI_CBIO) + 1; + + // restore original value + pci_conf_write(bus, slot, PCI_CBIO, tmp); + + return ret; +} + int pci_init(void) { uint32_t slot, bus; @@ -114,11 +131,11 @@ int pci_init(void) return 0; } -int pci_get_device_info(uint32_t vendor_id, uint32_t device_id, uint32_t* iobase, uint32_t* irq) +int pci_get_device_info(uint32_t vendor_id, uint32_t device_id, pci_info_t* info) { uint32_t slot, bus; - if (!iobase || !irq) + if (!info) return -EINVAL; if (!mechanism) @@ -129,8 +146,9 @@ int pci_get_device_info(uint32_t vendor_id, uint32_t device_id, uint32_t* iobase if (adapters[bus][slot] != -1) { if (((adapters[bus][slot] & 0xffff) == vendor_id) && (((adapters[bus][slot] & 0xffff0000) >> 16) == device_id)) { - *iobase = pci_what_iobase(bus, slot); - *irq = pci_what_irq(bus, slot); + info->base[0] = pci_what_iobase(bus, slot); + info->size[0] = pci_what_size(bus, slot); + info->irq = pci_what_irq(bus, slot); return 0; } }