Patch "scsi: aacraid: Process Error for response I/O" has been added to the 4.4-stable tree
Subsystems (3)
This is a note to let you know that I've just added the patch titled
scsi: aacraid: Process Error for response I/O
to the 4.4-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
scsi-aacraid-process-error-for-response-i-o.patch
and it can be found in the queue-4.4 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From foo@baz Mon Nov 6 10:22:56 CET 2017
From: Raghava Aditya Renukunta <[email protected]>
Date: Sat, 7 Oct 2017 22:37:47 +0000
Subject: scsi: aacraid: Process Error for response I/O
From: Raghava Aditya Renukunta <[email protected]>
[ Upstream commit 4ec57fb4edaec523f0f78a0449a3b063749ac58b ]
Make sure that the driver processes error conditions even in the fast response path for response from the adapter.
--- drivers/scsi/aacraid/aachba.c | 291 +++++++++++++++++++++--------------------- 1 file changed, 152 insertions(+), 139 deletions(-)
drivers/scsi/aacraid/aachba.c +152 -139
@@ -2977,16 +2977,11 @@ static void aac_srb_callback(void *contereturn ;BUG_ON (fibptr ==NULL ); - dev = fibptr->dev; - -scsi_dma_unmap (scsicmd); -/* expose physical device if expose_physicald flag is on */ -if (scsicmd->cmnd[0 ] ==INQUIRY && !(scsicmd->cmnd[1 ] &0x01 ) - && expose_physicals >0 ) -aac_expose_phy_device (scsicmd); + dev = fibptr->dev; srbreply = (struct aac_srb_reply *)fib_data (fibptr); + scsicmd->sense_buffer[0 ] ='\0' ;/* Initialize sense valid flag to false */ if (fibptr->flags &FIB_CONTEXT_FLAG_FASTRESP ) {
@@ -2999,158 +2994,176 @@ static void aac_srb_callback(void *conte*/ scsi_set_resid (scsicmd,scsi_bufflen (scsicmd) -le32_to_cpu (srbreply->data_xfer_length)); -/* -* First check the fib status -*/ + } -if (le32_to_cpu (srbreply->status) !=ST_OK ) { -int len; -printk (KERN_WARNING "aac_srb_callback: srb failed, status = %d\n" ,le32_to_cpu (srbreply->status)); - len =min_t (u32,le32_to_cpu (srbreply->sense_data_size), -SCSI_SENSE_BUFFERSIZE ); - scsicmd->result =DID_ERROR <<16 - |COMMAND_COMPLETE <<8 - |SAM_STAT_CHECK_CONDITION ; -memcpy (scsicmd->sense_buffer, - srbreply->sense_data, len); - } +scsi_dma_unmap (scsicmd); -/* -* Next check the srb status -*/ -switch ((le32_to_cpu (srbreply->srb_status))&0x3f ) { -case SRB_STATUS_ERROR_RECOVERY : -case SRB_STATUS_PENDING : -case SRB_STATUS_SUCCESS : - scsicmd->result =DID_OK <<16 |COMMAND_COMPLETE <<8 ; -break ; -case SRB_STATUS_DATA_OVERRUN : -switch (scsicmd->cmnd[0 ]) { -case READ_6 : -case WRITE_6 : -case READ_10 : -case WRITE_10 : -case READ_12 : -case WRITE_12 : -case READ_16 : -case WRITE_16 : -if (le32_to_cpu (srbreply->data_xfer_length) - < scsicmd->underflow) -printk (KERN_WARNING "aacraid: SCSI CMD underflow\n" ); -else -printk (KERN_WARNING "aacraid: SCSI CMD Data Overrun\n" ); - scsicmd->result =DID_ERROR <<16 - |COMMAND_COMPLETE <<8 ; -break ; -case INQUIRY : { - scsicmd->result =DID_OK <<16 - |COMMAND_COMPLETE <<8 ; -break ; - } -default : - scsicmd->result =DID_OK <<16 |COMMAND_COMPLETE <<8 ; -break ; - } -break ; -case SRB_STATUS_ABORTED : - scsicmd->result =DID_ABORT <<16 |ABORT <<8 ; -break ; -case SRB_STATUS_ABORT_FAILED : -/* -* Not sure about this one - but assuming the -* hba was trying to abort for some reason -*/ - scsicmd->result =DID_ERROR <<16 |ABORT <<8 ; -break ; -case SRB_STATUS_PARITY_ERROR : - scsicmd->result =DID_PARITY <<16 - |MSG_PARITY_ERROR <<8 ; -break ; -case SRB_STATUS_NO_DEVICE : -case SRB_STATUS_INVALID_PATH_ID : -case SRB_STATUS_INVALID_TARGET_ID : -case SRB_STATUS_INVALID_LUN : -case SRB_STATUS_SELECTION_TIMEOUT : - scsicmd->result =DID_NO_CONNECT <<16 - |COMMAND_COMPLETE <<8 ; -break ; +/* expose physical device if expose_physicald flag is on */ +if (scsicmd->cmnd[0 ] ==INQUIRY && !(scsicmd->cmnd[1 ] &0x01 ) + && expose_physicals >0 ) +aac_expose_phy_device (scsicmd); -case SRB_STATUS_COMMAND_TIMEOUT : -case SRB_STATUS_TIMEOUT : - scsicmd->result =DID_TIME_OUT <<16 - |COMMAND_COMPLETE <<8 ; -break ; +/* +* First check the fib status +*/ -case SRB_STATUS_BUSY : - scsicmd->result =DID_BUS_BUSY <<16 - |COMMAND_COMPLETE <<8 ; -break ; +if (le32_to_cpu (srbreply->status) !=ST_OK ) { +int len; -case SRB_STATUS_BUS_RESET : - scsicmd->result =DID_RESET <<16 - |COMMAND_COMPLETE <<8 ; -break ; +pr_warn ("aac_srb_callback: srb failed, status = %d\n" , +le32_to_cpu (srbreply->status)); + len =min_t (u32,le32_to_cpu (srbreply->sense_data_size), +SCSI_SENSE_BUFFERSIZE ); + scsicmd->result =DID_ERROR <<16 + |COMMAND_COMPLETE <<8 + |SAM_STAT_CHECK_CONDITION ; +memcpy (scsicmd->sense_buffer, + srbreply->sense_data, len); + } -case SRB_STATUS_MESSAGE_REJECTED : +/* +* Next check the srb status +*/ +switch ((le32_to_cpu (srbreply->srb_status))&0x3f ) { +case SRB_STATUS_ERROR_RECOVERY : +case SRB_STATUS_PENDING : +case SRB_STATUS_SUCCESS : + scsicmd->result =DID_OK <<16 |COMMAND_COMPLETE <<8 ; +break ; +case SRB_STATUS_DATA_OVERRUN : +switch (scsicmd->cmnd[0 ]) { +case READ_6 : +case WRITE_6 : +case READ_10 : +case WRITE_10 : +case READ_12 : +case WRITE_12 : +case READ_16 : +case WRITE_16 : +if (le32_to_cpu (srbreply->data_xfer_length) + < scsicmd->underflow) +pr_warn ("aacraid: SCSI CMD underflow\n" ); +else +pr_warn ("aacraid: SCSI CMD Data Overrun\n" ); scsicmd->result =DID_ERROR <<16 - |MESSAGE_REJECT <<8 ; + |COMMAND_COMPLETE <<8 ; +break ; +case INQUIRY : + scsicmd->result =DID_OK <<16 + |COMMAND_COMPLETE <<8 ;break ; -case SRB_STATUS_REQUEST_FLUSHED : -case SRB_STATUS_ERROR : -case SRB_STATUS_INVALID_REQUEST : -case SRB_STATUS_REQUEST_SENSE_FAILED : -case SRB_STATUS_NO_HBA : -case SRB_STATUS_UNEXPECTED_BUS_FREE : -case SRB_STATUS_PHASE_SEQUENCE_FAILURE : -case SRB_STATUS_BAD_SRB_BLOCK_LENGTH : -case SRB_STATUS_DELAYED_RETRY : -case SRB_STATUS_BAD_FUNCTION : -case SRB_STATUS_NOT_STARTED : -case SRB_STATUS_NOT_IN_USE : -case SRB_STATUS_FORCE_ABORT : -case SRB_STATUS_DOMAIN_VALIDATION_FAIL :default : + scsicmd->result =DID_OK <<16 |COMMAND_COMPLETE <<8 ; +break ; + } +break ; +case SRB_STATUS_ABORTED : + scsicmd->result =DID_ABORT <<16 |ABORT <<8 ; +break ; +case SRB_STATUS_ABORT_FAILED : +/* +* Not sure about this one - but assuming the +* hba was trying to abort for some reason +*/ + scsicmd->result =DID_ERROR <<16 |ABORT <<8 ; +break ; +case SRB_STATUS_PARITY_ERROR : + scsicmd->result =DID_PARITY <<16 + |MSG_PARITY_ERROR <<8 ; +break ; +case SRB_STATUS_NO_DEVICE : +case SRB_STATUS_INVALID_PATH_ID : +case SRB_STATUS_INVALID_TARGET_ID : +case SRB_STATUS_INVALID_LUN : +case SRB_STATUS_SELECTION_TIMEOUT : + scsicmd->result =DID_NO_CONNECT <<16 + |COMMAND_COMPLETE <<8 ; +break ; + +case SRB_STATUS_COMMAND_TIMEOUT : +case SRB_STATUS_TIMEOUT : + scsicmd->result =DID_TIME_OUT <<16 + |COMMAND_COMPLETE <<8 ; +break ; + +case SRB_STATUS_BUSY : + scsicmd->result =DID_BUS_BUSY <<16 + |COMMAND_COMPLETE <<8 ; +break ; + +case SRB_STATUS_BUS_RESET : + scsicmd->result =DID_RESET <<16 + |COMMAND_COMPLETE <<8 ; +break ; + +case SRB_STATUS_MESSAGE_REJECTED : + scsicmd->result =DID_ERROR <<16 + |MESSAGE_REJECT <<8 ; +break ; +case SRB_STATUS_REQUEST_FLUSHED : +case SRB_STATUS_ERROR : +case SRB_STATUS_INVALID_REQUEST : +case SRB_STATUS_REQUEST_SENSE_FAILED : +case SRB_STATUS_NO_HBA : +case SRB_STATUS_UNEXPECTED_BUS_FREE : +case SRB_STATUS_PHASE_SEQUENCE_FAILURE : +case SRB_STATUS_BAD_SRB_BLOCK_LENGTH : +case SRB_STATUS_DELAYED_RETRY : +case SRB_STATUS_BAD_FUNCTION : +case SRB_STATUS_NOT_STARTED : +case SRB_STATUS_NOT_IN_USE : +case SRB_STATUS_FORCE_ABORT : +case SRB_STATUS_DOMAIN_VALIDATION_FAIL : +default :#ifdef AAC_DETAILED_STATUS_INFO -printk (KERN_INFO "aacraid: SRB ERROR(%u) %s scsi cmd 0x%x - scsi status 0x%x\n" , -le32_to_cpu (srbreply->srb_status) &0x3F , -aac_get_status_string ( -le32_to_cpu (srbreply->srb_status) &0x3F ), - scsicmd->cmnd[0 ], -le32_to_cpu (srbreply->scsi_status)); +pr_info ("aacraid: SRB ERROR(%u) %s scsi cmd 0x%x -scsi status 0x%x\n" , +le32_to_cpu (srbreply->srb_status) &0x3F , +aac_get_status_string ( +le32_to_cpu (srbreply->srb_status) &0x3F ), + scsicmd->cmnd[0 ], +le32_to_cpu (srbreply->scsi_status));#endif -if ((scsicmd->cmnd[0 ] ==ATA_12 ) - || (scsicmd->cmnd[0 ] ==ATA_16 )) { -if (scsicmd->cmnd[2 ] & (0x01 <<5 )) { - scsicmd->result =DID_OK <<16 - |COMMAND_COMPLETE <<8 ; -break ; - }else { - scsicmd->result =DID_ERROR <<16 - |COMMAND_COMPLETE <<8 ; -break ; - } +/* +* When the CC bit is SET by the host in ATA pass thru CDB, +* driver is supposed to return DID_OK +* +* When the CC bit is RESET by the host, driver should +* return DID_ERROR +*/ +if ((scsicmd->cmnd[0 ] ==ATA_12 ) + || (scsicmd->cmnd[0 ] ==ATA_16 )) { + +if (scsicmd->cmnd[2 ] & (0x01 <<5 )) { + scsicmd->result =DID_OK <<16 + |COMMAND_COMPLETE <<8 ; +break ; }else { scsicmd->result =DID_ERROR <<16 |COMMAND_COMPLETE <<8 ; -break ; +break ; } + }else { + scsicmd->result =DID_ERROR <<16 + |COMMAND_COMPLETE <<8 ; +break ; } -if (le32_to_cpu (srbreply->scsi_status) - ==SAM_STAT_CHECK_CONDITION ) { -int len; - - scsicmd->result |=SAM_STAT_CHECK_CONDITION ; - len =min_t (u32,le32_to_cpu (srbreply->sense_data_size), -SCSI_SENSE_BUFFERSIZE ); + } +if (le32_to_cpu (srbreply->scsi_status) + ==SAM_STAT_CHECK_CONDITION ) { +int len; + + scsicmd->result |=SAM_STAT_CHECK_CONDITION ; + len =min_t (u32,le32_to_cpu (srbreply->sense_data_size), +SCSI_SENSE_BUFFERSIZE );#ifdef AAC_DETAILED_STATUS_INFO -printk (KERN_WARNING "aac_srb_callback: check condition, status = %d len=%d\n" , -le32_to_cpu (srbreply->status), len); +pr_warn ("aac_srb_callback: check condition, status = %d len=%d\n" , +le32_to_cpu (srbreply->status), len);#endif -memcpy (scsicmd->sense_buffer, - srbreply->sense_data, len); - } +memcpy (scsicmd->sense_buffer, + srbreply->sense_data, len); } +/* * OR in the scsi status (already shifted up a bit) */
Patches currently in stable-queue which might be from [email protected] are
queue-4.4/scsi-aacraid-process-error-for-response-i-o.patch