ata-all.c revision 74253
1139749Simp/*-
259477Swpaul * Copyright (c) 1998,1999,2000,2001 S�ren Schmidt
359477Swpaul * All rights reserved.
459477Swpaul *
559477Swpaul * Redistribution and use in source and binary forms, with or without
659477Swpaul * modification, are permitted provided that the following conditions
759477Swpaul * are met:
859477Swpaul * 1. Redistributions of source code must retain the above copyright
959477Swpaul *    notice, this list of conditions and the following disclaimer,
1059477Swpaul *    without modification, immediately at the beginning of the file.
1159477Swpaul * 2. Redistributions in binary form must reproduce the above copyright
1259477Swpaul *    notice, this list of conditions and the following disclaimer in the
1359477Swpaul *    documentation and/or other materials provided with the distribution.
1459477Swpaul * 3. The name of the author may not be used to endorse or promote products
1559477Swpaul *    derived from this software without specific prior written permission.
1659477Swpaul *
1759477Swpaul * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
1859477Swpaul * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
1959477Swpaul * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
2059477Swpaul * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
2159477Swpaul * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
2259477Swpaul * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2359477Swpaul * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2459477Swpaul * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2559477Swpaul * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
2659477Swpaul * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2759477Swpaul *
2859477Swpaul * $FreeBSD: head/sys/dev/ata/ata-all.c 74253 2001-03-14 14:00:09Z sos $
2959477Swpaul */
3059477Swpaul
3159477Swpaul#include "pci.h"
3259477Swpaul#include "opt_ata.h"
33119418Sobrien#include <sys/param.h>
34119418Sobrien#include <sys/systm.h>
35119418Sobrien#include <sys/kernel.h>
3659477Swpaul#include <sys/disk.h>
37165360Sjkim#include <sys/module.h>
3859477Swpaul#include <sys/bus.h>
3959477Swpaul#include <sys/bio.h>
4059477Swpaul#include <sys/malloc.h>
4159477Swpaul#include <sys/devicestat.h>
4259477Swpaul#include <sys/sysctl.h>
43129876Sphk#include <machine/stdarg.h>
4459477Swpaul#include <machine/resource.h>
4559477Swpaul#include <machine/bus.h>
4659477Swpaul#include <sys/rman.h>
4759477Swpaul#ifdef __alpha__
48157642Sps#include <machine/md_var.h>
4959477Swpaul#endif
5059477Swpaul#include <dev/ata/ata-all.h>
5159477Swpaul#include <dev/ata/ata-disk.h>
5259477Swpaul#include <dev/ata/atapi-all.h>
53109514Sobrien
5459477Swpaul/* prototypes */
5559477Swpaulstatic void ata_boot_attach(void);
56117659Swpaulstatic void ata_intr(void *);
57117659Swpaulstatic int ata_getparam(struct ata_softc *, int, u_int8_t);
58117659Swpaulstatic int ata_service(struct ata_softc *);
59157642Spsstatic char *active2str(int);
6059477Swpaulstatic void bswap(int8_t *, int);
61119285Simpstatic void btrim(int8_t *, int);
62119285Simpstatic void bpack(int8_t *, int8_t *, int);
63118814Swpaul
6459477Swpaul/* global vars */
6559477Swpauldevclass_t ata_devclass;
66105135Salfred
67105135Salfred/* local vars */
6859477Swpaulstatic struct intr_config_hook *ata_delayed_attach = NULL;
69166037Sjkimstatic char ata_conf[256];
70166037Sjkimstatic MALLOC_DEFINE(M_ATA, "ATA generic", "ATA driver generic layer");
71166037Sjkim
72166037Sjkim/* misc defines */
73166037Sjkim#define MASTER	0
74166037Sjkim#define SLAVE	1
7559477Swpaul
7659477Swpaulint
7759477Swpaulata_probe(device_t dev)
7859477Swpaul{
7995722Sphk    struct ata_softc *scp;
8059477Swpaul    int rid;
8159477Swpaul
8259477Swpaul    if (!dev)
8359477Swpaul	return ENXIO;
8459477Swpaul    scp = device_get_softc(dev);
8559477Swpaul    if (!scp || scp->devices)
8659477Swpaul	return ENXIO;
8759477Swpaul
8859477Swpaul    /* initialize the softc basics */
89166049Sjkim    scp->active = ATA_IDLE;
9059477Swpaul    scp->dev = dev;
9159477Swpaul
9259477Swpaul    rid = ATA_IOADDR_RID;
9359477Swpaul    scp->r_io = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 0, ~0,
9484145Sjlemon				   ATA_IOSIZE, RF_ACTIVE);
95165360Sjkim    if (!scp->r_io)
9684145Sjlemon	goto failure;
9796026Sphk
98114590Sps    rid = ATA_ALTADDR_RID;
99114590Sps    scp->r_altio = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 0, ~0,
100114590Sps				      ATA_ALTIOSIZE, RF_ACTIVE);
101114590Sps    if (!scp->r_altio)
102166031Sjkim	goto failure;
103166031Sjkim
104166031Sjkim    rid = ATA_BMADDR_RID;
105166031Sjkim    scp->r_bmio = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 0, ~0,
106166032Sjkim				     ATA_BMIOSIZE, RF_ACTIVE);
107166032Sjkim
10859477Swpaul    if (bootverbose)
109160078Syongari	ata_printf(scp, -1, "iobase=0x%04x altiobase=0x%04x bmaddr=0x%04x\n",
110160078Syongari		   (int)rman_get_start(scp->r_io),
111160078Syongari		   (int)rman_get_start(scp->r_altio),
112160078Syongari		   (scp->r_bmio) ? (int)rman_get_start(scp->r_bmio) : 0);
113160078Syongari
114160078Syongari    ata_reset(scp);
115160078Syongari
116160078Syongari    TAILQ_INIT(&scp->ata_queue);
117164830Smarius    TAILQ_INIT(&scp->atapi_queue);
118164830Smarius    return 0;
119160078Syongari
120164830Smariusfailure:
121165090Sscottl    if (scp->r_io)
122160078Syongari	bus_release_resource(dev, SYS_RES_IOPORT, ATA_IOADDR_RID, scp->r_io);
123166031Sjkim    if (scp->r_altio)
124160078Syongari	bus_release_resource(dev, SYS_RES_IOPORT, ATA_ALTADDR_RID,scp->r_altio);
125160078Syongari    if (scp->r_bmio)
126160078Syongari	bus_release_resource(dev, SYS_RES_IOPORT, ATA_BMADDR_RID, scp->r_bmio);
127105135Salfred    if (bootverbose)
128150763Simp	ata_printf(scp, -1, "probe allocation failed\n");
12959477Swpaul    return ENXIO;
13059477Swpaul}
131164827Smarius
13259477Swpaulint
13359477Swpaulata_attach(device_t dev)
134105135Salfred{
135150763Simp    struct ata_softc *scp;
13659477Swpaul    int error, rid;
137166037Sjkim
13859477Swpaul    if (!dev)
13959477Swpaul	return ENXIO;
14059477Swpaul    scp = device_get_softc(dev);
14159477Swpaul    if (!scp)
142157642Sps	return ENXIO;
143157642Sps
144118814Swpaul    rid = ATA_IRQ_RID;
14559477Swpaul    scp->r_irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 0, ~0, 1,
146166037Sjkim				    RF_SHAREABLE | RF_ACTIVE);
147166037Sjkim    if (!scp->r_irq) {
14859477Swpaul	ata_printf(scp, -1, "unable to allocate interrupt\n");
14959477Swpaul	return ENXIO;
15059477Swpaul    }
15159477Swpaul    if ((error = bus_setup_intr(dev, scp->r_irq, INTR_TYPE_BIO|INTR_ENTROPY,
15259477Swpaul				ata_intr, scp, &scp->ih)))
15359477Swpaul	return error;
15459477Swpaul
15559477Swpaul    /*
15659477Swpaul     * do not attach devices if we are in early boot, this is done later
15759477Swpaul     * when interrupts are enabled by a hook into the boot process.
15859477Swpaul     * otherwise attach what the probe has found in scp->devices.
15959477Swpaul     */
16059477Swpaul    if (!ata_delayed_attach) {
16159477Swpaul	if (scp->devices & ATA_ATA_SLAVE)
16259477Swpaul	    if (ata_getparam(scp, ATA_SLAVE, ATA_C_ATA_IDENTIFY))
16359477Swpaul		scp->devices &= ~ATA_ATA_SLAVE;
16459477Swpaul	if (scp->devices & ATA_ATAPI_SLAVE)
16559477Swpaul	    if (ata_getparam(scp, ATA_SLAVE, ATA_C_ATAPI_IDENTIFY))
16659477Swpaul		scp->devices &= ~ATA_ATAPI_SLAVE;
16759477Swpaul	if (scp->devices & ATA_ATA_MASTER)
168165361Sjkim	    if (ata_getparam(scp, ATA_MASTER, ATA_C_ATA_IDENTIFY))
16959477Swpaul		scp->devices &= ~ATA_ATA_MASTER;
17059477Swpaul	if (scp->devices & ATA_ATAPI_MASTER)
171166037Sjkim	    if (ata_getparam(scp, ATA_MASTER,ATA_C_ATAPI_IDENTIFY))
172166037Sjkim		scp->devices &= ~ATA_ATAPI_MASTER;
173114590Sps#ifdef DEV_ATADISK
17459477Swpaul	if (scp->devices & ATA_ATA_MASTER)
17595667Sphk	    ad_attach(scp, ATA_MASTER);
17695667Sphk	if (scp->devices & ATA_ATA_SLAVE)
17759477Swpaul	    ad_attach(scp, ATA_SLAVE);
17895667Sphk#endif
179118814Swpaul#if defined(DEV_ATAPICD) || defined(DEV_ATAPIFD) || defined(DEV_ATAPIST)
180157642Sps	if (scp->devices & ATA_ATAPI_MASTER)
181157642Sps	    atapi_attach(scp, ATA_MASTER);
182165361Sjkim	if (scp->devices & ATA_ATAPI_SLAVE)
183157642Sps	    atapi_attach(scp, ATA_SLAVE);
184157642Sps#endif
185157642Sps    }
186157642Sps    return 0;
187118814Swpaul}
188121816Sbrooks
189118814Swpaulint
190118814Swpaulata_detach(device_t dev)
191118814Swpaul{
192118814Swpaul    struct ata_softc *scp;
193118814Swpaul    int s;
194118814Swpaul
195118814Swpaul    if (!dev)
196118814Swpaul	return ENXIO;
197118814Swpaul    scp = device_get_softc(dev);
198118814Swpaul    if (!scp || !scp->devices)
199118814Swpaul	return ENXIO;
200118814Swpaul
201165343Soleg    /* make sure channel is not busy SOS XXX */
202165343Soleg    s = splbio();
203165343Soleg    while (!atomic_cmpset_int(&scp->active, ATA_IDLE, ATA_ACTIVE))
204118814Swpaul        tsleep((caddr_t)&s, PRIBIO, "atachm", hz/4);
20559477Swpaul    splx(s);
20659477Swpaul
20759477Swpaul    /* disable interrupts on devices */
20859477Swpaul    ATA_OUTB(scp->r_io, ATA_DRIVE, ATA_D_IBM | ATA_MASTER);
20959477Swpaul    ATA_OUTB(scp->r_altio, ATA_ALTSTAT, ATA_A_IDS | ATA_A_4BIT);
21059477Swpaul    ATA_OUTB(scp->r_io, ATA_DRIVE, ATA_D_IBM | ATA_SLAVE);
21159477Swpaul    ATA_OUTB(scp->r_altio, ATA_ALTSTAT, ATA_A_IDS | ATA_A_4BIT);
21259477Swpaul
213164830Smarius#ifdef DEV_ATADISK
21459477Swpaul    if (scp->devices & ATA_ATA_MASTER && scp->dev_softc[MASTER])
21559477Swpaul	ad_detach(scp->dev_softc[MASTER], 1);
21684145Sjlemon    if (scp->devices & ATA_ATA_SLAVE && scp->dev_softc[SLAVE])
217150763Simp	ad_detach(scp->dev_softc[SLAVE], 1);
21859477Swpaul#endif
219166037Sjkim#if defined(DEV_ATAPICD) || defined(DEV_ATAPIFD) || defined(DEV_ATAPIST)
22059477Swpaul    if (scp->devices & ATA_ATAPI_MASTER && scp->dev_softc[MASTER])
22159477Swpaul	atapi_detach(scp->dev_softc[MASTER]);
22259477Swpaul    if (scp->devices & ATA_ATAPI_SLAVE && scp->dev_softc[SLAVE])
22359477Swpaul	atapi_detach(scp->dev_softc[SLAVE]);
224165343Soleg#endif
22559477Swpaul
22659477Swpaul    if (scp->dev_param[MASTER]) {
22759477Swpaul	free(scp->dev_param[MASTER], M_ATA);
22859477Swpaul	scp->dev_param[MASTER] = NULL;
22959477Swpaul    }
23059477Swpaul    if (scp->dev_param[SLAVE]) {
23159477Swpaul	free(scp->dev_param[SLAVE], M_ATA);
23259477Swpaul	scp->dev_param[SLAVE] = NULL;
23359477Swpaul    }
234165361Sjkim    scp->dev_softc[MASTER] = NULL;
235165361Sjkim    scp->dev_softc[SLAVE] = NULL;
23659477Swpaul    scp->mode[MASTER] = ATA_PIO;
23759477Swpaul    scp->mode[SLAVE] = ATA_PIO;
23859477Swpaul    scp->devices = 0;
239165343Soleg
24059477Swpaul    bus_teardown_intr(dev, scp->r_irq, scp->ih);
24159477Swpaul    bus_release_resource(dev, SYS_RES_IRQ, ATA_IRQ_RID, scp->r_irq);
24259477Swpaul    if (scp->r_bmio)
243114590Sps	bus_release_resource(dev, SYS_RES_IOPORT, ATA_BMADDR_RID, scp->r_bmio);
24459477Swpaul    bus_release_resource(dev, SYS_RES_IOPORT, ATA_ALTADDR_RID, scp->r_altio);
24559477Swpaul    bus_release_resource(dev, SYS_RES_IOPORT, ATA_IOADDR_RID, scp->r_io);
24659477Swpaul    scp->active = ATA_IDLE;
24759477Swpaul    return 0;
248165343Soleg}
24959477Swpaul
25059477Swpaulint
25159477Swpaulata_resume(device_t dev)
252165360Sjkim{
25359477Swpaul    struct ata_softc *scp = device_get_softc(dev);
25495673Sphk
25583029Swpaul    ata_reinit(scp);
25683029Swpaul    return 0;
257165360Sjkim}
258165360Sjkim
25959477Swpaulstatic int
26083597Swpaulata_getparam(struct ata_softc *scp, int device, u_int8_t command)
26183597Swpaul{
262165360Sjkim    struct ata_params *ata_parm;
26383597Swpaul    int8_t buffer[DEV_BSIZE];
26483597Swpaul    int retry = 0;
26559477Swpaul
26659477Swpaul    /* select drive */
26759477Swpaul    ATA_OUTB(scp->r_io, ATA_DRIVE, ATA_D_IBM | device);
26859477Swpaul    DELAY(1);
26959477Swpaul
27059477Swpaul    /* enable interrupt */
271165343Soleg    ATA_OUTB(scp->r_altio, ATA_ALTSTAT, ATA_A_4BIT);
27259477Swpaul    DELAY(1);
27359477Swpaul
27459477Swpaul    /* apparently some devices needs this repeated */
275165343Soleg    do {
27659477Swpaul	if (ata_command(scp, device, command, 0, 0, 0, 0, 0, ATA_WAIT_INTR)) {
27759477Swpaul	    ata_printf(scp, device, "identify failed\n");
27859477Swpaul	    return -1;
279165343Soleg	}
280165343Soleg	if (retry++ > 4) {
281165343Soleg	    ata_printf(scp, device, "identify retries exceeded\n");
28284145Sjlemon	    return -1;
283165343Soleg	}
28459477Swpaul    } while (ata_wait(scp, device,
28559477Swpaul		      ((command == ATA_C_ATAPI_IDENTIFY) ?
28659477Swpaul			ATA_S_DRQ : (ATA_S_READY | ATA_S_DSC | ATA_S_DRQ))));
287165343Soleg
28859477Swpaul    ATA_INSW(scp->r_io, ATA_DATA, (int16_t *)buffer,
289165361Sjkim	     sizeof(buffer)/sizeof(int16_t));
290165343Soleg    ata_parm = malloc(sizeof(struct ata_params), M_ATA, M_NOWAIT);
29159477Swpaul    if (!ata_parm) {
292165343Soleg	ata_printf(scp, device, "malloc for identify data failed\n");
29359477Swpaul        return -1;
294165343Soleg    }
295165343Soleg    bcopy(buffer, ata_parm, sizeof(struct ata_params));
296128870Sandre    if (command == ATA_C_ATA_IDENTIFY ||
297164830Smarius	!((ata_parm->model[0] == 'N' && ata_parm->model[1] == 'E') ||
298165343Soleg          (ata_parm->model[0] == 'F' && ata_parm->model[1] == 'X')))
299165343Soleg        bswap(ata_parm->model, sizeof(ata_parm->model));
300165343Soleg    btrim(ata_parm->model, sizeof(ata_parm->model));
301165343Soleg    bpack(ata_parm->model, ata_parm->model, sizeof(ata_parm->model));
30284145Sjlemon    bswap(ata_parm->revision, sizeof(ata_parm->revision));
303165360Sjkim    btrim(ata_parm->revision, sizeof(ata_parm->revision));
304153234Soleg    bpack(ata_parm->revision, ata_parm->revision, sizeof(ata_parm->revision));
30559477Swpaul    scp->dev_param[ATA_DEV(device)] = ata_parm;
30659477Swpaul    return 0;
30759477Swpaul}
30859477Swpaul
30959477Swpaulstatic void
310114628Spsata_boot_attach(void)
311114628Sps{
312114628Sps    struct ata_softc *scp;
313114628Sps    int ctlr;
314164830Smarius
315114628Sps    /*
316114628Sps     * run through all ata devices and look for real ATA & ATAPI devices
317166037Sjkim     * using the hints we found in the early probe, this avoids some of
318151370Sgrehan     * the delays probing of non-exsistent devices can cause.
319114628Sps     */
320114628Sps    for (ctlr=0; ctlr<devclass_get_maxunit(ata_devclass); ctlr++) {
321166031Sjkim	if (!(scp = devclass_get_softc(ata_devclass, ctlr)))
322166037Sjkim	    continue;
323166031Sjkim	if (scp->devices & ATA_ATA_SLAVE)
324166031Sjkim	    if (ata_getparam(scp, ATA_SLAVE, ATA_C_ATA_IDENTIFY))
325114628Sps		scp->devices &= ~ATA_ATA_SLAVE;
326114628Sps	if (scp->devices & ATA_ATAPI_SLAVE)
327114628Sps	    if (ata_getparam(scp, ATA_SLAVE, ATA_C_ATAPI_IDENTIFY))
328114628Sps		scp->devices &= ~ATA_ATAPI_SLAVE;
329114628Sps	if (scp->devices & ATA_ATA_MASTER)
330128870Sandre	    if (ata_getparam(scp, ATA_MASTER, ATA_C_ATA_IDENTIFY))
33159477Swpaul		scp->devices &= ~ATA_ATA_MASTER;
33259477Swpaul	if (scp->devices & ATA_ATAPI_MASTER)
33359477Swpaul	    if (ata_getparam(scp, ATA_MASTER, ATA_C_ATAPI_IDENTIFY))
33484145Sjlemon		scp->devices &= ~ATA_ATAPI_MASTER;
335165360Sjkim    }
336165360Sjkim
337166037Sjkim#ifdef DEV_ATADISK
338165360Sjkim    /* now we know whats there, do the real attach, first the ATA disks */
339165360Sjkim    for (ctlr=0; ctlr<devclass_get_maxunit(ata_devclass); ctlr++) {
340165360Sjkim	if (!(scp = devclass_get_softc(ata_devclass, ctlr)))
341165360Sjkim	    continue;
342165360Sjkim	if (scp->devices & ATA_ATA_MASTER)
343165360Sjkim	    ad_attach(scp, ATA_MASTER);
344165360Sjkim	if (scp->devices & ATA_ATA_SLAVE)
345165360Sjkim	    ad_attach(scp, ATA_SLAVE);
346165360Sjkim    }
347165360Sjkim#endif
348165360Sjkim#if defined(DEV_ATAPICD) || defined(DEV_ATAPIFD) || defined(DEV_ATAPIST)
349165360Sjkim    /* then the atapi devices */
350165360Sjkim    for (ctlr=0; ctlr<devclass_get_maxunit(ata_devclass); ctlr++) {
351165360Sjkim	if (!(scp = devclass_get_softc(ata_devclass, ctlr)))
352165360Sjkim	    continue;
353165360Sjkim	if (scp->devices & ATA_ATAPI_MASTER)
354165360Sjkim	    atapi_attach(scp, ATA_MASTER);
355165360Sjkim	if (scp->devices & ATA_ATAPI_SLAVE)
356165360Sjkim	    atapi_attach(scp, ATA_SLAVE);
357165360Sjkim    }
358165360Sjkim#endif
359165360Sjkim    if (ata_delayed_attach) {
360165360Sjkim	config_intrhook_disestablish(ata_delayed_attach);
361165360Sjkim	free(ata_delayed_attach, M_ATA);
362165360Sjkim	ata_delayed_attach = NULL;
363165360Sjkim    }
364165360Sjkim}
365165360Sjkim
366165360Sjkimstatic void
367165360Sjkimata_intr(void *data)
368165360Sjkim{
369165360Sjkim    struct ata_softc *scp = (struct ata_softc *)data;
370165360Sjkim
371166037Sjkim    /*
372165360Sjkim     * on PCI systems we might share an interrupt line with another
373165360Sjkim     * device or our twin ATA channel, so call scp->intr_func to figure
374165360Sjkim     * out if it is really an interrupt we should process here
375165360Sjkim     */
376165360Sjkim    if (scp->intr_func && scp->intr_func(scp))
377165360Sjkim	return;
378165360Sjkim
379165360Sjkim    /* if drive is busy it didn't interrupt */
380165360Sjkim    if (ATA_INB(scp->r_altio, ATA_ALTSTAT) & ATA_S_BUSY)
381165360Sjkim	return;
382165360Sjkim
383165360Sjkim    /* clear interrupt and get status */
384165360Sjkim    scp->status = ATA_INB(scp->r_io, ATA_STATUS);
385165360Sjkim
386165360Sjkim    if (scp->status & ATA_S_ERROR)
387165360Sjkim	scp->error = ATA_INB(scp->r_io, ATA_ERROR);
388165360Sjkim
389165360Sjkim    /* find & call the responsible driver to process this interrupt */
390165360Sjkim    switch (scp->active) {
391150763Simp#ifdef DEV_ATADISK
39259477Swpaul    case ATA_ACTIVE_ATA:
39359477Swpaul	if (!scp->running || ad_interrupt(scp->running) == ATA_OP_CONTINUES)
39483029Swpaul	    return;
395165360Sjkim	break;
39659477Swpaul#endif
39759477Swpaul#if defined(DEV_ATAPICD) || defined(DEV_ATAPIFD) || defined(DEV_ATAPIST)
39859477Swpaul    case ATA_ACTIVE_ATAPI:
39959477Swpaul	if (!scp->running || atapi_interrupt(scp->running) == ATA_OP_CONTINUES)
400165360Sjkim	    return;
40159477Swpaul	break;
402165360Sjkim#endif
403165360Sjkim    case ATA_WAIT_INTR:
40459477Swpaul    case ATA_WAIT_INTR | ATA_REINITING:
40559477Swpaul	wakeup((caddr_t)scp);
40659477Swpaul	break;
40759477Swpaul
40859477Swpaul    case ATA_WAIT_READY:
40959477Swpaul    case ATA_WAIT_READY | ATA_REINITING:
41059477Swpaul	break;
41159477Swpaul
41259477Swpaul    case ATA_IDLE:
41359477Swpaul	if (scp->flags & ATA_QUEUED) {
41459477Swpaul	    scp->active = ATA_ACTIVE; /* XXX */
415165360Sjkim	    if (ata_service(scp) == ATA_OP_CONTINUES)
41659477Swpaul		return;
417165360Sjkim	}
41883029Swpaul	/* FALLTHROUGH */
41983029Swpaul
42083029Swpaul    default:
42195673Sphk#ifdef ATA_DEBUG
42283029Swpaul    {
42383029Swpaul	static int intr_count = 0;
42495673Sphk
42583029Swpaul	if (intr_count++ < 10)
42683029Swpaul	    ata_printf(scp, -1, "unwanted interrupt %d status = %02x\n",
42783029Swpaul		       intr_count, scp->status);
42883029Swpaul    }
42983029Swpaul#endif
43083029Swpaul    }
43183029Swpaul    scp->active &= ATA_REINITING;
43283029Swpaul    if (scp->active & ATA_REINITING)
43383029Swpaul	return;
43483029Swpaul    scp->running = NULL;
43583029Swpaul    ata_start(scp);
43683029Swpaul    return;
43783029Swpaul}
43883029Swpaul
43983029Swpaulvoid
44083029Swpaulata_start(struct ata_softc *scp)
44183029Swpaul{
44283029Swpaul#ifdef DEV_ATADISK
44383029Swpaul    struct ad_request *ad_request;
44483029Swpaul#endif
445165360Sjkim#if defined(DEV_ATAPICD) || defined(DEV_ATAPIFD) || defined(DEV_ATAPIST)
446165360Sjkim    struct atapi_request *atapi_request;
44759477Swpaul#endif
44859477Swpaul
44959477Swpaul    if (!atomic_cmpset_int(&scp->active, ATA_IDLE, ATA_ACTIVE))
450165360Sjkim	return;
45159477Swpaul
452166037Sjkim#ifdef DEV_ATADISK
45396026Sphk    /* find & call the responsible driver if anything on the ATA queue */
45459477Swpaul    if (TAILQ_EMPTY(&scp->ata_queue)) {
455165360Sjkim	if (scp->devices & (ATA_ATA_MASTER) && scp->dev_softc[MASTER])
456165360Sjkim	    ad_start((struct ad_softc *)scp->dev_softc[MASTER]);
457165360Sjkim	if (scp->devices & (ATA_ATA_SLAVE) && scp->dev_softc[SLAVE])
458166037Sjkim	    ad_start((struct ad_softc *)scp->dev_softc[SLAVE]);
459165361Sjkim    }
460165360Sjkim    if ((ad_request = TAILQ_FIRST(&scp->ata_queue))) {
461165360Sjkim	TAILQ_REMOVE(&scp->ata_queue, ad_request, chain);
46296026Sphk	scp->active = ATA_ACTIVE_ATA;
463165360Sjkim	scp->running = ad_request;
464165360Sjkim	if (ad_transfer(ad_request) == ATA_OP_CONTINUES)
46596026Sphk	    return;
466165360Sjkim    }
46796026Sphk
468165360Sjkim#endif
46959477Swpaul#if defined(DEV_ATAPICD) || defined(DEV_ATAPIFD) || defined(DEV_ATAPIST)
47059477Swpaul    /* find & call the responsible driver if anything on the ATAPI queue */
471114590Sps    if (TAILQ_EMPTY(&scp->atapi_queue)) {
472114590Sps	if (scp->devices & (ATA_ATAPI_MASTER) && scp->dev_softc[MASTER])
473114590Sps	    atapi_start((struct atapi_softc *)scp->dev_softc[MASTER]);
474114590Sps	if (scp->devices & (ATA_ATAPI_SLAVE) && scp->dev_softc[SLAVE])
475114590Sps	    atapi_start((struct atapi_softc *)scp->dev_softc[SLAVE]);
476114590Sps    }
477114590Sps    if ((atapi_request = TAILQ_FIRST(&scp->atapi_queue))) {
478114590Sps	TAILQ_REMOVE(&scp->atapi_queue, atapi_request, chain);
479164830Smarius	scp->active = ATA_ACTIVE_ATAPI;
480114590Sps	scp->running = atapi_request;
481114590Sps	atapi_transfer(atapi_request);
482114590Sps	return;
483114590Sps    }
484114590Sps#endif
485114590Sps    scp->active = ATA_IDLE;
486114590Sps}
487114590Sps
488114590Spsvoid
489114590Spsata_reset(struct ata_softc *scp)
490114590Sps{
491114590Sps    u_int8_t lsb, msb, ostat0, ostat1;
492114590Sps    u_int8_t stat0 = ATA_S_BUSY, stat1 = ATA_S_BUSY;
493114590Sps    int mask = 0, timeout;
494114590Sps
495114590Sps    /* do we have any signs of ATA/ATAPI HW being present ? */
496114590Sps    ATA_OUTB(scp->r_io, ATA_DRIVE, ATA_D_IBM | ATA_MASTER);
497114590Sps    DELAY(10);
498114590Sps    ostat0 = ATA_INB(scp->r_io, ATA_STATUS);
499114590Sps    if ((ostat0 & 0xf8) != 0xf8 && ostat0 != 0xa5)
500114590Sps	mask |= 0x01;
501114590Sps    ATA_OUTB(scp->r_io, ATA_DRIVE, ATA_D_IBM | ATA_SLAVE);
502114590Sps    DELAY(10);
503114590Sps    ostat1 = ATA_INB(scp->r_io, ATA_STATUS);
504114590Sps    if ((ostat1 & 0xf8) != 0xf8 && ostat1 != 0xa5)
505114590Sps	mask |= 0x02;
506114590Sps
507114590Sps    scp->devices = 0;
508114590Sps    if (!mask)
509114590Sps	return;
510114590Sps
511114590Sps    /* in some setups we dont want to test for a slave */
512114590Sps    if (scp->flags & ATA_NO_SLAVE)
513114590Sps	mask &= ~0x02;
514114590Sps
515114590Sps    if (bootverbose)
516114590Sps	ata_printf(scp, -1, "mask=%02x ostat0=%02x ostat2=%02x\n",
517114590Sps		   mask, ostat0, ostat1);
518114590Sps
519114590Sps    /* reset channel */
520114590Sps    ATA_OUTB(scp->r_altio, ATA_ALTSTAT, ATA_A_IDS | ATA_A_RESET);
521114590Sps    DELAY(10000);
522114590Sps    ATA_OUTB(scp->r_altio, ATA_ALTSTAT, ATA_A_IDS);
523114590Sps    DELAY(100000);
524114590Sps    ATA_INB(scp->r_io, ATA_ERROR);
525114590Sps
526114590Sps    /* wait for BUSY to go inactive */
527114590Sps    for (timeout = 0; timeout < 310000; timeout++) {
528114590Sps	if (stat0 & ATA_S_BUSY) {
529114590Sps            ATA_OUTB(scp->r_io, ATA_DRIVE, ATA_D_IBM | ATA_MASTER);
530114590Sps            DELAY(10);
531114590Sps            stat0 = ATA_INB(scp->r_io, ATA_STATUS);
532114590Sps            if (!(stat0 & ATA_S_BUSY)) {
533114590Sps                /* check for ATAPI signature while its still there */
534114590Sps		lsb = ATA_INB(scp->r_io, ATA_CYL_LSB);
535114590Sps		msb = ATA_INB(scp->r_io, ATA_CYL_MSB);
536166031Sjkim		if (bootverbose)
537114590Sps		    ata_printf(scp, ATA_MASTER,
538114590Sps			       "ATAPI probe %02x %02x\n", lsb, msb);
539114590Sps		if (lsb == ATAPI_MAGIC_LSB && msb == ATAPI_MAGIC_MSB)
540114590Sps                    scp->devices |= ATA_ATAPI_MASTER;
541114590Sps            }
542114590Sps        }
543114590Sps        if (stat1 & ATA_S_BUSY) {
544114590Sps            ATA_OUTB(scp->r_io, ATA_DRIVE, ATA_D_IBM | ATA_SLAVE);
545114590Sps            DELAY(10);
546114590Sps            stat1 = ATA_INB(scp->r_io, ATA_STATUS);
547114590Sps            if (!(stat1 & ATA_S_BUSY)) {
548114590Sps                /* check for ATAPI signature while its still there */
549114590Sps		lsb = ATA_INB(scp->r_io, ATA_CYL_LSB);
550114590Sps		msb = ATA_INB(scp->r_io, ATA_CYL_MSB);
551114590Sps		if (bootverbose)
552114590Sps		    ata_printf(scp, ATA_SLAVE,
553114590Sps			       "ATAPI probe %02x %02x\n", lsb, msb);
554166031Sjkim		if (lsb == ATAPI_MAGIC_LSB && msb == ATAPI_MAGIC_MSB)
555114590Sps                    scp->devices |= ATA_ATAPI_SLAVE;
556114590Sps            }
557114590Sps        }
558114590Sps	if (mask == 0x01)      /* wait for master only */
559114590Sps	    if (!(stat0 & ATA_S_BUSY))
560114590Sps		break;
561114590Sps	if (mask == 0x02)      /* wait for slave only */
562114590Sps	    if (!(stat1 & ATA_S_BUSY))
563114590Sps		break;
564114590Sps	if (mask == 0x03)      /* wait for both master & slave */
565114590Sps	    if (!(stat0 & ATA_S_BUSY) && !(stat1 & ATA_S_BUSY))
566114590Sps		break;
567114590Sps	DELAY(100);
568114590Sps    }
569114590Sps    DELAY(10);
570114590Sps    ATA_OUTB(scp->r_altio, ATA_ALTSTAT, ATA_A_4BIT);
571166031Sjkim
572135772Sps    if (stat0 & ATA_S_BUSY)
573135772Sps	mask &= ~0x01;
574135772Sps    if (stat1 & ATA_S_BUSY)
575135772Sps	mask &= ~0x02;
576135772Sps    if (bootverbose)
577166665Sjkim	ata_printf(scp, -1, "mask=%02x stat0=%02x stat1=%02x\n",
578166665Sjkim		   mask, stat0, stat1);
579166665Sjkim    if (!mask)
580166665Sjkim	return;
581166665Sjkim
582166665Sjkim    if (mask & 0x01 && ostat0 != 0x00 && !(scp->devices & ATA_ATAPI_MASTER)) {
583166665Sjkim        ATA_OUTB(scp->r_io, ATA_DRIVE, ATA_D_IBM | ATA_MASTER);
584166665Sjkim        DELAY(10);
585135772Sps	ATA_OUTB(scp->r_io, ATA_ERROR, 0x58);
586135772Sps	ATA_OUTB(scp->r_io, ATA_CYL_LSB, 0xa5);
587135772Sps	lsb = ATA_INB(scp->r_io, ATA_ERROR);
588135772Sps	msb = ATA_INB(scp->r_io, ATA_CYL_LSB);
589135772Sps	if (bootverbose)
590135772Sps	    ata_printf(scp, ATA_MASTER, "ATA probe %02x %02x\n", lsb, msb);
591135772Sps        if (lsb != 0x58 && msb == 0xa5)
592135772Sps            scp->devices |= ATA_ATA_MASTER;
593135772Sps    }
594166031Sjkim    if (mask & 0x02 && ostat1 != 0x00 && !(scp->devices & ATA_ATAPI_SLAVE)) {
595166031Sjkim        ATA_OUTB(scp->r_io, ATA_DRIVE, ATA_D_IBM | ATA_SLAVE);
596166031Sjkim        DELAY(10);
597166031Sjkim	ATA_OUTB(scp->r_io, ATA_ERROR, 0x58);
598166031Sjkim	ATA_OUTB(scp->r_io, ATA_CYL_LSB, 0xa5);
599166031Sjkim	lsb = ATA_INB(scp->r_io, ATA_ERROR);
600166031Sjkim	msb = ATA_INB(scp->r_io, ATA_CYL_LSB);
601166031Sjkim	if (bootverbose)
602166031Sjkim	    ata_printf(scp, ATA_SLAVE, "ATA probe %02x %02x\n", lsb, msb);
603166031Sjkim        if (lsb != 0x58 && msb == 0xa5)
604166031Sjkim            scp->devices |= ATA_ATA_SLAVE;
605166031Sjkim    }
606166031Sjkim    if (bootverbose)
607166031Sjkim	ata_printf(scp, -1, "devices=%02x\n", scp->devices);
608166031Sjkim}
609166031Sjkim
610166031Sjkimint
611166031Sjkimata_reinit(struct ata_softc *scp)
612166031Sjkim{
613166032Sjkim    int devices, misdev, newdev;
614166032Sjkim
615166032Sjkim    scp->active = ATA_REINITING;
616166032Sjkim    scp->running = NULL;
617166032Sjkim    devices = scp->devices;
618166032Sjkim    ata_printf(scp, -1, "resetting devices .. ");
619166032Sjkim    ata_reset(scp);
620166032Sjkim
621166032Sjkim    if ((misdev = devices & ~scp->devices)) {
622166032Sjkim#ifdef DEV_ATADISK
623166032Sjkim	if (misdev & ATA_ATA_MASTER && scp->dev_softc[MASTER])
624166032Sjkim	    ad_detach(scp->dev_softc[MASTER], 0);
625166032Sjkim	if (misdev & ATA_ATA_SLAVE && scp->dev_softc[SLAVE])
626166666Sjkim	    ad_detach(scp->dev_softc[SLAVE], 0);
627166032Sjkim#endif
628166032Sjkim#if defined(DEV_ATAPICD) || defined(DEV_ATAPIFD) || defined(DEV_ATAPIST)
629166032Sjkim	if (misdev & ATA_ATAPI_MASTER && scp->dev_softc[MASTER])
630166032Sjkim	    atapi_detach(scp->dev_softc[MASTER]);
631166666Sjkim	if (misdev & ATA_ATAPI_SLAVE && scp->dev_softc[SLAVE])
632166666Sjkim	    atapi_detach(scp->dev_softc[SLAVE]);
633166666Sjkim#endif
634166666Sjkim	if (misdev & ATA_ATA_MASTER || misdev & ATA_ATAPI_MASTER) {
635166666Sjkim	    free(scp->dev_param[MASTER], M_ATA);
636166666Sjkim	    scp->dev_param[MASTER] = NULL;
637166666Sjkim	}
638166666Sjkim	if (misdev & ATA_ATA_SLAVE || misdev & ATA_ATAPI_SLAVE) {
639166032Sjkim	    free(scp->dev_param[SLAVE], M_ATA);
640166032Sjkim	    scp->dev_param[SLAVE] = NULL;
641166032Sjkim	}
642166032Sjkim    }
643166032Sjkim    if ((newdev = ~devices & scp->devices)) {
644166032Sjkim	if (newdev & ATA_ATA_MASTER)
645166032Sjkim	    if (ata_getparam(scp, ATA_MASTER, ATA_C_ATA_IDENTIFY))
646166032Sjkim		newdev &= ~ATA_ATA_MASTER;
647166032Sjkim	if (newdev & ATA_ATA_SLAVE)
648166032Sjkim	    if (ata_getparam(scp, ATA_SLAVE, ATA_C_ATA_IDENTIFY))
649166032Sjkim		newdev &= ~ATA_ATA_SLAVE;
650166032Sjkim	if (newdev & ATA_ATAPI_MASTER)
651166032Sjkim	    if (ata_getparam(scp, ATA_MASTER, ATA_C_ATAPI_IDENTIFY))
652166032Sjkim		newdev &= ~ATA_ATAPI_MASTER;
653166032Sjkim	if (newdev & ATA_ATAPI_SLAVE)
654166032Sjkim	    if (ata_getparam(scp, ATA_SLAVE, ATA_C_ATAPI_IDENTIFY))
655166032Sjkim		newdev &= ~ATA_ATAPI_SLAVE;
656114590Sps	if (newdev)
657114590Sps	    printf("\n");
658166037Sjkim    }
659166037Sjkim    scp->active = ATA_IDLE;
660166037Sjkim#ifdef DEV_ATADISK
661166037Sjkim    if (newdev & ATA_ATA_MASTER && !scp->dev_softc[MASTER])
662114590Sps	ad_attach(scp, ATA_MASTER);
663114590Sps    else if (scp->devices & ATA_ATA_MASTER && scp->dev_softc[MASTER])
664114590Sps	ad_reinit((struct ad_softc *)scp->dev_softc[MASTER]);
665166037Sjkim    if (newdev & ATA_ATA_SLAVE && !scp->dev_softc[SLAVE])
666151370Sgrehan	ad_attach(scp, ATA_SLAVE);
667114590Sps    else if (scp->devices & (ATA_ATA_SLAVE) && scp->dev_softc[SLAVE])
668114590Sps	ad_reinit((struct ad_softc *)scp->dev_softc[SLAVE]);
669166031Sjkim#endif
670166037Sjkim#if defined(DEV_ATAPICD) || defined(DEV_ATAPIFD) || defined(DEV_ATAPIST)
671166031Sjkim    if (newdev & ATA_ATAPI_MASTER && !scp->dev_softc[MASTER])
672166031Sjkim	atapi_attach(scp, ATA_MASTER);
673114590Sps    else if (scp->devices & (ATA_ATAPI_MASTER) && scp->dev_softc[MASTER])
674114590Sps	atapi_reinit((struct atapi_softc *)scp->dev_softc[MASTER]);
675114590Sps    if (newdev & ATA_ATAPI_SLAVE && !scp->dev_softc[SLAVE])
676114590Sps	atapi_attach(scp, ATA_SLAVE);
677114590Sps    else if (scp->devices & (ATA_ATAPI_SLAVE) && scp->dev_softc[SLAVE])
678117659Swpaul	atapi_reinit((struct atapi_softc *)scp->dev_softc[SLAVE]);
679117659Swpaul#endif
680157642Sps    printf("done\n");
681157642Sps    ata_start(scp);
682165361Sjkim    return 0;
683157642Sps}
684157642Sps
685157642Spsstatic int
686117659Swpaulata_service(struct ata_softc *scp)
687157642Sps{
688157642Sps    /* do we have a SERVICE request from the drive ? */
689166031Sjkim    if ((scp->status & (ATA_S_SERVICE|ATA_S_ERROR|ATA_S_DRQ)) == ATA_S_SERVICE){
690166031Sjkim	ATA_OUTB(scp->r_bmio, ATA_BMSTAT_PORT,
691166031Sjkim		 ata_dmastatus(scp) | ATA_BMSTAT_INTERRUPT);
692166031Sjkim#ifdef DEV_ATADISK
693166031Sjkim	if ((ATA_INB(scp->r_io, ATA_DRIVE) & ATA_SLAVE) == ATA_MASTER) {
694166031Sjkim	    if ((scp->devices & ATA_ATA_MASTER) && scp->dev_softc[MASTER])
695166031Sjkim		return ad_service((struct ad_softc *)scp->dev_softc[MASTER], 0);
696166031Sjkim	}
697166031Sjkim	else {
698157642Sps	    if ((scp->devices & ATA_ATA_SLAVE) && scp->dev_softc[SLAVE])
699166032Sjkim		return ad_service((struct ad_softc *)scp->dev_softc[SLAVE], 0);
700157642Sps	}
701166032Sjkim#endif
702166032Sjkim    }
703166032Sjkim    return ATA_OP_FINISHED;
704166032Sjkim}
705166032Sjkim
706166032Sjkimint
707166032Sjkimata_wait(struct ata_softc *scp, int device, u_int8_t mask)
708166032Sjkim{
709166032Sjkim    int timeout = 0;
710166032Sjkim
711166032Sjkim    DELAY(1);
712164830Smarius    while (timeout < 5000000) {	/* timeout 5 secs */
713166032Sjkim	scp->status = ATA_INB(scp->r_io, ATA_STATUS);
714166032Sjkim
715157642Sps	/* if drive fails status, reselect the drive just to be sure */
716166032Sjkim	if (scp->status == 0xff) {
717166032Sjkim	    ata_printf(scp, device, "no status, reselecting device\n");
718166032Sjkim	    ATA_OUTB(scp->r_io, ATA_DRIVE, ATA_D_IBM | device);
719166032Sjkim	    DELAY(10);
720119157Sambrisko	    scp->status = ATA_INB(scp->r_io, ATA_STATUS);
721114590Sps	    if (scp->status == 0xff)
722		return -1;
723	}
724
725	/* are we done ? */
726	if (!(scp->status & ATA_S_BUSY))
727	    break;
728
729	if (timeout > 1000) {
730	    timeout += 1000;
731	    DELAY(1000);
732	}
733	else {
734	    timeout += 10;
735	    DELAY(10);
736	}
737    }
738    if (scp->status & ATA_S_ERROR)
739	scp->error = ATA_INB(scp->r_io, ATA_ERROR);
740    if (timeout >= 5000000)
741	return -1;
742    if (!mask)
743	return (scp->status & ATA_S_ERROR);
744
745    /* Wait 50 msec for bits wanted. */
746    timeout = 5000;
747    while (timeout--) {
748	scp->status = ATA_INB(scp->r_io, ATA_STATUS);
749	if ((scp->status & mask) == mask) {
750	    if (scp->status & ATA_S_ERROR)
751		scp->error = ATA_INB(scp->r_io, ATA_ERROR);
752	    return (scp->status & ATA_S_ERROR);
753	}
754	DELAY (10);
755    }
756    return -1;
757}
758
759int
760ata_command(struct ata_softc *scp, int device, u_int8_t command,
761	   u_int16_t cylinder, u_int8_t head, u_int8_t sector,
762	   u_int8_t count, u_int8_t feature, int flags)
763{
764    int error = 0;
765#ifdef ATA_DEBUG
766    ata_printf(scp, device, "ata_command: addr=%04x, cmd=%02x, "
767	       "c=%d, h=%d, s=%d, count=%d, feature=%d, flags=%02x\n",
768	       rman_get_start(scp->r_io), command, cylinder, head, sector,
769	       count, feature, flags);
770#endif
771
772    /* disable interrupt from device */
773    if (scp->flags & ATA_QUEUED)
774	ATA_OUTB(scp->r_altio, ATA_ALTSTAT, ATA_A_IDS | ATA_A_4BIT);
775
776    /* select device */
777    ATA_OUTB(scp->r_io, ATA_DRIVE, ATA_D_IBM | device);
778
779    /* ready to issue command ? */
780    if (ata_wait(scp, device, 0) < 0) {
781	ata_printf(scp, device,
782		   "timeout waiting to give command=%02x s=%02x e=%02x\n",
783		   command, scp->status, scp->error);
784	return -1;
785    }
786
787    ATA_OUTB(scp->r_io, ATA_FEATURE, feature);
788    ATA_OUTB(scp->r_io, ATA_COUNT, count);
789    ATA_OUTB(scp->r_io, ATA_SECTOR, sector);
790    ATA_OUTB(scp->r_io, ATA_CYL_MSB, cylinder >> 8);
791    ATA_OUTB(scp->r_io, ATA_CYL_LSB, cylinder);
792    ATA_OUTB(scp->r_io, ATA_DRIVE, ATA_D_IBM | device | head);
793
794    switch (flags) {
795    case ATA_WAIT_INTR:
796	scp->active |= ATA_WAIT_INTR;
797	asleep((caddr_t)scp, PRIBIO, "atacmd", 10 * hz);
798	ATA_OUTB(scp->r_io, ATA_CMD, command);
799
800	/* enable interrupt */
801	if (scp->flags & ATA_QUEUED)
802	    ATA_OUTB(scp->r_altio, ATA_ALTSTAT, ATA_A_4BIT);
803
804	if (await(PRIBIO, 10 * hz)) {
805	    ata_printf(scp, device, "ata_command: timeout waiting for intr\n");
806	    scp->active &= ~ATA_WAIT_INTR;
807	    error = -1;
808	}
809	break;
810
811    case ATA_WAIT_READY:
812	scp->active |= ATA_WAIT_READY;
813	ATA_OUTB(scp->r_io, ATA_CMD, command);
814	if (ata_wait(scp, device, ATA_S_READY) < 0) {
815	    ata_printf(scp, device,
816		       "timeout waiting for command=%02x s=%02x e=%02x\n",
817		       command, scp->status, scp->error);
818	    error = -1;
819	}
820	scp->active &= ~ATA_WAIT_READY;
821	break;
822
823    case ATA_IMMEDIATE:
824	ATA_OUTB(scp->r_io, ATA_CMD, command);
825	break;
826
827    default:
828	ata_printf(scp, device, "DANGER: illegal interrupt flag=%s\n",
829		   active2str(flags));
830    }
831    /* enable interrupt */
832    if (scp->flags & ATA_QUEUED)
833	ATA_OUTB(scp->r_altio, ATA_ALTSTAT, ATA_A_4BIT);
834    return error;
835}
836
837int
838ata_get_lun(u_int32_t *map)
839{
840    int lun = ffs(~*map) - 1;
841
842    *map |= (1 << lun);
843    return lun;
844}
845
846int
847ata_test_lun(u_int32_t *map, int lun)
848{
849    return (*map & (1 << lun));
850}
851
852void
853ata_free_lun(u_int32_t *map, int lun)
854{
855    *map &= ~(1 << lun);
856}
857
858int
859ata_printf(struct ata_softc *scp, int device, const char * fmt, ...)
860{
861    va_list ap;
862    int ret;
863
864    if (device == -1)
865	ret = printf("ata%d: ", device_get_unit(scp->dev));
866    else
867	ret = printf("ata%d-%s: ", device_get_unit(scp->dev),
868		     (device == ATA_MASTER) ? "master" : "slave");
869    va_start(ap, fmt);
870    ret += vprintf(fmt, ap);
871    va_end(ap);
872    return ret;
873}
874
875char *
876ata_mode2str(int mode)
877{
878    switch (mode) {
879    case ATA_PIO: return "BIOSPIO";
880    case ATA_PIO0: return "PIO0";
881    case ATA_PIO1: return "PIO1";
882    case ATA_PIO2: return "PIO2";
883    case ATA_PIO3: return "PIO3";
884    case ATA_PIO4: return "PIO4";
885    case ATA_WDMA2: return "WDMA2";
886    case ATA_UDMA2: return "UDMA33";
887    case ATA_UDMA4: return "UDMA66";
888    case ATA_UDMA5: return "UDMA100";
889    case ATA_DMA: return "BIOSDMA";
890    default: return "???";
891    }
892}
893
894int
895ata_pio2mode(int pio)
896{
897    switch (pio) {
898    default:
899    case 0: return ATA_PIO0;
900    case 1: return ATA_PIO1;
901    case 2: return ATA_PIO2;
902    case 3: return ATA_PIO3;
903    case 4: return ATA_PIO4;
904    }
905}
906
907int
908ata_pmode(struct ata_params *ap)
909{
910    if (ap->atavalid & ATA_FLAG_64_70) {
911	if (ap->apiomodes & 2)
912	    return 4;
913	if (ap->apiomodes & 1)
914	    return 3;
915    }
916    if (ap->opiomode == 2)
917	return 2;
918    if (ap->opiomode == 1)
919	return 1;
920    if (ap->opiomode == 0)
921	return 0;
922    return -1;
923}
924
925int
926ata_wmode(struct ata_params *ap)
927{
928    if (ap->wdmamodes & 4)
929	return 2;
930    if (ap->wdmamodes & 2)
931	return 1;
932    if (ap->wdmamodes & 1)
933	return 0;
934    return -1;
935}
936
937int
938ata_umode(struct ata_params *ap)
939{
940    if (ap->atavalid & ATA_FLAG_88) {
941	if (ap->udmamodes & 0x20)
942	    return 5;
943	if (ap->udmamodes & 0x10)
944	    return 4;
945	if (ap->udmamodes & 0x08)
946	    return 3;
947	if (ap->udmamodes & 0x04)
948	    return 2;
949	if (ap->udmamodes & 0x02)
950	    return 1;
951	if (ap->udmamodes & 0x01)
952	    return 0;
953    }
954    return -1;
955}
956
957static char *
958active2str(int active)
959{
960    static char buf[8];
961
962    switch (active) {
963    case ATA_IDLE:
964	return("ATA_IDLE");
965    case ATA_IMMEDIATE:
966	return("ATA_IMMEDIATE");
967    case ATA_WAIT_INTR:
968	return("ATA_WAIT_INTR");
969    case ATA_WAIT_READY:
970	return("ATA_WAIT_READY");
971    case ATA_ACTIVE:
972	return("ATA_ACTIVE");
973    case ATA_ACTIVE_ATA:
974	return("ATA_ACTIVE_ATA");
975    case ATA_ACTIVE_ATAPI:
976	return("ATA_ACTIVE_ATAPI");
977    case ATA_REINITING:
978	return("ATA_REINITING");
979    default:
980	sprintf(buf, "0x%02x", active);
981	return buf;
982    }
983}
984
985static void
986bswap(int8_t *buf, int len)
987{
988    u_int16_t *ptr = (u_int16_t*)(buf + len);
989
990    while (--ptr >= (u_int16_t*)buf)
991	*ptr = ntohs(*ptr);
992}
993
994static void
995btrim(int8_t *buf, int len)
996{
997    int8_t *ptr;
998
999    for (ptr = buf; ptr < buf+len; ++ptr)
1000	if (!*ptr)
1001	    *ptr = ' ';
1002    for (ptr = buf + len - 1; ptr >= buf && *ptr == ' '; --ptr)
1003	*ptr = 0;
1004}
1005
1006static void
1007bpack(int8_t *src, int8_t *dst, int len)
1008{
1009    int i, j, blank;
1010
1011    for (i = j = blank = 0 ; i < len; i++) {
1012	if (blank && src[i] == ' ') continue;
1013	if (blank && src[i] != ' ') {
1014	    dst[j++] = src[i];
1015	    blank = 0;
1016	    continue;
1017	}
1018	if (src[i] == ' ') {
1019	    blank = 1;
1020	    if (i == 0)
1021		continue;
1022	}
1023	dst[j++] = src[i];
1024    }
1025    if (j < len)
1026	dst[j] = 0x00;
1027}
1028
1029static void
1030ata_change_mode(struct ata_softc *scp, int device, int mode)
1031{
1032    int s = splbio();
1033
1034    while (!atomic_cmpset_int(&scp->active, ATA_IDLE, ATA_ACTIVE))
1035	tsleep((caddr_t)&s, PRIBIO, "atachm", hz/4);
1036
1037    ata_dmainit(scp, device, ata_pmode(ATA_PARAM(scp, device)),
1038		mode < ATA_DMA ?  -1 : ata_wmode(ATA_PARAM(scp, device)),
1039		mode < ATA_DMA ?  -1 : ata_umode(ATA_PARAM(scp, device)));
1040    scp->active = ATA_IDLE;
1041    ata_start(scp);
1042    splx(s);
1043}
1044
1045static int
1046sysctl_hw_ata(SYSCTL_HANDLER_ARGS)
1047{
1048    struct ata_softc *scp;
1049    int ctlr, error, i;
1050
1051    /* readout internal state */
1052    bzero(ata_conf, sizeof(ata_conf));
1053    for (ctlr=0; ctlr<devclass_get_maxunit(ata_devclass); ctlr++) {
1054	if (!(scp = devclass_get_softc(ata_devclass, ctlr)))
1055	    continue;
1056	for (i = 0; i < 2; i++) {
1057	    if (!scp->dev_softc[i])
1058		strcat(ata_conf, "---,");
1059	    else if (scp->mode[i] >= ATA_DMA)
1060		strcat(ata_conf, "dma,");
1061	    else
1062		strcat(ata_conf, "pio,");
1063	}
1064    }
1065    error = sysctl_handle_string(oidp, ata_conf, sizeof(ata_conf), req);
1066    if (error == 0 && req->newptr != NULL) {
1067	char *ptr = ata_conf;
1068
1069        /* update internal state */
1070	i = 0;
1071        while (*ptr) {
1072	    if (!strncmp(ptr, "pio", 3) || !strncmp(ptr, "PIO", 3)) {
1073		if ((scp = devclass_get_softc(ata_devclass, i >> 1)) &&
1074		    scp->dev_softc[i & 1] && scp->mode[i & 1] >= ATA_DMA)
1075		    ata_change_mode(scp, (i & 1)?ATA_SLAVE:ATA_MASTER, ATA_PIO);
1076	    }
1077	    else if (!strncmp(ptr, "dma", 3) || !strncmp(ptr, "DMA", 3)) {
1078		if ((scp = devclass_get_softc(ata_devclass, i >> 1)) &&
1079		    scp->dev_softc[i & 1] && scp->mode[i & 1] < ATA_DMA)
1080		    ata_change_mode(scp, (i & 1)?ATA_SLAVE:ATA_MASTER, ATA_DMA);
1081	    }
1082	    else if (strncmp(ptr, "---", 3))
1083		break;
1084	    ptr+=3;
1085	    if (*ptr++ != ',' ||
1086		++i > (devclass_get_maxunit(ata_devclass) << 1))
1087		break;
1088        }
1089    }
1090    return error;
1091}
1092SYSCTL_PROC(_hw, OID_AUTO, atamodes, CTLTYPE_STRING | CTLFLAG_RW,
1093            0, sizeof(ata_conf), sysctl_hw_ata, "A", "");
1094
1095static void
1096ata_init(void)
1097{
1098    /* register boot attach to be run when interrupts are enabled */
1099    if (!(ata_delayed_attach = (struct intr_config_hook *)
1100			       malloc(sizeof(struct intr_config_hook),
1101				      M_TEMP, M_NOWAIT | M_ZERO))) {
1102	printf("ata: malloc of delayed attach hook failed\n");
1103	return;
1104    }
1105
1106    ata_delayed_attach->ich_func = (void*)ata_boot_attach;
1107    if (config_intrhook_establish(ata_delayed_attach) != 0) {
1108	printf("ata: config_intrhook_establish failed\n");
1109	free(ata_delayed_attach, M_TEMP);
1110    }
1111}
1112SYSINIT(atadev, SI_SUB_DRIVERS, SI_ORDER_SECOND, ata_init, NULL)
1113