Commit f1dec6b1 authored by Ranjan Kumar's avatar Ranjan Kumar Committed by Martin K. Petersen
Browse files

scsi: mpi3mr: Avoid escalating to higher level reset when target is removed



SCSI error handling has taken place for timed out I/Os on a drive and the
corresponding drive is removed. Stop escalating to higher level of reset by
returning the TUR with "I_T NEXUS LOSS OCCURRED" sense key.

Signed-off-by: default avatarRanjan Kumar <ranjan.kumar@broadcom.com>
Signed-off-by: default avatarSreekanth Reddy <sreekanth.reddy@broadcom.com>
Link: https://lore.kernel.org/r/20230316110209.60145-5-ranjan.kumar@broadcom.com


Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent 22beef38
Loading
Loading
Loading
Loading
+23 −5
Original line number Diff line number Diff line
@@ -4015,9 +4015,13 @@ static int mpi3mr_eh_target_reset(struct scsi_cmnd *scmd)
	stgt_priv_data = sdev_priv_data->tgt_priv_data;
	dev_handle = stgt_priv_data->dev_handle;
	if (stgt_priv_data->dev_removed) {
		struct scmd_priv *cmd_priv = scsi_cmd_priv(scmd);
		sdev_printk(KERN_INFO, scmd->device,
		    "%s:target(handle = 0x%04x) is removed, target reset is not issued\n",
		    mrioc->name, dev_handle);
		if (!cmd_priv->in_lld_scope || cmd_priv->host_tag == MPI3MR_HOSTTAG_INVALID)
			retval = SUCCESS;
		else
			retval = FAILED;
		goto out;
	}
@@ -4083,9 +4087,13 @@ static int mpi3mr_eh_dev_reset(struct scsi_cmnd *scmd)
	stgt_priv_data = sdev_priv_data->tgt_priv_data;
	dev_handle = stgt_priv_data->dev_handle;
	if (stgt_priv_data->dev_removed) {
		struct scmd_priv *cmd_priv = scsi_cmd_priv(scmd);
		sdev_printk(KERN_INFO, scmd->device,
		    "%s: device(handle = 0x%04x) is removed, device(LUN) reset is not issued\n",
		    mrioc->name, dev_handle);
		if (!cmd_priv->in_lld_scope || cmd_priv->host_tag == MPI3MR_HOSTTAG_INVALID)
			retval = SUCCESS;
		else
			retval = FAILED;
		goto out;
	}
@@ -4644,13 +4652,24 @@ static int mpi3mr_qcmd(struct Scsi_Host *shost,
		goto out;
	}

	stgt_priv_data = sdev_priv_data->tgt_priv_data;
	dev_handle = stgt_priv_data->dev_handle;

	/* Avoid error handling escalation when device is removed or blocked */

	if (scmd->device->host->shost_state == SHOST_RECOVERY &&
		scmd->cmnd[0] == TEST_UNIT_READY &&
		(stgt_priv_data->dev_removed || (dev_handle == MPI3MR_INVALID_DEV_HANDLE))) {
		scsi_build_sense(scmd, 0, UNIT_ATTENTION, 0x29, 0x07);
		scsi_done(scmd);
		goto out;
	}

	if (mrioc->reset_in_progress) {
		retval = SCSI_MLQUEUE_HOST_BUSY;
		goto out;
	}

	stgt_priv_data = sdev_priv_data->tgt_priv_data;

	if (atomic_read(&stgt_priv_data->block_io)) {
		if (mrioc->stop_drv_processing) {
			scmd->result = DID_NO_CONNECT << 16;
@@ -4661,7 +4680,6 @@ static int mpi3mr_qcmd(struct Scsi_Host *shost,
		goto out;
	}

	dev_handle = stgt_priv_data->dev_handle;
	if (dev_handle == MPI3MR_INVALID_DEV_HANDLE) {
		scmd->result = DID_NO_CONNECT << 16;
		scsi_done(scmd);