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