The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/isp/isp_target.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

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

Cache object: 4bbe8def32fd90123cfa82e6d9268a7e


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.