1 /* $FreeBSD: releng/12.2/sys/dev/usb/usb_debug.c 326255 2017-11-27 14:52:40Z pfg $ */ 2 /*- 3 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 4 * 5 * Copyright (c) 2008 Hans Petter Selasky. All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 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. 15 * 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 26 * SUCH DAMAGE. 27 */ 28 29 #include "implementation/global_implementation.h" 30 #ifdef LOSCFG_SHELL 31 #include "shcmd.h" 32 #endif 33 34 35 /* 36 * Define this unconditionally in case a kernel module is loaded that 37 * has been compiled with debugging options. 38 */ 39 int usb_debug = 0; 40 #ifdef LOSCFG_USB_DEBUG 41 void 42 usb_debug_func(int level) 43 { 44 usb_debug = level; 45 PRINTK("The level of usb other class debug is %d\n", level); 46 } 47 DEBUG_MODULE(other, usb_debug_func); 48 #endif 49 50 /*------------------------------------------------------------------------* 51 * usb_dump_iface 52 * 53 * This function dumps information about an USB interface. 54 *------------------------------------------------------------------------*/ 55 void 56 usb_dump_iface(struct usb_interface *iface) 57 { 58 if (iface == NULL) { 59 return; 60 } 61 PRINTK(" iface=%p idesc=%p altindex=%d\n", 62 iface, iface->idesc, iface->alt_index); 63 } 64 65 /*------------------------------------------------------------------------* 66 * usb_dump_device 67 * 68 * This function dumps information about an USB device. 69 *------------------------------------------------------------------------*/ 70 void 71 usb_dump_device(struct usb_device *udev) 72 { 73 if (udev == NULL) { 74 return; 75 } 76 PRINTK(" bus=%p \n" 77 " address=%d config=%d depth=%d speed=%d self_powered=%d\n" 78 " power=%d langid=%d\n", 79 udev->bus, 80 udev->address, udev->curr_config_no, udev->depth, udev->speed, 81 udev->flags.self_powered, udev->power, udev->langid); 82 } 83 84 /*------------------------------------------------------------------------* 85 * usb_dump_queue 86 * 87 * This function dumps the USB transfer that are queued up on an USB endpoint. 88 *------------------------------------------------------------------------*/ 89 void 90 usb_dump_queue(struct usb_endpoint *ep) 91 { 92 struct usb_xfer *xfer; 93 usb_stream_t x; 94 95 PRINTK("usb_dump_queue: endpoint=%p xfer: ", ep); 96 for (x = 0; x != USB_MAX_EP_STREAMS; x++) { 97 TAILQ_FOREACH(xfer, &ep->endpoint_q[x].head, wait_entry) 98 PRINTK(" %p", xfer); 99 } 100 PRINTK("\n"); 101 } 102 103 /*------------------------------------------------------------------------* 104 * usb_dump_endpoint 105 * 106 * This function dumps information about an USB endpoint. 107 *------------------------------------------------------------------------*/ 108 void 109 usb_dump_endpoint(struct usb_endpoint *ep) 110 { 111 if (ep) { 112 PRINTK("usb_dump_endpoint: endpoint=%p", ep); 113 114 PRINTK(" edesc=%p isoc_next=%d toggle_next=%d", 115 ep->edesc, ep->isoc_next, ep->toggle_next); 116 117 if (ep->edesc) { 118 PRINTK(" bEndpointAddress=0x%02x", 119 ep->edesc->bEndpointAddress); 120 } 121 PRINTK("\n"); 122 usb_dump_queue(ep); 123 } else { 124 PRINTK("usb_dump_endpoint: endpoint=NULL\n"); 125 } 126 } 127 128 /*------------------------------------------------------------------------* 129 * usb_dump_xfer 130 * 131 * This function dumps information about an USB transfer. 132 *------------------------------------------------------------------------*/ 133 void 134 usb_dump_xfer(struct usb_xfer *xfer) 135 { 136 struct usb_device *udev; 137 PRINTK("usb_dump_xfer: xfer=%p\n", xfer); 138 if (xfer == NULL) { 139 return; 140 } 141 if (xfer->endpoint == NULL) { 142 PRINTK("xfer %p: endpoint=NULL\n", 143 xfer); 144 return; 145 } 146 udev = xfer->xroot->udev; 147 PRINTK("xfer %p: udev=%p vid=0x%04x pid=0x%04x addr=%d " 148 "endpoint=%p ep=0x%02x attr=0x%02x\n", 149 xfer, udev, 150 UGETW(udev->ddesc.idVendor), 151 UGETW(udev->ddesc.idProduct), 152 udev->address, xfer->endpoint, 153 xfer->endpoint->edesc->bEndpointAddress, 154 xfer->endpoint->edesc->bmAttributes); 155 } 156 157 #ifdef LOSCFG_USB_DEBUG 158 unsigned int usb_port_reset_delay = USB_PORT_RESET_DELAY; 159 unsigned int usb_port_root_reset_delay = USB_PORT_ROOT_RESET_DELAY; 160 unsigned int usb_port_reset_recovery = USB_PORT_RESET_RECOVERY; 161 unsigned int usb_port_powerup_delay = USB_PORT_POWERUP_DELAY; 162 unsigned int usb_port_resume_delay = USB_PORT_RESUME_DELAY; 163 unsigned int usb_set_address_settle = USB_SET_ADDRESS_SETTLE; 164 unsigned int usb_resume_delay = USB_RESUME_DELAY; 165 unsigned int usb_resume_wait = USB_RESUME_WAIT; 166 unsigned int usb_resume_recovery = USB_RESUME_RECOVERY; 167 unsigned int usb_extra_power_up_time = USB_EXTRA_POWER_UP_TIME; 168 169 #ifdef LOSCFG_DRIVERS_USB_HOST_EHCI 170 extern struct debug_module_data debug_ehci_mod; 171 #endif 172 #ifdef LOSCFG_DRIVERS_USB_ETHERNET 173 extern struct debug_module_data debug_axe_mod; 174 extern struct debug_module_data debug_axge_mod; 175 #endif 176 #ifdef LOSCFG_DRIVERS_USB_4G_MODEM 177 extern struct debug_module_data debug_cdce_mod; 178 #endif 179 #ifdef LOSCFG_DRIVERS_USB_RNDIS_HOST 180 extern struct debug_module_data debug_urndis_mod; 181 #endif 182 #if defined(LOSCFG_DRIVERS_USB_SERIAL) || defined(LOSCFG_DRIVERS_USB_4G_MODEM) 183 extern struct debug_module_data debug_u3g_mod; 184 extern struct debug_module_data debug_serial_mod; 185 #endif 186 #ifdef LOSCFG_DRIVERS_USB_MASS_STORAGE 187 extern struct debug_module_data debug_umass_mod; 188 #endif 189 #ifdef LOSCFG_DRIVERS_USB_HOST_DRIVER 190 extern struct debug_module_data debug_controller_mod; 191 extern struct debug_module_data debug_uhub_mod; 192 extern struct debug_module_data debug_process_mod; 193 #endif 194 195 static struct debug_module_data *debug_mode_list[] = { 196 #ifdef LOSCFG_DRIVERS_USB_HOST_EHCI 197 &debug_ehci_mod, 198 #endif 199 #ifdef LOSCFG_DRIVERS_USB_ETHERNET 200 &debug_axe_mod, 201 &debug_axge_mod, 202 #endif 203 #ifdef LOSCFG_DRIVERS_USB_4G_MODEM 204 &debug_cdce_mod, 205 #endif 206 #ifdef LOSCFG_DRIVERS_USB_RNDIS_HOST 207 &debug_urndis_mod, 208 #endif 209 #if defined(LOSCFG_DRIVERS_USB_SERIAL) || defined(LOSCFG_DRIVERS_USB_4G_MODEM) 210 &debug_u3g_mod, 211 &debug_serial_mod, 212 #endif 213 #ifdef LOSCFG_DRIVERS_USB_MASS_STORAGE 214 &debug_umass_mod, 215 #endif 216 #ifdef LOSCFG_DRIVERS_USB_HOST_DRIVER 217 &debug_controller_mod, 218 &debug_uhub_mod, 219 &debug_process_mod, 220 #endif 221 &debug_other_mod, 222 NULL 223 }; 224 225 void 226 usb_debug_module_regsiter(void) 227 { 228 uint32_t i; 229 struct debug_module_data* mod; 230 for (i = 0; (mod = debug_mode_list[i]) && (mod != NULL); i++) { 231 debug_module_register(mod); 232 } 233 } 234 235 void 236 usb_debug_module_unregsiter(void) 237 { 238 uint32_t i; 239 struct debug_module_data* mod; 240 for (i = 0; (mod = debug_mode_list[i]) && (mod != NULL); i++) { 241 debug_module_unregister(mod); 242 } 243 } 244 245 #ifdef LOSCFG_SHELL_CMD_DEBUG 246 void 247 usb_debug_shell_cmd(uint32_t argc, char **argv) 248 { 249 uint32_t level = 0; 250 char *str; 251 struct debug_module_data* mod; 252 253 if (argc != 2) { 254 PRINTK("Usage: usb_debug module level\n"); 255 PRINTK("Modules:\n"); 256 debug_module_dump(); 257 return; 258 } 259 260 str = argv[0]; 261 level = strtoul(argv[1], 0, 0); 262 263 mod = get_debug_module(str); 264 if (mod == NULL) { 265 PRINTK("The module is not supported!\n"); 266 return; 267 } 268 269 if (mod->callback) 270 mod->callback(level); 271 } 272 273 SHELLCMD_ENTRY(usb_debug_shellcmd, CMD_TYPE_EX, "usb_debug", 0, (CmdCallBackFunc)usb_debug_shell_cmd); 274 #endif 275 #endif 276