summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorsos <sos@FreeBSD.org>2000-01-28 13:35:43 +0000
committersos <sos@FreeBSD.org>2000-01-28 13:35:43 +0000
commit1f5af77314970ee321c9373f3839b3bbe04c4fc1 (patch)
treed005c678641a6b7a7066e1414fc5a429956812ec /sys
parent7fd8aeb670b3d69472dcce6dd88f3f23840c4c9a (diff)
downloadFreeBSD-src-1f5af77314970ee321c9373f3839b3bbe04c4fc1.zip
FreeBSD-src-1f5af77314970ee321c9373f3839b3bbe04c4fc1.tar.gz
Cleanup the ata_dmainit function a bit.
Also allow BIOS setup DMA on unknown controllers.
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/ata/ata-all.h2
-rw-r--r--sys/dev/ata/ata-dma.c72
2 files changed, 41 insertions, 33 deletions
diff --git a/sys/dev/ata/ata-all.h b/sys/dev/ata/ata-all.h
index ff6c640..009827e 100644
--- a/sys/dev/ata/ata-all.h
+++ b/sys/dev/ata/ata-all.h
@@ -313,7 +313,7 @@ void ata_reset(struct ata_softc *, int32_t *);
int32_t ata_reinit(struct ata_softc *);
int32_t ata_wait(struct ata_softc *, int32_t, u_int8_t);
int32_t ata_command(struct ata_softc *, int32_t, u_int32_t, u_int32_t, u_int32_t, u_int32_t, u_int32_t, u_int32_t, int32_t);
-int32_t ata_dmainit(struct ata_softc *, int32_t, int32_t, int32_t, int32_t);
+void ata_dmainit(struct ata_softc *, int32_t, int32_t, int32_t, int32_t);
int32_t ata_dmasetup(struct ata_softc *, int32_t, int8_t *, int32_t, int32_t);
void ata_dmastart(struct ata_softc *);
int32_t ata_dmastatus(struct ata_softc *);
diff --git a/sys/dev/ata/ata-dma.c b/sys/dev/ata/ata-dma.c
index 56de719..06def84 100644
--- a/sys/dev/ata/ata-dma.c
+++ b/sys/dev/ata/ata-dma.c
@@ -60,15 +60,18 @@ static void hpt366_timing(struct ata_softc *, int32_t, int32_t);
#if NPCI > 0
-int32_t
+void
ata_dmainit(struct ata_softc *scp, int32_t device,
int32_t apiomode, int32_t wdmamode, int32_t udmamode)
{
int32_t devno = (scp->unit << 1) + ATA_DEV(device);
int32_t error;
+ /* set our most pessimistic default mode */
+ scp->mode[ATA_DEV(device)] = ATA_PIO;
+
if (!scp->bmaddr)
- return -1;
+ return;
/* if simplex controller, only allow DMA on primary channel */
if (scp->unit == 1) {
@@ -76,7 +79,7 @@ ata_dmainit(struct ata_softc *scp, int32_t device,
(ATA_BMSTAT_DMA_MASTER | ATA_BMSTAT_DMA_SLAVE));
if (inb(scp->bmaddr + ATA_BMSTAT_PORT) & ATA_BMSTAT_DMA_SIMPLEX) {
ata_printf(scp, device, "simplex device, DMA on primary only\n");
- return -1;
+ return;
}
}
@@ -84,12 +87,12 @@ ata_dmainit(struct ata_softc *scp, int32_t device,
void *dmatab;
if (!(dmatab = malloc(PAGE_SIZE, M_DEVBUF, M_NOWAIT)))
- return -1;
+ return;
if (((uintptr_t)dmatab >> PAGE_SHIFT) ^
(((uintptr_t)dmatab + PAGE_SIZE - 1) >> PAGE_SHIFT)) {
ata_printf(scp, device, "dmatab crosses page boundary, no DMA\n");
free(dmatab, M_DEVBUF);
- return -1;
+ return;
}
scp->dmatab[ATA_DEV(device)] = dmatab;
}
@@ -117,7 +120,7 @@ ata_dmainit(struct ata_softc *scp, int32_t device,
(pci_read_config(scp->dev, 0x48, 4) &
~mask48) | new48, 4);
scp->mode[ATA_DEV(device)] = ATA_UDMA2;
- return 0;
+ return;
}
}
/* FALLTHROUGH */
@@ -176,7 +179,7 @@ ata_dmainit(struct ata_softc *scp, int32_t device,
(pci_read_config(scp->dev, 0x44, 4) & ~mask44)|
new44, 4);
scp->mode[ATA_DEV(device)] = ATA_WDMA2;
- return 0;
+ return;
}
}
/* we could set PIO mode timings, but we assume the BIOS did that */
@@ -202,7 +205,7 @@ ata_dmainit(struct ata_softc *scp, int32_t device,
(error) ? "failed" : "success");
if (!error) {
scp->mode[ATA_DEV(device)] = ATA_WDMA2;
- return 0;
+ return;
}
}
break;
@@ -231,7 +234,7 @@ ata_dmainit(struct ata_softc *scp, int32_t device,
pci_read_config(scp->dev, 0x53, 1) | 0x03, 1);
scp->flags |= ATA_ATAPI_DMA_RO;
scp->mode[ATA_DEV(device)] = ATA_UDMA2;
- return 0;
+ return;
}
}
if (wdmamode >= 2 && apiomode >= 4) {
@@ -246,7 +249,7 @@ ata_dmainit(struct ata_softc *scp, int32_t device,
pci_read_config(scp->dev, 0x53, 1) | 0x03, 1);
scp->flags |= ATA_ATAPI_DMA_RO;
scp->mode[ATA_DEV(device)] = ATA_WDMA2;
- return 0;
+ return;
}
}
/* we could set PIO mode timings, but we assume the BIOS did that */
@@ -266,7 +269,7 @@ ata_dmainit(struct ata_softc *scp, int32_t device,
if (!error) {
pci_write_config(scp->dev, 0x53 - devno, 0xe8, 1);
scp->mode[ATA_DEV(device)] = ATA_UDMA4;
- return 0;
+ return;
}
}
if (udmamode >= 2) {
@@ -279,7 +282,7 @@ ata_dmainit(struct ata_softc *scp, int32_t device,
if (!error) {
pci_write_config(scp->dev, 0x53 - devno, 0xea, 1);
scp->mode[ATA_DEV(device)] = ATA_UDMA2;
- return 0;
+ return;
}
}
}
@@ -295,7 +298,7 @@ ata_dmainit(struct ata_softc *scp, int32_t device,
if (!error) {
pci_write_config(scp->dev, 0x53 - devno, 0xc3, 1);
scp->mode[ATA_DEV(device)] = ATA_UDMA4;
- return 0;
+ return;
}
}
@@ -313,7 +316,7 @@ ata_dmainit(struct ata_softc *scp, int32_t device,
if (!error) {
pci_write_config(scp->dev, 0x53 - devno, 0xc0, 1);
scp->mode[ATA_DEV(device)] = ATA_UDMA2;
- return 0;
+ return;
}
}
if (wdmamode >= 2 && apiomode >= 4) {
@@ -327,7 +330,7 @@ ata_dmainit(struct ata_softc *scp, int32_t device,
pci_write_config(scp->dev, 0x53 - devno, 0x82, 1);
pci_write_config(scp->dev, 0x4b - devno, 0x31, 1);
scp->mode[ATA_DEV(device)] = ATA_WDMA2;
- return 0;
+ return;
}
}
/* we could set PIO mode timings, but we assume the BIOS did that */
@@ -344,7 +347,7 @@ ata_dmainit(struct ata_softc *scp, int32_t device,
if (!error) {
pci_write_config(scp->dev, 0x40 + (devno << 1), 0xa301, 2);
scp->mode[ATA_DEV(device)] = ATA_UDMA2;
- return 0;
+ return;
}
}
if (wdmamode >=2 && apiomode >= 4) {
@@ -357,7 +360,7 @@ ata_dmainit(struct ata_softc *scp, int32_t device,
if (!error) {
pci_write_config(scp->dev, 0x40 + (devno << 1), 0x0301, 2);
scp->mode[ATA_DEV(device)] = ATA_WDMA2;
- return 0;
+ return;
}
}
/* we could set PIO mode timings, but we assume the BIOS did that */
@@ -382,7 +385,7 @@ ata_dmainit(struct ata_softc *scp, int32_t device,
outb(scp->bmaddr+0x11, inl(scp->bmaddr+0x11) | scp->unit ? 8:2);
promise_timing(scp, devno, ATA_UDMA4);
scp->mode[ATA_DEV(device)] = ATA_UDMA4;
- return 0;
+ return;
}
}
if (udmamode >= 2) {
@@ -395,7 +398,7 @@ ata_dmainit(struct ata_softc *scp, int32_t device,
if (!error) {
promise_timing(scp, devno, ATA_UDMA2);
scp->mode[ATA_DEV(device)] = ATA_UDMA2;
- return 0;
+ return;
}
}
if (wdmamode >= 2 && apiomode >= 4) {
@@ -408,7 +411,7 @@ ata_dmainit(struct ata_softc *scp, int32_t device,
if (!error) {
promise_timing(scp, devno, ATA_WDMA2);
scp->mode[ATA_DEV(device)] = ATA_WDMA2;
- return 0;
+ return;
}
}
error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
@@ -421,7 +424,7 @@ ata_dmainit(struct ata_softc *scp, int32_t device,
(apiomode >= 0) ? apiomode : 0);
promise_timing(scp, devno, ata_pio2mode(apiomode));
scp->mode[ATA_DEV(device)] = ata_pio2mode(apiomode);
- return -1;
+ return;
case 0x00041103: /* HighPoint HPT366 controller */
/* no ATAPI devices for now */
@@ -439,7 +442,7 @@ ata_dmainit(struct ata_softc *scp, int32_t device,
if (!error) {
hpt366_timing(scp, devno, ATA_UDMA4);
scp->mode[ATA_DEV(device)] = ATA_UDMA4;
- return 0;
+ return;
}
}
if (udmamode >= 2) {
@@ -452,7 +455,7 @@ ata_dmainit(struct ata_softc *scp, int32_t device,
if (!error) {
hpt366_timing(scp, devno, ATA_UDMA2);
scp->mode[ATA_DEV(device)] = ATA_UDMA2;
- return 0;
+ return;
}
}
if (wdmamode >= 2 && apiomode >= 4) {
@@ -465,7 +468,7 @@ ata_dmainit(struct ata_softc *scp, int32_t device,
if (!error) {
hpt366_timing(scp, devno, ATA_WDMA2);
scp->mode[ATA_DEV(device)] = ATA_WDMA2;
- return 0;
+ return;
}
}
error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
@@ -477,7 +480,7 @@ ata_dmainit(struct ata_softc *scp, int32_t device,
(apiomode >= 0) ? apiomode : 0);
hpt366_timing(scp, devno, ata_pio2mode(apiomode));
scp->mode[ATA_DEV(device)] = ata_pio2mode(apiomode);
- return -1;
+ return;
default: /* unknown controller chip */
/* better not try generic DMA on ATAPI devices it almost never works */
@@ -485,6 +488,16 @@ ata_dmainit(struct ata_softc *scp, int32_t device,
(device == ATA_SLAVE && scp->devices & ATA_ATAPI_SLAVE))
break;
+ /* if controller says its setup for DMA take the easy way out */
+ /* the downside is we dont know what DMA mode we are in */
+ if ((udmamode >= 0 || wdmamode > 1) &&
+ (inb(scp->bmaddr + ATA_BMSTAT_PORT) &
+ ((device==ATA_MASTER) ?
+ ATA_BMSTAT_DMA_MASTER : ATA_BMSTAT_DMA_SLAVE))) {
+ scp->mode[ATA_DEV(device)] = ATA_DMA;
+ return;
+ }
+
/* well, we have no support for this, but try anyways */
if ((wdmamode >= 2 && apiomode >= 4) && scp->bmaddr) {
error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
@@ -495,17 +508,12 @@ ata_dmainit(struct ata_softc *scp, int32_t device,
(error) ? "failed" : "success");
if (!error) {
scp->mode[ATA_DEV(device)] = ATA_WDMA2;
- return 0;
+ return;
}
}
}
- 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",
- (error) ? "failed" : "success",(apiomode>=0) ? apiomode : 0);
- scp->mode[ATA_DEV(device)] = ata_pio2mode(apiomode);
- return -1;
+ ata_printf(scp, device, "using PIO mode set by BIOS\n");
}
int32_t
OpenPOWER on IntegriCloud