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>
This commit is contained in:
parent
599e204efc
commit
8049fc91de
|
@ -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,
|
||||
|
|
|
@ -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")))
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue