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