Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jbarnes/pci-2.6
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jbarnes/pci-2.6: PCI: clear bridge resource range if BIOS assigned bad one PCI: hotplug/cpqphp, fix NULL dereference Revert "PCI: create function symlinks in /sys/bus/pci/slots/N/" PCI: change resource collision messages from KERN_ERR to KERN_INFO
This commit is contained in:
Коммит
eda054770e
|
@ -133,46 +133,6 @@ Description:
|
||||||
The symbolic link points to the PCI device sysfs entry of the
|
The symbolic link points to the PCI device sysfs entry of the
|
||||||
Physical Function this device associates with.
|
Physical Function this device associates with.
|
||||||
|
|
||||||
|
|
||||||
What: /sys/bus/pci/slots/...
|
|
||||||
Date: April 2005 (possibly older)
|
|
||||||
KernelVersion: 2.6.12 (possibly older)
|
|
||||||
Contact: linux-pci@vger.kernel.org
|
|
||||||
Description:
|
|
||||||
When the appropriate driver is loaded, it will create a
|
|
||||||
directory per claimed physical PCI slot in
|
|
||||||
/sys/bus/pci/slots/. The names of these directories are
|
|
||||||
specific to the driver, which in turn, are specific to the
|
|
||||||
platform, but in general, should match the label on the
|
|
||||||
machine's physical chassis.
|
|
||||||
|
|
||||||
The drivers that can create slot directories include the
|
|
||||||
PCI hotplug drivers, and as of 2.6.27, the pci_slot driver.
|
|
||||||
|
|
||||||
The slot directories contain, at a minimum, a file named
|
|
||||||
'address' which contains the PCI bus:device:function tuple.
|
|
||||||
Other files may appear as well, but are specific to the
|
|
||||||
driver.
|
|
||||||
|
|
||||||
What: /sys/bus/pci/slots/.../function[0-7]
|
|
||||||
Date: March 2010
|
|
||||||
KernelVersion: 2.6.35
|
|
||||||
Contact: linux-pci@vger.kernel.org
|
|
||||||
Description:
|
|
||||||
If PCI slot directories (as described above) are created,
|
|
||||||
and the physical slot is actually populated with a device,
|
|
||||||
symbolic links in the slot directory pointing to the
|
|
||||||
device's PCI functions are created as well.
|
|
||||||
|
|
||||||
What: /sys/bus/pci/devices/.../slot
|
|
||||||
Date: March 2010
|
|
||||||
KernelVersion: 2.6.35
|
|
||||||
Contact: linux-pci@vger.kernel.org
|
|
||||||
Description:
|
|
||||||
If PCI slot directories (as described above) are created,
|
|
||||||
a symbolic link pointing to the slot directory will be
|
|
||||||
created as well.
|
|
||||||
|
|
||||||
What: /sys/bus/pci/slots/.../module
|
What: /sys/bus/pci/slots/.../module
|
||||||
Date: June 2009
|
Date: June 2009
|
||||||
Contact: linux-pci@vger.kernel.org
|
Contact: linux-pci@vger.kernel.org
|
||||||
|
|
|
@ -1277,6 +1277,7 @@ void pcibios_allocate_bus_resources(struct pci_bus *bus)
|
||||||
printk(KERN_WARNING "PCI: Cannot allocate resource region "
|
printk(KERN_WARNING "PCI: Cannot allocate resource region "
|
||||||
"%d of PCI bridge %d, will remap\n", i, bus->number);
|
"%d of PCI bridge %d, will remap\n", i, bus->number);
|
||||||
clear_resource:
|
clear_resource:
|
||||||
|
res->start = res->end = 0;
|
||||||
res->flags = 0;
|
res->flags = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -117,6 +117,7 @@ static void __init pcibios_allocate_bus_resources(struct list_head *bus_list)
|
||||||
* Invalidate the resource to prevent
|
* Invalidate the resource to prevent
|
||||||
* child resource allocations in this
|
* child resource allocations in this
|
||||||
* range. */
|
* range. */
|
||||||
|
r->start = r->end = 0;
|
||||||
r->flags = 0;
|
r->flags = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1309,6 +1309,7 @@ void pcibios_allocate_bus_resources(struct pci_bus *bus)
|
||||||
printk(KERN_WARNING "PCI: Cannot allocate resource region "
|
printk(KERN_WARNING "PCI: Cannot allocate resource region "
|
||||||
"%d of PCI bridge %d, will remap\n", i, bus->number);
|
"%d of PCI bridge %d, will remap\n", i, bus->number);
|
||||||
clear_resource:
|
clear_resource:
|
||||||
|
res->start = res->end = 0;
|
||||||
res->flags = 0;
|
res->flags = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -96,6 +96,7 @@ EXPORT_SYMBOL(pcibios_align_resource);
|
||||||
* the fact the PCI specs explicitly allow address decoders to be
|
* the fact the PCI specs explicitly allow address decoders to be
|
||||||
* shared between expansion ROMs and other resource regions, it's
|
* shared between expansion ROMs and other resource regions, it's
|
||||||
* at least dangerous)
|
* at least dangerous)
|
||||||
|
* - bad resource sizes or overlaps with other regions
|
||||||
*
|
*
|
||||||
* Our solution:
|
* Our solution:
|
||||||
* (1) Allocate resources for all buses behind PCI-to-PCI bridges.
|
* (1) Allocate resources for all buses behind PCI-to-PCI bridges.
|
||||||
|
@ -136,6 +137,7 @@ static void __init pcibios_allocate_bus_resources(struct list_head *bus_list)
|
||||||
* child resource allocations in this
|
* child resource allocations in this
|
||||||
* range.
|
* range.
|
||||||
*/
|
*/
|
||||||
|
r->start = r->end = 0;
|
||||||
r->flags = 0;
|
r->flags = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -828,7 +828,14 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||||
pci_name(pdev), err);
|
pci_name(pdev), err);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
bus = pdev->subordinate;
|
bus = pdev->subordinate;
|
||||||
|
if (!bus) {
|
||||||
|
dev_notice(&pdev->dev, "the device is not a bridge, "
|
||||||
|
"skipping\n");
|
||||||
|
rc = -ENODEV;
|
||||||
|
goto err_disable_device;
|
||||||
|
}
|
||||||
|
|
||||||
/* Need to read VID early b/c it's used to differentiate CPQ and INTC
|
/* Need to read VID early b/c it's used to differentiate CPQ and INTC
|
||||||
* discovery
|
* discovery
|
||||||
|
|
|
@ -1035,39 +1035,6 @@ error:
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pci_remove_slot_links(struct pci_dev *dev)
|
|
||||||
{
|
|
||||||
char func[10];
|
|
||||||
struct pci_slot *slot;
|
|
||||||
|
|
||||||
sysfs_remove_link(&dev->dev.kobj, "slot");
|
|
||||||
list_for_each_entry(slot, &dev->bus->slots, list) {
|
|
||||||
if (slot->number != PCI_SLOT(dev->devfn))
|
|
||||||
continue;
|
|
||||||
snprintf(func, 10, "function%d", PCI_FUNC(dev->devfn));
|
|
||||||
sysfs_remove_link(&slot->kobj, func);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static int pci_create_slot_links(struct pci_dev *dev)
|
|
||||||
{
|
|
||||||
int result = 0;
|
|
||||||
char func[10];
|
|
||||||
struct pci_slot *slot;
|
|
||||||
|
|
||||||
list_for_each_entry(slot, &dev->bus->slots, list) {
|
|
||||||
if (slot->number != PCI_SLOT(dev->devfn))
|
|
||||||
continue;
|
|
||||||
result = sysfs_create_link(&dev->dev.kobj, &slot->kobj, "slot");
|
|
||||||
if (result)
|
|
||||||
goto out;
|
|
||||||
snprintf(func, 10, "function%d", PCI_FUNC(dev->devfn));
|
|
||||||
result = sysfs_create_link(&slot->kobj, &dev->dev.kobj, func);
|
|
||||||
}
|
|
||||||
out:
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
int __must_check pci_create_sysfs_dev_files (struct pci_dev *pdev)
|
int __must_check pci_create_sysfs_dev_files (struct pci_dev *pdev)
|
||||||
{
|
{
|
||||||
int retval;
|
int retval;
|
||||||
|
@ -1130,8 +1097,6 @@ int __must_check pci_create_sysfs_dev_files (struct pci_dev *pdev)
|
||||||
if (retval)
|
if (retval)
|
||||||
goto err_vga_file;
|
goto err_vga_file;
|
||||||
|
|
||||||
pci_create_slot_links(pdev);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err_vga_file:
|
err_vga_file:
|
||||||
|
@ -1181,8 +1146,6 @@ void pci_remove_sysfs_dev_files(struct pci_dev *pdev)
|
||||||
if (!sysfs_initialized)
|
if (!sysfs_initialized)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
pci_remove_slot_links(pdev);
|
|
||||||
|
|
||||||
pci_remove_capabilities_sysfs(pdev);
|
pci_remove_capabilities_sysfs(pdev);
|
||||||
|
|
||||||
if (pdev->cfg_size < PCI_CFG_SPACE_EXP_SIZE)
|
if (pdev->cfg_size < PCI_CFG_SPACE_EXP_SIZE)
|
||||||
|
|
|
@ -97,16 +97,16 @@ int pci_claim_resource(struct pci_dev *dev, int resource)
|
||||||
|
|
||||||
root = pci_find_parent_resource(dev, res);
|
root = pci_find_parent_resource(dev, res);
|
||||||
if (!root) {
|
if (!root) {
|
||||||
dev_err(&dev->dev, "no compatible bridge window for %pR\n",
|
dev_info(&dev->dev, "no compatible bridge window for %pR\n",
|
||||||
res);
|
res);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
conflict = request_resource_conflict(root, res);
|
conflict = request_resource_conflict(root, res);
|
||||||
if (conflict) {
|
if (conflict) {
|
||||||
dev_err(&dev->dev,
|
dev_info(&dev->dev,
|
||||||
"address space collision: %pR conflicts with %s %pR\n",
|
"address space collision: %pR conflicts with %s %pR\n",
|
||||||
res, conflict->name, conflict);
|
res, conflict->name, conflict);
|
||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -97,50 +97,6 @@ static ssize_t cur_speed_read_file(struct pci_slot *slot, char *buf)
|
||||||
return bus_speed_read(slot->bus->cur_bus_speed, buf);
|
return bus_speed_read(slot->bus->cur_bus_speed, buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void remove_sysfs_files(struct pci_slot *slot)
|
|
||||||
{
|
|
||||||
char func[10];
|
|
||||||
struct list_head *tmp;
|
|
||||||
|
|
||||||
list_for_each(tmp, &slot->bus->devices) {
|
|
||||||
struct pci_dev *dev = pci_dev_b(tmp);
|
|
||||||
if (PCI_SLOT(dev->devfn) != slot->number)
|
|
||||||
continue;
|
|
||||||
sysfs_remove_link(&dev->dev.kobj, "slot");
|
|
||||||
|
|
||||||
snprintf(func, 10, "function%d", PCI_FUNC(dev->devfn));
|
|
||||||
sysfs_remove_link(&slot->kobj, func);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static int create_sysfs_files(struct pci_slot *slot)
|
|
||||||
{
|
|
||||||
int result;
|
|
||||||
char func[10];
|
|
||||||
struct list_head *tmp;
|
|
||||||
|
|
||||||
list_for_each(tmp, &slot->bus->devices) {
|
|
||||||
struct pci_dev *dev = pci_dev_b(tmp);
|
|
||||||
if (PCI_SLOT(dev->devfn) != slot->number)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
result = sysfs_create_link(&dev->dev.kobj, &slot->kobj, "slot");
|
|
||||||
if (result)
|
|
||||||
goto fail;
|
|
||||||
|
|
||||||
snprintf(func, 10, "function%d", PCI_FUNC(dev->devfn));
|
|
||||||
result = sysfs_create_link(&slot->kobj, &dev->dev.kobj, func);
|
|
||||||
if (result)
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
fail:
|
|
||||||
remove_sysfs_files(slot);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void pci_slot_release(struct kobject *kobj)
|
static void pci_slot_release(struct kobject *kobj)
|
||||||
{
|
{
|
||||||
struct pci_dev *dev;
|
struct pci_dev *dev;
|
||||||
|
@ -153,8 +109,6 @@ static void pci_slot_release(struct kobject *kobj)
|
||||||
if (PCI_SLOT(dev->devfn) == slot->number)
|
if (PCI_SLOT(dev->devfn) == slot->number)
|
||||||
dev->slot = NULL;
|
dev->slot = NULL;
|
||||||
|
|
||||||
remove_sysfs_files(slot);
|
|
||||||
|
|
||||||
list_del(&slot->list);
|
list_del(&slot->list);
|
||||||
|
|
||||||
kfree(slot);
|
kfree(slot);
|
||||||
|
@ -346,8 +300,6 @@ placeholder:
|
||||||
INIT_LIST_HEAD(&slot->list);
|
INIT_LIST_HEAD(&slot->list);
|
||||||
list_add(&slot->list, &parent->slots);
|
list_add(&slot->list, &parent->slots);
|
||||||
|
|
||||||
create_sysfs_files(slot);
|
|
||||||
|
|
||||||
list_for_each_entry(dev, &parent->devices, bus_list)
|
list_for_each_entry(dev, &parent->devices, bus_list)
|
||||||
if (PCI_SLOT(dev->devfn) == slot_nr)
|
if (PCI_SLOT(dev->devfn) == slot_nr)
|
||||||
dev->slot = slot;
|
dev->slot = slot;
|
||||||
|
|
Загрузка…
Ссылка в новой задаче