root/dev/ic/isp_target.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. isp_target_notify
  2. isp_lun_cmd
  3. isp_target_put_entry
  4. isp_target_put_atio
  5. isp_endcmd
  6. isp_target_async
  7. isp_got_msg
  8. isp_got_msg_fc
  9. isp_notify_ack
  10. isp_handle_atio
  11. isp_handle_atio2
  12. isp_handle_ctio
  13. isp_handle_ctio2

    1 /* $OpenBSD: isp_target.c,v 1.14 2007/02/14 00:53:48 jsg Exp $ */
    2 /*
    3  * Machine and OS Independent Target Mode Code for the Qlogic SCSI/FC adapters.
    4  *
    5  * Copyright (c) 1999, 2000, 2001 by Matthew Jacob
    6  * All rights reserved.
    7  * mjacob@feral.com
    8  *
    9  * Redistribution and use in source and binary forms, with or without
   10  * modification, are permitted provided that the following conditions
   11  * are met:
   12  * 1. Redistributions of source code must retain the above copyright
   13  *    notice immediately at the beginning of the file, without modification,
   14  *    this list of conditions, and the following disclaimer.
   15  * 2. The name of the author may not be used to endorse or promote products
   16  *    derived from this software without specific prior written permission.
   17  *
   18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   19  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   21  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
   22  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   23  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   24  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   25  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   26  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   27  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   28  * SUCH DAMAGE.
   29  */
   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 <dev/isp/isp_freebsd.h>
   44 #endif
   45 #ifdef  __OpenBSD__
   46 #include <dev/ic/isp_openbsd.h>
   47 #endif
   48 #ifdef  __linux__
   49 #include "isp_linux.h"
   50 #endif
   51 
   52 #ifdef  ISP_TARGET_MODE
   53 static const char atiocope[] =
   54     "ATIO returned for lun %d because it was in the middle of Bus Device Reset "
   55     "on bus %d";
   56 static const char atior[] =
   57     "ATIO returned on for lun %d on from IID %d because a Bus Reset occurred "
   58     "on bus %d";
   59 
   60 static void isp_got_msg(struct ispsoftc *, int, in_entry_t *);
   61 static void isp_got_msg_fc(struct ispsoftc *, int, in_fcentry_t *);
   62 static void isp_notify_ack(struct ispsoftc *, void *);
   63 static void isp_handle_atio(struct ispsoftc *, at_entry_t *);
   64 static void isp_handle_atio2(struct ispsoftc *, at2_entry_t *);
   65 static void isp_handle_ctio(struct ispsoftc *, ct_entry_t *);
   66 static void isp_handle_ctio2(struct ispsoftc *, ct2_entry_t *);
   67 
   68 /*
   69  * The Qlogic driver gets an interrupt to look at response queue entries.
   70  * Some of these are status completions for initiatior mode commands, but
   71  * if target mode is enabled, we get a whole wad of response queue entries
   72  * to be handled here.
   73  *
   74  * Basically the split into 3 main groups: Lun Enable/Modification responses,
   75  * SCSI Command processing, and Immediate Notification events.
   76  *
   77  * You start by writing a request queue entry to enable target mode (and
   78  * establish some resource limitations which you can modify later).
   79  * The f/w responds with a LUN ENABLE or LUN MODIFY response with
   80  * the status of this action. If the enable was successful, you can expect...
   81  *
   82  * Response queue entries with SCSI commands encapsulate show up in an ATIO
   83  * (Accept Target IO) type- sometimes with enough info to stop the command at
   84  * this level. Ultimately the driver has to feed back to the f/w's request
   85  * queue a sequence of CTIOs (continue target I/O) that describe data to
   86  * be moved and/or status to be sent) and finally finishing with sending
   87  * to the f/w's response queue an ATIO which then completes the handshake
   88  * with the f/w for that command. There's a lot of variations on this theme,
   89  * including flags you can set in the CTIO for the Qlogic 2X00 fibre channel
   90  * cards that 'auto-replenish' the f/w's ATIO count, but this is the basic
   91  * gist of it.
   92  *
   93  * The third group that can show up in the response queue are Immediate
   94  * Notification events. These include things like notifications of SCSI bus
   95  * resets, or Bus Device Reset messages or other messages received. This
   96  * a classic oddbins area. It can get  a little weird because you then turn
   97  * around and acknowledge the Immediate Notify by writing an entry onto the
   98  * request queue and then the f/w turns around and gives you an acknowledgement
   99  * to *your* acknowledgement on the response queue (the idea being to let
  100  * the f/w tell you when the event is *really* over I guess).
  101  *
  102  */
  103 
  104 
  105 /*
  106  * A new response queue entry has arrived. The interrupt service code
  107  * has already swizzled it into the platform dependent from canonical form.
  108  *
  109  * Because of the way this driver is designed, unfortunately most of the
  110  * actual synchronization work has to be done in the platform-specific
  111  * code - we have no synchronization primitives in the common code.
  112  */
  113 
  114 int
  115 isp_target_notify(struct ispsoftc *isp, void *vptr, u_int16_t *optrp)
  116 {
  117         u_int16_t status, seqid;
  118         union {
  119                 at_entry_t      *atiop;
  120                 at2_entry_t     *at2iop;
  121                 ct_entry_t      *ctiop;
  122                 ct2_entry_t     *ct2iop;
  123                 lun_entry_t     *lunenp;
  124                 in_entry_t      *inotp;
  125                 in_fcentry_t    *inot_fcp;
  126                 na_entry_t      *nackp;
  127                 na_fcentry_t    *nack_fcp;
  128                 isphdr_t        *hp;
  129                 void *          *vp;
  130 #define atiop           unp.atiop
  131 #define at2iop          unp.at2iop
  132 #define ctiop           unp.ctiop
  133 #define ct2iop          unp.ct2iop
  134 #define lunenp          unp.lunenp
  135 #define inotp           unp.inotp
  136 #define inot_fcp        unp.inot_fcp
  137 #define nackp           unp.nackp
  138 #define nack_fcp        unp.nack_fcp
  139 #define hdrp            unp.hp
  140         } unp;
  141         u_int8_t local[QENTRY_LEN];
  142         int bus, type, rval = 1;
  143 
  144         type = isp_get_response_type(isp, (isphdr_t *)vptr);
  145         unp.vp = vptr;
  146 
  147         ISP_TDQE(isp, "isp_target_notify", (int) *optrp, vptr);
  148 
  149         switch(type) {
  150         case RQSTYPE_ATIO:
  151                 isp_get_atio(isp, atiop, (at_entry_t *) local);
  152                 isp_handle_atio(isp, (at_entry_t *) local);
  153                 break;
  154         case RQSTYPE_CTIO:
  155                 isp_get_ctio(isp, ctiop, (ct_entry_t *) local);
  156                 isp_handle_ctio(isp, (ct_entry_t *) local);
  157                 break;
  158         case RQSTYPE_ATIO2:
  159                 isp_get_atio2(isp, at2iop, (at2_entry_t *) local);
  160                 isp_handle_atio2(isp, (at2_entry_t *) local);
  161                 break;
  162         case RQSTYPE_CTIO2:
  163                 isp_get_ctio2(isp, ct2iop, (ct2_entry_t *) local);
  164                 isp_handle_ctio2(isp, (ct2_entry_t *) local);
  165                 break;
  166         case RQSTYPE_ENABLE_LUN:
  167         case RQSTYPE_MODIFY_LUN:
  168                 isp_get_enable_lun(isp, lunenp, (lun_entry_t *) local);
  169                 (void) isp_async(isp, ISPASYNC_TARGET_ACTION, local);
  170                 break;
  171 
  172         case RQSTYPE_NOTIFY:
  173                 /*
  174                  * Either the ISP received a SCSI message it can't
  175                  * handle, or it's returning an Immed. Notify entry
  176                  * we sent. We can send Immed. Notify entries to
  177                  * increment the firmware's resource count for them
  178                  * (we set this initially in the Enable Lun entry).
  179                  */
  180                 bus = 0;
  181                 if (IS_FC(isp)) {
  182                         isp_get_notify_fc(isp, inot_fcp, (in_fcentry_t *)local);
  183                         inot_fcp = (in_fcentry_t *) local;
  184                         status = inot_fcp->in_status;
  185                         seqid = inot_fcp->in_seqid;
  186                 } else {
  187                         isp_get_notify(isp, inotp, (in_entry_t *)local);
  188                         inotp = (in_entry_t *) local;
  189                         status = inotp->in_status & 0xff;
  190                         seqid = inotp->in_seqid;
  191                         if (IS_DUALBUS(isp)) {
  192                                 bus = GET_BUS_VAL(inotp->in_iid);
  193                                 SET_BUS_VAL(inotp->in_iid, 0);
  194                         }
  195                 }
  196                 isp_prt(isp, ISP_LOGTDEBUG0,
  197                     "Immediate Notify On Bus %d, status=0x%x seqid=0x%x",
  198                     bus, status, seqid);
  199 
  200                 /*
  201                  * ACK it right away.
  202                  */
  203                 isp_notify_ack(isp, (status == IN_RESET)? NULL : local);
  204                 switch (status) {
  205                 case IN_RESET:
  206                         (void) isp_async(isp, ISPASYNC_BUS_RESET, &bus);
  207                         break;
  208                 case IN_MSG_RECEIVED:
  209                 case IN_IDE_RECEIVED:
  210                         if (IS_FC(isp)) {
  211                                 isp_got_msg_fc(isp, bus, (in_fcentry_t *)local);
  212                         } else {
  213                                 isp_got_msg(isp, bus, (in_entry_t *)local);
  214                         }
  215                         break;
  216                 case IN_RSRC_UNAVAIL:
  217                         isp_prt(isp, ISP_LOGWARN, "Firmware out of ATIOs");
  218                         break;
  219                 case IN_PORT_LOGOUT:
  220                 case IN_ABORT_TASK:
  221                 case IN_PORT_CHANGED:
  222                 case IN_GLOBAL_LOGO:
  223                         (void) isp_async(isp, ISPASYNC_TARGET_ACTION, &local);
  224                         break;
  225                 default:
  226                         isp_prt(isp, ISP_LOGERR,
  227                             "bad status (0x%x) in isp_target_notify", status);
  228                         break;
  229                 }
  230                 break;
  231 
  232         case RQSTYPE_NOTIFY_ACK:
  233                 /*
  234                  * The ISP is acknowledging our acknowledgement of an
  235                  * Immediate Notify entry for some asynchronous event.
  236                  */
  237                 if (IS_FC(isp)) {
  238                         isp_get_notify_ack_fc(isp, nack_fcp,
  239                             (na_fcentry_t *)local);
  240                         nack_fcp = (na_fcentry_t *)local;
  241                         isp_prt(isp, ISP_LOGTDEBUG1,
  242                             "Notify Ack status=0x%x seqid 0x%x",
  243                             nack_fcp->na_status, nack_fcp->na_seqid);
  244                 } else {
  245                         isp_get_notify_ack(isp, nackp, (na_entry_t *)local);
  246                         nackp = (na_entry_t *)local;
  247                         isp_prt(isp, ISP_LOGTDEBUG1,
  248                             "Notify Ack event 0x%x status=0x%x seqid 0x%x",
  249                             nackp->na_event, nackp->na_status, nackp->na_seqid);
  250                 }
  251                 break;
  252         default:
  253                 isp_prt(isp, ISP_LOGERR,
  254                     "Unknown entry type 0x%x in isp_target_notify", type);
  255                 rval = 0;
  256                 break;
  257         }
  258 #undef  atiop
  259 #undef  at2iop
  260 #undef  ctiop
  261 #undef  ct2iop
  262 #undef  lunenp
  263 #undef  inotp
  264 #undef  inot_fcp
  265 #undef  nackp
  266 #undef  nack_fcp
  267 #undef  hdrp
  268         return (rval);
  269 }
  270 
  271  
  272 /*
  273  * Toggle (on/off) target mode for bus/target/lun
  274  *
  275  * The caller has checked for overlap and legality.
  276  *
  277  * Note that not all of bus, target or lun can be paid attention to.
  278  * Note also that this action will not be complete until the f/w writes
  279  * response entry. The caller is responsible for synchronizing this.
  280  */
  281 int
  282 isp_lun_cmd(struct ispsoftc *isp, int cmd, int bus, int tgt, int lun,
  283     int cmd_cnt, int inot_cnt, u_int32_t opaque)
  284 {
  285         lun_entry_t el;
  286         u_int16_t nxti, optr;
  287         void *outp;
  288 
  289 
  290         MEMZERO(&el, sizeof (el));
  291         if (IS_DUALBUS(isp)) {
  292                 el.le_rsvd = (bus & 0x1) << 7;
  293         }
  294         el.le_cmd_count = cmd_cnt;
  295         el.le_in_count = inot_cnt;
  296         if (cmd == RQSTYPE_ENABLE_LUN) {
  297                 if (IS_SCSI(isp)) {
  298                         el.le_flags = LUN_TQAE|LUN_DISAD;
  299                         el.le_cdb6len = 12;
  300                         el.le_cdb7len = 12;
  301                 }
  302         } else if (cmd == -RQSTYPE_ENABLE_LUN) {
  303                 cmd = RQSTYPE_ENABLE_LUN;
  304                 el.le_cmd_count = 0;
  305                 el.le_in_count = 0;
  306         } else if (cmd == -RQSTYPE_MODIFY_LUN) {
  307                 cmd = RQSTYPE_MODIFY_LUN;
  308                 el.le_ops = LUN_CCDECR | LUN_INDECR;
  309         } else {
  310                 el.le_ops = LUN_CCINCR | LUN_ININCR;
  311         }
  312         el.le_header.rqs_entry_type = cmd;
  313         el.le_header.rqs_entry_count = 1;
  314         el.le_reserved = opaque;
  315         if (IS_SCSI(isp)) {
  316                 el.le_tgt = tgt;
  317                 el.le_lun = lun;
  318         } else if ((FCPARAM(isp)->isp_fwattr & ISP_FW_ATTR_SCCLUN) == 0) {
  319                 el.le_lun = lun;
  320         }
  321         el.le_timeout = 2;
  322 
  323         if (isp_getrqentry(isp, &nxti, &optr, &outp)) {
  324                 isp_prt(isp, ISP_LOGERR,
  325                     "Request Queue Overflow in isp_lun_cmd");
  326                 return (-1);
  327         }
  328         ISP_TDQE(isp, "isp_lun_cmd", (int) optr, &el);
  329         isp_put_enable_lun(isp, &el, outp);
  330         ISP_ADD_REQUEST(isp, nxti);
  331         return (0);
  332 }
  333 
  334 
  335 int
  336 isp_target_put_entry(struct ispsoftc *isp, void *ap)
  337 {
  338         void *outp;
  339         u_int16_t nxti, optr;
  340         u_int8_t etype = ((isphdr_t *) ap)->rqs_entry_type;
  341 
  342         if (isp_getrqentry(isp, &nxti, &optr, &outp)) {
  343                 isp_prt(isp, ISP_LOGWARN,
  344                     "Request Queue Overflow in isp_target_put_entry");
  345                 return (-1);
  346         }
  347         switch (etype) {
  348         case RQSTYPE_ATIO:
  349                 isp_put_atio(isp, (at_entry_t *) ap, (at_entry_t *) outp);
  350                 break;
  351         case RQSTYPE_ATIO2:
  352                 isp_put_atio2(isp, (at2_entry_t *) ap, (at2_entry_t *) outp);
  353                 break;
  354         case RQSTYPE_CTIO:
  355                 isp_put_ctio(isp, (ct_entry_t *) ap, (ct_entry_t *) outp);
  356                 break;
  357         case RQSTYPE_CTIO2:
  358                 isp_put_ctio2(isp, (ct2_entry_t *) ap, (ct2_entry_t *) outp);
  359                 break;
  360         default:
  361                 isp_prt(isp, ISP_LOGERR,
  362                     "Unknown type 0x%x in isp_put_entry", etype);
  363                 return (-1);
  364         }
  365 
  366         ISP_TDQE(isp, "isp_target_put_entry", (int) optr, ap);
  367         ISP_ADD_REQUEST(isp, nxti);
  368         return (0);
  369 }
  370 
  371 int
  372 isp_target_put_atio(struct ispsoftc *isp, void *arg)
  373 {
  374         union {
  375                 at_entry_t _atio;
  376                 at2_entry_t _atio2;
  377         } atun;
  378 
  379         MEMZERO(&atun, sizeof atun);
  380         if (IS_FC(isp)) {
  381                 at2_entry_t *aep = arg;
  382                 atun._atio2.at_header.rqs_entry_type = RQSTYPE_ATIO2;
  383                 atun._atio2.at_header.rqs_entry_count = 1;
  384                 if (FCPARAM(isp)->isp_fwattr & ISP_FW_ATTR_SCCLUN) {
  385                         atun._atio2.at_scclun = (u_int16_t) aep->at_scclun;
  386                 } else {
  387                         atun._atio2.at_lun = (u_int8_t) aep->at_lun;
  388                 }
  389                 atun._atio2.at_iid = aep->at_iid;
  390                 atun._atio2.at_rxid = aep->at_rxid;
  391                 atun._atio2.at_status = CT_OK;
  392         } else {
  393                 at_entry_t *aep = arg;
  394                 atun._atio.at_header.rqs_entry_type = RQSTYPE_ATIO;
  395                 atun._atio.at_header.rqs_entry_count = 1;
  396                 atun._atio.at_handle = aep->at_handle;
  397                 atun._atio.at_iid = aep->at_iid;
  398                 atun._atio.at_tgt = aep->at_tgt;
  399                 atun._atio.at_lun = aep->at_lun;
  400                 atun._atio.at_tag_type = aep->at_tag_type;
  401                 atun._atio.at_tag_val = aep->at_tag_val;
  402                 atun._atio.at_status = (aep->at_flags & AT_TQAE);
  403                 atun._atio.at_status |= CT_OK;
  404         }
  405         return (isp_target_put_entry(isp, &atun));
  406 }
  407 
  408 /*
  409  * Command completion- both for handling cases of no resources or
  410  * no blackhole driver, or other cases where we have to, inline,
  411  * finish the command sanely, or for normal command completion.
  412  *
  413  * The 'completion' code value has the scsi status byte in the low 8 bits.
  414  * If status is a CHECK CONDITION and bit 8 is nonzero, then bits 12..15 have
  415  * the sense key and  bits 16..23 have the ASCQ and bits 24..31 have the ASC
  416  * values.
  417  *
  418  * NB: the key, asc, ascq, cannot be used for parallel SCSI as it doesn't
  419  * NB: inline SCSI sense reporting. As such, we lose this information. XXX.
  420  *
  421  * For both parallel && fibre channel, we use the feature that does
  422  * an automatic resource autoreplenish so we don't have then later do
  423  * put of an atio to replenish the f/w's resource count.
  424  */
  425 
  426 int
  427 isp_endcmd(struct ispsoftc *isp, void *arg, u_int32_t code, u_int16_t hdl)
  428 {
  429         int sts;
  430         union {
  431                 ct_entry_t _ctio;
  432                 ct2_entry_t _ctio2;
  433         } un;
  434 
  435         MEMZERO(&un, sizeof un);
  436         sts = code & 0xff;
  437 
  438         if (IS_FC(isp)) {
  439                 at2_entry_t *aep = arg;
  440                 ct2_entry_t *cto = &un._ctio2;
  441 
  442                 cto->ct_header.rqs_entry_type = RQSTYPE_CTIO2;
  443                 cto->ct_header.rqs_entry_count = 1;
  444                 cto->ct_iid = aep->at_iid;
  445                 if ((FCPARAM(isp)->isp_fwattr & ISP_FW_ATTR_SCCLUN) == 0) {
  446                         cto->ct_lun = aep->at_lun;
  447                 }
  448                 cto->ct_rxid = aep->at_rxid;
  449                 cto->rsp.m1.ct_scsi_status = sts & 0xff;
  450                 cto->ct_flags = CT2_SENDSTATUS | CT2_NO_DATA | CT2_FLAG_MODE1;
  451                 if (hdl == 0) {
  452                         cto->ct_flags |= CT2_CCINCR;
  453                 }
  454                 if (aep->at_datalen) {
  455                         cto->ct_resid = aep->at_datalen;
  456                         cto->rsp.m1.ct_scsi_status |= CT2_DATA_UNDER;
  457                 }
  458                 if ((sts & 0xff) == SCSI_CHECK && (sts & ECMD_SVALID)) {
  459                         cto->rsp.m1.ct_resp[0] = 0xf0;
  460                         cto->rsp.m1.ct_resp[2] = (code >> 12) & 0xf;
  461                         cto->rsp.m1.ct_resp[7] = 8;
  462                         cto->rsp.m1.ct_resp[12] = (code >> 24) & 0xff;
  463                         cto->rsp.m1.ct_resp[13] = (code >> 16) & 0xff;
  464                         cto->rsp.m1.ct_senselen = 16;
  465                         cto->rsp.m1.ct_scsi_status |= CT2_SNSLEN_VALID;
  466                 }
  467                 cto->ct_syshandle = hdl;
  468         } else {
  469                 at_entry_t *aep = arg;
  470                 ct_entry_t *cto = &un._ctio;
  471 
  472                 cto->ct_header.rqs_entry_type = RQSTYPE_CTIO;
  473                 cto->ct_header.rqs_entry_count = 1;
  474                 cto->ct_fwhandle = aep->at_handle;
  475                 cto->ct_iid = aep->at_iid;
  476                 cto->ct_tgt = aep->at_tgt;
  477                 cto->ct_lun = aep->at_lun;
  478                 cto->ct_tag_type = aep->at_tag_type;
  479                 cto->ct_tag_val = aep->at_tag_val;
  480                 if (aep->at_flags & AT_TQAE) {
  481                         cto->ct_flags |= CT_TQAE;
  482                 }
  483                 cto->ct_flags = CT_SENDSTATUS | CT_NO_DATA;
  484                 if (hdl == 0) {
  485                         cto->ct_flags |= CT_CCINCR;
  486                 }
  487                 cto->ct_scsi_status = sts;
  488                 cto->ct_syshandle = hdl;
  489         }
  490         return (isp_target_put_entry(isp, &un));
  491 }
  492 
  493 int
  494 isp_target_async(struct ispsoftc *isp, int bus, int event)
  495 {
  496         tmd_event_t evt;
  497         tmd_msg_t msg;
  498 
  499         switch (event) {
  500         /*
  501          * These three we handle here to propagate an effective bus reset
  502          * upstream, but these do not require any immediate notify actions
  503          * so we return when done.
  504          */
  505         case ASYNC_LIP_F8:
  506         case ASYNC_LIP_OCCURRED:
  507         case ASYNC_LOOP_UP:
  508         case ASYNC_LOOP_DOWN:
  509         case ASYNC_LOOP_RESET:
  510         case ASYNC_PTPMODE:
  511                 /*
  512                  * These don't require any immediate notify actions. We used
  513                  * treat them like SCSI Bus Resets, but that was just plain
  514                  * wrong. Let the normal CTIO completion report what occurred.
  515                  */
  516                 return (0);
  517 
  518         case ASYNC_BUS_RESET:
  519         case ASYNC_TIMEOUT_RESET:
  520                 if (IS_FC(isp)) {
  521                         return (0); /* we'll be getting an inotify instead */
  522                 }
  523                 evt.ev_bus = bus;
  524                 evt.ev_event = event;
  525                 (void) isp_async(isp, ISPASYNC_TARGET_EVENT, &evt);
  526                 break;
  527         case ASYNC_DEVICE_RESET:
  528                 /*
  529                  * Bus Device Reset resets a specific target, so
  530                  * we pass this as a synthesized message.
  531                  */
  532                 MEMZERO(&msg, sizeof msg);
  533                 if (IS_FC(isp)) {
  534                         msg.nt_iid = FCPARAM(isp)->isp_loopid;
  535                 } else {
  536                         msg.nt_iid = SDPARAM(isp)->isp_initiator_id;
  537                 }
  538                 msg.nt_bus = bus;
  539                 msg.nt_msg[0] = MSG_BUS_DEV_RESET;
  540                 (void) isp_async(isp, ISPASYNC_TARGET_MESSAGE, &msg);
  541                 break;
  542         default:
  543                 isp_prt(isp, ISP_LOGERR,
  544                     "isp_target_async: unknown event 0x%x", event);
  545                 break;
  546         }
  547         if (isp->isp_state == ISP_RUNSTATE)
  548                 isp_notify_ack(isp, NULL);
  549         return(0);
  550 }
  551 
  552 
  553 /*
  554  * Process a received message.
  555  * The ISP firmware can handle most messages, there are only
  556  * a few that we need to deal with:
  557  * - abort: clean up the current command
  558  * - abort tag and clear queue
  559  */
  560 
  561 static void
  562 isp_got_msg(struct ispsoftc *isp, int bus, in_entry_t *inp)
  563 {
  564         u_int8_t status = inp->in_status & ~QLTM_SVALID;
  565 
  566         if (status == IN_IDE_RECEIVED || status == IN_MSG_RECEIVED) {
  567                 tmd_msg_t msg;
  568 
  569                 MEMZERO(&msg, sizeof (msg));
  570                 msg.nt_bus = bus;
  571                 msg.nt_iid = inp->in_iid;
  572                 msg.nt_tgt = inp->in_tgt;
  573                 msg.nt_lun = inp->in_lun;
  574                 msg.nt_tagtype = inp->in_tag_type;
  575                 msg.nt_tagval = inp->in_tag_val;
  576                 MEMCPY(msg.nt_msg, inp->in_msg, IN_MSGLEN);
  577                 (void) isp_async(isp, ISPASYNC_TARGET_MESSAGE, &msg);
  578         } else {
  579                 isp_prt(isp, ISP_LOGERR,
  580                     "unknown immediate notify status 0x%x", inp->in_status);
  581         }
  582 }
  583 
  584 /*
  585  * Synthesize a message from the task management flags in a FCP_CMND_IU.
  586  */
  587 static void
  588 isp_got_msg_fc(struct ispsoftc *isp, int bus, in_fcentry_t *inp)
  589 {
  590         int lun;
  591         static const char f1[] = "%s from iid %d lun %d seq 0x%x";
  592         static const char f2[] = 
  593             "unknown %s 0x%x lun %d iid %d task flags 0x%x seq 0x%x\n";
  594 
  595         if (FCPARAM(isp)->isp_fwattr & ISP_FW_ATTR_SCCLUN) {
  596                 lun = inp->in_scclun;
  597         } else {
  598                 lun = inp->in_lun;
  599         }
  600 
  601         if (inp->in_status != IN_MSG_RECEIVED) {
  602                 isp_prt(isp, ISP_LOGINFO, f2, "immediate notify status",
  603                     inp->in_status, lun, inp->in_iid,
  604                     inp->in_task_flags,  inp->in_seqid);
  605         } else {
  606                 tmd_msg_t msg;
  607 
  608                 MEMZERO(&msg, sizeof (msg));
  609                 msg.nt_bus = bus;
  610                 msg.nt_iid = inp->in_iid;
  611                 msg.nt_tagval = inp->in_seqid;
  612                 msg.nt_lun = lun;
  613 
  614                 if (inp->in_task_flags & TASK_FLAGS_ABORT_TASK) {
  615                         isp_prt(isp, ISP_LOGINFO, f1, "ABORT TASK",
  616                             inp->in_iid, lun, inp->in_seqid);
  617                         msg.nt_msg[0] = MSG_ABORT_TAG;
  618                 } else if (inp->in_task_flags & TASK_FLAGS_CLEAR_TASK_SET) {
  619                         isp_prt(isp, ISP_LOGINFO, f1, "CLEAR TASK SET",
  620                             inp->in_iid, lun, inp->in_seqid);
  621                         msg.nt_msg[0] = MSG_CLEAR_QUEUE;
  622                 } else if (inp->in_task_flags & TASK_FLAGS_TARGET_RESET) {
  623                         isp_prt(isp, ISP_LOGINFO, f1, "TARGET RESET",
  624                             inp->in_iid, lun, inp->in_seqid);
  625                         msg.nt_msg[0] = MSG_BUS_DEV_RESET;
  626                 } else if (inp->in_task_flags & TASK_FLAGS_CLEAR_ACA) {
  627                         isp_prt(isp, ISP_LOGINFO, f1, "CLEAR ACA",
  628                             inp->in_iid, lun, inp->in_seqid);
  629                         /* ???? */
  630                         msg.nt_msg[0] = MSG_REL_RECOVERY;
  631                 } else if (inp->in_task_flags & TASK_FLAGS_TERMINATE_TASK) {
  632                         isp_prt(isp, ISP_LOGINFO, f1, "TERMINATE TASK",
  633                             inp->in_iid, lun, inp->in_seqid);
  634                         msg.nt_msg[0] = MSG_TERM_IO_PROC;
  635                 } else {
  636                         isp_prt(isp, ISP_LOGWARN, f2, "task flag",
  637                             inp->in_status, lun, inp->in_iid,
  638                             inp->in_task_flags,  inp->in_seqid);
  639                 }
  640                 if (msg.nt_msg[0]) {
  641                         (void) isp_async(isp, ISPASYNC_TARGET_MESSAGE, &msg);
  642                 }
  643         }
  644 }
  645 
  646 static void
  647 isp_notify_ack(struct ispsoftc *isp, void *arg)
  648 {
  649         char storage[QENTRY_LEN];
  650         u_int16_t nxti, optr;
  651         void *outp;
  652 
  653         if (isp_getrqentry(isp, &nxti, &optr, &outp)) {
  654                 isp_prt(isp, ISP_LOGWARN,
  655                     "Request Queue Overflow For isp_notify_ack");
  656                 return;
  657         }
  658 
  659         MEMZERO(storage, QENTRY_LEN);
  660 
  661         if (IS_FC(isp)) {
  662                 na_fcentry_t *na = (na_fcentry_t *) storage;
  663                 if (arg) {
  664                         in_fcentry_t *inp = arg;
  665                         MEMCPY(storage, arg, sizeof (isphdr_t));
  666                         na->na_iid = inp->in_iid;
  667                         if (FCPARAM(isp)->isp_fwattr & ISP_FW_ATTR_SCCLUN) {
  668                                 na->na_lun = inp->in_scclun;
  669                         } else {
  670                                 na->na_lun = inp->in_lun;
  671                         }
  672                         na->na_task_flags = inp->in_task_flags;
  673                         na->na_seqid = inp->in_seqid;
  674                         na->na_flags = NAFC_RCOUNT;
  675                         na->na_status = inp->in_status;
  676                         if (inp->in_status == IN_RESET) {
  677                                 na->na_flags |= NAFC_RST_CLRD;
  678                         }
  679                 } else {
  680                         na->na_flags = NAFC_RST_CLRD;
  681                 }
  682                 na->na_header.rqs_entry_type = RQSTYPE_NOTIFY_ACK;
  683                 na->na_header.rqs_entry_count = 1;
  684                 isp_put_notify_ack_fc(isp, na, (na_fcentry_t *)outp);
  685         } else {
  686                 na_entry_t *na = (na_entry_t *) storage;
  687                 if (arg) {
  688                         in_entry_t *inp = arg;
  689                         MEMCPY(storage, arg, sizeof (isphdr_t));
  690                         na->na_iid = inp->in_iid;
  691                         na->na_lun = inp->in_lun;
  692                         na->na_tgt = inp->in_tgt;
  693                         na->na_seqid = inp->in_seqid;
  694                         if (inp->in_status == IN_RESET) {
  695                                 na->na_event = NA_RST_CLRD;
  696                         }
  697                 } else {
  698                         na->na_event = NA_RST_CLRD;
  699                 }
  700                 na->na_header.rqs_entry_type = RQSTYPE_NOTIFY_ACK;
  701                 na->na_header.rqs_entry_count = 1;
  702                 isp_put_notify_ack(isp, na, (na_entry_t *)outp);
  703         }
  704         ISP_TDQE(isp, "isp_notify_ack", (int) optr, storage);
  705         ISP_ADD_REQUEST(isp, nxti);
  706 }
  707 
  708 static void
  709 isp_handle_atio(struct ispsoftc *isp, at_entry_t *aep)
  710 {
  711         int lun;
  712         lun = aep->at_lun;
  713         /*
  714          * The firmware status (except for the QLTM_SVALID bit) indicates
  715          * why this ATIO was sent to us.
  716          *
  717          * If QLTM_SVALID is set, the firmware has recommended Sense Data.
  718          *
  719          * If the DISCONNECTS DISABLED bit is set in the flags field,
  720          * we're still connected on the SCSI bus - i.e. the initiator
  721          * did not set DiscPriv in the identify message. We don't care
  722          * about this so it's ignored.
  723          */
  724 
  725         switch(aep->at_status & ~QLTM_SVALID) {
  726         case AT_PATH_INVALID:
  727                 /*
  728                  * ATIO rejected by the firmware due to disabled lun.
  729                  */
  730                 isp_prt(isp, ISP_LOGERR,
  731                     "rejected ATIO for disabled lun %d", lun);
  732                 break;
  733         case AT_NOCAP:
  734                 /*
  735                  * Requested Capability not available
  736                  * We sent an ATIO that overflowed the firmware's
  737                  * command resource count.
  738                  */
  739                 isp_prt(isp, ISP_LOGERR,
  740                     "rejected ATIO for lun %d because of command count"
  741                     " overflow", lun);
  742                 break;
  743 
  744         case AT_BDR_MSG:
  745                 /*
  746                  * If we send an ATIO to the firmware to increment
  747                  * its command resource count, and the firmware is
  748                  * recovering from a Bus Device Reset, it returns
  749                  * the ATIO with this status. We set the command
  750                  * resource count in the Enable Lun entry and do
  751                  * not increment it. Therefore we should never get
  752                  * this status here.
  753                  */
  754                 isp_prt(isp, ISP_LOGERR, atiocope, lun,
  755                     GET_BUS_VAL(aep->at_iid));
  756                 break;
  757 
  758         case AT_CDB:            /* Got a CDB */
  759         case AT_PHASE_ERROR:    /* Bus Phase Sequence Error */
  760                 /*
  761                  * Punt to platform specific layer.
  762                  */
  763                 (void) isp_async(isp, ISPASYNC_TARGET_ACTION, aep);
  764                 break;
  765 
  766         case AT_RESET:
  767                 /*
  768                  * A bus reset came along and blew away this command. Why
  769                  * they do this in addition the async event code stuff,
  770                  * I dunno.
  771                  *
  772                  * Ignore it because the async event will clear things
  773                  * up for us.
  774                  */
  775                 isp_prt(isp, ISP_LOGWARN, atior, lun,
  776                     GET_IID_VAL(aep->at_iid), GET_BUS_VAL(aep->at_iid));
  777                 break;
  778 
  779 
  780         default:
  781                 isp_prt(isp, ISP_LOGERR,
  782                     "Unknown ATIO status 0x%x from initiator %d for lun %d",
  783                     aep->at_status, aep->at_iid, lun);
  784                 (void) isp_target_put_atio(isp, aep);
  785                 break;
  786         }
  787 }
  788 
  789 static void
  790 isp_handle_atio2(struct ispsoftc *isp, at2_entry_t *aep)
  791 {
  792         int lun;
  793 
  794         if (FCPARAM(isp)->isp_fwattr & ISP_FW_ATTR_SCCLUN) {
  795                 lun = aep->at_scclun;
  796         } else {
  797                 lun = aep->at_lun;
  798         }
  799 
  800         /*
  801          * The firmware status (except for the QLTM_SVALID bit) indicates
  802          * why this ATIO was sent to us.
  803          *
  804          * If QLTM_SVALID is set, the firmware has recommended Sense Data.
  805          *
  806          * If the DISCONNECTS DISABLED bit is set in the flags field,
  807          * we're still connected on the SCSI bus - i.e. the initiator
  808          * did not set DiscPriv in the identify message. We don't care
  809          * about this so it's ignored.
  810          */
  811 
  812         switch(aep->at_status & ~QLTM_SVALID) {
  813         case AT_PATH_INVALID:
  814                 /*
  815                  * ATIO rejected by the firmware due to disabled lun.
  816                  */
  817                 isp_prt(isp, ISP_LOGERR,
  818                     "rejected ATIO2 for disabled lun %d", lun);
  819                 break;
  820         case AT_NOCAP:
  821                 /*
  822                  * Requested Capability not available
  823                  * We sent an ATIO that overflowed the firmware's
  824                  * command resource count.
  825                  */
  826                 isp_prt(isp, ISP_LOGERR,
  827                     "rejected ATIO2 for lun %d- command count overflow", lun);
  828                 break;
  829 
  830         case AT_BDR_MSG:
  831                 /*
  832                  * If we send an ATIO to the firmware to increment
  833                  * its command resource count, and the firmware is
  834                  * recovering from a Bus Device Reset, it returns
  835                  * the ATIO with this status. We set the command
  836                  * resource count in the Enable Lun entry and no
  837                  * not increment it. Therefore we should never get
  838                  * this status here.
  839                  */
  840                 isp_prt(isp, ISP_LOGERR, atiocope, lun, 0);
  841                 break;
  842 
  843         case AT_CDB:            /* Got a CDB */
  844                 /*
  845                  * Punt to platform specific layer.
  846                  */
  847                 (void) isp_async(isp, ISPASYNC_TARGET_ACTION, aep);
  848                 break;
  849 
  850         case AT_RESET:
  851                 /*
  852                  * A bus reset came along an blew away this command. Why
  853                  * they do this in addition the async event code stuff,
  854                  * I dunno.
  855                  *
  856                  * Ignore it because the async event will clear things
  857                  * up for us.
  858                  */
  859                 isp_prt(isp, ISP_LOGERR, atior, lun, aep->at_iid, 0);
  860                 break;
  861 
  862 
  863         default:
  864                 isp_prt(isp, ISP_LOGERR,
  865                     "Unknown ATIO2 status 0x%x from initiator %d for lun %d",
  866                     aep->at_status, aep->at_iid, lun);
  867                 (void) isp_target_put_atio(isp, aep);
  868                 break;
  869         }
  870 }
  871 
  872 static void
  873 isp_handle_ctio(struct ispsoftc *isp, ct_entry_t *ct)
  874 {
  875         void *xs;
  876         int pl = ISP_LOGTDEBUG2;
  877         char *fmsg = NULL;
  878 
  879         if (ct->ct_syshandle) {
  880                 xs = isp_find_xs(isp, ct->ct_syshandle);
  881                 if (xs == NULL)
  882                         pl = ISP_LOGALL;
  883         } else {
  884                 xs = NULL;
  885         }
  886 
  887         switch(ct->ct_status & ~QLTM_SVALID) {
  888         case CT_OK:
  889                 /*
  890                  * There are generally 3 possibilities as to why we'd get
  891                  * this condition:
  892                  *      We disconnected after receiving a CDB.
  893                  *      We sent or received data.
  894                  *      We sent status & command complete.
  895                  */
  896 
  897                 if (ct->ct_flags & CT_SENDSTATUS) {
  898                         break;
  899                 } else if ((ct->ct_flags & CT_DATAMASK) == CT_NO_DATA) {
  900                         /*
  901                          * Nothing to do in this case.
  902                          */
  903                         isp_prt(isp, pl, "CTIO- iid %d disconnected OK",
  904                             ct->ct_iid);
  905                         return;
  906                 }
  907                 break;
  908 
  909         case CT_BDR_MSG:
  910                 /*
  911                  * Bus Device Reset message received or the SCSI Bus has
  912                  * been Reset; the firmware has gone to Bus Free.
  913                  *
  914                  * The firmware generates an async mailbox interrupt to
  915                  * notify us of this and returns outstanding CTIOs with this
  916                  * status. These CTIOs are handled in that same way as
  917                  * CT_ABORTED ones, so just fall through here.
  918                  */
  919                 fmsg = "Bus Device Reset";
  920                 /*FALLTHROUGH*/
  921         case CT_RESET:
  922                 if (fmsg == NULL)
  923                         fmsg = "Bus Reset";
  924                 /*FALLTHROUGH*/
  925         case CT_ABORTED:
  926                 /*
  927                  * When an Abort message is received the firmware goes to
  928                  * Bus Free and returns all outstanding CTIOs with the status
  929                  * set, then sends us an Immediate Notify entry.
  930                  */
  931                 if (fmsg == NULL)
  932                         fmsg = "ABORT TAG message sent by Initiator";
  933 
  934                 isp_prt(isp, ISP_LOGWARN, "CTIO destroyed by %s", fmsg);
  935                 break;
  936 
  937         case CT_INVAL:
  938                 /*
  939                  * CTIO rejected by the firmware due to disabled lun.
  940                  * "Cannot Happen".
  941                  */
  942                 isp_prt(isp, ISP_LOGERR,
  943                     "Firmware rejected CTIO for disabled lun %d",
  944                     ct->ct_lun);
  945                 break;
  946 
  947         case CT_NOPATH:
  948                 /*
  949                  * CTIO rejected by the firmware due "no path for the
  950                  * nondisconnecting nexus specified". This means that
  951                  * we tried to access the bus while a non-disconnecting
  952                  * command is in process.
  953                  */
  954                 isp_prt(isp, ISP_LOGERR,
  955                     "Firmware rejected CTIO for bad nexus %d/%d/%d",
  956                     ct->ct_iid, ct->ct_tgt, ct->ct_lun);
  957                 break;
  958 
  959         case CT_RSELTMO:
  960                 fmsg = "Reselection";
  961                 /*FALLTHROUGH*/
  962         case CT_TIMEOUT:
  963                 if (fmsg == NULL)
  964                         fmsg = "Command";
  965                 isp_prt(isp, ISP_LOGERR, "Firmware timed out on %s", fmsg);
  966                 break;
  967 
  968         case    CT_PANIC:
  969                 if (fmsg == NULL)
  970                         fmsg = "Unrecoverable Error";
  971                 /*FALLTHROUGH*/
  972         case CT_ERR:
  973                 if (fmsg == NULL)
  974                         fmsg = "Completed with Error";
  975                 /*FALLTHROUGH*/
  976         case CT_PHASE_ERROR:
  977                 if (fmsg == NULL)
  978                         fmsg = "Phase Sequence Error";
  979                 /*FALLTHROUGH*/
  980         case CT_TERMINATED:
  981                 if (fmsg == NULL)
  982                         fmsg = "terminated by TERMINATE TRANSFER";
  983                 /*FALLTHROUGH*/
  984         case CT_NOACK:
  985                 if (fmsg == NULL)
  986                         fmsg = "unacknowledged Immediate Notify pending";
  987                 isp_prt(isp, ISP_LOGERR, "CTIO returned by f/w- %s", fmsg);
  988                 break;
  989         default:
  990                 isp_prt(isp, ISP_LOGERR, "Unknown CTIO status 0x%x",
  991                     ct->ct_status & ~QLTM_SVALID);
  992                 break;
  993         }
  994 
  995         if (xs == NULL) {
  996                 /*
  997                  * There may be more than one CTIO for a data transfer,
  998                  * or this may be a status CTIO we're not monitoring.
  999                  *
 1000                  * The assumption is that they'll all be returned in the
 1001                  * order we got them.
 1002                  */
 1003                 if (ct->ct_syshandle == 0) {
 1004                         if ((ct->ct_flags & CT_SENDSTATUS) == 0) {
 1005                                 isp_prt(isp, pl,
 1006                                     "intermediate CTIO completed ok");
 1007                         } else {
 1008                                 isp_prt(isp, pl,
 1009                                     "unmonitored CTIO completed ok");
 1010                         }
 1011                 } else {
 1012                         isp_prt(isp, pl,
 1013                             "NO xs for CTIO (handle 0x%x) status 0x%x",
 1014                             ct->ct_syshandle, ct->ct_status & ~QLTM_SVALID);
 1015                 }
 1016         } else {
 1017                 /*
 1018                  * Final CTIO completed. Release DMA resources and
 1019                  * notify platform dependent layers.
 1020                  */
 1021                 if ((ct->ct_flags & CT_DATAMASK) != CT_NO_DATA) {
 1022                         ISP_DMAFREE(isp, xs, ct->ct_syshandle);
 1023                 }
 1024                 isp_prt(isp, pl, "final CTIO complete");
 1025                 /*
 1026                  * The platform layer will destroy the handle if appropriate.
 1027                  */
 1028                 (void) isp_async(isp, ISPASYNC_TARGET_ACTION, ct);
 1029         }
 1030 }
 1031 
 1032 static void
 1033 isp_handle_ctio2(struct ispsoftc *isp, ct2_entry_t *ct)
 1034 {
 1035         XS_T *xs;
 1036         int pl = ISP_LOGTDEBUG2;
 1037         char *fmsg = NULL;
 1038 
 1039         if (ct->ct_syshandle) {
 1040                 xs = isp_find_xs(isp, ct->ct_syshandle);
 1041                 if (xs == NULL)
 1042                         pl = ISP_LOGALL;
 1043         } else {
 1044                 xs = NULL;
 1045         }
 1046 
 1047         switch(ct->ct_status & ~QLTM_SVALID) {
 1048         case CT_BUS_ERROR:
 1049                 isp_prt(isp, ISP_LOGERR, "PCI DMA Bus Error");
 1050                 /* FALLTHROUGH */
 1051         case CT_DATA_OVER:
 1052         case CT_DATA_UNDER:
 1053         case CT_OK:
 1054                 /*
 1055                  * There are generally 2 possibilities as to why we'd get
 1056                  * this condition:
 1057                  *      We sent or received data.
 1058                  *      We sent status & command complete.
 1059                  */
 1060 
 1061                 break;
 1062 
 1063         case CT_BDR_MSG:
 1064                 /*
 1065                  * Target Reset function received.
 1066                  *
 1067                  * The firmware generates an async mailbox interrupt to
 1068                  * notify us of this and returns outstanding CTIOs with this
 1069                  * status. These CTIOs are handled in that same way as
 1070                  * CT_ABORTED ones, so just fall through here.
 1071                  */
 1072                 fmsg = "TARGET RESET Task Management Function Received";
 1073                 /*FALLTHROUGH*/
 1074         case CT_RESET:
 1075                 if (fmsg == NULL)
 1076                         fmsg = "LIP Reset";
 1077                 /*FALLTHROUGH*/
 1078         case CT_ABORTED:
 1079                 /*
 1080                  * When an Abort message is received the firmware goes to
 1081                  * Bus Free and returns all outstanding CTIOs with the status
 1082                  * set, then sends us an Immediate Notify entry.
 1083                  */
 1084                 if (fmsg == NULL)
 1085                         fmsg = "ABORT Task Management Function Received";
 1086 
 1087                 isp_prt(isp, ISP_LOGERR, "CTIO2 destroyed by %s", fmsg);
 1088                 break;
 1089 
 1090         case CT_INVAL:
 1091                 /*
 1092                  * CTIO rejected by the firmware - invalid data direction.
 1093                  */
 1094                 isp_prt(isp, ISP_LOGERR, "CTIO2 had wrong data direction");
 1095                 break;
 1096 
 1097         case CT_RSELTMO:
 1098                 fmsg = "failure to reconnect to initiator";
 1099                 /*FALLTHROUGH*/
 1100         case CT_TIMEOUT:
 1101                 if (fmsg == NULL)
 1102                         fmsg = "command";
 1103                 isp_prt(isp, ISP_LOGERR, "Firmware timed out on %s", fmsg);
 1104                 break;
 1105 
 1106         case CT_ERR:
 1107                 fmsg = "Completed with Error";
 1108                 /*FALLTHROUGH*/
 1109         case CT_LOGOUT:
 1110                 if (fmsg == NULL)
 1111                         fmsg = "Port Logout";
 1112                 /*FALLTHROUGH*/
 1113         case CT_PORTNOTAVAIL:
 1114                 if (fmsg == NULL)
 1115                         fmsg = "Port not available";
 1116         case CT_PORTCHANGED:
 1117                 if (fmsg == NULL)
 1118                         fmsg = "Port Changed";
 1119         case CT_NOACK:
 1120                 if (fmsg == NULL)
 1121                         fmsg = "unacknowledged Immediate Notify pending";
 1122                 isp_prt(isp, ISP_LOGERR, "CTIO returned by f/w- %s", fmsg);
 1123                 break;
 1124 
 1125         case CT_INVRXID:
 1126                 /*
 1127                  * CTIO rejected by the firmware because an invalid RX_ID.
 1128                  * Just print a message.
 1129                  */
 1130                 isp_prt(isp, ISP_LOGERR,
 1131                     "CTIO2 completed with Invalid RX_ID 0x%x", ct->ct_rxid);
 1132                 break;
 1133 
 1134         default:
 1135                 isp_prt(isp, ISP_LOGERR, "Unknown CTIO2 status 0x%x",
 1136                     ct->ct_status & ~QLTM_SVALID);
 1137                 break;
 1138         }
 1139 
 1140         if (xs == NULL) {
 1141                 /*
 1142                  * There may be more than one CTIO for a data transfer,
 1143                  * or this may be a status CTIO we're not monitoring.
 1144                  *
 1145                  * The assumption is that they'll all be returned in the
 1146                  * order we got them.
 1147                  */
 1148                 if (ct->ct_syshandle == 0) {
 1149                         if ((ct->ct_flags & CT_SENDSTATUS) == 0) {
 1150                                 isp_prt(isp, pl,
 1151                                     "intermediate CTIO completed ok");
 1152                         } else {
 1153                                 isp_prt(isp, pl,
 1154                                     "unmonitored CTIO completed ok");
 1155                         }
 1156                 } else {
 1157                         isp_prt(isp, pl,
 1158                             "NO xs for CTIO (handle 0x%x) status 0x%x",
 1159                             ct->ct_syshandle, ct->ct_status & ~QLTM_SVALID);
 1160                 }
 1161         } else {
 1162                 if ((ct->ct_flags & CT2_DATAMASK) != CT2_NO_DATA) {
 1163                         ISP_DMAFREE(isp, xs, ct->ct_syshandle);
 1164                 }
 1165                 if (ct->ct_flags & CT_SENDSTATUS) {
 1166                         /*
 1167                          * Sent status and command complete.
 1168                          *
 1169                          * We're now really done with this command, so we
 1170                          * punt to the platform dependent layers because
 1171                          * only there can we do the appropriate command
 1172                          * complete thread synchronization.
 1173                          */
 1174                         isp_prt(isp, pl, "status CTIO complete");
 1175                 } else {
 1176                         /*
 1177                          * Final CTIO completed. Release DMA resources and
 1178                          * notify platform dependent layers.
 1179                          */
 1180                         isp_prt(isp, pl, "data CTIO complete");
 1181                 }
 1182                 (void) isp_async(isp, ISPASYNC_TARGET_ACTION, ct);
 1183                 /*
 1184                  * The platform layer will destroy the handle if appropriate.
 1185                  */
 1186         }
 1187 }
 1188 #endif

/* [<][>][^][v][top][bottom][index][help] */