isp_target.c revision 73319
1/* $FreeBSD: head/sys/dev/isp/isp_target.c 73319 2001-03-02 06:28:55Z 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 char *atiocope =
50    "ATIO returned for lun %d because it was in the middle of Bus Device Reset";
51static char *atior =
52    "ATIO returned for lun %d from initiator %d because a Bus Reset occurred";
53
54static void isp_got_msg __P((struct ispsoftc *, int, in_entry_t *));
55static void isp_got_msg_fc __P((struct ispsoftc *, int, in_fcentry_t *));
56static void isp_notify_ack __P((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(isp, vptr, optrp)
110	struct ispsoftc *isp;
111	void *vptr;
112	u_int16_t *optrp;
113{
114	u_int16_t status, seqid;
115	union {
116		at_entry_t	*atiop;
117		at2_entry_t	*at2iop;
118		ct_entry_t	*ctiop;
119		ct2_entry_t	*ct2iop;
120		lun_entry_t	*lunenp;
121		in_entry_t	*inotp;
122		in_fcentry_t	*inot_fcp;
123		na_entry_t	*nackp;
124		na_fcentry_t	*nack_fcp;
125		isphdr_t	*hp;
126		void *		*vp;
127#define	atiop		unp.atiop
128#define	at2iop		unp.at2iop
129#define	ctiop		unp.ctiop
130#define	ct2iop		unp.ct2iop
131#define	lunenp		unp.lunenp
132#define	inotp		unp.inotp
133#define	inot_fcp	unp.inot_fcp
134#define	nackp		unp.nackp
135#define	nack_fcp	unp.nack_fcp
136#define	hdrp		unp.hp
137	} unp;
138	int bus, rval = 0;
139
140	unp.vp = vptr;
141
142	ISP_TDQE(isp, "isp_target_notify", (int) *optrp, vptr);
143
144	switch(hdrp->rqs_entry_type) {
145	case RQSTYPE_ATIO:
146		isp_handle_atio(isp, atiop);
147		break;
148	case RQSTYPE_CTIO:
149		isp_handle_ctio(isp, ctiop);
150		break;
151	case RQSTYPE_ATIO2:
152		isp_handle_atio2(isp, at2iop);
153		break;
154	case RQSTYPE_CTIO2:
155		isp_handle_ctio2(isp, ct2iop);
156		break;
157	case RQSTYPE_ENABLE_LUN:
158	case RQSTYPE_MODIFY_LUN:
159		(void) isp_async(isp, ISPASYNC_TARGET_ACTION, vptr);
160		break;
161
162	case RQSTYPE_NOTIFY:
163		/*
164		 * Either the ISP received a SCSI message it can't
165		 * handle, or it's returning an Immed. Notify entry
166		 * we sent. We can send Immed. Notify entries to
167		 * increment the firmware's resource count for them
168		 * (we set this initially in the Enable Lun entry).
169		 */
170		bus = 0;
171		if (IS_FC(isp)) {
172			status = inot_fcp->in_status;
173			seqid = inot_fcp->in_seqid;
174		} else {
175			status = inotp->in_status & 0xff;
176			seqid = inotp->in_seqid;
177			if (IS_DUALBUS(isp)) {
178				bus = (inotp->in_iid & 0x80) >> 7;
179				inotp->in_iid &= ~0x80;
180			}
181		}
182		isp_prt(isp, ISP_LOGTDEBUG1,
183		    "Immediate Notify, status=0x%x seqid=0x%x", status, seqid);
184		switch (status) {
185		case IN_RESET:
186			(void) isp_async(isp, ISPASYNC_BUS_RESET, &bus);
187			break;
188		case IN_MSG_RECEIVED:
189		case IN_IDE_RECEIVED:
190			if (IS_FC(isp)) {
191				isp_got_msg_fc(isp, bus, vptr);
192			} else {
193				isp_got_msg(isp, bus, vptr);
194			}
195			break;
196		case IN_RSRC_UNAVAIL:
197			isp_prt(isp, ISP_LOGWARN, "Firmware out of ATIOs");
198			break;
199		case IN_ABORT_TASK:
200			isp_prt(isp, ISP_LOGWARN,
201			    "Abort Task for Initiator %d RX_ID 0x%x",
202			    inot_fcp->in_iid, seqid);
203			break;
204		case IN_PORT_LOGOUT:
205			isp_prt(isp, ISP_LOGWARN,
206			    "Port Logout for Initiator %d RX_ID 0x%x",
207			    inot_fcp->in_iid, seqid);
208			break;
209		case IN_PORT_CHANGED:
210			isp_prt(isp, ISP_LOGWARN,
211			    "Port Changed for Initiator %d RX_ID 0x%x",
212			    inot_fcp->in_iid, seqid);
213			break;
214		case IN_GLOBAL_LOGO:
215			isp_prt(isp, ISP_LOGWARN, "All ports logged out");
216			break;
217		default:
218			isp_prt(isp, ISP_LOGERR,
219			    "bad status (0x%x) in isp_target_notify", status);
220			break;
221		}
222		isp_notify_ack(isp, vptr);
223		break;
224
225	case RQSTYPE_NOTIFY_ACK:
226		/*
227		 * The ISP is acknowledging our acknowledgement of an
228		 * Immediate Notify entry for some asynchronous event.
229		 */
230		if (IS_FC(isp)) {
231			isp_prt(isp, ISP_LOGTDEBUG1,
232			    "Notify Ack status=0x%x seqid 0x%x",
233			    nack_fcp->na_status, nack_fcp->na_seqid);
234		} else {
235			isp_prt(isp, ISP_LOGTDEBUG1,
236			    "Notify Ack event 0x%x status=0x%x seqid 0x%x",
237			    nackp->na_event, nackp->na_status, nackp->na_seqid);
238		}
239		break;
240	default:
241		isp_prt(isp, ISP_LOGERR,
242		    "Unknown entry type 0x%x in isp_target_notify",
243		    hdrp->rqs_entry_type);
244		rval = -1;
245		break;
246	}
247#undef	atiop
248#undef	at2iop
249#undef	ctiop
250#undef	ct2iop
251#undef	lunenp
252#undef	inotp
253#undef	inot_fcp
254#undef	nackp
255#undef	nack_fcp
256#undef	hdrp
257	return (rval);
258}
259
260
261/*
262 * Toggle (on/off) target mode for bus/target/lun
263 *
264 * The caller has checked for overlap and legality.
265 *
266 * Note that not all of bus, target or lun can be paid attention to.
267 * Note also that this action will not be complete until the f/w writes
268 * response entry. The caller is responsible for synchronizing this.
269 */
270int
271isp_lun_cmd(isp, cmd, bus, tgt, lun, opaque)
272	struct ispsoftc *isp;
273	int cmd;
274	int bus;
275	int tgt;
276	int lun;
277	u_int32_t opaque;
278{
279	lun_entry_t el;
280	u_int16_t iptr, optr;
281	void *outp;
282
283
284	MEMZERO(&el, sizeof (el));
285	if (IS_DUALBUS(isp)) {
286		el.le_rsvd = (bus & 0x1) << 7;
287	}
288	el.le_cmd_count = DFLT_CMD_CNT;
289	el.le_in_count = DFLT_INOTIFY;
290	if (cmd == RQSTYPE_ENABLE_LUN) {
291		if (IS_SCSI(isp)) {
292			el.le_flags = LUN_TQAE|LUN_DISAD;
293			el.le_cdb6len = 12;
294			el.le_cdb7len = 12;
295		}
296	} else if (cmd == -RQSTYPE_ENABLE_LUN) {
297		cmd = RQSTYPE_ENABLE_LUN;
298		el.le_cmd_count = 0;
299		el.le_in_count = 0;
300	} else if (cmd == -RQSTYPE_MODIFY_LUN) {
301		cmd = RQSTYPE_MODIFY_LUN;
302		el.le_ops = LUN_CCDECR | LUN_INDECR;
303	} else {
304		el.le_ops = LUN_CCINCR | LUN_ININCR;
305	}
306	el.le_header.rqs_entry_type = cmd;
307	el.le_header.rqs_entry_count = 1;
308	el.le_reserved = opaque;
309	if (IS_SCSI(isp)) {
310		el.le_tgt = tgt;
311		el.le_lun = lun;
312	} else if (isp->isp_maxluns <= 16) {
313		el.le_lun = lun;
314	}
315
316	if (isp_getrqentry(isp, &iptr, &optr, &outp)) {
317		isp_prt(isp, ISP_LOGWARN,
318		    "Request Queue Overflow in isp_lun_cmd");
319		return (-1);
320	}
321	ISP_SWIZ_ENABLE_LUN(isp, outp, &el);
322	ISP_TDQE(isp, "isp_lun_cmd", (int) optr, &el);
323	ISP_ADD_REQUEST(isp, iptr);
324	return (0);
325}
326
327
328int
329isp_target_put_entry(isp, ap)
330	struct ispsoftc *isp;
331	void *ap;
332{
333	void *outp;
334	u_int16_t iptr, optr;
335	u_int8_t etype = ((isphdr_t *) ap)->rqs_entry_type;
336
337	if (isp_getrqentry(isp, &iptr, &optr, &outp)) {
338		isp_prt(isp, ISP_LOGWARN,
339		    "Request Queue Overflow in isp_target_put_entry");
340		return (-1);
341	}
342	switch (etype) {
343	case RQSTYPE_ATIO:
344		ISP_SWIZ_ATIO(isp, outp, ap);
345		break;
346	case RQSTYPE_ATIO2:
347		ISP_SWIZ_ATIO2(isp, outp, ap);
348		break;
349	case RQSTYPE_CTIO:
350		ISP_SWIZ_CTIO(isp, outp, ap);
351		break;
352	case RQSTYPE_CTIO2:
353		ISP_SWIZ_CTIO2(isp, outp, ap);
354		break;
355	default:
356		isp_prt(isp, ISP_LOGERR,
357		    "Unknown type 0x%x in isp_put_entry", etype);
358		return (-1);
359	}
360
361	ISP_TDQE(isp, "isp_target_put_entry", (int) optr, ap);;
362
363	ISP_ADD_REQUEST(isp, iptr);
364	return (0);
365}
366
367int
368isp_target_put_atio(isp, iid, tgt, lun, ttype, tval)
369	struct ispsoftc *isp;
370	int iid;
371	int tgt;
372	int lun;
373	int ttype;
374	int tval;
375{
376	union {
377		at_entry_t _atio;
378		at2_entry_t _atio2;
379	} atun;
380
381	MEMZERO(&atun, sizeof atun);
382	if (IS_FC(isp)) {
383		atun._atio2.at_header.rqs_entry_type = RQSTYPE_ATIO2;
384		atun._atio2.at_header.rqs_entry_count = 1;
385		if (isp->isp_maxluns > 16) {
386			atun._atio2.at_scclun = (u_int16_t) lun;
387		} else {
388			atun._atio2.at_lun = (u_int8_t) lun;
389		}
390		atun._atio2.at_status = CT_OK;
391	} else {
392		atun._atio.at_header.rqs_entry_type = RQSTYPE_ATIO;
393		atun._atio.at_header.rqs_entry_count = 1;
394		atun._atio.at_iid = iid;
395		atun._atio.at_tgt = tgt;
396		atun._atio.at_lun = lun;
397		atun._atio.at_tag_type = ttype;
398		atun._atio.at_tag_val = tval;
399		atun._atio.at_status = CT_OK;
400	}
401	return (isp_target_put_entry(isp, &atun));
402}
403
404/*
405 * Command completion- both for handling cases of no resources or
406 * no blackhole driver, or other cases where we have to, inline,
407 * finish the command sanely, or for normal command completion.
408 *
409 * The 'completion' code value has the scsi status byte in the low 8 bits.
410 * If status is a CHECK CONDITION and bit 8 is nonzero, then bits 12..15 have
411 * the sense key and  bits 16..23 have the ASCQ and bits 24..31 have the ASC
412 * values.
413 *
414 * NB: the key, asc, ascq, cannot be used for parallel SCSI as it doesn't
415 * NB: inline SCSI sense reporting.
416 *
417 * For both parallel && fibre channel, we use the feature that does
418 * an automatic resource autoreplenish so we don't have then later do
419 * put of an atio to replenish the f/w's resource count.
420 */
421
422int
423isp_endcmd(struct ispsoftc *isp, void *arg, u_int32_t code, u_int16_t hdl)
424{
425	int sts;
426	union {
427		ct_entry_t _ctio;
428		ct2_entry_t _ctio2;
429	} un;
430
431	MEMZERO(&un, sizeof un);
432	sts = code & 0xff;
433
434	if (IS_FC(isp)) {
435		at2_entry_t *aep = arg;
436		ct2_entry_t *cto = &un._ctio2;
437
438		cto->ct_header.rqs_entry_type = RQSTYPE_CTIO2;
439		cto->ct_header.rqs_entry_count = 1;
440		cto->ct_iid = aep->at_iid;
441		if (isp->isp_maxluns <= 16) {
442			cto->ct_lun = aep->at_lun;
443		}
444		cto->ct_rxid = aep->at_rxid;
445		cto->rsp.m1.ct_scsi_status = sts & 0xff;
446		cto->ct_flags = CT2_SENDSTATUS | CT2_NO_DATA | CT2_FLAG_MODE1;
447		if (hdl == 0) {
448			cto->ct_flags |= CT2_CCINCR;
449		}
450		if (aep->at_datalen) {
451			cto->ct_resid = aep->at_datalen;
452			cto->ct_flags |= CT2_DATA_UNDER;
453		}
454		if ((sts & 0xff) == SCSI_CHECK && (sts & ECMD_SVALID)) {
455			cto->rsp.m1.ct_resp[0] = 0xf0;
456			cto->rsp.m1.ct_resp[2] = (code >> 12) & 0xf;
457			cto->rsp.m1.ct_resp[7] = 8;
458			cto->rsp.m1.ct_resp[12] = (code >> 24) & 0xff;
459			cto->rsp.m1.ct_resp[13] = (code >> 16) & 0xff;
460			cto->rsp.m1.ct_senselen = 16;
461			cto->ct_flags |= CT2_SNSLEN_VALID;
462		}
463		cto->ct_reserved = hdl;
464	} else {
465		at_entry_t *aep = arg;
466		ct_entry_t *cto = &un._ctio;
467
468		cto->ct_header.rqs_entry_type = RQSTYPE_CTIO;
469		cto->ct_header.rqs_entry_count = 1;
470		cto->ct_fwhandle = aep->at_handle;
471		cto->ct_iid = aep->at_iid;
472		cto->ct_tgt = aep->at_tgt;
473		cto->ct_lun = aep->at_lun;
474		cto->ct_tag_type = aep->at_tag_type;
475		cto->ct_tag_val = aep->at_tag_val;
476		cto->ct_flags = CT_SENDSTATUS | CT_NO_DATA;
477		if (hdl == 0) {
478			cto->ct_flags |= CT_CCINCR;
479		}
480		cto->ct_scsi_status = sts;
481		cto->ct_reserved = hdl;
482	}
483	return (isp_target_put_entry(isp, &un));
484}
485
486void
487isp_target_async(isp, bus, event)
488	struct ispsoftc *isp;
489	int bus;
490	int event;
491{
492	tmd_event_t evt;
493	tmd_msg_t msg;
494
495	switch (event) {
496	/*
497	 * These three we handle here to propagate an effective bus reset
498	 * upstream, but these do not require any immediate notify actions
499	 * so we return when done.
500	 */
501	case ASYNC_LIP_OCCURRED:
502	case ASYNC_LOOP_UP:
503	case ASYNC_LOOP_DOWN:
504		evt.ev_bus = bus;
505		evt.ev_event = event;
506		(void) isp_async(isp, ISPASYNC_TARGET_EVENT, &evt);
507		return;
508
509	case ASYNC_LOOP_RESET:
510	case ASYNC_BUS_RESET:
511	case ASYNC_TIMEOUT_RESET:
512		if (IS_FC(isp)) {
513			return;	/* we'll be getting an inotify instead */
514		}
515		evt.ev_bus = bus;
516		evt.ev_event = event;
517		(void) isp_async(isp, ISPASYNC_TARGET_EVENT, &evt);
518		break;
519	case ASYNC_DEVICE_RESET:
520		/*
521		 * Bus Device Reset resets a specific target, so
522		 * we pass this as a synthesized message.
523		 */
524		MEMZERO(&msg, sizeof msg);
525		if (IS_FC(isp)) {
526			msg.nt_iid = FCPARAM(isp)->isp_loopid;
527		} else {
528			msg.nt_iid = SDPARAM(isp)->isp_initiator_id;
529		}
530		msg.nt_bus = bus;
531		msg.nt_msg[0] = MSG_BUS_DEV_RESET;
532		(void) isp_async(isp, ISPASYNC_TARGET_MESSAGE, &msg);
533		break;
534	default:
535		isp_prt(isp, ISP_LOGERR,
536		    "isp_target_async: unknown event 0x%x", event);
537		break;
538	}
539	if (isp->isp_state == ISP_RUNSTATE)
540		isp_notify_ack(isp, NULL);
541}
542
543
544/*
545 * Process a received message.
546 * The ISP firmware can handle most messages, there are only
547 * a few that we need to deal with:
548 * - abort: clean up the current command
549 * - abort tag and clear queue
550 */
551
552static void
553isp_got_msg(isp, bus, inp)
554	struct ispsoftc *isp;
555	int bus;
556	in_entry_t *inp;
557{
558	u_int8_t status = inp->in_status & ~QLTM_SVALID;
559
560	if (status == IN_IDE_RECEIVED || status == IN_MSG_RECEIVED) {
561		tmd_msg_t msg;
562
563		MEMZERO(&msg, sizeof (msg));
564		msg.nt_bus = bus;
565		msg.nt_iid = inp->in_iid;
566		msg.nt_tgt = inp->in_tgt;
567		msg.nt_lun = inp->in_lun;
568		msg.nt_tagtype = inp->in_tag_type;
569		msg.nt_tagval = inp->in_tag_val;
570		MEMCPY(msg.nt_msg, inp->in_msg, IN_MSGLEN);
571		(void) isp_async(isp, ISPASYNC_TARGET_MESSAGE, &msg);
572	} else {
573		isp_prt(isp, ISP_LOGERR,
574		    "unknown immediate notify status 0x%x", inp->in_status);
575	}
576}
577
578/*
579 * Synthesize a message from the task management flags in a FCP_CMND_IU.
580 */
581static void
582isp_got_msg_fc(isp, bus, inp)
583	struct ispsoftc *isp;
584	int bus;
585	in_fcentry_t *inp;
586{
587	static char *f1 = "%s from iid %d lun %d seq 0x%x";
588	static char *f2 =
589	    "unknown %s 0x%x lun %d iid %d task flags 0x%x seq 0x%x\n";
590
591	if (inp->in_status != IN_MSG_RECEIVED) {
592		isp_prt(isp, ISP_LOGINFO, f2, "immediate notify status",
593		    inp->in_status, inp->in_lun, inp->in_iid,
594		    inp->in_task_flags,  inp->in_seqid);
595	} else {
596		tmd_msg_t msg;
597
598		MEMZERO(&msg, sizeof (msg));
599		msg.nt_bus = bus;
600		msg.nt_iid = inp->in_iid;
601		if (isp->isp_maxluns > 16) {
602			msg.nt_lun = inp->in_scclun;
603		} else {
604			msg.nt_lun = inp->in_lun;
605		}
606		msg.nt_tagval = inp->in_seqid;
607
608		if (inp->in_task_flags & TASK_FLAGS_ABORT_TASK) {
609			isp_prt(isp, ISP_LOGINFO, f1, "ABORT TASK",
610			    inp->in_iid, inp->in_lun, inp->in_seqid);
611			msg.nt_msg[0] = MSG_ABORT_TAG;
612		} else if (inp->in_task_flags & TASK_FLAGS_CLEAR_TASK_SET) {
613			isp_prt(isp, ISP_LOGINFO, f1, "CLEAR TASK SET",
614			    inp->in_iid, inp->in_lun, inp->in_seqid);
615			msg.nt_msg[0] = MSG_CLEAR_QUEUE;
616		} else if (inp->in_task_flags & TASK_FLAGS_TARGET_RESET) {
617			isp_prt(isp, ISP_LOGINFO, f1, "TARGET RESET",
618			    inp->in_iid, inp->in_lun, inp->in_seqid);
619			msg.nt_msg[0] = MSG_BUS_DEV_RESET;
620		} else if (inp->in_task_flags & TASK_FLAGS_CLEAR_ACA) {
621			isp_prt(isp, ISP_LOGINFO, f1, "CLEAR ACA",
622			    inp->in_iid, inp->in_lun, inp->in_seqid);
623			/* ???? */
624			msg.nt_msg[0] = MSG_REL_RECOVERY;
625		} else if (inp->in_task_flags & TASK_FLAGS_TERMINATE_TASK) {
626			isp_prt(isp, ISP_LOGINFO, f1, "TERMINATE TASK",
627			    inp->in_iid, inp->in_lun, inp->in_seqid);
628			msg.nt_msg[0] = MSG_TERM_IO_PROC;
629		} else {
630			isp_prt(isp, ISP_LOGWARN, f2, "task flag",
631			    inp->in_status, inp->in_lun, inp->in_iid,
632			    inp->in_task_flags,  inp->in_seqid);
633		}
634		if (msg.nt_msg[0]) {
635			(void) isp_async(isp, ISPASYNC_TARGET_MESSAGE, &msg);
636		}
637	}
638}
639
640static void
641isp_notify_ack(isp, arg)
642	struct ispsoftc *isp;
643	void *arg;
644{
645	char storage[QENTRY_LEN];
646	u_int16_t iptr, optr;
647	void *outp;
648
649	if (isp_getrqentry(isp, &iptr, &optr, &outp)) {
650		isp_prt(isp, ISP_LOGWARN,
651		    "Request Queue Overflow For isp_notify_ack");
652		return;
653	}
654
655	MEMZERO(storage, QENTRY_LEN);
656
657	if (IS_FC(isp)) {
658		na_fcentry_t *na = (na_fcentry_t *) storage;
659		if (arg) {
660			in_fcentry_t *inp = arg;
661			MEMCPY(storage, arg, sizeof (isphdr_t));
662			na->na_iid = inp->in_iid;
663			if (isp->isp_maxluns > 16) {
664				na->na_lun = inp->in_scclun;
665			} else {
666				na->na_lun = inp->in_lun;
667			}
668			na->na_task_flags = inp->in_task_flags;
669			na->na_seqid = inp->in_seqid;
670			na->na_flags = NAFC_RCOUNT;
671			if (inp->in_status == IN_RESET) {
672				na->na_flags |= NAFC_RST_CLRD;
673			}
674		} else {
675			na->na_flags = NAFC_RST_CLRD;
676		}
677		na->na_header.rqs_entry_type = RQSTYPE_NOTIFY_ACK;
678		na->na_header.rqs_entry_count = 1;
679		ISP_SWIZ_NOT_ACK_FC(isp, outp, na);
680	} else {
681		na_entry_t *na = (na_entry_t *) storage;
682		if (arg) {
683			in_entry_t *inp = arg;
684			MEMCPY(storage, arg, sizeof (isphdr_t));
685			na->na_iid = inp->in_iid;
686			na->na_lun = inp->in_lun;
687			na->na_tgt = inp->in_tgt;
688			na->na_seqid = inp->in_seqid;
689			if (inp->in_status == IN_RESET) {
690				na->na_event = NA_RST_CLRD;
691			}
692		} else {
693			na->na_event = NA_RST_CLRD;
694		}
695		na->na_header.rqs_entry_type = RQSTYPE_NOTIFY_ACK;
696		na->na_header.rqs_entry_count = 1;
697		ISP_SWIZ_NOT_ACK(isp, outp, na);
698	}
699	ISP_TDQE(isp, "isp_notify_ack", (int) optr, storage);
700	ISP_ADD_REQUEST(isp, iptr);
701}
702
703static void
704isp_handle_atio(isp, aep)
705	struct ispsoftc *isp;
706	at_entry_t *aep;
707{
708	int lun;
709	lun = aep->at_lun;
710	/*
711	 * The firmware status (except for the QLTM_SVALID bit) indicates
712	 * why this ATIO was sent to us.
713	 *
714	 * If QLTM_SVALID is set, the firware has recommended Sense Data.
715	 *
716	 * If the DISCONNECTS DISABLED bit is set in the flags field,
717	 * we're still connected on the SCSI bus - i.e. the initiator
718	 * did not set DiscPriv in the identify message. We don't care
719	 * about this so it's ignored.
720	 */
721
722	switch(aep->at_status & ~QLTM_SVALID) {
723	case AT_PATH_INVALID:
724		/*
725		 * ATIO rejected by the firmware due to disabled lun.
726		 */
727		isp_prt(isp, ISP_LOGERR,
728		    "rejected ATIO for disabled lun %d", lun);
729		break;
730	case AT_NOCAP:
731		/*
732		 * Requested Capability not available
733		 * We sent an ATIO that overflowed the firmware's
734		 * command resource count.
735		 */
736		isp_prt(isp, ISP_LOGERR,
737		    "rejected ATIO for lun %d because of command count"
738		    " overflow", lun);
739		break;
740
741	case AT_BDR_MSG:
742		/*
743		 * If we send an ATIO to the firmware to increment
744		 * its command resource count, and the firmware is
745		 * recovering from a Bus Device Reset, it returns
746		 * the ATIO with this status. We set the command
747		 * resource count in the Enable Lun entry and no
748		 * not increment it. Therefore we should never get
749		 * this status here.
750		 */
751		isp_prt(isp, ISP_LOGERR, atiocope, lun);
752		break;
753
754	case AT_CDB:		/* Got a CDB */
755	case AT_PHASE_ERROR:	/* Bus Phase Sequence Error */
756		/*
757		 * Punt to platform specific layer.
758		 */
759		(void) isp_async(isp, ISPASYNC_TARGET_ACTION, aep);
760		break;
761
762	case AT_RESET:
763		/*
764		 * A bus reset came along an blew away this command. Why
765		 * they do this in addition the async event code stuff,
766		 * I dunno.
767		 *
768		 * Ignore it because the async event will clear things
769		 * up for us.
770		 */
771		isp_prt(isp, ISP_LOGWARN, atior, lun, aep->at_iid);
772		break;
773
774
775	default:
776		isp_prt(isp, ISP_LOGERR,
777		    "Unknown ATIO status 0x%x from initiator %d for lun %d",
778		    aep->at_status, aep->at_iid, lun);
779		(void) isp_target_put_atio(isp, aep->at_iid, aep->at_tgt,
780		    lun, aep->at_tag_type, aep->at_tag_val);
781		break;
782	}
783}
784
785static void
786isp_handle_atio2(isp, aep)
787	struct ispsoftc *isp;
788	at2_entry_t *aep;
789{
790	int lun;
791
792	if (isp->isp_maxluns > 16) {
793		lun = aep->at_scclun;
794	} else {
795		lun = aep->at_lun;
796	}
797
798	/*
799	 * The firmware status (except for the QLTM_SVALID bit) indicates
800	 * why this ATIO was sent to us.
801	 *
802	 * If QLTM_SVALID is set, the firware has recommended Sense Data.
803	 *
804	 * If the DISCONNECTS DISABLED bit is set in the flags field,
805	 * we're still connected on the SCSI bus - i.e. the initiator
806	 * did not set DiscPriv in the identify message. We don't care
807	 * about this so it's ignored.
808	 */
809
810	switch(aep->at_status & ~QLTM_SVALID) {
811	case AT_PATH_INVALID:
812		/*
813		 * ATIO rejected by the firmware due to disabled lun.
814		 */
815		isp_prt(isp, ISP_LOGERR,
816		    "rejected ATIO2 for disabled lun %d", lun);
817		break;
818	case AT_NOCAP:
819		/*
820		 * Requested Capability not available
821		 * We sent an ATIO that overflowed the firmware's
822		 * command resource count.
823		 */
824		isp_prt(isp, ISP_LOGERR,
825		    "rejected ATIO2 for lun %d- command count overflow", lun);
826		break;
827
828	case AT_BDR_MSG:
829		/*
830		 * If we send an ATIO to the firmware to increment
831		 * its command resource count, and the firmware is
832		 * recovering from a Bus Device Reset, it returns
833		 * the ATIO with this status. We set the command
834		 * resource count in the Enable Lun entry and no
835		 * not increment it. Therefore we should never get
836		 * this status here.
837		 */
838		isp_prt(isp, ISP_LOGERR, atiocope, lun);
839		break;
840
841	case AT_CDB:		/* Got a CDB */
842		/*
843		 * Punt to platform specific layer.
844		 */
845		(void) isp_async(isp, ISPASYNC_TARGET_ACTION, aep);
846		break;
847
848	case AT_RESET:
849		/*
850		 * A bus reset came along an blew away this command. Why
851		 * they do this in addition the async event code stuff,
852		 * I dunno.
853		 *
854		 * Ignore it because the async event will clear things
855		 * up for us.
856		 */
857		isp_prt(isp, ISP_LOGERR, atior, lun, aep->at_iid);
858		break;
859
860
861	default:
862		isp_prt(isp, ISP_LOGERR,
863		    "Unknown ATIO2 status 0x%x from initiator %d for lun %d",
864		    aep->at_status, aep->at_iid, lun);
865		(void) isp_target_put_atio(isp, aep->at_iid, 0, lun, 0, 0);
866		break;
867	}
868}
869
870static void
871isp_handle_ctio(isp, ct)
872	struct ispsoftc *isp;
873	ct_entry_t *ct;
874{
875	XS_T *xs;
876	int pl = ISP_LOGTDEBUG2;
877	char *fmsg = NULL;
878
879	if (ct->ct_reserved) {
880		xs = isp_find_xs(isp, ct->ct_reserved);
881		if (xs == NULL)
882			pl = ISP_LOGALL;
883	} else {
884		pl = ISP_LOGTDEBUG1;
885		xs = NULL;
886	}
887
888	switch(ct->ct_status & ~QLTM_SVALID) {
889	case CT_OK:
890		/*
891		 * There are generally 3 possibilities as to why we'd get
892		 * this condition:
893		 * 	We disconnected after receiving a CDB.
894		 * 	We sent or received data.
895		 * 	We sent status & command complete.
896		 */
897
898		if (ct->ct_flags & CT_SENDSTATUS) {
899			break;
900		} else if ((ct->ct_flags & CT_DATAMASK) == CT_NO_DATA) {
901			/*
902			 * Nothing to do in this case.
903			 */
904			isp_prt(isp, pl, "CTIO- iid %d disconnected OK",
905			    ct->ct_iid);
906			return;
907		}
908		break;
909
910	case CT_BDR_MSG:
911		/*
912		 * Bus Device Reset message received or the SCSI Bus has
913		 * been Reset; the firmware has gone to Bus Free.
914		 *
915		 * The firmware generates an async mailbox interupt to
916		 * notify us of this and returns outstanding CTIOs with this
917		 * status. These CTIOs are handled in that same way as
918		 * CT_ABORTED ones, so just fall through here.
919		 */
920		fmsg = "Bus Device Reset";
921		/*FALLTHROUGH*/
922	case CT_RESET:
923		if (fmsg == NULL)
924			fmsg = "Bus Reset";
925		/*FALLTHROUGH*/
926	case CT_ABORTED:
927		/*
928		 * When an Abort message is received the firmware goes to
929		 * Bus Free and returns all outstanding CTIOs with the status
930		 * set, then sends us an Immediate Notify entry.
931		 */
932		if (fmsg == NULL)
933			fmsg = "ABORT TASK sent by Initiator";
934
935		isp_prt(isp, ISP_LOGWARN, "CTIO destroyed by %s", fmsg);
936		break;
937
938	case CT_INVAL:
939		/*
940		 * CTIO rejected by the firmware due to disabled lun.
941		 * "Cannot Happen".
942		 */
943		isp_prt(isp, ISP_LOGERR,
944		    "Firmware rejected CTIO for disabled lun %d",
945		    ct->ct_lun);
946		break;
947
948	case CT_NOPATH:
949		/*
950		 * CTIO rejected by the firmware due "no path for the
951		 * nondisconnecting nexus specified". This means that
952		 * we tried to access the bus while a non-disconnecting
953		 * command is in process.
954		 */
955		isp_prt(isp, ISP_LOGERR,
956		    "Firmware rejected CTIO for bad nexus %d/%d/%d",
957		    ct->ct_iid, ct->ct_tgt, ct->ct_lun);
958		break;
959
960	case CT_RSELTMO:
961		fmsg = "Reselection";
962		/*FALLTHROUGH*/
963	case CT_TIMEOUT:
964		if (fmsg == NULL)
965			fmsg = "Command";
966		isp_prt(isp, ISP_LOGERR, "Firmware timed out on %s", fmsg);
967		break;
968
969	case CT_ERR:
970		fmsg = "Completed with Error";
971		/*FALLTHROUGH*/
972	case CT_PHASE_ERROR:
973		if (fmsg == NULL)
974			fmsg = "Phase Sequence Error";
975		/*FALLTHROUGH*/
976	case CT_TERMINATED:
977		if (fmsg == NULL)
978			fmsg = "terminated by TERMINATE TRANSFER";
979		/*FALLTHROUGH*/
980	case CT_NOACK:
981		if (fmsg == NULL)
982			fmsg = "unacknowledged Immediate Notify pending";
983
984		isp_prt(isp, ISP_LOGERR, "CTIO returned by f/w- %s", fmsg);
985#if	0
986			if (status & SENSEVALID) {
987				bcopy((caddr_t) (cep + CTIO_SENSE_OFFSET),
988				    (caddr_t) &cdp->cd_sensedata,
989				    sizeof(scsi_sense_t));
990				cdp->cd_flags |= CDF_SENSEVALID;
991			}
992#endif
993		break;
994	default:
995		isp_prt(isp, ISP_LOGERR, "Unknown CTIO status 0x%x",
996		    ct->ct_status & ~QLTM_SVALID);
997		break;
998	}
999
1000	if (xs == NULL) {
1001		/*
1002		 * There may be more than one CTIO for a data transfer,
1003		 * or this may be a status CTIO we're not monitoring.
1004		 *
1005		 * The assumption is that they'll all be returned in the
1006		 * order we got them.
1007		 */
1008		if (ct->ct_reserved == 0) {
1009			if ((ct->ct_flags & CT_SENDSTATUS) == 0) {
1010				isp_prt(isp, pl,
1011				    "intermediate CTIO completed ok");
1012			} else {
1013				isp_prt(isp, pl,
1014				    "unmonitored CTIO completed ok");
1015			}
1016		} else {
1017			isp_prt(isp, pl,
1018			    "NO xs for CTIO (handle 0x%x) status 0x%x",
1019			    ct->ct_reserved, ct->ct_status & ~QLTM_SVALID);
1020		}
1021	} else {
1022		if (ct->ct_flags & CT_SENDSTATUS) {
1023			/*
1024			 * Sent status and command complete.
1025			 *
1026			 * We're now really done with this command, so we
1027			 * punt to the platform dependent layers because
1028			 * only there can we do the appropriate command
1029			 * complete thread synchronization.
1030			 */
1031			isp_prt(isp, pl, "status CTIO complete");
1032		} else {
1033			/*
1034			 * Final CTIO completed. Release DMA resources and
1035			 * notify platform dependent layers.
1036			 */
1037			isp_prt(isp, pl, "data CTIO complete");
1038			ISP_DMAFREE(isp, xs, ct->ct_reserved);
1039		}
1040		(void) isp_async(isp, ISPASYNC_TARGET_ACTION, ct);
1041		/*
1042		 * The platform layer will destroy the handle if appropriate.
1043		 */
1044	}
1045}
1046
1047static void
1048isp_handle_ctio2(isp, ct)
1049	struct ispsoftc *isp;
1050	ct2_entry_t *ct;
1051{
1052	XS_T *xs;
1053	int pl = ISP_LOGTDEBUG2;
1054	char *fmsg = NULL;
1055
1056	if (ct->ct_reserved) {
1057		xs = isp_find_xs(isp, ct->ct_reserved);
1058		if (xs == NULL)
1059			pl = ISP_LOGALL;
1060	} else {
1061		pl = ISP_LOGTDEBUG1;
1062		xs = NULL;
1063	}
1064
1065	switch(ct->ct_status & ~QLTM_SVALID) {
1066	case CT_OK:
1067		/*
1068		 * There are generally 2 possibilities as to why we'd get
1069		 * this condition:
1070		 * 	We sent or received data.
1071		 * 	We sent status & command complete.
1072		 */
1073
1074		break;
1075
1076	case CT_BDR_MSG:
1077		/*
1078		 * Bus Device Reset message received or the SCSI Bus has
1079		 * been Reset; the firmware has gone to Bus Free.
1080		 *
1081		 * The firmware generates an async mailbox interupt to
1082		 * notify us of this and returns outstanding CTIOs with this
1083		 * status. These CTIOs are handled in that same way as
1084		 * CT_ABORTED ones, so just fall through here.
1085		 */
1086		fmsg = "Bus Device Reset";
1087		/*FALLTHROUGH*/
1088	case CT_RESET:
1089		if (fmsg == NULL)
1090			fmsg = "Bus Reset";
1091		/*FALLTHROUGH*/
1092	case CT_ABORTED:
1093		/*
1094		 * When an Abort message is received the firmware goes to
1095		 * Bus Free and returns all outstanding CTIOs with the status
1096		 * set, then sends us an Immediate Notify entry.
1097		 */
1098		if (fmsg == NULL)
1099			fmsg = "ABORT TASK sent by Initiator";
1100
1101		isp_prt(isp, ISP_LOGERR, "CTIO2 destroyed by %s", fmsg);
1102		break;
1103
1104	case CT_INVAL:
1105		/*
1106		 * CTIO rejected by the firmware - invalid data direction.
1107		 */
1108		isp_prt(isp, ISP_LOGERR, "CTIO2 had wrong data directiond");
1109		break;
1110
1111	case CT_NOPATH:
1112		/*
1113		 * CTIO rejected by the firmware due "no path for the
1114		 * nondisconnecting nexus specified". This means that
1115		 * we tried to access the bus while a non-disconnecting
1116		 * command is in process.
1117		 */
1118		isp_prt(isp, ISP_LOGERR,
1119		    "Firmware rejected CTIO2 for bad nexus %d->%d",
1120		    ct->ct_iid, ct->ct_lun);
1121		break;
1122
1123	case CT_RSELTMO:
1124		fmsg = "Reselection";
1125		/*FALLTHROUGH*/
1126	case CT_TIMEOUT:
1127		if (fmsg == NULL)
1128			fmsg = "Command";
1129		isp_prt(isp, ISP_LOGERR, "Firmware timed out on %s", fmsg);
1130		break;
1131
1132	case CT_ERR:
1133		fmsg = "Completed with Error";
1134		/*FALLTHROUGH*/
1135	case CT_PHASE_ERROR:	/* Bus phase sequence error */
1136		if (fmsg == NULL)
1137			fmsg = "Phase Sequence Error";
1138		/*FALLTHROUGH*/
1139	case CT_TERMINATED:
1140		if (fmsg == NULL)
1141			fmsg = "terminated by TERMINATE TRANSFER";
1142		/*FALLTHROUGH*/
1143	case CT_LOGOUT:
1144		if (fmsg == NULL)
1145			fmsg = "Port Logout";
1146		/*FALLTHROUGH*/
1147	case CT_PORTNOTAVAIL:
1148		if (fmsg == NULL)
1149			fmsg = "Port not available";
1150	case CT_NOACK:
1151		if (fmsg == NULL)
1152			fmsg = "unacknowledged Immediate Notify pending";
1153
1154		isp_prt(isp, ISP_LOGERR, "CTIO returned by f/w- %s", fmsg);
1155#if	0
1156			if (status & SENSEVALID) {
1157				bcopy((caddr_t) (cep + CTIO_SENSE_OFFSET),
1158				    (caddr_t) &cdp->cd_sensedata,
1159				    sizeof(scsi_sense_t));
1160				cdp->cd_flags |= CDF_SENSEVALID;
1161			}
1162#endif
1163		break;
1164
1165	case CT_INVRXID:
1166		/*
1167		 * CTIO rejected by the firmware because an invalid RX_ID.
1168		 * Just print a message.
1169		 */
1170		isp_prt(isp, ISP_LOGERR,
1171		    "CTIO2 completed with Invalid RX_ID 0x%x", ct->ct_rxid);
1172		break;
1173
1174	default:
1175		isp_prt(isp, ISP_LOGERR, "Unknown CTIO status 0x%x",
1176		    ct->ct_status & ~QLTM_SVALID);
1177		break;
1178	}
1179
1180	if (xs == NULL) {
1181		/*
1182		 * There may be more than one CTIO for a data transfer,
1183		 * or this may be a status CTIO we're not monitoring.
1184		 *
1185		 * The assumption is that they'll all be returned in the
1186		 * order we got them.
1187		 */
1188		if (ct->ct_reserved == 0) {
1189			if ((ct->ct_flags & CT_SENDSTATUS) == 0) {
1190				isp_prt(isp, pl,
1191				    "intermediate CTIO completed ok");
1192			} else {
1193				isp_prt(isp, pl,
1194				    "unmonitored CTIO completed ok");
1195			}
1196		} else {
1197			isp_prt(isp, pl,
1198			    "NO xs for CTIO (handle 0x%x) status 0x%x",
1199			    ct->ct_reserved, ct->ct_status & ~QLTM_SVALID);
1200		}
1201	} else {
1202		if (ct->ct_flags & CT_SENDSTATUS) {
1203			/*
1204			 * Sent status and command complete.
1205			 *
1206			 * We're now really done with this command, so we
1207			 * punt to the platform dependent layers because
1208			 * only there can we do the appropriate command
1209			 * complete thread synchronization.
1210			 */
1211			isp_prt(isp, pl, "status CTIO complete");
1212		} else {
1213			/*
1214			 * Final CTIO completed. Release DMA resources and
1215			 * notify platform dependent layers.
1216			 */
1217			isp_prt(isp, pl, "data CTIO complete");
1218			ISP_DMAFREE(isp, xs, ct->ct_reserved);
1219		}
1220		(void) isp_async(isp, ISPASYNC_TARGET_ACTION, ct);
1221		/*
1222		 * The platform layer will destroy the handle if appropriate.
1223		 */
1224	}
1225}
1226#endif
1227