PCI: introduce pci_assign_unassigned_bridge_resources
For use by pciehp. pci_setup_bridge() will not check enabled for the slot bridge, otherwise update res is not updated to bridge BAR. That is, bridge is already enabled for port service. Signed-off-by: Yinghai Lu <yinghai@kernel.org> Reviewed-by: Alex Chiang <achiang@hp.com> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
This commit is contained in:
parent
977d17bb17
commit
6841ec681a
|
@ -71,35 +71,34 @@ static void free_failed_list(struct resource_list_x *head)
|
|||
head->next = NULL;
|
||||
}
|
||||
|
||||
static void pbus_assign_resources_sorted(const struct pci_bus *bus,
|
||||
struct resource_list_x *fail_head)
|
||||
static void __dev_sort_resources(struct pci_dev *dev,
|
||||
struct resource_list *head)
|
||||
{
|
||||
struct pci_dev *dev;
|
||||
struct resource *res;
|
||||
struct resource_list head, *list, *tmp;
|
||||
int idx;
|
||||
u16 class = dev->class >> 8;
|
||||
|
||||
head.next = NULL;
|
||||
list_for_each_entry(dev, &bus->devices, bus_list) {
|
||||
u16 class = dev->class >> 8;
|
||||
/* Don't touch classless devices or host bridges or ioapics. */
|
||||
if (class == PCI_CLASS_NOT_DEFINED || class == PCI_CLASS_BRIDGE_HOST)
|
||||
return;
|
||||
|
||||
/* Don't touch classless devices or host bridges or ioapics. */
|
||||
if (class == PCI_CLASS_NOT_DEFINED ||
|
||||
class == PCI_CLASS_BRIDGE_HOST)
|
||||
continue;
|
||||
|
||||
/* Don't touch ioapic devices already enabled by firmware */
|
||||
if (class == PCI_CLASS_SYSTEM_PIC) {
|
||||
u16 command;
|
||||
pci_read_config_word(dev, PCI_COMMAND, &command);
|
||||
if (command & (PCI_COMMAND_IO | PCI_COMMAND_MEMORY))
|
||||
continue;
|
||||
}
|
||||
|
||||
pdev_sort_resources(dev, &head);
|
||||
/* Don't touch ioapic devices already enabled by firmware */
|
||||
if (class == PCI_CLASS_SYSTEM_PIC) {
|
||||
u16 command;
|
||||
pci_read_config_word(dev, PCI_COMMAND, &command);
|
||||
if (command & (PCI_COMMAND_IO | PCI_COMMAND_MEMORY))
|
||||
return;
|
||||
}
|
||||
|
||||
for (list = head.next; list;) {
|
||||
pdev_sort_resources(dev, head);
|
||||
}
|
||||
|
||||
static void __assign_resources_sorted(struct resource_list *head,
|
||||
struct resource_list_x *fail_head)
|
||||
{
|
||||
struct resource *res;
|
||||
struct resource_list *list, *tmp;
|
||||
int idx;
|
||||
|
||||
for (list = head->next; list;) {
|
||||
res = list->res;
|
||||
idx = res - &list->dev->resource[0];
|
||||
if (pci_assign_resource(list->dev, idx)) {
|
||||
|
@ -115,6 +114,30 @@ static void pbus_assign_resources_sorted(const struct pci_bus *bus,
|
|||
}
|
||||
}
|
||||
|
||||
static void pdev_assign_resources_sorted(struct pci_dev *dev,
|
||||
struct resource_list_x *fail_head)
|
||||
{
|
||||
struct resource_list head;
|
||||
|
||||
head.next = NULL;
|
||||
__dev_sort_resources(dev, &head);
|
||||
__assign_resources_sorted(&head, fail_head);
|
||||
|
||||
}
|
||||
|
||||
static void pbus_assign_resources_sorted(const struct pci_bus *bus,
|
||||
struct resource_list_x *fail_head)
|
||||
{
|
||||
struct pci_dev *dev;
|
||||
struct resource_list head;
|
||||
|
||||
head.next = NULL;
|
||||
list_for_each_entry(dev, &bus->devices, bus_list)
|
||||
__dev_sort_resources(dev, &head);
|
||||
|
||||
__assign_resources_sorted(&head, fail_head);
|
||||
}
|
||||
|
||||
void pci_setup_cardbus(struct pci_bus *bus)
|
||||
{
|
||||
struct pci_dev *bridge = bus->self;
|
||||
|
@ -273,9 +296,6 @@ static void __pci_setup_bridge(struct pci_bus *bus, unsigned long type)
|
|||
{
|
||||
struct pci_dev *bridge = bus->self;
|
||||
|
||||
if (pci_is_enabled(bridge))
|
||||
return;
|
||||
|
||||
dev_info(&bridge->dev, "PCI bridge to [bus %02x-%02x]\n",
|
||||
bus->secondary, bus->subordinate);
|
||||
|
||||
|
@ -646,7 +666,8 @@ static void __ref __pci_bus_assign_resources(const struct pci_bus *bus,
|
|||
|
||||
switch (dev->class >> 8) {
|
||||
case PCI_CLASS_BRIDGE_PCI:
|
||||
pci_setup_bridge(b);
|
||||
if (!pci_is_enabled(dev))
|
||||
pci_setup_bridge(b);
|
||||
break;
|
||||
|
||||
case PCI_CLASS_BRIDGE_CARDBUS:
|
||||
|
@ -667,6 +688,34 @@ void __ref pci_bus_assign_resources(const struct pci_bus *bus)
|
|||
}
|
||||
EXPORT_SYMBOL(pci_bus_assign_resources);
|
||||
|
||||
static void __ref __pci_bridge_assign_resources(const struct pci_dev *bridge,
|
||||
struct resource_list_x *fail_head)
|
||||
{
|
||||
struct pci_bus *b;
|
||||
|
||||
pdev_assign_resources_sorted((struct pci_dev *)bridge, fail_head);
|
||||
|
||||
b = bridge->subordinate;
|
||||
if (!b)
|
||||
return;
|
||||
|
||||
__pci_bus_assign_resources(b, fail_head);
|
||||
|
||||
switch (bridge->class >> 8) {
|
||||
case PCI_CLASS_BRIDGE_PCI:
|
||||
pci_setup_bridge(b);
|
||||
break;
|
||||
|
||||
case PCI_CLASS_BRIDGE_CARDBUS:
|
||||
pci_setup_cardbus(b);
|
||||
break;
|
||||
|
||||
default:
|
||||
dev_info(&bridge->dev, "not setting up bridge for bus "
|
||||
"%04x:%02x\n", pci_domain_nr(b), b->number);
|
||||
break;
|
||||
}
|
||||
}
|
||||
static void pci_bridge_release_resources(struct pci_bus *bus,
|
||||
unsigned long type)
|
||||
{
|
||||
|
@ -911,3 +960,16 @@ enable_and_dump:
|
|||
pci_bus_dump_resources(bus);
|
||||
}
|
||||
}
|
||||
|
||||
void pci_assign_unassigned_bridge_resources(struct pci_dev *bridge)
|
||||
{
|
||||
struct pci_bus *parent = bridge->subordinate;
|
||||
int retval;
|
||||
|
||||
pci_bus_size_bridges(parent);
|
||||
__pci_bridge_assign_resources(bridge, NULL);
|
||||
retval = pci_reenable_device(bridge);
|
||||
pci_set_master(bridge);
|
||||
pci_enable_bridges(parent);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(pci_assign_unassigned_bridge_resources);
|
||||
|
|
|
@ -801,6 +801,7 @@ void pci_bus_assign_resources(const struct pci_bus *bus);
|
|||
void pci_bus_size_bridges(struct pci_bus *bus);
|
||||
int pci_claim_resource(struct pci_dev *, int);
|
||||
void pci_assign_unassigned_resources(void);
|
||||
void pci_assign_unassigned_bridge_resources(struct pci_dev *bridge);
|
||||
void pdev_enable_device(struct pci_dev *);
|
||||
void pdev_sort_resources(struct pci_dev *, struct resource_list *);
|
||||
int pci_enable_resources(struct pci_dev *, int mask);
|
||||
|
|
Loading…
Reference in New Issue