31#ifdef USB_GLOBAL_INCLUDE_FILE
32#include USB_GLOBAL_INCLUDE_FILE
34#include <sys/stdint.h>
35#include <sys/stddef.h>
40#include <sys/kernel.h>
42#include <sys/module.h>
45#include <sys/condvar.h>
46#include <sys/sysctl.h>
48#include <sys/unistd.h>
49#include <sys/callout.h>
50#include <sys/malloc.h>
58#define USB_DEBUG_VAR usb_debug
78 &
usb_no_cs_fail, 0,
"USB clear stall failures are ignored, if set");
83 &
usb_full_ddesc, 0,
"USB always read complete device descriptor, if set");
88struct usb_ctrl_debug {
95 int bmRequestType_value;
99struct usb_ctrl_debug_bits {
109static struct usb_ctrl_debug usb_ctrl_debug = {
112 .bmRequestType_value = -1,
113 .bRequest_value = -1,
116SYSCTL_INT(_hw_usb, OID_AUTO, ctrl_bus_fail, CTLFLAG_RWTUN,
117 &usb_ctrl_debug.bus_index, 0,
"USB controller index to fail");
118SYSCTL_INT(_hw_usb, OID_AUTO, ctrl_dev_fail, CTLFLAG_RWTUN,
119 &usb_ctrl_debug.dev_index, 0,
"USB device address to fail");
120SYSCTL_INT(_hw_usb, OID_AUTO, ctrl_ds_fail, CTLFLAG_RWTUN,
121 &usb_ctrl_debug.ds_fail, 0,
"USB fail data stage");
122SYSCTL_INT(_hw_usb, OID_AUTO, ctrl_ss_fail, CTLFLAG_RWTUN,
123 &usb_ctrl_debug.ss_fail, 0,
"USB fail status stage");
124SYSCTL_INT(_hw_usb, OID_AUTO, ctrl_ds_delay, CTLFLAG_RWTUN,
125 &usb_ctrl_debug.ds_delay, 0,
"USB data stage delay in ms");
126SYSCTL_INT(_hw_usb, OID_AUTO, ctrl_ss_delay, CTLFLAG_RWTUN,
127 &usb_ctrl_debug.ss_delay, 0,
"USB status stage delay in ms");
128SYSCTL_INT(_hw_usb, OID_AUTO, ctrl_rt_fail, CTLFLAG_RWTUN,
129 &usb_ctrl_debug.bmRequestType_value, 0,
"USB bmRequestType to fail");
130SYSCTL_INT(_hw_usb, OID_AUTO, ctrl_rv_fail, CTLFLAG_RWTUN,
131 &usb_ctrl_debug.bRequest_value, 0,
"USB bRequest to fail");
140 struct usb_ctrl_debug_bits *dbg)
144 memset(dbg, 0,
sizeof(*dbg));
148 temp = usb_ctrl_debug.ds_delay;
151 else if (temp > (16*1024))
154 dbg->ds_delay = temp;
158 temp = usb_ctrl_debug.ss_delay;
161 else if (temp > (16*1024))
164 dbg->ss_delay = temp;
174 temp = usb_ctrl_debug.bmRequestType_value;
176 if ((temp !=
req->bmRequestType) && (temp >= 0) && (temp <= 255))
179 temp = usb_ctrl_debug.bRequest_value;
181 if ((temp !=
req->bRequest) && (temp >= 0) && (temp <= 255))
184 temp = usb_ctrl_debug.ds_fail;
188 temp = usb_ctrl_debug.ss_fail;
273 if ((ep < ep_first) || (ep >= ep_end))
308 DPRINTF(
"Clear stall failed.\n");
321 DPRINTF(
"Trying to re-enumerate.\n");
326 DPRINTF(
"Trying to re-enumerate.\n");
410 struct usb_ctrl_debug_bits dbg;
434 DPRINTFN(5,
"udev=%p bmRequestType=0x%02x bRequest=0x%02x "
435 "wValue=0x%02x%02x wIndex=0x%02x%02x wLength=0x%02x%02x\n",
436 udev,
req->bmRequestType,
req->bRequest,
437 req->wValue[1],
req->wValue[0],
438 req->wIndex[1],
req->wIndex[0],
439 req->wLength[1],
req->wLength[0]);
443 DPRINTF(
"usb device has gone\n");
454#if (USB_HAVE_USER_IO == 0)
458 if ((mtx != NULL) && (mtx != &Giant)) {
470 if (hr_func != NULL) {
471 DPRINTF(
"Handle Request function is set\n");
478 DPRINTFN(1,
"The handle request function "
479 "does not support writing data!\n");
488 err = (hr_func) (udev,
req, &
desc, &temp);
532 usbd_get_debug_bits(udev,
req, &dbg);
570 }
else if (temp > 0) {
575 if (dbg.ds_delay > 0) {
613 if (dbg.ss_delay > 0) {
652 if (temp > acttemp) {
689 delta_ticks = ticks - start_ticks;
690 if (delta_ticks > max_ticks) {
713 if ((mtx != NULL) && (mtx != &Giant))
723 DPRINTF(
"error=%s - waiting a bit for TT cleanup\n",
857 DPRINTFN(2,
"port %d reset returning error=%s\n",
900 DPRINTF(
"Wrong state for warm reset\n");
956 DPRINTFN(2,
"port %d warm reset returning error=%s\n",
987 struct mtx *mtx, uint16_t *actlen,
void *
desc,
988 uint16_t min_len, uint16_t max_len,
989 uint16_t
id, uint8_t type, uint8_t index,
996 DPRINTFN(4,
"id=%d, type=%d, index=%d, max_len=%d\n",
1005 if ((min_len < 2) || (max_len < 2)) {
1012 desc, 0, NULL, 1000 );
1015 min_len != max_len) {
1017 memset(
desc, 0, max_len);
1027 if (buf[0] > max_len)
1029 else if (buf[0] < 2)
1051 if (min_len == max_len) {
1053 if ((buf[0] > min_len) && (actlen == NULL))
1063 if (max_len > buf[0]) {
1068 while (min_len > max_len) {
1078 if (actlen != NULL) {
1101 uint16_t
len, uint8_t string_index)
1115 if (string_index == 0) {
1125 (udev, mtx, buf,
len, udev->
langid, string_index);
1130 temp = (uint8_t *)buf;
1142 n = (temp[0] / 2) - 1;
1153 for (i = 0; (i !=
n); i++) {
1154 c =
UGETW(temp + (2 * i));
1157 if (((c & 0xff00) == 0) && (swap & 1)) {
1161 }
else if (((c & 0x00ff) == 0) && (swap & 2)) {
1207 uint16_t max_len, uint16_t lang_id,
1208 uint8_t string_index)
1246 if (hr_func == NULL)
1250 err = (hr_func) (udev, &
req, &ptr, &
len);
1256 else if (ptr == NULL)
1277 DPRINTFN(4,
"confidx=%d\n", conf_index);
1306 DPRINTF(
"Configuration descriptor too big\n");
1309#if (USB_HAVE_FIXED_CONFIG == 0)
1310 return (malloc(
size, M_USBDEV, M_ZERO | M_WAITOK));
1312 memset(udev->config_data, 0,
sizeof(udev->config_data));
1313 return (udev->config_data);
1325#if (USB_HAVE_FIXED_CONFIG == 0)
1326 free(ptr, M_USBDEV);
1350 DPRINTFN(4,
"index=%d\n",
index);
1360 if (
len < (uint32_t)
sizeof(*cdesc)) {
1364 DPRINTF(
"Configuration descriptor was truncated\n");
1409 uint8_t *alt_iface_no, uint8_t iface_index)
1414 if ((iface == NULL) || (iface->
idesc == NULL))
1435 uint8_t iface_index, uint8_t alt_no)
1441 if ((iface == NULL) || (iface->
idesc == NULL))
1446 req.wValue[0] = alt_no;
1459 DPRINTF(
"Setting default alternate number failed. (ignored)\n");
1497 uint16_t
len = (nports + 7 + (8 * 8)) / 8;
1519 uint16_t
len =
sizeof(*hd) - 32 + 1 + ((nports + 7) / 8);
1566 DPRINTFN(6,
"setting device address=%d\n",
addr);
1611 req.wIndex[0] = port;
1669 uint8_t port, uint8_t timeout)
1676 req.wIndex[0] = port;
1677 req.wIndex[1] = timeout;
1691 uint8_t port, uint8_t timeout)
1698 req.wIndex[0] = port;
1699 req.wIndex[1] = timeout;
1734 uint8_t port, uint16_t sel)
1741 req.wIndex[0] = port;
1756 uint8_t port, uint16_t sel)
1763 req.wIndex[0] = port;
1778 uint8_t iface_index, uint16_t report)
1783 if ((iface == NULL) || (iface->
idesc == NULL)) {
1786 DPRINTFN(5,
"iface=%p, report=%d, endpt=%d\n",
1807 uint8_t iface_index, uint8_t type, uint8_t
id)
1812 if ((iface == NULL) || (iface->
idesc == NULL)) {
1815 DPRINTFN(5,
"len=%d\n",
len);
1835 uint16_t
len, uint8_t iface_index, uint8_t type, uint8_t
id)
1840 if ((iface == NULL) || (iface->
idesc == NULL)) {
1843 DPRINTFN(5,
"len=%d\n",
len);
1863 uint8_t iface_index, uint8_t duration, uint8_t
id)
1868 if ((iface == NULL) || (iface->
idesc == NULL)) {
1871 DPRINTFN(5,
"%d %d\n", duration,
id);
1891 void *d, uint16_t
size, uint8_t iface_index)
1896 if ((iface == NULL) || (iface->
idesc == NULL)) {
1924 DPRINTF(
"setting config %d\n", conf);
1930 req.wValue[0] = conf;
1975 switch (udev->
speed) {
1988 DPRINTF(
"Trying fallback for getting the USB device descriptor\n");
2009 DPRINTF(
"Minimum bMaxPacketSize is large enough "
2010 "to hold the complete device descriptor or "
2011 "only one bMaxPacketSize choice\n");
2023 DPRINTFN(0,
"getting device descriptor "
2024 "at addr %d failed, %s\n", udev->
address,
2029 DPRINTF(
"adding unit addr=%d, rev=%02x, class=%d, "
2030 "subclass=%d, protocol=%d, maxpacket=%d, len=%d, speed=%d\n",
2059 uint8_t do_retry = 1;
2070#if USB_HAVE_TT_SUPPORT
2077 DPRINTF(
"Trying to reset parent High Speed TT.\n");
2090 DPRINTF(
"Resetting parent High "
2091 "Speed TT failed (%s).\n",
2103 DPRINTFN(0,
"addr=%d, port reset failed, %s\n",
2126 DPRINTFN(0,
"addr=%d, set address failed! (%s, ignored)\n",
2140 if (err && do_retry) {
2221 req.wIndex[0] = port;
2238 uint8_t port, uint8_t addr, uint8_t type, uint8_t
endpoint)
2255 req.wIndex[0] = port;
2272 uint8_t port, uint8_t link_state)
2279 req.wIndex[0] = port;
2280 req.wIndex[1] = link_state;
2299 uint8_t port, uint8_t besl, uint8_t addr, uint8_t rwe)
2308 req.wIndex[0] = (port & 0xF) | ((besl & 0xF) << 4);
2309 req.wIndex[1] = (
addr & 0x7F) | (rwe ? 0x80 : 0x00);
usb_handle_req_t * roothub_exec
usb_error_t(* set_address)(struct usb_device *, struct mtx *, uint16_t)
const struct usb_bus_methods * methods
enum usb_hc_mode usb_mode
struct usb_device * parent_hs_hub
struct usb_xfer * ctrl_xfer[USB_CTRL_XFER_MAX]
struct usb_device_descriptor ddesc
uint32_t clear_stall_errors
struct usb_device * parent_hub
struct usb_endpoint * ep_curr
struct usb_endpoint * endpoints
struct usb_device_flags flags
struct usb_xfer_queue endpoint_q[USB_MAX_EP_STREAMS]
struct usb_endpoint_descriptor * edesc
struct usb_interface_descriptor * idesc
struct usb_page_cache * frbuffers
struct usb_xfer_flags flags
struct usb_xfer_root * xroot
#define UPS_C_BH_PORT_RESET
#define UT_WRITE_INTERFACE
#define UT_WRITE_CLASS_OTHER
#define UT_WRITE_CLASS_DEVICE
#define UHF_PORT_LINK_STATE
#define UR_CLEAR_TT_BUFFER
#define UHF_BH_PORT_RESET
#define UT_READ_CLASS_INTERFACE
#define UHF_PORT_U1_TIMEOUT
#define UPS_PORT_LS_SS_INA
#define UPS_PORT_LS_COMP_MODE
#define UPS_PORT_LINK_STATE_GET(x)
#define UT_WRITE_ENDPOINT
#define UT_READ_CLASS_DEVICE
#define UPS_PORT_LS_LOOPBACK
#define UT_WRITE_CLASS_INTERFACE
#define UT_READ_CLASS_OTHER
#define UPS_CURRENT_CONNECT_STATUS
#define UHF_C_BH_PORT_RESET
#define UT_READ_INTERFACE
#define UR_GET_DESCRIPTOR
#define UHF_PORT_U2_TIMEOUT
void usbd_copy_in(struct usb_page_cache *cache, usb_frlength_t offset, const void *ptr, usb_frlength_t len)
void usbd_copy_out(struct usb_page_cache *cache, usb_frlength_t offset, void *ptr, usb_frlength_t len)
#define USB_XFER_LOCK(_x)
#define USB_ADD_BYTES(ptr, size)
#define USB_BUS_UNLOCK(_b)
#define USB_XFER_UNLOCK(_x)
#define usb_port_reset_recovery
#define usb_port_reset_delay
#define usb_set_address_settle
uint8_t usbd_get_bus_index(struct usb_device *udev)
uint8_t usbd_ctrl_lock(struct usb_device *udev)
void usbd_ctrl_unlock(struct usb_device *udev)
void usb_set_device_state(struct usb_device *udev, enum usb_dev_state state)
struct usb_interface * usbd_get_iface(struct usb_device *udev, uint8_t iface_index)
uint8_t usbd_get_device_index(struct usb_device *udev)
uint8_t uhub_count_active_host_ports(struct usb_device *, enum usb_dev_speed)
struct usb_endpoint_descriptor desc
struct usb_host_endpoint * endpoint
usb_handle_req_t * usb_temp_get_desc_p
#define USETW2(w, b1, b0)
const char * usbd_errstr(usb_error_t err)
#define USB_CS_RESET_LIMIT
#define USB_MAX_EP_STREAMS
void usbd_start_re_enumerate(struct usb_device *udev)
uint8_t usb_proc_is_gone(struct usb_process *up)
usb_error_t usbd_req_set_hub_u2_timeout(struct usb_device *udev, struct mtx *mtx, uint8_t port, uint8_t timeout)
static usb_handle_req_t * usbd_get_hr_func(struct usb_device *udev)
usb_error_t usbd_req_get_hub_descriptor(struct usb_device *udev, struct mtx *mtx, struct usb_hub_descriptor *hd, uint8_t nports)
void * usbd_alloc_config_desc(struct usb_device *udev, uint32_t size)
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)
usb_error_t usbd_req_get_alt_interface_no(struct usb_device *udev, struct mtx *mtx, uint8_t *alt_iface_no, uint8_t iface_index)
usb_error_t usbd_req_get_desc(struct usb_device *udev, struct mtx *mtx, uint16_t *actlen, void *desc, uint16_t min_len, uint16_t max_len, uint16_t id, uint8_t type, uint8_t index, uint8_t retries)
void usbd_free_config_desc(struct usb_device *udev, void *ptr)
usb_error_t usbd_req_get_ss_hub_descriptor(struct usb_device *udev, struct mtx *mtx, struct usb_hub_ss_descriptor *hd, uint8_t nports)
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_clear_tt_buffer(struct usb_device *udev, struct mtx *mtx, uint8_t port, uint8_t addr, uint8_t type, uint8_t endpoint)
usb_error_t usbd_req_get_device_status(struct usb_device *udev, struct mtx *mtx, struct usb_status *st)
usb_error_t usbd_req_set_config(struct usb_device *udev, struct mtx *mtx, uint8_t conf)
static int usb_no_cs_fail
usb_error_t usbd_req_get_device_desc(struct usb_device *udev, struct mtx *mtx, struct usb_device_descriptor *d)
usb_error_t usbd_req_set_device_feature(struct usb_device *udev, struct mtx *mtx, uint16_t sel)
usb_error_t usbd_setup_device_desc(struct usb_device *udev, struct mtx *mtx)
usb_error_t usbd_req_set_alt_interface_no(struct usb_device *udev, struct mtx *mtx, uint8_t iface_index, uint8_t alt_no)
usb_error_t usbd_req_get_report_descriptor(struct usb_device *udev, struct mtx *mtx, void *d, uint16_t size, uint8_t iface_index)
usb_error_t usbd_req_reset_tt(struct usb_device *udev, struct mtx *mtx, uint8_t port)
usb_error_t usbd_req_get_string_desc(struct usb_device *udev, struct mtx *mtx, void *sdesc, uint16_t max_len, uint16_t lang_id, uint8_t string_index)
usb_error_t usbd_req_get_config_desc_full(struct usb_device *udev, struct mtx *mtx, struct usb_config_descriptor **ppcd, uint8_t index)
usb_error_t usbd_req_set_hub_u1_timeout(struct usb_device *udev, struct mtx *mtx, uint8_t port, uint8_t timeout)
usb_error_t usbd_do_request_proc(struct usb_device *udev, struct usb_process *pproc, struct usb_device_request *req, void *data, uint16_t flags, uint16_t *actlen, usb_timeout_t timeout)
usb_error_t usbd_req_set_hub_feature(struct usb_device *udev, struct mtx *mtx, uint16_t sel)
usb_error_t usbd_req_reset_port(struct usb_device *udev, struct mtx *mtx, uint8_t port)
usb_error_t usbd_req_get_string_any(struct usb_device *udev, struct mtx *mtx, char *buf, uint16_t len, uint8_t string_index)
usb_error_t usbd_req_get_config(struct usb_device *udev, struct mtx *mtx, uint8_t *pconf)
usb_error_t usbd_req_clear_hub_feature(struct usb_device *udev, struct mtx *mtx, uint16_t sel)
void usb_do_clear_stall_callback(struct usb_xfer *xfer, usb_error_t error)
usb_error_t usbd_req_set_report(struct usb_device *udev, struct mtx *mtx, void *data, uint16_t len, uint8_t iface_index, uint8_t type, uint8_t id)
void usbd_do_request_callback(struct usb_xfer *xfer, usb_error_t error)
static int usb_full_ddesc
usb_error_t usbd_req_re_enumerate(struct usb_device *udev, struct mtx *mtx)
usb_error_t usbd_req_set_hub_depth(struct usb_device *udev, struct mtx *mtx, uint16_t depth)
usb_error_t usbd_req_clear_port_feature(struct usb_device *udev, struct mtx *mtx, uint8_t port, uint16_t sel)
usb_error_t usbd_req_get_report(struct usb_device *udev, struct mtx *mtx, void *data, uint16_t len, uint8_t iface_index, uint8_t type, uint8_t id)
usb_error_t usbd_req_get_config_desc(struct usb_device *udev, struct mtx *mtx, struct usb_config_descriptor *d, uint8_t conf_index)
usb_error_t usbd_req_set_idle(struct usb_device *udev, struct mtx *mtx, uint8_t iface_index, uint8_t duration, uint8_t id)
usb_error_t usbd_req_set_address(struct usb_device *udev, struct mtx *mtx, uint16_t addr)
usb_error_t usbd_req_get_hub_status(struct usb_device *udev, struct mtx *mtx, struct usb_hub_status *st)
usb_error_t usbd_req_set_protocol(struct usb_device *udev, struct mtx *mtx, uint8_t iface_index, uint16_t report)
usb_error_t usbd_req_get_descriptor_ptr(struct usb_device *udev, struct usb_config_descriptor **ppcd, uint16_t wValue)
usb_error_t usbd_req_warm_reset_port(struct usb_device *udev, struct mtx *mtx, uint8_t port)
usb_error_t usbd_req_clear_device_feature(struct usb_device *udev, struct mtx *mtx, uint16_t sel)
usb_error_t usbd_do_request_flags(struct usb_device *udev, struct mtx *mtx, struct usb_device_request *req, void *data, uint16_t flags, uint16_t *actlen, usb_timeout_t timeout)
SYSCTL_INT(_hw_usb, OID_AUTO, no_cs_fail, CTLFLAG_RWTUN, &usb_no_cs_fail, 0, "USB clear stall failures are ignored, if set")
usb_error_t usbd_req_set_port_feature(struct usb_device *udev, struct mtx *mtx, uint8_t port, uint16_t sel)
usb_error_t usbd_req_get_port_status(struct usb_device *udev, struct mtx *mtx, struct usb_port_status *ps, uint8_t port)
void usbd_transfer_submit(struct usb_xfer *xfer)
void usbd_xfer_set_frames(struct usb_xfer *xfer, usb_frcount_t n)
void usbd_xfer_set_frame_len(struct usb_xfer *xfer, usb_frcount_t frindex, usb_frlength_t len)
void usbd_ctrl_transfer_setup(struct usb_device *udev)
usb_frlength_t usbd_xfer_frame_len(struct usb_xfer *xfer, usb_frcount_t frindex)
void usbd_transfer_start(struct usb_xfer *xfer)
void usb_command_wrapper(struct usb_xfer_queue *pq, struct usb_xfer *xfer)
void usbd_transfer_stop(struct usb_xfer *xfer)
usb_frlength_t usbd_xfer_max_len(struct usb_xfer *xfer)
void usbd_clear_stall_locked(struct usb_device *udev, struct usb_endpoint *ep)
uint8_t usbd_transfer_pending(struct usb_xfer *xfer)
void usb_pause_mtx(struct mtx *mtx, int timo)
#define USB_MTX_UNLOCK(_m)
#define USB_MTX_ASSERT(_m, _t)
int usbd_copy_in_user(struct usb_page_cache *cache, usb_frlength_t offset, const void *ptr, usb_frlength_t len)
#define USB_DELAY_STATUS_STAGE
int usbd_copy_out_user(struct usb_page_cache *cache, usb_frlength_t offset, void *ptr, usb_frlength_t len)
@ USB_ERR_NORMAL_COMPLETION
@ USB_ERR_PENDING_REQUESTS
#define USB_USER_DATA_PTR
#define USB_SHORT_XFER_OK
#define USB_ST_TRANSFERRED
#define USB_MS_TO_TICKS(ms)
#define USB_GET_STATE(xfer)
#define usbd_do_request(u, m, r, d)
usb_error_t() usb_handle_req_t(struct usb_device *, struct usb_device_request *, const void **, uint16_t *)