Summary: Kernel panic using usbdevfs for interrupt transfers (OHCI hcd)
Hi all, I am currently trying to use usb interrupt transfers from the usb file system. I am trying to speak to an HID device by submiting interrupt URBs at ep 1. The less i can saw is that it does not work well... The not-working program is the following : #include <stdio.h> #include <stdlib.h> #include <errno.h> #include <string.h> #include <fcntl.h> #include <unistd.h> #include <sys/ioctl.h> #include <sys/wait.h> #include <bits/signum.h> /* SIGRTMAX */ #include <signal.h> #include <linux/usbdevice_fs.h> unsigned char bytes[64]; typedef void (*usb_interrupt_handler) (int signum, siginfo_t * si, void* data); static void incoming_intr(int signum, siginfo_t * si, void* data) { struct usbdevfs_urb *purb = (struct usbdevfs_urb *) si->si_addr; int err = si->si_errno; printf("Received Interrupt with ERRCODE %u, ERRCOUNT %u and POINTER %p\n", err, purb->error_count, purb); printf("Value %llx%llx%llx%llx%llx%llx%llx%llx\n", *(unsigned long long *) data , *(unsigned long long *) (data + 8) , *(unsigned long long *) (data + 16) , *(unsigned long long *) (data + 24) , *(unsigned long long *) (data + 32) , *(unsigned long long *) (data + 40) , *(unsigned long long *) (data + 48) , *(unsigned long long *) (data + 56)); fflush(stdout); } struct usbdevfs_urb *pcururb; int usb_interrupt_enable(int fd, unsigned char ep, usb_interrupt_handler h) { struct usbdevfs_urb *purb = malloc(sizeof(struct usbdevfs_urb)); struct sigaction act; sigset_t sigset; int ret; /* zeroing buffer*/ memset(purb, 0, sizeof(struct usbdevfs_urb)); printf("urb pointer : %p\n", purb); /*sigaction */ sigemptyset(&sigset); act.sa_sigaction = incoming_intr; act.sa_mask = sigset; /* null mask */ act.sa_flags = SA_SIGINFO; sigaction(SIGRTMAX, &act, 0); /* Ensure the endpoint address is correct */ ep |= 0x80; /* preparing the urb */ purb->type = USBDEVFS_URB_TYPE_INTERRUPT; purb->endpoint = ep; purb->buffer_length = 64; purb->buffer = (unsigned char *)bytes; purb->flags = 0; purb->start_frame = -1; purb->signr = SIGRTMAX; pcururb = purb; ret = ioctl(fd, USBDEVFS_SUBMITURB, purb); if (ret != 0) fprintf(stderr, "error submitting interrupt URB at endpoint 0x%x: %s", ep, strerror(errno)); return ret == 0; } int usb_interrupt_disable(int fd, unsigned char ep) { int ret; ret = ioctl(fd, USBDEVFS_DISCARDURB, pcururb); if (ret != 0) fprintf(stderr, "error discarding interrupt URB at endpoint 0x%x: %s", ep, strerror(errno)); return ret == 0; } int main(int argc, char *argv[]) { if(argc == 2) { int fd = open(argv[1], O_RDWR); if(fd > 0) { int ret; ret = ioctl(USBDEVFS_CLAIMINTERFACE, 0); if(ret != 0) { long long i = 0; usb_interrupt_enable(fd, 1, incoming_intr); for(; i != 1; i--); usb_interrupt_disable(fd, 1);; ret = ioctl(USBDEVFS_RELEASEINTERFACE, 0); } close(fd); return 0; } return 1; } else return 1; } I don't know if i am misusing the usbdevfs, but even this leads to strange behaviour: -With an uhci host controller uhci_submit_urb() fails with EINVAL. [Tested on x86 computer ] -With an ohci host controller i have a kernel panic with i run this program at least 2 times. [Tested on 2 x86 computers] ksymoops 2.4.5 on i686 2.4.19-24mdkcustom. Options used -V (default) -k /proc/ksyms (default) -l /proc/modules (default) -o /lib/modules/2.4.19-24mdkcustom/ (default) -m /boot/System.map-2.4.19-24mdkcustom (default) Warning: You did not tell me where to find symbol information. I will assume that the log matches the kernel and modules that are running right now and I'll use the default options above for symbol resolution. If the current kernel and/or modules do not match the log, you can get more accurate output by telling me the kernel version and where to find map, modules, ksyms etc. ksymoops -h explains the options. Warning (find_objects): no *.o files in /lib/modules/2.4.19-24mdkcustom/kernel/. Is /lib/modules/2.4.19-24mdkcustom/kernel/ a valid module directory? Warning (compare_ksyms_lsmod): module ext3 is in lsmod but not in ksyms, probably no symbols exported Warning (map_ksym_to_module): cannot match loaded module jbd to a unique module object. Trace may not be reliable. *pde = 00000000 Oops: 0000 CPU: 0 EIP: 0010:[<d892ee04>] Not tainted Using defaults from ksymoops -t elf32-i386 -a i386 EFLAGS: 00010246 eax: ffffffff ebx: 00000000 ecx: cea2e55c edx: 00000000 esi: cea2e55c edx: 20687469 ebp: cd2edf58 esp: cd2edf40 ds: 0018 es: 0018 ss: 0018 d257b800 d2489000 00000002 d3e35380 04000001 cd2edfc4 cd2edf98 c010a207 0000000b d257b800 cd2edfc4 c0382a60 0000000b cd2edfc4 cd2edfbc c010a39b Call Trace: [<d892fbcd>][<c010a207>][<c010a39b>][<c010c888>] Code: 66 8b 47 06 40 66 89 47 06 66 3b 47 04 74 40 9c 5b fa 8b 45 >>EIP; d892ee04 <[usb-ohci]dl_done_list+54/110> <===== >>eax; ffffffff <END_OF_CODE+23087b3c/????> >>ecx; cea2e55c <_end+e66bcd0/1844d7d4> >>esi; cea2e55c <_end+e66bcd0/1844d7d4> >>edx; 20687469 Before first symbol >>ebp; cd2edf58 <_end+cf2b6cc/1844d7d4> >>esp; cd2edf40 <_end+cf2b6b4/1844d7d4> Trace; d892fbcd <[usb-ohci]hc_interrupt+11d/170> Trace; c010a207 <handle_IRQ_event+37/70> Trace; c010a39b <do_IRQ+7b/c0> Trace; c010c888 <call_do_IRQ+5/d> Code; d892ee04 <[usb-ohci]dl_done_list+54/110> 00000000 <_EIP>: Code; d892ee04 <[usb-ohci]dl_done_list+54/110> <===== 0: 66 8b 47 06 mov 0x6(%edi),%ax <===== Code; d892ee08 <[usb-ohci]dl_done_list+58/110> 4: 40 inc %eax Code; d892ee09 <[usb-ohci]dl_done_list+59/110> 5: 66 89 47 06 mov %ax,0x6(%edi) Code; d892ee0d <[usb-ohci]dl_done_list+5d/110> 9: 66 3b 47 04 cmp 0x4(%edi),%ax Code; d892ee11 <[usb-ohci]dl_done_list+61/110> d: 74 40 je 4f <_EIP+0x4f> d892ee53 <[usb-ohci]dl_done_list+a3/110> Code; d892ee13 <[usb-ohci]dl_done_list+63/110> f: 9c pushf Code; d892ee14 <[usb-ohci]dl_done_list+64/110> 10: 5b pop %ebx Code; d892ee15 <[usb-ohci]dl_done_list+65/110> 11: fa cli Code; d892ee16 <[usb-ohci]dl_done_list+66/110> 12: 8b 45 00 mov 0x0(%ebp),%eax <0>Kernel panic: Aiee, Killing interrupt handlers! 3 warnings issued. Results may not be reliable. Kernels tested: (both with same Kernel Panic) : -2.4.19-24mdk -2.4.21-pre5 HID peripherals tested: - Microsoft Corp. SideWinder PnP GamePad - USB mouse - Home made HID device (based on Microchip PIC16C765) Computers: - 1 AMD K6-2, 1 Athlon XP, 1 Athlon, 3 different USB Chipsets - All of them running Mandrake Linux 9.0 I think this bug is perfectly reproductible by running the previous test program and plugging an HID device. To reproduce it: -Build the kernel with input subsystem disabled -rmmod hid -run crashme /proc/bus/usb/xxx/xxx at least twice So my questions are: -Am i using usbdevfs the wrong way? *or* -Is this a kernel bug? *or* - anything else? Fabien Chevalier French Supelec Student ------------------------------------------------------- This SF.net email is sponsored by: Etnus, makers of TotalView, The debugger for complex code. Debugging C/C++ programs can leave you feeling lost and disoriented. TotalView can help you find your way. Available on major UNIX and Linux platforms. Try it free. www.etnus.com _______________________________________________ [EMAIL PROTECTED] To unsubscribe, use the last form field at: https://lists.sourceforge.net/lists/listinfo/linux-usb-users