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