xref: /freebsd/sys/dev/isp/isp_freebsd.c (revision 1a2cdef4962b47be5057809ce730a733b7f3c27c)
1 /* $FreeBSD$ */
2 /*
3  * Platform (FreeBSD) dependent common attachment code for Qlogic adapters.
4  *
5  * Copyright (c) 1997, 1998, 1999, 2000, 2001 by Matthew Jacob
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 #include <dev/isp/isp_freebsd.h>
29 #include <machine/stdarg.h>	/* for use by isp_prt below */
30 
31 
32 static void isp_intr_enable(void *);
33 static void isp_cam_async(void *, u_int32_t, struct cam_path *, void *);
34 static void isp_poll(struct cam_sim *);
35 static void isp_relsim(void *);
36 static timeout_t isp_watchdog;
37 static void isp_action(struct cam_sim *, union ccb *);
38 
39 
40 static struct ispsoftc *isplist = NULL;
41 
42 void
43 isp_attach(struct ispsoftc *isp)
44 {
45 	int primary, secondary;
46 	struct ccb_setasync csa;
47 	struct cam_devq *devq;
48 	struct cam_sim *sim;
49 	struct cam_path *path;
50 
51 	/*
52 	 * Establish (in case of 12X0) which bus is the primary.
53 	 */
54 
55 	primary = 0;
56 	secondary = 1;
57 
58 	/*
59 	 * Create the device queue for our SIM(s).
60 	 */
61 	devq = cam_simq_alloc(isp->isp_maxcmds);
62 	if (devq == NULL) {
63 		return;
64 	}
65 
66 	/*
67 	 * Construct our SIM entry.
68 	 */
69 	sim = cam_sim_alloc(isp_action, isp_poll, "isp", isp,
70 	    device_get_unit(isp->isp_dev), 1, isp->isp_maxcmds, devq);
71 	if (sim == NULL) {
72 		cam_simq_free(devq);
73 		return;
74 	}
75 
76 	isp->isp_osinfo.ehook.ich_func = isp_intr_enable;
77 	isp->isp_osinfo.ehook.ich_arg = isp;
78 	if (config_intrhook_establish(&isp->isp_osinfo.ehook) != 0) {
79 		isp_prt(isp, ISP_LOGERR,
80 		    "could not establish interrupt enable hook");
81 		cam_sim_free(sim, TRUE);
82 		return;
83 	}
84 
85 	if (xpt_bus_register(sim, primary) != CAM_SUCCESS) {
86 		cam_sim_free(sim, TRUE);
87 		return;
88 	}
89 
90 	if (xpt_create_path(&path, NULL, cam_sim_path(sim),
91 	    CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
92 		xpt_bus_deregister(cam_sim_path(sim));
93 		cam_sim_free(sim, TRUE);
94 		return;
95 	}
96 
97 	xpt_setup_ccb(&csa.ccb_h, path, 5);
98 	csa.ccb_h.func_code = XPT_SASYNC_CB;
99 	csa.event_enable = AC_LOST_DEVICE;
100 	csa.callback = isp_cam_async;
101 	csa.callback_arg = sim;
102 	xpt_action((union ccb *)&csa);
103 	isp->isp_sim = sim;
104 	isp->isp_path = path;
105 
106 	/*
107 	 * If we have a second channel, construct SIM entry for that.
108 	 */
109 	if (IS_DUALBUS(isp)) {
110 		sim = cam_sim_alloc(isp_action, isp_poll, "isp", isp,
111 		    device_get_unit(isp->isp_dev), 1, isp->isp_maxcmds, devq);
112 		if (sim == NULL) {
113 			xpt_bus_deregister(cam_sim_path(isp->isp_sim));
114 			xpt_free_path(isp->isp_path);
115 			cam_simq_free(devq);
116 			return;
117 		}
118 		if (xpt_bus_register(sim, secondary) != CAM_SUCCESS) {
119 			xpt_bus_deregister(cam_sim_path(isp->isp_sim));
120 			xpt_free_path(isp->isp_path);
121 			cam_sim_free(sim, TRUE);
122 			return;
123 		}
124 
125 		if (xpt_create_path(&path, NULL, cam_sim_path(sim),
126 		    CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
127 			xpt_bus_deregister(cam_sim_path(isp->isp_sim));
128 			xpt_free_path(isp->isp_path);
129 			xpt_bus_deregister(cam_sim_path(sim));
130 			cam_sim_free(sim, TRUE);
131 			return;
132 		}
133 
134 		xpt_setup_ccb(&csa.ccb_h, path, 5);
135 		csa.ccb_h.func_code = XPT_SASYNC_CB;
136 		csa.event_enable = AC_LOST_DEVICE;
137 		csa.callback = isp_cam_async;
138 		csa.callback_arg = sim;
139 		xpt_action((union ccb *)&csa);
140 		isp->isp_sim2 = sim;
141 		isp->isp_path2 = path;
142 	}
143 	if (isp->isp_role != ISP_ROLE_NONE) {
144 		isp->isp_state = ISP_RUNSTATE;
145 		ENABLE_INTS(isp);
146 	}
147 	if (isplist == NULL) {
148 		isplist = isp;
149 	} else {
150 		struct ispsoftc *tmp = isplist;
151 		while (tmp->isp_osinfo.next) {
152 			tmp = tmp->isp_osinfo.next;
153 		}
154 		tmp->isp_osinfo.next = isp;
155 	}
156 }
157 
158 static void
159 isp_intr_enable(void *arg)
160 {
161 	struct ispsoftc *isp = arg;
162 	if (isp->isp_role != ISP_ROLE_NONE) {
163 		ENABLE_INTS(isp);
164 		isp->isp_osinfo.intsok = 1;
165 	}
166 	/* Release our hook so that the boot can continue. */
167 	config_intrhook_disestablish(&isp->isp_osinfo.ehook);
168 }
169 
170 /*
171  * Put the target mode functions here, because some are inlines
172  */
173 
174 #ifdef	ISP_TARGET_MODE
175 
176 static __inline int is_lun_enabled(struct ispsoftc *, int, lun_id_t);
177 static __inline int are_any_luns_enabled(struct ispsoftc *, int);
178 static __inline tstate_t *get_lun_statep(struct ispsoftc *, int, lun_id_t);
179 static __inline void rls_lun_statep(struct ispsoftc *, tstate_t *);
180 static __inline int isp_psema_sig_rqe(struct ispsoftc *);
181 static __inline int isp_cv_wait_timed_rqe(struct ispsoftc *, int);
182 static __inline void isp_cv_signal_rqe(struct ispsoftc *, int);
183 static __inline void isp_vsema_rqe(struct ispsoftc *);
184 static cam_status
185 create_lun_state(struct ispsoftc *, int, struct cam_path *, tstate_t **);
186 static void destroy_lun_state(struct ispsoftc *, tstate_t *);
187 static void isp_en_lun(struct ispsoftc *, union ccb *);
188 static cam_status isp_abort_tgt_ccb(struct ispsoftc *, union ccb *);
189 static timeout_t isp_refire_putback_atio;
190 static void isp_complete_ctio(union ccb *);
191 static void isp_target_putback_atio(union ccb *);
192 static cam_status isp_target_start_ctio(struct ispsoftc *, union ccb *);
193 static int isp_handle_platform_atio(struct ispsoftc *, at_entry_t *);
194 static int isp_handle_platform_atio2(struct ispsoftc *, at2_entry_t *);
195 static int isp_handle_platform_ctio(struct ispsoftc *, void *);
196 
197 static __inline int
198 is_lun_enabled(struct ispsoftc *isp, int bus, lun_id_t lun)
199 {
200 	tstate_t *tptr;
201 	ISP_LOCK(isp);
202 	tptr = isp->isp_osinfo.lun_hash[LUN_HASH_FUNC(isp, bus, lun)];
203 	if (tptr == NULL) {
204 		ISP_UNLOCK(isp);
205 		return (0);
206 	}
207 	do {
208 		if (tptr->lun == (lun_id_t) lun && tptr->bus == bus) {
209 			ISP_UNLOCK(isp);
210 			return (1);
211 		}
212 	} while ((tptr = tptr->next) != NULL);
213 	ISP_UNLOCK(isp);
214 	return (0);
215 }
216 
217 static __inline int
218 are_any_luns_enabled(struct ispsoftc *isp, int port)
219 {
220 	int lo, hi;
221 	if (IS_DUALBUS(isp)) {
222 		lo = (port * (LUN_HASH_SIZE >> 1));
223 		hi = lo + (LUN_HASH_SIZE >> 1);
224 	} else {
225 		lo = 0;
226 		hi = LUN_HASH_SIZE;
227 	}
228 	for (lo = 0; lo < hi; lo++) {
229 		if (isp->isp_osinfo.lun_hash[lo]) {
230 			return (1);
231 		}
232 	}
233 	return (0);
234 }
235 
236 static __inline tstate_t *
237 get_lun_statep(struct ispsoftc *isp, int bus, lun_id_t lun)
238 {
239 	tstate_t *tptr;
240 
241 	ISP_LOCK(isp);
242 	if (lun == CAM_LUN_WILDCARD) {
243 		tptr = &isp->isp_osinfo.tsdflt[bus];
244 		tptr->hold++;
245 		ISP_UNLOCK(isp);
246 		return (tptr);
247 	} else {
248 		tptr = isp->isp_osinfo.lun_hash[LUN_HASH_FUNC(isp, bus, lun)];
249 	}
250 	if (tptr == NULL) {
251 		ISP_UNLOCK(isp);
252 		return (NULL);
253 	}
254 
255 	do {
256 		if (tptr->lun == lun && tptr->bus == bus) {
257 			tptr->hold++;
258 			ISP_UNLOCK(isp);
259 			return (tptr);
260 		}
261 	} while ((tptr = tptr->next) != NULL);
262 	ISP_UNLOCK(isp);
263 	return (tptr);
264 }
265 
266 static __inline void
267 rls_lun_statep(struct ispsoftc *isp, tstate_t *tptr)
268 {
269 	if (tptr->hold)
270 		tptr->hold--;
271 }
272 
273 static __inline int
274 isp_psema_sig_rqe(struct ispsoftc *isp)
275 {
276 	ISP_LOCK(isp);
277 	while (isp->isp_osinfo.tmflags & TM_BUSY) {
278 		isp->isp_osinfo.tmflags |= TM_WANTED;
279 		if (tsleep(&isp->isp_osinfo.tmflags, PRIBIO|PCATCH, "i0", 0)) {
280 			ISP_UNLOCK(isp);
281 			return (-1);
282 		}
283 		isp->isp_osinfo.tmflags |= TM_BUSY;
284 	}
285 	ISP_UNLOCK(isp);
286 	return (0);
287 }
288 
289 static __inline int
290 isp_cv_wait_timed_rqe(struct ispsoftc *isp, int timo)
291 {
292 	ISP_LOCK(isp);
293 	if (tsleep(&isp->isp_osinfo.rstatus, PRIBIO, "qt1", timo)) {
294 		ISP_UNLOCK(isp);
295 		return (-1);
296 	}
297 	ISP_UNLOCK(isp);
298 	return (0);
299 }
300 
301 static __inline void
302 isp_cv_signal_rqe(struct ispsoftc *isp, int status)
303 {
304 	isp->isp_osinfo.rstatus = status;
305 	wakeup(&isp->isp_osinfo.rstatus);
306 }
307 
308 static __inline void
309 isp_vsema_rqe(struct ispsoftc *isp)
310 {
311 	ISP_LOCK(isp);
312 	if (isp->isp_osinfo.tmflags & TM_WANTED) {
313 		isp->isp_osinfo.tmflags &= ~TM_WANTED;
314 		wakeup(&isp->isp_osinfo.tmflags);
315 	}
316 	isp->isp_osinfo.tmflags &= ~TM_BUSY;
317 	ISP_UNLOCK(isp);
318 }
319 
320 static cam_status
321 create_lun_state(struct ispsoftc *isp, int bus,
322     struct cam_path *path, tstate_t **rslt)
323 {
324 	cam_status status;
325 	lun_id_t lun;
326 	int hfx;
327 	tstate_t *tptr, *new;
328 
329 	lun = xpt_path_lun_id(path);
330 	if (lun < 0) {
331 		return (CAM_LUN_INVALID);
332 	}
333 	if (is_lun_enabled(isp, bus, lun)) {
334 		return (CAM_LUN_ALRDY_ENA);
335 	}
336 	new = (tstate_t *) malloc(sizeof (tstate_t), M_DEVBUF, M_NOWAIT|M_ZERO);
337 	if (new == NULL) {
338 		return (CAM_RESRC_UNAVAIL);
339 	}
340 
341 	status = xpt_create_path(&new->owner, NULL, xpt_path_path_id(path),
342 	    xpt_path_target_id(path), xpt_path_lun_id(path));
343 	if (status != CAM_REQ_CMP) {
344 		free(new, M_DEVBUF);
345 		return (status);
346 	}
347 	new->bus = bus;
348 	new->lun = lun;
349 	SLIST_INIT(&new->atios);
350 	SLIST_INIT(&new->inots);
351 	new->hold = 1;
352 
353 	hfx = LUN_HASH_FUNC(isp, new->bus, new->lun);
354 	ISP_LOCK(isp);
355 	tptr = isp->isp_osinfo.lun_hash[hfx];
356 	if (tptr == NULL) {
357 		isp->isp_osinfo.lun_hash[hfx] = new;
358 	} else {
359 		while (tptr->next)
360 			tptr = tptr->next;
361 		tptr->next = new;
362 	}
363 	ISP_UNLOCK(isp);
364 	*rslt = new;
365 	return (CAM_REQ_CMP);
366 }
367 
368 static __inline void
369 destroy_lun_state(struct ispsoftc *isp, tstate_t *tptr)
370 {
371 	int hfx;
372 	tstate_t *lw, *pw;
373 
374 	hfx = LUN_HASH_FUNC(isp, tptr->bus, tptr->lun);
375 	ISP_LOCK(isp);
376 	if (tptr->hold) {
377 		ISP_UNLOCK(isp);
378 		return;
379 	}
380 	pw = isp->isp_osinfo.lun_hash[hfx];
381 	if (pw == NULL) {
382 		ISP_UNLOCK(isp);
383 		return;
384 	} else if (pw->lun == tptr->lun && pw->bus == tptr->bus) {
385 		isp->isp_osinfo.lun_hash[hfx] = pw->next;
386 	} else {
387 		lw = pw;
388 		pw = lw->next;
389 		while (pw) {
390 			if (pw->lun == tptr->lun && pw->bus == tptr->bus) {
391 				lw->next = pw->next;
392 				break;
393 			}
394 			lw = pw;
395 			pw = pw->next;
396 		}
397 		if (pw == NULL) {
398 			ISP_UNLOCK(isp);
399 			return;
400 		}
401 	}
402 	free(tptr, M_DEVBUF);
403 	ISP_UNLOCK(isp);
404 }
405 
406 static void
407 isp_en_lun(struct ispsoftc *isp, union ccb *ccb)
408 {
409 	const char lfmt[] = "Lun now %sabled for target mode on channel %d";
410 	struct ccb_en_lun *cel = &ccb->cel;
411 	tstate_t *tptr;
412 	u_int16_t rstat;
413 	int bus, frozen = 0;
414 	lun_id_t lun;
415 	target_id_t tgt;
416 
417 
418 	bus = XS_CHANNEL(ccb) & 0x1;
419 	tgt = ccb->ccb_h.target_id;
420 	lun = ccb->ccb_h.target_lun;
421 
422 	/*
423 	 * Do some sanity checking first.
424 	 */
425 
426 	if ((lun != CAM_LUN_WILDCARD) &&
427 	    (lun < 0 || lun >= (lun_id_t) isp->isp_maxluns)) {
428 		ccb->ccb_h.status = CAM_LUN_INVALID;
429 		return;
430 	}
431 	if (IS_SCSI(isp)) {
432 		sdparam *sdp = isp->isp_param;
433 		sdp += bus;
434 		if (tgt != CAM_TARGET_WILDCARD &&
435 		    tgt != sdp->isp_initiator_id) {
436 			ccb->ccb_h.status = CAM_TID_INVALID;
437 			return;
438 		}
439 	} else {
440 		if (tgt != CAM_TARGET_WILDCARD &&
441 		    tgt != FCPARAM(isp)->isp_iid) {
442 			ccb->ccb_h.status = CAM_TID_INVALID;
443 			return;
444 		}
445 	}
446 
447 	if (tgt == CAM_TARGET_WILDCARD) {
448 		if (lun != CAM_LUN_WILDCARD) {
449 			ccb->ccb_h.status = CAM_LUN_INVALID;
450 			return;
451 		}
452 	}
453 
454 	/*
455 	 * If Fibre Channel, stop and drain all activity to this bus.
456 	 */
457 #if	0
458 	if (IS_FC(isp)) {
459 		ISP_LOCK(isp);
460 		frozen = 1;
461 		xpt_freeze_simq(isp->isp_sim, 1);
462 		isp->isp_osinfo.drain = 1;
463 		while (isp->isp_osinfo.drain) {
464 			 (void) msleep(&isp->isp_osinfo.drain,
465 				    &isp->isp_osinfo.lock, PRIBIO,
466 				    "ispdrain", 10 * hz);
467 		}
468 		ISP_UNLOCK(isp);
469 	}
470 #endif
471 
472 	/*
473 	 * Check to see if we're enabling on fibre channel and
474 	 * don't yet have a notion of who the heck we are (no
475 	 * loop yet).
476 	 */
477 	if (IS_FC(isp) && cel->enable &&
478 	    (isp->isp_osinfo.tmflags & TM_TMODE_ENABLED) == 0) {
479 		fcparam *fcp = isp->isp_param;
480 		int rv;
481 
482 		ISP_LOCK(isp);
483 		rv = isp_fc_runstate(isp, 2 * 1000000);
484 		ISP_UNLOCK(isp);
485 		if (fcp->isp_fwstate != FW_READY ||
486 		    fcp->isp_loopstate != LOOP_READY) {
487 			xpt_print_path(ccb->ccb_h.path);
488 			isp_prt(isp, ISP_LOGWARN,
489 			    "could not get a good port database read");
490 			ccb->ccb_h.status = CAM_REQ_CMP_ERR;
491 			if (frozen)
492 				xpt_release_simq(isp->isp_sim, 1);
493 			return;
494 		}
495 	}
496 
497 
498 	/*
499 	 * Next check to see whether this is a target/lun wildcard action.
500 	 *
501 	 * If so, we enable/disable target mode but don't do any lun enabling.
502 	 */
503 	if (lun == CAM_LUN_WILDCARD && tgt == CAM_TARGET_WILDCARD) {
504 		int av = bus << 31;
505 		tptr = &isp->isp_osinfo.tsdflt[bus];
506 		if (cel->enable) {
507 			if (isp->isp_osinfo.tmflags & (1 << bus)) {
508 				ccb->ccb_h.status = CAM_LUN_ALRDY_ENA;
509 				if (frozen)
510 					xpt_release_simq(isp->isp_sim, 1);
511 				return;
512 			}
513 			ccb->ccb_h.status =
514 			    xpt_create_path(&tptr->owner, NULL,
515 			    xpt_path_path_id(ccb->ccb_h.path),
516 			    xpt_path_target_id(ccb->ccb_h.path),
517 			    xpt_path_lun_id(ccb->ccb_h.path));
518 			if (ccb->ccb_h.status != CAM_REQ_CMP) {
519 				if (frozen)
520 					xpt_release_simq(isp->isp_sim, 1);
521 				return;
522 			}
523 			SLIST_INIT(&tptr->atios);
524 			SLIST_INIT(&tptr->inots);
525 			av |= ENABLE_TARGET_FLAG;
526 			ISP_LOCK(isp);
527 			av = isp_control(isp, ISPCTL_TOGGLE_TMODE, &av);
528 			if (av) {
529 				ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
530 				xpt_free_path(tptr->owner);
531 				ISP_UNLOCK(isp);
532 				if (frozen)
533 					xpt_release_simq(isp->isp_sim, 1);
534 				return;
535 			}
536 			isp->isp_osinfo.tmflags |= (1 << bus);
537 			ISP_UNLOCK(isp);
538 		} else {
539 			if ((isp->isp_osinfo.tmflags & (1 << bus)) == 0) {
540 				ccb->ccb_h.status = CAM_LUN_INVALID;
541 				if (frozen)
542 					xpt_release_simq(isp->isp_sim, 1);
543 				return;
544 			}
545 			if (are_any_luns_enabled(isp, bus)) {
546 				ccb->ccb_h.status = CAM_SCSI_BUSY;
547 				if (frozen)
548 					xpt_release_simq(isp->isp_sim, 1);
549 				return;
550 			}
551 			ISP_LOCK(isp);
552 			av = isp_control(isp, ISPCTL_TOGGLE_TMODE, &av);
553 			if (av) {
554 				ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
555 				ISP_UNLOCK(isp);
556 				if (frozen)
557 					xpt_release_simq(isp->isp_sim, 1);
558 				return;
559 			}
560 			isp->isp_osinfo.tmflags &= ~(1 << bus);
561 			ISP_UNLOCK(isp);
562 			ccb->ccb_h.status = CAM_REQ_CMP;
563 		}
564 		xpt_print_path(ccb->ccb_h.path);
565 		isp_prt(isp, ISP_LOGINFO, "Target Mode %sabled on channel %d",
566 		    (cel->enable) ? "en" : "dis", bus);
567 		if (frozen)
568 			xpt_release_simq(isp->isp_sim, 1);
569 		return;
570 	}
571 
572 	/*
573 	 * We can move along now...
574 	 */
575 
576 	if (frozen)
577 		xpt_release_simq(isp->isp_sim, 1);
578 
579 
580 	if (cel->enable) {
581 		ccb->ccb_h.status =
582 		    create_lun_state(isp, bus, ccb->ccb_h.path, &tptr);
583 		if (ccb->ccb_h.status != CAM_REQ_CMP) {
584 			return;
585 		}
586 	} else {
587 		tptr = get_lun_statep(isp, bus, lun);
588 		if (tptr == NULL) {
589 			ccb->ccb_h.status = CAM_LUN_INVALID;
590 			return;
591 		}
592 	}
593 
594 	if (isp_psema_sig_rqe(isp)) {
595 		rls_lun_statep(isp, tptr);
596 		if (cel->enable)
597 			destroy_lun_state(isp, tptr);
598 		ccb->ccb_h.status = CAM_REQ_CMP_ERR;
599 		return;
600 	}
601 
602 	ISP_LOCK(isp);
603 	if (cel->enable) {
604 		u_int32_t seq = isp->isp_osinfo.rollinfo++;
605 		rstat = LUN_ERR;
606 		if (isp_lun_cmd(isp, RQSTYPE_ENABLE_LUN, bus, tgt, lun, seq)) {
607 			xpt_print_path(ccb->ccb_h.path);
608 			isp_prt(isp, ISP_LOGWARN, "isp_lun_cmd failed");
609 			goto out;
610 		}
611 		if (isp_cv_wait_timed_rqe(isp, 30 * hz)) {
612 			xpt_print_path(ccb->ccb_h.path);
613 			isp_prt(isp, ISP_LOGERR,
614 			    "wait for ENABLE LUN timed out");
615 			goto out;
616 		}
617 		rstat = isp->isp_osinfo.rstatus;
618 		if (rstat != LUN_OK) {
619 			xpt_print_path(ccb->ccb_h.path);
620 			isp_prt(isp, ISP_LOGERR,
621 			    "ENABLE LUN returned 0x%x", rstat);
622 			goto out;
623 		}
624 	} else {
625 		u_int32_t seq;
626 
627 		seq = isp->isp_osinfo.rollinfo++;
628 		rstat = LUN_ERR;
629 
630 		if (isp_lun_cmd(isp, -RQSTYPE_MODIFY_LUN, bus, tgt, lun, seq)) {
631 			xpt_print_path(ccb->ccb_h.path);
632 			isp_prt(isp, ISP_LOGERR, "isp_lun_cmd failed");
633 			goto out;
634 		}
635 		if (isp_cv_wait_timed_rqe(isp, 30 * hz)) {
636 			xpt_print_path(ccb->ccb_h.path);
637 			isp_prt(isp, ISP_LOGERR,
638 			    "wait for MODIFY LUN timed out");
639 			goto out;
640 		}
641 		rstat = isp->isp_osinfo.rstatus;
642 		if (rstat != LUN_OK) {
643 			xpt_print_path(ccb->ccb_h.path);
644 			isp_prt(isp, ISP_LOGERR,
645 			    "MODIFY LUN returned 0x%x", rstat);
646 			goto out;
647 		}
648 		rstat = LUN_ERR;
649 		seq = isp->isp_osinfo.rollinfo++;
650 
651 		if (isp_lun_cmd(isp, -RQSTYPE_ENABLE_LUN, bus, tgt, lun, seq)) {
652 			xpt_print_path(ccb->ccb_h.path);
653 			isp_prt(isp, ISP_LOGERR, "isp_lun_cmd failed");
654 			goto out;
655 		}
656 		if (isp_cv_wait_timed_rqe(isp, 30 * hz)) {
657 			xpt_print_path(ccb->ccb_h.path);
658 			isp_prt(isp, ISP_LOGERR,
659 			     "wait for ENABLE LUN timed out");
660 			goto out;
661 		}
662 		rstat = isp->isp_osinfo.rstatus;
663 		if (rstat != LUN_OK) {
664 			xpt_print_path(ccb->ccb_h.path);
665 			isp_prt(isp, ISP_LOGWARN,
666 			    "ENABLE LUN returned 0x%x", rstat);
667 			goto out;
668 		}
669 	}
670 out:
671 	isp_vsema_rqe(isp);
672 	ISP_UNLOCK(isp);
673 
674 	if (rstat != LUN_OK) {
675 		xpt_print_path(ccb->ccb_h.path);
676 		isp_prt(isp, ISP_LOGWARN,
677 		    "lun %sable failed", (cel->enable) ? "en" : "dis");
678 		ccb->ccb_h.status = CAM_REQ_CMP_ERR;
679 		rls_lun_statep(isp, tptr);
680 		if (cel->enable)
681 			destroy_lun_state(isp, tptr);
682 	} else {
683 		xpt_print_path(ccb->ccb_h.path);
684 		isp_prt(isp, ISP_LOGINFO, lfmt,
685 		    (cel->enable) ? "en" : "dis", bus);
686 		rls_lun_statep(isp, tptr);
687 		if (cel->enable == 0) {
688 			destroy_lun_state(isp, tptr);
689 		}
690 		ccb->ccb_h.status = CAM_REQ_CMP;
691 	}
692 }
693 
694 static cam_status
695 isp_abort_tgt_ccb(struct ispsoftc *isp, union ccb *ccb)
696 {
697 	tstate_t *tptr;
698 	struct ccb_hdr_slist *lp;
699 	struct ccb_hdr *curelm;
700 	int found;
701 	union ccb *accb = ccb->cab.abort_ccb;
702 
703 	if (accb->ccb_h.target_id != CAM_TARGET_WILDCARD) {
704 		if (IS_FC(isp) && (accb->ccb_h.target_id !=
705 		    ((fcparam *) isp->isp_param)->isp_loopid)) {
706 			return (CAM_PATH_INVALID);
707 		} else if (IS_SCSI(isp) && (accb->ccb_h.target_id !=
708 		    ((sdparam *) isp->isp_param)->isp_initiator_id)) {
709 			return (CAM_PATH_INVALID);
710 		}
711 	}
712 	tptr = get_lun_statep(isp, XS_CHANNEL(ccb), accb->ccb_h.target_lun);
713 	if (tptr == NULL) {
714 		return (CAM_PATH_INVALID);
715 	}
716 	if (accb->ccb_h.func_code == XPT_ACCEPT_TARGET_IO) {
717 		lp = &tptr->atios;
718 	} else if (accb->ccb_h.func_code == XPT_IMMED_NOTIFY) {
719 		lp = &tptr->inots;
720 	} else {
721 		rls_lun_statep(isp, tptr);
722 		return (CAM_UA_ABORT);
723 	}
724 	curelm = SLIST_FIRST(lp);
725 	found = 0;
726 	if (curelm == &accb->ccb_h) {
727 		found = 1;
728 		SLIST_REMOVE_HEAD(lp, sim_links.sle);
729 	} else {
730 		while(curelm != NULL) {
731 			struct ccb_hdr *nextelm;
732 
733 			nextelm = SLIST_NEXT(curelm, sim_links.sle);
734 			if (nextelm == &accb->ccb_h) {
735 				found = 1;
736 				SLIST_NEXT(curelm, sim_links.sle) =
737 				    SLIST_NEXT(nextelm, sim_links.sle);
738 				break;
739 			}
740 			curelm = nextelm;
741 		}
742 	}
743 	rls_lun_statep(isp, tptr);
744 	if (found) {
745 		accb->ccb_h.status = CAM_REQ_ABORTED;
746 		return (CAM_REQ_CMP);
747 	}
748 	return(CAM_PATH_INVALID);
749 }
750 
751 static cam_status
752 isp_target_start_ctio(struct ispsoftc *isp, union ccb *ccb)
753 {
754 	void *qe;
755 	struct ccb_scsiio *cso = &ccb->csio;
756 	u_int16_t *hp, save_handle;
757 	u_int16_t iptr, optr;
758 
759 
760 	if (isp_getrqentry(isp, &iptr, &optr, &qe)) {
761 		xpt_print_path(ccb->ccb_h.path);
762 		printf("Request Queue Overflow in isp_target_start_ctio\n");
763 		return (CAM_RESRC_UNAVAIL);
764 	}
765 	bzero(qe, QENTRY_LEN);
766 
767 	/*
768 	 * We're either moving data or completing a command here.
769 	 */
770 
771 	if (IS_FC(isp)) {
772 		struct ccb_accept_tio *atiop;
773 		ct2_entry_t *cto = qe;
774 
775 		cto->ct_header.rqs_entry_type = RQSTYPE_CTIO2;
776 		cto->ct_header.rqs_entry_count = 1;
777 		cto->ct_iid = cso->init_id;
778 		if (isp->isp_maxluns <= 16) {
779 			cto->ct_lun = ccb->ccb_h.target_lun;
780 		}
781 		/*
782 		 * Start with a residual based on what the original datalength
783 		 * was supposed to be. Basically, we ignore what CAM has set
784 		 * for residuals. The data transfer routines will knock off
785 		 * the residual for each byte actually moved- and also will
786 		 * be responsible for setting the underrun flag.
787 		 */
788 		/* HACK! HACK! */
789 		if ((atiop = ccb->ccb_h.periph_priv.entries[1].ptr) != NULL) {
790 			cto->ct_resid = atiop->ccb_h.spriv_field0;
791 		}
792 
793 		cto->ct_rxid = cso->tag_id;
794 		if (cso->dxfer_len == 0) {
795 			cto->ct_flags |= CT2_FLAG_MODE1 | CT2_NO_DATA;
796 			if (ccb->ccb_h.flags & CAM_SEND_STATUS) {
797 				cto->ct_flags |= CT2_SENDSTATUS;
798 				cto->rsp.m1.ct_scsi_status = cso->scsi_status;
799 			}
800 			if ((ccb->ccb_h.flags & CAM_SEND_SENSE) != 0) {
801 				int m = min(cso->sense_len, MAXRESPLEN);
802 				bcopy(&cso->sense_data, cto->rsp.m1.ct_resp, m);
803 				cto->rsp.m1.ct_senselen = m;
804 				cto->rsp.m1.ct_scsi_status |= CT2_SNSLEN_VALID;
805 			}
806 		} else {
807 			cto->ct_flags |= CT2_FLAG_MODE0;
808 			if ((cso->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) {
809 				cto->ct_flags |= CT2_DATA_IN;
810 			} else {
811 				cto->ct_flags |= CT2_DATA_OUT;
812 			}
813 			if ((ccb->ccb_h.flags & CAM_SEND_STATUS) != 0) {
814 				cto->ct_flags |= CT2_SENDSTATUS;
815 				cto->rsp.m0.ct_scsi_status = cso->scsi_status;
816 			}
817 			/*
818 			 * If we're sending data and status back together,
819 			 * we can't also send back sense data as well.
820 			 */
821 			ccb->ccb_h.flags &= ~CAM_SEND_SENSE;
822 		}
823 		if (cto->ct_flags & CT2_SENDSTATUS) {
824 			isp_prt(isp, ISP_LOGTDEBUG1,
825 			    "CTIO2[%x] SCSI STATUS 0x%x datalength %u",
826 			    cto->ct_rxid, cso->scsi_status, cto->ct_resid);
827 		}
828 		if  (cto->ct_flags & CT2_SENDSTATUS)
829 			cto->ct_flags |= CT2_CCINCR;
830 		cto->ct_timeout = 10;
831 		hp = &cto->ct_syshandle;
832 	} else {
833 		ct_entry_t *cto = qe;
834 
835 		cto->ct_header.rqs_entry_type = RQSTYPE_CTIO;
836 		cto->ct_header.rqs_entry_count = 1;
837 		cto->ct_iid = cso->init_id;
838 		cto->ct_iid |= XS_CHANNEL(ccb) << 7;
839 		cto->ct_tgt = ccb->ccb_h.target_id;
840 		cto->ct_lun = ccb->ccb_h.target_lun;
841 		cto->ct_fwhandle = AT_GET_HANDLE(cso->tag_id);
842 		if (AT_HAS_TAG(cso->tag_id)) {
843 			cto->ct_tag_val = (u_int8_t) AT_GET_TAG(cso->tag_id);
844 			cto->ct_flags |= CT_TQAE;
845 		}
846 		if (ccb->ccb_h.flags & CAM_DIS_DISCONNECT) {
847 			cto->ct_flags |= CT_NODISC;
848 		}
849 		if (cso->dxfer_len == 0) {
850 			cto->ct_flags |= CT_NO_DATA;
851 		} else if ((cso->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) {
852 			cto->ct_flags |= CT_DATA_IN;
853 		} else {
854 			cto->ct_flags |= CT_DATA_OUT;
855 		}
856 		if (ccb->ccb_h.flags & CAM_SEND_STATUS) {
857 			cto->ct_flags |= CT_SENDSTATUS;
858 			cto->ct_scsi_status = cso->scsi_status;
859 			cto->ct_resid = cso->resid;
860 		}
861 		if (cto->ct_flags & CT_SENDSTATUS) {
862 			isp_prt(isp, ISP_LOGTDEBUG1,
863 			    "CTIO[%x] SCSI STATUS 0x%x resid %d tag_id %x",
864 			    cto->ct_fwhandle, cso->scsi_status, cso->resid,
865 			    cso->tag_id);
866 		}
867 		cto->ct_timeout = 10;
868 		hp = &cto->ct_syshandle;
869 		ccb->ccb_h.flags &= ~CAM_SEND_SENSE;
870 		if  (cto->ct_flags & CT_SENDSTATUS)
871 			cto->ct_flags |= CT_CCINCR;
872 	}
873 
874 	if (isp_save_xs(isp, (XS_T *)ccb, hp)) {
875 		xpt_print_path(ccb->ccb_h.path);
876 		printf("No XFLIST pointers for isp_target_start_ctio\n");
877 		return (CAM_RESRC_UNAVAIL);
878 	}
879 
880 
881 	/*
882 	 * Call the dma setup routines for this entry (and any subsequent
883 	 * CTIOs) if there's data to move, and then tell the f/w it's got
884 	 * new things to play with. As with isp_start's usage of DMA setup,
885 	 * any swizzling is done in the machine dependent layer. Because
886 	 * of this, we put the request onto the queue area first in native
887 	 * format.
888 	 */
889 
890 	save_handle = *hp;
891 
892 	switch (ISP_DMASETUP(isp, cso, qe, &iptr, optr)) {
893 	case CMD_QUEUED:
894 		ISP_ADD_REQUEST(isp, iptr);
895 		return (CAM_REQ_INPROG);
896 
897 	case CMD_EAGAIN:
898 		ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
899 		isp_destroy_handle(isp, save_handle);
900 		return (CAM_RESRC_UNAVAIL);
901 
902 	default:
903 		isp_destroy_handle(isp, save_handle);
904 		return (XS_ERR(ccb));
905 	}
906 }
907 
908 static void
909 isp_refire_putback_atio(void *arg)
910 {
911 	int s = splcam();
912 	isp_target_putback_atio(arg);
913 	splx(s);
914 }
915 
916 static void
917 isp_target_putback_atio(union ccb *ccb)
918 {
919 	struct ispsoftc *isp;
920 	struct ccb_scsiio *cso;
921 	u_int16_t iptr, optr;
922 	void *qe;
923 
924 	isp = XS_ISP(ccb);
925 
926 	if (isp_getrqentry(isp, &iptr, &optr, &qe)) {
927 		(void) timeout(isp_refire_putback_atio, ccb, 10);
928 		isp_prt(isp, ISP_LOGWARN,
929 		    "isp_target_putback_atio: Request Queue Overflow");
930 		return;
931 	}
932 	bzero(qe, QENTRY_LEN);
933 	cso = &ccb->csio;
934 	if (IS_FC(isp)) {
935 		at2_entry_t *at = qe;
936 		at->at_header.rqs_entry_type = RQSTYPE_ATIO2;
937 		at->at_header.rqs_entry_count = 1;
938 		if (isp->isp_maxluns > 16) {
939 			at->at_scclun = (uint16_t) ccb->ccb_h.target_lun;
940 		} else {
941 			at->at_lun = (uint8_t) ccb->ccb_h.target_lun;
942 		}
943 		at->at_status = CT_OK;
944 		at->at_rxid = cso->tag_id;
945 		ISP_SWIZ_ATIO2(isp, qe, qe);
946 	} else {
947 		at_entry_t *at = qe;
948 		at->at_header.rqs_entry_type = RQSTYPE_ATIO;
949 		at->at_header.rqs_entry_count = 1;
950 		at->at_iid = cso->init_id;
951 		at->at_iid |= XS_CHANNEL(ccb) << 7;
952 		at->at_tgt = cso->ccb_h.target_id;
953 		at->at_lun = cso->ccb_h.target_lun;
954 		at->at_status = CT_OK;
955 		at->at_tag_val = AT_GET_TAG(cso->tag_id);
956 		at->at_handle = AT_GET_HANDLE(cso->tag_id);
957 		ISP_SWIZ_ATIO(isp, qe, qe);
958 	}
959 	ISP_TDQE(isp, "isp_target_putback_atio", (int) optr, qe);
960 	ISP_ADD_REQUEST(isp, iptr);
961 	isp_complete_ctio(ccb);
962 }
963 
964 static void
965 isp_complete_ctio(union ccb *ccb)
966 {
967 	struct ispsoftc *isp = XS_ISP(ccb);
968 	if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_INPROG) {
969 		ccb->ccb_h.status |= CAM_REQ_CMP;
970 	}
971 	ccb->ccb_h.status &= ~CAM_SIM_QUEUED;
972 	if (isp->isp_osinfo.simqfrozen & SIMQFRZ_RESOURCE) {
973 		isp->isp_osinfo.simqfrozen &= ~SIMQFRZ_RESOURCE;
974 		if (isp->isp_osinfo.simqfrozen == 0) {
975 			if ((ccb->ccb_h.status & CAM_DEV_QFRZN) == 0) {
976 				isp_prt(isp, ISP_LOGDEBUG2, "ctio->relsimq");
977 				ccb->ccb_h.status |= CAM_RELEASE_SIMQ;
978 			} else {
979 				isp_prt(isp, ISP_LOGWARN, "ctio->devqfrozen");
980 			}
981 		} else {
982 			isp_prt(isp, ISP_LOGWARN,
983 			    "ctio->simqfrozen(%x)", isp->isp_osinfo.simqfrozen);
984 		}
985 	}
986 	xpt_done(ccb);
987 }
988 
989 /*
990  * Handle ATIO stuff that the generic code can't.
991  * This means handling CDBs.
992  */
993 
994 static int
995 isp_handle_platform_atio(struct ispsoftc *isp, at_entry_t *aep)
996 {
997 	tstate_t *tptr;
998 	int status, bus;
999 	struct ccb_accept_tio *atiop;
1000 
1001 	/*
1002 	 * The firmware status (except for the QLTM_SVALID bit)
1003 	 * indicates why this ATIO was sent to us.
1004 	 *
1005 	 * If QLTM_SVALID is set, the firware has recommended Sense Data.
1006 	 *
1007 	 * If the DISCONNECTS DISABLED bit is set in the flags field,
1008 	 * we're still connected on the SCSI bus - i.e. the initiator
1009 	 * did not set DiscPriv in the identify message. We don't care
1010 	 * about this so it's ignored.
1011 	 */
1012 	status = aep->at_status;
1013 	if ((status & ~QLTM_SVALID) == AT_PHASE_ERROR) {
1014 		/*
1015 		 * Bus Phase Sequence error. We should have sense data
1016 		 * suggested by the f/w. I'm not sure quite yet what
1017 		 * to do about this for CAM.
1018 		 */
1019 		isp_prt(isp, ISP_LOGWARN, "PHASE ERROR");
1020 		isp_endcmd(isp, aep, SCSI_STATUS_BUSY, 0);
1021 		return (0);
1022 	}
1023 	if ((status & ~QLTM_SVALID) != AT_CDB) {
1024 		isp_prt(isp,
1025 		    ISP_LOGWARN, "bogus atio (0x%x) leaked to platform",
1026 		    status);
1027 		isp_endcmd(isp, aep, SCSI_STATUS_BUSY, 0);
1028 		return (0);
1029 	}
1030 
1031 	bus = aep->at_iid >> 7;
1032 	aep->at_iid &= 0x7f;
1033 	tptr = get_lun_statep(isp, bus, aep->at_lun);
1034 	if (tptr == NULL) {
1035 		tptr = get_lun_statep(isp, bus, CAM_LUN_WILDCARD);
1036 	}
1037 
1038 	if (tptr == NULL) {
1039 		/*
1040 		 * Because we can't autofeed sense data back with
1041 		 * a command for parallel SCSI, we can't give back
1042 		 * a CHECK CONDITION. We'll give back a BUSY status
1043 		 * instead. This works out okay because the only
1044 		 * time we should, in fact, get this, is in the
1045 		 * case that somebody configured us without the
1046 		 * blackhole driver, so they get what they deserve.
1047 		 */
1048 		isp_endcmd(isp, aep, SCSI_STATUS_BUSY, 0);
1049 		return (0);
1050 	}
1051 
1052 	atiop = (struct ccb_accept_tio *) SLIST_FIRST(&tptr->atios);
1053 	if (atiop == NULL) {
1054 		/*
1055 		 * Because we can't autofeed sense data back with
1056 		 * a command for parallel SCSI, we can't give back
1057 		 * a CHECK CONDITION. We'll give back a QUEUE FULL status
1058 		 * instead. This works out okay because the only time we
1059 		 * should, in fact, get this, is in the case that we've
1060 		 * run out of ATIOS.
1061 		 */
1062 		xpt_print_path(tptr->owner);
1063 		isp_prt(isp, ISP_LOGWARN,
1064 		    "no ATIOS for lun %d from initiator %d on channel %d",
1065 		    aep->at_lun, aep->at_iid, bus);
1066 		rls_lun_statep(isp, tptr);
1067 		if (aep->at_flags & AT_TQAE)
1068 			isp_endcmd(isp, aep, SCSI_STATUS_QUEUE_FULL, 0);
1069 		else
1070 			isp_endcmd(isp, aep, SCSI_STATUS_BUSY, 0);
1071 		return (0);
1072 	}
1073 	SLIST_REMOVE_HEAD(&tptr->atios, sim_links.sle);
1074 	if (tptr == &isp->isp_osinfo.tsdflt[bus]) {
1075 		atiop->ccb_h.target_id = aep->at_tgt;
1076 		atiop->ccb_h.target_lun = aep->at_lun;
1077 	}
1078 	if (aep->at_flags & AT_NODISC) {
1079 		atiop->ccb_h.flags = CAM_DIS_DISCONNECT;
1080 	} else {
1081 		atiop->ccb_h.flags = 0;
1082 	}
1083 
1084 	if (status & QLTM_SVALID) {
1085 		size_t amt = imin(QLTM_SENSELEN, sizeof (atiop->sense_data));
1086 		atiop->sense_len = amt;
1087 		MEMCPY(&atiop->sense_data, aep->at_sense, amt);
1088 	} else {
1089 		atiop->sense_len = 0;
1090 	}
1091 
1092 	atiop->init_id = aep->at_iid & 0x7f;
1093 	atiop->cdb_len = aep->at_cdblen;
1094 	MEMCPY(atiop->cdb_io.cdb_bytes, aep->at_cdb, aep->at_cdblen);
1095 	atiop->ccb_h.status = CAM_CDB_RECVD;
1096 	/*
1097 	 * Construct a tag 'id' based upon tag value (which may be 0..255)
1098 	 * and the handle (which we have to preserve).
1099 	 */
1100 	AT_MAKE_TAGID(atiop->tag_id, aep);
1101 	if (aep->at_flags & AT_TQAE) {
1102 		atiop->tag_action = aep->at_tag_type;
1103 		atiop->ccb_h.status |= CAM_TAG_ACTION_VALID;
1104 	}
1105 	xpt_done((union ccb*)atiop);
1106 	isp_prt(isp, ISP_LOGTDEBUG1,
1107 	    "ATIO[%x] CDB=0x%x iid%d->lun%d tag 0x%x ttype 0x%x %s",
1108 	    aep->at_handle, aep->at_cdb[0] & 0xff, aep->at_iid, aep->at_lun,
1109 	    aep->at_tag_val & 0xff, aep->at_tag_type,
1110 	    (aep->at_flags & AT_NODISC)? "nondisc" : "disconnecting");
1111 	rls_lun_statep(isp, tptr);
1112 	return (0);
1113 }
1114 
1115 static int
1116 isp_handle_platform_atio2(struct ispsoftc *isp, at2_entry_t *aep)
1117 {
1118 	lun_id_t lun;
1119 	tstate_t *tptr;
1120 	struct ccb_accept_tio *atiop;
1121 
1122 	/*
1123 	 * The firmware status (except for the QLTM_SVALID bit)
1124 	 * indicates why this ATIO was sent to us.
1125 	 *
1126 	 * If QLTM_SVALID is set, the firware has recommended Sense Data.
1127 	 */
1128 	if ((aep->at_status & ~QLTM_SVALID) != AT_CDB) {
1129 		isp_prt(isp, ISP_LOGWARN,
1130 		    "bogus atio (0x%x) leaked to platform", aep->at_status);
1131 		isp_endcmd(isp, aep, SCSI_STATUS_BUSY, 0);
1132 		return (0);
1133 	}
1134 
1135 	if (isp->isp_maxluns > 16) {
1136 		lun = aep->at_scclun;
1137 	} else {
1138 		lun = aep->at_lun;
1139 	}
1140 	tptr = get_lun_statep(isp, 0, lun);
1141 	if (tptr == NULL) {
1142 		tptr = get_lun_statep(isp, 0, CAM_LUN_WILDCARD);
1143 	}
1144 
1145 	if (tptr == NULL) {
1146 		/*
1147 		 * What we'd like to know is whether or not we have a listener
1148 		 * upstream that really hasn't configured yet. If we do, then
1149 		 * we can give a more sensible reply here. If not, then we can
1150 		 * reject this out of hand.
1151 		 *
1152 		 * Choices for what to send were
1153 		 *
1154                  *	Not Ready, Unit Not Self-Configured Yet
1155 		 *	(0x2,0x3e,0x00)
1156 		 *
1157 		 * for the former and
1158 		 *
1159 		 *	Illegal Request, Logical Unit Not Supported
1160 		 *	(0x5,0x25,0x00)
1161 		 *
1162 		 * for the latter.
1163 		 *
1164 		 * We used to decide whether there was at least one listener
1165 		 * based upon whether the black hole driver was configured.
1166 		 * However, recent config(8) changes have made this hard to do
1167 		 * at this time.
1168 		 *
1169 		 */
1170 		u_int32_t ccode = SCSI_STATUS_BUSY;
1171 
1172 		/*
1173 		 * Because we can't autofeed sense data back with
1174 		 * a command for parallel SCSI, we can't give back
1175 		 * a CHECK CONDITION. We'll give back a BUSY status
1176 		 * instead. This works out okay because the only
1177 		 * time we should, in fact, get this, is in the
1178 		 * case that somebody configured us without the
1179 		 * blackhole driver, so they get what they deserve.
1180 		 */
1181 		isp_endcmd(isp, aep, ccode, 0);
1182 		return (0);
1183 	}
1184 
1185 	atiop = (struct ccb_accept_tio *) SLIST_FIRST(&tptr->atios);
1186 	if (atiop == NULL) {
1187 		/*
1188 		 * Because we can't autofeed sense data back with
1189 		 * a command for parallel SCSI, we can't give back
1190 		 * a CHECK CONDITION. We'll give back a QUEUE FULL status
1191 		 * instead. This works out okay because the only time we
1192 		 * should, in fact, get this, is in the case that we've
1193 		 * run out of ATIOS.
1194 		 */
1195 		xpt_print_path(tptr->owner);
1196 		isp_prt(isp, ISP_LOGWARN,
1197 		    "no ATIOS for lun %d from initiator %d", lun, aep->at_iid);
1198 		rls_lun_statep(isp, tptr);
1199 		if (aep->at_flags & AT_TQAE)
1200 			isp_endcmd(isp, aep, SCSI_STATUS_QUEUE_FULL, 0);
1201 		else
1202 			isp_endcmd(isp, aep, SCSI_STATUS_BUSY, 0);
1203 		return (0);
1204 	}
1205 	SLIST_REMOVE_HEAD(&tptr->atios, sim_links.sle);
1206 
1207 	if (tptr == &isp->isp_osinfo.tsdflt[0]) {
1208 		atiop->ccb_h.target_id =
1209 			((fcparam *)isp->isp_param)->isp_loopid;
1210 		atiop->ccb_h.target_lun = lun;
1211 	}
1212 	/*
1213 	 * We don't get 'suggested' sense data as we do with SCSI cards.
1214 	 */
1215 	atiop->sense_len = 0;
1216 
1217 	atiop->init_id = aep->at_iid;
1218 	atiop->cdb_len = ATIO2_CDBLEN;
1219 	MEMCPY(atiop->cdb_io.cdb_bytes, aep->at_cdb, ATIO2_CDBLEN);
1220 	atiop->ccb_h.status = CAM_CDB_RECVD;
1221 	atiop->tag_id = aep->at_rxid;
1222 	switch (aep->at_taskflags & ATIO2_TC_ATTR_MASK) {
1223 	case ATIO2_TC_ATTR_SIMPLEQ:
1224 		atiop->tag_action = MSG_SIMPLE_Q_TAG;
1225 		break;
1226         case ATIO2_TC_ATTR_HEADOFQ:
1227 		atiop->tag_action = MSG_HEAD_OF_Q_TAG;
1228 		break;
1229         case ATIO2_TC_ATTR_ORDERED:
1230 		atiop->tag_action = MSG_ORDERED_Q_TAG;
1231 		break;
1232         case ATIO2_TC_ATTR_ACAQ:		/* ?? */
1233 	case ATIO2_TC_ATTR_UNTAGGED:
1234 	default:
1235 		atiop->tag_action = 0;
1236 		break;
1237 	}
1238 	if (atiop->tag_action != 0) {
1239 		atiop->ccb_h.status |= CAM_TAG_ACTION_VALID;
1240 	}
1241 
1242 	/*
1243 	 * Preserve overall command datalength in private field.
1244 	 */
1245 	atiop->ccb_h.spriv_field0 = aep->at_datalen;
1246 
1247 	xpt_done((union ccb*)atiop);
1248 	isp_prt(isp, ISP_LOGTDEBUG1,
1249 	    "ATIO2[%x] CDB=0x%x iid%d->lun%d tattr 0x%x datalen %u",
1250 	    aep->at_rxid, aep->at_cdb[0] & 0xff, aep->at_iid,
1251 	    lun, aep->at_taskflags, aep->at_datalen);
1252 	rls_lun_statep(isp, tptr);
1253 	return (0);
1254 }
1255 
1256 static int
1257 isp_handle_platform_ctio(struct ispsoftc *isp, void *arg)
1258 {
1259 	union ccb *ccb;
1260 	int sentstatus, ok, notify_cam, resid = 0;
1261 
1262 	/*
1263 	 * CTIO and CTIO2 are close enough....
1264 	 */
1265 
1266 	ccb = (union ccb *) isp_find_xs(isp, ((ct_entry_t *)arg)->ct_syshandle);
1267 	KASSERT((ccb != NULL), ("null ccb in isp_handle_platform_ctio"));
1268 	isp_destroy_handle(isp, ((ct_entry_t *)arg)->ct_syshandle);
1269 
1270 	if (IS_FC(isp)) {
1271 		ct2_entry_t *ct = arg;
1272 		sentstatus = ct->ct_flags & CT2_SENDSTATUS;
1273 		ok = (ct->ct_status & ~QLTM_SVALID) == CT_OK;
1274 		if (ok && sentstatus && (ccb->ccb_h.flags & CAM_SEND_SENSE)) {
1275 			ccb->ccb_h.status |= CAM_SENT_SENSE;
1276 		}
1277 		isp_prt(isp, ISP_LOGTDEBUG1,
1278 		    "CTIO2[%x] sts 0x%x flg 0x%x sns %d %s",
1279 		    ct->ct_rxid, ct->ct_status, ct->ct_flags,
1280 		    (ccb->ccb_h.status & CAM_SENT_SENSE) != 0,
1281 		    sentstatus? "FIN" : "MID");
1282 		notify_cam = ct->ct_header.rqs_seqno & 0x1;
1283 		if (ct->ct_flags & CT2_DATAMASK)
1284 			resid = ct->ct_resid;
1285 	} else {
1286 		ct_entry_t *ct = arg;
1287 		sentstatus = ct->ct_flags & CT_SENDSTATUS;
1288 		ok = (ct->ct_status  & ~QLTM_SVALID) == CT_OK;
1289 		isp_prt(isp, ISP_LOGTDEBUG1,
1290 		    "CTIO[%x] tag %x iid %x tgt %d lun %d sts 0x%x flg %x %s",
1291 		    ct->ct_fwhandle, ct->ct_tag_val, ct->ct_iid, ct->ct_tgt,
1292 		    ct->ct_lun, ct->ct_status, ct->ct_flags,
1293 		    sentstatus? "FIN" : "MID");
1294 
1295 		/*
1296 		 * We *ought* to be able to get back to the original ATIO
1297 		 * here, but for some reason this gets lost. It's just as
1298 		 * well because it's squirrelled away as part of periph
1299 		 * private data.
1300 		 *
1301 		 * We can live without it as long as we continue to use
1302 		 * the auto-replenish feature for CTIOs.
1303 		 */
1304 		notify_cam = ct->ct_header.rqs_seqno & 0x1;
1305 		if (ct->ct_status  & QLTM_SVALID) {
1306 			char *sp = (char *)ct;
1307 			sp += CTIO_SENSE_OFFSET;
1308 			ccb->csio.sense_len =
1309 			    min(sizeof (ccb->csio.sense_data), QLTM_SENSELEN);
1310 			MEMCPY(&ccb->csio.sense_data, sp, ccb->csio.sense_len);
1311 			ccb->ccb_h.status |= CAM_AUTOSNS_VALID;
1312 		}
1313 		if (ct->ct_flags & CT_DATAMASK)
1314 			resid = ct->ct_resid;
1315 	}
1316 	ccb->csio.resid += resid;
1317 
1318 	/*
1319 	 * We're here either because intermediate data transfers are done
1320 	 * and/or the final status CTIO (which may have joined with a
1321 	 * Data Transfer) is done.
1322 	 *
1323 	 * In any case, for this platform, the upper layers figure out
1324 	 * what to do next, so all we do here is collect status and
1325 	 * pass information along. Any DMA handles have already been
1326 	 * freed.
1327 	 */
1328 	if (notify_cam == 0) {
1329 		isp_prt(isp, ISP_LOGTDEBUG0, "  INTER CTIO done");
1330 		return (0);
1331 	}
1332 
1333 	isp_prt(isp, ISP_LOGTDEBUG0, "%s CTIO done (resid %d)",
1334 	    (sentstatus)? "  FINAL " : "MIDTERM ", ccb->csio.resid);
1335 
1336 	if (!ok) {
1337 		isp_target_putback_atio(ccb);
1338 	} else {
1339 		isp_complete_ctio(ccb);
1340 
1341 	}
1342 	return (0);
1343 }
1344 #endif
1345 
1346 static void
1347 isp_cam_async(void *cbarg, u_int32_t code, struct cam_path *path, void *arg)
1348 {
1349 	struct cam_sim *sim;
1350 	struct ispsoftc *isp;
1351 
1352 	sim = (struct cam_sim *)cbarg;
1353 	isp = (struct ispsoftc *) cam_sim_softc(sim);
1354 	switch (code) {
1355 	case AC_LOST_DEVICE:
1356 		if (IS_SCSI(isp)) {
1357 			u_int16_t oflags, nflags;
1358 			sdparam *sdp = isp->isp_param;
1359 			int tgt;
1360 
1361 			tgt = xpt_path_target_id(path);
1362 			ISP_LOCK(isp);
1363 			sdp += cam_sim_bus(sim);
1364 #ifndef	ISP_TARGET_MODE
1365 			if (tgt == sdp->isp_initiator_id) {
1366 				nflags = DPARM_DEFAULT;
1367 			} else {
1368 				nflags = DPARM_SAFE_DFLT;
1369 				if (isp->isp_loaded_fw) {
1370 					nflags |= DPARM_NARROW | DPARM_ASYNC;
1371 				}
1372 			}
1373 #else
1374 			nflags = DPARM_DEFAULT;
1375 #endif
1376 			oflags = sdp->isp_devparam[tgt].dev_flags;
1377 			sdp->isp_devparam[tgt].dev_flags = nflags;
1378 			sdp->isp_devparam[tgt].dev_update = 1;
1379 			isp->isp_update |= (1 << cam_sim_bus(sim));
1380 			(void) isp_control(isp, ISPCTL_UPDATE_PARAMS, NULL);
1381 			sdp->isp_devparam[tgt].dev_flags = oflags;
1382 			ISP_UNLOCK(isp);
1383 		}
1384 		break;
1385 	default:
1386 		isp_prt(isp, ISP_LOGWARN, "isp_cam_async: Code 0x%x", code);
1387 		break;
1388 	}
1389 }
1390 
1391 static void
1392 isp_poll(struct cam_sim *sim)
1393 {
1394 	struct ispsoftc *isp = cam_sim_softc(sim);
1395 	ISP_LOCK(isp);
1396 	(void) isp_intr(isp);
1397 	ISP_UNLOCK(isp);
1398 }
1399 
1400 static void
1401 isp_relsim(void *arg)
1402 {
1403 	struct ispsoftc *isp = arg;
1404 	ISP_LOCK(isp);
1405 	if (isp->isp_osinfo.simqfrozen & SIMQFRZ_TIMED) {
1406 		int wasfrozen = isp->isp_osinfo.simqfrozen & SIMQFRZ_TIMED;
1407 		isp->isp_osinfo.simqfrozen &= ~SIMQFRZ_TIMED;
1408 		if (wasfrozen && isp->isp_osinfo.simqfrozen == 0) {
1409 			xpt_release_simq(isp->isp_sim, 1);
1410 			isp_prt(isp, ISP_LOGDEBUG2, "timed relsimq");
1411 		}
1412 	}
1413 	ISP_UNLOCK(isp);
1414 }
1415 
1416 static void
1417 isp_watchdog(void *arg)
1418 {
1419 	XS_T *xs = arg;
1420 	struct ispsoftc *isp = XS_ISP(xs);
1421 	u_int32_t handle;
1422 
1423 	/*
1424 	 * We've decided this command is dead. Make sure we're not trying
1425 	 * to kill a command that's already dead by getting it's handle and
1426 	 * and seeing whether it's still alive.
1427 	 */
1428 	ISP_LOCK(isp);
1429 	handle = isp_find_handle(isp, xs);
1430 	if (handle) {
1431 		u_int16_t r;
1432 
1433 		if (XS_CMD_DONE_P(xs)) {
1434 			isp_prt(isp, ISP_LOGDEBUG1,
1435 			    "watchdog found done cmd (handle 0x%x)", handle);
1436 			ISP_UNLOCK(isp);
1437 			return;
1438 		}
1439 
1440 		if (XS_CMD_WDOG_P(xs)) {
1441 			isp_prt(isp, ISP_LOGDEBUG2,
1442 			    "recursive watchdog (handle 0x%x)", handle);
1443 			ISP_UNLOCK(isp);
1444 			return;
1445 		}
1446 
1447 		XS_CMD_S_WDOG(xs);
1448 
1449 		r = ISP_READ(isp, BIU_ISR);
1450 
1451 		if (INT_PENDING(isp, r) && isp_intr(isp) && XS_CMD_DONE_P(xs)) {
1452 			isp_prt(isp, ISP_LOGDEBUG2,
1453 			    "watchdog cleanup (%x, %x)", handle, r);
1454 			xpt_done((union ccb *) xs);
1455 		} else if (XS_CMD_GRACE_P(xs)) {
1456 			/*
1457 			 * Make sure the command is *really* dead before we
1458 			 * release the handle (and DMA resources) for reuse.
1459 			 */
1460 			(void) isp_control(isp, ISPCTL_ABORT_CMD, arg);
1461 
1462 			/*
1463 			 * After this point, the comamnd is really dead.
1464 			 */
1465 			if (XS_XFRLEN(xs)) {
1466 				ISP_DMAFREE(isp, xs, handle);
1467                 	}
1468 			isp_destroy_handle(isp, handle);
1469 			xpt_print_path(xs->ccb_h.path);
1470 			isp_prt(isp, ISP_LOGWARN,
1471 			    "watchdog timeout (%x, %x)", handle, r);
1472 			XS_SETERR(xs, CAM_CMD_TIMEOUT);
1473 			XS_CMD_C_WDOG(xs);
1474 			isp_done(xs);
1475 		} else {
1476 			u_int16_t iptr, optr;
1477 			ispreq_t *mp;
1478 
1479 			XS_CMD_C_WDOG(xs);
1480 			xs->ccb_h.timeout_ch = timeout(isp_watchdog, xs, hz);
1481 			if (isp_getrqentry(isp, &iptr, &optr, (void **) &mp)) {
1482 				ISP_UNLOCK(isp);
1483 				return;
1484 			}
1485 			XS_CMD_S_GRACE(xs);
1486 			MEMZERO((void *) mp, sizeof (*mp));
1487 			mp->req_header.rqs_entry_count = 1;
1488 			mp->req_header.rqs_entry_type = RQSTYPE_MARKER;
1489 			mp->req_modifier = SYNC_ALL;
1490 			mp->req_target = XS_CHANNEL(xs) << 7;
1491 			ISP_SWIZZLE_REQUEST(isp, mp);
1492 			ISP_ADD_REQUEST(isp, iptr);
1493 		}
1494 	} else {
1495 		isp_prt(isp, ISP_LOGDEBUG2, "watchdog with no command");
1496 	}
1497 	ISP_UNLOCK(isp);
1498 }
1499 
1500 static void
1501 isp_action(struct cam_sim *sim, union ccb *ccb)
1502 {
1503 	int bus, tgt, error;
1504 	struct ispsoftc *isp;
1505 	struct ccb_trans_settings *cts;
1506 
1507 	CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_TRACE, ("isp_action\n"));
1508 
1509 	isp = (struct ispsoftc *)cam_sim_softc(sim);
1510 	ccb->ccb_h.sim_priv.entries[0].field = 0;
1511 	ccb->ccb_h.sim_priv.entries[1].ptr = isp;
1512 	if (isp->isp_state != ISP_RUNSTATE &&
1513 	    ccb->ccb_h.func_code == XPT_SCSI_IO) {
1514 		ISP_LOCK(isp);
1515 		isp_init(isp);
1516 		if (isp->isp_state != ISP_INITSTATE) {
1517 			ISP_UNLOCK(isp);
1518 			/*
1519 			 * Lie. Say it was a selection timeout.
1520 			 */
1521 			ccb->ccb_h.status = CAM_SEL_TIMEOUT | CAM_DEV_QFRZN;
1522 			xpt_freeze_devq(ccb->ccb_h.path, 1);
1523 			xpt_done(ccb);
1524 			return;
1525 		}
1526 		isp->isp_state = ISP_RUNSTATE;
1527 		ISP_UNLOCK(isp);
1528 	}
1529 	isp_prt(isp, ISP_LOGDEBUG2, "isp_action code %x", ccb->ccb_h.func_code);
1530 
1531 	switch (ccb->ccb_h.func_code) {
1532 	case XPT_SCSI_IO:	/* Execute the requested I/O operation */
1533 		/*
1534 		 * Do a couple of preliminary checks...
1535 		 */
1536 		if ((ccb->ccb_h.flags & CAM_CDB_POINTER) != 0) {
1537 			if ((ccb->ccb_h.flags & CAM_CDB_PHYS) != 0) {
1538 				ccb->ccb_h.status = CAM_REQ_INVALID;
1539 				xpt_done(ccb);
1540 				break;
1541 			}
1542 		}
1543 #ifdef	DIAGNOSTIC
1544 		if (ccb->ccb_h.target_id > (ISP_MAX_TARGETS(isp) - 1)) {
1545 			ccb->ccb_h.status = CAM_PATH_INVALID;
1546 		} else if (ccb->ccb_h.target_lun > (ISP_MAX_LUNS(isp) - 1)) {
1547 			ccb->ccb_h.status = CAM_PATH_INVALID;
1548 		}
1549 		if (ccb->ccb_h.status == CAM_PATH_INVALID) {
1550 			isp_prt(isp, ISP_LOGERR,
1551 			    "invalid tgt/lun (%d.%d) in XPT_SCSI_IO",
1552 			    ccb->ccb_h.target_id, ccb->ccb_h.target_lun);
1553 			xpt_done(ccb);
1554 			break;
1555 		}
1556 #endif
1557 		((struct ccb_scsiio *) ccb)->scsi_status = SCSI_STATUS_OK;
1558 		ISP_LOCK(isp);
1559 		error = isp_start((XS_T *) ccb);
1560 		ISP_UNLOCK(isp);
1561 		switch (error) {
1562 		case CMD_QUEUED:
1563 			ccb->ccb_h.status |= CAM_SIM_QUEUED;
1564 			if (ccb->ccb_h.timeout != CAM_TIME_INFINITY) {
1565 				u_int64_t ticks = (u_int64_t) hz;
1566 				if (ccb->ccb_h.timeout == CAM_TIME_DEFAULT)
1567 					ticks = 60 * 1000 * ticks;
1568 				else
1569 					ticks = ccb->ccb_h.timeout * hz;
1570 				ticks = ((ticks + 999) / 1000) + hz + hz;
1571 				if (ticks >= 0x80000000) {
1572 					isp_prt(isp, ISP_LOGERR,
1573 					    "timeout overflow");
1574 					ticks = 0x80000000;
1575 				}
1576 				ccb->ccb_h.timeout_ch = timeout(isp_watchdog,
1577 				    (caddr_t)ccb, (int)ticks);
1578 			} else {
1579 				callout_handle_init(&ccb->ccb_h.timeout_ch);
1580 			}
1581 			break;
1582 		case CMD_RQLATER:
1583 			if (isp->isp_osinfo.simqfrozen == 0) {
1584 				isp_prt(isp, ISP_LOGDEBUG2,
1585 				    "RQLATER freeze simq");
1586 				isp->isp_osinfo.simqfrozen |= SIMQFRZ_TIMED;
1587 				timeout(isp_relsim, isp, 500);
1588 				xpt_freeze_simq(sim, 1);
1589 			}
1590 			XS_SETERR(ccb, CAM_REQUEUE_REQ);
1591 			xpt_done(ccb);
1592 			break;
1593 		case CMD_EAGAIN:
1594 			if (isp->isp_osinfo.simqfrozen == 0) {
1595 				xpt_freeze_simq(sim, 1);
1596 				isp_prt(isp, ISP_LOGDEBUG2,
1597 				    "EAGAIN freeze simq");
1598 			}
1599 			isp->isp_osinfo.simqfrozen |= SIMQFRZ_RESOURCE;
1600 			XS_SETERR(ccb, CAM_REQUEUE_REQ);
1601 			xpt_done(ccb);
1602 			break;
1603 		case CMD_COMPLETE:
1604 			ISP_LOCK(isp);
1605 			isp_done((struct ccb_scsiio *) ccb);
1606 			ISP_UNLOCK(isp);
1607 			break;
1608 		default:
1609 			isp_prt(isp, ISP_LOGERR,
1610 			    "What's this? 0x%x at %d in file %s",
1611 			    error, __LINE__, __FILE__);
1612 			XS_SETERR(ccb, CAM_REQ_CMP_ERR);
1613 			xpt_done(ccb);
1614 		}
1615 		break;
1616 
1617 #ifdef	ISP_TARGET_MODE
1618 	case XPT_EN_LUN:		/* Enable LUN as a target */
1619 		isp_en_lun(isp, ccb);
1620 		xpt_done(ccb);
1621 		break;
1622 
1623 	case XPT_NOTIFY_ACK:		/* recycle notify ack */
1624 	case XPT_IMMED_NOTIFY:		/* Add Immediate Notify Resource */
1625 	case XPT_ACCEPT_TARGET_IO:	/* Add Accept Target IO Resource */
1626 	{
1627 		tstate_t *tptr =
1628 		    get_lun_statep(isp, XS_CHANNEL(ccb), ccb->ccb_h.target_lun);
1629 		if (tptr == NULL) {
1630 			ccb->ccb_h.status = CAM_LUN_INVALID;
1631 			xpt_done(ccb);
1632 			break;
1633 		}
1634 		ccb->ccb_h.sim_priv.entries[0].field = 0;
1635 		ccb->ccb_h.sim_priv.entries[1].ptr = isp;
1636 		ISP_LOCK(isp);
1637 		if (ccb->ccb_h.func_code == XPT_ACCEPT_TARGET_IO) {
1638 			SLIST_INSERT_HEAD(&tptr->atios,
1639 			    &ccb->ccb_h, sim_links.sle);
1640 		} else {
1641 			SLIST_INSERT_HEAD(&tptr->inots, &ccb->ccb_h,
1642 			    sim_links.sle);
1643 		}
1644 		ISP_UNLOCK(isp);
1645 		rls_lun_statep(isp, tptr);
1646 		ccb->ccb_h.status = CAM_REQ_INPROG;
1647 		break;
1648 	}
1649 	case XPT_CONT_TARGET_IO:
1650 	{
1651 		ISP_LOCK(isp);
1652 		ccb->ccb_h.status = isp_target_start_ctio(isp, ccb);
1653 		if (ccb->ccb_h.status != CAM_REQ_INPROG) {
1654 			if (isp->isp_osinfo.simqfrozen == 0) {
1655 				xpt_freeze_simq(sim, 1);
1656 				xpt_print_path(ccb->ccb_h.path);
1657 				isp_prt(isp, ISP_LOGINFO,
1658 				    "XPT_CONT_TARGET_IO freeze simq");
1659 			}
1660 			isp->isp_osinfo.simqfrozen |= SIMQFRZ_RESOURCE;
1661 			XS_SETERR(ccb, CAM_REQUEUE_REQ);
1662 			xpt_done(ccb);
1663 		} else {
1664 			ccb->ccb_h.status |= CAM_SIM_QUEUED;
1665 		}
1666 		ISP_UNLOCK(isp);
1667 		break;
1668 	}
1669 #endif
1670 	case XPT_RESET_DEV:		/* BDR the specified SCSI device */
1671 
1672 		bus = cam_sim_bus(xpt_path_sim(ccb->ccb_h.path));
1673 		tgt = ccb->ccb_h.target_id;
1674 		tgt |= (bus << 16);
1675 
1676 		ISP_LOCK(isp);
1677 		error = isp_control(isp, ISPCTL_RESET_DEV, &tgt);
1678 		ISP_UNLOCK(isp);
1679 		if (error) {
1680 			ccb->ccb_h.status = CAM_REQ_CMP_ERR;
1681 		} else {
1682 			ccb->ccb_h.status = CAM_REQ_CMP;
1683 		}
1684 		xpt_done(ccb);
1685 		break;
1686 	case XPT_ABORT:			/* Abort the specified CCB */
1687 	{
1688 		union ccb *accb = ccb->cab.abort_ccb;
1689 		switch (accb->ccb_h.func_code) {
1690 #ifdef	ISP_TARGET_MODE
1691 		case XPT_ACCEPT_TARGET_IO:
1692 		case XPT_IMMED_NOTIFY:
1693         		ccb->ccb_h.status = isp_abort_tgt_ccb(isp, ccb);
1694 			break;
1695 		case XPT_CONT_TARGET_IO:
1696 			isp_prt(isp, ISP_LOGERR, "cannot abort CTIOs yet");
1697 			ccb->ccb_h.status = CAM_UA_ABORT;
1698 			break;
1699 #endif
1700 		case XPT_SCSI_IO:
1701 			ISP_LOCK(isp);
1702 			error = isp_control(isp, ISPCTL_ABORT_CMD, ccb);
1703 			ISP_UNLOCK(isp);
1704 			if (error) {
1705 				ccb->ccb_h.status = CAM_UA_ABORT;
1706 			} else {
1707 				ccb->ccb_h.status = CAM_REQ_CMP;
1708 			}
1709 			break;
1710 		default:
1711 			ccb->ccb_h.status = CAM_REQ_INVALID;
1712 			break;
1713 		}
1714 		xpt_done(ccb);
1715 		break;
1716 	}
1717 	case XPT_SET_TRAN_SETTINGS:	/* Nexus Settings */
1718 
1719 		cts = &ccb->cts;
1720 		tgt = cts->ccb_h.target_id;
1721 		ISP_LOCK(isp);
1722 		if (IS_SCSI(isp)) {
1723 			sdparam *sdp = isp->isp_param;
1724 			u_int16_t *dptr;
1725 
1726 			bus = cam_sim_bus(xpt_path_sim(cts->ccb_h.path));
1727 
1728 			sdp += bus;
1729 #if	0
1730 			if (cts->flags & CCB_TRANS_CURRENT_SETTINGS)
1731 				dptr = &sdp->isp_devparam[tgt].cur_dflags;
1732 			else
1733 				dptr = &sdp->isp_devparam[tgt].dev_flags;
1734 #else
1735 			/*
1736 			 * We always update (internally) from dev_flags
1737 			 * so any request to change settings just gets
1738 			 * vectored to that location.
1739 			 */
1740 			dptr = &sdp->isp_devparam[tgt].dev_flags;
1741 #endif
1742 
1743 			/*
1744 			 * Note that these operations affect the
1745 			 * the goal flags (dev_flags)- not
1746 			 * the current state flags. Then we mark
1747 			 * things so that the next operation to
1748 			 * this HBA will cause the update to occur.
1749 			 */
1750 			if (cts->valid & CCB_TRANS_DISC_VALID) {
1751 				if ((cts->flags & CCB_TRANS_DISC_ENB) != 0) {
1752 					*dptr |= DPARM_DISC;
1753 				} else {
1754 					*dptr &= ~DPARM_DISC;
1755 				}
1756 			}
1757 			if (cts->valid & CCB_TRANS_TQ_VALID) {
1758 				if ((cts->flags & CCB_TRANS_TAG_ENB) != 0) {
1759 					*dptr |= DPARM_TQING;
1760 				} else {
1761 					*dptr &= ~DPARM_TQING;
1762 				}
1763 			}
1764 			if (cts->valid & CCB_TRANS_BUS_WIDTH_VALID) {
1765 				switch (cts->bus_width) {
1766 				case MSG_EXT_WDTR_BUS_16_BIT:
1767 					*dptr |= DPARM_WIDE;
1768 					break;
1769 				default:
1770 					*dptr &= ~DPARM_WIDE;
1771 				}
1772 			}
1773 			/*
1774 			 * Any SYNC RATE of nonzero and SYNC_OFFSET
1775 			 * of nonzero will cause us to go to the
1776 			 * selected (from NVRAM) maximum value for
1777 			 * this device. At a later point, we'll
1778 			 * allow finer control.
1779 			 */
1780 			if ((cts->valid & CCB_TRANS_SYNC_RATE_VALID) &&
1781 			    (cts->valid & CCB_TRANS_SYNC_OFFSET_VALID) &&
1782 			    (cts->sync_offset > 0)) {
1783 				*dptr |= DPARM_SYNC;
1784 			} else {
1785 				*dptr &= ~DPARM_SYNC;
1786 			}
1787 			*dptr |= DPARM_SAFE_DFLT;
1788 			isp_prt(isp, ISP_LOGDEBUG0,
1789 			    "%d.%d set %s period 0x%x offset 0x%x flags 0x%x",
1790 			    bus, tgt, (cts->flags & CCB_TRANS_CURRENT_SETTINGS)?
1791 			    "current" : "user",
1792 			    sdp->isp_devparam[tgt].sync_period,
1793 			    sdp->isp_devparam[tgt].sync_offset,
1794 			    sdp->isp_devparam[tgt].dev_flags);
1795 			sdp->isp_devparam[tgt].dev_update = 1;
1796 			isp->isp_update |= (1 << bus);
1797 		}
1798 		ISP_UNLOCK(isp);
1799 		ccb->ccb_h.status = CAM_REQ_CMP;
1800 		xpt_done(ccb);
1801 		break;
1802 
1803 	case XPT_GET_TRAN_SETTINGS:
1804 
1805 		cts = &ccb->cts;
1806 		tgt = cts->ccb_h.target_id;
1807 		if (IS_FC(isp)) {
1808 			/*
1809 			 * a lot of normal SCSI things don't make sense.
1810 			 */
1811 			cts->flags = CCB_TRANS_TAG_ENB | CCB_TRANS_DISC_ENB;
1812 			cts->valid = CCB_TRANS_DISC_VALID | CCB_TRANS_TQ_VALID;
1813 			/*
1814 			 * How do you measure the width of a high
1815 			 * speed serial bus? Well, in bytes.
1816 			 *
1817 			 * Offset and period make no sense, though, so we set
1818 			 * (above) a 'base' transfer speed to be gigabit.
1819 			 */
1820 			cts->bus_width = MSG_EXT_WDTR_BUS_8_BIT;
1821 		} else {
1822 			sdparam *sdp = isp->isp_param;
1823 			u_int16_t dval, pval, oval;
1824 			int bus = cam_sim_bus(xpt_path_sim(cts->ccb_h.path));
1825 
1826 			sdp += bus;
1827 			if (cts->flags & CCB_TRANS_CURRENT_SETTINGS) {
1828 				ISP_LOCK(isp);
1829 				sdp->isp_devparam[tgt].dev_refresh = 1;
1830 				isp->isp_update |= (1 << bus);
1831 				(void) isp_control(isp, ISPCTL_UPDATE_PARAMS,
1832 				    NULL);
1833 				ISP_UNLOCK(isp);
1834 				dval = sdp->isp_devparam[tgt].cur_dflags;
1835 				oval = sdp->isp_devparam[tgt].cur_offset;
1836 				pval = sdp->isp_devparam[tgt].cur_period;
1837 			} else {
1838 				dval = sdp->isp_devparam[tgt].dev_flags;
1839 				oval = sdp->isp_devparam[tgt].sync_offset;
1840 				pval = sdp->isp_devparam[tgt].sync_period;
1841 			}
1842 
1843 			ISP_LOCK(isp);
1844 			cts->flags &= ~(CCB_TRANS_DISC_ENB|CCB_TRANS_TAG_ENB);
1845 
1846 			if (dval & DPARM_DISC) {
1847 				cts->flags |= CCB_TRANS_DISC_ENB;
1848 			}
1849 			if (dval & DPARM_TQING) {
1850 				cts->flags |= CCB_TRANS_TAG_ENB;
1851 			}
1852 			if (dval & DPARM_WIDE) {
1853 				cts->bus_width = MSG_EXT_WDTR_BUS_16_BIT;
1854 			} else {
1855 				cts->bus_width = MSG_EXT_WDTR_BUS_8_BIT;
1856 			}
1857 			cts->valid = CCB_TRANS_BUS_WIDTH_VALID |
1858 			    CCB_TRANS_DISC_VALID | CCB_TRANS_TQ_VALID;
1859 
1860 			if ((dval & DPARM_SYNC) && oval != 0) {
1861 				cts->sync_period = pval;
1862 				cts->sync_offset = oval;
1863 				cts->valid |=
1864 				    CCB_TRANS_SYNC_RATE_VALID |
1865 				    CCB_TRANS_SYNC_OFFSET_VALID;
1866 			}
1867 			ISP_UNLOCK(isp);
1868 			isp_prt(isp, ISP_LOGDEBUG0,
1869 			    "%d.%d get %s period 0x%x offset 0x%x flags 0x%x",
1870 			    bus, tgt, (cts->flags & CCB_TRANS_CURRENT_SETTINGS)?
1871 			    "current" : "user", pval, oval, dval);
1872 		}
1873 		ccb->ccb_h.status = CAM_REQ_CMP;
1874 		xpt_done(ccb);
1875 		break;
1876 
1877 	case XPT_CALC_GEOMETRY:
1878 	{
1879 		struct ccb_calc_geometry *ccg;
1880 		u_int32_t secs_per_cylinder;
1881 		u_int32_t size_mb;
1882 
1883 		ccg = &ccb->ccg;
1884 		if (ccg->block_size == 0) {
1885 			isp_prt(isp, ISP_LOGERR,
1886 			    "%d.%d XPT_CALC_GEOMETRY block size 0?",
1887 			    ccg->ccb_h.target_id, ccg->ccb_h.target_lun);
1888 			ccb->ccb_h.status = CAM_REQ_INVALID;
1889 			xpt_done(ccb);
1890 			break;
1891 		}
1892 		size_mb = ccg->volume_size /((1024L * 1024L) / ccg->block_size);
1893 		if (size_mb > 1024) {
1894 			ccg->heads = 255;
1895 			ccg->secs_per_track = 63;
1896 		} else {
1897 			ccg->heads = 64;
1898 			ccg->secs_per_track = 32;
1899 		}
1900 		secs_per_cylinder = ccg->heads * ccg->secs_per_track;
1901 		ccg->cylinders = ccg->volume_size / secs_per_cylinder;
1902 		ccb->ccb_h.status = CAM_REQ_CMP;
1903 		xpt_done(ccb);
1904 		break;
1905 	}
1906 	case XPT_RESET_BUS:		/* Reset the specified bus */
1907 		bus = cam_sim_bus(sim);
1908 		ISP_LOCK(isp);
1909 		error = isp_control(isp, ISPCTL_RESET_BUS, &bus);
1910 		ISP_UNLOCK(isp);
1911 		if (error)
1912 			ccb->ccb_h.status = CAM_REQ_CMP_ERR;
1913 		else {
1914 			if (cam_sim_bus(sim) && isp->isp_path2 != NULL)
1915 				xpt_async(AC_BUS_RESET, isp->isp_path2, NULL);
1916 			else if (isp->isp_path != NULL)
1917 				xpt_async(AC_BUS_RESET, isp->isp_path, NULL);
1918 			ccb->ccb_h.status = CAM_REQ_CMP;
1919 		}
1920 		xpt_done(ccb);
1921 		break;
1922 
1923 	case XPT_TERM_IO:		/* Terminate the I/O process */
1924 		ccb->ccb_h.status = CAM_REQ_INVALID;
1925 		xpt_done(ccb);
1926 		break;
1927 
1928 	case XPT_PATH_INQ:		/* Path routing inquiry */
1929 	{
1930 		struct ccb_pathinq *cpi = &ccb->cpi;
1931 
1932 		cpi->version_num = 1;
1933 #ifdef	ISP_TARGET_MODE
1934 		cpi->target_sprt = PIT_PROCESSOR | PIT_DISCONNECT | PIT_TERM_IO;
1935 #else
1936 		cpi->target_sprt = 0;
1937 #endif
1938 		cpi->hba_eng_cnt = 0;
1939 		cpi->max_target = ISP_MAX_TARGETS(isp) - 1;
1940 		cpi->max_lun = ISP_MAX_LUNS(isp) - 1;
1941 		cpi->bus_id = cam_sim_bus(sim);
1942 		if (IS_FC(isp)) {
1943 			cpi->hba_misc = PIM_NOBUSRESET;
1944 			/*
1945 			 * Because our loop ID can shift from time to time,
1946 			 * make our initiator ID out of range of our bus.
1947 			 */
1948 			cpi->initiator_id = cpi->max_target + 1;
1949 
1950 			/*
1951 			 * Set base transfer capabilities for Fibre Channel.
1952 			 * Technically not correct because we don't know
1953 			 * what media we're running on top of- but we'll
1954 			 * look good if we always say 100MB/s.
1955 			 */
1956 			cpi->base_transfer_speed = 100000;
1957 			cpi->hba_inquiry = PI_TAG_ABLE;
1958 		} else {
1959 			sdparam *sdp = isp->isp_param;
1960 			sdp += cam_sim_bus(xpt_path_sim(cpi->ccb_h.path));
1961 			cpi->hba_inquiry = PI_SDTR_ABLE|PI_TAG_ABLE|PI_WIDE_16;
1962 			cpi->hba_misc = 0;
1963 			cpi->initiator_id = sdp->isp_initiator_id;
1964 			cpi->base_transfer_speed = 3300;
1965 		}
1966 		strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN);
1967 		strncpy(cpi->hba_vid, "Qlogic", HBA_IDLEN);
1968 		strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN);
1969 		cpi->unit_number = cam_sim_unit(sim);
1970 		cpi->ccb_h.status = CAM_REQ_CMP;
1971 		xpt_done(ccb);
1972 		break;
1973 	}
1974 	default:
1975 		ccb->ccb_h.status = CAM_REQ_INVALID;
1976 		xpt_done(ccb);
1977 		break;
1978 	}
1979 }
1980 
1981 #define	ISPDDB	(CAM_DEBUG_INFO|CAM_DEBUG_TRACE|CAM_DEBUG_CDB)
1982 void
1983 isp_done(struct ccb_scsiio *sccb)
1984 {
1985 	struct ispsoftc *isp = XS_ISP(sccb);
1986 
1987 	if (XS_NOERR(sccb))
1988 		XS_SETERR(sccb, CAM_REQ_CMP);
1989 
1990 	if ((sccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP &&
1991 	    (sccb->scsi_status != SCSI_STATUS_OK)) {
1992 		sccb->ccb_h.status &= ~CAM_STATUS_MASK;
1993 		if ((sccb->scsi_status == SCSI_STATUS_CHECK_COND) &&
1994 		    (sccb->ccb_h.status & CAM_AUTOSNS_VALID) == 0) {
1995 			sccb->ccb_h.status |= CAM_AUTOSENSE_FAIL;
1996 		} else {
1997 			sccb->ccb_h.status |= CAM_SCSI_STATUS_ERROR;
1998 		}
1999 	}
2000 
2001 	sccb->ccb_h.status &= ~CAM_SIM_QUEUED;
2002 	if ((sccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
2003 		if ((sccb->ccb_h.status & CAM_DEV_QFRZN) == 0) {
2004 			sccb->ccb_h.status |= CAM_DEV_QFRZN;
2005 			xpt_freeze_devq(sccb->ccb_h.path, 1);
2006 			if (sccb->scsi_status != SCSI_STATUS_OK)
2007 				isp_prt(isp, ISP_LOGDEBUG2,
2008 				    "freeze devq %d.%d %x %x",
2009 				    sccb->ccb_h.target_id,
2010 				    sccb->ccb_h.target_lun, sccb->ccb_h.status,
2011 				    sccb->scsi_status);
2012 		}
2013 	}
2014 
2015 	/*
2016 	 * If we were frozen waiting resources, clear that we were frozen
2017 	 * waiting for resources. If we are no longer frozen, and the devq
2018 	 * isn't frozen, mark the completing CCB to have the XPT layer
2019 	 * release the simq.
2020 	 */
2021 	if (isp->isp_osinfo.simqfrozen & SIMQFRZ_RESOURCE) {
2022 		isp->isp_osinfo.simqfrozen &= ~SIMQFRZ_RESOURCE;
2023 		if (isp->isp_osinfo.simqfrozen == 0) {
2024 			if ((sccb->ccb_h.status & CAM_DEV_QFRZN) == 0) {
2025 				isp_prt(isp, ISP_LOGDEBUG2,
2026 				    "isp_done->relsimq");
2027 				sccb->ccb_h.status |= CAM_RELEASE_SIMQ;
2028 			} else {
2029 				isp_prt(isp, ISP_LOGDEBUG2,
2030 				    "isp_done->devq frozen");
2031 			}
2032 		} else {
2033 			isp_prt(isp, ISP_LOGDEBUG2,
2034 			    "isp_done -> simqfrozen = %x",
2035 			    isp->isp_osinfo.simqfrozen);
2036 		}
2037 	}
2038 	if ((CAM_DEBUGGED(sccb->ccb_h.path, ISPDDB)) &&
2039 	    (sccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
2040 		xpt_print_path(sccb->ccb_h.path);
2041 		isp_prt(isp, ISP_LOGINFO,
2042 		    "cam completion status 0x%x", sccb->ccb_h.status);
2043 	}
2044 
2045 	XS_CMD_S_DONE(sccb);
2046 	if (XS_CMD_WDOG_P(sccb) == 0) {
2047 		untimeout(isp_watchdog, (caddr_t)sccb, sccb->ccb_h.timeout_ch);
2048 		if (XS_CMD_GRACE_P(sccb)) {
2049 			isp_prt(isp, ISP_LOGDEBUG2,
2050 			    "finished command on borrowed time");
2051 		}
2052 		XS_CMD_S_CLEAR(sccb);
2053 		ISP_UNLOCK(isp);
2054 #ifdef	ISP_SMPLOCK
2055 		mtx_lock(&Giant);
2056 		xpt_done((union ccb *) sccb);
2057 		mtx_unlock(&Giant);
2058 #else
2059 		xpt_done((union ccb *) sccb);
2060 #endif
2061 		ISP_LOCK(isp);
2062 	}
2063 }
2064 
2065 int
2066 isp_async(struct ispsoftc *isp, ispasync_t cmd, void *arg)
2067 {
2068 	int bus, rv = 0;
2069 	switch (cmd) {
2070 	case ISPASYNC_NEW_TGT_PARAMS:
2071 	{
2072 		int flags, tgt;
2073 		sdparam *sdp = isp->isp_param;
2074 		struct ccb_trans_settings neg;
2075 		struct cam_path *tmppath;
2076 
2077 		tgt = *((int *)arg);
2078 		bus = (tgt >> 16) & 0xffff;
2079 		tgt &= 0xffff;
2080 		sdp += bus;
2081 		if (xpt_create_path(&tmppath, NULL,
2082 		    cam_sim_path(bus? isp->isp_sim2 : isp->isp_sim),
2083 		    tgt, CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
2084 			isp_prt(isp, ISP_LOGWARN,
2085 			    "isp_async cannot make temp path for %d.%d",
2086 			    tgt, bus);
2087 			rv = -1;
2088 			break;
2089 		}
2090 		flags = sdp->isp_devparam[tgt].cur_dflags;
2091 		neg.valid = CCB_TRANS_DISC_VALID | CCB_TRANS_TQ_VALID;
2092 		if (flags & DPARM_DISC) {
2093 			neg.flags |= CCB_TRANS_DISC_ENB;
2094 		}
2095 		if (flags & DPARM_TQING) {
2096 			neg.flags |= CCB_TRANS_TAG_ENB;
2097 		}
2098 		neg.valid |= CCB_TRANS_BUS_WIDTH_VALID;
2099 		neg.bus_width = (flags & DPARM_WIDE)?
2100 		    MSG_EXT_WDTR_BUS_8_BIT : MSG_EXT_WDTR_BUS_16_BIT;
2101 		neg.sync_period = sdp->isp_devparam[tgt].cur_period;
2102 		neg.sync_offset = sdp->isp_devparam[tgt].cur_offset;
2103 		if (flags & DPARM_SYNC) {
2104 			neg.valid |=
2105 			    CCB_TRANS_SYNC_RATE_VALID |
2106 			    CCB_TRANS_SYNC_OFFSET_VALID;
2107 		}
2108 		isp_prt(isp, ISP_LOGDEBUG2,
2109 		    "NEW_TGT_PARAMS bus %d tgt %d period %x offset %x flags %x",
2110 		    bus, tgt, neg.sync_period, neg.sync_offset, flags);
2111 		xpt_setup_ccb(&neg.ccb_h, tmppath, 1);
2112 		xpt_async(AC_TRANSFER_NEG, tmppath, &neg);
2113 		xpt_free_path(tmppath);
2114 		break;
2115 	}
2116 	case ISPASYNC_BUS_RESET:
2117 		bus = *((int *)arg);
2118 		isp_prt(isp, ISP_LOGINFO, "SCSI bus reset on bus %d detected",
2119 		    bus);
2120 		if (bus > 0 && isp->isp_path2) {
2121 			xpt_async(AC_BUS_RESET, isp->isp_path2, NULL);
2122 		} else if (isp->isp_path) {
2123 			xpt_async(AC_BUS_RESET, isp->isp_path, NULL);
2124 		}
2125 		break;
2126 	case ISPASYNC_LOOP_DOWN:
2127 		if (isp->isp_path) {
2128 			if (isp->isp_osinfo.simqfrozen == 0) {
2129 				isp_prt(isp, ISP_LOGDEBUG2,
2130 				    "loop down freeze simq");
2131 				xpt_freeze_simq(isp->isp_sim, 1);
2132 			}
2133 			isp->isp_osinfo.simqfrozen |= SIMQFRZ_LOOPDOWN;
2134 		}
2135 		isp_prt(isp, ISP_LOGINFO, "Loop DOWN");
2136 		break;
2137 	case ISPASYNC_LOOP_UP:
2138 		if (isp->isp_path) {
2139 			int wasfrozen =
2140 			    isp->isp_osinfo.simqfrozen & SIMQFRZ_LOOPDOWN;
2141 			isp->isp_osinfo.simqfrozen &= ~SIMQFRZ_LOOPDOWN;
2142 			if (wasfrozen && isp->isp_osinfo.simqfrozen == 0) {
2143 				xpt_release_simq(isp->isp_sim, 1);
2144 				isp_prt(isp, ISP_LOGDEBUG2,
2145 				    "loop up release simq");
2146 			}
2147 		}
2148 		isp_prt(isp, ISP_LOGINFO, "Loop UP");
2149 		break;
2150 	case ISPASYNC_PROMENADE:
2151 	{
2152 		const char *fmt = "Target %d (Loop 0x%x) Port ID 0x%x "
2153 		    "(role %s) %s\n Port WWN 0x%08x%08x\n Node WWN 0x%08x%08x";
2154 		static const char *roles[4] = {
2155 		    "(none)", "Target", "Initiator", "Target/Initiator"
2156 		};
2157 		fcparam *fcp = isp->isp_param;
2158 		int tgt = *((int *) arg);
2159 		struct lportdb *lp = &fcp->portdb[tgt];
2160 
2161 		isp_prt(isp, ISP_LOGINFO, fmt, tgt, lp->loopid, lp->portid,
2162 		    roles[lp->roles & 0x3],
2163 		    (lp->valid)? "Arrived" : "Departed",
2164 		    (u_int32_t) (lp->port_wwn >> 32),
2165 		    (u_int32_t) (lp->port_wwn & 0xffffffffLL),
2166 		    (u_int32_t) (lp->node_wwn >> 32),
2167 		    (u_int32_t) (lp->node_wwn & 0xffffffffLL));
2168 		break;
2169 	}
2170 	case ISPASYNC_CHANGE_NOTIFY:
2171 		if (arg == (void *) 1) {
2172 			isp_prt(isp, ISP_LOGINFO,
2173 			    "Name Server Database Changed");
2174 		} else {
2175 			isp_prt(isp, ISP_LOGINFO,
2176 			    "Name Server Database Changed");
2177 		}
2178 		break;
2179 	case ISPASYNC_FABRIC_DEV:
2180 	{
2181 		int target, lrange;
2182 		struct lportdb *lp = NULL;
2183 		char *pt;
2184 		sns_ganrsp_t *resp = (sns_ganrsp_t *) arg;
2185 		u_int32_t portid;
2186 		u_int64_t wwpn, wwnn;
2187 		fcparam *fcp = isp->isp_param;
2188 
2189 		portid =
2190 		    (((u_int32_t) resp->snscb_port_id[0]) << 16) |
2191 		    (((u_int32_t) resp->snscb_port_id[1]) << 8) |
2192 		    (((u_int32_t) resp->snscb_port_id[2]));
2193 
2194 		wwpn =
2195 		    (((u_int64_t)resp->snscb_portname[0]) << 56) |
2196 		    (((u_int64_t)resp->snscb_portname[1]) << 48) |
2197 		    (((u_int64_t)resp->snscb_portname[2]) << 40) |
2198 		    (((u_int64_t)resp->snscb_portname[3]) << 32) |
2199 		    (((u_int64_t)resp->snscb_portname[4]) << 24) |
2200 		    (((u_int64_t)resp->snscb_portname[5]) << 16) |
2201 		    (((u_int64_t)resp->snscb_portname[6]) <<  8) |
2202 		    (((u_int64_t)resp->snscb_portname[7]));
2203 
2204 		wwnn =
2205 		    (((u_int64_t)resp->snscb_nodename[0]) << 56) |
2206 		    (((u_int64_t)resp->snscb_nodename[1]) << 48) |
2207 		    (((u_int64_t)resp->snscb_nodename[2]) << 40) |
2208 		    (((u_int64_t)resp->snscb_nodename[3]) << 32) |
2209 		    (((u_int64_t)resp->snscb_nodename[4]) << 24) |
2210 		    (((u_int64_t)resp->snscb_nodename[5]) << 16) |
2211 		    (((u_int64_t)resp->snscb_nodename[6]) <<  8) |
2212 		    (((u_int64_t)resp->snscb_nodename[7]));
2213 		if (portid == 0 || wwpn == 0) {
2214 			break;
2215 		}
2216 
2217 		switch (resp->snscb_port_type) {
2218 		case 1:
2219 			pt = "   N_Port";
2220 			break;
2221 		case 2:
2222 			pt = "  NL_Port";
2223 			break;
2224 		case 3:
2225 			pt = "F/NL_Port";
2226 			break;
2227 		case 0x7f:
2228 			pt = "  Nx_Port";
2229 			break;
2230 		case 0x81:
2231 			pt = "  F_port";
2232 			break;
2233 		case 0x82:
2234 			pt = "  FL_Port";
2235 			break;
2236 		case 0x84:
2237 			pt = "   E_port";
2238 			break;
2239 		default:
2240 			pt = "?";
2241 			break;
2242 		}
2243 		isp_prt(isp, ISP_LOGINFO,
2244 		    "%s @ 0x%x, Node 0x%08x%08x Port %08x%08x",
2245 		    pt, portid, ((u_int32_t) (wwnn >> 32)), ((u_int32_t) wwnn),
2246 		    ((u_int32_t) (wwpn >> 32)), ((u_int32_t) wwpn));
2247 		/*
2248 		 * We're only interested in SCSI_FCP types (for now)
2249 		 */
2250 		if ((resp->snscb_fc4_types[2] & 1) == 0) {
2251 			break;
2252 		}
2253 		if (fcp->isp_topo != TOPO_F_PORT)
2254 			lrange = FC_SNS_ID+1;
2255 		else
2256 			lrange = 0;
2257 		/*
2258 		 * Is it already in our list?
2259 		 */
2260 		for (target = lrange; target < MAX_FC_TARG; target++) {
2261 			if (target >= FL_PORT_ID && target <= FC_SNS_ID) {
2262 				continue;
2263 			}
2264 			lp = &fcp->portdb[target];
2265 			if (lp->port_wwn == wwpn && lp->node_wwn == wwnn) {
2266 				lp->fabric_dev = 1;
2267 				break;
2268 			}
2269 		}
2270 		if (target < MAX_FC_TARG) {
2271 			break;
2272 		}
2273 		for (target = lrange; target < MAX_FC_TARG; target++) {
2274 			if (target >= FL_PORT_ID && target <= FC_SNS_ID) {
2275 				continue;
2276 			}
2277 			lp = &fcp->portdb[target];
2278 			if (lp->port_wwn == 0) {
2279 				break;
2280 			}
2281 		}
2282 		if (target == MAX_FC_TARG) {
2283 			isp_prt(isp, ISP_LOGWARN,
2284 			    "no more space for fabric devices");
2285 			break;
2286 		}
2287 		lp->node_wwn = wwnn;
2288 		lp->port_wwn = wwpn;
2289 		lp->portid = portid;
2290 		lp->fabric_dev = 1;
2291 		break;
2292 	}
2293 #ifdef	ISP_TARGET_MODE
2294 	case ISPASYNC_TARGET_MESSAGE:
2295 	{
2296 		tmd_msg_t *mp = arg;
2297 		isp_prt(isp, ISP_LOGDEBUG2,
2298 		    "bus %d iid %d tgt %d lun %d ttype %x tval %x msg[0]=%x",
2299 		    mp->nt_bus, (int) mp->nt_iid, (int) mp->nt_tgt,
2300 		    (int) mp->nt_lun, mp->nt_tagtype, mp->nt_tagval,
2301 		    mp->nt_msg[0]);
2302 		break;
2303 	}
2304 	case ISPASYNC_TARGET_EVENT:
2305 	{
2306 		tmd_event_t *ep = arg;
2307 		isp_prt(isp, ISP_LOGDEBUG2,
2308 		    "bus %d event code 0x%x", ep->ev_bus, ep->ev_event);
2309 		break;
2310 	}
2311 	case ISPASYNC_TARGET_ACTION:
2312 		switch (((isphdr_t *)arg)->rqs_entry_type) {
2313 		default:
2314 			isp_prt(isp, ISP_LOGWARN,
2315 			   "event 0x%x for unhandled target action",
2316 			    ((isphdr_t *)arg)->rqs_entry_type);
2317 			break;
2318 		case RQSTYPE_ATIO:
2319 			rv = isp_handle_platform_atio(isp, (at_entry_t *) arg);
2320 			break;
2321 		case RQSTYPE_ATIO2:
2322 			rv = isp_handle_platform_atio2(isp, (at2_entry_t *)arg);
2323 			break;
2324 		case RQSTYPE_CTIO2:
2325 		case RQSTYPE_CTIO:
2326 			rv = isp_handle_platform_ctio(isp, arg);
2327 			break;
2328 		case RQSTYPE_ENABLE_LUN:
2329 		case RQSTYPE_MODIFY_LUN:
2330 			isp_cv_signal_rqe(isp, ((lun_entry_t *)arg)->le_status);
2331 			break;
2332 		}
2333 		break;
2334 #endif
2335 	default:
2336 		isp_prt(isp, ISP_LOGERR, "unknown isp_async event %d", cmd);
2337 		rv = -1;
2338 		break;
2339 	}
2340 	return (rv);
2341 }
2342 
2343 
2344 /*
2345  * Locks are held before coming here.
2346  */
2347 void
2348 isp_uninit(struct ispsoftc *isp)
2349 {
2350 	ISP_WRITE(isp, HCCR, HCCR_CMD_RESET);
2351 	DISABLE_INTS(isp);
2352 }
2353 
2354 void
2355 isp_prt(struct ispsoftc *isp, int level, const char *fmt, ...)
2356 {
2357 	va_list ap;
2358 	if (level != ISP_LOGALL && (level & isp->isp_dblev) == 0) {
2359 		return;
2360 	}
2361 	printf("%s: ", device_get_nameunit(isp->isp_dev));
2362 	va_start(ap, fmt);
2363 	vprintf(fmt, ap);
2364 	va_end(ap);
2365 	printf("\n");
2366 }
2367