svn commit: r261262 - head/sys/dev/usb/input

Hans Petter Selasky hselasky at FreeBSD.org
Wed Jan 29 12:34:06 UTC 2014


Author: hselasky
Date: Wed Jan 29 12:34:05 2014
New Revision: 261262
URL: http://svnweb.freebsd.org/changeset/base/261262

Log:
  - Remove some dead code.
  - Use system provided functions for HID report requests.
  - Nice the mode setting, because the USB hardware does appear to
  handle the commands right away.
  
  MFC after:	1 week

Modified:
  head/sys/dev/usb/input/wsp.c

Modified: head/sys/dev/usb/input/wsp.c
==============================================================================
--- head/sys/dev/usb/input/wsp.c	Wed Jan 29 11:39:58 2014	(r261261)
+++ head/sys/dev/usb/input/wsp.c	Wed Jan 29 12:34:05 2014	(r261262)
@@ -569,15 +569,11 @@ static const STRUCT_USB_HOST_ID wsp_devs
 
 enum {
 	WSP_INTR_DT,
-	WSP_RESET,
 	WSP_N_TRANSFER,
 };
 
 struct wsp_softc {
-	device_t sc_dev;
 	struct usb_device *sc_usb_device;
-#define	MODE_LENGTH 8
-	uint8_t	sc_mode_bytes[MODE_LENGTH];	/* device mode */
 	struct mtx sc_mutex;		/* for synchronization */
 	struct usb_xfer *sc_xfer[WSP_N_TRANSFER];
 	struct usb_fifo_sc sc_fifo;
@@ -648,8 +644,6 @@ static struct usb_fifo_methods wsp_fifo_
 };
 
 /* device initialization and shutdown */
-static usb_error_t wsp_req_get_report(struct usb_device *udev, void *data);
-static int wsp_set_device_mode(device_t dev, interface_mode mode);
 static int wsp_enable(struct wsp_softc *sc);
 static void wsp_disable(struct wsp_softc *sc);
 
@@ -662,7 +656,6 @@ static device_probe_t wsp_probe;
 static device_attach_t wsp_attach;
 static device_detach_t wsp_detach;
 static usb_callback_t wsp_intr_callback;
-static usb_callback_t wsp_reset_callback;
 
 static struct usb_config wsp_config[WSP_N_TRANSFER] = {
 	[WSP_INTR_DT] = {
@@ -676,87 +669,36 @@ static struct usb_config wsp_config[WSP_
 		.bufsize = 0,		/* use wMaxPacketSize */
 		.callback = &wsp_intr_callback,
 	},
-	[WSP_RESET] = {
-		.type = UE_CONTROL,
-		.endpoint = 0,		/* Control pipe */
-		.direction = UE_DIR_ANY,
-		.bufsize = sizeof(struct usb_device_request) + MODE_LENGTH,
-		.callback = &wsp_reset_callback,
-		.interval = 0,		/* no pre-delay */
-	},
 };
 
-usb_error_t
-wsp_req_get_report(struct usb_device *udev, void *data)
+static usb_error_t
+wsp_set_device_mode(struct wsp_softc *sc, interface_mode mode)
 {
-	struct usb_device_request req;
-
-	req.bmRequestType = UT_READ_CLASS_INTERFACE;
-	req.bRequest = UR_GET_REPORT;
-	USETW2(req.wValue, (uint8_t)0x03 /* type */ , (uint8_t)0x00 /* id */ );
-	USETW(req.wIndex, 0);
-	USETW(req.wLength, MODE_LENGTH);
-
-	return (usbd_do_request(udev, NULL /* mutex */ , &req, data));
-}
-
-static int
-wsp_set_device_mode(device_t dev, interface_mode mode)
-{
-	struct wsp_softc *sc;
-	usb_device_request_t req;
+	uint8_t	mode_bytes[8];
 	usb_error_t err;
 
-	if ((mode != RAW_SENSOR_MODE) && (mode != HID_MODE))
-		return (ENXIO);
-
-	sc = device_get_softc(dev);
+	err = usbd_req_get_report(sc->sc_usb_device, NULL,
+	    mode_bytes, sizeof(mode_bytes), 0,
+	    0x03, 0x00);
 
-	sc->sc_mode_bytes[0] = mode;
-	req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
-	req.bRequest = UR_SET_REPORT;
-	USETW2(req.wValue, (uint8_t)0x03 /* type */ , (uint8_t)0x00 /* id */ );
-	USETW(req.wIndex, 0);
-	USETW(req.wLength, MODE_LENGTH);
-	err = usbd_do_request(sc->sc_usb_device, NULL, &req, sc->sc_mode_bytes);
-	if (err != USB_ERR_NORMAL_COMPLETION)
-		return (ENXIO);
-
-	return (0);
-}
-
-static void
-wsp_reset_callback(struct usb_xfer *xfer, usb_error_t error)
-{
-	usb_device_request_t req;
-	struct usb_page_cache *pc;
-	struct wsp_softc *sc = usbd_xfer_softc(xfer);
+	if (err != USB_ERR_NORMAL_COMPLETION) {
+		DPRINTF("Failed to read device mode (%d)\n", err);
+		return (err);
+	}
 
-	switch (USB_GET_STATE(xfer)) {
-	case USB_ST_SETUP:
-		sc->sc_mode_bytes[0] = RAW_SENSOR_MODE;
-		req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
-		req.bRequest = UR_SET_REPORT;
-		USETW2(req.wValue,
-		    (uint8_t)0x03 /* type */ , (uint8_t)0x00 /* id */ );
-		USETW(req.wIndex, 0);
-		USETW(req.wLength, MODE_LENGTH);
+	/*
+	 * XXX Need to wait at least 250ms for hardware to get
+	 * ready. The device mode handling appears to be handled
+	 * asynchronously and we should not issue these commands too
+	 * quickly.
+	 */
+	pause("WHW", hz / 4);
 
-		pc = usbd_xfer_get_frame(xfer, 0);
-		usbd_copy_in(pc, 0, &req, sizeof(req));
-		pc = usbd_xfer_get_frame(xfer, 1);
-		usbd_copy_in(pc, 0, sc->sc_mode_bytes, MODE_LENGTH);
-
-		usbd_xfer_set_frame_len(xfer, 0, sizeof(req));
-		usbd_xfer_set_frame_len(xfer, 1, MODE_LENGTH);
-		usbd_xfer_set_frames(xfer, 2);
-		usbd_transfer_submit(xfer);
-		break;
+	mode_bytes[0] = mode;
 
-	case USB_ST_TRANSFERRED:
-	default:
-		break;
-	}
+	return (usbd_req_set_report(sc->sc_usb_device, NULL,
+	    mode_bytes, sizeof(mode_bytes), 0,
+	    0x03, 0x00));
 }
 
 static int
@@ -820,27 +762,35 @@ wsp_attach(device_t dev)
 
 	DPRINTFN(WSP_LLEVEL_INFO, "sc=%p\n", sc);
 
-	sc->sc_dev = dev;
 	sc->sc_usb_device = uaa->device;
 
 	/*
-	 * By default the touchpad behaves like an HID device, sending
+	 * By default the touchpad behaves like a HID device, sending
 	 * packets with reportID = 8. Such reports contain only
 	 * limited information. They encode movement deltas and button
 	 * events, but do not include data from the pressure
 	 * sensors. The device input mode can be switched from HID
 	 * reports to raw sensor data using vendor-specific USB
-	 * control commands; but first the mode must be read.
+	 * control commands:
 	 */
-	err = wsp_req_get_report(sc->sc_usb_device, sc->sc_mode_bytes);
+
+	/*
+	 * During re-enumeration of the device we need to force the
+	 * device back into HID mode before switching it to RAW
+	 * mode. Else the device does not work like expected.
+	 */
+	err = wsp_set_device_mode(sc, HID_MODE);
 	if (err != USB_ERR_NORMAL_COMPLETION) {
-		DPRINTF("failed to read device mode (%d)\n", err);
+		DPRINTF("Failed to set mode to HID MODE (%d)\n", err);
 		return (ENXIO);
 	}
-	if (wsp_set_device_mode(dev, RAW_SENSOR_MODE) != 0) {
-		DPRINTF("failed to set mode to 'RAW_SENSOR' (%d)\n", err);
+
+	err = wsp_set_device_mode(sc, RAW_SENSOR_MODE);
+	if (err != USB_ERR_NORMAL_COMPLETION) {
+		DPRINTF("failed to set mode to RAW MODE (%d)\n", err);
 		return (ENXIO);
 	}
+
 	mtx_init(&sc->sc_mutex, "wspmtx", NULL, MTX_DEF | MTX_RECURSE);
 
 	/* get device specific configuration */
@@ -891,7 +841,7 @@ wsp_detach(device_t dev)
 {
 	struct wsp_softc *sc = device_get_softc(dev);
 
-	wsp_set_device_mode(dev, HID_MODE);
+	(void) wsp_set_device_mode(sc, HID_MODE);
 
 	mtx_lock(&sc->sc_mutex);
 	if (sc->sc_state & WSP_ENABLED)


More information about the svn-src-head mailing list