Skip to content

Commit

Permalink
PCI: Setup disabled bridges even if buses are added
Browse files Browse the repository at this point in the history
This patch sets up disabled bridges even if buses have already been
added.

pci_assign_unassigned_resources is called after buses are added.
pci_assign_unassigned_resources calls pci_bus_assign_resources.
pci_bus_assign_resources calls pci_setup_bridge to configure BARs of
bridges.

Currently pci_setup_bridge returns immediately if the bus have already
been added. So pci_assign_unassigned_resources can't configure BARs of
bridges that were added in a disabled state; this patch fixes the issue.

On logical hot-add, we need to prevent the kernel from re-initializing
bridges that have already been initialized. To achieve this,
pci_setup_bridge returns immediately if the bridge have already been
enabled.

We don't need to check whether the specified bus is a root bus or not.
pci_setup_bridge is not called on a root bus, because a root bus does
not have a bridge.

The patch adds a new helper function, pci_is_enabled. I made the
function name similar to pci_is_managed. The codes which use
enable_cnt directly are changed to use pci_is_enabled.

Acked-by: Alex Chiang <achiang@hp.com>
Signed-off-by: Yuji Shimada <shimada-yxb@necst.nec.co.jp>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
  • Loading branch information
Yuji Shimada authored and Jesse Barnes committed Apr 6, 2009
1 parent 7eb93b1 commit 296ccb0
Show file tree
Hide file tree
Showing 5 changed files with 10 additions and 5 deletions.
2 changes: 1 addition & 1 deletion drivers/pci/bus.c
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ void pci_enable_bridges(struct pci_bus *bus)

list_for_each_entry(dev, &bus->devices, bus_list) {
if (dev->subordinate) {
if (atomic_read(&dev->enable_cnt) == 0) {
if (!pci_is_enabled(dev)) {
retval = pci_enable_device(dev);
pci_set_master(dev);
}
Expand Down
2 changes: 1 addition & 1 deletion drivers/pci/pci-sysfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ static ssize_t is_enabled_store(struct device *dev,
return -EPERM;

if (!val) {
if (atomic_read(&pdev->enable_cnt) != 0)
if (pci_is_enabled(pdev))
pci_disable_device(pdev);
else
result = -EIO;
Expand Down
4 changes: 2 additions & 2 deletions drivers/pci/pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -844,7 +844,7 @@ static int do_pci_enable_device(struct pci_dev *dev, int bars)
*/
int pci_reenable_device(struct pci_dev *dev)
{
if (atomic_read(&dev->enable_cnt))
if (pci_is_enabled(dev))
return do_pci_enable_device(dev, (1 << PCI_NUM_RESOURCES) - 1);
return 0;
}
Expand Down Expand Up @@ -1042,7 +1042,7 @@ static void do_pci_disable_device(struct pci_dev *dev)
*/
void pci_disable_enabled_device(struct pci_dev *dev)
{
if (atomic_read(&dev->enable_cnt))
if (pci_is_enabled(dev))
do_pci_disable_device(dev);
}

Expand Down
2 changes: 1 addition & 1 deletion drivers/pci/setup-bus.c
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ static void pci_setup_bridge(struct pci_bus *bus)
struct pci_bus_region region;
u32 l, bu, lu, io_upper16;

if (!pci_is_root_bus(bus) && bus->is_added)
if (pci_is_enabled(bridge))
return;

dev_info(&bridge->dev, "PCI bridge, secondary bus %04x:%02x\n",
Expand Down
5 changes: 5 additions & 0 deletions include/linux/pci.h
Original file line number Diff line number Diff line change
Expand Up @@ -674,6 +674,11 @@ int __must_check pci_reenable_device(struct pci_dev *);
int __must_check pcim_enable_device(struct pci_dev *pdev);
void pcim_pin_device(struct pci_dev *pdev);

static inline int pci_is_enabled(struct pci_dev *pdev)
{
return (atomic_read(&pdev->enable_cnt) > 0);
}

static inline int pci_is_managed(struct pci_dev *pdev)
{
return pdev->is_managed;
Expand Down

0 comments on commit 296ccb0

Please sign in to comment.