diff options
| author | Søren Schmidt <sos@FreeBSD.org> | 2000-08-22 08:41:29 +0000 |
|---|---|---|
| committer | Søren Schmidt <sos@FreeBSD.org> | 2000-08-22 08:41:29 +0000 |
| commit | 9410ca24df16efb5ffc00cb5d3ad94edfc7256b3 (patch) | |
| tree | 332013ba5967b590e124b00488af77086ac9e106 | |
| parent | f30b7f18adf9a1c6aa7feea3900a80960ff820e9 (diff) | |
Notes
| -rw-r--r-- | sys/dev/ata/ata-all.c | 170 | ||||
| -rw-r--r-- | sys/dev/ata/ata-all.h | 1 | ||||
| -rw-r--r-- | sys/dev/ata/ata-disk.c | 33 | ||||
| -rw-r--r-- | sys/dev/ata/ata-dma.c | 339 | ||||
| -rw-r--r-- | sys/dev/ata/atapi-cd.c | 98 | ||||
| -rw-r--r-- | sys/dev/ata/atapi-cd.h | 3 |
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 */ |
