diff options
Diffstat (limited to 'sound/usb/6fire/pcm.c')
| -rw-r--r-- | sound/usb/6fire/pcm.c | 87 |
1 files changed, 65 insertions, 22 deletions
diff --git a/sound/usb/6fire/pcm.c b/sound/usb/6fire/pcm.c index 3d2551cc10f..ba40489b2de 100644 --- a/sound/usb/6fire/pcm.c +++ b/sound/usb/6fire/pcm.c @@ -79,32 +79,35 @@ static int usb6fire_pcm_set_rate(struct pcm_runtime *rt) ctrl_rt->usb_streaming = false; ret = ctrl_rt->update_streaming(ctrl_rt); if (ret < 0) { - snd_printk(KERN_ERR PREFIX "error stopping streaming while " - "setting samplerate %d.\n", rates[rt->rate]); + dev_err(&rt->chip->dev->dev, + "error stopping streaming while setting samplerate %d.\n", + rates[rt->rate]); return ret; } ret = ctrl_rt->set_rate(ctrl_rt, rt->rate); if (ret < 0) { - snd_printk(KERN_ERR PREFIX "error setting samplerate %d.\n", - rates[rt->rate]); + dev_err(&rt->chip->dev->dev, + "error setting samplerate %d.\n", + rates[rt->rate]); return ret; } ret = ctrl_rt->set_channels(ctrl_rt, OUT_N_CHANNELS, IN_N_CHANNELS, false, false); if (ret < 0) { - snd_printk(KERN_ERR PREFIX "error initializing channels " - "while setting samplerate %d.\n", - rates[rt->rate]); + dev_err(&rt->chip->dev->dev, + "error initializing channels while setting samplerate %d.\n", + rates[rt->rate]); return ret; } ctrl_rt->usb_streaming = true; ret = ctrl_rt->update_streaming(ctrl_rt); if (ret < 0) { - snd_printk(KERN_ERR PREFIX "error starting streaming while " - "setting samplerate %d.\n", rates[rt->rate]); + dev_err(&rt->chip->dev->dev, + "error starting streaming while setting samplerate %d.\n", + rates[rt->rate]); return ret; } @@ -124,7 +127,7 @@ static struct pcm_substream *usb6fire_pcm_get_substream( return &rt->playback; else if (alsa_sub->stream == SNDRV_PCM_STREAM_CAPTURE) return &rt->capture; - snd_printk(KERN_ERR PREFIX "error getting pcm substream slot.\n"); + dev_err(&rt->chip->dev->dev, "error getting pcm substream slot.\n"); return NULL; } @@ -257,7 +260,7 @@ static void usb6fire_pcm_playback(struct pcm_substream *sub, else if (alsa_rt->format == SNDRV_PCM_FORMAT_S24_LE) dest = (u32 *) (urb->buffer); else { - snd_printk(KERN_ERR PREFIX "Unknown sample format."); + dev_err(&rt->chip->dev->dev, "Unknown sample format."); return; } @@ -307,8 +310,8 @@ static void usb6fire_pcm_in_urb_handler(struct urb *usb_urb) } if (rt->stream_state == STREAM_DISABLED) { - snd_printk(KERN_ERR PREFIX "internal error: " - "stream disabled in in-urb handler.\n"); + dev_err(&rt->chip->dev->dev, + "internal error: stream disabled in in-urb handler.\n"); return; } @@ -410,7 +413,7 @@ static int usb6fire_pcm_open(struct snd_pcm_substream *alsa_sub) if (!sub) { mutex_unlock(&rt->stream_mutex); - snd_printk(KERN_ERR PREFIX "invalid stream type.\n"); + dev_err(&rt->chip->dev->dev, "invalid stream type.\n"); return -EINVAL; } @@ -481,8 +484,9 @@ static int usb6fire_pcm_prepare(struct snd_pcm_substream *alsa_sub) break; if (rt->rate == ARRAY_SIZE(rates)) { mutex_unlock(&rt->stream_mutex); - snd_printk("invalid rate %d in prepare.\n", - alsa_rt->rate); + dev_err(&rt->chip->dev->dev, + "invalid rate %d in prepare.\n", + alsa_rt->rate); return -EINVAL; } @@ -494,8 +498,8 @@ static int usb6fire_pcm_prepare(struct snd_pcm_substream *alsa_sub) ret = usb6fire_pcm_stream_start(rt); if (ret) { mutex_unlock(&rt->stream_mutex); - snd_printk(KERN_ERR PREFIX - "could not start pcm stream.\n"); + dev_err(&rt->chip->dev->dev, + "could not start pcm stream.\n"); return ret; } } @@ -582,6 +586,33 @@ static void usb6fire_pcm_init_urb(struct pcm_urb *urb, urb->instance.number_of_packets = PCM_N_PACKETS_PER_URB; } +static int usb6fire_pcm_buffers_init(struct pcm_runtime *rt) +{ + int i; + + for (i = 0; i < PCM_N_URBS; i++) { + rt->out_urbs[i].buffer = kzalloc(PCM_N_PACKETS_PER_URB + * PCM_MAX_PACKET_SIZE, GFP_KERNEL); + if (!rt->out_urbs[i].buffer) + return -ENOMEM; + rt->in_urbs[i].buffer = kzalloc(PCM_N_PACKETS_PER_URB + * PCM_MAX_PACKET_SIZE, GFP_KERNEL); + if (!rt->in_urbs[i].buffer) + return -ENOMEM; + } + return 0; +} + +static void usb6fire_pcm_buffers_destroy(struct pcm_runtime *rt) +{ + int i; + + for (i = 0; i < PCM_N_URBS; i++) { + kfree(rt->out_urbs[i].buffer); + kfree(rt->in_urbs[i].buffer); + } +} + int usb6fire_pcm_init(struct sfire_chip *chip) { int i; @@ -593,6 +624,13 @@ int usb6fire_pcm_init(struct sfire_chip *chip) if (!rt) return -ENOMEM; + ret = usb6fire_pcm_buffers_init(rt); + if (ret) { + usb6fire_pcm_buffers_destroy(rt); + kfree(rt); + return ret; + } + rt->chip = chip; rt->stream_state = STREAM_DISABLED; rt->rate = ARRAY_SIZE(rates); @@ -614,8 +652,9 @@ int usb6fire_pcm_init(struct sfire_chip *chip) ret = snd_pcm_new(chip->card, "DMX6FireUSB", 0, 1, 1, &pcm); if (ret < 0) { + usb6fire_pcm_buffers_destroy(rt); kfree(rt); - snd_printk(KERN_ERR PREFIX "cannot create pcm instance.\n"); + dev_err(&chip->dev->dev, "cannot create pcm instance.\n"); return ret; } @@ -625,9 +664,10 @@ int usb6fire_pcm_init(struct sfire_chip *chip) snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &pcm_ops); if (ret) { + usb6fire_pcm_buffers_destroy(rt); kfree(rt); - snd_printk(KERN_ERR PREFIX - "error preallocating pcm buffers.\n"); + dev_err(&chip->dev->dev, + "error preallocating pcm buffers.\n"); return ret; } rt->instance = pcm; @@ -669,6 +709,9 @@ void usb6fire_pcm_abort(struct sfire_chip *chip) void usb6fire_pcm_destroy(struct sfire_chip *chip) { - kfree(chip->pcm); + struct pcm_runtime *rt = chip->pcm; + + usb6fire_pcm_buffers_destroy(rt); + kfree(rt); chip->pcm = NULL; } |
