Skip to content

Commit

Permalink
s390/pci: update function handle after resume from hibernate
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Sebastian Ott authored and Martin Schwidefsky committed Aug 30, 2013
1 parent d03abe5 commit 57b5918
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 5 deletions.
4 changes: 4 additions & 0 deletions arch/s390/include/asm/pci.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
/* must be set before including pci_clp.h */
#define PCI_BAR_COUNT 6

#include <linux/pci.h>
#include <asm-generic/pci.h>
#include <asm-generic/pci-dma-compat.h>
#include <asm/pci_clp.h>
Expand Down Expand Up @@ -137,6 +138,7 @@ int zpci_unregister_ioat(struct zpci_dev *, u8);
/* CLP */
int clp_scan_pci_devices(void);
int clp_rescan_pci_devices(void);
int clp_rescan_pci_devices_simple(void);
int clp_add_pci_device(u32, u32, int);
int clp_enable_fh(struct zpci_dev *, u8);
int clp_disable_fh(struct zpci_dev *);
Expand All @@ -145,9 +147,11 @@ int clp_disable_fh(struct zpci_dev *);
/* Error handling and recovery */
void zpci_event_error(void *);
void zpci_event_availability(void *);
void zpci_rescan(void);
#else /* CONFIG_PCI */
static inline void zpci_event_error(void *e) {}
static inline void zpci_event_availability(void *e) {}
static inline void zpci_rescan(void) {}
#endif /* CONFIG_PCI */

#ifdef CONFIG_HOTPLUG_PCI_S390
Expand Down
2 changes: 2 additions & 0 deletions arch/s390/kernel/suspend.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include <asm/ctl_reg.h>
#include <asm/ipl.h>
#include <asm/cio.h>
#include <asm/pci.h>

/*
* References to section boundaries
Expand Down Expand Up @@ -219,4 +220,5 @@ void s390_early_resume(void)
{
lgr_info_log();
channel_subsystem_reinit();
zpci_rescan();
}
15 changes: 10 additions & 5 deletions arch/s390/pci/pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@

/* list of all detected zpci devices */
static LIST_HEAD(zpci_list);
static DEFINE_MUTEX(zpci_list_lock);
static DEFINE_SPINLOCK(zpci_list_lock);

static void zpci_enable_irq(struct irq_data *data);
static void zpci_disable_irq(struct irq_data *data);
Expand Down Expand Up @@ -88,14 +88,14 @@ struct zpci_dev *get_zdev_by_fid(u32 fid)
{
struct zpci_dev *tmp, *zdev = NULL;

mutex_lock(&zpci_list_lock);
spin_lock(&zpci_list_lock);
list_for_each_entry(tmp, &zpci_list, entry) {
if (tmp->fid == fid) {
zdev = tmp;
break;
}
}
mutex_unlock(&zpci_list_lock);
spin_unlock(&zpci_list_lock);
return zdev;
}

Expand Down Expand Up @@ -821,9 +821,9 @@ int zpci_create_device(struct zpci_dev *zdev)
if (rc)
goto out_disable;

mutex_lock(&zpci_list_lock);
spin_lock(&zpci_list_lock);
list_add_tail(&zdev->entry, &zpci_list);
mutex_unlock(&zpci_list_lock);
spin_unlock(&zpci_list_lock);

zpci_init_slot(zdev);

Expand Down Expand Up @@ -939,3 +939,8 @@ static int __init pci_base_init(void)
return rc;
}
subsys_initcall_sync(pci_base_init);

void zpci_rescan(void)
{
clp_rescan_pci_devices_simple();
}
29 changes: 29 additions & 0 deletions arch/s390/pci/pci_clp.c
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,20 @@ static void __clp_rescan(struct clp_fh_list_entry *entry)
}
}

static void __clp_update(struct clp_fh_list_entry *entry)
{
struct zpci_dev *zdev;

if (!entry->vendor_id)
return;

zdev = get_zdev_by_fid(entry->fid);
if (!zdev)
return;

zdev->fh = entry->fh;
}

int clp_scan_pci_devices(void)
{
struct clp_req_rsp_list_pci *rrb;
Expand Down Expand Up @@ -348,3 +362,18 @@ int clp_rescan_pci_devices(void)
clp_free_block(rrb);
return rc;
}

int clp_rescan_pci_devices_simple(void)
{
struct clp_req_rsp_list_pci *rrb;
int rc;

rrb = clp_alloc_block(GFP_NOWAIT);
if (!rrb)
return -ENOMEM;

rc = clp_list_pci(rrb, __clp_update);

clp_free_block(rrb);
return rc;
}

0 comments on commit 57b5918

Please sign in to comment.