diff options
author | sos <sos@FreeBSD.org> | 2002-02-04 19:23:40 +0000 |
---|---|---|
committer | sos <sos@FreeBSD.org> | 2002-02-04 19:23:40 +0000 |
commit | f0704f5ca18f3a7991726b05a2bf9eeea477567a (patch) | |
tree | 5e4cc6717e35748abaad55907c0de3f487461cd0 /sys/dev | |
parent | 2ceaebc7d8f7c823715cc793b8557152e5c3392e (diff) | |
download | FreeBSD-src-f0704f5ca18f3a7991726b05a2bf9eeea477567a.zip FreeBSD-src-f0704f5ca18f3a7991726b05a2bf9eeea477567a.tar.gz |
Major update of the ATA RAID code, part 1:
Overhaul of the attach/detach code and structures, there were some nasty
bugs in the old implementation. This made it possible to collapse the
ATA/ATAPI device control structures into one generic structure.
A note here, the kernel is NOT ready for detach of active devices,
it fails all over in random places, but for inactive devices it works.
However for ATA RAID this works, since the RAID abstration layer
insulates the buggy^H^H^H^H^H^Hfragile device subsystem from the
physical disks.
Proberly detect the RAID's from the BIOS, and mark critical RAID1
arrays as such, but continue if there is enough of the mirror left
to do so.
Properly fail arrays on a live system. For RAID0 that means return EIO,
and for RAID1 it means continue on the still working part of the mirror
if possible, else return EIO.
If the state changes, log this to the console.
Allow for Promise & Highpoint controllers/arrays to coexist on the
same machine. It is not possible to distribute arrays over different
makes of controllers though.
If Promise SuperSwap enclosures are used, signal disk state on the
status LED on the front.
Misc fixes that I had lying around for various minor bugs.
Sponsored by: Advanis Inc.
Diffstat (limited to 'sys/dev')
-rw-r--r-- | sys/dev/ata/ata-all.c | 1065 | ||||
-rw-r--r-- | sys/dev/ata/ata-all.h | 91 | ||||
-rw-r--r-- | sys/dev/ata/ata-card.c | 12 | ||||
-rw-r--r-- | sys/dev/ata/ata-disk.c | 492 | ||||
-rw-r--r-- | sys/dev/ata/ata-disk.h | 24 | ||||
-rw-r--r-- | sys/dev/ata/ata-dma.c | 648 | ||||
-rw-r--r-- | sys/dev/ata/ata-isa.c | 24 | ||||
-rw-r--r-- | sys/dev/ata/ata-pci.c | 145 | ||||
-rw-r--r-- | sys/dev/ata/ata-raid.c | 744 | ||||
-rw-r--r-- | sys/dev/ata/ata-raid.h | 198 | ||||
-rw-r--r-- | sys/dev/ata/atapi-all.c | 322 | ||||
-rw-r--r-- | sys/dev/ata/atapi-all.h | 51 | ||||
-rw-r--r-- | sys/dev/ata/atapi-cd.c | 258 | ||||
-rw-r--r-- | sys/dev/ata/atapi-cd.h | 8 | ||||
-rw-r--r-- | sys/dev/ata/atapi-fd.c | 95 | ||||
-rw-r--r-- | sys/dev/ata/atapi-fd.h | 4 | ||||
-rw-r--r-- | sys/dev/ata/atapi-tape.c | 123 | ||||
-rw-r--r-- | sys/dev/ata/atapi-tape.h | 12 |
18 files changed, 2263 insertions, 2053 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 */ diff --git a/sys/dev/ata/ata-all.h b/sys/dev/ata/ata-all.h index 4b04f96..3f31e47 100644 --- a/sys/dev/ata/ata-all.h +++ b/sys/dev/ata/ata-all.h @@ -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 @@ -65,7 +65,7 @@ #define ATA_C_READ 0x20 /* read command */ #define ATA_C_READ48 0x24 /* read command */ #define ATA_C_READ_DMA48 0x25 /* read w/DMA command */ -#define ATA_C_READ_DMA_QUEUED48 0x26 /* read w/DMA QUEUED command */ +#define ATA_C_READ_DMA_QUEUED48 0x26 /* read w/DMA QUEUED command */ #define ATA_C_READ_MUL48 0x29 /* read multi command */ #define ATA_C_WRITE 0x30 /* write command */ #define ATA_C_WRITE48 0x34 /* write command */ @@ -88,13 +88,13 @@ #define ATA_C_ATA_IDENTIFY 0xec /* get ATA params */ #define ATA_C_SETFEATURES 0xef /* features command */ #define ATA_C_F_SETXFER 0x03 /* set transfer mode */ -#define ATA_C_F_ENAB_WCACHE 0x02 /* enable write cache */ +#define ATA_C_F_ENAB_WCACHE 0x02 /* enable write cache */ #define ATA_C_F_DIS_WCACHE 0x82 /* disable write cache */ -#define ATA_C_F_ENAB_RCACHE 0xaa /* enable readahead cache */ +#define ATA_C_F_ENAB_RCACHE 0xaa /* enable readahead cache */ #define ATA_C_F_DIS_RCACHE 0x55 /* disable readahead cache */ -#define ATA_C_F_ENAB_RELIRQ 0x5d /* enable release interrupt */ +#define ATA_C_F_ENAB_RELIRQ 0x5d /* enable release interrupt */ #define ATA_C_F_DIS_RELIRQ 0xdd /* disable release interrupt */ -#define ATA_C_F_ENAB_SRVIRQ 0x5e /* enable service interrupt */ +#define ATA_C_F_ENAB_SRVIRQ 0x5e /* enable service interrupt */ #define ATA_C_F_DIS_SRVIRQ 0xde /* disable service interrupt */ #define ATA_STATUS 0x07 /* status register */ @@ -119,20 +119,16 @@ /* misc defines */ #define ATA_PRIMARY 0x1f0 #define ATA_SECONDARY 0x170 -#define ATA_MASTER 0x00 -#define ATA_SLAVE 0x10 #define ATA_IOSIZE 0x08 #define ATA_ALTIOSIZE 0x01 #define ATA_BMIOSIZE 0x08 #define ATA_OP_FINISHED 0x00 #define ATA_OP_CONTINUES 0x01 -#define ATA_DEV(device) ((device == ATA_MASTER) ? 0 : 1) -#define ATA_PARAM(scp, device) (scp->dev_param[ATA_DEV(device)]) - #define ATA_IOADDR_RID 0 #define ATA_ALTADDR_RID 1 #define ATA_BMADDR_RID 2 #define ATA_IRQ_RID 0 +#define ATA_DEV(device) ((device == ATA_MASTER) ? 0 : 1) /* busmaster DMA related defines */ #define ATA_DMA_ENTRIES 256 @@ -162,22 +158,38 @@ struct ata_dmaentry { u_int32_t count; }; -/* structure describing an ATA device */ -struct ata_softc { +/* structure describing an ATA/ATAPI device */ +struct ata_device { + struct ata_channel *channel; + int unit; /* unit number */ +#define ATA_MASTER 0x00 +#define ATA_SLAVE 0x10 + + char *name; /* device name */ + struct ata_params *param; /* ata param structure */ + void *driver; /* ptr to driver for device */ + int flags; +#define ATA_D_USE_CHS 0x0001 +#define ATA_D_DETACHING 0x0002 +#define ATA_D_MEDIA_CHANGED 0x0004 + + int mode; /* transfermode */ + int cmd; /* last cmd executed */ + void *result; /* misc data */ +}; + +/* structure describing an ATA channel */ +struct ata_channel { struct device *dev; /* device handle */ - int channel; /* channel on this controller */ + int unit; /* channel number */ struct resource *r_io; /* io addr resource handle */ struct resource *r_altio; /* altio addr resource handle */ struct resource *r_bmio; /* bmio addr resource handle */ struct resource *r_irq; /* interrupt of this channel */ void *ih; /* interrupt handle */ - int (*intr_func)(struct ata_softc *); /* interrupt function */ + int (*intr_func)(struct ata_channel *); /* interrupt function */ u_int32_t chiptype; /* pciid of controller chip */ u_int32_t alignment; /* dma engine min alignment */ - char *dev_name[2]; /* name of device */ - struct ata_params *dev_param[2]; /* ptr to devices params */ - void *dev_softc[2]; /* ptr to devices softc's */ - int mode[2]; /* transfer mode for devices */ int flags; /* controller flags */ #define ATA_NO_SLAVE 0x01 #define ATA_USE_16BIT 0x02 @@ -185,6 +197,10 @@ struct ata_softc { #define ATA_QUEUED 0x08 #define ATA_DMA_ACTIVE 0x10 + struct ata_device device[2]; /* devices on this channel */ +#define MASTER 0x00 +#define SLAVE 0x01 + int devices; /* what is present */ #define ATA_ATA_MASTER 0x01 #define ATA_ATA_SLAVE 0x02 @@ -199,7 +215,6 @@ struct ata_softc { #define ATA_WAIT_INTR 0x0002 #define ATA_WAIT_READY 0x0004 #define ATA_WAIT_MASK 0x0007 -#define ATA_USE_CHS 0x0008 #define ATA_ACTIVE 0x0010 #define ATA_ACTIVE_ATA 0x0020 #define ATA_ACTIVE_ATAPI 0x0040 @@ -210,6 +225,12 @@ struct ata_softc { void *running; /* currently running request */ }; +/* disk bay/drawer related */ +#define ATA_LED_OFF 0x00 +#define ATA_LED_RED 0x01 +#define ATA_LED_GREEN 0x02 +#define ATA_LED_ORANGE 0x03 + /* externs */ extern devclass_t ata_devclass; @@ -219,14 +240,16 @@ int ata_attach(device_t); int ata_detach(device_t); int ata_resume(device_t); -void ata_start(struct ata_softc *); -void ata_reset(struct ata_softc *); -int ata_reinit(struct ata_softc *); -int ata_wait(struct ata_softc *, int, u_int8_t); -int ata_command(struct ata_softc *, int, u_int8_t, u_int64_t, u_int16_t, u_int8_t, int); -int ata_printf(struct ata_softc *, int, const char *, ...) __printflike(3, 4); -void ata_set_name(struct ata_softc *, int, char *, int); -void ata_free_name(struct ata_softc *, int); +void ata_start(struct ata_channel *); +void ata_reset(struct ata_channel *); +int ata_reinit(struct ata_channel *); +int ata_wait(struct ata_device *, u_int8_t); +int ata_command(struct ata_device *, u_int8_t, u_int64_t, u_int16_t, u_int8_t, int); +void ata_drawerleds(struct ata_device *, u_int8_t); +int ata_printf(struct ata_channel *, int, const char *, ...) __printflike(3, 4); +int ata_prtdev(struct ata_device *, const char *, ...) __printflike(2, 3); +void ata_set_name(struct ata_device *, char *, int); +void ata_free_name(struct ata_device *); int ata_get_lun(u_int32_t *); int ata_test_lun(u_int32_t *, int); void ata_free_lun(u_int32_t *, int); @@ -236,12 +259,12 @@ int ata_wmode(struct ata_params *); int ata_umode(struct ata_params *); int ata_find_dev(device_t, u_int32_t, u_int32_t); -void *ata_dmaalloc(struct ata_softc *, int); -void ata_dmainit(struct ata_softc *, int, int, int, int); -int ata_dmasetup(struct ata_softc *, int, struct ata_dmaentry *, caddr_t, int); -void ata_dmastart(struct ata_softc *, int, struct ata_dmaentry *, int); -int ata_dmastatus(struct ata_softc *); -int ata_dmadone(struct ata_softc *); +void *ata_dmaalloc(struct ata_channel *, int); +void ata_dmainit(struct ata_channel *, int, int, int, int); +int ata_dmasetup(struct ata_channel *, int, struct ata_dmaentry *, caddr_t, int); +void ata_dmastart(struct ata_channel *, int, struct ata_dmaentry *, int); +int ata_dmastatus(struct ata_channel *); +int ata_dmadone(struct ata_channel *); /* macros to hide busspace uglyness */ #define ATA_INB(res, offset) \ diff --git a/sys/dev/ata/ata-card.c b/sys/dev/ata/ata-card.c index f66ee27..586a625 100644 --- a/sys/dev/ata/ata-card.c +++ b/sys/dev/ata/ata-card.c @@ -50,8 +50,8 @@ static int ata_pccard_match(device_t dev) { - int error = 0; - u_int32_t fcn = PCCARD_FUNCTION_UNSPEC; + u_int32_t fcn = PCCARD_FUNCTION_UNSPEC; + int error = 0; error = pccard_get_function(dev, &fcn); if (error != 0) @@ -69,7 +69,7 @@ ata_pccard_match(device_t dev) static int ata_pccard_probe(device_t dev) { - struct ata_softc *scp = device_get_softc(dev); + struct ata_channel *ch = device_get_softc(dev); struct resource *io; int rid, len, start, end; u_long tmp; @@ -108,8 +108,8 @@ ata_pccard_probe(device_t dev) else return ENOMEM; - scp->channel = 0; - scp->flags |= (ATA_USE_16BIT | ATA_NO_SLAVE); + ch->unit = 0; + ch->flags |= (ATA_USE_16BIT | ATA_NO_SLAVE); return ata_probe(dev); } @@ -129,7 +129,7 @@ static device_method_t ata_pccard_methods[] = { static driver_t ata_pccard_driver = { "ata", ata_pccard_methods, - sizeof(struct ata_softc), + sizeof(struct ata_channel), }; DRIVER_MODULE(ata, pccard, ata_pccard_driver, ata_devclass, 0, 0); diff --git a/sys/dev/ata/ata-disk.c b/sys/dev/ata/ata-disk.c index 062aed5..68b5262 100644 --- a/sys/dev/ata/ata-disk.c +++ b/sys/dev/ata/ata-disk.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 @@ -80,15 +80,18 @@ static void ad_timeout(struct ad_request *); static void ad_free(struct ad_request *); static int ad_version(u_int16_t); +/* misc defines */ +#define AD_MAX_RETRIES 3 + /* internal vars */ static u_int32_t adp_lun_map = 0; -static MALLOC_DEFINE(M_AD, "AD driver", "ATA disk driver"); static int ata_dma = 1; static int ata_wc = 0; static int ata_tags = 0; TUNABLE_INT("hw.ata.ata_dma", &ata_dma); TUNABLE_INT("hw.ata.wc", &ata_wc); TUNABLE_INT("hw.ata.tags", &ata_tags); +static MALLOC_DEFINE(M_AD, "AD driver", "ATA disk driver"); /* sysctl vars */ SYSCTL_DECL(_hw_ata); @@ -99,94 +102,90 @@ SYSCTL_INT(_hw_ata, OID_AUTO, wc, CTLFLAG_RD, &ata_wc, 0, SYSCTL_INT(_hw_ata, OID_AUTO, tags, CTLFLAG_RD, &ata_tags, 0, "ATA disk tagged queuing support"); -/* defines */ -#define AD_MAX_RETRIES 3 -#define AD_PARAM ATA_PARAM(adp->controller, adp->unit) - /* experimental cache flush on BIO_ORDERED */ #undef ATA_FLUSHCACHE_ON void -ad_attach(struct ata_softc *scp, int device) +ad_attach(struct ata_device *atadev) { struct ad_softc *adp; dev_t dev; if (!(adp = malloc(sizeof(struct ad_softc), M_AD, M_NOWAIT | M_ZERO))) { - ata_printf(scp, device, "failed to allocate driver storage\n"); + ata_prtdev(atadev, "failed to allocate driver storage\n"); return; } - adp->controller = scp; - adp->unit = device; + adp->device = atadev; #ifdef ATA_STATIC_ID - adp->lun = (device_get_unit(scp->dev) << 1) + ATA_DEV(device); + adp->lun = (device_get_unit(atadev->channel->dev)<<1)+ATA_DEV(atadev->unit); #else adp->lun = ata_get_lun(&adp_lun_map); #endif - ata_set_name(scp, device, "ad", adp->lun); - adp->heads = AD_PARAM->heads; - adp->sectors = AD_PARAM->sectors; - adp->total_secs = AD_PARAM->cylinders * adp->heads * adp->sectors; + ata_set_name(atadev, "ad", adp->lun); + adp->heads = atadev->param->heads; + adp->sectors = atadev->param->sectors; + adp->total_secs = atadev->param->cylinders * adp->heads * adp->sectors; /* does this device need oldstyle CHS addressing */ - if (!ad_version(AD_PARAM->version_major) || - !(AD_PARAM->atavalid & ATA_FLAG_54_58) || !AD_PARAM->lba_size) + if (!ad_version(atadev->param->version_major) || + !(atadev->param->atavalid & ATA_FLAG_54_58) || !atadev->param->lba_size) adp->flags |= AD_F_CHS_USED; /* use the 28bit LBA size if valid */ - if (AD_PARAM->cylinders == 16383 && adp->total_secs < AD_PARAM->lba_size) - adp->total_secs = AD_PARAM->lba_size; + if (atadev->param->cylinders == 16383 && + adp->total_secs < atadev->param->lba_size) + adp->total_secs = atadev->param->lba_size; /* use the 48bit LBA size if valid */ - if (AD_PARAM->support.address48) - adp->total_secs = AD_PARAM->lba_size48; + if (atadev->param->support.address48) + adp->total_secs = atadev->param->lba_size48; /* use multiple sectors/interrupt if device supports it */ adp->transfersize = DEV_BSIZE; - if (ad_version(AD_PARAM->version_major)) { - int secsperint = max(1, min(AD_PARAM->sectors_intr, 16)); + if (ad_version(atadev->param->version_major)) { + int secsperint = max(1, min(atadev->param->sectors_intr, 16)); - if (!ata_command(adp->controller, adp->unit, ATA_C_SET_MULTI, - 0, secsperint, 0, ATA_WAIT_INTR) && - !ata_wait(adp->controller, adp->unit, 0)) - adp->transfersize *= secsperint; + if (!ata_command(atadev, ATA_C_SET_MULTI, 0, secsperint, + 0, ATA_WAIT_INTR) && !ata_wait(atadev, 0)) + adp->transfersize *= secsperint; } - /* enable read cacheing if not default on device */ - if (ata_command(adp->controller, adp->unit, ATA_C_SETFEATURES, + /* enable read caching if not default on device */ + if (ata_command(atadev, ATA_C_SETFEATURES, 0, 0, ATA_C_F_ENAB_RCACHE, ATA_WAIT_INTR)) - ata_printf(scp, device, "enabling readahead cache failed\n"); + ata_prtdev(atadev, "enabling readahead cache failed\n"); - /* enable write cacheing if allowed and not default on device */ + /* enable write caching if allowed and not default on device */ if (ata_wc || (ata_tags && ad_tagsupported(adp))) { - if (ata_command(adp->controller, adp->unit, ATA_C_SETFEATURES, + if (ata_command(atadev, ATA_C_SETFEATURES, 0, 0, ATA_C_F_ENAB_WCACHE, ATA_WAIT_INTR)) - ata_printf(scp, device, "enabling write cache failed\n"); + ata_prtdev(atadev, "enabling write cache failed\n"); } else { - if (ata_command(adp->controller, adp->unit, ATA_C_SETFEATURES, + if (ata_command(atadev, ATA_C_SETFEATURES, 0, 0, ATA_C_F_DIS_WCACHE, ATA_WAIT_INTR)) - ata_printf(scp, device, "disabling write cache failed\n"); + ata_prtdev(atadev, "disabling write cache failed\n"); } /* use DMA if allowed and if drive/controller supports it */ if (ata_dma) - ata_dmainit(adp->controller, adp->unit, ata_pmode(AD_PARAM), - ata_wmode(AD_PARAM), ata_umode(AD_PARAM)); + ata_dmainit(atadev->channel, atadev->unit, ata_pmode(atadev->param), + ata_wmode(atadev->param), ata_umode(atadev->param)); else - ata_dmainit(adp->controller, adp->unit, ata_pmode(AD_PARAM), -1, -1); + ata_dmainit(atadev->channel, atadev->unit, + ata_pmode(atadev->param), -1, -1); /* use tagged queueing if allowed and supported */ if (ata_tags && ad_tagsupported(adp)) { - adp->num_tags = AD_PARAM->queuelen; + adp->num_tags = atadev->param->queuelen; adp->flags |= AD_F_TAG_ENABLED; - adp->controller->flags |= ATA_QUEUED; - if (ata_command(adp->controller, adp->unit, ATA_C_SETFEATURES, + adp->device->channel->flags |= ATA_QUEUED; + if (ata_command(atadev, ATA_C_SETFEATURES, 0, 0, ATA_C_F_DIS_RELIRQ, ATA_WAIT_INTR)) - ata_printf(scp, device, "disabling release interrupt failed\n"); - if (ata_command(adp->controller, adp->unit, ATA_C_SETFEATURES, + ata_prtdev(atadev, "disabling release interrupt failed\n"); + if (ata_command(atadev, ATA_C_SETFEATURES, 0, 0, ATA_C_F_DIS_SRVIRQ, ATA_WAIT_INTR)) - ata_printf(scp, device, "disabling service interrupt failed\n"); + ata_prtdev(atadev, "disabling service interrupt failed\n"); } devstat_add_entry(&adp->stats, "ad", adp->lun, DEV_BSIZE, @@ -200,12 +199,6 @@ ad_attach(struct ata_softc *scp, int device) adp->dev = dev; bioq_init(&adp->queue); - /* if this disk belongs to an ATA RAID dont print the probe */ - if (!ar_probe(adp)) - adp->flags |= AD_F_RAID_SUBDISK; - else - ad_print(adp, ""); - /* construct the disklabel */ bzero(&adp->disk.d_label, sizeof(struct disklabel)); adp->disk.d_label.d_secsize = DEV_BSIZE; @@ -215,44 +208,46 @@ ad_attach(struct ata_softc *scp, int device) adp->disk.d_label.d_secpercyl = adp->sectors * adp->heads; adp->disk.d_label.d_secperunit = adp->total_secs; - /* store our softc signalling we are ready to go */ - scp->dev_softc[ATA_DEV(device)] = adp; + atadev->driver = adp; + + /* if this disk belongs to an ATA RAID dont print the probe */ + if (!ar_probe(adp)) + adp->flags |= AD_F_RAID_SUBDISK; + else + ad_print(adp, ""); } void -ad_detach(struct ad_softc *adp, int flush) +ad_detach(struct ata_device *atadev, int flush) /* get rid of flush XXX SOS */ { + struct ad_softc *adp = atadev->driver; struct ad_request *request; struct bio *bp; - adp->flags |= AD_F_DETACHING; - - if (adp->flags & AD_F_RAID_SUBDISK) - printf("WARNING! detaching RAID subdisk, danger ahead\n"); - - ata_printf(adp->controller, adp->unit, "removed from configuration\n"); + atadev->flags |= ATA_D_DETACHING; + ata_prtdev(atadev, "removed from configuration\n"); ad_invalidatequeue(adp, NULL); - TAILQ_FOREACH(request, &adp->controller->ata_queue, chain) { - if (request->device != adp) + TAILQ_FOREACH(request, &atadev->channel->ata_queue, chain) { + if (request->softc != adp) continue; - TAILQ_REMOVE(&adp->controller->ata_queue, request, chain); + TAILQ_REMOVE(&atadev->channel->ata_queue, request, chain); biofinish(request->bp, NULL, ENXIO); ad_free(request); } while ((bp = bioq_first(&adp->queue))) { + bioq_remove(&adp->queue, bp); biofinish(bp, NULL, ENXIO); } disk_invalidate(&adp->disk); disk_destroy(adp->dev); devstat_remove_entry(&adp->stats); if (flush) { - if (ata_command(adp->controller, adp->unit, ATA_C_FLUSHCACHE, - 0, 0, 0, ATA_WAIT_READY)) - ata_printf(adp->controller, adp->unit, - "flushing cache on detach failed\n"); + if (ata_command(atadev, ATA_C_FLUSHCACHE, 0, 0, 0, ATA_WAIT_READY)) + ata_prtdev(atadev, "flushing cache on detach failed\n"); } + ata_free_name(atadev); ata_free_lun(&adp_lun_map, adp->lun); - adp->controller->dev_softc[ATA_DEV(adp->unit)] = NULL; + atadev->driver = NULL; free(adp, M_AD); } @@ -271,10 +266,8 @@ adclose(dev_t dev, int flags, int fmt, struct thread *td) { struct ad_softc *adp = dev->si_drv1; - if (ata_command(adp->controller, adp->unit, ATA_C_FLUSHCACHE, - 0, 0, 0, ATA_WAIT_READY)) - ata_printf(adp->controller, adp->unit, - "flushing cache on close failed\n"); + if (ata_command(adp->device, ATA_C_FLUSHCACHE, 0, 0, 0, ATA_WAIT_READY)) + ata_prtdev(adp->device, "flushing cache on close failed\n"); return 0; } @@ -284,14 +277,13 @@ adstrategy(struct bio *bp) struct ad_softc *adp = bp->bio_dev->si_drv1; int s; - if (adp->flags & AD_F_DETACHING) { + if (adp->device->flags & ATA_D_DETACHING) { biofinish(bp, NULL, ENXIO); return; } - s = splbio(); bioqdisksort(&adp->queue, bp); - ata_start(adp->controller); + ata_start(adp->device->channel); splx(s); } @@ -314,8 +306,8 @@ addump(dev_t dev) return ENXIO; /* force PIO mode for dumps */ - adp->controller->mode[ATA_DEV(adp->unit)] = ATA_PIO; - ata_reinit(adp->controller); + adp->device->mode = ATA_PIO; + ata_reinit(adp->device->channel); blkcnt = howmany(PAGE_SIZE, secsize); @@ -335,7 +327,7 @@ addump(dev_t dev) } bzero(&request, sizeof(struct ad_request)); - request.device = adp; + request.softc = adp; request.blockaddr = blkno; request.bytecount = PAGE_SIZE * dumppages; request.data = va; @@ -357,15 +349,15 @@ addump(dev_t dev) addr += PAGE_SIZE * dumppages; } - if (ata_wait(adp->controller, adp->unit, ATA_S_READY | ATA_S_DSC) < 0) - ata_printf(adp->controller, adp->unit, - "timeout waiting for final ready\n"); + if (ata_wait(adp->device, ATA_S_READY | ATA_S_DSC) < 0) + ata_prtdev(adp->device, "timeout waiting for final ready\n"); return 0; } void -ad_start(struct ad_softc *adp) +ad_start(struct ata_device *atadev) { + struct ad_softc *adp = atadev->driver; struct bio *bp = bioq_first(&adp->queue); struct ad_request *request; int tag = 0; @@ -392,12 +384,12 @@ ad_start(struct ad_softc *adp) } if (!(request = malloc(sizeof(struct ad_request), M_AD, M_NOWAIT|M_ZERO))) { - ata_printf(adp->controller, adp->unit, "out of memory in start\n"); + ata_prtdev(atadev, "out of memory in start\n"); return; } /* setup request */ - request->device = adp; + request->softc = adp; request->bp = bp; request->blockaddr = bp->bio_pblkno; request->bytecount = bp->bio_bcount; @@ -405,9 +397,9 @@ ad_start(struct ad_softc *adp) request->tag = tag; if (bp->bio_cmd == BIO_READ) request->flags |= ADR_F_READ; - if (adp->controller->mode[ATA_DEV(adp->unit)] >= ATA_DMA) { - if (!(request->dmatab = ata_dmaalloc(adp->controller, adp->unit))) - adp->controller->mode[ATA_DEV(adp->unit)] = ATA_PIO; + if (adp->device->mode >= ATA_DMA) { + if (!(request->dmatab = ata_dmaalloc(atadev->channel, atadev->unit))) + adp->device->mode = ATA_PIO; } /* insert in tag array */ @@ -417,7 +409,7 @@ ad_start(struct ad_softc *adp) bioq_remove(&adp->queue, bp); /* link onto controller queue */ - TAILQ_INSERT_TAIL(&adp->controller->ata_queue, request, chain); + TAILQ_INSERT_TAIL(&atadev->channel->ata_queue, request, chain); } int @@ -430,7 +422,7 @@ ad_transfer(struct ad_request *request) int flags = ATA_IMMEDIATE; /* get request params */ - adp = request->device; + adp = request->softc; /* calculate transfer details */ lba = request->blockaddr + (request->donecount / DEV_BSIZE); @@ -446,9 +438,9 @@ ad_transfer(struct ad_request *request) /* setup transfer parameters !! 65536 for 48bit SOS XXX */ count = howmany(request->bytecount, DEV_BSIZE); - max_count = AD_PARAM->support.address48 ? 65536 : 256; + max_count = adp->device->param->support.address48 ? 65536 : 256; if (count > max_count) { - ata_printf(adp->controller, adp->unit, + ata_prtdev(adp->device, "count %d size transfers not supported\n", count); count = max_count; } @@ -459,7 +451,7 @@ ad_transfer(struct ad_request *request) int head = (lba % (adp->sectors * adp->heads)) / adp->sectors; lba = (sector&0xff) | ((cylinder&0xffff)<<8) | ((head&0xf)<<24); - flags |= ATA_USE_CHS; + adp->device->flags |= ATA_D_USE_CHS; } /* setup first transfer length */ @@ -469,66 +461,59 @@ ad_transfer(struct ad_request *request) /* does this drive & transfer work with DMA ? */ request->flags &= ~ADR_F_DMA_USED; - if (adp->controller->mode[ATA_DEV(adp->unit)] >= ATA_DMA && - !ata_dmasetup(adp->controller, adp->unit, request->dmatab, - request->data, request->bytecount)) { + if (adp->device->mode >= ATA_DMA && + !ata_dmasetup(adp->device->channel, adp->device->unit, + request->dmatab, request->data, request->bytecount)) { request->flags |= ADR_F_DMA_USED; request->currentsize = request->bytecount; /* do we have tags enabled ? */ if (adp->flags & AD_F_TAG_ENABLED) { - cmd = (request->flags & ADR_F_READ) ? + cmd = (request->flags & ADR_F_READ) ? ATA_C_READ_DMA_QUEUED : ATA_C_WRITE_DMA_QUEUED; - if (ata_command(adp->controller, adp->unit, cmd, lba, + if (ata_command(adp->device, cmd, lba, request->tag << 3, count, flags)) { - ata_printf(adp->controller, adp->unit, - "error executing command"); + ata_prtdev(adp->device, "error executing command"); goto transfer_failed; } - if (ata_wait(adp->controller, adp->unit, ATA_S_READY)) { - ata_printf(adp->controller, adp->unit, - "timeout waiting for READY\n"); + if (ata_wait(adp->device, ATA_S_READY)) { + ata_prtdev(adp->device, "timeout waiting for READY\n"); goto transfer_failed; } adp->outstanding++; /* if ATA bus RELEASE check for SERVICE */ if (adp->flags & AD_F_TAG_ENABLED && - ATA_INB(adp->controller->r_io, ATA_IREASON) & ATA_I_RELEASE) + ATA_INB(adp->device->channel->r_io, ATA_IREASON) & + ATA_I_RELEASE) return ad_service(adp, 1); } else { - cmd = (request->flags & ADR_F_READ) ? + cmd = (request->flags & ADR_F_READ) ? ATA_C_READ_DMA : ATA_C_WRITE_DMA; - if (ata_command(adp->controller, adp->unit, - cmd, lba, count, 0, flags)) { - ata_printf(adp->controller, adp->unit, - "error executing command"); + if (ata_command(adp->device, cmd, lba, count, 0, flags)) { + ata_prtdev(adp->device, "error executing command"); goto transfer_failed; } #if 0 /* * wait for data transfer phase * - * well this should be here acording to specs, but + * well this should be here acording to specs, but older * promise controllers doesn't like it, they lockup! - * thats probably why tags doesn't work on the promise - * as this is needed there... */ - if (ata_wait(adp->controller, adp->unit, - ATA_S_READY | ATA_S_DRQ)) { - ata_printf(adp->controller, adp->unit, - "timeout waiting for data phase\n"); + if (ata_wait(adp->device, ATA_S_READY | ATA_S_DRQ)) { + ata_prtdev(adp->device, "timeout waiting for data phase\n"); goto transfer_failed; } #endif } /* start transfer, return and wait for interrupt */ - ata_dmastart(adp->controller, adp->unit, - request->dmatab, request->flags & ADR_F_READ); + ata_dmastart(adp->device->channel, adp->device->unit, + request->dmatab, request->flags & ADR_F_READ); return ATA_OP_CONTINUES; } @@ -540,8 +525,8 @@ ad_transfer(struct ad_request *request) else cmd = request->flags&ADR_F_READ ? ATA_C_READ : ATA_C_WRITE; - if (ata_command(adp->controller, adp->unit, cmd, lba, count, 0, flags)){ - ata_printf(adp->controller, adp->unit, "error executing command"); + if (ata_command(adp->device, cmd, lba, count, 0, flags)){ + ata_prtdev(adp->device, "error executing command"); goto transfer_failed; } } @@ -554,19 +539,18 @@ ad_transfer(struct ad_request *request) return ATA_OP_CONTINUES; /* ready to write PIO data ? */ - if (ata_wait(adp->controller, adp->unit, - (ATA_S_READY | ATA_S_DSC | ATA_S_DRQ)) < 0) { - ata_printf(adp->controller, adp->unit, "timeout waiting for DRQ"); + if (ata_wait(adp->device, (ATA_S_READY | ATA_S_DSC | ATA_S_DRQ)) < 0) { + ata_prtdev(adp->device, "timeout waiting for DRQ"); goto transfer_failed; } /* output the data */ - if (adp->controller->flags & ATA_USE_16BIT) - ATA_OUTSW(adp->controller->r_io, ATA_DATA, + if (adp->device->channel->flags & ATA_USE_16BIT) + ATA_OUTSW(adp->device->channel->r_io, ATA_DATA, (void *)((uintptr_t)request->data + request->donecount), request->currentsize / sizeof(int16_t)); else - ATA_OUTSL(adp->controller->r_io, ATA_DATA, + ATA_OUTSL(adp->device->channel->r_io, ATA_DATA, (void *)((uintptr_t)request->data + request->donecount), request->currentsize / sizeof(int32_t)); return ATA_OP_CONTINUES; @@ -578,7 +562,7 @@ transfer_failed: /* if retries still permit, reinject this request */ if (request->retries++ < AD_MAX_RETRIES) - TAILQ_INSERT_HEAD(&adp->controller->ata_queue, request, chain); + TAILQ_INSERT_HEAD(&adp->device->channel->ata_queue, request, chain); else { /* retries all used up, return error */ request->bp->bio_error = EIO; @@ -587,54 +571,54 @@ transfer_failed: biofinish(request->bp, &adp->stats, 0); ad_free(request); } - ata_reinit(adp->controller); + ata_reinit(adp->device->channel); return ATA_OP_CONTINUES; } int ad_interrupt(struct ad_request *request) { - struct ad_softc *adp = request->device; + struct ad_softc *adp = request->softc; int dma_stat = 0; #ifdef ATA_FLUSHCACHE_ON if (request->flags & ADR_F_FLUSHCACHE) - goto finish; + goto finish; #endif /* finish DMA transfer */ if (request->flags & ADR_F_DMA_USED) - dma_stat = ata_dmadone(adp->controller); + dma_stat = ata_dmadone(adp->device->channel); /* do we have a corrected soft error ? */ - if (adp->controller->status & ATA_S_CORR) + if (adp->device->channel->status & ATA_S_CORR) diskerr(request->bp, "soft error (ECC corrected)", request->blockaddr + (request->donecount / DEV_BSIZE), &adp->disk.d_label); /* did any real errors happen ? */ - if ((adp->controller->status & ATA_S_ERROR) || + if ((adp->device->channel->status & ATA_S_ERROR) || (request->flags & ADR_F_DMA_USED && dma_stat & ATA_BMSTAT_ERROR)) { - adp->controller->error = ATA_INB(adp->controller->r_io, ATA_ERROR); - diskerr(request->bp, - (adp->controller->error & ATA_E_ICRC) ? - "UDMA ICRC error" : "hard error", + adp->device->channel->error = + ATA_INB(adp->device->channel->r_io, ATA_ERROR); + diskerr(request->bp, (adp->device->channel->error & ATA_E_ICRC) ? + "UDMA ICRC error" : "hard error", request->blockaddr + (request->donecount / DEV_BSIZE), &adp->disk.d_label); /* if this is a UDMA CRC error, reinject request */ if (request->flags & ADR_F_DMA_USED && - adp->controller->error & ATA_E_ICRC) { + adp->device->channel->error & ATA_E_ICRC) { untimeout((timeout_t *)ad_timeout, request,request->timeout_handle); ad_invalidatequeue(adp, request); if (request->retries++ < AD_MAX_RETRIES) printf(" retrying\n"); else { - ata_dmainit(adp->controller, adp->unit, - ata_pmode(AD_PARAM), -1, -1); + ata_dmainit(adp->device->channel, adp->device->unit, + ata_pmode(adp->device->param), -1, -1); printf(" falling back to PIO mode\n"); } - TAILQ_INSERT_HEAD(&adp->controller->ata_queue, request, chain); + TAILQ_INSERT_HEAD(&adp->device->channel->ata_queue, request, chain); return ATA_OP_FINISHED; } @@ -642,49 +626,45 @@ ad_interrupt(struct ad_request *request) if (request->flags & ADR_F_DMA_USED) { untimeout((timeout_t *)ad_timeout, request,request->timeout_handle); ad_invalidatequeue(adp, request); - ata_dmainit(adp->controller, adp->unit, - ata_pmode(AD_PARAM), -1, -1); + ata_dmainit(adp->device->channel, adp->device->unit, + ata_pmode(adp->device->param), -1, -1); request->flags |= ADR_F_FORCE_PIO; - TAILQ_INSERT_HEAD(&adp->controller->ata_queue, request, chain); + TAILQ_INSERT_HEAD(&adp->device->channel->ata_queue, request, chain); return ATA_OP_FINISHED; } request->flags |= ADR_F_ERROR; printf(" status=%02x error=%02x\n", - adp->controller->status, adp->controller->error); + adp->device->channel->status, adp->device->channel->error); } /* if we arrived here with forced PIO mode, DMA doesn't work right */ if (request->flags & ADR_F_FORCE_PIO) - ata_printf(adp->controller, adp->unit, - "DMA problem fallback to PIO mode\n"); + ata_prtdev(adp->device, "DMA problem fallback to PIO mode\n"); /* if this was a PIO read operation, get the data */ if (!(request->flags & ADR_F_DMA_USED) && (request->flags & (ADR_F_READ | ADR_F_ERROR)) == ADR_F_READ) { /* ready to receive data? */ - if ((adp->controller->status & (ATA_S_READY | ATA_S_DSC | ATA_S_DRQ)) - != (ATA_S_READY | ATA_S_DSC | ATA_S_DRQ)) - ata_printf(adp->controller, adp->unit, - "read interrupt arrived early"); - - if (ata_wait(adp->controller, adp->unit, - (ATA_S_READY | ATA_S_DSC | ATA_S_DRQ)) != 0) { - ata_printf(adp->controller, adp->unit, - "read error detected (too) late"); + if ((adp->device->channel->status & (ATA_S_READY|ATA_S_DSC|ATA_S_DRQ)) + != (ATA_S_READY|ATA_S_DSC|ATA_S_DRQ)) + ata_prtdev(adp->device, "read interrupt arrived early"); + + if (ata_wait(adp->device, (ATA_S_READY | ATA_S_DSC | ATA_S_DRQ)) != 0) { + ata_prtdev(adp->device, "read error detected (too) late"); request->flags |= ADR_F_ERROR; } else { /* data ready, read in */ - if (adp->controller->flags & ATA_USE_16BIT) - ATA_INSW(adp->controller->r_io, ATA_DATA, - (void *)((uintptr_t)request->data + request->donecount), - request->currentsize / sizeof(int16_t)); + if (adp->device->channel->flags & ATA_USE_16BIT) + ATA_INSW(adp->device->channel->r_io, ATA_DATA, + (void*)((uintptr_t)request->data + request->donecount), + request->currentsize / sizeof(int16_t)); else - ATA_INSL(adp->controller->r_io, ATA_DATA, - (void *)((uintptr_t)request->data + request->donecount), - request->currentsize / sizeof(int32_t)); + ATA_INSL(adp->device->channel->r_io, ATA_DATA, + (void*)((uintptr_t)request->data + request->donecount), + request->currentsize / sizeof(int32_t)); } } @@ -710,9 +690,8 @@ ad_interrupt(struct ad_request *request) #ifdef ATA_FLUSHCACHE_ON if (request->bp->bio_flags & BIO_ORDERED) { request->flags |= ADR_F_FLUSHCACHE; - if (ata_command(adp->controller, adp->unit, ATA_C_FLUSHCACHE, - 0, 0, 0, ATA_IMMEDIATE)) - ata_printf(adp->controller, adp->unit, "flushing cache failed\n"); + if (ata_command(adp->device, ATA_C_FLUSHCACHE, 0, 0, 0, ATA_IMMEDIATE)) + ata_prtdev(adp->device, "flushing cache failed\n"); else return ATA_OP_CONTINUES; } @@ -730,87 +709,86 @@ int ad_service(struct ad_softc *adp, int change) { /* do we have to check the other device on this channel ? */ - if (adp->controller->flags & ATA_QUEUED && change) { - int device = adp->unit; - - if (adp->unit == ATA_MASTER) { - if (adp->controller->devices & ATA_ATA_SLAVE && - ((struct ad_softc *) - (adp->controller->dev_softc[ATA_DEV(ATA_SLAVE)]))->flags & - AD_F_TAG_ENABLED) + if (adp->device->channel->flags & ATA_QUEUED && change) { + int device = adp->device->unit; + + if (adp->device->unit == ATA_MASTER) { + if (adp->device->channel->devices & ATA_ATA_SLAVE && + ((struct ad_softc *) + (adp->device->channel-> + device[ATA_DEV(ATA_SLAVE)].driver))->flags&AD_F_TAG_ENABLED) device = ATA_SLAVE; } else { - if (adp->controller->devices & ATA_ATA_MASTER && - ((struct ad_softc *) - (adp->controller->dev_softc[ATA_DEV(ATA_MASTER)]))->flags & - AD_F_TAG_ENABLED) + if (adp->device->channel->devices & ATA_ATA_MASTER && + ((struct ad_softc *) + (adp->device->channel-> + device[ATA_DEV(ATA_MASTER)].driver))->flags&AD_F_TAG_ENABLED) device = ATA_MASTER; } - if (device != adp->unit && + if (device != adp->device->unit && ((struct ad_softc *) - (adp->controller->dev_softc[ATA_DEV(device)]))->outstanding > 0) { - ATA_OUTB(adp->controller->r_io, ATA_DRIVE, ATA_D_IBM | device); - adp = adp->controller->dev_softc[ATA_DEV(device)]; + (adp->device->channel-> + device[ATA_DEV(device)].driver))->outstanding > 0) { + ATA_OUTB(adp->device->channel->r_io, ATA_DRIVE, ATA_D_IBM | device); + adp = adp->device->channel->device[ATA_DEV(device)].driver; DELAY(1); } } - adp->controller->status = ATA_INB(adp->controller->r_altio, ATA_ALTSTAT); + adp->device->channel->status = + ATA_INB(adp->device->channel->r_altio, ATA_ALTSTAT); /* do we have a SERVICE request from the drive ? */ if (adp->flags & AD_F_TAG_ENABLED && adp->outstanding > 0 && - adp->controller->status & ATA_S_SERVICE) { + adp->device->channel->status & ATA_S_SERVICE) { struct ad_request *request; int tag; /* check for error */ - if (adp->controller->status & ATA_S_ERROR) { - ata_printf(adp->controller, adp->unit, - "Oops! controller says s=0x%02x e=0x%02x\n", - adp->controller->status, adp->controller->error); + if (adp->device->channel->status & ATA_S_ERROR) { + ata_prtdev(adp->device, "Oops! controller says s=0x%02x e=0x%02x\n", + adp->device->channel->status, + adp->device->channel->error); ad_invalidatequeue(adp, NULL); return ATA_OP_FINISHED; } /* issue SERVICE cmd */ - if (ata_command(adp->controller, adp->unit, ATA_C_SERVICE, - 0, 0, 0, ATA_IMMEDIATE)) { - ata_printf(adp->controller, adp->unit, - "problem executing SERVICE cmd\n"); + if (ata_command(adp->device, ATA_C_SERVICE, 0, 0, 0, ATA_IMMEDIATE)) { + ata_prtdev(adp->device, "problem executing SERVICE cmd\n"); ad_invalidatequeue(adp, NULL); return ATA_OP_FINISHED; } /* setup the transfer environment when ready */ - if (ata_wait(adp->controller, adp->unit, ATA_S_READY)) { - ata_printf(adp->controller, adp->unit, - "problem issueing SERVICE tag=%d s=0x%02x e=0x%02x\n", - ATA_INB(adp->controller->r_io, ATA_COUNT) >> 3, - adp->controller->status, adp->controller->error); + if (ata_wait(adp->device, ATA_S_READY)) { + ata_prtdev(adp->device, "SERVICE timeout tag=%d s=%02x e=%02x\n", + ATA_INB(adp->device->channel->r_io, ATA_COUNT) >> 3, + adp->device->channel->status, + adp->device->channel->error); ad_invalidatequeue(adp, NULL); return ATA_OP_FINISHED; } - tag = ATA_INB(adp->controller->r_io, ATA_COUNT) >> 3; + tag = ATA_INB(adp->device->channel->r_io, ATA_COUNT) >> 3; if (!(request = adp->tags[tag])) { - ata_printf(adp->controller, adp->unit, - "no request for tag=%d\n", tag); + ata_prtdev(adp->device, "no request for tag=%d\n", tag); ad_invalidatequeue(adp, NULL); return ATA_OP_FINISHED; } - adp->controller->active = ATA_ACTIVE_ATA; - adp->controller->running = request; + adp->device->channel->active = ATA_ACTIVE_ATA; + adp->device->channel->running = request; request->serv++; /* start DMA transfer when ready */ - if (ata_wait(adp->controller, adp->unit, ATA_S_READY | ATA_S_DRQ)) { - ata_printf(adp->controller, adp->unit, - "timeout waiting for data phase s=%02x e=%02x\n", - adp->controller->status, adp->controller->error); + if (ata_wait(adp->device, ATA_S_READY | ATA_S_DRQ)) { + ata_prtdev(adp->device, "timeout starting DMA s=%02x e=%02x\n", + adp->device->channel->status, + adp->device->channel->error); ad_invalidatequeue(adp, NULL); return ATA_OP_FINISHED; } - ata_dmastart(adp->controller, adp->unit, + ata_dmastart(adp->device->channel, adp->device->unit, request->dmatab, request->flags & ADR_F_READ); return ATA_OP_CONTINUES; } @@ -824,7 +802,7 @@ ad_free(struct ad_request *request) if (request->dmatab) free(request->dmatab, M_DEVBUF); - request->device->tags[request->tag] = NULL; + request->softc->tags[request->tag] = NULL; free(request, M_AD); splx(s); @@ -838,18 +816,18 @@ ad_invalidatequeue(struct ad_softc *adp, struct ad_request *request) struct ad_request *tmpreq; int tag; - ata_printf(adp->controller, adp->unit,"invalidating queued requests\n"); + ata_prtdev(adp->device, "invalidating queued requests\n"); for (tag = 0; tag <= adp->num_tags; tag++) { tmpreq = adp->tags[tag]; adp->tags[tag] = NULL; if (tmpreq == request || tmpreq == NULL) continue; - untimeout((timeout_t *)ad_timeout, tmpreq, tmpreq->timeout_handle); - TAILQ_INSERT_HEAD(&adp->controller->ata_queue, tmpreq, chain); + untimeout((timeout_t *)ad_timeout, tmpreq, tmpreq->timeout_handle); + TAILQ_INSERT_HEAD(&adp->device->channel->ata_queue, tmpreq, chain); } - if (ata_command(adp->controller, adp->unit, ATA_C_NOP, + if (ata_command(adp->device, ATA_C_NOP, 0, 0, ATA_C_F_FLUSHQUEUE, ATA_WAIT_READY)) - ata_printf(adp->controller, adp->unit, "flush queue failed\n"); + ata_prtdev(adp->device, "flush queue failed\n"); adp->outstanding = 0; } } @@ -857,22 +835,22 @@ ad_invalidatequeue(struct ad_softc *adp, struct ad_request *request) static int ad_tagsupported(struct ad_softc *adp) { - const char *drives[] = {"IBM-DPTA", "IBM-DTLA", NULL}; + const char *good[] = {"IBM-DPTA", "IBM-DTLA", NULL}; int i = 0; - switch (adp->controller->chiptype) { + switch (adp->device->channel->chiptype) { case 0x4d33105a: /* Promises before TX2 doesn't work with tagged queuing */ case 0x4d38105a: case 0x0d30105a: case 0x4d30105a: - return 0; + return 0; } /* check that drive does DMA, has tags enabled, and is one we know works */ - if (adp->controller->mode[ATA_DEV(adp->unit)] >= ATA_DMA && - AD_PARAM->support.queued && AD_PARAM->enabled.queued) { - while (drives[i] != NULL) { - if (!strncmp(AD_PARAM->model, drives[i], strlen(drives[i]))) + if (adp->device->mode >= ATA_DMA && adp->device->param->support.queued && + adp->device->param->enabled.queued) { + while (good[i] != NULL) { + if (!strncmp(adp->device->param->model, good[i], strlen(good[i]))) return 1; i++; } @@ -881,9 +859,9 @@ ad_tagsupported(struct ad_softc *adp) * we want "IC" (IBM CORP) and "AT" or "AV" (ATA interface) * but doesn't care about the other info (size, capacity etc) */ - if (!strncmp(AD_PARAM->model, "IC", 2) && - (!strncmp(AD_PARAM->model + 8, "AT", 2) || - !strncmp(AD_PARAM->model + 8, "AV", 2))) + if (!strncmp(adp->device->param->model, "IC", 2) && + (!strncmp(adp->device->param->model + 8, "AT", 2) || + !strncmp(adp->device->param->model + 8, "AV", 2))) return 1; } return 0; @@ -892,30 +870,28 @@ ad_tagsupported(struct ad_softc *adp) static void ad_timeout(struct ad_request *request) { - struct ad_softc *adp = request->device; + struct ad_softc *adp = request->softc; int s = splbio(); - adp->controller->running = NULL; - ata_printf(adp->controller, adp->unit, - "%s command timeout tag=%d serv=%d - resetting\n", + adp->device->channel->running = NULL; + ata_prtdev(adp->device, "%s command timeout tag=%d serv=%d - resetting\n", (request->flags & ADR_F_READ) ? "READ" : "WRITE", request->tag, request->serv); if (request->flags & ADR_F_DMA_USED) { - ata_dmadone(adp->controller); + ata_dmadone(adp->device->channel); ad_invalidatequeue(adp, request); - if (request->retries == AD_MAX_RETRIES) { - ata_dmainit(adp->controller, adp->unit, - ata_pmode(AD_PARAM), -1, -1); - ata_printf(adp->controller, adp->unit, - "trying fallback to PIO mode\n"); + if (request->retries == AD_MAX_RETRIES) { + ata_dmainit(adp->device->channel, adp->device->unit, + ata_pmode(adp->device->param), -1, -1); + ata_prtdev(adp->device, "trying fallback to PIO mode\n"); request->retries = 0; } } /* if retries still permit, reinject this request */ if (request->retries++ < AD_MAX_RETRIES) { - TAILQ_INSERT_HEAD(&adp->controller->ata_queue, request, chain); + TAILQ_INSERT_HEAD(&adp->device->channel->ata_queue, request, chain); } else { /* retries all used up, return error */ @@ -924,7 +900,7 @@ ad_timeout(struct ad_request *request) biofinish(request->bp, &adp->stats, 0); ad_free(request); } - ata_reinit(adp->controller); + ata_reinit(adp->device->channel); splx(s); } @@ -933,13 +909,16 @@ ad_reinit(struct ad_softc *adp) { /* reinit disk parameters */ ad_invalidatequeue(adp, NULL); - ata_command(adp->controller, adp->unit, ATA_C_SET_MULTI, 0, + ata_command(adp->device, ATA_C_SET_MULTI, 0, adp->transfersize / DEV_BSIZE, 0, ATA_WAIT_INTR); - if (adp->controller->mode[ATA_DEV(adp->unit)] >= ATA_DMA) - ata_dmainit(adp->controller, adp->unit, ata_pmode(AD_PARAM), - ata_wmode(AD_PARAM), ata_umode(AD_PARAM)); + if (adp->device->mode >= ATA_DMA) + ata_dmainit(adp->device->channel, adp->device->unit, + ata_pmode(adp->device->param), + ata_wmode(adp->device->param), + ata_umode(adp->device->param)); else - ata_dmainit(adp->controller, adp->unit, ata_pmode(AD_PARAM), -1, -1); + ata_dmainit(adp->device->channel, adp->device->unit, + ata_pmode(adp->device->param), -1, -1); } void @@ -947,15 +926,14 @@ ad_print(struct ad_softc *adp, char *prepend) { if (prepend) printf("%s", prepend); if (bootverbose) { - ata_printf(adp->controller, adp->unit, - "<%.40s/%.8s> ATA-%d disk at ata%d-%s\n", - AD_PARAM->model, AD_PARAM->revision, - ad_version(AD_PARAM->version_major), - device_get_unit(adp->controller->dev), - (adp->unit == ATA_MASTER) ? "master" : "slave"); + ata_prtdev(adp->device, "<%.40s/%.8s> ATA-%d disk at ata%d-%s\n", + adp->device->param->model, adp->device->param->revision, + ad_version(adp->device->param->version_major), + device_get_unit(adp->device->channel->dev), + (adp->device->unit == ATA_MASTER) ? "master" : "slave"); if (prepend) printf("%s", prepend); - ata_printf(adp->controller, adp->unit, + ata_prtdev(adp->device, "%lluMB (%llu sectors), %llu C, %u H, %u S, %u B\n", (unsigned long long)(adp->total_secs / ((1024L*1024L)/DEV_BSIZE)), @@ -965,32 +943,30 @@ ad_print(struct ad_softc *adp, char *prepend) adp->heads, adp->sectors, DEV_BSIZE); if (prepend) printf("%s", prepend); - ata_printf(adp->controller, adp->unit, - "%d secs/int, %d depth queue, %s%s\n", + ata_prtdev(adp->device, "%d secs/int, %d depth queue, %s%s\n", adp->transfersize / DEV_BSIZE, adp->num_tags + 1, (adp->flags & AD_F_TAG_ENABLED) ? "tagged " : "", - ata_mode2str(adp->controller->mode[ATA_DEV(adp->unit)])); + ata_mode2str(adp->device->mode)); if (prepend) printf("%s", prepend); - ata_printf(adp->controller, adp->unit, - "piomode=%d dmamode=%d udmamode=%d cblid=%d\n", - ata_pmode(AD_PARAM), ata_wmode(AD_PARAM), - ata_umode(AD_PARAM), AD_PARAM->hwres_cblid); + ata_prtdev(adp->device, "piomode=%d dmamode=%d udmamode=%d cblid=%d\n", + ata_pmode(adp->device->param), ata_wmode(adp->device->param), + ata_umode(adp->device->param), + adp->device->param->hwres_cblid); } else - ata_printf(adp->controller, adp->unit, - "%lluMB <%.40s> [%lld/%d/%d] at ata%d-%s %s%s\n", + ata_prtdev(adp->device,"%lluMB <%.40s> [%lld/%d/%d] at ata%d-%s %s%s\n", (unsigned long long)(adp->total_secs / ((1024L * 1024L) / DEV_BSIZE)), - AD_PARAM->model, + adp->device->param->model, (unsigned long long)(adp->total_secs / (adp->heads*adp->sectors)), adp->heads, adp->sectors, - device_get_unit(adp->controller->dev), - (adp->unit == ATA_MASTER) ? "master" : "slave", + device_get_unit(adp->device->channel->dev), + (adp->device->unit == ATA_MASTER) ? "master" : "slave", (adp->flags & AD_F_TAG_ENABLED) ? "tagged " : "", - ata_mode2str(adp->controller->mode[ATA_DEV(adp->unit)])); + ata_mode2str(adp->device->mode)); } static int diff --git a/sys/dev/ata/ata-disk.h b/sys/dev/ata/ata-disk.h index 217063f..0bf49d8 100644 --- a/sys/dev/ata/ata-disk.h +++ b/sys/dev/ata/ata-disk.h @@ -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 @@ -30,12 +30,12 @@ /* structure describing an ATA disk request */ struct ad_request { - struct ad_softc *device; /* ptr to parent device */ + struct ad_softc *softc; /* ptr to parent device */ u_int32_t blockaddr; /* block number */ u_int32_t bytecount; /* bytes to transfer */ u_int32_t donecount; /* bytes transferred */ u_int32_t currentsize; /* size of current transfer */ - struct callout_handle timeout_handle; /* handle for untimeout */ + struct callout_handle timeout_handle; /* handle for untimeout */ int retries; /* retry count */ int flags; #define ADR_F_READ 0x0001 @@ -55,8 +55,7 @@ struct ad_request { /* structure describing an ATA disk */ struct ad_softc { - struct ata_softc *controller; /* ptr to parent ctrl */ - int unit; /* ATA_MASTER or ATA_SLAVE */ + struct ata_device *device; /* ptr to device softc */ int lun; /* logical unit number */ u_int64_t total_secs; /* total # of sectors (LBA) */ u_int8_t heads; @@ -65,11 +64,10 @@ struct ad_softc { int num_tags; /* number of tags supported */ int flags; /* drive flags */ #define AD_F_LABELLING 0x0001 -#define AD_F_DETACHING 0x0002 -#define AD_F_CHS_USED 0x0004 -#define AD_F_32B_ENABLED 0x0008 -#define AD_F_TAG_ENABLED 0x0010 -#define AD_F_RAID_SUBDISK 0x0020 +#define AD_F_CHS_USED 0x0002 +#define AD_F_32B_ENABLED 0x0004 +#define AD_F_TAG_ENABLED 0x0008 +#define AD_F_RAID_SUBDISK 0x0010 struct ad_request *tags[32]; /* tag array of requests */ int outstanding; /* tags not serviced yet */ @@ -79,9 +77,9 @@ struct ad_softc { dev_t dev; /* device place holder */ }; -void ad_attach(struct ata_softc *, int); -void ad_detach(struct ad_softc *, int); -void ad_start(struct ad_softc *); +void ad_attach(struct ata_device *); +void ad_detach(struct ata_device *, int); +void ad_start(struct ata_device *); int ad_transfer(struct ad_request *); int ad_interrupt(struct ad_request *); int ad_service(struct ad_softc *, int); diff --git a/sys/dev/ata/ata-dma.c b/sys/dev/ata/ata-dma.c index f634053..a64d40a 100644 --- a/sys/dev/ata/ata-dma.c +++ b/sys/dev/ata/ata-dma.c @@ -45,29 +45,28 @@ #include <dev/ata/ata-all.h> /* prototypes */ -static void cyrix_timing(struct ata_softc *, int, int); -static void promise_timing(struct ata_softc *, int, int); -static void hpt_timing(struct ata_softc *, int, int); +static void cyrix_timing(struct ata_channel *, int, int); +static void promise_timing(struct ata_channel *, int, int); +static void hpt_timing(struct ata_channel *, int, int); /* misc defines */ #ifdef __alpha__ #undef vtophys #define vtophys(va) alpha_XXX_dmamap((vm_offset_t)va) #endif -#define ATAPI_DEVICE(scp, device) \ - ((device == ATA_MASTER && scp->devices & ATA_ATAPI_MASTER) || \ - (device == ATA_SLAVE && scp->devices & ATA_ATAPI_SLAVE)) - +#define ATAPI_DEVICE(ch, device) \ + ((device == ATA_MASTER && ch->devices & ATA_ATAPI_MASTER) || \ + (device == ATA_SLAVE && ch->devices & ATA_ATAPI_SLAVE)) void * -ata_dmaalloc(struct ata_softc *scp, int device) +ata_dmaalloc(struct ata_channel *ch, int device) { void *dmatab; if ((dmatab = malloc(PAGE_SIZE, M_DEVBUF, M_NOWAIT))) { if (((uintptr_t)dmatab >> PAGE_SHIFT) ^ (((uintptr_t)dmatab + PAGE_SIZE - 1) >> PAGE_SHIFT)) { - ata_printf(scp, device, "dmatab crosses page boundary, no DMA\n"); + ata_printf(ch, device, "dmatab crosses page boundary, no DMA\n"); free(dmatab, M_DEVBUF); dmatab = NULL; } @@ -76,41 +75,41 @@ ata_dmaalloc(struct ata_softc *scp, int device) } void -ata_dmainit(struct ata_softc *scp, int device, +ata_dmainit(struct ata_channel *ch, int device, int apiomode, int wdmamode, int udmamode) { - device_t parent = device_get_parent(scp->dev); - int devno = (scp->channel << 1) + ATA_DEV(device); + struct ata_device *atadev = &ch->device[ATA_DEV(device)]; + device_t parent = device_get_parent(ch->dev); + int devno = (ch->unit << 1) + ATA_DEV(device); int error; /* set our most pessimistic default mode */ - scp->mode[ATA_DEV(device)] = ATA_PIO; + atadev->mode = ATA_PIO; - if (!scp->r_bmio) + if (!ch->r_bmio) return; /* if simplex controller, only allow DMA on primary channel */ - if (scp->channel == 1) { - ATA_OUTB(scp->r_bmio, ATA_BMSTAT_PORT, - ATA_INB(scp->r_bmio, ATA_BMSTAT_PORT) & + if (ch->unit == 1) { + ATA_OUTB(ch->r_bmio, ATA_BMSTAT_PORT, + ATA_INB(ch->r_bmio, ATA_BMSTAT_PORT) & (ATA_BMSTAT_DMA_MASTER | ATA_BMSTAT_DMA_SLAVE)); - if (ATA_INB(scp->r_bmio, ATA_BMSTAT_PORT) & ATA_BMSTAT_DMA_SIMPLEX) { - ata_printf(scp, device, "simplex device, DMA on primary only\n"); + if (ATA_INB(ch->r_bmio, ATA_BMSTAT_PORT) & ATA_BMSTAT_DMA_SIMPLEX) { + ata_prtdev(atadev, "simplex device, DMA on primary only\n"); return; } } /* DMA engine address alignment is usually 1 word (2 bytes) */ - scp->alignment = 0x1; + ch->alignment = 0x1; #if 1 - if (udmamode > 2 && !ATA_PARAM(scp, device)->hwres_cblid) { - ata_printf(scp, device, - "DMA limited to UDMA33, non-ATA66 compliant cable\n"); + if (udmamode > 2 && !ch->device[ATA_DEV(device)].param->hwres_cblid) { + ata_prtdev(atadev,"DMA limited to UDMA33, non-ATA66 cable or device\n"); udmamode = 2; } #endif - switch (scp->chiptype) { + switch (ch->chiptype) { case 0x248a8086: /* Intel ICH3 mobile */ case 0x248b8086: /* Intel ICH3 */ @@ -122,10 +121,10 @@ ata_dmainit(struct ata_softc *scp, int device, word54 = pci_read_config(parent, 0x54, 2); if (word54 & (0x10 << devno)) { - error = ata_command(scp, device, ATA_C_SETFEATURES, 0, - ATA_UDMA5, ATA_C_F_SETXFER,ATA_WAIT_READY); - if (bootverbose) - ata_printf(scp, device, "%s setting UDMA5 on Intel chip\n", + error = ata_command(atadev, ATA_C_SETFEATURES, 0, + ATA_UDMA5, ATA_C_F_SETXFER,ATA_WAIT_READY); + if (bootverbose) + ata_prtdev(atadev, "%s setting UDMA5 on Intel chip\n", (error) ? "failed" : "success"); if (!error) { mask48 = (1 << devno) + (3 << (16 + (devno << 2))); @@ -133,8 +132,8 @@ ata_dmainit(struct ata_softc *scp, int device, pci_write_config(parent, 0x48, (pci_read_config(parent, 0x48, 4) & ~mask48) | new48, 4); - pci_write_config(parent, 0x54, word54 | (0x1000<<devno), 2); - scp->mode[ATA_DEV(device)] = ATA_UDMA5; + pci_write_config(parent, 0x54, word54 | (0x1000<<devno), 2); + atadev->mode = ATA_UDMA5; return; } } @@ -144,18 +143,18 @@ ata_dmainit(struct ata_softc *scp, int device, pci_read_config(parent, 0x54, 2) & ~(0x1000<<devno),2); /* FALLTHROUGH */ - case 0x24118086: /* Intel ICH */ - case 0x76018086: /* Intel ICH */ + case 0x24118086: /* Intel ICH */ + case 0x76018086: /* Intel ICH */ if (udmamode >= 4) { int32_t mask48, new48; int16_t word54; word54 = pci_read_config(parent, 0x54, 2); if (word54 & (0x10 << devno)) { - error = ata_command(scp, device, ATA_C_SETFEATURES, 0, - ATA_UDMA4, ATA_C_F_SETXFER,ATA_WAIT_READY); - if (bootverbose) - ata_printf(scp, device, "%s setting UDMA4 on Intel chip\n", + error = ata_command(atadev, ATA_C_SETFEATURES, 0, + ATA_UDMA4, ATA_C_F_SETXFER, ATA_WAIT_READY); + if (bootverbose) + ata_prtdev(atadev, "%s setting UDMA4 on Intel chip\n", (error) ? "failed" : "success"); if (!error) { mask48 = (1 << devno) + (3 << (16 + (devno << 2))); @@ -164,11 +163,11 @@ ata_dmainit(struct ata_softc *scp, int device, (pci_read_config(parent, 0x48, 4) & ~mask48) | new48, 4); pci_write_config(parent, 0x54, word54 | (1 << devno), 2); - scp->mode[ATA_DEV(device)] = ATA_UDMA4; + atadev->mode = ATA_UDMA4; return; } } - } + } /* make sure eventual ATA66 mode from the BIOS is disabled */ pci_write_config(parent, 0x54, pci_read_config(parent, 0x54, 2) & ~(1 << devno), 2); @@ -181,10 +180,10 @@ ata_dmainit(struct ata_softc *scp, int device, if (udmamode >= 2) { int32_t mask48, new48; - error = ata_command(scp, device, ATA_C_SETFEATURES, 0, + error = ata_command(atadev, ATA_C_SETFEATURES, 0, ATA_UDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); if (bootverbose) - ata_printf(scp, device, "%s setting UDMA2 on Intel chip\n", + ata_prtdev(atadev, "%s setting UDMA2 on Intel chip\n", (error) ? "failed" : "success"); if (!error) { mask48 = (1 << devno) + (3 << (16 + (devno << 2))); @@ -192,7 +191,7 @@ ata_dmainit(struct ata_softc *scp, int device, pci_write_config(parent, 0x48, (pci_read_config(parent, 0x48, 4) & ~mask48) | new48, 4); - scp->mode[ATA_DEV(device)] = ATA_UDMA2; + atadev->mode = ATA_UDMA2; return; } } @@ -206,7 +205,7 @@ ata_dmainit(struct ata_softc *scp, int device, int32_t mask40, new40, mask44, new44; /* if SITRE not set doit for both channels */ - if (!((pci_read_config(parent,0x40,4)>>(scp->channel<<8))&0x4000)) { + if (!((pci_read_config(parent,0x40,4)>>(ch->unit<<8))&0x4000)) { new40 = pci_read_config(parent, 0x40, 4); new44 = pci_read_config(parent, 0x44, 4); if (!(new40 & 0x00004000)) { @@ -221,10 +220,10 @@ ata_dmainit(struct ata_softc *scp, int device, pci_write_config(parent, 0x40, new40, 4); pci_write_config(parent, 0x44, new44, 4); } - error = ata_command(scp, device, ATA_C_SETFEATURES, 0, + error = ata_command(atadev, ATA_C_SETFEATURES, 0, ATA_WDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); if (bootverbose) - ata_printf(scp, device, "%s setting WDMA2 on Intel chip\n", + ata_prtdev(atadev, "%s setting WDMA2 on Intel chip\n", (error) ? "failed" : "success"); if (!error) { if (device == ATA_MASTER) { @@ -239,7 +238,7 @@ ata_dmainit(struct ata_softc *scp, int device, mask44 = 0x0000000f; new44 = 0x0000000b; } - if (scp->channel) { + if (ch->unit) { mask40 <<= 16; new40 <<= 16; mask44 <<= 4; @@ -247,11 +246,11 @@ ata_dmainit(struct ata_softc *scp, int device, } pci_write_config(parent, 0x40, (pci_read_config(parent, 0x40, 4) & ~mask40)| - new40, 4); + new40, 4); pci_write_config(parent, 0x44, (pci_read_config(parent, 0x44, 4) & ~mask44)| - new44, 4); - scp->mode[ATA_DEV(device)] = ATA_WDMA2; + new44, 4); + atadev->mode = ATA_WDMA2; return; } } @@ -263,20 +262,20 @@ ata_dmainit(struct ata_softc *scp, int device, int32_t word40; word40 = pci_read_config(parent, 0x40, 4); - word40 >>= scp->channel * 16; + word40 >>= ch->unit * 16; /* Check for timing config usable for DMA on controller */ if (!((word40 & 0x3300) == 0x2300 && ((word40 >> (device == ATA_MASTER ? 0 : 4)) & 1) == 1)) break; - error = ata_command(scp, device, ATA_C_SETFEATURES, 0, + error = ata_command(atadev, ATA_C_SETFEATURES, 0, ATA_WDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); if (bootverbose) - ata_printf(scp, device, "%s setting WDMA2 on Intel chip\n", + ata_prtdev(atadev, "%s setting WDMA2 on Intel chip\n", (error) ? "failed" : "success"); if (!error) { - scp->mode[ATA_DEV(device)] = ATA_WDMA2; + atadev->mode = ATA_WDMA2; return; } } @@ -285,16 +284,15 @@ ata_dmainit(struct ata_softc *scp, int device, case 0x522910b9: /* AcerLabs Aladdin IV/V */ /* the older Aladdin doesn't support ATAPI DMA on both master & slave */ if (pci_get_revid(parent) < 0xc2 && - scp->devices & ATA_ATAPI_MASTER && scp->devices & ATA_ATAPI_SLAVE) { - ata_printf(scp, device, - "Aladdin: two atapi devices on this channel, no DMA\n"); + ch->devices & ATA_ATAPI_MASTER && ch->devices & ATA_ATAPI_SLAVE) { + ata_prtdev(atadev, "two atapi devices on this channel, no DMA\n"); break; } if (udmamode >= 5 && pci_get_revid(parent) >= 0xc4) { - error = ata_command(scp, device, ATA_C_SETFEATURES, 0, + error = ata_command(atadev, ATA_C_SETFEATURES, 0, ATA_UDMA5, ATA_C_F_SETXFER, ATA_WAIT_READY); if (bootverbose) - ata_printf(scp, device, "%s setting UDMA5 on Acer chip\n", + ata_prtdev(atadev, "%s setting UDMA5 on Acer chip\n", (error) ? "failed" : "success"); if (!error) { int32_t word54 = pci_read_config(parent, 0x54, 4); @@ -306,15 +304,15 @@ ata_dmainit(struct ata_softc *scp, int device, pci_write_config(parent, 0x54, word54, 4); pci_write_config(parent, 0x53, pci_read_config(parent, 0x53, 1) | 0x03, 1); - scp->mode[ATA_DEV(device)] = ATA_UDMA5; + atadev->mode = ATA_UDMA5; return; } } if (udmamode >= 4 && pci_get_revid(parent) >= 0xc2) { - error = ata_command(scp, device, ATA_C_SETFEATURES, 0, + error = ata_command(atadev, ATA_C_SETFEATURES, 0, ATA_UDMA4, ATA_C_F_SETXFER, ATA_WAIT_READY); if (bootverbose) - ata_printf(scp, device, "%s setting UDMA4 on Acer chip\n", + ata_prtdev(atadev, "%s setting UDMA4 on Acer chip\n", (error) ? "failed" : "success"); if (!error) { int32_t word54 = pci_read_config(parent, 0x54, 4); @@ -326,15 +324,15 @@ ata_dmainit(struct ata_softc *scp, int device, pci_write_config(parent, 0x54, word54, 4); pci_write_config(parent, 0x53, pci_read_config(parent, 0x53, 1) | 0x03, 1); - scp->mode[ATA_DEV(device)] = ATA_UDMA4; + atadev->mode = ATA_UDMA4; return; } } if (udmamode >= 2 && pci_get_revid(parent) >= 0x20) { - error = ata_command(scp, device, ATA_C_SETFEATURES, 0, + error = ata_command(atadev, ATA_C_SETFEATURES, 0, ATA_UDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); if (bootverbose) - ata_printf(scp, device, "%s setting UDMA2 on Acer chip\n", + ata_prtdev(atadev, "%s setting UDMA2 on Acer chip\n", (error) ? "failed" : "success"); if (!error) { int32_t word54 = pci_read_config(parent, 0x54, 4); @@ -344,8 +342,8 @@ ata_dmainit(struct ata_softc *scp, int device, pci_write_config(parent, 0x54, word54, 4); pci_write_config(parent, 0x53, pci_read_config(parent, 0x53, 1) | 0x03, 1); - scp->flags |= ATA_ATAPI_DMA_RO; - scp->mode[ATA_DEV(device)] = ATA_UDMA2; + ch->flags |= ATA_ATAPI_DMA_RO; + atadev->mode = ATA_UDMA2; return; } } @@ -355,16 +353,16 @@ ata_dmainit(struct ata_softc *scp, int device, ~(0x0008 << (devno << 2)), 2); if (wdmamode >= 2 && apiomode >= 4) { - error = ata_command(scp, device, ATA_C_SETFEATURES, 0, + error = ata_command(atadev, ATA_C_SETFEATURES, 0, ATA_WDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); if (bootverbose) - ata_printf(scp, device, "%s setting WDMA2 on Acer chip\n", + ata_prtdev(atadev, "%s setting WDMA2 on Acer chip\n", (error) ? "failed" : "success"); if (!error) { pci_write_config(parent, 0x53, pci_read_config(parent, 0x53, 1) | 0x03, 1); - scp->flags |= ATA_ATAPI_DMA_RO; - scp->mode[ATA_DEV(device)] = ATA_WDMA2; + ch->flags |= ATA_ATAPI_DMA_RO; + atadev->mode = ATA_WDMA2; return; } } @@ -375,14 +373,14 @@ ata_dmainit(struct ata_softc *scp, int device, case 0x74111022: /* AMD 766 */ if (udmamode >= 5) { - error = ata_command(scp, device, ATA_C_SETFEATURES, 0, + error = ata_command(atadev, ATA_C_SETFEATURES, 0, ATA_UDMA5, ATA_C_F_SETXFER, ATA_WAIT_READY); if (bootverbose) - ata_printf(scp, device, "%s setting UDMA5 on AMD chip\n", + ata_prtdev(atadev, "%s setting UDMA5 on AMD chip\n", (error) ? "failed" : "success"); if (!error) { - pci_write_config(parent, 0x53 - devno, 0xc6, 1); - scp->mode[ATA_DEV(device)] = ATA_UDMA5; + pci_write_config(parent, 0x53 - devno, 0xc6, 1); + atadev->mode = ATA_UDMA5; return; } } @@ -390,14 +388,14 @@ ata_dmainit(struct ata_softc *scp, int device, case 0x74091022: /* AMD 756 */ if (udmamode >= 4) { - error = ata_command(scp, device, ATA_C_SETFEATURES, 0, + error = ata_command(atadev, ATA_C_SETFEATURES, 0, ATA_UDMA4, ATA_C_F_SETXFER, ATA_WAIT_READY); if (bootverbose) - ata_printf(scp, device, "%s setting UDMA4 on AMD chip\n", + ata_prtdev(atadev, "%s setting UDMA4 on AMD chip\n", (error) ? "failed" : "success"); if (!error) { - pci_write_config(parent, 0x53 - devno, 0xc5, 1); - scp->mode[ATA_DEV(device)] = ATA_UDMA4; + pci_write_config(parent, 0x53 - devno, 0xc5, 1); + atadev->mode = ATA_UDMA4; return; } } @@ -442,66 +440,66 @@ via_82c586: udmamode = 0; if (udmamode >= 6) { - error = ata_command(scp, device, ATA_C_SETFEATURES, 0, + error = ata_command(atadev, ATA_C_SETFEATURES, 0, ATA_UDMA6, ATA_C_F_SETXFER, ATA_WAIT_READY); if (bootverbose) - ata_printf(scp, device, "%s setting UDMA6 on VIA chip\n", + ata_prtdev(atadev, "%s setting UDMA6 on VIA chip\n", (error) ? "failed" : "success"); if (!error) { pci_write_config(parent, 0x53 - devno, reg_val[6], 1); - scp->mode[ATA_DEV(device)] = ATA_UDMA6; + atadev->mode = ATA_UDMA6; return; } } if (udmamode >= 5) { - error = ata_command(scp, device, ATA_C_SETFEATURES, 0, + error = ata_command(atadev, ATA_C_SETFEATURES, 0, ATA_UDMA5, ATA_C_F_SETXFER, ATA_WAIT_READY); if (bootverbose) - ata_printf(scp, device, "%s setting UDMA5 on VIA chip\n", + ata_prtdev(atadev, "%s setting UDMA5 on VIA chip\n", (error) ? "failed" : "success"); if (!error) { pci_write_config(parent, 0x53 - devno, reg_val[5], 1); - scp->mode[ATA_DEV(device)] = ATA_UDMA5; + atadev->mode = ATA_UDMA5; return; } } if (udmamode >= 4) { - error = ata_command(scp, device, ATA_C_SETFEATURES, 0, + error = ata_command(atadev, ATA_C_SETFEATURES, 0, ATA_UDMA4, ATA_C_F_SETXFER, ATA_WAIT_READY); if (bootverbose) - ata_printf(scp, device, "%s setting UDMA4 on VIA chip\n", + ata_prtdev(atadev, "%s setting UDMA4 on VIA chip\n", (error) ? "failed" : "success"); if (!error) { pci_write_config(parent, 0x53 - devno, reg_val[4], 1); - scp->mode[ATA_DEV(device)] = ATA_UDMA4; + atadev->mode = ATA_UDMA4; return; } } if (udmamode >= 2) { - error = ata_command(scp, device, ATA_C_SETFEATURES, 0, + error = ata_command(atadev, ATA_C_SETFEATURES, 0, ATA_UDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); if (bootverbose) - ata_printf(scp, device, "%s setting UDMA2 on VIA chip\n", + ata_prtdev(atadev, "%s setting UDMA2 on VIA chip\n", (error) ? "failed" : "success"); if (!error) { pci_write_config(parent, 0x53 - devno, reg_val[2], 1); - scp->mode[ATA_DEV(device)] = ATA_UDMA2; + atadev->mode = ATA_UDMA2; return; } } } if (wdmamode >= 2 && apiomode >= 4) { - error = ata_command(scp, device, ATA_C_SETFEATURES, 0, + error = ata_command(atadev, ATA_C_SETFEATURES, 0, ATA_WDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); if (bootverbose) - ata_printf(scp, device, "%s setting WDMA2 on %s chip\n", + ata_prtdev(atadev, "%s setting WDMA2 on %s chip\n", (error) ? "failed" : "success", - (scp->chiptype == 0x74091022) ? "AMD" : "VIA"); + (ch->chiptype == 0x74091022) ? "AMD" : "VIA"); if (!error) { - pci_write_config(parent, 0x53 - devno, 0x0b, 1); - pci_write_config(parent, 0x4b - devno, 0x31, 1); - scp->mode[ATA_DEV(device)] = ATA_WDMA2; + pci_write_config(parent, 0x53 - devno, 0x0b, 1); + pci_write_config(parent, 0x4b - devno, 0x31, 1); + atadev->mode = ATA_WDMA2; return; } } @@ -509,54 +507,54 @@ via_82c586: break; case 0x55131039: /* SiS 5591 */ - if (ata_find_dev(parent, 0x06301039, 0x30) || /* SiS 630 */ - ata_find_dev(parent, 0x06331039, 0x00) || /* SiS 633 */ - ata_find_dev(parent, 0x06351039, 0x00) || /* SiS 635 */ - ata_find_dev(parent, 0x06401039, 0x00) || /* SiS 640 */ - ata_find_dev(parent, 0x06451039, 0x00) || /* SiS 645 */ - ata_find_dev(parent, 0x06501039, 0x00) || /* SiS 650 */ - ata_find_dev(parent, 0x07301039, 0x00) || /* SiS 730 */ - ata_find_dev(parent, 0x07331039, 0x00) || /* SiS 733 */ - ata_find_dev(parent, 0x07351039, 0x00) || /* SiS 735 */ - ata_find_dev(parent, 0x07401039, 0x00) || /* SiS 740 */ - ata_find_dev(parent, 0x07451039, 0x00) || /* SiS 745 */ - ata_find_dev(parent, 0x07501039, 0x00)) { /* SiS 750 */ + if (ata_find_dev(parent, 0x06301039, 0x30) || /* SiS 630 */ + ata_find_dev(parent, 0x06331039, 0x00) || /* SiS 633 */ + ata_find_dev(parent, 0x06351039, 0x00) || /* SiS 635 */ + ata_find_dev(parent, 0x06401039, 0x00) || /* SiS 640 */ + ata_find_dev(parent, 0x06451039, 0x00) || /* SiS 645 */ + ata_find_dev(parent, 0x06501039, 0x00) || /* SiS 650 */ + ata_find_dev(parent, 0x07301039, 0x00) || /* SiS 730 */ + ata_find_dev(parent, 0x07331039, 0x00) || /* SiS 733 */ + ata_find_dev(parent, 0x07351039, 0x00) || /* SiS 735 */ + ata_find_dev(parent, 0x07401039, 0x00) || /* SiS 740 */ + ata_find_dev(parent, 0x07451039, 0x00) || /* SiS 745 */ + ata_find_dev(parent, 0x07501039, 0x00)) { /* SiS 750 */ int8_t reg = 0x40 + (devno << 1); int16_t val = pci_read_config(parent, reg, 2) & 0x0fff; if (udmamode >= 5) { - error = ata_command(scp, device, ATA_C_SETFEATURES, 0, + error = ata_command(atadev, ATA_C_SETFEATURES, 0, ATA_UDMA5, ATA_C_F_SETXFER, ATA_WAIT_READY); if (bootverbose) - ata_printf(scp, device, "%s setting UDMA5 on SiS chip\n", + ata_prtdev(atadev, "%s setting UDMA5 on SiS chip\n", (error) ? "failed" : "success"); if (!error) { pci_write_config(parent, reg, val | 0x8000, 2); - scp->mode[ATA_DEV(device)] = ATA_UDMA5; + atadev->mode = ATA_UDMA5; return; } } if (udmamode >= 4) { - error = ata_command(scp, device, ATA_C_SETFEATURES, 0, + error = ata_command(atadev, ATA_C_SETFEATURES, 0, ATA_UDMA4, ATA_C_F_SETXFER, ATA_WAIT_READY); if (bootverbose) - ata_printf(scp, device, "%s setting UDMA4 on SiS chip\n", + ata_prtdev(atadev, "%s setting UDMA4 on SiS chip\n", (error) ? "failed" : "success"); if (!error) { pci_write_config(parent, reg, val | 0x9000, 2); - scp->mode[ATA_DEV(device)] = ATA_UDMA4; + atadev->mode = ATA_UDMA4; return; } } if (udmamode >= 2) { - error = ata_command(scp, device, ATA_C_SETFEATURES, 0, + error = ata_command(atadev, ATA_C_SETFEATURES, 0, ATA_UDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); if (bootverbose) - ata_printf(scp, device, "%s setting UDMA2 on SiS chip\n", + ata_prtdev(atadev, "%s setting UDMA2 on SiS chip\n", (error) ? "failed" : "success"); if (!error) { pci_write_config(parent, reg, val | 0xb000, 2); - scp->mode[ATA_DEV(device)] = ATA_UDMA2; + atadev->mode = ATA_UDMA2; return; } } @@ -568,50 +566,50 @@ via_82c586: int16_t val = pci_read_config(parent, reg, 2) & 0x0fff; if (udmamode >= 4) { - error = ata_command(scp, device, ATA_C_SETFEATURES, 0, + error = ata_command(atadev, ATA_C_SETFEATURES, 0, ATA_UDMA4, ATA_C_F_SETXFER, ATA_WAIT_READY); if (bootverbose) - ata_printf(scp, device, "%s setting UDMA4 on SiS chip\n", + ata_prtdev(atadev, "%s setting UDMA4 on SiS chip\n", (error) ? "failed" : "success"); if (!error) { pci_write_config(parent, reg, val | 0x9000, 2); - scp->mode[ATA_DEV(device)] = ATA_UDMA4; + atadev->mode = ATA_UDMA4; return; } } if (udmamode >= 2) { - error = ata_command(scp, device, ATA_C_SETFEATURES, 0, + error = ata_command(atadev, ATA_C_SETFEATURES, 0, ATA_UDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); if (bootverbose) - ata_printf(scp, device, "%s setting UDMA2 on SiS chip\n", + ata_prtdev(atadev, "%s setting UDMA2 on SiS chip\n", (error) ? "failed" : "success"); if (!error) { pci_write_config(parent, reg, val | 0xa000, 2); - scp->mode[ATA_DEV(device)] = ATA_UDMA2; + atadev->mode = ATA_UDMA2; return; } } } else if (udmamode >= 2 && pci_get_revid(parent) > 0xc1) { - error = ata_command(scp, device, ATA_C_SETFEATURES, 0, + error = ata_command(atadev, ATA_C_SETFEATURES, 0, ATA_UDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); if (bootverbose) - ata_printf(scp, device, "%s setting UDMA2 on SiS chip\n", + ata_prtdev(atadev, "%s setting UDMA2 on SiS chip\n", (error) ? "failed" : "success"); if (!error) { pci_write_config(parent, 0x40 + (devno << 1), 0xa301, 2); - scp->mode[ATA_DEV(device)] = ATA_UDMA2; + atadev->mode = ATA_UDMA2; return; } } if (wdmamode >=2 && apiomode >= 4) { - error = ata_command(scp, device, ATA_C_SETFEATURES, 0, + error = ata_command(atadev, ATA_C_SETFEATURES, 0, ATA_WDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); if (bootverbose) - ata_printf(scp, device, "%s setting WDMA2 on SiS chip\n", + ata_prtdev(atadev, "%s setting WDMA2 on SiS chip\n", (error) ? "failed" : "success"); if (!error) { pci_write_config(parent, 0x40 + (devno << 1), 0x0301, 2); - scp->mode[ATA_DEV(device)] = ATA_WDMA2; + atadev->mode = ATA_WDMA2; return; } } @@ -622,17 +620,17 @@ via_82c586: if (udmamode >= 5) { u_int8_t umode; - error = ata_command(scp, device, ATA_C_SETFEATURES, 0, + error = ata_command(atadev, ATA_C_SETFEATURES, 0, ATA_UDMA5, ATA_C_F_SETXFER, ATA_WAIT_READY); if (bootverbose) - ata_printf(scp, device, "%s setting UDMA5 on CMD chip\n", + ata_prtdev(atadev, "%s setting UDMA5 on CMD chip\n", (error) ? "failed" : "success"); if (!error) { - umode = pci_read_config(parent, scp->channel ? 0x7b : 0x73, 1); + umode = pci_read_config(parent, ch->unit ? 0x7b : 0x73, 1); umode &= ~(device == ATA_MASTER ? 0x35 : 0xca); umode |= (device == ATA_MASTER ? 0x05 : 0x0a); - pci_write_config(parent, scp->channel ? 0x7b : 0x73, umode, 1); - scp->mode[ATA_DEV(device)] = ATA_UDMA5; + pci_write_config(parent, ch->unit ? 0x7b : 0x73, umode, 1); + atadev->mode = ATA_UDMA5; return; } } @@ -642,55 +640,55 @@ via_82c586: if (udmamode >= 4) { u_int8_t umode; - error = ata_command(scp, device, ATA_C_SETFEATURES, 0, + error = ata_command(atadev, ATA_C_SETFEATURES, 0, ATA_UDMA4, ATA_C_F_SETXFER, ATA_WAIT_READY); if (bootverbose) - ata_printf(scp, device, "%s setting UDMA4 on CMD chip\n", + ata_prtdev(atadev, "%s setting UDMA4 on CMD chip\n", (error) ? "failed" : "success"); if (!error) { - umode = pci_read_config(parent, scp->channel ? 0x7b : 0x73, 1); + umode = pci_read_config(parent, ch->unit ? 0x7b : 0x73, 1); umode &= ~(device == ATA_MASTER ? 0x35 : 0xca); umode |= (device == ATA_MASTER ? 0x15 : 0x4a); - pci_write_config(parent, scp->channel ? 0x7b : 0x73, umode, 1); - scp->mode[ATA_DEV(device)] = ATA_UDMA4; + pci_write_config(parent, ch->unit ? 0x7b : 0x73, umode, 1); + atadev->mode = ATA_UDMA4; return; } } if (udmamode >= 2) { u_int8_t umode; - error = ata_command(scp, device, ATA_C_SETFEATURES, 0, + error = ata_command(atadev, ATA_C_SETFEATURES, 0, ATA_UDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); if (bootverbose) - ata_printf(scp, device, "%s setting UDMA2 on CMD chip\n", + ata_prtdev(atadev, "%s setting UDMA2 on CMD chip\n", (error) ? "failed" : "success"); if (!error) { - umode = pci_read_config(parent, scp->channel ? 0x7b : 0x73, 1); + umode = pci_read_config(parent, ch->unit ? 0x7b : 0x73, 1); umode &= ~(device == ATA_MASTER ? 0x35 : 0xca); umode |= (device == ATA_MASTER ? 0x11 : 0x42); - pci_write_config(parent, scp->channel ? 0x7b : 0x73, umode, 1); - scp->mode[ATA_DEV(device)] = ATA_UDMA2; + pci_write_config(parent, ch->unit ? 0x7b : 0x73, umode, 1); + atadev->mode = ATA_UDMA2; return; } } /* make sure eventual UDMA mode from the BIOS is disabled */ - pci_write_config(parent, scp->channel ? 0x7b : 0x73, - pci_read_config(parent, scp->channel ? 0x7b : 0x73, 1)& + pci_write_config(parent, ch->unit ? 0x7b : 0x73, + pci_read_config(parent, ch->unit ? 0x7b : 0x73, 1)& ~(device == ATA_MASTER ? 0x35 : 0xca), 1); /* FALLTHROUGH */ case 0x06461095: /* CMD 646 ATA controller */ if (wdmamode >= 2 && apiomode >= 4) { - error = ata_command(scp, device, ATA_C_SETFEATURES, 0, + error = ata_command(atadev, ATA_C_SETFEATURES, 0, ATA_WDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); if (bootverbose) - ata_printf(scp, device, "%s setting WDMA2 on CMD chip\n", + ata_prtdev(atadev, "%s setting WDMA2 on CMD chip\n", error ? "failed" : "success"); if (!error) { int32_t offset = (devno < 3) ? (devno << 1) : 7; pci_write_config(parent, 0x54 + offset, 0x3f, 1); - scp->mode[ATA_DEV(device)] = ATA_WDMA2; + atadev->mode = ATA_WDMA2; return; } } @@ -699,14 +697,14 @@ via_82c586: case 0xc6931080: /* Cypress 82c693 ATA controller */ if (wdmamode >= 2 && apiomode >= 4) { - error = ata_command(scp, device, ATA_C_SETFEATURES, 0, + error = ata_command(atadev, ATA_C_SETFEATURES, 0, ATA_WDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); if (bootverbose) - ata_printf(scp, device, "%s setting WDMA2 on Cypress chip\n", + ata_prtdev(atadev, "%s setting WDMA2 on Cypress chip\n", error ? "failed" : "success"); if (!error) { - pci_write_config(scp->dev, scp->channel ? 0x4e:0x4c, 0x2020, 2); - scp->mode[ATA_DEV(device)] = ATA_WDMA2; + pci_write_config(ch->dev, ch->unit ? 0x4e:0x4c, 0x2020, 2); + atadev->mode = ATA_WDMA2; return; } } @@ -714,49 +712,48 @@ via_82c586: break; case 0x01021078: /* Cyrix 5530 ATA33 controller */ - scp->alignment = 0xf; /* DMA engine requires 16 byte alignment */ + ch->alignment = 0xf; /* DMA engine requires 16 byte alignment */ if (udmamode >= 2) { - error = ata_command(scp, device, ATA_C_SETFEATURES, 0, + error = ata_command(atadev, ATA_C_SETFEATURES, 0, ATA_UDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); if (bootverbose) - ata_printf(scp, device, "%s setting UDMA2 on Cyrix chip\n", + ata_prtdev(atadev, "%s setting UDMA2 on Cyrix chip\n", (error) ? "failed" : "success"); if (!error) { - cyrix_timing(scp, devno, ATA_UDMA2); - scp->mode[ATA_DEV(device)] = ATA_UDMA2; + cyrix_timing(ch, devno, ATA_UDMA2); + atadev->mode = ATA_UDMA2; return; } } if (wdmamode >= 2 && apiomode >= 4) { - error = ata_command(scp, device, ATA_C_SETFEATURES, 0, + error = ata_command(atadev, ATA_C_SETFEATURES, 0, ATA_WDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); if (bootverbose) - ata_printf(scp, device, "%s setting WDMA2 on Cyrix chip\n", + ata_prtdev(atadev, "%s setting WDMA2 on Cyrix chip\n", (error) ? "failed" : "success"); if (!error) { - cyrix_timing(scp, devno, ATA_WDMA2); - scp->mode[ATA_DEV(device)] = ATA_WDMA2; + cyrix_timing(ch, devno, ATA_WDMA2); + atadev->mode = ATA_WDMA2; return; } } - error = ata_command(scp, device, ATA_C_SETFEATURES, 0, + error = ata_command(atadev, ATA_C_SETFEATURES, 0, ATA_PIO0 + apiomode, ATA_C_F_SETXFER, ATA_WAIT_READY); if (bootverbose) - ata_printf(scp, device, "%s setting %s on Cyrix chip\n", + ata_prtdev(atadev, "%s setting %s on Cyrix chip\n", (error) ? "failed" : "success", ata_mode2str(ATA_PIO0 + apiomode)); - cyrix_timing(scp, devno, ATA_PIO0 + apiomode); - scp->mode[ATA_DEV(device)] = ATA_PIO0 + apiomode; + cyrix_timing(ch, devno, ATA_PIO0 + apiomode); + atadev->mode = ATA_PIO0 + apiomode; return; case 0x02111166: /* ServerWorks ROSB4 ATA33 controller */ if (udmamode >= 2) { - error = ata_command(scp, device, ATA_C_SETFEATURES, 0, + error = ata_command(atadev, ATA_C_SETFEATURES, 0, ATA_UDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); if (bootverbose) - ata_printf(scp, device, - "%s setting UDMA2 on ServerWorks chip\n", + ata_prtdev(atadev, "%s setting UDMA2 on ServerWorks chip\n", (error) ? "failed" : "success"); if (!error) { u_int16_t reg56; @@ -768,19 +765,18 @@ via_82c586: reg56 &= ~(0xf << (devno * 4)); reg56 |= (0x2 << (devno * 4)); pci_write_config(parent, 0x56, reg56, 2); - scp->mode[ATA_DEV(device)] = ATA_UDMA2; + atadev->mode = ATA_UDMA2; return; } } if (wdmamode >= 2 && apiomode >= 4) { - error = ata_command(scp, device, ATA_C_SETFEATURES, 0, + error = ata_command(atadev, ATA_C_SETFEATURES, 0, ATA_WDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); if (bootverbose) - ata_printf(scp, device, - "%s setting WDMA2 on ServerWorks chip\n", + ata_prtdev(atadev, "%s setting WDMA2 on ServerWorks chip\n", (error) ? "failed" : "success"); if (!error) { - int offset = (scp->channel * 2) + (device == ATA_MASTER); + int offset = (ch->unit * 2) + (device == ATA_MASTER); int word44 = pci_read_config(parent, 0x44, 4); pci_write_config(parent, 0x54, @@ -789,7 +785,7 @@ via_82c586: word44 &= ~(0xff << (offset << 8)); word44 |= (0x20 << (offset << 8)); pci_write_config(parent, 0x44, 0x20, 4); - scp->mode[ATA_DEV(device)] = ATA_WDMA2; + atadev->mode = ATA_WDMA2; return; } } @@ -797,15 +793,15 @@ via_82c586: break; case 0x4d69105a: /* Promise TX2 ATA133 controllers */ - ATA_OUTB(scp->r_bmio, ATA_BMDEVSPEC_0, 0x0b); - if (udmamode >= 6 && !(ATA_INB(scp->r_bmio, ATA_BMDEVSPEC_1) & 0x04)) { - error = ata_command(scp, device, ATA_C_SETFEATURES, 0, + ATA_OUTB(ch->r_bmio, ATA_BMDEVSPEC_0, 0x0b); + if (udmamode >= 6 && !(ATA_INB(ch->r_bmio, ATA_BMDEVSPEC_1) & 0x04)) { + error = ata_command(atadev, ATA_C_SETFEATURES, 0, ATA_UDMA6, ATA_C_F_SETXFER, ATA_WAIT_READY); if (bootverbose) - ata_printf(scp, device, "%s setting UDMA6 on Promise chip\n", + ata_prtdev(atadev, "%s setting UDMA6 on Promise chip\n", (error) ? "failed" : "success"); if (!error) { - scp->mode[ATA_DEV(device)] = ATA_UDMA6; + atadev->mode = ATA_UDMA6; return; } } @@ -813,49 +809,49 @@ via_82c586: case 0x4d68105a: /* Promise TX2 ATA100 controllers */ case 0x6268105a: /* Promise TX2 ATA100 controllers */ - ATA_OUTB(scp->r_bmio, ATA_BMDEVSPEC_0, 0x0b); - if (udmamode >= 5 && !(ATA_INB(scp->r_bmio, ATA_BMDEVSPEC_1) & 0x04)) { - error = ata_command(scp, device, ATA_C_SETFEATURES, 0, + ATA_OUTB(ch->r_bmio, ATA_BMDEVSPEC_0, 0x0b); + if (udmamode >= 5 && !(ATA_INB(ch->r_bmio, ATA_BMDEVSPEC_1) & 0x04)) { + error = ata_command(atadev, ATA_C_SETFEATURES, 0, ATA_UDMA5, ATA_C_F_SETXFER, ATA_WAIT_READY); if (bootverbose) - ata_printf(scp, device, "%s setting UDMA5 on Promise chip\n", + ata_prtdev(atadev, "%s setting UDMA5 on Promise chip\n", (error) ? "failed" : "success"); if (!error) { - scp->mode[ATA_DEV(device)] = ATA_UDMA5; + atadev->mode = ATA_UDMA5; return; } } - ATA_OUTB(scp->r_bmio, ATA_BMDEVSPEC_0, 0x0b); - if (udmamode >= 4 && !(ATA_INB(scp->r_bmio, ATA_BMDEVSPEC_1) & 0x04)) { - error = ata_command(scp, device, ATA_C_SETFEATURES, 0, + ATA_OUTB(ch->r_bmio, ATA_BMDEVSPEC_0, 0x0b); + if (udmamode >= 4 && !(ATA_INB(ch->r_bmio, ATA_BMDEVSPEC_1) & 0x04)) { + error = ata_command(atadev, ATA_C_SETFEATURES, 0, ATA_UDMA4, ATA_C_F_SETXFER, ATA_WAIT_READY); if (bootverbose) - ata_printf(scp, device, "%s setting UDMA4 on Promise chip\n", + ata_prtdev(atadev, "%s setting UDMA4 on Promise chip\n", (error) ? "failed" : "success"); if (!error) { - scp->mode[ATA_DEV(device)] = ATA_UDMA4; + atadev->mode = ATA_UDMA4; return; } } if (udmamode >= 2) { - error = ata_command(scp, device, ATA_C_SETFEATURES, 0, + error = ata_command(atadev, ATA_C_SETFEATURES, 0, ATA_UDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); if (bootverbose) - ata_printf(scp, device, "%s setting %s on Promise chip\n", - (error) ? "failed" : "success", "UDMA2"); + ata_prtdev(atadev, "%s setting UDMA on Promise chip\n", + (error) ? "failed" : "success"); if (!error) { - scp->mode[ATA_DEV(device)] = ATA_UDMA2; + atadev->mode = ATA_UDMA2; return; } } if (wdmamode >= 2 && apiomode >= 4) { - error = ata_command(scp, device, ATA_C_SETFEATURES, 0, + error = ata_command(atadev, ATA_C_SETFEATURES, 0, ATA_WDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); if (bootverbose) - ata_printf(scp, device, "%s setting %s on Promise chip\n", - (error) ? "failed" : "success", "WDMA2"); + ata_prtdev(atadev, "%s setting WDMA2 on Promise chip\n", + (error) ? "failed" : "success"); if (!error) { - scp->mode[ATA_DEV(device)] = ATA_WDMA2; + atadev->mode = ATA_WDMA2; return; } } @@ -863,207 +859,207 @@ via_82c586: case 0x4d30105a: /* Promise Ultra/FastTrak 100 controllers */ case 0x0d30105a: /* Promise OEM ATA100 controllers */ - if (!ATAPI_DEVICE(scp, device) && udmamode >= 5 && - !(pci_read_config(parent, 0x50, 2)&(scp->channel ? 1<<11 : 1<<10))){ - error = ata_command(scp, device, ATA_C_SETFEATURES, 0, + if (!ATAPI_DEVICE(ch, device) && udmamode >= 5 && + !(pci_read_config(parent, 0x50, 2)&(ch->unit ? 1<<11 : 1<<10))){ + error = ata_command(atadev, ATA_C_SETFEATURES, 0, ATA_UDMA5, ATA_C_F_SETXFER, ATA_WAIT_READY); if (bootverbose) - ata_printf(scp, device, "%s setting UDMA5 on Promise chip\n", + ata_prtdev(atadev, "%s setting UDMA5 on Promise chip\n", (error) ? "failed" : "success"); if (!error) { - promise_timing(scp, devno, ATA_UDMA5); - scp->mode[ATA_DEV(device)] = ATA_UDMA5; + promise_timing(ch, devno, ATA_UDMA5); + atadev->mode = ATA_UDMA5; return; } } /* FALLTHROUGH */ case 0x4d38105a: /* Promise Ultra/FastTrak 66 controllers */ - if (!ATAPI_DEVICE(scp, device) && udmamode >= 4 && - !(pci_read_config(parent, 0x50, 2)&(scp->channel ? 1<<11 : 1<<10))){ - error = ata_command(scp, device, ATA_C_SETFEATURES, 0, + if (!ATAPI_DEVICE(ch, device) && udmamode >= 4 && + !(pci_read_config(parent, 0x50, 2)&(ch->unit ? 1<<11 : 1<<10))){ + error = ata_command(atadev, ATA_C_SETFEATURES, 0, ATA_UDMA4, ATA_C_F_SETXFER, ATA_WAIT_READY); if (bootverbose) - ata_printf(scp, device, "%s setting UDMA4 on Promise chip\n", + ata_prtdev(atadev, "%s setting UDMA4 on Promise chip\n", (error) ? "failed" : "success"); if (!error) { - promise_timing(scp, devno, ATA_UDMA4); - scp->mode[ATA_DEV(device)] = ATA_UDMA4; + promise_timing(ch, devno, ATA_UDMA4); + atadev->mode = ATA_UDMA4; return; } } /* FALLTHROUGH */ case 0x4d33105a: /* Promise Ultra/FastTrak 33 controllers */ - if (!ATAPI_DEVICE(scp, device) && udmamode >= 2) { - error = ata_command(scp, device, ATA_C_SETFEATURES, 0, + if (!ATAPI_DEVICE(ch, device) && udmamode >= 2) { + error = ata_command(atadev, ATA_C_SETFEATURES, 0, ATA_UDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); if (bootverbose) - ata_printf(scp, device, "%s setting UDMA2 on Promise chip\n", + ata_prtdev(atadev, "%s setting UDMA2 on Promise chip\n", (error) ? "failed" : "success"); if (!error) { - promise_timing(scp, devno, ATA_UDMA2); - scp->mode[ATA_DEV(device)] = ATA_UDMA2; + promise_timing(ch, devno, ATA_UDMA2); + atadev->mode = ATA_UDMA2; return; } } - if (!ATAPI_DEVICE(scp, device) && wdmamode >= 2 && apiomode >= 4) { - error = ata_command(scp, device, ATA_C_SETFEATURES, 0, + if (!ATAPI_DEVICE(ch, device) && wdmamode >= 2 && apiomode >= 4) { + error = ata_command(atadev, ATA_C_SETFEATURES, 0, ATA_WDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); if (bootverbose) - ata_printf(scp, device, "%s setting WDMA2 on Promise chip\n", + ata_prtdev(atadev, "%s setting WDMA2 on Promise chip\n", (error) ? "failed" : "success"); if (!error) { - promise_timing(scp, devno, ATA_WDMA2); - scp->mode[ATA_DEV(device)] = ATA_WDMA2; + promise_timing(ch, devno, ATA_WDMA2); + atadev->mode = ATA_WDMA2; return; } } - error = ata_command(scp, device, ATA_C_SETFEATURES, 0, + error = ata_command(atadev, ATA_C_SETFEATURES, 0, ATA_PIO0 + apiomode, ATA_C_F_SETXFER, ATA_WAIT_READY); if (bootverbose) - ata_printf(scp, device, "%s setting PIO%d on Promise chip\n", + ata_prtdev(atadev, "%s setting PIO%d on Promise chip\n", (error) ? "failed" : "success", (apiomode >= 0) ? apiomode : 0); - promise_timing(scp, devno, ATA_PIO0 + apiomode); - scp->mode[ATA_DEV(device)] = ATA_PIO0 + apiomode; + promise_timing(ch, devno, ATA_PIO0 + apiomode); + atadev->mode = ATA_PIO0 + apiomode; return; case 0x00041103: /* HighPoint HPT366/368/370/372 controllers */ - if (!ATAPI_DEVICE(scp, device) && + if (!ATAPI_DEVICE(ch, device) && udmamode >= 6 && pci_get_revid(parent) >= 0x05 && - !(pci_read_config(parent, 0x5a, 1) & (scp->channel ? 0x01:0x02))) { - error = ata_command(scp, device, ATA_C_SETFEATURES, 0, + !(pci_read_config(parent, 0x5a, 1) & (ch->unit ? 0x01:0x02))) { + error = ata_command(atadev, ATA_C_SETFEATURES, 0, ATA_UDMA6, ATA_C_F_SETXFER, ATA_WAIT_READY); if (bootverbose) - ata_printf(scp, device, "%s setting UDMA6 on HighPoint chip\n", + ata_prtdev(atadev, "%s setting UDMA6 on HighPoint chip\n", (error) ? "failed" : "success"); if (!error) { - hpt_timing(scp, devno, ATA_UDMA6); - scp->mode[ATA_DEV(device)] = ATA_UDMA6; + hpt_timing(ch, devno, ATA_UDMA6); + atadev->mode = ATA_UDMA6; return; } } - if (!ATAPI_DEVICE(scp, device) && + if (!ATAPI_DEVICE(ch, device) && udmamode >= 5 && pci_get_revid(parent) >= 0x03 && - !(pci_read_config(parent, 0x5a, 1) & (scp->channel ? 0x01:0x02))) { - error = ata_command(scp, device, ATA_C_SETFEATURES, 0, + !(pci_read_config(parent, 0x5a, 1) & (ch->unit ? 0x01:0x02))) { + error = ata_command(atadev, ATA_C_SETFEATURES, 0, ATA_UDMA5, ATA_C_F_SETXFER, ATA_WAIT_READY); if (bootverbose) - ata_printf(scp, device, "%s setting UDMA5 on HighPoint chip\n", + ata_prtdev(atadev, "%s setting UDMA5 on HighPoint chip\n", (error) ? "failed" : "success"); if (!error) { - hpt_timing(scp, devno, ATA_UDMA5); - scp->mode[ATA_DEV(device)] = ATA_UDMA5; + hpt_timing(ch, devno, ATA_UDMA5); + atadev->mode = ATA_UDMA5; return; } } - if (!ATAPI_DEVICE(scp, device) && udmamode >= 4 && - !(pci_read_config(parent, 0x5a, 1) & (scp->channel ? 0x01:0x02))) { - error = ata_command(scp, device, ATA_C_SETFEATURES, 0, + if (!ATAPI_DEVICE(ch, device) && udmamode >= 4 && + !(pci_read_config(parent, 0x5a, 1) & (ch->unit ? 0x01:0x02))) { + error = ata_command(atadev, ATA_C_SETFEATURES, 0, ATA_UDMA4, ATA_C_F_SETXFER, ATA_WAIT_READY); if (bootverbose) - ata_printf(scp, device, "%s setting UDMA4 on HighPoint chip\n", + ata_prtdev(atadev, "%s setting UDMA4 on HighPoint chip\n", (error) ? "failed" : "success"); if (!error) { - hpt_timing(scp, devno, ATA_UDMA4); - scp->mode[ATA_DEV(device)] = ATA_UDMA4; + hpt_timing(ch, devno, ATA_UDMA4); + atadev->mode = ATA_UDMA4; return; } } - if (!ATAPI_DEVICE(scp, device) && udmamode >= 2) { - error = ata_command(scp, device, ATA_C_SETFEATURES, 0, + if (!ATAPI_DEVICE(ch, device) && udmamode >= 2) { + error = ata_command(atadev, ATA_C_SETFEATURES, 0, ATA_UDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); if (bootverbose) - ata_printf(scp, device, "%s setting UDMA2 on HighPoint chip\n", + ata_prtdev(atadev, "%s setting UDMA2 on HighPoint chip\n", (error) ? "failed" : "success"); if (!error) { - hpt_timing(scp, devno, ATA_UDMA2); - scp->mode[ATA_DEV(device)] = ATA_UDMA2; + hpt_timing(ch, devno, ATA_UDMA2); + atadev->mode = ATA_UDMA2; return; } } - if (!ATAPI_DEVICE(scp, device) && wdmamode >= 2 && apiomode >= 4) { - error = ata_command(scp, device, ATA_C_SETFEATURES, 0, + if (!ATAPI_DEVICE(ch, device) && wdmamode >= 2 && apiomode >= 4) { + error = ata_command(atadev, ATA_C_SETFEATURES, 0, ATA_WDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); if (bootverbose) - ata_printf(scp, device, "%s setting WDMA2 on HighPoint chip\n", + ata_prtdev(atadev, "%s setting WDMA2 on HighPoint chip\n", (error) ? "failed" : "success"); if (!error) { - hpt_timing(scp, devno, ATA_WDMA2); - scp->mode[ATA_DEV(device)] = ATA_WDMA2; + hpt_timing(ch, devno, ATA_WDMA2); + atadev->mode = ATA_WDMA2; return; } } - error = ata_command(scp, device, ATA_C_SETFEATURES, 0, + error = ata_command(atadev, ATA_C_SETFEATURES, 0, ATA_PIO0 + apiomode, ATA_C_F_SETXFER, ATA_WAIT_READY); if (bootverbose) - ata_printf(scp, device, "%s setting PIO%d on HighPoint chip\n", + ata_prtdev(atadev, "%s setting PIO%d on HighPoint chip\n", (error) ? "failed" : "success", (apiomode >= 0) ? apiomode : 0); - hpt_timing(scp, devno, ATA_PIO0 + apiomode); - scp->mode[ATA_DEV(device)] = ATA_PIO0 + apiomode; + hpt_timing(ch, devno, ATA_PIO0 + apiomode); + atadev->mode = ATA_PIO0 + apiomode; return; default: /* unknown controller chip */ /* better not try generic DMA on ATAPI devices it almost never works */ - if ((device == ATA_MASTER && scp->devices & ATA_ATAPI_MASTER) || - (device == ATA_SLAVE && scp->devices & ATA_ATAPI_SLAVE)) + if ((device == ATA_MASTER && ch->devices & ATA_ATAPI_MASTER) || + (device == ATA_SLAVE && ch->devices & ATA_ATAPI_SLAVE)) break; /* if controller says its setup for DMA take the easy way out */ /* the downside is we dont know what DMA mode we are in */ if ((udmamode >= 0 || wdmamode > 1) && - (ATA_INB(scp->r_bmio, ATA_BMSTAT_PORT) & + (ATA_INB(ch->r_bmio, ATA_BMSTAT_PORT) & ((device==ATA_MASTER) ? ATA_BMSTAT_DMA_MASTER : ATA_BMSTAT_DMA_SLAVE))) { - scp->mode[ATA_DEV(device)] = ATA_DMA; + atadev->mode = ATA_DMA; return; } /* well, we have no support for this, but try anyways */ - if ((wdmamode >= 2 && apiomode >= 4) && scp->r_bmio) { - error = ata_command(scp, device, ATA_C_SETFEATURES, 0, + if ((wdmamode >= 2 && apiomode >= 4) && ch->r_bmio) { + error = ata_command(atadev, ATA_C_SETFEATURES, 0, ATA_WDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); if (bootverbose) - ata_printf(scp, device, "%s setting WDMA2 on generic chip\n", + ata_prtdev(atadev, "%s setting WDMA2 on generic chip\n", (error) ? "failed" : "success"); if (!error) { - scp->mode[ATA_DEV(device)] = ATA_WDMA2; + atadev->mode = ATA_WDMA2; return; } } } - error = ata_command(scp, device, ATA_C_SETFEATURES, 0, ATA_PIO0 + apiomode, + error = ata_command(atadev, ATA_C_SETFEATURES, 0, ATA_PIO0 + apiomode, ATA_C_F_SETXFER,ATA_WAIT_READY); if (bootverbose) - ata_printf(scp, device, "%s setting PIO%d on generic chip\n", + ata_prtdev(atadev, "%s setting PIO%d on generic chip\n", (error) ? "failed" : "success", apiomode < 0 ? 0 : apiomode); if (!error) - scp->mode[ATA_DEV(device)] = ATA_PIO0 + apiomode; + atadev->mode = ATA_PIO0 + apiomode; else { if (bootverbose) - ata_printf(scp, device, "using PIO mode set by BIOS\n"); - scp->mode[ATA_DEV(device)] = ATA_PIO; + ata_prtdev(atadev, "using PIO mode set by BIOS\n"); + atadev->mode = ATA_PIO; } } int -ata_dmasetup(struct ata_softc *scp, int device, struct ata_dmaentry *dmatab, +ata_dmasetup(struct ata_channel *ch, int device, struct ata_dmaentry *dmatab, caddr_t data, int32_t count) { u_int32_t dma_count, dma_base; int i = 0; - if (((uintptr_t)data & scp->alignment) || (count & scp->alignment)) { - ata_printf(scp, device, "non aligned DMA transfer attempted\n"); + if (((uintptr_t)data & ch->alignment) || (count & ch->alignment)) { + ata_printf(ch, device, "non aligned DMA transfer attempted\n"); return -1; } if (!count) { - ata_printf(scp, device, "zero length DMA transfer attempted\n"); + ata_printf(ch, device, "zero length DMA transfer attempted\n"); return -1; } @@ -1077,7 +1073,7 @@ ata_dmasetup(struct ata_softc *scp, int device, struct ata_dmaentry *dmatab, dmatab[i].count = (dma_count & 0xffff); i++; if (i >= ATA_DMA_ENTRIES) { - ata_printf(scp, device, "too many segments in DMA table\n"); + ata_printf(ch, device, "too many segments in DMA table\n"); return -1; } dma_base = vtophys(data); @@ -1091,41 +1087,41 @@ ata_dmasetup(struct ata_softc *scp, int device, struct ata_dmaentry *dmatab, } void -ata_dmastart(struct ata_softc *scp, int device, +ata_dmastart(struct ata_channel *ch, int device, struct ata_dmaentry *dmatab, int dir) { - scp->flags |= ATA_DMA_ACTIVE; - ATA_OUTL(scp->r_bmio, ATA_BMDTP_PORT, vtophys(dmatab)); - ATA_OUTB(scp->r_bmio, ATA_BMCMD_PORT, dir ? ATA_BMCMD_WRITE_READ : 0); - ATA_OUTB(scp->r_bmio, ATA_BMSTAT_PORT, - (ATA_INB(scp->r_bmio, ATA_BMSTAT_PORT) | + ch->flags |= ATA_DMA_ACTIVE; + ATA_OUTL(ch->r_bmio, ATA_BMDTP_PORT, vtophys(dmatab)); + ATA_OUTB(ch->r_bmio, ATA_BMCMD_PORT, dir ? ATA_BMCMD_WRITE_READ : 0); + ATA_OUTB(ch->r_bmio, ATA_BMSTAT_PORT, + (ATA_INB(ch->r_bmio, ATA_BMSTAT_PORT) | (ATA_BMSTAT_INTERRUPT | ATA_BMSTAT_ERROR))); - ATA_OUTB(scp->r_bmio, ATA_BMCMD_PORT, - ATA_INB(scp->r_bmio, ATA_BMCMD_PORT) | ATA_BMCMD_START_STOP); + ATA_OUTB(ch->r_bmio, ATA_BMCMD_PORT, + ATA_INB(ch->r_bmio, ATA_BMCMD_PORT) | ATA_BMCMD_START_STOP); } int -ata_dmadone(struct ata_softc *scp) +ata_dmadone(struct ata_channel *ch) { int error; - ATA_OUTB(scp->r_bmio, ATA_BMCMD_PORT, - ATA_INB(scp->r_bmio, ATA_BMCMD_PORT) & ~ATA_BMCMD_START_STOP); - scp->flags &= ~ATA_DMA_ACTIVE; - error = ATA_INB(scp->r_bmio, ATA_BMSTAT_PORT); - ATA_OUTB(scp->r_bmio, ATA_BMSTAT_PORT, + ATA_OUTB(ch->r_bmio, ATA_BMCMD_PORT, + ATA_INB(ch->r_bmio, ATA_BMCMD_PORT) & ~ATA_BMCMD_START_STOP); + ch->flags &= ~ATA_DMA_ACTIVE; + error = ATA_INB(ch->r_bmio, ATA_BMSTAT_PORT); + ATA_OUTB(ch->r_bmio, ATA_BMSTAT_PORT, error | ATA_BMSTAT_INTERRUPT | ATA_BMSTAT_ERROR); return error & ATA_BMSTAT_MASK; } int -ata_dmastatus(struct ata_softc *scp) +ata_dmastatus(struct ata_channel *ch) { - return ATA_INB(scp->r_bmio, ATA_BMSTAT_PORT) & ATA_BMSTAT_MASK; + return ATA_INB(ch->r_bmio, ATA_BMSTAT_PORT) & ATA_BMSTAT_MASK; } static void -cyrix_timing(struct ata_softc *scp, int devno, int mode) +cyrix_timing(struct ata_channel *ch, int devno, int mode) { u_int32_t reg20 = 0x0000e132; u_int32_t reg24 = 0x00017771; @@ -1139,12 +1135,12 @@ cyrix_timing(struct ata_softc *scp, int devno, int mode) case ATA_WDMA2: reg24 = 0x00002020; break; case ATA_UDMA2: reg24 = 0x00911030; break; } - ATA_OUTL(scp->r_bmio, (devno << 3) + 0x20, reg20); - ATA_OUTL(scp->r_bmio, (devno << 3) + 0x24, reg24); + ATA_OUTL(ch->r_bmio, (devno << 3) + 0x20, reg20); + ATA_OUTL(ch->r_bmio, (devno << 3) + 0x24, reg24); } static void -promise_timing(struct ata_softc *scp, int devno, int mode) +promise_timing(struct ata_channel *ch, int devno, int mode) { u_int32_t timing = 0; struct promise_timing { @@ -1168,17 +1164,17 @@ promise_timing(struct ata_softc *scp, int devno, int mode) t->prefetch = 1; t->errdy = 1; t->syncin = 1; } - switch (scp->chiptype) { + switch (ch->chiptype) { case 0x4d33105a: /* Promise Ultra/Fasttrak 33 */ switch (mode) { default: - case ATA_PIO0: t->pa = 9; t->pb = 19; t->mb = 7; t->mc = 15; break; - case ATA_PIO1: t->pa = 5; t->pb = 12; t->mb = 7; t->mc = 15; break; - case ATA_PIO2: t->pa = 3; t->pb = 8; t->mb = 7; t->mc = 15; break; - case ATA_PIO3: t->pa = 2; t->pb = 6; t->mb = 7; t->mc = 15; break; - case ATA_PIO4: t->pa = 1; t->pb = 4; t->mb = 7; t->mc = 15; break; - case ATA_WDMA2: t->pa = 3; t->pb = 7; t->mb = 3; t->mc = 3; break; - case ATA_UDMA2: t->pa = 3; t->pb = 7; t->mb = 1; t->mc = 1; break; + case ATA_PIO0: t->pa = 9; t->pb = 19; t->mb = 7; t->mc = 15; break; + case ATA_PIO1: t->pa = 5; t->pb = 12; t->mb = 7; t->mc = 15; break; + case ATA_PIO2: t->pa = 3; t->pb = 8; t->mb = 7; t->mc = 15; break; + case ATA_PIO3: t->pa = 2; t->pb = 6; t->mb = 7; t->mc = 15; break; + case ATA_PIO4: t->pa = 1; t->pb = 4; t->mb = 7; t->mc = 15; break; + case ATA_WDMA2: t->pa = 3; t->pb = 7; t->mb = 3; t->mc = 3; break; + case ATA_UDMA2: t->pa = 3; t->pb = 7; t->mb = 1; t->mc = 1; break; } break; @@ -1187,38 +1183,38 @@ promise_timing(struct ata_softc *scp, int devno, int mode) case 0x0d30105a: /* Promise OEM ATA 100 */ switch (mode) { default: - case ATA_PIO0: t->pa = 15; t->pb = 31; t->mb = 7; t->mc = 15; break; - case ATA_PIO1: t->pa = 10; t->pb = 24; t->mb = 7; t->mc = 15; break; - case ATA_PIO2: t->pa = 6; t->pb = 16; t->mb = 7; t->mc = 15; break; - case ATA_PIO3: t->pa = 4; t->pb = 12; t->mb = 7; t->mc = 15; break; - case ATA_PIO4: t->pa = 2; t->pb = 8; t->mb = 7; t->mc = 15; break; - case ATA_WDMA2: t->pa = 6; t->pb = 14; t->mb = 6; t->mc = 6; break; - case ATA_UDMA2: t->pa = 6; t->pb = 14; t->mb = 2; t->mc = 2; break; - case ATA_UDMA4: t->pa = 3; t->pb = 7; t->mb = 1; t->mc = 1; break; - case ATA_UDMA5: t->pa = 3; t->pb = 7; t->mb = 1; t->mc = 1; break; + case ATA_PIO0: t->pa = 15; t->pb = 31; t->mb = 7; t->mc = 15; break; + case ATA_PIO1: t->pa = 10; t->pb = 24; t->mb = 7; t->mc = 15; break; + case ATA_PIO2: t->pa = 6; t->pb = 16; t->mb = 7; t->mc = 15; break; + case ATA_PIO3: t->pa = 4; t->pb = 12; t->mb = 7; t->mc = 15; break; + case ATA_PIO4: t->pa = 2; t->pb = 8; t->mb = 7; t->mc = 15; break; + case ATA_WDMA2: t->pa = 6; t->pb = 14; t->mb = 6; t->mc = 6; break; + case ATA_UDMA2: t->pa = 6; t->pb = 14; t->mb = 2; t->mc = 2; break; + case ATA_UDMA4: t->pa = 3; t->pb = 7; t->mb = 1; t->mc = 1; break; + case ATA_UDMA5: t->pa = 3; t->pb = 7; t->mb = 1; t->mc = 1; break; } break; } - pci_write_config(device_get_parent(scp->dev), 0x60 + (devno<<2), timing, 4); + pci_write_config(device_get_parent(ch->dev), 0x60 + (devno<<2), timing, 4); } static void -hpt_timing(struct ata_softc *scp, int devno, int mode) +hpt_timing(struct ata_channel *ch, int devno, int mode) { - device_t parent = device_get_parent(scp->dev); + device_t parent = device_get_parent(ch->dev); u_int32_t timing; if (pci_get_revid(parent) >= 0x05) { /* HPT372 */ switch (mode) { - case ATA_PIO0: timing = 0x0d029d5e; break; - case ATA_PIO1: timing = 0x0d029d26; break; - case ATA_PIO2: timing = 0x0c829ca6; break; - case ATA_PIO3: timing = 0x0c829c84; break; - case ATA_PIO4: timing = 0x0c829c62; break; + case ATA_PIO0: timing = 0x0d029d5e; break; + case ATA_PIO1: timing = 0x0d029d26; break; + case ATA_PIO2: timing = 0x0c829ca6; break; + case ATA_PIO3: timing = 0x0c829c84; break; + case ATA_PIO4: timing = 0x0c829c62; break; case ATA_WDMA2: timing = 0x2c829262; break; - case ATA_UDMA2: timing = 0x1c91dc62; break; - case ATA_UDMA4: timing = 0x1c8ddc62; break; - case ATA_UDMA5: timing = 0x1c6ddc62; break; - case ATA_UDMA6: timing = 0x1c81dc62; break; + case ATA_UDMA2: timing = 0x1c91dc62; break; + case ATA_UDMA4: timing = 0x1c8ddc62; break; + case ATA_UDMA5: timing = 0x1c6ddc62; break; + case ATA_UDMA6: timing = 0x1c81dc62; break; default: timing = 0x0d029d5e; } pci_write_config(parent, 0x40 + (devno << 2) , timing, 4); @@ -1231,10 +1227,10 @@ hpt_timing(struct ata_softc *scp, int devno, int mode) case ATA_PIO2: timing = 0x06514e33; break; case ATA_PIO3: timing = 0x06514e22; break; case ATA_PIO4: timing = 0x06514e21; break; - case ATA_WDMA2: timing = 0x26514e21; break; - case ATA_UDMA2: timing = 0x16494e31; break; - case ATA_UDMA4: timing = 0x16454e31; break; - case ATA_UDMA5: timing = 0x16454e31; break; + case ATA_WDMA2: timing = 0x26514e21; break; + case ATA_UDMA2: timing = 0x16494e31; break; + case ATA_UDMA4: timing = 0x16454e31; break; + case ATA_UDMA5: timing = 0x16454e31; break; default: timing = 0x06514e57; } pci_write_config(parent, 0x40 + (devno << 2) , timing, 4); diff --git a/sys/dev/ata/ata-isa.c b/sys/dev/ata/ata-isa.c index 6d346ea..cb04242 100644 --- a/sys/dev/ata/ata-isa.c +++ b/sys/dev/ata/ata-isa.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 @@ -57,10 +57,10 @@ static struct isa_pnp_id ata_ids[] = { static int ata_isa_probe(device_t dev) { - struct ata_softc *scp = device_get_softc(dev); + struct ata_channel *ch = device_get_softc(dev); struct resource *io; - int rid; u_long tmp; + int rid; /* check isapnp ids */ if (ISA_PNP_PROBE(device_get_parent(dev), dev, ata_ids) == ENXIO) @@ -80,8 +80,8 @@ ata_isa_probe(device_t dev) } bus_release_resource(dev, SYS_RES_IOPORT, rid, io); - scp->channel = 0; - scp->flags |= ATA_USE_16BIT; + ch->unit = 0; + ch->flags |= ATA_USE_16BIT; return ata_probe(dev); } @@ -96,7 +96,7 @@ static device_method_t ata_isa_methods[] = { static driver_t ata_isa_driver = { "ata", ata_isa_methods, - sizeof(struct ata_softc), + sizeof(struct ata_channel), }; DRIVER_MODULE(ata, isa, ata_isa_driver, ata_devclass, 0, 0); @@ -108,38 +108,38 @@ DRIVER_MODULE(ata, isa, ata_isa_driver, ata_devclass, 0, 0); #include "pci.h" #if NPCI == 0 void * -ata_dmaalloc(struct ata_softc *scp, int device) +ata_dmaalloc(struct ata_channel *ch, int device) { return 0; } void -ata_dmainit(struct ata_softc *scp, int device, +ata_dmainit(struct ata_channel *ch, int device, int piomode, int wdmamode, int udmamode) { } int -ata_dmasetup(struct ata_softc *scp, int device, struct ata_dmaentry *dmatab, +ata_dmasetup(struct ata_channel *ch, int device, struct ata_dmaentry *dmatab, caddr_t data, int32_t count) { return -1; } void -ata_dmastart(struct ata_softc *scp, int device, +ata_dmastart(struct ata_channel *ch, int device, struct ata_dmaentry *dmatab, int dir) { } int -ata_dmadone(struct ata_softc *scp) +ata_dmadone(struct ata_channel *ch) { return -1; } int -ata_dmastatus(struct ata_softc *scp) +ata_dmastatus(struct ata_channel *ch) { return -1; } diff --git a/sys/dev/ata/ata-pci.c b/sys/dev/ata/ata-pci.c index 44c558b..952f9b1 100644 --- a/sys/dev/ata/ata-pci.c +++ b/sys/dev/ata/ata-pci.c @@ -50,7 +50,7 @@ #include <dev/ata/ata-all.h> /* device structures */ -struct ata_pci_softc { +struct ata_pci_controller { struct resource *bmio; int bmaddr; struct resource *irq; @@ -246,12 +246,12 @@ ata_pci_match(device_t dev) /* we belive we are on a TX4, now do our (simple) magic */ if (pci_get_slot(dev) == 1) { bus_get_resource(dev, SYS_RES_IRQ, 0, &start, &end); - return "Promise TX4 ATA100 controller (channel 0+1)"; + return "Promise TX4 ATA100 controller (channel 0+1)"; } else if (pci_get_slot(dev) == 2 && start && end) { bus_set_resource(dev, SYS_RES_IRQ, 0, start, end); start = end = 0; - return "Promise TX4 ATA100 controller (channel 2+3)"; + return "Promise TX4 ATA100 controller (channel 2+3)"; } else start = end = 0; @@ -317,8 +317,9 @@ ata_pci_add_child(device_t dev, int unit) return ENOMEM; } else { - if (!(child = device_add_child(dev, "ata", - devclass_find_free_unit(devclass_find("ata"), 2)))) + if (!(child = + device_add_child(dev, "ata", + devclass_find_free_unit(ata_devclass, 2)))) return ENOMEM; } return 0; @@ -327,7 +328,7 @@ ata_pci_add_child(device_t dev, int unit) static int ata_pci_attach(device_t dev) { - struct ata_pci_softc *sc = device_get_softc(dev); + struct ata_pci_controller *controller = device_get_softc(dev); u_int8_t class, subclass; u_int32_t type, cmd; int rid; @@ -349,9 +350,9 @@ ata_pci_attach(device_t dev) /* is there a valid port range to connect to ? */ rid = 0x20; - sc->bmio = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, - 0, ~0, 1, RF_ACTIVE); - if (!sc->bmio) + controller->bmio = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, + 0, ~0, 1, RF_ACTIVE); + if (!controller->bmio) device_printf(dev, "Busmastering DMA not configured\n"); } else @@ -367,11 +368,11 @@ ata_pci_attach(device_t dev) case 0x4d38105a: /* Promise 66 & 100 (before TX2) need the clock changed */ case 0x4d30105a: case 0x0d30105a: - ATA_OUTB(sc->bmio, 0x11, ATA_INB(sc->bmio, 0x11) | 0x0a); + ATA_OUTB(controller->bmio, 0x11, ATA_INB(controller->bmio, 0x11)|0x0a); /* FALLTHROUGH */ case 0x4d33105a: /* Promise (before TX2) need burst mode turned on */ - ATA_OUTB(sc->bmio, 0x1f, ATA_INB(sc->bmio, 0x1f) | 0x01); + ATA_OUTB(controller->bmio, 0x1f, ATA_INB(controller->bmio, 0x1f)|0x01); break; case 0x00041103: /* HighPoint HPT 366/368/370/372 */ @@ -380,7 +381,7 @@ ata_pci_attach(device_t dev) case 0x01: /* turn off interrupt prediction */ pci_write_config(dev, 0x51, - (pci_read_config(dev, 0x51, 1) & ~0x80), 1); + (pci_read_config(dev, 0x51, 1) & ~0x80), 1); break; case 0x02: /* HPT 368 */ @@ -389,12 +390,12 @@ ata_pci_attach(device_t dev) case 0x05: /* HPT 372 */ /* turn off interrupt prediction */ pci_write_config(dev, 0x51, - (pci_read_config(dev, 0x51, 1) & ~0x03), 1); + (pci_read_config(dev, 0x51, 1) & ~0x03), 1); pci_write_config(dev, 0x55, - (pci_read_config(dev, 0x55, 1) & ~0x03), 1); + (pci_read_config(dev, 0x55, 1) & ~0x03), 1); /* turn on interrupts */ pci_write_config(dev, 0x5a, - (pci_read_config(dev, 0x5a, 1) & ~0x10), 1); + (pci_read_config(dev, 0x5a, 1) & ~0x10), 1); } break; @@ -404,7 +405,7 @@ ata_pci_attach(device_t dev) if ((ata_find_dev(dev, 0x06861106, 0x10) && !ata_find_dev(dev, 0x06861106, 0x40)) || ata_find_dev(dev, 0x05961106, 0x12)) - pci_write_config(dev, 0x50, 0x030b030b, 4); + pci_write_config(dev, 0x50, 0x030b030b, 4); /* the southbridge might need the data corruption fix */ if (ata_find_dev(dev, 0x06861106, 0x40) || @@ -437,15 +438,15 @@ ata_pci_attach(device_t dev) case 0x10001042: /* RZ 100? known bad, no DMA */ case 0x10011042: case 0x06401095: /* CMD 640 known bad, no DMA */ - sc->bmio = NULL; + controller->bmio = NULL; device_printf(dev, "Busmastering DMA disabled\n"); } - if (sc->bmio) { - sc->bmaddr = rman_get_start(sc->bmio); + if (controller->bmio) { + controller->bmaddr = rman_get_start(controller->bmio); BUS_RELEASE_RESOURCE(device_get_parent(dev), dev, - SYS_RES_IOPORT, rid, sc->bmio); - sc->bmio = NULL; + SYS_RES_IOPORT, rid, controller->bmio); + controller->bmio = NULL; } /* @@ -467,7 +468,7 @@ ata_pci_attach(device_t dev) } static int -ata_pci_intr(struct ata_softc *scp) +ata_pci_intr(struct ata_channel *ch) { u_int8_t dmastat; @@ -476,19 +477,19 @@ ata_pci_intr(struct ata_softc *scp) * cases with our twin channel, we only want to process interrupts * that we know this channel generated. */ - switch (scp->chiptype) { - case 0x00041103: /* HighPoint HPT366/368/370/372 */ - if (((dmastat = ata_dmastatus(scp)) & + switch (ch->chiptype) { + case 0x00041103: /* HighPoint HPT366/368/370/372 */ + if (((dmastat = ata_dmastatus(ch)) & (ATA_BMSTAT_ACTIVE | ATA_BMSTAT_INTERRUPT)) != ATA_BMSTAT_INTERRUPT) return 1; - ATA_OUTB(scp->r_bmio, ATA_BMSTAT_PORT, dmastat | ATA_BMSTAT_INTERRUPT); + ATA_OUTB(ch->r_bmio, ATA_BMSTAT_PORT, dmastat | ATA_BMSTAT_INTERRUPT); DELAY(1); return 0; case 0x06481095: /* CMD 648 */ case 0x06491095: /* CMD 649 */ - if (!(pci_read_config(device_get_parent(scp->dev), 0x71, 1) & - (scp->channel ? 0x08 : 0x04))) + if (!(pci_read_config(device_get_parent(ch->dev), 0x71, 1) & + (ch->unit ? 0x08 : 0x04))) return 1; break; @@ -496,24 +497,24 @@ ata_pci_intr(struct ata_softc *scp) case 0x4d38105a: /* Promise Ultra/Fasttrak 66 */ case 0x4d30105a: /* Promise Ultra/Fasttrak 100 */ case 0x0d30105a: /* Promise OEM ATA100 */ - if (!(ATA_INL(scp->r_bmio, (scp->channel ? 0x14 : 0x1c)) & - (scp->channel ? 0x00004000 : 0x00000400))) + if (!(ATA_INL(ch->r_bmio, (ch->unit ? 0x14 : 0x1c)) & + (ch->unit ? 0x00004000 : 0x00000400))) return 1; - break; + break; case 0x4d68105a: /* Promise TX2 ATA100 */ case 0x6268105a: /* Promise TX2 ATA100 */ case 0x4d69105a: /* Promise TX2 ATA133 */ - ATA_OUTB(scp->r_bmio, ATA_BMDEVSPEC_0, 0x0b); - if (!(ATA_INB(scp->r_bmio, ATA_BMDEVSPEC_1) & 0x20)) + ATA_OUTB(ch->r_bmio, ATA_BMDEVSPEC_0, 0x0b); + if (!(ATA_INB(ch->r_bmio, ATA_BMDEVSPEC_1) & 0x20)) return 1; break; } - if (scp->flags & ATA_DMA_ACTIVE) { - if (!((dmastat = ata_dmastatus(scp)) & ATA_BMSTAT_INTERRUPT)) + if (ch->flags & ATA_DMA_ACTIVE) { + if (!((dmastat = ata_dmastatus(ch)) & ATA_BMSTAT_INTERRUPT)) return 1; - ATA_OUTB(scp->r_bmio, ATA_BMSTAT_PORT, dmastat | ATA_BMSTAT_INTERRUPT); + ATA_OUTB(ch->r_bmio, ATA_BMSTAT_PORT, dmastat | ATA_BMSTAT_INTERRUPT); DELAY(1); } return 0; @@ -522,14 +523,14 @@ ata_pci_intr(struct ata_softc *scp) static int ata_pci_print_child(device_t dev, device_t child) { - struct ata_softc *scp = device_get_softc(child); + struct ata_channel *ch = device_get_softc(child); int retval = 0; retval += bus_print_child_header(dev, child); - retval += printf(": at 0x%lx", rman_get_start(scp->r_io)); + retval += printf(": at 0x%lx", rman_get_start(ch->r_io)); if (ATA_MASTERDEV(dev)) - retval += printf(" irq %d", 14 + scp->channel); + retval += printf(" irq %d", 14 + ch->unit); retval += bus_print_child_footer(dev, child); @@ -540,9 +541,9 @@ static struct resource * ata_pci_alloc_resource(device_t dev, device_t child, int type, int *rid, u_long start, u_long end, u_long count, u_int flags) { - struct ata_pci_softc *sc = device_get_softc(dev); + struct ata_pci_controller *controller = device_get_softc(dev); struct resource *res = NULL; - int channel = ((struct ata_softc *)device_get_softc(child))->channel; + int unit = ((struct ata_channel *)device_get_softc(child))->unit; int myrid; if (type == SYS_RES_IOPORT) { @@ -550,7 +551,7 @@ ata_pci_alloc_resource(device_t dev, device_t child, int type, int *rid, case ATA_IOADDR_RID: if (ATA_MASTERDEV(dev)) { myrid = 0; - start = (channel ? ATA_SECONDARY : ATA_PRIMARY); + start = (unit ? ATA_SECONDARY : ATA_PRIMARY); end = start + ATA_IOSIZE - 1; count = ATA_IOSIZE; res = BUS_ALLOC_RESOURCE(device_get_parent(dev), child, @@ -558,7 +559,7 @@ ata_pci_alloc_resource(device_t dev, device_t child, int type, int *rid, start, end, count, flags); } else { - myrid = 0x10 + 8 * channel; + myrid = 0x10 + 8 * unit; res = BUS_ALLOC_RESOURCE(device_get_parent(dev), dev, SYS_RES_IOPORT, &myrid, start, end, count, flags); @@ -568,7 +569,7 @@ ata_pci_alloc_resource(device_t dev, device_t child, int type, int *rid, case ATA_ALTADDR_RID: if (ATA_MASTERDEV(dev)) { myrid = 0; - start = (channel ? ATA_SECONDARY : ATA_PRIMARY) + ATA_ALTOFFSET; + start = (unit ? ATA_SECONDARY : ATA_PRIMARY) + ATA_ALTOFFSET; end = start + ATA_ALTIOSIZE - 1; count = ATA_ALTIOSIZE; res = BUS_ALLOC_RESOURCE(device_get_parent(dev), child, @@ -576,8 +577,8 @@ ata_pci_alloc_resource(device_t dev, device_t child, int type, int *rid, start, end, count, flags); } else { - myrid = 0x14 + 8 * channel; - res = BUS_ALLOC_RESOURCE(device_get_parent(dev), dev, + myrid = 0x14 + 8 * unit; + res = BUS_ALLOC_RESOURCE(device_get_parent(dev), dev, SYS_RES_IOPORT, &myrid, start, end, count, flags); if (res) { @@ -586,7 +587,7 @@ ata_pci_alloc_resource(device_t dev, device_t child, int type, int *rid, count = ATA_ALTIOSIZE; BUS_RELEASE_RESOURCE(device_get_parent(dev), dev, SYS_RES_IOPORT, myrid, res); - res = BUS_ALLOC_RESOURCE(device_get_parent(dev), dev, + res = BUS_ALLOC_RESOURCE(device_get_parent(dev), dev, SYS_RES_IOPORT, &myrid, start, end, count, flags); } @@ -594,14 +595,15 @@ ata_pci_alloc_resource(device_t dev, device_t child, int type, int *rid, break; case ATA_BMADDR_RID: - if (sc->bmaddr) { + if (controller->bmaddr) { myrid = 0x20; - start = (channel == 0 ? sc->bmaddr : sc->bmaddr + ATA_BMIOSIZE); + start = (unit == 0 ? + controller->bmaddr : controller->bmaddr+ATA_BMIOSIZE); end = start + ATA_BMIOSIZE - 1; count = ATA_BMIOSIZE; res = BUS_ALLOC_RESOURCE(device_get_parent(dev), child, - SYS_RES_IOPORT, &myrid, - start, end, count, flags); + SYS_RES_IOPORT, &myrid, + start, end, count, flags); } } return res; @@ -610,9 +612,9 @@ ata_pci_alloc_resource(device_t dev, device_t child, int type, int *rid, if (type == SYS_RES_IRQ && *rid == ATA_IRQ_RID) { if (ATA_MASTERDEV(dev)) { #ifdef __alpha__ - return alpha_platform_alloc_ide_intr(channel); + return alpha_platform_alloc_ide_intr(unit); #else - int irq = (channel == 0 ? 14 : 15); + int irq = (unit == 0 ? 14 : 15); return BUS_ALLOC_RESOURCE(device_get_parent(dev), child, SYS_RES_IRQ, rid, irq, irq, 1, flags); @@ -620,11 +622,12 @@ ata_pci_alloc_resource(device_t dev, device_t child, int type, int *rid, } else { /* primary and secondary channels share interrupt, keep track */ - if (!sc->irq) - sc->irq = BUS_ALLOC_RESOURCE(device_get_parent(dev), dev, - SYS_RES_IRQ, rid, 0, ~0, 1, flags); - sc->irqcnt++; - return sc->irq; + if (!controller->irq) + controller->irq = BUS_ALLOC_RESOURCE(device_get_parent(dev), + dev, SYS_RES_IRQ, + rid, 0, ~0, 1, flags); + controller->irqcnt++; + return controller->irq; } } return 0; @@ -634,8 +637,8 @@ static int ata_pci_release_resource(device_t dev, device_t child, int type, int rid, struct resource *r) { - struct ata_pci_softc *sc = device_get_softc(dev); - int channel = ((struct ata_softc *)device_get_softc(child))->channel; + struct ata_pci_controller *controller = device_get_softc(dev); + int unit = ((struct ata_channel *)device_get_softc(child))->unit; if (type == SYS_RES_IOPORT) { switch (rid) { @@ -645,7 +648,7 @@ ata_pci_release_resource(device_t dev, device_t child, int type, int rid, SYS_RES_IOPORT, 0x0, r); else return BUS_RELEASE_RESOURCE(device_get_parent(dev), dev, - SYS_RES_IOPORT, 0x10+8*channel, r); + SYS_RES_IOPORT, 0x10 + 8 * unit, r); break; case ATA_ALTADDR_RID: @@ -654,7 +657,7 @@ ata_pci_release_resource(device_t dev, device_t child, int type, int rid, SYS_RES_IOPORT, 0x0, r); else return BUS_RELEASE_RESOURCE(device_get_parent(dev), dev, - SYS_RES_IOPORT, 0x14+8*channel, r); + SYS_RES_IOPORT, 0x14 + 8 * unit, r); break; case ATA_BMADDR_RID: @@ -670,7 +673,7 @@ ata_pci_release_resource(device_t dev, device_t child, int type, int rid, if (ATA_MASTERDEV(dev)) { #ifdef __alpha__ - return alpha_platform_release_ide_intr(channel, r); + return alpha_platform_release_ide_intr(unit, r); #else return BUS_RELEASE_RESOURCE(device_get_parent(dev), child, SYS_RES_IRQ, rid, r); @@ -678,9 +681,9 @@ ata_pci_release_resource(device_t dev, device_t child, int type, int rid, } else { /* primary and secondary channels share interrupt, keep track */ - if (--sc->irqcnt) + if (--controller->irqcnt) return 0; - sc->irq = 0; + controller->irq = 0; return BUS_RELEASE_RESOURCE(device_get_parent(dev), dev, SYS_RES_IRQ, rid, r); } @@ -743,7 +746,7 @@ static device_method_t ata_pci_methods[] = { static driver_t ata_pci_driver = { "atapci", ata_pci_methods, - sizeof(struct ata_pci_softc), + sizeof(struct ata_pci_controller), }; static devclass_t ata_pci_devclass; @@ -753,7 +756,7 @@ DRIVER_MODULE(atapci, pci, ata_pci_driver, ata_pci_devclass, 0, 0); static int ata_pcisub_probe(device_t dev) { - struct ata_softc *scp = device_get_softc(dev); + struct ata_channel *ch = device_get_softc(dev); device_t *children; int count, i; @@ -761,11 +764,11 @@ ata_pcisub_probe(device_t dev) device_get_children(device_get_parent(dev), &children, &count); for (i = 0; i < count; i++) { if (children[i] == dev) - scp->channel = i; + ch->unit = i; } free(children, M_TEMP); - scp->chiptype = pci_get_devid(device_get_parent(dev)); - scp->intr_func = ata_pci_intr; + ch->chiptype = pci_get_devid(device_get_parent(dev)); + ch->intr_func = ata_pci_intr; return ata_probe(dev); } @@ -781,7 +784,7 @@ static device_method_t ata_pcisub_methods[] = { static driver_t ata_pcisub_driver = { "ata", ata_pcisub_methods, - sizeof(struct ata_softc), + sizeof(struct ata_channel), }; DRIVER_MODULE(ata, atapci, ata_pcisub_driver, ata_devclass, 0, 0); diff --git a/sys/dev/ata/ata-raid.c b/sys/dev/ata/ata-raid.c index 480b5ac..ba7e5cf 100644 --- a/sys/dev/ata/ata-raid.c +++ b/sys/dev/ata/ata-raid.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2000,2001 Søren Schmidt <sos@FreeBSD.org> + * Copyright (c) 2000,2001,2002 Søren Schmidt <sos@FreeBSD.org> * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -48,92 +48,165 @@ #include <dev/ata/ata-raid.h> /* device structures */ -static d_open_t aropen; -static d_strategy_t arstrategy; +static d_open_t aropen; +static d_strategy_t arstrategy; static struct cdevsw ar_cdevsw = { - /* open */ aropen, - /* close */ nullclose, - /* read */ physread, - /* write */ physwrite, - /* ioctl */ noioctl, - /* poll */ nopoll, - /* mmap */ nommap, - /* strategy */ arstrategy, - /* name */ "ar", - /* maj */ 157, - /* dump */ nodump, - /* psize */ nopsize, - /* flags */ D_DISK, + /* open */ aropen, + /* close */ nullclose, + /* read */ physread, + /* write */ physwrite, + /* ioctl */ noioctl, + /* poll */ nopoll, + /* mmap */ nommap, + /* strategy */ arstrategy, + /* name */ "ar", + /* maj */ 157, + /* dump */ nodump, + /* psize */ nopsize, + /* flags */ D_DISK, }; static struct cdevsw ardisk_cdevsw; /* prototypes */ -static void ar_attach(struct ar_softc *); static void ar_done(struct bio *); -static int ar_highpoint_conf(struct ad_softc *, struct ar_softc **); -static int ar_promise_conf(struct ad_softc *, struct ar_softc **); -static int ar_read(struct ad_softc *, u_int32_t, int, char *); +static int ar_highpoint_read_conf(struct ad_softc *, struct ar_softc **); +static int ar_promise_read_conf(struct ad_softc *, struct ar_softc **); +static int ar_read(struct ad_softc *, u_int32_t, int, u_int8_t *); +/* misc defines */ +#define AD_STRATEGY(x) si_disk->d_devsw->d_strategy(x) +#define AD_SOFTC(x) ((struct ad_softc *)(x.device->driver)) + /* internal vars */ static int ar_init = 0; -static struct ar_softc *ar_table[16]; +static struct ar_softc *ar_table[MAX_ARRAYS]; static MALLOC_DEFINE(M_AR, "AR driver", "ATA RAID driver"); - + int -ar_probe(struct ad_softc *adp) -{ +ar_probe(struct ad_softc *adp) { if (!ar_init) { bzero(&ar_table, sizeof(ar_table)); ar_init = 1; } - switch(adp->controller->chiptype) { + switch(adp->device->channel->chiptype) { case 0x4d33105a: case 0x4d38105a: case 0x4d30105a: case 0x0d30105a: case 0x4d68105a: case 0x6268105a: - return (ar_promise_conf(adp, ar_table)); + /* test RAID bit in PCI reg */ + return (ar_promise_read_conf(adp, ar_table)); case 0x00041103: - return (ar_highpoint_conf(adp, ar_table)); + /* test RAID bit in PCI reg */ + return (ar_highpoint_read_conf(adp, ar_table)); } return 1; } -static void -ar_attach(struct ar_softc *raid) +void +ar_attach() { + struct ar_softc *raid; dev_t dev; - int i; - - printf("ar%d: %luMB <ATA ", - raid->lun, raid->total_secs / ((1024L * 1024L) / DEV_BSIZE)); - switch (raid->flags & (AR_F_RAID_0 | AR_F_RAID_1 | AR_F_SPAN)) { - case AR_F_RAID_0: - printf("RAID0 "); break; - case AR_F_RAID_1: - printf("RAID1 "); break; - case AR_F_SPAN: - printf("SPAN "); break; - case (AR_F_RAID_0 | AR_F_RAID_1): - printf("RAID0+1 "); break; - default: - printf("unknown array 0x%x ", raid->flags); - return; + int array, disk; + + for (array = 0; array < MAX_ARRAYS; array++) { + if (!(raid = ar_table[array]) || !raid->flags) { + continue; + } + + for (disk = 0; disk < raid->total_disks; disk++) { + if (raid->disks[disk].device) { + switch (raid->flags & (AR_F_RAID0 | AR_F_RAID1 | AR_F_SPAN)) { + case AR_F_SPAN: + case AR_F_RAID0: + if (raid->disks[disk].flags & AR_DF_ONLINE) + ata_drawerleds(raid->disks[disk].device, ATA_LED_GREEN); + else { + raid->flags &= ~AR_F_READY; + ata_drawerleds(raid->disks[disk].device, ATA_LED_RED); + } + break; + + case AR_F_RAID1: + case AR_F_RAID0 | AR_F_RAID1: + if (disk < raid->width) { + if (!(raid->disks[disk].flags & AR_DF_ONLINE) && + !(raid->disks[disk+raid->width].flags&AR_DF_ONLINE)) + raid->flags &= ~AR_F_READY; + else if (((raid->disks[disk].flags & AR_DF_ONLINE) && + !(raid->disks + [disk + raid->width].flags & AR_DF_ONLINE))|| + (!(raid->disks[disk].flags & AR_DF_ONLINE) && + (raid->disks + [disk + raid->width].flags & AR_DF_ONLINE))) + raid->flags |= AR_F_DEGRADED; + } + if (raid->disks[disk].flags & AR_DF_ONLINE) + ata_drawerleds(raid->disks[disk].device, ATA_LED_GREEN); + else + ata_drawerleds(raid->disks[disk].device, ATA_LED_RED); + break; + } + } + else { + raid->disks[disk].flags &= + ~(AR_DF_PRESENT | AR_DF_ASSIGNED | AR_DF_ONLINE); + } + } + + dev = disk_create(raid->lun, &raid->disk, 0, &ar_cdevsw,&ardisk_cdevsw); + dev->si_drv1 = raid; + dev->si_iosize_max = 256 * DEV_BSIZE; + raid->dev = dev; + + printf("ar%d: %lluMB <ATA ", + raid->lun, raid->total_sectors / ((1024L * 1024L) / DEV_BSIZE)); + switch (raid->flags & (AR_F_RAID0 | AR_F_RAID1 | AR_F_SPAN)) { + case AR_F_RAID0: + printf("RAID0 "); break; + case AR_F_RAID1: + printf("RAID1 "); break; + case AR_F_SPAN: + printf("SPAN "); break; + case (AR_F_RAID0 | AR_F_RAID1): + printf("RAID0+1 "); break; + default: + printf("unknown 0x%x ", raid->flags); + return; + } + printf("array> [%d/%d/%d] status: ", + raid->cylinders, raid->heads, raid->sectors); + switch (raid->flags & (AR_F_DEGRADED | AR_F_READY)) { + case AR_F_READY: + printf("READY"); + break; + case (AR_F_DEGRADED | AR_F_READY): + printf("DEGRADED"); + break; + default: + printf("BROKEN"); + break; + } + printf(" subdisks:\n"); + for (disk = 0; disk < raid->total_disks; disk++) { + if (raid->disks[disk].flags & AR_DF_ONLINE) + printf(" %d READY ", disk); + else if (raid->disks[disk].flags & AR_DF_ASSIGNED) + printf(" %d DOWN ", disk); + else if (raid->disks[disk].flags & AR_DF_SPARE) + printf(" %d SPARE ", disk); + else if (raid->disks[disk].flags & AR_DF_PRESENT) + printf(" %d FREE ", disk); + else + printf(" %d FAILURE no device present\n", disk); + if (raid->disks[disk].flags & AR_DF_PRESENT) + ad_print(AD_SOFTC(raid->disks[disk]), ""); + } } - printf("array> [%d/%d/%d] subdisks:\n", - raid->cylinders, raid->heads, raid->sectors); - for (i = 0; i < raid->num_subdisks; i++) - ad_print(raid->subdisk[i], " "); - for (i = 0; i < raid->num_mirrordisks; i++) - ad_print(raid->mirrordisk[i], " "); - - dev = disk_create(raid->lun, &raid->disk, 0, &ar_cdevsw, &ardisk_cdevsw); - dev->si_drv1 = raid; - dev->si_iosize_max = 256 * DEV_BSIZE; - raid->dev = dev; } static int @@ -141,7 +214,7 @@ aropen(dev_t dev, int flags, int fmt, struct thread *td) { struct ar_softc *rdp = dev->si_drv1; struct disklabel *dl; - + dl = &rdp->disk.d_label; bzero(dl, sizeof *dl); dl->d_secsize = DEV_BSIZE; @@ -149,7 +222,7 @@ aropen(dev_t dev, int flags, int fmt, struct thread *td) dl->d_ntracks = rdp->heads; dl->d_ncylinders = rdp->cylinders; dl->d_secpercyl = rdp->sectors * rdp->heads; - dl->d_secperunit = rdp->total_secs; + dl->d_secperunit = rdp->total_sectors; return 0; } @@ -160,6 +233,12 @@ arstrategy(struct bio *bp) int lba, count, chunk; caddr_t data; + if (!(rdp->flags & AR_F_READY)) { + bp->bio_flags |= BIO_ERROR; + bp->bio_error = EIO; + biodone(bp); + return; + } bp->bio_resid = bp->bio_bcount; lba = bp->bio_pblkno; data = bp->bio_data; @@ -169,43 +248,56 @@ arstrategy(struct bio *bp) int plba; buf1 = malloc(sizeof(struct ar_buf), M_AR, M_NOWAIT | M_ZERO); - if (rdp->flags & AR_F_SPAN) { + switch (rdp->flags & (AR_F_RAID0 | AR_F_RAID1 | AR_F_SPAN)) { + case AR_F_SPAN: plba = lba; - while (plba >= (rdp->subdisk[buf1->drive]->total_secs-rdp->reserved) - && buf1->drive < rdp->num_subdisks) - plba-=(rdp->subdisk[buf1->drive++]->total_secs-rdp->reserved); + while (plba >= + AD_SOFTC(rdp->disks[buf1->drive])->total_secs-rdp->reserved) + plba -= (AD_SOFTC(rdp->disks[buf1->drive++])->total_secs - + rdp->reserved); buf1->bp.bio_pblkno = plba; - chunk = min(rdp->subdisk[buf1->drive]->total_secs - - rdp->reserved - plba, count); - } - else if (rdp->flags & AR_F_RAID_0) { + chunk = min(AD_SOFTC(rdp->disks[buf1->drive])->total_secs - + rdp->reserved - plba, count); + break; + + case AR_F_RAID0: + case AR_F_RAID0 | AR_F_RAID1: plba = lba / rdp->interleave; chunk = lba % rdp->interleave; - if (plba == rdp->total_secs / rdp->interleave) { + if (plba == rdp->total_sectors / rdp->interleave) { int lastblksize = - (rdp->total_secs-(plba*rdp->interleave))/rdp->num_subdisks; + (rdp->total_sectors-(plba*rdp->interleave))/rdp->width; buf1->drive = chunk / lastblksize; buf1->bp.bio_pblkno = - ((plba / rdp->num_subdisks) * rdp->interleave) + - chunk % lastblksize; + ((plba / rdp->width) * rdp->interleave) + chunk%lastblksize; chunk = min(count, lastblksize); } else { - buf1->drive = plba % rdp->num_subdisks; + buf1->drive = plba % rdp->width; buf1->bp.bio_pblkno = - ((plba / rdp->num_subdisks) * rdp->interleave) + chunk; + ((plba / rdp->width) * rdp->interleave) + chunk; chunk = min(count, rdp->interleave - chunk); } - } - else { + break; + + case AR_F_RAID1: buf1->bp.bio_pblkno = lba; buf1->drive = 0; chunk = count; + break; + + default: + printf("Oops! unknown array type in arstrategy\n"); + bp->bio_flags |= BIO_ERROR; + bp->bio_error = EIO; + biodone(bp); + return; } if (buf1->drive > 0) buf1->bp.bio_pblkno += rdp->offset; + buf1->bp.bio_caller1 = (void *)rdp; buf1->bp.bio_bcount = chunk * DEV_BSIZE; buf1->bp.bio_data = data; @@ -214,33 +306,98 @@ arstrategy(struct bio *bp) buf1->bp.bio_done = ar_done; buf1->org = bp; - /* simpleminded load balancing on RAID1 arrays */ - if (rdp->flags & AR_F_RAID_1 && bp->bio_cmd == BIO_READ) { - if (buf1->bp.bio_pblkno < - (rdp->last_lba[buf1->drive][rdp->last_disk] - 100) || - buf1->bp.bio_pblkno > - (rdp->last_lba[buf1->drive][rdp->last_disk] + 100)) { - rdp->last_disk = 1 - rdp->last_disk; - rdp->last_lba[buf1->drive][rdp->last_disk] = - buf1->bp.bio_pblkno; + switch (rdp->flags & (AR_F_RAID0 | AR_F_RAID1 | AR_F_SPAN)) { + case AR_F_SPAN: + case AR_F_RAID0: + if (!AD_SOFTC(rdp->disks[buf1->drive])->dev->si_disk) { + rdp->disks[buf1->drive].flags = ~(AR_DF_PRESENT | AR_DF_ONLINE); + ata_drawerleds(rdp->disks[buf1->drive].device, ATA_LED_RED); + rdp->flags &= ~AR_F_READY; + printf("ar%d: ERROR broken array in strategy\n", rdp->lun); + bp->bio_flags |= BIO_ERROR; + bp->bio_error = EIO; + biodone(bp); + return; } - if (rdp->last_disk) - buf1->bp.bio_dev = rdp->mirrordisk[buf1->drive]->dev; - else - buf1->bp.bio_dev = rdp->subdisk[buf1->drive]->dev; - } - else - buf1->bp.bio_dev = rdp->subdisk[buf1->drive]->dev; - - if (rdp->flags & AR_F_RAID_1 && bp->bio_cmd == BIO_WRITE) { - buf2 = malloc(sizeof(struct ar_buf), M_AR, M_NOWAIT); - bcopy(buf1, buf2, sizeof(struct ar_buf)); - buf2->bp.bio_dev = rdp->mirrordisk[buf1->drive]->dev; - buf2->mirror = buf1; - buf1->mirror = buf2; - buf2->bp.bio_dev->si_disk->d_devsw->d_strategy((struct bio *)buf2); + buf1->bp.bio_dev = AD_SOFTC(rdp->disks[buf1->drive])->dev; + buf1->bp.bio_dev->AD_STRATEGY((struct bio *)buf1); + break; + + case AR_F_RAID1: + case AR_F_RAID0 | AR_F_RAID1: + if (rdp->flags & AR_F_REBUILDING) { + if ((bp->bio_pblkno >= rdp->lock_start && + bp->bio_pblkno < rdp->lock_end) || + ((bp->bio_pblkno + chunk) >= rdp->lock_start && + (bp->bio_pblkno + chunk) < rdp->lock_end)) { + tsleep(rdp, PRIBIO, "arwait", 0); + } + } + if (rdp->disks[buf1->drive].flags & AR_DF_ONLINE && + !AD_SOFTC(rdp->disks[buf1->drive])->dev->si_disk) { + rdp->disks[buf1->drive].flags = ~(AR_DF_PRESENT | AR_DF_ONLINE); + ata_drawerleds(rdp->disks[buf1->drive].device, ATA_LED_RED); + if (rdp->disks[buf1->drive + rdp->width].flags & AR_DF_ONLINE) { + rdp->flags |= AR_F_DEGRADED; + printf("ar%d: WARNING mirror lost in strategy\n", rdp->lun); + } + else + rdp->flags &= ~AR_F_READY; + } + if (rdp->disks[buf1->drive + rdp->width].flags & AR_DF_ONLINE && + !AD_SOFTC(rdp->disks[buf1->drive + rdp->width])->dev->si_disk) { + rdp->disks[buf1->drive + rdp->width].flags = + ~(AR_DF_PRESENT | AR_DF_ONLINE); + ata_drawerleds(rdp->disks[buf1->drive + rdp->width].device, + ATA_LED_RED); + if (rdp->disks[buf1->drive].flags & AR_DF_ONLINE) { + rdp->flags |= AR_F_DEGRADED; + printf("ar%d: WARNING mirror lost in strategy\n", rdp->lun); + } + else + rdp->flags &= ~AR_F_READY; + } + if (!(rdp->flags & AR_F_READY)) { + printf("ar%d: ERROR broken array in strategy\n", rdp->lun); + bp->bio_flags |= BIO_ERROR; + bp->bio_error = EIO; + biodone(bp); + return; + } + if (bp->bio_cmd == BIO_WRITE) { + if (rdp->disks[buf1->drive + rdp->width].flags & AR_DF_ONLINE) { + if (rdp->disks[buf1->drive].flags & AR_DF_ONLINE) { + buf2 = malloc(sizeof(struct ar_buf), M_AR, M_NOWAIT); + bcopy(buf1, buf2, sizeof(struct ar_buf)); + buf1->mirror = buf2; + buf2->mirror = buf1; + buf2->drive = buf1->drive + rdp->width; + buf2->bp.bio_dev = + AD_SOFTC(rdp->disks[buf2->drive])->dev; + buf2->bp.bio_dev->AD_STRATEGY((struct bio *)buf2); + rdp->disks[buf2->drive].last_lba = + buf1->bp.bio_pblkno + chunk; + } + else + buf1->drive = buf1->drive + rdp->width; + } + } + if (bp->bio_cmd == BIO_READ) { + if ((buf1->bp.bio_pblkno < + (rdp->disks[buf1->drive].last_lba - AR_PROXIMITY) || + buf1->bp.bio_pblkno > + (rdp->disks[buf1->drive].last_lba + AR_PROXIMITY) || + !(rdp->disks[buf1->drive].flags & AR_DF_ONLINE)) && + (rdp->disks[buf1->drive+rdp->width].flags & AR_DF_ONLINE)) + buf1->drive = buf1->drive + rdp->width; + } + buf1->bp.bio_dev = AD_SOFTC(rdp->disks[buf1->drive])->dev; + buf1->bp.bio_dev->AD_STRATEGY((struct bio *)buf1); + rdp->disks[buf1->drive].last_lba = buf1->bp.bio_pblkno + chunk; + break; + default: + printf("DOH!! unknown array type in arstrategy\n"); } - buf1->bp.bio_dev->si_disk->d_devsw->d_strategy((struct bio *)buf1); } } @@ -253,69 +410,116 @@ ar_done(struct bio *bp) s = splbio(); - if (bp->bio_flags & BIO_ERROR) { - if (bp->bio_cmd == BIO_WRITE || buf->done || !(rdp->flags&AR_F_RAID_1)){ + switch (rdp->flags & (AR_F_RAID0 | AR_F_RAID1 | AR_F_SPAN)) { + + case AR_F_SPAN: + case AR_F_RAID0: + if (bp->bio_flags & BIO_ERROR) { + printf("ar%d: ERROR broken array in done\n", rdp->lun); + rdp->disks[buf->drive].flags = ~(AR_DF_PRESENT | AR_DF_ONLINE); + rdp->flags &= ~AR_F_READY; buf->org->bio_flags |= BIO_ERROR; - buf->org->bio_error = bp->bio_error; + buf->org->bio_error = EIO; + biodone(buf->org); + ata_drawerleds(rdp->disks[buf->drive].device, ATA_LED_RED); } - printf("ar%d: subdisk error\n", rdp->lun); - } + else { + buf->org->bio_resid -= buf->bp.bio_bcount; + if (buf->org->bio_resid == 0) + biodone(buf->org); + } + break; - if (rdp->flags & AR_F_RAID_1) { - if (bp->bio_cmd == BIO_WRITE) { - if (!buf->done) { - buf->mirror->done = 1; - goto done; + case AR_F_RAID1: + case AR_F_RAID0 | AR_F_RAID1: + if (bp->bio_flags & BIO_ERROR) { + rdp->disks[buf->drive].flags = ~(AR_DF_PRESENT | AR_DF_ONLINE); + ata_drawerleds(rdp->disks[buf->drive].device, ATA_LED_RED); + if (rdp->flags & AR_F_DEGRADED && + !(rdp->disks[buf->mirror->drive].flags & AR_DF_ONLINE)) { + rdp->flags &= ~AR_F_READY; + printf("ar%d: ERROR broken array in done\n", rdp->lun); + buf->org->bio_flags |= BIO_ERROR; + buf->org->bio_error = EIO; + biodone(buf->org); } - } + else { + rdp->flags |= AR_F_DEGRADED; + printf("ar%d: WARNING mirror lost in done\n", rdp->lun); + if (bp->bio_cmd == BIO_READ) { + if (buf->drive < rdp->width) + buf->drive = buf->drive + rdp->width; + else + buf->drive = buf->drive - rdp->width; + buf->bp.bio_dev = AD_SOFTC(rdp->disks[buf->drive])->dev; + buf->bp.bio_flags = buf->org->bio_flags; + buf->bp.bio_error = 0; + buf->bp.bio_dev->AD_STRATEGY((struct bio *)buf); + splx(s); + return; + } + if (bp->bio_cmd == BIO_WRITE) { + if (!(buf->flags & AB_F_DONE)) + buf->mirror->flags |= AB_F_DONE; + else { + buf->org->bio_resid -= bp->bio_bcount; + if (buf->org->bio_resid == 0) + biodone(buf->org); + } + } + } + } else { - if (!buf->done && bp->bio_flags & BIO_ERROR) { - /* read error on this disk, try mirror */ - buf->done = 1; - buf->bp.bio_dev = rdp->mirrordisk[buf->drive]->dev; - buf->bp.bio_dev->si_disk->d_devsw->d_strategy((struct bio*)buf); - return; + if (bp->bio_cmd == BIO_WRITE) { + if (!(buf->flags & AB_F_DONE) && !(rdp->flags & AR_F_DEGRADED)){ + buf->mirror->flags |= AB_F_DONE; + break; + } } + buf->org->bio_resid -= bp->bio_bcount; + if (buf->org->bio_resid == 0) + biodone(buf->org); } + break; + + default: + printf("Oops! unknown array type in ar_done\n"); } - buf->org->bio_resid -= bp->bio_bcount; - if (buf->org->bio_resid == 0) - biodone(buf->org); -done: free(buf, M_AR); splx(s); } /* read the RAID info from a disk on a HighPoint controller */ static int -ar_highpoint_conf(struct ad_softc *adp, struct ar_softc **raidp) +ar_highpoint_read_conf(struct ad_softc *adp, struct ar_softc **raidp) { struct highpoint_raid_conf *info; - struct ar_softc *raid; - int array, error = 1; + struct ar_softc *raid = NULL; + int array, disk_number = 0, error = 1; if (!(info = (struct highpoint_raid_conf *) malloc(sizeof(struct highpoint_raid_conf), M_AR, M_NOWAIT | M_ZERO))) return error; - if (ar_read(adp, 0x09, DEV_BSIZE, (char *)info)) { + if (ar_read(adp, HPT_LBA, sizeof(struct highpoint_raid_conf), + (u_int8_t *)info)) { if (bootverbose) printf("HighPoint read conf failed\n"); goto highpoint_out; } /* check if this is a HighPoint RAID struct */ - if (info->magic != HPT_MAGIC_OK) { + if (!(info->magic == HPT_MAGIC_OK || info->magic == HPT_MAGIC_BAD)) { if (bootverbose) printf("HighPoint check1 failed\n"); goto highpoint_out; } /* now convert HighPoint config info into our generic form */ - for (array = 0; array < 8; array++) { + for (array = 0; array < MAX_ARRAYS; array++) { if (!raidp[array]) { raidp[array] = - (struct ar_softc*)malloc(sizeof(struct ar_softc),M_AR, + (struct ar_softc*)malloc(sizeof(struct ar_softc), M_AR, M_NOWAIT | M_ZERO); if (!raidp[array]) { printf("ar: failed to allocate raid config storage\n"); @@ -323,69 +527,49 @@ ar_highpoint_conf(struct ad_softc *adp, struct ar_softc **raidp) } } raid = raidp[array]; + if (raid->flags & AR_F_PROMISE_RAID) + continue; + raid->flags = AR_F_HIGHPOINT_RAID; switch (info->type) { - case HPT_T_RAID_0: + case HPT_T_RAID0: /* check the order byte to determine what this really is */ - switch (info->order & (HPT_O_MIRROR | HPT_O_STRIPE)) { - case HPT_O_MIRROR: - goto hpt_mirror; - - case HPT_O_STRIPE: + switch (info->order & HPT_O_RAIDMASK) { + case HPT_O_RAID0: if (raid->magic_0 && raid->magic_0 != info->magic_0) continue; raid->magic_0 = info->magic_0; - raid->flags |= (AR_F_RAID_0 | AR_F_RAID_1); - raid->interleave = 1 << info->raid0_shift; - raid->subdisk[info->disk_number] = adp; - raid->num_subdisks++; - if ((raid->num_subdisks + raid->num_mirrordisks) == - (info->raid_disks * 2)) - raid->flags |= AR_F_CONF_DONE; + raid->flags |= AR_F_RAID0; + raid->interleave = 1 << info->stripe_shift; + disk_number = info->disk_number; break; - case (HPT_O_MIRROR | HPT_O_STRIPE): - if (raid->magic_1 && raid->magic_1 != info->magic_0) + case HPT_O_RAID1: + if (raid->magic_0 && raid->magic_0 != info->magic_0) continue; - raid->magic_1 = info->magic_0; - raid->flags |= (AR_F_RAID_0 | AR_F_RAID_1); - raid->mirrordisk[info->disk_number] = adp; - raid->num_mirrordisks++; - if ((raid->num_subdisks + raid->num_mirrordisks) == - (info->raid_disks * 2)) - raid->flags |= AR_F_CONF_DONE; + raid->magic_0 = info->magic_0; + raid->flags |= AR_F_RAID1; + disk_number = (info->disk_number > 0); break; - - default: + + case HPT_O_RAID01SRC: if (raid->magic_0 && raid->magic_0 != info->magic_0) continue; raid->magic_0 = info->magic_0; - raid->flags |= AR_F_RAID_0; - raid->interleave = 1 << info->raid0_shift; - raid->subdisk[info->disk_number] = adp; - raid->num_subdisks++; - if (raid->num_subdisks == info->raid_disks) - raid->flags |= AR_F_CONF_DONE; - } - break; + raid->flags |= (AR_F_RAID0 | AR_F_RAID1); + raid->interleave = 1 << info->stripe_shift; + disk_number = info->disk_number; + break; - case HPT_T_RAID_1: -hpt_mirror: - if (raid->magic_0 && raid->magic_0 != info->magic_0) - continue; - raid->magic_0 = info->magic_0; - raid->flags |= AR_F_RAID_1; - if (info->disk_number == 0 && raid->num_subdisks == 0) { - raid->subdisk[raid->num_subdisks] = adp; - raid->num_subdisks = 1; - } - if (info->disk_number != 0 && raid->num_mirrordisks == 0) { - raid->mirrordisk[raid->num_mirrordisks] = adp; - raid->num_mirrordisks = 1; + case HPT_O_RAID01DST: + if (raid->magic_1 && raid->magic_1 != info->magic_0) + continue; + raid->magic_1 = info->magic_0; + raid->flags |= (AR_F_RAID0 | AR_F_RAID1); + raid->interleave = 1 << info->stripe_shift; + disk_number = info->disk_number + info->array_width; + break; } - if ((raid->num_subdisks + - raid->num_mirrordisks) == (info->raid_disks * 2)) - raid->flags |= AR_F_CONF_DONE; break; case HPT_T_SPAN: @@ -393,30 +577,37 @@ hpt_mirror: continue; raid->magic_0 = info->magic_0; raid->flags |= AR_F_SPAN; - raid->subdisk[info->disk_number] = adp; - raid->num_subdisks++; - if (raid->num_subdisks == info->raid_disks) - raid->flags |= AR_F_CONF_DONE; + disk_number = info->disk_number; break; default: printf("HighPoint unknown RAID type 0x%02x\n", info->type); + goto highpoint_out; } - /* do we have a complete array to attach to ? */ - if (raid->flags & AR_F_CONF_DONE) { + raid->disks[disk_number].device = adp->device; + if (info->magic == HPT_MAGIC_OK) { + raid->disks[disk_number].flags |= + (AR_DF_PRESENT | AR_DF_ONLINE | AR_DF_ASSIGNED); + raid->flags |= AR_F_READY; raid->lun = array; + raid->width = info->array_width; raid->heads = 255; raid->sectors = 63; - raid->cylinders = (info->total_secs - 9) / (63 * 255); - raid->total_secs = info->total_secs - (9 * raid->num_subdisks); + raid->cylinders = (info->total_sectors - 9) / (63 * 255); + raid->total_sectors = info->total_sectors - (9 * raid->width); raid->offset = 10; raid->reserved = 10; - ar_attach(raid); } + else { + raid->disks[disk_number].flags &= ~ AR_DF_ONLINE; + raid->disks[disk_number].flags |= (AR_DF_PRESENT | AR_DF_ASSIGNED); + } + if (disk_number >= raid->total_disks) + raid->total_disks = disk_number + 1; error = 0; + break; } - highpoint_out: free(info, M_AR); return error; @@ -424,22 +615,19 @@ highpoint_out: /* read the RAID info from a disk on a Promise Fasttrak controller */ static int -ar_promise_conf(struct ad_softc *adp, struct ar_softc **raidp) +ar_promise_read_conf(struct ad_softc *adp, struct ar_softc **raidp) { struct promise_raid_conf *info; struct ar_softc *raid; - u_int32_t lba, magic; - u_int32_t cksum, *ckptr; - int count, disk_number, array, error = 1; + u_int32_t magic, cksum, *ckptr; + int array, count, disk, error = 1; if (!(info = (struct promise_raid_conf *) malloc(sizeof(struct promise_raid_conf), M_AR, M_NOWAIT | M_ZERO))) return error; - lba = ((adp->total_secs / (adp->heads * adp->sectors)) * - adp->heads * adp->sectors) - adp->sectors; - - if (ar_read(adp, lba, 4 * DEV_BSIZE, (char *)info)) { + if (ar_read(adp, PR_LBA(adp), sizeof(struct promise_raid_conf), + (u_int8_t *)info)) { if (bootverbose) printf("Promise read conf failed\n"); goto promise_out; @@ -450,116 +638,136 @@ ar_promise_conf(struct ad_softc *adp, struct ar_softc **raidp) if (bootverbose) printf("Promise check1 failed\n"); goto promise_out; - } + } /* check if the checksum is OK */ for (cksum = 0, ckptr = (int32_t *)info, count = 0; count < 511; count++) cksum += *ckptr++; if (cksum != *ckptr) { if (bootverbose) - printf("Promise check2 failed\n"); + printf("Promise check2 failed\n"); goto promise_out; } /* now convert Promise config info into our generic form */ - if ((info->raid.flags != PR_F_READY) || - (((info->raid.status & (PR_S_DEFINED|PR_S_ONLINE)) != - (PR_S_DEFINED|PR_S_ONLINE)))) { + if ((info->raid.integrity != PR_I_VALID) || + (((info->raid.status & (PR_S_VALID | PR_S_ONLINE)) != + (PR_S_VALID | PR_S_ONLINE)))) { if (bootverbose) - printf("Promise check3 failed\n"); + printf("Promise check3 failed\n"); goto promise_out; } - magic = (adp->controller->chiptype >> 16) | info->raid.array_number << 16; - - array = info->raid.array_number; - if (raidp[array]) { - if (magic != raidp[array]->magic_0) { - if (bootverbose) - printf("Promise check4 failed\n"); - goto promise_out; - } - } - else { - if (!(raidp[array] = (struct ar_softc *) - malloc(sizeof(struct ar_softc), M_AR, M_NOWAIT))) { - printf("ar: failed to allocate raid config storage\n"); - goto promise_out; + for (array = 0; array < MAX_ARRAYS; array++) { + if (!raidp[array]) { + raidp[array] = + (struct ar_softc*)malloc(sizeof(struct ar_softc), M_AR, + M_NOWAIT | M_ZERO); + if (!raidp[array]) { + printf("ar: failed to allocate raid config storage\n"); + goto promise_out; + } } - else - bzero(raidp[array], sizeof(struct ar_softc)); - } - raid = raidp[array]; - raid->magic_0 = magic; + raid = raidp[array]; + if (raid->flags & AR_F_HIGHPOINT_RAID) + continue; - switch (info->raid.type) { - case PR_T_STRIPE: - raid->flags |= AR_F_RAID_0; - raid->interleave = 1 << info->raid.raid0_shift; - break; + magic = (adp->device->channel->chiptype >> 16) | + (info->raid.array_number << 16); - case PR_T_MIRROR: - raid->flags |= AR_F_RAID_1; - break; + if (raid->flags & AR_F_PROMISE_RAID && magic != raid->magic_0) + continue; - case PR_T_SPAN: - raid->flags |= AR_F_SPAN; - break; + /* update our knowledge about the array config based on generation */ + if (info->raid.generation >= raid->generation) { + raid->flags = AR_F_PROMISE_RAID; + raid->magic_0 = magic; + raid->lun = array; + if ((info->raid.status & + (PR_S_VALID | PR_S_ONLINE | PR_S_INITED | PR_S_READY)) == + (PR_S_VALID | PR_S_ONLINE | PR_S_INITED | PR_S_READY)) { + raid->flags |= AR_F_READY; + if (info->raid.status & PR_S_DEGRADED) + raid->flags |= AR_F_DEGRADED; + } + else + raid->flags &= ~AR_F_READY; - default: - printf("Promise unknown RAID type 0x%02x\n", info->raid.type); - goto promise_out; - } + switch (info->raid.type) { + case PR_T_RAID0: + raid->flags |= AR_F_RAID0; + break; + + case PR_T_RAID1: + raid->flags |= AR_F_RAID1; + if (info->raid.array_width > 1) + raid->flags |= AR_F_RAID0; + break; - /* find out where this disk is in the defined array */ - disk_number = info->raid.disk_number; - if (disk_number < info->raid.raid0_disks) { - raid->subdisk[disk_number] = adp; - raid->num_subdisks++; - if (raid->num_subdisks > 1 && !(raid->flags & AR_F_SPAN)) { - raid->flags |= AR_F_RAID_0; - raid->interleave = 1 << info->raid.raid0_shift; + case PR_T_SPAN: + raid->flags |= AR_F_SPAN; + break; + + default: + printf("Promise unknown RAID type 0x%02x\n", info->raid.type); + goto promise_out; + } + raid->interleave = 1 << info->raid.stripe_shift; + raid->width = info->raid.array_width; + raid->total_disks = info->raid.total_disks; + raid->heads = info->raid.heads + 1; + raid->sectors = info->raid.sectors; + raid->cylinders = info->raid.cylinders + 1; + raid->total_sectors = info->raid.total_sectors; + raid->offset = 0; + raid->reserved = 63; + + /* convert disk flags to our internal types */ + for (disk = 0; disk < info->raid.total_disks; disk++) { + raid->disks[disk].flags = 0; + if (adp->device) { + if (info->raid.disk[disk].flags & PR_F_VALID) + raid->disks[disk].flags |= AR_DF_PRESENT; + if (info->raid.disk[disk].flags & PR_F_ONLINE) + raid->disks[disk].flags |= AR_DF_ONLINE; + if (info->raid.disk[disk].flags & PR_F_ASSIGNED) + raid->disks[disk].flags |= AR_DF_ASSIGNED; + if (info->raid.disk[disk].flags & PR_F_SPARE) + raid->disks[disk].flags |= AR_DF_SPARE; + if (info->raid.disk[disk].flags & (PR_F_REDIR | PR_F_DOWN)) + raid->disks[disk].flags &= ~AR_DF_ONLINE; + if (info->raid.disk[disk].flags & PR_F_READY) + raid->disks[disk].flags |= AR_DF_PRESENT; + } + } } - } - else { - raid->mirrordisk[disk_number - info->raid.raid0_disks] = adp; - raid->num_mirrordisks++; - } - /* do we have a complete array to attach to ? */ - if (raid->num_subdisks + raid->num_mirrordisks == info->raid.total_disks) { - raid->flags |= AR_F_CONF_DONE; - raid->lun = array; - raid->heads = info->raid.heads + 1; - raid->sectors = info->raid.sectors; - raid->cylinders = info->raid.cylinders + 1; - raid->total_secs = info->raid.total_secs; - raid->offset = 0; - raid->reserved = 63; - ar_attach(raid); + raid->disks[info->raid.disk_number].device = adp->device; + error = 0; + break; } - error = 0; promise_out: free(info, M_AR); return error; } -int -ar_read(struct ad_softc *adp, u_int32_t lba, int count, char *data) +static int +ar_read(struct ad_softc *adp, u_int32_t lba, int count, u_int8_t *data) { - if (ata_command(adp->controller, adp->unit | ATA_D_LBA, - (count > DEV_BSIZE) ? ATA_C_READ_MUL : ATA_C_READ, + if (ata_command(adp->device, count > DEV_BSIZE ? ATA_C_READ_MUL:ATA_C_READ, lba, count / DEV_BSIZE, 0, ATA_WAIT_INTR)) { - ata_printf(adp->controller, adp->unit, "RAID read config failed\n"); + ata_printf(adp->device->channel, adp->device->unit, + "RAID read config failed\n"); return 1; } - if (ata_wait(adp->controller, adp->unit, ATA_S_READY|ATA_S_DSC|ATA_S_DRQ)) { - ata_printf(adp->controller, adp->unit, "RAID read config timeout\n"); + if (ata_wait(adp->device, ATA_S_READY|ATA_S_DSC|ATA_S_DRQ)){ + ata_printf(adp->device->channel, adp->device->unit, + "RAID read config timeout\n"); return 1; } - ATA_INSW(adp->controller->r_io, ATA_DATA, (int16_t *)data, + ATA_INSW(adp->device->channel->r_io, ATA_DATA, (int16_t *)data, count/sizeof(int16_t)); - ATA_INB(adp->controller->r_io, ATA_STATUS); + ATA_INB(adp->device->channel->r_io, ATA_STATUS); return 0; } diff --git a/sys/dev/ata/ata-raid.h b/sys/dev/ata/ata-raid.h index c5a242e..acc3eb0 100644 --- a/sys/dev/ata/ata-raid.h +++ b/sys/dev/ata/ata-raid.h @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2000,2001 Søren Schmidt <sos@FreeBSD.org> + * Copyright (c) 2000,2001,2002 Søren Schmidt <sos@FreeBSD.org> * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -28,44 +28,62 @@ * $FreeBSD$ */ +struct ar_disk { + struct ata_device *device; + off_t last_lba; /* last lba used */ + int flags; +#define AR_DF_PRESENT 0x00000001 +#define AR_DF_ASSIGNED 0x00000002 +#define AR_DF_SPARE 0x00000004 +#define AR_DF_ONLINE 0x00000008 +}; + +#define MAX_ARRAYS 16 +#define MAX_DISKS 16 +#define AR_PROXIMITY 2048 + struct ar_softc { - int lun; - int32_t magic_0; - int32_t magic_1; - int flags; -#define AR_F_RAID_0 0x0001 /* STRIPE */ -#define AR_F_RAID_1 0x0002 /* MIRROR */ -#define AR_F_SPAN 0x0004 /* SPAN */ -#define AR_F_CONF_DONE 0x0008 + int lun; + int32_t magic_0; /* ident for this array */ + int32_t magic_1; /* ident for this array */ + int flags; +#define AR_F_RAID0 0x0001 /* STRIPE */ +#define AR_F_RAID1 0x0002 /* MIRROR */ +#define AR_F_SPAN 0x0004 /* SPAN */ +#define AR_F_READY 0x0100 +#define AR_F_DEGRADED 0x0200 +#define AR_F_REBUILDING 0x0400 +#define AR_F_PROMISE_RAID 0x1000 +#define AR_F_HIGHPOINT_RAID 0x2000 - int num_subdisks; - struct ad_softc *subdisk[8]; - int num_mirrordisks; - struct ad_softc *mirrordisk[8]; - int interleave; - int last_disk; - int32_t last_lba[8][2]; - - u_int16_t heads; - u_int16_t sectors; - u_int32_t cylinders; - u_int32_t total_secs; - int reserved; /* sectors that are NOT to be used */ - int offset; /* offset from start of disk */ - - struct disk disk; /* disklabel/slice stuff */ - dev_t dev; /* device place holder */ - + int total_disks; /* number of disks in this array */ + int generation; /* generation of this array */ + struct ar_disk disks[MAX_DISKS]; /* ptr to each disk in array */ + int width; /* array width in disks */ + u_int16_t heads; + u_int16_t sectors; + u_int32_t cylinders; + u_int64_t total_sectors; + int interleave; /* interleave in bytes */ + int reserved; /* sectors that are NOT to be used */ + int offset; /* offset from start of disk */ + u_int64_t lock_start; /* start of locked area for rebuild */ + u_int64_t lock_end; /* end of locked area for rebuild */ + struct disk disk; /* disklabel/slice stuff */ + dev_t dev; /* device place holder */ }; struct ar_buf { - struct bio bp; - struct bio *org; - int drive; - struct ar_buf *mirror; - int done; + struct bio bp; + struct bio *org; + struct ar_buf *mirror; + int drive; + int flags; +#define AB_F_DONE 0x01 }; +#define HPT_LBA 9 + struct highpoint_raid_conf { int8_t filler1[32]; u_int32_t magic; /* 0x20 */ @@ -75,24 +93,27 @@ struct highpoint_raid_conf { u_int32_t magic_0; u_int32_t magic_1; u_int32_t order; -#define HPT_O_MIRROR 0x01 -#define HPT_O_STRIPE 0x02 +#define HPT_O_RAID0 0x00 +#define HPT_O_RAID1 0x01 +#define HPT_O_RAID01DST 0x02 +#define HPT_O_RAID01SRC 0x03 +#define HPT_O_RAIDMASK 0x03 #define HPT_O_OK 0x04 - u_int8_t raid_disks; - u_int8_t raid0_shift; + u_int8_t array_width; + u_int8_t stripe_shift; u_int8_t type; -#define HPT_T_RAID_0 0x00 -#define HPT_T_RAID_1 0x01 -#define HPT_T_RAID_01_RAID_0 0x02 +#define HPT_T_RAID0 0x00 +#define HPT_T_RAID1 0x01 +#define HPT_T_RAID01_RAID0 0x02 #define HPT_T_SPAN 0x03 #define HPT_T_RAID_3 0x04 #define HPT_T_RAID_5 0x05 #define HPT_T_SINGLEDISK 0x06 -#define HPT_T_RAID_01_RAID_1 0x07 +#define HPT_T_RAID01_RAID1 0x07 u_int8_t disk_number; - u_int32_t total_secs; + u_int32_t total_sectors; u_int32_t disk_mode; u_int32_t boot_mode; u_int8_t boot_disk; @@ -102,8 +123,8 @@ struct highpoint_raid_conf { struct { u_int32_t timestamp; u_int8_t reason; -#define HPT_R_REMOVED 0xfe -#define HPT_R_BROKEN 0xff +#define HPT_R_REMOVED 0xfe +#define HPT_R_BROKEN 0xff u_int8_t disk; u_int8_t status; @@ -113,62 +134,77 @@ struct highpoint_raid_conf { int8_t filler2[60]; } __attribute__((packed)); +#define PR_LBA(adp) \ + (((adp->total_secs / (adp->heads * adp->sectors)) * \ + adp->heads * adp->sectors) - adp->sectors) + struct promise_raid_conf { char promise_id[24]; #define PR_MAGIC "Promise Technology, Inc." - int32_t dummy_0; - int8_t magic_0[8]; - int16_t magic_1; - int32_t magic_2; - int8_t filler1[470]; + u_int32_t dummy_0; + u_int8_t magic_0[8]; + u_int16_t magic_1; + u_int32_t magic_2; + u_int8_t filler1[470]; struct { - int32_t flags; /* 0x200 */ -#define PR_F_READY 0x00000080 -#define PR_F_SPARE 0x00000040 -#define PR_F_DOWN 0x00000020 + u_int32_t integrity; /* 0x200 */ +#define PR_I_VALID 0x00000080 + + u_int8_t flags; #define PR_F_VALID 0x00000001 +#define PR_F_ONLINE 0x00000002 +#define PR_F_ASSIGNED 0x00000004 +#define PR_F_SPARE 0x00000008 +#define PR_F_DUPLICATE 0x00000010 +#define PR_F_REDIR 0x00000020 +#define PR_F_DOWN 0x00000040 +#define PR_F_READY 0x00000080 - int8_t dummy_0; - int8_t disk_number; - int8_t channel; - int8_t device; - int8_t magic_0[8]; - int32_t disk_offset; /* 0x210 */ - int32_t disk_secs; - int32_t dummy_1; - int16_t dummy_2; - int8_t status; -#define PR_S_DEFINED 0x01 -#define PR_S_ONLINE 0x02 -#define PR_S_OFFLINE 0x10 - - int8_t type; -#define PR_T_STRIPE 0x00 -#define PR_T_MIRROR 0x01 -#define PR_T_STRIPE_MIRROR 0x04 -#define PR_T_SPAN 0x08 + u_int8_t disk_number; + u_int8_t channel; + u_int8_t device; + u_int8_t magic_0[8]; + u_int32_t disk_offset; /* 0x210 */ + u_int32_t disk_sectors; + u_int32_t dummy_1; + u_int16_t generation; + u_int8_t status; +#define PR_S_VALID 0x01 +#define PR_S_ONLINE 0x02 +#define PR_S_INITED 0x04 +#define PR_S_READY 0x08 +#define PR_S_DEGRADED 0x10 +#define PR_S_MARKED 0x20 + + u_int8_t type; +#define PR_T_RAID0 0x00 +#define PR_T_RAID1 0x01 +#define PR_T_RAID3 0x02 +#define PR_T_RAID5 0x04 +#define PR_T_SPAN 0x08 u_int8_t total_disks; /* 0x220 */ - u_int8_t raid0_shift; - u_int8_t raid0_disks; + u_int8_t stripe_shift; + u_int8_t array_width; u_int8_t array_number; - u_int32_t total_secs; + u_int32_t total_sectors; u_int16_t cylinders; u_int8_t heads; u_int8_t sectors; int8_t magic_1[8]; - struct { - int8_t flags; - int8_t dummy_0; - int8_t channel; - int8_t device; - int8_t magic_0[8]; + struct { /* 0x240 */ + u_int8_t flags; + u_int8_t dummy_0; + u_int8_t channel; + u_int8_t device; + u_int8_t magic_0[8]; } disk[8]; } raid; int32_t filler2[346]; - uint32_t checksum; + u_int32_t checksum; } __attribute__((packed)); int ar_probe(struct ad_softc *); +void ar_attach(void); diff --git a/sys/dev/ata/atapi-all.c b/sys/dev/ata/atapi-all.c index 813e371..aab4082 100644 --- a/sys/dev/ata/atapi-all.c +++ b/sys/dev/ata/atapi-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 @@ -52,125 +52,117 @@ static char *atapi_type(int); static char *atapi_cmd2str(u_int8_t); static char *atapi_skey2str(u_int8_t); +/* misc defines */ +#define ATAPI_MAX_RETRIES 3 + /* internal vars */ -static MALLOC_DEFINE(M_ATAPI, "ATAPI generic", "ATAPI driver generic layer"); static int atapi_dma = 0; TUNABLE_INT("hw.ata.atapi_dma", &atapi_dma); +static MALLOC_DEFINE(M_ATAPI, "ATAPI generic", "ATAPI driver generic layer"); /* systcl vars */ SYSCTL_DECL(_hw_ata); SYSCTL_INT(_hw_ata, OID_AUTO, atapi_dma, CTLFLAG_RD, &atapi_dma, 0, "ATAPI device DMA mode control"); -/* defines */ -#define ATAPI_MAX_RETRIES 3 -#define ATP_PARAM ATA_PARAM(atp->controller, atp->unit) - void -atapi_attach(struct ata_softc *scp, int device) +atapi_attach(struct ata_device *atadev) { - struct atapi_softc *atp; - - if (!(atp = malloc(sizeof(struct atapi_softc), M_ATAPI, M_NOWAIT|M_ZERO))) { - ata_printf(scp, device, "failed to allocate driver storage\n"); - return; - } - atp->controller = scp; - atp->unit = device; if (bootverbose) - ata_printf(scp, device, - "piomode=%d dmamode=%d udmamode=%d dmaflag=%d\n", - ata_pmode(ATP_PARAM), ata_wmode(ATP_PARAM), - ata_umode(ATP_PARAM), ATP_PARAM->support_dma); - - if (atapi_dma && !(ATP_PARAM->drq_type == ATAPI_DRQT_INTR)) { - ata_dmainit(atp->controller, atp->unit, - (ata_pmode(ATP_PARAM) < 0) ? - (ATP_PARAM->support_dma ? 4 : 0) : ata_pmode(ATP_PARAM), - (ata_wmode(ATP_PARAM) < 0) ? - (ATP_PARAM->support_dma ? 2 : 0) : ata_wmode(ATP_PARAM), - ata_umode(ATP_PARAM)); + ata_prtdev(atadev, "piomode=%d dmamode=%d udmamode=%d dmaflag=%d\n", + ata_pmode(atadev->param), ata_wmode(atadev->param), + ata_umode(atadev->param), atadev->param->support_dma); + + if (atapi_dma && !(atadev->param->drq_type == ATAPI_DRQT_INTR)) { + ata_dmainit(atadev->channel, atadev->unit, + (ata_pmode(atadev->param) < 0) ? + (atadev->param->support_dma ? 4:0):ata_pmode(atadev->param), + (ata_wmode(atadev->param) < 0) ? + (atadev->param->support_dma ? 2:0):ata_wmode(atadev->param), + ata_umode(atadev->param)); } else - ata_dmainit(atp->controller, atp->unit, - ata_pmode(ATP_PARAM) < 0 ? 0 : ata_pmode(ATP_PARAM), -1,-1); + ata_dmainit(atadev->channel, atadev->unit, + ata_pmode(atadev->param) < 0 ? 0 : ata_pmode(atadev->param), + -1, -1); + + if (!(atadev->result = malloc(sizeof(struct atapi_reqsense), M_ATAPI, + M_NOWAIT | M_ZERO))) + ata_prtdev(atadev, "no memory for sense data\n"); - switch (ATP_PARAM->type) { + switch (atadev->param->type) { #ifdef DEV_ATAPICD case ATAPI_TYPE_CDROM: - if (acdattach(atp)) + if (acdattach(atadev)) goto notfound; break; #endif #ifdef DEV_ATAPIFD case ATAPI_TYPE_DIRECT: - if (afdattach(atp)) + if (afdattach(atadev)) goto notfound; break; #endif #ifdef DEV_ATAPIST case ATAPI_TYPE_TAPE: - if (astattach(atp)) + if (astattach(atadev)) goto notfound; break; #endif notfound: default: - ata_printf(scp, device, "<%.40s/%.8s> %s device - NO DRIVER!\n", - ATP_PARAM->model, ATP_PARAM->revision, - atapi_type(ATP_PARAM->type)); - free(atp, M_ATAPI); - atp = NULL; + ata_prtdev(atadev, "<%.40s/%.8s> %s device - NO DRIVER!\n", + atadev->param->model, atadev->param->revision, + atapi_type(atadev->param->type)); + free(atadev->result, M_ATAPI); + atadev->driver = NULL; } - - /* store our softc signalling we are ready to go */ - scp->dev_softc[ATA_DEV(device)] = atp; } void -atapi_detach(struct atapi_softc *atp) +atapi_detach(struct ata_device *atadev) { struct atapi_request *request; - atp->flags |= ATAPI_F_DETACHING; - ata_printf(atp->controller, atp->unit, "removed from configuration\n"); - switch (ATP_PARAM->type) { + atadev->flags |= ATA_D_DETACHING; + ata_prtdev(atadev, "removed from configuration\n"); + switch (atadev->param->type) { #ifdef DEV_ATAPICD case ATAPI_TYPE_CDROM: - acddetach(atp); + acddetach(atadev); break; #endif #ifdef DEV_ATAPIFD case ATAPI_TYPE_DIRECT: - afddetach(atp); + afddetach(atadev); break; #endif #ifdef DEV_ATAPIST case ATAPI_TYPE_TAPE: - astdetach(atp); + astdetach(atadev); break; #endif default: return; } - TAILQ_FOREACH(request, &atp->controller->atapi_queue, chain) { - if (request->device != atp) + TAILQ_FOREACH(request, &atadev->channel->atapi_queue, chain) { + if (request->device != atadev) continue; - TAILQ_REMOVE(&atp->controller->atapi_queue, request, chain); + TAILQ_REMOVE(&atadev->channel->atapi_queue, request, chain); if (request->driver) { struct bio *bp = (struct bio *) request->driver; biofinish(bp, NULL, ENXIO); } if (request->dmatab) free(request->dmatab, M_DEVBUF); - free(request, M_ATAPI); + free(request, M_ATAPI); } - atp->controller->dev_softc[ATA_DEV(atp->unit)] = NULL; - free(atp, M_ATAPI); + free(atadev->result, M_ATAPI); + atadev->driver = NULL; /* XXX SOS safetybelt */ } int -atapi_queue_cmd(struct atapi_softc *atp, int8_t *ccb, caddr_t data, +atapi_queue_cmd(struct ata_device *atadev, int8_t *ccb, caddr_t data, int count, int flags, int timeout, atapi_callback_t callback, void *driver) { @@ -181,35 +173,34 @@ atapi_queue_cmd(struct atapi_softc *atp, int8_t *ccb, caddr_t data, M_NOWAIT | M_ZERO))) return ENOMEM; - request->device = atp; + request->device = atadev; request->data = data; request->bytecount = count; request->flags = flags; request->timeout = timeout * hz; - request->ccbsize = (ATP_PARAM->packet_size) ? 16 : 12; + request->ccbsize = atadev->param->packet_size ? 16 : 12; bcopy(ccb, request->ccb, request->ccbsize); if (callback) { request->callback = callback; request->driver = driver; } - if (atp->controller->mode[ATA_DEV(atp->unit)] >= ATA_DMA) { - if (!(request->dmatab = ata_dmaalloc(atp->controller, atp->unit))) - atp->controller->mode[ATA_DEV(atp->unit)] = ATA_PIO; + if (atadev->mode >= ATA_DMA) { + if (!(request->dmatab = ata_dmaalloc(atadev->channel, atadev->unit))) + atadev->mode = ATA_PIO; } s = splbio(); /* append onto controller queue and try to start controller */ #ifdef ATAPI_DEBUG - ata_printf(atp->controller, atp->unit, "queueing %s ", - atapi_cmd2str(request->ccb[0])); + ata_prtdev(atadev, "queueing %s ", atapi_cmd2str(request->ccb[0])); atapi_dump("ccb = ", &request->ccb[0], sizeof(request->ccb)); #endif if (flags & ATPR_F_AT_HEAD) - TAILQ_INSERT_HEAD(&atp->controller->atapi_queue, request, chain); + TAILQ_INSERT_HEAD(&atadev->channel->atapi_queue, request, chain); else - TAILQ_INSERT_TAIL(&atp->controller->atapi_queue, request, chain); - ata_start(atp->controller); + TAILQ_INSERT_TAIL(&atadev->channel->atapi_queue, request, chain); + ata_start(atadev->channel); /* if callback used, then just return, gets called from interrupt context */ if (callback) { @@ -222,7 +213,7 @@ atapi_queue_cmd(struct atapi_softc *atp, int8_t *ccb, caddr_t data, splx(s); error = request->error; if (error) - atp->sense = request->sense; + bcopy(&request->sense, atadev->result, sizeof(struct atapi_reqsense)); if (request->dmatab) free(request->dmatab, M_DEVBUF); free(request, M_ATAPI); @@ -230,22 +221,22 @@ atapi_queue_cmd(struct atapi_softc *atp, int8_t *ccb, caddr_t data, } void -atapi_start(struct atapi_softc *atp) +atapi_start(struct ata_device *atadev) { - switch (ATP_PARAM->type) { + switch (atadev->param->type) { #ifdef DEV_ATAPICD case ATAPI_TYPE_CDROM: - acd_start(atp); + acd_start(atadev); break; #endif #ifdef DEV_ATAPIFD case ATAPI_TYPE_DIRECT: - afd_start(atp); + afd_start(atadev); break; #endif #ifdef DEV_ATAPIST case ATAPI_TYPE_TAPE: - ast_start(atp); + ast_start(atadev); break; #endif default: @@ -256,20 +247,19 @@ atapi_start(struct atapi_softc *atp) int atapi_transfer(struct atapi_request *request) { - struct atapi_softc *atp = request->device; + struct ata_device *atadev = request->device; int timout; u_int8_t reason; #ifdef ATAPI_DEBUG - ata_printf(atp->controller, atp->unit, "starting %s ", - atapi_cmd2str(request->ccb[0])); + ata_prtdev(atadev, "starting %s ", atapi_cmd2str(request->ccb[0])); atapi_dump("ccb = ", &request->ccb[0], sizeof(request->ccb)); #endif /* is this just a POLL DSC command ? */ if (request->ccb[0] == ATAPI_POLL_DSC) { - ATA_OUTB(atp->controller->r_io, ATA_DRIVE, ATA_D_IBM | atp->unit); + ATA_OUTB(atadev->channel->r_io, ATA_DRIVE, ATA_D_IBM | atadev->unit); DELAY(10); - if (ATA_INB(atp->controller->r_altio, ATA_ALTSTAT) & ATA_S_DSC) + if (ATA_INB(atadev->channel->r_altio, ATA_ALTSTAT) & ATA_S_DSC) request->error = 0; else request->error = EBUSY; @@ -282,53 +272,49 @@ atapi_transfer(struct atapi_request *request) request, request->timeout); if (!(request->flags & ATPR_F_INTERNAL)) - atp->cmd = request->ccb[0]; + atadev->cmd = request->ccb[0]; /* if DMA enabled setup DMA hardware */ request->flags &= ~ATPR_F_DMA_USED; - if ((atp->controller->mode[ATA_DEV(atp->unit)] >= ATA_DMA) && - (request->ccb[0] == ATAPI_READ || - request->ccb[0] == ATAPI_READ_BIG || + if ((atadev->mode >= ATA_DMA) && + (request->ccb[0] == ATAPI_READ || request->ccb[0] == ATAPI_READ_BIG || ((request->ccb[0] == ATAPI_WRITE || request->ccb[0] == ATAPI_WRITE_BIG) && - !(atp->controller->flags & ATA_ATAPI_DMA_RO))) && - !ata_dmasetup(atp->controller, atp->unit, request->dmatab, + !(atadev->channel->flags & ATA_ATAPI_DMA_RO))) && + !ata_dmasetup(atadev->channel, atadev->unit, request->dmatab, (void *)request->data, request->bytecount)) { request->flags |= ATPR_F_DMA_USED; } /* start ATAPI operation */ - if (ata_command(atp->controller, atp->unit, ATA_C_PACKET_CMD, - (request->bytecount << 8), 0, + if (ata_command(atadev, ATA_C_PACKET_CMD, (request->bytecount << 8), 0, (request->flags & ATPR_F_DMA_USED) ? ATA_F_DMA : 0, ATA_IMMEDIATE)) - ata_printf(atp->controller, atp->unit, - "failure to send ATAPI packet command\n"); + ata_prtdev(atadev, "failure to send ATAPI packet command\n"); if (request->flags & ATPR_F_DMA_USED) - ata_dmastart(atp->controller, atp->unit, + ata_dmastart(atadev->channel, atadev->unit, request->dmatab, request->flags & ATPR_F_READ); /* command interrupt device ? just return */ - if (ATP_PARAM->drq_type == ATAPI_DRQT_INTR) + if (atadev->param->drq_type == ATAPI_DRQT_INTR) return ATA_OP_CONTINUES; /* ready to write ATAPI command */ timout = 5000; /* might be less for fast devices */ while (timout--) { - reason = ATA_INB(atp->controller->r_io, ATA_IREASON); - atp->controller->status = ATA_INB(atp->controller->r_io, ATA_STATUS); + reason = ATA_INB(atadev->channel->r_io, ATA_IREASON); + atadev->channel->status = ATA_INB(atadev->channel->r_io, ATA_STATUS); if (((reason & (ATA_I_CMD | ATA_I_IN)) | - (atp->controller->status&(ATA_S_DRQ|ATA_S_BUSY)))==ATAPI_P_CMDOUT) + (atadev->channel->status&(ATA_S_DRQ|ATA_S_BUSY)))==ATAPI_P_CMDOUT) break; DELAY(20); } if (timout <= 0) { - ata_printf(atp->controller, atp->unit, - "failure to execute ATAPI packet command\n"); + ata_prtdev(atadev, "failure to execute ATAPI packet command\n"); untimeout((timeout_t *)atapi_timeout, request, request->timeout_handle); request->error = EIO; - atapi_finish(request); + atapi_finish(request); return ATA_OP_FINISHED; } @@ -336,7 +322,7 @@ atapi_transfer(struct atapi_request *request) DELAY(10); /* send actual command */ - ATA_OUTSW(atp->controller->r_io, ATA_DATA, (int16_t *)request->ccb, + ATA_OUTSW(atadev->channel->r_io, ATA_DATA, (int16_t *)request->ccb, request->ccbsize / sizeof(int16_t)); return ATA_OP_CONTINUES; } @@ -344,32 +330,31 @@ atapi_transfer(struct atapi_request *request) int atapi_interrupt(struct atapi_request *request) { - struct atapi_softc *atp = request->device; + struct ata_device *atadev = request->device; int reason, dma_stat = 0; - reason = (ATA_INB(atp->controller->r_io, ATA_IREASON)&(ATA_I_CMD|ATA_I_IN))| - (atp->controller->status & ATA_S_DRQ); + reason = (ATA_INB(atadev->channel->r_io, ATA_IREASON)&(ATA_I_CMD|ATA_I_IN))| + (atadev->channel->status & ATA_S_DRQ); if (reason == ATAPI_P_CMDOUT) { - if (!(atp->controller->status & ATA_S_DRQ)) { - ata_printf(atp->controller, atp->unit, - "command interrupt without DRQ\n"); + if (!(atadev->channel->status & ATA_S_DRQ)) { + ata_prtdev(atadev, "command interrupt without DRQ\n"); untimeout((timeout_t *)atapi_timeout, request, request->timeout_handle); request->error = EIO; - atapi_finish(request); + atapi_finish(request); return ATA_OP_FINISHED; } - ATA_OUTSW(atp->controller->r_io, ATA_DATA, (int16_t *)request->ccb, + ATA_OUTSW(atadev->channel->r_io, ATA_DATA, (int16_t *)request->ccb, request->ccbsize / sizeof(int16_t)); return ATA_OP_CONTINUES; } if (request->flags & ATPR_F_DMA_USED) { - dma_stat = ata_dmadone(atp->controller); - if ((atp->controller->status & (ATA_S_ERROR | ATA_S_DWF)) || + dma_stat = ata_dmadone(atadev->channel); + if ((atadev->channel->status & (ATA_S_ERROR | ATA_S_DWF)) || dma_stat & ATA_BMSTAT_ERROR) { - request->result = ATA_INB(atp->controller->r_io, ATA_ERROR); + request->result = ATA_INB(atadev->channel->r_io, ATA_ERROR); } else { request->result = 0; @@ -378,16 +363,15 @@ atapi_interrupt(struct atapi_request *request) } } else { - int length = ATA_INB(atp->controller->r_io, ATA_CYL_LSB) | - ATA_INB(atp->controller->r_io, ATA_CYL_MSB) << 8; + int length = ATA_INB(atadev->channel->r_io, ATA_CYL_LSB) | + ATA_INB(atadev->channel->r_io, ATA_CYL_MSB) << 8; switch (reason) { case ATAPI_P_WRITE: if (request->flags & ATPR_F_READ) { - request->result = ATA_INB(atp->controller->r_io, ATA_ERROR); - ata_printf(atp->controller, atp->unit, - "%s trying to write on read buffer\n", - atapi_cmd2str(atp->cmd)); + request->result = ATA_INB(atadev->channel->r_io, ATA_ERROR); + ata_prtdev(atadev, "%s trying to write on read buffer\n", + atapi_cmd2str(atadev->cmd)); break; } atapi_write(request, length); @@ -395,18 +379,16 @@ atapi_interrupt(struct atapi_request *request) case ATAPI_P_READ: if (!(request->flags & ATPR_F_READ)) { - request->result = ATA_INB(atp->controller->r_io, ATA_ERROR); - ata_printf(atp->controller, atp->unit, - "%s trying to read on write buffer\n", - atapi_cmd2str(atp->cmd)); + request->result = ATA_INB(atadev->channel->r_io, ATA_ERROR); + ata_prtdev(atadev, "%s trying to read on write buffer\n", + atapi_cmd2str(atadev->cmd)); break; } atapi_read(request, length); return ATA_OP_CONTINUES; case ATAPI_P_DONEDRQ: - ata_printf(atp->controller, atp->unit, "%s DONEDRQ\n", - atapi_cmd2str(atp->cmd)); + ata_prtdev(atadev, "%s DONEDRQ\n", atapi_cmd2str(atadev->cmd)); if (request->flags & ATPR_F_READ) atapi_read(request, length); else @@ -415,16 +397,15 @@ atapi_interrupt(struct atapi_request *request) case ATAPI_P_ABORT: case ATAPI_P_DONE: - if (atp->controller->status & (ATA_S_ERROR | ATA_S_DWF)) - request->result = ATA_INB(atp->controller->r_io, ATA_ERROR); + if (atadev->channel->status & (ATA_S_ERROR | ATA_S_DWF)) + request->result = ATA_INB(atadev->channel->r_io, ATA_ERROR); else if (!(request->flags & ATPR_F_INTERNAL)) request->result = 0; break; default: - ata_printf(atp->controller, atp->unit, - "unknown transfer phase %d\n", reason); + ata_prtdev(atadev, "unknown transfer phase %d\n", reason); } } untimeout((timeout_t *)atapi_timeout, request, request->timeout_handle); @@ -438,19 +419,18 @@ atapi_interrupt(struct atapi_request *request) request->bytecount = sizeof(struct atapi_reqsense); request->flags &= ATPR_F_QUIET; request->flags |= ATPR_F_READ | ATPR_F_INTERNAL; - TAILQ_INSERT_HEAD(&atp->controller->atapi_queue, request, chain); + TAILQ_INSERT_HEAD(&atadev->channel->atapi_queue, request, chain); } else { - if (request->result) { + if (request->result) { switch ((request->result & ATAPI_SK_MASK)) { case ATAPI_SK_NO_SENSE: request->error = 0; break; case ATAPI_SK_RECOVERED_ERROR: - ata_printf(atp->controller, atp->unit, - "%s - recovered error\n", - atapi_cmd2str(atp->cmd)); + ata_prtdev(atadev, "%s - recovered error\n", + atapi_cmd2str(atadev->cmd)); request->error = 0; break; @@ -459,7 +439,7 @@ atapi_interrupt(struct atapi_request *request) break; case ATAPI_SK_UNIT_ATTENTION: - atp->flags |= ATAPI_F_MEDIA_CHANGED; + atadev->flags |= ATA_D_MEDIA_CHANGED; request->error = EIO; break; @@ -469,9 +449,8 @@ atapi_interrupt(struct atapi_request *request) if (request->flags & ATPR_F_QUIET) break; - ata_printf(atp->controller, atp->unit, - "%s - %s asc=0x%02x ascq=0x%02x ", - atapi_cmd2str(atp->cmd), + ata_prtdev(atadev, "%s - %s asc=0x%02x ascq=0x%02x ", + atapi_cmd2str(atadev->cmd), atapi_skey2str(request->sense.sense_key), request->sense.asc, request->sense.ascq); if (request->sense.sksv) @@ -484,38 +463,39 @@ atapi_interrupt(struct atapi_request *request) } else request->error = 0; - atapi_finish(request); + atapi_finish(request); } return ATA_OP_FINISHED; } void -atapi_reinit(struct atapi_softc *atp) +atapi_reinit(struct ata_device *atadev) { /* reinit device parameters */ - if (atp->controller->mode[ATA_DEV(atp->unit)] >= ATA_DMA) - ata_dmainit(atp->controller, atp->unit, - (ata_pmode(ATP_PARAM) < 0) ? - (ATP_PARAM->support_dma ? 4 : 0) : ata_pmode(ATP_PARAM), - (ata_wmode(ATP_PARAM) < 0) ? - (ATP_PARAM->support_dma ? 2 : 0) : ata_wmode(ATP_PARAM), - ata_umode(ATP_PARAM)); + if (atadev->mode >= ATA_DMA) + ata_dmainit(atadev->channel, atadev->unit, + (ata_pmode(atadev->param) < 0) ? + (atadev->param->support_dma ? 4:0):ata_pmode(atadev->param), + (ata_wmode(atadev->param) < 0) ? + (atadev->param->support_dma ? 2:0):ata_wmode(atadev->param), + ata_umode(atadev->param)); else - ata_dmainit(atp->controller, atp->unit, - ata_pmode(ATP_PARAM)<0 ? 0 : ata_pmode(ATP_PARAM), -1, -1); + ata_dmainit(atadev->channel, atadev->unit, + ata_pmode(atadev->param)<0 ? 0 : ata_pmode(atadev->param), + -1, -1); } int -atapi_test_ready(struct atapi_softc *atp) +atapi_test_ready(struct ata_device *atadev) { int8_t ccb[16] = { ATAPI_TEST_UNIT_READY, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - return atapi_queue_cmd(atp, ccb, NULL, 0, 0, 30, NULL, NULL); + return atapi_queue_cmd(atadev, ccb, NULL, 0, 0, 30, NULL, NULL); } int -atapi_wait_dsc(struct atapi_softc *atp, int timeout) +atapi_wait_dsc(struct ata_device *atadev, int timeout) { int error = 0; int8_t ccb[16] = { ATAPI_POLL_DSC, 0, 0, 0, 0, @@ -523,7 +503,7 @@ atapi_wait_dsc(struct atapi_softc *atp, int timeout) timeout *= hz; while (timeout > 0) { - error = atapi_queue_cmd(atp, ccb, NULL, 0, 0, 0, NULL, NULL); + error = atapi_queue_cmd(atadev, ccb, NULL, 0, 0, 0, NULL, NULL); if (error != EBUSY) break; tsleep((caddr_t)&error, PRIBIO, "atpwt", hz / 2); @@ -548,24 +528,24 @@ atapi_read(struct atapi_request *request, int length) { int8_t **buffer = (int8_t **)&request->data; int size = min(request->bytecount, length); - struct ata_softc *scp = request->device->controller; + struct ata_channel *ch = request->device->channel; int resid; if (request->flags & ATPR_F_INTERNAL) *buffer = (int8_t *)&request->sense; - if (scp->flags & ATA_USE_16BIT || (size % sizeof(int32_t))) - ATA_INSW(scp->r_io, ATA_DATA, (void *)((uintptr_t)*buffer), + if (ch->flags & ATA_USE_16BIT || (size % sizeof(int32_t))) + ATA_INSW(ch->r_io, ATA_DATA, (void *)((uintptr_t)*buffer), size / sizeof(int16_t)); else - ATA_INSL(scp->r_io, ATA_DATA, (void *)((uintptr_t)*buffer), + ATA_INSL(ch->r_io, ATA_DATA, (void *)((uintptr_t)*buffer), size / sizeof(int32_t)); if (request->bytecount < length) { - ata_printf(scp, request->device->unit, "read data overrun %d/%d\n", + ata_prtdev(request->device, "read data overrun %d/%d\n", length, request->bytecount); for (resid=request->bytecount; resid<length; resid+=sizeof(int16_t)) - ATA_INW(scp->r_io, ATA_DATA); + ATA_INW(ch->r_io, ATA_DATA); } *buffer += size; request->bytecount -= size; @@ -577,24 +557,24 @@ atapi_write(struct atapi_request *request, int length) { int8_t **buffer = (int8_t **)&request->data; int size = min(request->bytecount, length); - struct ata_softc *scp = request->device->controller; + struct ata_channel *ch = request->device->channel; int resid; if (request->flags & ATPR_F_INTERNAL) *buffer = (int8_t *)&request->sense; - if (scp->flags & ATA_USE_16BIT || (size % sizeof(int32_t))) - ATA_OUTSW(scp->r_io, ATA_DATA, (void *)((uintptr_t)*buffer), + if (ch->flags & ATA_USE_16BIT || (size % sizeof(int32_t))) + ATA_OUTSW(ch->r_io, ATA_DATA, (void *)((uintptr_t)*buffer), size / sizeof(int16_t)); else - ATA_OUTSL(scp->r_io, ATA_DATA, (void *)((uintptr_t)*buffer), + ATA_OUTSL(ch->r_io, ATA_DATA, (void *)((uintptr_t)*buffer), size / sizeof(int32_t)); if (request->bytecount < length) { - ata_printf(scp, request->device->unit, "write data underrun %d/%d\n", + ata_prtdev(request->device, "write data underrun %d/%d\n", length, request->bytecount); for (resid=request->bytecount; resid<length; resid+=sizeof(int16_t)) - ATA_OUTW(scp->r_io, ATA_DATA, 0); + ATA_OUTW(ch->r_io, ATA_DATA, 0); } *buffer += size; request->bytecount -= size; @@ -605,8 +585,8 @@ static void atapi_finish(struct atapi_request *request) { #ifdef ATAPI_DEBUG - ata_printf(request->device->controller, request->device->unit, - "finished %s%s\n", request->callback ? "callback " : "", + ata_prtdev(atadev->device->device, "finished %s%s\n", + request->callback ? "callback " : "", atapi_cmd2str(request->ccb[0])); #endif if (request->callback) { @@ -623,33 +603,33 @@ atapi_finish(struct atapi_request *request) static void atapi_timeout(struct atapi_request *request) { - struct atapi_softc *atp = request->device; + struct ata_device *atadev = request->device; int s = splbio(); - atp->controller->running = NULL; - ata_printf(atp->controller, atp->unit, "%s command timeout - resetting\n", + atadev->channel->running = NULL; + ata_prtdev(atadev, "%s command timeout - resetting\n", atapi_cmd2str(request->ccb[0])); if (request->flags & ATPR_F_DMA_USED) { - ata_dmadone(atp->controller); + ata_dmadone(atadev->channel); if (request->retries == ATAPI_MAX_RETRIES) { - ata_dmainit(atp->controller, atp->unit, - (ata_pmode(ATP_PARAM)<0)?0:ata_pmode(ATP_PARAM),-1,-1); - ata_printf(atp->controller, atp->unit, - "trying fallback to PIO mode\n"); + ata_dmainit(atadev->channel, atadev->unit, + (ata_pmode(atadev->param) < 0) ? 0 : + ata_pmode(atadev->param), -1, -1); + ata_prtdev(atadev, "trying fallback to PIO mode\n"); request->retries = 0; } } /* if retries still permit, reinject this request */ if (request->retries++ < ATAPI_MAX_RETRIES) - TAILQ_INSERT_HEAD(&atp->controller->atapi_queue, request, chain); + TAILQ_INSERT_HEAD(&atadev->channel->atapi_queue, request, chain); else { - /* retries all used up, return error */ + /* retries all used up, return error */ request->error = EIO; wakeup((caddr_t)request); } - ata_reinit(atp->controller); + ata_reinit(atadev->channel); splx(s); } diff --git a/sys/dev/ata/atapi-all.h b/sys/dev/ata/atapi-all.h index 9727a2c..0d2df68 100644 --- a/sys/dev/ata/atapi-all.h +++ b/sys/dev/ata/atapi-all.h @@ -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 @@ -143,21 +143,10 @@ struct atapi_reqsense { u_int8_t sk_specific2; /* sense key specific */ }; -struct atapi_softc { - struct ata_softc *controller; /* ptr to controller softc */ - int unit; /* ATA_MASTER or ATA_SLAVE */ - void *driver; /* ptr to subdriver softc */ - u_int8_t cmd; /* last cmd executed */ - struct atapi_reqsense sense; /* last cmd sense if error */ - int flags; /* drive flags */ -#define ATAPI_F_MEDIA_CHANGED 0x0001 -#define ATAPI_F_DETACHING 0x0002 -}; - typedef int atapi_callback_t(struct atapi_request *); struct atapi_request { - struct atapi_softc *device; /* ptr to parent device */ + struct ata_device *device; /* ptr to parent softc */ u_int8_t ccb[16]; /* command control block */ int ccbsize; /* size of ccb (12 | 16) */ u_int32_t bytecount; /* bytes to transfer */ @@ -178,27 +167,27 @@ struct atapi_request { caddr_t data; /* pointer to data buf */ atapi_callback_t *callback; /* ptr to callback func */ struct ata_dmaentry *dmatab; /* DMA transfer table */ - void *driver; /* driver specific */ + void *driver; /* driver specific */ TAILQ_ENTRY(atapi_request) chain; /* list management */ }; -void atapi_attach(struct ata_softc *, int); -void atapi_detach(struct atapi_softc *); -void atapi_start(struct atapi_softc *); +void atapi_attach(struct ata_device *); +void atapi_detach(struct ata_device *); +void atapi_start(struct ata_device *); int atapi_transfer(struct atapi_request *); int atapi_interrupt(struct atapi_request *); -int atapi_queue_cmd(struct atapi_softc *, int8_t [], caddr_t, int, int, int, atapi_callback_t, void *); -void atapi_reinit(struct atapi_softc *); -int atapi_test_ready(struct atapi_softc *); -int atapi_wait_dsc(struct atapi_softc *, int); -void atapi_request_sense(struct atapi_softc *, struct atapi_reqsense *); +int atapi_queue_cmd(struct ata_device *, int8_t [], caddr_t, int, int, int, atapi_callback_t, void *); +void atapi_reinit(struct ata_device *); +int atapi_test_ready(struct ata_device *); +int atapi_wait_dsc(struct ata_device *, int); +void atapi_request_sense(struct ata_device *, struct atapi_reqsense *); void atapi_dump(char *, void *, int); -int acdattach(struct atapi_softc *); -void acddetach(struct atapi_softc *); -void acd_start(struct atapi_softc *); -int afdattach(struct atapi_softc *); -void afddetach(struct atapi_softc *); -void afd_start(struct atapi_softc *); -int astattach(struct atapi_softc *); -void astdetach(struct atapi_softc *); -void ast_start(struct atapi_softc *); +int acdattach(struct ata_device *); +void acddetach(struct ata_device *); +void acd_start(struct ata_device *); +int afdattach(struct ata_device *); +void afddetach(struct ata_device *); +void afd_start(struct ata_device *); +int astattach(struct ata_device *); +void astdetach(struct ata_device *); +void ast_start(struct ata_device *); diff --git a/sys/dev/ata/atapi-cd.c b/sys/dev/ata/atapi-cd.c index 4902ad0..3486b0a 100644 --- a/sys/dev/ata/atapi-cd.c +++ b/sys/dev/ata/atapi-cd.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 @@ -70,7 +70,7 @@ static struct cdevsw acd_cdevsw = { }; /* prototypes */ -static struct acd_softc *acd_init_lun(struct atapi_softc *, struct devstat *); +static struct acd_softc *acd_init_lun(struct ata_device *, struct devstat *); static void acd_make_dev(struct acd_softc *); static void acd_describe(struct acd_softc *); static void lba2msf(u_int32_t, u_int8_t *, u_int8_t *, u_int8_t *); @@ -105,33 +105,32 @@ static u_int32_t acd_lun_map = 0; static MALLOC_DEFINE(M_ACD, "ACD driver", "ATAPI CD driver buffers"); int -acdattach(struct atapi_softc *atp) +acdattach(struct ata_device *atadev) { struct acd_softc *cdp; struct changer *chp; - if ((cdp = acd_init_lun(atp, NULL)) == NULL) { - ata_printf(atp->controller, atp->unit, "acd: out of memory\n"); + if ((cdp = acd_init_lun(atadev, NULL)) == NULL) { + ata_prtdev(atadev, "acd: out of memory\n"); return -1; } - ata_set_name(atp->controller, atp->unit, "acd", cdp->lun); + ata_set_name(atadev, "acd", cdp->lun); acd_get_cap(cdp); /* if this is a changer device, allocate the neeeded lun's */ if (cdp->cap.mech == MST_MECH_CHANGER) { - int8_t ccb[16] = { ATAPI_MECH_STATUS, - 0, 0, 0, 0, 0, 0, 0, + int8_t ccb[16] = { ATAPI_MECH_STATUS, 0, 0, 0, 0, 0, 0, 0, sizeof(struct changer)>>8, sizeof(struct changer), 0, 0, 0, 0, 0, 0 }; chp = malloc(sizeof(struct changer), M_ACD, M_NOWAIT | M_ZERO); if (chp == NULL) { - ata_printf(atp->controller, atp->unit, "out of memory\n"); + ata_prtdev(atadev, "out of memory\n"); free(cdp, M_ACD); return -1; } - if (!atapi_queue_cmd(cdp->atp, ccb, (caddr_t)chp, + if (!atapi_queue_cmd(cdp->device, ccb, (caddr_t)chp, sizeof(struct changer), ATPR_F_READ, 60, NULL, NULL)) { struct acd_softc *tmpcdp = cdp; @@ -141,17 +140,17 @@ acdattach(struct atapi_softc *atp) chp->table_length = htons(chp->table_length); if (!(cdparr = malloc(sizeof(struct acd_softc) * chp->slots, - M_ACD, M_NOWAIT))) { - ata_printf(atp->controller, atp->unit, "out of memory\n"); + M_ACD, M_NOWAIT))) { + ata_prtdev(atadev, "out of memory\n"); free(chp, M_ACD); free(cdp, M_ACD); return -1; } for (count = 0; count < chp->slots; count++) { if (count > 0) { - tmpcdp = acd_init_lun(atp, NULL); + tmpcdp = acd_init_lun(atadev, NULL); if (!tmpcdp) { - ata_printf(atp->controller,atp->unit,"out of memory\n"); + ata_prtdev(atadev, "out of memory\n"); break; } } @@ -159,19 +158,16 @@ acdattach(struct atapi_softc *atp) tmpcdp->driver = cdparr; tmpcdp->slot = count; tmpcdp->changer_info = chp; - acd_make_dev(tmpcdp); + acd_make_dev(tmpcdp); devstat_add_entry(cdp->stats, "acd", tmpcdp->lun, DEV_BSIZE, DEVSTAT_NO_ORDERED_TAGS, DEVSTAT_TYPE_CDROM | DEVSTAT_TYPE_IF_IDE, DEVSTAT_PRIORITY_CD); } - name = - malloc(strlen(atp->controller->dev_name[ATA_DEV(atp->unit)])+1, - M_ACD, M_NOWAIT); - strcpy(name, atp->controller->dev_name[ATA_DEV(atp->unit)]); - ata_free_name(atp->controller, atp->unit); - ata_set_name(atp->controller, atp->unit, name, - cdp->lun + cdp->changer_info->slots - 1); + name = malloc(strlen(atadev->name) + 1, M_ACD, M_NOWAIT); + strcpy(name, atadev->name); + ata_free_name(atadev); + ata_set_name(atadev, name, cdp->lun + cdp->changer_info->slots - 1); free(name, M_ACD); } } @@ -182,15 +178,15 @@ acdattach(struct atapi_softc *atp) DEVSTAT_TYPE_CDROM | DEVSTAT_TYPE_IF_IDE, DEVSTAT_PRIORITY_CD); } - cdp->atp->driver = cdp; acd_describe(cdp); + atadev->driver = cdp; return 0; } void -acddetach(struct atapi_softc *atp) +acddetach(struct ata_device *atadev) { - struct acd_softc *cdp = atp->driver; + struct acd_softc *cdp = atadev->driver; struct acd_devlist *entry; struct bio *bp; int subdev; @@ -200,7 +196,8 @@ acddetach(struct atapi_softc *atp) if (cdp->driver[subdev] == cdp) continue; while ((bp = bioq_first(&cdp->driver[subdev]->queue))) { - biofinish(bp, NULL, ENXIO); + bioq_remove(&cdp->driver[subdev]->queue, bp); + biofinish(bp, NULL, ENXIO); } destroy_dev(cdp->driver[subdev]->dev); while ((entry = TAILQ_FIRST(&cdp->driver[subdev]->dev_list))) { @@ -216,10 +213,8 @@ acddetach(struct atapi_softc *atp) free(cdp->driver, M_ACD); free(cdp->changer_info, M_ACD); } - while ((bp = bioq_first(&cdp->queue))) { - biofinish(bp, NULL, ENXIO); - } - destroy_dev(cdp->dev); + while ((bp = bioq_first(&cdp->queue))) + biofinish(bp, NULL, ENXIO); while ((entry = TAILQ_FIRST(&cdp->dev_list))) { destroy_dev(entry->dev); TAILQ_REMOVE(&cdp->dev_list, entry, chain); @@ -227,13 +222,14 @@ acddetach(struct atapi_softc *atp) } devstat_remove_entry(cdp->stats); free(cdp->stats, M_ACD); - ata_free_name(atp->controller, atp->unit); + ata_free_name(atadev); ata_free_lun(&acd_lun_map, cdp->lun); free(cdp, M_ACD); + atadev->driver = NULL; } static struct acd_softc * -acd_init_lun(struct atapi_softc *atp, struct devstat *stats) +acd_init_lun(struct ata_device *atadev, struct devstat *stats) { struct acd_softc *cdp; @@ -241,7 +237,7 @@ acd_init_lun(struct atapi_softc *atp, struct devstat *stats) return NULL; TAILQ_INIT(&cdp->dev_list); bioq_init(&cdp->queue); - cdp->atp = atp; + cdp->device = atadev; cdp->lun = ata_get_lun(&acd_lun_map); cdp->block_size = 2048; cdp->slot = -1; @@ -271,7 +267,7 @@ acd_make_dev(struct acd_softc *cdp) dev->si_iosize_max = 252 * DEV_BSIZE; dev->si_bsize_phys = 2048; /* XXX SOS */ cdp->dev = dev; - cdp->atp->flags |= ATAPI_F_MEDIA_CHANGED; + cdp->device->flags |= ATA_D_MEDIA_CHANGED; } static void @@ -281,19 +277,17 @@ acd_describe(struct acd_softc *cdp) char *mechanism; if (bootverbose) { - ata_printf(cdp->atp->controller, cdp->atp->unit, - "<%.40s/%.8s> %s drive at ata%d as %s\n", - ATA_PARAM(cdp->atp->controller, cdp->atp->unit)->model, - ATA_PARAM(cdp->atp->controller, cdp->atp->unit)->revision, + ata_prtdev(cdp->device, "<%.40s/%.8s> %s drive at ata%d as %s\n", + cdp->device->param->model, cdp->device->param->revision, (cdp->cap.write_dvdr) ? "DVD-R" : (cdp->cap.write_dvdram) ? "DVD-RAM" : (cdp->cap.write_cdrw) ? "CD-RW" : (cdp->cap.write_cdr) ? "CD-R" : (cdp->cap.read_dvdrom) ? "DVD-ROM" : "CDROM", - device_get_unit(cdp->atp->controller->dev), - (cdp->atp->unit == ATA_MASTER) ? "master" : "slave"); + device_get_unit(cdp->device->channel->dev), + (cdp->device->unit == ATA_MASTER) ? "master" : "slave"); - ata_printf(cdp->atp->controller, cdp->atp->unit, "%s", ""); + ata_prtdev(cdp->device, "%s", ""); if (cdp->cap.cur_read_speed) { printf("read %dKB/s", cdp->cap.cur_read_speed * 1000 / 1024); if (cdp->cap.max_read_speed) @@ -311,11 +305,9 @@ acd_describe(struct acd_softc *cdp) printf("%s %dKB buffer", comma ? "," : "", cdp->cap.buf_size); comma = 1; } - printf("%s %s\n", - comma ? "," : "", ata_mode2str( - cdp->atp->controller->mode[ATA_DEV(cdp->atp->unit)])); + printf("%s %s\n", comma ? "," : "", ata_mode2str(cdp->device->mode)); - ata_printf(cdp->atp->controller, cdp->atp->unit, "Reads:"); + ata_prtdev(cdp->device, "Reads:"); comma = 0; if (cdp->cap.read_cdr) { printf(" CD-R"); comma = 1; @@ -325,9 +317,9 @@ acd_describe(struct acd_softc *cdp) } if (cdp->cap.cd_da) { if (cdp->cap.cd_da_stream) - printf("%s CD-DA stream", comma ? "," : ""); + printf("%s CD-DA stream", comma ? "," : ""); else - printf("%s CD-DA", comma ? "," : ""); + printf("%s CD-DA", comma ? "," : ""); comma = 1; } if (cdp->cap.read_dvdrom) { @@ -343,7 +335,7 @@ acd_describe(struct acd_softc *cdp) printf("%s packet", comma ? "," : ""); printf("\n"); - ata_printf(cdp->atp->controller, cdp->atp->unit, "Writes:"); + ata_prtdev(cdp->device, "Writes:"); if (cdp->cap.write_cdr || cdp->cap.write_cdrw || cdp->cap.write_dvdr || cdp->cap.write_dvdram) { comma = 0; @@ -367,14 +359,14 @@ acd_describe(struct acd_softc *cdp) } printf("\n"); if (cdp->cap.audio_play) { - ata_printf(cdp->atp->controller, cdp->atp->unit, "Audio: "); + ata_prtdev(cdp->device, "Audio: "); if (cdp->cap.audio_play) printf("play"); if (cdp->cap.max_vol_levels) printf(", %d volume levels", cdp->cap.max_vol_levels); printf("\n"); } - ata_printf(cdp->atp->controller, cdp->atp->unit, "Mechanism: "); + ata_prtdev(cdp->device, "Mechanism: "); switch (cdp->cap.mech) { case MST_MECH_CADDY: mechanism = "caddy"; break; @@ -401,7 +393,7 @@ acd_describe(struct acd_softc *cdp) printf("\n"); if (cdp->cap.mech != MST_MECH_CHANGER) { - ata_printf(cdp->atp->controller, cdp->atp->unit, "Medium: "); + ata_prtdev(cdp->device, "Medium: "); switch (cdp->cap.medium_type & MST_TYPE_MASK_HIGH) { case MST_CDROM: printf("CD-ROM "); break; @@ -451,7 +443,7 @@ acd_describe(struct acd_softc *cdp) } } else { - ata_printf(cdp->atp->controller, cdp->atp->unit, "%s ", + ata_prtdev(cdp->device, "%s ", (cdp->cap.write_dvdr) ? "DVD-R" : (cdp->cap.write_dvdram) ? "DVD-RAM" : (cdp->cap.write_cdrw) ? "CD-RW" : @@ -461,12 +453,10 @@ acd_describe(struct acd_softc *cdp) if (cdp->changer_info) printf("with %d CD changer ", cdp->changer_info->slots); - printf("<%.40s> at ata%d-%s %s\n", - ATA_PARAM(cdp->atp->controller, cdp->atp->unit)->model, - device_get_unit(cdp->atp->controller->dev), - (cdp->atp->unit == ATA_MASTER) ? "master" : "slave", - ata_mode2str(cdp->atp->controller->mode[ATA_DEV(cdp->atp->unit)]) - ); + printf("<%.40s> at ata%d-%s %s\n", cdp->device->param->model, + device_get_unit(cdp->device->channel->dev), + (cdp->device->unit == ATA_MASTER) ? "master" : "slave", + ata_mode2str(cdp->device->mode) ); } } @@ -543,10 +533,10 @@ acdioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct thread *td) acd_select_slot(cdp); tsleep(&cdp->changer_info, PRIBIO, "acdctl", 0); } - if (cdp->atp->flags & ATAPI_F_MEDIA_CHANGED) + if (cdp->device->flags & ATA_D_MEDIA_CHANGED) switch (cmd) { case CDIOCRESET: - atapi_test_ready(cdp->atp); + atapi_test_ready(cdp->device); break; default: @@ -587,7 +577,7 @@ acdioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct thread *td) error = suser(td->td_proc); if (error) break; - error = atapi_test_ready(cdp->atp); + error = atapi_test_ready(cdp->device); break; case CDIOCEJECT: @@ -728,7 +718,7 @@ acdioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct thread *td) break; } - if ((error = atapi_queue_cmd(cdp->atp, ccb, (caddr_t)&cdp->subchan, + if ((error = atapi_queue_cmd(cdp->device,ccb,(caddr_t)&cdp->subchan, sizeof(cdp->subchan), ATPR_F_READ, 10, NULL, NULL))) { break; @@ -855,7 +845,7 @@ acdioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct thread *td) ccb[5] = lba; ccb[8] = blocks; ccb[9] = 0xf0; - if ((error = atapi_queue_cmd(cdp->atp, ccb, buffer, size, + if ((error = atapi_queue_cmd(cdp->device, ccb, buffer, size, ATPR_F_READ, 30, NULL,NULL))) break; @@ -1001,11 +991,11 @@ acdioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct thread *td) break; case CDRIOCGETPROGRESS: - error = acd_get_progress(cdp, (int *)addr); + error = acd_get_progress(cdp, (int *)addr); break; case CDRIOCSENDCUE: - error = acd_send_cue(cdp, (struct cdr_cuesheet *)addr); + error = acd_send_cue(cdp, (struct cdr_cuesheet *)addr); break; case DVDIOCREPORTKEY: @@ -1062,7 +1052,7 @@ acdstrategy(struct bio *bp) struct acd_softc *cdp = bp->bio_dev->si_drv1; int s; - if (cdp->atp->flags & ATAPI_F_DETACHING) { + if (cdp->device->flags & ATA_D_DETACHING) { biofinish(bp, NULL, ENXIO); return; } @@ -1079,14 +1069,14 @@ acdstrategy(struct bio *bp) s = splbio(); bioqdisksort(&cdp->queue, bp); - ata_start(cdp->atp->controller); + ata_start(cdp->device->channel); splx(s); } void -acd_start(struct atapi_softc *atp) +acd_start(struct ata_device *atadev) { - struct acd_softc *cdp = atp->driver; + struct acd_softc *cdp = atadev->driver; struct bio *bp = bioq_first(&cdp->queue); u_int32_t lba, lastlba, count; int8_t ccb[16]; @@ -1103,7 +1093,7 @@ acd_start(struct atapi_softc *atp) if (i == cdp->changer_info->current_slot) continue; if (bioq_first(&(cdp->driver[i]->queue))) { - if (!bp || time_second > (cdp->timestamp + 10)) { + if (!bp || time_second > (cdp->timestamp + 10)) { acd_select_slot(cdp->driver[i]); return; } @@ -1115,7 +1105,7 @@ acd_start(struct atapi_softc *atp) bioq_remove(&cdp->queue, bp); /* reject all queued entries if media changed */ - if (cdp->atp->flags & ATAPI_F_MEDIA_CHANGED) { + if (cdp->device->flags & ATA_D_MEDIA_CHANGED) { biofinish(bp, NULL, EIO); return; } @@ -1182,7 +1172,7 @@ acd_start(struct atapi_softc *atp) devstat_start_transaction(cdp->stats); - atapi_queue_cmd(cdp->atp, ccb, bp->bio_data, count * blocksize, + atapi_queue_cmd(cdp->device, ccb, bp->bio_data, count * blocksize, bp->bio_cmd == BIO_READ ? ATPR_F_READ : 0, (ccb[0] == ATAPI_WRITE_BIG) ? 60 : 30, acd_done, bp); } @@ -1214,16 +1204,16 @@ acd_read_toc(struct acd_softc *cdp) bzero(&cdp->toc, sizeof(cdp->toc)); bzero(ccb, sizeof(ccb)); - if (atapi_test_ready(cdp->atp) != 0) + if (atapi_test_ready(cdp->device) != 0) return; - cdp->atp->flags &= ~ATAPI_F_MEDIA_CHANGED; + cdp->device->flags &= ~ATA_D_MEDIA_CHANGED; len = sizeof(struct ioc_toc_header) + sizeof(struct cd_toc_entry); ccb[0] = ATAPI_READ_TOC; ccb[7] = len>>8; ccb[8] = len; - if (atapi_queue_cmd(cdp->atp, ccb, (caddr_t)&cdp->toc, len, + if (atapi_queue_cmd(cdp->device, ccb, (caddr_t)&cdp->toc, len, ATPR_F_READ | ATPR_F_QUIET, 30, NULL, NULL)) { bzero(&cdp->toc, sizeof(cdp->toc)); return; @@ -1239,7 +1229,7 @@ acd_read_toc(struct acd_softc *cdp) ccb[0] = ATAPI_READ_TOC; ccb[7] = len>>8; ccb[8] = len; - if (atapi_queue_cmd(cdp->atp, ccb, (caddr_t)&cdp->toc, len, + if (atapi_queue_cmd(cdp->device, ccb, (caddr_t)&cdp->toc, len, ATPR_F_READ | ATPR_F_QUIET, 30, NULL, NULL)) { bzero(&cdp->toc, sizeof(cdp->toc)); return; @@ -1247,28 +1237,22 @@ acd_read_toc(struct acd_softc *cdp) cdp->toc.hdr.len = ntohs(cdp->toc.hdr.len); cdp->block_size = (cdp->toc.tab[0].control & 4) ? 2048 : 2352; -#if 0 - cdp->disk_size = ntohl(cdp->toc.tab[cdp->toc.hdr.ending_track].addr.lba); -#else bzero(ccb, sizeof(ccb)); ccb[0] = ATAPI_READ_CAPACITY; - if (atapi_queue_cmd(cdp->atp, ccb, (caddr_t)sizes, sizeof(sizes), + if (atapi_queue_cmd(cdp->device, ccb, (caddr_t)sizes, sizeof(sizes), ATPR_F_READ | ATPR_F_QUIET, 30, NULL, NULL)) { bzero(&cdp->toc, sizeof(cdp->toc)); return; } cdp->disk_size = ntohl(sizes[0]) + 1; -#endif bzero(&cdp->disklabel, sizeof(struct disklabel)); - strncpy(cdp->disklabel.d_typename, " ", - sizeof(cdp->disklabel.d_typename)); - strncpy(cdp->disklabel.d_typename, - cdp->atp->controller->dev_name[ATA_DEV(cdp->atp->unit)], - min(strlen(cdp->atp->controller->dev_name[ATA_DEV(cdp->atp->unit)]), - sizeof(cdp->disklabel.d_typename) - 1)); - strncpy(cdp->disklabel.d_packname, "unknown ", - sizeof(cdp->disklabel.d_packname)); + strncpy(cdp->disklabel.d_typename, " ", + sizeof(cdp->disklabel.d_typename)); + strncpy(cdp->disklabel.d_typename, cdp->device->name, + min(strlen(cdp->device->name),sizeof(cdp->disklabel.d_typename)-1)); + strncpy(cdp->disklabel.d_packname, "unknown ", + sizeof(cdp->disklabel.d_packname)); cdp->disklabel.d_secsize = cdp->block_size; cdp->disklabel.d_nsectors = 100; cdp->disklabel.d_ntracks = 1; @@ -1296,7 +1280,7 @@ acd_read_toc(struct acd_softc *cdp) sprintf(name, "acd%dt%d", cdp->lun, track); entry = malloc(sizeof(struct acd_devlist), M_ACD, M_NOWAIT | M_ZERO); - entry->dev = make_dev(&acd_cdevsw, (cdp->lun << 3) | (track << 16), + entry->dev = make_dev(&acd_cdevsw, (cdp->lun << 3) | (track << 16), 0, 0, 0644, name, NULL); entry->dev->si_drv1 = cdp->dev->si_drv1; TAILQ_INSERT_TAIL(&cdp->dev_list, entry, chain); @@ -1304,8 +1288,7 @@ acd_read_toc(struct acd_softc *cdp) #ifdef ACD_DEBUG if (cdp->disk_size && cdp->toc.hdr.ending_track) { - ata_printf(cdp->atp->controller, cdp->atp->unit, - "(%d sectors (%d bytes)), %d tracks ", + ata_prtdev(cdp->device, "(%d sectors (%d bytes)), %d tracks ", cdp->disk_size, cdp->block_size, cdp->toc.hdr.ending_track - cdp->toc.hdr.starting_track + 1); if (cdp->toc.tab[0].control & 4) @@ -1323,22 +1306,10 @@ acd_play(struct acd_softc *cdp, int start, int end) int8_t ccb[16]; bzero(ccb, sizeof(ccb)); -#if 1 ccb[0] = ATAPI_PLAY_MSF; lba2msf(start, &ccb[3], &ccb[4], &ccb[5]); lba2msf(end, &ccb[6], &ccb[7], &ccb[8]); -#else - ccb[0] = ATAPI_PLAY_12; - ccb[2] = start>>24; - ccb[3] = start>>16; - ccb[4] = start>>8; - ccb[5] = start; - ccb[6] = (end - start)>>24; - ccb[7] = (end - start)>>16; - ccb[8] = (end - start)>>8; - ccb[9] = (end - start); -#endif - return atapi_queue_cmd(cdp->atp, ccb, NULL, 0, 0, 10, NULL, NULL); + return atapi_queue_cmd(cdp->device, ccb, NULL, 0, 0, 10, NULL, NULL); } static int @@ -1379,7 +1350,7 @@ acd_select_done(struct atapi_request *request) cdp->slot, 0, 0, 0, 0, 0, 0, 0 }; /* load the wanted slot */ - atapi_queue_cmd(cdp->atp, ccb, NULL, 0, ATPR_F_AT_HEAD, 30, + atapi_queue_cmd(cdp->device, ccb, NULL, 0, ATPR_F_AT_HEAD, 30, acd_select_done1, cdp); return 0; } @@ -1391,7 +1362,7 @@ acd_select_slot(struct acd_softc *cdp) cdp->changer_info->current_slot, 0, 0, 0, 0, 0, 0, 0 }; /* unload the current media from player */ - atapi_queue_cmd(cdp->atp, ccb, NULL, 0, ATPR_F_AT_HEAD, 30, + atapi_queue_cmd(cdp->device, ccb, NULL, 0, ATPR_F_AT_HEAD, 30, acd_select_done, cdp); } @@ -1402,10 +1373,10 @@ acd_init_writer(struct acd_softc *cdp, int test_write) bzero(ccb, sizeof(ccb)); ccb[0] = ATAPI_REZERO; - atapi_queue_cmd(cdp->atp, ccb, NULL, 0, ATPR_F_QUIET, 60, NULL, NULL); + atapi_queue_cmd(cdp->device, ccb, NULL, 0, ATPR_F_QUIET, 60, NULL, NULL); ccb[0] = ATAPI_SEND_OPC_INFO; ccb[1] = 0x01; - atapi_queue_cmd(cdp->atp, ccb, NULL, 0, ATPR_F_QUIET, 30, NULL, NULL); + atapi_queue_cmd(cdp->device, ccb, NULL, 0, ATPR_F_QUIET, 30, NULL, NULL); return 0; } @@ -1424,26 +1395,26 @@ acd_fixate(struct acd_softc *cdp, int multisession) param.data_length = 0; if (multisession) - param.session_type = CDR_SESS_MULTI; + param.session_type = CDR_SESS_MULTI; else - param.session_type = CDR_SESS_NONE; + param.session_type = CDR_SESS_NONE; if ((error = acd_mode_select(cdp, (caddr_t)¶m, param.page_length + 10))) return error; - error = atapi_queue_cmd(cdp->atp, ccb, NULL, 0, 0, 30, NULL, NULL); + error = atapi_queue_cmd(cdp->device, ccb, NULL, 0, 0, 30, NULL, NULL); if (error) return error; /* some drives just return ready, wait for the expected fixate time */ - if ((error = atapi_test_ready(cdp->atp)) != EBUSY) { + if ((error = atapi_test_ready(cdp->device)) != EBUSY) { timeout = timeout / (cdp->cap.cur_write_speed / 177); tsleep(&error, PRIBIO, "acdfix", timeout * hz / 2); - return atapi_test_ready(cdp->atp); + return atapi_test_ready(cdp->device); } while (timeout-- > 0) { - if ((error = atapi_test_ready(cdp->atp)) != EBUSY) + if ((error = atapi_test_ready(cdp->device)) != EBUSY) return error; tsleep(&error, PRIBIO, "acdcld", hz/2); } @@ -1536,7 +1507,8 @@ acd_flush(struct acd_softc *cdp) int8_t ccb[16] = { ATAPI_SYNCHRONIZE_CACHE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - return atapi_queue_cmd(cdp->atp, ccb, NULL, 0, ATPR_F_QUIET, 60, NULL,NULL); + return atapi_queue_cmd(cdp->device, ccb, NULL, 0, ATPR_F_QUIET, 60, + NULL, NULL); } static int @@ -1550,7 +1522,7 @@ acd_read_track_info(struct acd_softc *cdp, 0, 0, 0, 0, 0, 0, 0 }; int error; - if ((error = atapi_queue_cmd(cdp->atp, ccb, (caddr_t)info, sizeof(*info), + if ((error = atapi_queue_cmd(cdp->device, ccb, (caddr_t)info, sizeof(*info), ATPR_F_READ, 30, NULL, NULL))) return error; info->track_start_addr = ntohl(info->track_start_addr); @@ -1566,18 +1538,19 @@ acd_get_progress(struct acd_softc *cdp, int *finished) { int8_t ccb[16] = { ATAPI_READ_CAPACITY, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + struct atapi_reqsense *sense = cdp->device->result; char tmp[8]; - if (atapi_test_ready(cdp->atp) != EBUSY) { - if (atapi_queue_cmd(cdp->atp, ccb, tmp, sizeof(tmp), + if (atapi_test_ready(cdp->device) != EBUSY) { + if (atapi_queue_cmd(cdp->device, ccb, tmp, sizeof(tmp), ATPR_F_READ, 30, NULL, NULL) != EBUSY) { *finished = 100; return 0; } } - if (cdp->atp->sense.sksv) - *finished = ((cdp->atp->sense.sk_specific2 | - (cdp->atp->sense.sk_specific1 << 8)) * 100) / 65535; + if (sense->sksv) + *finished = + ((sense->sk_specific2 | (sense->sk_specific1 << 8)) * 100) / 65535; else *finished = 0; return 0; @@ -1623,12 +1596,14 @@ acd_send_cue(struct acd_softc *cdp, struct cdr_cuesheet *cuesheet) #ifdef ACD_DEBUG printf("acd: cuesheet lenght = %d\n", cuesheet->len); for (i=0; i<cuesheet->len; i++) - if (i%8) printf(" %02x", buffer[i]); - else printf("\n%02x", buffer[i]); + if (i%8) + printf(" %02x", buffer[i]); + else + printf("\n%02x", buffer[i]); printf("\n"); #endif - error = atapi_queue_cmd(cdp->atp, ccb, buffer, cuesheet->len, 0, 30, - NULL, NULL); + error = atapi_queue_cmd(cdp->device, ccb, buffer, cuesheet->len, 0, + 30, NULL, NULL); free(buffer, M_ACD); return error; } @@ -1678,7 +1653,7 @@ acd_report_key(struct acd_softc *cdp, struct dvd_authinfo *ai) d = malloc(length, M_ACD, M_NOWAIT | M_ZERO); d->length = htons(length - 2); - error = atapi_queue_cmd(cdp->atp, ccb, (caddr_t)d, length, + error = atapi_queue_cmd(cdp->device, ccb, (caddr_t)d, length, ai->format == DVD_INVALIDATE_AGID ? 0 : ATPR_F_READ, 10, NULL, NULL); if (error) { @@ -1765,7 +1740,7 @@ acd_send_key(struct acd_softc *cdp, struct dvd_authinfo *ai) ccb[9] = length & 0xff; ccb[10] = (ai->agid << 6) | ai->format; d->length = htons(length - 2); - error = atapi_queue_cmd(cdp->atp, ccb, (caddr_t)d, length, 0, + error = atapi_queue_cmd(cdp->device, ccb, (caddr_t)d, length, 0, 10, NULL, NULL); free(d, M_ACD); return error; @@ -1824,8 +1799,8 @@ acd_read_structure(struct acd_softc *cdp, struct dvd_struct *s) ccb[8] = (length >> 8) & 0xff; ccb[9] = length & 0xff; ccb[10] = s->agid << 6; - error = atapi_queue_cmd(cdp->atp, ccb, (caddr_t)d, length, ATPR_F_READ, - 30, NULL, NULL); + error = atapi_queue_cmd(cdp->device, ccb, (caddr_t)d, length, ATPR_F_READ, + 30, NULL, NULL); if (error) { free(d, M_ACD); return error; @@ -1898,7 +1873,7 @@ acd_eject(struct acd_softc *cdp, int close) return 0; acd_prevent_allow(cdp, 0); cdp->flags &= ~F_LOCKED; - cdp->atp->flags |= ATAPI_F_MEDIA_CHANGED; + cdp->device->flags |= ATA_D_MEDIA_CHANGED; return acd_start_stop(cdp, 2); } @@ -1908,8 +1883,8 @@ acd_blank(struct acd_softc *cdp, int blanktype) int8_t ccb[16] = { ATAPI_BLANK, 0x10 | (blanktype & 0x7), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - cdp->atp->flags |= ATAPI_F_MEDIA_CHANGED; - return atapi_queue_cmd(cdp->atp, ccb, NULL, 0, 0, 30, NULL, NULL); + cdp->device->flags |= ATA_D_MEDIA_CHANGED; + return atapi_queue_cmd(cdp->device, ccb, NULL, 0, 0, 30, NULL, NULL); } static int @@ -1918,7 +1893,7 @@ acd_prevent_allow(struct acd_softc *cdp, int lock) int8_t ccb[16] = { ATAPI_PREVENT_ALLOW, 0, 0, 0, lock, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - return atapi_queue_cmd(cdp->atp, ccb, NULL, 0, 0, 30, NULL, NULL); + return atapi_queue_cmd(cdp->device, ccb, NULL, 0, 0, 30, NULL, NULL); } static int @@ -1927,7 +1902,7 @@ acd_start_stop(struct acd_softc *cdp, int start) int8_t ccb[16] = { ATAPI_START_STOP, 0, 0, 0, start, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - return atapi_queue_cmd(cdp->atp, ccb, NULL, 0, 0, 30, NULL, NULL); + return atapi_queue_cmd(cdp->device, ccb, NULL, 0, 0, 30, NULL, NULL); } static int @@ -1936,7 +1911,7 @@ acd_pause_resume(struct acd_softc *cdp, int pause) int8_t ccb[16] = { ATAPI_PAUSE, 0, 0, 0, 0, 0, 0, 0, pause, 0, 0, 0, 0, 0, 0, 0 }; - return atapi_queue_cmd(cdp->atp, ccb, NULL, 0, 0, 30, NULL, NULL); + return atapi_queue_cmd(cdp->device, ccb, NULL, 0, 0, 30, NULL, NULL); } static int @@ -1946,8 +1921,8 @@ acd_mode_sense(struct acd_softc *cdp, int page, caddr_t pagebuf, int pagesize) pagesize>>8, pagesize, 0, 0, 0, 0, 0, 0, 0 }; int error; - error = atapi_queue_cmd(cdp->atp, ccb, pagebuf, pagesize, ATPR_F_READ, 10, - NULL, NULL); + error = atapi_queue_cmd(cdp->device, ccb, pagebuf, pagesize, ATPR_F_READ, + 10, NULL, NULL); #ifdef ACD_DEBUG atapi_dump("acd: mode sense ", pagebuf, pagesize); #endif @@ -1961,11 +1936,12 @@ acd_mode_select(struct acd_softc *cdp, caddr_t pagebuf, int pagesize) pagesize>>8, pagesize, 0, 0, 0, 0, 0, 0, 0 }; #ifdef ACD_DEBUG - ata_printf(cdp->atp->controller, cdp->atp->unit, + ata_prtdev(cdp->device, "modeselect pagesize=%d\n", pagesize); atapi_dump("mode select ", pagebuf, pagesize); #endif - return atapi_queue_cmd(cdp->atp, ccb, pagebuf, pagesize, 0, 30, NULL, NULL); + return atapi_queue_cmd(cdp->device, ccb, pagebuf, pagesize, 0, + 30, NULL, NULL); } static int @@ -1975,7 +1951,7 @@ acd_set_speed(struct acd_softc *cdp, int rdspeed, int wrspeed) wrspeed >> 8, wrspeed, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; int error; - error = atapi_queue_cmd(cdp->atp, ccb, NULL, 0, 0, 30, NULL, NULL); + error = atapi_queue_cmd(cdp->device, ccb, NULL, 0, 0, 30, NULL, NULL); if (!error) acd_get_cap(cdp); return error; diff --git a/sys/dev/ata/atapi-cd.h b/sys/dev/ata/atapi-cd.h index 364fb3c..7660531 100644 --- a/sys/dev/ata/atapi-cd.h +++ b/sys/dev/ata/atapi-cd.h @@ -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 @@ -305,13 +305,13 @@ struct acd_devlist { /* Structure describing an ATAPI CDROM device */ struct acd_softc { - struct atapi_softc *atp; /* controller structure */ + struct ata_device *device; /* device softc */ int lun; /* logical device unit */ int flags; /* device state flags */ -#define F_LOCKED 0x0001 /* this unit is locked */ +#define F_LOCKED 0x0001 /* this unit is locked */ struct bio_queue_head queue; /* queue of i/o requests */ - TAILQ_HEAD(, acd_devlist) dev_list; /* list of "track" devices */ + TAILQ_HEAD(, acd_devlist) dev_list; /* list of "track" devices */ struct toc toc; /* table of disc contents */ struct audiopage au; /* audio page info */ struct audiopage aumask; /* audio page mask */ diff --git a/sys/dev/ata/atapi-fd.c b/sys/dev/ata/atapi-fd.c index 72bd44e..303d10c 100644 --- a/sys/dev/ata/atapi-fd.c +++ b/sys/dev/ata/atapi-fd.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 @@ -79,20 +79,20 @@ static u_int32_t afd_lun_map = 0; static MALLOC_DEFINE(M_AFD, "AFD driver", "ATAPI floppy driver buffers"); int -afdattach(struct atapi_softc *atp) +afdattach(struct ata_device *atadev) { struct afd_softc *fdp; dev_t dev; fdp = malloc(sizeof(struct afd_softc), M_AFD, M_NOWAIT | M_ZERO); if (!fdp) { - ata_printf(atp->controller, atp->unit, "out of memory\n"); + ata_prtdev(atadev, "out of memory\n"); return -1; } - fdp->atp = atp; + fdp->device = atadev; fdp->lun = ata_get_lun(&afd_lun_map); - ata_set_name(atp->controller, atp->unit, "afd", fdp->lun); + ata_set_name(atadev, "afd", fdp->lun); bioq_init(&fdp->queue); if (afd_sense(fdp)) { @@ -100,8 +100,7 @@ afdattach(struct atapi_softc *atp) return -1; } - if (!strncmp(ATA_PARAM(fdp->atp->controller, fdp->atp->unit)->model, - "IOMEGA ZIP", 10)) + if (!strncmp(atadev->param->model, "IOMEGA ZIP", 10)) fdp->transfersize = 64; devstat_add_entry(&fdp->stats, "afd", fdp->lun, DEV_BSIZE, @@ -112,27 +111,29 @@ afdattach(struct atapi_softc *atp) dev->si_drv1 = fdp; dev->si_iosize_max = 252 * DEV_BSIZE; fdp->dev = dev; - fdp->atp->flags |= ATAPI_F_MEDIA_CHANGED; - fdp->atp->driver = fdp; afd_describe(fdp); + atadev->flags |= ATA_D_MEDIA_CHANGED; + atadev->driver = fdp; return 0; } void -afddetach(struct atapi_softc *atp) +afddetach(struct ata_device *atadev) { - struct afd_softc *fdp = atp->driver; + struct afd_softc *fdp = atadev->driver; struct bio *bp; while ((bp = bioq_first(&fdp->queue))) { + bioq_remove(&fdp->queue, bp); biofinish(bp, NULL, ENXIO); } disk_invalidate(&fdp->disk); disk_destroy(fdp->dev); devstat_remove_entry(&fdp->stats); - ata_free_name(atp->controller, atp->unit); + ata_free_name(atadev); ata_free_lun(&afd_lun_map, fdp->lun); free(fdp, M_AFD); + atadev->driver = NULL; } static int @@ -144,21 +145,20 @@ afd_sense(struct afd_softc *fdp) int count, error = 0; /* The IOMEGA Clik! doesn't support reading the cap page, fake it */ - if (!strncmp(ATA_PARAM(fdp->atp->controller, fdp->atp->unit)->model, - "IOMEGA Clik!", 12)) { + if (!strncmp(fdp->device->param->model, "IOMEGA Clik!", 12)) { fdp->transfersize = 64; fdp->cap.transfer_rate = 500; fdp->cap.heads = 1; fdp->cap.sectors = 2; fdp->cap.cylinders = 39441; fdp->cap.sector_size = 512; - atapi_test_ready(fdp->atp); + atapi_test_ready(fdp->device); return 0; } /* get drive capabilities, some drives needs this repeated */ for (count = 0 ; count < 5 ; count++) { - if (!(error = atapi_queue_cmd(fdp->atp, ccb, (caddr_t)&fdp->cap, + if (!(error = atapi_queue_cmd(fdp->device, ccb, (caddr_t)&fdp->cap, sizeof(struct afd_cappage), ATPR_F_READ, 30, NULL, NULL))) break; @@ -175,27 +175,24 @@ static void afd_describe(struct afd_softc *fdp) { if (bootverbose) { - ata_printf(fdp->atp->controller, fdp->atp->unit, + ata_prtdev(fdp->device, "<%.40s/%.8s> rewriteable drive at ata%d as %s\n", - ATA_PARAM(fdp->atp->controller, fdp->atp->unit)->model, - ATA_PARAM(fdp->atp->controller, fdp->atp->unit)->revision, - device_get_unit(fdp->atp->controller->dev), - (fdp->atp->unit == ATA_MASTER) ? "master" : "slave"); - ata_printf(fdp->atp->controller, fdp->atp->unit, + fdp->device->param->model, fdp->device->param->revision, + device_get_unit(fdp->device->channel->dev), + (fdp->device->unit == ATA_MASTER) ? "master" : "slave"); + ata_prtdev(fdp->device, "%luMB (%u sectors), %u cyls, %u heads, %u S/T, %u B/S\n", (fdp->cap.cylinders * fdp->cap.heads * fdp->cap.sectors) / ((1024L * 1024L) / fdp->cap.sector_size), fdp->cap.cylinders * fdp->cap.heads * fdp->cap.sectors, fdp->cap.cylinders, fdp->cap.heads, fdp->cap.sectors, fdp->cap.sector_size); - ata_printf(fdp->atp->controller, fdp->atp->unit, "%dKB/s,", - fdp->lun, fdp->cap.transfer_rate/8); + ata_prtdev(fdp->device, "%dKB/s,", fdp->lun, fdp->cap.transfer_rate/8); if (fdp->transfersize) printf(" transfer limit %d blks,", fdp->transfersize); - printf(" %s\n", ata_mode2str(fdp->atp->controller->mode[ - ATA_DEV(fdp->atp->unit)])); + printf(" %s\n", ata_mode2str(fdp->device->mode)); if (fdp->cap.medium_type) { - ata_printf(fdp->atp->controller, fdp->atp->unit, "Medium: "); + ata_prtdev(fdp->device, "Medium: "); switch (fdp->cap.medium_type) { case MFD_2DD: printf("720KB DD disk"); break; @@ -217,16 +214,14 @@ afd_describe(struct afd_softc *fdp) printf("\n"); } else { - ata_printf(fdp->atp->controller, fdp->atp->unit, - "%luMB <%.40s> [%d/%d/%d] at ata%d-%s %s\n", + ata_prtdev(fdp->device, "%luMB <%.40s> [%d/%d/%d] at ata%d-%s %s\n", (fdp->cap.cylinders * fdp->cap.heads * fdp->cap.sectors) / - ((1024L * 1024L) / fdp->cap.sector_size), - ATA_PARAM(fdp->atp->controller, fdp->atp->unit)->model, + ((1024L * 1024L) / fdp->cap.sector_size), + fdp->device->param->model, fdp->cap.cylinders, fdp->cap.heads, fdp->cap.sectors, - device_get_unit(fdp->atp->controller->dev), - (fdp->atp->unit == ATA_MASTER) ? "master" : "slave", - ata_mode2str(fdp->atp->controller-> - mode[ATA_DEV(fdp->atp->unit)])); + device_get_unit(fdp->device->channel->dev), + (fdp->device->unit == ATA_MASTER) ? "master" : "slave", + ata_mode2str(fdp->device->mode)); } } @@ -236,16 +231,15 @@ afdopen(dev_t dev, int flags, int fmt, struct thread *td) struct afd_softc *fdp = dev->si_drv1; struct disklabel *label = &fdp->disk.d_label; - atapi_test_ready(fdp->atp); + atapi_test_ready(fdp->device); if (count_dev(dev) == 1) afd_prevent_allow(fdp, 1); if (afd_sense(fdp)) - ata_printf(fdp->atp->controller, fdp->atp->unit, - "sense media type failed\n"); + ata_prtdev(fdp->device, "sense media type failed\n"); - fdp->atp->flags &= ~ATAPI_F_MEDIA_CHANGED; + fdp->device->flags &= ~ATA_D_MEDIA_CHANGED; bzero(label, sizeof *label); label->d_secsize = fdp->cap.sector_size; @@ -294,21 +288,21 @@ afdstrategy(struct bio *bp) struct afd_softc *fdp = bp->bio_dev->si_drv1; int s; - if (fdp->atp->flags & ATAPI_F_DETACHING) { + if (fdp->device->flags & ATA_D_DETACHING) { biofinish(bp, NULL, ENXIO); return; } s = splbio(); bioqdisksort(&fdp->queue, bp); - ata_start(fdp->atp->controller); + ata_start(fdp->device->channel); splx(s); } void -afd_start(struct atapi_softc *atp) +afd_start(struct ata_device *atadev) { - struct afd_softc *fdp = atp->driver; + struct afd_softc *fdp = atadev->driver; struct bio *bp = bioq_first(&fdp->queue); u_int32_t lba; u_int16_t count; @@ -321,7 +315,7 @@ afd_start(struct atapi_softc *atp) bioq_remove(&fdp->queue, bp); /* should reject all queued entries if media have changed. */ - if (fdp->atp->flags & ATAPI_F_MEDIA_CHANGED) { + if (fdp->device->flags & ATA_D_MEDIA_CHANGED) { biofinish(bp, NULL, EIO); return; } @@ -348,7 +342,7 @@ afd_start(struct atapi_softc *atp) ccb[7] = fdp->transfersize>>8; ccb[8] = fdp->transfersize; - atapi_queue_cmd(fdp->atp, ccb, data_ptr, + atapi_queue_cmd(fdp->device, ccb, data_ptr, fdp->transfersize * fdp->cap.sector_size, (bp->bio_cmd == BIO_READ) ? ATPR_F_READ : 0, 30, afd_partial_done, bp); @@ -365,7 +359,7 @@ afd_start(struct atapi_softc *atp) ccb[7] = count>>8; ccb[8] = count; - atapi_queue_cmd(fdp->atp, ccb, data_ptr, count * fdp->cap.sector_size, + atapi_queue_cmd(fdp->device, ccb, data_ptr, count * fdp->cap.sector_size, (bp->bio_cmd == BIO_READ) ? ATPR_F_READ : 0, 30, afd_done, bp); } @@ -417,7 +411,7 @@ afd_eject(struct afd_softc *fdp, int close) return 0; if ((error = afd_prevent_allow(fdp, 0))) return error; - fdp->atp->flags |= ATAPI_F_MEDIA_CHANGED; + fdp->device->flags |= ATA_D_MEDIA_CHANGED; return afd_start_stop(fdp, 2); } @@ -427,7 +421,7 @@ afd_start_stop(struct afd_softc *fdp, int start) int8_t ccb[16] = { ATAPI_START_STOP, 0, 0, 0, start, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - return atapi_queue_cmd(fdp->atp, ccb, NULL, 0, 0, 30, NULL, NULL); + return atapi_queue_cmd(fdp->device, ccb, NULL, 0, 0, 30, NULL, NULL); } static int @@ -436,8 +430,7 @@ afd_prevent_allow(struct afd_softc *fdp, int lock) int8_t ccb[16] = { ATAPI_PREVENT_ALLOW, 0, 0, 0, lock, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - if (!strncmp(ATA_PARAM(fdp->atp->controller, fdp->atp->unit)->model, - "IOMEGA Clik!", 12)) + if (!strncmp(fdp->device->param->model, "IOMEGA Clik!", 12)) return 0; - return atapi_queue_cmd(fdp->atp, ccb, NULL, 0, 0, 30, NULL, NULL); + return atapi_queue_cmd(fdp->device, ccb, NULL, 0, 0, 30, NULL, NULL); } diff --git a/sys/dev/ata/atapi-fd.h b/sys/dev/ata/atapi-fd.h index a8e80ba..8de3e19 100644 --- a/sys/dev/ata/atapi-fd.h +++ b/sys/dev/ata/atapi-fd.h @@ -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 @@ -69,7 +69,7 @@ struct afd_cappage { }; struct afd_softc { - struct atapi_softc *atp; /* controller structure */ + struct ata_device *device; /* device softc */ int lun; /* logical device unit */ int transfersize; /* max size of each transfer */ struct bio_queue_head queue; /* queue of i/o requests */ diff --git a/sys/dev/ata/atapi-tape.c b/sys/dev/ata/atapi-tape.c index f4aac19..5500a35 100644 --- a/sys/dev/ata/atapi-tape.c +++ b/sys/dev/ata/atapi-tape.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 @@ -85,7 +85,7 @@ static u_int64_t ast_total = 0; static MALLOC_DEFINE(M_AST, "AST driver", "ATAPI tape driver buffers"); int -astattach(struct atapi_softc *atp) +astattach(struct ata_device *atadev) { struct ast_softc *stp; struct ast_readposition position; @@ -93,13 +93,13 @@ astattach(struct atapi_softc *atp) stp = malloc(sizeof(struct ast_softc), M_AST, M_NOWAIT | M_ZERO); if (!stp) { - ata_printf(atp->controller, atp->unit, "out of memory\n"); + ata_prtdev(atadev, "out of memory\n"); return -1; } - stp->atp = atp; + stp->device = atadev; stp->lun = ata_get_lun(&ast_lun_map); - ata_set_name(atp->controller, atp->unit, "ast", stp->lun); + ata_set_name(atadev, "ast", stp->lun); bioq_init(&stp->queue); if (ast_sense(stp)) { @@ -107,8 +107,7 @@ astattach(struct atapi_softc *atp) return -1; } - if (!strcmp(ATA_PARAM(stp->atp->controller, stp->atp->unit)->model, - "OnStream DI-30")) { + if (!strcmp(atadev->param->model, "OnStream DI-30")) { struct ast_transferpage transfer; struct ast_identifypage identify; @@ -138,27 +137,29 @@ astattach(struct atapi_softc *atp) dev->si_drv1 = stp; dev->si_iosize_max = 252 * DEV_BSIZE; stp->dev2 = dev; - stp->atp->flags |= ATAPI_F_MEDIA_CHANGED; - stp->atp->driver = stp; + stp->device->flags |= ATA_D_MEDIA_CHANGED; ast_describe(stp); + atadev->driver = stp; return 0; } -void -astdetach(struct atapi_softc *atp) +void +astdetach(struct ata_device *atadev) { - struct ast_softc *stp = atp->driver; + struct ast_softc *stp = atadev->driver; struct bio *bp; while ((bp = bioq_first(&stp->queue))) { + bioq_remove(&stp->queue, bp); biofinish(bp, NULL, ENXIO); } destroy_dev(stp->dev1); destroy_dev(stp->dev2); devstat_remove_entry(&stp->stats); - ata_free_name(atp->controller, atp->unit); + ata_free_name(atadev); ata_free_lun(&ast_lun_map, stp->lun); free(stp, M_AST); + atadev->driver = NULL; } static int @@ -193,20 +194,16 @@ static void ast_describe(struct ast_softc *stp) { if (bootverbose) { - ata_printf(stp->atp->controller, stp->atp->unit, - "<%.40s/%.8s> tape drive at ata%d as %s\n", - ATA_PARAM(stp->atp->controller, stp->atp->unit)->model, - ATA_PARAM(stp->atp->controller, stp->atp->unit)->revision, - device_get_unit(stp->atp->controller->dev), - (stp->atp->unit == ATA_MASTER) ? "master" : "slave"); - ata_printf(stp->atp->controller, stp->atp->unit, "%dKB/s, ", - stp->cap.max_speed); + ata_prtdev(stp->device, "<%.40s/%.8s> tape drive at ata%d as %s\n", + stp->device->param->model, stp->device->param->revision, + device_get_unit(stp->device->channel->dev), + (stp->device->unit == ATA_MASTER) ? "master" : "slave"); + ata_prtdev(stp->device, "%dKB/s, ", stp->cap.max_speed); printf("transfer limit %d blk%s, ", stp->cap.ctl, (stp->cap.ctl > 1) ? "s" : ""); printf("%dKB buffer, ", (stp->cap.buffer_size * DEV_BSIZE) / 1024); - printf("%s\n", ata_mode2str(stp->atp->controller->mode[ - ATA_DEV(stp->atp->unit)])); - ata_printf(stp->atp->controller, stp->atp->unit, "Medium: "); + printf("%s\n", ata_mode2str(stp->device->mode)); + ata_prtdev(stp->device, "Medium: "); switch (stp->cap.medium_type) { case 0x00: printf("none"); break; @@ -236,13 +233,11 @@ ast_describe(struct ast_softc *stp) printf("\n"); } else { - ata_printf(stp->atp->controller, stp->atp->unit, - "TAPE <%.40s> at ata%d-%s %s\n", - ATA_PARAM(stp->atp->controller, stp->atp->unit)->model, - device_get_unit(stp->atp->controller->dev), - (stp->atp->unit == ATA_MASTER) ? "master" : "slave", - ata_mode2str(stp->atp->controller-> - mode[ATA_DEV(stp->atp->unit)])); + ata_prtdev(stp->device, "TAPE <%.40s> at ata%d-%s %s\n", + stp->device->param->model, + device_get_unit(stp->device->channel->dev), + (stp->device->unit == ATA_MASTER) ? "master" : "slave", + ata_mode2str(stp->device->mode)); } } @@ -257,16 +252,15 @@ astopen(dev_t dev, int flags, int fmt, struct thread *td) if (count_dev(dev) > 1) return EBUSY; - atapi_test_ready(stp->atp); + atapi_test_ready(stp->device); if (stp->cap.lock) ast_prevent_allow(stp, 1); if (ast_sense(stp)) - ata_printf(stp->atp->controller, stp->atp->unit, - "sense media type failed\n"); + ata_prtdev(stp->device, "sense media type failed\n"); - stp->atp->flags &= ~ATAPI_F_MEDIA_CHANGED; + stp->device->flags &= ~ATA_D_MEDIA_CHANGED; stp->flags &= ~(F_DATA_WRITTEN | F_FM_WRITTEN); ast_total = 0; return 0; @@ -295,8 +289,7 @@ astclose(dev_t dev, int flags, int fmt, struct thread *td) stp->flags &= F_CTL_WARN; #ifdef AST_DEBUG - ata_printf(stp->atp->controller, stp->atp->unit, - "%llu total bytes transferred\n", ast_total); + ata_prtdev(stp->device, "%llu total bytes transferred\n", ast_total); #endif return 0; } @@ -419,7 +412,7 @@ aststrategy(struct bio *bp) struct ast_softc *stp = bp->bio_dev->si_drv1; int s; - if (stp->atp->flags & ATAPI_F_DETACHING) { + if (stp->device->flags & ATA_D_DETACHING) { biofinish(bp, NULL, ENXIO); return; } @@ -437,17 +430,16 @@ aststrategy(struct bio *bp) /* check for != blocksize requests */ if (bp->bio_bcount % stp->blksize) { - ata_printf(stp->atp->controller, stp->atp->unit, - "bad request, must be multiple of %d\n", stp->blksize); + ata_prtdev(stp->device, "transfers must be multiple of %d\n", + stp->blksize); biofinish(bp, NULL, EIO); return; } /* warn about transfers bigger than the device suggests */ - if (bp->bio_bcount > stp->blksize * stp->cap.ctl) { + if (bp->bio_bcount > stp->blksize * stp->cap.ctl) { if ((stp->flags & F_CTL_WARN) == 0) { - ata_printf(stp->atp->controller, stp->atp->unit, - "WARNING: CTL exceeded %ld>%d\n", + ata_prtdev(stp->device, "WARNING: CTL exceeded %ld>%d\n", bp->bio_bcount, stp->blksize * stp->cap.ctl); stp->flags |= F_CTL_WARN; } @@ -455,14 +447,14 @@ aststrategy(struct bio *bp) s = splbio(); bioq_insert_tail(&stp->queue, bp); - ata_start(stp->atp->controller); + ata_start(stp->device->channel); splx(s); } void -ast_start(struct atapi_softc *atp) +ast_start(struct ata_device *atadev) { - struct ast_softc *stp = atp->driver; + struct ast_softc *stp = atadev->driver; struct bio *bp = bioq_first(&stp->queue); u_int32_t blkcount; int8_t ccb[16]; @@ -487,7 +479,7 @@ ast_start(struct atapi_softc *atp) devstat_start_transaction(&stp->stats); - atapi_queue_cmd(stp->atp, ccb, bp->bio_data, blkcount * stp->blksize, + atapi_queue_cmd(stp->device, ccb, bp->bio_data, blkcount * stp->blksize, (bp->bio_cmd == BIO_READ) ? ATPR_F_READ : 0, 120, ast_done, bp); } @@ -506,7 +498,7 @@ ast_done(struct atapi_request *request) if (!(bp->bio_cmd == BIO_READ)) stp->flags |= F_DATA_WRITTEN; bp->bio_resid = bp->bio_bcount - request->donecount; - ast_total += (bp->bio_bcount - bp->bio_resid); + ast_total += (bp->bio_bcount - bp->bio_resid); } biofinish(bp, &stp->stats, 0); return 0; @@ -519,8 +511,8 @@ ast_mode_sense(struct ast_softc *stp, int page, void *pagebuf, int pagesize) 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; int error; - error = atapi_queue_cmd(stp->atp, ccb, pagebuf, pagesize, ATPR_F_READ, 10, - NULL, NULL); + error = atapi_queue_cmd(stp->device, ccb, pagebuf, pagesize, ATPR_F_READ, + 10, NULL, NULL); #ifdef AST_DEBUG atapi_dump("ast: mode sense ", pagebuf, pagesize); #endif @@ -534,12 +526,11 @@ ast_mode_select(struct ast_softc *stp, void *pagebuf, int pagesize) 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; #ifdef AST_DEBUG - ata_printf(stp->atp->controller, stp->atp->unit, - "modeselect pagesize=%d\n", pagesize); + ata_prtdev(stp->device, "modeselect pagesize=%d\n", pagesize); atapi_dump("mode select ", pagebuf, pagesize); #endif - return atapi_queue_cmd(stp->atp, ccb, pagebuf, pagesize, 0, 10, - NULL, NULL); + return atapi_queue_cmd(stp->device, ccb, pagebuf, pagesize, 0, + 10, NULL, NULL); } static int @@ -559,10 +550,10 @@ ast_write_filemark(struct ast_softc *stp, u_int8_t function) stp->flags |= F_FM_WRITTEN; } } - error = atapi_queue_cmd(stp->atp, ccb, NULL, 0, 0, 10, NULL, NULL); + error = atapi_queue_cmd(stp->device, ccb, NULL, 0, 0, 10, NULL, NULL); if (error) return error; - return atapi_wait_dsc(stp->atp, 10*60); + return atapi_wait_dsc(stp->device, 10*60); } static int @@ -573,7 +564,7 @@ ast_read_position(struct ast_softc *stp, int hard, 0, 0, 0, 0, 0, 0, 0, 0 }; int error; - error = atapi_queue_cmd(stp->atp, ccb, (caddr_t)position, + error = atapi_queue_cmd(stp->device, ccb, (caddr_t)position, sizeof(struct ast_readposition), ATPR_F_READ, 10, NULL, NULL); position->tape = ntohl(position->tape); @@ -587,7 +578,7 @@ ast_space(struct ast_softc *stp, u_int8_t function, int32_t count) int8_t ccb[16] = { ATAPI_SPACE, function, count>>16, count>>8, count, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - return atapi_queue_cmd(stp->atp, ccb, NULL, 0, 0, 60*60, NULL, NULL); + return atapi_queue_cmd(stp->device, ccb, NULL, 0, 0, 60*60, NULL, NULL); } static int @@ -598,10 +589,10 @@ ast_locate(struct ast_softc *stp, int hard, u_int32_t pos) 0, 0, 0, 0, 0, 0, 0, 0, 0 }; int error; - error = atapi_queue_cmd(stp->atp, ccb, NULL, 0, 0, 10, NULL, NULL); + error = atapi_queue_cmd(stp->device, ccb, NULL, 0, 0, 10, NULL, NULL); if (error) return error; - return atapi_wait_dsc(stp->atp, 60*60); + return atapi_wait_dsc(stp->device, 60*60); } static int @@ -610,7 +601,7 @@ ast_prevent_allow(struct ast_softc *stp, int lock) int8_t ccb[16] = { ATAPI_PREVENT_ALLOW, 0, 0, 0, lock, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - return atapi_queue_cmd(stp->atp, ccb, NULL, 0, 0,30, NULL, NULL); + return atapi_queue_cmd(stp->device, ccb, NULL, 0, 0,30, NULL, NULL); } static int @@ -622,13 +613,13 @@ ast_load_unload(struct ast_softc *stp, u_int8_t function) if ((function & SS_EJECT) && !stp->cap.eject) return 0; - error = atapi_queue_cmd(stp->atp, ccb, NULL, 0, 0, 10, NULL, NULL); + error = atapi_queue_cmd(stp->device, ccb, NULL, 0, 0, 10, NULL, NULL); if (error) return error; tsleep((caddr_t)&error, PRIBIO, "astlu", 1 * hz); if (function == SS_EJECT) return 0; - return atapi_wait_dsc(stp->atp, 60*60); + return atapi_wait_dsc(stp->device, 60*60); } static int @@ -638,10 +629,10 @@ ast_rewind(struct ast_softc *stp) 0, 0, 0, 0, 0, 0, 0, 0 }; int error; - error = atapi_queue_cmd(stp->atp, ccb, NULL, 0, 0, 10, NULL, NULL); + error = atapi_queue_cmd(stp->device, ccb, NULL, 0, 0, 10, NULL, NULL); if (error) return error; - return atapi_wait_dsc(stp->atp, 60*60); + return atapi_wait_dsc(stp->device, 60*60); } static int @@ -654,5 +645,5 @@ ast_erase(struct ast_softc *stp) if ((error = ast_rewind(stp))) return error; - return atapi_queue_cmd(stp->atp, ccb, NULL, 0, 0, 60*60, NULL, NULL); + return atapi_queue_cmd(stp->device, ccb, NULL, 0, 0, 60*60, NULL, NULL); } diff --git a/sys/dev/ata/atapi-tape.h b/sys/dev/ata/atapi-tape.h index 9a1f29a..e4dab20 100644 --- a/sys/dev/ata/atapi-tape.h +++ b/sys/dev/ata/atapi-tape.h @@ -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 @@ -144,14 +144,14 @@ struct ast_readposition { }; struct ast_softc { - struct atapi_softc *atp; /* controller structure */ + struct ata_device *device; /* device softc */ int lun; /* logical device unit */ int flags; /* device state flags */ #define F_CTL_WARN 0x0001 /* warned about CTL wrong? */ -#define F_WRITEPROTECT 0x0002 /* media is writeprotected */ -#define F_DATA_WRITTEN 0x0004 /* data has been written */ -#define F_FM_WRITTEN 0x0008 /* filemark has been written */ -#define F_ONSTREAM 0x0100 /* OnStream ADR device */ +#define F_WRITEPROTECT 0x0002 /* media is writeprotected */ +#define F_DATA_WRITTEN 0x0004 /* data has been written */ +#define F_FM_WRITTEN 0x0008 /* filemark has been written */ +#define F_ONSTREAM 0x0100 /* OnStream ADR device */ int blksize; /* block size (512 | 1024) */ struct bio_queue_head queue; /* queue of i/o requests */ |