ata-all.c revision 149594
11573Srgrimes/*-
21573Srgrimes * Copyright (c) 1998 - 2005 S�ren Schmidt <sos@FreeBSD.org>
31573Srgrimes * All rights reserved.
41573Srgrimes *
51573Srgrimes * Redistribution and use in source and binary forms, with or without
61573Srgrimes * modification, are permitted provided that the following conditions
71573Srgrimes * are met:
81573Srgrimes * 1. Redistributions of source code must retain the above copyright
91573Srgrimes *    notice, this list of conditions and the following disclaimer,
101573Srgrimes *    without modification, immediately at the beginning of the file.
111573Srgrimes * 2. Redistributions in binary form must reproduce the above copyright
121573Srgrimes *    notice, this list of conditions and the following disclaimer in the
131573Srgrimes *    documentation and/or other materials provided with the distribution.
141573Srgrimes * 3. The name of the author may not be used to endorse or promote products
151573Srgrimes *    derived from this software without specific prior written permission.
161573Srgrimes *
171573Srgrimes * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
181573Srgrimes * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
191573Srgrimes * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
201573Srgrimes * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
211573Srgrimes * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
221573Srgrimes * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
231573Srgrimes * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
241573Srgrimes * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
251573Srgrimes * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
261573Srgrimes * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
271573Srgrimes */
281573Srgrimes
291573Srgrimes#include <sys/cdefs.h>
301573Srgrimes__FBSDID("$FreeBSD: head/sys/dev/ata/ata-all.c 149594 2005-08-29 18:19:06Z sos $");
311573Srgrimes
321573Srgrimes#include "opt_ata.h"
331573Srgrimes#include <sys/param.h>
341573Srgrimes#include <sys/systm.h>
351573Srgrimes#include <sys/ata.h>
361573Srgrimes#include <sys/kernel.h>
371573Srgrimes#include <sys/module.h>
3862232Sdcs#include <sys/endian.h>
3962232Sdcs#include <sys/ctype.h>
401573Srgrimes#include <sys/conf.h>
411573Srgrimes#include <sys/bus.h>
421573Srgrimes#include <sys/bio.h>
431573Srgrimes#include <sys/malloc.h>
441573Srgrimes#include <sys/sysctl.h>
451573Srgrimes#include <sys/sema.h>
461573Srgrimes#include <sys/taskqueue.h>
471573Srgrimes#include <vm/uma.h>
481573Srgrimes#include <machine/stdarg.h>
491573Srgrimes#include <machine/resource.h>
501573Srgrimes#include <machine/bus.h>
511573Srgrimes#include <sys/rman.h>
521573Srgrimes#ifdef __alpha__
531573Srgrimes#include <machine/md_var.h>
5419277Sache#endif
5519277Sache#include <dev/ata/ata-all.h>
561573Srgrimes#include <ata_if.h>
571573Srgrimes
581573Srgrimes/* device structure */
591573Srgrimesstatic  d_ioctl_t       ata_ioctl;
601573Srgrimesstatic struct cdevsw ata_cdevsw = {
611573Srgrimes	.d_version =    D_VERSION,
621573Srgrimes	.d_flags =      D_NEEDGIANT, /* we need this as newbus isn't mpsafe */
631573Srgrimes	.d_ioctl =      ata_ioctl,
641573Srgrimes	.d_name =       "ata",
651573Srgrimes};
661573Srgrimes
671573Srgrimes/* prototypes */
681573Srgrimesstatic void ata_interrupt(void *);
691573Srgrimesstatic void ata_boot_attach(void);
701573Srgrimesstatic device_t ata_add_child(device_t, struct ata_device *, int);
711573Srgrimesstatic void bswap(int8_t *, int);
721573Srgrimesstatic void btrim(int8_t *, int);
731573Srgrimesstatic void bpack(int8_t *, int8_t *, int);
741573Srgrimes
751573Srgrimes/* global vars */
761573SrgrimesMALLOC_DEFINE(M_ATA, "ATA generic", "ATA driver generic layer");
771573Srgrimesint (*ata_raid_ioctl_func)(u_long cmd, caddr_t data) = NULL;
781573Srgrimesdevclass_t ata_devclass;
791573Srgrimesuma_zone_t ata_request_zone;
801573Srgrimesuma_zone_t ata_composite_zone;
811573Srgrimesint ata_wc = 1;
821573Srgrimes
831573Srgrimes/* local vars */
841573Srgrimesstatic struct intr_config_hook *ata_delayed_attach = NULL;
851573Srgrimesstatic int ata_dma = 1;
8692905Sobrienstatic int atapi_dma = 1;
8792905Sobrien
8892905Sobrien/* sysctl vars */
8992905SobrienSYSCTL_NODE(_hw, OID_AUTO, ata, CTLFLAG_RD, 0, "ATA driver parameters");
9092905SobrienTUNABLE_INT("hw.ata.ata_dma", &ata_dma);
9192905SobrienSYSCTL_INT(_hw_ata, OID_AUTO, ata_dma, CTLFLAG_RDTUN, &ata_dma, 0,
9292905Sobrien	   "ATA disk DMA mode control");
9392905SobrienTUNABLE_INT("hw.ata.atapi_dma", &atapi_dma);
9492905SobrienSYSCTL_INT(_hw_ata, OID_AUTO, atapi_dma, CTLFLAG_RDTUN, &atapi_dma, 0,
9592905Sobrien	   "ATAPI device DMA mode control");
9692905SobrienTUNABLE_INT("hw.ata.wc", &ata_wc);
9792905SobrienSYSCTL_INT(_hw_ata, OID_AUTO, wc, CTLFLAG_RDTUN, &ata_wc, 0,
9892905Sobrien	   "ATA disk write caching");
9992905Sobrien
10092905Sobrien/*
10192905Sobrien * newbus device interface related functions
10292905Sobrien */
10392905Sobrienint
10492905Sobrienata_probe(device_t dev)
10592905Sobrien{
10692905Sobrien    return 0;
10792905Sobrien}
10892905Sobrien
10992905Sobrienint
11017141Sjkhata_attach(device_t dev)
11192905Sobrien{
11292905Sobrien    struct ata_channel *ch = device_get_softc(dev);
11392905Sobrien    int error, rid;
11417141Sjkh
11592905Sobrien    /* check that we have a virgin channel to attach */
11692905Sobrien    if (ch->r_irq)
11792905Sobrien	return EEXIST;
11892905Sobrien
11992905Sobrien    /* initialize the softc basics */
12092905Sobrien    ch->dev = dev;
12192905Sobrien    ch->state = ATA_IDLE;
12292905Sobrien    bzero(&ch->state_mtx, sizeof(struct mtx));
12392905Sobrien    mtx_init(&ch->state_mtx, "ATA state lock", NULL, MTX_DEF);
12492905Sobrien    bzero(&ch->queue_mtx, sizeof(struct mtx));
12592905Sobrien    mtx_init(&ch->queue_mtx, "ATA queue lock", NULL, MTX_DEF);
12692905Sobrien    TAILQ_INIT(&ch->ata_queue);
12792905Sobrien
12892905Sobrien    /* reset the controller HW, the channel and device(s) */
12992905Sobrien    while (ATA_LOCKING(dev, ATA_LF_LOCK) != ch->unit)
13092905Sobrien	tsleep(&error, PRIBIO, "ataatch", 1);
1311573Srgrimes    ATA_RESET(dev);
1321573Srgrimes    ATA_LOCKING(dev, ATA_LF_UNLOCK);
1331573Srgrimes
1341573Srgrimes    /* setup interrupt delivery */
1351573Srgrimes    rid = ATA_IRQ_RID;
1361573Srgrimes    ch->r_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
1371573Srgrimes				       RF_SHAREABLE | RF_ACTIVE);
1381573Srgrimes    if (!ch->r_irq) {
1391573Srgrimes	device_printf(dev, "unable to allocate interrupt\n");
1401573Srgrimes	return ENXIO;
1411573Srgrimes    }
1421573Srgrimes    if ((error = bus_setup_intr(dev, ch->r_irq, ATA_INTR_FLAGS,
1431573Srgrimes				ata_interrupt, ch, &ch->ih))) {
1441573Srgrimes	device_printf(dev, "unable to setup interrupt\n");
1451573Srgrimes	return error;
1461573Srgrimes    }
1471573Srgrimes
1481573Srgrimes    /* probe and attach devices on this channel unless we are in early boot */
1491573Srgrimes    if (!ata_delayed_attach)
1501573Srgrimes	ata_identify(dev);
1511573Srgrimes    return 0;
1521573Srgrimes}
1531573Srgrimes
1541573Srgrimesint
1551573Srgrimesata_detach(device_t dev)
1561573Srgrimes{
1571573Srgrimes    struct ata_channel *ch = device_get_softc(dev);
1581573Srgrimes    device_t *children;
1591573Srgrimes    int nchildren, i;
1601573Srgrimes
1611573Srgrimes    /* check that we have a vaild channel to detach */
1621573Srgrimes    if (!ch->r_irq)
1631573Srgrimes	return ENXIO;
1641573Srgrimes
1651573Srgrimes    /* detach & delete all children */
1661573Srgrimes    if (!device_get_children(dev, &children, &nchildren)) {
1671573Srgrimes	for (i = 0; i < nchildren; i++)
1681573Srgrimes	    if (children[i])
1691573Srgrimes		device_delete_child(dev, children[i]);
1701573Srgrimes	free(children, M_TEMP);
1711573Srgrimes    }
1721573Srgrimes
1731573Srgrimes    /* release resources */
1741573Srgrimes    bus_teardown_intr(dev, ch->r_irq, ch->ih);
17562232Sdcs    bus_release_resource(dev, SYS_RES_IRQ, ATA_IRQ_RID, ch->r_irq);
17662232Sdcs    ch->r_irq = NULL;
17762232Sdcs    mtx_destroy(&ch->state_mtx);
1781573Srgrimes    mtx_destroy(&ch->queue_mtx);
1791573Srgrimes    return 0;
1801573Srgrimes}
1811573Srgrimes
1821573Srgrimesint
1831573Srgrimesata_reinit(device_t dev)
1841573Srgrimes{
1851573Srgrimes    struct ata_channel *ch = device_get_softc(dev);
1861573Srgrimes    device_t *children;
1871573Srgrimes    int nchildren, i;
1881573Srgrimes
1891573Srgrimes    /* check that we have a vaild channel to reinit */
1901573Srgrimes    if (!ch || !ch->r_irq)
1911573Srgrimes	return ENXIO;
1921573Srgrimes
1931573Srgrimes    if (bootverbose)
1941573Srgrimes	device_printf(dev, "reiniting channel ..\n");
1951573Srgrimes
1961573Srgrimes    /* poll for locking the channel */
19792889Sobrien    while (ATA_LOCKING(dev, ATA_LF_LOCK) != ch->unit)
19892889Sobrien	tsleep(&dev, PRIBIO, "atarini", 1);
19992889Sobrien
20092889Sobrien    /* unconditionally grap the channel lock */
2011573Srgrimes    mtx_lock(&ch->state_mtx);
2021573Srgrimes    ch->state = ATA_STALL_QUEUE;
2031573Srgrimes    mtx_unlock(&ch->state_mtx);
2041573Srgrimes
2051573Srgrimes    /* reset the controller HW, the channel and device(s) */
2061573Srgrimes    ATA_RESET(dev);
2071573Srgrimes
2081573Srgrimes    /* reinit the children and delete any that fails */
2091573Srgrimes    if (!device_get_children(dev, &children, &nchildren)) {
2101573Srgrimes	mtx_lock(&Giant);       /* newbus suckage it needs Giant */
2111573Srgrimes	for (i = 0; i < nchildren; i++) {
2121573Srgrimes	    if (children[i] && device_is_attached(children[i]))
2131573Srgrimes		if (ATA_REINIT(children[i])) {
2141573Srgrimes		    /*
2151573Srgrimes		     * if we have a running request and its device matches
2161573Srgrimes		     * this child we need to inform the request that the
2171573Srgrimes		     * device is gone and remove it from ch->running
2181573Srgrimes		     */
2191573Srgrimes		    if (ch->running && ch->running->dev == children[i]) {
2201573Srgrimes			device_printf(ch->running->dev,
2211573Srgrimes				      "FAILURE - device detached\n");
2221573Srgrimes			ch->running->dev = NULL;
2231573Srgrimes			ch->running = NULL;
2241573Srgrimes		    }
2251573Srgrimes		    device_delete_child(dev, children[i]);
2261573Srgrimes		}
2271573Srgrimes	}
2281573Srgrimes	free(children, M_TEMP);
2291573Srgrimes	mtx_unlock(&Giant);     /* newbus suckage dealt with, release Giant */
2301573Srgrimes    }
2311573Srgrimes
2321573Srgrimes    /* catch request in ch->running if we havn't already */
2331573Srgrimes    ata_catch_inflight(dev);
2341573Srgrimes
2351573Srgrimes    /* we're done release the channel for new work */
2361573Srgrimes    mtx_lock(&ch->state_mtx);
2371573Srgrimes    ch->state = ATA_IDLE;
2381573Srgrimes    mtx_unlock(&ch->state_mtx);
2391573Srgrimes    ATA_LOCKING(dev, ATA_LF_UNLOCK);
2401573Srgrimes
2411573Srgrimes    if (bootverbose)
2421573Srgrimes	device_printf(dev, "reinit done ..\n");
2431573Srgrimes
2441573Srgrimes    /* kick off requests on the queue */
2451573Srgrimes    ata_start(dev);
2461573Srgrimes    return 0;
2471573Srgrimes}
2481573Srgrimes
2491573Srgrimesint
25062391Sdcsata_suspend(device_t dev)
25162263Sdcs{
25262263Sdcs    struct ata_channel *ch;
2531573Srgrimes
2541573Srgrimes    /* check for valid device */
2551573Srgrimes    if (!dev || !(ch = device_get_softc(dev)))
2561573Srgrimes	return ENXIO;
2571573Srgrimes
2581573Srgrimes    /* wait for the channel to be IDLE before entering suspend mode */
2591573Srgrimes    while (1) {
2601573Srgrimes	mtx_lock(&ch->state_mtx);
2611573Srgrimes	if (ch->state == ATA_IDLE) {
2621573Srgrimes	    ch->state = ATA_ACTIVE;
2631573Srgrimes	    mtx_unlock(&ch->state_mtx);
2641573Srgrimes	    break;
2651573Srgrimes	}
2661573Srgrimes	mtx_unlock(&ch->state_mtx);
2671573Srgrimes	tsleep(ch, PRIBIO, "atasusp", hz/10);
2681573Srgrimes    }
2691573Srgrimes    ATA_LOCKING(dev, ATA_LF_UNLOCK);
2701573Srgrimes    return 0;
2711573Srgrimes}
2721573Srgrimes
2731573Srgrimesint
2741573Srgrimesata_resume(device_t dev)
2751573Srgrimes{
27662232Sdcs    struct ata_channel *ch;
27762232Sdcs    int error;
27862232Sdcs
27962232Sdcs    /* check for valid device */
28062232Sdcs    if (!dev || !(ch = device_get_softc(dev)))
28162232Sdcs	return ENXIO;
28262755Sdcs
28362232Sdcs    /* reinit the devices, we dont know what mode/state they are in */
28462232Sdcs    error = ata_reinit(dev);
28562232Sdcs
28662232Sdcs    /* kick off requests on the queue */
2871573Srgrimes    ata_start(dev);
2881573Srgrimes    return error;
2891573Srgrimes}
2901573Srgrimes
2911573Srgrimesstatic void
2921573Srgrimesata_interrupt(void *data)
2931573Srgrimes{
2941573Srgrimes    struct ata_channel *ch = (struct ata_channel *)data;
2951573Srgrimes    struct ata_request *request;
2961573Srgrimes
2971573Srgrimes    mtx_lock(&ch->state_mtx);
2981573Srgrimes    do {
2991573Srgrimes	/* do we have a running request */
3001573Srgrimes	if (!(request = ch->running) || (request->flags & ATA_R_TIMEOUT))
3011573Srgrimes	    break;
3021573Srgrimes
3031573Srgrimes	ATA_DEBUG_RQ(request, "interrupt");
3041573Srgrimes
3051573Srgrimes	/* ignore interrupt if device is busy */
30692889Sobrien	if (ATA_IDX_INB(ch, ATA_ALTSTAT) & ATA_S_BUSY) {
3071573Srgrimes	    DELAY(100);
3081573Srgrimes	    if (ATA_IDX_INB(ch, ATA_ALTSTAT) & ATA_S_BUSY)
3091573Srgrimes		break;
31092889Sobrien	}
3111573Srgrimes
3121573Srgrimes	/* check for the right state */
31392889Sobrien	if (ch->state != ATA_ACTIVE && ch->state != ATA_STALL_QUEUE) {
31492889Sobrien	    device_printf(request->dev,
31592889Sobrien			  "interrupt state=%d unexpected\n", ch->state);
31692889Sobrien	    break;
31792889Sobrien	}
3181573Srgrimes
3191573Srgrimes	/*
3201573Srgrimes	 * we have the HW locks, so end the tranaction for this request
3211573Srgrimes	 * if it finishes immediately otherwise wait for next interrupt
3221573Srgrimes	 */
3231573Srgrimes	if (ch->hw.end_transaction(request) == ATA_OP_FINISHED) {
32417141Sjkh	    ch->running = NULL;
3251573Srgrimes	    if (ch->state == ATA_ACTIVE)
3261573Srgrimes		ch->state = ATA_IDLE;
3271573Srgrimes	    mtx_unlock(&ch->state_mtx);
3281573Srgrimes	    ATA_LOCKING(ch->dev, ATA_LF_UNLOCK);
3291573Srgrimes	    ata_finish(request);
3301573Srgrimes	    return;
3311573Srgrimes	}
3321573Srgrimes    } while (0);
3331573Srgrimes    mtx_unlock(&ch->state_mtx);
3341573Srgrimes}
3351573Srgrimes
3361573Srgrimes/*
3371573Srgrimes * device related interfaces
3381573Srgrimes */
3391573Srgrimesstatic int
3401573Srgrimesata_ioctl(struct cdev *dev, u_long cmd, caddr_t data,
3411573Srgrimes	  int32_t flag, struct thread *td)
3421573Srgrimes{
3431573Srgrimes    device_t device, *children;
3441573Srgrimes    struct ata_ioc_devices *devices = (struct ata_ioc_devices *)data;
3451573Srgrimes    int *value = (int *)data;
3461573Srgrimes    int i, nchildren, error = ENOTTY;
3471573Srgrimes
3481573Srgrimes    switch (cmd) {
3491573Srgrimes    case IOCATAGMAXCHANNEL:
3501573Srgrimes	*value = devclass_get_maxunit(ata_devclass);
3511573Srgrimes	error = 0;
35292889Sobrien	break;
3531573Srgrimes
3541573Srgrimes    case IOCATAREINIT:
3551573Srgrimes	if (*value > devclass_get_maxunit(ata_devclass) ||
35692889Sobrien	    !(device = devclass_get_device(ata_devclass, *value)))
3571573Srgrimes	    return ENXIO;
35892889Sobrien	error = ata_reinit(device);
35992889Sobrien	ata_start(device);
36092889Sobrien	break;
36192889Sobrien
36292889Sobrien    case IOCATAATTACH:
3631573Srgrimes	if (*value > devclass_get_maxunit(ata_devclass) ||
3641573Srgrimes	    !(device = devclass_get_device(ata_devclass, *value)))
3651573Srgrimes	    return ENXIO;
3661573Srgrimes	/* XXX SOS should enable channel HW on controller */
3671573Srgrimes	error = ata_attach(device);
3681573Srgrimes	break;
3691573Srgrimes
3701573Srgrimes    case IOCATADETACH:
37117141Sjkh	if (*value > devclass_get_maxunit(ata_devclass) ||
3721573Srgrimes	    !(device = devclass_get_device(ata_devclass, *value)))
3731573Srgrimes	    return ENXIO;
3741573Srgrimes	error = ata_detach(device);
3751573Srgrimes	/* XXX SOS should disable channel HW on controller */
3761573Srgrimes	break;
3771573Srgrimes
3781573Srgrimes    case IOCATADEVICES:
3791573Srgrimes	if (devices->channel > devclass_get_maxunit(ata_devclass) ||
3801573Srgrimes	    !(device = devclass_get_device(ata_devclass, devices->channel)))
3811573Srgrimes	    return ENXIO;
3821573Srgrimes	bzero(devices->name[0], 32);
3831573Srgrimes	bzero(&devices->params[0], sizeof(struct ata_params));
38417141Sjkh	bzero(devices->name[1], 32);
3851573Srgrimes	bzero(&devices->params[1], sizeof(struct ata_params));
3861573Srgrimes	if (!device_get_children(device, &children, &nchildren)) {
3871573Srgrimes	    for (i = 0; i < nchildren; i++) {
3881573Srgrimes		if (children[i] && device_is_attached(children[i])) {
3891573Srgrimes		    struct ata_device *atadev = device_get_softc(children[i]);
3901573Srgrimes
3911573Srgrimes		    if (atadev->unit == ATA_MASTER) {
3921573Srgrimes			strncpy(devices->name[0],
3931573Srgrimes				device_get_nameunit(children[i]), 32);
3941573Srgrimes			bcopy(&atadev->param, &devices->params[0],
3951573Srgrimes			      sizeof(struct ata_params));
3961573Srgrimes		    }
3971573Srgrimes		    if (atadev->unit == ATA_SLAVE) {
3981573Srgrimes			strncpy(devices->name[1],
3991573Srgrimes				device_get_nameunit(children[i]), 32);
4001573Srgrimes			bcopy(&atadev->param, &devices->params[1],
4011573Srgrimes			      sizeof(struct ata_params));
4021573Srgrimes		    }
4031573Srgrimes		}
4041573Srgrimes	    }
4051573Srgrimes	    free(children, M_TEMP);
4061573Srgrimes	    error = 0;
4071573Srgrimes	}
4081573Srgrimes	else
4091573Srgrimes	    error = ENODEV;
4101573Srgrimes	break;
4111573Srgrimes
4121573Srgrimes    default:
4131573Srgrimes	if (ata_raid_ioctl_func)
4141573Srgrimes	    error = ata_raid_ioctl_func(cmd, data);
4151573Srgrimes    }
4161573Srgrimes    return error;
4171573Srgrimes}
4181573Srgrimes
4191573Srgrimesint
4201573Srgrimesata_device_ioctl(device_t dev, u_long cmd, caddr_t data)
4211573Srgrimes{
4221573Srgrimes    struct ata_device *atadev = device_get_softc(dev);
4231573Srgrimes    struct ata_ioc_request *ioc_request = (struct ata_ioc_request *)data;
4241573Srgrimes    struct ata_params *params = (struct ata_params *)data;
4251573Srgrimes    int *mode = (int *)data;
4261573Srgrimes    struct ata_request *request;
42717141Sjkh    caddr_t buf;
4281573Srgrimes    int error;
4291573Srgrimes
4301573Srgrimes    switch (cmd) {
4311573Srgrimes    case IOCATAREQUEST:
43249094Sache	if (!(buf = malloc(ioc_request->count, M_ATA, M_NOWAIT))) {
4331573Srgrimes	    return ENOMEM;
4341573Srgrimes	}
4351573Srgrimes	if (!(request = ata_alloc_request())) {
4361573Srgrimes	    free(buf, M_ATA);
4371573Srgrimes	    return  ENOMEM;
4381573Srgrimes	}
4391573Srgrimes	if (ioc_request->flags & ATA_CMD_WRITE) {
4401573Srgrimes	    error = copyin(ioc_request->data, buf, ioc_request->count);
4411573Srgrimes	    if (error) {
4421573Srgrimes		free(buf, M_ATA);
4431573Srgrimes		ata_free_request(request);
44449094Sache		return error;
4451573Srgrimes	    }
4461573Srgrimes	}
4471573Srgrimes	request->dev = dev;
44817141Sjkh	if (ioc_request->flags & ATA_CMD_ATAPI) {
4491573Srgrimes	    request->flags = ATA_R_ATAPI;
4501573Srgrimes	    bcopy(ioc_request->u.atapi.ccb, request->u.atapi.ccb, 16);
4511573Srgrimes	}
4521573Srgrimes	else {
4531573Srgrimes	    request->u.ata.command = ioc_request->u.ata.command;
4541573Srgrimes	    request->u.ata.feature = ioc_request->u.ata.feature;
4551573Srgrimes	    request->u.ata.lba = ioc_request->u.ata.lba;
4561573Srgrimes	    request->u.ata.count = ioc_request->u.ata.count;
4571573Srgrimes	}
4581573Srgrimes	request->timeout = ioc_request->timeout;
4591573Srgrimes	request->data = buf;
4601573Srgrimes	request->bytecount = ioc_request->count;
4611573Srgrimes	request->transfersize = request->bytecount;
4621573Srgrimes	if (ioc_request->flags & ATA_CMD_CONTROL)
4631573Srgrimes	    request->flags |= ATA_R_CONTROL;
4641573Srgrimes	if (ioc_request->flags & ATA_CMD_READ)
4651573Srgrimes	    request->flags |= ATA_R_READ;
4661573Srgrimes	if (ioc_request->flags & ATA_CMD_WRITE)
4671573Srgrimes	    request->flags |= ATA_R_WRITE;
4681573Srgrimes	ata_queue_request(request);
4691573Srgrimes	if (!(request->flags & ATA_R_ATAPI)) {
4701573Srgrimes	    ioc_request->u.ata.command = request->u.ata.command;
4711573Srgrimes	    ioc_request->u.ata.feature = request->u.ata.feature;
4721573Srgrimes	    ioc_request->u.ata.lba = request->u.ata.lba;
47349094Sache	    ioc_request->u.ata.count = request->u.ata.count;
4741573Srgrimes	}
47517141Sjkh	ioc_request->error = request->result;
4761573Srgrimes	if (ioc_request->flags & ATA_CMD_READ)
4771573Srgrimes	    error = copyout(buf, ioc_request->data, ioc_request->count);
4781573Srgrimes	else
4791573Srgrimes	    error = 0;
4801573Srgrimes	free(buf, M_ATA);
4811573Srgrimes	ata_free_request(request);
4821573Srgrimes	return error;
4831573Srgrimes
48417141Sjkh    case IOCATAGPARM:
4851573Srgrimes	bcopy(&atadev->param, params, sizeof(struct ata_params));
4861573Srgrimes	return 0;
4871573Srgrimes
4881573Srgrimes    case IOCATASMODE:
4891573Srgrimes	atadev->mode = *mode;
4901573Srgrimes	ATA_SETMODE(device_get_parent(dev), dev);
4911573Srgrimes	return 0;
4921573Srgrimes
4931573Srgrimes    case IOCATAGMODE:
49449094Sache	*mode = atadev->mode;
4951573Srgrimes	return 0;
4961573Srgrimes    default:
4971573Srgrimes	return ENOTTY;
4981573Srgrimes    }
4991573Srgrimes}
5001573Srgrimes
50192889Sobrienstatic void
5021573Srgrimesata_boot_attach(void)
5031573Srgrimes{
5041573Srgrimes    struct ata_channel *ch;
50592889Sobrien    int ctlr;
5061573Srgrimes
50717141Sjkh    /* release the hook that got us here, only needed during boot */
5081573Srgrimes    if (ata_delayed_attach) {
5091573Srgrimes	config_intrhook_disestablish(ata_delayed_attach);
5101573Srgrimes	free(ata_delayed_attach, M_TEMP);
5111573Srgrimes	ata_delayed_attach = NULL;
5121573Srgrimes    }
5131573Srgrimes
51492889Sobrien    /* kick of probe and attach on all channels */
51592889Sobrien    for (ctlr = 0; ctlr < devclass_get_maxunit(ata_devclass); ctlr++) {
5161573Srgrimes	if ((ch = devclass_get_softc(ata_devclass, ctlr))) {
5171573Srgrimes	    ata_identify(ch->dev);
5181573Srgrimes	}
5191573Srgrimes    }
5201573Srgrimes}
5211573Srgrimes
5221573Srgrimes
5231573Srgrimes/*
5241573Srgrimes * misc support functions
5251573Srgrimes */
52692889Sobrienstatic device_t
52792889Sobrienata_add_child(device_t parent, struct ata_device *atadev, int unit)
52892889Sobrien{
5291573Srgrimes    device_t child;
53092889Sobrien
53192889Sobrien    if ((child = device_add_child(parent, NULL, unit))) {
53292889Sobrien	device_set_softc(child, atadev);
5331573Srgrimes	device_quiet(child);
5341573Srgrimes	atadev->dev = child;
5351573Srgrimes	atadev->max_iosize = DEV_BSIZE;
5361573Srgrimes	atadev->mode = ATA_PIO_MAX;
5371573Srgrimes    }
5381573Srgrimes    return child;
5391573Srgrimes}
5401573Srgrimes
5411573Srgrimesstatic int
5421573Srgrimesata_getparam(device_t parent, struct ata_device *atadev)
5431573Srgrimes{
5441573Srgrimes    struct ata_channel *ch = device_get_softc(parent);
5451573Srgrimes    struct ata_request *request;
5461573Srgrimes    u_int8_t command = 0;
5471573Srgrimes    int error = ENOMEM, retries = 2;
5481573Srgrimes
5491573Srgrimes    if (ch->devices &
55017141Sjkh	(atadev->unit == ATA_MASTER ? ATA_ATA_MASTER : ATA_ATA_SLAVE))
5511573Srgrimes	command = ATA_ATA_IDENTIFY;
5521573Srgrimes    if (ch->devices &
5531573Srgrimes	(atadev->unit == ATA_MASTER ? ATA_ATAPI_MASTER : ATA_ATAPI_SLAVE))
5541573Srgrimes	command = ATA_ATAPI_IDENTIFY;
55592889Sobrien    if (!command)
5561573Srgrimes	return ENXIO;
5571573Srgrimes
5581573Srgrimes    while (retries-- > 0 && error) {
55992889Sobrien	if (!(request = ata_alloc_request()))
5601573Srgrimes	    break;
5611573Srgrimes	request->dev = atadev->dev;
56292889Sobrien	request->timeout = 1;
56392889Sobrien	request->retries = 0;
56492889Sobrien	request->u.ata.command = command;
56592889Sobrien	request->flags = (ATA_R_READ|ATA_R_AT_HEAD|ATA_R_DIRECT|ATA_R_QUIET);
56692889Sobrien	request->data = (void *)&atadev->param;
56792889Sobrien	request->bytecount = sizeof(struct ata_params);
5681573Srgrimes	request->donecount = 0;
5691573Srgrimes	request->transfersize = DEV_BSIZE;
5701573Srgrimes	ata_queue_request(request);
5711573Srgrimes	error = request->result;
5721573Srgrimes	ata_free_request(request);
5731573Srgrimes    }
5741573Srgrimes
57517141Sjkh    if (!error && (isprint(atadev->param.model[0]) ||
57649094Sache		   isprint(atadev->param.model[1]))) {
5771573Srgrimes	struct ata_params *atacap = &atadev->param;
5781573Srgrimes	char buffer[64];
5791573Srgrimes#if BYTE_ORDER == BIG_ENDIAN
5801573Srgrimes	int16_t *ptr;
5811573Srgrimes
5821573Srgrimes	for (ptr = (int16_t *)atacap;
5831573Srgrimes	     ptr < (int16_t *)atacap + sizeof(struct ata_params)/2; ptr++) {
5841573Srgrimes	    *ptr = bswap16(*ptr);
5851573Srgrimes	}
5861573Srgrimes#endif
5871573Srgrimes	if (!(!strncmp(atacap->model, "FX", 2) ||
5881573Srgrimes	      !strncmp(atacap->model, "NEC", 3) ||
5891573Srgrimes	      !strncmp(atacap->model, "Pioneer", 7) ||
5901573Srgrimes	      !strncmp(atacap->model, "SHARP", 5))) {
5911573Srgrimes	    bswap(atacap->model, sizeof(atacap->model));
5921573Srgrimes	    bswap(atacap->revision, sizeof(atacap->revision));
5931573Srgrimes	    bswap(atacap->serial, sizeof(atacap->serial));
5941573Srgrimes	}
5951573Srgrimes	btrim(atacap->model, sizeof(atacap->model));
5961573Srgrimes	bpack(atacap->model, atacap->model, sizeof(atacap->model));
5971573Srgrimes	btrim(atacap->revision, sizeof(atacap->revision));
5981573Srgrimes	bpack(atacap->revision, atacap->revision, sizeof(atacap->revision));
5991573Srgrimes	btrim(atacap->serial, sizeof(atacap->serial));
6001573Srgrimes	bpack(atacap->serial, atacap->serial, sizeof(atacap->serial));
6011573Srgrimes	sprintf(buffer, "%.40s/%.8s", atacap->model, atacap->revision);
6021573Srgrimes	device_set_desc_copy(atadev->dev, buffer);
6031573Srgrimes	if (bootverbose)
6041573Srgrimes	    printf("ata%d-%s: pio=%s wdma=%s udma=%s cable=%s wire\n",
60517141Sjkh		   ch->unit, atadev->unit == ATA_MASTER ? "master":"slave",
6061573Srgrimes		   ata_mode2str(ata_pmode(atacap)),
6071573Srgrimes		   ata_mode2str(ata_wmode(atacap)),
6081573Srgrimes		   ata_mode2str(ata_umode(atacap)),
6091573Srgrimes		   (atacap->hwres & ATA_CABLE_ID) ? "80":"40");
6101573Srgrimes
6111573Srgrimes	if (atadev->param.config & ATA_PROTO_ATAPI) {
6121573Srgrimes	    if (atapi_dma && ch->dma &&
6131573Srgrimes		(atadev->param.config & ATA_DRQ_MASK) != ATA_DRQ_INTR &&
6141573Srgrimes		ata_umode(&atadev->param) >= ATA_UDMA2)
6151573Srgrimes		atadev->mode = ATA_DMA_MAX;
6161573Srgrimes	}
6171573Srgrimes	else {
6181573Srgrimes	    if (ata_dma && ch->dma &&
6191573Srgrimes		(ata_umode(&atadev->param) > 0 ||
6201573Srgrimes		 ata_wmode(&atadev->param) > 0))
6211573Srgrimes		atadev->mode = ATA_DMA_MAX;
6221573Srgrimes	}
6231573Srgrimes    }
6241573Srgrimes    else {
6251573Srgrimes	if (!error)
6261573Srgrimes	    error = ENXIO;
6271573Srgrimes    }
6281573Srgrimes    return error;
6291573Srgrimes}
6301573Srgrimes
6311573Srgrimesint
6321573Srgrimesata_identify(device_t dev)
6331573Srgrimes{
6341573Srgrimes    struct ata_channel *ch = device_get_softc(dev);
63517141Sjkh    struct ata_device *master = NULL, *slave = NULL;
6361573Srgrimes    device_t master_child = NULL, slave_child = NULL;
6371573Srgrimes    int master_unit = -1, slave_unit = -1;
63849094Sache
6391573Srgrimes    if (ch->devices & (ATA_ATA_MASTER | ATA_ATAPI_MASTER)) {
6401573Srgrimes	if (!(master = malloc(sizeof(struct ata_device),
6411573Srgrimes			      M_ATA, M_NOWAIT | M_ZERO))) {
6421573Srgrimes	    device_printf(dev, "out of memory\n");
6431573Srgrimes	    return ENOMEM;
6441573Srgrimes	}
6451573Srgrimes	master->unit = ATA_MASTER;
6461573Srgrimes    }
6471573Srgrimes    if (ch->devices & (ATA_ATA_SLAVE | ATA_ATAPI_SLAVE)) {
6481573Srgrimes	if (!(slave = malloc(sizeof(struct ata_device),
6491573Srgrimes			     M_ATA, M_NOWAIT | M_ZERO))) {
6501573Srgrimes	    free(master, M_ATA);
65149094Sache	    device_printf(dev, "out of memory\n");
6521573Srgrimes	    return ENOMEM;
65317141Sjkh	}
6541573Srgrimes	slave->unit = ATA_SLAVE;
6551573Srgrimes    }
6561573Srgrimes
6571573Srgrimes#ifdef ATA_STATIC_ID
6581573Srgrimes    if (ch->devices & ATA_ATA_MASTER)
6591573Srgrimes	master_unit = (device_get_unit(dev) << 1);
6601573Srgrimes#endif
6611573Srgrimes    if (master && !(master_child = ata_add_child(dev, master, master_unit))) {
66217141Sjkh	free(master, M_ATA);
6631573Srgrimes	master = NULL;
6641573Srgrimes    }
66549094Sache#ifdef ATA_STATIC_ID
6661573Srgrimes    if (ch->devices & ATA_ATA_SLAVE)
6671573Srgrimes	slave_unit = (device_get_unit(dev) << 1) + 1;
6681573Srgrimes#endif
6691573Srgrimes    if (slave && !(slave_child = ata_add_child(dev, slave, slave_unit))) {
6701573Srgrimes	free(slave, M_ATA);
6711573Srgrimes	slave = NULL;
6721573Srgrimes    }
67392889Sobrien
6741573Srgrimes    if (slave && ata_getparam(dev, slave)) {
6751573Srgrimes	device_delete_child(dev, slave_child);
6761573Srgrimes	free(slave, M_ATA);
67792889Sobrien    }
6781573Srgrimes    if (master && ata_getparam(dev, master)) {
67992889Sobrien	device_delete_child(dev, master_child);
68092889Sobrien	free(master, M_ATA);
6811573Srgrimes    }
68249094Sache
6831573Srgrimes    bus_generic_probe(dev);
6841573Srgrimes    bus_generic_attach(dev);
6851573Srgrimes    return 0;
6861573Srgrimes}
68717141Sjkh
6881573Srgrimesvoid
6891573Srgrimesata_default_registers(device_t dev)
6901573Srgrimes{
6911573Srgrimes    struct ata_channel *ch = device_get_softc(dev);
6921573Srgrimes
69392889Sobrien    /* fill in the defaults from whats setup already */
6941573Srgrimes    ch->r_io[ATA_ERROR].res = ch->r_io[ATA_FEATURE].res;
6951573Srgrimes    ch->r_io[ATA_ERROR].offset = ch->r_io[ATA_FEATURE].offset;
6961573Srgrimes    ch->r_io[ATA_IREASON].res = ch->r_io[ATA_COUNT].res;
6971573Srgrimes    ch->r_io[ATA_IREASON].offset = ch->r_io[ATA_COUNT].offset;
6981573Srgrimes    ch->r_io[ATA_STATUS].res = ch->r_io[ATA_COMMAND].res;
6991573Srgrimes    ch->r_io[ATA_STATUS].offset = ch->r_io[ATA_COMMAND].offset;
70092889Sobrien    ch->r_io[ATA_ALTSTAT].res = ch->r_io[ATA_CONTROL].res;
7011573Srgrimes    ch->r_io[ATA_ALTSTAT].offset = ch->r_io[ATA_CONTROL].offset;
70292889Sobrien}
70392889Sobrien
7041573Srgrimesvoid
7051573Srgrimesata_modify_if_48bit(struct ata_request *request)
7061573Srgrimes{
7071573Srgrimes    struct ata_channel *ch = device_get_softc(device_get_parent(request->dev));
7081573Srgrimes    struct ata_device *atadev = device_get_softc(request->dev);
7091573Srgrimes
7101573Srgrimes    atadev->flags &= ~ATA_D_48BIT_ACTIVE;
7111573Srgrimes
7121573Srgrimes    if ((request->u.ata.lba >= ATA_MAX_28BIT_LBA ||
7131573Srgrimes	 request->u.ata.count > 256) &&
7141573Srgrimes	atadev->param.support.command2 & ATA_SUPPORT_ADDRESS48) {
7151573Srgrimes
7161573Srgrimes	/* translate command into 48bit version */
7171573Srgrimes	switch (request->u.ata.command) {
7181573Srgrimes	case ATA_READ:
7191573Srgrimes	    request->u.ata.command = ATA_READ48;
7201573Srgrimes	    break;
7211573Srgrimes	case ATA_READ_MUL:
7221573Srgrimes	    request->u.ata.command = ATA_READ_MUL48;
7231573Srgrimes	    break;
7241573Srgrimes	case ATA_READ_DMA:
7251573Srgrimes	    if (ch->flags & ATA_NO_48BIT_DMA) {
7261573Srgrimes		if (request->transfersize > DEV_BSIZE)
72717141Sjkh		    request->u.ata.command = ATA_READ_MUL48;
7281573Srgrimes		else
7291573Srgrimes		    request->u.ata.command = ATA_READ48;
7301573Srgrimes		request->flags &= ~ATA_R_DMA;
7311573Srgrimes	    }
7321573Srgrimes	    else
73392889Sobrien		request->u.ata.command = ATA_READ_DMA48;
73492889Sobrien	    break;
7351573Srgrimes	case ATA_READ_DMA_QUEUED:
7361573Srgrimes	    if (ch->flags & ATA_NO_48BIT_DMA) {
7371573Srgrimes		if (request->transfersize > DEV_BSIZE)
7381573Srgrimes		    request->u.ata.command = ATA_READ_MUL48;
7391573Srgrimes		else
7401573Srgrimes		    request->u.ata.command = ATA_READ48;
7411573Srgrimes		request->flags &= ~ATA_R_DMA;
7421573Srgrimes	    }
7431573Srgrimes	    else
7441573Srgrimes		request->u.ata.command = ATA_READ_DMA_QUEUED48;
7451573Srgrimes	    break;
74692889Sobrien	case ATA_WRITE:
7471573Srgrimes	    request->u.ata.command = ATA_WRITE48;
7481573Srgrimes	    break;
7491573Srgrimes	case ATA_WRITE_MUL:
7501573Srgrimes	    request->u.ata.command = ATA_WRITE_MUL48;
7511573Srgrimes	    break;
7521573Srgrimes	case ATA_WRITE_DMA:
7531573Srgrimes	    if (ch->flags & ATA_NO_48BIT_DMA) {
7541573Srgrimes		if (request->transfersize > DEV_BSIZE)
7551573Srgrimes		    request->u.ata.command = ATA_WRITE_MUL48;
7561573Srgrimes		else
7571573Srgrimes		    request->u.ata.command = ATA_WRITE48;
7581573Srgrimes		request->flags &= ~ATA_R_DMA;
7591573Srgrimes	    }
7601573Srgrimes	    else
7611573Srgrimes		request->u.ata.command = ATA_WRITE_DMA48;
7621573Srgrimes	    break;
7631573Srgrimes	case ATA_WRITE_DMA_QUEUED:
7641573Srgrimes	    if (ch->flags & ATA_NO_48BIT_DMA) {
7651573Srgrimes		if (request->transfersize > DEV_BSIZE)
7661573Srgrimes		    request->u.ata.command = ATA_WRITE_MUL48;
7671573Srgrimes		else
7681573Srgrimes		    request->u.ata.command = ATA_WRITE48;
7691573Srgrimes		request->u.ata.command = ATA_WRITE48;
77092889Sobrien		request->flags &= ~ATA_R_DMA;
7711573Srgrimes	    }
7721573Srgrimes	    else
7731573Srgrimes		request->u.ata.command = ATA_WRITE_DMA_QUEUED48;
77492889Sobrien	    break;
77592889Sobrien	case ATA_FLUSHCACHE:
7761573Srgrimes	    request->u.ata.command = ATA_FLUSHCACHE48;
77792889Sobrien	    break;
77892889Sobrien	default:
77992889Sobrien	    return;
7801573Srgrimes	}
7811573Srgrimes	atadev->flags |= ATA_D_48BIT_ACTIVE;
7821573Srgrimes    }
7831573Srgrimes}
7841573Srgrimes
7851573Srgrimesvoid
7861573Srgrimesata_udelay(int interval)
7871573Srgrimes{
7881573Srgrimes    /* for now just use DELAY, the timer/sleep subsytems are not there yet */
7891573Srgrimes    if (1 || interval < (1000000/hz) || ata_delayed_attach)
7901573Srgrimes	DELAY(interval);
7911573Srgrimes    else
7921573Srgrimes	tsleep(&interval, PRIBIO, "ataslp", interval/(1000000/hz));
7931573Srgrimes}
7941573Srgrimes
7951573Srgrimeschar *
7961573Srgrimesata_mode2str(int mode)
7971573Srgrimes{
79817141Sjkh    switch (mode) {
7991573Srgrimes    case -1: return "UNSUPPORTED";
80017141Sjkh    case ATA_PIO0: return "PIO0";
8011573Srgrimes    case ATA_PIO1: return "PIO1";
80217141Sjkh    case ATA_PIO2: return "PIO2";
80317141Sjkh    case ATA_PIO3: return "PIO3";
8041573Srgrimes    case ATA_PIO4: return "PIO4";
8051573Srgrimes    case ATA_WDMA0: return "WDMA0";
8061573Srgrimes    case ATA_WDMA1: return "WDMA1";
80717141Sjkh    case ATA_WDMA2: return "WDMA2";
8081573Srgrimes    case ATA_UDMA0: return "UDMA16";
80917141Sjkh    case ATA_UDMA1: return "UDMA25";
8101573Srgrimes    case ATA_UDMA2: return "UDMA33";
81117141Sjkh    case ATA_UDMA3: return "UDMA40";
81217141Sjkh    case ATA_UDMA4: return "UDMA66";
8131573Srgrimes    case ATA_UDMA5: return "UDMA100";
8141573Srgrimes    case ATA_UDMA6: return "UDMA133";
8151573Srgrimes    case ATA_SA150: return "SATA150";
8161573Srgrimes    case ATA_SA300: return "SATA300";
8171573Srgrimes    default:
8181573Srgrimes	if (mode & ATA_DMA_MASK)
8191573Srgrimes	    return "BIOSDMA";
8201573Srgrimes	else
8211573Srgrimes	    return "BIOSPIO";
8221573Srgrimes    }
8231573Srgrimes}
8241573Srgrimes
8251573Srgrimesint
82617514Sacheata_pmode(struct ata_params *ap)
82717514Sache{
82817514Sache    if (ap->atavalid & ATA_FLAG_64_70) {
82924637Sache	if (ap->apiomodes & 0x02)
83024637Sache	    return ATA_PIO4;
83124637Sache	if (ap->apiomodes & 0x01)
83217514Sache	    return ATA_PIO3;
83324637Sache    }
83424637Sache    if (ap->mwdmamodes & 0x04)
83524637Sache	return ATA_PIO4;
83624637Sache    if (ap->mwdmamodes & 0x02)
83724637Sache	return ATA_PIO3;
83824637Sache    if (ap->mwdmamodes & 0x01)
83924637Sache	return ATA_PIO2;
84024637Sache    if ((ap->retired_piomode & ATA_RETIRED_PIO_MASK) == 0x200)
84117514Sache	return ATA_PIO2;
84217514Sache    if ((ap->retired_piomode & ATA_RETIRED_PIO_MASK) == 0x100)
8431573Srgrimes	return ATA_PIO1;
8441573Srgrimes    if ((ap->retired_piomode & ATA_RETIRED_PIO_MASK) == 0x000)
8451573Srgrimes	return ATA_PIO0;
8461573Srgrimes    return ATA_PIO0;
8471573Srgrimes}
8481573Srgrimes
84992889Sobrienint
8501573Srgrimesata_wmode(struct ata_params *ap)
8511573Srgrimes{
8521573Srgrimes    if (ap->mwdmamodes & 0x04)
85392889Sobrien	return ATA_WDMA2;
85492889Sobrien    if (ap->mwdmamodes & 0x02)
8551573Srgrimes	return ATA_WDMA1;
85692889Sobrien    if (ap->mwdmamodes & 0x01)
85792889Sobrien	return ATA_WDMA0;
85892889Sobrien    return -1;
85992889Sobrien}
8601573Srgrimes
86117508Sacheint
8621573Srgrimesata_umode(struct ata_params *ap)
8631573Srgrimes{
8641573Srgrimes    if (ap->atavalid & ATA_FLAG_88) {
8651573Srgrimes	if (ap->udmamodes & 0x40)
8661573Srgrimes	    return ATA_UDMA6;
8671573Srgrimes	if (ap->udmamodes & 0x20)
8681573Srgrimes	    return ATA_UDMA5;
8691573Srgrimes	if (ap->udmamodes & 0x10)
8701573Srgrimes	    return ATA_UDMA4;
8711573Srgrimes	if (ap->udmamodes & 0x08)
8721573Srgrimes	    return ATA_UDMA3;
87317508Sache	if (ap->udmamodes & 0x04)
87417508Sache	    return ATA_UDMA2;
87517508Sache	if (ap->udmamodes & 0x02)
87617508Sache	    return ATA_UDMA1;
87717508Sache	if (ap->udmamodes & 0x01)
87817508Sache	    return ATA_UDMA0;
87917508Sache    }
88017508Sache    return -1;
88117508Sache}
88217508Sache
88317508Sacheint
88417508Sacheata_limit_mode(device_t dev, int mode, int maxmode)
88517508Sache{
88617508Sache    struct ata_device *atadev = device_get_softc(dev);
88717508Sache
88817508Sache    if (maxmode && mode > maxmode)
88917508Sache	mode = maxmode;
89017508Sache
89117508Sache    if (mode >= ATA_UDMA0 && ata_umode(&atadev->param) > 0)
89217508Sache	return min(mode, ata_umode(&atadev->param));
89317508Sache
89417508Sache    if (mode >= ATA_WDMA0 && ata_wmode(&atadev->param) > 0)
89517508Sache	return min(mode, ata_wmode(&atadev->param));
89617508Sache
89717508Sache    if (mode > ata_pmode(&atadev->param))
89817508Sache	return min(mode, ata_pmode(&atadev->param));
89917508Sache
90017508Sache    return mode;
90117508Sache}
90217508Sache
90317508Sachestatic void
90417508Sachebswap(int8_t *buf, int len)
90517508Sache{
90617508Sache    u_int16_t *ptr = (u_int16_t*)(buf + len);
90717508Sache
90817508Sache    while (--ptr >= (u_int16_t*)buf)
90917508Sache	*ptr = ntohs(*ptr);
91017508Sache}
91117508Sache
91217508Sachestatic void
91317508Sachebtrim(int8_t *buf, int len)
91417508Sache{
91517508Sache    int8_t *ptr;
91617508Sache
91717508Sache    for (ptr = buf; ptr < buf+len; ++ptr)
91817508Sache	if (!*ptr || *ptr == '_')
91917508Sache	    *ptr = ' ';
92017508Sache    for (ptr = buf + len - 1; ptr >= buf && *ptr == ' '; --ptr)
92117508Sache	*ptr = 0;
92217508Sache}
92317508Sache
92417508Sachestatic void
92517508Sachebpack(int8_t *src, int8_t *dst, int len)
92617508Sache{
92717508Sache    int i, j, blank;
92817508Sache
92917508Sache    for (i = j = blank = 0 ; i < len; i++) {
93017508Sache	if (blank && src[i] == ' ') continue;
93117508Sache	if (blank && src[i] != ' ') {
93217508Sache	    dst[j++] = src[i];
93317508Sache	    blank = 0;
93417508Sache	    continue;
93517508Sache	}
9361573Srgrimes	if (src[i] == ' ') {
9371573Srgrimes	    blank = 1;
93817508Sache	    if (i == 0)
9391573Srgrimes		continue;
9401573Srgrimes	}
9411573Srgrimes	dst[j++] = src[i];
9421573Srgrimes    }
94392889Sobrien    if (j < len)
9441573Srgrimes	dst[j] = 0x00;
9451573Srgrimes}
9461573Srgrimes
9471573Srgrimes
9481573Srgrimes/*
94992889Sobrien * module handeling
95092889Sobrien */
9511573Srgrimesstatic int
95292889Sobrienata_module_event_handler(module_t mod, int what, void *arg)
9531573Srgrimes{
9541573Srgrimes    static struct cdev *atacdev;
9551573Srgrimes
9561573Srgrimes    switch (what) {
9571573Srgrimes    case MOD_LOAD:
9581573Srgrimes	/* register controlling device */
9591573Srgrimes	atacdev = make_dev(&ata_cdevsw, 0, UID_ROOT, GID_OPERATOR, 0600, "ata");
96092889Sobrien
9611573Srgrimes	if (cold) {
9621573Srgrimes	    /* register boot attach to be run when interrupts are enabled */
9631573Srgrimes	    if (!(ata_delayed_attach = (struct intr_config_hook *)
96492889Sobrien				       malloc(sizeof(struct intr_config_hook),
9651573Srgrimes					      M_TEMP, M_NOWAIT | M_ZERO))) {
96692889Sobrien		printf("ata: malloc of delayed attach hook failed\n");
9671573Srgrimes		return EIO;
96817141Sjkh	    }
9691573Srgrimes	    ata_delayed_attach->ich_func = (void*)ata_boot_attach;
9701573Srgrimes	    if (config_intrhook_establish(ata_delayed_attach) != 0) {
9711573Srgrimes		printf("ata: config_intrhook_establish failed\n");
9721573Srgrimes		free(ata_delayed_attach, M_TEMP);
9731573Srgrimes	    }
97417141Sjkh	}
9751573Srgrimes	return 0;
9761573Srgrimes
9771573Srgrimes    case MOD_UNLOAD:
9781573Srgrimes	/* deregister controlling device */
9791573Srgrimes	destroy_dev(atacdev);
98092889Sobrien	return 0;
9811573Srgrimes
9821573Srgrimes    default:
9831573Srgrimes	return EOPNOTSUPP;
98492889Sobrien    }
9851573Srgrimes}
9861573Srgrimes
98792889Sobrienstatic moduledata_t ata_moduledata = { "ata", ata_module_event_handler, NULL };
98892889SobrienDECLARE_MODULE(ata, ata_moduledata, SI_SUB_CONFIGURE, SI_ORDER_SECOND);
98992889SobrienMODULE_VERSION(ata, 1);
9901573Srgrimes
9911573Srgrimesstatic void
9921573Srgrimesata_init(void)
9931573Srgrimes{
9941573Srgrimes    ata_request_zone = uma_zcreate("ata_request", sizeof(struct ata_request),
9951573Srgrimes				   NULL, NULL, NULL, NULL, 0, 0);
9961573Srgrimes    ata_composite_zone = uma_zcreate("ata_composite",
9971573Srgrimes				     sizeof(struct ata_composite),
9981573Srgrimes				     NULL, NULL, NULL, NULL, 0, 0);
9991573Srgrimes}
10001573SrgrimesSYSINIT(ata_register, SI_SUB_DRIVERS, SI_ORDER_SECOND, ata_init, NULL);
10011573Srgrimes
10021573Srgrimesstatic void
10031573Srgrimesata_uninit(void)
10041573Srgrimes{
10051573Srgrimes    uma_zdestroy(ata_composite_zone);
10061573Srgrimes    uma_zdestroy(ata_request_zone);
10071573Srgrimes}
10081573SrgrimesSYSUNINIT(ata_unregister, SI_SUB_DRIVERS, SI_ORDER_SECOND, ata_uninit, NULL);
10091573Srgrimes