Factor-out hardware-independent part of USB HID support to new module

It will be used by the upcoming HID-over-i2C implementation.  Should be
no-op, except hid.ko module dependency is to be added to affected drivers.

Reviewed by:	hselasky, manu
Differential revision:	https://reviews.freebsd.org/D27867
This commit is contained in:
Vladimir Kondratyev 2020-10-05 01:21:08 +03:00
parent 1ffa5c63f4
commit 67de2db262
48 changed files with 185 additions and 1478 deletions

View File

@ -54,6 +54,8 @@
.. ..
firewire firewire
.. ..
hid
..
hwpmc hwpmc
.. ..
hyperv hyperv

View File

@ -94,6 +94,10 @@ EVDEV= input.h \
uinput.h uinput.h
EVDEVDIR= ${INCLUDEDIR}/dev/evdev EVDEVDIR= ${INCLUDEDIR}/dev/evdev
.PATH: ${SRCTOP}/sys/dev/hid
HID= hid.h
HIDDIR= ${INCLUDEDIR}/dev/hid
.PATH: ${SRCTOP}/sys/dev/hyperv/include ${SRCTOP}/sys/dev/hyperv/utilities .PATH: ${SRCTOP}/sys/dev/hyperv/include ${SRCTOP}/sys/dev/hyperv/utilities
HYPERV= hv_snapshot.h \ HYPERV= hv_snapshot.h \
hyperv.h hyperv.h
@ -172,6 +176,7 @@ INCSGROUPS= INCS \
CRYPTO \ CRYPTO \
EVDEV \ EVDEV \
FS9660 \ FS9660 \
HID \
HYPERV \ HYPERV \
OPENCRYPTO \ OPENCRYPTO \
PCI \ PCI \
@ -287,7 +292,7 @@ copies: .PHONY .META
done; \ done; \
fi fi
.endfor .endfor
.for i in ${LDIRS} ${LSUBDIRS:Ndev/agp:Ndev/acpica:Ndev/evdev:Ndev/hyperv:Ndev/pci:Ndev/veriexec} ${LSUBSUBDIRS} .for i in ${LDIRS} ${LSUBDIRS:Ndev/agp:Ndev/acpica:Ndev/evdev:Ndev/hid:Ndev/hyperv:Ndev/pci:Ndev/veriexec} ${LSUBSUBDIRS}
cd ${SRCTOP}/sys; \ cd ${SRCTOP}/sys; \
${INSTALL} -C ${TAG_ARGS} -o ${BINOWN} -g ${BINGRP} -m 444 $i/*.h \ ${INSTALL} -C ${TAG_ARGS} -o ${BINOWN} -g ${BINGRP} -m 444 $i/*.h \
${SDESTDIR}${INCLUDEDIR}/$i ${SDESTDIR}${INCLUDEDIR}/$i
@ -323,7 +328,7 @@ symlinks: .PHONY .META
cd ${SRCTOP}; ${INSTALL_SYMLINK} ${TAG_ARGS:D${TAG_ARGS},dev} \ cd ${SRCTOP}; ${INSTALL_SYMLINK} ${TAG_ARGS:D${TAG_ARGS},dev} \
$$(printf '../../../%s ' sys/$i/*.h) ${SDESTDIR}${INCLUDEDIR}/$i $$(printf '../../../%s ' sys/$i/*.h) ${SDESTDIR}${INCLUDEDIR}/$i
.endfor .endfor
.for i in ${LSUBDIRS:Ndev/agp:Ndev/acpica:Ndev/evdev:Ndev/hyperv:Ndev/pci:Ndev/veriexec} .for i in ${LSUBDIRS:Ndev/agp:Ndev/acpica:Ndev/evdev:Ndev/hid:Ndev/hyperv:Ndev/pci:Ndev/veriexec}
cd ${SRCTOP}; ${INSTALL_SYMLINK} ${TAG_ARGS:D${TAG_ARGS},dev} \ cd ${SRCTOP}; ${INSTALL_SYMLINK} ${TAG_ARGS:D${TAG_ARGS},dev} \
$$(printf '../../../../%s ' sys/$i/*.h) ${SDESTDIR}${INCLUDEDIR}/$i $$(printf '../../../../%s ' sys/$i/*.h) ${SDESTDIR}${INCLUDEDIR}/$i
.endfor .endfor
@ -335,6 +340,8 @@ symlinks: .PHONY .META
${INSTALL_SYMLINK} ${TAG_ARGS:D${TAG_ARGS},dev} \ ${INSTALL_SYMLINK} ${TAG_ARGS:D${TAG_ARGS},dev} \
$$(printf '../../../../sys/dev/evdev/%s ' input.h input-event-codes.h uinput.h) \ $$(printf '../../../../sys/dev/evdev/%s ' input.h input-event-codes.h uinput.h) \
${SDESTDIR}${INCLUDEDIR}/dev/evdev; ${SDESTDIR}${INCLUDEDIR}/dev/evdev;
${INSTALL_SYMLINK} ${TAG_ARGS:D${TAG_ARGS},dev} ../../../../sys/dev/hid/hid.h \
${SDESTDIR}${INCLUDEDIR}/dev/hid; \
${INSTALL_SYMLINK} ${TAG_ARGS:D${TAG_ARGS},dev} ../../../../sys/dev/hyperv/include/hyperv.h \ ${INSTALL_SYMLINK} ${TAG_ARGS:D${TAG_ARGS},dev} ../../../../sys/dev/hyperv/include/hyperv.h \
${SDESTDIR}${INCLUDEDIR}/dev/hyperv; \ ${SDESTDIR}${INCLUDEDIR}/dev/hyperv; \
${INSTALL_SYMLINK} ${TAG_ARGS:D${TAG_ARGS},dev} ../../../../sys/dev/hyperv/utilities/hv_snapshot.h \ ${INSTALL_SYMLINK} ${TAG_ARGS:D${TAG_ARGS},dev} ../../../../sys/dev/hyperv/utilities/hv_snapshot.h \

View File

@ -38,6 +38,7 @@ To compile this driver into the kernel, place the following lines into
your kernel configuration file: your kernel configuration file:
.Bd -ragged -offset indent .Bd -ragged -offset indent
.Cd "device atp" .Cd "device atp"
.Cd "device hid"
.Cd "device usb" .Cd "device usb"
.Ed .Ed
.Pp .Pp

View File

@ -39,6 +39,7 @@ place the following line in your
kernel configuration file: kernel configuration file:
.Bd -ragged -offset indent .Bd -ragged -offset indent
.Cd "device usb" .Cd "device usb"
.Cd "device hid"
.Cd "device ucom" .Cd "device ucom"
.Cd "device ucycom" .Cd "device ucycom"
.Ed .Ed

View File

@ -28,6 +28,7 @@ To compile this driver into the kernel, place the following lines into
your kernel configuration file: your kernel configuration file:
.Bd -ragged -offset indent .Bd -ragged -offset indent
.Cd "device usb" .Cd "device usb"
.Cd "device hid"
.Cd "device ugold" .Cd "device ugold"
.Ed .Ed
.Pp .Pp

View File

@ -41,6 +41,8 @@ place the following line in your
kernel configuration file: kernel configuration file:
.Bd -ragged -offset indent .Bd -ragged -offset indent
.Cd "device uhid" .Cd "device uhid"
.Cd "device hid"
.Cd "device usb"
.Ed .Ed
.Pp .Pp
Alternatively, to load the driver as a Alternatively, to load the driver as a

View File

@ -36,6 +36,8 @@ place the following line in your
kernel configuration file: kernel configuration file:
.Bd -ragged -offset indent .Bd -ragged -offset indent
.Cd "device ukbd" .Cd "device ukbd"
.Cd "device hid"
.Cd "device usb"
.Ed .Ed
.Pp .Pp
Alternatively, to load the driver as a Alternatively, to load the driver as a

View File

@ -36,6 +36,7 @@ place the following lines in your
kernel configuration file: kernel configuration file:
.Bd -ragged -offset indent .Bd -ragged -offset indent
.Cd "device ums" .Cd "device ums"
.Cd "device hid"
.Cd "device uhci" .Cd "device uhci"
.Cd "device ohci" .Cd "device ohci"
.Cd "device usb" .Cd "device usb"

View File

@ -36,6 +36,7 @@ your kernel configuration file:
.Bd -ragged -offset indent .Bd -ragged -offset indent
.Cd "device wmt" .Cd "device wmt"
.Cd "device usb" .Cd "device usb"
.Cd "device hid"
.Cd "device evdev" .Cd "device evdev"
.Ed .Ed
.Pp .Pp

View File

@ -35,6 +35,7 @@ To compile this driver into the kernel, place the following lines into
your kernel configuration file: your kernel configuration file:
.Bd -ragged -offset indent .Bd -ragged -offset indent
.Cd "device wsp" .Cd "device wsp"
.Cd "device hid"
.Cd "device usb" .Cd "device usb"
.Ed .Ed
.Pp .Pp

View File

@ -380,3 +380,6 @@ device netmap # netmap(4) support
options EVDEV_SUPPORT # evdev support in legacy drivers options EVDEV_SUPPORT # evdev support in legacy drivers
device evdev # input event device support device evdev # input event device support
device uinput # install /dev/uinput cdev device uinput # install /dev/uinput cdev
# HID support
device hid # Generic HID support

View File

@ -116,6 +116,9 @@ device wlan_ccmp # 802.11 CCMP support
device wlan_tkip # 802.11 TKIP support device wlan_tkip # 802.11 TKIP support
device wlan_amrr # AMRR transmit rate control algorithm device wlan_amrr # AMRR transmit rate control algorithm
# HID support
device hid # Generic HID support
# Flattened Device Tree # Flattened Device Tree
options FDT # Configure using FDT/DTB data options FDT # Configure using FDT/DTB data
options FDT_DTB_STATIC options FDT_DTB_STATIC

View File

@ -280,6 +280,9 @@ device aw_sid # Allwinner Secure ID EFUSE
# Thermal sensors # Thermal sensors
device aw_thermal # Allwinner Thermal Sensor Controller device aw_thermal # Allwinner Thermal Sensor Controller
# HID support
device hid # Generic HID support
# Flattened Device Tree # Flattened Device Tree
options FDT # Configure using FDT/DTB data options FDT # Configure using FDT/DTB data
makeoptions MODULES_EXTRA+="dtb/allwinner" makeoptions MODULES_EXTRA+="dtb/allwinner"

View File

@ -113,6 +113,9 @@ device wlan_amrr # AMRR transmit rate control algorithm
#device mmc # SD/MMC protocol #device mmc # SD/MMC protocol
#device mmcsd # SDCard disk device #device mmcsd # SDCard disk device
# HID support
device hid # Generic HID support
# Flattened Device Tree # Flattened Device Tree
options FDT # Configure using FDT/DTB data options FDT # Configure using FDT/DTB data

View File

@ -106,6 +106,9 @@ device u3g # USB modems
#device wlan_tkip # 802.11 TKIP support #device wlan_tkip # 802.11 TKIP support
#device wlan_amrr # AMRR transmit rate control algorithm #device wlan_amrr # AMRR transmit rate control algorithm
# HID support
device hid # Generic HID support
device vt device vt
device kbdmux device kbdmux
device ukbd device ukbd

View File

@ -89,6 +89,9 @@ device sound
device fdt_pinctrl device fdt_pinctrl
# HID support
device hid # Generic HID support
# Flattened Device Tree # Flattened Device Tree
options FDT # Configure using FDT/DTB data options FDT # Configure using FDT/DTB data
# Note: DTB is normally loaded and modified by RPi boot loader, then # Note: DTB is normally loaded and modified by RPi boot loader, then

View File

@ -130,6 +130,9 @@ device drm2
#device sound #device sound
#device snd_hda #device snd_hda
# HID support
device hid # Generic HID support
# Flattened Device Tree # Flattened Device Tree
options FDT # Configure using FDT/DTB data options FDT # Configure using FDT/DTB data
device fdt_pinctrl device fdt_pinctrl

View File

@ -103,5 +103,8 @@ device vt
device kbdmux device kbdmux
device ukbd device ukbd
# HID support
device hid # Generic HID support
# Flattened Device Tree # Flattened Device Tree
options FDT # Configure using FDT/DTB data options FDT # Configure using FDT/DTB data

View File

@ -380,3 +380,6 @@ device acpi
# DTBs # DTBs
makeoptions MODULES_EXTRA="dtb/allwinner dtb/freescale dtb/imx8 dtb/nvidia dtb/mv dtb/rockchip dtb/rpi" makeoptions MODULES_EXTRA="dtb/allwinner dtb/freescale dtb/imx8 dtb/nvidia dtb/mv dtb/rockchip dtb/rpi"
# HID support
device hid # Generic HID support

View File

@ -1815,6 +1815,7 @@ dev/gpio/gpio_if.m optional gpio
dev/gpio/gpiobus_if.m optional gpio dev/gpio/gpiobus_if.m optional gpio
dev/gpio/gpiopps.c optional gpiopps fdt dev/gpio/gpiopps.c optional gpiopps fdt
dev/gpio/ofw_gpiobus.c optional fdt gpio dev/gpio/ofw_gpiobus.c optional fdt gpio
dev/hid/hid.c optional hid
dev/hifn/hifn7751.c optional hifn dev/hifn/hifn7751.c optional hifn
dev/hptiop/hptiop.c optional hptiop scbus dev/hptiop/hptiop.c optional hptiop scbus
dev/hwpmc/hwpmc_logging.c optional hwpmc dev/hwpmc/hwpmc_logging.c optional hwpmc

View File

@ -779,91 +779,6 @@ hid_is_collection(const void *desc, usb_size_t size, int32_t usage)
return (err); return (err);
} }
/*------------------------------------------------------------------------*
* hid_get_descriptor_from_usb
*
* This function will search for a HID descriptor between two USB
* interface descriptors.
*
* Return values:
* NULL: No more HID descriptors.
* Else: Pointer to HID descriptor.
*------------------------------------------------------------------------*/
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);
}
/*------------------------------------------------------------------------*
* usbd_req_get_hid_desc
*
* This function will read out an USB report descriptor from the USB
* device.
*
* Return values:
* NULL: Failure.
* Else: Success. The pointer should eventually be passed to free().
*------------------------------------------------------------------------*/
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);
}
/*------------------------------------------------------------------------* /*------------------------------------------------------------------------*
* calculate HID item resolution. unit/mm for distances, unit/rad for angles * calculate HID item resolution. unit/mm for distances, unit/rad for angles
*------------------------------------------------------------------------*/ *------------------------------------------------------------------------*/
@ -1013,3 +928,5 @@ hid_is_keyboard(const void *d_ptr, uint16_t d_len)
return (1); return (1);
return (0); return (0);
} }
MODULE_VERSION(hid, 1);

View File

@ -28,38 +28,8 @@
* SUCH DAMAGE. * SUCH DAMAGE.
*/ */
#ifndef _USB_HID_H_ #ifndef _HID_HID_H_
#define _USB_HID_H_ #define _HID_HID_H_
#ifndef USB_GLOBAL_INCLUDE_FILE
#include <dev/usb/usb_endian.h>
#endif
#define UR_GET_HID_DESCRIPTOR 0x06
#define UDESC_HID 0x21
#define UDESC_REPORT 0x22
#define UDESC_PHYSICAL 0x23
#define UR_SET_HID_DESCRIPTOR 0x07
#define UR_GET_REPORT 0x01
#define UR_SET_REPORT 0x09
#define UR_GET_IDLE 0x02
#define UR_SET_IDLE 0x0a
#define UR_GET_PROTOCOL 0x03
#define UR_SET_PROTOCOL 0x0b
struct usb_hid_descriptor {
uByte bLength;
uByte bDescriptorType;
uWord bcdHID;
uByte bCountryCode;
uByte bNumDescriptors;
struct {
uByte bDescriptorType;
uWord wDescriptorLength;
} descrs[1];
} __packed;
#define USB_HID_DESCRIPTOR_SIZE(n) (9+((n)*3))
/* Usage pages */ /* Usage pages */
#define HUP_UNDEFINED 0x0000 #define HUP_UNDEFINED 0x0000
@ -206,7 +176,6 @@ struct usb_hid_descriptor {
#define HUM_DEGREE 0x14 #define HUM_DEGREE 0x14
#if defined(_KERNEL) || defined(_STANDALONE) #if defined(_KERNEL) || defined(_STANDALONE)
struct usb_config_descriptor;
#define HID_ITEM_MAXUSAGE 4 #define HID_ITEM_MAXUSAGE 4
@ -271,14 +240,8 @@ uint32_t hid_get_data_unsigned(const uint8_t *buf, usb_size_t len,
void hid_put_data_unsigned(uint8_t *buf, usb_size_t len, void hid_put_data_unsigned(uint8_t *buf, usb_size_t len,
struct hid_location *loc, unsigned int value); struct hid_location *loc, unsigned int value);
int hid_is_collection(const void *desc, usb_size_t size, int32_t usage); int hid_is_collection(const void *desc, usb_size_t size, int32_t usage);
struct usb_hid_descriptor *hid_get_descriptor_from_usb(
struct usb_config_descriptor *cd,
struct usb_interface_descriptor *id);
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);
int32_t hid_item_resolution(struct hid_item *hi); int32_t hid_item_resolution(struct hid_item *hi);
int hid_is_mouse(const void *d_ptr, uint16_t d_len); int hid_is_mouse(const void *d_ptr, uint16_t d_len);
int hid_is_keyboard(const void *d_ptr, uint16_t d_len); int hid_is_keyboard(const void *d_ptr, uint16_t d_len);
#endif /* _KERNEL || _STANDALONE */ #endif /* _KERNEL || _STANDALONE */
#endif /* _USB_HID_H_ */ #endif /* _HID_HID_H_ */

View File

@ -33,7 +33,7 @@
* This file contains replacements for broken HID report descriptors. * This file contains replacements for broken HID report descriptors.
*/ */
#define UHID_GRAPHIRE_REPORT_DESCR(...) \ #define HID_GRAPHIRE_REPORT_DESCR(...) \
0x05, 0x0d, /* USAGE_PAGE (Digitizers) */\ 0x05, 0x0d, /* USAGE_PAGE (Digitizers) */\
0x09, 0x01, /* USAGE (Digitizer) */\ 0x09, 0x01, /* USAGE (Digitizer) */\
0xa1, 0x01, /* COLLECTION (Application) */\ 0xa1, 0x01, /* COLLECTION (Application) */\
@ -97,7 +97,7 @@
0xb1, 0x02, /* FEATURE (Data,Var,Abs) */\ 0xb1, 0x02, /* FEATURE (Data,Var,Abs) */\
0xc0, /* END_COLLECTION */\ 0xc0, /* END_COLLECTION */\
#define UHID_GRAPHIRE3_4X5_REPORT_DESCR(...) \ #define HID_GRAPHIRE3_4X5_REPORT_DESCR(...) \
0x05, 0x01, /* USAGE_PAGE (Generic Desktop) */\ 0x05, 0x01, /* USAGE_PAGE (Generic Desktop) */\
0x09, 0x02, /* USAGE (Mouse) */\ 0x09, 0x02, /* USAGE (Mouse) */\
0xa1, 0x01, /* COLLECTION (Application) */\ 0xa1, 0x01, /* COLLECTION (Application) */\
@ -184,7 +184,7 @@
* The descriptor has no output report format, thus preventing you from * The descriptor has no output report format, thus preventing you from
* controlling the LEDs and the built-in rumblers. * controlling the LEDs and the built-in rumblers.
*/ */
#define UHID_XB360GP_REPORT_DESCR(...) \ #define HID_XB360GP_REPORT_DESCR(...) \
0x05, 0x01, /* USAGE PAGE (Generic Desktop) */\ 0x05, 0x01, /* USAGE PAGE (Generic Desktop) */\
0x09, 0x05, /* USAGE (Gamepad) */\ 0x09, 0x05, /* USAGE (Gamepad) */\
0xa1, 0x01, /* COLLECTION (Application) */\ 0xa1, 0x01, /* COLLECTION (Application) */\
@ -277,7 +277,7 @@
0xc0 /* END COLLECTION */\ 0xc0 /* END COLLECTION */\
/* Fixed report descriptor for Super Nintendo gamepads */ /* Fixed report descriptor for Super Nintendo gamepads */
#define UHID_SNES_REPORT_DESCR(...) \ #define HID_SNES_REPORT_DESCR(...) \
0x05, 0x01, /* Usage Page (Desktop), */\ 0x05, 0x01, /* Usage Page (Desktop), */\
0x09, 0x04, /* Usage (Joystik), */\ 0x09, 0x04, /* Usage (Joystik), */\
0xA1, 0x01, /* Collection (Application), */\ 0xA1, 0x01, /* Collection (Application), */\
@ -304,3 +304,67 @@
0x81, 0x01, /* Input (Constant), */\ 0x81, 0x01, /* Input (Constant), */\
0xC0, /* End Collection, */\ 0xC0, /* End Collection, */\
0xC0 /* End Collection */ 0xC0 /* End Collection */
/* HID mouse boot protocol descriptor */
#define HID_MOUSE_BOOTPROTO_DESCR(...) \
0x05, 0x01, /* Usage Page (Generic Desktop Ctrls) */\
0x09, 0x02, /* Usage (Mouse) */\
0xA1, 0x01, /* Collection (Application) */\
0x09, 0x01, /* Usage (Pointer) */\
0xA1, 0x00, /* Collection (Physical) */\
0x95, 0x03, /* Report Count (3) */\
0x75, 0x01, /* Report Size (1) */\
0x05, 0x09, /* Usage Page (Button) */\
0x19, 0x01, /* Usage Minimum (0x01) */\
0x29, 0x03, /* Usage Maximum (0x03) */\
0x15, 0x00, /* Logical Minimum (0) */\
0x25, 0x01, /* Logical Maximum (1) */\
0x81, 0x02, /* Input (Data,Var,Abs) */\
0x95, 0x01, /* Report Count (1) */\
0x75, 0x05, /* Report Size (5) */\
0x81, 0x03, /* Input (Const) */\
0x75, 0x08, /* Report Size (8) */\
0x95, 0x02, /* Report Count (2) */\
0x05, 0x01, /* Usage Page (Generic Desktop Ctrls) */\
0x09, 0x30, /* Usage (X) */\
0x09, 0x31, /* Usage (Y) */\
0x15, 0x81, /* Logical Minimum (-127) */\
0x25, 0x7F, /* Logical Maximum (127) */\
0x81, 0x06, /* Input (Data,Var,Rel) */\
0xC0, /* End Collection */\
0xC0, /* End Collection */
/* HID keyboard boot protocol descriptor */
#define HID_KBD_BOOTPROTO_DESCR(...) \
0x05, 0x01, /* Usage Page (Generic Desktop Ctrls) */\
0x09, 0x06, /* Usage (Keyboard) */\
0xA1, 0x01, /* Collection (Application) */\
0x05, 0x07, /* Usage Page (Kbrd/Keypad) */\
0x19, 0xE0, /* Usage Minimum (0xE0) */\
0x29, 0xE7, /* Usage Maximum (0xE7) */\
0x15, 0x00, /* Logical Minimum (0) */\
0x25, 0x01, /* Logical Maximum (1) */\
0x75, 0x01, /* Report Size (1) */\
0x95, 0x08, /* Report Count (8) */\
0x81, 0x02, /* Input (Data,Var,Abs) */\
0x95, 0x01, /* Report Count (1) */\
0x75, 0x08, /* Report Size (8) */\
0x81, 0x01, /* Input (Const,Array,Abs) */\
0x95, 0x03, /* Report Count (3) */\
0x75, 0x01, /* Report Size (1) */\
0x05, 0x08, /* Usage Page (LEDs) */\
0x19, 0x01, /* Usage Minimum (Num Lock) */\
0x29, 0x03, /* Usage Maximum (Scroll Lock) */\
0x91, 0x02, /* Output (Data,Var,Abs) */\
0x95, 0x05, /* Report Count (5) */\
0x75, 0x01, /* Report Size (1) */\
0x91, 0x01, /* Output (Const,Array,Abs) */\
0x95, 0x06, /* Report Count (6) */\
0x75, 0x08, /* Report Size (8) */\
0x15, 0x00, /* Logical Minimum (0) */\
0x26, 0xFF, 0x00, /* Logical Maximum (255) */\
0x05, 0x07, /* Usage Page (Kbrd/Keypad) */\
0x19, 0x00, /* Usage Minimum (0x00) */\
0x2A, 0xFF, 0x00, /* Usage Maximum (0xFF) */\
0x81, 0x00, /* Input (Data,Array,Abs) */\
0xC0, /* End Collection */

View File

@ -6210,6 +6210,7 @@ uaudio_hid_detach(struct uaudio_softc *sc)
DRIVER_MODULE_ORDERED(uaudio, uhub, uaudio_driver, uaudio_devclass, NULL, 0, SI_ORDER_ANY); DRIVER_MODULE_ORDERED(uaudio, uhub, uaudio_driver, uaudio_devclass, NULL, 0, SI_ORDER_ANY);
MODULE_DEPEND(uaudio, usb, 1, 1, 1); MODULE_DEPEND(uaudio, usb, 1, 1, 1);
MODULE_DEPEND(uaudio, sound, SOUND_MINVER, SOUND_PREFVER, SOUND_MAXVER); MODULE_DEPEND(uaudio, sound, SOUND_MINVER, SOUND_PREFVER, SOUND_MAXVER);
MODULE_DEPEND(uaudio, hid, 1, 1, 1);
MODULE_VERSION(uaudio, 1); MODULE_VERSION(uaudio, 1);
USB_PNP_HOST_INFO(uaudio_devs); USB_PNP_HOST_INFO(uaudio_devs);
USB_PNP_HOST_INFO(uaudio_vendor_midi); USB_PNP_HOST_INFO(uaudio_vendor_midi);

View File

@ -2633,6 +2633,7 @@ static driver_t atp_driver = {
DRIVER_MODULE(atp, uhub, atp_driver, atp_devclass, NULL, 0); DRIVER_MODULE(atp, uhub, atp_driver, atp_devclass, NULL, 0);
MODULE_DEPEND(atp, usb, 1, 1, 1); MODULE_DEPEND(atp, usb, 1, 1, 1);
MODULE_DEPEND(atp, hid, 1, 1, 1);
MODULE_VERSION(atp, 1); MODULE_VERSION(atp, 1);
USB_PNP_HOST_INFO(fg_devs); USB_PNP_HOST_INFO(fg_devs);
USB_PNP_HOST_INFO(wsp_devs); USB_PNP_HOST_INFO(wsp_devs);

View File

@ -907,5 +907,6 @@ static driver_t uhid_driver = {
DRIVER_MODULE(uhid, uhub, uhid_driver, uhid_devclass, NULL, 0); DRIVER_MODULE(uhid, uhub, uhid_driver, uhid_devclass, NULL, 0);
MODULE_DEPEND(uhid, usb, 1, 1, 1); MODULE_DEPEND(uhid, usb, 1, 1, 1);
MODULE_DEPEND(uhid, hid, 1, 1, 1);
MODULE_VERSION(uhid, 1); MODULE_VERSION(uhid, 1);
USB_PNP_HOST_INFO(uhid_devs); USB_PNP_HOST_INFO(uhid_devs);

View File

@ -2185,6 +2185,7 @@ static driver_t ukbd_driver = {
DRIVER_MODULE(ukbd, uhub, ukbd_driver, ukbd_devclass, ukbd_driver_load, 0); DRIVER_MODULE(ukbd, uhub, ukbd_driver, ukbd_devclass, ukbd_driver_load, 0);
MODULE_DEPEND(ukbd, usb, 1, 1, 1); MODULE_DEPEND(ukbd, usb, 1, 1, 1);
MODULE_DEPEND(ukbd, hid, 1, 1, 1);
#ifdef EVDEV_SUPPORT #ifdef EVDEV_SUPPORT
MODULE_DEPEND(ukbd, evdev, 1, 1, 1); MODULE_DEPEND(ukbd, evdev, 1, 1, 1);
#endif #endif

View File

@ -1213,6 +1213,7 @@ static driver_t ums_driver = {
DRIVER_MODULE(ums, uhub, ums_driver, ums_devclass, NULL, 0); DRIVER_MODULE(ums, uhub, ums_driver, ums_devclass, NULL, 0);
MODULE_DEPEND(ums, usb, 1, 1, 1); MODULE_DEPEND(ums, usb, 1, 1, 1);
MODULE_DEPEND(ums, hid, 1, 1, 1);
#ifdef EVDEV_SUPPORT #ifdef EVDEV_SUPPORT
MODULE_DEPEND(ums, evdev, 1, 1, 1); MODULE_DEPEND(ums, evdev, 1, 1, 1);
#endif #endif

View File

@ -1,11 +1,7 @@
/*- /*-
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
* *
* Copyright (c) 2000 Nick Hibma <n_hibma@FreeBSD.org> * Copyright (c) 2020 Vladimir Kondratyev <wulf@FreeBSD.org>
* All rights reserved.
*
* Copyright (c) 2005 Ed Schouten <ed@FreeBSD.org>
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
@ -30,277 +26,14 @@
* *
* $FreeBSD$ * $FreeBSD$
* *
* This file contains replacements for broken HID report descriptors. * This a proxy file for replacements for broken HID report descriptors.
*/ */
#define UHID_GRAPHIRE_REPORT_DESCR(...) \ #include <dev/hid/hidrdesc.h>
0x05, 0x0d, /* USAGE_PAGE (Digitizers) */\
0x09, 0x01, /* USAGE (Digitizer) */\
0xa1, 0x01, /* COLLECTION (Application) */\
0x85, 0x02, /* REPORT_ID (2) */\
0x05, 0x0d, /* USAGE_PAGE (Digitizers) */\
0x09, 0x01, /* USAGE (Digitizer) */\
0xa1, 0x00, /* COLLECTION (Physical) */\
0x15, 0x00, /* LOGICAL_MINIMUM (0) */\
0x25, 0x01, /* LOGICAL_MAXIMUM (1) */\
0x09, 0x33, /* USAGE (Touch) */\
0x95, 0x01, /* REPORT_COUNT (1) */\
0x75, 0x01, /* REPORT_SIZE (1) */\
0x81, 0x02, /* INPUT (Data,Var,Abs) */\
0x09, 0x44, /* USAGE (Barrel Switch) */\
0x95, 0x02, /* REPORT_COUNT (2) */\
0x75, 0x01, /* REPORT_SIZE (1) */\
0x81, 0x02, /* INPUT (Data,Var,Abs) */\
0x09, 0x00, /* USAGE (Undefined) */\
0x95, 0x02, /* REPORT_COUNT (2) */\
0x75, 0x01, /* REPORT_SIZE (1) */\
0x81, 0x03, /* INPUT (Cnst,Var,Abs) */\
0x09, 0x3c, /* USAGE (Invert) */\
0x95, 0x01, /* REPORT_COUNT (1) */\
0x75, 0x01, /* REPORT_SIZE (1) */\
0x81, 0x02, /* INPUT (Data,Var,Abs) */\
0x09, 0x38, /* USAGE (Transducer Index) */\
0x95, 0x01, /* REPORT_COUNT (1) */\
0x75, 0x01, /* REPORT_SIZE (1) */\
0x81, 0x02, /* INPUT (Data,Var,Abs) */\
0x09, 0x32, /* USAGE (In Range) */\
0x95, 0x01, /* REPORT_COUNT (1) */\
0x75, 0x01, /* REPORT_SIZE (1) */\
0x81, 0x02, /* INPUT (Data,Var,Abs) */\
0x05, 0x01, /* USAGE_PAGE (Generic Desktop) */\
0x09, 0x30, /* USAGE (X) */\
0x15, 0x00, /* LOGICAL_MINIMUM (0) */\
0x26, 0xde, 0x27, /* LOGICAL_MAXIMUM (10206) */\
0x95, 0x01, /* REPORT_COUNT (1) */\
0x75, 0x10, /* REPORT_SIZE (16) */\
0x81, 0x02, /* INPUT (Data,Var,Abs) */\
0x09, 0x31, /* USAGE (Y) */\
0x26, 0xfe, 0x1c, /* LOGICAL_MAXIMUM (7422) */\
0x95, 0x01, /* REPORT_COUNT (1) */\
0x75, 0x10, /* REPORT_SIZE (16) */\
0x81, 0x02, /* INPUT (Data,Var,Abs) */\
0x05, 0x0d, /* USAGE_PAGE (Digitizers) */\
0x09, 0x30, /* USAGE (Tip Pressure) */\
0x26, 0xff, 0x01, /* LOGICAL_MAXIMUM (511) */\
0x95, 0x01, /* REPORT_COUNT (1) */\
0x75, 0x10, /* REPORT_SIZE (16) */\
0x81, 0x02, /* INPUT (Data,Var,Abs) */\
0xc0, /* END_COLLECTION */\
0x05, 0x0d, /* USAGE_PAGE (Digitizers) */\
0x09, 0x00, /* USAGE (Undefined) */\
0x85, 0x02, /* REPORT_ID (2) */\
0x95, 0x01, /* REPORT_COUNT (1) */\
0xb1, 0x02, /* FEATURE (Data,Var,Abs) */\
0x09, 0x00, /* USAGE (Undefined) */\
0x85, 0x03, /* REPORT_ID (3) */\
0x95, 0x01, /* REPORT_COUNT (1) */\
0xb1, 0x02, /* FEATURE (Data,Var,Abs) */\
0xc0, /* END_COLLECTION */\
#define UHID_GRAPHIRE3_4X5_REPORT_DESCR(...) \ #define UHID_GRAPHIRE_REPORT_DESCR HID_GRAPHIRE_REPORT_DESCR
0x05, 0x01, /* USAGE_PAGE (Generic Desktop) */\ #define UHID_GRAPHIRE3_4X5_REPORT_DESCR HID_GRAPHIRE3_4X5_REPORT_DESCR
0x09, 0x02, /* USAGE (Mouse) */\ #define UHID_XB360GP_REPORT_DESCR HID_XB360GP_REPORT_DESCR
0xa1, 0x01, /* COLLECTION (Application) */\ #define UHID_SNES_REPORT_DESCR HID_SNES_REPORT_DESCR
0x85, 0x01, /* REPORT_ID (1) */\ #define UHID_MOUSE_BOOTPROTO_DESCR HID_MOUSE_BOOTPROTO_DESCR
0x09, 0x01, /* USAGE (Pointer) */\ #define UHID_KBD_BOOTPROTO_DESCR HID_KBD_BOOTPROTO_DESCR
0xa1, 0x00, /* COLLECTION (Physical) */\
0x05, 0x09, /* USAGE_PAGE (Button) */\
0x19, 0x01, /* USAGE_MINIMUM (Button 1) */\
0x29, 0x03, /* USAGE_MAXIMUM (Button 3) */\
0x15, 0x00, /* LOGICAL_MINIMUM (0) */\
0x25, 0x01, /* LOGICAL_MAXIMUM (1) */\
0x95, 0x03, /* REPORT_COUNT (3) */\
0x75, 0x01, /* REPORT_SIZE (1) */\
0x81, 0x02, /* INPUT (Data,Var,Abs) */\
0x95, 0x01, /* REPORT_COUNT (1) */\
0x75, 0x05, /* REPORT_SIZE (5) */\
0x81, 0x01, /* INPUT (Cnst,Ary,Abs) */\
0x05, 0x01, /* USAGE_PAGE (Generic Desktop) */\
0x09, 0x30, /* USAGE (X) */\
0x09, 0x31, /* USAGE (Y) */\
0x09, 0x38, /* USAGE (Wheel) */\
0x15, 0x81, /* LOGICAL_MINIMUM (-127) */\
0x25, 0x7f, /* LOGICAL_MAXIMUM (127) */\
0x75, 0x08, /* REPORT_SIZE (8) */\
0x95, 0x03, /* REPORT_COUNT (3) */\
0x81, 0x06, /* INPUT (Data,Var,Rel) */\
0xc0, /* END_COLLECTION */\
0xc0, /* END_COLLECTION */\
0x05, 0x0d, /* USAGE_PAGE (Digitizers) */\
0x09, 0x01, /* USAGE (Pointer) */\
0xa1, 0x01, /* COLLECTION (Applicaption) */\
0x85, 0x02, /* REPORT_ID (2) */\
0x05, 0x0d, /* USAGE_PAGE (Digitizers) */\
0x09, 0x01, /* USAGE (Digitizer) */\
0xa1, 0x00, /* COLLECTION (Physical) */\
0x09, 0x33, /* USAGE (Touch) */\
0x09, 0x44, /* USAGE (Barrel Switch) */\
0x09, 0x44, /* USAGE (Barrel Switch) */\
0x15, 0x00, /* LOGICAL_MINIMUM (0) */\
0x25, 0x01, /* LOGICAL_MAXIMUM (1) */\
0x75, 0x01, /* REPORT_SIZE (1) */\
0x95, 0x03, /* REPORT_COUNT (3) */\
0x81, 0x02, /* INPUT (Data,Var,Abs) */\
0x75, 0x01, /* REPORT_SIZE (1) */\
0x95, 0x02, /* REPORT_COUNT (2) */\
0x81, 0x01, /* INPUT (Cnst,Ary,Abs) */\
0x09, 0x3c, /* USAGE (Invert) */\
0x09, 0x38, /* USAGE (Transducer Index) */\
0x09, 0x32, /* USAGE (In Range) */\
0x75, 0x01, /* REPORT_SIZE (1) */\
0x95, 0x03, /* REPORT_COUNT (3) */\
0x81, 0x02, /* INPUT (Data,Var,Abs) */\
0x05, 0x01, /* USAGE_PAGE (Generic Desktop) */\
0x09, 0x30, /* USAGE (X) */\
0x15, 0x00, /* LOGICAL_MINIMUM (0) */\
0x26, 0xde, 0x27, /* LOGICAL_MAXIMUM (10206) */\
0x75, 0x10, /* REPORT_SIZE (16) */\
0x95, 0x01, /* REPORT_COUNT (1) */\
0x81, 0x02, /* INPUT (Data,Var,Abs) */\
0x09, 0x31, /* USAGE (Y) */\
0x26, 0xfe, 0x1c, /* LOGICAL_MAXIMUM (7422) */\
0x75, 0x10, /* REPORT_SIZE (16) */\
0x95, 0x01, /* REPORT_COUNT (1) */\
0x81, 0x02, /* INPUT (Data,Var,Abs) */\
0x05, 0x0d, /* USAGE_PAGE (Digitizers) */\
0x09, 0x30, /* USAGE (Tip Pressure) */\
0x26, 0xff, 0x01, /* LOGICAL_MAXIMUM (511) */\
0x75, 0x10, /* REPORT_SIZE (16) */\
0x95, 0x01, /* REPORT_COUNT (1) */\
0x81, 0x02, /* INPUT (Data,Var,Abs) */\
0xc0, /* END_COLLECTION */\
0x05, 0x0d, /* USAGE_PAGE (Digitizers) */\
0x09, 0x00, /* USAGE (Undefined) */\
0x85, 0x02, /* REPORT_ID (2) */\
0x95, 0x01, /* REPORT_COUNT (1) */\
0xb1, 0x02, /* FEATURE (Data,Var,Abs) */\
0x09, 0x00, /* USAGE (Undefined) */\
0x85, 0x03, /* REPORT_ID (3) */\
0x95, 0x01, /* REPORT_COUNT (1) */\
0xb1, 0x02, /* FEATURE (Data,Var,Abs) */\
0xc0 /* END_COLLECTION */\
/*
* The descriptor has no output report format, thus preventing you from
* controlling the LEDs and the built-in rumblers.
*/
#define UHID_XB360GP_REPORT_DESCR(...) \
0x05, 0x01, /* USAGE PAGE (Generic Desktop) */\
0x09, 0x05, /* USAGE (Gamepad) */\
0xa1, 0x01, /* COLLECTION (Application) */\
/* Unused */\
0x75, 0x08, /* REPORT SIZE (8) */\
0x95, 0x01, /* REPORT COUNT (1) */\
0x81, 0x01, /* INPUT (Constant) */\
/* Byte count */\
0x75, 0x08, /* REPORT SIZE (8) */\
0x95, 0x01, /* REPORT COUNT (1) */\
0x05, 0x01, /* USAGE PAGE (Generic Desktop) */\
0x09, 0x3b, /* USAGE (Byte Count) */\
0x81, 0x01, /* INPUT (Constant) */\
/* D-Pad */\
0x05, 0x01, /* USAGE PAGE (Generic Desktop) */\
0x09, 0x01, /* USAGE (Pointer) */\
0xa1, 0x00, /* COLLECTION (Physical) */\
0x75, 0x01, /* REPORT SIZE (1) */\
0x15, 0x00, /* LOGICAL MINIMUM (0) */\
0x25, 0x01, /* LOGICAL MAXIMUM (1) */\
0x35, 0x00, /* PHYSICAL MINIMUM (0) */\
0x45, 0x01, /* PHYSICAL MAXIMUM (1) */\
0x95, 0x04, /* REPORT COUNT (4) */\
0x05, 0x01, /* USAGE PAGE (Generic Desktop) */\
0x09, 0x90, /* USAGE (D-Pad Up) */\
0x09, 0x91, /* USAGE (D-Pad Down) */\
0x09, 0x93, /* USAGE (D-Pad Left) */\
0x09, 0x92, /* USAGE (D-Pad Right) */\
0x81, 0x02, /* INPUT (Data, Variable, Absolute) */\
0xc0, /* END COLLECTION */\
/* Buttons 5-11 */\
0x75, 0x01, /* REPORT SIZE (1) */\
0x15, 0x00, /* LOGICAL MINIMUM (0) */\
0x25, 0x01, /* LOGICAL MAXIMUM (1) */\
0x35, 0x00, /* PHYSICAL MINIMUM (0) */\
0x45, 0x01, /* PHYSICAL MAXIMUM (1) */\
0x95, 0x07, /* REPORT COUNT (7) */\
0x05, 0x09, /* USAGE PAGE (Button) */\
0x09, 0x08, /* USAGE (Button 8) */\
0x09, 0x07, /* USAGE (Button 7) */\
0x09, 0x09, /* USAGE (Button 9) */\
0x09, 0x0a, /* USAGE (Button 10) */\
0x09, 0x05, /* USAGE (Button 5) */\
0x09, 0x06, /* USAGE (Button 6) */\
0x09, 0x0b, /* USAGE (Button 11) */\
0x81, 0x02, /* INPUT (Data, Variable, Absolute) */\
/* Unused */\
0x75, 0x01, /* REPORT SIZE (1) */\
0x95, 0x01, /* REPORT COUNT (1) */\
0x81, 0x01, /* INPUT (Constant) */\
/* Buttons 1-4 */\
0x75, 0x01, /* REPORT SIZE (1) */\
0x15, 0x00, /* LOGICAL MINIMUM (0) */\
0x25, 0x01, /* LOGICAL MAXIMUM (1) */\
0x35, 0x00, /* PHYSICAL MINIMUM (0) */\
0x45, 0x01, /* PHYSICAL MAXIMUM (1) */\
0x95, 0x04, /* REPORT COUNT (4) */\
0x05, 0x09, /* USAGE PAGE (Button) */\
0x19, 0x01, /* USAGE MINIMUM (Button 1) */\
0x29, 0x04, /* USAGE MAXIMUM (Button 4) */\
0x81, 0x02, /* INPUT (Data, Variable, Absolute) */\
/* Triggers */\
0x75, 0x08, /* REPORT SIZE (8) */\
0x15, 0x00, /* LOGICAL MINIMUM (0) */\
0x26, 0xff, 0x00, /* LOGICAL MAXIMUM (255) */\
0x35, 0x00, /* PHYSICAL MINIMUM (0) */\
0x46, 0xff, 0x00, /* PHYSICAL MAXIMUM (255) */\
0x95, 0x02, /* REPORT SIZE (2) */\
0x05, 0x01, /* USAGE PAGE (Generic Desktop) */\
0x09, 0x32, /* USAGE (Z) */\
0x09, 0x35, /* USAGE (Rz) */\
0x81, 0x02, /* INPUT (Data, Variable, Absolute) */\
/* Sticks */\
0x75, 0x10, /* REPORT SIZE (16) */\
0x16, 0x00, 0x80, /* LOGICAL MINIMUM (-32768) */\
0x26, 0xff, 0x7f, /* LOGICAL MAXIMUM (32767) */\
0x36, 0x00, 0x80, /* PHYSICAL MINIMUM (-32768) */\
0x46, 0xff, 0x7f, /* PHYSICAL MAXIMUM (32767) */\
0x95, 0x04, /* REPORT COUNT (4) */\
0x05, 0x01, /* USAGE PAGE (Generic Desktop) */\
0x09, 0x30, /* USAGE (X) */\
0x09, 0x31, /* USAGE (Y) */\
0x09, 0x33, /* USAGE (Rx) */\
0x09, 0x34, /* USAGE (Ry) */\
0x81, 0x02, /* INPUT (Data, Variable, Absolute) */\
/* Unused */\
0x75, 0x30, /* REPORT SIZE (48) */\
0x95, 0x01, /* REPORT COUNT (1) */\
0x81, 0x01, /* INPUT (Constant) */\
0xc0 /* END COLLECTION */\
/* Fixed report descriptor for Super Nintendo gamepads */
#define UHID_SNES_REPORT_DESCR(...) \
0x05, 0x01, /* Usage Page (Desktop), */\
0x09, 0x04, /* Usage (Joystik), */\
0xA1, 0x01, /* Collection (Application), */\
0xA1, 0x02, /* Collection (Logical), */\
0x14, /* Logical Minimum (0), */\
0x75, 0x08, /* Report Size (8), */\
0x95, 0x03, /* Report Count (3), */\
0x81, 0x01, /* Input (Constant), */\
0x26, 0xFF, 0x00, /* Logical Maximum (255), */\
0x95, 0x02, /* Report Count (2), */\
0x09, 0x30, /* Usage (X), */\
0x09, 0x31, /* Usage (Y), */\
0x81, 0x02, /* Input (Variable), */\
0x75, 0x01, /* Report Size (1), */\
0x95, 0x04, /* Report Count (4), */\
0x81, 0x01, /* Input (Constant), */\
0x25, 0x01, /* Logical Maximum (1), */\
0x95, 0x0A, /* Report Count (10), */\
0x05, 0x09, /* Usage Page (Button), */\
0x19, 0x01, /* Usage Minimum (01h), */\
0x29, 0x0A, /* Usage Maximum (0Ah), */\
0x81, 0x02, /* Input (Variable), */\
0x95, 0x0A, /* Report Count (10), */\
0x81, 0x01, /* Input (Constant), */\
0xC0, /* End Collection, */\
0xC0 /* End Collection */

View File

@ -1072,6 +1072,7 @@ static driver_t wmt_driver = {
DRIVER_MODULE(wmt, uhub, wmt_driver, wmt_devclass, NULL, 0); DRIVER_MODULE(wmt, uhub, wmt_driver, wmt_devclass, NULL, 0);
MODULE_DEPEND(wmt, usb, 1, 1, 1); MODULE_DEPEND(wmt, usb, 1, 1, 1);
MODULE_DEPEND(wmt, hid, 1, 1, 1);
MODULE_DEPEND(wmt, evdev, 1, 1, 1); MODULE_DEPEND(wmt, evdev, 1, 1, 1);
MODULE_VERSION(wmt, 1); MODULE_VERSION(wmt, 1);
USB_PNP_HOST_INFO(wmt_devs); USB_PNP_HOST_INFO(wmt_devs);

View File

@ -1403,5 +1403,6 @@ static devclass_t wsp_devclass;
DRIVER_MODULE(wsp, uhub, wsp_driver, wsp_devclass, NULL, 0); DRIVER_MODULE(wsp, uhub, wsp_driver, wsp_devclass, NULL, 0);
MODULE_DEPEND(wsp, usb, 1, 1, 1); MODULE_DEPEND(wsp, usb, 1, 1, 1);
MODULE_DEPEND(wsp, hid, 1, 1, 1);
MODULE_VERSION(wsp, 1); MODULE_VERSION(wsp, 1);
USB_PNP_HOST_INFO(wsp_devs); USB_PNP_HOST_INFO(wsp_devs);

View File

@ -142,6 +142,7 @@ static const STRUCT_USB_HOST_ID ugold_devs[] = {
DRIVER_MODULE(ugold, uhub, ugold_driver, ugold_devclass, NULL, NULL); DRIVER_MODULE(ugold, uhub, ugold_driver, ugold_devclass, NULL, NULL);
MODULE_DEPEND(ugold, usb, 1, 1, 1); MODULE_DEPEND(ugold, usb, 1, 1, 1);
MODULE_DEPEND(ugold, hid, 1, 1, 1);
MODULE_VERSION(ugold, 1); MODULE_VERSION(ugold, 1);
USB_PNP_HOST_INFO(ugold_devs); USB_PNP_HOST_INFO(ugold_devs);

View File

@ -185,6 +185,7 @@ static const STRUCT_USB_HOST_ID ucycom_devs[] = {
DRIVER_MODULE(ucycom, uhub, ucycom_driver, ucycom_devclass, NULL, 0); DRIVER_MODULE(ucycom, uhub, ucycom_driver, ucycom_devclass, NULL, 0);
MODULE_DEPEND(ucycom, ucom, 1, 1, 1); MODULE_DEPEND(ucycom, ucom, 1, 1, 1);
MODULE_DEPEND(ucycom, usb, 1, 1, 1); MODULE_DEPEND(ucycom, usb, 1, 1, 1);
MODULE_DEPEND(ucycom, hid, 1, 1, 1);
MODULE_VERSION(ucycom, 1); MODULE_VERSION(ucycom, 1);
USB_PNP_HOST_INFO(ucycom_devs); USB_PNP_HOST_INFO(ucycom_devs);

View File

@ -68,717 +68,6 @@
#include <dev/usb/usb_request.h> #include <dev/usb/usb_request.h>
#endif /* USB_GLOBAL_INCLUDE_FILE */ #endif /* USB_GLOBAL_INCLUDE_FILE */
static void hid_clear_local(struct hid_item *);
static uint8_t hid_get_byte(struct hid_data *s, const uint16_t wSize);
#define MAXUSAGE 64
#define MAXPUSH 4
#define MAXID 16
#define MAXLOCCNT 2048
struct hid_pos_data {
int32_t rid;
uint32_t pos;
};
struct hid_data {
const uint8_t *start;
const uint8_t *end;
const uint8_t *p;
struct hid_item cur[MAXPUSH];
struct hid_pos_data last_pos[MAXID];
int32_t usages_min[MAXUSAGE];
int32_t usages_max[MAXUSAGE];
int32_t usage_last; /* last seen usage */
uint32_t loc_size; /* last seen size */
uint32_t loc_count; /* last seen count */
uint32_t ncount; /* end usage item count */
uint32_t icount; /* current usage item count */
uint8_t kindset; /* we have 5 kinds so 8 bits are enough */
uint8_t pushlevel; /* current pushlevel */
uint8_t nusage; /* end "usages_min/max" index */
uint8_t iusage; /* current "usages_min/max" index */
uint8_t ousage; /* current "usages_min/max" offset */
uint8_t susage; /* usage set flags */
};
/*------------------------------------------------------------------------*
* hid_clear_local
*------------------------------------------------------------------------*/
static void
hid_clear_local(struct hid_item *c)
{
c->loc.count = 0;
c->loc.size = 0;
c->nusages = 0;
memset(c->usages, 0, sizeof(c->usages));
c->usage_minimum = 0;
c->usage_maximum = 0;
c->designator_index = 0;
c->designator_minimum = 0;
c->designator_maximum = 0;
c->string_index = 0;
c->string_minimum = 0;
c->string_maximum = 0;
c->set_delimiter = 0;
}
static void
hid_switch_rid(struct hid_data *s, struct hid_item *c, int32_t next_rID)
{
uint8_t i;
/* check for same report ID - optimise */
if (c->report_ID == next_rID)
return;
/* save current position for current rID */
if (c->report_ID == 0) {
i = 0;
} else {
for (i = 1; i != MAXID; i++) {
if (s->last_pos[i].rid == c->report_ID)
break;
if (s->last_pos[i].rid == 0)
break;
}
}
if (i != MAXID) {
s->last_pos[i].rid = c->report_ID;
s->last_pos[i].pos = c->loc.pos;
}
/* store next report ID */
c->report_ID = next_rID;
/* lookup last position for next rID */
if (next_rID == 0) {
i = 0;
} else {
for (i = 1; i != MAXID; i++) {
if (s->last_pos[i].rid == next_rID)
break;
if (s->last_pos[i].rid == 0)
break;
}
}
if (i != MAXID) {
s->last_pos[i].rid = next_rID;
c->loc.pos = s->last_pos[i].pos;
} else {
DPRINTF("Out of RID entries, position is set to zero!\n");
c->loc.pos = 0;
}
}
/*------------------------------------------------------------------------*
* hid_start_parse
*------------------------------------------------------------------------*/
struct hid_data *
hid_start_parse(const void *d, usb_size_t len, int kindset)
{
struct hid_data *s;
if ((kindset-1) & kindset) {
DPRINTFN(0, "Only one bit can be "
"set in the kindset\n");
return (NULL);
}
s = malloc(sizeof *s, M_TEMP, M_WAITOK | M_ZERO);
s->start = s->p = d;
s->end = ((const uint8_t *)d) + len;
s->kindset = kindset;
return (s);
}
/*------------------------------------------------------------------------*
* hid_end_parse
*------------------------------------------------------------------------*/
void
hid_end_parse(struct hid_data *s)
{
if (s == NULL)
return;
free(s, M_TEMP);
}
/*------------------------------------------------------------------------*
* get byte from HID descriptor
*------------------------------------------------------------------------*/
static uint8_t
hid_get_byte(struct hid_data *s, const uint16_t wSize)
{
const uint8_t *ptr;
uint8_t retval;
ptr = s->p;
/* check if end is reached */
if (ptr == s->end)
return (0);
/* read out a byte */
retval = *ptr;
/* check if data pointer can be advanced by "wSize" bytes */
if ((s->end - ptr) < wSize)
ptr = s->end;
else
ptr += wSize;
/* update pointer */
s->p = ptr;
return (retval);
}
/*------------------------------------------------------------------------*
* hid_get_item
*------------------------------------------------------------------------*/
int
hid_get_item(struct hid_data *s, struct hid_item *h)
{
struct hid_item *c;
unsigned int bTag, bType, bSize;
uint32_t oldpos;
int32_t mask;
int32_t dval;
if (s == NULL)
return (0);
c = &s->cur[s->pushlevel];
top:
/* check if there is an array of items */
if (s->icount < s->ncount) {
/* get current usage */
if (s->iusage < s->nusage) {
dval = s->usages_min[s->iusage] + s->ousage;
c->usage = dval;
s->usage_last = dval;
if (dval == s->usages_max[s->iusage]) {
s->iusage ++;
s->ousage = 0;
} else {
s->ousage ++;
}
} else {
DPRINTFN(1, "Using last usage\n");
dval = s->usage_last;
}
c->nusages = 1;
/* array type HID item may have multiple usages */
while ((c->flags & HIO_VARIABLE) == 0 && s->ousage == 0 &&
s->iusage < s->nusage && c->nusages < HID_ITEM_MAXUSAGE)
c->usages[c->nusages++] = s->usages_min[s->iusage++];
if ((c->flags & HIO_VARIABLE) == 0 && s->ousage == 0 &&
s->iusage < s->nusage)
DPRINTFN(0, "HID_ITEM_MAXUSAGE should be increased "
"up to %hhu to parse the HID report descriptor\n",
s->nusage);
s->icount ++;
/*
* Only copy HID item, increment position and return
* if correct kindset!
*/
if (s->kindset & (1 << c->kind)) {
*h = *c;
DPRINTFN(1, "%u,%u,%u\n", h->loc.pos,
h->loc.size, h->loc.count);
c->loc.pos += c->loc.size * c->loc.count;
return (1);
}
}
/* reset state variables */
s->icount = 0;
s->ncount = 0;
s->iusage = 0;
s->nusage = 0;
s->susage = 0;
s->ousage = 0;
hid_clear_local(c);
/* get next item */
while (s->p != s->end) {
bSize = hid_get_byte(s, 1);
if (bSize == 0xfe) {
/* long item */
bSize = hid_get_byte(s, 1);
bSize |= hid_get_byte(s, 1) << 8;
bTag = hid_get_byte(s, 1);
bType = 0xff; /* XXX what should it be */
} else {
/* short item */
bTag = bSize >> 4;
bType = (bSize >> 2) & 3;
bSize &= 3;
if (bSize == 3)
bSize = 4;
}
switch (bSize) {
case 0:
dval = 0;
mask = 0;
break;
case 1:
dval = (int8_t)hid_get_byte(s, 1);
mask = 0xFF;
break;
case 2:
dval = hid_get_byte(s, 1);
dval |= hid_get_byte(s, 1) << 8;
dval = (int16_t)dval;
mask = 0xFFFF;
break;
case 4:
dval = hid_get_byte(s, 1);
dval |= hid_get_byte(s, 1) << 8;
dval |= hid_get_byte(s, 1) << 16;
dval |= hid_get_byte(s, 1) << 24;
mask = 0xFFFFFFFF;
break;
default:
dval = hid_get_byte(s, bSize);
DPRINTFN(0, "bad length %u (data=0x%02x)\n",
bSize, dval);
continue;
}
switch (bType) {
case 0: /* Main */
switch (bTag) {
case 8: /* Input */
c->kind = hid_input;
ret:
c->flags = dval;
c->loc.count = s->loc_count;
c->loc.size = s->loc_size;
if (c->flags & HIO_VARIABLE) {
/* range check usage count */
if (c->loc.count > MAXLOCCNT) {
DPRINTFN(0, "Number of "
"items(%u) truncated to %u\n",
(unsigned)(c->loc.count),
MAXLOCCNT);
s->ncount = MAXLOCCNT;
} else
s->ncount = c->loc.count;
/*
* The "top" loop will return
* one and one item:
*/
c->loc.count = 1;
} else {
s->ncount = 1;
}
goto top;
case 9: /* Output */
c->kind = hid_output;
goto ret;
case 10: /* Collection */
c->kind = hid_collection;
c->collection = dval;
c->collevel++;
c->usage = s->usage_last;
c->nusages = 1;
*h = *c;
return (1);
case 11: /* Feature */
c->kind = hid_feature;
goto ret;
case 12: /* End collection */
c->kind = hid_endcollection;
if (c->collevel == 0) {
DPRINTFN(0, "invalid end collection\n");
return (0);
}
c->collevel--;
*h = *c;
return (1);
default:
DPRINTFN(0, "Main bTag=%d\n", bTag);
break;
}
break;
case 1: /* Global */
switch (bTag) {
case 0:
c->_usage_page = dval << 16;
break;
case 1:
c->logical_minimum = dval;
break;
case 2:
c->logical_maximum = dval;
break;
case 3:
c->physical_minimum = dval;
break;
case 4:
c->physical_maximum = dval;
break;
case 5:
c->unit_exponent = dval;
break;
case 6:
c->unit = dval;
break;
case 7:
/* mask because value is unsigned */
s->loc_size = dval & mask;
break;
case 8:
hid_switch_rid(s, c, dval & mask);
break;
case 9:
/* mask because value is unsigned */
s->loc_count = dval & mask;
break;
case 10: /* Push */
/* stop parsing, if invalid push level */
if ((s->pushlevel + 1) >= MAXPUSH) {
DPRINTFN(0, "Cannot push item @ %d\n", s->pushlevel);
return (0);
}
s->pushlevel ++;
s->cur[s->pushlevel] = *c;
/* store size and count */
c->loc.size = s->loc_size;
c->loc.count = s->loc_count;
/* update current item pointer */
c = &s->cur[s->pushlevel];
break;
case 11: /* Pop */
/* stop parsing, if invalid push level */
if (s->pushlevel == 0) {
DPRINTFN(0, "Cannot pop item @ 0\n");
return (0);
}
s->pushlevel --;
/* preserve position */
oldpos = c->loc.pos;
c = &s->cur[s->pushlevel];
/* restore size and count */
s->loc_size = c->loc.size;
s->loc_count = c->loc.count;
/* set default item location */
c->loc.pos = oldpos;
c->loc.size = 0;
c->loc.count = 0;
break;
default:
DPRINTFN(0, "Global bTag=%d\n", bTag);
break;
}
break;
case 2: /* Local */
switch (bTag) {
case 0:
if (bSize != 4)
dval = (dval & mask) | c->_usage_page;
/* set last usage, in case of a collection */
s->usage_last = dval;
if (s->nusage < MAXUSAGE) {
s->usages_min[s->nusage] = dval;
s->usages_max[s->nusage] = dval;
s->nusage ++;
} else {
DPRINTFN(0, "max usage reached\n");
}
/* clear any pending usage sets */
s->susage = 0;
break;
case 1:
s->susage |= 1;
if (bSize != 4)
dval = (dval & mask) | c->_usage_page;
c->usage_minimum = dval;
goto check_set;
case 2:
s->susage |= 2;
if (bSize != 4)
dval = (dval & mask) | c->_usage_page;
c->usage_maximum = dval;
check_set:
if (s->susage != 3)
break;
/* sanity check */
if ((s->nusage < MAXUSAGE) &&
(c->usage_minimum <= c->usage_maximum)) {
/* add usage range */
s->usages_min[s->nusage] =
c->usage_minimum;
s->usages_max[s->nusage] =
c->usage_maximum;
s->nusage ++;
} else {
DPRINTFN(0, "Usage set dropped\n");
}
s->susage = 0;
break;
case 3:
c->designator_index = dval;
break;
case 4:
c->designator_minimum = dval;
break;
case 5:
c->designator_maximum = dval;
break;
case 7:
c->string_index = dval;
break;
case 8:
c->string_minimum = dval;
break;
case 9:
c->string_maximum = dval;
break;
case 10:
c->set_delimiter = dval;
break;
default:
DPRINTFN(0, "Local bTag=%d\n", bTag);
break;
}
break;
default:
DPRINTFN(0, "default bType=%d\n", bType);
break;
}
}
return (0);
}
/*------------------------------------------------------------------------*
* hid_report_size
*------------------------------------------------------------------------*/
int
hid_report_size(const void *buf, usb_size_t len, enum hid_kind k, uint8_t *id)
{
struct hid_data *d;
struct hid_item h;
uint32_t temp;
uint32_t hpos;
uint32_t lpos;
uint8_t any_id;
any_id = 0;
hpos = 0;
lpos = 0xFFFFFFFF;
for (d = hid_start_parse(buf, len, 1 << k); hid_get_item(d, &h);) {
if (h.kind == k) {
/* check for ID-byte presence */
if ((h.report_ID != 0) && !any_id) {
if (id != NULL)
*id = h.report_ID;
any_id = 1;
}
/* compute minimum */
if (lpos > h.loc.pos)
lpos = h.loc.pos;
/* compute end position */
temp = h.loc.pos + (h.loc.size * h.loc.count);
/* compute maximum */
if (hpos < temp)
hpos = temp;
}
}
hid_end_parse(d);
/* safety check - can happen in case of currupt descriptors */
if (lpos > hpos)
temp = 0;
else
temp = hpos - lpos;
/* check for ID byte */
if (any_id)
temp += 8;
else if (id != NULL)
*id = 0;
/* return length in bytes rounded up */
return ((temp + 7) / 8);
}
/*------------------------------------------------------------------------*
* hid_locate
*------------------------------------------------------------------------*/
int
hid_locate(const void *desc, usb_size_t size, int32_t u, enum hid_kind k,
uint8_t index, struct hid_location *loc, uint32_t *flags, uint8_t *id)
{
struct hid_data *d;
struct hid_item h;
int i;
for (d = hid_start_parse(desc, size, 1 << k); hid_get_item(d, &h);) {
for (i = 0; i < h.nusages; i++) {
if (h.kind == k && h.usages[i] == u) {
if (index--)
break;
if (loc != NULL)
*loc = h.loc;
if (flags != NULL)
*flags = h.flags;
if (id != NULL)
*id = h.report_ID;
hid_end_parse(d);
return (1);
}
}
}
if (loc != NULL)
loc->size = 0;
if (flags != NULL)
*flags = 0;
if (id != NULL)
*id = 0;
hid_end_parse(d);
return (0);
}
/*------------------------------------------------------------------------*
* hid_get_data
*------------------------------------------------------------------------*/
static uint32_t
hid_get_data_sub(const uint8_t *buf, usb_size_t len, struct hid_location *loc,
int is_signed)
{
uint32_t hpos = loc->pos;
uint32_t hsize = loc->size;
uint32_t data;
uint32_t rpos;
uint8_t n;
DPRINTFN(11, "hid_get_data: loc %d/%d\n", hpos, hsize);
/* Range check and limit */
if (hsize == 0)
return (0);
if (hsize > 32)
hsize = 32;
/* Get data in a safe way */
data = 0;
rpos = (hpos / 8);
n = (hsize + 7) / 8;
rpos += n;
while (n--) {
rpos--;
if (rpos < len)
data |= buf[rpos] << (8 * n);
}
/* Correctly shift down data */
data = (data >> (hpos % 8));
n = 32 - hsize;
/* Mask and sign extend in one */
if (is_signed != 0)
data = (int32_t)((int32_t)data << n) >> n;
else
data = (uint32_t)((uint32_t)data << n) >> n;
DPRINTFN(11, "hid_get_data: loc %d/%d = %lu\n",
loc->pos, loc->size, (long)data);
return (data);
}
int32_t
hid_get_data(const uint8_t *buf, usb_size_t len, struct hid_location *loc)
{
return (hid_get_data_sub(buf, len, loc, 1));
}
uint32_t
hid_get_data_unsigned(const uint8_t *buf, usb_size_t len, struct hid_location *loc)
{
return (hid_get_data_sub(buf, len, loc, 0));
}
/*------------------------------------------------------------------------*
* hid_put_data
*------------------------------------------------------------------------*/
void
hid_put_data_unsigned(uint8_t *buf, usb_size_t len,
struct hid_location *loc, unsigned int value)
{
uint32_t hpos = loc->pos;
uint32_t hsize = loc->size;
uint64_t data;
uint64_t mask;
uint32_t rpos;
uint8_t n;
DPRINTFN(11, "hid_put_data: loc %d/%d = %u\n", hpos, hsize, value);
/* Range check and limit */
if (hsize == 0)
return;
if (hsize > 32)
hsize = 32;
/* Put data in a safe way */
rpos = (hpos / 8);
n = (hsize + 7) / 8;
data = ((uint64_t)value) << (hpos % 8);
mask = ((1ULL << hsize) - 1ULL) << (hpos % 8);
rpos += n;
while (n--) {
rpos--;
if (rpos < len) {
buf[rpos] &= ~(mask >> (8 * n));
buf[rpos] |= (data >> (8 * n));
}
}
}
/*------------------------------------------------------------------------*
* hid_is_collection
*------------------------------------------------------------------------*/
int
hid_is_collection(const void *desc, usb_size_t size, int32_t usage)
{
struct hid_data *hd;
struct hid_item hi;
int err;
hd = hid_start_parse(desc, size, hid_input);
if (hd == NULL)
return (0);
while ((err = hid_get_item(hd, &hi))) {
if (hi.kind == hid_collection &&
hi.usage == usage)
break;
}
hid_end_parse(hd);
return (err);
}
/*------------------------------------------------------------------------* /*------------------------------------------------------------------------*
* hid_get_descriptor_from_usb * hid_get_descriptor_from_usb
* *
@ -863,153 +152,3 @@ usbd_req_get_hid_desc(struct usb_device *udev, struct mtx *mtx,
} }
return (USB_ERR_NORMAL_COMPLETION); return (USB_ERR_NORMAL_COMPLETION);
} }
/*------------------------------------------------------------------------*
* calculate HID item resolution. unit/mm for distances, unit/rad for angles
*------------------------------------------------------------------------*/
int32_t
hid_item_resolution(struct hid_item *hi)
{
/*
* hid unit scaling table according to HID Usage Table Review
* Request 39 Tbl 17 http://www.usb.org/developers/hidpage/HUTRR39b.pdf
*/
static const int64_t scale[0x10][2] = {
[0x00] = { 1, 1 },
[0x01] = { 1, 10 },
[0x02] = { 1, 100 },
[0x03] = { 1, 1000 },
[0x04] = { 1, 10000 },
[0x05] = { 1, 100000 },
[0x06] = { 1, 1000000 },
[0x07] = { 1, 10000000 },
[0x08] = { 100000000, 1 },
[0x09] = { 10000000, 1 },
[0x0A] = { 1000000, 1 },
[0x0B] = { 100000, 1 },
[0x0C] = { 10000, 1 },
[0x0D] = { 1000, 1 },
[0x0E] = { 100, 1 },
[0x0F] = { 10, 1 },
};
int64_t logical_size;
int64_t physical_size;
int64_t multiplier;
int64_t divisor;
int64_t resolution;
switch (hi->unit) {
case HUM_CENTIMETER:
multiplier = 1;
divisor = 10;
break;
case HUM_INCH:
multiplier = 10;
divisor = 254;
break;
case HUM_RADIAN:
multiplier = 1;
divisor = 1;
break;
case HUM_DEGREE:
multiplier = 573;
divisor = 10;
break;
default:
return (0);
}
if ((hi->logical_maximum <= hi->logical_minimum) ||
(hi->physical_maximum <= hi->physical_minimum) ||
(hi->unit_exponent < 0) || (hi->unit_exponent >= nitems(scale)))
return (0);
logical_size = (int64_t)hi->logical_maximum -
(int64_t)hi->logical_minimum;
physical_size = (int64_t)hi->physical_maximum -
(int64_t)hi->physical_minimum;
/* Round to ceiling */
resolution = logical_size * multiplier * scale[hi->unit_exponent][0] /
(physical_size * divisor * scale[hi->unit_exponent][1]);
if (resolution > INT32_MAX)
return (0);
return (resolution);
}
/*------------------------------------------------------------------------*
* hid_is_mouse
*
* This function will decide if a USB descriptor belongs to a USB mouse.
*
* Return values:
* Zero: Not a USB mouse.
* Else: Is a USB mouse.
*------------------------------------------------------------------------*/
int
hid_is_mouse(const void *d_ptr, uint16_t d_len)
{
struct hid_data *hd;
struct hid_item hi;
int mdepth;
int found;
hd = hid_start_parse(d_ptr, d_len, 1 << hid_input);
if (hd == NULL)
return (0);
mdepth = 0;
found = 0;
while (hid_get_item(hd, &hi)) {
switch (hi.kind) {
case hid_collection:
if (mdepth != 0)
mdepth++;
else if (hi.collection == 1 &&
hi.usage ==
HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_MOUSE))
mdepth++;
break;
case hid_endcollection:
if (mdepth != 0)
mdepth--;
break;
case hid_input:
if (mdepth == 0)
break;
if (hi.usage ==
HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_X) &&
(hi.flags & (HIO_CONST|HIO_RELATIVE)) == HIO_RELATIVE)
found++;
if (hi.usage ==
HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_Y) &&
(hi.flags & (HIO_CONST|HIO_RELATIVE)) == HIO_RELATIVE)
found++;
break;
default:
break;
}
}
hid_end_parse(hd);
return (found);
}
/*------------------------------------------------------------------------*
* hid_is_keyboard
*
* This function will decide if a USB descriptor belongs to a USB keyboard.
*
* Return values:
* Zero: Not a USB keyboard.
* Else: Is a USB keyboard.
*------------------------------------------------------------------------*/
int
hid_is_keyboard(const void *d_ptr, uint16_t d_len)
{
if (hid_is_collection(d_ptr, d_len,
HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_KEYBOARD)))
return (1);
return (0);
}

View File

@ -31,6 +31,8 @@
#ifndef _USB_HID_H_ #ifndef _USB_HID_H_
#define _USB_HID_H_ #define _USB_HID_H_
#include <dev/hid/hid.h>
#ifndef USB_GLOBAL_INCLUDE_FILE #ifndef USB_GLOBAL_INCLUDE_FILE
#include <dev/usb/usb_endian.h> #include <dev/usb/usb_endian.h>
#endif #endif
@ -61,224 +63,14 @@ struct usb_hid_descriptor {
#define USB_HID_DESCRIPTOR_SIZE(n) (9+((n)*3)) #define USB_HID_DESCRIPTOR_SIZE(n) (9+((n)*3))
/* Usage pages */
#define HUP_UNDEFINED 0x0000
#define HUP_GENERIC_DESKTOP 0x0001
#define HUP_SIMULATION 0x0002
#define HUP_VR_CONTROLS 0x0003
#define HUP_SPORTS_CONTROLS 0x0004
#define HUP_GAMING_CONTROLS 0x0005
#define HUP_KEYBOARD 0x0007
#define HUP_LEDS 0x0008
#define HUP_BUTTON 0x0009
#define HUP_ORDINALS 0x000a
#define HUP_TELEPHONY 0x000b
#define HUP_CONSUMER 0x000c
#define HUP_DIGITIZERS 0x000d
#define HUP_PHYSICAL_IFACE 0x000e
#define HUP_UNICODE 0x0010
#define HUP_ALPHANUM_DISPLAY 0x0014
#define HUP_MONITOR 0x0080
#define HUP_MONITOR_ENUM_VAL 0x0081
#define HUP_VESA_VC 0x0082
#define HUP_VESA_CMD 0x0083
#define HUP_POWER 0x0084
#define HUP_BATTERY_SYSTEM 0x0085
#define HUP_BARCODE_SCANNER 0x008b
#define HUP_SCALE 0x008c
#define HUP_CAMERA_CONTROL 0x0090
#define HUP_ARCADE 0x0091
#define HUP_MICROSOFT 0xff00
/* Usages, generic desktop */
#define HUG_POINTER 0x0001
#define HUG_MOUSE 0x0002
#define HUG_JOYSTICK 0x0004
#define HUG_GAME_PAD 0x0005
#define HUG_KEYBOARD 0x0006
#define HUG_KEYPAD 0x0007
#define HUG_X 0x0030
#define HUG_Y 0x0031
#define HUG_Z 0x0032
#define HUG_RX 0x0033
#define HUG_RY 0x0034
#define HUG_RZ 0x0035
#define HUG_SLIDER 0x0036
#define HUG_DIAL 0x0037
#define HUG_WHEEL 0x0038
#define HUG_HAT_SWITCH 0x0039
#define HUG_COUNTED_BUFFER 0x003a
#define HUG_BYTE_COUNT 0x003b
#define HUG_MOTION_WAKEUP 0x003c
#define HUG_VX 0x0040
#define HUG_VY 0x0041
#define HUG_VZ 0x0042
#define HUG_VBRX 0x0043
#define HUG_VBRY 0x0044
#define HUG_VBRZ 0x0045
#define HUG_VNO 0x0046
#define HUG_TWHEEL 0x0048 /* M$ Wireless Intellimouse Wheel */
#define HUG_SYSTEM_CONTROL 0x0080
#define HUG_SYSTEM_POWER_DOWN 0x0081
#define HUG_SYSTEM_SLEEP 0x0082
#define HUG_SYSTEM_WAKEUP 0x0083
#define HUG_SYSTEM_CONTEXT_MENU 0x0084
#define HUG_SYSTEM_MAIN_MENU 0x0085
#define HUG_SYSTEM_APP_MENU 0x0086
#define HUG_SYSTEM_MENU_HELP 0x0087
#define HUG_SYSTEM_MENU_EXIT 0x0088
#define HUG_SYSTEM_MENU_SELECT 0x0089
#define HUG_SYSTEM_MENU_RIGHT 0x008a
#define HUG_SYSTEM_MENU_LEFT 0x008b
#define HUG_SYSTEM_MENU_UP 0x008c
#define HUG_SYSTEM_MENU_DOWN 0x008d
#define HUG_APPLE_EJECT 0x00b8
/* Usages Digitizers */
#define HUD_UNDEFINED 0x0000
#define HUD_DIGITIZER 0x0001
#define HUD_PEN 0x0002
#define HUD_TOUCHSCREEN 0x0004
#define HUD_TOUCHPAD 0x0005
#define HUD_CONFIG 0x000e
#define HUD_FINGER 0x0022
#define HUD_TIP_PRESSURE 0x0030
#define HUD_BARREL_PRESSURE 0x0031
#define HUD_IN_RANGE 0x0032
#define HUD_TOUCH 0x0033
#define HUD_UNTOUCH 0x0034
#define HUD_TAP 0x0035
#define HUD_QUALITY 0x0036
#define HUD_DATA_VALID 0x0037
#define HUD_TRANSDUCER_INDEX 0x0038
#define HUD_TABLET_FKEYS 0x0039
#define HUD_PROGRAM_CHANGE_KEYS 0x003a
#define HUD_BATTERY_STRENGTH 0x003b
#define HUD_INVERT 0x003c
#define HUD_X_TILT 0x003d
#define HUD_Y_TILT 0x003e
#define HUD_AZIMUTH 0x003f
#define HUD_ALTITUDE 0x0040
#define HUD_TWIST 0x0041
#define HUD_TIP_SWITCH 0x0042
#define HUD_SEC_TIP_SWITCH 0x0043
#define HUD_BARREL_SWITCH 0x0044
#define HUD_ERASER 0x0045
#define HUD_TABLET_PICK 0x0046
#define HUD_CONFIDENCE 0x0047
#define HUD_WIDTH 0x0048
#define HUD_HEIGHT 0x0049
#define HUD_CONTACTID 0x0051
#define HUD_INPUT_MODE 0x0052
#define HUD_DEVICE_INDEX 0x0053
#define HUD_CONTACTCOUNT 0x0054
#define HUD_CONTACT_MAX 0x0055
#define HUD_SCAN_TIME 0x0056
#define HUD_SURFACE_SWITCH 0x0057
#define HUD_BUTTONS_SWITCH 0x0058
#define HUD_BUTTON_TYPE 0x0059
#define HUD_LATENCY_MODE 0x0060
/* Usages, Consumer */
#define HUC_AC_PAN 0x0238
#define HID_USAGE2(p,u) (((p) << 16) | (u))
#define UHID_INPUT_REPORT 0x01
#define UHID_OUTPUT_REPORT 0x02
#define UHID_FEATURE_REPORT 0x03
/* Bits in the input/output/feature items */
#define HIO_CONST 0x001
#define HIO_VARIABLE 0x002
#define HIO_RELATIVE 0x004
#define HIO_WRAP 0x008
#define HIO_NONLINEAR 0x010
#define HIO_NOPREF 0x020
#define HIO_NULLSTATE 0x040
#define HIO_VOLATILE 0x080
#define HIO_BUFBYTES 0x100
/* Units of Measure */
#define HUM_CENTIMETER 0x11
#define HUM_RADIAN 0x12
#define HUM_INCH 0x13
#define HUM_DEGREE 0x14
#if defined(_KERNEL) || defined(_STANDALONE) #if defined(_KERNEL) || defined(_STANDALONE)
struct usb_config_descriptor; struct usb_config_descriptor;
#define HID_ITEM_MAXUSAGE 4
enum hid_kind {
hid_input, hid_output, hid_feature, hid_collection, hid_endcollection
};
struct hid_location {
uint32_t size;
uint32_t count;
uint32_t pos;
};
struct hid_item {
/* Global */
int32_t _usage_page;
int32_t logical_minimum;
int32_t logical_maximum;
int32_t physical_minimum;
int32_t physical_maximum;
int32_t unit_exponent;
int32_t unit;
int32_t report_ID;
/* Local */
int nusages;
union {
int32_t usage;
int32_t usages[HID_ITEM_MAXUSAGE];
};
int32_t usage_minimum;
int32_t usage_maximum;
int32_t designator_index;
int32_t designator_minimum;
int32_t designator_maximum;
int32_t string_index;
int32_t string_minimum;
int32_t string_maximum;
int32_t set_delimiter;
/* Misc */
int32_t collection;
int collevel;
enum hid_kind kind;
uint32_t flags;
/* Location */
struct hid_location loc;
};
/* prototypes from "usb_hid.c" */
struct hid_data *hid_start_parse(const void *d, usb_size_t len, int kindset);
void hid_end_parse(struct hid_data *s);
int hid_get_item(struct hid_data *s, struct hid_item *h);
int hid_report_size(const void *buf, usb_size_t len, enum hid_kind k,
uint8_t *id);
int hid_locate(const void *desc, usb_size_t size, int32_t usage,
enum hid_kind kind, uint8_t index, struct hid_location *loc,
uint32_t *flags, uint8_t *id);
int32_t hid_get_data(const uint8_t *buf, usb_size_t len,
struct hid_location *loc);
uint32_t hid_get_data_unsigned(const uint8_t *buf, usb_size_t len,
struct hid_location *loc);
void hid_put_data_unsigned(uint8_t *buf, usb_size_t len,
struct hid_location *loc, unsigned int value);
int hid_is_collection(const void *desc, usb_size_t size, int32_t usage);
struct usb_hid_descriptor *hid_get_descriptor_from_usb( struct usb_hid_descriptor *hid_get_descriptor_from_usb(
struct usb_config_descriptor *cd, struct usb_config_descriptor *cd,
struct usb_interface_descriptor *id); struct usb_interface_descriptor *id);
usb_error_t usbd_req_get_hid_desc(struct usb_device *udev, struct mtx *mtx, usb_error_t usbd_req_get_hid_desc(struct usb_device *udev, struct mtx *mtx,
void **descp, uint16_t *sizep, struct malloc_type *mem, void **descp, uint16_t *sizep, struct malloc_type *mem,
uint8_t iface_index); uint8_t iface_index);
int32_t hid_item_resolution(struct hid_item *hi);
int hid_is_mouse(const void *d_ptr, uint16_t d_len);
int hid_is_keyboard(const void *d_ptr, uint16_t d_len);
#endif /* _KERNEL || _STANDALONE */ #endif /* _KERNEL || _STANDALONE */
#endif /* _USB_HID_H_ */ #endif /* _USB_HID_H_ */

View File

@ -348,3 +348,6 @@ device xenpci # Xen HVM Hypervisor services driver
options EVDEV_SUPPORT # evdev support in legacy drivers options EVDEV_SUPPORT # evdev support in legacy drivers
device evdev # input event device support device evdev # input event device support
device uinput # install /dev/uinput cdev device uinput # install /dev/uinput cdev
# HID support
device hid # Generic HID support

View File

@ -212,3 +212,6 @@ device cryptocteon # Octeon coprocessor 2 crypto offload
# PMC support # PMC support
#device hwpmc #device hwpmc
# HID support
device hid # Generic HID support

View File

@ -109,5 +109,8 @@ device ukbd # Allow keyboard like HIDs to control console
device umass # Disks/Mass storage - Requires scbus and da device umass # Disks/Mass storage - Requires scbus and da
device ums # Mouse device ums # Mouse
# HID support
device hid # Generic HID support
# FDT support # FDT support
options FDT options FDT

View File

@ -237,3 +237,6 @@ device cryptocteon # Octeon coprocessor 2 crypto offload
# PMC support # PMC support
#device hwpmc #device hwpmc
# HID support
device hid # Generic HID support

View File

@ -129,6 +129,7 @@ SUBDIR= \
${_glxiic} \ ${_glxiic} \
${_glxsb} \ ${_glxsb} \
gpio \ gpio \
hid \
hifn \ hifn \
${_hpt27xx} \ ${_hpt27xx} \
${_hptiop} \ ${_hptiop} \

6
sys/modules/hid/Makefile Normal file
View File

@ -0,0 +1,6 @@
# $FreeBSD$
SUBDIR = \
hid
.include <bsd.subdir.mk>

View File

@ -0,0 +1,9 @@
# $FreeBSD$
.PATH: ${SRCTOP}/sys/dev/hid
KMOD= hid
SRCS= hid.c
SRCS+= opt_usb.h
.include <bsd.kmod.mk>

View File

@ -240,3 +240,5 @@ device virtio_blk # VirtIO Block device
device virtio_scsi # VirtIO SCSI device device virtio_scsi # VirtIO SCSI device
device virtio_balloon # VirtIO Memory Balloon device device virtio_balloon # VirtIO Memory Balloon device
# HID support
device hid # Generic HID support

View File

@ -270,3 +270,5 @@ device virtio_blk # VirtIO Block device
device virtio_scsi # VirtIO SCSI device device virtio_scsi # VirtIO SCSI device
device virtio_balloon # VirtIO Memory Balloon device device virtio_balloon # VirtIO Memory Balloon device
# HID support
device hid # Generic HID support

View File

@ -251,3 +251,5 @@ device virtio_blk # VirtIO Block device
device virtio_scsi # VirtIO SCSI device device virtio_scsi # VirtIO SCSI device
device virtio_balloon # VirtIO Memory Balloon device device virtio_balloon # VirtIO Memory Balloon device
# HID support
device hid # Generic HID support

View File

@ -117,3 +117,6 @@ device diu
device videomode device videomode
device vt device vt
device fbd device fbd
# HID support
device hid # Generic HID support

View File

@ -118,3 +118,6 @@ device diu
device videomode device videomode
device vt device vt
device fbd device fbd
# HID support
device hid # Generic HID support

View File

@ -120,3 +120,6 @@ device fbd
options KBD_INSTALL_CDEV options KBD_INSTALL_CDEV
device ukbd device ukbd
device ums device ums
# HID support
device hid # Generic HID support