summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/dev/ata/ata-all.c267
-rw-r--r--sys/dev/ata/ata-all.h200
-rw-r--r--sys/dev/ata/ata-disk.c358
-rw-r--r--sys/dev/ata/ata-disk.h61
-rw-r--r--sys/dev/ata/ata-dma.c164
-rw-r--r--sys/dev/ata/atapi-all.c91
-rw-r--r--sys/dev/ata/atapi-all.h43
-rw-r--r--sys/dev/ata/atapi-cd.c216
-rw-r--r--sys/dev/ata/atapi-cd.h8
-rw-r--r--sys/dev/ata/atapi-fd.c51
-rw-r--r--sys/dev/ata/atapi-fd.h4
-rw-r--r--sys/dev/ata/atapi-tape.c95
-rw-r--r--sys/dev/ata/atapi-tape.h6
13 files changed, 992 insertions, 572 deletions
diff --git a/sys/dev/ata/ata-all.c b/sys/dev/ata/ata-all.c
index 68782d5..d82ad66 100644
--- a/sys/dev/ata/ata-all.c
+++ b/sys/dev/ata/ata-all.c
@@ -81,11 +81,12 @@ static int ata_detach(device_t);
static int ata_resume(device_t);
static void ata_boot_attach(void);
static void ata_intr(void *);
-static int32_t ata_getparam(struct ata_softc *, int32_t, u_int8_t);
-static int8_t *active2str(int32_t);
-static void bswap(int8_t *, int32_t);
-static void btrim(int8_t *, int32_t);
-static void bpack(int8_t *, int8_t *, int32_t);
+static int ata_getparam(struct ata_softc *, int, u_int8_t);
+static int ata_service(struct ata_softc *);
+static char *active2str(int);
+static void bswap(int8_t *, int);
+static void btrim(int8_t *, int);
+static void bpack(int8_t *, int8_t *, int);
/* local vars */
static devclass_t ata_devclass;
@@ -204,11 +205,11 @@ struct ata_pci_softc {
struct resource bmio_1;
struct resource bmio_2;
struct resource *irq;
- int32_t irqcnt;
+ int irqcnt;
};
-int32_t
-ata_find_dev(device_t dev, int32_t type, int32_t revid)
+int
+ata_find_dev(device_t dev, u_int32_t type, u_int32_t revid)
{
device_t *children, child;
int nchildren, i;
@@ -284,6 +285,9 @@ ata_pci_match(device_t dev)
return "Cypress 82C693 ATA controller";
break;
+ case 0x01021078:
+ return "Cyrix 5530 ATA33 controller";
+
case 0x74091022:
return "AMD 756 ATA66 controller";
@@ -293,6 +297,7 @@ ata_pci_match(device_t dev)
case 0x4d38105a:
return "Promise ATA66 controller";
+ case 0x0d30105a:
case 0x4d30105a:
return "Promise ATA100 controller";
@@ -318,9 +323,6 @@ ata_pci_match(device_t dev)
case 0x06401095:
return "CMD 640 ATA controller !WARNING! buggy chip data loss possible";
- case 0x01021078:
- return "Cyrix 5530 ATA controller (generic mode)";
-
/* unknown chipsets, try generic DMA if it seems possible */
default:
if (pci_get_class(dev) == PCIC_STORAGE &&
@@ -393,7 +395,7 @@ ata_pci_attach(device_t dev)
}
else {
if (type == 0x4d33105a || type == 0x4d38105a ||
- type == 0x4d30105a || type == 0x00041103) {
+ type == 0x4d30105a || type == 0x0d30105a || type == 0x00041103) {
/* Promise and HighPoint controllers support busmastering DMA */
rid = 0x20;
sc->bmio = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid,
@@ -411,21 +413,23 @@ ata_pci_attach(device_t dev)
(pci_read_config(dev, 0x53, 1) & ~0x01) | 0x02, 1);
break;
- case 0x4d38105a: /* Promise 66's need their clock changed */
- case 0x4d30105a: /* Promise 100's too */
+ case 0x4d38105a: /* Promise 66 & 100 need their clock changed */
+ case 0x4d30105a:
+ case 0x0d30105a:
outb(rman_get_start(sc->bmio) + 0x11,
inb(rman_get_start(sc->bmio) + 0x11) | 0x0a);
/* FALLTHROUGH */
- case 0x4d33105a: /* Promise's need burst mode to be turned on */
+ case 0x4d33105a: /* Promise (all) need burst mode to be turned on */
outb(rman_get_start(sc->bmio) + 0x1f,
inb(rman_get_start(sc->bmio) + 0x1f) | 0x01);
break;
- case 0x00041103: /* HighPoint's need to turn off interrupt prediction */
+ case 0x00041103: /* HighPoint */
switch (pci_get_revid(dev)) {
case 0x00:
case 0x01:
+ /* turn off interrupt prediction */
pci_write_config(dev, 0x51,
(pci_read_config(dev, 0x51, 1) & ~0x80), 1);
break;
@@ -433,10 +437,12 @@ ata_pci_attach(device_t dev)
case 0x02:
case 0x03:
case 0x04:
+ /* turn off interrupt prediction */
pci_write_config(dev, 0x51,
(pci_read_config(dev, 0x51, 1) & ~0x02), 1);
pci_write_config(dev, 0x55,
(pci_read_config(dev, 0x55, 1) & ~0x02), 1);
+ /* turn on interrupts */
pci_write_config(dev, 0x5a,
(pci_read_config(dev, 0x5a, 1) & ~0x10), 1);
@@ -761,8 +767,8 @@ ata_probe(device_t dev)
struct resource *altio = 0;
struct resource *bmio = 0;
int rid;
- int32_t ioaddr, altioaddr, bmaddr;
- int32_t mask = 0;
+ u_int32_t ioaddr, altioaddr, bmaddr;
+ int mask = 0;
u_int8_t status0, status1;
if (!scp || scp->flags & ATA_ATTACHED)
@@ -786,7 +792,7 @@ ata_probe(device_t dev)
if (altio)
altioaddr = rman_get_start(altio);
else
- altioaddr = ioaddr + ATA_IOSIZE;
+ altioaddr = ioaddr + ATA_IOSIZE - 2; /* pccard ?? XXX */
rid = ATA_BMADDR_RID;
bmio = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 0, ~0, 1, RF_ACTIVE);
@@ -953,8 +959,8 @@ ata_resume(device_t dev)
return 0;
}
-static int32_t
-ata_getparam(struct ata_softc *scp, int32_t device, u_int8_t command)
+static int
+ata_getparam(struct ata_softc *scp, int device, u_int8_t command)
{
struct ata_params *ata_parm;
int8_t buffer[DEV_BSIZE];
@@ -965,7 +971,7 @@ ata_getparam(struct ata_softc *scp, int32_t device, u_int8_t command)
DELAY(1);
/* enable interrupt */
- outb(scp->altioaddr, ATA_A_4BIT);
+ outb(scp->altioaddr + ATA_ALTCTRL, ATA_A_4BIT);
DELAY(1);
/* apparently some devices needs this repeated */
@@ -1006,7 +1012,7 @@ static void
ata_boot_attach(void)
{
struct ata_softc *scp;
- int32_t ctlr;
+ int ctlr;
/*
* run through all ata devices and look for real ATA & ATAPI devices
@@ -1063,7 +1069,7 @@ static void
ata_intr(void *data)
{
struct ata_softc *scp = (struct ata_softc *)data;
- u_int8_t dmastat;
+ u_int8_t dmastat = 0;
/*
* since we might share the IRQ with another device, and in some
@@ -1073,14 +1079,16 @@ ata_intr(void *data)
switch (scp->chiptype) {
#if NPCI > 0
case 0x00041103: /* HighPoint HPT366/368/370 */
- if (!((dmastat = ata_dmastatus(scp)) & ATA_BMSTAT_INTERRUPT))
+ if (((dmastat = ata_dmastatus(scp)) &
+ (ATA_BMSTAT_ACTIVE | ATA_BMSTAT_INTERRUPT)) != ATA_BMSTAT_INTERRUPT)
return;
outb(scp->bmaddr + ATA_BMSTAT_PORT, dmastat | ATA_BMSTAT_INTERRUPT);
break;
- case 0x4d33105a: /* Promise 33's */
- case 0x4d38105a: /* Promise 66's */
- case 0x4d30105a: /* Promise 100's */
+ case 0x4d33105a: /* Promise Ultra/Fasttrak 33 */
+ case 0x4d38105a: /* Promise Ultra/Fasttrak 66 */
+ case 0x4d30105a: /* Promise Ultra/Fasttrak 100 */
+ case 0x0d30105a: /* Promise OEM ATA100 */
{
struct ata_pci_softc *sc=device_get_softc(device_get_parent(scp->dev));
@@ -1088,37 +1096,39 @@ ata_intr(void *data)
((scp->unit) ? 0x00004000 : 0x00000400)))
return;
}
- /* FALLTHROUGH */
+
#endif
default:
if (scp->flags & ATA_DMA_ACTIVE) {
- if (!((dmastat = ata_dmastatus(scp)) & ATA_BMSTAT_INTERRUPT))
+ if (((dmastat = ata_dmastatus(scp)) &
+ (ATA_BMSTAT_ACTIVE|ATA_BMSTAT_INTERRUPT))!=ATA_BMSTAT_INTERRUPT)
return;
- else
- outb(scp->bmaddr+ATA_BMSTAT_PORT, dmastat|ATA_BMSTAT_INTERRUPT);
+ outb(scp->bmaddr + ATA_BMSTAT_PORT, dmastat | ATA_BMSTAT_INTERRUPT);
}
}
DELAY(1);
- /* get status, if drive is busy it didn't interrupt so return */
- if ((scp->status = inb(scp->ioaddr + ATA_STATUS)) & ATA_S_BUSY)
+ /* if drive is busy it didn't interrupt */
+ if (inb(scp->altioaddr + ATA_ALTSTAT) & ATA_S_BUSY)
return;
+ /* clear interrupt and get status */
+ scp->status = inb(scp->ioaddr + ATA_STATUS);
+
+ if (scp->status & ATA_S_ERROR)
+ scp->error = inb(scp->ioaddr + ATA_ERROR);
+
/* find & call the responsible driver to process this interrupt */
switch (scp->active) {
#if NATADISK > 0
case ATA_ACTIVE_ATA:
- if (!scp->running)
- return;
- if (ad_interrupt(scp->running) == ATA_OP_CONTINUES)
+ if (!scp->running || ad_interrupt(scp->running) == ATA_OP_CONTINUES)
return;
break;
#endif
#if NATAPICD > 0 || NATAPIFD > 0 || NATAPIST > 0
case ATA_ACTIVE_ATAPI:
- if (!scp->running)
- return;
- if (atapi_interrupt(scp->running) == ATA_OP_CONTINUES)
+ if (!scp->running || atapi_interrupt(scp->running) == ATA_OP_CONTINUES)
return;
break;
#endif
@@ -1132,20 +1142,29 @@ ata_intr(void *data)
case ATA_REINITING:
return;
- default:
case ATA_IDLE:
-#ifdef ATA_DEBUG
- {
- static int32_t intr_count = 0;
- if (intr_count++ < 10)
- ata_printf(scp, -1, "unwanted interrupt %d status = %02x\n",
- intr_count, scp->status);
+ if (scp->flags & ATA_QUEUED) {
+ scp->active = ATA_ACTIVE;
+ if (ata_service(scp) == ATA_OP_CONTINUES)
+ return;
}
+ /* FALLTHROUGH */
+
+ default:
+#ifdef ATA_DEBUG
+ {
+ static int intr_count = 0;
+
+ if (intr_count++ < 10)
+ ata_printf(scp, -1, "unwanted interrupt %d status = %02x\n",
+ intr_count, scp->status);
+ }
#endif
}
scp->active = ATA_IDLE;
scp->running = NULL;
ata_start(scp);
+ return;
}
void
@@ -1160,6 +1179,7 @@ ata_start(struct ata_softc *scp)
if (scp->active != ATA_IDLE)
return;
+
scp->active = ATA_ACTIVE;
#if NATADISK > 0
@@ -1174,9 +1194,10 @@ ata_start(struct ata_softc *scp)
TAILQ_REMOVE(&scp->ata_queue, ad_request, chain);
scp->active = ATA_ACTIVE_ATA;
scp->running = ad_request;
- ad_transfer(ad_request);
- return;
+ if (ad_transfer(ad_request) == ATA_OP_CONTINUES)
+ return;
}
+
#endif
#if NATAPICD > 0 || NATAPIFD > 0 || NATAPIST > 0
/* find & call the responsible driver if anything on the ATAPI queue */
@@ -1198,18 +1219,18 @@ ata_start(struct ata_softc *scp)
}
void
-ata_reset(struct ata_softc *scp, int32_t *mask)
+ata_reset(struct ata_softc *scp, int *mask)
{
- int32_t timeout;
+ int timeout;
u_int8_t status0 = ATA_S_BUSY, status1 = ATA_S_BUSY;
/* reset channel */
outb(scp->ioaddr + ATA_DRIVE, ATA_D_IBM | ATA_MASTER);
DELAY(1);
inb(scp->ioaddr + ATA_STATUS);
- outb(scp->altioaddr, ATA_A_IDS | ATA_A_RESET);
+ outb(scp->altioaddr + ATA_ALTCTRL, ATA_A_IDS | ATA_A_RESET);
DELAY(10000);
- outb(scp->altioaddr, ATA_A_IDS);
+ outb(scp->altioaddr + ATA_ALTCTRL, ATA_A_IDS);
DELAY(10000);
inb(scp->ioaddr + ATA_ERROR);
DELAY(3000);
@@ -1250,7 +1271,7 @@ ata_reset(struct ata_softc *scp, int32_t *mask)
DELAY(100);
}
DELAY(1);
- outb(scp->altioaddr, ATA_A_4BIT);
+ outb(scp->altioaddr + ATA_ALTCTRL, ATA_A_4BIT);
if (status0 & ATA_S_BUSY)
*mask &= ~0x01;
if (status1 & ATA_S_BUSY)
@@ -1288,10 +1309,10 @@ ata_reset(struct ata_softc *scp, int32_t *mask)
}
}
-int32_t
+int
ata_reinit(struct ata_softc *scp)
{
- int32_t mask = 0, omask;
+ int mask = 0, omask;
scp->active = ATA_REINITING;
scp->running = NULL;
@@ -1325,21 +1346,41 @@ ata_reinit(struct ata_softc *scp)
return 0;
}
-int32_t
-ata_wait(struct ata_softc *scp, int32_t device, u_int8_t mask)
+static int
+ata_service(struct ata_softc *scp)
{
- u_int32_t timeout = 0;
+ /* do we have a SERVICE request from the drive ? */
+ if ((scp->status & (ATA_S_SERVICE|ATA_S_ERROR|ATA_S_DRQ)) == ATA_S_SERVICE){
+ outb(scp->bmaddr + ATA_BMSTAT_PORT, ata_dmastatus(scp) | ATA_BMSTAT_INTERRUPT);
+#if NATADISK > 0
+ if ((inb(scp->ioaddr + ATA_DRIVE) & ATA_SLAVE) == ATA_MASTER) {
+ if ((scp->devices & ATA_ATA_MASTER) && scp->dev_softc[0])
+ return ad_service((struct ad_softc *)scp->dev_softc[0], 0);
+ }
+ else {
+ if ((scp->devices & ATA_ATA_SLAVE) && scp->dev_softc[1])
+ return ad_service((struct ad_softc *)scp->dev_softc[1], 0);
+ }
+#endif
+ }
+ return ATA_OP_FINISHED;
+}
+
+int
+ata_wait(struct ata_softc *scp, int device, u_int8_t mask)
+{
+ int timeout = 0;
DELAY(1);
while (timeout < 5000000) { /* timeout 5 secs */
- scp->status = inb(scp->ioaddr + ATA_STATUS);
+ scp->status = inb(scp->altioaddr + ATA_ALTSTAT);
/* if drive fails status, reselect the drive just to be sure */
if (scp->status == 0xff) {
ata_printf(scp, device, "no status, reselecting device\n");
outb(scp->ioaddr + ATA_DRIVE, ATA_D_IBM | device);
DELAY(1);
- scp->status = inb(scp->ioaddr + ATA_STATUS);
+ scp->status = inb(scp->altioaddr + ATA_ALTSTAT);
}
/* are we done ? */
@@ -1365,7 +1406,7 @@ ata_wait(struct ata_softc *scp, int32_t device, u_int8_t mask)
/* Wait 50 msec for bits wanted. */
timeout = 5000;
while (timeout--) {
- scp->status = inb(scp->ioaddr + ATA_STATUS);
+ scp->status = inb(scp->altioaddr + ATA_ALTSTAT);
if ((scp->status & mask) == mask) {
if (scp->status & ATA_S_ERROR)
scp->error = inb(scp->ioaddr + ATA_ERROR);
@@ -1376,17 +1417,26 @@ ata_wait(struct ata_softc *scp, int32_t device, u_int8_t mask)
return -1;
}
-int32_t
-ata_command(struct ata_softc *scp, int32_t device, u_int32_t command,
- u_int32_t cylinder, u_int32_t head, u_int32_t sector,
- u_int32_t count, u_int32_t feature, int32_t flags)
+int
+ata_command(struct ata_softc *scp, int device, u_int8_t command,
+ u_int16_t cylinder, u_int8_t head, u_int8_t sector,
+ u_int8_t count, u_int8_t feature, int flags)
{
+ int error = 0;
#ifdef ATA_DEBUG
ata_printf(scp, device, "ata_command: addr=%04x, cmd=%02x, "
- "c=%d, h=%d, s=%d, count=%d, flags=%02x\n",
- scp->ioaddr, command, cylinder, head, sector, count, flags);
+ "c=%d, h=%d, s=%d, count=%d, feature=%d, flags=%02x\n",
+ scp->ioaddr, command, cylinder, head, sector,
+ count, feature, flags);
#endif
+ /* disable interrupt from device */
+ if (scp->flags & ATA_QUEUED)
+ outb(scp->altioaddr + ATA_ALTCTRL, ATA_A_IDS | ATA_A_4BIT);
+
+ /* select device */
+ outb(scp->ioaddr + ATA_DRIVE, ATA_D_IBM | device);
+
/* ready to issue command ? */
if (ata_wait(scp, device, 0) < 0) {
ata_printf(scp, device,
@@ -1394,12 +1444,13 @@ ata_command(struct ata_softc *scp, int32_t device, u_int32_t command,
command, scp->status, scp->error);
return -1;
}
+
outb(scp->ioaddr + ATA_FEATURE, feature);
- outb(scp->ioaddr + ATA_CYL_LSB, cylinder);
+ outb(scp->ioaddr + ATA_COUNT, count);
+ outb(scp->ioaddr + ATA_SECTOR, sector);
outb(scp->ioaddr + ATA_CYL_MSB, cylinder >> 8);
+ outb(scp->ioaddr + ATA_CYL_LSB, cylinder);
outb(scp->ioaddr + ATA_DRIVE, ATA_D_IBM | device | head);
- outb(scp->ioaddr + ATA_SECTOR, sector);
- outb(scp->ioaddr + ATA_COUNT, count);
switch (flags) {
case ATA_WAIT_INTR:
@@ -1409,10 +1460,15 @@ ata_command(struct ata_softc *scp, int32_t device, u_int32_t command,
scp->active = ATA_WAIT_INTR;
asleep((caddr_t)scp, PRIBIO, "atacmd", 10 * hz);
outb(scp->ioaddr + ATA_CMD, command);
+
+ /* enable interrupt */
+ if (scp->flags & ATA_QUEUED)
+ outb(scp->altioaddr + ATA_ALTCTRL, ATA_A_4BIT);
+
if (await(PRIBIO, 10 * hz)) {
ata_printf(scp, device, "ata_command: timeout waiting for intr\n");
scp->active = ATA_IDLE;
- return -1;
+ error = -1;
}
break;
@@ -1427,9 +1483,7 @@ ata_command(struct ata_softc *scp, int32_t device, u_int32_t command,
ata_printf(scp, device,
"timeout waiting for command=%02x s=%02x e=%02x\n",
command, scp->status, scp->error);
- if (scp->active != ATA_REINITING)
- scp->active = ATA_IDLE;
- return -1;
+ error = -1;
}
if (scp->active != ATA_REINITING)
scp->active = ATA_IDLE;
@@ -1443,11 +1497,29 @@ ata_command(struct ata_softc *scp, int32_t device, u_int32_t command,
ata_printf(scp, device, "DANGER: illegal interrupt flag=%s\n",
active2str(flags));
}
- return 0;
+ /* enable interrupt */
+ if (scp->flags & ATA_QUEUED)
+ outb(scp->altioaddr + ATA_ALTCTRL, ATA_A_4BIT);
+ return error;
}
int
-ata_printf(struct ata_softc *scp, int32_t device, const char * fmt, ...)
+ata_get_lun(u_int32_t *map)
+{
+ int lun = ffs(~*map) - 1;
+
+ *map |= (1 << lun);
+ return lun;
+}
+
+void
+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;
@@ -1463,23 +1535,8 @@ ata_printf(struct ata_softc *scp, int32_t device, const char * fmt, ...)
return ret;
}
-int
-ata_get_lun(u_int32_t *map)
-{
- int lun = ffs(~*map) - 1;
-
- *map |= (1 << lun);
- return lun;
-}
-
-void
-ata_free_lun(u_int32_t *map, int lun)
-{
- *map &= ~(1 << lun);
-}
-
-int8_t *
-ata_mode2str(int32_t mode)
+char *
+ata_mode2str(int mode)
{
switch (mode) {
case ATA_PIO: return "BIOSPIO";
@@ -1497,8 +1554,8 @@ ata_mode2str(int32_t mode)
}
}
-int8_t
-ata_pio2mode(int32_t pio)
+int
+ata_pio2mode(int pio)
{
switch (pio) {
default:
@@ -1560,8 +1617,8 @@ ata_umode(struct ata_params *ap)
return -1;
}
-static int8_t *
-active2str(int32_t active)
+static char *
+active2str(int active)
{
static char buf[8];
@@ -1589,7 +1646,7 @@ active2str(int32_t active)
}
static void
-bswap(int8_t *buf, int32_t len)
+bswap(int8_t *buf, int len)
{
u_int16_t *ptr = (u_int16_t*)(buf + len);
@@ -1598,7 +1655,7 @@ bswap(int8_t *buf, int32_t len)
}
static void
-btrim(int8_t *buf, int32_t len)
+btrim(int8_t *buf, int len)
{
int8_t *ptr;
@@ -1610,9 +1667,9 @@ btrim(int8_t *buf, int32_t len)
}
static void
-bpack(int8_t *src, int8_t *dst, int32_t len)
+bpack(int8_t *src, int8_t *dst, int len)
{
- int32_t i, j, blank;
+ int i, j, blank;
for (i = j = blank = 0 ; i < len; i++) {
if (blank && src[i] == ' ') continue;
@@ -1633,14 +1690,14 @@ bpack(int8_t *src, int8_t *dst, int32_t len)
}
static void
-ata_change_mode(struct ata_softc *scp, int32_t device, int32_t mode)
+ata_change_mode(struct ata_softc *scp, int device, int mode)
{
- int32_t s = splbio();
+ int s = splbio();
while (scp->active != ATA_IDLE)
tsleep((caddr_t)&s, PRIBIO, "atachm", hz/4);
scp->active = ATA_REINITING;
- ata_dmainit(scp, device, ata_pmode(ATA_PARAM(scp, device)),
+ ata_dmainit(scp, device, ata_pmode(ATA_PARAM(scp, device)),
mode < ATA_DMA ? -1 : ata_wmode(ATA_PARAM(scp, device)),
mode < ATA_DMA ? -1 : ata_umode(ATA_PARAM(scp, device)));
scp->active = ATA_IDLE;
diff --git a/sys/dev/ata/ata-all.h b/sys/dev/ata/ata-all.h
index 811b989..3ab34ce 100644
--- a/sys/dev/ata/ata-all.h
+++ b/sys/dev/ata/ata-all.h
@@ -58,21 +58,30 @@
#define ATA_D_IBM 0xa0 /* 512 byte sectors, ECC */
#define ATA_CMD 0x07 /* command register */
+#define ATA_C_NOP 0x00 /* NOP command */
+#define ATA_C_F_FLUSHQUEUE 0x00 /* flush queued cmd's */
+#define ATA_C_F_AUTOPOLL 0x01 /* start autopoll function */
#define ATA_C_ATAPI_RESET 0x08 /* reset ATAPI device */
#define ATA_C_READ 0x20 /* read command */
#define ATA_C_WRITE 0x30 /* write command */
#define ATA_C_PACKET_CMD 0xa0 /* packet command */
#define ATA_C_ATAPI_IDENTIFY 0xa1 /* get ATAPI params*/
+#define ATA_C_SERVICE 0xa2 /* service command */
#define ATA_C_READ_MUL 0xc4 /* read multi command */
#define ATA_C_WRITE_MUL 0xc5 /* write multi command */
#define ATA_C_SET_MULTI 0xc6 /* set multi size command */
+#define ATA_C_READ_DMA_QUEUED 0xc7 /* read w/DMA QUEUED command */
#define ATA_C_READ_DMA 0xc8 /* read w/DMA command */
#define ATA_C_WRITE_DMA 0xca /* write w/DMA command */
+#define ATA_C_WRITE_DMA_QUEUED 0xcc /* write w/DMA QUEUED command */
#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_RCACHE 0xaa /* enable readahead cache */
#define ATA_C_F_ENAB_WCACHE 0x02 /* enable write cache */
+#define ATA_C_F_ENAB_SRVIRQ 0x5e /* enable service interrupt */
+#define ATA_C_F_ENAB_RCACHE 0xaa /* enable readahead cache */
+#define ATA_C_F_DIS_RELIRQ 0xdd /* disable release interrupt */
+#define ATA_C_F_DIS_SRVIRQ 0xde /* disable service interrupt */
#define ATA_STATUS 0x07 /* status register */
#define ATA_S_ERROR 0x01 /* error */
@@ -86,13 +95,14 @@
#define ATA_S_READY 0x40 /* drive ready */
#define ATA_S_BUSY 0x80 /* busy */
-#define ATA_ALTPORT 0x206 /* alternate status register */
-#define ATA_ALTPORT_PCCARD 0x8 /* ditto on PCCARD devices */
+#define ATA_ALTSTAT 0x02 /* alternate status register */
+#define ATA_ALTCTRL 0X02 /* alternate device control */
#define ATA_A_IDS 0x02 /* disable interrupts */
#define ATA_A_RESET 0x04 /* RESET controller */
#define ATA_A_4BIT 0x08 /* 4 head bits */
-#define ATA_ALTIOSIZE 0x01
+#define ATA_ALTPORT 0x204 /* alternate registers offset */
+#define ATA_ALTIOSIZE 0x01 /* alternate registers size */
/* misc defines */
#define ATA_MASTER 0x00
@@ -101,8 +111,7 @@
#define ATA_OP_FINISHED 0x00
#define ATA_OP_CONTINUES 0x01
#define ATA_DEV(unit) ((unit == ATA_MASTER) ? 0 : 1)
-#define ATA_PARAM(scp, unit) scp->dev_param[ATA_DEV(unit)]
-
+#define ATA_PARAM(scp, unit) (scp->dev_param[ATA_DEV(unit)])
/* busmaster DMA related defines */
#define ATA_BM_OFFSET1 0x08
@@ -156,25 +165,25 @@ struct ata_params {
#define ATAPI_PROTO_ATAPI 2
u_int16_t cylinders; /* number of cylinders */
- int16_t reserved2;
+ u_int16_t reserved2;
u_int16_t heads; /* # heads */
- int16_t unfbytespertrk; /* # unformatted bytes/track */
- int16_t unfbytes; /* # unformatted bytes/sector */
+ u_int16_t unfbytespertrk; /* # unformatted bytes/track */
+ u_int16_t unfbytes; /* # unformatted bytes/sector */
u_int16_t sectors; /* # sectors/track */
- int16_t vendorunique0[3];
- int8_t serial[20]; /* serial number */
- int16_t buffertype; /* buffer type */
+ u_int16_t vendorunique0[3];
+ u_int8_t serial[20]; /* serial number */
+ u_int16_t buffertype; /* buffer type */
#define ATA_BT_SINGLEPORTSECTOR 1 /* 1 port, 1 sector buffer */
#define ATA_BT_DUALPORTMULTI 2 /* 2 port, mult sector buffer */
#define ATA_BT_DUALPORTMULTICACHE 3 /* above plus track cache */
- int16_t buffersize; /* buf size, 512-byte units */
- int16_t necc; /* ecc bytes appended */
- int8_t revision[8]; /* firmware revision */
- int8_t model[40]; /* model name */
- int8_t nsecperint; /* sectors per interrupt */
- int8_t vendorunique1;
- int16_t usedmovsd; /* double word read/write? */
+ u_int16_t buffersize; /* buf size, 512-byte units */
+ u_int16_t necc; /* ecc bytes appended */
+ u_int8_t revision[8]; /* firmware revision */
+ u_int8_t model[40]; /* model name */
+ u_int8_t nsecperint; /* sectors per interrupt */
+ u_int8_t vendorunique1;
+ u_int16_t usedmovsd; /* double word read/write? */
u_int8_t vendorcap; /* vendor capabilities */
u_int8_t dmaflag :1; /* DMA supported - always 1 */
@@ -183,92 +192,103 @@ struct ata_params {
u_int8_t iordyflag :1; /* IORDY supported */
u_int8_t softreset :1; /* needs softreset when busy */
u_int8_t stdby_ovlap :1; /* standby/overlap supported */
- u_int8_t queuing :1; /* supports queuing overlap */
+ u_int8_t queueing :1; /* supports queuing overlap */
u_int8_t idmaflag :1; /* interleaved DMA supported */
- int16_t capvalidate; /* validation for above */
+ u_int16_t capvalidate; /* validation for above */
- int8_t vendorunique3;
- int8_t opiomode; /* PIO modes 0-2 */
- int8_t vendorunique4;
- int8_t odmamode; /* old DMA modes, not ATA-3 */
+ u_int8_t vendorunique3;
+ u_int8_t opiomode; /* PIO modes 0-2 */
+ u_int8_t vendorunique4;
+ u_int8_t odmamode; /* old DMA modes, not ATA-3 */
- int16_t atavalid; /* fields valid */
+ u_int16_t atavalid; /* fields valid */
#define ATA_FLAG_54_58 1 /* words 54-58 valid */
#define ATA_FLAG_64_70 2 /* words 64-70 valid */
#define ATA_FLAG_88 4 /* word 88 valid */
- int16_t currcyls;
- int16_t currheads;
- int16_t currsectors;
- int16_t currsize0;
- int16_t currsize1;
- int8_t currmultsect;
- int8_t multsectvalid;
- int32_t lbasize;
+ u_int16_t currcyls;
+ u_int16_t currheads;
+ u_int16_t currsectors;
+ u_int16_t currsize0;
+ u_int16_t currsize1;
+ u_int8_t currmultsect;
+ u_int8_t multsectvalid;
+ u_int32_t lbasize;
- int16_t sdmamodes; /* singleword DMA modes */
- int16_t wdmamodes; /* multiword DMA modes */
- int16_t apiomodes; /* advanced PIO modes */
+ u_int16_t sdmamodes; /* singleword DMA modes */
+ u_int16_t wdmamodes; /* multiword DMA modes */
+ u_int16_t apiomodes; /* advanced PIO modes */
u_int16_t mwdmamin; /* min. M/W DMA time/word ns */
u_int16_t mwdmarec; /* rec. M/W DMA time ns */
u_int16_t pioblind; /* min. PIO cycle w/o flow */
u_int16_t pioiordy; /* min. PIO cycle IORDY flow */
- int16_t reserved69;
- int16_t reserved70;
+ u_int16_t reserved69;
+ u_int16_t reserved70;
u_int16_t rlsovlap; /* rel time (us) for overlap */
u_int16_t rlsservice; /* rel time (us) for service */
- int16_t reserved73;
- int16_t reserved74;
- int16_t queuelen;
- int16_t reserved76;
- int16_t reserved77;
- int16_t reserved78;
- int16_t reserved79;
- int16_t versmajor;
- int16_t versminor;
- int16_t featsupp1;
- int16_t featsupp2;
- int16_t featsupp3;
- int16_t featenab1;
- int16_t featenab2;
- int16_t featenab3;
- int16_t udmamodes; /* UltraDMA modes */
- int16_t erasetime;
- int16_t enherasetime;
- int16_t apmlevel;
- int16_t masterpasswdrev;
+ u_int16_t reserved73;
+ u_int16_t reserved74;
+ u_int16_t queuelen:5;
+ u_int16_t :11;
+ u_int16_t reserved76;
+ u_int16_t reserved77;
+ u_int16_t reserved78;
+ u_int16_t reserved79;
+ u_int16_t versmajor;
+ u_int16_t versminor;
+ u_int16_t featsupp1; /* 82 */
+ u_int16_t supmicrocode:1;
+ u_int16_t supqueued:1;
+ u_int16_t supcfa:1;
+ u_int16_t supapm:1;
+ u_int16_t suprmsn:1;
+ u_int16_t :11;
+ u_int16_t featsupp3; /* 84 */
+ u_int16_t featenab1; /* 85 */
+ u_int16_t enabmicrocode:1;
+ u_int16_t enabqueued:1;
+ u_int16_t enabcfa:1;
+ u_int16_t enabapm:1;
+ u_int16_t enabrmsn:1;
+ u_int16_t :11;
+ u_int16_t featenab3; /* 87 */
+ u_int16_t udmamodes; /* UltraDMA modes */
+ u_int16_t erasetime;
+ u_int16_t enherasetime;
+ u_int16_t apmlevel;
+ u_int16_t masterpasswdrev;
u_int16_t masterhwres :8;
u_int16_t slavehwres :5;
u_int16_t cblid :1;
u_int16_t reserved93_1415 :2;
- int16_t reserved94[32];
- int16_t rmvstat;
- int16_t securstat;
- int16_t reserved129[30];
- int16_t cfapwrmode;
- int16_t reserved161[84];
- int16_t integrity;
+ u_int16_t reserved94[32];
+ u_int16_t rmvstat;
+ u_int16_t securstat;
+ u_int16_t reserved129[30];
+ u_int16_t cfapwrmode;
+ u_int16_t reserved161[84];
+ u_int16_t integrity;
};
/* structure describing an ATA device */
struct ata_softc {
struct device *dev; /* device handle */
- int32_t unit; /* unit on this controller */
+ int unit; /* unit on this controller */
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 */
- int32_t ioaddr; /* physical port addr */
- int32_t altioaddr; /* physical alt port addr */
- int32_t bmaddr; /* physical bus master port */
- int32_t chiptype; /* pciid of controller chip */
+ u_int32_t ioaddr; /* physical port addr */
+ u_int32_t altioaddr; /* physical alt port addr */
+ u_int32_t bmaddr; /* physical bus master port */
+ u_int32_t chiptype; /* pciid of controller chip */
+ u_int32_t alignment; /* dma engine min alignment */
struct ata_params *dev_param[2]; /* ptr to devices params */
void *dev_softc[2]; /* ptr to devices softc's */
- struct ata_dmaentry *dmatab[2]; /* DMA transfer tables */
- int32_t mode[2]; /* transfer mode for devices */
+ int mode[2]; /* transfer mode for devices */
#define ATA_PIO 0x00
#define ATA_PIO0 0x08
#define ATA_PIO1 0x09
@@ -281,13 +301,14 @@ struct ata_softc {
#define ATA_UDMA4 0x44
#define ATA_UDMA5 0x45
- int32_t flags; /* controller flags */
+ int flags; /* controller flags */
#define ATA_DMA_ACTIVE 0x01
#define ATA_ATAPI_DMA_RO 0x02
#define ATA_USE_16BIT 0x04
#define ATA_ATTACHED 0x08
+#define ATA_QUEUED 0x10
- int32_t devices; /* what is present */
+ int devices; /* what is present */
#define ATA_ATA_MASTER 0x01
#define ATA_ATA_SLAVE 0x02
#define ATA_ATAPI_MASTER 0x04
@@ -295,7 +316,7 @@ struct ata_softc {
u_int8_t status; /* last controller status */
u_int8_t error; /* last controller error */
- int32_t active; /* active processing request */
+ int active; /* active processing request */
#define ATA_IDLE 0x0
#define ATA_IMMEDIATE 0x1
#define ATA_WAIT_INTR 0x2
@@ -315,24 +336,25 @@ extern devclass_t ata_devclass;
/* public prototypes */
void ata_start(struct ata_softc *);
-void ata_reset(struct ata_softc *, int32_t *);
-int32_t ata_reinit(struct ata_softc *);
-int32_t ata_wait(struct ata_softc *, int32_t, u_int8_t);
-int32_t ata_command(struct ata_softc *, int32_t, u_int32_t, u_int32_t, u_int32_t, u_int32_t, u_int32_t, u_int32_t, int32_t);
-int ata_printf(struct ata_softc *, int32_t, const char *, ...) __printflike(3, 4);
+void ata_reset(struct ata_softc *, int *);
+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_int16_t, u_int8_t, u_int8_t, u_int8_t, u_int8_t, int);
+int ata_printf(struct ata_softc *, int, const char *, ...) __printflike(3, 4);
int ata_get_lun(u_int32_t *);
void ata_free_lun(u_int32_t *, int);
-int8_t *ata_mode2str(int32_t);
-int8_t ata_pio2mode(int32_t);
+char *ata_mode2str(int);
+int ata_pio2mode(int);
int ata_pmode(struct ata_params *);
int ata_wmode(struct ata_params *);
int ata_umode(struct ata_params *);
#if NPCI > 0
-int32_t ata_find_dev(device_t, int32_t, int32_t);
+int ata_find_dev(device_t, u_int32_t, u_int32_t);
#endif
-void ata_dmainit(struct ata_softc *, int32_t, int32_t, int32_t, int32_t);
-int32_t ata_dmasetup(struct ata_softc *, int32_t, int8_t *, int32_t, int32_t);
-void ata_dmastart(struct ata_softc *);
-int32_t ata_dmastatus(struct ata_softc *);
-int32_t ata_dmadone(struct ata_softc *);
+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 *);
diff --git a/sys/dev/ata/ata-disk.c b/sys/dev/ata/ata-disk.c
index 86d945c..4f12574 100644
--- a/sys/dev/ata/ata-disk.c
+++ b/sys/dev/ata/ata-disk.c
@@ -75,8 +75,11 @@ static struct cdevsw ad_cdevsw = {
static struct cdevsw addisk_cdevsw;
/* prototypes */
+static void ad_invalidatequeue(struct ad_softc *, struct ad_request *);
+static int ad_tagsupported(struct ad_softc *);
static void ad_timeout(struct ad_request *);
-static int32_t ad_version(u_int16_t);
+static void ad_free(struct ad_request *);
+static int ad_version(u_int16_t);
/* internal vars */
static u_int32_t adp_lun_map = 0;
@@ -87,11 +90,11 @@ MALLOC_DEFINE(M_AD, "AD driver", "ATA disk driver");
#define AD_PARAM ATA_PARAM(adp->controller, adp->unit)
void
-ad_attach(struct ata_softc *scp, int32_t device)
+ad_attach(struct ata_softc *scp, int device)
{
struct ad_softc *adp;
dev_t dev;
- int32_t secsperint;
+ int secsperint;
if (!(adp = malloc(sizeof(struct ad_softc), M_AD, M_NOWAIT))) {
@@ -113,7 +116,8 @@ ad_attach(struct ata_softc *scp, int32_t device)
if (AD_PARAM->cylinders == 16383 && adp->total_secs < AD_PARAM->lbasize)
adp->total_secs = AD_PARAM->lbasize;
- if (AD_PARAM->atavalid & ATA_FLAG_54_58 && AD_PARAM->lbasize)
+ if (ad_version(AD_PARAM->versmajor) &&
+ AD_PARAM->atavalid & ATA_FLAG_54_58 && AD_PARAM->lbasize)
adp->flags |= AD_F_LBA_ENABLED;
/* use multiple sectors/interrupt if device supports it */
@@ -122,7 +126,7 @@ ad_attach(struct ata_softc *scp, int32_t device)
secsperint = max(1, min(AD_PARAM->nsecperint, 16));
if (!ata_command(adp->controller, adp->unit, ATA_C_SET_MULTI,
0, 0, 0, secsperint, 0, ATA_WAIT_INTR) &&
- ata_wait(adp->controller, adp->unit, ATA_S_READY) >= 0)
+ !ata_wait(adp->controller, adp->unit, 0))
adp->transfersize *= secsperint;
}
@@ -136,15 +140,24 @@ ad_attach(struct ata_softc *scp, int32_t device)
printf("ad%d: enabling write cache failed\n", adp->lun);
/* use DMA if drive & controller supports it */
- ata_dmainit(adp->controller, adp->unit, ata_pmode(AD_PARAM),
- ata_wmode(AD_PARAM), ata_umode(AD_PARAM));
+ ata_dmainit(adp->controller, adp->unit,
+ ata_pmode(AD_PARAM), ata_wmode(AD_PARAM), ata_umode(AD_PARAM));
- /* use tagged queueing if supported (not yet) */
- if ((adp->num_tags = (AD_PARAM->queuelen & 0x1f) + 1))
+ /* use tagged queueing if supported */
+ if (ad_tagsupported(adp)) {
+ adp->num_tags = AD_PARAM->queuelen;
adp->flags |= AD_F_TAG_ENABLED;
+ adp->controller->flags |= ATA_QUEUED;
+ if (ata_command(adp->controller, adp->unit, ATA_C_SETFEATURES,
+ 0, 0, 0, 0, ATA_C_F_DIS_RELIRQ, ATA_WAIT_INTR))
+ printf("ad%d: disabling release interrupt failed\n", adp->lun);
+ if (ata_command(adp->controller, adp->unit, ATA_C_SETFEATURES,
+ 0, 0, 0, 0, ATA_C_F_DIS_SRVIRQ, ATA_WAIT_INTR))
+ printf("ad%d: disabling service interrupt failed\n", adp->lun);
+ }
if (bootverbose) {
- printf("ad%d: <%.40s/%.8s> ATA-%d disk at ata%d as %s\n",
+ printf("ad%d: <%.40s/%.8s> ATA-%d disk at ata%d-%s\n",
adp->lun, AD_PARAM->model, AD_PARAM->revision,
ad_version(AD_PARAM->versmajor), device_get_unit(scp->dev),
(adp->unit == ATA_MASTER) ? "master" : "slave");
@@ -155,8 +168,9 @@ ad_attach(struct ata_softc *scp, int32_t device)
adp->total_secs / (adp->heads * adp->sectors),
adp->heads, adp->sectors, DEV_BSIZE);
- printf("ad%d: %d secs/int, %d depth queue, %s\n",
- adp->lun, adp->transfersize / DEV_BSIZE, adp->num_tags,
+ printf("ad%d: %d secs/int, %d depth queue, %s%s\n",
+ adp->lun, adp->transfersize / DEV_BSIZE, adp->num_tags + 1,
+ (adp->flags & AD_F_TAG_ENABLED) ? "tagged " : "",
ata_mode2str(adp->controller->mode[ATA_DEV(adp->unit)]));
printf("ad%d: piomode=%d dmamode=%d udmamode=%d cblid=%d\n",
@@ -165,11 +179,12 @@ ad_attach(struct ata_softc *scp, int32_t device)
}
else
- printf("ad%d: %luMB <%.40s> [%d/%d/%d] at ata%d-%s using %s\n",
+ printf("ad%d: %luMB <%.40s> [%d/%d/%d] at ata%d-%s %s%s\n",
adp->lun, adp->total_secs / ((1024L * 1024L) / DEV_BSIZE),
AD_PARAM->model, adp->total_secs / (adp->heads * adp->sectors),
adp->heads, adp->sectors, device_get_unit(scp->dev),
(adp->unit == ATA_MASTER) ? "master" : "slave",
+ (adp->flags & AD_F_TAG_ENABLED) ? "tagged " : "",
ata_mode2str(adp->controller->mode[ATA_DEV(adp->unit)]));
devstat_add_entry(&adp->stats, "ad", adp->lun, DEV_BSIZE,
@@ -196,7 +211,7 @@ ad_detach(struct ad_softc *adp)
}
static int
-adopen(dev_t dev, int32_t flags, int32_t fmt, struct proc *p)
+adopen(dev_t dev, int flags, int fmt, struct proc *p)
{
struct ad_softc *adp = dev->si_drv1;
struct disklabel *dl;
@@ -216,7 +231,7 @@ static void
adstrategy(struct bio *bp)
{
struct ad_softc *adp = bp->bio_dev->si_drv1;
- int32_t s;
+ int s;
/* if it's a null transfer, return immediatly. */
if (bp->bio_bcount == 0) {
@@ -251,7 +266,7 @@ addump(dev_t dev)
ata_reinit(adp->controller);
while (count > 0) {
- void *va;
+ caddr_t va;
DELAY(1000);
if (is_physical_memory(addr))
va = pmap_kenter_temporary(trunc_page(addr));
@@ -262,7 +277,7 @@ addump(dev_t dev)
request.device = adp;
request.blockaddr = blkno;
request.bytecount = PAGE_SIZE;
- request.data = (int8_t *) va;
+ request.data = va;
while (request.bytecount > 0) {
ad_transfer(&request);
@@ -299,10 +314,19 @@ ad_start(struct ad_softc *adp)
{
struct bio *bp = bioq_first(&adp->queue);
struct ad_request *request;
+ int tag = 0;
if (!bp)
return;
+ /* if tagged queueing enabled get free tag */
+ if (adp->flags & AD_F_TAG_ENABLED) {
+ while (tag <= adp->num_tags && adp->tags[tag])
+ tag++;
+ if (tag > adp->num_tags )
+ return;
+ }
+
if (!(request = malloc(sizeof(struct ad_request), M_AD, M_NOWAIT))) {
printf("ad%d: out of memory in start\n", adp->lun);
return;
@@ -315,7 +339,15 @@ ad_start(struct ad_softc *adp)
request->blockaddr = bp->bio_pblkno;
request->bytecount = bp->bio_bcount;
request->data = bp->bio_data;
+ request->tag = tag;
request->flags = (bp->bio_cmd == BIO_READ) ? ADR_F_READ : 0;
+ 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;
+ }
+
+ /* insert in tag array */
+ adp->tags[tag] = request;
/* remove from drive queue */
bioq_remove(&adp->queue, bp);
@@ -324,7 +356,7 @@ ad_start(struct ad_softc *adp)
TAILQ_INSERT_TAIL(&adp->controller->ata_queue, request, chain);
}
-void
+int
ad_transfer(struct ad_request *request)
{
struct ad_softc *adp;
@@ -373,17 +405,73 @@ 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,
- (void *)request->data, request->bytecount,
- (request->flags & ADR_F_READ))) {
+ if (adp->controller->mode[ATA_DEV(adp->unit)] >= ATA_DMA &&
+ !ata_dmasetup(adp->controller, adp->unit, request->dmatab,
+ request->data, request->bytecount)) {
request->flags |= ADR_F_DMA_USED;
- cmd = request->flags&ADR_F_READ ? ATA_C_READ_DMA : ATA_C_WRITE_DMA;
request->currentsize = request->bytecount;
+
+ /* do we have tags enabled ? */
+ if (adp->flags & AD_F_TAG_ENABLED) {
+ cmd = (request->flags & ADR_F_READ) ?
+ ATA_C_READ_DMA_QUEUED : ATA_C_WRITE_DMA_QUEUED;
+
+ if (ata_command(adp->controller, adp->unit, cmd,
+ cylinder, head, sector, request->tag << 3,
+ count, ATA_IMMEDIATE)) {
+ printf("ad%d: error executing command", adp->lun);
+ goto transfer_failed;
+ }
+ if (ata_wait(adp->controller, adp->unit, ATA_S_READY)) {
+ printf("ad%d: timeout waiting for READY\n", adp->lun);
+ goto transfer_failed;
+ }
+ adp->outstanding++;
+
+ /* if ATA bus RELEASE check for SERVICE */
+ if (adp->flags & AD_F_TAG_ENABLED &&
+ inb(adp->controller->ioaddr + ATA_IREASON) & ATA_I_RELEASE){
+ return ad_service(adp, 1);
+ }
+ }
+ else {
+ cmd = (request->flags & ADR_F_READ) ?
+ ATA_C_READ_DMA : ATA_C_WRITE_DMA;
+
+ if (ata_command(adp->controller, adp->unit, cmd, cylinder,
+ head, sector, count, 0, ATA_IMMEDIATE)) {
+ printf("ad%d: error executing command", adp->lun);
+ goto transfer_failed;
+ }
+#if 0
+ /*
+ * well this should be here acording to specs, but
+ * 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)) {
+ printf("ad%d: timeout waiting for data phase\n", adp->lun);
+ goto transfer_failed;
+ }
+#endif
+ }
+
+ /* check for possible error from controller */
+ if (adp->controller->status & ATA_S_ERROR) {
+ printf("ad%d: error executing transfer cmd\n", adp->lun);
+ goto transfer_failed;
+ }
+
+ /* start transfer, return and wait for interrupt */
+ ata_dmastart(adp->controller, adp->unit,
+ request->dmatab, request->flags & ADR_F_READ);
+ return ATA_OP_CONTINUES;
}
/* does this drive support multi sector transfers ? */
- else if (request->currentsize > DEV_BSIZE)
+ if (request->currentsize > DEV_BSIZE)
cmd = request->flags&ADR_F_READ ? ATA_C_READ_MUL : ATA_C_WRITE_MUL;
/* just plain old single sector transfer */
@@ -395,12 +483,6 @@ ad_transfer(struct ad_request *request)
printf("ad%d: error executing command", adp->lun);
goto transfer_failed;
}
-
- /* if this is a DMA transfer, start it, return and wait for interrupt */
- if (request->flags & ADR_F_DMA_USED) {
- ata_dmastart(adp->controller);
- return;
- }
}
/* calculate this transfer length */
@@ -408,7 +490,7 @@ ad_transfer(struct ad_request *request)
/* if this is a PIO read operation, return and wait for interrupt */
if (request->flags & ADR_F_READ)
- return;
+ return ATA_OP_CONTINUES;
/* ready to write PIO data ? */
if (ata_wait(adp->controller, adp->unit,
@@ -426,10 +508,11 @@ ad_transfer(struct ad_request *request)
outsl(adp->controller->ioaddr + ATA_DATA,
(void *)((uintptr_t)request->data + request->donecount),
request->currentsize / sizeof(int32_t));
- return;
+ return ATA_OP_CONTINUES;
transfer_failed:
untimeout((timeout_t *)ad_timeout, request, request->timeout_handle);
+ ad_invalidatequeue(adp, request);
printf(" - resetting\n");
/* if retries still permit, reinject this request */
@@ -442,34 +525,29 @@ transfer_failed:
request->bp->bio_resid = request->bytecount;
devstat_end_transaction_bio(&adp->stats, request->bp);
biodone(request->bp);
- free(request, M_AD);
+ ad_free(request);
}
ata_reinit(adp->controller);
+ return ATA_OP_CONTINUES;
}
-int32_t
+int
ad_interrupt(struct ad_request *request)
{
struct ad_softc *adp = request->device;
- int32_t dma_stat = 0;
+ int dma_stat = 0;
/* finish DMA transfer */
if (request->flags & ADR_F_DMA_USED)
dma_stat = ata_dmadone(adp->controller);
- /* get drive status */
- if (ata_wait(adp->controller, adp->unit, 0) < 0) {
- printf("ad%d: timeout waiting for status", adp->lun);
- request->flags |= ADR_F_ERROR;
- }
-
/* do we have a corrected soft error ? */
if (adp->controller->status & ATA_S_CORR)
printf("ad%d: soft error ECC corrected\n", adp->lun);
/* did any real errors happen ? */
if ((adp->controller->status & ATA_S_ERROR) ||
- ((request->flags & ADR_F_DMA_USED) && (dma_stat & ATA_BMSTAT_ERROR))) {
+ (request->flags & ADR_F_DMA_USED && dma_stat & ATA_BMSTAT_ERROR)) {
printf("ad%d: %s %s ERROR blk# %d", adp->lun,
(adp->controller->error & ATA_E_ICRC) ? "UDMA ICRC" : "HARD",
(request->flags & ADR_F_READ) ? "READ" : "WRITE",
@@ -479,6 +557,7 @@ ad_interrupt(struct ad_request *request)
if (request->flags & ADR_F_DMA_USED &&
adp->controller->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");
@@ -494,7 +573,9 @@ ad_interrupt(struct ad_request *request)
/* if using DMA, try once again in PIO mode */
if (request->flags & ADR_F_DMA_USED) {
untimeout((timeout_t *)ad_timeout, request,request->timeout_handle);
- ata_dmainit(adp->controller, adp->unit, ata_pmode(AD_PARAM), -1,-1);
+ ad_invalidatequeue(adp, request);
+ ata_dmainit(adp->controller, adp->unit,
+ ata_pmode(AD_PARAM), -1, -1);
request->flags |= ADR_F_FORCE_PIO;
TAILQ_INSERT_HEAD(&adp->controller->ata_queue, request, chain);
return ATA_OP_FINISHED;
@@ -511,7 +592,7 @@ ad_interrupt(struct ad_request *request)
/* 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)) {
+ (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))
@@ -556,61 +637,212 @@ ad_interrupt(struct ad_request *request)
request->bp->bio_resid = request->bytecount;
devstat_end_transaction_bio(&adp->stats, request->bp);
biodone(request->bp);
- free(request, M_AD);
+ ad_free(request);
+ adp->outstanding--;
+
+ /* check for SERVICE (tagged operations only) */
+ return ad_service(adp, 1);
+}
+
+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)
+ 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)
+ device = ATA_MASTER;
+ }
+ if (device != adp->unit &&
+ ((struct ad_softc *)
+ (adp->controller->dev_softc[ATA_DEV(device)]))->outstanding > 0) {
+ outb(adp->controller->ioaddr + ATA_DRIVE, ATA_D_IBM | device);
+ adp = adp->controller->dev_softc[ATA_DEV(device)];
+ DELAY(1);
+ }
+ }
+ adp->controller->status = inb(adp->controller->altioaddr + ATA_ALTSTAT);
+
+ /* do we have a SERVICE request from the drive ? */
+ if (adp->flags & AD_F_TAG_ENABLED &&
+ adp->controller->status & ATA_S_SERVICE) {
+ struct ad_request *request;
+ int tag;
+
+ /* check for error */
+ if (adp->controller->status & ATA_S_ERROR) {
+ printf("ad%d: Oops! controller says s=0x%02x e=0x%02x\n",
+ adp->lun, adp->controller->status, adp->controller->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, 0, 0, ATA_IMMEDIATE)) {
+ printf("ad%d: problem executing SERVICE cmd\n", adp->lun);
+ ad_invalidatequeue(adp, NULL);
+ return ATA_OP_FINISHED;
+ }
+
+ /* setup the transfer environment when ready */
+ if (ata_wait(adp->controller, adp->unit, ATA_S_READY)) {
+ printf("ad%d: problem issueing SERVICE tag=%d s=0x%02x e=0x%02x\n",
+ adp->lun, inb(adp->controller->ioaddr + ATA_COUNT) >> 3,
+ adp->controller->status, adp->controller->error);
+ ad_invalidatequeue(adp, NULL);
+ return ATA_OP_FINISHED;
+ }
+ tag = inb(adp->controller->ioaddr + ATA_COUNT) >> 3;
+ if (!(request = adp->tags[tag])) {
+ printf("ad%d: no request for this tag=%d??\n", adp->lun, tag);
+ ad_invalidatequeue(adp, NULL);
+ return ATA_OP_FINISHED;
+ }
+ adp->controller->active = ATA_ACTIVE_ATA;
+ adp->controller->running = request;
+ request->serv++;
+
+ /* start DMA transfer when ready */
+ if (ata_wait(adp->controller, adp->unit, ATA_S_READY | ATA_S_DRQ)) {
+ printf("ad%d: timeout waiting for data phase s=%02x e=%02x\n",
+ adp->lun, adp->controller->status, adp->controller->error);
+ ad_invalidatequeue(adp, NULL);
+ return ATA_OP_FINISHED;
+ }
+ ata_dmastart(adp->controller, adp->unit,
+ request->dmatab, request->flags & ADR_F_READ);
+ return ATA_OP_CONTINUES;
+ }
return ATA_OP_FINISHED;
}
-void
-ad_reinit(struct ad_softc *adp)
+static void
+ad_free(struct ad_request *request)
{
- /* reinit disk parameters */
- ata_command(adp->controller, adp->unit, ATA_C_SET_MULTI, 0, 0, 0,
- adp->transfersize / DEV_BSIZE, 0, ATA_WAIT_READY);
- 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));
- else
- ata_dmainit(adp->controller, adp->unit, ata_pmode(AD_PARAM), -1, -1);
+ int s = splbio();
+
+ if (request->dmatab)
+ free(request->dmatab, M_DEVBUF);
+ request->device->tags[request->tag] = NULL;
+ free(request, M_AD);
+
+ splx(s);
+}
+
+static void
+ad_invalidatequeue(struct ad_softc *adp, struct ad_request *request)
+{
+ /* if tags used invalidate all other tagged transfers */
+ if (adp->flags & AD_F_TAG_ENABLED) {
+ struct ad_request *tmpreq;
+ int tag;
+
+ printf("ad%d: invalidating queued requests\n", adp->lun);
+ 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);
+ }
+ if (ata_command(adp->controller, adp->unit, ATA_C_NOP,
+ 0, 0, 0, 0, ATA_C_F_FLUSHQUEUE, ATA_WAIT_READY))
+ printf("ad%d: flushing queue failed\n", adp->lun);
+ adp->outstanding = 0;
+ }
+}
+
+static int
+ad_tagsupported(struct ad_softc *adp)
+{
+ const char *drives[] = {"IBM-DPTA", "IBM-DTLA", NULL};
+ int i = 0;
+
+ /* Promise controllers doesn't work with tagged queuing */
+ if ((adp->controller->chiptype & 0x0000ffff) == 0x0000105a)
+ return 0;
+
+ /* check that drive has tags enabled, and is one we know works */
+ if (AD_PARAM->supqueued && AD_PARAM->enabqueued) {
+ while (drives[i] != NULL) {
+ if (!strncmp(AD_PARAM->model, drives[i], strlen(drives[i])))
+ return 1;
+ i++;
+ }
+ }
+ return 0;
}
static void
ad_timeout(struct ad_request *request)
{
struct ad_softc *adp = request->device;
- int32_t s = splbio();
+ int s = splbio();
adp->controller->running = NULL;
- printf("ad%d: %s command timeout - resetting\n",
- adp->lun, (request->flags & ADR_F_READ) ? "READ" : "WRITE");
+ printf("ad%d: %s command timeout tag=%d serv=%d - resetting\n",
+ adp->lun, (request->flags & ADR_F_READ) ? "READ" : "WRITE",
+ request->tag, request->serv);
if (request->flags & ADR_F_DMA_USED) {
ata_dmadone(adp->controller);
+ ad_invalidatequeue(adp, request);
if (request->retries == AD_MAX_RETRIES) {
- ata_dmainit(adp->controller, adp->unit, ata_pmode(AD_PARAM), -1,-1);
+ ata_dmainit(adp->controller, adp->unit,
+ ata_pmode(AD_PARAM), -1, -1);
printf("ad%d: trying fallback to PIO mode\n", adp->lun);
request->retries = 0;
}
}
/* if retries still permit, reinject this request */
- if (request->retries++ < AD_MAX_RETRIES)
+ if (request->retries++ < AD_MAX_RETRIES) {
TAILQ_INSERT_HEAD(&adp->controller->ata_queue, request, chain);
+ }
else {
/* retries all used up, return error */
request->bp->bio_error = EIO;
request->bp->bio_flags |= BIO_ERROR;
devstat_end_transaction_bio(&adp->stats, request->bp);
biodone(request->bp);
- free(request, M_AD);
+ ad_free(request);
}
ata_reinit(adp->controller);
splx(s);
}
-static int32_t
+void
+ad_reinit(struct ad_softc *adp)
+{
+ /* reinit disk parameters */
+ ad_invalidatequeue(adp, NULL);
+ ata_command(adp->controller, adp->unit, ATA_C_SET_MULTI, 0, 0, 0,
+ adp->transfersize / DEV_BSIZE, 0, ATA_WAIT_READY);
+ 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));
+ else
+ ata_dmainit(adp->controller, adp->unit, ata_pmode(AD_PARAM), -1, -1);
+}
+
+static int
ad_version(u_int16_t version)
{
- int32_t bit;
+ int bit;
if (version == 0xffff)
return 0;
diff --git a/sys/dev/ata/ata-disk.h b/sys/dev/ata/ata-disk.h
index 4a184d9..13ea2f9 100644
--- a/sys/dev/ata/ata-disk.h
+++ b/sys/dev/ata/ata-disk.h
@@ -28,51 +28,58 @@
* $FreeBSD$
*/
+/* structure describing an ATA disk request */
+struct ad_request {
+ struct ad_softc *device; /* 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 */
+ int retries; /* retry count */
+ int flags;
+#define ADR_F_READ 0x0001
+#define ADR_F_ERROR 0x0002
+#define ADR_F_DMA_USED 0x0004
+#define ADR_F_QUEUED 0x0008
+#define ADR_F_FORCE_PIO 0x0010
+
+ caddr_t data; /* pointer to data buf */
+ struct bio *bp; /* associated bio ptr */
+ u_int8_t tag; /* tag ID of this request */
+ int serv; /* request had service */
+ struct ata_dmaentry *dmatab; /* DMA transfer table */
+ TAILQ_ENTRY(ad_request) chain; /* list management */
+};
+
/* structure describing an ATA disk */
struct ad_softc {
struct ata_softc *controller; /* ptr to parent ctrl */
- int32_t unit; /* ATA_MASTER or ATA_SLAVE */
- int32_t lun; /* logical unit number */
+ int unit; /* ATA_MASTER or ATA_SLAVE */
+ int lun; /* logical unit number */
u_int32_t total_secs; /* total # of sectors (LBA) */
u_int8_t heads;
u_int8_t sectors;
u_int32_t transfersize; /* size of each transfer */
- u_int32_t num_tags; /* number of tags supported */
- u_int32_t flags; /* drive flags */
+ int num_tags; /* number of tags supported */
+ int flags; /* drive flags */
#define AD_F_LABELLING 0x0001
#define AD_F_LBA_ENABLED 0x0002
#define AD_F_32B_ENABLED 0x0004
#define AD_F_TAG_ENABLED 0x0008
+ struct ad_request *tags[32]; /* tag array of requests */
+ int outstanding; /* tags not serviced yet */
struct bio_queue_head queue; /* head of request queue */
struct devstat stats; /* devstat entry */
struct disk disk; /* disklabel/slice stuff */
dev_t dev1, dev2; /* device place holder */
};
-struct ad_request {
- struct ad_softc *device; /* 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 */
- int32_t retries; /* retry count */
- int32_t flags;
-#define ADR_F_READ 0x0001
-#define ADR_F_ERROR 0x0002
-#define ADR_F_DMA_USED 0x0004
-#define ADR_F_FORCE_PIO 0x0008
-
- int8_t *data; /* pointer to data buf */
- struct bio *bp; /* associated bio ptr */
- u_int8_t tag; /* tag ID of this request */
- TAILQ_ENTRY(ad_request) chain; /* list management */
-};
-
-void ad_attach(struct ata_softc *, int32_t);
+void ad_attach(struct ata_softc *, int);
void ad_detach(struct ad_softc *);
void ad_start(struct ad_softc *);
-void ad_transfer(struct ad_request *);
-int32_t ad_interrupt(struct ad_request *);
+int ad_transfer(struct ad_request *);
+int ad_interrupt(struct ad_request *);
+int ad_service(struct ad_softc *, int);
void ad_reinit(struct ad_softc *);
diff --git a/sys/dev/ata/ata-dma.c b/sys/dev/ata/ata-dma.c
index 838495d..763017d 100644
--- a/sys/dev/ata/ata-dma.c
+++ b/sys/dev/ata/ata-dma.c
@@ -48,8 +48,9 @@
#if NPCI > 0
/* prototypes */
-static void promise_timing(struct ata_softc *, int32_t, int32_t);
-static void hpt_timing(struct ata_softc *, int32_t, int32_t);
+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);
/* misc defines */
#ifdef __alpha__
@@ -57,9 +58,25 @@ static void hpt_timing(struct ata_softc *, int32_t, int32_t);
#define vtophys(va) alpha_XXX_dmamap((vm_offset_t)va)
#endif
+void *
+ata_dmaalloc(struct ata_softc *scp, 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");
+ free(dmatab, M_DEVBUF);
+ dmatab = NULL;
+ }
+ }
+ return dmatab;
+}
+
void
-ata_dmainit(struct ata_softc *scp, int32_t device,
- int32_t apiomode, int32_t wdmamode, int32_t udmamode)
+ata_dmainit(struct ata_softc *scp, int device,
+ int apiomode, int wdmamode, int udmamode)
{
device_t parent = device_get_parent(scp->dev);
int devno = (scp->unit << 1) + ATA_DEV(device);
@@ -81,19 +98,9 @@ ata_dmainit(struct ata_softc *scp, int32_t device,
}
}
- if (!scp->dmatab[ATA_DEV(device)]) {
- void *dmatab;
+ /* DMA engine address alignment is usually 1 word (2 bytes) */
+ scp->alignment = 0x1;
- if (!(dmatab = malloc(PAGE_SIZE, M_DEVBUF, M_NOWAIT)))
- return;
- 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");
- free(dmatab, M_DEVBUF);
- return;
- }
- scp->dmatab[ATA_DEV(device)] = dmatab;
- }
if (udmamode > 2 && !ATA_PARAM(scp, device)->cblid) {
ata_printf(scp, device,
"DMA limited to UDMA33, non-ATA66 compliant cable\n");
@@ -285,7 +292,7 @@ ata_dmainit(struct ata_softc *scp, int32_t device,
"Aladdin: two atapi devices on this channel, no DMA\n");
break;
}
- if (udmamode >= 2) {
+ if (udmamode >= 2 && pci_read_config(parent, 0x08, 1) > 0x20) {
int32_t word54 = pci_read_config(parent, 0x54, 4);
error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
@@ -472,15 +479,54 @@ via_82c586:
/* we could set PIO mode timings, but we assume the BIOS did that */
break;
- case 0x4d33105a: /* Promise Ultra33 / FastTrak33 controllers */
- case 0x4d38105a: /* Promise Ultra66 / FastTrak66 controllers */
- case 0x4d30105a: /* Promise Ultra100 / FastTrak100 controllers */
+ case 0x01021078:
+ scp->alignment = 0xf; /* DMA engine requires 16 byte alignment */
+ if (udmamode >= 2) {
+ error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
+ ATA_UDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY);
+ if (bootverbose)
+ ata_printf(scp, device, "%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;
+ return;
+ }
+ }
+ if (wdmamode >= 2 && apiomode >= 4) {
+ error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
+ ATA_WDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY);
+ if (bootverbose)
+ ata_printf(scp, device, "%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;
+ return;
+ }
+ }
+ error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
+ ata_pio2mode(apiomode), ATA_C_F_SETXFER,
+ ATA_WAIT_READY);
+ if (bootverbose)
+ ata_printf(scp, device, "%s setting %s on Cyrix chip\n",
+ (error) ? "failed" : "success",
+ ata_mode2str(ata_pio2mode(apiomode)));
+ cyrix_timing(scp, devno, ata_pio2mode(apiomode));
+ scp->mode[ATA_DEV(device)] = ata_pio2mode(apiomode);
+ return;
+
+ case 0x4d33105a: /* Promise Ultra/FastTrak 33 controllers */
+ case 0x4d38105a: /* Promise Ultra/FastTrak 66 controllers */
+ case 0x4d30105a: /* Promise Ultra/FastTrak 100 controllers */
+ case 0x0d30105a: /* Promise OEM ATA100 controllers */
/* the Promise can only do DMA on ATA disks not on ATAPI devices */
if ((device == ATA_MASTER && scp->devices & ATA_ATAPI_MASTER) ||
(device == ATA_SLAVE && scp->devices & ATA_ATAPI_SLAVE))
break;
- if (udmamode >=5 && scp->chiptype == 0x4d30105a &&
+ if (udmamode >=5 &&
+ (scp->chiptype == 0x4d30105a || scp->chiptype == 0x0d30105a) &&
!(pci_read_config(parent, 0x50, 2)&(scp->unit ? 1<<11 : 1<<10))) {
error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
ATA_UDMA5, ATA_C_F_SETXFER, ATA_WAIT_READY);
@@ -494,8 +540,8 @@ via_82c586:
return;
}
}
- if (udmamode >=4 &&
- (scp->chiptype == 0x4d38105a || scp->chiptype == 0x4d30105a) &&
+ if (udmamode >=4 && (scp->chiptype == 0x4d38105a ||
+ scp->chiptype == 0x4d30105a || scp->chiptype == 0x0d30105a) &&
!(pci_read_config(parent, 0x50, 2)&(scp->unit ? 1<<11 : 1<<10))) {
error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
ATA_UDMA4, ATA_C_F_SETXFER, ATA_WAIT_READY);
@@ -663,23 +709,23 @@ via_82c586:
}
}
-int32_t
-ata_dmasetup(struct ata_softc *scp, int32_t device,
- int8_t *data, int32_t count, int32_t flags)
+int
+ata_dmasetup(struct ata_softc *scp, int device, struct ata_dmaentry *dmatab,
+ caddr_t data, int32_t count)
{
- struct ata_dmaentry *dmatab;
u_int32_t dma_count, dma_base;
int i = 0;
- if (((uintptr_t)data & 1) || (count & 1))
+ if (((uintptr_t)data & scp->alignment) || (count & scp->alignment)) {
+ ata_printf(scp, device, "non aligned DMA transfer attempted\n");
return -1;
+ }
if (!count) {
ata_printf(scp, device, "zero length DMA transfer attempted\n");
return -1;
}
- dmatab = scp->dmatab[ATA_DEV(device)];
dma_base = vtophys(data);
dma_count = min(count, (PAGE_SIZE - ((uintptr_t)data & PAGE_MASK)));
data += dma_count;
@@ -700,22 +746,24 @@ ata_dmasetup(struct ata_softc *scp, int32_t device,
}
dmatab[i].base = dma_base;
dmatab[i].count = (dma_count & 0xffff) | ATA_DMA_EOT;
- outl(scp->bmaddr + ATA_BMDTP_PORT, vtophys(dmatab));
- outb(scp->bmaddr + ATA_BMCMD_PORT, flags ? ATA_BMCMD_WRITE_READ:0);
- outb(scp->bmaddr + ATA_BMSTAT_PORT, (inb(scp->bmaddr + ATA_BMSTAT_PORT) |
- (ATA_BMSTAT_INTERRUPT | ATA_BMSTAT_ERROR)));
return 0;
}
void
-ata_dmastart(struct ata_softc *scp)
+ata_dmastart(struct ata_softc *scp, int device,
+ struct ata_dmaentry *dmatab, int dir)
{
scp->flags |= ATA_DMA_ACTIVE;
+ outl(scp->bmaddr + ATA_BMDTP_PORT, vtophys(dmatab));
+ outb(scp->bmaddr + ATA_BMCMD_PORT, dir ? ATA_BMCMD_WRITE_READ : 0);
+ outb(scp->bmaddr + ATA_BMSTAT_PORT,
+ (inb(scp->bmaddr + ATA_BMSTAT_PORT) |
+ (ATA_BMSTAT_INTERRUPT | ATA_BMSTAT_ERROR)));
outb(scp->bmaddr + ATA_BMCMD_PORT,
inb(scp->bmaddr + ATA_BMCMD_PORT) | ATA_BMCMD_START_STOP);
}
-int32_t
+int
ata_dmadone(struct ata_softc *scp)
{
outb(scp->bmaddr + ATA_BMCMD_PORT,
@@ -724,14 +772,33 @@ ata_dmadone(struct ata_softc *scp)
return inb(scp->bmaddr + ATA_BMSTAT_PORT) & ATA_BMSTAT_MASK;
}
-int32_t
+int
ata_dmastatus(struct ata_softc *scp)
{
return inb(scp->bmaddr + ATA_BMSTAT_PORT) & ATA_BMSTAT_MASK;
}
static void
-promise_timing(struct ata_softc *scp, int32_t devno, int32_t mode)
+cyrix_timing(struct ata_softc *scp, int devno, int mode)
+{
+ u_int32_t reg20 = 0x0000e132;
+ u_int32_t reg24 = 0x00017771;
+
+ switch (mode) {
+ case ATA_PIO0: reg20 = 0x0000e132; break;
+ case ATA_PIO1: reg20 = 0x00018121; break;
+ case ATA_PIO2: reg20 = 0x00024020; break;
+ case ATA_PIO3: reg20 = 0x00032010; break;
+ case ATA_PIO4: reg20 = 0x00040010; break;
+ case ATA_WDMA2: reg24 = 0x00002020; break;
+ case ATA_UDMA2: reg24 = 0x00911030; break;
+ }
+ outl(scp->bmaddr + (devno * 8) + 0x20, reg20);
+ outl(scp->bmaddr + (devno * 8) + 0x24, reg24);
+}
+
+static void
+promise_timing(struct ata_softc *scp, int devno, int mode)
{
u_int32_t timing = 0;
struct promise_timing {
@@ -756,7 +823,7 @@ promise_timing(struct ata_softc *scp, int32_t devno, int32_t mode)
}
switch (scp->chiptype) {
- case 0x4d33105a: /* Promise 33's */
+ 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;
@@ -769,8 +836,9 @@ promise_timing(struct ata_softc *scp, int32_t devno, int32_t mode)
}
break;
- case 0x4d38105a: /* Promise 66's */
- case 0x4d30105a: /* Promise 100's */
+ case 0x4d38105a: /* Promise Ultra/Fasttrak 66 */
+ case 0x4d30105a: /* Promise Ultra/Fasttrak 100 */
+ 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;
@@ -789,7 +857,7 @@ promise_timing(struct ata_softc *scp, int32_t devno, int32_t mode)
}
static void
-hpt_timing(struct ata_softc *scp, int32_t devno, int32_t mode)
+hpt_timing(struct ata_softc *scp, int devno, int mode)
{
device_t parent = device_get_parent(scp->dev);
u_int32_t timing;
@@ -859,14 +927,14 @@ hpt_timing(struct ata_softc *scp, int32_t devno, int32_t mode)
#else /* NPCI > 0 */
void
-ata_dmainit(struct ata_softc *scp, int32_t device,
- int32_t piomode, int32_t wdmamode, int32_t udmamode)
+ata_dmainit(struct ata_softc *scp, int device,
+ int piomode, int wdmamode, int udmamode)
{
}
-int32_t
-ata_dmasetup(struct ata_softc *scp, int32_t device,
- int8_t *data, int32_t count, int32_t flags)
+int
+ata_dmasetup(struct ata_softc *scp, int device,
+ int8_t *data, int32_t count, int flags)
{
return -1;
}
@@ -876,13 +944,13 @@ ata_dmastart(struct ata_softc *scp)
{
}
-int32_t
+int
ata_dmadone(struct ata_softc *scp)
{
return -1;
}
-int32_t
+int
ata_dmastatus(struct ata_softc *scp)
{
return -1;
diff --git a/sys/dev/ata/atapi-all.c b/sys/dev/ata/atapi-all.c
index b8ee8ae..8b034ff 100644
--- a/sys/dev/ata/atapi-all.c
+++ b/sys/dev/ata/atapi-all.c
@@ -44,12 +44,12 @@
#include <dev/ata/atapi-all.h>
/* prototypes */
-static void atapi_read(struct atapi_request *, int32_t);
-static void atapi_write(struct atapi_request *, int32_t);
+static void atapi_read(struct atapi_request *, int);
+static void atapi_write(struct atapi_request *, int);
static void atapi_timeout(struct atapi_request *request);
-static int8_t *atapi_type(int32_t);
-static int8_t *atapi_cmd2str(u_int8_t);
-static int8_t *atapi_skey2str(u_int8_t);
+static char *atapi_type(int);
+static char *atapi_cmd2str(u_int8_t);
+static char *atapi_skey2str(u_int8_t);
/* internal vars */
MALLOC_DEFINE(M_ATAPI, "ATAPI generic", "ATAPI driver generic layer");
@@ -59,7 +59,7 @@ MALLOC_DEFINE(M_ATAPI, "ATAPI generic", "ATAPI driver generic layer");
#define ATP_PARAM ATA_PARAM(atp->controller, atp->unit)
void
-atapi_attach(struct ata_softc *scp, int32_t device)
+atapi_attach(struct ata_softc *scp, int device)
{
struct atapi_softc *atp;
@@ -88,7 +88,7 @@ atapi_attach(struct ata_softc *scp, int32_t device)
else
#endif
/* set PIO mode */
- ata_dmainit(atp->controller, atp->unit,
+ ata_dmainit(atp->controller, atp->unit,
ata_pmode(ATP_PARAM)<0 ? 0 : ata_pmode(ATP_PARAM), -1, -1);
switch (ATP_PARAM->device_type) {
@@ -147,13 +147,13 @@ atapi_detach(struct atapi_softc *atp)
free(atp, M_ATAPI);
}
-int32_t
-atapi_queue_cmd(struct atapi_softc *atp, int8_t *ccb, void *data,
- int32_t count, int32_t flags, int32_t timeout,
+int
+atapi_queue_cmd(struct atapi_softc *atp, int8_t *ccb, caddr_t data,
+ int count, int flags, int timeout,
atapi_callback_t callback, void *driver)
{
struct atapi_request *request;
- int32_t error, s;
+ int error, s;
if (!(request = malloc(sizeof(struct atapi_request), M_ATAPI, M_NOWAIT)))
return ENOMEM;
@@ -170,6 +170,10 @@ atapi_queue_cmd(struct atapi_softc *atp, int8_t *ccb, void *data,
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;
+ }
s = splbio();
@@ -203,6 +207,8 @@ atapi_queue_cmd(struct atapi_softc *atp, int8_t *ccb, void *data,
printf("%s: finished %s\n",
request->device->devname, atapi_cmd2str(request->ccb[0]));
#endif
+ if (request->dmatab)
+ free(request->dmatab, M_DEVBUF);
free(request, M_ATAPI);
return error;
}
@@ -235,8 +241,8 @@ void
atapi_transfer(struct atapi_request *request)
{
struct atapi_softc *atp = request->device;
- int32_t timout;
- int8_t reason;
+ int timout;
+ u_int8_t reason;
#ifdef ATAPI_DEBUG
printf("%s: starting %s ",
@@ -257,9 +263,8 @@ atapi_transfer(struct atapi_request *request)
((request->ccb[0] == ATAPI_WRITE ||
request->ccb[0] == ATAPI_WRITE_BIG) &&
!(atp->controller->flags & ATA_ATAPI_DMA_RO))) &&
- !ata_dmasetup(atp->controller, atp->unit,
- (void *)request->data, request->bytecount,
- request->flags & ATPR_F_READ)) {
+ !ata_dmasetup(atp->controller, atp->unit, request->dmatab,
+ (void *)request->data, request->bytecount)) {
request->flags |= ATPR_F_DMA_USED;
}
@@ -271,7 +276,8 @@ atapi_transfer(struct atapi_request *request)
printf("%s: failure to send ATAPI packet command\n", atp->devname);
if (request->flags & ATPR_F_DMA_USED)
- ata_dmastart(atp->controller);
+ ata_dmastart(atp->controller, atp->unit,
+ request->dmatab, request->flags & ATPR_F_READ);
/* command interrupt device ? just return */
if (ATP_PARAM->drqtype == ATAPI_DRQT_INTR)
@@ -301,12 +307,12 @@ atapi_transfer(struct atapi_request *request)
request->ccbsize / sizeof(int16_t));
}
-int32_t
+int
atapi_interrupt(struct atapi_request *request)
{
struct atapi_softc *atp = request->device;
int8_t **buffer = (int8_t **)&request->data;
- int32_t reason, dma_stat = 0;
+ int reason, dma_stat = 0;
if (request->ccb[0] == ATAPI_REQUEST_SENSE)
*buffer = (int8_t *)&request->sense;
@@ -338,8 +344,8 @@ atapi_interrupt(struct atapi_request *request)
}
}
else {
- int32_t length = inb(atp->controller->ioaddr + ATA_CYL_LSB) |
- inb(atp->controller->ioaddr + ATA_CYL_MSB) << 8;
+ int length = inb(atp->controller->ioaddr + ATA_CYL_LSB) |
+ inb(atp->controller->ioaddr + ATA_CYL_MSB) << 8;
switch (reason) {
case ATAPI_P_WRITE:
@@ -441,8 +447,11 @@ op_finished:
printf("%s: finished %s (callback)\n",
request->device->devname, atapi_cmd2str(request->ccb[0]));
#endif
- if (!((request->callback)(request)))
+ if (!((request->callback)(request))) {
+ if (request->dmatab)
+ free(request->dmatab, M_DEVBUF);
free(request, M_ATAPI);
+ }
}
else
wakeup((caddr_t)request);
@@ -462,11 +471,11 @@ atapi_reinit(struct atapi_softc *atp)
(ATP_PARAM->dmaflag ? 2 : 0) : ata_wmode(ATP_PARAM),
ata_umode(ATP_PARAM));
else
- ata_dmainit(atp->controller, atp->unit,
+ ata_dmainit(atp->controller, atp->unit,
ata_pmode(ATP_PARAM)<0 ? 0 : ata_pmode(ATP_PARAM), -1, -1);
}
-int32_t
+int
atapi_test_ready(struct atapi_softc *atp)
{
int8_t ccb[16] = { ATAPI_TEST_UNIT_READY, 0, 0, 0, 0,
@@ -475,10 +484,10 @@ atapi_test_ready(struct atapi_softc *atp)
return atapi_queue_cmd(atp, ccb, NULL, 0, 0, 30, NULL, NULL);
}
-int32_t
-atapi_wait_ready(struct atapi_softc *atp, int32_t timeout)
+int
+atapi_wait_ready(struct atapi_softc *atp, int timeout)
{
- int32_t error = 0, timout = timeout * hz;
+ int error = 0, timout = timeout * hz;
while (timout > 0) {
if ((error = atapi_test_ready(atp)) != EBUSY)
@@ -490,7 +499,7 @@ atapi_wait_ready(struct atapi_softc *atp, int32_t timeout)
}
void
-atapi_dump(int8_t *label, void *data, int32_t len)
+atapi_dump(char *label, void *data, int len)
{
u_int8_t *p = data;
@@ -501,11 +510,11 @@ atapi_dump(int8_t *label, void *data, int32_t len)
}
static void
-atapi_read(struct atapi_request *request, int32_t length)
+atapi_read(struct atapi_request *request, int length)
{
int8_t **buffer = (int8_t **)&request->data;
- int32_t size = min(request->bytecount, length);
- int32_t resid;
+ int size = min(request->bytecount, length);
+ int resid;
if (request->ccb[0] == ATAPI_REQUEST_SENSE)
*buffer = (int8_t *)&request->sense;
@@ -530,11 +539,11 @@ atapi_read(struct atapi_request *request, int32_t length)
}
static void
-atapi_write(struct atapi_request *request, int32_t length)
+atapi_write(struct atapi_request *request, int length)
{
int8_t **buffer = (int8_t **)&request->data;
- int32_t size = min(request->bytecount, length);
- int32_t resid;
+ int size = min(request->bytecount, length);
+ int resid;
if (request->ccb[0] == ATAPI_REQUEST_SENSE)
*buffer = (int8_t *)&request->sense;
@@ -562,7 +571,7 @@ static void
atapi_timeout(struct atapi_request *request)
{
struct atapi_softc *atp = request->device;
- int32_t s = splbio();
+ int s = splbio();
atp->controller->running = NULL;
printf("%s: %s command timeout - resetting\n",
@@ -571,7 +580,7 @@ atapi_timeout(struct atapi_request *request)
if (request->flags & ATPR_F_DMA_USED) {
ata_dmadone(atp->controller);
if (request->retries == ATAPI_MAX_RETRIES) {
- ata_dmainit(atp->controller, atp->unit,
+ ata_dmainit(atp->controller, atp->unit,
(ata_pmode(ATP_PARAM)<0)?0:ata_pmode(ATP_PARAM),-1,-1);
printf("%s: trying fallback to PIO mode\n", atp->devname);
request->retries = 0;
@@ -590,8 +599,8 @@ atapi_timeout(struct atapi_request *request)
splx(s);
}
-static int8_t *
-atapi_type(int32_t type)
+static char *
+atapi_type(int type)
{
switch (type) {
case ATAPI_TYPE_CDROM:
@@ -607,7 +616,7 @@ atapi_type(int32_t type)
}
}
-static int8_t *
+static char *
atapi_cmd2str(u_int8_t cmd)
{
switch (cmd) {
@@ -659,14 +668,14 @@ atapi_cmd2str(u_int8_t cmd)
case 0xbd: return ("MECH_STATUS");
case 0xbe: return ("READ_CD");
default: {
- static int8_t buffer[16];
+ static char buffer[16];
sprintf(buffer, "unknown CMD (0x%02x)", cmd);
return buffer;
}
}
}
-static int8_t *
+static char *
atapi_skey2str(u_int8_t skey)
{
switch (skey) {
diff --git a/sys/dev/ata/atapi-all.h b/sys/dev/ata/atapi-all.h
index 6223f5d..72cf781 100644
--- a/sys/dev/ata/atapi-all.h
+++ b/sys/dev/ata/atapi-all.h
@@ -143,57 +143,58 @@ struct atapi_reqsense {
struct atapi_softc {
struct ata_softc *controller; /* ptr to controller softc */
- int32_t unit; /* ATA_MASTER or ATA_SLAVE */
+ int unit; /* ATA_MASTER or ATA_SLAVE */
void *driver; /* ptr to subdriver softc */
- int8_t *devname; /* this devices name */
- int8_t cmd; /* last cmd executed */
- u_int32_t flags; /* drive flags */
+ char *devname; /* this devices name */
+ u_int8_t cmd; /* last cmd executed */
+ int flags; /* drive flags */
#define ATAPI_F_MEDIA_CHANGED 0x0001
};
-typedef int32_t atapi_callback_t(struct atapi_request *);
+typedef int atapi_callback_t(struct atapi_request *);
struct atapi_request {
struct atapi_softc *device; /* ptr to parent device */
u_int8_t ccb[16]; /* command control block */
- int32_t ccbsize; /* size of ccb (12 | 16) */
+ int ccbsize; /* size of ccb (12 | 16) */
u_int32_t bytecount; /* bytes to transfer */
u_int32_t donecount; /* bytes transferred */
- int32_t timeout; /* timeout for this cmd */
+ int timeout; /* timeout for this cmd */
struct callout_handle timeout_handle; /* handle for untimeout */
- int32_t retries; /* retry count */
- int32_t result; /* result of this cmd */
- int32_t error; /* result translated to errno */
+ int retries; /* retry count */
+ int result; /* result of this cmd */
+ int error; /* result translated to errno */
struct atapi_reqsense sense; /* sense data if error */
- int32_t flags;
+ int flags;
#define ATPR_F_READ 0x0001
#define ATPR_F_DMA_USED 0x0002
#define ATPR_F_AT_HEAD 0x0004
- int8_t *data; /* pointer to data buf */
+ 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 */
TAILQ_ENTRY(atapi_request) chain; /* list management */
};
-void atapi_attach(struct ata_softc *, int32_t);
+void atapi_attach(struct ata_softc *, int);
void atapi_detach(struct atapi_softc *);
void atapi_start(struct atapi_softc *);
void atapi_transfer(struct atapi_request *);
-int32_t atapi_interrupt(struct atapi_request *);
-int32_t atapi_queue_cmd(struct atapi_softc *, int8_t [], void *, int32_t, int32_t, int32_t, atapi_callback_t, void *);
+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 *);
-int32_t atapi_test_ready(struct atapi_softc *);
-int32_t atapi_wait_ready(struct atapi_softc *, int32_t);
+int atapi_test_ready(struct atapi_softc *);
+int atapi_wait_ready(struct atapi_softc *, int);
void atapi_request_sense(struct atapi_softc *, struct atapi_reqsense *);
-void atapi_dump(int8_t *, void *, int32_t);
-int32_t acdattach(struct atapi_softc *);
+void atapi_dump(char *, void *, int);
+int acdattach(struct atapi_softc *);
void acddetach(struct atapi_softc *);
void acd_start(struct atapi_softc *);
-int32_t afdattach(struct atapi_softc *);
+int afdattach(struct atapi_softc *);
void afddetach(struct atapi_softc *);
void afd_start(struct atapi_softc *);
-int32_t astattach(struct atapi_softc *);
+int astattach(struct atapi_softc *);
void astdetach(struct atapi_softc *);
void ast_start(struct atapi_softc *);
diff --git a/sys/dev/ata/atapi-cd.c b/sys/dev/ata/atapi-cd.c
index 1e01633..3efd1f4 100644
--- a/sys/dev/ata/atapi-cd.c
+++ b/sys/dev/ata/atapi-cd.c
@@ -43,6 +43,7 @@
#include <sys/fcntl.h>
#include <sys/conf.h>
#include <sys/stat.h>
+#include <sys/ctype.h>
#include <dev/ata/ata-all.h>
#include <dev/ata/atapi-all.h>
#include <dev/ata/atapi-cd.h>
@@ -72,29 +73,30 @@ static struct cdevsw acd_cdevsw = {
/* prototypes */
static struct acd_softc *acd_init_lun(struct atapi_softc *, struct devstat *);
static void acd_make_dev(struct acd_softc *);
+static void acd_clone(void *, char *, int, dev_t *);
static void acd_describe(struct acd_softc *);
-static void lba2msf(int32_t, u_int8_t *, u_int8_t *, u_int8_t *);
-static int32_t msf2lba(u_int8_t, u_int8_t, u_int8_t);
-static int32_t acd_done(struct atapi_request *);
+static void lba2msf(u_int32_t, u_int8_t *, u_int8_t *, u_int8_t *);
+static u_int32_t msf2lba(u_int8_t, u_int8_t, u_int8_t);
+static int acd_done(struct atapi_request *);
static void acd_read_toc(struct acd_softc *);
static void acd_construct_label(struct acd_softc *);
-static int32_t acd_setchan(struct acd_softc *, u_int8_t, u_int8_t, u_int8_t, u_int8_t);
+static int acd_setchan(struct acd_softc *, u_int8_t, u_int8_t, u_int8_t, u_int8_t);
static void acd_select_slot(struct acd_softc *);
-static int32_t acd_open_track(struct acd_softc *, struct cdr_track *);
-static int32_t acd_close_track(struct acd_softc *);
-static int32_t acd_close_disk(struct acd_softc *);
-static int32_t acd_read_track_info(struct acd_softc *, int32_t, struct acd_track_info*);
+static int acd_open_track(struct acd_softc *, struct cdr_track *);
+static int acd_close_track(struct acd_softc *);
+static int acd_close_disk(struct acd_softc *);
+static int acd_read_track_info(struct acd_softc *, int32_t, struct acd_track_info*);
static int acd_report_key(struct acd_softc *, struct dvd_authinfo *);
static int acd_send_key(struct acd_softc *, struct dvd_authinfo *);
static int acd_read_structure(struct acd_softc *, struct dvd_struct *);
-static int32_t acd_eject(struct acd_softc *, int32_t);
-static int32_t acd_blank(struct acd_softc *);
-static int32_t acd_prevent_allow(struct acd_softc *, int32_t);
-static int32_t acd_start_stop(struct acd_softc *, int32_t);
-static int32_t acd_pause_resume(struct acd_softc *, int32_t);
-static int32_t acd_mode_sense(struct acd_softc *, u_int8_t, void *, int32_t);
-static int32_t acd_mode_select(struct acd_softc *, void *, int32_t);
-static int32_t acd_set_speed(struct acd_softc *cdp, int32_t);
+static int acd_eject(struct acd_softc *, int);
+static int acd_blank(struct acd_softc *);
+static int acd_prevent_allow(struct acd_softc *, int);
+static int acd_start_stop(struct acd_softc *, int);
+static int acd_pause_resume(struct acd_softc *, int);
+static int acd_mode_sense(struct acd_softc *, int, caddr_t, int);
+static int acd_mode_select(struct acd_softc *, caddr_t, int);
+static int acd_set_speed(struct acd_softc *cdp, int);
/* internal vars */
static u_int32_t acd_lun_map = 0;
@@ -105,11 +107,12 @@ acdattach(struct atapi_softc *atp)
{
struct acd_softc *cdp;
struct changer *chp;
- int32_t count, error = 0;
- static int32_t acd_cdev_done = 0;
+ int count, error = 0;
+ static int acd_cdev_done = 0;
if (!acd_cdev_done) {
cdevsw_add(&acd_cdevsw);
+ EVENTHANDLER_REGISTER(dev_clone, acd_clone, 0, 1000);
acd_cdev_done++;
}
@@ -121,7 +124,7 @@ acdattach(struct atapi_softc *atp)
/* get drive capabilities, some drives needs this repeated */
for (count = 0 ; count < 5 ; count++) {
if (!(error = acd_mode_sense(cdp, ATAPI_CDROM_CAP_PAGE,
- &cdp->cap, sizeof(cdp->cap))))
+ (caddr_t)&cdp->cap, sizeof(cdp->cap))))
break;
}
if (error) {
@@ -149,14 +152,15 @@ acdattach(struct atapi_softc *atp)
return -1;
}
bzero(chp, sizeof(struct changer));
- error = atapi_queue_cmd(cdp->atp, ccb, chp, sizeof(struct changer),
+ error = atapi_queue_cmd(cdp->atp, ccb, (caddr_t)chp,
+ sizeof(struct changer),
ATPR_F_READ, 60, NULL, NULL);
if (!error) {
struct acd_softc *tmpcdp = cdp;
struct acd_softc **cdparr;
- int32_t count;
- int8_t string[16];
+ int count;
+ char string[16];
chp->table_length = htons(chp->table_length);
if (!(cdparr = malloc(sizeof(struct acd_softc) * chp->slots,
@@ -272,11 +276,29 @@ acd_make_dev(struct acd_softc *cdp)
cdp->atp->flags |= ATAPI_F_MEDIA_CHANGED;
}
+static void
+acd_clone(void *arg, char *name, int namelen, dev_t *dev)
+{
+ char *namep;
+ int unit, track = 0;
+
+ if (*dev != NODEV ||
+ !dev_stdclone(name, &namep, "acd", &unit) || *namep++ != 't')
+ return;
+ while (isdigit(*namep)) {
+ track *= 10;
+ track += *namep++ - '0';
+ }
+ if (*namep)
+ return;
+ *dev = make_dev(&acd_cdevsw, unit | (track << 16), 0, 0, 0644, name, NULL);
+}
+
static void
acd_describe(struct acd_softc *cdp)
{
- int32_t comma = 0;
- int8_t *mechanism;
+ int comma = 0;
+ char *mechanism;
if (bootverbose) {
printf("acd%d: <%.40s/%.8s> %s drive at ata%d as %s\n",
@@ -467,7 +489,7 @@ acd_describe(struct acd_softc *cdp)
}
static __inline void
-lba2msf(int32_t lba, u_int8_t *m, u_int8_t *s, u_int8_t *f)
+lba2msf(u_int32_t lba, u_int8_t *m, u_int8_t *s, u_int8_t *f)
{
lba += 150;
lba &= 0xffffff;
@@ -477,14 +499,14 @@ lba2msf(int32_t lba, u_int8_t *m, u_int8_t *s, u_int8_t *f)
*f = lba % 75;
}
-static __inline int32_t
+static __inline u_int32_t
msf2lba(u_int8_t m, u_int8_t s, u_int8_t f)
{
return (m * 60 + s) * 75 + f - 150;
}
static int
-acdopen(dev_t dev, int32_t flags, int32_t fmt, struct proc *p)
+acdopen(dev_t dev, int flags, int fmt, struct proc *p)
{
struct acd_softc *cdp;
int track = (dev->si_udev & 0x00ff0000) >> 16;
@@ -520,7 +542,7 @@ acdopen(dev_t dev, int32_t flags, int32_t fmt, struct proc *p)
}
static int
-acdclose(dev_t dev, int32_t flags, int32_t fmt, struct proc *p)
+acdclose(dev_t dev, int flags, int fmt, struct proc *p)
{
struct acd_softc *cdp = dev->si_drv1;
@@ -539,10 +561,10 @@ acdclose(dev_t dev, int32_t flags, int32_t fmt, struct proc *p)
}
static int
-acdioctl(dev_t dev, u_long cmd, caddr_t addr, int32_t flags, struct proc *p)
+acdioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
{
struct acd_softc *cdp = dev->si_drv1;
- int32_t error = 0;
+ int error = 0;
if (!cdp)
return ENXIO;
@@ -625,8 +647,8 @@ acdioctl(dev_t dev, u_long cmd, caddr_t addr, int32_t flags, struct proc *p)
struct ioc_read_toc_entry *te = (struct ioc_read_toc_entry *)addr;
struct toc *toc = &cdp->toc;
struct toc buf;
- u_int32_t len;
- u_int8_t starting_track = te->starting_track;
+ int starting_track = te->starting_track;
+ int len;
if (!cdp->toc.hdr.ending_track) {
error = EIO;
@@ -681,7 +703,7 @@ acdioctl(dev_t dev, u_long cmd, caddr_t addr, int32_t flags, struct proc *p)
(struct ioc_read_toc_single_entry *)addr;
struct toc *toc = &cdp->toc;
struct toc buf;
- u_int8_t track = te->track;
+ u_char track = te->track;
if (!cdp->toc.hdr.ending_track) {
error = EIO;
@@ -723,7 +745,7 @@ acdioctl(dev_t dev, u_long cmd, caddr_t addr, int32_t flags, struct proc *p)
struct ioc_read_subchannel *args =
(struct ioc_read_subchannel *)addr;
struct cd_sub_channel_info data;
- u_int32_t len = args->data_len;
+ int len = args->data_len;
int32_t abslba, rellba;
int8_t ccb[16] = { ATAPI_READ_SUBCHANNEL, 0, 0x40, 1, 0, 0, 0,
sizeof(cdp->subchan)>>8, sizeof(cdp->subchan),
@@ -735,7 +757,7 @@ acdioctl(dev_t dev, u_long cmd, caddr_t addr, int32_t flags, struct proc *p)
break;
}
- if ((error = atapi_queue_cmd(cdp->atp, ccb, &cdp->subchan,
+ if ((error = atapi_queue_cmd(cdp->atp, ccb, (caddr_t)&cdp->subchan,
sizeof(cdp->subchan), ATPR_F_READ, 10,
NULL, NULL))) {
break;
@@ -792,8 +814,8 @@ acdioctl(dev_t dev, u_long cmd, caddr_t addr, int32_t flags, struct proc *p)
case CDIOCPLAYTRACKS:
{
struct ioc_play_track *args = (struct ioc_play_track *)addr;
- u_int32_t start, len;
- int32_t t1, t2;
+ u_int start, len;
+ int t1, t2;
int8_t ccb[16];
if (!cdp->toc.hdr.ending_track) {
@@ -832,9 +854,10 @@ acdioctl(dev_t dev, u_long cmd, caddr_t addr, int32_t flags, struct proc *p)
case CDIOCREADAUDIO:
{
struct ioc_read_audio *args = (struct ioc_read_audio *)addr;
- int32_t lba, frames, error = 0;
- u_int8_t *buffer, *ubuf = args->buffer;
+ int32_t lba;
+ caddr_t buffer, ubuf = args->buffer;
int8_t ccb[16];
+ int frames, error = 0;
if (!cdp->toc.hdr.ending_track) {
error = EIO;
@@ -866,8 +889,8 @@ acdioctl(dev_t dev, u_long cmd, caddr_t addr, int32_t flags, struct proc *p)
}
bzero(ccb, sizeof(ccb));
while (frames > 0) {
- int32_t size;
- u_int8_t blocks;
+ int8_t blocks;
+ int size;
blocks = (frames>CD_BUFFER_BLOCKS) ? CD_BUFFER_BLOCKS : frames;
size = blocks * 2352;
@@ -906,7 +929,7 @@ acdioctl(dev_t dev, u_long cmd, caddr_t addr, int32_t flags, struct proc *p)
struct ioc_vol *arg = (struct ioc_vol *)addr;
if ((error = acd_mode_sense(cdp, ATAPI_CDROM_AUDIO_PAGE,
- &cdp->au, sizeof(cdp->au))))
+ (caddr_t)&cdp->au, sizeof(cdp->au))))
break;
if (cdp->au.page_code != ATAPI_CDROM_AUDIO_PAGE) {
@@ -925,14 +948,15 @@ acdioctl(dev_t dev, u_long cmd, caddr_t addr, int32_t flags, struct proc *p)
struct ioc_vol *arg = (struct ioc_vol *)addr;
if ((error = acd_mode_sense(cdp, ATAPI_CDROM_AUDIO_PAGE,
- &cdp->au, sizeof(cdp->au))))
+ (caddr_t)&cdp->au, sizeof(cdp->au))))
break;
if (cdp->au.page_code != ATAPI_CDROM_AUDIO_PAGE) {
error = EIO;
break;
}
if ((error = acd_mode_sense(cdp, ATAPI_CDROM_AUDIO_PAGE_MASK,
- &cdp->aumask, sizeof(cdp->aumask))))
+ (caddr_t)&cdp->aumask,
+ sizeof(cdp->aumask))))
break;
cdp->au.data_length = 0;
cdp->au.port[0].channels = CHANNEL_0;
@@ -941,7 +965,7 @@ acdioctl(dev_t dev, u_long cmd, caddr_t addr, int32_t flags, struct proc *p)
cdp->au.port[1].volume = arg->vol[1] & cdp->aumask.port[1].volume;
cdp->au.port[2].volume = arg->vol[2] & cdp->aumask.port[2].volume;
cdp->au.port[3].volume = arg->vol[3] & cdp->aumask.port[3].volume;
- error = acd_mode_select(cdp, &cdp->au, sizeof(cdp->au));
+ error = acd_mode_select(cdp, (caddr_t)&cdp->au, sizeof(cdp->au));
break;
}
case CDIOCSETPATCH:
@@ -1008,15 +1032,15 @@ acdioctl(dev_t dev, u_long cmd, caddr_t addr, int32_t flags, struct proc *p)
break;
case CDRIOCWRITESPEED:
- error = acd_set_speed(cdp, (*(int32_t *)addr) * 177);
+ error = acd_set_speed(cdp, (*(int *)addr) * 177);
break;
case CDRIOCGETBLOCKSIZE:
- *(int32_t *)addr = cdp->block_size;
+ *(int *)addr = cdp->block_size;
break;
case CDRIOCSETBLOCKSIZE:
- cdp->block_size = *(int32_t *)addr;
+ cdp->block_size = *(int *)addr;
break;
case DVDIOCREPORTKEY:
@@ -1071,7 +1095,7 @@ static void
acdstrategy(struct bio *bp)
{
struct acd_softc *cdp = bp->bio_dev->si_drv1;
- int32_t s;
+ int s;
/* if it's a null transfer, return immediatly. */
if (bp->bio_bcount == 0) {
@@ -1179,7 +1203,7 @@ acd_start(struct atapi_softc *atp)
bp->bio_cmd == BIO_READ ? ATPR_F_READ : 0, 30, acd_done,bp);
}
-static int32_t
+static int
acd_done(struct atapi_request *request)
{
struct bio *bp = request->driver;
@@ -1199,7 +1223,7 @@ acd_done(struct atapi_request *request)
static void
acd_read_toc(struct acd_softc *cdp)
{
- int32_t ntracks, len;
+ int ntracks, len;
int8_t ccb[16];
bzero(&cdp->toc, sizeof(cdp->toc));
@@ -1214,8 +1238,8 @@ 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, &cdp->toc, len, ATPR_F_READ, 30,
- NULL, NULL)) {
+ if (atapi_queue_cmd(cdp->atp, ccb, (caddr_t)&cdp->toc, len, ATPR_F_READ,
+ 30, NULL, NULL)) {
bzero(&cdp->toc, sizeof(cdp->toc));
return;
}
@@ -1230,8 +1254,8 @@ 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, &cdp->toc, len, ATPR_F_READ, 30,
- NULL, NULL)) {
+ if (atapi_queue_cmd(cdp->atp, ccb, (caddr_t)&cdp->toc, len, ATPR_F_READ,
+ 30, NULL, NULL)) {
bzero(&cdp->toc, sizeof(cdp->toc));
return;
}
@@ -1240,7 +1264,7 @@ acd_read_toc(struct acd_softc *cdp)
bzero(ccb, sizeof(ccb));
ccb[0] = ATAPI_READ_CAPACITY;
- if (atapi_queue_cmd(cdp->atp, ccb, &cdp->info, sizeof(cdp->info),
+ if (atapi_queue_cmd(cdp->atp, ccb, (caddr_t)&cdp->info, sizeof(cdp->info),
ATPR_F_READ, 30, NULL, NULL))
bzero(&cdp->info, sizeof(cdp->info));
@@ -1293,13 +1317,13 @@ acd_construct_label(struct acd_softc *cdp)
cdp->disklabel.d_checksum = dkcksum(&cdp->disklabel);
}
-static int32_t
+static int
acd_setchan(struct acd_softc *cdp,
u_int8_t c0, u_int8_t c1, u_int8_t c2, u_int8_t c3)
{
- int32_t error;
+ int error;
- if ((error = acd_mode_sense(cdp, ATAPI_CDROM_AUDIO_PAGE, &cdp->au,
+ if ((error = acd_mode_sense(cdp, ATAPI_CDROM_AUDIO_PAGE, (caddr_t)&cdp->au,
sizeof(cdp->au))))
return error;
if (cdp->au.page_code != ATAPI_CDROM_AUDIO_PAGE)
@@ -1309,10 +1333,10 @@ acd_setchan(struct acd_softc *cdp,
cdp->au.port[1].channels = c1;
cdp->au.port[2].channels = c2;
cdp->au.port[3].channels = c3;
- return acd_mode_select(cdp, &cdp->au, sizeof(cdp->au));
+ return acd_mode_select(cdp, (caddr_t)&cdp->au, sizeof(cdp->au));
}
-static int32_t
+static int
acd_select_done1(struct atapi_request *request)
{
struct acd_softc *cdp = request->driver;
@@ -1323,7 +1347,7 @@ acd_select_done1(struct atapi_request *request)
return 0;
}
-static int32_t
+static int
acd_select_done(struct atapi_request *request)
{
struct acd_softc *cdp = request->driver;
@@ -1347,7 +1371,7 @@ acd_select_slot(struct acd_softc *cdp)
acd_select_done, cdp);
}
-static int32_t
+static int
acd_close_disk(struct acd_softc *cdp)
{
int8_t ccb[16] = { ATAPI_CLOSE_TRACK, 0, 0x02, 0, 0, 0, 0, 0,
@@ -1356,14 +1380,14 @@ acd_close_disk(struct acd_softc *cdp)
return atapi_queue_cmd(cdp->atp, ccb, NULL, 0, 0, 5*60, NULL, NULL);
}
-static int32_t
+static int
acd_open_track(struct acd_softc *cdp, struct cdr_track *track)
{
struct write_param param;
- int32_t error;
+ int error;
if ((error = acd_mode_sense(cdp, ATAPI_CDROM_WRITE_PARAMETERS_PAGE,
- &param, sizeof(param))))
+ (caddr_t)&param, sizeof(param))))
return error;
param.page_code = ATAPI_CDROM_WRITE_PARAMETERS_PAGE;
@@ -1433,10 +1457,10 @@ acd_open_track(struct acd_softc *cdp, struct cdr_track *track)
#endif
param.fp = 0;
param.packet_size = 0;
- return acd_mode_select(cdp, &param, sizeof(param));
+ return acd_mode_select(cdp, (caddr_t)&param, sizeof(param));
}
-static int32_t
+static int
acd_close_track(struct acd_softc *cdp)
{
int8_t ccb[16] = { ATAPI_SYNCHRONIZE_CACHE, 0, 0, 0, 0, 0, 0, 0,
@@ -1445,7 +1469,7 @@ acd_close_track(struct acd_softc *cdp)
return atapi_queue_cmd(cdp->atp, ccb, NULL, 0, 0, 60, NULL, NULL);
}
-static int32_t
+static int
acd_read_track_info(struct acd_softc *cdp,
int32_t lba, struct acd_track_info *info)
{
@@ -1454,9 +1478,9 @@ acd_read_track_info(struct acd_softc *cdp,
0,
sizeof(*info)>>8, sizeof(*info),
0, 0, 0, 0, 0, 0, 0 };
- int32_t error;
+ int error;
- if ((error = atapi_queue_cmd(cdp->atp, ccb, info, sizeof(*info),
+ if ((error = atapi_queue_cmd(cdp->atp, ccb, (caddr_t)info, sizeof(*info),
ATPR_F_READ, 30, NULL, NULL)))
return error;
info->track_start_addr = ntohl(info->track_start_addr);
@@ -1476,9 +1500,9 @@ acd_report_key(struct acd_softc *cdp, struct dvd_authinfo *ai)
u_char data[12];
} d;
u_int32_t lba = 0;
- int32_t error;
int16_t length;
int8_t ccb[16];
+ int error;
switch (ai->format) {
case DVD_REPORT_AGID:
@@ -1514,7 +1538,7 @@ acd_report_key(struct acd_softc *cdp, struct dvd_authinfo *ai)
ccb[10] = (ai->agid << 6) | ai->format;
bzero(&d, sizeof(d));
d.length = htons(length - 2);
- error = atapi_queue_cmd(cdp->atp, ccb, &d, length,
+ error = atapi_queue_cmd(cdp->atp, ccb, (caddr_t)&d, length,
ai->format == DVD_INVALIDATE_AGID ? 0 : ATPR_F_READ,
10, NULL, NULL);
if (error)
@@ -1597,7 +1621,8 @@ 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);
- return atapi_queue_cmd(cdp->atp, ccb, &d, length, 0, 10, NULL, NULL);
+ return atapi_queue_cmd(cdp->atp, ccb, (caddr_t)&d, length, 0,
+ 10, NULL, NULL);
}
static int
@@ -1609,7 +1634,7 @@ acd_read_structure(struct acd_softc *cdp, struct dvd_struct *s)
u_char data[2048];
} d;
u_int16_t length;
- int32_t error = 0;
+ int error = 0;
int8_t ccb[16];
bzero(&d, sizeof(d));
@@ -1657,8 +1682,8 @@ acd_read_structure(struct acd_softc *cdp, struct dvd_struct *s)
ccb[9] = length & 0xff;
ccb[10] = s->agid << 6;
d.length = htons(length - 2);
- error = atapi_queue_cmd(cdp->atp, ccb, &d, length, ATPR_F_READ, 30,
- NULL, NULL);
+ error = atapi_queue_cmd(cdp->atp, ccb, (caddr_t)&d, length, ATPR_F_READ,
+ 30, NULL, NULL);
if (error)
return error;
@@ -1707,10 +1732,10 @@ acd_read_structure(struct acd_softc *cdp, struct dvd_struct *s)
return 0;
}
-static int32_t
-acd_eject(struct acd_softc *cdp, int32_t close)
+static int
+acd_eject(struct acd_softc *cdp, int close)
{
- int32_t error;
+ int error;
if ((error = acd_start_stop(cdp, 0)) == EBUSY) {
if (!close)
@@ -1732,20 +1757,20 @@ acd_eject(struct acd_softc *cdp, int32_t close)
return acd_start_stop(cdp, 2);
}
-static int32_t
+static int
acd_blank(struct acd_softc *cdp)
{
int8_t ccb[16] = { ATAPI_BLANK, 1, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0 };
- int32_t error;
+ int error;
error = atapi_queue_cmd(cdp->atp, ccb, NULL, 0, 0, 60*60, NULL, NULL);
cdp->atp->flags |= ATAPI_F_MEDIA_CHANGED;
return error;
}
-static int32_t
-acd_prevent_allow(struct acd_softc *cdp, int32_t lock)
+static int
+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 };
@@ -1753,8 +1778,8 @@ acd_prevent_allow(struct acd_softc *cdp, int32_t lock)
return atapi_queue_cmd(cdp->atp, ccb, NULL, 0, 0, 30, NULL, NULL);
}
-static int32_t
-acd_start_stop(struct acd_softc *cdp, int32_t start)
+static int
+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 };
@@ -1762,8 +1787,8 @@ acd_start_stop(struct acd_softc *cdp, int32_t start)
return atapi_queue_cmd(cdp->atp, ccb, NULL, 0, 0, 30, NULL, NULL);
}
-static int32_t
-acd_pause_resume(struct acd_softc *cdp, int32_t pause)
+static int
+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 };
@@ -1771,13 +1796,12 @@ acd_pause_resume(struct acd_softc *cdp, int32_t pause)
return atapi_queue_cmd(cdp->atp, ccb, NULL, 0, 0, 30, NULL, NULL);
}
-static int32_t
-acd_mode_sense(struct acd_softc *cdp, u_int8_t page,
- void *pagebuf, int32_t pagesize)
+static int
+acd_mode_sense(struct acd_softc *cdp, int page, caddr_t pagebuf, int pagesize)
{
int8_t ccb[16] = { ATAPI_MODE_SENSE_BIG, 0, page, 0, 0, 0, 0,
pagesize>>8, pagesize, 0, 0, 0, 0, 0, 0, 0 };
- int32_t error;
+ int error;
error = atapi_queue_cmd(cdp->atp, ccb, pagebuf, pagesize, ATPR_F_READ, 10,
NULL, NULL);
@@ -1787,8 +1811,8 @@ acd_mode_sense(struct acd_softc *cdp, u_int8_t page,
return error;
}
-static int32_t
-acd_mode_select(struct acd_softc *cdp, void *pagebuf, int32_t pagesize)
+static int
+acd_mode_select(struct acd_softc *cdp, caddr_t pagebuf, int pagesize)
{
int8_t ccb[16] = { ATAPI_MODE_SELECT_BIG, 0x10, 0, 0, 0, 0, 0,
pagesize>>8, pagesize, 0, 0, 0, 0, 0, 0, 0 };
@@ -1800,8 +1824,8 @@ acd_mode_select(struct acd_softc *cdp, void *pagebuf, int32_t pagesize)
return atapi_queue_cmd(cdp->atp, ccb, pagebuf, pagesize, 0, 30, NULL, NULL);
}
-static int32_t
-acd_set_speed(struct acd_softc *cdp, int32_t speed)
+static int
+acd_set_speed(struct acd_softc *cdp, int speed)
{
int8_t ccb[16] = { ATAPI_SET_SPEED, 0, 0xff, 0xff, speed>>8, speed,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
diff --git a/sys/dev/ata/atapi-cd.h b/sys/dev/ata/atapi-cd.h
index 72b70e8..478305a 100644
--- a/sys/dev/ata/atapi-cd.h
+++ b/sys/dev/ata/atapi-cd.h
@@ -309,8 +309,8 @@ struct acd_track_info {
/* Structure describing an ATAPI CDROM device */
struct acd_softc {
struct atapi_softc *atp; /* controller structure */
- int32_t lun; /* logical device unit */
- int32_t flags; /* device state flags */
+ int lun; /* logical device unit */
+ int flags; /* device state flags */
#define F_LOCKED 0x0001 /* this unit is locked */
struct bio_queue_head bio_queue; /* Queue of i/o requests */
@@ -335,9 +335,9 @@ struct acd_softc {
} subchan;
struct changer *changer_info; /* changer info */
struct acd_softc **driver; /* softc's of changer slots */
- int32_t slot; /* this instance slot number */
+ int slot; /* this instance slot number */
time_t timestamp; /* this instance timestamp */
- u_int32_t block_size; /* blocksize currently used */
+ int block_size; /* blocksize currently used */
struct disklabel disklabel; /* fake disk label */
struct devstat *stats; /* devstat entry */
dev_t dev1, dev2; /* device place holders */
diff --git a/sys/dev/ata/atapi-fd.c b/sys/dev/ata/atapi-fd.c
index abeac02..fe2573b 100644
--- a/sys/dev/ata/atapi-fd.c
+++ b/sys/dev/ata/atapi-fd.c
@@ -67,19 +67,19 @@ static struct cdevsw afd_cdevsw = {
static struct cdevsw afddisk_cdevsw;
/* prototypes */
-static int32_t afd_sense(struct afd_softc *);
+static int afd_sense(struct afd_softc *);
static void afd_describe(struct afd_softc *);
-static int32_t afd_partial_done(struct atapi_request *);
-static int32_t afd_done(struct atapi_request *);
-static int32_t afd_eject(struct afd_softc *, int32_t);
-static int32_t afd_start_stop(struct afd_softc *, int32_t);
-static int32_t afd_prevent_allow(struct afd_softc *, int32_t);
+static int afd_partial_done(struct atapi_request *);
+static int afd_done(struct atapi_request *);
+static int afd_eject(struct afd_softc *, int);
+static int afd_start_stop(struct afd_softc *, int);
+static int afd_prevent_allow(struct afd_softc *, int);
/* internal vars */
static u_int32_t afd_lun_map = 0;
MALLOC_DEFINE(M_AFD, "AFD driver", "ATAPI floppy driver buffers");
-int32_t
+int
afdattach(struct atapi_softc *atp)
{
struct afd_softc *fdp;
@@ -133,14 +133,14 @@ afddetach(struct atapi_softc *atp)
free(fdp, M_AFD);
}
-static int32_t
+static int
afd_sense(struct afd_softc *fdp)
{
int8_t buffer[256];
int8_t ccb[16] = { ATAPI_MODE_SENSE_BIG, 0, ATAPI_REWRITEABLE_CAP_PAGE,
0, 0, 0, 0, sizeof(buffer)>>8, sizeof(buffer) & 0xff,
0, 0, 0, 0, 0, 0, 0 };
- int32_t count, error = 0;
+ int count, error = 0;
bzero(buffer, sizeof(buffer));
/* get drive capabilities, some drives needs this repeated */
@@ -217,7 +217,7 @@ afd_describe(struct afd_softc *fdp)
}
static int
-afdopen(dev_t dev, int32_t flags, int32_t fmt, struct proc *p)
+afdopen(dev_t dev, int flags, int fmt, struct proc *p)
{
struct afd_softc *fdp = dev->si_drv1;
struct disklabel *label = &fdp->disk.d_label;
@@ -243,7 +243,7 @@ afdopen(dev_t dev, int32_t flags, int32_t fmt, struct proc *p)
}
static int
-afdclose(dev_t dev, int32_t flags, int32_t fmt, struct proc *p)
+afdclose(dev_t dev, int flags, int fmt, struct proc *p)
{
struct afd_softc *fdp = dev->si_drv1;
@@ -253,7 +253,7 @@ afdclose(dev_t dev, int32_t flags, int32_t fmt, struct proc *p)
}
static int
-afdioctl(dev_t dev, u_long cmd, caddr_t addr, int32_t flag, struct proc *p)
+afdioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct proc *p)
{
struct afd_softc *fdp = dev->si_drv1;
@@ -277,7 +277,7 @@ static void
afdstrategy(struct bio *bp)
{
struct afd_softc *fdp = bp->bio_dev->si_drv1;
- int32_t s;
+ int s;
/* if it's a null transfer, return immediatly. */
if (bp->bio_bcount == 0) {
@@ -297,9 +297,10 @@ afd_start(struct atapi_softc *atp)
{
struct afd_softc *fdp = atp->driver;
struct bio *bp = bioq_first(&fdp->bio_queue);
- u_int32_t lba, count;
+ u_int32_t lba;
+ u_int16_t count;
int8_t ccb[16];
- int8_t *data_ptr;
+ caddr_t data_ptr;
if (!bp)
return;
@@ -357,7 +358,7 @@ afd_start(struct atapi_softc *atp)
(bp->bio_cmd == BIO_READ) ? ATPR_F_READ : 0, 30, afd_done, bp);
}
-static int32_t
+static int
afd_partial_done(struct atapi_request *request)
{
struct bio *bp = request->driver;
@@ -370,7 +371,7 @@ afd_partial_done(struct atapi_request *request)
return 0;
}
-static int32_t
+static int
afd_done(struct atapi_request *request)
{
struct bio *bp = request->driver;
@@ -387,10 +388,10 @@ afd_done(struct atapi_request *request)
return 0;
}
-static int32_t
-afd_eject(struct afd_softc *fdp, int32_t close)
+static int
+afd_eject(struct afd_softc *fdp, int close)
{
- int32_t error;
+ int error;
if ((error = afd_start_stop(fdp, 0)) == EBUSY) {
if (!close)
@@ -409,12 +410,12 @@ afd_eject(struct afd_softc *fdp, int32_t close)
return afd_start_stop(fdp, 2);
}
-static int32_t
-afd_start_stop(struct afd_softc *fdp, int32_t start)
+static int
+afd_start_stop(struct afd_softc *fdp, int start)
{
int8_t ccb[16] = { ATAPI_START_STOP, 0x01, 0, 0, start,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
- int32_t error;
+ int error;
error = atapi_queue_cmd(fdp->atp, ccb, NULL, 0, 0, 10, NULL, NULL);
if (error)
@@ -422,8 +423,8 @@ afd_start_stop(struct afd_softc *fdp, int32_t start)
return atapi_wait_ready(fdp->atp, 30);
}
-static int32_t
-afd_prevent_allow(struct afd_softc *fdp, int32_t lock)
+static int
+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 };
diff --git a/sys/dev/ata/atapi-fd.h b/sys/dev/ata/atapi-fd.h
index d68474a..203dcea 100644
--- a/sys/dev/ata/atapi-fd.h
+++ b/sys/dev/ata/atapi-fd.h
@@ -72,8 +72,8 @@ struct afd_cappage {
struct afd_softc {
struct atapi_softc *atp; /* controller structure */
- int32_t lun; /* logical device unit */
- int32_t transfersize; /* max size of each transfer */
+ int lun; /* logical device unit */
+ int transfersize; /* max size of each transfer */
struct bio_queue_head bio_queue; /* queue of i/o requests */
struct afd_header header; /* capabilities page info */
struct afd_cappage cap; /* capabilities page info */
diff --git a/sys/dev/ata/atapi-tape.c b/sys/dev/ata/atapi-tape.c
index aaa2be7..e390b3f 100644
--- a/sys/dev/ata/atapi-tape.c
+++ b/sys/dev/ata/atapi-tape.c
@@ -65,32 +65,32 @@ static struct cdevsw ast_cdevsw = {
};
/* prototypes */
-static int32_t ast_sense(struct ast_softc *);
+static int ast_sense(struct ast_softc *);
static void ast_describe(struct ast_softc *);
-static int32_t ast_done(struct atapi_request *);
-static int32_t ast_mode_sense(struct ast_softc *, u_int8_t, void *, int32_t);
-static int32_t ast_mode_select(struct ast_softc *, void *, int32_t);
-static int32_t ast_write_filemark(struct ast_softc *, u_int8_t);
-static int32_t ast_read_position(struct ast_softc *, int32_t, struct ast_readposition *);
-static int32_t ast_space(struct ast_softc *, u_int8_t, u_int32_t);
-static int32_t ast_locate(struct ast_softc *, int32_t, int32_t);
-static int32_t ast_prevent_allow(struct ast_softc *stp, int32_t lock);
-static int32_t ast_load_unload(struct ast_softc *, u_int8_t);
-static int32_t ast_rewind(struct ast_softc *);
-static int32_t ast_erase(struct ast_softc *);
+static int ast_done(struct atapi_request *);
+static int ast_mode_sense(struct ast_softc *, int, void *, int);
+static int ast_mode_select(struct ast_softc *, void *, int);
+static int ast_write_filemark(struct ast_softc *, u_int8_t);
+static int ast_read_position(struct ast_softc *, int, struct ast_readposition *);
+static int ast_space(struct ast_softc *, u_int8_t, int32_t);
+static int ast_locate(struct ast_softc *, int, u_int32_t);
+static int ast_prevent_allow(struct ast_softc *stp, int);
+static int ast_load_unload(struct ast_softc *, u_int8_t);
+static int ast_rewind(struct ast_softc *);
+static int ast_erase(struct ast_softc *);
/* internal vars */
static u_int32_t ast_lun_map = 0;
static u_int64_t ast_total = 0;
MALLOC_DEFINE(M_AST, "AST driver", "ATAPI tape driver buffers");
-int32_t
+int
astattach(struct atapi_softc *atp)
{
struct ast_softc *stp;
struct ast_readposition position;
dev_t dev;
- static int32_t ast_cdev_done = 0;
+ static int ast_cdev_done = 0;
if (!ast_cdev_done) {
cdevsw_add(&ast_cdevsw);
@@ -161,10 +161,10 @@ astdetach(struct atapi_softc *atp)
free(stp, M_AST);
}
-static int32_t
+static int
ast_sense(struct ast_softc *stp)
{
- int32_t count, error = 0;
+ int count, error = 0;
/* get drive capabilities, some drives needs this repeated */
for (count = 0 ; count < 5 ; count++) {
@@ -245,7 +245,7 @@ ast_describe(struct ast_softc *stp)
}
static int
-astopen(dev_t dev, int32_t flags, int32_t fmt, struct proc *p)
+astopen(dev_t dev, int flags, int fmt, struct proc *p)
{
struct ast_softc *stp = dev->si_drv1;
@@ -270,7 +270,7 @@ astopen(dev_t dev, int32_t flags, int32_t fmt, struct proc *p)
}
static int
-astclose(dev_t dev, int32_t flags, int32_t fmt, struct proc *p)
+astclose(dev_t dev, int flags, int fmt, struct proc *p)
{
struct ast_softc *stp = dev->si_drv1;
@@ -298,10 +298,10 @@ astclose(dev_t dev, int32_t flags, int32_t fmt, struct proc *p)
}
static int
-astioctl(dev_t dev, u_long cmd, caddr_t addr, int32_t flag, struct proc *p)
+astioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct proc *p)
{
struct ast_softc *stp = dev->si_drv1;
- int32_t error = 0;
+ int error = 0;
switch (cmd) {
case MTIOCGET:
@@ -323,7 +323,7 @@ astioctl(dev_t dev, u_long cmd, caddr_t addr, int32_t flag, struct proc *p)
}
case MTIOCTOP:
{
- int32_t i;
+ int i;
struct mtop *mt = (struct mtop *)addr;
switch ((int16_t) (mt->mt_op)) {
@@ -413,7 +413,7 @@ static void
aststrategy(struct bio *bp)
{
struct ast_softc *stp = bp->bio_dev->si_drv1;
- int32_t s;
+ int s;
/* if it's a null transfer, return immediatly. */
if (bp->bio_bcount == 0) {
@@ -485,7 +485,7 @@ ast_start(struct atapi_softc *atp)
(bp->bio_cmd == BIO_READ) ? ATPR_F_READ : 0, 60, ast_done, bp);
}
-static int32_t
+static int
ast_done(struct atapi_request *request)
{
struct bio *bp = request->driver;
@@ -506,13 +506,12 @@ ast_done(struct atapi_request *request)
return 0;
}
-static int32_t
-ast_mode_sense(struct ast_softc *stp, u_int8_t page,
- void *pagebuf, int32_t pagesize)
+static int
+ast_mode_sense(struct ast_softc *stp, int page, void *pagebuf, int pagesize)
{
int8_t ccb[16] = { ATAPI_MODE_SENSE, 0x08, page, pagesize>>8, pagesize,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
- int32_t error;
+ int error;
error = atapi_queue_cmd(stp->atp, ccb, pagebuf, pagesize, ATPR_F_READ, 10,
NULL, NULL);
@@ -522,8 +521,8 @@ ast_mode_sense(struct ast_softc *stp, u_int8_t page,
return error;
}
-static int32_t
-ast_mode_select(struct ast_softc *stp, void *pagebuf, int32_t pagesize)
+static int
+ast_mode_select(struct ast_softc *stp, void *pagebuf, int pagesize)
{
int8_t ccb[16] = { ATAPI_MODE_SELECT, 0x10, 0, pagesize>>8, pagesize,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
@@ -536,12 +535,12 @@ ast_mode_select(struct ast_softc *stp, void *pagebuf, int32_t pagesize)
NULL, NULL);
}
-static int32_t
+static int
ast_write_filemark(struct ast_softc *stp, u_int8_t function)
{
int8_t ccb[16] = { ATAPI_WEOF, 0x01, 0, 0, function, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0 };
- int32_t error;
+ int error;
if (stp->flags & F_ONSTREAM)
ccb[4] = 0x00; /* only flush buffers supported */
@@ -559,15 +558,15 @@ ast_write_filemark(struct ast_softc *stp, u_int8_t function)
return atapi_wait_ready(stp->atp, 10*60);
}
-static int32_t
-ast_read_position(struct ast_softc *stp, int32_t hard,
+static int
+ast_read_position(struct ast_softc *stp, int hard,
struct ast_readposition *position)
{
int8_t ccb[16] = { ATAPI_READ_POSITION, (hard ? 0x01 : 0), 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0 };
- int32_t error;
+ int error;
- error = atapi_queue_cmd(stp->atp, ccb, position,
+ error = atapi_queue_cmd(stp->atp, ccb, (caddr_t)position,
sizeof(struct ast_readposition), ATPR_F_READ, 10,
NULL, NULL);
position->tape = ntohl(position->tape);
@@ -575,8 +574,8 @@ ast_read_position(struct ast_softc *stp, int32_t hard,
return error;
}
-static int32_t
-ast_space(struct ast_softc *stp, u_int8_t function, u_int32_t count)
+static int
+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 };
@@ -584,13 +583,13 @@ ast_space(struct ast_softc *stp, u_int8_t function, u_int32_t count)
return atapi_queue_cmd(stp->atp, ccb, NULL, 0, 0, 60*60, NULL, NULL);
}
-static int32_t
-ast_locate(struct ast_softc *stp, int32_t hard, int32_t pos)
+static int
+ast_locate(struct ast_softc *stp, int hard, u_int32_t pos)
{
int8_t ccb[16] = { ATAPI_LOCATE, 0x01 | (hard ? 0x4 : 0), 0,
pos>>24, pos>>16, pos>>8, pos,
0, 0, 0, 0, 0, 0, 0, 0, 0 };
- int32_t error;
+ int error;
error = atapi_queue_cmd(stp->atp, ccb, NULL, 0, 0, 10, NULL, NULL);
if (error)
@@ -598,8 +597,8 @@ ast_locate(struct ast_softc *stp, int32_t hard, int32_t pos)
return atapi_wait_ready(stp->atp, 60*60);
}
-static int32_t
-ast_prevent_allow(struct ast_softc *stp, int32_t lock)
+static int
+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 };
@@ -607,12 +606,12 @@ ast_prevent_allow(struct ast_softc *stp, int32_t lock)
return atapi_queue_cmd(stp->atp, ccb, NULL, 0, 0,30, NULL, NULL);
}
-static int32_t
+static int
ast_load_unload(struct ast_softc *stp, u_int8_t function)
{
int8_t ccb[16] = { ATAPI_START_STOP, 0x01, 0, 0, function, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0 };
- int32_t error;
+ int error;
if ((function & SS_EJECT) && !stp->cap.eject)
return 0;
@@ -625,12 +624,12 @@ ast_load_unload(struct ast_softc *stp, u_int8_t function)
return atapi_wait_ready(stp->atp, 60*60);
}
-static int32_t
+static int
ast_rewind(struct ast_softc *stp)
{
int8_t ccb[16] = { ATAPI_REWIND, 0x01, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0 };
- int32_t error;
+ int error;
error = atapi_queue_cmd(stp->atp, ccb, NULL, 0, 0, 10, NULL, NULL);
if (error)
@@ -638,12 +637,12 @@ ast_rewind(struct ast_softc *stp)
return atapi_wait_ready(stp->atp, 60*60);
}
-static int32_t
+static int
ast_erase(struct ast_softc *stp)
{
int8_t ccb[16] = { ATAPI_ERASE, 3, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0 };
- int32_t error;
+ int error;
if ((error = ast_rewind(stp)))
return error;
diff --git a/sys/dev/ata/atapi-tape.h b/sys/dev/ata/atapi-tape.h
index 1170579..d978c7f 100644
--- a/sys/dev/ata/atapi-tape.h
+++ b/sys/dev/ata/atapi-tape.h
@@ -145,15 +145,15 @@ struct ast_readposition {
struct ast_softc {
struct atapi_softc *atp; /* controller structure */
- int32_t lun; /* logical device unit */
- int32_t flags; /* device state flags */
+ 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 */
- int32_t blksize; /* block size (512 | 1024) */
+ int blksize; /* block size (512 | 1024) */
struct bio_queue_head bio_queue; /* queue of i/o requests */
struct atapi_params *param; /* drive parameters table */
struct ast_cappage cap; /* capabilities page info */
OpenPOWER on IntegriCloud