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

Cache object: 4e569daa4049e15dc1778e855bb66453


[ 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.