Date: Wed, 10 Feb 2010 17:38:08 +1030 From: "Daniel O'Connor" <doconnor@gsoft.com.au> To: freebsd-usb@freebsd.org Subject: usb_interrupt_read blocks "forever" sometimes Message-ID: <201002101738.30753.doconnor@gsoft.com.au>
index | next in thread | raw e-mail
[-- Attachment #1 --]
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
[-- Attachment #2 --]
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.12 (FreeBSD)
iD8DBQBLcltu5ZPcIHs/zowRArvvAJ9od5hnf94qPGFkPz7nSLjw/vtMxwCgln6G
ZvkQnEFw9bzem+h/hiRIgcs=
=BaVK
-----END PGP SIGNATURE-----
help
Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201002101738.30753.doconnor>
