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