mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-26 10:49:33 +00:00
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:
parent
944239c59e
commit
4bee2a5dce
3 changed files with 40 additions and 33 deletions
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in a new issue