diff options
Diffstat (limited to 'sys/dev/ata/ata-all.c')
-rw-r--r-- | sys/dev/ata/ata-all.c | 1065 |
1 files changed, 553 insertions, 512 deletions
diff --git a/sys/dev/ata/ata-all.c b/sys/dev/ata/ata-all.c index f8d2d9e..10c5381 100644 --- a/sys/dev/ata/ata-all.c +++ b/sys/dev/ata/ata-all.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 1998,1999,2000,2001 Søren Schmidt <sos@FreeBSD.org> + * Copyright (c) 1998,1999,2000,2001,2002 Søren Schmidt <sos@FreeBSD.org> * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -51,10 +51,11 @@ #endif #include <dev/ata/ata-all.h> #include <dev/ata/ata-disk.h> +#include <dev/ata/ata-raid.h> #include <dev/ata/atapi-all.h> /* device structures */ -static d_ioctl_t ataioctl; +static d_ioctl_t ataioctl; static struct cdevsw ata_cdevsw = { /* open */ nullopen, /* close */ nullclose, @@ -74,12 +75,12 @@ static struct cdevsw ata_cdevsw = { /* prototypes */ static void ata_boot_attach(void); static void ata_intr(void *); -static int ata_getparam(struct ata_softc *, int, u_int8_t); -static int ata_service(struct ata_softc *); +static int ata_getparam(struct ata_device *, u_int8_t); +static int ata_service(struct ata_channel *); static void bswap(int8_t *, int); static void btrim(int8_t *, int); static void bpack(int8_t *, int8_t *, int); -static void ata_change_mode(struct ata_softc *, int, int); +static void ata_change_mode(struct ata_device *, int); /* sysctl vars */ SYSCTL_NODE(_hw, OID_AUTO, ata, CTLFLAG_RD, 0, "ATA driver parameters"); @@ -91,120 +92,118 @@ devclass_t ata_devclass; static struct intr_config_hook *ata_delayed_attach = NULL; static MALLOC_DEFINE(M_ATA, "ATA generic", "ATA driver generic layer"); -/* misc defines */ -#define MASTER 0 -#define SLAVE 1 - int ata_probe(device_t dev) { - struct ata_softc *scp; + struct ata_channel *ch; int rid; - if (!dev) - return ENXIO; - scp = device_get_softc(dev); - if (!scp) + if (!dev || !(ch = device_get_softc(dev))) return ENXIO; - if (scp->r_io || scp->r_altio || scp->r_irq) + + if (ch->r_io || ch->r_altio || ch->r_irq) return EEXIST; /* initialize the softc basics */ - scp->active = ATA_IDLE; - scp->dev = dev; + ch->active = ATA_IDLE; + ch->dev = dev; rid = ATA_IOADDR_RID; - scp->r_io = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 0, ~0, - ATA_IOSIZE, RF_ACTIVE); - if (!scp->r_io) + ch->r_io = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 0, ~0, + ATA_IOSIZE, RF_ACTIVE); + if (!ch->r_io) goto failure; rid = ATA_ALTADDR_RID; - scp->r_altio = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 0, ~0, - ATA_ALTIOSIZE, RF_ACTIVE); - if (!scp->r_altio) + ch->r_altio = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 0, ~0, + ATA_ALTIOSIZE, RF_ACTIVE); + if (!ch->r_altio) goto failure; rid = ATA_BMADDR_RID; - scp->r_bmio = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 0, ~0, - ATA_BMIOSIZE, RF_ACTIVE); + ch->r_bmio = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 0, ~0, + ATA_BMIOSIZE, RF_ACTIVE); if (bootverbose) - ata_printf(scp, -1, "iobase=0x%04x altiobase=0x%04x bmaddr=0x%04x\n", - (int)rman_get_start(scp->r_io), - (int)rman_get_start(scp->r_altio), - (scp->r_bmio) ? (int)rman_get_start(scp->r_bmio) : 0); - - ata_reset(scp); - - TAILQ_INIT(&scp->ata_queue); - TAILQ_INIT(&scp->atapi_queue); + ata_printf(ch, -1, "iobase=0x%04x altiobase=0x%04x bmaddr=0x%04x\n", + (int)rman_get_start(ch->r_io), + (int)rman_get_start(ch->r_altio), + (ch->r_bmio) ? (int)rman_get_start(ch->r_bmio) : 0); + + ata_reset(ch); + + ch->device[MASTER].channel = ch; + ch->device[MASTER].unit = ATA_MASTER; + ch->device[MASTER].mode = ATA_PIO; + ch->device[SLAVE].channel = ch; + ch->device[SLAVE].unit = ATA_SLAVE; + ch->device[SLAVE].mode = ATA_PIO; + TAILQ_INIT(&ch->ata_queue); + TAILQ_INIT(&ch->atapi_queue); return 0; failure: - if (scp->r_io) - bus_release_resource(dev, SYS_RES_IOPORT, ATA_IOADDR_RID, scp->r_io); - if (scp->r_altio) - bus_release_resource(dev, SYS_RES_IOPORT, ATA_ALTADDR_RID,scp->r_altio); - if (scp->r_bmio) - bus_release_resource(dev, SYS_RES_IOPORT, ATA_BMADDR_RID, scp->r_bmio); + if (ch->r_io) + bus_release_resource(dev, SYS_RES_IOPORT, ATA_IOADDR_RID, ch->r_io); + if (ch->r_altio) + bus_release_resource(dev, SYS_RES_IOPORT, ATA_ALTADDR_RID, ch->r_altio); + if (ch->r_bmio) + bus_release_resource(dev, SYS_RES_IOPORT, ATA_BMADDR_RID, ch->r_bmio); if (bootverbose) - ata_printf(scp, -1, "probe allocation failed\n"); + ata_printf(ch, -1, "probe allocation failed\n"); return ENXIO; } int ata_attach(device_t dev) { - struct ata_softc *scp; + struct ata_channel *ch; int error, rid; - if (!dev) - return ENXIO; - scp = device_get_softc(dev); - if (!scp) + if (!dev || !(ch = device_get_softc(dev))) return ENXIO; rid = ATA_IRQ_RID; - scp->r_irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 0, ~0, 1, - RF_SHAREABLE | RF_ACTIVE); - if (!scp->r_irq) { - ata_printf(scp, -1, "unable to allocate interrupt\n"); + ch->r_irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 0, ~0, 1, + RF_SHAREABLE | RF_ACTIVE); + if (!ch->r_irq) { + ata_printf(ch, -1, "unable to allocate interrupt\n"); return ENXIO; } - if ((error = bus_setup_intr(dev, scp->r_irq, INTR_TYPE_BIO|INTR_ENTROPY, - ata_intr, scp, &scp->ih))) + if ((error = bus_setup_intr(dev, ch->r_irq, INTR_TYPE_BIO | INTR_ENTROPY, + ata_intr, ch, &ch->ih))) return error; /* * do not attach devices if we are in early boot, this is done later * when interrupts are enabled by a hook into the boot process. - * otherwise attach what the probe has found in scp->devices. + * otherwise attach what the probe has found in ch->devices. */ if (!ata_delayed_attach) { - if (scp->devices & ATA_ATA_SLAVE) - if (ata_getparam(scp, ATA_SLAVE, ATA_C_ATA_IDENTIFY)) - scp->devices &= ~ATA_ATA_SLAVE; - if (scp->devices & ATA_ATAPI_SLAVE) - if (ata_getparam(scp, ATA_SLAVE, ATA_C_ATAPI_IDENTIFY)) - scp->devices &= ~ATA_ATAPI_SLAVE; - if (scp->devices & ATA_ATA_MASTER) - if (ata_getparam(scp, ATA_MASTER, ATA_C_ATA_IDENTIFY)) - scp->devices &= ~ATA_ATA_MASTER; - if (scp->devices & ATA_ATAPI_MASTER) - if (ata_getparam(scp, ATA_MASTER,ATA_C_ATAPI_IDENTIFY)) - scp->devices &= ~ATA_ATAPI_MASTER; + if (ch->devices & ATA_ATA_SLAVE) + if (ata_getparam(&ch->device[SLAVE], ATA_C_ATA_IDENTIFY)) + ch->devices &= ~ATA_ATA_SLAVE; + if (ch->devices & ATA_ATAPI_SLAVE) + if (ata_getparam(&ch->device[SLAVE], ATA_C_ATAPI_IDENTIFY)) + ch->devices &= ~ATA_ATAPI_SLAVE; + if (ch->devices & ATA_ATA_MASTER) + if (ata_getparam(&ch->device[MASTER], ATA_C_ATA_IDENTIFY)) + ch->devices &= ~ATA_ATA_MASTER; + if (ch->devices & ATA_ATAPI_MASTER) + if (ata_getparam(&ch->device[MASTER] ,ATA_C_ATAPI_IDENTIFY)) + ch->devices &= ~ATA_ATAPI_MASTER; #ifdef DEV_ATADISK - if (scp->devices & ATA_ATA_MASTER) - ad_attach(scp, ATA_MASTER); - if (scp->devices & ATA_ATA_SLAVE) - ad_attach(scp, ATA_SLAVE); + if (ch->devices & ATA_ATA_MASTER) + ad_attach(&ch->device[MASTER]); + if (ch->devices & ATA_ATA_SLAVE) + ad_attach(&ch->device[SLAVE]); #endif #if defined(DEV_ATAPICD) || defined(DEV_ATAPIFD) || defined(DEV_ATAPIST) - if (scp->devices & ATA_ATAPI_MASTER) - atapi_attach(scp, ATA_MASTER); - if (scp->devices & ATA_ATAPI_SLAVE) - atapi_attach(scp, ATA_SLAVE); + if (ch->devices & ATA_ATAPI_MASTER) + atapi_attach(&ch->device[MASTER]); + if (ch->devices & ATA_ATAPI_SLAVE) + atapi_attach(&ch->device[SLAVE]); #endif + /* we should probe & attach RAID's here as well SOS XXX */ } return 0; } @@ -212,88 +211,85 @@ ata_attach(device_t dev) int ata_detach(device_t dev) { - struct ata_softc *scp; + struct ata_channel *ch; int s; - if (!dev) - return ENXIO; - scp = device_get_softc(dev); - if (!scp) + if (!dev || !(ch = device_get_softc(dev))) return ENXIO; - /* make sure channel is not busy SOS XXX */ + /* make sure channel is not busy */ s = splbio(); - while (!atomic_cmpset_int(&scp->active, ATA_IDLE, ATA_CONTROL)) - tsleep((caddr_t)&s, PRIBIO, "atachm", hz/4); + while (!atomic_cmpset_int(&ch->active, ATA_IDLE, ATA_CONTROL)) + tsleep((caddr_t)&s, PRIBIO, "atarel", hz/4); splx(s); /* disable interrupts on devices */ - ATA_OUTB(scp->r_io, ATA_DRIVE, ATA_D_IBM | ATA_MASTER); - ATA_OUTB(scp->r_altio, ATA_ALTSTAT, ATA_A_IDS | ATA_A_4BIT); - ATA_OUTB(scp->r_io, ATA_DRIVE, ATA_D_IBM | ATA_SLAVE); - ATA_OUTB(scp->r_altio, ATA_ALTSTAT, ATA_A_IDS | ATA_A_4BIT); + ATA_OUTB(ch->r_io, ATA_DRIVE, ATA_D_IBM | ATA_MASTER); + ATA_OUTB(ch->r_altio, ATA_ALTSTAT, ATA_A_IDS | ATA_A_4BIT); + ATA_OUTB(ch->r_io, ATA_DRIVE, ATA_D_IBM | ATA_SLAVE); + ATA_OUTB(ch->r_altio, ATA_ALTSTAT, ATA_A_IDS | ATA_A_4BIT); #ifdef DEV_ATADISK - if (scp->devices & ATA_ATA_MASTER && scp->dev_softc[MASTER]) - ad_detach(scp->dev_softc[MASTER], 1); - if (scp->devices & ATA_ATA_SLAVE && scp->dev_softc[SLAVE]) - ad_detach(scp->dev_softc[SLAVE], 1); + if (ch->devices & ATA_ATA_MASTER && ch->device[MASTER].driver) + ad_detach(&ch->device[MASTER], 1); + if (ch->devices & ATA_ATA_SLAVE && ch->device[SLAVE].driver) + ad_detach(&ch->device[SLAVE], 1); #endif #if defined(DEV_ATAPICD) || defined(DEV_ATAPIFD) || defined(DEV_ATAPIST) - if (scp->devices & ATA_ATAPI_MASTER && scp->dev_softc[MASTER]) - atapi_detach(scp->dev_softc[MASTER]); - if (scp->devices & ATA_ATAPI_SLAVE && scp->dev_softc[SLAVE]) - atapi_detach(scp->dev_softc[SLAVE]); + if (ch->devices & ATA_ATAPI_MASTER && ch->device[MASTER].driver) + atapi_detach(&ch->device[MASTER]); + if (ch->devices & ATA_ATAPI_SLAVE && ch->device[SLAVE].driver) + atapi_detach(&ch->device[SLAVE]); #endif - if (scp->dev_param[MASTER]) { - free(scp->dev_param[MASTER], M_ATA); - scp->dev_param[MASTER] = NULL; + if (ch->device[MASTER].param) { + free(ch->device[MASTER].param, M_ATA); + ch->device[MASTER].param = NULL; } - if (scp->dev_param[SLAVE]) { - free(scp->dev_param[SLAVE], M_ATA); - scp->dev_param[SLAVE] = NULL; + if (ch->device[SLAVE].param) { + free(ch->device[SLAVE].param, M_ATA); + ch->device[SLAVE].param = NULL; } - scp->dev_softc[MASTER] = NULL; - scp->dev_softc[SLAVE] = NULL; - scp->mode[MASTER] = ATA_PIO; - scp->mode[SLAVE] = ATA_PIO; - scp->devices = 0; - - bus_teardown_intr(dev, scp->r_irq, scp->ih); - bus_release_resource(dev, SYS_RES_IRQ, ATA_IRQ_RID, scp->r_irq); - if (scp->r_bmio) - bus_release_resource(dev, SYS_RES_IOPORT, ATA_BMADDR_RID, scp->r_bmio); - bus_release_resource(dev, SYS_RES_IOPORT, ATA_ALTADDR_RID, scp->r_altio); - bus_release_resource(dev, SYS_RES_IOPORT, ATA_IOADDR_RID, scp->r_io); - scp->r_io = NULL; - scp->r_altio = NULL; - scp->r_bmio = NULL; - scp->r_irq = NULL; - scp->active = ATA_IDLE; + ch->device[MASTER].driver = NULL; + ch->device[SLAVE].driver = NULL; + ch->device[MASTER].mode = ATA_PIO; + ch->device[SLAVE].mode = ATA_PIO; + ch->devices = 0; + + bus_teardown_intr(dev, ch->r_irq, ch->ih); + bus_release_resource(dev, SYS_RES_IRQ, ATA_IRQ_RID, ch->r_irq); + if (ch->r_bmio) + bus_release_resource(dev, SYS_RES_IOPORT, ATA_BMADDR_RID, ch->r_bmio); + bus_release_resource(dev, SYS_RES_IOPORT, ATA_ALTADDR_RID, ch->r_altio); + bus_release_resource(dev, SYS_RES_IOPORT, ATA_IOADDR_RID, ch->r_io); + ch->r_io = NULL; + ch->r_altio = NULL; + ch->r_bmio = NULL; + ch->r_irq = NULL; + ch->active = ATA_IDLE; return 0; } int ata_resume(device_t dev) { - struct ata_softc *scp = device_get_softc(dev); - - ata_reinit(scp); - return 0; + return ata_reinit(device_get_softc(dev)); } static int ataioctl(dev_t dev, u_long cmd, caddr_t addr, int32_t flag, struct thread *td) { struct ata_cmd *iocmd = (struct ata_cmd *)addr; + struct ata_device *atadev; + struct ata_channel *ch; device_t device; int error; if (cmd != IOCATA) return ENOTTY; - if (iocmd->channel >= devclass_get_maxunit(ata_devclass)) + if (iocmd->device < -1 || iocmd->device > SLAVE || iocmd->channel < 0 || + iocmd->channel >= devclass_get_maxunit(ata_devclass)) return ENXIO; if (!(device = devclass_get_device(ata_devclass, iocmd->channel))) @@ -315,119 +311,112 @@ ataioctl(dev_t dev, u_long cmd, caddr_t addr, int32_t flag, struct thread *td) } case ATAREINIT: { - struct ata_softc *scp; int s; - scp = device_get_softc(device); - if (!scp) + if (!(ch = device_get_softc(device))) return ENODEV; - /* make sure channel is not busy SOS XXX */ + /* make sure channel is not busy */ s = splbio(); - while (!atomic_cmpset_int(&scp->active, ATA_IDLE, ATA_ACTIVE)) - tsleep((caddr_t)&s, PRIBIO, "atachm", hz/4); - error = ata_reinit(scp); + while (!atomic_cmpset_int(&ch->active, ATA_IDLE, ATA_ACTIVE)) + tsleep((caddr_t)&s, PRIBIO, "atarin", hz/4); + error = ata_reinit(ch); splx(s); return error; } - case ATAGMODE: { - struct ata_softc *scp; - - scp = device_get_softc(device); - if (!scp) + case ATAGMODE: + if (!(ch = device_get_softc(device))) return ENODEV; - if (scp->dev_param[MASTER]) - iocmd->u.mode.mode[MASTER] = scp->mode[MASTER]; + + if ((iocmd->device == MASTER || iocmd->device == -1) && + ch->device[MASTER].driver) + iocmd->u.mode.mode[MASTER] = ch->device[MASTER].mode; else iocmd->u.mode.mode[MASTER] = -1; - if (scp->dev_param[SLAVE]) - iocmd->u.mode.mode[SLAVE] = scp->mode[SLAVE]; + + if ((iocmd->device == SLAVE || iocmd->device == -1) && + ch->device[SLAVE].param) + iocmd->u.mode.mode[SLAVE] = ch->device[SLAVE].mode; else iocmd->u.mode.mode[SLAVE] = -1; return 0; - } - case ATASMODE: { - struct ata_softc *scp; - - scp = device_get_softc(device); - if (!scp) + case ATASMODE: + if (!(ch = device_get_softc(device))) return ENODEV; - if (scp->dev_param[MASTER] && iocmd->u.mode.mode[MASTER] >= 0) { - ata_change_mode(scp, ATA_MASTER, iocmd->u.mode.mode[MASTER]); - iocmd->u.mode.mode[MASTER] = scp->mode[MASTER]; + + if ((iocmd->device == MASTER || iocmd->device == -1) && + iocmd->u.mode.mode[MASTER] >= 0 && ch->device[MASTER].param) { + ata_change_mode(&ch->device[MASTER],iocmd->u.mode.mode[MASTER]); + iocmd->u.mode.mode[MASTER] = ch->device[MASTER].mode; } else iocmd->u.mode.mode[MASTER] = -1; - if (scp->dev_param[SLAVE] && iocmd->u.mode.mode[SLAVE] >= 0) { - ata_change_mode(scp, ATA_SLAVE, iocmd->u.mode.mode[SLAVE]); - iocmd->u.mode.mode[SLAVE] = scp->mode[SLAVE]; + if ((iocmd->device == SLAVE || iocmd->device == -1) && + iocmd->u.mode.mode[SLAVE] >= 0 && ch->device[SLAVE].param) { + ata_change_mode(&ch->device[SLAVE], iocmd->u.mode.mode[SLAVE]); + iocmd->u.mode.mode[SLAVE] = ch->device[SLAVE].mode; } else iocmd->u.mode.mode[SLAVE] = -1; - return 0; - } - case ATAGPARM: { - struct ata_softc *scp; + return 0; - scp = device_get_softc(device); - if (!scp) + case ATAGPARM: + if (!(ch = device_get_softc(device))) return ENODEV; iocmd->u.param.type[MASTER] = - scp->devices & (ATA_ATA_MASTER | ATA_ATAPI_MASTER); + ch->devices & (ATA_ATA_MASTER | ATA_ATAPI_MASTER); iocmd->u.param.type[SLAVE] = - scp->devices & (ATA_ATA_SLAVE | ATA_ATAPI_SLAVE); + ch->devices & (ATA_ATA_SLAVE | ATA_ATAPI_SLAVE); - if (scp->dev_name[MASTER]) - strcpy(iocmd->u.param.name[MASTER], scp->dev_name[MASTER]); - if (scp->dev_name[SLAVE]) - strcpy(iocmd->u.param.name[SLAVE], scp->dev_name[SLAVE]); + if (ch->device[MASTER].name) + strcpy(iocmd->u.param.name[MASTER], ch->device[MASTER].name); + if (ch->device[SLAVE].name) + strcpy(iocmd->u.param.name[SLAVE], ch->device[SLAVE].name); - if (scp->dev_param[MASTER]) - bcopy(scp->dev_param[MASTER], &iocmd->u.param.params[MASTER], + if (ch->device[MASTER].param) + bcopy(ch->device[MASTER].param, &iocmd->u.param.params[MASTER], sizeof(struct ata_params)); - if (scp->dev_param[SLAVE]) - bcopy(scp->dev_param[SLAVE], &iocmd->u.param.params[SLAVE], + if (ch->device[SLAVE].param) + bcopy(ch->device[SLAVE].param, &iocmd->u.param.params[SLAVE], sizeof(struct ata_params)); + return 0; - } #if defined(DEV_ATAPICD) || defined(DEV_ATAPIFD) || defined(DEV_ATAPIST) case ATAPICMD: { - struct ata_softc *scp; - struct atapi_softc *atp; caddr_t buf; - scp = device_get_softc(device); - if (!scp) + ch = device_get_softc(device); + if (!ch) return ENODEV; - if (!scp->dev_softc[iocmd->device] || - !(scp->devices & - (iocmd->device == 0 ? ATA_ATAPI_MASTER : ATA_ATAPI_SLAVE))) + + if (!(atadev = &ch->device[iocmd->device]) || + !(ch->devices & (iocmd->device == MASTER ? + ATA_ATAPI_MASTER : ATA_ATAPI_SLAVE))) return ENODEV; - if (!(buf = malloc(iocmd->u.atapi.count, M_ATA, M_NOWAIT))) + if (!(buf = malloc(iocmd->u.atapi.count, M_ATA, M_NOWAIT))) return ENOMEM; - atp = scp->dev_softc[iocmd->device]; if (iocmd->u.atapi.flags & ATAPI_CMD_WRITE) { error = copyin(iocmd->u.atapi.data, buf, iocmd->u.atapi.count); if (error) return error; } - error = atapi_queue_cmd(atp, iocmd->u.atapi.ccb, + error = atapi_queue_cmd(atadev, iocmd->u.atapi.ccb, buf, iocmd->u.atapi.count, (iocmd->u.atapi.flags == ATAPI_CMD_READ ? - ATPR_F_READ : 0) | ATPR_F_QUIET, + ATPR_F_READ : 0) | ATPR_F_QUIET, iocmd->u.atapi.timeout, NULL, NULL); if (error) { iocmd->u.atapi.error = error; - bcopy(&atp->sense, iocmd->u.atapi.sense_data, + bcopy(&atadev->result, iocmd->u.atapi.sense_data, sizeof(struct atapi_reqsense)); error = 0; } @@ -443,160 +432,162 @@ ataioctl(dev_t dev, u_long cmd, caddr_t addr, int32_t flag, struct thread *td) } static int -ata_getparam(struct ata_softc *scp, int device, u_int8_t command) +ata_getparam(struct ata_device *atadev, u_int8_t command) { struct ata_params *ata_parm; int retry = 0; /* select drive */ - ATA_OUTB(scp->r_io, ATA_DRIVE, ATA_D_IBM | device); + ATA_OUTB(atadev->channel->r_io, ATA_DRIVE, ATA_D_IBM | atadev->unit); DELAY(1); /* enable interrupt */ - ATA_OUTB(scp->r_altio, ATA_ALTSTAT, ATA_A_4BIT); + ATA_OUTB(atadev->channel->r_altio, ATA_ALTSTAT, ATA_A_4BIT); DELAY(1); /* apparently some devices needs this repeated */ do { - if (ata_command(scp, device, command, 0, 0, 0, ATA_WAIT_INTR)) { - ata_printf(scp, device, "%s identify failed\n", + if (ata_command(atadev, command, 0, 0, 0, ATA_WAIT_INTR)) { + ata_prtdev(atadev, "%s identify failed\n", command == ATA_C_ATAPI_IDENTIFY ? "ATAPI" : "ATA"); return -1; } if (retry++ > 4) { - ata_printf(scp, device, "%s identify retries exceeded\n", + ata_prtdev(atadev, "%s identify retries exceeded\n", command == ATA_C_ATAPI_IDENTIFY ? "ATAPI" : "ATA"); return -1; } - } while (ata_wait(scp, device, - ((command == ATA_C_ATAPI_IDENTIFY) ? - ATA_S_DRQ : (ATA_S_READY | ATA_S_DSC | ATA_S_DRQ)))); + } while (ata_wait(atadev, ((command == ATA_C_ATAPI_IDENTIFY) ? + ATA_S_DRQ : (ATA_S_READY|ATA_S_DSC|ATA_S_DRQ)))); ata_parm = malloc(sizeof(struct ata_params), M_ATA, M_NOWAIT); if (!ata_parm) { int i; for (i = 0; i < sizeof(struct ata_params)/sizeof(int16_t); i++) - ATA_INW(scp->r_io, ATA_DATA); - ata_printf(scp, device, "malloc for identify data failed\n"); - return -1; + ATA_INW(atadev->channel->r_io, ATA_DATA); + ata_prtdev(atadev, "malloc for identify data failed\n"); + return -1; } - ATA_INSW(scp->r_io, ATA_DATA, (int16_t *)ata_parm, + ATA_INSW(atadev->channel->r_io, ATA_DATA, (int16_t *)ata_parm, sizeof(struct ata_params)/sizeof(int16_t)); if (command == ATA_C_ATA_IDENTIFY || !((ata_parm->model[0] == 'N' && ata_parm->model[1] == 'E') || - (ata_parm->model[0] == 'F' && ata_parm->model[1] == 'X'))) - bswap(ata_parm->model, sizeof(ata_parm->model)); + (ata_parm->model[0] == 'F' && ata_parm->model[1] == 'X') || + (ata_parm->model[0] == 'P' && ata_parm->model[1] == 'i'))) + bswap(ata_parm->model, sizeof(ata_parm->model)); btrim(ata_parm->model, sizeof(ata_parm->model)); bpack(ata_parm->model, ata_parm->model, sizeof(ata_parm->model)); bswap(ata_parm->revision, sizeof(ata_parm->revision)); btrim(ata_parm->revision, sizeof(ata_parm->revision)); bpack(ata_parm->revision, ata_parm->revision, sizeof(ata_parm->revision)); - scp->dev_param[ATA_DEV(device)] = ata_parm; + atadev->param = ata_parm; return 0; } static void ata_boot_attach(void) { - struct ata_softc *scp; + struct ata_channel *ch; int ctlr; + if (ata_delayed_attach) { + config_intrhook_disestablish(ata_delayed_attach); + free(ata_delayed_attach, M_TEMP); + ata_delayed_attach = NULL; + } + /* * run through all ata devices and look for real ATA & ATAPI devices * using the hints we found in the early probe, this avoids some of * the delays probing of non-exsistent devices can cause. */ for (ctlr=0; ctlr<devclass_get_maxunit(ata_devclass); ctlr++) { - if (!(scp = devclass_get_softc(ata_devclass, ctlr))) + if (!(ch = devclass_get_softc(ata_devclass, ctlr))) continue; - if (scp->devices & ATA_ATA_SLAVE) - if (ata_getparam(scp, ATA_SLAVE, ATA_C_ATA_IDENTIFY)) - scp->devices &= ~ATA_ATA_SLAVE; - if (scp->devices & ATA_ATAPI_SLAVE) - if (ata_getparam(scp, ATA_SLAVE, ATA_C_ATAPI_IDENTIFY)) - scp->devices &= ~ATA_ATAPI_SLAVE; - if (scp->devices & ATA_ATA_MASTER) - if (ata_getparam(scp, ATA_MASTER, ATA_C_ATA_IDENTIFY)) - scp->devices &= ~ATA_ATA_MASTER; - if (scp->devices & ATA_ATAPI_MASTER) - if (ata_getparam(scp, ATA_MASTER, ATA_C_ATAPI_IDENTIFY)) - scp->devices &= ~ATA_ATAPI_MASTER; + if (ch->devices & ATA_ATA_SLAVE) + if (ata_getparam(&ch->device[SLAVE], ATA_C_ATA_IDENTIFY)) + ch->devices &= ~ATA_ATA_SLAVE; + if (ch->devices & ATA_ATAPI_SLAVE) + if (ata_getparam(&ch->device[SLAVE], ATA_C_ATAPI_IDENTIFY)) + ch->devices &= ~ATA_ATAPI_SLAVE; + if (ch->devices & ATA_ATA_MASTER) + if (ata_getparam(&ch->device[MASTER], ATA_C_ATA_IDENTIFY)) + ch->devices &= ~ATA_ATA_MASTER; + if (ch->devices & ATA_ATAPI_MASTER) + if (ata_getparam(&ch->device[MASTER], ATA_C_ATAPI_IDENTIFY)) + ch->devices &= ~ATA_ATAPI_MASTER; } #ifdef DEV_ATADISK /* now we know whats there, do the real attach, first the ATA disks */ for (ctlr=0; ctlr<devclass_get_maxunit(ata_devclass); ctlr++) { - if (!(scp = devclass_get_softc(ata_devclass, ctlr))) + if (!(ch = devclass_get_softc(ata_devclass, ctlr))) continue; - if (scp->devices & ATA_ATA_MASTER) - ad_attach(scp, ATA_MASTER); - if (scp->devices & ATA_ATA_SLAVE) - ad_attach(scp, ATA_SLAVE); + if (ch->devices & ATA_ATA_MASTER) + ad_attach(&ch->device[MASTER]); + if (ch->devices & ATA_ATA_SLAVE) + ad_attach(&ch->device[SLAVE]); } + ar_attach(); #endif #if defined(DEV_ATAPICD) || defined(DEV_ATAPIFD) || defined(DEV_ATAPIST) /* then the atapi devices */ for (ctlr=0; ctlr<devclass_get_maxunit(ata_devclass); ctlr++) { - if (!(scp = devclass_get_softc(ata_devclass, ctlr))) + if (!(ch = devclass_get_softc(ata_devclass, ctlr))) continue; - if (scp->devices & ATA_ATAPI_MASTER) - atapi_attach(scp, ATA_MASTER); - if (scp->devices & ATA_ATAPI_SLAVE) - atapi_attach(scp, ATA_SLAVE); + if (ch->devices & ATA_ATAPI_MASTER) + atapi_attach(&ch->device[MASTER]); + if (ch->devices & ATA_ATAPI_SLAVE) + atapi_attach(&ch->device[SLAVE]); } #endif - if (ata_delayed_attach) { - config_intrhook_disestablish(ata_delayed_attach); - free(ata_delayed_attach, M_TEMP); - ata_delayed_attach = NULL; - } } static void ata_intr(void *data) { - struct ata_softc *scp = (struct ata_softc *)data; + struct ata_channel *ch = (struct ata_channel *)data; /* * on PCI systems we might share an interrupt line with another - * device or our twin ATA channel, so call scp->intr_func to figure + * device or our twin ATA channel, so call ch->intr_func to figure * out if it is really an interrupt we should process here */ - if (scp->intr_func && scp->intr_func(scp)) + if (ch->intr_func && ch->intr_func(ch)) return; /* if drive is busy it didn't interrupt */ - if (ATA_INB(scp->r_altio, ATA_ALTSTAT) & ATA_S_BUSY) { + if (ATA_INB(ch->r_altio, ATA_ALTSTAT) & ATA_S_BUSY) { DELAY(100); - if (!(ATA_INB(scp->r_altio, ATA_ALTSTAT) & ATA_S_DRQ)) + if (!(ATA_INB(ch->r_altio, ATA_ALTSTAT) & ATA_S_DRQ)) return; } /* clear interrupt and get status */ - scp->status = ATA_INB(scp->r_io, ATA_STATUS); + ch->status = ATA_INB(ch->r_io, ATA_STATUS); - if (scp->status & ATA_S_ERROR) - scp->error = ATA_INB(scp->r_io, ATA_ERROR); + if (ch->status & ATA_S_ERROR) + ch->error = ATA_INB(ch->r_io, ATA_ERROR); /* find & call the responsible driver to process this interrupt */ - switch (scp->active) { + switch (ch->active) { #ifdef DEV_ATADISK case ATA_ACTIVE_ATA: - if (!scp->running || ad_interrupt(scp->running) == ATA_OP_CONTINUES) + if (!ch->running || ad_interrupt(ch->running) == ATA_OP_CONTINUES) return; break; #endif #if defined(DEV_ATAPICD) || defined(DEV_ATAPIFD) || defined(DEV_ATAPIST) case ATA_ACTIVE_ATAPI: - if (!scp->running || atapi_interrupt(scp->running) == ATA_OP_CONTINUES) + if (!ch->running || atapi_interrupt(ch->running) == ATA_OP_CONTINUES) return; break; #endif case ATA_WAIT_INTR: case ATA_WAIT_INTR | ATA_CONTROL: - wakeup((caddr_t)scp); + wakeup((caddr_t)ch); break; case ATA_WAIT_READY: @@ -604,9 +595,9 @@ ata_intr(void *data) break; case ATA_IDLE: - if (scp->flags & ATA_QUEUED) { - scp->active = ATA_ACTIVE; /* XXX */ - if (ata_service(scp) == ATA_OP_CONTINUES) + if (ch->flags & ATA_QUEUED) { + ch->active = ATA_ACTIVE; /* XXX */ + if (ata_service(ch) == ATA_OP_CONTINUES) return; } /* FALLTHROUGH */ @@ -617,22 +608,21 @@ ata_intr(void *data) static int intr_count = 0; if (intr_count++ < 10) - ata_printf(scp, -1, - "unwanted interrupt #%d active=0x%x status=0x%02x\n", - intr_count, scp->active, scp->status); + ata_printf(ch, -1, "unwanted interrupt #%d active=%02x s=%02x\n", + intr_count, ch->active, ch->status); } #endif } - scp->active &= ATA_CONTROL; - if (scp->active & ATA_CONTROL) + ch->active &= ATA_CONTROL; + if (ch->active & ATA_CONTROL) return; - scp->running = NULL; - ata_start(scp); + ch->running = NULL; + ata_start(ch); return; } void -ata_start(struct ata_softc *scp) +ata_start(struct ata_channel *ch) { #ifdef DEV_ATADISK struct ad_request *ad_request; @@ -641,21 +631,21 @@ ata_start(struct ata_softc *scp) struct atapi_request *atapi_request; #endif - if (!atomic_cmpset_int(&scp->active, ATA_IDLE, ATA_ACTIVE)) + if (!atomic_cmpset_int(&ch->active, ATA_IDLE, ATA_ACTIVE)) return; #ifdef DEV_ATADISK /* find & call the responsible driver if anything on the ATA queue */ - if (TAILQ_EMPTY(&scp->ata_queue)) { - if (scp->devices & (ATA_ATA_MASTER) && scp->dev_softc[MASTER]) - ad_start((struct ad_softc *)scp->dev_softc[MASTER]); - if (scp->devices & (ATA_ATA_SLAVE) && scp->dev_softc[SLAVE]) - ad_start((struct ad_softc *)scp->dev_softc[SLAVE]); + if (TAILQ_EMPTY(&ch->ata_queue)) { + if (ch->devices & (ATA_ATA_MASTER) && ch->device[MASTER].driver) + ad_start(&ch->device[MASTER]); + if (ch->devices & (ATA_ATA_SLAVE) && ch->device[SLAVE].driver) + ad_start(&ch->device[SLAVE]); } - if ((ad_request = TAILQ_FIRST(&scp->ata_queue))) { - TAILQ_REMOVE(&scp->ata_queue, ad_request, chain); - scp->active = ATA_ACTIVE_ATA; - scp->running = ad_request; + if ((ad_request = TAILQ_FIRST(&ch->ata_queue))) { + TAILQ_REMOVE(&ch->ata_queue, ad_request, chain); + ch->active = ATA_ACTIVE_ATA; + ch->running = ad_request; if (ad_transfer(ad_request) == ATA_OP_CONTINUES) return; } @@ -663,101 +653,99 @@ ata_start(struct ata_softc *scp) #endif #if defined(DEV_ATAPICD) || defined(DEV_ATAPIFD) || defined(DEV_ATAPIST) /* find & call the responsible driver if anything on the ATAPI queue */ - if (TAILQ_EMPTY(&scp->atapi_queue)) { - if (scp->devices & (ATA_ATAPI_MASTER) && scp->dev_softc[MASTER]) - atapi_start((struct atapi_softc *)scp->dev_softc[MASTER]); - if (scp->devices & (ATA_ATAPI_SLAVE) && scp->dev_softc[SLAVE]) - atapi_start((struct atapi_softc *)scp->dev_softc[SLAVE]); + if (TAILQ_EMPTY(&ch->atapi_queue)) { + if (ch->devices & (ATA_ATAPI_MASTER) && ch->device[MASTER].driver) + atapi_start(&ch->device[MASTER]); + if (ch->devices & (ATA_ATAPI_SLAVE) && ch->device[SLAVE].driver) + atapi_start(&ch->device[SLAVE]); } - if ((atapi_request = TAILQ_FIRST(&scp->atapi_queue))) { - TAILQ_REMOVE(&scp->atapi_queue, atapi_request, chain); - scp->active = ATA_ACTIVE_ATAPI; - scp->running = atapi_request; + if ((atapi_request = TAILQ_FIRST(&ch->atapi_queue))) { + TAILQ_REMOVE(&ch->atapi_queue, atapi_request, chain); + ch->active = ATA_ACTIVE_ATAPI; + ch->running = atapi_request; if (atapi_transfer(atapi_request) == ATA_OP_CONTINUES) return; } #endif - scp->active = ATA_IDLE; + ch->active = ATA_IDLE; } void -ata_reset(struct ata_softc *scp) +ata_reset(struct ata_channel *ch) { u_int8_t lsb, msb, ostat0, ostat1; u_int8_t stat0 = 0, stat1 = 0; int mask = 0, timeout; /* do we have any signs of ATA/ATAPI HW being present ? */ - ATA_OUTB(scp->r_io, ATA_DRIVE, ATA_D_IBM | ATA_MASTER); + ATA_OUTB(ch->r_io, ATA_DRIVE, ATA_D_IBM | ATA_MASTER); DELAY(10); - ostat0 = ATA_INB(scp->r_io, ATA_STATUS); + ostat0 = ATA_INB(ch->r_io, ATA_STATUS); if ((ostat0 & 0xf8) != 0xf8 && ostat0 != 0xa5) { stat0 = ATA_S_BUSY; mask |= 0x01; } - ATA_OUTB(scp->r_io, ATA_DRIVE, ATA_D_IBM | ATA_SLAVE); + ATA_OUTB(ch->r_io, ATA_DRIVE, ATA_D_IBM | ATA_SLAVE); DELAY(10); - ostat1 = ATA_INB(scp->r_io, ATA_STATUS); + ostat1 = ATA_INB(ch->r_io, ATA_STATUS); if ((ostat1 & 0xf8) != 0xf8 && ostat1 != 0xa5) { stat1 = ATA_S_BUSY; mask |= 0x02; } - scp->devices = 0; + ch->devices = 0; if (!mask) return; /* in some setups we dont want to test for a slave */ - if (scp->flags & ATA_NO_SLAVE) { + if (ch->flags & ATA_NO_SLAVE) { stat1 = 0x0; mask &= ~0x02; } if (bootverbose) - ata_printf(scp, -1, "mask=%02x ostat0=%02x ostat2=%02x\n", + ata_printf(ch, -1, "mask=%02x ostat0=%02x ostat2=%02x\n", mask, ostat0, ostat1); /* reset channel */ - ATA_OUTB(scp->r_io, ATA_DRIVE, ATA_D_IBM | ATA_MASTER); + ATA_OUTB(ch->r_io, ATA_DRIVE, ATA_D_IBM | ATA_MASTER); DELAY(10); - ATA_OUTB(scp->r_altio, ATA_ALTSTAT, ATA_A_IDS | ATA_A_RESET); + ATA_OUTB(ch->r_altio, ATA_ALTSTAT, ATA_A_IDS | ATA_A_RESET); DELAY(10000); - ATA_OUTB(scp->r_altio, ATA_ALTSTAT, ATA_A_IDS); + ATA_OUTB(ch->r_altio, ATA_ALTSTAT, ATA_A_IDS); DELAY(100000); - ATA_INB(scp->r_io, ATA_ERROR); + ATA_INB(ch->r_io, ATA_ERROR); /* wait for BUSY to go inactive */ for (timeout = 0; timeout < 310000; timeout++) { if (stat0 & ATA_S_BUSY) { - ATA_OUTB(scp->r_io, ATA_DRIVE, ATA_D_IBM | ATA_MASTER); - DELAY(10); - stat0 = ATA_INB(scp->r_io, ATA_STATUS); - if (!(stat0 & ATA_S_BUSY)) { - /* check for ATAPI signature while its still there */ - lsb = ATA_INB(scp->r_io, ATA_CYL_LSB); - msb = ATA_INB(scp->r_io, ATA_CYL_MSB); + ATA_OUTB(ch->r_io, ATA_DRIVE, ATA_D_IBM | ATA_MASTER); + DELAY(10); + stat0 = ATA_INB(ch->r_io, ATA_STATUS); + if (!(stat0 & ATA_S_BUSY)) { + /* check for ATAPI signature while its still there */ + lsb = ATA_INB(ch->r_io, ATA_CYL_LSB); + msb = ATA_INB(ch->r_io, ATA_CYL_MSB); if (bootverbose) - ata_printf(scp, ATA_MASTER, - "ATAPI probe %02x %02x\n", lsb, msb); + ata_printf(ch, ATA_MASTER, "ATAPI %02x %02x\n", lsb, msb); if (lsb == ATAPI_MAGIC_LSB && msb == ATAPI_MAGIC_MSB) - scp->devices |= ATA_ATAPI_MASTER; - } - } - if (stat1 & ATA_S_BUSY) { - ATA_OUTB(scp->r_io, ATA_DRIVE, ATA_D_IBM | ATA_SLAVE); - DELAY(10); - stat1 = ATA_INB(scp->r_io, ATA_STATUS); - if (!(stat1 & ATA_S_BUSY)) { - /* check for ATAPI signature while its still there */ - lsb = ATA_INB(scp->r_io, ATA_CYL_LSB); - msb = ATA_INB(scp->r_io, ATA_CYL_MSB); + ch->devices |= ATA_ATAPI_MASTER; + } + } + if (stat1 & ATA_S_BUSY) { + ATA_OUTB(ch->r_io, ATA_DRIVE, ATA_D_IBM | ATA_SLAVE); + DELAY(10); + stat1 = ATA_INB(ch->r_io, ATA_STATUS); + if (!(stat1 & ATA_S_BUSY)) { + /* check for ATAPI signature while its still there */ + lsb = ATA_INB(ch->r_io, ATA_CYL_LSB); + msb = ATA_INB(ch->r_io, ATA_CYL_MSB); if (bootverbose) - ata_printf(scp, ATA_SLAVE, - "ATAPI probe %02x %02x\n", lsb, msb); + ata_printf(ch, ATA_SLAVE, "ATAPI %02x %02x\n", lsb, msb); if (lsb == ATAPI_MAGIC_LSB && msb == ATAPI_MAGIC_MSB) - scp->devices |= ATA_ATAPI_SLAVE; - } - } + ch->devices |= ATA_ATAPI_SLAVE; + } + } if (mask == 0x01) /* wait for master only */ if (!(stat0 & ATA_S_BUSY)) break; @@ -770,140 +758,142 @@ ata_reset(struct ata_softc *scp) DELAY(100); } DELAY(10); - ATA_OUTB(scp->r_altio, ATA_ALTSTAT, ATA_A_4BIT); + ATA_OUTB(ch->r_altio, ATA_ALTSTAT, ATA_A_4BIT); if (stat0 & ATA_S_BUSY) mask &= ~0x01; if (stat1 & ATA_S_BUSY) mask &= ~0x02; if (bootverbose) - ata_printf(scp, -1, "mask=%02x stat0=%02x stat1=%02x\n", + ata_printf(ch, -1, "mask=%02x stat0=%02x stat1=%02x\n", mask, stat0, stat1); if (!mask) return; - if (mask & 0x01 && ostat0 != 0x00 && !(scp->devices & ATA_ATAPI_MASTER)) { - ATA_OUTB(scp->r_io, ATA_DRIVE, ATA_D_IBM | ATA_MASTER); - DELAY(10); - ATA_OUTB(scp->r_io, ATA_ERROR, 0x58); - ATA_OUTB(scp->r_io, ATA_CYL_LSB, 0xa5); - lsb = ATA_INB(scp->r_io, ATA_ERROR); - msb = ATA_INB(scp->r_io, ATA_CYL_LSB); + if (mask & 0x01 && ostat0 != 0x00 && !(ch->devices & ATA_ATAPI_MASTER)) { + ATA_OUTB(ch->r_io, ATA_DRIVE, ATA_D_IBM | ATA_MASTER); + DELAY(10); + ATA_OUTB(ch->r_io, ATA_ERROR, 0x58); + ATA_OUTB(ch->r_io, ATA_CYL_LSB, 0xa5); + lsb = ATA_INB(ch->r_io, ATA_ERROR); + msb = ATA_INB(ch->r_io, ATA_CYL_LSB); if (bootverbose) - ata_printf(scp, ATA_MASTER, "ATA probe %02x %02x\n", lsb, msb); - if (lsb != 0x58 && msb == 0xa5) - scp->devices |= ATA_ATA_MASTER; + ata_printf(ch, ATA_MASTER, "ATA %02x %02x\n", lsb, msb); + if (lsb != 0x58 && msb == 0xa5) + ch->devices |= ATA_ATA_MASTER; } - if (mask & 0x02 && ostat1 != 0x00 && !(scp->devices & ATA_ATAPI_SLAVE)) { - ATA_OUTB(scp->r_io, ATA_DRIVE, ATA_D_IBM | ATA_SLAVE); - DELAY(10); - ATA_OUTB(scp->r_io, ATA_ERROR, 0x58); - ATA_OUTB(scp->r_io, ATA_CYL_LSB, 0xa5); - lsb = ATA_INB(scp->r_io, ATA_ERROR); - msb = ATA_INB(scp->r_io, ATA_CYL_LSB); + if (mask & 0x02 && ostat1 != 0x00 && !(ch->devices & ATA_ATAPI_SLAVE)) { + ATA_OUTB(ch->r_io, ATA_DRIVE, ATA_D_IBM | ATA_SLAVE); + DELAY(10); + ATA_OUTB(ch->r_io, ATA_ERROR, 0x58); + ATA_OUTB(ch->r_io, ATA_CYL_LSB, 0xa5); + lsb = ATA_INB(ch->r_io, ATA_ERROR); + msb = ATA_INB(ch->r_io, ATA_CYL_LSB); if (bootverbose) - ata_printf(scp, ATA_SLAVE, "ATA probe %02x %02x\n", lsb, msb); - if (lsb != 0x58 && msb == 0xa5) - scp->devices |= ATA_ATA_SLAVE; + ata_printf(ch, ATA_SLAVE, "ATA %02x %02x\n", lsb, msb); + if (lsb != 0x58 && msb == 0xa5) + ch->devices |= ATA_ATA_SLAVE; } if (bootverbose) - ata_printf(scp, -1, "devices=%02x\n", scp->devices); + ata_printf(ch, -1, "devices=%02x\n", ch->devices); } int -ata_reinit(struct ata_softc *scp) +ata_reinit(struct ata_channel *ch) { int devices, misdev, newdev; - if (!scp->r_io || !scp->r_altio || !scp->r_irq) + if (!ch->r_io || !ch->r_altio || !ch->r_irq) return ENXIO; - scp->active = ATA_CONTROL; - scp->running = NULL; - devices = scp->devices; - ata_printf(scp, -1, "resetting devices .. "); - ata_reset(scp); + ch->active = ATA_CONTROL; + ch->running = NULL; + devices = ch->devices; + ata_printf(ch, -1, "resetting devices .. "); + ata_reset(ch); - if ((misdev = devices & ~scp->devices)) { + if ((misdev = devices & ~ch->devices)) { if (misdev) printf("\n"); #ifdef DEV_ATADISK - if (misdev & ATA_ATA_MASTER && scp->dev_softc[MASTER]) - ad_detach(scp->dev_softc[MASTER], 0); - if (misdev & ATA_ATA_SLAVE && scp->dev_softc[SLAVE]) - ad_detach(scp->dev_softc[SLAVE], 0); + if (misdev & ATA_ATA_MASTER && ch->device[MASTER].driver) + ad_detach(&ch->device[MASTER], 0); + if (misdev & ATA_ATA_SLAVE && ch->device[SLAVE].driver) + ad_detach(&ch->device[SLAVE], 0); #endif #if defined(DEV_ATAPICD) || defined(DEV_ATAPIFD) || defined(DEV_ATAPIST) - if (misdev & ATA_ATAPI_MASTER && scp->dev_softc[MASTER]) - atapi_detach(scp->dev_softc[MASTER]); - if (misdev & ATA_ATAPI_SLAVE && scp->dev_softc[SLAVE]) - atapi_detach(scp->dev_softc[SLAVE]); + if (misdev & ATA_ATAPI_MASTER && ch->device[MASTER].driver) + atapi_detach(&ch->device[MASTER]); + if (misdev & ATA_ATAPI_SLAVE && ch->device[SLAVE].driver) + atapi_detach(&ch->device[SLAVE]); #endif if (misdev & ATA_ATA_MASTER || misdev & ATA_ATAPI_MASTER) { - free(scp->dev_param[MASTER], M_ATA); - scp->dev_param[MASTER] = NULL; + free(ch->device[MASTER].param, M_ATA); + ch->device[MASTER].param = NULL; } if (misdev & ATA_ATA_SLAVE || misdev & ATA_ATAPI_SLAVE) { - free(scp->dev_param[SLAVE], M_ATA); - scp->dev_param[SLAVE] = NULL; + free(ch->device[SLAVE].param, M_ATA); + ch->device[SLAVE].param = NULL; } } - if ((newdev = ~devices & scp->devices)) { + if ((newdev = ~devices & ch->devices)) { if (newdev & ATA_ATA_MASTER) - if (ata_getparam(scp, ATA_MASTER, ATA_C_ATA_IDENTIFY)) + if (ata_getparam(&ch->device[MASTER], ATA_C_ATA_IDENTIFY)) newdev &= ~ATA_ATA_MASTER; if (newdev & ATA_ATA_SLAVE) - if (ata_getparam(scp, ATA_SLAVE, ATA_C_ATA_IDENTIFY)) + if (ata_getparam(&ch->device[SLAVE], ATA_C_ATA_IDENTIFY)) newdev &= ~ATA_ATA_SLAVE; if (newdev & ATA_ATAPI_MASTER) - if (ata_getparam(scp, ATA_MASTER, ATA_C_ATAPI_IDENTIFY)) + if (ata_getparam(&ch->device[MASTER], ATA_C_ATAPI_IDENTIFY)) newdev &= ~ATA_ATAPI_MASTER; if (newdev & ATA_ATAPI_SLAVE) - if (ata_getparam(scp, ATA_SLAVE, ATA_C_ATAPI_IDENTIFY)) + if (ata_getparam(&ch->device[SLAVE], ATA_C_ATAPI_IDENTIFY)) newdev &= ~ATA_ATAPI_SLAVE; } if (!misdev && newdev) printf("\n"); #ifdef DEV_ATADISK - if (newdev & ATA_ATA_MASTER && !scp->dev_softc[MASTER]) - ad_attach(scp, ATA_MASTER); - else if (scp->devices & ATA_ATA_MASTER && scp->dev_softc[MASTER]) - ad_reinit((struct ad_softc *)scp->dev_softc[MASTER]); - if (newdev & ATA_ATA_SLAVE && !scp->dev_softc[SLAVE]) - ad_attach(scp, ATA_SLAVE); - else if (scp->devices & (ATA_ATA_SLAVE) && scp->dev_softc[SLAVE]) - ad_reinit((struct ad_softc *)scp->dev_softc[SLAVE]); + if (newdev & ATA_ATA_MASTER && !ch->device[MASTER].driver) + ad_attach(&ch->device[MASTER]); + else if (ch->devices & ATA_ATA_MASTER && ch->device[MASTER].driver) + ad_reinit((struct ad_softc *)ch->device[MASTER].driver); + if (newdev & ATA_ATA_SLAVE && !ch->device[SLAVE].driver) + ad_attach(&ch->device[SLAVE]); + else if (ch->devices & (ATA_ATA_SLAVE) && ch->device[SLAVE].driver) + ad_reinit((struct ad_softc *)ch->device[SLAVE].driver); #endif #if defined(DEV_ATAPICD) || defined(DEV_ATAPIFD) || defined(DEV_ATAPIST) - if (newdev & ATA_ATAPI_MASTER && !scp->dev_softc[MASTER]) - atapi_attach(scp, ATA_MASTER); - else if (scp->devices & (ATA_ATAPI_MASTER) && scp->dev_softc[MASTER]) - atapi_reinit((struct atapi_softc *)scp->dev_softc[MASTER]); - if (newdev & ATA_ATAPI_SLAVE && !scp->dev_softc[SLAVE]) - atapi_attach(scp, ATA_SLAVE); - else if (scp->devices & (ATA_ATAPI_SLAVE) && scp->dev_softc[SLAVE]) - atapi_reinit((struct atapi_softc *)scp->dev_softc[SLAVE]); + if (newdev & ATA_ATAPI_MASTER && !ch->device[MASTER].driver) + atapi_attach(&ch->device[MASTER]); + else if (ch->devices & (ATA_ATAPI_MASTER) && ch->device[MASTER].driver) + atapi_reinit(ch->device[MASTER].driver); + if (newdev & ATA_ATAPI_SLAVE && !ch->device[SLAVE].driver) + atapi_attach(&ch->device[SLAVE]); + else if (ch->devices & (ATA_ATAPI_SLAVE) && ch->device[SLAVE].driver) + atapi_reinit(ch->device[SLAVE].driver); #endif printf("done\n"); - scp->active = ATA_IDLE; - ata_start(scp); + ch->active = ATA_IDLE; + ata_start(ch); return 0; } static int -ata_service(struct ata_softc *scp) +ata_service(struct ata_channel *ch) { /* do we have a SERVICE request from the drive ? */ - if ((scp->status & (ATA_S_SERVICE|ATA_S_ERROR|ATA_S_DRQ)) == ATA_S_SERVICE){ - ATA_OUTB(scp->r_bmio, ATA_BMSTAT_PORT, - ata_dmastatus(scp) | ATA_BMSTAT_INTERRUPT); + if ((ch->status & (ATA_S_SERVICE|ATA_S_ERROR|ATA_S_DRQ)) == ATA_S_SERVICE) { + ATA_OUTB(ch->r_bmio, ATA_BMSTAT_PORT, + ata_dmastatus(ch) | ATA_BMSTAT_INTERRUPT); #ifdef DEV_ATADISK - if ((ATA_INB(scp->r_io, ATA_DRIVE) & ATA_SLAVE) == ATA_MASTER) { - if ((scp->devices & ATA_ATA_MASTER) && scp->dev_softc[MASTER]) - return ad_service((struct ad_softc *)scp->dev_softc[MASTER], 0); + if ((ATA_INB(ch->r_io, ATA_DRIVE) & ATA_SLAVE) == ATA_MASTER) { + if ((ch->devices & ATA_ATA_MASTER) && ch->device[MASTER].driver) + return ad_service((struct ad_softc *) + ch->device[MASTER].driver, 0); } else { - if ((scp->devices & ATA_ATA_SLAVE) && scp->dev_softc[SLAVE]) - return ad_service((struct ad_softc *)scp->dev_softc[SLAVE], 0); + if ((ch->devices & ATA_ATA_SLAVE) && ch->device[SLAVE].driver) + return ad_service((struct ad_softc *) + ch->device[SLAVE].driver, 0); } #endif } @@ -911,26 +901,26 @@ ata_service(struct ata_softc *scp) } int -ata_wait(struct ata_softc *scp, int device, u_int8_t mask) +ata_wait(struct ata_device *atadev, u_int8_t mask) { int timeout = 0; DELAY(1); - while (timeout < 5000000) { /* timeout 5 secs */ - scp->status = ATA_INB(scp->r_io, ATA_STATUS); + while (timeout < 5000000) { /* timeout 5 secs */ + atadev->channel->status = ATA_INB(atadev->channel->r_io, ATA_STATUS); /* if drive fails status, reselect the drive just to be sure */ - if (scp->status == 0xff) { - ata_printf(scp, device, "no status, reselecting device\n"); - ATA_OUTB(scp->r_io, ATA_DRIVE, ATA_D_IBM | device); + if (atadev->channel->status == 0xff) { + ata_prtdev(atadev, "no status, reselecting device\n"); + ATA_OUTB(atadev->channel->r_io, ATA_DRIVE, ATA_D_IBM|atadev->unit); DELAY(10); - scp->status = ATA_INB(scp->r_io, ATA_STATUS); - if (scp->status == 0xff) + atadev->channel->status = ATA_INB(atadev->channel->r_io,ATA_STATUS); + if (atadev->channel->status == 0xff) return -1; } /* are we done ? */ - if (!(scp->status & ATA_S_BUSY)) + if (!(atadev->channel->status & ATA_S_BUSY)) break; if (timeout > 1000) { @@ -942,21 +932,21 @@ ata_wait(struct ata_softc *scp, int device, u_int8_t mask) DELAY(10); } } - if (scp->status & ATA_S_ERROR) - scp->error = ATA_INB(scp->r_io, ATA_ERROR); + if (atadev->channel->status & ATA_S_ERROR) + atadev->channel->error = ATA_INB(atadev->channel->r_io, ATA_ERROR); if (timeout >= 5000000) return -1; if (!mask) - return (scp->status & ATA_S_ERROR); + return (atadev->channel->status & ATA_S_ERROR); /* Wait 50 msec for bits wanted. */ timeout = 5000; while (timeout--) { - scp->status = ATA_INB(scp->r_io, ATA_STATUS); - if ((scp->status & mask) == mask) { - if (scp->status & ATA_S_ERROR) - scp->error = ATA_INB(scp->r_io, ATA_ERROR); - return (scp->status & ATA_S_ERROR); + atadev->channel->status = ATA_INB(atadev->channel->r_io, ATA_STATUS); + if ((atadev->channel->status & mask) == mask) { + if (atadev->channel->status & ATA_S_ERROR) + atadev->channel->error=ATA_INB(atadev->channel->r_io,ATA_ERROR); + return (atadev->channel->status & ATA_S_ERROR); } DELAY (10); } @@ -964,45 +954,45 @@ ata_wait(struct ata_softc *scp, int device, u_int8_t mask) } int -ata_command(struct ata_softc *scp, int device, u_int8_t command, +ata_command(struct ata_device *atadev, u_int8_t command, u_int64_t lba, u_int16_t count, u_int8_t feature, int flags) { int error = 0; #ifdef ATA_DEBUG - ata_printf(scp, device, "ata_command: addr=%04lx, cmd=%02x, " + ata_prtdev(atadev, "ata_command: addr=%04lx, cmd=%02x, " "lba=%lld, count=%d, feature=%d, flags=%02x\n", - rman_get_start(scp->r_io), command, lba, count, feature, flags); + rman_get_start(atadev->channel->r_io), + command, lba, count, feature, flags); #endif /* select device */ - ATA_OUTB(scp->r_io, ATA_DRIVE, ATA_D_IBM | device); + ATA_OUTB(atadev->channel->r_io, ATA_DRIVE, ATA_D_IBM | atadev->unit); /* disable interrupt from device */ - if (scp->flags & ATA_QUEUED) - ATA_OUTB(scp->r_altio, ATA_ALTSTAT, ATA_A_IDS | ATA_A_4BIT); + if (atadev->channel->flags & ATA_QUEUED) + ATA_OUTB(atadev->channel->r_altio, ATA_ALTSTAT, ATA_A_IDS | ATA_A_4BIT); /* ready to issue command ? */ - if (ata_wait(scp, device, 0) < 0) { - ata_printf(scp, device, - "timeout waiting to give command=%02x s=%02x e=%02x\n", - command, scp->status, scp->error); + if (ata_wait(atadev, 0) < 0) { + ata_prtdev(atadev, "timeout sending command=%02x s=%02x e=%02x\n", + command, atadev->channel->status, atadev->channel->error); return -1; } /* only use 48bit addressing if needed because of the overhead */ - if ((lba > 268435455 || count > 256) && scp->dev_param[ATA_DEV(device)] && - scp->dev_param[ATA_DEV(device)]->support.address48) { - ATA_OUTB(scp->r_io, ATA_FEATURE, (feature>>8) & 0xff); - ATA_OUTB(scp->r_io, ATA_FEATURE, feature); - ATA_OUTB(scp->r_io, ATA_COUNT, (count>>8) & 0xff); - ATA_OUTB(scp->r_io, ATA_COUNT, count & 0xff); - ATA_OUTB(scp->r_io, ATA_SECTOR, (lba>>24) & 0xff); - ATA_OUTB(scp->r_io, ATA_SECTOR, lba & 0xff); - ATA_OUTB(scp->r_io, ATA_CYL_LSB, (lba<<32) & 0xff); - ATA_OUTB(scp->r_io, ATA_CYL_LSB, (lba>>8) & 0xff); - ATA_OUTB(scp->r_io, ATA_CYL_MSB, (lba>>40) & 0xff); - ATA_OUTB(scp->r_io, ATA_CYL_MSB, (lba>>16) & 0xff); - ATA_OUTB(scp->r_io, ATA_DRIVE, ATA_D_LBA | device); + if ((lba > 268435455 || count > 256) && atadev->param && + atadev->param->support.address48) { + ATA_OUTB(atadev->channel->r_io, ATA_FEATURE, (feature>>8) & 0xff); + ATA_OUTB(atadev->channel->r_io, ATA_FEATURE, feature); + ATA_OUTB(atadev->channel->r_io, ATA_COUNT, (count>>8) & 0xff); + ATA_OUTB(atadev->channel->r_io, ATA_COUNT, count & 0xff); + ATA_OUTB(atadev->channel->r_io, ATA_SECTOR, (lba>>24) & 0xff); + ATA_OUTB(atadev->channel->r_io, ATA_SECTOR, lba & 0xff); + ATA_OUTB(atadev->channel->r_io, ATA_CYL_LSB, (lba<<32) & 0xff); + ATA_OUTB(atadev->channel->r_io, ATA_CYL_LSB, (lba>>8) & 0xff); + ATA_OUTB(atadev->channel->r_io, ATA_CYL_MSB, (lba>>40) & 0xff); + ATA_OUTB(atadev->channel->r_io, ATA_CYL_MSB, (lba>>16) & 0xff); + ATA_OUTB(atadev->channel->r_io, ATA_DRIVE, ATA_D_LBA | atadev->unit); /* translate command into 48bit version */ switch (command) { @@ -1025,77 +1015,185 @@ ata_command(struct ata_softc *scp, int device, u_int8_t command, case ATA_C_FLUSHCACHE: command = ATA_C_FLUSHCACHE48; break; default: - ata_printf(scp, device, "can't translate cmd to 48bit version\n"); + ata_prtdev(atadev, "can't translate cmd to 48bit version\n"); return -1; } } else { - ATA_OUTB(scp->r_io, ATA_FEATURE, feature); - ATA_OUTB(scp->r_io, ATA_COUNT, count); - ATA_OUTB(scp->r_io, ATA_SECTOR, lba & 0xff); - ATA_OUTB(scp->r_io, ATA_CYL_LSB, (lba>>8) & 0xff); - ATA_OUTB(scp->r_io, ATA_CYL_MSB, (lba>>16) & 0xff); - if (flags & ATA_USE_CHS) - ATA_OUTB(scp->r_io, ATA_DRIVE, - ATA_D_IBM | device | ((lba>>24) & 0xf)); + ATA_OUTB(atadev->channel->r_io, ATA_FEATURE, feature); + ATA_OUTB(atadev->channel->r_io, ATA_COUNT, count); + ATA_OUTB(atadev->channel->r_io, ATA_SECTOR, lba & 0xff); + ATA_OUTB(atadev->channel->r_io, ATA_CYL_LSB, (lba>>8) & 0xff); + ATA_OUTB(atadev->channel->r_io, ATA_CYL_MSB, (lba>>16) & 0xff); + if (atadev->flags & ATA_D_USE_CHS) + ATA_OUTB(atadev->channel->r_io, ATA_DRIVE, + ATA_D_IBM | atadev->unit | ((lba>>24) & 0xf)); else - ATA_OUTB(scp->r_io, ATA_DRIVE, - ATA_D_IBM | ATA_D_LBA | device | ((lba>>24) & 0xf)); + ATA_OUTB(atadev->channel->r_io, ATA_DRIVE, + ATA_D_IBM | ATA_D_LBA | atadev->unit | ((lba>>24) &0xf)); } switch (flags & ATA_WAIT_MASK) { case ATA_IMMEDIATE: - ATA_OUTB(scp->r_io, ATA_CMD, command); + ATA_OUTB(atadev->channel->r_io, ATA_CMD, command); /* enable interrupt */ - if (scp->flags & ATA_QUEUED) - ATA_OUTB(scp->r_altio, ATA_ALTSTAT, ATA_A_4BIT); + if (atadev->channel->flags & ATA_QUEUED) + ATA_OUTB(atadev->channel->r_altio, ATA_ALTSTAT, ATA_A_4BIT); break; case ATA_WAIT_INTR: - scp->active |= ATA_WAIT_INTR; - ATA_OUTB(scp->r_io, ATA_CMD, command); + atadev->channel->active |= ATA_WAIT_INTR; + ATA_OUTB(atadev->channel->r_io, ATA_CMD, command); /* enable interrupt */ - if (scp->flags & ATA_QUEUED) - ATA_OUTB(scp->r_altio, ATA_ALTSTAT, ATA_A_4BIT); + if (atadev->channel->flags & ATA_QUEUED) + ATA_OUTB(atadev->channel->r_altio, ATA_ALTSTAT, ATA_A_4BIT); - if (tsleep((caddr_t)scp, PRIBIO, "atacmd", 10 * hz) != 0) { - ata_printf(scp, device, "ata_command: timeout waiting for intr\n"); - scp->active &= ~ATA_WAIT_INTR; + if (tsleep((caddr_t)atadev->channel, PRIBIO, "atacmd", 10 * hz) != 0) { + ata_prtdev(atadev, "timeout waiting for interrupt\n"); + atadev->channel->active &= ~ATA_WAIT_INTR; error = -1; } break; case ATA_WAIT_READY: - scp->active |= ATA_WAIT_READY; - ATA_OUTB(scp->r_io, ATA_CMD, command); - if (ata_wait(scp, device, ATA_S_READY) < 0) { - ata_printf(scp, device, - "timeout waiting for command=%02x s=%02x e=%02x\n", - command, scp->status, scp->error); + atadev->channel->active |= ATA_WAIT_READY; + ATA_OUTB(atadev->channel->r_io, ATA_CMD, command); + if (ata_wait(atadev, ATA_S_READY) < 0) { + ata_prtdev(atadev, "timeout waiting for cmd=%02x s=%02x e=%02x\n", + command, atadev->channel->status,atadev->channel->error); error = -1; } - scp->active &= ~ATA_WAIT_READY; + atadev->channel->active &= ~ATA_WAIT_READY; break; } return error; } void -ata_set_name(struct ata_softc *scp, int device, char *name, int lun) +ata_drawerleds(struct ata_device *atadev, u_int8_t color) +{ + u_int8_t count, drive; + int s = splbio(); + int state; + + if ((state = atadev->channel->active) != ATA_CONTROL) { + while (!atomic_cmpset_int(&atadev->channel->active, + ATA_IDLE, ATA_CONTROL)) + tsleep((caddr_t)&s, PRIBIO, "ataled", hz/4); + } + + /* magic sequence to set the LED color on the Promise SuperSwap */ + ATA_INB(atadev->channel->r_io, ATA_DRIVE); + DELAY(1); + ATA_OUTB(atadev->channel->r_io, ATA_DRIVE, ATA_D_IBM | atadev->unit); + DELAY(1); + ATA_OUTB(atadev->channel->r_io, ATA_DRIVE, ATA_D_IBM | atadev->unit); + DELAY(1); + ATA_OUTB(atadev->channel->r_io, ATA_DRIVE, ATA_D_IBM | atadev->unit); + DELAY(1); + count = ATA_INB(atadev->channel->r_io, ATA_COUNT); + DELAY(1); + drive = ATA_INB(atadev->channel->r_io, ATA_DRIVE); + DELAY(1); + ATA_OUTB(atadev->channel->r_io, ATA_COUNT, color); + DELAY(1); + ATA_OUTB(atadev->channel->r_io, ATA_DRIVE, ATA_D_IBM | atadev->unit); + DELAY(1); + + atadev->channel->active = state; + splx(s); +} + +static void +ata_change_mode(struct ata_device *atadev, int mode) +{ + int umode, wmode, pmode; + int s = splbio(); + + while (!atomic_cmpset_int(&atadev->channel->active, ATA_IDLE, ATA_ACTIVE)) + tsleep((caddr_t)&s, PRIBIO, "atachm", hz/4); + + umode = ata_umode(atadev->param); + wmode = ata_wmode(atadev->param); + pmode = ata_pmode(atadev->param); + + switch (mode & ATA_DMA_MASK) { + case ATA_UDMA: + if ((mode & ATA_MODE_MASK) < umode) + umode = mode & ATA_MODE_MASK; + break; + case ATA_WDMA: + if ((mode & ATA_MODE_MASK) < wmode) + wmode = mode & ATA_MODE_MASK; + umode = -1; + break; + default: + if (((mode & ATA_MODE_MASK) - ATA_PIO0) < pmode) + pmode = (mode & ATA_MODE_MASK) - ATA_PIO0; + umode = -1; + wmode = -1; + } + ata_dmainit(atadev->channel, atadev->unit, pmode, wmode, umode); + + atadev->channel->active = ATA_IDLE; + ata_start(atadev->channel); + splx(s); +} + +int +ata_printf(struct ata_channel *ch, int device, const char * fmt, ...) +{ + va_list ap; + int ret; + + if (device == -1) + ret = printf("ata%d: ", device_get_unit(ch->dev)); + else { + if (ch->device[ATA_DEV(device)].name) + ret = printf("%s: ", ch->device[ATA_DEV(device)].name); + else + ret = printf("ata%d-%s: ", device_get_unit(ch->dev), + (device == ATA_MASTER) ? "master" : "slave"); + } + va_start(ap, fmt); + ret += vprintf(fmt, ap); + va_end(ap); + return ret; +} + +int +ata_prtdev(struct ata_device *atadev, const char * fmt, ...) +{ + va_list ap; + int ret; + + if (atadev->name) + ret = printf("%s: ", atadev->name); + else + ret = printf("ata%d-%s: ", device_get_unit(atadev->channel->dev), + (atadev->unit == ATA_MASTER) ? "master" : "slave"); + va_start(ap, fmt); + ret += vprintf(fmt, ap); + va_end(ap); + return ret; +} + +void +ata_set_name(struct ata_device *atadev, char *name, int lun) { - scp->dev_name[ATA_DEV(device)] = malloc(strlen(name) + 4, M_ATA, M_NOWAIT); - if (scp->dev_name[ATA_DEV(device)]) - sprintf(scp->dev_name[ATA_DEV(device)], "%s%d", name, lun); + atadev->name = malloc(strlen(name) + 4, M_ATA, M_NOWAIT); + if (atadev->name) + sprintf(atadev->name, "%s%d", name, lun); } void -ata_free_name(struct ata_softc *scp, int device) +ata_free_name(struct ata_device *atadev) { - if (scp->dev_name[ATA_DEV(device)]) - free(scp->dev_name[ATA_DEV(device)], M_ATA); - scp->dev_name[ATA_DEV(device)] = NULL; + if (atadev->name) + free(atadev->name, M_ATA); + atadev->name = NULL; } int @@ -1119,27 +1217,6 @@ ata_free_lun(u_int32_t *map, int lun) *map &= ~(1 << lun); } -int -ata_printf(struct ata_softc *scp, int device, const char * fmt, ...) -{ - va_list ap; - int ret; - - if (device == -1) - ret = printf("ata%d: ", device_get_unit(scp->dev)); - else { - if (scp->dev_name[ATA_DEV(device)]) - ret = printf("%s: ", scp->dev_name[ATA_DEV(device)]); - else - ret = printf("ata%d-%s: ", device_get_unit(scp->dev), - (device == ATA_MASTER) ? "master" : "slave"); - } - va_start(ap, fmt); - ret += vprintf(fmt, ap); - va_end(ap); - return ret; -} - char * ata_mode2str(int mode) { @@ -1150,12 +1227,12 @@ ata_mode2str(int mode) case ATA_PIO2: return "PIO2"; case ATA_PIO3: return "PIO3"; case ATA_PIO4: return "PIO4"; + case ATA_DMA: return "BIOSDMA"; case ATA_WDMA2: return "WDMA2"; case ATA_UDMA2: return "UDMA33"; case ATA_UDMA4: return "UDMA66"; case ATA_UDMA5: return "UDMA100"; case ATA_UDMA6: return "UDMA133"; - case ATA_DMA: return "BIOSDMA"; default: return "???"; } } @@ -1257,42 +1334,6 @@ bpack(int8_t *src, int8_t *dst, int len) } static void -ata_change_mode(struct ata_softc *scp, int device, int mode) -{ - int umode, wmode, pmode; - int s = splbio(); - - while (!atomic_cmpset_int(&scp->active, ATA_IDLE, ATA_ACTIVE)) - tsleep((caddr_t)&s, PRIBIO, "atachm", hz/4); - - umode = ata_umode(ATA_PARAM(scp, device)); - wmode = ata_wmode(ATA_PARAM(scp, device)); - pmode = ata_pmode(ATA_PARAM(scp, device)); - - switch (mode & ATA_DMA_MASK) { - case ATA_UDMA: - if ((mode & ATA_MODE_MASK) < umode) - umode = mode & ATA_MODE_MASK; - break; - case ATA_WDMA: - if ((mode & ATA_MODE_MASK) < wmode) - wmode = mode & ATA_MODE_MASK; - umode = -1; - break; - default: - if (((mode & ATA_MODE_MASK) - ATA_PIO0) < pmode) - pmode = (mode & ATA_MODE_MASK) - ATA_PIO0; - umode = -1; - wmode = -1; - } - ata_dmainit(scp, device, pmode, wmode, umode); - - scp->active = ATA_IDLE; - ata_start(scp); - splx(s); -} - -static void ata_init(void) { /* register controlling device */ |