diff options
author | Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> | 2012-04-24 15:15:18 -0400 |
---|---|---|
committer | Bjorn Helgaas <bhelgaas@google.com> | 2012-04-30 18:47:26 -0400 |
commit | 977f857ca566a1e68045fcbb7cfc9c4acb077cf0 (patch) | |
tree | eca7bfd254d2beca6da23cf28e03a50c3d214707 /drivers/pci/pci.c | |
parent | 66f75a5d028beaf67c931435fdc3e7823125730c (diff) |
PCI: move mutex locking out of pci_dev_reset function
The intent of git commit 6fbf9e7a90862988c278462d85ce9684605a52b2
"PCI: Introduce __pci_reset_function_locked to be used when holding
device_lock." was to have a non-locking function that would call
pci_dev_reset function.
But it fell short of that by just probing and not actually reseting
the device. To make that work we need a way to move the lock
around device_lock to not be in pci_dev_reset (as the caller of
__pci_reset_function_locked already holds said lock). We do this by
renaming pci_dev_reset to __pci_dev_reset and bubbling said mutex out
of __pci_dev_reset to pci_dev_reset (a wrapper around __pci_dev_reset).
The __pci_reset_function_locked can now call __pci_dev_reset without
having to worry about the dead-lock.
Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Diffstat (limited to 'drivers/pci/pci.c')
-rw-r--r-- | drivers/pci/pci.c | 27 |
1 files changed, 17 insertions, 10 deletions
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 111569ccab43..9e31c0ab650e 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c | |||
@@ -3164,18 +3164,12 @@ static int pci_parent_bus_reset(struct pci_dev *dev, int probe) | |||
3164 | return 0; | 3164 | return 0; |
3165 | } | 3165 | } |
3166 | 3166 | ||
3167 | static int pci_dev_reset(struct pci_dev *dev, int probe) | 3167 | static int __pci_dev_reset(struct pci_dev *dev, int probe) |
3168 | { | 3168 | { |
3169 | int rc; | 3169 | int rc; |
3170 | 3170 | ||
3171 | might_sleep(); | 3171 | might_sleep(); |
3172 | 3172 | ||
3173 | if (!probe) { | ||
3174 | pci_cfg_access_lock(dev); | ||
3175 | /* block PM suspend, driver probe, etc. */ | ||
3176 | device_lock(&dev->dev); | ||
3177 | } | ||
3178 | |||
3179 | rc = pci_dev_specific_reset(dev, probe); | 3173 | rc = pci_dev_specific_reset(dev, probe); |
3180 | if (rc != -ENOTTY) | 3174 | if (rc != -ENOTTY) |
3181 | goto done; | 3175 | goto done; |
@@ -3194,14 +3188,27 @@ static int pci_dev_reset(struct pci_dev *dev, int probe) | |||
3194 | 3188 | ||
3195 | rc = pci_parent_bus_reset(dev, probe); | 3189 | rc = pci_parent_bus_reset(dev, probe); |
3196 | done: | 3190 | done: |
3191 | return rc; | ||
3192 | } | ||
3193 | |||
3194 | static int pci_dev_reset(struct pci_dev *dev, int probe) | ||
3195 | { | ||
3196 | int rc; | ||
3197 | |||
3198 | if (!probe) { | ||
3199 | pci_cfg_access_lock(dev); | ||
3200 | /* block PM suspend, driver probe, etc. */ | ||
3201 | device_lock(&dev->dev); | ||
3202 | } | ||
3203 | |||
3204 | rc = __pci_dev_reset(dev, probe); | ||
3205 | |||
3197 | if (!probe) { | 3206 | if (!probe) { |
3198 | device_unlock(&dev->dev); | 3207 | device_unlock(&dev->dev); |
3199 | pci_cfg_access_unlock(dev); | 3208 | pci_cfg_access_unlock(dev); |
3200 | } | 3209 | } |
3201 | |||
3202 | return rc; | 3210 | return rc; |
3203 | } | 3211 | } |
3204 | |||
3205 | /** | 3212 | /** |
3206 | * __pci_reset_function - reset a PCI device function | 3213 | * __pci_reset_function - reset a PCI device function |
3207 | * @dev: PCI device to reset | 3214 | * @dev: PCI device to reset |
@@ -3246,7 +3253,7 @@ EXPORT_SYMBOL_GPL(__pci_reset_function); | |||
3246 | */ | 3253 | */ |
3247 | int __pci_reset_function_locked(struct pci_dev *dev) | 3254 | int __pci_reset_function_locked(struct pci_dev *dev) |
3248 | { | 3255 | { |
3249 | return pci_dev_reset(dev, 1); | 3256 | return __pci_dev_reset(dev, 0); |
3250 | } | 3257 | } |
3251 | EXPORT_SYMBOL_GPL(__pci_reset_function_locked); | 3258 | EXPORT_SYMBOL_GPL(__pci_reset_function_locked); |
3252 | 3259 | ||