diff options
author | Sebastian Ott <sebott@linux.vnet.ibm.com> | 2013-08-29 13:40:01 -0400 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2013-08-30 02:57:20 -0400 |
commit | 57b5918c33a0797930c3791fb602a8a9d46ef80c (patch) | |
tree | 47e3a5b503e8551f130fb722fbf1ae281e6ed292 /arch/s390/pci | |
parent | d03abe5882cc4815bf98c0e01a1deafa4a5d6730 (diff) |
s390/pci: update function handle after resume from hibernate
Function handles may change while the system was in hibernation
use list pci functions and update the function handles.
Signed-off-by: Sebastian Ott <sebott@linux.vnet.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'arch/s390/pci')
-rw-r--r-- | arch/s390/pci/pci.c | 15 | ||||
-rw-r--r-- | arch/s390/pci/pci_clp.c | 29 |
2 files changed, 39 insertions, 5 deletions
diff --git a/arch/s390/pci/pci.c b/arch/s390/pci/pci.c index a7ed6685e7fb..f17a8343e360 100644 --- a/arch/s390/pci/pci.c +++ b/arch/s390/pci/pci.c | |||
@@ -46,7 +46,7 @@ | |||
46 | 46 | ||
47 | /* list of all detected zpci devices */ | 47 | /* list of all detected zpci devices */ |
48 | static LIST_HEAD(zpci_list); | 48 | static LIST_HEAD(zpci_list); |
49 | static DEFINE_MUTEX(zpci_list_lock); | 49 | static DEFINE_SPINLOCK(zpci_list_lock); |
50 | 50 | ||
51 | static void zpci_enable_irq(struct irq_data *data); | 51 | static void zpci_enable_irq(struct irq_data *data); |
52 | static void zpci_disable_irq(struct irq_data *data); | 52 | static void zpci_disable_irq(struct irq_data *data); |
@@ -88,14 +88,14 @@ struct zpci_dev *get_zdev_by_fid(u32 fid) | |||
88 | { | 88 | { |
89 | struct zpci_dev *tmp, *zdev = NULL; | 89 | struct zpci_dev *tmp, *zdev = NULL; |
90 | 90 | ||
91 | mutex_lock(&zpci_list_lock); | 91 | spin_lock(&zpci_list_lock); |
92 | list_for_each_entry(tmp, &zpci_list, entry) { | 92 | list_for_each_entry(tmp, &zpci_list, entry) { |
93 | if (tmp->fid == fid) { | 93 | if (tmp->fid == fid) { |
94 | zdev = tmp; | 94 | zdev = tmp; |
95 | break; | 95 | break; |
96 | } | 96 | } |
97 | } | 97 | } |
98 | mutex_unlock(&zpci_list_lock); | 98 | spin_unlock(&zpci_list_lock); |
99 | return zdev; | 99 | return zdev; |
100 | } | 100 | } |
101 | 101 | ||
@@ -821,9 +821,9 @@ int zpci_create_device(struct zpci_dev *zdev) | |||
821 | if (rc) | 821 | if (rc) |
822 | goto out_disable; | 822 | goto out_disable; |
823 | 823 | ||
824 | mutex_lock(&zpci_list_lock); | 824 | spin_lock(&zpci_list_lock); |
825 | list_add_tail(&zdev->entry, &zpci_list); | 825 | list_add_tail(&zdev->entry, &zpci_list); |
826 | mutex_unlock(&zpci_list_lock); | 826 | spin_unlock(&zpci_list_lock); |
827 | 827 | ||
828 | zpci_init_slot(zdev); | 828 | zpci_init_slot(zdev); |
829 | 829 | ||
@@ -939,3 +939,8 @@ out: | |||
939 | return rc; | 939 | return rc; |
940 | } | 940 | } |
941 | subsys_initcall_sync(pci_base_init); | 941 | subsys_initcall_sync(pci_base_init); |
942 | |||
943 | void zpci_rescan(void) | ||
944 | { | ||
945 | clp_rescan_pci_devices_simple(); | ||
946 | } | ||
diff --git a/arch/s390/pci/pci_clp.c b/arch/s390/pci/pci_clp.c index 3eaf63a6ecac..475563c3d1e4 100644 --- a/arch/s390/pci/pci_clp.c +++ b/arch/s390/pci/pci_clp.c | |||
@@ -319,6 +319,20 @@ static void __clp_rescan(struct clp_fh_list_entry *entry) | |||
319 | } | 319 | } |
320 | } | 320 | } |
321 | 321 | ||
322 | static void __clp_update(struct clp_fh_list_entry *entry) | ||
323 | { | ||
324 | struct zpci_dev *zdev; | ||
325 | |||
326 | if (!entry->vendor_id) | ||
327 | return; | ||
328 | |||
329 | zdev = get_zdev_by_fid(entry->fid); | ||
330 | if (!zdev) | ||
331 | return; | ||
332 | |||
333 | zdev->fh = entry->fh; | ||
334 | } | ||
335 | |||
322 | int clp_scan_pci_devices(void) | 336 | int clp_scan_pci_devices(void) |
323 | { | 337 | { |
324 | struct clp_req_rsp_list_pci *rrb; | 338 | struct clp_req_rsp_list_pci *rrb; |
@@ -348,3 +362,18 @@ int clp_rescan_pci_devices(void) | |||
348 | clp_free_block(rrb); | 362 | clp_free_block(rrb); |
349 | return rc; | 363 | return rc; |
350 | } | 364 | } |
365 | |||
366 | int clp_rescan_pci_devices_simple(void) | ||
367 | { | ||
368 | struct clp_req_rsp_list_pci *rrb; | ||
369 | int rc; | ||
370 | |||
371 | rrb = clp_alloc_block(GFP_NOWAIT); | ||
372 | if (!rrb) | ||
373 | return -ENOMEM; | ||
374 | |||
375 | rc = clp_list_pci(rrb, __clp_update); | ||
376 | |||
377 | clp_free_block(rrb); | ||
378 | return rc; | ||
379 | } | ||