This commit was manufactured by cvs2svn to create tag
[linux-2.6.git] / drivers / pci / pci-driver.c
index 7ce952c..64195d6 100644 (file)
  *  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
  */
@@ -270,16 +291,6 @@ static int pci_device_remove(struct device * dev)
                        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;
 }
@@ -305,8 +316,8 @@ static int pci_device_suspend(struct device * dev, u32 state)
        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;
 }
 
@@ -318,7 +329,7 @@ static int pci_device_suspend(struct device * dev, u32 state)
 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);
@@ -393,30 +404,30 @@ pci_populate_driver_dir(struct pci_driver *drv)
  * @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;
 }
 
 /**
@@ -501,9 +512,16 @@ static int pci_bus_match(struct device * dev, struct device_driver * drv)
  */
 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;
 }
 
 /**