]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[pci] Allow drivers to specify a PCI class
authorMichael Brown <mcb30@ipxe.org>
Mon, 2 Feb 2015 14:31:18 +0000 (14:31 +0000)
committerMichael Brown <mcb30@ipxe.org>
Mon, 2 Feb 2015 14:31:18 +0000 (14:31 +0000)
Allow drivers to specify a supported PCI class code.  To save space in
the final binary, make this an attribute of the driver rather than an
attribute of a PCI device ID list entry.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
src/arch/i386/drivers/net/undi.c
src/drivers/bus/pci.c
src/include/ipxe/pci.h
src/include/ipxe/pci_ids.h

index 2bc54824c7b1abadc143cdcfaf94a8938abf51e5..c4a11c57fabd6629b45e85d4032a6c50fb7d21b4 100644 (file)
@@ -68,10 +68,6 @@ static int undipci_probe ( struct pci_device *pci ) {
        struct undi_rom *undirom;
        int rc;
 
-       /* Ignore non-network devices */
-       if ( PCI_BASE_CLASS ( pci->class ) != PCI_BASE_CLASS_NETWORK )
-               return -ENOTTY;
-
        /* Allocate UNDI device structure */
        undi = zalloc ( sizeof ( *undi ) );
        if ( ! undi )
@@ -138,12 +134,13 @@ static void undipci_remove ( struct pci_device *pci ) {
 }
 
 static struct pci_device_id undipci_nics[] = {
-PCI_ROM ( 0xffff, 0xffff, "undipci", "UNDI (PCI)", 0 ),
+       PCI_ROM ( 0xffff, 0xffff, "undipci", "UNDI (PCI)", 0 ),
 };
 
 struct pci_driver undipci_driver __pci_driver_fallback = {
        .ids = undipci_nics,
        .id_count = ( sizeof ( undipci_nics ) / sizeof ( undipci_nics[0] ) ),
+       .class = PCI_CLASS ( PCI_CLASS_NETWORK, PCI_ANY_ID, PCI_ANY_ID ),
        .probe = undipci_probe,
        .remove = undipci_remove,
 };
index 4a8d00b54fefef1e8df13d43c919e2e04336abaa..f861d452559db25a6d28ba3af5b7f17a462433d2 100644 (file)
@@ -253,6 +253,8 @@ int pci_find_driver ( struct pci_device *pci ) {
        unsigned int i;
 
        for_each_table_entry ( driver, PCI_DRIVERS ) {
+               if ( ( driver->class.class ^ pci->class ) & driver->class.mask )
+                       continue;
                for ( i = 0 ; i < driver->id_count ; i++ ) {
                        id = &driver->ids[i];
                        if ( ( id->vendor != PCI_ANY_ID ) &&
@@ -334,14 +336,15 @@ static int pcibus_probe ( struct root_device *rootdev ) {
 
                /* Look for a driver */
                if ( ( rc = pci_find_driver ( pci ) ) != 0 ) {
-                       DBGC ( pci, PCI_FMT " (%04x:%04x) has no driver\n",
-                              PCI_ARGS ( pci ), pci->vendor, pci->device );
+                       DBGC ( pci, PCI_FMT " (%04x:%04x class %06x) has no "
+                              "driver\n", PCI_ARGS ( pci ), pci->vendor,
+                              pci->device, pci->class );
                        continue;
                }
 
                /* Add to device hierarchy */
                pci->dev.parent = &rootdev->dev;
-               list_add ( &pci->dev.siblings, &rootdev->dev.children);
+               list_add ( &pci->dev.siblings, &rootdev->dev.children );
 
                /* Look for a driver */
                if ( ( rc = pci_probe ( pci ) ) == 0 ) {
index 692771ebefb7a8d0a7552995bc90b45c57cdfcb1..0bd976ebf03defe4c2b8023c06406c0a2b1238ec 100644 (file)
@@ -279,6 +279,29 @@ struct pci_device_id {
 /** Match-anything ID */
 #define PCI_ANY_ID 0xffff
 
+/** A PCI class ID */
+struct pci_class_id {
+       /** Class */
+       uint32_t class;
+       /** Class mask */
+       uint32_t mask;
+};
+
+/** Construct PCI class ID
+ *
+ * @v base             Base class (or PCI_ANY_ID)
+ * @v sub              Subclass (or PCI_ANY_ID)
+ * @v progif           Programming interface (or PCI_ANY_ID)
+ */
+#define PCI_CLASS(base,sub,progif) {                                      \
+       .class = ( ( ( (base) & 0xff ) << 16 ) |                           \
+                  ( ( (sub) & 0xff ) << 8 ) |                             \
+                  ( ( (progif) & 0xff) << 0 ) ),                          \
+       .mask = ( ( ( ( (base) == PCI_ANY_ID ) ? 0x00 : 0xff ) << 16 ) |   \
+                 ( ( ( (sub) == PCI_ANY_ID ) ? 0x00 : 0xff ) << 8 ) |     \
+                 ( ( ( (progif) == PCI_ANY_ID ) ? 0x00 : 0xff ) << 0 ) ), \
+       }
+
 /** A PCI device */
 struct pci_device {
        /** Generic device */
@@ -322,6 +345,8 @@ struct pci_driver {
        struct pci_device_id *ids;
        /** Number of entries in PCI ID table */
        unsigned int id_count;
+       /** PCI class ID */
+       struct pci_class_id class;
        /**
         * Probe device
         *
index 25c7782bcbb4e1f28871640d914193ad9b4a8c2e..bed701f29bb77abf107016d95155ba3b28104347 100644 (file)
@@ -11,116 +11,53 @@ FILE_LICENCE ( GPL2_ONLY );
 
 /* Device classes and subclasses */
 
-#define PCI_CLASS_NOT_DEFINED          0x0000
-#define PCI_CLASS_NOT_DEFINED_VGA      0x0001
+#define PCI_CLASS_NONE                 0x00
 
-#define PCI_BASE_CLASS_STORAGE         0x01
-#define PCI_CLASS_STORAGE_SCSI         0x0100
-#define PCI_CLASS_STORAGE_IDE          0x0101
-#define PCI_CLASS_STORAGE_FLOPPY       0x0102
-#define PCI_CLASS_STORAGE_IPI          0x0103
-#define PCI_CLASS_STORAGE_RAID         0x0104
-#define PCI_CLASS_STORAGE_OTHER                0x0180
+#define PCI_CLASS_STORAGE              0x01
 
-#define PCI_BASE_CLASS_NETWORK         0x02
-#define PCI_CLASS_NETWORK_ETHERNET     0x0200
-#define PCI_CLASS_NETWORK_TOKEN_RING   0x0201
-#define PCI_CLASS_NETWORK_FDDI         0x0202
-#define PCI_CLASS_NETWORK_ATM          0x0203
-#define PCI_CLASS_NETWORK_OTHER                0x0280
+#define PCI_CLASS_NETWORK              0x02
+#define PCI_CLASS_NETWORK_ETHERNET     0x00
+#define PCI_CLASS_NETWORK_TOKENRING    0x01
+#define PCI_CLASS_NETWORK_FDDI         0x02
+#define PCI_CLASS_NETWORK_ATM          0x03
+#define PCI_CLASS_NETWORK_ISDN         0x04
+#define PCI_CLASS_NETWORK_WORLDFIP     0x05
+#define PCI_CLASS_NETWORK_PICMG                0x06
 
-#define PCI_BASE_CLASS_DISPLAY         0x03
-#define PCI_CLASS_DISPLAY_VGA          0x0300
-#define PCI_CLASS_DISPLAY_XGA          0x0301
-#define PCI_CLASS_DISPLAY_3D           0x0302
-#define PCI_CLASS_DISPLAY_OTHER                0x0380
+#define PCI_CLASS_DISPLAY              0x03
 
-#define PCI_BASE_CLASS_MULTIMEDIA      0x04
-#define PCI_CLASS_MULTIMEDIA_VIDEO     0x0400
-#define PCI_CLASS_MULTIMEDIA_AUDIO     0x0401
-#define PCI_CLASS_MULTIMEDIA_PHONE     0x0402
-#define PCI_CLASS_MULTIMEDIA_OTHER     0x0480
+#define PCI_CLASS_MEDIA                        0x04
 
-#define PCI_BASE_CLASS_MEMORY          0x05
-#define PCI_CLASS_MEMORY_RAM           0x0500
-#define PCI_CLASS_MEMORY_FLASH         0x0501
-#define PCI_CLASS_MEMORY_OTHER         0x0580
+#define PCI_CLASS_MEMORY               0x05
 
-#define PCI_BASE_CLASS_BRIDGE          0x06
-#define PCI_CLASS_BRIDGE_HOST          0x0600
-#define PCI_CLASS_BRIDGE_ISA           0x0601
-#define PCI_CLASS_BRIDGE_EISA          0x0602
-#define PCI_CLASS_BRIDGE_MC            0x0603
-#define PCI_CLASS_BRIDGE_PCI           0x0604
-#define PCI_CLASS_BRIDGE_PCMCIA                0x0605
-#define PCI_CLASS_BRIDGE_NUBUS         0x0606
-#define PCI_CLASS_BRIDGE_CARDBUS       0x0607
-#define PCI_CLASS_BRIDGE_RACEWAY       0x0608
-#define PCI_CLASS_BRIDGE_OTHER         0x0680
+#define PCI_CLASS_BRIDGE               0x06
 
-#define PCI_BASE_CLASS_COMMUNICATION   0x07
-#define PCI_CLASS_COMMUNICATION_SERIAL 0x0700
-#define PCI_CLASS_COMMUNICATION_PARALLEL 0x0701
-#define PCI_CLASS_COMMUNICATION_MULTISERIAL 0x0702
-#define PCI_CLASS_COMMUNICATION_MODEM  0x0703
-#define PCI_CLASS_COMMUNICATION_OTHER  0x0780
+#define PCI_CLASS_COMMS                        0x07
 
-#define PCI_BASE_CLASS_SYSTEM          0x08
-#define PCI_CLASS_SYSTEM_PIC           0x0800
-#define PCI_CLASS_SYSTEM_DMA           0x0801
-#define PCI_CLASS_SYSTEM_TIMER         0x0802
-#define PCI_CLASS_SYSTEM_RTC           0x0803
-#define PCI_CLASS_SYSTEM_PCI_HOTPLUG   0x0804
-#define PCI_CLASS_SYSTEM_OTHER         0x0880
+#define PCI_CLASS_GENERIC              0x08
 
-#define PCI_BASE_CLASS_INPUT           0x09
-#define PCI_CLASS_INPUT_KEYBOARD       0x0900
-#define PCI_CLASS_INPUT_PEN            0x0901
-#define PCI_CLASS_INPUT_MOUSE          0x0902
-#define PCI_CLASS_INPUT_SCANNER                0x0903
-#define PCI_CLASS_INPUT_GAMEPORT       0x0904
-#define PCI_CLASS_INPUT_OTHER          0x0980
+#define PCI_CLASS_INPUT                        0x09
 
-#define PCI_BASE_CLASS_DOCKING         0x0a
-#define PCI_CLASS_DOCKING_GENERIC      0x0a00
-#define PCI_CLASS_DOCKING_OTHER                0x0a80
+#define PCI_CLASS_DOCK                 0x0a
 
-#define PCI_BASE_CLASS_PROCESSOR       0x0b
-#define PCI_CLASS_PROCESSOR_386                0x0b00
-#define PCI_CLASS_PROCESSOR_486                0x0b01
-#define PCI_CLASS_PROCESSOR_PENTIUM    0x0b02
-#define PCI_CLASS_PROCESSOR_ALPHA      0x0b10
-#define PCI_CLASS_PROCESSOR_POWERPC    0x0b20
-#define PCI_CLASS_PROCESSOR_MIPS       0x0b30
-#define PCI_CLASS_PROCESSOR_CO         0x0b40
+#define PCI_CLASS_CPU                  0x0b
 
-#define PCI_BASE_CLASS_SERIAL          0x0c
-#define PCI_CLASS_SERIAL_FIREWIRE      0x0c00
-#define PCI_CLASS_SERIAL_ACCESS                0x0c01
-#define PCI_CLASS_SERIAL_SSA           0x0c02
-#define PCI_CLASS_SERIAL_USB           0x0c03
-#define PCI_CLASS_SERIAL_FIBER         0x0c04
-#define PCI_CLASS_SERIAL_SMBUS         0x0c05
+#define PCI_CLASS_SERIAL               0x0c
+#define PCI_CLASS_SERIAL_USB           0x03
+#define PCI_CLASS_SERIAL_USB_UHCI      0x00
+#define PCI_CLASS_SERIAL_USB_OHCI      0x10
+#define PCI_CLASS_SERIAL_USB_EHCI      0x20
+#define PCI_CLASS_SERIAL_USB_XHCI      0x30
 
-#define PCI_BASE_CLASS_INTELLIGENT     0x0e
-#define PCI_CLASS_INTELLIGENT_I2O      0x0e00
+#define PCI_CLASS_WIFI                 0x0d
 
-#define PCI_BASE_CLASS_SATELLITE       0x0f
-#define PCI_CLASS_SATELLITE_TV         0x0f00
-#define PCI_CLASS_SATELLITE_AUDIO      0x0f01
-#define PCI_CLASS_SATELLITE_VOICE      0x0f03
-#define PCI_CLASS_SATELLITE_DATA       0x0f04
+#define PCI_CLASS_IO                   0x0e
 
-#define PCI_BASE_CLASS_CRYPT           0x10
-#define PCI_CLASS_CRYPT_NETWORK                0x1000
-#define PCI_CLASS_CRYPT_ENTERTAINMENT  0x1001
-#define PCI_CLASS_CRYPT_OTHER          0x1080
+#define PCI_CLASS_SATELLITE            0x0f
 
-#define PCI_BASE_CLASS_SIGNAL_PROCESSING 0x11
-#define PCI_CLASS_SP_DPIO              0x1100
-#define PCI_CLASS_SP_OTHER             0x1180
+#define PCI_CLASS_CRYPTO               0x10
 
-#define PCI_CLASS_OTHERS               0xff
+#define PCI_CLASS_DATA                 0x11
 
 /* Vendors */