scsi: aacraid: Check for PCI state of device in a generic way

Commit 16ae9dd35d ("scsi: aacraid: Fix for excessive prints on EEH")
introduced checks about the state of device before any PCI operations in
the driver. Basically, this prevents it to perform PCI accesses when
device is in the process of recover from a PCI error. In PowerPC, such
mechanism is called EEH, and the aforementioned commit introduced checks
that are based on EEH-specific primitives for that.

The potential problems with this approach are three: first, these checks
are "locked" to powerpc only - another archs could have error recovery
methods too, like AER in Intel. Also, the powerpc primitives perform
expensive FW accesses to validate the precise PCI state of a device.
Finally, code becomes more complicated and needs ifdef validation based
on arch config being set.

So, this patch makes use of generic PCI state checks, which are
lightweight and non-dependent of arch configs - also, it makes the code
cleaner.

Fixes: 16ae9dd35d ("scsi: aacraid: Fix for excessive prints on EEH")
Signed-off-by: Guilherme G. Piccoli <gpiccoli@linux.vnet.ibm.com>
Reviewed-by: Dave Carroll <david.carroll@microsemi.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
Guilherme G. Piccoli 2017-11-17 19:14:53 -02:00 committed by Martin K. Petersen
parent 5ebde4694e
commit bd257b2f3b
1 changed files with 2 additions and 31 deletions

View File

@ -467,35 +467,6 @@ int aac_queue_get(struct aac_dev * dev, u32 * index, u32 qid, struct hw_fib * hw
return 0; return 0;
} }
#ifdef CONFIG_EEH
static inline int aac_check_eeh_failure(struct aac_dev *dev)
{
/* Check for an EEH failure for the given
* device node. Function eeh_dev_check_failure()
* returns 0 if there has not been an EEH error
* otherwise returns a non-zero value.
*
* Need to be called before any PCI operation,
* i.e.,before aac_adapter_check_health()
*/
struct eeh_dev *edev = pci_dev_to_eeh_dev(dev->pdev);
if (eeh_dev_check_failure(edev)) {
/* The EEH mechanisms will handle this
* error and reset the device if
* necessary.
*/
return 1;
}
return 0;
}
#else
static inline int aac_check_eeh_failure(struct aac_dev *dev)
{
return 0;
}
#endif
/* /*
* Define the highest level of host to adapter communication routines. * Define the highest level of host to adapter communication routines.
* These routines will support host to adapter FS commuication. These * These routines will support host to adapter FS commuication. These
@ -701,7 +672,7 @@ int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size,
return -ETIMEDOUT; return -ETIMEDOUT;
} }
if (aac_check_eeh_failure(dev)) if (unlikely(pci_channel_offline(dev->pdev)))
return -EFAULT; return -EFAULT;
if ((blink = aac_adapter_check_health(dev)) > 0) { if ((blink = aac_adapter_check_health(dev)) > 0) {
@ -801,7 +772,7 @@ int aac_hba_send(u8 command, struct fib *fibptr, fib_callback callback,
spin_unlock_irqrestore(&fibptr->event_lock, flags); spin_unlock_irqrestore(&fibptr->event_lock, flags);
if (aac_check_eeh_failure(dev)) if (unlikely(pci_channel_offline(dev->pdev)))
return -EFAULT; return -EFAULT;
fibptr->flags |= FIB_CONTEXT_FLAG_WAIT; fibptr->flags |= FIB_CONTEXT_FLAG_WAIT;