diff options
author | sos <sos@FreeBSD.org> | 2000-01-25 20:14:51 +0000 |
---|---|---|
committer | sos <sos@FreeBSD.org> | 2000-01-25 20:14:51 +0000 |
commit | b5f4230b5557aa4ebed715b6fad6b54a2186ab6f (patch) | |
tree | c8153c4597fb6ad210c5e15ab8babe0f6b001834 /sys/dev | |
parent | f89d1d8b6d89f552c70c95ff524a040e0eefd4b3 (diff) | |
download | FreeBSD-src-b5f4230b5557aa4ebed715b6fad6b54a2186ab6f.zip FreeBSD-src-b5f4230b5557aa4ebed715b6fad6b54a2186ab6f.tar.gz |
Retry a bit more agressively on the atapi identify.
Try to support older systems reporting irq0 for the first channels.
Support sharing of the std interrupts (says peter :) )
Dont use READ_CD on normal data reads (2048 bytes), too many old drives
doesn't support this command even if the std says "shall" :(, but still
use READ_CD on all other blocksizes.
Add the geometry to the ad probe, its still usefull.
Diffstat (limited to 'sys/dev')
-rw-r--r-- | sys/dev/ata/ata-all.c | 68 | ||||
-rw-r--r-- | sys/dev/ata/ata-all.h | 1 | ||||
-rw-r--r-- | sys/dev/ata/ata-disk.c | 5 | ||||
-rw-r--r-- | sys/dev/ata/atapi-cd.c | 10 | ||||
-rw-r--r-- | sys/dev/ata/atapi-fd.c | 2 | ||||
-rw-r--r-- | sys/dev/ata/atapi-tape.c | 2 |
6 files changed, 57 insertions, 31 deletions
diff --git a/sys/dev/ata/ata-all.c b/sys/dev/ata/ata-all.c index 669b530..a1abee5 100644 --- a/sys/dev/ata/ata-all.c +++ b/sys/dev/ata/ata-all.c @@ -305,6 +305,9 @@ ata_pciattach(device_t dev) iobase_1 = pci_read_config(dev, 0x10, 4) & IOMASK; altiobase_1 = pci_read_config(dev, 0x14, 4) & IOMASK; irq1 = pci_read_config(dev, PCI_INTERRUPT_REG, 4) & 0xff; + /* this is needed for old non-std systems */ + if (iobase_1 == IO_WD1 && irq1 == 0x00) + irq1 = 14; } if (pci_get_progif(dev) & PCIP_STORAGE_IDE_MASTERDEV) { @@ -316,6 +319,9 @@ ata_pciattach(device_t dev) iobase_2 = pci_read_config(dev, 0x18, 4) & IOMASK; altiobase_2 = pci_read_config(dev, 0x1c, 4) & IOMASK; irq2 = pci_read_config(dev, PCI_INTERRUPT_REG, 4) & 0xff; + /* this is needed for old non-std systems */ + if (iobase_2 == IO_WD2 && irq2 == 0x00) + irq2 = 15; } /* is this controller busmaster DMA capable ? */ @@ -384,51 +390,58 @@ ata_pciattach(device_t dev) /* now probe the addresse found for "real" ATA/ATAPI hardware */ lun = 0; if (iobase_1 && ata_probe(iobase_1, altiobase_1, bmaddr_1, dev, &lun)) { + int rid; + void *ih; + scp = atadevices[lun]; scp->chiptype = type; - if (iobase_1 == IO_WD1) -#ifdef __i386__ - inthand_add(device_get_nameunit(dev), irq1, ataintr, scp, - &bio_imask, INTR_EXCL); -#endif + rid = 0; + if (iobase_1 == IO_WD1) { #ifdef __alpha__ alpha_platform_setup_ide_intr(0, ataintr, scp); +#else + bus_set_resource(dev, SYS_RES_IRQ, rid, irq1, 1); + if (!(irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 0, ~0, 1, + RF_SHAREABLE | RF_ACTIVE))) + printf("ata_pciattach: Unable to alloc interrupt\n"); #endif - else { - int rid = 0; - void *ih; - + } else { if (!(irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 0, ~0, 1, RF_SHAREABLE | RF_ACTIVE))) printf("ata_pciattach: Unable to alloc interrupt\n"); - bus_setup_intr(dev, irq, INTR_TYPE_BIO, ataintr, scp, &ih); } + if (irq) + bus_setup_intr(dev, irq, INTR_TYPE_BIO, ataintr, scp, &ih); printf("ata%d at 0x%04x irq %d on ata-pci%d\n", lun, iobase_1, isa_apic_irq(irq1), unit); } lun = 1; if (iobase_2 && ata_probe(iobase_2, altiobase_2, bmaddr_2, dev, &lun)) { + int rid; + void *ih; + scp = atadevices[lun]; scp->chiptype = type; - if (iobase_2 == IO_WD2) -#ifdef __i386__ - inthand_add(device_get_nameunit(dev), irq2, ataintr, scp, - &bio_imask, INTR_EXCL); -#endif + if (iobase_2 == IO_WD2) { #ifdef __alpha__ alpha_platform_setup_ide_intr(1, ataintr, scp); +#else + rid = 1; + bus_set_resource(dev, SYS_RES_IRQ, rid, irq2, 1); + if (!(irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 0, ~0, 1, + RF_SHAREABLE | RF_ACTIVE))) + printf("ata_pciattach: Unable to alloc interrupt\n"); #endif - else { - int rid = 0; - void *ih; - + } else { + rid = 0; if (irq1 != irq2 || irq == NULL) { if (!(irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 0, ~0, 1, RF_SHAREABLE | RF_ACTIVE))) printf("ata_pciattach: Unable to alloc interrupt\n"); } - bus_setup_intr(dev, irq, INTR_TYPE_BIO, ataintr, scp, &ih); } + if (irq) + bus_setup_intr(dev, irq, INTR_TYPE_BIO, ataintr, scp, &ih); printf("ata%d at 0x%04x irq %d on ata-pci%d\n", lun, iobase_2, isa_apic_irq(irq2), unit); } @@ -680,17 +693,23 @@ ata_getparam(struct ata_softc *scp, int32_t device, u_int8_t command) outb(scp->ioaddr + ATA_DRIVE, ATA_D_IBM | device); DELAY(1); + /* enable interrupts */ + outb(scp->altioaddr, ATA_A_4BIT); + DELAY(1); + /* apparently some devices needs this repeated */ do { if (ata_command(scp, device, command, 0, 0, 0, 0, 0, ATA_WAIT_INTR)) { ata_printf(scp, device, "identify failed\n"); return -1; } - if (retry++) { + if (retry++ > 4) { ata_printf(scp, device, "drive wont come ready after identify\n"); return -1; } - } while (ata_wait(scp, device, ATA_S_READY|ATA_S_DSC|ATA_S_DRQ)); + } while (ata_wait(scp, device, + ((command == ATA_C_ATAPI_IDENTIFY) ? + ATA_S_DRQ : (ATA_S_READY | ATA_S_DSC | ATA_S_DRQ)))); insw(scp->ioaddr + ATA_DATA, buffer, sizeof(buffer)/sizeof(int16_t)); ata_parm = malloc(sizeof(struct ata_params), M_ATA, M_NOWAIT); @@ -1000,9 +1019,9 @@ ata_command(struct ata_softc *scp, int32_t device, u_int32_t command, ata_printf(scp, device, "WARNING: WAIT_INTR active=%s\n", active2str(scp->active)); scp->active = ATA_WAIT_INTR; - asleep((caddr_t)scp, PRIBIO, "atacmd", 500); + asleep((caddr_t)scp, PRIBIO, "atacmd", 10 * hz); outb(scp->ioaddr + ATA_CMD, command); - if (await(PRIBIO, 500)) { + if (await(PRIBIO, 10 * hz)) { ata_printf(scp, device, "ata_command: timeout waiting for intr\n"); scp->active = ATA_IDLE; return -1; @@ -1051,6 +1070,7 @@ ata_mode2str(int32_t mode) case ATA_WDMA2: return "WDMA2"; case ATA_UDMA2: return "UDMA33"; case ATA_UDMA4: return "UDMA66"; + case ATA_DMA: return "DMA"; default: return "???"; } } diff --git a/sys/dev/ata/ata-all.h b/sys/dev/ata/ata-all.h index 2b6e720..66de7f1 100644 --- a/sys/dev/ata/ata-all.h +++ b/sys/dev/ata/ata-all.h @@ -268,6 +268,7 @@ struct ata_softc { #define ATA_WDMA2 0x22 #define ATA_UDMA2 0x42 #define ATA_UDMA4 0x44 +#define ATA_DMA 0xff 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 fc57baf..c21be76 100644 --- a/sys/dev/ata/ata-disk.c +++ b/sys/dev/ata/ata-disk.c @@ -182,9 +182,10 @@ ad_attach(struct ata_softc *scp, int32_t device) } else - printf("ad%d: %luMB disk <%.40s> at ata%d as %s mode %s\n", + printf("ad%d: %luMB <%.40s> [%d/%d/%d] at ata%d-%s using %s\n", adp->lun, adp->total_secs / ((1024L * 1024L) / DEV_BSIZE), - AD_PARAM->model, scp->lun, + AD_PARAM->model, adp->total_secs / (adp->heads * adp->sectors), + adp->heads, adp->sectors, scp->lun, (adp->unit == ATA_MASTER) ? "master" : "slave ", ata_mode2str(adp->controller->mode[ATA_DEV(adp->unit)])); diff --git a/sys/dev/ata/atapi-cd.c b/sys/dev/ata/atapi-cd.c index d6e550b..5e5f4c2 100644 --- a/sys/dev/ata/atapi-cd.c +++ b/sys/dev/ata/atapi-cd.c @@ -409,7 +409,7 @@ acd_describe(struct acd_softc *cdp) if (cdp->changer_info) sprintf(changer, " with %d CD changer", cdp->changer_info->slots); - printf("acd%d: %s%s <%.40s> at ata%d as %s mode %s\n", + printf("acd%d: %s%s <%.40s> at ata%d-%s using %s\n", cdp->lun, (cdp->cap.write_dvdr) ? "DVD-R" : (cdp->cap.write_dvdram) ? "DVD-RAM" : (cdp->cap.write_cdrw) ? "CD-RW" : @@ -1094,8 +1094,12 @@ acd_start(struct acd_softc *cdp) lba = bp->b_blkno / (cdp->block_size / DEV_BSIZE); if (bp->b_flags & B_READ) { - ccb[0] = ATAPI_READ_CD; - ccb[9] = 0x10; /* read user data only */ + if (cdp->block_size == 2048) + ccb[0] = ATAPI_READ_BIG; + else { + ccb[0] = ATAPI_READ_CD; + ccb[9] = 0x10; + } } else ccb[0] = ATAPI_WRITE_BIG; diff --git a/sys/dev/ata/atapi-fd.c b/sys/dev/ata/atapi-fd.c index 949cd75..5bfa527 100644 --- a/sys/dev/ata/atapi-fd.c +++ b/sys/dev/ata/atapi-fd.c @@ -195,7 +195,7 @@ afd_describe(struct afd_softc *fdp) printf("\n"); } else { - printf("afd%d: %luMB floppy <%.40s> at ata%d as %s mode %s\n", + printf("afd%d: %luMB floppy <%.40s> at ata%d-%s using %s\n", fdp->lun, (fdp->cap.cylinders*fdp->cap.heads*fdp->cap.sectors) / ((1024L * 1024L) / fdp->cap.sector_size), ATA_PARAM(fdp->atp->controller, fdp->atp->unit)->model, diff --git a/sys/dev/ata/atapi-tape.c b/sys/dev/ata/atapi-tape.c index 7f9e570..07578a4 100644 --- a/sys/dev/ata/atapi-tape.c +++ b/sys/dev/ata/atapi-tape.c @@ -223,7 +223,7 @@ ast_describe(struct ast_softc *stp) printf("\n"); } else { - printf("ast%d: TAPE <%.40s> at ata%d as %s mode %s\n", + printf("ast%d: TAPE <%.40s> at ata%d-%s using %s\n", stp->lun, ATA_PARAM(stp->atp->controller, stp->atp->unit)->model, stp->atp->controller->lun, (stp->atp->unit == ATA_MASTER) ? "master" : "slave", |