summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSøren Schmidt <sos@FreeBSD.org>2000-08-22 08:41:29 +0000
committerSøren Schmidt <sos@FreeBSD.org>2000-08-22 08:41:29 +0000
commit9410ca24df16efb5ffc00cb5d3ad94edfc7256b3 (patch)
tree332013ba5967b590e124b00488af77086ac9e106
parentf30b7f18adf9a1c6aa7feea3900a80960ff820e9 (diff)
Notes
-rw-r--r--sys/dev/ata/ata-all.c170
-rw-r--r--sys/dev/ata/ata-all.h1
-rw-r--r--sys/dev/ata/ata-disk.c33
-rw-r--r--sys/dev/ata/ata-dma.c339
-rw-r--r--sys/dev/ata/atapi-cd.c98
-rw-r--r--sys/dev/ata/atapi-cd.h3
6 files changed, 378 insertions, 266 deletions
diff --git a/sys/dev/ata/ata-all.c b/sys/dev/ata/ata-all.c
index 12ddcceeb55e..f5330038569c 100644
--- a/sys/dev/ata/ata-all.c
+++ b/sys/dev/ata/ata-all.c
@@ -254,11 +254,14 @@ ata_pci_match(device_t dev)
case 0x71998086:
return "Intel PIIX4 ATA33 controller";
+ case 0x24218086:
+ return "Intel ICH0 ATA33 controller";
+
case 0x24118086:
return "Intel ICH ATA66 controller";
- case 0x24218086:
- return "Intel ICH0 ATA33 controller";
+ case 0x244b8086:
+ return "Intel ICH2 ATA100 controller";
case 0x522910b9:
return "AcerLabs Aladdin ATA33 controller";
@@ -267,7 +270,7 @@ ata_pci_match(device_t dev)
if (ata_find_dev(dev, 0x05861106, 0))
return "VIA 82C586 ATA33 controller";
if (ata_find_dev(dev, 0x05961106, 0x12))
- return "VIA 82C596B ATA66 controller";
+ return "VIA 82C596 ATA66 controller";
if (ata_find_dev(dev, 0x05961106, 0))
return "VIA 82C596 ATA33 controller";
if (ata_find_dev(dev, 0x06861106, 0))
@@ -294,8 +297,22 @@ ata_pci_match(device_t dev)
case 0x4d38105a:
return "Promise ATA66 controller";
+ case 0x4d30105a:
+ return "Promise ATA100 controller";
+
case 0x00041103:
- return "HighPoint HPT366 ATA66 controller";
+ switch (pci_get_revid(dev)) {
+ case 0x00:
+ case 0x01:
+ return "HighPoint HPT366 ATA66 controller";
+ case 0x02:
+ return "HighPoint HPT368 ATA66 controller";
+ case 0x03:
+ case 0x04:
+ return "HighPoint HPT370 ATA100 controller";
+ default:
+ return "Unknown revision HighPoint ATA controller";
+ }
/* unsupported but known chipsets, generic DMA only */
case 0x10001042:
@@ -379,8 +396,9 @@ ata_pci_attach(device_t dev)
device_printf(dev, "Busmastering DMA not enabled\n");
}
else {
- if (type == 0x4d33105a || type == 0x4d38105a || type == 0x00041103) {
- /* Promise and HPT366 controllers support busmastering DMA */
+ if (type == 0x4d33105a || type == 0x4d38105a ||
+ type == 0x4d30105a || type == 0x00041103) {
+ /* Promise and HighPoint controllers support busmastering DMA */
rid = 0x20;
sc->bmio = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid,
0, ~0, 1, RF_ACTIVE);
@@ -398,6 +416,7 @@ ata_pci_attach(device_t dev)
break;
case 0x4d38105a: /* Promise 66's need their clock changed */
+ case 0x4d30105a: /* Promise 100's too */
outb(rman_get_start(sc->bmio) + 0x11,
inb(rman_get_start(sc->bmio) + 0x11) | 0x0a);
/* FALLTHROUGH */
@@ -407,8 +426,25 @@ ata_pci_attach(device_t dev)
inb(rman_get_start(sc->bmio) + 0x1f) | 0x01);
break;
- case 0x00041103: /* HPT366 turn of fast interrupt prediction */
- pci_write_config(dev, 0x51, (pci_read_config(dev, 0x51, 1) & ~0x80), 1);
+ case 0x00041103: /* HighPoint's need to turn off interrupt prediction */
+ switch (pci_get_revid(dev)) {
+ case 0x00:
+ case 0x01:
+ pci_write_config(dev, 0x51,
+ (pci_read_config(dev, 0x51, 1) & ~0x80), 1);
+ break;
+
+ case 0x02:
+ case 0x03:
+ case 0x04:
+ 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);
+ pci_write_config(dev, 0x5a,
+ (pci_read_config(dev, 0x5a, 1) & ~0x10), 1);
+
+ }
break;
case 0x05711106:
@@ -699,16 +735,7 @@ ata_pcisub_probe(device_t dev)
/* kids of pci ata chipsets has their physical unit number in ivars */
scp->unit = (uintptr_t) device_get_ivars(dev);
-
- /* set the chiptype to the hostchip ID, makes life easier */
- if (ata_find_dev(device_get_parent(dev), 0x05861106, 0))
- scp->chiptype = 0x05861106;
- else if (ata_find_dev(device_get_parent(dev), 0x05961106, 0))
- scp->chiptype = 0x05961106;
- else if (ata_find_dev(device_get_parent(dev), 0x06861106, 0))
- scp->chiptype = 0x06861106;
- else
- scp->chiptype = pci_get_devid(device_get_parent(dev));
+ scp->chiptype = pci_get_devid(device_get_parent(dev));
return ata_probe(dev);
}
@@ -801,50 +828,13 @@ ata_probe(device_t dev)
goto failure;
ata_reset(scp, &mask);
- if (!mask)
- goto failure;
- /*
- * OK, we have at least one device on the chain, check for ATAPI
- * signatures, if none check if its a good old ATA device.
- */
- outb(scp->ioaddr + ATA_DRIVE, (ATA_D_IBM | ATA_MASTER));
- DELAY(1);
- if (inb(scp->ioaddr + ATA_CYL_LSB) == ATAPI_MAGIC_LSB &&
- inb(scp->ioaddr + ATA_CYL_MSB) == ATAPI_MAGIC_MSB) {
- scp->devices |= ATA_ATAPI_MASTER;
- }
- outb(scp->ioaddr + ATA_DRIVE, (ATA_D_IBM | ATA_SLAVE));
- DELAY(1);
- if (inb(scp->ioaddr + ATA_CYL_LSB) == ATAPI_MAGIC_LSB &&
- inb(scp->ioaddr + ATA_CYL_MSB) == ATAPI_MAGIC_MSB) {
- scp->devices |= ATA_ATAPI_SLAVE;
- }
- if (status0 != 0x00 && !(scp->devices & ATA_ATAPI_MASTER)) {
- outb(scp->ioaddr + ATA_DRIVE, (ATA_D_IBM | ATA_MASTER));
- DELAY(1);
- outb(scp->ioaddr + ATA_ERROR, 0x58);
- outb(scp->ioaddr + ATA_CYL_LSB, 0xa5);
- if (inb(scp->ioaddr + ATA_ERROR) != 0x58 &&
- inb(scp->ioaddr + ATA_CYL_LSB) == 0xa5) {
- scp->devices |= ATA_ATA_MASTER;
- }
- }
- if (status1 != 0x00 && !(scp->devices & ATA_ATAPI_SLAVE)) {
- outb(scp->ioaddr + ATA_DRIVE, (ATA_D_IBM | ATA_SLAVE));
- DELAY(1);
- outb(scp->ioaddr + ATA_ERROR, 0x58);
- outb(scp->ioaddr + ATA_CYL_LSB, 0xa5);
- if (inb(scp->ioaddr + ATA_ERROR) != 0x58 &&
- inb(scp->ioaddr + ATA_CYL_LSB) == 0xa5) {
- scp->devices |= ATA_ATA_SLAVE;
- }
- }
if (bootverbose)
ata_printf(scp, -1, "devices = 0x%x\n", scp->devices);
- if (!scp->devices) {
+
+ if (!mask)
goto failure;
- }
+
TAILQ_INIT(&scp->ata_queue);
TAILQ_INIT(&scp->atapi_queue);
return 0;
@@ -1086,7 +1076,7 @@ ata_intr(void *data)
*/
switch (scp->chiptype) {
#if NPCI > 0
- case 0x00041103: /* HighPoint HPT366 */
+ case 0x00041103: /* HighPoint HPT366/368/370 */
if (!((dmastat = ata_dmastatus(scp)) & ATA_BMSTAT_INTERRUPT))
return;
outb(scp->bmaddr + ATA_BMSTAT_PORT, dmastat | ATA_BMSTAT_INTERRUPT);
@@ -1094,6 +1084,7 @@ ata_intr(void *data)
case 0x4d33105a: /* Promise 33's */
case 0x4d38105a: /* Promise 66's */
+ case 0x4d30105a: /* Promise 100's */
{
struct ata_pci_softc *sc=device_get_softc(device_get_parent(scp->dev));
@@ -1214,7 +1205,7 @@ void
ata_reset(struct ata_softc *scp, int32_t *mask)
{
int32_t timeout;
- u_int8_t status0 = 0, status1 = 0;
+ u_int8_t status0 = ATA_S_BUSY, status1 = ATA_S_BUSY;
/* reset channel */
outb(scp->ioaddr + ATA_DRIVE, ATA_D_IBM | ATA_MASTER);
@@ -1229,12 +1220,28 @@ ata_reset(struct ata_softc *scp, int32_t *mask)
/* wait for BUSY to go inactive */
for (timeout = 0; timeout < 310000; timeout++) {
- outb(scp->ioaddr + ATA_DRIVE, ATA_D_IBM | ATA_MASTER);
- DELAY(1);
- status0 = inb(scp->ioaddr + ATA_STATUS);
- outb(scp->ioaddr + ATA_DRIVE, ATA_D_IBM | ATA_SLAVE);
- DELAY(1);
- status1 = inb(scp->ioaddr + ATA_STATUS);
+ if (status0 & ATA_S_BUSY) {
+ outb(scp->ioaddr + ATA_DRIVE, ATA_D_IBM | ATA_MASTER);
+ DELAY(1);
+ status0 = inb(scp->ioaddr + ATA_STATUS);
+ if (!(status0 & ATA_S_BUSY)) {
+ /* check for ATAPI signature while its still there */
+ if (inb(scp->ioaddr + ATA_CYL_LSB) == ATAPI_MAGIC_LSB &&
+ inb(scp->ioaddr + ATA_CYL_MSB) == ATAPI_MAGIC_MSB)
+ scp->devices |= ATA_ATAPI_MASTER;
+ }
+ }
+ if (status1 & ATA_S_BUSY) {
+ outb(scp->ioaddr + ATA_DRIVE, ATA_D_IBM | ATA_SLAVE);
+ DELAY(1);
+ status1 = inb(scp->ioaddr + ATA_STATUS);
+ if (!(status1 & ATA_S_BUSY)) {
+ /* check for ATAPI signature while its still there */
+ if (inb(scp->ioaddr + ATA_CYL_LSB) == ATAPI_MAGIC_LSB &&
+ inb(scp->ioaddr + ATA_CYL_MSB) == ATAPI_MAGIC_MSB)
+ scp->devices |= ATA_ATAPI_SLAVE;
+ }
+ }
if (*mask == 0x01) /* wait for master only */
if (!(status0 & ATA_S_BUSY))
break;
@@ -1255,6 +1262,34 @@ ata_reset(struct ata_softc *scp, int32_t *mask)
if (bootverbose)
ata_printf(scp, -1, "mask=%02x status0=%02x status1=%02x\n",
*mask, status0, status1);
+ if (!mask) {
+ scp->devices = 0;
+ return;
+ }
+ /*
+ * OK, we have at least one device on the chain, checks for ATAPI
+ * already done, if none check if its a good old ATA device.
+ */
+ if (status0 != 0x00 && !(scp->devices & ATA_ATAPI_MASTER)) {
+ outb(scp->ioaddr + ATA_DRIVE, (ATA_D_IBM | ATA_MASTER));
+ DELAY(1);
+ outb(scp->ioaddr + ATA_ERROR, 0x58);
+ outb(scp->ioaddr + ATA_CYL_LSB, 0xa5);
+ if (inb(scp->ioaddr + ATA_ERROR) != 0x58 &&
+ inb(scp->ioaddr + ATA_CYL_LSB) == 0xa5) {
+ scp->devices |= ATA_ATA_MASTER;
+ }
+ }
+ if (status1 != 0x00 && !(scp->devices & ATA_ATAPI_SLAVE)) {
+ outb(scp->ioaddr + ATA_DRIVE, (ATA_D_IBM | ATA_SLAVE));
+ DELAY(1);
+ outb(scp->ioaddr + ATA_ERROR, 0x58);
+ outb(scp->ioaddr + ATA_CYL_LSB, 0xa5);
+ if (inb(scp->ioaddr + ATA_ERROR) != 0x58 &&
+ inb(scp->ioaddr + ATA_CYL_LSB) == 0xa5) {
+ scp->devices |= ATA_ATA_SLAVE;
+ }
+ }
}
int32_t
@@ -1460,6 +1495,7 @@ ata_mode2str(int32_t mode)
case ATA_WDMA2: return "WDMA2";
case ATA_UDMA2: return "UDMA33";
case ATA_UDMA4: return "UDMA66";
+ case ATA_UDMA5: return "UDMA100";
case ATA_DMA: return "BIOSDMA";
default: return "???";
}
@@ -1512,6 +1548,8 @@ int
ata_umode(struct ata_params *ap)
{
if (ap->atavalid & ATA_FLAG_88) {
+ if (ap->udmamodes & 0x20)
+ return 5;
if (ap->udmamodes & 0x10)
return 4;
if (ap->udmamodes & 0x08)
diff --git a/sys/dev/ata/ata-all.h b/sys/dev/ata/ata-all.h
index 14a3d971882e..811b98966ef8 100644
--- a/sys/dev/ata/ata-all.h
+++ b/sys/dev/ata/ata-all.h
@@ -279,6 +279,7 @@ struct ata_softc {
#define ATA_WDMA2 0x22
#define ATA_UDMA2 0x42
#define ATA_UDMA4 0x44
+#define ATA_UDMA5 0x45
int32_t flags; /* controller flags */
#define ATA_DMA_ACTIVE 0x01
diff --git a/sys/dev/ata/ata-disk.c b/sys/dev/ata/ata-disk.c
index 31ac11c15635..50f56d9510b0 100644
--- a/sys/dev/ata/ata-disk.c
+++ b/sys/dev/ata/ata-disk.c
@@ -134,11 +134,13 @@ ad_attach(struct ata_softc *scp, int32_t device)
/* use multiple sectors/interrupt if device supports it */
adp->transfersize = DEV_BSIZE;
- 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)
+ if (ad_version(AD_PARAM->versmajor)) {
+ 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)
adp->transfersize *= secsperint;
+ }
/* enable read/write cacheing if not default on device */
if (ata_command(adp->controller, adp->unit, ATA_C_SETFEATURES,
@@ -413,7 +415,7 @@ ad_transfer(struct ad_request *request)
if (ata_command(adp->controller, adp->unit, cmd,
cylinder, head, sector, count, 0, ATA_IMMEDIATE)) {
- printf("ad%d: error executing command\n", adp->lun);
+ printf("ad%d: error executing command", adp->lun);
goto transfer_failed;
}
@@ -451,12 +453,21 @@ ad_transfer(struct ad_request *request)
transfer_failed:
untimeout((timeout_t *)ad_timeout, request, request->timeout_handle);
- request->bp->b_error = EIO;
- request->bp->b_flags |= B_ERROR;
- request->bp->b_resid = request->bytecount;
- devstat_end_transaction_buf(&adp->stats, request->bp);
- biodone(request->bp);
- free(request, M_AD);
+ printf(" - resetting\n");
+
+ /* if retries still permit, reinject this request */
+ if (request->retries++ < AD_MAX_RETRIES)
+ TAILQ_INSERT_HEAD(&adp->controller->ata_queue, request, chain);
+ else {
+ /* retries all used up, return error */
+ request->bp->b_error = EIO;
+ request->bp->b_flags |= B_ERROR;
+ request->bp->b_resid = request->bytecount;
+ devstat_end_transaction_buf(&adp->stats, request->bp);
+ biodone(request->bp);
+ free(request, M_AD);
+ }
+ ata_reinit(adp->controller);
}
int32_t
diff --git a/sys/dev/ata/ata-dma.c b/sys/dev/ata/ata-dma.c
index 503e68d81234..2c856925ba3c 100644
--- a/sys/dev/ata/ata-dma.c
+++ b/sys/dev/ata/ata-dma.c
@@ -48,7 +48,7 @@
/* prototypes */
static void promise_timing(struct ata_softc *, int32_t, int32_t);
-static void hpt366_timing(struct ata_softc *, int32_t, int32_t);
+static void hpt_timing(struct ata_softc *, int32_t, int32_t);
/* misc defines */
#ifdef __alpha__
@@ -61,8 +61,8 @@ ata_dmainit(struct ata_softc *scp, int32_t device,
int32_t apiomode, int32_t wdmamode, int32_t udmamode)
{
device_t parent = device_get_parent(scp->dev);
- int32_t devno = (scp->unit << 1) + ATA_DEV(device);
- int32_t error;
+ int devno = (scp->unit << 1) + ATA_DEV(device);
+ int error;
/* set our most pessimistic default mode */
scp->mode[ATA_DEV(device)] = ATA_PIO;
@@ -101,6 +101,36 @@ ata_dmainit(struct ata_softc *scp, int32_t device,
switch (scp->chiptype) {
+ case 0x244b8086: /* Intel ICH2 */
+ if (udmamode >= 5) {
+ int32_t mask48, new48;
+ int16_t word54;
+
+ word54 = pci_read_config(parent, 0x54, 2);
+ if (word54 & (0x10 << devno)) {
+ error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
+ ATA_UDMA5, ATA_C_F_SETXFER,ATA_WAIT_READY);
+ if (bootverbose)
+ ata_printf(scp, device,
+ "%s setting UDMA5 on ICH2 chip\n",
+ (error) ? "failed" : "success");
+ if (!error) {
+ mask48 = (1 << devno) + (3 << (16 + (devno << 2)));
+ new48 = (1 << devno) + (1 << (16 + (devno << 2)));
+ pci_write_config(parent, 0x48,
+ (pci_read_config(parent, 0x48, 4) &
+ ~mask48) | new48, 4);
+ pci_write_config(parent, 0x54, word54 | (0x1000<<devno), 2);
+ scp->mode[ATA_DEV(device)] = ATA_UDMA5;
+ return;
+ }
+ }
+ }
+ /* make sure eventual ATA100 mode from the BIOS is disabled */
+ pci_write_config(parent, 0x54,
+ pci_read_config(parent, 0x54, 2) & ~(0x1000<<devno),2);
+ /* FALLTHROUGH */
+
case 0x24118086: /* Intel ICH */
if (udmamode >= 4) {
int32_t mask48, new48;
@@ -112,8 +142,9 @@ ata_dmainit(struct ata_softc *scp, int32_t device,
ATA_UDMA4, ATA_C_F_SETXFER,ATA_WAIT_READY);
if (bootverbose)
ata_printf(scp, device,
- "%s setting up UDMA4 mode on ICH chip\n",
- (error) ? "failed" : "success");
+ "%s setting UDMA4 on ICH%s chip\n",
+ (error) ? "failed" : "success",
+ (scp->chiptype == 0x244b8086) ? "2" : "");
if (!error) {
mask48 = (1 << devno) + (3 << (16 + (devno << 2)));
new48 = (1 << devno) + (2 << (16 + (devno << 2)));
@@ -126,6 +157,9 @@ ata_dmainit(struct ata_softc *scp, int32_t device,
}
}
}
+ /* make sure eventual ATA66 mode from the BIOS is disabled */
+ pci_write_config(parent, 0x54,
+ pci_read_config(parent, 0x54, 2) & ~(1 << devno), 2);
/* FALLTHROUGH */
case 0x71118086: /* Intel PIIX4 */
@@ -137,10 +171,11 @@ ata_dmainit(struct ata_softc *scp, int32_t device,
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 up UDMA2 mode on %s chip\n",
+ ata_printf(scp, device, "%s setting UDMA2 on %s chip\n",
(error) ? "failed" : "success",
- (scp->chiptype == 0x24118086) ? "ICH" :
- (scp->chiptype == 0x24218086) ? "ICH0" :"PIIX4");
+ (scp->chiptype == 0x244b8086) ? "ICH2" :
+ (scp->chiptype == 0x24118086) ? "ICH" :
+ (scp->chiptype == 0x24218086) ? "ICH0" :"PIIX4");
if (!error) {
mask48 = (1 << devno) + (3 << (16 + (devno << 2)));
new48 = (1 << devno) + (2 << (16 + (devno << 2)));
@@ -151,6 +186,9 @@ ata_dmainit(struct ata_softc *scp, int32_t device,
return;
}
}
+ /* make sure eventual ATA33 mode from the BIOS is disabled */
+ pci_write_config(parent, 0x48,
+ pci_read_config(parent, 0x48, 4) & ~(1 << devno), 4);
/* FALLTHROUGH */
case 0x70108086: /* Intel PIIX3 */
@@ -176,11 +214,12 @@ ata_dmainit(struct ata_softc *scp, int32_t device,
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 up WDMA2 mode on %s chip\n",
+ ata_printf(scp, device, "%s setting WDMA2 on %s chip\n",
(error) ? "failed" : "success",
- (scp->chiptype == 0x70108086) ? "PIIX3" :
+ (scp->chiptype == 0x244b8086) ? "ICH2" :
(scp->chiptype == 0x24118086) ? "ICH" :
- (scp->chiptype == 0x24218086) ? "ICH0" :"PIIX4");
+ (scp->chiptype == 0x24218086) ? "ICH0" :
+ (scp->chiptype == 0x70108086) ? "PIIX3":"PIIX4");
if (!error) {
if (device == ATA_MASTER) {
mask40 = 0x0000330f;
@@ -229,7 +268,7 @@ ata_dmainit(struct ata_softc *scp, int32_t device,
ATA_WDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY);
if (bootverbose)
ata_printf(scp, device,
- "%s setting up WDMA2 mode on PIIX chip\n",
+ "%s setting WDMA2 on PIIX chip\n",
(error) ? "failed" : "success");
if (!error) {
scp->mode[ATA_DEV(device)] = ATA_WDMA2;
@@ -252,7 +291,7 @@ ata_dmainit(struct ata_softc *scp, int32_t device,
ATA_UDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY);
if (bootverbose)
ata_printf(scp, device,
- "%s setting up UDMA2 mode on Aladdin chip\n",
+ "%s setting UDMA2 on Aladdin chip\n",
(error) ? "failed" : "success");
if (!error) {
word54 &= ~(0x000f000f << (devno << 2));
@@ -270,7 +309,7 @@ ata_dmainit(struct ata_softc *scp, int32_t device,
ATA_WDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY);
if (bootverbose)
ata_printf(scp, device,
- "%s setting up WDMA2 mode on Aladdin chip\n",
+ "%s setting WDMA2 on Aladdin chip\n",
(error) ? "failed" : "success");
if (!error) {
pci_write_config(parent, 0x53,
@@ -291,7 +330,7 @@ ata_dmainit(struct ata_softc *scp, int32_t device,
ATA_UDMA4, ATA_C_F_SETXFER, ATA_WAIT_READY);
if (bootverbose)
ata_printf(scp, device,
- "%s setting up UDMA4 mode on AMD chip\n",
+ "%s setting UDMA4 on AMD chip\n",
(error) ? "failed" : "success");
if (!error) {
pci_write_config(parent, 0x53 - devno, 0xc3, 1);
@@ -301,69 +340,59 @@ ata_dmainit(struct ata_softc *scp, int32_t device,
}
goto via_82c586;
- case 0x06861106: /* VIA 82C686 */
-via_82c686:
- if (udmamode >= 4) {
- error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
- ATA_UDMA4, ATA_C_F_SETXFER, ATA_WAIT_READY);
- if (bootverbose)
- ata_printf(scp, device,
- "%s setting up UDMA4 mode on VIA chip\n",
- (error) ? "failed" : "success");
- if (!error) {
- pci_write_config(parent, 0x53 - devno, 0xe8, 1);
- scp->mode[ATA_DEV(device)] = ATA_UDMA4;
- return;
+ case 0x05711106: /* VIA 82C571, 82C586, 82C596, 82C686 */
+ if (ata_find_dev(parent, 0x06861106, 0) || /* 82C686a */
+ ata_find_dev(parent, 0x05961106, 0x12)) { /* 82C596b */
+
+ if (udmamode >= 4) {
+ error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
+ ATA_UDMA4, ATA_C_F_SETXFER, ATA_WAIT_READY);
+ if (bootverbose)
+ ata_printf(scp, device,
+ "%s setting UDMA4 on VIA chip\n",
+ (error) ? "failed" : "success");
+ if (!error) {
+ pci_write_config(parent, 0x53 - devno, 0xe8, 1);
+ scp->mode[ATA_DEV(device)] = ATA_UDMA4;
+ return;
+ }
}
- }
- 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 up UDMA2 mode on VIA chip\n",
- (error) ? "failed" : "success");
- if (!error) {
- pci_write_config(parent, 0x53 - devno, 0xea, 1);
- scp->mode[ATA_DEV(device)] = ATA_UDMA2;
- return;
+ 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 VIA chip\n",
+ (error) ? "failed" : "success");
+ if (!error) {
+ pci_write_config(parent, 0x53 - devno, 0xea, 1);
+ scp->mode[ATA_DEV(device)] = ATA_UDMA2;
+ return;
+ }
}
}
- goto via_generic;
-
- case 0x05961106: /* VIA 82C596 */
- /* 82c596 revision >= 0x12 is like the 82c686 */
- if (ata_find_dev(parent, 0x05961106, 0x12))
- goto via_82c686;
- /* FALLTHROUGH */
-
- case 0x05861106: /* VIA 82C586 */
+ else if (ata_find_dev(parent, 0x05961106, 0) || /* 82C596a */
+ ata_find_dev(parent, 0x05861106, 0x02)) { /* 82C586b */
via_82c586:
- /* UDMA2 mode only on 82C586 > rev1, 82C596, AMD 756 */
- if ((udmamode >= 2 && ata_find_dev(parent, 0x05861106, 0x02)) ||
- (udmamode >= 2 && scp->chiptype == 0x05961106) ||
- (udmamode >= 2 && scp->chiptype == 0x74091022)) {
- 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 up UDMA2 mode on %s chip\n",
- (error) ? "failed" : "success",
- (scp->chiptype == 0x74091022) ? "AMD" : "VIA");
- if (!error) {
- pci_write_config(parent, 0x53 - devno, 0xc0, 1);
- scp->mode[ATA_DEV(device)] = ATA_UDMA2;
- return;
+ 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 %s chip\n",
+ (error) ? "failed" : "success",
+ (scp->chiptype == 0x74091022) ? "AMD" : "VIA");
+ if (!error) {
+ pci_write_config(parent, 0x53 - devno, 0xc0, 1);
+ scp->mode[ATA_DEV(device)] = ATA_UDMA2;
+ return;
+ }
}
}
- /* FALLTHROUGH */
-
- case 0x05711106: /* VIA 82C571 */
-via_generic:
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 up WDMA2 mode on %s chip\n",
+ ata_printf(scp, device, "%s setting WDMA2 on %s chip\n",
(error) ? "failed" : "success",
(scp->chiptype == 0x74091022) ? "AMD" : "VIA");
if (!error) {
@@ -382,7 +411,7 @@ via_generic:
ATA_UDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY);
if (bootverbose)
ata_printf(scp, device,
- "%s setting up UDMA2 mode on SiS chip\n",
+ "%s setting UDMA2 on SiS chip\n",
(error) ? "failed" : "success");
if (!error) {
pci_write_config(parent, 0x40 + (devno << 1), 0xa301, 2);
@@ -395,7 +424,7 @@ via_generic:
ATA_WDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY);
if (bootverbose)
ata_printf(scp, device,
- "%s setting up WDMA2 mode on SiS chip\n",
+ "%s setting WDMA2 on SiS chip\n",
(error) ? "failed" : "success");
if (!error) {
pci_write_config(parent, 0x40 + (devno << 1), 0x0301, 2);
@@ -412,7 +441,7 @@ via_generic:
ATA_WDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY);
if (bootverbose)
ata_printf(scp, device,
- "%s setting up WDMA2 mode on CMD646 chip\n",
+ "%s setting WDMA2 on CMD646 chip\n",
error ? "failed" : "success");
if (!error) {
int32_t offset = (devno < 3) ? (devno << 1) : 7;
@@ -431,7 +460,7 @@ via_generic:
ATA_WDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY);
if (bootverbose)
ata_printf(scp, device,
- "%s setting up WDMA2 mode on Cypress chip\n",
+ "%s setting WDMA2 on Cypress chip\n",
error ? "failed" : "success");
if (!error) {
pci_write_config(scp->dev, scp->unit ? 0x4e : 0x4c, 0x2020, 2);
@@ -444,18 +473,34 @@ via_generic:
case 0x4d33105a: /* Promise Ultra33 / FastTrak33 controllers */
case 0x4d38105a: /* Promise Ultra66 / FastTrak66 controllers */
+ case 0x4d30105a: /* Promise Ultra100 / FastTrak100 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 >=4 && scp->chiptype == 0x4d38105a &&
+ if (udmamode >=5 && scp->chiptype == 0x4d30105a &&
+ !(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);
+ if (bootverbose)
+ ata_printf(scp, device,
+ "%s setting UDMA5 on Promise chip\n",
+ (error) ? "failed" : "success");
+ if (!error) {
+ promise_timing(scp, devno, ATA_UDMA5);
+ scp->mode[ATA_DEV(device)] = ATA_UDMA5;
+ return;
+ }
+ }
+ if (udmamode >=4 &&
+ (scp->chiptype == 0x4d38105a || scp->chiptype == 0x4d30105a) &&
!(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);
if (bootverbose)
ata_printf(scp, device,
- "%s setting up UDMA4 mode on Promise chip\n",
+ "%s setting UDMA4 on Promise chip\n",
(error) ? "failed" : "success");
if (!error) {
promise_timing(scp, devno, ATA_UDMA4);
@@ -468,7 +513,7 @@ via_generic:
ATA_UDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY);
if (bootverbose)
ata_printf(scp, device,
- "%s setting up UDMA2 mode on Promise chip\n",
+ "%s setting UDMA2 on Promise chip\n",
(error) ? "failed" : "success");
if (!error) {
promise_timing(scp, devno, ATA_UDMA2);
@@ -481,7 +526,7 @@ via_generic:
ATA_WDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY);
if (bootverbose)
ata_printf(scp, device,
- "%s setting up WDMA2 mode on Promise chip\n",
+ "%s setting WDMA2 on Promise chip\n",
(error) ? "failed" : "success");
if (!error) {
promise_timing(scp, devno, ATA_WDMA2);
@@ -494,28 +539,44 @@ via_generic:
ATA_C_F_SETXFER, ATA_WAIT_READY);
if (bootverbose)
ata_printf(scp, device,
- "%s setting up PIO%d mode on Promise chip\n",
+ "%s setting PIO%d on Promise chip\n",
(error) ? "failed" : "success",
(apiomode >= 0) ? apiomode : 0);
promise_timing(scp, devno, ata_pio2mode(apiomode));
scp->mode[ATA_DEV(device)] = ata_pio2mode(apiomode);
return;
- case 0x00041103: /* HighPoint HPT366 controller */
+ case 0x00041103: /* HighPoint HPT366/368/370 controllers */
/* no ATAPI devices for now */
if ((device == ATA_MASTER && scp->devices & ATA_ATAPI_MASTER) ||
(device == ATA_SLAVE && scp->devices & ATA_ATAPI_SLAVE))
break;
- if (udmamode >=4 && !(pci_read_config(parent, 0x5a, 1) & 0x2)) {
+ if (udmamode >=5 && pci_get_revid(parent) >= 0x03 &&
+ !(pci_read_config(parent, 0x5a, 1) & (scp->unit ? 0x01 : 0x02))) {
+ error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
+ ATA_UDMA5, ATA_C_F_SETXFER, ATA_WAIT_READY);
+ if (bootverbose)
+ ata_printf(scp, device,
+ "%s setting UDMA5 on HPT370 chip\n",
+ (error) ? "failed" : "success");
+ if (!error) {
+ hpt_timing(scp, devno, ATA_UDMA5);
+ scp->mode[ATA_DEV(device)] = ATA_UDMA5;
+ return;
+ }
+ }
+
+ if (udmamode >=4 &&
+ !(pci_read_config(parent, 0x5a, 1) & (scp->unit ? 0x01 : 0x02))) {
error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
ATA_UDMA4, ATA_C_F_SETXFER, ATA_WAIT_READY);
if (bootverbose)
ata_printf(scp, device,
- "%s setting up UDMA4 mode on HPT366 chip\n",
+ "%s setting UDMA4 on HPT366 chip\n",
(error) ? "failed" : "success");
if (!error) {
- hpt366_timing(scp, devno, ATA_UDMA4);
+ hpt_timing(scp, devno, ATA_UDMA4);
scp->mode[ATA_DEV(device)] = ATA_UDMA4;
return;
}
@@ -525,10 +586,10 @@ via_generic:
ATA_UDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY);
if (bootverbose)
ata_printf(scp, device,
- "%s setting up UDMA2 mode on HPT366 chip\n",
+ "%s setting UDMA2 on HPT366 chip\n",
(error) ? "failed" : "success");
if (!error) {
- hpt366_timing(scp, devno, ATA_UDMA2);
+ hpt_timing(scp, devno, ATA_UDMA2);
scp->mode[ATA_DEV(device)] = ATA_UDMA2;
return;
}
@@ -538,10 +599,10 @@ via_generic:
ATA_WDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY);
if (bootverbose)
ata_printf(scp, device,
- "%s setting up WDMA2 mode on HPT366 chip\n",
+ "%s setting WDMA2 on HPT366 chip\n",
(error) ? "failed" : "success");
if (!error) {
- hpt366_timing(scp, devno, ATA_WDMA2);
+ hpt_timing(scp, devno, ATA_WDMA2);
scp->mode[ATA_DEV(device)] = ATA_WDMA2;
return;
}
@@ -550,10 +611,10 @@ via_generic:
ata_pio2mode(apiomode),
ATA_C_F_SETXFER, ATA_WAIT_READY);
if (bootverbose)
- ata_printf(scp, device, "%s setting up PIO%d mode on HPT366 chip\n",
+ ata_printf(scp, device, "%s setting PIO%d on HPT366 chip\n",
(error) ? "failed" : "success",
(apiomode >= 0) ? apiomode : 0);
- hpt366_timing(scp, devno, ata_pio2mode(apiomode));
+ hpt_timing(scp, devno, ata_pio2mode(apiomode));
scp->mode[ATA_DEV(device)] = ata_pio2mode(apiomode);
return;
@@ -579,7 +640,7 @@ via_generic:
ATA_WDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY);
if (bootverbose)
ata_printf(scp, device,
- "%s setting up WDMA2 mode on generic chip\n",
+ "%s setting WDMA2 on generic chip\n",
(error) ? "failed" : "success");
if (!error) {
scp->mode[ATA_DEV(device)] = ATA_WDMA2;
@@ -590,7 +651,7 @@ via_generic:
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 up PIO%d mode on generic chip\n",
+ ata_printf(scp, device, "%s setting PIO%d on generic chip\n",
(error) ? "failed" : "success", apiomode < 0 ? 0 : apiomode);
if (!error)
scp->mode[ATA_DEV(device)] = ata_pio2mode(apiomode);
@@ -607,7 +668,7 @@ ata_dmasetup(struct ata_softc *scp, int32_t device,
{
struct ata_dmaentry *dmatab;
u_int32_t dma_count, dma_base;
- int32_t i = 0;
+ int i = 0;
if (((uintptr_t)data & 1) || (count & 1))
return -1;
@@ -708,6 +769,7 @@ promise_timing(struct ata_softc *scp, int32_t devno, int32_t mode)
break;
case 0x4d38105a: /* Promise 66's */
+ case 0x4d30105a: /* Promise 100's */
switch (mode) {
default:
case ATA_PIO0: t->pa = 15; t->pb = 31; t->mb = 7; t->mc = 15; break;
@@ -718,6 +780,7 @@ promise_timing(struct ata_softc *scp, int32_t devno, int32_t mode)
case ATA_WDMA2: t->pa = 6; t->pb = 14; t->mb = 6; t->mc = 6; break;
case ATA_UDMA2: t->pa = 6; t->pb = 14; t->mb = 2; t->mc = 2; break;
case ATA_UDMA4: t->pa = 3; t->pb = 7; t->mb = 1; t->mc = 1; break;
+ case ATA_UDMA5: t->pa = 3; t->pb = 7; t->mb = 1; t->mc = 1; break;
}
break;
}
@@ -725,53 +788,71 @@ promise_timing(struct ata_softc *scp, int32_t devno, int32_t mode)
}
static void
-hpt366_timing(struct ata_softc *scp, int32_t devno, int32_t mode)
+hpt_timing(struct ata_softc *scp, int32_t devno, int32_t mode)
{
device_t parent = device_get_parent(scp->dev);
u_int32_t timing;
- switch (pci_read_config(parent, 0x41 + (devno << 2), 1)) {
- case 0x85: /* 25Mhz */
+ if (pci_get_revid(parent) >= 0x03) { /* HPT370 */
switch (mode) {
- case ATA_PIO0: timing = 0xc0d08585; break;
- case ATA_PIO1: timing = 0xc0d08572; break;
- case ATA_PIO2: timing = 0xc0ca8542; break;
- case ATA_PIO3: timing = 0xc0ca8532; break;
- case ATA_PIO4: timing = 0xc0ca8521; break;
- case ATA_WDMA2: timing = 0xa0ca8521; break;
- case ATA_UDMA2: timing = 0x90cf8521; break;
- case ATA_UDMA4: timing = 0x90c98521; break;
- default: timing = 0x01208585;
+ case ATA_PIO0: timing = 0x06914e57; break;
+ case ATA_PIO1: timing = 0x06914e43; break;
+ case ATA_PIO2: timing = 0x06514e33; break;
+ case ATA_PIO3: timing = 0x06514e22; break;
+ case ATA_PIO4: timing = 0x06514e21; break;
+ case ATA_WDMA2: timing = 0x26514e21; break;
+ case ATA_UDMA2: timing = 0x16494e31; break;
+ case ATA_UDMA4: timing = 0x16454e31; break;
+ case ATA_UDMA5: timing = 0x16454e31; break;
+ default: timing = 0x06514e57;
}
- break;
- default:
- case 0xa7: /* 33MHz */
- switch (mode) {
- case ATA_PIO0: timing = 0xc0d0a7aa; break;
- case ATA_PIO1: timing = 0xc0d0a7a3; break;
- case ATA_PIO2: timing = 0xc0d0a753; break;
- case ATA_PIO3: timing = 0xc0c8a742; break;
- case ATA_PIO4: timing = 0xc0c8a731; break;
- case ATA_WDMA2: timing = 0xa0c8a731; break;
- case ATA_UDMA2: timing = 0x90caa731; break;
- case ATA_UDMA4: timing = 0x90c9a731; break;
- default: timing = 0x0120a7a7;
- }
- break;
- case 0xd9: /* 40Mhz */
- switch (mode) {
- case ATA_PIO0: timing = 0xc018d9d9; break;
- case ATA_PIO1: timing = 0xc010d9c7; break;
- case ATA_PIO2: timing = 0xc010d997; break;
- case ATA_PIO3: timing = 0xc010d974; break;
- case ATA_PIO4: timing = 0xc008d963; break;
- case ATA_WDMA2: timing = 0xa008d943; break;
- case ATA_UDMA2: timing = 0x900bd943; break;
- case ATA_UDMA4: timing = 0x900fd943; break;
- default: timing = 0x0120d9d9;
+ pci_write_config(parent, 0x40 + (devno << 2) , timing, 4);
+ pci_write_config(parent, 0x5b, 0x22, 1);
+ }
+ else { /* HPT36[68] */
+ switch (pci_read_config(parent, 0x41 + (devno << 2), 1)) {
+ case 0x85: /* 25Mhz */
+ switch (mode) {
+ case ATA_PIO0: timing = 0xc0d08585; break;
+ case ATA_PIO1: timing = 0xc0d08572; break;
+ case ATA_PIO2: timing = 0xc0ca8542; break;
+ case ATA_PIO3: timing = 0xc0ca8532; break;
+ case ATA_PIO4: timing = 0xc0ca8521; break;
+ case ATA_WDMA2: timing = 0xa0ca8521; break;
+ case ATA_UDMA2: timing = 0x90cf8521; break;
+ case ATA_UDMA4: timing = 0x90c98521; break;
+ default: timing = 0x01208585;
+ }
+ break;
+ default:
+ case 0xa7: /* 33MHz */
+ switch (mode) {
+ case ATA_PIO0: timing = 0xc0d0a7aa; break;
+ case ATA_PIO1: timing = 0xc0d0a7a3; break;
+ case ATA_PIO2: timing = 0xc0d0a753; break;
+ case ATA_PIO3: timing = 0xc0c8a742; break;
+ case ATA_PIO4: timing = 0xc0c8a731; break;
+ case ATA_WDMA2: timing = 0xa0c8a731; break;
+ case ATA_UDMA2: timing = 0x90caa731; break;
+ case ATA_UDMA4: timing = 0x90c9a731; break;
+ default: timing = 0x0120a7a7;
+ }
+ break;
+ case 0xd9: /* 40Mhz */
+ switch (mode) {
+ case ATA_PIO0: timing = 0xc018d9d9; break;
+ case ATA_PIO1: timing = 0xc010d9c7; break;
+ case ATA_PIO2: timing = 0xc010d997; break;
+ case ATA_PIO3: timing = 0xc010d974; break;
+ case ATA_PIO4: timing = 0xc008d963; break;
+ case ATA_WDMA2: timing = 0xa008d943; break;
+ case ATA_UDMA2: timing = 0x900bd943; break;
+ case ATA_UDMA4: timing = 0x900fd943; break;
+ default: timing = 0x0120d9d9;
+ }
}
+ pci_write_config(parent, 0x40 + (devno << 2), (timing & ~0x80000000),4);
}
- pci_write_config(parent, 0x40 + (devno << 2) , (timing & ~0x80000000), 4);
}
#else /* NPCI > 0 */
diff --git a/sys/dev/ata/atapi-cd.c b/sys/dev/ata/atapi-cd.c
index e21a428f255b..ea81904839d4 100644
--- a/sys/dev/ata/atapi-cd.c
+++ b/sys/dev/ata/atapi-cd.c
@@ -145,7 +145,8 @@ acdattach(struct atapi_softc *atp)
chp = malloc(sizeof(struct changer), M_ACD, M_NOWAIT);
if (chp == NULL) {
printf("acd: out of memory\n");
- return 0;
+ free(cdp, M_ACD);
+ return -1;
}
bzero(chp, sizeof(struct changer));
error = atapi_queue_cmd(cdp->atp, ccb, chp, sizeof(struct changer),
@@ -161,6 +162,8 @@ acdattach(struct atapi_softc *atp)
if (!(cdparr = malloc(sizeof(struct acd_softc) * chp->slots,
M_ACD, M_NOWAIT))) {
printf("acd: out of memory\n");
+ free(chp, M_ACD);
+ free(cdp, M_ACD);
return -1;
}
for (count = 0; count < chp->slots; count++) {
@@ -168,7 +171,7 @@ acdattach(struct atapi_softc *atp)
tmpcdp = acd_init_lun(atp, cdp->stats);
if (!tmpcdp) {
printf("acd: out of memory\n");
- return -1;
+ break;
}
}
cdparr[count] = tmpcdp;
@@ -234,7 +237,6 @@ acd_init_lun(struct atapi_softc *atp, struct devstat *stats)
bufq_init(&cdp->buf_queue);
cdp->atp = atp;
cdp->lun = ata_get_lun(&acd_lun_map);
- cdp->flags &= ~(F_WRITTEN|F_DISK_OPEN|F_TRACK_OPEN);
cdp->block_size = 2048;
cdp->slot = -1;
cdp->changer_info = NULL;
@@ -484,9 +486,17 @@ msf2lba(u_int8_t m, u_int8_t s, u_int8_t f)
static int
acdopen(dev_t dev, int32_t flags, int32_t fmt, struct proc *p)
{
- struct acd_softc *cdp = dev->si_drv1;
+ struct acd_softc *cdp;
+ int track = (dev->si_udev & 0x00ff0000) >> 16;
- if (!cdp)
+ if (track) {
+ dev_t dev1 = makedev(major(dev), (dev->si_udev & 0xff0000ff));
+
+ if (track <= ((struct acd_softc*)(dev1->si_drv1))->toc.hdr.ending_track)
+ dev->si_drv1 = dev1->si_drv1;
+ }
+
+ if (!(cdp = dev->si_drv1))
return ENXIO;
if (flags & FWRITE) {
@@ -514,6 +524,9 @@ acdclose(dev_t dev, int32_t flags, int32_t fmt, struct proc *p)
{
struct acd_softc *cdp = dev->si_drv1;
+ if (!cdp)
+ return ENXIO;
+
if (count_dev(dev) == 1) {
if (cdp->changer_info && cdp->slot != cdp->changer_info->current_slot) {
acd_select_slot(cdp);
@@ -531,6 +544,9 @@ acdioctl(dev_t dev, u_long cmd, caddr_t addr, int32_t flags, struct proc *p)
struct acd_softc *cdp = dev->si_drv1;
int32_t error = 0;
+ if (!cdp)
+ return ENXIO;
+
if (cdp->changer_info && cdp->slot != cdp->changer_info->current_slot) {
acd_select_slot(cdp);
tsleep(&cdp->changer_info, PRIBIO, "acdctl", 0);
@@ -977,51 +993,18 @@ acdioctl(dev_t dev, u_long cmd, caddr_t addr, int32_t flags, struct proc *p)
break;
case CDRIOCOPENDISK:
- if ((cdp->flags & F_WRITTEN) || (cdp->flags & F_DISK_OPEN)) {
- error = EINVAL;
- printf("acd%d: sequence error (disk already open)\n", cdp->lun);
- }
- cdp->flags &= ~(F_WRITTEN | F_TRACK_OPEN);
- cdp->flags |= F_DISK_OPEN;
break;
case CDRIOCOPENTRACK:
- if (!(cdp->flags & F_DISK_OPEN)) {
- error = EINVAL;
- printf("acd%d: sequence error (disk not open)\n", cdp->lun);
- }
- else {
- if ((error = acd_open_track(cdp, (struct cdr_track *)addr)))
- break;
- cdp->flags |= F_TRACK_OPEN;
- }
+ error = acd_open_track(cdp, (struct cdr_track *)addr);
break;
case CDRIOCCLOSETRACK:
- if (!(cdp->flags & F_TRACK_OPEN)) {
- error = EINVAL;
- printf("acd%d: sequence error (no track open)\n", cdp->lun);
- }
- else {
- if (cdp->flags & F_WRITTEN) {
- acd_close_track(cdp);
- cdp->flags &= ~F_TRACK_OPEN;
- }
- }
+ error = acd_close_track(cdp);
break;
case CDRIOCCLOSEDISK:
- if (!(cdp->flags & F_DISK_OPEN)) {
- error = EINVAL;
- printf("acd%d: sequence error (nothing to close)\n", cdp->lun);
- }
- else if (!(cdp->flags & F_WRITTEN)) {
- cdp->flags &= ~(F_DISK_OPEN | F_TRACK_OPEN);
- }
- else {
- error = acd_close_disk(cdp);
- cdp->flags &= ~(F_WRITTEN | F_DISK_OPEN | F_TRACK_OPEN);
- }
+ error = acd_close_disk(cdp);
break;
case CDRIOCWRITESPEED:
@@ -1113,6 +1096,7 @@ acd_start(struct atapi_softc *atp)
struct buf *bp = bufq_first(&cdp->buf_queue);
u_int32_t lba, count;
int8_t ccb[16];
+ int track, blocksize;
if (cdp->changer_info) {
int i;
@@ -1145,11 +1129,18 @@ acd_start(struct atapi_softc *atp)
}
bzero(ccb, sizeof(ccb));
- count = (bp->b_bcount + (cdp->block_size - 1)) / cdp->block_size;
- if (bp->b_flags & B_PHYS)
- lba = bp->b_offset / cdp->block_size;
+
+ lba = bp->b_offset / cdp->block_size;
+ track = (bp->b_dev->si_udev & 0x00ff0000) >> 16;
+
+ if (track) {
+ lba += ntohl(cdp->toc.tab[track - 1].addr.lba);
+ blocksize = (cdp->toc.tab[track - 1].control & 4) ? 2048 : 2352;
+ }
else
- lba = bp->b_blkno / (cdp->block_size / DEV_BSIZE);
+ blocksize = cdp->block_size;
+
+ count = (bp->b_bcount + (blocksize - 1)) / blocksize;
if (bp->b_flags & B_READ) {
/* if transfer goes beyond EOM adjust it to be within limits */
@@ -1161,7 +1152,7 @@ acd_start(struct atapi_softc *atp)
return;
}
}
- if (cdp->block_size == 2048)
+ if (blocksize == 2048)
ccb[0] = ATAPI_READ_BIG;
else {
ccb[0] = ATAPI_READ_CD;
@@ -1181,8 +1172,8 @@ acd_start(struct atapi_softc *atp)
devstat_start_transaction(cdp->stats);
- atapi_queue_cmd(cdp->atp, ccb, bp->b_data, count * cdp->block_size,
- bp->b_flags & B_READ ? ATPR_F_READ : 0, 30, acd_done, bp);
+ atapi_queue_cmd(cdp->atp, ccb, bp->b_data, count * blocksize,
+ bp->b_flags & B_READ ? ATPR_F_READ : 0, 30, acd_done,bp);
}
static int32_t
@@ -1195,11 +1186,8 @@ acd_done(struct atapi_request *request)
bp->b_error = request->error;
bp->b_flags |= B_ERROR;
}
- else {
+ else
bp->b_resid = bp->b_bcount - request->donecount;
- if (!(bp->b_flags & B_READ))
- cdp->flags |= F_WRITTEN;
- }
devstat_end_transaction_buf(cdp->stats, bp);
biodone(bp);
return 0;
@@ -1217,9 +1205,6 @@ acd_read_toc(struct acd_softc *cdp)
atapi_test_ready(cdp->atp);
- if (cdp->atp->flags & ATAPI_F_MEDIA_CHANGED)
- cdp->flags &= ~(F_WRITTEN | F_DISK_OPEN | F_TRACK_OPEN);
-
cdp->atp->flags &= ~ATAPI_F_MEDIA_CHANGED;
len = sizeof(struct ioc_toc_header) + sizeof(struct cd_toc_entry);
@@ -1258,6 +1243,7 @@ acd_read_toc(struct acd_softc *cdp)
cdp->info.volsize = ntohl(cdp->info.volsize);
cdp->info.blksize = ntohl(cdp->info.blksize);
+ cdp->block_size = (cdp->toc.tab[0].control & 4) ? 2048 : 2352;
#ifdef ACD_DEBUG
if (cdp->info.volsize && cdp->toc.hdr.ending_track) {
@@ -1739,7 +1725,6 @@ acd_eject(struct acd_softc *cdp, int32_t close)
return 0;
acd_prevent_allow(cdp, 0);
cdp->flags &= ~F_LOCKED;
- cdp->flags &= ~(F_WRITTEN | F_DISK_OPEN | F_TRACK_OPEN);
cdp->atp->flags |= ATAPI_F_MEDIA_CHANGED;
return acd_start_stop(cdp, 2);
}
@@ -1752,7 +1737,6 @@ acd_blank(struct acd_softc *cdp)
int32_t error;
error = atapi_queue_cmd(cdp->atp, ccb, NULL, 0, 0, 60*60, NULL, NULL);
- cdp->flags &= ~(F_WRITTEN | F_DISK_OPEN | F_TRACK_OPEN);
cdp->atp->flags |= ATAPI_F_MEDIA_CHANGED;
return error;
}
diff --git a/sys/dev/ata/atapi-cd.h b/sys/dev/ata/atapi-cd.h
index f99ac3ecbbdd..8bd91284781e 100644
--- a/sys/dev/ata/atapi-cd.h
+++ b/sys/dev/ata/atapi-cd.h
@@ -312,9 +312,6 @@ struct acd_softc {
int32_t lun; /* logical device unit */
int32_t flags; /* device state flags */
#define F_LOCKED 0x0001 /* this unit is locked */
-#define F_WRITTEN 0x0002 /* medium has been written to */
-#define F_DISK_OPEN 0x0004 /* disk open for writing */
-#define F_TRACK_OPEN 0x0008 /* track open for writing */
struct buf_queue_head buf_queue; /* Queue of i/o requests */
struct toc toc; /* table of disc contents */