root/dev/ata/ata_wdc.c

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

DEFINITIONS

This source file includes following definitions.
  1. wdc_ata_bio
  2. wdc_ata_bio_start
  3. _wdc_ata_bio_start
  4. wdc_ata_bio_intr
  5. wdc_ata_bio_kill_xfer
  6. wdc_ata_bio_done
  7. wdc_ata_ctrl_intr
  8. wdc_ata_err
  9. wdc_ata_addref
  10. wdc_ata_delref

    1 /*      $OpenBSD: ata_wdc.c,v 1.30 2007/02/14 00:53:47 jsg Exp $        */
    2 /*      $NetBSD: ata_wdc.c,v 1.21 1999/08/09 09:43:11 bouyer Exp $      */
    3 
    4 /*
    5  * Copyright (c) 1998, 2001 Manuel Bouyer.
    6  *
    7  * Redistribution and use in source and binary forms, with or without
    8  * modification, are permitted provided that the following conditions
    9  * are met:
   10  * 1. Redistributions of source code must retain the above copyright
   11  *    notice, this list of conditions and the following disclaimer.
   12  * 2. Redistributions in binary form must reproduce the above copyright
   13  *    notice, this list of conditions and the following disclaimer in the
   14  *    documentation and/or other materials provided with the distribution.
   15  * 3. All advertising materials mentioning features or use of this software
   16  *    must display the following acknowledgement:
   17  *      This product includes software developed by Manuel Bouyer.
   18  * 4. Neither the name of the University nor the names of its contributors
   19  *    may be used to endorse or promote products derived from this software
   20  *    without specific prior written permission.
   21  *
   22  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   23  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   24  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   25  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
   26  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   27  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   28  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   29  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   30  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
   31  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   32  *
   33  */
   34 
   35 /*-
   36  * Copyright (c) 1998 The NetBSD Foundation, Inc.
   37  * All rights reserved.
   38  *
   39  * This code is derived from software contributed to The NetBSD Foundation
   40  * by Charles M. Hannum, by Onno van der Linden and by Manuel Bouyer.
   41  *
   42  * Redistribution and use in source and binary forms, with or without
   43  * modification, are permitted provided that the following conditions
   44  * are met:
   45  * 1. Redistributions of source code must retain the above copyright
   46  *    notice, this list of conditions and the following disclaimer.
   47  * 2. Redistributions in binary form must reproduce the above copyright
   48  *    notice, this list of conditions and the following disclaimer in the
   49  *    documentation and/or other materials provided with the distribution.
   50  * 3. All advertising materials mentioning features or use of this software
   51  *    must display the following acknowledgement:
   52  *        This product includes software developed by the NetBSD
   53  *        Foundation, Inc. and its contributors.
   54  * 4. Neither the name of The NetBSD Foundation nor the names of its
   55  *    contributors may be used to endorse or promote products derived
   56  *    from this software without specific prior written permission.
   57  *
   58  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
   59  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
   60  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   61  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
   62  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   63  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   64  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   65  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   66  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   67  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   68  * POSSIBILITY OF SUCH DAMAGE.
   69  */
   70 
   71 #include <sys/param.h>
   72 #include <sys/systm.h>
   73 #include <sys/kernel.h>
   74 #include <sys/file.h>
   75 #include <sys/stat.h>
   76 #include <sys/buf.h>
   77 #include <sys/malloc.h>
   78 #include <sys/device.h>
   79 #include <sys/disklabel.h>
   80 #include <sys/syslog.h>
   81 #include <sys/proc.h>
   82 
   83 #include <machine/intr.h>
   84 #include <machine/bus.h>
   85 
   86 #include <dev/ata/atareg.h>
   87 #include <dev/ata/atavar.h>
   88 #include <dev/ic/wdcreg.h>
   89 #include <dev/ic/wdcvar.h>
   90 #include <dev/ata/wdvar.h>
   91 
   92 #define DEBUG_INTR   0x01
   93 #define DEBUG_XFERS  0x02
   94 #define DEBUG_STATUS 0x04
   95 #define DEBUG_FUNCS  0x08
   96 #define DEBUG_PROBE  0x10
   97 
   98 #ifdef WDCDEBUG
   99 #ifndef WDCDEBUG_WD_MASK
  100 #define WDCDEBUG_WD_MASK 0x00
  101 #endif
  102 int wdcdebug_wd_mask = WDCDEBUG_WD_MASK;
  103 #define WDCDEBUG_PRINT(args, level) do {        \
  104         if ((wdcdebug_wd_mask & (level)) != 0)  \
  105                 printf args;                    \
  106 } while (0)
  107 #else
  108 #define WDCDEBUG_PRINT(args, level)
  109 #endif
  110 
  111 #define ATA_DELAY 10000 /* 10s for a drive I/O */
  112 
  113 struct cfdriver wdc_cd = {
  114         NULL, "wdc", DV_DULL
  115 };
  116 
  117 void  wdc_ata_bio_start(struct channel_softc *, struct wdc_xfer *);
  118 void  _wdc_ata_bio_start(struct channel_softc *, struct wdc_xfer *);
  119 int   wdc_ata_bio_intr(struct channel_softc *, struct wdc_xfer *, int);
  120 void  wdc_ata_bio_kill_xfer(struct channel_softc *, struct wdc_xfer *);
  121 void  wdc_ata_bio_done(struct channel_softc *, struct wdc_xfer *);
  122 int   wdc_ata_ctrl_intr(struct channel_softc *, struct wdc_xfer *, int);
  123 int   wdc_ata_err(struct ata_drive_datas *, struct ata_bio *);
  124 #define WDC_ATA_NOERR 0x00 /* Drive doesn't report an error */
  125 #define WDC_ATA_RECOV 0x01 /* There was a recovered error */
  126 #define WDC_ATA_ERR   0x02 /* Drive reports an error */
  127 
  128 /*
  129  * Handle block I/O operation. Return WDC_COMPLETE, WDC_QUEUED, or
  130  * WDC_TRY_AGAIN. Must be called at splbio().
  131  */
  132 int
  133 wdc_ata_bio(struct ata_drive_datas *drvp, struct ata_bio *ata_bio)
  134 {
  135         struct wdc_xfer *xfer;
  136         struct channel_softc *chp = drvp->chnl_softc;
  137 
  138         xfer = wdc_get_xfer(WDC_NOSLEEP);
  139         if (xfer == NULL)
  140                 return WDC_TRY_AGAIN;
  141         if (ata_bio->flags & ATA_POLL)
  142                 xfer->c_flags |= C_POLL;
  143         if (!(ata_bio->flags & ATA_POLL) &&
  144             (drvp->drive_flags & (DRIVE_DMA | DRIVE_UDMA)) &&
  145             (ata_bio->flags & ATA_SINGLE) == 0 &&
  146             (ata_bio->bcount > 512 ||
  147             (chp->wdc->quirks & WDC_QUIRK_NOSHORTDMA) == 0))
  148                 xfer->c_flags |= C_DMA;
  149         xfer->drive = drvp->drive;
  150         xfer->cmd = ata_bio;
  151         xfer->databuf = ata_bio->databuf;
  152         xfer->c_bcount = ata_bio->bcount;
  153         xfer->c_start = wdc_ata_bio_start;
  154         xfer->c_intr = wdc_ata_bio_intr;
  155         xfer->c_kill_xfer = wdc_ata_bio_kill_xfer;
  156         wdc_exec_xfer(chp, xfer);
  157         return (ata_bio->flags & ATA_ITSDONE) ? WDC_COMPLETE : WDC_QUEUED;
  158 }
  159 
  160 void
  161 wdc_ata_bio_start(struct channel_softc *chp, struct wdc_xfer *xfer)
  162 {
  163         struct ata_bio *ata_bio = xfer->cmd;
  164         WDCDEBUG_PRINT(("wdc_ata_bio_start %s:%d:%d\n",
  165             chp->wdc->sc_dev.dv_xname, chp->channel, xfer->drive),
  166             DEBUG_XFERS);
  167 
  168         /* start timeout machinery */
  169         if ((ata_bio->flags & ATA_POLL) == 0)
  170                 timeout_add(&chp->ch_timo, ATA_DELAY / 1000 * hz);
  171         _wdc_ata_bio_start(chp, xfer);
  172 }
  173 
  174 void
  175 _wdc_ata_bio_start(struct channel_softc *chp, struct wdc_xfer *xfer)
  176 {
  177         struct ata_bio *ata_bio = xfer->cmd;
  178         struct ata_drive_datas *drvp = &chp->ch_drive[xfer->drive];
  179         u_int16_t cyl;
  180         u_int8_t head, sect, cmd = 0;
  181         int nblks;
  182         int ata_delay;
  183         int dma_flags = 0;
  184 
  185         WDCDEBUG_PRINT(("_wdc_ata_bio_start %s:%d:%d\n",
  186             chp->wdc->sc_dev.dv_xname, chp->channel, xfer->drive),
  187             DEBUG_INTR | DEBUG_XFERS);
  188         /* Do control operations specially. */
  189         if (drvp->state < READY) {
  190                 /*
  191                  * Actually, we want to be careful not to mess with the control
  192                  * state if the device is currently busy, but we can assume
  193                  * that we never get to this point if that's the case.
  194                  */
  195                 /* at this point, we should only be in RECAL state */
  196                 if (drvp->state != RECAL) {
  197                         printf("%s:%d:%d: bad state %d in _wdc_ata_bio_start\n",
  198                             chp->wdc->sc_dev.dv_xname, chp->channel,
  199                             xfer->drive, drvp->state);
  200                         panic("_wdc_ata_bio_start: bad state");
  201                 }
  202                 xfer->c_intr = wdc_ata_ctrl_intr;
  203                 wdc_set_drive(chp, xfer->drive);
  204                 if (wdcwait(chp, WDCS_DRDY, WDCS_DRDY, ATA_DELAY) != 0)
  205                         goto timeout;
  206                 wdccommandshort(chp, xfer->drive, WDCC_RECAL);
  207                 drvp->state = RECAL_WAIT;
  208                 if ((ata_bio->flags & ATA_POLL) == 0) {
  209                         chp->ch_flags |= WDCF_IRQ_WAIT;
  210                 } else {
  211                         /* Wait for at last 400ns for status bit to be valid */
  212                         DELAY(1);
  213                         wdc_ata_ctrl_intr(chp, xfer, 0);
  214                 }
  215                 return;
  216         }
  217 
  218         if (xfer->c_flags & C_DMA) {
  219                 if (drvp->n_xfers <= NXFER)
  220                         drvp->n_xfers++;
  221                 dma_flags = (ata_bio->flags & ATA_READ) ?  WDC_DMA_READ : 0;
  222                 if (ata_bio->flags & ATA_LBA48)
  223                         dma_flags |= WDC_DMA_LBA48;
  224         }
  225         if (ata_bio->flags & ATA_SINGLE)
  226                 ata_delay = ATA_DELAY;
  227         else
  228                 ata_delay = ATA_DELAY;
  229 again:
  230         /*
  231          *
  232          * When starting a multi-sector transfer, or doing single-sector
  233          * transfers...
  234          */
  235         if (xfer->c_skip == 0 || (ata_bio->flags & ATA_SINGLE) != 0) {
  236                 if (ata_bio->flags & ATA_SINGLE)
  237                         nblks = 1;
  238                 else
  239                         nblks = xfer->c_bcount / ata_bio->lp->d_secsize;
  240                 if (ata_bio->flags & ATA_LBA) {
  241                         sect = (ata_bio->blkno >> 0) & 0xff;
  242                         cyl = (ata_bio->blkno >> 8) & 0xffff;
  243                         head = (ata_bio->blkno >> 24) & 0x0f;
  244                         head |= WDSD_LBA;
  245                 } else {
  246                         int blkno = ata_bio->blkno;
  247                         sect = blkno % ata_bio->lp->d_nsectors;
  248                         sect++;    /* Sectors begin with 1, not 0. */
  249                         blkno /= ata_bio->lp->d_nsectors;
  250                         head = blkno % ata_bio->lp->d_ntracks;
  251                         blkno /= ata_bio->lp->d_ntracks;
  252                         cyl = blkno;
  253                         head |= WDSD_CHS;
  254                 }
  255                 if (xfer->c_flags & C_DMA) {
  256                         ata_bio->nblks = nblks;
  257                         ata_bio->nbytes = xfer->c_bcount;
  258                         if (ata_bio->flags & ATA_LBA48)
  259                                 cmd = (ata_bio->flags & ATA_READ) ?
  260                                     WDCC_READDMA_EXT : WDCC_WRITEDMA_EXT;
  261                         else
  262                                 cmd = (ata_bio->flags & ATA_READ) ?
  263                                     WDCC_READDMA : WDCC_WRITEDMA;
  264                         /* Init the DMA channel. */
  265                         if ((*chp->wdc->dma_init)(chp->wdc->dma_arg,
  266                             chp->channel, xfer->drive,
  267                             (char *)xfer->databuf + xfer->c_skip,
  268                             ata_bio->nbytes, dma_flags) != 0) {
  269                                 ata_bio->error = ERR_DMA;
  270                                 ata_bio->r_error = 0;
  271                                 wdc_ata_bio_done(chp, xfer);
  272                                 return;
  273                         }
  274                         /* Initiate command */
  275                         wdc_set_drive(chp, xfer->drive);
  276                         if (wait_for_ready(chp, ata_delay) < 0)
  277                                 goto timeout;
  278                         if (ata_bio->flags & ATA_LBA48) {
  279                                 wdccommandext(chp, xfer->drive, cmd,
  280                                     (u_int64_t)ata_bio->blkno, nblks);
  281                         } else {
  282                                 wdccommand(chp, xfer->drive, cmd, cyl,
  283                                     head, sect, nblks, 0);
  284                         }
  285                         /* start the DMA channel */
  286                         (*chp->wdc->dma_start)(chp->wdc->dma_arg,
  287                             chp->channel, xfer->drive);
  288                         chp->ch_flags |= WDCF_DMA_WAIT;
  289                         /* wait for irq */
  290                         goto intr;
  291                 } /* else not DMA */
  292                 ata_bio->nblks = min(nblks, ata_bio->multi);
  293                 ata_bio->nbytes = ata_bio->nblks * ata_bio->lp->d_secsize;
  294                 if (ata_bio->nblks > 1 && (ata_bio->flags & ATA_SINGLE) == 0) {
  295                         if (ata_bio->flags & ATA_LBA48)
  296                                 cmd = (ata_bio->flags & ATA_READ) ?
  297                                     WDCC_READMULTI_EXT : WDCC_WRITEMULTI_EXT;
  298                         else
  299                                 cmd = (ata_bio->flags & ATA_READ) ?
  300                                     WDCC_READMULTI : WDCC_WRITEMULTI;
  301                 } else {
  302                         if (ata_bio->flags & ATA_LBA48)
  303                                 cmd = (ata_bio->flags & ATA_READ) ?
  304                                     WDCC_READ_EXT : WDCC_WRITE_EXT;
  305                         else
  306                                 cmd = (ata_bio->flags & ATA_READ) ?
  307                                     WDCC_READ : WDCC_WRITE;
  308                 }
  309                 /* Initiate command! */
  310                 wdc_set_drive(chp, xfer->drive);
  311                 if (wait_for_ready(chp, ata_delay) < 0)
  312                         goto timeout;
  313                 if (ata_bio->flags & ATA_LBA48) {
  314                         wdccommandext(chp, xfer->drive, cmd,
  315                             (u_int64_t)ata_bio->blkno, nblks);
  316                 } else {
  317                         wdccommand(chp, xfer->drive, cmd, cyl,
  318                             head, sect, nblks,
  319                             (ata_bio->lp->d_type == DTYPE_ST506) ?
  320                             ata_bio->lp->d_precompcyl / 4 : 0);
  321                 }
  322         } else if (ata_bio->nblks > 1) {
  323                 /* The number of blocks in the last stretch may be smaller. */
  324                 nblks = xfer->c_bcount / ata_bio->lp->d_secsize;
  325                 if (ata_bio->nblks > nblks) {
  326                         ata_bio->nblks = nblks;
  327                         ata_bio->nbytes = xfer->c_bcount;
  328                 }
  329         }
  330         /* If this was a write and not using DMA, push the data. */
  331         if ((ata_bio->flags & ATA_READ) == 0) {
  332                 if (wait_for_drq(chp, ata_delay) != 0) {
  333                         printf("%s:%d:%d: timeout waiting for DRQ, "
  334                             "st=0x%b, err=0x%02x\n",
  335                             chp->wdc->sc_dev.dv_xname, chp->channel,
  336                             xfer->drive, chp->ch_status, WDCS_BITS,
  337                             chp->ch_error);
  338                         if (wdc_ata_err(drvp, ata_bio) != WDC_ATA_ERR)
  339                                 ata_bio->error = TIMEOUT;
  340                         wdc_ata_bio_done(chp, xfer);
  341                         return;
  342                 }
  343                 if (wdc_ata_err(drvp, ata_bio) == WDC_ATA_ERR) {
  344                         wdc_ata_bio_done(chp, xfer);
  345                         return;
  346                 }
  347                 wdc_output_bytes(drvp, (char *)xfer->databuf + xfer->c_skip,
  348                     ata_bio->nbytes);
  349         }
  350 
  351 intr:   /* Wait for IRQ (either real or polled) */
  352         if ((ata_bio->flags & ATA_POLL) == 0) {
  353                 chp->ch_flags |= WDCF_IRQ_WAIT;
  354         } else {
  355                 /* Wait for at last 400ns for status bit to be valid */
  356                 delay(1);
  357                 if (chp->ch_flags & WDCF_DMA_WAIT) {
  358                         wdc_dmawait(chp, xfer, ATA_DELAY);
  359                         chp->ch_flags &= ~WDCF_DMA_WAIT;
  360                 }
  361                 wdc_ata_bio_intr(chp, xfer, 0);
  362                 if ((ata_bio->flags & ATA_ITSDONE) == 0)
  363                         goto again;
  364         }
  365         return;
  366 timeout:
  367         printf("%s:%d:%d: not ready, st=0x%b, err=0x%02x\n",
  368             chp->wdc->sc_dev.dv_xname, chp->channel, xfer->drive,
  369             chp->ch_status, WDCS_BITS, chp->ch_error);
  370         if (wdc_ata_err(drvp, ata_bio) != WDC_ATA_ERR)
  371                 ata_bio->error = TIMEOUT;
  372         wdc_ata_bio_done(chp, xfer);
  373         return;
  374 }
  375 
  376 int
  377 wdc_ata_bio_intr(struct channel_softc *chp, struct wdc_xfer *xfer, int irq)
  378 {
  379         struct ata_bio *ata_bio = xfer->cmd;
  380         struct ata_drive_datas *drvp = &chp->ch_drive[xfer->drive];
  381         int drv_err;
  382 
  383         WDCDEBUG_PRINT(("wdc_ata_bio_intr %s:%d:%d\n",
  384             chp->wdc->sc_dev.dv_xname, chp->channel, xfer->drive),
  385             DEBUG_INTR | DEBUG_XFERS);
  386 
  387 
  388         /* Is it not a transfer, but a control operation? */
  389         if (drvp->state < READY) {
  390                 printf("%s:%d:%d: bad state %d in wdc_ata_bio_intr\n",
  391                     chp->wdc->sc_dev.dv_xname, chp->channel, xfer->drive,
  392                     drvp->state);
  393                 panic("wdc_ata_bio_intr: bad state");
  394         }
  395 
  396         /*
  397          * reset on timeout. This will cause extra resets in the case
  398          * of occasional lost interrupts
  399          */
  400         if (xfer->c_flags & C_TIMEOU)
  401                 goto timeout;
  402 
  403         /* Ack interrupt done by wait_for_unbusy */
  404         if (wait_for_unbusy(chp,
  405             (irq == 0) ? ATA_DELAY : 0) < 0) {
  406                 if (irq)
  407                         return 0; /* IRQ was not for us */
  408                 printf("%s:%d:%d: device timeout, c_bcount=%d, c_skip%d\n",
  409                     chp->wdc->sc_dev.dv_xname, chp->channel, xfer->drive,
  410                     xfer->c_bcount, xfer->c_skip);
  411 
  412                 goto timeout;
  413         }
  414         if (chp->wdc->cap & WDC_CAPABILITY_IRQACK)
  415                 chp->wdc->irqack(chp);
  416 
  417         drv_err = wdc_ata_err(drvp, ata_bio);
  418 
  419         if (xfer->c_flags & C_DMA) {
  420                 if (chp->wdc->dma_status != 0) {
  421                         if (drv_err != WDC_ATA_ERR) {
  422                                 ata_bio->error = ERR_DMA;
  423                                 drv_err = WDC_ATA_ERR;
  424                         }
  425                 }
  426                 if (chp->ch_status & WDCS_DRQ) {
  427                         if (drv_err != WDC_ATA_ERR) {
  428                                 printf("%s:%d:%d: intr with DRQ (st=0x%b)\n",
  429                                     chp->wdc->sc_dev.dv_xname, chp->channel,
  430                                     xfer->drive, chp->ch_status, WDCS_BITS);
  431                                 ata_bio->error = TIMEOUT;
  432                                 drv_err = WDC_ATA_ERR;
  433                         }
  434                 }
  435                 if (drv_err != WDC_ATA_ERR)
  436                         goto end;
  437                 ata_dmaerr(drvp);
  438         }
  439 
  440         /* if we had an error, end */
  441         if (drv_err == WDC_ATA_ERR) {
  442                 wdc_ata_bio_done(chp, xfer);
  443                 return 1;
  444         }
  445 
  446         /* If this was a read and not using DMA, fetch the data. */
  447         if ((ata_bio->flags & ATA_READ) != 0) {
  448                 if ((chp->ch_status & WDCS_DRQ) != WDCS_DRQ) {
  449                         printf("%s:%d:%d: read intr before drq\n",
  450                             chp->wdc->sc_dev.dv_xname, chp->channel,
  451                             xfer->drive);
  452                         ata_bio->error = TIMEOUT;
  453                         wdc_ata_bio_done(chp, xfer);
  454                         return 1;
  455                 }
  456                 wdc_input_bytes(drvp, (char *)xfer->databuf + xfer->c_skip,
  457                     ata_bio->nbytes);
  458         }
  459 end:
  460         ata_bio->blkno += ata_bio->nblks;
  461         ata_bio->blkdone += ata_bio->nblks;
  462         xfer->c_skip += ata_bio->nbytes;
  463         xfer->c_bcount -= ata_bio->nbytes;
  464         /* See if this transfer is complete. */
  465         if (xfer->c_bcount > 0) {
  466                 if ((ata_bio->flags & ATA_POLL) == 0) {
  467                         /* Start the next operation */
  468                         _wdc_ata_bio_start(chp, xfer);
  469                 } else {
  470                         /* Let _wdc_ata_bio_start do the loop */
  471                         return 1;
  472                 }
  473         } else { /* Done with this transfer */
  474                 ata_bio->error = NOERROR;
  475                 wdc_ata_bio_done(chp, xfer);
  476         }
  477         return 1;
  478 
  479 timeout:
  480         if (xfer->c_flags & C_DMA)
  481                 ata_dmaerr(drvp);
  482 
  483         ata_bio->error = TIMEOUT;
  484         wdc_ata_bio_done(chp, xfer);
  485         return 1;
  486 }
  487 
  488 void
  489 wdc_ata_bio_kill_xfer(struct channel_softc *chp, struct wdc_xfer *xfer)
  490 {
  491         struct ata_bio *ata_bio = xfer->cmd;
  492 
  493         timeout_del(&chp->ch_timo);
  494         /* remove this command from xfer queue */
  495         wdc_free_xfer(chp, xfer);
  496 
  497         ata_bio->flags |= ATA_ITSDONE;
  498         ata_bio->error = ERR_NODEV;
  499         ata_bio->r_error = WDCE_ABRT;
  500         if ((ata_bio->flags & ATA_POLL) == 0) {
  501                 WDCDEBUG_PRINT(("wdc_ata_done: wddone\n"), DEBUG_XFERS);
  502                 wddone(ata_bio->wd);
  503         }
  504 }
  505 
  506 void
  507 wdc_ata_bio_done(struct channel_softc *chp, struct wdc_xfer *xfer)
  508 {
  509         struct ata_bio *ata_bio = xfer->cmd;
  510 
  511         WDCDEBUG_PRINT(("wdc_ata_bio_done %s:%d:%d: flags 0x%x\n",
  512             chp->wdc->sc_dev.dv_xname, chp->channel, xfer->drive,
  513             (u_int)xfer->c_flags),
  514             DEBUG_XFERS);
  515 
  516         timeout_del(&chp->ch_timo);
  517 
  518         /* feed back residual bcount to our caller */
  519         ata_bio->bcount = xfer->c_bcount;
  520 
  521         /* remove this command from xfer queue */
  522         wdc_free_xfer(chp, xfer);
  523 
  524         ata_bio->flags |= ATA_ITSDONE;
  525         if ((ata_bio->flags & ATA_POLL) == 0) {
  526                 WDCDEBUG_PRINT(("wdc_ata_done: wddone\n"), DEBUG_XFERS);
  527                 wddone(ata_bio->wd);
  528         }
  529         WDCDEBUG_PRINT(("wdcstart from wdc_ata_done, flags 0x%x\n",
  530             chp->ch_flags), DEBUG_XFERS);
  531         wdcstart(chp);
  532 }
  533 
  534 /*
  535  * Implement operations needed before read/write.
  536  */
  537 int
  538 wdc_ata_ctrl_intr(struct channel_softc *chp, struct wdc_xfer *xfer, int irq)
  539 {
  540         struct ata_bio *ata_bio = xfer->cmd;
  541         struct ata_drive_datas *drvp = &chp->ch_drive[xfer->drive];
  542         char *errstring = NULL;
  543         int delay = (irq == 0) ? ATA_DELAY : 0;
  544 
  545         WDCDEBUG_PRINT(("wdc_ata_ctrl_intr: state %d\n", drvp->state),
  546             DEBUG_FUNCS);
  547 
  548 again:
  549         switch (drvp->state) {
  550         case RECAL:    /* Should not be in this state here */
  551                 panic("wdc_ata_ctrl_intr: state==RECAL");
  552                 break;
  553 
  554         case RECAL_WAIT:
  555                 errstring = "recal";
  556                 if (wdcwait(chp, WDCS_DRDY, WDCS_DRDY, delay))
  557                         goto timeout;
  558                 if (chp->wdc->cap & WDC_CAPABILITY_IRQACK)
  559                         chp->wdc->irqack(chp);
  560                 if (chp->ch_status & (WDCS_ERR | WDCS_DWF))
  561                         goto error;
  562         /* FALLTHROUGH */
  563 
  564         case PIOMODE:
  565                 /* Don't try to set modes if controller can't be adjusted */
  566                 if ((chp->wdc->cap & WDC_CAPABILITY_MODE) == 0)
  567                         goto geometry;
  568                 /* Also don't try if the drive didn't report its mode */
  569                 if ((drvp->drive_flags & DRIVE_MODE) == 0)
  570                         goto geometry;
  571                 /* SET FEATURES 0x08 is only for PIO mode > 2 */
  572                 if (drvp->PIO_mode <= 2)
  573                         goto geometry;
  574                 wdccommand(chp, drvp->drive, SET_FEATURES, 0, 0, 0,
  575                     0x08 | drvp->PIO_mode, WDSF_SET_MODE);
  576                 drvp->state = PIOMODE_WAIT;
  577                 break;
  578 
  579         case PIOMODE_WAIT:
  580                 errstring = "piomode";
  581                 if (wdcwait(chp, WDCS_DRDY, WDCS_DRDY, delay))
  582                         goto timeout;
  583                 if (chp->wdc->cap & WDC_CAPABILITY_IRQACK)
  584                         chp->wdc->irqack(chp);
  585                 if (chp->ch_status & (WDCS_ERR | WDCS_DWF))
  586                         goto error;
  587         /* FALLTHROUGH */
  588 
  589         case DMAMODE:
  590                 if (drvp->drive_flags & DRIVE_UDMA) {
  591                         wdccommand(chp, drvp->drive, SET_FEATURES, 0, 0, 0,
  592                             0x40 | drvp->UDMA_mode, WDSF_SET_MODE);
  593                 } else if (drvp->drive_flags & DRIVE_DMA) {
  594                         wdccommand(chp, drvp->drive, SET_FEATURES, 0, 0, 0,
  595                             0x20 | drvp->DMA_mode, WDSF_SET_MODE);
  596                 } else {
  597                         goto geometry;
  598                 }
  599                 drvp->state = DMAMODE_WAIT;
  600                 break;
  601         case DMAMODE_WAIT:
  602                 errstring = "dmamode";
  603                 if (wdcwait(chp, WDCS_DRDY, WDCS_DRDY, delay))
  604                         goto timeout;
  605                 if (chp->wdc->cap & WDC_CAPABILITY_IRQACK)
  606                         chp->wdc->irqack(chp);
  607                 if (chp->ch_status & (WDCS_ERR | WDCS_DWF))
  608                         goto error;
  609         /* FALLTHROUGH */
  610 
  611         case GEOMETRY:
  612         geometry:
  613                 if (ata_bio->flags & ATA_LBA)
  614                         goto multimode;
  615                 wdccommand(chp, xfer->drive, WDCC_IDP,
  616                     ata_bio->lp->d_ncylinders,
  617                     ata_bio->lp->d_ntracks - 1, 0, ata_bio->lp->d_nsectors,
  618                     (ata_bio->lp->d_type == DTYPE_ST506) ?
  619                         ata_bio->lp->d_precompcyl / 4 : 0);
  620                 drvp->state = GEOMETRY_WAIT;
  621                 break;
  622 
  623         case GEOMETRY_WAIT:
  624                 errstring = "geometry";
  625                 if (wdcwait(chp, WDCS_DRDY, WDCS_DRDY, delay))
  626                         goto timeout;
  627                 if (chp->wdc->cap & WDC_CAPABILITY_IRQACK)
  628                         chp->wdc->irqack(chp);
  629                 if (chp->ch_status & (WDCS_ERR | WDCS_DWF))
  630                         goto error;
  631                 /* FALLTHROUGH */
  632 
  633         case MULTIMODE:
  634         multimode:
  635                 if (ata_bio->multi == 1)
  636                         goto ready;
  637                 wdccommand(chp, xfer->drive, WDCC_SETMULTI, 0, 0, 0,
  638                     ata_bio->multi, 0);
  639                 drvp->state = MULTIMODE_WAIT;
  640                 break;
  641 
  642         case MULTIMODE_WAIT:
  643                 errstring = "setmulti";
  644                 if (wdcwait(chp, WDCS_DRDY, WDCS_DRDY, delay))
  645                         goto timeout;
  646                 if (chp->wdc->cap & WDC_CAPABILITY_IRQACK)
  647                         chp->wdc->irqack(chp);
  648                 if (chp->ch_status & (WDCS_ERR | WDCS_DWF))
  649                         goto error;
  650                 /* FALLTHROUGH */
  651 
  652         case READY:
  653         ready:
  654                 drvp->state = READY;
  655                 /*
  656                  * The drive is usable now
  657                  */
  658                 xfer->c_intr = wdc_ata_bio_intr;
  659                 _wdc_ata_bio_start(chp, xfer);
  660                 return 1;
  661         }
  662 
  663         if ((ata_bio->flags & ATA_POLL) == 0) {
  664                 chp->ch_flags |= WDCF_IRQ_WAIT;
  665         } else {
  666                 goto again;
  667         }
  668         return 1;
  669 
  670 timeout:
  671         if (irq && (xfer->c_flags & C_TIMEOU) == 0) {
  672                 return 0; /* IRQ was not for us */
  673         }
  674         printf("%s:%d:%d: %s timed out\n",
  675             chp->wdc->sc_dev.dv_xname, chp->channel, xfer->drive, errstring);
  676         ata_bio->error = TIMEOUT;
  677         drvp->state = 0;
  678         wdc_ata_bio_done(chp, xfer);
  679         return 0;
  680 error:
  681         printf("%s:%d:%d: %s ",
  682             chp->wdc->sc_dev.dv_xname, chp->channel, xfer->drive,
  683             errstring);
  684         if (chp->ch_status & WDCS_DWF) {
  685                 printf("drive fault\n");
  686                 ata_bio->error = ERR_DF;
  687         } else {
  688                 printf("error (%x)\n", chp->ch_error);
  689                 ata_bio->r_error = chp->ch_error;
  690                 ata_bio->error = ERROR;
  691         }
  692         drvp->state = 0;
  693         wdc_ata_bio_done(chp, xfer);
  694         return 1;
  695 }
  696 
  697 int
  698 wdc_ata_err(struct ata_drive_datas *drvp, struct ata_bio *ata_bio)
  699 {
  700         struct channel_softc *chp = drvp->chnl_softc;
  701         ata_bio->error = 0;
  702         if (chp->ch_status & WDCS_BSY) {
  703                 ata_bio->error = TIMEOUT;
  704                 return WDC_ATA_ERR;
  705         }
  706 
  707         if (chp->ch_status & WDCS_DWF) {
  708                 ata_bio->error = ERR_DF;
  709                 return WDC_ATA_ERR;
  710         }
  711 
  712         if (chp->ch_status & WDCS_ERR) {
  713                 ata_bio->error = ERROR;
  714                 ata_bio->r_error = chp->ch_error;
  715                 if (drvp->drive_flags & DRIVE_UDMA &&
  716                     (ata_bio->r_error & WDCE_CRC)) {
  717                         /*
  718                          * Record the CRC error, to avoid downgrading to
  719                          * multiword DMA
  720                          */
  721                         drvp->drive_flags |= DRIVE_DMAERR;
  722                 }
  723                 if (ata_bio->r_error & (WDCE_BBK | WDCE_UNC | WDCE_IDNF |
  724                     WDCE_ABRT | WDCE_TK0NF | WDCE_AMNF))
  725                         return WDC_ATA_ERR;
  726                 return WDC_ATA_NOERR;
  727         }
  728 
  729         if (chp->ch_status & WDCS_CORR)
  730                 ata_bio->flags |= ATA_CORR;
  731         return WDC_ATA_NOERR;
  732 }
  733 
  734 #if 0
  735 int
  736 wdc_ata_addref(drvp)
  737         struct ata_drive_datas *drvp;
  738 {
  739         struct channel_softc *chp = drvp->chnl_softc;
  740 
  741         return (wdc_addref(chp));
  742 }
  743 
  744 void
  745 wdc_ata_delref(drvp)
  746         struct ata_drive_datas *drvp;
  747 {
  748         struct channel_softc *chp = drvp->chnl_softc;
  749 
  750         wdc_delref(chp);
  751 }
  752 #endif

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