From 67f43f38eeb34da43b624a29d57b703f4c4844b4 Mon Sep 17 00:00:00 2001 From: Sebastian Ott Date: Thu, 29 Aug 2013 19:33:16 +0200 Subject: s390/pci/hotplug: convert to be builtin only Convert s390' pci hotplug to be builtin only, with no module option. Suggested-by: Bjorn Helgaas Signed-off-by: Sebastian Ott Signed-off-by: Martin Schwidefsky --- drivers/pci/hotplug/s390_pci_hpc.c | 61 ++------------------------------------ 1 file changed, 2 insertions(+), 59 deletions(-) (limited to 'drivers/pci/hotplug/s390_pci_hpc.c') diff --git a/drivers/pci/hotplug/s390_pci_hpc.c b/drivers/pci/hotplug/s390_pci_hpc.c index ea3fa90d020..0d9c12fbcb3 100644 --- a/drivers/pci/hotplug/s390_pci_hpc.c +++ b/drivers/pci/hotplug/s390_pci_hpc.c @@ -148,7 +148,7 @@ static struct hotplug_slot_ops s390_hotplug_slot_ops = { .get_adapter_status = get_adapter_status, }; -static int init_pci_slot(struct zpci_dev *zdev) +int zpci_init_slot(struct zpci_dev *zdev) { struct hotplug_slot *hotplug_slot; struct hotplug_slot_info *info; @@ -202,7 +202,7 @@ error: return -ENOMEM; } -static void exit_pci_slot(struct zpci_dev *zdev) +void zpci_exit_slot(struct zpci_dev *zdev) { struct list_head *tmp, *n; struct slot *slot; @@ -215,60 +215,3 @@ static void exit_pci_slot(struct zpci_dev *zdev) pci_hp_deregister(slot->hotplug_slot); } } - -static struct pci_hp_callback_ops hp_ops = { - .create_slot = init_pci_slot, - .remove_slot = exit_pci_slot, -}; - -static void __init init_pci_slots(void) -{ - struct zpci_dev *zdev; - - /* - * Create a structure for each slot, and register that slot - * with the pci_hotplug subsystem. - */ - mutex_lock(&zpci_list_lock); - list_for_each_entry(zdev, &zpci_list, entry) { - init_pci_slot(zdev); - } - mutex_unlock(&zpci_list_lock); -} - -static void __exit exit_pci_slots(void) -{ - struct list_head *tmp, *n; - struct slot *slot; - - /* - * Unregister all of our slots with the pci_hotplug subsystem. - * Memory will be freed in release_slot() callback after slot's - * lifespan is finished. - */ - list_for_each_safe(tmp, n, &s390_hotplug_slot_list) { - slot = list_entry(tmp, struct slot, slot_list); - list_del(&slot->slot_list); - pci_hp_deregister(slot->hotplug_slot); - } -} - -static int __init pci_hotplug_s390_init(void) -{ - if (!s390_pci_probe) - return -EOPNOTSUPP; - - zpci_register_hp_ops(&hp_ops); - init_pci_slots(); - - return 0; -} - -static void __exit pci_hotplug_s390_exit(void) -{ - exit_pci_slots(); - zpci_deregister_hp_ops(); -} - -module_init(pci_hotplug_s390_init); -module_exit(pci_hotplug_s390_exit); -- cgit v1.2.3-70-g09d2 From 0ff70ec88ba61f72b05b365a21fbd8aa60436254 Mon Sep 17 00:00:00 2001 From: Sebastian Ott Date: Thu, 29 Aug 2013 19:35:19 +0200 Subject: s390/pci: add recover sysfs knob Add an arch specific attribute to recover a pci function from an error state or config space blockage. Signed-off-by: Sebastian Ott Signed-off-by: Martin Schwidefsky --- arch/s390/pci/pci.c | 4 ++-- arch/s390/pci/pci_sysfs.c | 27 +++++++++++++++++++++++++++ drivers/pci/hotplug/s390_pci_hpc.c | 2 -- 3 files changed, 29 insertions(+), 4 deletions(-) (limited to 'drivers/pci/hotplug/s390_pci_hpc.c') diff --git a/arch/s390/pci/pci.c b/arch/s390/pci/pci.c index 61167b1209a..b0ccd424308 100644 --- a/arch/s390/pci/pci.c +++ b/arch/s390/pci/pci.c @@ -791,6 +791,8 @@ int zpci_enable_device(struct zpci_dev *zdev) rc = zpci_dma_init_device(zdev); if (rc) goto out_dma; + + zdev->state = ZPCI_FN_STATE_ONLINE; return 0; out_dma: @@ -819,8 +821,6 @@ int zpci_create_device(struct zpci_dev *zdev) rc = zpci_enable_device(zdev); if (rc) goto out_free; - - zdev->state = ZPCI_FN_STATE_ONLINE; } rc = zpci_scan_bus(zdev); if (rc) diff --git a/arch/s390/pci/pci_sysfs.c b/arch/s390/pci/pci_sysfs.c index e99a2557f18..cf8a12ff733 100644 --- a/arch/s390/pci/pci_sysfs.c +++ b/arch/s390/pci/pci_sysfs.c @@ -48,11 +48,38 @@ static ssize_t show_pfgid(struct device *dev, struct device_attribute *attr, } static DEVICE_ATTR(pfgid, S_IRUGO, show_pfgid, NULL); +static void recover_callback(struct device *dev) +{ + struct pci_dev *pdev = to_pci_dev(dev); + struct zpci_dev *zdev = get_zdev(pdev); + int ret; + + pci_stop_and_remove_bus_device(pdev); + ret = zpci_disable_device(zdev); + if (ret) + return; + + ret = zpci_enable_device(zdev); + if (ret) + return; + + pci_rescan_bus(zdev->bus); +} + +static ssize_t store_recover(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + int rc = device_schedule_callback(dev, recover_callback); + return rc ? rc : count; +} +static DEVICE_ATTR(recover, S_IWUSR, NULL, store_recover); + static struct device_attribute *zpci_dev_attrs[] = { &dev_attr_function_id, &dev_attr_function_handle, &dev_attr_pchid, &dev_attr_pfgid, + &dev_attr_recover, NULL, }; diff --git a/drivers/pci/hotplug/s390_pci_hpc.c b/drivers/pci/hotplug/s390_pci_hpc.c index 0d9c12fbcb3..66e505ca24e 100644 --- a/drivers/pci/hotplug/s390_pci_hpc.c +++ b/drivers/pci/hotplug/s390_pci_hpc.c @@ -79,8 +79,6 @@ static int enable_slot(struct hotplug_slot *hotplug_slot) 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); -- cgit v1.2.3-70-g09d2