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