descr.c revision 187994
11553Srgrimes/* $NetBSD: descr.c,v 1.9 2000/09/24 02:13:24 augustss Exp $ */ 21553Srgrimes 31553Srgrimes/* 41553Srgrimes * Copyright (c) 1999 Lennart Augustsson <augustss@netbsd.org> 51553Srgrimes * All rights reserved. 61553Srgrimes * 71553Srgrimes * Redistribution and use in source and binary forms, with or without 81553Srgrimes * modification, are permitted provided that the following conditions 91553Srgrimes * are met: 101553Srgrimes * 1. Redistributions of source code must retain the above copyright 111553Srgrimes * notice, this list of conditions and the following disclaimer. 121553Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 131553Srgrimes * notice, this list of conditions and the following disclaimer in the 141553Srgrimes * documentation and/or other materials provided with the distribution. 151553Srgrimes * 161553Srgrimes * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 171553Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 181553Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 191553Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 201553Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 211553Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 221553Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 231553Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 241553Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 251553Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 261553Srgrimes * SUCH DAMAGE. 271553Srgrimes */ 281553Srgrimes 291553Srgrimes#include <sys/cdefs.h> 301553Srgrimes__FBSDID("$FreeBSD: head/lib/libusbhid/descr.c 187994 2009-02-02 00:49:39Z alfred $"); 311553Srgrimes 321553Srgrimes#include <sys/types.h> 331553Srgrimes 341553Srgrimes#include <assert.h> 3529602Scharnier#include <errno.h> 361553Srgrimes#include <stdlib.h> 371553Srgrimes#include <string.h> 381553Srgrimes#include <unistd.h> 391553Srgrimes#include <sys/time.h> 401553Srgrimes#include <sys/ioctl.h> 4129602Scharnier 4229602Scharnier#include <dev/usb2/include/usb2_ioctl.h> 4329602Scharnier 4429602Scharnier#include "usbhid.h" 4545588Smarkm#include "usbvar.h" 461553Srgrimes 471553Srgrimesint 481553Srgrimeshid_set_immed(int fd, int enable) 491553Srgrimes{ 501553Srgrimes int ret; 511553Srgrimes ret = ioctl(fd, USB_SET_IMMED, &enable); 521553Srgrimes if (ret < 0) 531553Srgrimes ret = hid_set_immed_compat7(fd, enable); 541553Srgrimes return (ret); 551553Srgrimes} 561553Srgrimes 571553Srgrimesint 581553Srgrimeshid_get_report_id(int fd) 591553Srgrimes{ 601553Srgrimes int temp = -1; 611553Srgrimes int ret; 621553Srgrimes 638857Srgrimes ret = ioctl(fd, USB_GET_REPORT_ID, &temp); 641553Srgrimes if (ret < 0) 651553Srgrimes ret = hid_get_report_id_compat7(fd); 661553Srgrimes else 671553Srgrimes ret = temp; 681553Srgrimes 691553Srgrimes return (ret); 701553Srgrimes} 711553Srgrimes 721553Srgrimesreport_desc_t 731553Srgrimeshid_get_report_desc(int fd) 741553Srgrimes{ 751553Srgrimes struct usb2_gen_descriptor ugd; 761553Srgrimes report_desc_t rep; 771553Srgrimes void *data; 781553Srgrimes 791553Srgrimes memset(&ugd, 0, sizeof(ugd)); 801553Srgrimes 811553Srgrimes /* get actual length first */ 821553Srgrimes ugd.ugd_data = NULL; 831553Srgrimes ugd.ugd_maxlen = 65535; 841553Srgrimes if (ioctl(fd, USB_GET_REPORT_DESC, &ugd) < 0) { 851553Srgrimes /* could not read descriptor */ 861553Srgrimes /* try FreeBSD 7 compat code */ 871553Srgrimes return (hid_get_report_desc_compat7(fd)); 881553Srgrimes } 891553Srgrimes 901553Srgrimes /* 911553Srgrimes * NOTE: The kernel will return a failure if 921553Srgrimes * "ugd_actlen" is zero. 931553Srgrimes */ 941553Srgrimes data = malloc(ugd.ugd_actlen); 952657Scsgr if (data == NULL) 962657Scsgr return (NULL); 972657Scsgr 982657Scsgr /* fetch actual descriptor */ 992657Scsgr ugd.ugd_data = data; 1002657Scsgr ugd.ugd_maxlen = ugd.ugd_actlen; 1012657Scsgr if (ioctl(fd, USB_GET_REPORT_DESC, &ugd) < 0) { 1022657Scsgr /* could not read descriptor */ 1032657Scsgr free(data); 1041553Srgrimes return (NULL); 1051553Srgrimes } 1061553Srgrimes 1071553Srgrimes /* check END_COLLECTION */ 1081553Srgrimes if (((unsigned char *)ugd.ugd_data)[ugd.ugd_actlen -1] != 0xC0) { 1091553Srgrimes /* invalid end byte */ 1101553Srgrimes free(data); 1111553Srgrimes return (NULL); 1121553Srgrimes } 1131553Srgrimes 1141553Srgrimes rep = hid_use_report_desc(data, ugd.ugd_actlen); 11536042Sguido 1161553Srgrimes free(data); 1172657Scsgr 11819617Sjulian return (rep); 1191553Srgrimes} 1201553Srgrimes 12129602Scharnierreport_desc_t 1221553Srgrimeshid_use_report_desc(unsigned char *data, unsigned int size) 12330807Sache{ 1241553Srgrimes report_desc_t r; 1251553Srgrimes 1261553Srgrimes r = malloc(sizeof(*r) + size); 1271553Srgrimes if (r == 0) { 1281553Srgrimes errno = ENOMEM; 1291553Srgrimes return (NULL); 1301553Srgrimes } 1311553Srgrimes r->size = size; 13213142Speter memcpy(r->data, data, size); 13319617Sjulian return (r); 1341553Srgrimes} 13545089Smarkm 13645089Smarkmvoid 13745089Smarkmhid_dispose_report_desc(report_desc_t r) 13845089Smarkm{ 13945089Smarkm 14045089Smarkm free(r); 14145089Smarkm} 14245089Smarkm