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