|
@@ -339,7 +339,7 @@ static int snd_usb_audio_create(struct usb_device *dev, int idx,
|
|
}
|
|
}
|
|
|
|
|
|
mutex_init(&chip->mutex);
|
|
mutex_init(&chip->mutex);
|
|
- mutex_init(&chip->shutdown_mutex);
|
|
|
|
|
|
+ init_rwsem(&chip->shutdown_rwsem);
|
|
chip->index = idx;
|
|
chip->index = idx;
|
|
chip->dev = dev;
|
|
chip->dev = dev;
|
|
chip->card = card;
|
|
chip->card = card;
|
|
@@ -560,7 +560,7 @@ static void snd_usb_audio_disconnect(struct usb_device *dev,
|
|
|
|
|
|
card = chip->card;
|
|
card = chip->card;
|
|
mutex_lock(®ister_mutex);
|
|
mutex_lock(®ister_mutex);
|
|
- mutex_lock(&chip->shutdown_mutex);
|
|
|
|
|
|
+ down_write(&chip->shutdown_rwsem);
|
|
chip->shutdown = 1;
|
|
chip->shutdown = 1;
|
|
chip->num_interfaces--;
|
|
chip->num_interfaces--;
|
|
if (chip->num_interfaces <= 0) {
|
|
if (chip->num_interfaces <= 0) {
|
|
@@ -582,11 +582,11 @@ static void snd_usb_audio_disconnect(struct usb_device *dev,
|
|
snd_usb_mixer_disconnect(p);
|
|
snd_usb_mixer_disconnect(p);
|
|
}
|
|
}
|
|
usb_chip[chip->index] = NULL;
|
|
usb_chip[chip->index] = NULL;
|
|
- mutex_unlock(&chip->shutdown_mutex);
|
|
|
|
|
|
+ up_write(&chip->shutdown_rwsem);
|
|
mutex_unlock(®ister_mutex);
|
|
mutex_unlock(®ister_mutex);
|
|
snd_card_free_when_closed(card);
|
|
snd_card_free_when_closed(card);
|
|
} else {
|
|
} else {
|
|
- mutex_unlock(&chip->shutdown_mutex);
|
|
|
|
|
|
+ up_write(&chip->shutdown_rwsem);
|
|
mutex_unlock(®ister_mutex);
|
|
mutex_unlock(®ister_mutex);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -618,16 +618,20 @@ int snd_usb_autoresume(struct snd_usb_audio *chip)
|
|
{
|
|
{
|
|
int err = -ENODEV;
|
|
int err = -ENODEV;
|
|
|
|
|
|
|
|
+ down_read(&chip->shutdown_rwsem);
|
|
if (!chip->shutdown && !chip->probing)
|
|
if (!chip->shutdown && !chip->probing)
|
|
err = usb_autopm_get_interface(chip->pm_intf);
|
|
err = usb_autopm_get_interface(chip->pm_intf);
|
|
|
|
+ up_read(&chip->shutdown_rwsem);
|
|
|
|
|
|
return err;
|
|
return err;
|
|
}
|
|
}
|
|
|
|
|
|
void snd_usb_autosuspend(struct snd_usb_audio *chip)
|
|
void snd_usb_autosuspend(struct snd_usb_audio *chip)
|
|
{
|
|
{
|
|
|
|
+ down_read(&chip->shutdown_rwsem);
|
|
if (!chip->shutdown && !chip->probing)
|
|
if (!chip->shutdown && !chip->probing)
|
|
usb_autopm_put_interface(chip->pm_intf);
|
|
usb_autopm_put_interface(chip->pm_intf);
|
|
|
|
+ up_read(&chip->shutdown_rwsem);
|
|
}
|
|
}
|
|
|
|
|
|
static int usb_audio_suspend(struct usb_interface *intf, pm_message_t message)
|
|
static int usb_audio_suspend(struct usb_interface *intf, pm_message_t message)
|