isp_target.c revision 1.8 1 /* $NetBSD: isp_target.c,v 1.8 2000/08/08 22:58:31 mjacob Exp $ */
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 (at) 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
52 static char *atiocope =
53 "ATIO returned for lun %d because it was in the middle of Bus Device Reset";
54 static char *atior =
55 "ATIO returned for lun %d from initiator %d because a Bus Reset occurred";
56
57 static void isp_got_msg __P((struct ispsoftc *, int, in_entry_t *));
58 static void isp_got_msg_fc __P((struct ispsoftc *, int, in_fcentry_t *));
59 static void isp_notify_ack __P((struct ispsoftc *, void *));
60 static void isp_handle_atio(struct ispsoftc *, at_entry_t *);
61 static void isp_handle_atio2(struct ispsoftc *, at2_entry_t *);
62 static void isp_handle_ctio(struct ispsoftc *, ct_entry_t *);
63 static 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
111 int
112 isp_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 */
273 int
274 isp_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
331 int
332 isp_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
370 int
371 isp_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
425 int
426 isp_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
488 void
489 isp_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 = FCPARAM(isp)->isp_loopid;
529 } else {
530 msg.nt_iid = SDPARAM(isp)->isp_initiator_id;
531 }
532 msg.nt_bus = bus;
533 msg.nt_msg[0] = MSG_BUS_DEV_RESET;
534 (void) isp_async(isp, ISPASYNC_TARGET_MESSAGE, &msg);
535 break;
536 default:
537 isp_prt(isp, ISP_LOGERR,
538 "isp_target_async: unknown event 0x%x", event);
539 break;
540 }
541 if (isp->isp_state == ISP_RUNSTATE)
542 isp_notify_ack(isp, NULL);
543 }
544
545
546 /*
547 * Process a received message.
548 * The ISP firmware can handle most messages, there are only
549 * a few that we need to deal with:
550 * - abort: clean up the current command
551 * - abort tag and clear queue
552 */
553
554 static void
555 isp_got_msg(isp, bus, inp)
556 struct ispsoftc *isp;
557 int bus;
558 in_entry_t *inp;
559 {
560 u_int8_t status = inp->in_status & ~QLTM_SVALID;
561
562 if (status == IN_IDE_RECEIVED || status == IN_MSG_RECEIVED) {
563 tmd_msg_t msg;
564
565 MEMZERO(&msg, sizeof (msg));
566 msg.nt_bus = bus;
567 msg.nt_iid = inp->in_iid;
568 msg.nt_tgt = inp->in_tgt;
569 msg.nt_lun = inp->in_lun;
570 msg.nt_tagtype = inp->in_tag_type;
571 msg.nt_tagval = inp->in_tag_val;
572 MEMCPY(msg.nt_msg, inp->in_msg, IN_MSGLEN);
573 (void) isp_async(isp, ISPASYNC_TARGET_MESSAGE, &msg);
574 } else {
575 isp_prt(isp, ISP_LOGERR,
576 "unknown immediate notify status 0x%x", inp->in_status);
577 }
578 }
579
580 /*
581 * Synthesize a message from the task management flags in a FCP_CMND_IU.
582 */
583 static void
584 isp_got_msg_fc(isp, bus, inp)
585 struct ispsoftc *isp;
586 int bus;
587 in_fcentry_t *inp;
588 {
589 static char *f1 = "%s from iid %d lun %d seq 0x%x";
590 static char *f2 =
591 "unknown %s 0x%x lun %d iid %d task flags 0x%x seq 0x%x\n";
592
593 if (inp->in_status != IN_MSG_RECEIVED) {
594 isp_prt(isp, ISP_LOGINFO, f2, "immediate notify status",
595 inp->in_status, inp->in_lun, inp->in_iid,
596 inp->in_task_flags, inp->in_seqid);
597 } else {
598 tmd_msg_t msg;
599
600 MEMZERO(&msg, sizeof (msg));
601 msg.nt_bus = bus;
602 msg.nt_iid = inp->in_iid;
603 if (isp->isp_maxluns > 16) {
604 msg.nt_lun = inp->in_scclun;
605 } else {
606 msg.nt_lun = inp->in_lun;
607 }
608 msg.nt_tagval = inp->in_seqid;
609
610 if (inp->in_task_flags & TASK_FLAGS_ABORT_TASK) {
611 isp_prt(isp, ISP_LOGINFO, f1, "ABORT TASK",
612 inp->in_iid, inp->in_lun, inp->in_seqid);
613 msg.nt_msg[0] = MSG_ABORT_TAG;
614 } else if (inp->in_task_flags & TASK_FLAGS_CLEAR_TASK_SET) {
615 isp_prt(isp, ISP_LOGINFO, f1, "CLEAR TASK SET",
616 inp->in_iid, inp->in_lun, inp->in_seqid);
617 msg.nt_msg[0] = MSG_CLEAR_QUEUE;
618 } else if (inp->in_task_flags & TASK_FLAGS_TARGET_RESET) {
619 isp_prt(isp, ISP_LOGINFO, f1, "TARGET RESET",
620 inp->in_iid, inp->in_lun, inp->in_seqid);
621 msg.nt_msg[0] = MSG_BUS_DEV_RESET;
622 } else if (inp->in_task_flags & TASK_FLAGS_CLEAR_ACA) {
623 isp_prt(isp, ISP_LOGINFO, f1, "CLEAR ACA",
624 inp->in_iid, inp->in_lun, inp->in_seqid);
625 /* ???? */
626 msg.nt_msg[0] = MSG_REL_RECOVERY;
627 } else if (inp->in_task_flags & TASK_FLAGS_TERMINATE_TASK) {
628 isp_prt(isp, ISP_LOGINFO, f1, "TERMINATE TASK",
629 inp->in_iid, inp->in_lun, inp->in_seqid);
630 msg.nt_msg[0] = MSG_TERM_IO_PROC;
631 } else {
632 isp_prt(isp, ISP_LOGWARN, f2, "task flag",
633 inp->in_status, inp->in_lun, inp->in_iid,
634 inp->in_task_flags, inp->in_seqid);
635 }
636 if (msg.nt_msg[0]) {
637 (void) isp_async(isp, ISPASYNC_TARGET_MESSAGE, &msg);
638 }
639 }
640 }
641
642 static void
643 isp_notify_ack(isp, arg)
644 struct ispsoftc *isp;
645 void *arg;
646 {
647 char storage[QENTRY_LEN];
648 u_int16_t iptr, optr;
649 void *outp;
650
651 if (isp_getrqentry(isp, &iptr, &optr, &outp)) {
652 isp_prt(isp, ISP_LOGWARN,
653 "Request Queue Overflow For isp_notify_ack");
654 return;
655 }
656
657 MEMZERO(storage, QENTRY_LEN);
658
659 if (IS_FC(isp)) {
660 na_fcentry_t *na = (na_fcentry_t *) storage;
661 if (arg) {
662 in_fcentry_t *inp = arg;
663 MEMCPY(storage, arg, sizeof (isphdr_t));
664 na->na_iid = inp->in_iid;
665 if (isp->isp_maxluns > 16) {
666 na->na_lun = inp->in_scclun;
667 } else {
668 na->na_lun = inp->in_lun;
669 }
670 na->na_task_flags = inp->in_task_flags;
671 na->na_seqid = inp->in_seqid;
672 na->na_flags = NAFC_RCOUNT;
673 if (inp->in_status == IN_RESET) {
674 na->na_flags |= NAFC_RST_CLRD;
675 }
676 } else {
677 na->na_flags = NAFC_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_FC(isp, outp, na);
682 } else {
683 na_entry_t *na = (na_entry_t *) storage;
684 if (arg) {
685 in_entry_t *inp = arg;
686 MEMCPY(storage, arg, sizeof (isphdr_t));
687 na->na_iid = inp->in_iid;
688 na->na_lun = inp->in_lun;
689 na->na_tgt = inp->in_tgt;
690 na->na_seqid = inp->in_seqid;
691 if (inp->in_status == IN_RESET) {
692 na->na_event = NA_RST_CLRD;
693 }
694 } else {
695 na->na_event = NA_RST_CLRD;
696 }
697 na->na_header.rqs_entry_type = RQSTYPE_NOTIFY_ACK;
698 na->na_header.rqs_entry_count = 1;
699 ISP_SWIZ_NOT_ACK(isp, outp, na);
700 }
701 ISP_TDQE(isp, "isp_notify_ack", (int) optr, storage);
702 ISP_ADD_REQUEST(isp, iptr);
703 }
704
705 static void
706 isp_handle_atio(isp, aep)
707 struct ispsoftc *isp;
708 at_entry_t *aep;
709 {
710 int lun;
711 lun = aep->at_lun;
712 /*
713 * The firmware status (except for the QLTM_SVALID bit) indicates
714 * why this ATIO was sent to us.
715 *
716 * If QLTM_SVALID is set, the firware has recommended Sense Data.
717 *
718 * If the DISCONNECTS DISABLED bit is set in the flags field,
719 * we're still connected on the SCSI bus - i.e. the initiator
720 * did not set DiscPriv in the identify message. We don't care
721 * about this so it's ignored.
722 */
723
724 switch(aep->at_status & ~QLTM_SVALID) {
725 case AT_PATH_INVALID:
726 /*
727 * ATIO rejected by the firmware due to disabled lun.
728 */
729 isp_prt(isp, ISP_LOGERR,
730 "rejected ATIO for disabled lun %d", lun);
731 break;
732 case AT_NOCAP:
733 /*
734 * Requested Capability not available
735 * We sent an ATIO that overflowed the firmware's
736 * command resource count.
737 */
738 isp_prt(isp, ISP_LOGERR,
739 "rejected ATIO for lun %d because of command count"
740 " overflow", lun);
741 break;
742
743 case AT_BDR_MSG:
744 /*
745 * If we send an ATIO to the firmware to increment
746 * its command resource count, and the firmware is
747 * recovering from a Bus Device Reset, it returns
748 * the ATIO with this status. We set the command
749 * resource count in the Enable Lun entry and no
750 * not increment it. Therefore we should never get
751 * this status here.
752 */
753 isp_prt(isp, ISP_LOGERR, atiocope, lun);
754 break;
755
756 case AT_CDB: /* Got a CDB */
757 case AT_PHASE_ERROR: /* Bus Phase Sequence Error */
758 /*
759 * Punt to platform specific layer.
760 */
761 (void) isp_async(isp, ISPASYNC_TARGET_ACTION, aep);
762 break;
763
764 case AT_RESET:
765 /*
766 * A bus reset came along an blew away this command. Why
767 * they do this in addition the async event code stuff,
768 * I dunno.
769 *
770 * Ignore it because the async event will clear things
771 * up for us.
772 */
773 isp_prt(isp, ISP_LOGWARN, atior, lun, aep->at_iid);
774 break;
775
776
777 default:
778 isp_prt(isp, ISP_LOGERR,
779 "Unknown ATIO status 0x%x from initiator %d for lun %d",
780 aep->at_status, aep->at_iid, lun);
781 (void) isp_target_put_atio(isp, aep->at_iid, aep->at_tgt,
782 lun, aep->at_tag_type, aep->at_tag_val);
783 break;
784 }
785 }
786
787 static void
788 isp_handle_atio2(isp, aep)
789 struct ispsoftc *isp;
790 at2_entry_t *aep;
791 {
792 int lun;
793
794 if (isp->isp_maxluns > 16) {
795 lun = aep->at_scclun;
796 } else {
797 lun = aep->at_lun;
798 }
799
800 /*
801 * The firmware status (except for the QLTM_SVALID bit) indicates
802 * why this ATIO was sent to us.
803 *
804 * If QLTM_SVALID is set, the firware has recommended Sense Data.
805 *
806 * If the DISCONNECTS DISABLED bit is set in the flags field,
807 * we're still connected on the SCSI bus - i.e. the initiator
808 * did not set DiscPriv in the identify message. We don't care
809 * about this so it's ignored.
810 */
811
812 switch(aep->at_status & ~QLTM_SVALID) {
813 case AT_PATH_INVALID:
814 /*
815 * ATIO rejected by the firmware due to disabled lun.
816 */
817 isp_prt(isp, ISP_LOGERR,
818 "rejected ATIO2 for disabled lun %d", lun);
819 break;
820 case AT_NOCAP:
821 /*
822 * Requested Capability not available
823 * We sent an ATIO that overflowed the firmware's
824 * command resource count.
825 */
826 isp_prt(isp, ISP_LOGERR,
827 "rejected ATIO2 for lun %d- command count overflow", lun);
828 break;
829
830 case AT_BDR_MSG:
831 /*
832 * If we send an ATIO to the firmware to increment
833 * its command resource count, and the firmware is
834 * recovering from a Bus Device Reset, it returns
835 * the ATIO with this status. We set the command
836 * resource count in the Enable Lun entry and no
837 * not increment it. Therefore we should never get
838 * this status here.
839 */
840 isp_prt(isp, ISP_LOGERR, atiocope, lun);
841 break;
842
843 case AT_CDB: /* Got a CDB */
844 /*
845 * Punt to platform specific layer.
846 */
847 (void) isp_async(isp, ISPASYNC_TARGET_ACTION, aep);
848 break;
849
850 case AT_RESET:
851 /*
852 * A bus reset came along an blew away this command. Why
853 * they do this in addition the async event code stuff,
854 * I dunno.
855 *
856 * Ignore it because the async event will clear things
857 * up for us.
858 */
859 isp_prt(isp, ISP_LOGERR, atior, lun, aep->at_iid);
860 break;
861
862
863 default:
864 isp_prt(isp, ISP_LOGERR,
865 "Unknown ATIO2 status 0x%x from initiator %d for lun %d",
866 aep->at_status, aep->at_iid, lun);
867 (void) isp_target_put_atio(isp, aep->at_iid, 0, lun, 0, 0);
868 break;
869 }
870 }
871
872 static void
873 isp_handle_ctio(isp, ct)
874 struct ispsoftc *isp;
875 ct_entry_t *ct;
876 {
877 XS_T *xs;
878 int pl = ISP_LOGTDEBUG2;
879 char *fmsg = NULL;
880
881 if (ct->ct_reserved) {
882 xs = isp_find_xs(isp, ct->ct_reserved);
883 if (xs == NULL)
884 pl = ISP_LOGALL;
885 } else {
886 pl = ISP_LOGTDEBUG1;
887 xs = NULL;
888 }
889
890 switch(ct->ct_status & ~QLTM_SVALID) {
891 case CT_OK:
892 /*
893 * There are generally 3 possibilities as to why we'd get
894 * this condition:
895 * We disconnected after receiving a CDB.
896 * We sent or received data.
897 * We sent status & command complete.
898 */
899
900 if (ct->ct_flags & CT_SENDSTATUS) {
901 break;
902 } else if ((ct->ct_flags & CT_DATAMASK) == CT_NO_DATA) {
903 /*
904 * Nothing to do in this case.
905 */
906 isp_prt(isp, pl, "CTIO- iid %d disconnected OK",
907 ct->ct_iid);
908 return;
909 }
910 break;
911
912 case CT_BDR_MSG:
913 /*
914 * Bus Device Reset message received or the SCSI Bus has
915 * been Reset; the firmware has gone to Bus Free.
916 *
917 * The firmware generates an async mailbox interupt to
918 * notify us of this and returns outstanding CTIOs with this
919 * status. These CTIOs are handled in that same way as
920 * CT_ABORTED ones, so just fall through here.
921 */
922 fmsg = "Bus Device Reset";
923 /*FALLTHROUGH*/
924 case CT_RESET:
925 if (fmsg == NULL)
926 fmsg = "Bus Reset";
927 /*FALLTHROUGH*/
928 case CT_ABORTED:
929 /*
930 * When an Abort message is received the firmware goes to
931 * Bus Free and returns all outstanding CTIOs with the status
932 * set, then sends us an Immediate Notify entry.
933 */
934 if (fmsg == NULL)
935 fmsg = "ABORT TASK sent by Initiator";
936
937 isp_prt(isp, ISP_LOGWARN, "CTIO destroyed by %s", fmsg);
938 break;
939
940 case CT_INVAL:
941 /*
942 * CTIO rejected by the firmware due to disabled lun.
943 * "Cannot Happen".
944 */
945 isp_prt(isp, ISP_LOGERR,
946 "Firmware rejected CTIO for disabled lun %d",
947 ct->ct_lun);
948 break;
949
950 case CT_NOPATH:
951 /*
952 * CTIO rejected by the firmware due "no path for the
953 * nondisconnecting nexus specified". This means that
954 * we tried to access the bus while a non-disconnecting
955 * command is in process.
956 */
957 isp_prt(isp, ISP_LOGERR,
958 "Firmware rejected CTIO for bad nexus %d/%d/%d",
959 ct->ct_iid, ct->ct_tgt, ct->ct_lun);
960 break;
961
962 case CT_RSELTMO:
963 fmsg = "Reselection";
964 /*FALLTHROUGH*/
965 case CT_TIMEOUT:
966 if (fmsg == NULL)
967 fmsg = "Command";
968 isp_prt(isp, ISP_LOGERR, "Firmware timed out on %s", fmsg);
969 break;
970
971 case CT_ERR:
972 fmsg = "Completed with Error";
973 /*FALLTHROUGH*/
974 case CT_PHASE_ERROR:
975 if (fmsg == NULL)
976 fmsg = "Phase Sequence Error";
977 /*FALLTHROUGH*/
978 case CT_TERMINATED:
979 if (fmsg == NULL)
980 fmsg = "terminated by TERMINATE TRANSFER";
981 /*FALLTHROUGH*/
982 case CT_NOACK:
983 if (fmsg == NULL)
984 fmsg = "unacknowledged Immediate Notify pending";
985
986 isp_prt(isp, ISP_LOGERR, "CTIO returned by f/w- %s", fmsg);
987 #if 0
988 if (status & SENSEVALID) {
989 bcopy((caddr_t) (cep + CTIO_SENSE_OFFSET),
990 (caddr_t) &cdp->cd_sensedata,
991 sizeof(scsi_sense_t));
992 cdp->cd_flags |= CDF_SENSEVALID;
993 }
994 #endif
995 break;
996 default:
997 isp_prt(isp, ISP_LOGERR, "Unknown CTIO status 0x%x",
998 ct->ct_status & ~QLTM_SVALID);
999 break;
1000 }
1001
1002 if (xs == NULL) {
1003 /*
1004 * There may be more than one CTIO for a data transfer,
1005 * or this may be a status CTIO we're not monitoring.
1006 *
1007 * The assumption is that they'll all be returned in the
1008 * order we got them.
1009 */
1010 if (ct->ct_reserved == 0) {
1011 if ((ct->ct_flags & CT_SENDSTATUS) == 0) {
1012 isp_prt(isp, pl,
1013 "intermediate CTIO completed ok");
1014 } else {
1015 isp_prt(isp, pl,
1016 "unmonitored CTIO completed ok");
1017 }
1018 } else {
1019 isp_prt(isp, pl,
1020 "NO xs for CTIO (handle 0x%x) status 0x%x",
1021 ct->ct_reserved, ct->ct_status & ~QLTM_SVALID);
1022 }
1023 } else {
1024 if (ct->ct_flags & CT_SENDSTATUS) {
1025 /*
1026 * Sent status and command complete.
1027 *
1028 * We're now really done with this command, so we
1029 * punt to the platform dependent layers because
1030 * only there can we do the appropriate command
1031 * complete thread synchronization.
1032 */
1033 isp_prt(isp, pl, "status CTIO complete");
1034 } else {
1035 /*
1036 * Final CTIO completed. Release DMA resources and
1037 * notify platform dependent layers.
1038 */
1039 isp_prt(isp, pl, "data CTIO complete");
1040 ISP_DMAFREE(isp, xs, ct->ct_reserved);
1041 }
1042 (void) isp_async(isp, ISPASYNC_TARGET_ACTION, ct);
1043 /*
1044 * The platform layer will destroy the handle if appropriate.
1045 */
1046 }
1047 }
1048
1049 static void
1050 isp_handle_ctio2(isp, ct)
1051 struct ispsoftc *isp;
1052 ct2_entry_t *ct;
1053 {
1054 XS_T *xs;
1055 int pl = ISP_LOGTDEBUG2;
1056 char *fmsg = NULL;
1057
1058 if (ct->ct_reserved) {
1059 xs = isp_find_xs(isp, ct->ct_reserved);
1060 if (xs == NULL)
1061 pl = ISP_LOGALL;
1062 } else {
1063 pl = ISP_LOGTDEBUG1;
1064 xs = NULL;
1065 }
1066
1067 switch(ct->ct_status & ~QLTM_SVALID) {
1068 case CT_OK:
1069 /*
1070 * There are generally 2 possibilities as to why we'd get
1071 * this condition:
1072 * We sent or received data.
1073 * We sent status & command complete.
1074 */
1075
1076 break;
1077
1078 case CT_BDR_MSG:
1079 /*
1080 * Bus Device Reset message received or the SCSI Bus has
1081 * been Reset; the firmware has gone to Bus Free.
1082 *
1083 * The firmware generates an async mailbox interupt to
1084 * notify us of this and returns outstanding CTIOs with this
1085 * status. These CTIOs are handled in that same way as
1086 * CT_ABORTED ones, so just fall through here.
1087 */
1088 fmsg = "Bus Device Reset";
1089 /*FALLTHROUGH*/
1090 case CT_RESET:
1091 if (fmsg == NULL)
1092 fmsg = "Bus Reset";
1093 /*FALLTHROUGH*/
1094 case CT_ABORTED:
1095 /*
1096 * When an Abort message is received the firmware goes to
1097 * Bus Free and returns all outstanding CTIOs with the status
1098 * set, then sends us an Immediate Notify entry.
1099 */
1100 if (fmsg == NULL)
1101 fmsg = "ABORT TASK sent by Initiator";
1102
1103 isp_prt(isp, ISP_LOGERR, "CTIO2 destroyed by %s", fmsg);
1104 break;
1105
1106 case CT_INVAL:
1107 /*
1108 * CTIO rejected by the firmware - invalid data direction.
1109 */
1110 isp_prt(isp, ISP_LOGERR, "CTIO2 had wrong data directiond");
1111 break;
1112
1113 case CT_NOPATH:
1114 /*
1115 * CTIO rejected by the firmware due "no path for the
1116 * nondisconnecting nexus specified". This means that
1117 * we tried to access the bus while a non-disconnecting
1118 * command is in process.
1119 */
1120 isp_prt(isp, ISP_LOGERR,
1121 "Firmware rejected CTIO2 for bad nexus %d->%d",
1122 ct->ct_iid, ct->ct_lun);
1123 break;
1124
1125 case CT_RSELTMO:
1126 fmsg = "Reselection";
1127 /*FALLTHROUGH*/
1128 case CT_TIMEOUT:
1129 if (fmsg == NULL)
1130 fmsg = "Command";
1131 isp_prt(isp, ISP_LOGERR, "Firmware timed out on %s", fmsg);
1132 break;
1133
1134 case CT_ERR:
1135 fmsg = "Completed with Error";
1136 /*FALLTHROUGH*/
1137 case CT_PHASE_ERROR: /* Bus phase sequence error */
1138 if (fmsg == NULL)
1139 fmsg = "Phase Sequence Error";
1140 /*FALLTHROUGH*/
1141 case CT_TERMINATED:
1142 if (fmsg == NULL)
1143 fmsg = "terminated by TERMINATE TRANSFER";
1144 /*FALLTHROUGH*/
1145 case CT_LOGOUT:
1146 if (fmsg == NULL)
1147 fmsg = "Port Logout";
1148 /*FALLTHROUGH*/
1149 case CT_PORTNOTAVAIL:
1150 if (fmsg == NULL)
1151 fmsg = "Port not available";
1152 case CT_NOACK:
1153 if (fmsg == NULL)
1154 fmsg = "unacknowledged Immediate Notify pending";
1155
1156 isp_prt(isp, ISP_LOGERR, "CTIO returned by f/w- %s", fmsg);
1157 #if 0
1158 if (status & SENSEVALID) {
1159 bcopy((caddr_t) (cep + CTIO_SENSE_OFFSET),
1160 (caddr_t) &cdp->cd_sensedata,
1161 sizeof(scsi_sense_t));
1162 cdp->cd_flags |= CDF_SENSEVALID;
1163 }
1164 #endif
1165 break;
1166
1167 case CT_INVRXID:
1168 /*
1169 * CTIO rejected by the firmware because an invalid RX_ID.
1170 * Just print a message.
1171 */
1172 isp_prt(isp, ISP_LOGERR,
1173 "CTIO2 completed with Invalid RX_ID 0x%x", ct->ct_rxid);
1174 break;
1175
1176 default:
1177 isp_prt(isp, ISP_LOGERR, "Unknown CTIO status 0x%x",
1178 ct->ct_status & ~QLTM_SVALID);
1179 break;
1180 }
1181
1182 if (xs == NULL) {
1183 /*
1184 * There may be more than one CTIO for a data transfer,
1185 * or this may be a status CTIO we're not monitoring.
1186 *
1187 * The assumption is that they'll all be returned in the
1188 * order we got them.
1189 */
1190 if (ct->ct_reserved == 0) {
1191 if ((ct->ct_flags & CT_SENDSTATUS) == 0) {
1192 isp_prt(isp, pl,
1193 "intermediate CTIO completed ok");
1194 } else {
1195 isp_prt(isp, pl,
1196 "unmonitored CTIO completed ok");
1197 }
1198 } else {
1199 isp_prt(isp, pl,
1200 "NO xs for CTIO (handle 0x%x) status 0x%x",
1201 ct->ct_reserved, ct->ct_status & ~QLTM_SVALID);
1202 }
1203 } else {
1204 if (ct->ct_flags & CT_SENDSTATUS) {
1205 /*
1206 * Sent status and command complete.
1207 *
1208 * We're now really done with this command, so we
1209 * punt to the platform dependent layers because
1210 * only there can we do the appropriate command
1211 * complete thread synchronization.
1212 */
1213 isp_prt(isp, pl, "status CTIO complete");
1214 } else {
1215 /*
1216 * Final CTIO completed. Release DMA resources and
1217 * notify platform dependent layers.
1218 */
1219 isp_prt(isp, pl, "data CTIO complete");
1220 ISP_DMAFREE(isp, xs, ct->ct_reserved);
1221 }
1222 (void) isp_async(isp, ISPASYNC_TARGET_ACTION, ct);
1223 /*
1224 * The platform layer will destroy the handle if appropriate.
1225 */
1226 }
1227 }
1228 #endif
1229