root/dev/ic/isp_openbsd.c

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

DEFINITIONS

This source file includes following definitions.
  1. isp_attach
  2. ispminphys
  3. ispcmd_slow
  4. isp_add2_blocked_queue
  5. ispcmd
  6. isp_polled_cmd
  7. isp_done
  8. isp_wdog
  9. isp_uninit
  10. isp_requeue
  11. isp_trestart
  12. isp_restart
  13. isp_async
  14. isp_prt

    1 /*      $OpenBSD: isp_openbsd.c,v 1.30 2007/04/10 17:47:55 miod Exp $ */
    2 /*
    3  * Platform (OpenBSD) dependent common attachment code for Qlogic adapters.
    4  *
    5  * Copyright (c) 1999, 2000, 2001 by Matthew Jacob
    6  * All rights reserved.
    7  *
    8  * Redistribution and use in source and binary forms, with or without
    9  * modification, are permitted provided that the following conditions
   10  * are met:
   11  * 1. Redistributions of source code must retain the above copyright
   12  *    notice immediately at the beginning of the file, without modification,
   13  *    this list of conditions, and the following disclaimer.
   14  *    documentation and/or other materials provided with the distribution.
   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  * The author may be reached via electronic communications at
   31  *
   32  *  mjacob@feral.com
   33  *
   34  * or, via United States Postal Address
   35  *
   36  *  Matthew Jacob
   37  *  Feral Software
   38  *  PMB#825
   39  *  5214-F Diamond Heights Blvd.
   40  *  San Francisco, CA, 94131
   41  */
   42 
   43 /* expand expensive inline functions here. */
   44 #define EXPENSIVE_INLINE
   45 #include <dev/ic/isp_openbsd.h>
   46 
   47 /*
   48  * Set a timeout for the watchdogging of a command.
   49  *
   50  * The dimensional analysis is
   51  *
   52  *      milliseconds * (seconds/millisecond) * (ticks/second) = ticks
   53  *
   54  *                      =
   55  *
   56  *      (milliseconds / 1000) * hz = ticks
   57  *
   58  *
   59  * For timeouts less than 1 second, we'll get zero. Because of this, and
   60  * because we want to establish *our* timeout to be longer than what the
   61  * firmware might do, we just add 3 seconds at the back end.
   62  */
   63 #define _XT(xs) ((((xs)->timeout/1000) * hz) + (3 * hz))
   64 
   65 static void ispminphys(struct buf *);
   66 static int32_t ispcmd_slow(XS_T *);
   67 static int32_t ispcmd(XS_T *);
   68 
   69 static struct scsi_device isp_dev = { NULL, NULL, NULL, NULL };
   70 
   71 static int isp_polled_cmd (struct ispsoftc *, XS_T *);
   72 static void isp_wdog (void *);
   73 static void isp_requeue(void *);
   74 static void isp_trestart(void *);
   75 static void isp_restart(struct ispsoftc *);
   76 
   77 struct cfdriver isp_cd = {
   78         NULL, "isp", DV_DULL
   79 };
   80 
   81 
   82 /*
   83  * Complete attachment of hardware, include subdevices.
   84  */
   85 void
   86 isp_attach(struct ispsoftc *isp)
   87 {
   88         struct scsibus_attach_args saa;
   89         struct scsi_link *lptr = &isp->isp_osinfo._link[0];
   90         isp->isp_osinfo._adapter.scsi_minphys = ispminphys;
   91 
   92         isp->isp_state = ISP_RUNSTATE;
   93 
   94         /*
   95          * We only manage a single wait queues for dual bus controllers.
   96          * This is arguably broken.
   97          */
   98         isp->isp_osinfo.wqf = isp->isp_osinfo.wqt = NULL;
   99 
  100         lptr->adapter_softc = isp;
  101         lptr->device = &isp_dev;
  102         lptr->adapter = &isp->isp_osinfo._adapter;
  103         lptr->openings = imin(isp->isp_maxcmds, MAXISPREQUEST(isp));
  104         isp->isp_osinfo._adapter.scsi_cmd = ispcmd_slow;
  105         if (IS_FC(isp)) {
  106                 lptr->adapter_buswidth = MAX_FC_TARG;
  107                 /* We can set max lun width here */
  108                 /* loopid set below */
  109         } else {
  110                 sdparam *sdp = isp->isp_param;
  111                 lptr->adapter_buswidth = MAX_TARGETS;
  112                 /* We can set max lun width here */
  113                 lptr->adapter_target = sdp->isp_initiator_id;
  114                 isp->isp_osinfo.discovered[0] = 1 << sdp->isp_initiator_id;
  115                 if (IS_DUALBUS(isp)) {
  116                         struct scsi_link *lptrb = &isp->isp_osinfo._link[1];
  117                         lptrb->adapter_softc = isp;
  118                         lptrb->device = &isp_dev;
  119                         lptrb->adapter = &isp->isp_osinfo._adapter;
  120                         lptrb->openings = lptr->openings;
  121                         lptrb->adapter_buswidth = MAX_TARGETS;
  122                         lptrb->adapter_target = sdp->isp_initiator_id;
  123                         lptrb->flags = SDEV_2NDBUS;
  124                         isp->isp_osinfo.discovered[1] =
  125                             1 << (sdp+1)->isp_initiator_id;
  126                 }
  127         }
  128 
  129         /*
  130          * Send a SCSI Bus Reset (used to be done as part of attach,
  131          * but now left to the OS outer layers).
  132          *
  133          * We don't do 'bus resets' for FC because the LIP that occurs
  134          * when we start the firmware does all that for us.
  135          */
  136         if (IS_SCSI(isp)) {
  137                 int bus = 0;
  138                 ISP_LOCK(isp);
  139                 (void) isp_control(isp, ISPCTL_RESET_BUS, &bus);
  140                 if (IS_DUALBUS(isp)) {
  141                         bus++;
  142                         (void) isp_control(isp, ISPCTL_RESET_BUS, &bus);
  143                 }
  144                 ISP_UNLOCK(isp);
  145                 /*
  146                  * wait for the bus to settle.
  147                  */
  148                 delay(4 * 1000000);
  149         } else {
  150                 fcparam *fcp = isp->isp_param;
  151                 int defid = MAX_FC_TARG;
  152                 delay(2 * 1000000);
  153                 ISP_LOCK(isp);
  154                 isp_fc_runstate(isp, 10 * 1000000);
  155                 if (fcp->isp_fwstate == FW_READY &&
  156                     fcp->isp_loopstate >= LOOP_PDB_RCVD) {
  157                         defid = fcp->isp_loopid;
  158                 }
  159                 ISP_UNLOCK(isp);
  160                 lptr->adapter_target = defid;
  161         }
  162 
  163         bzero(&saa, sizeof(saa));
  164         saa.saa_sc_link = lptr;
  165 
  166         /*
  167          * And attach children (if any).
  168          */
  169         config_found((void *)isp, &saa, scsiprint);
  170         if (IS_DUALBUS(isp)) {
  171                 lptr++;
  172                 bzero(&saa, sizeof(saa));
  173                 saa.saa_sc_link = lptr;
  174                 config_found((void *)isp, &saa, scsiprint);
  175         }
  176 }
  177 
  178 /*
  179  * minphys our xfers
  180  *
  181  * Unfortunately, the buffer pointer describes the target device- not the
  182  * adapter device, so we can't use the pointer to find out what kind of
  183  * adapter we are and adjust accordingly.
  184  */
  185 
  186 static void
  187 ispminphys(struct buf *bp)
  188 {
  189         /*
  190          * XX: Only the 1020 has a 24 bit limit.
  191          */
  192         if (bp->b_bcount >= (1 << 24)) {
  193                 bp->b_bcount = (1 << 24);
  194         }
  195         minphys(bp);
  196 }
  197 
  198 static int32_t
  199 ispcmd_slow(XS_T *xs)
  200 {
  201         sdparam *sdp;
  202         int tgt, chan;
  203         u_int16_t f;
  204         struct ispsoftc *isp = XS_ISP(xs);
  205 
  206         if (IS_FC(isp)) {
  207                 if (cold == 0) {
  208                         isp->isp_osinfo.no_mbox_ints = 0;
  209                         isp->isp_osinfo._adapter.scsi_cmd = ispcmd;
  210                 }
  211                 return (ispcmd(xs));
  212         }
  213 
  214         /*
  215          * Have we completed discovery for this target on this adapter?
  216          */
  217         sdp = isp->isp_param;
  218         tgt = XS_TGT(xs);
  219         chan = XS_CHANNEL(xs);
  220         sdp += chan;
  221         if ((xs->flags & SCSI_POLL) != 0 ||
  222             (isp->isp_osinfo.discovered[chan] & (1 << tgt)) != 0) {
  223                 return (ispcmd(xs));
  224         }
  225         if (cold == 0) {
  226                 isp->isp_osinfo.no_mbox_ints = 0;
  227         }
  228 
  229         f = DPARM_DEFAULT;
  230         if (xs->sc_link->quirks & SDEV_NOSYNC) {
  231                 f &= ~DPARM_SYNC;
  232         }
  233         if (xs->sc_link->quirks & SDEV_NOWIDE) {
  234                 f &= ~DPARM_WIDE;
  235         }
  236         if (xs->sc_link->quirks & SDEV_NOTAGS) {
  237                 f &= ~DPARM_TQING;
  238         }
  239 
  240         /*
  241          * Okay, we know about this device now,
  242          * so mark parameters to be updated for it.
  243          */
  244         sdp->isp_devparam[tgt].goal_flags = f;
  245         sdp->isp_devparam[tgt].dev_update = 1;
  246         isp->isp_update |= (1 << chan);
  247 
  248         /*
  249          * Now check to see whether we can get out of this checking mode now.
  250          * XXX: WE CANNOT AS YET BECAUSE THERE IS NO MECHANISM TO TELL US
  251          * XXX: WHEN WE'RE DONE DISCOVERY BECAUSE WE NEED ONE COMMAND AFTER
  252          * XXX: DISCOVERY IS DONE FOR EACH TARGET TO TELL US THAT WE'RE DONE
  253          * XXX: AND THAT DOESN'T HAPPEN HERE. AT BEST WE CAN MARK OURSELVES
  254          * XXX: DONE WITH DISCOVERY FOR THIS TARGET AND SO SAVE MAYBE 20
  255          * XXX: LINES OF C CODE.
  256          */
  257         isp->isp_osinfo.discovered[chan] |= (1 << tgt);
  258         /* do not bother with these lines- they'll never execute correctly */
  259 #if     0
  260         sdp = isp->isp_param;
  261         for (chan = 0; chan < (IS_12X0(isp)? 2 : 1); chan++, sdp++) {
  262                 f = 0xffff & ~(1 << sdp->isp_initiator_id);
  263                 if (isp->isp_osinfo.discovered[chan] != f) {
  264                         break;
  265                 }
  266         }
  267         if (chan == (IS_12X0(isp)? 2 : 1)) {
  268                 isp->isp_osinfo._adapter.scsipi_cmd = ispcmd;
  269                 if (IS_12X0(isp))
  270                         isp->isp_update |= 2;
  271         }
  272 #endif
  273         return (ispcmd(xs));
  274 }
  275 
  276 static INLINE void isp_add2_blocked_queue(struct ispsoftc *, XS_T *);
  277 
  278 static INLINE void
  279 isp_add2_blocked_queue(struct ispsoftc *isp, XS_T *xs)
  280 {
  281         if (isp->isp_osinfo.wqf != NULL) {
  282                 isp->isp_osinfo.wqt->free_list.le_next = xs;
  283         } else {
  284                 isp->isp_osinfo.wqf = xs;
  285         }
  286         isp->isp_osinfo.wqt = xs;
  287         xs->free_list.le_next = NULL;
  288 }
  289 
  290 static int32_t
  291 ispcmd(XS_T *xs)
  292 {
  293         struct ispsoftc *isp;
  294         int result;
  295 
  296 
  297         /*
  298          * Make sure that there's *some* kind of sane setting.
  299          */
  300         isp = XS_ISP(xs);
  301 
  302         timeout_set(&xs->stimeout, isp_wdog, isp);
  303 
  304         if (XS_LUN(xs) >= isp->isp_maxluns) {
  305                 xs->error = XS_SELTIMEOUT;
  306                 return (COMPLETE);
  307         }
  308 
  309         ISP_LOCK(isp);
  310         if (isp->isp_state < ISP_RUNSTATE) {
  311                 DISABLE_INTS(isp);
  312                 isp_init(isp);
  313                 if (isp->isp_state != ISP_INITSTATE) {
  314                         ENABLE_INTS(isp);
  315                         ISP_UNLOCK(isp);
  316                         XS_SETERR(xs, HBA_BOTCH);
  317                         return (CMD_COMPLETE);
  318                 }
  319                 isp->isp_state = ISP_RUNSTATE;
  320                 ENABLE_INTS(isp);
  321         }
  322 
  323         /*
  324          * Check for queue blockage...
  325          */
  326         if (isp->isp_osinfo.blocked) {
  327                 if (xs->flags & SCSI_POLL) {
  328                         ISP_UNLOCK(isp);
  329                         return (TRY_AGAIN_LATER);
  330                 }
  331                 if (isp->isp_osinfo.blocked == 2) {
  332                         isp_restart(isp);
  333                 }
  334                 if (isp->isp_osinfo.blocked) {
  335                         isp_add2_blocked_queue(isp, xs);
  336                         ISP_UNLOCK(isp);
  337                         isp_prt(isp, ISP_LOGDEBUG0, "added to blocked queue");
  338                         return (SUCCESSFULLY_QUEUED);
  339                 }
  340         }
  341 
  342         if (xs->flags & SCSI_POLL) {
  343                 volatile u_int8_t ombi = isp->isp_osinfo.no_mbox_ints;
  344                 isp->isp_osinfo.no_mbox_ints = 1;
  345                 result = isp_polled_cmd(isp, xs);
  346                 isp->isp_osinfo.no_mbox_ints = ombi;
  347                 ISP_UNLOCK(isp);
  348                 return (result);
  349         }
  350 
  351         result = isp_start(xs);
  352 
  353         switch (result) {
  354         case CMD_QUEUED:
  355                 result = SUCCESSFULLY_QUEUED;
  356                 if (xs->timeout) {
  357                         timeout_add(&xs->stimeout, _XT(xs));
  358                         XS_CMD_S_TIMER(xs);
  359                 }
  360                 if (isp->isp_osinfo.hiwater < isp->isp_nactive) {
  361                         isp->isp_osinfo.hiwater = isp->isp_nactive;
  362                         isp_prt(isp, ISP_LOGDEBUG0,
  363                             "Active Hiwater Mark=%d", isp->isp_nactive);
  364                 }
  365                 break;
  366         case CMD_EAGAIN:
  367                 isp->isp_osinfo.blocked |= 2;
  368                 isp_prt(isp, ISP_LOGDEBUG0, "blocking queue");
  369                 isp_add2_blocked_queue(isp, xs);
  370                 result = SUCCESSFULLY_QUEUED;
  371                 break;
  372         case CMD_RQLATER:
  373                 result = SUCCESSFULLY_QUEUED;   /* Lie */
  374                 isp_prt(isp, ISP_LOGDEBUG1, "retrying later for %d.%d",
  375                     XS_TGT(xs), XS_LUN(xs));
  376                 timeout_set(&xs->stimeout, isp_requeue, xs);
  377                 timeout_add(&xs->stimeout, hz);
  378                 XS_CMD_S_TIMER(xs);
  379                 break;
  380         case CMD_COMPLETE:
  381                 result = COMPLETE;
  382                 break;
  383         }
  384         ISP_UNLOCK(isp);
  385         return (result);
  386 }
  387 
  388 static int
  389 isp_polled_cmd(struct ispsoftc *isp, XS_T *xs)
  390 {
  391         int result;
  392         int infinite = 0, mswait;
  393 
  394         result = isp_start(xs);
  395 
  396         switch (result) {
  397         case CMD_QUEUED:
  398                 result = SUCCESSFULLY_QUEUED;
  399                 break;
  400         case CMD_RQLATER:
  401         case CMD_EAGAIN:
  402                 result = TRY_AGAIN_LATER;
  403                 break;
  404         case CMD_COMPLETE:
  405                 result = COMPLETE;
  406                 break;
  407                 
  408         }
  409 
  410         if (result != SUCCESSFULLY_QUEUED) {
  411                 return (result);
  412         }
  413 
  414         /*
  415          * If we can't use interrupts, poll on completion.
  416          */
  417         if ((mswait = XS_TIME(xs)) == 0)
  418                 infinite = 1;
  419 
  420         while (mswait || infinite) {
  421                 u_int16_t isr, sema, mbox;
  422                 if (ISP_READ_ISR(isp, &isr, &sema, &mbox)) {
  423                         isp_intr(isp, isr, sema, mbox);
  424                         if (XS_CMD_DONE_P(xs)) {
  425                                 break;
  426                         }
  427                 }
  428                 USEC_DELAY(1000);
  429                 mswait -= 1;
  430         }
  431 
  432         /*
  433          * If no other error occurred but we didn't finish,
  434          * something bad happened.
  435          */
  436         if (XS_CMD_DONE_P(xs) == 0) {
  437                 if (isp_control(isp, ISPCTL_ABORT_CMD, xs)) {
  438                         isp_reinit(isp);
  439                 }
  440                 if (XS_NOERR(xs)) {
  441                         XS_SETERR(xs, HBA_BOTCH);
  442                 }
  443         }
  444         result = COMPLETE;
  445         return (result);
  446 }
  447 
  448 void
  449 isp_done(XS_T *xs)
  450 {
  451         XS_CMD_S_DONE(xs);
  452         if (XS_CMD_WDOG_P(xs) == 0) {
  453                 struct ispsoftc *isp = XS_ISP(xs);
  454                 if (XS_CMD_TIMER_P(xs)) {
  455                         timeout_del(&xs->stimeout);
  456                         XS_CMD_C_TIMER(xs);
  457                 }
  458                 if (XS_CMD_GRACE_P(xs)) {
  459                         struct ispsoftc *isp = XS_ISP(xs);
  460                         isp_prt(isp, ISP_LOGWARN,
  461                             "finished command on borrowed time");
  462                 }
  463                 XS_CMD_S_CLEAR(xs);
  464                 scsi_done(xs);
  465                 if (isp->isp_osinfo.blocked == 2) {
  466                         isp->isp_osinfo.blocked = 0;
  467                         isp_prt(isp, ISP_LOGDEBUG0, "restarting blocked queue");
  468                         isp_restart(isp);
  469                 }
  470         }
  471 }
  472 
  473 static void
  474 isp_wdog(void *arg)
  475 {
  476         XS_T *xs = arg;
  477         struct ispsoftc *isp = XS_ISP(xs);
  478         u_int32_t handle;
  479 
  480         /*
  481          * We've decided this command is dead. Make sure we're not trying
  482          * to kill a command that's already dead by getting its handle and
  483          * and seeing whether it's still alive.
  484          */
  485         ISP_LOCK(isp);
  486         handle = isp_find_handle(isp, xs);
  487         if (handle) {
  488                 u_int16_t isr, sema, mbox;
  489 
  490                 if (XS_CMD_DONE_P(xs)) {
  491                         isp_prt(isp, ISP_LOGDEBUG1,
  492                             "watchdog found done cmd (handle 0x%x)",
  493                             handle);
  494                         ISP_UNLOCK(isp);
  495                         return;
  496                 }
  497 
  498                 if (XS_CMD_WDOG_P(xs)) {
  499                         isp_prt(isp, ISP_LOGDEBUG1,
  500                             "recursive watchdog (handle 0x%x)",
  501                             handle);
  502                         ISP_UNLOCK(isp);
  503                         return;
  504                 }
  505 
  506                 XS_CMD_S_WDOG(xs);
  507 
  508                 if (ISP_READ_ISR(isp, &isr, &sema, &mbox)) {
  509                         isp_intr(isp, isr, sema, mbox);
  510                 }
  511 
  512                 if (XS_CMD_DONE_P(xs)) {
  513                         isp_prt(isp, ISP_LOGINFO,
  514                             "watchdog cleanup for handle 0x%x", handle);
  515                         XS_CMD_C_WDOG(xs);
  516                         isp_done(xs);
  517                 } else if (XS_CMD_GRACE_P(xs)) {
  518                         /*
  519                          * Make sure the command is *really* dead before we
  520                          * release the handle (and DMA resources) for reuse.
  521                          */
  522                         (void) isp_control(isp, ISPCTL_ABORT_CMD, arg);
  523 
  524                         /*
  525                          * After this point, the command is really dead.
  526                          */
  527                         if (XS_XFRLEN(xs)) {
  528                                 ISP_DMAFREE(isp, xs, handle);
  529                         }
  530                         isp_prt(isp, ISP_LOGWARN,
  531                             "watchdog timeout on handle %x", handle);
  532                         isp_destroy_handle(isp, handle);
  533                         XS_SETERR(xs, XS_TIMEOUT);
  534                         XS_CMD_S_CLEAR(xs);
  535                         isp_done(xs);
  536                 } else {
  537                         u_int16_t nxti, optr;
  538                         ispreq_t local, *mp = &local, *qe;
  539 
  540                         isp_prt(isp, ISP_LOGWARN,
  541                             "possible command timeout on handle %x", handle);
  542 
  543                         XS_CMD_C_WDOG(xs);
  544                         timeout_add(&xs->stimeout, _XT(xs));
  545                         XS_CMD_S_TIMER(xs);
  546                         if (isp_getrqentry(isp, &nxti, &optr, (void **) &qe)) {
  547                                 ISP_UNLOCK(isp);
  548                                 return;
  549                         }
  550                         XS_CMD_S_GRACE(xs);
  551                         MEMZERO((void *) mp, sizeof (*mp));
  552                         mp->req_header.rqs_entry_count = 1;
  553                         mp->req_header.rqs_entry_type = RQSTYPE_MARKER;
  554                         mp->req_modifier = SYNC_ALL;
  555                         mp->req_target = XS_CHANNEL(xs) << 7;
  556                         isp_put_request(isp, mp, qe);
  557                         ISP_ADD_REQUEST(isp, nxti);
  558                 }
  559         } else if (isp->isp_dblev) {
  560                 isp_prt(isp, ISP_LOGDEBUG1, "watchdog with no command");
  561         }
  562         ISP_UNLOCK(isp);
  563 }
  564 
  565 /*
  566  * Free any associated resources prior to decommissioning and
  567  * set the card to a known state (so it doesn't wake up and kick
  568  * us when we aren't expecting it to).
  569  *
  570  * Locks are held before coming here.
  571  */
  572 void
  573 isp_uninit(struct ispsoftc *isp)
  574 {
  575         ISP_LOCK(isp);
  576         /*
  577          * Leave with interrupts disabled.
  578          */
  579         DISABLE_INTS(isp);
  580 
  581         ISP_UNLOCK(isp);
  582 }
  583 
  584 /*
  585  * Restart function for a command to be requeued later.
  586  */
  587 static void
  588 isp_requeue(void *arg)
  589 {
  590         int r;
  591         struct scsi_xfer *xs = arg;
  592         struct ispsoftc *isp = XS_ISP(xs);
  593         ISP_LOCK(isp);
  594         r = isp_start(xs);
  595         switch (r) {
  596         case CMD_QUEUED:
  597                 isp_prt(isp, ISP_LOGDEBUG1, "restarted command for %d.%d",
  598                     XS_TGT(xs), XS_LUN(xs));
  599                 if (xs->timeout) {
  600                         timeout_set(&xs->stimeout, isp_wdog, isp);
  601                         timeout_add(&xs->stimeout, _XT(xs));
  602                         XS_CMD_S_TIMER(xs);
  603                 }
  604                 break;
  605         case CMD_EAGAIN:
  606                 isp_prt(isp, ISP_LOGDEBUG0, "blocked cmd again");
  607                 isp->isp_osinfo.blocked |= 2;
  608                 isp_add2_blocked_queue(isp, xs);
  609                 break;
  610         case CMD_RQLATER:
  611                 isp_prt(isp, ISP_LOGDEBUG0, "%s for %d.%d",
  612                     (r == CMD_EAGAIN)? "CMD_EAGAIN" : "CMD_RQLATER",
  613                     XS_TGT(xs), XS_LUN(xs));
  614                 timeout_set(&xs->stimeout, isp_requeue, xs);
  615                 timeout_add(&xs->stimeout, hz);
  616                 XS_CMD_S_TIMER(xs);
  617                 break;
  618         case CMD_COMPLETE:
  619                 /* can only be an error */
  620                 if (XS_NOERR(xs))
  621                         XS_SETERR(xs, XS_DRIVER_STUFFUP);
  622                 isp_done(xs);
  623                 break;
  624         }
  625         ISP_UNLOCK(isp);
  626 }
  627 
  628 /*
  629  * Restart function after a LOOP UP event or a command completing,
  630  * sometimes done as a timeout for some hysteresis.
  631  */
  632 static void
  633 isp_trestart(void *arg)
  634 {
  635         struct ispsoftc *isp = arg;
  636         struct scsi_xfer *list;
  637 
  638         ISP_LOCK(isp);
  639         isp->isp_osinfo.rtpend = 0;
  640         list = isp->isp_osinfo.wqf;
  641         if (isp->isp_osinfo.blocked == 0 && list != NULL) {
  642                 int nrestarted = 0;
  643 
  644                 isp->isp_osinfo.wqf = NULL;
  645                 ISP_UNLOCK(isp);
  646                 do {
  647                         struct scsi_xfer *xs = list;
  648                         list = xs->free_list.le_next;
  649                         xs->free_list.le_next = NULL;
  650                         isp_requeue(xs);
  651                         if (isp->isp_osinfo.wqf == NULL)
  652                                 nrestarted++;
  653                 } while (list != NULL);
  654                 isp_prt(isp, ISP_LOGDEBUG0, "requeued %d commands", nrestarted);
  655         } else {
  656                 ISP_UNLOCK(isp);
  657         }
  658 }
  659 
  660 static void
  661 isp_restart(struct ispsoftc *isp)
  662 {
  663         struct scsi_xfer *list;
  664 
  665         list = isp->isp_osinfo.wqf;
  666         if (isp->isp_osinfo.blocked == 0 && list != NULL) {
  667                 int nrestarted = 0;
  668 
  669                 isp->isp_osinfo.wqf = NULL;
  670                 do {
  671                         struct scsi_xfer *xs = list;
  672                         list = xs->free_list.le_next;
  673                         xs->free_list.le_next = NULL;
  674                         isp_requeue(xs);
  675                         if (isp->isp_osinfo.wqf == NULL)
  676                                 nrestarted++;
  677                 } while (list != NULL);
  678                 isp_prt(isp, ISP_LOGDEBUG0, "requeued %d commands", nrestarted);
  679         }
  680 }
  681 
  682 int
  683 isp_async(struct ispsoftc *isp, ispasync_t cmd, void *arg)
  684 {
  685         int bus, tgt;
  686 
  687         switch (cmd) {
  688         case ISPASYNC_NEW_TGT_PARAMS:
  689         if (IS_SCSI(isp) && isp->isp_dblev) {
  690                 sdparam *sdp = isp->isp_param;
  691                 char *wt;
  692                 int mhz, flags, period;
  693 
  694                 tgt = *((int *) arg);
  695                 bus = (tgt >> 16) & 0xffff;
  696                 tgt &= 0xffff;
  697                 sdp += bus;
  698                 flags = sdp->isp_devparam[tgt].actv_flags;
  699                 period = sdp->isp_devparam[tgt].actv_period;
  700 
  701                 if ((flags & DPARM_SYNC) && period &&
  702                     (sdp->isp_devparam[tgt].actv_offset) != 0) {
  703                         /*
  704                          * There's some ambiguity about our negotiated speed
  705                          * if we haven't detected LVD mode correctly (which
  706                          * seems to happen, unfortunately). If we're in LVD
  707                          * mode, then different rules apply about speed.
  708                          */
  709                         if (sdp->isp_lvdmode || period < 0xc) {
  710                                 switch (period) {
  711                                 case 0x9:
  712                                         mhz = 80;
  713                                         break;
  714                                 case 0xa:
  715                                         mhz = 40;
  716                                         break;
  717                                 case 0xb:
  718                                         mhz = 33;
  719                                         break;
  720                                 case 0xc:
  721                                         mhz = 25;
  722                                         break;
  723                                 default:
  724                                         mhz = 1000 / (period * 4);
  725                                         break;
  726                                 }
  727                         } else {
  728                                 mhz = 1000 / (period * 4);
  729                         }
  730                 } else {
  731                         mhz = 0;
  732                 }
  733                 switch (flags & (DPARM_WIDE|DPARM_TQING)) {
  734                 case DPARM_WIDE:
  735                         wt = ", 16 bit wide";
  736                         break;
  737                 case DPARM_TQING:
  738                         wt = ", Tagged Queueing Enabled";
  739                         break;
  740                 case DPARM_WIDE|DPARM_TQING:
  741                         wt = ", 16 bit wide, Tagged Queueing Enabled";
  742                         break;
  743                 default:
  744                         wt = " ";
  745                         break;
  746                 }
  747                 if (mhz) {
  748                         isp_prt(isp, ISP_LOGINFO,
  749                             "Bus %d Target %d at %dMHz Max Offset %d%s",
  750                             bus, tgt, mhz, sdp->isp_devparam[tgt].actv_offset,
  751                             wt);
  752                 } else {
  753                         isp_prt(isp, ISP_LOGINFO,
  754                             "Bus %d Target %d Async Mode%s", bus, tgt, wt);
  755                 }
  756                 break;
  757         }
  758         case ISPASYNC_BUS_RESET:
  759                 if (arg)
  760                         bus = *((int *) arg);
  761                 else
  762                         bus = 0;
  763                 isp_prt(isp, ISP_LOGINFO, "SCSI bus %d reset detected", bus);
  764                 break;
  765         case ISPASYNC_LOOP_DOWN:
  766                 /*
  767                  * Hopefully we get here in time to minimize the number
  768                  * of commands we are firing off that are sure to die.
  769                  */
  770                 isp->isp_osinfo.blocked |= 1;
  771                 isp_prt(isp, ISP_LOGINFO, "Loop DOWN");
  772                 break;
  773         case ISPASYNC_LOOP_UP:
  774                 isp->isp_osinfo.blocked &= ~1;
  775                 if (isp->isp_osinfo.rtpend == 0) {
  776                         timeout_set(&isp->isp_osinfo.rqt, isp_trestart, isp);
  777                         isp->isp_osinfo.rtpend = 1;
  778                 }
  779                 timeout_add(&isp->isp_osinfo.rqt, 1);
  780                 isp_prt(isp, ISP_LOGINFO, "Loop UP");
  781                 break;
  782         case ISPASYNC_PROMENADE:
  783         if (IS_FC(isp) && isp->isp_dblev) {
  784                 const char *fmt = "Target %d (Loop 0x%x) Port ID 0x%x "
  785                     "role %s %s\n Port WWN 0x%08x%08x\n Node WWN 0x%08x%08x";
  786                 const static char *roles[4] = {
  787                     "No", "Target", "Initiator", "Target/Initiator"
  788                 };
  789                 fcparam *fcp = isp->isp_param;
  790                 int tgt = *((int *) arg);
  791                 struct lportdb *lp = &fcp->portdb[tgt]; 
  792 
  793                 isp_prt(isp, ISP_LOGINFO, fmt, tgt, lp->loopid, lp->portid,
  794                     roles[lp->roles & 0x3],
  795                     (lp->valid)? "Arrived" : "Departed",
  796                     (u_int32_t) (lp->port_wwn >> 32),
  797                     (u_int32_t) (lp->port_wwn & 0xffffffffLL),
  798                     (u_int32_t) (lp->node_wwn >> 32),
  799                     (u_int32_t) (lp->node_wwn & 0xffffffffLL));
  800                 break;
  801         }
  802         case ISPASYNC_CHANGE_NOTIFY:
  803                 if (arg == (void *) 1) {
  804                         isp_prt(isp, ISP_LOGINFO,
  805                             "Name Server Database Changed");
  806                 } else {
  807                         isp_prt(isp, ISP_LOGINFO,
  808                             "Name Server Database Changed");
  809                 }
  810                 break;
  811         case ISPASYNC_FABRIC_DEV:
  812         {
  813                 int target, base, lim;
  814                 fcparam *fcp = isp->isp_param;
  815                 struct lportdb *lp = NULL;
  816                 struct lportdb *clp = (struct lportdb *) arg;
  817                 char *pt;
  818 
  819                 switch (clp->port_type) {
  820                 case 1:
  821                         pt = "   N_Port";
  822                         break;
  823                 case 2:
  824                         pt = "  NL_Port";
  825                         break;
  826                 case 3:
  827                         pt = "F/NL_Port";
  828                         break;
  829                 case 0x7f:
  830                         pt = "  Nx_Port";
  831                         break;
  832                 case 0x81:
  833                         pt = "  F_port";
  834                         break;
  835                 case 0x82:
  836                         pt = "  FL_Port";
  837                         break;
  838                 case 0x84:
  839                         pt = "   E_port";
  840                         break;
  841                 default:
  842                         pt = " ";
  843                         break;
  844                 }
  845 
  846                 isp_prt(isp, ISP_LOGINFO,
  847                     "%s Fabric Device @ PortID 0x%x", pt, clp->portid);
  848 
  849                 /*
  850                  * If we don't have an initiator role we bail.
  851                  *
  852                  * We just use ISPASYNC_FABRIC_DEV for announcement purposes.
  853                  */
  854 
  855                 if ((isp->isp_role & ISP_ROLE_INITIATOR) == 0) {
  856                         break;
  857                 }
  858 
  859                 /*
  860                  * Is this entry for us? If so, we bail.
  861                  */
  862 
  863                 if (fcp->isp_portid == clp->portid) {
  864                         break;
  865                 }
  866 
  867                 /*
  868                  * Else, the default policy is to find room for it in
  869                  * our local port database. Later, when we execute
  870                  * the call to isp_pdb_sync either this newly arrived
  871                  * or already logged in device will be (re)announced.
  872                  */
  873 
  874                 if (fcp->isp_topo == TOPO_FL_PORT)
  875                         base = FC_SNS_ID+1;
  876                 else
  877                         base = 0;
  878 
  879                 if (fcp->isp_topo == TOPO_N_PORT)
  880                         lim = 1;
  881                 else
  882                         lim = MAX_FC_TARG;
  883 
  884                 /*
  885                  * Is it already in our list?
  886                  */
  887                 for (target = base; target < lim; target++) {
  888                         if (target >= FL_PORT_ID && target <= FC_SNS_ID) {
  889                                 continue;
  890                         }
  891                         lp = &fcp->portdb[target];
  892                         if (lp->port_wwn == clp->port_wwn &&
  893                             lp->node_wwn == clp->node_wwn) {
  894                                 lp->fabric_dev = 1;
  895                                 break;
  896                         }
  897                 }
  898                 if (target < lim) {
  899                         break;
  900                 }
  901                 for (target = base; target < lim; target++) {
  902                         if (target >= FL_PORT_ID && target <= FC_SNS_ID) {
  903                                 continue;
  904                         }
  905                         lp = &fcp->portdb[target];
  906                         if (lp->port_wwn == 0) {
  907                                 break;
  908                         }
  909                 }
  910                 if (target == lim) {
  911                         isp_prt(isp, ISP_LOGWARN,
  912                             "out of space for fabric devices");
  913                         break;
  914                 }
  915                 lp->port_type = clp->port_type;
  916                 lp->fc4_type = clp->fc4_type;
  917                 lp->node_wwn = clp->node_wwn;
  918                 lp->port_wwn = clp->port_wwn;
  919                 lp->portid = clp->portid;
  920                 lp->fabric_dev = 1;
  921                 break;
  922         }
  923         case ISPASYNC_FW_CRASH:
  924         {
  925                 u_int16_t mbox1, mbox6;
  926                 mbox1 = ISP_READ(isp, OUTMAILBOX1);
  927                 if (IS_DUALBUS(isp)) { 
  928                         mbox6 = ISP_READ(isp, OUTMAILBOX6);
  929                 } else {
  930                         mbox6 = 0;
  931                 }
  932                 isp_prt(isp, ISP_LOGERR,
  933                     "Internal Firmware Error on bus %d @ RISC Address 0x%x",
  934                     mbox6, mbox1);
  935 #ifdef  ISP_FW_CRASH_DUMP
  936                 if (IS_FC(isp)) {
  937                         isp->isp_osinfo.blocked |= 1;
  938                         isp_fw_dump(isp);
  939                 }
  940                 isp_reinit(isp);
  941                 isp_async(isp, ISPASYNC_FW_RESTART, NULL);
  942 #endif
  943                 break;
  944         }
  945         default:
  946                 break;
  947         }
  948         return (0);
  949 }
  950 
  951 void
  952 isp_prt(struct ispsoftc *isp, int level, const char *fmt, ...)
  953 {
  954         va_list ap;
  955         if (level != ISP_LOGALL && (level & isp->isp_dblev) == 0) {
  956                 return;
  957         }
  958         printf("%s: ", isp->isp_name);
  959         va_start(ap, fmt);
  960         vprintf(fmt, ap);
  961         va_end(ap);
  962         printf("\n");
  963 }

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