Commit 1ff28f22 authored by Martin K. Petersen's avatar Martin K. Petersen
Browse files

Merge branch '5.14/scsi-result' into 5.14/scsi-staging



Include Hannes' SCSI command result rework in the staging branch.

[mkp: remove DRIVER_SENSE from mpi3mr]

Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parents ed1b86ba 3d45cefc
Loading
Loading
Loading
Loading
+3 −4
Original line number Original line Diff line number Diff line
@@ -1172,10 +1172,9 @@ Members of interest:
                   of 0 implies a successfully completed command (and all
                   of 0 implies a successfully completed command (and all
                   data (if any) has been transferred to or from the SCSI
                   data (if any) has been transferred to or from the SCSI
                   target device). 'result' is a 32 bit unsigned integer that
                   target device). 'result' is a 32 bit unsigned integer that
                   can be viewed as 4 related bytes. The SCSI status value is
                   can be viewed as 2 related bytes. The SCSI status value is
                   in the LSB. See include/scsi/scsi.h status_byte(),
                   in the LSB. See include/scsi/scsi.h status_byte() and
                   msg_byte(), host_byte() and driver_byte() macros and
                   host_byte() macros and related constants.
                   related constants.
    sense_buffer
    sense_buffer
		 - an array (maximum size: SCSI_SENSE_BUFFERSIZE bytes) that
		 - an array (maximum size: SCSI_SENSE_BUFFERSIZE bytes) that
                   should be written when the SCSI status (LSB of 'result')
                   should be written when the SCSI status (LSB of 'result')
+1 −1
Original line number Original line Diff line number Diff line
@@ -84,7 +84,7 @@ static int bsg_transport_complete_rq(struct request *rq, struct sg_io_v4 *hdr)
	 */
	 */
	hdr->device_status = job->result & 0xff;
	hdr->device_status = job->result & 0xff;
	hdr->transport_status = host_byte(job->result);
	hdr->transport_status = host_byte(job->result);
	hdr->driver_status = driver_byte(job->result);
	hdr->driver_status = 0;
	hdr->info = 0;
	hdr->info = 0;
	if (hdr->device_status || hdr->transport_status || hdr->driver_status)
	if (hdr->device_status || hdr->transport_status || hdr->driver_status)
		hdr->info |= SG_INFO_CHECK;
		hdr->info |= SG_INFO_CHECK;
+3 −1
Original line number Original line Diff line number Diff line
@@ -96,7 +96,9 @@ static int bsg_scsi_complete_rq(struct request *rq, struct sg_io_v4 *hdr)
	 */
	 */
	hdr->device_status = sreq->result & 0xff;
	hdr->device_status = sreq->result & 0xff;
	hdr->transport_status = host_byte(sreq->result);
	hdr->transport_status = host_byte(sreq->result);
	hdr->driver_status = driver_byte(sreq->result);
	hdr->driver_status = 0;
	if (scsi_status_is_check_condition(sreq->result))
		hdr->driver_status = DRIVER_SENSE;
	hdr->info = 0;
	hdr->info = 0;
	if (hdr->device_status || hdr->transport_status || hdr->driver_status)
	if (hdr->device_status || hdr->transport_status || hdr->driver_status)
		hdr->info |= SG_INFO_CHECK;
		hdr->info |= SG_INFO_CHECK;
+8 −5
Original line number Original line Diff line number Diff line
@@ -254,9 +254,11 @@ static int blk_complete_sghdr_rq(struct request *rq, struct sg_io_hdr *hdr,
	 */
	 */
	hdr->status = req->result & 0xff;
	hdr->status = req->result & 0xff;
	hdr->masked_status = status_byte(req->result);
	hdr->masked_status = status_byte(req->result);
	hdr->msg_status = msg_byte(req->result);
	hdr->msg_status = COMMAND_COMPLETE;
	hdr->host_status = host_byte(req->result);
	hdr->host_status = host_byte(req->result);
	hdr->driver_status = driver_byte(req->result);
	hdr->driver_status = 0;
	if (scsi_status_is_check_condition(hdr->status))
		hdr->driver_status = DRIVER_SENSE;
	hdr->info = 0;
	hdr->info = 0;
	if (hdr->masked_status || hdr->host_status || hdr->driver_status)
	if (hdr->masked_status || hdr->host_status || hdr->driver_status)
		hdr->info |= SG_INFO_CHECK;
		hdr->info |= SG_INFO_CHECK;
@@ -484,8 +486,9 @@ int sg_scsi_ioctl(struct request_queue *q, struct gendisk *disk, fmode_t mode,
		break;
		break;
	}
	}


	if (bytes && blk_rq_map_kern(q, rq, buffer, bytes, GFP_NOIO)) {
	if (bytes) {
		err = DRIVER_ERROR << 24;
		err = blk_rq_map_kern(q, rq, buffer, bytes, GFP_NOIO);
		if (err)
			goto error;
			goto error;
	}
	}


+14 −16
Original line number Original line Diff line number Diff line
@@ -196,9 +196,7 @@ void ata_scsi_set_sense(struct ata_device *dev, struct scsi_cmnd *cmd,
	if (!cmd)
	if (!cmd)
		return;
		return;


	cmd->result = (DRIVER_SENSE << 24) | SAM_STAT_CHECK_CONDITION;
	scsi_build_sense(cmd, d_sense, sk, asc, ascq);

	scsi_build_sense_buffer(d_sense, cmd->sense_buffer, sk, asc, ascq);
}
}


void ata_scsi_set_sense_information(struct ata_device *dev,
void ata_scsi_set_sense_information(struct ata_device *dev,
@@ -409,13 +407,16 @@ int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg)
	cmd_result = scsi_execute(scsidev, scsi_cmd, data_dir, argbuf, argsize,
	cmd_result = scsi_execute(scsidev, scsi_cmd, data_dir, argbuf, argsize,
				  sensebuf, &sshdr, (10*HZ), 5, 0, 0, NULL);
				  sensebuf, &sshdr, (10*HZ), 5, 0, 0, NULL);


	if (driver_byte(cmd_result) == DRIVER_SENSE) {/* sense data available */
	if (cmd_result < 0) {
		rc = cmd_result;
		goto error;
	}
	if (scsi_sense_valid(&sshdr)) {/* sense data available */
		u8 *desc = sensebuf + 8;
		u8 *desc = sensebuf + 8;
		cmd_result &= ~(0xFF<<24); /* DRIVER_SENSE is not an error */


		/* If we set cc then ATA pass-through will cause a
		/* If we set cc then ATA pass-through will cause a
		 * check condition even if no error. Filter that. */
		 * check condition even if no error. Filter that. */
		if (cmd_result & SAM_STAT_CHECK_CONDITION) {
		if (scsi_status_is_check_condition(cmd_result)) {
			if (sshdr.sense_key == RECOVERED_ERROR &&
			if (sshdr.sense_key == RECOVERED_ERROR &&
			    sshdr.asc == 0 && sshdr.ascq == 0x1d)
			    sshdr.asc == 0 && sshdr.ascq == 0x1d)
				cmd_result &= ~SAM_STAT_CHECK_CONDITION;
				cmd_result &= ~SAM_STAT_CHECK_CONDITION;
@@ -490,9 +491,12 @@ int ata_task_ioctl(struct scsi_device *scsidev, void __user *arg)
	cmd_result = scsi_execute(scsidev, scsi_cmd, DMA_NONE, NULL, 0,
	cmd_result = scsi_execute(scsidev, scsi_cmd, DMA_NONE, NULL, 0,
				sensebuf, &sshdr, (10*HZ), 5, 0, 0, NULL);
				sensebuf, &sshdr, (10*HZ), 5, 0, 0, NULL);


	if (driver_byte(cmd_result) == DRIVER_SENSE) {/* sense data available */
	if (cmd_result < 0) {
		rc = cmd_result;
		goto error;
	}
	if (scsi_sense_valid(&sshdr)) {/* sense data available */
		u8 *desc = sensebuf + 8;
		u8 *desc = sensebuf + 8;
		cmd_result &= ~(0xFF<<24); /* DRIVER_SENSE is not an error */


		/* If we set cc then ATA pass-through will cause a
		/* If we set cc then ATA pass-through will cause a
		 * check condition even if no error. Filter that. */
		 * check condition even if no error. Filter that. */
@@ -638,7 +642,7 @@ static struct ata_queued_cmd *ata_scsi_qc_new(struct ata_device *dev,
		if (cmd->request->rq_flags & RQF_QUIET)
		if (cmd->request->rq_flags & RQF_QUIET)
			qc->flags |= ATA_QCFLAG_QUIET;
			qc->flags |= ATA_QCFLAG_QUIET;
	} else {
	} else {
		cmd->result = (DID_OK << 16) | (QUEUE_FULL << 1);
		cmd->result = (DID_OK << 16) | SAM_STAT_TASK_SET_FULL;
		cmd->scsi_done(cmd);
		cmd->scsi_done(cmd);
	}
	}


@@ -858,8 +862,6 @@ static void ata_gen_passthru_sense(struct ata_queued_cmd *qc)


	memset(sb, 0, SCSI_SENSE_BUFFERSIZE);
	memset(sb, 0, SCSI_SENSE_BUFFERSIZE);


	cmd->result = (DRIVER_SENSE << 24) | SAM_STAT_CHECK_CONDITION;

	/*
	/*
	 * Use ata_to_sense_error() to map status register bits
	 * Use ata_to_sense_error() to map status register bits
	 * onto sense key, asc & ascq.
	 * onto sense key, asc & ascq.
@@ -874,8 +876,7 @@ static void ata_gen_passthru_sense(struct ata_queued_cmd *qc)
		 * ATA PASS-THROUGH INFORMATION AVAILABLE
		 * ATA PASS-THROUGH INFORMATION AVAILABLE
		 * Always in descriptor format sense.
		 * Always in descriptor format sense.
		 */
		 */
		scsi_build_sense_buffer(1, cmd->sense_buffer,
		scsi_build_sense(cmd, 1, RECOVERED_ERROR, 0, 0x1D);
					RECOVERED_ERROR, 0, 0x1D);
	}
	}


	if ((cmd->sense_buffer[0] & 0x7f) >= 0x72) {
	if ((cmd->sense_buffer[0] & 0x7f) >= 0x72) {
@@ -957,8 +958,6 @@ static void ata_gen_ata_sense(struct ata_queued_cmd *qc)


	memset(sb, 0, SCSI_SENSE_BUFFERSIZE);
	memset(sb, 0, SCSI_SENSE_BUFFERSIZE);


	cmd->result = (DRIVER_SENSE << 24) | SAM_STAT_CHECK_CONDITION;

	if (ata_dev_disabled(dev)) {
	if (ata_dev_disabled(dev)) {
		/* Device disabled after error recovery */
		/* Device disabled after error recovery */
		/* LOGICAL UNIT NOT READY, HARD RESET REQUIRED */
		/* LOGICAL UNIT NOT READY, HARD RESET REQUIRED */
@@ -4196,7 +4195,6 @@ void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd)


	case REQUEST_SENSE:
	case REQUEST_SENSE:
		ata_scsi_set_sense(dev, cmd, 0, 0, 0);
		ata_scsi_set_sense(dev, cmd, 0, 0, 0);
		cmd->result = (DRIVER_SENSE << 24);
		break;
		break;


	/* if we reach this, then writeback caching is disabled,
	/* if we reach this, then writeback caching is disabled,
Loading