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>
This commit is contained in:
Sebastian Ott
2013-06-05 16:06:42 +02:00
committed by Martin Schwidefsky
parent 944239c59e
commit 4bee2a5dce
3 changed files with 40 additions and 33 deletions

View File

@@ -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)