svn commit: r233771 - head/sys/dev/usb

Hans Petter Selasky hselasky at FreeBSD.org
Mon Apr 2 07:51:31 UTC 2012


Author: hselasky
Date: Mon Apr  2 07:51:30 2012
New Revision: 233771
URL: http://svn.freebsd.org/changeset/base/233771

Log:
  Add definitions and structures for USB 2.0 Link Power Management, LPM.
  
  MFC after:	2 weeks

Modified:
  head/sys/dev/usb/usb.h
  head/sys/dev/usb/usb_request.c
  head/sys/dev/usb/usb_request.h

Modified: head/sys/dev/usb/usb.h
==============================================================================
--- head/sys/dev/usb/usb.h	Mon Apr  2 07:42:17 2012	(r233770)
+++ head/sys/dev/usb/usb.h	Mon Apr  2 07:51:30 2012	(r233771)
@@ -225,7 +225,8 @@ typedef struct usb_device_request usb_de
 #define	UR_RESET_TT		0x09
 #define	UR_GET_TT_STATE		0x0a
 #define	UR_STOP_TT		0x0b
-#define	UR_SET_HUB_DEPTH	0x0c
+#define	UR_SET_AND_TEST		0x0c	/* USB 2.0 only */
+#define	UR_SET_HUB_DEPTH	0x0c	/* USB 3.0 only */
 #define	USB_SS_HUB_DEPTH_MAX	5
 #define	UR_GET_PORT_ERR_COUNT	0x0d
 
@@ -248,6 +249,7 @@ typedef struct usb_device_request usb_de
 #define	UHF_PORT_LINK_STATE	5
 #define	UHF_PORT_POWER		8
 #define	UHF_PORT_LOW_SPEED	9
+#define	UHF_PORT_L1		10
 #define	UHF_C_PORT_CONNECTION	16
 #define	UHF_C_PORT_ENABLE	17
 #define	UHF_C_PORT_SUSPEND	18
@@ -255,6 +257,7 @@ typedef struct usb_device_request usb_de
 #define	UHF_C_PORT_RESET	20
 #define	UHF_PORT_TEST		21
 #define	UHF_PORT_INDICATOR	22
+#define	UHF_C_PORT_L1		23
 
 /* SuperSpeed HUB specific features */
 #define	UHF_PORT_U1_TIMEOUT	23
@@ -324,7 +327,12 @@ struct usb_devcap_usb2ext_descriptor {
 	uByte	bDescriptorType;
 	uByte	bDevCapabilityType;
 	uDWord	bmAttributes;
-#define	USB_V2EXT_LPM 0x02
+#define	USB_V2EXT_LPM (1U << 1)
+#define	USB_V2EXT_BESL_SUPPORTED (1U << 2)
+#define	USB_V2EXT_BESL_BASELINE_VALID (1U << 3)
+#define	USB_V2EXT_BESL_DEEP_VALID (1U << 4)
+#define	USB_V2EXT_BESL_BASELINE_GET(x) (((x) >> 8) & 0xF)
+#define	USB_V2EXT_BESL_DEEP_GET(x) (((x) >> 12) & 0xF)
 } __packed;
 typedef struct usb_devcap_usb2ext_descriptor usb_devcap_usb2ext_descriptor_t;
 
@@ -671,6 +679,7 @@ struct usb_port_status {
 #define	UPS_SUSPEND			0x0004
 #define	UPS_OVERCURRENT_INDICATOR	0x0008
 #define	UPS_RESET			0x0010
+#define	UPS_PORT_L1			0x0020	/* USB 2.0 only */
 /* The link-state bits are valid for Super-Speed USB HUBs */
 #define	UPS_PORT_LINK_STATE_GET(x)	(((x) >> 5) & 0xF)
 #define	UPS_PORT_LINK_STATE_SET(x)	(((x) & 0xF) << 5)
@@ -701,7 +710,8 @@ struct usb_port_status {
 #define	UPS_C_SUSPEND			0x0004
 #define	UPS_C_OVERCURRENT_INDICATOR	0x0008
 #define	UPS_C_PORT_RESET		0x0010
-#define	UPS_C_BH_PORT_RESET		0x0020
+#define	UPS_C_PORT_L1			0x0020	/* USB 2.0 only */
+#define	UPS_C_BH_PORT_RESET		0x0020	/* USB 3.0 only */
 #define	UPS_C_PORT_LINK_STATE		0x0040
 #define	UPS_C_PORT_CONFIG_ERROR		0x0080
 } __packed;

Modified: head/sys/dev/usb/usb_request.c
==============================================================================
--- head/sys/dev/usb/usb_request.c	Mon Apr  2 07:42:17 2012	(r233770)
+++ head/sys/dev/usb/usb_request.c	Mon Apr  2 07:51:30 2012	(r233771)
@@ -2226,3 +2226,57 @@ usbd_req_set_port_link_state(struct usb_
 	USETW(req.wLength, 0);
 	return (usbd_do_request(udev, mtx, &req, 0));
 }
+
+/*------------------------------------------------------------------------*
+ *		usbd_req_set_lpm_info
+ *
+ * USB 2.0 specific request for Link Power Management.
+ *
+ * Returns:
+ * 0:				Success
+ * USB_ERR_PENDING_REQUESTS:	NYET
+ * USB_ERR_TIMEOUT:		TIMEOUT
+ * USB_ERR_STALL:		STALL
+ * Else:			Failure
+ *------------------------------------------------------------------------*/
+usb_error_t
+usbd_req_set_lpm_info(struct usb_device *udev, struct mtx *mtx,
+    uint8_t port, uint8_t besl, uint8_t addr, uint8_t rwe)
+{
+	struct usb_device_request req;
+	usb_error_t err;
+	uint8_t buf[1];
+
+	req.bmRequestType = UT_WRITE_CLASS_OTHER;
+	req.bRequest = UR_SET_AND_TEST;
+	USETW(req.wValue, UHF_PORT_L1);
+	req.wIndex[0] = (port & 0xF) | ((besl & 0xF) << 4);
+	req.wIndex[1] = (addr & 0x7F) | (rwe ? 0x80 : 0x00);
+	USETW(req.wLength, sizeof(buf));
+
+	/* set default value in case of short transfer */
+	buf[0] = 0x00;
+
+	err = usbd_do_request(udev, mtx, &req, buf);
+	if (err)
+		return (err);
+
+	switch (buf[0]) {
+	case 0x00:	/* SUCCESS */
+		break;
+	case 0x10:	/* NYET */
+		err = USB_ERR_PENDING_REQUESTS;
+		break;
+	case 0x11:	/* TIMEOUT */
+		err = USB_ERR_TIMEOUT;
+		break;
+	case 0x30:	/* STALL */
+		err = USB_ERR_STALLED;
+		break;
+	default:	/* reserved */
+		err = USB_ERR_IOERROR;
+		break;
+	}
+	return (err);
+}
+

Modified: head/sys/dev/usb/usb_request.h
==============================================================================
--- head/sys/dev/usb/usb_request.h	Mon Apr  2 07:42:17 2012	(r233770)
+++ head/sys/dev/usb/usb_request.h	Mon Apr  2 07:51:30 2012	(r233771)
@@ -91,5 +91,7 @@ usb_error_t usbd_req_clear_tt_buffer(str
 		    uint8_t port, uint8_t addr, uint8_t type, uint8_t endpoint);
 usb_error_t usbd_req_set_port_link_state(struct usb_device *udev,
 		    struct mtx *mtx, uint8_t port, uint8_t link_state);
+usb_error_t usbd_req_set_lpm_info(struct usb_device *udev, struct mtx *mtx,
+		    uint8_t port, uint8_t besl, uint8_t addr, uint8_t rwe);
 
 #endif					/* _USB_REQUEST_H_ */


More information about the svn-src-head mailing list