From 072d656a2fe0b0d89ded610d11257889fc35e0f1 Mon Sep 17 00:00:00 2001 From: Michael Brown Date: Mon, 2 Feb 2015 14:31:18 +0000 Subject: [PATCH] [pci] Allow drivers to specify a PCI class 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 --- src/arch/i386/drivers/net/undi.c | 7 +- src/drivers/bus/pci.c | 9 ++- src/include/ipxe/pci.h | 25 +++++++ src/include/ipxe/pci_ids.h | 123 ++++++++----------------------- 4 files changed, 63 insertions(+), 101 deletions(-) diff --git a/src/arch/i386/drivers/net/undi.c b/src/arch/i386/drivers/net/undi.c index 2bc54824..c4a11c57 100644 --- a/src/arch/i386/drivers/net/undi.c +++ b/src/arch/i386/drivers/net/undi.c @@ -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, }; diff --git a/src/drivers/bus/pci.c b/src/drivers/bus/pci.c index 4a8d00b5..f861d452 100644 --- a/src/drivers/bus/pci.c +++ b/src/drivers/bus/pci.c @@ -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 ) { diff --git a/src/include/ipxe/pci.h b/src/include/ipxe/pci.h index 692771eb..0bd976eb 100644 --- a/src/include/ipxe/pci.h +++ b/src/include/ipxe/pci.h @@ -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 * diff --git a/src/include/ipxe/pci_ids.h b/src/include/ipxe/pci_ids.h index 25c7782b..bed701f2 100644 --- a/src/include/ipxe/pci_ids.h +++ b/src/include/ipxe/pci_ids.h @@ -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 */