Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756593AbZDNO2U (ORCPT ); Tue, 14 Apr 2009 10:28:20 -0400 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1756595AbZDNO15 (ORCPT ); Tue, 14 Apr 2009 10:27:57 -0400 Received: from cantor2.suse.de ([195.135.220.15]:57410 "EHLO mx2.suse.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1756635AbZDNO1y (ORCPT ); Tue, 14 Apr 2009 10:27:54 -0400 Date: Tue, 14 Apr 2009 16:27:52 +0200 Message-ID: From: Takashi Iwai To: "Carlos R. Mafra" Cc: linux-kernel@vger.kernel.org, alsa-devel@vger.kernel.org Subject: Re: General protection fault when unloading snd_hda_intel on 2.6.30-rc1+ In-Reply-To: <20090411193630.GA16968@Pilar.aei.mpg.de> References: <20090411193630.GA16968@Pilar.aei.mpg.de> User-Agent: Wanderlust/2.12.0 (Your Wildest Dreams) SEMI/1.14.6 (Maruoka) FLIM/1.14.7 (=?ISO-8859-4?Q?Sanj=F2?=) APEL/10.6 Emacs/22.3 (x86_64-suse-linux-gnu) MULE/5.0 (SAKAKI) MIME-Version: 1.0 (generated by SEMI 1.14.6 - "Maruoka") Content-Type: text/plain; charset=US-ASCII Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 8664 Lines: 224 At Sat, 11 Apr 2009 21:36:30 +0200, Carlos R. Mafra wrote: > > If I try on my Vaio VGN-FZ240E, using the latest kernel 2.6.30-rc1-00191-gd848223 > > modprobe -r snd_hda_intel > > I get the following trace (copied from dmesg): > > general protection fault: 0000 [#1] SMP > last sysfs file: /sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq > CPU 1 > Modules linked in: nvram uvcvideo videodev v4l1_compat v4l2_compat_ioctl32 snd_hda_codec_idt > usbhid snd_hda_intel(-) snd_hda_codec snd_hwdep snd_pcm sr_mod sky2 i2c_i801 iwlagn snd_timer > sg snd_page_alloc evdev ata_piix ahci libata sd_mod scsi_mod uhci_hcd ohci_hcd ehci_hcd usbcore [last unloaded: scsi_wait_scan] > Pid: 9063, comm: modprobe Not tainted 2.6.30-rc1-00191-gd848223 #48 VGN-FZ240E > RIP: 0010:[] [] input_event+0x40/0xa0 > RSP: 0018:ffff88006f283a78 EFLAGS: 00010293 > RAX: 0000000000000008 RBX: 0000000000000003 RCX: 0000000000000000 > RDX: 0000000000000007 RSI: 0000000000000005 RDI: 697665646632785c > RBP: ffff88006f283aa8 R08: 0000000004d6f76c R09: 0000000000000001 > R10: 0000000000000000 R11: 0000000000000001 R12: ffffffff805bb97c > R13: 0000000000000005 R14: 697665646632785c R15: 0000000000000000 > FS: 00007fc6c1e1c6f0(0000) GS:ffff880001028000(0000) knlGS:0000000000000000 > CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b > CR2: 000000000071bf40 CR3: 000000007e2d4000 CR4: 00000000000006e0 > DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 > DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400 > Process modprobe (pid: 9063, threadinfo ffff88006f282000, task ffff88006f206840) > Stack: > ffff88006f283aa8 0000000000000003 ffffffff805bb97c ffff88007e811cc0 > 0000000000000001 0000000000000000 ffff88006f283ae8 ffffffff80475612 > ffff88007f241ae0 0000000000000002 ffff88007d5eb010 0000000000000000 > Call Trace: > [] snd_jack_report+0x92/0xa0 > [] stac92xx_unsol_event+0x2e7/0x5e0 [snd_hda_codec_idt] > [] stac_issue_unsol_event+0x58/0x70 [snd_hda_codec_idt] > [] stac92xx_init+0x186/0x660 [snd_hda_codec_idt] > [] stac92xx_resume+0x20/0x60 [snd_hda_codec_idt] > [] hda_call_codec_resume+0x53/0x90 [snd_hda_codec] > [] snd_hda_power_up+0x40/0x70 [snd_hda_codec] > [] snd_hda_codec_write+0x45/0xa0 [snd_hda_codec] > [] restore_pincfgs+0x6a/0xa0 [snd_hda_codec] > [] snd_hda_codec_free+0x35/0x120 [snd_hda_codec] > [] snd_hda_bus_free+0x68/0xb0 [snd_hda_codec] > [] snd_hda_bus_dev_free+0x14/0x20 [snd_hda_codec] > [] snd_device_free+0x71/0xd0 > [] snd_device_free_all+0x64/0x70 > [] snd_card_do_free+0x3a/0xd0 > [] snd_card_free+0xa9/0xd0 > [] azx_remove+0x18/0x2a [snd_hda_intel] > [] pci_device_remove+0x2f/0x60 > [] __device_release_driver+0x6c/0xb0 > [] driver_detach+0xa8/0xb0 > [] bus_remove_driver+0x98/0xd0 > [] driver_unregister+0x47/0x60 > [] pci_unregister_driver+0x4c/0xc0 > [] alsa_card_azx_exit+0x10/0x12 [snd_hda_intel] > [] sys_delete_module+0x18b/0x240 > [] ? up_write+0x9/0x10 > [] system_call_fastpath+0x16/0x1b > Code: 89 5d d8 4c 89 65 e0 49 89 fe 41 89 f5 41 89 cf 83 fe 1f 76 16 48 8b 5d d8 4c 8b 65 > e0 4c 8b 6d e8 4c 8b 75 f0 4c 8b 7d f8 c9 c3 <0f> a3 77 20 19 c0 85 c0 74 e0 48 8d 9f f8 06 00 00 89 55 d0 48 > RIP [] input_event+0x40/0xa0 > RSP > ---[ end trace 7fa0517f56c40085 ]--- This seems happening in the path exciting the codec again in the release due to restoration of the pin defcfg values. Could you try the patch below, or merge for-next or master branch of sound git tree? git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound-2.6.git Thanks, Takashi --- diff --git a/include/sound/jack.h b/include/sound/jack.h index 6b013c6..f236e42 100644 --- a/include/sound/jack.h +++ b/include/sound/jack.h @@ -50,6 +50,8 @@ struct snd_jack { int type; const char *id; char name[100]; + void *private_data; + void (*private_free)(struct snd_jack *); }; #ifdef CONFIG_SND_JACK diff --git a/sound/core/jack.c b/sound/core/jack.c index c8254c6..d54d1a0 100644 --- a/sound/core/jack.c +++ b/sound/core/jack.c @@ -35,6 +35,9 @@ static int snd_jack_dev_free(struct snd_device *device) { struct snd_jack *jack = device->device_data; + if (jack->private_free) + jack->private_free(jack); + /* If the input device is registered with the input subsystem * then we need to use a different deallocator. */ if (jack->registered) diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index 1f2ad76..56ce19e 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c @@ -350,12 +350,20 @@ static int conexant_mux_enum_put(struct snd_kcontrol *kcontrol, } #ifdef CONFIG_SND_JACK +static void conexant_free_jack_priv(struct snd_jack *jack) +{ + struct conexant_jack *jacks = jack->private_data; + jacks->nid = 0; + jacks->jack = NULL; +} + static int conexant_add_jack(struct hda_codec *codec, hda_nid_t nid, int type) { struct conexant_spec *spec; struct conexant_jack *jack; const char *name; + int err; spec = codec->spec; snd_array_init(&spec->jacks, sizeof(*jack), 32); @@ -368,7 +376,12 @@ static int conexant_add_jack(struct hda_codec *codec, jack->nid = nid; jack->type = type; - return snd_jack_new(codec->bus->card, name, type, &jack->jack); + err = snd_jack_new(codec->bus->card, name, type, &jack->jack); + if (err < 0) + return err; + jack->jack->private_data = jack; + jack->jack->private_free = conexant_free_jack_priv; + return 0; } static void conexant_report_jack(struct hda_codec *codec, hda_nid_t nid) @@ -455,8 +468,10 @@ static void conexant_free(struct hda_codec *codec) if (spec->jacks.list) { struct conexant_jack *jacks = spec->jacks.list; int i; - for (i = 0; i < spec->jacks.used; i++) - snd_device_free(codec->bus->card, &jacks[i].jack); + for (i = 0; i < spec->jacks.used; i++, jacks++) { + if (jacks->jack) + snd_device_free(codec->bus->card, jacks->jack); + } snd_array_free(&spec->jacks); } #endif diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 61996a2..ce30b45 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -3851,6 +3851,15 @@ static void stac_gpio_set(struct hda_codec *codec, unsigned int mask, AC_VERB_SET_GPIO_DATA, gpiostate); /* sync */ } +#ifdef CONFIG_SND_JACK +static void stac92xx_free_jack_priv(struct snd_jack *jack) +{ + struct sigmatel_jack *jacks = jack->private_data; + jacks->nid = 0; + jacks->jack = NULL; +} +#endif + static int stac92xx_add_jack(struct hda_codec *codec, hda_nid_t nid, int type) { @@ -3860,6 +3869,7 @@ static int stac92xx_add_jack(struct hda_codec *codec, int def_conf = snd_hda_codec_get_pincfg(codec, nid); int connectivity = get_defcfg_connect(def_conf); char name[32]; + int err; if (connectivity && connectivity != AC_JACK_PORT_FIXED) return 0; @@ -3876,10 +3886,15 @@ static int stac92xx_add_jack(struct hda_codec *codec, snd_hda_get_jack_connectivity(def_conf), snd_hda_get_jack_location(def_conf)); - return snd_jack_new(codec->bus->card, name, type, &jack->jack); -#else - return 0; + err = snd_jack_new(codec->bus->card, name, type, &jack->jack); + if (err < 0) { + jack->nid = 0; + return err; + } + jack->jack->private_data = jack; + jack->jack->private_free = stac92xx_free_jack_priv; #endif + return 0; } static int stac_add_event(struct sigmatel_spec *spec, hda_nid_t nid, @@ -4138,8 +4153,10 @@ static void stac92xx_free_jacks(struct hda_codec *codec) if (!codec->bus->shutdown && spec->jacks.list) { struct sigmatel_jack *jacks = spec->jacks.list; int i; - for (i = 0; i < spec->jacks.used; i++) - snd_device_free(codec->bus->card, &jacks[i].jack); + for (i = 0; i < spec->jacks.used; i++, jacks++) { + if (jacks->jack) + snd_device_free(codec->bus->card, jacks->jack); + } } snd_array_free(&spec->jacks); #endif -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/