From 8049fc91ded9d780b9f6d5c40bc43ad3242b7a3b Mon Sep 17 00:00:00 2001 From: Vadim Bendebury Date: Tue, 24 Apr 2012 12:53:19 -0700 Subject: [PATCH] Allow device ID arrays in the PCI driver structure MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Many PCI devices share the very same driver despite having different PCI device IDs, which causes a lot of copy and paste of driver definitions. This change introduces a way to specify the array of acceptable device IDs in a single driver entry. As an example the Intel {Sandy|Ivy} Bridge SATA driver is being modified to use a single driver structure for all different SATA controller flavors, a few more Ivy Bridge IDs are being added as well. BUG=none TEST=manual . modified coreboot brought up an Ivy Bridge platform all the way to Linux login screen. Change-Id: I761c5611b93ef946053783f7a755e6c456dd6991 Signed-off-by: Vadim Bendebury Reviewed-on: http://review.coreboot.org/982 Tested-by: build bot (Jenkins) Reviewed-by: Kyösti Mälkki Reviewed-by: Patrick Georgi --- src/devices/pci_device.c | 24 +++++++++++++++++++++++- src/include/device/pci.h | 1 + src/southbridge/intel/bd82x6x/sata.c | 27 ++++----------------------- 3 files changed, 28 insertions(+), 24 deletions(-) diff --git a/src/devices/pci_device.c b/src/devices/pci_device.c index c0559956b3..c9af7c4cc8 100644 --- a/src/devices/pci_device.c +++ b/src/devices/pci_device.c @@ -795,6 +795,28 @@ static struct device_operations *get_pci_bridge_ops(device_t dev) return &default_pci_ops_bus; } +/** + * Check if a device id matches a PCI driver entry. + * + * The driver entry can either point at a zero terminated array of acceptable + * device IDs, or include a single device ID. + * + * @driver pointer to the PCI driver entry being checked + * @device_id PCI device ID of the device being matched + */ +static int device_id_match(struct pci_driver *driver, unsigned short device_id) +{ + if (driver->devices) { + unsigned short check_id; + const unsigned short *device_list = driver->devices; + while ((check_id = *device_list++) != 0) + if (check_id == device_id) + return 1; + } + + return (driver->device == device_id); +} + /** * Set up PCI device operation. * @@ -817,7 +839,7 @@ static void set_pci_ops(struct device *dev) */ for (driver = &pci_drivers[0]; driver != &epci_drivers[0]; driver++) { if ((driver->vendor == dev->vendor) && - (driver->device == dev->device)) { + device_id_match(driver, dev->device)) { dev->ops = (struct device_operations *)driver->ops; printk(BIOS_SPEW, "%s [%04x/%04x] %sops\n", dev_path(dev), driver->vendor, driver->device, diff --git a/src/include/device/pci.h b/src/include/device/pci.h index d4cfb8558c..e864d6d47f 100644 --- a/src/include/device/pci.h +++ b/src/include/device/pci.h @@ -42,6 +42,7 @@ struct pci_driver { const struct device_operations *ops; unsigned short vendor; unsigned short device; + const unsigned short *devices; }; #define __pci_driver __attribute__ ((used,__section__(".rodata.pci_driver"))) diff --git a/src/southbridge/intel/bd82x6x/sata.c b/src/southbridge/intel/bd82x6x/sata.c index 057b8825b0..fef12cd80b 100644 --- a/src/southbridge/intel/bd82x6x/sata.c +++ b/src/southbridge/intel/bd82x6x/sata.c @@ -215,32 +215,13 @@ static struct device_operations sata_ops = { .ops_pci = &sata_pci_ops, }; +static const unsigned short all_dev_ids[] = { 0x1c00, 0x1c01, 0x1c02, 0x1c03, + 0x1e00, 0x1e01, 0x1e02, 0x1e03, + 0 }; /* Non-AHCI and Non-RAID Mode */ static const struct pci_driver pch_sata_normal_driver __pci_driver = { .ops = &sata_ops, .vendor = PCI_VENDOR_ID_INTEL, - .device = 0x1c00, -}; -static const struct pci_driver pch_sata_mobile_normal_driver __pci_driver = { - .ops = &sata_ops, - .vendor = PCI_VENDOR_ID_INTEL, - .device = 0x1c01, -}; - -/* AHCI Mode */ -static const struct pci_driver pch_sata_ahci_driver __pci_driver = { - .ops = &sata_ops, - .vendor = PCI_VENDOR_ID_INTEL, - .device = 0x1c02, -}; -static const struct pci_driver pch_sata_mobile_ahci_driver __pci_driver = { - .ops = &sata_ops, - .vendor = PCI_VENDOR_ID_INTEL, - .device = 0x1c03, -}; -static const struct pci_driver pch_sata_mobile_ahci_driver_a __pci_driver = { - .ops = &sata_ops, - .vendor = PCI_VENDOR_ID_INTEL, - .device = 0x1e03, + .devices = all_dev_ids, };