mirror of
https://github.com/torvalds/linux.git
synced 2024-12-09 04:31:39 +00:00
PCI: Unify device inaccessible
Bring surprise removals and permanent failures together so we no longer need separate flags. The implementation enforces that error handling will not be able to override a surprise removal's permanent channel failure. Signed-off-by: Keith Busch <keith.busch@intel.com> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> Reviewed-by: Sinan Kaya <okaya@kernel.org>
This commit is contained in:
parent
7b42d97e99
commit
a6bd101b8f
@ -295,21 +295,71 @@ struct pci_sriov {
|
|||||||
bool drivers_autoprobe; /* Auto probing of VFs by driver */
|
bool drivers_autoprobe; /* Auto probing of VFs by driver */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* pci_dev priv_flags */
|
/**
|
||||||
#define PCI_DEV_DISCONNECTED 0
|
* pci_dev_set_io_state - Set the new error state if possible.
|
||||||
#define PCI_DEV_ADDED 1
|
*
|
||||||
|
* @dev - pci device to set new error_state
|
||||||
|
* @new - the state we want dev to be in
|
||||||
|
*
|
||||||
|
* Must be called with device_lock held.
|
||||||
|
*
|
||||||
|
* Returns true if state has been changed to the requested state.
|
||||||
|
*/
|
||||||
|
static inline bool pci_dev_set_io_state(struct pci_dev *dev,
|
||||||
|
pci_channel_state_t new)
|
||||||
|
{
|
||||||
|
bool changed = false;
|
||||||
|
|
||||||
|
device_lock_assert(&dev->dev);
|
||||||
|
switch (new) {
|
||||||
|
case pci_channel_io_perm_failure:
|
||||||
|
switch (dev->error_state) {
|
||||||
|
case pci_channel_io_frozen:
|
||||||
|
case pci_channel_io_normal:
|
||||||
|
case pci_channel_io_perm_failure:
|
||||||
|
changed = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case pci_channel_io_frozen:
|
||||||
|
switch (dev->error_state) {
|
||||||
|
case pci_channel_io_frozen:
|
||||||
|
case pci_channel_io_normal:
|
||||||
|
changed = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case pci_channel_io_normal:
|
||||||
|
switch (dev->error_state) {
|
||||||
|
case pci_channel_io_frozen:
|
||||||
|
case pci_channel_io_normal:
|
||||||
|
changed = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (changed)
|
||||||
|
dev->error_state = new;
|
||||||
|
return changed;
|
||||||
|
}
|
||||||
|
|
||||||
static inline int pci_dev_set_disconnected(struct pci_dev *dev, void *unused)
|
static inline int pci_dev_set_disconnected(struct pci_dev *dev, void *unused)
|
||||||
{
|
{
|
||||||
set_bit(PCI_DEV_DISCONNECTED, &dev->priv_flags);
|
device_lock(&dev->dev);
|
||||||
|
pci_dev_set_io_state(dev, pci_channel_io_perm_failure);
|
||||||
|
device_unlock(&dev->dev);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool pci_dev_is_disconnected(const struct pci_dev *dev)
|
static inline bool pci_dev_is_disconnected(const struct pci_dev *dev)
|
||||||
{
|
{
|
||||||
return test_bit(PCI_DEV_DISCONNECTED, &dev->priv_flags);
|
return dev->error_state == pci_channel_io_perm_failure;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* pci_dev priv_flags */
|
||||||
|
#define PCI_DEV_ADDED 0
|
||||||
|
|
||||||
static inline void pci_dev_assign_added(struct pci_dev *dev, bool added)
|
static inline void pci_dev_assign_added(struct pci_dev *dev, bool added)
|
||||||
{
|
{
|
||||||
assign_bit(PCI_DEV_ADDED, &dev->priv_flags, added);
|
assign_bit(PCI_DEV_ADDED, &dev->priv_flags, added);
|
||||||
|
@ -52,9 +52,8 @@ static int report_error_detected(struct pci_dev *dev,
|
|||||||
const struct pci_error_handlers *err_handler;
|
const struct pci_error_handlers *err_handler;
|
||||||
|
|
||||||
device_lock(&dev->dev);
|
device_lock(&dev->dev);
|
||||||
dev->error_state = state;
|
if (!pci_dev_set_io_state(dev, state) ||
|
||||||
|
!dev->driver ||
|
||||||
if (!dev->driver ||
|
|
||||||
!dev->driver->err_handler ||
|
!dev->driver->err_handler ||
|
||||||
!dev->driver->err_handler->error_detected) {
|
!dev->driver->err_handler->error_detected) {
|
||||||
/*
|
/*
|
||||||
@ -130,9 +129,8 @@ static int report_resume(struct pci_dev *dev, void *data)
|
|||||||
const struct pci_error_handlers *err_handler;
|
const struct pci_error_handlers *err_handler;
|
||||||
|
|
||||||
device_lock(&dev->dev);
|
device_lock(&dev->dev);
|
||||||
dev->error_state = pci_channel_io_normal;
|
if (!pci_dev_set_io_state(dev, pci_channel_io_normal) ||
|
||||||
|
!dev->driver ||
|
||||||
if (!dev->driver ||
|
|
||||||
!dev->driver->err_handler ||
|
!dev->driver->err_handler ||
|
||||||
!dev->driver->err_handler->resume)
|
!dev->driver->err_handler->resume)
|
||||||
goto out;
|
goto out;
|
||||||
|
Loading…
Reference in New Issue
Block a user