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