diff options
author | Vadim Bendebury <vbendeb@chromium.org> | 2012-04-24 12:53:19 -0700 |
---|---|---|
committer | Patrick Georgi <patrick@georgi-clan.de> | 2012-05-01 20:02:21 +0200 |
commit | 8049fc91ded9d780b9f6d5c40bc43ad3242b7a3b (patch) | |
tree | a2e4295afbe11c4838d1ec303a78b778eab154df /src/devices | |
parent | 599e204efc5a55eb388a2ff11afb0e2196c21875 (diff) |
Allow device ID arrays in the PCI driver structure
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 <vbendeb@chromium.org>
Reviewed-on: http://review.coreboot.org/982
Tested-by: build bot (Jenkins)
Reviewed-by: Kyösti Mälkki <kyosti.malkki@gmail.com>
Reviewed-by: Patrick Georgi <patrick@georgi-clan.de>
Diffstat (limited to 'src/devices')
-rw-r--r-- | src/devices/pci_device.c | 24 |
1 files changed, 23 insertions, 1 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 @@ -796,6 +796,28 @@ static struct device_operations *get_pci_bridge_ops(device_t dev) } /** + * 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. * * Check if it already has a driver. If not, use find_device_operations(), @@ -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, |