usb/137189: [usb][patch] create and use sysctl nodes for HID report descriptors

Hans Petter Selasky hselasky at freebsd.org
Mon Jul 27 21:50:04 UTC 2009


The following reply was made to PR usb/137189; it has been noted by GNATS.

From: Hans Petter Selasky <hselasky at freebsd.org>
To: Eygene Ryabinkin <rea-fbsd at codelabs.ru>
Cc: FreeBSD-gnats-submit at freebsd.org
Subject: Re: usb/137189: [usb][patch] create and use sysctl nodes for HID report descriptors
Date: Mon, 27 Jul 2009 22:41:38 +0200

 On Monday 27 July 2009 21:44:59 Eygene Ryabinkin wrote:
 > >Number:         137189
 > >Category:       usb
 > >Synopsis:       [usb][patch] create and use sysctl nodes for HID report
 > > descriptors Confidential:   no
 > >Severity:       non-critical
 > >Priority:       medium
 > >Responsible:    freebsd-usb
 > >State:          open
 > >Quarter:
 > >Keywords:
 > >Date-Required:
 > >Class:          sw-bug
 > >Submitter-Id:   current-users
 > >Arrival-Date:   Mon Jul 27 19:50:03 UTC 2009
 > >Closed-Date:
 > >Last-Modified:
 > >Originator:     Eygene Ryabinkin
 > >Release:        FreeBSD 8.0-BETA2 amd64
 > >Organization:
 >
 > Code Labs
 >
 > >Environment:
 >
 > System: FreeBSD 8.0-BETA2 amd64
 >
 > >Description:
 >
 > usbhidctl in 8.x can dump report descriptors only from the uhid(4)
 > devices.  When, for example, ums(4) or ukbd(4) grab HID devices,
 > there is no way to dump and decode their descriptors via usbhidctl.
 >
 > >How-To-Repeat:
 >
 > Run 'usbhidctl -f /dev/ums0 -d' and see how it will fail.
 >
 
 Hi,
 
 Can you change your patch, so that usbhidctl uses libusb to get the HID 
 descriptor, instead of sysctl?
 
 1) Locate all HID descriptors on a per interface basis:
 
 struct usb_hid_descriptor *
 hid_get_descriptor_from_usb(struct usb_config_descriptor *cd,
     struct usb_interface_descriptor *id)
 {
         struct usb_descriptor *desc = (void *)id;
 
         if (desc == NULL) {
                 return (NULL);
         }
         while ((desc = usb_desc_foreach(cd, desc))) {
                 if ((desc->bDescriptorType == UDESC_HID) &&
                     (desc->bLength >= USB_HID_DESCRIPTOR_SIZE(0))) {
                         return (void *)desc;
                 }
                 if (desc->bDescriptorType == UDESC_INTERFACE) {
                         break;
                 }
         }
         return (NULL);
 }
 
 2) Retrieve HID descriptor using control request:
 usb_error_t
 usbd_req_get_hid_desc(struct usb_device *udev, struct mtx *mtx,
     void **descp, uint16_t *sizep,
     struct malloc_type *mem, uint8_t iface_index)
 {
         struct usb_interface *iface = usbd_get_iface(udev, iface_index);
         struct usb_hid_descriptor *hid;
         usb_error_t err;
 
         if ((iface == NULL) || (iface->idesc == NULL)) {
                 return (USB_ERR_INVAL);
         }
         hid = hid_get_descriptor_from_usb
             (usbd_get_config_descriptor(udev), iface->idesc);
 
         if (hid == NULL) {
                 return (USB_ERR_IOERROR);
         }
         *sizep = UGETW(hid->descrs[0].wDescriptorLength);
         if (*sizep == 0) {
                 return (USB_ERR_IOERROR);
         }
         if (mtx)
                 mtx_unlock(mtx);
 
         *descp = malloc(*sizep, mem, M_ZERO | M_WAITOK);
 
         if (mtx)
                 mtx_lock(mtx);
 
         if (*descp == NULL) {
                 return (USB_ERR_NOMEM);
         }
         err = usbd_req_get_report_descriptor
             (udev, mtx, *descp, *sizep, iface_index);
 
         if (err) {
                 free(*descp, mem);
                 *descp = NULL;
                 return (err);
         }
         return (USB_ERR_NORMAL_COMPLETION);
 }
 
 See kernel code in sys/dev/usb/ for reference and man libusb.
 
 --HPS
 
 
 
 --HPS
 


More information about the freebsd-usb mailing list