summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorsos <sos@FreeBSD.org>2000-09-19 11:08:39 +0000
committersos <sos@FreeBSD.org>2000-09-19 11:08:39 +0000
commit344ad581f6366320298344989520a6c564e88492 (patch)
tree8e1d799ffeab2c7da78b6bc14eb91fad17e910c3 /sys
parent2a2d53f9301ec86ea8b26361641b8e8e55d75f35 (diff)
downloadFreeBSD-src-344ad581f6366320298344989520a6c564e88492.zip
FreeBSD-src-344ad581f6366320298344989520a6c564e88492.tar.gz
Add support for tagged queuing on ATA drives. There is only support for
IBM's DPTA and DTLA series of drives (no other disk vendors are known to support this) on non-Promise controllers (promise controllers lockup when given the tagged queuing specific commands). It gives especially master/slave comboes about 5% better performance. Add support for the Promise ATA100 OEM chip (pdc20265) Add support for the Cyrix 5530 Change the way status is read from the drives, use the alternate status reg when possible. Better support for DEVFS, the acdXtY devices are now created when needed. Lots of little cleanups.
Diffstat (limited to 'sys')
-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