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