• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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