<html>
  <head>

    <meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
  </head>
  <body bgcolor="#FFFFFF" text="#000000">
    <meta http-equiv="content-type" content="text/html;
      charset=ISO-8859-1">
    <span style="color: rgb(0, 0, 0); font-family: Arial, Helvetica,
      sans-serif; font-size: 13px; font-style: normal; font-variant:
      normal; font-weight: normal; letter-spacing: normal; line-height:
      normal; orphans: 2; text-align: -webkit-auto; text-indent: 0px;
      text-transform: none; white-space: normal; widows: 2;
      word-spacing: 0px; -webkit-text-size-adjust: auto;
      -webkit-text-stroke-width: 0px; display: inline !important; float:
      none; "></span>Hello,<br>
    <br>
    I've been trying to connect an HP ScanJet 5590 to an Atheros AR7241
    rev 1 system (MIPS 24Kc V7.4 CPU), using OpenWrt. The CPU is big
    endian. I got the error:<br>
    <tt><br>
      [hp5590] hp5590_get_ack<br>
      [sanei_usb] sanei_usb_control_msg: rtype = 0xc0, req = 12, value =
      142, index = 32, len = 1<br>
      USB error: error sending control message: Connection timed out<br>
      [sanei_usb] sanei_usb_control_msg: libusb complained: error
      sending control message: Connection timed out<br>
      [hp5590] hp5590_get_ack: USB-in-USB: error getting acknowledge</tt>
    <meta http-equiv="content-type" content="text/html;
      charset=ISO-8859-1">
    <br>
    <br>
    Using SANE_DEBUG_SANEI_USB=255 and SANE_DEBUG_HP5590=255 I got
    exactly the same result (even print_buffer() output was the same) as
    another user who tried to use this backend on a PPC (see this post:
    <meta http-equiv="content-type" content="text/html;
      charset=ISO-8859-1">
    <a
href="http://lists.alioth.debian.org/pipermail/sane-devel/2010-June/026900.html">http://lists.alioth.debian.org/pipermail/sane-devel/2010-June/026900.html</a>).<br>
    <br>
    So I tried to run the same device under a little endian platform and
    I saw a difference:<br>
    <br>
    <tt>Little Endian (working)<br>
      =======================<br>
      [hp5590] hp5590_init_scanner<br>
      [hp5590] hp5590_cmd: USB-in-USB: command : 0012<br>
      [hp5590] hp5590_control_msg: USB-in-USB: core data: no<br>
      [hp5590] hp5590_control_msg: USB-in-USB: sending control msg<br>
      [sanei_usb] sanei_usb_control_msg: rtype = 0x40, req = 4, value =
      143, index = 0, len = 8<br>
      [sanei_usb] 0000: C0 04 00 12 00 00 32 00 <br>
      <br>
      Big Endian (not working)<br>
      ========================<br>
      [hp5590] hp5590_init_scanner<br>
      [hp5590] hp5590_cmd: USB-in-USB: command : 0012<br>
      [hp5590] hp5590_control_msg: USB-in-USB: core data: no<br>
      [hp5590] hp5590_control_msg: USB-in-USB: sending control msg<br>
      [sanei_usb] sanei_usb_control_msg: rtype = 0x40, req = 4, value =
      143, index = 0, len = 8<br>
      [sanei_usb] 000 C0 04 00 12 00 00 00 32</tt><br>
    <br>
    There is a difference in the version of the backend (1.0.19 for
    little endian, 1.0.22 for big endian), so the output is not exactly
    identical, but in the last line you see that the last two bytes are
    swapped. This goes to hp5590_control_msg(), in hp5590_low.c line 251
    and line 323 (version 1.0.22):<br>
    <br>
    <tt>246: memset (&ctrl, 0, sizeof (ctrl));<br>
      247: ctrl.bRequestType = 0xc0;<br>
      248: ctrl.bRequest = request;<br>
      249: ctrl.wValue = htons (value);<br>
      250: ctrl.wIndex = htons (index);<br>
      251: ctrl.wLength = size;</tt><br>
    <br>
    Since the module does work in little endian, and the content of ctrl
    is passed through, I assume that the hardware wants ctrl.wLength in
    little endian, so I replaced it with:<br>
    <tt><br>
      ctrl.wLength = htole16 (size);</tt><br>
    <br>
    Then, in hp5590_verify_last_cmd(), the code calls
    hp5590_control_msg() to retrieve a uint16_t buffer (line 469) to
    read it as it is returned without any byte swap (line 477). To
    correct this I've added the same command as above, assuming that the
    hardware does return a little endian 16-bit value:<br>
    <br>
    <tt>verify_cmd = le16toh (verify_cmd);</tt><br>
    <br>
    I've tested the scanner with such modification and it works, but
    I've not tested it for regressions in little endian. The patch is
    attached.<br>
    <br>
    Regards,<br>
    Nhan<br>
    <br>
  </body>
</html>