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