Update of /cvsroot/alsa/alsa-kernel/usb
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv10344

Modified Files:
        usbaudio.c 
Log Message:
fix deadlock on register_mutex and other bugs
in initialization error paths

Index: usbaudio.c
===================================================================
RCS file: /cvsroot/alsa/alsa-kernel/usb/usbaudio.c,v
retrieving revision 1.92
retrieving revision 1.93
diff -u -r1.92 -r1.93
--- usbaudio.c  19 Mar 2004 07:46:03 -0000      1.92
+++ usbaudio.c  22 Mar 2004 07:50:47 -0000      1.93
@@ -2826,9 +2826,6 @@
 
 static int snd_usb_audio_free(snd_usb_audio_t *chip)
 {
-       down(&register_mutex);
-       usb_chip[chip->index] = NULL;
-       up(&register_mutex);
        snd_magic_kfree(chip);
        return 0;
 }
@@ -2843,10 +2840,11 @@
 /*
  * create a chip instance and set its names.
  */
-static int snd_usb_audio_create(snd_card_t *card, struct usb_device *dev,
+static int snd_usb_audio_create(struct usb_device *dev, int idx,
                                const snd_usb_audio_quirk_t *quirk,
                                snd_usb_audio_t **rchip)
 {
+       snd_card_t *card;
        snd_usb_audio_t *chip;
        int err, len;
        char component[14];
@@ -2859,14 +2857,22 @@
        if (dev->speed != USB_SPEED_FULL &&
            dev->speed != USB_SPEED_HIGH) {
                snd_printk(KERN_ERR "unknown device speed %d\n", dev->speed);
-               snd_usb_audio_free(chip);
                return -ENXIO;
        }
 
+       card = snd_card_new(index[idx], id[idx], THIS_MODULE, 0);
+       if (card == NULL) {
+               snd_printk(KERN_ERR "cannot create card instance %d\n", idx);
+               return -ENOMEM;
+       }
+
        chip = snd_magic_kcalloc(snd_usb_audio_t, 0, GFP_KERNEL);
-       if (! chip)
+       if (! chip) {
+               snd_card_free(card);
                return -ENOMEM;
+       }
 
+       chip->index = idx;
        chip->dev = dev;
        chip->card = card;
        INIT_LIST_HEAD(&chip->pcm_list);
@@ -2874,6 +2880,7 @@
 
        if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
                snd_usb_audio_free(chip);
+               snd_card_free(card);
                return err;
        }
 
@@ -2946,7 +2953,6 @@
        struct usb_host_config *config = dev->actconfig;
        const snd_usb_audio_quirk_t *quirk = (const snd_usb_audio_quirk_t 
*)usb_id->driver_info;
        int i, err;
-       snd_card_t *card;
        snd_usb_audio_t *chip;
        struct usb_host_interface *alts;
        int ifnum;
@@ -2974,11 +2980,11 @@
        down(&register_mutex);
        for (i = 0; i < SNDRV_CARDS; i++) {
                if (usb_chip[i] && usb_chip[i]->dev == dev) {
-                       chip = usb_chip[i];
-                       if (chip->shutdown) {
+                       if (usb_chip[i]->shutdown) {
                                snd_printk(KERN_ERR "USB device is in the shutdown 
state, cannot create a card instance\n");
                                goto __error;
                        }
+                       chip = usb_chip[i];
                        break;
                }
        }
@@ -2995,17 +3001,9 @@
                        if (enable[i] && ! usb_chip[i] &&
                            (vid[i] == -1 || vid[i] == dev->descriptor.idVendor) &&
                            (pid[i] == -1 || pid[i] == dev->descriptor.idProduct)) {
-                               card = snd_card_new(index[i], id[i], THIS_MODULE, 0);
-                               if (card == NULL) {
-                                       snd_printk(KERN_ERR "cannot create a card 
instance %d\n", i);
-                                       goto __error;
-                               }
-                               if (snd_usb_audio_create(card, dev, quirk, &chip) < 0) 
{
-                                       snd_card_free(card);
+                               if (snd_usb_audio_create(dev, i, quirk, &chip) < 0) {
                                        goto __error;
                                }
-                               chip->index = i;
-                               usb_chip[i] = chip;
                                break;
                        }
                if (! chip) {
@@ -3031,16 +3029,17 @@
 
        /* we are allowed to call snd_card_register() many times */
        if (snd_card_register(chip->card) < 0) {
-               if (! chip->num_interfaces)
-                       snd_card_free(chip->card);
                goto __error;
        }
 
+       usb_chip[chip->index] = chip;
        chip->num_interfaces++;
        up(&register_mutex);
        return chip;
 
  __error:
+       if (chip && !chip->num_interfaces)
+               snd_card_free(chip->card);
        up(&register_mutex);
  __err_val:
        return NULL;
@@ -3074,6 +3073,7 @@
                list_for_each(p, &chip->midi_list) {
                        snd_usbmidi_disconnect(p, &usb_audio_driver);
                }
+               usb_chip[chip->index] = NULL;
                up(&register_mutex);
                snd_card_free_in_thread(card);
        } else {



-------------------------------------------------------
This SF.Net email is sponsored by: IBM Linux Tutorials
Free Linux tutorial presented by Daniel Robbins, President and CEO of
GenToo technologies. Learn everything from fundamentals to system
administration.http://ads.osdn.com/?ad_id=1470&alloc_id=3638&op=click
_______________________________________________
Alsa-cvslog mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/alsa-cvslog

Reply via email to