[BUG] usbaudio on EHCI controller

Brandon Philips <[email protected]>
Newsgroups gmane.linux.usb.devel
Message-ID <[email protected]>
Hello-

I ran into this bug while running: krecord -d /dev/dsp1 and unplugging
my usb microphone.  

It is reproducible and the patch at the bottom of this email fixes it.
However, I feel that the root cause, which I was unable to find after a
bit of poking, isn't really fixed.

The controller is Intel Corporation 82801G (ICH7 Family) USB2 EHCI
Controller (rev 02) (prog-if 20 [EHCI]).

Backtrace, dissasembled drivers/usb/core/buffer.o, and patch follow.

Thanks,

	Brandon

BUG: unable to handle kernel paging request at virtual address 000fd460
printing eip: f8bd88fd *pde = 00000000 
Oops: 0000 [#1] SMP DEBUG_PAGEALLOC
Modules linked in: snd_usb_audio uvcvideo nls_iso8859_1 nls_cp437 vfat fat compat_ioctl32 snd_usb_lib videobuf_vmalloc videobuf_core videodev v4l1_compat v4l2_common snd_rawmidi snd_seq_device snd_hwdep battery ac thinkpad_acpi nvram thermal fan button iwl3945 mac80211 cfg80211 binfmt_misc ipt_MASQUERADE iptable_nat nf_nat nf_conntrack_ipv4 nf_conntrack ip_tables x_tables tun ipv6 berry_charge kvm_intel kvm snd_ac97_codec ac97_bus snd_pcm_oss snd_mixer_oss fuse joydev hdaps input_polldev cpufreq_userspace ieee80211 ieee80211_crypt acpi_cpufreq arc4 ecb blkcipher usb_storage snd_hda_intel pcmcia mmc_block snd_pcm snd_timer firmware_class serio_raw nsc_ircc sdhci snd ehci_hcd irda yenta_socket rsrc_nonstatic uhci_hcd soundcore i2c_i801 psmouse crc_ccitt pcmcia_core pcspkr mmc_core snd_page_a
 lloc usbcore power_supply video output processor e1000 backlight evdev

Pid: 20662, comm: krecord Not tainted (2.6.24-rc3 #25)
EIP: 0060:[<f8bd88fd>] EFLAGS: 00210286 CPU: 1
EIP is at hcd_buffer_free+0x11/0x5e [usbcore]
EAX: 000fd460 EBX: f6d0e000 ECX: 36d0e000 EDX: 00000044
ESI: 000fd460 EDI: 00000044 EBP: f6e0db40 ESP: f6c59ebc
 DS: 007b ES: 007b FS: 00d8 GS: 0000 SS: 0068
Process krecord (pid: 20662, ti=f6c58000 task=cdc0f000 task.ti=f6c58000)
Stack: f5af1e4c 00000044 f6e22c00 f8f0e550 36d0e000 f5af1dd0 00000001 f8f0e588 
       f40e4a18 f6e22800 f5969b30 f8f0fa5c f6e22800 f8e4d604 00000002 f8e1617e 
       f6e22d70 f5969b30 f8e177d8 f4072248 00000010 f7fc7000 f4072078 f6e0db40 
Call Trace:
 [<f8f0e550>] release_urb_ctx+0x2a/0x3b [snd_usb_audio]
 [<f8f0e588>] release_substream_urbs+0x27/0x75 [snd_usb_audio]
 [<f8f0fa5c>] snd_usb_hw_free+0x34/0x50 [snd_usb_audio]
 [<f8e4d604>] snd_pcm_release_substream+0x32/0x63 [snd_pcm]
 [<f8e1617e>] snd_pcm_oss_release_file+0x16/0x28 [snd_pcm_oss]
 [<f8e177d8>] snd_pcm_oss_release+0x42/0x83 [snd_pcm_oss]
 [<c0174436>] __fput+0xb1/0x15b
 [<c0171d50>] filp_close+0x51/0x58
 [<c0126db3>] put_files_struct+0x56/0x97
 [<c0127f05>] do_exit+0x214/0x671
 [<c0309ba3>] _spin_unlock+0x14/0x1c
 [<c0129c6b>] irq_exit+0x5f/0x77
 [<c01283cf>] sys_exit_group+0x0/0xd
 [<c0103ffe>] syscall_call+0x7/0xb
 =======================
Code: 56 c7 eb 05 bf ed ff ff ff b8 74 0d bf f8 e8 f4 07 56 c7 89 f8 5b 5e 5f 5d c3 57 89 d7 56 89 c6 53 89 cb 85 db 8b 4c 24 10 74 49 <8b> 00 31 d2 83 b8 60 01 00 00 00 75 0a 89 d8 5b 5e 5f e9 cd 77 
EIP: [<f8bd88fd>] hcd_buffer_free+0x11/0x5e [usbcore] SS:ESP 0068:f6c59ebc
Fixing recursive fault but reboot is needed!
hub 5-0:1.0: debounce: port 5: total 100ms stable 100ms status 0x100
hub 5-0:1.0: hub_suspend
usb usb5: bus auto-suspend
ehci_hcd 0000:00:1d.7: suspend root hub

drivers/usb/core/buffer.o:     file format elf32-i386

Disassembly of section .text:

00000000 <hcd_buffer_free>:
hcd_buffer_free():
/home/philips/kernel/linux-2.6/drivers/usb/core/buffer.c:128
	struct usb_bus 	*bus,
	size_t			size,
	void 			*addr,
	dma_addr_t		dma
)
{
   0:	57                   	push   %edi
   1:	89 d7                	mov    %edx,%edi
   3:	56                   	push   %esi
   4:	89 c6                	mov    %eax,%esi
   6:	53                   	push   %ebx
   7:	89 cb                	mov    %ecx,%ebx
/home/philips/kernel/linux-2.6/drivers/usb/core/buffer.c:132
	struct usb_hcd		*hcd = bus_to_hcd(bus);
	int 			i;

	if (!addr)
   9:	85 db                	test   %ebx,%ebx
/home/philips/kernel/linux-2.6/drivers/usb/core/buffer.c:128
	struct usb_bus 	*bus,
	size_t			size,
	void 			*addr,
	dma_addr_t		dma
)
{
   b:	8b 4c 24 10          	mov    0x10(%esp),%ecx
/home/philips/kernel/linux-2.6/drivers/usb/core/buffer.c:132
	struct usb_hcd		*hcd = bus_to_hcd(bus);
	int 			i;

	if (!addr)
   f:	74 49                	je     5a <hcd_buffer_free+0x5a>
/home/philips/kernel/linux-2.6/drivers/usb/core/buffer.c:135
		return;

	if (!bus->controller->dma_mask) {
  11:	8b 00                	mov    (%eax),%eax
/home/philips/kernel/linux-2.6/drivers/usb/core/buffer.c:136
		kfree(addr);
  13:	31 d2                	xor    %edx,%edx
/home/philips/kernel/linux-2.6/drivers/usb/core/buffer.c:135
	int 			i;

	if (!addr)
		return;

	if (!bus->controller->dma_mask) {
  15:	83 b8 60 01 00 00 00 	cmpl   $0x0,0x160(%eax)
  1c:	75 0a                	jne    28 <hcd_buffer_free+0x28>
/home/philips/kernel/linux-2.6/drivers/usb/core/buffer.c:136
		kfree(addr);
  1e:	89 d8                	mov    %ebx,%eax
/home/philips/kernel/linux-2.6/drivers/usb/core/buffer.c:147
			dma_pool_free(hcd->pool [i], addr, dma);
			return;
		}
	}
	dma_free_coherent(hcd->self.controller, size, addr, dma);
}
  20:	5b                   	pop    %ebx
  21:	5e                   	pop    %esi
  22:	5f                   	pop    %edi
/home/philips/kernel/linux-2.6/drivers/usb/core/buffer.c:136

	if (!addr)
		return;

	if (!bus->controller->dma_mask) {
		kfree(addr);
  23:	e9 fc ff ff ff       	jmp    24 <hcd_buffer_free+0x24>
			24: R_386_PC32	kfree
/home/philips/kernel/linux-2.6/drivers/usb/core/buffer.c:141
		return;
	}

	for (i = 0; i < HCD_BUFFER_POOLS; i++) {
		if (size <= pool_max [i]) {
  28:	3b 3c 95 00 00 00 00 	cmp    0x0(,%edx,4),%edi
			2b: R_386_32	.rodata
  2f:	77 11                	ja     42 <hcd_buffer_free+0x42>
/home/philips/kernel/linux-2.6/drivers/usb/core/buffer.c:142
			dma_pool_free(hcd->pool [i], addr, dma);
  31:	8b 84 96 e4 00 00 00 	mov    0xe4(%esi,%edx,4),%eax
  38:	89 da                	mov    %ebx,%edx
/home/philips/kernel/linux-2.6/drivers/usb/core/buffer.c:147
			return;
		}
	}
	dma_free_coherent(hcd->self.controller, size, addr, dma);
}
  3a:	5b                   	pop    %ebx
  3b:	5e                   	pop    %esi
  3c:	5f                   	pop    %edi
/home/philips/kernel/linux-2.6/drivers/usb/core/buffer.c:142
		return;
	}

	for (i = 0; i < HCD_BUFFER_POOLS; i++) {
		if (size <= pool_max [i]) {
			dma_pool_free(hcd->pool [i], addr, dma);
  3d:	e9 fc ff ff ff       	jmp    3e <hcd_buffer_free+0x3e>
			3e: R_386_PC32	dma_pool_free
/home/philips/kernel/linux-2.6/drivers/usb/core/buffer.c:140
	if (!bus->controller->dma_mask) {
		kfree(addr);
		return;
	}

	for (i = 0; i < HCD_BUFFER_POOLS; i++) {
  42:	42                   	inc    %edx
  43:	83 fa 04             	cmp    $0x4,%edx
  46:	75 e0                	jne    28 <hcd_buffer_free+0x28>
/home/philips/kernel/linux-2.6/drivers/usb/core/buffer.c:146
		if (size <= pool_max [i]) {
			dma_pool_free(hcd->pool [i], addr, dma);
			return;
		}
	}
	dma_free_coherent(hcd->self.controller, size, addr, dma);
  48:	89 4c 24 10          	mov    %ecx,0x10(%esp)
  4c:	89 d9                	mov    %ebx,%ecx
  4e:	89 fa                	mov    %edi,%edx
/home/philips/kernel/linux-2.6/drivers/usb/core/buffer.c:147
}
  50:	5b                   	pop    %ebx
/home/philips/kernel/linux-2.6/drivers/usb/core/buffer.c:146
		if (size <= pool_max [i]) {
			dma_pool_free(hcd->pool [i], addr, dma);
			return;
		}
	}
	dma_free_coherent(hcd->self.controller, size, addr, dma);
  51:	8b 06                	mov    (%esi),%eax
/home/philips/kernel/linux-2.6/drivers/usb/core/buffer.c:147
}
  53:	5e                   	pop    %esi
  54:	5f                   	pop    %edi
/home/philips/kernel/linux-2.6/drivers/usb/core/buffer.c:146
		if (size <= pool_max [i]) {
			dma_pool_free(hcd->pool [i], addr, dma);
			return;
		}
	}
	dma_free_coherent(hcd->self.controller, size, addr, dma);
  55:	e9 fc ff ff ff       	jmp    56 <hcd_buffer_free+0x56>
			56: R_386_PC32	dma_free_coherent
/home/philips/kernel/linux-2.6/drivers/usb/core/buffer.c:147
}
  5a:	5b                   	pop    %ebx
  5b:	5e                   	pop    %esi
  5c:	5f                   	pop    %edi
  5d:	c3                   	ret    

diff --git a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c
index 967b823..e4151a0 100644
--- a/sound/usb/usbaudio.c
+++ b/sound/usb/usbaudio.c
@@ -1484,8 +1484,10 @@ static int snd_usb_hw_free(struct snd_pcm_substream *substream)
 	subs->cur_audiofmt = NULL;
 	subs->cur_rate = 0;
 	subs->period_bytes = 0;
+	mutex_lock(&register_mutex);
 	if (!subs->stream->chip->shutdown)
 		release_substream_urbs(subs, 0);
+	mutex_unlock(&register_mutex);
 	return snd_pcm_free_vmalloc_buffer(substream);
 }
 

-------------------------------------------------------------------------
SF.Net email is sponsored by: The Future of Linux Business White Paper
from Novell.  From the desktop to the data center, Linux is going
mainstream.  Let it simplify your IT future.
http://altfarm.mediaplex.com/ad/ck/8857-50307-18918-4
_______________________________________________
[email protected]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.