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
usb_debug_func(int level)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
usb_dump_iface(struct usb_interface * iface)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
usb_dump_device(struct usb_device * udev)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
usb_dump_queue(struct usb_endpoint * ep)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
usb_dump_endpoint(struct usb_endpoint * ep)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
usb_dump_xfer(struct usb_xfer * xfer)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
usb_debug_module_regsiter(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
usb_debug_module_unregsiter(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
usb_debug_shell_cmd(uint32_t argc,char ** argv)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