diff options
-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 */ |