Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev/pci Add complete support for all channels on VT6421A...
details: https://anonhg.NetBSD.org/src/rev/b79cb499e98e
branches: trunk
changeset: 767183:b79cb499e98e
user: jakllsch <jakllsch%NetBSD.org@localhost>
date: Sun Jul 10 20:01:37 2011 +0000
description:
Add complete support for all channels on VT6421A SATA/PATA controller to
viaide(4).
diffstat:
sys/dev/pci/pciide_apollo_reg.h | 7 +-
sys/dev/pci/viaide.c | 142 ++++++++++++++++++++++++++++++++-------
2 files changed, 118 insertions(+), 31 deletions(-)
diffs (284 lines):
diff -r 8e292184c443 -r b79cb499e98e sys/dev/pci/pciide_apollo_reg.h
--- a/sys/dev/pci/pciide_apollo_reg.h Sun Jul 10 16:54:04 2011 +0000
+++ b/sys/dev/pci/pciide_apollo_reg.h Sun Jul 10 20:01:37 2011 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: pciide_apollo_reg.h,v 1.19 2011/06/30 20:09:40 wiz Exp $ */
+/* $NetBSD: pciide_apollo_reg.h,v 1.20 2011/07/10 20:01:37 jakllsch Exp $ */
/*
* Copyright (c) 1998 Manuel Bouyer.
@@ -91,6 +91,7 @@
#define APO_VIA_REGBASE 0x40
#define APO_AMD_REGBASE 0x40
#define APO_NVIDIA_REGBASE 0x50
+#define APO_VIA_VT6421_REGBASE 0xa0
/* misc. configuration registers */
#define APO_IDECONF(sc) ((sc)->sc_apo_regbase + 0x00)
@@ -110,7 +111,7 @@
#define APO_IDECONF_FIFO_CONF_MASK 0x60000000
/* Misc. controls register - VIA only */
-#define APO_CTLMISC(sc) 0x44
+#define APO_CTLMISC(sc) ((sc)->sc_apo_regbase + 0x04)
#define APO_CTLMISC_BM_STS_RTY 0x00000008
#define APO_CTLMISC_FIFO_HWS 0x00000010
#define APO_CTLMISC_WR_IRDY_WS 0x00000020
@@ -129,7 +130,7 @@
(((1 - (channel)) << 4) + ((1 - (drive)) << 3) + 4))
/* misc timings control - VIA only */
-#define APO_MISCTIM(sc) 0x4c
+#define APO_MISCTIM(sc) ((sc)->sc_apo_regbase + 0x0c)
/* Ultra-DMA control (586A/B only, amd and nvidia ) */
#define APO_UDMA(sc) ((sc)->sc_apo_regbase + 0x10)
diff -r 8e292184c443 -r b79cb499e98e sys/dev/pci/viaide.c
--- a/sys/dev/pci/viaide.c Sun Jul 10 16:54:04 2011 +0000
+++ b/sys/dev/pci/viaide.c Sun Jul 10 20:01:37 2011 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: viaide.c,v 1.75 2011/05/17 17:34:54 dyoung Exp $ */
+/* $NetBSD: viaide.c,v 1.76 2011/07/10 20:01:37 jakllsch Exp $ */
/*
* Copyright (c) 1999, 2000, 2001 Manuel Bouyer.
@@ -26,10 +26,11 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: viaide.c,v 1.75 2011/05/17 17:34:54 dyoung Exp $");
+__KERNEL_RCSID(0, "$NetBSD: viaide.c,v 1.76 2011/07/10 20:01:37 jakllsch Exp $");
#include <sys/param.h>
#include <sys/systm.h>
+#include <sys/malloc.h>
#include <dev/pci/pcivar.h>
#include <dev/pci/pcidevs.h>
@@ -46,7 +47,7 @@
static void via_mapregs_compat_native(const struct pci_attach_args *,
struct pciide_channel *);
static int via_sata_chip_map_common(struct pciide_softc *,
- struct pci_attach_args *);
+ const struct pci_attach_args *);
static void via_sata_chip_map(struct pciide_softc *,
const struct pci_attach_args *, int);
static void via_sata_chip_map_6(struct pciide_softc *,
@@ -311,7 +312,7 @@
},
{ PCI_PRODUCT_VIATECH_VT6421_RAID,
0,
- "VIA Technologies VT6421 Serial RAID Controller",
+ "VIA Technologies VT6421 Serial ATA RAID Controller",
via_sata_chip_map_new,
},
{ PCI_PRODUCT_VIATECH_VT8237_SATA,
@@ -366,7 +367,7 @@
static int
viaide_match(device_t parent, cfdata_t match, void *aux)
{
- struct pci_attach_args *pa = aux;
+ const struct pci_attach_args *pa = aux;
if (viaide_lookup(pa->pa_id) != NULL)
return (2);
@@ -376,7 +377,7 @@
static void
viaide_attach(device_t parent, device_t self, void *aux)
{
- struct pci_attach_args *pa = aux;
+ const struct pci_attach_args *pa = aux;
struct pciide_softc *sc = device_private(self);
const struct pciide_product_desc *pp;
@@ -835,10 +836,14 @@
}
static int
-via_sata_chip_map_common(struct pciide_softc *sc, struct pci_attach_args *pa)
+via_sata_chip_map_common(struct pciide_softc *sc,
+ const struct pci_attach_args *cpa)
{
pcireg_t csr;
int maptype, ret;
+ struct pci_attach_args pac, *pa = &pac;
+
+ pac = *cpa;
if (pciide_chipen(sc, pa) == 0)
return 0;
@@ -908,18 +913,15 @@
}
static void
-via_sata_chip_map(struct pciide_softc *sc, const struct pci_attach_args *pa0,
+via_sata_chip_map(struct pciide_softc *sc, const struct pci_attach_args *pa,
int satareg_shift)
{
struct pciide_channel *cp;
struct ata_channel *wdc_cp;
struct wdc_regs *wdr;
- struct pci_attach_args pacopy, *pa;
pcireg_t interface;
int channel;
- pacopy = *pa0;
- pa = &pacopy;
interface = PCI_INTERFACE(pa->pa_class);
if (via_sata_chip_map_common(sc, pa) == 0)
@@ -983,33 +985,118 @@
}
static void
+via_vt6421_mapreg_dma(struct pciide_softc *sc, const struct pci_attach_args *pa)
+{
+ struct pciide_channel *pc;
+ int chan, reg;
+ bus_size_t size;
+
+ sc->sc_dma_ok = (pci_mapreg_map(pa, PCIIDE_REG_BUS_MASTER_DMA,
+ PCI_MAPREG_TYPE_IO, 0, &sc->sc_dma_iot, &sc->sc_dma_ioh,
+ NULL, &sc->sc_dma_ios) == 0);
+ sc->sc_dmat = pa->pa_dmat;
+ if (sc->sc_dma_ok == 0) {
+ aprint_verbose(", but unused (couldn't map registers)");
+ } else {
+ sc->sc_wdcdev.dma_arg = sc;
+ sc->sc_wdcdev.dma_init = pciide_dma_init;
+ sc->sc_wdcdev.dma_start = pciide_dma_start;
+ sc->sc_wdcdev.dma_finish = pciide_dma_finish;
+ }
+
+ if (device_cfdata(sc->sc_wdcdev.sc_atac.atac_dev)->cf_flags &
+ PCIIDE_OPTIONS_NODMA) {
+ aprint_verbose(
+ ", but unused (forced off by config file)");
+ sc->sc_dma_ok = 0;
+ }
+
+ if (sc->sc_dma_ok == 0)
+ return;
+
+ for (chan = 0; chan < 4; chan++) {
+ pc = &sc->pciide_channels[chan];
+ for (reg = 0; reg < IDEDMA_NREGS; reg++) {
+ size = 4;
+ if (size > (IDEDMA_SCH_OFFSET - reg))
+ size = IDEDMA_SCH_OFFSET - reg;
+ if (bus_space_subregion(sc->sc_dma_iot, sc->sc_dma_ioh,
+ IDEDMA_SCH_OFFSET * chan + reg, size,
+ &pc->dma_iohs[reg]) != 0) {
+ sc->sc_dma_ok = 0;
+ aprint_verbose(", but can't subregion offset "
+ "%d size %lu",
+ reg, (u_long)size);
+ return;
+ }
+ }
+ }
+}
+
+static int
+via_vt6421_chansetup(struct pciide_softc *sc, int channel)
+{
+ struct pciide_channel *cp = &sc->pciide_channels[channel];
+
+ sc->wdc_chanarray[channel] = &cp->ata_channel;
+
+ cp->ata_channel.ch_channel = channel;
+ cp->ata_channel.ch_atac = &sc->sc_wdcdev.sc_atac;
+ cp->ata_channel.ch_queue =
+ malloc(sizeof(struct ata_queue), M_DEVBUF, M_NOWAIT);
+ cp->ata_channel.ch_ndrive = 2;
+ if (cp->ata_channel.ch_queue == NULL) {
+ aprint_error("%s channel %d: "
+ "can't allocate memory for command queue",
+ device_xname(sc->sc_wdcdev.sc_atac.atac_dev), channel);
+ return 0;
+ }
+ return 1;
+}
+
+static void
via_sata_chip_map_new(struct pciide_softc *sc,
- const struct pci_attach_args *pa0)
+ const struct pci_attach_args *pa)
{
struct pciide_channel *cp;
struct ata_channel *wdc_cp;
struct wdc_regs *wdr;
- struct pci_attach_args pacopy, *pa;
- pcireg_t interface;
int channel;
pci_intr_handle_t intrhandle;
const char *intrstr;
int i;
- pacopy = *pa0;
- pa = &pacopy;
- interface = PCI_INTERFACE(pa->pa_class);
-
- if (via_sata_chip_map_common(sc, pa) == 0)
+ if (pciide_chipen(sc, pa) == 0)
return;
- if (interface == 0) {
- ATADEBUG_PRINT(("via_sata_chip_map interface == 0\n"),
- DEBUG_PROBE);
- interface = PCIIDE_INTERFACE_BUS_MASTER_DMA |
- PCIIDE_INTERFACE_PCI(0) | PCIIDE_INTERFACE_PCI(1);
+ sc->sc_apo_regbase = APO_VIA_VT6421_REGBASE;
+
+ if (pci_mapreg_map(pa, PCI_BAR(5), PCI_MAPREG_TYPE_IO, 0,
+ &sc->sc_ba5_st, &sc->sc_ba5_sh, NULL, &sc->sc_ba5_ss) != 0) {
+ aprint_error_dev(sc->sc_wdcdev.sc_atac.atac_dev,
+ "couldn't map SATA regs\n");
}
+ aprint_verbose_dev(sc->sc_wdcdev.sc_atac.atac_dev,
+ "bus-master DMA support present");
+ via_vt6421_mapreg_dma(sc, pa);
+ aprint_verbose("\n");
+
+ sc->sc_wdcdev.sc_atac.atac_cap |= ATAC_CAP_DATA16 | ATAC_CAP_DATA32;
+ sc->sc_wdcdev.sc_atac.atac_pio_cap = 4;
+ if (sc->sc_dma_ok) {
+ sc->sc_wdcdev.sc_atac.atac_cap |= ATAC_CAP_DMA | ATAC_CAP_UDMA;
+ sc->sc_wdcdev.irqack = pciide_irqack;
+ sc->sc_wdcdev.sc_atac.atac_dma_cap = 2;
+ sc->sc_wdcdev.sc_atac.atac_udma_cap = 6;
+ }
+ sc->sc_wdcdev.sc_atac.atac_set_modes = sata_setup_channel;
+
+ sc->sc_wdcdev.sc_atac.atac_channels = sc->wdc_chanarray;
+ sc->sc_wdcdev.sc_atac.atac_nchannels = 3;
+
+ wdc_allocate_regs(&sc->sc_wdcdev);
+
if (pci_intr_map(pa, &intrhandle) != 0) {
aprint_error_dev(sc->sc_wdcdev.sc_atac.atac_dev,
"couldn't map native-PCI interrupt\n");
@@ -1033,9 +1120,9 @@
for (channel = 0; channel < sc->sc_wdcdev.sc_atac.atac_nchannels;
channel++) {
cp = &sc->pciide_channels[channel];
- if (pciide_chansetup(sc, channel, interface) == 0)
+ if (via_vt6421_chansetup(sc, channel) == 0)
continue;
- cp->ata_channel.ch_ndrive = 1;
+ cp->ata_channel.ch_ndrive = 2;
wdc_cp = &cp->ata_channel;
wdr = CHAN_TO_WDC_REGS(wdc_cp);
@@ -1065,9 +1152,8 @@
wdc_cp->ch_channel);
continue;
}
- sc->sc_wdcdev.sc_atac.atac_probe = wdc_sataprobe;
- if (pci_mapreg_map(pa, (PCI_MAPREG_START + (4 * (channel))),
+ if (pci_mapreg_map(pa, PCI_BAR(wdc_cp->ch_channel),
PCI_MAPREG_TYPE_IO, 0, &wdr->cmd_iot, &wdr->cmd_baseioh,
NULL, &wdr->cmd_ios) != 0) {
aprint_error_dev(sc->sc_wdcdev.sc_atac.atac_dev,
Home |
Main Index |
Thread Index |
Old Index