3 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
5 * Copyright (c) 2008 Hans Petter Selasky. All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 #ifdef USB_GLOBAL_INCLUDE_FILE
30 #include USB_GLOBAL_INCLUDE_FILE
32 #include <sys/stdint.h>
33 #include <sys/stddef.h>
34 #include <sys/param.h>
35 #include <sys/queue.h>
36 #include <sys/types.h>
37 #include <sys/systm.h>
38 #include <sys/kernel.h>
40 #include <sys/module.h>
42 #include <sys/mutex.h>
43 #include <sys/condvar.h>
44 #include <sys/sysctl.h>
46 #include <sys/unistd.h>
47 #include <sys/callout.h>
48 #include <sys/malloc.h>
51 #include <dev/usb/usb.h>
52 #include <dev/usb/usbdi.h>
53 #include <dev/usb/usbdi_util.h>
56 #define USB_DEBUG_VAR usb_debug
58 #include <dev/usb/usb_core.h>
59 #include <dev/usb/usb_process.h>
60 #include <dev/usb/usb_busdma.h>
61 #include <dev/usb/usb_transfer.h>
62 #include <dev/usb/usb_device.h>
63 #include <dev/usb/usb_debug.h>
64 #include <dev/usb/usb_dynamic.h>
65 #include <dev/usb/usb_hub.h>
67 #include <dev/usb/usb_controller.h>
68 #include <dev/usb/usb_bus.h>
69 #endif /* USB_GLOBAL_INCLUDE_FILE */
71 /* function prototypes */
73 static uint8_t usb_handle_get_stall(struct usb_device *, uint8_t);
74 static usb_error_t usb_handle_remote_wakeup(struct usb_xfer *, uint8_t);
75 static usb_error_t usb_handle_request(struct usb_xfer *);
76 static usb_error_t usb_handle_set_config(struct usb_xfer *, uint8_t);
77 static usb_error_t usb_handle_set_stall(struct usb_xfer *, uint8_t,
79 static usb_error_t usb_handle_iface_request(struct usb_xfer *, void **,
80 uint16_t *, struct usb_device_request, uint16_t,
83 /*------------------------------------------------------------------------*
84 * usb_handle_request_callback
86 * This function is the USB callback for generic USB Device control
88 *------------------------------------------------------------------------*/
90 usb_handle_request_callback(struct usb_xfer *xfer, usb_error_t error)
94 /* check the current transfer state */
96 switch (USB_GET_STATE(xfer)) {
98 case USB_ST_TRANSFERRED:
100 /* handle the request */
101 err = usb_handle_request(xfer);
104 if (err == USB_ERR_BAD_CONTEXT) {
105 /* we need to re-setup the control transfer */
106 usb_needs_explore(xfer->xroot->bus, 0);
111 usbd_transfer_submit(xfer);
115 /* check if a control transfer is active */
116 if (xfer->flags_int.control_rem != 0xFFFF) {
117 /* handle the request */
118 err = usb_handle_request(xfer);
120 if (xfer->error != USB_ERR_CANCELLED) {
121 /* should not happen - try stalling */
130 * If a control transfer is active, stall it, and wait for the
131 * next control transfer.
133 usbd_xfer_set_frame_len(xfer, 0, sizeof(struct usb_device_request));
135 xfer->flags.manual_status = 1;
136 xfer->flags.force_short_xfer = 0;
137 usbd_xfer_set_stall(xfer); /* cancel previous transfer, if any */
138 usbd_transfer_submit(xfer);
141 /*------------------------------------------------------------------------*
142 * usb_handle_set_config
147 *------------------------------------------------------------------------*/
149 usb_handle_set_config(struct usb_xfer *xfer, uint8_t conf_no)
151 struct usb_device *udev = xfer->xroot->udev;
156 * We need to protect against other threads doing probe and
159 USB_XFER_UNLOCK(xfer);
161 /* Prevent re-enumeration */
162 do_unlock = usbd_enum_lock(udev);
164 if (conf_no == USB_UNCONFIG_NO) {
165 conf_no = USB_UNCONFIG_INDEX;
168 * The relationship between config number and config index
169 * is very simple in our case:
174 if (usbd_set_config_index(udev, conf_no)) {
175 DPRINTF("set config %d failed\n", conf_no);
176 err = USB_ERR_STALLED;
179 if (usb_probe_and_attach(udev, USB_IFACE_INDEX_ANY)) {
180 DPRINTF("probe and attach failed\n");
181 err = USB_ERR_STALLED;
186 usbd_enum_unlock(udev);
192 usb_check_alt_setting(struct usb_device *udev,
193 struct usb_interface *iface, uint8_t alt_index)
198 /* Prevent re-enumeration */
199 do_unlock = usbd_enum_lock(udev);
201 if (alt_index >= usbd_get_no_alts(udev->cdesc, iface->idesc))
205 usbd_enum_unlock(udev);
210 /*------------------------------------------------------------------------*
211 * usb_handle_iface_request
216 *------------------------------------------------------------------------*/
218 usb_handle_iface_request(struct usb_xfer *xfer,
219 void **ppdata, uint16_t *plen,
220 struct usb_device_request req, uint16_t off, uint8_t state)
222 struct usb_interface *iface;
223 struct usb_interface *iface_parent; /* parent interface */
224 struct usb_device *udev = xfer->xroot->udev;
230 if ((req.bmRequestType & 0x1F) == UT_INTERFACE) {
231 iface_index = req.wIndex[0]; /* unicast */
233 iface_index = 0; /* broadcast */
237 * We need to protect against other threads doing probe and
240 USB_XFER_UNLOCK(xfer);
242 /* Prevent re-enumeration */
243 do_unlock = usbd_enum_lock(udev);
248 iface = usbd_get_iface(udev, iface_index);
249 if ((iface == NULL) ||
250 (iface->idesc == NULL)) {
251 /* end of interfaces non-existing interface */
254 /* set initial state */
258 /* forward request to interface, if any */
262 (iface->subdev != NULL) &&
263 device_is_attached(iface->subdev)) {
265 DEVMETHOD(usb_handle_request, NULL); /* dummy */
267 error = USB_HANDLE_REQUEST(iface->subdev,
271 iface_parent = usbd_get_iface(udev, iface->parent_iface_index);
273 if ((iface_parent == NULL) ||
274 (iface_parent->idesc == NULL)) {
275 /* non-existing interface */
278 /* forward request to parent interface, if any */
282 (iface_parent != NULL) &&
283 (iface_parent->subdev != NULL) &&
284 ((req.bmRequestType & 0x1F) == UT_INTERFACE) &&
285 (iface_parent->subdev != iface->subdev) &&
286 device_is_attached(iface_parent->subdev)) {
287 error = USB_HANDLE_REQUEST(iface_parent->subdev,
288 &req, ppdata, plen, off, &temp_state);
291 /* negativly adjust pointer and length */
292 *ppdata = ((uint8_t *)(*ppdata)) - off;
295 if ((state == USB_HR_NOT_COMPLETE) &&
296 (temp_state == USB_HR_COMPLETE_OK))
300 } else if (error == ENOTTY) {
303 if ((req.bmRequestType & 0x1F) != UT_INTERFACE) {
304 iface_index++; /* iterate */
307 if (state != USB_HR_NOT_COMPLETE) {
308 /* we are complete */
311 switch (req.bmRequestType) {
312 case UT_WRITE_INTERFACE:
313 switch (req.bRequest) {
314 case UR_SET_INTERFACE:
316 * We assume that the endpoints are the same
317 * across the alternate settings.
319 * Reset the endpoints, because re-attaching
320 * only a part of the device is not possible.
322 error = usb_check_alt_setting(udev,
323 iface, req.wValue[0]);
325 DPRINTF("alt setting does not exist %s\n",
329 error = usb_reset_iface_endpoints(udev, iface_index);
331 DPRINTF("alt setting failed %s\n",
335 /* update the current alternate setting */
336 iface->alt_index = req.wValue[0];
344 case UT_READ_INTERFACE:
345 switch (req.bRequest) {
346 case UR_GET_INTERFACE:
347 *ppdata = &iface->alt_index;
360 usbd_enum_unlock(udev);
366 usbd_enum_unlock(udev);
368 return (USB_ERR_SHORT_XFER);
372 usbd_enum_unlock(udev);
374 return (USB_ERR_STALLED);
377 /*------------------------------------------------------------------------*
383 *------------------------------------------------------------------------*/
385 usb_handle_set_stall(struct usb_xfer *xfer, uint8_t ep, uint8_t do_stall)
387 struct usb_device *udev = xfer->xroot->udev;
390 USB_XFER_UNLOCK(xfer);
391 err = usbd_set_endpoint_stall(udev,
392 usbd_get_ep_by_addr(udev, ep), do_stall);
397 /*------------------------------------------------------------------------*
398 * usb_handle_get_stall
403 *------------------------------------------------------------------------*/
405 usb_handle_get_stall(struct usb_device *udev, uint8_t ea_val)
407 struct usb_endpoint *ep;
410 ep = usbd_get_ep_by_addr(udev, ea_val);
415 USB_BUS_LOCK(udev->bus);
416 halted = ep->is_stalled;
417 USB_BUS_UNLOCK(udev->bus);
422 /*------------------------------------------------------------------------*
423 * usb_handle_remote_wakeup
428 *------------------------------------------------------------------------*/
430 usb_handle_remote_wakeup(struct usb_xfer *xfer, uint8_t is_on)
432 struct usb_device *udev;
435 udev = xfer->xroot->udev;
441 udev->flags.remote_wakeup = 1;
443 udev->flags.remote_wakeup = 0;
449 /* In case we are out of sync, update the power state. */
450 usb_bus_power_update(udev->bus);
452 return (0); /* success */
455 /*------------------------------------------------------------------------*
458 * Internal state sequence:
460 * USB_HR_NOT_COMPLETE -> USB_HR_COMPLETE_OK v USB_HR_COMPLETE_ERR
463 * 0: Ready to start hardware
464 * Else: Stall current transfer, if any
465 *------------------------------------------------------------------------*/
467 usb_handle_request(struct usb_xfer *xfer)
469 struct usb_device_request req;
470 struct usb_device *udev;
471 const void *src_zcopy; /* zero-copy source pointer */
472 const void *src_mcopy; /* non zero-copy source pointer */
473 uint16_t off; /* data offset */
474 uint16_t rem; /* data remainder */
475 uint16_t max_len; /* max fragment length */
478 uint8_t is_complete = 1;
486 * Filter the USB transfer state into
487 * something which we understand:
490 switch (USB_GET_STATE(xfer)) {
492 state = USB_HR_NOT_COMPLETE;
494 if (!xfer->flags_int.control_act) {
499 case USB_ST_TRANSFERRED:
500 if (!xfer->flags_int.control_act) {
501 state = USB_HR_COMPLETE_OK;
503 state = USB_HR_NOT_COMPLETE;
507 state = USB_HR_COMPLETE_ERR;
511 /* reset frame stuff */
513 usbd_xfer_set_frame_len(xfer, 0, 0);
515 usbd_xfer_set_frame_offset(xfer, 0, 0);
516 usbd_xfer_set_frame_offset(xfer, sizeof(req), 1);
518 /* get the current request, if any */
520 usbd_copy_out(xfer->frbuffers, 0, &req, sizeof(req));
522 if (xfer->flags_int.control_rem == 0xFFFF) {
523 /* first time - not initialised */
524 rem = UGETW(req.wLength);
527 /* not first time - initialised */
528 rem = xfer->flags_int.control_rem;
529 off = UGETW(req.wLength) - rem;
532 /* set some defaults */
537 udev = xfer->xroot->udev;
539 /* get some request fields decoded */
541 wValue = UGETW(req.wValue);
543 DPRINTF("req 0x%02x 0x%02x 0x%04x 0x%04x "
544 "off=0x%x rem=0x%x, state=%d\n", req.bmRequestType,
545 req.bRequest, wValue, UGETW(req.wIndex), off, rem, state);
547 /* demultiplex the control request */
549 switch (req.bmRequestType) {
551 if (state != USB_HR_NOT_COMPLETE) {
554 switch (req.bRequest) {
555 case UR_GET_DESCRIPTOR:
556 goto tr_handle_get_descriptor;
558 goto tr_handle_get_config;
560 goto tr_handle_get_status;
566 case UT_WRITE_DEVICE:
567 switch (req.bRequest) {
569 goto tr_handle_set_address;
571 goto tr_handle_set_config;
572 case UR_CLEAR_FEATURE:
574 case UF_DEVICE_REMOTE_WAKEUP:
575 goto tr_handle_clear_wakeup;
582 case UF_DEVICE_REMOTE_WAKEUP:
583 goto tr_handle_set_wakeup;
593 case UT_WRITE_ENDPOINT:
594 switch (req.bRequest) {
595 case UR_CLEAR_FEATURE:
597 case UF_ENDPOINT_HALT:
598 goto tr_handle_clear_halt;
605 case UF_ENDPOINT_HALT:
606 goto tr_handle_set_halt;
616 case UT_READ_ENDPOINT:
617 switch (req.bRequest) {
619 goto tr_handle_get_ep_status;
625 /* we use "USB_ADD_BYTES" to de-const the src_zcopy */
626 err = usb_handle_iface_request(xfer,
627 USB_ADD_BYTES(&src_zcopy, 0),
628 &max_len, req, off, state);
632 } else if (err == USB_ERR_SHORT_XFER) {
636 * Reset zero-copy pointer and max length
637 * variable in case they were unintentionally
644 * Check if we have a vendor specific
647 goto tr_handle_get_descriptor;
651 tr_handle_get_descriptor:
652 err = (usb_temp_get_desc_p) (udev, &req, &src_zcopy, &max_len);
655 if (src_zcopy == NULL)
659 tr_handle_get_config:
660 temp.buf[0] = udev->curr_config_no;
661 src_mcopy = temp.buf;
665 tr_handle_get_status:
669 USB_BUS_LOCK(udev->bus);
670 if (udev->flags.remote_wakeup) {
671 wValue |= UDS_REMOTE_WAKEUP;
673 if (udev->flags.self_powered) {
674 wValue |= UDS_SELF_POWERED;
676 USB_BUS_UNLOCK(udev->bus);
678 USETW(temp.wStatus, wValue);
679 src_mcopy = temp.wStatus;
680 max_len = sizeof(temp.wStatus);
683 tr_handle_set_address:
684 if (state == USB_HR_NOT_COMPLETE) {
685 if (wValue >= 0x80) {
688 } else if (udev->curr_config_no != 0) {
689 /* we are configured ! */
692 } else if (state != USB_HR_NOT_COMPLETE) {
693 udev->address = (wValue & 0x7F);
698 tr_handle_set_config:
699 if (state == USB_HR_NOT_COMPLETE) {
700 if (usb_handle_set_config(xfer, req.wValue[0])) {
706 tr_handle_clear_halt:
707 if (state == USB_HR_NOT_COMPLETE) {
708 if (usb_handle_set_stall(xfer, req.wIndex[0], 0)) {
714 tr_handle_clear_wakeup:
715 if (state == USB_HR_NOT_COMPLETE) {
716 if (usb_handle_remote_wakeup(xfer, 0)) {
723 if (state == USB_HR_NOT_COMPLETE) {
724 if (usb_handle_set_stall(xfer, req.wIndex[0], 1)) {
730 tr_handle_set_wakeup:
731 if (state == USB_HR_NOT_COMPLETE) {
732 if (usb_handle_remote_wakeup(xfer, 1)) {
738 tr_handle_get_ep_status:
739 if (state == USB_HR_NOT_COMPLETE) {
741 usb_handle_get_stall(udev, req.wIndex[0]);
743 src_mcopy = temp.wStatus;
744 max_len = sizeof(temp.wStatus);
749 if (state != USB_HR_NOT_COMPLETE) {
752 /* subtract offset from length */
756 /* Compute the real maximum data length */
758 if (max_len > xfer->max_data_length) {
759 max_len = usbd_xfer_max_len(xfer);
765 * If the remainder is greater than the maximum data length,
766 * we need to truncate the value for the sake of the
769 if (rem > xfer->max_data_length) {
770 rem = usbd_xfer_max_len(xfer);
772 if ((rem != max_len) && (is_complete != 0)) {
774 * If we don't transfer the data we can transfer, then
775 * the transfer is short !
777 xfer->flags.force_short_xfer = 1;
783 xfer->flags.force_short_xfer = 0;
784 xfer->nframes = max_len ? 2 : 1;
788 src_mcopy = USB_ADD_BYTES(src_mcopy, off);
789 usbd_copy_in(xfer->frbuffers + 1, 0,
791 usbd_xfer_set_frame_len(xfer, 1, max_len);
793 usbd_xfer_set_frame_data(xfer, 1,
794 USB_ADD_BYTES(src_zcopy, off), max_len);
797 /* the end is reached, send status */
798 xfer->flags.manual_status = 0;
799 usbd_xfer_set_frame_len(xfer, 1, 0);
801 DPRINTF("success\n");
802 return (0); /* success */
805 DPRINTF("%s\n", (state != USB_HR_NOT_COMPLETE) ?
806 "complete" : "stalled");
807 return (USB_ERR_STALLED);
810 DPRINTF("bad context\n");
811 return (USB_ERR_BAD_CONTEXT);