diff options
author | Sebastian Ott <sebott@linux.vnet.ibm.com> | 2013-08-29 13:35:19 -0400 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2013-08-30 02:57:12 -0400 |
commit | 0ff70ec88ba61f72b05b365a21fbd8aa60436254 (patch) | |
tree | 0e45820fc2aaf256dc758a4ea4f83f6a2f961546 | |
parent | cb8091828757bbc9459ef59248f4a793e681f8cd (diff) |
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 <sebott@linux.vnet.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
-rw-r--r-- | arch/s390/pci/pci.c | 4 | ||||
-rw-r--r-- | arch/s390/pci/pci_sysfs.c | 27 | ||||
-rw-r--r-- | drivers/pci/hotplug/s390_pci_hpc.c | 2 |
3 files changed, 29 insertions, 4 deletions
diff --git a/arch/s390/pci/pci.c b/arch/s390/pci/pci.c index 61167b1209a3..b0ccd424308a 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) | |||
791 | rc = zpci_dma_init_device(zdev); | 791 | rc = zpci_dma_init_device(zdev); |
792 | if (rc) | 792 | if (rc) |
793 | goto out_dma; | 793 | goto out_dma; |
794 | |||
795 | zdev->state = ZPCI_FN_STATE_ONLINE; | ||
794 | return 0; | 796 | return 0; |
795 | 797 | ||
796 | out_dma: | 798 | out_dma: |
@@ -819,8 +821,6 @@ int zpci_create_device(struct zpci_dev *zdev) | |||
819 | rc = zpci_enable_device(zdev); | 821 | rc = zpci_enable_device(zdev); |
820 | if (rc) | 822 | if (rc) |
821 | goto out_free; | 823 | goto out_free; |
822 | |||
823 | zdev->state = ZPCI_FN_STATE_ONLINE; | ||
824 | } | 824 | } |
825 | rc = zpci_scan_bus(zdev); | 825 | rc = zpci_scan_bus(zdev); |
826 | if (rc) | 826 | if (rc) |
diff --git a/arch/s390/pci/pci_sysfs.c b/arch/s390/pci/pci_sysfs.c index e99a2557f186..cf8a12ff733b 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, | |||
48 | } | 48 | } |
49 | static DEVICE_ATTR(pfgid, S_IRUGO, show_pfgid, NULL); | 49 | static DEVICE_ATTR(pfgid, S_IRUGO, show_pfgid, NULL); |
50 | 50 | ||
51 | static void recover_callback(struct device *dev) | ||
52 | { | ||
53 | struct pci_dev *pdev = to_pci_dev(dev); | ||
54 | struct zpci_dev *zdev = get_zdev(pdev); | ||
55 | int ret; | ||
56 | |||
57 | pci_stop_and_remove_bus_device(pdev); | ||
58 | ret = zpci_disable_device(zdev); | ||
59 | if (ret) | ||
60 | return; | ||
61 | |||
62 | ret = zpci_enable_device(zdev); | ||
63 | if (ret) | ||
64 | return; | ||
65 | |||
66 | pci_rescan_bus(zdev->bus); | ||
67 | } | ||
68 | |||
69 | static ssize_t store_recover(struct device *dev, struct device_attribute *attr, | ||
70 | const char *buf, size_t count) | ||
71 | { | ||
72 | int rc = device_schedule_callback(dev, recover_callback); | ||
73 | return rc ? rc : count; | ||
74 | } | ||
75 | static DEVICE_ATTR(recover, S_IWUSR, NULL, store_recover); | ||
76 | |||
51 | static struct device_attribute *zpci_dev_attrs[] = { | 77 | static struct device_attribute *zpci_dev_attrs[] = { |
52 | &dev_attr_function_id, | 78 | &dev_attr_function_id, |
53 | &dev_attr_function_handle, | 79 | &dev_attr_function_handle, |
54 | &dev_attr_pchid, | 80 | &dev_attr_pchid, |
55 | &dev_attr_pfgid, | 81 | &dev_attr_pfgid, |
82 | &dev_attr_recover, | ||
56 | NULL, | 83 | NULL, |
57 | }; | 84 | }; |
58 | 85 | ||
diff --git a/drivers/pci/hotplug/s390_pci_hpc.c b/drivers/pci/hotplug/s390_pci_hpc.c index 0d9c12fbcb3a..66e505ca24ef 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) | |||
79 | if (rc) | 79 | if (rc) |
80 | goto out_deconfigure; | 80 | goto out_deconfigure; |
81 | 81 | ||
82 | slot->zdev->state = ZPCI_FN_STATE_ONLINE; | ||
83 | |||
84 | pci_scan_slot(slot->zdev->bus, ZPCI_DEVFN); | 82 | pci_scan_slot(slot->zdev->bus, ZPCI_DEVFN); |
85 | pci_bus_add_devices(slot->zdev->bus); | 83 | pci_bus_add_devices(slot->zdev->bus); |
86 | 84 | ||