Make DMA mode works on Promise Ultra66/100 with 48-bit LBA drives.

Ok'ed by bouyer in tech-kern@netbsd.org.
This commit is contained in:
nakayama 2003-04-28 05:20:29 +00:00
parent 4661d01ee2
commit 1e411d7027
4 changed files with 77 additions and 8 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: ata_wdc.c,v 1.38 2002/09/27 15:37:09 provos Exp $ */
/* $NetBSD: ata_wdc.c,v 1.39 2003/04/28 05:20:29 nakayama Exp $ */
/*
* Copyright (c) 1998, 2001 Manuel Bouyer.
@ -68,7 +68,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: ata_wdc.c,v 1.38 2002/09/27 15:37:09 provos Exp $");
__KERNEL_RCSID(0, "$NetBSD: ata_wdc.c,v 1.39 2003/04/28 05:20:29 nakayama Exp $");
#ifndef WDCDEBUG
#define WDCDEBUG
@ -271,6 +271,8 @@ _wdc_ata_bio_start(chp, xfer)
if (drvp->n_xfers <= NXFER)
drvp->n_xfers++;
dma_flags = (ata_bio->flags & ATA_READ) ? WDC_DMA_READ : 0;
if (ata_bio->flags & ATA_LBA48)
dma_flags |= WDC_DMA_LBA48;
}
if (ata_bio->flags & ATA_SINGLE)
ata_delay = ATA_DELAY;

View File

@ -1,4 +1,4 @@
/* $NetBSD: wdcvar.h,v 1.35 2003/01/27 18:21:26 thorpej Exp $ */
/* $NetBSD: wdcvar.h,v 1.36 2003/04/28 05:20:30 nakayama Exp $ */
/*-
* Copyright (c) 1998 The NetBSD Foundation, Inc.
@ -124,8 +124,9 @@ struct wdc_softc { /* Per controller state */
void (*dma_start) __P((void *, int, int));
int (*dma_finish) __P((void *, int, int, int));
/* flags passed to dma_init */
#define WDC_DMA_READ 0x01
#define WDC_DMA_IRQW 0x02
#define WDC_DMA_READ 0x01
#define WDC_DMA_IRQW 0x02
#define WDC_DMA_LBA48 0x04
int dma_status; /* status returned from dma_finish() */
#define WDC_DMAST_NOIRQ 0x01 /* missing IRQ */
#define WDC_DMAST_ERR 0x02 /* DMA error */

View File

@ -1,4 +1,4 @@
/* $NetBSD: pciide.c,v 1.190 2003/04/19 23:37:26 christos Exp $ */
/* $NetBSD: pciide.c,v 1.191 2003/04/28 05:20:31 nakayama Exp $ */
/*
@ -76,7 +76,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: pciide.c,v 1.190 2003/04/19 23:37:26 christos Exp $");
__KERNEL_RCSID(0, "$NetBSD: pciide.c,v 1.191 2003/04/28 05:20:31 nakayama Exp $");
#ifndef WDCDEBUG
#define WDCDEBUG
@ -210,6 +210,8 @@ void pdc202xx_setup_channel __P((struct channel_softc*));
void pdc20268_setup_channel __P((struct channel_softc*));
int pdc202xx_pci_intr __P((void *));
int pdc20265_pci_intr __P((void *));
static void pdc20262_dma_start __P((void*, int, int));
static int pdc20262_dma_finish __P((void*, int, int, int));
void opti_chip_map __P((struct pciide_softc*, struct pci_attach_args*));
void opti_setup_channel __P((struct channel_softc*));
@ -4337,6 +4339,13 @@ pdc202xx_chip_map(sc, pa)
sc->sc_wdcdev.channels = sc->wdc_chanarray;
sc->sc_wdcdev.nchannels = PCIIDE_NUM_CHANNELS;
if (sc->sc_pp->ide_product == PCI_PRODUCT_PROMISE_ULTRA66 ||
sc->sc_pp->ide_product == PCI_PRODUCT_PROMISE_ULTRA100 ||
sc->sc_pp->ide_product == PCI_PRODUCT_PROMISE_ULTRA100X) {
sc->sc_wdcdev.dma_start = pdc20262_dma_start;
sc->sc_wdcdev.dma_finish = pdc20262_dma_finish;
}
if (!PDC_IS_268(sc)) {
/* setup failsafe defaults */
mode = 0;
@ -4663,6 +4672,61 @@ pdc20265_pci_intr(arg)
return rv;
}
static void
pdc20262_dma_start(v, channel, drive)
void *v;
int channel, drive;
{
struct pciide_softc *sc = v;
struct pciide_dma_maps *dma_maps =
&sc->pciide_channels[channel].dma_maps[drive];
int atapi;
if (dma_maps->dma_flags & WDC_DMA_LBA48) {
atapi = (dma_maps->dma_flags & WDC_DMA_READ) ?
PDC262_ATAPI_LBA48_READ : PDC262_ATAPI_LBA48_WRITE;
atapi |= dma_maps->dmamap_xfer->dm_mapsize >> 1;
bus_space_write_4(sc->sc_dma_iot, sc->sc_dma_ioh,
PDC262_ATAPI(channel), atapi);
}
pciide_dma_start(v, channel, drive);
}
int
pdc20262_dma_finish(v, channel, drive, force)
void *v;
int channel, drive;
int force;
{
struct pciide_softc *sc = v;
struct pciide_dma_maps *dma_maps =
&sc->pciide_channels[channel].dma_maps[drive];
struct channel_softc *chp;
int atapi, error;
error = pciide_dma_finish(v, channel, drive, force);
if (dma_maps->dma_flags & WDC_DMA_LBA48) {
chp = sc->wdc_chanarray[channel];
atapi = 0;
if (chp->ch_drive[0].drive_flags & DRIVE_ATAPI ||
chp->ch_drive[1].drive_flags & DRIVE_ATAPI) {
if ((!(chp->ch_drive[0].drive_flags & DRIVE_UDMA) ||
(chp->ch_drive[1].drive_flags & DRIVE_UDMA) ||
!(chp->ch_drive[1].drive_flags & DRIVE_DMA)) &&
(!(chp->ch_drive[1].drive_flags & DRIVE_UDMA) ||
(chp->ch_drive[0].drive_flags & DRIVE_UDMA) ||
!(chp->ch_drive[0].drive_flags & DRIVE_DMA)))
atapi = PDC262_ATAPI_UDMA;
}
bus_space_write_4(sc->sc_dma_iot, sc->sc_dma_ioh,
PDC262_ATAPI(channel), atapi);
}
return error;
}
void
opti_chip_map(sc, pa)
struct pciide_softc *sc;

View File

@ -1,4 +1,4 @@
/* $NetBSD: pciide_pdc202xx_reg.h,v 1.8 2002/07/26 14:11:35 wiz Exp $ */
/* $NetBSD: pciide_pdc202xx_reg.h,v 1.9 2003/04/28 05:20:33 nakayama Exp $ */
/*
* Copyright (c) 1999 Manuel Bouyer.
@ -99,6 +99,8 @@
#define PDC262_ATAPI_DMA_READ 0x00001000
#define PDC262_ATAPI_DMA_WRITE 0x00002000
#define PDC262_ATAPI_UDMA 0x00004000
#define PDC262_ATAPI_LBA48_READ 0x05000000
#define PDC262_ATAPI_LBA48_WRITE 0x06000000
/*
* The timings provided here cmoes from the PDC20262 docs. I hope they are