summaryrefslogtreecommitdiffstats
path: root/sys/dev
diff options
context:
space:
mode:
authorsos <sos@FreeBSD.org>2000-01-25 20:14:51 +0000
committersos <sos@FreeBSD.org>2000-01-25 20:14:51 +0000
commitb5f4230b5557aa4ebed715b6fad6b54a2186ab6f (patch)
treec8153c4597fb6ad210c5e15ab8babe0f6b001834 /sys/dev
parentf89d1d8b6d89f552c70c95ff524a040e0eefd4b3 (diff)
downloadFreeBSD-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.c68
-rw-r--r--sys/dev/ata/ata-all.h1
-rw-r--r--sys/dev/ata/ata-disk.c5
-rw-r--r--sys/dev/ata/atapi-cd.c10
-rw-r--r--sys/dev/ata/atapi-fd.c2
-rw-r--r--sys/dev/ata/atapi-tape.c2
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",
OpenPOWER on IntegriCloud