diff options
Diffstat (limited to 'drivers/scsi/mpi3mr/mpi3mr_os.c')
| -rw-r--r-- | drivers/scsi/mpi3mr/mpi3mr_os.c | 22 | 
1 files changed, 21 insertions, 1 deletions
| diff --git a/drivers/scsi/mpi3mr/mpi3mr_os.c b/drivers/scsi/mpi3mr/mpi3mr_os.c index ce444efd859e..e467b56949e9 100644 --- a/drivers/scsi/mpi3mr/mpi3mr_os.c +++ b/drivers/scsi/mpi3mr/mpi3mr_os.c @@ -49,6 +49,13 @@ static void mpi3mr_send_event_ack(struct mpi3mr_ioc *mrioc, u8 event,  #define MPI3_EVENT_WAIT_FOR_DEVICES_TO_REFRESH	(0xFFFE) +/* + * SAS Log info code for a NCQ collateral abort after an NCQ error: + * IOC_LOGINFO_PREFIX_PL | PL_LOGINFO_CODE_SATA_NCQ_FAIL_ALL_CMDS_AFTR_ERR + * See: drivers/message/fusion/lsi/mpi_log_sas.h + */ +#define IOC_LOGINFO_SATA_NCQ_FAIL_AFTER_ERR	0x31080000 +  /**   * mpi3mr_host_tag_for_scmd - Get host tag for a scmd   * @mrioc: Adapter instance reference @@ -3430,7 +3437,18 @@ void mpi3mr_process_op_reply_desc(struct mpi3mr_ioc *mrioc,  		scmd->result = DID_NO_CONNECT << 16;  		break;  	case MPI3_IOCSTATUS_SCSI_IOC_TERMINATED: -		scmd->result = DID_SOFT_ERROR << 16; +		if (ioc_loginfo == IOC_LOGINFO_SATA_NCQ_FAIL_AFTER_ERR) { +			/* +			 * This is a ATA NCQ command aborted due to another NCQ +			 * command failure. We must retry this command +			 * immediately but without incrementing its retry +			 * counter. +			 */ +			WARN_ON_ONCE(xfer_count != 0); +			scmd->result = DID_IMM_RETRY << 16; +		} else { +			scmd->result = DID_SOFT_ERROR << 16; +		}  		break;  	case MPI3_IOCSTATUS_SCSI_TASK_TERMINATED:  	case MPI3_IOCSTATUS_SCSI_EXT_TERMINATED: @@ -5365,6 +5383,8 @@ mpi3mr_probe(struct pci_dev *pdev, const struct pci_device_id *id)  	spin_lock_init(&mrioc->tgtdev_lock);  	spin_lock_init(&mrioc->watchdog_lock);  	spin_lock_init(&mrioc->chain_buf_lock); +	spin_lock_init(&mrioc->adm_req_q_bar_writeq_lock); +	spin_lock_init(&mrioc->adm_reply_q_bar_writeq_lock);  	spin_lock_init(&mrioc->sas_node_lock);  	spin_lock_init(&mrioc->trigger_lock); | 
