Commit 783684f1 authored by Sebastian Ott's avatar Sebastian Ott Committed by Martin Schwidefsky
Browse files

s390/pci: introduce clp_get_state



Code handling pci hotplug needs to determine the configuration
state of a pci function. Implement clp_get_state as a wrapper
for list pci functions.

Also change enum zpci_state to match the configuration state
values.

Signed-off-by: default avatarSebastian Ott <sebott@linux.vnet.ibm.com>
Reviewed-by: default avatarGerald Schaefer <gerald.schaefer@de.ibm.com>
Signed-off-by: default avatarMartin Schwidefsky <schwidefsky@de.ibm.com>
parent 4e5bd780
Loading
Loading
Loading
Loading
+5 −5
Original line number Original line Diff line number Diff line
@@ -70,11 +70,10 @@ struct zpci_fmb {
} __packed __aligned(128);
} __packed __aligned(128);


enum zpci_state {
enum zpci_state {
	ZPCI_FN_STATE_RESERVED,
	ZPCI_FN_STATE_STANDBY = 0,
	ZPCI_FN_STATE_STANDBY,
	ZPCI_FN_STATE_CONFIGURED = 1,
	ZPCI_FN_STATE_CONFIGURED,
	ZPCI_FN_STATE_RESERVED = 2,
	ZPCI_FN_STATE_ONLINE,
	ZPCI_FN_STATE_ONLINE = 3,
	NR_ZPCI_FN_STATES,
};
};


struct zpci_bar_struct {
struct zpci_bar_struct {
@@ -172,6 +171,7 @@ int clp_rescan_pci_devices_simple(void);
int clp_add_pci_device(u32, u32, int);
int clp_add_pci_device(u32, u32, int);
int clp_enable_fh(struct zpci_dev *, u8);
int clp_enable_fh(struct zpci_dev *, u8);
int clp_disable_fh(struct zpci_dev *);
int clp_disable_fh(struct zpci_dev *);
int clp_get_state(u32 fid, enum zpci_state *state);


#ifdef CONFIG_PCI
#ifdef CONFIG_PCI
/* Error handling and recovery */
/* Error handling and recovery */
+42 −9
Original line number Original line Diff line number Diff line
@@ -295,8 +295,8 @@ int clp_disable_fh(struct zpci_dev *zdev)
	return rc;
	return rc;
}
}


static int clp_list_pci(struct clp_req_rsp_list_pci *rrb,
static int clp_list_pci(struct clp_req_rsp_list_pci *rrb, void *data,
			void (*cb)(struct clp_fh_list_entry *entry))
			void (*cb)(struct clp_fh_list_entry *, void *))
{
{
	u64 resume_token = 0;
	u64 resume_token = 0;
	int entries, i, rc;
	int entries, i, rc;
@@ -327,13 +327,13 @@ static int clp_list_pci(struct clp_req_rsp_list_pci *rrb,


		resume_token = rrb->response.resume_token;
		resume_token = rrb->response.resume_token;
		for (i = 0; i < entries; i++)
		for (i = 0; i < entries; i++)
			cb(&rrb->response.fh_list[i]);
			cb(&rrb->response.fh_list[i], data);
	} while (resume_token);
	} while (resume_token);
out:
out:
	return rc;
	return rc;
}
}


static void __clp_add(struct clp_fh_list_entry *entry)
static void __clp_add(struct clp_fh_list_entry *entry, void *data)
{
{
	if (!entry->vendor_id)
	if (!entry->vendor_id)
		return;
		return;
@@ -341,7 +341,7 @@ static void __clp_add(struct clp_fh_list_entry *entry)
	clp_add_pci_device(entry->fid, entry->fh, entry->config_state);
	clp_add_pci_device(entry->fid, entry->fh, entry->config_state);
}
}


static void __clp_rescan(struct clp_fh_list_entry *entry)
static void __clp_rescan(struct clp_fh_list_entry *entry, void *data)
{
{
	struct zpci_dev *zdev;
	struct zpci_dev *zdev;


@@ -364,7 +364,7 @@ static void __clp_rescan(struct clp_fh_list_entry *entry)
	}
	}
}
}


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


@@ -387,7 +387,7 @@ int clp_scan_pci_devices(void)
	if (!rrb)
	if (!rrb)
		return -ENOMEM;
		return -ENOMEM;


	rc = clp_list_pci(rrb, __clp_add);
	rc = clp_list_pci(rrb, NULL, __clp_add);


	clp_free_block(rrb);
	clp_free_block(rrb);
	return rc;
	return rc;
@@ -402,7 +402,7 @@ int clp_rescan_pci_devices(void)
	if (!rrb)
	if (!rrb)
		return -ENOMEM;
		return -ENOMEM;


	rc = clp_list_pci(rrb, __clp_rescan);
	rc = clp_list_pci(rrb, NULL, __clp_rescan);


	clp_free_block(rrb);
	clp_free_block(rrb);
	return rc;
	return rc;
@@ -417,7 +417,40 @@ int clp_rescan_pci_devices_simple(void)
	if (!rrb)
	if (!rrb)
		return -ENOMEM;
		return -ENOMEM;


	rc = clp_list_pci(rrb, __clp_update);
	rc = clp_list_pci(rrb, NULL, __clp_update);

	clp_free_block(rrb);
	return rc;
}

struct clp_state_data {
	u32 fid;
	enum zpci_state state;
};

static void __clp_get_state(struct clp_fh_list_entry *entry, void *data)
{
	struct clp_state_data *sd = data;

	if (entry->fid != sd->fid)
		return;

	sd->state = entry->config_state;
}

int clp_get_state(u32 fid, enum zpci_state *state)
{
	struct clp_req_rsp_list_pci *rrb;
	struct clp_state_data sd = {fid, ZPCI_FN_STATE_RESERVED};
	int rc;

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

	rc = clp_list_pci(rrb, &sd, __clp_get_state);
	if (!rc)
		*state = sd.state;


	clp_free_block(rrb);
	clp_free_block(rrb);
	return rc;
	return rc;