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