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