Commit da4a154c authored by David S. Miller's avatar David S. Miller

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: default avatarDavid S. Miller <davem@davemloft.net>
parents 06d53b03 2cbab3c2
...@@ -184,6 +184,9 @@ int pdsc_auxbus_dev_del(struct pdsc *cf, struct pdsc *pf) ...@@ -184,6 +184,9 @@ int pdsc_auxbus_dev_del(struct pdsc *cf, struct pdsc *pf)
struct pds_auxiliary_dev *padev; struct pds_auxiliary_dev *padev;
int err = 0; int err = 0;
if (!cf)
return -ENODEV;
mutex_lock(&pf->config_lock); mutex_lock(&pf->config_lock);
padev = pf->vfs[cf->vf_id].padev; padev = pf->vfs[cf->vf_id].padev;
...@@ -202,14 +205,27 @@ int pdsc_auxbus_dev_del(struct pdsc *cf, struct pdsc *pf) ...@@ -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) int pdsc_auxbus_dev_add(struct pdsc *cf, struct pdsc *pf)
{ {
struct pds_auxiliary_dev *padev; struct pds_auxiliary_dev *padev;
enum pds_core_vif_types vt;
char devname[PDS_DEVNAME_LEN]; char devname[PDS_DEVNAME_LEN];
enum pds_core_vif_types vt;
unsigned long mask;
u16 vt_support; u16 vt_support;
int client_id; int client_id;
int err = 0; int err = 0;
if (!cf)
return -ENODEV;
mutex_lock(&pf->config_lock); 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 /* We only support vDPA so far, so it is the only one to
* be verified that it is available in the Core device and * be verified that it is available in the Core device and
* enabled in the devlink param. In the future this might * enabled in the devlink param. In the future this might
......
...@@ -607,8 +607,7 @@ static void pdsc_check_pci_health(struct pdsc *pdsc) ...@@ -607,8 +607,7 @@ static void pdsc_check_pci_health(struct pdsc *pdsc)
if (fw_status != PDS_RC_BAD_PCI) if (fw_status != PDS_RC_BAD_PCI)
return; return;
pdsc_reset_prepare(pdsc->pdev); pci_reset_function(pdsc->pdev);
pdsc_reset_done(pdsc->pdev);
} }
void pdsc_health_thread(struct work_struct *work) void pdsc_health_thread(struct work_struct *work)
......
...@@ -284,9 +284,6 @@ int pdsc_devcmd_reset(struct pdsc *pdsc); ...@@ -284,9 +284,6 @@ int pdsc_devcmd_reset(struct pdsc *pdsc);
int pdsc_dev_init(struct pdsc *pdsc); int pdsc_dev_init(struct pdsc *pdsc);
void pdsc_dev_uninit(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, int pdsc_intr_alloc(struct pdsc *pdsc, char *name,
irq_handler_t handler, void *data); irq_handler_t handler, void *data);
void pdsc_intr_free(struct pdsc *pdsc, int index); void pdsc_intr_free(struct pdsc *pdsc, int index);
......
...@@ -45,6 +45,7 @@ static void pdsc_unmap_bars(struct pdsc *pdsc) ...@@ -45,6 +45,7 @@ static void pdsc_unmap_bars(struct pdsc *pdsc)
for (i = 0; i < PDS_CORE_BARS_MAX; i++) { for (i = 0; i < PDS_CORE_BARS_MAX; i++) {
if (bars[i].vaddr) if (bars[i].vaddr)
pci_iounmap(pdsc->pdev, 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) ...@@ -468,19 +469,28 @@ static void pdsc_restart_health_thread(struct pdsc *pdsc)
mod_timer(&pdsc->wdtimer, jiffies + 1); 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); struct pdsc *pdsc = pci_get_drvdata(pdev);
pdsc_stop_health_thread(pdsc); pdsc_stop_health_thread(pdsc);
pdsc_fw_down(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); pdsc_unmap_bars(pdsc);
pci_release_regions(pdev); 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 pdsc *pdsc = pci_get_drvdata(pdev);
struct device *dev = pdsc->dev; struct device *dev = pdsc->dev;
...@@ -510,12 +520,43 @@ void pdsc_reset_done(struct pci_dev *pdev) ...@@ -510,12 +520,43 @@ void pdsc_reset_done(struct pci_dev *pdev)
pdsc_fw_up(pdsc); pdsc_fw_up(pdsc);
pdsc_restart_health_thread(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 = { static const struct pci_error_handlers pdsc_err_handler = {
/* FLR handling */ /* FLR handling */
.reset_prepare = pdsc_reset_prepare, .reset_prepare = pdsc_reset_prepare,
.reset_done = pdsc_reset_done, .reset_done = pdsc_reset_done,
/* AER handling */
.error_detected = pdsc_pci_error_detected,
.resume = pdsc_pci_error_resume,
}; };
static struct pci_driver pdsc_driver = { static struct pci_driver pdsc_driver = {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment