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