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


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

FreeBSD/Linux Kernel Cross Reference
sys/dev/ic/bha.c

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

    1 /*      $NetBSD: bha.c,v 1.67 2006/08/17 17:11:28 christos Exp $        */
    2 
    3 /*-
    4  * Copyright (c) 1997, 1998, 1999 The NetBSD Foundation, Inc.
    5  * All rights reserved.
    6  *
    7  * This code is derived from software contributed to The NetBSD Foundation
    8  * by Charles M. Hannum and by Jason R. Thorpe of the Numerical Aerospace
    9  * Simulation Facility, NASA Ames Research Center.
   10  *
   11  * Redistribution and use in source and binary forms, with or without
   12  * modification, are permitted provided that the following conditions
   13  * are met:
   14  * 1. Redistributions of source code must retain the above copyright
   15  *    notice, this list of conditions and the following disclaimer.
   16  * 2. Redistributions in binary form must reproduce the above copyright
   17  *    notice, this list of conditions and the following disclaimer in the
   18  *    documentation and/or other materials provided with the distribution.
   19  * 3. All advertising materials mentioning features or use of this software
   20  *    must display the following acknowledgement:
   21  *      This product includes software developed by the NetBSD
   22  *      Foundation, Inc. and its contributors.
   23  * 4. Neither the name of The NetBSD Foundation nor the names of its
   24  *    contributors may be used to endorse or promote products derived
   25  *    from this software without specific prior written permission.
   26  *
   27  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
   28  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
   29  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   30  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
   31  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   32  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   33  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   34  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   35  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   36  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   37  * POSSIBILITY OF SUCH DAMAGE.
   38  */
   39 
   40 /*
   41  * Originally written by Julian Elischer (julian@tfs.com)
   42  * for TRW Financial Systems for use under the MACH(2.5) operating system.
   43  *
   44  * TRW Financial Systems, in accordance with their agreement with Carnegie
   45  * Mellon University, makes this software available to CMU to distribute
   46  * or use in any manner that they see fit as long as this message is kept with
   47  * the software. For this reason TFS also grants any other persons or
   48  * organisations permission to use or modify this software.
   49  *
   50  * TFS supplies this software to be publicly redistributed
   51  * on the understanding that TFS is not responsible for the correct
   52  * functioning of this software in any circumstances.
   53  */
   54 
   55 #include <sys/cdefs.h>
   56 __KERNEL_RCSID(0, "$NetBSD: bha.c,v 1.67 2006/08/17 17:11:28 christos Exp $");
   57 
   58 #include "opt_ddb.h"
   59 
   60 #include <sys/param.h>
   61 #include <sys/systm.h>
   62 #include <sys/callout.h>
   63 #include <sys/kernel.h>
   64 #include <sys/errno.h>
   65 #include <sys/ioctl.h>
   66 #include <sys/device.h>
   67 #include <sys/malloc.h>
   68 #include <sys/buf.h>
   69 #include <sys/proc.h>
   70 #include <sys/user.h>
   71 
   72 #include <uvm/uvm_extern.h>
   73 
   74 #include <machine/bus.h>
   75 #include <machine/intr.h>
   76 
   77 #include <dev/scsipi/scsi_all.h>
   78 #include <dev/scsipi/scsipi_all.h>
   79 #include <dev/scsipi/scsiconf.h>
   80 
   81 #include <dev/ic/bhareg.h>
   82 #include <dev/ic/bhavar.h>
   83 
   84 #ifndef DDB
   85 #define Debugger() panic("should call debugger here (bha.c)")
   86 #endif /* ! DDB */
   87 
   88 #define BHA_MAXXFER     ((BHA_NSEG - 1) << PGSHIFT)
   89 
   90 #ifdef BHADEBUG
   91 int     bha_debug = 0;
   92 #endif /* BHADEBUG */
   93 
   94 static int      bha_cmd(bus_space_tag_t, bus_space_handle_t, const char *, int,
   95                         u_char *, int, u_char *);
   96 
   97 static void     bha_scsipi_request(struct scsipi_channel *,
   98                                    scsipi_adapter_req_t, void *);
   99 static void     bha_minphys(struct buf *);
  100 
  101 static void     bha_get_xfer_mode(struct bha_softc *,
  102                                   struct scsipi_xfer_mode *);
  103 
  104 static void     bha_done(struct bha_softc *, struct bha_ccb *);
  105 static int      bha_poll(struct bha_softc *, struct scsipi_xfer *, int);
  106 static void     bha_timeout(void *arg);
  107 
  108 static int      bha_init(struct bha_softc *);
  109 
  110 static int      bha_create_mailbox(struct bha_softc *);
  111 static void     bha_collect_mbo(struct bha_softc *);
  112 
  113 static void     bha_queue_ccb(struct bha_softc *, struct bha_ccb *);
  114 static void     bha_start_ccbs(struct bha_softc *);
  115 static void     bha_finish_ccbs(struct bha_softc *);
  116 
  117 static struct bha_ccb *bha_ccb_phys_kv(struct bha_softc *, bus_addr_t);
  118 static void     bha_create_ccbs(struct bha_softc *, int);
  119 static int      bha_init_ccb(struct bha_softc *, struct bha_ccb *);
  120 static struct bha_ccb *bha_get_ccb(struct bha_softc *);
  121 static void     bha_free_ccb(struct bha_softc *, struct bha_ccb *);
  122 
  123 #define BHA_RESET_TIMEOUT       2000    /* time to wait for reset (mSec) */
  124 #define BHA_ABORT_TIMEOUT       2000    /* time to wait for abort (mSec) */
  125 
  126 /*
  127  * Number of CCBs in an allocation group; must be computed at run-time.
  128  */
  129 static int      bha_ccbs_per_group;
  130 
  131 static inline struct bha_mbx_out *
  132 bha_nextmbo(struct bha_softc *sc, struct bha_mbx_out *mbo)
  133 {
  134 
  135         if (mbo == &sc->sc_mbo[sc->sc_mbox_count - 1])
  136                 return (&sc->sc_mbo[0]);
  137         return (mbo + 1);
  138 }
  139 
  140 static inline struct bha_mbx_in *
  141 bha_nextmbi(struct bha_softc *sc, struct bha_mbx_in *mbi)
  142 {
  143         if (mbi == &sc->sc_mbi[sc->sc_mbox_count - 1])
  144                 return (&sc->sc_mbi[0]);
  145         return (mbi + 1);
  146 }
  147 
  148 /*
  149  * bha_attach:
  150  *
  151  *      Finish attaching a Buslogic controller, and configure children.
  152  */
  153 void
  154 bha_attach(struct bha_softc *sc)
  155 {
  156         struct scsipi_adapter *adapt = &sc->sc_adapter;
  157         struct scsipi_channel *chan = &sc->sc_channel;
  158         int initial_ccbs;
  159 
  160         /*
  161          * Initialize the number of CCBs per group.
  162          */
  163         if (bha_ccbs_per_group == 0)
  164                 bha_ccbs_per_group = BHA_CCBS_PER_GROUP;
  165 
  166         initial_ccbs = bha_info(sc);
  167         if (initial_ccbs == 0) {
  168                 aprint_error("%s: unable to get adapter info\n",
  169                     sc->sc_dev.dv_xname);
  170                 return;
  171         }
  172 
  173         /*
  174          * Fill in the scsipi_adapter.
  175          */
  176         memset(adapt, 0, sizeof(*adapt));
  177         adapt->adapt_dev = &sc->sc_dev;
  178         adapt->adapt_nchannels = 1;
  179         /* adapt_openings initialized below */
  180         adapt->adapt_max_periph = sc->sc_mbox_count;
  181         adapt->adapt_request = bha_scsipi_request;
  182         adapt->adapt_minphys = bha_minphys;
  183 
  184         /*
  185          * Fill in the scsipi_channel.
  186          */
  187         memset(chan, 0, sizeof(*chan));
  188         chan->chan_adapter = adapt;
  189         chan->chan_bustype = &scsi_bustype;
  190         chan->chan_channel = 0;
  191         chan->chan_flags = SCSIPI_CHAN_CANGROW;
  192         chan->chan_ntargets = (sc->sc_flags & BHAF_WIDE) ? 16 : 8;
  193         chan->chan_nluns = (sc->sc_flags & BHAF_WIDE_LUN) ? 32 : 8;
  194         chan->chan_id = sc->sc_scsi_id;
  195 
  196         TAILQ_INIT(&sc->sc_free_ccb);
  197         TAILQ_INIT(&sc->sc_waiting_ccb);
  198         TAILQ_INIT(&sc->sc_allocating_ccbs);
  199 
  200         if (bha_create_mailbox(sc) != 0)
  201                 return;
  202 
  203         bha_create_ccbs(sc, initial_ccbs);
  204         if (sc->sc_cur_ccbs < 2) {
  205                 aprint_error("%s: not enough CCBs to run\n",
  206                     sc->sc_dev.dv_xname);
  207                 return;
  208         }
  209 
  210         adapt->adapt_openings = sc->sc_cur_ccbs;
  211 
  212         if (bha_init(sc) != 0)
  213                 return;
  214 
  215         (void) config_found(&sc->sc_dev, &sc->sc_channel, scsiprint);
  216 }
  217 
  218 /*
  219  * bha_intr:
  220  *
  221  *      Interrupt service routine.
  222  */
  223 int
  224 bha_intr(void *arg)
  225 {
  226         struct bha_softc *sc = arg;
  227         bus_space_tag_t iot = sc->sc_iot;
  228         bus_space_handle_t ioh = sc->sc_ioh;
  229         u_char sts;
  230 
  231 #ifdef BHADEBUG
  232         printf("%s: bha_intr ", sc->sc_dev.dv_xname);
  233 #endif /* BHADEBUG */
  234 
  235         /*
  236          * First acknowledge the interrupt, Then if it's not telling about
  237          * a completed operation just return.
  238          */
  239         sts = bus_space_read_1(iot, ioh, BHA_INTR_PORT);
  240         if ((sts & BHA_INTR_ANYINTR) == 0)
  241                 return (0);
  242         bus_space_write_1(iot, ioh, BHA_CTRL_PORT, BHA_CTRL_IRST);
  243 
  244 #ifdef BHADIAG
  245         /* Make sure we clear CCB_SENDING before finishing a CCB. */
  246         bha_collect_mbo(sc);
  247 #endif
  248 
  249         /* Mail box out empty? */
  250         if (sts & BHA_INTR_MBOA) {
  251                 struct bha_toggle toggle;
  252 
  253                 toggle.cmd.opcode = BHA_MBO_INTR_EN;
  254                 toggle.cmd.enable = 0;
  255                 bha_cmd(iot, ioh, sc->sc_dev.dv_xname,
  256                     sizeof(toggle.cmd), (u_char *)&toggle.cmd,
  257                     0, (u_char *)0);
  258                 bha_start_ccbs(sc);
  259         }
  260 
  261         /* Mail box in full? */
  262         if (sts & BHA_INTR_MBIF)
  263                 bha_finish_ccbs(sc);
  264 
  265         return (1);
  266 }
  267 
  268 /*****************************************************************************
  269  * SCSI interface routines
  270  *****************************************************************************/
  271 
  272 /*
  273  * bha_scsipi_request:
  274  *
  275  *      Perform a request for the SCSIPI layer.
  276  */
  277 static void
  278 bha_scsipi_request(struct scsipi_channel *chan, scsipi_adapter_req_t req,
  279     void *arg)
  280 {
  281         struct scsipi_adapter *adapt = chan->chan_adapter;
  282         struct bha_softc *sc = (void *)adapt->adapt_dev;
  283         struct scsipi_xfer *xs;
  284         struct scsipi_periph *periph;
  285         bus_dma_tag_t dmat = sc->sc_dmat;
  286         struct bha_ccb *ccb;
  287         int error, seg, flags, s;
  288 
  289         switch (req) {
  290         case ADAPTER_REQ_RUN_XFER:
  291                 xs = arg;
  292                 periph = xs->xs_periph;
  293                 flags = xs->xs_control;
  294 
  295                 SC_DEBUG(periph, SCSIPI_DB2, ("bha_scsipi_request\n"));
  296 
  297                 /* Get a CCB to use. */
  298                 ccb = bha_get_ccb(sc);
  299 #ifdef DIAGNOSTIC
  300                 /*
  301                  * This should never happen as we track the resources
  302                  * in the mid-layer.
  303                  */
  304                 if (ccb == NULL) {
  305                         scsipi_printaddr(periph);
  306                         printf("unable to allocate ccb\n");
  307                         panic("bha_scsipi_request");
  308                 }
  309 #endif
  310 
  311                 ccb->xs = xs;
  312                 ccb->timeout = xs->timeout;
  313 
  314                 /*
  315                  * Put all the arguments for the xfer in the ccb
  316                  */
  317                 if (flags & XS_CTL_RESET) {
  318                         ccb->opcode = BHA_RESET_CCB;
  319                         ccb->scsi_cmd_length = 0;
  320                 } else {
  321                         /* can't use S/G if zero length */
  322                         if (xs->cmdlen > sizeof(ccb->scsi_cmd)) {
  323                                 printf("%s: cmdlen %d too large for CCB\n",
  324                                     sc->sc_dev.dv_xname, xs->cmdlen);
  325                                 xs->error = XS_DRIVER_STUFFUP;
  326                                 goto out_bad;
  327                         }
  328                         ccb->opcode = (xs->datalen ? BHA_INIT_SCAT_GATH_CCB
  329                                                    : BHA_INITIATOR_CCB);
  330                         memcpy(&ccb->scsi_cmd, xs->cmd,
  331                             ccb->scsi_cmd_length = xs->cmdlen);
  332                 }
  333 
  334                 if (xs->datalen) {
  335                         /*
  336                          * Map the DMA transfer.
  337                          */
  338 #ifdef TFS
  339                         if (flags & XS_CTL_DATA_UIO) {
  340                                 error = bus_dmamap_load_uio(dmat,
  341                                     ccb->dmamap_xfer, (struct uio *)xs->data,
  342                                     ((flags & XS_CTL_NOSLEEP) ? BUS_DMA_NOWAIT :
  343                                      BUS_DMA_WAITOK) | BUS_DMA_STREAMING |
  344                                      ((flags & XS_CTL_DATA_IN) ? BUS_DMA_READ :
  345                                       BUS_DMA_WRITE));
  346                         } else
  347 #endif /* TFS */
  348                         {
  349                                 error = bus_dmamap_load(dmat,
  350                                     ccb->dmamap_xfer, xs->data, xs->datalen,
  351                                     NULL,
  352                                     ((flags & XS_CTL_NOSLEEP) ? BUS_DMA_NOWAIT :
  353                                      BUS_DMA_WAITOK) | BUS_DMA_STREAMING |
  354                                      ((flags & XS_CTL_DATA_IN) ? BUS_DMA_READ :
  355                                       BUS_DMA_WRITE));
  356                         }
  357 
  358                         switch (error) {
  359                         case 0:
  360                                 break;
  361 
  362                         case ENOMEM:
  363                         case EAGAIN:
  364                                 xs->error = XS_RESOURCE_SHORTAGE;
  365                                 goto out_bad;
  366 
  367                         default:
  368                                 xs->error = XS_DRIVER_STUFFUP;
  369                                 printf("%s: error %d loading DMA map\n",
  370                                     sc->sc_dev.dv_xname, error);
  371  out_bad:
  372                                 bha_free_ccb(sc, ccb);
  373                                 scsipi_done(xs);
  374                                 return;
  375                         }
  376 
  377                         bus_dmamap_sync(dmat, ccb->dmamap_xfer, 0,
  378                             ccb->dmamap_xfer->dm_mapsize,
  379                             (flags & XS_CTL_DATA_IN) ? BUS_DMASYNC_PREREAD :
  380                             BUS_DMASYNC_PREWRITE);
  381 
  382                         /*
  383                          * Load the hardware scatter/gather map with the
  384                          * contents of the DMA map.
  385                          */
  386                         for (seg = 0; seg < ccb->dmamap_xfer->dm_nsegs; seg++) {
  387                                 ltophys(ccb->dmamap_xfer->dm_segs[seg].ds_addr,
  388                                     ccb->scat_gath[seg].seg_addr);
  389                                 ltophys(ccb->dmamap_xfer->dm_segs[seg].ds_len,
  390                                     ccb->scat_gath[seg].seg_len);
  391                         }
  392 
  393                         ltophys(ccb->hashkey + offsetof(struct bha_ccb,
  394                             scat_gath), ccb->data_addr);
  395                         ltophys(ccb->dmamap_xfer->dm_nsegs *
  396                             sizeof(struct bha_scat_gath), ccb->data_length);
  397                 } else {
  398                         /*
  399                          * No data xfer, use non S/G values.
  400                          */
  401                         ltophys(0, ccb->data_addr);
  402                         ltophys(0, ccb->data_length);
  403                 }
  404 
  405                 if (XS_CTL_TAGTYPE(xs) != 0) {
  406                         ccb->tag_enable = 1;
  407                         ccb->tag_type = xs->xs_tag_type & 0x03;
  408                 } else {
  409                         ccb->tag_enable = 0;
  410                         ccb->tag_type = 0;
  411                 }
  412 
  413                 ccb->data_out = 0;
  414                 ccb->data_in = 0;
  415                 ccb->target = periph->periph_target;
  416                 ccb->lun = periph->periph_lun;
  417                 ltophys(ccb->hashkey + offsetof(struct bha_ccb, scsi_sense),
  418                     ccb->sense_ptr);
  419                 ccb->req_sense_length = sizeof(ccb->scsi_sense);
  420                 ccb->host_stat = 0x00;
  421                 ccb->target_stat = 0x00;
  422                 ccb->link_id = 0;
  423                 ltophys(0, ccb->link_addr);
  424 
  425                 BHA_CCB_SYNC(sc, ccb, BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
  426 
  427                 s = splbio();
  428                 bha_queue_ccb(sc, ccb);
  429                 splx(s);
  430 
  431                 SC_DEBUG(periph, SCSIPI_DB3, ("cmd_sent\n"));
  432                 if ((flags & XS_CTL_POLL) == 0)
  433                         return;
  434 
  435                 /*
  436                  * If we can't use interrupts, poll on completion
  437                  */
  438                 if (bha_poll(sc, xs, ccb->timeout)) {
  439                         bha_timeout(ccb);
  440                         if (bha_poll(sc, xs, ccb->timeout))
  441                                 bha_timeout(ccb);
  442                 }
  443                 return;
  444 
  445         case ADAPTER_REQ_GROW_RESOURCES:
  446                 if (sc->sc_cur_ccbs == sc->sc_max_ccbs) {
  447                         chan->chan_flags &= ~SCSIPI_CHAN_CANGROW;
  448                         return;
  449                 }
  450                 seg = sc->sc_cur_ccbs;
  451                 bha_create_ccbs(sc, bha_ccbs_per_group);
  452                 adapt->adapt_openings += sc->sc_cur_ccbs - seg;
  453                 return;
  454 
  455         case ADAPTER_REQ_SET_XFER_MODE:
  456                 /*
  457                  * Can't really do this on the Buslogic.  It has its
  458                  * own setup info.  But we do know how to query what
  459                  * the settings are.
  460                  */
  461                 bha_get_xfer_mode(sc, (struct scsipi_xfer_mode *)arg);
  462                 return;
  463         }
  464 }
  465 
  466 /*
  467  * bha_minphys:
  468  *
  469  *      Limit a transfer to our maximum transfer size.
  470  */
  471 void
  472 bha_minphys(struct buf *bp)
  473 {
  474 
  475         if (bp->b_bcount > BHA_MAXXFER)
  476                 bp->b_bcount = BHA_MAXXFER;
  477         minphys(bp);
  478 }
  479 
  480 /*****************************************************************************
  481  * SCSI job execution helper routines
  482  *****************************************************************************/
  483 
  484 /*
  485  * bha_get_xfer_mode;
  486  *
  487  *      Negotiate the xfer mode for the specified periph, and report
  488  *      back the mode to the midlayer.
  489  *
  490  *      NOTE: we must be called at splbio().
  491  */
  492 static void
  493 bha_get_xfer_mode(struct bha_softc *sc, struct scsipi_xfer_mode *xm)
  494 {
  495         struct bha_setup hwsetup;
  496         struct bha_period hwperiod;
  497         struct bha_sync *bs;
  498         int toff = xm->xm_target & 7, tmask = (1 << toff);
  499         int wide, period, offset, rlen;
  500 
  501         /*
  502          * Issue an Inquire Setup Information.  We can extract
  503          * sync and wide information from here.
  504          */
  505         rlen = sizeof(hwsetup.reply) +
  506             ((sc->sc_flags & BHAF_WIDE) ? sizeof(hwsetup.reply_w) : 0);
  507         hwsetup.cmd.opcode = BHA_INQUIRE_SETUP;
  508         hwsetup.cmd.len = rlen;
  509         bha_cmd(sc->sc_iot, sc->sc_ioh, sc->sc_dev.dv_xname,
  510             sizeof(hwsetup.cmd), (u_char *)&hwsetup.cmd,
  511             rlen, (u_char *)&hwsetup.reply);
  512 
  513         xm->xm_mode = 0;
  514         xm->xm_period = 0;
  515         xm->xm_offset = 0;
  516 
  517         /*
  518          * First check for wide.  On later boards, we can check
  519          * directly in the setup info if wide is currently active.
  520          *
  521          * On earlier boards, we have to make an educated guess.
  522          */
  523         if (sc->sc_flags & BHAF_WIDE) {
  524                 if (strcmp(sc->sc_firmware, "5.06L") >= 0) {
  525                         if (xm->xm_target > 7) {
  526                                 wide =
  527                                     hwsetup.reply_w.high_wide_active & tmask;
  528                         } else {
  529                                 wide =
  530                                     hwsetup.reply_w.low_wide_active & tmask;
  531                         }
  532                         if (wide)
  533                                 xm->xm_mode |= PERIPH_CAP_WIDE16;
  534                 } else {
  535                         /* XXX Check `wide permitted' in the config info. */
  536                         xm->xm_mode |= PERIPH_CAP_WIDE16;
  537                 }
  538         }
  539 
  540         /*
  541          * Now get basic sync info.
  542          */
  543         bs = (xm->xm_target > 7) ?
  544              &hwsetup.reply_w.sync_high[toff] :
  545              &hwsetup.reply.sync_low[toff];
  546 
  547         if (bs->valid) {
  548                 xm->xm_mode |= PERIPH_CAP_SYNC;
  549                 period = (bs->period * 50) + 20;
  550                 offset = bs->offset;
  551 
  552                 /*
  553                  * On boards that can do Fast and Ultra, use the Inquire Period
  554                  * command to get the period.
  555                  */
  556                 if (sc->sc_firmware[0] >= '3') {
  557                         rlen = sizeof(hwperiod.reply) +
  558                             ((sc->sc_flags & BHAF_WIDE) ?
  559                               sizeof(hwperiod.reply_w) : 0);
  560                         hwperiod.cmd.opcode = BHA_INQUIRE_PERIOD;
  561                         hwperiod.cmd.len = rlen;
  562                         bha_cmd(sc->sc_iot, sc->sc_ioh, sc->sc_dev.dv_xname,
  563                             sizeof(hwperiod.cmd), (u_char *)&hwperiod.cmd,
  564                             rlen, (u_char *)&hwperiod.reply);
  565 
  566                         if (xm->xm_target > 7)
  567                                 period = hwperiod.reply_w.period[toff];
  568                         else
  569                                 period = hwperiod.reply.period[toff];
  570 
  571                         period *= 10;
  572                 }
  573 
  574                 xm->xm_period =
  575                     scsipi_sync_period_to_factor(period * 100);
  576                 xm->xm_offset = offset;
  577         }
  578 
  579         /*
  580          * Now check for tagged queueing support.
  581          *
  582          * XXX Check `tags permitted' in the config info.
  583          */
  584         if (sc->sc_flags & BHAF_TAGGED_QUEUEING)
  585                 xm->xm_mode |= PERIPH_CAP_TQING;
  586 
  587         scsipi_async_event(&sc->sc_channel, ASYNC_EVENT_XFER_MODE, xm);
  588 }
  589 
  590 /*
  591  * bha_done:
  592  *
  593  *      A CCB has completed execution.  Pass the status back to the
  594  *      upper layer.
  595  */
  596 static void
  597 bha_done(struct bha_softc *sc, struct bha_ccb *ccb)
  598 {
  599         bus_dma_tag_t dmat = sc->sc_dmat;
  600         struct scsipi_xfer *xs = ccb->xs;
  601 
  602         SC_DEBUG(xs->xs_periph, SCSIPI_DB2, ("bha_done\n"));
  603 
  604 #ifdef BHADIAG
  605         if (ccb->flags & CCB_SENDING) {
  606                 printf("%s: exiting ccb still in transit!\n",
  607                     sc->sc_dev.dv_xname);
  608                 Debugger();
  609                 return;
  610         }
  611 #endif
  612         if ((ccb->flags & CCB_ALLOC) == 0) {
  613                 printf("%s: exiting ccb not allocated!\n",
  614                     sc->sc_dev.dv_xname);
  615                 Debugger();
  616                 return;
  617         }
  618 
  619         /*
  620          * If we were a data transfer, unload the map that described
  621          * the data buffer.
  622          */
  623         if (xs->datalen) {
  624                 bus_dmamap_sync(dmat, ccb->dmamap_xfer, 0,
  625                     ccb->dmamap_xfer->dm_mapsize,
  626                     (xs->xs_control & XS_CTL_DATA_IN) ? BUS_DMASYNC_POSTREAD :
  627                     BUS_DMASYNC_POSTWRITE);
  628                 bus_dmamap_unload(dmat, ccb->dmamap_xfer);
  629         }
  630 
  631         if (xs->error == XS_NOERROR) {
  632                 if (ccb->host_stat != BHA_OK) {
  633                         switch (ccb->host_stat) {
  634                         case BHA_SEL_TIMEOUT:   /* No response */
  635                                 xs->error = XS_SELTIMEOUT;
  636                                 break;
  637                         default:        /* Other scsi protocol messes */
  638                                 printf("%s: host_stat %x\n",
  639                                     sc->sc_dev.dv_xname, ccb->host_stat);
  640                                 xs->error = XS_DRIVER_STUFFUP;
  641                                 break;
  642                         }
  643                 } else if (ccb->target_stat != SCSI_OK) {
  644                         switch (ccb->target_stat) {
  645                         case SCSI_CHECK:
  646                                 memcpy(&xs->sense.scsi_sense,
  647                                     &ccb->scsi_sense,
  648                                     sizeof(xs->sense.scsi_sense));
  649                                 xs->error = XS_SENSE;
  650                                 break;
  651                         case SCSI_BUSY:
  652                                 xs->error = XS_BUSY;
  653                                 break;
  654                         default:
  655                                 printf("%s: target_stat %x\n",
  656                                     sc->sc_dev.dv_xname, ccb->target_stat);
  657                                 xs->error = XS_DRIVER_STUFFUP;
  658                                 break;
  659                         }
  660                 } else
  661                         xs->resid = 0;
  662         }
  663 
  664         bha_free_ccb(sc, ccb);
  665         scsipi_done(xs);
  666 }
  667 
  668 /*
  669  * bha_poll:
  670  *
  671  *      Poll for completion of the specified job.
  672  */
  673 static int
  674 bha_poll(struct bha_softc *sc, struct scsipi_xfer *xs, int count)
  675 {
  676         bus_space_tag_t iot = sc->sc_iot;
  677         bus_space_handle_t ioh = sc->sc_ioh;
  678 
  679         /* timeouts are in msec, so we loop in 1000 usec cycles */
  680         while (count) {
  681                 /*
  682                  * If we had interrupts enabled, would we
  683                  * have got an interrupt?
  684                  */
  685                 if (bus_space_read_1(iot, ioh, BHA_INTR_PORT) &
  686                     BHA_INTR_ANYINTR)
  687                         bha_intr(sc);
  688                 if (xs->xs_status & XS_STS_DONE)
  689                         return (0);
  690                 delay(1000);    /* only happens in boot so ok */
  691                 count--;
  692         }
  693         return (1);
  694 }
  695 
  696 /*
  697  * bha_timeout:
  698  *
  699  *      CCB timeout handler.
  700  */
  701 static void
  702 bha_timeout(void *arg)
  703 {
  704         struct bha_ccb *ccb = arg;
  705         struct scsipi_xfer *xs = ccb->xs;
  706         struct scsipi_periph *periph = xs->xs_periph;
  707         struct bha_softc *sc =
  708             (void *)periph->periph_channel->chan_adapter->adapt_dev;
  709         int s;
  710 
  711         scsipi_printaddr(periph);
  712         printf("timed out");
  713 
  714         s = splbio();
  715 
  716 #ifdef BHADIAG
  717         /*
  718          * If the ccb's mbx is not free, then the board has gone Far East?
  719          */
  720         bha_collect_mbo(sc);
  721         if (ccb->flags & CCB_SENDING) {
  722                 printf("%s: not taking commands!\n", sc->sc_dev.dv_xname);
  723                 Debugger();
  724         }
  725 #endif
  726 
  727         /*
  728          * If it has been through before, then
  729          * a previous abort has failed, don't
  730          * try abort again
  731          */
  732         if (ccb->flags & CCB_ABORT) {
  733                 /* abort timed out */
  734                 printf(" AGAIN\n");
  735                 /* XXX Must reset! */
  736         } else {
  737                 /* abort the operation that has timed out */
  738                 printf("\n");
  739                 ccb->xs->error = XS_TIMEOUT;
  740                 ccb->timeout = BHA_ABORT_TIMEOUT;
  741                 ccb->flags |= CCB_ABORT;
  742                 bha_queue_ccb(sc, ccb);
  743         }
  744 
  745         splx(s);
  746 }
  747 
  748 /*****************************************************************************
  749  * Misc. subroutines.
  750  *****************************************************************************/
  751 
  752 /*
  753  * bha_cmd:
  754  *
  755  *      Send a command to the Buglogic controller.
  756  */
  757 static int
  758 bha_cmd(bus_space_tag_t iot, bus_space_handle_t ioh, const char *name, int icnt,
  759     u_char *ibuf, int ocnt, u_char *obuf)
  760 {
  761         int i;
  762         int wait;
  763         u_char sts;
  764         u_char opcode = ibuf[0];
  765 
  766         /*
  767          * Calculate a reasonable timeout for the command.
  768          */
  769         switch (opcode) {
  770         case BHA_INQUIRE_DEVICES:
  771         case BHA_INQUIRE_DEVICES_2:
  772                 wait = 90 * 20000;
  773                 break;
  774         default:
  775                 wait = 1 * 20000;
  776                 break;
  777         }
  778 
  779         /*
  780          * Wait for the adapter to go idle, unless it's one of
  781          * the commands which don't need this
  782          */
  783         if (opcode != BHA_MBO_INTR_EN) {
  784                 for (i = 20000; i; i--) {       /* 1 sec? */
  785                         sts = bus_space_read_1(iot, ioh, BHA_STAT_PORT);
  786                         if (sts & BHA_STAT_IDLE)
  787                                 break;
  788                         delay(50);
  789                 }
  790                 if (!i) {
  791                         printf("%s: bha_cmd, host not idle(0x%x)\n",
  792                             name, sts);
  793                         return (1);
  794                 }
  795         }
  796 
  797         /*
  798          * Now that it is idle, if we expect output, preflush the
  799          * queue feeding to us.
  800          */
  801         if (ocnt) {
  802                 while ((bus_space_read_1(iot, ioh, BHA_STAT_PORT)) &
  803                     BHA_STAT_DF)
  804                         (void)bus_space_read_1(iot, ioh, BHA_DATA_PORT);
  805         }
  806 
  807         /*
  808          * Output the command and the number of arguments given
  809          * for each byte, first check the port is empty.
  810          */
  811         while (icnt--) {
  812                 for (i = wait; i; i--) {
  813                         sts = bus_space_read_1(iot, ioh, BHA_STAT_PORT);
  814                         if (!(sts & BHA_STAT_CDF))
  815                                 break;
  816                         delay(50);
  817                 }
  818                 if (!i) {
  819                         if (opcode != BHA_INQUIRE_REVISION)
  820                                 printf("%s: bha_cmd, cmd/data port full\n",
  821                                     name);
  822                         goto bad;
  823                 }
  824                 bus_space_write_1(iot, ioh, BHA_CMD_PORT, *ibuf++);
  825         }
  826 
  827         /*
  828          * If we expect input, loop that many times, each time,
  829          * looking for the data register to have valid data
  830          */
  831         while (ocnt--) {
  832                 for (i = wait; i; i--) {
  833                         sts = bus_space_read_1(iot, ioh, BHA_STAT_PORT);
  834                         if (sts & BHA_STAT_DF)
  835                                 break;
  836                         delay(50);
  837                 }
  838                 if (!i) {
  839 #ifdef BHADEBUG
  840                         if (opcode != BHA_INQUIRE_REVISION)
  841                                 printf("%s: bha_cmd, cmd/data port empty %d\n",
  842                                     name, ocnt);
  843 #endif /* BHADEBUG */
  844                         goto bad;
  845                 }
  846                 *obuf++ = bus_space_read_1(iot, ioh, BHA_DATA_PORT);
  847         }
  848 
  849         /*
  850          * Wait for the board to report a finished instruction.
  851          * We may get an extra interrupt for the HACC signal, but this is
  852          * unimportant.
  853          */
  854         if (opcode != BHA_MBO_INTR_EN && opcode != BHA_MODIFY_IOPORT) {
  855                 for (i = 20000; i; i--) {       /* 1 sec? */
  856                         sts = bus_space_read_1(iot, ioh, BHA_INTR_PORT);
  857                         /* XXX Need to save this in the interrupt handler? */
  858                         if (sts & BHA_INTR_HACC)
  859                                 break;
  860                         delay(50);
  861                 }
  862                 if (!i) {
  863                         printf("%s: bha_cmd, host not finished(0x%x)\n",
  864                             name, sts);
  865                         return (1);
  866                 }
  867         }
  868         bus_space_write_1(iot, ioh, BHA_CTRL_PORT, BHA_CTRL_IRST);
  869         return (0);
  870 
  871 bad:
  872         bus_space_write_1(iot, ioh, BHA_CTRL_PORT, BHA_CTRL_SRST);
  873         return (1);
  874 }
  875 
  876 /*
  877  * bha_find:
  878  *
  879  *      Find the board.
  880  */
  881 int
  882 bha_find(bus_space_tag_t iot, bus_space_handle_t ioh)
  883 {
  884         int i;
  885         u_char sts;
  886         struct bha_extended_inquire inquire;
  887 
  888         /* Check something is at the ports we need to access */
  889         sts = bus_space_read_1(iot, ioh, BHA_STAT_PORT);
  890         if (sts == 0xFF)
  891                 return (0);
  892 
  893         /*
  894          * Reset board, If it doesn't respond, assume
  895          * that it's not there.. good for the probe
  896          */
  897 
  898         bus_space_write_1(iot, ioh, BHA_CTRL_PORT,
  899             BHA_CTRL_HRST | BHA_CTRL_SRST);
  900 
  901         delay(100);
  902         for (i = BHA_RESET_TIMEOUT; i; i--) {
  903                 sts = bus_space_read_1(iot, ioh, BHA_STAT_PORT);
  904                 if (sts == (BHA_STAT_IDLE | BHA_STAT_INIT))
  905                         break;
  906                 delay(1000);
  907         }
  908         if (!i) {
  909 #ifdef BHADEBUG
  910                 if (bha_debug)
  911                         printf("bha_find: No answer from buslogic board\n");
  912 #endif /* BHADEBUG */
  913                 return (0);
  914         }
  915 
  916         /*
  917          * The BusLogic cards implement an Adaptec 1542 (aha)-compatible
  918          * interface. The native bha interface is not compatible with
  919          * an aha. 1542. We need to ensure that we never match an
  920          * Adaptec 1542. We must also avoid sending Adaptec-compatible
  921          * commands to a real bha, lest it go into 1542 emulation mode.
  922          * (On an indirect bus like ISA, we should always probe for BusLogic
  923          * interfaces before Adaptec interfaces).
  924          */
  925 
  926         /*
  927          * Make sure we don't match an AHA-1542A or AHA-1542B, by checking
  928          * for an extended-geometry register.  The 1542[AB] don't have one.
  929          */
  930         sts = bus_space_read_1(iot, ioh, BHA_EXTGEOM_PORT);
  931         if (sts == 0xFF)
  932                 return (0);
  933 
  934         /*
  935          * Check that we actually know how to use this board.
  936          */
  937         delay(1000);
  938         inquire.cmd.opcode = BHA_INQUIRE_EXTENDED;
  939         inquire.cmd.len = sizeof(inquire.reply);
  940         i = bha_cmd(iot, ioh, "(bha_find)",
  941             sizeof(inquire.cmd), (u_char *)&inquire.cmd,
  942             sizeof(inquire.reply), (u_char *)&inquire.reply);
  943 
  944         /*
  945          * Some 1542Cs (CP, perhaps not CF, may depend on firmware rev)
  946          * have the extended-geometry register and also respond to
  947          * BHA_INQUIRE_EXTENDED.  Make sure we never match such cards,
  948          * by checking the size of the reply is what a BusLogic card returns.
  949          */
  950         if (i) {
  951 #ifdef BHADEBUG
  952                 printf("bha_find: board returned %d instead of %d to %s\n",
  953                        i, sizeof(inquire.reply), "INQUIRE_EXTENDED");
  954 #endif
  955                 return (0);
  956         }
  957 
  958         /* OK, we know we've found a buslogic adaptor. */
  959 
  960         switch (inquire.reply.bus_type) {
  961         case BHA_BUS_TYPE_24BIT:
  962         case BHA_BUS_TYPE_32BIT:
  963                 break;
  964         case BHA_BUS_TYPE_MCA:
  965                 /* We don't grok MicroChannel (yet). */
  966                 return (0);
  967         default:
  968                 printf("bha_find: illegal bus type %c\n",
  969                     inquire.reply.bus_type);
  970                 return (0);
  971         }
  972 
  973         return (1);
  974 }
  975 
  976 
  977 /*
  978  * bha_inquire_config:
  979  *
  980  *      Determine irq/drq.
  981  */
  982 int
  983 bha_inquire_config(bus_space_tag_t iot, bus_space_handle_t ioh,
  984             struct bha_probe_data *sc)
  985 {
  986         int irq, drq;
  987         struct bha_config config;
  988 
  989         /*
  990          * Assume we have a board at this stage setup DMA channel from
  991          * jumpers and save int level
  992          */
  993         delay(1000);
  994         config.cmd.opcode = BHA_INQUIRE_CONFIG;
  995         bha_cmd(iot, ioh, "(bha_inquire_config)",
  996             sizeof(config.cmd), (u_char *)&config.cmd,
  997             sizeof(config.reply), (u_char *)&config.reply);
  998         switch (config.reply.chan) {
  999         case EISADMA:
 1000                 drq = -1;
 1001                 break;
 1002         case CHAN0:
 1003                 drq = 0;
 1004                 break;
 1005         case CHAN5:
 1006                 drq = 5;
 1007                 break;
 1008         case CHAN6:
 1009                 drq = 6;
 1010                 break;
 1011         case CHAN7:
 1012                 drq = 7;
 1013                 break;
 1014         default:
 1015                 printf("bha: illegal drq setting %x\n",
 1016                     config.reply.chan);
 1017                 return (0);
 1018         }
 1019 
 1020         switch (config.reply.intr) {
 1021         case INT9:
 1022                 irq = 9;
 1023                 break;
 1024         case INT10:
 1025                 irq = 10;
 1026                 break;
 1027         case INT11:
 1028                 irq = 11;
 1029                 break;
 1030         case INT12:
 1031                 irq = 12;
 1032                 break;
 1033         case INT14:
 1034                 irq = 14;
 1035                 break;
 1036         case INT15:
 1037                 irq = 15;
 1038                 break;
 1039         default:
 1040                 printf("bha: illegal irq setting %x\n",
 1041                     config.reply.intr);
 1042                 return (0);
 1043         }
 1044 
 1045         /* if we want to fill in softc, do so now */
 1046         if (sc != NULL) {
 1047                 sc->sc_irq = irq;
 1048                 sc->sc_drq = drq;
 1049         }
 1050 
 1051         return (1);
 1052 }
 1053 
 1054 int
 1055 bha_probe_inquiry(bus_space_tag_t iot, bus_space_handle_t ioh,
 1056     struct bha_probe_data *bpd)
 1057 {
 1058         return bha_find(iot, ioh) && bha_inquire_config(iot, ioh, bpd);
 1059 }
 1060 
 1061 /*
 1062  * bha_disable_isacompat:
 1063  *
 1064  *      Disable the ISA-compatibility ioports on PCI bha devices,
 1065  *      to ensure they're not autoconfigured a second time as an ISA bha.
 1066  */
 1067 int
 1068 bha_disable_isacompat(struct bha_softc *sc)
 1069 {
 1070         struct bha_isadisable isa_disable;
 1071 
 1072         isa_disable.cmd.opcode = BHA_MODIFY_IOPORT;
 1073         isa_disable.cmd.modifier = BHA_IOMODIFY_DISABLE1;
 1074         bha_cmd(sc->sc_iot, sc->sc_ioh, sc->sc_dev.dv_xname,
 1075             sizeof(isa_disable.cmd), (u_char*)&isa_disable.cmd,
 1076             0, (u_char *)0);
 1077         return (0);
 1078 }
 1079 
 1080 /*
 1081  * bha_info:
 1082  *
 1083  *      Get information about the board, and report it.  We
 1084  *      return the initial number of CCBs, 0 if we failed.
 1085  */
 1086 int
 1087 bha_info(struct bha_softc *sc)
 1088 {
 1089         bus_space_tag_t iot = sc->sc_iot;
 1090         bus_space_handle_t ioh = sc->sc_ioh;
 1091         struct bha_extended_inquire inquire;
 1092         struct bha_config config;
 1093         struct bha_devices devices;
 1094         struct bha_setup setup;
 1095         struct bha_model model;
 1096         struct bha_revision revision;
 1097         struct bha_digit digit;
 1098         int i, j, initial_ccbs, rlen;
 1099         char *name = sc->sc_dev.dv_xname;
 1100         char *p;
 1101 
 1102         /*
 1103          * Fetch the extended inquire information.
 1104          */
 1105         inquire.cmd.opcode = BHA_INQUIRE_EXTENDED;
 1106         inquire.cmd.len = sizeof(inquire.reply);
 1107         bha_cmd(iot, ioh, name,
 1108             sizeof(inquire.cmd), (u_char *)&inquire.cmd,
 1109             sizeof(inquire.reply), (u_char *)&inquire.reply);
 1110 
 1111         /*
 1112          * Fetch the configuration information.
 1113          */
 1114         config.cmd.opcode = BHA_INQUIRE_CONFIG;
 1115         bha_cmd(iot, ioh, name,
 1116             sizeof(config.cmd), (u_char *)&config.cmd,
 1117             sizeof(config.reply), (u_char *)&config.reply);
 1118 
 1119         sc->sc_scsi_id = config.reply.scsi_dev;
 1120 
 1121         /*
 1122          * Get the firmware revision.
 1123          */
 1124         p = sc->sc_firmware;
 1125         revision.cmd.opcode = BHA_INQUIRE_REVISION;
 1126         bha_cmd(iot, ioh, name,
 1127             sizeof(revision.cmd), (u_char *)&revision.cmd,
 1128             sizeof(revision.reply), (u_char *)&revision.reply);
 1129         *p++ = revision.reply.firm_revision;
 1130         *p++ = '.';
 1131         *p++ = revision.reply.firm_version;
 1132         digit.cmd.opcode = BHA_INQUIRE_REVISION_3;
 1133         bha_cmd(iot, ioh, name,
 1134             sizeof(digit.cmd), (u_char *)&digit.cmd,
 1135             sizeof(digit.reply), (u_char *)&digit.reply);
 1136         *p++ = digit.reply.digit;
 1137         if (revision.reply.firm_revision >= '3' ||
 1138             (revision.reply.firm_revision == '3' &&
 1139              revision.reply.firm_version >= '3')) {
 1140                 digit.cmd.opcode = BHA_INQUIRE_REVISION_4;
 1141                 bha_cmd(iot, ioh, name,
 1142                     sizeof(digit.cmd), (u_char *)&digit.cmd,
 1143                     sizeof(digit.reply), (u_char *)&digit.reply);
 1144                 *p++ = digit.reply.digit;
 1145         }
 1146         while (p > sc->sc_firmware && (p[-1] == ' ' || p[-1] == '\0'))
 1147                 p--;
 1148         *p = '\0';
 1149 
 1150         /*
 1151          * Get the model number.
 1152          *
 1153          * Some boards do not handle the Inquire Board Model Number
 1154          * command correctly, or don't give correct information.
 1155          *
 1156          * So, we use the Firmware Revision and Extended Setup
 1157          * information to fixup the model number in these cases.
 1158          *
 1159          * The firmware version indicates:
 1160          *
 1161          *      5.xx    BusLogic "W" Series Host Adapters
 1162          *              BT-948/958/958D
 1163          *
 1164          *      4.xx    BusLogic "C" Series Host Adapters
 1165          *              BT-946C/956C/956CD/747C/757C/757CD/445C/545C/540CF
 1166          *
 1167          *      3.xx    BusLogic "S" Series Host Adapters
 1168          *              BT-747S/747D/757S/757D/445S/545S/542D
 1169          *              BT-542B/742A (revision H)
 1170          *
 1171          *      2.xx    BusLogic "A" Series Host Adapters
 1172          *              BT-542B/742A (revision G and below)
 1173          *
 1174          *      0.xx    AMI FastDisk VLB/EISA BusLogic Clone Host Adapter
 1175          */
 1176         if (inquire.reply.bus_type == BHA_BUS_TYPE_24BIT &&
 1177             sc->sc_firmware[0] < '3')
 1178                 snprintf(sc->sc_model, sizeof(sc->sc_model), "542B");
 1179         else if (inquire.reply.bus_type == BHA_BUS_TYPE_32BIT &&
 1180             sc->sc_firmware[0] == '2' &&
 1181             (sc->sc_firmware[2] == '1' ||
 1182              (sc->sc_firmware[2] == '2' && sc->sc_firmware[3] == '')))
 1183                 snprintf(sc->sc_model, sizeof(sc->sc_model), "742A");
 1184         else if (inquire.reply.bus_type == BHA_BUS_TYPE_32BIT &&
 1185             sc->sc_firmware[0] == '')
 1186                 snprintf(sc->sc_model, sizeof(sc->sc_model), "747A");
 1187         else {
 1188                 p = sc->sc_model;
 1189                 model.cmd.opcode = BHA_INQUIRE_MODEL;
 1190                 model.cmd.len = sizeof(model.reply);
 1191                 bha_cmd(iot, ioh, name,
 1192                     sizeof(model.cmd), (u_char *)&model.cmd,
 1193                     sizeof(model.reply), (u_char *)&model.reply);
 1194                 *p++ = model.reply.id[0];
 1195                 *p++ = model.reply.id[1];
 1196                 *p++ = model.reply.id[2];
 1197                 *p++ = model.reply.id[3];
 1198                 while (p > sc->sc_model && (p[-1] == ' ' || p[-1] == '\0'))
 1199                         p--;
 1200                 *p++ = model.reply.version[0];
 1201                 *p++ = model.reply.version[1];
 1202                 while (p > sc->sc_model && (p[-1] == ' ' || p[-1] == '\0'))
 1203                         p--;
 1204                 *p = '\0';
 1205         }
 1206 
 1207         /* Enable round-robin scheme - appeared at firmware rev. 3.31. */
 1208         if (strcmp(sc->sc_firmware, "3.31") >= 0)
 1209                 sc->sc_flags |= BHAF_STRICT_ROUND_ROBIN;
 1210 
 1211         /*
 1212          * Determine some characteristics about our bus.
 1213          */
 1214         if (inquire.reply.scsi_flags & BHA_SCSI_WIDE)
 1215                 sc->sc_flags |= BHAF_WIDE;
 1216         if (inquire.reply.scsi_flags & BHA_SCSI_DIFFERENTIAL)
 1217                 sc->sc_flags |= BHAF_DIFFERENTIAL;
 1218         if (inquire.reply.scsi_flags & BHA_SCSI_ULTRA)
 1219                 sc->sc_flags |= BHAF_ULTRA;
 1220 
 1221         /*
 1222          * Determine some characterists of the board.
 1223          */
 1224         sc->sc_max_dmaseg = inquire.reply.sg_limit;
 1225 
 1226         /*
 1227          * Determine the maximum CCB count and whether or not
 1228          * tagged queueing is available on this host adapter.
 1229          *
 1230          * Tagged queueing works on:
 1231          *
 1232          *      "W" Series adapters
 1233          *      "C" Series adapters with firmware >= 4.22
 1234          *      "S" Series adapters with firmware >= 3.35
 1235          *
 1236          * The internal CCB counts are:
 1237          *
 1238          *      192     BT-948/958/958D
 1239          *      100     BT-946C/956C/956CD/747C/757C/757CD/445C
 1240          *      50      BT-545C/540CF
 1241          *      30      BT-747S/747D/757S/757D/445S/545S/542D/542B/742A
 1242          */
 1243         switch (sc->sc_firmware[0]) {
 1244         case '5':
 1245                 sc->sc_max_ccbs = 192;
 1246                 sc->sc_flags |= BHAF_TAGGED_QUEUEING;
 1247                 break;
 1248 
 1249         case '4':
 1250                 if (sc->sc_model[0] == '5')
 1251                         sc->sc_max_ccbs = 50;
 1252                 else
 1253                         sc->sc_max_ccbs = 100;
 1254                 if (strcmp(sc->sc_firmware, "4.22") >= 0)
 1255                         sc->sc_flags |= BHAF_TAGGED_QUEUEING;
 1256                 break;
 1257 
 1258         case '3':
 1259                 if (strcmp(sc->sc_firmware, "3.35") >= 0)
 1260                         sc->sc_flags |= BHAF_TAGGED_QUEUEING;
 1261                 /* FALLTHROUGH */
 1262 
 1263         default:
 1264                 sc->sc_max_ccbs = 30;
 1265         }
 1266 
 1267         /*
 1268          * Set the mailbox count to precisely the number of HW CCBs
 1269          * available.  A mailbox isn't required while a CCB is executing,
 1270          * but this allows us to actually enqueue up to our resource
 1271          * limit.
 1272          *
 1273          * This will keep the mailbox count small on boards which don't
 1274          * have strict round-robin (they have to scan the entire set of
 1275          * mailboxes each time they run a command).
 1276          */
 1277         sc->sc_mbox_count = sc->sc_max_ccbs;
 1278 
 1279         /*
 1280          * Obtain setup information.
 1281          */
 1282         rlen = sizeof(setup.reply) +
 1283             ((sc->sc_flags & BHAF_WIDE) ? sizeof(setup.reply_w) : 0);
 1284         setup.cmd.opcode = BHA_INQUIRE_SETUP;
 1285         setup.cmd.len = rlen;
 1286         bha_cmd(iot, ioh, name,
 1287             sizeof(setup.cmd), (u_char *)&setup.cmd,
 1288             rlen, (u_char *)&setup.reply);
 1289 
 1290         aprint_normal("%s: model BT-%s, firmware %s\n", sc->sc_dev.dv_xname,
 1291             sc->sc_model, sc->sc_firmware);
 1292 
 1293         aprint_normal("%s: %d H/W CCBs", sc->sc_dev.dv_xname, sc->sc_max_ccbs);
 1294         if (setup.reply.sync_neg)
 1295                 aprint_normal(", sync");
 1296         if (setup.reply.parity)
 1297                 aprint_normal(", parity");
 1298         if (sc->sc_flags & BHAF_TAGGED_QUEUEING)
 1299                 aprint_normal(", tagged queueing");
 1300         if (sc->sc_flags & BHAF_WIDE_LUN)
 1301                 aprint_normal(", wide LUN support");
 1302         aprint_normal("\n");
 1303 
 1304         /*
 1305          * Poll targets 0 - 7.
 1306          */
 1307         devices.cmd.opcode = BHA_INQUIRE_DEVICES;
 1308         bha_cmd(iot, ioh, name,
 1309             sizeof(devices.cmd), (u_char *)&devices.cmd,
 1310             sizeof(devices.reply), (u_char *)&devices.reply);
 1311 
 1312         /* Count installed units. */
 1313         initial_ccbs = 0;
 1314         for (i = 0; i < 8; i++) {
 1315                 for (j = 0; j < 8; j++) {
 1316                         if (((devices.reply.lun_map[i] >> j) & 1) == 1)
 1317                                 initial_ccbs++;
 1318                 }
 1319         }
 1320 
 1321         /*
 1322          * Poll targets 8 - 15 if we have a wide bus.
 1323          */
 1324         if (sc->sc_flags & BHAF_WIDE) {
 1325                 devices.cmd.opcode = BHA_INQUIRE_DEVICES_2;
 1326                 bha_cmd(iot, ioh, name,
 1327                     sizeof(devices.cmd), (u_char *)&devices.cmd,
 1328                     sizeof(devices.reply), (u_char *)&devices.reply);
 1329 
 1330                 for (i = 0; i < 8; i++) {
 1331                         for (j = 0; j < 8; j++) {
 1332                                 if (((devices.reply.lun_map[i] >> j) & 1) == 1)
 1333                                         initial_ccbs++;
 1334                         }
 1335                 }
 1336         }
 1337 
 1338         /*
 1339          * Double the initial CCB count, for good measure.
 1340          */
 1341         initial_ccbs *= 2;
 1342 
 1343         /*
 1344          * Sanity check the initial CCB count; don't create more than
 1345          * we can enqueue (sc_max_ccbs), and make sure there are some
 1346          * at all.
 1347          */
 1348         if (initial_ccbs > sc->sc_max_ccbs)
 1349                 initial_ccbs = sc->sc_max_ccbs;
 1350         if (initial_ccbs == 0)
 1351                 initial_ccbs = 2;
 1352 
 1353         return (initial_ccbs);
 1354 }
 1355 
 1356 /*
 1357  * bha_init:
 1358  *
 1359  *      Initialize the board.
 1360  */
 1361 static int
 1362 bha_init(struct bha_softc *sc)
 1363 {
 1364         char *name = sc->sc_dev.dv_xname;
 1365         struct bha_toggle toggle;
 1366         struct bha_mailbox mailbox;
 1367         struct bha_mbx_out *mbo;
 1368         struct bha_mbx_in *mbi;
 1369         int i;
 1370 
 1371         /*
 1372          * Set up the mailbox.  We always run the mailbox in round-robin.
 1373          */
 1374         for (i = 0; i < sc->sc_mbox_count; i++) {
 1375                 mbo = &sc->sc_mbo[i];
 1376                 mbi = &sc->sc_mbi[i];
 1377 
 1378                 mbo->cmd = BHA_MBO_FREE;
 1379                 BHA_MBO_SYNC(sc, mbo, BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
 1380 
 1381                 mbi->comp_stat = BHA_MBI_FREE;
 1382                 BHA_MBI_SYNC(sc, mbi, BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
 1383         }
 1384 
 1385         sc->sc_cmbo = sc->sc_tmbo = &sc->sc_mbo[0];
 1386         sc->sc_tmbi = &sc->sc_mbi[0];
 1387 
 1388         sc->sc_mbofull = 0;
 1389 
 1390         /*
 1391          * If the board supports strict round-robin, enable that.
 1392          */
 1393         if (sc->sc_flags & BHAF_STRICT_ROUND_ROBIN) {
 1394                 toggle.cmd.opcode = BHA_ROUND_ROBIN;
 1395                 toggle.cmd.enable = 1;
 1396                 bha_cmd(sc->sc_iot, sc->sc_ioh, name,
 1397                     sizeof(toggle.cmd), (u_char *)&toggle.cmd,
 1398                     0, NULL);
 1399         }
 1400 
 1401         /*
 1402          * Give the mailbox to the board.
 1403          */
 1404         mailbox.cmd.opcode = BHA_MBX_INIT_EXTENDED;
 1405         mailbox.cmd.nmbx = sc->sc_mbox_count;
 1406         ltophys(sc->sc_dmamap_mbox->dm_segs[0].ds_addr, mailbox.cmd.addr);
 1407         bha_cmd(sc->sc_iot, sc->sc_ioh, name,
 1408             sizeof(mailbox.cmd), (u_char *)&mailbox.cmd,
 1409             0, (u_char *)0);
 1410 
 1411         return (0);
 1412 }
 1413 
 1414 /*****************************************************************************
 1415  * CCB execution engine
 1416  *****************************************************************************/
 1417 
 1418 /*
 1419  * bha_queue_ccb:
 1420  *
 1421  *      Queue a CCB to be sent to the controller, and send it if possible.
 1422  */
 1423 static void
 1424 bha_queue_ccb(struct bha_softc *sc, struct bha_ccb *ccb)
 1425 {
 1426 
 1427         TAILQ_INSERT_TAIL(&sc->sc_waiting_ccb, ccb, chain);
 1428         bha_start_ccbs(sc);
 1429 }
 1430 
 1431 /*
 1432  * bha_start_ccbs:
 1433  *
 1434  *      Send as many CCBs as we have empty mailboxes for.
 1435  */
 1436 static void
 1437 bha_start_ccbs(struct bha_softc *sc)
 1438 {
 1439         bus_space_tag_t iot = sc->sc_iot;
 1440         bus_space_handle_t ioh = sc->sc_ioh;
 1441         struct bha_ccb_group *bcg;
 1442         struct bha_mbx_out *mbo;
 1443         struct bha_ccb *ccb;
 1444 
 1445         mbo = sc->sc_tmbo;
 1446 
 1447         while ((ccb = TAILQ_FIRST(&sc->sc_waiting_ccb)) != NULL) {
 1448                 if (sc->sc_mbofull >= sc->sc_mbox_count) {
 1449 #ifdef DIAGNOSTIC
 1450                         if (sc->sc_mbofull > sc->sc_mbox_count)
 1451                                 panic("bha_start_ccbs: mbofull > mbox_count");
 1452 #endif
 1453                         /*
 1454                          * No mailboxes available; attempt to collect ones
 1455                          * that have already been used.
 1456                          */
 1457                         bha_collect_mbo(sc);
 1458                         if (sc->sc_mbofull == sc->sc_mbox_count) {
 1459                                 /*
 1460                                  * Still no more available; have the
 1461                                  * controller interrupt us when it
 1462                                  * frees one.
 1463                                  */
 1464                                 struct bha_toggle toggle;
 1465 
 1466                                 toggle.cmd.opcode = BHA_MBO_INTR_EN;
 1467                                 toggle.cmd.enable = 1;
 1468                                 bha_cmd(iot, ioh, sc->sc_dev.dv_xname,
 1469                                     sizeof(toggle.cmd), (u_char *)&toggle.cmd,
 1470                                     0, (u_char *)0);
 1471                                 break;
 1472                         }
 1473                 }
 1474 
 1475                 TAILQ_REMOVE(&sc->sc_waiting_ccb, ccb, chain);
 1476 #ifdef BHADIAG
 1477                 ccb->flags |= CCB_SENDING;
 1478 #endif
 1479 
 1480                 /*
 1481                  * Put the CCB in the mailbox.
 1482                  */
 1483                 bcg = BHA_CCB_GROUP(ccb);
 1484                 ltophys(bcg->bcg_dmamap->dm_segs[0].ds_addr +
 1485                     BHA_CCB_OFFSET(ccb), mbo->ccb_addr);
 1486                 if (ccb->flags & CCB_ABORT)
 1487                         mbo->cmd = BHA_MBO_ABORT;
 1488                 else
 1489                         mbo->cmd = BHA_MBO_START;
 1490 
 1491                 BHA_MBO_SYNC(sc, mbo,
 1492                     BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
 1493 
 1494                 /* Tell the card to poll immediately. */
 1495                 bus_space_write_1(iot, ioh, BHA_CMD_PORT, BHA_START_SCSI);
 1496 
 1497                 if ((ccb->xs->xs_control & XS_CTL_POLL) == 0)
 1498                         callout_reset(&ccb->xs->xs_callout,
 1499                             mstohz(ccb->timeout), bha_timeout, ccb);
 1500 
 1501                 ++sc->sc_mbofull;
 1502                 mbo = bha_nextmbo(sc, mbo);
 1503         }
 1504 
 1505         sc->sc_tmbo = mbo;
 1506 }
 1507 
 1508 /*
 1509  * bha_finish_ccbs:
 1510  *
 1511  *      Finalize the execution of CCBs in our incoming mailbox.
 1512  */
 1513 static void
 1514 bha_finish_ccbs(struct bha_softc *sc)
 1515 {
 1516         struct bha_mbx_in *mbi;
 1517         struct bha_ccb *ccb;
 1518         int i;
 1519 
 1520         mbi = sc->sc_tmbi;
 1521 
 1522         BHA_MBI_SYNC(sc, mbi, BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
 1523 
 1524         if (mbi->comp_stat == BHA_MBI_FREE) {
 1525                 for (i = 0; i < sc->sc_mbox_count; i++) {
 1526                         if (mbi->comp_stat != BHA_MBI_FREE) {
 1527 #ifdef BHADIAG
 1528                                 /*
 1529                                  * This can happen in normal operation if
 1530                                  * we use all mailbox slots.
 1531                                  */
 1532                                 printf("%s: mbi not in round-robin order\n",
 1533                                     sc->sc_dev.dv_xname);
 1534 #endif
 1535                                 goto again;
 1536                         }
 1537                         mbi = bha_nextmbi(sc, mbi);
 1538                         BHA_MBI_SYNC(sc, mbi,
 1539                             BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
 1540                 }
 1541 #ifdef BHADIAGnot
 1542                 printf("%s: mbi interrupt with no full mailboxes\n",
 1543                     sc->sc_dev.dv_xname);
 1544 #endif
 1545                 return;
 1546         }
 1547 
 1548  again:
 1549         do {
 1550                 ccb = bha_ccb_phys_kv(sc, phystol(mbi->ccb_addr));
 1551                 if (ccb == NULL) {
 1552                         printf("%s: bad mbi ccb pointer 0x%08x; skipping\n",
 1553                             sc->sc_dev.dv_xname, phystol(mbi->ccb_addr));
 1554                         goto next;
 1555                 }
 1556 
 1557                 BHA_CCB_SYNC(sc, ccb,
 1558                     BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
 1559 
 1560 #ifdef BHADEBUG
 1561                 if (bha_debug) {
 1562                         u_char *cp = ccb->scsi_cmd;
 1563                         printf("op=%x %x %x %x %x %x\n",
 1564                             cp[0], cp[1], cp[2], cp[3], cp[4], cp[5]);
 1565                         printf("comp_stat %x for mbi addr = %p, ",
 1566                             mbi->comp_stat, mbi);
 1567                         printf("ccb addr = %p\n", ccb);
 1568                 }
 1569 #endif /* BHADEBUG */
 1570 
 1571                 switch (mbi->comp_stat) {
 1572                 case BHA_MBI_OK:
 1573                 case BHA_MBI_ERROR:
 1574                         if ((ccb->flags & CCB_ABORT) != 0) {
 1575                                 /*
 1576                                  * If we already started an abort, wait for it
 1577                                  * to complete before clearing the CCB.  We
 1578                                  * could instead just clear CCB_SENDING, but
 1579                                  * what if the mailbox was already received?
 1580                                  * The worst that happens here is that we clear
 1581                                  * the CCB a bit later than we need to.  BFD.
 1582                                  */
 1583                                 goto next;
 1584                         }
 1585                         break;
 1586 
 1587                 case BHA_MBI_ABORT:
 1588                 case BHA_MBI_UNKNOWN:
 1589                         /*
 1590                          * Even if the CCB wasn't found, we clear it anyway.
 1591                          * See preceding comment.
 1592                          */
 1593                         break;
 1594 
 1595                 default:
 1596                         printf("%s: bad mbi comp_stat %02x; skipping\n",
 1597                             sc->sc_dev.dv_xname, mbi->comp_stat);
 1598                         goto next;
 1599                 }
 1600 
 1601                 callout_stop(&ccb->xs->xs_callout);
 1602                 bha_done(sc, ccb);
 1603 
 1604         next:
 1605                 mbi->comp_stat = BHA_MBI_FREE;
 1606                 BHA_CCB_SYNC(sc, ccb,
 1607                     BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
 1608 
 1609                 mbi = bha_nextmbi(sc, mbi);
 1610                 BHA_MBI_SYNC(sc, mbi,
 1611                     BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
 1612         } while (mbi->comp_stat != BHA_MBI_FREE);
 1613 
 1614         sc->sc_tmbi = mbi;
 1615 }
 1616 
 1617 /*****************************************************************************
 1618  * Mailbox management functions.
 1619  *****************************************************************************/
 1620 
 1621 /*
 1622  * bha_create_mailbox:
 1623  *
 1624  *      Create the mailbox structures.  Helper function for bha_attach().
 1625  *
 1626  *      NOTE: The Buslogic hardware only gets one DMA address for the
 1627  *      mailbox!  It expects:
 1628  *
 1629  *              mailbox_out[mailbox_size]
 1630  *              mailbox_in[mailbox_size]
 1631  */
 1632 static int
 1633 bha_create_mailbox(struct bha_softc *sc)
 1634 {
 1635         bus_dma_segment_t seg;
 1636         size_t size;
 1637         int error, rseg;
 1638 
 1639         size = (sizeof(struct bha_mbx_out) * sc->sc_mbox_count) +
 1640                (sizeof(struct bha_mbx_in)  * sc->sc_mbox_count);
 1641 
 1642         error = bus_dmamem_alloc(sc->sc_dmat, size, PAGE_SIZE, 0, &seg,
 1643             1, &rseg, sc->sc_dmaflags);
 1644         if (error) {
 1645                 aprint_error("%s: unable to allocate mailboxes, error = %d\n",
 1646                     sc->sc_dev.dv_xname, error);
 1647                 goto bad_0;
 1648         }
 1649 
 1650         error = bus_dmamem_map(sc->sc_dmat, &seg, rseg, size,
 1651             (caddr_t *)&sc->sc_mbo, sc->sc_dmaflags | BUS_DMA_COHERENT);
 1652         if (error) {
 1653                 aprint_error("%s: unable to map mailboxes, error = %d\n",
 1654                     sc->sc_dev.dv_xname, error);
 1655                 goto bad_1;
 1656         }
 1657 
 1658         memset(sc->sc_mbo, 0, size);
 1659 
 1660         error = bus_dmamap_create(sc->sc_dmat, size, 1, size, 0,
 1661             sc->sc_dmaflags, &sc->sc_dmamap_mbox);
 1662         if (error) {
 1663                 aprint_error(
 1664                     "%s: unable to create mailbox DMA map, error = %d\n",
 1665                     sc->sc_dev.dv_xname, error);
 1666                 goto bad_2;
 1667         }
 1668 
 1669         error = bus_dmamap_load(sc->sc_dmat, sc->sc_dmamap_mbox,
 1670             sc->sc_mbo, size, NULL, 0);
 1671         if (error) {
 1672                 aprint_error("%s: unable to load mailbox DMA map, error = %d\n",
 1673                     sc->sc_dev.dv_xname, error);
 1674                 goto bad_3;
 1675         }
 1676 
 1677         sc->sc_mbi = (struct bha_mbx_in *)(sc->sc_mbo + sc->sc_mbox_count);
 1678 
 1679         return (0);
 1680 
 1681  bad_3:
 1682         bus_dmamap_destroy(sc->sc_dmat, sc->sc_dmamap_mbox);
 1683  bad_2:
 1684         bus_dmamem_unmap(sc->sc_dmat, (caddr_t)sc->sc_mbo, size);
 1685  bad_1:
 1686         bus_dmamem_free(sc->sc_dmat, &seg, rseg);
 1687  bad_0:
 1688         return (error);
 1689 }
 1690 
 1691 /*
 1692  * bha_collect_mbo:
 1693  *
 1694  *      Garbage collect mailboxes that are no longer in use.
 1695  */
 1696 static void
 1697 bha_collect_mbo(struct bha_softc *sc)
 1698 {
 1699         struct bha_mbx_out *mbo;
 1700 #ifdef BHADIAG
 1701         struct bha_ccb *ccb;
 1702 #endif
 1703 
 1704         mbo = sc->sc_cmbo;
 1705 
 1706         while (sc->sc_mbofull > 0) {
 1707                 BHA_MBO_SYNC(sc, mbo,
 1708                     BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
 1709                 if (mbo->cmd != BHA_MBO_FREE)
 1710                         break;
 1711 
 1712 #ifdef BHADIAG
 1713                 ccb = bha_ccb_phys_kv(sc, phystol(mbo->ccb_addr));
 1714                 ccb->flags &= ~CCB_SENDING;
 1715 #endif
 1716 
 1717                 --sc->sc_mbofull;
 1718                 mbo = bha_nextmbo(sc, mbo);
 1719         }
 1720 
 1721         sc->sc_cmbo = mbo;
 1722 }
 1723 
 1724 /*****************************************************************************
 1725  * CCB management functions
 1726  *****************************************************************************/
 1727 
 1728 static inline void
 1729 bha_reset_ccb(struct bha_ccb *ccb)
 1730 {
 1731 
 1732         ccb->flags = 0;
 1733 }
 1734 
 1735 /*
 1736  * bha_create_ccbs:
 1737  *
 1738  *      Create a set of CCBs.
 1739  *
 1740  *      We determine the target CCB count, and then keep creating them
 1741  *      until we reach the target, or fail.  CCBs that are allocated
 1742  *      but not "created" are left on the allocating list.
 1743  *
 1744  *      XXX AB_QUIET/AB_SILENT lossage here; this is called during
 1745  *      boot as well as at run-time.
 1746  */
 1747 static void
 1748 bha_create_ccbs(struct bha_softc *sc, int count)
 1749 {
 1750         struct bha_ccb_group *bcg;
 1751         struct bha_ccb *ccb;
 1752         bus_dma_segment_t seg;
 1753         bus_dmamap_t ccbmap;
 1754         int target, i, error, rseg;
 1755 
 1756         /*
 1757          * If the current CCB count is already the max number we're
 1758          * allowed to have, bail out now.
 1759          */
 1760         if (sc->sc_cur_ccbs == sc->sc_max_ccbs)
 1761                 return;
 1762 
 1763         /*
 1764          * Compute our target count, and clamp it down to the max
 1765          * number we're allowed to have.
 1766          */
 1767         target = sc->sc_cur_ccbs + count;
 1768         if (target > sc->sc_max_ccbs)
 1769                 target = sc->sc_max_ccbs;
 1770 
 1771         /*
 1772          * If there are CCBs on the allocating list, don't allocate a
 1773          * CCB group yet.
 1774          */
 1775         if (TAILQ_FIRST(&sc->sc_allocating_ccbs) != NULL)
 1776                 goto have_allocating_ccbs;
 1777 
 1778  allocate_group:
 1779         error = bus_dmamem_alloc(sc->sc_dmat, PAGE_SIZE,
 1780             PAGE_SIZE, 0, &seg, 1, &rseg, sc->sc_dmaflags | BUS_DMA_NOWAIT);
 1781         if (error) {
 1782                 printf("%s: unable to allocate CCB group, error = %d\n",
 1783                     sc->sc_dev.dv_xname, error);
 1784                 goto bad_0;
 1785         }
 1786 
 1787         error = bus_dmamem_map(sc->sc_dmat, &seg, rseg, PAGE_SIZE,
 1788             (void *)&bcg,
 1789             sc->sc_dmaflags | BUS_DMA_NOWAIT | BUS_DMA_COHERENT);
 1790         if (error) {
 1791                 printf("%s: unable to map CCB group, error = %d\n",
 1792                     sc->sc_dev.dv_xname, error);
 1793                 goto bad_1;
 1794         }
 1795 
 1796         memset(bcg, 0, PAGE_SIZE);
 1797 
 1798         error = bus_dmamap_create(sc->sc_dmat, PAGE_SIZE,
 1799             1, PAGE_SIZE, 0, sc->sc_dmaflags | BUS_DMA_NOWAIT, &ccbmap);
 1800         if (error) {
 1801                 printf("%s: unable to create CCB group DMA map, error = %d\n",
 1802                     sc->sc_dev.dv_xname, error);
 1803                 goto bad_2;
 1804         }
 1805 
 1806         error = bus_dmamap_load(sc->sc_dmat, ccbmap, bcg, PAGE_SIZE, NULL,
 1807             sc->sc_dmaflags | BUS_DMA_NOWAIT);
 1808         if (error) {
 1809                 printf("%s: unable to load CCB group DMA map, error = %d\n",
 1810                     sc->sc_dev.dv_xname, error);
 1811                 goto bad_3;
 1812         }
 1813 
 1814         bcg->bcg_dmamap = ccbmap;
 1815 
 1816 #ifdef DIAGNOSTIC
 1817         if (BHA_CCB_GROUP(&bcg->bcg_ccbs[0]) !=
 1818             BHA_CCB_GROUP(&bcg->bcg_ccbs[bha_ccbs_per_group - 1]))
 1819                 panic("bha_create_ccbs: CCB group size botch");
 1820 #endif
 1821 
 1822         /*
 1823          * Add all of the CCBs in this group to the allocating list.
 1824          */
 1825         for (i = 0; i < bha_ccbs_per_group; i++) {
 1826                 ccb = &bcg->bcg_ccbs[i];
 1827                 TAILQ_INSERT_TAIL(&sc->sc_allocating_ccbs, ccb, chain);
 1828         }
 1829 
 1830  have_allocating_ccbs:
 1831         /*
 1832          * Loop over the allocating list until we reach our CCB target.
 1833          * If we run out on the list, we'll allocate another group's
 1834          * worth.
 1835          */
 1836         while (sc->sc_cur_ccbs < target) {
 1837                 ccb = TAILQ_FIRST(&sc->sc_allocating_ccbs);
 1838                 if (ccb == NULL)
 1839                         goto allocate_group;
 1840                 if (bha_init_ccb(sc, ccb) != 0) {
 1841                         /*
 1842                          * We were unable to initialize the CCB.
 1843                          * This is likely due to a resource shortage,
 1844                          * so bail out now.
 1845                          */
 1846                         return;
 1847                 }
 1848         }
 1849 
 1850         /*
 1851          * If we got here, we've reached our target!
 1852          */
 1853         return;
 1854 
 1855  bad_3:
 1856         bus_dmamap_destroy(sc->sc_dmat, ccbmap);
 1857  bad_2:
 1858         bus_dmamem_unmap(sc->sc_dmat, (caddr_t)bcg, PAGE_SIZE);
 1859  bad_1:
 1860         bus_dmamem_free(sc->sc_dmat, &seg, rseg);
 1861  bad_0:
 1862         return;
 1863 }
 1864 
 1865 /*
 1866  * bha_init_ccb:
 1867  *
 1868  *      Initialize a CCB; helper function for bha_create_ccbs().
 1869  */
 1870 static int
 1871 bha_init_ccb(struct bha_softc *sc, struct bha_ccb *ccb)
 1872 {
 1873         struct bha_ccb_group *bcg = BHA_CCB_GROUP(ccb);
 1874         int hashnum, error;
 1875 
 1876         /*
 1877          * Create the DMA map for this CCB.
 1878          *
 1879          * XXX ALLOCNOW is a hack to prevent bounce buffer shortages
 1880          * XXX in the ISA case.  A better solution is needed.
 1881          */
 1882         error = bus_dmamap_create(sc->sc_dmat, BHA_MAXXFER, BHA_NSEG,
 1883             BHA_MAXXFER, 0, BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW | sc->sc_dmaflags,
 1884             &ccb->dmamap_xfer);
 1885         if (error) {
 1886                 printf("%s: unable to create CCB DMA map, error = %d\n",
 1887                     sc->sc_dev.dv_xname, error);
 1888                 return (error);
 1889         }
 1890 
 1891         TAILQ_REMOVE(&sc->sc_allocating_ccbs, ccb, chain);
 1892 
 1893         /*
 1894          * Put the CCB into the phystokv hash table.
 1895          */
 1896         ccb->hashkey = bcg->bcg_dmamap->dm_segs[0].ds_addr +
 1897             BHA_CCB_OFFSET(ccb);
 1898         hashnum = CCB_HASH(ccb->hashkey);
 1899         ccb->nexthash = sc->sc_ccbhash[hashnum];
 1900         sc->sc_ccbhash[hashnum] = ccb;
 1901         bha_reset_ccb(ccb);
 1902 
 1903         TAILQ_INSERT_HEAD(&sc->sc_free_ccb, ccb, chain);
 1904         sc->sc_cur_ccbs++;
 1905 
 1906         return (0);
 1907 }
 1908 
 1909 /*
 1910  * bha_get_ccb:
 1911  *
 1912  *      Get a CCB for the SCSI operation.  If there are none left,
 1913  *      wait until one becomes available, if we can.
 1914  */
 1915 static struct bha_ccb *
 1916 bha_get_ccb(struct bha_softc *sc)
 1917 {
 1918         struct bha_ccb *ccb;
 1919         int s;
 1920 
 1921         s = splbio();
 1922         ccb = TAILQ_FIRST(&sc->sc_free_ccb);
 1923         if (ccb != NULL) {
 1924                 TAILQ_REMOVE(&sc->sc_free_ccb, ccb, chain);
 1925                 ccb->flags |= CCB_ALLOC;
 1926         }
 1927         splx(s);
 1928         return (ccb);
 1929 }
 1930 
 1931 /*
 1932  * bha_free_ccb:
 1933  *
 1934  *      Put a CCB back onto the free list.
 1935  */
 1936 static void
 1937 bha_free_ccb(struct bha_softc *sc, struct bha_ccb *ccb)
 1938 {
 1939         int s;
 1940 
 1941         s = splbio();
 1942         bha_reset_ccb(ccb);
 1943         TAILQ_INSERT_HEAD(&sc->sc_free_ccb, ccb, chain);
 1944         splx(s);
 1945 }
 1946 
 1947 /*
 1948  * bha_ccb_phys_kv:
 1949  *
 1950  *      Given a CCB DMA address, locate the CCB in kernel virtual space.
 1951  */
 1952 static struct bha_ccb *
 1953 bha_ccb_phys_kv(struct bha_softc *sc, bus_addr_t ccb_phys)
 1954 {
 1955         int hashnum = CCB_HASH(ccb_phys);
 1956         struct bha_ccb *ccb = sc->sc_ccbhash[hashnum];
 1957 
 1958         while (ccb) {
 1959                 if (ccb->hashkey == ccb_phys)
 1960                         break;
 1961                 ccb = ccb->nexthash;
 1962         }
 1963         return (ccb);
 1964 }

Cache object: dc658fda406640c784c34c84e6a11f0c


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


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