Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 6 Mar 2017 06:22:37 +0000 (UTC)
From:      Alexander Motin <mav@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org
Subject:   svn commit: r314733 - stable/10/sys/dev/isp
Message-ID:  <201703060622.v266MbjK094704@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: mav
Date: Mon Mar  6 06:22:37 2017
New Revision: 314733
URL: https://svnweb.freebsd.org/changeset/base/314733

Log:
  MFC r314086: Fix multiple problems around LUN disable under load.
  
   - Move private data about ATIOs/INOTs from per-LUN to per-channel data.
  This allows active commands to continue operation after LUN destruction.
  This also simplifies lookup of the data by tag in some situations.
   - Unify three restart_queue processing implementations.
   - Complete all ATIOs from restart_queue on LUN disable.
   - Delete ATIO private data when command completed or aborted, not depending
  on the ATIO being requeued, that was ugly hack and could never happen.  CAM
  should always call ether XPT_CONT_TARGET_IO with status or XPT_ABORT.
   - Implement XPT_ABORT for queued ATIOs/INOTs to allow CAM do graceful
  shutdown, not depending on LUN disable, as it is done in ahd(4)/targ(4).
   - Unify isp_endcmd() arguments to make it more usable in generic code.
   - Remove never really used LUN state reference counter.

Modified:
  stable/10/sys/dev/isp/isp_freebsd.c
  stable/10/sys/dev/isp/isp_freebsd.h
  stable/10/sys/dev/isp/isp_target.c
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/sys/dev/isp/isp_freebsd.c
==============================================================================
--- stable/10/sys/dev/isp/isp_freebsd.c	Mon Mar  6 06:22:07 2017	(r314732)
+++ stable/10/sys/dev/isp/isp_freebsd.c	Mon Mar  6 06:22:37 2017	(r314733)
@@ -109,6 +109,9 @@ isp_attach_chan(ispsoftc_t *isp, struct 
 	struct ccb_setasync csa;
 	struct cam_sim *sim;
 	struct cam_path *path;
+#ifdef	ISP_TARGET_MODE
+	int i;
+#endif
 
 	/*
 	 * Construct our SIM entry.
@@ -149,6 +152,14 @@ isp_attach_chan(ispsoftc_t *isp, struct 
 		spi->path = path;
 #ifdef	ISP_TARGET_MODE
 		TAILQ_INIT(&spi->waitq);
+		STAILQ_INIT(&spi->ntfree);
+		for (i = 0; i < ATPDPSIZE; i++)
+			STAILQ_INSERT_TAIL(&spi->ntfree, &spi->ntpool[i], next);
+		LIST_INIT(&spi->atfree);
+		for (i = ATPDPSIZE-1; i >= 0; i--)
+			LIST_INSERT_HEAD(&spi->atfree, &spi->atpool[i], next);
+		for (i = 0; i < ATPDPHASHSIZE; i++)
+			LIST_INIT(&spi->atused[i]);
 #endif
 	} else {
 		fcparam *fcp = FCPARAM(isp, chan);
@@ -167,6 +178,14 @@ isp_attach_chan(ispsoftc_t *isp, struct 
 		TASK_INIT(&fc->gtask, 1, isp_gdt_task, fc);
 #ifdef	ISP_TARGET_MODE
 		TAILQ_INIT(&fc->waitq);
+		STAILQ_INIT(&fc->ntfree);
+		for (i = 0; i < ATPDPSIZE; i++)
+			STAILQ_INSERT_TAIL(&fc->ntfree, &fc->ntpool[i], next);
+		LIST_INIT(&fc->atfree);
+		for (i = ATPDPSIZE-1; i >= 0; i--)
+			LIST_INSERT_HEAD(&fc->atfree, &fc->atpool[i], next);
+		for (i = 0; i < ATPDPHASHSIZE; i++)
+			LIST_INIT(&fc->atused[i]);
 #endif
 		isp_loop_changed(isp, chan);
 		ISP_UNLOCK(isp);
@@ -831,19 +850,15 @@ isp_free_pcmd(ispsoftc_t *isp, union ccb
  * Put the target mode functions here, because some are inlines
  */
 #ifdef	ISP_TARGET_MODE
-static ISP_INLINE int is_lun_enabled(ispsoftc_t *, int, lun_id_t);
 static ISP_INLINE tstate_t *get_lun_statep(ispsoftc_t *, int, lun_id_t);
-static ISP_INLINE tstate_t *get_lun_statep_from_tag(ispsoftc_t *, int, uint32_t);
-static ISP_INLINE void rls_lun_statep(ispsoftc_t *, tstate_t *);
-static ISP_INLINE inot_private_data_t *get_ntp_from_tagdata(ispsoftc_t *, uint32_t, uint32_t, tstate_t **);
-static ISP_INLINE atio_private_data_t *isp_get_atpd(ispsoftc_t *, tstate_t *, uint32_t);
-static ISP_INLINE atio_private_data_t *isp_find_atpd(ispsoftc_t *, tstate_t *, uint32_t);
-static ISP_INLINE void isp_put_atpd(ispsoftc_t *, tstate_t *, atio_private_data_t *);
-static ISP_INLINE inot_private_data_t *isp_get_ntpd(ispsoftc_t *, tstate_t *);
-static ISP_INLINE inot_private_data_t *isp_find_ntpd(ispsoftc_t *, tstate_t *, uint32_t, uint32_t);
-static ISP_INLINE void isp_put_ntpd(ispsoftc_t *, tstate_t *, inot_private_data_t *);
+static atio_private_data_t *isp_get_atpd(ispsoftc_t *, int, uint32_t);
+static atio_private_data_t *isp_find_atpd(ispsoftc_t *, int, uint32_t);
+static void isp_put_atpd(ispsoftc_t *, int, atio_private_data_t *);
+static inot_private_data_t *isp_get_ntpd(ispsoftc_t *, int);
+static inot_private_data_t *isp_find_ntpd(ispsoftc_t *, int, uint32_t, uint32_t);
+static void isp_put_ntpd(ispsoftc_t *, int, inot_private_data_t *);
 static cam_status create_lun_state(ispsoftc_t *, int, struct cam_path *, tstate_t **);
-static void destroy_lun_state(ispsoftc_t *, tstate_t *);
+static void destroy_lun_state(ispsoftc_t *, int, tstate_t *);
 static void isp_enable_lun(ispsoftc_t *, union ccb *);
 static void isp_disable_lun(ispsoftc_t *, union ccb *);
 static timeout_t isp_refire_putback_atio;
@@ -859,43 +874,7 @@ static void isp_handle_platform_notify_f
 static void isp_handle_platform_notify_24xx(ispsoftc_t *, in_fcentry_24xx_t *);
 static int isp_handle_platform_target_notify_ack(ispsoftc_t *, isp_notify_t *, uint32_t rsp);
 static void isp_handle_platform_target_tmf(ispsoftc_t *, isp_notify_t *);
-static void isp_target_mark_aborted(ispsoftc_t *, union ccb *);
-static void isp_target_mark_aborted_early(ispsoftc_t *, tstate_t *, uint32_t);
-
-static ISP_INLINE int
-is_lun_enabled(ispsoftc_t *isp, int bus, lun_id_t lun)
-{
-	tstate_t *tptr;
-	struct tslist *lhp;
-
-	ISP_GET_PC_ADDR(isp, bus, lun_hash[LUN_HASH_FUNC(lun)], lhp);
-	SLIST_FOREACH(tptr, lhp, next) {
-		if (tptr->ts_lun == lun) {
-			return (1);
-		}
-	}
-	return (0);
-}
-
-static void
-dump_tstates(ispsoftc_t *isp, int bus)
-{
-	int i, j;
-	struct tslist *lhp;
-	tstate_t *tptr = NULL;
-
-	if (bus >= isp->isp_nchan) {
-		return;
-	}
-	for (i = 0; i < LUN_HASH_SIZE; i++) {
-		ISP_GET_PC_ADDR(isp, bus, lun_hash[i], lhp);
-		j = 0;
-		SLIST_FOREACH(tptr, lhp, next) {
-			xpt_print(tptr->owner, "[%d, %d] atio_cnt=%d inot_cnt=%d\n", i, j, tptr->atio_count, tptr->inot_count);
-			j++;
-		}
-	}
-}
+static void isp_target_mark_aborted_early(ispsoftc_t *, int chan, tstate_t *, uint32_t);
 
 static ISP_INLINE tstate_t *
 get_lun_statep(ispsoftc_t *isp, int bus, lun_id_t lun)
@@ -906,74 +885,50 @@ get_lun_statep(ispsoftc_t *isp, int bus,
 	if (bus < isp->isp_nchan) {
 		ISP_GET_PC_ADDR(isp, bus, lun_hash[LUN_HASH_FUNC(lun)], lhp);
 		SLIST_FOREACH(tptr, lhp, next) {
-			if (tptr->ts_lun == lun) {
-				tptr->hold++;
+			if (tptr->ts_lun == lun)
 				return (tptr);
-			}
 		}
 	}
 	return (NULL);
 }
 
-static ISP_INLINE tstate_t *
-get_lun_statep_from_tag(ispsoftc_t *isp, int bus, uint32_t tagval)
-{
-	tstate_t *tptr = NULL;
-	atio_private_data_t *atp;
-	struct tslist *lhp;
-	int i;
-
-	if (bus < isp->isp_nchan && tagval != 0) {
-		for (i = 0; i < LUN_HASH_SIZE; i++) {
-			ISP_GET_PC_ADDR(isp, bus, lun_hash[i], lhp);
-			SLIST_FOREACH(tptr, lhp, next) {
-				atp = isp_find_atpd(isp, tptr, tagval);
-				if (atp) {
-					tptr->hold++;
-					return (tptr);
-				}
-			}
-		}
-	}
-	return (NULL);
-}
-
-static ISP_INLINE inot_private_data_t *
-get_ntp_from_tagdata(ispsoftc_t *isp, uint32_t tag_id, uint32_t seq_id, tstate_t **rslt)
+static int
+isp_atio_restart(ispsoftc_t *isp, int bus, tstate_t *tptr)
 {
 	inot_private_data_t *ntp;
-	tstate_t *tptr;
-	struct tslist *lhp;
-	int bus, i;
+	struct ntpdlist rq;
 
-	for (bus = 0; bus < isp->isp_nchan; bus++) {
-		for (i = 0; i < LUN_HASH_SIZE; i++) {
-			ISP_GET_PC_ADDR(isp, bus, lun_hash[i], lhp);
-			SLIST_FOREACH(tptr, lhp, next) {
-				ntp = isp_find_ntpd(isp, tptr, tag_id, seq_id);
-				if (ntp) {
-					*rslt = tptr;
-					tptr->hold++;
-					return (ntp);
-				}
-			}
+	if (STAILQ_EMPTY(&tptr->restart_queue))
+		return (0);
+	STAILQ_INIT(&rq);
+	STAILQ_CONCAT(&rq, &tptr->restart_queue);
+	while ((ntp = STAILQ_FIRST(&rq)) != NULL) {
+		STAILQ_REMOVE_HEAD(&rq, next);
+		if (IS_24XX(isp)) {
+			isp_prt(isp, ISP_LOGTDEBUG0,
+			    "%s: restarting resrc deprived %x", __func__,
+			    ((at7_entry_t *)ntp->data)->at_rxid);
+			isp_handle_platform_atio7(isp, (at7_entry_t *) ntp->data);
+		} else {
+			isp_prt(isp, ISP_LOGTDEBUG0,
+			    "%s: restarting resrc deprived %x", __func__,
+			    ((at2_entry_t *)ntp->data)->at_rxid);
+			isp_handle_platform_atio2(isp, (at2_entry_t *) ntp->data);
 		}
+		isp_put_ntpd(isp, bus, ntp);
+		if (!STAILQ_EMPTY(&tptr->restart_queue))
+			break;
 	}
-	return (NULL);
-}
-
-static ISP_INLINE void
-rls_lun_statep(ispsoftc_t *isp, tstate_t *tptr)
-{
-	KASSERT((tptr->hold), ("tptr not held"));
-	tptr->hold--;
+	if (!STAILQ_EMPTY(&rq)) {
+		STAILQ_CONCAT(&rq, &tptr->restart_queue);
+		STAILQ_CONCAT(&tptr->restart_queue, &rq);
+	}
+	return (!STAILQ_EMPTY(&tptr->restart_queue));
 }
 
 static void
 isp_tmcmd_restart(ispsoftc_t *isp)
 {
-	inot_private_data_t *ntp;
-	inot_private_data_t *restart_queue;
 	tstate_t *tptr;
 	union ccb *ccb;
 	struct tslist *lhp;
@@ -983,31 +938,8 @@ isp_tmcmd_restart(ispsoftc_t *isp)
 	for (bus = 0; bus < isp->isp_nchan; bus++) {
 		for (i = 0; i < LUN_HASH_SIZE; i++) {
 			ISP_GET_PC_ADDR(isp, bus, lun_hash[i], lhp);
-			SLIST_FOREACH(tptr, lhp, next) {
-				if ((restart_queue = tptr->restart_queue) != NULL)
-					tptr->restart_queue = NULL;
-				while (restart_queue) {
-					ntp = restart_queue;
-					restart_queue = ntp->rd.nt.nt_hba;
-					if (IS_24XX(isp)) {
-						isp_prt(isp, ISP_LOGTDEBUG0, "%s: restarting resrc deprived %x", __func__, ((at7_entry_t *)ntp->rd.data)->at_rxid);
-						isp_handle_platform_atio7(isp, (at7_entry_t *) ntp->rd.data);
-					} else {
-						isp_prt(isp, ISP_LOGTDEBUG0, "%s: restarting resrc deprived %x", __func__, ((at2_entry_t *)ntp->rd.data)->at_rxid);
-						isp_handle_platform_atio2(isp, (at2_entry_t *) ntp->rd.data);
-					}
-					isp_put_ntpd(isp, tptr, ntp);
-					if (tptr->restart_queue && restart_queue != NULL) {
-						ntp = tptr->restart_queue;
-						tptr->restart_queue = restart_queue;
-						while (restart_queue->rd.nt.nt_hba) {
-							restart_queue = restart_queue->rd.nt.nt_hba;
-						}
-						restart_queue->rd.nt.nt_hba = ntp;
-						break;
-					}
-				}
-			}
+			SLIST_FOREACH(tptr, lhp, next)
+				isp_atio_restart(isp, bus, tptr);
 		}
 
 		/*
@@ -1022,95 +954,108 @@ isp_tmcmd_restart(ispsoftc_t *isp)
 	}
 }
 
-static ISP_INLINE atio_private_data_t *
-isp_get_atpd(ispsoftc_t *isp, tstate_t *tptr, uint32_t tag)
+static atio_private_data_t *
+isp_get_atpd(ispsoftc_t *isp, int chan, uint32_t tag)
 {
+	struct atpdlist *atfree;
+	struct atpdlist *atused;
 	atio_private_data_t *atp;
 
-	atp = LIST_FIRST(&tptr->atfree);
+	ISP_GET_PC_ADDR(isp, chan, atfree, atfree);
+	atp = LIST_FIRST(atfree);
 	if (atp) {
 		LIST_REMOVE(atp, next);
 		atp->tag = tag;
-		LIST_INSERT_HEAD(&tptr->atused[ATPDPHASH(tag)], atp, next);
+		ISP_GET_PC(isp, chan, atused, atused);
+		LIST_INSERT_HEAD(&atused[ATPDPHASH(tag)], atp, next);
 	}
 	return (atp);
 }
 
-static ISP_INLINE atio_private_data_t *
-isp_find_atpd(ispsoftc_t *isp, tstate_t *tptr, uint32_t tag)
+static atio_private_data_t *
+isp_find_atpd(ispsoftc_t *isp, int chan, uint32_t tag)
 {
+	struct atpdlist *atused;
 	atio_private_data_t *atp;
 
-	LIST_FOREACH(atp, &tptr->atused[ATPDPHASH(tag)], next) {
+	ISP_GET_PC(isp, chan, atused, atused);
+	LIST_FOREACH(atp, &atused[ATPDPHASH(tag)], next) {
 		if (atp->tag == tag)
 			return (atp);
 	}
 	return (NULL);
 }
 
-static ISP_INLINE void
-isp_put_atpd(ispsoftc_t *isp, tstate_t *tptr, atio_private_data_t *atp)
+static void
+isp_put_atpd(ispsoftc_t *isp, int chan, atio_private_data_t *atp)
 {
+	struct atpdlist *atfree;
+
 	if (atp->ests) {
 		isp_put_ecmd(isp, atp->ests);
 	}
 	LIST_REMOVE(atp, next);
 	memset(atp, 0, sizeof (*atp));
-	LIST_INSERT_HEAD(&tptr->atfree, atp, next);
+	ISP_GET_PC_ADDR(isp, chan, atfree, atfree);
+	LIST_INSERT_HEAD(atfree, atp, next);
 }
 
 static void
-isp_dump_atpd(ispsoftc_t *isp, tstate_t *tptr)
+isp_dump_atpd(ispsoftc_t *isp, int chan)
 {
-	atio_private_data_t *atp;
+	atio_private_data_t *atp, *atpool;
 	const char *states[8] = { "Free", "ATIO", "CAM", "CTIO", "LAST_CTIO", "PDON", "?6", "7" };
 
-	for (atp = tptr->atpool; atp < &tptr->atpool[ATPDPSIZE]; atp++) {
-		xpt_print(tptr->owner, "ATP: [0x%x] origdlen %u bytes_xfrd %u lun %x nphdl 0x%04x s_id 0x%06x d_id 0x%06x oxid 0x%04x state %s\n",
-		    atp->tag, atp->orig_datalen, atp->bytes_xfered, atp->lun, atp->nphdl, atp->sid, atp->portid, atp->oxid, states[atp->state & 0x7]);
+	ISP_GET_PC(isp, chan, atpool, atpool);
+	for (atp = atpool; atp < &atpool[ATPDPSIZE]; atp++) {
+		isp_prt(isp, ISP_LOGALL, "Chan %d ATP [0x%x] origdlen %u bytes_xfrd %u lun %jx nphdl 0x%04x s_id 0x%06x d_id 0x%06x oxid 0x%04x state %s\n",
+		    chan, atp->tag, atp->orig_datalen, atp->bytes_xfered, (uintmax_t)atp->lun, atp->nphdl, atp->sid, atp->portid, atp->oxid, states[atp->state & 0x7]);
 	}
 }
 
-
-static ISP_INLINE inot_private_data_t *
-isp_get_ntpd(ispsoftc_t *isp, tstate_t *tptr)
+static inot_private_data_t *
+isp_get_ntpd(ispsoftc_t *isp, int chan)
 {
+	struct ntpdlist *ntfree;
 	inot_private_data_t *ntp;
-	ntp = tptr->ntfree;
-	if (ntp) {
-		tptr->ntfree = ntp->next;
-	}
+
+	ISP_GET_PC_ADDR(isp, chan, ntfree, ntfree);
+	ntp = STAILQ_FIRST(ntfree);
+	if (ntp)
+		STAILQ_REMOVE_HEAD(ntfree, next);
 	return (ntp);
 }
 
-static ISP_INLINE inot_private_data_t *
-isp_find_ntpd(ispsoftc_t *isp, tstate_t *tptr, uint32_t tag_id, uint32_t seq_id)
+static inot_private_data_t *
+isp_find_ntpd(ispsoftc_t *isp, int chan, uint32_t tag_id, uint32_t seq_id)
 {
-	inot_private_data_t *ntp;
-	for (ntp = tptr->ntpool; ntp < &tptr->ntpool[ATPDPSIZE]; ntp++) {
-		if (ntp->rd.tag_id == tag_id && ntp->rd.seq_id == seq_id) {
+	inot_private_data_t *ntp, *ntp2;
+
+	ISP_GET_PC(isp, chan, ntpool, ntp);
+	ISP_GET_PC_ADDR(isp, chan, ntpool[ATPDPSIZE], ntp2);
+	for (; ntp < ntp2; ntp++) {
+		if (ntp->tag_id == tag_id && ntp->seq_id == seq_id)
 			return (ntp);
-		}
 	}
 	return (NULL);
 }
 
-static ISP_INLINE void
-isp_put_ntpd(ispsoftc_t *isp, tstate_t *tptr, inot_private_data_t *ntp)
+static void
+isp_put_ntpd(ispsoftc_t *isp, int chan, inot_private_data_t *ntp)
 {
-	ntp->rd.tag_id = ntp->rd.seq_id = 0;
-	ntp->next = tptr->ntfree;
-	tptr->ntfree = ntp;
+	struct ntpdlist *ntfree;
+
+	ntp->tag_id = ntp->seq_id = 0;
+	ISP_GET_PC_ADDR(isp, chan, ntfree, ntfree);
+	STAILQ_INSERT_HEAD(ntfree, ntp, next);
 }
 
 static cam_status
 create_lun_state(ispsoftc_t *isp, int bus, struct cam_path *path, tstate_t **rslt)
 {
-	cam_status status;
 	lun_id_t lun;
 	struct tslist *lhp;
 	tstate_t *tptr;
-	int i;
 
 	lun = xpt_path_lun_id(path);
 	if (lun != CAM_LUN_WILDCARD) {
@@ -1118,30 +1063,13 @@ create_lun_state(ispsoftc_t *isp, int bu
 			return (CAM_LUN_INVALID);
 		}
 	}
-	if (is_lun_enabled(isp, bus, lun)) {
-		return (CAM_LUN_ALRDY_ENA);
-	}
 	tptr = malloc(sizeof (tstate_t), M_DEVBUF, M_NOWAIT|M_ZERO);
 	if (tptr == NULL) {
 		return (CAM_RESRC_UNAVAIL);
 	}
 	tptr->ts_lun = lun;
-	status = xpt_create_path(&tptr->owner, NULL, xpt_path_path_id(path), xpt_path_target_id(path), lun);
-	if (status != CAM_REQ_CMP) {
-		free(tptr, M_DEVBUF);
-		return (status);
-	}
 	SLIST_INIT(&tptr->atios);
 	SLIST_INIT(&tptr->inots);
-	LIST_INIT(&tptr->atfree);
-	for (i = ATPDPSIZE-1; i >= 0; i--)
-		LIST_INSERT_HEAD(&tptr->atfree, &tptr->atpool[i], next);
-	for (i = 0; i < ATPDPHASHSIZE; i++)
-		LIST_INIT(&tptr->atused[i]);
-	for (i = 0; i < ATPDPSIZE-1; i++)
-		tptr->ntpool[i].next = &tptr->ntpool[i+1];
-	tptr->ntfree = tptr->ntpool;
-	tptr->hold = 1;
 	ISP_GET_PC_ADDR(isp, bus, lun_hash[LUN_HASH_FUNC(lun)], lhp);
 	SLIST_INSERT_HEAD(lhp, tptr, next);
 	*rslt = tptr;
@@ -1149,34 +1077,30 @@ create_lun_state(ispsoftc_t *isp, int bu
 	return (CAM_REQ_CMP);
 }
 
-static ISP_INLINE void
-destroy_lun_state(ispsoftc_t *isp, tstate_t *tptr)
+static void
+destroy_lun_state(ispsoftc_t *isp, int bus, tstate_t *tptr)
 {
 	union ccb *ccb;
 	struct tslist *lhp;
+	inot_private_data_t *ntp;
 
-	KASSERT((tptr->hold != 0), ("tptr is not held"));
-	KASSERT((tptr->hold == 1), ("tptr still held (%d)", tptr->hold));
-	do {
-		ccb = (union ccb *)SLIST_FIRST(&tptr->atios);
-		if (ccb) {
-			SLIST_REMOVE_HEAD(&tptr->atios, sim_links.sle);
-			ccb->ccb_h.status = CAM_REQ_ABORTED;
-			xpt_done(ccb);
-		}
-	} while (ccb);
-	do {
-		ccb = (union ccb *)SLIST_FIRST(&tptr->inots);
-		if (ccb) {
-			SLIST_REMOVE_HEAD(&tptr->inots, sim_links.sle);
-			ccb->ccb_h.status = CAM_REQ_ABORTED;
-			xpt_done(ccb);
-		}
-	} while (ccb);
-	ISP_GET_PC_ADDR(isp, cam_sim_bus(xpt_path_sim(tptr->owner)), lun_hash[LUN_HASH_FUNC(tptr->ts_lun)], lhp);
+	while ((ccb = (union ccb *)SLIST_FIRST(&tptr->atios)) != NULL) {
+		SLIST_REMOVE_HEAD(&tptr->atios, sim_links.sle);
+		ccb->ccb_h.status = CAM_REQ_ABORTED;
+		xpt_done(ccb);
+	};
+	while ((ccb = (union ccb *)SLIST_FIRST(&tptr->inots)) != NULL) {
+		SLIST_REMOVE_HEAD(&tptr->inots, sim_links.sle);
+		ccb->ccb_h.status = CAM_REQ_ABORTED;
+		xpt_done(ccb);
+	}
+	while ((ntp = STAILQ_FIRST(&tptr->restart_queue)) != NULL) {
+		isp_endcmd(isp, ntp->data, NIL_HANDLE, bus, SCSI_STATUS_BUSY, 0);
+		STAILQ_REMOVE_HEAD(&tptr->restart_queue, next);
+		isp_put_ntpd(isp, bus, ntp);
+	}
+	ISP_GET_PC_ADDR(isp, bus, lun_hash[LUN_HASH_FUNC(tptr->ts_lun)], lhp);
 	SLIST_REMOVE(lhp, tptr, tstate, next);
-	ISP_PATH_PRT(isp, ISP_LOGTDEBUG0, tptr->owner, "destroyed tstate\n");
-	xpt_free_path(tptr->owner);
 	free(tptr, M_DEVBUF);
 }
 
@@ -1223,7 +1147,6 @@ isp_enable_lun(ispsoftc_t *isp, union cc
 		return;
 	}
 
-	rls_lun_statep(isp, tptr);
 	ccb->ccb_h.status = CAM_REQ_CMP;
 	xpt_done(ccb);
 }
@@ -1254,7 +1177,7 @@ isp_disable_lun(ispsoftc_t *isp, union c
 		return;
 	}
 
-	destroy_lun_state(isp, tptr);
+	destroy_lun_state(isp, bus, tptr);
 	ccb->ccb_h.status = CAM_REQ_CMP;
 	xpt_done(ccb);
 }
@@ -1263,7 +1186,6 @@ static void
 isp_target_start_ctio(ispsoftc_t *isp, union ccb *ccb, enum Start_Ctio_How how)
 {
 	int fctape, sendstatus, resid;
-	tstate_t *tptr;
 	fcparam *fcp;
 	atio_private_data_t *atp;
 	struct ccb_scsiio *cso;
@@ -1271,16 +1193,6 @@ isp_target_start_ctio(ispsoftc_t *isp, u
 	uint32_t dmaresult, handle, xfrlen, sense_length, tmp;
 	uint8_t local[QENTRY_LEN];
 
-	tptr = get_lun_statep(isp, XS_CHANNEL(ccb), XS_LUN(ccb));
-	if (tptr == NULL) {
-		tptr = get_lun_statep(isp, XS_CHANNEL(ccb), CAM_LUN_WILDCARD);
-		if (tptr == NULL) {
-			isp_prt(isp, ISP_LOGERR, "%s: [0x%x] cannot find tstate pointer", __func__, ccb->csio.tag_id);
-			ccb->ccb_h.status = CAM_DEV_NOT_THERE;
-			xpt_done(ccb);
-			return;
-		}
-	}
 	isp_prt(isp, ISP_LOGTDEBUG0, "%s: ENTRY[0x%x] how %u xfrlen %u sendstatus %d sense_len %u", __func__, ccb->csio.tag_id, how, ccb->csio.dxfer_len,
 	    (ccb->ccb_h.flags & CAM_SEND_STATUS) != 0, ((ccb->ccb_h.flags & CAM_SEND_SENSE)? ccb->csio.sense_len : 0));
 
@@ -1313,10 +1225,10 @@ isp_target_start_ctio(ispsoftc_t *isp, u
 			}
 		}
 
-		atp = isp_find_atpd(isp, tptr, cso->tag_id);
+		atp = isp_find_atpd(isp, XS_CHANNEL(ccb), cso->tag_id);
 		if (atp == NULL) {
 			isp_prt(isp, ISP_LOGERR, "%s: [0x%x] cannot find private data adjunct in %s", __func__, cso->tag_id, __func__);
-			isp_dump_atpd(isp, tptr);
+			isp_dump_atpd(isp, XS_CHANNEL(ccb));
 			ccb->ccb_h.status = CAM_REQ_CMP_ERR;
 			xpt_done(ccb);
 			continue;
@@ -1763,7 +1675,6 @@ isp_target_start_ctio(ispsoftc_t *isp, u
 		atp->ctcnt++;
 		atp->seqno++;
 	}
-	rls_lun_statep(isp, tptr);
 }
 
 static void
@@ -1860,7 +1771,7 @@ isp_handle_platform_atio2(ispsoftc_t *is
 	 */
 	if ((aep->at_status & ~QLTM_SVALID) != AT_CDB) {
 		isp_prt(isp, ISP_LOGWARN, "bogus atio (0x%x) leaked to platform", aep->at_status);
-		isp_endcmd(isp, aep, SCSI_STATUS_BUSY, 0);
+		isp_endcmd(isp, aep, NIL_HANDLE, 0, SCSI_STATUS_BUSY, 0);
 		return;
 	}
 
@@ -1884,9 +1795,9 @@ isp_handle_platform_atio2(ispsoftc_t *is
 		if (tptr == NULL) {
 			isp_prt(isp, ISP_LOGWARN, "%s: [0x%x] no state pointer for lun %d or wildcard", __func__, aep->at_rxid, lun);
 			if (lun == 0) {
-				isp_endcmd(isp, aep, SCSI_STATUS_BUSY, 0);
+				isp_endcmd(isp, aep, nphdl, 0, SCSI_STATUS_BUSY, 0);
 			} else {
-				isp_endcmd(isp, aep, SCSI_STATUS_CHECK_COND | ECMD_SVALID | (0x5 << 12) | (0x25 << 16), 0);
+				isp_endcmd(isp, aep, nphdl, 0, SCSI_STATUS_CHECK_COND | ECMD_SVALID | (0x5 << 12) | (0x25 << 16), 0);
 			}
 			return;
 		}
@@ -1895,38 +1806,15 @@ isp_handle_platform_atio2(ispsoftc_t *is
 	/*
 	 * Start any commands pending resources first.
 	 */
-	if (tptr->restart_queue) {
-		inot_private_data_t *restart_queue = tptr->restart_queue;
-		tptr->restart_queue = NULL;
-		while (restart_queue) {
-			ntp = restart_queue;
-			restart_queue = ntp->rd.nt.nt_hba;
-			isp_prt(isp, ISP_LOGTDEBUG0, "%s: restarting resrc deprived %x", __func__, ((at2_entry_t *)ntp->rd.data)->at_rxid);
-			isp_handle_platform_atio2(isp, (at2_entry_t *) ntp->rd.data);
-			isp_put_ntpd(isp, tptr, ntp);
-			/*
-			 * If a recursion caused the restart queue to start to fill again,
-			 * stop and splice the new list on top of the old list and restore
-			 * it and go to noresrc.
-			 */
-			if (tptr->restart_queue) {
-				ntp = tptr->restart_queue;
-				tptr->restart_queue = restart_queue;
-				while (restart_queue->rd.nt.nt_hba) {
-					restart_queue = restart_queue->rd.nt.nt_hba;
-				}
-				restart_queue->rd.nt.nt_hba = ntp;
-				goto noresrc;
-			}
-		}
-	}
+	if (isp_atio_restart(isp, 0, tptr))
+		goto noresrc;
 
 	atiop = (struct ccb_accept_tio *) SLIST_FIRST(&tptr->atios);
 	if (atiop == NULL) {
 		goto noresrc;
 	}
 
-	atp = isp_get_atpd(isp, tptr, aep->at_rxid);
+	atp = isp_get_atpd(isp, 0, aep->at_rxid);
 	if (atp == NULL) {
 		goto noresrc;
 	}
@@ -2001,19 +1889,15 @@ isp_handle_platform_atio2(ispsoftc_t *is
 	atp->state = ATPD_STATE_CAM;
 	xpt_done((union ccb *)atiop);
 	isp_prt(isp, ISP_LOGTDEBUG0, "ATIO2[0x%x] CDB=0x%x lun %d datalen %u", aep->at_rxid, atp->cdb0, lun, atp->orig_datalen);
-	rls_lun_statep(isp, tptr);
 	return;
 noresrc:
-	ntp = isp_get_ntpd(isp, tptr);
+	ntp = isp_get_ntpd(isp, 0);
 	if (ntp == NULL) {
-		rls_lun_statep(isp, tptr);
-		isp_endcmd(isp, aep, SCSI_STATUS_BUSY, 0);
+		isp_endcmd(isp, aep, nphdl, 0, SCSI_STATUS_BUSY, 0);
 		return;
 	}
-	memcpy(ntp->rd.data, aep, QENTRY_LEN);
-	ntp->rd.nt.nt_hba = tptr->restart_queue;
-	tptr->restart_queue = ntp;
-	rls_lun_statep(isp, tptr);
+	memcpy(ntp->data, aep, QENTRY_LEN);
+	STAILQ_INSERT_TAIL(&tptr->restart_queue, ntp, next);
 }
 
 static void
@@ -2118,40 +2002,13 @@ isp_handle_platform_atio7(ispsoftc_t *is
 	/*
 	 * Start any commands pending resources first.
 	 */
-	if (tptr->restart_queue) {
-		inot_private_data_t *restart_queue = tptr->restart_queue;
-		tptr->restart_queue = NULL;
-		while (restart_queue) {
-			ntp = restart_queue;
-			restart_queue = ntp->rd.nt.nt_hba;
-			isp_prt(isp, ISP_LOGTDEBUG0, "%s: restarting resrc deprived %x", __func__, ((at7_entry_t *)ntp->rd.data)->at_rxid);
-			isp_handle_platform_atio7(isp, (at7_entry_t *) ntp->rd.data);
-			isp_put_ntpd(isp, tptr, ntp);
-			/*
-			 * If a recursion caused the restart queue to start to fill again,
-			 * stop and splice the new list on top of the old list and restore
-			 * it and go to noresrc.
-			 */
-			if (tptr->restart_queue) {
-				isp_prt(isp, ISP_LOGTDEBUG0, "%s: restart queue refilling", __func__);
-				if (restart_queue) {
-					ntp = tptr->restart_queue;
-					tptr->restart_queue = restart_queue;
-					while (restart_queue->rd.nt.nt_hba) {
-						restart_queue = restart_queue->rd.nt.nt_hba;
-					}
-					restart_queue->rd.nt.nt_hba = ntp;
-				}
-				goto noresrc;
-			}
-		}
-	}
+	if (isp_atio_restart(isp, chan, tptr))
+		goto noresrc;
 
 	/*
 	 * If the f/w is out of resources, just send a BUSY status back.
 	 */
 	if (aep->at_rxid == AT7_NORESRC_RXID) {
-		rls_lun_statep(isp, tptr);
 		isp_endcmd(isp, aep, nphdl, chan, SCSI_BUSY, 0);
 		return;
 	}
@@ -2165,7 +2022,7 @@ isp_handle_platform_atio7(ispsoftc_t *is
 		goto noresrc;
 	}
 
-	oatp = isp_find_atpd(isp, tptr, aep->at_rxid);
+	oatp = isp_find_atpd(isp, chan, aep->at_rxid);
 	if (oatp) {
 		isp_prt(isp, ISP_LOGTDEBUG0, "[0x%x] tag wraparound in isp_handle_platforms_atio7 (N-Port Handle 0x%04x S_ID 0x%04x OX_ID 0x%04x) oatp state %d",
 		    aep->at_rxid, nphdl, sid, aep->at_hdr.ox_id, oatp->state);
@@ -2174,7 +2031,7 @@ isp_handle_platform_atio7(ispsoftc_t *is
 		 */
 		goto noresrc;
 	}
-	atp = isp_get_atpd(isp, tptr, aep->at_rxid);
+	atp = isp_get_atpd(isp, chan, aep->at_rxid);
 	if (atp == NULL) {
 		isp_prt(isp, ISP_LOGTDEBUG0, "[0x%x] out of atps", aep->at_rxid);
 		goto noresrc;
@@ -2230,22 +2087,17 @@ isp_handle_platform_atio7(ispsoftc_t *is
 	isp_prt(isp, ISP_LOGTDEBUG0, "ATIO7[0x%x] CDB=0x%x lun %jx datalen %u",
 	    aep->at_rxid, atp->cdb0, (uintmax_t)lun, atp->orig_datalen);
 	xpt_done((union ccb *)atiop);
-	rls_lun_statep(isp, tptr);
 	return;
 noresrc:
-	if (atp) {
-		isp_put_atpd(isp, tptr, atp);
-	}
-	ntp = isp_get_ntpd(isp, tptr);
+	if (atp)
+		isp_put_atpd(isp, chan, atp);
+	ntp = isp_get_ntpd(isp, chan);
 	if (ntp == NULL) {
-		rls_lun_statep(isp, tptr);
 		isp_endcmd(isp, aep, nphdl, chan, SCSI_STATUS_BUSY, 0);
 		return;
 	}
-	memcpy(ntp->rd.data, aep, QENTRY_LEN);
-	ntp->rd.nt.nt_hba = tptr->restart_queue;
-	tptr->restart_queue = ntp;
-	rls_lun_statep(isp, tptr);
+	memcpy(ntp->data, aep, QENTRY_LEN);
+	STAILQ_INSERT_TAIL(&tptr->restart_queue, ntp, next);
 }
 
 
@@ -2256,7 +2108,7 @@ noresrc:
  * transaction.
  */
 static void
-isp_handle_srr_start(ispsoftc_t *isp, tstate_t *tptr, atio_private_data_t *atp)
+isp_handle_srr_start(ispsoftc_t *isp, atio_private_data_t *atp)
 {
 	in_fcentry_24xx_t *inot;
 	uint32_t srr_off, ccb_off, ccb_len, ccb_end;
@@ -2356,7 +2208,6 @@ mdp:
 static void
 isp_handle_srr_notify(ispsoftc_t *isp, void *inot_raw)
 {
-	tstate_t *tptr;
 	in_fcentry_24xx_t *inot = inot_raw;
 	atio_private_data_t *atp;
 	uint32_t tag = inot->in_rxid;
@@ -2367,15 +2218,8 @@ isp_handle_srr_notify(ispsoftc_t *isp, v
 		return;
 	}
 
-	tptr = get_lun_statep_from_tag(isp, bus, tag);
-	if (tptr == NULL) {
-		isp_prt(isp, ISP_LOGERR, "%s: cannot find tptr for tag %x in SRR Notify", __func__, tag);
-		isp_async(isp, ISPASYNC_TARGET_NOTIFY_ACK, inot);
-		return;
-	}
-	atp = isp_find_atpd(isp, tptr, tag);
+	atp = isp_find_atpd(isp, bus, tag);
 	if (atp == NULL) {
-		rls_lun_statep(isp, tptr);
 		isp_prt(isp, ISP_LOGERR, "%s: cannot find adjunct for %x in SRR Notify", __func__, tag);
 		isp_async(isp, ISPASYNC_TARGET_NOTIFY_ACK, inot);
 		return;
@@ -2385,8 +2229,7 @@ isp_handle_srr_notify(ispsoftc_t *isp, v
 	isp_prt(isp, ISP_LOGTINFO /* ISP_LOGTDEBUG0 */, "SRR[0x%x] inot->in_rxid flags 0x%x srr_iu=%x reloff 0x%x", inot->in_rxid, inot->in_flags, inot->in_srr_iu,
 	    inot->in_srr_reloff_lo | (inot->in_srr_reloff_hi << 16));
 	if (atp->srr_ccb)
-		isp_handle_srr_start(isp, tptr, atp);
-	rls_lun_statep(isp, tptr);
+		isp_handle_srr_start(isp, atp);
 }
 
 static void
@@ -2394,7 +2237,6 @@ isp_handle_platform_ctio(ispsoftc_t *isp
 {
 	union ccb *ccb;
 	int sentstatus = 0, ok = 0, notify_cam = 0, resid = 0, failure = 0;
-	tstate_t *tptr = NULL;
 	atio_private_data_t *atp = NULL;
 	int bus;
 	uint32_t handle, moved_data = 0, data_requested;
@@ -2413,19 +2255,10 @@ isp_handle_platform_ctio(ispsoftc_t *isp
 	}
 
 	bus = XS_CHANNEL(ccb);
-	tptr = get_lun_statep(isp, bus, XS_LUN(ccb));
-	if (tptr == NULL) {
-		tptr = get_lun_statep(isp, bus, CAM_LUN_WILDCARD);
-	}
-	if (tptr == NULL) {
-		isp_prt(isp, ISP_LOGERR, "%s: cannot find tptr for tag %x after I/O", __func__, ccb->csio.tag_id);
-		return;
-	}
-
 	if (IS_24XX(isp)) {
-		atp = isp_find_atpd(isp, tptr, ((ct7_entry_t *)arg)->ct_rxid);
+		atp = isp_find_atpd(isp, bus, ((ct7_entry_t *)arg)->ct_rxid);
 	} else {
-		atp = isp_find_atpd(isp, tptr, ((ct2_entry_t *)arg)->ct_rxid);
+		atp = isp_find_atpd(isp, bus, ((ct2_entry_t *)arg)->ct_rxid);
 	}
 	if (atp == NULL) {
 		/*
@@ -2433,10 +2266,9 @@ isp_handle_platform_ctio(ispsoftc_t *isp
 		 * ct_rxid value, filling only ct_syshandle.  Workaround
 		 * that using tag_id from the CCB, pointed by ct_syshandle.
 		 */
-		atp = isp_find_atpd(isp, tptr, ccb->csio.tag_id);
+		atp = isp_find_atpd(isp, bus, ccb->csio.tag_id);
 	}
 	if (atp == NULL) {
-		rls_lun_statep(isp, tptr);
 		isp_prt(isp, ISP_LOGERR, "%s: cannot find adjunct for %x after I/O", __func__, ccb->csio.tag_id);
 		return;
 	}
@@ -2451,8 +2283,7 @@ isp_handle_platform_ctio(ispsoftc_t *isp
 		if (ct->ct_nphdl == CT7_SRR) {
 			atp->srr_ccb = ccb;
 			if (atp->srr_notify_rcvd)
-				isp_handle_srr_start(isp, tptr, atp);
-			rls_lun_statep(isp, tptr);
+				isp_handle_srr_start(isp, atp);
 			return;
 		}
 		if (ct->ct_nphdl == CT_HBA_RESET) {
@@ -2473,8 +2304,7 @@ isp_handle_platform_ctio(ispsoftc_t *isp
 		if (ct->ct_status == CT_SRR) {
 			atp->srr_ccb = ccb;
 			if (atp->srr_notify_rcvd)
-				isp_handle_srr_start(isp, tptr, atp);
-			rls_lun_statep(isp, tptr);
+				isp_handle_srr_start(isp, atp);
 			isp_target_putback_atio(ccb);
 			return;
 		}
@@ -2509,7 +2339,6 @@ isp_handle_platform_ctio(ispsoftc_t *isp
 			ccb->ccb_h.status |= CAM_REQ_CMP_ERR;
 	}
 	atp->state = ATPD_STATE_PDON;
-	rls_lun_statep(isp, tptr);
 
 	/*
 	 * We never *not* notify CAM when there has been any error (ok == 0),
@@ -2525,6 +2354,12 @@ isp_handle_platform_ctio(ispsoftc_t *isp
 	}
 
 	/*
+	 * If we sent status or error happened, we are done with this ATIO.
+	 */
+	if (sentstatus || !ok)
+		isp_put_atpd(isp, bus, atp);
+
+	/*
 	 * We're telling CAM we're done with this CTIO transaction.
 	 *
 	 * 24XX cards never need an ATIO put back.
@@ -2904,11 +2739,11 @@ isp_handle_platform_target_tmf(ispsoftc_
 
 	switch (notify->nt_ncode) {
 	case NT_ABORT_TASK:
-		isp_target_mark_aborted_early(isp, tptr, inot->tag_id);
+		isp_target_mark_aborted_early(isp, notify->nt_channel, tptr, inot->tag_id);
 		inot->arg = MSG_ABORT_TASK;
 		break;
 	case NT_ABORT_TASK_SET:
-		isp_target_mark_aborted_early(isp, tptr, TAG_ANY);
+		isp_target_mark_aborted_early(isp, notify->nt_channel, tptr, TAG_ANY);
 		inot->arg = MSG_ABORT_TASK_SET;
 		break;
 	case NT_CLEAR_ACA:
@@ -2934,30 +2769,26 @@ isp_handle_platform_target_tmf(ispsoftc_
 		goto bad;
 	}
 
-	ntp = isp_get_ntpd(isp, tptr);
+	ntp = isp_get_ntpd(isp, notify->nt_channel);
 	if (ntp == NULL) {
 		isp_prt(isp, ISP_LOGWARN, "%s: out of inotify private structures", __func__);
 		goto bad;
 	}
-	ISP_MEMCPY(&ntp->rd.nt, notify, sizeof (isp_notify_t));
+	ISP_MEMCPY(&ntp->nt, notify, sizeof (isp_notify_t));
 	if (notify->nt_lreserved) {
-		ISP_MEMCPY(&ntp->rd.data, notify->nt_lreserved, QENTRY_LEN);
-		ntp->rd.nt.nt_lreserved = &ntp->rd.data;
+		ISP_MEMCPY(&ntp->data, notify->nt_lreserved, QENTRY_LEN);
+		ntp->nt.nt_lreserved = &ntp->data;
 	}
-	ntp->rd.seq_id = notify->nt_tagval;
-	ntp->rd.tag_id = notify->nt_tagval >> 32;
+	ntp->seq_id = notify->nt_tagval;
+	ntp->tag_id = notify->nt_tagval >> 32;
 
 	tptr->inot_count--;
 	SLIST_REMOVE_HEAD(&tptr->inots, sim_links.sle);
-	rls_lun_statep(isp, tptr);
 	ISP_PATH_PRT(isp, ISP_LOGTDEBUG2, inot->ccb_h.path, "%s: Take FREE INOT count now %d\n", __func__, tptr->inot_count);
 	inot->ccb_h.status = CAM_MESSAGE_RECV;
 	xpt_done((union ccb *)inot);
 	return;
 bad:
-	if (tptr) {
-		rls_lun_statep(isp, tptr);
-	}
 	if (notify->nt_need_ack && notify->nt_lreserved) {
 		if (((isphdr_t *)notify->nt_lreserved)->rqs_entry_type == RQSTYPE_ABTS_RCVD) {
 			if (isp_acknak_abts(isp, notify->nt_lreserved, ENOMEM)) {
@@ -2969,72 +2800,39 @@ bad:
 	}
 }
 
-/*
- * Find the associated private data and mark it as dead so
- * we don't try to work on it any further.
- */
-static void
-isp_target_mark_aborted(ispsoftc_t *isp, union ccb *ccb)
-{
-	tstate_t *tptr;
-	atio_private_data_t *atp;
-	union ccb *accb = ccb->cab.abort_ccb;
-
-	tptr = get_lun_statep(isp, XS_CHANNEL(accb), XS_LUN(accb));
-	if (tptr == NULL) {
-		tptr = get_lun_statep(isp, XS_CHANNEL(accb), CAM_LUN_WILDCARD);
-		if (tptr == NULL) {
-			ccb->ccb_h.status = CAM_REQ_INVALID;
-			return;
-		}
-	}
-
-	atp = isp_find_atpd(isp, tptr, accb->atio.tag_id);
-	if (atp == NULL) {
-		ccb->ccb_h.status = CAM_REQ_INVALID;
-	} else {
-		atp->dead = 1;
-		ccb->ccb_h.status = CAM_REQ_CMP;
-	}
-	rls_lun_statep(isp, tptr);
-}
-
 static void
-isp_target_mark_aborted_early(ispsoftc_t *isp, tstate_t *tptr, uint32_t tag_id)
+isp_target_mark_aborted_early(ispsoftc_t *isp, int chan, tstate_t *tptr, uint32_t tag_id)
 {
-	atio_private_data_t *atp;
-	inot_private_data_t *restart_queue = tptr->restart_queue;
+	atio_private_data_t *atp, *atpool;
+	inot_private_data_t *ntp, *tmp;
+	uint32_t this_tag_id;
 
 	/*
 	 * First, clean any commands pending restart
 	 */
-	tptr->restart_queue = NULL;
-	while (restart_queue) {
-		uint32_t this_tag_id;
-		inot_private_data_t *ntp = restart_queue;
-
-		restart_queue = ntp->rd.nt.nt_hba;
-
-		if (IS_24XX(isp)) {
-			this_tag_id = ((at7_entry_t *)ntp->rd.data)->at_rxid;
-		} else {
-			this_tag_id = ((at2_entry_t *)ntp->rd.data)->at_rxid;
-		}
+	STAILQ_FOREACH_SAFE(ntp, &tptr->restart_queue, next, tmp) {
+		if (IS_24XX(isp))
+			this_tag_id = ((at7_entry_t *)ntp->data)->at_rxid;
+		else
+			this_tag_id = ((at2_entry_t *)ntp->data)->at_rxid;
 		if ((uint64_t)tag_id == TAG_ANY || tag_id == this_tag_id) {
-			isp_put_ntpd(isp, tptr, ntp);
-		} else {
-			ntp->rd.nt.nt_hba = tptr->restart_queue;
-			tptr->restart_queue = ntp;
+			isp_endcmd(isp, ntp->data, NIL_HANDLE, chan,
+			    ECMD_TERMINATE, 0);
+			isp_put_ntpd(isp, chan, ntp);
+			STAILQ_REMOVE(&tptr->restart_queue, ntp,
+			    inot_private_data, next);
 		}
 	}
 
 	/*
 	 * Now mark other ones dead as well.
 	 */
-	for (atp = tptr->atpool; atp < &tptr->atpool[ATPDPSIZE]; atp++) {
-		if ((uint64_t)tag_id == TAG_ANY || atp->tag == tag_id) {
+	ISP_GET_PC(isp, chan, atpool, atpool);
+	for (atp = atpool; atp < &atpool[ATPDPSIZE]; atp++) {
+		if (atp->lun != tptr->ts_lun)
+			continue;
+		if ((uint64_t)tag_id == TAG_ANY || atp->tag == tag_id)
 			atp->dead = 1;
-		}
 	}
 }
 #endif
@@ -3433,6 +3231,77 @@ isp_kthread(void *arg)
 	kthread_exit();
 }
 
+#ifdef	ISP_TARGET_MODE
+static void
+isp_abort_atio(ispsoftc_t *isp, union ccb *ccb)
+{
+	atio_private_data_t *atp;
+	union ccb *accb = ccb->cab.abort_ccb;
+	struct ccb_hdr *sccb;

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201703060622.v266MbjK094704>