static void * yds_malloc(void *addr, int direction, size_t size) { struct yds_softc *sc; struct yds_dma *p; int error; p = kmem_alloc(sizeof(*p), KM_SLEEP); if (p == NULL) return NULL; sc = addr; error = yds_allocmem(sc, size, 16, p); if (error) { kmem_free(p, sizeof(*p)); return NULL; } p->next = sc->sc_dmas; sc->sc_dmas = p; return KERNADDR(p); }
static int yds_allocate_slots(struct yds_softc *sc, int resuming) { size_t pcs, rcs, ecs, ws, memsize; void *mp; u_int32_t da; /* DMA address */ char *va; /* KVA */ off_t cb; int i; struct yds_dma *p; /* Alloc DSP Control Data */ pcs = YREAD4(sc, YDS_PLAY_CTRLSIZE) * sizeof(u_int32_t); rcs = YREAD4(sc, YDS_REC_CTRLSIZE) * sizeof(u_int32_t); ecs = YREAD4(sc, YDS_EFFECT_CTRLSIZE) * sizeof(u_int32_t); ws = WORK_SIZE; YWRITE4(sc, YDS_WORK_SIZE, ws / sizeof(u_int32_t)); DPRINTF(("play control size : %d\n", (unsigned int)pcs)); DPRINTF(("rec control size : %d\n", (unsigned int)rcs)); DPRINTF(("eff control size : %d\n", (unsigned int)ecs)); DPRINTF(("work size : %d\n", (unsigned int)ws)); #ifdef DIAGNOSTIC if (pcs != sizeof(struct play_slot_ctrl_bank)) { printf("%s: invalid play slot ctrldata %d != %d\n", sc->sc_dev.dv_xname, (unsigned int)pcs, (unsigned int)sizeof(struct play_slot_ctrl_bank)); } if (rcs != sizeof(struct rec_slot_ctrl_bank)) { printf("%s: invalid rec slot ctrldata %d != %d\n", sc->sc_dev.dv_xname, (unsigned int)rcs, (unsigned int)sizeof(struct rec_slot_ctrl_bank)); } #endif memsize = N_PLAY_SLOTS*N_PLAY_SLOT_CTRL_BANK*pcs + N_REC_SLOT_CTRL*N_REC_SLOT_CTRL_BANK*rcs + ws; memsize += (N_PLAY_SLOTS+1)*sizeof(u_int32_t); p = &sc->sc_ctrldata; if (!resuming) { i = yds_allocmem(sc, memsize, 16, p); if (i) { printf("%s: couldn't alloc/map DSP DMA buffer, reason %d\n", sc->sc_dev.dv_xname, i); free(p, M_DEVBUF); return 1; } } mp = KERNADDR(p); da = DMAADDR(p); DPRINTF(("mp:%p, DMA addr:%p\n", mp, (void *) sc->sc_ctrldata.map->dm_segs[0].ds_addr)); bzero(mp, memsize); /* Work space */ cb = 0; va = (u_int8_t*)mp; YWRITE4(sc, YDS_WORK_BASE, da + cb); cb += ws; /* Play control data table */ sc->ptbl = (u_int32_t *)(va + cb); sc->ptbloff = cb; YWRITE4(sc, YDS_PLAY_CTRLBASE, da + cb); cb += (N_PLAY_SLOT_CTRL + 1) * sizeof(u_int32_t); /* Record slot control data */ sc->rbank = (struct rec_slot_ctrl_bank *)(va + cb); YWRITE4(sc, YDS_REC_CTRLBASE, da + cb); sc->rbankoff = cb; cb += N_REC_SLOT_CTRL * N_REC_SLOT_CTRL_BANK * rcs; #if 0 /* Effect slot control data -- unused */ YWRITE4(sc, YDS_EFFECT_CTRLBASE, da + cb); cb += N_EFFECT_SLOT_CTRL * N_EFFECT_SLOT_CTRL_BANK * ecs; #endif /* Play slot control data */ sc->pbankoff = da + cb; for (i=0; i<N_PLAY_SLOT_CTRL; i++) { sc->pbankp[i*2] = (struct play_slot_ctrl_bank *)(va + cb); *(sc->ptbl + i+1) = da + cb; cb += pcs; sc->pbankp[i*2+1] = (struct play_slot_ctrl_bank *)(va + cb); cb += pcs; } /* Sync play control data table */ bus_dmamap_sync(sc->sc_dmatag, p->map, sc->ptbloff, (N_PLAY_SLOT_CTRL+1) * sizeof(u_int32_t), BUS_DMASYNC_PREWRITE); return 0; }