Commit 14b5cb37 authored by Bjorn Helgaas's avatar Bjorn Helgaas

Merge branch 'pci/yijing-ari' into next

* pci/yijing-ari:
  PCI: shpchp: Iterate over all devices in slot, not functions 0-7
  PCI: sgihp: Iterate over all devices in slot, not functions 0-7
  PCI: cpcihp: Iterate over all devices in slot, not functions 0-7
  PCI: pciehp: Iterate over all devices in slot, not functions 0-7
  PCI: Consolidate "next-function" functions
  PCI: Rename pci_enable_ari() to pci_configure_ari()
  PCI: Enable ARI if dev and upstream bridge support it; disable otherwise
parents 708b59bf fcbed0bc
...@@ -252,8 +252,8 @@ int cpci_led_off(struct slot* slot) ...@@ -252,8 +252,8 @@ int cpci_led_off(struct slot* slot)
int __ref cpci_configure_slot(struct slot *slot) int __ref cpci_configure_slot(struct slot *slot)
{ {
struct pci_dev *dev;
struct pci_bus *parent; struct pci_bus *parent;
int fn;
dbg("%s - enter", __func__); dbg("%s - enter", __func__);
...@@ -282,18 +282,13 @@ int __ref cpci_configure_slot(struct slot *slot) ...@@ -282,18 +282,13 @@ int __ref cpci_configure_slot(struct slot *slot)
} }
parent = slot->dev->bus; parent = slot->dev->bus;
for (fn = 0; fn < 8; fn++) { list_for_each_entry(dev, &parent->devices, bus_list)
struct pci_dev *dev; if (PCI_SLOT(dev->devfn) != PCI_SLOT(slot->devfn))
dev = pci_get_slot(parent,
PCI_DEVFN(PCI_SLOT(slot->devfn), fn));
if (!dev)
continue; continue;
if ((dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) || if ((dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) ||
(dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)) (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS))
pci_hp_add_bridge(dev); pci_hp_add_bridge(dev);
pci_dev_put(dev);
}
pci_assign_unassigned_bridge_resources(parent->self); pci_assign_unassigned_bridge_resources(parent->self);
...@@ -305,8 +300,7 @@ int __ref cpci_configure_slot(struct slot *slot) ...@@ -305,8 +300,7 @@ int __ref cpci_configure_slot(struct slot *slot)
int cpci_unconfigure_slot(struct slot* slot) int cpci_unconfigure_slot(struct slot* slot)
{ {
int i; struct pci_dev *dev, *temp;
struct pci_dev *dev;
dbg("%s - enter", __func__); dbg("%s - enter", __func__);
if (!slot->dev) { if (!slot->dev) {
...@@ -314,13 +308,12 @@ int cpci_unconfigure_slot(struct slot* slot) ...@@ -314,13 +308,12 @@ int cpci_unconfigure_slot(struct slot* slot)
return -ENODEV; return -ENODEV;
} }
for (i = 0; i < 8; i++) { list_for_each_entry_safe(dev, temp, &slot->bus->devices, bus_list) {
dev = pci_get_slot(slot->bus, if (PCI_SLOT(dev->devfn) != PCI_SLOT(slot->devfn))
PCI_DEVFN(PCI_SLOT(slot->devfn), i)); continue;
if (dev) { pci_dev_get(dev);
pci_stop_and_remove_bus_device(dev); pci_stop_and_remove_bus_device(dev);
pci_dev_put(dev); pci_dev_put(dev);
}
} }
pci_dev_put(slot->dev); pci_dev_put(slot->dev);
slot->dev = NULL; slot->dev = NULL;
......
...@@ -39,7 +39,7 @@ int pciehp_configure_device(struct slot *p_slot) ...@@ -39,7 +39,7 @@ int pciehp_configure_device(struct slot *p_slot)
struct pci_dev *dev; struct pci_dev *dev;
struct pci_dev *bridge = p_slot->ctrl->pcie->port; struct pci_dev *bridge = p_slot->ctrl->pcie->port;
struct pci_bus *parent = bridge->subordinate; struct pci_bus *parent = bridge->subordinate;
int num, fn; int num;
struct controller *ctrl = p_slot->ctrl; struct controller *ctrl = p_slot->ctrl;
dev = pci_get_slot(parent, PCI_DEVFN(0, 0)); dev = pci_get_slot(parent, PCI_DEVFN(0, 0));
...@@ -57,28 +57,18 @@ int pciehp_configure_device(struct slot *p_slot) ...@@ -57,28 +57,18 @@ int pciehp_configure_device(struct slot *p_slot)
return -ENODEV; return -ENODEV;
} }
for (fn = 0; fn < 8; fn++) { list_for_each_entry(dev, &parent->devices, bus_list)
dev = pci_get_slot(parent, PCI_DEVFN(0, fn));
if (!dev)
continue;
if ((dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) || if ((dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) ||
(dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)) (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS))
pci_hp_add_bridge(dev); pci_hp_add_bridge(dev);
pci_dev_put(dev);
}
pci_assign_unassigned_bridge_resources(bridge); pci_assign_unassigned_bridge_resources(bridge);
for (fn = 0; fn < 8; fn++) { list_for_each_entry(dev, &parent->devices, bus_list) {
dev = pci_get_slot(parent, PCI_DEVFN(0, fn)); if ((dev->class >> 16) == PCI_BASE_CLASS_DISPLAY)
if (!dev)
continue; continue;
if ((dev->class >> 16) == PCI_BASE_CLASS_DISPLAY) {
pci_dev_put(dev);
continue;
}
pci_configure_slot(dev); pci_configure_slot(dev);
pci_dev_put(dev);
} }
pci_bus_add_devices(parent); pci_bus_add_devices(parent);
...@@ -89,9 +79,9 @@ int pciehp_configure_device(struct slot *p_slot) ...@@ -89,9 +79,9 @@ int pciehp_configure_device(struct slot *p_slot)
int pciehp_unconfigure_device(struct slot *p_slot) int pciehp_unconfigure_device(struct slot *p_slot)
{ {
int ret, rc = 0; int ret, rc = 0;
int j;
u8 bctl = 0; u8 bctl = 0;
u8 presence = 0; u8 presence = 0;
struct pci_dev *dev, *temp;
struct pci_bus *parent = p_slot->ctrl->pcie->port->subordinate; struct pci_bus *parent = p_slot->ctrl->pcie->port->subordinate;
u16 command; u16 command;
struct controller *ctrl = p_slot->ctrl; struct controller *ctrl = p_slot->ctrl;
...@@ -102,33 +92,31 @@ int pciehp_unconfigure_device(struct slot *p_slot) ...@@ -102,33 +92,31 @@ int pciehp_unconfigure_device(struct slot *p_slot)
if (ret) if (ret)
presence = 0; presence = 0;
for (j = 0; j < 8; j++) { list_for_each_entry_safe(dev, temp, &parent->devices, bus_list) {
struct pci_dev *temp = pci_get_slot(parent, PCI_DEVFN(0, j)); pci_dev_get(dev);
if (!temp) if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE && presence) {
continue; pci_read_config_byte(dev, PCI_BRIDGE_CONTROL, &bctl);
if (temp->hdr_type == PCI_HEADER_TYPE_BRIDGE && presence) {
pci_read_config_byte(temp, PCI_BRIDGE_CONTROL, &bctl);
if (bctl & PCI_BRIDGE_CTL_VGA) { if (bctl & PCI_BRIDGE_CTL_VGA) {
ctrl_err(ctrl, ctrl_err(ctrl,
"Cannot remove display device %s\n", "Cannot remove display device %s\n",
pci_name(temp)); pci_name(dev));
pci_dev_put(temp); pci_dev_put(dev);
rc = -EINVAL; rc = -EINVAL;
break; break;
} }
} }
pci_stop_and_remove_bus_device(temp); pci_stop_and_remove_bus_device(dev);
/* /*
* Ensure that no new Requests will be generated from * Ensure that no new Requests will be generated from
* the device. * the device.
*/ */
if (presence) { if (presence) {
pci_read_config_word(temp, PCI_COMMAND, &command); pci_read_config_word(dev, PCI_COMMAND, &command);
command &= ~(PCI_COMMAND_MASTER | PCI_COMMAND_SERR); command &= ~(PCI_COMMAND_MASTER | PCI_COMMAND_SERR);
command |= PCI_COMMAND_INTX_DISABLE; command |= PCI_COMMAND_INTX_DISABLE;
pci_write_config_word(temp, PCI_COMMAND, command); pci_write_config_word(dev, PCI_COMMAND, command);
} }
pci_dev_put(temp); pci_dev_put(dev);
} }
return rc; return rc;
......
...@@ -334,7 +334,7 @@ static int enable_slot(struct hotplug_slot *bss_hotplug_slot) ...@@ -334,7 +334,7 @@ static int enable_slot(struct hotplug_slot *bss_hotplug_slot)
struct slot *slot = bss_hotplug_slot->private; struct slot *slot = bss_hotplug_slot->private;
struct pci_bus *new_bus = NULL; struct pci_bus *new_bus = NULL;
struct pci_dev *dev; struct pci_dev *dev;
int func, num_funcs; int num_funcs;
int new_ppb = 0; int new_ppb = 0;
int rc; int rc;
char *ssdt = NULL; char *ssdt = NULL;
...@@ -381,29 +381,26 @@ static int enable_slot(struct hotplug_slot *bss_hotplug_slot) ...@@ -381,29 +381,26 @@ static int enable_slot(struct hotplug_slot *bss_hotplug_slot)
* to the Linux PCI interface and tell the drivers * to the Linux PCI interface and tell the drivers
* about them. * about them.
*/ */
for (func = 0; func < num_funcs; func++) { list_for_each_entry(dev, &slot->pci_bus->devices, bus_list) {
dev = pci_get_slot(slot->pci_bus, if (PCI_SLOT(dev->devfn) != slot->device_num + 1)
PCI_DEVFN(slot->device_num + 1, continue;
PCI_FUNC(func)));
if (dev) { /* Need to do slot fixup on PPB before fixup of children
/* Need to do slot fixup on PPB before fixup of children * (PPB's pcidev_info needs to be in pcidev_info list
* (PPB's pcidev_info needs to be in pcidev_info list * before child's SN_PCIDEV_INFO() call to setup
* before child's SN_PCIDEV_INFO() call to setup * pdi_host_pcidev_info).
* pdi_host_pcidev_info). */
*/ pcibios_fixup_device_resources(dev);
pcibios_fixup_device_resources(dev); if (SN_ACPI_BASE_SUPPORT())
if (SN_ACPI_BASE_SUPPORT()) sn_acpi_slot_fixup(dev);
sn_acpi_slot_fixup(dev); else
else sn_io_slot_fixup(dev);
sn_io_slot_fixup(dev); if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) { pci_hp_add_bridge(dev);
pci_hp_add_bridge(dev); if (dev->subordinate) {
if (dev->subordinate) { new_bus = dev->subordinate;
new_bus = dev->subordinate; new_ppb = 1;
new_ppb = 1;
}
} }
pci_dev_put(dev);
} }
} }
...@@ -481,8 +478,7 @@ static int enable_slot(struct hotplug_slot *bss_hotplug_slot) ...@@ -481,8 +478,7 @@ static int enable_slot(struct hotplug_slot *bss_hotplug_slot)
static int disable_slot(struct hotplug_slot *bss_hotplug_slot) static int disable_slot(struct hotplug_slot *bss_hotplug_slot)
{ {
struct slot *slot = bss_hotplug_slot->private; struct slot *slot = bss_hotplug_slot->private;
struct pci_dev *dev; struct pci_dev *dev, *temp;
int func;
int rc; int rc;
acpi_owner_id ssdt_id = 0; acpi_owner_id ssdt_id = 0;
...@@ -542,15 +538,14 @@ static int disable_slot(struct hotplug_slot *bss_hotplug_slot) ...@@ -542,15 +538,14 @@ static int disable_slot(struct hotplug_slot *bss_hotplug_slot)
} }
/* Free the SN resources assigned to the Linux device.*/ /* Free the SN resources assigned to the Linux device.*/
for (func = 0; func < 8; func++) { list_for_each_entry_safe(dev, temp, &slot->pci_bus->devices, bus_list) {
dev = pci_get_slot(slot->pci_bus, if (PCI_SLOT(dev->devfn) != slot->device_num + 1)
PCI_DEVFN(slot->device_num + 1, continue;
PCI_FUNC(func)));
if (dev) { pci_dev_get(dev);
sn_bus_free_data(dev); sn_bus_free_data(dev);
pci_stop_and_remove_bus_device(dev); pci_stop_and_remove_bus_device(dev);
pci_dev_put(dev); pci_dev_put(dev);
}
} }
/* Remove the SSDT for the slot from the ACPI namespace */ /* Remove the SSDT for the slot from the ACPI namespace */
......
...@@ -40,7 +40,7 @@ int __ref shpchp_configure_device(struct slot *p_slot) ...@@ -40,7 +40,7 @@ int __ref shpchp_configure_device(struct slot *p_slot)
struct controller *ctrl = p_slot->ctrl; struct controller *ctrl = p_slot->ctrl;
struct pci_dev *bridge = ctrl->pci_dev; struct pci_dev *bridge = ctrl->pci_dev;
struct pci_bus *parent = bridge->subordinate; struct pci_bus *parent = bridge->subordinate;
int num, fn; int num;
dev = pci_get_slot(parent, PCI_DEVFN(p_slot->device, 0)); dev = pci_get_slot(parent, PCI_DEVFN(p_slot->device, 0));
if (dev) { if (dev) {
...@@ -57,24 +57,20 @@ int __ref shpchp_configure_device(struct slot *p_slot) ...@@ -57,24 +57,20 @@ int __ref shpchp_configure_device(struct slot *p_slot)
return -ENODEV; return -ENODEV;
} }
for (fn = 0; fn < 8; fn++) { list_for_each_entry(dev, &parent->devices, bus_list) {
dev = pci_get_slot(parent, PCI_DEVFN(p_slot->device, fn)); if (PCI_SLOT(dev->devfn) != p_slot->device)
if (!dev)
continue; continue;
if ((dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) || if ((dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) ||
(dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)) (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS))
pci_hp_add_bridge(dev); pci_hp_add_bridge(dev);
pci_dev_put(dev);
} }
pci_assign_unassigned_bridge_resources(bridge); pci_assign_unassigned_bridge_resources(bridge);
for (fn = 0; fn < 8; fn++) { list_for_each_entry(dev, &parent->devices, bus_list) {
dev = pci_get_slot(parent, PCI_DEVFN(p_slot->device, fn)); if (PCI_SLOT(dev->devfn) != p_slot->device)
if (!dev)
continue; continue;
pci_configure_slot(dev); pci_configure_slot(dev);
pci_dev_put(dev);
} }
pci_bus_add_devices(parent); pci_bus_add_devices(parent);
...@@ -85,32 +81,32 @@ int __ref shpchp_configure_device(struct slot *p_slot) ...@@ -85,32 +81,32 @@ int __ref shpchp_configure_device(struct slot *p_slot)
int shpchp_unconfigure_device(struct slot *p_slot) int shpchp_unconfigure_device(struct slot *p_slot)
{ {
int rc = 0; int rc = 0;
int j;
u8 bctl = 0; u8 bctl = 0;
struct pci_bus *parent = p_slot->ctrl->pci_dev->subordinate; struct pci_bus *parent = p_slot->ctrl->pci_dev->subordinate;
struct pci_dev *dev, *temp;
struct controller *ctrl = p_slot->ctrl; struct controller *ctrl = p_slot->ctrl;
ctrl_dbg(ctrl, "%s: domain:bus:dev = %04x:%02x:%02x\n", ctrl_dbg(ctrl, "%s: domain:bus:dev = %04x:%02x:%02x\n",
__func__, pci_domain_nr(parent), p_slot->bus, p_slot->device); __func__, pci_domain_nr(parent), p_slot->bus, p_slot->device);
for (j = 0; j < 8 ; j++) { list_for_each_entry_safe(dev, temp, &parent->devices, bus_list) {
struct pci_dev *temp = pci_get_slot(parent, if (PCI_SLOT(dev->devfn) != p_slot->device)
(p_slot->device << 3) | j);
if (!temp)
continue; continue;
if (temp->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
pci_read_config_byte(temp, PCI_BRIDGE_CONTROL, &bctl); pci_dev_get(dev);
if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
pci_read_config_byte(dev, PCI_BRIDGE_CONTROL, &bctl);
if (bctl & PCI_BRIDGE_CTL_VGA) { if (bctl & PCI_BRIDGE_CTL_VGA) {
ctrl_err(ctrl, ctrl_err(ctrl,
"Cannot remove display device %s\n", "Cannot remove display device %s\n",
pci_name(temp)); pci_name(dev));
pci_dev_put(temp); pci_dev_put(dev);
rc = -EINVAL; rc = -EINVAL;
break; break;
} }
} }
pci_stop_and_remove_bus_device(temp); pci_stop_and_remove_bus_device(dev);
pci_dev_put(temp); pci_dev_put(dev);
} }
return rc; return rc;
} }
......
...@@ -2042,10 +2042,13 @@ void pci_free_cap_save_buffers(struct pci_dev *dev) ...@@ -2042,10 +2042,13 @@ void pci_free_cap_save_buffers(struct pci_dev *dev)
} }
/** /**
* pci_enable_ari - enable ARI forwarding if hardware support it * pci_configure_ari - enable or disable ARI forwarding
* @dev: the PCI device * @dev: the PCI device
*
* If @dev and its upstream bridge both support ARI, enable ARI in the
* bridge. Otherwise, disable ARI in the bridge.
*/ */
void pci_enable_ari(struct pci_dev *dev) void pci_configure_ari(struct pci_dev *dev)
{ {
u32 cap; u32 cap;
struct pci_dev *bridge; struct pci_dev *bridge;
...@@ -2053,9 +2056,6 @@ void pci_enable_ari(struct pci_dev *dev) ...@@ -2053,9 +2056,6 @@ void pci_enable_ari(struct pci_dev *dev)
if (pcie_ari_disabled || !pci_is_pcie(dev) || dev->devfn) if (pcie_ari_disabled || !pci_is_pcie(dev) || dev->devfn)
return; return;
if (!pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ARI))
return;
bridge = dev->bus->self; bridge = dev->bus->self;
if (!bridge) if (!bridge)
return; return;
...@@ -2064,8 +2064,15 @@ void pci_enable_ari(struct pci_dev *dev) ...@@ -2064,8 +2064,15 @@ void pci_enable_ari(struct pci_dev *dev)
if (!(cap & PCI_EXP_DEVCAP2_ARI)) if (!(cap & PCI_EXP_DEVCAP2_ARI))
return; return;
pcie_capability_set_word(bridge, PCI_EXP_DEVCTL2, PCI_EXP_DEVCTL2_ARI); if (pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ARI)) {
bridge->ari_enabled = 1; pcie_capability_set_word(bridge, PCI_EXP_DEVCTL2,
PCI_EXP_DEVCTL2_ARI);
bridge->ari_enabled = 1;
} else {
pcie_capability_clear_word(bridge, PCI_EXP_DEVCTL2,
PCI_EXP_DEVCTL2_ARI);
bridge->ari_enabled = 0;
}
} }
/** /**
......
...@@ -204,7 +204,7 @@ extern int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, ...@@ -204,7 +204,7 @@ extern int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
extern int pci_resource_bar(struct pci_dev *dev, int resno, extern int pci_resource_bar(struct pci_dev *dev, int resno,
enum pci_bar_type *type); enum pci_bar_type *type);
extern int pci_bus_add_child(struct pci_bus *bus); extern int pci_bus_add_child(struct pci_bus *bus);
extern void pci_enable_ari(struct pci_dev *dev); extern void pci_configure_ari(struct pci_dev *dev);
/** /**
* pci_ari_enabled - query ARI forwarding status * pci_ari_enabled - query ARI forwarding status
* @bus: the PCI bus * @bus: the PCI bus
......
...@@ -1285,7 +1285,7 @@ static void pci_init_capabilities(struct pci_dev *dev) ...@@ -1285,7 +1285,7 @@ static void pci_init_capabilities(struct pci_dev *dev)
pci_vpd_pci22_init(dev); pci_vpd_pci22_init(dev);
/* Alternative Routing-ID Forwarding */ /* Alternative Routing-ID Forwarding */
pci_enable_ari(dev); pci_configure_ari(dev);
/* Single Root I/O Virtualization */ /* Single Root I/O Virtualization */
pci_iov_init(dev); pci_iov_init(dev);
...@@ -1348,31 +1348,31 @@ struct pci_dev *__ref pci_scan_single_device(struct pci_bus *bus, int devfn) ...@@ -1348,31 +1348,31 @@ struct pci_dev *__ref pci_scan_single_device(struct pci_bus *bus, int devfn)
} }
EXPORT_SYMBOL(pci_scan_single_device); EXPORT_SYMBOL(pci_scan_single_device);
static unsigned next_ari_fn(struct pci_dev *dev, unsigned fn) static unsigned next_fn(struct pci_bus *bus, struct pci_dev *dev, unsigned fn)
{ {
u16 cap; int pos;
unsigned pos, next_fn; u16 cap = 0;
unsigned next_fn;
if (!dev) if (pci_ari_enabled(bus)) {
return 0; if (!dev)
return 0;
pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ARI);
if (!pos)
return 0;
pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ARI); pci_read_config_word(dev, pos + PCI_ARI_CAP, &cap);
if (!pos) next_fn = PCI_ARI_CAP_NFN(cap);
return 0; if (next_fn <= fn)
pci_read_config_word(dev, pos + 4, &cap); return 0; /* protect against malformed list */
next_fn = cap >> 8;
if (next_fn <= fn)
return 0;
return next_fn;
}
static unsigned next_trad_fn(struct pci_dev *dev, unsigned fn) return next_fn;
{ }
return (fn + 1) % 8;
} /* dev may be NULL for non-contiguous multifunction devices */
if (!dev || dev->multifunction)
return (fn + 1) % 8;
static unsigned no_next_fn(struct pci_dev *dev, unsigned fn)
{
return 0; return 0;
} }
...@@ -1405,7 +1405,6 @@ int pci_scan_slot(struct pci_bus *bus, int devfn) ...@@ -1405,7 +1405,6 @@ int pci_scan_slot(struct pci_bus *bus, int devfn)
{ {
unsigned fn, nr = 0; unsigned fn, nr = 0;
struct pci_dev *dev; struct pci_dev *dev;
unsigned (*next_fn)(struct pci_dev *, unsigned) = no_next_fn;
if (only_one_child(bus) && (devfn > 0)) if (only_one_child(bus) && (devfn > 0))
return 0; /* Already scanned the entire slot */ return 0; /* Already scanned the entire slot */
...@@ -1416,12 +1415,7 @@ int pci_scan_slot(struct pci_bus *bus, int devfn) ...@@ -1416,12 +1415,7 @@ int pci_scan_slot(struct pci_bus *bus, int devfn)
if (!dev->is_added) if (!dev->is_added)
nr++; nr++;
if (pci_ari_enabled(bus)) for (fn = next_fn(bus, dev, 0); fn > 0; fn = next_fn(bus, dev, fn)) {
next_fn = next_ari_fn;
else if (dev->multifunction)
next_fn = next_trad_fn;
for (fn = next_fn(dev, 0); fn > 0; fn = next_fn(dev, fn)) {
dev = pci_scan_single_device(bus, devfn + fn); dev = pci_scan_single_device(bus, devfn + fn);
if (dev) { if (dev) {
if (!dev->is_added) if (!dev->is_added)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment