diff options
author | Takashi Iwai <tiwai@suse.de> | 2015-01-19 09:54:00 -0500 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2015-01-20 02:17:16 -0500 |
commit | 85a9339becf0af4d547ceb6bb16d1893b05fbce4 (patch) | |
tree | 0f25a3def6f9aeca37f942c4aa70b88772a48259 /sound | |
parent | 84ac9bb12e8158e1affad4ae7718eb653fa5e36d (diff) |
ALSA: line6: Reorganize card resource handling
This is a fairly big rewrite regarding the card resource management in
line6 drivers:
- The card creation is moved into line6_probe(). This adds the global
destructor to private_free, so that each driver doesn't have to call
it any longer.
- The USB disconnect callback handles the card release, thus each
driver needs to concentrate on only its own resources. No need to
snd_card_*() call in the destructor.
- Fix the potential stall in disconnection by removing
snd_card_free(). It's replaced with snd_card_free_when_closed()
for asynchronous release.
- The only remaining operation for the card in each driver is the call
of snd_card_register(). All the rest are dealt in the common module
by itself.
- These ended up with removal of audio.[ch] as a result of a reduction
of one layer. Each driver just needs to call line6_probe().
Tested-by: Chris Rorvick <chris@rorvick.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound')
-rw-r--r-- | sound/usb/line6/Makefile | 1 | ||||
-rw-r--r-- | sound/usb/line6/audio.c | 74 | ||||
-rw-r--r-- | sound/usb/line6/audio.h | 21 | ||||
-rw-r--r-- | sound/usb/line6/capture.c | 1 | ||||
-rw-r--r-- | sound/usb/line6/driver.c | 82 | ||||
-rw-r--r-- | sound/usb/line6/midi.c | 1 | ||||
-rw-r--r-- | sound/usb/line6/pcm.c | 1 | ||||
-rw-r--r-- | sound/usb/line6/playback.c | 1 | ||||
-rw-r--r-- | sound/usb/line6/pod.c | 60 | ||||
-rw-r--r-- | sound/usb/line6/podhd.c | 75 | ||||
-rw-r--r-- | sound/usb/line6/toneport.c | 65 | ||||
-rw-r--r-- | sound/usb/line6/variax.c | 58 |
12 files changed, 85 insertions, 355 deletions
diff --git a/sound/usb/line6/Makefile b/sound/usb/line6/Makefile index fa3a78dac097..b8b3b2a543d8 100644 --- a/sound/usb/line6/Makefile +++ b/sound/usb/line6/Makefile | |||
@@ -1,5 +1,4 @@ | |||
1 | snd-usb-line6-y := \ | 1 | snd-usb-line6-y := \ |
2 | audio.o \ | ||
3 | capture.o \ | 2 | capture.o \ |
4 | driver.o \ | 3 | driver.o \ |
5 | midi.o \ | 4 | midi.o \ |
diff --git a/sound/usb/line6/audio.c b/sound/usb/line6/audio.c deleted file mode 100644 index 95686e5af4bd..000000000000 --- a/sound/usb/line6/audio.c +++ /dev/null | |||
@@ -1,74 +0,0 @@ | |||
1 | /* | ||
2 | * Line6 Linux USB driver - 0.9.1beta | ||
3 | * | ||
4 | * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at) | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License as | ||
8 | * published by the Free Software Foundation, version 2. | ||
9 | * | ||
10 | */ | ||
11 | |||
12 | #include <sound/core.h> | ||
13 | #include <sound/initval.h> | ||
14 | #include <linux/export.h> | ||
15 | |||
16 | #include "driver.h" | ||
17 | #include "audio.h" | ||
18 | |||
19 | /* | ||
20 | Initialize the Line6 USB audio system. | ||
21 | */ | ||
22 | int line6_init_audio(struct usb_line6 *line6) | ||
23 | { | ||
24 | struct snd_card *card; | ||
25 | int err; | ||
26 | |||
27 | err = snd_card_new(line6->ifcdev, | ||
28 | SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1, | ||
29 | THIS_MODULE, 0, &card); | ||
30 | if (err < 0) | ||
31 | return err; | ||
32 | |||
33 | line6->card = card; | ||
34 | |||
35 | strcpy(card->id, line6->properties->id); | ||
36 | strcpy(card->driver, DRIVER_NAME); | ||
37 | strcpy(card->shortname, line6->properties->name); | ||
38 | /* longname is 80 chars - see asound.h */ | ||
39 | sprintf(card->longname, "Line6 %s at USB %s", line6->properties->name, | ||
40 | dev_name(line6->ifcdev)); | ||
41 | return 0; | ||
42 | } | ||
43 | EXPORT_SYMBOL_GPL(line6_init_audio); | ||
44 | |||
45 | /* | ||
46 | Register the Line6 USB audio system. | ||
47 | */ | ||
48 | int line6_register_audio(struct usb_line6 *line6) | ||
49 | { | ||
50 | int err; | ||
51 | |||
52 | err = snd_card_register(line6->card); | ||
53 | if (err < 0) | ||
54 | return err; | ||
55 | |||
56 | return 0; | ||
57 | } | ||
58 | EXPORT_SYMBOL_GPL(line6_register_audio); | ||
59 | |||
60 | /* | ||
61 | Cleanup the Line6 USB audio system. | ||
62 | */ | ||
63 | void line6_cleanup_audio(struct usb_line6 *line6) | ||
64 | { | ||
65 | struct snd_card *card = line6->card; | ||
66 | |||
67 | if (card == NULL) | ||
68 | return; | ||
69 | |||
70 | snd_card_disconnect(card); | ||
71 | snd_card_free(card); | ||
72 | line6->card = NULL; | ||
73 | } | ||
74 | EXPORT_SYMBOL_GPL(line6_cleanup_audio); | ||
diff --git a/sound/usb/line6/audio.h b/sound/usb/line6/audio.h deleted file mode 100644 index 5f8a09a0fa95..000000000000 --- a/sound/usb/line6/audio.h +++ /dev/null | |||
@@ -1,21 +0,0 @@ | |||
1 | /* | ||
2 | * Line6 Linux USB driver - 0.9.1beta | ||
3 | * | ||
4 | * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at) | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License as | ||
8 | * published by the Free Software Foundation, version 2. | ||
9 | * | ||
10 | */ | ||
11 | |||
12 | #ifndef AUDIO_H | ||
13 | #define AUDIO_H | ||
14 | |||
15 | #include "driver.h" | ||
16 | |||
17 | extern void line6_cleanup_audio(struct usb_line6 *); | ||
18 | extern int line6_init_audio(struct usb_line6 *); | ||
19 | extern int line6_register_audio(struct usb_line6 *); | ||
20 | |||
21 | #endif | ||
diff --git a/sound/usb/line6/capture.c b/sound/usb/line6/capture.c index 727b31876d48..e8c54ede9227 100644 --- a/sound/usb/line6/capture.c +++ b/sound/usb/line6/capture.c | |||
@@ -14,7 +14,6 @@ | |||
14 | #include <sound/pcm.h> | 14 | #include <sound/pcm.h> |
15 | #include <sound/pcm_params.h> | 15 | #include <sound/pcm_params.h> |
16 | 16 | ||
17 | #include "audio.h" | ||
18 | #include "capture.h" | 17 | #include "capture.h" |
19 | #include "driver.h" | 18 | #include "driver.h" |
20 | #include "pcm.h" | 19 | #include "pcm.h" |
diff --git a/sound/usb/line6/driver.c b/sound/usb/line6/driver.c index b8f5134dcec2..8b6a658a8a58 100644 --- a/sound/usb/line6/driver.c +++ b/sound/usb/line6/driver.c | |||
@@ -15,7 +15,9 @@ | |||
15 | #include <linux/slab.h> | 15 | #include <linux/slab.h> |
16 | #include <linux/usb.h> | 16 | #include <linux/usb.h> |
17 | 17 | ||
18 | #include "audio.h" | 18 | #include <sound/core.h> |
19 | #include <sound/initval.h> | ||
20 | |||
19 | #include "capture.h" | 21 | #include "capture.h" |
20 | #include "driver.h" | 22 | #include "driver.h" |
21 | #include "midi.h" | 23 | #include "midi.h" |
@@ -481,17 +483,16 @@ ssize_t line6_nop_read(struct device *dev, struct device_attribute *attr, | |||
481 | EXPORT_SYMBOL_GPL(line6_nop_read); | 483 | EXPORT_SYMBOL_GPL(line6_nop_read); |
482 | 484 | ||
483 | /* | 485 | /* |
484 | Generic destructor. | 486 | Card destructor. |
485 | */ | 487 | */ |
486 | static void line6_destruct(struct usb_interface *interface) | 488 | static void line6_destruct(struct snd_card *card) |
487 | { | 489 | { |
488 | struct usb_line6 *line6; | 490 | struct usb_line6 *line6 = card->private_data; |
491 | struct usb_device *usbdev; | ||
489 | 492 | ||
490 | if (interface == NULL) | 493 | if (!line6) |
491 | return; | ||
492 | line6 = usb_get_intfdata(interface); | ||
493 | if (line6 == NULL) | ||
494 | return; | 494 | return; |
495 | usbdev = line6->usbdev; | ||
495 | 496 | ||
496 | /* free buffer memory first: */ | 497 | /* free buffer memory first: */ |
497 | kfree(line6->buffer_message); | 498 | kfree(line6->buffer_message); |
@@ -500,8 +501,11 @@ static void line6_destruct(struct usb_interface *interface) | |||
500 | /* then free URBs: */ | 501 | /* then free URBs: */ |
501 | usb_free_urb(line6->urb_listen); | 502 | usb_free_urb(line6->urb_listen); |
502 | 503 | ||
503 | /* make sure the device isn't destructed twice: */ | 504 | /* free interface data: */ |
504 | usb_set_intfdata(interface, NULL); | 505 | kfree(line6); |
506 | |||
507 | /* decrement reference counters: */ | ||
508 | usb_put_dev(usbdev); | ||
505 | } | 509 | } |
506 | 510 | ||
507 | /* | 511 | /* |
@@ -513,6 +517,7 @@ int line6_probe(struct usb_interface *interface, | |||
513 | int (*private_init)(struct usb_interface *, struct usb_line6 *)) | 517 | int (*private_init)(struct usb_interface *, struct usb_line6 *)) |
514 | { | 518 | { |
515 | struct usb_device *usbdev; | 519 | struct usb_device *usbdev; |
520 | struct snd_card *card; | ||
516 | int interface_number; | 521 | int interface_number; |
517 | int ret; | 522 | int ret; |
518 | 523 | ||
@@ -569,8 +574,26 @@ int line6_probe(struct usb_interface *interface, | |||
569 | } | 574 | } |
570 | } | 575 | } |
571 | 576 | ||
577 | ret = snd_card_new(line6->ifcdev, | ||
578 | SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1, | ||
579 | THIS_MODULE, 0, &card); | ||
580 | if (ret < 0) | ||
581 | goto err_put; | ||
582 | |||
583 | line6->card = card; | ||
584 | strcpy(card->id, line6->properties->id); | ||
585 | strcpy(card->driver, DRIVER_NAME); | ||
586 | strcpy(card->shortname, line6->properties->name); | ||
587 | sprintf(card->longname, "Line6 %s at USB %s", line6->properties->name, | ||
588 | dev_name(line6->ifcdev)); | ||
589 | card->private_data = line6; | ||
590 | card->private_free = line6_destruct; | ||
591 | |||
572 | usb_set_intfdata(interface, line6); | 592 | usb_set_intfdata(interface, line6); |
573 | 593 | ||
594 | /* increment reference counters: */ | ||
595 | usb_get_dev(usbdev); | ||
596 | |||
574 | if (properties->capabilities & LINE6_CAP_CONTROL) { | 597 | if (properties->capabilities & LINE6_CAP_CONTROL) { |
575 | /* initialize USB buffers: */ | 598 | /* initialize USB buffers: */ |
576 | line6->buffer_listen = | 599 | line6->buffer_listen = |
@@ -612,15 +635,11 @@ int line6_probe(struct usb_interface *interface, | |||
612 | dev_info(&interface->dev, "Line6 %s now attached\n", | 635 | dev_info(&interface->dev, "Line6 %s now attached\n", |
613 | line6->properties->name); | 636 | line6->properties->name); |
614 | 637 | ||
615 | /* increment reference counters: */ | ||
616 | usb_get_intf(interface); | ||
617 | usb_get_dev(usbdev); | ||
618 | |||
619 | return 0; | 638 | return 0; |
620 | 639 | ||
621 | err_destruct: | 640 | err_destruct: |
622 | line6_destruct(interface); | 641 | snd_card_free(card); |
623 | err_put: | 642 | err_put: |
624 | return ret; | 643 | return ret; |
625 | } | 644 | } |
626 | EXPORT_SYMBOL_GPL(line6_probe); | 645 | EXPORT_SYMBOL_GPL(line6_probe); |
@@ -642,29 +661,26 @@ void line6_disconnect(struct usb_interface *interface) | |||
642 | 661 | ||
643 | interface_number = interface->cur_altsetting->desc.bInterfaceNumber; | 662 | interface_number = interface->cur_altsetting->desc.bInterfaceNumber; |
644 | line6 = usb_get_intfdata(interface); | 663 | line6 = usb_get_intfdata(interface); |
664 | if (!line6) | ||
665 | return; | ||
645 | 666 | ||
646 | if (line6 != NULL) { | 667 | if (line6->urb_listen != NULL) |
647 | if (line6->urb_listen != NULL) | 668 | line6_stop_listen(line6); |
648 | line6_stop_listen(line6); | ||
649 | 669 | ||
650 | if (usbdev != line6->usbdev) | 670 | if (usbdev != line6->usbdev) |
651 | dev_err(line6->ifcdev, | 671 | dev_err(line6->ifcdev, "driver bug: inconsistent usb device\n"); |
652 | "driver bug: inconsistent usb device\n"); | ||
653 | 672 | ||
673 | snd_card_disconnect(line6->card); | ||
674 | if (line6->disconnect) | ||
654 | line6->disconnect(interface); | 675 | line6->disconnect(interface); |
655 | 676 | ||
656 | dev_info(&interface->dev, "Line6 %s now disconnected\n", | 677 | dev_info(&interface->dev, "Line6 %s now disconnected\n", |
657 | line6->properties->name); | 678 | line6->properties->name); |
658 | } | ||
659 | |||
660 | line6_destruct(interface); | ||
661 | 679 | ||
662 | /* free interface data: */ | 680 | /* make sure the device isn't destructed twice: */ |
663 | kfree(line6); | 681 | usb_set_intfdata(interface, NULL); |
664 | 682 | ||
665 | /* decrement reference counters: */ | 683 | snd_card_free_when_closed(line6->card); |
666 | usb_put_intf(interface); | ||
667 | usb_put_dev(usbdev); | ||
668 | } | 684 | } |
669 | EXPORT_SYMBOL_GPL(line6_disconnect); | 685 | EXPORT_SYMBOL_GPL(line6_disconnect); |
670 | 686 | ||
diff --git a/sound/usb/line6/midi.c b/sound/usb/line6/midi.c index f333cef5d2d7..68793cc5dc1e 100644 --- a/sound/usb/line6/midi.c +++ b/sound/usb/line6/midi.c | |||
@@ -15,7 +15,6 @@ | |||
15 | #include <sound/core.h> | 15 | #include <sound/core.h> |
16 | #include <sound/rawmidi.h> | 16 | #include <sound/rawmidi.h> |
17 | 17 | ||
18 | #include "audio.h" | ||
19 | #include "driver.h" | 18 | #include "driver.h" |
20 | #include "midi.h" | 19 | #include "midi.h" |
21 | #include "usbdefs.h" | 20 | #include "usbdefs.h" |
diff --git a/sound/usb/line6/pcm.c b/sound/usb/line6/pcm.c index edab3cd7c048..1e77d0d9da17 100644 --- a/sound/usb/line6/pcm.c +++ b/sound/usb/line6/pcm.c | |||
@@ -16,7 +16,6 @@ | |||
16 | #include <sound/pcm.h> | 16 | #include <sound/pcm.h> |
17 | #include <sound/pcm_params.h> | 17 | #include <sound/pcm_params.h> |
18 | 18 | ||
19 | #include "audio.h" | ||
20 | #include "capture.h" | 19 | #include "capture.h" |
21 | #include "driver.h" | 20 | #include "driver.h" |
22 | #include "playback.h" | 21 | #include "playback.h" |
diff --git a/sound/usb/line6/playback.c b/sound/usb/line6/playback.c index 5a7fe409a3b9..ec2384c875a7 100644 --- a/sound/usb/line6/playback.c +++ b/sound/usb/line6/playback.c | |||
@@ -14,7 +14,6 @@ | |||
14 | #include <sound/pcm.h> | 14 | #include <sound/pcm.h> |
15 | #include <sound/pcm_params.h> | 15 | #include <sound/pcm_params.h> |
16 | 16 | ||
17 | #include "audio.h" | ||
18 | #include "capture.h" | 17 | #include "capture.h" |
19 | #include "driver.h" | 18 | #include "driver.h" |
20 | #include "pcm.h" | 19 | #include "pcm.h" |
diff --git a/sound/usb/line6/pod.c b/sound/usb/line6/pod.c index d6bc5a1ab7f4..6b30deb6b157 100644 --- a/sound/usb/line6/pod.c +++ b/sound/usb/line6/pod.c | |||
@@ -18,7 +18,6 @@ | |||
18 | #include <sound/core.h> | 18 | #include <sound/core.h> |
19 | #include <sound/control.h> | 19 | #include <sound/control.h> |
20 | 20 | ||
21 | #include "audio.h" | ||
22 | #include "capture.h" | 21 | #include "capture.h" |
23 | #include "driver.h" | 22 | #include "driver.h" |
24 | #include "playback.h" | 23 | #include "playback.h" |
@@ -340,7 +339,7 @@ static void pod_startup4(struct work_struct *work) | |||
340 | line6_read_serial_number(&pod->line6, &pod->serial_number); | 339 | line6_read_serial_number(&pod->line6, &pod->serial_number); |
341 | 340 | ||
342 | /* ALSA audio interface: */ | 341 | /* ALSA audio interface: */ |
343 | line6_register_audio(line6); | 342 | snd_card_register(line6->card); |
344 | } | 343 | } |
345 | 344 | ||
346 | /* POD special files: */ | 345 | /* POD special files: */ |
@@ -398,21 +397,6 @@ static struct snd_kcontrol_new pod_control_monitor = { | |||
398 | }; | 397 | }; |
399 | 398 | ||
400 | /* | 399 | /* |
401 | POD destructor. | ||
402 | */ | ||
403 | static void pod_destruct(struct usb_interface *interface) | ||
404 | { | ||
405 | struct usb_line6_pod *pod = usb_get_intfdata(interface); | ||
406 | |||
407 | if (pod == NULL) | ||
408 | return; | ||
409 | line6_cleanup_audio(&pod->line6); | ||
410 | |||
411 | del_timer(&pod->startup_timer); | ||
412 | cancel_work_sync(&pod->startup_work); | ||
413 | } | ||
414 | |||
415 | /* | ||
416 | POD device disconnected. | 400 | POD device disconnected. |
417 | */ | 401 | */ |
418 | static void line6_pod_disconnect(struct usb_interface *interface) | 402 | static void line6_pod_disconnect(struct usb_interface *interface) |
@@ -424,21 +408,18 @@ static void line6_pod_disconnect(struct usb_interface *interface) | |||
424 | pod = usb_get_intfdata(interface); | 408 | pod = usb_get_intfdata(interface); |
425 | 409 | ||
426 | if (pod != NULL) { | 410 | if (pod != NULL) { |
427 | struct snd_line6_pcm *line6pcm = pod->line6.line6pcm; | ||
428 | struct device *dev = &interface->dev; | 411 | struct device *dev = &interface->dev; |
429 | 412 | ||
430 | if (line6pcm != NULL) | ||
431 | line6_pcm_disconnect(line6pcm); | ||
432 | |||
433 | if (dev != NULL) { | 413 | if (dev != NULL) { |
434 | /* remove sysfs entries: */ | 414 | /* remove sysfs entries: */ |
435 | device_remove_file(dev, &dev_attr_device_id); | 415 | device_remove_file(dev, &dev_attr_device_id); |
436 | device_remove_file(dev, &dev_attr_firmware_version); | 416 | device_remove_file(dev, &dev_attr_firmware_version); |
437 | device_remove_file(dev, &dev_attr_serial_number); | 417 | device_remove_file(dev, &dev_attr_serial_number); |
438 | } | 418 | } |
439 | } | ||
440 | 419 | ||
441 | pod_destruct(interface); | 420 | del_timer_sync(&pod->startup_timer); |
421 | cancel_work_sync(&pod->startup_work); | ||
422 | } | ||
442 | } | 423 | } |
443 | 424 | ||
444 | /* | 425 | /* |
@@ -457,8 +438,8 @@ static int pod_create_files2(struct device *dev) | |||
457 | /* | 438 | /* |
458 | Try to init POD device. | 439 | Try to init POD device. |
459 | */ | 440 | */ |
460 | static int pod_try_init(struct usb_interface *interface, | 441 | static int pod_init(struct usb_interface *interface, |
461 | struct usb_line6 *line6) | 442 | struct usb_line6 *line6) |
462 | { | 443 | { |
463 | int err; | 444 | int err; |
464 | struct usb_line6_pod *pod = (struct usb_line6_pod *) line6; | 445 | struct usb_line6_pod *pod = (struct usb_line6_pod *) line6; |
@@ -477,11 +458,6 @@ static int pod_try_init(struct usb_interface *interface, | |||
477 | if (err < 0) | 458 | if (err < 0) |
478 | return err; | 459 | return err; |
479 | 460 | ||
480 | /* initialize audio system: */ | ||
481 | err = line6_init_audio(line6); | ||
482 | if (err < 0) | ||
483 | return err; | ||
484 | |||
485 | /* initialize MIDI subsystem: */ | 461 | /* initialize MIDI subsystem: */ |
486 | err = line6_init_midi(line6); | 462 | err = line6_init_midi(line6); |
487 | if (err < 0) | 463 | if (err < 0) |
@@ -514,20 +490,6 @@ static int pod_try_init(struct usb_interface *interface, | |||
514 | return 0; | 490 | return 0; |
515 | } | 491 | } |
516 | 492 | ||
517 | /* | ||
518 | Init POD device (and clean up in case of failure). | ||
519 | */ | ||
520 | static int pod_init(struct usb_interface *interface, | ||
521 | struct usb_line6 *line6) | ||
522 | { | ||
523 | int err = pod_try_init(interface, line6); | ||
524 | |||
525 | if (err < 0) | ||
526 | pod_destruct(interface); | ||
527 | |||
528 | return err; | ||
529 | } | ||
530 | |||
531 | #define LINE6_DEVICE(prod) USB_DEVICE(0x0e41, prod) | 493 | #define LINE6_DEVICE(prod) USB_DEVICE(0x0e41, prod) |
532 | #define LINE6_IF_NUM(prod, n) USB_DEVICE_INTERFACE_NUMBER(0x0e41, prod, n) | 494 | #define LINE6_IF_NUM(prod, n) USB_DEVICE_INTERFACE_NUMBER(0x0e41, prod, n) |
533 | 495 | ||
@@ -636,17 +598,13 @@ static int pod_probe(struct usb_interface *interface, | |||
636 | const struct usb_device_id *id) | 598 | const struct usb_device_id *id) |
637 | { | 599 | { |
638 | struct usb_line6_pod *pod; | 600 | struct usb_line6_pod *pod; |
639 | int err; | ||
640 | 601 | ||
641 | pod = kzalloc(sizeof(*pod), GFP_KERNEL); | 602 | pod = kzalloc(sizeof(*pod), GFP_KERNEL); |
642 | if (!pod) | 603 | if (!pod) |
643 | return -ENODEV; | 604 | return -ENODEV; |
644 | err = line6_probe(interface, &pod->line6, | 605 | return line6_probe(interface, &pod->line6, |
645 | &pod_properties_table[id->driver_info], | 606 | &pod_properties_table[id->driver_info], |
646 | pod_init); | 607 | pod_init); |
647 | if (err < 0) | ||
648 | kfree(pod); | ||
649 | return err; | ||
650 | } | 608 | } |
651 | 609 | ||
652 | static struct usb_driver pod_driver = { | 610 | static struct usb_driver pod_driver = { |
diff --git a/sound/usb/line6/podhd.c b/sound/usb/line6/podhd.c index 8f4ca1d20b62..1d11185780e3 100644 --- a/sound/usb/line6/podhd.c +++ b/sound/usb/line6/podhd.c | |||
@@ -15,7 +15,6 @@ | |||
15 | #include <sound/core.h> | 15 | #include <sound/core.h> |
16 | #include <sound/pcm.h> | 16 | #include <sound/pcm.h> |
17 | 17 | ||
18 | #include "audio.h" | ||
19 | #include "driver.h" | 18 | #include "driver.h" |
20 | #include "pcm.h" | 19 | #include "pcm.h" |
21 | #include "usbdefs.h" | 20 | #include "usbdefs.h" |
@@ -86,57 +85,17 @@ static struct line6_pcm_properties podhd_pcm_properties = { | |||
86 | }; | 85 | }; |
87 | 86 | ||
88 | /* | 87 | /* |
89 | POD HD destructor. | ||
90 | */ | ||
91 | static void podhd_destruct(struct usb_interface *interface) | ||
92 | { | ||
93 | struct usb_line6_podhd *podhd = usb_get_intfdata(interface); | ||
94 | |||
95 | if (podhd == NULL) | ||
96 | return; | ||
97 | line6_cleanup_audio(&podhd->line6); | ||
98 | } | ||
99 | |||
100 | /* | ||
101 | POD HD device disconnected. | ||
102 | */ | ||
103 | static void line6_podhd_disconnect(struct usb_interface *interface) | ||
104 | { | ||
105 | struct usb_line6_podhd *podhd; | ||
106 | |||
107 | if (interface == NULL) | ||
108 | return; | ||
109 | podhd = usb_get_intfdata(interface); | ||
110 | |||
111 | if (podhd != NULL) { | ||
112 | struct snd_line6_pcm *line6pcm = podhd->line6.line6pcm; | ||
113 | |||
114 | if (line6pcm != NULL) | ||
115 | line6_pcm_disconnect(line6pcm); | ||
116 | } | ||
117 | |||
118 | podhd_destruct(interface); | ||
119 | } | ||
120 | |||
121 | /* | ||
122 | Try to init POD HD device. | 88 | Try to init POD HD device. |
123 | */ | 89 | */ |
124 | static int podhd_try_init(struct usb_interface *interface, | 90 | static int podhd_init(struct usb_interface *interface, |
125 | struct usb_line6_podhd *podhd) | 91 | struct usb_line6 *line6) |
126 | { | 92 | { |
93 | struct usb_line6_podhd *podhd = (struct usb_line6_podhd *) line6; | ||
127 | int err; | 94 | int err; |
128 | struct usb_line6 *line6 = &podhd->line6; | ||
129 | 95 | ||
130 | if ((interface == NULL) || (podhd == NULL)) | 96 | if ((interface == NULL) || (podhd == NULL)) |
131 | return -ENODEV; | 97 | return -ENODEV; |
132 | 98 | ||
133 | line6->disconnect = line6_podhd_disconnect; | ||
134 | |||
135 | /* initialize audio system: */ | ||
136 | err = line6_init_audio(line6); | ||
137 | if (err < 0) | ||
138 | return err; | ||
139 | |||
140 | /* initialize MIDI subsystem: */ | 99 | /* initialize MIDI subsystem: */ |
141 | err = line6_init_midi(line6); | 100 | err = line6_init_midi(line6); |
142 | if (err < 0) | 101 | if (err < 0) |
@@ -148,8 +107,7 @@ static int podhd_try_init(struct usb_interface *interface, | |||
148 | return err; | 107 | return err; |
149 | 108 | ||
150 | /* register USB audio system: */ | 109 | /* register USB audio system: */ |
151 | err = line6_register_audio(line6); | 110 | return snd_card_register(line6->card); |
152 | return err; | ||
153 | } | 111 | } |
154 | 112 | ||
155 | #define LINE6_DEVICE(prod) USB_DEVICE(0x0e41, prod) | 113 | #define LINE6_DEVICE(prod) USB_DEVICE(0x0e41, prod) |
@@ -218,38 +176,19 @@ static const struct line6_properties podhd_properties_table[] = { | |||
218 | }; | 176 | }; |
219 | 177 | ||
220 | /* | 178 | /* |
221 | Init POD HD device (and clean up in case of failure). | ||
222 | */ | ||
223 | static int podhd_init(struct usb_interface *interface, | ||
224 | struct usb_line6 *line6) | ||
225 | { | ||
226 | struct usb_line6_podhd *podhd = (struct usb_line6_podhd *) line6; | ||
227 | int err = podhd_try_init(interface, podhd); | ||
228 | |||
229 | if (err < 0) | ||
230 | podhd_destruct(interface); | ||
231 | |||
232 | return err; | ||
233 | } | ||
234 | |||
235 | /* | ||
236 | Probe USB device. | 179 | Probe USB device. |
237 | */ | 180 | */ |
238 | static int podhd_probe(struct usb_interface *interface, | 181 | static int podhd_probe(struct usb_interface *interface, |
239 | const struct usb_device_id *id) | 182 | const struct usb_device_id *id) |
240 | { | 183 | { |
241 | struct usb_line6_podhd *podhd; | 184 | struct usb_line6_podhd *podhd; |
242 | int err; | ||
243 | 185 | ||
244 | podhd = kzalloc(sizeof(*podhd), GFP_KERNEL); | 186 | podhd = kzalloc(sizeof(*podhd), GFP_KERNEL); |
245 | if (!podhd) | 187 | if (!podhd) |
246 | return -ENODEV; | 188 | return -ENODEV; |
247 | err = line6_probe(interface, &podhd->line6, | 189 | return line6_probe(interface, &podhd->line6, |
248 | &podhd_properties_table[id->driver_info], | 190 | &podhd_properties_table[id->driver_info], |
249 | podhd_init); | 191 | podhd_init); |
250 | if (err < 0) | ||
251 | kfree(podhd); | ||
252 | return err; | ||
253 | } | 192 | } |
254 | 193 | ||
255 | static struct usb_driver podhd_driver = { | 194 | static struct usb_driver podhd_driver = { |
diff --git a/sound/usb/line6/toneport.c b/sound/usb/line6/toneport.c index 6ec3268a6153..3097a75a9bec 100644 --- a/sound/usb/line6/toneport.c +++ b/sound/usb/line6/toneport.c | |||
@@ -17,7 +17,6 @@ | |||
17 | #include <sound/core.h> | 17 | #include <sound/core.h> |
18 | #include <sound/control.h> | 18 | #include <sound/control.h> |
19 | 19 | ||
20 | #include "audio.h" | ||
21 | #include "capture.h" | 20 | #include "capture.h" |
22 | #include "driver.h" | 21 | #include "driver.h" |
23 | #include "playback.h" | 22 | #include "playback.h" |
@@ -331,18 +330,6 @@ static struct snd_kcontrol_new toneport_control_source = { | |||
331 | }; | 330 | }; |
332 | 331 | ||
333 | /* | 332 | /* |
334 | Toneport destructor. | ||
335 | */ | ||
336 | static void toneport_destruct(struct usb_interface *interface) | ||
337 | { | ||
338 | struct usb_line6_toneport *toneport = usb_get_intfdata(interface); | ||
339 | |||
340 | if (toneport == NULL) | ||
341 | return; | ||
342 | line6_cleanup_audio(&toneport->line6); | ||
343 | } | ||
344 | |||
345 | /* | ||
346 | Setup Toneport device. | 333 | Setup Toneport device. |
347 | */ | 334 | */ |
348 | static void toneport_setup(struct usb_line6_toneport *toneport) | 335 | static void toneport_setup(struct usb_line6_toneport *toneport) |
@@ -394,25 +381,14 @@ static void line6_toneport_disconnect(struct usb_interface *interface) | |||
394 | device_remove_file(&interface->dev, &dev_attr_led_red); | 381 | device_remove_file(&interface->dev, &dev_attr_led_red); |
395 | device_remove_file(&interface->dev, &dev_attr_led_green); | 382 | device_remove_file(&interface->dev, &dev_attr_led_green); |
396 | } | 383 | } |
397 | |||
398 | if (toneport != NULL) { | ||
399 | struct snd_line6_pcm *line6pcm = toneport->line6.line6pcm; | ||
400 | |||
401 | if (line6pcm != NULL) { | ||
402 | line6_pcm_release(line6pcm, LINE6_BITS_PCM_MONITOR); | ||
403 | line6_pcm_disconnect(line6pcm); | ||
404 | } | ||
405 | } | ||
406 | |||
407 | toneport_destruct(interface); | ||
408 | } | 384 | } |
409 | 385 | ||
410 | 386 | ||
411 | /* | 387 | /* |
412 | Try to init Toneport device. | 388 | Try to init Toneport device. |
413 | */ | 389 | */ |
414 | static int toneport_try_init(struct usb_interface *interface, | 390 | static int toneport_init(struct usb_interface *interface, |
415 | struct usb_line6 *line6) | 391 | struct usb_line6 *line6) |
416 | { | 392 | { |
417 | int err; | 393 | int err; |
418 | struct usb_line6_toneport *toneport = (struct usb_line6_toneport *) line6; | 394 | struct usb_line6_toneport *toneport = (struct usb_line6_toneport *) line6; |
@@ -422,11 +398,6 @@ static int toneport_try_init(struct usb_interface *interface, | |||
422 | 398 | ||
423 | line6->disconnect = line6_toneport_disconnect; | 399 | line6->disconnect = line6_toneport_disconnect; |
424 | 400 | ||
425 | /* initialize audio system: */ | ||
426 | err = line6_init_audio(line6); | ||
427 | if (err < 0) | ||
428 | return err; | ||
429 | |||
430 | /* initialize PCM subsystem: */ | 401 | /* initialize PCM subsystem: */ |
431 | err = line6_init_pcm(line6, &toneport_pcm_properties); | 402 | err = line6_init_pcm(line6, &toneport_pcm_properties); |
432 | if (err < 0) | 403 | if (err < 0) |
@@ -456,11 +427,6 @@ static int toneport_try_init(struct usb_interface *interface, | |||
456 | break; | 427 | break; |
457 | } | 428 | } |
458 | 429 | ||
459 | /* register audio system: */ | ||
460 | err = line6_register_audio(line6); | ||
461 | if (err < 0) | ||
462 | return err; | ||
463 | |||
464 | line6_read_serial_number(line6, &toneport->serial_number); | 430 | line6_read_serial_number(line6, &toneport->serial_number); |
465 | line6_read_data(line6, 0x80c2, &toneport->firmware_version, 1); | 431 | line6_read_data(line6, 0x80c2, &toneport->firmware_version, 1); |
466 | 432 | ||
@@ -477,21 +443,8 @@ static int toneport_try_init(struct usb_interface *interface, | |||
477 | (unsigned long)toneport); | 443 | (unsigned long)toneport); |
478 | mod_timer(&toneport->timer, jiffies + TONEPORT_PCM_DELAY * HZ); | 444 | mod_timer(&toneport->timer, jiffies + TONEPORT_PCM_DELAY * HZ); |
479 | 445 | ||
480 | return 0; | 446 | /* register audio system: */ |
481 | } | 447 | return snd_card_register(line6->card); |
482 | |||
483 | /* | ||
484 | Init Toneport device (and clean up in case of failure). | ||
485 | */ | ||
486 | static int toneport_init(struct usb_interface *interface, | ||
487 | struct usb_line6 *line6) | ||
488 | { | ||
489 | int err = toneport_try_init(interface, line6); | ||
490 | |||
491 | if (err < 0) | ||
492 | toneport_destruct(interface); | ||
493 | |||
494 | return err; | ||
495 | } | 448 | } |
496 | 449 | ||
497 | #ifdef CONFIG_PM | 450 | #ifdef CONFIG_PM |
@@ -595,18 +548,14 @@ static int toneport_probe(struct usb_interface *interface, | |||
595 | const struct usb_device_id *id) | 548 | const struct usb_device_id *id) |
596 | { | 549 | { |
597 | struct usb_line6_toneport *toneport; | 550 | struct usb_line6_toneport *toneport; |
598 | int err; | ||
599 | 551 | ||
600 | toneport = kzalloc(sizeof(*toneport), GFP_KERNEL); | 552 | toneport = kzalloc(sizeof(*toneport), GFP_KERNEL); |
601 | if (!toneport) | 553 | if (!toneport) |
602 | return -ENODEV; | 554 | return -ENODEV; |
603 | toneport->type = id->driver_info; | 555 | toneport->type = id->driver_info; |
604 | err = line6_probe(interface, &toneport->line6, | 556 | return line6_probe(interface, &toneport->line6, |
605 | &toneport_properties_table[id->driver_info], | 557 | &toneport_properties_table[id->driver_info], |
606 | toneport_init); | 558 | toneport_init); |
607 | if (err < 0) | ||
608 | kfree(toneport); | ||
609 | return err; | ||
610 | } | 559 | } |
611 | 560 | ||
612 | static struct usb_driver toneport_driver = { | 561 | static struct usb_driver toneport_driver = { |
diff --git a/sound/usb/line6/variax.c b/sound/usb/line6/variax.c index 9a9c7e48e24f..a591c2c5794f 100644 --- a/sound/usb/line6/variax.c +++ b/sound/usb/line6/variax.c | |||
@@ -16,7 +16,6 @@ | |||
16 | #include <linux/module.h> | 16 | #include <linux/module.h> |
17 | #include <sound/core.h> | 17 | #include <sound/core.h> |
18 | 18 | ||
19 | #include "audio.h" | ||
20 | #include "driver.h" | 19 | #include "driver.h" |
21 | #include "usbdefs.h" | 20 | #include "usbdefs.h" |
22 | 21 | ||
@@ -179,7 +178,7 @@ static void variax_startup6(struct work_struct *work) | |||
179 | CHECK_STARTUP_PROGRESS(variax->startup_progress, VARIAX_STARTUP_SETUP); | 178 | CHECK_STARTUP_PROGRESS(variax->startup_progress, VARIAX_STARTUP_SETUP); |
180 | 179 | ||
181 | /* ALSA audio interface: */ | 180 | /* ALSA audio interface: */ |
182 | line6_register_audio(&variax->line6); | 181 | snd_card_register(variax->line6.card); |
183 | } | 182 | } |
184 | 183 | ||
185 | /* | 184 | /* |
@@ -211,13 +210,16 @@ static void line6_variax_process_message(struct usb_line6 *line6) | |||
211 | /* | 210 | /* |
212 | Variax destructor. | 211 | Variax destructor. |
213 | */ | 212 | */ |
214 | static void variax_destruct(struct usb_interface *interface) | 213 | static void line6_variax_disconnect(struct usb_interface *interface) |
215 | { | 214 | { |
216 | struct usb_line6_variax *variax = usb_get_intfdata(interface); | 215 | struct usb_line6_variax *variax; |
216 | |||
217 | if (!interface) | ||
218 | return; | ||
217 | 219 | ||
218 | if (variax == NULL) | 220 | variax = usb_get_intfdata(interface); |
221 | if (!variax) | ||
219 | return; | 222 | return; |
220 | line6_cleanup_audio(&variax->line6); | ||
221 | 223 | ||
222 | del_timer(&variax->startup_timer1); | 224 | del_timer(&variax->startup_timer1); |
223 | del_timer(&variax->startup_timer2); | 225 | del_timer(&variax->startup_timer2); |
@@ -227,21 +229,10 @@ static void variax_destruct(struct usb_interface *interface) | |||
227 | } | 229 | } |
228 | 230 | ||
229 | /* | 231 | /* |
230 | Workbench device disconnected. | ||
231 | */ | ||
232 | static void line6_variax_disconnect(struct usb_interface *interface) | ||
233 | { | ||
234 | if (interface == NULL) | ||
235 | return; | ||
236 | |||
237 | variax_destruct(interface); | ||
238 | } | ||
239 | |||
240 | /* | ||
241 | Try to init workbench device. | 232 | Try to init workbench device. |
242 | */ | 233 | */ |
243 | static int variax_try_init(struct usb_interface *interface, | 234 | static int variax_init(struct usb_interface *interface, |
244 | struct usb_line6 *line6) | 235 | struct usb_line6 *line6) |
245 | { | 236 | { |
246 | struct usb_line6_variax *variax = (struct usb_line6_variax *) line6; | 237 | struct usb_line6_variax *variax = (struct usb_line6_variax *) line6; |
247 | int err; | 238 | int err; |
@@ -263,11 +254,6 @@ static int variax_try_init(struct usb_interface *interface, | |||
263 | if (variax->buffer_activate == NULL) | 254 | if (variax->buffer_activate == NULL) |
264 | return -ENOMEM; | 255 | return -ENOMEM; |
265 | 256 | ||
266 | /* initialize audio system: */ | ||
267 | err = line6_init_audio(&variax->line6); | ||
268 | if (err < 0) | ||
269 | return err; | ||
270 | |||
271 | /* initialize MIDI subsystem: */ | 257 | /* initialize MIDI subsystem: */ |
272 | err = line6_init_midi(&variax->line6); | 258 | err = line6_init_midi(&variax->line6); |
273 | if (err < 0) | 259 | if (err < 0) |
@@ -278,20 +264,6 @@ static int variax_try_init(struct usb_interface *interface, | |||
278 | return 0; | 264 | return 0; |
279 | } | 265 | } |
280 | 266 | ||
281 | /* | ||
282 | Init workbench device (and clean up in case of failure). | ||
283 | */ | ||
284 | static int variax_init(struct usb_interface *interface, | ||
285 | struct usb_line6 *line6) | ||
286 | { | ||
287 | int err = variax_try_init(interface, line6); | ||
288 | |||
289 | if (err < 0) | ||
290 | variax_destruct(interface); | ||
291 | |||
292 | return err; | ||
293 | } | ||
294 | |||
295 | #define LINE6_DEVICE(prod) USB_DEVICE(0x0e41, prod) | 267 | #define LINE6_DEVICE(prod) USB_DEVICE(0x0e41, prod) |
296 | #define LINE6_IF_NUM(prod, n) USB_DEVICE_INTERFACE_NUMBER(0x0e41, prod, n) | 268 | #define LINE6_IF_NUM(prod, n) USB_DEVICE_INTERFACE_NUMBER(0x0e41, prod, n) |
297 | 269 | ||
@@ -335,17 +307,13 @@ static int variax_probe(struct usb_interface *interface, | |||
335 | const struct usb_device_id *id) | 307 | const struct usb_device_id *id) |
336 | { | 308 | { |
337 | struct usb_line6_variax *variax; | 309 | struct usb_line6_variax *variax; |
338 | int err; | ||
339 | 310 | ||
340 | variax = kzalloc(sizeof(*variax), GFP_KERNEL); | 311 | variax = kzalloc(sizeof(*variax), GFP_KERNEL); |
341 | if (!variax) | 312 | if (!variax) |
342 | return -ENODEV; | 313 | return -ENODEV; |
343 | err = line6_probe(interface, &variax->line6, | 314 | return line6_probe(interface, &variax->line6, |
344 | &variax_properties_table[id->driver_info], | 315 | &variax_properties_table[id->driver_info], |
345 | variax_init); | 316 | variax_init); |
346 | if (err < 0) | ||
347 | kfree(variax); | ||
348 | return err; | ||
349 | } | 317 | } |
350 | 318 | ||
351 | static struct usb_driver variax_driver = { | 319 | static struct usb_driver variax_driver = { |