Commit 9f4c887f authored by Martin K. Petersen's avatar Martin K. Petersen
Browse files

Merge patch series "scsi: EH rework prep patches, part 1"

Hannes Reinecke <hare@suse.de> says:

Hi all,

(taking up an old thread:) here's the first batch of patches for my EH
rework.  It modifies the reset callbacks for SCSI drivers such that
the final conversion to drop the 'struct scsi_cmnd' argument and use
the entity in question (host, bus, target, device) as the argument to
the SCSI EH callbacks becomes possible.  The first part covers drivers
which just requires minor tweaks.

Link: https://lore.kernel.org/r/20231002154328.43718-1-hare@suse.de


Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parents 78882c76 82b2fb52
Loading
Loading
Loading
Loading
+65 −29
Original line number Diff line number Diff line
@@ -183,73 +183,109 @@ static struct fc_function_template mptfc_transport_functions = {
};

static int
mptfc_block_error_handler(struct scsi_cmnd *SCpnt,
			  int (*func)(struct scsi_cmnd *SCpnt),
			  const char *caller)
mptfc_block_error_handler(struct fc_rport *rport)
{
	MPT_SCSI_HOST		*hd;
	struct scsi_device	*sdev = SCpnt->device;
	struct Scsi_Host	*shost = sdev->host;
	struct fc_rport		*rport = starget_to_rport(scsi_target(sdev));
	struct Scsi_Host	*shost = rport_to_shost(rport);
	unsigned long		flags;
	int			ready;
	MPT_ADAPTER		*ioc;
	int			loops = 40;	/* seconds */

	hd = shost_priv(SCpnt->device->host);
	hd = shost_priv(shost);
	ioc = hd->ioc;
	spin_lock_irqsave(shost->host_lock, flags);
	while ((ready = fc_remote_port_chkready(rport) >> 16) == DID_IMM_RETRY
	 || (loops > 0 && ioc->active == 0)) {
		spin_unlock_irqrestore(shost->host_lock, flags);
		dfcprintk (ioc, printk(MYIOC_s_DEBUG_FMT
			"mptfc_block_error_handler.%d: %d:%llu, port status is "
			"%x, active flag %d, deferring %s recovery.\n",
			"mptfc_block_error_handler.%d: %s, port status is "
			"%x, active flag %d, deferring recovery.\n",
			ioc->name, ioc->sh->host_no,
			SCpnt->device->id, SCpnt->device->lun,
			ready, ioc->active, caller));
			dev_name(&rport->dev), ready, ioc->active));
		msleep(1000);
		spin_lock_irqsave(shost->host_lock, flags);
		loops --;
	}
	spin_unlock_irqrestore(shost->host_lock, flags);

	if (ready == DID_NO_CONNECT || !SCpnt->device->hostdata
	 || ioc->active == 0) {
	if (ready == DID_NO_CONNECT || ioc->active == 0) {
		dfcprintk (ioc, printk(MYIOC_s_DEBUG_FMT
			"%s.%d: %d:%llu, failing recovery, "
			"port state %x, active %d, vdevice %p.\n", caller,
			"mpt_block_error_handler.%d: %s, failing recovery, "
			"port state %x, active %d.\n",
			ioc->name, ioc->sh->host_no,
			SCpnt->device->id, SCpnt->device->lun, ready,
			ioc->active, SCpnt->device->hostdata));
			dev_name(&rport->dev), ready, ioc->active));
		return FAILED;
	}
	dfcprintk (ioc, printk(MYIOC_s_DEBUG_FMT
		"%s.%d: %d:%llu, executing recovery.\n", caller,
		ioc->name, ioc->sh->host_no,
		SCpnt->device->id, SCpnt->device->lun));
	return (*func)(SCpnt);
	return SUCCESS;
}

static int
mptfc_abort(struct scsi_cmnd *SCpnt)
{
	return
	    mptfc_block_error_handler(SCpnt, mptscsih_abort, __func__);
	struct Scsi_Host *shost = SCpnt->device->host;
	struct fc_rport *rport = starget_to_rport(scsi_target(SCpnt->device));
	MPT_SCSI_HOST __maybe_unused *hd = shost_priv(shost);
	int rtn;

	rtn = mptfc_block_error_handler(rport);
	if (rtn == SUCCESS) {
		dfcprintk (hd->ioc, printk(MYIOC_s_DEBUG_FMT
			"%s.%d: %d:%llu, executing recovery.\n", __func__,
			hd->ioc->name, shost->host_no,
			SCpnt->device->id, SCpnt->device->lun));
		rtn = mptscsih_abort(SCpnt);
	}
	return rtn;
}

static int
mptfc_dev_reset(struct scsi_cmnd *SCpnt)
{
	return
	    mptfc_block_error_handler(SCpnt, mptscsih_dev_reset, __func__);
	struct Scsi_Host *shost = SCpnt->device->host;
	struct fc_rport *rport = starget_to_rport(scsi_target(SCpnt->device));
	MPT_SCSI_HOST __maybe_unused *hd = shost_priv(shost);
	int rtn;

	rtn = mptfc_block_error_handler(rport);
	if (rtn == SUCCESS) {
		dfcprintk (hd->ioc, printk(MYIOC_s_DEBUG_FMT
			"%s.%d: %d:%llu, executing recovery.\n", __func__,
			hd->ioc->name, shost->host_no,
			SCpnt->device->id, SCpnt->device->lun));
		rtn = mptscsih_dev_reset(SCpnt);
	}
	return rtn;
}

static int
mptfc_bus_reset(struct scsi_cmnd *SCpnt)
{
	return
	    mptfc_block_error_handler(SCpnt, mptscsih_bus_reset, __func__);
	struct Scsi_Host *shost = SCpnt->device->host;
	MPT_SCSI_HOST __maybe_unused *hd = shost_priv(shost);
	int channel = SCpnt->device->channel;
	struct mptfc_rport_info *ri;
	int rtn;

	list_for_each_entry(ri, &hd->ioc->fc_rports, list) {
		if (ri->flags & MPT_RPORT_INFO_FLAGS_REGISTERED) {
			VirtTarget *vtarget = ri->starget->hostdata;

			if (!vtarget || vtarget->channel != channel)
				continue;
			rtn = fc_block_rport(ri->rport);
			if (rtn != 0)
				break;
		}
	}
	if (rtn == 0) {
		dfcprintk (hd->ioc, printk(MYIOC_s_DEBUG_FMT
			"%s.%d: %d:%llu, executing recovery.\n", __func__,
			hd->ioc->name, shost->host_no,
			SCpnt->device->id, SCpnt->device->lun));
		rtn = mptscsih_bus_reset(SCpnt);
	}
	return rtn;
}

static void
+54 −1
Original line number Diff line number Diff line
@@ -1793,7 +1793,7 @@ mptscsih_abort(struct scsi_cmnd * SCpnt)

/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/**
 *	mptscsih_dev_reset - Perform a SCSI TARGET_RESET!  new_eh variant
 *	mptscsih_dev_reset - Perform a SCSI LOGICAL_UNIT_RESET!
 *	@SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
 *
 *	(linux scsi_host_template.eh_dev_reset_handler routine)
@@ -1808,6 +1808,58 @@ mptscsih_dev_reset(struct scsi_cmnd * SCpnt)
	VirtDevice	 *vdevice;
	MPT_ADAPTER	*ioc;

	/* If we can't locate our host adapter structure, return FAILED status.
	 */
	if ((hd = shost_priv(SCpnt->device->host)) == NULL){
		printk(KERN_ERR MYNAM ": lun reset: "
		   "Can't locate host! (sc=%p)\n", SCpnt);
		return FAILED;
	}

	ioc = hd->ioc;
	printk(MYIOC_s_INFO_FMT "attempting lun reset! (sc=%p)\n",
	       ioc->name, SCpnt);
	scsi_print_command(SCpnt);

	vdevice = SCpnt->device->hostdata;
	if (!vdevice || !vdevice->vtarget) {
		retval = 0;
		goto out;
	}

	retval = mptscsih_IssueTaskMgmt(hd,
				MPI_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET,
				vdevice->vtarget->channel,
				vdevice->vtarget->id, vdevice->lun, 0,
				mptscsih_get_tm_timeout(ioc));

 out:
	printk (MYIOC_s_INFO_FMT "lun reset: %s (sc=%p)\n",
	    ioc->name, ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);

	if (retval == 0)
		return SUCCESS;
	else
		return FAILED;
}

/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/**
 *	mptscsih_target_reset - Perform a SCSI TARGET_RESET!
 *	@SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
 *
 *	(linux scsi_host_template.eh_target_reset_handler routine)
 *
 *	Returns SUCCESS or FAILED.
 **/
int
mptscsih_target_reset(struct scsi_cmnd * SCpnt)
{
	MPT_SCSI_HOST	*hd;
	int		 retval;
	VirtDevice	 *vdevice;
	MPT_ADAPTER	*ioc;

	/* If we can't locate our host adapter structure, return FAILED status.
	 */
	if ((hd = shost_priv(SCpnt->device->host)) == NULL){
@@ -3256,6 +3308,7 @@ EXPORT_SYMBOL(mptscsih_slave_destroy);
EXPORT_SYMBOL(mptscsih_slave_configure);
EXPORT_SYMBOL(mptscsih_abort);
EXPORT_SYMBOL(mptscsih_dev_reset);
EXPORT_SYMBOL(mptscsih_target_reset);
EXPORT_SYMBOL(mptscsih_bus_reset);
EXPORT_SYMBOL(mptscsih_host_reset);
EXPORT_SYMBOL(mptscsih_bios_param);
+1 −0
Original line number Diff line number Diff line
@@ -120,6 +120,7 @@ extern void mptscsih_slave_destroy(struct scsi_device *device);
extern int mptscsih_slave_configure(struct scsi_device *device);
extern int mptscsih_abort(struct scsi_cmnd * SCpnt);
extern int mptscsih_dev_reset(struct scsi_cmnd * SCpnt);
extern int mptscsih_target_reset(struct scsi_cmnd * SCpnt);
extern int mptscsih_bus_reset(struct scsi_cmnd * SCpnt);
extern int mptscsih_host_reset(struct scsi_cmnd *SCpnt);
extern int mptscsih_bios_param(struct scsi_device * sdev, struct block_device *bdev, sector_t capacity, int geom[]);
+22 −10
Original line number Diff line number Diff line
@@ -536,13 +536,18 @@ ahd_linux_unmap_scb(struct ahd_softc *ahd, struct scb *scb)
	struct scsi_cmnd *cmd;

	cmd = scb->io_ctx;
	if (cmd) {
		ahd_sync_sglist(ahd, scb, BUS_DMASYNC_POSTWRITE);
		scsi_dma_unmap(cmd);
	}
}

/******************************** Macros **************************************/
#define BUILD_SCSIID(ahd, cmd)						\
	(((scmd_id(cmd) << TID_SHIFT) & TID) | (ahd)->our_id)
static inline unsigned int ahd_build_scsiid(struct ahd_softc *ahd,
					    struct scsi_device *sdev)
{
	return ((sdev_id(sdev) << TID_SHIFT) & TID) | (ahd)->our_id;
}

/*
 * Return a string describing the driver.
@@ -811,14 +816,14 @@ ahd_linux_dev_reset(struct scsi_cmnd *cmd)

	tinfo = ahd_fetch_transinfo(ahd, 'A', ahd->our_id,
				    cmd->device->id, &tstate);
	reset_scb->io_ctx = cmd;
	reset_scb->io_ctx = NULL;
	reset_scb->platform_data->dev = dev;
	reset_scb->sg_count = 0;
	ahd_set_residual(reset_scb, 0);
	ahd_set_sense_residual(reset_scb, 0);
	reset_scb->platform_data->xfer_len = 0;
	reset_scb->hscb->control = 0;
	reset_scb->hscb->scsiid = BUILD_SCSIID(ahd,cmd);
	reset_scb->hscb->scsiid = ahd_build_scsiid(ahd, cmd->device);
	reset_scb->hscb->lun = cmd->device->lun;
	reset_scb->hscb->cdb_len = 0;
	reset_scb->hscb->task_management = SIU_TASKMGMT_LUN_RESET;
@@ -1577,7 +1582,7 @@ ahd_linux_run_command(struct ahd_softc *ahd, struct ahd_linux_device *dev,
	 * Fill out basics of the HSCB.
	 */
	hscb->control = 0;
	hscb->scsiid = BUILD_SCSIID(ahd, cmd);
	hscb->scsiid = ahd_build_scsiid(ahd, cmd->device);
	hscb->lun = cmd->device->lun;
	scb->hscb->task_management = 0;
	mask = SCB_GET_TARGET_MASK(ahd, scb);
@@ -1766,10 +1771,17 @@ ahd_done(struct ahd_softc *ahd, struct scb *scb)
	dev = scb->platform_data->dev;
	dev->active--;
	dev->openings++;
	if (cmd) {
		if ((cmd->result & (CAM_DEV_QFRZN << 16)) != 0) {
			cmd->result &= ~(CAM_DEV_QFRZN << 16);
			dev->qfrozen--;
		}
	} else if (scb->flags & SCB_DEVICE_RESET) {
		if (ahd->platform_data->eh_done)
			complete(ahd->platform_data->eh_done);
		ahd_free_scb(ahd, scb);
		return;
	}
	ahd_linux_unmap_scb(ahd, scb);

	/*
+70 −57
Original line number Diff line number Diff line
@@ -366,7 +366,8 @@ static void ahc_linux_queue_cmd_complete(struct ahc_softc *ahc,
					 struct scsi_cmnd *cmd);
static void ahc_linux_freeze_simq(struct ahc_softc *ahc);
static void ahc_linux_release_simq(struct ahc_softc *ahc);
static int  ahc_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag);
static int  ahc_linux_queue_recovery_cmd(struct scsi_device *sdev,
					 struct scsi_cmnd *cmd);
static void ahc_linux_initialize_scsi_bus(struct ahc_softc *ahc);
static u_int ahc_linux_user_tagdepth(struct ahc_softc *ahc,
				     struct ahc_devinfo *devinfo);
@@ -728,7 +729,7 @@ ahc_linux_abort(struct scsi_cmnd *cmd)
{
	int error;

	error = ahc_linux_queue_recovery_cmd(cmd, SCB_ABORT);
	error = ahc_linux_queue_recovery_cmd(cmd->device, cmd);
	if (error != SUCCESS)
		printk("aic7xxx_abort returns 0x%x\n", error);
	return (error);
@@ -742,7 +743,7 @@ ahc_linux_dev_reset(struct scsi_cmnd *cmd)
{
	int error;

	error = ahc_linux_queue_recovery_cmd(cmd, SCB_DEVICE_RESET);
	error = ahc_linux_queue_recovery_cmd(cmd->device, NULL);
	if (error != SUCCESS)
		printk("aic7xxx_dev_reset returns 0x%x\n", error);
	return (error);
@@ -798,11 +799,18 @@ struct scsi_host_template aic7xxx_driver_template = {

/**************************** Tasklet Handler *********************************/

/******************************** Macros **************************************/
#define BUILD_SCSIID(ahc, cmd)						    \
	((((cmd)->device->id << TID_SHIFT) & TID)			    \
	| (((cmd)->device->channel == 0) ? (ahc)->our_id : (ahc)->our_id_b) \
	| (((cmd)->device->channel == 0) ? 0 : TWIN_CHNLB))

static inline unsigned int ahc_build_scsiid(struct ahc_softc *ahc,
					    struct scsi_device *sdev)
{
	unsigned int scsiid = (sdev->id << TID_SHIFT) & TID;

	if (sdev->channel == 0)
		scsiid |= ahc->our_id;
	else
		scsiid |= ahc->our_id_b | TWIN_CHNLB;
	return scsiid;
}

/******************************** Bus DMA *************************************/
int
@@ -1457,7 +1465,7 @@ ahc_linux_run_command(struct ahc_softc *ahc, struct ahc_linux_device *dev,
	 * Fill out basics of the HSCB.
	 */
	hscb->control = 0;
	hscb->scsiid = BUILD_SCSIID(ahc, cmd);
	hscb->scsiid = ahc_build_scsiid(ahc, cmd->device);
	hscb->lun = cmd->device->lun;
	mask = SCB_GET_TARGET_MASK(ahc, scb);
	tinfo = ahc_fetch_transinfo(ahc, SCB_GET_CHANNEL(ahc, scb),
@@ -2029,11 +2037,12 @@ ahc_linux_release_simq(struct ahc_softc *ahc)
}

static int
ahc_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag)
ahc_linux_queue_recovery_cmd(struct scsi_device *sdev,
			     struct scsi_cmnd *cmd)
{
	struct ahc_softc *ahc;
	struct ahc_linux_device *dev;
	struct scb *pending_scb;
	struct scb *pending_scb = NULL, *scb;
	u_int  saved_scbptr;
	u_int  active_scb_index;
	u_int  last_phase;
@@ -2046,18 +2055,19 @@ ahc_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag)
	int    disconnected;
	unsigned long flags;

	pending_scb = NULL;
	paused = FALSE;
	wait = FALSE;
	ahc = *(struct ahc_softc **)cmd->device->host->hostdata;
	ahc = *(struct ahc_softc **)sdev->host->hostdata;

	scmd_printk(KERN_INFO, cmd, "Attempting to queue a%s message\n",
	       flag == SCB_ABORT ? "n ABORT" : " TARGET RESET");
	sdev_printk(KERN_INFO, sdev, "Attempting to queue a%s message\n",
	       cmd ? "n ABORT" : " TARGET RESET");

	if (cmd) {
		printk("CDB:");
		for (cdb_byte = 0; cdb_byte < cmd->cmd_len; cdb_byte++)
			printk(" 0x%x", cmd->cmnd[cdb_byte]);
		printk("\n");
	}

	ahc_lock(ahc, &flags);

@@ -2068,7 +2078,7 @@ ahc_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag)
	 * at all, and the system wanted us to just abort the
	 * command, return success.
	 */
	dev = scsi_transport_device_data(cmd->device);
	dev = scsi_transport_device_data(sdev);

	if (dev == NULL) {
		/*
@@ -2076,13 +2086,12 @@ ahc_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag)
		 * so we must not still own the command.
		 */
		printk("%s:%d:%d:%d: Is not an active device\n",
		       ahc_name(ahc), cmd->device->channel, cmd->device->id,
		       (u8)cmd->device->lun);
		       ahc_name(ahc), sdev->channel, sdev->id, (u8)sdev->lun);
		retval = SUCCESS;
		goto no_cmd;
	}

	if ((dev->flags & (AHC_DEV_Q_BASIC|AHC_DEV_Q_TAGGED)) == 0
	if (cmd && (dev->flags & (AHC_DEV_Q_BASIC|AHC_DEV_Q_TAGGED)) == 0
	 && ahc_search_untagged_queues(ahc, cmd, cmd->device->id,
				       cmd->device->channel + 'A',
				       (u8)cmd->device->lun,
@@ -2097,25 +2106,28 @@ ahc_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag)
	/*
	 * See if we can find a matching cmd in the pending list.
	 */
	LIST_FOREACH(pending_scb, &ahc->pending_scbs, pending_links) {
		if (pending_scb->io_ctx == cmd)
	if (cmd) {
		LIST_FOREACH(scb, &ahc->pending_scbs, pending_links) {
			if (scb->io_ctx == cmd) {
				pending_scb = scb;
				break;
			}

	if (pending_scb == NULL && flag == SCB_DEVICE_RESET) {

		}
	} else {
		/* Any SCB for this device will do for a target reset */
		LIST_FOREACH(pending_scb, &ahc->pending_scbs, pending_links) {
			if (ahc_match_scb(ahc, pending_scb, scmd_id(cmd),
					  scmd_channel(cmd) + 'A',
		LIST_FOREACH(scb, &ahc->pending_scbs, pending_links) {
			if (ahc_match_scb(ahc, scb, sdev->id,
					  sdev->channel + 'A',
					  CAM_LUN_WILDCARD,
					  SCB_LIST_NULL, ROLE_INITIATOR))
					  SCB_LIST_NULL, ROLE_INITIATOR)) {
				pending_scb = scb;
				break;
			}
		}
	}

	if (pending_scb == NULL) {
		scmd_printk(KERN_INFO, cmd, "Command not found\n");
		sdev_printk(KERN_INFO, sdev, "Command not found\n");
		goto no_cmd;
	}

@@ -2146,22 +2158,22 @@ ahc_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag)
	ahc_dump_card_state(ahc);

	disconnected = TRUE;
	if (flag == SCB_ABORT) {
		if (ahc_search_qinfifo(ahc, cmd->device->id,
				       cmd->device->channel + 'A',
				       cmd->device->lun,
	if (cmd) {
		if (ahc_search_qinfifo(ahc, sdev->id,
				       sdev->channel + 'A',
				       sdev->lun,
				       pending_scb->hscb->tag,
				       ROLE_INITIATOR, CAM_REQ_ABORTED,
				       SEARCH_COMPLETE) > 0) {
			printk("%s:%d:%d:%d: Cmd aborted from QINFIFO\n",
			       ahc_name(ahc), cmd->device->channel,
			       cmd->device->id, (u8)cmd->device->lun);
			       ahc_name(ahc), sdev->channel,
			       sdev->id, (u8)sdev->lun);
			retval = SUCCESS;
			goto done;
		}
	} else if (ahc_search_qinfifo(ahc, cmd->device->id,
				      cmd->device->channel + 'A',
				      cmd->device->lun,
	} else if (ahc_search_qinfifo(ahc, sdev->id,
				      sdev->channel + 'A',
				      sdev->lun,
				      pending_scb->hscb->tag,
				      ROLE_INITIATOR, /*status*/0,
				      SEARCH_COUNT) > 0) {
@@ -2174,7 +2186,7 @@ ahc_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag)
		bus_scb = ahc_lookup_scb(ahc, ahc_inb(ahc, SCB_TAG));
		if (bus_scb == pending_scb)
			disconnected = FALSE;
		else if (flag != SCB_ABORT
		else if (!cmd
		      && ahc_inb(ahc, SAVED_SCSIID) == pending_scb->hscb->scsiid
		      && ahc_inb(ahc, SAVED_LUN) == SCB_GET_LUN(pending_scb))
			disconnected = FALSE;
@@ -2194,18 +2206,18 @@ ahc_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag)
	saved_scsiid = ahc_inb(ahc, SAVED_SCSIID);
	if (last_phase != P_BUSFREE
	 && (pending_scb->hscb->tag == active_scb_index
	  || (flag == SCB_DEVICE_RESET
	   && SCSIID_TARGET(ahc, saved_scsiid) == scmd_id(cmd)))) {
	  || (!cmd && SCSIID_TARGET(ahc, saved_scsiid) == sdev->id))) {

		/*
		 * We're active on the bus, so assert ATN
		 * and hope that the target responds.
		 */
		pending_scb = ahc_lookup_scb(ahc, active_scb_index);
		pending_scb->flags |= SCB_RECOVERY_SCB|flag;
		pending_scb->flags |= SCB_RECOVERY_SCB;
		pending_scb->flags |= cmd ? SCB_ABORT : SCB_DEVICE_RESET;
		ahc_outb(ahc, MSG_OUT, HOST_MSG);
		ahc_outb(ahc, SCSISIGO, last_phase|ATNO);
		scmd_printk(KERN_INFO, cmd, "Device is active, asserting ATN\n");
		sdev_printk(KERN_INFO, sdev, "Device is active, asserting ATN\n");
		wait = TRUE;
	} else if (disconnected) {

@@ -2226,7 +2238,8 @@ ahc_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag)
		 * an unsolicited reselection occurred.
		 */
		pending_scb->hscb->control |= MK_MESSAGE|DISCONNECTED;
		pending_scb->flags |= SCB_RECOVERY_SCB|flag;
		pending_scb->flags |= SCB_RECOVERY_SCB;
		pending_scb->flags |= cmd ? SCB_ABORT : SCB_DEVICE_RESET;

		/*
		 * Remove any cached copy of this SCB in the
@@ -2235,9 +2248,9 @@ ahc_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag)
		 * same element in the SCB, SCB_NEXT, for
		 * both the qinfifo and the disconnected list.
		 */
		ahc_search_disc_list(ahc, cmd->device->id,
				     cmd->device->channel + 'A',
				     cmd->device->lun, pending_scb->hscb->tag,
		ahc_search_disc_list(ahc, sdev->id,
				     sdev->channel + 'A',
				     sdev->lun, pending_scb->hscb->tag,
				     /*stop_on_first*/TRUE,
				     /*remove*/TRUE,
				     /*save_state*/FALSE);
@@ -2260,9 +2273,9 @@ ahc_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag)
		 * so we are the next SCB for this target
		 * to run.
		 */
		ahc_search_qinfifo(ahc, cmd->device->id,
				   cmd->device->channel + 'A',
				   cmd->device->lun, SCB_LIST_NULL,
		ahc_search_qinfifo(ahc, sdev->id,
				   sdev->channel + 'A',
				   (u8)sdev->lun, SCB_LIST_NULL,
				   ROLE_INITIATOR, CAM_REQUEUE_REQ,
				   SEARCH_COMPLETE);
		ahc_qinfifo_requeue_tail(ahc, pending_scb);
@@ -2271,7 +2284,7 @@ ahc_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag)
		printk("Device is disconnected, re-queuing SCB\n");
		wait = TRUE;
	} else {
		scmd_printk(KERN_INFO, cmd, "Unable to deliver message\n");
		sdev_printk(KERN_INFO, sdev, "Unable to deliver message\n");
		retval = FAILED;
		goto done;
	}
Loading