diff options
| author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2006-03-23 23:44:19 -0500 |
|---|---|---|
| committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2006-03-23 23:44:19 -0500 |
| commit | 1ebbe2b20091d306453a5cf480a87e6cd28ae76f (patch) | |
| tree | f5cd7a0fa69b8b1938cb5a0faed2e7b0628072a5 /sound/usb/usbaudio.c | |
| parent | ac58c9059da8886b5e8cde012a80266b18ca146e (diff) | |
| parent | 674a396c6d2ba0341ebdd7c1c9950f32f018e2dd (diff) | |
Merge branch 'linus'
Diffstat (limited to 'sound/usb/usbaudio.c')
| -rw-r--r-- | sound/usb/usbaudio.c | 168 |
1 files changed, 128 insertions, 40 deletions
diff --git a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c index d5013383fad7..4e614ac39f21 100644 --- a/sound/usb/usbaudio.c +++ b/sound/usb/usbaudio.c | |||
| @@ -47,6 +47,7 @@ | |||
| 47 | #include <linux/usb.h> | 47 | #include <linux/usb.h> |
| 48 | #include <linux/vmalloc.h> | 48 | #include <linux/vmalloc.h> |
| 49 | #include <linux/moduleparam.h> | 49 | #include <linux/moduleparam.h> |
| 50 | #include <linux/mutex.h> | ||
| 50 | #include <sound/core.h> | 51 | #include <sound/core.h> |
| 51 | #include <sound/info.h> | 52 | #include <sound/info.h> |
| 52 | #include <sound/pcm.h> | 53 | #include <sound/pcm.h> |
| @@ -69,6 +70,7 @@ static int vid[SNDRV_CARDS] = { [0 ... (SNDRV_CARDS-1)] = -1 }; /* Vendor ID for | |||
| 69 | static int pid[SNDRV_CARDS] = { [0 ... (SNDRV_CARDS-1)] = -1 }; /* Product ID for this card */ | 70 | static int pid[SNDRV_CARDS] = { [0 ... (SNDRV_CARDS-1)] = -1 }; /* Product ID for this card */ |
| 70 | static int nrpacks = 4; /* max. number of packets per urb */ | 71 | static int nrpacks = 4; /* max. number of packets per urb */ |
| 71 | static int async_unlink = 1; | 72 | static int async_unlink = 1; |
| 73 | static int device_setup[SNDRV_CARDS]; /* device parameter for this card*/ | ||
| 72 | 74 | ||
| 73 | module_param_array(index, int, NULL, 0444); | 75 | module_param_array(index, int, NULL, 0444); |
| 74 | MODULE_PARM_DESC(index, "Index value for the USB audio adapter."); | 76 | MODULE_PARM_DESC(index, "Index value for the USB audio adapter."); |
| @@ -84,6 +86,8 @@ module_param(nrpacks, int, 0644); | |||
| 84 | MODULE_PARM_DESC(nrpacks, "Max. number of packets per URB."); | 86 | MODULE_PARM_DESC(nrpacks, "Max. number of packets per URB."); |
| 85 | module_param(async_unlink, bool, 0444); | 87 | module_param(async_unlink, bool, 0444); |
| 86 | MODULE_PARM_DESC(async_unlink, "Use async unlink mode."); | 88 | MODULE_PARM_DESC(async_unlink, "Use async unlink mode."); |
| 89 | module_param_array(device_setup, int, NULL, 0444); | ||
| 90 | MODULE_PARM_DESC(device_setup, "Specific device setup (if needed)."); | ||
| 87 | 91 | ||
| 88 | 92 | ||
| 89 | /* | 93 | /* |
| @@ -202,7 +206,7 @@ struct snd_usb_stream { | |||
| 202 | * the all interfaces on the same card as one sound device. | 206 | * the all interfaces on the same card as one sound device. |
| 203 | */ | 207 | */ |
| 204 | 208 | ||
| 205 | static DECLARE_MUTEX(register_mutex); | 209 | static DEFINE_MUTEX(register_mutex); |
| 206 | static struct snd_usb_audio *usb_chip[SNDRV_CARDS]; | 210 | static struct snd_usb_audio *usb_chip[SNDRV_CARDS]; |
| 207 | 211 | ||
| 208 | 212 | ||
| @@ -475,6 +479,18 @@ static int retire_playback_sync_urb_hs(struct snd_usb_substream *subs, | |||
| 475 | return 0; | 479 | return 0; |
| 476 | } | 480 | } |
| 477 | 481 | ||
| 482 | /* determine the number of frames in the next packet */ | ||
| 483 | static int snd_usb_audio_next_packet_size(struct snd_usb_substream *subs) | ||
| 484 | { | ||
| 485 | if (subs->fill_max) | ||
| 486 | return subs->maxframesize; | ||
| 487 | else { | ||
| 488 | subs->phase = (subs->phase & 0xffff) | ||
| 489 | + (subs->freqm << subs->datainterval); | ||
| 490 | return min(subs->phase >> 16, subs->maxframesize); | ||
| 491 | } | ||
| 492 | } | ||
| 493 | |||
| 478 | /* | 494 | /* |
| 479 | * Prepare urb for streaming before playback starts. | 495 | * Prepare urb for streaming before playback starts. |
| 480 | * | 496 | * |
| @@ -492,16 +508,7 @@ static int prepare_startup_playback_urb(struct snd_usb_substream *subs, | |||
| 492 | urb->dev = ctx->subs->dev; | 508 | urb->dev = ctx->subs->dev; |
| 493 | urb->number_of_packets = subs->packs_per_ms; | 509 | urb->number_of_packets = subs->packs_per_ms; |
| 494 | for (i = 0; i < subs->packs_per_ms; ++i) { | 510 | for (i = 0; i < subs->packs_per_ms; ++i) { |
| 495 | /* calculate the size of a packet */ | 511 | counts = snd_usb_audio_next_packet_size(subs); |
| 496 | if (subs->fill_max) | ||
| 497 | counts = subs->maxframesize; /* fixed */ | ||
| 498 | else { | ||
| 499 | subs->phase = (subs->phase & 0xffff) | ||
| 500 | + (subs->freqm << subs->datainterval); | ||
| 501 | counts = subs->phase >> 16; | ||
| 502 | if (counts > subs->maxframesize) | ||
| 503 | counts = subs->maxframesize; | ||
| 504 | } | ||
| 505 | urb->iso_frame_desc[i].offset = offs * stride; | 512 | urb->iso_frame_desc[i].offset = offs * stride; |
| 506 | urb->iso_frame_desc[i].length = counts * stride; | 513 | urb->iso_frame_desc[i].length = counts * stride; |
| 507 | offs += counts; | 514 | offs += counts; |
| @@ -538,16 +545,7 @@ static int prepare_playback_urb(struct snd_usb_substream *subs, | |||
| 538 | urb->number_of_packets = 0; | 545 | urb->number_of_packets = 0; |
| 539 | spin_lock_irqsave(&subs->lock, flags); | 546 | spin_lock_irqsave(&subs->lock, flags); |
| 540 | for (i = 0; i < ctx->packets; i++) { | 547 | for (i = 0; i < ctx->packets; i++) { |
| 541 | /* calculate the size of a packet */ | 548 | counts = snd_usb_audio_next_packet_size(subs); |
| 542 | if (subs->fill_max) | ||
| 543 | counts = subs->maxframesize; /* fixed */ | ||
| 544 | else { | ||
| 545 | subs->phase = (subs->phase & 0xffff) | ||
| 546 | + (subs->freqm << subs->datainterval); | ||
| 547 | counts = subs->phase >> 16; | ||
| 548 | if (counts > subs->maxframesize) | ||
| 549 | counts = subs->maxframesize; | ||
| 550 | } | ||
| 551 | /* set up descriptor */ | 549 | /* set up descriptor */ |
| 552 | urb->iso_frame_desc[i].offset = offs * stride; | 550 | urb->iso_frame_desc[i].offset = offs * stride; |
| 553 | urb->iso_frame_desc[i].length = counts * stride; | 551 | urb->iso_frame_desc[i].length = counts * stride; |
| @@ -725,10 +723,9 @@ static int snd_pcm_alloc_vmalloc_buffer(struct snd_pcm_substream *subs, size_t s | |||
| 725 | static int snd_pcm_free_vmalloc_buffer(struct snd_pcm_substream *subs) | 723 | static int snd_pcm_free_vmalloc_buffer(struct snd_pcm_substream *subs) |
| 726 | { | 724 | { |
| 727 | struct snd_pcm_runtime *runtime = subs->runtime; | 725 | struct snd_pcm_runtime *runtime = subs->runtime; |
| 728 | if (runtime->dma_area) { | 726 | |
| 729 | vfree(runtime->dma_area); | 727 | vfree(runtime->dma_area); |
| 730 | runtime->dma_area = NULL; | 728 | runtime->dma_area = NULL; |
| 731 | } | ||
| 732 | return 0; | 729 | return 0; |
| 733 | } | 730 | } |
| 734 | 731 | ||
| @@ -779,6 +776,35 @@ static int deactivate_urbs(struct snd_usb_substream *subs, int force, int can_sl | |||
| 779 | } | 776 | } |
| 780 | 777 | ||
| 781 | 778 | ||
| 779 | static const char *usb_error_string(int err) | ||
| 780 | { | ||
| 781 | switch (err) { | ||
| 782 | case -ENODEV: | ||
| 783 | return "no device"; | ||
| 784 | case -ENOENT: | ||
| 785 | return "endpoint not enabled"; | ||
| 786 | case -EPIPE: | ||
| 787 | return "endpoint stalled"; | ||
| 788 | case -ENOSPC: | ||
| 789 | return "not enough bandwidth"; | ||
| 790 | case -ESHUTDOWN: | ||
| 791 | return "device disabled"; | ||
| 792 | case -EHOSTUNREACH: | ||
| 793 | return "device suspended"; | ||
| 794 | #ifndef CONFIG_USB_EHCI_SPLIT_ISO | ||
| 795 | case -ENOSYS: | ||
| 796 | return "enable CONFIG_USB_EHCI_SPLIT_ISO to play through a hub"; | ||
| 797 | #endif | ||
| 798 | case -EINVAL: | ||
| 799 | case -EAGAIN: | ||
| 800 | case -EFBIG: | ||
| 801 | case -EMSGSIZE: | ||
| 802 | return "internal error"; | ||
| 803 | default: | ||
| 804 | return "unknown error"; | ||
| 805 | } | ||
| 806 | } | ||
| 807 | |||
| 782 | /* | 808 | /* |
| 783 | * set up and start data/sync urbs | 809 | * set up and start data/sync urbs |
| 784 | */ | 810 | */ |
| @@ -811,16 +837,22 @@ static int start_urbs(struct snd_usb_substream *subs, struct snd_pcm_runtime *ru | |||
| 811 | subs->unlink_mask = 0; | 837 | subs->unlink_mask = 0; |
| 812 | subs->running = 1; | 838 | subs->running = 1; |
| 813 | for (i = 0; i < subs->nurbs; i++) { | 839 | for (i = 0; i < subs->nurbs; i++) { |
| 814 | if ((err = usb_submit_urb(subs->dataurb[i].urb, GFP_ATOMIC)) < 0) { | 840 | err = usb_submit_urb(subs->dataurb[i].urb, GFP_ATOMIC); |
| 815 | snd_printk(KERN_ERR "cannot submit datapipe for urb %d, err = %d\n", i, err); | 841 | if (err < 0) { |
| 842 | snd_printk(KERN_ERR "cannot submit datapipe " | ||
| 843 | "for urb %d, error %d: %s\n", | ||
| 844 | i, err, usb_error_string(err)); | ||
| 816 | goto __error; | 845 | goto __error; |
| 817 | } | 846 | } |
| 818 | set_bit(i, &subs->active_mask); | 847 | set_bit(i, &subs->active_mask); |
| 819 | } | 848 | } |
| 820 | if (subs->syncpipe) { | 849 | if (subs->syncpipe) { |
| 821 | for (i = 0; i < SYNC_URBS; i++) { | 850 | for (i = 0; i < SYNC_URBS; i++) { |
| 822 | if ((err = usb_submit_urb(subs->syncurb[i].urb, GFP_ATOMIC)) < 0) { | 851 | err = usb_submit_urb(subs->syncurb[i].urb, GFP_ATOMIC); |
| 823 | snd_printk(KERN_ERR "cannot submit syncpipe for urb %d, err = %d\n", i, err); | 852 | if (err < 0) { |
| 853 | snd_printk(KERN_ERR "cannot submit syncpipe " | ||
| 854 | "for urb %d, error %d: %s\n", | ||
| 855 | i, err, usb_error_string(err)); | ||
| 824 | goto __error; | 856 | goto __error; |
| 825 | } | 857 | } |
| 826 | set_bit(i + 16, &subs->active_mask); | 858 | set_bit(i + 16, &subs->active_mask); |
| @@ -1390,8 +1422,8 @@ static int snd_usb_hw_params(struct snd_pcm_substream *substream, | |||
| 1390 | channels = params_channels(hw_params); | 1422 | channels = params_channels(hw_params); |
| 1391 | fmt = find_format(subs, format, rate, channels); | 1423 | fmt = find_format(subs, format, rate, channels); |
| 1392 | if (! fmt) { | 1424 | if (! fmt) { |
| 1393 | snd_printd(KERN_DEBUG "cannot set format: format = %s, rate = %d, channels = %d\n", | 1425 | snd_printd(KERN_DEBUG "cannot set format: format = 0x%x, rate = %d, channels = %d\n", |
| 1394 | snd_pcm_format_name(format), rate, channels); | 1426 | format, rate, channels); |
| 1395 | return -EINVAL; | 1427 | return -EINVAL; |
| 1396 | } | 1428 | } |
| 1397 | 1429 | ||
| @@ -2017,6 +2049,8 @@ static struct usb_driver usb_audio_driver = { | |||
| 2017 | }; | 2049 | }; |
| 2018 | 2050 | ||
| 2019 | 2051 | ||
| 2052 | #if defined(CONFIG_PROCFS) && defined(CONFIG_SND_VERBOSE_PROCFS) | ||
| 2053 | |||
| 2020 | /* | 2054 | /* |
| 2021 | * proc interface for list the supported pcm formats | 2055 | * proc interface for list the supported pcm formats |
| 2022 | */ | 2056 | */ |
| @@ -2032,7 +2066,7 @@ static void proc_dump_substream_formats(struct snd_usb_substream *subs, struct s | |||
| 2032 | fp = list_entry(p, struct audioformat, list); | 2066 | fp = list_entry(p, struct audioformat, list); |
| 2033 | snd_iprintf(buffer, " Interface %d\n", fp->iface); | 2067 | snd_iprintf(buffer, " Interface %d\n", fp->iface); |
| 2034 | snd_iprintf(buffer, " Altset %d\n", fp->altsetting); | 2068 | snd_iprintf(buffer, " Altset %d\n", fp->altsetting); |
| 2035 | snd_iprintf(buffer, " Format: %s\n", snd_pcm_format_name(fp->format)); | 2069 | snd_iprintf(buffer, " Format: 0x%x\n", fp->format); |
| 2036 | snd_iprintf(buffer, " Channels: %d\n", fp->channels); | 2070 | snd_iprintf(buffer, " Channels: %d\n", fp->channels); |
| 2037 | snd_iprintf(buffer, " Endpoint: %d %s (%s)\n", | 2071 | snd_iprintf(buffer, " Endpoint: %d %s (%s)\n", |
| 2038 | fp->endpoint & USB_ENDPOINT_NUMBER_MASK, | 2072 | fp->endpoint & USB_ENDPOINT_NUMBER_MASK, |
| @@ -2107,6 +2141,13 @@ static void proc_pcm_format_add(struct snd_usb_stream *stream) | |||
| 2107 | snd_info_set_text_ops(entry, stream, 1024, proc_pcm_format_read); | 2141 | snd_info_set_text_ops(entry, stream, 1024, proc_pcm_format_read); |
| 2108 | } | 2142 | } |
| 2109 | 2143 | ||
| 2144 | #else | ||
| 2145 | |||
| 2146 | static inline void proc_pcm_format_add(struct snd_usb_stream *stream) | ||
| 2147 | { | ||
| 2148 | } | ||
| 2149 | |||
| 2150 | #endif | ||
| 2110 | 2151 | ||
| 2111 | /* | 2152 | /* |
| 2112 | * initialize the substream instance. | 2153 | * initialize the substream instance. |
| @@ -2509,6 +2550,8 @@ static int parse_audio_format(struct snd_usb_audio *chip, struct audioformat *fp | |||
| 2509 | return 0; | 2550 | return 0; |
| 2510 | } | 2551 | } |
| 2511 | 2552 | ||
| 2553 | static int audiophile_skip_setting_quirk(struct snd_usb_audio *chip, | ||
| 2554 | int iface, int altno); | ||
| 2512 | static int parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no) | 2555 | static int parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no) |
| 2513 | { | 2556 | { |
| 2514 | struct usb_device *dev; | 2557 | struct usb_device *dev; |
| @@ -2543,6 +2586,12 @@ static int parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no) | |||
| 2543 | stream = (get_endpoint(alts, 0)->bEndpointAddress & USB_DIR_IN) ? | 2586 | stream = (get_endpoint(alts, 0)->bEndpointAddress & USB_DIR_IN) ? |
| 2544 | SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK; | 2587 | SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK; |
| 2545 | altno = altsd->bAlternateSetting; | 2588 | altno = altsd->bAlternateSetting; |
| 2589 | |||
| 2590 | /* audiophile usb: skip altsets incompatible with device_setup | ||
| 2591 | */ | ||
| 2592 | if (chip->usb_id == USB_ID(0x0763, 0x2003) && | ||
| 2593 | audiophile_skip_setting_quirk(chip, iface_no, altno)) | ||
| 2594 | continue; | ||
| 2546 | 2595 | ||
| 2547 | /* get audio formats */ | 2596 | /* get audio formats */ |
| 2548 | fmt = snd_usb_find_csint_desc(alts->extra, alts->extralen, NULL, AS_GENERAL); | 2597 | fmt = snd_usb_find_csint_desc(alts->extra, alts->extralen, NULL, AS_GENERAL); |
| @@ -2637,7 +2686,7 @@ static int parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no) | |||
| 2637 | continue; | 2686 | continue; |
| 2638 | } | 2687 | } |
| 2639 | 2688 | ||
| 2640 | snd_printdd(KERN_INFO "%d:%u:%d: add audio endpoint 0x%x\n", dev->devnum, iface_no, i, fp->endpoint); | 2689 | snd_printdd(KERN_INFO "%d:%u:%d: add audio endpoint 0x%x\n", dev->devnum, iface_no, altno, fp->endpoint); |
| 2641 | err = add_audio_endpoint(chip, stream, fp); | 2690 | err = add_audio_endpoint(chip, stream, fp); |
| 2642 | if (err < 0) { | 2691 | if (err < 0) { |
| 2643 | kfree(fp->rate_table); | 2692 | kfree(fp->rate_table); |
| @@ -3045,6 +3094,45 @@ static int snd_usb_audigy2nx_boot_quirk(struct usb_device *dev) | |||
| 3045 | return 0; | 3094 | return 0; |
| 3046 | } | 3095 | } |
| 3047 | 3096 | ||
| 3097 | /* | ||
| 3098 | * Setup quirks | ||
| 3099 | */ | ||
| 3100 | #define AUDIOPHILE_SET 0x01 /* if set, parse device_setup */ | ||
| 3101 | #define AUDIOPHILE_SET_DTS 0x02 /* if set, enable DTS Digital Output */ | ||
| 3102 | #define AUDIOPHILE_SET_96K 0x04 /* 48-96KHz rate if set, 8-48KHz otherwise */ | ||
| 3103 | #define AUDIOPHILE_SET_24B 0x08 /* 24bits sample if set, 16bits otherwise */ | ||
| 3104 | #define AUDIOPHILE_SET_DI 0x10 /* if set, enable Digital Input */ | ||
| 3105 | #define AUDIOPHILE_SET_MASK 0x1F /* bit mask for setup value */ | ||
| 3106 | #define AUDIOPHILE_SET_24B_48K_DI 0x19 /* value for 24bits+48KHz+Digital Input */ | ||
| 3107 | #define AUDIOPHILE_SET_24B_48K_NOTDI 0x09 /* value for 24bits+48KHz+No Digital Input */ | ||
| 3108 | #define AUDIOPHILE_SET_16B_48K_DI 0x11 /* value for 16bits+48KHz+Digital Input */ | ||
| 3109 | #define AUDIOPHILE_SET_16B_48K_NOTDI 0x01 /* value for 16bits+48KHz+No Digital Input */ | ||
| 3110 | |||
| 3111 | static int audiophile_skip_setting_quirk(struct snd_usb_audio *chip, | ||
| 3112 | int iface, int altno) | ||
| 3113 | { | ||
| 3114 | if (device_setup[chip->index] & AUDIOPHILE_SET) { | ||
| 3115 | if ((device_setup[chip->index] & AUDIOPHILE_SET_DTS) | ||
| 3116 | && altno != 6) | ||
| 3117 | return 1; /* skip this altsetting */ | ||
| 3118 | if ((device_setup[chip->index] & AUDIOPHILE_SET_96K) | ||
| 3119 | && altno != 1) | ||
| 3120 | return 1; /* skip this altsetting */ | ||
| 3121 | if ((device_setup[chip->index] & AUDIOPHILE_SET_MASK) == | ||
| 3122 | AUDIOPHILE_SET_24B_48K_DI && altno != 2) | ||
| 3123 | return 1; /* skip this altsetting */ | ||
| 3124 | if ((device_setup[chip->index] & AUDIOPHILE_SET_MASK) == | ||
| 3125 | AUDIOPHILE_SET_24B_48K_NOTDI && altno != 3) | ||
| 3126 | return 1; /* skip this altsetting */ | ||
| 3127 | if ((device_setup[chip->index] & AUDIOPHILE_SET_MASK) == | ||
| 3128 | AUDIOPHILE_SET_16B_48K_DI && altno != 4) | ||
| 3129 | return 1; /* skip this altsetting */ | ||
| 3130 | if ((device_setup[chip->index] & AUDIOPHILE_SET_MASK) == | ||
| 3131 | AUDIOPHILE_SET_16B_48K_NOTDI && altno != 5) | ||
| 3132 | return 1; /* skip this altsetting */ | ||
| 3133 | } | ||
| 3134 | return 0; /* keep this altsetting */ | ||
| 3135 | } | ||
| 3048 | 3136 | ||
| 3049 | /* | 3137 | /* |
| 3050 | * audio-interface quirks | 3138 | * audio-interface quirks |
| @@ -3070,7 +3158,7 @@ static int snd_usb_create_quirk(struct snd_usb_audio *chip, | |||
| 3070 | [QUIRK_MIDI_NOVATION] = snd_usb_create_midi_interface, | 3158 | [QUIRK_MIDI_NOVATION] = snd_usb_create_midi_interface, |
| 3071 | [QUIRK_MIDI_RAW] = snd_usb_create_midi_interface, | 3159 | [QUIRK_MIDI_RAW] = snd_usb_create_midi_interface, |
| 3072 | [QUIRK_MIDI_EMAGIC] = snd_usb_create_midi_interface, | 3160 | [QUIRK_MIDI_EMAGIC] = snd_usb_create_midi_interface, |
| 3073 | [QUIRK_MIDI_MIDITECH] = snd_usb_create_midi_interface, | 3161 | [QUIRK_MIDI_CME] = snd_usb_create_midi_interface, |
| 3074 | [QUIRK_AUDIO_STANDARD_INTERFACE] = create_standard_audio_quirk, | 3162 | [QUIRK_AUDIO_STANDARD_INTERFACE] = create_standard_audio_quirk, |
| 3075 | [QUIRK_AUDIO_FIXED_ENDPOINT] = create_fixed_stream_quirk, | 3163 | [QUIRK_AUDIO_FIXED_ENDPOINT] = create_fixed_stream_quirk, |
| 3076 | [QUIRK_AUDIO_EDIROL_UA700_UA25] = create_ua700_ua25_quirk, | 3164 | [QUIRK_AUDIO_EDIROL_UA700_UA25] = create_ua700_ua25_quirk, |
| @@ -3282,7 +3370,7 @@ static void *snd_usb_audio_probe(struct usb_device *dev, | |||
| 3282 | 3370 | ||
| 3283 | /* check whether it's already registered */ | 3371 | /* check whether it's already registered */ |
| 3284 | chip = NULL; | 3372 | chip = NULL; |
| 3285 | down(®ister_mutex); | 3373 | mutex_lock(®ister_mutex); |
| 3286 | for (i = 0; i < SNDRV_CARDS; i++) { | 3374 | for (i = 0; i < SNDRV_CARDS; i++) { |
| 3287 | if (usb_chip[i] && usb_chip[i]->dev == dev) { | 3375 | if (usb_chip[i] && usb_chip[i]->dev == dev) { |
| 3288 | if (usb_chip[i]->shutdown) { | 3376 | if (usb_chip[i]->shutdown) { |
| @@ -3335,13 +3423,13 @@ static void *snd_usb_audio_probe(struct usb_device *dev, | |||
| 3335 | 3423 | ||
| 3336 | usb_chip[chip->index] = chip; | 3424 | usb_chip[chip->index] = chip; |
| 3337 | chip->num_interfaces++; | 3425 | chip->num_interfaces++; |
| 3338 | up(®ister_mutex); | 3426 | mutex_unlock(®ister_mutex); |
| 3339 | return chip; | 3427 | return chip; |
| 3340 | 3428 | ||
| 3341 | __error: | 3429 | __error: |
| 3342 | if (chip && !chip->num_interfaces) | 3430 | if (chip && !chip->num_interfaces) |
| 3343 | snd_card_free(chip->card); | 3431 | snd_card_free(chip->card); |
| 3344 | up(®ister_mutex); | 3432 | mutex_unlock(®ister_mutex); |
| 3345 | __err_val: | 3433 | __err_val: |
| 3346 | return NULL; | 3434 | return NULL; |
| 3347 | } | 3435 | } |
| @@ -3361,7 +3449,7 @@ static void snd_usb_audio_disconnect(struct usb_device *dev, void *ptr) | |||
| 3361 | 3449 | ||
| 3362 | chip = ptr; | 3450 | chip = ptr; |
| 3363 | card = chip->card; | 3451 | card = chip->card; |
| 3364 | down(®ister_mutex); | 3452 | mutex_lock(®ister_mutex); |
| 3365 | chip->shutdown = 1; | 3453 | chip->shutdown = 1; |
| 3366 | chip->num_interfaces--; | 3454 | chip->num_interfaces--; |
| 3367 | if (chip->num_interfaces <= 0) { | 3455 | if (chip->num_interfaces <= 0) { |
| @@ -3379,10 +3467,10 @@ static void snd_usb_audio_disconnect(struct usb_device *dev, void *ptr) | |||
| 3379 | snd_usb_mixer_disconnect(p); | 3467 | snd_usb_mixer_disconnect(p); |
| 3380 | } | 3468 | } |
| 3381 | usb_chip[chip->index] = NULL; | 3469 | usb_chip[chip->index] = NULL; |
| 3382 | up(®ister_mutex); | 3470 | mutex_unlock(®ister_mutex); |
| 3383 | snd_card_free(card); | 3471 | snd_card_free(card); |
| 3384 | } else { | 3472 | } else { |
| 3385 | up(®ister_mutex); | 3473 | mutex_unlock(®ister_mutex); |
| 3386 | } | 3474 | } |
| 3387 | } | 3475 | } |
| 3388 | 3476 | ||
