xref: /freebsd/sys/dev/isp/isp_freebsd.c (revision daf1cffce2e07931f27c6c6998652e90df6ba87e)
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 	struct ccb_scsiio *cso = &ccb->csio;
691 	u_int32_t *hp, save_handle;
692 	u_int16_t iptr, optr;
693 
694 	if (isp_getrqentry(isp, &iptr, &optr, &qe)) {
695 		xpt_print_path(ccb->ccb_h.path);
696 		printf("Request Queue Overflow in isp_target_start_ctio\n");
697 		return (CAM_RESRC_UNAVAIL);
698 	}
699 	bzero(qe, QENTRY_LEN);
700 
701 	/*
702 	 * We're either moving data or completing a command here.
703 	 */
704 
705 	if (IS_FC(isp)) {
706 		ct2_entry_t *cto = qe;
707 		u_int16_t *ssptr = NULL;
708 
709 		cto->ct_header.rqs_entry_type = RQSTYPE_CTIO2;
710 		cto->ct_header.rqs_entry_count = 1;
711 		cto->ct_iid = cso->init_id;
712 #ifndef	ISP2100_SCCLUN
713 		cto->ct_lun = ccb->ccb_h.target_lun;
714 #endif
715 		cto->ct_rxid = cso->tag_id;
716 		cto->ct_flags = CT2_CCINCR;
717 		if (cso->dxfer_len == 0) {
718 			cto->ct_flags |= CT2_FLAG_MODE1 | CT2_NO_DATA;
719 			KASSERT(ccb->ccb_h.flags & CAM_SEND_STATUS,
720 			    ("a CTIO with no data and no status?"));
721 			cto->ct_flags |= CT2_SENDSTATUS;
722 			ssptr = &cto->rsp.m1.ct_scsi_status;
723 			*ssptr = cso->scsi_status;
724 			if ((ccb->ccb_h.flags & CAM_SEND_SENSE) != 0) {
725 				int m = min(cso->sense_len, MAXRESPLEN);
726 				bcopy(&cso->sense_data, cto->rsp.m1.ct_resp, m);
727 				cto->rsp.m1.ct_senselen = m;
728 				cto->rsp.m1.ct_scsi_status |= CT2_SNSLEN_VALID;
729 			}
730 		} else {
731 			cto->ct_flags |= CT2_FLAG_MODE0;
732 			if ((cso->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) {
733 				cto->ct_flags |= CT2_DATA_IN;
734 			} else {
735 				cto->ct_flags |= CT2_DATA_OUT;
736 			}
737 			if ((ccb->ccb_h.flags & CAM_SEND_STATUS) != 0) {
738 				ssptr = &cto->rsp.m0.ct_scsi_status;
739 				cto->ct_flags |= CT2_SENDSTATUS;
740 				cto->rsp.m0.ct_scsi_status = cso->scsi_status;
741 			}
742 			ccb->ccb_h.flags &= ~CAM_SEND_SENSE;
743 		}
744 		if (ssptr && cso->resid) {
745 			cto->ct_resid = cso->resid;
746 			if (cso->resid < 0)
747 				*ssptr |= CT2_DATA_OVER;
748 			else
749 				*ssptr |= CT2_DATA_UNDER;
750 		}
751 		if (isp_tdebug > 1 && ssptr &&
752 		    (cso->scsi_status != SCSI_STATUS_OK || cso->resid)) {
753 			printf("%s:CTIO2 RX_ID 0x%x SCSI STATUS 0x%x "
754 			    "resid %d\n", isp->isp_name, cto->ct_rxid,
755 			    cso->scsi_status, cso->resid);
756 		}
757 		hp = &cto->ct_reserved;
758 	} else {
759 		ct_entry_t *cto = qe;
760 
761 		cto->ct_header.rqs_entry_type = RQSTYPE_CTIO;
762 		cto->ct_header.rqs_entry_count = 1;
763 		cto->ct_iid = cso->init_id;
764 		cto->ct_tgt = ccb->ccb_h.target_id;
765 		cto->ct_lun = ccb->ccb_h.target_lun;
766 		cto->ct_tag_type = cso->tag_action;
767 		cto->ct_tag_val = cso->tag_id;
768 		cto->ct_flags = CT_CCINCR;
769 		if (cso->dxfer_len) {
770 			cto->ct_flags |= CT_NO_DATA;
771 		} else if ((cso->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) {
772 			cto->ct_flags |= CT_DATA_IN;
773 		} else {
774 			cto->ct_flags |= CT_DATA_OUT;
775 		}
776 		if ((ccb->ccb_h.flags & CAM_SEND_STATUS) != 0) {
777 			cto->ct_flags |= CT_SENDSTATUS;
778 			cto->ct_scsi_status = cso->scsi_status;
779 			cto->ct_resid = cso->resid;
780 		}
781 		if (isp_tdebug > 1 &&
782 		    (cso->scsi_status != SCSI_STATUS_OK || cso->resid)) {
783 			printf("%s:CTIO SCSI STATUS 0x%x resid %d\n",
784 			    isp->isp_name, cso->scsi_status, cso->resid);
785 		}
786 		hp = &cto->ct_reserved;
787 		ccb->ccb_h.flags &= ~CAM_SEND_SENSE;
788 	}
789 
790 	if (isp_save_xs(isp, (ISP_SCSI_XFER_T *)ccb, hp)) {
791 		xpt_print_path(ccb->ccb_h.path);
792 		printf("No XFLIST pointers for isp_target_start_ctio\n");
793 		return (CAM_RESRC_UNAVAIL);
794 	}
795 
796 
797 	/*
798 	 * Call the dma setup routines for this entry (and any subsequent
799 	 * CTIOs) if there's data to move, and then tell the f/w it's got
800 	 * new things to play with. As with ispscsicmd's usage of DMA setup,
801 	 * any swizzling is done in the machine dependent layer. Because
802 	 * of this, we put the request onto the queue area first in native
803 	 * format.
804 	 */
805 
806 	save_handle = *hp;
807 	switch (ISP_DMASETUP(isp, cso, qe, &iptr, optr)) {
808 	case CMD_QUEUED:
809 		MemoryBarrier();
810 		ISP_ADD_REQUEST(isp, iptr);
811 		return (CAM_REQ_INPROG);
812 
813 	case CMD_EAGAIN:
814 		ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
815 		isp_destroy_handle(isp, save_handle);
816 		return (CAM_RESRC_UNAVAIL);
817 
818 	default:
819 		isp_destroy_handle(isp, save_handle);
820 		return (ccb->ccb_h.spriv_field0);
821 	}
822 }
823 
824 /*
825  * Handle ATIO stuff that the generic code can't.
826  * This means handling CDBs.
827  */
828 
829 static int
830 isp_handle_platform_atio(struct ispsoftc *isp, at_entry_t *aep)
831 {
832 	tstate_t *tptr;
833 	int status;
834 	struct ccb_accept_tio *atiop;
835 
836 	/*
837 	 * The firmware status (except for the QLTM_SVALID bit)
838 	 * indicates why this ATIO was sent to us.
839 	 *
840 	 * If QLTM_SVALID is set, the firware has recommended Sense Data.
841 	 *
842 	 * If the DISCONNECTS DISABLED bit is set in the flags field,
843 	 * we're still connected on the SCSI bus - i.e. the initiator
844 	 * did not set DiscPriv in the identify message. We don't care
845 	 * about this so it's ignored.
846 	 */
847 	status = aep->at_status;
848 	if ((status & ~QLTM_SVALID) == AT_PHASE_ERROR) {
849 		/*
850 		 * Bus Phase Sequence error. We should have sense data
851 		 * suggested by the f/w. I'm not sure quite yet what
852 		 * to do about this for CAM.
853 		 */
854 		printf("%s: PHASE ERROR\n", isp->isp_name);
855 		isp_endcmd(isp, aep, SCSI_STATUS_BUSY, 0);
856 		return (0);
857 	}
858 	if ((status & ~QLTM_SVALID) != AT_CDB) {
859 		printf("%s: bogus atio (0x%x) leaked to platform\n",
860 		    isp->isp_name, status);
861 		isp_endcmd(isp, aep, SCSI_STATUS_BUSY, 0);
862 		return (0);
863 	}
864 
865 	tptr = get_lun_statep(isp, aep->at_lun);
866 	if (tptr == NULL) {
867 		tptr = get_lun_statep(isp, CAM_LUN_WILDCARD);
868 	}
869 
870 	if (tptr == NULL) {
871 		/*
872 		 * Because we can't autofeed sense data back with
873 		 * a command for parallel SCSI, we can't give back
874 		 * a CHECK CONDITION. We'll give back a BUSY status
875 		 * instead. This works out okay because the only
876 		 * time we should, in fact, get this, is in the
877 		 * case that somebody configured us without the
878 		 * blackhole driver, so they get what they deserve.
879 		 */
880 		isp_endcmd(isp, aep, SCSI_STATUS_BUSY, 0);
881 		return (0);
882 	}
883 
884 	atiop = (struct ccb_accept_tio *) SLIST_FIRST(&tptr->atios);
885 	if (atiop == NULL) {
886 		/*
887 		 * Because we can't autofeed sense data back with
888 		 * a command for parallel SCSI, we can't give back
889 		 * a CHECK CONDITION. We'll give back a QUEUE FULL status
890 		 * instead. This works out okay because the only time we
891 		 * should, in fact, get this, is in the case that we've
892 		 * run out of ATIOS.
893 		 */
894 		xpt_print_path(tptr->owner);
895 		printf("no ATIOS for lun %d from initiator %d\n",
896 		    aep->at_lun, aep->at_iid);
897 		rls_lun_statep(isp, tptr);
898 		if (aep->at_flags & AT_TQAE)
899 			isp_endcmd(isp, aep, SCSI_STATUS_QUEUE_FULL, 0);
900 		else
901 			isp_endcmd(isp, aep, SCSI_STATUS_BUSY, 0);
902 		return (0);
903 	}
904 	SLIST_REMOVE_HEAD(&tptr->atios, sim_links.sle);
905 	if (tptr == &isp->isp_osinfo.tsdflt) {
906 		atiop->ccb_h.target_id = aep->at_tgt;
907 		atiop->ccb_h.target_lun = aep->at_lun;
908 	}
909 	if (aep->at_flags & AT_NODISC) {
910 		xpt_print_path(tptr->owner);
911 		printf("incoming command that cannot disconnect\n");
912 	}
913 
914 
915 	atiop->init_id = aep->at_iid;
916 	atiop->cdb_len = aep->at_cdblen;
917 	MEMCPY(atiop->cdb_io.cdb_bytes, aep->at_cdb, aep->at_cdblen);
918 	atiop->ccb_h.status = CAM_CDB_RECVD;
919 	if ((atiop->tag_action = aep->at_tag_type) != 0) {
920 		atiop->tag_id = aep->at_tag_val;
921 		atiop->ccb_h.status |= CAM_TAG_ACTION_VALID;
922 	}
923 	xpt_done((union ccb*)atiop);
924 	if (isp_tdebug > 1) {
925 		printf("%s:ATIO CDB=0x%x iid%d->lun%d tag 0x%x ttype 0x%x\n",
926 		    isp->isp_name, aep->at_cdb[0] & 0xff, aep->at_iid,
927 		    aep->at_lun, aep->at_tag_val & 0xff, aep->at_tag_type);
928 	}
929 	rls_lun_statep(isp, tptr);
930 	return (0);
931 }
932 
933 static int
934 isp_handle_platform_atio2(struct ispsoftc *isp, at2_entry_t *aep)
935 {
936 	lun_id_t lun;
937 	tstate_t *tptr;
938 	struct ccb_accept_tio *atiop;
939 
940 	/*
941 	 * The firmware status (except for the QLTM_SVALID bit)
942 	 * indicates why this ATIO was sent to us.
943 	 *
944 	 * If QLTM_SVALID is set, the firware has recommended Sense Data.
945 	 */
946 	if ((aep->at_status & ~QLTM_SVALID) != AT_CDB) {
947 		printf("%s: bogus atio (0x%x) leaked to platform\n",
948 		    isp->isp_name, aep->at_status);
949 		isp_endcmd(isp, aep, SCSI_STATUS_BUSY, 0);
950 		return (0);
951 	}
952 
953 #ifdef	ISP2100_SCCLUN
954 	lun = aep->at_scclun;
955 #else
956 	lun = aep->at_lun;
957 #endif
958 	tptr = get_lun_statep(isp, lun);
959 	if (tptr == NULL) {
960 		tptr = get_lun_statep(isp, CAM_LUN_WILDCARD);
961 	}
962 
963 	if (tptr == NULL) {
964 #if	0
965 		/* XXX WE REALLY NEED A HARDWIRED SENSE/INQ CTIO TO USE XXX */
966 		u_int32_t ccode = SCSI_STATUS_CHECK_COND | ECMD_SVALID;
967 #if	NTARGBH > 0
968 		/* Not Ready, Unit Not Self-Configured yet.... */
969 		ccode |= (SSD_KEY_NOT_READY << 8) | (0x3E << 24);
970 #else
971 		/* Illegal Request, Unit Not Self-Configured yet.... */
972 		ccode |= (SSD_KEY_ILLEGAL_REQUEST << 8) | (0x25 << 24);
973 #endif
974 #else
975 		u_int32_t ccode = SCSI_STATUS_BUSY;
976 #endif
977 
978 		/*
979 		 * Because we can't autofeed sense data back with
980 		 * a command for parallel SCSI, we can't give back
981 		 * a CHECK CONDITION. We'll give back a BUSY status
982 		 * instead. This works out okay because the only
983 		 * time we should, in fact, get this, is in the
984 		 * case that somebody configured us without the
985 		 * blackhole driver, so they get what they deserve.
986 		 */
987 		isp_endcmd(isp, aep, ccode, 0);
988 		return (0);
989 	}
990 
991 	atiop = (struct ccb_accept_tio *) SLIST_FIRST(&tptr->atios);
992 	if (atiop == NULL) {
993 		/*
994 		 * Because we can't autofeed sense data back with
995 		 * a command for parallel SCSI, we can't give back
996 		 * a CHECK CONDITION. We'll give back a QUEUE FULL status
997 		 * instead. This works out okay because the only time we
998 		 * should, in fact, get this, is in the case that we've
999 		 * run out of ATIOS.
1000 		 */
1001 		xpt_print_path(tptr->owner);
1002 		printf("no ATIOS for lun %d from initiator %d\n",
1003 		    lun, aep->at_iid);
1004 		rls_lun_statep(isp, tptr);
1005 		if (aep->at_flags & AT_TQAE)
1006 			isp_endcmd(isp, aep, SCSI_STATUS_QUEUE_FULL, 0);
1007 		else
1008 			isp_endcmd(isp, aep, SCSI_STATUS_BUSY, 0);
1009 		return (0);
1010 	}
1011 	SLIST_REMOVE_HEAD(&tptr->atios, sim_links.sle);
1012 	if (tptr == &isp->isp_osinfo.tsdflt) {
1013 		atiop->ccb_h.target_id =
1014 			((fcparam *)isp->isp_param)->isp_loopid;
1015 		atiop->ccb_h.target_lun = lun;
1016 	}
1017 	atiop->init_id = aep->at_iid;
1018 	atiop->cdb_len = ATIO2_CDBLEN;
1019 	MEMCPY(atiop->cdb_io.cdb_bytes, aep->at_cdb, ATIO2_CDBLEN);
1020 	atiop->ccb_h.status = CAM_CDB_RECVD;
1021 	atiop->tag_id = aep->at_rxid;
1022 	switch (aep->at_taskflags & ATIO2_TC_ATTR_MASK) {
1023 	case ATIO2_TC_ATTR_SIMPLEQ:
1024 		atiop->tag_action = MSG_SIMPLE_Q_TAG;
1025 		break;
1026         case ATIO2_TC_ATTR_HEADOFQ:
1027 		atiop->tag_action = MSG_HEAD_OF_Q_TAG;
1028 		break;
1029         case ATIO2_TC_ATTR_ORDERED:
1030 		atiop->tag_action = MSG_ORDERED_Q_TAG;
1031 		break;
1032         case ATIO2_TC_ATTR_ACAQ:		/* ?? */
1033 	case ATIO2_TC_ATTR_UNTAGGED:
1034 	default:
1035 		atiop->tag_action = 0;
1036 		break;
1037 	}
1038 	if (atiop->tag_action != 0) {
1039 		atiop->ccb_h.status |= CAM_TAG_ACTION_VALID;
1040 	}
1041 	xpt_done((union ccb*)atiop);
1042 	if (isp_tdebug > 1) {
1043 		printf("%s:ATIO2 RX_ID 0x%x CDB=0x%x iid%d->lun%d tattr 0x%x\n",
1044 		    isp->isp_name, aep->at_rxid & 0xffff, aep->at_cdb[0] & 0xff,
1045 		    aep->at_iid, lun, aep->at_taskflags);
1046 	}
1047 	rls_lun_statep(isp, tptr);
1048 	return (0);
1049 }
1050 
1051 static int
1052 isp_handle_platform_ctio(struct ispsoftc *isp, void * arg)
1053 {
1054 	union ccb *ccb;
1055 	int sentstatus, ok;
1056 
1057 	/*
1058 	 * CTIO and CTIO2 are close enough....
1059 	 */
1060 
1061 	ccb = (union ccb *) isp_find_xs(isp, ((ct_entry_t *)arg)->ct_reserved);
1062 	KASSERT((ccb != NULL), ("null ccb in isp_handle_platform_ctio"));
1063 	isp_destroy_handle(isp, ((ct_entry_t *)arg)->ct_reserved);
1064 
1065 	if (IS_FC(isp)) {
1066 		ct2_entry_t *ct = arg;
1067 		sentstatus = ct->ct_flags & CT2_SENDSTATUS;
1068 		ok = (ct->ct_status & ~QLTM_SVALID) == CT_OK;
1069 		if (ok && ccb->ccb_h.flags & CAM_SEND_SENSE) {
1070 			ccb->ccb_h.status |= CAM_SENT_SENSE;
1071 		}
1072 		if (isp_tdebug > 1) {
1073 			printf("%s:CTIO2 RX_ID 0x%x sts 0x%x flg 0x%x sns "
1074 			    "%d FIN\n", isp->isp_name, ct->ct_rxid,
1075 			    ct->ct_status, ct->ct_flags,
1076 			    (ccb->ccb_h.status & CAM_SENT_SENSE) != 0);
1077 		}
1078 	} else {
1079 		ct_entry_t *ct = arg;
1080 		sentstatus = ct->ct_flags & CT_SENDSTATUS;
1081 		ok = (ct->ct_status  & ~QLTM_SVALID) == CT_OK;
1082 		if (isp_tdebug > 1) {
1083 			printf("%s:CTIO tag 0x%x sts 0x%x flg 0x%x FIN\n",
1084 			    isp->isp_name, ct->ct_tag_val, ct->ct_status,
1085 			    ct->ct_flags);
1086 		}
1087 	}
1088 
1089 	/*
1090 	 * We're here either because data transfers are done (and
1091 	 * it's time to send a final status CTIO) or because the final
1092 	 * status CTIO is done. We don't get called for all intermediate
1093 	 * CTIOs that happen for a large data transfer.
1094 	 *
1095 	 * In any case, for this platform, the upper layers figure out
1096 	 * what to do next, so all we do here is collect status and
1097 	 * pass information along.
1098 	 */
1099 
1100 	if (sentstatus) {
1101 		/*
1102 		 * Data transfer done. See if all went okay.
1103 		 */
1104 		if (ok) {
1105 			ccb->csio.resid = 0;
1106 		} else {
1107 			ccb->csio.resid = ccb->csio.dxfer_len;
1108 		}
1109 	}
1110 
1111 
1112 	if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_INPROG) {
1113 		ccb->ccb_h.status |= CAM_REQ_CMP;
1114 	}
1115 	ccb->ccb_h.status &= ~CAM_SIM_QUEUED;
1116 	if (isp->isp_osinfo.simqfrozen & SIMQFRZ_RESOURCE) {
1117 		isp->isp_osinfo.simqfrozen &= ~SIMQFRZ_RESOURCE;
1118 		if (isp->isp_osinfo.simqfrozen == 0) {
1119 			if ((ccb->ccb_h.status & CAM_DEV_QFRZN) == 0) {
1120 				IDPRINTF(3, ("%s: isp_done -> relsimq\n",
1121 				    isp->isp_name));
1122 				ccb->ccb_h.status |= CAM_RELEASE_SIMQ;
1123 			} else {
1124 				IDPRINTF(3, ("%s: isp_done -> devq frozen\n",
1125 				    isp->isp_name));
1126 			}
1127 		} else {
1128 			IDPRINTF(3, ("%s: isp_done -> simqfrozen = %x\n",
1129 			    isp->isp_name, isp->isp_osinfo.simqfrozen));
1130 		}
1131 	}
1132 	xpt_done(ccb);
1133 	return (0);
1134 }
1135 #endif
1136 
1137 static void
1138 isp_cam_async(void *cbarg, u_int32_t code, struct cam_path *path, void *arg)
1139 {
1140 	struct cam_sim *sim;
1141 	struct ispsoftc *isp;
1142 
1143 	sim = (struct cam_sim *)cbarg;
1144 	isp = (struct ispsoftc *) cam_sim_softc(sim);
1145 	switch (code) {
1146 	case AC_LOST_DEVICE:
1147 		if (IS_SCSI(isp)) {
1148 			u_int16_t oflags, nflags;
1149 			sdparam *sdp = isp->isp_param;
1150 			int s, rvf, tgt;
1151 
1152 			tgt = xpt_path_target_id(path);
1153 			rvf = ISP_FW_REVX(isp->isp_fwrev);
1154 			s = splcam();
1155 			sdp += cam_sim_bus(sim);
1156 			isp->isp_update |= (1 << cam_sim_bus(sim));
1157 			nflags = DPARM_SAFE_DFLT;
1158 			if (rvf >= ISP_FW_REV(7, 55, 0) ||
1159 			   (ISP_FW_REV(4, 55, 0) <= rvf &&
1160 			   (rvf < ISP_FW_REV(5, 0, 0)))) {
1161 				nflags |= DPARM_NARROW | DPARM_ASYNC;
1162 			}
1163 			oflags = sdp->isp_devparam[tgt].dev_flags;
1164 			sdp->isp_devparam[tgt].dev_flags = nflags;
1165 			sdp->isp_devparam[tgt].dev_update = 1;
1166 			(void) isp_control(isp, ISPCTL_UPDATE_PARAMS, NULL);
1167 			sdp->isp_devparam[tgt].dev_flags = oflags;
1168 			(void) splx(s);
1169 		}
1170 		break;
1171 	default:
1172 		printf("%s: isp_attach Async Code 0x%x\n", isp->isp_name, code);
1173 		break;
1174 	}
1175 }
1176 
1177 static void
1178 isp_poll(struct cam_sim *sim)
1179 {
1180 	isp_intr((struct ispsoftc *) cam_sim_softc(sim));
1181 }
1182 
1183 static void
1184 isp_relsim(void *arg)
1185 {
1186 	struct ispsoftc *isp = arg;
1187 	int s = splcam();
1188 	if (isp->isp_osinfo.simqfrozen & SIMQFRZ_TIMED) {
1189 		int wasfrozen = isp->isp_osinfo.simqfrozen & SIMQFRZ_TIMED;
1190 		isp->isp_osinfo.simqfrozen &= ~SIMQFRZ_TIMED;
1191 		if (wasfrozen && isp->isp_osinfo.simqfrozen == 0) {
1192 			xpt_release_simq(isp->isp_sim, 1);
1193 			IDPRINTF(3, ("%s: timed relsimq\n", isp->isp_name));
1194 		}
1195 	}
1196 	splx(s);
1197 }
1198 
1199 static void
1200 isp_action(struct cam_sim *sim, union ccb *ccb)
1201 {
1202 	int s, bus, tgt, error;
1203 	struct ispsoftc *isp;
1204 	struct ccb_trans_settings *cts;
1205 
1206 	CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_TRACE, ("isp_action\n"));
1207 
1208 	isp = (struct ispsoftc *)cam_sim_softc(sim);
1209 	ccb->ccb_h.sim_priv.entries[0].field = 0;
1210 	ccb->ccb_h.sim_priv.entries[1].ptr = isp;
1211 	if (isp->isp_state != ISP_RUNSTATE &&
1212 	    ccb->ccb_h.func_code == XPT_SCSI_IO) {
1213 		s = splcam();
1214 		DISABLE_INTS(isp);
1215 		isp_init(isp);
1216 		if (isp->isp_state != ISP_INITSTATE) {
1217 			(void) splx(s);
1218 			/*
1219 			 * Lie. Say it was a selection timeout.
1220 			 */
1221 			ccb->ccb_h.status = CAM_SEL_TIMEOUT;
1222 			ccb->ccb_h.status |= CAM_DEV_QFRZN;
1223 			xpt_freeze_devq(ccb->ccb_h.path, 1);
1224 			xpt_done(ccb);
1225 			return;
1226 		}
1227 		isp->isp_state = ISP_RUNSTATE;
1228 		ENABLE_INTS(isp);
1229 		(void) splx(s);
1230 	}
1231 	IDPRINTF(4, ("%s: isp_action code %x\n", isp->isp_name,
1232 	    ccb->ccb_h.func_code));
1233 
1234 	switch (ccb->ccb_h.func_code) {
1235 	case XPT_SCSI_IO:	/* Execute the requested I/O operation */
1236 		/*
1237 		 * Do a couple of preliminary checks...
1238 		 */
1239 		if ((ccb->ccb_h.flags & CAM_CDB_POINTER) != 0) {
1240 			if ((ccb->ccb_h.flags & CAM_CDB_PHYS) != 0) {
1241 				ccb->ccb_h.status = CAM_REQ_INVALID;
1242 				xpt_done(ccb);
1243 				break;
1244 			}
1245 		}
1246 #ifdef	DIAGNOSTIC
1247 		if (ccb->ccb_h.target_id > (ISP_MAX_TARGETS(isp) - 1)) {
1248 			ccb->ccb_h.status = CAM_PATH_INVALID;
1249 		} else if (ccb->ccb_h.target_lun > (ISP_MAX_LUNS(isp) - 1)) {
1250 			ccb->ccb_h.status = CAM_PATH_INVALID;
1251 		}
1252 		if (ccb->ccb_h.status == CAM_PATH_INVALID) {
1253 			printf("%s: invalid tgt/lun (%d.%d) in XPT_SCSI_IO\n",
1254 			    isp->isp_name, ccb->ccb_h.target_id,
1255 			    ccb->ccb_h.target_lun);
1256 			xpt_done(ccb);
1257 			break;
1258 		}
1259 #endif
1260 		((struct ccb_scsiio *) ccb)->scsi_status = SCSI_STATUS_OK;
1261 		s = splcam();
1262 		DISABLE_INTS(isp);
1263 		error = ispscsicmd((ISP_SCSI_XFER_T *) ccb);
1264 		ENABLE_INTS(isp);
1265 		splx(s);
1266 		switch (error) {
1267 		case CMD_QUEUED:
1268 			ccb->ccb_h.status |= CAM_SIM_QUEUED;
1269 			break;
1270 		case CMD_RQLATER:
1271 			if (isp->isp_osinfo.simqfrozen == 0) {
1272 				IDPRINTF(3, ("%s: RQLATER freeze simq\n",
1273 				    isp->isp_name));
1274 				isp->isp_osinfo.simqfrozen |= SIMQFRZ_TIMED;
1275 				timeout(isp_relsim, isp, 500);
1276 				xpt_freeze_simq(sim, 1);
1277 			}
1278 			ccb->ccb_h.status &= ~CAM_STATUS_MASK;
1279                         ccb->ccb_h.status |= CAM_REQUEUE_REQ;
1280 			xpt_done(ccb);
1281 			break;
1282 		case CMD_EAGAIN:
1283 			if (isp->isp_osinfo.simqfrozen == 0) {
1284 				xpt_freeze_simq(sim, 1);
1285 				IDPRINTF(3, ("%s: EAGAIN freeze simq\n",
1286 				    isp->isp_name));
1287 			}
1288 			isp->isp_osinfo.simqfrozen |= SIMQFRZ_RESOURCE;
1289 			ccb->ccb_h.status &= ~CAM_STATUS_MASK;
1290                         ccb->ccb_h.status |= CAM_REQUEUE_REQ;
1291 			xpt_done(ccb);
1292 			break;
1293 		case CMD_COMPLETE:
1294 			isp_done((struct ccb_scsiio *) ccb);
1295 			break;
1296 		default:
1297 			printf("%s: What's this? 0x%x at %d in file %s\n",
1298 			    isp->isp_name, error, __LINE__, __FILE__);
1299 			ccb->ccb_h.status &= ~CAM_STATUS_MASK;
1300 			ccb->ccb_h.status |= CAM_REQ_CMP_ERR;
1301 			xpt_done(ccb);
1302 		}
1303 		break;
1304 
1305 #ifdef	ISP_TARGET_MODE
1306 	case XPT_EN_LUN:		/* Enable LUN as a target */
1307 		isp_en_lun(isp, ccb);
1308 		xpt_done(ccb);
1309 		break;
1310 
1311 	case XPT_NOTIFY_ACK:		/* recycle notify ack */
1312 xpt_print_path(ccb->ccb_h.path);
1313 printf("notify ack\n");
1314 	case XPT_IMMED_NOTIFY:		/* Add Immediate Notify Resource */
1315 	case XPT_ACCEPT_TARGET_IO:	/* Add Accept Target IO Resource */
1316 	{
1317 		tstate_t *tptr = get_lun_statep(isp, ccb->ccb_h.target_lun);
1318 		if (tptr == NULL) {
1319 			ccb->ccb_h.status = CAM_LUN_INVALID;
1320 			xpt_done(ccb);
1321 			break;
1322 		}
1323 		s = splsoftcam();
1324 		if (ccb->ccb_h.func_code == XPT_ACCEPT_TARGET_IO) {
1325 			SLIST_INSERT_HEAD(&tptr->atios,
1326 			    &ccb->ccb_h, sim_links.sle);
1327 		} else {
1328 			SLIST_INSERT_HEAD(&tptr->inots, &ccb->ccb_h,
1329 			    sim_links.sle);
1330 		}
1331 		splx(s);
1332 		rls_lun_statep(isp, tptr);
1333 		ccb->ccb_h.status = CAM_REQ_INPROG;
1334 		break;
1335 	}
1336 	case XPT_CONT_TARGET_IO:
1337 	{
1338 		s = splcam();
1339 		ccb->ccb_h.status = isp_target_start_ctio(isp, ccb);
1340 		if (ccb->ccb_h.status != CAM_REQ_INPROG) {
1341 			if (isp->isp_osinfo.simqfrozen == 0) {
1342 				xpt_freeze_simq(sim, 1);
1343 				xpt_print_path(ccb->ccb_h.path);
1344 				printf("XPT_CONT_TARGET_IO freeze simq\n");
1345 			}
1346 			isp->isp_osinfo.simqfrozen |= SIMQFRZ_RESOURCE;
1347 			ccb->ccb_h.status &= ~CAM_STATUS_MASK;
1348                         ccb->ccb_h.status |= CAM_REQUEUE_REQ;
1349 			xpt_done(ccb);
1350 		} else {
1351 			ccb->ccb_h.status |= CAM_SIM_QUEUED;
1352 		}
1353 		splx(s);
1354 		break;
1355 	}
1356 #endif
1357 	case XPT_RESET_DEV:		/* BDR the specified SCSI device */
1358 
1359 		bus = cam_sim_bus(xpt_path_sim(ccb->ccb_h.path));
1360 		tgt = ccb->ccb_h.target_id;
1361 		tgt |= (bus << 16);
1362 
1363 		s = splcam();
1364 		error = isp_control(isp, ISPCTL_RESET_DEV, &tgt);
1365 		(void) splx(s);
1366 		if (error) {
1367 			ccb->ccb_h.status = CAM_REQ_CMP_ERR;
1368 		} else {
1369 			ccb->ccb_h.status = CAM_REQ_CMP;
1370 		}
1371 		xpt_done(ccb);
1372 		break;
1373 	case XPT_ABORT:			/* Abort the specified CCB */
1374 	{
1375 		union ccb *accb = ccb->cab.abort_ccb;
1376 		switch (accb->ccb_h.func_code) {
1377 #ifdef	ISP_TARGET_MODE
1378 		case XPT_ACCEPT_TARGET_IO:
1379 		case XPT_IMMED_NOTIFY:
1380         		ccb->ccb_h.status = isp_abort_tgt_ccb(isp, ccb);
1381 			break;
1382 		case XPT_CONT_TARGET_IO:
1383 			PRINTF("%s: cannot abort CTIOs yet\n", isp->isp_name);
1384 			ccb->ccb_h.status = CAM_UA_ABORT;
1385 			break;
1386 #endif
1387 		case XPT_SCSI_IO:
1388 			s = splcam();
1389 			error = isp_control(isp, ISPCTL_ABORT_CMD, ccb);
1390 			(void) splx(s);
1391 			if (error) {
1392 				ccb->ccb_h.status = CAM_UA_ABORT;
1393 			} else {
1394 				ccb->ccb_h.status = CAM_REQ_CMP;
1395 			}
1396 			break;
1397 		default:
1398 			ccb->ccb_h.status = CAM_REQ_INVALID;
1399 			break;
1400 		}
1401 		xpt_done(ccb);
1402 		break;
1403 	}
1404 	case XPT_SET_TRAN_SETTINGS:	/* Nexus Settings */
1405 
1406 		cts = &ccb->cts;
1407 		tgt = cts->ccb_h.target_id;
1408 		s = splcam();
1409 		if (IS_SCSI(isp)) {
1410 			sdparam *sdp = isp->isp_param;
1411 			u_int16_t *dptr;
1412 
1413 			bus = cam_sim_bus(xpt_path_sim(cts->ccb_h.path));
1414 
1415 			sdp += bus;
1416 #if	0
1417 			if (cts->flags & CCB_TRANS_CURRENT_SETTINGS)
1418 				dptr = &sdp->isp_devparam[tgt].cur_dflags;
1419 			else
1420 				dptr = &sdp->isp_devparam[tgt].dev_flags;
1421 #else
1422 			/*
1423 			 * We always update (internally) from dev_flags
1424 			 * so any request to change settings just gets
1425 			 * vectored to that location.
1426 			 */
1427 			dptr = &sdp->isp_devparam[tgt].dev_flags;
1428 #endif
1429 
1430 			/*
1431 			 * Note that these operations affect the
1432 			 * the goal flags (dev_flags)- not
1433 			 * the current state flags. Then we mark
1434 			 * things so that the next operation to
1435 			 * this HBA will cause the update to occur.
1436 			 */
1437 			if (cts->valid & CCB_TRANS_DISC_VALID) {
1438 				if ((cts->flags & CCB_TRANS_DISC_ENB) != 0) {
1439 					*dptr |= DPARM_DISC;
1440 				} else {
1441 					*dptr &= ~DPARM_DISC;
1442 				}
1443 			}
1444 			if (cts->valid & CCB_TRANS_TQ_VALID) {
1445 				if ((cts->flags & CCB_TRANS_TAG_ENB) != 0) {
1446 					*dptr |= DPARM_TQING;
1447 				} else {
1448 					*dptr &= ~DPARM_TQING;
1449 				}
1450 			}
1451 			if (cts->valid & CCB_TRANS_BUS_WIDTH_VALID) {
1452 				switch (cts->bus_width) {
1453 				case MSG_EXT_WDTR_BUS_16_BIT:
1454 					*dptr |= DPARM_WIDE;
1455 					break;
1456 				default:
1457 					*dptr &= ~DPARM_WIDE;
1458 				}
1459 			}
1460 			/*
1461 			 * Any SYNC RATE of nonzero and SYNC_OFFSET
1462 			 * of nonzero will cause us to go to the
1463 			 * selected (from NVRAM) maximum value for
1464 			 * this device. At a later point, we'll
1465 			 * allow finer control.
1466 			 */
1467 			if ((cts->valid & CCB_TRANS_SYNC_RATE_VALID) &&
1468 			    (cts->valid & CCB_TRANS_SYNC_OFFSET_VALID) &&
1469 			    (cts->sync_offset > 0)) {
1470 				*dptr |= DPARM_SYNC;
1471 			} else {
1472 				*dptr &= ~DPARM_SYNC;
1473 			}
1474 			*dptr |= DPARM_SAFE_DFLT;
1475 			if (bootverbose || isp->isp_dblev >= 3)
1476 				printf("%s: %d.%d set %s period 0x%x offset "
1477 				    "0x%x flags 0x%x\n", isp->isp_name, bus,
1478 				    tgt,
1479 				    (cts->flags & CCB_TRANS_CURRENT_SETTINGS)?
1480 				    "current" : "user",
1481 				    sdp->isp_devparam[tgt].sync_period,
1482 				    sdp->isp_devparam[tgt].sync_offset,
1483 				    sdp->isp_devparam[tgt].dev_flags);
1484 			sdp->isp_devparam[tgt].dev_update = 1;
1485 			isp->isp_update |= (1 << bus);
1486 		}
1487 		(void) splx(s);
1488 		ccb->ccb_h.status = CAM_REQ_CMP;
1489 		xpt_done(ccb);
1490 		break;
1491 
1492 	case XPT_GET_TRAN_SETTINGS:
1493 
1494 		cts = &ccb->cts;
1495 		tgt = cts->ccb_h.target_id;
1496 		if (IS_FC(isp)) {
1497 			/*
1498 			 * a lot of normal SCSI things don't make sense.
1499 			 */
1500 			cts->flags = CCB_TRANS_TAG_ENB | CCB_TRANS_DISC_ENB;
1501 			cts->valid = CCB_TRANS_DISC_VALID | CCB_TRANS_TQ_VALID;
1502 			/*
1503 			 * How do you measure the width of a high
1504 			 * speed serial bus? Well, in bytes.
1505 			 *
1506 			 * Offset and period make no sense, though, so we set
1507 			 * (above) a 'base' transfer speed to be gigabit.
1508 			 */
1509 			cts->bus_width = MSG_EXT_WDTR_BUS_8_BIT;
1510 		} else {
1511 			sdparam *sdp = isp->isp_param;
1512 			u_int16_t dval, pval, oval;
1513 			int bus = cam_sim_bus(xpt_path_sim(cts->ccb_h.path));
1514 
1515 			sdp += bus;
1516 			if (cts->flags & CCB_TRANS_CURRENT_SETTINGS) {
1517 				s = splcam();
1518 				sdp->isp_devparam[tgt].dev_refresh = 1;
1519 				isp->isp_update |= (1 << bus);
1520 				(void) isp_control(isp, ISPCTL_UPDATE_PARAMS,
1521 				    NULL);
1522 				(void) splx(s);
1523 				dval = sdp->isp_devparam[tgt].cur_dflags;
1524 				oval = sdp->isp_devparam[tgt].cur_offset;
1525 				pval = sdp->isp_devparam[tgt].cur_period;
1526 			} else {
1527 				dval = sdp->isp_devparam[tgt].dev_flags;
1528 				oval = sdp->isp_devparam[tgt].sync_offset;
1529 				pval = sdp->isp_devparam[tgt].sync_period;
1530 			}
1531 
1532 			s = splcam();
1533 			cts->flags &= ~(CCB_TRANS_DISC_ENB|CCB_TRANS_TAG_ENB);
1534 
1535 			if (dval & DPARM_DISC) {
1536 				cts->flags |= CCB_TRANS_DISC_ENB;
1537 			}
1538 			if (dval & DPARM_TQING) {
1539 				cts->flags |= CCB_TRANS_TAG_ENB;
1540 			}
1541 			if (dval & DPARM_WIDE) {
1542 				cts->bus_width = MSG_EXT_WDTR_BUS_16_BIT;
1543 			} else {
1544 				cts->bus_width = MSG_EXT_WDTR_BUS_8_BIT;
1545 			}
1546 			cts->valid = CCB_TRANS_BUS_WIDTH_VALID |
1547 			    CCB_TRANS_DISC_VALID | CCB_TRANS_TQ_VALID;
1548 
1549 			if ((dval & DPARM_SYNC) && oval != 0) {
1550 				cts->sync_period = pval;
1551 				cts->sync_offset = oval;
1552 				cts->valid |=
1553 				    CCB_TRANS_SYNC_RATE_VALID |
1554 				    CCB_TRANS_SYNC_OFFSET_VALID;
1555 			}
1556 			splx(s);
1557 			if (bootverbose || isp->isp_dblev >= 3)
1558 				printf("%s: %d.%d get %s period 0x%x offset "
1559 				    "0x%x flags 0x%x\n", isp->isp_name, bus,
1560 				    tgt,
1561 			    	    (cts->flags & CCB_TRANS_CURRENT_SETTINGS)?
1562 				    "current" : "user", pval, oval, dval);
1563 		}
1564 		ccb->ccb_h.status = CAM_REQ_CMP;
1565 		xpt_done(ccb);
1566 		break;
1567 
1568 	case XPT_CALC_GEOMETRY:
1569 	{
1570 		struct ccb_calc_geometry *ccg;
1571 		u_int32_t secs_per_cylinder;
1572 		u_int32_t size_mb;
1573 
1574 		ccg = &ccb->ccg;
1575 		if (ccg->block_size == 0) {
1576 			printf("%s: %d.%d XPT_CALC_GEOMETRY block size 0?\n",
1577 				isp->isp_name, ccg->ccb_h.target_id,
1578 				ccg->ccb_h.target_lun);
1579 			ccb->ccb_h.status = CAM_REQ_INVALID;
1580 			xpt_done(ccb);
1581 			break;
1582 		}
1583 		size_mb = ccg->volume_size /((1024L * 1024L) / ccg->block_size);
1584 		if (size_mb > 1024) {
1585 			ccg->heads = 255;
1586 			ccg->secs_per_track = 63;
1587 		} else {
1588 			ccg->heads = 64;
1589 			ccg->secs_per_track = 32;
1590 		}
1591 		secs_per_cylinder = ccg->heads * ccg->secs_per_track;
1592 		ccg->cylinders = ccg->volume_size / secs_per_cylinder;
1593 		ccb->ccb_h.status = CAM_REQ_CMP;
1594 		xpt_done(ccb);
1595 		break;
1596 	}
1597 	case XPT_RESET_BUS:		/* Reset the specified bus */
1598 		bus = cam_sim_bus(sim);
1599 		s = splcam();
1600 		error = isp_control(isp, ISPCTL_RESET_BUS, &bus);
1601 		(void) splx(s);
1602 		if (error)
1603 			ccb->ccb_h.status = CAM_REQ_CMP_ERR;
1604 		else {
1605 			if (cam_sim_bus(sim) && isp->isp_path2 != NULL)
1606 				xpt_async(AC_BUS_RESET, isp->isp_path2, NULL);
1607 			else if (isp->isp_path != NULL)
1608 				xpt_async(AC_BUS_RESET, isp->isp_path, NULL);
1609 			ccb->ccb_h.status = CAM_REQ_CMP;
1610 		}
1611 		xpt_done(ccb);
1612 		break;
1613 
1614 	case XPT_TERM_IO:		/* Terminate the I/O process */
1615 		/* Does this need to be implemented? */
1616 		ccb->ccb_h.status = CAM_REQ_INVALID;
1617 		xpt_done(ccb);
1618 		break;
1619 
1620 	case XPT_PATH_INQ:		/* Path routing inquiry */
1621 	{
1622 		struct ccb_pathinq *cpi = &ccb->cpi;
1623 
1624 		cpi->version_num = 1;
1625 #ifdef	ISP_TARGET_MODE
1626 		cpi->target_sprt = PIT_PROCESSOR | PIT_DISCONNECT | PIT_TERM_IO;
1627 #else
1628 		cpi->target_sprt = 0;
1629 #endif
1630 		cpi->hba_eng_cnt = 0;
1631 		cpi->max_target = ISP_MAX_TARGETS(isp) - 1;
1632 		cpi->max_lun = ISP_MAX_LUNS(isp) - 1;
1633 		cpi->bus_id = cam_sim_bus(sim);
1634 		if (IS_FC(isp)) {
1635 			cpi->hba_misc = PIM_NOBUSRESET;
1636 			/*
1637 			 * Because our loop ID can shift from time to time,
1638 			 * make our initiator ID out of range of our bus.
1639 			 */
1640 			cpi->initiator_id = cpi->max_target + 1;
1641 
1642 			/*
1643 			 * Set base transfer capabilities for Fibre Channel.
1644 			 * Technically not correct because we don't know
1645 			 * what media we're running on top of- but we'll
1646 			 * look good if we always say 100MB/s.
1647 			 */
1648 			cpi->base_transfer_speed = 100000;
1649 			cpi->hba_inquiry = PI_TAG_ABLE;
1650 		} else {
1651 			sdparam *sdp = isp->isp_param;
1652 			sdp += cam_sim_bus(xpt_path_sim(cpi->ccb_h.path));
1653 			cpi->hba_inquiry = PI_SDTR_ABLE|PI_TAG_ABLE|PI_WIDE_16;
1654 			cpi->hba_misc = 0;
1655 			cpi->initiator_id = sdp->isp_initiator_id;
1656 			cpi->base_transfer_speed = 3300;
1657 		}
1658 		strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN);
1659 		strncpy(cpi->hba_vid, "Qlogic", HBA_IDLEN);
1660 		strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN);
1661 		cpi->unit_number = cam_sim_unit(sim);
1662 		cpi->ccb_h.status = CAM_REQ_CMP;
1663 		xpt_done(ccb);
1664 		break;
1665 	}
1666 	default:
1667 		ccb->ccb_h.status = CAM_REQ_INVALID;
1668 		xpt_done(ccb);
1669 		break;
1670 	}
1671 }
1672 
1673 #define	ISPDDB	(CAM_DEBUG_INFO|CAM_DEBUG_TRACE|CAM_DEBUG_CDB)
1674 void
1675 isp_done(struct ccb_scsiio *sccb)
1676 {
1677 	struct ispsoftc *isp = XS_ISP(sccb);
1678 
1679 	if (XS_NOERR(sccb))
1680 		XS_SETERR(sccb, CAM_REQ_CMP);
1681 	sccb->ccb_h.status &= ~CAM_STATUS_MASK;
1682 	sccb->ccb_h.status |= sccb->ccb_h.spriv_field0;
1683 	if ((sccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP &&
1684 	    (sccb->scsi_status != SCSI_STATUS_OK)) {
1685 		sccb->ccb_h.status &= ~CAM_STATUS_MASK;
1686 		if ((sccb->scsi_status == SCSI_STATUS_CHECK_COND) &&
1687 		    (sccb->ccb_h.status & CAM_AUTOSNS_VALID) == 0) {
1688 			sccb->ccb_h.status |= CAM_AUTOSENSE_FAIL;
1689 		} else {
1690 			sccb->ccb_h.status |= CAM_SCSI_STATUS_ERROR;
1691 		}
1692 	}
1693 	sccb->ccb_h.status &= ~CAM_SIM_QUEUED;
1694 	if ((sccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1695 		if ((sccb->ccb_h.status & CAM_DEV_QFRZN) == 0) {
1696 			sccb->ccb_h.status |= CAM_DEV_QFRZN;
1697 			xpt_freeze_devq(sccb->ccb_h.path, 1);
1698 			if (sccb->scsi_status != SCSI_STATUS_OK)
1699 				IDPRINTF(3, ("%s: fdevq %d.%d %x %x\n",
1700 				    isp->isp_name, sccb->ccb_h.target_id,
1701 				    sccb->ccb_h.target_lun, sccb->ccb_h.status,
1702 				    sccb->scsi_status));
1703 		}
1704 	}
1705 	/*
1706 	 * If we were frozen waiting resources, clear that we were frozen
1707 	 * waiting for resources. If we are no longer frozen, and the devq
1708 	 * isn't frozen, mark the completing CCB to have the XPT layer
1709 	 * release the simq.
1710 	 */
1711 	if (isp->isp_osinfo.simqfrozen & SIMQFRZ_RESOURCE) {
1712 		isp->isp_osinfo.simqfrozen &= ~SIMQFRZ_RESOURCE;
1713 		if (isp->isp_osinfo.simqfrozen == 0) {
1714 			if ((sccb->ccb_h.status & CAM_DEV_QFRZN) == 0) {
1715 				IDPRINTF(3, ("%s: isp_done -> relsimq\n",
1716 				    isp->isp_name));
1717 				sccb->ccb_h.status |= CAM_RELEASE_SIMQ;
1718 			} else {
1719 				IDPRINTF(3, ("%s: isp_done -> devq frozen\n",
1720 				    isp->isp_name));
1721 			}
1722 		} else {
1723 			IDPRINTF(3, ("%s: isp_done -> simqfrozen = %x\n",
1724 			    isp->isp_name, isp->isp_osinfo.simqfrozen));
1725 		}
1726 	}
1727 	if (CAM_DEBUGGED(sccb->ccb_h.path, ISPDDB) &&
1728 	    (sccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1729 		xpt_print_path(sccb->ccb_h.path);
1730 		printf("cam completion status 0x%x\n", sccb->ccb_h.status);
1731 	}
1732 	xpt_done((union ccb *) sccb);
1733 }
1734 
1735 int
1736 isp_async(struct ispsoftc *isp, ispasync_t cmd, void *arg)
1737 {
1738 	int bus, rv = 0;
1739 	switch (cmd) {
1740 	case ISPASYNC_NEW_TGT_PARAMS:
1741 	{
1742 		int flags, tgt;
1743 		sdparam *sdp = isp->isp_param;
1744 		struct ccb_trans_settings neg;
1745 		struct cam_path *tmppath;
1746 
1747 		tgt = *((int *)arg);
1748 		bus = (tgt >> 16) & 0xffff;
1749 		tgt &= 0xffff;
1750 		sdp += bus;
1751 		if (xpt_create_path(&tmppath, NULL,
1752 		    cam_sim_path(bus? isp->isp_sim2 : isp->isp_sim),
1753 		    tgt, CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
1754 			xpt_print_path(isp->isp_path);
1755 			printf("isp_async cannot make temp path for "
1756 			    "target %d bus %d\n", tgt, bus);
1757 			rv = -1;
1758 			break;
1759 		}
1760 		flags = sdp->isp_devparam[tgt].cur_dflags;
1761 		neg.valid = CCB_TRANS_DISC_VALID | CCB_TRANS_TQ_VALID;
1762 		if (flags & DPARM_DISC) {
1763 			neg.flags |= CCB_TRANS_DISC_ENB;
1764 		}
1765 		if (flags & DPARM_TQING) {
1766 			neg.flags |= CCB_TRANS_TAG_ENB;
1767 		}
1768 		neg.valid |= CCB_TRANS_BUS_WIDTH_VALID;
1769 		neg.bus_width = (flags & DPARM_WIDE)?
1770 		    MSG_EXT_WDTR_BUS_8_BIT : MSG_EXT_WDTR_BUS_16_BIT;
1771 		neg.sync_period = sdp->isp_devparam[tgt].cur_period;
1772 		neg.sync_offset = sdp->isp_devparam[tgt].cur_offset;
1773 		if (flags & DPARM_SYNC) {
1774 			neg.valid |=
1775 			    CCB_TRANS_SYNC_RATE_VALID |
1776 			    CCB_TRANS_SYNC_OFFSET_VALID;
1777 		}
1778 		IDPRINTF(3, ("%s: NEW_TGT_PARAMS bus %d tgt %d period "
1779 		    "0x%x offset 0x%x flags 0x%x\n", isp->isp_name,
1780 		    bus, tgt, neg.sync_period, neg.sync_offset, flags));
1781 		xpt_setup_ccb(&neg.ccb_h, tmppath, 1);
1782 		xpt_async(AC_TRANSFER_NEG, tmppath, &neg);
1783 		xpt_free_path(tmppath);
1784 		break;
1785 	}
1786 	case ISPASYNC_BUS_RESET:
1787 		bus = *((int *)arg);
1788 		printf("%s: SCSI bus reset on bus %d detected\n",
1789 		    isp->isp_name, bus);
1790 		if (bus > 0 && isp->isp_path2) {
1791 			xpt_async(AC_BUS_RESET, isp->isp_path2, NULL);
1792 		} else if (isp->isp_path) {
1793 			xpt_async(AC_BUS_RESET, isp->isp_path, NULL);
1794 		}
1795 		break;
1796 	case ISPASYNC_LOOP_DOWN:
1797 		if (isp->isp_path) {
1798 			if (isp->isp_osinfo.simqfrozen == 0) {
1799 				IDPRINTF(3, ("%s: loop down freeze simq\n",
1800 				    isp->isp_name));
1801 				xpt_freeze_simq(isp->isp_sim, 1);
1802 			}
1803 			isp->isp_osinfo.simqfrozen |= SIMQFRZ_LOOPDOWN;
1804 		}
1805 		printf("%s: Loop DOWN\n", isp->isp_name);
1806 		break;
1807 	case ISPASYNC_LOOP_UP:
1808 		if (isp->isp_path) {
1809 			int wasfrozen =
1810 			    isp->isp_osinfo.simqfrozen & SIMQFRZ_LOOPDOWN;
1811 			isp->isp_osinfo.simqfrozen &= ~SIMQFRZ_LOOPDOWN;
1812 			if (wasfrozen && isp->isp_osinfo.simqfrozen == 0) {
1813 				xpt_release_simq(isp->isp_sim, 1);
1814 				IDPRINTF(3, ("%s: loop up release simq\n",
1815 					isp->isp_name));
1816 			}
1817 		}
1818 		printf("%s: Loop UP\n", isp->isp_name);
1819 		break;
1820 	case ISPASYNC_PDB_CHANGED:
1821 	{
1822 		const char *fmt = "%s: Target %d (Loop 0x%x) Port ID 0x%x "
1823 		    "role %s %s\n Port WWN 0x%08x%08x\n Node WWN 0x%08x%08x\n";
1824 		const static char *roles[4] = {
1825 		    "(none)", "Target", "Initiator", "Target/Initiator"
1826 		};
1827 		char *ptr;
1828 		fcparam *fcp = isp->isp_param;
1829 		int tgt = *((int *) arg);
1830 		struct lportdb *lp = &fcp->portdb[tgt];
1831 
1832 		if (lp->valid) {
1833 			ptr = "arrived";
1834 		} else {
1835 			ptr = "disappeared";
1836 		}
1837 		printf(fmt, isp->isp_name, tgt, lp->loopid, lp->portid,
1838 		    roles[lp->roles & 0x3], ptr,
1839 		    (u_int32_t) (lp->port_wwn >> 32),
1840 		    (u_int32_t) (lp->port_wwn & 0xffffffffLL),
1841 		    (u_int32_t) (lp->node_wwn >> 32),
1842 		    (u_int32_t) (lp->node_wwn & 0xffffffffLL));
1843 		break;
1844 	}
1845 	case ISPASYNC_CHANGE_NOTIFY:
1846 		printf("%s: Name Server Database Changed\n", isp->isp_name);
1847 		break;
1848 #ifdef	ISP2100_FABRIC
1849 	case ISPASYNC_FABRIC_DEV:
1850 	{
1851 		int target;
1852 		struct lportdb *lp;
1853 		sns_scrsp_t *resp = (sns_scrsp_t *) arg;
1854 		u_int32_t portid;
1855 		u_int64_t wwn;
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 		wwn =
1865 		    (((u_int64_t)resp->snscb_portname[0]) << 56) |
1866 		    (((u_int64_t)resp->snscb_portname[1]) << 48) |
1867 		    (((u_int64_t)resp->snscb_portname[2]) << 40) |
1868 		    (((u_int64_t)resp->snscb_portname[3]) << 32) |
1869 		    (((u_int64_t)resp->snscb_portname[4]) << 24) |
1870 		    (((u_int64_t)resp->snscb_portname[5]) << 16) |
1871 		    (((u_int64_t)resp->snscb_portname[6]) <<  8) |
1872 		    (((u_int64_t)resp->snscb_portname[7]));
1873 		printf("%s: type 0x%x@portid 0x%x 0x%08x%08x\n", isp->isp_name,
1874 		    resp->snscb_port_type, portid,
1875 		    ((u_int32_t) (wwn >> 32)), ((u_int32_t) wwn));
1876 		if (resp->snscb_port_type != 2) {
1877 			rv = 0;
1878 			break;
1879 		}
1880 		for (target = FC_SNS_ID+1; target < MAX_FC_TARG; target++) {
1881 			lp = &fcp->portdb[target];
1882 			if (lp->port_wwn == wwn)
1883 				break;
1884 		}
1885 		if (target < MAX_FC_TARG) {
1886 			rv = 0;
1887 			break;
1888 		}
1889 		for (target = FC_SNS_ID+1; target < MAX_FC_TARG; target++) {
1890 			lp = &fcp->portdb[target];
1891 			if (lp->port_wwn == 0)
1892 				break;
1893 		}
1894 		if (target == MAX_FC_TARG) {
1895 			printf("%s: no more space for fabric devices\n",
1896 			    isp->isp_name);
1897 			break;
1898 		}
1899 		lp->port_wwn = lp->node_wwn = wwn;
1900 		lp->portid = portid;
1901 		rv = 0;
1902 		break;
1903 	}
1904 #endif
1905 #ifdef	ISP_TARGET_MODE
1906 	case ISPASYNC_TARGET_MESSAGE:
1907 	{
1908 		tmd_msg_t *mp = arg;
1909 		ITDEBUG(2, ("%s: bus %d iid %d tgt %d lun %d ttype %x tval %x"
1910 		    " msg[0]=0x%x\n", isp->isp_name, mp->nt_bus,
1911 		    (int) mp->nt_iid, (int) mp->nt_tgt, (int) mp->nt_lun,
1912 		    mp->nt_tagtype, mp->nt_tagval, mp->nt_msg[0]));
1913 		break;
1914 	}
1915 	case ISPASYNC_TARGET_EVENT:
1916 	{
1917 		tmd_event_t *ep = arg;
1918 		ITDEBUG(2, ("%s: bus %d event code 0x%x\n", isp->isp_name,
1919 		    ep->ev_bus, ep->ev_event));
1920 		break;
1921 	}
1922 	case ISPASYNC_TARGET_ACTION:
1923 		switch (((isphdr_t *)arg)->rqs_entry_type) {
1924 		default:
1925 			printf("%s: event 0x%x for unhandled target action\n",
1926 			    isp->isp_name, ((isphdr_t *)arg)->rqs_entry_type);
1927 			break;
1928 		case RQSTYPE_ATIO:
1929 			rv = isp_handle_platform_atio(isp, (at_entry_t *) arg);
1930 			break;
1931 		case RQSTYPE_ATIO2:
1932 			rv = isp_handle_platform_atio2(isp, (at2_entry_t *)arg);
1933 			break;
1934 		case RQSTYPE_CTIO2:
1935 		case RQSTYPE_CTIO:
1936 			rv = isp_handle_platform_ctio(isp, arg);
1937 			break;
1938 		case RQSTYPE_ENABLE_LUN:
1939 		case RQSTYPE_MODIFY_LUN:
1940 			isp_cv_signal_rqe(isp, ((lun_entry_t *)arg)->le_status);
1941 			break;
1942 		}
1943 		break;
1944 #endif
1945 	default:
1946 		PRINTF("%s: unknown isp_async event %d\n", isp->isp_name, cmd);
1947 		rv = -1;
1948 		break;
1949 	}
1950 	return (rv);
1951 }
1952 
1953 
1954 /*
1955  * Locks are held before coming here.
1956  */
1957 void
1958 isp_uninit(struct ispsoftc *isp)
1959 {
1960 	ISP_WRITE(isp, HCCR, HCCR_CMD_RESET);
1961 	DISABLE_INTS(isp);
1962 }
1963