summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorAlexander Yurchenko <grange@cvs.openbsd.org>2003-05-17 18:45:16 +0000
committerAlexander Yurchenko <grange@cvs.openbsd.org>2003-05-17 18:45:16 +0000
commitd5ba085e38515d85e898acf0af4a59ac70804ccc (patch)
treebdf44ab041bcc866fd76d50b153448a10ca36b8e /sys
parent8674de0af687b72185752755f79ef186009fde48 (diff)
Experimental support for SiI 3112 SATA card; from NetBSD.
Thanks to chris@ for this card.
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/pci/pciide.c124
-rw-r--r--sys/dev/pci/pciide_sii3112_reg.h105
2 files changed, 228 insertions, 1 deletions
diff --git a/sys/dev/pci/pciide.c b/sys/dev/pci/pciide.c
index 49f02f6e95f..cfa34bca73f 100644
--- a/sys/dev/pci/pciide.c
+++ b/sys/dev/pci/pciide.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pciide.c,v 1.125 2003/05/17 18:35:04 grange Exp $ */
+/* $OpenBSD: pciide.c,v 1.126 2003/05/17 18:45:15 grange Exp $ */
/* $NetBSD: pciide.c,v 1.127 2001/08/03 01:31:08 tsutsui Exp $ */
/*
@@ -106,6 +106,7 @@ int wdcdebug_pciide_mask = 0;
#include <dev/pci/pciide_amd_reg.h>
#include <dev/pci/pciide_apollo_reg.h>
#include <dev/pci/pciide_cmd_reg.h>
+#include <dev/pci/pciide_sii3112_reg.h>
#include <dev/pci/pciide_cy693_reg.h>
#include <dev/pci/pciide_sis_reg.h>
#include <dev/pci/pciide_acer_reg.h>
@@ -227,6 +228,9 @@ void cmd_channel_map(struct pci_attach_args *,
int cmd_pci_intr(void *);
void cmd646_9_irqack(struct channel_softc *);
+void sii3112_chip_map(struct pciide_softc*, struct pci_attach_args*);
+void sii3112_setup_channel(struct channel_softc*);
+
void cy693_chip_map(struct pciide_softc*, struct pci_attach_args*);
void cy693_setup_channel(struct channel_softc*);
@@ -409,6 +413,10 @@ const struct pciide_product_desc pciide_cmd_products[] = {
{ PCI_PRODUCT_CMDTECH_680, /* CMD Technology PCI0680 */
IDE_PCI_CLASS_OVERRIDE,
cmd680_chip_map
+ },
+ { PCI_PRODUCT_CMDTECH_3112, /* SiI 3112 SATA */
+ IDE_PCI_CLASS_OVERRIDE, /* XXX: subclass RAID */
+ sii3112_chip_map
}
};
@@ -3059,6 +3067,120 @@ cmd680_setup_channel(chp)
}
void
+sii3112_chip_map(struct pciide_softc *sc, struct pci_attach_args *pa)
+{
+ struct pciide_channel *cp;
+ bus_size_t cmdsize, ctlsize;
+ pcireg_t interface;
+ int channel;
+
+ if (pciide_chipen(sc, pa) == 0)
+ return;
+
+ printf(": DMA");
+ pciide_mapreg_dma(sc, pa);
+
+ /*
+ * Rev. <= 0x01 of the 3112 have a bug that can cause data
+ * corruption if DMA transfers cross an 8K boundary. This is
+ * apparently hard to tickle, but we'll go ahead and play it
+ * safe.
+ */
+ if (PCI_REVISION(pa->pa_class) <= 0x01) {
+ sc->sc_dma_maxsegsz = 8192;
+ sc->sc_dma_boundary = 8192;
+ }
+
+ sc->sc_wdcdev.cap |= WDC_CAPABILITY_DATA16 | WDC_CAPABILITY_DATA32 |
+ WDC_CAPABILITY_MODE;
+ sc->sc_wdcdev.PIO_cap = 4;
+ if (sc->sc_dma_ok) {
+ sc->sc_wdcdev.cap |= WDC_CAPABILITY_DMA | WDC_CAPABILITY_UDMA;
+ sc->sc_wdcdev.cap |= WDC_CAPABILITY_IRQACK;
+ sc->sc_wdcdev.irqack = pciide_irqack;
+ sc->sc_wdcdev.DMA_cap = 2;
+ sc->sc_wdcdev.UDMA_cap = 6;
+ }
+ sc->sc_wdcdev.set_modes = sii3112_setup_channel;
+
+ sc->sc_wdcdev.channels = sc->wdc_chanarray;
+ sc->sc_wdcdev.nchannels = PCIIDE_NUM_CHANNELS;
+
+ /*
+ * The 3112 can be told to identify as a RAID controller.
+ * In this case, we have to fake interface
+ */
+ if (PCI_SUBCLASS(pa->pa_class) == PCI_SUBCLASS_MASS_STORAGE_IDE) {
+ interface = PCI_INTERFACE(pa->pa_class);
+ } else {
+ interface = PCIIDE_INTERFACE_BUS_MASTER_DMA |
+ PCIIDE_INTERFACE_PCI(0) | PCIIDE_INTERFACE_PCI(1);
+ }
+
+ pciide_print_channels(sc->sc_wdcdev.nchannels, interface);
+
+ for (channel = 0; channel < sc->sc_wdcdev.nchannels; channel++) {
+ cp = &sc->pciide_channels[channel];
+ if (pciide_chansetup(sc, channel, interface) == 0)
+ continue;
+ pciide_mapchan(pa, cp, interface, &cmdsize, &ctlsize,
+ pciide_pci_intr);
+ if (cp->hw_ok == 0)
+ continue;
+ pciide_map_compat_intr(pa, cp, channel, interface);
+ sc->sc_wdcdev.set_modes(&cp->wdc_channel);
+ }
+}
+
+void
+sii3112_setup_channel(struct channel_softc *chp)
+{
+ struct ata_drive_datas *drvp;
+ int drive;
+ u_int32_t idedma_ctl, dtm;
+ struct pciide_channel *cp = (struct pciide_channel*)chp;
+ struct pciide_softc *sc = (struct pciide_softc*)cp->wdc_channel.wdc;
+
+ /* setup DMA if needed */
+ pciide_channel_dma_setup(cp);
+
+ idedma_ctl = 0;
+ dtm = 0;
+
+ for (drive = 0; drive < 2; drive++) {
+ drvp = &chp->ch_drive[drive];
+ /* If no drive, skip */
+ if ((drvp->drive_flags & DRIVE) == 0)
+ continue;
+ if (drvp->drive_flags & DRIVE_UDMA) {
+ /* use Ultra/DMA */
+ drvp->drive_flags &= ~DRIVE_DMA;
+ idedma_ctl |= IDEDMA_CTL_DRV_DMA(drive);
+ dtm |= DTM_IDEx_DMA;
+ } else if (drvp->drive_flags & DRIVE_DMA) {
+ idedma_ctl |= IDEDMA_CTL_DRV_DMA(drive);
+ dtm |= DTM_IDEx_DMA;
+ } else {
+ dtm |= DTM_IDEx_PIO;
+ }
+ }
+
+ /*
+ * Nothing to do to setup modes; it is meaningless in S-ATA
+ * (but many S-ATA drives still want to get the SET_FEATURE
+ * command).
+ */
+ if (idedma_ctl != 0) {
+ /* Add software bits in status register */
+ bus_space_write_1(sc->sc_dma_iot, sc->sc_dma_ioh,
+ IDEDMA_CTL(chp->channel), idedma_ctl);
+ }
+ pci_conf_write(sc->sc_pc, sc->sc_tag,
+ chp->channel == 0 ? SII3112_DTM_IDE0 : SII3112_DTM_IDE1, dtm);
+ pciide_print_modes(cp);
+}
+
+void
cy693_chip_map(sc, pa)
struct pciide_softc *sc;
struct pci_attach_args *pa;
diff --git a/sys/dev/pci/pciide_sii3112_reg.h b/sys/dev/pci/pciide_sii3112_reg.h
new file mode 100644
index 00000000000..702b91f87f0
--- /dev/null
+++ b/sys/dev/pci/pciide_sii3112_reg.h
@@ -0,0 +1,105 @@
+/* $OpenBSD: pciide_sii3112_reg.h,v 1.1 2003/05/17 18:45:15 grange Exp $ */
+/* $NetBSD: pciide_sii3112_reg.h,v 1.1 2003/03/20 04:22:50 thorpej Exp $ */
+
+/*
+ * Copyright (c) 2003 Wasabi Systems, Inc.
+ * All rights reserved.
+ *
+ * Written by Jason R. Thorpe for Wasabi Systems, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed for the NetBSD Project by
+ * Wasabi Systems, Inc.
+ * 4. The name of Wasabi Systems, Inc. may not be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _DEV_PCI_PCIIDE_SII3112_REG_H_
+#define _DEV_PCI_PCIIDE_SII3112_REG_H_
+
+/*
+ * PCI configuration space registers.
+ */
+
+#define SII3112_PCI_CFGCTL 0x40
+#define CFGCTL_CFGWREN (1U << 0) /* enable cfg writes */
+#define CFGCTL_BA5INDEN (1U << 1) /* BA5 indirect access enable */
+
+#define SII3112_PCI_SWDATA 0x44
+
+#define SII3112_PCI_BM_IDE0 0x70
+ /* == BAR4+0x00 */
+
+#define SII3112_PCI_PRD_IDE0 0x74
+ /* == BAR4+0x04 */
+
+#define SII3112_PCI_BM_IDE1 0x78
+ /* == BAR4+0x08 */
+
+#define SII3112_PCI_PRD_IDE1 0x7c
+ /* == BAR4+0x0c */
+
+#define SII3112_DTM_IDE0 0x80 /* Data Transfer Mode - IDE0 */
+#define SII3112_DTM_IDE1 0x84 /* Data Transfer Mode - IDE1 */
+#define DTM_IDEx_PIO 0x00000000 /* PCI DMA, IDE PIO (or 1) */
+#define DTM_IDEx_DMA 0x00000002 /* PCI DMA, IDE DMA (or 3) */
+
+
+#define SII3112_SCS_CMD 0x88 /* System Config Status */
+#define SCS_CMD_PBM_RESET (1U << 0) /* PBM module reset */
+#define SCS_CMD_ARB_RESET (1U << 1) /* ARB module reset */
+#define SCS_CMD_FF1_RESET (1U << 4) /* IDE1 FIFO reset */
+#define SCS_CMD_FF0_RESET (1U << 5) /* IDE0 FIFO reset */
+#define SCS_CMD_IDE1_RESET (1U << 6) /* IDE1 module reset */
+#define SCS_CMD_IDE0_RESET (1U << 7) /* IDE0 module reset */
+#define SCS_CMD_BA5_EN (1U << 16) /* BA5 is enabled */
+#define SCS_CMD_IDE0_INT_BLOCK (1U << 22) /* IDE0 interrupt block */
+#define SCS_CMD_IDE1_INT_BLOCK (1U << 23) /* IDE1 interrupt block */
+
+#define SII3112_SSDR 0x8c /* System SW Data Register */
+
+#define SII3112_FMA_CSR 0x90 /* Flash Memory Addr - CSR */
+
+#define SII3112_FM_DATA 0x94 /* Flash Memory Data */
+
+#define SII3112_EEA_CSR 0x98 /* EEPROM Memory Addr - CSR */
+
+#define SII3112_EE_DATA 0x9c /* EEPROM Data */
+
+#define SII3112_TCS_IDE0 0xa0 /* IDEx config, status */
+#define SII3112_TCS_IDE1 0xb0
+#define TCS_IDEx_BCA (1U << 1) /* buffered command active */
+#define TCS_IDEx_CH_RESET (1U << 2) /* channel reset */
+#define TCS_IDEx_VDMA_INT (1U << 10) /* virtual DMA interrupt */
+#define TCS_IDEx_INT (1U << 11) /* interrupt status */
+#define TCS_IDEx_WTT (1U << 12) /* watchdog timer timeout */
+#define TCS_IDEx_WTEN (1U << 13) /* watchdog timer enable */
+#define TCS_IDEx_WTINTEN (1U << 14) /* watchdog timer int. enable */
+
+#define SII3112_BA5_IND_ADDR 0xc0 /* BA5 indirect address */
+
+#define SII3112_BA5_IND_DATA 0xc4 /* BA5 indirect data */
+
+#endif /* _DEV_PCI_PCIIDE_SII3112_REG_H_ */