isp_freebsd.c revision 316399
1/*-
2 * Copyright (c) 1997-2009 by Matthew Jacob
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice immediately at the beginning of the file, without modification,
10 *    this list of conditions, and the following disclaimer.
11 * 2. The name of the author may not be used to endorse or promote products
12 *    derived from this software without specific prior written permission.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
18 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 */
26
27/*
28 * Platform (FreeBSD) dependent common attachment code for Qlogic adapters.
29 */
30#include <sys/cdefs.h>
31__FBSDID("$FreeBSD: stable/10/sys/dev/isp/isp_freebsd.c 316399 2017-04-02 10:52:00Z mav $");
32
33#include <dev/isp/isp_freebsd.h>
34#include <sys/unistd.h>
35#include <sys/kthread.h>
36#include <sys/conf.h>
37#include <sys/module.h>
38#include <sys/ioccom.h>
39#include <dev/isp/isp_ioctl.h>
40#include <sys/devicestat.h>
41#include <cam/cam_periph.h>
42#include <cam/cam_xpt_periph.h>
43
44MODULE_VERSION(isp, 1);
45MODULE_DEPEND(isp, cam, 1, 1, 1);
46int isp_announced = 0;
47int isp_loop_down_limit = 60;	/* default loop down limit */
48int isp_quickboot_time = 7;	/* don't wait more than N secs for loop up */
49int isp_gone_device_time = 30;	/* grace time before reporting device lost */
50static const char prom3[] = "Chan %d [%u] PortID 0x%06x Departed because of %s";
51
52static void isp_freeze_loopdown(ispsoftc_t *, int);
53static void isp_loop_changed(ispsoftc_t *isp, int chan);
54static d_ioctl_t ispioctl;
55static void isp_cam_async(void *, uint32_t, struct cam_path *, void *);
56static void isp_poll(struct cam_sim *);
57static timeout_t isp_watchdog;
58static timeout_t isp_gdt;
59static task_fn_t isp_gdt_task;
60static void isp_kthread(void *);
61static void isp_action(struct cam_sim *, union ccb *);
62static int isp_timer_count;
63static void isp_timer(void *);
64
65static struct cdevsw isp_cdevsw = {
66	.d_version =	D_VERSION,
67	.d_ioctl =	ispioctl,
68	.d_name =	"isp",
69};
70
71static int
72isp_role_sysctl(SYSCTL_HANDLER_ARGS)
73{
74	ispsoftc_t *isp = (ispsoftc_t *)arg1;
75	int chan = arg2;
76	int error, old, value;
77
78	value = FCPARAM(isp, chan)->role;
79
80	error = sysctl_handle_int(oidp, &value, 0, req);
81	if ((error != 0) || (req->newptr == NULL))
82		return (error);
83
84	if (value < ISP_ROLE_NONE || value > ISP_ROLE_BOTH)
85		return (EINVAL);
86
87	ISP_LOCK(isp);
88	old = FCPARAM(isp, chan)->role;
89
90	/* We don't allow target mode switch from here. */
91	value = (old & ISP_ROLE_TARGET) | (value & ISP_ROLE_INITIATOR);
92
93	/* If nothing has changed -- we are done. */
94	if (value == old) {
95		ISP_UNLOCK(isp);
96		return (0);
97	}
98
99	/* Actually change the role. */
100	error = isp_control(isp, ISPCTL_CHANGE_ROLE, chan, value);
101	ISP_UNLOCK(isp);
102	return (error);
103}
104
105static int
106isp_attach_chan(ispsoftc_t *isp, struct cam_devq *devq, int chan)
107{
108	struct ccb_setasync csa;
109	struct cam_sim *sim;
110	struct cam_path *path;
111#ifdef	ISP_TARGET_MODE
112	int i;
113#endif
114
115	/*
116	 * Construct our SIM entry.
117	 */
118	sim = cam_sim_alloc(isp_action, isp_poll, "isp", isp, device_get_unit(isp->isp_dev), &isp->isp_osinfo.lock, isp->isp_maxcmds, isp->isp_maxcmds, devq);
119
120	if (sim == NULL) {
121		return (ENOMEM);
122	}
123
124	ISP_LOCK(isp);
125	if (xpt_bus_register(sim, isp->isp_dev, chan) != CAM_SUCCESS) {
126		ISP_UNLOCK(isp);
127		cam_sim_free(sim, FALSE);
128		return (EIO);
129	}
130	ISP_UNLOCK(isp);
131	if (xpt_create_path(&path, NULL, cam_sim_path(sim), CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
132		ISP_LOCK(isp);
133		xpt_bus_deregister(cam_sim_path(sim));
134		ISP_UNLOCK(isp);
135		cam_sim_free(sim, FALSE);
136		return (ENXIO);
137	}
138	xpt_setup_ccb(&csa.ccb_h, path, 5);
139	csa.ccb_h.func_code = XPT_SASYNC_CB;
140	csa.event_enable = AC_LOST_DEVICE;
141	csa.callback = isp_cam_async;
142	csa.callback_arg = sim;
143
144	ISP_LOCK(isp);
145	xpt_action((union ccb *)&csa);
146	ISP_UNLOCK(isp);
147
148	if (IS_SCSI(isp)) {
149		struct isp_spi *spi = ISP_SPI_PC(isp, chan);
150		spi->sim = sim;
151		spi->path = path;
152#ifdef	ISP_TARGET_MODE
153		TAILQ_INIT(&spi->waitq);
154		STAILQ_INIT(&spi->ntfree);
155		for (i = 0; i < ATPDPSIZE; i++)
156			STAILQ_INSERT_TAIL(&spi->ntfree, &spi->ntpool[i], next);
157		LIST_INIT(&spi->atfree);
158		for (i = ATPDPSIZE-1; i >= 0; i--)
159			LIST_INSERT_HEAD(&spi->atfree, &spi->atpool[i], next);
160		for (i = 0; i < ATPDPHASHSIZE; i++)
161			LIST_INIT(&spi->atused[i]);
162#endif
163	} else {
164		fcparam *fcp = FCPARAM(isp, chan);
165		struct isp_fc *fc = ISP_FC_PC(isp, chan);
166		struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(isp->isp_osinfo.dev);
167		struct sysctl_oid *tree = device_get_sysctl_tree(isp->isp_osinfo.dev);
168		char name[16];
169
170		ISP_LOCK(isp);
171		fc->sim = sim;
172		fc->path = path;
173		fc->isp = isp;
174		fc->ready = 1;
175
176		callout_init_mtx(&fc->gdt, &isp->isp_osinfo.lock, 0);
177		TASK_INIT(&fc->gtask, 1, isp_gdt_task, fc);
178#ifdef	ISP_TARGET_MODE
179		TAILQ_INIT(&fc->waitq);
180		STAILQ_INIT(&fc->ntfree);
181		for (i = 0; i < ATPDPSIZE; i++)
182			STAILQ_INSERT_TAIL(&fc->ntfree, &fc->ntpool[i], next);
183		LIST_INIT(&fc->atfree);
184		for (i = ATPDPSIZE-1; i >= 0; i--)
185			LIST_INSERT_HEAD(&fc->atfree, &fc->atpool[i], next);
186		for (i = 0; i < ATPDPHASHSIZE; i++)
187			LIST_INIT(&fc->atused[i]);
188#endif
189		isp_loop_changed(isp, chan);
190		ISP_UNLOCK(isp);
191		if (kproc_create(isp_kthread, fc, &fc->kproc, 0, 0,
192		    "%s_%d", device_get_nameunit(isp->isp_osinfo.dev), chan)) {
193			xpt_free_path(fc->path);
194			ISP_LOCK(isp);
195			xpt_bus_deregister(cam_sim_path(fc->sim));
196			ISP_UNLOCK(isp);
197			cam_sim_free(fc->sim, FALSE);
198			return (ENOMEM);
199		}
200		fc->num_threads += 1;
201		if (chan > 0) {
202			snprintf(name, sizeof(name), "chan%d", chan);
203			tree = SYSCTL_ADD_NODE(ctx, SYSCTL_CHILDREN(tree),
204			    OID_AUTO, name, CTLFLAG_RW, 0, "Virtual channel");
205		}
206		SYSCTL_ADD_QUAD(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
207		    "wwnn", CTLFLAG_RD, &fcp->isp_wwnn,
208		    "World Wide Node Name");
209		SYSCTL_ADD_QUAD(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
210		    "wwpn", CTLFLAG_RD, &fcp->isp_wwpn,
211		    "World Wide Port Name");
212		SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
213		    "loop_down_limit", CTLFLAG_RW, &fc->loop_down_limit, 0,
214		    "Loop Down Limit");
215		SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
216		    "gone_device_time", CTLFLAG_RW, &fc->gone_device_time, 0,
217		    "Gone Device Time");
218#if defined(ISP_TARGET_MODE) && defined(DEBUG)
219		SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
220		    "inject_lost_data_frame", CTLFLAG_RW, &fc->inject_lost_data_frame, 0,
221		    "Cause a Lost Frame on a Read");
222#endif
223		SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
224		    "role", CTLTYPE_INT | CTLFLAG_RW, isp, chan,
225		    isp_role_sysctl, "I", "Current role");
226		SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
227		    "speed", CTLFLAG_RD, &fcp->isp_gbspeed, 0,
228		    "Connection speed in gigabits");
229		SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
230		    "linkstate", CTLFLAG_RD, &fcp->isp_linkstate, 0,
231		    "Link state");
232		SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
233		    "fwstate", CTLFLAG_RD, &fcp->isp_fwstate, 0,
234		    "Firmware state");
235		SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
236		    "loopstate", CTLFLAG_RD, &fcp->isp_loopstate, 0,
237		    "Loop state");
238		SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
239		    "topo", CTLFLAG_RD, &fcp->isp_topo, 0,
240		    "Connection topology");
241	}
242	return (0);
243}
244
245static void
246isp_detach_chan(ispsoftc_t *isp, int chan)
247{
248	struct cam_sim *sim;
249	struct cam_path *path;
250	struct ccb_setasync csa;
251	int *num_threads;
252
253	ISP_GET_PC(isp, chan, sim, sim);
254	ISP_GET_PC(isp, chan, path, path);
255	ISP_GET_PC_ADDR(isp, chan, num_threads, num_threads);
256
257	xpt_setup_ccb(&csa.ccb_h, path, 5);
258	csa.ccb_h.func_code = XPT_SASYNC_CB;
259	csa.event_enable = 0;
260	csa.callback = isp_cam_async;
261	csa.callback_arg = sim;
262	xpt_action((union ccb *)&csa);
263	xpt_free_path(path);
264	xpt_bus_deregister(cam_sim_path(sim));
265	cam_sim_free(sim, FALSE);
266
267	/* Wait for the channel's spawned threads to exit. */
268	wakeup(isp->isp_osinfo.pc.ptr);
269	while (*num_threads != 0)
270		mtx_sleep(isp, &isp->isp_osinfo.lock, PRIBIO, "isp_reap", 100);
271}
272
273int
274isp_attach(ispsoftc_t *isp)
275{
276	const char *nu = device_get_nameunit(isp->isp_osinfo.dev);
277	int du = device_get_unit(isp->isp_dev);
278	int chan;
279
280	/*
281	 * Create the device queue for our SIM(s).
282	 */
283	isp->isp_osinfo.devq = cam_simq_alloc(isp->isp_maxcmds);
284	if (isp->isp_osinfo.devq == NULL) {
285		return (EIO);
286	}
287
288	for (chan = 0; chan < isp->isp_nchan; chan++) {
289		if (isp_attach_chan(isp, isp->isp_osinfo.devq, chan)) {
290			goto unwind;
291		}
292	}
293
294	callout_init_mtx(&isp->isp_osinfo.tmo, &isp->isp_osinfo.lock, 0);
295	isp_timer_count = hz >> 2;
296	callout_reset(&isp->isp_osinfo.tmo, isp_timer_count, isp_timer, isp);
297	isp->isp_osinfo.timer_active = 1;
298
299	isp->isp_osinfo.cdev = make_dev(&isp_cdevsw, du, UID_ROOT, GID_OPERATOR, 0600, "%s", nu);
300	if (isp->isp_osinfo.cdev) {
301		isp->isp_osinfo.cdev->si_drv1 = isp;
302	}
303	return (0);
304
305unwind:
306	while (--chan >= 0) {
307		struct cam_sim *sim;
308		struct cam_path *path;
309
310		ISP_GET_PC(isp, chan, sim, sim);
311		ISP_GET_PC(isp, chan, path, path);
312		xpt_free_path(path);
313		ISP_LOCK(isp);
314		xpt_bus_deregister(cam_sim_path(sim));
315		ISP_UNLOCK(isp);
316		cam_sim_free(sim, FALSE);
317	}
318	if (isp->isp_osinfo.cdev) {
319		destroy_dev(isp->isp_osinfo.cdev);
320		isp->isp_osinfo.cdev = NULL;
321	}
322	cam_simq_free(isp->isp_osinfo.devq);
323	isp->isp_osinfo.devq = NULL;
324	return (-1);
325}
326
327int
328isp_detach(ispsoftc_t *isp)
329{
330	struct cam_sim *sim;
331	int chan;
332
333	ISP_LOCK(isp);
334	for (chan = isp->isp_nchan - 1; chan >= 0; chan -= 1) {
335		ISP_GET_PC(isp, chan, sim, sim);
336		if (sim->refcount > 2) {
337			ISP_UNLOCK(isp);
338			return (EBUSY);
339		}
340	}
341	/* Tell spawned threads that we're exiting. */
342	isp->isp_osinfo.is_exiting = 1;
343	if (isp->isp_osinfo.timer_active) {
344		callout_stop(&isp->isp_osinfo.tmo);
345		isp->isp_osinfo.timer_active = 0;
346	}
347	for (chan = isp->isp_nchan - 1; chan >= 0; chan -= 1)
348		isp_detach_chan(isp, chan);
349	ISP_UNLOCK(isp);
350
351	if (isp->isp_osinfo.cdev) {
352		destroy_dev(isp->isp_osinfo.cdev);
353		isp->isp_osinfo.cdev = NULL;
354	}
355	if (isp->isp_osinfo.devq != NULL) {
356		cam_simq_free(isp->isp_osinfo.devq);
357		isp->isp_osinfo.devq = NULL;
358	}
359	return (0);
360}
361
362static void
363isp_freeze_loopdown(ispsoftc_t *isp, int chan)
364{
365	struct isp_fc *fc = ISP_FC_PC(isp, chan);
366
367	if (fc->sim == NULL)
368		return;
369	if (fc->simqfrozen == 0) {
370		isp_prt(isp, ISP_LOGDEBUG0,
371		    "Chan %d Freeze simq (loopdown)", chan);
372		fc->simqfrozen = SIMQFRZ_LOOPDOWN;
373		xpt_hold_boot();
374		xpt_freeze_simq(fc->sim, 1);
375	} else {
376		isp_prt(isp, ISP_LOGDEBUG0,
377		    "Chan %d Mark simq frozen (loopdown)", chan);
378		fc->simqfrozen |= SIMQFRZ_LOOPDOWN;
379	}
380}
381
382static void
383isp_unfreeze_loopdown(ispsoftc_t *isp, int chan)
384{
385	struct isp_fc *fc = ISP_FC_PC(isp, chan);
386
387	if (fc->sim == NULL)
388		return;
389	int wasfrozen = fc->simqfrozen & SIMQFRZ_LOOPDOWN;
390	fc->simqfrozen &= ~SIMQFRZ_LOOPDOWN;
391	if (wasfrozen && fc->simqfrozen == 0) {
392		isp_prt(isp, ISP_LOGDEBUG0,
393		    "Chan %d Release simq", chan);
394		xpt_release_simq(fc->sim, 1);
395		xpt_release_boot();
396	}
397}
398
399static int
400ispioctl(struct cdev *dev, u_long c, caddr_t addr, int flags, struct thread *td)
401{
402	ispsoftc_t *isp;
403	int nr, chan, retval = ENOTTY;
404
405	isp = dev->si_drv1;
406
407	switch (c) {
408	case ISP_SDBLEV:
409	{
410		int olddblev = isp->isp_dblev;
411		isp->isp_dblev = *(int *)addr;
412		*(int *)addr = olddblev;
413		retval = 0;
414		break;
415	}
416	case ISP_GETROLE:
417		chan = *(int *)addr;
418		if (chan < 0 || chan >= isp->isp_nchan) {
419			retval = -ENXIO;
420			break;
421		}
422		if (IS_FC(isp)) {
423			*(int *)addr = FCPARAM(isp, chan)->role;
424		} else {
425			*(int *)addr = ISP_ROLE_INITIATOR;
426		}
427		retval = 0;
428		break;
429	case ISP_SETROLE:
430		if (IS_SCSI(isp))
431			break;
432		nr = *(int *)addr;
433		chan = nr >> 8;
434		if (chan < 0 || chan >= isp->isp_nchan) {
435			retval = -ENXIO;
436			break;
437		}
438		nr &= 0xff;
439		if (nr & ~(ISP_ROLE_INITIATOR|ISP_ROLE_TARGET)) {
440			retval = EINVAL;
441			break;
442		}
443		ISP_LOCK(isp);
444		*(int *)addr = FCPARAM(isp, chan)->role;
445		retval = isp_control(isp, ISPCTL_CHANGE_ROLE, chan, nr);
446		ISP_UNLOCK(isp);
447		retval = 0;
448		break;
449
450	case ISP_RESETHBA:
451		ISP_LOCK(isp);
452		isp_reinit(isp, 0);
453		ISP_UNLOCK(isp);
454		retval = 0;
455		break;
456
457	case ISP_RESCAN:
458		if (IS_FC(isp)) {
459			chan = *(int *)addr;
460			if (chan < 0 || chan >= isp->isp_nchan) {
461				retval = -ENXIO;
462				break;
463			}
464			ISP_LOCK(isp);
465			if (isp_fc_runstate(isp, chan, 5 * 1000000) != LOOP_READY) {
466				retval = EIO;
467			} else {
468				retval = 0;
469			}
470			ISP_UNLOCK(isp);
471		}
472		break;
473
474	case ISP_FC_LIP:
475		if (IS_FC(isp)) {
476			chan = *(int *)addr;
477			if (chan < 0 || chan >= isp->isp_nchan) {
478				retval = -ENXIO;
479				break;
480			}
481			ISP_LOCK(isp);
482			if (isp_control(isp, ISPCTL_SEND_LIP, chan)) {
483				retval = EIO;
484			} else {
485				retval = 0;
486			}
487			ISP_UNLOCK(isp);
488		}
489		break;
490	case ISP_FC_GETDINFO:
491	{
492		struct isp_fc_device *ifc = (struct isp_fc_device *) addr;
493		fcportdb_t *lp;
494
495		if (IS_SCSI(isp)) {
496			break;
497		}
498		if (ifc->loopid >= MAX_FC_TARG) {
499			retval = EINVAL;
500			break;
501		}
502		lp = &FCPARAM(isp, ifc->chan)->portdb[ifc->loopid];
503		if (lp->state != FC_PORTDB_STATE_NIL) {
504			ifc->role = (lp->prli_word3 & SVC3_ROLE_MASK) >> SVC3_ROLE_SHIFT;
505			ifc->loopid = lp->handle;
506			ifc->portid = lp->portid;
507			ifc->node_wwn = lp->node_wwn;
508			ifc->port_wwn = lp->port_wwn;
509			retval = 0;
510		} else {
511			retval = ENODEV;
512		}
513		break;
514	}
515	case ISP_FC_GETHINFO:
516	{
517		struct isp_hba_device *hba = (struct isp_hba_device *) addr;
518		int chan = hba->fc_channel;
519
520		if (chan < 0 || chan >= isp->isp_nchan) {
521			retval = ENXIO;
522			break;
523		}
524		hba->fc_fw_major = ISP_FW_MAJORX(isp->isp_fwrev);
525		hba->fc_fw_minor = ISP_FW_MINORX(isp->isp_fwrev);
526		hba->fc_fw_micro = ISP_FW_MICROX(isp->isp_fwrev);
527		hba->fc_nchannels = isp->isp_nchan;
528		if (IS_FC(isp)) {
529			hba->fc_nports = MAX_FC_TARG;
530			hba->fc_speed = FCPARAM(isp, hba->fc_channel)->isp_gbspeed;
531			hba->fc_topology = FCPARAM(isp, chan)->isp_topo + 1;
532			hba->fc_loopid = FCPARAM(isp, chan)->isp_loopid;
533			hba->nvram_node_wwn = FCPARAM(isp, chan)->isp_wwnn_nvram;
534			hba->nvram_port_wwn = FCPARAM(isp, chan)->isp_wwpn_nvram;
535			hba->active_node_wwn = FCPARAM(isp, chan)->isp_wwnn;
536			hba->active_port_wwn = FCPARAM(isp, chan)->isp_wwpn;
537		} else {
538			hba->fc_nports = MAX_TARGETS;
539			hba->fc_speed = 0;
540			hba->fc_topology = 0;
541			hba->nvram_node_wwn = 0ull;
542			hba->nvram_port_wwn = 0ull;
543			hba->active_node_wwn = 0ull;
544			hba->active_port_wwn = 0ull;
545		}
546		retval = 0;
547		break;
548	}
549	case ISP_TSK_MGMT:
550	{
551		int needmarker;
552		struct isp_fc_tsk_mgmt *fct = (struct isp_fc_tsk_mgmt *) addr;
553		uint16_t nphdl;
554		mbreg_t mbs;
555
556		if (IS_SCSI(isp)) {
557			break;
558		}
559
560		chan = fct->chan;
561		if (chan < 0 || chan >= isp->isp_nchan) {
562			retval = -ENXIO;
563			break;
564		}
565
566		needmarker = retval = 0;
567		nphdl = fct->loopid;
568		ISP_LOCK(isp);
569		if (IS_24XX(isp)) {
570			void *reqp;
571			uint8_t resp[QENTRY_LEN];
572			isp24xx_tmf_t tmf;
573			isp24xx_statusreq_t sp;
574			fcparam *fcp = FCPARAM(isp, chan);
575			fcportdb_t *lp;
576			int i;
577
578			for (i = 0; i < MAX_FC_TARG; i++) {
579				lp = &fcp->portdb[i];
580				if (lp->handle == nphdl) {
581					break;
582				}
583			}
584			if (i == MAX_FC_TARG) {
585				retval = ENXIO;
586				ISP_UNLOCK(isp);
587				break;
588			}
589			ISP_MEMZERO(&tmf, sizeof(tmf));
590			tmf.tmf_header.rqs_entry_type = RQSTYPE_TSK_MGMT;
591			tmf.tmf_header.rqs_entry_count = 1;
592			tmf.tmf_nphdl = lp->handle;
593			tmf.tmf_delay = 2;
594			tmf.tmf_timeout = 4;
595			tmf.tmf_tidlo = lp->portid;
596			tmf.tmf_tidhi = lp->portid >> 16;
597			tmf.tmf_vpidx = ISP_GET_VPIDX(isp, chan);
598			tmf.tmf_lun[1] = fct->lun & 0xff;
599			if (fct->lun >= 256) {
600				tmf.tmf_lun[0] = 0x40 | (fct->lun >> 8);
601			}
602			switch (fct->action) {
603			case IPT_CLEAR_ACA:
604				tmf.tmf_flags = ISP24XX_TMF_CLEAR_ACA;
605				break;
606			case IPT_TARGET_RESET:
607				tmf.tmf_flags = ISP24XX_TMF_TARGET_RESET;
608				needmarker = 1;
609				break;
610			case IPT_LUN_RESET:
611				tmf.tmf_flags = ISP24XX_TMF_LUN_RESET;
612				needmarker = 1;
613				break;
614			case IPT_CLEAR_TASK_SET:
615				tmf.tmf_flags = ISP24XX_TMF_CLEAR_TASK_SET;
616				needmarker = 1;
617				break;
618			case IPT_ABORT_TASK_SET:
619				tmf.tmf_flags = ISP24XX_TMF_ABORT_TASK_SET;
620				needmarker = 1;
621				break;
622			default:
623				retval = EINVAL;
624				break;
625			}
626			if (retval) {
627				ISP_UNLOCK(isp);
628				break;
629			}
630
631			/* Prepare space for response in memory */
632			memset(resp, 0xff, sizeof(resp));
633			tmf.tmf_handle = isp_allocate_handle(isp, resp,
634			    ISP_HANDLE_CTRL);
635			if (tmf.tmf_handle == 0) {
636				isp_prt(isp, ISP_LOGERR,
637				    "%s: TMF of Chan %d out of handles",
638				    __func__, chan);
639				ISP_UNLOCK(isp);
640				retval = ENOMEM;
641				break;
642			}
643
644			/* Send request and wait for response. */
645			reqp = isp_getrqentry(isp);
646			if (reqp == NULL) {
647				isp_prt(isp, ISP_LOGERR,
648				    "%s: TMF of Chan %d out of rqent",
649				    __func__, chan);
650				isp_destroy_handle(isp, tmf.tmf_handle);
651				ISP_UNLOCK(isp);
652				retval = EIO;
653				break;
654			}
655			isp_put_24xx_tmf(isp, &tmf, (isp24xx_tmf_t *)reqp);
656			if (isp->isp_dblev & ISP_LOGDEBUG1)
657				isp_print_bytes(isp, "IOCB TMF", QENTRY_LEN, reqp);
658			ISP_SYNC_REQUEST(isp);
659			if (msleep(resp, &isp->isp_lock, 0, "TMF", 5*hz) == EWOULDBLOCK) {
660				isp_prt(isp, ISP_LOGERR,
661				    "%s: TMF of Chan %d timed out",
662				    __func__, chan);
663				isp_destroy_handle(isp, tmf.tmf_handle);
664				ISP_UNLOCK(isp);
665				retval = EIO;
666				break;
667			}
668			if (isp->isp_dblev & ISP_LOGDEBUG1)
669				isp_print_bytes(isp, "IOCB TMF response", QENTRY_LEN, resp);
670			isp_get_24xx_response(isp, (isp24xx_statusreq_t *)resp, &sp);
671
672			if (sp.req_completion_status != 0)
673				retval = EIO;
674			else if (needmarker)
675				fcp->sendmarker = 1;
676		} else {
677			MBSINIT(&mbs, 0, MBLOGALL, 0);
678			if (ISP_CAP_2KLOGIN(isp) == 0) {
679				nphdl <<= 8;
680			}
681			switch (fct->action) {
682			case IPT_CLEAR_ACA:
683				mbs.param[0] = MBOX_CLEAR_ACA;
684				mbs.param[1] = nphdl;
685				mbs.param[2] = fct->lun;
686				break;
687			case IPT_TARGET_RESET:
688				mbs.param[0] = MBOX_TARGET_RESET;
689				mbs.param[1] = nphdl;
690				needmarker = 1;
691				break;
692			case IPT_LUN_RESET:
693				mbs.param[0] = MBOX_LUN_RESET;
694				mbs.param[1] = nphdl;
695				mbs.param[2] = fct->lun;
696				needmarker = 1;
697				break;
698			case IPT_CLEAR_TASK_SET:
699				mbs.param[0] = MBOX_CLEAR_TASK_SET;
700				mbs.param[1] = nphdl;
701				mbs.param[2] = fct->lun;
702				needmarker = 1;
703				break;
704			case IPT_ABORT_TASK_SET:
705				mbs.param[0] = MBOX_ABORT_TASK_SET;
706				mbs.param[1] = nphdl;
707				mbs.param[2] = fct->lun;
708				needmarker = 1;
709				break;
710			default:
711				retval = EINVAL;
712				break;
713			}
714			if (retval == 0) {
715				if (needmarker) {
716					FCPARAM(isp, chan)->sendmarker = 1;
717				}
718				retval = isp_control(isp, ISPCTL_RUN_MBOXCMD, &mbs);
719				if (retval) {
720					retval = EIO;
721				}
722			}
723		}
724		ISP_UNLOCK(isp);
725		break;
726	}
727	default:
728		break;
729	}
730	return (retval);
731}
732
733/*
734 * Local Inlines
735 */
736
737static ISP_INLINE int isp_get_pcmd(ispsoftc_t *, union ccb *);
738static ISP_INLINE void isp_free_pcmd(ispsoftc_t *, union ccb *);
739
740static ISP_INLINE int
741isp_get_pcmd(ispsoftc_t *isp, union ccb *ccb)
742{
743	ISP_PCMD(ccb) = isp->isp_osinfo.pcmd_free;
744	if (ISP_PCMD(ccb) == NULL) {
745		return (-1);
746	}
747	isp->isp_osinfo.pcmd_free = ((struct isp_pcmd *)ISP_PCMD(ccb))->next;
748	return (0);
749}
750
751static ISP_INLINE void
752isp_free_pcmd(ispsoftc_t *isp, union ccb *ccb)
753{
754	if (ISP_PCMD(ccb)) {
755#ifdef	ISP_TARGET_MODE
756		PISP_PCMD(ccb)->datalen = 0;
757		PISP_PCMD(ccb)->totslen = 0;
758		PISP_PCMD(ccb)->cumslen = 0;
759		PISP_PCMD(ccb)->crn = 0;
760#endif
761		PISP_PCMD(ccb)->next = isp->isp_osinfo.pcmd_free;
762		isp->isp_osinfo.pcmd_free = ISP_PCMD(ccb);
763		ISP_PCMD(ccb) = NULL;
764	}
765}
766
767/*
768 * Put the target mode functions here, because some are inlines
769 */
770#ifdef	ISP_TARGET_MODE
771static ISP_INLINE tstate_t *get_lun_statep(ispsoftc_t *, int, lun_id_t);
772static atio_private_data_t *isp_get_atpd(ispsoftc_t *, int, uint32_t);
773static atio_private_data_t *isp_find_atpd(ispsoftc_t *, int, uint32_t);
774static void isp_put_atpd(ispsoftc_t *, int, atio_private_data_t *);
775static inot_private_data_t *isp_get_ntpd(ispsoftc_t *, int);
776static inot_private_data_t *isp_find_ntpd(ispsoftc_t *, int, uint32_t, uint32_t);
777static void isp_put_ntpd(ispsoftc_t *, int, inot_private_data_t *);
778static cam_status create_lun_state(ispsoftc_t *, int, struct cam_path *, tstate_t **);
779static void destroy_lun_state(ispsoftc_t *, int, tstate_t *);
780static void isp_enable_lun(ispsoftc_t *, union ccb *);
781static void isp_disable_lun(ispsoftc_t *, union ccb *);
782static timeout_t isp_refire_putback_atio;
783static timeout_t isp_refire_notify_ack;
784static void isp_complete_ctio(union ccb *);
785static void isp_target_putback_atio(union ccb *);
786enum Start_Ctio_How { FROM_CAM, FROM_TIMER, FROM_SRR, FROM_CTIO_DONE };
787static void isp_target_start_ctio(ispsoftc_t *, union ccb *, enum Start_Ctio_How);
788static void isp_handle_platform_atio2(ispsoftc_t *, at2_entry_t *);
789static void isp_handle_platform_atio7(ispsoftc_t *, at7_entry_t *);
790static void isp_handle_platform_ctio(ispsoftc_t *, void *);
791static int isp_handle_platform_target_notify_ack(ispsoftc_t *, isp_notify_t *, uint32_t rsp);
792static void isp_handle_platform_target_tmf(ispsoftc_t *, isp_notify_t *);
793static void isp_target_mark_aborted_early(ispsoftc_t *, int chan, tstate_t *, uint32_t);
794
795static ISP_INLINE tstate_t *
796get_lun_statep(ispsoftc_t *isp, int bus, lun_id_t lun)
797{
798	tstate_t *tptr = NULL;
799	struct tslist *lhp;
800
801	if (bus < isp->isp_nchan) {
802		ISP_GET_PC_ADDR(isp, bus, lun_hash[LUN_HASH_FUNC(lun)], lhp);
803		SLIST_FOREACH(tptr, lhp, next) {
804			if (tptr->ts_lun == lun)
805				return (tptr);
806		}
807	}
808	return (NULL);
809}
810
811static int
812isp_atio_restart(ispsoftc_t *isp, int bus, tstate_t *tptr)
813{
814	inot_private_data_t *ntp;
815	struct ntpdlist rq;
816
817	if (STAILQ_EMPTY(&tptr->restart_queue))
818		return (0);
819	STAILQ_INIT(&rq);
820	STAILQ_CONCAT(&rq, &tptr->restart_queue);
821	while ((ntp = STAILQ_FIRST(&rq)) != NULL) {
822		STAILQ_REMOVE_HEAD(&rq, next);
823		if (IS_24XX(isp)) {
824			isp_prt(isp, ISP_LOGTDEBUG0,
825			    "%s: restarting resrc deprived %x", __func__,
826			    ((at7_entry_t *)ntp->data)->at_rxid);
827			isp_handle_platform_atio7(isp, (at7_entry_t *) ntp->data);
828		} else {
829			isp_prt(isp, ISP_LOGTDEBUG0,
830			    "%s: restarting resrc deprived %x", __func__,
831			    ((at2_entry_t *)ntp->data)->at_rxid);
832			isp_handle_platform_atio2(isp, (at2_entry_t *) ntp->data);
833		}
834		isp_put_ntpd(isp, bus, ntp);
835		if (!STAILQ_EMPTY(&tptr->restart_queue))
836			break;
837	}
838	if (!STAILQ_EMPTY(&rq)) {
839		STAILQ_CONCAT(&rq, &tptr->restart_queue);
840		STAILQ_CONCAT(&tptr->restart_queue, &rq);
841	}
842	return (!STAILQ_EMPTY(&tptr->restart_queue));
843}
844
845static void
846isp_tmcmd_restart(ispsoftc_t *isp)
847{
848	tstate_t *tptr;
849	union ccb *ccb;
850	struct tslist *lhp;
851	struct isp_ccbq *waitq;
852	int bus, i;
853
854	for (bus = 0; bus < isp->isp_nchan; bus++) {
855		for (i = 0; i < LUN_HASH_SIZE; i++) {
856			ISP_GET_PC_ADDR(isp, bus, lun_hash[i], lhp);
857			SLIST_FOREACH(tptr, lhp, next)
858				isp_atio_restart(isp, bus, tptr);
859		}
860
861		/*
862		 * We only need to do this once per channel.
863		 */
864		ISP_GET_PC_ADDR(isp, bus, waitq, waitq);
865		ccb = (union ccb *)TAILQ_FIRST(waitq);
866		if (ccb != NULL) {
867			TAILQ_REMOVE(waitq, &ccb->ccb_h, periph_links.tqe);
868			isp_target_start_ctio(isp, ccb, FROM_TIMER);
869		}
870	}
871}
872
873static atio_private_data_t *
874isp_get_atpd(ispsoftc_t *isp, int chan, uint32_t tag)
875{
876	struct atpdlist *atfree;
877	struct atpdlist *atused;
878	atio_private_data_t *atp;
879
880	ISP_GET_PC_ADDR(isp, chan, atfree, atfree);
881	atp = LIST_FIRST(atfree);
882	if (atp) {
883		LIST_REMOVE(atp, next);
884		atp->tag = tag;
885		ISP_GET_PC(isp, chan, atused, atused);
886		LIST_INSERT_HEAD(&atused[ATPDPHASH(tag)], atp, next);
887	}
888	return (atp);
889}
890
891static atio_private_data_t *
892isp_find_atpd(ispsoftc_t *isp, int chan, uint32_t tag)
893{
894	struct atpdlist *atused;
895	atio_private_data_t *atp;
896
897	ISP_GET_PC(isp, chan, atused, atused);
898	LIST_FOREACH(atp, &atused[ATPDPHASH(tag)], next) {
899		if (atp->tag == tag)
900			return (atp);
901	}
902	return (NULL);
903}
904
905static void
906isp_put_atpd(ispsoftc_t *isp, int chan, atio_private_data_t *atp)
907{
908	struct atpdlist *atfree;
909
910	if (atp->ests) {
911		isp_put_ecmd(isp, atp->ests);
912	}
913	LIST_REMOVE(atp, next);
914	memset(atp, 0, sizeof (*atp));
915	ISP_GET_PC_ADDR(isp, chan, atfree, atfree);
916	LIST_INSERT_HEAD(atfree, atp, next);
917}
918
919static void
920isp_dump_atpd(ispsoftc_t *isp, int chan)
921{
922	atio_private_data_t *atp, *atpool;
923	const char *states[8] = { "Free", "ATIO", "CAM", "CTIO", "LAST_CTIO", "PDON", "?6", "7" };
924
925	ISP_GET_PC(isp, chan, atpool, atpool);
926	for (atp = atpool; atp < &atpool[ATPDPSIZE]; atp++) {
927		if (atp->state == ATPD_STATE_FREE)
928			continue;
929		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",
930		    chan, atp->tag, atp->orig_datalen, atp->bytes_xfered, (uintmax_t)atp->lun, atp->nphdl, atp->sid, atp->did, atp->oxid, states[atp->state & 0x7]);
931	}
932}
933
934static inot_private_data_t *
935isp_get_ntpd(ispsoftc_t *isp, int chan)
936{
937	struct ntpdlist *ntfree;
938	inot_private_data_t *ntp;
939
940	ISP_GET_PC_ADDR(isp, chan, ntfree, ntfree);
941	ntp = STAILQ_FIRST(ntfree);
942	if (ntp)
943		STAILQ_REMOVE_HEAD(ntfree, next);
944	return (ntp);
945}
946
947static inot_private_data_t *
948isp_find_ntpd(ispsoftc_t *isp, int chan, uint32_t tag_id, uint32_t seq_id)
949{
950	inot_private_data_t *ntp, *ntp2;
951
952	ISP_GET_PC(isp, chan, ntpool, ntp);
953	ISP_GET_PC_ADDR(isp, chan, ntpool[ATPDPSIZE], ntp2);
954	for (; ntp < ntp2; ntp++) {
955		if (ntp->tag_id == tag_id && ntp->seq_id == seq_id)
956			return (ntp);
957	}
958	return (NULL);
959}
960
961static void
962isp_put_ntpd(ispsoftc_t *isp, int chan, inot_private_data_t *ntp)
963{
964	struct ntpdlist *ntfree;
965
966	ntp->tag_id = ntp->seq_id = 0;
967	ISP_GET_PC_ADDR(isp, chan, ntfree, ntfree);
968	STAILQ_INSERT_HEAD(ntfree, ntp, next);
969}
970
971static cam_status
972create_lun_state(ispsoftc_t *isp, int bus, struct cam_path *path, tstate_t **rslt)
973{
974	lun_id_t lun;
975	struct tslist *lhp;
976	tstate_t *tptr;
977
978	lun = xpt_path_lun_id(path);
979	if (lun != CAM_LUN_WILDCARD) {
980		if (ISP_MAX_LUNS(isp) > 0 && lun >= ISP_MAX_LUNS(isp)) {
981			return (CAM_LUN_INVALID);
982		}
983	}
984	tptr = malloc(sizeof (tstate_t), M_DEVBUF, M_NOWAIT|M_ZERO);
985	if (tptr == NULL) {
986		return (CAM_RESRC_UNAVAIL);
987	}
988	tptr->ts_lun = lun;
989	SLIST_INIT(&tptr->atios);
990	SLIST_INIT(&tptr->inots);
991	ISP_GET_PC_ADDR(isp, bus, lun_hash[LUN_HASH_FUNC(lun)], lhp);
992	SLIST_INSERT_HEAD(lhp, tptr, next);
993	*rslt = tptr;
994	ISP_PATH_PRT(isp, ISP_LOGTDEBUG0, path, "created tstate\n");
995	return (CAM_REQ_CMP);
996}
997
998static void
999destroy_lun_state(ispsoftc_t *isp, int bus, tstate_t *tptr)
1000{
1001	union ccb *ccb;
1002	struct tslist *lhp;
1003	inot_private_data_t *ntp;
1004
1005	while ((ccb = (union ccb *)SLIST_FIRST(&tptr->atios)) != NULL) {
1006		SLIST_REMOVE_HEAD(&tptr->atios, sim_links.sle);
1007		ccb->ccb_h.status = CAM_REQ_ABORTED;
1008		xpt_done(ccb);
1009	};
1010	while ((ccb = (union ccb *)SLIST_FIRST(&tptr->inots)) != NULL) {
1011		SLIST_REMOVE_HEAD(&tptr->inots, sim_links.sle);
1012		ccb->ccb_h.status = CAM_REQ_ABORTED;
1013		xpt_done(ccb);
1014	}
1015	while ((ntp = STAILQ_FIRST(&tptr->restart_queue)) != NULL) {
1016		isp_endcmd(isp, ntp->data, NIL_HANDLE, bus, SCSI_STATUS_BUSY, 0);
1017		STAILQ_REMOVE_HEAD(&tptr->restart_queue, next);
1018		isp_put_ntpd(isp, bus, ntp);
1019	}
1020	ISP_GET_PC_ADDR(isp, bus, lun_hash[LUN_HASH_FUNC(tptr->ts_lun)], lhp);
1021	SLIST_REMOVE(lhp, tptr, tstate, next);
1022	free(tptr, M_DEVBUF);
1023}
1024
1025static void
1026isp_enable_lun(ispsoftc_t *isp, union ccb *ccb)
1027{
1028	tstate_t *tptr;
1029	int bus;
1030	target_id_t target;
1031	lun_id_t lun;
1032
1033	if (!IS_FC(isp) || !ISP_CAP_TMODE(isp) || !ISP_CAP_SCCFW(isp)) {
1034		xpt_print(ccb->ccb_h.path, "Target mode is not supported\n");
1035		ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
1036		xpt_done(ccb);
1037		return;
1038	}
1039
1040	/*
1041	 * We only support either target and lun both wildcard
1042	 * or target and lun both non-wildcard.
1043	 */
1044	bus = XS_CHANNEL(ccb);
1045	target = ccb->ccb_h.target_id;
1046	lun = ccb->ccb_h.target_lun;
1047	ISP_PATH_PRT(isp, ISP_LOGTDEBUG0|ISP_LOGCONFIG, ccb->ccb_h.path,
1048	    "enabling lun %jx\n", (uintmax_t)lun);
1049	if ((target == CAM_TARGET_WILDCARD) != (lun == CAM_LUN_WILDCARD)) {
1050		ccb->ccb_h.status = CAM_LUN_INVALID;
1051		xpt_done(ccb);
1052		return;
1053	}
1054
1055	/* Create the state pointer. It should not already exist. */
1056	tptr = get_lun_statep(isp, bus, lun);
1057	if (tptr) {
1058		ccb->ccb_h.status = CAM_LUN_ALRDY_ENA;
1059		xpt_done(ccb);
1060		return;
1061	}
1062	ccb->ccb_h.status = create_lun_state(isp, bus, ccb->ccb_h.path, &tptr);
1063	if (ccb->ccb_h.status != CAM_REQ_CMP) {
1064		xpt_done(ccb);
1065		return;
1066	}
1067
1068	ccb->ccb_h.status = CAM_REQ_CMP;
1069	xpt_done(ccb);
1070}
1071
1072static void
1073isp_disable_lun(ispsoftc_t *isp, union ccb *ccb)
1074{
1075	tstate_t *tptr = NULL;
1076	int bus;
1077	target_id_t target;
1078	lun_id_t lun;
1079
1080	bus = XS_CHANNEL(ccb);
1081	target = ccb->ccb_h.target_id;
1082	lun = ccb->ccb_h.target_lun;
1083	ISP_PATH_PRT(isp, ISP_LOGTDEBUG0|ISP_LOGCONFIG, ccb->ccb_h.path,
1084	    "disabling lun %jx\n", (uintmax_t)lun);
1085	if ((target == CAM_TARGET_WILDCARD) != (lun == CAM_LUN_WILDCARD)) {
1086		ccb->ccb_h.status = CAM_LUN_INVALID;
1087		xpt_done(ccb);
1088		return;
1089	}
1090
1091	/* Find the state pointer. */
1092	if ((tptr = get_lun_statep(isp, bus, lun)) == NULL) {
1093		ccb->ccb_h.status = CAM_PATH_INVALID;
1094		xpt_done(ccb);
1095		return;
1096	}
1097
1098	destroy_lun_state(isp, bus, tptr);
1099	ccb->ccb_h.status = CAM_REQ_CMP;
1100	xpt_done(ccb);
1101}
1102
1103static void
1104isp_target_start_ctio(ispsoftc_t *isp, union ccb *ccb, enum Start_Ctio_How how)
1105{
1106	int fctape, sendstatus, resid;
1107	fcparam *fcp;
1108	atio_private_data_t *atp;
1109	struct ccb_scsiio *cso;
1110	struct isp_ccbq *waitq;
1111	uint32_t dmaresult, handle, xfrlen, sense_length, tmp;
1112	uint8_t local[QENTRY_LEN];
1113
1114	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,
1115	    (ccb->ccb_h.flags & CAM_SEND_STATUS) != 0, ((ccb->ccb_h.flags & CAM_SEND_SENSE)? ccb->csio.sense_len : 0));
1116
1117	ISP_GET_PC_ADDR(isp, XS_CHANNEL(ccb), waitq, waitq);
1118	switch (how) {
1119	case FROM_CAM:
1120		/*
1121		 * Insert at the tail of the list, if any, waiting CTIO CCBs
1122		 */
1123		TAILQ_INSERT_TAIL(waitq, &ccb->ccb_h, periph_links.tqe);
1124		break;
1125	case FROM_TIMER:
1126	case FROM_SRR:
1127	case FROM_CTIO_DONE:
1128		TAILQ_INSERT_HEAD(waitq, &ccb->ccb_h, periph_links.tqe);
1129		break;
1130	}
1131
1132	while ((ccb = (union ccb *) TAILQ_FIRST(waitq)) != NULL) {
1133		TAILQ_REMOVE(waitq, &ccb->ccb_h, periph_links.tqe);
1134
1135		cso = &ccb->csio;
1136		xfrlen = cso->dxfer_len;
1137		if (xfrlen == 0) {
1138			if ((ccb->ccb_h.flags & CAM_SEND_STATUS) == 0) {
1139				ISP_PATH_PRT(isp, ISP_LOGERR, ccb->ccb_h.path, "a data transfer length of zero but no status to send is wrong\n");
1140				ccb->ccb_h.status = CAM_REQ_INVALID;
1141				xpt_done(ccb);
1142				continue;
1143			}
1144		}
1145
1146		atp = isp_find_atpd(isp, XS_CHANNEL(ccb), cso->tag_id);
1147		if (atp == NULL) {
1148			isp_prt(isp, ISP_LOGERR, "%s: [0x%x] cannot find private data adjunct in %s", __func__, cso->tag_id, __func__);
1149			isp_dump_atpd(isp, XS_CHANNEL(ccb));
1150			ccb->ccb_h.status = CAM_REQ_CMP_ERR;
1151			xpt_done(ccb);
1152			continue;
1153		}
1154
1155		/*
1156		 * Is this command a dead duck?
1157		 */
1158		if (atp->dead) {
1159			isp_prt(isp, ISP_LOGERR, "%s: [0x%x] not sending a CTIO for a dead command", __func__, cso->tag_id);
1160			ccb->ccb_h.status = CAM_REQ_ABORTED;
1161			xpt_done(ccb);
1162			continue;
1163		}
1164
1165		/*
1166		 * Check to make sure we're still in target mode.
1167		 */
1168		fcp = FCPARAM(isp, XS_CHANNEL(ccb));
1169		if ((fcp->role & ISP_ROLE_TARGET) == 0) {
1170			isp_prt(isp, ISP_LOGERR, "%s: [0x%x] stopping sending a CTIO because we're no longer in target mode", __func__, cso->tag_id);
1171			ccb->ccb_h.status = CAM_PROVIDE_FAIL;
1172			xpt_done(ccb);
1173			continue;
1174		}
1175
1176		/*
1177		 * We're only handling ATPD_CCB_OUTSTANDING outstanding CCB at a time (one of which
1178		 * could be split into two CTIOs to split data and status).
1179		 */
1180		if (atp->ctcnt >= ATPD_CCB_OUTSTANDING) {
1181			isp_prt(isp, ISP_LOGTINFO, "[0x%x] handling only %d CCBs at a time (flags for this ccb: 0x%x)", cso->tag_id, ATPD_CCB_OUTSTANDING, ccb->ccb_h.flags);
1182			TAILQ_INSERT_HEAD(waitq, &ccb->ccb_h, periph_links.tqe);
1183			break;
1184		}
1185
1186		/*
1187		 * Does the initiator expect FC-Tape style responses?
1188		 */
1189		if ((atp->word3 & PRLI_WD3_RETRY) && fcp->fctape_enabled) {
1190			fctape = 1;
1191		} else {
1192			fctape = 0;
1193		}
1194
1195		/*
1196		 * If we already did the data xfer portion of a CTIO that sends data
1197		 * and status, don't do it again and do the status portion now.
1198		 */
1199		if (atp->sendst) {
1200			isp_prt(isp, ISP_LOGTDEBUG0, "[0x%x] now sending synthesized status orig_dl=%u xfered=%u bit=%u",
1201			    cso->tag_id, atp->orig_datalen, atp->bytes_xfered, atp->bytes_in_transit);
1202			xfrlen = 0;	/* we already did the data transfer */
1203			atp->sendst = 0;
1204		}
1205		if (ccb->ccb_h.flags & CAM_SEND_STATUS) {
1206			sendstatus = 1;
1207		} else {
1208			sendstatus = 0;
1209		}
1210
1211		if (ccb->ccb_h.flags & CAM_SEND_SENSE) {
1212			KASSERT((sendstatus != 0), ("how can you have CAM_SEND_SENSE w/o CAM_SEND_STATUS?"));
1213			/*
1214			 * Sense length is not the entire sense data structure size. Periph
1215			 * drivers don't seem to be setting sense_len to reflect the actual
1216			 * size. We'll peek inside to get the right amount.
1217			 */
1218			sense_length = cso->sense_len;
1219
1220			/*
1221			 * This 'cannot' happen
1222			 */
1223			if (sense_length > (XCMD_SIZE - MIN_FCP_RESPONSE_SIZE)) {
1224				sense_length = XCMD_SIZE - MIN_FCP_RESPONSE_SIZE;
1225			}
1226		} else {
1227			sense_length = 0;
1228		}
1229
1230		memset(local, 0, QENTRY_LEN);
1231
1232		/*
1233		 * Check for overflow
1234		 */
1235		tmp = atp->bytes_xfered + atp->bytes_in_transit;
1236		if (xfrlen > 0 && tmp > atp->orig_datalen) {
1237			isp_prt(isp, ISP_LOGERR,
1238			    "%s: [0x%x] data overflow by %u bytes", __func__,
1239			    cso->tag_id, tmp + xfrlen - atp->orig_datalen);
1240			ccb->ccb_h.status = CAM_DATA_RUN_ERR;
1241			xpt_done(ccb);
1242			continue;
1243		}
1244		if (xfrlen > atp->orig_datalen - tmp) {
1245			xfrlen = atp->orig_datalen - tmp;
1246			if (xfrlen == 0 && !sendstatus) {
1247				cso->resid = cso->dxfer_len;
1248				ccb->ccb_h.status = CAM_REQ_CMP;
1249				xpt_done(ccb);
1250				continue;
1251			}
1252		}
1253
1254		if (IS_24XX(isp)) {
1255			ct7_entry_t *cto = (ct7_entry_t *) local;
1256
1257			cto->ct_header.rqs_entry_type = RQSTYPE_CTIO7;
1258			cto->ct_header.rqs_entry_count = 1;
1259			cto->ct_header.rqs_seqno |= ATPD_SEQ_NOTIFY_CAM;
1260			ATPD_SET_SEQNO(cto, atp);
1261			cto->ct_nphdl = atp->nphdl;
1262			cto->ct_rxid = atp->tag;
1263			cto->ct_iid_lo = atp->sid;
1264			cto->ct_iid_hi = atp->sid >> 16;
1265			cto->ct_oxid = atp->oxid;
1266			cto->ct_vpidx = ISP_GET_VPIDX(isp, XS_CHANNEL(ccb));
1267			cto->ct_timeout = (XS_TIME(ccb) + 999) / 1000;
1268			cto->ct_flags = atp->tattr << CT7_TASK_ATTR_SHIFT;
1269
1270			/*
1271			 * Mode 1, status, no data. Only possible when we are sending status, have
1272			 * no data to transfer, and any sense data can fit into a ct7_entry_t.
1273			 *
1274			 * Mode 2, status, no data. We have to use this in the case that
1275			 * the sense data won't fit into a ct7_entry_t.
1276			 *
1277			 */
1278			if (sendstatus && xfrlen == 0) {
1279				cto->ct_flags |= CT7_SENDSTATUS | CT7_NO_DATA;
1280				resid = atp->orig_datalen - atp->bytes_xfered - atp->bytes_in_transit;
1281				if (sense_length <= MAXRESPLEN_24XX) {
1282					cto->ct_flags |= CT7_FLAG_MODE1;
1283					cto->ct_scsi_status = cso->scsi_status;
1284					if (resid < 0) {
1285						cto->ct_resid = -resid;
1286						cto->ct_scsi_status |= (FCP_RESID_OVERFLOW << 8);
1287					} else if (resid > 0) {
1288						cto->ct_resid = resid;
1289						cto->ct_scsi_status |= (FCP_RESID_UNDERFLOW << 8);
1290					}
1291					if (fctape) {
1292						cto->ct_flags |= CT7_CONFIRM|CT7_EXPLCT_CONF;
1293					}
1294					if (sense_length) {
1295						cto->ct_scsi_status |= (FCP_SNSLEN_VALID << 8);
1296						cto->rsp.m1.ct_resplen = cto->ct_senselen = sense_length;
1297						memcpy(cto->rsp.m1.ct_resp, &cso->sense_data, sense_length);
1298					}
1299				} else {
1300					bus_addr_t addr;
1301					char buf[XCMD_SIZE];
1302					fcp_rsp_iu_t *rp;
1303
1304					if (atp->ests == NULL) {
1305						atp->ests = isp_get_ecmd(isp);
1306						if (atp->ests == NULL) {
1307							TAILQ_INSERT_HEAD(waitq, &ccb->ccb_h, periph_links.tqe);
1308							break;
1309						}
1310					}
1311					memset(buf, 0, sizeof (buf));
1312					rp = (fcp_rsp_iu_t *)buf;
1313					if (fctape) {
1314						cto->ct_flags |= CT7_CONFIRM|CT7_EXPLCT_CONF;
1315						rp->fcp_rsp_bits |= FCP_CONF_REQ;
1316					}
1317					cto->ct_flags |= CT7_FLAG_MODE2;
1318	        			rp->fcp_rsp_scsi_status = cso->scsi_status;
1319					if (resid < 0) {
1320						rp->fcp_rsp_resid = -resid;
1321						rp->fcp_rsp_bits |= FCP_RESID_OVERFLOW;
1322					} else if (resid > 0) {
1323						rp->fcp_rsp_resid = resid;
1324						rp->fcp_rsp_bits |= FCP_RESID_UNDERFLOW;
1325					}
1326					if (sense_length) {
1327	        				rp->fcp_rsp_snslen = sense_length;
1328						cto->ct_senselen = sense_length;
1329						rp->fcp_rsp_bits |= FCP_SNSLEN_VALID;
1330						isp_put_fcp_rsp_iu(isp, rp, atp->ests);
1331						memcpy(((fcp_rsp_iu_t *)atp->ests)->fcp_rsp_extra, &cso->sense_data, sense_length);
1332					} else {
1333						isp_put_fcp_rsp_iu(isp, rp, atp->ests);
1334					}
1335					if (isp->isp_dblev & ISP_LOGTDEBUG1) {
1336						isp_print_bytes(isp, "FCP Response Frame After Swizzling", MIN_FCP_RESPONSE_SIZE + sense_length, atp->ests);
1337					}
1338					addr = isp->isp_osinfo.ecmd_dma;
1339					addr += ((((isp_ecmd_t *)atp->ests) - isp->isp_osinfo.ecmd_base) * XCMD_SIZE);
1340					isp_prt(isp, ISP_LOGTDEBUG0, "%s: ests base %p vaddr %p ecmd_dma %jx addr %jx len %u", __func__, isp->isp_osinfo.ecmd_base, atp->ests,
1341					    (uintmax_t) isp->isp_osinfo.ecmd_dma, (uintmax_t)addr, MIN_FCP_RESPONSE_SIZE + sense_length);
1342					cto->rsp.m2.ct_datalen = MIN_FCP_RESPONSE_SIZE + sense_length;
1343					cto->rsp.m2.ct_fcp_rsp_iudata.ds_base = DMA_LO32(addr);
1344					cto->rsp.m2.ct_fcp_rsp_iudata.ds_basehi = DMA_HI32(addr);
1345					cto->rsp.m2.ct_fcp_rsp_iudata.ds_count = MIN_FCP_RESPONSE_SIZE + sense_length;
1346				}
1347				if (sense_length) {
1348					isp_prt(isp, ISP_LOGTDEBUG0, "%s: CTIO7[0x%x] seq %u nc %d CDB0=%x sstatus=0x%x flags=0x%x resid=%d slen %u sense: %x %x/%x/%x", __func__,
1349					    cto->ct_rxid, ATPD_GET_SEQNO(cto), ATPD_GET_NCAM(cto), atp->cdb0, cto->ct_scsi_status, cto->ct_flags, cto->ct_resid, sense_length,
1350					    cso->sense_data.error_code, cso->sense_data.sense_buf[1], cso->sense_data.sense_buf[11], cso->sense_data.sense_buf[12]);
1351				} else {
1352					isp_prt(isp, ISP_LOGDEBUG0, "%s: CTIO7[0x%x] seq %u nc %d CDB0=%x sstatus=0x%x flags=0x%x resid=%d", __func__,
1353					    cto->ct_rxid, ATPD_GET_SEQNO(cto), ATPD_GET_NCAM(cto), atp->cdb0, cto->ct_scsi_status, cto->ct_flags, cto->ct_resid);
1354				}
1355				atp->state = ATPD_STATE_LAST_CTIO;
1356			}
1357
1358			/*
1359			 * Mode 0 data transfers, *possibly* with status.
1360			 */
1361			if (xfrlen != 0) {
1362				cto->ct_flags |= CT7_FLAG_MODE0;
1363				if ((cso->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) {
1364					cto->ct_flags |= CT7_DATA_IN;
1365				} else {
1366					cto->ct_flags |= CT7_DATA_OUT;
1367				}
1368
1369				cto->rsp.m0.reloff = atp->bytes_xfered + atp->bytes_in_transit;
1370				cto->rsp.m0.ct_xfrlen = xfrlen;
1371
1372#ifdef	DEBUG
1373				if (ISP_FC_PC(isp, XS_CHANNEL(ccb))->inject_lost_data_frame && xfrlen > ISP_FC_PC(isp, XS_CHANNEL(ccb))->inject_lost_data_frame) {
1374					isp_prt(isp, ISP_LOGWARN, "%s: truncating data frame with xfrlen %d to %d", __func__, xfrlen, xfrlen - (xfrlen >> 2));
1375					ISP_FC_PC(isp, XS_CHANNEL(ccb))->inject_lost_data_frame = 0;
1376					cto->rsp.m0.ct_xfrlen -= xfrlen >> 2;
1377				}
1378#endif
1379				if (sendstatus) {
1380					resid = atp->orig_datalen - atp->bytes_xfered - xfrlen;
1381					if (cso->scsi_status == SCSI_STATUS_OK && resid == 0 /* && fctape == 0 */) {
1382						cto->ct_flags |= CT7_SENDSTATUS;
1383						atp->state = ATPD_STATE_LAST_CTIO;
1384						if (fctape) {
1385							cto->ct_flags |= CT7_CONFIRM|CT7_EXPLCT_CONF;
1386						}
1387					} else {
1388						atp->sendst = 1;	/* send status later */
1389						cto->ct_header.rqs_seqno &= ~ATPD_SEQ_NOTIFY_CAM;
1390						atp->state = ATPD_STATE_CTIO;
1391					}
1392				} else {
1393					atp->state = ATPD_STATE_CTIO;
1394				}
1395				isp_prt(isp, ISP_LOGTDEBUG0, "%s: CTIO7[0x%x] seq %u nc %d CDB0=%x sstatus=0x%x flags=0x%x xfrlen=%u off=%u", __func__,
1396				    cto->ct_rxid, ATPD_GET_SEQNO(cto), ATPD_GET_NCAM(cto), atp->cdb0, cto->ct_scsi_status, cto->ct_flags, xfrlen, atp->bytes_xfered);
1397			}
1398		} else {
1399			ct2_entry_t *cto = (ct2_entry_t *) local;
1400
1401			if (isp->isp_osinfo.sixtyfourbit)
1402				cto->ct_header.rqs_entry_type = RQSTYPE_CTIO3;
1403			else
1404				cto->ct_header.rqs_entry_type = RQSTYPE_CTIO2;
1405			cto->ct_header.rqs_entry_count = 1;
1406			cto->ct_header.rqs_seqno |= ATPD_SEQ_NOTIFY_CAM;
1407			ATPD_SET_SEQNO(cto, atp);
1408			if (ISP_CAP_2KLOGIN(isp)) {
1409				((ct2e_entry_t *)cto)->ct_iid = atp->nphdl;
1410			} else {
1411				cto->ct_iid = atp->nphdl;
1412				if (ISP_CAP_SCCFW(isp) == 0) {
1413					cto->ct_lun = ccb->ccb_h.target_lun;
1414				}
1415			}
1416			cto->ct_timeout = (XS_TIME(ccb) + 999) / 1000;
1417			cto->ct_rxid = cso->tag_id;
1418
1419			/*
1420			 * Mode 1, status, no data. Only possible when we are sending status, have
1421			 * no data to transfer, and the sense length can fit in the ct7_entry.
1422			 *
1423			 * Mode 2, status, no data. We have to use this in the case the response
1424			 * length won't fit into a ct2_entry_t.
1425			 *
1426			 * We'll fill out this structure with information as if this were a
1427			 * Mode 1. The hardware layer will create the Mode 2 FCP RSP IU as
1428			 * needed based upon this.
1429			 */
1430			if (sendstatus && xfrlen == 0) {
1431				cto->ct_flags |= CT2_SENDSTATUS | CT2_NO_DATA;
1432				resid = atp->orig_datalen - atp->bytes_xfered - atp->bytes_in_transit;
1433				if (sense_length <= MAXRESPLEN) {
1434					if (resid < 0) {
1435						cto->ct_resid = -resid;
1436					} else if (resid > 0) {
1437						cto->ct_resid = resid;
1438					}
1439					cto->ct_flags |= CT2_FLAG_MODE1;
1440					cto->rsp.m1.ct_scsi_status = cso->scsi_status;
1441					if (resid < 0) {
1442						cto->rsp.m1.ct_scsi_status |= CT2_DATA_OVER;
1443					} else if (resid > 0) {
1444						cto->rsp.m1.ct_scsi_status |= CT2_DATA_UNDER;
1445					}
1446					if (fctape) {
1447						cto->ct_flags |= CT2_CONFIRM;
1448					}
1449					if (sense_length) {
1450						cto->rsp.m1.ct_scsi_status |= CT2_SNSLEN_VALID;
1451						cto->rsp.m1.ct_resplen = cto->rsp.m1.ct_senselen = sense_length;
1452						memcpy(cto->rsp.m1.ct_resp, &cso->sense_data, sense_length);
1453					}
1454				} else {
1455					bus_addr_t addr;
1456					char buf[XCMD_SIZE];
1457					fcp_rsp_iu_t *rp;
1458
1459					if (atp->ests == NULL) {
1460						atp->ests = isp_get_ecmd(isp);
1461						if (atp->ests == NULL) {
1462							TAILQ_INSERT_HEAD(waitq, &ccb->ccb_h, periph_links.tqe);
1463							break;
1464						}
1465					}
1466					memset(buf, 0, sizeof (buf));
1467					rp = (fcp_rsp_iu_t *)buf;
1468					if (fctape) {
1469						cto->ct_flags |= CT2_CONFIRM;
1470						rp->fcp_rsp_bits |= FCP_CONF_REQ;
1471					}
1472					cto->ct_flags |= CT2_FLAG_MODE2;
1473	        			rp->fcp_rsp_scsi_status = cso->scsi_status;
1474					if (resid < 0) {
1475						rp->fcp_rsp_resid = -resid;
1476						rp->fcp_rsp_bits |= FCP_RESID_OVERFLOW;
1477					} else if (resid > 0) {
1478						rp->fcp_rsp_resid = resid;
1479						rp->fcp_rsp_bits |= FCP_RESID_UNDERFLOW;
1480					}
1481					if (sense_length) {
1482	        				rp->fcp_rsp_snslen = sense_length;
1483						rp->fcp_rsp_bits |= FCP_SNSLEN_VALID;
1484						isp_put_fcp_rsp_iu(isp, rp, atp->ests);
1485						memcpy(((fcp_rsp_iu_t *)atp->ests)->fcp_rsp_extra, &cso->sense_data, sense_length);
1486					} else {
1487						isp_put_fcp_rsp_iu(isp, rp, atp->ests);
1488					}
1489					if (isp->isp_dblev & ISP_LOGTDEBUG1) {
1490						isp_print_bytes(isp, "FCP Response Frame After Swizzling", MIN_FCP_RESPONSE_SIZE + sense_length, atp->ests);
1491					}
1492					addr = isp->isp_osinfo.ecmd_dma;
1493					addr += ((((isp_ecmd_t *)atp->ests) - isp->isp_osinfo.ecmd_base) * XCMD_SIZE);
1494					isp_prt(isp, ISP_LOGTDEBUG0, "%s: ests base %p vaddr %p ecmd_dma %jx addr %jx len %u", __func__, isp->isp_osinfo.ecmd_base, atp->ests,
1495					    (uintmax_t) isp->isp_osinfo.ecmd_dma, (uintmax_t)addr, MIN_FCP_RESPONSE_SIZE + sense_length);
1496					cto->rsp.m2.ct_datalen = MIN_FCP_RESPONSE_SIZE + sense_length;
1497					if (cto->ct_header.rqs_entry_type == RQSTYPE_CTIO3) {
1498						cto->rsp.m2.u.ct_fcp_rsp_iudata_64.ds_base = DMA_LO32(addr);
1499						cto->rsp.m2.u.ct_fcp_rsp_iudata_64.ds_basehi = DMA_HI32(addr);
1500						cto->rsp.m2.u.ct_fcp_rsp_iudata_64.ds_count = MIN_FCP_RESPONSE_SIZE + sense_length;
1501					} else {
1502						cto->rsp.m2.u.ct_fcp_rsp_iudata_32.ds_base = DMA_LO32(addr);
1503						cto->rsp.m2.u.ct_fcp_rsp_iudata_32.ds_count = MIN_FCP_RESPONSE_SIZE + sense_length;
1504					}
1505				}
1506				if (sense_length) {
1507					isp_prt(isp, ISP_LOGTDEBUG0, "%s: CTIO2[0x%x] seq %u nc %d CDB0=%x sstatus=0x%x flags=0x%x resid=%d sense: %x %x/%x/%x", __func__,
1508					    cto->ct_rxid, ATPD_GET_SEQNO(cto), ATPD_GET_NCAM(cto), atp->cdb0, cso->scsi_status, cto->ct_flags, cto->ct_resid,
1509					    cso->sense_data.error_code, cso->sense_data.sense_buf[1], cso->sense_data.sense_buf[11], cso->sense_data.sense_buf[12]);
1510				} else {
1511					isp_prt(isp, ISP_LOGTDEBUG0, "%s: CTIO2[0x%x] seq %u nc %d CDB0=%x sstatus=0x%x flags=0x%x resid=%d", __func__, cto->ct_rxid,
1512					    ATPD_GET_SEQNO(cto), ATPD_GET_NCAM(cto), atp->cdb0, cso->scsi_status, cto->ct_flags, cto->ct_resid);
1513				}
1514				atp->state = ATPD_STATE_LAST_CTIO;
1515			}
1516
1517			if (xfrlen != 0) {
1518				cto->ct_flags |= CT2_FLAG_MODE0;
1519				if ((cso->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) {
1520					cto->ct_flags |= CT2_DATA_IN;
1521				} else {
1522					cto->ct_flags |= CT2_DATA_OUT;
1523				}
1524
1525				cto->ct_reloff = atp->bytes_xfered + atp->bytes_in_transit;
1526				cto->rsp.m0.ct_xfrlen = xfrlen;
1527
1528				if (sendstatus) {
1529					resid = atp->orig_datalen - atp->bytes_xfered - xfrlen;
1530					if (cso->scsi_status == SCSI_STATUS_OK && resid == 0 /*&& fctape == 0*/) {
1531						cto->ct_flags |= CT2_SENDSTATUS;
1532						atp->state = ATPD_STATE_LAST_CTIO;
1533						if (fctape) {
1534							cto->ct_flags |= CT2_CONFIRM;
1535						}
1536					} else {
1537						atp->sendst = 1;	/* send status later */
1538						cto->ct_header.rqs_seqno &= ~ATPD_SEQ_NOTIFY_CAM;
1539						atp->state = ATPD_STATE_CTIO;
1540					}
1541				} else {
1542					atp->state = ATPD_STATE_CTIO;
1543				}
1544			}
1545			isp_prt(isp, ISP_LOGTDEBUG0, "%s: CTIO2[%x] seq %u nc %d CDB0=%x scsi status %x flags %x resid %d xfrlen %u offset %u", __func__, cto->ct_rxid,
1546			    ATPD_GET_SEQNO(cto), ATPD_GET_NCAM(cto), atp->cdb0, cso->scsi_status, cto->ct_flags, cto->ct_resid, cso->dxfer_len, atp->bytes_xfered);
1547		}
1548
1549		if (isp_get_pcmd(isp, ccb)) {
1550			ISP_PATH_PRT(isp, ISP_LOGWARN, ccb->ccb_h.path, "out of PCMDs\n");
1551			TAILQ_INSERT_HEAD(waitq, &ccb->ccb_h, periph_links.tqe);
1552			break;
1553		}
1554		handle = isp_allocate_handle(isp, ccb, ISP_HANDLE_TARGET);
1555		if (handle == 0) {
1556			ISP_PATH_PRT(isp, ISP_LOGWARN, ccb->ccb_h.path, "No XFLIST pointers for %s\n", __func__);
1557			TAILQ_INSERT_HEAD(waitq, &ccb->ccb_h, periph_links.tqe);
1558			isp_free_pcmd(isp, ccb);
1559			break;
1560		}
1561		atp->bytes_in_transit += xfrlen;
1562		PISP_PCMD(ccb)->datalen = xfrlen;
1563
1564
1565		/*
1566		 * Call the dma setup routines for this entry (and any subsequent
1567		 * CTIOs) if there's data to move, and then tell the f/w it's got
1568		 * new things to play with. As with isp_start's usage of DMA setup,
1569		 * any swizzling is done in the machine dependent layer. Because
1570		 * of this, we put the request onto the queue area first in native
1571		 * format.
1572		 */
1573
1574		if (IS_24XX(isp)) {
1575			ct7_entry_t *cto = (ct7_entry_t *) local;
1576			cto->ct_syshandle = handle;
1577		} else {
1578			ct2_entry_t *cto = (ct2_entry_t *) local;
1579			cto->ct_syshandle = handle;
1580		}
1581
1582		dmaresult = ISP_DMASETUP(isp, cso, (ispreq_t *) local);
1583		if (dmaresult != CMD_QUEUED) {
1584			isp_destroy_handle(isp, handle);
1585			isp_free_pcmd(isp, ccb);
1586			if (dmaresult == CMD_EAGAIN) {
1587				TAILQ_INSERT_HEAD(waitq, &ccb->ccb_h, periph_links.tqe);
1588				break;
1589			}
1590			ccb->ccb_h.status = CAM_REQ_CMP_ERR;
1591			xpt_done(ccb);
1592			continue;
1593		}
1594		isp->isp_nactive++;
1595		ccb->ccb_h.status = CAM_REQ_INPROG | CAM_SIM_QUEUED;
1596		if (xfrlen) {
1597			ccb->ccb_h.spriv_field0 = atp->bytes_xfered;
1598		} else {
1599			ccb->ccb_h.spriv_field0 = ~0;
1600		}
1601		atp->ctcnt++;
1602		atp->seqno++;
1603	}
1604}
1605
1606static void
1607isp_refire_putback_atio(void *arg)
1608{
1609	union ccb *ccb = arg;
1610
1611	ISP_ASSERT_LOCKED((ispsoftc_t *)XS_ISP(ccb));
1612	isp_target_putback_atio(ccb);
1613}
1614
1615static void
1616isp_refire_notify_ack(void *arg)
1617{
1618	isp_tna_t *tp  = arg;
1619	ispsoftc_t *isp = tp->isp;
1620
1621	ISP_ASSERT_LOCKED(isp);
1622	if (isp_notify_ack(isp, tp->not)) {
1623		callout_schedule(&tp->timer, 5);
1624	} else {
1625		free(tp, M_DEVBUF);
1626	}
1627}
1628
1629
1630static void
1631isp_target_putback_atio(union ccb *ccb)
1632{
1633	ispsoftc_t *isp = XS_ISP(ccb);
1634	struct ccb_scsiio *cso = &ccb->csio;
1635	at2_entry_t local, *at = &local;
1636
1637	ISP_MEMZERO(at, sizeof (at2_entry_t));
1638	at->at_header.rqs_entry_type = RQSTYPE_ATIO2;
1639	at->at_header.rqs_entry_count = 1;
1640	if (ISP_CAP_SCCFW(isp)) {
1641		at->at_scclun = (uint16_t) ccb->ccb_h.target_lun;
1642	} else {
1643		at->at_lun = (uint8_t) ccb->ccb_h.target_lun;
1644	}
1645	at->at_status = CT_OK;
1646	at->at_rxid = cso->tag_id;
1647	at->at_iid = cso->ccb_h.target_id;
1648	if (isp_target_put_entry(isp, at)) {
1649		callout_reset(&PISP_PCMD(ccb)->wdog, 10,
1650		    isp_refire_putback_atio, ccb);
1651	} else
1652		isp_complete_ctio(ccb);
1653}
1654
1655static void
1656isp_complete_ctio(union ccb *ccb)
1657{
1658	if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_INPROG) {
1659		ccb->ccb_h.status &= ~CAM_SIM_QUEUED;
1660		xpt_done(ccb);
1661	}
1662}
1663
1664static void
1665isp_handle_platform_atio2(ispsoftc_t *isp, at2_entry_t *aep)
1666{
1667	fcparam *fcp;
1668	lun_id_t lun;
1669	fcportdb_t *lp;
1670	tstate_t *tptr;
1671	struct ccb_accept_tio *atiop;
1672	uint16_t nphdl;
1673	atio_private_data_t *atp;
1674	inot_private_data_t *ntp;
1675
1676	/*
1677	 * The firmware status (except for the QLTM_SVALID bit)
1678	 * indicates why this ATIO was sent to us.
1679	 *
1680	 * If QLTM_SVALID is set, the firmware has recommended Sense Data.
1681	 */
1682	if ((aep->at_status & ~QLTM_SVALID) != AT_CDB) {
1683		isp_prt(isp, ISP_LOGWARN, "bogus atio (0x%x) leaked to platform", aep->at_status);
1684		isp_endcmd(isp, aep, NIL_HANDLE, 0, SCSI_STATUS_BUSY, 0);
1685		return;
1686	}
1687
1688	fcp = FCPARAM(isp, 0);
1689	if (ISP_CAP_SCCFW(isp)) {
1690		lun = aep->at_scclun;
1691	} else {
1692		lun = aep->at_lun;
1693	}
1694	if (ISP_CAP_2KLOGIN(isp)) {
1695		nphdl = ((at2e_entry_t *)aep)->at_iid;
1696	} else {
1697		nphdl = aep->at_iid;
1698	}
1699	tptr = get_lun_statep(isp, 0, lun);
1700	if (tptr == NULL) {
1701		tptr = get_lun_statep(isp, 0, CAM_LUN_WILDCARD);
1702		if (tptr == NULL) {
1703			isp_prt(isp, ISP_LOGWARN, "%s: [0x%x] no state pointer for lun %d or wildcard", __func__, aep->at_rxid, lun);
1704			if (lun == 0) {
1705				isp_endcmd(isp, aep, nphdl, 0, SCSI_STATUS_BUSY, 0);
1706			} else {
1707				isp_endcmd(isp, aep, nphdl, 0, SCSI_STATUS_CHECK_COND | ECMD_SVALID | (0x5 << 12) | (0x25 << 16), 0);
1708			}
1709			return;
1710		}
1711	}
1712
1713	/*
1714	 * Start any commands pending resources first.
1715	 */
1716	if (isp_atio_restart(isp, 0, tptr))
1717		goto noresrc;
1718
1719	atiop = (struct ccb_accept_tio *) SLIST_FIRST(&tptr->atios);
1720	if (atiop == NULL) {
1721		goto noresrc;
1722	}
1723
1724	atp = isp_get_atpd(isp, 0, aep->at_rxid);
1725	if (atp == NULL) {
1726		goto noresrc;
1727	}
1728
1729	atp->state = ATPD_STATE_ATIO;
1730	SLIST_REMOVE_HEAD(&tptr->atios, sim_links.sle);
1731	ISP_PATH_PRT(isp, ISP_LOGTDEBUG2, atiop->ccb_h.path, "Take FREE ATIO\n");
1732	atiop->ccb_h.target_id = fcp->isp_loopid;
1733	atiop->ccb_h.target_lun = lun;
1734
1735	/*
1736	 * We don't get 'suggested' sense data as we do with SCSI cards.
1737	 */
1738	atiop->sense_len = 0;
1739
1740	/*
1741	 * If we're not in the port database, add ourselves.
1742	 */
1743	if (IS_2100(isp))
1744		atiop->init_id = nphdl;
1745	else {
1746		if (isp_find_pdb_by_handle(isp, 0, nphdl, &lp)) {
1747			atiop->init_id = FC_PORTDB_TGT(isp, 0, lp);
1748		} else {
1749			isp_prt(isp, ISP_LOGTINFO, "%s: port %x isn't in PDB",
1750			    __func__, nphdl);
1751			isp_dump_portdb(isp, 0);
1752			isp_endcmd(isp, aep, NIL_HANDLE, 0, ECMD_TERMINATE, 0);
1753			return;
1754		}
1755	}
1756	atiop->cdb_len = ATIO2_CDBLEN;
1757	ISP_MEMCPY(atiop->cdb_io.cdb_bytes, aep->at_cdb, ATIO2_CDBLEN);
1758	atiop->ccb_h.status = CAM_CDB_RECVD;
1759	atiop->tag_id = atp->tag;
1760	switch (aep->at_taskflags & ATIO2_TC_ATTR_MASK) {
1761	case ATIO2_TC_ATTR_SIMPLEQ:
1762		atiop->ccb_h.flags |= CAM_TAG_ACTION_VALID;
1763		atiop->tag_action = MSG_SIMPLE_Q_TAG;
1764		break;
1765	case ATIO2_TC_ATTR_HEADOFQ:
1766		atiop->ccb_h.flags |= CAM_TAG_ACTION_VALID;
1767		atiop->tag_action = MSG_HEAD_OF_Q_TAG;
1768		break;
1769	case ATIO2_TC_ATTR_ORDERED:
1770		atiop->ccb_h.flags |= CAM_TAG_ACTION_VALID;
1771		atiop->tag_action = MSG_ORDERED_Q_TAG;
1772		break;
1773	case ATIO2_TC_ATTR_ACAQ:		/* ?? */
1774	case ATIO2_TC_ATTR_UNTAGGED:
1775	default:
1776		atiop->tag_action = 0;
1777		break;
1778	}
1779
1780	atp->orig_datalen = aep->at_datalen;
1781	atp->bytes_xfered = 0;
1782	atp->lun = lun;
1783	atp->nphdl = nphdl;
1784	atp->sid = PORT_ANY;
1785	atp->oxid = aep->at_oxid;
1786	atp->cdb0 = aep->at_cdb[0];
1787	atp->tattr = aep->at_taskflags & ATIO2_TC_ATTR_MASK;
1788	atp->state = ATPD_STATE_CAM;
1789	xpt_done((union ccb *)atiop);
1790	isp_prt(isp, ISP_LOGTDEBUG0, "ATIO2[0x%x] CDB=0x%x lun %d datalen %u", aep->at_rxid, atp->cdb0, lun, atp->orig_datalen);
1791	return;
1792noresrc:
1793	ntp = isp_get_ntpd(isp, 0);
1794	if (ntp == NULL) {
1795		isp_endcmd(isp, aep, nphdl, 0, SCSI_STATUS_BUSY, 0);
1796		return;
1797	}
1798	memcpy(ntp->data, aep, QENTRY_LEN);
1799	STAILQ_INSERT_TAIL(&tptr->restart_queue, ntp, next);
1800}
1801
1802static void
1803isp_handle_platform_atio7(ispsoftc_t *isp, at7_entry_t *aep)
1804{
1805	int cdbxlen;
1806	lun_id_t lun;
1807	uint16_t chan, nphdl = NIL_HANDLE;
1808	uint32_t did, sid;
1809	fcportdb_t *lp;
1810	tstate_t *tptr;
1811	struct ccb_accept_tio *atiop;
1812	atio_private_data_t *atp = NULL;
1813	atio_private_data_t *oatp;
1814	inot_private_data_t *ntp;
1815
1816	did = (aep->at_hdr.d_id[0] << 16) | (aep->at_hdr.d_id[1] << 8) | aep->at_hdr.d_id[2];
1817	sid = (aep->at_hdr.s_id[0] << 16) | (aep->at_hdr.s_id[1] << 8) | aep->at_hdr.s_id[2];
1818	lun = CAM_EXTLUN_BYTE_SWIZZLE(be64dec(aep->at_cmnd.fcp_cmnd_lun));
1819
1820	if (ISP_CAP_MULTI_ID(isp) && isp->isp_nchan > 1) {
1821		/* Channel has to be derived from D_ID */
1822		isp_find_chan_by_did(isp, did, &chan);
1823		if (chan == ISP_NOCHAN) {
1824			isp_prt(isp, ISP_LOGWARN,
1825			    "%s: [RX_ID 0x%x] D_ID %x not found on any channel",
1826			    __func__, aep->at_rxid, did);
1827			isp_endcmd(isp, aep, NIL_HANDLE, ISP_NOCHAN,
1828			    ECMD_TERMINATE, 0);
1829			return;
1830		}
1831	} else {
1832		chan = 0;
1833	}
1834
1835	/*
1836	 * Find the PDB entry for this initiator
1837	 */
1838	if (isp_find_pdb_by_portid(isp, chan, sid, &lp) == 0) {
1839		/*
1840		 * If we're not in the port database terminate the exchange.
1841		 */
1842		isp_prt(isp, ISP_LOGTINFO, "%s: [RX_ID 0x%x] D_ID 0x%06x found on Chan %d for S_ID 0x%06x wasn't in PDB already",
1843		    __func__, aep->at_rxid, did, chan, sid);
1844		isp_dump_portdb(isp, chan);
1845		isp_endcmd(isp, aep, NIL_HANDLE, chan, ECMD_TERMINATE, 0);
1846		return;
1847	}
1848	nphdl = lp->handle;
1849
1850	/*
1851	 * Get the tstate pointer
1852	 */
1853	tptr = get_lun_statep(isp, chan, lun);
1854	if (tptr == NULL) {
1855		tptr = get_lun_statep(isp, chan, CAM_LUN_WILDCARD);
1856		if (tptr == NULL) {
1857			isp_prt(isp, ISP_LOGWARN,
1858			    "%s: [0x%x] no state pointer for lun %jx or wildcard",
1859			    __func__, aep->at_rxid, (uintmax_t)lun);
1860			if (lun == 0) {
1861				isp_endcmd(isp, aep, nphdl, chan, SCSI_STATUS_BUSY, 0);
1862			} else {
1863				isp_endcmd(isp, aep, nphdl, chan, SCSI_STATUS_CHECK_COND | ECMD_SVALID | (0x5 << 12) | (0x25 << 16), 0);
1864			}
1865			return;
1866		}
1867	}
1868
1869	/*
1870	 * Start any commands pending resources first.
1871	 */
1872	if (isp_atio_restart(isp, chan, tptr))
1873		goto noresrc;
1874
1875	/*
1876	 * If the f/w is out of resources, just send a BUSY status back.
1877	 */
1878	if (aep->at_rxid == AT7_NORESRC_RXID) {
1879		isp_endcmd(isp, aep, nphdl, chan, SCSI_BUSY, 0);
1880		return;
1881	}
1882
1883	/*
1884	 * If we're out of resources, just send a BUSY status back.
1885	 */
1886	atiop = (struct ccb_accept_tio *) SLIST_FIRST(&tptr->atios);
1887	if (atiop == NULL) {
1888		isp_prt(isp, ISP_LOGTDEBUG0, "[0x%x] out of atios", aep->at_rxid);
1889		goto noresrc;
1890	}
1891
1892	oatp = isp_find_atpd(isp, chan, aep->at_rxid);
1893	if (oatp) {
1894		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",
1895		    aep->at_rxid, nphdl, sid, aep->at_hdr.ox_id, oatp->state);
1896		/*
1897		 * It's not a "no resource" condition- but we can treat it like one
1898		 */
1899		goto noresrc;
1900	}
1901	atp = isp_get_atpd(isp, chan, aep->at_rxid);
1902	if (atp == NULL) {
1903		isp_prt(isp, ISP_LOGTDEBUG0, "[0x%x] out of atps", aep->at_rxid);
1904		goto noresrc;
1905	}
1906	atp->word3 = lp->prli_word3;
1907	atp->state = ATPD_STATE_ATIO;
1908	SLIST_REMOVE_HEAD(&tptr->atios, sim_links.sle);
1909	ISP_PATH_PRT(isp, ISP_LOGTDEBUG2, atiop->ccb_h.path, "Take FREE ATIO\n");
1910	atiop->init_id = FC_PORTDB_TGT(isp, chan, lp);
1911	atiop->ccb_h.target_id = FCPARAM(isp, chan)->isp_loopid;
1912	atiop->ccb_h.target_lun = lun;
1913	atiop->sense_len = 0;
1914	cdbxlen = aep->at_cmnd.fcp_cmnd_alen_datadir >> FCP_CMND_ADDTL_CDBLEN_SHIFT;
1915	if (cdbxlen) {
1916		isp_prt(isp, ISP_LOGWARN, "additional CDBLEN ignored");
1917	}
1918	cdbxlen = sizeof (aep->at_cmnd.cdb_dl.sf.fcp_cmnd_cdb);
1919	ISP_MEMCPY(atiop->cdb_io.cdb_bytes, aep->at_cmnd.cdb_dl.sf.fcp_cmnd_cdb, cdbxlen);
1920	atiop->cdb_len = cdbxlen;
1921	atiop->ccb_h.status = CAM_CDB_RECVD;
1922	atiop->tag_id = atp->tag;
1923	switch (aep->at_cmnd.fcp_cmnd_task_attribute & FCP_CMND_TASK_ATTR_MASK) {
1924	case FCP_CMND_TASK_ATTR_SIMPLE:
1925		atiop->ccb_h.flags |= CAM_TAG_ACTION_VALID;
1926		atiop->tag_action = MSG_SIMPLE_Q_TAG;
1927		break;
1928	case FCP_CMND_TASK_ATTR_HEAD:
1929		atiop->ccb_h.flags |= CAM_TAG_ACTION_VALID;
1930		atiop->tag_action = MSG_HEAD_OF_Q_TAG;
1931		break;
1932	case FCP_CMND_TASK_ATTR_ORDERED:
1933		atiop->ccb_h.flags |= CAM_TAG_ACTION_VALID;
1934		atiop->tag_action = MSG_ORDERED_Q_TAG;
1935		break;
1936	default:
1937		/* FALLTHROUGH */
1938	case FCP_CMND_TASK_ATTR_ACA:
1939	case FCP_CMND_TASK_ATTR_UNTAGGED:
1940		atiop->tag_action = 0;
1941		break;
1942	}
1943	atp->orig_datalen = aep->at_cmnd.cdb_dl.sf.fcp_cmnd_dl;
1944	atp->bytes_xfered = 0;
1945	atp->lun = lun;
1946	atp->nphdl = nphdl;
1947	atp->sid = sid;
1948	atp->did = did;
1949	atp->oxid = aep->at_hdr.ox_id;
1950	atp->rxid = aep->at_hdr.rx_id;
1951	atp->cdb0 = atiop->cdb_io.cdb_bytes[0];
1952	atp->tattr = aep->at_cmnd.fcp_cmnd_task_attribute & FCP_CMND_TASK_ATTR_MASK;
1953	atp->state = ATPD_STATE_CAM;
1954	isp_prt(isp, ISP_LOGTDEBUG0, "ATIO7[0x%x] CDB=0x%x lun %jx datalen %u",
1955	    aep->at_rxid, atp->cdb0, (uintmax_t)lun, atp->orig_datalen);
1956	xpt_done((union ccb *)atiop);
1957	return;
1958noresrc:
1959	if (atp)
1960		isp_put_atpd(isp, chan, atp);
1961	ntp = isp_get_ntpd(isp, chan);
1962	if (ntp == NULL) {
1963		isp_endcmd(isp, aep, nphdl, chan, SCSI_STATUS_BUSY, 0);
1964		return;
1965	}
1966	memcpy(ntp->data, aep, QENTRY_LEN);
1967	STAILQ_INSERT_TAIL(&tptr->restart_queue, ntp, next);
1968}
1969
1970
1971/*
1972 * Handle starting an SRR (sequence retransmit request)
1973 * We get here when we've gotten the immediate notify
1974 * and the return of all outstanding CTIOs for this
1975 * transaction.
1976 */
1977static void
1978isp_handle_srr_start(ispsoftc_t *isp, atio_private_data_t *atp)
1979{
1980	in_fcentry_24xx_t *inot;
1981	uint32_t srr_off, ccb_off, ccb_len, ccb_end;
1982	union ccb *ccb;
1983
1984	inot = (in_fcentry_24xx_t *)atp->srr;
1985	srr_off = inot->in_srr_reloff_lo | (inot->in_srr_reloff_hi << 16);
1986	ccb = atp->srr_ccb;
1987	atp->srr_ccb = NULL;
1988	atp->nsrr++;
1989	if (ccb == NULL) {
1990		isp_prt(isp, ISP_LOGWARN, "SRR[0x%x] null ccb", atp->tag);
1991		goto fail;
1992	}
1993
1994	ccb_off = ccb->ccb_h.spriv_field0;
1995	ccb_len = ccb->csio.dxfer_len;
1996        ccb_end = (ccb_off == ~0)? ~0 : ccb_off + ccb_len;
1997
1998	switch (inot->in_srr_iu) {
1999	case R_CTL_INFO_SOLICITED_DATA:
2000		/*
2001		 * We have to restart a FCP_DATA data out transaction
2002		 */
2003		atp->sendst = 0;
2004		atp->bytes_xfered = srr_off;
2005		if (ccb_len == 0) {
2006			isp_prt(isp, ISP_LOGWARN, "SRR[0x%x] SRR offset 0x%x but current CCB doesn't transfer data", atp->tag, srr_off);
2007			goto mdp;
2008		}
2009 		if (srr_off < ccb_off || ccb_off > srr_off + ccb_len) {
2010			isp_prt(isp, ISP_LOGWARN, "SRR[0x%x] SRR offset 0x%x not covered by current CCB data range [0x%x..0x%x]", atp->tag, srr_off, ccb_off, ccb_end);
2011			goto mdp;
2012		}
2013		isp_prt(isp, ISP_LOGWARN, "SRR[0x%x] SRR offset 0x%x covered by current CCB data range [0x%x..0x%x]", atp->tag, srr_off, ccb_off, ccb_end);
2014		break;
2015	case R_CTL_INFO_COMMAND_STATUS:
2016		isp_prt(isp, ISP_LOGTINFO, "SRR[0x%x] Got an FCP RSP SRR- resending status", atp->tag);
2017		atp->sendst = 1;
2018		/*
2019		 * We have to restart a FCP_RSP IU transaction
2020		 */
2021		break;
2022	case R_CTL_INFO_DATA_DESCRIPTOR:
2023		/*
2024		 * We have to restart an FCP DATA in transaction
2025		 */
2026		isp_prt(isp, ISP_LOGWARN, "Got an FCP DATA IN SRR- dropping");
2027		goto fail;
2028
2029	default:
2030		isp_prt(isp, ISP_LOGWARN, "Got an unknown information (%x) SRR- dropping", inot->in_srr_iu);
2031		goto fail;
2032	}
2033
2034	/*
2035	 * We can't do anything until this is acked, so we might as well start it now.
2036	 * We aren't going to do the usual asynchronous ack issue because we need
2037	 * to make sure this gets on the wire first.
2038	 */
2039	if (isp_notify_ack(isp, inot)) {
2040		isp_prt(isp, ISP_LOGWARN, "could not push positive ack for SRR- you lose");
2041		goto fail;
2042	}
2043	isp_target_start_ctio(isp, ccb, FROM_SRR);
2044	return;
2045fail:
2046	inot->in_reserved = 1;
2047	isp_async(isp, ISPASYNC_TARGET_NOTIFY_ACK, inot);
2048	ccb->ccb_h.status &= ~CAM_STATUS_MASK;
2049	ccb->ccb_h.status |= CAM_REQ_CMP_ERR;
2050	isp_complete_ctio(ccb);
2051	return;
2052mdp:
2053	if (isp_notify_ack(isp, inot)) {
2054		isp_prt(isp, ISP_LOGWARN, "could not push positive ack for SRR- you lose");
2055		goto fail;
2056	}
2057	ccb->ccb_h.status &= ~CAM_STATUS_MASK;
2058	ccb->ccb_h.status = CAM_MESSAGE_RECV;
2059	/*
2060	 * This is not a strict interpretation of MDP, but it's close
2061	 */
2062	ccb->csio.msg_ptr = &ccb->csio.sense_data.sense_buf[SSD_FULL_SIZE - 16];
2063	ccb->csio.msg_len = 7;
2064	ccb->csio.msg_ptr[0] = MSG_EXTENDED;
2065	ccb->csio.msg_ptr[1] = 5;
2066	ccb->csio.msg_ptr[2] = 0;	/* modify data pointer */
2067	ccb->csio.msg_ptr[3] = srr_off >> 24;
2068	ccb->csio.msg_ptr[4] = srr_off >> 16;
2069	ccb->csio.msg_ptr[5] = srr_off >> 8;
2070	ccb->csio.msg_ptr[6] = srr_off;
2071	isp_complete_ctio(ccb);
2072}
2073
2074
2075static void
2076isp_handle_platform_srr(ispsoftc_t *isp, isp_notify_t *notify)
2077{
2078	in_fcentry_24xx_t *inot = notify->nt_lreserved;
2079	atio_private_data_t *atp;
2080	uint32_t tag = notify->nt_tagval & 0xffffffff;
2081
2082	atp = isp_find_atpd(isp, notify->nt_channel, tag);
2083	if (atp == NULL) {
2084		isp_prt(isp, ISP_LOGERR, "%s: cannot find adjunct for %x in SRR Notify",
2085		    __func__, tag);
2086		isp_async(isp, ISPASYNC_TARGET_NOTIFY_ACK, inot);
2087		return;
2088	}
2089	atp->srr_notify_rcvd = 1;
2090	memcpy(atp->srr, inot, sizeof (atp->srr));
2091	isp_prt(isp, ISP_LOGTINFO, "SRR[0x%x] flags 0x%x srr_iu %x reloff 0x%x",
2092	    inot->in_rxid, inot->in_flags, inot->in_srr_iu,
2093	    ((uint32_t)inot->in_srr_reloff_hi << 16) | inot->in_srr_reloff_lo);
2094	if (atp->srr_ccb)
2095		isp_handle_srr_start(isp, atp);
2096}
2097
2098static void
2099isp_handle_platform_ctio(ispsoftc_t *isp, void *arg)
2100{
2101	union ccb *ccb;
2102	int sentstatus = 0, ok = 0, notify_cam = 0, failure = 0;
2103	atio_private_data_t *atp = NULL;
2104	int bus;
2105	uint32_t handle, data_requested, resid;
2106
2107	handle = ((ct2_entry_t *)arg)->ct_syshandle;
2108	ccb = isp_find_xs(isp, handle);
2109	if (ccb == NULL) {
2110		isp_print_bytes(isp, "null ccb in isp_handle_platform_ctio", QENTRY_LEN, arg);
2111		return;
2112	}
2113	isp_destroy_handle(isp, handle);
2114	resid = data_requested = PISP_PCMD(ccb)->datalen;
2115	isp_free_pcmd(isp, ccb);
2116	if (isp->isp_nactive) {
2117		isp->isp_nactive--;
2118	}
2119
2120	bus = XS_CHANNEL(ccb);
2121	if (IS_24XX(isp)) {
2122		atp = isp_find_atpd(isp, bus, ((ct7_entry_t *)arg)->ct_rxid);
2123	} else {
2124		atp = isp_find_atpd(isp, bus, ((ct2_entry_t *)arg)->ct_rxid);
2125	}
2126	if (atp == NULL) {
2127		/*
2128		 * XXX: isp_clear_commands() generates fake CTIO with zero
2129		 * ct_rxid value, filling only ct_syshandle.  Workaround
2130		 * that using tag_id from the CCB, pointed by ct_syshandle.
2131		 */
2132		atp = isp_find_atpd(isp, bus, ccb->csio.tag_id);
2133	}
2134	if (atp == NULL) {
2135		isp_prt(isp, ISP_LOGERR, "%s: cannot find adjunct for %x after I/O", __func__, ccb->csio.tag_id);
2136		return;
2137	}
2138	KASSERT((atp->ctcnt > 0), ("ctio count not greater than zero"));
2139	atp->bytes_in_transit -= data_requested;
2140	atp->ctcnt -= 1;
2141	ccb->ccb_h.status &= ~CAM_STATUS_MASK;
2142
2143	if (IS_24XX(isp)) {
2144		ct7_entry_t *ct = arg;
2145
2146		if (ct->ct_nphdl == CT7_SRR) {
2147			atp->srr_ccb = ccb;
2148			if (atp->srr_notify_rcvd)
2149				isp_handle_srr_start(isp, atp);
2150			return;
2151		}
2152		if (ct->ct_nphdl == CT_HBA_RESET) {
2153			sentstatus = (ccb->ccb_h.flags & CAM_SEND_STATUS) &&
2154			    (atp->sendst == 0);
2155			failure = CAM_UNREC_HBA_ERROR;
2156		} else {
2157			sentstatus = ct->ct_flags & CT7_SENDSTATUS;
2158			ok = (ct->ct_nphdl == CT7_OK);
2159			notify_cam = (ct->ct_header.rqs_seqno & ATPD_SEQ_NOTIFY_CAM) != 0;
2160			if ((ct->ct_flags & CT7_DATAMASK) != CT7_NO_DATA)
2161				resid = ct->ct_resid;
2162		}
2163		isp_prt(isp, ok? ISP_LOGTDEBUG0 : ISP_LOGWARN, "%s: CTIO7[%x] seq %u nc %d sts 0x%x flg 0x%x sns %d resid %d %s", __func__, ct->ct_rxid, ATPD_GET_SEQNO(ct),
2164		   notify_cam, ct->ct_nphdl, ct->ct_flags, (ccb->ccb_h.status & CAM_SENT_SENSE) != 0, resid, sentstatus? "FIN" : "MID");
2165	} else {
2166		ct2_entry_t *ct = arg;
2167		if (ct->ct_status == CT_SRR) {
2168			atp->srr_ccb = ccb;
2169			if (atp->srr_notify_rcvd)
2170				isp_handle_srr_start(isp, atp);
2171			isp_target_putback_atio(ccb);
2172			return;
2173		}
2174		if (ct->ct_status == CT_HBA_RESET) {
2175			sentstatus = (ccb->ccb_h.flags & CAM_SEND_STATUS) &&
2176			    (atp->sendst == 0);
2177			failure = CAM_UNREC_HBA_ERROR;
2178		} else {
2179			sentstatus = ct->ct_flags & CT2_SENDSTATUS;
2180			ok = (ct->ct_status & ~QLTM_SVALID) == CT_OK;
2181			notify_cam = (ct->ct_header.rqs_seqno & ATPD_SEQ_NOTIFY_CAM) != 0;
2182			if ((ct->ct_flags & CT2_DATAMASK) != CT2_NO_DATA)
2183				resid = ct->ct_resid;
2184		}
2185		isp_prt(isp, ok? ISP_LOGTDEBUG0 : ISP_LOGWARN, "%s: CTIO2[%x] seq %u nc %d sts 0x%x flg 0x%x sns %d resid %d %s", __func__, ct->ct_rxid, ATPD_GET_SEQNO(ct),
2186		    notify_cam, ct->ct_status, ct->ct_flags, (ccb->ccb_h.status & CAM_SENT_SENSE) != 0, resid, sentstatus? "FIN" : "MID");
2187	}
2188	if (ok) {
2189		if (data_requested > 0) {
2190			atp->bytes_xfered += data_requested - resid;
2191			ccb->csio.resid = ccb->csio.dxfer_len -
2192			    (data_requested - resid);
2193		}
2194		if (sentstatus && (ccb->ccb_h.flags & CAM_SEND_SENSE))
2195			ccb->ccb_h.status |= CAM_SENT_SENSE;
2196		ccb->ccb_h.status |= CAM_REQ_CMP;
2197	} else {
2198		notify_cam = 1;
2199		if (failure == CAM_UNREC_HBA_ERROR)
2200			ccb->ccb_h.status |= CAM_UNREC_HBA_ERROR;
2201		else
2202			ccb->ccb_h.status |= CAM_REQ_CMP_ERR;
2203	}
2204	atp->state = ATPD_STATE_PDON;
2205
2206	/*
2207	 * We never *not* notify CAM when there has been any error (ok == 0),
2208	 * so we never need to do an ATIO putback if we're not notifying CAM.
2209	 */
2210	isp_prt(isp, ISP_LOGTDEBUG0, "%s CTIO[0x%x] done (ok=%d nc=%d nowsendstatus=%d ccb ss=%d)",
2211	    (sentstatus)? "  FINAL " : "MIDTERM ", atp->tag, ok, notify_cam, atp->sendst, (ccb->ccb_h.flags & CAM_SEND_STATUS) != 0);
2212	if (notify_cam == 0) {
2213		if (atp->sendst) {
2214			isp_target_start_ctio(isp, ccb, FROM_CTIO_DONE);
2215		}
2216		return;
2217	}
2218
2219	/*
2220	 * We are done with this ATIO if we successfully sent status.
2221	 * In all other cases expect either another CTIO or XPT_ABORT.
2222	 */
2223	if (ok && sentstatus)
2224		isp_put_atpd(isp, bus, atp);
2225
2226	/*
2227	 * We're telling CAM we're done with this CTIO transaction.
2228	 *
2229	 * 24XX cards never need an ATIO put back.
2230	 *
2231	 * Other cards need one put back only on error.
2232	 * In the latter case, a timeout will re-fire
2233	 * and try again in case we didn't have
2234	 * queue resources to do so at first. In any case,
2235	 * once the putback is done we do the completion
2236	 * call.
2237	 */
2238	if (ok || IS_24XX(isp)) {
2239		isp_complete_ctio(ccb);
2240	} else {
2241		isp_target_putback_atio(ccb);
2242	}
2243}
2244
2245static int
2246isp_handle_platform_target_notify_ack(ispsoftc_t *isp, isp_notify_t *mp, uint32_t rsp)
2247{
2248
2249	if (isp->isp_state != ISP_RUNSTATE) {
2250		isp_prt(isp, ISP_LOGTINFO, "Notify Code 0x%x (qevalid=%d) acked- h/w not ready (dropping)", mp->nt_ncode, mp->nt_lreserved != NULL);
2251		return (0);
2252	}
2253
2254	/*
2255	 * This case is for a Task Management Function, which shows up as an ATIO7 entry.
2256	 */
2257	if (IS_24XX(isp) && mp->nt_lreserved && ((isphdr_t *)mp->nt_lreserved)->rqs_entry_type == RQSTYPE_ATIO) {
2258		ct7_entry_t local, *cto = &local;
2259		at7_entry_t *aep = (at7_entry_t *)mp->nt_lreserved;
2260		fcportdb_t *lp;
2261		uint32_t sid;
2262		uint16_t nphdl;
2263
2264		sid = (aep->at_hdr.s_id[0] << 16) | (aep->at_hdr.s_id[1] << 8) | aep->at_hdr.s_id[2];
2265		if (isp_find_pdb_by_portid(isp, mp->nt_channel, sid, &lp)) {
2266			nphdl = lp->handle;
2267		} else {
2268			nphdl = NIL_HANDLE;
2269		}
2270		ISP_MEMZERO(&local, sizeof (local));
2271		cto->ct_header.rqs_entry_type = RQSTYPE_CTIO7;
2272		cto->ct_header.rqs_entry_count = 1;
2273		cto->ct_nphdl = nphdl;
2274		cto->ct_rxid = aep->at_rxid;
2275		cto->ct_vpidx = mp->nt_channel;
2276		cto->ct_iid_lo = sid;
2277		cto->ct_iid_hi = sid >> 16;
2278		cto->ct_oxid = aep->at_hdr.ox_id;
2279		cto->ct_flags = CT7_SENDSTATUS|CT7_NOACK|CT7_NO_DATA|CT7_FLAG_MODE1;
2280		cto->ct_flags |= (aep->at_ta_len >> 12) << CT7_TASK_ATTR_SHIFT;
2281		if (rsp != 0) {
2282			cto->ct_scsi_status |= (FCP_RSPLEN_VALID << 8);
2283			cto->rsp.m1.ct_resplen = 4;
2284			ISP_MEMZERO(cto->rsp.m1.ct_resp, sizeof (cto->rsp.m1.ct_resp));
2285			cto->rsp.m1.ct_resp[0] = rsp & 0xff;
2286			cto->rsp.m1.ct_resp[1] = (rsp >> 8) & 0xff;
2287			cto->rsp.m1.ct_resp[2] = (rsp >> 16) & 0xff;
2288			cto->rsp.m1.ct_resp[3] = (rsp >> 24) & 0xff;
2289		}
2290		return (isp_target_put_entry(isp, &local));
2291	}
2292
2293	/*
2294	 * This case is for a responding to an ABTS frame
2295	 */
2296	if (IS_24XX(isp) && mp->nt_lreserved && ((isphdr_t *)mp->nt_lreserved)->rqs_entry_type == RQSTYPE_ABTS_RCVD) {
2297
2298		/*
2299		 * Overload nt_need_ack here to mark whether we've terminated the associated command.
2300		 */
2301		if (mp->nt_need_ack) {
2302			uint8_t storage[QENTRY_LEN];
2303			ct7_entry_t *cto = (ct7_entry_t *) storage;
2304			abts_t *abts = (abts_t *)mp->nt_lreserved;
2305
2306			ISP_MEMZERO(cto, sizeof (ct7_entry_t));
2307			isp_prt(isp, ISP_LOGTDEBUG0, "%s: [%x] terminating after ABTS received", __func__, abts->abts_rxid_task);
2308			cto->ct_header.rqs_entry_type = RQSTYPE_CTIO7;
2309			cto->ct_header.rqs_entry_count = 1;
2310			cto->ct_nphdl = mp->nt_nphdl;
2311			cto->ct_rxid = abts->abts_rxid_task;
2312			cto->ct_iid_lo = mp->nt_sid;
2313			cto->ct_iid_hi = mp->nt_sid >> 16;
2314			cto->ct_oxid = abts->abts_ox_id;
2315			cto->ct_vpidx = mp->nt_channel;
2316			cto->ct_flags = CT7_NOACK|CT7_TERMINATE;
2317			if (isp_target_put_entry(isp, cto)) {
2318				return (ENOMEM);
2319			}
2320			mp->nt_need_ack = 0;
2321		}
2322		if (isp_acknak_abts(isp, mp->nt_lreserved, 0) == ENOMEM) {
2323			return (ENOMEM);
2324		} else {
2325			return (0);
2326		}
2327	}
2328
2329	/*
2330	 * Handle logout cases here
2331	 */
2332	if (mp->nt_ncode == NT_GLOBAL_LOGOUT) {
2333		isp_del_all_wwn_entries(isp, mp->nt_channel);
2334	}
2335
2336	if (mp->nt_ncode == NT_LOGOUT) {
2337		if (!IS_2100(isp) && IS_FC(isp)) {
2338			isp_del_wwn_entries(isp, mp);
2339		}
2340	}
2341
2342	/*
2343	 * General purpose acknowledgement
2344	 */
2345	if (mp->nt_need_ack) {
2346		isp_prt(isp, ISP_LOGTINFO, "Notify Code 0x%x (qevalid=%d) being acked", mp->nt_ncode, mp->nt_lreserved != NULL);
2347		/*
2348		 * Don't need to use the guaranteed send because the caller can retry
2349		 */
2350		return (isp_notify_ack(isp, mp->nt_lreserved));
2351	}
2352	return (0);
2353}
2354
2355/*
2356 * Handle task management functions.
2357 *
2358 * We show up here with a notify structure filled out.
2359 *
2360 * The nt_lreserved tag points to the original queue entry
2361 */
2362static void
2363isp_handle_platform_target_tmf(ispsoftc_t *isp, isp_notify_t *notify)
2364{
2365	tstate_t *tptr;
2366	fcportdb_t *lp;
2367	struct ccb_immediate_notify *inot;
2368	inot_private_data_t *ntp = NULL;
2369	atio_private_data_t *atp;
2370	lun_id_t lun;
2371
2372	isp_prt(isp, ISP_LOGTDEBUG0, "%s: code 0x%x sid  0x%x tagval 0x%016llx chan %d lun %x", __func__, notify->nt_ncode,
2373	    notify->nt_sid, (unsigned long long) notify->nt_tagval, notify->nt_channel, notify->nt_lun);
2374	if (notify->nt_lun == LUN_ANY) {
2375		if (notify->nt_tagval == TAG_ANY) {
2376			lun = CAM_LUN_WILDCARD;
2377		} else {
2378			atp = isp_find_atpd(isp, notify->nt_channel,
2379			    notify->nt_tagval & 0xffffffff);
2380			lun = atp ? atp->lun : CAM_LUN_WILDCARD;
2381		}
2382	} else {
2383		lun = notify->nt_lun;
2384	}
2385	tptr = get_lun_statep(isp, notify->nt_channel, lun);
2386	if (tptr == NULL) {
2387		tptr = get_lun_statep(isp, notify->nt_channel, CAM_LUN_WILDCARD);
2388		if (tptr == NULL) {
2389			isp_prt(isp, ISP_LOGWARN, "%s: no state pointer found for chan %d lun 0x%x", __func__, notify->nt_channel, lun);
2390			goto bad;
2391		}
2392	}
2393	inot = (struct ccb_immediate_notify *) SLIST_FIRST(&tptr->inots);
2394	if (inot == NULL) {
2395		isp_prt(isp, ISP_LOGWARN, "%s: out of immediate notify structures for chan %d lun 0x%x", __func__, notify->nt_channel, lun);
2396		goto bad;
2397	}
2398
2399	if (isp_find_pdb_by_portid(isp, notify->nt_channel, notify->nt_sid, &lp) == 0 &&
2400	    isp_find_pdb_by_handle(isp, notify->nt_channel, notify->nt_nphdl, &lp) == 0) {
2401		inot->initiator_id = CAM_TARGET_WILDCARD;
2402	} else {
2403		inot->initiator_id = FC_PORTDB_TGT(isp, notify->nt_channel, lp);
2404	}
2405	inot->seq_id = notify->nt_tagval;
2406	inot->tag_id = notify->nt_tagval >> 32;
2407
2408	switch (notify->nt_ncode) {
2409	case NT_ABORT_TASK:
2410		isp_target_mark_aborted_early(isp, notify->nt_channel, tptr, inot->tag_id);
2411		inot->arg = MSG_ABORT_TASK;
2412		break;
2413	case NT_ABORT_TASK_SET:
2414		isp_target_mark_aborted_early(isp, notify->nt_channel, tptr, TAG_ANY);
2415		inot->arg = MSG_ABORT_TASK_SET;
2416		break;
2417	case NT_CLEAR_ACA:
2418		inot->arg = MSG_CLEAR_ACA;
2419		break;
2420	case NT_CLEAR_TASK_SET:
2421		inot->arg = MSG_CLEAR_TASK_SET;
2422		break;
2423	case NT_LUN_RESET:
2424		inot->arg = MSG_LOGICAL_UNIT_RESET;
2425		break;
2426	case NT_TARGET_RESET:
2427		inot->arg = MSG_TARGET_RESET;
2428		break;
2429	case NT_QUERY_TASK_SET:
2430		inot->arg = MSG_QUERY_TASK_SET;
2431		break;
2432	case NT_QUERY_ASYNC_EVENT:
2433		inot->arg = MSG_QUERY_ASYNC_EVENT;
2434		break;
2435	default:
2436		isp_prt(isp, ISP_LOGWARN, "%s: unknown TMF code 0x%x for chan %d lun 0x%x", __func__, notify->nt_ncode, notify->nt_channel, lun);
2437		goto bad;
2438	}
2439
2440	ntp = isp_get_ntpd(isp, notify->nt_channel);
2441	if (ntp == NULL) {
2442		isp_prt(isp, ISP_LOGWARN, "%s: out of inotify private structures", __func__);
2443		goto bad;
2444	}
2445	ISP_MEMCPY(&ntp->nt, notify, sizeof (isp_notify_t));
2446	if (notify->nt_lreserved) {
2447		ISP_MEMCPY(&ntp->data, notify->nt_lreserved, QENTRY_LEN);
2448		ntp->nt.nt_lreserved = &ntp->data;
2449	}
2450	ntp->seq_id = notify->nt_tagval;
2451	ntp->tag_id = notify->nt_tagval >> 32;
2452
2453	SLIST_REMOVE_HEAD(&tptr->inots, sim_links.sle);
2454	ISP_PATH_PRT(isp, ISP_LOGTDEBUG2, inot->ccb_h.path, "Take FREE INOT\n");
2455	inot->ccb_h.status = CAM_MESSAGE_RECV;
2456	xpt_done((union ccb *)inot);
2457	return;
2458bad:
2459	if (notify->nt_need_ack) {
2460		if (((isphdr_t *)notify->nt_lreserved)->rqs_entry_type == RQSTYPE_ABTS_RCVD) {
2461			if (isp_acknak_abts(isp, notify->nt_lreserved, ENOMEM)) {
2462				isp_prt(isp, ISP_LOGWARN, "you lose- unable to send an ACKNAK");
2463			}
2464		} else {
2465			isp_async(isp, ISPASYNC_TARGET_NOTIFY_ACK, notify->nt_lreserved);
2466		}
2467	}
2468}
2469
2470static void
2471isp_target_mark_aborted_early(ispsoftc_t *isp, int chan, tstate_t *tptr, uint32_t tag_id)
2472{
2473	atio_private_data_t *atp, *atpool;
2474	inot_private_data_t *ntp, *tmp;
2475	uint32_t this_tag_id;
2476
2477	/*
2478	 * First, clean any commands pending restart
2479	 */
2480	STAILQ_FOREACH_SAFE(ntp, &tptr->restart_queue, next, tmp) {
2481		if (IS_24XX(isp))
2482			this_tag_id = ((at7_entry_t *)ntp->data)->at_rxid;
2483		else
2484			this_tag_id = ((at2_entry_t *)ntp->data)->at_rxid;
2485		if ((uint64_t)tag_id == TAG_ANY || tag_id == this_tag_id) {
2486			isp_endcmd(isp, ntp->data, NIL_HANDLE, chan,
2487			    ECMD_TERMINATE, 0);
2488			isp_put_ntpd(isp, chan, ntp);
2489			STAILQ_REMOVE(&tptr->restart_queue, ntp,
2490			    inot_private_data, next);
2491		}
2492	}
2493
2494	/*
2495	 * Now mark other ones dead as well.
2496	 */
2497	ISP_GET_PC(isp, chan, atpool, atpool);
2498	for (atp = atpool; atp < &atpool[ATPDPSIZE]; atp++) {
2499		if (atp->lun != tptr->ts_lun)
2500			continue;
2501		if ((uint64_t)tag_id == TAG_ANY || atp->tag == tag_id)
2502			atp->dead = 1;
2503	}
2504}
2505#endif
2506
2507static void
2508isp_cam_async(void *cbarg, uint32_t code, struct cam_path *path, void *arg)
2509{
2510	struct cam_sim *sim;
2511	int bus, tgt;
2512	ispsoftc_t *isp;
2513
2514	sim = (struct cam_sim *)cbarg;
2515	isp = (ispsoftc_t *) cam_sim_softc(sim);
2516	bus = cam_sim_bus(sim);
2517	tgt = xpt_path_target_id(path);
2518
2519	switch (code) {
2520	case AC_LOST_DEVICE:
2521		if (IS_SCSI(isp)) {
2522			uint16_t oflags, nflags;
2523			sdparam *sdp = SDPARAM(isp, bus);
2524
2525			if (tgt >= 0) {
2526				nflags = sdp->isp_devparam[tgt].nvrm_flags;
2527				nflags &= DPARM_SAFE_DFLT;
2528				if (isp->isp_loaded_fw) {
2529					nflags |= DPARM_NARROW | DPARM_ASYNC;
2530				}
2531				oflags = sdp->isp_devparam[tgt].goal_flags;
2532				sdp->isp_devparam[tgt].goal_flags = nflags;
2533				sdp->isp_devparam[tgt].dev_update = 1;
2534				sdp->update = 1;
2535				(void) isp_control(isp, ISPCTL_UPDATE_PARAMS, bus);
2536				sdp->isp_devparam[tgt].goal_flags = oflags;
2537			}
2538		}
2539		break;
2540	default:
2541		isp_prt(isp, ISP_LOGWARN, "isp_cam_async: Code 0x%x", code);
2542		break;
2543	}
2544}
2545
2546static void
2547isp_poll(struct cam_sim *sim)
2548{
2549	ispsoftc_t *isp = cam_sim_softc(sim);
2550
2551	ISP_RUN_ISR(isp);
2552}
2553
2554
2555static void
2556isp_watchdog(void *arg)
2557{
2558	struct ccb_scsiio *xs = arg;
2559	ispsoftc_t *isp;
2560	uint32_t ohandle = ISP_HANDLE_FREE, handle;
2561
2562	isp = XS_ISP(xs);
2563
2564	handle = isp_find_handle(isp, xs);
2565
2566	/*
2567	 * Hand crank the interrupt code just to be sure the command isn't stuck somewhere.
2568	 */
2569	if (handle != ISP_HANDLE_FREE) {
2570		ISP_RUN_ISR(isp);
2571		ohandle = handle;
2572		handle = isp_find_handle(isp, xs);
2573	}
2574	if (handle != ISP_HANDLE_FREE) {
2575		/*
2576		 * Try and make sure the command is really dead before
2577		 * we release the handle (and DMA resources) for reuse.
2578		 *
2579		 * If we are successful in aborting the command then
2580		 * we're done here because we'll get the command returned
2581		 * back separately.
2582		 */
2583		if (isp_control(isp, ISPCTL_ABORT_CMD, xs) == 0) {
2584			return;
2585		}
2586
2587		/*
2588		 * Note that after calling the above, the command may in
2589		 * fact have been completed.
2590		 */
2591		xs = isp_find_xs(isp, handle);
2592
2593		/*
2594		 * If the command no longer exists, then we won't
2595		 * be able to find the xs again with this handle.
2596		 */
2597		if (xs == NULL) {
2598			return;
2599		}
2600
2601		/*
2602		 * After this point, the command is really dead.
2603		 */
2604		if (XS_XFRLEN(xs)) {
2605			ISP_DMAFREE(isp, xs, handle);
2606		}
2607		isp_destroy_handle(isp, handle);
2608		isp_prt(isp, ISP_LOGERR, "%s: timeout for handle 0x%x", __func__, handle);
2609		xs->ccb_h.status &= ~CAM_STATUS_MASK;
2610		xs->ccb_h.status |= CAM_CMD_TIMEOUT;
2611		isp_prt_endcmd(isp, xs);
2612		isp_done(xs);
2613	} else {
2614		if (ohandle != ISP_HANDLE_FREE) {
2615			isp_prt(isp, ISP_LOGWARN, "%s: timeout for handle 0x%x, recovered during interrupt", __func__, ohandle);
2616		} else {
2617			isp_prt(isp, ISP_LOGWARN, "%s: timeout for handle already free", __func__);
2618		}
2619	}
2620}
2621
2622static void
2623isp_make_here(ispsoftc_t *isp, fcportdb_t *fcp, int chan, int tgt)
2624{
2625	union ccb *ccb;
2626	struct isp_fc *fc = ISP_FC_PC(isp, chan);
2627
2628	/*
2629	 * Allocate a CCB, create a wildcard path for this target and schedule a rescan.
2630	 */
2631	ccb = xpt_alloc_ccb_nowait();
2632	if (ccb == NULL) {
2633		isp_prt(isp, ISP_LOGWARN, "Chan %d unable to alloc CCB for rescan", chan);
2634		return;
2635	}
2636	if (xpt_create_path(&ccb->ccb_h.path, NULL, cam_sim_path(fc->sim),
2637	    tgt, CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
2638		isp_prt(isp, ISP_LOGWARN, "unable to create path for rescan");
2639		xpt_free_ccb(ccb);
2640		return;
2641	}
2642	xpt_rescan(ccb);
2643}
2644
2645static void
2646isp_make_gone(ispsoftc_t *isp, fcportdb_t *fcp, int chan, int tgt)
2647{
2648	struct cam_path *tp;
2649	struct isp_fc *fc = ISP_FC_PC(isp, chan);
2650
2651	if (xpt_create_path(&tp, NULL, cam_sim_path(fc->sim), tgt, CAM_LUN_WILDCARD) == CAM_REQ_CMP) {
2652		xpt_async(AC_LOST_DEVICE, tp, NULL);
2653		xpt_free_path(tp);
2654	}
2655}
2656
2657/*
2658 * Gone Device Timer Function- when we have decided that a device has gone
2659 * away, we wait a specific period of time prior to telling the OS it has
2660 * gone away.
2661 *
2662 * This timer function fires once a second and then scans the port database
2663 * for devices that are marked dead but still have a virtual target assigned.
2664 * We decrement a counter for that port database entry, and when it hits zero,
2665 * we tell the OS the device has gone away.
2666 */
2667static void
2668isp_gdt(void *arg)
2669{
2670	struct isp_fc *fc = arg;
2671	taskqueue_enqueue(taskqueue_thread, &fc->gtask);
2672}
2673
2674static void
2675isp_gdt_task(void *arg, int pending)
2676{
2677	struct isp_fc *fc = arg;
2678	ispsoftc_t *isp = fc->isp;
2679	int chan = fc - isp->isp_osinfo.pc.fc;
2680	fcportdb_t *lp;
2681	struct ac_contract ac;
2682	struct ac_device_changed *adc;
2683	int dbidx, more_to_do = 0;
2684
2685	ISP_LOCK(isp);
2686	isp_prt(isp, ISP_LOGDEBUG0, "Chan %d GDT timer expired", chan);
2687	for (dbidx = 0; dbidx < MAX_FC_TARG; dbidx++) {
2688		lp = &FCPARAM(isp, chan)->portdb[dbidx];
2689
2690		if (lp->state != FC_PORTDB_STATE_ZOMBIE) {
2691			continue;
2692		}
2693		if (lp->gone_timer != 0) {
2694			lp->gone_timer -= 1;
2695			more_to_do++;
2696			continue;
2697		}
2698		isp_prt(isp, ISP_LOGCONFIG, prom3, chan, dbidx, lp->portid, "Gone Device Timeout");
2699		if (lp->is_target) {
2700			lp->is_target = 0;
2701			isp_make_gone(isp, lp, chan, dbidx);
2702		}
2703		if (lp->is_initiator) {
2704			lp->is_initiator = 0;
2705			ac.contract_number = AC_CONTRACT_DEV_CHG;
2706			adc = (struct ac_device_changed *) ac.contract_data;
2707			adc->wwpn = lp->port_wwn;
2708			adc->port = lp->portid;
2709			adc->target = dbidx;
2710			adc->arrived = 0;
2711			xpt_async(AC_CONTRACT, fc->path, &ac);
2712		}
2713		lp->state = FC_PORTDB_STATE_NIL;
2714	}
2715	if (fc->ready) {
2716		if (more_to_do) {
2717			callout_reset(&fc->gdt, hz, isp_gdt, fc);
2718		} else {
2719			callout_deactivate(&fc->gdt);
2720			isp_prt(isp, ISP_LOG_SANCFG, "Chan %d Stopping Gone Device Timer @ %lu", chan, (unsigned long) time_uptime);
2721		}
2722	}
2723	ISP_UNLOCK(isp);
2724}
2725
2726/*
2727 * When loop goes down we remember the time and freeze CAM command queue.
2728 * During some time period we are trying to reprobe the loop.  But if we
2729 * fail, we tell the OS that devices have gone away and drop the freeze.
2730 *
2731 * We don't clear the devices out of our port database because, when loop
2732 * come back up, we have to do some actual cleanup with the chip at that
2733 * point (implicit PLOGO, e.g., to get the chip's port database state right).
2734 */
2735static void
2736isp_loop_changed(ispsoftc_t *isp, int chan)
2737{
2738	fcparam *fcp = FCPARAM(isp, chan);
2739	struct isp_fc *fc = ISP_FC_PC(isp, chan);
2740
2741	if (fc->loop_down_time)
2742		return;
2743	isp_prt(isp, ISP_LOG_SANCFG|ISP_LOGDEBUG0, "Chan %d Loop changed", chan);
2744	if (fcp->role & ISP_ROLE_INITIATOR)
2745		isp_freeze_loopdown(isp, chan);
2746	fc->loop_down_time = time_uptime;
2747	wakeup(fc);
2748}
2749
2750static void
2751isp_loop_up(ispsoftc_t *isp, int chan)
2752{
2753	struct isp_fc *fc = ISP_FC_PC(isp, chan);
2754
2755	isp_prt(isp, ISP_LOG_SANCFG|ISP_LOGDEBUG0, "Chan %d Loop is up", chan);
2756	fc->loop_seen_once = 1;
2757	fc->loop_down_time = 0;
2758	isp_unfreeze_loopdown(isp, chan);
2759}
2760
2761static void
2762isp_loop_dead(ispsoftc_t *isp, int chan)
2763{
2764	fcparam *fcp = FCPARAM(isp, chan);
2765	struct isp_fc *fc = ISP_FC_PC(isp, chan);
2766	fcportdb_t *lp;
2767	struct ac_contract ac;
2768	struct ac_device_changed *adc;
2769	int dbidx, i;
2770
2771	isp_prt(isp, ISP_LOG_SANCFG|ISP_LOGDEBUG0, "Chan %d Loop is dead", chan);
2772
2773	/*
2774	 * Notify to the OS all targets who we now consider have departed.
2775	 */
2776	for (dbidx = 0; dbidx < MAX_FC_TARG; dbidx++) {
2777		lp = &fcp->portdb[dbidx];
2778
2779		if (lp->state == FC_PORTDB_STATE_NIL)
2780			continue;
2781
2782		/*
2783		 * XXX: CLEAN UP AND COMPLETE ANY PENDING COMMANDS FIRST!
2784		 */
2785		for (i = 0; i < isp->isp_maxcmds; i++) {
2786			struct ccb_scsiio *xs;
2787
2788			if (ISP_H2HT(isp->isp_xflist[i].handle) != ISP_HANDLE_INITIATOR) {
2789				continue;
2790			}
2791			if ((xs = isp->isp_xflist[i].cmd) == NULL) {
2792				continue;
2793                        }
2794			if (dbidx != XS_TGT(xs)) {
2795				continue;
2796			}
2797			isp_prt(isp, ISP_LOGWARN, "command handle 0x%x for %d.%d.%jx orphaned by loop down timeout",
2798			    isp->isp_xflist[i].handle, chan, XS_TGT(xs),
2799			    (uintmax_t)XS_LUN(xs));
2800		}
2801
2802		isp_prt(isp, ISP_LOGCONFIG, prom3, chan, dbidx, lp->portid, "Loop Down Timeout");
2803		if (lp->is_target) {
2804			lp->is_target = 0;
2805			isp_make_gone(isp, lp, chan, dbidx);
2806		}
2807		if (lp->is_initiator) {
2808			lp->is_initiator = 0;
2809			ac.contract_number = AC_CONTRACT_DEV_CHG;
2810			adc = (struct ac_device_changed *) ac.contract_data;
2811			adc->wwpn = lp->port_wwn;
2812			adc->port = lp->portid;
2813			adc->target = dbidx;
2814			adc->arrived = 0;
2815			xpt_async(AC_CONTRACT, fc->path, &ac);
2816		}
2817	}
2818
2819	isp_unfreeze_loopdown(isp, chan);
2820	fc->loop_down_time = 0;
2821}
2822
2823static void
2824isp_kthread(void *arg)
2825{
2826	struct isp_fc *fc = arg;
2827	ispsoftc_t *isp = fc->isp;
2828	int chan = fc - isp->isp_osinfo.pc.fc;
2829	int slp = 0, d;
2830	int lb, lim;
2831
2832	mtx_lock(&isp->isp_osinfo.lock);
2833
2834	while (isp->isp_osinfo.is_exiting == 0) {
2835		isp_prt(isp, ISP_LOG_SANCFG|ISP_LOGDEBUG0,
2836		    "Chan %d Checking FC state", chan);
2837		lb = isp_fc_runstate(isp, chan, 250000);
2838		isp_prt(isp, ISP_LOG_SANCFG|ISP_LOGDEBUG0,
2839		    "Chan %d FC got to %s state", chan,
2840		    isp_fc_loop_statename(lb));
2841
2842		/*
2843		 * Our action is different based upon whether we're supporting
2844		 * Initiator mode or not. If we are, we might freeze the simq
2845		 * when loop is down and set all sorts of different delays to
2846		 * check again.
2847		 *
2848		 * If not, we simply just wait for loop to come up.
2849		 */
2850		if (lb == LOOP_READY || lb < 0) {
2851			slp = 0;
2852		} else {
2853			/*
2854			 * If we've never seen loop up and we've waited longer
2855			 * than quickboot time, or we've seen loop up but we've
2856			 * waited longer than loop_down_limit, give up and go
2857			 * to sleep until loop comes up.
2858			 */
2859			if (fc->loop_seen_once == 0)
2860				lim = isp_quickboot_time;
2861			else
2862				lim = fc->loop_down_limit;
2863			d = time_uptime - fc->loop_down_time;
2864			if (d >= lim)
2865				slp = 0;
2866			else if (d < 10)
2867				slp = 1;
2868			else if (d < 30)
2869				slp = 5;
2870			else if (d < 60)
2871				slp = 10;
2872			else if (d < 120)
2873				slp = 20;
2874			else
2875				slp = 30;
2876		}
2877
2878		if (slp == 0) {
2879			if (lb == LOOP_READY)
2880				isp_loop_up(isp, chan);
2881			else
2882				isp_loop_dead(isp, chan);
2883		}
2884
2885		isp_prt(isp, ISP_LOG_SANCFG|ISP_LOGDEBUG0,
2886		    "Chan %d sleep for %d seconds", chan, slp);
2887		msleep(fc, &isp->isp_osinfo.lock, PRIBIO, "ispf", slp * hz);
2888	}
2889	fc->num_threads -= 1;
2890	mtx_unlock(&isp->isp_osinfo.lock);
2891	kthread_exit();
2892}
2893
2894#ifdef	ISP_TARGET_MODE
2895static void
2896isp_abort_atio(ispsoftc_t *isp, union ccb *ccb)
2897{
2898	atio_private_data_t *atp;
2899	union ccb *accb = ccb->cab.abort_ccb;
2900	struct ccb_hdr *sccb;
2901	tstate_t *tptr;
2902
2903	tptr = get_lun_statep(isp, XS_CHANNEL(accb), XS_LUN(accb));
2904	if (tptr != NULL) {
2905		/* Search for the ATIO among queueued. */
2906		SLIST_FOREACH(sccb, &tptr->atios, sim_links.sle) {
2907			if (sccb != &accb->ccb_h)
2908				continue;
2909			SLIST_REMOVE(&tptr->atios, sccb, ccb_hdr, sim_links.sle);
2910			ISP_PATH_PRT(isp, ISP_LOGTDEBUG2, sccb->path,
2911			    "Abort FREE ATIO\n");
2912			accb->ccb_h.status = CAM_REQ_ABORTED;
2913			xpt_done(accb);
2914			ccb->ccb_h.status = CAM_REQ_CMP;
2915			return;
2916		}
2917	}
2918
2919	/* Search for the ATIO among running. */
2920	atp = isp_find_atpd(isp, XS_CHANNEL(accb), accb->atio.tag_id);
2921	if (atp != NULL) {
2922		/* Send TERMINATE to firmware. */
2923		if (!atp->dead && IS_24XX(isp)) {
2924			uint8_t storage[QENTRY_LEN];
2925			ct7_entry_t *cto = (ct7_entry_t *) storage;
2926
2927			ISP_MEMZERO(cto, sizeof (ct7_entry_t));
2928			cto->ct_header.rqs_entry_type = RQSTYPE_CTIO7;
2929			cto->ct_header.rqs_entry_count = 1;
2930			cto->ct_nphdl = atp->nphdl;
2931			cto->ct_rxid = atp->tag;
2932			cto->ct_iid_lo = atp->sid;
2933			cto->ct_iid_hi = atp->sid >> 16;
2934			cto->ct_oxid = atp->oxid;
2935			cto->ct_vpidx = XS_CHANNEL(accb);
2936			cto->ct_flags = CT7_NOACK|CT7_TERMINATE;
2937			isp_target_put_entry(isp, cto);
2938		}
2939		isp_put_atpd(isp, XS_CHANNEL(accb), atp);
2940		ccb->ccb_h.status = CAM_REQ_CMP;
2941	} else {
2942		ccb->ccb_h.status = CAM_UA_ABORT;
2943	}
2944}
2945
2946static void
2947isp_abort_inot(ispsoftc_t *isp, union ccb *ccb)
2948{
2949	inot_private_data_t *ntp;
2950	union ccb *accb = ccb->cab.abort_ccb;
2951	struct ccb_hdr *sccb;
2952	tstate_t *tptr;
2953
2954	tptr = get_lun_statep(isp, XS_CHANNEL(accb), XS_LUN(accb));
2955	if (tptr != NULL) {
2956		/* Search for the INOT among queueued. */
2957		SLIST_FOREACH(sccb, &tptr->inots, sim_links.sle) {
2958			if (sccb != &accb->ccb_h)
2959				continue;
2960			SLIST_REMOVE(&tptr->inots, sccb, ccb_hdr, sim_links.sle);
2961			ISP_PATH_PRT(isp, ISP_LOGTDEBUG2, sccb->path,
2962			    "Abort FREE INOT\n");
2963			accb->ccb_h.status = CAM_REQ_ABORTED;
2964			xpt_done(accb);
2965			ccb->ccb_h.status = CAM_REQ_CMP;
2966			return;
2967		}
2968	}
2969
2970	/* Search for the INOT among running. */
2971	ntp = isp_find_ntpd(isp, XS_CHANNEL(accb), accb->cin1.tag_id, accb->cin1.seq_id);
2972	if (ntp != NULL) {
2973		if (ntp->nt.nt_need_ack) {
2974			isp_async(isp, ISPASYNC_TARGET_NOTIFY_ACK,
2975			    ntp->nt.nt_lreserved);
2976		}
2977		isp_put_ntpd(isp, XS_CHANNEL(accb), ntp);
2978		ccb->ccb_h.status = CAM_REQ_CMP;
2979	} else {
2980		ccb->ccb_h.status = CAM_UA_ABORT;
2981		return;
2982	}
2983}
2984#endif
2985
2986static void
2987isp_action(struct cam_sim *sim, union ccb *ccb)
2988{
2989	int bus, tgt, ts, error;
2990	ispsoftc_t *isp;
2991	struct ccb_trans_settings *cts;
2992
2993	CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_TRACE, ("isp_action\n"));
2994
2995	isp = (ispsoftc_t *)cam_sim_softc(sim);
2996	mtx_assert(&isp->isp_lock, MA_OWNED);
2997	isp_prt(isp, ISP_LOGDEBUG2, "isp_action code %x", ccb->ccb_h.func_code);
2998	ISP_PCMD(ccb) = NULL;
2999
3000	switch (ccb->ccb_h.func_code) {
3001	case XPT_SCSI_IO:	/* Execute the requested I/O operation */
3002		bus = XS_CHANNEL(ccb);
3003		/*
3004		 * Do a couple of preliminary checks...
3005		 */
3006		if ((ccb->ccb_h.flags & CAM_CDB_POINTER) != 0) {
3007			if ((ccb->ccb_h.flags & CAM_CDB_PHYS) != 0) {
3008				ccb->ccb_h.status = CAM_REQ_INVALID;
3009				isp_done((struct ccb_scsiio *) ccb);
3010				break;
3011			}
3012		}
3013		ccb->csio.req_map = NULL;
3014#ifdef	DIAGNOSTIC
3015		if (ccb->ccb_h.target_id >= ISP_MAX_TARGETS(isp)) {
3016			xpt_print(ccb->ccb_h.path, "invalid target\n");
3017			ccb->ccb_h.status = CAM_PATH_INVALID;
3018		} else if (ISP_MAX_LUNS(isp) > 0 &&
3019		    ccb->ccb_h.target_lun >= ISP_MAX_LUNS(isp)) {
3020			xpt_print(ccb->ccb_h.path, "invalid lun\n");
3021			ccb->ccb_h.status = CAM_PATH_INVALID;
3022		}
3023		if (ccb->ccb_h.status == CAM_PATH_INVALID) {
3024			xpt_done(ccb);
3025			break;
3026		}
3027#endif
3028		ccb->csio.scsi_status = SCSI_STATUS_OK;
3029		if (isp_get_pcmd(isp, ccb)) {
3030			isp_prt(isp, ISP_LOGWARN, "out of PCMDs");
3031			cam_freeze_devq(ccb->ccb_h.path);
3032			cam_release_devq(ccb->ccb_h.path, RELSIM_RELEASE_AFTER_TIMEOUT, 0, 250, 0);
3033			ccb->ccb_h.status = CAM_REQUEUE_REQ;
3034			xpt_done(ccb);
3035			break;
3036		}
3037		error = isp_start((XS_T *) ccb);
3038		switch (error) {
3039		case CMD_QUEUED:
3040			ccb->ccb_h.status |= CAM_SIM_QUEUED;
3041			if (ccb->ccb_h.timeout == CAM_TIME_INFINITY) {
3042				break;
3043			}
3044			ts = ccb->ccb_h.timeout;
3045			if (ts == CAM_TIME_DEFAULT) {
3046				ts = 60*1000;
3047			}
3048			ts = isp_mstohz(ts);
3049			callout_reset(&PISP_PCMD(ccb)->wdog, ts, isp_watchdog, ccb);
3050			break;
3051		case CMD_RQLATER:
3052			isp_prt(isp, ISP_LOGDEBUG0, "%d.%jx retry later",
3053			    XS_TGT(ccb), (uintmax_t)XS_LUN(ccb));
3054			cam_freeze_devq(ccb->ccb_h.path);
3055			cam_release_devq(ccb->ccb_h.path, RELSIM_RELEASE_AFTER_TIMEOUT, 0, 1000, 0);
3056			ccb->ccb_h.status = CAM_REQUEUE_REQ;
3057			isp_free_pcmd(isp, ccb);
3058			xpt_done(ccb);
3059			break;
3060		case CMD_EAGAIN:
3061			isp_free_pcmd(isp, ccb);
3062			cam_freeze_devq(ccb->ccb_h.path);
3063			cam_release_devq(ccb->ccb_h.path, RELSIM_RELEASE_AFTER_TIMEOUT, 0, 100, 0);
3064			ccb->ccb_h.status = CAM_REQUEUE_REQ;
3065			xpt_done(ccb);
3066			break;
3067		case CMD_COMPLETE:
3068			isp_done((struct ccb_scsiio *) ccb);
3069			break;
3070		default:
3071			isp_prt(isp, ISP_LOGERR, "What's this? 0x%x at %d in file %s", error, __LINE__, __FILE__);
3072			ccb->ccb_h.status = CAM_REQUEUE_REQ;
3073			isp_free_pcmd(isp, ccb);
3074			xpt_done(ccb);
3075		}
3076		break;
3077
3078#ifdef	ISP_TARGET_MODE
3079	case XPT_EN_LUN:		/* Enable/Disable LUN as a target */
3080		if (ccb->cel.enable) {
3081			isp_enable_lun(isp, ccb);
3082		} else {
3083			isp_disable_lun(isp, ccb);
3084		}
3085		break;
3086	case XPT_IMMEDIATE_NOTIFY:	/* Add Immediate Notify Resource */
3087	case XPT_ACCEPT_TARGET_IO:	/* Add Accept Target IO Resource */
3088	{
3089		tstate_t *tptr = get_lun_statep(isp, XS_CHANNEL(ccb), ccb->ccb_h.target_lun);
3090		if (tptr == NULL) {
3091			const char *str;
3092
3093			if (ccb->ccb_h.func_code == XPT_IMMEDIATE_NOTIFY)
3094				str = "XPT_IMMEDIATE_NOTIFY";
3095			else
3096				str = "XPT_ACCEPT_TARGET_IO";
3097			ISP_PATH_PRT(isp, ISP_LOGWARN, ccb->ccb_h.path,
3098			    "%s: no state pointer found for %s\n",
3099			    __func__, str);
3100			ccb->ccb_h.status = CAM_DEV_NOT_THERE;
3101			xpt_done(ccb);
3102			break;
3103		}
3104		ccb->ccb_h.spriv_field0 = 0;
3105		ccb->ccb_h.spriv_ptr1 = isp;
3106
3107		if (ccb->ccb_h.func_code == XPT_ACCEPT_TARGET_IO) {
3108			ccb->atio.tag_id = 0;
3109			SLIST_INSERT_HEAD(&tptr->atios, &ccb->ccb_h, sim_links.sle);
3110			ISP_PATH_PRT(isp, ISP_LOGTDEBUG2, ccb->ccb_h.path,
3111			    "Put FREE ATIO\n");
3112		} else if (ccb->ccb_h.func_code == XPT_IMMEDIATE_NOTIFY) {
3113			ccb->cin1.seq_id = ccb->cin1.tag_id = 0;
3114			SLIST_INSERT_HEAD(&tptr->inots, &ccb->ccb_h, sim_links.sle);
3115			ISP_PATH_PRT(isp, ISP_LOGTDEBUG2, ccb->ccb_h.path,
3116			    "Put FREE INOT\n");
3117		}
3118		ccb->ccb_h.status = CAM_REQ_INPROG;
3119		break;
3120	}
3121	case XPT_NOTIFY_ACKNOWLEDGE:		/* notify ack */
3122	{
3123		inot_private_data_t *ntp;
3124
3125		/*
3126		 * XXX: Because we cannot guarantee that the path information in the notify acknowledge ccb
3127		 * XXX: matches that for the immediate notify, we have to *search* for the notify structure
3128		 */
3129		/*
3130		 * All the relevant path information is in the associated immediate notify
3131		 */
3132		ISP_PATH_PRT(isp, ISP_LOGTDEBUG0, ccb->ccb_h.path, "%s: [0x%x] NOTIFY ACKNOWLEDGE for 0x%x seen\n", __func__, ccb->cna2.tag_id, ccb->cna2.seq_id);
3133		ntp = isp_find_ntpd(isp, XS_CHANNEL(ccb), ccb->cna2.tag_id, ccb->cna2.seq_id);
3134		if (ntp == NULL) {
3135			ISP_PATH_PRT(isp, ISP_LOGWARN, ccb->ccb_h.path, "%s: [0x%x] XPT_NOTIFY_ACKNOWLEDGE of 0x%x cannot find ntp private data\n", __func__,
3136			     ccb->cna2.tag_id, ccb->cna2.seq_id);
3137			ccb->ccb_h.status = CAM_DEV_NOT_THERE;
3138			xpt_done(ccb);
3139			break;
3140		}
3141		if (isp_handle_platform_target_notify_ack(isp, &ntp->nt,
3142		    (ccb->ccb_h.flags & CAM_SEND_STATUS) ? ccb->cna2.arg : 0)) {
3143			cam_freeze_devq(ccb->ccb_h.path);
3144			cam_release_devq(ccb->ccb_h.path, RELSIM_RELEASE_AFTER_TIMEOUT, 0, 1000, 0);
3145			ccb->ccb_h.status &= ~CAM_STATUS_MASK;
3146			ccb->ccb_h.status |= CAM_REQUEUE_REQ;
3147			break;
3148		}
3149		isp_put_ntpd(isp, XS_CHANNEL(ccb), ntp);
3150		ccb->ccb_h.status = CAM_REQ_CMP;
3151		ISP_PATH_PRT(isp, ISP_LOGTDEBUG0, ccb->ccb_h.path, "%s: [0x%x] calling xpt_done for tag 0x%x\n", __func__, ccb->cna2.tag_id, ccb->cna2.seq_id);
3152		xpt_done(ccb);
3153		break;
3154	}
3155	case XPT_CONT_TARGET_IO:
3156		isp_target_start_ctio(isp, ccb, FROM_CAM);
3157		break;
3158#endif
3159	case XPT_RESET_DEV:		/* BDR the specified SCSI device */
3160		bus = cam_sim_bus(xpt_path_sim(ccb->ccb_h.path));
3161		tgt = ccb->ccb_h.target_id;
3162		tgt |= (bus << 16);
3163
3164		error = isp_control(isp, ISPCTL_RESET_DEV, bus, tgt);
3165		if (error) {
3166			ccb->ccb_h.status = CAM_REQ_CMP_ERR;
3167		} else {
3168			/*
3169			 * If we have a FC device, reset the Command
3170			 * Reference Number, because the target will expect
3171			 * that we re-start the CRN at 1 after a reset.
3172			 */
3173			if (IS_FC(isp))
3174				isp_fcp_reset_crn(isp, bus, tgt, /*tgt_set*/ 1);
3175
3176			ccb->ccb_h.status = CAM_REQ_CMP;
3177		}
3178		xpt_done(ccb);
3179		break;
3180	case XPT_ABORT:			/* Abort the specified CCB */
3181	{
3182		union ccb *accb = ccb->cab.abort_ccb;
3183		switch (accb->ccb_h.func_code) {
3184#ifdef	ISP_TARGET_MODE
3185		case XPT_ACCEPT_TARGET_IO:
3186			isp_abort_atio(isp, ccb);
3187			break;
3188		case XPT_IMMEDIATE_NOTIFY:
3189			isp_abort_inot(isp, ccb);
3190			break;
3191#endif
3192		case XPT_SCSI_IO:
3193			error = isp_control(isp, ISPCTL_ABORT_CMD, accb);
3194			if (error) {
3195				ccb->ccb_h.status = CAM_UA_ABORT;
3196			} else {
3197				ccb->ccb_h.status = CAM_REQ_CMP;
3198			}
3199			break;
3200		default:
3201			ccb->ccb_h.status = CAM_REQ_INVALID;
3202			break;
3203		}
3204		/*
3205		 * This is not a queued CCB, so the caller expects it to be
3206		 * complete when control is returned.
3207		 */
3208		break;
3209	}
3210#define	IS_CURRENT_SETTINGS(c)	(c->type == CTS_TYPE_CURRENT_SETTINGS)
3211	case XPT_SET_TRAN_SETTINGS:	/* Nexus Settings */
3212		cts = &ccb->cts;
3213		if (!IS_CURRENT_SETTINGS(cts)) {
3214			ccb->ccb_h.status = CAM_REQ_INVALID;
3215			xpt_done(ccb);
3216			break;
3217		}
3218		tgt = cts->ccb_h.target_id;
3219		bus = cam_sim_bus(xpt_path_sim(cts->ccb_h.path));
3220		if (IS_SCSI(isp)) {
3221			struct ccb_trans_settings_scsi *scsi = &cts->proto_specific.scsi;
3222			struct ccb_trans_settings_spi *spi = &cts->xport_specific.spi;
3223			sdparam *sdp = SDPARAM(isp, bus);
3224			uint16_t *dptr;
3225
3226			if (spi->valid == 0 && scsi->valid == 0) {
3227				ccb->ccb_h.status = CAM_REQ_CMP;
3228				xpt_done(ccb);
3229				break;
3230			}
3231
3232			/*
3233			 * We always update (internally) from goal_flags
3234			 * so any request to change settings just gets
3235			 * vectored to that location.
3236			 */
3237			dptr = &sdp->isp_devparam[tgt].goal_flags;
3238
3239			if ((spi->valid & CTS_SPI_VALID_DISC) != 0) {
3240				if ((spi->flags & CTS_SPI_FLAGS_DISC_ENB) != 0)
3241					*dptr |= DPARM_DISC;
3242				else
3243					*dptr &= ~DPARM_DISC;
3244			}
3245
3246			if ((scsi->valid & CTS_SCSI_VALID_TQ) != 0) {
3247				if ((scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) != 0)
3248					*dptr |= DPARM_TQING;
3249				else
3250					*dptr &= ~DPARM_TQING;
3251			}
3252
3253			if ((spi->valid & CTS_SPI_VALID_BUS_WIDTH) != 0) {
3254				if (spi->bus_width == MSG_EXT_WDTR_BUS_16_BIT)
3255					*dptr |= DPARM_WIDE;
3256				else
3257					*dptr &= ~DPARM_WIDE;
3258			}
3259
3260			/*
3261			 * XXX: FIX ME
3262			 */
3263			if ((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) && (spi->valid & CTS_SPI_VALID_SYNC_RATE) && (spi->sync_period && spi->sync_offset)) {
3264				*dptr |= DPARM_SYNC;
3265				/*
3266				 * XXX: CHECK FOR LEGALITY
3267				 */
3268				sdp->isp_devparam[tgt].goal_period = spi->sync_period;
3269				sdp->isp_devparam[tgt].goal_offset = spi->sync_offset;
3270			} else {
3271				*dptr &= ~DPARM_SYNC;
3272			}
3273			isp_prt(isp, ISP_LOGDEBUG0, "SET (%d.%d.%d) to flags %x off %x per %x", bus, tgt, cts->ccb_h.target_lun, sdp->isp_devparam[tgt].goal_flags,
3274			    sdp->isp_devparam[tgt].goal_offset, sdp->isp_devparam[tgt].goal_period);
3275			sdp->isp_devparam[tgt].dev_update = 1;
3276			sdp->update = 1;
3277		}
3278		ccb->ccb_h.status = CAM_REQ_CMP;
3279		xpt_done(ccb);
3280		break;
3281	case XPT_GET_TRAN_SETTINGS:
3282		cts = &ccb->cts;
3283		tgt = cts->ccb_h.target_id;
3284		bus = cam_sim_bus(xpt_path_sim(cts->ccb_h.path));
3285		if (IS_FC(isp)) {
3286			fcparam *fcp = FCPARAM(isp, bus);
3287			struct ccb_trans_settings_scsi *scsi = &cts->proto_specific.scsi;
3288			struct ccb_trans_settings_fc *fc = &cts->xport_specific.fc;
3289
3290			cts->protocol = PROTO_SCSI;
3291			cts->protocol_version = SCSI_REV_2;
3292			cts->transport = XPORT_FC;
3293			cts->transport_version = 0;
3294
3295			scsi->valid = CTS_SCSI_VALID_TQ;
3296			scsi->flags = CTS_SCSI_FLAGS_TAG_ENB;
3297			fc->valid = CTS_FC_VALID_SPEED;
3298			fc->bitrate = 100000;
3299			fc->bitrate *= fcp->isp_gbspeed;
3300			if (tgt < MAX_FC_TARG) {
3301				fcportdb_t *lp = &fcp->portdb[tgt];
3302				fc->wwnn = lp->node_wwn;
3303				fc->wwpn = lp->port_wwn;
3304				fc->port = lp->portid;
3305				fc->valid |= CTS_FC_VALID_WWNN | CTS_FC_VALID_WWPN | CTS_FC_VALID_PORT;
3306			}
3307		} else {
3308			struct ccb_trans_settings_scsi *scsi = &cts->proto_specific.scsi;
3309			struct ccb_trans_settings_spi *spi = &cts->xport_specific.spi;
3310			sdparam *sdp = SDPARAM(isp, bus);
3311			uint16_t dval, pval, oval;
3312
3313			if (IS_CURRENT_SETTINGS(cts)) {
3314				sdp->isp_devparam[tgt].dev_refresh = 1;
3315				sdp->update = 1;
3316				(void) isp_control(isp, ISPCTL_UPDATE_PARAMS, bus);
3317				dval = sdp->isp_devparam[tgt].actv_flags;
3318				oval = sdp->isp_devparam[tgt].actv_offset;
3319				pval = sdp->isp_devparam[tgt].actv_period;
3320			} else {
3321				dval = sdp->isp_devparam[tgt].nvrm_flags;
3322				oval = sdp->isp_devparam[tgt].nvrm_offset;
3323				pval = sdp->isp_devparam[tgt].nvrm_period;
3324			}
3325
3326			cts->protocol = PROTO_SCSI;
3327			cts->protocol_version = SCSI_REV_2;
3328			cts->transport = XPORT_SPI;
3329			cts->transport_version = 2;
3330
3331			spi->valid = 0;
3332			scsi->valid = 0;
3333			spi->flags = 0;
3334			scsi->flags = 0;
3335			if (dval & DPARM_DISC) {
3336				spi->flags |= CTS_SPI_FLAGS_DISC_ENB;
3337			}
3338			if ((dval & DPARM_SYNC) && oval && pval) {
3339				spi->sync_offset = oval;
3340				spi->sync_period = pval;
3341			} else {
3342				spi->sync_offset = 0;
3343				spi->sync_period = 0;
3344			}
3345			spi->valid |= CTS_SPI_VALID_SYNC_OFFSET;
3346			spi->valid |= CTS_SPI_VALID_SYNC_RATE;
3347			spi->valid |= CTS_SPI_VALID_BUS_WIDTH;
3348			if (dval & DPARM_WIDE) {
3349				spi->bus_width = MSG_EXT_WDTR_BUS_16_BIT;
3350			} else {
3351				spi->bus_width = MSG_EXT_WDTR_BUS_8_BIT;
3352			}
3353			if (cts->ccb_h.target_lun != CAM_LUN_WILDCARD) {
3354				scsi->valid = CTS_SCSI_VALID_TQ;
3355				if (dval & DPARM_TQING) {
3356					scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB;
3357				}
3358				spi->valid |= CTS_SPI_VALID_DISC;
3359			}
3360			isp_prt(isp, ISP_LOGDEBUG0, "GET %s (%d.%d.%d) to flags %x off %x per %x", IS_CURRENT_SETTINGS(cts)? "ACTIVE" : "NVRAM",
3361			    bus, tgt, cts->ccb_h.target_lun, dval, oval, pval);
3362		}
3363		ccb->ccb_h.status = CAM_REQ_CMP;
3364		xpt_done(ccb);
3365		break;
3366
3367	case XPT_CALC_GEOMETRY:
3368		cam_calc_geometry(&ccb->ccg, 1);
3369		xpt_done(ccb);
3370		break;
3371
3372	case XPT_RESET_BUS:		/* Reset the specified bus */
3373		bus = cam_sim_bus(sim);
3374		error = isp_control(isp, ISPCTL_RESET_BUS, bus);
3375		if (error) {
3376			ccb->ccb_h.status = CAM_REQ_CMP_ERR;
3377			xpt_done(ccb);
3378			break;
3379		}
3380		if (bootverbose) {
3381			xpt_print(ccb->ccb_h.path, "reset bus on channel %d\n", bus);
3382		}
3383		if (IS_FC(isp)) {
3384			xpt_async(AC_BUS_RESET, ISP_FC_PC(isp, bus)->path, 0);
3385		} else {
3386			xpt_async(AC_BUS_RESET, ISP_SPI_PC(isp, bus)->path, 0);
3387		}
3388		ccb->ccb_h.status = CAM_REQ_CMP;
3389		xpt_done(ccb);
3390		break;
3391
3392	case XPT_TERM_IO:		/* Terminate the I/O process */
3393		ccb->ccb_h.status = CAM_REQ_INVALID;
3394		xpt_done(ccb);
3395		break;
3396
3397	case XPT_SET_SIM_KNOB:		/* Set SIM knobs */
3398	{
3399		struct ccb_sim_knob *kp = &ccb->knob;
3400		fcparam *fcp;
3401
3402		if (!IS_FC(isp)) {
3403			ccb->ccb_h.status = CAM_REQ_INVALID;
3404			xpt_done(ccb);
3405			break;
3406		}
3407
3408		bus = cam_sim_bus(xpt_path_sim(kp->ccb_h.path));
3409		fcp = FCPARAM(isp, bus);
3410
3411		if (kp->xport_specific.fc.valid & KNOB_VALID_ADDRESS) {
3412			fcp->isp_wwnn = ISP_FC_PC(isp, bus)->def_wwnn = kp->xport_specific.fc.wwnn;
3413			fcp->isp_wwpn = ISP_FC_PC(isp, bus)->def_wwpn = kp->xport_specific.fc.wwpn;
3414			isp_prt(isp, ISP_LOGALL, "Setting Channel %d wwns to 0x%jx 0x%jx", bus, fcp->isp_wwnn, fcp->isp_wwpn);
3415		}
3416		ccb->ccb_h.status = CAM_REQ_CMP;
3417		if (kp->xport_specific.fc.valid & KNOB_VALID_ROLE) {
3418			int rchange = 0;
3419			int newrole = 0;
3420
3421			switch (kp->xport_specific.fc.role) {
3422			case KNOB_ROLE_NONE:
3423				if (fcp->role != ISP_ROLE_NONE) {
3424					rchange = 1;
3425					newrole = ISP_ROLE_NONE;
3426				}
3427				break;
3428			case KNOB_ROLE_TARGET:
3429				if (fcp->role != ISP_ROLE_TARGET) {
3430					rchange = 1;
3431					newrole = ISP_ROLE_TARGET;
3432				}
3433				break;
3434			case KNOB_ROLE_INITIATOR:
3435				if (fcp->role != ISP_ROLE_INITIATOR) {
3436					rchange = 1;
3437					newrole = ISP_ROLE_INITIATOR;
3438				}
3439				break;
3440			case KNOB_ROLE_BOTH:
3441				if (fcp->role != ISP_ROLE_BOTH) {
3442					rchange = 1;
3443					newrole = ISP_ROLE_BOTH;
3444				}
3445				break;
3446			}
3447			if (rchange) {
3448				ISP_PATH_PRT(isp, ISP_LOGCONFIG, ccb->ccb_h.path, "changing role on from %d to %d\n", fcp->role, newrole);
3449				if (isp_control(isp, ISPCTL_CHANGE_ROLE,
3450				    bus, newrole) != 0) {
3451					ccb->ccb_h.status = CAM_REQ_CMP_ERR;
3452					xpt_done(ccb);
3453					break;
3454				}
3455			}
3456		}
3457		xpt_done(ccb);
3458		break;
3459	}
3460	case XPT_GET_SIM_KNOB:		/* Get SIM knobs */
3461	{
3462		struct ccb_sim_knob *kp = &ccb->knob;
3463
3464		if (IS_FC(isp)) {
3465			fcparam *fcp;
3466
3467			bus = cam_sim_bus(xpt_path_sim(kp->ccb_h.path));
3468			fcp = FCPARAM(isp, bus);
3469
3470			kp->xport_specific.fc.wwnn = fcp->isp_wwnn;
3471			kp->xport_specific.fc.wwpn = fcp->isp_wwpn;
3472			switch (fcp->role) {
3473			case ISP_ROLE_NONE:
3474				kp->xport_specific.fc.role = KNOB_ROLE_NONE;
3475				break;
3476			case ISP_ROLE_TARGET:
3477				kp->xport_specific.fc.role = KNOB_ROLE_TARGET;
3478				break;
3479			case ISP_ROLE_INITIATOR:
3480				kp->xport_specific.fc.role = KNOB_ROLE_INITIATOR;
3481				break;
3482			case ISP_ROLE_BOTH:
3483				kp->xport_specific.fc.role = KNOB_ROLE_BOTH;
3484				break;
3485			}
3486			kp->xport_specific.fc.valid = KNOB_VALID_ADDRESS | KNOB_VALID_ROLE;
3487			ccb->ccb_h.status = CAM_REQ_CMP;
3488		} else {
3489			ccb->ccb_h.status = CAM_REQ_INVALID;
3490		}
3491		xpt_done(ccb);
3492		break;
3493	}
3494	case XPT_PATH_INQ:		/* Path routing inquiry */
3495	{
3496		struct ccb_pathinq *cpi = &ccb->cpi;
3497
3498		cpi->version_num = 1;
3499#ifdef	ISP_TARGET_MODE
3500		if (IS_FC(isp) && ISP_CAP_TMODE(isp) && ISP_CAP_SCCFW(isp))
3501			cpi->target_sprt = PIT_PROCESSOR | PIT_DISCONNECT | PIT_TERM_IO;
3502		else
3503#endif
3504			cpi->target_sprt = 0;
3505		cpi->hba_eng_cnt = 0;
3506		cpi->max_target = ISP_MAX_TARGETS(isp) - 1;
3507		cpi->max_lun = ISP_MAX_LUNS(isp) == 0 ?
3508		    255 : ISP_MAX_LUNS(isp) - 1;
3509		cpi->bus_id = cam_sim_bus(sim);
3510		if (isp->isp_osinfo.sixtyfourbit)
3511			cpi->maxio = (ISP_NSEG64_MAX - 1) * PAGE_SIZE;
3512		else
3513			cpi->maxio = (ISP_NSEG_MAX - 1) * PAGE_SIZE;
3514
3515		bus = cam_sim_bus(xpt_path_sim(cpi->ccb_h.path));
3516		if (IS_FC(isp)) {
3517			fcparam *fcp = FCPARAM(isp, bus);
3518
3519			cpi->hba_misc = PIM_NOBUSRESET | PIM_UNMAPPED;
3520			cpi->hba_misc |= PIM_EXTLUNS | PIM_NOSCAN;
3521
3522			/*
3523			 * Because our loop ID can shift from time to time,
3524			 * make our initiator ID out of range of our bus.
3525			 */
3526			cpi->initiator_id = cpi->max_target + 1;
3527
3528			/*
3529			 * Set base transfer capabilities for Fibre Channel, for this HBA.
3530			 */
3531			if (IS_25XX(isp)) {
3532				cpi->base_transfer_speed = 8000000;
3533			} else if (IS_24XX(isp)) {
3534				cpi->base_transfer_speed = 4000000;
3535			} else if (IS_23XX(isp)) {
3536				cpi->base_transfer_speed = 2000000;
3537			} else {
3538				cpi->base_transfer_speed = 1000000;
3539			}
3540			cpi->hba_inquiry = PI_TAG_ABLE;
3541			cpi->transport = XPORT_FC;
3542			cpi->transport_version = 0;
3543			cpi->xport_specific.fc.wwnn = fcp->isp_wwnn;
3544			cpi->xport_specific.fc.wwpn = fcp->isp_wwpn;
3545			cpi->xport_specific.fc.port = fcp->isp_portid;
3546			cpi->xport_specific.fc.bitrate = fcp->isp_gbspeed * 1000;
3547		} else {
3548			sdparam *sdp = SDPARAM(isp, bus);
3549			cpi->hba_inquiry = PI_SDTR_ABLE|PI_TAG_ABLE|PI_WIDE_16;
3550			cpi->hba_misc = PIM_UNMAPPED;
3551			cpi->initiator_id = sdp->isp_initiator_id;
3552			cpi->base_transfer_speed = 3300;
3553			cpi->transport = XPORT_SPI;
3554			cpi->transport_version = 2;
3555		}
3556		cpi->protocol = PROTO_SCSI;
3557		cpi->protocol_version = SCSI_REV_2;
3558		strlcpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN);
3559		strlcpy(cpi->hba_vid, "Qlogic", HBA_IDLEN);
3560		strlcpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN);
3561		cpi->unit_number = cam_sim_unit(sim);
3562		cpi->ccb_h.status = CAM_REQ_CMP;
3563		xpt_done(ccb);
3564		break;
3565	}
3566	default:
3567		ccb->ccb_h.status = CAM_REQ_INVALID;
3568		xpt_done(ccb);
3569		break;
3570	}
3571}
3572
3573void
3574isp_done(XS_T *sccb)
3575{
3576	ispsoftc_t *isp = XS_ISP(sccb);
3577	uint32_t status;
3578
3579	if (XS_NOERR(sccb))
3580		XS_SETERR(sccb, CAM_REQ_CMP);
3581
3582	if ((sccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP && (sccb->scsi_status != SCSI_STATUS_OK)) {
3583		sccb->ccb_h.status &= ~CAM_STATUS_MASK;
3584		if ((sccb->scsi_status == SCSI_STATUS_CHECK_COND) && (sccb->ccb_h.status & CAM_AUTOSNS_VALID) == 0) {
3585			sccb->ccb_h.status |= CAM_AUTOSENSE_FAIL;
3586		} else {
3587			sccb->ccb_h.status |= CAM_SCSI_STATUS_ERROR;
3588		}
3589	}
3590
3591	sccb->ccb_h.status &= ~CAM_SIM_QUEUED;
3592	status = sccb->ccb_h.status & CAM_STATUS_MASK;
3593	if (status != CAM_REQ_CMP &&
3594	    (sccb->ccb_h.status & CAM_DEV_QFRZN) == 0) {
3595		sccb->ccb_h.status |= CAM_DEV_QFRZN;
3596		xpt_freeze_devq(sccb->ccb_h.path, 1);
3597	}
3598
3599	if (ISP_PCMD(sccb)) {
3600		if (callout_active(&PISP_PCMD(sccb)->wdog))
3601			callout_stop(&PISP_PCMD(sccb)->wdog);
3602		isp_free_pcmd(isp, (union ccb *) sccb);
3603	}
3604	xpt_done((union ccb *) sccb);
3605}
3606
3607void
3608isp_async(ispsoftc_t *isp, ispasync_t cmd, ...)
3609{
3610	int bus;
3611	static const char prom[] = "Chan %d [%d] WWPN 0x%16jx PortID 0x%06x handle 0x%x %s %s";
3612	char buf[64];
3613	char *msg = NULL;
3614	target_id_t tgt;
3615	fcportdb_t *lp;
3616	struct isp_fc *fc;
3617	struct cam_path *tmppath;
3618	struct ac_contract ac;
3619	struct ac_device_changed *adc;
3620	va_list ap;
3621
3622	switch (cmd) {
3623	case ISPASYNC_NEW_TGT_PARAMS:
3624	{
3625		struct ccb_trans_settings_scsi *scsi;
3626		struct ccb_trans_settings_spi *spi;
3627		int flags, tgt;
3628		sdparam *sdp;
3629		struct ccb_trans_settings cts;
3630
3631		memset(&cts, 0, sizeof (struct ccb_trans_settings));
3632
3633		va_start(ap, cmd);
3634		bus = va_arg(ap, int);
3635		tgt = va_arg(ap, int);
3636		va_end(ap);
3637		sdp = SDPARAM(isp, bus);
3638
3639		if (xpt_create_path(&tmppath, NULL, cam_sim_path(ISP_SPI_PC(isp, bus)->sim), tgt, CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
3640			isp_prt(isp, ISP_LOGWARN, "isp_async cannot make temp path for %d.%d", tgt, bus);
3641			break;
3642		}
3643		flags = sdp->isp_devparam[tgt].actv_flags;
3644		cts.type = CTS_TYPE_CURRENT_SETTINGS;
3645		cts.protocol = PROTO_SCSI;
3646		cts.transport = XPORT_SPI;
3647
3648		scsi = &cts.proto_specific.scsi;
3649		spi = &cts.xport_specific.spi;
3650
3651		if (flags & DPARM_TQING) {
3652			scsi->valid |= CTS_SCSI_VALID_TQ;
3653			scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB;
3654		}
3655
3656		if (flags & DPARM_DISC) {
3657			spi->valid |= CTS_SPI_VALID_DISC;
3658			spi->flags |= CTS_SPI_FLAGS_DISC_ENB;
3659		}
3660		spi->flags |= CTS_SPI_VALID_BUS_WIDTH;
3661		if (flags & DPARM_WIDE) {
3662			spi->bus_width = MSG_EXT_WDTR_BUS_16_BIT;
3663		} else {
3664			spi->bus_width = MSG_EXT_WDTR_BUS_8_BIT;
3665		}
3666		if (flags & DPARM_SYNC) {
3667			spi->valid |= CTS_SPI_VALID_SYNC_RATE;
3668			spi->valid |= CTS_SPI_VALID_SYNC_OFFSET;
3669			spi->sync_period = sdp->isp_devparam[tgt].actv_period;
3670			spi->sync_offset = sdp->isp_devparam[tgt].actv_offset;
3671		}
3672		isp_prt(isp, ISP_LOGDEBUG2, "NEW_TGT_PARAMS bus %d tgt %d period %x offset %x flags %x", bus, tgt, sdp->isp_devparam[tgt].actv_period, sdp->isp_devparam[tgt].actv_offset, flags);
3673		xpt_setup_ccb(&cts.ccb_h, tmppath, 1);
3674		xpt_async(AC_TRANSFER_NEG, tmppath, &cts);
3675		xpt_free_path(tmppath);
3676		break;
3677	}
3678	case ISPASYNC_BUS_RESET:
3679	{
3680		va_start(ap, cmd);
3681		bus = va_arg(ap, int);
3682		va_end(ap);
3683		isp_prt(isp, ISP_LOGINFO, "SCSI bus reset on bus %d detected", bus);
3684		if (IS_FC(isp)) {
3685			xpt_async(AC_BUS_RESET, ISP_FC_PC(isp, bus)->path, NULL);
3686		} else {
3687			xpt_async(AC_BUS_RESET, ISP_SPI_PC(isp, bus)->path, NULL);
3688		}
3689		break;
3690	}
3691	case ISPASYNC_LIP:
3692		if (msg == NULL)
3693			msg = "LIP Received";
3694		/* FALLTHROUGH */
3695	case ISPASYNC_LOOP_RESET:
3696		if (msg == NULL)
3697			msg = "LOOP Reset";
3698		/* FALLTHROUGH */
3699	case ISPASYNC_LOOP_DOWN:
3700		if (msg == NULL)
3701			msg = "LOOP Down";
3702		va_start(ap, cmd);
3703		bus = va_arg(ap, int);
3704		va_end(ap);
3705		isp_fcp_reset_crn(isp, bus, /*tgt*/0, /*tgt_set*/ 0);
3706		isp_loop_changed(isp, bus);
3707		isp_prt(isp, ISP_LOGINFO, "Chan %d %s", bus, msg);
3708		break;
3709	case ISPASYNC_LOOP_UP:
3710		va_start(ap, cmd);
3711		bus = va_arg(ap, int);
3712		va_end(ap);
3713		isp_loop_changed(isp, bus);
3714		isp_prt(isp, ISP_LOGINFO, "Chan %d Loop UP", bus);
3715		break;
3716	case ISPASYNC_DEV_ARRIVED:
3717		va_start(ap, cmd);
3718		bus = va_arg(ap, int);
3719		lp = va_arg(ap, fcportdb_t *);
3720		va_end(ap);
3721		fc = ISP_FC_PC(isp, bus);
3722		tgt = FC_PORTDB_TGT(isp, bus, lp);
3723		isp_gen_role_str(buf, sizeof (buf), lp->prli_word3);
3724		isp_prt(isp, ISP_LOGCONFIG, prom, bus, tgt, lp->port_wwn, lp->portid, lp->handle, buf, "arrived");
3725		if ((FCPARAM(isp, bus)->role & ISP_ROLE_INITIATOR) &&
3726		    (lp->prli_word3 & PRLI_WD3_TARGET_FUNCTION)) {
3727			lp->is_target = 1;
3728			isp_fcp_reset_crn(isp, bus, tgt, /*tgt_set*/ 1);
3729			isp_make_here(isp, lp, bus, tgt);
3730		}
3731		if ((FCPARAM(isp, bus)->role & ISP_ROLE_TARGET) &&
3732		    (lp->prli_word3 & PRLI_WD3_INITIATOR_FUNCTION)) {
3733			lp->is_initiator = 1;
3734			ac.contract_number = AC_CONTRACT_DEV_CHG;
3735			adc = (struct ac_device_changed *) ac.contract_data;
3736			adc->wwpn = lp->port_wwn;
3737			adc->port = lp->portid;
3738			adc->target = tgt;
3739			adc->arrived = 1;
3740			xpt_async(AC_CONTRACT, fc->path, &ac);
3741		}
3742		break;
3743	case ISPASYNC_DEV_CHANGED:
3744		va_start(ap, cmd);
3745		bus = va_arg(ap, int);
3746		lp = va_arg(ap, fcportdb_t *);
3747		va_end(ap);
3748		fc = ISP_FC_PC(isp, bus);
3749		tgt = FC_PORTDB_TGT(isp, bus, lp);
3750		isp_gen_role_str(buf, sizeof (buf), lp->new_prli_word3);
3751		isp_prt(isp, ISP_LOGCONFIG, prom, bus, tgt, lp->port_wwn, lp->new_portid, lp->handle, buf, "changed");
3752changed:
3753		if (lp->is_target !=
3754		    ((FCPARAM(isp, bus)->role & ISP_ROLE_INITIATOR) &&
3755		     (lp->new_prli_word3 & PRLI_WD3_TARGET_FUNCTION))) {
3756			lp->is_target = !lp->is_target;
3757			if (lp->is_target) {
3758				isp_fcp_reset_crn(isp, bus, tgt, /*tgt_set*/ 1);
3759				isp_make_here(isp, lp, bus, tgt);
3760			} else {
3761				isp_make_gone(isp, lp, bus, tgt);
3762				isp_fcp_reset_crn(isp, bus, tgt, /*tgt_set*/ 1);
3763			}
3764		}
3765		if (lp->is_initiator !=
3766		    ((FCPARAM(isp, bus)->role & ISP_ROLE_TARGET) &&
3767		     (lp->new_prli_word3 & PRLI_WD3_INITIATOR_FUNCTION))) {
3768			lp->is_initiator = !lp->is_initiator;
3769			ac.contract_number = AC_CONTRACT_DEV_CHG;
3770			adc = (struct ac_device_changed *) ac.contract_data;
3771			adc->wwpn = lp->port_wwn;
3772			adc->port = lp->portid;
3773			adc->target = tgt;
3774			adc->arrived = lp->is_initiator;
3775			xpt_async(AC_CONTRACT, fc->path, &ac);
3776		}
3777		break;
3778	case ISPASYNC_DEV_STAYED:
3779		va_start(ap, cmd);
3780		bus = va_arg(ap, int);
3781		lp = va_arg(ap, fcportdb_t *);
3782		va_end(ap);
3783		fc = ISP_FC_PC(isp, bus);
3784		tgt = FC_PORTDB_TGT(isp, bus, lp);
3785		isp_gen_role_str(buf, sizeof (buf), lp->prli_word3);
3786		isp_prt(isp, ISP_LOGCONFIG, prom, bus, tgt, lp->port_wwn, lp->portid, lp->handle, buf, "stayed");
3787		goto changed;
3788	case ISPASYNC_DEV_GONE:
3789		va_start(ap, cmd);
3790		bus = va_arg(ap, int);
3791		lp = va_arg(ap, fcportdb_t *);
3792		va_end(ap);
3793		fc = ISP_FC_PC(isp, bus);
3794		tgt = FC_PORTDB_TGT(isp, bus, lp);
3795		/*
3796		 * If this has a virtual target or initiator set the isp_gdt
3797		 * timer running on it to delay its departure.
3798		 */
3799		isp_gen_role_str(buf, sizeof (buf), lp->prli_word3);
3800		if (lp->is_target || lp->is_initiator) {
3801			lp->state = FC_PORTDB_STATE_ZOMBIE;
3802			lp->gone_timer = fc->gone_device_time;
3803			isp_prt(isp, ISP_LOGCONFIG, prom, bus, tgt, lp->port_wwn, lp->portid, lp->handle, buf, "gone zombie");
3804			if (fc->ready && !callout_active(&fc->gdt)) {
3805				isp_prt(isp, ISP_LOG_SANCFG|ISP_LOGDEBUG0, "Chan %d Starting Gone Device Timer with %u seconds time now %lu", bus, lp->gone_timer, (unsigned long)time_uptime);
3806				callout_reset(&fc->gdt, hz, isp_gdt, fc);
3807			}
3808			break;
3809		}
3810		isp_prt(isp, ISP_LOGCONFIG, prom, bus, tgt, lp->port_wwn, lp->portid, lp->handle, buf, "gone");
3811		break;
3812	case ISPASYNC_CHANGE_NOTIFY:
3813	{
3814		char *msg;
3815		int evt, nphdl, nlstate, portid, reason;
3816
3817		va_start(ap, cmd);
3818		bus = va_arg(ap, int);
3819		evt = va_arg(ap, int);
3820		if (evt == ISPASYNC_CHANGE_PDB) {
3821			nphdl = va_arg(ap, int);
3822			nlstate = va_arg(ap, int);
3823			reason = va_arg(ap, int);
3824		} else if (evt == ISPASYNC_CHANGE_SNS) {
3825			portid = va_arg(ap, int);
3826		} else {
3827			nphdl = NIL_HANDLE;
3828			nlstate = reason = 0;
3829		}
3830		va_end(ap);
3831		fc = ISP_FC_PC(isp, bus);
3832
3833		if (evt == ISPASYNC_CHANGE_PDB) {
3834			msg = "Port Database Changed";
3835			isp_prt(isp, ISP_LOGINFO,
3836			    "Chan %d %s (nphdl 0x%x state 0x%x reason 0x%x)",
3837			    bus, msg, nphdl, nlstate, reason);
3838		} else if (evt == ISPASYNC_CHANGE_SNS) {
3839			msg = "Name Server Database Changed";
3840			isp_prt(isp, ISP_LOGINFO, "Chan %d %s (PortID 0x%06x)",
3841			    bus, msg, portid);
3842		} else {
3843			msg = "Other Change Notify";
3844			isp_prt(isp, ISP_LOGINFO, "Chan %d %s", bus, msg);
3845		}
3846		isp_loop_changed(isp, bus);
3847		break;
3848	}
3849#ifdef	ISP_TARGET_MODE
3850	case ISPASYNC_TARGET_NOTIFY:
3851	{
3852		isp_notify_t *notify;
3853		va_start(ap, cmd);
3854		notify = va_arg(ap, isp_notify_t *);
3855		va_end(ap);
3856		switch (notify->nt_ncode) {
3857		case NT_ABORT_TASK:
3858		case NT_ABORT_TASK_SET:
3859		case NT_CLEAR_ACA:
3860		case NT_CLEAR_TASK_SET:
3861		case NT_LUN_RESET:
3862		case NT_TARGET_RESET:
3863		case NT_QUERY_TASK_SET:
3864		case NT_QUERY_ASYNC_EVENT:
3865			/*
3866			 * These are task management functions.
3867			 */
3868			isp_handle_platform_target_tmf(isp, notify);
3869			break;
3870		case NT_BUS_RESET:
3871		case NT_LIP_RESET:
3872		case NT_LINK_UP:
3873		case NT_LINK_DOWN:
3874		case NT_HBA_RESET:
3875			/*
3876			 * No action need be taken here.
3877			 */
3878			break;
3879		case NT_GLOBAL_LOGOUT:
3880		case NT_LOGOUT:
3881			/*
3882			 * This is device arrival/departure notification
3883			 */
3884			isp_handle_platform_target_notify_ack(isp, notify, 0);
3885			break;
3886		case NT_SRR:
3887			isp_handle_platform_srr(isp, notify);
3888			break;
3889		default:
3890			isp_prt(isp, ISP_LOGALL, "target notify code 0x%x", notify->nt_ncode);
3891			isp_handle_platform_target_notify_ack(isp, notify, 0);
3892			break;
3893		}
3894		break;
3895	}
3896	case ISPASYNC_TARGET_NOTIFY_ACK:
3897	{
3898		void *inot;
3899		va_start(ap, cmd);
3900		inot = va_arg(ap, void *);
3901		va_end(ap);
3902		if (isp_notify_ack(isp, inot)) {
3903			isp_tna_t *tp = malloc(sizeof (*tp), M_DEVBUF, M_NOWAIT);
3904			if (tp) {
3905				tp->isp = isp;
3906				memcpy(tp->data, inot, sizeof (tp->data));
3907				tp->not = tp->data;
3908				callout_init_mtx(&tp->timer, &isp->isp_lock, 0);
3909				callout_reset(&tp->timer, 5,
3910				    isp_refire_notify_ack, tp);
3911			} else {
3912				isp_prt(isp, ISP_LOGERR, "you lose- cannot allocate a notify refire");
3913			}
3914		}
3915		break;
3916	}
3917	case ISPASYNC_TARGET_ACTION:
3918	{
3919		isphdr_t *hp;
3920
3921		va_start(ap, cmd);
3922		hp = va_arg(ap, isphdr_t *);
3923		va_end(ap);
3924		switch (hp->rqs_entry_type) {
3925		case RQSTYPE_ATIO:
3926			isp_handle_platform_atio7(isp, (at7_entry_t *) hp);
3927			break;
3928		case RQSTYPE_ATIO2:
3929			isp_handle_platform_atio2(isp, (at2_entry_t *) hp);
3930			break;
3931		case RQSTYPE_CTIO7:
3932		case RQSTYPE_CTIO3:
3933		case RQSTYPE_CTIO2:
3934		case RQSTYPE_CTIO:
3935			isp_handle_platform_ctio(isp, hp);
3936			break;
3937		default:
3938			isp_prt(isp, ISP_LOGWARN, "%s: unhandled target action 0x%x",
3939			    __func__, hp->rqs_entry_type);
3940			break;
3941		}
3942		break;
3943	}
3944#endif
3945	case ISPASYNC_FW_CRASH:
3946	{
3947		uint16_t mbox1, mbox6;
3948		mbox1 = ISP_READ(isp, OUTMAILBOX1);
3949		if (IS_DUALBUS(isp)) {
3950			mbox6 = ISP_READ(isp, OUTMAILBOX6);
3951		} else {
3952			mbox6 = 0;
3953		}
3954		isp_prt(isp, ISP_LOGERR, "Internal Firmware Error on bus %d @ RISC Address 0x%x", mbox6, mbox1);
3955#if 0
3956		mbox1 = isp->isp_osinfo.mbox_sleep_ok;
3957		isp->isp_osinfo.mbox_sleep_ok = 0;
3958		isp_reinit(isp, 1);
3959		isp->isp_osinfo.mbox_sleep_ok = mbox1;
3960		isp_async(isp, ISPASYNC_FW_RESTARTED, NULL);
3961#endif
3962		break;
3963	}
3964	default:
3965		isp_prt(isp, ISP_LOGERR, "unknown isp_async event %d", cmd);
3966		break;
3967	}
3968}
3969
3970uint64_t
3971isp_default_wwn(ispsoftc_t * isp, int chan, int isactive, int iswwnn)
3972{
3973	uint64_t seed;
3974	struct isp_fc *fc = ISP_FC_PC(isp, chan);
3975
3976	/* First try to use explicitly configured WWNs. */
3977	seed = iswwnn ? fc->def_wwnn : fc->def_wwpn;
3978	if (seed)
3979		return (seed);
3980
3981	/* Otherwise try to use WWNs from NVRAM. */
3982	if (isactive) {
3983		seed = iswwnn ? FCPARAM(isp, chan)->isp_wwnn_nvram :
3984		    FCPARAM(isp, chan)->isp_wwpn_nvram;
3985		if (seed)
3986			return (seed);
3987	}
3988
3989	/* If still no WWNs, try to steal them from the first channel. */
3990	if (chan > 0) {
3991		seed = iswwnn ? ISP_FC_PC(isp, 0)->def_wwnn :
3992		    ISP_FC_PC(isp, 0)->def_wwpn;
3993		if (seed == 0) {
3994			seed = iswwnn ? FCPARAM(isp, 0)->isp_wwnn_nvram :
3995			    FCPARAM(isp, 0)->isp_wwpn_nvram;
3996		}
3997	}
3998
3999	/* If still nothing -- improvise. */
4000	if (seed == 0) {
4001		seed = 0x400000007F000000ull + device_get_unit(isp->isp_dev);
4002		if (!iswwnn)
4003			seed ^= 0x0100000000000000ULL;
4004	}
4005
4006	/* For additional channels we have to improvise even more. */
4007	if (!iswwnn && chan > 0) {
4008		/*
4009		 * We'll stick our channel number plus one first into bits
4010		 * 57..59 and thence into bits 52..55 which allows for 8 bits
4011		 * of channel which is enough for our maximum of 255 channels.
4012		 */
4013		seed ^= 0x0100000000000000ULL;
4014		seed ^= ((uint64_t) (chan + 1) & 0xf) << 56;
4015		seed ^= ((uint64_t) ((chan + 1) >> 4) & 0xf) << 52;
4016	}
4017	return (seed);
4018}
4019
4020void
4021isp_prt(ispsoftc_t *isp, int level, const char *fmt, ...)
4022{
4023	int loc;
4024	char lbuf[200];
4025	va_list ap;
4026
4027	if (level != ISP_LOGALL && (level & isp->isp_dblev) == 0) {
4028		return;
4029	}
4030	snprintf(lbuf, sizeof (lbuf), "%s: ", device_get_nameunit(isp->isp_dev));
4031	loc = strlen(lbuf);
4032	va_start(ap, fmt);
4033	vsnprintf(&lbuf[loc], sizeof (lbuf) - loc - 1, fmt, ap);
4034	va_end(ap);
4035	printf("%s\n", lbuf);
4036}
4037
4038void
4039isp_xs_prt(ispsoftc_t *isp, XS_T *xs, int level, const char *fmt, ...)
4040{
4041	va_list ap;
4042	if (level != ISP_LOGALL && (level & isp->isp_dblev) == 0) {
4043		return;
4044	}
4045	xpt_print_path(xs->ccb_h.path);
4046	va_start(ap, fmt);
4047	vprintf(fmt, ap);
4048	va_end(ap);
4049	printf("\n");
4050}
4051
4052uint64_t
4053isp_nanotime_sub(struct timespec *b, struct timespec *a)
4054{
4055	uint64_t elapsed;
4056	struct timespec x = *b;
4057	timespecsub(&x, a);
4058	elapsed = GET_NANOSEC(&x);
4059	if (elapsed == 0)
4060		elapsed++;
4061	return (elapsed);
4062}
4063
4064int
4065isp_mbox_acquire(ispsoftc_t *isp)
4066{
4067	if (isp->isp_osinfo.mboxbsy) {
4068		return (1);
4069	} else {
4070		isp->isp_osinfo.mboxcmd_done = 0;
4071		isp->isp_osinfo.mboxbsy = 1;
4072		return (0);
4073	}
4074}
4075
4076void
4077isp_mbox_wait_complete(ispsoftc_t *isp, mbreg_t *mbp)
4078{
4079	u_int t, to;
4080
4081	to = (mbp->timeout == 0) ? MBCMD_DEFAULT_TIMEOUT : mbp->timeout;
4082	if (isp->isp_osinfo.mbox_sleep_ok) {
4083		isp->isp_osinfo.mbox_sleep_ok = 0;
4084		isp->isp_osinfo.mbox_sleeping = 1;
4085		msleep_sbt(&isp->isp_osinfo.mboxcmd_done, &isp->isp_osinfo.lock,
4086		    PRIBIO, "ispmbx_sleep", to * SBT_1US, 0, 0);
4087		isp->isp_osinfo.mbox_sleep_ok = 1;
4088		isp->isp_osinfo.mbox_sleeping = 0;
4089	} else {
4090		for (t = 0; t < to; t += 100) {
4091			if (isp->isp_osinfo.mboxcmd_done)
4092				break;
4093			ISP_RUN_ISR(isp);
4094			if (isp->isp_osinfo.mboxcmd_done)
4095				break;
4096			ISP_DELAY(100);
4097		}
4098	}
4099	if (isp->isp_osinfo.mboxcmd_done == 0) {
4100		isp_prt(isp, ISP_LOGWARN, "%s Mailbox Command (0x%x) Timeout (%uus) (%s:%d)",
4101		    isp->isp_osinfo.mbox_sleep_ok? "Interrupting" : "Polled",
4102		    isp->isp_lastmbxcmd, to, mbp->func, mbp->lineno);
4103		mbp->param[0] = MBOX_TIMEOUT;
4104		isp->isp_osinfo.mboxcmd_done = 1;
4105	}
4106}
4107
4108void
4109isp_mbox_notify_done(ispsoftc_t *isp)
4110{
4111	isp->isp_osinfo.mboxcmd_done = 1;
4112	if (isp->isp_osinfo.mbox_sleeping)
4113		wakeup(&isp->isp_osinfo.mboxcmd_done);
4114}
4115
4116void
4117isp_mbox_release(ispsoftc_t *isp)
4118{
4119	isp->isp_osinfo.mboxbsy = 0;
4120}
4121
4122int
4123isp_fc_scratch_acquire(ispsoftc_t *isp, int chan)
4124{
4125	int ret = 0;
4126	if (isp->isp_osinfo.pc.fc[chan].fcbsy) {
4127		ret = -1;
4128	} else {
4129		isp->isp_osinfo.pc.fc[chan].fcbsy = 1;
4130	}
4131	return (ret);
4132}
4133
4134int
4135isp_mstohz(int ms)
4136{
4137	int hz;
4138	struct timeval t;
4139	t.tv_sec = ms / 1000;
4140	t.tv_usec = (ms % 1000) * 1000;
4141	hz = tvtohz(&t);
4142	if (hz < 0) {
4143		hz = 0x7fffffff;
4144	}
4145	if (hz == 0) {
4146		hz = 1;
4147	}
4148	return (hz);
4149}
4150
4151void
4152isp_platform_intr(void *arg)
4153{
4154	ispsoftc_t *isp = arg;
4155
4156	ISP_LOCK(isp);
4157	ISP_RUN_ISR(isp);
4158	ISP_UNLOCK(isp);
4159}
4160
4161void
4162isp_platform_intr_resp(void *arg)
4163{
4164	ispsoftc_t *isp = arg;
4165
4166	ISP_LOCK(isp);
4167	isp_intr_respq(isp);
4168	ISP_UNLOCK(isp);
4169
4170	/* We have handshake enabled, so explicitly complete interrupt */
4171	ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_CLEAR_RISC_INT);
4172}
4173
4174void
4175isp_platform_intr_atio(void *arg)
4176{
4177	ispsoftc_t *isp = arg;
4178
4179	ISP_LOCK(isp);
4180#ifdef	ISP_TARGET_MODE
4181	isp_intr_atioq(isp);
4182#endif
4183	ISP_UNLOCK(isp);
4184
4185	/* We have handshake enabled, so explicitly complete interrupt */
4186	ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_CLEAR_RISC_INT);
4187}
4188
4189void
4190isp_common_dmateardown(ispsoftc_t *isp, struct ccb_scsiio *csio, uint32_t hdl)
4191{
4192	if ((csio->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) {
4193		bus_dmamap_sync(isp->isp_osinfo.dmat, PISP_PCMD(csio)->dmap, BUS_DMASYNC_POSTREAD);
4194	} else {
4195		bus_dmamap_sync(isp->isp_osinfo.dmat, PISP_PCMD(csio)->dmap, BUS_DMASYNC_POSTWRITE);
4196	}
4197	bus_dmamap_unload(isp->isp_osinfo.dmat, PISP_PCMD(csio)->dmap);
4198}
4199
4200/*
4201 * Reset the command reference number for all LUNs on a specific target
4202 * (needed when a target arrives again) or for all targets on a port
4203 * (needed for events like a LIP).
4204 */
4205void
4206isp_fcp_reset_crn(ispsoftc_t *isp, int chan, uint32_t tgt, int tgt_set)
4207{
4208	struct isp_fc *fc = ISP_FC_PC(isp, chan);
4209	struct isp_nexus *nxp;
4210	int i;
4211
4212	if (tgt_set == 0)
4213		isp_prt(isp, ISP_LOGDEBUG0,
4214		    "Chan %d resetting CRN on all targets", chan);
4215	else
4216		isp_prt(isp, ISP_LOGDEBUG0,
4217		    "Chan %d resetting CRN on target %u", chan, tgt);
4218
4219	for (i = 0; i < NEXUS_HASH_WIDTH; i++) {
4220		for (nxp = fc->nexus_hash[i]; nxp != NULL; nxp = nxp->next) {
4221			if (tgt_set == 0 || tgt == nxp->tgt)
4222				nxp->crnseed = 0;
4223		}
4224	}
4225}
4226
4227int
4228isp_fcp_next_crn(ispsoftc_t *isp, uint8_t *crnp, XS_T *cmd)
4229{
4230	lun_id_t lun;
4231	uint32_t chan, tgt;
4232	struct isp_fc *fc;
4233	struct isp_nexus *nxp;
4234	int idx;
4235
4236	if (IS_2100(isp))
4237		return (0);
4238
4239	chan = XS_CHANNEL(cmd);
4240	tgt = XS_TGT(cmd);
4241	lun = XS_LUN(cmd);
4242	fc = &isp->isp_osinfo.pc.fc[chan];
4243	idx = NEXUS_HASH(tgt, lun);
4244	nxp = fc->nexus_hash[idx];
4245
4246	while (nxp) {
4247		if (nxp->tgt == tgt && nxp->lun == lun)
4248			break;
4249		nxp = nxp->next;
4250	}
4251	if (nxp == NULL) {
4252		nxp = fc->nexus_free_list;
4253		if (nxp == NULL) {
4254			nxp = malloc(sizeof (struct isp_nexus), M_DEVBUF, M_ZERO|M_NOWAIT);
4255			if (nxp == NULL) {
4256				return (-1);
4257			}
4258		} else {
4259			fc->nexus_free_list = nxp->next;
4260		}
4261		nxp->tgt = tgt;
4262		nxp->lun = lun;
4263		nxp->next = fc->nexus_hash[idx];
4264		fc->nexus_hash[idx] = nxp;
4265	}
4266	if (nxp->crnseed == 0)
4267		nxp->crnseed = 1;
4268	PISP_PCMD(cmd)->crn = nxp->crnseed;
4269	*crnp = nxp->crnseed++;
4270	return (0);
4271}
4272
4273/*
4274 * We enter with the lock held
4275 */
4276void
4277isp_timer(void *arg)
4278{
4279	ispsoftc_t *isp = arg;
4280#ifdef	ISP_TARGET_MODE
4281	isp_tmcmd_restart(isp);
4282#endif
4283	callout_reset(&isp->isp_osinfo.tmo, isp_timer_count, isp_timer, isp);
4284}
4285
4286isp_ecmd_t *
4287isp_get_ecmd(ispsoftc_t *isp)
4288{
4289	isp_ecmd_t *ecmd = isp->isp_osinfo.ecmd_free;
4290	if (ecmd) {
4291		isp->isp_osinfo.ecmd_free = ecmd->next;
4292	}
4293	return (ecmd);
4294}
4295
4296void
4297isp_put_ecmd(ispsoftc_t *isp, isp_ecmd_t *ecmd)
4298{
4299	ecmd->next = isp->isp_osinfo.ecmd_free;
4300	isp->isp_osinfo.ecmd_free = ecmd;
4301}
4302