isp_target.c revision 1.15 1 /* $NetBSD: isp_target.c,v 1.15 2001/09/05 22:32:38 mjacob Exp $ */
2 /*
3 * This driver, which is contained in NetBSD in the files:
4 *
5 * sys/dev/ic/isp.c
6 * sys/dev/ic/isp_inline.h
7 * sys/dev/ic/isp_netbsd.c
8 * sys/dev/ic/isp_netbsd.h
9 * sys/dev/ic/isp_target.c
10 * sys/dev/ic/isp_target.h
11 * sys/dev/ic/isp_tpublic.h
12 * sys/dev/ic/ispmbox.h
13 * sys/dev/ic/ispreg.h
14 * sys/dev/ic/ispvar.h
15 * sys/microcode/isp/asm_sbus.h
16 * sys/microcode/isp/asm_1040.h
17 * sys/microcode/isp/asm_1080.h
18 * sys/microcode/isp/asm_12160.h
19 * sys/microcode/isp/asm_2100.h
20 * sys/microcode/isp/asm_2200.h
21 * sys/pci/isp_pci.c
22 * sys/sbus/isp_sbus.c
23 *
24 * Is being actively maintained by Matthew Jacob (mjacob (at) netbsd.org).
25 * This driver also is shared source with FreeBSD, OpenBSD, Linux, Solaris,
26 * Linux versions. This tends to be an interesting maintenance problem.
27 *
28 * Please coordinate with Matthew Jacob on changes you wish to make here.
29 */
30 /*
31 * Machine and OS Independent Target Mode Code for the Qlogic SCSI/FC adapters.
32 *
33 * Copyright (c) 1999, 2000, 2001 by Matthew Jacob
34 * All rights reserved.
35 * mjacob (at) feral.com
36 *
37 * Redistribution and use in source and binary forms, with or without
38 * modification, are permitted provided that the following conditions
39 * are met:
40 * 1. Redistributions of source code must retain the above copyright
41 * notice immediately at the beginning of the file, without modification,
42 * this list of conditions, and the following disclaimer.
43 * 2. The name of the author may not be used to endorse or promote products
44 * derived from this software without specific prior written permission.
45 *
46 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
47 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
48 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
49 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
50 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
51 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
52 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
53 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
54 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
55 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
56 * SUCH DAMAGE.
57 */
58
59 /*
60 * Include header file appropriate for platform we're building on.
61 */
62
63 #ifdef __NetBSD__
64 #include <dev/ic/isp_netbsd.h>
65 #endif
66 #ifdef __FreeBSD__
67 #include <dev/isp/isp_freebsd.h>
68 #endif
69 #ifdef __OpenBSD__
70 #include <dev/ic/isp_openbsd.h>
71 #endif
72 #ifdef __linux__
73 #include "isp_linux.h"
74 #endif
75
76 #ifdef ISP_TARGET_MODE
77 static const char atiocope[] =
78 "ATIO returned for lun %d because it was in the middle of Bus Device Reset "
79 "on bus %d";
80 static const char atior[] =
81 "ATIO returned on for lun %d on from IID %d because a Bus Reset occurred "
82 "on bus %d";
83
84 static void isp_got_msg(struct ispsoftc *, int, in_entry_t *);
85 static void isp_got_msg_fc(struct ispsoftc *, int, in_fcentry_t *);
86 static void isp_notify_ack(struct ispsoftc *, void *);
87 static void isp_handle_atio(struct ispsoftc *, at_entry_t *);
88 static void isp_handle_atio2(struct ispsoftc *, at2_entry_t *);
89 static void isp_handle_ctio(struct ispsoftc *, ct_entry_t *);
90 static void isp_handle_ctio2(struct ispsoftc *, ct2_entry_t *);
91
92 /*
93 * The Qlogic driver gets an interrupt to look at response queue entries.
94 * Some of these are status completions for initiatior mode commands, but
95 * if target mode is enabled, we get a whole wad of response queue entries
96 * to be handled here.
97 *
98 * Basically the split into 3 main groups: Lun Enable/Modification responses,
99 * SCSI Command processing, and Immediate Notification events.
100 *
101 * You start by writing a request queue entry to enable target mode (and
102 * establish some resource limitations which you can modify later).
103 * The f/w responds with a LUN ENABLE or LUN MODIFY response with
104 * the status of this action. If the enable was successful, you can expect...
105 *
106 * Response queue entries with SCSI commands encapsulate show up in an ATIO
107 * (Accept Target IO) type- sometimes with enough info to stop the command at
108 * this level. Ultimately the driver has to feed back to the f/w's request
109 * queue a sequence of CTIOs (continue target I/O) that describe data to
110 * be moved and/or status to be sent) and finally finishing with sending
111 * to the f/w's response queue an ATIO which then completes the handshake
112 * with the f/w for that command. There's a lot of variations on this theme,
113 * including flags you can set in the CTIO for the Qlogic 2X00 fibre channel
114 * cards that 'auto-replenish' the f/w's ATIO count, but this is the basic
115 * gist of it.
116 *
117 * The third group that can show up in the response queue are Immediate
118 * Notification events. These include things like notifications of SCSI bus
119 * resets, or Bus Device Reset messages or other messages received. This
120 * a classic oddbins area. It can get a little weird because you then turn
121 * around and acknowledge the Immediate Notify by writing an entry onto the
122 * request queue and then the f/w turns around and gives you an acknowledgement
123 * to *your* acknowledgement on the response queue (the idea being to let
124 * the f/w tell you when the event is *really* over I guess).
125 *
126 */
127
128
129 /*
130 * A new response queue entry has arrived. The interrupt service code
131 * has already swizzled it into the platform dependent from canonical form.
132 *
133 * Because of the way this driver is designed, unfortunately most of the
134 * actual synchronization work has to be done in the platform specific
135 * code- we have no synchroniation primitives in the common code.
136 */
137
138 int
139 isp_target_notify(struct ispsoftc *isp, void *vptr, u_int16_t *optrp)
140 {
141 u_int16_t status, seqid;
142 union {
143 at_entry_t *atiop;
144 at2_entry_t *at2iop;
145 ct_entry_t *ctiop;
146 ct2_entry_t *ct2iop;
147 lun_entry_t *lunenp;
148 in_entry_t *inotp;
149 in_fcentry_t *inot_fcp;
150 na_entry_t *nackp;
151 na_fcentry_t *nack_fcp;
152 isphdr_t *hp;
153 void * *vp;
154 #define atiop unp.atiop
155 #define at2iop unp.at2iop
156 #define ctiop unp.ctiop
157 #define ct2iop unp.ct2iop
158 #define lunenp unp.lunenp
159 #define inotp unp.inotp
160 #define inot_fcp unp.inot_fcp
161 #define nackp unp.nackp
162 #define nack_fcp unp.nack_fcp
163 #define hdrp unp.hp
164 } unp;
165 int bus, rval = 0;
166
167 unp.vp = vptr;
168
169 ISP_TDQE(isp, "isp_target_notify", (int) *optrp, vptr);
170
171 switch(hdrp->rqs_entry_type) {
172 case RQSTYPE_ATIO:
173 isp_handle_atio(isp, atiop);
174 break;
175 case RQSTYPE_CTIO:
176 isp_handle_ctio(isp, ctiop);
177 break;
178 case RQSTYPE_ATIO2:
179 isp_handle_atio2(isp, at2iop);
180 break;
181 case RQSTYPE_CTIO2:
182 isp_handle_ctio2(isp, ct2iop);
183 break;
184 case RQSTYPE_ENABLE_LUN:
185 case RQSTYPE_MODIFY_LUN:
186 (void) isp_async(isp, ISPASYNC_TARGET_ACTION, vptr);
187 break;
188
189 case RQSTYPE_NOTIFY:
190 /*
191 * Either the ISP received a SCSI message it can't
192 * handle, or it's returning an Immed. Notify entry
193 * we sent. We can send Immed. Notify entries to
194 * increment the firmware's resource count for them
195 * (we set this initially in the Enable Lun entry).
196 */
197 bus = 0;
198 if (IS_FC(isp)) {
199 status = inot_fcp->in_status;
200 seqid = inot_fcp->in_seqid;
201 } else {
202 status = inotp->in_status & 0xff;
203 seqid = inotp->in_seqid;
204 if (IS_DUALBUS(isp)) {
205 bus = GET_BUS_VAL(inotp->in_iid);
206 SET_BUS_VAL(inotp->in_iid, 0);
207 }
208 }
209 isp_prt(isp, ISP_LOGTDEBUG0,
210 "Immediate Notify On Bus %d, status=0x%x seqid=0x%x",
211 bus, status, seqid);
212
213 /*
214 * ACK it right away.
215 */
216 isp_notify_ack(isp, (status == IN_RESET)? NULL : vptr);
217 switch (status) {
218 case IN_RESET:
219 (void) isp_async(isp, ISPASYNC_BUS_RESET, &bus);
220 break;
221 case IN_MSG_RECEIVED:
222 case IN_IDE_RECEIVED:
223 if (IS_FC(isp)) {
224 isp_got_msg_fc(isp, bus, vptr);
225 } else {
226 isp_got_msg(isp, bus, vptr);
227 }
228 break;
229 case IN_RSRC_UNAVAIL:
230 isp_prt(isp, ISP_LOGWARN, "Firmware out of ATIOs");
231 break;
232 case IN_ABORT_TASK:
233 isp_prt(isp, ISP_LOGWARN,
234 "Abort Task from IID %d RX_ID 0x%x",
235 inot_fcp->in_iid, seqid);
236 (void) isp_async(isp, ISPASYNC_TARGET_ACTION, &bus);
237 break;
238 case IN_PORT_LOGOUT:
239 isp_prt(isp, ISP_LOGWARN,
240 "Port Logout for Initiator %d RX_ID 0x%x",
241 inot_fcp->in_iid, seqid);
242 break;
243 case IN_PORT_CHANGED:
244 isp_prt(isp, ISP_LOGWARN,
245 "Port Changed for Initiator %d RX_ID 0x%x",
246 inot_fcp->in_iid, seqid);
247 break;
248 case IN_GLOBAL_LOGO:
249 isp_prt(isp, ISP_LOGWARN, "All ports logged out");
250 break;
251 default:
252 isp_prt(isp, ISP_LOGERR,
253 "bad status (0x%x) in isp_target_notify", status);
254 break;
255 }
256 break;
257
258 case RQSTYPE_NOTIFY_ACK:
259 /*
260 * The ISP is acknowledging our acknowledgement of an
261 * Immediate Notify entry for some asynchronous event.
262 */
263 if (IS_FC(isp)) {
264 isp_prt(isp, ISP_LOGTDEBUG1,
265 "Notify Ack status=0x%x seqid 0x%x",
266 nack_fcp->na_status, nack_fcp->na_seqid);
267 } else {
268 isp_prt(isp, ISP_LOGTDEBUG1,
269 "Notify Ack event 0x%x status=0x%x seqid 0x%x",
270 nackp->na_event, nackp->na_status, nackp->na_seqid);
271 }
272 break;
273 default:
274 isp_prt(isp, ISP_LOGERR,
275 "Unknown entry type 0x%x in isp_target_notify",
276 hdrp->rqs_entry_type);
277 rval = -1;
278 break;
279 }
280 #undef atiop
281 #undef at2iop
282 #undef ctiop
283 #undef ct2iop
284 #undef lunenp
285 #undef inotp
286 #undef inot_fcp
287 #undef nackp
288 #undef nack_fcp
289 #undef hdrp
290 return (rval);
291 }
292
293
294 /*
295 * Toggle (on/off) target mode for bus/target/lun
296 *
297 * The caller has checked for overlap and legality.
298 *
299 * Note that not all of bus, target or lun can be paid attention to.
300 * Note also that this action will not be complete until the f/w writes
301 * response entry. The caller is responsible for synchronizing this.
302 */
303 int
304 isp_lun_cmd(struct ispsoftc *isp, int cmd, int bus, int tgt, int lun,
305 int cmd_cnt, int inot_cnt, u_int32_t opaque)
306 {
307 lun_entry_t el;
308 u_int16_t iptr, optr;
309 void *outp;
310
311
312 MEMZERO(&el, sizeof (el));
313 if (IS_DUALBUS(isp)) {
314 el.le_rsvd = (bus & 0x1) << 7;
315 }
316 el.le_cmd_count = cmd_cnt;
317 el.le_in_count = inot_cnt;
318 if (cmd == RQSTYPE_ENABLE_LUN) {
319 if (IS_SCSI(isp)) {
320 el.le_flags = LUN_TQAE|LUN_DISAD;
321 el.le_cdb6len = 12;
322 el.le_cdb7len = 12;
323 }
324 } else if (cmd == -RQSTYPE_ENABLE_LUN) {
325 cmd = RQSTYPE_ENABLE_LUN;
326 el.le_cmd_count = 0;
327 el.le_in_count = 0;
328 } else if (cmd == -RQSTYPE_MODIFY_LUN) {
329 cmd = RQSTYPE_MODIFY_LUN;
330 el.le_ops = LUN_CCDECR | LUN_INDECR;
331 } else {
332 el.le_ops = LUN_CCINCR | LUN_ININCR;
333 }
334 el.le_header.rqs_entry_type = cmd;
335 el.le_header.rqs_entry_count = 1;
336 el.le_reserved = opaque;
337 if (IS_SCSI(isp)) {
338 el.le_tgt = tgt;
339 el.le_lun = lun;
340 } else if ((FCPARAM(isp)->isp_fwattr & ISP_FW_ATTR_SCCLUN) == 0) {
341 el.le_lun = lun;
342 }
343 el.le_timeout = 2;
344
345 if (isp_getrqentry(isp, &iptr, &optr, &outp)) {
346 isp_prt(isp, ISP_LOGWARN,
347 "Request Queue Overflow in isp_lun_cmd");
348 return (-1);
349 }
350 ISP_SWIZ_ENABLE_LUN(isp, outp, &el);
351 ISP_TDQE(isp, "isp_lun_cmd", (int) optr, &el);
352 ISP_ADD_REQUEST(isp, iptr);
353 return (0);
354 }
355
356
357 int
358 isp_target_put_entry(struct ispsoftc *isp, void *ap)
359 {
360 void *outp;
361 u_int16_t iptr, optr;
362 u_int8_t etype = ((isphdr_t *) ap)->rqs_entry_type;
363
364 if (isp_getrqentry(isp, &iptr, &optr, &outp)) {
365 isp_prt(isp, ISP_LOGWARN,
366 "Request Queue Overflow in isp_target_put_entry");
367 return (-1);
368 }
369 switch (etype) {
370 case RQSTYPE_ATIO:
371 ISP_SWIZ_ATIO(isp, outp, ap);
372 break;
373 case RQSTYPE_ATIO2:
374 ISP_SWIZ_ATIO2(isp, outp, ap);
375 break;
376 case RQSTYPE_CTIO:
377 ISP_SWIZ_CTIO(isp, outp, ap);
378 break;
379 case RQSTYPE_CTIO2:
380 ISP_SWIZ_CTIO2(isp, outp, ap);
381 break;
382 default:
383 isp_prt(isp, ISP_LOGERR,
384 "Unknown type 0x%x in isp_put_entry", etype);
385 return (-1);
386 }
387
388 ISP_TDQE(isp, "isp_target_put_entry", (int) optr, ap);;
389
390 ISP_ADD_REQUEST(isp, iptr);
391 return (0);
392 }
393
394 int
395 isp_target_put_atio(struct ispsoftc *isp, void *arg)
396 {
397 union {
398 at_entry_t _atio;
399 at2_entry_t _atio2;
400 } atun;
401
402 MEMZERO(&atun, sizeof atun);
403 if (IS_FC(isp)) {
404 at2_entry_t *aep = arg;
405 atun._atio2.at_header.rqs_entry_type = RQSTYPE_ATIO2;
406 atun._atio2.at_header.rqs_entry_count = 1;
407 if (FCPARAM(isp)->isp_fwattr & ISP_FW_ATTR_SCCLUN) {
408 atun._atio2.at_scclun = (u_int16_t) aep->at_scclun;
409 } else {
410 atun._atio2.at_lun = (u_int8_t) aep->at_lun;
411 }
412 atun._atio2.at_status = CT_OK;
413 } else {
414 at_entry_t *aep = arg;
415 atun._atio.at_header.rqs_entry_type = RQSTYPE_ATIO;
416 atun._atio.at_header.rqs_entry_count = 1;
417 atun._atio.at_handle = aep->at_handle;
418 atun._atio.at_iid = aep->at_iid;
419 atun._atio.at_tgt = aep->at_tgt;
420 atun._atio.at_lun = aep->at_lun;
421 atun._atio.at_tag_type = aep->at_tag_type;
422 atun._atio.at_tag_val = aep->at_tag_val;
423 atun._atio.at_status = (aep->at_flags & AT_TQAE);
424 atun._atio.at_status |= CT_OK;
425 }
426 return (isp_target_put_entry(isp, &atun));
427 }
428
429 /*
430 * Command completion- both for handling cases of no resources or
431 * no blackhole driver, or other cases where we have to, inline,
432 * finish the command sanely, or for normal command completion.
433 *
434 * The 'completion' code value has the scsi status byte in the low 8 bits.
435 * If status is a CHECK CONDITION and bit 8 is nonzero, then bits 12..15 have
436 * the sense key and bits 16..23 have the ASCQ and bits 24..31 have the ASC
437 * values.
438 *
439 * NB: the key, asc, ascq, cannot be used for parallel SCSI as it doesn't
440 * NB: inline SCSI sense reporting. As such, we lose this information. XXX.
441 *
442 * For both parallel && fibre channel, we use the feature that does
443 * an automatic resource autoreplenish so we don't have then later do
444 * put of an atio to replenish the f/w's resource count.
445 */
446
447 int
448 isp_endcmd(struct ispsoftc *isp, void *arg, u_int32_t code, u_int16_t hdl)
449 {
450 int sts;
451 union {
452 ct_entry_t _ctio;
453 ct2_entry_t _ctio2;
454 } un;
455
456 MEMZERO(&un, sizeof un);
457 sts = code & 0xff;
458
459 if (IS_FC(isp)) {
460 at2_entry_t *aep = arg;
461 ct2_entry_t *cto = &un._ctio2;
462
463 cto->ct_header.rqs_entry_type = RQSTYPE_CTIO2;
464 cto->ct_header.rqs_entry_count = 1;
465 cto->ct_iid = aep->at_iid;
466 if ((FCPARAM(isp)->isp_fwattr & ISP_FW_ATTR_SCCLUN) == 0) {
467 cto->ct_lun = aep->at_lun;
468 }
469 cto->ct_rxid = aep->at_rxid;
470 cto->rsp.m1.ct_scsi_status = sts & 0xff;
471 cto->ct_flags = CT2_SENDSTATUS | CT2_NO_DATA | CT2_FLAG_MODE1;
472 if (hdl == 0) {
473 cto->ct_flags |= CT2_CCINCR;
474 }
475 if (aep->at_datalen) {
476 cto->ct_resid = aep->at_datalen;
477 cto->rsp.m1.ct_scsi_status |= CT2_DATA_UNDER;
478 }
479 if ((sts & 0xff) == SCSI_CHECK && (sts & ECMD_SVALID)) {
480 cto->rsp.m1.ct_resp[0] = 0xf0;
481 cto->rsp.m1.ct_resp[2] = (code >> 12) & 0xf;
482 cto->rsp.m1.ct_resp[7] = 8;
483 cto->rsp.m1.ct_resp[12] = (code >> 24) & 0xff;
484 cto->rsp.m1.ct_resp[13] = (code >> 16) & 0xff;
485 cto->rsp.m1.ct_senselen = 16;
486 cto->rsp.m1.ct_scsi_status |= CT2_SNSLEN_VALID;
487 }
488 cto->ct_syshandle = hdl;
489 } else {
490 at_entry_t *aep = arg;
491 ct_entry_t *cto = &un._ctio;
492
493 cto->ct_header.rqs_entry_type = RQSTYPE_CTIO;
494 cto->ct_header.rqs_entry_count = 1;
495 cto->ct_fwhandle = aep->at_handle;
496 cto->ct_iid = aep->at_iid;
497 cto->ct_tgt = aep->at_tgt;
498 cto->ct_lun = aep->at_lun;
499 cto->ct_tag_type = aep->at_tag_type;
500 cto->ct_tag_val = aep->at_tag_val;
501 if (aep->at_flags & AT_TQAE) {
502 cto->ct_flags |= CT_TQAE;
503 }
504 cto->ct_flags = CT_SENDSTATUS | CT_NO_DATA;
505 if (hdl == 0) {
506 cto->ct_flags |= CT_CCINCR;
507 }
508 cto->ct_scsi_status = sts;
509 cto->ct_syshandle = hdl;
510 }
511 return (isp_target_put_entry(isp, &un));
512 }
513
514 void
515 isp_target_async(struct ispsoftc *isp, int bus, int event)
516 {
517 tmd_event_t evt;
518 tmd_msg_t msg;
519
520 switch (event) {
521 /*
522 * These three we handle here to propagate an effective bus reset
523 * upstream, but these do not require any immediate notify actions
524 * so we return when done.
525 */
526 case ASYNC_LIP_F8:
527 case ASYNC_LIP_OCCURRED:
528 case ASYNC_LOOP_UP:
529 case ASYNC_LOOP_DOWN:
530 case ASYNC_LOOP_RESET:
531 case ASYNC_PTPMODE:
532 /*
533 * These don't require any immediate notify actions. We used
534 * treat them like SCSI Bus Resets, but that was just plain
535 * wrong. Let the normal CTIO completion report what occurred.
536 */
537 return;
538
539 case ASYNC_BUS_RESET:
540 case ASYNC_TIMEOUT_RESET:
541 if (IS_FC(isp)) {
542 return; /* we'll be getting an inotify instead */
543 }
544 evt.ev_bus = bus;
545 evt.ev_event = event;
546 (void) isp_async(isp, ISPASYNC_TARGET_EVENT, &evt);
547 break;
548 case ASYNC_DEVICE_RESET:
549 /*
550 * Bus Device Reset resets a specific target, so
551 * we pass this as a synthesized message.
552 */
553 MEMZERO(&msg, sizeof msg);
554 if (IS_FC(isp)) {
555 msg.nt_iid = FCPARAM(isp)->isp_loopid;
556 } else {
557 msg.nt_iid = SDPARAM(isp)->isp_initiator_id;
558 }
559 msg.nt_bus = bus;
560 msg.nt_msg[0] = MSG_BUS_DEV_RESET;
561 (void) isp_async(isp, ISPASYNC_TARGET_MESSAGE, &msg);
562 break;
563 default:
564 isp_prt(isp, ISP_LOGERR,
565 "isp_target_async: unknown event 0x%x", event);
566 break;
567 }
568 if (isp->isp_state == ISP_RUNSTATE)
569 isp_notify_ack(isp, NULL);
570 }
571
572
573 /*
574 * Process a received message.
575 * The ISP firmware can handle most messages, there are only
576 * a few that we need to deal with:
577 * - abort: clean up the current command
578 * - abort tag and clear queue
579 */
580
581 static void
582 isp_got_msg(struct ispsoftc *isp, int bus, in_entry_t *inp)
583 {
584 u_int8_t status = inp->in_status & ~QLTM_SVALID;
585
586 if (status == IN_IDE_RECEIVED || status == IN_MSG_RECEIVED) {
587 tmd_msg_t msg;
588
589 MEMZERO(&msg, sizeof (msg));
590 msg.nt_bus = bus;
591 msg.nt_iid = inp->in_iid;
592 msg.nt_tgt = inp->in_tgt;
593 msg.nt_lun = inp->in_lun;
594 msg.nt_tagtype = inp->in_tag_type;
595 msg.nt_tagval = inp->in_tag_val;
596 MEMCPY(msg.nt_msg, inp->in_msg, IN_MSGLEN);
597 (void) isp_async(isp, ISPASYNC_TARGET_MESSAGE, &msg);
598 } else {
599 isp_prt(isp, ISP_LOGERR,
600 "unknown immediate notify status 0x%x", inp->in_status);
601 }
602 }
603
604 /*
605 * Synthesize a message from the task management flags in a FCP_CMND_IU.
606 */
607 static void
608 isp_got_msg_fc(struct ispsoftc *isp, int bus, in_fcentry_t *inp)
609 {
610 int lun;
611 static const char f1[] = "%s from iid %d lun %d seq 0x%x";
612 static const char f2[] =
613 "unknown %s 0x%x lun %d iid %d task flags 0x%x seq 0x%x\n";
614
615 if (FCPARAM(isp)->isp_fwattr & ISP_FW_ATTR_SCCLUN) {
616 lun = inp->in_scclun;
617 } else {
618 lun = inp->in_lun;
619 }
620
621 if (inp->in_status != IN_MSG_RECEIVED) {
622 isp_prt(isp, ISP_LOGINFO, f2, "immediate notify status",
623 inp->in_status, lun, inp->in_iid,
624 inp->in_task_flags, inp->in_seqid);
625 } else {
626 tmd_msg_t msg;
627
628 MEMZERO(&msg, sizeof (msg));
629 msg.nt_bus = bus;
630 msg.nt_iid = inp->in_iid;
631 msg.nt_tagval = inp->in_seqid;
632 msg.nt_lun = lun;
633
634 if (inp->in_task_flags & TASK_FLAGS_ABORT_TASK) {
635 isp_prt(isp, ISP_LOGINFO, f1, "ABORT TASK",
636 inp->in_iid, msg.nt_lun, inp->in_seqid);
637 msg.nt_msg[0] = MSG_ABORT_TAG;
638 } else if (inp->in_task_flags & TASK_FLAGS_CLEAR_TASK_SET) {
639 isp_prt(isp, ISP_LOGINFO, f1, "CLEAR TASK SET",
640 inp->in_iid, msg.nt_lun, inp->in_seqid);
641 msg.nt_msg[0] = MSG_CLEAR_QUEUE;
642 } else if (inp->in_task_flags & TASK_FLAGS_TARGET_RESET) {
643 isp_prt(isp, ISP_LOGINFO, f1, "TARGET RESET",
644 inp->in_iid, msg.nt_lun, inp->in_seqid);
645 msg.nt_msg[0] = MSG_BUS_DEV_RESET;
646 } else if (inp->in_task_flags & TASK_FLAGS_CLEAR_ACA) {
647 isp_prt(isp, ISP_LOGINFO, f1, "CLEAR ACA",
648 inp->in_iid, msg.nt_lun, inp->in_seqid);
649 /* ???? */
650 msg.nt_msg[0] = MSG_REL_RECOVERY;
651 } else if (inp->in_task_flags & TASK_FLAGS_TERMINATE_TASK) {
652 isp_prt(isp, ISP_LOGINFO, f1, "TERMINATE TASK",
653 inp->in_iid, msg.nt_lun, inp->in_seqid);
654 msg.nt_msg[0] = MSG_TERM_IO_PROC;
655 } else {
656 isp_prt(isp, ISP_LOGWARN, f2, "task flag",
657 inp->in_status, msg.nt_lun, inp->in_iid,
658 inp->in_task_flags, inp->in_seqid);
659 }
660 if (msg.nt_msg[0]) {
661 (void) isp_async(isp, ISPASYNC_TARGET_MESSAGE, &msg);
662 }
663 }
664 }
665
666 static void
667 isp_notify_ack(struct ispsoftc *isp, void *arg)
668 {
669 char storage[QENTRY_LEN];
670 u_int16_t iptr, optr;
671 void *outp;
672
673 if (isp_getrqentry(isp, &iptr, &optr, &outp)) {
674 isp_prt(isp, ISP_LOGWARN,
675 "Request Queue Overflow For isp_notify_ack");
676 return;
677 }
678
679 MEMZERO(storage, QENTRY_LEN);
680
681 if (IS_FC(isp)) {
682 na_fcentry_t *na = (na_fcentry_t *) storage;
683 if (arg) {
684 in_fcentry_t *inp = arg;
685 MEMCPY(storage, arg, sizeof (isphdr_t));
686 na->na_iid = inp->in_iid;
687 if (FCPARAM(isp)->isp_fwattr & ISP_FW_ATTR_SCCLUN) {
688 na->na_lun = inp->in_scclun;
689 } else {
690 na->na_lun = inp->in_lun;
691 }
692 na->na_task_flags = inp->in_task_flags;
693 na->na_seqid = inp->in_seqid;
694 na->na_flags = NAFC_RCOUNT;
695 if (inp->in_status == IN_RESET) {
696 na->na_flags |= NAFC_RST_CLRD;
697 }
698 } else {
699 na->na_flags = NAFC_RST_CLRD;
700 }
701 na->na_header.rqs_entry_type = RQSTYPE_NOTIFY_ACK;
702 na->na_header.rqs_entry_count = 1;
703 ISP_SWIZ_NOT_ACK_FC(isp, outp, na);
704 } else {
705 na_entry_t *na = (na_entry_t *) storage;
706 if (arg) {
707 in_entry_t *inp = arg;
708 MEMCPY(storage, arg, sizeof (isphdr_t));
709 na->na_iid = inp->in_iid;
710 na->na_lun = inp->in_lun;
711 na->na_tgt = inp->in_tgt;
712 na->na_seqid = inp->in_seqid;
713 if (inp->in_status == IN_RESET) {
714 na->na_event = NA_RST_CLRD;
715 }
716 } else {
717 na->na_event = NA_RST_CLRD;
718 }
719 na->na_header.rqs_entry_type = RQSTYPE_NOTIFY_ACK;
720 na->na_header.rqs_entry_count = 1;
721 ISP_SWIZ_NOT_ACK(isp, outp, na);
722 }
723 ISP_TDQE(isp, "isp_notify_ack", (int) optr, storage);
724 ISP_ADD_REQUEST(isp, iptr);
725 }
726
727 static void
728 isp_handle_atio(struct ispsoftc *isp, at_entry_t *aep)
729 {
730 int lun;
731 lun = aep->at_lun;
732 /*
733 * The firmware status (except for the QLTM_SVALID bit) indicates
734 * why this ATIO was sent to us.
735 *
736 * If QLTM_SVALID is set, the firware has recommended Sense Data.
737 *
738 * If the DISCONNECTS DISABLED bit is set in the flags field,
739 * we're still connected on the SCSI bus - i.e. the initiator
740 * did not set DiscPriv in the identify message. We don't care
741 * about this so it's ignored.
742 */
743
744 switch(aep->at_status & ~QLTM_SVALID) {
745 case AT_PATH_INVALID:
746 /*
747 * ATIO rejected by the firmware due to disabled lun.
748 */
749 isp_prt(isp, ISP_LOGERR,
750 "rejected ATIO for disabled lun %d", lun);
751 break;
752 case AT_NOCAP:
753 /*
754 * Requested Capability not available
755 * We sent an ATIO that overflowed the firmware's
756 * command resource count.
757 */
758 isp_prt(isp, ISP_LOGERR,
759 "rejected ATIO for lun %d because of command count"
760 " overflow", lun);
761 break;
762
763 case AT_BDR_MSG:
764 /*
765 * If we send an ATIO to the firmware to increment
766 * its command resource count, and the firmware is
767 * recovering from a Bus Device Reset, it returns
768 * the ATIO with this status. We set the command
769 * resource count in the Enable Lun entry and no
770 * not increment it. Therefore we should never get
771 * this status here.
772 */
773 isp_prt(isp, ISP_LOGERR, atiocope, lun,
774 GET_BUS_VAL(aep->at_iid));
775 break;
776
777 case AT_CDB: /* Got a CDB */
778 case AT_PHASE_ERROR: /* Bus Phase Sequence Error */
779 /*
780 * Punt to platform specific layer.
781 */
782 (void) isp_async(isp, ISPASYNC_TARGET_ACTION, aep);
783 break;
784
785 case AT_RESET:
786 /*
787 * A bus reset came along an blew away this command. Why
788 * they do this in addition the async event code stuff,
789 * I dunno.
790 *
791 * Ignore it because the async event will clear things
792 * up for us.
793 */
794 isp_prt(isp, ISP_LOGWARN, atior, lun,
795 GET_IID_VAL(aep->at_iid), GET_BUS_VAL(aep->at_iid));
796 break;
797
798
799 default:
800 isp_prt(isp, ISP_LOGERR,
801 "Unknown ATIO status 0x%x from initiator %d for lun %d",
802 aep->at_status, aep->at_iid, lun);
803 (void) isp_target_put_atio(isp, aep);
804 break;
805 }
806 }
807
808 static void
809 isp_handle_atio2(struct ispsoftc *isp, at2_entry_t *aep)
810 {
811 int lun;
812
813 if (FCPARAM(isp)->isp_fwattr & ISP_FW_ATTR_SCCLUN) {
814 lun = aep->at_scclun;
815 } else {
816 lun = aep->at_lun;
817 }
818
819 /*
820 * The firmware status (except for the QLTM_SVALID bit) indicates
821 * why this ATIO was sent to us.
822 *
823 * If QLTM_SVALID is set, the firware has recommended Sense Data.
824 *
825 * If the DISCONNECTS DISABLED bit is set in the flags field,
826 * we're still connected on the SCSI bus - i.e. the initiator
827 * did not set DiscPriv in the identify message. We don't care
828 * about this so it's ignored.
829 */
830
831 switch(aep->at_status & ~QLTM_SVALID) {
832 case AT_PATH_INVALID:
833 /*
834 * ATIO rejected by the firmware due to disabled lun.
835 */
836 isp_prt(isp, ISP_LOGERR,
837 "rejected ATIO2 for disabled lun %d", lun);
838 break;
839 case AT_NOCAP:
840 /*
841 * Requested Capability not available
842 * We sent an ATIO that overflowed the firmware's
843 * command resource count.
844 */
845 isp_prt(isp, ISP_LOGERR,
846 "rejected ATIO2 for lun %d- command count overflow", lun);
847 break;
848
849 case AT_BDR_MSG:
850 /*
851 * If we send an ATIO to the firmware to increment
852 * its command resource count, and the firmware is
853 * recovering from a Bus Device Reset, it returns
854 * the ATIO with this status. We set the command
855 * resource count in the Enable Lun entry and no
856 * not increment it. Therefore we should never get
857 * this status here.
858 */
859 isp_prt(isp, ISP_LOGERR, atiocope, lun, 0);
860 break;
861
862 case AT_CDB: /* Got a CDB */
863 /*
864 * Punt to platform specific layer.
865 */
866 (void) isp_async(isp, ISPASYNC_TARGET_ACTION, aep);
867 break;
868
869 case AT_RESET:
870 /*
871 * A bus reset came along an blew away this command. Why
872 * they do this in addition the async event code stuff,
873 * I dunno.
874 *
875 * Ignore it because the async event will clear things
876 * up for us.
877 */
878 isp_prt(isp, ISP_LOGERR, atior, lun, aep->at_iid, 0);
879 break;
880
881
882 default:
883 isp_prt(isp, ISP_LOGERR,
884 "Unknown ATIO2 status 0x%x from initiator %d for lun %d",
885 aep->at_status, aep->at_iid, lun);
886 (void) isp_target_put_atio(isp, aep);
887 break;
888 }
889 }
890
891 static void
892 isp_handle_ctio(struct ispsoftc *isp, ct_entry_t *ct)
893 {
894 void *xs;
895 int pl = ISP_LOGTDEBUG2;
896 char *fmsg = NULL;
897
898 if (ct->ct_syshandle) {
899 xs = isp_find_xs(isp, ct->ct_syshandle);
900 if (xs == NULL)
901 pl = ISP_LOGALL;
902 } else {
903 xs = NULL;
904 }
905
906 switch(ct->ct_status & ~QLTM_SVALID) {
907 case CT_OK:
908 /*
909 * There are generally 3 possibilities as to why we'd get
910 * this condition:
911 * We disconnected after receiving a CDB.
912 * We sent or received data.
913 * We sent status & command complete.
914 */
915
916 if (ct->ct_flags & CT_SENDSTATUS) {
917 break;
918 } else if ((ct->ct_flags & CT_DATAMASK) == CT_NO_DATA) {
919 /*
920 * Nothing to do in this case.
921 */
922 isp_prt(isp, pl, "CTIO- iid %d disconnected OK",
923 ct->ct_iid);
924 return;
925 }
926 break;
927
928 case CT_BDR_MSG:
929 /*
930 * Bus Device Reset message received or the SCSI Bus has
931 * been Reset; the firmware has gone to Bus Free.
932 *
933 * The firmware generates an async mailbox interupt to
934 * notify us of this and returns outstanding CTIOs with this
935 * status. These CTIOs are handled in that same way as
936 * CT_ABORTED ones, so just fall through here.
937 */
938 fmsg = "Bus Device Reset";
939 /*FALLTHROUGH*/
940 case CT_RESET:
941 if (fmsg == NULL)
942 fmsg = "Bus Reset";
943 /*FALLTHROUGH*/
944 case CT_ABORTED:
945 /*
946 * When an Abort message is received the firmware goes to
947 * Bus Free and returns all outstanding CTIOs with the status
948 * set, then sends us an Immediate Notify entry.
949 */
950 if (fmsg == NULL)
951 fmsg = "ABORT TAG message sent by Initiator";
952
953 isp_prt(isp, ISP_LOGWARN, "CTIO destroyed by %s", fmsg);
954 break;
955
956 case CT_INVAL:
957 /*
958 * CTIO rejected by the firmware due to disabled lun.
959 * "Cannot Happen".
960 */
961 isp_prt(isp, ISP_LOGERR,
962 "Firmware rejected CTIO for disabled lun %d",
963 ct->ct_lun);
964 break;
965
966 case CT_NOPATH:
967 /*
968 * CTIO rejected by the firmware due "no path for the
969 * nondisconnecting nexus specified". This means that
970 * we tried to access the bus while a non-disconnecting
971 * command is in process.
972 */
973 isp_prt(isp, ISP_LOGERR,
974 "Firmware rejected CTIO for bad nexus %d/%d/%d",
975 ct->ct_iid, ct->ct_tgt, ct->ct_lun);
976 break;
977
978 case CT_RSELTMO:
979 fmsg = "Reselection";
980 /*FALLTHROUGH*/
981 case CT_TIMEOUT:
982 if (fmsg == NULL)
983 fmsg = "Command";
984 isp_prt(isp, ISP_LOGERR, "Firmware timed out on %s", fmsg);
985 break;
986
987 case CT_PANIC:
988 if (fmsg == NULL)
989 fmsg = "Unrecoverable Error";
990 /*FALLTHROUGH*/
991 case CT_ERR:
992 if (fmsg == NULL)
993 fmsg = "Completed with Error";
994 /*FALLTHROUGH*/
995 case CT_PHASE_ERROR:
996 if (fmsg == NULL)
997 fmsg = "Phase Sequence Error";
998 /*FALLTHROUGH*/
999 case CT_TERMINATED:
1000 if (fmsg == NULL)
1001 fmsg = "terminated by TERMINATE TRANSFER";
1002 /*FALLTHROUGH*/
1003 case CT_NOACK:
1004 if (fmsg == NULL)
1005 fmsg = "unacknowledged Immediate Notify pending";
1006 isp_prt(isp, ISP_LOGERR, "CTIO returned by f/w- %s", fmsg);
1007 break;
1008 default:
1009 isp_prt(isp, ISP_LOGERR, "Unknown CTIO status 0x%x",
1010 ct->ct_status & ~QLTM_SVALID);
1011 break;
1012 }
1013
1014 if (xs == NULL) {
1015 /*
1016 * There may be more than one CTIO for a data transfer,
1017 * or this may be a status CTIO we're not monitoring.
1018 *
1019 * The assumption is that they'll all be returned in the
1020 * order we got them.
1021 */
1022 if (ct->ct_syshandle == 0) {
1023 if ((ct->ct_flags & CT_SENDSTATUS) == 0) {
1024 isp_prt(isp, pl,
1025 "intermediate CTIO completed ok");
1026 } else {
1027 isp_prt(isp, pl,
1028 "unmonitored CTIO completed ok");
1029 }
1030 } else {
1031 isp_prt(isp, pl,
1032 "NO xs for CTIO (handle 0x%x) status 0x%x",
1033 ct->ct_syshandle, ct->ct_status & ~QLTM_SVALID);
1034 }
1035 } else {
1036 /*
1037 * Final CTIO completed. Release DMA resources and
1038 * notify platform dependent layers.
1039 */
1040 if ((ct->ct_flags & CT_DATAMASK) != CT_NO_DATA) {
1041 ISP_DMAFREE(isp, xs, ct->ct_syshandle);
1042 }
1043 isp_prt(isp, pl, "final CTIO complete");
1044 /*
1045 * The platform layer will destroy the handle if appropriate.
1046 */
1047 (void) isp_async(isp, ISPASYNC_TARGET_ACTION, ct);
1048 }
1049 }
1050
1051 static void
1052 isp_handle_ctio2(struct ispsoftc *isp, ct2_entry_t *ct)
1053 {
1054 XS_T *xs;
1055 int pl = ISP_LOGTDEBUG2;
1056 char *fmsg = NULL;
1057
1058 if (ct->ct_syshandle) {
1059 xs = isp_find_xs(isp, ct->ct_syshandle);
1060 if (xs == NULL)
1061 pl = ISP_LOGALL;
1062 } else {
1063 xs = NULL;
1064 }
1065
1066 switch(ct->ct_status & ~QLTM_SVALID) {
1067 case CT_BUS_ERROR:
1068 isp_prt(isp, ISP_LOGERR, "PCI DMA Bus Error");
1069 /* FALL Through */
1070 case CT_DATA_OVER:
1071 case CT_DATA_UNDER:
1072 case CT_OK:
1073 /*
1074 * There are generally 2 possibilities as to why we'd get
1075 * this condition:
1076 * We sent or received data.
1077 * We sent status & command complete.
1078 */
1079
1080 break;
1081
1082 case CT_BDR_MSG:
1083 /*
1084 * Target Reset function received.
1085 *
1086 * The firmware generates an async mailbox interupt to
1087 * notify us of this and returns outstanding CTIOs with this
1088 * status. These CTIOs are handled in that same way as
1089 * CT_ABORTED ones, so just fall through here.
1090 */
1091 fmsg = "TARGET RESET Task Management Function Received";
1092 /*FALLTHROUGH*/
1093 case CT_RESET:
1094 if (fmsg == NULL)
1095 fmsg = "LIP Reset";
1096 /*FALLTHROUGH*/
1097 case CT_ABORTED:
1098 /*
1099 * When an Abort message is received the firmware goes to
1100 * Bus Free and returns all outstanding CTIOs with the status
1101 * set, then sends us an Immediate Notify entry.
1102 */
1103 if (fmsg == NULL)
1104 fmsg = "ABORT Task Management Function Received";
1105
1106 isp_prt(isp, ISP_LOGERR, "CTIO2 destroyed by %s", fmsg);
1107 break;
1108
1109 case CT_INVAL:
1110 /*
1111 * CTIO rejected by the firmware - invalid data direction.
1112 */
1113 isp_prt(isp, ISP_LOGERR, "CTIO2 had wrong data directiond");
1114 break;
1115
1116 case CT_RSELTMO:
1117 fmsg = "failure to reconnect to initiator";
1118 /*FALLTHROUGH*/
1119 case CT_TIMEOUT:
1120 if (fmsg == NULL)
1121 fmsg = "command";
1122 isp_prt(isp, ISP_LOGERR, "Firmware timed out on %s", fmsg);
1123 break;
1124
1125 case CT_ERR:
1126 fmsg = "Completed with Error";
1127 /*FALLTHROUGH*/
1128 case CT_LOGOUT:
1129 if (fmsg == NULL)
1130 fmsg = "Port Logout";
1131 /*FALLTHROUGH*/
1132 case CT_PORTNOTAVAIL:
1133 if (fmsg == NULL)
1134 fmsg = "Port not available";
1135 case CT_PORTCHANGED:
1136 if (fmsg == NULL)
1137 fmsg = "Port Changed";
1138 case CT_NOACK:
1139 if (fmsg == NULL)
1140 fmsg = "unacknowledged Immediate Notify pending";
1141 isp_prt(isp, ISP_LOGERR, "CTIO returned by f/w- %s", fmsg);
1142 break;
1143
1144 case CT_INVRXID:
1145 /*
1146 * CTIO rejected by the firmware because an invalid RX_ID.
1147 * Just print a message.
1148 */
1149 isp_prt(isp, ISP_LOGERR,
1150 "CTIO2 completed with Invalid RX_ID 0x%x", ct->ct_rxid);
1151 break;
1152
1153 default:
1154 isp_prt(isp, ISP_LOGERR, "Unknown CTIO2 status 0x%x",
1155 ct->ct_status & ~QLTM_SVALID);
1156 break;
1157 }
1158
1159 if (xs == NULL) {
1160 /*
1161 * There may be more than one CTIO for a data transfer,
1162 * or this may be a status CTIO we're not monitoring.
1163 *
1164 * The assumption is that they'll all be returned in the
1165 * order we got them.
1166 */
1167 if (ct->ct_syshandle == 0) {
1168 if ((ct->ct_flags & CT_SENDSTATUS) == 0) {
1169 isp_prt(isp, pl,
1170 "intermediate CTIO completed ok");
1171 } else {
1172 isp_prt(isp, pl,
1173 "unmonitored CTIO completed ok");
1174 }
1175 } else {
1176 isp_prt(isp, pl,
1177 "NO xs for CTIO (handle 0x%x) status 0x%x",
1178 ct->ct_syshandle, ct->ct_status & ~QLTM_SVALID);
1179 }
1180 } else {
1181 if ((ct->ct_flags & CT2_DATAMASK) != CT2_NO_DATA) {
1182 ISP_DMAFREE(isp, xs, ct->ct_syshandle);
1183 }
1184 if (ct->ct_flags & CT_SENDSTATUS) {
1185 /*
1186 * Sent status and command complete.
1187 *
1188 * We're now really done with this command, so we
1189 * punt to the platform dependent layers because
1190 * only there can we do the appropriate command
1191 * complete thread synchronization.
1192 */
1193 isp_prt(isp, pl, "status CTIO complete");
1194 } else {
1195 /*
1196 * Final CTIO completed. Release DMA resources and
1197 * notify platform dependent layers.
1198 */
1199 isp_prt(isp, pl, "data CTIO complete");
1200 }
1201 (void) isp_async(isp, ISPASYNC_TARGET_ACTION, ct);
1202 /*
1203 * The platform layer will destroy the handle if appropriate.
1204 */
1205 }
1206 }
1207 #endif
1208