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

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
Loading
Loading
Loading
Loading
+17 −1
Original line number Diff line number Diff line
@@ -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
+1 −2
Original line number Diff line number Diff line
@@ -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)
+0 −3
Original line number Diff line number Diff line
@@ -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);
+44 −3
Original line number Diff line number Diff line
@@ -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);
	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 = {