Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 17 Jul 2009 22:26:51 +0200 (CEST)
From:      Juergen Lock <nox@jelal.kn-bremen.de>
To:        hselasky@c2i.net
Cc:        freebsd-usb@freebsd.org
Subject:   Re: Failing controls transfers in VMware
Message-ID:  <200907172026.n6HKQpbQ070554@triton.kn-bremen.de>
In-Reply-To: <200907012107.48635.hselasky@c2i.net>
References:  <4A4A5D7E.70708@nurfuerspam.de> <200907010913.08747.hselasky@c2i.net> <4A4BAB8D.9000502@nurfuerspam.de>

next in thread | previous in thread | raw e-mail | index | archive | help
In article <200907012107.48635.hselasky@c2i.net> you write:
>On Wednesday 01 July 2009 20:31:41 Markus Dolze wrote:
>> Hans Petter Selasky wrote:
>> > On Tuesday 30 June 2009 22:11:47 Markus Dolze wrote:
>> >> Markus Dolze wrote:
>> >>> To repeat run the attached program:
>> >>>
>> >>>    1. Fill in some vendor / product ID of a device detected as ugen
>> >>> device 2. Compile and run the code (devel/libusb must be installed).
>> >
>> > You should use this function when reading strings:
>> >
>> > int     usb_get_string_simple(usb_dev_handle * dev, int index, char *buf,
>> > size_t buflen);
>>
>> Yes, this is more easy, but I crafted the control transfers myself to
>> show that actually the control transfer is failing.
>
>Sometimes you have to pass the exact length of the string, and not the maximum 
>length when doing the control request.

Just though I'd mention...  hplip (ports/print/hplip, actually I am testing
the port for the new version that was posted on -ports) works around a
similar issue (string fetching failing on first try) by simply retrying
the same transfer after a 2s delay.  (And I just got that working here on
7-stable by checking for a return value of -EIO in addition to 0 that was
in the original code and made my printer not work.)

 Here is that code (with the patch), see also:
	http://lists.freebsd.org/pipermail/freebsd-ports/2009-July/055840.html

..
/* This function is similar to usb_get_string_simple, but it handles zero returns. */
static int get_string_descriptor(usb_dev_handle *dev, int index, char *buf, size_t buflen)
{
   char tbuf[255];       /* Some devices choke on size > 255 */
   int ret, si, di, cnt=5;

   while (cnt--)
   {
      ret = usb_control_msg(dev, USB_ENDPOINT_IN, USB_REQ_GET_DESCRIPTOR, (USB_DT_STRING << 8) + index, 
               0x409, tbuf, sizeof(tbuf), LIBUSB_CONTROL_REQ_TIMEOUT);
      if (ret==0 || ret == -EIO)
      {
	 /* This retry is necessary for lj1000 and lj1005. des 12/12/07
         Also HP Photosmart 42xx seems to suffer transient errors with serial id */
         BUG("get_string_descriptor error result %d, retrying in 2 secs...", ret);
         sleep(2);
         continue;
      }
      break;
   }

   if (ret < 0)
   {
      BUG("unable get_string_descriptor %d: %m\n", ret); 
      return ret;
   }

   if (tbuf[1] != USB_DT_STRING)
   {
      BUG("invalid get_string_descriptor tag act=%d exp=%d\n", tbuf[1], USB_DT_STRING); 
      return -EIO;
   }

   if (tbuf[0] > ret)
   {
      BUG("invalid get_string_descriptor size act=%d exp=%d\n", tbuf[0], ret); 
      return -EFBIG;
   }

   for (di = 0, si = 2; si < tbuf[0]; si += 2)
   {
      if (di >= (buflen - 1))
         break;

      if (tbuf[si + 1])   /* high byte */
         buf[di++] = '0';
      else
         buf[di++] = tbuf[si];
   }

   buf[di] = 0;

   return di;
}
..

 Btw, something else since that question also came up on -ports, does the
new stack support accessing e.g. ulpt devices as ugen too?  I know the old
one didn't, which is why you have to take out ulpt (and umass depending
on the particular printer) out of the kernel when you want to use hplip,
which you don't have to do e.g. on (sorry :) Linux...  (As mentioned in
that other post testing head here is difficult since it has ata issues
on this box. ):

 Thanx,
	Juergen



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200907172026.n6HKQpbQ070554>