summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian Ott <sebott@linux.vnet.ibm.com>2013-06-05 16:06:42 +0200
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2013-06-26 21:10:07 +0200
commit4bee2a5dce45096851cb8694d962bf8c016816a8 (patch)
tree282a39310da585ad5e88d57791bfba728ed46280
parent944239c59e93a2a76c0c0dfa473700f82572e17d (diff)
s390/pci: cleanup hotplug code
Provide wrappers for the [de]configure operations, add some error handling, and use pci_scan_slot instead of pci_scan_single_device. Reviewed-by: Gerald Schaefer <gerald.schaefer@de.ibm.com> Signed-off-by: Sebastian Ott <sebott@linux.vnet.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
-rw-r--r--arch/s390/include/asm/pci.h1
-rw-r--r--arch/s390/pci/pci.c19
-rw-r--r--drivers/pci/hotplug/s390_pci_hpc.c53
3 files changed, 40 insertions, 33 deletions
diff --git a/arch/s390/include/asm/pci.h b/arch/s390/include/asm/pci.h
index 6c1801235db9..be41f4f885ce 100644
--- a/arch/s390/include/asm/pci.h
+++ b/arch/s390/include/asm/pci.h
@@ -143,7 +143,6 @@ int zpci_enable_device(struct zpci_dev *);
int zpci_disable_device(struct zpci_dev *);
void zpci_stop_device(struct zpci_dev *);
void zpci_free_device(struct zpci_dev *);
-int zpci_scan_device(struct zpci_dev *);
int zpci_register_ioat(struct zpci_dev *, u8, u64, u64, u64);
int zpci_unregister_ioat(struct zpci_dev *, u8);
diff --git a/arch/s390/pci/pci.c b/arch/s390/pci/pci.c
index a56fce445c39..628769b91b97 100644
--- a/arch/s390/pci/pci.c
+++ b/arch/s390/pci/pci.c
@@ -974,25 +974,6 @@ void zpci_stop_device(struct zpci_dev *zdev)
}
EXPORT_SYMBOL_GPL(zpci_stop_device);
-int zpci_scan_device(struct zpci_dev *zdev)
-{
- zdev->pdev = pci_scan_single_device(zdev->bus, ZPCI_DEVFN);
- if (!zdev->pdev) {
- pr_err("pci_scan_single_device failed for fid: 0x%x\n",
- zdev->fid);
- goto out;
- }
-
- pci_bus_add_devices(zdev->bus);
-
- return 0;
-out:
- zpci_dma_exit_device(zdev);
- clp_disable_fh(zdev);
- return -EIO;
-}
-EXPORT_SYMBOL_GPL(zpci_scan_device);
-
static inline int barsize(u8 size)
{
return (size) ? (1 << size) >> 10 : 0;
diff --git a/drivers/pci/hotplug/s390_pci_hpc.c b/drivers/pci/hotplug/s390_pci_hpc.c
index 46a7b738f61f..b12acaad9dc6 100644
--- a/drivers/pci/hotplug/s390_pci_hpc.c
+++ b/drivers/pci/hotplug/s390_pci_hpc.c
@@ -41,6 +41,28 @@ struct slot {
struct zpci_dev *zdev;
};
+static inline int slot_configure(struct slot *slot)
+{
+ int ret = sclp_pci_configure(slot->zdev->fid);
+
+ zpci_dbg(3, "conf fid:%x, rc:%d\n", slot->zdev->fid, ret);
+ if (!ret)
+ slot->zdev->state = ZPCI_FN_STATE_CONFIGURED;
+
+ return ret;
+}
+
+static inline int slot_deconfigure(struct slot *slot)
+{
+ int ret = sclp_pci_deconfigure(slot->zdev->fid);
+
+ zpci_dbg(3, "deconf fid:%x, rc:%d\n", slot->zdev->fid, ret);
+ if (!ret)
+ slot->zdev->state = ZPCI_FN_STATE_STANDBY;
+
+ return ret;
+}
+
static int enable_slot(struct hotplug_slot *hotplug_slot)
{
struct slot *slot = hotplug_slot->private;
@@ -49,14 +71,23 @@ static int enable_slot(struct hotplug_slot *hotplug_slot)
if (slot->zdev->state != ZPCI_FN_STATE_STANDBY)
return -EIO;
- rc = sclp_pci_configure(slot->zdev->fid);
- zpci_dbg(3, "conf fid:%x, rc:%d\n", slot->zdev->fid, rc);
- if (!rc) {
- slot->zdev->state = ZPCI_FN_STATE_CONFIGURED;
- /* automatically scan the device after is was configured */
- zpci_enable_device(slot->zdev);
- zpci_scan_device(slot->zdev);
- }
+ rc = slot_configure(slot);
+ if (rc)
+ return rc;
+
+ rc = zpci_enable_device(slot->zdev);
+ if (rc)
+ goto out_deconfigure;
+
+ slot->zdev->state = ZPCI_FN_STATE_ONLINE;
+
+ pci_scan_slot(slot->zdev->bus, ZPCI_DEVFN);
+ pci_bus_add_devices(slot->zdev->bus);
+
+ return rc;
+
+out_deconfigure:
+ slot_deconfigure(slot);
return rc;
}
@@ -74,11 +105,7 @@ static int disable_slot(struct hotplug_slot *hotplug_slot)
/* TODO: we rely on the user to unbind/remove the device, is that plausible
* or do we need to trigger that here?
*/
- rc = sclp_pci_deconfigure(slot->zdev->fid);
- zpci_dbg(3, "deconf fid:%x, rc:%d\n", slot->zdev->fid, rc);
- if (!rc)
- slot->zdev->state = ZPCI_FN_STATE_STANDBY;
- return rc;
+ return slot_deconfigure(slot);
}
static int get_power_status(struct hotplug_slot *hotplug_slot, u8 *value)