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