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

Annotation of src/sys/dev/ata/ata.c, Revision 1.70.2.8

1.70.2.8! yamt        1: /*     $NetBSD: ata.c,v 1.70.2.7 2008/03/17 09:14:37 yamt Exp $        */
1.21      thorpej     2:
1.2       bouyer      3: /*
1.16      bouyer      4:  * Copyright (c) 1998, 2001 Manuel Bouyer.  All rights reserved.
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:
                     16:  *  This product includes software developed by Manuel 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.
                     19:  *
                     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.65      perry      23:  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
1.2       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.
                     30:  */
1.14      lukem      31:
                     32: #include <sys/cdefs.h>
1.70.2.8! yamt       33: __KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.70.2.7 2008/03/17 09:14:37 yamt Exp $");
1.2       bouyer     34:
1.70.2.4  yamt       35: #include "opt_ata.h"
1.2       bouyer     36:
                     37: #include <sys/param.h>
                     38: #include <sys/systm.h>
                     39: #include <sys/kernel.h>
                     40: #include <sys/malloc.h>
                     41: #include <sys/device.h>
1.30      bouyer     42: #include <sys/conf.h>
                     43: #include <sys/fcntl.h>
1.23      thorpej    44: #include <sys/proc.h>
1.41      thorpej    45: #include <sys/pool.h>
1.23      thorpej    46: #include <sys/kthread.h>
                     47: #include <sys/errno.h>
1.30      bouyer     48: #include <sys/ataio.h>
1.70.2.6  yamt       49: #include <sys/kmem.h>
                     50: #include <sys/simplelock.h>
1.70.2.5  yamt       51: #include <sys/intr.h>
                     52: #include <sys/bus.h>
1.15      bouyer     53:
1.70.2.2  yamt       54: #include <dev/ata/ataconf.h>
1.2       bouyer     55: #include <dev/ata/atareg.h>
                     56: #include <dev/ata/atavar.h>
1.70.2.2  yamt       57: #include <dev/ic/wdcvar.h>     /* for PIOBM */
1.2       bouyer     58:
1.23      thorpej    59: #include "locators.h"
                     60:
1.51      thorpej    61: #include "atapibus.h"
                     62: #include "ataraid.h"
                     63:
1.65      perry      64: #if NATARAID > 0
                     65: #include <dev/ata/ata_raidvar.h>
1.51      thorpej    66: #endif
                     67:
1.2       bouyer     68: #define DEBUG_FUNCS  0x08
                     69: #define DEBUG_PROBE  0x10
1.23      thorpej    70: #define DEBUG_DETACH 0x20
1.44      thorpej    71: #define        DEBUG_XFERS  0x40
1.47      thorpej    72: #ifdef ATADEBUG
                     73: int atadebug_mask = 0;
                     74: #define ATADEBUG_PRINT(args, level) \
1.70.2.2  yamt       75:        if (atadebug_mask & (level)) \
1.2       bouyer     76:                printf args
                     77: #else
1.47      thorpej    78: #define ATADEBUG_PRINT(args, level)
1.2       bouyer     79: #endif
                     80:
1.70.2.4  yamt       81: POOL_INIT(ata_xfer_pool, sizeof(struct ata_xfer), 0, 0, 0, "ataspl", NULL,
                     82:     IPL_BIO);
1.41      thorpej    83:
1.51      thorpej    84: /*
                     85:  * A queue of atabus instances, used to ensure the same bus probe order
                     86:  * for a given hardware configuration at each boot.
                     87:  */
                     88: struct atabus_initq_head atabus_initq_head =
                     89:     TAILQ_HEAD_INITIALIZER(atabus_initq_head);
                     90: struct simplelock atabus_interlock = SIMPLELOCK_INITIALIZER;
                     91:
1.23      thorpej    92: /*****************************************************************************
                     93:  * ATA bus layer.
                     94:  *
                     95:  * ATA controllers attach an atabus instance, which handles probing the bus
                     96:  * for drives, etc.
                     97:  *****************************************************************************/
                     98:
1.30      bouyer     99: dev_type_open(atabusopen);
                    100: dev_type_close(atabusclose);
                    101: dev_type_ioctl(atabusioctl);
                    102:
                    103: const struct cdevsw atabus_cdevsw = {
                    104:        atabusopen, atabusclose, noread, nowrite, atabusioctl,
1.70.2.2  yamt      105:        nostop, notty, nopoll, nommap, nokqfilter, D_OTHER
1.30      bouyer    106: };
                    107:
                    108: extern struct cfdriver atabus_cd;
                    109:
1.70.2.6  yamt      110: static void atabus_childdetached(device_t, device_t);
1.70.2.7  yamt      111: static bool atabus_resume(device_t PMF_FN_PROTO);
                    112: static bool atabus_suspend(device_t PMF_FN_PROTO);
1.30      bouyer    113:
1.23      thorpej   114: /*
                    115:  * atabusprint:
                    116:  *
                    117:  *     Autoconfiguration print routine used by ATA controllers when
                    118:  *     attaching an atabus instance.
                    119:  */
                    120: int
                    121: atabusprint(void *aux, const char *pnp)
                    122: {
1.48      thorpej   123:        struct ata_channel *chan = aux;
1.65      perry     124:
1.23      thorpej   125:        if (pnp)
                    126:                aprint_normal("atabus at %s", pnp);
1.26      thorpej   127:        aprint_normal(" channel %d", chan->ch_channel);
1.23      thorpej   128:
                    129:        return (UNCONF);
                    130: }
                    131:
                    132: /*
                    133:  * ataprint:
                    134:  *
                    135:  *     Autoconfiguration print routine.
                    136:  */
                    137: int
                    138: ataprint(void *aux, const char *pnp)
                    139: {
                    140:        struct ata_device *adev = aux;
                    141:
                    142:        if (pnp)
                    143:                aprint_normal("wd at %s", pnp);
                    144:        aprint_normal(" drive %d", adev->adev_drv_data->drive);
                    145:
                    146:        return (UNCONF);
                    147: }
                    148:
1.52      thorpej   149: /*
                    150:  * ata_channel_attach:
                    151:  *
                    152:  *     Common parts of attaching an atabus to an ATA controller channel.
                    153:  */
                    154: void
                    155: ata_channel_attach(struct ata_channel *chp)
                    156: {
                    157:
                    158:        if (chp->ch_flags & ATACH_DISABLED)
                    159:                return;
1.65      perry     160:
1.70.2.4  yamt      161:        callout_init(&chp->ch_callout, 0);
1.52      thorpej   162:
                    163:        TAILQ_INIT(&chp->ch_queue->queue_xfer);
                    164:        chp->ch_queue->queue_freeze = 0;
1.68      bouyer    165:        chp->ch_queue->queue_flags = 0;
1.52      thorpej   166:        chp->ch_queue->active_xfer = NULL;
                    167:
1.70.2.8! yamt      168:        chp->atabus = config_found_ia(chp->ch_atac->atac_dev, "ata", chp,
1.70.2.1  yamt      169:                atabusprint);
1.52      thorpej   170: }
                    171:
1.51      thorpej   172: static void
                    173: atabusconfig(struct atabus_softc *atabus_sc)
                    174: {
                    175:        struct ata_channel *chp = atabus_sc->sc_chan;
                    176:        struct atac_softc *atac = chp->ch_atac;
1.58      thorpej   177:        int i, s;
1.51      thorpej   178:        struct atabus_initq *atabus_initq = NULL;
                    179:
                    180:        /* Probe for the drives. */
1.70.2.2  yamt      181:        /* XXX for SATA devices we will power up all drives at once */
1.51      thorpej   182:        (*atac->atac_probe)(chp);
                    183:
                    184:        ATADEBUG_PRINT(("atabusattach: ch_drive_flags 0x%x 0x%x\n",
                    185:            chp->ch_drive[0].drive_flags, chp->ch_drive[1].drive_flags),
                    186:            DEBUG_PROBE);
                    187:
                    188:        /* If no drives, abort here */
                    189:        for (i = 0; i < chp->ch_ndrive; i++)
                    190:                if ((chp->ch_drive[i].drive_flags & DRIVE) != 0)
                    191:                        break;
                    192:        if (i == chp->ch_ndrive)
                    193:                goto out;
                    194:
                    195:        /* Shortcut in case we've been shutdown */
                    196:        if (chp->ch_flags & ATACH_SHUTDOWN)
                    197:                goto out;
                    198:
                    199:        /* Make sure the devices probe in atabus order to avoid jitter. */
                    200:        simple_lock(&atabus_interlock);
                    201:        while(1) {
                    202:                atabus_initq = TAILQ_FIRST(&atabus_initq_head);
                    203:                if (atabus_initq->atabus_sc == atabus_sc)
                    204:                        break;
                    205:                ltsleep(&atabus_initq_head, PRIBIO, "ata_initq", 0,
                    206:                    &atabus_interlock);
                    207:        }
                    208:        simple_unlock(&atabus_interlock);
                    209:
                    210:        /*
                    211:         * Attach an ATAPI bus, if needed.
                    212:         */
                    213:        for (i = 0; i < chp->ch_ndrive; i++) {
                    214:                if (chp->ch_drive[i].drive_flags & DRIVE_ATAPI) {
                    215: #if NATAPIBUS > 0
                    216:                        (*atac->atac_atapibus_attach)(atabus_sc);
                    217: #else
                    218:                        /*
                    219:                         * Fake the autoconfig "not configured" message
                    220:                         */
                    221:                        aprint_normal("atapibus at %s not configured\n",
1.70.2.8! yamt      222:                            device_xname(atac->atac_dev));
1.51      thorpej   223:                        chp->atapibus = NULL;
1.58      thorpej   224:                        s = splbio();
1.51      thorpej   225:                        for (i = 0; i < chp->ch_ndrive; i++)
                    226:                                chp->ch_drive[i].drive_flags &= ~DRIVE_ATAPI;
1.58      thorpej   227:                        splx(s);
1.51      thorpej   228: #endif
                    229:                        break;
                    230:                }
                    231:        }
                    232:
                    233:        for (i = 0; i < chp->ch_ndrive; i++) {
                    234:                struct ata_device adev;
                    235:                if ((chp->ch_drive[i].drive_flags &
                    236:                    (DRIVE_ATA | DRIVE_OLD)) == 0) {
                    237:                        continue;
                    238:                }
                    239:                memset(&adev, 0, sizeof(struct ata_device));
                    240:                adev.adev_bustype = atac->atac_bustype_ata;
                    241:                adev.adev_channel = chp->ch_channel;
                    242:                adev.adev_openings = 1;
                    243:                adev.adev_drv_data = &chp->ch_drive[i];
1.70.2.8! yamt      244:                chp->ata_drives[i] = config_found_ia(atabus_sc->sc_dev,
1.70.2.1  yamt      245:                    "ata_hl", &adev, ataprint);
1.51      thorpej   246:                if (chp->ata_drives[i] != NULL)
                    247:                        ata_probe_caps(&chp->ch_drive[i]);
1.58      thorpej   248:                else {
                    249:                        s = splbio();
1.51      thorpej   250:                        chp->ch_drive[i].drive_flags &=
                    251:                            ~(DRIVE_ATA | DRIVE_OLD);
1.58      thorpej   252:                        splx(s);
                    253:                }
1.51      thorpej   254:        }
                    255:
                    256:        /* now that we know the drives, the controller can set its modes */
                    257:        if (atac->atac_set_modes) {
                    258:                (*atac->atac_set_modes)(chp);
                    259:                ata_print_modes(chp);
                    260:        }
                    261: #if NATARAID > 0
                    262:        if (atac->atac_cap & ATAC_CAP_RAID)
                    263:                for (i = 0; i < chp->ch_ndrive; i++)
                    264:                        if (chp->ata_drives[i] != NULL)
                    265:                                ata_raid_check_component(chp->ata_drives[i]);
                    266: #endif /* NATARAID > 0 */
                    267:
                    268:        /*
                    269:         * reset drive_flags for unattached devices, reset state for attached
                    270:         * ones
                    271:         */
1.58      thorpej   272:        s = splbio();
1.51      thorpej   273:        for (i = 0; i < chp->ch_ndrive; i++) {
                    274:                if (chp->ch_drive[i].drv_softc == NULL)
                    275:                        chp->ch_drive[i].drive_flags = 0;
                    276:                else
                    277:                        chp->ch_drive[i].state = 0;
                    278:        }
1.58      thorpej   279:        splx(s);
1.51      thorpej   280:
                    281:  out:
                    282:        if (atabus_initq == NULL) {
                    283:                simple_lock(&atabus_interlock);
                    284:                while(1) {
                    285:                        atabus_initq = TAILQ_FIRST(&atabus_initq_head);
                    286:                        if (atabus_initq->atabus_sc == atabus_sc)
                    287:                                break;
                    288:                        ltsleep(&atabus_initq_head, PRIBIO, "ata_initq", 0,
                    289:                            &atabus_interlock);
                    290:                }
                    291:                simple_unlock(&atabus_interlock);
                    292:        }
1.70.2.2  yamt      293:        simple_lock(&atabus_interlock);
                    294:        TAILQ_REMOVE(&atabus_initq_head, atabus_initq, atabus_initq);
                    295:        simple_unlock(&atabus_interlock);
1.51      thorpej   296:
1.70.2.2  yamt      297:        free(atabus_initq, M_DEVBUF);
                    298:        wakeup(&atabus_initq_head);
1.51      thorpej   299:
                    300:        ata_delref(chp);
                    301:
                    302:        config_pending_decr();
                    303: }
                    304:
1.23      thorpej   305: /*
                    306:  * atabus_thread:
                    307:  *
                    308:  *     Worker thread for the ATA bus.
                    309:  */
                    310: static void
                    311: atabus_thread(void *arg)
                    312: {
                    313:        struct atabus_softc *sc = arg;
1.48      thorpej   314:        struct ata_channel *chp = sc->sc_chan;
1.24      thorpej   315:        struct ata_xfer *xfer;
1.48      thorpej   316:        int i, s;
1.23      thorpej   317:
                    318:        s = splbio();
1.48      thorpej   319:        chp->ch_flags |= ATACH_TH_RUN;
                    320:
                    321:        /*
                    322:         * Probe the drives.  Reset all flags to 0 to indicate to controllers
                    323:         * that can re-probe that all drives must be probed..
                    324:         *
                    325:         * Note: ch_ndrive may be changed during the probe.
                    326:         */
                    327:        for (i = 0; i < ATA_MAXDRIVES; i++)
                    328:                chp->ch_drive[i].drive_flags = 0;
1.23      thorpej   329:        splx(s);
                    330:
                    331:        /* Configure the devices on the bus. */
1.68      bouyer    332:        atabusconfig(sc);
1.23      thorpej   333:
1.69      bouyer    334:        s = splbio();
1.23      thorpej   335:        for (;;) {
1.48      thorpej   336:                if ((chp->ch_flags & (ATACH_TH_RESET | ATACH_SHUTDOWN)) == 0 &&
1.33      bouyer    337:                    (chp->ch_queue->active_xfer == NULL ||
1.23      thorpej   338:                     chp->ch_queue->queue_freeze == 0)) {
1.48      thorpej   339:                        chp->ch_flags &= ~ATACH_TH_RUN;
1.27      thorpej   340:                        (void) tsleep(&chp->ch_thread, PRIBIO, "atath", 0);
1.48      thorpej   341:                        chp->ch_flags |= ATACH_TH_RUN;
1.23      thorpej   342:                }
1.59      thorpej   343:                if (chp->ch_flags & ATACH_SHUTDOWN) {
1.23      thorpej   344:                        break;
1.59      thorpej   345:                }
1.48      thorpej   346:                if (chp->ch_flags & ATACH_TH_RESET) {
1.31      bouyer    347:                        /*
1.55      thorpej   348:                         * ata_reset_channel() will freeze 2 times, so
1.31      bouyer    349:                         * unfreeze one time. Not a problem as we're at splbio
                    350:                         */
1.23      thorpej   351:                        chp->ch_queue->queue_freeze--;
1.55      thorpej   352:                        ata_reset_channel(chp, AT_WAIT | chp->ch_reset_flags);
1.33      bouyer    353:                } else if (chp->ch_queue->active_xfer != NULL &&
1.23      thorpej   354:                           chp->ch_queue->queue_freeze == 1) {
                    355:                        /*
                    356:                         * Caller has bumped queue_freeze, decrease it.
                    357:                         */
                    358:                        chp->ch_queue->queue_freeze--;
1.33      bouyer    359:                        xfer = chp->ch_queue->active_xfer;
1.23      thorpej   360:                        KASSERT(xfer != NULL);
1.61      bouyer    361:                        (*xfer->c_start)(xfer->c_chp, xfer);
1.23      thorpej   362:                } else if (chp->ch_queue->queue_freeze > 1)
                    363:                        panic("ata_thread: queue_freeze");
                    364:        }
1.69      bouyer    365:        splx(s);
1.27      thorpej   366:        chp->ch_thread = NULL;
1.70      christos  367:        wakeup(&chp->ch_flags);
1.23      thorpej   368:        kthread_exit(0);
                    369: }
                    370:
                    371: /*
                    372:  * atabus_match:
                    373:  *
                    374:  *     Autoconfiguration match routine.
                    375:  */
                    376: static int
1.70.2.6  yamt      377: atabus_match(device_t parent, struct cfdata *cf, void *aux)
1.23      thorpej   378: {
1.48      thorpej   379:        struct ata_channel *chp = aux;
1.23      thorpej   380:
                    381:        if (chp == NULL)
                    382:                return (0);
1.65      perry     383:
1.26      thorpej   384:        if (cf->cf_loc[ATACF_CHANNEL] != chp->ch_channel &&
1.23      thorpej   385:            cf->cf_loc[ATACF_CHANNEL] != ATACF_CHANNEL_DEFAULT)
1.70.2.2  yamt      386:                return (0);
1.65      perry     387:
1.23      thorpej   388:        return (1);
                    389: }
                    390:
                    391: /*
                    392:  * atabus_attach:
                    393:  *
                    394:  *     Autoconfiguration attach routine.
                    395:  */
                    396: static void
1.70.2.6  yamt      397: atabus_attach(device_t parent, device_t self, void *aux)
1.23      thorpej   398: {
1.70.2.6  yamt      399:        struct atabus_softc *sc = device_private(self);
1.48      thorpej   400:        struct ata_channel *chp = aux;
1.23      thorpej   401:        struct atabus_initq *initq;
1.70.2.4  yamt      402:        int error;
1.23      thorpej   403:
                    404:        sc->sc_chan = chp;
                    405:
                    406:        aprint_normal("\n");
                    407:        aprint_naive("\n");
                    408:
1.70.2.8! yamt      409:        sc->sc_dev = self;
        !           410:
1.70.2.2  yamt      411:        if (ata_addref(chp))
                    412:                return;
1.35      mycroft   413:
1.23      thorpej   414:        initq = malloc(sizeof(*initq), M_DEVBUF, M_WAITOK);
                    415:        initq->atabus_sc = sc;
                    416:        TAILQ_INSERT_TAIL(&atabus_initq_head, initq, atabus_initq);
                    417:        config_pending_incr();
1.70.2.4  yamt      418:
                    419:        if ((error = kthread_create(PRI_NONE, 0, NULL, atabus_thread, sc,
1.70.2.6  yamt      420:            &chp->ch_thread, "%s", device_xname(self))) != 0)
                    421:                aprint_error_dev(self,
                    422:                    "unable to create kernel thread: error %d\n", error);
                    423:
                    424:        if (!pmf_device_register(self, atabus_suspend, atabus_resume))
                    425:                aprint_error_dev(self, "couldn't establish power handler\n");
1.23      thorpej   426: }
                    427:
                    428: /*
                    429:  * atabus_activate:
                    430:  *
                    431:  *     Autoconfiguration activation routine.
                    432:  */
                    433: static int
1.70.2.6  yamt      434: atabus_activate(device_t self, enum devact act)
1.23      thorpej   435: {
1.70.2.6  yamt      436:        struct atabus_softc *sc = device_private(self);
1.48      thorpej   437:        struct ata_channel *chp = sc->sc_chan;
1.70.2.6  yamt      438:        device_t dev = NULL;
1.23      thorpej   439:        int s, i, error = 0;
                    440:
                    441:        s = splbio();
                    442:        switch (act) {
                    443:        case DVACT_ACTIVATE:
                    444:                error = EOPNOTSUPP;
                    445:                break;
1.65      perry     446:
1.23      thorpej   447:        case DVACT_DEACTIVATE:
                    448:                /*
                    449:                 * We might deactivate the children of atapibus twice
                    450:                 * (once bia atapibus, once directly), but since the
                    451:                 * generic autoconfiguration code maintains the DVF_ACTIVE
                    452:                 * flag, it's safe.
                    453:                 */
                    454:                if ((dev = chp->atapibus) != NULL) {
                    455:                        error = config_deactivate(dev);
                    456:                        if (error)
                    457:                                goto out;
                    458:                }
                    459:
1.48      thorpej   460:                for (i = 0; i < chp->ch_ndrive; i++) {
1.23      thorpej   461:                        if ((dev = chp->ch_drive[i].drv_softc) != NULL) {
1.47      thorpej   462:                                ATADEBUG_PRINT(("atabus_activate: %s: "
1.70.2.6  yamt      463:                                    "deactivating %s\n", device_xname(self),
                    464:                                    device_xname(dev)),
1.23      thorpej   465:                                    DEBUG_DETACH);
                    466:                                error = config_deactivate(dev);
                    467:                                if (error)
                    468:                                        goto out;
                    469:                        }
                    470:                }
                    471:                break;
                    472:        }
                    473:  out:
                    474:        splx(s);
                    475:
1.47      thorpej   476: #ifdef ATADEBUG
1.23      thorpej   477:        if (dev != NULL && error != 0)
1.47      thorpej   478:                ATADEBUG_PRINT(("atabus_activate: %s: "
1.70.2.6  yamt      479:                    "error %d deactivating %s\n", device_xname(self),
                    480:                    error, device_xname(dev)), DEBUG_DETACH);
1.47      thorpej   481: #endif /* ATADEBUG */
1.23      thorpej   482:
                    483:        return (error);
                    484: }
                    485:
                    486: /*
                    487:  * atabus_detach:
                    488:  *
                    489:  *     Autoconfiguration detach routine.
                    490:  */
                    491: static int
1.70.2.6  yamt      492: atabus_detach(device_t self, int flags)
1.23      thorpej   493: {
1.70.2.6  yamt      494:        struct atabus_softc *sc = device_private(self);
1.48      thorpej   495:        struct ata_channel *chp = sc->sc_chan;
1.70.2.6  yamt      496:        device_t dev = NULL;
1.57      thorpej   497:        int s, i, error = 0;
1.23      thorpej   498:
                    499:        /* Shutdown the channel. */
1.57      thorpej   500:        s = splbio();           /* XXX ALSO NEED AN INTERLOCK HERE. */
1.48      thorpej   501:        chp->ch_flags |= ATACH_SHUTDOWN;
1.57      thorpej   502:        splx(s);
1.70.2.6  yamt      503:
1.27      thorpej   504:        wakeup(&chp->ch_thread);
1.70.2.6  yamt      505:
1.27      thorpej   506:        while (chp->ch_thread != NULL)
1.70      christos  507:                (void) tsleep(&chp->ch_flags, PRIBIO, "atadown", 0);
1.65      perry     508:
1.66      tacha     509:
1.23      thorpej   510:        /*
                    511:         * Detach atapibus and its children.
                    512:         */
                    513:        if ((dev = chp->atapibus) != NULL) {
1.47      thorpej   514:                ATADEBUG_PRINT(("atabus_detach: %s: detaching %s\n",
1.70.2.6  yamt      515:                    device_xname(self), device_xname(dev)), DEBUG_DETACH);
                    516:
1.23      thorpej   517:                error = config_detach(dev, flags);
                    518:                if (error)
                    519:                        goto out;
                    520:        }
                    521:
                    522:        /*
                    523:         * Detach our other children.
                    524:         */
1.48      thorpej   525:        for (i = 0; i < chp->ch_ndrive; i++) {
1.23      thorpej   526:                if (chp->ch_drive[i].drive_flags & DRIVE_ATAPI)
                    527:                        continue;
                    528:                if ((dev = chp->ch_drive[i].drv_softc) != NULL) {
1.47      thorpej   529:                        ATADEBUG_PRINT(("atabus_detach: %s: detaching %s\n",
1.70.2.6  yamt      530:                            device_xname(self), device_xname(dev)),
1.23      thorpej   531:                            DEBUG_DETACH);
                    532:                        error = config_detach(dev, flags);
                    533:                        if (error)
                    534:                                goto out;
                    535:                }
                    536:        }
                    537:
                    538:  out:
1.47      thorpej   539: #ifdef ATADEBUG
1.23      thorpej   540:        if (dev != NULL && error != 0)
1.47      thorpej   541:                ATADEBUG_PRINT(("atabus_detach: %s: error %d detaching %s\n",
1.70.2.6  yamt      542:                    device_xname(self), error, device_xname(dev)),
1.23      thorpej   543:                    DEBUG_DETACH);
1.47      thorpej   544: #endif /* ATADEBUG */
1.23      thorpej   545:
                    546:        return (error);
                    547: }
                    548:
1.70.2.6  yamt      549: void
                    550: atabus_childdetached(device_t self, device_t child)
                    551: {
                    552:        struct atabus_softc *sc = device_private(self);
                    553:        struct ata_channel *chp = sc->sc_chan;
                    554:        int i;
                    555:
                    556:        /*
                    557:         * atapibus detached.
                    558:         */
                    559:        if (child == chp->atapibus) {
                    560:                chp->atapibus = NULL;
                    561:                return;
                    562:        }
                    563:
                    564:        /*
                    565:         * Detach our other children.
                    566:         */
                    567:        for (i = 0; i < chp->ch_ndrive; i++) {
                    568:                if (chp->ch_drive[i].drive_flags & DRIVE_ATAPI)
                    569:                        continue;
                    570:                if (child == chp->ch_drive[i].drv_softc) {
                    571:                        chp->ch_drive[i].drv_softc = NULL;
                    572:                        chp->ch_drive[i].drive_flags = 0;
                    573:                        return;
                    574:                }
                    575:        }
                    576:
                    577:        aprint_error_dev(self, "unknown child %p", (const void *)child);
                    578: }
                    579:
1.70.2.8! yamt      580: CFATTACH_DECL2_NEW(atabus, sizeof(struct atabus_softc),
1.70.2.6  yamt      581:     atabus_match, atabus_attach, atabus_detach, atabus_activate, NULL,
                    582:     atabus_childdetached);
1.23      thorpej   583:
                    584: /*****************************************************************************
                    585:  * Common ATA bus operations.
                    586:  *****************************************************************************/
                    587:
1.2       bouyer    588: /* Get the disk's parameters */
                    589: int
1.21      thorpej   590: ata_get_params(struct ata_drive_datas *drvp, u_int8_t flags,
                    591:     struct ataparams *prms)
1.2       bouyer    592: {
1.36      thorpej   593:        struct ata_command ata_c;
1.50      thorpej   594:        struct ata_channel *chp = drvp->chnl_softc;
                    595:        struct atac_softc *atac = chp->ch_atac;
1.70.2.6  yamt      596:        char *tb;
                    597:        int i, rv;
1.2       bouyer    598:        u_int16_t *p;
                    599:
1.70.2.4  yamt      600:        ATADEBUG_PRINT(("%s\n", __func__), DEBUG_FUNCS);
1.2       bouyer    601:
1.70.2.6  yamt      602:        tb = kmem_zalloc(DEV_BSIZE, KM_SLEEP);
1.2       bouyer    603:        memset(prms, 0, sizeof(struct ataparams));
1.36      thorpej   604:        memset(&ata_c, 0, sizeof(struct ata_command));
1.2       bouyer    605:
                    606:        if (drvp->drive_flags & DRIVE_ATA) {
1.36      thorpej   607:                ata_c.r_command = WDCC_IDENTIFY;
                    608:                ata_c.r_st_bmask = WDCS_DRDY;
1.70.2.1  yamt      609:                ata_c.r_st_pmask = WDCS_DRQ;
1.36      thorpej   610:                ata_c.timeout = 3000; /* 3s */
1.7       bouyer    611:        } else if (drvp->drive_flags & DRIVE_ATAPI) {
1.36      thorpej   612:                ata_c.r_command = ATAPI_IDENTIFY_DEVICE;
                    613:                ata_c.r_st_bmask = 0;
1.70.2.1  yamt      614:                ata_c.r_st_pmask = WDCS_DRQ;
1.36      thorpej   615:                ata_c.timeout = 10000; /* 10s */
1.7       bouyer    616:        } else {
1.47      thorpej   617:                ATADEBUG_PRINT(("ata_get_parms: no disks\n"),
1.10      bouyer    618:                    DEBUG_FUNCS|DEBUG_PROBE);
1.70.2.6  yamt      619:                rv = CMD_ERR;
                    620:                goto out;
1.2       bouyer    621:        }
1.36      thorpej   622:        ata_c.flags = AT_READ | flags;
                    623:        ata_c.data = tb;
                    624:        ata_c.bcount = DEV_BSIZE;
1.50      thorpej   625:        if ((*atac->atac_bustype_ata->ata_exec_command)(drvp,
                    626:                                                &ata_c) != ATACMD_COMPLETE) {
1.47      thorpej   627:                ATADEBUG_PRINT(("ata_get_parms: wdc_exec_command failed\n"),
1.10      bouyer    628:                    DEBUG_FUNCS|DEBUG_PROBE);
1.70.2.6  yamt      629:                rv = CMD_AGAIN;
                    630:                goto out;
1.10      bouyer    631:        }
1.36      thorpej   632:        if (ata_c.flags & (AT_ERROR | AT_TIMEOU | AT_DF)) {
1.47      thorpej   633:                ATADEBUG_PRINT(("ata_get_parms: ata_c.flags=0x%x\n",
1.36      thorpej   634:                    ata_c.flags), DEBUG_FUNCS|DEBUG_PROBE);
1.70.2.6  yamt      635:                rv = CMD_ERR;
                    636:                goto out;
1.70.2.4  yamt      637:        }
                    638:        /* if we didn't read any data something is wrong */
1.70.2.6  yamt      639:        if ((ata_c.flags & AT_XFDONE) == 0) {
                    640:                rv = CMD_ERR;
                    641:                goto out;
                    642:        }
1.70.2.2  yamt      643:
1.70.2.4  yamt      644:        /* Read in parameter block. */
                    645:        memcpy(prms, tb, sizeof(struct ataparams));
                    646:
                    647:        /*
                    648:         * Shuffle string byte order.
                    649:         * ATAPI NEC, Mitsumi and Pioneer drives and
                    650:         * old ATA TDK CompactFlash cards
                    651:         * have different byte order.
                    652:         */
1.70.2.2  yamt      653: #if BYTE_ORDER == BIG_ENDIAN
                    654: # define M(n)  prms->atap_model[(n) ^ 1]
                    655: #else
                    656: # define M(n)  prms->atap_model[n]
                    657: #endif
1.70.2.4  yamt      658:        if (
1.70.2.2  yamt      659: #if BYTE_ORDER == BIG_ENDIAN
1.70.2.4  yamt      660:            !
1.70.2.2  yamt      661: #endif
1.70.2.4  yamt      662:            ((drvp->drive_flags & DRIVE_ATAPI) ?
                    663:             ((M(0) == 'N' && M(1) == 'E') ||
                    664:              (M(0) == 'F' && M(1) == 'X') ||
                    665:              (M(0) == 'P' && M(1) == 'i')) :
1.70.2.6  yamt      666:             ((M(0) == 'T' && M(1) == 'D' && M(2) == 'K')))) {
                    667:                rv = CMD_OK;
                    668:                goto out;
                    669:             }
1.70.2.4  yamt      670: #undef M
                    671:        for (i = 0; i < sizeof(prms->atap_model); i += 2) {
                    672:                p = (u_int16_t *)(prms->atap_model + i);
                    673:                *p = bswap16(*p);
                    674:        }
                    675:        for (i = 0; i < sizeof(prms->atap_serial); i += 2) {
                    676:                p = (u_int16_t *)(prms->atap_serial + i);
                    677:                *p = bswap16(*p);
                    678:        }
                    679:        for (i = 0; i < sizeof(prms->atap_revision); i += 2) {
                    680:                p = (u_int16_t *)(prms->atap_revision + i);
                    681:                *p = bswap16(*p);
1.2       bouyer    682:        }
1.70.2.4  yamt      683:
1.70.2.6  yamt      684:        rv = CMD_OK;
                    685:  out:
                    686:        kmem_free(tb, DEV_BSIZE);
                    687:        return rv;
1.2       bouyer    688: }
                    689:
                    690: int
1.21      thorpej   691: ata_set_mode(struct ata_drive_datas *drvp, u_int8_t mode, u_int8_t flags)
1.2       bouyer    692: {
1.36      thorpej   693:        struct ata_command ata_c;
1.50      thorpej   694:        struct ata_channel *chp = drvp->chnl_softc;
                    695:        struct atac_softc *atac = chp->ch_atac;
1.2       bouyer    696:
1.47      thorpej   697:        ATADEBUG_PRINT(("ata_set_mode=0x%x\n", mode), DEBUG_FUNCS);
1.36      thorpej   698:        memset(&ata_c, 0, sizeof(struct ata_command));
1.2       bouyer    699:
1.36      thorpej   700:        ata_c.r_command = SET_FEATURES;
                    701:        ata_c.r_st_bmask = 0;
                    702:        ata_c.r_st_pmask = 0;
                    703:        ata_c.r_features = WDSF_SET_MODE;
                    704:        ata_c.r_count = mode;
                    705:        ata_c.flags = flags;
                    706:        ata_c.timeout = 1000; /* 1s */
1.50      thorpej   707:        if ((*atac->atac_bustype_ata->ata_exec_command)(drvp,
                    708:                                                &ata_c) != ATACMD_COMPLETE)
1.2       bouyer    709:                return CMD_AGAIN;
1.36      thorpej   710:        if (ata_c.flags & (AT_ERROR | AT_TIMEOU | AT_DF)) {
1.2       bouyer    711:                return CMD_ERR;
                    712:        }
                    713:        return CMD_OK;
1.11      bouyer    714: }
                    715:
1.70.2.2  yamt      716: #if NATA_DMA
1.11      bouyer    717: void
1.21      thorpej   718: ata_dmaerr(struct ata_drive_datas *drvp, int flags)
1.11      bouyer    719: {
                    720:        /*
                    721:         * Downgrade decision: if we get NERRS_MAX in NXFER.
                    722:         * We start with n_dmaerrs set to NERRS_MAX-1 so that the
                    723:         * first error within the first NXFER ops will immediatly trigger
                    724:         * a downgrade.
                    725:         * If we got an error and n_xfers is bigger than NXFER reset counters.
                    726:         */
                    727:        drvp->n_dmaerrs++;
                    728:        if (drvp->n_dmaerrs >= NERRS_MAX && drvp->n_xfers <= NXFER) {
1.39      thorpej   729:                ata_downgrade_mode(drvp, flags);
1.11      bouyer    730:                drvp->n_dmaerrs = NERRS_MAX-1;
                    731:                drvp->n_xfers = 0;
                    732:                return;
                    733:        }
                    734:        if (drvp->n_xfers > NXFER) {
                    735:                drvp->n_dmaerrs = 1; /* just got an error */
                    736:                drvp->n_xfers = 1; /* restart counting from this error */
1.4       bouyer    737:        }
1.2       bouyer    738: }
1.70.2.2  yamt      739: #endif /* NATA_DMA */
1.30      bouyer    740:
1.44      thorpej   741: /*
1.68      bouyer    742:  * freeze the queue and wait for the controller to be idle. Caller has to
                    743:  * unfreeze/restart the queue
                    744:  */
                    745: void
                    746: ata_queue_idle(struct ata_queue *queue)
                    747: {
                    748:        int s = splbio();
                    749:        queue->queue_freeze++;
                    750:        while (queue->active_xfer != NULL) {
                    751:                queue->queue_flags |= QF_IDLE_WAIT;
                    752:                tsleep(&queue->queue_flags, PRIBIO, "qidl", 0);
                    753:        }
                    754:        splx(s);
                    755: }
                    756:
                    757: /*
1.57      thorpej   758:  * Add a command to the queue and start controller.
                    759:  *
                    760:  * MUST BE CALLED AT splbio()!
1.44      thorpej   761:  */
                    762: void
1.48      thorpej   763: ata_exec_xfer(struct ata_channel *chp, struct ata_xfer *xfer)
1.44      thorpej   764: {
                    765:
1.47      thorpej   766:        ATADEBUG_PRINT(("ata_exec_xfer %p channel %d drive %d\n", xfer,
1.44      thorpej   767:            chp->ch_channel, xfer->c_drive), DEBUG_XFERS);
                    768:
                    769:        /* complete xfer setup */
                    770:        xfer->c_chp = chp;
                    771:
                    772:        /* insert at the end of command list */
                    773:        TAILQ_INSERT_TAIL(&chp->ch_queue->queue_xfer, xfer, c_xferchain);
1.47      thorpej   774:        ATADEBUG_PRINT(("atastart from ata_exec_xfer, flags 0x%x\n",
1.44      thorpej   775:            chp->ch_flags), DEBUG_XFERS);
1.62      bouyer    776:        /*
                    777:         * if polling and can sleep, wait for the xfer to be at head of queue
                    778:         */
                    779:        if ((xfer->c_flags & (C_POLL | C_WAIT)) ==  (C_POLL | C_WAIT)) {
                    780:                while (chp->ch_queue->active_xfer != NULL ||
                    781:                    TAILQ_FIRST(&chp->ch_queue->queue_xfer) != xfer) {
                    782:                        xfer->c_flags |= C_WAITACT;
                    783:                        tsleep(xfer, PRIBIO, "ataact", 0);
                    784:                        xfer->c_flags &= ~C_WAITACT;
                    785:                        if (xfer->c_flags & C_FREE) {
                    786:                                ata_free_xfer(chp, xfer);
                    787:                                return;
                    788:                        }
                    789:                }
                    790:        }
1.45      thorpej   791:        atastart(chp);
                    792: }
                    793:
                    794: /*
                    795:  * Start I/O on a controller, for the given channel.
                    796:  * The first xfer may be not for our channel if the channel queues
                    797:  * are shared.
1.57      thorpej   798:  *
                    799:  * MUST BE CALLED AT splbio()!
1.45      thorpej   800:  */
                    801: void
1.48      thorpej   802: atastart(struct ata_channel *chp)
1.45      thorpej   803: {
1.49      thorpej   804:        struct atac_softc *atac = chp->ch_atac;
1.45      thorpej   805:        struct ata_xfer *xfer;
                    806:
1.56      thorpej   807: #ifdef ATA_DEBUG
1.45      thorpej   808:        int spl1, spl2;
                    809:
                    810:        spl1 = splbio();
                    811:        spl2 = splbio();
                    812:        if (spl2 != spl1) {
                    813:                printf("atastart: not at splbio()\n");
                    814:                panic("atastart");
                    815:        }
                    816:        splx(spl2);
                    817:        splx(spl1);
1.56      thorpej   818: #endif /* ATA_DEBUG */
1.45      thorpej   819:
                    820:        /* is there a xfer ? */
                    821:        if ((xfer = TAILQ_FIRST(&chp->ch_queue->queue_xfer)) == NULL)
                    822:                return;
                    823:
                    824:        /* adjust chp, in case we have a shared queue */
                    825:        chp = xfer->c_chp;
                    826:
                    827:        if (chp->ch_queue->active_xfer != NULL) {
                    828:                return; /* channel aleady active */
                    829:        }
                    830:        if (__predict_false(chp->ch_queue->queue_freeze > 0)) {
1.68      bouyer    831:                if (chp->ch_queue->queue_flags & QF_IDLE_WAIT) {
                    832:                        chp->ch_queue->queue_flags &= ~QF_IDLE_WAIT;
                    833:                        wakeup(&chp->ch_queue->queue_flags);
                    834:                }
                    835:                return; /* queue frozen */
1.45      thorpej   836:        }
1.62      bouyer    837:        /*
                    838:         * if someone is waiting for the command to be active, wake it up
                    839:         * and let it process the command
                    840:         */
                    841:        if (xfer->c_flags & C_WAITACT) {
                    842:                ATADEBUG_PRINT(("atastart: xfer %p channel %d drive %d "
                    843:                    "wait active\n", xfer, chp->ch_channel, xfer->c_drive),
                    844:                    DEBUG_XFERS);
                    845:                wakeup(xfer);
                    846:                return;
                    847:        }
1.45      thorpej   848: #ifdef DIAGNOSTIC
1.48      thorpej   849:        if ((chp->ch_flags & ATACH_IRQ_WAIT) != 0)
1.45      thorpej   850:                panic("atastart: channel waiting for irq");
                    851: #endif
1.49      thorpej   852:        if (atac->atac_claim_hw)
                    853:                if (!(*atac->atac_claim_hw)(chp, 0))
1.45      thorpej   854:                        return;
                    855:
1.47      thorpej   856:        ATADEBUG_PRINT(("atastart: xfer %p channel %d drive %d\n", xfer,
1.45      thorpej   857:            chp->ch_channel, xfer->c_drive), DEBUG_XFERS);
                    858:        if (chp->ch_drive[xfer->c_drive].drive_flags & DRIVE_RESET) {
                    859:                chp->ch_drive[xfer->c_drive].drive_flags &= ~DRIVE_RESET;
                    860:                chp->ch_drive[xfer->c_drive].state = 0;
                    861:        }
                    862:        chp->ch_queue->active_xfer = xfer;
                    863:        TAILQ_REMOVE(&chp->ch_queue->queue_xfer, xfer, c_xferchain);
1.65      perry     864:
1.49      thorpej   865:        if (atac->atac_cap & ATAC_CAP_NOIRQ)
1.45      thorpej   866:                KASSERT(xfer->c_flags & C_POLL);
1.62      bouyer    867:
1.45      thorpej   868:        xfer->c_start(chp, xfer);
1.44      thorpej   869: }
                    870:
1.41      thorpej   871: struct ata_xfer *
                    872: ata_get_xfer(int flags)
                    873: {
                    874:        struct ata_xfer *xfer;
                    875:        int s;
                    876:
                    877:        s = splbio();
                    878:        xfer = pool_get(&ata_xfer_pool,
                    879:            ((flags & ATAXF_NOSLEEP) != 0 ? PR_NOWAIT : PR_WAITOK));
                    880:        splx(s);
                    881:        if (xfer != NULL) {
                    882:                memset(xfer, 0, sizeof(struct ata_xfer));
                    883:        }
                    884:        return xfer;
                    885: }
                    886:
                    887: void
1.48      thorpej   888: ata_free_xfer(struct ata_channel *chp, struct ata_xfer *xfer)
1.41      thorpej   889: {
1.49      thorpej   890:        struct atac_softc *atac = chp->ch_atac;
1.41      thorpej   891:        int s;
                    892:
1.62      bouyer    893:        if (xfer->c_flags & C_WAITACT) {
                    894:                /* Someone is waiting for this xfer, so we can't free now */
                    895:                xfer->c_flags |= C_FREE;
                    896:                wakeup(xfer);
                    897:                return;
                    898:        }
                    899:
1.70.2.2  yamt      900: #if NATA_PIOBM         /* XXX wdc dependent code */
                    901:        if (xfer->c_flags & C_PIOBM) {
                    902:                struct wdc_softc *wdc = CHAN_TO_WDC(chp);
                    903:
                    904:                /* finish the busmastering PIO */
                    905:                (*wdc->piobm_done)(wdc->dma_arg,
                    906:                    chp->ch_channel, xfer->c_drive);
                    907:                chp->ch_flags &= ~(ATACH_DMA_WAIT | ATACH_PIOBM_WAIT | ATACH_IRQ_WAIT);
                    908:        }
                    909: #endif
                    910:
1.49      thorpej   911:        if (atac->atac_free_hw)
                    912:                (*atac->atac_free_hw)(chp);
1.41      thorpej   913:        s = splbio();
                    914:        pool_put(&ata_xfer_pool, xfer);
                    915:        splx(s);
                    916: }
                    917:
1.42      thorpej   918: /*
1.48      thorpej   919:  * Kill off all pending xfers for a ata_channel.
1.42      thorpej   920:  *
                    921:  * Must be called at splbio().
                    922:  */
                    923: void
                    924: ata_kill_pending(struct ata_drive_datas *drvp)
                    925: {
1.48      thorpej   926:        struct ata_channel *chp = drvp->chnl_softc;
1.42      thorpej   927:        struct ata_xfer *xfer, *next_xfer;
                    928:        int s = splbio();
                    929:
                    930:        for (xfer = TAILQ_FIRST(&chp->ch_queue->queue_xfer);
                    931:            xfer != NULL; xfer = next_xfer) {
                    932:                next_xfer = TAILQ_NEXT(xfer, c_xferchain);
                    933:                if (xfer->c_chp != chp || xfer->c_drive != drvp->drive)
                    934:                        continue;
                    935:                TAILQ_REMOVE(&chp->ch_queue->queue_xfer, xfer, c_xferchain);
                    936:                (*xfer->c_kill_xfer)(chp, xfer, KILL_GONE);
                    937:        }
                    938:
                    939:        while ((xfer = chp->ch_queue->active_xfer) != NULL) {
                    940:                if (xfer->c_chp == chp && xfer->c_drive == drvp->drive) {
                    941:                        drvp->drive_flags |= DRIVE_WAITDRAIN;
                    942:                        (void) tsleep(&chp->ch_queue->active_xfer,
                    943:                            PRIBIO, "atdrn", 0);
                    944:                } else {
                    945:                        /* no more xfer for us */
                    946:                        break;
                    947:                }
                    948:        }
                    949:        splx(s);
                    950: }
                    951:
1.55      thorpej   952: /*
                    953:  * ata_reset_channel:
                    954:  *
                    955:  *     Reset and ATA channel.
1.57      thorpej   956:  *
                    957:  *     MUST BE CALLED AT splbio()!
1.55      thorpej   958:  */
                    959: void
                    960: ata_reset_channel(struct ata_channel *chp, int flags)
                    961: {
                    962:        struct atac_softc *atac = chp->ch_atac;
                    963:        int drive;
                    964:
1.57      thorpej   965: #ifdef ATA_DEBUG
                    966:        int spl1, spl2;
                    967:
                    968:        spl1 = splbio();
                    969:        spl2 = splbio();
                    970:        if (spl2 != spl1) {
                    971:                printf("ata_reset_channel: not at splbio()\n");
                    972:                panic("ata_reset_channel");
                    973:        }
                    974:        splx(spl2);
                    975:        splx(spl1);
                    976: #endif /* ATA_DEBUG */
                    977:
1.55      thorpej   978:        chp->ch_queue->queue_freeze++;
                    979:
                    980:        /*
                    981:         * If we can poll or wait it's OK, otherwise wake up the
                    982:         * kernel thread to do it for us.
                    983:         */
                    984:        if ((flags & (AT_POLL | AT_WAIT)) == 0) {
                    985:                if (chp->ch_flags & ATACH_TH_RESET) {
                    986:                        /* No need to schedule a reset more than one time. */
1.60      bouyer    987:                        chp->ch_queue->queue_freeze--;
1.55      thorpej   988:                        return;
                    989:                }
                    990:                chp->ch_flags |= ATACH_TH_RESET;
                    991:                chp->ch_reset_flags = flags & (AT_RST_EMERG | AT_RST_NOCMD);
                    992:                wakeup(&chp->ch_thread);
                    993:                return;
                    994:        }
                    995:
                    996:        (*atac->atac_bustype_ata->ata_reset_channel)(chp, flags);
                    997:
                    998:        for (drive = 0; drive < chp->ch_ndrive; drive++)
                    999:                chp->ch_drive[drive].state = 0;
                   1000:
                   1001:        chp->ch_flags &= ~ATACH_TH_RESET;
                   1002:        if ((flags & AT_RST_EMERG) == 0)  {
                   1003:                chp->ch_queue->queue_freeze--;
                   1004:                atastart(chp);
                   1005:        } else {
                   1006:                /* make sure that we can use polled commands */
                   1007:                TAILQ_INIT(&chp->ch_queue->queue_xfer);
                   1008:                chp->ch_queue->queue_freeze = 0;
                   1009:                chp->ch_queue->active_xfer = NULL;
                   1010:        }
                   1011: }
                   1012:
1.43      thorpej  1013: int
1.48      thorpej  1014: ata_addref(struct ata_channel *chp)
1.43      thorpej  1015: {
1.65      perry    1016:        struct atac_softc *atac = chp->ch_atac;
1.49      thorpej  1017:        struct scsipi_adapter *adapt = &atac->atac_atapi_adapter._generic;
1.43      thorpej  1018:        int s, error = 0;
                   1019:
                   1020:        s = splbio();
                   1021:        if (adapt->adapt_refcnt++ == 0 &&
                   1022:            adapt->adapt_enable != NULL) {
1.70.2.8! yamt     1023:                error = (*adapt->adapt_enable)(atac->atac_dev, 1);
1.43      thorpej  1024:                if (error)
                   1025:                        adapt->adapt_refcnt--;
                   1026:        }
                   1027:        splx(s);
                   1028:        return (error);
                   1029: }
                   1030:
                   1031: void
1.48      thorpej  1032: ata_delref(struct ata_channel *chp)
1.43      thorpej  1033: {
1.49      thorpej  1034:        struct atac_softc *atac = chp->ch_atac;
                   1035:        struct scsipi_adapter *adapt = &atac->atac_atapi_adapter._generic;
1.43      thorpej  1036:        int s;
                   1037:
                   1038:        s = splbio();
                   1039:        if (adapt->adapt_refcnt-- == 1 &&
                   1040:            adapt->adapt_enable != NULL)
1.70.2.8! yamt     1041:                (void) (*adapt->adapt_enable)(atac->atac_dev, 0);
1.43      thorpej  1042:        splx(s);
                   1043: }
                   1044:
1.38      thorpej  1045: void
1.48      thorpej  1046: ata_print_modes(struct ata_channel *chp)
1.38      thorpej  1047: {
1.49      thorpej  1048:        struct atac_softc *atac = chp->ch_atac;
1.38      thorpej  1049:        int drive;
                   1050:        struct ata_drive_datas *drvp;
                   1051:
1.67      matt     1052:        for (drive = 0; drive < chp->ch_ndrive; drive++) {
1.38      thorpej  1053:                drvp = &chp->ch_drive[drive];
1.67      matt     1054:                if ((drvp->drive_flags & DRIVE) == 0 || drvp->drv_softc == NULL)
1.38      thorpej  1055:                        continue;
1.70.2.3  yamt     1056:                aprint_verbose("%s(%s:%d:%d): using PIO mode %d",
1.70.2.6  yamt     1057:                        device_xname(drvp->drv_softc),
1.70.2.8! yamt     1058:                        device_xname(atac->atac_dev),
1.67      matt     1059:                        chp->ch_channel, drvp->drive, drvp->PIO_mode);
1.70.2.2  yamt     1060: #if NATA_DMA
1.38      thorpej  1061:                if (drvp->drive_flags & DRIVE_DMA)
1.70.2.3  yamt     1062:                        aprint_verbose(", DMA mode %d", drvp->DMA_mode);
1.70.2.2  yamt     1063: #if NATA_UDMA
1.38      thorpej  1064:                if (drvp->drive_flags & DRIVE_UDMA) {
1.70.2.3  yamt     1065:                        aprint_verbose(", Ultra-DMA mode %d", drvp->UDMA_mode);
1.38      thorpej  1066:                        if (drvp->UDMA_mode == 2)
1.70.2.3  yamt     1067:                                aprint_verbose(" (Ultra/33)");
1.38      thorpej  1068:                        else if (drvp->UDMA_mode == 4)
1.70.2.3  yamt     1069:                                aprint_verbose(" (Ultra/66)");
1.38      thorpej  1070:                        else if (drvp->UDMA_mode == 5)
1.70.2.3  yamt     1071:                                aprint_verbose(" (Ultra/100)");
1.38      thorpej  1072:                        else if (drvp->UDMA_mode == 6)
1.70.2.3  yamt     1073:                                aprint_verbose(" (Ultra/133)");
1.38      thorpej  1074:                }
1.70.2.2  yamt     1075: #endif /* NATA_UDMA */
                   1076: #endif /* NATA_DMA */
                   1077: #if NATA_DMA || NATA_PIOBM
                   1078:                if (0
                   1079: #if NATA_DMA
                   1080:                    || (drvp->drive_flags & (DRIVE_DMA | DRIVE_UDMA))
                   1081: #endif
                   1082: #if NATA_PIOBM
                   1083:                    /* PIOBM capable controllers use DMA for PIO commands */
                   1084:                    || (atac->atac_cap & ATAC_CAP_PIOBM)
                   1085: #endif
                   1086:                    )
1.70.2.3  yamt     1087:                        aprint_verbose(" (using DMA)");
1.70.2.2  yamt     1088: #endif /* NATA_DMA || NATA_PIOBM */
1.70.2.3  yamt     1089:                aprint_verbose("\n");
1.38      thorpej  1090:        }
                   1091: }
                   1092:
1.70.2.2  yamt     1093: #if NATA_DMA
1.39      thorpej  1094: /*
                   1095:  * downgrade the transfer mode of a drive after an error. return 1 if
                   1096:  * downgrade was possible, 0 otherwise.
1.57      thorpej  1097:  *
                   1098:  * MUST BE CALLED AT splbio()!
1.39      thorpej  1099:  */
                   1100: int
                   1101: ata_downgrade_mode(struct ata_drive_datas *drvp, int flags)
                   1102: {
1.48      thorpej  1103:        struct ata_channel *chp = drvp->chnl_softc;
1.49      thorpej  1104:        struct atac_softc *atac = chp->ch_atac;
1.70.2.6  yamt     1105:        device_t drv_dev = drvp->drv_softc;
1.70.2.1  yamt     1106:        int cf_flags = device_cfdata(drv_dev)->cf_flags;
1.39      thorpej  1107:
                   1108:        /* if drive or controller don't know its mode, we can't do much */
                   1109:        if ((drvp->drive_flags & DRIVE_MODE) == 0 ||
1.49      thorpej  1110:            (atac->atac_set_modes == NULL))
1.39      thorpej  1111:                return 0;
                   1112:        /* current drive mode was set by a config flag, let it this way */
                   1113:        if ((cf_flags & ATA_CONFIG_PIO_SET) ||
                   1114:            (cf_flags & ATA_CONFIG_DMA_SET) ||
                   1115:            (cf_flags & ATA_CONFIG_UDMA_SET))
                   1116:                return 0;
                   1117:
1.70.2.2  yamt     1118: #if NATA_UDMA
1.39      thorpej  1119:        /*
                   1120:         * If we were using Ultra-DMA mode, downgrade to the next lower mode.
                   1121:         */
                   1122:        if ((drvp->drive_flags & DRIVE_UDMA) && drvp->UDMA_mode >= 2) {
                   1123:                drvp->UDMA_mode--;
1.70.2.8! yamt     1124:                aprint_error_dev(drv_dev,
        !          1125:                    "transfer error, downgrading to Ultra-DMA mode %d\n",
        !          1126:                    drvp->UDMA_mode);
1.39      thorpej  1127:        }
1.70.2.2  yamt     1128: #endif
1.39      thorpej  1129:
                   1130:        /*
                   1131:         * If we were using ultra-DMA, don't downgrade to multiword DMA.
                   1132:         */
                   1133:        else if (drvp->drive_flags & (DRIVE_DMA | DRIVE_UDMA)) {
                   1134:                drvp->drive_flags &= ~(DRIVE_DMA | DRIVE_UDMA);
                   1135:                drvp->PIO_mode = drvp->PIO_cap;
1.70.2.8! yamt     1136:                aprint_error_dev(drv_dev,
        !          1137:                    "transfer error, downgrading to PIO mode %d\n",
        !          1138:                    drvp->PIO_mode);
1.39      thorpej  1139:        } else /* already using PIO, can't downgrade */
                   1140:                return 0;
                   1141:
1.49      thorpej  1142:        (*atac->atac_set_modes)(chp);
1.39      thorpej  1143:        ata_print_modes(chp);
1.70.2.2  yamt     1144:        /* reset the channel, which will schedule all drives for setup */
1.55      thorpej  1145:        ata_reset_channel(chp, flags | AT_RST_NOCMD);
1.39      thorpej  1146:        return 1;
                   1147: }
1.70.2.2  yamt     1148: #endif /* NATA_DMA */
1.39      thorpej  1149:
1.40      thorpej  1150: /*
                   1151:  * Probe drive's capabilities, for use by the controller later
1.65      perry    1152:  * Assumes drvp points to an existing drive.
1.40      thorpej  1153:  */
                   1154: void
                   1155: ata_probe_caps(struct ata_drive_datas *drvp)
                   1156: {
                   1157:        struct ataparams params, params2;
1.48      thorpej  1158:        struct ata_channel *chp = drvp->chnl_softc;
1.49      thorpej  1159:        struct atac_softc *atac = chp->ch_atac;
1.70.2.6  yamt     1160:        device_t drv_dev = drvp->drv_softc;
1.58      thorpej  1161:        int i, printed, s;
1.70      christos 1162:        const char *sep = "";
1.40      thorpej  1163:        int cf_flags;
                   1164:
                   1165:        if (ata_get_params(drvp, AT_WAIT, &params) != CMD_OK) {
                   1166:                /* IDENTIFY failed. Can't tell more about the device */
                   1167:                return;
                   1168:        }
1.49      thorpej  1169:        if ((atac->atac_cap & (ATAC_CAP_DATA16 | ATAC_CAP_DATA32)) ==
                   1170:            (ATAC_CAP_DATA16 | ATAC_CAP_DATA32)) {
1.40      thorpej  1171:                /*
                   1172:                 * Controller claims 16 and 32 bit transfers.
                   1173:                 * Re-do an IDENTIFY with 32-bit transfers,
                   1174:                 * and compare results.
                   1175:                 */
1.58      thorpej  1176:                s = splbio();
1.40      thorpej  1177:                drvp->drive_flags |= DRIVE_CAP32;
1.58      thorpej  1178:                splx(s);
1.40      thorpej  1179:                ata_get_params(drvp, AT_WAIT, &params2);
                   1180:                if (memcmp(&params, &params2, sizeof(struct ataparams)) != 0) {
                   1181:                        /* Not good. fall back to 16bits */
1.58      thorpej  1182:                        s = splbio();
1.40      thorpej  1183:                        drvp->drive_flags &= ~DRIVE_CAP32;
1.58      thorpej  1184:                        splx(s);
1.40      thorpej  1185:                } else {
1.70.2.8! yamt     1186:                        aprint_verbose_dev(drv_dev, "32-bit data port\n");
1.40      thorpej  1187:                }
                   1188:        }
                   1189: #if 0 /* Some ultra-DMA drives claims to only support ATA-3. sigh */
1.65      perry    1190:        if (params.atap_ata_major > 0x01 &&
1.40      thorpej  1191:            params.atap_ata_major != 0xffff) {
                   1192:                for (i = 14; i > 0; i--) {
                   1193:                        if (params.atap_ata_major & (1 << i)) {
1.70.2.8! yamt     1194:                                aprint_verbose_dev(drv_dev,
        !          1195:                                    "ATA version %d\n", i);
1.40      thorpej  1196:                                drvp->ata_vers = i;
                   1197:                                break;
                   1198:                        }
                   1199:                }
                   1200:        }
                   1201: #endif
                   1202:
                   1203:        /* An ATAPI device is at last PIO mode 3 */
                   1204:        if (drvp->drive_flags & DRIVE_ATAPI)
                   1205:                drvp->PIO_mode = 3;
                   1206:
                   1207:        /*
1.65      perry    1208:         * It's not in the specs, but it seems that some drive
1.40      thorpej  1209:         * returns 0xffff in atap_extensions when this field is invalid
                   1210:         */
                   1211:        if (params.atap_extensions != 0xffff &&
                   1212:            (params.atap_extensions & WDC_EXT_MODES)) {
                   1213:                printed = 0;
                   1214:                /*
                   1215:                 * XXX some drives report something wrong here (they claim to
                   1216:                 * support PIO mode 8 !). As mode is coded on 3 bits in
                   1217:                 * SET FEATURE, limit it to 7 (so limit i to 4).
                   1218:                 * If higher mode than 7 is found, abort.
                   1219:                 */
                   1220:                for (i = 7; i >= 0; i--) {
                   1221:                        if ((params.atap_piomode_supp & (1 << i)) == 0)
                   1222:                                continue;
                   1223:                        if (i > 4)
                   1224:                                return;
                   1225:                        /*
                   1226:                         * See if mode is accepted.
                   1227:                         * If the controller can't set its PIO mode,
                   1228:                         * assume the defaults are good, so don't try
                   1229:                         * to set it
                   1230:                         */
1.49      thorpej  1231:                        if (atac->atac_set_modes)
1.40      thorpej  1232:                                /*
                   1233:                                 * It's OK to pool here, it's fast enouth
                   1234:                                 * to not bother waiting for interrupt
                   1235:                                 */
                   1236:                                if (ata_set_mode(drvp, 0x08 | (i + 3),
                   1237:                                   AT_WAIT) != CMD_OK)
                   1238:                                        continue;
1.65      perry    1239:                        if (!printed) {
1.70.2.8! yamt     1240:                                aprint_verbose_dev(drv_dev,
        !          1241:                                    "drive supports PIO mode %d", i + 3);
1.40      thorpej  1242:                                sep = ",";
                   1243:                                printed = 1;
                   1244:                        }
                   1245:                        /*
                   1246:                         * If controller's driver can't set its PIO mode,
                   1247:                         * get the highter one for the drive.
                   1248:                         */
1.49      thorpej  1249:                        if (atac->atac_set_modes == NULL ||
                   1250:                            atac->atac_pio_cap >= i + 3) {
1.40      thorpej  1251:                                drvp->PIO_mode = i + 3;
                   1252:                                drvp->PIO_cap = i + 3;
                   1253:                                break;
                   1254:                        }
                   1255:                }
                   1256:                if (!printed) {
1.65      perry    1257:                        /*
1.40      thorpej  1258:                         * We didn't find a valid PIO mode.
                   1259:                         * Assume the values returned for DMA are buggy too
                   1260:                         */
                   1261:                        return;
                   1262:                }
1.58      thorpej  1263:                s = splbio();
1.40      thorpej  1264:                drvp->drive_flags |= DRIVE_MODE;
1.58      thorpej  1265:                splx(s);
1.40      thorpej  1266:                printed = 0;
                   1267:                for (i = 7; i >= 0; i--) {
                   1268:                        if ((params.atap_dmamode_supp & (1 << i)) == 0)
                   1269:                                continue;
1.70.2.2  yamt     1270: #if NATA_DMA
1.49      thorpej  1271:                        if ((atac->atac_cap & ATAC_CAP_DMA) &&
                   1272:                            atac->atac_set_modes != NULL)
1.40      thorpej  1273:                                if (ata_set_mode(drvp, 0x20 | i, AT_WAIT)
                   1274:                                    != CMD_OK)
                   1275:                                        continue;
1.70.2.2  yamt     1276: #endif
1.40      thorpej  1277:                        if (!printed) {
1.70.2.3  yamt     1278:                                aprint_verbose("%s DMA mode %d", sep, i);
1.40      thorpej  1279:                                sep = ",";
                   1280:                                printed = 1;
                   1281:                        }
1.70.2.2  yamt     1282: #if NATA_DMA
1.49      thorpej  1283:                        if (atac->atac_cap & ATAC_CAP_DMA) {
                   1284:                                if (atac->atac_set_modes != NULL &&
                   1285:                                    atac->atac_dma_cap < i)
1.40      thorpej  1286:                                        continue;
                   1287:                                drvp->DMA_mode = i;
                   1288:                                drvp->DMA_cap = i;
1.58      thorpej  1289:                                s = splbio();
1.40      thorpej  1290:                                drvp->drive_flags |= DRIVE_DMA;
1.58      thorpej  1291:                                splx(s);
1.40      thorpej  1292:                        }
1.70.2.2  yamt     1293: #endif
1.40      thorpej  1294:                        break;
                   1295:                }
                   1296:                if (params.atap_extensions & WDC_EXT_UDMA_MODES) {
                   1297:                        printed = 0;
                   1298:                        for (i = 7; i >= 0; i--) {
                   1299:                                if ((params.atap_udmamode_supp & (1 << i))
                   1300:                                    == 0)
                   1301:                                        continue;
1.70.2.2  yamt     1302: #if NATA_UDMA
1.49      thorpej  1303:                                if (atac->atac_set_modes != NULL &&
                   1304:                                    (atac->atac_cap & ATAC_CAP_UDMA))
1.40      thorpej  1305:                                        if (ata_set_mode(drvp, 0x40 | i,
                   1306:                                            AT_WAIT) != CMD_OK)
                   1307:                                                continue;
1.70.2.2  yamt     1308: #endif
1.40      thorpej  1309:                                if (!printed) {
1.70.2.3  yamt     1310:                                        aprint_verbose("%s Ultra-DMA mode %d",
1.40      thorpej  1311:                                            sep, i);
                   1312:                                        if (i == 2)
1.70.2.3  yamt     1313:                                                aprint_verbose(" (Ultra/33)");
1.40      thorpej  1314:                                        else if (i == 4)
1.70.2.3  yamt     1315:                                                aprint_verbose(" (Ultra/66)");
1.40      thorpej  1316:                                        else if (i == 5)
1.70.2.3  yamt     1317:                                                aprint_verbose(" (Ultra/100)");
1.40      thorpej  1318:                                        else if (i == 6)
1.70.2.3  yamt     1319:                                                aprint_verbose(" (Ultra/133)");
1.40      thorpej  1320:                                        sep = ",";
                   1321:                                        printed = 1;
                   1322:                                }
1.70.2.2  yamt     1323: #if NATA_UDMA
1.49      thorpej  1324:                                if (atac->atac_cap & ATAC_CAP_UDMA) {
                   1325:                                        if (atac->atac_set_modes != NULL &&
                   1326:                                            atac->atac_udma_cap < i)
1.40      thorpej  1327:                                                continue;
                   1328:                                        drvp->UDMA_mode = i;
                   1329:                                        drvp->UDMA_cap = i;
1.58      thorpej  1330:                                        s = splbio();
1.40      thorpej  1331:                                        drvp->drive_flags |= DRIVE_UDMA;
1.58      thorpej  1332:                                        splx(s);
1.40      thorpej  1333:                                }
1.70.2.2  yamt     1334: #endif
1.40      thorpej  1335:                                break;
                   1336:                        }
                   1337:                }
1.70.2.3  yamt     1338:                aprint_verbose("\n");
1.40      thorpej  1339:        }
                   1340:
1.58      thorpej  1341:        s = splbio();
1.40      thorpej  1342:        drvp->drive_flags &= ~DRIVE_NOSTREAM;
                   1343:        if (drvp->drive_flags & DRIVE_ATAPI) {
1.65      perry    1344:                if (atac->atac_cap & ATAC_CAP_ATAPI_NOSTREAM)
1.40      thorpej  1345:                        drvp->drive_flags |= DRIVE_NOSTREAM;
                   1346:        } else {
1.65      perry    1347:                if (atac->atac_cap & ATAC_CAP_ATA_NOSTREAM)
1.40      thorpej  1348:                        drvp->drive_flags |= DRIVE_NOSTREAM;
                   1349:        }
1.58      thorpej  1350:        splx(s);
1.40      thorpej  1351:
                   1352:        /* Try to guess ATA version here, if it didn't get reported */
                   1353:        if (drvp->ata_vers == 0) {
1.70.2.2  yamt     1354: #if NATA_UDMA
1.40      thorpej  1355:                if (drvp->drive_flags & DRIVE_UDMA)
                   1356:                        drvp->ata_vers = 4; /* should be at last ATA-4 */
1.70.2.2  yamt     1357:                else
                   1358: #endif
                   1359:                if (drvp->PIO_cap > 2)
1.40      thorpej  1360:                        drvp->ata_vers = 2; /* should be at last ATA-2 */
                   1361:        }
1.70.2.1  yamt     1362:        cf_flags = device_cfdata(drv_dev)->cf_flags;
1.40      thorpej  1363:        if (cf_flags & ATA_CONFIG_PIO_SET) {
1.58      thorpej  1364:                s = splbio();
1.40      thorpej  1365:                drvp->PIO_mode =
                   1366:                    (cf_flags & ATA_CONFIG_PIO_MODES) >> ATA_CONFIG_PIO_OFF;
                   1367:                drvp->drive_flags |= DRIVE_MODE;
1.58      thorpej  1368:                splx(s);
1.40      thorpej  1369:        }
1.70.2.2  yamt     1370: #if NATA_DMA
1.49      thorpej  1371:        if ((atac->atac_cap & ATAC_CAP_DMA) == 0) {
1.40      thorpej  1372:                /* don't care about DMA modes */
                   1373:                return;
                   1374:        }
                   1375:        if (cf_flags & ATA_CONFIG_DMA_SET) {
1.58      thorpej  1376:                s = splbio();
1.40      thorpej  1377:                if ((cf_flags & ATA_CONFIG_DMA_MODES) ==
                   1378:                    ATA_CONFIG_DMA_DISABLE) {
                   1379:                        drvp->drive_flags &= ~DRIVE_DMA;
                   1380:                } else {
                   1381:                        drvp->DMA_mode = (cf_flags & ATA_CONFIG_DMA_MODES) >>
                   1382:                            ATA_CONFIG_DMA_OFF;
                   1383:                        drvp->drive_flags |= DRIVE_DMA | DRIVE_MODE;
                   1384:                }
1.58      thorpej  1385:                splx(s);
1.40      thorpej  1386:        }
1.70.2.2  yamt     1387: #if NATA_UDMA
1.49      thorpej  1388:        if ((atac->atac_cap & ATAC_CAP_UDMA) == 0) {
1.40      thorpej  1389:                /* don't care about UDMA modes */
                   1390:                return;
                   1391:        }
                   1392:        if (cf_flags & ATA_CONFIG_UDMA_SET) {
1.58      thorpej  1393:                s = splbio();
1.40      thorpej  1394:                if ((cf_flags & ATA_CONFIG_UDMA_MODES) ==
                   1395:                    ATA_CONFIG_UDMA_DISABLE) {
                   1396:                        drvp->drive_flags &= ~DRIVE_UDMA;
                   1397:                } else {
                   1398:                        drvp->UDMA_mode = (cf_flags & ATA_CONFIG_UDMA_MODES) >>
                   1399:                            ATA_CONFIG_UDMA_OFF;
                   1400:                        drvp->drive_flags |= DRIVE_UDMA | DRIVE_MODE;
                   1401:                }
1.58      thorpej  1402:                splx(s);
1.40      thorpej  1403:        }
1.70.2.2  yamt     1404: #endif /* NATA_UDMA */
                   1405: #endif /* NATA_DMA */
1.40      thorpej  1406: }
                   1407:
1.30      bouyer   1408: /* management of the /dev/atabus* devices */
1.54      thorpej  1409: int
1.70.2.2  yamt     1410: atabusopen(dev_t dev, int flag, int fmt,
                   1411:     struct lwp *l)
1.30      bouyer   1412: {
1.70.2.2  yamt     1413:        struct atabus_softc *sc;
                   1414:        int error, unit = minor(dev);
1.65      perry    1415:
1.70.2.2  yamt     1416:        if (unit >= atabus_cd.cd_ndevs ||
1.70.2.8! yamt     1417:            (sc = device_private(atabus_cd.cd_devs[unit])) == NULL)
1.70.2.2  yamt     1418:                return (ENXIO);
1.65      perry    1419:
1.70.2.2  yamt     1420:        if (sc->sc_flags & ATABUSCF_OPEN)
                   1421:                return (EBUSY);
1.30      bouyer   1422:
1.70.2.2  yamt     1423:        if ((error = ata_addref(sc->sc_chan)) != 0)
                   1424:                return (error);
1.30      bouyer   1425:
1.70.2.2  yamt     1426:        sc->sc_flags |= ATABUSCF_OPEN;
1.30      bouyer   1427:
1.70.2.2  yamt     1428:        return (0);
1.30      bouyer   1429: }
                   1430:
                   1431:
                   1432: int
1.70.2.2  yamt     1433: atabusclose(dev_t dev, int flag, int fmt,
                   1434:     struct lwp *l)
1.30      bouyer   1435: {
1.70.2.8! yamt     1436:        struct atabus_softc *sc =
        !          1437:            device_private(atabus_cd.cd_devs[minor(dev)]);
1.30      bouyer   1438:
1.70.2.2  yamt     1439:        ata_delref(sc->sc_chan);
1.30      bouyer   1440:
1.70.2.2  yamt     1441:        sc->sc_flags &= ~ATABUSCF_OPEN;
1.30      bouyer   1442:
1.70.2.2  yamt     1443:        return (0);
1.30      bouyer   1444: }
                   1445:
                   1446: int
1.70.2.4  yamt     1447: atabusioctl(dev_t dev, u_long cmd, void *addr, int flag,
1.70.2.2  yamt     1448:     struct lwp *l)
1.30      bouyer   1449: {
1.70.2.8! yamt     1450:        struct atabus_softc *sc =
        !          1451:            device_private(atabus_cd.cd_devs[minor(dev)]);
1.48      thorpej  1452:        struct ata_channel *chp = sc->sc_chan;
1.32      bouyer   1453:        int min_drive, max_drive, drive;
1.70.2.2  yamt     1454:        int error;
1.30      bouyer   1455:        int s;
                   1456:
1.70.2.2  yamt     1457:        /*
                   1458:         * Enforce write permission for ioctls that change the
                   1459:         * state of the bus.  Host adapter specific ioctls must
                   1460:         * be checked by the adapter driver.
                   1461:         */
                   1462:        switch (cmd) {
                   1463:        case ATABUSIOSCAN:
                   1464:        case ATABUSIODETACH:
                   1465:        case ATABUSIORESET:
                   1466:                if ((flag & FWRITE) == 0)
                   1467:                        return (EBADF);
                   1468:        }
1.30      bouyer   1469:
1.70.2.2  yamt     1470:        switch (cmd) {
                   1471:        case ATABUSIORESET:
1.30      bouyer   1472:                s = splbio();
1.55      thorpej  1473:                ata_reset_channel(sc->sc_chan, AT_WAIT | AT_POLL);
1.30      bouyer   1474:                splx(s);
                   1475:                error = 0;
                   1476:                break;
1.32      bouyer   1477:        case ATABUSIOSCAN:
                   1478:        {
                   1479: #if 0
                   1480:                struct atabusioscan_args *a=
                   1481:                    (struct atabusioscan_args *)addr;
                   1482: #endif
                   1483:                if ((chp->ch_drive[0].drive_flags & DRIVE_OLD) ||
                   1484:                    (chp->ch_drive[1].drive_flags & DRIVE_OLD))
                   1485:                        return (EOPNOTSUPP);
                   1486:                return (EOPNOTSUPP);
                   1487:        }
                   1488:        case ATABUSIODETACH:
                   1489:        {
                   1490:                struct atabusioscan_args *a=
                   1491:                    (struct atabusioscan_args *)addr;
                   1492:                if ((chp->ch_drive[0].drive_flags & DRIVE_OLD) ||
                   1493:                    (chp->ch_drive[1].drive_flags & DRIVE_OLD))
                   1494:                        return (EOPNOTSUPP);
                   1495:                switch (a->at_dev) {
                   1496:                case -1:
                   1497:                        min_drive = 0;
                   1498:                        max_drive = 1;
                   1499:                        break;
                   1500:                case 0:
                   1501:                case 1:
                   1502:                        min_drive = max_drive = a->at_dev;
                   1503:                        break;
                   1504:                default:
                   1505:                        return (EINVAL);
                   1506:                }
                   1507:                for (drive = min_drive; drive <= max_drive; drive++) {
                   1508:                        if (chp->ch_drive[drive].drv_softc != NULL) {
                   1509:                                error = config_detach(
                   1510:                                    chp->ch_drive[drive].drv_softc, 0);
                   1511:                                if (error)
                   1512:                                        return (error);
1.70.2.6  yamt     1513:                                KASSERT(chp->ch_drive[drive].drv_softc == NULL);
1.32      bouyer   1514:                        }
                   1515:                }
                   1516:                error = 0;
                   1517:                break;
                   1518:        }
1.30      bouyer   1519:        default:
                   1520:                error = ENOTTY;
                   1521:        }
                   1522:        return (error);
                   1523: };
1.64      jmcneill 1524:
1.70.2.6  yamt     1525: static bool
1.70.2.7  yamt     1526: atabus_suspend(device_t dv PMF_FN_ARGS)
1.70.2.6  yamt     1527: {
                   1528:        struct atabus_softc *sc = device_private(dv);
                   1529:        struct ata_channel *chp = sc->sc_chan;
                   1530:
                   1531:        ata_queue_idle(chp->ch_queue);
                   1532:
                   1533:        return true;
                   1534: }
                   1535:
                   1536: static bool
1.70.2.7  yamt     1537: atabus_resume(device_t dv PMF_FN_ARGS)
1.64      jmcneill 1538: {
1.70.2.6  yamt     1539:        struct atabus_softc *sc = device_private(dv);
1.64      jmcneill 1540:        struct ata_channel *chp = sc->sc_chan;
                   1541:        int s;
                   1542:
1.70.2.6  yamt     1543:        /*
                   1544:         * XXX joerg: with wdc, the first channel unfreezes the controler.
                   1545:         * Move this the reset and queue idling into wdc.
                   1546:         */
                   1547:        s = splbio();
                   1548:        if (chp->ch_queue->queue_freeze == 0) {
1.64      jmcneill 1549:                splx(s);
1.70.2.6  yamt     1550:                return true;
1.64      jmcneill 1551:        }
1.70.2.6  yamt     1552:        KASSERT(chp->ch_queue->queue_freeze > 0);
                   1553:        /* unfreeze the queue and reset drives */
                   1554:        chp->ch_queue->queue_freeze--;
                   1555:        ata_reset_channel(chp, AT_WAIT);
                   1556:        splx(s);
1.64      jmcneill 1557:
1.70.2.6  yamt     1558:        return true;
1.64      jmcneill 1559: }

CVSweb <webmaster@jp.NetBSD.org>