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:
committed by
Bjorn Helgaas
parent
7b42d97e99
commit
a6bd101b8f
@ -295,21 +295,71 @@ struct pci_sriov {
|
||||
bool drivers_autoprobe; /* Auto probing of VFs by driver */
|
||||
};
|
||||
|
||||
/* pci_dev priv_flags */
|
||||
#define PCI_DEV_DISCONNECTED 0
|
||||
#define PCI_DEV_ADDED 1
|
||||
/**
|
||||
* pci_dev_set_io_state - Set the new error state if possible.
|
||||
*
|
||||
* @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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
assign_bit(PCI_DEV_ADDED, &dev->priv_flags, added);
|
||||
|
Reference in New Issue
Block a user