X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=sound%2Fusb%2Fpcm.c;h=0e4e0640c50486b608b4a3df4c83b18fd11cae17;hb=021f163d696caed5a336fa1569efdd22216da340;hp=9245f52d43bdecfeb710b6cfc6ae99b3202aae90;hpb=01d85b9b2b6bec2b0773cf2afc58699dc4b052f8;p=deliverable%2Flinux.git diff --git a/sound/usb/pcm.c b/sound/usb/pcm.c index 9245f52d43bd..0e4e0640c504 100644 --- a/sound/usb/pcm.c +++ b/sound/usb/pcm.c @@ -35,6 +35,7 @@ #include "pcm.h" #include "clock.h" #include "power.h" +#include "media.h" #define SUBSTREAM_FLAG_DATA_EP_STARTED 0 #define SUBSTREAM_FLAG_SYNC_EP_STARTED 1 @@ -159,6 +160,8 @@ static int init_pitch_v1(struct snd_usb_audio *chip, int iface, unsigned char data[1]; int err; + if (get_iface_desc(alts)->bNumEndpoints < 1) + return -EINVAL; ep = get_endpoint(alts, 0)->bEndpointAddress; data[0] = 1; @@ -715,10 +718,14 @@ static int snd_usb_hw_params(struct snd_pcm_substream *substream, struct audioformat *fmt; int ret; + ret = media_snd_start_pipeline(subs); + if (ret) + return ret; + ret = snd_pcm_lib_alloc_vmalloc_buffer(substream, params_buffer_bytes(hw_params)); if (ret < 0) - return ret; + goto err_ret; subs->pcm_format = params_format(hw_params); subs->period_bytes = params_period_bytes(hw_params); @@ -732,22 +739,27 @@ static int snd_usb_hw_params(struct snd_pcm_substream *substream, dev_dbg(&subs->dev->dev, "cannot set format: format = %#x, rate = %d, channels = %d\n", subs->pcm_format, subs->cur_rate, subs->channels); - return -EINVAL; + ret = -EINVAL; + goto err_ret; } ret = snd_usb_lock_shutdown(subs->stream->chip); if (ret < 0) - return ret; + goto err_ret; ret = set_format(subs, fmt); snd_usb_unlock_shutdown(subs->stream->chip); if (ret < 0) - return ret; + goto err_ret; subs->interface = fmt->iface; subs->altset_idx = fmt->altset_idx; subs->need_setup_ep = true; return 0; + +err_ret: + media_snd_stop_pipeline(subs); + return ret; } /* @@ -759,6 +771,7 @@ static int snd_usb_hw_free(struct snd_pcm_substream *substream) { struct snd_usb_substream *subs = substream->runtime->private_data; + media_snd_stop_pipeline(subs); subs->cur_audiofmt = NULL; subs->cur_rate = 0; subs->period_bytes = 0; @@ -1219,6 +1232,7 @@ static int snd_usb_pcm_open(struct snd_pcm_substream *substream, int direction) struct snd_usb_stream *as = snd_pcm_substream_chip(substream); struct snd_pcm_runtime *runtime = substream->runtime; struct snd_usb_substream *subs = &as->substream[direction]; + int ret; subs->interface = -1; subs->altset_idx = 0; @@ -1232,7 +1246,12 @@ static int snd_usb_pcm_open(struct snd_pcm_substream *substream, int direction) subs->dsd_dop.channel = 0; subs->dsd_dop.marker = 1; - return setup_hw_info(runtime, subs); + ret = setup_hw_info(runtime, subs); + if (ret == 0) + ret = media_snd_stream_init(subs, as->pcm, direction); + if (ret) + snd_usb_autosuspend(subs->stream->chip); + return ret; } static int snd_usb_pcm_close(struct snd_pcm_substream *substream, int direction) @@ -1241,6 +1260,7 @@ static int snd_usb_pcm_close(struct snd_pcm_substream *substream, int direction) struct snd_usb_substream *subs = &as->substream[direction]; stop_endpoints(subs, true); + media_snd_stop_pipeline(subs); if (subs->interface >= 0 && !snd_usb_lock_shutdown(subs->stream->chip)) {