Cleanup the ata_dmainit function a bit.

Also allow BIOS setup DMA on unknown controllers.
This commit is contained in:
Søren Schmidt 2000-01-28 13:35:43 +00:00
parent 67e394e034
commit 02ce0452e1
2 changed files with 41 additions and 33 deletions

View File

@ -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 *);

View File

@ -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