root/dev/isa/aha.c

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

DEFINITIONS

This source file includes following definitions.
  1. aha_cmd
  2. aha_isapnp_probe
  3. ahaprobe
  4. ahaattach
  5. aha_finish_ccbs
  6. ahaintr
  7. aha_reset_ccb
  8. aha_free_ccb
  9. aha_init_ccb
  10. aha_get_ccb
  11. aha_ccb_phys_kv
  12. aha_queue_ccb
  13. aha_collect_mbo
  14. aha_start_ccbs
  15. aha_done
  16. aha_find
  17. aha_init
  18. aha_inquire_setup_information
  19. ahaminphys
  20. aha_scsi_cmd
  21. aha_poll
  22. aha_timeout

    1 /*      $OpenBSD: aha.c,v 1.57 2007/08/15 02:04:30 krw Exp $    */
    2 /*      $NetBSD: aha.c,v 1.11 1996/05/12 23:51:23 mycroft Exp $ */
    3 
    4 #undef AHADIAG
    5 
    6 /*
    7  * Copyright (c) 1994, 1996 Charles M. Hannum.  All rights reserved.
    8  *
    9  * Redistribution and use in source and binary forms, with or without
   10  * modification, are permitted provided that the following conditions
   11  * are met:
   12  * 1. Redistributions of source code must retain the above copyright
   13  *    notice, this list of conditions and the following disclaimer.
   14  * 2. Redistributions in binary form must reproduce the above copyright
   15  *    notice, this list of conditions and the following disclaimer in the
   16  *    documentation and/or other materials provided with the distribution.
   17  * 3. All advertising materials mentioning features or use of this software
   18  *    must display the following acknowledgement:
   19  *      This product includes software developed by Charles M. Hannum.
   20  * 4. The name of the author may not be used to endorse or promote products
   21  *    derived from this software without specific prior written permission.
   22  *
   23  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   24  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   25  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   26  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
   27  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   28  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   29  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   30  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   31  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
   32  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   33  */
   34 
   35 /*
   36  * Originally written by Julian Elischer (julian@tfs.com)
   37  * for TRW Financial Systems for use under the MACH(2.5) operating system.
   38  *
   39  * TRW Financial Systems, in accordance with their agreement with Carnegie
   40  * Mellon University, makes this software available to CMU to distribute
   41  * or use in any manner that they see fit as long as this message is kept with
   42  * the software. For this reason TFS also grants any other persons or
   43  * organisations permission to use or modify this software.
   44  *
   45  * TFS supplies this software to be publicly redistributed
   46  * on the understanding that TFS is not responsible for the correct
   47  * functioning of this software in any circumstances.
   48  */
   49 
   50 #include <sys/types.h>
   51 #include <sys/param.h>
   52 #include <sys/systm.h>
   53 #include <sys/kernel.h>
   54 #include <sys/errno.h>
   55 #include <sys/ioctl.h>
   56 #include <sys/device.h>
   57 #include <sys/malloc.h>
   58 #include <sys/buf.h>
   59 #include <sys/proc.h>
   60 #include <sys/user.h>
   61 #include <sys/timeout.h>
   62 
   63 #include <uvm/uvm.h>
   64 #include <uvm/uvm_extern.h>
   65 
   66 #include <machine/intr.h>
   67 #include <machine/bus.h>
   68 
   69 #include <scsi/scsi_all.h>
   70 #include <scsi/scsiconf.h>
   71 
   72 #include <dev/isa/isavar.h>
   73 #include <dev/isa/isadmavar.h>
   74 #include <dev/isa/ahareg.h>
   75 
   76 #ifndef DDB
   77 #define Debugger() panic("should call debugger here (aha1542.c)")
   78 #endif /* ! DDB */
   79 
   80 /* XXX fixme:
   81  * on i386 at least, xfers to/from user memory
   82  * cannot be serviced at interrupt time.
   83  */
   84 #ifdef i386
   85 #define VOLATILE_XS(xs) \
   86         ((xs)->datalen > 0 && (xs)->bp == NULL && \
   87         ((xs)->flags & SCSI_POLL) == 0)
   88 #else
   89 #define VOLATILE_XS(xs)        0
   90 #endif
   91 
   92 /*
   93  * Mail box defs  etc.
   94  * these could be bigger but we need the aha_softc to fit on a single page..
   95  */
   96 #define AHA_MBX_SIZE    16      /* mail box size */
   97 
   98 #define AHA_CCB_MAX     16      /* store up to 32 CCBs at one time */
   99 #define CCB_HASH_SIZE   16      /* hash table size for phystokv */
  100 #define CCB_HASH_SHIFT  9
  101 #define CCB_HASH(x)     ((((long)(x))>>CCB_HASH_SHIFT) & (CCB_HASH_SIZE - 1))
  102 
  103 #define aha_nextmbx(wmb, mbx, mbio) \
  104         if ((wmb) == &(mbx)->mbio[AHA_MBX_SIZE - 1])    \
  105                 (wmb) = &(mbx)->mbio[0];                \
  106         else                                            \
  107                 (wmb)++;
  108 
  109 struct aha_mbx {
  110         struct aha_mbx_out mbo[AHA_MBX_SIZE];
  111         struct aha_mbx_in mbi[AHA_MBX_SIZE];
  112         struct aha_mbx_out *cmbo;       /* Collection Mail Box out */
  113         struct aha_mbx_out *tmbo;       /* Target Mail Box out */
  114         struct aha_mbx_in *tmbi;        /* Target Mail Box in */
  115 };
  116 
  117 struct aha_softc {
  118         struct device sc_dev;
  119         struct isadev sc_id;
  120         void *sc_ih;
  121         bus_dma_tag_t sc_dmat;
  122 
  123         int sc_iobase;
  124         int sc_irq, sc_drq;
  125 
  126         char sc_model[18],
  127              sc_firmware[4];
  128 
  129         struct aha_mbx *sc_mbx;         /* all the mailboxes */
  130 #define wmbx    (sc->sc_mbx)
  131         struct aha_ccb *sc_ccbhash[CCB_HASH_SIZE];
  132         TAILQ_HEAD(, aha_ccb) sc_free_ccb, sc_waiting_ccb;
  133         int sc_numccbs, sc_mbofull;
  134         int sc_scsi_dev;                /* our scsi id */
  135         struct scsi_link sc_link;
  136 };
  137 
  138 #ifdef AHADEBUG
  139 int     aha_debug = 1;
  140 #endif /* AHADEBUG */
  141 
  142 int aha_cmd(int, struct aha_softc *, int, u_char *, int, u_char *);
  143 void aha_finish_ccbs(struct aha_softc *);
  144 int ahaintr(void *);
  145 void aha_reset_ccb(struct aha_softc *, struct aha_ccb *);
  146 void aha_free_ccb(struct aha_softc *, struct aha_ccb *);
  147 int aha_init_ccb(struct aha_softc *, struct aha_ccb *, int);
  148 struct aha_ccb *aha_get_ccb(struct aha_softc *, int);
  149 struct aha_ccb *aha_ccb_phys_kv(struct aha_softc *, u_long);
  150 void aha_queue_ccb(struct aha_softc *, struct aha_ccb *);
  151 void aha_collect_mbo(struct aha_softc *);
  152 void aha_start_ccbs(struct aha_softc *);
  153 void aha_done(struct aha_softc *, struct aha_ccb *);
  154 int aha_find(struct isa_attach_args *, struct aha_softc *, int);
  155 void aha_init(struct aha_softc *);
  156 void aha_inquire_setup_information(struct aha_softc *);
  157 void ahaminphys(struct buf *);
  158 int aha_scsi_cmd(struct scsi_xfer *);
  159 int aha_poll(struct aha_softc *, struct scsi_xfer *, int);
  160 void aha_timeout(void *arg);
  161 
  162 struct scsi_adapter aha_switch = {
  163         aha_scsi_cmd,
  164         ahaminphys,
  165         0,
  166         0,
  167 };
  168 
  169 /* the below structure is so we have a default dev struct for out link struct */
  170 struct scsi_device aha_dev = {
  171         NULL,                   /* Use default error handler */
  172         NULL,                   /* have a queue, served by this */
  173         NULL,                   /* have no async handler */
  174         NULL,                   /* Use default 'done' routine */
  175 };
  176 
  177 int     aha_isapnp_probe(struct device *, void *, void *);
  178 int     ahaprobe(struct device *, void *, void *);
  179 void    ahaattach(struct device *, struct device *, void *);
  180 
  181 struct cfattach aha_isapnp_ca = {
  182         sizeof(struct aha_softc), aha_isapnp_probe, ahaattach
  183 };
  184 
  185 struct cfattach aha_isa_ca = {
  186         sizeof(struct aha_softc), ahaprobe, ahaattach
  187 };
  188 
  189 struct cfdriver aha_cd = {
  190         NULL, "aha", DV_DULL
  191 };
  192 
  193 #define AHA_RESET_TIMEOUT       2000    /* time to wait for reset (mSec) */
  194 #define AHA_ABORT_TIMEOUT       2000    /* time to wait for abort (mSec) */
  195 
  196 #include "bha.h"
  197 
  198 /*
  199  * aha_cmd(iobase, sc, icnt, ibuf, ocnt, obuf)
  200  *
  201  * Activate Adapter command
  202  *    icnt:   number of args (outbound bytes including opcode)
  203  *    ibuf:   argument buffer
  204  *    ocnt:   number of expected returned bytes
  205  *    obuf:   result buffer
  206  *    wait:   number of seconds to wait for response
  207  *
  208  * Performs an adapter command through the ports.  Not to be confused with a
  209  * scsi command, which is read in via the dma; one of the adapter commands
  210  * tells it to read in a scsi command.
  211  */
  212 int
  213 aha_cmd(iobase, sc, icnt, ibuf, ocnt, obuf)
  214         int iobase;
  215         struct aha_softc *sc;
  216         int icnt, ocnt;
  217         u_char *ibuf, *obuf;
  218 {
  219         const char *name;
  220         register int i;
  221         int wait;
  222         u_char sts;
  223         u_char opcode = ibuf[0];
  224 
  225         if (sc != NULL)
  226                 name = sc->sc_dev.dv_xname;
  227         else
  228                 name = "(aha probe)";
  229 
  230         /*
  231          * Calculate a reasonable timeout for the command.
  232          */
  233         switch (opcode) {
  234         case AHA_INQUIRE_DEVICES:
  235                 wait = 15 * 20000;
  236                 break;
  237         default:
  238                 wait = 1 * 20000;
  239                 break;
  240         }
  241 
  242         /*
  243          * Wait for the adapter to go idle, unless it's one of
  244          * the commands which don't need this
  245          */
  246         if (opcode != AHA_MBO_INTR_EN) {
  247                 for (i = 20000; i; i--) {       /* 1 sec? */
  248                         sts = inb(iobase + AHA_STAT_PORT);
  249                         if (sts & AHA_STAT_IDLE)
  250                                 break;
  251                         delay(50);
  252                 }
  253                 if (!i) {
  254                         printf("%s: aha_cmd, host not idle(0x%x)\n",
  255                             name, sts);
  256                         return (ENXIO);
  257                 }
  258         }
  259         /*
  260          * Now that it is idle, if we expect output, preflush the
  261          * queue feeding to us.
  262          */
  263         if (ocnt) {
  264                 while ((inb(iobase + AHA_STAT_PORT)) & AHA_STAT_DF)
  265                         inb(iobase + AHA_DATA_PORT);
  266         }
  267         /*
  268          * Output the command and the number of arguments given
  269          * for each byte, first check the port is empty.
  270          */
  271         while (icnt--) {
  272                 for (i = wait; i; i--) {
  273                         sts = inb(iobase + AHA_STAT_PORT);
  274                         if (!(sts & AHA_STAT_CDF))
  275                                 break;
  276                         delay(50);
  277                 }
  278                 if (!i) {
  279                         if (opcode != AHA_INQUIRE_REVISION)
  280                                 printf("%s: aha_cmd, cmd/data port full\n",
  281                                     name);
  282                         outb(iobase + AHA_CTRL_PORT, AHA_CTRL_SRST);
  283                         return (ENXIO);
  284                 }
  285                 outb(iobase + AHA_CMD_PORT, *ibuf++);
  286         }
  287         /*
  288          * If we expect input, loop that many times, each time,
  289          * looking for the data register to have valid data
  290          */
  291         while (ocnt--) {
  292                 for (i = wait; i; i--) {
  293                         sts = inb(iobase + AHA_STAT_PORT);
  294                         if (sts & AHA_STAT_DF)
  295                                 break;
  296                         delay(50);
  297                 }
  298                 if (!i) {
  299                         if (opcode != AHA_INQUIRE_REVISION)
  300                                 printf("%s: aha_cmd, cmd/data port empty %d\n",
  301                                     name, ocnt);
  302                         outb(iobase + AHA_CTRL_PORT, AHA_CTRL_SRST);
  303                         return (ENXIO);
  304                 }
  305                 *obuf++ = inb(iobase + AHA_DATA_PORT);
  306         }
  307         /*
  308          * Wait for the board to report a finished instruction.
  309          * We may get an extra interrupt for the HACC signal, but this is
  310          * unimportant.
  311          */
  312         if (opcode != AHA_MBO_INTR_EN) {
  313                 for (i = 20000; i; i--) {       /* 1 sec? */
  314                         sts = inb(iobase + AHA_INTR_PORT);
  315                         /* XXX Need to save this in the interrupt handler? */
  316                         if (sts & AHA_INTR_HACC)
  317                                 break;
  318                         delay(50);
  319                 }
  320                 if (!i) {
  321                         printf("%s: aha_cmd, host not finished(0x%x)\n",
  322                             name, sts);
  323                         return (ENXIO);
  324                 }
  325         }
  326         outb(iobase + AHA_CTRL_PORT, AHA_CTRL_IRST);
  327         return (0);
  328 }
  329 
  330 int
  331 aha_isapnp_probe(parent, match, aux)
  332         struct device *parent;
  333         void *match, *aux;
  334 {
  335         return (1);
  336 }
  337 
  338 
  339 /*
  340  * Check if the device can be found at the port given
  341  * and if so, set it up ready for further work
  342  * as an argument, takes the isa_device structure from
  343  * autoconf.c
  344  */
  345 int
  346 ahaprobe(parent, match, aux)
  347         struct device *parent;
  348         void *match, *aux;
  349 {
  350         register struct isa_attach_args *ia = aux;
  351 #if NBHA > 0
  352         extern int btports[], nbtports;
  353         int i;
  354 
  355         for (i = 0; i < nbtports; i++)
  356                 if (btports[i] == ia->ia_iobase)
  357                         return (0);
  358 #endif
  359 
  360         /* See if there is a unit at this location. */
  361         if (aha_find(ia, NULL, 0) != 0)
  362                 return (0);
  363 
  364         ia->ia_msize = 0;
  365         ia->ia_iosize = 4;
  366         /* IRQ and DRQ set by aha_find(). */
  367         return (1);
  368 }
  369 
  370 /*
  371  * Attach all the sub-devices we can find
  372  */
  373 void
  374 ahaattach(parent, self, aux)
  375         struct device *parent, *self;
  376         void *aux;
  377 {
  378         struct isa_attach_args *ia = aux;
  379         struct aha_softc *sc = (void *)self;
  380         struct scsibus_attach_args saa;
  381         int isapnp = !strcmp(parent->dv_cfdata->cf_driver->cd_name, "isapnp");
  382 
  383         if (isapnp) {
  384                 ia->ia_iobase = ia->ipa_io[0].base;
  385                 isadma_cascade(ia->ia_drq);
  386         }
  387 
  388         if (aha_find(ia, sc, isapnp) != 0)
  389                 panic("ahaattach: aha_find of %s failed", self->dv_xname);
  390         sc->sc_iobase = ia->ia_iobase;
  391         sc->sc_dmat = ia->ia_dmat;
  392 
  393         if (sc->sc_drq != DRQUNK && isapnp == 0)
  394                 isadma_cascade(sc->sc_drq);
  395 
  396         aha_inquire_setup_information(sc);
  397         aha_init(sc);
  398         TAILQ_INIT(&sc->sc_free_ccb);
  399         TAILQ_INIT(&sc->sc_waiting_ccb);
  400 
  401         /*
  402          * fill in the prototype scsi_link.
  403          */
  404         sc->sc_link.adapter_softc = sc;
  405         sc->sc_link.adapter_target = sc->sc_scsi_dev;
  406         sc->sc_link.adapter = &aha_switch;
  407         sc->sc_link.device = &aha_dev;
  408         sc->sc_link.openings = 2;
  409 
  410         bzero(&saa, sizeof(saa));
  411         saa.saa_sc_link = &sc->sc_link;
  412 
  413         sc->sc_ih = isa_intr_establish(ia->ia_ic, sc->sc_irq, IST_EDGE,
  414             IPL_BIO, ahaintr, sc, sc->sc_dev.dv_xname);
  415 
  416         /*
  417          * ask the adapter what subunits are present
  418          */
  419         config_found(self, &saa, scsiprint);
  420 }
  421 
  422 void
  423 aha_finish_ccbs(sc)
  424         struct aha_softc *sc;
  425 {
  426         struct aha_mbx_in *wmbi;
  427         struct aha_ccb *ccb;
  428         int i;
  429 
  430         wmbi = wmbx->tmbi;
  431 
  432         if (wmbi->stat == AHA_MBI_FREE) {
  433                 for (i = 0; i < AHA_MBX_SIZE; i++) {
  434                         if (wmbi->stat != AHA_MBI_FREE) {
  435                                 printf("%s: mbi not in round-robin order\n",
  436                                     sc->sc_dev.dv_xname);
  437                                 goto AGAIN;
  438                         }
  439                         aha_nextmbx(wmbi, wmbx, mbi);
  440                 }
  441 #ifdef AHADIAGnot
  442                 printf("%s: mbi interrupt with no full mailboxes\n",
  443                     sc->sc_dev.dv_xname);
  444 #endif
  445                 return;
  446         }
  447 
  448 AGAIN:
  449         do {
  450                 ccb = aha_ccb_phys_kv(sc, phystol(wmbi->ccb_addr));
  451                 if (!ccb) {
  452                         printf("%s: bad mbi ccb pointer; skipping\n",
  453                             sc->sc_dev.dv_xname);
  454                         goto next;
  455                 }
  456 
  457 #ifdef AHADEBUG
  458                 if (aha_debug) {
  459                         u_char *cp = (u_char *)&ccb->scsi_cmd;
  460                         printf("op=%x %x %x %x %x %x\n",
  461                             cp[0], cp[1], cp[2], cp[3], cp[4], cp[5]);
  462                         printf("stat %x for mbi addr = 0x%08x, ",
  463                             wmbi->stat, wmbi);
  464                         printf("ccb addr = 0x%x\n", ccb);
  465                 }
  466 #endif /* AHADEBUG */
  467 
  468                 switch (wmbi->stat) {
  469                 case AHA_MBI_OK:
  470                 case AHA_MBI_ERROR:
  471                         if ((ccb->flags & CCB_ABORT) != 0) {
  472                                 /*
  473                                  * If we already started an abort, wait for it
  474                                  * to complete before clearing the CCB.  We
  475                                  * could instead just clear CCB_SENDING, but
  476                                  * what if the mailbox was already received?
  477                                  * The worst that happens here is that we clear
  478                                  * the CCB a bit later than we need to.  BFD.
  479                                  */
  480                                 goto next;
  481                         }
  482                         break;
  483 
  484                 case AHA_MBI_ABORT:
  485                 case AHA_MBI_UNKNOWN:
  486                         /*
  487                          * Even if the CCB wasn't found, we clear it anyway.
  488                          * See preceding comment.
  489                          */
  490                         break;
  491 
  492                 default:
  493                         printf("%s: bad mbi status %02x; skipping\n",
  494                             sc->sc_dev.dv_xname, wmbi->stat);
  495                         goto next;
  496                 }
  497 
  498                 if ((ccb->xs->flags & SCSI_POLL) == 0)
  499                         timeout_del(&ccb->xs->stimeout);
  500                 bus_dmamap_sync(sc->sc_dmat, ccb->ccb_dmam, 0,
  501                     ccb->ccb_dmam->dm_mapsize, BUS_DMASYNC_POSTREAD);
  502                 aha_done(sc, ccb);
  503 
  504         next:
  505                 wmbi->stat = AHA_MBI_FREE;
  506                 aha_nextmbx(wmbi, wmbx, mbi);
  507         } while (wmbi->stat != AHA_MBI_FREE);
  508 
  509         wmbx->tmbi = wmbi;
  510 }
  511 
  512 /*
  513  * Catch an interrupt from the adaptor
  514  */
  515 int
  516 ahaintr(arg)
  517         void *arg;
  518 {
  519         struct aha_softc *sc = arg;
  520         int iobase = sc->sc_iobase;
  521         u_char sts;
  522 
  523 #ifdef AHADEBUG
  524         if (aha_debug)
  525                 printf("%s: ahaintr ", sc->sc_dev.dv_xname);
  526 #endif /*AHADEBUG */
  527 
  528         /*
  529          * First acknowlege the interrupt, Then if it's not telling about
  530          * a completed operation just return.
  531          */
  532         sts = inb(iobase + AHA_INTR_PORT);
  533         if ((sts & AHA_INTR_ANYINTR) == 0)
  534                 return (0);
  535         outb(iobase + AHA_CTRL_PORT, AHA_CTRL_IRST);
  536 
  537 #ifdef AHADIAG
  538         /* Make sure we clear CCB_SENDING before finishing a CCB. */
  539         aha_collect_mbo(sc);
  540 #endif
  541 
  542         /* Mail box out empty? */
  543         if (sts & AHA_INTR_MBOA) {
  544                 struct aha_toggle toggle;
  545 
  546                 toggle.cmd.opcode = AHA_MBO_INTR_EN;
  547                 toggle.cmd.enable = 0;
  548                 aha_cmd(iobase, sc, sizeof(toggle.cmd), (u_char *)&toggle.cmd,
  549                     0, (u_char *)0);
  550                 aha_start_ccbs(sc);
  551         }
  552 
  553         /* Mail box in full? */
  554         if (sts & AHA_INTR_MBIF)
  555                 aha_finish_ccbs(sc);
  556 
  557         return (1);
  558 }
  559 
  560 void
  561 aha_reset_ccb(sc, ccb)
  562         struct aha_softc *sc;
  563         struct aha_ccb *ccb;
  564 {
  565 
  566         ccb->flags = 0;
  567 }
  568 
  569 /*
  570  * A ccb is put onto the free list.
  571  */
  572 void
  573 aha_free_ccb(sc, ccb)
  574         struct aha_softc *sc;
  575         struct aha_ccb *ccb;
  576 {
  577         int s, hashnum;
  578         struct aha_ccb **hashccb;
  579 
  580         s = splbio();
  581 
  582         if (ccb->ccb_dmam->dm_segs[0].ds_addr != 0)
  583                 bus_dmamap_unload(sc->sc_dmat, ccb->ccb_dmam);
  584 
  585         /* remove from hash table */
  586 
  587         hashnum = CCB_HASH(ccb->ccb_dmam->dm_segs[0].ds_addr);
  588         hashccb = &sc->sc_ccbhash[hashnum];
  589 
  590         while (*hashccb) {
  591                 if ((*hashccb)->ccb_dmam->dm_segs[0].ds_addr ==
  592                     ccb->ccb_dmam->dm_segs[0].ds_addr) {
  593                         *hashccb = (*hashccb)->nexthash;
  594                         break;
  595                 }
  596                 hashccb = &(*hashccb)->nexthash;
  597         }
  598 
  599         aha_reset_ccb(sc, ccb);
  600         TAILQ_INSERT_HEAD(&sc->sc_free_ccb, ccb, chain);
  601 
  602         /*
  603          * If there were none, wake anybody waiting for one to come free,
  604          * starting with queued entries.
  605          */
  606         if (TAILQ_NEXT(ccb, chain) == NULL)
  607                 wakeup(&sc->sc_free_ccb);
  608 
  609         splx(s);
  610 }
  611 
  612 int
  613 aha_init_ccb(sc, ccb, flags)
  614         struct aha_softc *sc;
  615         struct aha_ccb *ccb;
  616         int flags;
  617 {
  618         int error, wait, state = 0;
  619 
  620         bzero(ccb, sizeof(struct aha_ccb));
  621         aha_reset_ccb(sc, ccb);
  622 
  623         wait = (flags & SCSI_NOSLEEP) ? BUS_DMA_NOWAIT : BUS_DMA_WAITOK;
  624         /* Create a DMA map for the data area.  */
  625         error = bus_dmamap_create(sc->sc_dmat, MAXPHYS, (MAXPHYS / NBPG) + 1,
  626             MAXPHYS, 0, wait | BUS_DMA_ALLOCNOW, &ccb->dmam);
  627         if (error)
  628                 goto fail;
  629         state++;
  630 
  631         /* Create a DMA map for the command control block.  */
  632         error = bus_dmamap_create(sc->sc_dmat, CCB_PHYS_SIZE, 1, CCB_PHYS_SIZE,
  633             0, wait | BUS_DMA_ALLOCNOW, &ccb->ccb_dmam);
  634         if (error)
  635                 goto fail;
  636 
  637         return (0);
  638 
  639  fail:
  640         if (state > 0)
  641                 bus_dmamap_destroy(sc->sc_dmat, ccb->dmam);
  642         return (error);
  643 }
  644 
  645 /*
  646  * Get a free ccb
  647  *
  648  * If there are none, see if we can allocate a new one.  If so, put it in
  649  * the hash table too otherwise either return an error or sleep.
  650  */
  651 struct aha_ccb *
  652 aha_get_ccb(sc, flags)
  653         struct aha_softc *sc;
  654         int flags;
  655 {
  656         struct aha_ccb *ccb;
  657         int hashnum, s;
  658 
  659         s = splbio();
  660 
  661         /*
  662          * If we can and have to, sleep waiting for one to come free
  663          * but only if we can't allocate a new one.
  664          */
  665         for (;;) {
  666                 ccb = TAILQ_FIRST(&sc->sc_free_ccb);
  667                 if (ccb) {
  668                         TAILQ_REMOVE(&sc->sc_free_ccb, ccb, chain);
  669                         break;
  670                 }
  671                 if (sc->sc_numccbs < AHA_CCB_MAX) {
  672                         MALLOC(ccb, struct aha_ccb *, sizeof *ccb, M_DEVBUF,
  673                             (flags & SCSI_NOSLEEP) ? M_NOWAIT : M_WAITOK);
  674                         if (ccb == NULL) {
  675                                 printf("%s: can't malloc ccb\n",
  676                                     sc->sc_dev.dv_xname);
  677                                 goto out;
  678                         }
  679                         if (aha_init_ccb(sc, ccb, flags) == 0) {
  680                                 sc->sc_numccbs++;
  681                                 break;
  682                         }
  683                         FREE(ccb, M_DEVBUF);
  684                         ccb = NULL;
  685                 }
  686                 if (flags & SCSI_NOSLEEP)
  687                         goto out;
  688                 tsleep(&sc->sc_free_ccb, PRIBIO, "ahaccb", 0);
  689         }
  690 
  691         ccb->flags |= CCB_ALLOC;
  692 
  693         if (bus_dmamap_load(sc->sc_dmat, ccb->ccb_dmam, ccb, CCB_PHYS_SIZE,
  694             NULL, BUS_DMA_NOWAIT) != 0) {
  695                 aha_free_ccb(sc, ccb);
  696                 ccb = NULL;
  697         } else {
  698                 hashnum = CCB_HASH(ccb->ccb_dmam->dm_segs[0].ds_addr);
  699                 ccb->nexthash = sc->sc_ccbhash[hashnum];
  700                 sc->sc_ccbhash[hashnum] = ccb;
  701         }
  702 out:
  703         splx(s);
  704         return (ccb);
  705 }
  706 
  707 /*
  708  * Given a physical address, find the ccb that it corresponds to.
  709  */
  710 struct aha_ccb *
  711 aha_ccb_phys_kv(sc, ccb_phys)
  712         struct aha_softc *sc;
  713         u_long ccb_phys;
  714 {
  715         int hashnum = CCB_HASH(ccb_phys);
  716         struct aha_ccb *ccb = sc->sc_ccbhash[hashnum];
  717 
  718         while (ccb) {
  719                 if (ccb->ccb_dmam->dm_segs[0].ds_addr == ccb_phys)
  720                         break;
  721                 ccb = ccb->nexthash;
  722         }
  723         return (ccb);
  724 }
  725 
  726 /*
  727  * Queue a CCB to be sent to the controller, and send it if possible.
  728  */
  729 void
  730 aha_queue_ccb(sc, ccb)
  731         struct aha_softc *sc;
  732         struct aha_ccb *ccb;
  733 {
  734 
  735         TAILQ_INSERT_TAIL(&sc->sc_waiting_ccb, ccb, chain);
  736         aha_start_ccbs(sc);
  737 }
  738 
  739 /*
  740  * Garbage collect mailboxes that are no longer in use.
  741  */
  742 void
  743 aha_collect_mbo(sc)
  744         struct aha_softc *sc;
  745 {
  746         struct aha_mbx_out *wmbo;       /* Mail Box Out pointer */
  747 #ifdef AHADIAG
  748         struct aha_ccb *ccb;
  749 #endif
  750 
  751         wmbo = wmbx->cmbo;
  752 
  753         while (sc->sc_mbofull > 0) {
  754                 if (wmbo->cmd != AHA_MBO_FREE)
  755                         break;
  756 
  757 #ifdef AHADIAG
  758                 ccb = aha_ccb_phys_kv(sc, phystol(wmbo->ccb_addr));
  759                 if (!ccb) {
  760                         printf("%s: bad mbo ccb pointer; skipping\n",
  761                             sc->sc_dev.dv_xname);
  762                 } else
  763                         ccb->flags &= ~CCB_SENDING;
  764 #endif
  765 
  766                 --sc->sc_mbofull;
  767                 aha_nextmbx(wmbo, wmbx, mbo);
  768         }
  769 
  770         wmbx->cmbo = wmbo;
  771 }
  772 
  773 /*
  774  * Send as many CCBs as we have empty mailboxes for.
  775  */
  776 void
  777 aha_start_ccbs(sc)
  778         struct aha_softc *sc;
  779 {
  780         int iobase = sc->sc_iobase;
  781         struct aha_mbx_out *wmbo;       /* Mail Box Out pointer */
  782         struct aha_ccb *ccb;
  783 
  784         wmbo = wmbx->tmbo;
  785 
  786         while ((ccb = TAILQ_FIRST(&sc->sc_waiting_ccb)) != NULL) {
  787                 if (sc->sc_mbofull >= AHA_MBX_SIZE) {
  788                         aha_collect_mbo(sc);
  789                         if (sc->sc_mbofull >= AHA_MBX_SIZE) {
  790                                 struct aha_toggle toggle;
  791 
  792                                 toggle.cmd.opcode = AHA_MBO_INTR_EN;
  793                                 toggle.cmd.enable = 1;
  794                                 aha_cmd(iobase, sc, sizeof(toggle.cmd),
  795                                     (u_char *)&toggle.cmd, 0, (u_char *)0);
  796                                 break;
  797                         }
  798                 }
  799 
  800                 TAILQ_REMOVE(&sc->sc_waiting_ccb, ccb, chain);
  801 #ifdef AHADIAG
  802                 ccb->flags |= CCB_SENDING;
  803 #endif
  804 
  805                 /* Link ccb to mbo. */
  806                 bus_dmamap_sync(sc->sc_dmat, ccb->ccb_dmam, 0,
  807                     ccb->ccb_dmam->dm_mapsize, BUS_DMASYNC_PREWRITE);
  808                 ltophys(ccb->ccb_dmam->dm_segs[0].ds_addr, wmbo->ccb_addr);
  809                 if (ccb->flags & CCB_ABORT)
  810                         wmbo->cmd = AHA_MBO_ABORT;
  811                 else
  812                         wmbo->cmd = AHA_MBO_START;
  813 
  814                 /* Tell the card to poll immediately. */
  815                 outb(iobase + AHA_CMD_PORT, AHA_START_SCSI);
  816 
  817                 if ((ccb->xs->flags & SCSI_POLL) == 0) {
  818                         timeout_set(&ccb->xs->stimeout, aha_timeout, ccb);
  819                         timeout_add(&ccb->xs->stimeout, (ccb->timeout * hz) / 1000);
  820                 }
  821 
  822                 ++sc->sc_mbofull;
  823                 aha_nextmbx(wmbo, wmbx, mbo);
  824         }
  825 
  826         wmbx->tmbo = wmbo;
  827 }
  828 
  829 /*
  830  * We have a ccb which has been processed by the
  831  * adaptor, now we look to see how the operation
  832  * went. Wake up the owner if waiting
  833  */
  834 void
  835 aha_done(sc, ccb)
  836         struct aha_softc *sc;
  837         struct aha_ccb *ccb;
  838 {
  839         struct scsi_sense_data *s1, *s2;
  840         struct scsi_xfer *xs = ccb->xs;
  841 
  842         SC_DEBUG(xs->sc_link, SDEV_DB2, ("aha_done\n"));
  843         /*
  844          * Otherwise, put the results of the operation
  845          * into the xfer and call whoever started it
  846          */
  847 #ifdef AHADIAG
  848         if (ccb->flags & CCB_SENDING) {
  849                 printf("%s: exiting ccb still in transit!\n",
  850                     sc->sc_dev.dv_xname);
  851                 Debugger();
  852                 return;
  853         }
  854 #endif
  855         if ((ccb->flags & CCB_ALLOC) == 0) {
  856                 printf("%s: exiting ccb not allocated!\n",
  857                     sc->sc_dev.dv_xname);
  858                 Debugger();
  859                 return;
  860         }
  861         if (xs->error == XS_NOERROR) {
  862                 if (ccb->host_stat != AHA_OK) {
  863                         switch (ccb->host_stat) {
  864                         case AHA_SEL_TIMEOUT:   /* No response */
  865                                 xs->error = XS_SELTIMEOUT;
  866                                 break;
  867                         default:        /* Other scsi protocol messes */
  868                                 printf("%s: host_stat %x\n",
  869                                     sc->sc_dev.dv_xname, ccb->host_stat);
  870                                 xs->error = XS_DRIVER_STUFFUP;
  871                                 break;
  872                         }
  873                 } else if (ccb->target_stat != SCSI_OK) {
  874                         switch (ccb->target_stat) {
  875                         case SCSI_CHECK:
  876                                 s1 = (struct scsi_sense_data *)
  877                                     (((char *)(&ccb->scsi_cmd)) +
  878                                     ccb->scsi_cmd_length);
  879                                 s2 = &xs->sense;
  880                                 *s2 = *s1;
  881                                 xs->error = XS_SENSE;
  882                                 break;
  883                         case SCSI_BUSY:
  884                                 xs->error = XS_BUSY;
  885                                 break;
  886                         default:
  887                                 printf("%s: target_stat %x\n",
  888                                     sc->sc_dev.dv_xname, ccb->target_stat);
  889                                 xs->error = XS_DRIVER_STUFFUP;
  890                                 break;
  891                         }
  892                 } else
  893                         xs->resid = 0;
  894         }
  895         xs->flags |= ITSDONE;
  896 
  897         if (VOLATILE_XS(xs)) {
  898                 wakeup(ccb);
  899                 return;
  900         }
  901 
  902         if (ccb->dmam->dm_nsegs > 0) {
  903                 if (xs->flags & SCSI_DATA_IN)
  904                         bus_dmamap_sync(sc->sc_dmat, ccb->dmam, 0,
  905                             ccb->dmam->dm_mapsize, BUS_DMASYNC_POSTREAD);
  906                 if (xs->flags & SCSI_DATA_OUT)
  907                         bus_dmamap_sync(sc->sc_dmat, ccb->dmam, 0,
  908                             ccb->dmam->dm_mapsize, BUS_DMASYNC_POSTWRITE);
  909                 bus_dmamap_unload(sc->sc_dmat, ccb->dmam);
  910         }
  911         aha_free_ccb(sc, ccb);
  912         scsi_done(xs);
  913 }
  914 
  915 /*
  916  * Find the board and find its irq/drq
  917  */
  918 int
  919 aha_find(ia, sc, isapnp)
  920         struct isa_attach_args *ia;
  921         struct aha_softc *sc;
  922         int isapnp;
  923 {
  924         int iobase = ia->ia_iobase;
  925         int i;
  926         u_char sts;
  927         struct aha_config config;
  928         int irq, drq;
  929 
  930         /*
  931          * reset board, If it doesn't respond, assume
  932          * that it's not there.. good for the probe
  933          */
  934 
  935         outb(iobase + AHA_CTRL_PORT, AHA_CTRL_HRST | AHA_CTRL_SRST);
  936 
  937         delay(100);
  938         for (i = AHA_RESET_TIMEOUT; i; i--) {
  939                 sts = inb(iobase + AHA_STAT_PORT);
  940                 if (sts == (AHA_STAT_IDLE | AHA_STAT_INIT))
  941                         break;
  942                 delay(1000);    /* calibrated in msec */
  943         }
  944         if (!i) {
  945 #ifdef AHADEBUG
  946                 if (aha_debug)
  947                         printf("aha_find: No answer from adaptec board\n");
  948 #endif /* AHADEBUG */
  949                 return (1);
  950         }
  951 
  952         /*
  953          * setup dma channel from jumpers and save int
  954          * level
  955          */
  956         delay(1000);            /* for Bustek 545 */
  957         config.cmd.opcode = AHA_INQUIRE_CONFIG;
  958         aha_cmd(iobase, sc, sizeof(config.cmd), (u_char *)&config.cmd,
  959             sizeof(config.reply), (u_char *)&config.reply);
  960         switch (config.reply.chan) {
  961         case EISADMA:
  962                 drq = DRQUNK;   /* for EISA/VLB/PCI clones */
  963                 break;
  964         case CHAN0:
  965                 drq = 0;
  966                 break;
  967         case CHAN5:
  968                 drq = 5;
  969                 break;
  970         case CHAN6:
  971                 drq = 6;
  972                 break;
  973         case CHAN7:
  974                 drq = 7;
  975                 break;
  976         default:
  977                 printf("aha_find: illegal drq setting %x\n",
  978                     config.reply.chan);
  979                 return (1);
  980         }
  981         if (isapnp)
  982                 irq = ia->ia_irq;
  983 
  984         switch (config.reply.intr) {
  985         case INT9:
  986                 irq = 9;
  987                 break;
  988         case INT10:
  989                 irq = 10;
  990                 break;
  991         case INT11:
  992                 irq = 11;
  993                 break;
  994         case INT12:
  995                 irq = 12;
  996                 break;
  997         case INT14:
  998                 irq = 14;
  999                 break;
 1000         case INT15:
 1001                 irq = 15;
 1002                 break;
 1003         default:
 1004                 printf("aha_find: illegal irq setting %x\n",
 1005                     config.reply.intr);
 1006                 return (EIO);
 1007         }
 1008         if (isapnp)
 1009                 drq = ia->ia_drq;
 1010 
 1011         if (sc != NULL) {
 1012                 /* who are we on the scsi bus? */
 1013                 sc->sc_scsi_dev = config.reply.scsi_dev;
 1014 
 1015                 sc->sc_iobase = iobase;
 1016                 sc->sc_irq = irq;
 1017                 sc->sc_drq = drq;
 1018         } else {
 1019                 if (isapnp)
 1020                         return (0);
 1021                 if (ia->ia_irq == IRQUNK)
 1022                         ia->ia_irq = irq;
 1023                 else if (ia->ia_irq != irq)
 1024                         return (1);
 1025                 if (ia->ia_drq == DRQUNK)
 1026                         ia->ia_drq = drq;
 1027                 else if (ia->ia_drq != drq)
 1028                         return (1);
 1029         }
 1030 
 1031         return (0);
 1032 }
 1033 
 1034 /*
 1035  * Start the board, ready for normal operation
 1036  */
 1037 void
 1038 aha_init(sc)
 1039         struct aha_softc *sc;
 1040 {
 1041         int iobase = sc->sc_iobase;
 1042         struct aha_devices devices;
 1043         struct aha_setup setup;
 1044         struct aha_mailbox mailbox;
 1045         struct pglist pglist;
 1046         struct vm_page *pg;
 1047         vaddr_t va;
 1048         vsize_t size;
 1049         int i;
 1050 
 1051         /*
 1052          * XXX
 1053          * If we are a 1542C or later, disable the extended BIOS so that the
 1054          * mailbox interface is unlocked.
 1055          * No need to check the extended BIOS flags as some of the
 1056          * extensions that cause us problems are not flagged in that byte.
 1057          */
 1058         if (!strncmp(sc->sc_model, "1542C", 5)) {
 1059                 struct aha_extbios extbios;
 1060                 struct aha_unlock unlock;
 1061 
 1062                 printf("%s: unlocking mailbox interface\n",
 1063                     sc->sc_dev.dv_xname);
 1064                 extbios.cmd.opcode = AHA_EXT_BIOS;
 1065                 aha_cmd(iobase, sc, sizeof(extbios.cmd),
 1066                     (u_char *)&extbios.cmd, sizeof(extbios.reply),
 1067                     (u_char *)&extbios.reply);
 1068 
 1069 #ifdef AHADEBUG
 1070                 printf("%s: flags=%02x, mailboxlock=%02x\n",
 1071                     sc->sc_dev.dv_xname,
 1072                     extbios.reply.flags, extbios.reply.mailboxlock);
 1073 #endif /* AHADEBUG */
 1074 
 1075                 unlock.cmd.opcode = AHA_MBX_ENABLE;
 1076                 unlock.cmd.junk = 0;
 1077                 unlock.cmd.magic = extbios.reply.mailboxlock;
 1078                 aha_cmd(iobase, sc, sizeof(unlock.cmd), (u_char *)&unlock.cmd,
 1079                     0, (u_char *)0);
 1080         }
 1081 
 1082 #if 0
 1083         /*
 1084          * Change the bus on/off times to not clash with other dma users.
 1085          */
 1086         aha_cmd(sc, 1, 0, 0, 0, AHA_BUS_ON_TIME_SET, 7);
 1087         aha_cmd(sc, 1, 0, 0, 0, AHA_BUS_OFF_TIME_SET, 4);
 1088 #endif
 1089 
 1090         /* Inquire Installed Devices (to force synchronous negotiation). */
 1091         devices.cmd.opcode = AHA_INQUIRE_DEVICES;
 1092         aha_cmd(iobase, sc, sizeof(devices.cmd), (u_char *)&devices.cmd,
 1093             sizeof(devices.reply), (u_char *)&devices.reply);
 1094 
 1095         /* Obtain setup information from. */
 1096         setup.cmd.opcode = AHA_INQUIRE_SETUP;
 1097         setup.cmd.len = sizeof(setup.reply);
 1098         aha_cmd(iobase, sc, sizeof(setup.cmd), (u_char *)&setup.cmd,
 1099             sizeof(setup.reply), (u_char *)&setup.reply);
 1100 
 1101         printf("%s: %s, %s\n",
 1102             sc->sc_dev.dv_xname,
 1103             setup.reply.sync_neg ? "sync" : "async",
 1104             setup.reply.parity ? "parity" : "no parity");
 1105 
 1106         for (i = 0; i < 8; i++) {
 1107                 if (!setup.reply.sync[i].valid ||
 1108                     (!setup.reply.sync[i].offset &&
 1109                     !setup.reply.sync[i].period))
 1110                         continue;
 1111                 printf("%s targ %d: sync, offset %d, period %dnsec\n",
 1112                     sc->sc_dev.dv_xname, i, setup.reply.sync[i].offset,
 1113                     setup.reply.sync[i].period * 50 + 200);
 1114         }
 1115 
 1116         /*
 1117          * Set up initial mail box for round-robin operation.
 1118          */
 1119 
 1120         /*
 1121          * XXX - this vm juggling is so wrong. use bus_dma instead!
 1122          */
 1123         size = round_page(sizeof(struct aha_mbx));
 1124         TAILQ_INIT(&pglist);
 1125         if (uvm_pglistalloc(size, 0, 0xffffff, PAGE_SIZE, 0, &pglist, 1, 0) ||
 1126             uvm_map(kernel_map, &va, size, NULL, UVM_UNKNOWN_OFFSET, 0,
 1127                 UVM_MAPFLAG(UVM_PROT_ALL, UVM_PROT_ALL, UVM_INH_NONE,
 1128                         UVM_ADV_RANDOM, 0)))
 1129                 panic("aha_init: could not allocate mailbox");
 1130 
 1131         wmbx = (struct aha_mbx *)va;
 1132         for (pg = TAILQ_FIRST(&pglist); pg != NULL;
 1133             pg = TAILQ_NEXT(pg, pageq)) {
 1134                 pmap_kenter_pa(va, VM_PAGE_TO_PHYS(pg),
 1135                         VM_PROT_READ|VM_PROT_WRITE);
 1136                 va += PAGE_SIZE;
 1137         }
 1138         pmap_update(pmap_kernel());
 1139         /*
 1140          * XXXEND
 1141          */
 1142 
 1143         for (i = 0; i < AHA_MBX_SIZE; i++) {
 1144                 wmbx->mbo[i].cmd = AHA_MBO_FREE;
 1145                 wmbx->mbi[i].stat = AHA_MBI_FREE;
 1146         }
 1147         wmbx->cmbo = wmbx->tmbo = &wmbx->mbo[0];
 1148         wmbx->tmbi = &wmbx->mbi[0];
 1149         sc->sc_mbofull = 0;
 1150 
 1151         /* Initialize mail box. */
 1152         mailbox.cmd.opcode = AHA_MBX_INIT;
 1153         mailbox.cmd.nmbx = AHA_MBX_SIZE;
 1154         ltophys(vtophys((vaddr_t)wmbx), mailbox.cmd.addr);
 1155         aha_cmd(iobase, sc, sizeof(mailbox.cmd), (u_char *)&mailbox.cmd,
 1156             0, (u_char *)0);
 1157 }
 1158 
 1159 void
 1160 aha_inquire_setup_information(sc)
 1161         struct aha_softc *sc;
 1162 {
 1163         int iobase = sc->sc_iobase;
 1164         struct aha_revision revision;
 1165         u_char sts;
 1166         int i;
 1167         char *p;
 1168 
 1169         strlcpy(sc->sc_model, "unknown", sizeof sc->sc_model);
 1170 
 1171         /*
 1172          * Assume we have a board at this stage, do an adapter inquire
 1173          * to find out what type of controller it is.  If the command
 1174          * fails, we assume it's either a crusty board or an old 1542
 1175          * clone, and skip the board-specific stuff.
 1176          */
 1177         revision.cmd.opcode = AHA_INQUIRE_REVISION;
 1178         if (aha_cmd(iobase, sc, sizeof(revision.cmd), (u_char *)&revision.cmd,
 1179             sizeof(revision.reply), (u_char *)&revision.reply)) {
 1180                 /*
 1181                  * aha_cmd() already started the reset.  It's not clear we
 1182                  * even need to bother here.
 1183                  */
 1184                 for (i = AHA_RESET_TIMEOUT; i; i--) {
 1185                         sts = inb(iobase + AHA_STAT_PORT);
 1186                         if (sts == (AHA_STAT_IDLE | AHA_STAT_INIT))
 1187                                 break;
 1188                         delay(1000);
 1189                 }
 1190                 if (!i) {
 1191 #ifdef AHADEBUG
 1192                         printf("aha_init: soft reset failed\n");
 1193 #endif /* AHADEBUG */
 1194                         return;
 1195                 }
 1196 #ifdef AHADEBUG
 1197                 printf("aha_init: inquire command failed\n");
 1198 #endif /* AHADEBUG */
 1199                 goto noinquire;
 1200         }
 1201 
 1202 #ifdef AHADEBUG
 1203         printf("%s: inquire %x, %x, %x, %x\n",
 1204             sc->sc_dev.dv_xname,
 1205             revision.reply.boardid, revision.reply.spec_opts,
 1206             revision.reply.revision_1, revision.reply.revision_2);
 1207 #endif /* AHADEBUG */
 1208 
 1209         switch (revision.reply.boardid) {
 1210         case 0x31:
 1211                 strlcpy(sc->sc_model, "1540", sizeof sc->sc_model);
 1212                 break;
 1213         case 0x41:
 1214                 strlcpy(sc->sc_model, "1540A/1542A/1542B", sizeof sc->sc_model);
 1215                 break;
 1216         case 0x42:
 1217                 strlcpy(sc->sc_model, "1640", sizeof sc->sc_model);
 1218                 break;
 1219         case 0x43:
 1220         case 0x44:              /* Is this 1542C or -CF? */
 1221                 strlcpy(sc->sc_model, "1542C", sizeof sc->sc_model);
 1222                 break;
 1223         case 0x45:
 1224                 strlcpy(sc->sc_model, "1542CF", sizeof sc->sc_model);
 1225                 break;
 1226         case 0x46:
 1227                 strlcpy(sc->sc_model, "1542CP", sizeof sc->sc_model);
 1228                 break;
 1229         }
 1230 
 1231         p = sc->sc_firmware;
 1232         *p++ = revision.reply.revision_1;
 1233         *p++ = '.';
 1234         *p++ = revision.reply.revision_2;
 1235         *p = '\0';
 1236 
 1237 noinquire:
 1238         printf(": model AHA-%s, firmware %s\n", sc->sc_model, sc->sc_firmware);
 1239 }
 1240 
 1241 void
 1242 ahaminphys(bp)
 1243         struct buf *bp;
 1244 {
 1245 
 1246         if (bp->b_bcount > ((AHA_NSEG - 1) << PGSHIFT))
 1247                 bp->b_bcount = ((AHA_NSEG - 1) << PGSHIFT);
 1248         minphys(bp);
 1249 }
 1250 
 1251 /*
 1252  * start a scsi operation given the command and the data address. Also needs
 1253  * the unit, target and lu.
 1254  */
 1255 int
 1256 aha_scsi_cmd(xs)
 1257         struct scsi_xfer *xs;
 1258 {
 1259         struct scsi_link *sc_link = xs->sc_link;
 1260         struct aha_softc *sc = sc_link->adapter_softc;
 1261         struct aha_ccb *ccb;
 1262         struct aha_scat_gath *sg;
 1263         int seg, flags;
 1264 #ifdef  TFS
 1265         struct iovec *iovp;
 1266         int datalen;
 1267 #endif
 1268         int s;
 1269 
 1270         SC_DEBUG(sc_link, SDEV_DB2, ("aha_scsi_cmd\n"));
 1271         /*
 1272          * get a ccb to use. If the transfer
 1273          * is from a buf (possibly from interrupt time)
 1274          * then we can't allow it to sleep
 1275          */
 1276         flags = xs->flags;
 1277         if ((ccb = aha_get_ccb(sc, flags)) == NULL) {
 1278                 return (TRY_AGAIN_LATER);
 1279         }
 1280         ccb->xs = xs;
 1281         ccb->timeout = xs->timeout;
 1282 
 1283         /*
 1284          * Put all the arguments for the xfer in the ccb
 1285          */
 1286         if (flags & SCSI_RESET) {
 1287                 ccb->opcode = AHA_RESET_CCB;
 1288                 ccb->scsi_cmd_length = 0;
 1289         } else {
 1290                 /* can't use S/G if zero length */
 1291                 ccb->opcode =
 1292                     (xs->datalen ? AHA_INIT_SCAT_GATH_CCB : AHA_INITIATOR_CCB);
 1293                 bcopy(xs->cmd, &ccb->scsi_cmd,
 1294                     ccb->scsi_cmd_length = xs->cmdlen);
 1295         }
 1296 
 1297         if (xs->datalen) {
 1298                 sg = ccb->scat_gath;
 1299                 seg = 0;
 1300 #ifdef  TFS
 1301                 if (flags & SCSI_DATA_UIO) {
 1302                         iovp = ((struct uio *)xs->data)->uio_iov;
 1303                         datalen = ((struct uio *)xs->data)->uio_iovcnt;
 1304                         xs->datalen = 0;
 1305                         while (datalen && seg < AHA_NSEG) {
 1306                                 ltophys(iovp->iov_base, sg->seg_addr);
 1307                                 ltophys(iovp->iov_len, sg->seg_len);
 1308                                 xs->datalen += iovp->iov_len;
 1309                                 SC_DEBUGN(sc_link, SDEV_DB4, ("UIO(0x%x@0x%x)",
 1310                                     iovp->iov_len, iovp->iov_base));
 1311                                 sg++;
 1312                                 iovp++;
 1313                                 seg++;
 1314                                 datalen--;
 1315                         }
 1316                 } else
 1317 #endif /* TFS */
 1318                 {
 1319                         /*
 1320                          * Set up the scatter-gather block.
 1321                          */
 1322                         if (bus_dmamap_load(sc->sc_dmat, ccb->dmam, xs->data,
 1323                             xs->datalen, NULL, BUS_DMA_NOWAIT) != 0) {
 1324                                 aha_free_ccb(sc, ccb);
 1325                                 xs->error = XS_DRIVER_STUFFUP;
 1326                                 return (TRY_AGAIN_LATER);
 1327                         }
 1328                         for (seg = 0; seg < ccb->dmam->dm_nsegs; seg++) {
 1329                                 ltophys(ccb->dmam->dm_segs[seg].ds_addr,
 1330                                     sg[seg].seg_addr);
 1331                                 ltophys(ccb->dmam->dm_segs[seg].ds_len,
 1332                                     sg[seg].seg_len);
 1333                         }
 1334                 }
 1335                 if (flags & SCSI_DATA_OUT)
 1336                         bus_dmamap_sync(sc->sc_dmat, ccb->dmam, 0,
 1337                             ccb->dmam->dm_mapsize, BUS_DMASYNC_PREWRITE);
 1338                 if (flags & SCSI_DATA_IN)
 1339                         bus_dmamap_sync(sc->sc_dmat, ccb->dmam, 0,
 1340                             ccb->dmam->dm_mapsize, BUS_DMASYNC_PREREAD);
 1341                 ltophys((unsigned)
 1342                     ((struct aha_ccb *)(ccb->ccb_dmam->dm_segs[0].ds_addr))->
 1343                     scat_gath,
 1344                     ccb->data_addr);
 1345                 ltophys(ccb->dmam->dm_nsegs * sizeof(struct aha_scat_gath),
 1346                     ccb->data_length);
 1347         } else {                /* No data xfer, use non S/G values */
 1348                 ltophys(0, ccb->data_addr);
 1349                 ltophys(0, ccb->data_length);
 1350         }
 1351 
 1352         ccb->data_out = 0;
 1353         ccb->data_in = 0;
 1354         ccb->target = sc_link->target;
 1355         ccb->lun = sc_link->lun;
 1356         ccb->req_sense_length = sizeof(ccb->scsi_sense);
 1357         ccb->host_stat = 0x00;
 1358         ccb->target_stat = 0x00;
 1359         ccb->link_id = 0;
 1360         ltophys(0, ccb->link_addr);
 1361 
 1362         s = splbio();
 1363         aha_queue_ccb(sc, ccb);
 1364 
 1365         /*
 1366          * Usually return SUCCESSFULLY QUEUED
 1367          */
 1368         SC_DEBUG(sc_link, SDEV_DB3, ("cmd_sent\n"));
 1369 
 1370         if (VOLATILE_XS(xs)) {
 1371                 while ((ccb->xs->flags & ITSDONE) == 0) {
 1372                         tsleep(ccb, PRIBIO, "ahawait", 0);
 1373                 }
 1374                 if (ccb->dmam->dm_nsegs > 0) {
 1375                         if (flags & SCSI_DATA_OUT)
 1376                                 bus_dmamap_sync(sc->sc_dmat, ccb->dmam, 0,
 1377                                     ccb->dmam->dm_mapsize,
 1378                                     BUS_DMASYNC_POSTWRITE);
 1379                         if (flags & SCSI_DATA_IN)
 1380                                 bus_dmamap_sync(sc->sc_dmat, ccb->dmam, 0,
 1381                                     ccb->dmam->dm_mapsize,
 1382                                     BUS_DMASYNC_POSTREAD);
 1383                         bus_dmamap_unload(sc->sc_dmat, ccb->dmam);
 1384                 }
 1385                 aha_free_ccb(sc, ccb);
 1386                 scsi_done(xs);
 1387                 splx(s);
 1388                 return (COMPLETE);
 1389         }
 1390         splx(s);
 1391 
 1392         if ((flags & SCSI_POLL) == 0)
 1393                 return (SUCCESSFULLY_QUEUED);
 1394 
 1395         /*
 1396          * If we can't use interrupts, poll on completion
 1397          */
 1398         if (aha_poll(sc, xs, ccb->timeout)) {
 1399                 aha_timeout(ccb);
 1400                 if (aha_poll(sc, xs, ccb->timeout))
 1401                         aha_timeout(ccb);
 1402         }
 1403         return (COMPLETE);
 1404 }
 1405 
 1406 /*
 1407  * Poll a particular unit, looking for a particular xs
 1408  */
 1409 int
 1410 aha_poll(sc, xs, count)
 1411         struct aha_softc *sc;
 1412         struct scsi_xfer *xs;
 1413         int count;
 1414 {
 1415         int iobase = sc->sc_iobase;
 1416         int s;
 1417 
 1418         /* timeouts are in msec, so we loop in 1000 usec cycles */
 1419         while (count) {
 1420                 /*
 1421                  * If we had interrupts enabled, would we
 1422                  * have got an interrupt?
 1423                  */
 1424                 if (inb(iobase + AHA_INTR_PORT) & AHA_INTR_ANYINTR) {
 1425                         s = splbio();
 1426                         ahaintr(sc);
 1427                         splx(s);
 1428                 }
 1429                 if (xs->flags & ITSDONE)
 1430                         return (0);
 1431                 delay(1000);    /* only happens in boot so ok */
 1432                 count--;
 1433         }
 1434         return (1);
 1435 }
 1436 
 1437 void
 1438 aha_timeout(arg)
 1439         void *arg;
 1440 {
 1441         struct aha_ccb *ccb = arg;
 1442         struct scsi_xfer *xs;
 1443         struct scsi_link *sc_link;
 1444         struct aha_softc *sc;
 1445         int s;
 1446 
 1447         s = splbio();
 1448         bus_dmamap_sync(sc->sc_dmat, ccb->ccb_dmam, 0,
 1449             ccb->ccb_dmam->dm_mapsize, BUS_DMASYNC_POSTREAD);
 1450         xs = ccb->xs;
 1451         sc_link = xs->sc_link;
 1452         sc = sc_link->adapter_softc;
 1453 
 1454         sc_print_addr(sc_link);
 1455         printf("timed out");
 1456 
 1457 #ifdef AHADIAG
 1458         /*
 1459          * If The ccb's mbx is not free, then the board has gone south?
 1460          */
 1461         aha_collect_mbo(sc);
 1462         if (ccb->flags & CCB_SENDING) {
 1463                 printf("%s: not taking commands!\n", sc->sc_dev.dv_xname);
 1464                 Debugger();
 1465         }
 1466 #endif
 1467 
 1468         /*
 1469          * If it has been through before, then
 1470          * a previous abort has failed, don't
 1471          * try abort again
 1472          */
 1473         if (ccb->flags & CCB_ABORT) {
 1474                 /* abort timed out */
 1475                 printf(" AGAIN\n");
 1476                 /* XXX Must reset! */
 1477         } else {
 1478                 /* abort the operation that has timed out */
 1479                 printf("\n");
 1480                 ccb->xs->error = XS_TIMEOUT;
 1481                 ccb->timeout = AHA_ABORT_TIMEOUT;
 1482                 ccb->flags |= CCB_ABORT;
 1483                 aha_queue_ccb(sc, ccb);
 1484         }
 1485 
 1486         splx(s);
 1487 }
 1488 

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