Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bb02ce95 authored by Bjorn Helgaas's avatar Bjorn Helgaas
Browse files

Merge branch 'pci/virtualization' into next

* pci/virtualization:
  PCI: Remove __pci_dev_reset() and pci_dev_reset()
  PCI: Split ->reset_notify() method into ->reset_prepare() and ->reset_done()
  PCI: Protect pci_error_handlers->reset_notify() usage with device_lock()
  PCI: Protect pci_driver->sriov_configure() usage with device_lock()
  PCI: Mark Intel XXV710 NIC INTx masking as broken
  PCI: Restore PRI and PASID state after Function-Level Reset
  PCI: Cache PRI and PASID bits in pci_dev
parents c781f85b 52354b9d
Loading
Loading
Loading
Loading
+13 −23
Original line number Diff line number Diff line
@@ -2348,31 +2348,20 @@ static void fm10k_io_resume(struct pci_dev *pdev)
		netif_device_attach(netdev);
}

/**
 * fm10k_io_reset_notify - called when PCI function is reset
 * @pdev: Pointer to PCI device
 *
 * This callback is called when the PCI function is reset such as from
 * /sys/class/net/<enpX>/device/reset or similar. When prepare is true, it
 * means we should prepare for a function reset. If prepare is false, it means
 * the function reset just occurred.
 */
static void fm10k_io_reset_notify(struct pci_dev *pdev, bool prepare)
static void fm10k_io_reset_prepare(struct pci_dev *pdev)
{
	struct fm10k_intfc *interface = pci_get_drvdata(pdev);
	int err = 0;

	if (prepare) {
	/* warn incase we have any active VF devices */
	if (pci_num_vf(pdev))
		dev_warn(&pdev->dev,
			 "PCIe FLR may cause issues for any active VF devices\n");

		fm10k_prepare_suspend(interface);
	} else {
		err = fm10k_handle_resume(interface);
	fm10k_prepare_suspend(pci_get_drvdata(pdev));
}

static void fm10k_io_reset_done(struct pci_dev *pdev)
{
	struct fm10k_intfc *interface = pci_get_drvdata(pdev);
	int err = fm10k_handle_resume(interface);

	if (err) {
		dev_warn(&pdev->dev,
			 "fm10k_io_reset_notify failed: %d\n", err);
@@ -2384,7 +2373,8 @@ static const struct pci_error_handlers fm10k_err_handler = {
	.error_detected = fm10k_io_error_detected,
	.slot_reset = fm10k_io_slot_reset,
	.resume = fm10k_io_resume,
	.reset_notify = fm10k_io_reset_notify,
	.reset_prepare = fm10k_io_reset_prepare,
	.reset_done = fm10k_io_reset_done,
};

static struct pci_driver fm10k_driver = {
+44 −31
Original line number Diff line number Diff line
@@ -346,11 +346,13 @@ static const struct pci_device_id mwifiex_ids[] = {

MODULE_DEVICE_TABLE(pci, mwifiex_ids);

static void mwifiex_pcie_reset_notify(struct pci_dev *pdev, bool prepare)
/*
 * Cleanup all software without cleaning anything related to PCIe and HW.
 */
static void mwifiex_pcie_reset_prepare(struct pci_dev *pdev)
{
	struct pcie_service_card *card = pci_get_drvdata(pdev);
	struct mwifiex_adapter *adapter = card->adapter;
	int ret;

	if (!adapter) {
		dev_err(&pdev->dev, "%s: adapter structure is not valid\n",
@@ -359,37 +361,48 @@ static void mwifiex_pcie_reset_notify(struct pci_dev *pdev, bool prepare)
	}

	mwifiex_dbg(adapter, INFO,
		    "%s: vendor=0x%4.04x device=0x%4.04x rev=%d %s\n",
		    __func__, pdev->vendor, pdev->device,
		    pdev->revision,
		    prepare ? "Pre-FLR" : "Post-FLR");
		    "%s: vendor=0x%4.04x device=0x%4.04x rev=%d Pre-FLR\n",
		    __func__, pdev->vendor, pdev->device, pdev->revision);

	if (prepare) {
		/* Kernel would be performing FLR after this notification.
		 * Cleanup all software without cleaning anything related to
		 * PCIe and HW.
		 */
	mwifiex_shutdown_sw(adapter);
	adapter->surprise_removed = true;
	clear_bit(MWIFIEX_IFACE_WORK_DEVICE_DUMP, &card->work_flags);
	clear_bit(MWIFIEX_IFACE_WORK_CARD_RESET, &card->work_flags);
	} else {
		/* Kernel stores and restores PCIe function context before and
		 * after performing FLR respectively. Reconfigure the software
		 * and firmware including firmware redownload
	mwifiex_dbg(adapter, INFO, "%s, successful\n", __func__);
}

/*
 * Kernel stores and restores PCIe function context before and after performing
 * FLR respectively. Reconfigure the software and firmware including firmware
 * redownload.
 */
static void mwifiex_pcie_reset_done(struct pci_dev *pdev)
{
	struct pcie_service_card *card = pci_get_drvdata(pdev);
	struct mwifiex_adapter *adapter = card->adapter;
	int ret;

	if (!adapter) {
		dev_err(&pdev->dev, "%s: adapter structure is not valid\n",
			__func__);
		return;
	}

	mwifiex_dbg(adapter, INFO,
		    "%s: vendor=0x%4.04x device=0x%4.04x rev=%d Post-FLR\n",
		    __func__, pdev->vendor, pdev->device, pdev->revision);

	adapter->surprise_removed = false;
	ret = mwifiex_reinit_sw(adapter);
		if (ret) {
	if (ret)
		dev_err(&pdev->dev, "reinit failed: %d\n", ret);
			return;
		}
	}
	else
		mwifiex_dbg(adapter, INFO, "%s, successful\n", __func__);
}

static const struct pci_error_handlers mwifiex_pcie_err_handler[] = {
		{ .reset_notify = mwifiex_pcie_reset_notify, },
static const struct pci_error_handlers mwifiex_pcie_err_handler = {
	.reset_prepare		= mwifiex_pcie_reset_prepare,
	.reset_done		= mwifiex_pcie_reset_done,
};

#ifdef CONFIG_PM_SLEEP
@@ -410,7 +423,7 @@ static struct pci_driver __refdata mwifiex_pcie = {
	},
#endif
	.shutdown = mwifiex_pcie_shutdown,
	.err_handler = mwifiex_pcie_err_handler,
	.err_handler = &mwifiex_pcie_err_handler,
};

/*
+8 −7
Original line number Diff line number Diff line
@@ -2145,14 +2145,14 @@ static int nvme_probe(struct pci_dev *pdev, const struct pci_device_id *id)
	return result;
}

static void nvme_reset_notify(struct pci_dev *pdev, bool prepare)
static void nvme_reset_prepare(struct pci_dev *pdev)
{
	struct nvme_dev *dev = pci_get_drvdata(pdev);
	nvme_dev_disable(pci_get_drvdata(pdev), false);
}

	if (prepare)
		nvme_dev_disable(dev, false);
	else
		nvme_reset(dev);
static void nvme_reset_done(struct pci_dev *pdev)
{
	nvme_reset(pci_get_drvdata(pdev));
}

static void nvme_shutdown(struct pci_dev *pdev)
@@ -2275,7 +2275,8 @@ static const struct pci_error_handlers nvme_err_handler = {
	.error_detected	= nvme_error_detected,
	.slot_reset	= nvme_slot_reset,
	.resume		= nvme_error_resume,
	.reset_notify	= nvme_reset_notify,
	.reset_prepare	= nvme_reset_prepare,
	.reset_done	= nvme_reset_done,
};

static const struct pci_device_id nvme_id_table[] = {
+71 −16
Original line number Diff line number Diff line
@@ -153,23 +153,27 @@ int pci_enable_pri(struct pci_dev *pdev, u32 reqs)
	u32 max_requests;
	int pos;

	if (WARN_ON(pdev->pri_enabled))
		return -EBUSY;

	pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_PRI);
	if (!pos)
		return -EINVAL;

	pci_read_config_word(pdev, pos + PCI_PRI_CTRL, &control);
	pci_read_config_word(pdev, pos + PCI_PRI_STATUS, &status);
	if ((control & PCI_PRI_CTRL_ENABLE) ||
	    !(status & PCI_PRI_STATUS_STOPPED))
	if (!(status & PCI_PRI_STATUS_STOPPED))
		return -EBUSY;

	pci_read_config_dword(pdev, pos + PCI_PRI_MAX_REQ, &max_requests);
	reqs = min(max_requests, reqs);
	pdev->pri_reqs_alloc = reqs;
	pci_write_config_dword(pdev, pos + PCI_PRI_ALLOC_REQ, reqs);

	control |= PCI_PRI_CTRL_ENABLE;
	control = PCI_PRI_CTRL_ENABLE;
	pci_write_config_word(pdev, pos + PCI_PRI_CTRL, control);

	pdev->pri_enabled = 1;

	return 0;
}
EXPORT_SYMBOL_GPL(pci_enable_pri);
@@ -185,6 +189,9 @@ void pci_disable_pri(struct pci_dev *pdev)
	u16 control;
	int pos;

	if (WARN_ON(!pdev->pri_enabled))
		return;

	pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_PRI);
	if (!pos)
		return;
@@ -192,9 +199,33 @@ void pci_disable_pri(struct pci_dev *pdev)
	pci_read_config_word(pdev, pos + PCI_PRI_CTRL, &control);
	control &= ~PCI_PRI_CTRL_ENABLE;
	pci_write_config_word(pdev, pos + PCI_PRI_CTRL, control);

	pdev->pri_enabled = 0;
}
EXPORT_SYMBOL_GPL(pci_disable_pri);

/**
 * pci_restore_pri_state - Restore PRI
 * @pdev: PCI device structure
 */
void pci_restore_pri_state(struct pci_dev *pdev)
{
	u16 control = PCI_PRI_CTRL_ENABLE;
	u32 reqs = pdev->pri_reqs_alloc;
	int pos;

	if (!pdev->pri_enabled)
		return;

	pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_PRI);
	if (!pos)
		return;

	pci_write_config_dword(pdev, pos + PCI_PRI_ALLOC_REQ, reqs);
	pci_write_config_word(pdev, pos + PCI_PRI_CTRL, control);
}
EXPORT_SYMBOL_GPL(pci_restore_pri_state);

/**
 * pci_reset_pri - Resets device's PRI state
 * @pdev: PCI device structure
@@ -207,16 +238,14 @@ int pci_reset_pri(struct pci_dev *pdev)
	u16 control;
	int pos;

	if (WARN_ON(pdev->pri_enabled))
		return -EBUSY;

	pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_PRI);
	if (!pos)
		return -EINVAL;

	pci_read_config_word(pdev, pos + PCI_PRI_CTRL, &control);
	if (control & PCI_PRI_CTRL_ENABLE)
		return -EBUSY;

	control |= PCI_PRI_CTRL_RESET;

	control = PCI_PRI_CTRL_RESET;
	pci_write_config_word(pdev, pos + PCI_PRI_CTRL, control);

	return 0;
@@ -239,16 +268,14 @@ int pci_enable_pasid(struct pci_dev *pdev, int features)
	u16 control, supported;
	int pos;

	if (WARN_ON(pdev->pasid_enabled))
		return -EBUSY;

	pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_PASID);
	if (!pos)
		return -EINVAL;

	pci_read_config_word(pdev, pos + PCI_PASID_CTRL, &control);
	pci_read_config_word(pdev, pos + PCI_PASID_CAP, &supported);

	if (control & PCI_PASID_CTRL_ENABLE)
		return -EINVAL;

	supported &= PCI_PASID_CAP_EXEC | PCI_PASID_CAP_PRIV;

	/* User wants to enable anything unsupported? */
@@ -256,9 +283,12 @@ int pci_enable_pasid(struct pci_dev *pdev, int features)
		return -EINVAL;

	control = PCI_PASID_CTRL_ENABLE | features;
	pdev->pasid_features = features;

	pci_write_config_word(pdev, pos + PCI_PASID_CTRL, control);

	pdev->pasid_enabled = 1;

	return 0;
}
EXPORT_SYMBOL_GPL(pci_enable_pasid);
@@ -266,21 +296,46 @@ EXPORT_SYMBOL_GPL(pci_enable_pasid);
/**
 * pci_disable_pasid - Disable the PASID capability
 * @pdev: PCI device structure
 *
 */
void pci_disable_pasid(struct pci_dev *pdev)
{
	u16 control = 0;
	int pos;

	if (WARN_ON(!pdev->pasid_enabled))
		return;

	pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_PASID);
	if (!pos)
		return;

	pci_write_config_word(pdev, pos + PCI_PASID_CTRL, control);

	pdev->pasid_enabled = 0;
}
EXPORT_SYMBOL_GPL(pci_disable_pasid);

/**
 * pci_restore_pasid_state - Restore PASID capabilities
 * @pdev: PCI device structure
 */
void pci_restore_pasid_state(struct pci_dev *pdev)
{
	u16 control;
	int pos;

	if (!pdev->pasid_enabled)
		return;

	pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_PASID);
	if (!pos)
		return;

	control = PCI_PASID_CTRL_ENABLE | pdev->pasid_features;
	pci_write_config_word(pdev, pos + PCI_PASID_CTRL, control);
}
EXPORT_SYMBOL_GPL(pci_restore_pasid_state);

/**
 * pci_pasid_features - Check which PASID features are supported
 * @pdev: PCI device structure
+0 −4
Original line number Diff line number Diff line
@@ -461,8 +461,6 @@ static int sriov_init(struct pci_dev *dev, int pos)
	else
		iov->dev = dev;

	mutex_init(&iov->lock);

	dev->sriov = iov;
	dev->is_physfn = 1;
	rc = compute_max_vf_buses(dev);
@@ -491,8 +489,6 @@ static void sriov_release(struct pci_dev *dev)
	if (dev != dev->sriov->dev)
		pci_dev_put(dev->sriov->dev);

	mutex_destroy(&dev->sriov->lock);

	kfree(dev->sriov);
	dev->sriov = NULL;
}
Loading