mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-12-29 23:53:55 +08:00
s390/pci: split lpf
List pci functions is used to query and iterate over pci functions. This function currently has 2 users - initial device discovery and rescan after a machine check. Instead of having a multipurpose function pass a callback which gets called for each pci function. Signed-off-by: Sebastian Ott <sebott@linux.vnet.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
This commit is contained in:
parent
77e844b964
commit
1d57896638
arch/s390
@ -135,7 +135,8 @@ int zpci_register_ioat(struct zpci_dev *, u8, u64, u64, u64);
|
|||||||
int zpci_unregister_ioat(struct zpci_dev *, u8);
|
int zpci_unregister_ioat(struct zpci_dev *, u8);
|
||||||
|
|
||||||
/* CLP */
|
/* CLP */
|
||||||
int clp_find_pci_devices(void);
|
int clp_scan_pci_devices(void);
|
||||||
|
int clp_rescan_pci_devices(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 *);
|
||||||
@ -163,7 +164,6 @@ static inline void zpci_exit_slot(struct zpci_dev *zdev) {}
|
|||||||
/* Helpers */
|
/* Helpers */
|
||||||
struct zpci_dev *get_zdev(struct pci_dev *);
|
struct zpci_dev *get_zdev(struct pci_dev *);
|
||||||
struct zpci_dev *get_zdev_by_fid(u32);
|
struct zpci_dev *get_zdev_by_fid(u32);
|
||||||
bool zpci_fid_present(u32);
|
|
||||||
|
|
||||||
/* sysfs */
|
/* sysfs */
|
||||||
int zpci_sysfs_add_device(struct device *);
|
int zpci_sysfs_add_device(struct device *);
|
||||||
|
@ -99,11 +99,6 @@ struct zpci_dev *get_zdev_by_fid(u32 fid)
|
|||||||
return zdev;
|
return zdev;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool zpci_fid_present(u32 fid)
|
|
||||||
{
|
|
||||||
return (get_zdev_by_fid(fid) != NULL) ? true : false;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct zpci_dev *get_zdev_by_bus(struct pci_bus *bus)
|
static struct zpci_dev *get_zdev_by_bus(struct pci_bus *bus)
|
||||||
{
|
{
|
||||||
return (bus && bus->sysdata) ? (struct zpci_dev *) bus->sysdata : NULL;
|
return (bus && bus->sysdata) ? (struct zpci_dev *) bus->sysdata : NULL;
|
||||||
@ -926,7 +921,7 @@ static int __init pci_base_init(void)
|
|||||||
if (rc)
|
if (rc)
|
||||||
goto out_dma;
|
goto out_dma;
|
||||||
|
|
||||||
rc = clp_find_pci_devices();
|
rc = clp_scan_pci_devices();
|
||||||
if (rc)
|
if (rc)
|
||||||
goto out_find;
|
goto out_find;
|
||||||
|
|
||||||
|
@ -36,9 +36,9 @@ static inline u8 clp_instr(void *data)
|
|||||||
return cc;
|
return cc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void *clp_alloc_block(void)
|
static void *clp_alloc_block(gfp_t gfp_mask)
|
||||||
{
|
{
|
||||||
return (void *) __get_free_pages(GFP_KERNEL, get_order(CLP_BLK_SIZE));
|
return (void *) __get_free_pages(gfp_mask, get_order(CLP_BLK_SIZE));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void clp_free_block(void *ptr)
|
static void clp_free_block(void *ptr)
|
||||||
@ -70,7 +70,7 @@ static int clp_query_pci_fngrp(struct zpci_dev *zdev, u8 pfgid)
|
|||||||
struct clp_req_rsp_query_pci_grp *rrb;
|
struct clp_req_rsp_query_pci_grp *rrb;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
rrb = clp_alloc_block();
|
rrb = clp_alloc_block(GFP_KERNEL);
|
||||||
if (!rrb)
|
if (!rrb)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
@ -113,7 +113,7 @@ static int clp_query_pci_fn(struct zpci_dev *zdev, u32 fh)
|
|||||||
struct clp_req_rsp_query_pci *rrb;
|
struct clp_req_rsp_query_pci *rrb;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
rrb = clp_alloc_block();
|
rrb = clp_alloc_block(GFP_KERNEL);
|
||||||
if (!rrb)
|
if (!rrb)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
@ -181,7 +181,7 @@ static int clp_set_pci_fn(u32 *fh, u8 nr_dma_as, u8 command)
|
|||||||
struct clp_req_rsp_set_pci *rrb;
|
struct clp_req_rsp_set_pci *rrb;
|
||||||
int rc, retries = 1000;
|
int rc, retries = 1000;
|
||||||
|
|
||||||
rrb = clp_alloc_block();
|
rrb = clp_alloc_block(GFP_KERNEL);
|
||||||
if (!rrb)
|
if (!rrb)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
@ -245,49 +245,12 @@ int clp_disable_fh(struct zpci_dev *zdev)
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void clp_check_pcifn_entry(struct clp_fh_list_entry *entry)
|
static int clp_list_pci(struct clp_req_rsp_list_pci *rrb,
|
||||||
|
void (*cb)(struct clp_fh_list_entry *entry))
|
||||||
{
|
{
|
||||||
int present, rc;
|
|
||||||
|
|
||||||
if (!entry->vendor_id)
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* TODO: be a little bit more scalable */
|
|
||||||
present = zpci_fid_present(entry->fid);
|
|
||||||
|
|
||||||
if (present)
|
|
||||||
pr_debug("%s: device %x already present\n", __func__, entry->fid);
|
|
||||||
|
|
||||||
/* skip already used functions */
|
|
||||||
if (present && entry->config_state)
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* aev 306: function moved to stand-by state */
|
|
||||||
if (present && !entry->config_state) {
|
|
||||||
/*
|
|
||||||
* The handle is already disabled, that means no iota/irq freeing via
|
|
||||||
* the firmware interfaces anymore. Need to free resources manually
|
|
||||||
* (DMA memory, debug, sysfs)...
|
|
||||||
*/
|
|
||||||
zpci_stop_device(get_zdev_by_fid(entry->fid));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
rc = clp_add_pci_device(entry->fid, entry->fh, entry->config_state);
|
|
||||||
if (rc)
|
|
||||||
pr_err("Failed to add fid: 0x%x\n", entry->fid);
|
|
||||||
}
|
|
||||||
|
|
||||||
int clp_find_pci_devices(void)
|
|
||||||
{
|
|
||||||
struct clp_req_rsp_list_pci *rrb;
|
|
||||||
u64 resume_token = 0;
|
u64 resume_token = 0;
|
||||||
int entries, i, rc;
|
int entries, i, rc;
|
||||||
|
|
||||||
rrb = clp_alloc_block();
|
|
||||||
if (!rrb)
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
do {
|
do {
|
||||||
memset(rrb, 0, sizeof(*rrb));
|
memset(rrb, 0, sizeof(*rrb));
|
||||||
rrb->request.hdr.len = sizeof(rrb->request);
|
rrb->request.hdr.len = sizeof(rrb->request);
|
||||||
@ -316,12 +279,72 @@ int clp_find_pci_devices(void)
|
|||||||
resume_token = rrb->response.resume_token;
|
resume_token = rrb->response.resume_token;
|
||||||
|
|
||||||
for (i = 0; i < entries; i++)
|
for (i = 0; i < entries; i++)
|
||||||
clp_check_pcifn_entry(&rrb->response.fh_list[i]);
|
cb(&rrb->response.fh_list[i]);
|
||||||
} while (resume_token);
|
} while (resume_token);
|
||||||
|
|
||||||
pr_debug("Maximum number of supported PCI functions: %u\n",
|
pr_debug("Maximum number of supported PCI functions: %u\n",
|
||||||
rrb->response.max_fn);
|
rrb->response.max_fn);
|
||||||
out:
|
out:
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __clp_add(struct clp_fh_list_entry *entry)
|
||||||
|
{
|
||||||
|
if (!entry->vendor_id)
|
||||||
|
return;
|
||||||
|
|
||||||
|
clp_add_pci_device(entry->fid, entry->fh, entry->config_state);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __clp_rescan(struct clp_fh_list_entry *entry)
|
||||||
|
{
|
||||||
|
struct zpci_dev *zdev;
|
||||||
|
|
||||||
|
if (!entry->vendor_id)
|
||||||
|
return;
|
||||||
|
|
||||||
|
zdev = get_zdev_by_fid(entry->fid);
|
||||||
|
if (!zdev) {
|
||||||
|
clp_add_pci_device(entry->fid, entry->fh, entry->config_state);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!entry->config_state) {
|
||||||
|
/*
|
||||||
|
* The handle is already disabled, that means no iota/irq freeing via
|
||||||
|
* the firmware interfaces anymore. Need to free resources manually
|
||||||
|
* (DMA memory, debug, sysfs)...
|
||||||
|
*/
|
||||||
|
zpci_stop_device(zdev);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int clp_scan_pci_devices(void)
|
||||||
|
{
|
||||||
|
struct clp_req_rsp_list_pci *rrb;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
rrb = clp_alloc_block(GFP_KERNEL);
|
||||||
|
if (!rrb)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
rc = clp_list_pci(rrb, __clp_add);
|
||||||
|
|
||||||
|
clp_free_block(rrb);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
int clp_rescan_pci_devices(void)
|
||||||
|
{
|
||||||
|
struct clp_req_rsp_list_pci *rrb;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
rrb = clp_alloc_block(GFP_KERNEL);
|
||||||
|
if (!rrb)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
rc = clp_list_pci(rrb, __clp_rescan);
|
||||||
|
|
||||||
clp_free_block(rrb);
|
clp_free_block(rrb);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
@ -69,7 +69,7 @@ static void zpci_event_log_avail(struct zpci_ccdf_avail *ccdf)
|
|||||||
clp_add_pci_device(ccdf->fid, ccdf->fh, 0);
|
clp_add_pci_device(ccdf->fid, ccdf->fh, 0);
|
||||||
break;
|
break;
|
||||||
case 0x0306:
|
case 0x0306:
|
||||||
clp_find_pci_devices();
|
clp_rescan_pci_devices();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
Loading…
Reference in New Issue
Block a user