diff --git a/sys/dev/sound/usb/uaudio_pcm.c b/sys/dev/sound/usb/uaudio_pcm.c index 9e6e0d1b9c84..d75f3e3d2f1f 100644 --- a/sys/dev/sound/usb/uaudio_pcm.c +++ b/sys/dev/sound/usb/uaudio_pcm.c @@ -40,14 +40,15 @@ struct ua_chinfo { struct ua_info *parent; struct pcm_channel *channel; struct snd_dbuf *buffer; + u_char *buf; int dir, hwch; u_int32_t fmt, spd, blksz; /* XXXXX */ }; struct ua_info { device_t sc_dev; + u_int32_t bufsz; struct ua_chinfo pch, rch; - bus_dma_tag_t parent_dmat; }; static u_int32_t ua_playfmt[8*2+1]; /* 8 format * (stereo or mono) + endptr */ @@ -58,14 +59,13 @@ static u_int32_t ua_recfmt[8*2+1]; /* 8 format * (stereo or mono) + endptr */ static struct pcmchan_caps ua_reccaps = {8000, 48000, ua_recfmt, 0}; -#define UAUDIO_PCM_BUFF_SIZE 16*1024 +#define UAUDIO_DEFAULT_BUFSZ 16*1024 /************************************************************/ static void * ua_chan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, struct pcm_channel *c, int dir) { device_t pa_dev; - u_char *buf,*end; struct ua_info *sc = devinfo; struct ua_chinfo *ch = (dir == PCMDIR_PLAY)? &sc->pch : &sc->rch; @@ -91,14 +91,17 @@ ua_chan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, struct pcm_channel * } - /* allocate PCM side DMA buffer */ - if (sndbuf_alloc(ch->buffer, sc->parent_dmat, UAUDIO_PCM_BUFF_SIZE) != 0) { - return NULL; - } - - buf = end = sndbuf_getbuf(b); - end += sndbuf_getsize(b); - uaudio_chan_set_param_pcm_dma_buff(pa_dev, buf, end, ch->channel, dir); + ch->buf = malloc(sc->bufsz, M_DEVBUF, M_NOWAIT); + if (ch->buf == NULL) + return NULL; + if (sndbuf_setup(b, ch->buf, sc->bufsz) != 0) { + free(ch->buf, M_DEVBUF); + return NULL; + } + uaudio_chan_set_param_pcm_dma_buff(pa_dev, ch->buf, ch->buf+sc->bufsz, ch->channel, dir); + if (bootverbose) + device_printf(pa_dev, "%s buf %p\n", (dir == PCMDIR_PLAY)? + "play" : "rec", sndbuf_getbuf(ch->buffer)); ch->dir = dir; #ifndef NO_RECORDING @@ -112,6 +115,16 @@ ua_chan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, struct pcm_channel * return ch; } +static int +ua_chan_free(kobj_t obj, void *data) +{ + struct ua_chinfo *ua = data; + + if (ua->buf != NULL) + free(ua->buf, M_DEVBUF); + return 0; +} + static int ua_chan_setformat(kobj_t obj, void *data, u_int32_t format) { @@ -148,17 +161,15 @@ static int ua_chan_setblocksize(kobj_t obj, void *data, u_int32_t blocksize) { device_t pa_dev; - struct ua_info *ua; struct ua_chinfo *ch = data; - /* ch->blksz = blocksize; */ - if (blocksize) { - ch->blksz = blocksize; - } else { - ch->blksz = UAUDIO_PCM_BUFF_SIZE/2; - } + struct ua_info *ua = ch->parent; - /* XXXXX */ - ua = ch->parent; + if (blocksize) { + RANGE(blocksize, 128, ua->bufsz / 2); + if (sndbuf_resize(ch->buffer, ua->bufsz/blocksize, blocksize) != 0) { + ch->blksz = blocksize; + } + } pa_dev = device_get_parent(ua->sc_dev); uaudio_chan_set_param_blocksize(pa_dev, blocksize, ch->dir); @@ -220,6 +231,7 @@ ua_chan_getcaps(kobj_t obj, void *data) static kobj_method_t ua_chan_methods[] = { KOBJMETHOD(channel_init, ua_chan_init), + KOBJMETHOD(channel_free, ua_chan_free), KOBJMETHOD(channel_setformat, ua_chan_setformat), KOBJMETHOD(channel_setspeed, ua_chan_setspeed), KOBJMETHOD(channel_setblocksize, ua_chan_setblocksize), @@ -306,7 +318,6 @@ ua_attach(device_t dev) { struct ua_info *ua; char status[SND_STATUSLEN]; - unsigned int bufsz; ua = (struct ua_info *)malloc(sizeof *ua, M_DEVBUF, M_NOWAIT); if (!ua) @@ -315,20 +326,10 @@ ua_attach(device_t dev) ua->sc_dev = dev; - bufsz = pcm_getbuffersize(dev, 4096, UAUDIO_PCM_BUFF_SIZE, 65536); - - if (bus_dma_tag_create(/*parent*/NULL, /*alignment*/2, /*boundary*/0, - /*lowaddr*/BUS_SPACE_MAXADDR_32BIT, - /*highaddr*/BUS_SPACE_MAXADDR, - /*filter*/NULL, /*filterarg*/NULL, - /*maxsize*/bufsz, /*nsegments*/1, - /*maxsegz*/0x4000, /*flags*/0, - /*lockfunc*/busdma_lock_mutex, - /*lockarg*/&Giant, - &ua->parent_dmat) != 0) { - device_printf(dev, "unable to create dma tag\n"); - goto bad; - } + ua->bufsz = pcm_getbuffersize(dev, 4096, UAUDIO_DEFAULT_BUFSZ, 65536); + if (bootverbose) + device_printf(dev, "using a default buffer size of %jd\n", (intmax_t)ua->bufsz); + ua->bufsz = pcm_getbuffersize(dev, 4096, UAUDIO_DEFAULT_BUFSZ, 65536); if (mixer_init(dev, &ua_mixer_class, ua)) { return(ENXIO); @@ -351,12 +352,6 @@ ua_attach(device_t dev) pcm_setstatus(dev, status); return 0; -bad: - if (ua->parent_dmat) - bus_dma_tag_destroy(ua->parent_dmat); - free(ua, M_DEVBUF); - - return ENXIO; } static int @@ -370,7 +365,6 @@ ua_detach(device_t dev) return r; sc = pcm_getdevinfo(dev); - bus_dma_tag_destroy(sc->parent_dmat); free(sc, M_DEVBUF); return 0;