diff options
| author | Michael Brown | 2005-04-14 12:10:54 +0200 |
|---|---|---|
| committer | Michael Brown | 2005-04-14 12:10:54 +0200 |
| commit | 75d864432cc41c45d46df9ea7d3afd7cccbc0148 (patch) | |
| tree | 8b98bce9c01b2f99f16d5da9f93a4e147dfe1865 | |
| parent | Stripped references to variables in C code. (diff) | |
| download | ipxe-75d864432cc41c45d46df9ea7d3afd7cccbc0148.tar.gz ipxe-75d864432cc41c45d46df9ea7d3afd7cccbc0148.tar.xz ipxe-75d864432cc41c45d46df9ea7d3afd7cccbc0148.zip | |
Use the magic of common symbols to allow struct dev to effectively grow at
link time to accommodate whatever bus objects are included.
| -rw-r--r-- | src/core/main.c | 23 | ||||
| -rw-r--r-- | src/drivers/bus/eisa.c | 26 | ||||
| -rw-r--r-- | src/drivers/bus/mca.c | 22 | ||||
| -rw-r--r-- | src/drivers/bus/pci.c | 31 | ||||
| -rw-r--r-- | src/include/dev.h | 27 | ||||
| -rw-r--r-- | src/include/eisa.h | 1 | ||||
| -rw-r--r-- | src/include/mca.h | 1 | ||||
| -rw-r--r-- | src/include/pci.h | 2 |
8 files changed, 84 insertions, 49 deletions
diff --git a/src/core/main.c b/src/core/main.c index da1c58a6f..3cc777a8e 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -144,7 +144,10 @@ static int initialized; /* Global instance of the current boot device */ -struct dev dev; +DEV_BUS(struct {}, dev_bus); +struct dev dev = { + .bus = &dev_bus, +}; /************************************************************************** * initialise() - perform any C-level initialisation @@ -213,24 +216,6 @@ void exit(int status) } -/* - * Set PCI device to use. - * - * This routine can be called by e.g. the ROM prefix to specify that - * the first device to be tried should be the device on which the ROM - * was physically located. - * - * Note that this is deliberately in main.c rather than pci.c, because - * this function should generalise to other bus types (e.g. ISAPnP), - * and we don't want to end up dragging in pci.o unnecessarily. - */ -void set_pci_device ( uint16_t busdevfn ) { - dev.devid.bus_type = PCI_BUS_TYPE; - dev.pci.busdevfn = busdevfn; - dev.pci.already_tried = 0; -} - - #if 0 static int main_loop(int state) diff --git a/src/drivers/bus/eisa.c b/src/drivers/bus/eisa.c index a294895d3..c80974a8a 100644 --- a/src/drivers/bus/eisa.c +++ b/src/drivers/bus/eisa.c @@ -14,6 +14,14 @@ #endif /* + * Ensure that there is sufficient space in the shared dev_bus + * structure for a struct pci_device. + * + */ +DEV_BUS( struct eisa_device, eisa_dev ); +static char eisa_magic[0]; /* guaranteed unique symbol */ + +/* * Fill in parameters for an EISA device based on slot number * * Return 1 if device present, 0 otherwise @@ -52,15 +60,14 @@ static int fill_eisa_device ( struct eisa_device *eisa ) { * Obtain a struct eisa * from a struct dev * * * If dev has not previously been used for an EISA device scan, blank - * out dev.eisa + * out struct eisa */ struct eisa_device * eisa_device ( struct dev *dev ) { - struct eisa_device *eisa = &dev->eisa; + struct eisa_device *eisa = dev->bus;; - if ( dev->devid.bus_type != EISA_BUS_TYPE ) { + if ( eisa->magic != eisa_magic ) { memset ( eisa, 0, sizeof ( *eisa ) ); - dev->devid.bus_type = EISA_BUS_TYPE; - eisa->slot = EISA_MIN_SLOT; + eisa->magic = eisa_magic; } eisa->dev = dev; return eisa; @@ -74,8 +81,13 @@ int find_eisa_device ( struct eisa_device *eisa, struct eisa_driver *driver ) { unsigned int i; /* Iterate through all possible EISA slots, starting where we - * left off/ + * left off. If eisa->slot is zero (which it will be if we + * have a zeroed structure), start from slot EISA_MIN_SLOT, + * since slot 0 doesn't exist. */ + if ( ! eisa->slot ) { + eisa->slot = EISA_MIN_SLOT; + } for ( ; eisa->slot <= EISA_MAX_SLOT ; eisa->slot++ ) { /* If we've already used this device, skip it */ if ( eisa->already_tried ) { @@ -101,6 +113,8 @@ int find_eisa_device ( struct eisa_device *eisa, struct eisa_driver *driver ) { eisa->prod_id ) ); if ( eisa->dev ) { eisa->dev->name = driver->name; + eisa->dev->devid.bus_type + = ISA_BUS_TYPE; eisa->dev->devid.vendor_id = eisa->mfg_id; eisa->dev->devid.device_id diff --git a/src/drivers/bus/mca.c b/src/drivers/bus/mca.c index 28b99f77a..1715c5883 100644 --- a/src/drivers/bus/mca.c +++ b/src/drivers/bus/mca.c @@ -20,6 +20,14 @@ #endif /* + * Ensure that there is sufficient space in the shared dev_bus + * structure for a struct pci_device. + * + */ +DEV_BUS( struct mca_device, mca_dev ); +static char mca_magic[0]; /* guaranteed unique symbol */ + +/* * Fill in parameters for an MCA device based on slot number * */ @@ -53,14 +61,14 @@ static int fill_mca_device ( struct mca_device *mca ) { * Obtain a struct mca * from a struct dev * * * If dev has not previously been used for an MCA device scan, blank - * out dev.mca + * out struct mca */ struct mca_device * mca_device ( struct dev *dev ) { - struct mca_device *mca = &dev->mca; + struct mca_device *mca = dev->bus; - if ( dev->devid.bus_type != MCA_BUS_TYPE ) { + if ( mca->magic != mca_magic ) { memset ( mca, 0, sizeof ( *mca ) ); - dev->devid.bus_type = MCA_BUS_TYPE; + mca->magic = mca_magic; } mca->dev = dev; return mca; @@ -97,8 +105,10 @@ int find_mca_device ( struct mca_device *mca, struct mca_driver *driver ) { id->name, driver->name, id->id ); if ( mca->dev ) { mca->dev->name = driver->name; - mca->dev->devid.vendor_id = - GENERIC_MCA_VENDOR; + mca->dev->devid.bus_type + = MCA_BUS_TYPE; + mca->dev->devid.vendor_id + = GENERIC_MCA_VENDOR; mca->dev->devid.device_id = id->id; } mca->already_tried = 1; diff --git a/src/drivers/bus/pci.c b/src/drivers/bus/pci.c index 4b4e9a151..d23a647a8 100644 --- a/src/drivers/bus/pci.c +++ b/src/drivers/bus/pci.c @@ -10,6 +10,14 @@ #endif /* + * Ensure that there is sufficient space in the shared dev_bus + * structure for a struct pci_device. + * + */ +DEV_BUS( struct pci_device, pci_dev ); +static char pci_magic[0]; /* guaranteed unique symbol */ + +/* * Fill in parameters (vendor & device ids, class, membase etc.) for a * PCI device based on bus & devfn. * @@ -112,20 +120,34 @@ void adjust_pci_device ( struct pci_device *pci ) { * Obtain a struct pci * from a struct dev * * * If dev has not previously been used for a PCI device scan, blank - * out dev.pci + * out struct pci */ struct pci_device * pci_device ( struct dev *dev ) { - struct pci_device *pci = &dev->pci; + struct pci_device *pci = dev->bus; - if ( dev->devid.bus_type != PCI_BUS_TYPE ) { + if ( pci->magic != pci_magic ) { memset ( pci, 0, sizeof ( *pci ) ); - dev->devid.bus_type = PCI_BUS_TYPE; + pci->magic = pci_magic; } pci->dev = dev; return pci; } /* + * Set PCI device to use. + * + * This routine can be called by e.g. the ROM prefix to specify that + * the first device to be tried should be the device on which the ROM + * was physically located. + * + */ +void set_pci_device ( uint16_t busdevfn ) { + pci_dev.magic = pci_magic; + pci_dev.busdevfn = busdevfn; + pci_dev.already_tried = 0; +} + +/* * Find a PCI device matching the specified driver * */ @@ -154,6 +176,7 @@ int find_pci_device ( struct pci_device *pci, /* Fill in dev structure, if present */ if ( pci->dev ) { pci->dev->name = driver->name; + pci->dev->devid.bus_type = PCI_BUS_TYPE; pci->dev->devid.vendor_id = pci->vendor; pci->dev->devid.device_id = pci->dev_id; } diff --git a/src/include/dev.h b/src/include/dev.h index a9e2916b1..b5a2edda5 100644 --- a/src/include/dev.h +++ b/src/include/dev.h @@ -3,11 +3,6 @@ #include "stdint.h" -/* Bus types */ -#include "pci.h" -#include "eisa.h" -#include "mca.h" - /* Device types */ #include "nic.h" @@ -18,8 +13,7 @@ struct dev_id { uint8_t bus_type; #define PCI_BUS_TYPE 1 #define ISA_BUS_TYPE 2 -#define EISA_BUS_TYPE 3 -#define MCA_BUS_TYPE 4 +#define MCA_BUS_TYPE 3 } __attribute__ ((packed)); /* Dont use sizeof, that will include the padding */ @@ -29,18 +23,25 @@ struct dev { struct dev_operations *dev_op; const char *name; struct dev_id devid; /* device ID string (sent to DHCP server) */ - /* All possible bus types */ - union { - struct pci_device pci; - struct eisa_device eisa; - struct mca_device mca; - }; + /* Pointer to bus information for device. Whatever sets up + * the struct dev must make sure that this points to a buffer + * large enough for the required struct <bus>_device. + */ + void *bus; /* All possible device types */ union { struct nic nic; }; }; +/* + * Macro to help create a common symbol with enough space for any + * struct <bus>_device. + * + * Use as e.g. DEV_BUS(struct pci_device); + */ +#define DEV_BUS(datatype,symbol) datatype symbol __asm__ ( "_dev_bus" ); + struct dev_operations { void ( *disable ) ( struct dev * ); void ( *print_info ) ( struct dev * ); diff --git a/src/include/eisa.h b/src/include/eisa.h index 4fe14fc69..ed0ccef35 100644 --- a/src/include/eisa.h +++ b/src/include/eisa.h @@ -27,6 +27,7 @@ */ struct dev; struct eisa_device { + char *magic; /* must be first */ struct dev *dev; unsigned int slot; uint16_t ioaddr; diff --git a/src/include/mca.h b/src/include/mca.h index e69b65601..c12b1cabe 100644 --- a/src/include/mca.h +++ b/src/include/mca.h @@ -28,6 +28,7 @@ */ struct dev; struct mca_device { + char *magic; /* must be first */ struct dev *dev; unsigned int slot; unsigned char pos[8]; diff --git a/src/include/pci.h b/src/include/pci.h index 36edc0f58..988259a32 100644 --- a/src/include/pci.h +++ b/src/include/pci.h @@ -232,13 +232,13 @@ #define PCI_MSI_ADDRESS_HI 8 /* Upper 32 bits (if PCI_MSI_FLAGS_64BIT set) */ #define PCI_MSI_DATA_32 8 /* 16 bits of data for 32-bit devices */ #define PCI_MSI_DATA_64 12 /* 16 bits of data for 64-bit devices */ - /* * A physical PCI device * */ struct dev; struct pci_device { + char * magic; /* must be first */ struct dev * dev; uint32_t membase; /* BAR 1 */ uint32_t ioaddr; /* first IO BAR */ |
