isp_target.c revision 1.30 1 /* $NetBSD: isp_target.c,v 1.30 2007/05/24 21:30:43 mjacob Exp $ */
2 /*-
3 * Copyright (c) 1997-2006 by Matthew Jacob
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 */
28 /*
29 * Machine and OS Independent Target Mode Code for the Qlogic SCSI/FC adapters.
30 */
31 /*
32 * Bug fixes gratefully acknowledged from:
33 * Oded Kedem <oded (at) kashya.com>
34 */
35 /*
36 * Include header file appropriate for platform we're building on.
37 */
38
39 #ifdef __NetBSD__
40 #include <sys/cdefs.h>
41 __KERNEL_RCSID(0, "$NetBSD: isp_target.c,v 1.30 2007/05/24 21:30:43 mjacob Exp $");
42 #include <dev/ic/isp_netbsd.h>
43 #endif
44 #ifdef __FreeBSD__
45 #include <sys/cdefs.h>
46 __FBSDID("$FreeBSD:$");
47 #include <dev/isp/isp_freebsd.h>
48 #endif
49 #ifdef __OpenBSD__
50 #include <dev/ic/isp_openbsd.h>
51 #endif
52 #ifdef __linux__
53 #include "isp_linux.h"
54 #endif
55
56 #ifdef ISP_TARGET_MODE
57 static const char atiocope[] =
58 "ATIO returned for lun %d because it was in the middle of Bus Device Reset "
59 "on bus %d";
60 static const char atior[] =
61 "ATIO returned on for lun %d on from loopid %d because a Bus Reset "
62 "occurred on bus %d";
63
64 static void isp_got_msg(ispsoftc_t *, in_entry_t *);
65 static void isp_got_msg_fc(ispsoftc_t *, in_fcentry_t *);
66 static void isp_got_tmf_24xx(ispsoftc_t *, at7_entry_t *);
67 static void isp_handle_atio(ispsoftc_t *, at_entry_t *);
68 static void isp_handle_atio2(ispsoftc_t *, at2_entry_t *);
69 static void isp_handle_ctio(ispsoftc_t *, ct_entry_t *);
70 static void isp_handle_ctio2(ispsoftc_t *, ct2_entry_t *);
71 static void isp_handle_ctio7(ispsoftc_t *, ct7_entry_t *);
72
73 /*
74 * The Qlogic driver gets an interrupt to look at response queue entries.
75 * Some of these are status completions for initiatior mode commands, but
76 * if target mode is enabled, we get a whole wad of response queue entries
77 * to be handled here.
78 *
79 * Basically the split into 3 main groups: Lun Enable/Modification responses,
80 * SCSI Command processing, and Immediate Notification events.
81 *
82 * You start by writing a request queue entry to enable target mode (and
83 * establish some resource limitations which you can modify later).
84 * The f/w responds with a LUN ENABLE or LUN MODIFY response with
85 * the status of this action. If the enable was successful, you can expect...
86 *
87 * Response queue entries with SCSI commands encapsulate show up in an ATIO
88 * (Accept Target IO) type- sometimes with enough info to stop the command at
89 * this level. Ultimately the driver has to feed back to the f/w's request
90 * queue a sequence of CTIOs (continue target I/O) that describe data to
91 * be moved and/or status to be sent) and finally finishing with sending
92 * to the f/w's response queue an ATIO which then completes the handshake
93 * with the f/w for that command. There's a lot of variations on this theme,
94 * including flags you can set in the CTIO for the Qlogic 2X00 fibre channel
95 * cards that 'auto-replenish' the f/w's ATIO count, but this is the basic
96 * gist of it.
97 *
98 * The third group that can show up in the response queue are Immediate
99 * Notification events. These include things like notifications of SCSI bus
100 * resets, or Bus Device Reset messages or other messages received. This
101 * a classic oddbins area. It can get a little weird because you then turn
102 * around and acknowledge the Immediate Notify by writing an entry onto the
103 * request queue and then the f/w turns around and gives you an acknowledgement
104 * to *your* acknowledgement on the response queue (the idea being to let
105 * the f/w tell you when the event is *really* over I guess).
106 *
107 */
108
109
110 /*
111 * A new response queue entry has arrived. The interrupt service code
112 * has already swizzled it into the platform dependent from canonical form.
113 *
114 * Because of the way this driver is designed, unfortunately most of the
115 * actual synchronization work has to be done in the platform specific
116 * code- we have no synchroniation primitives in the common code.
117 */
118
119 int
120 isp_target_notify(ispsoftc_t *isp, void *vptr, uint32_t *optrp)
121 {
122 uint16_t status;
123 uint32_t seqid;
124 union {
125 at_entry_t *atiop;
126 at2_entry_t *at2iop;
127 at2e_entry_t *at2eiop;
128 at7_entry_t *at7iop;
129 ct_entry_t *ctiop;
130 ct2_entry_t *ct2iop;
131 ct2e_entry_t *ct2eiop;
132 ct7_entry_t *ct7iop;
133 lun_entry_t *lunenp;
134 in_entry_t *inotp;
135 in_fcentry_t *inot_fcp;
136 in_fcentry_e_t *inote_fcp;
137 in_fcentry_24xx_t *inot_24xx;
138 na_entry_t *nackp;
139 na_fcentry_t *nack_fcp;
140 na_fcentry_e_t *nacke_fcp;
141 na_fcentry_24xx_t *nack_24xx;
142 isphdr_t *hp;
143 abts_t *abts;
144 abts_rsp_t *abts_rsp;
145 els_t *els;
146 void * *vp;
147 #define atiop unp.atiop
148 #define at2iop unp.at2iop
149 #define at2eiop unp.at2eiop
150 #define at7iop unp.at7iop
151 #define ctiop unp.ctiop
152 #define ct2iop unp.ct2iop
153 #define ct2eiop unp.ct2eiop
154 #define ct7iop unp.ct7iop
155 #define lunenp unp.lunenp
156 #define inotp unp.inotp
157 #define inot_fcp unp.inot_fcp
158 #define inote_fcp unp.inote_fcp
159 #define inot_24xx unp.inot_24xx
160 #define nackp unp.nackp
161 #define nack_fcp unp.nack_fcp
162 #define nacke_fcp unp.nacke_fcp
163 #define nack_24xx unp.nack_24xx
164 #define abts unp.abts
165 #define abts_rsp unp.abts_rsp
166 #define els unp.els
167 #define hdrp unp.hp
168 } unp;
169 uint8_t local[QENTRY_LEN];
170 int bus, type, level, rval = 1;
171
172 type = isp_get_response_type(isp, (isphdr_t *)vptr);
173 unp.vp = vptr;
174
175 ISP_TDQE(isp, "isp_target_notify", (int) *optrp, vptr);
176
177 switch(type) {
178 case RQSTYPE_ATIO:
179 if (IS_24XX(isp)) {
180 int len;
181
182 isp_get_atio7(isp, at7iop, (at7_entry_t *) local);
183 at7iop = (at7_entry_t *) local;
184 /*
185 * Check for and do something with commands whose IULEN
186 * extends past a singel queue entry.
187 */
188 len = at7iop->at_ta_len & 0xfffff;
189 if (len > (QENTRY_LEN - 8)) {
190 len -= (QENTRY_LEN - 8);
191 isp_prt(isp, ISP_LOGINFO,
192 "long IU length (%d) ignored", len);
193 while (len > 0) {
194 *optrp = ISP_NXT_QENTRY(*optrp,
195 RESULT_QUEUE_LEN(isp));
196 len -= QENTRY_LEN;
197 }
198 }
199 /*
200 * Check for a task management function
201 */
202 if (at7iop->at_cmnd.fcp_cmnd_task_management) {
203 isp_got_tmf_24xx(isp, at7iop);
204 break;
205 }
206 /*
207 * Just go straight to outer layer for this one.
208 */
209 (void) isp_async(isp, ISPASYNC_TARGET_ACTION, local);
210 } else {
211 isp_get_atio(isp, atiop, (at_entry_t *) local);
212 isp_handle_atio(isp, (at_entry_t *) local);
213 }
214 break;
215
216 case RQSTYPE_CTIO:
217 isp_get_ctio(isp, ctiop, (ct_entry_t *) local);
218 isp_handle_ctio(isp, (ct_entry_t *) local);
219 break;
220
221 case RQSTYPE_ATIO2:
222 if (FCPARAM(isp)->isp_2klogin) {
223 isp_get_atio2e(isp, at2eiop, (at2e_entry_t *) local);
224 } else {
225 isp_get_atio2(isp, at2iop, (at2_entry_t *) local);
226 }
227 isp_handle_atio2(isp, (at2_entry_t *) local);
228 break;
229
230 case RQSTYPE_CTIO3:
231 case RQSTYPE_CTIO2:
232 if (FCPARAM(isp)->isp_2klogin) {
233 isp_get_ctio2e(isp, ct2eiop, (ct2e_entry_t *) local);
234 } else {
235 isp_get_ctio2(isp, ct2iop, (ct2_entry_t *) local);
236 }
237 isp_handle_ctio2(isp, (ct2_entry_t *) local);
238 break;
239
240 case RQSTYPE_CTIO7:
241 isp_get_ctio7(isp, ct7iop, (ct7_entry_t *) local);
242 isp_handle_ctio7(isp, (ct7_entry_t *) local);
243 break;
244
245 case RQSTYPE_ENABLE_LUN:
246 case RQSTYPE_MODIFY_LUN:
247 isp_get_enable_lun(isp, lunenp, (lun_entry_t *) local);
248 (void) isp_async(isp, ISPASYNC_TARGET_ACTION, local);
249 break;
250
251 case RQSTYPE_NOTIFY:
252 /*
253 * Either the ISP received a SCSI message it can't
254 * handle, or it's returning an Immed. Notify entry
255 * we sent. We can send Immed. Notify entries to
256 * increment the firmware's resource count for them
257 * (we set this initially in the Enable Lun entry).
258 */
259 bus = 0;
260 if (IS_24XX(isp)) {
261 isp_get_notify_24xx(isp, inot_24xx,
262 (in_fcentry_24xx_t *)local);
263 inot_24xx = (in_fcentry_24xx_t *) local;
264 status = inot_24xx->in_status;
265 seqid = inot_24xx->in_rxid;
266 isp_prt(isp, ISP_LOGTDEBUG0,
267 "Immediate Notify status=0x%x seqid=0x%x",
268 status, seqid);
269 switch (status) {
270 case IN24XX_LIP_RESET:
271 case IN24XX_LINK_RESET:
272 case IN24XX_PORT_LOGOUT:
273 case IN24XX_PORT_CHANGED:
274 case IN24XX_LINK_FAILED:
275 case IN24XX_SRR_RCVD:
276 case IN24XX_ELS_RCVD:
277 (void) isp_async(isp, ISPASYNC_TARGET_ACTION,
278 &local);
279 break;
280 default:
281 isp_prt(isp, ISP_LOGINFO,
282 "isp_target_notify: unknown status (0x%x)",
283 status);
284 isp_notify_ack(isp, local);
285 break;
286 }
287 break;
288 } else if (IS_FC(isp)) {
289 if (FCPARAM(isp)->isp_2klogin) {
290 isp_get_notify_fc_e(isp, inote_fcp,
291 (in_fcentry_e_t *)local);
292 } else {
293 isp_get_notify_fc(isp, inot_fcp,
294 (in_fcentry_t *)local);
295 }
296 inot_fcp = (in_fcentry_t *) local;
297 status = inot_fcp->in_status;
298 seqid = inot_fcp->in_seqid;
299 } else {
300 isp_get_notify(isp, inotp, (in_entry_t *)local);
301 inotp = (in_entry_t *) local;
302 status = inotp->in_status & 0xff;
303 seqid = inotp->in_seqid;
304 if (IS_DUALBUS(isp)) {
305 bus = GET_BUS_VAL(inotp->in_iid);
306 SET_BUS_VAL(inotp->in_iid, 0);
307 }
308 }
309
310 isp_prt(isp, ISP_LOGTDEBUG0,
311 "Immediate Notify On Bus %d, status=0x%x seqid=0x%x",
312 bus, status, seqid);
313
314 switch (status) {
315 case IN_MSG_RECEIVED:
316 case IN_IDE_RECEIVED:
317 if (IS_FC(isp)) {
318 isp_got_msg_fc(isp, (in_fcentry_t *)local);
319 } else {
320 isp_got_msg(isp, (in_entry_t *)local);
321 }
322 break;
323 case IN_RSRC_UNAVAIL:
324 isp_prt(isp, ISP_LOGINFO, "Firmware out of ATIOs");
325 isp_notify_ack(isp, local);
326 break;
327 case IN_RESET:
328 {
329 /*
330 * We form the notify structure here because we need
331 * to mark it as needing a NOTIFY ACK on return.
332 */
333 tmd_notify_t notify;
334
335 MEMZERO(¬ify, sizeof (tmd_notify_t));
336 notify.nt_hba = isp;
337 notify.nt_iid = INI_ANY;
338 /* nt_tgt set in outer layers */
339 notify.nt_lun = LUN_ANY;
340 notify.nt_tagval = TAG_ANY;
341 notify.nt_ncode = NT_BUS_RESET;
342 notify.nt_need_ack = 1;
343 (void) isp_async(isp, ISPASYNC_TARGET_NOTIFY, ¬ify);
344 break;
345 }
346 case IN_PORT_LOGOUT:
347 case IN_ABORT_TASK:
348 case IN_PORT_CHANGED:
349 case IN_GLOBAL_LOGO:
350 (void) isp_async(isp, ISPASYNC_TARGET_ACTION, &local);
351 break;
352 default:
353 isp_prt(isp, ISP_LOGINFO,
354 "isp_target_notify: unknown status (0x%x)",
355 status);
356 isp_notify_ack(isp, local);
357 break;
358 }
359 break;
360
361 case RQSTYPE_NOTIFY_ACK:
362 /*
363 * The ISP is acknowledging our acknowledgement of an
364 * Immediate Notify entry for some asynchronous event.
365 */
366 if (IS_24XX(isp)) {
367 isp_get_notify_ack_24xx(isp, nack_24xx,
368 (na_fcentry_24xx_t *) local);
369 nack_24xx = (na_fcentry_24xx_t *) local;
370 if (nack_24xx->na_status != NA_OK) {
371 level = ISP_LOGINFO;
372 } else {
373 level = ISP_LOGTDEBUG1;
374 }
375 isp_prt(isp, level,
376 "Notify Ack Status=0x%x; Subcode 0x%x seqid=0x%x",
377 nack_24xx->na_status, nack_24xx->na_status_subcode,
378 nack_24xx->na_rxid);
379 } else if (IS_FC(isp)) {
380 if (FCPARAM(isp)->isp_2klogin) {
381 isp_get_notify_ack_fc_e(isp, nacke_fcp,
382 (na_fcentry_e_t *)local);
383 } else {
384 isp_get_notify_ack_fc(isp, nack_fcp,
385 (na_fcentry_t *)local);
386 }
387 nack_fcp = (na_fcentry_t *)local;
388 if (nack_fcp->na_status != NA_OK) {
389 level = ISP_LOGINFO;
390 } else {
391 level = ISP_LOGTDEBUG1;
392 }
393 isp_prt(isp, level,
394 "Notify Ack Status=0x%x seqid 0x%x",
395 nack_fcp->na_status, nack_fcp->na_seqid);
396 } else {
397 isp_get_notify_ack(isp, nackp, (na_entry_t *)local);
398 nackp = (na_entry_t *)local;
399 if (nackp->na_status != NA_OK) {
400 level = ISP_LOGINFO;
401 } else {
402 level = ISP_LOGTDEBUG1;
403 }
404 isp_prt(isp, level,
405 "Notify Ack event 0x%x status=0x%x seqid 0x%x",
406 nackp->na_event, nackp->na_status, nackp->na_seqid);
407 }
408 break;
409
410 case RQSTYPE_ABTS_RCVD:
411 isp_get_abts(isp, abts, (abts_t *)local);
412 (void) isp_async(isp, ISPASYNC_TARGET_ACTION, &local);
413 break;
414 case RQSTYPE_ABTS_RSP:
415 isp_get_abts_rsp(isp, abts_rsp, (abts_rsp_t *)local);
416 abts_rsp = (abts_rsp_t *) local;
417 if (abts_rsp->abts_rsp_status) {
418 level = ISP_LOGINFO;
419 } else {
420 level = ISP_LOGTDEBUG0;
421 }
422 isp_prt(isp, level,
423 "ABTS RSP response[0x%x]: status=0x%x sub=(0x%x 0x%x)",
424 abts_rsp->abts_rsp_rxid_task, abts_rsp->abts_rsp_status,
425 abts_rsp->abts_rsp_payload.rsp.subcode1,
426 abts_rsp->abts_rsp_payload.rsp.subcode2);
427 break;
428 default:
429 isp_prt(isp, ISP_LOGERR,
430 "Unknown entry type 0x%x in isp_target_notify", type);
431 rval = 0;
432 break;
433 }
434 #undef atiop
435 #undef at2iop
436 #undef at2eiop
437 #undef at7iop
438 #undef ctiop
439 #undef ct2iop
440 #undef ct2eiop
441 #undef ct7iop
442 #undef lunenp
443 #undef inotp
444 #undef inot_fcp
445 #undef inote_fcp
446 #undef inot_24xx
447 #undef nackp
448 #undef nack_fcp
449 #undef nacke_fcp
450 #undef hack_24xx
451 #undef abts
452 #undef abts_rsp
453 #undef els
454 #undef hdrp
455 return (rval);
456 }
457
458
459 /*
460 * Toggle (on/off) target mode for bus/target/lun
461 *
462 * The caller has checked for overlap and legality.
463 *
464 * Note that not all of bus, target or lun can be paid attention to.
465 * Note also that this action will not be complete until the f/w writes
466 * response entry. The caller is responsible for synchronizing this.
467 */
468 int
469 isp_lun_cmd(ispsoftc_t *isp, int cmd, int bus, int tgt, int lun,
470 int cmd_cnt, int inot_cnt, uint32_t opaque)
471 {
472 lun_entry_t el;
473 uint32_t nxti, optr;
474 void *outp;
475
476
477 MEMZERO(&el, sizeof (el));
478 if (IS_DUALBUS(isp)) {
479 el.le_rsvd = (bus & 0x1) << 7;
480 }
481 el.le_cmd_count = cmd_cnt;
482 el.le_in_count = inot_cnt;
483 if (cmd == RQSTYPE_ENABLE_LUN) {
484 if (IS_SCSI(isp)) {
485 el.le_flags = LUN_TQAE|LUN_DISAD;
486 el.le_cdb6len = 12;
487 el.le_cdb7len = 12;
488 }
489 } else if (cmd == -RQSTYPE_ENABLE_LUN) {
490 cmd = RQSTYPE_ENABLE_LUN;
491 el.le_cmd_count = 0;
492 el.le_in_count = 0;
493 } else if (cmd == -RQSTYPE_MODIFY_LUN) {
494 cmd = RQSTYPE_MODIFY_LUN;
495 el.le_ops = LUN_CCDECR | LUN_INDECR;
496 } else {
497 el.le_ops = LUN_CCINCR | LUN_ININCR;
498 }
499 el.le_header.rqs_entry_type = cmd;
500 el.le_header.rqs_entry_count = 1;
501 el.le_reserved = opaque;
502 if (IS_SCSI(isp)) {
503 el.le_tgt = tgt;
504 el.le_lun = lun;
505 } else if (FCPARAM(isp)->isp_sccfw == 0) {
506 el.le_lun = lun;
507 }
508 el.le_timeout = 30;
509
510 if (isp_getrqentry(isp, &nxti, &optr, &outp)) {
511 isp_prt(isp, ISP_LOGERR,
512 "Request Queue Overflow in isp_lun_cmd");
513 return (-1);
514 }
515 ISP_TDQE(isp, "isp_lun_cmd", (int) optr, &el);
516 isp_put_enable_lun(isp, &el, outp);
517 ISP_ADD_REQUEST(isp, nxti);
518 return (0);
519 }
520
521
522 int
523 isp_target_put_entry(ispsoftc_t *isp, void *ap)
524 {
525 void *outp;
526 uint32_t nxti, optr;
527 uint8_t etype = ((isphdr_t *) ap)->rqs_entry_type;
528
529 if (isp_getrqentry(isp, &nxti, &optr, &outp)) {
530 isp_prt(isp, ISP_LOGWARN,
531 "Request Queue Overflow in isp_target_put_entry");
532 return (-1);
533 }
534 switch (etype) {
535 case RQSTYPE_ATIO:
536 isp_put_atio(isp, (at_entry_t *) ap, (at_entry_t *) outp);
537 break;
538 case RQSTYPE_ATIO2:
539 if (FCPARAM(isp)->isp_2klogin) {
540 isp_put_atio2e(isp, (at2e_entry_t *) ap,
541 (at2e_entry_t *) outp);
542 } else {
543 isp_put_atio2(isp, (at2_entry_t *) ap,
544 (at2_entry_t *) outp);
545 }
546 break;
547 case RQSTYPE_CTIO:
548 isp_put_ctio(isp, (ct_entry_t *) ap, (ct_entry_t *) outp);
549 break;
550 case RQSTYPE_CTIO2:
551 if (FCPARAM(isp)->isp_2klogin) {
552 isp_put_ctio2e(isp, (ct2e_entry_t *) ap,
553 (ct2e_entry_t *) outp);
554 } else {
555 isp_put_ctio2(isp, (ct2_entry_t *) ap,
556 (ct2_entry_t *) outp);
557 }
558 break;
559 case RQSTYPE_CTIO7:
560 isp_put_ctio7(isp, (ct7_entry_t *) ap, (ct7_entry_t *) outp);
561 break;
562 default:
563 isp_prt(isp, ISP_LOGERR,
564 "Unknown type 0x%x in isp_put_entry", etype);
565 return (-1);
566 }
567 ISP_TDQE(isp, "isp_target_put_entry", (int) optr, ap);
568 ISP_ADD_REQUEST(isp, nxti);
569 return (0);
570 }
571
572 int
573 isp_target_put_atio(ispsoftc_t *isp, void *arg)
574 {
575 union {
576 at_entry_t _atio;
577 at2_entry_t _atio2;
578 at2e_entry_t _atio2e;
579 } atun;
580
581 MEMZERO(&atun, sizeof atun);
582 if (IS_FC(isp)) {
583 at2_entry_t *aep = arg;
584 atun._atio2.at_header.rqs_entry_type = RQSTYPE_ATIO2;
585 atun._atio2.at_header.rqs_entry_count = 1;
586 if (FCPARAM(isp)->isp_sccfw) {
587 atun._atio2.at_scclun = aep->at_scclun;
588 } else {
589 atun._atio2.at_lun = (uint8_t) aep->at_lun;
590 }
591 if (FCPARAM(isp)->isp_2klogin) {
592 atun._atio2e.at_iid = ((at2e_entry_t *)aep)->at_iid;
593 } else {
594 atun._atio2.at_iid = aep->at_iid;
595 }
596 atun._atio2.at_rxid = aep->at_rxid;
597 atun._atio2.at_status = CT_OK;
598 } else {
599 at_entry_t *aep = arg;
600 atun._atio.at_header.rqs_entry_type = RQSTYPE_ATIO;
601 atun._atio.at_header.rqs_entry_count = 1;
602 atun._atio.at_handle = aep->at_handle;
603 atun._atio.at_iid = aep->at_iid;
604 atun._atio.at_tgt = aep->at_tgt;
605 atun._atio.at_lun = aep->at_lun;
606 atun._atio.at_tag_type = aep->at_tag_type;
607 atun._atio.at_tag_val = aep->at_tag_val;
608 atun._atio.at_status = (aep->at_flags & AT_TQAE);
609 atun._atio.at_status |= CT_OK;
610 }
611 return (isp_target_put_entry(isp, &atun));
612 }
613
614 /*
615 * Command completion- both for handling cases of no resources or
616 * no blackhole driver, or other cases where we have to, inline,
617 * finish the command sanely, or for normal command completion.
618 *
619 * The 'completion' code value has the scsi status byte in the low 8 bits.
620 * If status is a CHECK CONDITION and bit 8 is nonzero, then bits 12..15 have
621 * the sense key and bits 16..23 have the ASCQ and bits 24..31 have the ASC
622 * values.
623 *
624 * NB: the key, asc, ascq, cannot be used for parallel SCSI as it doesn't
625 * NB: inline SCSI sense reporting. As such, we lose this information. XXX.
626 *
627 * For both parallel && fibre channel, we use the feature that does
628 * an automatic resource autoreplenish so we don't have then later do
629 * put of an atio to replenish the f/w's resource count.
630 */
631
632 int
633 isp_endcmd(ispsoftc_t *isp, void *arg, uint32_t code, uint32_t hdl)
634 {
635 int sts;
636 union {
637 ct_entry_t _ctio;
638 ct2_entry_t _ctio2;
639 ct2e_entry_t _ctio2e;
640 ct7_entry_t _ctio7;
641 } un;
642
643 MEMZERO(&un, sizeof un);
644 sts = code & 0xff;
645
646 if (IS_24XX(isp)) {
647 at7_entry_t *aep = arg;
648 ct7_entry_t *cto = &un._ctio7;
649
650 cto->ct_header.rqs_entry_type = RQSTYPE_CTIO7;
651 cto->ct_header.rqs_entry_count = 1;
652 /* XXXX */ cto->ct_nphdl = aep->at_hdr.seq_id;
653 cto->ct_rxid = aep->at_rxid;
654 cto->ct_iid_lo = (aep->at_hdr.s_id[1] << 8) |
655 aep->at_hdr.s_id[2];
656 cto->ct_iid_hi = aep->at_hdr.s_id[0];
657 cto->ct_oxid = aep->at_hdr.ox_id;
658 cto->ct_scsi_status = sts;
659 cto->ct_flags = CT7_FLAG_MODE1 | CT7_NO_DATA | CT7_SENDSTATUS;
660 if (sts == SCSI_CHECK && (code & ECMD_SVALID)) {
661 cto->rsp.m1.ct_resplen = 16;
662 cto->rsp.m1.ct_resp[0] = 0xf0;
663 cto->rsp.m1.ct_resp[2] = (code >> 12) & 0xf;
664 cto->rsp.m1.ct_resp[7] = 8;
665 cto->rsp.m1.ct_resp[12] = (code >> 24) & 0xff;
666 cto->rsp.m1.ct_resp[13] = (code >> 16) & 0xff;
667 }
668 if (aep->at_cmnd.cdb_dl.sf.fcp_cmnd_dl) {
669 cto->ct_resid = aep->at_cmnd.cdb_dl.sf.fcp_cmnd_dl;
670 cto->ct_scsi_status |= CT2_DATA_UNDER;
671 }
672 cto->ct_syshandle = hdl;
673 } else if (IS_FC(isp)) {
674 at2_entry_t *aep = arg;
675 ct2_entry_t *cto = &un._ctio2;
676
677 cto->ct_header.rqs_entry_type = RQSTYPE_CTIO2;
678 cto->ct_header.rqs_entry_count = 1;
679 if (FCPARAM(isp)->isp_sccfw == 0) {
680 cto->ct_lun = aep->at_lun;
681 }
682 if (FCPARAM(isp)->isp_2klogin) {
683 un._ctio2e.ct_iid = ((at2e_entry_t *)aep)->at_iid;
684 } else {
685 cto->ct_iid = aep->at_iid;
686 }
687 cto->ct_rxid = aep->at_rxid;
688 cto->rsp.m1.ct_scsi_status = sts;
689 cto->ct_flags = CT2_SENDSTATUS | CT2_NO_DATA | CT2_FLAG_MODE1;
690 if (hdl == 0) {
691 cto->ct_flags |= CT2_CCINCR;
692 }
693 if (aep->at_datalen) {
694 cto->ct_resid = aep->at_datalen;
695 cto->rsp.m1.ct_scsi_status |= CT2_DATA_UNDER;
696 }
697 if (sts == SCSI_CHECK && (code & ECMD_SVALID)) {
698 cto->rsp.m1.ct_resp[0] = 0xf0;
699 cto->rsp.m1.ct_resp[2] = (code >> 12) & 0xf;
700 cto->rsp.m1.ct_resp[7] = 8;
701 cto->rsp.m1.ct_resp[12] = (code >> 24) & 0xff;
702 cto->rsp.m1.ct_resp[13] = (code >> 16) & 0xff;
703 cto->rsp.m1.ct_senselen = 16;
704 cto->rsp.m1.ct_scsi_status |= CT2_SNSLEN_VALID;
705 }
706 cto->ct_syshandle = hdl;
707 } else {
708 at_entry_t *aep = arg;
709 ct_entry_t *cto = &un._ctio;
710
711 cto->ct_header.rqs_entry_type = RQSTYPE_CTIO;
712 cto->ct_header.rqs_entry_count = 1;
713 cto->ct_fwhandle = aep->at_handle;
714 cto->ct_iid = aep->at_iid;
715 cto->ct_tgt = aep->at_tgt;
716 cto->ct_lun = aep->at_lun;
717 cto->ct_tag_type = aep->at_tag_type;
718 cto->ct_tag_val = aep->at_tag_val;
719 if (aep->at_flags & AT_TQAE) {
720 cto->ct_flags |= CT_TQAE;
721 }
722 cto->ct_flags = CT_SENDSTATUS | CT_NO_DATA;
723 if (hdl == 0) {
724 cto->ct_flags |= CT_CCINCR;
725 }
726 cto->ct_scsi_status = sts;
727 cto->ct_syshandle = hdl;
728 }
729 return (isp_target_put_entry(isp, &un));
730 }
731
732 /*
733 * These are either broadcast events or specifically CTIO fast completion
734 */
735 int
736 isp_target_async(ispsoftc_t *isp, int bus, int event)
737 {
738 tmd_notify_t notify;
739
740 MEMZERO(¬ify, sizeof (tmd_notify_t));
741 notify.nt_hba = isp;
742 notify.nt_iid = INI_ANY;
743 /* nt_tgt set in outer layers */
744 notify.nt_lun = LUN_ANY;
745 notify.nt_tagval = TAG_ANY;
746
747 if (IS_SCSI(isp)) {
748 TAG_INSERT_BUS(notify.nt_tagval, bus);
749 }
750
751 switch (event) {
752 case ASYNC_LOOP_UP:
753 case ASYNC_PTPMODE:
754 notify.nt_ncode = NT_LINK_UP;
755 (void) isp_async(isp, ISPASYNC_TARGET_NOTIFY, ¬ify);
756 break;
757 case ASYNC_LOOP_DOWN:
758 notify.nt_ncode = NT_LINK_DOWN;
759 (void) isp_async(isp, ISPASYNC_TARGET_NOTIFY, ¬ify);
760 break;
761 case ASYNC_LIP_ERROR:
762 case ASYNC_LIP_F8:
763 case ASYNC_LIP_OCCURRED:
764 case ASYNC_LOOP_RESET:
765 notify.nt_ncode = NT_LIP_RESET;
766 (void) isp_async(isp, ISPASYNC_TARGET_NOTIFY, ¬ify);
767 break;
768 case ASYNC_BUS_RESET:
769 case ASYNC_TIMEOUT_RESET: /* XXX: where does this come from ? */
770 notify.nt_ncode = NT_BUS_RESET;
771 (void) isp_async(isp, ISPASYNC_TARGET_NOTIFY, ¬ify);
772 break;
773 case ASYNC_DEVICE_RESET:
774 notify.nt_ncode = NT_TARGET_RESET;
775 (void) isp_async(isp, ISPASYNC_TARGET_NOTIFY, ¬ify);
776 break;
777 case ASYNC_CTIO_DONE:
778 {
779 uint8_t storage[QENTRY_LEN];
780 memset(storage, 0, QENTRY_LEN);
781 if (IS_24XX(isp)) {
782 ct7_entry_t *ct = (ct7_entry_t *) storage;
783 ct->ct_header.rqs_entry_type = RQSTYPE_CTIO7;
784 ct->ct_nphdl = CT7_OK;
785 ct->ct_syshandle = bus;
786 ct->ct_flags = CT7_SENDSTATUS|CT7_FASTPOST;
787 } else if (IS_FC(isp)) {
788 /* This should also suffice for 2K login code */
789 ct2_entry_t *ct = (ct2_entry_t *) storage;
790 ct->ct_header.rqs_entry_type = RQSTYPE_CTIO2;
791 ct->ct_status = CT_OK;
792 ct->ct_syshandle = bus;
793 ct->ct_flags = CT2_SENDSTATUS|CT2_FASTPOST;
794 } else {
795 ct_entry_t *ct = (ct_entry_t *) storage;
796 ct->ct_header.rqs_entry_type = RQSTYPE_CTIO;
797 ct->ct_status = CT_OK;
798 ct->ct_fwhandle = bus;
799 ct->ct_flags = CT_SENDSTATUS;
800 }
801 (void) isp_async(isp, ISPASYNC_TARGET_ACTION, storage);
802 break;
803 }
804 default:
805 isp_prt(isp, ISP_LOGERR,
806 "isp_target_async: unknown event 0x%x", event);
807 if (isp->isp_state == ISP_RUNSTATE) {
808 isp_notify_ack(isp, NULL);
809 }
810 break;
811 }
812 return (0);
813 }
814
815
816 /*
817 * Process a received message.
818 * The ISP firmware can handle most messages, there are only
819 * a few that we need to deal with:
820 * - abort: clean up the current command
821 * - abort tag and clear queue
822 */
823
824 static void
825 isp_got_msg(ispsoftc_t *isp, in_entry_t *inp)
826 {
827 tmd_notify_t nt;
828 uint8_t status = inp->in_status & ~QLTM_SVALID;
829
830 MEMZERO(&nt, sizeof (nt));
831 nt.nt_hba = isp;
832 nt.nt_iid = GET_IID_VAL(inp->in_iid);
833 nt.nt_tgt = inp->in_tgt;
834 nt.nt_lun = inp->in_lun;
835 IN_MAKE_TAGID(nt.nt_tagval, GET_BUS_VAL(inp->in_iid), 0, inp);
836 nt.nt_lreserved = inp;
837
838 if (status == IN_IDE_RECEIVED || status == IN_MSG_RECEIVED) {
839 switch (inp->in_msg[0]) {
840 case MSG_ABORT:
841 nt.nt_ncode = NT_ABORT_TASK_SET;
842 break;
843 case MSG_BUS_DEV_RESET:
844 nt.nt_ncode = NT_TARGET_RESET;
845 break;
846 case MSG_ABORT_TAG:
847 nt.nt_ncode = NT_ABORT_TASK;
848 break;
849 case MSG_CLEAR_QUEUE:
850 nt.nt_ncode = NT_CLEAR_TASK_SET;
851 break;
852 case MSG_REL_RECOVERY:
853 nt.nt_ncode = NT_CLEAR_ACA;
854 break;
855 case MSG_TERM_IO_PROC:
856 nt.nt_ncode = NT_ABORT_TASK;
857 break;
858 case MSG_LUN_RESET:
859 nt.nt_ncode = NT_LUN_RESET;
860 break;
861 default:
862 isp_prt(isp, ISP_LOGERR,
863 "unhandled message 0x%x", inp->in_msg[0]);
864 isp_notify_ack(isp, inp);
865 return;
866 }
867 (void) isp_async(isp, ISPASYNC_TARGET_NOTIFY, &nt);
868 } else {
869 isp_prt(isp, ISP_LOGERR,
870 "unknown immediate notify status 0x%x", inp->in_status);
871 isp_notify_ack(isp, inp);
872 }
873 }
874
875 /*
876 * Synthesize a message from the task management flags in a FCP_CMND_IU.
877 */
878 static void
879 isp_got_msg_fc(ispsoftc_t *isp, in_fcentry_t *inp)
880 {
881 tmd_notify_t nt;
882 static const char f1[] = "%s from N-port handle 0x%x lun %d seq 0x%x";
883 static const char f2[] = "unknown %s 0x%x lun %d N-Port handle 0x%x "
884 "task flags 0x%x seq 0x%x\n";
885 uint16_t seqid, loopid;
886
887 MEMZERO(&nt, sizeof (tmd_notify_t));
888 nt.nt_hba = isp;
889 if (FCPARAM(isp)->isp_2klogin) {
890 nt.nt_iid = ((in_fcentry_e_t *)inp)->in_iid;
891 loopid = ((in_fcentry_e_t *)inp)->in_iid;
892 seqid = ((in_fcentry_e_t *)inp)->in_seqid;
893 } else {
894 nt.nt_iid = inp->in_iid;
895 loopid = inp->in_iid;
896 seqid = inp->in_seqid;
897 }
898 /* nt_tgt set in outer layers */
899 if (FCPARAM(isp)->isp_sccfw) {
900 nt.nt_lun = inp->in_scclun;
901 } else {
902 nt.nt_lun = inp->in_lun;
903 }
904 IN_FC_MAKE_TAGID(nt.nt_tagval, 0, 0, seqid);
905 nt.nt_need_ack = 1;
906 nt.nt_lreserved = inp;
907
908 if (inp->in_status != IN_MSG_RECEIVED) {
909 isp_prt(isp, ISP_LOGINFO, f2, "immediate notify status",
910 inp->in_status, nt.nt_lun, loopid, inp->in_task_flags,
911 inp->in_seqid);
912 isp_notify_ack(isp, inp);
913 return;
914 }
915
916 if (inp->in_task_flags & TASK_FLAGS_ABORT_TASK_SET) {
917 isp_prt(isp, ISP_LOGINFO, f1, "ABORT TASK SET",
918 loopid, nt.nt_lun, inp->in_seqid);
919 nt.nt_ncode = NT_ABORT_TASK_SET;
920 } else if (inp->in_task_flags & TASK_FLAGS_CLEAR_TASK_SET) {
921 isp_prt(isp, ISP_LOGINFO, f1, "CLEAR TASK SET",
922 loopid, nt.nt_lun, inp->in_seqid);
923 nt.nt_ncode = NT_CLEAR_TASK_SET;
924 } else if (inp->in_task_flags & TASK_FLAGS_LUN_RESET) {
925 isp_prt(isp, ISP_LOGINFO, f1, "LUN RESET",
926 loopid, nt.nt_lun, inp->in_seqid);
927 nt.nt_ncode = NT_LUN_RESET;
928 } else if (inp->in_task_flags & TASK_FLAGS_TARGET_RESET) {
929 isp_prt(isp, ISP_LOGINFO, f1, "TARGET RESET",
930 loopid, nt.nt_lun, inp->in_seqid);
931 nt.nt_ncode = NT_TARGET_RESET;
932 } else if (inp->in_task_flags & TASK_FLAGS_CLEAR_ACA) {
933 isp_prt(isp, ISP_LOGINFO, f1, "CLEAR ACA",
934 loopid, nt.nt_lun, inp->in_seqid);
935 nt.nt_ncode = NT_CLEAR_ACA;
936 } else {
937 isp_prt(isp, ISP_LOGWARN, f2, "task flag", inp->in_status,
938 nt.nt_lun, loopid, inp->in_task_flags, inp->in_seqid);
939 isp_notify_ack(isp, inp);
940 return;
941 }
942 (void) isp_async(isp, ISPASYNC_TARGET_NOTIFY, &nt);
943 }
944
945 #define HILO(x) (uint32_t) (x >> 32), (uint32_t) x
946 static void
947 isp_got_tmf_24xx(ispsoftc_t *isp, at7_entry_t *aep)
948 {
949 tmd_notify_t nt;
950 static const char f1[] =
951 "%s from PortID 0x%06x lun %d seq 0x%08x%08x";
952 static const char f2[] =
953 "unknown Task Flag 0x%x lun %d PortID 0x%x tag 0x%08x%08x";
954 uint32_t sid;
955
956 MEMZERO(&nt, sizeof (tmd_notify_t));
957 nt.nt_hba = isp;
958 nt.nt_iid = INI_ANY;
959 nt.nt_lun =
960 (aep->at_cmnd.fcp_cmnd_lun[0] << 8) |
961 (aep->at_cmnd.fcp_cmnd_lun[1]);
962 /*
963 * XXX: VPIDX HAS TO BE DERIVED FROM DESTINATION PORT
964 */
965 nt.nt_tagval = aep->at_rxid;
966 nt.nt_lreserved = aep;
967 sid =
968 (aep->at_hdr.s_id[0] << 16) |
969 (aep->at_hdr.s_id[1] << 8) |
970 (aep->at_hdr.s_id[2]);
971
972 if (aep->at_cmnd.fcp_cmnd_task_management &
973 FCP_CMND_TMF_ABORT_TASK_SET) {
974 isp_prt(isp, ISP_LOGINFO, f1, "ABORT TASK SET",
975 sid, nt.nt_lun, HILO(nt.nt_tagval));
976 nt.nt_ncode = NT_ABORT_TASK_SET;
977 } else if (aep->at_cmnd.fcp_cmnd_task_management &
978 FCP_CMND_TMF_CLEAR_TASK_SET) {
979 isp_prt(isp, ISP_LOGINFO, f1, "CLEAR TASK SET",
980 sid, nt.nt_lun, HILO(nt.nt_tagval));
981 nt.nt_ncode = NT_CLEAR_TASK_SET;
982 } else if (aep->at_cmnd.fcp_cmnd_task_management &
983 FCP_CMND_TMF_LUN_RESET) {
984 isp_prt(isp, ISP_LOGINFO, f1, "LUN RESET",
985 sid, nt.nt_lun, HILO(nt.nt_tagval));
986 nt.nt_ncode = NT_LUN_RESET;
987 } else if (aep->at_cmnd.fcp_cmnd_task_management &
988 FCP_CMND_TMF_TGT_RESET) {
989 isp_prt(isp, ISP_LOGINFO, f1, "TARGET RESET",
990 sid, nt.nt_lun, HILO(nt.nt_tagval));
991 nt.nt_ncode = NT_TARGET_RESET;
992 nt.nt_lun = LUN_ANY;
993 } else if (aep->at_cmnd.fcp_cmnd_task_management &
994 FCP_CMND_TMF_CLEAR_ACA) {
995 isp_prt(isp, ISP_LOGINFO, f1, "CLEAR ACA",
996 sid, nt.nt_lun, HILO(nt.nt_tagval));
997 nt.nt_ncode = NT_CLEAR_ACA;
998 } else {
999 isp_prt(isp, ISP_LOGWARN, f2,
1000 aep->at_cmnd.fcp_cmnd_task_management,
1001 nt.nt_lun, sid, HILO(nt.nt_tagval));
1002 isp_endcmd(isp, aep, 0, 0);
1003 return;
1004 }
1005 (void) isp_async(isp, ISPASYNC_TARGET_NOTIFY, &nt);
1006 }
1007
1008 void
1009 isp_notify_ack(ispsoftc_t *isp, void *arg)
1010 {
1011 char storage[QENTRY_LEN];
1012 uint32_t nxti, optr;
1013 void *outp;
1014
1015 if (isp_getrqentry(isp, &nxti, &optr, &outp)) {
1016 isp_prt(isp, ISP_LOGWARN,
1017 "Request Queue Overflow For isp_notify_ack");
1018 return;
1019 }
1020
1021 MEMZERO(storage, QENTRY_LEN);
1022
1023 if (IS_24XX(isp) && arg != NULL && (((isphdr_t *)arg)->rqs_entry_type == RQSTYPE_ATIO)) {
1024 at7_entry_t *aep = arg;
1025 isp_endcmd(isp, aep, 0, 0);
1026 return;
1027 } else if (IS_24XX(isp) && arg != NULL && (((isphdr_t *)arg)->rqs_entry_type == RQSTYPE_ABTS_RSP)) {
1028 abts_rsp_t *abts_rsp = (abts_rsp_t *) storage;
1029 /*
1030 * The caller will have set response values as appropriate
1031 * in the ABTS structure just before calling us.
1032 */
1033 MEMCPY(abts_rsp, arg, QENTRY_LEN);
1034 isp_put_abts_rsp(isp, abts_rsp, (abts_rsp_t *)outp);
1035 } else if (IS_24XX(isp)) {
1036 na_fcentry_24xx_t *na = (na_fcentry_24xx_t *) storage;
1037 if (arg) {
1038 in_fcentry_24xx_t *in = arg;
1039 na->na_nphdl = in->in_nphdl;
1040 na->na_status = in->in_status;
1041 na->na_status_subcode = in->in_status_subcode;
1042 na->na_rxid = in->in_rxid;
1043 na->na_oxid = in->in_oxid;
1044 if (in->in_status == IN24XX_SRR_RCVD) {
1045 na->na_srr_rxid = in->in_srr_rxid;
1046 na->na_srr_reloff_hi = in->in_srr_reloff_hi;
1047 na->na_srr_reloff_lo = in->in_srr_reloff_lo;
1048 na->na_srr_iu = in->in_srr_iu;
1049 na->na_srr_flags = 1;
1050 na->na_srr_reject_vunique = 0;
1051 na->na_srr_reject_explanation = 1;
1052 na->na_srr_reject_code = 1;
1053 }
1054 }
1055 na->na_header.rqs_entry_type = RQSTYPE_NOTIFY_ACK;
1056 na->na_header.rqs_entry_count = 1;
1057 isp_put_notify_24xx_ack(isp, na, (na_fcentry_24xx_t *)outp);
1058 } else if (IS_FC(isp)) {
1059 na_fcentry_t *na = (na_fcentry_t *) storage;
1060 int iid = 0;
1061
1062 if (arg) {
1063 in_fcentry_t *inp = arg;
1064 MEMCPY(storage, arg, sizeof (isphdr_t));
1065 if (FCPARAM(isp)->isp_2klogin) {
1066 ((na_fcentry_e_t *)na)->na_iid =
1067 ((in_fcentry_e_t *)inp)->in_iid;
1068 iid = ((na_fcentry_e_t *)na)->na_iid;
1069 } else {
1070 na->na_iid = inp->in_iid;
1071 iid = na->na_iid;
1072 }
1073 na->na_task_flags =
1074 inp->in_task_flags & TASK_FLAGS_RESERVED_MASK;
1075 na->na_seqid = inp->in_seqid;
1076 na->na_flags = NAFC_RCOUNT;
1077 na->na_status = inp->in_status;
1078 if (inp->in_status == IN_RESET) {
1079 na->na_flags |= NAFC_RST_CLRD;
1080 }
1081 if (inp->in_status == IN_MSG_RECEIVED) {
1082 na->na_flags |= NAFC_TVALID;
1083 na->na_response = 0; /* XXX SUCCEEDED XXX */
1084 }
1085 } else {
1086 na->na_flags = NAFC_RST_CLRD;
1087 }
1088 na->na_header.rqs_entry_type = RQSTYPE_NOTIFY_ACK;
1089 na->na_header.rqs_entry_count = 1;
1090 if (FCPARAM(isp)->isp_2klogin) {
1091 isp_put_notify_ack_fc_e(isp, (na_fcentry_e_t *) na,
1092 (na_fcentry_e_t *)outp);
1093 } else {
1094 isp_put_notify_ack_fc(isp, na, (na_fcentry_t *)outp);
1095 }
1096 isp_prt(isp, ISP_LOGTDEBUG0, "notify ack loopid %u seqid %x "
1097 "flags %x tflags %x response %x", iid, na->na_seqid,
1098 na->na_flags, na->na_task_flags, na->na_response);
1099 } else {
1100 na_entry_t *na = (na_entry_t *) storage;
1101 if (arg) {
1102 in_entry_t *inp = arg;
1103 MEMCPY(storage, arg, sizeof (isphdr_t));
1104 na->na_iid = inp->in_iid;
1105 na->na_lun = inp->in_lun;
1106 na->na_tgt = inp->in_tgt;
1107 na->na_seqid = inp->in_seqid;
1108 if (inp->in_status == IN_RESET) {
1109 na->na_event = NA_RST_CLRD;
1110 }
1111 } else {
1112 na->na_event = NA_RST_CLRD;
1113 }
1114 na->na_header.rqs_entry_type = RQSTYPE_NOTIFY_ACK;
1115 na->na_header.rqs_entry_count = 1;
1116 isp_put_notify_ack(isp, na, (na_entry_t *)outp);
1117 isp_prt(isp, ISP_LOGTDEBUG0, "notify ack loopid %u lun %u tgt "
1118 "%u seqid %x event %x", na->na_iid, na->na_lun, na->na_tgt,
1119 na->na_seqid, na->na_event);
1120 }
1121 ISP_TDQE(isp, "isp_notify_ack", (int) optr, storage);
1122 ISP_ADD_REQUEST(isp, nxti);
1123 }
1124
1125 static void
1126 isp_handle_atio(ispsoftc_t *isp, at_entry_t *aep)
1127 {
1128 int lun;
1129 lun = aep->at_lun;
1130 /*
1131 * The firmware status (except for the QLTM_SVALID bit) indicates
1132 * why this ATIO was sent to us.
1133 *
1134 * If QLTM_SVALID is set, the firware has recommended Sense Data.
1135 *
1136 * If the DISCONNECTS DISABLED bit is set in the flags field,
1137 * we're still connected on the SCSI bus - i.e. the initiator
1138 * did not set DiscPriv in the identify message. We don't care
1139 * about this so it's ignored.
1140 */
1141
1142 switch(aep->at_status & ~QLTM_SVALID) {
1143 case AT_PATH_INVALID:
1144 /*
1145 * ATIO rejected by the firmware due to disabled lun.
1146 */
1147 isp_prt(isp, ISP_LOGERR,
1148 "rejected ATIO for disabled lun %d", lun);
1149 break;
1150 case AT_NOCAP:
1151 /*
1152 * Requested Capability not available
1153 * We sent an ATIO that overflowed the firmware's
1154 * command resource count.
1155 */
1156 isp_prt(isp, ISP_LOGERR,
1157 "rejected ATIO for lun %d because of command count"
1158 " overflow", lun);
1159 break;
1160
1161 case AT_BDR_MSG:
1162 /*
1163 * If we send an ATIO to the firmware to increment
1164 * its command resource count, and the firmware is
1165 * recovering from a Bus Device Reset, it returns
1166 * the ATIO with this status. We set the command
1167 * resource count in the Enable Lun entry and do
1168 * not increment it. Therefore we should never get
1169 * this status here.
1170 */
1171 isp_prt(isp, ISP_LOGERR, atiocope, lun,
1172 GET_BUS_VAL(aep->at_iid));
1173 break;
1174
1175 case AT_CDB: /* Got a CDB */
1176 case AT_PHASE_ERROR: /* Bus Phase Sequence Error */
1177 /*
1178 * Punt to platform specific layer.
1179 */
1180 (void) isp_async(isp, ISPASYNC_TARGET_ACTION, aep);
1181 break;
1182
1183 case AT_RESET:
1184 /*
1185 * A bus reset came along and blew away this command. Why
1186 * they do this in addition the async event code stuff,
1187 * I dunno.
1188 *
1189 * Ignore it because the async event will clear things
1190 * up for us.
1191 */
1192 isp_prt(isp, ISP_LOGWARN, atior, lun,
1193 GET_IID_VAL(aep->at_iid), GET_BUS_VAL(aep->at_iid));
1194 break;
1195
1196
1197 default:
1198 isp_prt(isp, ISP_LOGERR,
1199 "Unknown ATIO status 0x%x from loopid %d for lun %d",
1200 aep->at_status, aep->at_iid, lun);
1201 (void) isp_target_put_atio(isp, aep);
1202 break;
1203 }
1204 }
1205
1206 static void
1207 isp_handle_atio2(ispsoftc_t *isp, at2_entry_t *aep)
1208 {
1209 int lun, iid;
1210
1211 if (FCPARAM(isp)->isp_sccfw) {
1212 lun = aep->at_scclun;
1213 } else {
1214 lun = aep->at_lun;
1215 }
1216
1217 if (FCPARAM(isp)->isp_2klogin) {
1218 iid = ((at2e_entry_t *)aep)->at_iid;
1219 } else {
1220 iid = aep->at_iid;
1221 }
1222
1223 /*
1224 * The firmware status (except for the QLTM_SVALID bit) indicates
1225 * why this ATIO was sent to us.
1226 *
1227 * If QLTM_SVALID is set, the firware has recommended Sense Data.
1228 *
1229 * If the DISCONNECTS DISABLED bit is set in the flags field,
1230 * we're still connected on the SCSI bus - i.e. the initiator
1231 * did not set DiscPriv in the identify message. We don't care
1232 * about this so it's ignored.
1233 */
1234
1235 switch(aep->at_status & ~QLTM_SVALID) {
1236 case AT_PATH_INVALID:
1237 /*
1238 * ATIO rejected by the firmware due to disabled lun.
1239 */
1240 isp_prt(isp, ISP_LOGERR,
1241 "rejected ATIO2 for disabled lun %d", lun);
1242 break;
1243 case AT_NOCAP:
1244 /*
1245 * Requested Capability not available
1246 * We sent an ATIO that overflowed the firmware's
1247 * command resource count.
1248 */
1249 isp_prt(isp, ISP_LOGERR,
1250 "rejected ATIO2 for lun %d- command count overflow", lun);
1251 break;
1252
1253 case AT_BDR_MSG:
1254 /*
1255 * If we send an ATIO to the firmware to increment
1256 * its command resource count, and the firmware is
1257 * recovering from a Bus Device Reset, it returns
1258 * the ATIO with this status. We set the command
1259 * resource count in the Enable Lun entry and no
1260 * not increment it. Therefore we should never get
1261 * this status here.
1262 */
1263 isp_prt(isp, ISP_LOGERR, atiocope, lun, 0);
1264 break;
1265
1266 case AT_CDB: /* Got a CDB */
1267 /*
1268 * Punt to platform specific layer.
1269 */
1270 (void) isp_async(isp, ISPASYNC_TARGET_ACTION, aep);
1271 break;
1272
1273 case AT_RESET:
1274 /*
1275 * A bus reset came along an blew away this command. Why
1276 * they do this in addition the async event code stuff,
1277 * I dunno.
1278 *
1279 * Ignore it because the async event will clear things
1280 * up for us.
1281 */
1282 isp_prt(isp, ISP_LOGERR, atior, lun, iid, 0);
1283 break;
1284
1285
1286 default:
1287 isp_prt(isp, ISP_LOGERR,
1288 "Unknown ATIO2 status 0x%x from loopid %d for lun %d",
1289 aep->at_status, iid, lun);
1290 (void) isp_target_put_atio(isp, aep);
1291 break;
1292 }
1293 }
1294
1295 static void
1296 isp_handle_ctio(ispsoftc_t *isp, ct_entry_t *ct)
1297 {
1298 void *xs;
1299 int pl = ISP_LOGTDEBUG2;
1300 char *fmsg = NULL;
1301
1302 if (ct->ct_syshandle) {
1303 xs = isp_find_xs_tgt(isp, ct->ct_syshandle);
1304 if (xs == NULL) {
1305 pl = ISP_LOGALL;
1306 }
1307 } else {
1308 xs = NULL;
1309 }
1310
1311 switch(ct->ct_status & ~QLTM_SVALID) {
1312 case CT_OK:
1313 /*
1314 * There are generally 3 possibilities as to why we'd get
1315 * this condition:
1316 * We disconnected after receiving a CDB.
1317 * We sent or received data.
1318 * We sent status & command complete.
1319 */
1320
1321 if (ct->ct_flags & CT_SENDSTATUS) {
1322 break;
1323 } else if ((ct->ct_flags & CT_DATAMASK) == CT_NO_DATA) {
1324 /*
1325 * Nothing to do in this case.
1326 */
1327 isp_prt(isp, pl, "CTIO- iid %d disconnected OK",
1328 ct->ct_iid);
1329 return;
1330 }
1331 break;
1332
1333 case CT_BDR_MSG:
1334 /*
1335 * Bus Device Reset message received or the SCSI Bus has
1336 * been Reset; the firmware has gone to Bus Free.
1337 *
1338 * The firmware generates an async mailbox interupt to
1339 * notify us of this and returns outstanding CTIOs with this
1340 * status. These CTIOs are handled in that same way as
1341 * CT_ABORTED ones, so just fall through here.
1342 */
1343 fmsg = "Bus Device Reset";
1344 /*FALLTHROUGH*/
1345 case CT_RESET:
1346 if (fmsg == NULL)
1347 fmsg = "Bus Reset";
1348 /*FALLTHROUGH*/
1349 case CT_ABORTED:
1350 /*
1351 * When an Abort message is received the firmware goes to
1352 * Bus Free and returns all outstanding CTIOs with the status
1353 * set, then sends us an Immediate Notify entry.
1354 */
1355 if (fmsg == NULL)
1356 fmsg = "ABORT TAG message sent by Initiator";
1357
1358 isp_prt(isp, ISP_LOGTDEBUG0, "CTIO destroyed by %s", fmsg);
1359 break;
1360
1361 case CT_INVAL:
1362 /*
1363 * CTIO rejected by the firmware due to disabled lun.
1364 * "Cannot Happen".
1365 */
1366 isp_prt(isp, ISP_LOGERR,
1367 "Firmware rejected CTIO for disabled lun %d",
1368 ct->ct_lun);
1369 break;
1370
1371 case CT_NOPATH:
1372 /*
1373 * CTIO rejected by the firmware due "no path for the
1374 * nondisconnecting nexus specified". This means that
1375 * we tried to access the bus while a non-disconnecting
1376 * command is in process.
1377 */
1378 isp_prt(isp, ISP_LOGERR,
1379 "Firmware rejected CTIO for bad nexus %d/%d/%d",
1380 ct->ct_iid, ct->ct_tgt, ct->ct_lun);
1381 break;
1382
1383 case CT_RSELTMO:
1384 fmsg = "Reselection";
1385 /*FALLTHROUGH*/
1386 case CT_TIMEOUT:
1387 if (fmsg == NULL)
1388 fmsg = "Command";
1389 isp_prt(isp, ISP_LOGERR, "Firmware timed out on %s", fmsg);
1390 break;
1391
1392 case CT_PANIC:
1393 if (fmsg == NULL)
1394 fmsg = "Unrecoverable Error";
1395 /*FALLTHROUGH*/
1396 case CT_ERR:
1397 if (fmsg == NULL)
1398 fmsg = "Completed with Error";
1399 /*FALLTHROUGH*/
1400 case CT_PHASE_ERROR:
1401 if (fmsg == NULL)
1402 fmsg = "Phase Sequence Error";
1403 /*FALLTHROUGH*/
1404 case CT_TERMINATED:
1405 if (fmsg == NULL)
1406 fmsg = "terminated by TERMINATE TRANSFER";
1407 /*FALLTHROUGH*/
1408 case CT_NOACK:
1409 if (fmsg == NULL)
1410 fmsg = "unacknowledged Immediate Notify pending";
1411 isp_prt(isp, ISP_LOGERR, "CTIO returned by f/w- %s", fmsg);
1412 break;
1413 default:
1414 isp_prt(isp, ISP_LOGERR, "Unknown CTIO status 0x%x",
1415 ct->ct_status & ~QLTM_SVALID);
1416 break;
1417 }
1418
1419 if (xs == NULL) {
1420 /*
1421 * There may be more than one CTIO for a data transfer,
1422 * or this may be a status CTIO we're not monitoring.
1423 *
1424 * The assumption is that they'll all be returned in the
1425 * order we got them.
1426 */
1427 if (ct->ct_syshandle == 0) {
1428 if ((ct->ct_flags & CT_SENDSTATUS) == 0) {
1429 isp_prt(isp, pl,
1430 "intermediate CTIO completed ok");
1431 } else {
1432 isp_prt(isp, pl,
1433 "unmonitored CTIO completed ok");
1434 }
1435 } else {
1436 isp_prt(isp, pl,
1437 "NO xs for CTIO (handle 0x%x) status 0x%x",
1438 ct->ct_syshandle, ct->ct_status & ~QLTM_SVALID);
1439 }
1440 } else {
1441 /*
1442 * Final CTIO completed. Release DMA resources and
1443 * notify platform dependent layers.
1444 */
1445 if ((ct->ct_flags & CT_DATAMASK) != CT_NO_DATA) {
1446 ISP_DMAFREE(isp, xs, ct->ct_syshandle);
1447 }
1448 isp_prt(isp, pl, "final CTIO complete");
1449 /*
1450 * The platform layer will destroy the handle if appropriate.
1451 */
1452 (void) isp_async(isp, ISPASYNC_TARGET_ACTION, ct);
1453 }
1454 }
1455
1456 static void
1457 isp_handle_ctio2(ispsoftc_t *isp, ct2_entry_t *ct)
1458 {
1459 void *xs;
1460 int pl = ISP_LOGTDEBUG2;
1461 char *fmsg = NULL;
1462
1463 if (ct->ct_syshandle) {
1464 xs = isp_find_xs_tgt(isp, ct->ct_syshandle);
1465 if (xs == NULL) {
1466 pl = ISP_LOGALL;
1467 }
1468 } else {
1469 xs = NULL;
1470 }
1471
1472 switch(ct->ct_status & ~QLTM_SVALID) {
1473 case CT_BUS_ERROR:
1474 isp_prt(isp, ISP_LOGERR, "PCI DMA Bus Error");
1475 /* FALL Through */
1476 case CT_DATA_OVER:
1477 case CT_DATA_UNDER:
1478 case CT_OK:
1479 /*
1480 * There are generally 2 possibilities as to why we'd get
1481 * this condition:
1482 * We sent or received data.
1483 * We sent status & command complete.
1484 */
1485
1486 break;
1487
1488 case CT_BDR_MSG:
1489 /*
1490 * Target Reset function received.
1491 *
1492 * The firmware generates an async mailbox interupt to
1493 * notify us of this and returns outstanding CTIOs with this
1494 * status. These CTIOs are handled in that same way as
1495 * CT_ABORTED ones, so just fall through here.
1496 */
1497 fmsg = "TARGET RESET";
1498 /*FALLTHROUGH*/
1499 case CT_RESET:
1500 if (fmsg == NULL)
1501 fmsg = "LIP Reset";
1502 /*FALLTHROUGH*/
1503 case CT_ABORTED:
1504 /*
1505 * When an Abort message is received the firmware goes to
1506 * Bus Free and returns all outstanding CTIOs with the status
1507 * set, then sends us an Immediate Notify entry.
1508 */
1509 if (fmsg == NULL) {
1510 fmsg = "ABORT";
1511 }
1512
1513 isp_prt(isp, ISP_LOGTDEBUG0,
1514 "CTIO2 destroyed by %s: RX_ID=0x%x", fmsg, ct->ct_rxid);
1515 break;
1516
1517 case CT_INVAL:
1518 /*
1519 * CTIO rejected by the firmware - invalid data direction.
1520 */
1521 isp_prt(isp, ISP_LOGERR, "CTIO2 had wrong data direction");
1522 break;
1523
1524 case CT_RSELTMO:
1525 fmsg = "failure to reconnect to initiator";
1526 /*FALLTHROUGH*/
1527 case CT_TIMEOUT:
1528 if (fmsg == NULL)
1529 fmsg = "command";
1530 isp_prt(isp, ISP_LOGERR, "Firmware timed out on %s", fmsg);
1531 break;
1532
1533 case CT_ERR:
1534 fmsg = "Completed with Error";
1535 /*FALLTHROUGH*/
1536 case CT_LOGOUT:
1537 if (fmsg == NULL)
1538 fmsg = "Port Logout";
1539 /*FALLTHROUGH*/
1540 case CT_PORTUNAVAIL:
1541 if (fmsg == NULL)
1542 fmsg = "Port not available";
1543 /*FALLTHROUGH*/
1544 case CT_PORTCHANGED:
1545 if (fmsg == NULL)
1546 fmsg = "Port Changed";
1547 /*FALLTHROUGH*/
1548 case CT_NOACK:
1549 if (fmsg == NULL)
1550 fmsg = "unacknowledged Immediate Notify pending";
1551 isp_prt(isp, ISP_LOGWARN, "CTIO returned by f/w- %s", fmsg);
1552 break;
1553
1554 case CT_INVRXID:
1555 /*
1556 * CTIO rejected by the firmware because an invalid RX_ID.
1557 * Just print a message.
1558 */
1559 isp_prt(isp, ISP_LOGWARN,
1560 "CTIO2 completed with Invalid RX_ID 0x%x", ct->ct_rxid);
1561 break;
1562
1563 default:
1564 isp_prt(isp, ISP_LOGERR, "Unknown CTIO2 status 0x%x",
1565 ct->ct_status & ~QLTM_SVALID);
1566 break;
1567 }
1568
1569 if (xs == NULL) {
1570 /*
1571 * There may be more than one CTIO for a data transfer,
1572 * or this may be a status CTIO we're not monitoring.
1573 *
1574 * The assumption is that they'll all be returned in the
1575 * order we got them.
1576 */
1577 if (ct->ct_syshandle == 0) {
1578 if ((ct->ct_flags & CT2_SENDSTATUS) == 0) {
1579 isp_prt(isp, pl,
1580 "intermediate CTIO completed ok");
1581 } else {
1582 isp_prt(isp, pl,
1583 "unmonitored CTIO completed ok");
1584 }
1585 } else {
1586 isp_prt(isp, pl,
1587 "NO xs for CTIO (handle 0x%x) status 0x%x",
1588 ct->ct_syshandle, ct->ct_status & ~QLTM_SVALID);
1589 }
1590 } else {
1591 if ((ct->ct_flags & CT2_DATAMASK) != CT2_NO_DATA) {
1592 ISP_DMAFREE(isp, xs, ct->ct_syshandle);
1593 }
1594 if (ct->ct_flags & CT2_SENDSTATUS) {
1595 /*
1596 * Sent status and command complete.
1597 *
1598 * We're now really done with this command, so we
1599 * punt to the platform dependent layers because
1600 * only there can we do the appropriate command
1601 * complete thread synchronization.
1602 */
1603 isp_prt(isp, pl, "status CTIO complete");
1604 } else {
1605 /*
1606 * Final CTIO completed. Release DMA resources and
1607 * notify platform dependent layers.
1608 */
1609 isp_prt(isp, pl, "data CTIO complete");
1610 }
1611 (void) isp_async(isp, ISPASYNC_TARGET_ACTION, ct);
1612 /*
1613 * The platform layer will destroy the handle if appropriate.
1614 */
1615 }
1616 }
1617
1618 static void
1619 isp_handle_ctio7(ispsoftc_t *isp, ct7_entry_t *ct)
1620 {
1621 void *xs;
1622 int pl = ISP_LOGTDEBUG2;
1623 char *fmsg = NULL;
1624
1625 if (ct->ct_syshandle) {
1626 xs = isp_find_xs_tgt(isp, ct->ct_syshandle);
1627 if (xs == NULL) {
1628 pl = ISP_LOGALL;
1629 }
1630 } else {
1631 xs = NULL;
1632 }
1633
1634 switch(ct->ct_nphdl) {
1635 case CT7_BUS_ERROR:
1636 isp_prt(isp, ISP_LOGERR, "PCI DMA Bus Error");
1637 /* FALL Through */
1638 case CT7_DATA_OVER:
1639 case CT7_DATA_UNDER:
1640 case CT7_OK:
1641 /*
1642 * There are generally 2 possibilities as to why we'd get
1643 * this condition:
1644 * We sent or received data.
1645 * We sent status & command complete.
1646 */
1647
1648 break;
1649
1650 case CT7_RESET:
1651 if (fmsg == NULL) {
1652 fmsg = "LIP Reset";
1653 }
1654 /*FALLTHROUGH*/
1655 case CT7_ABORTED:
1656 /*
1657 * When an Abort message is received the firmware goes to
1658 * Bus Free and returns all outstanding CTIOs with the status
1659 * set, then sends us an Immediate Notify entry.
1660 */
1661 if (fmsg == NULL) {
1662 fmsg = "ABORT";
1663 }
1664 isp_prt(isp, ISP_LOGTDEBUG0,
1665 "CTIO7 destroyed by %s: RX_ID=0x%x", fmsg, ct->ct_rxid);
1666 break;
1667
1668 case CT7_TIMEOUT:
1669 if (fmsg == NULL) {
1670 fmsg = "command";
1671 }
1672 isp_prt(isp, ISP_LOGERR, "Firmware timed out on %s", fmsg);
1673 break;
1674
1675 case CT7_ERR:
1676 fmsg = "Completed with Error";
1677 /*FALLTHROUGH*/
1678 case CT7_LOGOUT:
1679 if (fmsg == NULL) {
1680 fmsg = "Port Logout";
1681 }
1682 /*FALLTHROUGH*/
1683 case CT7_PORTUNAVAIL:
1684 if (fmsg == NULL) {
1685 fmsg = "Port not available";
1686 }
1687 /*FALLTHROUGH*/
1688 case CT7_PORTCHANGED:
1689 if (fmsg == NULL) {
1690 fmsg = "Port Changed";
1691 }
1692 isp_prt(isp, ISP_LOGWARN, "CTIO returned by f/w- %s", fmsg);
1693 break;
1694
1695 case CT7_INVRXID:
1696 /*
1697 * CTIO rejected by the firmware because an invalid RX_ID.
1698 * Just print a message.
1699 */
1700 isp_prt(isp, ISP_LOGWARN,
1701 "CTIO7 completed with Invalid RX_ID 0x%x", ct->ct_rxid);
1702 break;
1703
1704 case CT7_REASSY_ERR:
1705 isp_prt(isp, ISP_LOGWARN, "reassembly error");
1706 break;
1707
1708 case CT7_SRR:
1709 isp_prt(isp, ISP_LOGWARN, "SRR received");
1710 break;
1711
1712 default:
1713 isp_prt(isp, ISP_LOGERR, "Unknown CTIO7 status 0x%x",
1714 ct->ct_nphdl);
1715 break;
1716 }
1717
1718 if (xs == NULL) {
1719 /*
1720 * There may be more than one CTIO for a data transfer,
1721 * or this may be a status CTIO we're not monitoring.
1722 *
1723 * The assumption is that they'll all be returned in the
1724 * order we got them.
1725 */
1726 if (ct->ct_syshandle == 0) {
1727 if (ct->ct_flags & CT7_TERMINATE) {
1728 isp_prt(isp, ISP_LOGINFO,
1729 "termination of 0x%x complete",
1730 ct->ct_rxid);
1731 } else if ((ct->ct_flags & CT7_SENDSTATUS) == 0) {
1732 isp_prt(isp, pl,
1733 "intermediate CTIO completed ok");
1734 } else {
1735 isp_prt(isp, pl,
1736 "unmonitored CTIO completed ok");
1737 }
1738 } else {
1739 isp_prt(isp, pl,
1740 "NO xs for CTIO (handle 0x%x) status 0x%x",
1741 ct->ct_syshandle, ct->ct_nphdl);
1742 }
1743 } else {
1744 if ((ct->ct_flags & CT2_DATAMASK) != CT2_NO_DATA) {
1745 ISP_DMAFREE(isp, xs, ct->ct_syshandle);
1746 }
1747 if (ct->ct_flags & CT2_SENDSTATUS) {
1748 /*
1749 * Sent status and command complete.
1750 *
1751 * We're now really done with this command, so we
1752 * punt to the platform dependent layers because
1753 * only there can we do the appropriate command
1754 * complete thread synchronization.
1755 */
1756 isp_prt(isp, pl, "status CTIO complete");
1757 } else {
1758 /*
1759 * Final CTIO completed. Release DMA resources and
1760 * notify platform dependent layers.
1761 */
1762 isp_prt(isp, pl, "data CTIO complete");
1763 }
1764 (void) isp_async(isp, ISPASYNC_TARGET_ACTION, ct);
1765 /*
1766 * The platform layer will destroy the handle if appropriate.
1767 */
1768 }
1769 }
1770 #endif
1771