Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 27 Jan 2009 16:19:07 GMT
From:      Hans Petter Selasky <hselasky@FreeBSD.org>
To:        Perforce Change Reviews <perforce@FreeBSD.org>
Subject:   PERFORCE change 156746 for review
Message-ID:  <200901271619.n0RGJ7Zu044923@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=156746

Change 156746 by hselasky@hselasky_laptop001 on 2009/01/27 16:18:15

	
	Add old-USB HID ioctls to libusbhid.
	Improve UHID driver.
	Reported by:  Daichi GOTO and Masanori OZAWA.

Affected files ...

.. //depot/projects/usb/src/lib/libusbhid/Makefile#2 edit
.. //depot/projects/usb/src/lib/libusbhid/descr.c#5 edit
.. //depot/projects/usb/src/lib/libusbhid/descr_compat.c#1 add
.. //depot/projects/usb/src/lib/libusbhid/usbhid.3#4 edit
.. //depot/projects/usb/src/lib/libusbhid/usbvar.h#2 edit
.. //depot/projects/usb/src/sys/dev/usb2/input/uhid2.c#14 edit

Differences ...

==== //depot/projects/usb/src/lib/libusbhid/Makefile#2 (text+ko) ====

@@ -15,7 +15,7 @@
 	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
 

==== //depot/projects/usb/src/lib/libusbhid/descr.c#5 (text+ko) ====

@@ -47,18 +47,26 @@
 int
 hid_set_immed(int fd, int enable)
 {
-	return (ioctl(fd, USB_SET_IMMED, &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;
 
-	if (ioctl(fd, USB_GET_REPORT_ID, &temp) < 0)
-		return (-1);
+	ret = ioctl(fd, USB_GET_REPORT_ID, &temp);
+	if (ret < 0)
+		ret = hid_get_report_id_compat7(fd);
+	else
+		ret = temp;
 
-	return (temp);
+	return (ret);
 }
 
 report_desc_t
@@ -67,39 +75,39 @@
 	struct usb2_gen_descriptor ugd;
 	report_desc_t rep;
 	void *data;
-	int size;
 
-	size = 256;			/* be conservative */
+	memset(&ugd, 0, sizeof(ugd));
 
-retry:
+	/* 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));
+	}
 
-	memset(&ugd, 0, sizeof(ugd));
-
-	data = malloc(size);
+	/*
+	 * NOTE: The kernel will return a failure if 
+	 * "ugd_actlen" is zero.
+	 */
+	data = malloc(ugd.ugd_actlen);
 	if (data == NULL)
 		return (NULL);
 
-	/* 
-	 * We subtract one from size so that the maximum descriptor
-	 * size is 65535 bytes, because "ugd_maxlen" is a 16-bit
-	 * variable!
-	 */
+	/* fetch actual descriptor */
 	ugd.ugd_data = data;
-	ugd.ugd_maxlen = size-1;
+	ugd.ugd_maxlen = ugd.ugd_actlen;
 	if (ioctl(fd, USB_GET_REPORT_DESC, &ugd) < 0) {
 		/* could not read descriptor */
 		free(data);
 		return (NULL);
 	}
 
-	if ((ugd.ugd_maxlen != 65535) && 
-	    (ugd.ugd_maxlen == ugd.ugd_actlen)) {
-		/* buffer is too small */
-		free (data);
-		size *= 4;
-		if (size <= 65536)
-			goto retry;
-		/* maximum reached - should not happen */
+	/* check END_COLLECTION */
+	if (((unsigned char *)ugd.ugd_data)[ugd.ugd_actlen -1] != 0xC0) {
+		/* invalid end byte */
+		free(data);
 		return (NULL);
 	}
 

==== //depot/projects/usb/src/lib/libusbhid/usbhid.3#4 (text+ko) ====

@@ -26,7 +26,7 @@
 .\"
 .\" $FreeBSD: src/lib/libusbhid/usbhid.3,v 1.18 2005/11/24 11:26:36 ru Exp $
 .\"
-.Dd December 29, 2001
+.Dd January 27, 2009
 .Dt USBHID 3
 .Os
 .Sh NAME
@@ -102,6 +102,8 @@
 .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

==== //depot/projects/usb/src/lib/libusbhid/usbvar.h#2 (text+ko) ====

@@ -25,7 +25,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/lib/libusbhid/usbvar.h,v 1.2 2002/03/27 16:07:18 joe Exp $
+ * $FreeBSD: $
  *
  */
 
@@ -34,3 +34,8 @@
 	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);

==== //depot/projects/usb/src/sys/dev/usb2/input/uhid2.c#14 (text+ko) ====

@@ -87,10 +87,9 @@
 
 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 @@
 	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_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 @@
 		}
 
 	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 @@
 		.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 @@
 			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;
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200901271619.n0RGJ7Zu044923>