Merge branch 'pds_core-AER-handling'
Shannon Nelson says: ==================== pds_core: AER handling Add simple handlers for the PCI AER callbacks, and improve the reset handling. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
da4a154ca2
@ -184,6 +184,9 @@ int pdsc_auxbus_dev_del(struct pdsc *cf, struct pdsc *pf)
|
||||
struct pds_auxiliary_dev *padev;
|
||||
int err = 0;
|
||||
|
||||
if (!cf)
|
||||
return -ENODEV;
|
||||
|
||||
mutex_lock(&pf->config_lock);
|
||||
|
||||
padev = pf->vfs[cf->vf_id].padev;
|
||||
@ -202,14 +205,27 @@ int pdsc_auxbus_dev_del(struct pdsc *cf, struct pdsc *pf)
|
||||
int pdsc_auxbus_dev_add(struct pdsc *cf, struct pdsc *pf)
|
||||
{
|
||||
struct pds_auxiliary_dev *padev;
|
||||
enum pds_core_vif_types vt;
|
||||
char devname[PDS_DEVNAME_LEN];
|
||||
enum pds_core_vif_types vt;
|
||||
unsigned long mask;
|
||||
u16 vt_support;
|
||||
int client_id;
|
||||
int err = 0;
|
||||
|
||||
if (!cf)
|
||||
return -ENODEV;
|
||||
|
||||
mutex_lock(&pf->config_lock);
|
||||
|
||||
mask = BIT_ULL(PDSC_S_FW_DEAD) |
|
||||
BIT_ULL(PDSC_S_STOPPING_DRIVER);
|
||||
if (cf->state & mask) {
|
||||
dev_err(pf->dev, "%s: can't add dev, VF client in bad state %#lx\n",
|
||||
__func__, cf->state);
|
||||
err = -ENXIO;
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
/* We only support vDPA so far, so it is the only one to
|
||||
* be verified that it is available in the Core device and
|
||||
* enabled in the devlink param. In the future this might
|
||||
|
@ -607,8 +607,7 @@ static void pdsc_check_pci_health(struct pdsc *pdsc)
|
||||
if (fw_status != PDS_RC_BAD_PCI)
|
||||
return;
|
||||
|
||||
pdsc_reset_prepare(pdsc->pdev);
|
||||
pdsc_reset_done(pdsc->pdev);
|
||||
pci_reset_function(pdsc->pdev);
|
||||
}
|
||||
|
||||
void pdsc_health_thread(struct work_struct *work)
|
||||
|
@ -284,9 +284,6 @@ int pdsc_devcmd_reset(struct pdsc *pdsc);
|
||||
int pdsc_dev_init(struct pdsc *pdsc);
|
||||
void pdsc_dev_uninit(struct pdsc *pdsc);
|
||||
|
||||
void pdsc_reset_prepare(struct pci_dev *pdev);
|
||||
void pdsc_reset_done(struct pci_dev *pdev);
|
||||
|
||||
int pdsc_intr_alloc(struct pdsc *pdsc, char *name,
|
||||
irq_handler_t handler, void *data);
|
||||
void pdsc_intr_free(struct pdsc *pdsc, int index);
|
||||
|
@ -45,6 +45,7 @@ static void pdsc_unmap_bars(struct pdsc *pdsc)
|
||||
for (i = 0; i < PDS_CORE_BARS_MAX; i++) {
|
||||
if (bars[i].vaddr)
|
||||
pci_iounmap(pdsc->pdev, bars[i].vaddr);
|
||||
bars[i].vaddr = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
@ -468,19 +469,28 @@ static void pdsc_restart_health_thread(struct pdsc *pdsc)
|
||||
mod_timer(&pdsc->wdtimer, jiffies + 1);
|
||||
}
|
||||
|
||||
void pdsc_reset_prepare(struct pci_dev *pdev)
|
||||
static void pdsc_reset_prepare(struct pci_dev *pdev)
|
||||
{
|
||||
struct pdsc *pdsc = pci_get_drvdata(pdev);
|
||||
|
||||
pdsc_stop_health_thread(pdsc);
|
||||
pdsc_fw_down(pdsc);
|
||||
|
||||
if (pdev->is_virtfn) {
|
||||
struct pdsc *pf;
|
||||
|
||||
pf = pdsc_get_pf_struct(pdsc->pdev);
|
||||
if (!IS_ERR(pf))
|
||||
pdsc_auxbus_dev_del(pdsc, pf);
|
||||
}
|
||||
|
||||
pdsc_unmap_bars(pdsc);
|
||||
pci_release_regions(pdev);
|
||||
pci_disable_device(pdev);
|
||||
if (pci_is_enabled(pdev))
|
||||
pci_disable_device(pdev);
|
||||
}
|
||||
|
||||
void pdsc_reset_done(struct pci_dev *pdev)
|
||||
static void pdsc_reset_done(struct pci_dev *pdev)
|
||||
{
|
||||
struct pdsc *pdsc = pci_get_drvdata(pdev);
|
||||
struct device *dev = pdsc->dev;
|
||||
@ -510,12 +520,43 @@ void pdsc_reset_done(struct pci_dev *pdev)
|
||||
|
||||
pdsc_fw_up(pdsc);
|
||||
pdsc_restart_health_thread(pdsc);
|
||||
|
||||
if (pdev->is_virtfn) {
|
||||
struct pdsc *pf;
|
||||
|
||||
pf = pdsc_get_pf_struct(pdsc->pdev);
|
||||
if (!IS_ERR(pf))
|
||||
pdsc_auxbus_dev_add(pdsc, pf);
|
||||
}
|
||||
}
|
||||
|
||||
static pci_ers_result_t pdsc_pci_error_detected(struct pci_dev *pdev,
|
||||
pci_channel_state_t error)
|
||||
{
|
||||
if (error == pci_channel_io_frozen) {
|
||||
pdsc_reset_prepare(pdev);
|
||||
return PCI_ERS_RESULT_NEED_RESET;
|
||||
}
|
||||
|
||||
return PCI_ERS_RESULT_NONE;
|
||||
}
|
||||
|
||||
static void pdsc_pci_error_resume(struct pci_dev *pdev)
|
||||
{
|
||||
struct pdsc *pdsc = pci_get_drvdata(pdev);
|
||||
|
||||
if (test_bit(PDSC_S_FW_DEAD, &pdsc->state))
|
||||
pci_reset_function_locked(pdev);
|
||||
}
|
||||
|
||||
static const struct pci_error_handlers pdsc_err_handler = {
|
||||
/* FLR handling */
|
||||
.reset_prepare = pdsc_reset_prepare,
|
||||
.reset_done = pdsc_reset_done,
|
||||
|
||||
/* AER handling */
|
||||
.error_detected = pdsc_pci_error_detected,
|
||||
.resume = pdsc_pci_error_resume,
|
||||
};
|
||||
|
||||
static struct pci_driver pdsc_driver = {
|
||||
|
Loading…
Reference in New Issue
Block a user