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