summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorchris <chris@openbsd.org>2001-03-16 09:16:05 +0000
committerchris <chris@openbsd.org>2001-03-16 09:16:05 +0000
commit4b629d80387ec452c55a11bf48b0dee0789e4b6b (patch)
tree7bff8d4db77db63601cfac70a19e0e75bb7b04c1
parentImplement pmap_growkernel. From NetBSD. (diff)
downloadwireguard-openbsd-4b629d80387ec452c55a11bf48b0dee0789e4b6b.tar.xz
wireguard-openbsd-4b629d80387ec452c55a11bf48b0dee0789e4b6b.zip
Pull in NetBSD Promise Ultra/100 support
(Now we actually program Ultra/100 modes instead of Ultra/66 modes on the Ultra/100 controller) This also fixes interrupt handling on the PDC20265/7 controller. I suspect this new interrupt routine for the PDC20255/7 controller should also be used on the PDC20262.
-rw-r--r--sys/dev/pci/pciide.c80
-rw-r--r--sys/dev/pci/pciide_pdc202xx_reg.h12
2 files changed, 78 insertions, 14 deletions
diff --git a/sys/dev/pci/pciide.c b/sys/dev/pci/pciide.c
index b522898644b..15a1f546c38 100644
--- a/sys/dev/pci/pciide.c
+++ b/sys/dev/pci/pciide.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pciide.c,v 1.45 2001/02/22 03:04:09 chris Exp $ */
+/* $OpenBSD: pciide.c,v 1.46 2001/03/16 09:16:05 chris Exp $ */
/* $NetBSD: pciide.c,v 1.48 1999/11/28 20:05:18 bouyer Exp $ */
/*
@@ -230,6 +230,7 @@ int acer_pci_intr __P((void *));
void pdc202xx_chip_map __P((struct pciide_softc*, struct pci_attach_args*));
void pdc202xx_setup_channel __P((struct channel_softc*));
int pdc202xx_pci_intr __P((void *));
+int pdc20265_pci_intr __P((void *));
void opti_chip_map __P((struct pciide_softc*, struct pci_attach_args*));
void opti_setup_channel __P((struct channel_softc*));
@@ -3155,8 +3156,13 @@ opti_setup_channel(chp)
/* A macro to test product */
#define PDC_IS_262(sc) \
((sc)->sc_pp->ide_product == PCI_PRODUCT_PROMISE_PDC20262 || \
- (sc)->sc_pp->ide_product == PCI_PRODUCT_PROMISE_PDC20265 || \
+ (sc)->sc_pp->ide_product == PCI_PRODUCT_PROMISE_PDC20265 || \
(sc)->sc_pp->ide_product == PCI_PRODUCT_PROMISE_PDC20267)
+#define PDC_IS_265(sc) \
+ ((sc)->sc_pp->ide_product == PCI_PRODUCT_PROMISE_PDC20265 || \
+ (sc)->sc_pp->ide_product == PCI_PRODUCT_PROMISE_PDC20267)
+
+
void
pdc202xx_chip_map(sc, pa)
@@ -3194,7 +3200,9 @@ pdc202xx_chip_map(sc, pa)
sc->sc_wdcdev.cap |= WDC_CAPABILITY_DMA | WDC_CAPABILITY_UDMA;
sc->sc_wdcdev.PIO_cap = 4;
sc->sc_wdcdev.DMA_cap = 2;
- if (PDC_IS_262(sc))
+ if (PDC_IS_265(sc))
+ sc->sc_wdcdev.UDMA_cap = 5;
+ else if (PDC_IS_262(sc))
sc->sc_wdcdev.UDMA_cap = 4;
else
sc->sc_wdcdev.UDMA_cap = 2;
@@ -3228,7 +3236,11 @@ pdc202xx_chip_map(sc, pa)
}
mode = PDC2xx_SCR_DMA;
- if (PDC_IS_262(sc)) {
+ if (PDC_IS_265(sc)) {
+ /* the BIOS set it up this way */
+ mode = PDC2xx_SCR_SET_GEN(mode, 0x3);
+ mode |= 0x80000000;
+ } else if (PDC_IS_262(sc)) {
mode = PDC2xx_SCR_SET_GEN(mode, PDC262_SCR_GEN_LAT);
} else {
/* the BIOS set it up this way */
@@ -3263,8 +3275,12 @@ pdc202xx_chip_map(sc, pa)
sc->sc_wdcdev.sc_dev.dv_xname, cp->name);
continue;
}
- pciide_mapchan(pa, cp, interface, &cmdsize, &ctlsize,
- pdc202xx_pci_intr);
+ if (PDC_IS_265(sc))
+ pciide_mapchan(pa, cp, interface, &cmdsize, &ctlsize,
+ pdc20265_pci_intr);
+ else
+ pciide_mapchan(pa, cp, interface, &cmdsize, &ctlsize,
+ pdc202xx_pci_intr);
if (cp->hw_ok == 0)
continue;
if (pciide_chan_candisable(cp))
@@ -3295,6 +3311,10 @@ pdc202xx_setup_channel(chp)
pciide_channel_dma_setup(cp);
idedma_ctl = 0;
+ WDCDEBUG_PRINT(("pdc202xx_setup_channel %s: scr 0x%x\n",
+ sc->sc_wdcdev.sc_dev.dv_xname,
+ bus_space_read_1(sc->sc_dma_iot, sc->sc_dma_ioh, PDC262_U66)),
+ DEBUG_PROBE);
/* Per channel settings */
if (PDC_IS_262(sc)) {
@@ -3322,6 +3342,10 @@ pdc202xx_setup_channel(chp)
scr &= ~PDC262_U66_EN(channel);
bus_space_write_1(sc->sc_dma_iot, sc->sc_dma_ioh,
PDC262_U66, scr);
+ WDCDEBUG_PRINT(("pdc202xx_setup_channel %s:%d: ATAPI 0x%x\n",
+ sc->sc_wdcdev.sc_dev.dv_xname, channel,
+ bus_space_read_4(sc->sc_dma_iot, sc->sc_dma_ioh,
+ PDC262_ATAPI(channel))), DEBUG_PROBE);
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) &&
@@ -3408,11 +3432,51 @@ pdc202xx_pci_intr(arg)
if (scr & PDC2xx_SCR_INT(i)) {
crv = wdcintr(wdc_cp);
if (crv == 0)
- printf("%s:%d: bogus intr\n",
- sc->sc_wdcdev.sc_dev.dv_xname, i);
+ printf("%s:%d: bogus intr (reg 0x%x)\n",
+ sc->sc_wdcdev.sc_dev.dv_xname, i, scr);
else
rv = 1;
}
}
return rv;
}
+
+int
+pdc20265_pci_intr(arg)
+ void *arg;
+{
+ struct pciide_softc *sc = arg;
+ struct pciide_channel *cp;
+ struct channel_softc *wdc_cp;
+ int i, rv, crv;
+ u_int32_t dmastat;
+
+ rv = 0;
+ for (i = 0; i < sc->sc_wdcdev.nchannels; i++) {
+ cp = &sc->pciide_channels[i];
+ wdc_cp = &cp->wdc_channel;
+ /*
+ * If a compat channel, skip. This may
+ * never be the case on a PDC2026x ??
+ */
+ if (cp->compat)
+ continue;
+ /*
+ * The Ultra/100 seems to assert PDC2xx_SCR_INT * spuriously,
+ * however it asserts INT in IDEDMA_CTL even for non-DMA ops.
+ * So use it instead (requires 2 reg reads instead of 1,
+ * but we can't do it another way).
+ */
+ dmastat = bus_space_read_1(sc->sc_dma_iot,
+ sc->sc_dma_ioh, IDEDMA_CTL + IDEDMA_SCH_OFFSET * i);
+ if((dmastat & IDEDMA_CTL_INTR) == 0)
+ continue;
+ crv = wdcintr(wdc_cp);
+ if (crv == 0)
+ printf("%s:%d: bogus intr\n",
+ sc->sc_wdcdev.sc_dev.dv_xname, i);
+ else
+ rv = 1;
+ }
+ return rv;
+}
diff --git a/sys/dev/pci/pciide_pdc202xx_reg.h b/sys/dev/pci/pciide_pdc202xx_reg.h
index 8bae46615a4..83479884a7b 100644
--- a/sys/dev/pci/pciide_pdc202xx_reg.h
+++ b/sys/dev/pci/pciide_pdc202xx_reg.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: pciide_pdc202xx_reg.h,v 1.2 2000/01/10 22:54:46 chris Exp $ */
+/* $OpenBSD: pciide_pdc202xx_reg.h,v 1.3 2001/03/16 09:16:06 chris Exp $ */
/* $NetBSD: pciide_pdc202xx_reg.h,v 1.1 1999/08/29 17:20:10 bouyer Exp $ */
/*
@@ -73,7 +73,7 @@
/* Ultra-DMA mode 3/4 control (PDC20262 only, 1 byte) */
#define PDC262_U66 0x11
-#define PDC262_U66_EN(chan) (0x1 << ((chan) *2))
+#define PDC262_U66_EN(chan) (0x2 << ((chan) *2))
/* primary mode (1 byte) */
#define PDC2xx_PM 0x1a
/* secondary mode (1 byte) */
@@ -110,7 +110,7 @@
static int8_t pdc2xx_pa[] = {0x9, 0x5, 0x3, 0x2, 0x1};
static int8_t pdc2xx_pb[] = {0x13, 0xc, 0x8, 0x6, 0x4};
-static int8_t pdc2xx_dma_mb[] = {0x7, 0x3, 0x3};
-static int8_t pdc2xx_dma_mc[] = {0xf, 0x4, 0x3};
-static int8_t pdc2xx_udma_mb[] = {0x3, 0x2, 0x1, 0x2, 0x1};
-static int8_t pdc2xx_udma_mc[] = {0x3, 0x2, 0x1, 0x2, 0x1};
+static int8_t pdc2xx_dma_mb[] = {0x3, 0x3, 0x3};
+static int8_t pdc2xx_dma_mc[] = {0x5, 0x4, 0x3};
+static int8_t pdc2xx_udma_mb[] = {0x3, 0x2, 0x1, 0x2, 0x1, 0x1};
+static int8_t pdc2xx_udma_mc[] = {0x3, 0x2, 0x1, 0x2, 0x1, 0x1};