scsi: aacraid: Process Error for response I/O
[ Upstream commit 4ec57fb4edaec523f0f78a0449a3b063749ac58b ] Make sure that the driver processes error conditions even in the fast response path for response from the adapter. Signed-off-by: Raghava Aditya Renukunta <RaghavaAditya.Renukunta@microsemi.com> Signed-off-by: Dave Carroll <David.Carroll@microsemi.com> Reviewed-by: Johannes Thumshirn <jthumshirn@suse.de> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com> Signed-off-by: Sasha Levin <alexander.levin@verizon.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
fff544c8cf
commit
d1f96c30ce
1 changed files with 155 additions and 142 deletions
|
@ -2977,16 +2977,11 @@ static void aac_srb_callback(void *context, struct fib * fibptr)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
BUG_ON(fibptr == NULL);
|
BUG_ON(fibptr == NULL);
|
||||||
|
|
||||||
dev = fibptr->dev;
|
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);
|
|
||||||
|
|
||||||
srbreply = (struct aac_srb_reply *) fib_data(fibptr);
|
srbreply = (struct aac_srb_reply *) fib_data(fibptr);
|
||||||
|
|
||||||
scsicmd->sense_buffer[0] = '\0'; /* Initialize sense valid flag to false */
|
scsicmd->sense_buffer[0] = '\0'; /* Initialize sense valid flag to false */
|
||||||
|
|
||||||
if (fibptr->flags & FIB_CONTEXT_FLAG_FASTRESP) {
|
if (fibptr->flags & FIB_CONTEXT_FLAG_FASTRESP) {
|
||||||
|
@ -2999,6 +2994,16 @@ static void aac_srb_callback(void *context, struct fib * fibptr)
|
||||||
*/
|
*/
|
||||||
scsi_set_resid(scsicmd, scsi_bufflen(scsicmd)
|
scsi_set_resid(scsicmd, scsi_bufflen(scsicmd)
|
||||||
- le32_to_cpu(srbreply->data_xfer_length));
|
- le32_to_cpu(srbreply->data_xfer_length));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* First check the fib status
|
* First check the fib status
|
||||||
*/
|
*/
|
||||||
|
@ -3006,7 +3011,8 @@ static void aac_srb_callback(void *context, struct fib * fibptr)
|
||||||
if (le32_to_cpu(srbreply->status) != ST_OK) {
|
if (le32_to_cpu(srbreply->status) != ST_OK) {
|
||||||
int len;
|
int len;
|
||||||
|
|
||||||
printk(KERN_WARNING "aac_srb_callback: srb failed, status = %d\n", le32_to_cpu(srbreply->status));
|
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),
|
len = min_t(u32, le32_to_cpu(srbreply->sense_data_size),
|
||||||
SCSI_SENSE_BUFFERSIZE);
|
SCSI_SENSE_BUFFERSIZE);
|
||||||
scsicmd->result = DID_ERROR << 16
|
scsicmd->result = DID_ERROR << 16
|
||||||
|
@ -3037,17 +3043,16 @@ static void aac_srb_callback(void *context, struct fib * fibptr)
|
||||||
case WRITE_16:
|
case WRITE_16:
|
||||||
if (le32_to_cpu(srbreply->data_xfer_length)
|
if (le32_to_cpu(srbreply->data_xfer_length)
|
||||||
< scsicmd->underflow)
|
< scsicmd->underflow)
|
||||||
printk(KERN_WARNING"aacraid: SCSI CMD underflow\n");
|
pr_warn("aacraid: SCSI CMD underflow\n");
|
||||||
else
|
else
|
||||||
printk(KERN_WARNING"aacraid: SCSI CMD Data Overrun\n");
|
pr_warn("aacraid: SCSI CMD Data Overrun\n");
|
||||||
scsicmd->result = DID_ERROR << 16
|
scsicmd->result = DID_ERROR << 16
|
||||||
| COMMAND_COMPLETE << 8;
|
| COMMAND_COMPLETE << 8;
|
||||||
break;
|
break;
|
||||||
case INQUIRY: {
|
case INQUIRY:
|
||||||
scsicmd->result = DID_OK << 16
|
scsicmd->result = DID_OK << 16
|
||||||
| COMMAND_COMPLETE << 8;
|
| COMMAND_COMPLETE << 8;
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
default:
|
default:
|
||||||
scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8;
|
scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8;
|
||||||
break;
|
break;
|
||||||
|
@ -3112,15 +3117,23 @@ static void aac_srb_callback(void *context, struct fib * fibptr)
|
||||||
case SRB_STATUS_DOMAIN_VALIDATION_FAIL:
|
case SRB_STATUS_DOMAIN_VALIDATION_FAIL:
|
||||||
default:
|
default:
|
||||||
#ifdef AAC_DETAILED_STATUS_INFO
|
#ifdef AAC_DETAILED_STATUS_INFO
|
||||||
printk(KERN_INFO "aacraid: SRB ERROR(%u) %s scsi cmd 0x%x - scsi status 0x%x\n",
|
pr_info("aacraid: SRB ERROR(%u) %s scsi cmd 0x%x -scsi status 0x%x\n",
|
||||||
le32_to_cpu(srbreply->srb_status) & 0x3F,
|
le32_to_cpu(srbreply->srb_status) & 0x3F,
|
||||||
aac_get_status_string(
|
aac_get_status_string(
|
||||||
le32_to_cpu(srbreply->srb_status) & 0x3F),
|
le32_to_cpu(srbreply->srb_status) & 0x3F),
|
||||||
scsicmd->cmnd[0],
|
scsicmd->cmnd[0],
|
||||||
le32_to_cpu(srbreply->scsi_status));
|
le32_to_cpu(srbreply->scsi_status));
|
||||||
#endif
|
#endif
|
||||||
|
/*
|
||||||
|
* 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)
|
if ((scsicmd->cmnd[0] == ATA_12)
|
||||||
|| (scsicmd->cmnd[0] == ATA_16)) {
|
|| (scsicmd->cmnd[0] == ATA_16)) {
|
||||||
|
|
||||||
if (scsicmd->cmnd[2] & (0x01 << 5)) {
|
if (scsicmd->cmnd[2] & (0x01 << 5)) {
|
||||||
scsicmd->result = DID_OK << 16
|
scsicmd->result = DID_OK << 16
|
||||||
| COMMAND_COMPLETE << 8;
|
| COMMAND_COMPLETE << 8;
|
||||||
|
@ -3144,13 +3157,13 @@ static void aac_srb_callback(void *context, struct fib * fibptr)
|
||||||
len = min_t(u32, le32_to_cpu(srbreply->sense_data_size),
|
len = min_t(u32, le32_to_cpu(srbreply->sense_data_size),
|
||||||
SCSI_SENSE_BUFFERSIZE);
|
SCSI_SENSE_BUFFERSIZE);
|
||||||
#ifdef AAC_DETAILED_STATUS_INFO
|
#ifdef AAC_DETAILED_STATUS_INFO
|
||||||
printk(KERN_WARNING "aac_srb_callback: check condition, status = %d len=%d\n",
|
pr_warn("aac_srb_callback: check condition, status = %d len=%d\n",
|
||||||
le32_to_cpu(srbreply->status), len);
|
le32_to_cpu(srbreply->status), len);
|
||||||
#endif
|
#endif
|
||||||
memcpy(scsicmd->sense_buffer,
|
memcpy(scsicmd->sense_buffer,
|
||||||
srbreply->sense_data, len);
|
srbreply->sense_data, len);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
/*
|
/*
|
||||||
* OR in the scsi status (already shifted up a bit)
|
* OR in the scsi status (already shifted up a bit)
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Add table
Reference in a new issue