git.openpandora.org
/
pandora-kernel.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
ALSA: usb-audio: Use rwsem for disconnect protection
[pandora-kernel.git]
/
sound
/
usb
/
card.c
diff --git
a/sound/usb/card.c
b/sound/usb/card.c
index
4a469f0
..
282f0fc
100644
(file)
--- a/
sound/usb/card.c
+++ b/
sound/usb/card.c
@@
-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->dev = dev;
chip->card = card;
chip->index = idx;
chip->dev = dev;
chip->card = card;
@@
-560,7
+560,7
@@
static void snd_usb_audio_disconnect(struct usb_device *dev,
card = chip->card;
mutex_lock(®ister_mutex);
card = chip->card;
mutex_lock(®ister_mutex);
-
mutex_lock(&chip->shutdown_mutex
);
+
down_write(&chip->shutdown_rwsem
);
chip->shutdown = 1;
chip->num_interfaces--;
if (chip->num_interfaces <= 0) {
chip->shutdown = 1;
chip->num_interfaces--;
if (chip->num_interfaces <= 0) {
@@
-582,11
+582,11
@@
static void snd_usb_audio_disconnect(struct usb_device *dev,
snd_usb_mixer_disconnect(p);
}
usb_chip[chip->index] = NULL;
snd_usb_mixer_disconnect(p);
}
usb_chip[chip->index] = NULL;
-
mutex_unlock(&chip->shutdown_mutex
);
+
up_write(&chip->shutdown_rwsem
);
mutex_unlock(®ister_mutex);
snd_card_free_when_closed(card);
} else {
mutex_unlock(®ister_mutex);
snd_card_free_when_closed(card);
} 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)
err = usb_autopm_get_interface(chip->pm_intf);
if (!chip->shutdown && !chip->probing)
err = usb_autopm_get_interface(chip->pm_intf);
+ up_read(&chip->shutdown_rwsem);
return err;
}
void snd_usb_autosuspend(struct snd_usb_audio *chip)
{
return err;
}
void snd_usb_autosuspend(struct snd_usb_audio *chip)
{
+ down_read(&chip->shutdown_rwsem);
if (!chip->shutdown && !chip->probing)
usb_autopm_put_interface(chip->pm_intf);
if (!chip->shutdown && !chip->probing)
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)
@@
-646,6
+650,8
@@
static int usb_audio_suspend(struct usb_interface *intf, pm_message_t message)
list_for_each(p, &chip->pcm_list) {
as = list_entry(p, struct snd_usb_stream, list);
snd_pcm_suspend_all(as->pcm);
list_for_each(p, &chip->pcm_list) {
as = list_entry(p, struct snd_usb_stream, list);
snd_pcm_suspend_all(as->pcm);
+ as->substream[0].need_setup_ep =
+ as->substream[1].need_setup_ep = true;
}
}
} else {
}
}
} else {