Add device description fields to struct device.
authorMichael Brown <mcb30@etherboot.org>
Wed, 10 Jan 2007 15:27:48 +0000 (15:27 +0000)
committerMichael Brown <mcb30@etherboot.org>
Wed, 10 Jan 2007 15:27:48 +0000 (15:27 +0000)
src/arch/i386/core/pcibios.c
src/arch/i386/drivers/net/undi.c
src/arch/i386/drivers/net/undiload.c
src/arch/i386/drivers/net/undionly.c
src/arch/i386/include/undi.h
src/arch/i386/include/undiload.h
src/arch/i386/prefix/pxeprefix.S
src/drivers/bus/pci.c
src/include/gpxe/device.h
src/include/gpxe/pci.h

index a4f61b7..1c93e4b 100644 (file)
@@ -72,7 +72,7 @@ int pcibios_read ( struct pci_device *pci, uint32_t command, uint32_t *value ){
                               : "=a" ( status ), "=b" ( discard_b ),
                                 "=c" ( *value ), "=D" ( discard_D )
                               : "a" ( command >> 16 ), "D" ( command ),
-                                "b" ( ( pci->bus << 8 ) | pci->devfn )
+                                "b" ( PCI_BUSDEVFN ( pci->bus, pci->devfn ) )
                               : "edx" );
 
        return ( ( status >> 8 ) & 0xff );
@@ -98,7 +98,7 @@ int pcibios_write ( struct pci_device *pci, uint32_t command, uint32_t value ){
                               : "=a" ( status ), "=b" ( discard_b ),
                                 "=c" ( discard_c ), "=D" ( discard_D )
                               : "a" ( command >> 16 ), "D" ( command ),
-                                "b" ( ( pci->bus << 8 ) | pci->devfn ),
+                                "b" ( PCI_BUSDEVFN ( pci->bus, pci->devfn ) ),
                                 "c" ( value )
                               : "edx" );
        
index 492e8fa..c93ad24 100644 (file)
@@ -64,7 +64,7 @@ static int undipci_probe ( struct pci_device *pci,
                           const struct pci_device_id *id __unused ) {
        struct undi_device *undi;
        struct undi_rom *undirom;
-       unsigned int busdevfn = ( ( pci->bus << 8 ) | pci->devfn );
+       unsigned int busdevfn = PCI_BUSDEVFN ( pci->bus, pci->devfn );
        int rc;
 
        /* Ignore non-network devices */
@@ -99,6 +99,7 @@ static int undipci_probe ( struct pci_device *pci,
        /* Add to device hierarchy */
        snprintf ( undi->dev.name, sizeof ( undi->dev.name ),
                   "UNDI-%s", pci->dev.name );
+       memcpy ( &undi->dev.desc, &pci->dev.desc, sizeof ( undi->dev.desc ) );
        undi->dev.parent = &pci->dev;
        INIT_LIST_HEAD ( &undi->dev.children );
        list_add ( &undi->dev.siblings, &pci->dev.children );
index 27f2652..70008a4 100644 (file)
@@ -76,13 +76,13 @@ int undi_load ( struct undi_device *undi, struct undi_rom *undirom ) {
        /* Debug info */
        DBGC ( undi, "UNDI %p loading UNDI ROM %p to CS %04x DS %04x for ",
               undi, undirom, undi_loader.UNDI_CS, undi_loader.UNDI_DS );
-       if ( undi->pci_busdevfn != 0xffff ) {
+       if ( undi->pci_busdevfn != UNDI_NO_PCI_BUSDEVFN ) {
                unsigned int bus = ( undi->pci_busdevfn >> 8 );
                unsigned int devfn = ( undi->pci_busdevfn & 0xff );
                DBGC ( undi, "PCI %02x:%02x.%x\n",
                       bus, PCI_SLOT ( devfn ), PCI_FUNC ( devfn ) );
        }
-       if ( undi->isapnp_csn != 0xffff ) {
+       if ( undi->isapnp_csn != UNDI_NO_ISAPNP_CSN ) {
                DBGC ( undi, "ISAPnP(%04x) CSN %04x\n",
                       undi->isapnp_read_port, undi->isapnp_csn );
        }
index bd53e1d..d955841 100644 (file)
  * find.
  */
 static int undibus_probe ( struct root_device *rootdev ) {
+       struct undi_device *undi = &preloaded_undi;
        int rc;
 
        /* Check for a valie preloaded UNDI device */
-       if ( ! preloaded_undi.entry.segment ) {
+       if ( ! undi->entry.segment ) {
                DBG ( "No preloaded UNDI device found!\n" );
                return -ENODEV;
        }
 
        /* Add to device hierarchy */
-       strncpy ( preloaded_undi.dev.name, "UNDI",
-                 ( sizeof ( preloaded_undi.dev.name ) - 1 ) );
-       preloaded_undi.dev.parent = &rootdev->dev;
-       list_add ( &preloaded_undi.dev.siblings, &rootdev->dev.children);
-       INIT_LIST_HEAD ( &preloaded_undi.dev.children );
+       strncpy ( undi->dev.name, "UNDI",
+                 ( sizeof ( undi->dev.name ) - 1 ) );
+       if ( undi->pci_busdevfn != UNDI_NO_PCI_BUSDEVFN ) {
+               struct pci_device_description *pcidesc = &undi->dev.desc.pci;
+               pcidesc->bus_type = BUS_TYPE_PCI;
+               pcidesc->busdevfn = undi->pci_busdevfn;
+               pcidesc->vendor = undi->pci_vendor;
+               pcidesc->device = undi->pci_device;
+       } else if ( undi->isapnp_csn != UNDI_NO_ISAPNP_CSN ) {
+               struct isapnp_device_description *isapnpdesc
+                       = &undi->dev.desc.isapnp;
+               isapnpdesc->bus_type = BUS_TYPE_ISAPNP;
+       }
+       undi->dev.parent = &rootdev->dev;
+       list_add ( &undi->dev.siblings, &rootdev->dev.children);
+       INIT_LIST_HEAD ( &undi->dev.children );
 
        /* Create network device */
-       if ( ( rc = undinet_probe ( &preloaded_undi ) ) != 0 )
+       if ( ( rc = undinet_probe ( undi ) ) != 0 )
                goto err;
 
        return 0;
 
  err:
-       list_del ( &preloaded_undi.dev.siblings );
+       list_del ( &undi->dev.siblings );
        return rc;
 }
 
@@ -81,8 +93,10 @@ static int undibus_probe ( struct root_device *rootdev ) {
  * @v rootdev          UNDI bus root device
  */
 static void undibus_remove ( struct root_device *rootdev __unused ) {
-       undinet_remove ( &preloaded_undi );
-       list_del ( &preloaded_undi.dev.siblings );
+       struct undi_device *undi = &preloaded_undi;
+
+       undinet_remove ( undi );
+       list_del ( &undi->dev.siblings );
 }
 
 /** UNDI bus root device driver */
index e2e3c1d..f6e22e7 100644 (file)
@@ -26,12 +26,22 @@ struct undi_device {
        UINT16_t fbms;
        /** Free base memory prior to load */
        UINT16_t restore_fbms;
-       /** PCI bus:dev.fn, or 0xffff */
+       /** PCI bus:dev.fn, or @c UNDI_NO_PCI_BUSDEVFN */
        UINT16_t pci_busdevfn;
-       /** ISAPnP card select number, or 0xffff */
+       /** ISAPnP card select number, or @c UNDI_NO_ISAPNP_CSN */
        UINT16_t isapnp_csn;
-       /** ISAPnP read port, or 0xffff */
+       /** ISAPnP read port, or @c UNDI_NO_ISAPNP_READ_PORT */
        UINT16_t isapnp_read_port;
+       /** PCI vendor ID
+        *
+        * Filled in only for the preloaded UNDI device by pxeprefix.S
+        */
+       UINT16_t pci_vendor;
+       /** PCI device ID 
+        *
+        * Filled in only for the preloaded UNDI device by pxeprefix.S
+        */
+       UINT16_t pci_device;
        /** Padding */
        UINT16_t pad;
 
@@ -45,6 +55,15 @@ struct undi_device {
        void *priv;
 } __attribute__ (( packed ));
 
+/** PCI bus:dev.fn field is invalid */
+#define UNDI_NO_PCI_BUSDEVFN 0xffff
+
+/** ISAPnP card select number field is invalid */
+#define UNDI_NO_ISAPNP_CSN 0xffff
+
+/** ISAPnP read port field is invalid */
+#define UNDI_NO_ISAPNP_READ_PORT 0xffff
+
 /**
  * Set UNDI driver-private data
  *
index e42563b..bfc1187 100644 (file)
@@ -25,8 +25,8 @@ static inline int undi_load_pci ( struct undi_device *undi,
                                  struct undi_rom *undirom,
                                  unsigned int pci_busdevfn ) {
        undi->pci_busdevfn = pci_busdevfn;
-       undi->isapnp_csn = 0xffff;
-       undi->isapnp_read_port = 0xffff;
+       undi->isapnp_csn = UNDI_NO_ISAPNP_CSN;
+       undi->isapnp_read_port = UNDI_NO_ISAPNP_READ_PORT;
        return undi_load ( undi, undirom );
 }
 
index 55a228f..8c091df 100644 (file)
@@ -220,7 +220,9 @@ get_physical_device:
        jmp     no_physical_device
 
 pci_physical_device:
-       /* Record PCI bus:dev.fn */
+       /* Record PCI bus:dev.fn and vendor/device IDs */
+       movl    ( pxe_parameter_structure + 0x03 ), %eax
+       movl    %eax, pci_vendor
        movw    ( pxe_parameter_structure + 0x0b ), %ax
        movw    %ax, pci_busdevfn
        movw    $10f, %si
@@ -680,6 +682,9 @@ pci_busdevfn:               .word 0xffff
 isapnp_csn:            .word 0xffff
 isapnp_read_port:      .word 0xffff
 
+pci_vendor:            .word 0
+pci_device:            .word 0
+
        .equ undi_device_size, ( . - undi_device )
 
 /*****************************************************************************
index 11a8e0a..56436b7 100644 (file)
@@ -282,6 +282,10 @@ static int pcibus_probe ( struct root_device *rootdev ) {
                        snprintf ( pci->dev.name, sizeof ( pci->dev.name ),
                                   "PCI%02x:%02x.%x", bus,
                                   PCI_SLOT ( devfn ), PCI_FUNC ( devfn ) );
+                       pci->dev.desc.bus_type = BUS_TYPE_PCI;
+                       pci->dev.desc.pci.busdevfn = PCI_BUSDEVFN (bus, devfn);
+                       pci->dev.desc.pci.vendor = pci->vendor;
+                       pci->dev.desc.pci.device = pci->device;
                        pci->dev.parent = &rootdev->dev;
                        list_add ( &pci->dev.siblings, &rootdev->dev.children);
                        INIT_LIST_HEAD ( &pci->dev.children );
index 9f670cf..139fb78 100644 (file)
 #include <gpxe/list.h>
 #include <gpxe/tables.h>
 
+/** A PCI device description */
+struct pci_device_description {
+       /** Bus type
+        *
+        * Must be @c BUS_TYPE_PCI.
+        */
+       unsigned int bus_type;
+       /** Bus:dev.fn address
+        *
+        * As constructed by PCI_BUSDEVFN().
+        */
+       unsigned int busdevfn;
+       /** Vendor ID */
+       unsigned int vendor;
+       /** Device ID */
+       unsigned int device;
+};
+
+/** PCI bus type */
+#define BUS_TYPE_PCI 1
+
+/** An ISAPnP device description */
+struct isapnp_device_description {
+       /** Bus type
+        *
+        * Must be @c BUS_TYPE_ISAPNP.
+        */
+       unsigned int bus_type;
+};
+
+/** PCI bus type */
+#define BUS_TYPE_ISAPNP 2
+
+/** A hardware device description */
+union device_description {
+       /** Bus type
+        *
+        * This must be a BUS_TYPE_XXX constant.
+        */
+       unsigned int bus_type;
+       /** PCI device description */
+       struct pci_device_description pci;
+       /** ISAPnP device description */
+       struct isapnp_device_description isapnp;
+};
+
 /** A hardware device */
 struct device {
        /** Name */
        char name[16];
+       /** Device description */
+       union device_description desc;
        /** Devices on the same bus */
        struct list_head siblings;
        /** Devices attached to this device */
index 8269dfa..eaa1560 100644 (file)
@@ -307,9 +307,10 @@ struct pci_driver {
 /** Declare a PCI driver */
 #define __pci_driver __table ( struct pci_driver, pci_drivers, 01 )
 
-#define PCI_DEVFN( slot, func )        ( ( (slot) << 3 ) | (func) )
-#define PCI_SLOT( devfn )      ( ( (devfn) >> 3 ) & 0x1f )
-#define PCI_FUNC( devfn )      ( (devfn) & 0x07 )
+#define PCI_DEVFN( slot, func )                ( ( (slot) << 3 ) | (func) )
+#define PCI_SLOT( devfn )              ( ( (devfn) >> 3 ) & 0x1f )
+#define PCI_FUNC( devfn )              ( (devfn) & 0x07 )
+#define PCI_BUSDEVFN( bus, devfn )     ( ( (bus) << 8 ) | (devfn) )
 
 #define PCI_BASE_CLASS( class )        ( (class) >> 16 )