diff --git a/sys/dev/ata/ata-all.c b/sys/dev/ata/ata-all.c index 01ebc464fca1..023f73a08a8f 100644 --- a/sys/dev/ata/ata-all.c +++ b/sys/dev/ata/ata-all.c @@ -287,10 +287,9 @@ ata_resume(device_t dev) static int ataioctl(dev_t dev, u_long cmd, caddr_t addr, int32_t flag, struct proc *p) { - struct ata_cmd *iocmd = (struct ata_cmd *)addr; device_t device; - int error = 0; + int error; if (cmd != IOCATA) return ENOTTY; @@ -304,15 +303,16 @@ ataioctl(dev_t dev, u_long cmd, caddr_t addr, int32_t flag, struct proc *p) switch (iocmd->cmd) { case ATAATTACH: { /* should enable channel HW on controller that can SOS XXX */ - if (!(error = ata_probe(device))) + error = ata_probe(device); + if (!error) error = ata_attach(device); - break; + return error; } case ATADETACH: { error = ata_detach(device); /* should disable channel HW on controller that can SOS XXX */ - break; + return error; } case ATAREINIT: { @@ -329,7 +329,7 @@ ataioctl(dev_t dev, u_long cmd, caddr_t addr, int32_t flag, struct proc *p) tsleep((caddr_t)&s, PRIBIO, "atachm", hz/4); error = ata_reinit(scp); splx(s); - break; + return error; } case ATAGMODE: { @@ -346,7 +346,7 @@ ataioctl(dev_t dev, u_long cmd, caddr_t addr, int32_t flag, struct proc *p) iocmd->u.mode.mode[SLAVE] = scp->mode[SLAVE]; else iocmd->u.mode.mode[SLAVE] = -1; - break; + return 0; } case ATASMODE: { @@ -368,7 +368,7 @@ ataioctl(dev_t dev, u_long cmd, caddr_t addr, int32_t flag, struct proc *p) } else iocmd->u.mode.mode[SLAVE] = -1; - break; + return 0; } case ATAGPARM: { @@ -394,13 +394,10 @@ ataioctl(dev_t dev, u_long cmd, caddr_t addr, int32_t flag, struct proc *p) if (scp->dev_param[SLAVE]) bcopy(scp->dev_param[SLAVE], &iocmd->u.param.params[SLAVE], sizeof(struct ata_params)); - break; + return 0; } - - default: - error = ENOTTY; } - return error; + return ENOTTY; } static int diff --git a/sys/dev/ata/ata-all.h b/sys/dev/ata/ata-all.h index 9eab30be132f..652255bae814 100644 --- a/sys/dev/ata/ata-all.h +++ b/sys/dev/ata/ata-all.h @@ -74,6 +74,7 @@ #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_SLEEP 0xe6 /* sleep command */ #define ATA_C_FLUSHCACHE 0xe7 /* flush cache to disk */ #define ATA_C_ATA_IDENTIFY 0xec /* get ATA params */ #define ATA_C_SETFEATURES 0xef /* features command */ diff --git a/sys/dev/ata/ata-disk.c b/sys/dev/ata/ata-disk.c index d1950af17ab6..338485f74829 100644 --- a/sys/dev/ata/ata-disk.c +++ b/sys/dev/ata/ata-disk.c @@ -53,11 +53,12 @@ /* device structures */ static d_open_t adopen; +static d_close_t adclose; static d_strategy_t adstrategy; static d_dump_t addump; static struct cdevsw ad_cdevsw = { /* open */ adopen, - /* close */ nullclose, + /* close */ adclose, /* read */ physread, /* write */ physwrite, /* ioctl */ noioctl, @@ -103,7 +104,7 @@ SYSCTL_INT(_hw_ata, OID_AUTO, tags, CTLFLAG_RD, &ata_tags, 0, #define AD_PARAM ATA_PARAM(adp->controller, adp->unit) /* experimental cache flush on BIO_ORDERED */ -#define ATA_FLUSHCACHE_ON +#undef ATA_FLUSHCACHE_ON void ad_attach(struct ata_softc *scp, int device) @@ -260,6 +261,18 @@ adopen(dev_t dev, int flags, int fmt, struct proc *p) return 0; } +static int +adclose(dev_t dev, int flags, int fmt, struct proc *p) +{ + struct ad_softc *adp = dev->si_drv1; + + if (ata_command(adp->controller, adp->unit, ATA_C_FLUSHCACHE, + 0, 0, 0, 0, 0, ATA_WAIT_READY)) + ata_printf(adp->controller, adp->unit, + "flushing cache on close failed\n"); + return 0; +} + static void adstrategy(struct bio *bp) { @@ -582,9 +595,10 @@ ad_interrupt(struct ad_request *request) struct ad_softc *adp = request->device; int dma_stat = 0; +#ifdef ATA_FLUSHCACHE_ON if (request->flags & ADR_F_FLUSHCACHE) goto finish; - +#endif /* finish DMA transfer */ if (request->flags & ADR_F_DMA_USED) dma_stat = ata_dmadone(adp->controller); @@ -700,8 +714,8 @@ ad_interrupt(struct ad_request *request) else return ATA_OP_CONTINUES; } -#endif finish: +#endif biofinish(request->bp, &adp->stats, 0); ad_free(request); adp->outstanding--; @@ -856,6 +870,15 @@ ad_tagsupported(struct ad_softc *adp) return 1; i++; } + /* + * check IBM's new obscure way of naming drives + * we want "IC" (IBM CORP) and "AT" or "AV" (ATA interface) + * but doesn't care about the other info (size, capacity etc) + */ + if (!strncmp(AD_PARAM->model, "IC", 2) && + (!strncmp(AD_PARAM->model + 8, "AT", 2) || + !strncmp(AD_PARAM->model + 8, "AV", 2))) + return 1; } return 0; } diff --git a/sys/dev/ata/ata-dma.c b/sys/dev/ata/ata-dma.c index d5c53118a976..22302911f781 100644 --- a/sys/dev/ata/ata-dma.c +++ b/sys/dev/ata/ata-dma.c @@ -54,6 +54,10 @@ static void hpt_timing(struct ata_softc *, int, int); #undef vtophys #define vtophys(va) alpha_XXX_dmamap((vm_offset_t)va) #endif +#define ATAPI_DEVICE(scp, device) \ + ((device == ATA_MASTER && scp->devices & ATA_ATAPI_MASTER) || \ + (device == ATA_SLAVE && scp->devices & ATA_ATAPI_SLAVE)) + void * ata_dmaalloc(struct ata_softc *scp, int device) @@ -718,18 +722,11 @@ ata_dmainit(struct ata_softc *scp, int device, /* we could set PIO mode timings, but we assume the BIOS did that */ break; - 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 */ case 0x4d68105a: /* Promise TX2 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 || - scp->chiptype == 0x0d30105a || scp->chiptype == 0x4d68105a) && + case 0x6268105a: /* Promise TX2v2 ATA100 controllers */ + if (!ATAPI_DEVICE(scp, device) && udmamode >= 5 && !(pci_read_config(parent, 0x50, 2)&(scp->channel ? 1<<11 : 1<<10))){ error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0, ATA_UDMA5, ATA_C_F_SETXFER, ATA_WAIT_READY); @@ -743,9 +740,10 @@ ata_dmainit(struct ata_softc *scp, int device, return; } } - if (udmamode >= 4 && - (scp->chiptype == 0x4d38105a || scp->chiptype == 0x4d30105a || - scp->chiptype == 0x0d30105a || scp->chiptype == 0x4d68105a) && + /* FALLTHROUGH */ + + case 0x4d38105a: /* Promise Ultra/FastTrak 66 controllers */ + if (!ATAPI_DEVICE(scp, device) && udmamode >= 4 && !(pci_read_config(parent, 0x50, 2)&(scp->channel ? 1<<11 : 1<<10))){ error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0, ATA_UDMA4, ATA_C_F_SETXFER, ATA_WAIT_READY); @@ -759,7 +757,10 @@ ata_dmainit(struct ata_softc *scp, int device, return; } } - if (udmamode >= 2) { + /* FALLTHROUGH */ + + case 0x4d33105a: /* Promise Ultra/FastTrak 33 controllers */ + if (!ATAPI_DEVICE(scp, device) && udmamode >= 2) { error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0, ATA_UDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); if (bootverbose) @@ -772,7 +773,7 @@ ata_dmainit(struct ata_softc *scp, int device, return; } } - if (wdmamode >= 2 && apiomode >= 4) { + if (!ATAPI_DEVICE(scp, device) && 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) @@ -798,12 +799,8 @@ ata_dmainit(struct ata_softc *scp, int device, return; 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 >=5 && pci_get_revid(parent) >= 0x03 && + if (!ATAPI_DEVICE(scp, device) && + udmamode >=5 && pci_get_revid(parent) >= 0x03 && !(pci_read_config(parent, 0x5a, 1) & (scp->channel ? 0x01:0x02))) { error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0, ATA_UDMA5, ATA_C_F_SETXFER, ATA_WAIT_READY); @@ -817,7 +814,7 @@ ata_dmainit(struct ata_softc *scp, int device, return; } } - if (udmamode >=4 && + if (!ATAPI_DEVICE(scp, device) && udmamode >=4 && !(pci_read_config(parent, 0x5a, 1) & (scp->channel ? 0x01:0x02))) { error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0, ATA_UDMA4, ATA_C_F_SETXFER, ATA_WAIT_READY); @@ -831,7 +828,7 @@ ata_dmainit(struct ata_softc *scp, int device, return; } } - if (udmamode >= 2) { + if (!ATAPI_DEVICE(scp, device) && udmamode >= 2) { error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0, ATA_UDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); if (bootverbose) @@ -844,7 +841,7 @@ ata_dmainit(struct ata_softc *scp, int device, return; } } - if (wdmamode >= 2 && apiomode >= 4) { + if (!ATAPI_DEVICE(scp, device) && 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) @@ -1048,6 +1045,7 @@ promise_timing(struct ata_softc *scp, int devno, int mode) case 0x4d30105a: /* Promise Ultra/Fasttrak 100 */ case 0x0d30105a: /* Promise OEM ATA 100 */ case 0x4d68105a: /* Promise TX2 ATA 100 */ + case 0x6268105a: /* Promise TX2v2 ATA 100 */ switch (mode) { default: case ATA_PIO0: t->pa = 15; t->pb = 31; t->mb = 7; t->mc = 15; break; diff --git a/sys/dev/ata/ata-pci.c b/sys/dev/ata/ata-pci.c index 0e79b0f518d4..3a743bd39cd6 100644 --- a/sys/dev/ata/ata-pci.c +++ b/sys/dev/ata/ata-pci.c @@ -173,6 +173,7 @@ ata_pci_match(device_t dev) case 0x0d30105a: case 0x4d30105a: case 0x4d68105a: + case 0x6268105a: return "Promise ATA100 controller"; case 0x00041103: @@ -280,6 +281,7 @@ ata_pci_attach(device_t dev) case 0x4d30105a: case 0x0d30105a: case 0x4d68105a: + case 0x6268105a: ATA_OUTB(sc->bmio, 0x11, ATA_INB(sc->bmio, 0x11) | 0x0a); /* FALLTHROUGH */ @@ -335,9 +337,9 @@ ata_pci_attach(device_t dev) /* prepare for ATA-66 on the 82C686 and rev 0x12 and newer 82C596's */ if (ata_find_dev(dev, 0x06861106, 0) || - ata_find_dev(dev, 0x05961106, 0x12)) { + ata_find_dev(dev, 0x05961106, 0x12)) pci_write_config(dev, 0x50, 0x030b030b, 4); - } + break; case 0x10001042: /* RZ 100? known bad, no DMA */ @@ -403,6 +405,7 @@ ata_pci_intr(struct ata_softc *scp) case 0x4d30105a: /* Promise Ultra/Fasttrak 100 */ case 0x0d30105a: /* Promise OEM ATA100 */ case 0x4d68105a: /* Promise TX2 ATA100 */ + case 0x6268105a: /* Promise TX2v2 ATA100 */ if (!(ATA_INL(scp->r_bmio, (scp->channel ? 0x14 : 0x1c)) & (scp->channel ? 0x00004000 : 0x00000400))) return 1; @@ -514,8 +517,7 @@ ata_pci_alloc_resource(device_t dev, device_t child, int type, int *rid, int irq = (channel == 0 ? 14 : 15); return BUS_ALLOC_RESOURCE(device_get_parent(dev), child, - SYS_RES_IRQ, rid, - irq, irq, 1, flags & ~RF_SHAREABLE); + SYS_RES_IRQ, rid, irq, irq, 1, flags); #endif } else { diff --git a/sys/dev/ata/atapi-all.c b/sys/dev/ata/atapi-all.c index b7d902b64726..97372985146f 100644 --- a/sys/dev/ata/atapi-all.c +++ b/sys/dev/ata/atapi-all.c @@ -675,7 +675,7 @@ atapi_cmd2str(u_int8_t cmd) { switch (cmd) { case 0x00: return ("TEST_UNIT_READY"); - case 0x01: return ("REWIND"); + case 0x01: return ("REZERO"); case 0x03: return ("REQUEST_SENSE"); case 0x04: return ("FORMAT_UNIT"); case 0x08: return ("READ"); diff --git a/sys/dev/ata/atapi-all.h b/sys/dev/ata/atapi-all.h index 186009c1d7ef..0b06177ce249 100644 --- a/sys/dev/ata/atapi-all.h +++ b/sys/dev/ata/atapi-all.h @@ -64,7 +64,7 @@ /* ATAPI commands */ #define ATAPI_TEST_UNIT_READY 0x00 /* check if device is ready */ -#define ATAPI_REWIND 0x01 /* rewind */ +#define ATAPI_REZERO 0x01 /* rewind */ #define ATAPI_REQUEST_SENSE 0x03 /* get sense data */ #define ATAPI_FORMAT 0x04 /* format unit */ #define ATAPI_READ 0x08 /* read data */ diff --git a/sys/dev/ata/atapi-cd.c b/sys/dev/ata/atapi-cd.c index 89abf6984c8a..3db545a1efd6 100644 --- a/sys/dev/ata/atapi-cd.c +++ b/sys/dev/ata/atapi-cd.c @@ -1142,11 +1142,12 @@ acd_start(struct atapi_softc *atp) /* if transfer goes beyond range adjust it to be within limits */ if (lba + count > lastlba) { /* if we are entirely beyond EOM return EOF */ - if ((count = lastlba - lba) <= 0) { + if (lastlba <= lba) { bp->bio_resid = bp->bio_bcount; biodone(bp); return; } + count = lastlba - lba; } switch (blocksize) { case 2048: @@ -1380,9 +1381,13 @@ acd_select_slot(struct acd_softc *cdp) static int acd_open_disk(struct acd_softc *cdp) { - int8_t ccb[16] = { ATAPI_SEND_OPC_INFO, 0x01, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0 }; + int8_t ccb[16]; + bzero(ccb, sizeof(ccb)); + ccb[0] = ATAPI_REZERO; + atapi_queue_cmd(cdp->atp, ccb, NULL, 0, ATPR_F_QUIET, 60, NULL, NULL); + ccb[0] = ATAPI_SEND_OPC_INFO; + ccb[1] = 0x01; atapi_queue_cmd(cdp->atp, ccb, NULL, 0, ATPR_F_QUIET, 30, NULL, NULL); return 0; } diff --git a/sys/dev/ata/atapi-tape.c b/sys/dev/ata/atapi-tape.c index fb02a1f9091a..98114c3fd424 100644 --- a/sys/dev/ata/atapi-tape.c +++ b/sys/dev/ata/atapi-tape.c @@ -642,7 +642,7 @@ ast_load_unload(struct ast_softc *stp, u_int8_t function) static int ast_rewind(struct ast_softc *stp) { - int8_t ccb[16] = { ATAPI_REWIND, 0x01, 0, 0, 0, 0, 0, 0, + int8_t ccb[16] = { ATAPI_REZERO, 0x01, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; int error;