xref: /freebsd/sys/dev/isp/isp_freebsd.c (revision e63a2405763dc40dbb83dedb7c6907dc23d46cb3)
1 /* $FreeBSD$ */
2 /*
3  * Platform (FreeBSD) dependent common attachment code for Qlogic adapters.
4  *
5  *---------------------------------------
6  * Copyright (c) 1997, 1998, 1999 by Matthew Jacob
7  * NASA/Ames Research Center
8  * All rights reserved.
9  *---------------------------------------
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice immediately at the beginning of the file, without modification,
16  *    this list of conditions, and the following disclaimer.
17  * 2. Redistributions in binary form must reproduce the above copyright
18  *    notice, this list of conditions and the following disclaimer in the
19  *    documentation and/or other materials provided with the distribution.
20  * 3. The name of the author may not be used to endorse or promote products
21  *    derived from this software without specific prior written permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
24  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
27  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33  * SUCH DAMAGE.
34  */
35 #include <dev/isp/isp_freebsd.h>
36 #include <sys/malloc.h>
37 
38 static void isp_cam_async(void *, u_int32_t, struct cam_path *, void *);
39 static void isp_poll(struct cam_sim *);
40 static void isp_relsim(void *);
41 static void isp_action(struct cam_sim *, union ccb *);
42 
43 static struct ispsoftc *isplist = NULL;
44 /* #define	ISP_LUN0_ONLY	1 */
45 #ifdef	DEBUG
46 int isp_debug = 2;
47 #elif defined(CAMDEBUG) || defined(DIAGNOSTIC)
48 int isp_debug = 1;
49 #else
50 int isp_debug = 0;
51 #endif
52 
53 void
54 isp_attach(struct ispsoftc *isp)
55 {
56 	int primary, secondary;
57 	struct ccb_setasync csa;
58 	struct cam_devq *devq;
59 	struct cam_sim *sim;
60 	struct cam_path *path;
61 
62 	/*
63 	 * Establish (in case of 12X0) which bus is the primary.
64 	 */
65 
66 	primary = 0;
67 	secondary = 1;
68 
69 	/*
70 	 * Create the device queue for our SIM(s).
71 	 */
72 	devq = cam_simq_alloc(isp->isp_maxcmds);
73 	if (devq == NULL) {
74 		return;
75 	}
76 
77 	/*
78 	 * Construct our SIM entry.
79 	 */
80 	sim = cam_sim_alloc(isp_action, isp_poll, "isp", isp,
81 	    isp->isp_unit, 1, isp->isp_maxcmds, devq);
82 	if (sim == NULL) {
83 		cam_simq_free(devq);
84 		return;
85 	}
86 	if (xpt_bus_register(sim, primary) != CAM_SUCCESS) {
87 		cam_sim_free(sim, TRUE);
88 		return;
89 	}
90 
91 	if (xpt_create_path(&path, NULL, cam_sim_path(sim),
92 	    CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
93 		xpt_bus_deregister(cam_sim_path(sim));
94 		cam_sim_free(sim, TRUE);
95 		return;
96 	}
97 
98 	xpt_setup_ccb(&csa.ccb_h, path, 5);
99 	csa.ccb_h.func_code = XPT_SASYNC_CB;
100 	csa.event_enable = AC_LOST_DEVICE;
101 	csa.callback = isp_cam_async;
102 	csa.callback_arg = sim;
103 	xpt_action((union ccb *)&csa);
104 	isp->isp_sim = sim;
105 	isp->isp_path = path;
106 
107 	/*
108 	 * If we have a second channel, construct SIM entry for that.
109 	 */
110 	if (IS_DUALBUS(isp)) {
111 		sim = cam_sim_alloc(isp_action, isp_poll, "isp", isp,
112 		    isp->isp_unit, 1, isp->isp_maxcmds, devq);
113 		if (sim == NULL) {
114 			xpt_bus_deregister(cam_sim_path(isp->isp_sim));
115 			xpt_free_path(isp->isp_path);
116 			cam_simq_free(devq);
117 			return;
118 		}
119 		if (xpt_bus_register(sim, secondary) != CAM_SUCCESS) {
120 			xpt_bus_deregister(cam_sim_path(isp->isp_sim));
121 			xpt_free_path(isp->isp_path);
122 			cam_sim_free(sim, TRUE);
123 			return;
124 		}
125 
126 		if (xpt_create_path(&path, NULL, cam_sim_path(sim),
127 		    CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
128 			xpt_bus_deregister(cam_sim_path(isp->isp_sim));
129 			xpt_free_path(isp->isp_path);
130 			xpt_bus_deregister(cam_sim_path(sim));
131 			cam_sim_free(sim, TRUE);
132 			return;
133 		}
134 
135 		xpt_setup_ccb(&csa.ccb_h, path, 5);
136 		csa.ccb_h.func_code = XPT_SASYNC_CB;
137 		csa.event_enable = AC_LOST_DEVICE;
138 		csa.callback = isp_cam_async;
139 		csa.callback_arg = sim;
140 		xpt_action((union ccb *)&csa);
141 		isp->isp_sim2 = sim;
142 		isp->isp_path2 = path;
143 	}
144 	isp->isp_state = ISP_RUNSTATE;
145 	if (isplist == NULL) {
146 		isplist = isp;
147 	} else {
148 		struct ispsoftc *tmp = isplist;
149 		while (tmp->isp_osinfo.next) {
150 			tmp = tmp->isp_osinfo.next;
151 		}
152 		tmp->isp_osinfo.next = isp;
153 	}
154 }
155 
156 
157 /*
158  * Put the target mode functions here, because some are inlines
159  */
160 
161 #ifdef	ISP_TARGET_MODE
162 #include "targbh.h"
163 
164 static __inline int is_lun_enabled(struct ispsoftc *, lun_id_t);
165 static __inline int are_any_luns_enabled(struct ispsoftc *);
166 static __inline tstate_t *get_lun_statep(struct ispsoftc *, lun_id_t);
167 static __inline void rls_lun_statep(struct ispsoftc *, tstate_t *);
168 static __inline int isp_psema_sig_rqe(struct ispsoftc *);
169 static __inline int isp_cv_wait_timed_rqe(struct ispsoftc *, int);
170 static __inline void isp_cv_signal_rqe(struct ispsoftc *, int);
171 static __inline void isp_vsema_rqe(struct ispsoftc *);
172 static cam_status
173 create_lun_state(struct ispsoftc *, struct cam_path *, tstate_t **);
174 static void destroy_lun_state(struct ispsoftc *, tstate_t *);
175 static void isp_en_lun(struct ispsoftc *, union ccb *);
176 static cam_status isp_abort_tgt_ccb(struct ispsoftc *, union ccb *);
177 static cam_status isp_target_start_ctio(struct ispsoftc *, union ccb *);
178 
179 
180 static int isp_handle_platform_atio(struct ispsoftc *, at_entry_t *);
181 static int isp_handle_platform_atio2(struct ispsoftc *, at2_entry_t *);
182 static int isp_handle_platform_ctio(struct ispsoftc *, void *);
183 
184 static __inline int
185 is_lun_enabled(struct ispsoftc *isp, lun_id_t lun)
186 {
187 	tstate_t *tptr;
188 	int s = splsoftcam();
189 	if ((tptr = isp->isp_osinfo.lun_hash[LUN_HASH_FUNC(lun)]) == NULL) {
190 		splx(s);
191 		return (0);
192 	}
193 	do {
194 		if (tptr->lun == (lun_id_t) lun) {
195 			splx(s);
196 			return (1);
197 		}
198 	} while ((tptr = tptr->next) != NULL);
199 	splx(s);
200 	return (0);
201 }
202 
203 static __inline int
204 are_any_luns_enabled(struct ispsoftc *isp)
205 {
206 	int i;
207 	for (i = 0; i < LUN_HASH_SIZE; i++) {
208 		if (isp->isp_osinfo.lun_hash[i]) {
209 			return (1);
210 		}
211 	}
212 	return (0);
213 }
214 
215 static __inline tstate_t *
216 get_lun_statep(struct ispsoftc *isp, lun_id_t lun)
217 {
218 	tstate_t *tptr;
219 	int s;
220 
221 	s = splsoftcam();
222 	if (lun == CAM_LUN_WILDCARD) {
223 		tptr = &isp->isp_osinfo.tsdflt;
224 		tptr->hold++;
225 		splx(s);
226 		return (tptr);
227 	} else {
228 		tptr = isp->isp_osinfo.lun_hash[LUN_HASH_FUNC(lun)];
229 	}
230 	if (tptr == NULL) {
231 		splx(s);
232 		return (NULL);
233 	}
234 
235 	do {
236 		if (tptr->lun == lun) {
237 			tptr->hold++;
238 			splx(s);
239 			return (tptr);
240 		}
241 	} while ((tptr = tptr->next) != NULL);
242 	splx(s);
243 	return (tptr);
244 }
245 
246 static __inline void
247 rls_lun_statep(struct ispsoftc *isp, tstate_t *tptr)
248 {
249 	if (tptr->hold)
250 		tptr->hold--;
251 }
252 
253 static __inline int
254 isp_psema_sig_rqe(struct ispsoftc *isp)
255 {
256 	int s = splcam();
257 	while (isp->isp_osinfo.tmflags & TM_BUSY) {
258 		isp->isp_osinfo.tmflags |= TM_WANTED;
259 		if (tsleep(&isp->isp_osinfo.tmflags, PRIBIO|PCATCH, "i0", 0)) {
260 			splx(s);
261 			return (-1);
262 		}
263 		isp->isp_osinfo.tmflags |= TM_BUSY;
264 	}
265 	splx(s);
266 	return (0);
267 }
268 
269 static __inline int
270 isp_cv_wait_timed_rqe(struct ispsoftc *isp, int timo)
271 {
272 	int s = splcam();
273 	if (tsleep(&isp->isp_osinfo.rstatus, PRIBIO, "qt1", timo)) {
274 		splx(s);
275 		return (-1);
276 	}
277 	splx(s);
278 	return (0);
279 }
280 
281 static __inline void
282 isp_cv_signal_rqe(struct ispsoftc *isp, int status)
283 {
284 	isp->isp_osinfo.rstatus = status;
285 	wakeup(&isp->isp_osinfo.rstatus);
286 }
287 
288 static __inline void
289 isp_vsema_rqe(struct ispsoftc *isp)
290 {
291 	int s = splcam();
292 	if (isp->isp_osinfo.tmflags & TM_WANTED) {
293 		isp->isp_osinfo.tmflags &= ~TM_WANTED;
294 		wakeup(&isp->isp_osinfo.tmflags);
295 	}
296 	isp->isp_osinfo.tmflags &= ~TM_BUSY;
297 	splx(s);
298 }
299 
300 static cam_status
301 create_lun_state(struct ispsoftc *isp, struct cam_path *path, tstate_t **rslt)
302 {
303 	int s;
304 	cam_status status;
305 	lun_id_t lun;
306 	tstate_t *tptr, *new;
307 
308 	lun = xpt_path_lun_id(path);
309 	if (lun < 0) {
310 		return (CAM_LUN_INVALID);
311 	}
312 	if (is_lun_enabled(isp, lun)) {
313 		return (CAM_LUN_ALRDY_ENA);
314 	}
315 	new = (tstate_t *) malloc(sizeof (tstate_t), M_DEVBUF, M_NOWAIT);
316 	if (new == NULL) {
317 		return (CAM_RESRC_UNAVAIL);
318 	}
319 	bzero(new, sizeof (tstate_t));
320 
321 	status = xpt_create_path(&new->owner, NULL, xpt_path_path_id(path),
322 	    xpt_path_target_id(path), xpt_path_lun_id(path));
323 	if (status != CAM_REQ_CMP) {
324 		free(new, M_DEVBUF);
325 		return (status);
326 	}
327 	new->lun = lun;
328 	SLIST_INIT(&new->atios);
329 	SLIST_INIT(&new->inots);
330 	new->hold = 1;
331 
332 	s = splsoftcam();
333 	if ((tptr = isp->isp_osinfo.lun_hash[LUN_HASH_FUNC(lun)]) == NULL) {
334 		isp->isp_osinfo.lun_hash[LUN_HASH_FUNC(lun)] = new;
335 	} else {
336 		while (tptr->next)
337 			tptr = tptr->next;
338 		tptr->next = new;
339 	}
340 	splx(s);
341 	*rslt = new;
342 	return (CAM_REQ_CMP);
343 }
344 
345 static __inline void
346 destroy_lun_state(struct ispsoftc *isp, tstate_t *tptr)
347 {
348 	tstate_t *lw, *pw;
349 	int s;
350 
351 	s = splsoftcam();
352 	if (tptr->hold) {
353 		splx(s);
354 		return;
355 	}
356 	pw = isp->isp_osinfo.lun_hash[LUN_HASH_FUNC(tptr->lun)];
357 	if (pw == NULL) {
358 		splx(s);
359 		return;
360 	} else if (pw->lun == tptr->lun) {
361 		isp->isp_osinfo.lun_hash[LUN_HASH_FUNC(tptr->lun)] = pw->next;
362 	} else {
363 		lw = pw;
364 		pw = lw->next;
365 		while (pw) {
366 			if (pw->lun == tptr->lun) {
367 				lw->next = pw->next;
368 				break;
369 			}
370 			lw = pw;
371 			pw = pw->next;
372 		}
373 		if (pw == NULL) {
374 			splx(s);
375 			return;
376 		}
377 	}
378 	free(tptr, M_DEVBUF);
379 	splx(s);
380 }
381 
382 static void
383 isp_en_lun(struct ispsoftc *isp, union ccb *ccb)
384 {
385 	const char *lfmt = "Lun now %sabled for target mode\n";
386 	struct ccb_en_lun *cel = &ccb->cel;
387 	tstate_t *tptr;
388 	u_int16_t rstat;
389 	int bus, s;
390 	lun_id_t lun;
391 	target_id_t tgt;
392 
393 
394 	bus = XS_CHANNEL(ccb);
395 	tgt = ccb->ccb_h.target_id;
396 	lun = ccb->ccb_h.target_lun;
397 
398 	/*
399 	 * First, check to see if we're enabling on fibre channel
400 	 * and don't yet have a notion of who the heck we are (no
401 	 * loop yet). We do this by
402 	 */
403 	if (IS_FC(isp) && cel->enable &&
404 	    (isp->isp_osinfo.tmflags & TM_TMODE_ENABLED) == 0) {
405 		int rv;
406 		fcparam *fcp = isp->isp_param;
407 
408 		s = splcam();
409 		rv = isp_control(isp, ISPCTL_FCLINK_TEST, NULL);
410 		(void) splx(s);
411 		if (rv || fcp->isp_fwstate != FW_READY) {
412 			xpt_print_path(ccb->ccb_h.path);
413 			printf("link status not good yet\n");
414 			ccb->ccb_h.status = CAM_REQ_CMP_ERR;
415 			return;
416 		}
417 		s = splcam();
418 		rv = isp_control(isp, ISPCTL_PDB_SYNC, NULL);
419 		(void) splx(s);
420 		if (rv || fcp->isp_loopstate != LOOP_READY) {
421 			xpt_print_path(ccb->ccb_h.path);
422 			printf("could not get a good port database\n");
423 			ccb->ccb_h.status = CAM_REQ_CMP_ERR;
424 			return;
425 		}
426 	}
427 
428 
429 	/*
430 	 * Next check to see whether this is a target/lun wildcard action.
431 	 *
432 	 * If so, we enable/disable target mode but don't do any lun enabling.
433 	 */
434 	if (lun == CAM_LUN_WILDCARD && tgt == CAM_TARGET_WILDCARD) {
435 		int av;
436 		tptr = &isp->isp_osinfo.tsdflt;
437 		if (cel->enable) {
438 			if (isp->isp_osinfo.tmflags & TM_TMODE_ENABLED) {
439 				ccb->ccb_h.status = CAM_LUN_ALRDY_ENA;
440 				return;
441 			}
442 			ccb->ccb_h.status =
443 			    xpt_create_path(&tptr->owner, NULL,
444 			    xpt_path_path_id(ccb->ccb_h.path),
445 			    xpt_path_target_id(ccb->ccb_h.path),
446 			    xpt_path_lun_id(ccb->ccb_h.path));
447 			if (ccb->ccb_h.status != CAM_REQ_CMP) {
448 				return;
449 			}
450 			SLIST_INIT(&tptr->atios);
451 			SLIST_INIT(&tptr->inots);
452 			av = 1;
453 			s = splcam();
454 			av = isp_control(isp, ISPCTL_TOGGLE_TMODE, &av);
455 			if (av) {
456 				ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
457 				xpt_free_path(tptr->owner);
458 				splx(s);
459 				return;
460 			}
461 			isp->isp_osinfo.tmflags |= TM_TMODE_ENABLED;
462 			splx(s);
463 		} else {
464 			if ((isp->isp_osinfo.tmflags & TM_TMODE_ENABLED) == 0) {
465 				ccb->ccb_h.status = CAM_LUN_INVALID;
466 				return;
467 			}
468 			if (are_any_luns_enabled(isp)) {
469 				ccb->ccb_h.status = CAM_SCSI_BUSY;
470 				return;
471 			}
472 			av = 0;
473 			s = splcam();
474 			av = isp_control(isp, ISPCTL_TOGGLE_TMODE, &av);
475 			if (av) {
476 				ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
477 				splx(s);
478 				return;
479 			}
480 			isp->isp_osinfo.tmflags &= ~TM_TMODE_ENABLED;
481 			splx(s);
482 			ccb->ccb_h.status = CAM_REQ_CMP;
483 		}
484 		xpt_print_path(ccb->ccb_h.path);
485 		printf(lfmt, (cel->enable) ? "en" : "dis");
486 		return;
487 	}
488 
489 	/*
490 	 * Do some sanity checking first.
491 	 */
492 
493 	if (IS_SCSI(isp)) {
494 		if (lun < 0 || lun >= 32) {
495 			ccb->ccb_h.status = CAM_LUN_INVALID;
496 			return;
497 		}
498 		if (tgt != CAM_TARGET_WILDCARD &&
499 		    tgt != ((sdparam *) isp->isp_param)->isp_initiator_id) {
500 			ccb->ccb_h.status = CAM_TID_INVALID;
501 			return;
502 		}
503 	} else {
504 #ifdef	ISP2100_SCCLUN
505 		if (lun < 0 || lun >= 65536) {
506 			ccb->ccb_h.status = CAM_LUN_INVALID;
507 			return;
508 		}
509 #else
510 		if (lun < 0 || lun >= 16) {
511 			ccb->ccb_h.status = CAM_LUN_INVALID;
512 			return;
513 		}
514 #endif
515 		if (tgt != CAM_TARGET_WILDCARD &&
516 		    tgt != ((fcparam *) isp->isp_param)->isp_loopid) {
517 			ccb->ccb_h.status = CAM_TID_INVALID;
518 			return;
519 		}
520 	}
521 
522 
523 	if (cel->enable) {
524 		ccb->ccb_h.status =
525 		    create_lun_state(isp, ccb->ccb_h.path, &tptr);
526 		if (ccb->ccb_h.status != CAM_REQ_CMP) {
527 			return;
528 		}
529 	} else {
530 		tptr = get_lun_statep(isp, lun);
531 		if (tptr == NULL) {
532 			ccb->ccb_h.status = CAM_LUN_INVALID;
533 			return;
534 		}
535 	}
536 
537 	if (isp_psema_sig_rqe(isp)) {
538 		rls_lun_statep(isp, tptr);
539 		if (cel->enable)
540 			destroy_lun_state(isp, tptr);
541 		ccb->ccb_h.status = CAM_REQ_CMP_ERR;
542 		return;
543 	}
544 
545 	s = splcam();
546 	if (cel->enable) {
547 		u_int32_t seq = isp->isp_osinfo.rollinfo++;
548 		rstat = LUN_ERR;
549 		if (isp_lun_cmd(isp, RQSTYPE_ENABLE_LUN, bus, tgt, lun, seq)) {
550 			xpt_print_path(ccb->ccb_h.path);
551 			printf("isp_lun_cmd failed\n");
552 			goto out;
553 		}
554 		if (isp_cv_wait_timed_rqe(isp, 30 * hz)) {
555 			xpt_print_path(ccb->ccb_h.path);
556 			printf("wait for ENABLE LUN timed out\n");
557 			goto out;
558 		}
559 		rstat = isp->isp_osinfo.rstatus;
560 		if (rstat != LUN_OK) {
561 			xpt_print_path(ccb->ccb_h.path);
562 			printf("ENABLE LUN returned 0x%x\n", rstat);
563 			goto out;
564 		}
565 	} else {
566 		u_int32_t seq;
567 
568 		seq = isp->isp_osinfo.rollinfo++;
569 		rstat = LUN_ERR;
570 
571 		if (isp_lun_cmd(isp, -RQSTYPE_MODIFY_LUN, bus, tgt, lun, seq)) {
572 			xpt_print_path(ccb->ccb_h.path);
573 			printf("isp_lun_cmd failed\n");
574 			goto out;
575 		}
576 		if (isp_cv_wait_timed_rqe(isp, 30 * hz)) {
577 			xpt_print_path(ccb->ccb_h.path);
578 			printf("wait for MODIFY LUN timed out\n");
579 			goto out;
580 		}
581 		rstat = isp->isp_osinfo.rstatus;
582 		if (rstat != LUN_OK) {
583 			xpt_print_path(ccb->ccb_h.path);
584 			printf("MODIFY LUN returned 0x%x\n", rstat);
585 			goto out;
586 		}
587 		rstat = LUN_ERR;
588 		seq = isp->isp_osinfo.rollinfo++;
589 
590 		if (isp_lun_cmd(isp, -RQSTYPE_ENABLE_LUN, bus, tgt, lun, seq)) {
591 			xpt_print_path(ccb->ccb_h.path);
592 			printf("isp_lun_cmd failed\n");
593 			goto out;
594 		}
595 		if (isp_cv_wait_timed_rqe(isp, 30 * hz)) {
596 			xpt_print_path(ccb->ccb_h.path);
597 			printf("wait for ENABLE LUN timed out\n");
598 			goto out;
599 		}
600 		rstat = isp->isp_osinfo.rstatus;
601 		if (rstat != LUN_OK) {
602 			xpt_print_path(ccb->ccb_h.path);
603 			printf("ENABLE LUN returned 0x%x\n", rstat);
604 			goto out;
605 		}
606 	}
607 out:
608 	isp_vsema_rqe(isp);
609 	splx(s);
610 
611 	if (rstat != LUN_OK) {
612 		xpt_print_path(ccb->ccb_h.path);
613 		printf("lun %sable failed\n", (cel->enable) ? "en" : "dis");
614 		ccb->ccb_h.status = CAM_REQ_CMP_ERR;
615 		rls_lun_statep(isp, tptr);
616 		if (cel->enable)
617 			destroy_lun_state(isp, tptr);
618 	} else {
619 		xpt_print_path(ccb->ccb_h.path);
620 		printf(lfmt, (cel->enable) ? "en" : "dis");
621 		rls_lun_statep(isp, tptr);
622 		if (cel->enable == 0) {
623 			destroy_lun_state(isp, tptr);
624 		}
625 		ccb->ccb_h.status = CAM_REQ_CMP;
626 	}
627 }
628 
629 static cam_status
630 isp_abort_tgt_ccb(struct ispsoftc *isp, union ccb *ccb)
631 {
632 	tstate_t *tptr;
633 	struct ccb_hdr_slist *lp;
634 	struct ccb_hdr *curelm;
635 	int found;
636 	union ccb *accb = ccb->cab.abort_ccb;
637 
638 	if (accb->ccb_h.target_id != CAM_TARGET_WILDCARD) {
639 		if (IS_FC(isp) && (accb->ccb_h.target_id !=
640 		    ((fcparam *) isp->isp_param)->isp_loopid)) {
641 			return (CAM_PATH_INVALID);
642 		} else if (IS_SCSI(isp) && (accb->ccb_h.target_id !=
643 		    ((sdparam *) isp->isp_param)->isp_initiator_id)) {
644 			return (CAM_PATH_INVALID);
645 		}
646 	}
647 	tptr = get_lun_statep(isp, accb->ccb_h.target_lun);
648 	if (tptr == NULL) {
649 		return (CAM_PATH_INVALID);
650 	}
651 	if (accb->ccb_h.func_code == XPT_ACCEPT_TARGET_IO) {
652 		lp = &tptr->atios;
653 	} else if (accb->ccb_h.func_code == XPT_IMMED_NOTIFY) {
654 		lp = &tptr->inots;
655 	} else {
656 		rls_lun_statep(isp, tptr);
657 		return (CAM_UA_ABORT);
658 	}
659 	curelm = SLIST_FIRST(lp);
660 	found = 0;
661 	if (curelm == &accb->ccb_h) {
662 		found = 1;
663 		SLIST_REMOVE_HEAD(lp, sim_links.sle);
664 	} else {
665 		while(curelm != NULL) {
666 			struct ccb_hdr *nextelm;
667 
668 			nextelm = SLIST_NEXT(curelm, sim_links.sle);
669 			if (nextelm == &accb->ccb_h) {
670 				found = 1;
671 				SLIST_NEXT(curelm, sim_links.sle) =
672 				    SLIST_NEXT(nextelm, sim_links.sle);
673 				break;
674 			}
675 			curelm = nextelm;
676 		}
677 	}
678 	rls_lun_statep(isp, tptr);
679 	if (found) {
680 		accb->ccb_h.status = CAM_REQ_ABORTED;
681 		return (CAM_REQ_CMP);
682 	}
683 	return(CAM_PATH_INVALID);
684 }
685 
686 static cam_status
687 isp_target_start_ctio(struct ispsoftc *isp, union ccb *ccb)
688 {
689 	void *qe;
690 	u_int32_t *hp, save_handle;
691 	u_int16_t iptr, optr;
692 
693 	if (isp_getrqentry(isp, &iptr, &optr, &qe)) {
694 		xpt_print_path(ccb->ccb_h.path);
695 		printf("Request Queue Overflow in isp_target_start_ctio\n");
696 		return (CAM_RESRC_UNAVAIL);
697 	}
698 	bzero(qe, QENTRY_LEN);
699 
700 	/*
701 	 * We're either moving data or completing a command here.
702 	 */
703 
704 	if (IS_FC(isp)) {
705 		ct2_entry_t *cto = qe;
706 		cto->ct_header.rqs_entry_type = RQSTYPE_CTIO2;
707 		cto->ct_header.rqs_entry_count = 1;
708 		cto->ct_iid = ccb->csio.init_id;
709 #ifndef	ISP2100_SCCLUN
710 		cto->ct_lun = ccb->ccb_h.target_lun;
711 #endif
712 		cto->ct_rxid = ccb->csio.tag_id;
713 		cto->ct_flags = CT2_FLAG_MODE0 | CT2_CCINCR;
714 		if (ccb->csio.dxfer_len == 0) {
715 			cto->ct_flags |= CT2_NO_DATA;
716 		}
717 		if ((ccb->ccb_h.flags & CAM_SEND_STATUS) != 0) {
718 			cto->ct_flags |= CT2_SENDSTATUS;
719 			cto->rsp.m0.ct_scsi_status = ccb->csio.scsi_status;
720 			if (ccb->csio.resid) {
721 				cto->ct_resid = ccb->csio.resid;
722 				if (ccb->csio.resid < 0)
723 					cto->ct_flags |= CT2_DATA_OVER;
724 				else
725 					cto->ct_flags |= CT2_DATA_UNDER;
726 			}
727 			if (isp_tdebug && (ccb->csio.scsi_status !=
728 			    SCSI_STATUS_OK || ccb->csio.resid)) {
729 				printf("%s:CTIO2 RX_ID 0x%x SCSI STATUS 0x%x "
730 				    "resid %d\n", isp->isp_name, cto->ct_rxid,
731 				    ccb->csio.scsi_status, ccb->csio.resid);
732 			}
733 			/*
734 			 * If we had Sense Data already,
735 			 * here's where we'd set it up.
736 			 */
737 		}
738 		hp = &cto->ct_reserved;
739 	} else {
740 		ct_entry_t *cto = qe;
741 		cto->ct_header.rqs_entry_type = RQSTYPE_CTIO;
742 		cto->ct_header.rqs_entry_count = 1;
743 		cto->ct_iid = ccb->csio.init_id;
744 		cto->ct_tgt = ccb->ccb_h.target_id;
745 		cto->ct_lun = ccb->ccb_h.target_lun;
746 		cto->ct_tag_type = ccb->csio.tag_action;
747 		cto->ct_tag_val = ccb->csio.tag_id;
748 		cto->ct_flags = CT_CCINCR;
749 		if (ccb->csio.dxfer_len) {
750 			cto->ct_flags |= CT_NO_DATA;
751 		}
752 		if ((ccb->ccb_h.flags & CAM_SEND_STATUS) != 0) {
753 			cto->ct_flags |= CT_SENDSTATUS;
754 			cto->ct_scsi_status = ccb->csio.scsi_status;
755 			cto->ct_resid = ccb->csio.resid;
756 		}
757 		if (isp_tdebug && (ccb->csio.scsi_status !=
758 		    SCSI_STATUS_OK || ccb->csio.resid)) {
759 			printf("%s:CTIO SCSI STATUS 0x%x resid %d\n",
760 			    isp->isp_name, ccb->csio.scsi_status,
761 			    ccb->csio.resid);
762 		}
763 		hp = &cto->ct_reserved;
764 	}
765 
766 	if (isp_save_xs(isp, (ISP_SCSI_XFER_T *)ccb, hp)) {
767 		xpt_print_path(ccb->ccb_h.path);
768 		printf("No XFLIST pointers for isp_target_start_ctio\n");
769 		return (CAM_RESRC_UNAVAIL);
770 	}
771 
772 
773 	/*
774 	 * Call the dma setup routines for this entry (and any subsequent
775 	 * CTIOs) if there's data to move, and then tell the f/w it's got
776 	 * new things to play with. As with ispscsicmd's usage of DMA setup,
777 	 * any swizzling is done in the machine dependent layer. Because
778 	 * of this, we put the request onto the queue area first in native
779 	 * format.
780 	 */
781 
782 	save_handle = *hp;
783 	switch (ISP_DMASETUP(isp, &ccb->csio, qe, &iptr, optr)) {
784 	case CMD_QUEUED:
785 		MemoryBarrier();
786 		ISP_ADD_REQUEST(isp, iptr);
787 		return (CAM_REQ_INPROG);
788 
789 	case CMD_EAGAIN:
790 		ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
791 		isp_destroy_handle(isp, save_handle);
792 		return (CAM_RESRC_UNAVAIL);
793 
794 	default:
795 		isp_destroy_handle(isp, save_handle);
796 		return (ccb->ccb_h.spriv_field0);
797 	}
798 }
799 
800 /*
801  * Handle ATIO stuff that the generic code can't.
802  * This means handling CDBs.
803  */
804 
805 static int
806 isp_handle_platform_atio(struct ispsoftc *isp, at_entry_t *aep)
807 {
808 	tstate_t *tptr;
809 	int status;
810 	struct ccb_accept_tio *atiop;
811 
812 	/*
813 	 * The firmware status (except for the QLTM_SVALID bit)
814 	 * indicates why this ATIO was sent to us.
815 	 *
816 	 * If QLTM_SVALID is set, the firware has recommended Sense Data.
817 	 *
818 	 * If the DISCONNECTS DISABLED bit is set in the flags field,
819 	 * we're still connected on the SCSI bus - i.e. the initiator
820 	 * did not set DiscPriv in the identify message. We don't care
821 	 * about this so it's ignored.
822 	 */
823 	status = aep->at_status;
824 	if ((status & ~QLTM_SVALID) == AT_PHASE_ERROR) {
825 		/*
826 		 * Bus Phase Sequence error. We should have sense data
827 		 * suggested by the f/w. I'm not sure quite yet what
828 		 * to do about this for CAM.
829 		 */
830 		printf("%s: PHASE ERROR\n", isp->isp_name);
831 		isp_endcmd(isp, aep, SCSI_STATUS_BUSY, 0);
832 		return (0);
833 	}
834 	if ((status & ~QLTM_SVALID) != AT_CDB) {
835 		printf("%s: bogus atio (0x%x) leaked to platform\n",
836 		    isp->isp_name, status);
837 		isp_endcmd(isp, aep, SCSI_STATUS_BUSY, 0);
838 		return (0);
839 	}
840 
841 	tptr = get_lun_statep(isp, aep->at_lun);
842 	if (tptr == NULL) {
843 		tptr = get_lun_statep(isp, CAM_LUN_WILDCARD);
844 	}
845 
846 	if (tptr == NULL) {
847 		/*
848 		 * Because we can't autofeed sense data back with
849 		 * a command for parallel SCSI, we can't give back
850 		 * a CHECK CONDITION. We'll give back a BUSY status
851 		 * instead. This works out okay because the only
852 		 * time we should, in fact, get this, is in the
853 		 * case that somebody configured us without the
854 		 * blackhole driver, so they get what they deserve.
855 		 */
856 		isp_endcmd(isp, aep, SCSI_STATUS_BUSY, 0);
857 		return (0);
858 	}
859 
860 	atiop = (struct ccb_accept_tio *) SLIST_FIRST(&tptr->atios);
861 	if (atiop == NULL) {
862 		/*
863 		 * Because we can't autofeed sense data back with
864 		 * a command for parallel SCSI, we can't give back
865 		 * a CHECK CONDITION. We'll give back a QUEUE FULL status
866 		 * instead. This works out okay because the only time we
867 		 * should, in fact, get this, is in the case that we've
868 		 * run out of ATIOS.
869 		 */
870 		xpt_print_path(tptr->owner);
871 		printf("no ATIOS for lun %d from initiator %d\n",
872 		    aep->at_lun, aep->at_iid);
873 		rls_lun_statep(isp, tptr);
874 		if (aep->at_flags & AT_TQAE)
875 			isp_endcmd(isp, aep, SCSI_STATUS_QUEUE_FULL, 0);
876 		else
877 			isp_endcmd(isp, aep, SCSI_STATUS_BUSY, 0);
878 		return (0);
879 	}
880 	SLIST_REMOVE_HEAD(&tptr->atios, sim_links.sle);
881 	if (tptr == &isp->isp_osinfo.tsdflt) {
882 		atiop->ccb_h.target_id = aep->at_tgt;
883 		atiop->ccb_h.target_lun = aep->at_lun;
884 	}
885 	if (aep->at_flags & AT_NODISC) {
886 		xpt_print_path(tptr->owner);
887 		printf("incoming command that cannot disconnect\n");
888 	}
889 
890 
891 	atiop->init_id = aep->at_iid;
892 	atiop->cdb_len = aep->at_cdblen;
893 	MEMCPY(atiop->cdb_io.cdb_bytes, aep->at_cdb, aep->at_cdblen);
894 	atiop->ccb_h.status = CAM_CDB_RECVD;
895 	if ((atiop->tag_action = aep->at_tag_type) != 0) {
896 		atiop->tag_id = aep->at_tag_val;
897 		atiop->ccb_h.status |= CAM_TAG_ACTION_VALID;
898 	}
899 	xpt_done((union ccb*)atiop);
900 	if (isp_tdebug) {
901 		printf("%s:ATIO CDB=0x%x iid%d->lun%d tag 0x%x ttype 0x%x\n",
902 		    isp->isp_name, aep->at_cdb[0] & 0xff, aep->at_iid,
903 		    aep->at_lun, aep->at_tag_val & 0xff, aep->at_tag_type);
904 	}
905 	rls_lun_statep(isp, tptr);
906 	return (0);
907 }
908 
909 static int
910 isp_handle_platform_atio2(struct ispsoftc *isp, at2_entry_t *aep)
911 {
912 	lun_id_t lun;
913 	tstate_t *tptr;
914 	struct ccb_accept_tio *atiop;
915 
916 	/*
917 	 * The firmware status (except for the QLTM_SVALID bit)
918 	 * indicates why this ATIO was sent to us.
919 	 *
920 	 * If QLTM_SVALID is set, the firware has recommended Sense Data.
921 	 */
922 	if ((aep->at_status & ~QLTM_SVALID) != AT_CDB) {
923 		printf("%s: bogus atio (0x%x) leaked to platform\n",
924 		    isp->isp_name, aep->at_status);
925 		isp_endcmd(isp, aep, SCSI_STATUS_BUSY, 0);
926 		return (0);
927 	}
928 
929 #ifdef	ISP2100_SCCLUN
930 	lun = aep->at_scclun;
931 #else
932 	lun = aep->at_lun;
933 #endif
934 	tptr = get_lun_statep(isp, lun);
935 	if (tptr == NULL) {
936 		tptr = get_lun_statep(isp, CAM_LUN_WILDCARD);
937 	}
938 
939 	if (tptr == NULL) {
940 #if	0
941 		/* XXX WE REALLY NEED A HARDWIRED SENSE/INQ CTIO TO USE XXX */
942 		u_int32_t ccode = SCSI_STATUS_CHECK_COND | 0x100;
943 #if	NTARGBH > 0
944 		/* Not Ready, Unit Not Self-Configured yet.... */
945 		ccode |= (SSD_KEY_NOT_READY << 8) | (0x3E << 24);
946 #else
947 		/* Illegal Request, Unit Not Self-Configured yet.... */
948 		ccode |= (SSD_KEY_ILLEGAL_REQUEST << 8) | (0x25 << 24);
949 #endif
950 #else
951 		u_int32_t ccode = SCSI_STATUS_BUSY;
952 #endif
953 
954 		/*
955 		 * Because we can't autofeed sense data back with
956 		 * a command for parallel SCSI, we can't give back
957 		 * a CHECK CONDITION. We'll give back a BUSY status
958 		 * instead. This works out okay because the only
959 		 * time we should, in fact, get this, is in the
960 		 * case that somebody configured us without the
961 		 * blackhole driver, so they get what they deserve.
962 		 */
963 		isp_endcmd(isp, aep, ccode, 0);
964 		return (0);
965 	}
966 
967 	atiop = (struct ccb_accept_tio *) SLIST_FIRST(&tptr->atios);
968 	if (atiop == NULL) {
969 		/*
970 		 * Because we can't autofeed sense data back with
971 		 * a command for parallel SCSI, we can't give back
972 		 * a CHECK CONDITION. We'll give back a QUEUE FULL status
973 		 * instead. This works out okay because the only time we
974 		 * should, in fact, get this, is in the case that we've
975 		 * run out of ATIOS.
976 		 */
977 		xpt_print_path(tptr->owner);
978 		printf("no ATIOS for lun %d from initiator %d\n",
979 		    lun, aep->at_iid);
980 		rls_lun_statep(isp, tptr);
981 		if (aep->at_flags & AT_TQAE)
982 			isp_endcmd(isp, aep, SCSI_STATUS_QUEUE_FULL, 0);
983 		else
984 			isp_endcmd(isp, aep, SCSI_STATUS_BUSY, 0);
985 		return (0);
986 	}
987 	SLIST_REMOVE_HEAD(&tptr->atios, sim_links.sle);
988 	if (tptr == &isp->isp_osinfo.tsdflt) {
989 		atiop->ccb_h.target_id =
990 			((fcparam *)isp->isp_param)->isp_loopid;
991 		atiop->ccb_h.target_lun = lun;
992 	}
993 	atiop->init_id = aep->at_iid;
994 	atiop->cdb_len = ATIO2_CDBLEN;
995 	MEMCPY(atiop->cdb_io.cdb_bytes, aep->at_cdb, ATIO2_CDBLEN);
996 	atiop->ccb_h.status = CAM_CDB_RECVD;
997 	atiop->tag_id = aep->at_rxid;
998 	switch (aep->at_taskflags & ATIO2_TC_ATTR_MASK) {
999 	case ATIO2_TC_ATTR_SIMPLEQ:
1000 		atiop->tag_action = MSG_SIMPLE_Q_TAG;
1001 		break;
1002         case ATIO2_TC_ATTR_HEADOFQ:
1003 		atiop->tag_action = MSG_HEAD_OF_Q_TAG;
1004 		break;
1005         case ATIO2_TC_ATTR_ORDERED:
1006 		atiop->tag_action = MSG_ORDERED_Q_TAG;
1007 		break;
1008         case ATIO2_TC_ATTR_ACAQ:		/* ?? */
1009 	case ATIO2_TC_ATTR_UNTAGGED:
1010 	default:
1011 		atiop->tag_action = 0;
1012 		break;
1013 	}
1014 	if (atiop->tag_action != 0) {
1015 		atiop->ccb_h.status |= CAM_TAG_ACTION_VALID;
1016 	}
1017 	xpt_done((union ccb*)atiop);
1018 	if (isp_tdebug) {
1019 		printf("%s:ATIO2 RX_ID 0x%x CDB=0x%x iid%d->lun%d tattr 0x%x\n",
1020 		    isp->isp_name, aep->at_rxid & 0xffff, aep->at_cdb[0] & 0xff,
1021 		    aep->at_iid, lun, aep->at_taskflags);
1022 	}
1023 	rls_lun_statep(isp, tptr);
1024 	return (0);
1025 }
1026 
1027 static int
1028 isp_handle_platform_ctio(struct ispsoftc *isp, void * arg)
1029 {
1030 	union ccb *ccb;
1031 	int sentstatus, ok;
1032 
1033 	/*
1034 	 * CTIO and CTIO2 are close enough....
1035 	 */
1036 
1037 	ccb = (union ccb *) isp_find_xs(isp, ((ct_entry_t *)arg)->ct_reserved);
1038 	KASSERT((ccb != NULL), ("null ccb in isp_handle_platform_ctio"));
1039 	isp_destroy_handle(isp, ((ct_entry_t *)arg)->ct_reserved);
1040 
1041 	if (IS_FC(isp)) {
1042 		ct2_entry_t *ct = arg;
1043 		sentstatus = ct->ct_flags & CT2_SENDSTATUS;
1044 		ok = (ct->ct_status & ~QLTM_SVALID) == CT_OK;
1045 		if (isp_tdebug) {
1046 			printf("%s:CTIO2 RX_ID 0x%x sts 0x%x flg 0x%x FIN\n\n",
1047 			    isp->isp_name, ct->ct_rxid, ct->ct_status,
1048 			    ct->ct_flags);
1049 		}
1050 	} else {
1051 		ct_entry_t *ct = arg;
1052 		sentstatus = ct->ct_flags & CT_SENDSTATUS;
1053 		ok = (ct->ct_status  & ~QLTM_SVALID) == CT_OK;
1054 		if (isp_tdebug) {
1055 			printf("%s:CTIO tag 0x%x sts 0x%x flg 0x%x FIN\n\n",
1056 			    isp->isp_name, ct->ct_tag_val, ct->ct_status,
1057 			    ct->ct_flags);
1058 		}
1059 	}
1060 
1061 	/*
1062 	 * We're here either because data transfers are done (and
1063 	 * it's time to send a final status CTIO) or because the final
1064 	 * status CTIO is done. We don't get called for all intermediate
1065 	 * CTIOs that happen for a large data transfer.
1066 	 *
1067 	 * In any case, for this platform, the upper layers figure out
1068 	 * what to do next, so all we do here is collect status and
1069 	 * pass information along.
1070 	 */
1071 
1072 	if (sentstatus) {
1073 		/*
1074 		 * Data transfer done. See if all went okay.
1075 		 */
1076 		if (ok) {
1077 			ccb->csio.resid = 0;
1078 		} else {
1079 			ccb->csio.resid = ccb->csio.dxfer_len;
1080 		}
1081 	}
1082 
1083 
1084 	if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_INPROG) {
1085 		ccb->ccb_h.status |= CAM_REQ_CMP;
1086 	}
1087 	ccb->ccb_h.status &= ~CAM_SIM_QUEUED;
1088 	if (isp->isp_osinfo.simqfrozen & SIMQFRZ_RESOURCE) {
1089 		isp->isp_osinfo.simqfrozen &= ~SIMQFRZ_RESOURCE;
1090 		if (isp->isp_osinfo.simqfrozen == 0) {
1091 			if ((ccb->ccb_h.status & CAM_DEV_QFRZN) == 0) {
1092 				IDPRINTF(3, ("%s: isp_done -> relsimq\n",
1093 				    isp->isp_name));
1094 				ccb->ccb_h.status |= CAM_RELEASE_SIMQ;
1095 			} else {
1096 				IDPRINTF(3, ("%s: isp_done -> devq frozen\n",
1097 				    isp->isp_name));
1098 			}
1099 		} else {
1100 			IDPRINTF(3, ("%s: isp_done -> simqfrozen = %x\n",
1101 			    isp->isp_name, isp->isp_osinfo.simqfrozen));
1102 		}
1103 	}
1104 	xpt_done(ccb);
1105 	return (0);
1106 }
1107 #endif
1108 
1109 static void
1110 isp_cam_async(void *cbarg, u_int32_t code, struct cam_path *path, void *arg)
1111 {
1112 	struct cam_sim *sim;
1113 	struct ispsoftc *isp;
1114 
1115 	sim = (struct cam_sim *)cbarg;
1116 	isp = (struct ispsoftc *) cam_sim_softc(sim);
1117 	switch (code) {
1118 	case AC_LOST_DEVICE:
1119 		if (IS_SCSI(isp)) {
1120 			u_int16_t oflags, nflags;
1121 			sdparam *sdp = isp->isp_param;
1122 			int s, rvf, tgt;
1123 
1124 			tgt = xpt_path_target_id(path);
1125 			rvf = ISP_FW_REVX(isp->isp_fwrev);
1126 			s = splcam();
1127 			sdp += cam_sim_bus(sim);
1128 			isp->isp_update |= (1 << cam_sim_bus(sim));
1129 			nflags = DPARM_SAFE_DFLT;
1130 			if (rvf >= ISP_FW_REV(7, 55, 0) ||
1131 			   (ISP_FW_REV(4, 55, 0) <= rvf &&
1132 			   (rvf < ISP_FW_REV(5, 0, 0)))) {
1133 				nflags |= DPARM_NARROW | DPARM_ASYNC;
1134 			}
1135 			oflags = sdp->isp_devparam[tgt].dev_flags;
1136 			sdp->isp_devparam[tgt].dev_flags = nflags;
1137 			sdp->isp_devparam[tgt].dev_update = 1;
1138 			(void) isp_control(isp, ISPCTL_UPDATE_PARAMS, NULL);
1139 			sdp->isp_devparam[tgt].dev_flags = oflags;
1140 			(void) splx(s);
1141 		}
1142 		break;
1143 	default:
1144 		printf("%s: isp_attach Async Code 0x%x\n", isp->isp_name, code);
1145 		break;
1146 	}
1147 }
1148 
1149 static void
1150 isp_poll(struct cam_sim *sim)
1151 {
1152 	isp_intr((struct ispsoftc *) cam_sim_softc(sim));
1153 }
1154 
1155 static void
1156 isp_relsim(void *arg)
1157 {
1158 	struct ispsoftc *isp = arg;
1159 	int s = splcam();
1160 	if (isp->isp_osinfo.simqfrozen & SIMQFRZ_TIMED) {
1161 		int wasfrozen = isp->isp_osinfo.simqfrozen & SIMQFRZ_TIMED;
1162 		isp->isp_osinfo.simqfrozen &= ~SIMQFRZ_TIMED;
1163 		if (wasfrozen && isp->isp_osinfo.simqfrozen == 0) {
1164 			xpt_release_simq(isp->isp_sim, 1);
1165 			IDPRINTF(3, ("%s: timed relsimq\n", isp->isp_name));
1166 		}
1167 	}
1168 	splx(s);
1169 }
1170 
1171 static void
1172 isp_action(struct cam_sim *sim, union ccb *ccb)
1173 {
1174 	int s, bus, tgt, error;
1175 	struct ispsoftc *isp;
1176 	struct ccb_trans_settings *cts;
1177 
1178 	CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_TRACE, ("isp_action\n"));
1179 
1180 	isp = (struct ispsoftc *)cam_sim_softc(sim);
1181 	ccb->ccb_h.sim_priv.entries[0].field = 0;
1182 	ccb->ccb_h.sim_priv.entries[1].ptr = isp;
1183 	if (isp->isp_state != ISP_RUNSTATE &&
1184 	    ccb->ccb_h.func_code == XPT_SCSI_IO) {
1185 		s = splcam();
1186 		DISABLE_INTS(isp);
1187 		isp_init(isp);
1188 		if (isp->isp_state != ISP_INITSTATE) {
1189 			(void) splx(s);
1190 			/*
1191 			 * Lie. Say it was a selection timeout.
1192 			 */
1193 			ccb->ccb_h.status = CAM_SEL_TIMEOUT;
1194 			ccb->ccb_h.status |= CAM_DEV_QFRZN;
1195 			xpt_freeze_devq(ccb->ccb_h.path, 1);
1196 			xpt_done(ccb);
1197 			return;
1198 		}
1199 		isp->isp_state = ISP_RUNSTATE;
1200 		ENABLE_INTS(isp);
1201 		(void) splx(s);
1202 	}
1203 	IDPRINTF(4, ("%s: isp_action code %x\n", isp->isp_name,
1204 	    ccb->ccb_h.func_code));
1205 
1206 	switch (ccb->ccb_h.func_code) {
1207 	case XPT_SCSI_IO:	/* Execute the requested I/O operation */
1208 		/*
1209 		 * Do a couple of preliminary checks...
1210 		 */
1211 		if ((ccb->ccb_h.flags & CAM_CDB_POINTER) != 0) {
1212 			if ((ccb->ccb_h.flags & CAM_CDB_PHYS) != 0) {
1213 				ccb->ccb_h.status = CAM_REQ_INVALID;
1214 				xpt_done(ccb);
1215 				break;
1216 			}
1217 		}
1218 #ifdef	DIAGNOSTIC
1219 		if (ccb->ccb_h.target_id > (ISP_MAX_TARGETS(isp) - 1)) {
1220 			ccb->ccb_h.status = CAM_PATH_INVALID;
1221 		} else if (ccb->ccb_h.target_lun > (ISP_MAX_LUNS(isp) - 1)) {
1222 			ccb->ccb_h.status = CAM_PATH_INVALID;
1223 		}
1224 		if (ccb->ccb_h.status == CAM_PATH_INVALID) {
1225 			printf("%s: invalid tgt/lun (%d.%d) in XPT_SCSI_IO\n",
1226 			    isp->isp_name, ccb->ccb_h.target_id,
1227 			    ccb->ccb_h.target_lun);
1228 			xpt_done(ccb);
1229 			break;
1230 		}
1231 #endif
1232 		((struct ccb_scsiio *) ccb)->scsi_status = SCSI_STATUS_OK;
1233 		s = splcam();
1234 		DISABLE_INTS(isp);
1235 		error = ispscsicmd((ISP_SCSI_XFER_T *) ccb);
1236 		ENABLE_INTS(isp);
1237 		splx(s);
1238 		switch (error) {
1239 		case CMD_QUEUED:
1240 			ccb->ccb_h.status |= CAM_SIM_QUEUED;
1241 			break;
1242 		case CMD_RQLATER:
1243 			if (isp->isp_osinfo.simqfrozen == 0) {
1244 				IDPRINTF(3, ("%s: RQLATER freeze simq\n",
1245 				    isp->isp_name));
1246 				isp->isp_osinfo.simqfrozen |= SIMQFRZ_TIMED;
1247 				timeout(isp_relsim, isp, 500);
1248 				xpt_freeze_simq(sim, 1);
1249 			}
1250 			ccb->ccb_h.status &= ~CAM_STATUS_MASK;
1251                         ccb->ccb_h.status |= CAM_REQUEUE_REQ;
1252 			xpt_done(ccb);
1253 			break;
1254 		case CMD_EAGAIN:
1255 			if (isp->isp_osinfo.simqfrozen == 0) {
1256 				xpt_freeze_simq(sim, 1);
1257 				IDPRINTF(3, ("%s: EAGAIN freeze simq\n",
1258 				    isp->isp_name));
1259 			}
1260 			isp->isp_osinfo.simqfrozen |= SIMQFRZ_RESOURCE;
1261 			ccb->ccb_h.status &= ~CAM_STATUS_MASK;
1262                         ccb->ccb_h.status |= CAM_REQUEUE_REQ;
1263 			xpt_done(ccb);
1264 			break;
1265 		case CMD_COMPLETE:
1266 			isp_done((struct ccb_scsiio *) ccb);
1267 			break;
1268 		default:
1269 			printf("%s: What's this? 0x%x at %d in file %s\n",
1270 			    isp->isp_name, error, __LINE__, __FILE__);
1271 			ccb->ccb_h.status &= ~CAM_STATUS_MASK;
1272 			ccb->ccb_h.status |= CAM_REQ_CMP_ERR;
1273 			xpt_done(ccb);
1274 		}
1275 		break;
1276 
1277 #ifdef	ISP_TARGET_MODE
1278 	case XPT_EN_LUN:		/* Enable LUN as a target */
1279 		isp_en_lun(isp, ccb);
1280 		xpt_done(ccb);
1281 		break;
1282 
1283 	case XPT_NOTIFY_ACK:		/* recycle notify ack */
1284 xpt_print_path(ccb->ccb_h.path);
1285 printf("notify ack\n");
1286 	case XPT_IMMED_NOTIFY:		/* Add Immediate Notify Resource */
1287 	case XPT_ACCEPT_TARGET_IO:	/* Add Accept Target IO Resource */
1288 	{
1289 		tstate_t *tptr = get_lun_statep(isp, ccb->ccb_h.target_lun);
1290 		if (tptr == NULL) {
1291 			ccb->ccb_h.status = CAM_LUN_INVALID;
1292 			xpt_done(ccb);
1293 			break;
1294 		}
1295 		s = splsoftcam();
1296 		if (ccb->ccb_h.func_code == XPT_ACCEPT_TARGET_IO) {
1297 			SLIST_INSERT_HEAD(&tptr->atios,
1298 			    &ccb->ccb_h, sim_links.sle);
1299 		} else {
1300 			SLIST_INSERT_HEAD(&tptr->inots, &ccb->ccb_h,
1301 			    sim_links.sle);
1302 		}
1303 		splx(s);
1304 		rls_lun_statep(isp, tptr);
1305 		ccb->ccb_h.status = CAM_REQ_INPROG;
1306 		break;
1307 	}
1308 	case XPT_CONT_TARGET_IO:
1309 	{
1310 		s = splcam();
1311 		ccb->ccb_h.status = isp_target_start_ctio(isp, ccb);
1312 		if (ccb->ccb_h.status != CAM_REQ_INPROG) {
1313 			if (isp->isp_osinfo.simqfrozen == 0) {
1314 				xpt_freeze_simq(sim, 1);
1315 				xpt_print_path(ccb->ccb_h.path);
1316 				printf("XPT_CONT_TARGET_IO freeze simq\n");
1317 			}
1318 			isp->isp_osinfo.simqfrozen |= SIMQFRZ_RESOURCE;
1319 			ccb->ccb_h.status &= ~CAM_STATUS_MASK;
1320                         ccb->ccb_h.status |= CAM_REQUEUE_REQ;
1321 			xpt_done(ccb);
1322 		} else {
1323 			ccb->ccb_h.status |= CAM_SIM_QUEUED;
1324 		}
1325 		splx(s);
1326 		break;
1327 	}
1328 #endif
1329 	case XPT_RESET_DEV:		/* BDR the specified SCSI device */
1330 
1331 		bus = cam_sim_bus(xpt_path_sim(ccb->ccb_h.path));
1332 		tgt = ccb->ccb_h.target_id;
1333 		tgt |= (bus << 16);
1334 
1335 		s = splcam();
1336 		error = isp_control(isp, ISPCTL_RESET_DEV, &tgt);
1337 		(void) splx(s);
1338 		if (error) {
1339 			ccb->ccb_h.status = CAM_REQ_CMP_ERR;
1340 		} else {
1341 			ccb->ccb_h.status = CAM_REQ_CMP;
1342 		}
1343 		xpt_done(ccb);
1344 		break;
1345 	case XPT_ABORT:			/* Abort the specified CCB */
1346 	{
1347 		union ccb *accb = ccb->cab.abort_ccb;
1348 		switch (accb->ccb_h.func_code) {
1349 #ifdef	ISP_TARGET_MODE
1350 		case XPT_ACCEPT_TARGET_IO:
1351 		case XPT_IMMED_NOTIFY:
1352         		ccb->ccb_h.status = isp_abort_tgt_ccb(isp, ccb);
1353 			break;
1354 		case XPT_CONT_TARGET_IO:
1355 			PRINTF("%s: cannot abort CTIOs yet\n", isp->isp_name);
1356 			ccb->ccb_h.status = CAM_UA_ABORT;
1357 			break;
1358 #endif
1359 		case XPT_SCSI_IO:
1360 			s = splcam();
1361 			error = isp_control(isp, ISPCTL_ABORT_CMD, ccb);
1362 			(void) splx(s);
1363 			if (error) {
1364 				ccb->ccb_h.status = CAM_UA_ABORT;
1365 			} else {
1366 				ccb->ccb_h.status = CAM_REQ_CMP;
1367 			}
1368 			break;
1369 		default:
1370 			ccb->ccb_h.status = CAM_REQ_INVALID;
1371 			break;
1372 		}
1373 		xpt_done(ccb);
1374 		break;
1375 	}
1376 	case XPT_SET_TRAN_SETTINGS:	/* Nexus Settings */
1377 
1378 		cts = &ccb->cts;
1379 		tgt = cts->ccb_h.target_id;
1380 		s = splcam();
1381 		if (IS_SCSI(isp)) {
1382 			sdparam *sdp = isp->isp_param;
1383 			u_int16_t *dptr;
1384 
1385 			bus = cam_sim_bus(xpt_path_sim(cts->ccb_h.path));
1386 
1387 			sdp += bus;
1388 #if	0
1389 			if (cts->flags & CCB_TRANS_CURRENT_SETTINGS)
1390 				dptr = &sdp->isp_devparam[tgt].cur_dflags;
1391 			else
1392 				dptr = &sdp->isp_devparam[tgt].dev_flags;
1393 #else
1394 			/*
1395 			 * We always update (internally) from dev_flags
1396 			 * so any request to change settings just gets
1397 			 * vectored to that location.
1398 			 */
1399 			dptr = &sdp->isp_devparam[tgt].dev_flags;
1400 #endif
1401 
1402 			/*
1403 			 * Note that these operations affect the
1404 			 * the goal flags (dev_flags)- not
1405 			 * the current state flags. Then we mark
1406 			 * things so that the next operation to
1407 			 * this HBA will cause the update to occur.
1408 			 */
1409 			if (cts->valid & CCB_TRANS_DISC_VALID) {
1410 				if ((cts->flags & CCB_TRANS_DISC_ENB) != 0) {
1411 					*dptr |= DPARM_DISC;
1412 				} else {
1413 					*dptr &= ~DPARM_DISC;
1414 				}
1415 			}
1416 			if (cts->valid & CCB_TRANS_TQ_VALID) {
1417 				if ((cts->flags & CCB_TRANS_TAG_ENB) != 0) {
1418 					*dptr |= DPARM_TQING;
1419 				} else {
1420 					*dptr &= ~DPARM_TQING;
1421 				}
1422 			}
1423 			if (cts->valid & CCB_TRANS_BUS_WIDTH_VALID) {
1424 				switch (cts->bus_width) {
1425 				case MSG_EXT_WDTR_BUS_16_BIT:
1426 					*dptr |= DPARM_WIDE;
1427 					break;
1428 				default:
1429 					*dptr &= ~DPARM_WIDE;
1430 				}
1431 			}
1432 			/*
1433 			 * Any SYNC RATE of nonzero and SYNC_OFFSET
1434 			 * of nonzero will cause us to go to the
1435 			 * selected (from NVRAM) maximum value for
1436 			 * this device. At a later point, we'll
1437 			 * allow finer control.
1438 			 */
1439 			if ((cts->valid & CCB_TRANS_SYNC_RATE_VALID) &&
1440 			    (cts->valid & CCB_TRANS_SYNC_OFFSET_VALID) &&
1441 			    (cts->sync_offset > 0)) {
1442 				*dptr |= DPARM_SYNC;
1443 			} else {
1444 				*dptr &= ~DPARM_SYNC;
1445 			}
1446 *dptr |= DPARM_SAFE_DFLT;
1447 			if (bootverbose || isp->isp_dblev >= 3)
1448 				printf("%s: %d.%d set %s period 0x%x offset "
1449 				    "0x%x flags 0x%x\n", isp->isp_name, bus,
1450 				    tgt,
1451 				    (cts->flags & CCB_TRANS_CURRENT_SETTINGS)?
1452 				    "current" : "user",
1453 				    sdp->isp_devparam[tgt].sync_period,
1454 				    sdp->isp_devparam[tgt].sync_offset,
1455 				    sdp->isp_devparam[tgt].dev_flags);
1456 			sdp->isp_devparam[tgt].dev_update = 1;
1457 			isp->isp_update |= (1 << bus);
1458 			(void) isp_control(isp, ISPCTL_UPDATE_PARAMS, NULL);
1459 		}
1460 		(void) splx(s);
1461 		ccb->ccb_h.status = CAM_REQ_CMP;
1462 		xpt_done(ccb);
1463 		break;
1464 
1465 	case XPT_GET_TRAN_SETTINGS:
1466 
1467 		cts = &ccb->cts;
1468 		tgt = cts->ccb_h.target_id;
1469 		if (IS_FC(isp)) {
1470 			/*
1471 			 * a lot of normal SCSI things don't make sense.
1472 			 */
1473 			cts->flags = CCB_TRANS_TAG_ENB | CCB_TRANS_DISC_ENB;
1474 			cts->valid = CCB_TRANS_DISC_VALID | CCB_TRANS_TQ_VALID;
1475 			/*
1476 			 * How do you measure the width of a high
1477 			 * speed serial bus? Well, in bytes.
1478 			 *
1479 			 * Offset and period make no sense, though, so we set
1480 			 * (above) a 'base' transfer speed to be gigabit.
1481 			 */
1482 			cts->bus_width = MSG_EXT_WDTR_BUS_8_BIT;
1483 		} else {
1484 			sdparam *sdp = isp->isp_param;
1485 			u_int16_t dval, pval, oval;
1486 			int bus = cam_sim_bus(xpt_path_sim(cts->ccb_h.path));
1487 
1488 			sdp += bus;
1489 			if (cts->flags & CCB_TRANS_CURRENT_SETTINGS) {
1490 				s = splcam();
1491 				/*
1492 				 * First do a refresh to see if things
1493 				 * have changed recently!
1494 				 */
1495 				sdp->isp_devparam[tgt].dev_refresh = 1;
1496 				isp->isp_update |= (1 << bus);
1497 				(void) isp_control(isp, ISPCTL_UPDATE_PARAMS,
1498 				    NULL);
1499 				(void) splx(s);
1500 				dval = sdp->isp_devparam[tgt].cur_dflags;
1501 				oval = sdp->isp_devparam[tgt].cur_offset;
1502 				pval = sdp->isp_devparam[tgt].cur_period;
1503 			} else {
1504 				dval = sdp->isp_devparam[tgt].dev_flags;
1505 				oval = sdp->isp_devparam[tgt].sync_offset;
1506 				pval = sdp->isp_devparam[tgt].sync_period;
1507 			}
1508 
1509 			s = splcam();
1510 			cts->flags &= ~(CCB_TRANS_DISC_ENB|CCB_TRANS_TAG_ENB);
1511 
1512 			if (dval & DPARM_DISC) {
1513 				cts->flags |= CCB_TRANS_DISC_ENB;
1514 			}
1515 			if (dval & DPARM_TQING) {
1516 				cts->flags |= CCB_TRANS_TAG_ENB;
1517 			}
1518 			if (dval & DPARM_WIDE) {
1519 				cts->bus_width = MSG_EXT_WDTR_BUS_16_BIT;
1520 			} else {
1521 				cts->bus_width = MSG_EXT_WDTR_BUS_8_BIT;
1522 			}
1523 			cts->valid = CCB_TRANS_BUS_WIDTH_VALID |
1524 			    CCB_TRANS_DISC_VALID | CCB_TRANS_TQ_VALID;
1525 
1526 			if ((dval & DPARM_SYNC) && oval != 0) {
1527 				cts->sync_period = pval;
1528 				cts->sync_offset = oval;
1529 				cts->valid |=
1530 				    CCB_TRANS_SYNC_RATE_VALID |
1531 				    CCB_TRANS_SYNC_OFFSET_VALID;
1532 			}
1533 			splx(s);
1534 			if (bootverbose || isp->isp_dblev >= 3)
1535 				printf("%s: %d.%d get %s period 0x%x offset "
1536 				    "0x%x flags 0x%x\n", isp->isp_name, bus,
1537 				    tgt,
1538 			    	    (cts->flags & CCB_TRANS_CURRENT_SETTINGS)?
1539 				    "current" : "user", pval, oval, dval);
1540 		}
1541 		ccb->ccb_h.status = CAM_REQ_CMP;
1542 		xpt_done(ccb);
1543 		break;
1544 
1545 	case XPT_CALC_GEOMETRY:
1546 	{
1547 		struct ccb_calc_geometry *ccg;
1548 		u_int32_t secs_per_cylinder;
1549 		u_int32_t size_mb;
1550 
1551 		ccg = &ccb->ccg;
1552 		if (ccg->block_size == 0) {
1553 			printf("%s: %d.%d XPT_CALC_GEOMETRY block size 0?\n",
1554 				isp->isp_name, ccg->ccb_h.target_id,
1555 				ccg->ccb_h.target_lun);
1556 			ccb->ccb_h.status = CAM_REQ_INVALID;
1557 			xpt_done(ccb);
1558 			break;
1559 		}
1560 		size_mb = ccg->volume_size /((1024L * 1024L) / ccg->block_size);
1561 		if (size_mb > 1024) {
1562 			ccg->heads = 255;
1563 			ccg->secs_per_track = 63;
1564 		} else {
1565 			ccg->heads = 64;
1566 			ccg->secs_per_track = 32;
1567 		}
1568 		secs_per_cylinder = ccg->heads * ccg->secs_per_track;
1569 		ccg->cylinders = ccg->volume_size / secs_per_cylinder;
1570 		ccb->ccb_h.status = CAM_REQ_CMP;
1571 		xpt_done(ccb);
1572 		break;
1573 	}
1574 	case XPT_RESET_BUS:		/* Reset the specified bus */
1575 		bus = cam_sim_bus(sim);
1576 		s = splcam();
1577 		error = isp_control(isp, ISPCTL_RESET_BUS, &bus);
1578 		(void) splx(s);
1579 		if (error)
1580 			ccb->ccb_h.status = CAM_REQ_CMP_ERR;
1581 		else {
1582 			if (cam_sim_bus(sim) && isp->isp_path2 != NULL)
1583 				xpt_async(AC_BUS_RESET, isp->isp_path2, NULL);
1584 			else if (isp->isp_path != NULL)
1585 				xpt_async(AC_BUS_RESET, isp->isp_path, NULL);
1586 			ccb->ccb_h.status = CAM_REQ_CMP;
1587 		}
1588 		xpt_done(ccb);
1589 		break;
1590 
1591 	case XPT_TERM_IO:		/* Terminate the I/O process */
1592 		/* Does this need to be implemented? */
1593 		ccb->ccb_h.status = CAM_REQ_INVALID;
1594 		xpt_done(ccb);
1595 		break;
1596 
1597 	case XPT_PATH_INQ:		/* Path routing inquiry */
1598 	{
1599 		struct ccb_pathinq *cpi = &ccb->cpi;
1600 
1601 		cpi->version_num = 1;
1602 #ifdef	ISP_TARGET_MODE
1603 		cpi->target_sprt = PIT_PROCESSOR | PIT_DISCONNECT | PIT_TERM_IO;
1604 #else
1605 		cpi->target_sprt = 0;
1606 #endif
1607 		cpi->hba_eng_cnt = 0;
1608 		cpi->max_target = ISP_MAX_TARGETS(isp) - 1;
1609 		cpi->max_lun = ISP_MAX_LUNS(isp) - 1;
1610 		cpi->bus_id = cam_sim_bus(sim);
1611 		if (IS_FC(isp)) {
1612 			cpi->hba_misc = PIM_NOBUSRESET;
1613 			/*
1614 			 * Because our loop ID can shift from time to time,
1615 			 * make our initiator ID out of range of our bus.
1616 			 */
1617 			cpi->initiator_id = cpi->max_target + 1;
1618 
1619 			/*
1620 			 * Set base transfer capabilities for Fibre Channel.
1621 			 * Technically not correct because we don't know
1622 			 * what media we're running on top of- but we'll
1623 			 * look good if we always say 100MB/s.
1624 			 */
1625 			cpi->base_transfer_speed = 100000;
1626 			cpi->hba_inquiry = PI_TAG_ABLE;
1627 		} else {
1628 			sdparam *sdp = isp->isp_param;
1629 			sdp += cam_sim_bus(xpt_path_sim(cpi->ccb_h.path));
1630 			cpi->hba_inquiry = PI_SDTR_ABLE|PI_TAG_ABLE|PI_WIDE_16;
1631 			cpi->hba_misc = 0;
1632 			cpi->initiator_id = sdp->isp_initiator_id;
1633 			cpi->base_transfer_speed = 3300;
1634 		}
1635 		strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN);
1636 		strncpy(cpi->hba_vid, "Qlogic", HBA_IDLEN);
1637 		strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN);
1638 		cpi->unit_number = cam_sim_unit(sim);
1639 		cpi->ccb_h.status = CAM_REQ_CMP;
1640 		xpt_done(ccb);
1641 		break;
1642 	}
1643 	default:
1644 		ccb->ccb_h.status = CAM_REQ_INVALID;
1645 		xpt_done(ccb);
1646 		break;
1647 	}
1648 }
1649 
1650 #define	ISPDDB	(CAM_DEBUG_INFO|CAM_DEBUG_TRACE|CAM_DEBUG_CDB)
1651 void
1652 isp_done(struct ccb_scsiio *sccb)
1653 {
1654 	struct ispsoftc *isp = XS_ISP(sccb);
1655 
1656 	if (XS_NOERR(sccb))
1657 		XS_SETERR(sccb, CAM_REQ_CMP);
1658 	sccb->ccb_h.status &= ~CAM_STATUS_MASK;
1659 	sccb->ccb_h.status |= sccb->ccb_h.spriv_field0;
1660 	if ((sccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP &&
1661 	    (sccb->scsi_status != SCSI_STATUS_OK)) {
1662 		sccb->ccb_h.status &= ~CAM_STATUS_MASK;
1663 		if ((sccb->scsi_status == SCSI_STATUS_CHECK_COND) &&
1664 		    (sccb->ccb_h.status & CAM_AUTOSNS_VALID) == 0) {
1665 			sccb->ccb_h.status |= CAM_AUTOSENSE_FAIL;
1666 		} else {
1667 			sccb->ccb_h.status |= CAM_SCSI_STATUS_ERROR;
1668 		}
1669 	}
1670 	sccb->ccb_h.status &= ~CAM_SIM_QUEUED;
1671 	if ((sccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1672 		if ((sccb->ccb_h.status & CAM_DEV_QFRZN) == 0) {
1673 			sccb->ccb_h.status |= CAM_DEV_QFRZN;
1674 			xpt_freeze_devq(sccb->ccb_h.path, 1);
1675 			if (sccb->scsi_status != SCSI_STATUS_OK)
1676 				IDPRINTF(3, ("%s: fdevq %d.%d %x %x\n",
1677 				    isp->isp_name, sccb->ccb_h.target_id,
1678 				    sccb->ccb_h.target_lun, sccb->ccb_h.status,
1679 				    sccb->scsi_status));
1680 		}
1681 	}
1682 	/*
1683 	 * If we were frozen waiting resources, clear that we were frozen
1684 	 * waiting for resources. If we are no longer frozen, and the devq
1685 	 * isn't frozen, mark the completing CCB to have the XPT layer
1686 	 * release the simq.
1687 	 */
1688 	if (isp->isp_osinfo.simqfrozen & SIMQFRZ_RESOURCE) {
1689 		isp->isp_osinfo.simqfrozen &= ~SIMQFRZ_RESOURCE;
1690 		if (isp->isp_osinfo.simqfrozen == 0) {
1691 			if ((sccb->ccb_h.status & CAM_DEV_QFRZN) == 0) {
1692 				IDPRINTF(3, ("%s: isp_done -> relsimq\n",
1693 				    isp->isp_name));
1694 				sccb->ccb_h.status |= CAM_RELEASE_SIMQ;
1695 			} else {
1696 				IDPRINTF(3, ("%s: isp_done -> devq frozen\n",
1697 				    isp->isp_name));
1698 			}
1699 		} else {
1700 			IDPRINTF(3, ("%s: isp_done -> simqfrozen = %x\n",
1701 			    isp->isp_name, isp->isp_osinfo.simqfrozen));
1702 		}
1703 	}
1704 	if (CAM_DEBUGGED(sccb->ccb_h.path, ISPDDB) &&
1705 	    (sccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1706 		xpt_print_path(sccb->ccb_h.path);
1707 		printf("cam completion status 0x%x\n", sccb->ccb_h.status);
1708 	}
1709 	xpt_done((union ccb *) sccb);
1710 }
1711 
1712 int
1713 isp_async(struct ispsoftc *isp, ispasync_t cmd, void *arg)
1714 {
1715 	int bus, rv = 0;
1716 	switch (cmd) {
1717 	case ISPASYNC_NEW_TGT_PARAMS:
1718 	{
1719 		int flags, tgt;
1720 		sdparam *sdp = isp->isp_param;
1721 		struct ccb_trans_settings neg;
1722 		struct cam_path *tmppath;
1723 
1724 		tgt = *((int *)arg);
1725 		bus = (tgt >> 16) & 0xffff;
1726 		tgt &= 0xffff;
1727 		sdp += bus;
1728 		if (xpt_create_path(&tmppath, NULL,
1729 		    cam_sim_path(bus? isp->isp_sim2 : isp->isp_sim),
1730 		    tgt, CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
1731 			xpt_print_path(isp->isp_path);
1732 			printf("isp_async cannot make temp path for "
1733 			    "target %d bus %d\n", tgt, bus);
1734 			rv = -1;
1735 			break;
1736 		}
1737 		flags = sdp->isp_devparam[tgt].cur_dflags;
1738 		neg.valid = CCB_TRANS_DISC_VALID | CCB_TRANS_TQ_VALID;
1739 		if (flags & DPARM_DISC) {
1740 			neg.flags |= CCB_TRANS_DISC_ENB;
1741 		}
1742 		if (flags & DPARM_TQING) {
1743 			neg.flags |= CCB_TRANS_TAG_ENB;
1744 		}
1745 		neg.valid |= CCB_TRANS_BUS_WIDTH_VALID;
1746 		neg.bus_width = (flags & DPARM_WIDE)?
1747 		    MSG_EXT_WDTR_BUS_8_BIT : MSG_EXT_WDTR_BUS_16_BIT;
1748 		neg.sync_period = sdp->isp_devparam[tgt].cur_period;
1749 		neg.sync_offset = sdp->isp_devparam[tgt].cur_offset;
1750 		if (flags & DPARM_SYNC) {
1751 			neg.valid |=
1752 			    CCB_TRANS_SYNC_RATE_VALID |
1753 			    CCB_TRANS_SYNC_OFFSET_VALID;
1754 		}
1755 		IDPRINTF(3, ("%s: NEW_TGT_PARAMS bus %d tgt %d period "
1756 		    "0x%x offset 0x%x flags 0x%x\n", isp->isp_name,
1757 		    bus, tgt, neg.sync_period, neg.sync_offset, flags));
1758 		xpt_setup_ccb(&neg.ccb_h, tmppath, 1);
1759 		xpt_async(AC_TRANSFER_NEG, tmppath, &neg);
1760 		xpt_free_path(tmppath);
1761 		break;
1762 	}
1763 	case ISPASYNC_BUS_RESET:
1764 		bus = *((int *)arg);
1765 		printf("%s: SCSI bus reset on bus %d detected\n",
1766 		    isp->isp_name, bus);
1767 		if (bus > 0 && isp->isp_path2) {
1768 			xpt_async(AC_BUS_RESET, isp->isp_path2, NULL);
1769 		} else if (isp->isp_path) {
1770 			xpt_async(AC_BUS_RESET, isp->isp_path, NULL);
1771 		}
1772 		break;
1773 	case ISPASYNC_LOOP_DOWN:
1774 		if (isp->isp_path) {
1775 			if (isp->isp_osinfo.simqfrozen == 0) {
1776 				IDPRINTF(3, ("%s: loop down freeze simq\n",
1777 				    isp->isp_name));
1778 				xpt_freeze_simq(isp->isp_sim, 1);
1779 			}
1780 			isp->isp_osinfo.simqfrozen |= SIMQFRZ_LOOPDOWN;
1781 		}
1782 		printf("%s: Loop DOWN\n", isp->isp_name);
1783 		break;
1784 	case ISPASYNC_LOOP_UP:
1785 		if (isp->isp_path) {
1786 			int wasfrozen =
1787 			    isp->isp_osinfo.simqfrozen & SIMQFRZ_LOOPDOWN;
1788 			isp->isp_osinfo.simqfrozen &= ~SIMQFRZ_LOOPDOWN;
1789 			if (wasfrozen && isp->isp_osinfo.simqfrozen == 0) {
1790 				xpt_release_simq(isp->isp_sim, 1);
1791 				IDPRINTF(3, ("%s: loop up release simq\n",
1792 					isp->isp_name));
1793 			}
1794 		}
1795 		printf("%s: Loop UP\n", isp->isp_name);
1796 		break;
1797 	case ISPASYNC_PDB_CHANGED:
1798 	{
1799 		const char *fmt = "%s: Target %d (Loop 0x%x) Port ID 0x%x "
1800 		    "role %s %s\n Port WWN 0x%08x%08x\n Node WWN 0x%08x%08x\n";
1801 		const static char *roles[4] = {
1802 		    "(none)", "Target", "Initiator", "Target/Initiator"
1803 		};
1804 		char *ptr;
1805 		fcparam *fcp = isp->isp_param;
1806 		int tgt = *((int *) arg);
1807 		struct lportdb *lp = &fcp->portdb[tgt];
1808 
1809 		if (lp->valid) {
1810 			ptr = "arrived";
1811 		} else {
1812 			ptr = "disappeared";
1813 		}
1814 		printf(fmt, isp->isp_name, tgt, lp->loopid, lp->portid,
1815 		    roles[lp->roles & 0x3], ptr,
1816 		    (u_int32_t) (lp->port_wwn >> 32),
1817 		    (u_int32_t) (lp->port_wwn & 0xffffffffLL),
1818 		    (u_int32_t) (lp->node_wwn >> 32),
1819 		    (u_int32_t) (lp->node_wwn & 0xffffffffLL));
1820 		break;
1821 	}
1822 	case ISPASYNC_CHANGE_NOTIFY:
1823 		printf("%s: Name Server Database Changed\n", isp->isp_name);
1824 		break;
1825 #ifdef	ISP2100_FABRIC
1826 	case ISPASYNC_FABRIC_DEV:
1827 	{
1828 		int target;
1829 		struct lportdb *lp;
1830 		sns_scrsp_t *resp = (sns_scrsp_t *) arg;
1831 		u_int32_t portid;
1832 		u_int64_t wwn;
1833 		fcparam *fcp = isp->isp_param;
1834 
1835 		rv = -1;
1836 
1837 		portid =
1838 		    (((u_int32_t) resp->snscb_port_id[0]) << 16) |
1839 		    (((u_int32_t) resp->snscb_port_id[1]) << 8) |
1840 		    (((u_int32_t) resp->snscb_port_id[2]));
1841 		wwn =
1842 		    (((u_int64_t)resp->snscb_portname[0]) << 56) |
1843 		    (((u_int64_t)resp->snscb_portname[1]) << 48) |
1844 		    (((u_int64_t)resp->snscb_portname[2]) << 40) |
1845 		    (((u_int64_t)resp->snscb_portname[3]) << 32) |
1846 		    (((u_int64_t)resp->snscb_portname[4]) << 24) |
1847 		    (((u_int64_t)resp->snscb_portname[5]) << 16) |
1848 		    (((u_int64_t)resp->snscb_portname[6]) <<  8) |
1849 		    (((u_int64_t)resp->snscb_portname[7]));
1850 		printf("%s: type 0x%x@portid 0x%x 0x%08x%08x\n", isp->isp_name,
1851 		    resp->snscb_port_type, portid,
1852 		    ((u_int32_t) (wwn >> 32)), ((u_int32_t) wwn));
1853 		if (resp->snscb_port_type != 2) {
1854 			rv = 0;
1855 			break;
1856 		}
1857 		for (target = FC_SNS_ID+1; target < MAX_FC_TARG; target++) {
1858 			lp = &fcp->portdb[target];
1859 			if (lp->port_wwn == wwn)
1860 				break;
1861 		}
1862 		if (target < MAX_FC_TARG) {
1863 			rv = 0;
1864 			break;
1865 		}
1866 		for (target = FC_SNS_ID+1; target < MAX_FC_TARG; target++) {
1867 			lp = &fcp->portdb[target];
1868 			if (lp->port_wwn == 0)
1869 				break;
1870 		}
1871 		if (target == MAX_FC_TARG) {
1872 			printf("%s: no more space for fabric devices\n",
1873 			    isp->isp_name);
1874 			break;
1875 		}
1876 		lp->port_wwn = lp->node_wwn = wwn;
1877 		lp->portid = portid;
1878 		rv = 0;
1879 		break;
1880 	}
1881 #endif
1882 #ifdef	ISP_TARGET_MODE
1883 	case ISPASYNC_TARGET_MESSAGE:
1884 	{
1885 		tmd_msg_t *mp = arg;
1886 		ITDEBUG(1, ("%s: bus %d iid %d tgt %d lun %d ttype %x tval %x"
1887 		    " msg[0]=0x%x\n", isp->isp_name, mp->nt_bus, mp->nt_iid,
1888 		    mp->nt_tgt, mp->nt_lun, mp->nt_tagtype, mp->nt_tagval,
1889 		    mp->nt_msg[0]));
1890 		break;
1891 	}
1892 	case ISPASYNC_TARGET_EVENT:
1893 	{
1894 		tmd_event_t *ep = arg;
1895 		ITDEBUG(1, ("%s: bus %d event code 0x%x\n", isp->isp_name,
1896 		    ep->ev_bus, ep->ev_event));
1897 		break;
1898 	}
1899 	case ISPASYNC_TARGET_ACTION:
1900 		switch (((isphdr_t *)arg)->rqs_entry_type) {
1901 		default:
1902 			printf("%s: event 0x%x for unhandled target action\n",
1903 			    isp->isp_name, ((isphdr_t *)arg)->rqs_entry_type);
1904 			break;
1905 		case RQSTYPE_ATIO:
1906 			rv = isp_handle_platform_atio(isp, (at_entry_t *) arg);
1907 			break;
1908 		case RQSTYPE_ATIO2:
1909 			rv = isp_handle_platform_atio2(isp, (at2_entry_t *)arg);
1910 			break;
1911 		case RQSTYPE_CTIO2:
1912 		case RQSTYPE_CTIO:
1913 			rv = isp_handle_platform_ctio(isp, arg);
1914 			break;
1915 		case RQSTYPE_ENABLE_LUN:
1916 		case RQSTYPE_MODIFY_LUN:
1917 			isp_cv_signal_rqe(isp, ((lun_entry_t *)arg)->le_status);
1918 			break;
1919 		}
1920 		break;
1921 #endif
1922 	default:
1923 		PRINTF("%s: unknown isp_async event %d\n", isp->isp_name, cmd);
1924 		rv = -1;
1925 		break;
1926 	}
1927 	return (rv);
1928 }
1929 
1930 
1931 /*
1932  * Locks are held before coming here.
1933  */
1934 void
1935 isp_uninit(struct ispsoftc *isp)
1936 {
1937 	ISP_WRITE(isp, HCCR, HCCR_CMD_RESET);
1938 	DISABLE_INTS(isp);
1939 }
1940