diff options
author | Anton Altaparmakov <aia21@cantab.net> | 2005-06-23 11:26:22 +0100 |
---|---|---|
committer | Anton Altaparmakov <aia21@cantab.net> | 2005-06-23 11:26:22 +0100 |
commit | 3357d4c75f1fb67e7304998c4ad4e9a9fed66fa4 (patch) | |
tree | ceba46966a5a1112a05d257d8ecb25ae5eee95e0 /drivers/pci | |
parent | 364f6c717deef4a3ac4982e670fa9846b43cd060 (diff) | |
parent | ee98689be1b054897ff17655008c3048fe88be94 (diff) |
Automatic merge with /usr/src/ntfs-2.6.git.
Diffstat (limited to 'drivers/pci')
-rw-r--r-- | drivers/pci/hotplug/cpci_hotplug_core.c | 2 | ||||
-rw-r--r-- | drivers/pci/hotplug/cpci_hotplug_pci.c | 5 | ||||
-rw-r--r-- | drivers/pci/hotplug/cpqphp_sysfs.c | 4 | ||||
-rw-r--r-- | drivers/pci/hotplug/pci_hotplug_core.c | 4 | ||||
-rw-r--r-- | drivers/pci/hotplug/rpadlpar_sysfs.c | 2 | ||||
-rw-r--r-- | drivers/pci/hotplug/shpchp_sysfs.c | 4 | ||||
-rw-r--r-- | drivers/pci/pci-driver.c | 31 | ||||
-rw-r--r-- | drivers/pci/pci-sysfs.c | 21 | ||||
-rw-r--r-- | drivers/pci/pcie/portdrv_core.c | 139 | ||||
-rw-r--r-- | drivers/pci/probe.c | 2 | ||||
-rw-r--r-- | drivers/pci/quirks.c | 6 |
11 files changed, 114 insertions, 106 deletions
diff --git a/drivers/pci/hotplug/cpci_hotplug_core.c b/drivers/pci/hotplug/cpci_hotplug_core.c index 8132d946c38..30af105271a 100644 --- a/drivers/pci/hotplug/cpci_hotplug_core.c +++ b/drivers/pci/hotplug/cpci_hotplug_core.c @@ -217,6 +217,8 @@ static void release_slot(struct hotplug_slot *hotplug_slot) kfree(slot->hotplug_slot->info); kfree(slot->hotplug_slot->name); kfree(slot->hotplug_slot); + if (slot->dev) + pci_dev_put(slot->dev); kfree(slot); } diff --git a/drivers/pci/hotplug/cpci_hotplug_pci.c b/drivers/pci/hotplug/cpci_hotplug_pci.c index c878028ad21..225b5e551dd 100644 --- a/drivers/pci/hotplug/cpci_hotplug_pci.c +++ b/drivers/pci/hotplug/cpci_hotplug_pci.c @@ -315,9 +315,12 @@ int cpci_unconfigure_slot(struct slot* slot) PCI_DEVFN(PCI_SLOT(slot->devfn), i)); if (dev) { pci_remove_bus_device(dev); - slot->dev = NULL; + pci_dev_put(dev); } } + pci_dev_put(slot->dev); + slot->dev = NULL; + dbg("%s - exit", __FUNCTION__); return 0; } diff --git a/drivers/pci/hotplug/cpqphp_sysfs.c b/drivers/pci/hotplug/cpqphp_sysfs.c index 41c7971d06c..4c11048ad51 100644 --- a/drivers/pci/hotplug/cpqphp_sysfs.c +++ b/drivers/pci/hotplug/cpqphp_sysfs.c @@ -38,7 +38,7 @@ /* A few routines that create sysfs entries for the hot plug controller */ -static ssize_t show_ctrl (struct device *dev, char *buf) +static ssize_t show_ctrl (struct device *dev, struct device_attribute *attr, char *buf) { struct pci_dev *pci_dev; struct controller *ctrl; @@ -82,7 +82,7 @@ static ssize_t show_ctrl (struct device *dev, char *buf) } static DEVICE_ATTR (ctrl, S_IRUGO, show_ctrl, NULL); -static ssize_t show_dev (struct device *dev, char *buf) +static ssize_t show_dev (struct device *dev, struct device_attribute *attr, char *buf) { struct pci_dev *pci_dev; struct controller *ctrl; diff --git a/drivers/pci/hotplug/pci_hotplug_core.c b/drivers/pci/hotplug/pci_hotplug_core.c index c802f6270b8..c4282902cb5 100644 --- a/drivers/pci/hotplug/pci_hotplug_core.c +++ b/drivers/pci/hotplug/pci_hotplug_core.c @@ -73,7 +73,7 @@ static ssize_t hotplug_slot_attr_show(struct kobject *kobj, { struct hotplug_slot *slot = to_hotplug_slot(kobj); struct hotplug_slot_attribute *attribute = to_hotplug_attr(attr); - return attribute->show ? attribute->show(slot, buf) : 0; + return attribute->show ? attribute->show(slot, buf) : -EIO; } static ssize_t hotplug_slot_attr_store(struct kobject *kobj, @@ -81,7 +81,7 @@ static ssize_t hotplug_slot_attr_store(struct kobject *kobj, { struct hotplug_slot *slot = to_hotplug_slot(kobj); struct hotplug_slot_attribute *attribute = to_hotplug_attr(attr); - return attribute->store ? attribute->store(slot, buf, len) : 0; + return attribute->store ? attribute->store(slot, buf, len) : -EIO; } static struct sysfs_ops hotplug_slot_sysfs_ops = { diff --git a/drivers/pci/hotplug/rpadlpar_sysfs.c b/drivers/pci/hotplug/rpadlpar_sysfs.c index 3285b822478..752e6513c44 100644 --- a/drivers/pci/hotplug/rpadlpar_sysfs.c +++ b/drivers/pci/hotplug/rpadlpar_sysfs.c @@ -48,7 +48,7 @@ dlpar_attr_store(struct kobject * kobj, struct attribute * attr, struct dlpar_io_attr *dlpar_attr = container_of(attr, struct dlpar_io_attr, attr); return dlpar_attr->store ? - dlpar_attr->store(dlpar_attr, buf, nbytes) : 0; + dlpar_attr->store(dlpar_attr, buf, nbytes) : -EIO; } static struct sysfs_ops dlpar_attr_sysfs_ops = { diff --git a/drivers/pci/hotplug/shpchp_sysfs.c b/drivers/pci/hotplug/shpchp_sysfs.c index 9a1ee132d12..c9445ebda5c 100644 --- a/drivers/pci/hotplug/shpchp_sysfs.c +++ b/drivers/pci/hotplug/shpchp_sysfs.c @@ -38,7 +38,7 @@ /* A few routines that create sysfs entries for the hot plug controller */ -static ssize_t show_ctrl (struct device *dev, char *buf) +static ssize_t show_ctrl (struct device *dev, struct device_attribute *attr, char *buf) { struct pci_dev *pci_dev; struct controller *ctrl; @@ -82,7 +82,7 @@ static ssize_t show_ctrl (struct device *dev, char *buf) } static DEVICE_ATTR (ctrl, S_IRUGO, show_ctrl, NULL); -static ssize_t show_dev (struct device *dev, char *buf) +static ssize_t show_dev (struct device *dev, struct device_attribute *attr, char *buf) { struct pci_dev *pci_dev; struct controller *ctrl; diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c index fe98553c978..e65bf2b395a 100644 --- a/drivers/pci/pci-driver.c +++ b/drivers/pci/pci-driver.c @@ -335,13 +335,14 @@ pci_driver_attr_show(struct kobject * kobj, struct attribute *attr, char *buf) { struct device_driver *driver = kobj_to_pci_driver(kobj); struct driver_attribute *dattr = attr_to_driver_attribute(attr); - ssize_t ret = 0; + ssize_t ret; - if (get_driver(driver)) { - if (dattr->show) - ret = dattr->show(driver, buf); - put_driver(driver); - } + if (!get_driver(driver)) + return -ENODEV; + + ret = dattr->show ? dattr->show(driver, buf) : -EIO; + + put_driver(driver); return ret; } @@ -351,13 +352,14 @@ pci_driver_attr_store(struct kobject * kobj, struct attribute *attr, { struct device_driver *driver = kobj_to_pci_driver(kobj); struct driver_attribute *dattr = attr_to_driver_attribute(attr); - ssize_t ret = 0; + ssize_t ret; - if (get_driver(driver)) { - if (dattr->store) - ret = dattr->store(driver, buf, count); - put_driver(driver); - } + if (!get_driver(driver)) + return -ENODEV; + + ret = dattr->store ? dattr->store(driver, buf, count) : -EIO; + + put_driver(driver); return ret; } @@ -393,7 +395,10 @@ int pci_register_driver(struct pci_driver *drv) drv->driver.bus = &pci_bus_type; drv->driver.probe = pci_device_probe; drv->driver.remove = pci_device_remove; - drv->driver.shutdown = pci_device_shutdown, + /* FIXME, once all of the existing PCI drivers have been fixed to set + * the pci shutdown function, this test can go away. */ + if (!drv->driver.shutdown) + drv->driver.shutdown = pci_device_shutdown; drv->driver.owner = drv->owner; drv->driver.kobj.ktype = &pci_driver_kobj_type; pci_init_dynids(&drv->dynids); diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c index 6ca0061137a..a15f94072a6 100644 --- a/drivers/pci/pci-sysfs.c +++ b/drivers/pci/pci-sysfs.c @@ -29,7 +29,7 @@ static int sysfs_initialized; /* = 0 */ /* show configuration fields */ #define pci_config_attr(field, format_string) \ static ssize_t \ -field##_show(struct device *dev, char *buf) \ +field##_show(struct device *dev, struct device_attribute *attr, char *buf) \ { \ struct pci_dev *pdev; \ \ @@ -44,7 +44,7 @@ pci_config_attr(subsystem_device, "0x%04x\n"); pci_config_attr(class, "0x%06x\n"); pci_config_attr(irq, "%u\n"); -static ssize_t local_cpus_show(struct device *dev, char *buf) +static ssize_t local_cpus_show(struct device *dev, struct device_attribute *attr, char *buf) { cpumask_t mask = pcibus_to_cpumask(to_pci_dev(dev)->bus); int len = cpumask_scnprintf(buf, PAGE_SIZE-2, mask); @@ -54,7 +54,7 @@ static ssize_t local_cpus_show(struct device *dev, char *buf) /* show resources */ static ssize_t -resource_show(struct device * dev, char * buf) +resource_show(struct device * dev, struct device_attribute *attr, char * buf) { struct pci_dev * pci_dev = to_pci_dev(dev); char * str = buf; @@ -73,7 +73,7 @@ resource_show(struct device * dev, char * buf) return (str - buf); } -static ssize_t modalias_show(struct device *dev, char *buf) +static ssize_t modalias_show(struct device *dev, struct device_attribute *attr, char *buf) { struct pci_dev *pci_dev = to_pci_dev(dev); @@ -339,16 +339,17 @@ pci_create_resource_files(struct pci_dev *pdev) if (!pci_resource_len(pdev, i)) continue; - res_attr = kmalloc(sizeof(*res_attr) + 10, GFP_ATOMIC); + /* allocate attribute structure, piggyback attribute name */ + res_attr = kcalloc(1, sizeof(*res_attr) + 10, GFP_ATOMIC); if (res_attr) { - memset(res_attr, 0, sizeof(*res_attr) + 10); + char *res_attr_name = (char *)(res_attr + 1); + pdev->res_attr[i] = res_attr; - /* Allocated above after the res_attr struct */ - res_attr->attr.name = (char *)(res_attr + 1); - sprintf(res_attr->attr.name, "resource%d", i); - res_attr->size = pci_resource_len(pdev, i); + sprintf(res_attr_name, "resource%d", i); + res_attr->attr.name = res_attr_name; res_attr->attr.mode = S_IRUSR | S_IWUSR; res_attr->attr.owner = THIS_MODULE; + res_attr->size = pci_resource_len(pdev, i); res_attr->mmap = pci_mmap_resource; res_attr->private = &pdev->resource[i]; sysfs_create_bin_file(&pdev->dev.kobj, res_attr); diff --git a/drivers/pci/pcie/portdrv_core.c b/drivers/pci/pcie/portdrv_core.c index 576285765e9..f5c5f10a3d2 100644 --- a/drivers/pci/pcie/portdrv_core.c +++ b/drivers/pci/pcie/portdrv_core.c @@ -232,19 +232,16 @@ static void pcie_device_init(struct pci_dev *parent, struct pcie_device *dev, /* Initialize generic device interface */ device = &dev->device; memset(device, 0, sizeof(struct device)); - INIT_LIST_HEAD(&device->node); - INIT_LIST_HEAD(&device->children); - INIT_LIST_HEAD(&device->bus_list); device->bus = &pcie_port_bus_type; device->driver = NULL; - device->driver_data = NULL; + device->driver_data = NULL; device->release = release_pcie_device; /* callback to free pcie dev */ - sprintf(&device->bus_id[0], "pcie%02x", + sprintf(&device->bus_id[0], "pcie%02x", get_descriptor_id(port_type, service_type)); device->parent = &parent->dev; } -static struct pcie_device* alloc_pcie_device(struct pci_dev *parent, +static struct pcie_device* alloc_pcie_device(struct pci_dev *parent, int port_type, int service_type, int irq, int irq_mode) { struct pcie_device *device; @@ -270,9 +267,9 @@ int pcie_port_device_probe(struct pci_dev *dev) pci_read_config_word(dev, pos + PCIE_CAPABILITIES_REG, ®); type = (reg >> 4) & PORT_TYPE_MASK; if ( type == PCIE_RC_PORT || type == PCIE_SW_UPSTREAM_PORT || - type == PCIE_SW_DOWNSTREAM_PORT ) + type == PCIE_SW_DOWNSTREAM_PORT ) return 0; - + return -ENODEV; } @@ -283,8 +280,8 @@ int pcie_port_device_register(struct pci_dev *dev) u16 reg16; /* Get port type */ - pci_read_config_word(dev, - pci_find_capability(dev, PCI_CAP_ID_EXP) + + pci_read_config_word(dev, + pci_find_capability(dev, PCI_CAP_ID_EXP) + PCIE_CAPABILITIES_REG, ®16); type = (reg16 >> 4) & PORT_TYPE_MASK; @@ -299,11 +296,11 @@ int pcie_port_device_register(struct pci_dev *dev) if (capabilities & (1 << i)) { child = alloc_pcie_device( dev, /* parent */ - type, /* port type */ + type, /* port type */ i, /* service type */ vectors[i], /* irq */ irq_mode /* interrupt mode */); - if (child) { + if (child) { status = device_register(&child->device); if (status) { kfree(child); @@ -317,84 +314,78 @@ int pcie_port_device_register(struct pci_dev *dev) } #ifdef CONFIG_PM -int pcie_port_device_suspend(struct pci_dev *dev, pm_message_t state) +static int suspend_iter(struct device *dev, void *data) { - struct list_head *head, *tmp; - struct device *parent, *child; - struct device_driver *driver; struct pcie_port_service_driver *service_driver; + u32 state = (u32)data; + + if ((dev->bus == &pcie_port_bus_type) && + (dev->driver)) { + service_driver = to_service_driver(dev->driver); + if (service_driver->suspend) + service_driver->suspend(to_pcie_device(dev), state); + } + return 0; +} - parent = &dev->dev; - head = &parent->children; - tmp = head->next; - while (head != tmp) { - child = container_of(tmp, struct device, node); - tmp = tmp->next; - if (child->bus != &pcie_port_bus_type) - continue; - driver = child->driver; - if (!driver) - continue; - service_driver = to_service_driver(driver); - if (service_driver->suspend) - service_driver->suspend(to_pcie_device(child), state); - } - return 0; +int pcie_port_device_suspend(struct pci_dev *dev, u32 state) +{ + device_for_each_child(&dev->dev, (void *)state, suspend_iter); + return 0; } -int pcie_port_device_resume(struct pci_dev *dev) -{ - struct list_head *head, *tmp; - struct device *parent, *child; - struct device_driver *driver; +static int resume_iter(struct device *dev, void *data) +{ struct pcie_port_service_driver *service_driver; - parent = &dev->dev; - head = &parent->children; - tmp = head->next; - while (head != tmp) { - child = container_of(tmp, struct device, node); - tmp = tmp->next; - if (child->bus != &pcie_port_bus_type) - continue; - driver = child->driver; - if (!driver) - continue; - service_driver = to_service_driver(driver); - if (service_driver->resume) - service_driver->resume(to_pcie_device(child)); + if ((dev->bus == &pcie_port_bus_type) && + (dev->driver)) { + service_driver = to_service_driver(dev->driver); + if (service_driver->resume) + service_driver->resume(to_pcie_device(dev)); } - return 0; + return 0; +} +int pcie_port_device_resume(struct pci_dev *dev) +{ + device_for_each_child(&dev->dev, NULL, resume_iter); + return 0; } #endif -void pcie_port_device_remove(struct pci_dev *dev) +static int remove_iter(struct device *dev, void *data) { - struct list_head *head, *tmp; - struct device *parent, *child; - struct device_driver *driver; struct pcie_port_service_driver *service_driver; - int interrupt_mode = PCIE_PORT_INTx_MODE; - parent = &dev->dev; - head = &parent->children; - tmp = head->next; - while (head != tmp) { - child = container_of(tmp, struct device, node); - tmp = tmp->next; - if (child->bus != &pcie_port_bus_type) - continue; - driver = child->driver; - if (driver) { - service_driver = to_service_driver(driver); - if (service_driver->remove) - service_driver->remove(to_pcie_device(child)); + if (dev->bus == &pcie_port_bus_type) { + if (dev->driver) { + service_driver = to_service_driver(dev->driver); + if (service_driver->remove) + service_driver->remove(to_pcie_device(dev)); } - interrupt_mode = (to_pcie_device(child))->interrupt_mode; - put_device(child); - device_unregister(child); + *(unsigned long*)data = (unsigned long)dev; + return 1; } + return 0; +} + +void pcie_port_device_remove(struct pci_dev *dev) +{ + struct device *device; + unsigned long device_addr; + int interrupt_mode = PCIE_PORT_INTx_MODE; + int status; + + do { + status = device_for_each_child(&dev->dev, &device_addr, remove_iter); + if (status) { + device = (struct device*)device_addr; + interrupt_mode = (to_pcie_device(device))->interrupt_mode; + put_device(device); + device_unregister(device); + } + } while (status); /* Switch to INTx by default if MSI enabled */ if (interrupt_mode == PCIE_PORT_MSIX_MODE) pci_disable_msix(dev); @@ -423,7 +414,7 @@ int pcie_port_service_register(struct pcie_port_service_driver *new) new->driver.resume = pcie_port_resume_service; return driver_register(&new->driver); -} +} void pcie_port_service_unregister(struct pcie_port_service_driver *new) { diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index b7ae87823c6..fd48b201eb5 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -125,7 +125,7 @@ static inline unsigned int pci_calc_resource_flags(unsigned int flags) /* * Find the extent of a PCI decode.. */ -static u32 pci_size(u32 base, u32 maxbase, unsigned long mask) +static u32 pci_size(u32 base, u32 maxbase, u32 mask) { u32 size = mask & maxbase; /* Find the significant bits */ if (!size) diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 2194669300b..968033fd29f 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -456,6 +456,12 @@ static void __init quirk_amd_8131_ioapic(struct pci_dev *dev) } DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8131_APIC, quirk_amd_8131_ioapic ); +static void __init quirk_svw_msi(struct pci_dev *dev) +{ + pci_msi_quirk = 1; + printk(KERN_WARNING "PCI: MSI quirk detected. pci_msi_quirk set.\n"); +} +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_GCNB_LE, quirk_svw_msi ); #endif /* CONFIG_X86_IO_APIC */ |