Hello!

I am trying to get the UPS shutdown working on APC BackUPS CS 500.  Its
HID report descriptor has many report IDs; the full dump from hid-core.c
is at the end of message.  The value which needs to be set is:

   FEATURE(64)[FEATURE]
     Field(0)
       Physical(ff86.0005)
       Usage(1)
         ff86.007c
       Logical Minimum(0)
       Logical Maximum(1)
       Report Size(8)
       Report Count(1)
       Report Offset(0)
       Flags( Variable Absolute Volatile )

I am using kernel 2.4.20 (with selected -ac and -pre3 patches - there
are some changes to hid-core.c, but they only add some USB IDs, which do
not match my device).

The first problem I have found was that hid_write_report() did not set
the proper report type in the high byte of wValue (0x200 was hardcoded,
which identifies the output report - but the feature report is needed).
Fixing this was easy - replacing 0x200 by ((report->type + 1) << 8) (I
see this is already in the 2.5 tree); however, this still was not
enough:

Mar 31 20:02:41 center4 apctest: Attempting to kill the UPS power!
Mar 31 20:02:41 center4 kernel: usb-uhci.c: interrupt, status 3, frame# 241
Mar 31 20:02:41 center4 kernel: hid-debug: input 0084.0030 = 1304
Mar 31 20:02:41 center4 kernel: hid-debug: input 0085.008c = 50
Mar 31 20:02:41 center4 kernel: hid-debug: input 0085.0029 = 10
Mar 31 20:02:41 center4 kernel: hid-debug: input ff86.007c = 0
Mar 31 20:02:41 center4 kernel: usb-uhci.c: ENXIO 84000280, flags 0, urb c1be0d60, 
burb c3d44cf8
Mar 31 20:02:41 center4 kernel: usb-uhci.c: ENXIO 84000280, flags 0, urb c1be0d60, 
burb c3d44cf8
Mar 31 20:02:41 center4 kernel: hid-core.c: ctrl urb status -32 received
Mar 31 20:02:41 center4 last message repeated 2 times

I have started to look for another reason why the UPS does not accept
the command.  In the USB HID specification I have found the following
text (section 5.6 Reports):

        If a device has multiple report structures, all data transfers
        start with a 1-byte identifier prefix that indicates which
        report structure applies to the transfer. This allows the class
        driver to distinguish incoming pointer data from keyboard data
        by examining the transfer prefix.

There is no indication whether this applies only to the data received
from the Interrupt In pipe, or also to the Interrupt Out pipe and
Control pipe.

I have tried to add the report ID byte to the request - and it worked!
The UPS started flashing alternately "On Line" and "Overload", and about
45 seconds later turned itself off.  The "ENXIO" log messages went away.

So it looks that at least this UPS wants to see the report ID inside the
data packet in the HID_SET_REPORT control transfer - even if the same
information is available in the low byte of wValue.

Is this the correct reading of the USB HID specification?  If it is,
hid-core.c in 2.5 is also wrong - it does not add an extra byte with
report ID in output requests:

vojtech   1.12        |         if (dir == USB_DIR_OUT)
vojtech   1.12        |                 hid_output_report(report, hid->ctrlbuf);
vojtech   1.12        | 
vojtech   1.12        |         hid->urbctrl->transfer_buffer_length = ((report->size 
- 1) >> 3) + 1 + ((report->id > 0) && (dir != USB_DIR_OUT));
vojtech   1.12        |         hid->urbctrl->pipe = (dir == USB_DIR_OUT) ?  
usb_sndctrlpipe(hid->dev, 0) : usb_rcvctrlpipe(hid->dev, 0);
vojtech   1.12        |         hid->urbctrl->dev = hid->dev;

Does anyone know any other HID devices which have settable
features/output values and also use report IDs?  Do they have similar
behavior?

I have made the following changes (WARNING: this is incomplete and will
break other devices!!!  Need to check if report ids are really used):


--- linux-2.4.20/drivers/usb/hid-core.c.alt-hid Tue Mar 18 17:09:28 2003
+++ linux-2.4.20/drivers/usb/hid-core.c Tue Apr  1 16:17:13 2003
@@ -41,8 +41,8 @@
 #include <asm/unaligned.h>
 #include <linux/input.h>
 
-#undef DEBUG
-#undef DEBUG_DATA
+#define DEBUG
+#define DEBUG_DATA
 
 #include <linux/usb.h>
 
@@ -993,6 +993,23 @@
        hid->urbout.setup_packet = (void *) &(hid->out[hid->outtail].dr);
        hid->urbout.dev = hid->dev;
 
+#ifdef DEBUG_DATA
+       {
+               unsigned size = hid->urbout.transfer_buffer_length;
+               unsigned n;
+               const u8 *buf = (const u8 *) hid->urbout.transfer_buffer;
+
+               printk(KERN_DEBUG __FILE__ ": submit_out (size %u, wValue=0x%04x, 
wIndex=0x%04x) = ",
+                      size,
+                      le16_to_cpup(&hid->out[hid->outtail].dr.wValue),
+                      le16_to_cpup(&hid->out[hid->outtail].dr.wIndex)
+                      );
+               for (n = 0; n < size; n++)
+                       printk(" %02x", (unsigned) buf[n]);
+               printk("\n");
+       }
+#endif
+
        if (usb_submit_urb(&hid->urbout)) {
                err("usb_submit_urb(out) failed");
                return -1;
@@ -1016,10 +1033,11 @@
 
 void hid_write_report(struct hid_device *hid, struct hid_report *report)
 {
-       hid_output_report(report, hid->out[hid->outhead].buffer);
+       hid->out[hid->outhead].buffer[0] = report->id; //XXX
+       hid_output_report(report, hid->out[hid->outhead].buffer + 1);
 
-       hid->out[hid->outhead].dr.wValue = cpu_to_le16(0x200 | report->id);
-       hid->out[hid->outhead].dr.wLength = cpu_to_le16((report->size + 7) >> 3);
+       hid->out[hid->outhead].dr.wValue = cpu_to_le16(((report->type + 1) << 8) | 
report->id);
+       hid->out[hid->outhead].dr.wLength = cpu_to_le16((report->size + 7) >> 3) + 1; 
//XXX
 
        hid->outhead = (hid->outhead + 1) & (HID_CONTROL_FIFO_SIZE - 1);
 




Full HID descriptor dump from APC BackUPS CS 500:

 Application(0084.0004)
   INPUT(6)[INPUT]
     Field(0)
       Physical(0084.0024)
       Usage(1)
         0085.0044
       Logical Minimum(0)
       Logical Maximum(255)
       Report Size(8)
       Report Count(1)
       Report Offset(0)
       Flags( Variable Absolute Volatile )
     Field(1)
       Physical(0084.0024)
       Usage(1)
         0085.0045
       Logical Minimum(0)
       Logical Maximum(255)
       Report Size(8)
       Report Count(1)
       Report Offset(8)
       Flags( Variable Absolute Volatile )
     Field(2)
       Physical(0084.0024)
       Usage(1)
         ff86.0060
       Logical Minimum(0)
       Logical Maximum(255)
       Report Size(8)
       Report Count(1)
       Report Offset(16)
       Flags( Variable Absolute Volatile )
   INPUT(12)[INPUT]
     Field(0)
       Physical(0084.0024)
       Usage(1)
         0085.0066
       Logical Minimum(0)
       Logical Maximum(16777214)
       Unit(1052673)
       Report Size(24)
       Report Count(1)
       Report Offset(0)
       Flags( Variable Absolute Volatile )
     Field(1)
       Physical(0084.0024)
       Usage(1)
         0085.0068
       Logical Minimum(0)
       Logical Maximum(65534)
       Unit(4097)
       Report Size(16)
       Report Count(1)
       Report Offset(24)
       Flags( Variable Absolute Volatile )
   INPUT(19)[INPUT]
     Field(0)
       Physical(0084.0024)
       Usage(1)
         0085.00d0
       Logical Minimum(0)
       Logical Maximum(1)
       Report Size(8)
       Report Count(1)
       Report Offset(0)
       Flags( Variable Absolute Volatile )
   INPUT(20)[INPUT]
     Field(0)
       Physical(0084.0024)
       Usage(1)
         0085.0042
       Logical Minimum(0)
       Logical Maximum(1)
       Report Size(8)
       Report Count(1)
       Report Offset(0)
       Flags( Variable Absolute Volatile )
     Field(1)
       Physical(0084.0024)
       Usage(1)
         0084.0069
       Logical Minimum(0)
       Logical Maximum(1)
       Report Size(8)
       Report Count(1)
       Report Offset(8)
       Flags( Variable Absolute Volatile )
   FEATURE(1)[FEATURE]
     Field(0)
       Physical(0084.0024)
       Usage(1)
         0084.00fe
       Logical Minimum(0)
       Logical Maximum(255)
       Report Size(8)
       Report Count(1)
       Report Offset(0)
       Flags( Variable Absolute )
   FEATURE(2)[FEATURE]
     Field(0)
       Physical(0084.0024)
       Usage(1)
         0084.00ff
       Logical Minimum(0)
       Logical Maximum(255)
       Report Size(8)
       Report Count(1)
       Report Offset(0)
       Flags( Variable Absolute )
   FEATURE(3)[FEATURE]
     Field(0)
       Physical(0084.0024)
       Usage(1)
         0085.0089
       Logical Minimum(0)
       Logical Maximum(255)
       Report Size(8)
       Report Count(1)
       Report Offset(0)
       Flags( Variable Absolute )
   FEATURE(4)[FEATURE]
     Field(0)
       Physical(0084.0024)
       Usage(1)
         0085.008f
       Logical Minimum(0)
       Logical Maximum(255)
       Report Size(8)
       Report Count(1)
       Report Offset(0)
       Flags( Variable Absolute )
   FEATURE(5)[FEATURE]
     Field(0)
       Physical(0084.0024)
       Usage(1)
         0085.008b
       Logical Minimum(0)
       Logical Maximum(255)
       Report Size(8)
       Report Count(1)
       Report Offset(0)
       Flags( Variable Absolute )
   FEATURE(6)[FEATURE]
     Field(0)
       Physical(0084.0024)
       Usage(1)
         0085.0044
       Logical Minimum(0)
       Logical Maximum(255)
       Report Size(8)
       Report Count(1)
       Report Offset(0)
       Flags( Variable Absolute Volatile )
     Field(1)
       Physical(0084.0024)
       Usage(1)
         0085.0045
       Logical Minimum(0)
       Logical Maximum(255)
       Report Size(8)
       Report Count(1)
       Report Offset(8)
       Flags( Variable Absolute Volatile )
     Field(2)
       Physical(0084.0024)
       Usage(1)
         ff86.0060
       Logical Minimum(0)
       Logical Maximum(255)
       Report Size(8)
       Report Count(1)
       Report Offset(16)
       Flags( Variable Absolute Volatile )
   FEATURE(7)[FEATURE]
     Field(0)
       Physical(0084.0024)
       Usage(1)
         0085.0085
       Logical Minimum(0)
       Logical Maximum(65535)
       Report Size(16)
       Report Count(1)
       Report Offset(0)
       Flags( Variable Absolute )
   FEATURE(8)[FEATURE]
     Field(0)
       Physical(0084.0024)
       Usage(1)
         0084.0040
       Logical Minimum(0)
       Logical Maximum(65534)
       Unit Exponent(5)
       Unit(15782177)
       Report Size(16)
       Report Count(1)
       Report Offset(0)
       Flags( Variable Absolute )
   FEATURE(9)[FEATURE]
     Field(0)
       Physical(0084.0024)
       Usage(1)
         0084.0030
       Logical Minimum(0)
       Logical Maximum(65534)
       Unit Exponent(5)
       Unit(15782177)
       Report Size(16)
       Report Count(1)
       Report Offset(0)
       Flags( Variable Absolute )
   FEATURE(10)[FEATURE]
     Field(0)
       Physical(0084.0024)
       Usage(1)
         0084.00fd
       Logical Minimum(0)
       Logical Maximum(255)
       Unit Exponent(5)
       Unit(15782177)
       Report Size(8)
       Report Count(1)
       Report Offset(0)
       Flags( Variable Absolute )
   FEATURE(11)[FEATURE]
     Field(0)
       Physical(0084.0024)
       Usage(1)
         0085.002c
       Logical Minimum(0)
       Logical Maximum(255)
       Unit Exponent(5)
       Unit(15782177)
       Report Size(8)
       Report Count(1)
       Report Offset(0)
       Flags( Variable Absolute )
   FEATURE(12)[FEATURE]
     Field(0)
       Physical(0084.0024)
       Usage(1)
         0085.0066
       Logical Minimum(0)
       Logical Maximum(16777214)
       Unit(1052673)
       Report Size(24)
       Report Count(1)
       Report Offset(0)
       Flags( Variable Absolute Volatile )
     Field(1)
       Physical(0084.0024)
       Usage(1)
         0085.0068
       Logical Minimum(0)
       Logical Maximum(65534)
       Unit(4097)
       Report Size(16)
       Report Count(1)
       Report Offset(24)
       Flags( Variable Absolute Volatile )
   FEATURE(13)[FEATURE]
     Field(0)
       Physical(0084.0024)
       Usage(1)
         0085.0083
       Logical Minimum(0)
       Logical Maximum(16777214)
       Unit(1052673)
       Report Size(24)
       Report Count(1)
       Report Offset(0)
       Flags( Variable Absolute )
   FEATURE(14)[FEATURE]
     Field(0)
       Physical(0084.0024)
       Usage(1)
         0085.0067
       Logical Minimum(0)
       Logical Maximum(16777214)
       Unit(1052673)
       Report Size(24)
       Report Count(1)
       Report Offset(0)
       Flags( Variable Absolute )
   FEATURE(15)[FEATURE]
     Field(0)
       Physical(0084.0024)
       Usage(1)
         0085.008c
       Logical Minimum(0)
       Logical Maximum(16777214)
       Unit(1052673)
       Report Size(24)
       Report Count(1)
       Report Offset(0)
       Flags( Variable Absolute )
   FEATURE(16)[FEATURE]
     Field(0)
       Physical(0084.0024)
       Usage(1)
         0085.008e
       Logical Minimum(0)
       Logical Maximum(16777214)
       Unit(1052673)
       Report Size(24)
       Report Count(1)
       Report Offset(0)
       Flags( Variable Absolute )
   FEATURE(17)[FEATURE]
     Field(0)
       Physical(0084.0024)
       Usage(1)
         0085.0029
       Logical Minimum(0)
       Logical Maximum(16777214)
       Unit(1052673)
       Report Size(24)
       Report Count(1)
       Report Offset(0)
       Flags( Variable Absolute Volatile )
   FEATURE(18)[FEATURE]
     Field(0)
       Physical(0084.0024)
       Usage(1)
         0085.008d
       Logical Minimum(0)
       Logical Maximum(16777214)
       Unit(1052673)
       Report Size(24)
       Report Count(1)
       Report Offset(0)
       Flags( Variable Absolute )
   FEATURE(19)[FEATURE]
     Field(0)
       Physical(0084.0024)
       Usage(1)
         0085.00d0
       Logical Minimum(0)
       Logical Maximum(1)
       Report Size(8)
       Report Count(1)
       Report Offset(0)
       Flags( Variable Absolute Volatile )
   FEATURE(20)[FEATURE]
     Field(0)
       Physical(0084.0024)
       Usage(1)
         0085.0042
       Logical Minimum(0)
       Logical Maximum(1)
       Report Size(8)
       Report Count(1)
       Report Offset(0)
       Flags( Variable Absolute Volatile )
     Field(1)
       Physical(0084.0024)
       Usage(1)
         0084.0069
       Logical Minimum(0)
       Logical Maximum(1)
       Report Size(8)
       Report Count(1)
       Report Offset(8)
       Flags( Variable Absolute Volatile )
   FEATURE(53)[FEATURE]
     Field(0)
       Physical(0084.0024)
       Usage(1)
         ff86.0072
       Logical Minimum(0)
       Logical Maximum(1)
       Report Size(8)
       Report Count(1)
       Report Offset(0)
       Flags( Variable Absolute Volatile )
   FEATURE(28)[FEATURE]
     Field(0)
       Physical(0084.0024)
       Usage(1)
         ff86.0016
       Logical Minimum(0)
       Logical Maximum(16777215)
       Report Size(24)
       Report Count(1)
       Report Offset(0)
       Flags( Variable Absolute Volatile )
   FEATURE(64)[FEATURE]
     Field(0)
       Physical(ff86.0005)
       Usage(1)
         ff86.007c
       Logical Minimum(0)
       Logical Maximum(1)
       Report Size(8)
       Report Count(1)
       Report Offset(0)
       Flags( Variable Absolute Volatile )
 hiddev0: USB HID v1.00 Joystick [American Power Conversion Back-UPS 500 FW: 6.5.I USB 
FW: c1 ] on usb2:3.0

-- 
Sergey Vlasov


-------------------------------------------------------
This SF.net email is sponsored by: ValueWeb: 
Dedicated Hosting for just $79/mo with 500 GB of bandwidth! 
No other company gives more support or power for your dedicated server
http://click.atdmt.com/AFF/go/sdnxxaff00300020aff/direct/01/
_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to