xref: /freebsd/sys/dev/isp/isp_freebsd.c (revision 91c878a6935c5c2e99866eb267e5bc3028bf6d2f)
1 /*-
2  *
3  * Copyright (c) 1997-2006 by Matthew Jacob
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice immediately at the beginning of the file, without modification,
11  *    this list of conditions, and the following disclaimer.
12  * 2. The name of the author may not be used to endorse or promote products
13  *    derived from this software without specific prior written permission.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
19  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25  * SUCH DAMAGE.
26  */
27 
28 /*
29  * Platform (FreeBSD) dependent common attachment code for Qlogic adapters.
30  */
31 #include <sys/cdefs.h>
32 __FBSDID("$FreeBSD$");
33 #include <dev/isp/isp_freebsd.h>
34 #include <sys/unistd.h>
35 #include <sys/kthread.h>
36 #include <machine/stdarg.h>	/* for use by isp_prt below */
37 #include <sys/conf.h>
38 #include <sys/module.h>
39 #include <sys/ioccom.h>
40 #include <dev/isp/isp_ioctl.h>
41 #if	__FreeBSD_version >= 500000
42 #include <sys/sysctl.h>
43 #endif
44 
45 
46 MODULE_VERSION(isp, 1);
47 MODULE_DEPEND(isp, cam, 1, 1, 1);
48 int isp_announced = 0;
49 
50 static d_ioctl_t ispioctl;
51 static void isp_intr_enable(void *);
52 static void isp_cam_async(void *, uint32_t, struct cam_path *, void *);
53 static void isp_poll(struct cam_sim *);
54 static timeout_t isp_watchdog;
55 static void isp_kthread(void *);
56 static void isp_action(struct cam_sim *, union ccb *);
57 
58 #if __FreeBSD_version < 700000
59 ispfwfunc *isp_get_firmware_p = NULL;
60 #endif
61 
62 #if __FreeBSD_version < 500000
63 #define ISP_CDEV_MAJOR	248
64 static struct cdevsw isp_cdevsw = {
65 	/* open */	nullopen,
66 	/* close */	nullclose,
67 	/* read */	noread,
68 	/* write */	nowrite,
69 	/* ioctl */	ispioctl,
70 	/* poll */	nopoll,
71 	/* mmap */	nommap,
72 	/* strategy */	nostrategy,
73 	/* name */	"isp",
74 	/* maj */	ISP_CDEV_MAJOR,
75 	/* dump */	nodump,
76 	/* psize */	nopsize,
77 	/* flags */	D_TAPE,
78 };
79 #define	isp_sysctl_update(x)	do { ; } while (0)
80 #else
81 static struct cdevsw isp_cdevsw = {
82 	.d_version =	D_VERSION,
83 	.d_flags =	D_NEEDGIANT,
84 	.d_ioctl =	ispioctl,
85 	.d_name =	"isp",
86 };
87 static void isp_sysctl_update(ispsoftc_t *);
88 #endif
89 
90 static ispsoftc_t *isplist = NULL;
91 
92 void
93 isp_attach(ispsoftc_t *isp)
94 {
95 	int primary, secondary;
96 	struct ccb_setasync csa;
97 	struct cam_devq *devq;
98 	struct cam_sim *sim;
99 	struct cam_path *path;
100 
101 	/*
102 	 * Establish (in case of 12X0) which bus is the primary.
103 	 */
104 
105 	primary = 0;
106 	secondary = 1;
107 
108 	/*
109 	 * Create the device queue for our SIM(s).
110 	 */
111 	devq = cam_simq_alloc(isp->isp_maxcmds);
112 	if (devq == NULL) {
113 		return;
114 	}
115 
116 	/*
117 	 * Construct our SIM entry.
118 	 */
119 	ISPLOCK_2_CAMLOCK(isp);
120 	sim = cam_sim_alloc(isp_action, isp_poll, "isp", isp,
121 	    device_get_unit(isp->isp_dev), 1, isp->isp_maxcmds, devq);
122 	if (sim == NULL) {
123 		cam_simq_free(devq);
124 		CAMLOCK_2_ISPLOCK(isp);
125 		return;
126 	}
127 	CAMLOCK_2_ISPLOCK(isp);
128 
129 	isp->isp_osinfo.ehook.ich_func = isp_intr_enable;
130 	isp->isp_osinfo.ehook.ich_arg = isp;
131 	ISPLOCK_2_CAMLOCK(isp);
132 	if (config_intrhook_establish(&isp->isp_osinfo.ehook) != 0) {
133 		cam_sim_free(sim, TRUE);
134 		CAMLOCK_2_ISPLOCK(isp);
135 		isp_prt(isp, ISP_LOGERR,
136 		    "could not establish interrupt enable hook");
137 		return;
138 	}
139 
140 	if (xpt_bus_register(sim, primary) != CAM_SUCCESS) {
141 		cam_sim_free(sim, TRUE);
142 		CAMLOCK_2_ISPLOCK(isp);
143 		return;
144 	}
145 
146 	if (xpt_create_path(&path, NULL, cam_sim_path(sim),
147 	    CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
148 		xpt_bus_deregister(cam_sim_path(sim));
149 		cam_sim_free(sim, TRUE);
150 		config_intrhook_disestablish(&isp->isp_osinfo.ehook);
151 		CAMLOCK_2_ISPLOCK(isp);
152 		return;
153 	}
154 
155 	xpt_setup_ccb(&csa.ccb_h, path, 5);
156 	csa.ccb_h.func_code = XPT_SASYNC_CB;
157 	csa.event_enable = AC_LOST_DEVICE;
158 	csa.callback = isp_cam_async;
159 	csa.callback_arg = sim;
160 	xpt_action((union ccb *)&csa);
161 	CAMLOCK_2_ISPLOCK(isp);
162 	isp->isp_sim = sim;
163 	isp->isp_path = path;
164 	/*
165 	 * Create a kernel thread for fibre channel instances. We
166 	 * don't have dual channel FC cards.
167 	 */
168 	if (IS_FC(isp)) {
169 		ISPLOCK_2_CAMLOCK(isp);
170 #if __FreeBSD_version >= 500000
171 		/* XXX: LOCK VIOLATION */
172 		cv_init(&isp->isp_osinfo.kthread_cv, "isp_kthread_cv");
173 		if (kthread_create(isp_kthread, isp, &isp->isp_osinfo.kproc,
174 		    RFHIGHPID, 0, "%s: fc_thrd",
175 		    device_get_nameunit(isp->isp_dev)))
176 #else
177 		if (kthread_create(isp_kthread, isp, &isp->isp_osinfo.kproc,
178 		    "%s: fc_thrd", device_get_nameunit(isp->isp_dev)))
179 #endif
180 		{
181 			xpt_bus_deregister(cam_sim_path(sim));
182 			cam_sim_free(sim, TRUE);
183 			config_intrhook_disestablish(&isp->isp_osinfo.ehook);
184 			CAMLOCK_2_ISPLOCK(isp);
185 			isp_prt(isp, ISP_LOGERR, "could not create kthread");
186 			return;
187 		}
188 		CAMLOCK_2_ISPLOCK(isp);
189 	}
190 
191 
192 	/*
193 	 * If we have a second channel, construct SIM entry for that.
194 	 */
195 	if (IS_DUALBUS(isp)) {
196 		ISPLOCK_2_CAMLOCK(isp);
197 		sim = cam_sim_alloc(isp_action, isp_poll, "isp", isp,
198 		    device_get_unit(isp->isp_dev), 1, isp->isp_maxcmds, devq);
199 		if (sim == NULL) {
200 			xpt_bus_deregister(cam_sim_path(isp->isp_sim));
201 			xpt_free_path(isp->isp_path);
202 			cam_simq_free(devq);
203 			config_intrhook_disestablish(&isp->isp_osinfo.ehook);
204 			return;
205 		}
206 		if (xpt_bus_register(sim, secondary) != CAM_SUCCESS) {
207 			xpt_bus_deregister(cam_sim_path(isp->isp_sim));
208 			xpt_free_path(isp->isp_path);
209 			cam_sim_free(sim, TRUE);
210 			config_intrhook_disestablish(&isp->isp_osinfo.ehook);
211 			CAMLOCK_2_ISPLOCK(isp);
212 			return;
213 		}
214 
215 		if (xpt_create_path(&path, NULL, cam_sim_path(sim),
216 		    CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
217 			xpt_bus_deregister(cam_sim_path(isp->isp_sim));
218 			xpt_free_path(isp->isp_path);
219 			xpt_bus_deregister(cam_sim_path(sim));
220 			cam_sim_free(sim, TRUE);
221 			config_intrhook_disestablish(&isp->isp_osinfo.ehook);
222 			CAMLOCK_2_ISPLOCK(isp);
223 			return;
224 		}
225 
226 		xpt_setup_ccb(&csa.ccb_h, path, 5);
227 		csa.ccb_h.func_code = XPT_SASYNC_CB;
228 		csa.event_enable = AC_LOST_DEVICE;
229 		csa.callback = isp_cam_async;
230 		csa.callback_arg = sim;
231 		xpt_action((union ccb *)&csa);
232 		CAMLOCK_2_ISPLOCK(isp);
233 		isp->isp_sim2 = sim;
234 		isp->isp_path2 = path;
235 	}
236 
237 	/*
238 	 * Create device nodes
239 	 */
240 	(void) make_dev(&isp_cdevsw, device_get_unit(isp->isp_dev), UID_ROOT,
241 	    GID_OPERATOR, 0600, "%s", device_get_nameunit(isp->isp_dev));
242 
243 	if (isp->isp_role != ISP_ROLE_NONE) {
244 		isp->isp_state = ISP_RUNSTATE;
245 		ENABLE_INTS(isp);
246 	}
247 	if (isplist == NULL) {
248 		isplist = isp;
249 	} else {
250 		ispsoftc_t *tmp = isplist;
251 		while (tmp->isp_osinfo.next) {
252 			tmp = tmp->isp_osinfo.next;
253 		}
254 		tmp->isp_osinfo.next = isp;
255 	}
256 	isp_sysctl_update(isp);
257 }
258 
259 static __inline void
260 isp_freeze_loopdown(ispsoftc_t *isp, char *msg)
261 {
262 	if (isp->isp_osinfo.simqfrozen == 0) {
263 		isp_prt(isp, ISP_LOGDEBUG0, "%s: freeze simq (loopdown)", msg);
264 		isp->isp_osinfo.simqfrozen |= SIMQFRZ_LOOPDOWN;
265 		ISPLOCK_2_CAMLOCK(isp);
266 		xpt_freeze_simq(isp->isp_sim, 1);
267 		CAMLOCK_2_ISPLOCK(isp);
268 	} else {
269 		isp_prt(isp, ISP_LOGDEBUG0, "%s: mark frozen (loopdown)", msg);
270 		isp->isp_osinfo.simqfrozen |= SIMQFRZ_LOOPDOWN;
271 	}
272 }
273 
274 
275 #if __FreeBSD_version < 500000
276 #define	_DEV	dev_t
277 #define	_IOP	struct proc
278 #else
279 #define	_IOP	struct thread
280 #define	_DEV	struct cdev *
281 #endif
282 
283 static int
284 ispioctl(_DEV dev, u_long c, caddr_t addr, int flags, _IOP *td)
285 {
286 	ispsoftc_t *isp;
287 	int nr, retval = ENOTTY;
288 
289 	isp = isplist;
290 	while (isp) {
291 		if (minor(dev) == device_get_unit(isp->isp_dev)) {
292 			break;
293 		}
294 		isp = isp->isp_osinfo.next;
295 	}
296 	if (isp == NULL)
297 		return (ENXIO);
298 
299 	switch (c) {
300 #ifdef	ISP_FW_CRASH_DUMP
301 	case ISP_GET_FW_CRASH_DUMP:
302 		if (IS_FC(isp)) {
303 			uint16_t *ptr = FCPARAM(isp)->isp_dump_data;
304 			size_t sz;
305 
306 			retval = 0;
307 			if (IS_2200(isp)) {
308 				sz = QLA2200_RISC_IMAGE_DUMP_SIZE;
309 			} else {
310 				sz = QLA2300_RISC_IMAGE_DUMP_SIZE;
311 			}
312 			ISP_LOCK(isp);
313 			if (ptr && *ptr) {
314 				void *uaddr = *((void **) addr);
315 				if (copyout(ptr, uaddr, sz)) {
316 					retval = EFAULT;
317 				} else {
318 					*ptr = 0;
319 				}
320 			} else {
321 				retval = ENXIO;
322 			}
323 			ISP_UNLOCK(isp);
324 		}
325 		break;
326 	case ISP_FORCE_CRASH_DUMP:
327 		if (IS_FC(isp)) {
328 			ISP_LOCK(isp);
329 			isp_freeze_loopdown(isp,
330 			    "ispioctl(ISP_FORCE_CRASH_DUMP)");
331 			isp_fw_dump(isp);
332 			isp_reinit(isp);
333 			ISP_UNLOCK(isp);
334 			retval = 0;
335 		}
336 		break;
337 #endif
338 	case ISP_SDBLEV:
339 	{
340 		int olddblev = isp->isp_dblev;
341 		isp->isp_dblev = *(int *)addr;
342 		*(int *)addr = olddblev;
343 		retval = 0;
344 		break;
345 	}
346 	case ISP_GETROLE:
347 		*(int *)addr = isp->isp_role;
348 		retval = 0;
349 		break;
350 	case ISP_SETROLE:
351 		nr = *(int *)addr;
352 		if (nr & ~(ISP_ROLE_INITIATOR|ISP_ROLE_TARGET)) {
353 			retval = EINVAL;
354 			break;
355 		}
356 		*(int *)addr = isp->isp_role;
357 		isp->isp_role = nr;
358 		/* FALLTHROUGH */
359 	case ISP_RESETHBA:
360 		ISP_LOCK(isp);
361 		isp_reinit(isp);
362 		ISP_UNLOCK(isp);
363 		retval = 0;
364 		break;
365 	case ISP_RESCAN:
366 		if (IS_FC(isp)) {
367 			ISP_LOCK(isp);
368 			if (isp_fc_runstate(isp, 5 * 1000000)) {
369 				retval = EIO;
370 			} else {
371 				retval = 0;
372 			}
373 			ISP_UNLOCK(isp);
374 		}
375 		break;
376 	case ISP_FC_LIP:
377 		if (IS_FC(isp)) {
378 			ISP_LOCK(isp);
379 			if (isp_control(isp, ISPCTL_SEND_LIP, 0)) {
380 				retval = EIO;
381 			} else {
382 				retval = 0;
383 			}
384 			ISP_UNLOCK(isp);
385 		}
386 		break;
387 	case ISP_FC_GETDINFO:
388 	{
389 		struct isp_fc_device *ifc = (struct isp_fc_device *) addr;
390 		struct lportdb *lp;
391 
392 		if (IS_SCSI(isp)) {
393 			break;
394 		}
395 		if (ifc->loopid < 0 || ifc->loopid >= MAX_FC_TARG) {
396 			retval = EINVAL;
397 			break;
398 		}
399 		ISP_LOCK(isp);
400 		lp = &FCPARAM(isp)->portdb[ifc->loopid];
401 		if (lp->valid) {
402 			ifc->role = lp->roles;
403 			ifc->loopid = lp->loopid;
404 			ifc->portid = lp->portid;
405 			ifc->node_wwn = lp->node_wwn;
406 			ifc->port_wwn = lp->port_wwn;
407 			retval = 0;
408 		} else {
409 			retval = ENODEV;
410 		}
411 		ISP_UNLOCK(isp);
412 		break;
413 	}
414 	case ISP_GET_STATS:
415 	{
416 		isp_stats_t *sp = (isp_stats_t *) addr;
417 
418 		MEMZERO(sp, sizeof (*sp));
419 		sp->isp_stat_version = ISP_STATS_VERSION;
420 		sp->isp_type = isp->isp_type;
421 		sp->isp_revision = isp->isp_revision;
422 		ISP_LOCK(isp);
423 		sp->isp_stats[ISP_INTCNT] = isp->isp_intcnt;
424 		sp->isp_stats[ISP_INTBOGUS] = isp->isp_intbogus;
425 		sp->isp_stats[ISP_INTMBOXC] = isp->isp_intmboxc;
426 		sp->isp_stats[ISP_INGOASYNC] = isp->isp_intoasync;
427 		sp->isp_stats[ISP_RSLTCCMPLT] = isp->isp_rsltccmplt;
428 		sp->isp_stats[ISP_FPHCCMCPLT] = isp->isp_fphccmplt;
429 		sp->isp_stats[ISP_RSCCHIWAT] = isp->isp_rscchiwater;
430 		sp->isp_stats[ISP_FPCCHIWAT] = isp->isp_fpcchiwater;
431 		ISP_UNLOCK(isp);
432 		retval = 0;
433 		break;
434 	}
435 	case ISP_CLR_STATS:
436 		ISP_LOCK(isp);
437 		isp->isp_intcnt = 0;
438 		isp->isp_intbogus = 0;
439 		isp->isp_intmboxc = 0;
440 		isp->isp_intoasync = 0;
441 		isp->isp_rsltccmplt = 0;
442 		isp->isp_fphccmplt = 0;
443 		isp->isp_rscchiwater = 0;
444 		isp->isp_fpcchiwater = 0;
445 		ISP_UNLOCK(isp);
446 		retval = 0;
447 		break;
448 	case ISP_FC_GETHINFO:
449 	{
450 		struct isp_hba_device *hba = (struct isp_hba_device *) addr;
451 		MEMZERO(hba, sizeof (*hba));
452 
453 		hba->fc_fw_major = ISP_FW_MAJORX(isp->isp_fwrev);
454 		hba->fc_fw_minor = ISP_FW_MINORX(isp->isp_fwrev);
455 		hba->fc_fw_micro = ISP_FW_MICROX(isp->isp_fwrev);
456 		if (IS_FC(isp)) {
457 			hba->fc_speed = FCPARAM(isp)->isp_gbspeed;
458 			hba->fc_scsi_supported = 1;
459 			hba->fc_topology = FCPARAM(isp)->isp_topo + 1;
460 			hba->fc_loopid = FCPARAM(isp)->isp_loopid;
461 			hba->nvram_node_wwn = FCPARAM(isp)->isp_nodewwn;
462 			hba->nvram_port_wwn = FCPARAM(isp)->isp_portwwn;
463 			hba->active_node_wwn = ISP_NODEWWN(isp);
464 			hba->active_port_wwn = ISP_PORTWWN(isp);
465 		}
466 		retval = 0;
467 		break;
468 	}
469 	case ISP_GET_FC_PARAM:
470 	{
471 		struct isp_fc_param *f = (struct isp_fc_param *) addr;
472 
473 		if (IS_SCSI(isp)) {
474 			break;
475 		}
476 		f->parameter = 0;
477 		if (strcmp(f->param_name, "framelength") == 0) {
478 			f->parameter = FCPARAM(isp)->isp_maxfrmlen;
479 			retval = 0;
480 			break;
481 		}
482 		if (strcmp(f->param_name, "exec_throttle") == 0) {
483 			f->parameter = FCPARAM(isp)->isp_execthrottle;
484 			retval = 0;
485 			break;
486 		}
487 		if (strcmp(f->param_name, "fullduplex") == 0) {
488 			if (FCPARAM(isp)->isp_fwoptions & ICBOPT_FULL_DUPLEX)
489 				f->parameter = 1;
490 			retval = 0;
491 			break;
492 		}
493 		if (strcmp(f->param_name, "loopid") == 0) {
494 			f->parameter = FCPARAM(isp)->isp_loopid;
495 			retval = 0;
496 			break;
497 		}
498 		retval = EINVAL;
499 		break;
500 	}
501 	case ISP_SET_FC_PARAM:
502 	{
503 		struct isp_fc_param *f = (struct isp_fc_param *) addr;
504 		uint32_t param = f->parameter;
505 
506 		if (IS_SCSI(isp)) {
507 			break;
508 		}
509 		f->parameter = 0;
510 		if (strcmp(f->param_name, "framelength") == 0) {
511 			if (param != 512 && param != 1024 && param != 1024) {
512 				retval = EINVAL;
513 				break;
514 			}
515 			FCPARAM(isp)->isp_maxfrmlen = param;
516 			retval = 0;
517 			break;
518 		}
519 		if (strcmp(f->param_name, "exec_throttle") == 0) {
520 			if (param < 16 || param > 255) {
521 				retval = EINVAL;
522 				break;
523 			}
524 			FCPARAM(isp)->isp_execthrottle = param;
525 			retval = 0;
526 			break;
527 		}
528 		if (strcmp(f->param_name, "fullduplex") == 0) {
529 			if (param != 0 && param != 1) {
530 				retval = EINVAL;
531 				break;
532 			}
533 			if (param) {
534 				FCPARAM(isp)->isp_fwoptions |=
535 				    ICBOPT_FULL_DUPLEX;
536 			} else {
537 				FCPARAM(isp)->isp_fwoptions &=
538 				    ~ICBOPT_FULL_DUPLEX;
539 			}
540 			retval = 0;
541 			break;
542 		}
543 		if (strcmp(f->param_name, "loopid") == 0) {
544 			if (param < 0 || param > 125) {
545 				retval = EINVAL;
546 				break;
547 			}
548 			FCPARAM(isp)->isp_loopid = param;
549 			retval = 0;
550 			break;
551 		}
552 		retval = EINVAL;
553 		break;
554 	}
555 	case ISP_TSK_MGMT:
556 	{
557 		int needmarker;
558 		struct isp_fc_tsk_mgmt *fct = (struct isp_fc_tsk_mgmt *) addr;
559 		uint16_t loopid;
560 		mbreg_t mbs;
561 
562 		if (IS_SCSI(isp)) {
563 			break;
564 		}
565 
566 		memset(&mbs, 0, sizeof (mbs));
567 		needmarker = retval = 0;
568 		loopid = fct->loopid;
569 		if (IS_2KLOGIN(isp) == 0) {
570 			loopid <<= 8;
571 		}
572 		switch (fct->action) {
573 		case IPT_CLEAR_ACA:
574 			mbs.param[0] = MBOX_CLEAR_ACA;
575 			mbs.param[1] = loopid;
576 			mbs.param[2] = fct->lun;
577 			break;
578 		case IPT_TARGET_RESET:
579 			mbs.param[0] = MBOX_TARGET_RESET;
580 			mbs.param[1] = loopid;
581 			needmarker = 1;
582 			break;
583 		case IPT_LUN_RESET:
584 			mbs.param[0] = MBOX_LUN_RESET;
585 			mbs.param[1] = loopid;
586 			mbs.param[2] = fct->lun;
587 			needmarker = 1;
588 			break;
589 		case IPT_CLEAR_TASK_SET:
590 			mbs.param[0] = MBOX_CLEAR_TASK_SET;
591 			mbs.param[1] = loopid;
592 			mbs.param[2] = fct->lun;
593 			needmarker = 1;
594 			break;
595 		case IPT_ABORT_TASK_SET:
596 			mbs.param[0] = MBOX_ABORT_TASK_SET;
597 			mbs.param[1] = loopid;
598 			mbs.param[2] = fct->lun;
599 			needmarker = 1;
600 			break;
601 		default:
602 			retval = EINVAL;
603 			break;
604 		}
605 		if (retval == 0) {
606 			ISP_LOCK(isp);
607 			if (needmarker) {
608 				isp->isp_sendmarker |= 1;
609 			}
610 			retval = isp_control(isp, ISPCTL_RUN_MBOXCMD, &mbs);
611 			ISP_UNLOCK(isp);
612 			if (retval)
613 				retval = EIO;
614 		}
615 		break;
616 	}
617 	default:
618 		break;
619 	}
620 	return (retval);
621 }
622 
623 #if __FreeBSD_version >= 500000
624 static void
625 isp_sysctl_update(ispsoftc_t *isp)
626 {
627 	struct sysctl_ctx_list *ctx =
628 	    device_get_sysctl_ctx(isp->isp_osinfo.dev);
629 	struct sysctl_oid *tree = device_get_sysctl_tree(isp->isp_osinfo.dev);
630 
631 	if (IS_SCSI(isp)) {
632 		isp->isp_osinfo.sysctl_info.spi.iid = DEFAULT_IID(isp);
633 		SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, "iid",
634 		    CTLFLAG_RD, &isp->isp_osinfo.sysctl_info.spi.iid, 0,
635 		    "Initiator ID");
636 		return;
637 	}
638 	snprintf(isp->isp_osinfo.sysctl_info.fc.wwnn,
639 	    sizeof (isp->isp_osinfo.sysctl_info.fc.wwnn), "0x%08x%08x",
640 	    (uint32_t) (ISP_NODEWWN(isp) >> 32), (uint32_t) ISP_NODEWWN(isp));
641 
642 	snprintf(isp->isp_osinfo.sysctl_info.fc.wwpn,
643 	    sizeof (isp->isp_osinfo.sysctl_info.fc.wwpn), "0x%08x%08x",
644 	    (uint32_t) (ISP_PORTWWN(isp) >> 32), (uint32_t) ISP_PORTWWN(isp));
645 
646 	SYSCTL_ADD_STRING(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
647 	       "wwnn", CTLFLAG_RD, isp->isp_osinfo.sysctl_info.fc.wwnn, 0,
648 	       "World Wide Node Name");
649 	SYSCTL_ADD_STRING(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
650 	       "wwpn", CTLFLAG_RD, isp->isp_osinfo.sysctl_info.fc.wwpn, 0,
651 	       "World Wide Port Name");
652 }
653 #endif
654 
655 static void
656 isp_intr_enable(void *arg)
657 {
658 	ispsoftc_t *isp = arg;
659 	if (isp->isp_role != ISP_ROLE_NONE) {
660 		ENABLE_INTS(isp);
661 #if	0
662 		isp->isp_osinfo.intsok = 1;
663 #endif
664 	}
665 	/* Release our hook so that the boot can continue. */
666 	config_intrhook_disestablish(&isp->isp_osinfo.ehook);
667 }
668 
669 /*
670  * Put the target mode functions here, because some are inlines
671  */
672 
673 #ifdef	ISP_TARGET_MODE
674 
675 static __inline int is_lun_enabled(ispsoftc_t *, int, lun_id_t);
676 static __inline int are_any_luns_enabled(ispsoftc_t *, int);
677 static __inline tstate_t *get_lun_statep(ispsoftc_t *, int, lun_id_t);
678 static __inline void rls_lun_statep(ispsoftc_t *, tstate_t *);
679 static __inline atio_private_data_t *isp_get_atpd(ispsoftc_t *, int);
680 static cam_status
681 create_lun_state(ispsoftc_t *, int, struct cam_path *, tstate_t **);
682 static void destroy_lun_state(ispsoftc_t *, tstate_t *);
683 static int isp_en_lun(ispsoftc_t *, union ccb *);
684 static void isp_ledone(ispsoftc_t *, lun_entry_t *);
685 static cam_status isp_abort_tgt_ccb(ispsoftc_t *, union ccb *);
686 static timeout_t isp_refire_putback_atio;
687 static void isp_complete_ctio(union ccb *);
688 static void isp_target_putback_atio(union ccb *);
689 static void isp_target_start_ctio(ispsoftc_t *, union ccb *);
690 static int isp_handle_platform_atio(ispsoftc_t *, at_entry_t *);
691 static int isp_handle_platform_atio2(ispsoftc_t *, at2_entry_t *);
692 static int isp_handle_platform_ctio(ispsoftc_t *, void *);
693 static int isp_handle_platform_notify_scsi(ispsoftc_t *, in_entry_t *);
694 static int isp_handle_platform_notify_fc(ispsoftc_t *, in_fcentry_t *);
695 
696 static __inline int
697 is_lun_enabled(ispsoftc_t *isp, int bus, lun_id_t lun)
698 {
699 	tstate_t *tptr;
700 	tptr = isp->isp_osinfo.lun_hash[LUN_HASH_FUNC(isp, bus, lun)];
701 	if (tptr == NULL) {
702 		return (0);
703 	}
704 	do {
705 		if (tptr->lun == (lun_id_t) lun && tptr->bus == bus) {
706 			return (1);
707 		}
708 	} while ((tptr = tptr->next) != NULL);
709 	return (0);
710 }
711 
712 static __inline int
713 are_any_luns_enabled(ispsoftc_t *isp, int port)
714 {
715 	int lo, hi;
716 	if (IS_DUALBUS(isp)) {
717 		lo = (port * (LUN_HASH_SIZE >> 1));
718 		hi = lo + (LUN_HASH_SIZE >> 1);
719 	} else {
720 		lo = 0;
721 		hi = LUN_HASH_SIZE;
722 	}
723 	for (lo = 0; lo < hi; lo++) {
724 		if (isp->isp_osinfo.lun_hash[lo]) {
725 			return (1);
726 		}
727 	}
728 	return (0);
729 }
730 
731 static __inline tstate_t *
732 get_lun_statep(ispsoftc_t *isp, int bus, lun_id_t lun)
733 {
734 	tstate_t *tptr = NULL;
735 
736 	if (lun == CAM_LUN_WILDCARD) {
737 		if (isp->isp_osinfo.tmflags[bus] & TM_WILDCARD_ENABLED) {
738 			tptr = &isp->isp_osinfo.tsdflt[bus];
739 			tptr->hold++;
740 			return (tptr);
741 		}
742 		return (NULL);
743 	} else {
744 		tptr = isp->isp_osinfo.lun_hash[LUN_HASH_FUNC(isp, bus, lun)];
745 		if (tptr == NULL) {
746 			return (NULL);
747 		}
748 	}
749 
750 	do {
751 		if (tptr->lun == lun && tptr->bus == bus) {
752 			tptr->hold++;
753 			return (tptr);
754 		}
755 	} while ((tptr = tptr->next) != NULL);
756 	return (tptr);
757 }
758 
759 static __inline void
760 rls_lun_statep(ispsoftc_t *isp, tstate_t *tptr)
761 {
762 	if (tptr->hold)
763 		tptr->hold--;
764 }
765 
766 static __inline atio_private_data_t *
767 isp_get_atpd(ispsoftc_t *isp, int tag)
768 {
769 	atio_private_data_t *atp;
770 	for (atp = isp->isp_osinfo.atpdp;
771 	    atp < &isp->isp_osinfo.atpdp[ATPDPSIZE]; atp++) {
772 		if (atp->tag == tag)
773 			return (atp);
774 	}
775 	return (NULL);
776 }
777 
778 static cam_status
779 create_lun_state(ispsoftc_t *isp, int bus,
780     struct cam_path *path, tstate_t **rslt)
781 {
782 	cam_status status;
783 	lun_id_t lun;
784 	int hfx;
785 	tstate_t *tptr, *new;
786 
787 	lun = xpt_path_lun_id(path);
788 	if (lun < 0) {
789 		return (CAM_LUN_INVALID);
790 	}
791 	if (is_lun_enabled(isp, bus, lun)) {
792 		return (CAM_LUN_ALRDY_ENA);
793 	}
794 	new = (tstate_t *) malloc(sizeof (tstate_t), M_DEVBUF, M_NOWAIT|M_ZERO);
795 	if (new == NULL) {
796 		return (CAM_RESRC_UNAVAIL);
797 	}
798 
799 	status = xpt_create_path(&new->owner, NULL, xpt_path_path_id(path),
800 	    xpt_path_target_id(path), xpt_path_lun_id(path));
801 	if (status != CAM_REQ_CMP) {
802 		free(new, M_DEVBUF);
803 		return (status);
804 	}
805 	new->bus = bus;
806 	new->lun = lun;
807 	SLIST_INIT(&new->atios);
808 	SLIST_INIT(&new->inots);
809 	new->hold = 1;
810 
811 	hfx = LUN_HASH_FUNC(isp, new->bus, new->lun);
812 	tptr = isp->isp_osinfo.lun_hash[hfx];
813 	if (tptr == NULL) {
814 		isp->isp_osinfo.lun_hash[hfx] = new;
815 	} else {
816 		while (tptr->next)
817 			tptr = tptr->next;
818 		tptr->next = new;
819 	}
820 	*rslt = new;
821 	return (CAM_REQ_CMP);
822 }
823 
824 static __inline void
825 destroy_lun_state(ispsoftc_t *isp, tstate_t *tptr)
826 {
827 	int hfx;
828 	tstate_t *lw, *pw;
829 
830 	if (tptr->hold) {
831 		return;
832 	}
833 	hfx = LUN_HASH_FUNC(isp, tptr->bus, tptr->lun);
834 	pw = isp->isp_osinfo.lun_hash[hfx];
835 	if (pw == NULL) {
836 		return;
837 	} else if (pw->lun == tptr->lun && pw->bus == tptr->bus) {
838 		isp->isp_osinfo.lun_hash[hfx] = pw->next;
839 	} else {
840 		lw = pw;
841 		pw = lw->next;
842 		while (pw) {
843 			if (pw->lun == tptr->lun && pw->bus == tptr->bus) {
844 				lw->next = pw->next;
845 				break;
846 			}
847 			lw = pw;
848 			pw = pw->next;
849 		}
850 		if (pw == NULL) {
851 			return;
852 		}
853 	}
854 	free(tptr, M_DEVBUF);
855 }
856 
857 /*
858  * Enable luns.
859  */
860 static int
861 isp_en_lun(ispsoftc_t *isp, union ccb *ccb)
862 {
863 	struct ccb_en_lun *cel = &ccb->cel;
864 	tstate_t *tptr;
865 	uint32_t seq;
866 	int bus, cmd, av, wildcard, tm_on;
867 	lun_id_t lun;
868 	target_id_t tgt;
869 
870 	bus = XS_CHANNEL(ccb);
871 	if (bus > 1) {
872 		xpt_print_path(ccb->ccb_h.path);
873 		printf("illegal bus %d\n", bus);
874 		ccb->ccb_h.status = CAM_PATH_INVALID;
875 		return (-1);
876 	}
877 	tgt = ccb->ccb_h.target_id;
878 	lun = ccb->ccb_h.target_lun;
879 
880 	isp_prt(isp, ISP_LOGTDEBUG0,
881 	    "isp_en_lun: %sabling lun 0x%x on channel %d",
882 	    cel->enable? "en" : "dis", lun, bus);
883 
884 
885 	if ((lun != CAM_LUN_WILDCARD) &&
886 	    (lun < 0 || lun >= (lun_id_t) isp->isp_maxluns)) {
887 		ccb->ccb_h.status = CAM_LUN_INVALID;
888 		return (-1);
889 	}
890 
891 	if (IS_SCSI(isp)) {
892 		sdparam *sdp = isp->isp_param;
893 		sdp += bus;
894 		if (tgt != CAM_TARGET_WILDCARD &&
895 		    tgt != sdp->isp_initiator_id) {
896 			ccb->ccb_h.status = CAM_TID_INVALID;
897 			return (-1);
898 		}
899 	} else {
900 		/*
901 		 * There's really no point in doing this yet w/o multi-tid
902 		 * capability. Even then, it's problematic.
903 		 */
904 #if	0
905 		if (tgt != CAM_TARGET_WILDCARD &&
906 		    tgt != FCPARAM(isp)->isp_iid) {
907 			ccb->ccb_h.status = CAM_TID_INVALID;
908 			return (-1);
909 		}
910 #endif
911 		/*
912 		 * This is as a good a place as any to check f/w capabilities.
913 		 */
914 		if ((FCPARAM(isp)->isp_fwattr & ISP_FW_ATTR_TMODE) == 0) {
915 			isp_prt(isp, ISP_LOGERR,
916 			    "firmware does not support target mode");
917 			ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
918 			return (-1);
919 		}
920 		/*
921 		 * XXX: We *could* handle non-SCCLUN f/w, but we'd have to
922 		 * XXX: dorks with our already fragile enable/disable code.
923 		 */
924 		if ((FCPARAM(isp)->isp_fwattr & ISP_FW_ATTR_SCCLUN) == 0) {
925 			isp_prt(isp, ISP_LOGERR,
926 			    "firmware not SCCLUN capable");
927 			ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
928 			return (-1);
929 		}
930 	}
931 
932 	if (tgt == CAM_TARGET_WILDCARD) {
933 		if (lun == CAM_LUN_WILDCARD) {
934 			wildcard = 1;
935 		} else {
936 			ccb->ccb_h.status = CAM_LUN_INVALID;
937 			return (-1);
938 		}
939 	} else {
940 		wildcard = 0;
941 	}
942 
943 	tm_on = (isp->isp_osinfo.tmflags[bus] & TM_TMODE_ENABLED) != 0;
944 
945 	/*
946 	 * Next check to see whether this is a target/lun wildcard action.
947 	 *
948 	 * If so, we know that we can accept commands for luns that haven't
949 	 * been enabled yet and send them upstream. Otherwise, we have to
950 	 * handle them locally (if we see them at all).
951 	 */
952 
953 	if (wildcard) {
954 		tptr = &isp->isp_osinfo.tsdflt[bus];
955 		if (cel->enable) {
956 			if (tm_on) {
957 				ccb->ccb_h.status = CAM_LUN_ALRDY_ENA;
958 				return (-1);
959 			}
960 			ccb->ccb_h.status =
961 			    xpt_create_path(&tptr->owner, NULL,
962 			    xpt_path_path_id(ccb->ccb_h.path),
963 			    xpt_path_target_id(ccb->ccb_h.path),
964 			    xpt_path_lun_id(ccb->ccb_h.path));
965 			if (ccb->ccb_h.status != CAM_REQ_CMP) {
966 				return (-1);
967 			}
968 			SLIST_INIT(&tptr->atios);
969 			SLIST_INIT(&tptr->inots);
970 			isp->isp_osinfo.tmflags[bus] |= TM_WILDCARD_ENABLED;
971 		} else {
972 			if (tm_on == 0) {
973 				ccb->ccb_h.status = CAM_REQ_CMP;
974 				return (-1);
975 			}
976 			if (tptr->hold) {
977 				ccb->ccb_h.status = CAM_SCSI_BUSY;
978 				return (-1);
979 			}
980 			xpt_free_path(tptr->owner);
981 			isp->isp_osinfo.tmflags[bus] &= ~TM_WILDCARD_ENABLED;
982 		}
983 	}
984 
985 	/*
986 	 * Now check to see whether this bus needs to be
987 	 * enabled/disabled with respect to target mode.
988 	 */
989 	av = bus << 31;
990 	if (cel->enable && tm_on == 0) {
991 		av |= ENABLE_TARGET_FLAG;
992 		av = isp_control(isp, ISPCTL_TOGGLE_TMODE, &av);
993 		if (av) {
994 			ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
995 			if (wildcard) {
996 				isp->isp_osinfo.tmflags[bus] &=
997 				    ~TM_WILDCARD_ENABLED;
998 				xpt_free_path(tptr->owner);
999 			}
1000 			return (-1);
1001 		}
1002 		isp->isp_osinfo.tmflags[bus] |= TM_TMODE_ENABLED;
1003 		isp_prt(isp, ISP_LOGINFO,
1004 		    "Target Mode enabled on channel %d", bus);
1005 	} else if (cel->enable == 0 && tm_on && wildcard) {
1006 		if (are_any_luns_enabled(isp, bus)) {
1007 			ccb->ccb_h.status = CAM_SCSI_BUSY;
1008 			return (-1);
1009 		}
1010 		av = isp_control(isp, ISPCTL_TOGGLE_TMODE, &av);
1011 		if (av) {
1012 			ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
1013 			return (-1);
1014 		}
1015 		isp->isp_osinfo.tmflags[bus] &= ~TM_TMODE_ENABLED;
1016 		isp_prt(isp, ISP_LOGINFO,
1017 		    "Target Mode disabled on channel %d", bus);
1018 	}
1019 
1020 	if (wildcard) {
1021 		ccb->ccb_h.status = CAM_REQ_CMP;
1022 		return (-1);
1023 	}
1024 
1025 	/*
1026 	 * Find an empty slot
1027 	 */
1028 	for (seq = 0; seq < NLEACT; seq++) {
1029 		if (isp->isp_osinfo.leact[seq] == 0) {
1030 			break;
1031 		}
1032 	}
1033 	if (seq >= NLEACT) {
1034 		ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
1035 		return (-1);
1036 
1037 	}
1038 	isp->isp_osinfo.leact[seq] = ccb;
1039 
1040 	if (cel->enable) {
1041 		ccb->ccb_h.status =
1042 		    create_lun_state(isp, bus, ccb->ccb_h.path, &tptr);
1043 		if (ccb->ccb_h.status != CAM_REQ_CMP) {
1044 			isp->isp_osinfo.leact[seq] = 0;
1045 			return (-1);
1046 		}
1047 	} else {
1048 		tptr = get_lun_statep(isp, bus, lun);
1049 		if (tptr == NULL) {
1050 			ccb->ccb_h.status = CAM_LUN_INVALID;
1051 			return (-1);
1052 		}
1053 	}
1054 
1055 	if (cel->enable) {
1056 		int c, n, ulun = lun;
1057 
1058 		cmd = RQSTYPE_ENABLE_LUN;
1059 		c = DFLT_CMND_CNT;
1060 		n = DFLT_INOT_CNT;
1061 		if (IS_FC(isp) && lun != 0) {
1062 			cmd = RQSTYPE_MODIFY_LUN;
1063 			n = 0;
1064 			/*
1065 		 	 * For SCC firmware, we only deal with setting
1066 			 * (enabling or modifying) lun 0.
1067 			 */
1068 			ulun = 0;
1069 		}
1070 		if (isp_lun_cmd(isp, cmd, bus, tgt, ulun, c, n, seq+1) == 0) {
1071 			rls_lun_statep(isp, tptr);
1072 			ccb->ccb_h.status = CAM_REQ_INPROG;
1073 			return (seq);
1074 		}
1075 	} else {
1076 		int c, n, ulun = lun;
1077 
1078 		cmd = -RQSTYPE_MODIFY_LUN;
1079 		c = DFLT_CMND_CNT;
1080 		n = DFLT_INOT_CNT;
1081 		if (IS_FC(isp) && lun != 0) {
1082 			n = 0;
1083 			/*
1084 		 	 * For SCC firmware, we only deal with setting
1085 			 * (enabling or modifying) lun 0.
1086 			 */
1087 			ulun = 0;
1088 		}
1089 		if (isp_lun_cmd(isp, cmd, bus, tgt, ulun, c, n, seq+1) == 0) {
1090 			rls_lun_statep(isp, tptr);
1091 			ccb->ccb_h.status = CAM_REQ_INPROG;
1092 			return (seq);
1093 		}
1094 	}
1095 	rls_lun_statep(isp, tptr);
1096 	xpt_print_path(ccb->ccb_h.path);
1097 	printf("isp_lun_cmd failed\n");
1098 	isp->isp_osinfo.leact[seq] = 0;
1099 	ccb->ccb_h.status = CAM_REQ_CMP_ERR;
1100 	return (-1);
1101 }
1102 
1103 static void
1104 isp_ledone(ispsoftc_t *isp, lun_entry_t *lep)
1105 {
1106 	const char lfmt[] = "lun %d now %sabled for target mode on channel %d";
1107 	union ccb *ccb;
1108 	uint32_t seq;
1109 	tstate_t *tptr;
1110 	int av;
1111 	struct ccb_en_lun *cel;
1112 
1113 	seq = lep->le_reserved - 1;
1114 	if (seq >= NLEACT) {
1115 		isp_prt(isp, ISP_LOGERR,
1116 		    "seq out of range (%u) in isp_ledone", seq);
1117 		return;
1118 	}
1119 	ccb = isp->isp_osinfo.leact[seq];
1120 	if (ccb == 0) {
1121 		isp_prt(isp, ISP_LOGERR,
1122 		    "no ccb for seq %u in isp_ledone", seq);
1123 		return;
1124 	}
1125 	cel = &ccb->cel;
1126 	tptr = get_lun_statep(isp, XS_CHANNEL(ccb), XS_LUN(ccb));
1127 	if (tptr == NULL) {
1128 		xpt_print_path(ccb->ccb_h.path);
1129 		printf("null tptr in isp_ledone\n");
1130 		isp->isp_osinfo.leact[seq] = 0;
1131 		return;
1132 	}
1133 
1134 	if (lep->le_status != LUN_OK) {
1135 		xpt_print_path(ccb->ccb_h.path);
1136 		printf("ENABLE/MODIFY LUN returned 0x%x\n", lep->le_status);
1137 err:
1138 		ccb->ccb_h.status = CAM_REQ_CMP_ERR;
1139 		xpt_print_path(ccb->ccb_h.path);
1140 		rls_lun_statep(isp, tptr);
1141 		isp->isp_osinfo.leact[seq] = 0;
1142 		ISPLOCK_2_CAMLOCK(isp);
1143 		xpt_done(ccb);
1144 		CAMLOCK_2_ISPLOCK(isp);
1145 		return;
1146 	} else {
1147 		isp_prt(isp, ISP_LOGTDEBUG0,
1148 		    "isp_ledone: ENABLE/MODIFY done okay");
1149 	}
1150 
1151 
1152 	if (cel->enable) {
1153 		ccb->ccb_h.status = CAM_REQ_CMP;
1154 		isp_prt(isp, ISP_LOGINFO, lfmt,
1155 		    XS_LUN(ccb), "en", XS_CHANNEL(ccb));
1156 		rls_lun_statep(isp, tptr);
1157 		isp->isp_osinfo.leact[seq] = 0;
1158 		ISPLOCK_2_CAMLOCK(isp);
1159 		xpt_done(ccb);
1160 		CAMLOCK_2_ISPLOCK(isp);
1161 		return;
1162 	}
1163 
1164 	if (lep->le_header.rqs_entry_type == RQSTYPE_MODIFY_LUN) {
1165 		if (isp_lun_cmd(isp, -RQSTYPE_ENABLE_LUN, XS_CHANNEL(ccb),
1166 		    XS_TGT(ccb), XS_LUN(ccb), 0, 0, seq+1)) {
1167 			xpt_print_path(ccb->ccb_h.path);
1168 			printf("isp_ledone: isp_lun_cmd failed\n");
1169 			goto err;
1170 		}
1171 		rls_lun_statep(isp, tptr);
1172 		return;
1173 	}
1174 
1175 	isp_prt(isp, ISP_LOGINFO, lfmt, XS_LUN(ccb), "dis", XS_CHANNEL(ccb));
1176 	rls_lun_statep(isp, tptr);
1177 	destroy_lun_state(isp, tptr);
1178 	ccb->ccb_h.status = CAM_REQ_CMP;
1179 	isp->isp_osinfo.leact[seq] = 0;
1180 	ISPLOCK_2_CAMLOCK(isp);
1181 	xpt_done(ccb);
1182 	CAMLOCK_2_ISPLOCK(isp);
1183 	if (are_any_luns_enabled(isp, XS_CHANNEL(ccb)) == 0) {
1184 		int bus = XS_CHANNEL(ccb);
1185 		av = bus << 31;
1186 		av = isp_control(isp, ISPCTL_TOGGLE_TMODE, &av);
1187 		if (av) {
1188 			isp_prt(isp, ISP_LOGWARN,
1189 			    "disable target mode on channel %d failed", bus);
1190 		} else {
1191 			isp_prt(isp, ISP_LOGINFO,
1192 			    "Target Mode disabled on channel %d", bus);
1193 		}
1194 		isp->isp_osinfo.tmflags[bus] &= ~TM_TMODE_ENABLED;
1195 	}
1196 }
1197 
1198 
1199 static cam_status
1200 isp_abort_tgt_ccb(ispsoftc_t *isp, union ccb *ccb)
1201 {
1202 	tstate_t *tptr;
1203 	struct ccb_hdr_slist *lp;
1204 	struct ccb_hdr *curelm;
1205 	int found, *ctr;
1206 	union ccb *accb = ccb->cab.abort_ccb;
1207 
1208 	isp_prt(isp, ISP_LOGTDEBUG0, "aborting ccb %p", accb);
1209 	if (accb->ccb_h.target_id != CAM_TARGET_WILDCARD) {
1210 		int badpath = 0;
1211 		if (IS_FC(isp) && (accb->ccb_h.target_id !=
1212 		    ((fcparam *) isp->isp_param)->isp_loopid)) {
1213 			badpath = 1;
1214 		} else if (IS_SCSI(isp) && (accb->ccb_h.target_id !=
1215 		    ((sdparam *) isp->isp_param)->isp_initiator_id)) {
1216 			badpath = 1;
1217 		}
1218 		if (badpath) {
1219 			/*
1220 			 * Being restrictive about target ids is really about
1221 			 * making sure we're aborting for the right multi-tid
1222 			 * path. This doesn't really make much sense at present.
1223 			 */
1224 #if	0
1225 			return (CAM_PATH_INVALID);
1226 #endif
1227 		}
1228 	}
1229 	tptr = get_lun_statep(isp, XS_CHANNEL(ccb), accb->ccb_h.target_lun);
1230 	if (tptr == NULL) {
1231 		isp_prt(isp, ISP_LOGTDEBUG0,
1232 		    "isp_abort_tgt_ccb: can't get statep");
1233 		return (CAM_PATH_INVALID);
1234 	}
1235 	if (accb->ccb_h.func_code == XPT_ACCEPT_TARGET_IO) {
1236 		lp = &tptr->atios;
1237 		ctr = &tptr->atio_count;
1238 	} else if (accb->ccb_h.func_code == XPT_IMMED_NOTIFY) {
1239 		lp = &tptr->inots;
1240 		ctr = &tptr->inot_count;
1241 	} else {
1242 		rls_lun_statep(isp, tptr);
1243 		isp_prt(isp, ISP_LOGTDEBUG0,
1244 		    "isp_abort_tgt_ccb: bad func %d\n", accb->ccb_h.func_code);
1245 		return (CAM_UA_ABORT);
1246 	}
1247 	curelm = SLIST_FIRST(lp);
1248 	found = 0;
1249 	if (curelm == &accb->ccb_h) {
1250 		found = 1;
1251 		SLIST_REMOVE_HEAD(lp, sim_links.sle);
1252 	} else {
1253 		while(curelm != NULL) {
1254 			struct ccb_hdr *nextelm;
1255 
1256 			nextelm = SLIST_NEXT(curelm, sim_links.sle);
1257 			if (nextelm == &accb->ccb_h) {
1258 				found = 1;
1259 				SLIST_NEXT(curelm, sim_links.sle) =
1260 				    SLIST_NEXT(nextelm, sim_links.sle);
1261 				break;
1262 			}
1263 			curelm = nextelm;
1264 		}
1265 	}
1266 	rls_lun_statep(isp, tptr);
1267 	if (found) {
1268 		(*ctr)--;
1269 		accb->ccb_h.status = CAM_REQ_ABORTED;
1270 		xpt_done(accb);
1271 		return (CAM_REQ_CMP);
1272 	}
1273 	isp_prt(isp, ISP_LOGTDEBUG0,
1274 	    "isp_abort_tgt_ccb: CCB %p not found\n", ccb);
1275 	return (CAM_PATH_INVALID);
1276 }
1277 
1278 static void
1279 isp_target_start_ctio(ispsoftc_t *isp, union ccb *ccb)
1280 {
1281 	void *qe;
1282 	struct ccb_scsiio *cso = &ccb->csio;
1283 	uint16_t *hp, save_handle;
1284 	uint16_t nxti, optr;
1285 	uint8_t local[QENTRY_LEN];
1286 
1287 
1288 	if (isp_getrqentry(isp, &nxti, &optr, &qe)) {
1289 		xpt_print_path(ccb->ccb_h.path);
1290 		printf("Request Queue Overflow in isp_target_start_ctio\n");
1291 		XS_SETERR(ccb, CAM_REQUEUE_REQ);
1292 		goto out;
1293 	}
1294 	memset(local, 0, QENTRY_LEN);
1295 
1296 	/*
1297 	 * We're either moving data or completing a command here.
1298 	 */
1299 
1300 	if (IS_FC(isp)) {
1301 		atio_private_data_t *atp;
1302 		ct2_entry_t *cto = (ct2_entry_t *) local;
1303 
1304 		cto->ct_header.rqs_entry_type = RQSTYPE_CTIO2;
1305 		cto->ct_header.rqs_entry_count = 1;
1306 		if (IS_2KLOGIN(isp)) {
1307 			((ct2e_entry_t *)cto)->ct_iid = cso->init_id;
1308 		} else {
1309 			cto->ct_iid = cso->init_id;
1310 			if (!(FCPARAM(isp)->isp_fwattr & ISP_FW_ATTR_SCCLUN)) {
1311 				cto->ct_lun = ccb->ccb_h.target_lun;
1312 			}
1313 		}
1314 
1315 		atp = isp_get_atpd(isp, cso->tag_id);
1316 		if (atp == NULL) {
1317 			isp_prt(isp, ISP_LOGERR,
1318 			    "cannot find private data adjunct for tag %x",
1319 			    cso->tag_id);
1320 			XS_SETERR(ccb, CAM_REQ_CMP_ERR);
1321 			goto out;
1322 		}
1323 
1324 		cto->ct_rxid = cso->tag_id;
1325 		if (cso->dxfer_len == 0) {
1326 			cto->ct_flags |= CT2_FLAG_MODE1 | CT2_NO_DATA;
1327 			if (ccb->ccb_h.flags & CAM_SEND_STATUS) {
1328 				cto->ct_flags |= CT2_SENDSTATUS;
1329 				cto->rsp.m1.ct_scsi_status = cso->scsi_status;
1330 				cto->ct_resid =
1331 				    atp->orig_datalen - atp->bytes_xfered;
1332 				if (cto->ct_resid < 0) {
1333 					cto->rsp.m1.ct_scsi_status |=
1334 					    CT2_DATA_OVER;
1335 				} else if (cto->ct_resid > 0) {
1336 					cto->rsp.m1.ct_scsi_status |=
1337 					    CT2_DATA_UNDER;
1338 				}
1339 			}
1340 			if ((ccb->ccb_h.flags & CAM_SEND_SENSE) != 0) {
1341 				int m = min(cso->sense_len, MAXRESPLEN);
1342 				memcpy(cto->rsp.m1.ct_resp,
1343 				    &cso->sense_data, m);
1344 				cto->rsp.m1.ct_senselen = m;
1345 				cto->rsp.m1.ct_scsi_status |= CT2_SNSLEN_VALID;
1346 			}
1347 		} else {
1348 			cto->ct_flags |= CT2_FLAG_MODE0;
1349 			if ((cso->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) {
1350 				cto->ct_flags |= CT2_DATA_IN;
1351 			} else {
1352 				cto->ct_flags |= CT2_DATA_OUT;
1353 			}
1354 			cto->ct_reloff = atp->bytes_xfered;
1355 			if ((ccb->ccb_h.flags & CAM_SEND_STATUS) != 0) {
1356 				cto->ct_flags |= CT2_SENDSTATUS;
1357 				cto->rsp.m0.ct_scsi_status = cso->scsi_status;
1358 				cto->ct_resid =
1359 				    atp->orig_datalen -
1360 				    (atp->bytes_xfered + cso->dxfer_len);
1361 				if (cto->ct_resid < 0) {
1362 					cto->rsp.m0.ct_scsi_status |=
1363 					    CT2_DATA_OVER;
1364 				} else if (cto->ct_resid > 0) {
1365 					cto->rsp.m0.ct_scsi_status |=
1366 					    CT2_DATA_UNDER;
1367 				}
1368 			} else {
1369 				atp->last_xframt = cso->dxfer_len;
1370 			}
1371 			/*
1372 			 * If we're sending data and status back together,
1373 			 * we can't also send back sense data as well.
1374 			 */
1375 			ccb->ccb_h.flags &= ~CAM_SEND_SENSE;
1376 		}
1377 
1378 		if (cto->ct_flags & CT2_SENDSTATUS) {
1379 			isp_prt(isp, ISP_LOGTDEBUG0,
1380 			    "CTIO2[%x] STATUS %x origd %u curd %u resid %u",
1381 			    cto->ct_rxid, cso->scsi_status, atp->orig_datalen,
1382 			    cso->dxfer_len, cto->ct_resid);
1383 			cto->ct_flags |= CT2_CCINCR;
1384 			atp->state = ATPD_STATE_LAST_CTIO;
1385 		} else {
1386 			atp->state = ATPD_STATE_CTIO;
1387 		}
1388 		cto->ct_timeout = 10;
1389 		hp = &cto->ct_syshandle;
1390 	} else {
1391 		ct_entry_t *cto = (ct_entry_t *) local;
1392 
1393 		cto->ct_header.rqs_entry_type = RQSTYPE_CTIO;
1394 		cto->ct_header.rqs_entry_count = 1;
1395 		cto->ct_iid = cso->init_id;
1396 		cto->ct_iid |= XS_CHANNEL(ccb) << 7;
1397 		cto->ct_tgt = ccb->ccb_h.target_id;
1398 		cto->ct_lun = ccb->ccb_h.target_lun;
1399 		cto->ct_fwhandle = AT_GET_HANDLE(cso->tag_id);
1400 		if (AT_HAS_TAG(cso->tag_id)) {
1401 			cto->ct_tag_val = (uint8_t) AT_GET_TAG(cso->tag_id);
1402 			cto->ct_flags |= CT_TQAE;
1403 		}
1404 		if (ccb->ccb_h.flags & CAM_DIS_DISCONNECT) {
1405 			cto->ct_flags |= CT_NODISC;
1406 		}
1407 		if (cso->dxfer_len == 0) {
1408 			cto->ct_flags |= CT_NO_DATA;
1409 		} else if ((cso->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) {
1410 			cto->ct_flags |= CT_DATA_IN;
1411 		} else {
1412 			cto->ct_flags |= CT_DATA_OUT;
1413 		}
1414 		if (ccb->ccb_h.flags & CAM_SEND_STATUS) {
1415 			cto->ct_flags |= CT_SENDSTATUS|CT_CCINCR;
1416 			cto->ct_scsi_status = cso->scsi_status;
1417 			cto->ct_resid = cso->resid;
1418 			isp_prt(isp, ISP_LOGTDEBUG0,
1419 			    "CTIO[%x] SCSI STATUS 0x%x resid %d tag_id %x",
1420 			    cto->ct_fwhandle, cso->scsi_status, cso->resid,
1421 			    cso->tag_id);
1422 		}
1423 		ccb->ccb_h.flags &= ~CAM_SEND_SENSE;
1424 		cto->ct_timeout = 10;
1425 		hp = &cto->ct_syshandle;
1426 	}
1427 
1428 	if (isp_save_xs_tgt(isp, ccb, hp)) {
1429 		xpt_print_path(ccb->ccb_h.path);
1430 		printf("No XFLIST pointers for isp_target_start_ctio\n");
1431 		XS_SETERR(ccb, CAM_REQUEUE_REQ);
1432 		goto out;
1433 	}
1434 
1435 
1436 	/*
1437 	 * Call the dma setup routines for this entry (and any subsequent
1438 	 * CTIOs) if there's data to move, and then tell the f/w it's got
1439 	 * new things to play with. As with isp_start's usage of DMA setup,
1440 	 * any swizzling is done in the machine dependent layer. Because
1441 	 * of this, we put the request onto the queue area first in native
1442 	 * format.
1443 	 */
1444 
1445 	save_handle = *hp;
1446 
1447 	switch (ISP_DMASETUP(isp, cso, (ispreq_t *) local, &nxti, optr)) {
1448 	case CMD_QUEUED:
1449 		ISP_ADD_REQUEST(isp, nxti);
1450 		ccb->ccb_h.status |= CAM_SIM_QUEUED;
1451 		return;
1452 
1453 	case CMD_EAGAIN:
1454 		XS_SETERR(ccb, CAM_REQUEUE_REQ);
1455 		break;
1456 
1457 	default:
1458 		break;
1459 	}
1460 	isp_destroy_tgt_handle(isp, save_handle);
1461 
1462 out:
1463 	ISPLOCK_2_CAMLOCK(isp);
1464 	xpt_done(ccb);
1465 	CAMLOCK_2_ISPLOCK(isp);
1466 }
1467 
1468 static void
1469 isp_refire_putback_atio(void *arg)
1470 {
1471 	int s = splcam();
1472 	isp_target_putback_atio(arg);
1473 	splx(s);
1474 }
1475 
1476 static void
1477 isp_target_putback_atio(union ccb *ccb)
1478 {
1479 	ispsoftc_t *isp;
1480 	struct ccb_scsiio *cso;
1481 	uint16_t nxti, optr;
1482 	void *qe;
1483 
1484 	isp = XS_ISP(ccb);
1485 
1486 	if (isp_getrqentry(isp, &nxti, &optr, &qe)) {
1487 		(void) timeout(isp_refire_putback_atio, ccb, 10);
1488 		isp_prt(isp, ISP_LOGWARN,
1489 		    "isp_target_putback_atio: Request Queue Overflow");
1490 		return;
1491 	}
1492 	memset(qe, 0, QENTRY_LEN);
1493 	cso = &ccb->csio;
1494 	if (IS_FC(isp)) {
1495 		at2_entry_t local, *at = &local;
1496 		MEMZERO(at, sizeof (at2_entry_t));
1497 		at->at_header.rqs_entry_type = RQSTYPE_ATIO2;
1498 		at->at_header.rqs_entry_count = 1;
1499 		if ((FCPARAM(isp)->isp_fwattr & ISP_FW_ATTR_SCCLUN) != 0) {
1500 			at->at_scclun = (uint16_t) ccb->ccb_h.target_lun;
1501 		} else {
1502 			at->at_lun = (uint8_t) ccb->ccb_h.target_lun;
1503 		}
1504 		at->at_status = CT_OK;
1505 		at->at_rxid = cso->tag_id;
1506 		at->at_iid = cso->ccb_h.target_id;
1507 		isp_put_atio2(isp, at, qe);
1508 	} else {
1509 		at_entry_t local, *at = &local;
1510 		MEMZERO(at, sizeof (at_entry_t));
1511 		at->at_header.rqs_entry_type = RQSTYPE_ATIO;
1512 		at->at_header.rqs_entry_count = 1;
1513 		at->at_iid = cso->init_id;
1514 		at->at_iid |= XS_CHANNEL(ccb) << 7;
1515 		at->at_tgt = cso->ccb_h.target_id;
1516 		at->at_lun = cso->ccb_h.target_lun;
1517 		at->at_status = CT_OK;
1518 		at->at_tag_val = AT_GET_TAG(cso->tag_id);
1519 		at->at_handle = AT_GET_HANDLE(cso->tag_id);
1520 		isp_put_atio(isp, at, qe);
1521 	}
1522 	ISP_TDQE(isp, "isp_target_putback_atio", (int) optr, qe);
1523 	ISP_ADD_REQUEST(isp, nxti);
1524 	isp_complete_ctio(ccb);
1525 }
1526 
1527 static void
1528 isp_complete_ctio(union ccb *ccb)
1529 {
1530 	ISPLOCK_2_CAMLOCK(isp);
1531 	if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_INPROG) {
1532 		ccb->ccb_h.status |= CAM_REQ_CMP;
1533 	}
1534 	ccb->ccb_h.status &= ~CAM_SIM_QUEUED;
1535 	xpt_done(ccb);
1536 	CAMLOCK_2_ISPLOCK(isp);
1537 }
1538 
1539 /*
1540  * Handle ATIO stuff that the generic code can't.
1541  * This means handling CDBs.
1542  */
1543 
1544 static int
1545 isp_handle_platform_atio(ispsoftc_t *isp, at_entry_t *aep)
1546 {
1547 	tstate_t *tptr;
1548 	int status, bus, iswildcard;
1549 	struct ccb_accept_tio *atiop;
1550 
1551 	/*
1552 	 * The firmware status (except for the QLTM_SVALID bit)
1553 	 * indicates why this ATIO was sent to us.
1554 	 *
1555 	 * If QLTM_SVALID is set, the firware has recommended Sense Data.
1556 	 *
1557 	 * If the DISCONNECTS DISABLED bit is set in the flags field,
1558 	 * we're still connected on the SCSI bus.
1559 	 */
1560 	status = aep->at_status;
1561 	if ((status & ~QLTM_SVALID) == AT_PHASE_ERROR) {
1562 		/*
1563 		 * Bus Phase Sequence error. We should have sense data
1564 		 * suggested by the f/w. I'm not sure quite yet what
1565 		 * to do about this for CAM.
1566 		 */
1567 		isp_prt(isp, ISP_LOGWARN, "PHASE ERROR");
1568 		isp_endcmd(isp, aep, SCSI_STATUS_BUSY, 0);
1569 		return (0);
1570 	}
1571 	if ((status & ~QLTM_SVALID) != AT_CDB) {
1572 		isp_prt(isp, ISP_LOGWARN, "bad atio (0x%x) leaked to platform",
1573 		    status);
1574 		isp_endcmd(isp, aep, SCSI_STATUS_BUSY, 0);
1575 		return (0);
1576 	}
1577 
1578 	bus = GET_BUS_VAL(aep->at_iid);
1579 	tptr = get_lun_statep(isp, bus, aep->at_lun);
1580 	if (tptr == NULL) {
1581 		tptr = get_lun_statep(isp, bus, CAM_LUN_WILDCARD);
1582 		if (tptr == NULL) {
1583 			/*
1584 			 * Because we can't autofeed sense data back with
1585 			 * a command for parallel SCSI, we can't give back
1586 			 * a CHECK CONDITION. We'll give back a BUSY status
1587 			 * instead. This works out okay because the only
1588 			 * time we should, in fact, get this, is in the
1589 			 * case that somebody configured us without the
1590 			 * blackhole driver, so they get what they deserve.
1591 			 */
1592 			isp_endcmd(isp, aep, SCSI_STATUS_BUSY, 0);
1593 			return (0);
1594 		}
1595 		iswildcard = 1;
1596 	} else {
1597 		iswildcard = 0;
1598 	}
1599 
1600 	atiop = (struct ccb_accept_tio *) SLIST_FIRST(&tptr->atios);
1601 	if (atiop == NULL) {
1602 		/*
1603 		 * Because we can't autofeed sense data back with
1604 		 * a command for parallel SCSI, we can't give back
1605 		 * a CHECK CONDITION. We'll give back a QUEUE FULL status
1606 		 * instead. This works out okay because the only time we
1607 		 * should, in fact, get this, is in the case that we've
1608 		 * run out of ATIOS.
1609 		 */
1610 		xpt_print_path(tptr->owner);
1611 		isp_prt(isp, ISP_LOGWARN,
1612 		    "no ATIOS for lun %d from initiator %d on channel %d",
1613 		    aep->at_lun, GET_IID_VAL(aep->at_iid), bus);
1614 		if (aep->at_flags & AT_TQAE)
1615 			isp_endcmd(isp, aep, SCSI_STATUS_QUEUE_FULL, 0);
1616 		else
1617 			isp_endcmd(isp, aep, SCSI_STATUS_BUSY, 0);
1618 		rls_lun_statep(isp, tptr);
1619 		return (0);
1620 	}
1621 	SLIST_REMOVE_HEAD(&tptr->atios, sim_links.sle);
1622 	tptr->atio_count--;
1623 	isp_prt(isp, ISP_LOGTDEBUG0, "Take FREE ATIO lun %d, count now %d",
1624 	    aep->at_lun, tptr->atio_count);
1625 	if (iswildcard) {
1626 		atiop->ccb_h.target_id = aep->at_tgt;
1627 		atiop->ccb_h.target_lun = aep->at_lun;
1628 	}
1629 	if (aep->at_flags & AT_NODISC) {
1630 		atiop->ccb_h.flags = CAM_DIS_DISCONNECT;
1631 	} else {
1632 		atiop->ccb_h.flags = 0;
1633 	}
1634 
1635 	if (status & QLTM_SVALID) {
1636 		size_t amt = imin(QLTM_SENSELEN, sizeof (atiop->sense_data));
1637 		atiop->sense_len = amt;
1638 		MEMCPY(&atiop->sense_data, aep->at_sense, amt);
1639 	} else {
1640 		atiop->sense_len = 0;
1641 	}
1642 
1643 	atiop->init_id = GET_IID_VAL(aep->at_iid);
1644 	atiop->cdb_len = aep->at_cdblen;
1645 	MEMCPY(atiop->cdb_io.cdb_bytes, aep->at_cdb, aep->at_cdblen);
1646 	atiop->ccb_h.status = CAM_CDB_RECVD;
1647 	/*
1648 	 * Construct a tag 'id' based upon tag value (which may be 0..255)
1649 	 * and the handle (which we have to preserve).
1650 	 */
1651 	AT_MAKE_TAGID(atiop->tag_id,  device_get_unit(isp->isp_dev), aep);
1652 	if (aep->at_flags & AT_TQAE) {
1653 		atiop->tag_action = aep->at_tag_type;
1654 		atiop->ccb_h.status |= CAM_TAG_ACTION_VALID;
1655 	}
1656 	xpt_done((union ccb*)atiop);
1657 	isp_prt(isp, ISP_LOGTDEBUG0,
1658 	    "ATIO[%x] CDB=0x%x bus %d iid%d->lun%d tag 0x%x ttype 0x%x %s",
1659 	    aep->at_handle, aep->at_cdb[0] & 0xff, GET_BUS_VAL(aep->at_iid),
1660 	    GET_IID_VAL(aep->at_iid), aep->at_lun, aep->at_tag_val & 0xff,
1661 	    aep->at_tag_type, (aep->at_flags & AT_NODISC)?
1662 	    "nondisc" : "disconnecting");
1663 	rls_lun_statep(isp, tptr);
1664 	return (0);
1665 }
1666 
1667 static int
1668 isp_handle_platform_atio2(ispsoftc_t *isp, at2_entry_t *aep)
1669 {
1670 	lun_id_t lun;
1671 	tstate_t *tptr;
1672 	struct ccb_accept_tio *atiop;
1673 	atio_private_data_t *atp;
1674 
1675 	/*
1676 	 * The firmware status (except for the QLTM_SVALID bit)
1677 	 * indicates why this ATIO was sent to us.
1678 	 *
1679 	 * If QLTM_SVALID is set, the firware has recommended Sense Data.
1680 	 */
1681 	if ((aep->at_status & ~QLTM_SVALID) != AT_CDB) {
1682 		isp_prt(isp, ISP_LOGWARN,
1683 		    "bogus atio (0x%x) leaked to platform", aep->at_status);
1684 		isp_endcmd(isp, aep, SCSI_STATUS_BUSY, 0);
1685 		return (0);
1686 	}
1687 
1688 	if ((FCPARAM(isp)->isp_fwattr & ISP_FW_ATTR_SCCLUN) != 0) {
1689 		lun = aep->at_scclun;
1690 	} else {
1691 		lun = aep->at_lun;
1692 	}
1693 	tptr = get_lun_statep(isp, 0, lun);
1694 	if (tptr == NULL) {
1695 		isp_prt(isp, ISP_LOGTDEBUG0,
1696 		    "[0x%x] no state pointer for lun %d", aep->at_rxid, lun);
1697 		tptr = get_lun_statep(isp, 0, CAM_LUN_WILDCARD);
1698 		if (tptr == NULL) {
1699 			isp_endcmd(isp, aep,
1700 			    SCSI_STATUS_CHECK_COND | ECMD_SVALID |
1701 			    (0x5 << 12) | (0x25 << 16), 0);
1702 			return (0);
1703 		}
1704 	}
1705 
1706 	atp = isp_get_atpd(isp, 0);
1707 	atiop = (struct ccb_accept_tio *) SLIST_FIRST(&tptr->atios);
1708 	if (atiop == NULL || atp == NULL) {
1709 
1710 		/*
1711 		 * Because we can't autofeed sense data back with
1712 		 * a command for parallel SCSI, we can't give back
1713 		 * a CHECK CONDITION. We'll give back a QUEUE FULL status
1714 		 * instead. This works out okay because the only time we
1715 		 * should, in fact, get this, is in the case that we've
1716 		 * run out of ATIOS.
1717 		 */
1718 		xpt_print_path(tptr->owner);
1719 		isp_prt(isp, ISP_LOGWARN,
1720 		    "no %s for lun %d from initiator %d",
1721 		    (atp == NULL && atiop == NULL)? "ATIO2s *or* ATPS" :
1722 		    ((atp == NULL)? "ATPs" : "ATIO2s"), lun, aep->at_iid);
1723 		rls_lun_statep(isp, tptr);
1724 		isp_endcmd(isp, aep, SCSI_STATUS_QUEUE_FULL, 0);
1725 		return (0);
1726 	}
1727 	atp->state = ATPD_STATE_ATIO;
1728 	SLIST_REMOVE_HEAD(&tptr->atios, sim_links.sle);
1729 	tptr->atio_count--;
1730 	isp_prt(isp, ISP_LOGTDEBUG0, "Take FREE ATIO lun %d, count now %d",
1731 	    lun, tptr->atio_count);
1732 
1733 	if (tptr == &isp->isp_osinfo.tsdflt[0]) {
1734 		atiop->ccb_h.target_id =
1735 		    ((fcparam *)isp->isp_param)->isp_loopid;
1736 		atiop->ccb_h.target_lun = lun;
1737 	}
1738 	/*
1739 	 * We don't get 'suggested' sense data as we do with SCSI cards.
1740 	 */
1741 	atiop->sense_len = 0;
1742 
1743 	atiop->init_id = aep->at_iid;
1744 	atiop->cdb_len = ATIO2_CDBLEN;
1745 	MEMCPY(atiop->cdb_io.cdb_bytes, aep->at_cdb, ATIO2_CDBLEN);
1746 	atiop->ccb_h.status = CAM_CDB_RECVD;
1747 	atiop->tag_id = aep->at_rxid;
1748 	switch (aep->at_taskflags & ATIO2_TC_ATTR_MASK) {
1749 	case ATIO2_TC_ATTR_SIMPLEQ:
1750 		atiop->tag_action = MSG_SIMPLE_Q_TAG;
1751 		break;
1752         case ATIO2_TC_ATTR_HEADOFQ:
1753 		atiop->tag_action = MSG_HEAD_OF_Q_TAG;
1754 		break;
1755         case ATIO2_TC_ATTR_ORDERED:
1756 		atiop->tag_action = MSG_ORDERED_Q_TAG;
1757 		break;
1758         case ATIO2_TC_ATTR_ACAQ:		/* ?? */
1759 	case ATIO2_TC_ATTR_UNTAGGED:
1760 	default:
1761 		atiop->tag_action = 0;
1762 		break;
1763 	}
1764 	atiop->ccb_h.flags = CAM_TAG_ACTION_VALID;
1765 
1766 	atp->tag = atiop->tag_id;
1767 	atp->lun = lun;
1768 	atp->orig_datalen = aep->at_datalen;
1769 	atp->last_xframt = 0;
1770 	atp->bytes_xfered = 0;
1771 	atp->state = ATPD_STATE_CAM;
1772 	ISPLOCK_2_CAMLOCK(siP);
1773 	xpt_done((union ccb*)atiop);
1774 
1775 	isp_prt(isp, ISP_LOGTDEBUG0,
1776 	    "ATIO2[%x] CDB=0x%x iid%d->lun%d tattr 0x%x datalen %u",
1777 	    aep->at_rxid, aep->at_cdb[0] & 0xff, aep->at_iid,
1778 	    lun, aep->at_taskflags, aep->at_datalen);
1779 	rls_lun_statep(isp, tptr);
1780 	return (0);
1781 }
1782 
1783 static int
1784 isp_handle_platform_ctio(ispsoftc_t *isp, void *arg)
1785 {
1786 	union ccb *ccb;
1787 	int sentstatus, ok, notify_cam, resid = 0;
1788 	uint16_t tval;
1789 
1790 	/*
1791 	 * CTIO and CTIO2 are close enough....
1792 	 */
1793 
1794 	ccb = isp_find_xs_tgt(isp, ((ct_entry_t *)arg)->ct_syshandle);
1795 	KASSERT((ccb != NULL), ("null ccb in isp_handle_platform_ctio"));
1796 	isp_destroy_tgt_handle(isp, ((ct_entry_t *)arg)->ct_syshandle);
1797 
1798 	if (IS_FC(isp)) {
1799 		ct2_entry_t *ct = arg;
1800 		atio_private_data_t *atp = isp_get_atpd(isp, ct->ct_rxid);
1801 		if (atp == NULL) {
1802 			isp_prt(isp, ISP_LOGERR,
1803 			    "cannot find adjunct for %x after I/O",
1804 			    ct->ct_rxid);
1805 			return (0);
1806 		}
1807 		sentstatus = ct->ct_flags & CT2_SENDSTATUS;
1808 		ok = (ct->ct_status & ~QLTM_SVALID) == CT_OK;
1809 		if (ok && sentstatus && (ccb->ccb_h.flags & CAM_SEND_SENSE)) {
1810 			ccb->ccb_h.status |= CAM_SENT_SENSE;
1811 		}
1812 		notify_cam = ct->ct_header.rqs_seqno & 0x1;
1813 		if ((ct->ct_flags & CT2_DATAMASK) != CT2_NO_DATA) {
1814 			resid = ct->ct_resid;
1815 			atp->bytes_xfered += (atp->last_xframt - resid);
1816 			atp->last_xframt = 0;
1817 		}
1818 		if (sentstatus || !ok) {
1819 			atp->tag = 0;
1820 		}
1821 		isp_prt(isp, ok? ISP_LOGTDEBUG0 : ISP_LOGWARN,
1822 		    "CTIO2[%x] sts 0x%x flg 0x%x sns %d resid %d %s",
1823 		    ct->ct_rxid, ct->ct_status, ct->ct_flags,
1824 		    (ccb->ccb_h.status & CAM_SENT_SENSE) != 0,
1825 		    resid, sentstatus? "FIN" : "MID");
1826 		tval = ct->ct_rxid;
1827 
1828 		/* XXX: should really come after isp_complete_ctio */
1829 		atp->state = ATPD_STATE_PDON;
1830 	} else {
1831 		ct_entry_t *ct = arg;
1832 		sentstatus = ct->ct_flags & CT_SENDSTATUS;
1833 		ok = (ct->ct_status  & ~QLTM_SVALID) == CT_OK;
1834 		/*
1835 		 * We *ought* to be able to get back to the original ATIO
1836 		 * here, but for some reason this gets lost. It's just as
1837 		 * well because it's squirrelled away as part of periph
1838 		 * private data.
1839 		 *
1840 		 * We can live without it as long as we continue to use
1841 		 * the auto-replenish feature for CTIOs.
1842 		 */
1843 		notify_cam = ct->ct_header.rqs_seqno & 0x1;
1844 		if (ct->ct_status & QLTM_SVALID) {
1845 			char *sp = (char *)ct;
1846 			sp += CTIO_SENSE_OFFSET;
1847 			ccb->csio.sense_len =
1848 			    min(sizeof (ccb->csio.sense_data), QLTM_SENSELEN);
1849 			MEMCPY(&ccb->csio.sense_data, sp, ccb->csio.sense_len);
1850 			ccb->ccb_h.status |= CAM_AUTOSNS_VALID;
1851 		}
1852 		if ((ct->ct_flags & CT_DATAMASK) != CT_NO_DATA) {
1853 			resid = ct->ct_resid;
1854 		}
1855 		isp_prt(isp, ISP_LOGTDEBUG0,
1856 		    "CTIO[%x] tag %x iid %d lun %d sts %x flg %x resid %d %s",
1857 		    ct->ct_fwhandle, ct->ct_tag_val, ct->ct_iid, ct->ct_lun,
1858 		    ct->ct_status, ct->ct_flags, resid,
1859 		    sentstatus? "FIN" : "MID");
1860 		tval = ct->ct_fwhandle;
1861 	}
1862 	ccb->csio.resid += resid;
1863 
1864 	/*
1865 	 * We're here either because intermediate data transfers are done
1866 	 * and/or the final status CTIO (which may have joined with a
1867 	 * Data Transfer) is done.
1868 	 *
1869 	 * In any case, for this platform, the upper layers figure out
1870 	 * what to do next, so all we do here is collect status and
1871 	 * pass information along. Any DMA handles have already been
1872 	 * freed.
1873 	 */
1874 	if (notify_cam == 0) {
1875 		isp_prt(isp, ISP_LOGTDEBUG0, "  INTER CTIO[0x%x] done", tval);
1876 		return (0);
1877 	}
1878 
1879 	isp_prt(isp, ISP_LOGTDEBUG0, "%s CTIO[0x%x] done",
1880 	    (sentstatus)? "  FINAL " : "MIDTERM ", tval);
1881 
1882 	if (!ok) {
1883 		isp_target_putback_atio(ccb);
1884 	} else {
1885 		isp_complete_ctio(ccb);
1886 
1887 	}
1888 	return (0);
1889 }
1890 
1891 static int
1892 isp_handle_platform_notify_scsi(ispsoftc_t *isp, in_entry_t *inp)
1893 {
1894 	return (0);	/* XXXX */
1895 }
1896 
1897 static int
1898 isp_handle_platform_notify_fc(ispsoftc_t *isp, in_fcentry_t *inp)
1899 {
1900 
1901 	switch (inp->in_status) {
1902 	case IN_PORT_LOGOUT:
1903 		isp_prt(isp, ISP_LOGWARN, "port logout of iid %d",
1904 		   inp->in_iid);
1905 		break;
1906 	case IN_PORT_CHANGED:
1907 		isp_prt(isp, ISP_LOGWARN, "port changed for iid %d",
1908 		   inp->in_iid);
1909 		break;
1910 	case IN_GLOBAL_LOGO:
1911 		isp_prt(isp, ISP_LOGINFO, "all ports logged out");
1912 		break;
1913 	case IN_ABORT_TASK:
1914 	{
1915 		atio_private_data_t *atp = isp_get_atpd(isp, inp->in_seqid);
1916 		struct ccb_immed_notify *inot = NULL;
1917 
1918 		if (atp) {
1919 			tstate_t *tptr = get_lun_statep(isp, 0, atp->lun);
1920 			if (tptr) {
1921 				inot = (struct ccb_immed_notify *)
1922 				    SLIST_FIRST(&tptr->inots);
1923 				if (inot) {
1924 					tptr->inot_count--;
1925 					SLIST_REMOVE_HEAD(&tptr->inots,
1926 					    sim_links.sle);
1927 					isp_prt(isp, ISP_LOGTDEBUG0,
1928 					    "Take FREE INOT count now %d",
1929 					    tptr->inot_count);
1930 				}
1931 			}
1932 			isp_prt(isp, ISP_LOGWARN,
1933 			   "abort task RX_ID %x IID %d state %d",
1934 			   inp->in_seqid, inp->in_iid, atp->state);
1935 		} else {
1936 			isp_prt(isp, ISP_LOGWARN,
1937 			   "abort task RX_ID %x from iid %d, state unknown",
1938 			   inp->in_seqid, inp->in_iid);
1939 		}
1940 		if (inot) {
1941 			inot->initiator_id = inp->in_iid;
1942 			inot->sense_len = 0;
1943 			inot->message_args[0] = MSG_ABORT_TAG;
1944 			inot->message_args[1] = inp->in_seqid & 0xff;
1945 			inot->message_args[2] = (inp->in_seqid >> 8) & 0xff;
1946 			inot->ccb_h.status = CAM_MESSAGE_RECV;
1947 			xpt_done((union ccb *)inot);
1948 		}
1949 		break;
1950 	}
1951 	default:
1952 		break;
1953 	}
1954 	return (0);
1955 }
1956 #endif
1957 
1958 static void
1959 isp_cam_async(void *cbarg, uint32_t code, struct cam_path *path, void *arg)
1960 {
1961 	struct cam_sim *sim;
1962 	ispsoftc_t *isp;
1963 
1964 	sim = (struct cam_sim *)cbarg;
1965 	isp = (ispsoftc_t *) cam_sim_softc(sim);
1966 	switch (code) {
1967 	case AC_LOST_DEVICE:
1968 		if (IS_SCSI(isp)) {
1969 			uint16_t oflags, nflags;
1970 			sdparam *sdp = isp->isp_param;
1971 			int tgt;
1972 
1973 			tgt = xpt_path_target_id(path);
1974 			if (tgt >= 0) {
1975 				sdp += cam_sim_bus(sim);
1976 				ISP_LOCK(isp);
1977 				nflags = sdp->isp_devparam[tgt].nvrm_flags;
1978 #ifndef	ISP_TARGET_MODE
1979 				nflags &= DPARM_SAFE_DFLT;
1980 				if (isp->isp_loaded_fw) {
1981 					nflags |= DPARM_NARROW | DPARM_ASYNC;
1982 				}
1983 #else
1984 				nflags = DPARM_DEFAULT;
1985 #endif
1986 				oflags = sdp->isp_devparam[tgt].goal_flags;
1987 				sdp->isp_devparam[tgt].goal_flags = nflags;
1988 				sdp->isp_devparam[tgt].dev_update = 1;
1989 				isp->isp_update |= (1 << cam_sim_bus(sim));
1990 				(void) isp_control(isp,
1991 				    ISPCTL_UPDATE_PARAMS, NULL);
1992 				sdp->isp_devparam[tgt].goal_flags = oflags;
1993 				ISP_UNLOCK(isp);
1994 			}
1995 		}
1996 		break;
1997 	default:
1998 		isp_prt(isp, ISP_LOGWARN, "isp_cam_async: Code 0x%x", code);
1999 		break;
2000 	}
2001 }
2002 
2003 static void
2004 isp_poll(struct cam_sim *sim)
2005 {
2006 	ispsoftc_t *isp = cam_sim_softc(sim);
2007 	uint16_t isr, sema, mbox;
2008 
2009 	ISP_LOCK(isp);
2010 	if (ISP_READ_ISR(isp, &isr, &sema, &mbox)) {
2011 		isp_intr(isp, isr, sema, mbox);
2012 	}
2013 	ISP_UNLOCK(isp);
2014 }
2015 
2016 
2017 static void
2018 isp_watchdog(void *arg)
2019 {
2020 	XS_T *xs = arg;
2021 	ispsoftc_t *isp = XS_ISP(xs);
2022 	uint32_t handle;
2023 	int iok;
2024 
2025 	/*
2026 	 * We've decided this command is dead. Make sure we're not trying
2027 	 * to kill a command that's already dead by getting it's handle and
2028 	 * and seeing whether it's still alive.
2029 	 */
2030 	ISP_LOCK(isp);
2031 	iok = isp->isp_osinfo.intsok;
2032 	isp->isp_osinfo.intsok = 0;
2033 	handle = isp_find_handle(isp, xs);
2034 	if (handle) {
2035 		uint16_t isr, sema, mbox;
2036 
2037 		if (XS_CMD_DONE_P(xs)) {
2038 			isp_prt(isp, ISP_LOGDEBUG1,
2039 			    "watchdog found done cmd (handle 0x%x)", handle);
2040 			ISP_UNLOCK(isp);
2041 			return;
2042 		}
2043 
2044 		if (XS_CMD_WDOG_P(xs)) {
2045 			isp_prt(isp, ISP_LOGDEBUG2,
2046 			    "recursive watchdog (handle 0x%x)", handle);
2047 			ISP_UNLOCK(isp);
2048 			return;
2049 		}
2050 
2051 		XS_CMD_S_WDOG(xs);
2052 		if (ISP_READ_ISR(isp, &isr, &sema, &mbox)) {
2053 			isp_intr(isp, isr, sema, mbox);
2054 		}
2055 		if (XS_CMD_DONE_P(xs)) {
2056 			isp_prt(isp, ISP_LOGDEBUG2,
2057 			    "watchdog cleanup for handle 0x%x", handle);
2058 			xpt_done((union ccb *) xs);
2059 		} else if (XS_CMD_GRACE_P(xs)) {
2060 			/*
2061 			 * Make sure the command is *really* dead before we
2062 			 * release the handle (and DMA resources) for reuse.
2063 			 */
2064 			(void) isp_control(isp, ISPCTL_ABORT_CMD, arg);
2065 
2066 			/*
2067 			 * After this point, the comamnd is really dead.
2068 			 */
2069 			if (XS_XFRLEN(xs)) {
2070 				ISP_DMAFREE(isp, xs, handle);
2071                 	}
2072 			isp_destroy_handle(isp, handle);
2073 			xpt_print_path(xs->ccb_h.path);
2074 			isp_prt(isp, ISP_LOGWARN,
2075 			    "watchdog timeout for handle 0x%x", handle);
2076 			XS_SETERR(xs, CAM_CMD_TIMEOUT);
2077 			XS_CMD_C_WDOG(xs);
2078 			isp_done(xs);
2079 		} else {
2080 			uint16_t nxti, optr;
2081 			ispreq_t local, *mp= &local, *qe;
2082 
2083 			XS_CMD_C_WDOG(xs);
2084 			xs->ccb_h.timeout_ch = timeout(isp_watchdog, xs, hz);
2085 			if (isp_getrqentry(isp, &nxti, &optr, (void **) &qe)) {
2086 				ISP_UNLOCK(isp);
2087 				return;
2088 			}
2089 			XS_CMD_S_GRACE(xs);
2090 			MEMZERO((void *) mp, sizeof (*mp));
2091 			mp->req_header.rqs_entry_count = 1;
2092 			mp->req_header.rqs_entry_type = RQSTYPE_MARKER;
2093 			mp->req_modifier = SYNC_ALL;
2094 			mp->req_target = XS_CHANNEL(xs) << 7;
2095 			isp_put_request(isp, mp, qe);
2096 			ISP_ADD_REQUEST(isp, nxti);
2097 		}
2098 	} else {
2099 		isp_prt(isp, ISP_LOGDEBUG2, "watchdog with no command");
2100 	}
2101 	isp->isp_osinfo.intsok = iok;
2102 	ISP_UNLOCK(isp);
2103 }
2104 
2105 static void
2106 isp_kthread(void *arg)
2107 {
2108 	ispsoftc_t *isp = arg;
2109 
2110 
2111 #if __FreeBSD_version < 500000
2112         int s;
2113 
2114         s = splcam();
2115         isp->isp_osinfo.intsok = 1;
2116 #else
2117 #ifdef	ISP_SMPLOCK
2118 	mtx_lock(&isp->isp_lock);
2119 #else
2120 	mtx_lock(&Giant);
2121 #endif
2122 #endif
2123 	/*
2124 	 * The first loop is for our usage where we have yet to have
2125 	 * gotten good fibre channel state.
2126 	 */
2127 	for (;;) {
2128 		int wasfrozen;
2129 
2130 		isp_prt(isp, ISP_LOGDEBUG0, "kthread: checking FC state");
2131 		while (isp_fc_runstate(isp, 2 * 1000000) != 0) {
2132 			isp_prt(isp, ISP_LOGDEBUG0, "kthread: FC state ungood");
2133 			if (FCPARAM(isp)->isp_fwstate != FW_READY ||
2134 			    FCPARAM(isp)->isp_loopstate < LOOP_PDB_RCVD) {
2135 				if (FCPARAM(isp)->loop_seen_once == 0 ||
2136 				    isp->isp_osinfo.ktmature == 0) {
2137 					break;
2138 				}
2139 			}
2140 #ifdef	ISP_SMPLOCK
2141 			msleep(isp_kthread, &isp->isp_lock,
2142 			    PRIBIO, "isp_fcthrd", hz);
2143 #else
2144 			(void) tsleep(isp_kthread, PRIBIO, "isp_fcthrd", hz);
2145 #endif
2146 		}
2147 
2148 		/*
2149 		 * Even if we didn't get good loop state we may be
2150 		 * unfreezing the SIMQ so that we can kill off
2151 		 * commands (if we've never seen loop before, for example).
2152 		 */
2153 		isp->isp_osinfo.ktmature = 1;
2154 		wasfrozen = isp->isp_osinfo.simqfrozen & SIMQFRZ_LOOPDOWN;
2155 		isp->isp_osinfo.simqfrozen &= ~SIMQFRZ_LOOPDOWN;
2156 		if (wasfrozen && isp->isp_osinfo.simqfrozen == 0) {
2157 			isp_prt(isp, ISP_LOGDEBUG0, "kthread: releasing simq");
2158 			ISPLOCK_2_CAMLOCK(isp);
2159 			xpt_release_simq(isp->isp_sim, 1);
2160 			CAMLOCK_2_ISPLOCK(isp);
2161 		}
2162 		isp_prt(isp, ISP_LOGDEBUG0, "kthread: waiting until called");
2163 #if __FreeBSD_version < 500000
2164 		tsleep(&isp->isp_osinfo.kproc, PRIBIO, "isp_fc_worker", 0);
2165 #else
2166 #ifdef	ISP_SMPLOCK
2167 		cv_wait(&isp->isp_osinfo.kthread_cv, &isp->isp_lock);
2168 #else
2169 		(void) tsleep(&isp->isp_osinfo.kthread_cv, PRIBIO, "fc_cv", 0);
2170 #endif
2171 #endif
2172 	}
2173 }
2174 
2175 static void
2176 isp_action(struct cam_sim *sim, union ccb *ccb)
2177 {
2178 	int bus, tgt, error;
2179 	ispsoftc_t *isp;
2180 	struct ccb_trans_settings *cts;
2181 
2182 	CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_TRACE, ("isp_action\n"));
2183 
2184 	isp = (ispsoftc_t *)cam_sim_softc(sim);
2185 	ccb->ccb_h.sim_priv.entries[0].field = 0;
2186 	ccb->ccb_h.sim_priv.entries[1].ptr = isp;
2187 	if (isp->isp_state != ISP_RUNSTATE &&
2188 	    ccb->ccb_h.func_code == XPT_SCSI_IO) {
2189 		CAMLOCK_2_ISPLOCK(isp);
2190 		isp_init(isp);
2191 		if (isp->isp_state != ISP_INITSTATE) {
2192 			ISP_UNLOCK(isp);
2193 			/*
2194 			 * Lie. Say it was a selection timeout.
2195 			 */
2196 			ccb->ccb_h.status = CAM_SEL_TIMEOUT | CAM_DEV_QFRZN;
2197 			xpt_freeze_devq(ccb->ccb_h.path, 1);
2198 			xpt_done(ccb);
2199 			return;
2200 		}
2201 		isp->isp_state = ISP_RUNSTATE;
2202 		ISPLOCK_2_CAMLOCK(isp);
2203 	}
2204 	isp_prt(isp, ISP_LOGDEBUG2, "isp_action code %x", ccb->ccb_h.func_code);
2205 
2206 
2207 	switch (ccb->ccb_h.func_code) {
2208 	case XPT_SCSI_IO:	/* Execute the requested I/O operation */
2209 		/*
2210 		 * Do a couple of preliminary checks...
2211 		 */
2212 		if ((ccb->ccb_h.flags & CAM_CDB_POINTER) != 0) {
2213 			if ((ccb->ccb_h.flags & CAM_CDB_PHYS) != 0) {
2214 				ccb->ccb_h.status = CAM_REQ_INVALID;
2215 				xpt_done(ccb);
2216 				break;
2217 			}
2218 		}
2219 #ifdef	DIAGNOSTIC
2220 		if (ccb->ccb_h.target_id > (ISP_MAX_TARGETS(isp) - 1)) {
2221 			ccb->ccb_h.status = CAM_PATH_INVALID;
2222 		} else if (ccb->ccb_h.target_lun > (ISP_MAX_LUNS(isp) - 1)) {
2223 			ccb->ccb_h.status = CAM_PATH_INVALID;
2224 		}
2225 		if (ccb->ccb_h.status == CAM_PATH_INVALID) {
2226 			isp_prt(isp, ISP_LOGERR,
2227 			    "invalid tgt/lun (%d.%d) in XPT_SCSI_IO",
2228 			    ccb->ccb_h.target_id, ccb->ccb_h.target_lun);
2229 			xpt_done(ccb);
2230 			break;
2231 		}
2232 #endif
2233 		((struct ccb_scsiio *) ccb)->scsi_status = SCSI_STATUS_OK;
2234 		CAMLOCK_2_ISPLOCK(isp);
2235 		error = isp_start((XS_T *) ccb);
2236 		switch (error) {
2237 		case CMD_QUEUED:
2238 			ccb->ccb_h.status |= CAM_SIM_QUEUED;
2239 			if (ccb->ccb_h.timeout != CAM_TIME_INFINITY) {
2240 				uint64_t ticks = (uint64_t) hz;
2241 				if (ccb->ccb_h.timeout == CAM_TIME_DEFAULT)
2242 					ticks = 60 * 1000 * ticks;
2243 				else
2244 					ticks = ccb->ccb_h.timeout * hz;
2245 				ticks = ((ticks + 999) / 1000) + hz + hz;
2246 				if (ticks >= 0x80000000) {
2247 					isp_prt(isp, ISP_LOGERR,
2248 					    "timeout overflow");
2249 					ticks = 0x7fffffff;
2250 				}
2251 				ccb->ccb_h.timeout_ch = timeout(isp_watchdog,
2252 				    (caddr_t)ccb, (int)ticks);
2253 			} else {
2254 				callout_handle_init(&ccb->ccb_h.timeout_ch);
2255 			}
2256 			ISPLOCK_2_CAMLOCK(isp);
2257 			break;
2258 		case CMD_RQLATER:
2259 			/*
2260 			 * This can only happen for Fibre Channel
2261 			 */
2262 			KASSERT((IS_FC(isp)), ("CMD_RQLATER for FC only"));
2263 			if (FCPARAM(isp)->loop_seen_once == 0 &&
2264 			    isp->isp_osinfo.ktmature) {
2265 				ISPLOCK_2_CAMLOCK(isp);
2266 				XS_SETERR(ccb, CAM_SEL_TIMEOUT);
2267 				xpt_done(ccb);
2268 				break;
2269 			}
2270 #if __FreeBSD_version < 500000
2271 			wakeup(&isp->isp_osinfo.kproc);
2272 #else
2273 #ifdef	ISP_SMPLOCK
2274 			cv_signal(&isp->isp_osinfo.kthread_cv);
2275 #else
2276 			wakeup(&isp->isp_osinfo.kthread_cv);
2277 #endif
2278 #endif
2279 			isp_freeze_loopdown(isp, "isp_action(RQLATER)");
2280 			XS_SETERR(ccb, CAM_REQUEUE_REQ);
2281 			ISPLOCK_2_CAMLOCK(isp);
2282 			xpt_done(ccb);
2283 			break;
2284 		case CMD_EAGAIN:
2285 			XS_SETERR(ccb, CAM_REQUEUE_REQ);
2286 			ISPLOCK_2_CAMLOCK(isp);
2287 			xpt_done(ccb);
2288 			break;
2289 		case CMD_COMPLETE:
2290 			isp_done((struct ccb_scsiio *) ccb);
2291 			ISPLOCK_2_CAMLOCK(isp);
2292 			break;
2293 		default:
2294 			isp_prt(isp, ISP_LOGERR,
2295 			    "What's this? 0x%x at %d in file %s",
2296 			    error, __LINE__, __FILE__);
2297 			XS_SETERR(ccb, CAM_REQ_CMP_ERR);
2298 			xpt_done(ccb);
2299 			ISPLOCK_2_CAMLOCK(isp);
2300 		}
2301 		break;
2302 
2303 #ifdef	ISP_TARGET_MODE
2304 	case XPT_EN_LUN:		/* Enable LUN as a target */
2305 	{
2306 		int seq, iok, i;
2307 		CAMLOCK_2_ISPLOCK(isp);
2308 		iok = isp->isp_osinfo.intsok;
2309 		isp->isp_osinfo.intsok = 0;
2310 		seq = isp_en_lun(isp, ccb);
2311 		if (seq < 0) {
2312 			isp->isp_osinfo.intsok = iok;
2313 			ISPLOCK_2_CAMLOCK(isp);
2314 			xpt_done(ccb);
2315 			break;
2316 		}
2317 		for (i = 0; isp->isp_osinfo.leact[seq] && i < 30 * 1000; i++) {
2318 			uint16_t isr, sema, mbox;
2319 			if (ISP_READ_ISR(isp, &isr, &sema, &mbox)) {
2320 				isp_intr(isp, isr, sema, mbox);
2321 			}
2322 			DELAY(1000);
2323 		}
2324 		isp->isp_osinfo.intsok = iok;
2325 		ISPLOCK_2_CAMLOCK(isp);
2326 		break;
2327 	}
2328 	case XPT_NOTIFY_ACK:		/* recycle notify ack */
2329 	case XPT_IMMED_NOTIFY:		/* Add Immediate Notify Resource */
2330 	case XPT_ACCEPT_TARGET_IO:	/* Add Accept Target IO Resource */
2331 	{
2332 		tstate_t *tptr =
2333 		    get_lun_statep(isp, XS_CHANNEL(ccb), ccb->ccb_h.target_lun);
2334 		if (tptr == NULL) {
2335 			ccb->ccb_h.status = CAM_LUN_INVALID;
2336 			xpt_done(ccb);
2337 			break;
2338 		}
2339 		ccb->ccb_h.sim_priv.entries[0].field = 0;
2340 		ccb->ccb_h.sim_priv.entries[1].ptr = isp;
2341 		ccb->ccb_h.flags = 0;
2342 
2343 		CAMLOCK_2_ISPLOCK(isp);
2344 		if (ccb->ccb_h.func_code == XPT_ACCEPT_TARGET_IO) {
2345 			/*
2346 			 * Note that the command itself may not be done-
2347 			 * it may not even have had the first CTIO sent.
2348 			 */
2349 			tptr->atio_count++;
2350 			isp_prt(isp, ISP_LOGTDEBUG0,
2351 			    "Put FREE ATIO, lun %d, count now %d",
2352 			    ccb->ccb_h.target_lun, tptr->atio_count);
2353 			SLIST_INSERT_HEAD(&tptr->atios, &ccb->ccb_h,
2354 			    sim_links.sle);
2355 		} else if (ccb->ccb_h.func_code == XPT_IMMED_NOTIFY) {
2356 			tptr->inot_count++;
2357 			isp_prt(isp, ISP_LOGTDEBUG0,
2358 			    "Put FREE INOT, lun %d, count now %d",
2359 			    ccb->ccb_h.target_lun, tptr->inot_count);
2360 			SLIST_INSERT_HEAD(&tptr->inots, &ccb->ccb_h,
2361 			    sim_links.sle);
2362 		} else {
2363 			isp_prt(isp, ISP_LOGWARN, "Got Notify ACK");;
2364 		}
2365 		rls_lun_statep(isp, tptr);
2366 		ccb->ccb_h.status = CAM_REQ_INPROG;
2367 		ISPLOCK_2_CAMLOCK(isp);
2368 		break;
2369 	}
2370 	case XPT_CONT_TARGET_IO:
2371 	{
2372 		CAMLOCK_2_ISPLOCK(isp);
2373 		isp_target_start_ctio(isp, ccb);
2374 		ISPLOCK_2_CAMLOCK(isp);
2375 		break;
2376 	}
2377 #endif
2378 	case XPT_RESET_DEV:		/* BDR the specified SCSI device */
2379 
2380 		bus = cam_sim_bus(xpt_path_sim(ccb->ccb_h.path));
2381 		tgt = ccb->ccb_h.target_id;
2382 		tgt |= (bus << 16);
2383 
2384 		CAMLOCK_2_ISPLOCK(isp);
2385 		error = isp_control(isp, ISPCTL_RESET_DEV, &tgt);
2386 		ISPLOCK_2_CAMLOCK(isp);
2387 		if (error) {
2388 			ccb->ccb_h.status = CAM_REQ_CMP_ERR;
2389 		} else {
2390 			ccb->ccb_h.status = CAM_REQ_CMP;
2391 		}
2392 		xpt_done(ccb);
2393 		break;
2394 	case XPT_ABORT:			/* Abort the specified CCB */
2395 	{
2396 		union ccb *accb = ccb->cab.abort_ccb;
2397 		CAMLOCK_2_ISPLOCK(isp);
2398 		switch (accb->ccb_h.func_code) {
2399 #ifdef	ISP_TARGET_MODE
2400 		case XPT_ACCEPT_TARGET_IO:
2401 		case XPT_IMMED_NOTIFY:
2402         		ccb->ccb_h.status = isp_abort_tgt_ccb(isp, ccb);
2403 			break;
2404 		case XPT_CONT_TARGET_IO:
2405 			isp_prt(isp, ISP_LOGERR, "cannot abort CTIOs yet");
2406 			ccb->ccb_h.status = CAM_UA_ABORT;
2407 			break;
2408 #endif
2409 		case XPT_SCSI_IO:
2410 			error = isp_control(isp, ISPCTL_ABORT_CMD, ccb);
2411 			if (error) {
2412 				ccb->ccb_h.status = CAM_UA_ABORT;
2413 			} else {
2414 				ccb->ccb_h.status = CAM_REQ_CMP;
2415 			}
2416 			break;
2417 		default:
2418 			ccb->ccb_h.status = CAM_REQ_INVALID;
2419 			break;
2420 		}
2421 		ISPLOCK_2_CAMLOCK(isp);
2422 		xpt_done(ccb);
2423 		break;
2424 	}
2425 #ifdef	CAM_NEW_TRAN_CODE
2426 #define	IS_CURRENT_SETTINGS(c)	(c->type == CTS_TYPE_CURRENT_SETTINGS)
2427 #else
2428 #define	IS_CURRENT_SETTINGS(c)	(c->flags & CCB_TRANS_CURRENT_SETTINGS)
2429 #endif
2430 	case XPT_SET_TRAN_SETTINGS:	/* Nexus Settings */
2431 		cts = &ccb->cts;
2432 		if (!IS_CURRENT_SETTINGS(cts)) {
2433 			ccb->ccb_h.status = CAM_REQ_INVALID;
2434 			xpt_done(ccb);
2435 			break;
2436 		}
2437 		tgt = cts->ccb_h.target_id;
2438 		CAMLOCK_2_ISPLOCK(isp);
2439 		if (IS_SCSI(isp)) {
2440 #ifndef	CAM_NEW_TRAN_CODE
2441 			sdparam *sdp = isp->isp_param;
2442 			uint16_t *dptr;
2443 
2444 			bus = cam_sim_bus(xpt_path_sim(cts->ccb_h.path));
2445 
2446 			sdp += bus;
2447 			/*
2448 			 * We always update (internally) from goal_flags
2449 			 * so any request to change settings just gets
2450 			 * vectored to that location.
2451 			 */
2452 			dptr = &sdp->isp_devparam[tgt].goal_flags;
2453 
2454 			/*
2455 			 * Note that these operations affect the
2456 			 * the goal flags (goal_flags)- not
2457 			 * the current state flags. Then we mark
2458 			 * things so that the next operation to
2459 			 * this HBA will cause the update to occur.
2460 			 */
2461 			if (cts->valid & CCB_TRANS_DISC_VALID) {
2462 				if ((cts->flags & CCB_TRANS_DISC_ENB) != 0) {
2463 					*dptr |= DPARM_DISC;
2464 				} else {
2465 					*dptr &= ~DPARM_DISC;
2466 				}
2467 			}
2468 			if (cts->valid & CCB_TRANS_TQ_VALID) {
2469 				if ((cts->flags & CCB_TRANS_TAG_ENB) != 0) {
2470 					*dptr |= DPARM_TQING;
2471 				} else {
2472 					*dptr &= ~DPARM_TQING;
2473 				}
2474 			}
2475 			if (cts->valid & CCB_TRANS_BUS_WIDTH_VALID) {
2476 				switch (cts->bus_width) {
2477 				case MSG_EXT_WDTR_BUS_16_BIT:
2478 					*dptr |= DPARM_WIDE;
2479 					break;
2480 				default:
2481 					*dptr &= ~DPARM_WIDE;
2482 				}
2483 			}
2484 			/*
2485 			 * Any SYNC RATE of nonzero and SYNC_OFFSET
2486 			 * of nonzero will cause us to go to the
2487 			 * selected (from NVRAM) maximum value for
2488 			 * this device. At a later point, we'll
2489 			 * allow finer control.
2490 			 */
2491 			if ((cts->valid & CCB_TRANS_SYNC_RATE_VALID) &&
2492 			    (cts->valid & CCB_TRANS_SYNC_OFFSET_VALID) &&
2493 			    (cts->sync_offset > 0)) {
2494 				*dptr |= DPARM_SYNC;
2495 			} else {
2496 				*dptr &= ~DPARM_SYNC;
2497 			}
2498 			*dptr |= DPARM_SAFE_DFLT;
2499 #else
2500 			struct ccb_trans_settings_scsi *scsi =
2501 			    &cts->proto_specific.scsi;
2502 			struct ccb_trans_settings_spi *spi =
2503 			    &cts->xport_specific.spi;
2504 			sdparam *sdp = isp->isp_param;
2505 			uint16_t *dptr;
2506 
2507 			bus = cam_sim_bus(xpt_path_sim(cts->ccb_h.path));
2508 			sdp += bus;
2509 			/*
2510 			 * We always update (internally) from goal_flags
2511 			 * so any request to change settings just gets
2512 			 * vectored to that location.
2513 			 */
2514 			dptr = &sdp->isp_devparam[tgt].goal_flags;
2515 
2516 			if ((spi->valid & CTS_SPI_VALID_DISC) != 0) {
2517 				if ((spi->flags & CTS_SPI_FLAGS_DISC_ENB) != 0)
2518 					*dptr |= DPARM_DISC;
2519 				else
2520 					*dptr &= ~DPARM_DISC;
2521 			}
2522 
2523 			if ((scsi->valid & CTS_SCSI_VALID_TQ) != 0) {
2524 				if ((scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) != 0)
2525 					*dptr |= DPARM_TQING;
2526 				else
2527 					*dptr &= ~DPARM_TQING;
2528 			}
2529 
2530 			if ((spi->valid & CTS_SPI_VALID_BUS_WIDTH) != 0) {
2531 				if (spi->bus_width == MSG_EXT_WDTR_BUS_16_BIT)
2532 					*dptr |= DPARM_WIDE;
2533 				else
2534 					*dptr &= ~DPARM_WIDE;
2535 			}
2536 
2537 			/*
2538 			 * XXX: FIX ME
2539 			 */
2540 			if ((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) &&
2541 			    (spi->valid & CTS_SPI_VALID_SYNC_RATE) &&
2542 			    (spi->sync_period && spi->sync_offset)) {
2543 				*dptr |= DPARM_SYNC;
2544 				/*
2545 				 * XXX: CHECK FOR LEGALITY
2546 				 */
2547 				sdp->isp_devparam[tgt].goal_period =
2548 				    spi->sync_period;
2549 				sdp->isp_devparam[tgt].goal_offset =
2550 				    spi->sync_offset;
2551 			} else {
2552 				*dptr &= ~DPARM_SYNC;
2553 			}
2554 #endif
2555 			isp_prt(isp, ISP_LOGDEBUG0,
2556 			    "SET bus %d targ %d to flags %x off %x per %x",
2557 			    bus, tgt, sdp->isp_devparam[tgt].goal_flags,
2558 			    sdp->isp_devparam[tgt].goal_offset,
2559 			    sdp->isp_devparam[tgt].goal_period);
2560 			sdp->isp_devparam[tgt].dev_update = 1;
2561 			isp->isp_update |= (1 << bus);
2562 		}
2563 		ISPLOCK_2_CAMLOCK(isp);
2564 		ccb->ccb_h.status = CAM_REQ_CMP;
2565 		xpt_done(ccb);
2566 		break;
2567 	case XPT_GET_TRAN_SETTINGS:
2568 		cts = &ccb->cts;
2569 		tgt = cts->ccb_h.target_id;
2570 		CAMLOCK_2_ISPLOCK(isp);
2571 		if (IS_FC(isp)) {
2572 #ifndef	CAM_NEW_TRAN_CODE
2573 			/*
2574 			 * a lot of normal SCSI things don't make sense.
2575 			 */
2576 			cts->flags = CCB_TRANS_TAG_ENB | CCB_TRANS_DISC_ENB;
2577 			cts->valid = CCB_TRANS_DISC_VALID | CCB_TRANS_TQ_VALID;
2578 			/*
2579 			 * How do you measure the width of a high
2580 			 * speed serial bus? Well, in bytes.
2581 			 *
2582 			 * Offset and period make no sense, though, so we set
2583 			 * (above) a 'base' transfer speed to be gigabit.
2584 			 */
2585 			cts->bus_width = MSG_EXT_WDTR_BUS_8_BIT;
2586 #else
2587 			fcparam *fcp = isp->isp_param;
2588 			struct ccb_trans_settings_fc *fc =
2589 			    &cts->xport_specific.fc;
2590 
2591 			cts->protocol = PROTO_SCSI;
2592 			cts->protocol_version = SCSI_REV_2;
2593 			cts->transport = XPORT_FC;
2594 			cts->transport_version = 0;
2595 
2596 			fc->valid = CTS_FC_VALID_SPEED;
2597 			if (fcp->isp_gbspeed == 2)
2598 				fc->bitrate = 200000;
2599 			else
2600 				fc->bitrate = 100000;
2601 			if (tgt > 0 && tgt < MAX_FC_TARG) {
2602 				struct lportdb *lp = &fcp->portdb[tgt];
2603 				fc->wwnn = lp->node_wwn;
2604 				fc->wwpn = lp->port_wwn;
2605 				fc->port = lp->portid;
2606 				fc->valid |= CTS_FC_VALID_WWNN |
2607 				    CTS_FC_VALID_WWPN | CTS_FC_VALID_PORT;
2608 			}
2609 #endif
2610 		} else {
2611 #ifdef	CAM_NEW_TRAN_CODE
2612 			struct ccb_trans_settings_scsi *scsi =
2613 			    &cts->proto_specific.scsi;
2614 			struct ccb_trans_settings_spi *spi =
2615 			    &cts->xport_specific.spi;
2616 #endif
2617 			sdparam *sdp = isp->isp_param;
2618 			int bus = cam_sim_bus(xpt_path_sim(cts->ccb_h.path));
2619 			uint16_t dval, pval, oval;
2620 
2621 			sdp += bus;
2622 
2623 			if (IS_CURRENT_SETTINGS(cts)) {
2624 				sdp->isp_devparam[tgt].dev_refresh = 1;
2625 				isp->isp_update |= (1 << bus);
2626 				(void) isp_control(isp, ISPCTL_UPDATE_PARAMS,
2627 				    NULL);
2628 				dval = sdp->isp_devparam[tgt].actv_flags;
2629 				oval = sdp->isp_devparam[tgt].actv_offset;
2630 				pval = sdp->isp_devparam[tgt].actv_period;
2631 			} else {
2632 				dval = sdp->isp_devparam[tgt].nvrm_flags;
2633 				oval = sdp->isp_devparam[tgt].nvrm_offset;
2634 				pval = sdp->isp_devparam[tgt].nvrm_period;
2635 			}
2636 
2637 #ifndef	CAM_NEW_TRAN_CODE
2638 			cts->flags &= ~(CCB_TRANS_DISC_ENB|CCB_TRANS_TAG_ENB);
2639 
2640 			if (dval & DPARM_DISC) {
2641 				cts->flags |= CCB_TRANS_DISC_ENB;
2642 			}
2643 			if (dval & DPARM_TQING) {
2644 				cts->flags |= CCB_TRANS_TAG_ENB;
2645 			}
2646 			if (dval & DPARM_WIDE) {
2647 				cts->bus_width = MSG_EXT_WDTR_BUS_16_BIT;
2648 			} else {
2649 				cts->bus_width = MSG_EXT_WDTR_BUS_8_BIT;
2650 			}
2651 			cts->valid = CCB_TRANS_BUS_WIDTH_VALID |
2652 			    CCB_TRANS_DISC_VALID | CCB_TRANS_TQ_VALID;
2653 
2654 			if ((dval & DPARM_SYNC) && oval != 0) {
2655 				cts->sync_period = pval;
2656 				cts->sync_offset = oval;
2657 				cts->valid |=
2658 				    CCB_TRANS_SYNC_RATE_VALID |
2659 				    CCB_TRANS_SYNC_OFFSET_VALID;
2660 			}
2661 #else
2662 			cts->protocol = PROTO_SCSI;
2663 			cts->protocol_version = SCSI_REV_2;
2664 			cts->transport = XPORT_SPI;
2665 			cts->transport_version = 2;
2666 
2667 			scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB;
2668 			spi->flags &= ~CTS_SPI_FLAGS_DISC_ENB;
2669 			if (dval & DPARM_DISC) {
2670 				spi->flags |= CTS_SPI_FLAGS_DISC_ENB;
2671 			}
2672 			if (dval & DPARM_TQING) {
2673 				scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB;
2674 			}
2675 			if ((dval & DPARM_SYNC) && oval && pval) {
2676 				spi->sync_offset = oval;
2677 				spi->sync_period = pval;
2678 				spi->valid |= CTS_SPI_VALID_SYNC_OFFSET;
2679 				spi->valid |= CTS_SPI_VALID_SYNC_RATE;
2680 			}
2681 			spi->valid |= CTS_SPI_VALID_BUS_WIDTH;
2682 			if (dval & DPARM_WIDE) {
2683 				spi->bus_width = MSG_EXT_WDTR_BUS_16_BIT;
2684 			} else {
2685 				spi->bus_width = MSG_EXT_WDTR_BUS_8_BIT;
2686 			}
2687 			if (cts->ccb_h.target_lun != CAM_LUN_WILDCARD) {
2688 				scsi->valid = CTS_SCSI_VALID_TQ;
2689 				spi->valid |= CTS_SPI_VALID_DISC;
2690 			} else {
2691 				scsi->valid = 0;
2692 			}
2693 #endif
2694 			isp_prt(isp, ISP_LOGDEBUG0,
2695 			    "GET %s bus %d targ %d to flags %x off %x per %x",
2696 			    IS_CURRENT_SETTINGS(cts)? "ACTIVE" : "NVRAM",
2697 			    bus, tgt, dval, oval, pval);
2698 		}
2699 		ISPLOCK_2_CAMLOCK(isp);
2700 		ccb->ccb_h.status = CAM_REQ_CMP;
2701 		xpt_done(ccb);
2702 		break;
2703 
2704 	case XPT_CALC_GEOMETRY:
2705 #if __FreeBSD_version < 500000
2706 	{
2707 		struct ccb_calc_geometry *ccg;
2708 		u_int32_t secs_per_cylinder;
2709 		u_int32_t size_mb;
2710 
2711 		ccg = &ccb->ccg;
2712 		if (ccg->block_size == 0) {
2713 			ccb->ccb_h.status = CAM_REQ_INVALID;
2714 			xpt_done(ccb);
2715 			break;
2716 		}
2717 		size_mb = ccg->volume_size /((1024L * 1024L) / ccg->block_size);
2718 		if (size_mb > 1024) {
2719 			ccg->heads = 255;
2720 			ccg->secs_per_track = 63;
2721 		} else {
2722 			ccg->heads = 64;
2723 			ccg->secs_per_track = 32;
2724 		}
2725 		secs_per_cylinder = ccg->heads * ccg->secs_per_track;
2726 		ccg->cylinders = ccg->volume_size / secs_per_cylinder;
2727 		ccb->ccb_h.status = CAM_REQ_CMP;
2728 		xpt_done(ccb);
2729 		break;
2730 	}
2731 #else
2732 	{
2733 		cam_calc_geometry(&ccb->ccg, /*extended*/1);
2734 		xpt_done(ccb);
2735 		break;
2736 	}
2737 #endif
2738 	case XPT_RESET_BUS:		/* Reset the specified bus */
2739 		bus = cam_sim_bus(sim);
2740 		CAMLOCK_2_ISPLOCK(isp);
2741 		error = isp_control(isp, ISPCTL_RESET_BUS, &bus);
2742 		ISPLOCK_2_CAMLOCK(isp);
2743 		if (error)
2744 			ccb->ccb_h.status = CAM_REQ_CMP_ERR;
2745 		else {
2746 			if (cam_sim_bus(sim) && isp->isp_path2 != NULL)
2747 				xpt_async(AC_BUS_RESET, isp->isp_path2, NULL);
2748 			else if (isp->isp_path != NULL)
2749 				xpt_async(AC_BUS_RESET, isp->isp_path, NULL);
2750 			ccb->ccb_h.status = CAM_REQ_CMP;
2751 		}
2752 		xpt_done(ccb);
2753 		break;
2754 
2755 	case XPT_TERM_IO:		/* Terminate the I/O process */
2756 		ccb->ccb_h.status = CAM_REQ_INVALID;
2757 		xpt_done(ccb);
2758 		break;
2759 
2760 	case XPT_PATH_INQ:		/* Path routing inquiry */
2761 	{
2762 		struct ccb_pathinq *cpi = &ccb->cpi;
2763 
2764 		cpi->version_num = 1;
2765 #ifdef	ISP_TARGET_MODE
2766 		cpi->target_sprt = PIT_PROCESSOR | PIT_DISCONNECT | PIT_TERM_IO;
2767 #else
2768 		cpi->target_sprt = 0;
2769 #endif
2770 		cpi->hba_eng_cnt = 0;
2771 		cpi->max_target = ISP_MAX_TARGETS(isp) - 1;
2772 		cpi->max_lun = ISP_MAX_LUNS(isp) - 1;
2773 		cpi->bus_id = cam_sim_bus(sim);
2774 		if (IS_FC(isp)) {
2775 			cpi->hba_misc = PIM_NOBUSRESET;
2776 			/*
2777 			 * Because our loop ID can shift from time to time,
2778 			 * make our initiator ID out of range of our bus.
2779 			 */
2780 			cpi->initiator_id = cpi->max_target + 1;
2781 
2782 			/*
2783 			 * Set base transfer capabilities for Fibre Channel.
2784 			 * Technically not correct because we don't know
2785 			 * what media we're running on top of- but we'll
2786 			 * look good if we always say 100MB/s.
2787 			 */
2788 			if (FCPARAM(isp)->isp_gbspeed == 2)
2789 				cpi->base_transfer_speed = 200000;
2790 			else
2791 				cpi->base_transfer_speed = 100000;
2792 			cpi->hba_inquiry = PI_TAG_ABLE;
2793 #ifdef	CAM_NEW_TRAN_CODE
2794 			cpi->transport = XPORT_FC;
2795 			cpi->transport_version = 0;	/* WHAT'S THIS FOR? */
2796 #endif
2797 		} else {
2798 			sdparam *sdp = isp->isp_param;
2799 			sdp += cam_sim_bus(xpt_path_sim(cpi->ccb_h.path));
2800 			cpi->hba_inquiry = PI_SDTR_ABLE|PI_TAG_ABLE|PI_WIDE_16;
2801 			cpi->hba_misc = 0;
2802 			cpi->initiator_id = sdp->isp_initiator_id;
2803 			cpi->base_transfer_speed = 3300;
2804 #ifdef	CAM_NEW_TRAN_CODE
2805 			cpi->transport = XPORT_SPI;
2806 			cpi->transport_version = 2;	/* WHAT'S THIS FOR? */
2807 #endif
2808 		}
2809 #ifdef	CAM_NEW_TRAN_CODE
2810 		cpi->protocol = PROTO_SCSI;
2811 		cpi->protocol_version = SCSI_REV_2;
2812 #endif
2813 		strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN);
2814 		strncpy(cpi->hba_vid, "Qlogic", HBA_IDLEN);
2815 		strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN);
2816 		cpi->unit_number = cam_sim_unit(sim);
2817 		cpi->ccb_h.status = CAM_REQ_CMP;
2818 		xpt_done(ccb);
2819 		break;
2820 	}
2821 	default:
2822 		ccb->ccb_h.status = CAM_REQ_INVALID;
2823 		xpt_done(ccb);
2824 		break;
2825 	}
2826 }
2827 
2828 #define	ISPDDB	(CAM_DEBUG_INFO|CAM_DEBUG_TRACE|CAM_DEBUG_CDB)
2829 void
2830 isp_done(struct ccb_scsiio *sccb)
2831 {
2832 	ispsoftc_t *isp = XS_ISP(sccb);
2833 
2834 	if (XS_NOERR(sccb))
2835 		XS_SETERR(sccb, CAM_REQ_CMP);
2836 
2837 	if ((sccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP &&
2838 	    (sccb->scsi_status != SCSI_STATUS_OK)) {
2839 		sccb->ccb_h.status &= ~CAM_STATUS_MASK;
2840 		if ((sccb->scsi_status == SCSI_STATUS_CHECK_COND) &&
2841 		    (sccb->ccb_h.status & CAM_AUTOSNS_VALID) == 0) {
2842 			sccb->ccb_h.status |= CAM_AUTOSENSE_FAIL;
2843 		} else {
2844 			sccb->ccb_h.status |= CAM_SCSI_STATUS_ERROR;
2845 		}
2846 	}
2847 
2848 	sccb->ccb_h.status &= ~CAM_SIM_QUEUED;
2849 	if ((sccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
2850 		if ((sccb->ccb_h.status & CAM_DEV_QFRZN) == 0) {
2851 			sccb->ccb_h.status |= CAM_DEV_QFRZN;
2852 			xpt_freeze_devq(sccb->ccb_h.path, 1);
2853 			isp_prt(isp, ISP_LOGDEBUG0,
2854 			    "freeze devq %d.%d cam sts %x scsi sts %x",
2855 			    sccb->ccb_h.target_id, sccb->ccb_h.target_lun,
2856 			    sccb->ccb_h.status, sccb->scsi_status);
2857 		}
2858 	}
2859 
2860 	if ((CAM_DEBUGGED(sccb->ccb_h.path, ISPDDB)) &&
2861 	    (sccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
2862 		xpt_print_path(sccb->ccb_h.path);
2863 		isp_prt(isp, ISP_LOGINFO,
2864 		    "cam completion status 0x%x", sccb->ccb_h.status);
2865 	}
2866 
2867 	XS_CMD_S_DONE(sccb);
2868 	if (XS_CMD_WDOG_P(sccb) == 0) {
2869 		untimeout(isp_watchdog, (caddr_t)sccb, sccb->ccb_h.timeout_ch);
2870 		if (XS_CMD_GRACE_P(sccb)) {
2871 			isp_prt(isp, ISP_LOGDEBUG2,
2872 			    "finished command on borrowed time");
2873 		}
2874 		XS_CMD_S_CLEAR(sccb);
2875 		ISPLOCK_2_CAMLOCK(isp);
2876 		xpt_done((union ccb *) sccb);
2877 		CAMLOCK_2_ISPLOCK(isp);
2878 	}
2879 }
2880 
2881 int
2882 isp_async(ispsoftc_t *isp, ispasync_t cmd, void *arg)
2883 {
2884 	int bus, rv = 0;
2885 	switch (cmd) {
2886 	case ISPASYNC_NEW_TGT_PARAMS:
2887 	{
2888 #ifdef	CAM_NEW_TRAN_CODE
2889 		struct ccb_trans_settings_scsi *scsi;
2890 		struct ccb_trans_settings_spi *spi;
2891 #endif
2892 		int flags, tgt;
2893 		sdparam *sdp = isp->isp_param;
2894 		struct ccb_trans_settings cts;
2895 		struct cam_path *tmppath;
2896 
2897 		memset(&cts, 0, sizeof (struct ccb_trans_settings));
2898 
2899 		tgt = *((int *)arg);
2900 		bus = (tgt >> 16) & 0xffff;
2901 		tgt &= 0xffff;
2902 		sdp += bus;
2903 		ISPLOCK_2_CAMLOCK(isp);
2904 		if (xpt_create_path(&tmppath, NULL,
2905 		    cam_sim_path(bus? isp->isp_sim2 : isp->isp_sim),
2906 		    tgt, CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
2907 			CAMLOCK_2_ISPLOCK(isp);
2908 			isp_prt(isp, ISP_LOGWARN,
2909 			    "isp_async cannot make temp path for %d.%d",
2910 			    tgt, bus);
2911 			rv = -1;
2912 			break;
2913 		}
2914 		CAMLOCK_2_ISPLOCK(isp);
2915 		flags = sdp->isp_devparam[tgt].actv_flags;
2916 #ifdef	CAM_NEW_TRAN_CODE
2917 		cts.type = CTS_TYPE_CURRENT_SETTINGS;
2918 		cts.protocol = PROTO_SCSI;
2919 		cts.transport = XPORT_SPI;
2920 
2921 		scsi = &cts.proto_specific.scsi;
2922 		spi = &cts.xport_specific.spi;
2923 
2924 		if (flags & DPARM_TQING) {
2925 			scsi->valid |= CTS_SCSI_VALID_TQ;
2926 			scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB;
2927 			spi->flags |= CTS_SPI_FLAGS_TAG_ENB;
2928 		}
2929 
2930 		if (flags & DPARM_DISC) {
2931 			spi->valid |= CTS_SPI_VALID_DISC;
2932 			spi->flags |= CTS_SPI_FLAGS_DISC_ENB;
2933 		}
2934 		spi->flags |= CTS_SPI_VALID_BUS_WIDTH;
2935 		if (flags & DPARM_WIDE) {
2936 			spi->bus_width = MSG_EXT_WDTR_BUS_16_BIT;
2937 		} else {
2938 			spi->bus_width = MSG_EXT_WDTR_BUS_8_BIT;
2939 		}
2940 		if (flags & DPARM_SYNC) {
2941 			spi->valid |= CTS_SPI_VALID_SYNC_RATE;
2942 			spi->valid |= CTS_SPI_VALID_SYNC_OFFSET;
2943 			spi->sync_period = sdp->isp_devparam[tgt].actv_period;
2944 			spi->sync_offset = sdp->isp_devparam[tgt].actv_offset;
2945 		}
2946 #else
2947 		cts.flags = CCB_TRANS_CURRENT_SETTINGS;
2948 		cts.valid = CCB_TRANS_DISC_VALID | CCB_TRANS_TQ_VALID;
2949 		if (flags & DPARM_DISC) {
2950 			cts.flags |= CCB_TRANS_DISC_ENB;
2951 		}
2952 		if (flags & DPARM_TQING) {
2953 			cts.flags |= CCB_TRANS_TAG_ENB;
2954 		}
2955 		cts.valid |= CCB_TRANS_BUS_WIDTH_VALID;
2956 		cts.bus_width = (flags & DPARM_WIDE)?
2957 		    MSG_EXT_WDTR_BUS_8_BIT : MSG_EXT_WDTR_BUS_16_BIT;
2958 		cts.sync_period = sdp->isp_devparam[tgt].actv_period;
2959 		cts.sync_offset = sdp->isp_devparam[tgt].actv_offset;
2960 		if (flags & DPARM_SYNC) {
2961 			cts.valid |=
2962 			    CCB_TRANS_SYNC_RATE_VALID |
2963 			    CCB_TRANS_SYNC_OFFSET_VALID;
2964 		}
2965 #endif
2966 		isp_prt(isp, ISP_LOGDEBUG2,
2967 		    "NEW_TGT_PARAMS bus %d tgt %d period %x offset %x flags %x",
2968 		    bus, tgt, sdp->isp_devparam[tgt].actv_period,
2969 		    sdp->isp_devparam[tgt].actv_offset, flags);
2970 		xpt_setup_ccb(&cts.ccb_h, tmppath, 1);
2971 		ISPLOCK_2_CAMLOCK(isp);
2972 		xpt_async(AC_TRANSFER_NEG, tmppath, &cts);
2973 		xpt_free_path(tmppath);
2974 		CAMLOCK_2_ISPLOCK(isp);
2975 		break;
2976 	}
2977 	case ISPASYNC_BUS_RESET:
2978 		bus = *((int *)arg);
2979 		isp_prt(isp, ISP_LOGINFO, "SCSI bus reset on bus %d detected",
2980 		    bus);
2981 		if (bus > 0 && isp->isp_path2) {
2982 			ISPLOCK_2_CAMLOCK(isp);
2983 			xpt_async(AC_BUS_RESET, isp->isp_path2, NULL);
2984 			CAMLOCK_2_ISPLOCK(isp);
2985 		} else if (isp->isp_path) {
2986 			ISPLOCK_2_CAMLOCK(isp);
2987 			xpt_async(AC_BUS_RESET, isp->isp_path, NULL);
2988 			CAMLOCK_2_ISPLOCK(isp);
2989 		}
2990 		break;
2991 	case ISPASYNC_LIP:
2992 		if (isp->isp_path) {
2993 			isp_freeze_loopdown(isp, "ISPASYNC_LIP");
2994 		}
2995 		isp_prt(isp, ISP_LOGINFO, "LIP Received");
2996 		break;
2997 	case ISPASYNC_LOOP_RESET:
2998 		if (isp->isp_path) {
2999 			isp_freeze_loopdown(isp, "ISPASYNC_LOOP_RESET");
3000 		}
3001 		isp_prt(isp, ISP_LOGINFO, "Loop Reset Received");
3002 		break;
3003 	case ISPASYNC_LOOP_DOWN:
3004 		if (isp->isp_path) {
3005 			isp_freeze_loopdown(isp, "ISPASYNC_LOOP_DOWN");
3006 		}
3007 		isp_prt(isp, ISP_LOGINFO, "Loop DOWN");
3008 		break;
3009 	case ISPASYNC_LOOP_UP:
3010 		/*
3011 		 * Now we just note that Loop has come up. We don't
3012 		 * actually do anything because we're waiting for a
3013 		 * Change Notify before activating the FC cleanup
3014 		 * thread to look at the state of the loop again.
3015 		 */
3016 		isp_prt(isp, ISP_LOGINFO, "Loop UP");
3017 		break;
3018 	case ISPASYNC_PROMENADE:
3019 	{
3020 		const char *fmt = "Target %d (Loop 0x%x) Port ID 0x%x "
3021 		    "(role %s) %s\n Port WWN 0x%08x%08x\n Node WWN 0x%08x%08x";
3022 		static const char *roles[4] = {
3023 		    "(none)", "Target", "Initiator", "Target/Initiator"
3024 		};
3025 		fcparam *fcp = isp->isp_param;
3026 		int tgt = *((int *) arg);
3027 #if __FreeBSD_version >= 500000
3028 		int is_tgt_mask = (SVC3_TGT_ROLE >> SVC3_ROLE_SHIFT);
3029 		struct cam_path *tmppath;
3030 #endif
3031 		struct lportdb *lp = &fcp->portdb[tgt];
3032 
3033 		isp_prt(isp, ISP_LOGINFO, fmt, tgt, lp->loopid, lp->portid,
3034 		    roles[lp->roles & 0x3],
3035 		    (lp->valid)? "Arrived" : "Departed",
3036 		    (uint32_t) (lp->port_wwn >> 32),
3037 		    (uint32_t) (lp->port_wwn & 0xffffffffLL),
3038 		    (uint32_t) (lp->node_wwn >> 32),
3039 		    (uint32_t) (lp->node_wwn & 0xffffffffLL));
3040 
3041 		ISPLOCK_2_CAMLOCK(isp);
3042 #if __FreeBSD_version >= 500000
3043 		if (xpt_create_path(&tmppath, NULL, cam_sim_path(isp->isp_sim),
3044 		    (target_id_t)tgt, CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
3045 			CAMLOCK_2_ISPLOCK(isp);
3046                         break;
3047                 }
3048 		/*
3049 		 * Policy: only announce targets.
3050 		 */
3051 		if (lp->roles & is_tgt_mask) {
3052 			if (lp->valid) {
3053 				xpt_async(AC_FOUND_DEVICE, tmppath, NULL);
3054 			} else {
3055 				xpt_async(AC_LOST_DEVICE, tmppath, NULL);
3056 			}
3057 		}
3058 		xpt_free_path(tmppath);
3059 #endif
3060 		CAMLOCK_2_ISPLOCK(isp);
3061 		break;
3062 	}
3063 	case ISPASYNC_CHANGE_NOTIFY:
3064 		if (arg == ISPASYNC_CHANGE_PDB) {
3065 			isp_prt(isp, ISP_LOGINFO,
3066 			    "Port Database Changed");
3067 		} else if (arg == ISPASYNC_CHANGE_SNS) {
3068 			isp_prt(isp, ISP_LOGINFO,
3069 			    "Name Server Database Changed");
3070 		}
3071 #if __FreeBSD_version < 500000
3072 		wakeup(&isp->isp_osinfo.kproc);
3073 #else
3074 #ifdef	ISP_SMPLOCK
3075 		cv_signal(&isp->isp_osinfo.kthread_cv);
3076 #else
3077 		wakeup(&isp->isp_osinfo.kthread_cv);
3078 #endif
3079 #endif
3080 		break;
3081 	case ISPASYNC_FABRIC_DEV:
3082 	{
3083 		int target, base, lim;
3084 		fcparam *fcp = isp->isp_param;
3085 		struct lportdb *lp = NULL;
3086 		struct lportdb *clp = (struct lportdb *) arg;
3087 		char *pt;
3088 
3089 		switch (clp->port_type) {
3090 		case 1:
3091 			pt = "   N_Port";
3092 			break;
3093 		case 2:
3094 			pt = "  NL_Port";
3095 			break;
3096 		case 3:
3097 			pt = "F/NL_Port";
3098 			break;
3099 		case 0x7f:
3100 			pt = "  Nx_Port";
3101 			break;
3102 		case 0x81:
3103 			pt = "  F_port";
3104 			break;
3105 		case 0x82:
3106 			pt = "  FL_Port";
3107 			break;
3108 		case 0x84:
3109 			pt = "   E_port";
3110 			break;
3111 		default:
3112 			pt = " ";
3113 			break;
3114 		}
3115 
3116 		isp_prt(isp, ISP_LOGINFO,
3117 		    "%s Fabric Device @ PortID 0x%x", pt, clp->portid);
3118 
3119 		/*
3120 		 * If we don't have an initiator role we bail.
3121 		 *
3122 		 * We just use ISPASYNC_FABRIC_DEV for announcement purposes.
3123 		 */
3124 
3125 		if ((isp->isp_role & ISP_ROLE_INITIATOR) == 0) {
3126 			break;
3127 		}
3128 
3129 		/*
3130 		 * Is this entry for us? If so, we bail.
3131 		 */
3132 
3133 		if (fcp->isp_portid == clp->portid) {
3134 			break;
3135 		}
3136 
3137 		/*
3138 		 * Else, the default policy is to find room for it in
3139 		 * our local port database. Later, when we execute
3140 		 * the call to isp_pdb_sync either this newly arrived
3141 		 * or already logged in device will be (re)announced.
3142 		 */
3143 
3144 		if (fcp->isp_topo == TOPO_FL_PORT)
3145 			base = FC_SNS_ID+1;
3146 		else
3147 			base = 0;
3148 
3149 		if (fcp->isp_topo == TOPO_N_PORT)
3150 			lim = 1;
3151 		else
3152 			lim = MAX_FC_TARG;
3153 
3154 		/*
3155 		 * Is it already in our list?
3156 		 */
3157 		for (target = base; target < lim; target++) {
3158 			if (target >= FL_PORT_ID && target <= FC_SNS_ID) {
3159 				continue;
3160 			}
3161 			lp = &fcp->portdb[target];
3162 			if (lp->port_wwn == clp->port_wwn &&
3163 			    lp->node_wwn == clp->node_wwn) {
3164 				lp->fabric_dev = 1;
3165 				break;
3166 			}
3167 		}
3168 		if (target < lim) {
3169 			break;
3170 		}
3171 		for (target = base; target < lim; target++) {
3172 			if (target >= FL_PORT_ID && target <= FC_SNS_ID) {
3173 				continue;
3174 			}
3175 			lp = &fcp->portdb[target];
3176 			if (lp->port_wwn == 0) {
3177 				break;
3178 			}
3179 		}
3180 		if (target == lim) {
3181 			isp_prt(isp, ISP_LOGWARN,
3182 			    "out of space for fabric devices");
3183 			break;
3184 		}
3185 		lp->port_type = clp->port_type;
3186 		lp->fc4_type = clp->fc4_type;
3187 		lp->node_wwn = clp->node_wwn;
3188 		lp->port_wwn = clp->port_wwn;
3189 		lp->portid = clp->portid;
3190 		lp->fabric_dev = 1;
3191 		break;
3192 	}
3193 #ifdef	ISP_TARGET_MODE
3194 	case ISPASYNC_TARGET_NOTIFY:
3195 	{
3196 		tmd_notify_t *nt = arg;
3197 		isp_prt(isp, ISP_LOGALL,
3198 		    "target notify code 0x%x", nt->nt_ncode);
3199 		break;
3200 	}
3201 	case ISPASYNC_TARGET_ACTION:
3202 		switch (((isphdr_t *)arg)->rqs_entry_type) {
3203 		default:
3204 			isp_prt(isp, ISP_LOGWARN,
3205 			   "event 0x%x for unhandled target action",
3206 			    ((isphdr_t *)arg)->rqs_entry_type);
3207 			break;
3208 		case RQSTYPE_NOTIFY:
3209 			if (IS_SCSI(isp)) {
3210 				rv = isp_handle_platform_notify_scsi(isp,
3211 				    (in_entry_t *) arg);
3212 			} else {
3213 				rv = isp_handle_platform_notify_fc(isp,
3214 				    (in_fcentry_t *) arg);
3215 			}
3216 			break;
3217 		case RQSTYPE_ATIO:
3218 			rv = isp_handle_platform_atio(isp, (at_entry_t *) arg);
3219 			break;
3220 		case RQSTYPE_ATIO2:
3221 			rv = isp_handle_platform_atio2(isp, (at2_entry_t *)arg);
3222 			break;
3223 		case RQSTYPE_CTIO3:
3224 		case RQSTYPE_CTIO2:
3225 		case RQSTYPE_CTIO:
3226 			rv = isp_handle_platform_ctio(isp, arg);
3227 			break;
3228 		case RQSTYPE_ENABLE_LUN:
3229 		case RQSTYPE_MODIFY_LUN:
3230 			isp_ledone(isp, (lun_entry_t *) arg);
3231 			break;
3232 		}
3233 		break;
3234 #endif
3235 	case ISPASYNC_FW_CRASH:
3236 	{
3237 		uint16_t mbox1, mbox6;
3238 		mbox1 = ISP_READ(isp, OUTMAILBOX1);
3239 		if (IS_DUALBUS(isp)) {
3240 			mbox6 = ISP_READ(isp, OUTMAILBOX6);
3241 		} else {
3242 			mbox6 = 0;
3243 		}
3244                 isp_prt(isp, ISP_LOGERR,
3245                     "Internal Firmware Error on bus %d @ RISC Address 0x%x",
3246                     mbox6, mbox1);
3247 #ifdef	ISP_FW_CRASH_DUMP
3248 		/*
3249 		 * XXX: really need a thread to do this right.
3250 		 */
3251 		if (IS_FC(isp)) {
3252 			FCPARAM(isp)->isp_fwstate = FW_CONFIG_WAIT;
3253 			FCPARAM(isp)->isp_loopstate = LOOP_NIL;
3254 			isp_freeze_loopdown(isp, "f/w crash");
3255 			isp_fw_dump(isp);
3256 		}
3257 		isp_reinit(isp);
3258 		isp_async(isp, ISPASYNC_FW_RESTARTED, NULL);
3259 #endif
3260 		break;
3261 	}
3262 	case ISPASYNC_UNHANDLED_RESPONSE:
3263 		break;
3264 	default:
3265 		isp_prt(isp, ISP_LOGERR, "unknown isp_async event %d", cmd);
3266 		break;
3267 	}
3268 	return (rv);
3269 }
3270 
3271 
3272 /*
3273  * Locks are held before coming here.
3274  */
3275 void
3276 isp_uninit(ispsoftc_t *isp)
3277 {
3278 	ISP_WRITE(isp, HCCR, HCCR_CMD_RESET);
3279 	DISABLE_INTS(isp);
3280 }
3281 
3282 void
3283 isp_prt(ispsoftc_t *isp, int level, const char *fmt, ...)
3284 {
3285 	va_list ap;
3286 	if (level != ISP_LOGALL && (level & isp->isp_dblev) == 0) {
3287 		return;
3288 	}
3289 	printf("%s: ", device_get_nameunit(isp->isp_dev));
3290 	va_start(ap, fmt);
3291 	vprintf(fmt, ap);
3292 	va_end(ap);
3293 	printf("\n");
3294 }
3295