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