summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/dev/pci/auich.c90
1 files changed, 63 insertions, 27 deletions
diff --git a/sys/dev/pci/auich.c b/sys/dev/pci/auich.c
index b1880c5ac72..46c01854aec 100644
--- a/sys/dev/pci/auich.c
+++ b/sys/dev/pci/auich.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: auich.c,v 1.52 2005/04/14 12:42:16 mickey Exp $ */
+/* $OpenBSD: auich.c,v 1.53 2005/05/31 19:17:03 jason Exp $ */
/*
* Copyright (c) 2000,2001 Michael Shalayeff
@@ -53,15 +53,6 @@
#include <dev/ic/ac97.h>
-/*
- * XXX > 4GB kaboom: define kvtop as a truncated vtophys. Will not
- * do the right thing on machines with more than 4 gig of ram.
- */
-#if defined(__amd64__)
-#include <uvm/uvm_extern.h> /* for vtophys */
-#define kvtop(va) (int)vtophys((vaddr_t)(va))
-#endif
-
/* 12.1.10 NAMBAR - native audio mixer base address register */
#define AUICH_NAMBAR 0x10
/* 12.1.11 NABMBAR - native audio bus mastering base address register */
@@ -182,12 +173,17 @@ struct auich_softc {
struct ac97_host_if host_if;
/* dma scatter-gather buffer lists, aligned to 8 bytes */
- struct auich_dmalist *dmalist_pcmo, *dmap_pcmo,
- dmasto_pcmo[AUICH_DMALIST_MAX+1];
- struct auich_dmalist *dmalist_pcmi, *dmap_pcmi,
- dmasto_pcmi[AUICH_DMALIST_MAX+1];
- struct auich_dmalist *dmalist_mici, *dmap_mici,
- dmasto_mici[AUICH_DMALIST_MAX+1];
+ struct auich_dmalist *dmalist_pcmo, *dmap_pcmo;
+ struct auich_dmalist *dmalist_pcmi, *dmap_pcmi;
+ struct auich_dmalist *dmalist_mici, *dmap_mici;
+
+ bus_dmamap_t dmalist_map;
+ bus_dma_segment_t dmalist_seg[2];
+ caddr_t dmalist_kva;
+ bus_addr_t dmalist_pcmo_pa;
+ bus_addr_t dmalist_pcmi_pa;
+ bus_addr_t dmalist_mici_pa;
+
/* i/o buffer pointers */
u_int32_t pcmo_start, pcmo_p, pcmo_end;
int pcmo_blksize, pcmo_fifoe;
@@ -351,7 +347,8 @@ auich_attach(parent, self, aux)
pcireg_t csr;
const char *intrstr;
u_int32_t status;
- int i;
+ bus_size_t dmasz;
+ int i, segs;
if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_INTEL &&
(PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_INTEL_82801DB_ACA ||
@@ -401,7 +398,37 @@ auich_attach(parent, self, aux)
}
sc->dmat = pa->pa_dmat;
- /* enable bus mastering (should not it be mi?) */
+ /* allocate dma memory */
+ dmasz = AUICH_DMALIST_MAX * 3 * sizeof(struct auich_dma);
+ segs = 1;
+ if (bus_dmamem_alloc(sc->dmat, dmasz, PAGE_SIZE, 0, sc->dmalist_seg,
+ segs, &segs, BUS_DMA_NOWAIT)) {
+ printf(": failed to alloc dmalist\n");
+ return;
+ }
+ if (bus_dmamem_map(sc->dmat, sc->dmalist_seg, segs, dmasz,
+ &sc->dmalist_kva, BUS_DMA_NOWAIT)) {
+ printf(": failed to map dmalist\n");
+ bus_dmamem_free(sc->dmat, sc->dmalist_seg, segs);
+ return;
+ }
+ if (bus_dmamap_create(sc->dmat, dmasz, segs, dmasz, 0, BUS_DMA_NOWAIT,
+ &sc->dmalist_map)) {
+ printf(": failed to create dmalist map\n");
+ bus_dmamem_unmap(sc->dmat, sc->dmalist_kva, dmasz);
+ bus_dmamem_free(sc->dmat, sc->dmalist_seg, segs);
+ return;
+ }
+ if (bus_dmamap_load_raw(sc->dmat, sc->dmalist_map, sc->dmalist_seg,
+ segs, dmasz, BUS_DMA_NOWAIT)) {
+ printf(": failed to load dmalist map: %d segs %u size\n", segs, dmasz);
+ bus_dmamap_destroy(sc->dmat, sc->dmalist_map);
+ bus_dmamem_unmap(sc->dmat, sc->dmalist_kva, dmasz);
+ bus_dmamem_free(sc->dmat, sc->dmalist_seg, segs);
+ return;
+ }
+
+ /* enable bus mastering (should it not be mi?) */
csr = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG);
pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG,
csr | PCI_COMMAND_MASTER_ENABLE);
@@ -451,12 +478,21 @@ auich_attach(parent, self, aux)
sc->sc_sample_size = 2;
}
- /* allocate dma lists */
-#define a(a) (void *)(((u_long)(a) + sizeof(*(a)) - 1) & ~(sizeof(*(a))-1))
- sc->dmalist_pcmo = sc->dmap_pcmo = a(sc->dmasto_pcmo);
- sc->dmalist_pcmi = sc->dmap_pcmi = a(sc->dmasto_pcmi);
- sc->dmalist_mici = sc->dmap_mici = a(sc->dmasto_mici);
-#undef a
+ sc->dmalist_pcmo = (struct auich_dmalist *)(sc->dmalist_kva +
+ (0 * sizeof(struct auich_dmalist) + AUICH_DMALIST_MAX));
+ sc->dmalist_pcmo_pa = sc->dmalist_map->dm_segs[0].ds_addr +
+ (0 * sizeof(struct auich_dmalist) + AUICH_DMALIST_MAX);
+
+ sc->dmalist_pcmi = (struct auich_dmalist *)(sc->dmalist_kva +
+ (1 * sizeof(struct auich_dmalist) + AUICH_DMALIST_MAX));
+ sc->dmalist_pcmi_pa = sc->dmalist_map->dm_segs[0].ds_addr +
+ (1 * sizeof(struct auich_dmalist) + AUICH_DMALIST_MAX);
+
+ sc->dmalist_mici = (struct auich_dmalist *)(sc->dmalist_kva +
+ (2 * sizeof(struct auich_dmalist) + AUICH_DMALIST_MAX));
+ sc->dmalist_mici_pa = sc->dmalist_map->dm_segs[0].ds_addr +
+ (2 * sizeof(struct auich_dmalist) + AUICH_DMALIST_MAX);
+
DPRINTF(AUICH_DEBUG_DMA, ("auich_attach: lists %p %p %p\n",
sc->dmalist_pcmo, sc->dmalist_pcmi, sc->dmalist_mici));
@@ -1282,7 +1318,7 @@ auich_trigger_output(v, start, end, blksize, intr, arg, param)
sc->dmap_pcmo = q;
bus_space_write_4(sc->iot, sc->aud_ioh, AUICH_PCMO + AUICH_BDBAR,
- kvtop((caddr_t)sc->dmalist_pcmo));
+ sc->dmalist_pcmo_pa);
bus_space_write_1(sc->iot, sc->aud_ioh, AUICH_PCMO + AUICH_CTRL,
AUICH_IOCE | AUICH_FEIE | AUICH_LVBIE | AUICH_RPBM);
bus_space_write_1(sc->iot, sc->aud_ioh, AUICH_PCMO + AUICH_LVI,
@@ -1333,7 +1369,7 @@ auich_trigger_input(v, start, end, blksize, intr, arg, param)
sc->dmap_pcmi = q;
bus_space_write_4(sc->iot, sc->aud_ioh, AUICH_PCMI + AUICH_BDBAR,
- kvtop((caddr_t)sc->dmalist_pcmi));
+ sc->dmalist_pcmi_pa);
bus_space_write_1(sc->iot, sc->aud_ioh, AUICH_PCMI + AUICH_CTRL,
AUICH_IOCE | AUICH_FEIE | AUICH_LVBIE | AUICH_RPBM);
bus_space_write_1(sc->iot, sc->aud_ioh, AUICH_PCMI + AUICH_LVI,
@@ -1429,7 +1465,7 @@ auich_calibrate(struct auich_softc *sc)
ociv = bus_space_read_1(sc->iot, sc->aud_ioh, AUICH_PCMI + AUICH_CIV);
nciv = ociv;
bus_space_write_4(sc->iot, sc->aud_ioh, AUICH_PCMI + AUICH_BDBAR,
- kvtop((caddr_t)sc->dmalist_pcmi));
+ sc->dmalist_pcmi_pa);
bus_space_write_1(sc->iot, sc->aud_ioh, AUICH_PCMI + AUICH_LVI,
(0 - 1) & AUICH_LVI_MASK);