* Registration of PCI drivers and handling of hot-pluggable devices.
*/
+/**
+ * pci_match_one_device - Tell if a PCI device structure has a matching
+ * PCI device id structure
+ * @id: single PCI device id structure to match
+ * @dev: the PCI device structure to match against
+ *
+ * Returns the matching pci_device_id structure or %NULL if there is no match.
+ */
+
+static inline const struct pci_device_id *
+pci_match_one_device(const struct pci_device_id *id, const struct pci_dev *dev)
+{
+ if ((id->vendor == PCI_ANY_ID || id->vendor == dev->vendor) &&
+ (id->device == PCI_ANY_ID || id->device == dev->device) &&
+ (id->subvendor == PCI_ANY_ID || id->subvendor == dev->subsystem_vendor) &&
+ (id->subdevice == PCI_ANY_ID || id->subdevice == dev->subsystem_device) &&
+ !((id->class ^ dev->class) & id->class_mask))
+ return id;
+ return NULL;
+}
+
/*
* Dynamic device IDs are disabled for !CONFIG_HOTPLUG
*/
drv->remove(pci_dev);
pci_dev->driver = NULL;
}
-
- /*
- * We would love to complain here if pci_dev->is_enabled is set, that
- * the driver should have called pci_disable_device(), but the
- * unfortunate fact is there are too many odd BIOS and bridge setups
- * that don't like drivers doing that all of the time.
- * Oh well, we can dream of sane hardware when we sleep, no matter how
- * horrible the crap we have to deal with is when we are awake...
- */
-
pci_dev_put(pci_dev);
return 0;
}
dev_state = state_conversion[state];
if (drv && drv->suspend)
i = drv->suspend(pci_dev, dev_state);
- else
- pci_save_state(pci_dev);
+
+ pci_save_state(pci_dev, pci_dev->saved_config_space);
return i;
}
static void pci_default_resume(struct pci_dev *pci_dev)
{
/* restore the PCI config space */
- pci_restore_state(pci_dev);
+ pci_restore_state(pci_dev, pci_dev->saved_config_space);
/* if the device was enabled before suspend, reenable */
if (pci_dev->is_enabled)
pci_enable_device(pci_dev);
* @drv: the driver structure to register
*
* Adds the driver structure to the list of registered drivers.
- * Returns a negative value on error, otherwise 0.
- * If no error occured, the driver remains registered even if
- * no device was claimed during registration.
+ * Returns a negative value on error. The driver remains registered
+ * even if no device was claimed during registration.
*/
-int pci_register_driver(struct pci_driver *drv)
+int
+pci_register_driver(struct pci_driver *drv)
{
- int error;
+ int count = 0;
/* initialize common driver fields */
drv->driver.name = drv->name;
drv->driver.bus = &pci_bus_type;
drv->driver.probe = pci_device_probe;
drv->driver.remove = pci_device_remove;
- drv->driver.owner = drv->owner;
drv->driver.kobj.ktype = &pci_driver_kobj_type;
pci_init_dynids(&drv->dynids);
/* register with core */
- error = driver_register(&drv->driver);
+ count = driver_register(&drv->driver);
- if (!error)
+ if (count >= 0) {
pci_populate_driver_dir(drv);
+ }
- return error;
+ return count ? count : 1;
}
/**
*/
struct pci_dev *pci_dev_get(struct pci_dev *dev)
{
- if (dev)
- get_device(&dev->dev);
- return dev;
+ struct device *tmp;
+
+ if (!dev)
+ return NULL;
+
+ tmp = get_device(&dev->dev);
+ if (tmp)
+ return to_pci_dev(tmp);
+ else
+ return NULL;
}
/**