root/dev/ic/dpt.c

/* [<][>][^][v][top][bottom][index][help] */
    1 /*      $OpenBSD: dpt.c,v 1.12 2007/04/10 17:47:55 miod Exp $   */
    2 /*      $NetBSD: dpt.c,v 1.12 1999/10/23 16:26:33 ad Exp $      */
    3 
    4 /*-
    5  * Copyright (c) 1997, 1998, 1999 The NetBSD Foundation, Inc.
    6  * All rights reserved.
    7  *
    8  * This code is derived from software contributed to The NetBSD Foundation
    9  * by Andy Doran, Charles M. Hannum and by Jason R. Thorpe of the Numerical 
   10  * Aerospace Simulation Facility, NASA Ames Research Center.
   11  *
   12  * Redistribution and use in source and binary forms, with or without
   13  * modification, are permitted provided that the following conditions
   14  * are met:
   15  * 1. Redistributions of source code must retain the above copyright
   16  *    notice, this list of conditions and the following disclaimer.
   17  * 2. Redistributions in binary form must reproduce the above copyright
   18  *    notice, this list of conditions and the following disclaimer in the
   19  *    documentation and/or other materials provided with the distribution.
   20  * 3. All advertising materials mentioning features or use of this software
   21  *    must display the following acknowledgement:
   22  *      This product includes software developed by the NetBSD
   23  *      Foundation, Inc. and its contributors.
   24  * 4. Neither the name of The NetBSD Foundation nor the names of its
   25  *    contributors may be used to endorse or promote products derived
   26  *    from this software without specific prior written permission.
   27  *
   28  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
   29  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
   30  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   31  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
   32  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   33  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   34  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   35  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   36  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   37  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   38  * POSSIBILITY OF SUCH DAMAGE.
   39  */
   40 
   41 /*
   42  * Portions of this code fall under the following copyright:
   43  *
   44  * Originally written by Julian Elischer (julian@tfs.com)
   45  * for TRW Financial Systems for use under the MACH(2.5) operating system.
   46  *
   47  * TRW Financial Systems, in accordance with their agreement with Carnegie
   48  * Mellon University, makes this software available to CMU to distribute
   49  * or use in any manner that they see fit as long as this message is kept with
   50  * the software. For this reason TFS also grants any other persons or
   51  * organisations permission to use or modify this software.
   52  *
   53  * TFS supplies this software to be publicly redistributed
   54  * on the understanding that TFS is not responsible for the correct
   55  * functioning of this software in any circumstances.
   56  */
   57 
   58 /*
   59  * Driver for DPT EATA SCSI adapters.
   60  *
   61  * TODO:
   62  *
   63  * o Need a front-end for (newer) ISA boards.
   64  * o Handle older firmware better.
   65  * o Find a bunch of different firmware EEPROMs and try them out.
   66  * o Test with a bunch of different boards.
   67  * o dpt_readcfg() should not be using CP_PIO_GETCFG.
   68  * o An interface to userland applications.
   69  * o Some sysctls or a utility (eg dptctl(8)) to control parameters.
   70  */
   71 
   72 #include <sys/cdefs.h>
   73 #ifdef __NetBSD__
   74 __KERNEL_RCSID(0, "$NetBSD: dpt.c,v 1.12 1999/10/23 16:26:33 ad Exp $");
   75 #endif /* __NetBSD__ */
   76 
   77 #include <sys/param.h>
   78 #include <sys/systm.h>
   79 #include <sys/kernel.h>
   80 #include <sys/device.h>
   81 #include <sys/queue.h>
   82 #include <sys/proc.h>
   83 #include <sys/buf.h>
   84 
   85 #include <machine/endian.h>
   86 #ifdef __NetBSD__
   87 #include <machine/bswap.h>
   88 #endif /* __NetBSD__ */
   89 #include <machine/bus.h>
   90 
   91 #ifdef __NetBSD__
   92 #include <dev/scsipi/scsi_all.h>
   93 #include <dev/scsipi/scsipi_all.h>
   94 #include <dev/scsipi/scsiconf.h>
   95 #endif /* __NetBSD__ */
   96 #ifdef __OpenBSD__
   97 #include <scsi/scsi_all.h>
   98 #include <scsi/scsiconf.h>
   99 #endif /* __OpenBSD__ */
  100 
  101 #include <dev/ic/dptreg.h>
  102 #include <dev/ic/dptvar.h>
  103 
  104 #ifdef __OpenBSD__
  105 static void dpt_enqueue(struct dpt_softc *, struct scsi_xfer *, int);
  106 static struct scsi_xfer *dpt_dequeue(struct dpt_softc *);
  107 
  108 struct cfdriver dpt_cd = {
  109         NULL, "dpt", DV_DULL
  110 };
  111 #endif /* __OpenBSD__ */
  112 
  113 /* A default for our link struct */
  114 #ifdef __NetBSD__
  115 static struct scsipi_device dpt_dev = {
  116 #endif /* __NetBSD__ */
  117 #ifdef __OpenBSD__
  118 static struct scsi_device dpt_dev = {
  119 #endif /* __OpenBSD__ */
  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 #ifndef offsetof
  127 #define offsetof(type, member) (int)((&((type *)0)->member))
  128 #endif /* offsetof */
  129 
  130 static char *dpt_cname[] = {
  131         "PM3334", "SmartRAID IV",
  132         "PM3332", "SmartRAID IV",
  133         "PM2144", "SmartCache IV",
  134         "PM2044", "SmartCache IV",
  135         "PM2142", "SmartCache IV",
  136         "PM2042", "SmartCache IV",
  137         "PM2041", "SmartCache IV",
  138         "PM3224", "SmartRAID III",
  139         "PM3222", "SmartRAID III", 
  140         "PM3021", "SmartRAID III",
  141         "PM2124", "SmartCache III",
  142         "PM2024", "SmartCache III",
  143         "PM2122", "SmartCache III",
  144         "PM2022", "SmartCache III",
  145         "PM2021", "SmartCache III",
  146         "SK2012", "SmartCache Plus", 
  147         "SK2011", "SmartCache Plus",
  148         NULL,     "unknown adapter, please report using sendbug(1)",
  149 };
  150 
  151 /*
  152  * Handle an interrupt from the HBA.
  153  */
  154 int
  155 dpt_intr(xxx_sc)
  156         void *xxx_sc;
  157 {
  158         struct dpt_softc *sc;
  159         struct dpt_ccb *ccb;
  160         struct eata_sp *sp;
  161         static int moretimo;
  162         int more;
  163 
  164         sc = xxx_sc;
  165         sp = sc->sc_statpack;
  166 
  167         if (!sp) {
  168 #ifdef DEBUG
  169                 printf("%s: premature intr (st:%02x aux:%02x)\n",
  170                         sc->sc_dv.dv_xname, dpt_inb(sc, HA_STATUS),
  171                         dpt_inb(sc, HA_AUX_STATUS));
  172 #else /* DEBUG */
  173                 (void) dpt_inb(sc, HA_STATUS);
  174 #endif /* DEBUG */
  175                 return (0);
  176         }
  177 
  178         more = 0;
  179 
  180 #ifdef DEBUG
  181         if ((dpt_inb(sc, HA_AUX_STATUS) & HA_AUX_INTR) == 0)
  182                 printf("%s: spurious intr\n", sc->sc_dv.dv_xname);
  183 #endif
  184 
  185         /* Don't get stalled by HA_ST_MORE */
  186         if (moretimo < DPT_MORE_TIMEOUT / 100)
  187                 moretimo = 0;
  188         
  189         for (;;) {
  190                 /*
  191                  * HBA might have interrupted while we were dealing with the
  192                  * last completed command, since we ACK before we deal; keep 
  193                  * polling. If no interrupt is signalled, but the HBA has
  194                  * indicated that more data will be available soon, hang 
  195                  * around. 
  196                  */ 
  197                 if ((dpt_inb(sc, HA_AUX_STATUS) & HA_AUX_INTR) == 0) {
  198                         if (more != 0 && moretimo++ < DPT_MORE_TIMEOUT / 100) {
  199                                 DELAY(10);
  200                                 continue;
  201                         }
  202                         break;
  203                 }
  204                 
  205                 bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap_ccb, sc->sc_spoff,
  206                     sizeof(struct eata_sp), BUS_DMASYNC_POSTREAD);
  207 
  208                 if (!sp) {
  209                         more = dpt_inb(sc, HA_STATUS) & HA_ST_MORE;
  210 
  211                         /* Don't get stalled by HA_ST_MORE */
  212                         if (moretimo < DPT_MORE_TIMEOUT / 100)
  213                                 moretimo = 0;
  214                         continue;
  215                 }
  216 
  217                 /* Might have looped before HBA can reset HBA_AUX_INTR */
  218                 if (sp->sp_ccbid == -1) {
  219                         DELAY(50);
  220 #ifdef DIAGNOSTIC
  221                         printf("%s: slow reset of HA_AUX_STATUS?",
  222                             sc->sc_dv.dv_xname);
  223 #endif
  224                         if ((dpt_inb(sc, HA_AUX_STATUS) & HA_AUX_INTR) == 0)
  225                                 return (0);
  226 #ifdef DIAGNOSTIC
  227                         printf("%s: was a slow reset of HA_AUX_STATUS",
  228                             sc->sc_dv.dv_xname);
  229 #endif
  230                         /* Re-sync DMA map */
  231                         bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap_ccb, 
  232                             sc->sc_spoff, sizeof(struct eata_sp),
  233                             BUS_DMASYNC_POSTREAD);
  234                 }
  235 
  236                 /* Make sure CCB ID from status packet is realistic */
  237                 if (sp->sp_ccbid >= 0 && sp->sp_ccbid < sc->sc_nccbs) {
  238                         /* Sync up DMA map and cache cmd status */
  239                         ccb = sc->sc_ccbs + sp->sp_ccbid;
  240 
  241                         bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap_ccb, 
  242                             CCB_OFF(sc, ccb), sizeof(struct dpt_ccb), 
  243                             BUS_DMASYNC_POSTWRITE);
  244 
  245                         ccb->ccb_hba_status = sp->sp_hba_status & 0x7F;
  246                         ccb->ccb_scsi_status = sp->sp_scsi_status;
  247 
  248                         /* 
  249                          * Ack the interrupt and process the CCB. If this
  250                          * is a private CCB it's up to dpt_poll() to notice.
  251                          */
  252                         sp->sp_ccbid = -1;
  253                         ccb->ccb_flg |= CCB_INTR;
  254                         more = dpt_inb(sc, HA_STATUS) & HA_ST_MORE;
  255                         if ((ccb->ccb_flg & CCB_PRIVATE) == 0)
  256                                 dpt_done_ccb(sc, ccb);
  257                 } else {
  258                         printf("%s: bogus status (returned CCB id %d)\n", 
  259                             sc->sc_dv.dv_xname, sp->sp_ccbid);
  260 
  261                         /* Ack the interrupt */
  262                         sp->sp_ccbid = -1;
  263                         more = dpt_inb(sc, HA_STATUS) & HA_ST_MORE;
  264                 }
  265                 
  266                 /* Don't get stalled by HA_ST_MORE */
  267                 if (moretimo < DPT_MORE_TIMEOUT / 100)
  268                         moretimo = 0;
  269         }
  270 
  271         return (0);
  272 }
  273 
  274 /*
  275  * Initialize and attach the HBA. This is the entry point from bus
  276  * specific probe-and-attach code.
  277  */
  278 void
  279 dpt_init(sc, intrstr)
  280         struct dpt_softc *sc;
  281         const char *intrstr;
  282 {
  283         struct eata_inquiry_data *ei;
  284         int i, j, error, rseg, mapsize;
  285         bus_dma_segment_t seg;
  286         struct eata_cfg *ec;
  287         char model[16];
  288 
  289         ec = &sc->sc_ec;
  290         
  291         /* Allocate the CCB/status packet/scratch DMA map and load */
  292         sc->sc_nccbs = min(betoh16(*(int16_t *)ec->ec_queuedepth),
  293                            DPT_MAX_CCBS);
  294         sc->sc_spoff = sc->sc_nccbs * sizeof(struct dpt_ccb);
  295         sc->sc_scroff = sc->sc_spoff + sizeof(struct eata_sp);
  296         sc->sc_scrlen = 256; /* XXX */
  297         mapsize = sc->sc_nccbs * sizeof(struct dpt_ccb) + sc->sc_scrlen +
  298             sizeof(struct eata_sp);
  299                 
  300         if ((error = bus_dmamem_alloc(sc->sc_dmat, mapsize, NBPG, 0, 
  301             &seg, 1, &rseg, BUS_DMA_NOWAIT)) != 0) {
  302                 printf("%s: unable to allocate CCBs, error = %d\n",
  303                     sc->sc_dv.dv_xname, error);
  304                 return;
  305         }
  306 
  307         if ((error = bus_dmamem_map(sc->sc_dmat, &seg, rseg, mapsize,
  308             (caddr_t *)&sc->sc_ccbs, BUS_DMA_NOWAIT|BUS_DMA_COHERENT)) != 0) {
  309                 printf("%s: unable to map CCBs, error = %d\n",
  310                     sc->sc_dv.dv_xname, error);
  311                 return;
  312         }
  313 
  314         if ((error = bus_dmamap_create(sc->sc_dmat, mapsize, mapsize, 1, 0, 
  315             BUS_DMA_NOWAIT, &sc->sc_dmamap_ccb)) != 0) {
  316                 printf("%s: unable to create CCB DMA map, error = %d\n",
  317                     sc->sc_dv.dv_xname, error);
  318                 return;
  319         }
  320 
  321         if ((error = bus_dmamap_load(sc->sc_dmat, sc->sc_dmamap_ccb,
  322             sc->sc_ccbs, mapsize, NULL, BUS_DMA_NOWAIT)) != 0) {
  323                 printf("%s: unable to load CCB DMA map, error = %d\n",
  324                     sc->sc_dv.dv_xname, error);
  325                 return;
  326         }
  327 
  328         sc->sc_statpack = (struct eata_sp *)((caddr_t)sc->sc_ccbs +
  329             sc->sc_spoff);
  330         sc->sc_sppa = sc->sc_dmamap_ccb->dm_segs[0].ds_addr + sc->sc_spoff;
  331         sc->sc_scr = (caddr_t)sc->sc_ccbs + sc->sc_scroff;
  332         sc->sc_scrpa = sc->sc_dmamap_ccb->dm_segs[0].ds_addr + sc->sc_scroff;
  333         sc->sc_statpack->sp_ccbid = -1;
  334 
  335         /* Initialize the CCBs */
  336         TAILQ_INIT(&sc->sc_free_ccb);
  337         i = dpt_create_ccbs(sc, sc->sc_ccbs, sc->sc_nccbs);
  338 
  339         if (i == 0) {
  340                 printf("%s: unable to create CCBs\n", sc->sc_dv.dv_xname);
  341                 return;
  342         } else if (i != sc->sc_nccbs) {
  343                 printf("%s: %d/%d CCBs created!\n", sc->sc_dv.dv_xname, i, 
  344                     sc->sc_nccbs);
  345                 sc->sc_nccbs = i;
  346         }
  347 
  348         /* Set shutdownhook before we start any device activity */
  349         sc->sc_sdh = shutdownhook_establish(dpt_shutdown, sc);
  350 
  351         /* Get the page 0 inquiry data from the HBA */
  352         dpt_hba_inquire(sc, &ei);
  353 
  354         /* 
  355          * dpt0 at pci0 dev 12 function 0: DPT SmartRAID III (PM3224A/9X-R)
  356          * dpt0: interrupting at irq 10
  357          * dpt0: 64 queued commands, 1 channel(s), adapter on ID(s) 7
  358          */
  359         for (i = 0; ei->ei_vendor[i] != ' ' && i < 8; i++)
  360                 ;
  361         ei->ei_vendor[i] = '\0';
  362 
  363         for (i = 0; ei->ei_model[i] != ' ' && i < 7; i++)
  364                 model[i] = ei->ei_model[i];
  365         for (j = 0; ei->ei_suffix[j] != ' ' && j < 7; j++)
  366                 model[i++] = ei->ei_suffix[j];
  367         model[i] = '\0';
  368 
  369         /* Find the canonical name for the board */
  370         for (i = 0; dpt_cname[i] != NULL; i += 2)
  371                 if (memcmp(ei->ei_model, dpt_cname[i], 6) == 0)
  372                         break;
  373                         
  374         printf("%s %s (%s)\n", ei->ei_vendor, dpt_cname[i + 1], model);
  375 
  376         if (intrstr != NULL)
  377                 printf("%s: interrupting at %s\n", sc->sc_dv.dv_xname, intrstr);
  378 
  379         printf("%s: %d queued commands, %d channel(s), adapter on ID(s)", 
  380             sc->sc_dv.dv_xname, sc->sc_nccbs, ec->ec_maxchannel + 1);
  381 
  382         for (i = 0; i <= ec->ec_maxchannel; i++)
  383                 printf(" %d", ec->ec_hba[3 - i]);
  384         printf("\n");
  385 
  386         /* Reset the SCSI bus */
  387         if (dpt_cmd(sc, NULL, 0, CP_IMMEDIATE, CPI_BUS_RESET))
  388                 panic("%s: dpt_cmd failed", sc->sc_dv.dv_xname);
  389         DELAY(20000);
  390         
  391         /* Fill in the adapter, each link and attach in turn */
  392 #ifdef __NetBSD__
  393         sc->sc_adapter.scsipi_cmd = dpt_scsi_cmd;
  394         sc->sc_adapter.scsipi_minphys = dpt_minphys;
  395 #endif /* __NetBSD__ */
  396 #ifdef __OpenBSD__
  397         sc->sc_adapter.scsi_cmd = dpt_scsi_cmd;
  398         sc->sc_adapter.scsi_minphys = dpt_minphys;
  399 #endif /* __OpenBSD__ */
  400 
  401         for (i = 0; i <= ec->ec_maxchannel; i++) {
  402 #ifdef __NetBSD__
  403                 struct scsipi_link *link;
  404 #endif /* __NetBSD__ */
  405 #ifdef __OpenBSD__
  406                 struct scsi_link *link;
  407 #endif /* __OpenBSD__ */
  408                 sc->sc_hbaid[i] = ec->ec_hba[3 - i];
  409                 link = &sc->sc_link[i];
  410 #ifdef __NetBSD__
  411                 link->scsipi_scsi.scsibus = i;
  412                 link->scsipi_scsi.adapter_target = sc->sc_hbaid[i];
  413                 link->scsipi_scsi.max_lun = ec->ec_maxlun;
  414                 link->scsipi_scsi.max_target = ec->ec_maxtarget;
  415                 link->type = BUS_SCSI;
  416 #endif /* __NetBSD__ */
  417 #ifdef __OpenBSD__
  418                 link->scsibus = i;
  419                 link->adapter_target = sc->sc_hbaid[i];
  420                 link->luns = ec->ec_maxlun + 1;
  421                 link->adapter_buswidth = ec->ec_maxtarget + 1;
  422 #endif /* __OpenBSD__ */
  423                 link->device = &dpt_dev;
  424                 link->adapter = &sc->sc_adapter;
  425                 link->adapter_softc = sc;
  426                 link->openings = sc->sc_nccbs;
  427                 config_found(&sc->sc_dv, link, scsiprint);
  428         }
  429 }
  430 
  431 /*
  432  * Our 'shutdownhook' to cleanly shut down the HBA. The HBA must flush 
  433  * all data from its cache and mark array groups as clean.
  434  */
  435 void
  436 dpt_shutdown(xxx_sc)
  437         void *xxx_sc;
  438 {
  439         struct dpt_softc *sc;
  440 
  441         sc = xxx_sc;
  442         printf("shutting down %s...", sc->sc_dv.dv_xname);
  443         dpt_cmd(sc, NULL, 0, CP_IMMEDIATE, CPI_POWEROFF_WARN);
  444         DELAY(5000*1000);
  445         printf(" done\n");
  446 }
  447 
  448 /*
  449  * Send an EATA command to the HBA.
  450  */
  451 int
  452 dpt_cmd(sc, cp, addr, eatacmd, icmd)
  453         struct dpt_softc *sc;
  454         struct eata_cp *cp;
  455         u_int32_t addr;
  456         int eatacmd, icmd;
  457 {
  458         int i;
  459         
  460         for (i = 20000; i; i--) {
  461                 if ((dpt_inb(sc, HA_AUX_STATUS) & HA_AUX_BUSY) == 0)
  462                         break;
  463                 DELAY(50);
  464         }
  465 
  466         /* Not the most graceful way to handle this */
  467         if (i == 0) {
  468                 printf("%s: HBA timeout on EATA command issue; aborting\n", 
  469                     sc->sc_dv.dv_xname);
  470                 return (-1);
  471         }
  472         
  473         if (cp == NULL)
  474                 addr = 0;
  475 
  476         dpt_outb(sc, HA_DMA_BASE + 0, (u_int32_t)addr);
  477         dpt_outb(sc, HA_DMA_BASE + 1, (u_int32_t)addr >> 8);
  478         dpt_outb(sc, HA_DMA_BASE + 2, (u_int32_t)addr >> 16);
  479         dpt_outb(sc, HA_DMA_BASE + 3, (u_int32_t)addr >> 24);
  480 
  481         if (eatacmd == CP_IMMEDIATE) {
  482                 if (cp == NULL) {
  483                         /* XXX should really pass meaningful values */
  484                         dpt_outb(sc, HA_ICMD_CODE2, 0);
  485                         dpt_outb(sc, HA_ICMD_CODE1, 0);
  486                 }
  487                 dpt_outb(sc, HA_ICMD, icmd);
  488         }
  489 
  490         dpt_outb(sc, HA_COMMAND, eatacmd);
  491         return (0);
  492 }
  493 
  494 /*
  495  * Wait for the HBA to reach an arbitrary state.
  496  */
  497 int
  498 dpt_wait(sc, mask, state, ms)
  499         struct dpt_softc *sc;
  500         u_int8_t mask, state;
  501         int ms;
  502 {
  503      
  504         for (ms *= 10; ms; ms--) {
  505                 if ((dpt_inb(sc, HA_STATUS) & mask) == state)
  506                         return (0);
  507                 DELAY(100);
  508         }
  509         return (-1);
  510 }
  511 
  512 /*
  513  * Wait for the specified CCB to finish. This is used when we may not be
  514  * able to sleep and/or interrupts are disabled (eg autoconfiguration). 
  515  * The timeout value from the CCB is used. This should only be used for 
  516  * CCB_PRIVATE requests; otherwise the CCB will get recycled before we get 
  517  * a look at it.
  518  */
  519 int
  520 dpt_poll(sc, ccb)
  521         struct dpt_softc *sc;
  522         struct dpt_ccb *ccb;
  523 {
  524         int i;
  525 
  526 #ifdef DEBUG
  527         if ((ccb->ccb_flg & CCB_PRIVATE) == 0)
  528                 panic("dpt_poll: called for non-CCB_PRIVATE request");
  529 #endif
  530 
  531         if ((ccb->ccb_flg & CCB_INTR) != 0)
  532                 return (0);                
  533 
  534         for (i = ccb->ccb_timeout * 20; i; i--) {
  535                 if ((dpt_inb(sc, HA_AUX_STATUS) & HA_AUX_INTR) != 0)
  536                         dpt_intr(sc);
  537                 if ((ccb->ccb_flg & CCB_INTR) != 0)
  538                         return (0);
  539                 DELAY(50);
  540         }
  541         return (-1);
  542 }
  543 
  544 /*
  545  * Read the EATA configuration from the HBA and perform some sanity checks.
  546  */
  547 int
  548 dpt_readcfg(sc)
  549         struct dpt_softc *sc;
  550 {
  551         struct eata_cfg *ec;
  552         int i, j, stat;
  553         u_int16_t *p;
  554 
  555         ec = &sc->sc_ec;
  556 
  557         /* Older firmware may puke if we talk to it too soon after reset */
  558         dpt_outb(sc, HA_COMMAND, CP_RESET);
  559         DELAY(750000);
  560 
  561         for (i = 1000; i; i--) {
  562                 if ((dpt_inb(sc, HA_STATUS) & HA_ST_READY) != 0)
  563                         break;
  564                 DELAY(2000);
  565         }
  566         
  567         if (i == 0) {
  568                 printf("%s: HBA not ready after reset: %02x\n", 
  569                     sc->sc_dv.dv_xname, dpt_inb(sc, HA_STATUS));
  570                 return (-1);
  571         }
  572 
  573         while((((stat = dpt_inb(sc, HA_STATUS))
  574             != (HA_ST_READY|HA_ST_SEEK_COMPLETE))
  575             && (stat != (HA_ST_READY|HA_ST_SEEK_COMPLETE|HA_ST_ERROR))
  576             && (stat != (HA_ST_READY|HA_ST_SEEK_COMPLETE|HA_ST_ERROR|HA_ST_DRQ)))
  577             || (dpt_wait(sc, HA_ST_BUSY, 0, 2000))) {
  578                 /* RAID drives still spinning up? */
  579                 if((dpt_inb(sc, HA_ERROR) != 'D')
  580                     || (dpt_inb(sc, HA_ERROR + 1) != 'P')
  581                     || (dpt_inb(sc, HA_ERROR + 2) != 'T')) {
  582                         printf("%s: HBA not ready\n", sc->sc_dv.dv_xname);
  583                         return (-1);
  584                 }
  585         }
  586 
  587         /* 
  588          * Issue the read-config command and wait for the data to appear.
  589          * XXX we shouldn't be doing this with PIO, but it makes it a lot
  590          * easier as no DMA setup is required.
  591          */
  592         dpt_outb(sc, HA_COMMAND, CP_PIO_GETCFG);
  593         memset(ec, 0, sizeof(*ec));
  594         i = ((int)&((struct eata_cfg *)0)->ec_cfglen + 
  595             sizeof(ec->ec_cfglen)) >> 1;
  596         p = (u_int16_t *)ec;
  597         
  598         if (dpt_wait(sc, 0xFF, HA_ST_DATA_RDY, 2000)) {
  599                 printf("%s: cfg data didn't appear (status:%02x)\n", 
  600                     sc->sc_dv.dv_xname, dpt_inb(sc, HA_STATUS));
  601                 return (-1);
  602         }
  603 
  604         /* Begin reading */
  605         while (i--)
  606                 *p++ = dpt_inw(sc, HA_DATA);
  607 
  608         if ((i = ec->ec_cfglen) > (sizeof(struct eata_cfg)
  609             - (int)(&(((struct eata_cfg *)0L)->ec_cfglen))
  610             - sizeof(ec->ec_cfglen)))
  611                 i = sizeof(struct eata_cfg)
  612                   - (int)(&(((struct eata_cfg *)0L)->ec_cfglen))
  613                   - sizeof(ec->ec_cfglen);
  614 
  615         j = i + (int)(&(((struct eata_cfg *)0L)->ec_cfglen)) + 
  616             sizeof(ec->ec_cfglen);
  617         i >>= 1;
  618 
  619         while (i--)
  620                 *p++ = dpt_inw(sc, HA_DATA);
  621         
  622         /* Flush until we have read 512 bytes. */
  623         i = (512 - j + 1) >> 1;
  624         while (i--)
  625                 dpt_inw(sc, HA_DATA);
  626         
  627         /* Defaults for older Firmware */
  628         if (p <= (u_short *)&ec->ec_hba[DPT_MAX_CHANNELS - 1])
  629                 ec->ec_hba[DPT_MAX_CHANNELS - 1] = 7;
  630 
  631         if ((dpt_inb(sc, HA_STATUS) & HA_ST_ERROR) != 0) {
  632                 printf("%s: HBA error\n", sc->sc_dv.dv_xname);
  633                 return (-1);
  634         }
  635         
  636         if (!ec->ec_hbavalid) {
  637                 printf("%s: ec_hba field invalid\n", sc->sc_dv.dv_xname);
  638                 return (-1);
  639         }
  640         
  641         if (memcmp(ec->ec_eatasig, "EATA", 4) != 0) {
  642                 printf("%s: EATA signature mismatch\n", sc->sc_dv.dv_xname);
  643                 return (-1);
  644         }
  645         
  646         if (!ec->ec_dmasupported) {
  647                 printf("%s: DMA not supported\n", sc->sc_dv.dv_xname);
  648                 return (-1);
  649         }
  650 
  651         return (0);
  652 }
  653 
  654 /*
  655  * Adjust the size of each I/O before it passes to the SCSI layer.
  656  */
  657 void
  658 dpt_minphys(bp)
  659         struct buf *bp;
  660 {
  661 
  662         if (bp->b_bcount > DPT_MAX_XFER)
  663                 bp->b_bcount = DPT_MAX_XFER;
  664         minphys(bp);
  665 }
  666 
  667 /*
  668  * Put a CCB onto the freelist.
  669  */
  670 void
  671 dpt_free_ccb(sc, ccb)
  672         struct dpt_softc *sc;
  673         struct dpt_ccb *ccb;
  674 {
  675         int s;
  676 
  677         s = splbio();
  678         ccb->ccb_flg = 0;
  679         TAILQ_INSERT_HEAD(&sc->sc_free_ccb, ccb, ccb_chain);
  680 
  681         /* Wake anybody waiting for a free ccb */
  682         if (TAILQ_NEXT(ccb, ccb_chain) == NULL)
  683                 wakeup(&sc->sc_free_ccb);
  684         splx(s);
  685 }
  686 
  687 /*
  688  * Initialize the specified CCB.
  689  */
  690 int
  691 dpt_init_ccb(sc, ccb)
  692         struct dpt_softc *sc;
  693         struct dpt_ccb *ccb;
  694 {
  695         int error;
  696         
  697         /* Create the DMA map for this CCB's data */
  698         error = bus_dmamap_create(sc->sc_dmat, DPT_MAX_XFER, DPT_SG_SIZE, 
  699             DPT_MAX_XFER, 0, BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW,
  700             &ccb->ccb_dmamap_xfer);
  701         
  702         if (error) {
  703                 printf("%s: can't create ccb dmamap (%d)\n", 
  704                    sc->sc_dv.dv_xname, error);
  705                 return (error);
  706         }
  707 
  708         ccb->ccb_flg = 0;
  709         ccb->ccb_ccbpa = sc->sc_dmamap_ccb->dm_segs[0].ds_addr +
  710             CCB_OFF(sc, ccb);
  711         return (0);
  712 }
  713 
  714 /*
  715  * Create a set of CCBs and add them to the free list.
  716  */
  717 int
  718 dpt_create_ccbs(sc, ccbstore, count)
  719         struct dpt_softc *sc;
  720         struct dpt_ccb *ccbstore;
  721         int count;
  722 {
  723         struct dpt_ccb *ccb;
  724         int i, error;
  725 
  726         memset(ccbstore, 0, sizeof(struct dpt_ccb) * count);
  727         
  728         for (i = 0, ccb = ccbstore; i < count; i++, ccb++) {
  729                 if ((error = dpt_init_ccb(sc, ccb)) != 0) {
  730                         printf("%s: unable to init ccb, error = %d\n",
  731                             sc->sc_dv.dv_xname, error);
  732                         break;
  733                 }
  734                 ccb->ccb_id = i;
  735                 TAILQ_INSERT_TAIL(&sc->sc_free_ccb, ccb, ccb_chain);
  736         }
  737 
  738         return (i);
  739 }
  740 
  741 /*
  742  * Get a free ccb. If there are none, see if we can allocate a new one. If 
  743  * none are available right now and we are permitted to sleep, then wait 
  744  * until one becomes free, otherwise return an error.
  745  */
  746 struct dpt_ccb *
  747 dpt_alloc_ccb(sc, flg)
  748         struct dpt_softc *sc;
  749         int flg;
  750 {
  751         struct dpt_ccb *ccb;
  752         int s;
  753 
  754         s = splbio();
  755 
  756         for (;;) {
  757                 ccb = TAILQ_FIRST(&sc->sc_free_ccb);
  758                 if (ccb) {
  759                         TAILQ_REMOVE(&sc->sc_free_ccb, ccb, ccb_chain);
  760                         break;
  761                 }
  762 #ifdef __NetBSD__
  763                 if ((flg & XS_CTL_NOSLEEP) != 0) {
  764 #endif /* __NetBSD__ */
  765 #ifdef __OpenBSD__
  766                 if ((flg & SCSI_NOSLEEP) != 0) {
  767 #endif /* __OpenBSD__ */
  768                         splx(s);
  769                         return (NULL);
  770                 }
  771                 tsleep(&sc->sc_free_ccb, PRIBIO, "dptccb", 0);
  772         }
  773 
  774         ccb->ccb_flg |= CCB_ALLOC;
  775         splx(s);
  776         return (ccb);
  777 }
  778 
  779 /*
  780  * We have a CCB which has been processed by the HBA, now we look to see how 
  781  * the operation went. CCBs marked with CCB_PRIVATE are not automatically
  782  * passed here by dpt_intr().
  783  */
  784 void
  785 dpt_done_ccb(sc, ccb)
  786         struct dpt_softc *sc;
  787         struct dpt_ccb *ccb;
  788 {
  789 #ifdef __NetBSD__
  790         struct scsipi_sense_data *s1, *s2;
  791         struct scsipi_xfer *xs;
  792 #endif /* __NetBSD__ */
  793 #ifdef __OpenBSD__
  794         struct scsi_sense_data *s1, *s2;
  795         struct scsi_xfer *xs;
  796 #endif /* __OpenBSD__ */
  797         bus_dma_tag_t dmat;
  798         
  799         dmat = sc->sc_dmat;
  800         xs = ccb->ccb_xs;
  801 
  802         SC_DEBUG(xs->sc_link, SDEV_DB2, ("dpt_done_ccb\n"));
  803 
  804         /*
  805          * If we were a data transfer, unload the map that described the 
  806          * data buffer.
  807          */
  808         if (xs->datalen) {
  809                 bus_dmamap_sync(dmat, ccb->ccb_dmamap_xfer, 0,
  810                     ccb->ccb_dmamap_xfer->dm_mapsize,
  811                     (xs->flags & SCSI_DATA_IN) ? BUS_DMASYNC_POSTREAD :
  812                     BUS_DMASYNC_POSTWRITE);
  813                 bus_dmamap_unload(dmat, ccb->ccb_dmamap_xfer);
  814         }
  815 
  816         /*
  817          * Otherwise, put the results of the operation into the xfer and 
  818          * call whoever started it.
  819          */
  820 #ifdef DIAGNOSTIC
  821         if ((ccb->ccb_flg & CCB_ALLOC) == 0) {
  822                 panic("%s: done ccb not allocated!", sc->sc_dv.dv_xname);
  823                 return;
  824         }
  825 #endif
  826         
  827         if (xs->error == XS_NOERROR) {
  828                 if (ccb->ccb_hba_status != HA_NO_ERROR) {
  829                         switch (ccb->ccb_hba_status) {
  830                         case HA_ERROR_SEL_TO:
  831                                 xs->error = XS_SELTIMEOUT;
  832                                 break;
  833                         case HA_ERROR_RESET:
  834                                 xs->error = XS_RESET;
  835                                 break;
  836                         default:        /* Other scsi protocol messes */
  837                                 printf("%s: HBA status %x\n",
  838                                     sc->sc_dv.dv_xname, ccb->ccb_hba_status);
  839                                 xs->error = XS_DRIVER_STUFFUP;
  840                         }
  841                 } else if (ccb->ccb_scsi_status != SCSI_OK) {
  842                         switch (ccb->ccb_scsi_status) {
  843                         case SCSI_CHECK:
  844                                 s1 = &ccb->ccb_sense;
  845 #ifdef __NetBSD__
  846                                 s2 = &xs->sense.scsi_sense;
  847 #endif /* __NetBSD__ */
  848 #ifdef __OpenBSD__
  849                                 s2 = &xs->sense;
  850 #endif /* __OpenBSD__ */
  851                                 *s2 = *s1;
  852                                 xs->error = XS_SENSE;
  853                                 break;
  854                         case SCSI_BUSY:
  855                                 xs->error = XS_BUSY;
  856                                 break;
  857                         default:
  858                                 printf("%s: SCSI status %x\n",
  859                                     sc->sc_dv.dv_xname, ccb->ccb_scsi_status);
  860                                 xs->error = XS_DRIVER_STUFFUP;
  861                         }
  862                 } else
  863                         xs->resid = 0;
  864                         
  865                 xs->status = ccb->ccb_scsi_status;
  866         }
  867 
  868         /* Free up the CCB and mark the command as done */
  869         dpt_free_ccb(sc, ccb);
  870 #ifdef __NetBSD__
  871         xs->xs_status |= XS_STS_DONE;
  872         scsipi_done(xs);
  873 #endif /* __NetBSD__ */
  874 #ifdef __OpenBSD__
  875         xs->flags |= ITSDONE;
  876         scsi_done(xs);
  877 #endif /* __OpenBSD__ */
  878 
  879         /*
  880          * If there are entries in the software queue, try to run the first
  881          * one. We should be more or less guaranteed to succeed, since we
  882          * just freed an CCB. NOTE: dpt_scsi_cmd() relies on our calling it
  883          * with the first entry in the queue.
  884          */
  885 #ifdef __NetBSD__
  886         if ((xs = TAILQ_FIRST(&sc->sc_queue)) != NULL)
  887 #endif /* __NetBSD__ */
  888 #ifdef __OpenBSD__
  889         if ((xs = LIST_FIRST(&sc->sc_queue)) != NULL)
  890 #endif /* __OpenBSD__ */
  891                 dpt_scsi_cmd(xs);
  892 }
  893 
  894 #ifdef __OpenBSD__
  895 /*
  896  * Insert a scsi_xfer into the software queue.  We overload xs->free_list
  897  * to avoid having to allocate additional resources (since we're used
  898  * only during resource shortages anyhow.
  899  */
  900 static void
  901 dpt_enqueue(sc, xs, infront)
  902         struct dpt_softc *sc;
  903         struct scsi_xfer *xs;
  904         int             infront;
  905 {
  906 
  907         if (infront || LIST_EMPTY(&sc->sc_queue)) {
  908                 if (LIST_EMPTY(&sc->sc_queue))
  909                         sc->sc_queuelast = xs;
  910                 LIST_INSERT_HEAD(&sc->sc_queue, xs, free_list);
  911                 return;
  912         }
  913         LIST_INSERT_AFTER(sc->sc_queuelast, xs, free_list);
  914         sc->sc_queuelast = xs;
  915 }
  916 
  917 /*
  918  * Pull a scsi_xfer off the front of the software queue.
  919  */
  920 static struct scsi_xfer *
  921 dpt_dequeue(sc)
  922         struct dpt_softc *sc;
  923 {
  924         struct scsi_xfer *xs;
  925 
  926         xs = LIST_FIRST(&sc->sc_queue);
  927         LIST_REMOVE(xs, free_list);
  928 
  929         if (LIST_EMPTY(&sc->sc_queue))
  930                 sc->sc_queuelast = NULL;
  931 
  932         return (xs);
  933 }
  934 #endif /* __OpenBSD__ */
  935 
  936 /*
  937  * Start a SCSI command.
  938  */
  939 int
  940 dpt_scsi_cmd(xs)
  941 #ifdef __NetBSD__
  942         struct scsipi_xfer *xs;
  943 #endif /* __NetBSD__ */
  944 #ifdef __OpenBSD__
  945         struct scsi_xfer *xs;
  946 #endif /* __OpenBSD__ */
  947 {
  948         int error, i, flags, s, fromqueue, dontqueue;
  949 #ifdef __NetBSD__
  950         struct scsipi_link *sc_link;
  951 #endif /* __NetBSD__ */
  952 #ifdef __OpenBSD__
  953         struct scsi_link *sc_link;
  954 #endif /* __OpenBSD__ */
  955         struct dpt_softc *sc;
  956         struct dpt_ccb *ccb;
  957         struct eata_sg *sg;
  958         struct eata_cp *cp;
  959         bus_dma_tag_t dmat;
  960         bus_dmamap_t xfer;
  961 
  962         sc_link = xs->sc_link;
  963 #ifdef __NetBSD__
  964         flags = xs->xs_control;
  965 #endif /* __NetBSD__ */
  966 #ifdef __OpenBSD__
  967         flags = xs->flags;
  968 #endif /* __OpenBSD__ */
  969         sc = sc_link->adapter_softc;
  970         dmat = sc->sc_dmat;
  971         fromqueue = 0;
  972         dontqueue = 0;
  973 
  974         SC_DEBUG(sc_link, SDEV_DB2, ("dpt_scsi_cmd\n"));
  975 
  976         /* Protect the queue */
  977         s = splbio();
  978 
  979         /*
  980          * If we're running the queue from dpt_done_ccb(), we've been called 
  981          * with the first queue entry as our argument.
  982          */
  983 #ifdef __NetBSD__
  984         if (xs == TAILQ_FIRST(&sc->sc_queue)) {
  985                 TAILQ_REMOVE(&sc->sc_queue, xs, adapter_q);
  986 #endif /* __NetBSD__ */
  987 #ifdef __OpenBSD__
  988         if (xs == LIST_FIRST(&sc->sc_queue)) {
  989                 xs = dpt_dequeue(sc);
  990 #endif /* __OpenBSD__ */
  991                 fromqueue = 1;
  992         } else {
  993                 /* Cmds must be no more than 12 bytes for us */
  994                 if (xs->cmdlen > 12) {
  995                         splx(s);
  996                         xs->error = XS_DRIVER_STUFFUP;
  997                         return (COMPLETE);
  998                 }
  999 
 1000                 /* XXX we can't reset devices just yet */
 1001 #ifdef __NetBSD__
 1002                 if ((flags & XS_CTL_RESET) != 0) {
 1003 #endif /* __NetBSD__ */
 1004 #ifdef __OpenBSD__
 1005                 if ((xs->flags & SCSI_RESET) != 0) {
 1006 #endif /* __OpenBSD__ */
 1007                         splx(s);
 1008                         xs->error = XS_DRIVER_STUFFUP;
 1009                         return (COMPLETE);
 1010                 }
 1011 
 1012                 /* Polled requests can't be queued for later */
 1013 #ifdef __NetBSD__
 1014                 dontqueue = flags & XS_CTL_POLL;
 1015 #endif /* __NetBSD__ */
 1016 #ifdef __OpenBSD__
 1017                 dontqueue = xs->flags & SCSI_POLL;
 1018 #endif /* __OpenBSD__ */
 1019 
 1020                 /* If there are jobs in the queue, run them first */
 1021 #ifdef __NetBSD__
 1022                 if (TAILQ_FIRST(&sc->sc_queue) != NULL) {
 1023 #endif /* __NetBSD__ */
 1024 #ifdef __OpenBSD__
 1025                 if (!LIST_EMPTY(&sc->sc_queue)) {
 1026 #endif /* __OpenBSD__ */
 1027                         /*
 1028                          * If we can't queue we abort, since we must 
 1029                          * preserve the queue order.
 1030                          */
 1031                         if (dontqueue) {
 1032                                 splx(s);
 1033                                 return (TRY_AGAIN_LATER);
 1034                         }
 1035 
 1036                         /* Swap with the first queue entry. */
 1037 #ifdef __NetBSD__
 1038                         TAILQ_INSERT_TAIL(&sc->sc_queue, xs, adapter_q);
 1039                         xs = TAILQ_FIRST(&sc->sc_queue);
 1040                         TAILQ_REMOVE(&sc->sc_queue, xs, adapter_q);
 1041 #endif /* __NetBSD__ */
 1042 #ifdef __OpenBSD__
 1043                         dpt_enqueue(sc, xs, 0);
 1044                         xs = dpt_dequeue(sc);
 1045 #endif /* __OpenBSD__ */
 1046                         fromqueue = 1;
 1047                 }
 1048         }
 1049 
 1050         /* Get a CCB */
 1051 #ifdef __NetBSD__
 1052         if ((ccb = dpt_alloc_ccb(sc, flags)) == NULL) {
 1053 #endif /* __NetBSD__ */
 1054 #ifdef __OpenBSD__
 1055         if ((ccb = dpt_alloc_ccb(sc, xs->flags)) == NULL) {
 1056 #endif /* __OpenBSD__ */
 1057                 /* If we can't queue, we lose */
 1058                 if (dontqueue) {
 1059                         splx(s);
 1060                         return (TRY_AGAIN_LATER);
 1061                 }
 1062                 
 1063                 /* 
 1064                  * Stuff request into the queue, in front if we came off 
 1065                  * it in the first place.
 1066                  */
 1067 #ifdef __NetBSD__
 1068                 if (fromqueue)
 1069                         TAILQ_INSERT_HEAD(&sc->sc_queue, xs, adapter_q);
 1070                 else
 1071                         TAILQ_INSERT_TAIL(&sc->sc_queue, xs, adapter_q);
 1072 #endif /* __NetBSD__ */
 1073 #ifdef __OpenBSD__
 1074                 dpt_enqueue(sc, xs, fromqueue);
 1075 #endif /* __OpenBSD__ */
 1076                 splx(s);
 1077                 return (SUCCESSFULLY_QUEUED);
 1078         }
 1079 
 1080         splx(s);
 1081 
 1082         ccb->ccb_xs = xs;
 1083         ccb->ccb_timeout = xs->timeout;
 1084 
 1085         cp = &ccb->ccb_eata_cp;
 1086 #ifdef __NetBSD__
 1087         memcpy(&cp->cp_scsi_cmd, xs->cmd, xs->cmdlen);
 1088 #endif /* __NetBSD__ */
 1089 #ifdef __OpenBSD__
 1090         bcopy(xs->cmd, &cp->cp_scsi_cmd, xs->cmdlen);
 1091 #endif /* __OpenBSD__ */
 1092         cp->cp_ccbid = ccb->ccb_id;
 1093 #ifdef __NetBSD__
 1094         cp->cp_id = sc_link->scsipi_scsi.target;
 1095         cp->cp_lun = sc_link->scsipi_scsi.lun;
 1096         cp->cp_channel = sc_link->scsipi_scsi.channel;
 1097 #endif /* __NetBSD__ */
 1098 #ifdef __OpenBSD__
 1099         cp->cp_id = sc_link->target;
 1100         cp->cp_lun = sc_link->lun;
 1101         cp->cp_channel = sc_link->scsibus;
 1102 #endif /* __OpenBSD__ */
 1103         cp->cp_senselen = sizeof(ccb->ccb_sense);
 1104         cp->cp_stataddr = htobe32(sc->sc_sppa);
 1105         cp->cp_dispri = 1;
 1106         cp->cp_identify = 1;
 1107         cp->cp_autosense = 1;
 1108 #ifdef __NetBSD__
 1109         cp->cp_datain = ((flags & XS_CTL_DATA_IN) != 0);
 1110         cp->cp_dataout = ((flags & XS_CTL_DATA_OUT) != 0);
 1111         cp->cp_interpret = (sc->sc_hbaid[sc_link->scsipi_scsi.channel] ==
 1112             sc_link->scsipi_scsi.target);
 1113 #endif /* __NetBSD__ */
 1114 #ifdef __OpenBSD__
 1115         cp->cp_datain = ((xs->flags & SCSI_DATA_IN) != 0);
 1116         cp->cp_dataout = ((xs->flags & SCSI_DATA_OUT) != 0);
 1117         cp->cp_interpret = (sc->sc_hbaid[sc_link->scsibus] == sc_link->target);
 1118 #endif /* __OpenBSD__ */
 1119 
 1120         /* Synchronous xfers musn't write-back through the cache */
 1121         if (xs->bp != NULL && (xs->bp->b_flags & (B_ASYNC | B_READ)) == 0)
 1122                 cp->cp_nocache = 1;
 1123         else
 1124                 cp->cp_nocache = 0;
 1125 
 1126         cp->cp_senseaddr = htobe32(sc->sc_dmamap_ccb->dm_segs[0].ds_addr +
 1127             CCB_OFF(sc, ccb) + offsetof(struct dpt_ccb, ccb_sense));
 1128             
 1129         if (xs->datalen) {
 1130                 xfer = ccb->ccb_dmamap_xfer;
 1131 #ifdef  TFS
 1132 #ifdef __NetBSD__
 1133                 if ((flags & XS_CTL_DATA_UIO) != 0) {
 1134                         error = bus_dmamap_load_uio(dmat, xfer, 
 1135                             (struct uio *)xs->data, (flags & XS_CTL_NOSLEEP) ? 
 1136                             BUS_DMA_NOWAIT : BUS_DMA_WAITOK);
 1137 #endif /* __NetBSD__ */
 1138 #ifdef __OpenBSD__
 1139                 if ((xs->flags & SCSI_DATA_UIO) != 0) {
 1140                         error = bus_dmamap_load_uio(dmat, xfer, 
 1141                             (xs->flags & SCSI_NOSLEEP) ?
 1142                             BUS_DMA_NOWAIT : BUS_DMA_WAITOK);
 1143 #endif /* __OpenBSD__ */
 1144                 } else
 1145 #endif /*TFS */
 1146                 {
 1147 #ifdef __NetBSD__
 1148                         error = bus_dmamap_load(dmat, xfer, xs->data, 
 1149                             xs->datalen, NULL, (flags & XS_CTL_NOSLEEP) ? 
 1150                             BUS_DMA_NOWAIT : BUS_DMA_WAITOK);
 1151 #endif /* __NetBSD__ */
 1152 #ifdef __OpenBSD__
 1153                         error = bus_dmamap_load(dmat, xfer, xs->data, 
 1154                             xs->datalen, NULL, (xs->flags & SCSI_NOSLEEP) ? 
 1155                             BUS_DMA_NOWAIT : BUS_DMA_WAITOK);
 1156 #endif /* __OpenBSD__ */
 1157                 }
 1158 
 1159                 if (error) {
 1160                         printf("%s: dpt_scsi_cmd: ", sc->sc_dv.dv_xname); 
 1161                         if (error == EFBIG)
 1162                                 printf("more than %d dma segs\n", DPT_SG_SIZE);
 1163                         else
 1164                                 printf("error %d loading dma map\n", error);
 1165                 
 1166                         xs->error = XS_DRIVER_STUFFUP;
 1167                         dpt_free_ccb(sc, ccb);
 1168                         return (COMPLETE);
 1169                 }
 1170 
 1171                 bus_dmamap_sync(dmat, xfer, 0, xfer->dm_mapsize,
 1172                     (flags & SCSI_DATA_IN) ? BUS_DMASYNC_PREREAD :
 1173                     BUS_DMASYNC_PREWRITE);
 1174 
 1175                 /* Don't bother using scatter/gather for just 1 segment */
 1176                 if (xfer->dm_nsegs == 1) {
 1177                         cp->cp_dataaddr = htobe32(xfer->dm_segs[0].ds_addr);
 1178                         cp->cp_datalen = htobe32(xfer->dm_segs[0].ds_len);
 1179                         cp->cp_scatter = 0;
 1180                 } else {
 1181                         /*
 1182                          * Load the hardware scatter/gather map with the
 1183                          * contents of the DMA map.
 1184                          */
 1185                         sg = ccb->ccb_sg;
 1186                         for (i = 0; i < xfer->dm_nsegs; i++, sg++) {
 1187                                 sg->sg_addr =
 1188                                   htobe32(xfer->dm_segs[i].ds_addr);
 1189                                 sg->sg_len =
 1190                                   htobe32(xfer->dm_segs[i].ds_len);
 1191                         }
 1192                         cp->cp_dataaddr = htobe32(CCB_OFF(sc, ccb) + 
 1193                             sc->sc_dmamap_ccb->dm_segs[0].ds_addr +
 1194                             offsetof(struct dpt_ccb, ccb_sg));
 1195                         cp->cp_datalen = htobe32(i * sizeof(struct eata_sg));
 1196                         cp->cp_scatter = 1;
 1197                 }
 1198         } else {
 1199                 cp->cp_dataaddr = 0;
 1200                 cp->cp_datalen = 0;
 1201                 cp->cp_scatter = 0;
 1202         }
 1203 
 1204         /* Sync up CCB and status packet */
 1205         bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap_ccb, CCB_OFF(sc, ccb), 
 1206             sizeof(struct dpt_ccb), BUS_DMASYNC_PREWRITE);
 1207         bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap_ccb, sc->sc_spoff, 
 1208             sizeof(struct eata_sp), BUS_DMASYNC_PREREAD);
 1209 
 1210         /* 
 1211          * Start the command. If we are polling on completion, mark it
 1212          * private so that dpt_intr/dpt_done_ccb don't recycle the CCB 
 1213          * without us noticing.
 1214          */
 1215         if (dontqueue != 0)
 1216                 ccb->ccb_flg |= CCB_PRIVATE; 
 1217         
 1218         if (dpt_cmd(sc, &ccb->ccb_eata_cp, ccb->ccb_ccbpa, CP_DMA_CMD, 0)) {
 1219                 printf("%s: dpt_cmd failed\n", sc->sc_dv.dv_xname);
 1220                 dpt_free_ccb(sc, ccb);
 1221                 return (TRY_AGAIN_LATER);
 1222         }
 1223 
 1224         if (dontqueue == 0)
 1225                 return (SUCCESSFULLY_QUEUED);
 1226 
 1227         /* Don't wait longer than this single command wants to wait */
 1228         if (dpt_poll(sc, ccb)) {
 1229                 dpt_timeout(ccb);
 1230                 /* Wait for abort to complete */
 1231                 if (dpt_poll(sc, ccb))
 1232                         dpt_timeout(ccb);
 1233         } 
 1234         
 1235         dpt_done_ccb(sc, ccb);
 1236         return (COMPLETE);
 1237 }
 1238 
 1239 /*
 1240  * Specified CCB has timed out, abort it.
 1241  */
 1242 void
 1243 dpt_timeout(arg)
 1244         void *arg;
 1245 {
 1246 #ifdef __NetBSD__
 1247         struct scsipi_link *sc_link;
 1248         struct scsipi_xfer *xs;
 1249 #endif /* __NetBSD__ */
 1250 #ifdef __OpenBSD__
 1251         struct scsi_link *sc_link;
 1252         struct scsi_xfer *xs;
 1253 #endif /* __OpenBSD__ */
 1254         struct dpt_softc *sc;
 1255         struct dpt_ccb *ccb;
 1256         int s;
 1257         
 1258         ccb = arg;
 1259         xs = ccb->ccb_xs;
 1260         sc_link = xs->sc_link;
 1261         sc  = sc_link->adapter_softc;
 1262 
 1263 #ifdef __NetBSD__
 1264         scsi_print_addr(sc_link);
 1265 #endif /* __NetBSD__ */
 1266 #ifdef __OpenBSD__
 1267         sc_print_addr(sc_link);
 1268 #endif /* __OpenBSD__ */
 1269         printf("timed out (status:%02x aux status:%02x)", 
 1270             dpt_inb(sc, HA_STATUS), dpt_inb(sc, HA_AUX_STATUS));
 1271 
 1272         s = splbio();
 1273 
 1274         if ((ccb->ccb_flg & CCB_ABORT) != 0) {
 1275                 /* Abort timed out, reset the HBA */
 1276                 printf(" AGAIN, resetting HBA\n");
 1277                 dpt_outb(sc, HA_COMMAND, CP_RESET);
 1278                 DELAY(750000);
 1279         } else {
 1280                 /* Abort the operation that has timed out */
 1281                 printf("\n");
 1282                 ccb->ccb_xs->error = XS_TIMEOUT;
 1283                 ccb->ccb_timeout = DPT_ABORT_TIMEOUT;
 1284                 ccb->ccb_flg |= CCB_ABORT;
 1285                 /* Start the abort */
 1286                 if (dpt_cmd(sc, &ccb->ccb_eata_cp, ccb->ccb_ccbpa, 
 1287                     CP_IMMEDIATE, CPI_SPEC_ABORT))
 1288                     printf("%s: dpt_cmd failed\n", sc->sc_dv.dv_xname);
 1289         }
 1290 
 1291         splx(s);
 1292 }
 1293 
 1294 #ifdef DEBUG
 1295 /*
 1296  * Dump the contents of an EATA status packet.
 1297  */
 1298 void
 1299 dpt_dump_sp(sp)
 1300         struct eata_sp *sp;
 1301 {
 1302         int i;
 1303         
 1304         printf("\thba_status\t%02x\n", sp->sp_hba_status);
 1305         printf("\tscsi_status\t%02x\n", sp->sp_scsi_status);    
 1306         printf("\tinv_residue\t%d\n", sp->sp_inv_residue);      
 1307         printf("\tccbid\t\t%d\n", sp->sp_ccbid);
 1308         printf("\tid_message\t%d\n", sp->sp_id_message);
 1309         printf("\tque_message\t%d\n", sp->sp_que_message);      
 1310         printf("\ttag_message\t%d\n", sp->sp_tag_message);
 1311         printf("\tmessages\t");
 1312         
 1313         for (i = 0; i < 9; i++)
 1314                 printf("%d ", sp->sp_messages[i]);
 1315                 
 1316         printf("\n");
 1317 }
 1318 #endif  /* DEBUG */
 1319 
 1320 /*
 1321  * Get inquiry data from the adapter.
 1322  */
 1323 void
 1324 dpt_hba_inquire(sc, ei)
 1325         struct dpt_softc *sc;
 1326         struct eata_inquiry_data **ei;
 1327 {
 1328         struct dpt_ccb *ccb;
 1329         struct eata_cp *cp;
 1330         bus_dma_tag_t dmat;
 1331         
 1332         *ei = (struct eata_inquiry_data *)sc->sc_scr;
 1333         dmat = sc->sc_dmat;
 1334 
 1335         /* Get a CCB and mark as private */
 1336         if ((ccb = dpt_alloc_ccb(sc, 0)) == NULL)
 1337                 panic("%s: no CCB for inquiry", sc->sc_dv.dv_xname);
 1338         
 1339         ccb->ccb_flg |= CCB_PRIVATE;
 1340         ccb->ccb_timeout = 200;
 1341 
 1342         /* Put all the arguments into the CCB */
 1343         cp = &ccb->ccb_eata_cp;
 1344         cp->cp_ccbid = ccb->ccb_id;
 1345         cp->cp_id = sc->sc_hbaid[0];
 1346         cp->cp_lun = 0;
 1347         cp->cp_channel = 0;
 1348         cp->cp_senselen = sizeof(ccb->ccb_sense);
 1349         cp->cp_stataddr = htobe32(sc->sc_sppa);
 1350         cp->cp_dispri = 1;
 1351         cp->cp_identify = 1;
 1352         cp->cp_autosense = 0;
 1353         cp->cp_interpret = 1;
 1354         cp->cp_nocache = 0;
 1355         cp->cp_datain = 1;
 1356         cp->cp_dataout = 0;
 1357         cp->cp_senseaddr = 0;
 1358         cp->cp_dataaddr = htobe32(sc->sc_scrpa);
 1359         cp->cp_datalen = htobe32(sizeof(struct eata_inquiry_data));
 1360         cp->cp_scatter = 0;
 1361         
 1362         /* Put together the SCSI inquiry command */
 1363         memset(&cp->cp_scsi_cmd, 0, 12);        /* XXX */
 1364         cp->cp_scsi_cmd = INQUIRY;
 1365         cp->cp_len = sizeof(struct eata_inquiry_data);
 1366 
 1367         /* Sync up CCB, status packet and scratch area */
 1368         bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap_ccb, CCB_OFF(sc, ccb), 
 1369             sizeof(struct dpt_ccb), BUS_DMASYNC_PREWRITE);
 1370         bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap_ccb, sc->sc_spoff, 
 1371             sizeof(struct eata_sp), BUS_DMASYNC_PREREAD);
 1372         bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap_ccb, sc->sc_scroff, 
 1373             sizeof(struct eata_inquiry_data), BUS_DMASYNC_PREREAD);
 1374 
 1375         /* Start the command and poll on completion */
 1376         if (dpt_cmd(sc, &ccb->ccb_eata_cp, ccb->ccb_ccbpa, CP_DMA_CMD, 0))
 1377                 panic("%s: dpt_cmd failed", sc->sc_dv.dv_xname);
 1378 
 1379         if (dpt_poll(sc, ccb))
 1380                 panic("%s: inquiry timed out", sc->sc_dv.dv_xname);
 1381 
 1382         if (ccb->ccb_hba_status != HA_NO_ERROR ||
 1383             ccb->ccb_scsi_status != SCSI_OK)
 1384                 panic("%s: inquiry failed (hba:%02x scsi:%02x", 
 1385                     sc->sc_dv.dv_xname, ccb->ccb_hba_status,
 1386                     ccb->ccb_scsi_status);
 1387         
 1388         /* Sync up the DMA map and free CCB, returning */
 1389         bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap_ccb, sc->sc_scroff, 
 1390             sizeof(struct eata_inquiry_data), BUS_DMASYNC_POSTREAD);
 1391         dpt_free_ccb(sc, ccb);
 1392 }

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