usb_interrupt_read blocks "forever" sometimes

Daniel O'Connor doconnor at gsoft.com.au
Wed Feb 10 07:08:38 UTC 2010


I am trying to talk to my WH1080 weather station and I find that 
sometimes when I start the program it will stall forever in 
usb_interrupt_read even though the timeout specified is 50 milliseconds.

I also tried using alarm() but that doesn't cause the transfer to abort 
(it appears the libusb code loops and doesn't check for EINTR).

The code in question is..
    signal(SIGALRM, alarmhandler);
    alarm(1);

    do {
    if ((bytes_read = usb_interrupt_read (station,
                                          USB_ENDPOINT_IN | USB_RECIP_INTERFACE,
                                          buf,
                                          8,
                                          100 )) == 8 ){
      if (i > 0)
        fprintf(stderr, "Read OK after %d tries\n", i + 1);
      return bytes_read;
    }
    if (errno == EINTR)
      fprintf(stderr, "Alarmed\n");
      
    fprintf(stderr, "Retrying..\n");

    if (errno == EAGAIN)
      usleep (10000);
    i++;
  }
  while (errno != EINTR && i < MAXTRIES);
...
(Then stuff printing out if we get EINTR etc)

The general procedure is to issue a request on the control endpoint and
then read the result via the interrupt end point in 8 byte pieces.

The retry stuff is there because I was having issues with reliable reads.

The alarm handler doesn't seem to get called sometimes, maybe one in 10
starts causes usb_interrupt_read to hang in..
(gdb) bt
#0  0x0000000800a8086c in poll () from /lib/libc.so.7
#1  0x000000080077531d in libusb20_dev_wait_process (pdev=0x7fffffffe870, timeout=1) 
at /usr/src/lib/libusb/libusb20.c:979
#2  0x000000080076f78c in usb_std_io (dev=0x801044d00, ep=Variable "ep" is not available.
) at /usr/src/lib/libusb/libusb20_compat01.c:598
#3  0x000000000040180d in read_station (buf=0x5048d0 "ÿÿÿÿÿÿÿÿ\036 \0040\021") at wh1080.c:249

Other starts I find it fails 10 times, retries the control message and
works fine - I figure the micro has issues missing requests.

The missing SIGALRM seems much worse though - how can it be masked? Of
course if usb_interrupt_read honored its timeout that wouldn't matter :)

The device reports as..
ugen0.5: <product 0x8021 vendor 0x1941> at usbus0, cfg=0 md=HOST spd=LOW (1.5Mbps) pwr=ON


 Configuration index 0

    bLength = 0x0009
    bDescriptorType = 0x0002
    wTotalLength = 0x0022
    bNumInterfaces = 0x0001
    bConfigurationValue = 0x0001
    iConfiguration = 0x0000  <no string>
    bmAttributes = 0x0080
    bMaxPower = 0x0032

    Interface 0
      bLength = 0x0009
      bDescriptorType = 0x0004
      bInterfaceNumber = 0x0000
      bAlternateSetting = 0x0000
      bNumEndpoints = 0x0001
      bInterfaceClass = 0x0003
      bInterfaceSubClass = 0x0000
      bInterfaceProtocol = 0x0000
      iInterface = 0x0000  <no string>

      Additional Descriptor

      bLength = 0x09
      bDescriptorType = 0x21
      bDescriptorSubType = 0x00
       RAW dump:
       0x00 | 0x09, 0x21, 0x00, 0x01, 0x00, 0x01, 0x22, 0x34,
       0x08 | 0x00

     Endpoint 0
        bLength = 0x0007
        bDescriptorType = 0x0005
        bEndpointAddress = 0x0081  <IN>
        bmAttributes = 0x0003  <INTERRUPT>
        wMaxPacketSize = 0x0008
        bInterval = 0x000a
        bRefresh = 0x0000
        bSynchAddress = 0x0000



Any help appreciated, thanks!

PS please CC me.

-- 
Daniel O'Connor software and network engineer
for Genesis Software - http://www.gsoft.com.au
"The nice thing about standards is that there
are so many of them to choose from."
  -- Andrew Tanenbaum
GPG Fingerprint - 5596 B766 97C0 0E94 4347 295E E593 DC20 7B3F CE8C
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 188 bytes
Desc: This is a digitally signed message part.
Url : http://lists.freebsd.org/pipermail/freebsd-usb/attachments/20100210/610c3743/attachment.pgp


More information about the freebsd-usb mailing list