aboutsummaryrefslogtreecommitdiffstats
path: root/sound/usb
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2015-01-28 01:24:41 -0500
committerTakashi Iwai <tiwai@suse.de>2015-01-28 01:24:41 -0500
commit5e0ddd07fa8fcbb84faac666d36ff9c37449a849 (patch)
tree29ff039af456f0aed5280943bc9e1593893b5b21 /sound/usb
parent1001fb810b1295d0600c0c6bdcb17889460470a5 (diff)
parent247d95ee6dd22e5323ecf7a73ff64110ef2fa2da (diff)
Merge branch 'topic/line6' into for-next
Diffstat (limited to 'sound/usb')
-rw-r--r--sound/usb/line6/Kconfig2
-rw-r--r--sound/usb/line6/capture.c223
-rw-r--r--sound/usb/line6/capture.h6
-rw-r--r--sound/usb/line6/driver.c202
-rw-r--r--sound/usb/line6/driver.h10
-rw-r--r--sound/usb/line6/midi.c18
-rw-r--r--sound/usb/line6/midi.h7
-rw-r--r--sound/usb/line6/pcm.c443
-rw-r--r--sound/usb/line6/pcm.h304
-rw-r--r--sound/usb/line6/playback.c284
-rw-r--r--sound/usb/line6/playback.h6
-rw-r--r--sound/usb/line6/pod.c45
-rw-r--r--sound/usb/line6/podhd.c17
-rw-r--r--sound/usb/line6/toneport.c216
-rw-r--r--sound/usb/line6/variax.c27
15 files changed, 705 insertions, 1105 deletions
diff --git a/sound/usb/line6/Kconfig b/sound/usb/line6/Kconfig
index af20947e0bda..f4585d378ef3 100644
--- a/sound/usb/line6/Kconfig
+++ b/sound/usb/line6/Kconfig
@@ -29,6 +29,8 @@ config SND_USB_PODHD
29config SND_USB_TONEPORT 29config SND_USB_TONEPORT
30 tristate "TonePort GX, UX1 and UX2 USB support" 30 tristate "TonePort GX, UX1 and UX2 USB support"
31 select SND_USB_LINE6 31 select SND_USB_LINE6
32 select NEW_LEDS
33 select LEDS_CLASS
32 help 34 help
33 This is a driver for TonePort GX, UX1 and UX2 devices. 35 This is a driver for TonePort GX, UX1 and UX2 devices.
34 36
diff --git a/sound/usb/line6/capture.c b/sound/usb/line6/capture.c
index 5a010ba163fa..4183c5f5edc2 100644
--- a/sound/usb/line6/capture.c
+++ b/sound/usb/line6/capture.c
@@ -20,26 +20,24 @@
20 20
21/* 21/*
22 Find a free URB and submit it. 22 Find a free URB and submit it.
23 must be called in line6pcm->in.lock context
23*/ 24*/
24static int submit_audio_in_urb(struct snd_line6_pcm *line6pcm) 25static int submit_audio_in_urb(struct snd_line6_pcm *line6pcm)
25{ 26{
26 int index; 27 int index;
27 unsigned long flags;
28 int i, urb_size; 28 int i, urb_size;
29 int ret; 29 int ret;
30 struct urb *urb_in; 30 struct urb *urb_in;
31 31
32 spin_lock_irqsave(&line6pcm->lock_audio_in, flags);
33 index = 32 index =
34 find_first_zero_bit(&line6pcm->active_urb_in, LINE6_ISO_BUFFERS); 33 find_first_zero_bit(&line6pcm->in.active_urbs, LINE6_ISO_BUFFERS);
35 34
36 if (index < 0 || index >= LINE6_ISO_BUFFERS) { 35 if (index < 0 || index >= LINE6_ISO_BUFFERS) {
37 spin_unlock_irqrestore(&line6pcm->lock_audio_in, flags);
38 dev_err(line6pcm->line6->ifcdev, "no free URB found\n"); 36 dev_err(line6pcm->line6->ifcdev, "no free URB found\n");
39 return -EINVAL; 37 return -EINVAL;
40 } 38 }
41 39
42 urb_in = line6pcm->urb_audio_in[index]; 40 urb_in = line6pcm->in.urbs[index];
43 urb_size = 0; 41 urb_size = 0;
44 42
45 for (i = 0; i < LINE6_ISO_PACKETS; ++i) { 43 for (i = 0; i < LINE6_ISO_PACKETS; ++i) {
@@ -51,7 +49,7 @@ static int submit_audio_in_urb(struct snd_line6_pcm *line6pcm)
51 } 49 }
52 50
53 urb_in->transfer_buffer = 51 urb_in->transfer_buffer =
54 line6pcm->buffer_in + 52 line6pcm->in.buffer +
55 index * LINE6_ISO_PACKETS * line6pcm->max_packet_size; 53 index * LINE6_ISO_PACKETS * line6pcm->max_packet_size;
56 urb_in->transfer_buffer_length = urb_size; 54 urb_in->transfer_buffer_length = urb_size;
57 urb_in->context = line6pcm; 55 urb_in->context = line6pcm;
@@ -59,81 +57,29 @@ static int submit_audio_in_urb(struct snd_line6_pcm *line6pcm)
59 ret = usb_submit_urb(urb_in, GFP_ATOMIC); 57 ret = usb_submit_urb(urb_in, GFP_ATOMIC);
60 58
61 if (ret == 0) 59 if (ret == 0)
62 set_bit(index, &line6pcm->active_urb_in); 60 set_bit(index, &line6pcm->in.active_urbs);
63 else 61 else
64 dev_err(line6pcm->line6->ifcdev, 62 dev_err(line6pcm->line6->ifcdev,
65 "URB in #%d submission failed (%d)\n", index, ret); 63 "URB in #%d submission failed (%d)\n", index, ret);
66 64
67 spin_unlock_irqrestore(&line6pcm->lock_audio_in, flags);
68 return 0; 65 return 0;
69} 66}
70 67
71/* 68/*
72 Submit all currently available capture URBs. 69 Submit all currently available capture URBs.
70 must be called in line6pcm->in.lock context
73*/ 71*/
74int line6_submit_audio_in_all_urbs(struct snd_line6_pcm *line6pcm) 72int line6_submit_audio_in_all_urbs(struct snd_line6_pcm *line6pcm)
75{ 73{
76 int ret, i; 74 int ret = 0, i;
77 75
78 for (i = 0; i < LINE6_ISO_BUFFERS; ++i) { 76 for (i = 0; i < LINE6_ISO_BUFFERS; ++i) {
79 ret = submit_audio_in_urb(line6pcm); 77 ret = submit_audio_in_urb(line6pcm);
80 if (ret < 0) 78 if (ret < 0)
81 return ret;
82 }
83
84 return 0;
85}
86
87/*
88 Unlink all currently active capture URBs.
89*/
90void line6_unlink_audio_in_urbs(struct snd_line6_pcm *line6pcm)
91{
92 unsigned int i;
93
94 for (i = LINE6_ISO_BUFFERS; i--;) {
95 if (test_bit(i, &line6pcm->active_urb_in)) {
96 if (!test_and_set_bit(i, &line6pcm->unlink_urb_in)) {
97 struct urb *u = line6pcm->urb_audio_in[i];
98
99 usb_unlink_urb(u);
100 }
101 }
102 }
103}
104
105/*
106 Wait until unlinking of all currently active capture URBs has been
107 finished.
108*/
109void line6_wait_clear_audio_in_urbs(struct snd_line6_pcm *line6pcm)
110{
111 int timeout = HZ;
112 unsigned int i;
113 int alive;
114
115 do {
116 alive = 0;
117 for (i = LINE6_ISO_BUFFERS; i--;) {
118 if (test_bit(i, &line6pcm->active_urb_in))
119 alive++;
120 }
121 if (!alive)
122 break; 79 break;
123 set_current_state(TASK_UNINTERRUPTIBLE); 80 }
124 schedule_timeout(1);
125 } while (--timeout > 0);
126 if (alive)
127 snd_printk(KERN_ERR "timeout: still %d active urbs..\n", alive);
128}
129 81
130/* 82 return ret;
131 Unlink all currently active capture URBs, and wait for finishing.
132*/
133void line6_unlink_wait_clear_audio_in_urbs(struct snd_line6_pcm *line6pcm)
134{
135 line6_unlink_audio_in_urbs(line6pcm);
136 line6_wait_clear_audio_in_urbs(line6pcm);
137} 83}
138 84
139/* 85/*
@@ -150,18 +96,18 @@ void line6_capture_copy(struct snd_line6_pcm *line6pcm, char *fbuf, int fsize)
150 if (runtime == NULL) 96 if (runtime == NULL)
151 return; 97 return;
152 98
153 if (line6pcm->pos_in_done + frames > runtime->buffer_size) { 99 if (line6pcm->in.pos_done + frames > runtime->buffer_size) {
154 /* 100 /*
155 The transferred area goes over buffer boundary, 101 The transferred area goes over buffer boundary,
156 copy two separate chunks. 102 copy two separate chunks.
157 */ 103 */
158 int len; 104 int len;
159 105
160 len = runtime->buffer_size - line6pcm->pos_in_done; 106 len = runtime->buffer_size - line6pcm->in.pos_done;
161 107
162 if (len > 0) { 108 if (len > 0) {
163 memcpy(runtime->dma_area + 109 memcpy(runtime->dma_area +
164 line6pcm->pos_in_done * bytes_per_frame, fbuf, 110 line6pcm->in.pos_done * bytes_per_frame, fbuf,
165 len * bytes_per_frame); 111 len * bytes_per_frame);
166 memcpy(runtime->dma_area, fbuf + len * bytes_per_frame, 112 memcpy(runtime->dma_area, fbuf + len * bytes_per_frame,
167 (frames - len) * bytes_per_frame); 113 (frames - len) * bytes_per_frame);
@@ -173,12 +119,12 @@ void line6_capture_copy(struct snd_line6_pcm *line6pcm, char *fbuf, int fsize)
173 } else { 119 } else {
174 /* copy single chunk */ 120 /* copy single chunk */
175 memcpy(runtime->dma_area + 121 memcpy(runtime->dma_area +
176 line6pcm->pos_in_done * bytes_per_frame, fbuf, fsize); 122 line6pcm->in.pos_done * bytes_per_frame, fbuf, fsize);
177 } 123 }
178 124
179 line6pcm->pos_in_done += frames; 125 line6pcm->in.pos_done += frames;
180 if (line6pcm->pos_in_done >= runtime->buffer_size) 126 if (line6pcm->in.pos_done >= runtime->buffer_size)
181 line6pcm->pos_in_done -= runtime->buffer_size; 127 line6pcm->in.pos_done -= runtime->buffer_size;
182} 128}
183 129
184void line6_capture_check_period(struct snd_line6_pcm *line6pcm, int length) 130void line6_capture_check_period(struct snd_line6_pcm *line6pcm, int length)
@@ -186,19 +132,15 @@ void line6_capture_check_period(struct snd_line6_pcm *line6pcm, int length)
186 struct snd_pcm_substream *substream = 132 struct snd_pcm_substream *substream =
187 get_substream(line6pcm, SNDRV_PCM_STREAM_CAPTURE); 133 get_substream(line6pcm, SNDRV_PCM_STREAM_CAPTURE);
188 134
189 line6pcm->bytes_in += length; 135 line6pcm->in.bytes += length;
190 if (line6pcm->bytes_in >= line6pcm->period_in) { 136 if (line6pcm->in.bytes >= line6pcm->in.period) {
191 line6pcm->bytes_in %= line6pcm->period_in; 137 line6pcm->in.bytes %= line6pcm->in.period;
138 spin_unlock(&line6pcm->in.lock);
192 snd_pcm_period_elapsed(substream); 139 snd_pcm_period_elapsed(substream);
140 spin_lock(&line6pcm->in.lock);
193 } 141 }
194} 142}
195 143
196void line6_free_capture_buffer(struct snd_line6_pcm *line6pcm)
197{
198 kfree(line6pcm->buffer_in);
199 line6pcm->buffer_in = NULL;
200}
201
202/* 144/*
203 * Callback for completed capture URB. 145 * Callback for completed capture URB.
204 */ 146 */
@@ -209,14 +151,14 @@ static void audio_in_callback(struct urb *urb)
209 151
210 struct snd_line6_pcm *line6pcm = (struct snd_line6_pcm *)urb->context; 152 struct snd_line6_pcm *line6pcm = (struct snd_line6_pcm *)urb->context;
211 153
212 line6pcm->last_frame_in = urb->start_frame; 154 line6pcm->in.last_frame = urb->start_frame;
213 155
214 /* find index of URB */ 156 /* find index of URB */
215 for (index = 0; index < LINE6_ISO_BUFFERS; ++index) 157 for (index = 0; index < LINE6_ISO_BUFFERS; ++index)
216 if (urb == line6pcm->urb_audio_in[index]) 158 if (urb == line6pcm->in.urbs[index])
217 break; 159 break;
218 160
219 spin_lock_irqsave(&line6pcm->lock_audio_in, flags); 161 spin_lock_irqsave(&line6pcm->in.lock, flags);
220 162
221 for (i = 0; i < LINE6_ISO_PACKETS; ++i) { 163 for (i = 0; i < LINE6_ISO_PACKETS; ++i) {
222 char *fbuf; 164 char *fbuf;
@@ -243,27 +185,26 @@ static void audio_in_callback(struct urb *urb)
243 line6pcm->prev_fbuf = fbuf; 185 line6pcm->prev_fbuf = fbuf;
244 line6pcm->prev_fsize = fsize; 186 line6pcm->prev_fsize = fsize;
245 187
246 if (!(line6pcm->flags & LINE6_BITS_PCM_IMPULSE)) 188 if (!test_bit(LINE6_STREAM_IMPULSE, &line6pcm->in.running) &&
247 if (test_bit(LINE6_INDEX_PCM_ALSA_CAPTURE_STREAM, 189 test_bit(LINE6_STREAM_PCM, &line6pcm->in.running) &&
248 &line6pcm->flags) && (fsize > 0)) 190 fsize > 0)
249 line6_capture_copy(line6pcm, fbuf, fsize); 191 line6_capture_copy(line6pcm, fbuf, fsize);
250 } 192 }
251 193
252 clear_bit(index, &line6pcm->active_urb_in); 194 clear_bit(index, &line6pcm->in.active_urbs);
253 195
254 if (test_and_clear_bit(index, &line6pcm->unlink_urb_in)) 196 if (test_and_clear_bit(index, &line6pcm->in.unlink_urbs))
255 shutdown = 1; 197 shutdown = 1;
256 198
257 spin_unlock_irqrestore(&line6pcm->lock_audio_in, flags);
258
259 if (!shutdown) { 199 if (!shutdown) {
260 submit_audio_in_urb(line6pcm); 200 submit_audio_in_urb(line6pcm);
261 201
262 if (!(line6pcm->flags & LINE6_BITS_PCM_IMPULSE)) 202 if (!test_bit(LINE6_STREAM_IMPULSE, &line6pcm->in.running) &&
263 if (test_bit(LINE6_INDEX_PCM_ALSA_CAPTURE_STREAM, 203 test_bit(LINE6_STREAM_PCM, &line6pcm->in.running))
264 &line6pcm->flags)) 204 line6_capture_check_period(line6pcm, length);
265 line6_capture_check_period(line6pcm, length);
266 } 205 }
206
207 spin_unlock_irqrestore(&line6pcm->in.lock, flags);
267} 208}
268 209
269/* open capture callback */ 210/* open capture callback */
@@ -290,102 +231,16 @@ static int snd_line6_capture_close(struct snd_pcm_substream *substream)
290 return 0; 231 return 0;
291} 232}
292 233
293/* hw_params capture callback */
294static int snd_line6_capture_hw_params(struct snd_pcm_substream *substream,
295 struct snd_pcm_hw_params *hw_params)
296{
297 int ret;
298 struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
299
300 /* -- Florian Demski [FD] */
301 /* don't ask me why, but this fixes the bug on my machine */
302 if (line6pcm == NULL) {
303 if (substream->pcm == NULL)
304 return -ENOMEM;
305 if (substream->pcm->private_data == NULL)
306 return -ENOMEM;
307 substream->private_data = substream->pcm->private_data;
308 line6pcm = snd_pcm_substream_chip(substream);
309 }
310 /* -- [FD] end */
311
312 ret = line6_pcm_acquire(line6pcm, LINE6_BIT_PCM_ALSA_CAPTURE_BUFFER);
313
314 if (ret < 0)
315 return ret;
316
317 ret = snd_pcm_lib_malloc_pages(substream,
318 params_buffer_bytes(hw_params));
319 if (ret < 0) {
320 line6_pcm_release(line6pcm, LINE6_BIT_PCM_ALSA_CAPTURE_BUFFER);
321 return ret;
322 }
323
324 line6pcm->period_in = params_period_bytes(hw_params);
325 return 0;
326}
327
328/* hw_free capture callback */
329static int snd_line6_capture_hw_free(struct snd_pcm_substream *substream)
330{
331 struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
332
333 line6_pcm_release(line6pcm, LINE6_BIT_PCM_ALSA_CAPTURE_BUFFER);
334 return snd_pcm_lib_free_pages(substream);
335}
336
337/* trigger callback */
338int snd_line6_capture_trigger(struct snd_line6_pcm *line6pcm, int cmd)
339{
340 int err;
341
342 switch (cmd) {
343 case SNDRV_PCM_TRIGGER_START:
344 case SNDRV_PCM_TRIGGER_RESUME:
345 err = line6_pcm_acquire(line6pcm,
346 LINE6_BIT_PCM_ALSA_CAPTURE_STREAM);
347
348 if (err < 0)
349 return err;
350
351 break;
352
353 case SNDRV_PCM_TRIGGER_STOP:
354 case SNDRV_PCM_TRIGGER_SUSPEND:
355 err = line6_pcm_release(line6pcm,
356 LINE6_BIT_PCM_ALSA_CAPTURE_STREAM);
357
358 if (err < 0)
359 return err;
360
361 break;
362
363 default:
364 return -EINVAL;
365 }
366
367 return 0;
368}
369
370/* capture pointer callback */
371static snd_pcm_uframes_t
372snd_line6_capture_pointer(struct snd_pcm_substream *substream)
373{
374 struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
375
376 return line6pcm->pos_in_done;
377}
378
379/* capture operators */ 234/* capture operators */
380struct snd_pcm_ops snd_line6_capture_ops = { 235struct snd_pcm_ops snd_line6_capture_ops = {
381 .open = snd_line6_capture_open, 236 .open = snd_line6_capture_open,
382 .close = snd_line6_capture_close, 237 .close = snd_line6_capture_close,
383 .ioctl = snd_pcm_lib_ioctl, 238 .ioctl = snd_pcm_lib_ioctl,
384 .hw_params = snd_line6_capture_hw_params, 239 .hw_params = snd_line6_hw_params,
385 .hw_free = snd_line6_capture_hw_free, 240 .hw_free = snd_line6_hw_free,
386 .prepare = snd_line6_prepare, 241 .prepare = snd_line6_prepare,
387 .trigger = snd_line6_trigger, 242 .trigger = snd_line6_trigger,
388 .pointer = snd_line6_capture_pointer, 243 .pointer = snd_line6_pointer,
389}; 244};
390 245
391int line6_create_audio_in_urbs(struct snd_line6_pcm *line6pcm) 246int line6_create_audio_in_urbs(struct snd_line6_pcm *line6pcm)
@@ -398,7 +253,7 @@ int line6_create_audio_in_urbs(struct snd_line6_pcm *line6pcm)
398 struct urb *urb; 253 struct urb *urb;
399 254
400 /* URB for audio in: */ 255 /* URB for audio in: */
401 urb = line6pcm->urb_audio_in[i] = 256 urb = line6pcm->in.urbs[i] =
402 usb_alloc_urb(LINE6_ISO_PACKETS, GFP_KERNEL); 257 usb_alloc_urb(LINE6_ISO_PACKETS, GFP_KERNEL);
403 258
404 if (urb == NULL) 259 if (urb == NULL)
diff --git a/sound/usb/line6/capture.h b/sound/usb/line6/capture.h
index 0939f400a405..890b21bff18c 100644
--- a/sound/usb/line6/capture.h
+++ b/sound/usb/line6/capture.h
@@ -24,12 +24,6 @@ extern void line6_capture_copy(struct snd_line6_pcm *line6pcm, char *fbuf,
24extern void line6_capture_check_period(struct snd_line6_pcm *line6pcm, 24extern void line6_capture_check_period(struct snd_line6_pcm *line6pcm,
25 int length); 25 int length);
26extern int line6_create_audio_in_urbs(struct snd_line6_pcm *line6pcm); 26extern int line6_create_audio_in_urbs(struct snd_line6_pcm *line6pcm);
27extern void line6_free_capture_buffer(struct snd_line6_pcm *line6pcm);
28extern int line6_submit_audio_in_all_urbs(struct snd_line6_pcm *line6pcm); 27extern int line6_submit_audio_in_all_urbs(struct snd_line6_pcm *line6pcm);
29extern void line6_unlink_audio_in_urbs(struct snd_line6_pcm *line6pcm);
30extern void line6_unlink_wait_clear_audio_in_urbs(struct snd_line6_pcm
31 *line6pcm);
32extern void line6_wait_clear_audio_in_urbs(struct snd_line6_pcm *line6pcm);
33extern int snd_line6_capture_trigger(struct snd_line6_pcm *line6pcm, int cmd);
34 28
35#endif 29#endif
diff --git a/sound/usb/line6/driver.c b/sound/usb/line6/driver.c
index 93cd4daa56bc..a0436993a167 100644
--- a/sound/usb/line6/driver.c
+++ b/sound/usb/line6/driver.c
@@ -413,26 +413,12 @@ int line6_read_serial_number(struct usb_line6 *line6, int *serial_number)
413EXPORT_SYMBOL_GPL(line6_read_serial_number); 413EXPORT_SYMBOL_GPL(line6_read_serial_number);
414 414
415/* 415/*
416 No operation (i.e., unsupported).
417*/
418ssize_t line6_nop_read(struct device *dev, struct device_attribute *attr,
419 char *buf)
420{
421 return 0;
422}
423EXPORT_SYMBOL_GPL(line6_nop_read);
424
425/*
426 Card destructor. 416 Card destructor.
427*/ 417*/
428static void line6_destruct(struct snd_card *card) 418static void line6_destruct(struct snd_card *card)
429{ 419{
430 struct usb_line6 *line6 = card->private_data; 420 struct usb_line6 *line6 = card->private_data;
431 struct usb_device *usbdev; 421 struct usb_device *usbdev = line6->usbdev;
432
433 if (!line6)
434 return;
435 usbdev = line6->usbdev;
436 422
437 /* free buffer memory first: */ 423 /* free buffer memory first: */
438 kfree(line6->buffer_message); 424 kfree(line6->buffer_message);
@@ -441,82 +427,96 @@ static void line6_destruct(struct snd_card *card)
441 /* then free URBs: */ 427 /* then free URBs: */
442 usb_free_urb(line6->urb_listen); 428 usb_free_urb(line6->urb_listen);
443 429
444 /* free interface data: */
445 kfree(line6);
446
447 /* decrement reference counters: */ 430 /* decrement reference counters: */
448 usb_put_dev(usbdev); 431 usb_put_dev(usbdev);
449} 432}
450 433
434/* get data from endpoint descriptor (see usb_maxpacket): */
435static void line6_get_interval(struct usb_line6 *line6)
436{
437 struct usb_device *usbdev = line6->usbdev;
438 struct usb_host_endpoint *ep;
439 unsigned pipe = usb_rcvintpipe(usbdev, line6->properties->ep_ctrl_r);
440 unsigned epnum = usb_pipeendpoint(pipe);
441
442 ep = usbdev->ep_in[epnum];
443 if (ep) {
444 line6->interval = ep->desc.bInterval;
445 line6->max_packet_size = le16_to_cpu(ep->desc.wMaxPacketSize);
446 } else {
447 dev_err(line6->ifcdev,
448 "endpoint not available, using fallback values");
449 line6->interval = LINE6_FALLBACK_INTERVAL;
450 line6->max_packet_size = LINE6_FALLBACK_MAXPACKETSIZE;
451 }
452}
453
454static int line6_init_cap_control(struct usb_line6 *line6)
455{
456 int ret;
457
458 /* initialize USB buffers: */
459 line6->buffer_listen = kmalloc(LINE6_BUFSIZE_LISTEN, GFP_KERNEL);
460 if (!line6->buffer_listen)
461 return -ENOMEM;
462
463 line6->buffer_message = kmalloc(LINE6_MESSAGE_MAXLEN, GFP_KERNEL);
464 if (!line6->buffer_message)
465 return -ENOMEM;
466
467 line6->urb_listen = usb_alloc_urb(0, GFP_KERNEL);
468 if (!line6->urb_listen)
469 return -ENOMEM;
470
471 ret = line6_start_listen(line6);
472 if (ret < 0) {
473 dev_err(line6->ifcdev, "cannot start listening: %d\n", ret);
474 return ret;
475 }
476
477 return 0;
478}
479
451/* 480/*
452 Probe USB device. 481 Probe USB device.
453*/ 482*/
454int line6_probe(struct usb_interface *interface, 483int line6_probe(struct usb_interface *interface,
455 struct usb_line6 *line6, 484 const struct usb_device_id *id,
456 const struct line6_properties *properties, 485 const struct line6_properties *properties,
457 int (*private_init)(struct usb_interface *, struct usb_line6 *)) 486 int (*private_init)(struct usb_line6 *, const struct usb_device_id *id),
487 size_t data_size)
458{ 488{
459 struct usb_device *usbdev = interface_to_usbdev(interface); 489 struct usb_device *usbdev = interface_to_usbdev(interface);
460 struct snd_card *card; 490 struct snd_card *card;
491 struct usb_line6 *line6;
461 int interface_number; 492 int interface_number;
462 int ret; 493 int ret;
463 494
464 /* we don't handle multiple configurations */ 495 if (WARN_ON(data_size < sizeof(*line6)))
465 if (usbdev->descriptor.bNumConfigurations != 1) { 496 return -EINVAL;
466 ret = -ENODEV;
467 goto err_put;
468 }
469
470 /* initialize device info: */
471 dev_info(&interface->dev, "Line 6 %s found\n", properties->name);
472 497
473 /* query interface number */ 498 /* we don't handle multiple configurations */
474 interface_number = interface->cur_altsetting->desc.bInterfaceNumber; 499 if (usbdev->descriptor.bNumConfigurations != 1)
500 return -ENODEV;
475 501
476 ret = usb_set_interface(usbdev, interface_number, 502 ret = snd_card_new(&interface->dev,
477 properties->altsetting); 503 SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1,
478 if (ret < 0) { 504 THIS_MODULE, data_size, &card);
479 dev_err(&interface->dev, "set_interface failed\n"); 505 if (ret < 0)
480 goto err_put; 506 return ret;
481 }
482 507
483 /* store basic data: */ 508 /* store basic data: */
509 line6 = card->private_data;
510 line6->card = card;
484 line6->properties = properties; 511 line6->properties = properties;
485 line6->usbdev = usbdev; 512 line6->usbdev = usbdev;
486 line6->ifcdev = &interface->dev; 513 line6->ifcdev = &interface->dev;
487 514
488 /* get data from endpoint descriptor (see usb_maxpacket): */ 515 strcpy(card->id, properties->id);
489 {
490 struct usb_host_endpoint *ep;
491 unsigned pipe = usb_rcvintpipe(usbdev, properties->ep_ctrl_r);
492 unsigned epnum = usb_pipeendpoint(pipe);
493 ep = usbdev->ep_in[epnum];
494
495 if (ep != NULL) {
496 line6->interval = ep->desc.bInterval;
497 line6->max_packet_size =
498 le16_to_cpu(ep->desc.wMaxPacketSize);
499 } else {
500 line6->interval = LINE6_FALLBACK_INTERVAL;
501 line6->max_packet_size = LINE6_FALLBACK_MAXPACKETSIZE;
502 dev_err(line6->ifcdev,
503 "endpoint not available, using fallback values");
504 }
505 }
506
507 ret = snd_card_new(line6->ifcdev,
508 SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1,
509 THIS_MODULE, 0, &card);
510 if (ret < 0)
511 goto err_put;
512
513 line6->card = card;
514 strcpy(card->id, line6->properties->id);
515 strcpy(card->driver, DRIVER_NAME); 516 strcpy(card->driver, DRIVER_NAME);
516 strcpy(card->shortname, line6->properties->name); 517 strcpy(card->shortname, properties->name);
517 sprintf(card->longname, "Line 6 %s at USB %s", line6->properties->name, 518 sprintf(card->longname, "Line 6 %s at USB %s", properties->name,
518 dev_name(line6->ifcdev)); 519 dev_name(line6->ifcdev));
519 card->private_data = line6;
520 card->private_free = line6_destruct; 520 card->private_free = line6_destruct;
521 521
522 usb_set_intfdata(interface, line6); 522 usb_set_intfdata(interface, line6);
@@ -524,52 +524,43 @@ int line6_probe(struct usb_interface *interface,
524 /* increment reference counters: */ 524 /* increment reference counters: */
525 usb_get_dev(usbdev); 525 usb_get_dev(usbdev);
526 526
527 if (properties->capabilities & LINE6_CAP_CONTROL) { 527 /* initialize device info: */
528 /* initialize USB buffers: */ 528 dev_info(&interface->dev, "Line 6 %s found\n", properties->name);
529 line6->buffer_listen =
530 kmalloc(LINE6_BUFSIZE_LISTEN, GFP_KERNEL);
531 if (line6->buffer_listen == NULL) {
532 ret = -ENOMEM;
533 goto err_destruct;
534 }
535 529
536 line6->buffer_message = 530 /* query interface number */
537 kmalloc(LINE6_MESSAGE_MAXLEN, GFP_KERNEL); 531 interface_number = interface->cur_altsetting->desc.bInterfaceNumber;
538 if (line6->buffer_message == NULL) {
539 ret = -ENOMEM;
540 goto err_destruct;
541 }
542 532
543 line6->urb_listen = usb_alloc_urb(0, GFP_KERNEL); 533 ret = usb_set_interface(usbdev, interface_number,
534 properties->altsetting);
535 if (ret < 0) {
536 dev_err(&interface->dev, "set_interface failed\n");
537 goto error;
538 }
544 539
545 if (line6->urb_listen == NULL) { 540 line6_get_interval(line6);
546 ret = -ENOMEM;
547 goto err_destruct;
548 }
549 541
550 ret = line6_start_listen(line6); 542 if (properties->capabilities & LINE6_CAP_CONTROL) {
551 if (ret < 0) { 543 ret = line6_init_cap_control(line6);
552 dev_err(&interface->dev, "%s: usb_submit_urb failed\n", 544 if (ret < 0)
553 __func__); 545 goto error;
554 goto err_destruct;
555 }
556 } 546 }
557 547
558 /* initialize device data based on device: */ 548 /* initialize device data based on device: */
559 ret = private_init(interface, line6); 549 ret = private_init(line6, id);
560 if (ret < 0) 550 if (ret < 0)
561 goto err_destruct; 551 goto error;
562 552
563 /* creation of additional special files should go here */ 553 /* creation of additional special files should go here */
564 554
565 dev_info(&interface->dev, "Line 6 %s now attached\n", 555 dev_info(&interface->dev, "Line 6 %s now attached\n",
566 line6->properties->name); 556 properties->name);
567 557
568 return 0; 558 return 0;
569 559
570 err_destruct: 560 error:
561 if (line6->disconnect)
562 line6->disconnect(line6);
571 snd_card_free(card); 563 snd_card_free(card);
572 err_put:
573 return ret; 564 return ret;
574} 565}
575EXPORT_SYMBOL_GPL(line6_probe); 566EXPORT_SYMBOL_GPL(line6_probe);
@@ -579,32 +570,23 @@ EXPORT_SYMBOL_GPL(line6_probe);
579*/ 570*/
580void line6_disconnect(struct usb_interface *interface) 571void line6_disconnect(struct usb_interface *interface)
581{ 572{
582 struct usb_line6 *line6; 573 struct usb_line6 *line6 = usb_get_intfdata(interface);
583 struct usb_device *usbdev; 574 struct usb_device *usbdev = interface_to_usbdev(interface);
584 int interface_number;
585 575
586 if (interface == NULL) 576 if (!line6)
587 return;
588 usbdev = interface_to_usbdev(interface);
589 if (usbdev == NULL)
590 return; 577 return;
591 578
592 interface_number = interface->cur_altsetting->desc.bInterfaceNumber; 579 if (WARN_ON(usbdev != line6->usbdev))
593 line6 = usb_get_intfdata(interface);
594 if (!line6)
595 return; 580 return;
596 581
597 if (line6->urb_listen != NULL) 582 if (line6->urb_listen != NULL)
598 line6_stop_listen(line6); 583 line6_stop_listen(line6);
599 584
600 if (usbdev != line6->usbdev)
601 dev_err(line6->ifcdev, "driver bug: inconsistent usb device\n");
602
603 snd_card_disconnect(line6->card); 585 snd_card_disconnect(line6->card);
604 if (line6->line6pcm) 586 if (line6->line6pcm)
605 line6_pcm_disconnect(line6->line6pcm); 587 line6_pcm_disconnect(line6->line6pcm);
606 if (line6->disconnect) 588 if (line6->disconnect)
607 line6->disconnect(interface); 589 line6->disconnect(line6);
608 590
609 dev_info(&interface->dev, "Line 6 %s now disconnected\n", 591 dev_info(&interface->dev, "Line 6 %s now disconnected\n",
610 line6->properties->name); 592 line6->properties->name);
diff --git a/sound/usb/line6/driver.h b/sound/usb/line6/driver.h
index efd58ac3215b..fce10f12f0d3 100644
--- a/sound/usb/line6/driver.h
+++ b/sound/usb/line6/driver.h
@@ -157,13 +157,11 @@ struct usb_line6 {
157 int message_length; 157 int message_length;
158 158
159 void (*process_message)(struct usb_line6 *); 159 void (*process_message)(struct usb_line6 *);
160 void (*disconnect)(struct usb_interface *); 160 void (*disconnect)(struct usb_line6 *line6);
161}; 161};
162 162
163extern char *line6_alloc_sysex_buffer(struct usb_line6 *line6, int code1, 163extern char *line6_alloc_sysex_buffer(struct usb_line6 *line6, int code1,
164 int code2, int size); 164 int code2, int size);
165extern ssize_t line6_nop_read(struct device *dev,
166 struct device_attribute *attr, char *buf);
167extern int line6_read_data(struct usb_line6 *line6, int address, void *data, 165extern int line6_read_data(struct usb_line6 *line6, int address, void *data,
168 size_t datalen); 166 size_t datalen);
169extern int line6_read_serial_number(struct usb_line6 *line6, 167extern int line6_read_serial_number(struct usb_line6 *line6,
@@ -182,9 +180,11 @@ extern int line6_write_data(struct usb_line6 *line6, int address, void *data,
182 size_t datalen); 180 size_t datalen);
183 181
184int line6_probe(struct usb_interface *interface, 182int line6_probe(struct usb_interface *interface,
185 struct usb_line6 *line6, 183 const struct usb_device_id *id,
186 const struct line6_properties *properties, 184 const struct line6_properties *properties,
187 int (*private_init)(struct usb_interface *, struct usb_line6 *)); 185 int (*private_init)(struct usb_line6 *, const struct usb_device_id *id),
186 size_t data_size);
187
188void line6_disconnect(struct usb_interface *interface); 188void line6_disconnect(struct usb_interface *interface);
189 189
190#ifdef CONFIG_PM 190#ifdef CONFIG_PM
diff --git a/sound/usb/line6/midi.c b/sound/usb/line6/midi.c
index b5a58a7fe11a..beeedf9a2cbe 100644
--- a/sound/usb/line6/midi.c
+++ b/sound/usb/line6/midi.c
@@ -45,12 +45,9 @@ static void line6_midi_transmit(struct snd_rawmidi_substream *substream)
45 line6_rawmidi_substream_midi(substream)->line6; 45 line6_rawmidi_substream_midi(substream)->line6;
46 struct snd_line6_midi *line6midi = line6->line6midi; 46 struct snd_line6_midi *line6midi = line6->line6midi;
47 struct midi_buffer *mb = &line6midi->midibuf_out; 47 struct midi_buffer *mb = &line6midi->midibuf_out;
48 unsigned long flags;
49 unsigned char chunk[LINE6_FALLBACK_MAXPACKETSIZE]; 48 unsigned char chunk[LINE6_FALLBACK_MAXPACKETSIZE];
50 int req, done; 49 int req, done;
51 50
52 spin_lock_irqsave(&line6->line6midi->midi_transmit_lock, flags);
53
54 for (;;) { 51 for (;;) {
55 req = min(line6_midibuf_bytes_free(mb), line6->max_packet_size); 52 req = min(line6_midibuf_bytes_free(mb), line6->max_packet_size);
56 done = snd_rawmidi_transmit_peek(substream, chunk, req); 53 done = snd_rawmidi_transmit_peek(substream, chunk, req);
@@ -71,8 +68,6 @@ static void line6_midi_transmit(struct snd_rawmidi_substream *substream)
71 68
72 send_midi_async(line6, chunk, done); 69 send_midi_async(line6, chunk, done);
73 } 70 }
74
75 spin_unlock_irqrestore(&line6->line6midi->midi_transmit_lock, flags);
76} 71}
77 72
78/* 73/*
@@ -92,7 +87,7 @@ static void midi_sent(struct urb *urb)
92 if (status == -ESHUTDOWN) 87 if (status == -ESHUTDOWN)
93 return; 88 return;
94 89
95 spin_lock_irqsave(&line6->line6midi->send_urb_lock, flags); 90 spin_lock_irqsave(&line6->line6midi->lock, flags);
96 num = --line6->line6midi->num_active_send_urbs; 91 num = --line6->line6midi->num_active_send_urbs;
97 92
98 if (num == 0) { 93 if (num == 0) {
@@ -103,12 +98,12 @@ static void midi_sent(struct urb *urb)
103 if (num == 0) 98 if (num == 0)
104 wake_up(&line6->line6midi->send_wait); 99 wake_up(&line6->line6midi->send_wait);
105 100
106 spin_unlock_irqrestore(&line6->line6midi->send_urb_lock, flags); 101 spin_unlock_irqrestore(&line6->line6midi->lock, flags);
107} 102}
108 103
109/* 104/*
110 Send an asynchronous MIDI message. 105 Send an asynchronous MIDI message.
111 Assumes that line6->line6midi->send_urb_lock is held 106 Assumes that line6->line6midi->lock is held
112 (i.e., this function is serialized). 107 (i.e., this function is serialized).
113*/ 108*/
114static int send_midi_async(struct usb_line6 *line6, unsigned char *data, 109static int send_midi_async(struct usb_line6 *line6, unsigned char *data,
@@ -166,12 +161,12 @@ static void line6_midi_output_trigger(struct snd_rawmidi_substream *substream,
166 line6_rawmidi_substream_midi(substream)->line6; 161 line6_rawmidi_substream_midi(substream)->line6;
167 162
168 line6->line6midi->substream_transmit = substream; 163 line6->line6midi->substream_transmit = substream;
169 spin_lock_irqsave(&line6->line6midi->send_urb_lock, flags); 164 spin_lock_irqsave(&line6->line6midi->lock, flags);
170 165
171 if (line6->line6midi->num_active_send_urbs == 0) 166 if (line6->line6midi->num_active_send_urbs == 0)
172 line6_midi_transmit(substream); 167 line6_midi_transmit(substream);
173 168
174 spin_unlock_irqrestore(&line6->line6midi->send_urb_lock, flags); 169 spin_unlock_irqrestore(&line6->line6midi->lock, flags);
175} 170}
176 171
177static void line6_midi_output_drain(struct snd_rawmidi_substream *substream) 172static void line6_midi_output_drain(struct snd_rawmidi_substream *substream)
@@ -281,8 +276,7 @@ int line6_init_midi(struct usb_line6 *line6)
281 rmidi->private_free = snd_line6_midi_free; 276 rmidi->private_free = snd_line6_midi_free;
282 277
283 init_waitqueue_head(&line6midi->send_wait); 278 init_waitqueue_head(&line6midi->send_wait);
284 spin_lock_init(&line6midi->send_urb_lock); 279 spin_lock_init(&line6midi->lock);
285 spin_lock_init(&line6midi->midi_transmit_lock);
286 line6midi->line6 = line6; 280 line6midi->line6 = line6;
287 281
288 err = line6_midibuf_init(&line6midi->midibuf_in, MIDI_BUFFER_SIZE, 0); 282 err = line6_midibuf_init(&line6midi->midibuf_in, MIDI_BUFFER_SIZE, 0);
diff --git a/sound/usb/line6/midi.h b/sound/usb/line6/midi.h
index ba6bf3828aa5..9d9467b2613c 100644
--- a/sound/usb/line6/midi.h
+++ b/sound/usb/line6/midi.h
@@ -40,14 +40,9 @@ struct snd_line6_midi {
40 int num_active_send_urbs; 40 int num_active_send_urbs;
41 41
42 /** 42 /**
43 Spin lock to protect updates of send_urb.
44 */
45 spinlock_t send_urb_lock;
46
47 /**
48 Spin lock to protect MIDI buffer handling. 43 Spin lock to protect MIDI buffer handling.
49 */ 44 */
50 spinlock_t midi_transmit_lock; 45 spinlock_t lock;
51 46
52 /** 47 /**
53 Wait queue for MIDI transmission. 48 Wait queue for MIDI transmission.
diff --git a/sound/usb/line6/pcm.c b/sound/usb/line6/pcm.c
index 8a6059adef69..8461d6bf992f 100644
--- a/sound/usb/line6/pcm.c
+++ b/sound/usb/line6/pcm.c
@@ -45,15 +45,22 @@ static int snd_line6_impulse_volume_put(struct snd_kcontrol *kcontrol,
45{ 45{
46 struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol); 46 struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol);
47 int value = ucontrol->value.integer.value[0]; 47 int value = ucontrol->value.integer.value[0];
48 int err;
48 49
49 if (line6pcm->impulse_volume == value) 50 if (line6pcm->impulse_volume == value)
50 return 0; 51 return 0;
51 52
52 line6pcm->impulse_volume = value; 53 line6pcm->impulse_volume = value;
53 if (value > 0) 54 if (value > 0) {
54 line6_pcm_acquire(line6pcm, LINE6_BITS_PCM_IMPULSE); 55 err = line6_pcm_acquire(line6pcm, LINE6_STREAM_IMPULSE);
55 else 56 if (err < 0) {
56 line6_pcm_release(line6pcm, LINE6_BITS_PCM_IMPULSE); 57 line6pcm->impulse_volume = 0;
58 line6_pcm_release(line6pcm, LINE6_STREAM_IMPULSE);
59 return err;
60 }
61 } else {
62 line6_pcm_release(line6pcm, LINE6_STREAM_IMPULSE);
63 }
57 return 1; 64 return 1;
58} 65}
59 66
@@ -90,180 +97,277 @@ static int snd_line6_impulse_period_put(struct snd_kcontrol *kcontrol,
90 return 1; 97 return 1;
91} 98}
92 99
93static bool test_flags(unsigned long flags0, unsigned long flags1, 100/*
94 unsigned long mask) 101 Unlink all currently active URBs.
95{ 102*/
96 return ((flags0 & mask) == 0) && ((flags1 & mask) != 0); 103static void line6_unlink_audio_urbs(struct snd_line6_pcm *line6pcm,
97} 104 struct line6_pcm_stream *pcms)
98
99int line6_pcm_acquire(struct snd_line6_pcm *line6pcm, int channels)
100{ 105{
101 unsigned long flags_old, flags_new, flags_final; 106 int i;
102 int err;
103
104 do {
105 flags_old = ACCESS_ONCE(line6pcm->flags);
106 flags_new = flags_old | channels;
107 } while (cmpxchg(&line6pcm->flags, flags_old, flags_new) != flags_old);
108
109 flags_final = flags_old;
110
111 line6pcm->prev_fbuf = NULL;
112
113 if (test_flags(flags_old, flags_new, LINE6_BITS_CAPTURE_BUFFER)) {
114 /* Invoked multiple times in a row so allocate once only */
115 if (!line6pcm->buffer_in) {
116 line6pcm->buffer_in =
117 kmalloc(LINE6_ISO_BUFFERS * LINE6_ISO_PACKETS *
118 line6pcm->max_packet_size, GFP_KERNEL);
119 if (!line6pcm->buffer_in) {
120 err = -ENOMEM;
121 goto pcm_acquire_error;
122 }
123
124 flags_final |= channels & LINE6_BITS_CAPTURE_BUFFER;
125 }
126 }
127 107
128 if (test_flags(flags_old, flags_new, LINE6_BITS_CAPTURE_STREAM)) { 108 for (i = 0; i < LINE6_ISO_BUFFERS; i++) {
129 /* 109 if (test_bit(i, &pcms->active_urbs)) {
130 Waiting for completion of active URBs in the stop handler is 110 if (!test_and_set_bit(i, &pcms->unlink_urbs))
131 a bug, we therefore report an error if capturing is restarted 111 usb_unlink_urb(pcms->urbs[i]);
132 too soon.
133 */
134 if (line6pcm->active_urb_in | line6pcm->unlink_urb_in) {
135 dev_err(line6pcm->line6->ifcdev, "Device not yet ready\n");
136 return -EBUSY;
137 } 112 }
138
139 line6pcm->count_in = 0;
140 line6pcm->prev_fsize = 0;
141 err = line6_submit_audio_in_all_urbs(line6pcm);
142
143 if (err < 0)
144 goto pcm_acquire_error;
145
146 flags_final |= channels & LINE6_BITS_CAPTURE_STREAM;
147 } 113 }
114}
148 115
149 if (test_flags(flags_old, flags_new, LINE6_BITS_PLAYBACK_BUFFER)) { 116/*
150 /* Invoked multiple times in a row so allocate once only */ 117 Wait until unlinking of all currently active URBs has been finished.
151 if (!line6pcm->buffer_out) { 118*/
152 line6pcm->buffer_out = 119static void line6_wait_clear_audio_urbs(struct snd_line6_pcm *line6pcm,
153 kmalloc(LINE6_ISO_BUFFERS * LINE6_ISO_PACKETS * 120 struct line6_pcm_stream *pcms)
154 line6pcm->max_packet_size, GFP_KERNEL); 121{
155 if (!line6pcm->buffer_out) { 122 int timeout = HZ;
156 err = -ENOMEM; 123 int i;
157 goto pcm_acquire_error; 124 int alive;
158 }
159
160 flags_final |= channels & LINE6_BITS_PLAYBACK_BUFFER;
161 }
162 }
163 125
164 if (test_flags(flags_old, flags_new, LINE6_BITS_PLAYBACK_STREAM)) { 126 do {
165 /* 127 alive = 0;
166 See comment above regarding PCM restart. 128 for (i = 0; i < LINE6_ISO_BUFFERS; i++) {
167 */ 129 if (test_bit(i, &pcms->active_urbs))
168 if (line6pcm->active_urb_out | line6pcm->unlink_urb_out) { 130 alive++;
169 dev_err(line6pcm->line6->ifcdev, "Device not yet ready\n");
170 return -EBUSY;
171 } 131 }
132 if (!alive)
133 break;
134 set_current_state(TASK_UNINTERRUPTIBLE);
135 schedule_timeout(1);
136 } while (--timeout > 0);
137 if (alive)
138 dev_err(line6pcm->line6->ifcdev,
139 "timeout: still %d active urbs..\n", alive);
140}
172 141
173 line6pcm->count_out = 0; 142static inline struct line6_pcm_stream *
174 err = line6_submit_audio_out_all_urbs(line6pcm); 143get_stream(struct snd_line6_pcm *line6pcm, int direction)
175 144{
176 if (err < 0) 145 return (direction == SNDRV_PCM_STREAM_PLAYBACK) ?
177 goto pcm_acquire_error; 146 &line6pcm->out : &line6pcm->in;
147}
178 148
179 flags_final |= channels & LINE6_BITS_PLAYBACK_STREAM; 149/* allocate a buffer if not opened yet;
150 * call this in line6pcm.state_change mutex
151 */
152static int line6_buffer_acquire(struct snd_line6_pcm *line6pcm,
153 struct line6_pcm_stream *pstr, int type)
154{
155 /* Invoked multiple times in a row so allocate once only */
156 if (!test_and_set_bit(type, &pstr->opened) && !pstr->buffer) {
157 pstr->buffer = kmalloc(LINE6_ISO_BUFFERS * LINE6_ISO_PACKETS *
158 line6pcm->max_packet_size, GFP_KERNEL);
159 if (!pstr->buffer)
160 return -ENOMEM;
180 } 161 }
181
182 return 0; 162 return 0;
183
184pcm_acquire_error:
185 /*
186 If not all requested resources/streams could be obtained, release
187 those which were successfully obtained (if any).
188 */
189 line6_pcm_release(line6pcm, flags_final & channels);
190 return err;
191} 163}
192EXPORT_SYMBOL_GPL(line6_pcm_acquire);
193 164
194int line6_pcm_release(struct snd_line6_pcm *line6pcm, int channels) 165/* free a buffer if all streams are closed;
166 * call this in line6pcm.state_change mutex
167 */
168static void line6_buffer_release(struct snd_line6_pcm *line6pcm,
169 struct line6_pcm_stream *pstr, int type)
195{ 170{
196 unsigned long flags_old, flags_new;
197
198 do {
199 flags_old = ACCESS_ONCE(line6pcm->flags);
200 flags_new = flags_old & ~channels;
201 } while (cmpxchg(&line6pcm->flags, flags_old, flags_new) != flags_old);
202 171
203 if (test_flags(flags_new, flags_old, LINE6_BITS_CAPTURE_STREAM)) 172 clear_bit(type, &pstr->opened);
204 line6_unlink_audio_in_urbs(line6pcm); 173 if (!pstr->opened) {
205 174 line6_wait_clear_audio_urbs(line6pcm, pstr);
206 if (test_flags(flags_new, flags_old, LINE6_BITS_CAPTURE_BUFFER)) { 175 kfree(pstr->buffer);
207 line6_wait_clear_audio_in_urbs(line6pcm); 176 pstr->buffer = NULL;
208 line6_free_capture_buffer(line6pcm);
209 } 177 }
178}
210 179
211 if (test_flags(flags_new, flags_old, LINE6_BITS_PLAYBACK_STREAM)) 180/* start a PCM stream */
212 line6_unlink_audio_out_urbs(line6pcm); 181static int line6_stream_start(struct snd_line6_pcm *line6pcm, int direction,
182 int type)
183{
184 unsigned long flags;
185 struct line6_pcm_stream *pstr = get_stream(line6pcm, direction);
186 int ret = 0;
187
188 spin_lock_irqsave(&pstr->lock, flags);
189 if (!test_and_set_bit(type, &pstr->running)) {
190 if (pstr->active_urbs || pstr->unlink_urbs) {
191 ret = -EBUSY;
192 goto error;
193 }
213 194
214 if (test_flags(flags_new, flags_old, LINE6_BITS_PLAYBACK_BUFFER)) { 195 pstr->count = 0;
215 line6_wait_clear_audio_out_urbs(line6pcm); 196 /* Submit all currently available URBs */
216 line6_free_playback_buffer(line6pcm); 197 if (direction == SNDRV_PCM_STREAM_PLAYBACK)
198 ret = line6_submit_audio_out_all_urbs(line6pcm);
199 else
200 ret = line6_submit_audio_in_all_urbs(line6pcm);
217 } 201 }
202 error:
203 if (ret < 0)
204 clear_bit(type, &pstr->running);
205 spin_unlock_irqrestore(&pstr->lock, flags);
206 return ret;
207}
218 208
219 return 0; 209/* stop a PCM stream; this doesn't sync with the unlinked URBs */
210static void line6_stream_stop(struct snd_line6_pcm *line6pcm, int direction,
211 int type)
212{
213 unsigned long flags;
214 struct line6_pcm_stream *pstr = get_stream(line6pcm, direction);
215
216 spin_lock_irqsave(&pstr->lock, flags);
217 clear_bit(type, &pstr->running);
218 if (!pstr->running) {
219 line6_unlink_audio_urbs(line6pcm, pstr);
220 if (direction == SNDRV_PCM_STREAM_CAPTURE) {
221 line6pcm->prev_fbuf = NULL;
222 line6pcm->prev_fsize = 0;
223 }
224 }
225 spin_unlock_irqrestore(&pstr->lock, flags);
220} 226}
221EXPORT_SYMBOL_GPL(line6_pcm_release);
222 227
223/* trigger callback */ 228/* common PCM trigger callback */
224int snd_line6_trigger(struct snd_pcm_substream *substream, int cmd) 229int snd_line6_trigger(struct snd_pcm_substream *substream, int cmd)
225{ 230{
226 struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream); 231 struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
227 struct snd_pcm_substream *s; 232 struct snd_pcm_substream *s;
228 int err; 233 int err;
229 234
230 spin_lock(&line6pcm->lock_trigger); 235 clear_bit(LINE6_FLAG_PREPARED, &line6pcm->flags);
231 clear_bit(LINE6_INDEX_PREPARED, &line6pcm->flags);
232 236
233 snd_pcm_group_for_each_entry(s, substream) { 237 snd_pcm_group_for_each_entry(s, substream) {
234 if (s->pcm->card != substream->pcm->card) 238 if (s->pcm->card != substream->pcm->card)
235 continue; 239 continue;
236 switch (s->stream) {
237 case SNDRV_PCM_STREAM_PLAYBACK:
238 err = snd_line6_playback_trigger(line6pcm, cmd);
239 240
240 if (err < 0) { 241 switch (cmd) {
241 spin_unlock(&line6pcm->lock_trigger); 242 case SNDRV_PCM_TRIGGER_START:
243 case SNDRV_PCM_TRIGGER_RESUME:
244 err = line6_stream_start(line6pcm, s->stream,
245 LINE6_STREAM_PCM);
246 if (err < 0)
242 return err; 247 return err;
243 }
244
245 break; 248 break;
246 249
247 case SNDRV_PCM_STREAM_CAPTURE: 250 case SNDRV_PCM_TRIGGER_STOP:
248 err = snd_line6_capture_trigger(line6pcm, cmd); 251 case SNDRV_PCM_TRIGGER_SUSPEND:
252 line6_stream_stop(line6pcm, s->stream,
253 LINE6_STREAM_PCM);
254 break;
249 255
250 if (err < 0) { 256 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
251 spin_unlock(&line6pcm->lock_trigger); 257 if (s->stream != SNDRV_PCM_STREAM_PLAYBACK)
252 return err; 258 return -EINVAL;
253 } 259 set_bit(LINE6_FLAG_PAUSE_PLAYBACK, &line6pcm->flags);
260 break;
254 261
262 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
263 if (s->stream != SNDRV_PCM_STREAM_PLAYBACK)
264 return -EINVAL;
265 clear_bit(LINE6_FLAG_PAUSE_PLAYBACK, &line6pcm->flags);
255 break; 266 break;
256 267
257 default: 268 default:
258 dev_err(line6pcm->line6->ifcdev, 269 return -EINVAL;
259 "Unknown stream direction %d\n", s->stream);
260 } 270 }
261 } 271 }
262 272
263 spin_unlock(&line6pcm->lock_trigger);
264 return 0; 273 return 0;
265} 274}
266 275
276/* common PCM pointer callback */
277snd_pcm_uframes_t snd_line6_pointer(struct snd_pcm_substream *substream)
278{
279 struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
280 struct line6_pcm_stream *pstr = get_stream(line6pcm, substream->stream);
281
282 return pstr->pos_done;
283}
284
285/* Acquire and start duplex streams:
286 * type is either LINE6_STREAM_IMPULSE or LINE6_STREAM_MONITOR
287 */
288int line6_pcm_acquire(struct snd_line6_pcm *line6pcm, int type)
289{
290 struct line6_pcm_stream *pstr;
291 int ret = 0, dir;
292
293 mutex_lock(&line6pcm->state_mutex);
294 for (dir = 0; dir < 2; dir++) {
295 pstr = get_stream(line6pcm, dir);
296 ret = line6_buffer_acquire(line6pcm, pstr, type);
297 if (ret < 0)
298 goto error;
299 if (!pstr->running)
300 line6_wait_clear_audio_urbs(line6pcm, pstr);
301 }
302 for (dir = 0; dir < 2; dir++) {
303 ret = line6_stream_start(line6pcm, dir, type);
304 if (ret < 0)
305 goto error;
306 }
307 error:
308 mutex_unlock(&line6pcm->state_mutex);
309 if (ret < 0)
310 line6_pcm_release(line6pcm, type);
311 return ret;
312}
313EXPORT_SYMBOL_GPL(line6_pcm_acquire);
314
315/* Stop and release duplex streams */
316void line6_pcm_release(struct snd_line6_pcm *line6pcm, int type)
317{
318 struct line6_pcm_stream *pstr;
319 int dir;
320
321 mutex_lock(&line6pcm->state_mutex);
322 for (dir = 0; dir < 2; dir++)
323 line6_stream_stop(line6pcm, dir, type);
324 for (dir = 0; dir < 2; dir++) {
325 pstr = get_stream(line6pcm, dir);
326 line6_buffer_release(line6pcm, pstr, type);
327 }
328 mutex_unlock(&line6pcm->state_mutex);
329}
330EXPORT_SYMBOL_GPL(line6_pcm_release);
331
332/* common PCM hw_params callback */
333int snd_line6_hw_params(struct snd_pcm_substream *substream,
334 struct snd_pcm_hw_params *hw_params)
335{
336 int ret;
337 struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
338 struct line6_pcm_stream *pstr = get_stream(line6pcm, substream->stream);
339
340 mutex_lock(&line6pcm->state_mutex);
341 ret = line6_buffer_acquire(line6pcm, pstr, LINE6_STREAM_PCM);
342 if (ret < 0)
343 goto error;
344
345 ret = snd_pcm_lib_malloc_pages(substream,
346 params_buffer_bytes(hw_params));
347 if (ret < 0) {
348 line6_buffer_release(line6pcm, pstr, LINE6_STREAM_PCM);
349 goto error;
350 }
351
352 pstr->period = params_period_bytes(hw_params);
353 error:
354 mutex_unlock(&line6pcm->state_mutex);
355 return ret;
356}
357
358/* common PCM hw_free callback */
359int snd_line6_hw_free(struct snd_pcm_substream *substream)
360{
361 struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
362 struct line6_pcm_stream *pstr = get_stream(line6pcm, substream->stream);
363
364 mutex_lock(&line6pcm->state_mutex);
365 line6_buffer_release(line6pcm, pstr, LINE6_STREAM_PCM);
366 mutex_unlock(&line6pcm->state_mutex);
367 return snd_pcm_lib_free_pages(substream);
368}
369
370
267/* control info callback */ 371/* control info callback */
268static int snd_line6_control_playback_info(struct snd_kcontrol *kcontrol, 372static int snd_line6_control_playback_info(struct snd_kcontrol *kcontrol,
269 struct snd_ctl_elem_info *uinfo) 373 struct snd_ctl_elem_info *uinfo)
@@ -282,7 +386,7 @@ static int snd_line6_control_playback_get(struct snd_kcontrol *kcontrol,
282 int i; 386 int i;
283 struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol); 387 struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol);
284 388
285 for (i = 2; i--;) 389 for (i = 0; i < 2; i++)
286 ucontrol->value.integer.value[i] = line6pcm->volume_playback[i]; 390 ucontrol->value.integer.value[i] = line6pcm->volume_playback[i];
287 391
288 return 0; 392 return 0;
@@ -295,7 +399,7 @@ static int snd_line6_control_playback_put(struct snd_kcontrol *kcontrol,
295 int i, changed = 0; 399 int i, changed = 0;
296 struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol); 400 struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol);
297 401
298 for (i = 2; i--;) 402 for (i = 0; i < 2; i++)
299 if (line6pcm->volume_playback[i] != 403 if (line6pcm->volume_playback[i] !=
300 ucontrol->value.integer.value[i]) { 404 ucontrol->value.integer.value[i]) {
301 line6pcm->volume_playback[i] = 405 line6pcm->volume_playback[i] =
@@ -334,21 +438,24 @@ static struct snd_kcontrol_new line6_controls[] = {
334/* 438/*
335 Cleanup the PCM device. 439 Cleanup the PCM device.
336*/ 440*/
337static void line6_cleanup_pcm(struct snd_pcm *pcm) 441static void cleanup_urbs(struct line6_pcm_stream *pcms)
338{ 442{
339 int i; 443 int i;
340 struct snd_line6_pcm *line6pcm = snd_pcm_chip(pcm);
341 444
342 for (i = LINE6_ISO_BUFFERS; i--;) { 445 for (i = 0; i < LINE6_ISO_BUFFERS; i++) {
343 if (line6pcm->urb_audio_out[i]) { 446 if (pcms->urbs[i]) {
344 usb_kill_urb(line6pcm->urb_audio_out[i]); 447 usb_kill_urb(pcms->urbs[i]);
345 usb_free_urb(line6pcm->urb_audio_out[i]); 448 usb_free_urb(pcms->urbs[i]);
346 }
347 if (line6pcm->urb_audio_in[i]) {
348 usb_kill_urb(line6pcm->urb_audio_in[i]);
349 usb_free_urb(line6pcm->urb_audio_in[i]);
350 } 449 }
351 } 450 }
451}
452
453static void line6_cleanup_pcm(struct snd_pcm *pcm)
454{
455 struct snd_line6_pcm *line6pcm = snd_pcm_chip(pcm);
456
457 cleanup_urbs(&line6pcm->out);
458 cleanup_urbs(&line6pcm->in);
352 kfree(line6pcm); 459 kfree(line6pcm);
353} 460}
354 461
@@ -383,8 +490,10 @@ static int snd_line6_new_pcm(struct usb_line6 *line6, struct snd_pcm **pcm_ret)
383*/ 490*/
384void line6_pcm_disconnect(struct snd_line6_pcm *line6pcm) 491void line6_pcm_disconnect(struct snd_line6_pcm *line6pcm)
385{ 492{
386 line6_unlink_wait_clear_audio_out_urbs(line6pcm); 493 line6_unlink_audio_urbs(line6pcm, &line6pcm->out);
387 line6_unlink_wait_clear_audio_in_urbs(line6pcm); 494 line6_unlink_audio_urbs(line6pcm, &line6pcm->in);
495 line6_wait_clear_audio_urbs(line6pcm, &line6pcm->out);
496 line6_wait_clear_audio_urbs(line6pcm, &line6pcm->in);
388} 497}
389 498
390/* 499/*
@@ -411,6 +520,7 @@ int line6_init_pcm(struct usb_line6 *line6,
411 if (!line6pcm) 520 if (!line6pcm)
412 return -ENOMEM; 521 return -ENOMEM;
413 522
523 mutex_init(&line6pcm->state_mutex);
414 line6pcm->pcm = pcm; 524 line6pcm->pcm = pcm;
415 line6pcm->properties = properties; 525 line6pcm->properties = properties;
416 line6pcm->volume_playback[0] = line6pcm->volume_playback[1] = 255; 526 line6pcm->volume_playback[0] = line6pcm->volume_playback[1] = 255;
@@ -424,9 +534,8 @@ int line6_init_pcm(struct usb_line6 *line6,
424 usb_maxpacket(line6->usbdev, 534 usb_maxpacket(line6->usbdev,
425 usb_sndisocpipe(line6->usbdev, ep_write), 1)); 535 usb_sndisocpipe(line6->usbdev, ep_write), 1));
426 536
427 spin_lock_init(&line6pcm->lock_audio_out); 537 spin_lock_init(&line6pcm->out.lock);
428 spin_lock_init(&line6pcm->lock_audio_in); 538 spin_lock_init(&line6pcm->in.lock);
429 spin_lock_init(&line6pcm->lock_trigger);
430 line6pcm->impulse_period = LINE6_IMPULSE_DEFAULT_PERIOD; 539 line6pcm->impulse_period = LINE6_IMPULSE_DEFAULT_PERIOD;
431 540
432 line6->line6pcm = line6pcm; 541 line6->line6pcm = line6pcm;
@@ -458,30 +567,22 @@ EXPORT_SYMBOL_GPL(line6_init_pcm);
458int snd_line6_prepare(struct snd_pcm_substream *substream) 567int snd_line6_prepare(struct snd_pcm_substream *substream)
459{ 568{
460 struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream); 569 struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
461 570 struct line6_pcm_stream *pstr = get_stream(line6pcm, substream->stream);
462 switch (substream->stream) { 571
463 case SNDRV_PCM_STREAM_PLAYBACK: 572 mutex_lock(&line6pcm->state_mutex);
464 if ((line6pcm->flags & LINE6_BITS_PLAYBACK_STREAM) == 0) 573 if (!pstr->running)
465 line6_unlink_wait_clear_audio_out_urbs(line6pcm); 574 line6_wait_clear_audio_urbs(line6pcm, pstr);
466 575
467 break; 576 if (!test_and_set_bit(LINE6_FLAG_PREPARED, &line6pcm->flags)) {
468 577 line6pcm->out.count = 0;
469 case SNDRV_PCM_STREAM_CAPTURE: 578 line6pcm->out.pos = 0;
470 if ((line6pcm->flags & LINE6_BITS_CAPTURE_STREAM) == 0) 579 line6pcm->out.pos_done = 0;
471 line6_unlink_wait_clear_audio_in_urbs(line6pcm); 580 line6pcm->out.bytes = 0;
472 581 line6pcm->in.count = 0;
473 break; 582 line6pcm->in.pos_done = 0;
474 } 583 line6pcm->in.bytes = 0;
475
476 if (!test_and_set_bit(LINE6_INDEX_PREPARED, &line6pcm->flags)) {
477 line6pcm->count_out = 0;
478 line6pcm->pos_out = 0;
479 line6pcm->pos_out_done = 0;
480 line6pcm->bytes_out = 0;
481 line6pcm->count_in = 0;
482 line6pcm->pos_in_done = 0;
483 line6pcm->bytes_in = 0;
484 } 584 }
485 585
586 mutex_unlock(&line6pcm->state_mutex);
486 return 0; 587 return 0;
487} 588}
diff --git a/sound/usb/line6/pcm.h b/sound/usb/line6/pcm.h
index c742b33666eb..42d3e6fc2c61 100644
--- a/sound/usb/line6/pcm.h
+++ b/sound/usb/line6/pcm.h
@@ -54,109 +54,33 @@
54 However, from the device's point of view, there is just a single 54 However, from the device's point of view, there is just a single
55 capture and playback stream, which must be shared between these 55 capture and playback stream, which must be shared between these
56 subsystems. It is therefore necessary to maintain the state of the 56 subsystems. It is therefore necessary to maintain the state of the
57 subsystems with respect to PCM usage. We define several constants of 57 subsystems with respect to PCM usage.
58 the form LINE6_BIT_PCM_<subsystem>_<direction>_<resource> with the 58
59 following meanings: 59 We define two bit flags, "opened" and "running", for each playback
60 *) <subsystem> is one of 60 or capture stream. Both can contain the bit flag corresponding to
61 -) ALSA: PCM playback and capture via ALSA 61 LINE6_STREAM_* type,
62 -) MONITOR: software monitoring 62 LINE6_STREAM_PCM = ALSA PCM playback or capture
63 -) IMPULSE: optional impulse response measurement 63 LINE6_STREAM_MONITOR = software monitoring
64 *) <direction> is one of 64 IMPULSE = optional impulse response measurement
65 -) PLAYBACK: audio output (from host to device) 65 The opened flag indicates whether the buffer is allocated while
66 -) CAPTURE: audio input (from device to host) 66 the running flag indicates whether the stream is running.
67 *) <resource> is one of 67
68 -) BUFFER: buffer required by PCM data stream 68 For monitor or impulse operations, the driver needs to call
69 -) STREAM: actual PCM data stream 69 snd_line6_duplex_acquire() or snd_line6_duplex_release() with the
70 70 appropriate LINE6_STREAM_* flag.
71 The subsystems call line6_pcm_acquire() to acquire the (shared)
72 resources needed for a particular operation (e.g., allocate the buffer
73 for ALSA playback or start the capture stream for software monitoring).
74 When a resource is no longer needed, it is released by calling
75 line6_pcm_release(). Buffer allocation and stream startup are handled
76 separately to allow the ALSA kernel driver to perform them at
77 appropriate places (since the callback which starts a PCM stream is not
78 allowed to sleep).
79*/ 71*/
72
73/* stream types */
80enum { 74enum {
81 /* individual bit indices: */ 75 LINE6_STREAM_PCM,
82 LINE6_INDEX_PCM_ALSA_PLAYBACK_BUFFER, 76 LINE6_STREAM_MONITOR,
83 LINE6_INDEX_PCM_ALSA_PLAYBACK_STREAM, 77 LINE6_STREAM_IMPULSE,
84 LINE6_INDEX_PCM_ALSA_CAPTURE_BUFFER, 78};
85 LINE6_INDEX_PCM_ALSA_CAPTURE_STREAM, 79
86 LINE6_INDEX_PCM_MONITOR_PLAYBACK_BUFFER, 80/* misc bit flags for PCM operation */
87 LINE6_INDEX_PCM_MONITOR_PLAYBACK_STREAM, 81enum {
88 LINE6_INDEX_PCM_MONITOR_CAPTURE_BUFFER, 82 LINE6_FLAG_PAUSE_PLAYBACK,
89 LINE6_INDEX_PCM_MONITOR_CAPTURE_STREAM, 83 LINE6_FLAG_PREPARED,
90 LINE6_INDEX_PCM_IMPULSE_PLAYBACK_BUFFER,
91 LINE6_INDEX_PCM_IMPULSE_PLAYBACK_STREAM,
92 LINE6_INDEX_PCM_IMPULSE_CAPTURE_BUFFER,
93 LINE6_INDEX_PCM_IMPULSE_CAPTURE_STREAM,
94 LINE6_INDEX_PAUSE_PLAYBACK,
95 LINE6_INDEX_PREPARED,
96
97#define LINE6_BIT(x) LINE6_BIT_ ## x = 1 << LINE6_INDEX_ ## x
98
99 /* individual bit masks: */
100 LINE6_BIT(PCM_ALSA_PLAYBACK_BUFFER),
101 LINE6_BIT(PCM_ALSA_PLAYBACK_STREAM),
102 LINE6_BIT(PCM_ALSA_CAPTURE_BUFFER),
103 LINE6_BIT(PCM_ALSA_CAPTURE_STREAM),
104 LINE6_BIT(PCM_MONITOR_PLAYBACK_BUFFER),
105 LINE6_BIT(PCM_MONITOR_PLAYBACK_STREAM),
106 LINE6_BIT(PCM_MONITOR_CAPTURE_BUFFER),
107 LINE6_BIT(PCM_MONITOR_CAPTURE_STREAM),
108 LINE6_BIT(PCM_IMPULSE_PLAYBACK_BUFFER),
109 LINE6_BIT(PCM_IMPULSE_PLAYBACK_STREAM),
110 LINE6_BIT(PCM_IMPULSE_CAPTURE_BUFFER),
111 LINE6_BIT(PCM_IMPULSE_CAPTURE_STREAM),
112 LINE6_BIT(PAUSE_PLAYBACK),
113 LINE6_BIT(PREPARED),
114
115 /* combined bit masks (by operation): */
116 LINE6_BITS_PCM_ALSA_BUFFER =
117 LINE6_BIT_PCM_ALSA_PLAYBACK_BUFFER |
118 LINE6_BIT_PCM_ALSA_CAPTURE_BUFFER,
119
120 LINE6_BITS_PCM_ALSA_STREAM =
121 LINE6_BIT_PCM_ALSA_PLAYBACK_STREAM |
122 LINE6_BIT_PCM_ALSA_CAPTURE_STREAM,
123
124 LINE6_BITS_PCM_MONITOR =
125 LINE6_BIT_PCM_MONITOR_PLAYBACK_BUFFER |
126 LINE6_BIT_PCM_MONITOR_PLAYBACK_STREAM |
127 LINE6_BIT_PCM_MONITOR_CAPTURE_BUFFER |
128 LINE6_BIT_PCM_MONITOR_CAPTURE_STREAM,
129
130 LINE6_BITS_PCM_IMPULSE =
131 LINE6_BIT_PCM_IMPULSE_PLAYBACK_BUFFER |
132 LINE6_BIT_PCM_IMPULSE_PLAYBACK_STREAM |
133 LINE6_BIT_PCM_IMPULSE_CAPTURE_BUFFER |
134 LINE6_BIT_PCM_IMPULSE_CAPTURE_STREAM,
135
136 /* combined bit masks (by direction): */
137 LINE6_BITS_PLAYBACK_BUFFER =
138 LINE6_BIT_PCM_IMPULSE_PLAYBACK_BUFFER |
139 LINE6_BIT_PCM_ALSA_PLAYBACK_BUFFER |
140 LINE6_BIT_PCM_MONITOR_PLAYBACK_BUFFER,
141
142 LINE6_BITS_PLAYBACK_STREAM =
143 LINE6_BIT_PCM_IMPULSE_PLAYBACK_STREAM |
144 LINE6_BIT_PCM_ALSA_PLAYBACK_STREAM |
145 LINE6_BIT_PCM_MONITOR_PLAYBACK_STREAM,
146
147 LINE6_BITS_CAPTURE_BUFFER =
148 LINE6_BIT_PCM_IMPULSE_CAPTURE_BUFFER |
149 LINE6_BIT_PCM_ALSA_CAPTURE_BUFFER |
150 LINE6_BIT_PCM_MONITOR_CAPTURE_BUFFER,
151
152 LINE6_BITS_CAPTURE_STREAM =
153 LINE6_BIT_PCM_IMPULSE_CAPTURE_STREAM |
154 LINE6_BIT_PCM_ALSA_CAPTURE_STREAM |
155 LINE6_BIT_PCM_MONITOR_CAPTURE_STREAM,
156
157 LINE6_BITS_STREAM =
158 LINE6_BITS_PLAYBACK_STREAM |
159 LINE6_BITS_CAPTURE_STREAM
160}; 84};
161 85
162struct line6_pcm_properties { 86struct line6_pcm_properties {
@@ -165,115 +89,87 @@ struct line6_pcm_properties {
165 int bytes_per_frame; 89 int bytes_per_frame;
166}; 90};
167 91
168struct snd_line6_pcm { 92struct line6_pcm_stream {
169 /** 93 /* allocated URBs */
170 Pointer back to the Line 6 driver data structure. 94 struct urb *urbs[LINE6_ISO_BUFFERS];
171 */
172 struct usb_line6 *line6;
173 95
174 /** 96 /* Temporary buffer;
175 Properties. 97 * Since the packet size is not known in advance, this buffer is
176 */ 98 * large enough to store maximum size packets.
177 struct line6_pcm_properties *properties; 99 */
100 unsigned char *buffer;
178 101
179 /** 102 /* Free frame position in the buffer. */
180 ALSA pcm stream 103 snd_pcm_uframes_t pos;
181 */
182 struct snd_pcm *pcm;
183 104
184 /** 105 /* Count processed bytes;
185 URBs for audio playback. 106 * This is modulo period size (to determine when a period is finished).
186 */ 107 */
187 struct urb *urb_audio_out[LINE6_ISO_BUFFERS]; 108 unsigned bytes;
188 109
189 /** 110 /* Counter to create desired sample rate */
190 URBs for audio capture. 111 unsigned count;
191 */
192 struct urb *urb_audio_in[LINE6_ISO_BUFFERS];
193 112
194 /** 113 /* period size in bytes */
195 Temporary buffer for playback. 114 unsigned period;
196 Since the packet size is not known in advance, this buffer is
197 large enough to store maximum size packets.
198 */
199 unsigned char *buffer_out;
200 115
201 /** 116 /* Processed frame position in the buffer;
202 Temporary buffer for capture. 117 * The contents of the ring buffer have been consumed by the USB
203 Since the packet size is not known in advance, this buffer is 118 * subsystem (i.e., sent to the USB device) up to this position.
204 large enough to store maximum size packets. 119 */
205 */ 120 snd_pcm_uframes_t pos_done;
206 unsigned char *buffer_in;
207 121
208 /** 122 /* Bit mask of active URBs */
209 Previously captured frame (for software monitoring). 123 unsigned long active_urbs;
210 */
211 unsigned char *prev_fbuf;
212 124
213 /** 125 /* Bit mask of URBs currently being unlinked */
214 Size of previously captured frame (for software monitoring). 126 unsigned long unlink_urbs;
215 */
216 int prev_fsize;
217 127
218 /** 128 /* Spin lock to protect updates of the buffer positions (not contents)
219 Free frame position in the playback buffer. 129 */
220 */ 130 spinlock_t lock;
221 snd_pcm_uframes_t pos_out;
222 131
223 /** 132 /* Bit flags for operational stream types */
224 Count processed bytes for playback. 133 unsigned long opened;
225 This is modulo period size (to determine when a period is
226 finished).
227 */
228 unsigned bytes_out;
229 134
230 /** 135 /* Bit flags for running stream types */
231 Counter to create desired playback sample rate. 136 unsigned long running;
232 */
233 unsigned count_out;
234 137
235 /** 138 int last_frame;
236 Playback period size in bytes 139};
237 */
238 unsigned period_out;
239 140
141struct snd_line6_pcm {
240 /** 142 /**
241 Processed frame position in the playback buffer. 143 Pointer back to the Line 6 driver data structure.
242 The contents of the output ring buffer have been consumed by
243 the USB subsystem (i.e., sent to the USB device) up to this
244 position.
245 */ 144 */
246 snd_pcm_uframes_t pos_out_done; 145 struct usb_line6 *line6;
247 146
248 /** 147 /**
249 Count processed bytes for capture. 148 Properties.
250 This is modulo period size (to determine when a period is
251 finished).
252 */ 149 */
253 unsigned bytes_in; 150 struct line6_pcm_properties *properties;
254 151
255 /** 152 /**
256 Counter to create desired capture sample rate. 153 ALSA pcm stream
257 */ 154 */
258 unsigned count_in; 155 struct snd_pcm *pcm;
259 156
260 /** 157 /* protection to state changes of in/out streams */
261 Capture period size in bytes 158 struct mutex state_mutex;
262 */ 159
263 unsigned period_in; 160 /* Capture and playback streams */
161 struct line6_pcm_stream in;
162 struct line6_pcm_stream out;
264 163
265 /** 164 /**
266 Processed frame position in the capture buffer. 165 Previously captured frame (for software monitoring).
267 The contents of the output ring buffer have been consumed by
268 the USB subsystem (i.e., sent to the USB device) up to this
269 position.
270 */ 166 */
271 snd_pcm_uframes_t pos_in_done; 167 unsigned char *prev_fbuf;
272 168
273 /** 169 /**
274 Bit mask of active playback URBs. 170 Size of previously captured frame (for software monitoring).
275 */ 171 */
276 unsigned long active_urb_out; 172 int prev_fsize;
277 173
278 /** 174 /**
279 Maximum size of USB packet. 175 Maximum size of USB packet.
@@ -281,38 +177,6 @@ struct snd_line6_pcm {
281 int max_packet_size; 177 int max_packet_size;
282 178
283 /** 179 /**
284 Bit mask of active capture URBs.
285 */
286 unsigned long active_urb_in;
287
288 /**
289 Bit mask of playback URBs currently being unlinked.
290 */
291 unsigned long unlink_urb_out;
292
293 /**
294 Bit mask of capture URBs currently being unlinked.
295 */
296 unsigned long unlink_urb_in;
297
298 /**
299 Spin lock to protect updates of the playback buffer positions (not
300 contents!)
301 */
302 spinlock_t lock_audio_out;
303
304 /**
305 Spin lock to protect updates of the capture buffer positions (not
306 contents!)
307 */
308 spinlock_t lock_audio_in;
309
310 /**
311 Spin lock to protect trigger.
312 */
313 spinlock_t lock_trigger;
314
315 /**
316 PCM playback volume (left and right). 180 PCM playback volume (left and right).
317 */ 181 */
318 int volume_playback[2]; 182 int volume_playback[2];
@@ -338,19 +202,21 @@ struct snd_line6_pcm {
338 int impulse_count; 202 int impulse_count;
339 203
340 /** 204 /**
341 Several status bits (see LINE6_BIT_*). 205 Several status bits (see LINE6_FLAG_*).
342 */ 206 */
343 unsigned long flags; 207 unsigned long flags;
344
345 int last_frame_in, last_frame_out;
346}; 208};
347 209
348extern int line6_init_pcm(struct usb_line6 *line6, 210extern int line6_init_pcm(struct usb_line6 *line6,
349 struct line6_pcm_properties *properties); 211 struct line6_pcm_properties *properties);
350extern int snd_line6_trigger(struct snd_pcm_substream *substream, int cmd); 212extern int snd_line6_trigger(struct snd_pcm_substream *substream, int cmd);
351extern int snd_line6_prepare(struct snd_pcm_substream *substream); 213extern int snd_line6_prepare(struct snd_pcm_substream *substream);
214extern int snd_line6_hw_params(struct snd_pcm_substream *substream,
215 struct snd_pcm_hw_params *hw_params);
216extern int snd_line6_hw_free(struct snd_pcm_substream *substream);
217extern snd_pcm_uframes_t snd_line6_pointer(struct snd_pcm_substream *substream);
352extern void line6_pcm_disconnect(struct snd_line6_pcm *line6pcm); 218extern void line6_pcm_disconnect(struct snd_line6_pcm *line6pcm);
353extern int line6_pcm_acquire(struct snd_line6_pcm *line6pcm, int channels); 219extern int line6_pcm_acquire(struct snd_line6_pcm *line6pcm, int type);
354extern int line6_pcm_release(struct snd_line6_pcm *line6pcm, int channels); 220extern void line6_pcm_release(struct snd_line6_pcm *line6pcm, int type);
355 221
356#endif 222#endif
diff --git a/sound/usb/line6/playback.c b/sound/usb/line6/playback.c
index 1c9f95a370ff..1708c05f14db 100644
--- a/sound/usb/line6/playback.c
+++ b/sound/usb/line6/playback.c
@@ -37,7 +37,8 @@ static void change_volume(struct urb *urb_out, int volume[],
37 buf_end = p + urb_out->transfer_buffer_length / sizeof(*p); 37 buf_end = p + urb_out->transfer_buffer_length / sizeof(*p);
38 38
39 for (; p < buf_end; ++p) { 39 for (; p < buf_end; ++p) {
40 *p = (*p * volume[chn & 1]) >> 8; 40 int val = (*p * volume[chn & 1]) >> 8;
41 *p = clamp(val, 0x7fff, -0x8000);
41 ++chn; 42 ++chn;
42 } 43 }
43 } else if (bytes_per_frame == 6) { 44 } else if (bytes_per_frame == 6) {
@@ -51,6 +52,7 @@ static void change_volume(struct urb *urb_out, int volume[],
51 52
52 val = p[0] + (p[1] << 8) + ((signed char)p[2] << 16); 53 val = p[0] + (p[1] << 8) + ((signed char)p[2] << 16);
53 val = (val * volume[chn & 1]) >> 8; 54 val = (val * volume[chn & 1]) >> 8;
55 val = clamp(val, 0x7fffff, -0x800000);
54 p[0] = val; 56 p[0] = val;
55 p[1] = val >> 8; 57 p[1] = val >> 8;
56 p[2] = val >> 16; 58 p[2] = val >> 16;
@@ -118,8 +120,10 @@ static void add_monitor_signal(struct urb *urb_out, unsigned char *signal,
118 po = (short *)urb_out->transfer_buffer; 120 po = (short *)urb_out->transfer_buffer;
119 buf_end = po + urb_out->transfer_buffer_length / sizeof(*po); 121 buf_end = po + urb_out->transfer_buffer_length / sizeof(*po);
120 122
121 for (; po < buf_end; ++pi, ++po) 123 for (; po < buf_end; ++pi, ++po) {
122 *po += (*pi * volume) >> 8; 124 int val = *po + ((*pi * volume) >> 8);
125 *po = clamp(val, 0x7fff, -0x8000);
126 }
123 } 127 }
124 128
125 /* 129 /*
@@ -130,11 +134,11 @@ static void add_monitor_signal(struct urb *urb_out, unsigned char *signal,
130 134
131/* 135/*
132 Find a free URB, prepare audio data, and submit URB. 136 Find a free URB, prepare audio data, and submit URB.
137 must be called in line6pcm->out.lock context
133*/ 138*/
134static int submit_audio_out_urb(struct snd_line6_pcm *line6pcm) 139static int submit_audio_out_urb(struct snd_line6_pcm *line6pcm)
135{ 140{
136 int index; 141 int index;
137 unsigned long flags;
138 int i, urb_size, urb_frames; 142 int i, urb_size, urb_frames;
139 int ret; 143 int ret;
140 const int bytes_per_frame = line6pcm->properties->bytes_per_frame; 144 const int bytes_per_frame = line6pcm->properties->bytes_per_frame;
@@ -145,17 +149,15 @@ static int submit_audio_out_urb(struct snd_line6_pcm *line6pcm)
145 (USB_INTERVALS_PER_SECOND / LINE6_ISO_INTERVAL); 149 (USB_INTERVALS_PER_SECOND / LINE6_ISO_INTERVAL);
146 struct urb *urb_out; 150 struct urb *urb_out;
147 151
148 spin_lock_irqsave(&line6pcm->lock_audio_out, flags);
149 index = 152 index =
150 find_first_zero_bit(&line6pcm->active_urb_out, LINE6_ISO_BUFFERS); 153 find_first_zero_bit(&line6pcm->out.active_urbs, LINE6_ISO_BUFFERS);
151 154
152 if (index < 0 || index >= LINE6_ISO_BUFFERS) { 155 if (index < 0 || index >= LINE6_ISO_BUFFERS) {
153 spin_unlock_irqrestore(&line6pcm->lock_audio_out, flags);
154 dev_err(line6pcm->line6->ifcdev, "no free URB found\n"); 156 dev_err(line6pcm->line6->ifcdev, "no free URB found\n");
155 return -EINVAL; 157 return -EINVAL;
156 } 158 }
157 159
158 urb_out = line6pcm->urb_audio_out[index]; 160 urb_out = line6pcm->out.urbs[index];
159 urb_size = 0; 161 urb_size = 0;
160 162
161 for (i = 0; i < LINE6_ISO_PACKETS; ++i) { 163 for (i = 0; i < LINE6_ISO_PACKETS; ++i) {
@@ -164,15 +166,13 @@ static int submit_audio_out_urb(struct snd_line6_pcm *line6pcm)
164 struct usb_iso_packet_descriptor *fout = 166 struct usb_iso_packet_descriptor *fout =
165 &urb_out->iso_frame_desc[i]; 167 &urb_out->iso_frame_desc[i];
166 168
167 if (line6pcm->flags & LINE6_BITS_CAPTURE_STREAM) 169 fsize = line6pcm->prev_fsize;
168 fsize = line6pcm->prev_fsize;
169
170 if (fsize == 0) { 170 if (fsize == 0) {
171 int n; 171 int n;
172 172
173 line6pcm->count_out += frame_increment; 173 line6pcm->out.count += frame_increment;
174 n = line6pcm->count_out / frame_factor; 174 n = line6pcm->out.count / frame_factor;
175 line6pcm->count_out -= n * frame_factor; 175 line6pcm->out.count -= n * frame_factor;
176 fsize = n * bytes_per_frame; 176 fsize = n * bytes_per_frame;
177 } 177 }
178 178
@@ -183,36 +183,35 @@ static int submit_audio_out_urb(struct snd_line6_pcm *line6pcm)
183 183
184 if (urb_size == 0) { 184 if (urb_size == 0) {
185 /* can't determine URB size */ 185 /* can't determine URB size */
186 spin_unlock_irqrestore(&line6pcm->lock_audio_out, flags);
187 dev_err(line6pcm->line6->ifcdev, "driver bug: urb_size = 0\n"); 186 dev_err(line6pcm->line6->ifcdev, "driver bug: urb_size = 0\n");
188 return -EINVAL; 187 return -EINVAL;
189 } 188 }
190 189
191 urb_frames = urb_size / bytes_per_frame; 190 urb_frames = urb_size / bytes_per_frame;
192 urb_out->transfer_buffer = 191 urb_out->transfer_buffer =
193 line6pcm->buffer_out + 192 line6pcm->out.buffer +
194 index * LINE6_ISO_PACKETS * line6pcm->max_packet_size; 193 index * LINE6_ISO_PACKETS * line6pcm->max_packet_size;
195 urb_out->transfer_buffer_length = urb_size; 194 urb_out->transfer_buffer_length = urb_size;
196 urb_out->context = line6pcm; 195 urb_out->context = line6pcm;
197 196
198 if (test_bit(LINE6_INDEX_PCM_ALSA_PLAYBACK_STREAM, &line6pcm->flags) && 197 if (test_bit(LINE6_STREAM_PCM, &line6pcm->out.running) &&
199 !test_bit(LINE6_INDEX_PAUSE_PLAYBACK, &line6pcm->flags)) { 198 !test_bit(LINE6_FLAG_PAUSE_PLAYBACK, &line6pcm->flags)) {
200 struct snd_pcm_runtime *runtime = 199 struct snd_pcm_runtime *runtime =
201 get_substream(line6pcm, SNDRV_PCM_STREAM_PLAYBACK)->runtime; 200 get_substream(line6pcm, SNDRV_PCM_STREAM_PLAYBACK)->runtime;
202 201
203 if (line6pcm->pos_out + urb_frames > runtime->buffer_size) { 202 if (line6pcm->out.pos + urb_frames > runtime->buffer_size) {
204 /* 203 /*
205 The transferred area goes over buffer boundary, 204 The transferred area goes over buffer boundary,
206 copy the data to the temp buffer. 205 copy the data to the temp buffer.
207 */ 206 */
208 int len; 207 int len;
209 208
210 len = runtime->buffer_size - line6pcm->pos_out; 209 len = runtime->buffer_size - line6pcm->out.pos;
211 210
212 if (len > 0) { 211 if (len > 0) {
213 memcpy(urb_out->transfer_buffer, 212 memcpy(urb_out->transfer_buffer,
214 runtime->dma_area + 213 runtime->dma_area +
215 line6pcm->pos_out * bytes_per_frame, 214 line6pcm->out.pos * bytes_per_frame,
216 len * bytes_per_frame); 215 len * bytes_per_frame);
217 memcpy(urb_out->transfer_buffer + 216 memcpy(urb_out->transfer_buffer +
218 len * bytes_per_frame, runtime->dma_area, 217 len * bytes_per_frame, runtime->dma_area,
@@ -223,26 +222,27 @@ static int submit_audio_out_urb(struct snd_line6_pcm *line6pcm)
223 } else { 222 } else {
224 memcpy(urb_out->transfer_buffer, 223 memcpy(urb_out->transfer_buffer,
225 runtime->dma_area + 224 runtime->dma_area +
226 line6pcm->pos_out * bytes_per_frame, 225 line6pcm->out.pos * bytes_per_frame,
227 urb_out->transfer_buffer_length); 226 urb_out->transfer_buffer_length);
228 } 227 }
229 228
230 line6pcm->pos_out += urb_frames; 229 line6pcm->out.pos += urb_frames;
231 if (line6pcm->pos_out >= runtime->buffer_size) 230 if (line6pcm->out.pos >= runtime->buffer_size)
232 line6pcm->pos_out -= runtime->buffer_size; 231 line6pcm->out.pos -= runtime->buffer_size;
232
233 change_volume(urb_out, line6pcm->volume_playback,
234 bytes_per_frame);
233 } else { 235 } else {
234 memset(urb_out->transfer_buffer, 0, 236 memset(urb_out->transfer_buffer, 0,
235 urb_out->transfer_buffer_length); 237 urb_out->transfer_buffer_length);
236 } 238 }
237 239
238 change_volume(urb_out, line6pcm->volume_playback, bytes_per_frame); 240 spin_lock_nested(&line6pcm->in.lock, SINGLE_DEPTH_NESTING);
239 241 if (line6pcm->prev_fbuf) {
240 if (line6pcm->prev_fbuf != NULL) { 242 if (test_bit(LINE6_STREAM_IMPULSE, &line6pcm->out.running)) {
241 if (line6pcm->flags & LINE6_BITS_PCM_IMPULSE) {
242 create_impulse_test_signal(line6pcm, urb_out, 243 create_impulse_test_signal(line6pcm, urb_out,
243 bytes_per_frame); 244 bytes_per_frame);
244 if (line6pcm->flags & 245 if (test_bit(LINE6_STREAM_PCM, &line6pcm->in.running)) {
245 LINE6_BIT_PCM_ALSA_CAPTURE_STREAM) {
246 line6_capture_copy(line6pcm, 246 line6_capture_copy(line6pcm,
247 urb_out->transfer_buffer, 247 urb_out->transfer_buffer,
248 urb_out-> 248 urb_out->
@@ -251,101 +251,43 @@ static int submit_audio_out_urb(struct snd_line6_pcm *line6pcm)
251 urb_out->transfer_buffer_length); 251 urb_out->transfer_buffer_length);
252 } 252 }
253 } else { 253 } else {
254 if (! 254 if (!(line6pcm->line6->properties->capabilities & LINE6_CAP_HWMON)
255 (line6pcm->line6-> 255 && line6pcm->out.running && line6pcm->in.running)
256 properties->capabilities & LINE6_CAP_HWMON)
257 && (line6pcm->flags & LINE6_BITS_PLAYBACK_STREAM)
258 && (line6pcm->flags & LINE6_BITS_CAPTURE_STREAM))
259 add_monitor_signal(urb_out, line6pcm->prev_fbuf, 256 add_monitor_signal(urb_out, line6pcm->prev_fbuf,
260 line6pcm->volume_monitor, 257 line6pcm->volume_monitor,
261 bytes_per_frame); 258 bytes_per_frame);
262 } 259 }
260 line6pcm->prev_fbuf = NULL;
261 line6pcm->prev_fsize = 0;
263 } 262 }
263 spin_unlock(&line6pcm->in.lock);
264 264
265 ret = usb_submit_urb(urb_out, GFP_ATOMIC); 265 ret = usb_submit_urb(urb_out, GFP_ATOMIC);
266 266
267 if (ret == 0) 267 if (ret == 0)
268 set_bit(index, &line6pcm->active_urb_out); 268 set_bit(index, &line6pcm->out.active_urbs);
269 else 269 else
270 dev_err(line6pcm->line6->ifcdev, 270 dev_err(line6pcm->line6->ifcdev,
271 "URB out #%d submission failed (%d)\n", index, ret); 271 "URB out #%d submission failed (%d)\n", index, ret);
272 272
273 spin_unlock_irqrestore(&line6pcm->lock_audio_out, flags);
274 return 0; 273 return 0;
275} 274}
276 275
277/* 276/*
278 Submit all currently available playback URBs. 277 Submit all currently available playback URBs.
279*/ 278 must be called in line6pcm->out.lock context
279 */
280int line6_submit_audio_out_all_urbs(struct snd_line6_pcm *line6pcm) 280int line6_submit_audio_out_all_urbs(struct snd_line6_pcm *line6pcm)
281{ 281{
282 int ret, i; 282 int ret = 0, i;
283 283
284 for (i = 0; i < LINE6_ISO_BUFFERS; ++i) { 284 for (i = 0; i < LINE6_ISO_BUFFERS; ++i) {
285 ret = submit_audio_out_urb(line6pcm); 285 ret = submit_audio_out_urb(line6pcm);
286 if (ret < 0) 286 if (ret < 0)
287 return ret;
288 }
289
290 return 0;
291}
292
293/*
294 Unlink all currently active playback URBs.
295*/
296void line6_unlink_audio_out_urbs(struct snd_line6_pcm *line6pcm)
297{
298 unsigned int i;
299
300 for (i = LINE6_ISO_BUFFERS; i--;) {
301 if (test_bit(i, &line6pcm->active_urb_out)) {
302 if (!test_and_set_bit(i, &line6pcm->unlink_urb_out)) {
303 struct urb *u = line6pcm->urb_audio_out[i];
304
305 usb_unlink_urb(u);
306 }
307 }
308 }
309}
310
311/*
312 Wait until unlinking of all currently active playback URBs has been
313 finished.
314*/
315void line6_wait_clear_audio_out_urbs(struct snd_line6_pcm *line6pcm)
316{
317 int timeout = HZ;
318 unsigned int i;
319 int alive;
320
321 do {
322 alive = 0;
323 for (i = LINE6_ISO_BUFFERS; i--;) {
324 if (test_bit(i, &line6pcm->active_urb_out))
325 alive++;
326 }
327 if (!alive)
328 break; 287 break;
329 set_current_state(TASK_UNINTERRUPTIBLE); 288 }
330 schedule_timeout(1);
331 } while (--timeout > 0);
332 if (alive)
333 snd_printk(KERN_ERR "timeout: still %d active urbs..\n", alive);
334}
335
336/*
337 Unlink all currently active playback URBs, and wait for finishing.
338*/
339void line6_unlink_wait_clear_audio_out_urbs(struct snd_line6_pcm *line6pcm)
340{
341 line6_unlink_audio_out_urbs(line6pcm);
342 line6_wait_clear_audio_out_urbs(line6pcm);
343}
344 289
345void line6_free_playback_buffer(struct snd_line6_pcm *line6pcm) 290 return ret;
346{
347 kfree(line6pcm->buffer_out);
348 line6pcm->buffer_out = NULL;
349} 291}
350 292
351/* 293/*
@@ -363,56 +305,56 @@ static void audio_out_callback(struct urb *urb)
363 memset(urb->transfer_buffer, 0, urb->transfer_buffer_length); 305 memset(urb->transfer_buffer, 0, urb->transfer_buffer_length);
364#endif 306#endif
365 307
366 line6pcm->last_frame_out = urb->start_frame; 308 line6pcm->out.last_frame = urb->start_frame;
367 309
368 /* find index of URB */ 310 /* find index of URB */
369 for (index = LINE6_ISO_BUFFERS; index--;) 311 for (index = 0; index < LINE6_ISO_BUFFERS; index++)
370 if (urb == line6pcm->urb_audio_out[index]) 312 if (urb == line6pcm->out.urbs[index])
371 break; 313 break;
372 314
373 if (index < 0) 315 if (index >= LINE6_ISO_BUFFERS)
374 return; /* URB has been unlinked asynchronously */ 316 return; /* URB has been unlinked asynchronously */
375 317
376 for (i = LINE6_ISO_PACKETS; i--;) 318 for (i = 0; i < LINE6_ISO_PACKETS; i++)
377 length += urb->iso_frame_desc[i].length; 319 length += urb->iso_frame_desc[i].length;
378 320
379 spin_lock_irqsave(&line6pcm->lock_audio_out, flags); 321 spin_lock_irqsave(&line6pcm->out.lock, flags);
380 322
381 if (test_bit(LINE6_INDEX_PCM_ALSA_PLAYBACK_STREAM, &line6pcm->flags)) { 323 if (test_bit(LINE6_STREAM_PCM, &line6pcm->out.running)) {
382 struct snd_pcm_runtime *runtime = substream->runtime; 324 struct snd_pcm_runtime *runtime = substream->runtime;
383 325
384 line6pcm->pos_out_done += 326 line6pcm->out.pos_done +=
385 length / line6pcm->properties->bytes_per_frame; 327 length / line6pcm->properties->bytes_per_frame;
386 328
387 if (line6pcm->pos_out_done >= runtime->buffer_size) 329 if (line6pcm->out.pos_done >= runtime->buffer_size)
388 line6pcm->pos_out_done -= runtime->buffer_size; 330 line6pcm->out.pos_done -= runtime->buffer_size;
389 } 331 }
390 332
391 clear_bit(index, &line6pcm->active_urb_out); 333 clear_bit(index, &line6pcm->out.active_urbs);
392 334
393 for (i = LINE6_ISO_PACKETS; i--;) 335 for (i = 0; i < LINE6_ISO_PACKETS; i++)
394 if (urb->iso_frame_desc[i].status == -EXDEV) { 336 if (urb->iso_frame_desc[i].status == -EXDEV) {
395 shutdown = 1; 337 shutdown = 1;
396 break; 338 break;
397 } 339 }
398 340
399 if (test_and_clear_bit(index, &line6pcm->unlink_urb_out)) 341 if (test_and_clear_bit(index, &line6pcm->out.unlink_urbs))
400 shutdown = 1; 342 shutdown = 1;
401 343
402 spin_unlock_irqrestore(&line6pcm->lock_audio_out, flags);
403
404 if (!shutdown) { 344 if (!shutdown) {
405 submit_audio_out_urb(line6pcm); 345 submit_audio_out_urb(line6pcm);
406 346
407 if (test_bit(LINE6_INDEX_PCM_ALSA_PLAYBACK_STREAM, 347 if (test_bit(LINE6_STREAM_PCM, &line6pcm->out.running)) {
408 &line6pcm->flags)) { 348 line6pcm->out.bytes += length;
409 line6pcm->bytes_out += length; 349 if (line6pcm->out.bytes >= line6pcm->out.period) {
410 if (line6pcm->bytes_out >= line6pcm->period_out) { 350 line6pcm->out.bytes %= line6pcm->out.period;
411 line6pcm->bytes_out %= line6pcm->period_out; 351 spin_unlock(&line6pcm->out.lock);
412 snd_pcm_period_elapsed(substream); 352 snd_pcm_period_elapsed(substream);
353 spin_lock(&line6pcm->out.lock);
413 } 354 }
414 } 355 }
415 } 356 }
357 spin_unlock_irqrestore(&line6pcm->out.lock, flags);
416} 358}
417 359
418/* open playback callback */ 360/* open playback callback */
@@ -438,110 +380,16 @@ static int snd_line6_playback_close(struct snd_pcm_substream *substream)
438 return 0; 380 return 0;
439} 381}
440 382
441/* hw_params playback callback */
442static int snd_line6_playback_hw_params(struct snd_pcm_substream *substream,
443 struct snd_pcm_hw_params *hw_params)
444{
445 int ret;
446 struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
447
448 /* -- Florian Demski [FD] */
449 /* don't ask me why, but this fixes the bug on my machine */
450 if (line6pcm == NULL) {
451 if (substream->pcm == NULL)
452 return -ENOMEM;
453 if (substream->pcm->private_data == NULL)
454 return -ENOMEM;
455 substream->private_data = substream->pcm->private_data;
456 line6pcm = snd_pcm_substream_chip(substream);
457 }
458 /* -- [FD] end */
459
460 ret = line6_pcm_acquire(line6pcm, LINE6_BIT_PCM_ALSA_PLAYBACK_BUFFER);
461
462 if (ret < 0)
463 return ret;
464
465 ret = snd_pcm_lib_malloc_pages(substream,
466 params_buffer_bytes(hw_params));
467 if (ret < 0) {
468 line6_pcm_release(line6pcm, LINE6_BIT_PCM_ALSA_PLAYBACK_BUFFER);
469 return ret;
470 }
471
472 line6pcm->period_out = params_period_bytes(hw_params);
473 return 0;
474}
475
476/* hw_free playback callback */
477static int snd_line6_playback_hw_free(struct snd_pcm_substream *substream)
478{
479 struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
480
481 line6_pcm_release(line6pcm, LINE6_BIT_PCM_ALSA_PLAYBACK_BUFFER);
482 return snd_pcm_lib_free_pages(substream);
483}
484
485/* trigger playback callback */
486int snd_line6_playback_trigger(struct snd_line6_pcm *line6pcm, int cmd)
487{
488 int err;
489
490 switch (cmd) {
491 case SNDRV_PCM_TRIGGER_START:
492 case SNDRV_PCM_TRIGGER_RESUME:
493 err = line6_pcm_acquire(line6pcm,
494 LINE6_BIT_PCM_ALSA_PLAYBACK_STREAM);
495
496 if (err < 0)
497 return err;
498
499 break;
500
501 case SNDRV_PCM_TRIGGER_STOP:
502 case SNDRV_PCM_TRIGGER_SUSPEND:
503 err = line6_pcm_release(line6pcm,
504 LINE6_BIT_PCM_ALSA_PLAYBACK_STREAM);
505
506 if (err < 0)
507 return err;
508
509 break;
510
511 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
512 set_bit(LINE6_INDEX_PAUSE_PLAYBACK, &line6pcm->flags);
513 break;
514
515 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
516 clear_bit(LINE6_INDEX_PAUSE_PLAYBACK, &line6pcm->flags);
517 break;
518
519 default:
520 return -EINVAL;
521 }
522
523 return 0;
524}
525
526/* playback pointer callback */
527static snd_pcm_uframes_t
528snd_line6_playback_pointer(struct snd_pcm_substream *substream)
529{
530 struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
531
532 return line6pcm->pos_out_done;
533}
534
535/* playback operators */ 383/* playback operators */
536struct snd_pcm_ops snd_line6_playback_ops = { 384struct snd_pcm_ops snd_line6_playback_ops = {
537 .open = snd_line6_playback_open, 385 .open = snd_line6_playback_open,
538 .close = snd_line6_playback_close, 386 .close = snd_line6_playback_close,
539 .ioctl = snd_pcm_lib_ioctl, 387 .ioctl = snd_pcm_lib_ioctl,
540 .hw_params = snd_line6_playback_hw_params, 388 .hw_params = snd_line6_hw_params,
541 .hw_free = snd_line6_playback_hw_free, 389 .hw_free = snd_line6_hw_free,
542 .prepare = snd_line6_prepare, 390 .prepare = snd_line6_prepare,
543 .trigger = snd_line6_trigger, 391 .trigger = snd_line6_trigger,
544 .pointer = snd_line6_playback_pointer, 392 .pointer = snd_line6_pointer,
545}; 393};
546 394
547int line6_create_audio_out_urbs(struct snd_line6_pcm *line6pcm) 395int line6_create_audio_out_urbs(struct snd_line6_pcm *line6pcm)
@@ -554,7 +402,7 @@ int line6_create_audio_out_urbs(struct snd_line6_pcm *line6pcm)
554 struct urb *urb; 402 struct urb *urb;
555 403
556 /* URB for audio out: */ 404 /* URB for audio out: */
557 urb = line6pcm->urb_audio_out[i] = 405 urb = line6pcm->out.urbs[i] =
558 usb_alloc_urb(LINE6_ISO_PACKETS, GFP_KERNEL); 406 usb_alloc_urb(LINE6_ISO_PACKETS, GFP_KERNEL);
559 407
560 if (urb == NULL) 408 if (urb == NULL)
diff --git a/sound/usb/line6/playback.h b/sound/usb/line6/playback.h
index 78a885113221..51fce29e8726 100644
--- a/sound/usb/line6/playback.h
+++ b/sound/usb/line6/playback.h
@@ -30,12 +30,6 @@
30extern struct snd_pcm_ops snd_line6_playback_ops; 30extern struct snd_pcm_ops snd_line6_playback_ops;
31 31
32extern int line6_create_audio_out_urbs(struct snd_line6_pcm *line6pcm); 32extern int line6_create_audio_out_urbs(struct snd_line6_pcm *line6pcm);
33extern void line6_free_playback_buffer(struct snd_line6_pcm *line6pcm);
34extern int line6_submit_audio_out_all_urbs(struct snd_line6_pcm *line6pcm); 33extern int line6_submit_audio_out_all_urbs(struct snd_line6_pcm *line6pcm);
35extern void line6_unlink_audio_out_urbs(struct snd_line6_pcm *line6pcm);
36extern void line6_unlink_wait_clear_audio_out_urbs(struct snd_line6_pcm
37 *line6pcm);
38extern void line6_wait_clear_audio_out_urbs(struct snd_line6_pcm *line6pcm);
39extern int snd_line6_playback_trigger(struct snd_line6_pcm *line6pcm, int cmd);
40 34
41#endif 35#endif
diff --git a/sound/usb/line6/pod.c b/sound/usb/line6/pod.c
index bf027fc70cba..6f7cd585f2d8 100644
--- a/sound/usb/line6/pod.c
+++ b/sound/usb/line6/pod.c
@@ -399,27 +399,18 @@ static struct snd_kcontrol_new pod_control_monitor = {
399/* 399/*
400 POD device disconnected. 400 POD device disconnected.
401*/ 401*/
402static void line6_pod_disconnect(struct usb_interface *interface) 402static void line6_pod_disconnect(struct usb_line6 *line6)
403{ 403{
404 struct usb_line6_pod *pod; 404 struct usb_line6_pod *pod = (struct usb_line6_pod *)line6;
405 struct device *dev = line6->ifcdev;
405 406
406 if (interface == NULL) 407 /* remove sysfs entries: */
407 return; 408 device_remove_file(dev, &dev_attr_device_id);
408 pod = usb_get_intfdata(interface); 409 device_remove_file(dev, &dev_attr_firmware_version);
409 410 device_remove_file(dev, &dev_attr_serial_number);
410 if (pod != NULL) {
411 struct device *dev = &interface->dev;
412
413 if (dev != NULL) {
414 /* remove sysfs entries: */
415 device_remove_file(dev, &dev_attr_device_id);
416 device_remove_file(dev, &dev_attr_firmware_version);
417 device_remove_file(dev, &dev_attr_serial_number);
418 }
419 411
420 del_timer_sync(&pod->startup_timer); 412 del_timer_sync(&pod->startup_timer);
421 cancel_work_sync(&pod->startup_work); 413 cancel_work_sync(&pod->startup_work);
422 }
423} 414}
424 415
425/* 416/*
@@ -444,8 +435,8 @@ static int pod_create_files2(struct device *dev)
444/* 435/*
445 Try to init POD device. 436 Try to init POD device.
446*/ 437*/
447static int pod_init(struct usb_interface *interface, 438static int pod_init(struct usb_line6 *line6,
448 struct usb_line6 *line6) 439 const struct usb_device_id *id)
449{ 440{
450 int err; 441 int err;
451 struct usb_line6_pod *pod = (struct usb_line6_pod *) line6; 442 struct usb_line6_pod *pod = (struct usb_line6_pod *) line6;
@@ -456,11 +447,8 @@ static int pod_init(struct usb_interface *interface,
456 init_timer(&pod->startup_timer); 447 init_timer(&pod->startup_timer);
457 INIT_WORK(&pod->startup_work, pod_startup4); 448 INIT_WORK(&pod->startup_work, pod_startup4);
458 449
459 if ((interface == NULL) || (pod == NULL))
460 return -ENODEV;
461
462 /* create sysfs entries: */ 450 /* create sysfs entries: */
463 err = pod_create_files2(&interface->dev); 451 err = pod_create_files2(line6->ifcdev);
464 if (err < 0) 452 if (err < 0)
465 return err; 453 return err;
466 454
@@ -603,14 +591,9 @@ static const struct line6_properties pod_properties_table[] = {
603static int pod_probe(struct usb_interface *interface, 591static int pod_probe(struct usb_interface *interface,
604 const struct usb_device_id *id) 592 const struct usb_device_id *id)
605{ 593{
606 struct usb_line6_pod *pod; 594 return line6_probe(interface, id,
607
608 pod = kzalloc(sizeof(*pod), GFP_KERNEL);
609 if (!pod)
610 return -ENODEV;
611 return line6_probe(interface, &pod->line6,
612 &pod_properties_table[id->driver_info], 595 &pod_properties_table[id->driver_info],
613 pod_init); 596 pod_init, sizeof(struct usb_line6_pod));
614} 597}
615 598
616static struct usb_driver pod_driver = { 599static struct usb_driver pod_driver = {
diff --git a/sound/usb/line6/podhd.c b/sound/usb/line6/podhd.c
index 7217fa7e5db1..43c39886597e 100644
--- a/sound/usb/line6/podhd.c
+++ b/sound/usb/line6/podhd.c
@@ -87,15 +87,11 @@ static struct line6_pcm_properties podhd_pcm_properties = {
87/* 87/*
88 Try to init POD HD device. 88 Try to init POD HD device.
89*/ 89*/
90static int podhd_init(struct usb_interface *interface, 90static int podhd_init(struct usb_line6 *line6,
91 struct usb_line6 *line6) 91 const struct usb_device_id *id)
92{ 92{
93 struct usb_line6_podhd *podhd = (struct usb_line6_podhd *) line6;
94 int err; 93 int err;
95 94
96 if ((interface == NULL) || (podhd == NULL))
97 return -ENODEV;
98
99 /* initialize MIDI subsystem: */ 95 /* initialize MIDI subsystem: */
100 err = line6_init_midi(line6); 96 err = line6_init_midi(line6);
101 if (err < 0) 97 if (err < 0)
@@ -181,14 +177,9 @@ static const struct line6_properties podhd_properties_table[] = {
181static int podhd_probe(struct usb_interface *interface, 177static int podhd_probe(struct usb_interface *interface,
182 const struct usb_device_id *id) 178 const struct usb_device_id *id)
183{ 179{
184 struct usb_line6_podhd *podhd; 180 return line6_probe(interface, id,
185
186 podhd = kzalloc(sizeof(*podhd), GFP_KERNEL);
187 if (!podhd)
188 return -ENODEV;
189 return line6_probe(interface, &podhd->line6,
190 &podhd_properties_table[id->driver_info], 181 &podhd_properties_table[id->driver_info],
191 podhd_init); 182 podhd_init, sizeof(struct usb_line6_podhd));
192} 183}
193 184
194static struct usb_driver podhd_driver = { 185static struct usb_driver podhd_driver = {
diff --git a/sound/usb/line6/toneport.c b/sound/usb/line6/toneport.c
index c1f61cde52ab..819e06b3f3db 100644
--- a/sound/usb/line6/toneport.c
+++ b/sound/usb/line6/toneport.c
@@ -14,6 +14,7 @@
14#include <linux/usb.h> 14#include <linux/usb.h>
15#include <linux/slab.h> 15#include <linux/slab.h>
16#include <linux/module.h> 16#include <linux/module.h>
17#include <linux/leds.h>
17#include <sound/core.h> 18#include <sound/core.h>
18#include <sound/control.h> 19#include <sound/control.h>
19 20
@@ -32,6 +33,15 @@ enum line6_device_type {
32 LINE6_TONEPORT_UX2, 33 LINE6_TONEPORT_UX2,
33}; 34};
34 35
36struct usb_line6_toneport;
37
38struct toneport_led {
39 struct led_classdev dev;
40 char name[64];
41 struct usb_line6_toneport *toneport;
42 bool registered;
43};
44
35struct usb_line6_toneport { 45struct usb_line6_toneport {
36 /** 46 /**
37 Generic Line 6 USB data. 47 Generic Line 6 USB data.
@@ -62,6 +72,9 @@ struct usb_line6_toneport {
62 Device type. 72 Device type.
63 */ 73 */
64 enum line6_device_type type; 74 enum line6_device_type type;
75
76 /* LED instances */
77 struct toneport_led leds[2];
65}; 78};
66 79
67static int toneport_send_cmd(struct usb_device *usbdev, int cmd1, int cmd2); 80static int toneport_send_cmd(struct usb_device *usbdev, int cmd1, int cmd2);
@@ -117,15 +130,6 @@ static struct line6_pcm_properties toneport_pcm_properties = {
117 .bytes_per_frame = 4 130 .bytes_per_frame = 4
118}; 131};
119 132
120/*
121 For the led on Guitarport.
122 Brightness goes from 0x00 to 0x26. Set a value above this to have led
123 blink.
124 (void cmd_0x02(byte red, byte green)
125*/
126static int led_red = 0x00;
127static int led_green = 0x26;
128
129static const struct { 133static const struct {
130 const char *name; 134 const char *name;
131 int code; 135 int code;
@@ -136,62 +140,6 @@ static const struct {
136 {"Inst & Mic", 0x0901} 140 {"Inst & Mic", 0x0901}
137}; 141};
138 142
139static bool toneport_has_led(enum line6_device_type type)
140{
141 return
142 (type == LINE6_GUITARPORT) ||
143 (type == LINE6_TONEPORT_GX);
144 /* add your device here if you are missing support for the LEDs */
145}
146
147static void toneport_update_led(struct device *dev)
148{
149 struct usb_interface *interface = to_usb_interface(dev);
150 struct usb_line6_toneport *tp = usb_get_intfdata(interface);
151 struct usb_line6 *line6;
152
153 if (!tp)
154 return;
155
156 line6 = &tp->line6;
157 if (line6)
158 toneport_send_cmd(line6->usbdev, (led_red << 8) | 0x0002,
159 led_green);
160}
161
162static ssize_t toneport_set_led_red(struct device *dev,
163 struct device_attribute *attr,
164 const char *buf, size_t count)
165{
166 int retval;
167
168 retval = kstrtoint(buf, 10, &led_red);
169 if (retval)
170 return retval;
171
172 toneport_update_led(dev);
173 return count;
174}
175
176static ssize_t toneport_set_led_green(struct device *dev,
177 struct device_attribute *attr,
178 const char *buf, size_t count)
179{
180 int retval;
181
182 retval = kstrtoint(buf, 10, &led_green);
183 if (retval)
184 return retval;
185
186 toneport_update_led(dev);
187 return count;
188}
189
190static DEVICE_ATTR(led_red, S_IWUSR | S_IRUGO, line6_nop_read,
191 toneport_set_led_red);
192static DEVICE_ATTR(led_green, S_IWUSR | S_IRUGO, line6_nop_read,
193 toneport_set_led_green);
194
195static int toneport_send_cmd(struct usb_device *usbdev, int cmd1, int cmd2) 143static int toneport_send_cmd(struct usb_device *usbdev, int cmd1, int cmd2)
196{ 144{
197 int ret; 145 int ret;
@@ -234,16 +182,23 @@ static int snd_toneport_monitor_put(struct snd_kcontrol *kcontrol,
234 struct snd_ctl_elem_value *ucontrol) 182 struct snd_ctl_elem_value *ucontrol)
235{ 183{
236 struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol); 184 struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol);
185 int err;
237 186
238 if (ucontrol->value.integer.value[0] == line6pcm->volume_monitor) 187 if (ucontrol->value.integer.value[0] == line6pcm->volume_monitor)
239 return 0; 188 return 0;
240 189
241 line6pcm->volume_monitor = ucontrol->value.integer.value[0]; 190 line6pcm->volume_monitor = ucontrol->value.integer.value[0];
242 191
243 if (line6pcm->volume_monitor > 0) 192 if (line6pcm->volume_monitor > 0) {
244 line6_pcm_acquire(line6pcm, LINE6_BITS_PCM_MONITOR); 193 err = line6_pcm_acquire(line6pcm, LINE6_STREAM_MONITOR);
245 else 194 if (err < 0) {
246 line6_pcm_release(line6pcm, LINE6_BITS_PCM_MONITOR); 195 line6pcm->volume_monitor = 0;
196 line6_pcm_release(line6pcm, LINE6_STREAM_MONITOR);
197 return err;
198 }
199 } else {
200 line6_pcm_release(line6pcm, LINE6_STREAM_MONITOR);
201 }
247 202
248 return 1; 203 return 1;
249} 204}
@@ -304,7 +259,7 @@ static void toneport_start_pcm(unsigned long arg)
304 struct usb_line6_toneport *toneport = (struct usb_line6_toneport *)arg; 259 struct usb_line6_toneport *toneport = (struct usb_line6_toneport *)arg;
305 struct usb_line6 *line6 = &toneport->line6; 260 struct usb_line6 *line6 = &toneport->line6;
306 261
307 line6_pcm_acquire(line6->line6pcm, LINE6_BITS_PCM_MONITOR); 262 line6_pcm_acquire(line6->line6pcm, LINE6_STREAM_MONITOR);
308} 263}
309 264
310/* control definition */ 265/* control definition */
@@ -330,6 +285,78 @@ static struct snd_kcontrol_new toneport_control_source = {
330}; 285};
331 286
332/* 287/*
288 For the led on Guitarport.
289 Brightness goes from 0x00 to 0x26. Set a value above this to have led
290 blink.
291 (void cmd_0x02(byte red, byte green)
292*/
293
294static bool toneport_has_led(enum line6_device_type type)
295{
296 return
297 (type == LINE6_GUITARPORT) ||
298 (type == LINE6_TONEPORT_GX);
299 /* add your device here if you are missing support for the LEDs */
300}
301
302static const char * const led_colors[2] = { "red", "green" };
303static const int led_init_vals[2] = { 0x00, 0x26 };
304
305static void toneport_update_led(struct usb_line6_toneport *toneport)
306{
307 toneport_send_cmd(toneport->line6.usbdev,
308 (toneport->leds[0].dev.brightness << 8) | 0x0002,
309 toneport->leds[1].dev.brightness);
310}
311
312static void toneport_led_brightness_set(struct led_classdev *led_cdev,
313 enum led_brightness brightness)
314{
315 struct toneport_led *leds =
316 container_of(led_cdev, struct toneport_led, dev);
317 toneport_update_led(leds->toneport);
318}
319
320static int toneport_init_leds(struct usb_line6_toneport *toneport)
321{
322 struct device *dev = &toneport->line6.usbdev->dev;
323 int i, err;
324
325 for (i = 0; i < 2; i++) {
326 struct toneport_led *led = &toneport->leds[i];
327 struct led_classdev *leddev = &led->dev;
328
329 led->toneport = toneport;
330 snprintf(led->name, sizeof(led->name), "%s::%s",
331 dev_name(dev), led_colors[i]);
332 leddev->name = led->name;
333 leddev->brightness = led_init_vals[i];
334 leddev->max_brightness = 0x26;
335 leddev->brightness_set = toneport_led_brightness_set;
336 err = led_classdev_register(dev, leddev);
337 if (err)
338 return err;
339 led->registered = true;
340 }
341
342 return 0;
343}
344
345static void toneport_remove_leds(struct usb_line6_toneport *toneport)
346{
347 struct toneport_led *led;
348 int i;
349
350 for (i = 0; i < 2; i++) {
351 led = &toneport->leds[i];
352 if (!led->registered)
353 break;
354 led_classdev_unregister(&led->dev);
355 led->registered = false;
356 }
357}
358
359/*
333 Setup Toneport device. 360 Setup Toneport device.
334*/ 361*/
335static void toneport_setup(struct usb_line6_toneport *toneport) 362static void toneport_setup(struct usb_line6_toneport *toneport)
@@ -359,42 +386,38 @@ static void toneport_setup(struct usb_line6_toneport *toneport)
359 } 386 }
360 387
361 if (toneport_has_led(toneport->type)) 388 if (toneport_has_led(toneport->type))
362 toneport_update_led(&usbdev->dev); 389 toneport_update_led(toneport);
390
391 mod_timer(&toneport->timer, jiffies + TONEPORT_PCM_DELAY * HZ);
363} 392}
364 393
365/* 394/*
366 Toneport device disconnected. 395 Toneport device disconnected.
367*/ 396*/
368static void line6_toneport_disconnect(struct usb_interface *interface) 397static void line6_toneport_disconnect(struct usb_line6 *line6)
369{ 398{
370 struct usb_line6_toneport *toneport; 399 struct usb_line6_toneport *toneport =
371 u16 idProduct; 400 (struct usb_line6_toneport *)line6;
372
373 if (interface == NULL)
374 return;
375 401
376 toneport = usb_get_intfdata(interface);
377 del_timer_sync(&toneport->timer); 402 del_timer_sync(&toneport->timer);
378 idProduct = le16_to_cpu(toneport->line6.usbdev->descriptor.idProduct);
379 403
380 if (toneport_has_led(idProduct)) { 404 if (toneport_has_led(toneport->type))
381 device_remove_file(&interface->dev, &dev_attr_led_red); 405 toneport_remove_leds(toneport);
382 device_remove_file(&interface->dev, &dev_attr_led_green);
383 }
384} 406}
385 407
386 408
387/* 409/*
388 Try to init Toneport device. 410 Try to init Toneport device.
389*/ 411*/
390static int toneport_init(struct usb_interface *interface, 412static int toneport_init(struct usb_line6 *line6,
391 struct usb_line6 *line6) 413 const struct usb_device_id *id)
392{ 414{
393 int err; 415 int err;
394 struct usb_line6_toneport *toneport = (struct usb_line6_toneport *) line6; 416 struct usb_line6_toneport *toneport = (struct usb_line6_toneport *) line6;
395 417
396 if ((interface == NULL) || (toneport == NULL)) 418 toneport->type = id->driver_info;
397 return -ENODEV; 419 setup_timer(&toneport->timer, toneport_start_pcm,
420 (unsigned long)toneport);
398 421
399 line6->disconnect = line6_toneport_disconnect; 422 line6->disconnect = line6_toneport_disconnect;
400 423
@@ -431,20 +454,13 @@ static int toneport_init(struct usb_interface *interface,
431 line6_read_data(line6, 0x80c2, &toneport->firmware_version, 1); 454 line6_read_data(line6, 0x80c2, &toneport->firmware_version, 1);
432 455
433 if (toneport_has_led(toneport->type)) { 456 if (toneport_has_led(toneport->type)) {
434 err = device_create_file(&interface->dev, &dev_attr_led_red); 457 err = toneport_init_leds(toneport);
435 if (err < 0)
436 return err;
437 err = device_create_file(&interface->dev, &dev_attr_led_green);
438 if (err < 0) 458 if (err < 0)
439 return err; 459 return err;
440 } 460 }
441 461
442 toneport_setup(toneport); 462 toneport_setup(toneport);
443 463
444 setup_timer(&toneport->timer, toneport_start_pcm,
445 (unsigned long)toneport);
446 mod_timer(&toneport->timer, jiffies + TONEPORT_PCM_DELAY * HZ);
447
448 /* register audio system: */ 464 /* register audio system: */
449 return snd_card_register(line6->card); 465 return snd_card_register(line6->card);
450} 466}
@@ -549,15 +565,9 @@ static const struct line6_properties toneport_properties_table[] = {
549static int toneport_probe(struct usb_interface *interface, 565static int toneport_probe(struct usb_interface *interface,
550 const struct usb_device_id *id) 566 const struct usb_device_id *id)
551{ 567{
552 struct usb_line6_toneport *toneport; 568 return line6_probe(interface, id,
553
554 toneport = kzalloc(sizeof(*toneport), GFP_KERNEL);
555 if (!toneport)
556 return -ENODEV;
557 toneport->type = id->driver_info;
558 return line6_probe(interface, &toneport->line6,
559 &toneport_properties_table[id->driver_info], 569 &toneport_properties_table[id->driver_info],
560 toneport_init); 570 toneport_init, sizeof(struct usb_line6_toneport));
561} 571}
562 572
563static struct usb_driver toneport_driver = { 573static struct usb_driver toneport_driver = {
diff --git a/sound/usb/line6/variax.c b/sound/usb/line6/variax.c
index 99a58cbfd2da..9701ffa61365 100644
--- a/sound/usb/line6/variax.c
+++ b/sound/usb/line6/variax.c
@@ -210,16 +210,9 @@ static void line6_variax_process_message(struct usb_line6 *line6)
210/* 210/*
211 Variax destructor. 211 Variax destructor.
212*/ 212*/
213static void line6_variax_disconnect(struct usb_interface *interface) 213static void line6_variax_disconnect(struct usb_line6 *line6)
214{ 214{
215 struct usb_line6_variax *variax; 215 struct usb_line6_variax *variax = (struct usb_line6_variax *)line6;
216
217 if (!interface)
218 return;
219
220 variax = usb_get_intfdata(interface);
221 if (!variax)
222 return;
223 216
224 del_timer(&variax->startup_timer1); 217 del_timer(&variax->startup_timer1);
225 del_timer(&variax->startup_timer2); 218 del_timer(&variax->startup_timer2);
@@ -231,8 +224,8 @@ static void line6_variax_disconnect(struct usb_interface *interface)
231/* 224/*
232 Try to init workbench device. 225 Try to init workbench device.
233*/ 226*/
234static int variax_init(struct usb_interface *interface, 227static int variax_init(struct usb_line6 *line6,
235 struct usb_line6 *line6) 228 const struct usb_device_id *id)
236{ 229{
237 struct usb_line6_variax *variax = (struct usb_line6_variax *) line6; 230 struct usb_line6_variax *variax = (struct usb_line6_variax *) line6;
238 int err; 231 int err;
@@ -244,9 +237,6 @@ static int variax_init(struct usb_interface *interface,
244 init_timer(&variax->startup_timer2); 237 init_timer(&variax->startup_timer2);
245 INIT_WORK(&variax->startup_work, variax_startup6); 238 INIT_WORK(&variax->startup_work, variax_startup6);
246 239
247 if ((interface == NULL) || (variax == NULL))
248 return -ENODEV;
249
250 /* initialize USB buffers: */ 240 /* initialize USB buffers: */
251 variax->buffer_activate = kmemdup(variax_activate, 241 variax->buffer_activate = kmemdup(variax_activate,
252 sizeof(variax_activate), GFP_KERNEL); 242 sizeof(variax_activate), GFP_KERNEL);
@@ -306,14 +296,9 @@ static const struct line6_properties variax_properties_table[] = {
306static int variax_probe(struct usb_interface *interface, 296static int variax_probe(struct usb_interface *interface,
307 const struct usb_device_id *id) 297 const struct usb_device_id *id)
308{ 298{
309 struct usb_line6_variax *variax; 299 return line6_probe(interface, id,
310
311 variax = kzalloc(sizeof(*variax), GFP_KERNEL);
312 if (!variax)
313 return -ENODEV;
314 return line6_probe(interface, &variax->line6,
315 &variax_properties_table[id->driver_info], 300 &variax_properties_table[id->driver_info],
316 variax_init); 301 variax_init, sizeof(struct usb_line6_variax));
317} 302}
318 303
319static struct usb_driver variax_driver = { 304static struct usb_driver variax_driver = {