summaryrefslogtreecommitdiffstats
path: root/sys/dev/usb/usb_request.c
diff options
context:
space:
mode:
authorhselasky <hselasky@FreeBSD.org>2012-04-02 07:51:30 +0000
committerhselasky <hselasky@FreeBSD.org>2012-04-02 07:51:30 +0000
commit0a4ce326a73bdc8b6b96ff8028c64860d1e775f1 (patch)
treeac77863678e77055eb470d5ecf0682d535b8f568 /sys/dev/usb/usb_request.c
parent6dfa60e0bf7108729fa98dcc5d5a4f38a306ea03 (diff)
downloadFreeBSD-src-0a4ce326a73bdc8b6b96ff8028c64860d1e775f1.zip
FreeBSD-src-0a4ce326a73bdc8b6b96ff8028c64860d1e775f1.tar.gz
Add definitions and structures for USB 2.0 Link Power Management, LPM.
MFC after: 2 weeks
Diffstat (limited to 'sys/dev/usb/usb_request.c')
-rw-r--r--sys/dev/usb/usb_request.c54
1 files changed, 54 insertions, 0 deletions
diff --git a/sys/dev/usb/usb_request.c b/sys/dev/usb/usb_request.c
index c403a70..3faebd3 100644
--- a/sys/dev/usb/usb_request.c
+++ b/sys/dev/usb/usb_request.c
@@ -2226,3 +2226,57 @@ usbd_req_set_port_link_state(struct usb_device *udev, struct mtx *mtx,
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);
+}
+
OpenPOWER on IntegriCloud