[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <CAErSpo4yiMrBcBPSV5MLKYsLQwhBA4L-fOHr4ocHDO9NwBpG7Q@mail.gmail.com>
Date: Mon, 5 Mar 2012 11:03:38 -0700
From: Bjorn Helgaas <bhelgaas@...gle.com>
To: Tadeusz Struk <tadeusz.struk@...el.com>
Cc: jbarnes@...tuousgeek.org, linux-kernel@...r.kernel.org,
kvm@...r.kernel.org, linux-pci@...r.kernel.org
Subject: Re: [PATCH 1/1 v3] PCI: Device specific reset function
On Mon, Mar 5, 2012 at 3:00 AM, Tadeusz Struk <tadeusz.struk@...el.com> wrote:
>
> ---
> drivers/pci/pci.h | 1 +
> drivers/pci/quirks.c | 33 +++++++++++++++++++++++++++------
> include/linux/pci.h | 1 +
> 3 files changed, 29 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
> index 1009a5e..4d10479 100644
> --- a/drivers/pci/pci.h
> +++ b/drivers/pci/pci.h
> @@ -315,6 +315,7 @@ struct pci_dev_reset_methods {
> u16 vendor;
> u16 device;
> int (*reset)(struct pci_dev *dev, int probe);
> + struct list_head list;
> };
>
> #ifdef CONFIG_PCI_QUIRKS
> diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
> index 6476547..f423d2f 100644
> --- a/drivers/pci/quirks.c
> +++ b/drivers/pci/quirks.c
> @@ -3070,26 +3070,47 @@ static int reset_intel_82599_sfp_virtfn(struct pci_dev *dev, int probe)
> }
>
> #define PCI_DEVICE_ID_INTEL_82599_SFP_VF 0x10ed
> -
> -static const struct pci_dev_reset_methods pci_dev_reset_methods[] = {
> +static struct pci_dev_reset_methods pci_dev_reset_methods[] = {
> { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82599_SFP_VF,
> - reset_intel_82599_sfp_virtfn },
> + reset_intel_82599_sfp_virtfn },
> { PCI_VENDOR_ID_INTEL, PCI_ANY_ID,
> reset_intel_generic_dev },
> - { 0 }
> };
>
> +static LIST_HEAD(reset_list);
> +
> +void pci_dev_specific_reset_add(struct pci_dev_reset_methods *reset_method)
> +{
> + INIT_LIST_HEAD(&reset_method->list);
> + list_add(&reset_method->list, &reset_list);
> +}
> +
> +static int __init pci_dev_specific_reset_init(void)
> +{
> + int i;
> +
> + for (i = 0; i < ARRAY_SIZE(pci_dev_reset_methods); i++) {
> + pci_dev_specific_reset_add(&pci_dev_reset_methods[i]);
> + }
> + return 0;
> +}
> +
> +late_initcall(pci_dev_specific_reset_init);
> +
> int pci_dev_specific_reset(struct pci_dev *dev, int probe)
> {
> const struct pci_dev_reset_methods *i;
> + struct pci_driver *drv = dev->driver;
> +
> + if (drv && drv->reset)
> + return drv->reset(dev, probe);
>
> - for (i = pci_dev_reset_methods; i->reset; i++) {
> + list_for_each_entry(i, &reset_list, list) {
> if ((i->vendor == dev->vendor ||
> i->vendor == (u16)PCI_ANY_ID) &&
> (i->device == dev->device ||
> i->device == (u16)PCI_ANY_ID))
> return i->reset(dev, probe);
> }
> -
> return -ENOTTY;
> }
> diff --git a/include/linux/pci.h b/include/linux/pci.h
> index a16b1df..a3a0bc5 100644
> --- a/include/linux/pci.h
> +++ b/include/linux/pci.h
> @@ -560,6 +560,7 @@ struct pci_driver {
> int (*resume_early) (struct pci_dev *dev);
> int (*resume) (struct pci_dev *dev); /* Device woken up */
> void (*shutdown) (struct pci_dev *dev);
> + int (*reset) (struct pci_dev *dev, int probe); /* Device specific reset */
> struct pci_error_handlers *err_handler;
> struct device_driver driver;
> struct pci_dynids dynids;
This patch now consists of two pieces:
1) Convert the reset method table to a list, and
2) Add the "reset" function pointer in struct pci_driver and the "if
(drv && drv->reset)" block.
These should be split into two patches.
After you split them, I don't think you even need part 1, so you
should probably just drop it.
Common practice would be to also include your driver patch that
actually uses the pci_driver.reset pointer as an additional patch in
the same series. That gives us more confidence that this solution
actually works and will be used.
Bjorn
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Powered by blists - more mailing lists