[BACK]Return to ata_wdc.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / dev / ata

Annotation of src/sys/dev/ata/ata_wdc.c, Revision 1.85.8.1

1.85.8.1! ad          1: /*     $NetBSD: ata_wdc.c,v 1.85 2006/09/30 15:56:18 itohy Exp $       */
1.2       bouyer      2:
                      3: /*
1.41      bouyer      4:  * Copyright (c) 1998, 2001, 2003 Manuel Bouyer.
1.2       bouyer      5:  *
                      6:  * Redistribution and use in source and binary forms, with or without
                      7:  * modification, are permitted provided that the following conditions
                      8:  * are met:
                      9:  * 1. Redistributions of source code must retain the above copyright
                     10:  *    notice, this list of conditions and the following disclaimer.
                     11:  * 2. Redistributions in binary form must reproduce the above copyright
                     12:  *    notice, this list of conditions and the following disclaimer in the
                     13:  *    documentation and/or other materials provided with the distribution.
                     14:  * 3. All advertising materials mentioning features or use of this software
                     15:  *    must display the following acknowledgement:
1.36      bouyer     16:  *     This product includes software developed by Manuel Bouyer.
1.40      bouyer     17:  * 4. The name of the author may not be used to endorse or promote products
                     18:  *    derived from this software without specific prior written permission.
1.2       bouyer     19:  *
1.27      bouyer     20:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
                     21:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
                     22:  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
1.79      perry      23:  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
1.27      bouyer     24:  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
                     25:  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
                     26:  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
                     27:  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
                     28:  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
                     29:  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1.2       bouyer     30:  */
                     31:
                     32: /*-
1.57      mycroft    33:  * Copyright (c) 1998, 2004 The NetBSD Foundation, Inc.
1.2       bouyer     34:  * All rights reserved.
                     35:  *
                     36:  * This code is derived from software contributed to The NetBSD Foundation
                     37:  * by Charles M. Hannum, by Onno van der Linden and by Manuel Bouyer.
                     38:  *
                     39:  * Redistribution and use in source and binary forms, with or without
                     40:  * modification, are permitted provided that the following conditions
                     41:  * are met:
                     42:  * 1. Redistributions of source code must retain the above copyright
                     43:  *    notice, this list of conditions and the following disclaimer.
                     44:  * 2. Redistributions in binary form must reproduce the above copyright
                     45:  *    notice, this list of conditions and the following disclaimer in the
                     46:  *    documentation and/or other materials provided with the distribution.
                     47:  * 3. All advertising materials mentioning features or use of this software
                     48:  *    must display the following acknowledgement:
                     49:  *        This product includes software developed by the NetBSD
                     50:  *        Foundation, Inc. and its contributors.
                     51:  * 4. Neither the name of The NetBSD Foundation nor the names of its
                     52:  *    contributors may be used to endorse or promote products derived
                     53:  *    from this software without specific prior written permission.
                     54:  *
                     55:  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
                     56:  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
                     57:  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
                     58:  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
                     59:  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
                     60:  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
                     61:  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
                     62:  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
                     63:  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
                     64:  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
                     65:  * POSSIBILITY OF SUCH DAMAGE.
                     66:  */
1.31      lukem      67:
                     68: #include <sys/cdefs.h>
1.85.8.1! ad         69: __KERNEL_RCSID(0, "$NetBSD: ata_wdc.c,v 1.85 2006/09/30 15:56:18 itohy Exp $");
1.2       bouyer     70:
1.85.8.1! ad         71: #include "opt_ata.h"
1.2       bouyer     72:
                     73: #include <sys/param.h>
                     74: #include <sys/systm.h>
                     75: #include <sys/kernel.h>
                     76: #include <sys/file.h>
                     77: #include <sys/stat.h>
                     78: #include <sys/buf.h>
1.76      yamt       79: #include <sys/bufq.h>
1.2       bouyer     80: #include <sys/malloc.h>
                     81: #include <sys/device.h>
                     82: #include <sys/disklabel.h>
                     83: #include <sys/syslog.h>
                     84: #include <sys/proc.h>
                     85:
                     86: #include <machine/intr.h>
                     87: #include <machine/bus.h>
                     88: #ifndef __BUS_SPACE_HAS_STREAM_METHODS
                     89: #define    bus_space_write_multi_stream_2    bus_space_write_multi_2
                     90: #define    bus_space_write_multi_stream_4    bus_space_write_multi_4
                     91: #define    bus_space_read_multi_stream_2    bus_space_read_multi_2
                     92: #define    bus_space_read_multi_stream_4    bus_space_read_multi_4
                     93: #endif /* __BUS_SPACE_HAS_STREAM_METHODS */
                     94:
1.84      itohy      95: #include <dev/ata/ataconf.h>
1.2       bouyer     96: #include <dev/ata/atareg.h>
                     97: #include <dev/ata/atavar.h>
                     98: #include <dev/ic/wdcreg.h>
                     99: #include <dev/ic/wdcvar.h>
                    100:
                    101: #define DEBUG_INTR   0x01
                    102: #define DEBUG_XFERS  0x02
                    103: #define DEBUG_STATUS 0x04
                    104: #define DEBUG_FUNCS  0x08
                    105: #define DEBUG_PROBE  0x10
1.71      thorpej   106: #ifdef ATADEBUG
1.41      bouyer    107: extern int wdcdebug_wd_mask; /* inited in wd.c */
1.71      thorpej   108: #define ATADEBUG_PRINT(args, level) \
1.2       bouyer    109:        if (wdcdebug_wd_mask & (level)) \
                    110:                printf args
                    111: #else
1.71      thorpej   112: #define ATADEBUG_PRINT(args, level)
1.2       bouyer    113: #endif
                    114:
1.17      bouyer    115: #define ATA_DELAY 10000 /* 10s for a drive I/O */
1.2       bouyer    116:
1.45      thorpej   117: static int     wdc_ata_bio(struct ata_drive_datas*, struct ata_bio*);
1.72      thorpej   118: static void    wdc_ata_bio_start(struct ata_channel *,struct ata_xfer *);
                    119: static void    _wdc_ata_bio_start(struct ata_channel *,struct ata_xfer *);
                    120: static int     wdc_ata_bio_intr(struct ata_channel *, struct ata_xfer *,
1.45      thorpej   121:                                 int);
1.72      thorpej   122: static void    wdc_ata_bio_kill_xfer(struct ata_channel *,
1.58      bouyer    123:                                      struct ata_xfer *, int);
1.79      perry     124: static void    wdc_ata_bio_done(struct ata_channel *, struct ata_xfer *);
1.45      thorpej   125: static int     wdc_ata_err(struct ata_drive_datas *, struct ata_bio *);
1.2       bouyer    126: #define WDC_ATA_NOERR 0x00 /* Drive doesn't report an error */
                    127: #define WDC_ATA_RECOV 0x01 /* There was a recovered error */
                    128: #define WDC_ATA_ERR   0x02 /* Drive reports an error */
1.45      thorpej   129: static int     wdc_ata_addref(struct ata_drive_datas *);
                    130: static void    wdc_ata_delref(struct ata_drive_datas *);
1.32      bouyer    131:
                    132: const struct ata_bustype wdc_ata_bustype = {
                    133:        SCSIPI_BUSTYPE_ATA,
                    134:        wdc_ata_bio,
1.59      bouyer    135:        wdc_reset_drive,
1.74      thorpej   136:        wdc_reset_channel,
1.32      bouyer    137:        wdc_exec_command,
                    138:        ata_get_params,
                    139:        wdc_ata_addref,
                    140:        wdc_ata_delref,
1.66      thorpej   141:        ata_kill_pending,
1.32      bouyer    142: };
                    143:
1.2       bouyer    144: /*
1.64      thorpej   145:  * Handle block I/O operation. Return ATACMD_COMPLETE, ATACMD_QUEUED, or
                    146:  * ATACMD_TRY_AGAIN. Must be called at splbio().
1.2       bouyer    147:  */
1.45      thorpej   148: static int
1.44      thorpej   149: wdc_ata_bio(struct ata_drive_datas *drvp, struct ata_bio *ata_bio)
1.2       bouyer    150: {
1.48      thorpej   151:        struct ata_xfer *xfer;
1.72      thorpej   152:        struct ata_channel *chp = drvp->chnl_softc;
1.73      thorpej   153:        struct atac_softc *atac = chp->ch_atac;
1.2       bouyer    154:
1.65      thorpej   155:        xfer = ata_get_xfer(ATAXF_NOSLEEP);
1.2       bouyer    156:        if (xfer == NULL)
1.64      thorpej   157:                return ATACMD_TRY_AGAIN;
1.73      thorpej   158:        if (atac->atac_cap & ATAC_CAP_NOIRQ)
1.30      bjh21     159:                ata_bio->flags |= ATA_POLL;
1.2       bouyer    160:        if (ata_bio->flags & ATA_POLL)
                    161:                xfer->c_flags |= C_POLL;
1.85      itohy     162: #if NATA_DMA
1.2       bouyer    163:        if ((drvp->drive_flags & (DRIVE_DMA | DRIVE_UDMA)) &&
                    164:            (ata_bio->flags & ATA_SINGLE) == 0)
                    165:                xfer->c_flags |= C_DMA;
1.85      itohy     166: #endif
                    167: #if NATA_DMA && NATA_PIOBM
                    168:        else
                    169: #endif
1.84      itohy     170: #if NATA_PIOBM
1.85      itohy     171:        if (atac->atac_cap & ATAC_CAP_PIOBM)
1.84      itohy     172:                xfer->c_flags |= C_PIOBM;
                    173: #endif
1.48      thorpej   174:        xfer->c_drive = drvp->drive;
                    175:        xfer->c_cmd = ata_bio;
                    176:        xfer->c_databuf = ata_bio->databuf;
1.2       bouyer    177:        xfer->c_bcount = ata_bio->bcount;
                    178:        xfer->c_start = wdc_ata_bio_start;
                    179:        xfer->c_intr = wdc_ata_bio_intr;
1.22      enami     180:        xfer->c_kill_xfer = wdc_ata_bio_kill_xfer;
1.68      thorpej   181:        ata_exec_xfer(chp, xfer);
1.64      thorpej   182:        return (ata_bio->flags & ATA_ITSDONE) ? ATACMD_COMPLETE : ATACMD_QUEUED;
1.2       bouyer    183: }
                    184:
1.45      thorpej   185: static void
1.72      thorpej   186: wdc_ata_bio_start(struct ata_channel *chp, struct ata_xfer *xfer)
1.2       bouyer    187: {
1.73      thorpej   188:        struct atac_softc *atac = chp->ch_atac;
                    189:        struct wdc_softc *wdc = CHAN_TO_WDC(chp);
1.72      thorpej   190:        struct wdc_regs *wdr = &wdc->regs[chp->ch_channel];
1.48      thorpej   191:        struct ata_bio *ata_bio = xfer->c_cmd;
                    192:        struct ata_drive_datas *drvp = &chp->ch_drive[xfer->c_drive];
1.41      bouyer    193:        int wait_flags = (xfer->c_flags & C_POLL) ? AT_POLL : 0;
1.80      christos  194:        const char *errstring;
1.41      bouyer    195:
1.71      thorpej   196:        ATADEBUG_PRINT(("wdc_ata_bio_start %s:%d:%d\n",
1.73      thorpej   197:            atac->atac_dev.dv_xname, chp->ch_channel, xfer->c_drive),
1.20      bouyer    198:            DEBUG_XFERS);
                    199:
1.41      bouyer    200:        /* Do control operations specially. */
                    201:        if (__predict_false(drvp->state < READY)) {
                    202:                /*
                    203:                 * Actually, we want to be careful not to mess with the control
                    204:                 * state if the device is currently busy, but we can assume
                    205:                 * that we never get to this point if that's the case.
                    206:                 */
1.81      peter     207:                /* If it's not a polled command, we need the kernel thread */
1.41      bouyer    208:                if ((xfer->c_flags & C_POLL) == 0 &&
1.72      thorpej   209:                    (chp->ch_flags & ATACH_TH_RUN) == 0) {
1.42      bouyer    210:                        chp->ch_queue->queue_freeze++;
1.52      thorpej   211:                        wakeup(&chp->ch_thread);
1.41      bouyer    212:                        return;
                    213:                }
                    214:                /*
                    215:                 * disable interrupts, all commands here should be quick
                    216:                 * enouth to be able to poll, and we don't go here that often
                    217:                 */
1.72      thorpej   218:                bus_space_write_1(wdr->ctl_iot, wdr->ctl_ioh, wd_aux_ctlr,
1.41      bouyer    219:                    WDCTL_4BIT | WDCTL_IDS);
1.70      thorpej   220:                if (wdc->select)
1.51      thorpej   221:                        wdc->select(chp, xfer->c_drive);
1.72      thorpej   222:                bus_space_write_1(wdr->cmd_iot, wdr->cmd_iohs[wd_sdh], 0,
1.48      thorpej   223:                    WDSD_IBM | (xfer->c_drive << 4));
1.53      fvdl      224:                DELAY(10);
1.41      bouyer    225:                errstring = "wait";
                    226:                if (wdcwait(chp, WDCS_DRDY, WDCS_DRDY, ATA_DELAY, wait_flags))
                    227:                        goto ctrltimeout;
1.48      thorpej   228:                wdccommandshort(chp, xfer->c_drive, WDCC_RECAL);
1.41      bouyer    229:                /* Wait for at last 400ns for status bit to be valid */
                    230:                DELAY(1);
                    231:                errstring = "recal";
                    232:                if (wdcwait(chp, WDCS_DRDY, WDCS_DRDY, ATA_DELAY, wait_flags))
                    233:                        goto ctrltimeout;
                    234:                if (chp->ch_status & (WDCS_ERR | WDCS_DWF))
                    235:                        goto ctrlerror;
                    236:                /* Don't try to set modes if controller can't be adjusted */
1.73      thorpej   237:                if (atac->atac_set_modes == NULL)
1.41      bouyer    238:                        goto geometry;
                    239:                /* Also don't try if the drive didn't report its mode */
                    240:                if ((drvp->drive_flags & DRIVE_MODE) == 0)
                    241:                        goto geometry;
                    242:                wdccommand(chp, drvp->drive, SET_FEATURES, 0, 0, 0,
                    243:                    0x08 | drvp->PIO_mode, WDSF_SET_MODE);
                    244:                errstring = "piomode";
                    245:                if (wdcwait(chp, WDCS_DRDY, WDCS_DRDY, ATA_DELAY, wait_flags))
                    246:                        goto ctrltimeout;
                    247:                if (chp->ch_status & (WDCS_ERR | WDCS_DWF))
                    248:                        goto ctrlerror;
1.85      itohy     249: #if NATA_DMA
                    250: #if NATA_UDMA
1.41      bouyer    251:                if (drvp->drive_flags & DRIVE_UDMA) {
                    252:                        wdccommand(chp, drvp->drive, SET_FEATURES, 0, 0, 0,
                    253:                            0x40 | drvp->UDMA_mode, WDSF_SET_MODE);
1.85      itohy     254:                } else
                    255: #endif
                    256:                if (drvp->drive_flags & DRIVE_DMA) {
1.41      bouyer    257:                        wdccommand(chp, drvp->drive, SET_FEATURES, 0, 0, 0,
                    258:                            0x20 | drvp->DMA_mode, WDSF_SET_MODE);
                    259:                } else {
                    260:                        goto geometry;
1.79      perry     261:                }
1.41      bouyer    262:                errstring = "dmamode";
                    263:                if (wdcwait(chp, WDCS_DRDY, WDCS_DRDY, ATA_DELAY, wait_flags))
                    264:                        goto ctrltimeout;
                    265:                if (chp->ch_status & (WDCS_ERR | WDCS_DWF))
                    266:                        goto ctrlerror;
1.85      itohy     267: #endif /* NATA_DMA */
1.41      bouyer    268: geometry:
                    269:                if (ata_bio->flags & ATA_LBA)
                    270:                        goto multimode;
1.48      thorpej   271:                wdccommand(chp, xfer->c_drive, WDCC_IDP,
1.41      bouyer    272:                    ata_bio->lp->d_ncylinders,
                    273:                    ata_bio->lp->d_ntracks - 1, 0, ata_bio->lp->d_nsectors,
                    274:                    (ata_bio->lp->d_type == DTYPE_ST506) ?
                    275:                        ata_bio->lp->d_precompcyl / 4 : 0);
                    276:                errstring = "geometry";
                    277:                if (wdcwait(chp, WDCS_DRDY, WDCS_DRDY, ATA_DELAY, wait_flags))
                    278:                        goto ctrltimeout;
                    279:                if (chp->ch_status & (WDCS_ERR | WDCS_DWF))
                    280:                        goto ctrlerror;
                    281: multimode:
                    282:                if (ata_bio->multi == 1)
                    283:                        goto ready;
1.48      thorpej   284:                wdccommand(chp, xfer->c_drive, WDCC_SETMULTI, 0, 0, 0,
1.41      bouyer    285:                    ata_bio->multi, 0);
                    286:                errstring = "setmulti";
                    287:                if (wdcwait(chp, WDCS_DRDY, WDCS_DRDY, ATA_DELAY, wait_flags))
                    288:                        goto ctrltimeout;
                    289:                if (chp->ch_status & (WDCS_ERR | WDCS_DWF))
                    290:                        goto ctrlerror;
                    291: ready:
                    292:                drvp->state = READY;
                    293:                /*
                    294:                 * The drive is usable now
                    295:                 */
1.72      thorpej   296:                bus_space_write_1(wdr->ctl_iot, wdr->ctl_ioh, wd_aux_ctlr,
1.41      bouyer    297:                    WDCTL_4BIT);
1.54      bouyer    298:                delay(10); /* some drives need a little delay here */
1.41      bouyer    299:        }
                    300:
1.20      bouyer    301:        _wdc_ata_bio_start(chp, xfer);
1.41      bouyer    302:        return;
                    303: ctrltimeout:
                    304:        printf("%s:%d:%d: %s timed out\n",
1.73      thorpej   305:            atac->atac_dev.dv_xname, chp->ch_channel, xfer->c_drive,
1.51      thorpej   306:            errstring);
1.41      bouyer    307:        ata_bio->error = TIMEOUT;
                    308:        goto ctrldone;
                    309: ctrlerror:
                    310:        printf("%s:%d:%d: %s ",
1.73      thorpej   311:            atac->atac_dev.dv_xname, chp->ch_channel, xfer->c_drive,
1.41      bouyer    312:            errstring);
                    313:        if (chp->ch_status & WDCS_DWF) {
                    314:                printf("drive fault\n");
                    315:                ata_bio->error = ERR_DF;
                    316:        } else {
                    317:                printf("error (%x)\n", chp->ch_error);
                    318:                ata_bio->r_error = chp->ch_error;
                    319:                ata_bio->error = ERROR;
                    320:        }
                    321: ctrldone:
                    322:        drvp->state = 0;
                    323:        wdc_ata_bio_done(chp, xfer);
1.72      thorpej   324:        bus_space_write_1(wdr->ctl_iot, wdr->ctl_ioh, wd_aux_ctlr, WDCTL_4BIT);
1.41      bouyer    325:        return;
1.20      bouyer    326: }
                    327:
1.45      thorpej   328: static void
1.72      thorpej   329: _wdc_ata_bio_start(struct ata_channel *chp, struct ata_xfer *xfer)
1.20      bouyer    330: {
1.73      thorpej   331:        struct atac_softc *atac = chp->ch_atac;
                    332:        struct wdc_softc *wdc = CHAN_TO_WDC(chp);
1.72      thorpej   333:        struct wdc_regs *wdr = &wdc->regs[chp->ch_channel];
1.48      thorpej   334:        struct ata_bio *ata_bio = xfer->c_cmd;
                    335:        struct ata_drive_datas *drvp = &chp->ch_drive[xfer->c_drive];
1.51      thorpej   336:        int wait_flags = (xfer->c_flags & C_POLL) ? AT_POLL : 0;
1.2       bouyer    337:        u_int16_t cyl;
                    338:        u_int8_t head, sect, cmd = 0;
1.85      itohy     339:        int nblks;
                    340: #if NATA_DMA || NATA_PIOBM
                    341:        int error, dma_flags = 0;
                    342: #endif
1.2       bouyer    343:
1.71      thorpej   344:        ATADEBUG_PRINT(("_wdc_ata_bio_start %s:%d:%d\n",
1.73      thorpej   345:            atac->atac_dev.dv_xname, chp->ch_channel, xfer->c_drive),
1.20      bouyer    346:            DEBUG_INTR | DEBUG_XFERS);
1.2       bouyer    347:
1.85      itohy     348: #if NATA_DMA || NATA_PIOBM
1.84      itohy     349:        if (xfer->c_flags & (C_DMA | C_PIOBM)) {
1.85      itohy     350: #if NATA_DMA
1.23      bouyer    351:                if (drvp->n_xfers <= NXFER)
                    352:                        drvp->n_xfers++;
1.85      itohy     353: #endif
1.2       bouyer    354:                dma_flags = (ata_bio->flags & ATA_READ) ?  WDC_DMA_READ : 0;
1.39      nakayama  355:                if (ata_bio->flags & ATA_LBA48)
                    356:                        dma_flags |= WDC_DMA_LBA48;
1.2       bouyer    357:        }
1.85      itohy     358: #endif
1.2       bouyer    359: again:
                    360:        /*
                    361:         *
                    362:         * When starting a multi-sector transfer, or doing single-sector
                    363:         * transfers...
                    364:         */
                    365:        if (xfer->c_skip == 0 || (ata_bio->flags & ATA_SINGLE) != 0) {
                    366:                if (ata_bio->flags & ATA_SINGLE)
                    367:                        nblks = 1;
1.79      perry     368:                else
1.2       bouyer    369:                        nblks = xfer->c_bcount / ata_bio->lp->d_secsize;
                    370:                /* Check for bad sectors and adjust transfer, if necessary. */
                    371:                if ((ata_bio->lp->d_flags & D_BADSECT) != 0) {
                    372:                        long blkdiff;
                    373:                        int i;
                    374:                        for (i = 0; (blkdiff = ata_bio->badsect[i]) != -1;
                    375:                            i++) {
                    376:                                blkdiff -= ata_bio->blkno;
                    377:                                if (blkdiff < 0)
                    378:                                        continue;
                    379:                                if (blkdiff == 0) {
                    380:                                        /* Replace current block of transfer. */
                    381:                                        ata_bio->blkno =
                    382:                                            ata_bio->lp->d_secperunit -
                    383:                                            ata_bio->lp->d_nsectors - i - 1;
                    384:                                }
                    385:                                if (blkdiff < nblks) {
                    386:                                        /* Bad block inside transfer. */
                    387:                                        ata_bio->flags |= ATA_SINGLE;
                    388:                                        nblks = 1;
                    389:                                }
                    390:                                break;
                    391:                        }
                    392:                /* Transfer is okay now. */
                    393:                }
1.34      christos  394:                if (ata_bio->flags & ATA_LBA48) {
                    395:                        sect = 0;
                    396:                        cyl =  0;
                    397:                        head = 0;
                    398:                } else if (ata_bio->flags & ATA_LBA) {
1.2       bouyer    399:                        sect = (ata_bio->blkno >> 0) & 0xff;
                    400:                        cyl = (ata_bio->blkno >> 8) & 0xffff;
                    401:                        head = (ata_bio->blkno >> 24) & 0x0f;
                    402:                        head |= WDSD_LBA;
                    403:                } else {
                    404:                        int blkno = ata_bio->blkno;
                    405:                        sect = blkno % ata_bio->lp->d_nsectors;
                    406:                        sect++;    /* Sectors begin with 1, not 0. */
                    407:                        blkno /= ata_bio->lp->d_nsectors;
                    408:                        head = blkno % ata_bio->lp->d_ntracks;
                    409:                        blkno /= ata_bio->lp->d_ntracks;
                    410:                        cyl = blkno;
                    411:                        head |= WDSD_CHS;
                    412:                }
1.85      itohy     413: #if NATA_DMA
1.2       bouyer    414:                if (xfer->c_flags & C_DMA) {
                    415:                        ata_bio->nblks = nblks;
                    416:                        ata_bio->nbytes = xfer->c_bcount;
                    417:                        cmd = (ata_bio->flags & ATA_READ) ?
                    418:                            WDCC_READDMA : WDCC_WRITEDMA;
                    419:                        /* Init the DMA channel. */
1.82      thorpej   420:                        error = (*wdc->dma_init)(wdc->dma_arg,
1.51      thorpej   421:                            chp->ch_channel, xfer->c_drive,
1.79      perry     422:                            (char *)xfer->c_databuf + xfer->c_skip,
1.82      thorpej   423:                            ata_bio->nbytes, dma_flags);
                    424:                        if (error) {
                    425:                                if (error == EINVAL) {
                    426:                                        /*
                    427:                                         * We can't do DMA on this transfer
                    428:                                         * for some reason.  Fall back to
                    429:                                         * PIO.
                    430:                                         */
                    431:                                        xfer->c_flags &= ~C_DMA;
                    432:                                        error = 0;
                    433:                                        goto do_pio;
                    434:                                }
1.2       bouyer    435:                                ata_bio->error = ERR_DMA;
                    436:                                ata_bio->r_error = 0;
                    437:                                wdc_ata_bio_done(chp, xfer);
                    438:                                return;
                    439:                        }
                    440:                        /* Initiate command */
1.70      thorpej   441:                        if (wdc->select)
1.51      thorpej   442:                                wdc->select(chp, xfer->c_drive);
1.72      thorpej   443:                        bus_space_write_1(wdr->cmd_iot, wdr->cmd_iohs[wd_sdh],
1.48      thorpej   444:                            0, WDSD_IBM | (xfer->c_drive << 4));
1.49      thorpej   445:                        switch(wdc_wait_for_ready(chp, ATA_DELAY, wait_flags)) {
1.41      bouyer    446:                        case WDCWAIT_OK:
1.79      perry     447:                                break;
1.41      bouyer    448:                        case WDCWAIT_TOUT:
1.2       bouyer    449:                                goto timeout;
1.41      bouyer    450:                        case WDCWAIT_THR:
                    451:                                return;
                    452:                        }
1.34      christos  453:                        if (ata_bio->flags & ATA_LBA48) {
1.75      thorpej   454:                            wdccommandext(chp, xfer->c_drive, atacmd_to48(cmd),
1.34      christos  455:                                (u_int64_t)ata_bio->blkno, nblks);
                    456:                        } else {
1.48      thorpej   457:                            wdccommand(chp, xfer->c_drive, cmd, cyl,
1.34      christos  458:                                head, sect, nblks, 0);
                    459:                        }
1.2       bouyer    460:                        /* start the DMA channel */
1.51      thorpej   461:                        (*wdc->dma_start)(wdc->dma_arg,
                    462:                            chp->ch_channel, xfer->c_drive);
1.72      thorpej   463:                        chp->ch_flags |= ATACH_DMA_WAIT;
1.41      bouyer    464:                        /* start timeout machinery */
                    465:                        if ((xfer->c_flags & C_POLL) == 0)
                    466:                                callout_reset(&chp->ch_callout,
                    467:                                    ATA_DELAY / 1000 * hz, wdctimeout, chp);
1.2       bouyer    468:                        /* wait for irq */
                    469:                        goto intr;
                    470:                } /* else not DMA */
1.82      thorpej   471:  do_pio:
1.85      itohy     472: #endif /* NATA_DMA */
1.84      itohy     473: #if NATA_PIOBM
                    474:                if ((xfer->c_flags & C_PIOBM) && xfer->c_skip == 0) {
                    475:                        if (ata_bio->flags & ATA_POLL) {
                    476:                                /* XXX not supported yet --- fall back to PIO */
                    477:                                xfer->c_flags &= ~C_PIOBM;
                    478:                        } else {
                    479:                                /* Init the DMA channel. */
                    480:                                error = (*wdc->dma_init)(wdc->dma_arg,
                    481:                                    chp->ch_channel, xfer->c_drive,
                    482:                                    (char *)xfer->c_databuf + xfer->c_skip,
                    483:                                    xfer->c_bcount,
                    484:                                    dma_flags | WDC_DMA_PIOBM_ATA);
                    485:                                if (error) {
                    486:                                        if (error == EINVAL) {
                    487:                                                /*
                    488:                                                 * We can't do DMA on this
                    489:                                                 * transfer for some reason.
                    490:                                                 * Fall back to PIO.
                    491:                                                 */
                    492:                                                xfer->c_flags &= ~C_PIOBM;
                    493:                                                error = 0;
                    494:                                        } else {
                    495:                                                ata_bio->error = ERR_DMA;
                    496:                                                ata_bio->r_error = 0;
                    497:                                                wdc_ata_bio_done(chp, xfer);
                    498:                                                return;
                    499:                                        }
                    500:                                }
                    501:                        }
                    502:                }
                    503: #endif
1.2       bouyer    504:                ata_bio->nblks = min(nblks, ata_bio->multi);
                    505:                ata_bio->nbytes = ata_bio->nblks * ata_bio->lp->d_secsize;
1.56      mycroft   506:                KASSERT(nblks == 1 || (ata_bio->flags & ATA_SINGLE) == 0);
                    507:                if (ata_bio->nblks > 1) {
1.2       bouyer    508:                        cmd = (ata_bio->flags & ATA_READ) ?
                    509:                            WDCC_READMULTI : WDCC_WRITEMULTI;
                    510:                } else {
                    511:                        cmd = (ata_bio->flags & ATA_READ) ?
                    512:                            WDCC_READ : WDCC_WRITE;
                    513:                }
                    514:                /* Initiate command! */
1.70      thorpej   515:                if (wdc->select)
1.51      thorpej   516:                        wdc->select(chp, xfer->c_drive);
1.72      thorpej   517:                bus_space_write_1(wdr->cmd_iot, wdr->cmd_iohs[wd_sdh], 0,
1.48      thorpej   518:                    WDSD_IBM | (xfer->c_drive << 4));
1.49      thorpej   519:                switch(wdc_wait_for_ready(chp, ATA_DELAY, wait_flags)) {
1.41      bouyer    520:                case WDCWAIT_OK:
                    521:                        break;
                    522:                case WDCWAIT_TOUT:
1.2       bouyer    523:                        goto timeout;
1.41      bouyer    524:                case WDCWAIT_THR:
                    525:                        return;
                    526:                }
1.34      christos  527:                if (ata_bio->flags & ATA_LBA48) {
1.75      thorpej   528:                    wdccommandext(chp, xfer->c_drive, atacmd_to48(cmd),
1.34      christos  529:                        (u_int64_t) ata_bio->blkno, nblks);
                    530:                } else {
1.48      thorpej   531:                    wdccommand(chp, xfer->c_drive, cmd, cyl,
1.34      christos  532:                        head, sect, nblks,
                    533:                        (ata_bio->lp->d_type == DTYPE_ST506) ?
                    534:                        ata_bio->lp->d_precompcyl / 4 : 0);
                    535:                }
1.41      bouyer    536:                /* start timeout machinery */
                    537:                if ((xfer->c_flags & C_POLL) == 0)
                    538:                        callout_reset(&chp->ch_callout,
                    539:                            ATA_DELAY / 1000 * hz, wdctimeout, chp);
1.2       bouyer    540:        } else if (ata_bio->nblks > 1) {
                    541:                /* The number of blocks in the last stretch may be smaller. */
                    542:                nblks = xfer->c_bcount / ata_bio->lp->d_secsize;
                    543:                if (ata_bio->nblks > nblks) {
                    544:                ata_bio->nblks = nblks;
                    545:                ata_bio->nbytes = xfer->c_bcount;
                    546:                }
                    547:        }
                    548:        /* If this was a write and not using DMA, push the data. */
                    549:        if ((ata_bio->flags & ATA_READ) == 0) {
1.41      bouyer    550:                /*
                    551:                 * we have to busy-wait here, we can't rely on running in
                    552:                 * thread context.
                    553:                 */
1.49      thorpej   554:                if (wdc_wait_for_drq(chp, ATA_DELAY, AT_POLL) != 0) {
1.2       bouyer    555:                        printf("%s:%d:%d: timeout waiting for DRQ, "
                    556:                            "st=0x%02x, err=0x%02x\n",
1.73      thorpej   557:                            atac->atac_dev.dv_xname, chp->ch_channel,
1.48      thorpej   558:                            xfer->c_drive, chp->ch_status, chp->ch_error);
1.16      bouyer    559:                        if (wdc_ata_err(drvp, ata_bio) != WDC_ATA_ERR)
1.2       bouyer    560:                                ata_bio->error = TIMEOUT;
                    561:                        wdc_ata_bio_done(chp, xfer);
                    562:                        return;
                    563:                }
1.16      bouyer    564:                if (wdc_ata_err(drvp, ata_bio) == WDC_ATA_ERR) {
1.2       bouyer    565:                        wdc_ata_bio_done(chp, xfer);
                    566:                        return;
                    567:                }
1.84      itohy     568: #if NATA_PIOBM
                    569:                if (xfer->c_flags & C_PIOBM) {
                    570:                        /* start the busmastering PIO */
                    571:                        (*wdc->piobm_start)(wdc->dma_arg,
                    572:                            chp->ch_channel, xfer->c_drive,
                    573:                            xfer->c_skip, ata_bio->nbytes, 0);
                    574:                        chp->ch_flags |= ATACH_DMA_WAIT;
                    575:                } else
                    576: #endif
                    577:
1.63      mycroft   578:                wdc->dataout_pio(chp, drvp->drive_flags,
1.62      mycroft   579:                    (char *)xfer->c_databuf + xfer->c_skip, ata_bio->nbytes);
1.2       bouyer    580:        }
                    581:
1.85      itohy     582: #if NATA_DMA
                    583: intr:
                    584: #endif
                    585:        /* Wait for IRQ (either real or polled) */
1.2       bouyer    586:        if ((ata_bio->flags & ATA_POLL) == 0) {
1.72      thorpej   587:                chp->ch_flags |= ATACH_IRQ_WAIT;
1.2       bouyer    588:        } else {
                    589:                /* Wait for at last 400ns for status bit to be valid */
                    590:                delay(1);
1.85      itohy     591: #if NATA_DMA
1.72      thorpej   592:                if (chp->ch_flags & ATACH_DMA_WAIT) {
1.26      bouyer    593:                        wdc_dmawait(chp, xfer, ATA_DELAY);
1.72      thorpej   594:                        chp->ch_flags &= ~ATACH_DMA_WAIT;
1.26      bouyer    595:                }
1.85      itohy     596: #endif
1.19      bouyer    597:                wdc_ata_bio_intr(chp, xfer, 0);
1.2       bouyer    598:                if ((ata_bio->flags & ATA_ITSDONE) == 0)
                    599:                        goto again;
                    600:        }
                    601:        return;
                    602: timeout:
                    603:        printf("%s:%d:%d: not ready, st=0x%02x, err=0x%02x\n",
1.73      thorpej   604:            atac->atac_dev.dv_xname, chp->ch_channel, xfer->c_drive,
1.2       bouyer    605:            chp->ch_status, chp->ch_error);
1.16      bouyer    606:        if (wdc_ata_err(drvp, ata_bio) != WDC_ATA_ERR)
1.2       bouyer    607:                ata_bio->error = TIMEOUT;
                    608:        wdc_ata_bio_done(chp, xfer);
                    609:        return;
                    610: }
                    611:
1.45      thorpej   612: static int
1.72      thorpej   613: wdc_ata_bio_intr(struct ata_channel *chp, struct ata_xfer *xfer, int irq)
1.2       bouyer    614: {
1.73      thorpej   615:        struct atac_softc *atac = chp->ch_atac;
                    616:        struct wdc_softc *wdc = CHAN_TO_WDC(chp);
1.48      thorpej   617:        struct ata_bio *ata_bio = xfer->c_cmd;
                    618:        struct ata_drive_datas *drvp = &chp->ch_drive[xfer->c_drive];
1.2       bouyer    619:        int drv_err;
                    620:
1.71      thorpej   621:        ATADEBUG_PRINT(("wdc_ata_bio_intr %s:%d:%d\n",
1.73      thorpej   622:            atac->atac_dev.dv_xname, chp->ch_channel, xfer->c_drive),
1.2       bouyer    623:            DEBUG_INTR | DEBUG_XFERS);
                    624:
                    625:
                    626:        /* Is it not a transfer, but a control operation? */
                    627:        if (drvp->state < READY) {
                    628:                printf("%s:%d:%d: bad state %d in wdc_ata_bio_intr\n",
1.73      thorpej   629:                    atac->atac_dev.dv_xname, chp->ch_channel, xfer->c_drive,
1.2       bouyer    630:                    drvp->state);
1.38      provos    631:                panic("wdc_ata_bio_intr: bad state");
1.2       bouyer    632:        }
                    633:
1.20      bouyer    634:        /*
                    635:         * if we missed an interrupt in a PIO transfer, reset and restart.
                    636:         * Don't try to continue transfer, we may have missed cycles.
                    637:         */
                    638:        if ((xfer->c_flags & (C_TIMEOU | C_DMA)) == C_TIMEOU) {
                    639:                ata_bio->error = TIMEOUT;
                    640:                wdc_ata_bio_done(chp, xfer);
                    641:                return 1;
                    642:        }
                    643:
1.84      itohy     644: #if NATA_PIOBM
                    645:        /* Transfer-done interrupt for busmastering PIO read */
                    646:        if ((xfer->c_flags & C_PIOBM) && (chp->ch_flags & ATACH_PIOBM_WAIT)) {
                    647:                chp->ch_flags &= ~ATACH_PIOBM_WAIT;
                    648:                goto end;
                    649:        }
                    650: #endif
                    651:
1.49      thorpej   652:        /* Ack interrupt done by wdc_wait_for_unbusy */
                    653:        if (wdc_wait_for_unbusy(chp, (irq == 0) ? ATA_DELAY : 0, AT_POLL) < 0) {
1.19      bouyer    654:                if (irq && (xfer->c_flags & C_TIMEOU) == 0)
1.18      bouyer    655:                        return 0; /* IRQ was not for us */
1.2       bouyer    656:                printf("%s:%d:%d: device timeout, c_bcount=%d, c_skip%d\n",
1.73      thorpej   657:                    atac->atac_dev.dv_xname, chp->ch_channel, xfer->c_drive,
1.2       bouyer    658:                    xfer->c_bcount, xfer->c_skip);
                    659:                ata_bio->error = TIMEOUT;
                    660:                wdc_ata_bio_done(chp, xfer);
                    661:                return 1;
                    662:        }
1.70      thorpej   663:        if (wdc->irqack)
1.51      thorpej   664:                wdc->irqack(chp);
1.79      perry     665:
1.16      bouyer    666:        drv_err = wdc_ata_err(drvp, ata_bio);
1.2       bouyer    667:
1.85      itohy     668: #if NATA_DMA
1.2       bouyer    669:        /* If we were using DMA, Turn off the DMA channel and check for error */
                    670:        if (xfer->c_flags & C_DMA) {
                    671:                if (ata_bio->flags & ATA_POLL) {
                    672:                        /*
1.13      bouyer    673:                         * IDE drives deassert WDCS_BSY before transfer is
1.2       bouyer    674:                         * complete when using DMA. Polling for DRQ to deassert
1.37      wiz       675:                         * is not enough DRQ is not required to be
1.7       bouyer    676:                         * asserted for DMA transfers, so poll for DRDY.
1.2       bouyer    677:                         */
                    678:                        if (wdcwait(chp, WDCS_DRDY | WDCS_DRQ, WDCS_DRDY,
1.41      bouyer    679:                            ATA_DELAY, ATA_POLL) == WDCWAIT_TOUT) {
1.7       bouyer    680:                                printf("%s:%d:%d: polled transfer timed out "
1.73      thorpej   681:                                    "(st=0x%x)\n", atac->atac_dev.dv_xname,
1.51      thorpej   682:                                    chp->ch_channel, xfer->c_drive,
1.48      thorpej   683:                                    chp->ch_status);
1.2       bouyer    684:                                ata_bio->error = TIMEOUT;
1.10      bouyer    685:                                drv_err = WDC_ATA_ERR;
                    686:                        }
                    687:                }
1.51      thorpej   688:                if (wdc->dma_status != 0) {
1.10      bouyer    689:                        if (drv_err != WDC_ATA_ERR) {
                    690:                                ata_bio->error = ERR_DMA;
                    691:                                drv_err = WDC_ATA_ERR;
1.2       bouyer    692:                        }
                    693:                }
                    694:                if (chp->ch_status & WDCS_DRQ) {
                    695:                        if (drv_err != WDC_ATA_ERR) {
                    696:                                printf("%s:%d:%d: intr with DRQ (st=0x%x)\n",
1.73      thorpej   697:                                    atac->atac_dev.dv_xname, chp->ch_channel,
1.48      thorpej   698:                                    xfer->c_drive, chp->ch_status);
1.2       bouyer    699:                                ata_bio->error = TIMEOUT;
                    700:                                drv_err = WDC_ATA_ERR;
                    701:                        }
                    702:                }
1.77      bouyer    703:                if (drv_err != WDC_ATA_ERR)
                    704:                        goto end;
1.78      bouyer    705:                if (ata_bio->r_error & WDCE_CRC || ata_bio->error == ERR_DMA)
1.55      mycroft   706:                        ata_dmaerr(drvp, (xfer->c_flags & C_POLL) ? AT_POLL : 0);
1.2       bouyer    707:        }
1.85      itohy     708: #endif /* NATA_DMA */
1.2       bouyer    709:
                    710:        /* if we had an error, end */
                    711:        if (drv_err == WDC_ATA_ERR) {
                    712:                wdc_ata_bio_done(chp, xfer);
                    713:                return 1;
                    714:        }
                    715:
                    716:        /* If this was a read and not using DMA, fetch the data. */
                    717:        if ((ata_bio->flags & ATA_READ) != 0) {
1.14      bouyer    718:                if ((chp->ch_status & WDCS_DRQ) != WDCS_DRQ) {
1.2       bouyer    719:                        printf("%s:%d:%d: read intr before drq\n",
1.73      thorpej   720:                            atac->atac_dev.dv_xname, chp->ch_channel,
1.48      thorpej   721:                            xfer->c_drive);
1.2       bouyer    722:                        ata_bio->error = TIMEOUT;
                    723:                        wdc_ata_bio_done(chp, xfer);
                    724:                        return 1;
                    725:                }
1.84      itohy     726: #if NATA_PIOBM
                    727:                if (xfer->c_flags & C_PIOBM) {
                    728:                        /* start the busmastering PIO */
                    729:                        (*wdc->piobm_start)(wdc->dma_arg,
                    730:                            chp->ch_channel, xfer->c_drive,
                    731:                            xfer->c_skip, ata_bio->nbytes,
                    732:                            WDC_PIOBM_XFER_IRQ);
                    733:                        chp->ch_flags |= ATACH_DMA_WAIT | ATACH_PIOBM_WAIT | ATACH_IRQ_WAIT;
                    734:                        return 1;
                    735:                } else
                    736: #endif
1.63      mycroft   737:                wdc->datain_pio(chp, drvp->drive_flags,
1.62      mycroft   738:                    (char *)xfer->c_databuf + xfer->c_skip, ata_bio->nbytes);
1.2       bouyer    739:        }
                    740:
1.85      itohy     741: #if NATA_DMA || NATA_PIOBM
1.2       bouyer    742: end:
1.85      itohy     743: #endif
1.2       bouyer    744:        ata_bio->blkno += ata_bio->nblks;
                    745:        ata_bio->blkdone += ata_bio->nblks;
                    746:        xfer->c_skip += ata_bio->nbytes;
                    747:        xfer->c_bcount -= ata_bio->nbytes;
                    748:        /* See if this transfer is complete. */
                    749:        if (xfer->c_bcount > 0) {
                    750:                if ((ata_bio->flags & ATA_POLL) == 0) {
                    751:                        /* Start the next operation */
1.20      bouyer    752:                        _wdc_ata_bio_start(chp, xfer);
1.2       bouyer    753:                } else {
1.20      bouyer    754:                        /* Let _wdc_ata_bio_start do the loop */
1.2       bouyer    755:                        return 1;
                    756:                }
                    757:        } else { /* Done with this transfer */
                    758:                ata_bio->error = NOERROR;
                    759:                wdc_ata_bio_done(chp, xfer);
                    760:        }
                    761:        return 1;
1.22      enami     762: }
                    763:
1.45      thorpej   764: static void
1.72      thorpej   765: wdc_ata_bio_kill_xfer(struct ata_channel *chp, struct ata_xfer *xfer,
1.58      bouyer    766:     int reason)
1.22      enami     767: {
1.48      thorpej   768:        struct ata_bio *ata_bio = xfer->c_cmd;
                    769:        int drive = xfer->c_drive;
1.22      enami     770:
1.65      thorpej   771:        ata_free_xfer(chp, xfer);
1.22      enami     772:
                    773:        ata_bio->flags |= ATA_ITSDONE;
1.58      bouyer    774:        switch (reason) {
                    775:        case KILL_GONE:
                    776:                ata_bio->error = ERR_NODEV;
                    777:                break;
                    778:        case KILL_RESET:
                    779:                ata_bio->error = ERR_RESET;
                    780:                break;
                    781:        default:
                    782:                printf("wdc_ata_bio_kill_xfer: unknown reason %d\n",
                    783:                    reason);
                    784:                panic("wdc_ata_bio_kill_xfer");
                    785:        }
1.22      enami     786:        ata_bio->r_error = WDCE_ABRT;
1.71      thorpej   787:        ATADEBUG_PRINT(("wdc_ata_done: drv_done\n"), DEBUG_XFERS);
1.46      thorpej   788:        (*chp->ch_drive[drive].drv_done)(chp->ch_drive[drive].drv_softc);
1.2       bouyer    789: }
                    790:
1.45      thorpej   791: static void
1.72      thorpej   792: wdc_ata_bio_done(struct ata_channel *chp, struct ata_xfer *xfer)
1.2       bouyer    793: {
1.48      thorpej   794:        struct ata_bio *ata_bio = xfer->c_cmd;
                    795:        int drive = xfer->c_drive;
1.2       bouyer    796:
1.71      thorpej   797:        ATADEBUG_PRINT(("wdc_ata_bio_done %s:%d:%d: flags 0x%x\n",
1.85.8.1! ad        798:            chp->ch_atac->atac_dev.dv_xname, chp->ch_channel, xfer->c_drive,
1.5       bouyer    799:            (u_int)xfer->c_flags),
1.4       bouyer    800:            DEBUG_XFERS);
1.10      bouyer    801:
1.24      thorpej   802:        callout_stop(&chp->ch_callout);
1.2       bouyer    803:
                    804:        /* feed back residual bcount to our caller */
                    805:        ata_bio->bcount = xfer->c_bcount;
                    806:
1.60      bouyer    807:        /* mark controller inactive and free xfer */
                    808:        chp->ch_queue->active_xfer = NULL;
1.65      thorpej   809:        ata_free_xfer(chp, xfer);
1.2       bouyer    810:
1.61      bouyer    811:        if (chp->ch_drive[drive].drive_flags & DRIVE_WAITDRAIN) {
                    812:                ata_bio->error = ERR_NODEV;
                    813:                chp->ch_drive[drive].drive_flags &= ~DRIVE_WAITDRAIN;
                    814:                wakeup(&chp->ch_queue->active_xfer);
                    815:        }
1.2       bouyer    816:        ata_bio->flags |= ATA_ITSDONE;
1.71      thorpej   817:        ATADEBUG_PRINT(("wdc_ata_done: drv_done\n"), DEBUG_XFERS);
1.46      thorpej   818:        (*chp->ch_drive[drive].drv_done)(chp->ch_drive[drive].drv_softc);
1.71      thorpej   819:        ATADEBUG_PRINT(("atastart from wdc_ata_done, flags 0x%x\n",
1.4       bouyer    820:            chp->ch_flags), DEBUG_XFERS);
1.69      thorpej   821:        atastart(chp);
1.2       bouyer    822: }
                    823:
1.45      thorpej   824: static int
1.44      thorpej   825: wdc_ata_err(struct ata_drive_datas *drvp, struct ata_bio *ata_bio)
1.2       bouyer    826: {
1.72      thorpej   827:        struct ata_channel *chp = drvp->chnl_softc;
1.2       bouyer    828:        ata_bio->error = 0;
                    829:        if (chp->ch_status & WDCS_BSY) {
                    830:                ata_bio->error = TIMEOUT;
                    831:                return WDC_ATA_ERR;
                    832:        }
                    833:
                    834:        if (chp->ch_status & WDCS_DWF) {
                    835:                ata_bio->error = ERR_DF;
                    836:                return WDC_ATA_ERR;
                    837:        }
                    838:
                    839:        if (chp->ch_status & WDCS_ERR) {
                    840:                ata_bio->error = ERROR;
                    841:                ata_bio->r_error = chp->ch_error;
                    842:                if (ata_bio->r_error & (WDCE_BBK | WDCE_UNC | WDCE_IDNF |
                    843:                    WDCE_ABRT | WDCE_TK0NF | WDCE_AMNF))
                    844:                        return WDC_ATA_ERR;
                    845:                return WDC_ATA_NOERR;
                    846:        }
                    847:
                    848:        if (chp->ch_status & WDCS_CORR)
                    849:                ata_bio->flags |= ATA_CORR;
                    850:        return WDC_ATA_NOERR;
1.8       thorpej   851: }
                    852:
1.45      thorpej   853: static int
1.44      thorpej   854: wdc_ata_addref(struct ata_drive_datas *drvp)
1.8       thorpej   855: {
1.72      thorpej   856:        struct ata_channel *chp = drvp->chnl_softc;
1.8       thorpej   857:
1.67      thorpej   858:        return (ata_addref(chp));
1.8       thorpej   859: }
                    860:
1.45      thorpej   861: static void
1.44      thorpej   862: wdc_ata_delref(struct ata_drive_datas *drvp)
1.8       thorpej   863: {
1.72      thorpej   864:        struct ata_channel *chp = drvp->chnl_softc;
1.8       thorpej   865:
1.67      thorpej   866:        ata_delref(chp);
1.2       bouyer    867: }

CVSweb <webmaster@jp.NetBSD.org>