Author: alfred
Date: Mon Feb  2 00:49:39 2009
New Revision: 187994
URL: http://svn.freebsd.org/changeset/base/187994

Log:
  src/usr.bin/usbhidaction/usbhidaction.c
  src/usr.bin/usbhidctl/usbhid.c
  src/sys/dev/usb2/include/usb2_hid.h
  src/sys/dev/usb2/input/uhid2.c
  src/lib/libusbhid/Makefile
  src/lib/libusbhid/descr.c
  src/lib/libusbhid/descr_compat.c
  src/lib/libusbhid/usbhid.3
  src/lib/libusbhid/usbhid.h
  src/lib/libusbhid/usbvar.h
  
  Patches to make libusbhid and HID userland utilities compatible with
  the new USB stack. All HID ioctls should go through the libusbhid
  library to ensure compatibility. I have found at least one piece of
  software in /usr/ports which needs to get updated before USB HID
  devices will work. This is the X joystick input driver.
  
  Reported and tested by:
  
  Daichi GOTO and Masanori OZAWA.
  
  src/sys/dev/usb2/core/usb2_process.c
  
  Correct USB process names.
  
  Reported by:
  
  Andre Guibert de Bruet
  
  src/sys/dev/usb2/serial/uftdi2.c
  
  Integrate changes from old USB stack.
  
  Submitted by: hps

Added:
  head/lib/libusbhid/descr_compat.c   (contents, props changed)
Modified:
  head/lib/libusbhid/Makefile
  head/lib/libusbhid/descr.c
  head/lib/libusbhid/usbhid.3
  head/lib/libusbhid/usbhid.h
  head/lib/libusbhid/usbvar.h
  head/sys/dev/usb2/bluetooth/ubtbcmfw2.c
  head/sys/dev/usb2/core/usb2_process.c
  head/sys/dev/usb2/include/usb2_hid.h
  head/sys/dev/usb2/input/uhid2.c
  head/sys/dev/usb2/serial/uftdi2.c
  head/usr.bin/usbhidaction/usbhidaction.c
  head/usr.bin/usbhidctl/usbhid.c

Modified: head/lib/libusbhid/Makefile
==============================================================================
--- head/lib/libusbhid/Makefile Sun Feb  1 23:28:52 2009        (r187993)
+++ head/lib/libusbhid/Makefile Mon Feb  2 00:49:39 2009        (r187994)
@@ -15,7 +15,7 @@ MLINKS=       usbhid.3 libusbhid.3 usbhid.3 hi
        usbhid.3 hid_init.3 \
        usbhid.3 hid_get_data.3 usbhid.3 hid_set_data.3
 
-SRCS=  descr.c parse.c usage.c data.c
+SRCS=  descr.c descr_compat.c parse.c usage.c data.c
 
 INCS=  usbhid.h
 

Modified: head/lib/libusbhid/descr.c
==============================================================================
--- head/lib/libusbhid/descr.c  Sun Feb  1 23:28:52 2009        (r187993)
+++ head/lib/libusbhid/descr.c  Mon Feb  2 00:49:39 2009        (r187994)
@@ -39,21 +39,83 @@ __FBSDID("$FreeBSD$");
 #include <sys/time.h>
 #include <sys/ioctl.h>
 
-#include <dev/usb/usb.h>
+#include <dev/usb2/include/usb2_ioctl.h>
 
 #include "usbhid.h"
 #include "usbvar.h"
 
+int
+hid_set_immed(int fd, int enable)
+{
+       int ret;
+       ret = ioctl(fd, USB_SET_IMMED, &enable);
+       if (ret < 0)
+               ret = hid_set_immed_compat7(fd, enable);
+       return (ret);
+}
+
+int
+hid_get_report_id(int fd)
+{
+       int temp = -1;
+       int ret;
+
+       ret = ioctl(fd, USB_GET_REPORT_ID, &temp);
+       if (ret < 0)
+               ret = hid_get_report_id_compat7(fd);
+       else
+               ret = temp;
+
+       return (ret);
+}
+
 report_desc_t
 hid_get_report_desc(int fd)
 {
-       struct usb_ctl_report_desc rep;
+       struct usb2_gen_descriptor ugd;
+       report_desc_t rep;
+       void *data;
+
+       memset(&ugd, 0, sizeof(ugd));
+
+       /* get actual length first */
+       ugd.ugd_data = NULL;
+       ugd.ugd_maxlen = 65535;
+       if (ioctl(fd, USB_GET_REPORT_DESC, &ugd) < 0) {
+               /* could not read descriptor */
+               /* try FreeBSD 7 compat code */
+               return (hid_get_report_desc_compat7(fd));
+       }
 
-       rep.ucrd_size = 0;
-       if (ioctl(fd, USB_GET_REPORT_DESC, &rep) < 0)
+       /*
+        * NOTE: The kernel will return a failure if 
+        * "ugd_actlen" is zero.
+        */
+       data = malloc(ugd.ugd_actlen);
+       if (data == NULL)
                return (NULL);
 
-       return hid_use_report_desc(rep.ucrd_data, (unsigned int)rep.ucrd_size);
+       /* fetch actual descriptor */
+       ugd.ugd_data = data;
+       ugd.ugd_maxlen = ugd.ugd_actlen;
+       if (ioctl(fd, USB_GET_REPORT_DESC, &ugd) < 0) {
+               /* could not read descriptor */
+               free(data);
+               return (NULL);
+       }
+
+       /* check END_COLLECTION */
+       if (((unsigned char *)ugd.ugd_data)[ugd.ugd_actlen -1] != 0xC0) {
+               /* invalid end byte */
+               free(data);
+               return (NULL);
+       }
+
+       rep = hid_use_report_desc(data, ugd.ugd_actlen);
+
+       free(data);
+
+       return (rep);
 }
 
 report_desc_t

Added: head/lib/libusbhid/descr_compat.c
==============================================================================
--- /dev/null   00:00:00 1970   (empty, because file is newly added)
+++ head/lib/libusbhid/descr_compat.c   Mon Feb  2 00:49:39 2009        
(r187994)
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 1999 Lennart Augustsson <augus...@netbsd.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * This file contains fallback-compatibility code for the old FreeBSD
+ * USB stack.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/types.h>
+
+#include <assert.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/time.h>
+#include <sys/ioctl.h>
+
+#include <dev/usb/usb.h>
+
+#include "usbhid.h"
+#include "usbvar.h"
+
+int
+hid_set_immed_compat7(int fd, int enable)
+{
+       return (ioctl(fd, USB_SET_IMMED, &enable));
+}
+
+int
+hid_get_report_id_compat7(int fd)
+{
+       int temp = -1;
+
+       if (ioctl(fd, USB_GET_REPORT_ID, &temp) < 0)
+               return (-1);
+
+       return (temp);
+}
+
+report_desc_t
+hid_get_report_desc_compat7(int fd)
+{
+       struct usb_ctl_report_desc rep;
+
+       rep.ucrd_size = 0;
+       if (ioctl(fd, USB_GET_REPORT_DESC, &rep) < 0)
+               return (NULL);
+
+       return (hid_use_report_desc(rep.ucrd_data, (unsigned 
int)rep.ucrd_size));
+}

Modified: head/lib/libusbhid/usbhid.3
==============================================================================
--- head/lib/libusbhid/usbhid.3 Sun Feb  1 23:28:52 2009        (r187993)
+++ head/lib/libusbhid/usbhid.3 Mon Feb  2 00:49:39 2009        (r187994)
@@ -26,12 +26,13 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd December 29, 2001
+.Dd January 27, 2009
 .Dt USBHID 3
 .Os
 .Sh NAME
 .Nm usbhid ,
 .Nm hid_get_report_desc ,
+.Nm hid_get_report_id ,
 .Nm hid_use_report_desc ,
 .Nm hid_dispose_report_desc ,
 .Nm hid_start_parse ,
@@ -51,6 +52,10 @@
 .In usbhid.h
 .Ft report_desc_t
 .Fn hid_get_report_desc "int file"
+.Ft int
+.Fn hid_get_report_id "int file"
+.Ft int
+.Fn hid_set_immed "int fd" "int enable"
 .Ft report_desc_t
 .Fn hid_use_report_desc "unsigned char *data" "unsigned int size"
 .Ft void
@@ -94,7 +99,15 @@ which contains the data layout informati
 The routines can be divided into four parts: extraction of the descriptor,
 parsing of the descriptor, translating to/from symbolic names, and
 data manipulation.
+.Ss Synchronous HID operation
+Synchronous HID operation can be enabled or disabled by a call to
+.Fn hid_set_immed .
+If the second argument is zero synchronous HID operation is disabled.
+Else synchronous HID operation is enabled.
+The function returns a negative value on failure.
 .Ss Descriptor Functions
+The report descriptor ID can be obtained by calling
+.Fn hid_get_report_id .
 A report descriptor can be obtained by calling
 .Fn hid_get_report_desc
 with a file descriptor obtained by opening a

Modified: head/lib/libusbhid/usbhid.h
==============================================================================
--- head/lib/libusbhid/usbhid.h Sun Feb  1 23:28:52 2009        (r187993)
+++ head/lib/libusbhid/usbhid.h Mon Feb  2 00:49:39 2009        (r187994)
@@ -87,6 +87,8 @@ __BEGIN_DECLS
 report_desc_t hid_get_report_desc(int file);
 report_desc_t hid_use_report_desc(unsigned char *data, unsigned int size);
 void hid_dispose_report_desc(report_desc_t);
+int hid_get_report_id(int file);
+int hid_set_immed(int fd, int enable);
 
 /* Parsing of a HID report descriptor, parse.c: */
 hid_data_t hid_start_parse(report_desc_t d, int kindset, int id);

Modified: head/lib/libusbhid/usbvar.h
==============================================================================
--- head/lib/libusbhid/usbvar.h Sun Feb  1 23:28:52 2009        (r187993)
+++ head/lib/libusbhid/usbvar.h Mon Feb  2 00:49:39 2009        (r187994)
@@ -34,3 +34,8 @@ struct report_desc {
        unsigned char data[1];
 };
 
+/* internal backwards compatibility functions */
+
+int    hid_set_immed_compat7(int fd, int enable);
+int    hid_get_report_id_compat7(int fd);
+report_desc_t  hid_get_report_desc_compat7(int fd);

Modified: head/sys/dev/usb2/bluetooth/ubtbcmfw2.c
==============================================================================
--- head/sys/dev/usb2/bluetooth/ubtbcmfw2.c     Sun Feb  1 23:28:52 2009        
(r187993)
+++ head/sys/dev/usb2/bluetooth/ubtbcmfw2.c     Mon Feb  2 00:49:39 2009        
(r187994)
@@ -385,8 +385,8 @@ ubtbcmfw_open(struct usb2_fifo *fifo, in
        else if (fflags & FWRITE)
                xfer = sc->sc_xfer[UBTBCMFW_BULK_DT_WR];
        else
-               return (EINVAL);        /* XXX can happen? */
-               
+               return (EINVAL);        /* should not happen */
+
        if (usb2_fifo_alloc_buffer(fifo, xfer->max_data_length,
                        UBTBCMFW_IFQ_MAXLEN) != 0)
                return (ENOMEM);

Modified: head/sys/dev/usb2/core/usb2_process.c
==============================================================================
--- head/sys/dev/usb2/core/usb2_process.c       Sun Feb  1 23:28:52 2009        
(r187993)
+++ head/sys/dev/usb2/core/usb2_process.c       Mon Feb  2 00:49:39 2009        
(r187994)
@@ -184,11 +184,11 @@ usb2_proc_setup(struct usb2_process *up,
 
        TAILQ_INIT(&up->up_qhead);
 
-       usb2_cv_init(&up->up_cv, "WMSG");
-       usb2_cv_init(&up->up_drain, "DMSG");
+       usb2_cv_init(&up->up_cv, "wmsg");
+       usb2_cv_init(&up->up_drain, "dmsg");
 
        if (USB_THREAD_CREATE(&usb2_process, up,
-           &up->up_ptr, "USBPROC")) {
+           &up->up_ptr, "usbproc")) {
                DPRINTFN(0, "Unable to create USB process.");
                up->up_ptr = NULL;
                goto error;

Modified: head/sys/dev/usb2/include/usb2_hid.h
==============================================================================
--- head/sys/dev/usb2/include/usb2_hid.h        Sun Feb  1 23:28:52 2009        
(r187993)
+++ head/sys/dev/usb2/include/usb2_hid.h        Mon Feb  2 00:49:39 2009        
(r187994)
@@ -29,6 +29,8 @@
 #ifndef _USB2_HID_H_
 #define        _USB2_HID_H_
 
+#include <dev/usb2/include/usb2_endian.h>
+
 #define        UR_GET_HID_DESCRIPTOR   0x06
 #define        UDESC_HID               0x21
 #define        UDESC_REPORT            0x22

Modified: head/sys/dev/usb2/input/uhid2.c
==============================================================================
--- head/sys/dev/usb2/input/uhid2.c     Sun Feb  1 23:28:52 2009        
(r187993)
+++ head/sys/dev/usb2/input/uhid2.c     Mon Feb  2 00:49:39 2009        
(r187994)
@@ -87,10 +87,9 @@ SYSCTL_INT(_hw_usb2_uhid, OID_AUTO, debu
 
 enum {
        UHID_INTR_DT_RD,
-       UHID_INTR_CS_RD,
        UHID_CTRL_DT_WR,
        UHID_CTRL_DT_RD,
-       UHID_N_TRANSFER = 4,
+       UHID_N_TRANSFER,
 };
 
 struct uhid_softc {
@@ -114,7 +113,6 @@ struct uhid_softc {
        uint8_t sc_fid;
        uint8_t sc_flags;
 #define        UHID_FLAG_IMMED        0x01     /* set if read should be 
immediate */
-#define        UHID_FLAG_INTR_STALL   0x02     /* set if interrupt transfer 
stalled */
 #define        UHID_FLAG_STATIC_DESC  0x04     /* set if report descriptors are
                                         * static */
 };
@@ -130,7 +128,6 @@ static device_attach_t uhid_attach;
 static device_detach_t uhid_detach;
 
 static usb2_callback_t uhid_intr_callback;
-static usb2_callback_t uhid_intr_clear_stall_callback;
 static usb2_callback_t uhid_write_callback;
 static usb2_callback_t uhid_read_callback;
 
@@ -174,41 +171,25 @@ uhid_intr_callback(struct usb2_xfer *xfe
                }
 
        case USB_ST_SETUP:
-               if (sc->sc_flags & UHID_FLAG_INTR_STALL) {
-                       usb2_transfer_start(sc->sc_xfer[UHID_INTR_CS_RD]);
-               } else {
-                       if (usb2_fifo_put_bytes_max(
-                           sc->sc_fifo.fp[USB_FIFO_RX]) != 0) {
-                               xfer->frlengths[0] = xfer->max_data_length;
-                               usb2_start_hardware(xfer);
-                       }
+re_submit:
+               if (usb2_fifo_put_bytes_max(
+                   sc->sc_fifo.fp[USB_FIFO_RX]) != 0) {
+                       xfer->frlengths[0] = sc->sc_isize;
+                       usb2_start_hardware(xfer);
                }
                return;
 
        default:                        /* Error */
                if (xfer->error != USB_ERR_CANCELLED) {
                        /* try to clear stall first */
-                       sc->sc_flags |= UHID_FLAG_INTR_STALL;
-                       usb2_transfer_start(sc->sc_xfer[UHID_INTR_CS_RD]);
+                       xfer->flags.stall_pipe = 1;
+                       goto re_submit;
                }
                return;
        }
 }
 
 static void
-uhid_intr_clear_stall_callback(struct usb2_xfer *xfer)
-{
-       struct uhid_softc *sc = xfer->priv_sc;
-       struct usb2_xfer *xfer_other = sc->sc_xfer[UHID_INTR_DT_RD];
-
-       if (usb2_clear_stall_callback(xfer, xfer_other)) {
-               DPRINTF("stall cleared\n");
-               sc->sc_flags &= ~UHID_FLAG_INTR_STALL;
-               usb2_transfer_start(xfer_other);
-       }
-}
-
-static void
 uhid_fill_set_report(struct usb2_device_request *req, uint8_t iface_no,
     uint8_t type, uint8_t id, uint16_t size)
 {
@@ -337,20 +318,10 @@ static const struct usb2_config uhid_con
                .endpoint = UE_ADDR_ANY,
                .direction = UE_DIR_IN,
                .mh.flags = {.pipe_bof = 1,.short_xfer_ok = 1,},
-               .mh.bufsize = 0,        /* use wMaxPacketSize */
+               .mh.bufsize = UHID_BSIZE,
                .mh.callback = &uhid_intr_callback,
        },
 
-       [UHID_INTR_CS_RD] = {
-               .type = UE_CONTROL,
-               .endpoint = 0x00,       /* Control pipe */
-               .direction = UE_DIR_ANY,
-               .mh.bufsize = sizeof(struct usb2_device_request),
-               .mh.callback = &uhid_intr_clear_stall_callback,
-               .mh.timeout = 1000,     /* 1 second */
-               .mh.interval = 50,      /* 50ms */
-       },
-
        [UHID_CTRL_DT_WR] = {
                .type = UE_CONTROL,
                .endpoint = 0x00,       /* Control pipe */
@@ -530,6 +501,8 @@ uhid_ioctl(struct usb2_fifo *fifo, u_lon
                        size = sc->sc_repdesc_size;
                }
                ugd->ugd_actlen = size;
+               if (ugd->ugd_data == NULL)
+                       break;          /* descriptor length only */
                error = copyout(sc->sc_repdesc_ptr, ugd->ugd_data, size);
                break;
 

Modified: head/sys/dev/usb2/serial/uftdi2.c
==============================================================================
--- head/sys/dev/usb2/serial/uftdi2.c   Sun Feb  1 23:28:52 2009        
(r187993)
+++ head/sys/dev/usb2/serial/uftdi2.c   Mon Feb  2 00:49:39 2009        
(r187994)
@@ -233,6 +233,7 @@ MODULE_DEPEND(uftdi, usb2_serial, 1, 1, 
 MODULE_DEPEND(uftdi, usb2_core, 1, 1, 1);
 
 static struct usb2_device_id uftdi_devs[] = {
+       {USB_VPI(USB_VENDOR_DRESDENELEKTRONIK, 
USB_PRODUCT_DRESDENELEKTRONIK_SENSORTERMINALBOARD, UFTDI_TYPE_8U232AM)},
        {USB_VPI(USB_VENDOR_FTDI, USB_PRODUCT_FTDI_SERIAL_8U100AX, 
UFTDI_TYPE_SIO)},
        {USB_VPI(USB_VENDOR_FTDI, USB_PRODUCT_FTDI_SERIAL_2232C, 
UFTDI_TYPE_8U232AM)},
        {USB_VPI(USB_VENDOR_FTDI, USB_PRODUCT_FTDI_SERIAL_8U232AM, 
UFTDI_TYPE_8U232AM)},

Modified: head/usr.bin/usbhidaction/usbhidaction.c
==============================================================================
--- head/usr.bin/usbhidaction/usbhidaction.c    Sun Feb  1 23:28:52 2009        
(r187993)
+++ head/usr.bin/usbhidaction/usbhidaction.c    Mon Feb  2 00:49:39 2009        
(r187994)
@@ -46,9 +46,7 @@
 #include <limits.h>
 #include <unistd.h>
 #include <sys/types.h>
-#include <sys/ioctl.h>
-#include <dev/usb/usb.h>
-#include <dev/usb/usbhid.h>
+#include <dev/usb2/include/usb2_hid.h>
 #include <usbhid.h>
 #include <syslog.h>
 #include <signal.h>
@@ -155,8 +153,7 @@ main(int argc, char **argv)
        fd = open(dev, O_RDWR);
        if (fd < 0)
                err(1, "%s", dev);
-       if (ioctl(fd, USB_GET_REPORT_ID, &reportid) < 0)
-               reportid = -1;
+       reportid = hid_get_report_id(fd);
        repd = hid_get_report_desc(fd);
        if (repd == NULL)
                err(1, "hid_get_report_desc() failed");

Modified: head/usr.bin/usbhidctl/usbhid.c
==============================================================================
--- head/usr.bin/usbhidctl/usbhid.c     Sun Feb  1 23:28:52 2009        
(r187993)
+++ head/usr.bin/usbhidctl/usbhid.c     Mon Feb  2 00:49:39 2009        
(r187994)
@@ -42,14 +42,12 @@
 #include <string.h>
 #include <sys/types.h>
 #include <fcntl.h>
-#include <sys/ioctl.h>
 #include <unistd.h>
 #include <err.h>
 #include <ctype.h>
 #include <errno.h>
 #include <usbhid.h>
-#include <dev/usb/usb.h>
-#include <dev/usb/usbhid.h>
+#include <dev/usb2/include/usb2_hid.h>
 
 int verbose = 0;
 int all = 0;
@@ -207,7 +205,6 @@ dumpdata(int f, report_desc_t rd, int lo
        struct hid_item h, *hids, *n;
        int r, dlen;
        u_char *dbuf;
-       static int one = 1;
        u_int32_t colls[100];
        int sp = 0;
        char namebuf[10000], *namep;
@@ -231,7 +228,7 @@ dumpdata(int f, report_desc_t rd, int lo
        dlen = hid_report_size(rd, hid_input, 0);
        dbuf = malloc(dlen);
        if (!loop)
-               if (ioctl(f, USB_SET_IMMED, &one) < 0) {
+               if (hid_set_immed(f, 1) < 0) {
                        if (errno == EOPNOTSUPP)
                                warnx("device does not support immediate mode, 
only changes reported.");
                        else
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to