xref: /netbsd/sys/dev/ic/isp_target.c (revision bf9ec67e)
1 /* $NetBSD: isp_target.c,v 1.18 2002/02/21 22:32:42 mjacob Exp $ */
2 /*
3  * This driver, which is contained in NetBSD in the files:
4  *
5  *	sys/dev/ic/isp.c
6  *	sys/dev/ic/isp_inline.h
7  *	sys/dev/ic/isp_netbsd.c
8  *	sys/dev/ic/isp_netbsd.h
9  *	sys/dev/ic/isp_target.c
10  *	sys/dev/ic/isp_target.h
11  *	sys/dev/ic/isp_tpublic.h
12  *	sys/dev/ic/ispmbox.h
13  *	sys/dev/ic/ispreg.h
14  *	sys/dev/ic/ispvar.h
15  *	sys/microcode/isp/asm_sbus.h
16  *	sys/microcode/isp/asm_1040.h
17  *	sys/microcode/isp/asm_1080.h
18  *	sys/microcode/isp/asm_12160.h
19  *	sys/microcode/isp/asm_2100.h
20  *	sys/microcode/isp/asm_2200.h
21  *	sys/pci/isp_pci.c
22  *	sys/sbus/isp_sbus.c
23  *
24  * Is being actively maintained by Matthew Jacob (mjacob@netbsd.org).
25  * This driver also is shared source with FreeBSD, OpenBSD, Linux, Solaris,
26  * Linux versions. This tends to be an interesting maintenance problem.
27  *
28  * Please coordinate with Matthew Jacob on changes you wish to make here.
29  */
30 /*
31  * Machine and OS Independent Target Mode Code for the Qlogic SCSI/FC adapters.
32  *
33  * Copyright (c) 1999, 2000, 2001 by Matthew Jacob
34  * All rights reserved.
35  * mjacob@feral.com
36  *
37  * Redistribution and use in source and binary forms, with or without
38  * modification, are permitted provided that the following conditions
39  * are met:
40  * 1. Redistributions of source code must retain the above copyright
41  *    notice immediately at the beginning of the file, without modification,
42  *    this list of conditions, and the following disclaimer.
43  * 2. The name of the author may not be used to endorse or promote products
44  *    derived from this software without specific prior written permission.
45  *
46  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
47  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
48  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
49  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
50  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
51  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
52  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
53  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
54  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
55  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
56  * SUCH DAMAGE.
57  */
58 
59 /*
60  * Bug fixes gratefully acknowledged from:
61  *     Oded Kedem <oded@kashya.com>
62  */
63 /*
64  * Include header file appropriate for platform we're building on.
65  */
66 
67 #include <sys/cdefs.h>
68 __KERNEL_RCSID(0, "$NetBSD: isp_target.c,v 1.18 2002/02/21 22:32:42 mjacob Exp $");
69 
70 #ifdef	__NetBSD__
71 #include <dev/ic/isp_netbsd.h>
72 #endif
73 #ifdef	__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 IID %d because a Bus Reset occurred "
89     "on bus %d";
90 
91 static void isp_got_msg(struct ispsoftc *, int, in_entry_t *);
92 static void isp_got_msg_fc(struct ispsoftc *, int, in_fcentry_t *);
93 static void isp_notify_ack(struct ispsoftc *, void *);
94 static void isp_handle_atio(struct ispsoftc *, at_entry_t *);
95 static void isp_handle_atio2(struct ispsoftc *, at2_entry_t *);
96 static void isp_handle_ctio(struct ispsoftc *, ct_entry_t *);
97 static void isp_handle_ctio2(struct ispsoftc *, ct2_entry_t *);
98 
99 /*
100  * The Qlogic driver gets an interrupt to look at response queue entries.
101  * Some of these are status completions for initiatior mode commands, but
102  * if target mode is enabled, we get a whole wad of response queue entries
103  * to be handled here.
104  *
105  * Basically the split into 3 main groups: Lun Enable/Modification responses,
106  * SCSI Command processing, and Immediate Notification events.
107  *
108  * You start by writing a request queue entry to enable target mode (and
109  * establish some resource limitations which you can modify later).
110  * The f/w responds with a LUN ENABLE or LUN MODIFY response with
111  * the status of this action. If the enable was successful, you can expect...
112  *
113  * Response queue entries with SCSI commands encapsulate show up in an ATIO
114  * (Accept Target IO) type- sometimes with enough info to stop the command at
115  * this level. Ultimately the driver has to feed back to the f/w's request
116  * queue a sequence of CTIOs (continue target I/O) that describe data to
117  * be moved and/or status to be sent) and finally finishing with sending
118  * to the f/w's response queue an ATIO which then completes the handshake
119  * with the f/w for that command. There's a lot of variations on this theme,
120  * including flags you can set in the CTIO for the Qlogic 2X00 fibre channel
121  * cards that 'auto-replenish' the f/w's ATIO count, but this is the basic
122  * gist of it.
123  *
124  * The third group that can show up in the response queue are Immediate
125  * Notification events. These include things like notifications of SCSI bus
126  * resets, or Bus Device Reset messages or other messages received. This
127  * a classic oddbins area. It can get  a little weird because you then turn
128  * around and acknowledge the Immediate Notify by writing an entry onto the
129  * request queue and then the f/w turns around and gives you an acknowledgement
130  * to *your* acknowledgement on the response queue (the idea being to let
131  * the f/w tell you when the event is *really* over I guess).
132  *
133  */
134 
135 
136 /*
137  * A new response queue entry has arrived. The interrupt service code
138  * has already swizzled it into the platform dependent from canonical form.
139  *
140  * Because of the way this driver is designed, unfortunately most of the
141  * actual synchronization work has to be done in the platform specific
142  * code- we have no synchroniation primitives in the common code.
143  */
144 
145 int
146 isp_target_notify(struct ispsoftc *isp, void *vptr, u_int16_t *optrp)
147 {
148 	u_int16_t status, seqid;
149 	union {
150 		at_entry_t	*atiop;
151 		at2_entry_t	*at2iop;
152 		ct_entry_t	*ctiop;
153 		ct2_entry_t	*ct2iop;
154 		lun_entry_t	*lunenp;
155 		in_entry_t	*inotp;
156 		in_fcentry_t	*inot_fcp;
157 		na_entry_t	*nackp;
158 		na_fcentry_t	*nack_fcp;
159 		isphdr_t	*hp;
160 		void *		*vp;
161 #define	atiop		unp.atiop
162 #define	at2iop		unp.at2iop
163 #define	ctiop		unp.ctiop
164 #define	ct2iop		unp.ct2iop
165 #define	lunenp		unp.lunenp
166 #define	inotp		unp.inotp
167 #define	inot_fcp	unp.inot_fcp
168 #define	nackp		unp.nackp
169 #define	nack_fcp	unp.nack_fcp
170 #define	hdrp		unp.hp
171 	} unp;
172 	u_int8_t local[QENTRY_LEN];
173 	int bus, type, rval = 0;
174 
175 	type = isp_get_response_type(isp, (isphdr_t *)vptr);
176 	unp.vp = vptr;
177 
178 	ISP_TDQE(isp, "isp_target_notify", (int) *optrp, vptr);
179 
180 	switch(type) {
181 	case RQSTYPE_ATIO:
182 		isp_get_atio(isp, atiop, (at_entry_t *) local);
183 		isp_handle_atio(isp, (at_entry_t *) local);
184 		break;
185 	case RQSTYPE_CTIO:
186 		isp_get_ctio(isp, ctiop, (ct_entry_t *) local);
187 		isp_handle_ctio(isp, (ct_entry_t *) local);
188 		break;
189 	case RQSTYPE_ATIO2:
190 		isp_get_atio2(isp, at2iop, (at2_entry_t *) local);
191 		isp_handle_atio2(isp, (at2_entry_t *) local);
192 		break;
193 	case RQSTYPE_CTIO2:
194 		isp_get_ctio2(isp, ct2iop, (ct2_entry_t *) local);
195 		isp_handle_ctio2(isp, (ct2_entry_t *) local);
196 		break;
197 	case RQSTYPE_ENABLE_LUN:
198 	case RQSTYPE_MODIFY_LUN:
199 		isp_get_enable_lun(isp, lunenp, (lun_entry_t *) local);
200 		(void) isp_async(isp, ISPASYNC_TARGET_ACTION, local);
201 		break;
202 
203 	case RQSTYPE_NOTIFY:
204 		/*
205 		 * Either the ISP received a SCSI message it can't
206 		 * handle, or it's returning an Immed. Notify entry
207 		 * we sent. We can send Immed. Notify entries to
208 		 * increment the firmware's resource count for them
209 		 * (we set this initially in the Enable Lun entry).
210 		 */
211 		bus = 0;
212 		if (IS_FC(isp)) {
213 			isp_get_notify_fc(isp, inot_fcp, (in_fcentry_t *)local);
214 			inot_fcp = (in_fcentry_t *) local;
215 			status = inot_fcp->in_status;
216 			seqid = inot_fcp->in_seqid;
217 		} else {
218 			isp_get_notify(isp, inotp, (in_entry_t *)local);
219 			inotp = (in_entry_t *) local;
220 			status = inotp->in_status & 0xff;
221 			seqid = inotp->in_seqid;
222 			if (IS_DUALBUS(isp)) {
223 				bus = GET_BUS_VAL(inotp->in_iid);
224 				SET_BUS_VAL(inotp->in_iid, 0);
225 			}
226 		}
227 		isp_prt(isp, ISP_LOGTDEBUG0,
228 		    "Immediate Notify On Bus %d, status=0x%x seqid=0x%x",
229 		    bus, status, seqid);
230 
231 		/*
232 		 * ACK it right away.
233 		 */
234 		isp_notify_ack(isp, (status == IN_RESET)? NULL : local);
235 		switch (status) {
236 		case IN_RESET:
237 			(void) isp_async(isp, ISPASYNC_BUS_RESET, &bus);
238 			break;
239 		case IN_MSG_RECEIVED:
240 		case IN_IDE_RECEIVED:
241 			if (IS_FC(isp)) {
242 				isp_got_msg_fc(isp, bus, (in_fcentry_t *)local);
243 			} else {
244 				isp_got_msg(isp, bus, (in_entry_t *)local);
245 			}
246 			break;
247 		case IN_RSRC_UNAVAIL:
248 			isp_prt(isp, ISP_LOGWARN, "Firmware out of ATIOs");
249 			break;
250 		case IN_ABORT_TASK:
251 			isp_prt(isp, ISP_LOGWARN,
252 			    "Abort Task from IID %d RX_ID 0x%x",
253 			    inot_fcp->in_iid, seqid);
254 			(void) isp_async(isp, ISPASYNC_TARGET_ACTION, &bus);
255 			break;
256 		case IN_PORT_LOGOUT:
257 			isp_prt(isp, ISP_LOGWARN,
258 			    "Port Logout for Initiator %d RX_ID 0x%x",
259 			    inot_fcp->in_iid, seqid);
260 			break;
261 		case IN_PORT_CHANGED:
262 			isp_prt(isp, ISP_LOGWARN,
263 			    "Port Changed for Initiator %d RX_ID 0x%x",
264 			    inot_fcp->in_iid, seqid);
265 			break;
266 		case IN_GLOBAL_LOGO:
267 			isp_prt(isp, ISP_LOGWARN, "All ports logged out");
268 			break;
269 		default:
270 			isp_prt(isp, ISP_LOGERR,
271 			    "bad status (0x%x) in isp_target_notify", status);
272 			break;
273 		}
274 		break;
275 
276 	case RQSTYPE_NOTIFY_ACK:
277 		/*
278 		 * The ISP is acknowledging our acknowledgement of an
279 		 * Immediate Notify entry for some asynchronous event.
280 		 */
281 		if (IS_FC(isp)) {
282 			isp_get_notify_ack_fc(isp, nack_fcp,
283 			    (na_fcentry_t *)local);
284 			nack_fcp = (na_fcentry_t *)local;
285 			isp_prt(isp, ISP_LOGTDEBUG1,
286 			    "Notify Ack status=0x%x seqid 0x%x",
287 			    nack_fcp->na_status, nack_fcp->na_seqid);
288 		} else {
289 			isp_get_notify_ack(isp, nackp, (na_entry_t *)local);
290 			nackp = (na_entry_t *)local;
291 			isp_prt(isp, ISP_LOGTDEBUG1,
292 			    "Notify Ack event 0x%x status=0x%x seqid 0x%x",
293 			    nackp->na_event, nackp->na_status, nackp->na_seqid);
294 		}
295 		break;
296 	default:
297 		isp_prt(isp, ISP_LOGERR,
298 		    "Unknown entry type 0x%x in isp_target_notify", type);
299 		rval = -1;
300 		break;
301 	}
302 #undef	atiop
303 #undef	at2iop
304 #undef	ctiop
305 #undef	ct2iop
306 #undef	lunenp
307 #undef	inotp
308 #undef	inot_fcp
309 #undef	nackp
310 #undef	nack_fcp
311 #undef	hdrp
312 	return (rval);
313 }
314 
315 
316 /*
317  * Toggle (on/off) target mode for bus/target/lun
318  *
319  * The caller has checked for overlap and legality.
320  *
321  * Note that not all of bus, target or lun can be paid attention to.
322  * Note also that this action will not be complete until the f/w writes
323  * response entry. The caller is responsible for synchronizing this.
324  */
325 int
326 isp_lun_cmd(struct ispsoftc *isp, int cmd, int bus, int tgt, int lun,
327     int cmd_cnt, int inot_cnt, u_int32_t opaque)
328 {
329 	lun_entry_t el;
330 	u_int16_t nxti, optr;
331 	void *outp;
332 
333 
334 	MEMZERO(&el, sizeof (el));
335 	if (IS_DUALBUS(isp)) {
336 		el.le_rsvd = (bus & 0x1) << 7;
337 	}
338 	el.le_cmd_count = cmd_cnt;
339 	el.le_in_count = inot_cnt;
340 	if (cmd == RQSTYPE_ENABLE_LUN) {
341 		if (IS_SCSI(isp)) {
342 			el.le_flags = LUN_TQAE|LUN_DISAD;
343 			el.le_cdb6len = 12;
344 			el.le_cdb7len = 12;
345 		}
346 	} else if (cmd == -RQSTYPE_ENABLE_LUN) {
347 		cmd = RQSTYPE_ENABLE_LUN;
348 		el.le_cmd_count = 0;
349 		el.le_in_count = 0;
350 	} else if (cmd == -RQSTYPE_MODIFY_LUN) {
351 		cmd = RQSTYPE_MODIFY_LUN;
352 		el.le_ops = LUN_CCDECR | LUN_INDECR;
353 	} else {
354 		el.le_ops = LUN_CCINCR | LUN_ININCR;
355 	}
356 	el.le_header.rqs_entry_type = cmd;
357 	el.le_header.rqs_entry_count = 1;
358 	el.le_reserved = opaque;
359 	if (IS_SCSI(isp)) {
360 		el.le_tgt = tgt;
361 		el.le_lun = lun;
362 	} else if ((FCPARAM(isp)->isp_fwattr & ISP_FW_ATTR_SCCLUN) == 0) {
363 		el.le_lun = lun;
364 	}
365 	el.le_timeout = 2;
366 
367 	if (isp_getrqentry(isp, &nxti, &optr, &outp)) {
368 		isp_prt(isp, ISP_LOGERR,
369 		    "Request Queue Overflow in isp_lun_cmd");
370 		return (-1);
371 	}
372 	ISP_TDQE(isp, "isp_lun_cmd", (int) optr, &el);
373 	isp_put_enable_lun(isp, &el, outp);
374 	ISP_ADD_REQUEST(isp, nxti);
375 	return (0);
376 }
377 
378 
379 int
380 isp_target_put_entry(struct ispsoftc *isp, void *ap)
381 {
382 	void *outp;
383 	u_int16_t nxti, optr;
384 	u_int8_t etype = ((isphdr_t *) ap)->rqs_entry_type;
385 
386 	if (isp_getrqentry(isp, &nxti, &optr, &outp)) {
387 		isp_prt(isp, ISP_LOGWARN,
388 		    "Request Queue Overflow in isp_target_put_entry");
389 		return (-1);
390 	}
391 	switch (etype) {
392 	case RQSTYPE_ATIO:
393 		isp_put_atio(isp, (at_entry_t *) ap, (at_entry_t *) outp);
394 		break;
395 	case RQSTYPE_ATIO2:
396 		isp_put_atio2(isp, (at2_entry_t *) ap, (at2_entry_t *) outp);
397 		break;
398 	case RQSTYPE_CTIO:
399 		isp_put_ctio(isp, (ct_entry_t *) ap, (ct_entry_t *) outp);
400 		break;
401 	case RQSTYPE_CTIO2:
402 		isp_put_ctio2(isp, (ct2_entry_t *) ap, (ct2_entry_t *) outp);
403 		break;
404 	default:
405 		isp_prt(isp, ISP_LOGERR,
406 		    "Unknown type 0x%x in isp_put_entry", etype);
407 		return (-1);
408 	}
409 
410 	ISP_TDQE(isp, "isp_target_put_entry", (int) optr, ap);;
411 	ISP_ADD_REQUEST(isp, nxti);
412 	return (0);
413 }
414 
415 int
416 isp_target_put_atio(struct ispsoftc *isp, void *arg)
417 {
418 	union {
419 		at_entry_t _atio;
420 		at2_entry_t _atio2;
421 	} atun;
422 
423 	MEMZERO(&atun, sizeof atun);
424 	if (IS_FC(isp)) {
425 		at2_entry_t *aep = arg;
426 		atun._atio2.at_header.rqs_entry_type = RQSTYPE_ATIO2;
427 		atun._atio2.at_header.rqs_entry_count = 1;
428 		if (FCPARAM(isp)->isp_fwattr & ISP_FW_ATTR_SCCLUN) {
429 			atun._atio2.at_scclun = (u_int16_t) aep->at_scclun;
430 		} else {
431 			atun._atio2.at_lun = (u_int8_t) aep->at_lun;
432 		}
433 		atun._atio2.at_status = CT_OK;
434 	} else {
435 		at_entry_t *aep = arg;
436 		atun._atio.at_header.rqs_entry_type = RQSTYPE_ATIO;
437 		atun._atio.at_header.rqs_entry_count = 1;
438 		atun._atio.at_handle = aep->at_handle;
439 		atun._atio.at_iid = aep->at_iid;
440 		atun._atio.at_tgt = aep->at_tgt;
441 		atun._atio.at_lun = aep->at_lun;
442 		atun._atio.at_tag_type = aep->at_tag_type;
443 		atun._atio.at_tag_val = aep->at_tag_val;
444 		atun._atio.at_status = (aep->at_flags & AT_TQAE);
445 		atun._atio.at_status |= CT_OK;
446 	}
447 	return (isp_target_put_entry(isp, &atun));
448 }
449 
450 /*
451  * Command completion- both for handling cases of no resources or
452  * no blackhole driver, or other cases where we have to, inline,
453  * finish the command sanely, or for normal command completion.
454  *
455  * The 'completion' code value has the scsi status byte in the low 8 bits.
456  * If status is a CHECK CONDITION and bit 8 is nonzero, then bits 12..15 have
457  * the sense key and  bits 16..23 have the ASCQ and bits 24..31 have the ASC
458  * values.
459  *
460  * NB: the key, asc, ascq, cannot be used for parallel SCSI as it doesn't
461  * NB: inline SCSI sense reporting. As such, we lose this information. XXX.
462  *
463  * For both parallel && fibre channel, we use the feature that does
464  * an automatic resource autoreplenish so we don't have then later do
465  * put of an atio to replenish the f/w's resource count.
466  */
467 
468 int
469 isp_endcmd(struct ispsoftc *isp, void *arg, u_int32_t code, u_int16_t hdl)
470 {
471 	int sts;
472 	union {
473 		ct_entry_t _ctio;
474 		ct2_entry_t _ctio2;
475 	} un;
476 
477 	MEMZERO(&un, sizeof un);
478 	sts = code & 0xff;
479 
480 	if (IS_FC(isp)) {
481 		at2_entry_t *aep = arg;
482 		ct2_entry_t *cto = &un._ctio2;
483 
484 		cto->ct_header.rqs_entry_type = RQSTYPE_CTIO2;
485 		cto->ct_header.rqs_entry_count = 1;
486 		cto->ct_iid = aep->at_iid;
487 		if ((FCPARAM(isp)->isp_fwattr & ISP_FW_ATTR_SCCLUN) == 0) {
488 			cto->ct_lun = aep->at_lun;
489 		}
490 		cto->ct_rxid = aep->at_rxid;
491 		cto->rsp.m1.ct_scsi_status = sts & 0xff;
492 		cto->ct_flags = CT2_SENDSTATUS | CT2_NO_DATA | CT2_FLAG_MODE1;
493 		if (hdl == 0) {
494 			cto->ct_flags |= CT2_CCINCR;
495 		}
496 		if (aep->at_datalen) {
497 			cto->ct_resid = aep->at_datalen;
498 			cto->rsp.m1.ct_scsi_status |= CT2_DATA_UNDER;
499 		}
500 		if ((sts & 0xff) == SCSI_CHECK && (sts & ECMD_SVALID)) {
501 			cto->rsp.m1.ct_resp[0] = 0xf0;
502 			cto->rsp.m1.ct_resp[2] = (code >> 12) & 0xf;
503 			cto->rsp.m1.ct_resp[7] = 8;
504 			cto->rsp.m1.ct_resp[12] = (code >> 24) & 0xff;
505 			cto->rsp.m1.ct_resp[13] = (code >> 16) & 0xff;
506 			cto->rsp.m1.ct_senselen = 16;
507 			cto->rsp.m1.ct_scsi_status |= CT2_SNSLEN_VALID;
508 		}
509 		cto->ct_syshandle = hdl;
510 	} else {
511 		at_entry_t *aep = arg;
512 		ct_entry_t *cto = &un._ctio;
513 
514 		cto->ct_header.rqs_entry_type = RQSTYPE_CTIO;
515 		cto->ct_header.rqs_entry_count = 1;
516 		cto->ct_fwhandle = aep->at_handle;
517 		cto->ct_iid = aep->at_iid;
518 		cto->ct_tgt = aep->at_tgt;
519 		cto->ct_lun = aep->at_lun;
520 		cto->ct_tag_type = aep->at_tag_type;
521 		cto->ct_tag_val = aep->at_tag_val;
522 		if (aep->at_flags & AT_TQAE) {
523 			cto->ct_flags |= CT_TQAE;
524 		}
525 		cto->ct_flags = CT_SENDSTATUS | CT_NO_DATA;
526 		if (hdl == 0) {
527 			cto->ct_flags |= CT_CCINCR;
528 		}
529 		cto->ct_scsi_status = sts;
530 		cto->ct_syshandle = hdl;
531 	}
532 	return (isp_target_put_entry(isp, &un));
533 }
534 
535 void
536 isp_target_async(struct ispsoftc *isp, int bus, int event)
537 {
538 	tmd_event_t evt;
539 	tmd_msg_t msg;
540 
541 	switch (event) {
542 	/*
543 	 * These three we handle here to propagate an effective bus reset
544 	 * upstream, but these do not require any immediate notify actions
545 	 * so we return when done.
546 	 */
547 	case ASYNC_LIP_F8:
548 	case ASYNC_LIP_OCCURRED:
549 	case ASYNC_LOOP_UP:
550 	case ASYNC_LOOP_DOWN:
551 	case ASYNC_LOOP_RESET:
552 	case ASYNC_PTPMODE:
553 		/*
554 		 * These don't require any immediate notify actions. We used
555 		 * treat them like SCSI Bus Resets, but that was just plain
556 		 * wrong. Let the normal CTIO completion report what occurred.
557 		 */
558                 return;
559 
560 	case ASYNC_BUS_RESET:
561 	case ASYNC_TIMEOUT_RESET:
562 		if (IS_FC(isp)) {
563 			return;	/* we'll be getting an inotify instead */
564 		}
565 		evt.ev_bus = bus;
566 		evt.ev_event = event;
567 		(void) isp_async(isp, ISPASYNC_TARGET_EVENT, &evt);
568 		break;
569 	case ASYNC_DEVICE_RESET:
570 		/*
571 		 * Bus Device Reset resets a specific target, so
572 		 * we pass this as a synthesized message.
573 		 */
574 		MEMZERO(&msg, sizeof msg);
575 		if (IS_FC(isp)) {
576 			msg.nt_iid = FCPARAM(isp)->isp_loopid;
577 		} else {
578 			msg.nt_iid = SDPARAM(isp)->isp_initiator_id;
579 		}
580 		msg.nt_bus = bus;
581 		msg.nt_msg[0] = MSG_BUS_DEV_RESET;
582 		(void) isp_async(isp, ISPASYNC_TARGET_MESSAGE, &msg);
583 		break;
584 	default:
585 		isp_prt(isp, ISP_LOGERR,
586 		    "isp_target_async: unknown event 0x%x", event);
587 		break;
588 	}
589 	if (isp->isp_state == ISP_RUNSTATE)
590 		isp_notify_ack(isp, NULL);
591 }
592 
593 
594 /*
595  * Process a received message.
596  * The ISP firmware can handle most messages, there are only
597  * a few that we need to deal with:
598  * - abort: clean up the current command
599  * - abort tag and clear queue
600  */
601 
602 static void
603 isp_got_msg(struct ispsoftc *isp, int bus, in_entry_t *inp)
604 {
605 	u_int8_t status = inp->in_status & ~QLTM_SVALID;
606 
607 	if (status == IN_IDE_RECEIVED || status == IN_MSG_RECEIVED) {
608 		tmd_msg_t msg;
609 
610 		MEMZERO(&msg, sizeof (msg));
611 		msg.nt_bus = bus;
612 		msg.nt_iid = inp->in_iid;
613 		msg.nt_tgt = inp->in_tgt;
614 		msg.nt_lun = inp->in_lun;
615 		msg.nt_tagtype = inp->in_tag_type;
616 		msg.nt_tagval = inp->in_tag_val;
617 		MEMCPY(msg.nt_msg, inp->in_msg, IN_MSGLEN);
618 		(void) isp_async(isp, ISPASYNC_TARGET_MESSAGE, &msg);
619 	} else {
620 		isp_prt(isp, ISP_LOGERR,
621 		    "unknown immediate notify status 0x%x", inp->in_status);
622 	}
623 }
624 
625 /*
626  * Synthesize a message from the task management flags in a FCP_CMND_IU.
627  */
628 static void
629 isp_got_msg_fc(struct ispsoftc *isp, int bus, in_fcentry_t *inp)
630 {
631 	int lun;
632 	static const char f1[] = "%s from iid %d lun %d seq 0x%x";
633 	static const char f2[] =
634 	    "unknown %s 0x%x lun %d iid %d task flags 0x%x seq 0x%x\n";
635 
636 	if (FCPARAM(isp)->isp_fwattr & ISP_FW_ATTR_SCCLUN) {
637 		lun = inp->in_scclun;
638 	} else {
639 		lun = inp->in_lun;
640 	}
641 
642 	if (inp->in_status != IN_MSG_RECEIVED) {
643 		isp_prt(isp, ISP_LOGINFO, f2, "immediate notify status",
644 		    inp->in_status, lun, inp->in_iid,
645 		    inp->in_task_flags,  inp->in_seqid);
646 	} else {
647 		tmd_msg_t msg;
648 
649 		MEMZERO(&msg, sizeof (msg));
650 		msg.nt_bus = bus;
651 		msg.nt_iid = inp->in_iid;
652 		msg.nt_tagval = inp->in_seqid;
653 		msg.nt_lun = lun;
654 
655 		if (inp->in_task_flags & TASK_FLAGS_ABORT_TASK) {
656 			isp_prt(isp, ISP_LOGINFO, f1, "ABORT TASK",
657 			    inp->in_iid, msg.nt_lun, inp->in_seqid);
658 			msg.nt_msg[0] = MSG_ABORT_TAG;
659 		} else if (inp->in_task_flags & TASK_FLAGS_CLEAR_TASK_SET) {
660 			isp_prt(isp, ISP_LOGINFO, f1, "CLEAR TASK SET",
661 			    inp->in_iid, msg.nt_lun, inp->in_seqid);
662 			msg.nt_msg[0] = MSG_CLEAR_QUEUE;
663 		} else if (inp->in_task_flags & TASK_FLAGS_TARGET_RESET) {
664 			isp_prt(isp, ISP_LOGINFO, f1, "TARGET RESET",
665 			    inp->in_iid, msg.nt_lun, inp->in_seqid);
666 			msg.nt_msg[0] = MSG_BUS_DEV_RESET;
667 		} else if (inp->in_task_flags & TASK_FLAGS_CLEAR_ACA) {
668 			isp_prt(isp, ISP_LOGINFO, f1, "CLEAR ACA",
669 			    inp->in_iid, msg.nt_lun, inp->in_seqid);
670 			/* ???? */
671 			msg.nt_msg[0] = MSG_REL_RECOVERY;
672 		} else if (inp->in_task_flags & TASK_FLAGS_TERMINATE_TASK) {
673 			isp_prt(isp, ISP_LOGINFO, f1, "TERMINATE TASK",
674 			    inp->in_iid, msg.nt_lun, inp->in_seqid);
675 			msg.nt_msg[0] = MSG_TERM_IO_PROC;
676 		} else {
677 			isp_prt(isp, ISP_LOGWARN, f2, "task flag",
678 			    inp->in_status, msg.nt_lun, inp->in_iid,
679 			    inp->in_task_flags,  inp->in_seqid);
680 		}
681 		if (msg.nt_msg[0]) {
682 			(void) isp_async(isp, ISPASYNC_TARGET_MESSAGE, &msg);
683 		}
684 	}
685 }
686 
687 static void
688 isp_notify_ack(struct ispsoftc *isp, void *arg)
689 {
690 	char storage[QENTRY_LEN];
691 	u_int16_t nxti, optr;
692 	void *outp;
693 
694 	if (isp_getrqentry(isp, &nxti, &optr, &outp)) {
695 		isp_prt(isp, ISP_LOGWARN,
696 		    "Request Queue Overflow For isp_notify_ack");
697 		return;
698 	}
699 
700 	MEMZERO(storage, QENTRY_LEN);
701 
702 	if (IS_FC(isp)) {
703 		na_fcentry_t *na = (na_fcentry_t *) storage;
704 		if (arg) {
705 			in_fcentry_t *inp = arg;
706 			MEMCPY(storage, arg, sizeof (isphdr_t));
707 			na->na_iid = inp->in_iid;
708 			if (FCPARAM(isp)->isp_fwattr & ISP_FW_ATTR_SCCLUN) {
709 				na->na_lun = inp->in_scclun;
710 			} else {
711 				na->na_lun = inp->in_lun;
712 			}
713 			na->na_task_flags = inp->in_task_flags;
714 			na->na_seqid = inp->in_seqid;
715 			na->na_flags = NAFC_RCOUNT;
716 			na->na_status = inp->in_status;
717 			if (inp->in_status == IN_RESET) {
718 				na->na_flags |= NAFC_RST_CLRD;
719 			}
720 		} else {
721 			na->na_flags = NAFC_RST_CLRD;
722 		}
723 		na->na_header.rqs_entry_type = RQSTYPE_NOTIFY_ACK;
724 		na->na_header.rqs_entry_count = 1;
725 		isp_put_notify_ack_fc(isp, na, (na_fcentry_t *)outp);
726 	} else {
727 		na_entry_t *na = (na_entry_t *) storage;
728 		if (arg) {
729 			in_entry_t *inp = arg;
730 			MEMCPY(storage, arg, sizeof (isphdr_t));
731 			na->na_iid = inp->in_iid;
732 			na->na_lun = inp->in_lun;
733 			na->na_tgt = inp->in_tgt;
734 			na->na_seqid = inp->in_seqid;
735 			if (inp->in_status == IN_RESET) {
736 				na->na_event = NA_RST_CLRD;
737 			}
738 		} else {
739 			na->na_event = NA_RST_CLRD;
740 		}
741 		na->na_header.rqs_entry_type = RQSTYPE_NOTIFY_ACK;
742 		na->na_header.rqs_entry_count = 1;
743 		isp_put_notify_ack(isp, na, (na_entry_t *)outp);
744 	}
745 	ISP_TDQE(isp, "isp_notify_ack", (int) optr, storage);
746 	ISP_ADD_REQUEST(isp, nxti);
747 }
748 
749 static void
750 isp_handle_atio(struct ispsoftc *isp, at_entry_t *aep)
751 {
752 	int lun;
753 	lun = aep->at_lun;
754 	/*
755 	 * The firmware status (except for the QLTM_SVALID bit) indicates
756 	 * why this ATIO was sent to us.
757 	 *
758 	 * If QLTM_SVALID is set, the firware has recommended Sense Data.
759 	 *
760 	 * If the DISCONNECTS DISABLED bit is set in the flags field,
761 	 * we're still connected on the SCSI bus - i.e. the initiator
762 	 * did not set DiscPriv in the identify message. We don't care
763 	 * about this so it's ignored.
764 	 */
765 
766 	switch(aep->at_status & ~QLTM_SVALID) {
767 	case AT_PATH_INVALID:
768 		/*
769 		 * ATIO rejected by the firmware due to disabled lun.
770 		 */
771 		isp_prt(isp, ISP_LOGERR,
772 		    "rejected ATIO for disabled lun %d", lun);
773 		break;
774 	case AT_NOCAP:
775 		/*
776 		 * Requested Capability not available
777 		 * We sent an ATIO that overflowed the firmware's
778 		 * command resource count.
779 		 */
780 		isp_prt(isp, ISP_LOGERR,
781 		    "rejected ATIO for lun %d because of command count"
782 		    " overflow", lun);
783 		break;
784 
785 	case AT_BDR_MSG:
786 		/*
787 		 * If we send an ATIO to the firmware to increment
788 		 * its command resource count, and the firmware is
789 		 * recovering from a Bus Device Reset, it returns
790 		 * the ATIO with this status. We set the command
791 		 * resource count in the Enable Lun entry and do
792 		 * not increment it. Therefore we should never get
793 		 * this status here.
794 		 */
795 		isp_prt(isp, ISP_LOGERR, atiocope, lun,
796 		    GET_BUS_VAL(aep->at_iid));
797 		break;
798 
799 	case AT_CDB:		/* Got a CDB */
800 	case AT_PHASE_ERROR:	/* Bus Phase Sequence Error */
801 		/*
802 		 * Punt to platform specific layer.
803 		 */
804 		(void) isp_async(isp, ISPASYNC_TARGET_ACTION, aep);
805 		break;
806 
807 	case AT_RESET:
808 		/*
809 		 * A bus reset came along an blew away this command. Why
810 		 * they do this in addition the async event code stuff,
811 		 * I dunno.
812 		 *
813 		 * Ignore it because the async event will clear things
814 		 * up for us.
815 		 */
816 		isp_prt(isp, ISP_LOGWARN, atior, lun,
817 		    GET_IID_VAL(aep->at_iid), GET_BUS_VAL(aep->at_iid));
818 		break;
819 
820 
821 	default:
822 		isp_prt(isp, ISP_LOGERR,
823 		    "Unknown ATIO status 0x%x from initiator %d for lun %d",
824 		    aep->at_status, aep->at_iid, lun);
825 		(void) isp_target_put_atio(isp, aep);
826 		break;
827 	}
828 }
829 
830 static void
831 isp_handle_atio2(struct ispsoftc *isp, at2_entry_t *aep)
832 {
833 	int lun;
834 
835 	if (FCPARAM(isp)->isp_fwattr & ISP_FW_ATTR_SCCLUN) {
836 		lun = aep->at_scclun;
837 	} else {
838 		lun = aep->at_lun;
839 	}
840 
841 	/*
842 	 * The firmware status (except for the QLTM_SVALID bit) indicates
843 	 * why this ATIO was sent to us.
844 	 *
845 	 * If QLTM_SVALID is set, the firware has recommended Sense Data.
846 	 *
847 	 * If the DISCONNECTS DISABLED bit is set in the flags field,
848 	 * we're still connected on the SCSI bus - i.e. the initiator
849 	 * did not set DiscPriv in the identify message. We don't care
850 	 * about this so it's ignored.
851 	 */
852 
853 	switch(aep->at_status & ~QLTM_SVALID) {
854 	case AT_PATH_INVALID:
855 		/*
856 		 * ATIO rejected by the firmware due to disabled lun.
857 		 */
858 		isp_prt(isp, ISP_LOGERR,
859 		    "rejected ATIO2 for disabled lun %d", lun);
860 		break;
861 	case AT_NOCAP:
862 		/*
863 		 * Requested Capability not available
864 		 * We sent an ATIO that overflowed the firmware's
865 		 * command resource count.
866 		 */
867 		isp_prt(isp, ISP_LOGERR,
868 		    "rejected ATIO2 for lun %d- command count overflow", lun);
869 		break;
870 
871 	case AT_BDR_MSG:
872 		/*
873 		 * If we send an ATIO to the firmware to increment
874 		 * its command resource count, and the firmware is
875 		 * recovering from a Bus Device Reset, it returns
876 		 * the ATIO with this status. We set the command
877 		 * resource count in the Enable Lun entry and no
878 		 * not increment it. Therefore we should never get
879 		 * this status here.
880 		 */
881 		isp_prt(isp, ISP_LOGERR, atiocope, lun, 0);
882 		break;
883 
884 	case AT_CDB:		/* Got a CDB */
885 		/*
886 		 * Punt to platform specific layer.
887 		 */
888 		(void) isp_async(isp, ISPASYNC_TARGET_ACTION, aep);
889 		break;
890 
891 	case AT_RESET:
892 		/*
893 		 * A bus reset came along an blew away this command. Why
894 		 * they do this in addition the async event code stuff,
895 		 * I dunno.
896 		 *
897 		 * Ignore it because the async event will clear things
898 		 * up for us.
899 		 */
900 		isp_prt(isp, ISP_LOGERR, atior, lun, aep->at_iid, 0);
901 		break;
902 
903 
904 	default:
905 		isp_prt(isp, ISP_LOGERR,
906 		    "Unknown ATIO2 status 0x%x from initiator %d for lun %d",
907 		    aep->at_status, aep->at_iid, lun);
908 		(void) isp_target_put_atio(isp, aep);
909 		break;
910 	}
911 }
912 
913 static void
914 isp_handle_ctio(struct ispsoftc *isp, ct_entry_t *ct)
915 {
916 	void *xs;
917 	int pl = ISP_LOGTDEBUG2;
918 	char *fmsg = NULL;
919 
920 	if (ct->ct_syshandle) {
921 		xs = isp_find_xs(isp, ct->ct_syshandle);
922 		if (xs == NULL)
923 			pl = ISP_LOGALL;
924 	} else {
925 		xs = NULL;
926 	}
927 
928 	switch(ct->ct_status & ~QLTM_SVALID) {
929 	case CT_OK:
930 		/*
931 		 * There are generally 3 possibilities as to why we'd get
932 		 * this condition:
933 		 * 	We disconnected after receiving a CDB.
934 		 * 	We sent or received data.
935 		 * 	We sent status & command complete.
936 		 */
937 
938 		if (ct->ct_flags & CT_SENDSTATUS) {
939 			break;
940 		} else if ((ct->ct_flags & CT_DATAMASK) == CT_NO_DATA) {
941 			/*
942 			 * Nothing to do in this case.
943 			 */
944 			isp_prt(isp, pl, "CTIO- iid %d disconnected OK",
945 			    ct->ct_iid);
946 			return;
947 		}
948 		break;
949 
950 	case CT_BDR_MSG:
951 		/*
952 		 * Bus Device Reset message received or the SCSI Bus has
953 		 * been Reset; the firmware has gone to Bus Free.
954 		 *
955 		 * The firmware generates an async mailbox interupt to
956 		 * notify us of this and returns outstanding CTIOs with this
957 		 * status. These CTIOs are handled in that same way as
958 		 * CT_ABORTED ones, so just fall through here.
959 		 */
960 		fmsg = "Bus Device Reset";
961 		/*FALLTHROUGH*/
962 	case CT_RESET:
963 		if (fmsg == NULL)
964 			fmsg = "Bus Reset";
965 		/*FALLTHROUGH*/
966 	case CT_ABORTED:
967 		/*
968 		 * When an Abort message is received the firmware goes to
969 		 * Bus Free and returns all outstanding CTIOs with the status
970 		 * set, then sends us an Immediate Notify entry.
971 		 */
972 		if (fmsg == NULL)
973 			fmsg = "ABORT TAG message sent by Initiator";
974 
975 		isp_prt(isp, ISP_LOGWARN, "CTIO destroyed by %s", fmsg);
976 		break;
977 
978 	case CT_INVAL:
979 		/*
980 		 * CTIO rejected by the firmware due to disabled lun.
981 		 * "Cannot Happen".
982 		 */
983 		isp_prt(isp, ISP_LOGERR,
984 		    "Firmware rejected CTIO for disabled lun %d",
985 		    ct->ct_lun);
986 		break;
987 
988 	case CT_NOPATH:
989 		/*
990 		 * CTIO rejected by the firmware due "no path for the
991 		 * nondisconnecting nexus specified". This means that
992 		 * we tried to access the bus while a non-disconnecting
993 		 * command is in process.
994 		 */
995 		isp_prt(isp, ISP_LOGERR,
996 		    "Firmware rejected CTIO for bad nexus %d/%d/%d",
997 		    ct->ct_iid, ct->ct_tgt, ct->ct_lun);
998 		break;
999 
1000 	case CT_RSELTMO:
1001 		fmsg = "Reselection";
1002 		/*FALLTHROUGH*/
1003 	case CT_TIMEOUT:
1004 		if (fmsg == NULL)
1005 			fmsg = "Command";
1006 		isp_prt(isp, ISP_LOGERR, "Firmware timed out on %s", fmsg);
1007 		break;
1008 
1009 	case	CT_PANIC:
1010 		if (fmsg == NULL)
1011 			fmsg = "Unrecoverable Error";
1012 		/*FALLTHROUGH*/
1013 	case CT_ERR:
1014 		if (fmsg == NULL)
1015 			fmsg = "Completed with Error";
1016 		/*FALLTHROUGH*/
1017 	case CT_PHASE_ERROR:
1018 		if (fmsg == NULL)
1019 			fmsg = "Phase Sequence Error";
1020 		/*FALLTHROUGH*/
1021 	case CT_TERMINATED:
1022 		if (fmsg == NULL)
1023 			fmsg = "terminated by TERMINATE TRANSFER";
1024 		/*FALLTHROUGH*/
1025 	case CT_NOACK:
1026 		if (fmsg == NULL)
1027 			fmsg = "unacknowledged Immediate Notify pending";
1028 		isp_prt(isp, ISP_LOGERR, "CTIO returned by f/w- %s", fmsg);
1029 		break;
1030 	default:
1031 		isp_prt(isp, ISP_LOGERR, "Unknown CTIO status 0x%x",
1032 		    ct->ct_status & ~QLTM_SVALID);
1033 		break;
1034 	}
1035 
1036 	if (xs == NULL) {
1037 		/*
1038 		 * There may be more than one CTIO for a data transfer,
1039 		 * or this may be a status CTIO we're not monitoring.
1040 		 *
1041 		 * The assumption is that they'll all be returned in the
1042 		 * order we got them.
1043 		 */
1044 		if (ct->ct_syshandle == 0) {
1045 			if ((ct->ct_flags & CT_SENDSTATUS) == 0) {
1046 				isp_prt(isp, pl,
1047 				    "intermediate CTIO completed ok");
1048 			} else {
1049 				isp_prt(isp, pl,
1050 				    "unmonitored CTIO completed ok");
1051 			}
1052 		} else {
1053 			isp_prt(isp, pl,
1054 			    "NO xs for CTIO (handle 0x%x) status 0x%x",
1055 			    ct->ct_syshandle, ct->ct_status & ~QLTM_SVALID);
1056 		}
1057 	} else {
1058 		/*
1059 		 * Final CTIO completed. Release DMA resources and
1060 		 * notify platform dependent layers.
1061 		 */
1062 		if ((ct->ct_flags & CT_DATAMASK) != CT_NO_DATA) {
1063 			ISP_DMAFREE(isp, xs, ct->ct_syshandle);
1064 		}
1065 		isp_prt(isp, pl, "final CTIO complete");
1066 		/*
1067 		 * The platform layer will destroy the handle if appropriate.
1068 		 */
1069 		(void) isp_async(isp, ISPASYNC_TARGET_ACTION, ct);
1070 	}
1071 }
1072 
1073 static void
1074 isp_handle_ctio2(struct ispsoftc *isp, ct2_entry_t *ct)
1075 {
1076 	XS_T *xs;
1077 	int pl = ISP_LOGTDEBUG2;
1078 	char *fmsg = NULL;
1079 
1080 	if (ct->ct_syshandle) {
1081 		xs = isp_find_xs(isp, ct->ct_syshandle);
1082 		if (xs == NULL)
1083 			pl = ISP_LOGALL;
1084 	} else {
1085 		xs = NULL;
1086 	}
1087 
1088 	switch(ct->ct_status & ~QLTM_SVALID) {
1089 	case CT_BUS_ERROR:
1090 		isp_prt(isp, ISP_LOGERR, "PCI DMA Bus Error");
1091 		/* FALL Through */
1092 	case CT_DATA_OVER:
1093 	case CT_DATA_UNDER:
1094 	case CT_OK:
1095 		/*
1096 		 * There are generally 2 possibilities as to why we'd get
1097 		 * this condition:
1098 		 * 	We sent or received data.
1099 		 * 	We sent status & command complete.
1100 		 */
1101 
1102 		break;
1103 
1104 	case CT_BDR_MSG:
1105 		/*
1106 		 * Target Reset function received.
1107 		 *
1108 		 * The firmware generates an async mailbox interupt to
1109 		 * notify us of this and returns outstanding CTIOs with this
1110 		 * status. These CTIOs are handled in that same way as
1111 		 * CT_ABORTED ones, so just fall through here.
1112 		 */
1113 		fmsg = "TARGET RESET Task Management Function Received";
1114 		/*FALLTHROUGH*/
1115 	case CT_RESET:
1116 		if (fmsg == NULL)
1117 			fmsg = "LIP Reset";
1118 		/*FALLTHROUGH*/
1119 	case CT_ABORTED:
1120 		/*
1121 		 * When an Abort message is received the firmware goes to
1122 		 * Bus Free and returns all outstanding CTIOs with the status
1123 		 * set, then sends us an Immediate Notify entry.
1124 		 */
1125 		if (fmsg == NULL)
1126 			fmsg = "ABORT Task Management Function Received";
1127 
1128 		isp_prt(isp, ISP_LOGERR, "CTIO2 destroyed by %s", fmsg);
1129 		break;
1130 
1131 	case CT_INVAL:
1132 		/*
1133 		 * CTIO rejected by the firmware - invalid data direction.
1134 		 */
1135 		isp_prt(isp, ISP_LOGERR, "CTIO2 had wrong data directiond");
1136 		break;
1137 
1138 	case CT_RSELTMO:
1139 		fmsg = "failure to reconnect to initiator";
1140 		/*FALLTHROUGH*/
1141 	case CT_TIMEOUT:
1142 		if (fmsg == NULL)
1143 			fmsg = "command";
1144 		isp_prt(isp, ISP_LOGERR, "Firmware timed out on %s", fmsg);
1145 		break;
1146 
1147 	case CT_ERR:
1148 		fmsg = "Completed with Error";
1149 		/*FALLTHROUGH*/
1150 	case CT_LOGOUT:
1151 		if (fmsg == NULL)
1152 			fmsg = "Port Logout";
1153 		/*FALLTHROUGH*/
1154 	case CT_PORTNOTAVAIL:
1155 		if (fmsg == NULL)
1156 			fmsg = "Port not available";
1157 	case CT_PORTCHANGED:
1158 		if (fmsg == NULL)
1159 			fmsg = "Port Changed";
1160 	case CT_NOACK:
1161 		if (fmsg == NULL)
1162 			fmsg = "unacknowledged Immediate Notify pending";
1163 		isp_prt(isp, ISP_LOGERR, "CTIO returned by f/w- %s", fmsg);
1164 		break;
1165 
1166 	case CT_INVRXID:
1167 		/*
1168 		 * CTIO rejected by the firmware because an invalid RX_ID.
1169 		 * Just print a message.
1170 		 */
1171 		isp_prt(isp, ISP_LOGERR,
1172 		    "CTIO2 completed with Invalid RX_ID 0x%x", ct->ct_rxid);
1173 		break;
1174 
1175 	default:
1176 		isp_prt(isp, ISP_LOGERR, "Unknown CTIO2 status 0x%x",
1177 		    ct->ct_status & ~QLTM_SVALID);
1178 		break;
1179 	}
1180 
1181 	if (xs == NULL) {
1182 		/*
1183 		 * There may be more than one CTIO for a data transfer,
1184 		 * or this may be a status CTIO we're not monitoring.
1185 		 *
1186 		 * The assumption is that they'll all be returned in the
1187 		 * order we got them.
1188 		 */
1189 		if (ct->ct_syshandle == 0) {
1190 			if ((ct->ct_flags & CT_SENDSTATUS) == 0) {
1191 				isp_prt(isp, pl,
1192 				    "intermediate CTIO completed ok");
1193 			} else {
1194 				isp_prt(isp, pl,
1195 				    "unmonitored CTIO completed ok");
1196 			}
1197 		} else {
1198 			isp_prt(isp, pl,
1199 			    "NO xs for CTIO (handle 0x%x) status 0x%x",
1200 			    ct->ct_syshandle, ct->ct_status & ~QLTM_SVALID);
1201 		}
1202 	} else {
1203 		if ((ct->ct_flags & CT2_DATAMASK) != CT2_NO_DATA) {
1204 			ISP_DMAFREE(isp, xs, ct->ct_syshandle);
1205 		}
1206 		if (ct->ct_flags & CT_SENDSTATUS) {
1207 			/*
1208 			 * Sent status and command complete.
1209 			 *
1210 			 * We're now really done with this command, so we
1211 			 * punt to the platform dependent layers because
1212 			 * only there can we do the appropriate command
1213 			 * complete thread synchronization.
1214 			 */
1215 			isp_prt(isp, pl, "status CTIO complete");
1216 		} else {
1217 			/*
1218 			 * Final CTIO completed. Release DMA resources and
1219 			 * notify platform dependent layers.
1220 			 */
1221 			isp_prt(isp, pl, "data CTIO complete");
1222 		}
1223 		(void) isp_async(isp, ISPASYNC_TARGET_ACTION, ct);
1224 		/*
1225 		 * The platform layer will destroy the handle if appropriate.
1226 		 */
1227 	}
1228 }
1229 #endif
1230