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:
parent
4661d01ee2
commit
1e411d7027
|
@ -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;
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue