From 0a4ce326a73bdc8b6b96ff8028c64860d1e775f1 Mon Sep 17 00:00:00 2001 From: hselasky Date: Mon, 2 Apr 2012 07:51:30 +0000 Subject: Add definitions and structures for USB 2.0 Link Power Management, LPM. MFC after: 2 weeks --- sys/dev/usb/usb_request.c | 54 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) (limited to 'sys/dev/usb/usb_request.c') 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); +} + -- cgit v1.1