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