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