public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Greg KH <gregkh@suse.de>
To: linux-kernel@vger.kernel.org, stable@kernel.org
Cc: Justin Forbes <jmforbes@linuxtx.org>,
	Zwane Mwaikambo <zwane@arm.linux.org.uk>,
	"Theodore Ts'o" <tytso@mit.edu>,
	Randy Dunlap <rdunlap@xenotime.net>,
	Dave Jones <davej@redhat.com>,
	Chuck Wolber <chuckw@quantumlinux.com>,
	Chris Wedgwood <reviews@ml.cw.f00f.org>,
	Michael Krufky <mkrufky@linuxtv.org>,
	Chuck Ebbert <cebbert@redhat.com>,
	Domenico Andreoli <cavokz@gmail.com>, Willy Tarreau <w@1wt.eu>,
	Rodrigo Rubira Branco <rbranco@la.checkpoint.com>,
	Jake Edge <jake@lwn.net>, Eugene Teo <eteo@redhat.com>,
	torvalds@linux-foundation.org, akpm@linux-foundation.org,
	alan@lxorguk.ukuu.org.uk, Takashi Iwai <tiwai@suse.de>
Subject: [patch 30/33] ALSA: Fix Oops with usb-audio reconnection
Date: Mon, 4 Aug 2008 13:16:24 -0700	[thread overview]
Message-ID: <20080804201624.GE1139@suse.de> (raw)
In-Reply-To: <20080804201321.GA1139@suse.de>

[-- Attachment #1: alsa-fix-oops-with-usb-audio-reconnection.patch --]
[-- Type: text/plain, Size: 8226 bytes --]

2.6.25-stable review patch.  If anyone has any objections, please let us
know.

------------------

From: Takashi Iwai <tiwai@suse.de>

Backport fixes for usb-audio Oops at reconnection.

9eb70e6... [ALSA] usb-audio - Fix race in reconnection
f18638d... [ALSA] Clean up snd_card_free*()
73d38b1... [ALSA] Fix the race of card instance unregistration

Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

---
 sound/core/init.c     |   36 ++++++++++--------------
 sound/usb/usbaudio.c  |   35 +++++++++++++++++------
 sound/usb/usbquirks.h |   75 +++++++++++++++++++++++++-------------------------
 3 files changed, 79 insertions(+), 67 deletions(-)

--- a/sound/core/init.c
+++ b/sound/core/init.c
@@ -311,6 +311,9 @@ int snd_card_disconnect(struct snd_card 
 	struct file *file;
 	int err;
 
+	if (!card)
+		return -EINVAL;
+
 	spin_lock(&card->files_lock);
 	if (card->shutdown) {
 		spin_unlock(&card->files_lock);
@@ -322,6 +325,7 @@ int snd_card_disconnect(struct snd_card 
 	/* phase 1: disable fops (user space) operations for ALSA API */
 	mutex_lock(&snd_card_mutex);
 	snd_cards[card->number] = NULL;
+	snd_cards_lock &= ~(1 << card->number);
 	mutex_unlock(&snd_card_mutex);
 	
 	/* phase 2: replace file->f_op with special dummy operations */
@@ -360,6 +364,15 @@ int snd_card_disconnect(struct snd_card 
 		snd_printk(KERN_ERR "not all devices for card %i can be disconnected\n", card->number);
 
 	snd_info_card_disconnect(card);
+#ifndef CONFIG_SYSFS_DEPRECATED
+	if (card->card_dev) {
+		device_unregister(card->card_dev);
+		card->card_dev = NULL;
+	}
+#endif
+#ifdef CONFIG_PM
+	wake_up(&card->power_sleep);
+#endif
 	return 0;	
 }
 
@@ -401,33 +414,14 @@ static int snd_card_do_free(struct snd_c
 		snd_printk(KERN_WARNING "unable to free card info\n");
 		/* Not fatal error */
 	}
-#ifndef CONFIG_SYSFS_DEPRECATED
-	if (card->card_dev)
-		device_unregister(card->card_dev);
-#endif
 	kfree(card);
 	return 0;
 }
 
-static int snd_card_free_prepare(struct snd_card *card)
-{
-	if (card == NULL)
-		return -EINVAL;
-	(void) snd_card_disconnect(card);
-	mutex_lock(&snd_card_mutex);
-	snd_cards[card->number] = NULL;
-	snd_cards_lock &= ~(1 << card->number);
-	mutex_unlock(&snd_card_mutex);
-#ifdef CONFIG_PM
-	wake_up(&card->power_sleep);
-#endif
-	return 0;
-}
-
 int snd_card_free_when_closed(struct snd_card *card)
 {
 	int free_now = 0;
-	int ret = snd_card_free_prepare(card);
+	int ret = snd_card_disconnect(card);
 	if (ret)
 		return ret;
 
@@ -447,7 +441,7 @@ EXPORT_SYMBOL(snd_card_free_when_closed)
 
 int snd_card_free(struct snd_card *card)
 {
-	int ret = snd_card_free_prepare(card);
+	int ret = snd_card_disconnect(card);
 	if (ret)
 		return ret;
 
--- a/sound/usb/usbaudio.c
+++ b/sound/usb/usbaudio.c
@@ -1762,8 +1762,10 @@ static int check_hw_params_convention(st
 
 	channels = kcalloc(MAX_MASK, sizeof(u32), GFP_KERNEL);
 	rates = kcalloc(MAX_MASK, sizeof(u32), GFP_KERNEL);
-	if (!channels || !rates)
+	if (!channels || !rates) {
+		err = -ENOMEM;
 		goto __out;
+	}
 
 	list_for_each(p, &subs->fmt_list) {
 		struct audioformat *f;
@@ -1916,7 +1918,10 @@ static int setup_hw_info(struct snd_pcm_
 				     1000 * MIN_PACKS_URB,
 				     /*(nrpacks * MAX_URBS) * 1000*/ UINT_MAX);
 
-	if (check_hw_params_convention(subs)) {
+	err = check_hw_params_convention(subs);
+	if (err < 0)
+		return err;
+	else if (err) {
 		hwc_debug("setting extra hw constraints...\n");
 		if ((err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
 					       hw_rule_rate, subs,
@@ -2463,11 +2468,12 @@ static int parse_audio_format_i_type(str
 		}
 		break;
 	case USB_AUDIO_FORMAT_PCM8:
-		/* Dallas DS4201 workaround */
+		pcm_format = SNDRV_PCM_FORMAT_U8;
+
+		/* Dallas DS4201 workaround: it advertises U8 format, but really
+		   supports S8. */
 		if (chip->usb_id == USB_ID(0x04fa, 0x4201))
 			pcm_format = SNDRV_PCM_FORMAT_S8;
-		else
-			pcm_format = SNDRV_PCM_FORMAT_U8;
 		break;
 	case USB_AUDIO_FORMAT_IEEE_FLOAT:
 		pcm_format = SNDRV_PCM_FORMAT_FLOAT_LE;
@@ -2671,12 +2677,23 @@ static int parse_audio_endpoints(struct 
 	int format;
 	struct audioformat *fp;
 	unsigned char *fmt, *csep;
+	int num;
 
 	dev = chip->dev;
 
 	/* parse the interface's altsettings */
 	iface = usb_ifnum_to_if(dev, iface_no);
-	for (i = 0; i < iface->num_altsetting; i++) {
+
+	num = iface->num_altsetting;
+
+	/*
+	 * Dallas DS4201 workaround: It presents 5 altsettings, but the last
+	 * one misses syncpipe, and does not produce any sound.
+	 */
+	if (chip->usb_id == USB_ID(0x04fa, 0x4201))
+		num = 4;
+
+	for (i = 0; i < num; i++) {
 		alts = &iface->altsetting[i];
 		altsd = get_iface_desc(alts);
 		/* skip invalid one */
@@ -3406,7 +3423,6 @@ static void snd_usb_audio_create_proc(st
 
 static int snd_usb_audio_free(struct snd_usb_audio *chip)
 {
-	usb_chip[chip->index] = NULL;
 	kfree(chip);
 	return 0;
 }
@@ -3600,8 +3616,8 @@ static void *snd_usb_audio_probe(struct 
 				snd_card_set_dev(chip->card, &intf->dev);
 				break;
 			}
-		if (! chip) {
-			snd_printk(KERN_ERR "no available usb audio device\n");
+		if (!chip) {
+			printk(KERN_ERR "no available usb audio device\n");
 			goto __error;
 		}
 	}
@@ -3671,6 +3687,7 @@ static void snd_usb_audio_disconnect(str
 		list_for_each(p, &chip->mixer_list) {
 			snd_usb_mixer_disconnect(p);
 		}
+		usb_chip[chip->index] = NULL;
 		mutex_unlock(&register_mutex);
 		snd_card_free_when_closed(card);
 	} else {
--- a/sound/usb/usbquirks.h
+++ b/sound/usb/usbquirks.h
@@ -39,6 +39,30 @@
 	.idProduct = prod, \
 	.bInterfaceClass = USB_CLASS_VENDOR_SPEC
 
+/* Creative/E-Mu devices */
+{
+	USB_DEVICE(0x041e, 0x3010),
+	.driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
+		.vendor_name = "Creative Labs",
+		.product_name = "Sound Blaster MP3+",
+		.ifnum = QUIRK_NO_INTERFACE
+	}
+},
+{
+	/* E-Mu 0202 USB */
+	.match_flags = USB_DEVICE_ID_MATCH_DEVICE,
+	.idVendor = 0x041e,
+	.idProduct = 0x3f02,
+	.bInterfaceClass = USB_CLASS_AUDIO,
+},
+{
+	/* E-Mu 0404 USB */
+	.match_flags = USB_DEVICE_ID_MATCH_DEVICE,
+	.idVendor = 0x041e,
+	.idProduct = 0x3f04,
+	.bInterfaceClass = USB_CLASS_AUDIO,
+},
+
 /*
  * Logitech QuickCam: bDeviceClass is vendor-specific, so generic interface
  * class matches do not take effect without an explicit ID match.
@@ -97,19 +121,7 @@
 	.bInterfaceClass = USB_CLASS_AUDIO,
 	.bInterfaceSubClass = USB_SUBCLASS_AUDIO_CONTROL
 },
-/* E-Mu devices */
-{
-	.match_flags = USB_DEVICE_ID_MATCH_DEVICE,
-	.idVendor = 0x041e,
-	.idProduct = 0x3f02,
-	.bInterfaceClass = USB_CLASS_AUDIO,
-},
-{
-	.match_flags = USB_DEVICE_ID_MATCH_DEVICE,
-	.idVendor = 0x041e,
-	.idProduct = 0x3f04,
-	.bInterfaceClass = USB_CLASS_AUDIO,
-},
+
 /*
  * Yamaha devices
  */
@@ -1165,19 +1177,6 @@ YAMAHA_DEVICE(0x7010, "UB99"),
 		}
 	}
 },
-{
-	USB_DEVICE(0x582, 0x00a6),
-	.driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
-		.vendor_name = "Roland",
-		.product_name = "Juno-G",
-		.ifnum = 0,
-		.type = QUIRK_MIDI_FIXED_ENDPOINT,
-		.data = & (const struct snd_usb_midi_endpoint_info) {
-			.out_cables = 0x0001,
-			.in_cables  = 0x0001
-		}
-	}
-},
 {	/*
 	 * This quirk is for the "Advanced" modes of the Edirol UA-25.
 	 * If the switch is not in an advanced setting, the UA-25 has
@@ -1336,6 +1335,19 @@ YAMAHA_DEVICE(0x7010, "UB99"),
 },
 	/* TODO: add Edirol MD-P1 support */
 {
+	USB_DEVICE(0x582, 0x00a6),
+	.driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
+		.vendor_name = "Roland",
+		.product_name = "Juno-G",
+		.ifnum = 0,
+		.type = QUIRK_MIDI_FIXED_ENDPOINT,
+		.data = & (const struct snd_usb_midi_endpoint_info) {
+			.out_cables = 0x0001,
+			.in_cables  = 0x0001
+		}
+	}
+},
+{
 	/* Roland SH-201 */
 	USB_DEVICE(0x0582, 0x00ad),
 	.driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
@@ -1719,17 +1731,6 @@ YAMAHA_DEVICE(0x7010, "UB99"),
 	}
 },
 
-{
-	/* Creative Sound Blaster MP3+ */
-	USB_DEVICE(0x041e, 0x3010),
-	.driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
-		.vendor_name = "Creative Labs",
-		.product_name = "Sound Blaster MP3+",
-		.ifnum = QUIRK_NO_INTERFACE
-	}
-	
-},
-
 /* Emagic devices */
 {
 	USB_DEVICE(0x086a, 0x0001),

-- 

  parent reply	other threads:[~2008-08-04 20:32 UTC|newest]

Thread overview: 34+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <20080804200515.110033151@mini.kroah.org>
2008-08-04 20:13 ` [patch 00/33] 2.6.25-stable review cycle Greg KH
2008-08-04 20:14   ` [patch 01/33] romfs_readpage: dont report errors for pages beyond i_size Greg KH
2008-08-04 20:14   ` [patch 02/33] x86: ioremap of 64-bit resource on 32-bit kernel fix Greg KH
2008-08-04 20:14   ` [patch 03/33] SCSI: megaraid_mbox: fix Dell CERC firmware problem Greg KH
2008-08-04 20:14   ` [patch 04/33] return to old errno choice in mkdir() et.al Greg KH
2008-08-04 20:14   ` [patch 05/33] POWERPC: PS3: Add time include to lpm Greg KH
2008-08-04 20:14   ` [patch 06/33] NFS: Ensure we zap only the access and acl caches when setting new acls Greg KH
2008-08-04 20:14   ` [patch 07/33] jbd: fix the way the b_modified flag is cleared Greg KH
2008-08-04 20:15   ` [patch 08/33] jbd: fix race between free buffer and commit transaction Greg KH
2008-08-04 20:15   ` [patch 09/33] jbd: fix possible journal overflow issues Greg KH
2008-08-04 20:15   ` [patch 10/33] Input: i8042 - retry failed CTR writes when resuming Greg KH
2008-08-04 20:15   ` [patch 11/33] Input: i8042 - add Intel D845PESV to nopnp list Greg KH
2008-08-04 20:15   ` [patch 12/33] Input: i8042 - add Gericom Bellagio to nomux blacklist Greg KH
2008-08-04 20:15   ` [patch 13/33] Input: i8042 - add Fujitsu-Siemens Amilo Pro V2030 to nomux table Greg KH
2008-08-04 20:15   ` [patch 14/33] Input: i8042 - add Fujitsu-Siemens Amilo Pro 2010 to nomux list Greg KH
2008-08-04 20:15   ` [patch 15/33] Input: i8042 - add Acer Aspire 1360 to nomux blacklist Greg KH
2008-08-04 20:15   ` [patch 16/33] FAT_VALID_MEDIA(): remove pointless test Greg KH
2008-08-04 20:15   ` [patch 17/33] fat: detect media without partition table correctly Greg KH
2008-08-04 20:15   ` [patch 18/33] Bluetooth: Signal user-space for HIDP and BNEP socket errors Greg KH
2008-08-04 20:15   ` [patch 19/33] bay: exit if notify handler cannot be installed Greg KH
2008-08-04 20:15   ` [patch 20/33] ath5k: Use software encryption for now Greg KH
2008-08-04 20:16   ` [patch 21/33] Add compat handler for PTRACE_GETSIGINFO Greg KH
2008-08-04 20:16   ` [patch 22/33] ACPI: Reject below-freezing temperatures as invalid critical temperatures Greg KH
2008-08-04 20:16   ` [patch 23/33] ACPI: update thermal temperature Greg KH
2008-08-04 20:16   ` [patch 24/33] Input: appletouch - implement reset-resume logic Greg KH
2008-08-04 20:16   ` [patch 25/33] USB: EHCI: fix remote-wakeup regression Greg KH
2008-08-04 20:16   ` [patch 26/33] pci: VT3336 cant do MSI either Greg KH
2008-08-04 20:16   ` [patch 27/33] ALSA: ac97 - Fix ASUS A9T laptop output Greg KH
2008-08-04 20:16   ` [patch 28/33] ALSA: Add more fallbacks to OSS PHONEOUT mixer map Greg KH
2008-08-04 20:16   ` [patch 29/33] ALSA: emu10k1 - Fix inverted Analog/Digital mixer switch on Audigy2 Greg KH
2008-08-04 20:16   ` Greg KH [this message]
2008-08-04 20:16   ` [patch 31/33] ALSA: hda - Add missing Thinkpad Z60m support Greg KH
2008-08-04 20:16   ` [patch 32/33] ALSA: hda - Fix wrong volumes in AD1988 auto-probe mode Greg KH
2008-08-04 20:16   ` [patch 33/33] vfs: fix lookup on deleted directory Greg KH

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20080804201624.GE1139@suse.de \
    --to=gregkh@suse.de \
    --cc=akpm@linux-foundation.org \
    --cc=alan@lxorguk.ukuu.org.uk \
    --cc=cavokz@gmail.com \
    --cc=cebbert@redhat.com \
    --cc=chuckw@quantumlinux.com \
    --cc=davej@redhat.com \
    --cc=eteo@redhat.com \
    --cc=jake@lwn.net \
    --cc=jmforbes@linuxtx.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mkrufky@linuxtv.org \
    --cc=rbranco@la.checkpoint.com \
    --cc=rdunlap@xenotime.net \
    --cc=reviews@ml.cw.f00f.org \
    --cc=stable@kernel.org \
    --cc=tiwai@suse.de \
    --cc=torvalds@linux-foundation.org \
    --cc=tytso@mit.edu \
    --cc=w@1wt.eu \
    --cc=zwane@arm.linux.org.uk \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox