Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4ec57fb4 authored by Raghava Aditya Renukunta's avatar Raghava Aditya Renukunta Committed by Martin K. Petersen
Browse files

scsi: aacraid: Process Error for response I/O



Make sure that the driver processes error conditions even in the fast
response path for response from the adapter.

Signed-off-by: default avatarRaghava Aditya Renukunta <RaghavaAditya.Renukunta@microsemi.com>
Signed-off-by: default avatarDave Carroll <David.Carroll@microsemi.com>
Reviewed-by: default avatarJohannes Thumshirn <jthumshirn@suse.de>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent c4e2fbca
Loading
Loading
Loading
Loading
+151 −138
Original line number Diff line number Diff line
@@ -3068,16 +3068,11 @@ static void aac_srb_callback(void *context, struct fib * fibptr)
		return;

	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) {
@@ -3090,6 +3085,16 @@ static void aac_srb_callback(void *context, struct fib * fibptr)
		 */
		scsi_set_resid(scsicmd, scsi_bufflen(scsicmd)
				   - 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
	 */
@@ -3097,7 +3102,8 @@ static void aac_srb_callback(void *context, struct fib * fibptr)
	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));
		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
@@ -3128,17 +3134,16 @@ static void aac_srb_callback(void *context, struct fib * fibptr)
		case  WRITE_16:
			if (le32_to_cpu(srbreply->data_xfer_length)
						< scsicmd->underflow)
					printk(KERN_WARNING"aacraid: SCSI CMD underflow\n");
				pr_warn("aacraid: SCSI CMD underflow\n");
			else
					printk(KERN_WARNING"aacraid: SCSI CMD Data Overrun\n");
				pr_warn("aacraid: SCSI CMD Data Overrun\n");
			scsicmd->result = DID_ERROR << 16
					| COMMAND_COMPLETE << 8;
			break;
			case INQUIRY: {
		case INQUIRY:
			scsicmd->result = DID_OK << 16
					| COMMAND_COMPLETE << 8;
			break;
			}
		default:
			scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8;
			break;
@@ -3203,15 +3208,23 @@ static void aac_srb_callback(void *context, struct fib * fibptr)
	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",
		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
		/*
		 * 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;
@@ -3235,13 +3248,13 @@ static void aac_srb_callback(void *context, struct fib * fibptr)
		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",
		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);
	}
	}

	/*
	 * OR in the scsi status (already shifted up a bit)
	 */