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