xref: /netbsd-src/sys/dev/ic/isp_target.c (revision 404fbe5fb94ca1e054339640cabb2801ce52dd30)
1 -/* $NetBSD: isp_target.c,v 1.32 2008/06/30 00:50:30 perry Exp $ */
2 /*-
3  *  Copyright (c) 1997-2008 by Matthew Jacob
4  *  All rights reserved.
5  *
6  *  Redistribution and use in source and binary forms, with or without
7  *  modification, are permitted provided that the following conditions
8  *  are met:
9  *
10  *  1. Redistributions of source code must retain the above copyright
11  *     notice, this list of conditions and the following disclaimer.
12  *  2. Redistributions in binary form must reproduce the above copyright
13  *     notice, this list of conditions and the following disclaimer in the
14  *     documentation and/or other materials provided with the distribution.
15  *
16  *  THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17  *  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  *  ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
20  *  FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21  *  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22  *  OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23  *  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24  *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25  *  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26  *  SUCH DAMAGE.
27  *
28  *
29  *  Alternatively, this software may be distributed under the terms of the
30  *  the GNU Public License ("GPL") with platforms where the prevalant license
31  *  is the GNU Public License:
32  *
33  *   This program is free software; you can redistribute it and/or modify
34  *   it under the terms of The Version 2 GNU General Public License as published
35  *   by the Free Software Foundation.
36  *
37  *   This program is distributed in the hope that it will be useful,
38  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
39  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
40  *   GNU General Public License for more details.
41  *
42  *   You should have received a copy of the GNU General Public License
43  *   along with this program; if not, write to the Free Software
44  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
45  *
46  *
47  *  Matthew Jacob
48  *  Feral Software
49  *  421 Laurel Avenue
50  *  Menlo Park, CA 94025
51  *  USA
52  *
53  *  gplbsd at feral com
54  */
55 /*
56  * Machine and OS Independent Target Mode Code for the Qlogic SCSI/FC adapters.
57  */
58 /*
59  * Bug fixes gratefully acknowledged from:
60  *	Oded Kedem <oded@kashya.com>
61  */
62 /*
63  * Include header file appropriate for platform we're building on.
64  */
65 
66 #ifdef	__NetBSD__
67 #include <sys/cdefs.h>
68 __KERNEL_RCSID(0, "$NetBSD: isp_target.c,v 1.32 2008/06/30 00:50:30 perry Exp $");
69 #include <dev/ic/isp_netbsd.h>
70 #endif
71 #ifdef	__FreeBSD__
72 #include <sys/cdefs.h>
73 __FBSDID("$FreeBSD:$");
74 #include <dev/isp/isp_freebsd.h>
75 #endif
76 #ifdef	__OpenBSD__
77 #include <dev/ic/isp_openbsd.h>
78 #endif
79 #ifdef	__linux__
80 #include "isp_linux.h"
81 #endif
82 
83 #ifdef	ISP_TARGET_MODE
84 static const char atiocope[] =
85     "ATIO returned for lun %d because it was in the middle of Bus Device Reset "
86     "on bus %d";
87 static const char atior[] =
88     "ATIO returned on for lun %d on from loopid %d because a Bus Reset "
89     "occurred on bus %d";
90 
91 static void isp_got_msg(ispsoftc_t *, in_entry_t *);
92 static void isp_got_msg_fc(ispsoftc_t *, in_fcentry_t *);
93 static void isp_got_tmf_24xx(ispsoftc_t *, at7_entry_t *);
94 static void isp_handle_atio(ispsoftc_t *, at_entry_t *);
95 static void isp_handle_atio2(ispsoftc_t *, at2_entry_t *);
96 static void isp_handle_ctio(ispsoftc_t *, ct_entry_t *);
97 static void isp_handle_ctio2(ispsoftc_t *, ct2_entry_t *);
98 static void isp_handle_ctio7(ispsoftc_t *, ct7_entry_t *);
99 static void isp_handle_24xx_inotify(ispsoftc_t *, in_fcentry_24xx_t *);
100 
101 /*
102  * The Qlogic driver gets an interrupt to look at response queue entries.
103  * Some of these are status completions for initiatior mode commands, but
104  * if target mode is enabled, we get a whole wad of response queue entries
105  * to be handled here.
106  *
107  * Basically the split into 3 main groups: Lun Enable/Modification responses,
108  * SCSI Command processing, and Immediate Notification events.
109  *
110  * You start by writing a request queue entry to enable target mode (and
111  * establish some resource limitations which you can modify later).
112  * The f/w responds with a LUN ENABLE or LUN MODIFY response with
113  * the status of this action. If the enable was successful, you can expect...
114  *
115  * Response queue entries with SCSI commands encapsulate show up in an ATIO
116  * (Accept Target IO) type- sometimes with enough info to stop the command at
117  * this level. Ultimately the driver has to feed back to the f/w's request
118  * queue a sequence of CTIOs (continue target I/O) that describe data to
119  * be moved and/or status to be sent) and finally finishing with sending
120  * to the f/w's response queue an ATIO which then completes the handshake
121  * with the f/w for that command. There's a lot of variations on this theme,
122  * including flags you can set in the CTIO for the Qlogic 2X00 fibre channel
123  * cards that 'auto-replenish' the f/w's ATIO count, but this is the basic
124  * gist of it.
125  *
126  * The third group that can show up in the response queue are Immediate
127  * Notification events. These include things like notifications of SCSI bus
128  * resets, or Bus Device Reset messages or other messages received. This
129  * a classic oddbins area. It can get  a little weird because you then turn
130  * around and acknowledge the Immediate Notify by writing an entry onto the
131  * request queue and then the f/w turns around and gives you an acknowledgement
132  * to *your* acknowledgement on the response queue (the idea being to let
133  * the f/w tell you when the event is *really* over I guess).
134  *
135  */
136 
137 
138 /*
139  * A new response queue entry has arrived. The interrupt service code
140  * has already swizzled it into the platform dependent from canonical form.
141  *
142  * Because of the way this driver is designed, unfortunately most of the
143  * actual synchronization work has to be done in the platform specific
144  * code- we have no synchroniation primitives in the common code.
145  */
146 
147 int
148 isp_target_notify(ispsoftc_t *isp, void *vptr, uint32_t *optrp)
149 {
150 	uint16_t status;
151 	uint32_t seqid;
152 	union {
153 		at_entry_t	*atiop;
154 		at2_entry_t	*at2iop;
155 		at2e_entry_t	*at2eiop;
156 		at7_entry_t	*at7iop;
157 		ct_entry_t	*ctiop;
158 		ct2_entry_t	*ct2iop;
159 		ct2e_entry_t	*ct2eiop;
160 		ct7_entry_t	*ct7iop;
161 		lun_entry_t	*lunenp;
162 		in_entry_t	*inotp;
163 		in_fcentry_t	*inot_fcp;
164 		in_fcentry_e_t	*inote_fcp;
165 		in_fcentry_24xx_t *inot_24xx;
166 		na_entry_t	*nackp;
167 		na_fcentry_t	*nack_fcp;
168 		na_fcentry_e_t	*nacke_fcp;
169 		na_fcentry_24xx_t *nack_24xx;
170 		isphdr_t	*hp;
171 		abts_t		*abts;
172 		abts_rsp_t	*abts_rsp;
173 		els_t		*els;
174 		void *		*vp;
175 #define	atiop		unp.atiop
176 #define	at2iop		unp.at2iop
177 #define	at2eiop		unp.at2eiop
178 #define	at7iop		unp.at7iop
179 #define	ctiop		unp.ctiop
180 #define	ct2iop		unp.ct2iop
181 #define	ct2eiop		unp.ct2eiop
182 #define	ct7iop		unp.ct7iop
183 #define	lunenp		unp.lunenp
184 #define	inotp		unp.inotp
185 #define	inot_fcp	unp.inot_fcp
186 #define	inote_fcp	unp.inote_fcp
187 #define	inot_24xx	unp.inot_24xx
188 #define	nackp		unp.nackp
189 #define	nack_fcp	unp.nack_fcp
190 #define	nacke_fcp	unp.nacke_fcp
191 #define	nack_24xx	unp.nack_24xx
192 #define	abts		unp.abts
193 #define	abts_rsp	unp.abts_rsp
194 #define els		unp.els
195 #define	hdrp		unp.hp
196 	} unp;
197 	uint8_t local[QENTRY_LEN];
198 	int bus, type, level, rval = 1;
199 
200 	type = isp_get_response_type(isp, (isphdr_t *)vptr);
201 	unp.vp = vptr;
202 
203 	ISP_TDQE(isp, "isp_target_notify", (int) *optrp, vptr);
204 
205 	switch(type) {
206 	case RQSTYPE_ATIO:
207 		if (IS_24XX(isp)) {
208 			int len;
209 
210 			isp_get_atio7(isp, at7iop, (at7_entry_t *) local);
211 			at7iop = (at7_entry_t *) local;
212 			/*
213 			 * Check for and do something with commands whose IULEN
214 			 * extends past a singel queue entry.
215 			 */
216 			len = at7iop->at_ta_len & 0xfffff;
217 			if (len > (QENTRY_LEN - 8)) {
218 				len -= (QENTRY_LEN - 8);
219 				isp_prt(isp, ISP_LOGINFO,
220 				    "long IU length (%d) ignored", len);
221 				while (len > 0) {
222 					*optrp =  ISP_NXT_QENTRY(*optrp,
223 					    RESULT_QUEUE_LEN(isp));
224 					len -= QENTRY_LEN;
225 				}
226 			}
227 			/*
228 			 * Check for a task management function
229 			 */
230 			if (at7iop->at_cmnd.fcp_cmnd_task_management) {
231 				isp_got_tmf_24xx(isp, at7iop);
232 				break;
233 			}
234 			/*
235 			 * Just go straight to outer layer for this one.
236 			 */
237 			isp_async(isp, ISPASYNC_TARGET_ACTION, local);
238 		} else {
239 			isp_get_atio(isp, atiop, (at_entry_t *) local);
240 			isp_handle_atio(isp, (at_entry_t *) local);
241 		}
242 		break;
243 
244 	case RQSTYPE_CTIO:
245 		isp_get_ctio(isp, ctiop, (ct_entry_t *) local);
246 		isp_handle_ctio(isp, (ct_entry_t *) local);
247 		break;
248 
249 	case RQSTYPE_ATIO2:
250 		if (ISP_CAP_2KLOGIN(isp)) {
251 			isp_get_atio2e(isp, at2eiop, (at2e_entry_t *) local);
252 		} else {
253 			isp_get_atio2(isp, at2iop, (at2_entry_t *) local);
254 		}
255 		isp_handle_atio2(isp, (at2_entry_t *) local);
256 		break;
257 
258 	case RQSTYPE_CTIO3:
259 	case RQSTYPE_CTIO2:
260 		if (ISP_CAP_2KLOGIN(isp)) {
261 			isp_get_ctio2e(isp, ct2eiop, (ct2e_entry_t *) local);
262 		} else {
263 			isp_get_ctio2(isp, ct2iop, (ct2_entry_t *) local);
264 		}
265 		isp_handle_ctio2(isp, (ct2_entry_t *) local);
266 		break;
267 
268 	case RQSTYPE_CTIO7:
269 		isp_get_ctio7(isp, ct7iop, (ct7_entry_t *) local);
270 		isp_handle_ctio7(isp, (ct7_entry_t *) local);
271 		break;
272 
273 	case RQSTYPE_ENABLE_LUN:
274 	case RQSTYPE_MODIFY_LUN:
275 		isp_get_enable_lun(isp, lunenp, (lun_entry_t *) local);
276 		isp_async(isp, ISPASYNC_TARGET_ACTION, local);
277 		break;
278 
279 	case RQSTYPE_NOTIFY:
280 		/*
281 		 * Either the ISP received a SCSI message it can't
282 		 * handle, or it's returning an Immed. Notify entry
283 		 * we sent. We can send Immed. Notify entries to
284 		 * increment the firmware's resource count for them
285 		 * (we set this initially in the Enable Lun entry).
286 		 */
287 		bus = 0;
288 		if (IS_24XX(isp)) {
289 			isp_get_notify_24xx(isp, inot_24xx,
290 			    (in_fcentry_24xx_t *)local);
291 			inot_24xx = (in_fcentry_24xx_t *) local;
292 			isp_handle_24xx_inotify(isp, inot_24xx);
293 			break;
294 		} else if (IS_FC(isp)) {
295 			if (ISP_CAP_2KLOGIN(isp)) {
296 				isp_get_notify_fc_e(isp, inote_fcp,
297 				    (in_fcentry_e_t *)local);
298 			} else {
299 				isp_get_notify_fc(isp, inot_fcp,
300 				    (in_fcentry_t *)local);
301 			}
302 			inot_fcp = (in_fcentry_t *) local;
303 			status = inot_fcp->in_status;
304 			seqid = inot_fcp->in_seqid;
305 		} else {
306 			isp_get_notify(isp, inotp, (in_entry_t *)local);
307 			inotp = (in_entry_t *) local;
308 			status = inotp->in_status & 0xff;
309 			seqid = inotp->in_seqid;
310 			if (IS_DUALBUS(isp)) {
311 				bus = GET_BUS_VAL(inotp->in_iid);
312 				SET_BUS_VAL(inotp->in_iid, 0);
313 			}
314 		}
315 
316 		isp_prt(isp, ISP_LOGTDEBUG0,
317 		    "Immediate Notify On Bus %d, status=0x%x seqid=0x%x",
318 		    bus, status, seqid);
319 
320 		switch (status) {
321 		case IN_MSG_RECEIVED:
322 		case IN_IDE_RECEIVED:
323 			if (IS_FC(isp)) {
324 				isp_got_msg_fc(isp, (in_fcentry_t *)local);
325 			} else {
326 				isp_got_msg(isp, (in_entry_t *)local);
327 			}
328 			break;
329 		case IN_RSRC_UNAVAIL:
330 			isp_prt(isp, ISP_LOGINFO, "Firmware out of ATIOs");
331 			isp_notify_ack(isp, local);
332 			break;
333 		case IN_RESET:
334 		{
335 			/*
336 			 * We form the notify structure here because we need
337 			 * to mark it as needing a NOTIFY ACK on return.
338 			 */
339 			tmd_notify_t notify;
340 
341 			MEMZERO(&notify, sizeof (tmd_notify_t));
342 			notify.nt_hba = isp;
343 			notify.nt_iid = INI_ANY;
344 			/* nt_tgt set in outer layers */
345 			notify.nt_lun = LUN_ANY;
346 			notify.nt_tagval = TAG_ANY;
347 			notify.nt_ncode = NT_BUS_RESET;
348 			notify.nt_need_ack = 1;
349 			isp_async(isp, ISPASYNC_TARGET_NOTIFY, &notify);
350 			break;
351 		}
352 		case IN_PORT_LOGOUT:
353 		case IN_ABORT_TASK:
354 		case IN_PORT_CHANGED:
355 		case IN_GLOBAL_LOGO:
356 			isp_async(isp, ISPASYNC_TARGET_ACTION, &local);
357 			break;
358 		default:
359 			isp_prt(isp, ISP_LOGINFO,
360 			    "isp_target_notify: unknown status (0x%x)",
361 			    status);
362 			isp_notify_ack(isp, local);
363 			break;
364 		}
365 		break;
366 
367 	case RQSTYPE_NOTIFY_ACK:
368 		/*
369 		 * The ISP is acknowledging our acknowledgement of an
370 		 * Immediate Notify entry for some asynchronous event.
371 		 */
372 		if (IS_24XX(isp)) {
373 			isp_get_notify_ack_24xx(isp, nack_24xx,
374 			    (na_fcentry_24xx_t *) local);
375 			nack_24xx = (na_fcentry_24xx_t *) local;
376 			if (nack_24xx->na_status != NA_OK) {
377 				level = ISP_LOGINFO;
378 			} else {
379 				level = ISP_LOGTDEBUG1;
380 			}
381 			isp_prt(isp, level,
382 			    "Notify Ack Status=0x%x; Subcode 0x%x seqid=0x%x",
383 			    nack_24xx->na_status, nack_24xx->na_status_subcode,
384 			    nack_24xx->na_rxid);
385 		} else if (IS_FC(isp)) {
386 			if (ISP_CAP_2KLOGIN(isp)) {
387 				isp_get_notify_ack_fc_e(isp, nacke_fcp,
388 				    (na_fcentry_e_t *)local);
389 			} else {
390 				isp_get_notify_ack_fc(isp, nack_fcp,
391 				    (na_fcentry_t *)local);
392 			}
393 			nack_fcp = (na_fcentry_t *)local;
394 			if (nack_fcp->na_status != NA_OK) {
395 				level = ISP_LOGINFO;
396 			} else {
397 				level = ISP_LOGTDEBUG1;
398 			}
399 			isp_prt(isp, level,
400 			    "Notify Ack Status=0x%x seqid 0x%x",
401 			    nack_fcp->na_status, nack_fcp->na_seqid);
402 		} else {
403 			isp_get_notify_ack(isp, nackp, (na_entry_t *)local);
404 			nackp = (na_entry_t *)local;
405 			if (nackp->na_status != NA_OK) {
406 				level = ISP_LOGINFO;
407 			} else {
408 				level = ISP_LOGTDEBUG1;
409 			}
410 			isp_prt(isp, level,
411 			    "Notify Ack event 0x%x status=0x%x seqid 0x%x",
412 			    nackp->na_event, nackp->na_status, nackp->na_seqid);
413 		}
414 		break;
415 
416 	case RQSTYPE_ABTS_RCVD:
417 		isp_get_abts(isp, abts, (abts_t *)local);
418 		isp_async(isp, ISPASYNC_TARGET_ACTION, &local);
419 		break;
420 	case RQSTYPE_ABTS_RSP:
421 		isp_get_abts_rsp(isp, abts_rsp, (abts_rsp_t *)local);
422 		abts_rsp = (abts_rsp_t *) local;
423 		if (abts_rsp->abts_rsp_status) {
424 			level = ISP_LOGINFO;
425 		} else {
426 			level = ISP_LOGTDEBUG0;
427 		}
428 		isp_prt(isp, level,
429 		    "ABTS RSP response[0x%x]: status=0x%x sub=(0x%x 0x%x)",
430 		    abts_rsp->abts_rsp_rxid_task, abts_rsp->abts_rsp_status,
431 		    abts_rsp->abts_rsp_payload.rsp.subcode1,
432 		    abts_rsp->abts_rsp_payload.rsp.subcode2);
433 		break;
434 	default:
435 		isp_prt(isp, ISP_LOGERR,
436 		    "Unknown entry type 0x%x in isp_target_notify", type);
437 		rval = 0;
438 		break;
439 	}
440 #undef	atiop
441 #undef	at2iop
442 #undef	at2eiop
443 #undef	at7iop
444 #undef	ctiop
445 #undef	ct2iop
446 #undef	ct2eiop
447 #undef	ct7iop
448 #undef	lunenp
449 #undef	inotp
450 #undef	inot_fcp
451 #undef	inote_fcp
452 #undef	inot_24xx
453 #undef	nackp
454 #undef	nack_fcp
455 #undef	nacke_fcp
456 #undef	hack_24xx
457 #undef	abts
458 #undef	abts_rsp
459 #undef	els
460 #undef	hdrp
461 	return (rval);
462 }
463 
464 
465 /*
466  * Toggle (on/off) target mode for bus/target/lun.
467  *
468  * The caller has checked for overlap and legality.
469  *
470  * Note that not all of bus, target or lun can be paid attention to.
471  * Note also that this action will not be complete until the f/w writes
472  * response entry. The caller is responsible for synchronizing this.
473  */
474 int
475 isp_lun_cmd(ispsoftc_t *isp, int cmd, int bus, int lun, int cmd_cnt, int inot_cnt)
476 {
477 	lun_entry_t el;
478 	uint32_t nxti, optr;
479 	void *outp;
480 
481 
482 	MEMZERO(&el, sizeof (el));
483 	if (IS_DUALBUS(isp)) {
484 		el.le_rsvd = (bus & 0x1) << 7;
485 	}
486 	el.le_cmd_count = cmd_cnt;
487 	el.le_in_count = inot_cnt;
488 	if (cmd == RQSTYPE_ENABLE_LUN) {
489 		if (IS_SCSI(isp)) {
490 			el.le_flags = LUN_TQAE|LUN_DISAD;
491 			el.le_cdb6len = 12;
492 			el.le_cdb7len = 12;
493 		}
494 	} else if (cmd == -RQSTYPE_ENABLE_LUN) {
495 		cmd = RQSTYPE_ENABLE_LUN;
496 		el.le_cmd_count = 0;
497 		el.le_in_count = 0;
498 	} else if (cmd == -RQSTYPE_MODIFY_LUN) {
499 		cmd = RQSTYPE_MODIFY_LUN;
500 		el.le_ops = LUN_CCDECR | LUN_INDECR;
501 	} else {
502 		el.le_ops = LUN_CCINCR | LUN_ININCR;
503 	}
504 	el.le_header.rqs_entry_type = cmd;
505 	el.le_header.rqs_entry_count = 1;
506 	if (IS_SCSI(isp)) {
507 		el.le_tgt = SDPARAM(isp, bus)->isp_initiator_id;
508 		el.le_lun = lun;
509 	} else if (ISP_CAP_SCCFW(isp) == 0) {
510 		el.le_lun = lun;
511 	}
512 	el.le_timeout = 30;
513 
514 	if (isp_getrqentry(isp, &nxti, &optr, &outp)) {
515 		isp_prt(isp, ISP_LOGERR,
516 		    "Request Queue Overflow in isp_lun_cmd");
517 		return (-1);
518 	}
519 	ISP_TDQE(isp, "isp_lun_cmd", (int) optr, &el);
520 	isp_put_enable_lun(isp, &el, outp);
521 	ISP_ADD_REQUEST(isp, nxti);
522 	return (0);
523 }
524 
525 
526 int
527 isp_target_put_entry(ispsoftc_t *isp, void *ap)
528 {
529 	void *outp;
530 	uint32_t nxti, optr;
531 	uint8_t etype = ((isphdr_t *) ap)->rqs_entry_type;
532 
533 	if (isp_getrqentry(isp, &nxti, &optr, &outp)) {
534 		isp_prt(isp, ISP_LOGWARN,
535 		    "Request Queue Overflow in isp_target_put_entry");
536 		return (-1);
537 	}
538 	switch (etype) {
539 	case RQSTYPE_ATIO:
540 		isp_put_atio(isp, (at_entry_t *) ap, (at_entry_t *) outp);
541 		break;
542 	case RQSTYPE_ATIO2:
543 		if (ISP_CAP_2KLOGIN(isp)) {
544 			isp_put_atio2e(isp, (at2e_entry_t *) ap,
545 			    (at2e_entry_t *) outp);
546 		} else {
547 			isp_put_atio2(isp, (at2_entry_t *) ap,
548 			    (at2_entry_t *) outp);
549 		}
550 		break;
551 	case RQSTYPE_CTIO:
552 		isp_put_ctio(isp, (ct_entry_t *) ap, (ct_entry_t *) outp);
553 		break;
554 	case RQSTYPE_CTIO2:
555 		if (ISP_CAP_2KLOGIN(isp)) {
556 			isp_put_ctio2e(isp, (ct2e_entry_t *) ap,
557 			    (ct2e_entry_t *) outp);
558 		} else {
559 			isp_put_ctio2(isp, (ct2_entry_t *) ap,
560 			    (ct2_entry_t *) outp);
561 		}
562 		break;
563 	case RQSTYPE_CTIO7:
564 		isp_put_ctio7(isp, (ct7_entry_t *) ap, (ct7_entry_t *) outp);
565 		break;
566 	default:
567 		isp_prt(isp, ISP_LOGERR,
568 		    "Unknown type 0x%x in isp_put_entry", etype);
569 		return (-1);
570 	}
571 	ISP_TDQE(isp, "isp_target_put_entry", (int) optr, ap);
572 	ISP_ADD_REQUEST(isp, nxti);
573 	return (0);
574 }
575 
576 int
577 isp_target_put_atio(ispsoftc_t *isp, void *arg)
578 {
579 	union {
580 		at_entry_t _atio;
581 		at2_entry_t _atio2;
582 		at2e_entry_t _atio2e;
583 	} atun;
584 
585 	MEMZERO(&atun, sizeof atun);
586 	if (IS_FC(isp)) {
587 		at2_entry_t *aep = arg;
588 		atun._atio2.at_header.rqs_entry_type = RQSTYPE_ATIO2;
589 		atun._atio2.at_header.rqs_entry_count = 1;
590 		if (ISP_CAP_SCCFW(isp)) {
591 			atun._atio2.at_scclun = aep->at_scclun;
592 		} else {
593 			atun._atio2.at_lun = (uint8_t) aep->at_lun;
594 		}
595 		if (ISP_CAP_2KLOGIN(isp)) {
596 			atun._atio2e.at_iid = ((at2e_entry_t *)aep)->at_iid;
597 		} else {
598 			atun._atio2.at_iid = aep->at_iid;
599 		}
600 		atun._atio2.at_rxid = aep->at_rxid;
601 		atun._atio2.at_status = CT_OK;
602 	} else {
603 		at_entry_t *aep = arg;
604 		atun._atio.at_header.rqs_entry_type = RQSTYPE_ATIO;
605 		atun._atio.at_header.rqs_entry_count = 1;
606 		atun._atio.at_handle = aep->at_handle;
607 		atun._atio.at_iid = aep->at_iid;
608 		atun._atio.at_tgt = aep->at_tgt;
609 		atun._atio.at_lun = aep->at_lun;
610 		atun._atio.at_tag_type = aep->at_tag_type;
611 		atun._atio.at_tag_val = aep->at_tag_val;
612 		atun._atio.at_status = (aep->at_flags & AT_TQAE);
613 		atun._atio.at_status |= CT_OK;
614 	}
615 	return (isp_target_put_entry(isp, &atun));
616 }
617 
618 /*
619  * Command completion- both for handling cases of no resources or
620  * no blackhole driver, or other cases where we have to, inline,
621  * finish the command sanely, or for normal command completion.
622  *
623  * The 'completion' code value has the scsi status byte in the low 8 bits.
624  * If status is a CHECK CONDITION and bit 8 is nonzero, then bits 12..15 have
625  * the sense key and  bits 16..23 have the ASCQ and bits 24..31 have the ASC
626  * values.
627  *
628  * NB: the key, asc, ascq, cannot be used for parallel SCSI as it doesn't
629  * NB: inline SCSI sense reporting. As such, we lose this information. XXX.
630  *
631  * For both parallel && fibre channel, we use the feature that does
632  * an automatic resource autoreplenish so we don't have then later do
633  * put of an atio to replenish the f/w's resource count.
634  */
635 
636 int
637 isp_endcmd(ispsoftc_t *isp, ...)
638 {
639 	uint32_t code, hdl;
640 	uint8_t sts;
641 	union {
642 		ct_entry_t _ctio;
643 		ct2_entry_t _ctio2;
644 		ct2e_entry_t _ctio2e;
645 		ct7_entry_t _ctio7;
646 	} un;
647 	va_list ap;
648 
649 	MEMZERO(&un, sizeof un);
650 
651 	if (IS_24XX(isp)) {
652 		int vpidx, nphdl;
653 		at7_entry_t *aep;
654 		ct7_entry_t *cto = &un._ctio7;
655 
656 		va_start(ap, isp);
657 		aep = va_arg(ap, at7_entry_t *);
658 		nphdl = va_arg(ap, int);
659 		vpidx = va_arg(ap, int);
660 		code = va_arg(ap, uint32_t);
661 		hdl = va_arg(ap, uint32_t);
662 		va_end(ap);
663 
664 		sts = code;
665 		cto->ct_header.rqs_entry_type = RQSTYPE_CTIO7;
666 		cto->ct_header.rqs_entry_count = 1;
667 		cto->ct_nphdl = nphdl;
668 		cto->ct_rxid = aep->at_rxid;
669 		cto->ct_iid_lo = (aep->at_hdr.s_id[1] << 8) |
670 		    aep->at_hdr.s_id[2];
671 		cto->ct_iid_hi = aep->at_hdr.s_id[0];
672 		cto->ct_oxid = aep->at_hdr.ox_id;
673 		cto->ct_scsi_status = sts;
674 		cto->ct_vpindex = vpidx;
675 		cto->ct_flags = CT7_FLAG_MODE1 | CT7_NO_DATA | CT7_SENDSTATUS;
676 		if (sts == SCSI_CHECK && (code & ECMD_SVALID)) {
677 			cto->rsp.m1.ct_resplen = 16;
678 			cto->rsp.m1.ct_resp[0] = 0xf0;
679 			cto->rsp.m1.ct_resp[2] = (code >> 12) & 0xf;
680 			cto->rsp.m1.ct_resp[7] = 8;
681 			cto->rsp.m1.ct_resp[12] = (code >> 24) & 0xff;
682 			cto->rsp.m1.ct_resp[13] = (code >> 16) & 0xff;
683 		}
684 		if (aep->at_cmnd.cdb_dl.sf.fcp_cmnd_dl) {
685 			cto->ct_resid = aep->at_cmnd.cdb_dl.sf.fcp_cmnd_dl;
686 			cto->ct_scsi_status |= CT2_DATA_UNDER;
687 		}
688 		cto->ct_syshandle = hdl;
689 	} else if (IS_FC(isp)) {
690 		at2_entry_t *aep;
691 		ct2_entry_t *cto = &un._ctio2;
692 
693 		va_start(ap, isp);
694 		aep = va_arg(ap, at2_entry_t *);
695 		code = va_arg(ap, uint32_t);
696 		hdl = va_arg(ap, uint32_t);
697 		va_end(ap);
698 		sts = code;
699 
700 		cto->ct_header.rqs_entry_type = RQSTYPE_CTIO2;
701 		cto->ct_header.rqs_entry_count = 1;
702 		if (ISP_CAP_SCCFW(isp) == 0) {
703 			cto->ct_lun = aep->at_lun;
704 		}
705 		if (ISP_CAP_2KLOGIN(isp)) {
706 			un._ctio2e.ct_iid = ((at2e_entry_t *)aep)->at_iid;
707 		} else {
708 			cto->ct_iid = aep->at_iid;
709 		}
710 		cto->ct_rxid = aep->at_rxid;
711 		cto->rsp.m1.ct_scsi_status = sts;
712 		cto->ct_flags = CT2_SENDSTATUS | CT2_NO_DATA | CT2_FLAG_MODE1;
713 		if (hdl == 0) {
714 			cto->ct_flags |= CT2_CCINCR;
715 		}
716 		if (aep->at_datalen) {
717 			cto->ct_resid = aep->at_datalen;
718 			cto->rsp.m1.ct_scsi_status |= CT2_DATA_UNDER;
719 		}
720 		if (sts == SCSI_CHECK && (code & ECMD_SVALID)) {
721 			cto->rsp.m1.ct_resp[0] = 0xf0;
722 			cto->rsp.m1.ct_resp[2] = (code >> 12) & 0xf;
723 			cto->rsp.m1.ct_resp[7] = 8;
724 			cto->rsp.m1.ct_resp[12] = (code >> 24) & 0xff;
725 			cto->rsp.m1.ct_resp[13] = (code >> 16) & 0xff;
726 			cto->rsp.m1.ct_senselen = 16;
727 			cto->rsp.m1.ct_scsi_status |= CT2_SNSLEN_VALID;
728 		}
729 		cto->ct_syshandle = hdl;
730 	} else {
731 		at_entry_t *aep;
732 		ct_entry_t *cto = &un._ctio;
733 
734 		va_start(ap, isp);
735 		aep = va_arg(ap, at_entry_t *);
736 		code = va_arg(ap, uint32_t);
737 		hdl = va_arg(ap, uint32_t);
738 		va_end(ap);
739 		sts = code;
740 
741 		cto->ct_header.rqs_entry_type = RQSTYPE_CTIO;
742 		cto->ct_header.rqs_entry_count = 1;
743 		cto->ct_fwhandle = aep->at_handle;
744 		cto->ct_iid = aep->at_iid;
745 		cto->ct_tgt = aep->at_tgt;
746 		cto->ct_lun = aep->at_lun;
747 		cto->ct_tag_type = aep->at_tag_type;
748 		cto->ct_tag_val = aep->at_tag_val;
749 		if (aep->at_flags & AT_TQAE) {
750 			cto->ct_flags |= CT_TQAE;
751 		}
752 		cto->ct_flags = CT_SENDSTATUS | CT_NO_DATA;
753 		if (hdl == 0) {
754 			cto->ct_flags |= CT_CCINCR;
755 		}
756 		cto->ct_scsi_status = sts;
757 		cto->ct_syshandle = hdl;
758 	}
759 	return (isp_target_put_entry(isp, &un));
760 }
761 
762 /*
763  * These are either broadcast events or specifically CTIO fast completion
764  */
765 int
766 isp_target_async(ispsoftc_t *isp, int bus, int event)
767 {
768 	tmd_notify_t notify;
769 
770 	MEMZERO(&notify, sizeof (tmd_notify_t));
771 	notify.nt_hba = isp;
772 	notify.nt_iid = INI_ANY;
773 	/* nt_tgt set in outer layers */
774 	notify.nt_lun = LUN_ANY;
775 	notify.nt_channel = bus;
776 	notify.nt_tagval = TAG_ANY;
777 
778 	if (IS_SCSI(isp)) {
779 		TAG_INSERT_BUS(notify.nt_tagval, bus);
780 	}
781 
782 	switch (event) {
783 	case ASYNC_LOOP_UP:
784 	case ASYNC_PTPMODE:
785 		notify.nt_ncode = NT_LINK_UP;
786 		isp_async(isp, ISPASYNC_TARGET_NOTIFY, &notify);
787 		break;
788 	case ASYNC_LOOP_DOWN:
789 		notify.nt_ncode = NT_LINK_DOWN;
790 		isp_async(isp, ISPASYNC_TARGET_NOTIFY, &notify);
791 		break;
792 	case ASYNC_LIP_ERROR:
793 	case ASYNC_LIP_F8:
794 	case ASYNC_LIP_OCCURRED:
795 	case ASYNC_LOOP_RESET:
796 		notify.nt_ncode = NT_LIP_RESET;
797 		isp_async(isp, ISPASYNC_TARGET_NOTIFY, &notify);
798 		break;
799 	case ASYNC_BUS_RESET:
800 	case ASYNC_TIMEOUT_RESET:	/* XXX: where does this come from ? */
801 		notify.nt_ncode = NT_BUS_RESET;
802 		isp_async(isp, ISPASYNC_TARGET_NOTIFY, &notify);
803 		break;
804 	case ASYNC_DEVICE_RESET:
805 		notify.nt_ncode = NT_TARGET_RESET;
806 		isp_async(isp, ISPASYNC_TARGET_NOTIFY, &notify);
807 		break;
808 	case ASYNC_CTIO_DONE:
809 	{
810 		uint8_t storage[QENTRY_LEN];
811 		memset(storage, 0, QENTRY_LEN);
812 		if (IS_24XX(isp)) {
813 			ct7_entry_t *ct = (ct7_entry_t *) storage;
814 			ct->ct_header.rqs_entry_type = RQSTYPE_CTIO7;
815 			ct->ct_nphdl = CT7_OK;
816 			ct->ct_syshandle = bus;
817 			ct->ct_flags = CT7_SENDSTATUS;
818 		} else if (IS_FC(isp)) {
819             		/* This should also suffice for 2K login code */
820 			ct2_entry_t *ct = (ct2_entry_t *) storage;
821 			ct->ct_header.rqs_entry_type = RQSTYPE_CTIO2;
822 			ct->ct_status = CT_OK;
823 			ct->ct_syshandle = bus;
824 			ct->ct_flags = CT2_SENDSTATUS|CT2_FASTPOST;
825 		} else {
826 			ct_entry_t *ct = (ct_entry_t *) storage;
827 			ct->ct_header.rqs_entry_type = RQSTYPE_CTIO;
828 			ct->ct_status = CT_OK;
829 			ct->ct_fwhandle = bus;
830 			ct->ct_flags = CT_SENDSTATUS;
831 		}
832 		isp_async(isp, ISPASYNC_TARGET_ACTION, storage);
833 		break;
834 	}
835 	default:
836 		isp_prt(isp, ISP_LOGERR,
837 		    "isp_target_async: unknown event 0x%x", event);
838 		if (isp->isp_state == ISP_RUNSTATE) {
839 			isp_notify_ack(isp, NULL);
840 		}
841 		break;
842 	}
843 	return (0);
844 }
845 
846 
847 /*
848  * Process a received message.
849  * The ISP firmware can handle most messages, there are only
850  * a few that we need to deal with:
851  * - abort: clean up the current command
852  * - abort tag and clear queue
853  */
854 
855 static void
856 isp_got_msg(ispsoftc_t *isp, in_entry_t *inp)
857 {
858 	tmd_notify_t nt;
859 	uint8_t status = inp->in_status & ~QLTM_SVALID;
860 
861 	MEMZERO(&nt, sizeof (nt));
862 	nt.nt_hba = isp;
863 	nt.nt_iid = GET_IID_VAL(inp->in_iid);
864 	nt.nt_tgt = inp->in_tgt;
865 	nt.nt_lun = inp->in_lun;
866 	IN_MAKE_TAGID(nt.nt_tagval, GET_BUS_VAL(inp->in_iid), 0, inp);
867 	nt.nt_lreserved = inp;
868 
869 	if (status == IN_IDE_RECEIVED || status == IN_MSG_RECEIVED) {
870 		switch (inp->in_msg[0]) {
871 		case MSG_ABORT:
872 			nt.nt_ncode = NT_ABORT_TASK_SET;
873 			break;
874 		case MSG_BUS_DEV_RESET:
875 			nt.nt_ncode = NT_TARGET_RESET;
876 			break;
877 		case MSG_ABORT_TAG:
878 			nt.nt_ncode = NT_ABORT_TASK;
879 			break;
880 		case MSG_CLEAR_QUEUE:
881 			nt.nt_ncode = NT_CLEAR_TASK_SET;
882 			break;
883 		case MSG_REL_RECOVERY:
884 			nt.nt_ncode = NT_CLEAR_ACA;
885 			break;
886 		case MSG_TERM_IO_PROC:
887 			nt.nt_ncode = NT_ABORT_TASK;
888 			break;
889 		case MSG_LUN_RESET:
890 			nt.nt_ncode = NT_LUN_RESET;
891 			break;
892 		default:
893 			isp_prt(isp, ISP_LOGERR,
894 			    "unhandled message 0x%x", inp->in_msg[0]);
895 			isp_notify_ack(isp, inp);
896 			return;
897 		}
898 		isp_async(isp, ISPASYNC_TARGET_NOTIFY, &nt);
899 	} else {
900 		isp_prt(isp, ISP_LOGERR,
901 		    "unknown immediate notify status 0x%x", inp->in_status);
902 		isp_notify_ack(isp, inp);
903 	}
904 }
905 
906 /*
907  * Synthesize a message from the task management flags in a FCP_CMND_IU.
908  */
909 static void
910 isp_got_msg_fc(ispsoftc_t *isp, in_fcentry_t *inp)
911 {
912 	tmd_notify_t nt;
913 	static const char f1[] = "%s from N-port handle 0x%x lun %d seq 0x%x";
914 	static const char f2[] = "unknown %s 0x%x lun %d N-Port handle 0x%x "
915 	    "task flags 0x%x seq 0x%x\n";
916 	uint16_t seqid, loopid;
917 
918 	MEMZERO(&nt, sizeof (tmd_notify_t));
919 	nt.nt_hba = isp;
920 	if (ISP_CAP_2KLOGIN(isp)) {
921 		nt.nt_iid = ((in_fcentry_e_t *)inp)->in_iid;
922 		loopid = ((in_fcentry_e_t *)inp)->in_iid;
923 		seqid = ((in_fcentry_e_t *)inp)->in_seqid;
924 	} else {
925 		nt.nt_iid = inp->in_iid;
926 		loopid = inp->in_iid;
927 		seqid = inp->in_seqid;
928 	}
929 	/* nt_tgt set in outer layers */
930 	if (ISP_CAP_SCCFW(isp)) {
931 		nt.nt_lun = inp->in_scclun;
932 	} else {
933 		nt.nt_lun = inp->in_lun;
934 	}
935 	IN_FC_MAKE_TAGID(nt.nt_tagval, 0, 0, seqid);
936 	nt.nt_need_ack = 1;
937 	nt.nt_lreserved = inp;
938 
939 	if (inp->in_status != IN_MSG_RECEIVED) {
940 		isp_prt(isp, ISP_LOGINFO, f2, "immediate notify status",
941 		    inp->in_status, nt.nt_lun, loopid, inp->in_task_flags,
942 		    inp->in_seqid);
943 		isp_notify_ack(isp, inp);
944 		return;
945 	}
946 
947 	if (inp->in_task_flags & TASK_FLAGS_ABORT_TASK_SET) {
948 		isp_prt(isp, ISP_LOGINFO, f1, "ABORT TASK SET",
949 		    loopid, nt.nt_lun, inp->in_seqid);
950 		nt.nt_ncode = NT_ABORT_TASK_SET;
951 	} else if (inp->in_task_flags & TASK_FLAGS_CLEAR_TASK_SET) {
952 		isp_prt(isp, ISP_LOGINFO, f1, "CLEAR TASK SET",
953 		    loopid, nt.nt_lun, inp->in_seqid);
954 		nt.nt_ncode = NT_CLEAR_TASK_SET;
955 	} else if (inp->in_task_flags & TASK_FLAGS_LUN_RESET) {
956 		isp_prt(isp, ISP_LOGINFO, f1, "LUN RESET",
957 		    loopid, nt.nt_lun, inp->in_seqid);
958 		nt.nt_ncode = NT_LUN_RESET;
959 	} else if (inp->in_task_flags & TASK_FLAGS_TARGET_RESET) {
960 		isp_prt(isp, ISP_LOGINFO, f1, "TARGET RESET",
961 		    loopid, nt.nt_lun, inp->in_seqid);
962 		nt.nt_ncode = NT_TARGET_RESET;
963 	} else if (inp->in_task_flags & TASK_FLAGS_CLEAR_ACA) {
964 		isp_prt(isp, ISP_LOGINFO, f1, "CLEAR ACA",
965 		    loopid, nt.nt_lun, inp->in_seqid);
966 		nt.nt_ncode = NT_CLEAR_ACA;
967 	} else {
968 		isp_prt(isp, ISP_LOGWARN, f2, "task flag", inp->in_status,
969 		    nt.nt_lun, loopid, inp->in_task_flags,  inp->in_seqid);
970 		isp_notify_ack(isp, inp);
971 		return;
972 	}
973 	isp_async(isp, ISPASYNC_TARGET_NOTIFY, &nt);
974 }
975 
976 #define	HILO(x)	(uint32_t) (x >> 32),  (uint32_t) x
977 static void
978 isp_got_tmf_24xx(ispsoftc_t *isp, at7_entry_t *aep)
979 {
980 	tmd_notify_t nt;
981 	static const char f1[] =
982 	    "%s from PortID 0x%06x lun %d seq 0x%08x%08x";
983 	static const char f2[] =
984 	    "unknown Task Flag 0x%x lun %d PortID 0x%x tag 0x%08x%08x";
985 	uint16_t chan;
986 	uint32_t sid, did;
987 
988 	MEMZERO(&nt, sizeof (tmd_notify_t));
989 	nt.nt_hba = isp;
990 	nt.nt_iid = INI_ANY;
991 	nt.nt_lun =
992 	    (aep->at_cmnd.fcp_cmnd_lun[0] << 8) |
993 	    (aep->at_cmnd.fcp_cmnd_lun[1]);
994 	nt.nt_tagval = aep->at_rxid;
995 	nt.nt_lreserved = aep;
996 	sid =
997 	    (aep->at_hdr.s_id[0] << 16) |
998 	    (aep->at_hdr.s_id[1] <<  8) |
999 	    (aep->at_hdr.s_id[2]);
1000 
1001 	/* Channel has to derived from D_ID */
1002 	did = (aep->at_hdr.d_id[0] << 16) | (aep->at_hdr.d_id[1] << 8) | aep->at_hdr.d_id[2];
1003 	for (chan = 0; chan < isp->isp_nchan; chan++) {
1004 		if (FCPARAM(isp, chan)->isp_portid == did) {
1005 		    break;
1006 		}
1007 	}
1008 	if (chan == isp->isp_nchan) {
1009 		isp_prt(isp, ISP_LOGWARN,
1010 		    "%s:  D_ID 0x%x not found on any channel", __func__,  did);
1011 		/* just drop on the floor */
1012 		return;
1013 	}
1014 	nt.nt_channel = chan;
1015 	if (aep->at_cmnd.fcp_cmnd_task_management &
1016 	    FCP_CMND_TMF_ABORT_TASK_SET) {
1017 		isp_prt(isp, ISP_LOGINFO, f1, "ABORT TASK SET",
1018 		    sid, nt.nt_lun, HILO(nt.nt_tagval));
1019 		nt.nt_ncode = NT_ABORT_TASK_SET;
1020 	} else if (aep->at_cmnd.fcp_cmnd_task_management &
1021 	    FCP_CMND_TMF_CLEAR_TASK_SET) {
1022 		isp_prt(isp, ISP_LOGINFO, f1, "CLEAR TASK SET",
1023 		    sid, nt.nt_lun, HILO(nt.nt_tagval));
1024 		nt.nt_ncode = NT_CLEAR_TASK_SET;
1025 	} else if (aep->at_cmnd.fcp_cmnd_task_management &
1026 	    FCP_CMND_TMF_LUN_RESET) {
1027 		isp_prt(isp, ISP_LOGINFO, f1, "LUN RESET",
1028 		    sid, nt.nt_lun, HILO(nt.nt_tagval));
1029 		nt.nt_ncode = NT_LUN_RESET;
1030 	} else if (aep->at_cmnd.fcp_cmnd_task_management &
1031 	    FCP_CMND_TMF_TGT_RESET) {
1032 		isp_prt(isp, ISP_LOGINFO, f1, "TARGET RESET",
1033 		    sid, nt.nt_lun, HILO(nt.nt_tagval));
1034 		nt.nt_ncode = NT_TARGET_RESET;
1035 		nt.nt_lun = LUN_ANY;
1036 	} else if (aep->at_cmnd.fcp_cmnd_task_management &
1037 	    FCP_CMND_TMF_CLEAR_ACA) {
1038 		isp_prt(isp, ISP_LOGINFO, f1, "CLEAR ACA",
1039 		    sid, nt.nt_lun, HILO(nt.nt_tagval));
1040 		nt.nt_ncode = NT_CLEAR_ACA;
1041 	} else {
1042 		isp_prt(isp, ISP_LOGWARN, f2,
1043 		    aep->at_cmnd.fcp_cmnd_task_management,
1044 		    nt.nt_lun, sid, HILO(nt.nt_tagval));
1045 		nt.nt_ncode = NT_UNKNOWN;
1046 		return;
1047 	}
1048 	isp_async(isp, ISPASYNC_TARGET_NOTIFY, &nt);
1049 }
1050 
1051 void
1052 isp_notify_ack(ispsoftc_t *isp, void *arg)
1053 {
1054 	char storage[QENTRY_LEN];
1055 	uint32_t nxti, optr;
1056 	void *outp;
1057 
1058 	if (isp_getrqentry(isp, &nxti, &optr, &outp)) {
1059 		isp_prt(isp, ISP_LOGWARN,
1060 		    "Request Queue Overflow For isp_notify_ack");
1061 		return;
1062 	}
1063 
1064 	MEMZERO(storage, QENTRY_LEN);
1065 
1066 	if (IS_24XX(isp) && arg != NULL && (((isphdr_t *)arg)->rqs_entry_type == RQSTYPE_ATIO)) {
1067 		at7_entry_t *aep = arg;
1068 isp_prt(isp, ISP_LOGWARN, "SQUAWK: notify ack with no known vpidx or nphdl");
1069 		isp_endcmd(isp, aep, NIL_HANDLE, 0, 0, 0);
1070 		return;
1071 	} else if (IS_24XX(isp) && arg != NULL && (((isphdr_t *)arg)->rqs_entry_type == RQSTYPE_ABTS_RSP)) {
1072 		abts_rsp_t *abts_rsp = (abts_rsp_t *) storage;
1073 		/*
1074 		 * The caller will have set response values as appropriate
1075 		 * in the ABTS structure just before calling us.
1076 		 */
1077 		MEMCPY(abts_rsp, arg, QENTRY_LEN);
1078 		isp_put_abts_rsp(isp, abts_rsp, (abts_rsp_t *)outp);
1079 	} else if (IS_24XX(isp)) {
1080 		na_fcentry_24xx_t *na = (na_fcentry_24xx_t *) storage;
1081 		if (arg) {
1082 			in_fcentry_24xx_t *in = arg;
1083 			na->na_nphdl = in->in_nphdl;
1084 			na->na_status = in->in_status;
1085 			na->na_status_subcode = in->in_status_subcode;
1086 			na->na_rxid = in->in_rxid;
1087 			na->na_oxid = in->in_oxid;
1088 			na->na_vpindex = in->in_vpindex;
1089 			na->na_srr_rxid = in->in_srr_rxid;
1090 			na->na_srr_reloff_hi = in->in_srr_reloff_hi;
1091 			na->na_srr_reloff_lo = in->in_srr_reloff_lo;
1092 			na->na_srr_iu = in->in_srr_iu;
1093 			if (in->in_status == IN24XX_SRR_RCVD) {
1094 				na->na_srr_flags = 1;
1095 				na->na_srr_reject_vunique = 0;
1096 				na->na_srr_reject_explanation = 1;
1097 				na->na_srr_reject_code = 1;
1098 			}
1099 		}
1100 		na->na_header.rqs_entry_type = RQSTYPE_NOTIFY_ACK;
1101 		na->na_header.rqs_entry_count = 1;
1102 		isp_put_notify_24xx_ack(isp, na, (na_fcentry_24xx_t *)outp);
1103 	} else if (IS_FC(isp)) {
1104 		na_fcentry_t *na = (na_fcentry_t *) storage;
1105 		int iid = 0;
1106 
1107 		if (arg) {
1108 			in_fcentry_t *inp = arg;
1109 			MEMCPY(storage, arg, sizeof (isphdr_t));
1110 			if (ISP_CAP_2KLOGIN(isp)) {
1111 				((na_fcentry_e_t *)na)->na_iid =
1112 				    ((in_fcentry_e_t *)inp)->in_iid;
1113 				iid = ((na_fcentry_e_t *)na)->na_iid;
1114 			} else {
1115 				na->na_iid = inp->in_iid;
1116 				iid = na->na_iid;
1117 			}
1118 			na->na_task_flags =
1119 			    inp->in_task_flags & TASK_FLAGS_RESERVED_MASK;
1120 			na->na_seqid = inp->in_seqid;
1121 			na->na_flags = NAFC_RCOUNT;
1122 			na->na_status = inp->in_status;
1123 			if (inp->in_status == IN_RESET) {
1124 				na->na_flags |= NAFC_RST_CLRD;
1125 			}
1126 			if (inp->in_status == IN_MSG_RECEIVED) {
1127 				na->na_flags |= NAFC_TVALID;
1128 				na->na_response = 0;	/* XXX SUCCEEDED XXX */
1129 			}
1130 		} else {
1131 			na->na_flags = NAFC_RST_CLRD;
1132 		}
1133 		na->na_header.rqs_entry_type = RQSTYPE_NOTIFY_ACK;
1134 		na->na_header.rqs_entry_count = 1;
1135 		if (ISP_CAP_2KLOGIN(isp)) {
1136 			isp_put_notify_ack_fc_e(isp, (na_fcentry_e_t *) na,
1137 			    (na_fcentry_e_t *)outp);
1138 		} else {
1139 			isp_put_notify_ack_fc(isp, na, (na_fcentry_t *)outp);
1140 		}
1141 		isp_prt(isp, ISP_LOGTDEBUG0, "notify ack loopid %u seqid %x "
1142 		    "flags %x tflags %x response %x", iid, na->na_seqid,
1143 		    na->na_flags, na->na_task_flags, na->na_response);
1144 	} else {
1145 		na_entry_t *na = (na_entry_t *) storage;
1146 		if (arg) {
1147 			in_entry_t *inp = arg;
1148 			MEMCPY(storage, arg, sizeof (isphdr_t));
1149 			na->na_iid = inp->in_iid;
1150 			na->na_lun = inp->in_lun;
1151 			na->na_tgt = inp->in_tgt;
1152 			na->na_seqid = inp->in_seqid;
1153 			if (inp->in_status == IN_RESET) {
1154 				na->na_event = NA_RST_CLRD;
1155 			}
1156 		} else {
1157 			na->na_event = NA_RST_CLRD;
1158 		}
1159 		na->na_header.rqs_entry_type = RQSTYPE_NOTIFY_ACK;
1160 		na->na_header.rqs_entry_count = 1;
1161 		isp_put_notify_ack(isp, na, (na_entry_t *)outp);
1162 		isp_prt(isp, ISP_LOGTDEBUG0, "notify ack loopid %u lun %u tgt "
1163 		    "%u seqid %x event %x", na->na_iid, na->na_lun, na->na_tgt,
1164 		    na->na_seqid, na->na_event);
1165 	}
1166 	ISP_TDQE(isp, "isp_notify_ack", (int) optr, storage);
1167 	ISP_ADD_REQUEST(isp, nxti);
1168 }
1169 
1170 static void
1171 isp_handle_atio(ispsoftc_t *isp, at_entry_t *aep)
1172 {
1173 	int lun;
1174 	lun = aep->at_lun;
1175 	/*
1176 	 * The firmware status (except for the QLTM_SVALID bit) indicates
1177 	 * why this ATIO was sent to us.
1178 	 *
1179 	 * If QLTM_SVALID is set, the firware has recommended Sense Data.
1180 	 *
1181 	 * If the DISCONNECTS DISABLED bit is set in the flags field,
1182 	 * we're still connected on the SCSI bus - i.e. the initiator
1183 	 * did not set DiscPriv in the identify message. We don't care
1184 	 * about this so it's ignored.
1185 	 */
1186 
1187 	switch(aep->at_status & ~QLTM_SVALID) {
1188 	case AT_PATH_INVALID:
1189 		/*
1190 		 * ATIO rejected by the firmware due to disabled lun.
1191 		 */
1192 		isp_prt(isp, ISP_LOGERR,
1193 		    "rejected ATIO for disabled lun %d", lun);
1194 		break;
1195 	case AT_NOCAP:
1196 		/*
1197 		 * Requested Capability not available
1198 		 * We sent an ATIO that overflowed the firmware's
1199 		 * command resource count.
1200 		 */
1201 		isp_prt(isp, ISP_LOGERR,
1202 		    "rejected ATIO for lun %d because of command count"
1203 		    " overflow", lun);
1204 		break;
1205 
1206 	case AT_BDR_MSG:
1207 		/*
1208 		 * If we send an ATIO to the firmware to increment
1209 		 * its command resource count, and the firmware is
1210 		 * recovering from a Bus Device Reset, it returns
1211 		 * the ATIO with this status. We set the command
1212 		 * resource count in the Enable Lun entry and do
1213 		 * not increment it. Therefore we should never get
1214 		 * this status here.
1215 		 */
1216 		isp_prt(isp, ISP_LOGERR, atiocope, lun,
1217 		    GET_BUS_VAL(aep->at_iid));
1218 		break;
1219 
1220 	case AT_CDB:		/* Got a CDB */
1221 	case AT_PHASE_ERROR:	/* Bus Phase Sequence Error */
1222 		/*
1223 		 * Punt to platform specific layer.
1224 		 */
1225 		isp_async(isp, ISPASYNC_TARGET_ACTION, aep);
1226 		break;
1227 
1228 	case AT_RESET:
1229 		/*
1230 		 * A bus reset came along and blew away this command. Why
1231 		 * they do this in addition the async event code stuff,
1232 		 * I dunno.
1233 		 *
1234 		 * Ignore it because the async event will clear things
1235 		 * up for us.
1236 		 */
1237 		isp_prt(isp, ISP_LOGWARN, atior, lun,
1238 		    GET_IID_VAL(aep->at_iid), GET_BUS_VAL(aep->at_iid));
1239 		break;
1240 
1241 
1242 	default:
1243 		isp_prt(isp, ISP_LOGERR,
1244 		    "Unknown ATIO status 0x%x from loopid %d for lun %d",
1245 		    aep->at_status, aep->at_iid, lun);
1246 		(void) isp_target_put_atio(isp, aep);
1247 		break;
1248 	}
1249 }
1250 
1251 static void
1252 isp_handle_atio2(ispsoftc_t *isp, at2_entry_t *aep)
1253 {
1254 	int lun, iid;
1255 
1256 	if (ISP_CAP_SCCFW(isp)) {
1257 		lun = aep->at_scclun;
1258 	} else {
1259 		lun = aep->at_lun;
1260 	}
1261 
1262 	if (ISP_CAP_2KLOGIN(isp)) {
1263 		iid = ((at2e_entry_t *)aep)->at_iid;
1264 	} else {
1265 		iid = aep->at_iid;
1266 	}
1267 
1268 	/*
1269 	 * The firmware status (except for the QLTM_SVALID bit) indicates
1270 	 * why this ATIO was sent to us.
1271 	 *
1272 	 * If QLTM_SVALID is set, the firware has recommended Sense Data.
1273 	 *
1274 	 * If the DISCONNECTS DISABLED bit is set in the flags field,
1275 	 * we're still connected on the SCSI bus - i.e. the initiator
1276 	 * did not set DiscPriv in the identify message. We don't care
1277 	 * about this so it's ignored.
1278 	 */
1279 
1280 	switch(aep->at_status & ~QLTM_SVALID) {
1281 	case AT_PATH_INVALID:
1282 		/*
1283 		 * ATIO rejected by the firmware due to disabled lun.
1284 		 */
1285 		isp_prt(isp, ISP_LOGERR,
1286 		    "rejected ATIO2 for disabled lun %d", lun);
1287 		break;
1288 	case AT_NOCAP:
1289 		/*
1290 		 * Requested Capability not available
1291 		 * We sent an ATIO that overflowed the firmware's
1292 		 * command resource count.
1293 		 */
1294 		isp_prt(isp, ISP_LOGERR,
1295 		    "rejected ATIO2 for lun %d- command count overflow", lun);
1296 		break;
1297 
1298 	case AT_BDR_MSG:
1299 		/*
1300 		 * If we send an ATIO to the firmware to increment
1301 		 * its command resource count, and the firmware is
1302 		 * recovering from a Bus Device Reset, it returns
1303 		 * the ATIO with this status. We set the command
1304 		 * resource count in the Enable Lun entry and no
1305 		 * not increment it. Therefore we should never get
1306 		 * this status here.
1307 		 */
1308 		isp_prt(isp, ISP_LOGERR, atiocope, lun, 0);
1309 		break;
1310 
1311 	case AT_CDB:		/* Got a CDB */
1312 		/*
1313 		 * Punt to platform specific layer.
1314 		 */
1315 		isp_async(isp, ISPASYNC_TARGET_ACTION, aep);
1316 		break;
1317 
1318 	case AT_RESET:
1319 		/*
1320 		 * A bus reset came along an blew away this command. Why
1321 		 * they do this in addition the async event code stuff,
1322 		 * I dunno.
1323 		 *
1324 		 * Ignore it because the async event will clear things
1325 		 * up for us.
1326 		 */
1327 		isp_prt(isp, ISP_LOGERR, atior, lun, iid, 0);
1328 		break;
1329 
1330 
1331 	default:
1332 		isp_prt(isp, ISP_LOGERR,
1333 		    "Unknown ATIO2 status 0x%x from loopid %d for lun %d",
1334 		    aep->at_status, iid, lun);
1335 		(void) isp_target_put_atio(isp, aep);
1336 		break;
1337 	}
1338 }
1339 
1340 static void
1341 isp_handle_ctio(ispsoftc_t *isp, ct_entry_t *ct)
1342 {
1343 	void *xs;
1344 	int pl = ISP_LOGTDEBUG2;
1345 	char *fmsg = NULL;
1346 
1347 	if (ct->ct_syshandle) {
1348 		xs = isp_find_xs_tgt(isp, ct->ct_syshandle);
1349 		if (xs == NULL) {
1350 			pl = ISP_LOGALL;
1351 		}
1352 	} else {
1353 		xs = NULL;
1354 	}
1355 
1356 	switch(ct->ct_status & ~QLTM_SVALID) {
1357 	case CT_OK:
1358 		/*
1359 		 * There are generally 3 possibilities as to why we'd get
1360 		 * this condition:
1361 		 * 	We disconnected after receiving a CDB.
1362 		 * 	We sent or received data.
1363 		 * 	We sent status & command complete.
1364 		 */
1365 
1366 		if (ct->ct_flags & CT_SENDSTATUS) {
1367 			break;
1368 		} else if ((ct->ct_flags & CT_DATAMASK) == CT_NO_DATA) {
1369 			/*
1370 			 * Nothing to do in this case.
1371 			 */
1372 			isp_prt(isp, pl, "CTIO- iid %d disconnected OK",
1373 			    ct->ct_iid);
1374 			return;
1375 		}
1376 		break;
1377 
1378 	case CT_BDR_MSG:
1379 		/*
1380 		 * Bus Device Reset message received or the SCSI Bus has
1381 		 * been Reset; the firmware has gone to Bus Free.
1382 		 *
1383 		 * The firmware generates an async mailbox interrupt to
1384 		 * notify us of this and returns outstanding CTIOs with this
1385 		 * status. These CTIOs are handled in that same way as
1386 		 * CT_ABORTED ones, so just fall through here.
1387 		 */
1388 		fmsg = "Bus Device Reset";
1389 		/*FALLTHROUGH*/
1390 	case CT_RESET:
1391 		if (fmsg == NULL)
1392 			fmsg = "Bus Reset";
1393 		/*FALLTHROUGH*/
1394 	case CT_ABORTED:
1395 		/*
1396 		 * When an Abort message is received the firmware goes to
1397 		 * Bus Free and returns all outstanding CTIOs with the status
1398 		 * set, then sends us an Immediate Notify entry.
1399 		 */
1400 		if (fmsg == NULL)
1401 			fmsg = "ABORT TAG message sent by Initiator";
1402 
1403 		isp_prt(isp, ISP_LOGTDEBUG0, "CTIO destroyed by %s", fmsg);
1404 		break;
1405 
1406 	case CT_INVAL:
1407 		/*
1408 		 * CTIO rejected by the firmware due to disabled lun.
1409 		 * "Cannot Happen".
1410 		 */
1411 		isp_prt(isp, ISP_LOGERR,
1412 		    "Firmware rejected CTIO for disabled lun %d",
1413 		    ct->ct_lun);
1414 		break;
1415 
1416 	case CT_NOPATH:
1417 		/*
1418 		 * CTIO rejected by the firmware due "no path for the
1419 		 * nondisconnecting nexus specified". This means that
1420 		 * we tried to access the bus while a non-disconnecting
1421 		 * command is in process.
1422 		 */
1423 		isp_prt(isp, ISP_LOGERR,
1424 		    "Firmware rejected CTIO for bad nexus %d/%d/%d",
1425 		    ct->ct_iid, ct->ct_tgt, ct->ct_lun);
1426 		break;
1427 
1428 	case CT_RSELTMO:
1429 		fmsg = "Reselection";
1430 		/*FALLTHROUGH*/
1431 	case CT_TIMEOUT:
1432 		if (fmsg == NULL)
1433 			fmsg = "Command";
1434 		isp_prt(isp, ISP_LOGWARN, "Firmware timed out on %s", fmsg);
1435 		break;
1436 
1437 	case	CT_PANIC:
1438 		if (fmsg == NULL)
1439 			fmsg = "Unrecoverable Error";
1440 		/*FALLTHROUGH*/
1441 	case CT_ERR:
1442 		if (fmsg == NULL)
1443 			fmsg = "Completed with Error";
1444 		/*FALLTHROUGH*/
1445 	case CT_PHASE_ERROR:
1446 		if (fmsg == NULL)
1447 			fmsg = "Phase Sequence Error";
1448 		/*FALLTHROUGH*/
1449 	case CT_TERMINATED:
1450 		if (fmsg == NULL)
1451 			fmsg = "terminated by TERMINATE TRANSFER";
1452 		/*FALLTHROUGH*/
1453 	case CT_NOACK:
1454 		if (fmsg == NULL)
1455 			fmsg = "unacknowledged Immediate Notify pending";
1456 		isp_prt(isp, ISP_LOGERR, "CTIO returned by f/w- %s", fmsg);
1457 		break;
1458 	default:
1459 		isp_prt(isp, ISP_LOGERR, "Unknown CTIO status 0x%x",
1460 		    ct->ct_status & ~QLTM_SVALID);
1461 		break;
1462 	}
1463 
1464 	if (xs == NULL) {
1465 		/*
1466 		 * There may be more than one CTIO for a data transfer,
1467 		 * or this may be a status CTIO we're not monitoring.
1468 		 *
1469 		 * The assumption is that they'll all be returned in the
1470 		 * order we got them.
1471 		 */
1472 		if (ct->ct_syshandle == 0) {
1473 			if ((ct->ct_flags & CT_SENDSTATUS) == 0) {
1474 				isp_prt(isp, pl,
1475 				    "intermediate CTIO completed ok");
1476 			} else {
1477 				isp_prt(isp, pl,
1478 				    "unmonitored CTIO completed ok");
1479 			}
1480 		} else {
1481 			isp_prt(isp, pl,
1482 			    "NO xs for CTIO (handle 0x%x) status 0x%x",
1483 			    ct->ct_syshandle, ct->ct_status & ~QLTM_SVALID);
1484 		}
1485 	} else {
1486 		/*
1487 		 * Final CTIO completed. Release DMA resources and
1488 		 * notify platform dependent layers.
1489 		 */
1490 		if ((ct->ct_flags & CT_DATAMASK) != CT_NO_DATA) {
1491 			ISP_DMAFREE(isp, xs, ct->ct_syshandle);
1492 		}
1493 		isp_prt(isp, pl, "final CTIO complete");
1494 		/*
1495 		 * The platform layer will destroy the handle if appropriate.
1496 		 */
1497 		isp_async(isp, ISPASYNC_TARGET_ACTION, ct);
1498 	}
1499 }
1500 
1501 static void
1502 isp_handle_ctio2(ispsoftc_t *isp, ct2_entry_t *ct)
1503 {
1504 	void *xs;
1505 	int pl = ISP_LOGTDEBUG2;
1506 	char *fmsg = NULL;
1507 
1508 	if (ct->ct_syshandle) {
1509 		xs = isp_find_xs_tgt(isp, ct->ct_syshandle);
1510 		if (xs == NULL) {
1511 			pl = ISP_LOGALL;
1512 		}
1513 	} else {
1514 		xs = NULL;
1515 	}
1516 
1517 	switch(ct->ct_status & ~QLTM_SVALID) {
1518 	case CT_BUS_ERROR:
1519 		isp_prt(isp, ISP_LOGERR, "PCI DMA Bus Error");
1520 		/* FALL Through */
1521 	case CT_DATA_OVER:
1522 	case CT_DATA_UNDER:
1523 	case CT_OK:
1524 		/*
1525 		 * There are generally 2 possibilities as to why we'd get
1526 		 * this condition:
1527 		 * 	We sent or received data.
1528 		 * 	We sent status & command complete.
1529 		 */
1530 
1531 		break;
1532 
1533 	case CT_BDR_MSG:
1534 		/*
1535 		 * Target Reset function received.
1536 		 *
1537 		 * The firmware generates an async mailbox interrupt to
1538 		 * notify us of this and returns outstanding CTIOs with this
1539 		 * status. These CTIOs are handled in that same way as
1540 		 * CT_ABORTED ones, so just fall through here.
1541 		 */
1542 		fmsg = "TARGET RESET";
1543 		/*FALLTHROUGH*/
1544 	case CT_RESET:
1545 		if (fmsg == NULL)
1546 			fmsg = "LIP Reset";
1547 		/*FALLTHROUGH*/
1548 	case CT_ABORTED:
1549 		/*
1550 		 * When an Abort message is received the firmware goes to
1551 		 * Bus Free and returns all outstanding CTIOs with the status
1552 		 * set, then sends us an Immediate Notify entry.
1553 		 */
1554 		if (fmsg == NULL) {
1555 			fmsg = "ABORT";
1556 		}
1557 
1558 		isp_prt(isp, ISP_LOGTDEBUG0,
1559 		    "CTIO2 destroyed by %s: RX_ID=0x%x", fmsg, ct->ct_rxid);
1560 		break;
1561 
1562 	case CT_INVAL:
1563 		/*
1564 		 * CTIO rejected by the firmware - invalid data direction.
1565 		 */
1566 		isp_prt(isp, ISP_LOGERR, "CTIO2 had wrong data direction");
1567 		break;
1568 
1569 	case CT_RSELTMO:
1570 		fmsg = "failure to reconnect to initiator";
1571 		/*FALLTHROUGH*/
1572 	case CT_TIMEOUT:
1573 		if (fmsg == NULL)
1574 			fmsg = "command";
1575 		isp_prt(isp, ISP_LOGWARN, "Firmware timed out on %s", fmsg);
1576 		break;
1577 
1578 	case CT_ERR:
1579 		fmsg = "Completed with Error";
1580 		/*FALLTHROUGH*/
1581 	case CT_LOGOUT:
1582 		if (fmsg == NULL)
1583 			fmsg = "Port Logout";
1584 		/*FALLTHROUGH*/
1585 	case CT_PORTUNAVAIL:
1586 		if (fmsg == NULL)
1587 			fmsg = "Port not available";
1588 		/*FALLTHROUGH*/
1589 	case CT_PORTCHANGED:
1590 		if (fmsg == NULL)
1591 			fmsg = "Port Changed";
1592 		/*FALLTHROUGH*/
1593 	case CT_NOACK:
1594 		if (fmsg == NULL)
1595 			fmsg = "unacknowledged Immediate Notify pending";
1596 		isp_prt(isp, ISP_LOGWARN, "CTIO returned by f/w- %s", fmsg);
1597 		break;
1598 
1599 	case CT_INVRXID:
1600 		/*
1601 		 * CTIO rejected by the firmware because an invalid RX_ID.
1602 		 * Just print a message.
1603 		 */
1604 		isp_prt(isp, ISP_LOGWARN,
1605 		    "CTIO2 completed with Invalid RX_ID 0x%x", ct->ct_rxid);
1606 		break;
1607 
1608 	default:
1609 		isp_prt(isp, ISP_LOGERR, "Unknown CTIO2 status 0x%x",
1610 		    ct->ct_status & ~QLTM_SVALID);
1611 		break;
1612 	}
1613 
1614 	if (xs == NULL) {
1615 		/*
1616 		 * There may be more than one CTIO for a data transfer,
1617 		 * or this may be a status CTIO we're not monitoring.
1618 		 *
1619 		 * The assumption is that they'll all be returned in the
1620 		 * order we got them.
1621 		 */
1622 		if (ct->ct_syshandle == 0) {
1623 			if ((ct->ct_flags & CT2_SENDSTATUS) == 0) {
1624 				isp_prt(isp, pl,
1625 				    "intermediate CTIO completed ok");
1626 			} else {
1627 				isp_prt(isp, pl,
1628 				    "unmonitored CTIO completed ok");
1629 			}
1630 		} else {
1631 			isp_prt(isp, pl,
1632 			    "NO xs for CTIO (handle 0x%x) status 0x%x",
1633 			    ct->ct_syshandle, ct->ct_status & ~QLTM_SVALID);
1634 		}
1635 	} else {
1636 		if ((ct->ct_flags & CT2_DATAMASK) != CT2_NO_DATA) {
1637 			ISP_DMAFREE(isp, xs, ct->ct_syshandle);
1638 		}
1639 		if (ct->ct_flags & CT2_SENDSTATUS) {
1640 			/*
1641 			 * Sent status and command complete.
1642 			 *
1643 			 * We're now really done with this command, so we
1644 			 * punt to the platform dependent layers because
1645 			 * only there can we do the appropriate command
1646 			 * complete thread synchronization.
1647 			 */
1648 			isp_prt(isp, pl, "status CTIO complete");
1649 		} else {
1650 			/*
1651 			 * Final CTIO completed. Release DMA resources and
1652 			 * notify platform dependent layers.
1653 			 */
1654 			isp_prt(isp, pl, "data CTIO complete");
1655 		}
1656 		isp_async(isp, ISPASYNC_TARGET_ACTION, ct);
1657 		/*
1658 		 * The platform layer will destroy the handle if appropriate.
1659 		 */
1660 	}
1661 }
1662 
1663 static void
1664 isp_handle_ctio7(ispsoftc_t *isp, ct7_entry_t *ct)
1665 {
1666 	void *xs;
1667 	int pl = ISP_LOGTDEBUG2;
1668 	char *fmsg = NULL;
1669 
1670 	if (ct->ct_syshandle) {
1671 		xs = isp_find_xs_tgt(isp, ct->ct_syshandle);
1672 		if (xs == NULL) {
1673 			pl = ISP_LOGALL;
1674 		}
1675 	} else {
1676 		xs = NULL;
1677 	}
1678 
1679 	switch(ct->ct_nphdl) {
1680 	case CT7_BUS_ERROR:
1681 		isp_prt(isp, ISP_LOGERR, "PCI DMA Bus Error");
1682 		/* FALL Through */
1683 	case CT7_DATA_OVER:
1684 	case CT7_DATA_UNDER:
1685 	case CT7_OK:
1686 		/*
1687 		 * There are generally 2 possibilities as to why we'd get
1688 		 * this condition:
1689 		 * 	We sent or received data.
1690 		 * 	We sent status & command complete.
1691 		 */
1692 
1693 		break;
1694 
1695 	case CT7_RESET:
1696 		if (fmsg == NULL) {
1697 			fmsg = "LIP Reset";
1698 		}
1699 		/*FALLTHROUGH*/
1700 	case CT7_ABORTED:
1701 		/*
1702 		 * When an Abort message is received the firmware goes to
1703 		 * Bus Free and returns all outstanding CTIOs with the status
1704 		 * set, then sends us an Immediate Notify entry.
1705 		 */
1706 		if (fmsg == NULL) {
1707 			fmsg = "ABORT";
1708 		}
1709 		isp_prt(isp, ISP_LOGTDEBUG0,
1710 		    "CTIO7 destroyed by %s: RX_ID=0x%x", fmsg, ct->ct_rxid);
1711 		break;
1712 
1713 	case CT7_TIMEOUT:
1714 		if (fmsg == NULL) {
1715 			fmsg = "command";
1716 		}
1717 		isp_prt(isp, ISP_LOGWARN, "Firmware timed out on %s", fmsg);
1718 		break;
1719 
1720 	case CT7_ERR:
1721 		fmsg = "Completed with Error";
1722 		/*FALLTHROUGH*/
1723 	case CT7_LOGOUT:
1724 		if (fmsg == NULL) {
1725 			fmsg = "Port Logout";
1726 		}
1727 		/*FALLTHROUGH*/
1728 	case CT7_PORTUNAVAIL:
1729 		if (fmsg == NULL) {
1730 			fmsg = "Port not available";
1731 		}
1732 		/*FALLTHROUGH*/
1733 	case CT7_PORTCHANGED:
1734 		if (fmsg == NULL) {
1735 			fmsg = "Port Changed";
1736 		}
1737 		isp_prt(isp, ISP_LOGWARN, "CTIO returned by f/w- %s", fmsg);
1738 		break;
1739 
1740 	case CT7_INVRXID:
1741 		/*
1742 		 * CTIO rejected by the firmware because an invalid RX_ID.
1743 		 * Just print a message.
1744 		 */
1745 		isp_prt(isp, ISP_LOGWARN,
1746 		    "CTIO7 completed with Invalid RX_ID 0x%x", ct->ct_rxid);
1747 		break;
1748 
1749 	case CT7_REASSY_ERR:
1750 		isp_prt(isp, ISP_LOGWARN, "reassembly error");
1751 		break;
1752 
1753 	case CT7_SRR:
1754 		isp_prt(isp, ISP_LOGWARN, "SRR received");
1755 		break;
1756 
1757 	default:
1758 		isp_prt(isp, ISP_LOGERR, "Unknown CTIO7 status 0x%x",
1759 		    ct->ct_nphdl);
1760 		break;
1761 	}
1762 
1763 	if (xs == NULL) {
1764 		/*
1765 		 * There may be more than one CTIO for a data transfer,
1766 		 * or this may be a status CTIO we're not monitoring.
1767 		 *
1768 		 * The assumption is that they'll all be returned in the
1769 		 * order we got them.
1770 		 */
1771 		if (ct->ct_syshandle == 0) {
1772 			if (ct->ct_flags & CT7_TERMINATE) {
1773 				isp_prt(isp, ISP_LOGINFO,
1774 				    "termination of 0x%x complete",
1775 				    ct->ct_rxid);
1776 			} else if ((ct->ct_flags & CT7_SENDSTATUS) == 0) {
1777 				isp_prt(isp, pl,
1778 				    "intermediate CTIO completed ok");
1779 			} else {
1780 				isp_prt(isp, pl,
1781 				    "unmonitored CTIO completed ok");
1782 			}
1783 		} else {
1784 			isp_prt(isp, pl,
1785 			    "NO xs for CTIO (handle 0x%x) status 0x%x",
1786 			    ct->ct_syshandle, ct->ct_nphdl);
1787 		}
1788 	} else {
1789 		if ((ct->ct_flags & CT2_DATAMASK) != CT2_NO_DATA) {
1790 			ISP_DMAFREE(isp, xs, ct->ct_syshandle);
1791 		}
1792 		if (ct->ct_flags & CT2_SENDSTATUS) {
1793 			/*
1794 			 * Sent status and command complete.
1795 			 *
1796 			 * We're now really done with this command, so we
1797 			 * punt to the platform dependent layers because
1798 			 * only there can we do the appropriate command
1799 			 * complete thread synchronization.
1800 			 */
1801 			isp_prt(isp, pl, "status CTIO complete");
1802 		} else {
1803 			/*
1804 			 * Final CTIO completed. Release DMA resources and
1805 			 * notify platform dependent layers.
1806 			 */
1807 			isp_prt(isp, pl, "data CTIO complete");
1808 		}
1809 		isp_async(isp, ISPASYNC_TARGET_ACTION, ct);
1810 		/*
1811 		 * The platform layer will destroy the handle if appropriate.
1812 		 */
1813 	}
1814 }
1815 
1816 static void
1817 isp_handle_24xx_inotify(ispsoftc_t *isp, in_fcentry_24xx_t *inot_24xx)
1818 {
1819 	uint8_t ochan, chan, lochan, hichan;
1820 
1821 
1822 	/*
1823 	 * Check to see whether we got a wildcard channel.
1824 	 * If so, we have to iterate over all channels.
1825 	 */
1826 	ochan = chan = inot_24xx->in_vpindex;
1827 	if (chan == 0xff) {
1828 		lochan = 0;
1829 		hichan = isp->isp_nchan;
1830 	} else {
1831 		if (chan > isp->isp_nchan) {
1832 			isp_prt(isp, ISP_LOGINFO,
1833 			    "%s: bad channel %d for status 0x%x",
1834 			    __func__, chan, inot_24xx->in_status);
1835 			isp_notify_ack(isp, inot_24xx);
1836 			return;
1837 		}
1838 		lochan = chan;
1839 		hichan = chan + 1;
1840 	}
1841 	isp_prt(isp, ISP_LOGTDEBUG0,
1842 	    "%s: Immediate Notify Channels %d..%d status=0x%x seqid=0x%x",
1843 	    __func__, lochan, hichan-1, inot_24xx->in_status,
1844 	   inot_24xx->in_rxid);
1845 	for (chan = lochan; chan < hichan; chan++) {
1846 		switch (inot_24xx->in_status) {
1847 		case IN24XX_LIP_RESET:
1848 		case IN24XX_LINK_RESET:
1849 		case IN24XX_PORT_LOGOUT:
1850 		case IN24XX_PORT_CHANGED:
1851 		case IN24XX_LINK_FAILED:
1852 		case IN24XX_SRR_RCVD:
1853 		case IN24XX_ELS_RCVD:
1854 			inot_24xx->in_vpindex = chan;
1855 			isp_async(isp, ISPASYNC_TARGET_ACTION, inot_24xx);
1856 			break;
1857 		default:
1858 			isp_prt(isp, ISP_LOGINFO,
1859 			    "%s: unhandled status (0x%x) for chan %d",
1860 			    __func__, inot_24xx->in_status, chan);
1861 			isp_notify_ack(isp, inot_24xx);
1862 			break;
1863 		}
1864 	}
1865 	inot_24xx->in_vpindex = ochan;
1866 }
1867 #endif
1868