* [PATCH v2 1/3] PCI: rework pci_enable_ari for support disable ari forwarding
@ 2012-10-16 7:10 Yijing Wang
2012-10-16 7:10 ` [PATCH v2 2/3] PCI: introduce pci_next_fn to get next func number Yijing Wang
2012-10-16 7:10 ` [PATCH v2 3/3] PCI, pciehp: ARI device hotplug support Yijing Wang
0 siblings, 2 replies; 5+ messages in thread
From: Yijing Wang @ 2012-10-16 7:10 UTC (permalink / raw)
To: Bjorn Helgaas, Yu Zhao, kernel.openeuler
Cc: linux-pci, Yinghai Lu, Hanjun Guo, jiang.liu, Yijing Wang
pci_enable_ari will be called if an ARI pci device found, set its bridge ARI Forwarding Enable
bit in Device Control 2 Register. But the bridge ARI Forwarding Enable bit will never be cleared
when an ARI device hot removed.
1. Hot add an ARI pci device;
2. Hot remove the ARI pci device;
3. Hot add an non ARI pci device;
In this case, we could only find fun 0 of non ARI pci device because of its bridge ARI Forwarding Enable
bit set.
As PCIe Spec 2.0(6.13/441) recommends:
"Following a hot-plug event below a Downstream Port, it is strongly recommended that software
Clear the ARI Forwarding Enable bit in the Downstream Port until software determines that a
newly added component is in fact an ARI Device"
So, this patch rework pci_enable_ari to support enable/disable ARI when a new device hot add.
Signed-off-by: Yijing Wang <wangyijing@huawei.com>
Signed-off-by: Jiang Liu <jiang.liu@huawei.com>
---
drivers/pci/pci.c | 21 +++++++++++++--------
drivers/pci/pci.h | 2 +-
drivers/pci/probe.c | 2 +-
3 files changed, 15 insertions(+), 10 deletions(-)
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 5485883..38f1ad6 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -2010,10 +2010,10 @@ 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 if hardware support it
* @dev: the PCI device
*/
-void pci_enable_ari(struct pci_dev *dev)
+void pci_configure_ari(struct pci_dev *dev)
{
u32 cap;
struct pci_dev *bridge;
@@ -2021,9 +2021,6 @@ void pci_enable_ari(struct pci_dev *dev)
if (pcie_ari_disabled || !pci_is_pcie(dev) || dev->devfn)
return;
- if (!pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ARI))
- return;
-
bridge = dev->bus->self;
if (!bridge)
return;
@@ -2031,10 +2028,18 @@ void pci_enable_ari(struct pci_dev *dev)
pcie_capability_read_dword(bridge, PCI_EXP_DEVCAP2, &cap);
if (!(cap & PCI_EXP_DEVCAP2_ARI))
return;
-
- pcie_capability_set_word(bridge, PCI_EXP_DEVCTL2, PCI_EXP_DEVCTL2_ARI);
- bridge->ari_enabled = 1;
+
+ if (pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ARI)) {
+ 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;
+ }
}
+EXPORT_SYMBOL(pci_configure_ari);
/**
* pci_enable_ido - enable ID-based Ordering on a device
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index bacbcba..d6eb3d9 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -211,7 +211,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,
enum pci_bar_type *type);
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
* @bus: the PCI bus
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index ec909af..bb7ecf6 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -1282,7 +1282,7 @@ static void pci_init_capabilities(struct pci_dev *dev)
pci_vpd_pci22_init(dev);
/* Alternative Routing-ID Forwarding */
- pci_enable_ari(dev);
+ pci_configure_ari(dev);
/* Single Root I/O Virtualization */
pci_iov_init(dev);
--
1.7.1
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH v2 2/3] PCI: introduce pci_next_fn to get next func number
2012-10-16 7:10 [PATCH v2 1/3] PCI: rework pci_enable_ari for support disable ari forwarding Yijing Wang
@ 2012-10-16 7:10 ` Yijing Wang
2012-10-16 7:10 ` [PATCH v2 3/3] PCI, pciehp: ARI device hotplug support Yijing Wang
1 sibling, 0 replies; 5+ messages in thread
From: Yijing Wang @ 2012-10-16 7:10 UTC (permalink / raw)
To: Bjorn Helgaas, Yu Zhao, kernel.openeuler
Cc: linux-pci, Yinghai Lu, Hanjun Guo, jiang.liu, Yijing Wang
Introduce pci_next_fn function to get next fn number.Since
this function maybe used by PCI module(eg. pciehp),so export it.
Signed-off-by: Yijing Wang <wangyijing@huawei.com>
Signed-off-by: Jiang Liu <jiang.liu@huawei.com>
---
drivers/pci/pci.h | 1 +
drivers/pci/probe.c | 67 +++++++++++++++++++++++++++++---------------------
2 files changed, 40 insertions(+), 28 deletions(-)
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index d6eb3d9..fe411f4 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -212,6 +212,7 @@ extern int pci_resource_bar(struct pci_dev *dev, int resno,
enum pci_bar_type *type);
extern int pci_bus_add_child(struct pci_bus *bus);
extern void pci_configure_ari(struct pci_dev *dev);
+extern int pci_next_fn(struct pci_bus *parent, int devfn);
/**
* pci_ari_enabled - query ARI forwarding status
* @bus: the PCI bus
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index bb7ecf6..435ee60 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -1345,33 +1345,49 @@ struct pci_dev *__ref pci_scan_single_device(struct pci_bus *bus, int devfn)
}
EXPORT_SYMBOL(pci_scan_single_device);
-static unsigned next_ari_fn(struct pci_dev *dev, unsigned fn)
+/**
+ * pci_next_fn - get next fn number for device
+ * @bus: PCI bus on which desired PCI Function device resides
+ * @devfn: encodes number of pci device
+ *
+ * return next_fn if success, if can not find next fn or fail,
+ * 0 is returned.
+ */
+int pci_next_fn(struct pci_bus *bus, int devfn)
{
u16 cap;
- unsigned pos, next_fn;
-
+ unsigned pos, next_fn = 0;
+ struct pci_dev *dev;
+
+ if (!bus || devfn < 0)
+ goto out;
+
+ dev = pci_get_slot(bus, devfn);
if (!dev)
- return 0;
+ goto out;
- pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ARI);
- if (!pos)
- return 0;
- pci_read_config_word(dev, pos + 4, &cap);
- next_fn = cap >> 8;
- if (next_fn <= fn)
- return 0;
+ if (!pci_ari_enabled(bus)) {
+ if (!dev->multifunction)
+ goto release;
+ else
+ next_fn = (PCI_FUNC(devfn) + 1) % 8;
+ } else {
+ pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ARI);
+ if (!pos)
+ goto release;
+ pci_read_config_word(dev, pos + 4, &cap);
+ next_fn = cap >> 8;
+ if (next_fn <= PCI_FUNC(devfn)) {
+ next_fn = 0;
+ goto release;
+ }
+ }
+release:
+ pci_dev_put(dev);
+out:
return next_fn;
}
-
-static unsigned next_trad_fn(struct pci_dev *dev, unsigned fn)
-{
- return (fn + 1) % 8;
-}
-
-static unsigned no_next_fn(struct pci_dev *dev, unsigned fn)
-{
- return 0;
-}
+EXPORT_SYMBOL(pci_next_fn);
static int only_one_child(struct pci_bus *bus)
{
@@ -1402,7 +1418,6 @@ int pci_scan_slot(struct pci_bus *bus, int devfn)
{
unsigned fn, nr = 0;
struct pci_dev *dev;
- unsigned (*next_fn)(struct pci_dev *, unsigned) = no_next_fn;
if (only_one_child(bus) && (devfn > 0))
return 0; /* Already scanned the entire slot */
@@ -1413,12 +1428,8 @@ int pci_scan_slot(struct pci_bus *bus, int devfn)
if (!dev->is_added)
nr++;
- if (pci_ari_enabled(bus))
- 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)) {
+ for (fn = pci_next_fn(bus, PCI_DEVFN(PCI_SLOT(devfn), 0)); fn > 0;
+ fn = pci_next_fn(bus, PCI_DEVFN(PCI_SLOT(devfn), fn))) {
dev = pci_scan_single_device(bus, devfn + fn);
if (dev) {
if (!dev->is_added)
--
1.7.1
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH v2 3/3] PCI, pciehp: ARI device hotplug support
2012-10-16 7:10 [PATCH v2 1/3] PCI: rework pci_enable_ari for support disable ari forwarding Yijing Wang
2012-10-16 7:10 ` [PATCH v2 2/3] PCI: introduce pci_next_fn to get next func number Yijing Wang
@ 2012-10-16 7:10 ` Yijing Wang
2013-01-08 17:44 ` Bjorn Helgaas
1 sibling, 1 reply; 5+ messages in thread
From: Yijing Wang @ 2012-10-16 7:10 UTC (permalink / raw)
To: Bjorn Helgaas, Yu Zhao, kernel.openeuler
Cc: linux-pci, Yinghai Lu, Hanjun Guo, jiang.liu, Yijing Wang
ARI device supports up to 256 Functions, pciehp now only scan and configure
Functions from 0 to 7, this patch fix this problem for ARI device hotplug.
Signed-off-by: Yijing Wang <wangyijing@huawei.com>
---
drivers/pci/hotplug/pciehp_pci.c | 40 ++++++++++++++++++++++++++-----------
1 files changed, 28 insertions(+), 12 deletions(-)
diff --git a/drivers/pci/hotplug/pciehp_pci.c b/drivers/pci/hotplug/pciehp_pci.c
index 09cecaf..b37e8a0 100644
--- a/drivers/pci/hotplug/pciehp_pci.c
+++ b/drivers/pci/hotplug/pciehp_pci.c
@@ -39,7 +39,7 @@ int pciehp_configure_device(struct slot *p_slot)
struct pci_dev *dev;
struct pci_dev *bridge = p_slot->ctrl->pcie->port;
struct pci_bus *parent = bridge->subordinate;
- int num, fn;
+ int num, fn = 0;
struct controller *ctrl = p_slot->ctrl;
dev = pci_get_slot(parent, PCI_DEVFN(0, 0));
@@ -56,21 +56,31 @@ int pciehp_configure_device(struct slot *p_slot)
ctrl_err(ctrl, "No new device found\n");
return -ENODEV;
}
-
- for (fn = 0; fn < 8; fn++) {
- dev = pci_get_slot(parent, PCI_DEVFN(0, fn));
+
+ do {
+ if (pci_ari_enabled(parent))
+ dev = pci_get_slot(parent, fn);
+ else
+ dev = pci_get_slot(parent, PCI_DEVFN(0, fn));
+
+ fn = pci_next_fn(parent, PCI_DEVFN(0, fn));
if (!dev)
continue;
if ((dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) ||
(dev->hdr_type == PCI_HEADER_TYPE_CARDBUS))
pci_hp_add_bridge(dev);
pci_dev_put(dev);
- }
+ } while (fn);
pci_assign_unassigned_bridge_resources(bridge);
- for (fn = 0; fn < 8; fn++) {
- dev = pci_get_slot(parent, PCI_DEVFN(0, fn));
+ do {
+ if (pci_ari_enabled(parent))
+ dev = pci_get_slot(parent, fn);
+ else
+ dev = pci_get_slot(parent, PCI_DEVFN(0, fn));
+
+ fn = pci_next_fn(parent, PCI_DEVFN(0, fn));
if (!dev)
continue;
if ((dev->class >> 16) == PCI_BASE_CLASS_DISPLAY) {
@@ -79,7 +89,7 @@ int pciehp_configure_device(struct slot *p_slot)
}
pci_configure_slot(dev);
pci_dev_put(dev);
- }
+ } while (fn);
pci_bus_add_devices(parent);
@@ -89,21 +99,27 @@ int pciehp_configure_device(struct slot *p_slot)
int pciehp_unconfigure_device(struct slot *p_slot)
{
int ret, rc = 0;
- int j;
+ int fn = 0;
u8 bctl = 0;
u8 presence = 0;
struct pci_bus *parent = p_slot->ctrl->pcie->port->subordinate;
u16 command;
struct controller *ctrl = p_slot->ctrl;
+ struct pci_dev *temp;
ctrl_dbg(ctrl, "%s: domain:bus:dev = %04x:%02x:00\n",
__func__, pci_domain_nr(parent), parent->number);
ret = pciehp_get_adapter_status(p_slot, &presence);
if (ret)
presence = 0;
+
+ do {
+ if (pci_ari_enabled(parent))
+ temp = pci_get_slot(parent, fn);
+ else
+ temp = pci_get_slot(parent, PCI_DEVFN(0, fn));
- for (j = 0; j < 8; j++) {
- struct pci_dev *temp = pci_get_slot(parent, PCI_DEVFN(0, j));
+ fn = pci_next_fn(parent, PCI_DEVFN(0, fn));
if (!temp)
continue;
if (temp->hdr_type == PCI_HEADER_TYPE_BRIDGE && presence) {
@@ -129,7 +145,7 @@ int pciehp_unconfigure_device(struct slot *p_slot)
pci_write_config_word(temp, PCI_COMMAND, command);
}
pci_dev_put(temp);
- }
+ } while (fn);
return rc;
}
--
1.7.1
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH v2 3/3] PCI, pciehp: ARI device hotplug support
2012-10-16 7:10 ` [PATCH v2 3/3] PCI, pciehp: ARI device hotplug support Yijing Wang
@ 2013-01-08 17:44 ` Bjorn Helgaas
2013-01-09 7:37 ` Yijing Wang
0 siblings, 1 reply; 5+ messages in thread
From: Bjorn Helgaas @ 2013-01-08 17:44 UTC (permalink / raw)
To: Yijing Wang
Cc: Yu Zhao, kernel.openeuler, linux-pci, Yinghai Lu, Hanjun Guo,
jiang.liu, Kenji Kaneshige
[+cc Kenji]
On Tue, Oct 16, 2012 at 1:10 AM, Yijing Wang <wangyijing@huawei.com> wrote:
> ARI device supports up to 256 Functions, pciehp now only scan and configure
> Functions from 0 to 7, this patch fix this problem for ARI device hotplug.
>
> Signed-off-by: Yijing Wang <wangyijing@huawei.com>
> ---
> drivers/pci/hotplug/pciehp_pci.c | 40 ++++++++++++++++++++++++++-----------
> 1 files changed, 28 insertions(+), 12 deletions(-)
>
> diff --git a/drivers/pci/hotplug/pciehp_pci.c b/drivers/pci/hotplug/pciehp_pci.c
> index 09cecaf..b37e8a0 100644
> --- a/drivers/pci/hotplug/pciehp_pci.c
> +++ b/drivers/pci/hotplug/pciehp_pci.c
> @@ -39,7 +39,7 @@ int pciehp_configure_device(struct slot *p_slot)
> struct pci_dev *dev;
> struct pci_dev *bridge = p_slot->ctrl->pcie->port;
> struct pci_bus *parent = bridge->subordinate;
> - int num, fn;
> + int num, fn = 0;
> struct controller *ctrl = p_slot->ctrl;
>
> dev = pci_get_slot(parent, PCI_DEVFN(0, 0));
> @@ -56,21 +56,31 @@ int pciehp_configure_device(struct slot *p_slot)
> ctrl_err(ctrl, "No new device found\n");
> return -ENODEV;
> }
> -
> - for (fn = 0; fn < 8; fn++) {
> - dev = pci_get_slot(parent, PCI_DEVFN(0, fn));
> +
> + do {
> + if (pci_ari_enabled(parent))
> + dev = pci_get_slot(parent, fn);
> + else
> + dev = pci_get_slot(parent, PCI_DEVFN(0, fn));
> +
> + fn = pci_next_fn(parent, PCI_DEVFN(0, fn));
This doesn't make sense to me. We just called pci_scan_slot(), which
already used pci_next_fn() to find all the functions. We shouldn't
have to have the ARI knowledge and pci_next_fn() looping here again
(and yet again after pci_assign_unassigned_bridge_resources()).
According to the pci_scan_slot() function comment, all the
newly-discovered devices should be on the bus->devices list. And in
fact, the similar code in acpiphp (enable_device()) *does* use the
bus->devices list.
I think cpci_configure_slot(), pciehp_configure_device(),
enable_slot() in sgi_hotplug.c, and shpchp_configure_device() should
be changed to use the bus->devices list. In addition, I think the
refcount management (pci_get_slot()/pci_dev_put()) should be removed.
> if (!dev)
> continue;
> if ((dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) ||
> (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS))
> pci_hp_add_bridge(dev);
> pci_dev_put(dev);
> - }
> + } while (fn);
>
> pci_assign_unassigned_bridge_resources(bridge);
>
> - for (fn = 0; fn < 8; fn++) {
> - dev = pci_get_slot(parent, PCI_DEVFN(0, fn));
> + do {
> + if (pci_ari_enabled(parent))
> + dev = pci_get_slot(parent, fn);
> + else
> + dev = pci_get_slot(parent, PCI_DEVFN(0, fn));
> +
> + fn = pci_next_fn(parent, PCI_DEVFN(0, fn));
> if (!dev)
> continue;
> if ((dev->class >> 16) == PCI_BASE_CLASS_DISPLAY) {
> @@ -79,7 +89,7 @@ int pciehp_configure_device(struct slot *p_slot)
> }
> pci_configure_slot(dev);
> pci_dev_put(dev);
> - }
> + } while (fn);
>
> pci_bus_add_devices(parent);
>
> @@ -89,21 +99,27 @@ int pciehp_configure_device(struct slot *p_slot)
> int pciehp_unconfigure_device(struct slot *p_slot)
> {
> int ret, rc = 0;
> - int j;
> + int fn = 0;
> u8 bctl = 0;
> u8 presence = 0;
> struct pci_bus *parent = p_slot->ctrl->pcie->port->subordinate;
> u16 command;
> struct controller *ctrl = p_slot->ctrl;
> + struct pci_dev *temp;
>
> ctrl_dbg(ctrl, "%s: domain:bus:dev = %04x:%02x:00\n",
> __func__, pci_domain_nr(parent), parent->number);
> ret = pciehp_get_adapter_status(p_slot, &presence);
> if (ret)
> presence = 0;
> +
> + do {
> + if (pci_ari_enabled(parent))
> + temp = pci_get_slot(parent, fn);
> + else
> + temp = pci_get_slot(parent, PCI_DEVFN(0, fn));
>
> - for (j = 0; j < 8; j++) {
> - struct pci_dev *temp = pci_get_slot(parent, PCI_DEVFN(0, j));
> + fn = pci_next_fn(parent, PCI_DEVFN(0, fn));
> if (!temp)
> continue;
> if (temp->hdr_type == PCI_HEADER_TYPE_BRIDGE && presence) {
> @@ -129,7 +145,7 @@ int pciehp_unconfigure_device(struct slot *p_slot)
> pci_write_config_word(temp, PCI_COMMAND, command);
> }
> pci_dev_put(temp);
> - }
> + } while (fn);
>
> return rc;
> }
> --
> 1.7.1
>
>
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH v2 3/3] PCI, pciehp: ARI device hotplug support
2013-01-08 17:44 ` Bjorn Helgaas
@ 2013-01-09 7:37 ` Yijing Wang
0 siblings, 0 replies; 5+ messages in thread
From: Yijing Wang @ 2013-01-09 7:37 UTC (permalink / raw)
To: Bjorn Helgaas
Cc: Yu Zhao, kernel.openeuler, linux-pci, Yinghai Lu, Hanjun Guo,
jiang.liu, Kenji Kaneshige
On 2013/1/9 1:44, Bjorn Helgaas wrote:
> [+cc Kenji]
>
> On Tue, Oct 16, 2012 at 1:10 AM, Yijing Wang <wangyijing@huawei.com> wrote:
>> ARI device supports up to 256 Functions, pciehp now only scan and configure
>> Functions from 0 to 7, this patch fix this problem for ARI device hotplug.
>>
>> Signed-off-by: Yijing Wang <wangyijing@huawei.com>
>> ---
>> drivers/pci/hotplug/pciehp_pci.c | 40 ++++++++++++++++++++++++++-----------
>> 1 files changed, 28 insertions(+), 12 deletions(-)
>>
>> diff --git a/drivers/pci/hotplug/pciehp_pci.c b/drivers/pci/hotplug/pciehp_pci.c
>> index 09cecaf..b37e8a0 100644
>> --- a/drivers/pci/hotplug/pciehp_pci.c
>> +++ b/drivers/pci/hotplug/pciehp_pci.c
>> @@ -39,7 +39,7 @@ int pciehp_configure_device(struct slot *p_slot)
>> struct pci_dev *dev;
>> struct pci_dev *bridge = p_slot->ctrl->pcie->port;
>> struct pci_bus *parent = bridge->subordinate;
>> - int num, fn;
>> + int num, fn = 0;
>> struct controller *ctrl = p_slot->ctrl;
>>
>> dev = pci_get_slot(parent, PCI_DEVFN(0, 0));
>> @@ -56,21 +56,31 @@ int pciehp_configure_device(struct slot *p_slot)
>> ctrl_err(ctrl, "No new device found\n");
>> return -ENODEV;
>> }
>> -
>> - for (fn = 0; fn < 8; fn++) {
>> - dev = pci_get_slot(parent, PCI_DEVFN(0, fn));
>> +
>> + do {
>> + if (pci_ari_enabled(parent))
>> + dev = pci_get_slot(parent, fn);
>> + else
>> + dev = pci_get_slot(parent, PCI_DEVFN(0, fn));
>> +
>> + fn = pci_next_fn(parent, PCI_DEVFN(0, fn));
>
> This doesn't make sense to me. We just called pci_scan_slot(), which
> already used pci_next_fn() to find all the functions. We shouldn't
> have to have the ARI knowledge and pci_next_fn() looping here again
> (and yet again after pci_assign_unassigned_bridge_resources()).
>
> According to the pci_scan_slot() function comment, all the
> newly-discovered devices should be on the bus->devices list. And in
> fact, the similar code in acpiphp (enable_device()) *does* use the
> bus->devices list.
>
Hi Bjorn,
Thanks for your review and comment! You are right, use bus->devices list is a better solution.
I will update my ARI device hotplug support patchset and send out again.
> I think cpci_configure_slot(), pciehp_configure_device(),
> enable_slot() in sgi_hotplug.c, and shpchp_configure_device() should
> be changed to use the bus->devices list. In addition, I think the
> refcount management (pci_get_slot()/pci_dev_put()) should be removed.
Remove pci_get_slot()/pci_dev_put() here looks good to me, Because refcount increment when pci_scan_slot,
here remove the refcount management is safe.
I will change this and test in my machine, and send out this patch if test result is ok.
Thanks very much!
Yijing.
>
>> if (!dev)
>> continue;
>> if ((dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) ||
>> (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS))
>> pci_hp_add_bridge(dev);
>> pci_dev_put(dev);
>> - }
>> + } while (fn);
>>
>> pci_assign_unassigned_bridge_resources(bridge);
>>
>> - for (fn = 0; fn < 8; fn++) {
>> - dev = pci_get_slot(parent, PCI_DEVFN(0, fn));
>> + do {
>> + if (pci_ari_enabled(parent))
>> + dev = pci_get_slot(parent, fn);
>> + else
>> + dev = pci_get_slot(parent, PCI_DEVFN(0, fn));
>> +
>> + fn = pci_next_fn(parent, PCI_DEVFN(0, fn));
>> if (!dev)
>> continue;
>> if ((dev->class >> 16) == PCI_BASE_CLASS_DISPLAY) {
>> @@ -79,7 +89,7 @@ int pciehp_configure_device(struct slot *p_slot)
>> }
>> pci_configure_slot(dev);
>> pci_dev_put(dev);
>> - }
>> + } while (fn);
>>
>> pci_bus_add_devices(parent);
>>
>> @@ -89,21 +99,27 @@ int pciehp_configure_device(struct slot *p_slot)
>> int pciehp_unconfigure_device(struct slot *p_slot)
>> {
>> int ret, rc = 0;
>> - int j;
>> + int fn = 0;
>> u8 bctl = 0;
>> u8 presence = 0;
>> struct pci_bus *parent = p_slot->ctrl->pcie->port->subordinate;
>> u16 command;
>> struct controller *ctrl = p_slot->ctrl;
>> + struct pci_dev *temp;
>>
>> ctrl_dbg(ctrl, "%s: domain:bus:dev = %04x:%02x:00\n",
>> __func__, pci_domain_nr(parent), parent->number);
>> ret = pciehp_get_adapter_status(p_slot, &presence);
>> if (ret)
>> presence = 0;
>> +
>> + do {
>> + if (pci_ari_enabled(parent))
>> + temp = pci_get_slot(parent, fn);
>> + else
>> + temp = pci_get_slot(parent, PCI_DEVFN(0, fn));
>>
>> - for (j = 0; j < 8; j++) {
>> - struct pci_dev *temp = pci_get_slot(parent, PCI_DEVFN(0, j));
>> + fn = pci_next_fn(parent, PCI_DEVFN(0, fn));
>> if (!temp)
>> continue;
>> if (temp->hdr_type == PCI_HEADER_TYPE_BRIDGE && presence) {
>> @@ -129,7 +145,7 @@ int pciehp_unconfigure_device(struct slot *p_slot)
>> pci_write_config_word(temp, PCI_COMMAND, command);
>> }
>> pci_dev_put(temp);
>> - }
>> + } while (fn);
>>
>> return rc;
>> }
>> --
>> 1.7.1
>>
>>
>
> .
>
--
Thanks!
Yijing
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2013-01-09 7:38 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-10-16 7:10 [PATCH v2 1/3] PCI: rework pci_enable_ari for support disable ari forwarding Yijing Wang
2012-10-16 7:10 ` [PATCH v2 2/3] PCI: introduce pci_next_fn to get next func number Yijing Wang
2012-10-16 7:10 ` [PATCH v2 3/3] PCI, pciehp: ARI device hotplug support Yijing Wang
2013-01-08 17:44 ` Bjorn Helgaas
2013-01-09 7:37 ` Yijing Wang
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.