root/dev/ic/bha.c

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

DEFINITIONS

This source file includes following definitions.
  1. bha_enqueue
  2. bha_dequeue
  3. bha_cmd
  4. bha_attach
  5. bha_finish_ccbs
  6. bha_intr
  7. bha_reset_ccb
  8. bha_free_ccb
  9. bha_init_ccb
  10. bha_create_ccbs
  11. bha_get_ccb
  12. bha_ccb_phys_kv
  13. bha_queue_ccb
  14. bha_collect_mbo
  15. bha_start_ccbs
  16. bha_done
  17. bha_find
  18. bha_disable_isacompat
  19. bha_init
  20. bha_inquire_setup_information
  21. bhaminphys
  22. bha_scsi_cmd
  23. bha_poll
  24. bha_timeout

    1 /*      $OpenBSD: bha.c,v 1.10 2007/04/10 17:47:55 miod Exp $   */
    2 /*      $NetBSD: bha.c,v 1.27 1998/11/19 21:53:00 thorpej Exp $ */
    3 
    4 #undef BHADEBUG
    5 #ifdef DDB
    6 #define integrate
    7 #else
    8 #define integrate       static inline
    9 #endif
   10 
   11 /*-
   12  * Copyright (c) 1997, 1998 The NetBSD Foundation, Inc.
   13  * All rights reserved.
   14  *
   15  * This code is derived from software contributed to The NetBSD Foundation
   16  * by Charles M. Hannum and by Jason R. Thorpe of the Numerical Aerospace
   17  * Simulation Facility, NASA Ames Research Center.
   18  *
   19  * Redistribution and use in source and binary forms, with or without
   20  * modification, are permitted provided that the following conditions
   21  * are met:
   22  * 1. Redistributions of source code must retain the above copyright
   23  *    notice, this list of conditions and the following disclaimer.
   24  * 2. Redistributions in binary form must reproduce the above copyright
   25  *    notice, this list of conditions and the following disclaimer in the
   26  *    documentation and/or other materials provided with the distribution.
   27  * 3. All advertising materials mentioning features or use of this software
   28  *    must display the following acknowledgement:
   29  *      This product includes software developed by the NetBSD
   30  *      Foundation, Inc. and its contributors.
   31  * 4. Neither the name of The NetBSD Foundation nor the names of its
   32  *    contributors may be used to endorse or promote products derived
   33  *    from this software without specific prior written permission.
   34  *
   35  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
   36  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
   37  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   38  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
   39  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   40  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   41  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   42  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   43  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   44  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   45  * POSSIBILITY OF SUCH DAMAGE.
   46  */
   47 
   48 /*
   49  * Originally written by Julian Elischer (julian@tfs.com)
   50  * for TRW Financial Systems for use under the MACH(2.5) operating system.
   51  *
   52  * TRW Financial Systems, in accordance with their agreement with Carnegie
   53  * Mellon University, makes this software available to CMU to distribute
   54  * or use in any manner that they see fit as long as this message is kept with
   55  * the software. For this reason TFS also grants any other persons or
   56  * organisations permission to use or modify this software.
   57  *
   58  * TFS supplies this software to be publicly redistributed
   59  * on the understanding that TFS is not responsible for the correct
   60  * functioning of this software in any circumstances.
   61  */
   62 
   63 #include <sys/types.h>
   64 #include <sys/param.h>
   65 #include <sys/systm.h>
   66 #include <sys/kernel.h>
   67 #include <sys/errno.h>
   68 #include <sys/ioctl.h>
   69 #include <sys/device.h>
   70 #include <sys/malloc.h>
   71 #include <sys/buf.h>
   72 #include <sys/proc.h>
   73 #include <sys/user.h>
   74 
   75 #include <machine/bus.h>
   76 #include <machine/intr.h>
   77 
   78 #include <scsi/scsi_all.h>
   79 #include <scsi/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 #define ISWIDE(sc)      ((sc)->sc_iswide)
   90 
   91 #ifdef BHADEBUG
   92 int     bha_debug = 1;
   93 #endif /* BHADEBUG */
   94 
   95 integrate void bha_finish_ccbs(struct bha_softc *);
   96 integrate void bha_reset_ccb(struct bha_softc *, struct bha_ccb *);
   97 void bha_free_ccb(struct bha_softc *, struct bha_ccb *);
   98 integrate int bha_init_ccb(struct bha_softc *, struct bha_ccb *);
   99 struct bha_ccb *bha_get_ccb(struct bha_softc *, int);
  100 struct bha_ccb *bha_ccb_phys_kv(struct bha_softc *, u_long);
  101 void bha_queue_ccb(struct bha_softc *, struct bha_ccb *);
  102 void bha_collect_mbo(struct bha_softc *);
  103 void bha_start_ccbs(struct bha_softc *);
  104 void bha_done(struct bha_softc *, struct bha_ccb *);
  105 int bha_init(struct bha_softc *);
  106 void bhaminphys(struct buf *);
  107 int bha_scsi_cmd(struct scsi_xfer *);
  108 int bha_poll(struct bha_softc *, struct scsi_xfer *, int);
  109 void bha_timeout(void *arg);
  110 int bha_create_ccbs(struct bha_softc *, struct bha_ccb *, int);
  111 void bha_enqueue(struct bha_softc *, struct scsi_xfer *, int);
  112 struct scsi_xfer *bha_dequeue(struct bha_softc *);
  113 
  114 struct cfdriver bha_cd = {
  115         NULL, "bha", DV_DULL
  116 };
  117 
  118 /* the below structure is so we have a default dev struct for out link struct */
  119 struct scsi_device bha_dev = {
  120         NULL,                   /* Use default error handler */
  121         NULL,                   /* have a queue, served by this */
  122         NULL,                   /* have no async handler */
  123         NULL,                   /* Use default 'done' routine */
  124 };
  125 
  126 #define BHA_RESET_TIMEOUT       2000    /* time to wait for reset (mSec) */
  127 #define BHA_ABORT_TIMEOUT       2000    /* time to wait for abort (mSec) */
  128 
  129 /*
  130  * Insert a scsi_xfer into the software queue.  We overload xs->free_list
  131  * to avoid having to allocate additional resources (since we're used
  132  * only during resource shortages anyhow.
  133  */
  134 void
  135 bha_enqueue(sc, xs, infront)
  136         struct bha_softc *sc;
  137         struct scsi_xfer *xs;
  138         int infront;
  139 {
  140 
  141         if (infront || LIST_EMPTY(&sc->sc_queue)) {
  142                 if (LIST_EMPTY(&sc->sc_queue))
  143                         sc->sc_queuelast = xs;
  144                 LIST_INSERT_HEAD(&sc->sc_queue, xs, free_list);
  145                 return;
  146         }
  147 
  148         LIST_INSERT_AFTER(sc->sc_queuelast, xs, free_list);
  149         sc->sc_queuelast = xs;
  150 }
  151 
  152 /*
  153  * Pull a scsi_xfer off the front of the software queue.
  154  */
  155 struct scsi_xfer *
  156 bha_dequeue(sc)
  157         struct bha_softc *sc;
  158 {
  159         struct scsi_xfer *xs;
  160 
  161         xs = LIST_FIRST(&sc->sc_queue);
  162         LIST_REMOVE(xs, free_list);
  163 
  164         if (LIST_EMPTY(&sc->sc_queue))
  165                 sc->sc_queuelast = NULL;
  166 
  167         return (xs);
  168 }
  169 
  170 /*
  171  * bha_cmd(iot, ioh, sc, icnt, ibuf, ocnt, obuf)
  172  *
  173  * Activate Adapter command
  174  *    icnt:   number of args (outbound bytes including opcode)
  175  *    ibuf:   argument buffer
  176  *    ocnt:   number of expected returned bytes
  177  *    obuf:   result buffer
  178  *    wait:   number of seconds to wait for response
  179  *
  180  * Performs an adapter command through the ports.  Not to be confused with a
  181  * scsi command, which is read in via the dma; one of the adapter commands
  182  * tells it to read in a scsi command.
  183  */
  184 int
  185 bha_cmd(iot, ioh, sc, icnt, ibuf, ocnt, obuf)
  186         bus_space_tag_t iot;
  187         bus_space_handle_t ioh;
  188         struct bha_softc *sc;
  189         int icnt, ocnt;
  190         u_char *ibuf, *obuf;
  191 {
  192         const char *name;
  193         register int i;
  194         int wait;
  195         u_char sts;
  196         u_char opcode = ibuf[0];
  197 
  198         if (sc != NULL)
  199                 name = sc->sc_dev.dv_xname;
  200         else
  201                 name = "(bha probe)";
  202 
  203         /*
  204          * Calculate a reasonable timeout for the command.
  205          */
  206         switch (opcode) {
  207         case BHA_INQUIRE_DEVICES:
  208         case BHA_INQUIRE_DEVICES_2:
  209                 wait = 90 * 20000;
  210                 break;
  211         default:
  212                 wait = 1 * 20000;
  213                 break;
  214         }
  215 
  216         /*
  217          * Wait for the adapter to go idle, unless it's one of
  218          * the commands which don't need this
  219          */
  220         if (opcode != BHA_MBO_INTR_EN) {
  221                 for (i = 20000; i; i--) {       /* 1 sec? */
  222                         sts = bus_space_read_1(iot, ioh, BHA_STAT_PORT);
  223                         if (sts & BHA_STAT_IDLE)
  224                                 break;
  225                         delay(50);
  226                 }
  227                 if (!i) {
  228                         printf("%s: bha_cmd, host not idle(0x%x)\n",
  229                             name, sts);
  230                         return (1);
  231                 }
  232         }
  233         /*
  234          * Now that it is idle, if we expect output, preflush the
  235          * queue feeding to us.
  236          */
  237         if (ocnt) {
  238                 while ((bus_space_read_1(iot, ioh, BHA_STAT_PORT)) &
  239                     BHA_STAT_DF)
  240                         bus_space_read_1(iot, ioh, BHA_DATA_PORT);
  241         }
  242         /*
  243          * Output the command and the number of arguments given
  244          * for each byte, first check the port is empty.
  245          */
  246         while (icnt--) {
  247                 for (i = wait; i; i--) {
  248                         sts = bus_space_read_1(iot, ioh, BHA_STAT_PORT);
  249                         if (!(sts & BHA_STAT_CDF))
  250                                 break;
  251                         delay(50);
  252                 }
  253                 if (!i) {
  254                         if (opcode != BHA_INQUIRE_REVISION)
  255                                 printf("%s: bha_cmd, cmd/data port full\n",
  256                                     name);
  257                         goto bad;
  258                 }
  259                 bus_space_write_1(iot, ioh, BHA_CMD_PORT, *ibuf++);
  260         }
  261         /*
  262          * If we expect input, loop that many times, each time,
  263          * looking for the data register to have valid data
  264          */
  265         while (ocnt--) {
  266                 for (i = wait; i; i--) {
  267                         sts = bus_space_read_1(iot, ioh, BHA_STAT_PORT);
  268                         if (sts & BHA_STAT_DF)
  269                                 break;
  270                         delay(50);
  271                 }
  272                 if (!i) {
  273                         if (opcode != BHA_INQUIRE_REVISION)
  274                                 printf("%s: bha_cmd, cmd/data port empty %d\n",
  275                                     name, ocnt);
  276                         goto bad;
  277                 }
  278                 *obuf++ = bus_space_read_1(iot, ioh, BHA_DATA_PORT);
  279         }
  280         /*
  281          * Wait for the board to report a finished instruction.
  282          * We may get an extra interrupt for the HACC signal, but this is
  283          * unimportant.
  284          */
  285         if (opcode != BHA_MBO_INTR_EN && opcode != BHA_MODIFY_IOPORT) {
  286                 for (i = 20000; i; i--) {       /* 1 sec? */
  287                         sts = bus_space_read_1(iot, ioh, BHA_INTR_PORT);
  288                         /* XXX Need to save this in the interrupt handler? */
  289                         if (sts & BHA_INTR_HACC)
  290                                 break;
  291                         delay(50);
  292                 }
  293                 if (!i) {
  294                         printf("%s: bha_cmd, host not finished(0x%x)\n",
  295                             name, sts);
  296                         return (1);
  297                 }
  298         }
  299         bus_space_write_1(iot, ioh, BHA_CTRL_PORT, BHA_CTRL_IRST);
  300         return (0);
  301 
  302 bad:
  303         bus_space_write_1(iot, ioh, BHA_CTRL_PORT, BHA_CTRL_SRST);
  304         return (1);
  305 }
  306 
  307 /*
  308  * Attach all the sub-devices we can find
  309  */
  310 void
  311 bha_attach(sc, bpd)
  312         struct bha_softc *sc;
  313         struct bha_probe_data *bpd;
  314 {
  315         struct scsibus_attach_args saa;
  316         int s;
  317 
  318         /*
  319          * Fill in the adapter.
  320          */
  321         sc->sc_adapter.scsi_cmd = bha_scsi_cmd;
  322         sc->sc_adapter.scsi_minphys = bhaminphys;
  323 
  324         /*
  325          * fill in the prototype scsi_link.
  326          */
  327         sc->sc_link.adapter_softc = sc;
  328         sc->sc_link.adapter_target = bpd->sc_scsi_dev;
  329         sc->sc_link.adapter = &sc->sc_adapter;
  330         sc->sc_link.device = &bha_dev;
  331         sc->sc_link.openings = 4;
  332 
  333         TAILQ_INIT(&sc->sc_free_ccb);
  334         TAILQ_INIT(&sc->sc_waiting_ccb);
  335         LIST_INIT(&sc->sc_queue);
  336 
  337         s = splbio();
  338         bha_inquire_setup_information(sc);
  339 
  340         printf("%s: model BT-%s, firmware %s\n", sc->sc_dev.dv_xname,
  341             sc->sc_model, sc->sc_firmware);
  342 
  343         if (bha_init(sc) != 0) {
  344                 /* Error during initialization! */
  345                 splx(s);
  346                 return;
  347         }
  348 
  349         splx(s);
  350 
  351         bzero(&saa, sizeof(saa));
  352         saa.saa_sc_link = &sc->sc_link;
  353 
  354         /*
  355          * ask the adapter what subunits are present
  356          */
  357         config_found(&sc->sc_dev, &saa, scsiprint);
  358 }
  359 
  360 integrate void
  361 bha_finish_ccbs(sc)
  362         struct bha_softc *sc;
  363 {
  364         struct bha_mbx_in *wmbi;
  365         struct bha_ccb *ccb;
  366         int i;
  367 
  368         wmbi = wmbx->tmbi;
  369 
  370         bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap_control,
  371             0, sc->sc_dmamap_control->dm_mapsize,
  372             BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
  373 
  374         if (wmbi->comp_stat == BHA_MBI_FREE) {
  375                 for (i = 0; i < BHA_MBX_SIZE; i++) {
  376                         if (wmbi->comp_stat != BHA_MBI_FREE) {
  377                                 printf("%s: mbi not in round-robin order\n",
  378                                     sc->sc_dev.dv_xname);
  379                                 goto AGAIN;
  380                         }
  381                         bha_nextmbx(wmbi, wmbx, mbi);
  382                         bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap_control,
  383                             0, sc->sc_dmamap_control->dm_mapsize,
  384                             BUS_DMASYNC_POSTREAD);
  385                 }
  386 #ifdef BHADIAGnot
  387                 printf("%s: mbi interrupt with no full mailboxes\n",
  388                     sc->sc_dev.dv_xname);
  389 #endif
  390                 return;
  391         }
  392 
  393 AGAIN:
  394         do {
  395                 ccb = bha_ccb_phys_kv(sc, phystol(wmbi->ccb_addr));
  396                 if (!ccb) {
  397                         printf("%s: bad mbi ccb pointer; skipping\n",
  398                             sc->sc_dev.dv_xname);
  399                         goto next;
  400                 }
  401 
  402                 bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap_control,
  403                     0, sc->sc_dmamap_control->dm_mapsize,
  404                     BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
  405 
  406 #ifdef BHADEBUG
  407                 if (bha_debug) {
  408                         u_int8_t *cp = ccb->scsi_cmd.bytes;
  409                         printf("op=%x %x %x %x %x %x\n",
  410                                 ccb->scsi_cmd.opcode,
  411                                 cp[0], cp[1], cp[2], cp[3], cp[4]);
  412                         printf("stat %x for mbi addr = 0x%08x, ",
  413                                 wmbi->comp_stat, wmbi);
  414                         printf("ccb addr = 0x%x\n", ccb);
  415                 }
  416 #endif /* BHADEBUG */
  417 
  418                 switch (wmbi->comp_stat) {
  419                 case BHA_MBI_OK:
  420                 case BHA_MBI_ERROR:
  421                         if ((ccb->flags & CCB_ABORT) != 0) {
  422                                 /*
  423                                  * If we already started an abort, wait for it
  424                                  * to complete before clearing the CCB.  We
  425                                  * could instead just clear CCB_SENDING, but
  426                                  * what if the mailbox was already received?
  427                                  * The worst that happens here is that we clear
  428                                  * the CCB a bit later than we need to.  BFD.
  429                                  */
  430                                 goto next;
  431                         }
  432                         break;
  433 
  434                 case BHA_MBI_ABORT:
  435                 case BHA_MBI_UNKNOWN:
  436                         /*
  437                          * Even if the CCB wasn't found, we clear it anyway.
  438                          * See preceding comment.
  439                          */
  440                         break;
  441 
  442                 default:
  443                         printf("%s: bad mbi status %02x; skipping\n",
  444                             sc->sc_dev.dv_xname, wmbi->comp_stat);
  445                         goto next;
  446                 }
  447 
  448                 timeout_del(&ccb->xs->stimeout);
  449                 bha_done(sc, ccb);
  450 
  451         next:
  452                 wmbi->comp_stat = BHA_MBI_FREE;
  453                 bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap_control,
  454                     0, sc->sc_dmamap_control->dm_mapsize,
  455                     BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
  456                 bha_nextmbx(wmbi, wmbx, mbi);
  457                 bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap_control,
  458                     0, sc->sc_dmamap_control->dm_mapsize,
  459                     BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
  460         } while (wmbi->comp_stat != BHA_MBI_FREE);
  461 
  462         wmbx->tmbi = wmbi;
  463 }
  464 
  465 /*
  466  * Catch an interrupt from the adaptor
  467  */
  468 int
  469 bha_intr(arg)
  470         void *arg;
  471 {
  472         struct bha_softc *sc = arg;
  473         bus_space_tag_t iot = sc->sc_iot;
  474         bus_space_handle_t ioh = sc->sc_ioh;
  475         u_char sts;
  476 
  477 #ifdef BHADEBUG
  478         printf("%s: bha_intr ", sc->sc_dev.dv_xname);
  479 #endif /* BHADEBUG */
  480 
  481         /*
  482          * First acknowledge the interrupt, Then if it's not telling about
  483          * a completed operation just return.
  484          */
  485         sts = bus_space_read_1(iot, ioh, BHA_INTR_PORT);
  486         if ((sts & BHA_INTR_ANYINTR) == 0)
  487                 return (0);
  488         bus_space_write_1(iot, ioh, BHA_CTRL_PORT, BHA_CTRL_IRST);
  489 
  490 #ifdef BHADIAG
  491         /* Make sure we clear CCB_SENDING before finishing a CCB. */
  492         bha_collect_mbo(sc);
  493 #endif
  494 
  495         /* Mail box out empty? */
  496         if (sts & BHA_INTR_MBOA) {
  497                 struct bha_toggle toggle;
  498 
  499                 toggle.cmd.opcode = BHA_MBO_INTR_EN;
  500                 toggle.cmd.enable = 0;
  501                 bha_cmd(iot, ioh, sc,
  502                     sizeof(toggle.cmd), (u_char *)&toggle.cmd,
  503                     0, (u_char *)0);
  504                 bha_start_ccbs(sc);
  505         }
  506 
  507         /* Mail box in full? */
  508         if (sts & BHA_INTR_MBIF)
  509                 bha_finish_ccbs(sc);
  510 
  511         return (1);
  512 }
  513 
  514 integrate void
  515 bha_reset_ccb(sc, ccb)
  516         struct bha_softc *sc;
  517         struct bha_ccb *ccb;
  518 {
  519 
  520         ccb->flags = 0;
  521 }
  522 
  523 /*
  524  * A ccb is put onto the free list.
  525  */
  526 void
  527 bha_free_ccb(sc, ccb)
  528         struct bha_softc *sc;
  529         struct bha_ccb *ccb;
  530 {
  531         int s;
  532 
  533         s = splbio();
  534 
  535         bha_reset_ccb(sc, ccb);
  536         TAILQ_INSERT_HEAD(&sc->sc_free_ccb, ccb, chain);
  537 
  538         /*
  539          * If there were none, wake anybody waiting for one to come free,
  540          * starting with queued entries.
  541          */
  542         if (TAILQ_NEXT(ccb, chain) == NULL)
  543                 wakeup(&sc->sc_free_ccb);
  544 
  545         splx(s);
  546 }
  547 
  548 integrate int
  549 bha_init_ccb(sc, ccb)
  550         struct bha_softc *sc;
  551         struct bha_ccb *ccb;
  552 {
  553         bus_dma_tag_t dmat = sc->sc_dmat;
  554         int hashnum, error;
  555 
  556         /*
  557          * Create the DMA map for this CCB.
  558          */
  559         error = bus_dmamap_create(dmat, BHA_MAXXFER, BHA_NSEG, BHA_MAXXFER,
  560             0, BUS_DMA_NOWAIT|BUS_DMA_ALLOCNOW | sc->sc_dmaflags,
  561             &ccb->dmamap_xfer);
  562         if (error) {
  563                 printf("%s: unable to create ccb DMA map, error = %d\n",
  564                     sc->sc_dev.dv_xname, error);
  565                 return (error);
  566         }
  567 
  568         /*
  569          * put in the phystokv hash table
  570          * Never gets taken out.
  571          */
  572         ccb->hashkey = sc->sc_dmamap_control->dm_segs[0].ds_addr +
  573             BHA_CCB_OFF(ccb);
  574         hashnum = CCB_HASH(ccb->hashkey);
  575         ccb->nexthash = sc->sc_ccbhash[hashnum];
  576         sc->sc_ccbhash[hashnum] = ccb;
  577         bha_reset_ccb(sc, ccb);
  578         return (0);
  579 }
  580 
  581 /*
  582  * Create a set of ccbs and add them to the free list.  Called once
  583  * by bha_init().  We return the number of CCBs successfully created.
  584  */
  585 int
  586 bha_create_ccbs(sc, ccbstore, count)
  587         struct bha_softc *sc;
  588         struct bha_ccb *ccbstore;
  589         int count;
  590 {
  591         struct bha_ccb *ccb;
  592         int i, error;
  593 
  594         bzero(ccbstore, sizeof(struct bha_ccb) * count);
  595         for (i = 0; i < count; i++) {
  596                 ccb = &ccbstore[i];
  597                 if ((error = bha_init_ccb(sc, ccb)) != 0) {
  598                         printf("%s: unable to initialize ccb, error = %d\n",
  599                             sc->sc_dev.dv_xname, error);
  600                         goto out;
  601                 }
  602                 TAILQ_INSERT_TAIL(&sc->sc_free_ccb, ccb, chain);
  603         }
  604  out:
  605         return (i);
  606 }
  607 
  608 /*
  609  * Get a free ccb
  610  *
  611  * If there are none, see if we can allocate a new one.  If so, put it in
  612  * the hash table too otherwise either return an error or sleep.
  613  */
  614 struct bha_ccb *
  615 bha_get_ccb(sc, flags)
  616         struct bha_softc *sc;
  617         int flags;
  618 {
  619         struct bha_ccb *ccb;
  620         int s;
  621 
  622         s = splbio();
  623 
  624         /*
  625          * If we can and have to, sleep waiting for one to come free
  626          * but only if we can't allocate a new one.
  627          */
  628         for (;;) {
  629                 ccb = TAILQ_FIRST(&sc->sc_free_ccb);
  630                 if (ccb) {
  631                         TAILQ_REMOVE(&sc->sc_free_ccb, ccb, chain);
  632                         break;
  633                 }
  634                 if ((flags & SCSI_NOSLEEP) != 0)
  635                         goto out;
  636                 tsleep(&sc->sc_free_ccb, PRIBIO, "bhaccb", 0);
  637         }
  638 
  639         ccb->flags |= CCB_ALLOC;
  640 
  641 out:
  642         splx(s);
  643         return (ccb);
  644 }
  645 
  646 /*
  647  * Given a physical address, find the ccb that it corresponds to.
  648  */
  649 struct bha_ccb *
  650 bha_ccb_phys_kv(sc, ccb_phys)
  651         struct bha_softc *sc;
  652         u_long ccb_phys;
  653 {
  654         int hashnum = CCB_HASH(ccb_phys);
  655         struct bha_ccb *ccb = sc->sc_ccbhash[hashnum];
  656 
  657         while (ccb) {
  658                 if (ccb->hashkey == ccb_phys)
  659                         break;
  660                 ccb = ccb->nexthash;
  661         }
  662         return (ccb);
  663 }
  664 
  665 /*
  666  * Queue a CCB to be sent to the controller, and send it if possible.
  667  */
  668 void
  669 bha_queue_ccb(sc, ccb)
  670         struct bha_softc *sc;
  671         struct bha_ccb *ccb;
  672 {
  673 
  674         timeout_set(&ccb->xs->stimeout, bha_timeout, ccb);
  675         TAILQ_INSERT_TAIL(&sc->sc_waiting_ccb, ccb, chain);
  676         bha_start_ccbs(sc);
  677 }
  678 
  679 /*
  680  * Garbage collect mailboxes that are no longer in use.
  681  */
  682 void
  683 bha_collect_mbo(sc)
  684         struct bha_softc *sc;
  685 {
  686         struct bha_mbx_out *wmbo;       /* Mail Box Out pointer */
  687 #ifdef BHADIAG
  688         struct bha_ccb *ccb;
  689 #endif
  690 
  691         wmbo = wmbx->cmbo;
  692 
  693         while (sc->sc_mbofull > 0) {
  694                 bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap_control,
  695                     0, sc->sc_dmamap_control->dm_mapsize,
  696                     BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
  697                 if (wmbo->cmd != BHA_MBO_FREE)
  698                         break;
  699 
  700 #ifdef BHADIAG
  701                 ccb = bha_ccb_phys_kv(sc, phystol(wmbo->ccb_addr));
  702                 ccb->flags &= ~CCB_SENDING;
  703 #endif
  704 
  705                 --sc->sc_mbofull;
  706                 bha_nextmbx(wmbo, wmbx, mbo);
  707         }
  708 
  709         wmbx->cmbo = wmbo;
  710 }
  711 
  712 /*
  713  * Send as many CCBs as we have empty mailboxes for.
  714  */
  715 void
  716 bha_start_ccbs(sc)
  717         struct bha_softc *sc;
  718 {
  719         bus_space_tag_t iot = sc->sc_iot;
  720         bus_space_handle_t ioh = sc->sc_ioh;
  721         struct bha_mbx_out *wmbo;       /* Mail Box Out pointer */
  722         struct bha_ccb *ccb;
  723         struct scsi_xfer *xs;
  724 
  725         wmbo = wmbx->tmbo;
  726 
  727         while ((ccb = TAILQ_FIRST(&sc->sc_waiting_ccb)) != NULL) {
  728 
  729                 xs = ccb->xs;
  730                 if (sc->sc_mbofull >= BHA_MBX_SIZE) {
  731                         bha_collect_mbo(sc);
  732                         if (sc->sc_mbofull >= BHA_MBX_SIZE) {
  733                                 struct bha_toggle toggle;
  734 
  735                                 toggle.cmd.opcode = BHA_MBO_INTR_EN;
  736                                 toggle.cmd.enable = 1;
  737                                 bha_cmd(iot, ioh, sc,
  738                                     sizeof(toggle.cmd), (u_char *)&toggle.cmd,
  739                                     0, (u_char *)0);
  740                                 break;
  741                         }
  742                 }
  743 
  744                 TAILQ_REMOVE(&sc->sc_waiting_ccb, ccb, chain);
  745 #ifdef BHADIAG
  746                 ccb->flags |= CCB_SENDING;
  747 #endif
  748 
  749                 /* Link ccb to mbo. */
  750                 ltophys(sc->sc_dmamap_control->dm_segs[0].ds_addr +
  751                     BHA_CCB_OFF(ccb), wmbo->ccb_addr);
  752                 if (ccb->flags & CCB_ABORT)
  753                         wmbo->cmd = BHA_MBO_ABORT;
  754                 else
  755                         wmbo->cmd = BHA_MBO_START;
  756 
  757                 bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap_control,
  758                     0, sc->sc_dmamap_control->dm_mapsize,
  759                     BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
  760 
  761                 /* Tell the card to poll immediately. */
  762                 bus_space_write_1(iot, ioh, BHA_CMD_PORT, BHA_START_SCSI);
  763 
  764                 if ((xs->flags & SCSI_POLL) == 0)
  765                         timeout_add(&xs->stimeout, (ccb->timeout * hz) / 1000);
  766 
  767                 ++sc->sc_mbofull;
  768                 bha_nextmbx(wmbo, wmbx, mbo);
  769         }
  770 
  771         wmbx->tmbo = wmbo;
  772 }
  773 
  774 /*
  775  * We have a ccb which has been processed by the
  776  * adaptor, now we look to see how the operation
  777  * went. Wake up the owner if waiting
  778  */
  779 void
  780 bha_done(sc, ccb)
  781         struct bha_softc *sc;
  782         struct bha_ccb *ccb;
  783 {
  784         bus_dma_tag_t dmat = sc->sc_dmat;
  785         struct scsi_sense_data *s1, *s2;
  786         struct scsi_xfer *xs = ccb->xs;
  787 
  788         SC_DEBUG(xs->sc_link, SDEV_DB2, ("bha_done\n"));
  789 
  790         /*
  791          * If we were a data transfer, unload the map that described
  792          * the data buffer.
  793          */
  794         if (xs->datalen) {
  795                 bus_dmamap_sync(dmat, ccb->dmamap_xfer,
  796                     0, ccb->dmamap_xfer->dm_mapsize,
  797                     (xs->flags & SCSI_DATA_IN) ? BUS_DMASYNC_POSTREAD :
  798                     BUS_DMASYNC_POSTWRITE);
  799                 bus_dmamap_unload(dmat, ccb->dmamap_xfer);
  800         }
  801 
  802         /*
  803          * Otherwise, put the results of the operation
  804          * into the xfer and call whoever started it
  805          */
  806 #ifdef BHADIAG
  807         if (ccb->flags & CCB_SENDING) {
  808                 printf("%s: exiting ccb still in transit!\n",
  809                     sc->sc_dev.dv_xname);
  810                 Debugger();
  811                 return;
  812         }
  813 #endif
  814         if ((ccb->flags & CCB_ALLOC) == 0) {
  815                 printf("%s: exiting ccb not allocated!\n",
  816                     sc->sc_dev.dv_xname);
  817                 Debugger();
  818                 return;
  819         }
  820         if (xs->error == XS_NOERROR) {
  821                 if (ccb->host_stat != BHA_OK) {
  822                         switch (ccb->host_stat) {
  823                         case BHA_SEL_TIMEOUT:   /* No response */
  824                                 xs->error = XS_SELTIMEOUT;
  825                                 break;
  826                         default:        /* Other scsi protocol messes */
  827                                 printf("%s: host_stat %x\n",
  828                                     sc->sc_dev.dv_xname, ccb->host_stat);
  829                                 xs->error = XS_DRIVER_STUFFUP;
  830                                 break;
  831                         }
  832                 } else if (ccb->target_stat != SCSI_OK) {
  833                         switch (ccb->target_stat) {
  834                         case SCSI_CHECK:
  835                                 s1 = &ccb->scsi_sense;
  836                                 s2 = &xs->sense;
  837                                 *s2 = *s1;
  838                                 xs->error = XS_SENSE;
  839                                 break;
  840                         case SCSI_BUSY:
  841                                 xs->error = XS_BUSY;
  842                                 break;
  843                         default:
  844                                 printf("%s: target_stat %x\n",
  845                                     sc->sc_dev.dv_xname, ccb->target_stat);
  846                                 xs->error = XS_DRIVER_STUFFUP;
  847                                 break;
  848                         }
  849                 } else
  850                         xs->resid = 0;
  851         }
  852         bha_free_ccb(sc, ccb);
  853         xs->flags |= ITSDONE;
  854         scsi_done(xs);
  855 
  856         /*
  857          * If there are queue entries in the software queue, try to
  858          * run the first one.  We should be more or less guaranteed
  859          * to succeed, since we just freed a CCB.
  860          *
  861          * NOTE: bha_scsi_cmd() relies on our calling it with
  862          * the first entry in the queue.
  863          */
  864         if ((xs = LIST_FIRST(&sc->sc_queue)) != NULL)
  865                 (void) bha_scsi_cmd(xs);
  866 }
  867 
  868 /*
  869  * Find the board and find its irq/drq
  870  */
  871 int
  872 bha_find(iot, ioh, sc)
  873         bus_space_tag_t iot;
  874         bus_space_handle_t ioh;
  875         struct bha_probe_data *sc;
  876 {
  877         int i, iswide;
  878         u_char sts;
  879         struct bha_extended_inquire inquire;
  880         struct bha_config config;
  881         int irq, drq;
  882 
  883         /* Check something is at the ports we need to access */
  884         sts = bus_space_read_1(iot, ioh, BHA_STAT_PORT);
  885         if (sts == 0xFF) {
  886 #ifdef BHADEBUG
  887                 if (bha_debug)
  888                         printf("bha_find: Not present\n");
  889 #endif /* BHADEBUG */
  890                 return (0);
  891         }
  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         for (i = BHA_RESET_TIMEOUT; i--;) {
  902                 delay(100);
  903                 sts = bus_space_read_1(iot, ioh, BHA_STAT_PORT);
  904                 if (sts == (BHA_STAT_IDLE | BHA_STAT_INIT))
  905                         break;
  906         }
  907         if (i < 0) {
  908 #ifdef BHADEBUG
  909                 if (bha_debug)
  910                         printf("bha_find: No answer from board a=%x sts=%b\n",
  911                             ioh, sts, BHA_STAT_BITS);
  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, NULL,
  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         /* Note if we have a wide bus. */
  974         iswide = inquire.reply.scsi_flags & BHA_SCSI_WIDE;
  975 
  976         /*
  977          * Assume we have a board at this stage setup dma channel from
  978          * jumpers and save int level
  979          */
  980         delay(1000);
  981         config.cmd.opcode = BHA_INQUIRE_CONFIG;
  982         bha_cmd(iot, ioh, NULL,
  983             sizeof(config.cmd), (u_char *)&config.cmd,
  984             sizeof(config.reply), (u_char *)&config.reply);
  985         switch (config.reply.chan) {
  986         case EISADMA:
  987                 drq = -1;
  988                 break;
  989         case CHAN0:
  990                 drq = 0;
  991                 break;
  992         case CHAN5:
  993                 drq = 5;
  994                 break;
  995         case CHAN6:
  996                 drq = 6;
  997                 break;
  998         case CHAN7:
  999                 drq = 7;
 1000                 break;
 1001         default:
 1002                 printf("bha_find: illegal drq setting %x\n",
 1003                     config.reply.chan);
 1004                 return (0);
 1005         }
 1006 
 1007         switch (config.reply.intr) {
 1008         case INT9:
 1009                 irq = 9;
 1010                 break;
 1011         case INT10:
 1012                 irq = 10;
 1013                 break;
 1014         case INT11:
 1015                 irq = 11;
 1016                 break;
 1017         case INT12:
 1018                 irq = 12;
 1019                 break;
 1020         case INT14:
 1021                 irq = 14;
 1022                 break;
 1023         case INT15:
 1024                 irq = 15;
 1025                 break;
 1026         default:
 1027                 printf("bha_find: illegal irq setting %x\n",
 1028                     config.reply.intr);
 1029                 return (0);
 1030         }
 1031 
 1032         /* if we want to fill in softc, do so now */
 1033         if (sc != NULL) {
 1034                 sc->sc_irq = irq;
 1035                 sc->sc_drq = drq;
 1036                 sc->sc_scsi_dev = config.reply.scsi_dev;
 1037                 sc->sc_iswide = iswide;
 1038         }
 1039 
 1040         return (1);
 1041 }
 1042 
 1043 
 1044 /*
 1045  * Disable the ISA-compatibility ioports on PCI bha devices,
 1046  * to ensure they're not autoconfigured a second time as an ISA bha.
 1047  */
 1048 int
 1049 bha_disable_isacompat(sc)
 1050         struct bha_softc *sc;
 1051 {
 1052         struct bha_isadisable isa_disable;
 1053 
 1054         isa_disable.cmd.opcode = BHA_MODIFY_IOPORT;
 1055         isa_disable.cmd.modifier = BHA_IOMODIFY_DISABLE1;
 1056         bha_cmd(sc->sc_iot, sc->sc_ioh, sc,
 1057             sizeof(isa_disable.cmd), (u_char *)&isa_disable.cmd,
 1058             0, (u_char *)0);
 1059         return (0);
 1060 }
 1061 
 1062 
 1063 /*
 1064  * Start the board, ready for normal operation
 1065  */
 1066 int
 1067 bha_init(sc)
 1068         struct bha_softc *sc;
 1069 {
 1070         bus_space_tag_t iot = sc->sc_iot;
 1071         bus_space_handle_t ioh = sc->sc_ioh;
 1072         bus_dma_segment_t seg;
 1073         struct bha_devices devices;
 1074         struct bha_setup setup;
 1075         struct bha_mailbox mailbox;
 1076         struct bha_period period;
 1077         int error, i, j, initial_ccbs, rlen, rseg;
 1078 
 1079         /* Enable round-robin scheme - appeared at firmware rev. 3.31. */
 1080         if (strcmp(sc->sc_firmware, "3.31") >= 0) {
 1081                 struct bha_toggle toggle;
 1082 
 1083                 toggle.cmd.opcode = BHA_ROUND_ROBIN;
 1084                 toggle.cmd.enable = 1;
 1085                 bha_cmd(iot, ioh, sc,
 1086                     sizeof(toggle.cmd), (u_char *)&toggle.cmd,
 1087                     0, (u_char *)0);
 1088         }
 1089 
 1090         /*
 1091          * Inquire installed devices (to force synchronous negotiation).
 1092          */
 1093 
 1094         /*
 1095          * Poll targets 0 - 7.
 1096          */
 1097         devices.cmd.opcode = BHA_INQUIRE_DEVICES;
 1098         bha_cmd(iot, ioh, sc,
 1099             sizeof(devices.cmd), (u_char *)&devices.cmd,
 1100             sizeof(devices.reply), (u_char *)&devices.reply);
 1101 
 1102         /* Count installed units. */
 1103         initial_ccbs = 0;
 1104         for (i = 0; i < 8; i++) {
 1105                 for (j = 0; j < 8; j++) {
 1106                         if (((devices.reply.lun_map[i] >> j) & 1) == 1)
 1107                                 initial_ccbs++;
 1108                 }
 1109         }
 1110 
 1111         /*
 1112          * Poll targets 8 - 15 if we have a wide bus.
 1113          */
 1114         if (ISWIDE(sc)) {
 1115                 devices.cmd.opcode = BHA_INQUIRE_DEVICES_2;
 1116                 bha_cmd(iot, ioh, sc,
 1117                     sizeof(devices.cmd), (u_char *)&devices.cmd,
 1118                     sizeof(devices.reply), (u_char *)&devices.reply);
 1119 
 1120                 for (i = 0; i < 8; i++) {
 1121                         for (j = 0; j < 8; j++) {
 1122                                 if (((devices.reply.lun_map[i] >> j) & 1) == 1)
 1123                                         initial_ccbs++;
 1124                         }
 1125                 }
 1126         }
 1127 
 1128         initial_ccbs *= sc->sc_link.openings;
 1129         if (initial_ccbs > BHA_CCB_MAX)
 1130                 initial_ccbs = BHA_CCB_MAX;
 1131         if (initial_ccbs == 0)  /* yes, this can happen */
 1132                 initial_ccbs = sc->sc_link.openings;
 1133 
 1134         /* Obtain setup information from. */
 1135         rlen = sizeof(setup.reply) +
 1136             (ISWIDE(sc) ? sizeof(setup.reply_w) : 0);
 1137         setup.cmd.opcode = BHA_INQUIRE_SETUP;
 1138         setup.cmd.len = rlen;
 1139         bha_cmd(iot, ioh, sc,
 1140             sizeof(setup.cmd), (u_char *)&setup.cmd,
 1141             rlen, (u_char *)&setup.reply);
 1142 
 1143         printf("%s: %s, %s\n", sc->sc_dev.dv_xname,
 1144             setup.reply.sync_neg ? "sync" : "async",
 1145             setup.reply.parity ? "parity" : "no parity");
 1146 
 1147         for (i = 0; i < 8; i++)
 1148                 period.reply.period[i] = setup.reply.sync[i].period * 5 + 20;
 1149         if (ISWIDE(sc)) {
 1150                 for (i = 0; i < 8; i++)
 1151                         period.reply_w.period[i] =
 1152                             setup.reply_w.sync_high[i].period * 5 + 20;
 1153         }
 1154 
 1155         if (sc->sc_firmware[0] >= '3') {
 1156                 rlen = sizeof(period.reply) +
 1157                     (ISWIDE(sc) ? sizeof(period.reply_w) : 0);
 1158                 period.cmd.opcode = BHA_INQUIRE_PERIOD;
 1159                 period.cmd.len = sizeof(period.reply);
 1160                 bha_cmd(iot, ioh, sc,
 1161                     sizeof(period.cmd), (u_char *)&period.cmd,
 1162                     rlen, (u_char *)&period.reply);
 1163         }
 1164 
 1165         for (i = 0; i < 8; i++) {
 1166                 if (!setup.reply.sync[i].valid ||
 1167                     (!setup.reply.sync[i].offset &&
 1168                      !setup.reply.sync[i].period))
 1169                         continue;
 1170                 printf("%s targ %d: sync, offset %d, period %dnsec\n",
 1171                     sc->sc_dev.dv_xname, i,
 1172                     setup.reply.sync[i].offset, period.reply.period[i] * 10);
 1173         }
 1174         if (ISWIDE(sc)) {
 1175                 for (i = 0; i < 8; i++) {
 1176                         if (!setup.reply_w.sync_high[i].valid ||
 1177                             (!setup.reply_w.sync_high[i].offset &&
 1178                              !setup.reply_w.sync_high[i].period))
 1179                                 continue;
 1180                         printf("%s targ %d: sync, offset %d, period %dnsec\n",
 1181                             sc->sc_dev.dv_xname, i + 8,
 1182                             setup.reply_w.sync_high[i].offset,
 1183                             period.reply_w.period[i] * 10);
 1184                 }
 1185         }
 1186 
 1187         /*
 1188          * Allocate the mailbox and control blocks.
 1189          */
 1190         if ((error = bus_dmamem_alloc(sc->sc_dmat, sizeof(struct bha_control),
 1191             NBPG, 0, &seg, 1, &rseg, BUS_DMA_NOWAIT)) != 0) {
 1192                 printf("%s: unable to allocate control structures, "
 1193                     "error = %d\n", sc->sc_dev.dv_xname, error);
 1194                 return (error);
 1195         }
 1196         if ((error = bus_dmamem_map(sc->sc_dmat, &seg, rseg,
 1197             sizeof(struct bha_control), (caddr_t *)&sc->sc_control,
 1198             BUS_DMA_NOWAIT)) != 0) {
 1199                 printf("%s: unable to map control structures, error = %d\n",
 1200                     sc->sc_dev.dv_xname, error);
 1201                 return (error);
 1202         }
 1203 
 1204         /*
 1205          * Create and load the DMA map used for the mailbox and
 1206          * control blocks.
 1207          */
 1208         if ((error = bus_dmamap_create(sc->sc_dmat, sizeof(struct bha_control),
 1209             1, sizeof(struct bha_control), 0, BUS_DMA_NOWAIT | sc->sc_dmaflags,
 1210             &sc->sc_dmamap_control)) != 0) {
 1211                 printf("%s: unable to create control DMA map, error = %d\n",
 1212                     sc->sc_dev.dv_xname, error);
 1213                 return (error);
 1214         }
 1215         if ((error = bus_dmamap_load(sc->sc_dmat, sc->sc_dmamap_control,
 1216             sc->sc_control, sizeof(struct bha_control), NULL,
 1217             BUS_DMA_NOWAIT)) != 0) {
 1218                 printf("%s: unable to load control DMA map, error = %d\n",
 1219                     sc->sc_dev.dv_xname, error);
 1220                 return (error);
 1221         }
 1222 
 1223         /*
 1224          * Initialize the control blocks.
 1225          */
 1226         i = bha_create_ccbs(sc, sc->sc_control->bc_ccbs, initial_ccbs);
 1227         if (i == 0) {
 1228                 printf("%s: unable to create control blocks\n",
 1229                     sc->sc_dev.dv_xname);
 1230                 return (ENOMEM);
 1231         } else if (i != initial_ccbs) {
 1232                 printf("%s: WARNING: only %d of %d control blocks created\n",
 1233                     sc->sc_dev.dv_xname, i, initial_ccbs);
 1234         }
 1235 
 1236         /*
 1237          * Set up initial mail box for round-robin operation.
 1238          */
 1239         for (i = 0; i < BHA_MBX_SIZE; i++) {
 1240                 wmbx->mbo[i].cmd = BHA_MBO_FREE;
 1241                 bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap_control,
 1242                     0, sc->sc_dmamap_control->dm_mapsize,
 1243                     BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
 1244                 wmbx->mbi[i].comp_stat = BHA_MBI_FREE;
 1245                 bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap_control,
 1246                     0, sc->sc_dmamap_control->dm_mapsize,
 1247                     BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
 1248         }
 1249         wmbx->cmbo = wmbx->tmbo = &wmbx->mbo[0];
 1250         wmbx->tmbi = &wmbx->mbi[0];
 1251         sc->sc_mbofull = 0;
 1252 
 1253         /* Initialize mail box. */
 1254         mailbox.cmd.opcode = BHA_MBX_INIT_EXTENDED;
 1255         mailbox.cmd.nmbx = BHA_MBX_SIZE;
 1256         ltophys(sc->sc_dmamap_control->dm_segs[0].ds_addr +
 1257             offsetof(struct bha_control, bc_mbx), mailbox.cmd.addr);
 1258         bha_cmd(iot, ioh, sc,
 1259             sizeof(mailbox.cmd), (u_char *)&mailbox.cmd,
 1260             0, (u_char *)0);
 1261         return (0);
 1262 }
 1263 
 1264 void
 1265 bha_inquire_setup_information(sc)
 1266         struct bha_softc *sc;
 1267 {
 1268         bus_space_tag_t iot = sc->sc_iot;
 1269         bus_space_handle_t ioh = sc->sc_ioh;
 1270         struct bha_model model;
 1271         struct bha_revision revision;
 1272         struct bha_digit digit;
 1273         char *p;
 1274 
 1275         /*
 1276          * Get the firmware revision.
 1277          */
 1278         p = sc->sc_firmware;
 1279         revision.cmd.opcode = BHA_INQUIRE_REVISION;
 1280         bha_cmd(iot, ioh, sc,
 1281             sizeof(revision.cmd), (u_char *)&revision.cmd,
 1282             sizeof(revision.reply), (u_char *)&revision.reply);
 1283         *p++ = revision.reply.firm_revision;
 1284         *p++ = '.';
 1285         *p++ = revision.reply.firm_version;
 1286         digit.cmd.opcode = BHA_INQUIRE_REVISION_3;
 1287         bha_cmd(iot, ioh, sc,
 1288             sizeof(digit.cmd), (u_char *)&digit.cmd,
 1289             sizeof(digit.reply), (u_char *)&digit.reply);
 1290         *p++ = digit.reply.digit;
 1291         if (revision.reply.firm_revision >= '3' ||
 1292             (revision.reply.firm_revision == '3' &&
 1293              revision.reply.firm_version >= '3')) {
 1294                 digit.cmd.opcode = BHA_INQUIRE_REVISION_4;
 1295                 bha_cmd(iot, ioh, sc,
 1296                     sizeof(digit.cmd), (u_char *)&digit.cmd,
 1297                     sizeof(digit.reply), (u_char *)&digit.reply);
 1298                 *p++ = digit.reply.digit;
 1299         }
 1300         while (p > sc->sc_firmware && (p[-1] == ' ' || p[-1] == '\0'))
 1301                 p--;
 1302         *p = '\0';
 1303 
 1304         /*
 1305          * Get the model number.
 1306          */
 1307         if (revision.reply.firm_revision >= '3') {
 1308                 p = sc->sc_model;
 1309                 model.cmd.opcode = BHA_INQUIRE_MODEL;
 1310                 model.cmd.len = sizeof(model.reply);
 1311                 bha_cmd(iot, ioh, sc,
 1312                     sizeof(model.cmd), (u_char *)&model.cmd,
 1313                     sizeof(model.reply), (u_char *)&model.reply);
 1314                 *p++ = model.reply.id[0];
 1315                 *p++ = model.reply.id[1];
 1316                 *p++ = model.reply.id[2];
 1317                 *p++ = model.reply.id[3];
 1318                 while (p > sc->sc_model && (p[-1] == ' ' || p[-1] == '\0'))
 1319                         p--;
 1320                 *p++ = model.reply.version[0];
 1321                 *p++ = model.reply.version[1];
 1322                 while (p > sc->sc_model && (p[-1] == ' ' || p[-1] == '\0'))
 1323                         p--;
 1324                 *p = '\0';
 1325         } else
 1326                 strlcpy(sc->sc_model, "542B", sizeof sc->sc_model);
 1327 }
 1328 
 1329 void
 1330 bhaminphys(bp)
 1331         struct buf *bp;
 1332 {
 1333 
 1334         if (bp->b_bcount > BHA_MAXXFER)
 1335                 bp->b_bcount = BHA_MAXXFER;
 1336         minphys(bp);
 1337 }
 1338 
 1339 /*
 1340  * start a scsi operation given the command and the data address.  Also needs
 1341  * the unit, target and lu.
 1342  */
 1343 int
 1344 bha_scsi_cmd(xs)
 1345         struct scsi_xfer *xs;
 1346 {
 1347         struct scsi_link *sc_link = xs->sc_link;
 1348         struct bha_softc *sc = sc_link->adapter_softc;
 1349         bus_dma_tag_t dmat = sc->sc_dmat;
 1350         struct bha_ccb *ccb;
 1351         int error, seg, flags, s;
 1352         int fromqueue = 0, dontqueue = 0;
 1353 
 1354         SC_DEBUG(sc_link, SDEV_DB2, ("bha_scsi_cmd\n"));
 1355 
 1356         s = splbio();           /* protect the queue */
 1357 
 1358         /*
 1359          * If we're running the queue from bha_done(), we've been
 1360          * called with the first queue entry as our argument.
 1361          */
 1362         if (xs == LIST_FIRST(&sc->sc_queue)) {
 1363                 xs = bha_dequeue(sc);
 1364                 fromqueue = 1;
 1365                 goto get_ccb;
 1366         }
 1367 
 1368         /* Polled requests can't be queued for later. */
 1369         dontqueue = xs->flags & SCSI_POLL;
 1370 
 1371         /*
 1372          * If there are jobs in the queue, run them first.
 1373          */
 1374         if (!LIST_EMPTY(&sc->sc_queue)) {
 1375                 /*
 1376                  * If we can't queue, we have to abort, since
 1377                  * we have to preserve order.
 1378                  */
 1379                 if (dontqueue) {
 1380                         splx(s);
 1381                         return (TRY_AGAIN_LATER);
 1382                 }
 1383 
 1384                 /*
 1385                  * Swap with the first queue entry.
 1386                  */
 1387                 bha_enqueue(sc, xs, 0);
 1388                 xs = bha_dequeue(sc);
 1389                 fromqueue = 1;
 1390         }
 1391 
 1392  get_ccb:
 1393         /*
 1394          * get a ccb to use. If the transfer
 1395          * is from a buf (possibly from interrupt time)
 1396          * then we can't allow it to sleep
 1397          */
 1398         flags = xs->flags;
 1399         if ((ccb = bha_get_ccb(sc, flags)) == NULL) {
 1400                 /*
 1401                  * If we can't queue, we lose.
 1402                  */
 1403                 if (dontqueue) {
 1404                         splx(s);
 1405                         return (TRY_AGAIN_LATER);
 1406                 }
 1407 
 1408                 /*
 1409                  * Stuff ourselves into the queue, in front
 1410                  * if we came off in the first place.
 1411                  */
 1412                 bha_enqueue(sc, xs, fromqueue);
 1413                 splx(s);
 1414                 return (SUCCESSFULLY_QUEUED);
 1415         }
 1416 
 1417         splx(s);                /* done playing with the queue */
 1418 
 1419         ccb->xs = xs;
 1420         ccb->timeout = xs->timeout;
 1421 
 1422         /*
 1423          * Put all the arguments for the xfer in the ccb
 1424          */
 1425         if (flags & SCSI_RESET) {
 1426                 ccb->opcode = BHA_RESET_CCB;
 1427                 ccb->scsi_cmd_length = 0;
 1428         } else {
 1429                 /* can't use S/G if zero length */
 1430                 ccb->opcode = (xs->datalen ? BHA_INIT_SCAT_GATH_CCB
 1431                                            : BHA_INITIATOR_CCB);
 1432                 bcopy(xs->cmd, &ccb->scsi_cmd,
 1433                     ccb->scsi_cmd_length = xs->cmdlen);
 1434         }
 1435 
 1436         if (xs->datalen) {
 1437                 /*
 1438                  * Map the DMA transfer.
 1439                  */
 1440 #ifdef TFS
 1441                 if (flags & SCSI_DATA_UIO) {
 1442                         error = bus_dmamap_load_uio(dmat,
 1443                             ccb->dmamap_xfer, (struct uio *)xs->data,
 1444                             (flags & SCSI_NOSLEEP) ? BUS_DMA_NOWAIT :
 1445                             BUS_DMA_WAITOK);
 1446                 } else
 1447 #endif /* TFS */
 1448                 {
 1449                         error = bus_dmamap_load(dmat,
 1450                             ccb->dmamap_xfer, xs->data, xs->datalen, NULL,
 1451                             (flags & SCSI_NOSLEEP) ? BUS_DMA_NOWAIT :
 1452                             BUS_DMA_WAITOK);
 1453                 }
 1454 
 1455                 if (error) {
 1456                         if (error == EFBIG) {
 1457                                 printf("%s: bha_scsi_cmd, more than %d"
 1458                                     " dma segments\n",
 1459                                     sc->sc_dev.dv_xname, BHA_NSEG);
 1460                         } else {
 1461                                 printf("%s: bha_scsi_cmd, error %d loading"
 1462                                     " dma map\n",
 1463                                     sc->sc_dev.dv_xname, error);
 1464                         }
 1465                         goto bad;
 1466                 }
 1467 
 1468                 bus_dmamap_sync(dmat, ccb->dmamap_xfer,
 1469                     0, ccb->dmamap_xfer->dm_mapsize,
 1470                     (flags & SCSI_DATA_IN) ? BUS_DMASYNC_PREREAD :
 1471                     BUS_DMASYNC_PREWRITE);
 1472 
 1473                 /*
 1474                  * Load the hardware scatter/gather map with the
 1475                  * contents of the DMA map.
 1476                  */
 1477                 for (seg = 0; seg < ccb->dmamap_xfer->dm_nsegs; seg++) {
 1478                         ltophys(ccb->dmamap_xfer->dm_segs[seg].ds_addr,
 1479                             ccb->scat_gath[seg].seg_addr);
 1480                         ltophys(ccb->dmamap_xfer->dm_segs[seg].ds_len,
 1481                             ccb->scat_gath[seg].seg_len);
 1482                 }
 1483 
 1484                 ltophys(sc->sc_dmamap_control->dm_segs[0].ds_addr +
 1485                     BHA_CCB_OFF(ccb) + offsetof(struct bha_ccb, scat_gath),
 1486                     ccb->data_addr);
 1487                 ltophys(ccb->dmamap_xfer->dm_nsegs *
 1488                     sizeof(struct bha_scat_gath), ccb->data_length);
 1489         } else {
 1490                 /*
 1491                  * No data xfer, use non S/G values.
 1492                  */
 1493                 ltophys(0, ccb->data_addr);
 1494                 ltophys(0, ccb->data_length);
 1495         }
 1496 
 1497         ccb->data_out = 0;
 1498         ccb->data_in = 0;
 1499         ccb->target = sc_link->target;
 1500         ccb->lun = sc_link->lun;
 1501         ltophys(sc->sc_dmamap_control->dm_segs[0].ds_addr +
 1502             BHA_CCB_OFF(ccb) + offsetof(struct bha_ccb, scsi_sense),
 1503             ccb->sense_ptr);
 1504         ccb->req_sense_length = sizeof(ccb->scsi_sense);
 1505         ccb->host_stat = 0x00;
 1506         ccb->target_stat = 0x00;
 1507         ccb->link_id = 0;
 1508         ltophys(0, ccb->link_addr);
 1509 
 1510         bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap_control,
 1511             0, sc->sc_dmamap_control->dm_mapsize,
 1512             BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
 1513 
 1514         s = splbio();
 1515         bha_queue_ccb(sc, ccb);
 1516         splx(s);
 1517 
 1518         /*
 1519          * Usually return SUCCESSFULLY QUEUED
 1520          */
 1521         SC_DEBUG(sc_link, SDEV_DB3, ("cmd_sent\n"));
 1522         if ((flags & SCSI_POLL) == 0)
 1523                 return (SUCCESSFULLY_QUEUED);
 1524 
 1525         /*
 1526          * If we can't use interrupts, poll on completion
 1527          */
 1528         if (bha_poll(sc, xs, ccb->timeout)) {
 1529                 bha_timeout(ccb);
 1530                 if (bha_poll(sc, xs, ccb->timeout))
 1531                         bha_timeout(ccb);
 1532         }
 1533         return (COMPLETE);
 1534 
 1535 bad:
 1536         xs->error = XS_DRIVER_STUFFUP;
 1537         bha_free_ccb(sc, ccb);
 1538         return (COMPLETE);
 1539 }
 1540 
 1541 /*
 1542  * Poll a particular unit, looking for a particular xs
 1543  */
 1544 int
 1545 bha_poll(sc, xs, count)
 1546         struct bha_softc *sc;
 1547         struct scsi_xfer *xs;
 1548         int count;
 1549 {
 1550         bus_space_tag_t iot = sc->sc_iot;
 1551         bus_space_handle_t ioh = sc->sc_ioh;
 1552 
 1553         /* timeouts are in msec, so we loop in 1000 usec cycles */
 1554         while (count) {
 1555                 /*
 1556                  * If we had interrupts enabled, would we
 1557                  * have got an interrupt?
 1558                  */
 1559                 if (bus_space_read_1(iot, ioh, BHA_INTR_PORT) &
 1560                     BHA_INTR_ANYINTR)
 1561                         bha_intr(sc);
 1562                 if (xs->flags & ITSDONE)
 1563                         return (0);
 1564                 delay(1000);    /* only happens in boot so ok */
 1565                 count--;
 1566         }
 1567         return (1);
 1568 }
 1569 
 1570 void
 1571 bha_timeout(arg)
 1572         void *arg;
 1573 {
 1574         struct bha_ccb *ccb = arg;
 1575         struct scsi_xfer *xs = ccb->xs;
 1576         struct scsi_link *sc_link = xs->sc_link;
 1577         struct bha_softc *sc = sc_link->adapter_softc;
 1578         int s;
 1579 
 1580         sc_print_addr(sc_link);
 1581         printf("timed out");
 1582 
 1583         s = splbio();
 1584 
 1585 #ifdef BHADIAG
 1586         /*
 1587          * If the ccb's mbx is not free, then the board has gone Far East?
 1588          */
 1589         bha_collect_mbo(sc);
 1590         if (ccb->flags & CCB_SENDING) {
 1591                 printf("%s: not taking commands!\n", sc->sc_dev.dv_xname);
 1592                 Debugger();
 1593         }
 1594 #endif
 1595 
 1596         /*
 1597          * If it has been through before, then
 1598          * a previous abort has failed, don't
 1599          * try abort again
 1600          */
 1601         if (ccb->flags & CCB_ABORT) {
 1602                 /* abort timed out */
 1603                 printf(" AGAIN\n");
 1604                 /* XXX Must reset! */
 1605         } else {
 1606                 /* abort the operation that has timed out */
 1607                 printf("\n");
 1608                 ccb->xs->error = XS_TIMEOUT;
 1609                 ccb->timeout = BHA_ABORT_TIMEOUT;
 1610                 ccb->flags |= CCB_ABORT;
 1611                 bha_queue_ccb(sc, ccb);
 1612         }
 1613 
 1614         splx(s);
 1615 }

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