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

Reply via email to