xref: /third_party/FreeBSD/sys/dev/usb/usb_debug.c (revision f9f848fa)
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 */
38int	usb_debug = 0;
39#ifdef LOSCFG_USB_DEBUG
40void
41usb_debug_func(int level)
42{
43	usb_debug = level;
44	PRINTK("The level of usb other class debug is %d\n", level);
45}
46DEBUG_MODULE(other, usb_debug_func);
47#endif
48
49/*------------------------------------------------------------------------*
50 *	usb_dump_iface
51 *
52 * This function dumps information about an USB interface.
53 *------------------------------------------------------------------------*/
54void
55usb_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 *------------------------------------------------------------------------*/
69void
70usb_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 *------------------------------------------------------------------------*/
88void
89usb_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 *------------------------------------------------------------------------*/
107void
108usb_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 *------------------------------------------------------------------------*/
132void
133usb_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
157unsigned int usb_port_reset_delay	= USB_PORT_RESET_DELAY;
158unsigned int usb_port_root_reset_delay	= USB_PORT_ROOT_RESET_DELAY;
159unsigned int usb_port_reset_recovery	= USB_PORT_RESET_RECOVERY;
160unsigned int usb_port_powerup_delay	= USB_PORT_POWERUP_DELAY;
161unsigned int usb_port_resume_delay	= USB_PORT_RESUME_DELAY;
162unsigned int usb_set_address_settle	= USB_SET_ADDRESS_SETTLE;
163unsigned int usb_resume_delay		= USB_RESUME_DELAY;
164unsigned int usb_resume_wait		= USB_RESUME_WAIT;
165unsigned int usb_resume_recovery	= USB_RESUME_RECOVERY;
166unsigned int usb_extra_power_up_time	= USB_EXTRA_POWER_UP_TIME;
167
168#ifdef LOSCFG_DRIVERS_USB_HOST_EHCI
169extern struct debug_module_data debug_ehci_mod;
170#endif
171#ifdef LOSCFG_DRIVERS_USB_ETHERNET
172extern struct debug_module_data debug_axe_mod;
173extern struct debug_module_data debug_axge_mod;
174#endif
175#ifdef LOSCFG_DRIVERS_USB_4G_MODEM
176extern struct debug_module_data debug_cdce_mod;
177#endif
178#ifdef LOSCFG_DRIVERS_USB_RNDIS_HOST
179extern struct debug_module_data debug_urndis_mod;
180#endif
181#if defined(LOSCFG_DRIVERS_USB_SERIAL) || defined(LOSCFG_DRIVERS_USB_4G_MODEM)
182extern struct debug_module_data debug_u3g_mod;
183extern struct debug_module_data debug_serial_mod;
184#endif
185#ifdef LOSCFG_DRIVERS_USB_MASS_STORAGE
186extern struct debug_module_data debug_umass_mod;
187#endif
188#ifdef LOSCFG_DRIVERS_USB_HOST_DRIVER
189extern struct debug_module_data debug_controller_mod;
190extern struct debug_module_data debug_uhub_mod;
191extern struct debug_module_data debug_process_mod;
192#endif
193
194static 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
224void
225usb_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
234void
235usb_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
245void
246usb_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
272SHELLCMD_ENTRY(usb_debug_shellcmd, CMD_TYPE_EX, "usb_debug", 0, (CmdCallBackFunc)usb_debug_shell_cmd);
273#endif
274#endif
275