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