usb_dynamic.c revision 330897
1/* $FreeBSD: stable/11/sys/dev/usb/usb_dynamic.c 330897 2018-03-14 03:19:51Z eadler $ */
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#ifdef USB_GLOBAL_INCLUDE_FILE
30#include USB_GLOBAL_INCLUDE_FILE
31#else
32#include <sys/stdint.h>
33#include <sys/stddef.h>
34#include <sys/param.h>
35#include <sys/queue.h>
36#include <sys/types.h>
37#include <sys/systm.h>
38#include <sys/kernel.h>
39#include <sys/bus.h>
40#include <sys/module.h>
41#include <sys/lock.h>
42#include <sys/mutex.h>
43#include <sys/condvar.h>
44#include <sys/sysctl.h>
45#include <sys/sx.h>
46#include <sys/unistd.h>
47#include <sys/callout.h>
48#include <sys/malloc.h>
49#include <sys/priv.h>
50
51#include <dev/usb/usb.h>
52#include <dev/usb/usbdi.h>
53
54#include <dev/usb/usb_core.h>
55#include <dev/usb/usb_process.h>
56#include <dev/usb/usb_device.h>
57#include <dev/usb/usb_dynamic.h>
58#include <dev/usb/usb_request.h>
59#endif			/* USB_GLOBAL_INCLUDE_FILE */
60
61/* function prototypes */
62static usb_handle_req_t usb_temp_get_desc_w;
63static usb_temp_setup_by_index_t usb_temp_setup_by_index_w;
64#if USB_HAVE_COMPAT_LINUX
65static usb_linux_free_device_t usb_linux_free_device_w;
66#endif
67static usb_temp_unsetup_t usb_temp_unsetup_w;
68static usb_test_quirk_t usb_test_quirk_w;
69static usb_quirk_ioctl_t usb_quirk_ioctl_w;
70
71/* global variables */
72usb_handle_req_t *usb_temp_get_desc_p = &usb_temp_get_desc_w;
73usb_temp_setup_by_index_t *usb_temp_setup_by_index_p = &usb_temp_setup_by_index_w;
74#if USB_HAVE_COMPAT_LINUX
75usb_linux_free_device_t *usb_linux_free_device_p = &usb_linux_free_device_w;
76#endif
77usb_temp_unsetup_t *usb_temp_unsetup_p = &usb_temp_unsetup_w;
78usb_test_quirk_t *usb_test_quirk_p = &usb_test_quirk_w;
79usb_quirk_ioctl_t *usb_quirk_ioctl_p = &usb_quirk_ioctl_w;
80devclass_t usb_devclass_ptr;
81
82static usb_error_t
83usb_temp_setup_by_index_w(struct usb_device *udev, uint16_t index)
84{
85	return (USB_ERR_INVAL);
86}
87
88static uint8_t
89usb_test_quirk_w(const struct usbd_lookup_info *info, uint16_t quirk)
90{
91	return (0);			/* no match */
92}
93
94static int
95usb_quirk_ioctl_w(unsigned long cmd, caddr_t data, int fflag, struct thread *td)
96{
97	return (ENOIOCTL);
98}
99
100static usb_error_t
101usb_temp_get_desc_w(struct usb_device *udev, struct usb_device_request *req, const void **pPtr, uint16_t *pLength)
102{
103	/* stall */
104	return (USB_ERR_STALLED);
105}
106
107static void
108usb_temp_unsetup_w(struct usb_device *udev)
109{
110	usbd_free_config_desc(udev, udev->usb_template_ptr);
111	udev->usb_template_ptr = NULL;
112}
113
114#if USB_HAVE_COMPAT_LINUX
115static void
116usb_linux_free_device_w(struct usb_device *udev)
117{
118	/* NOP */
119}
120#endif
121
122void
123usb_quirk_unload(void *arg)
124{
125	/* reset function pointers */
126
127	usb_test_quirk_p = &usb_test_quirk_w;
128	usb_quirk_ioctl_p = &usb_quirk_ioctl_w;
129
130	/* wait for CPU to exit the loaded functions, if any */
131
132	/* XXX this is a tradeoff */
133
134	pause("WAIT", hz);
135}
136
137void
138usb_temp_unload(void *arg)
139{
140	/* reset function pointers */
141
142	usb_temp_get_desc_p = &usb_temp_get_desc_w;
143	usb_temp_setup_by_index_p = &usb_temp_setup_by_index_w;
144	usb_temp_unsetup_p = &usb_temp_unsetup_w;
145
146	/* wait for CPU to exit the loaded functions, if any */
147
148	/* XXX this is a tradeoff */
149
150	pause("WAIT", hz);
151}
152
153void
154usb_bus_unload(void *arg)
155{
156	/* reset function pointers */
157
158	usb_devclass_ptr = NULL;
159
160	/* wait for CPU to exit the loaded functions, if any */
161
162	/* XXX this is a tradeoff */
163
164	pause("WAIT", hz);
165}
166
167#if USB_HAVE_COMPAT_LINUX
168void
169usb_linux_unload(void *arg)
170{
171	/* reset function pointers */
172
173	usb_linux_free_device_p = &usb_linux_free_device_w;
174
175	/* wait for CPU to exit the loaded functions, if any */
176
177	/* XXX this is a tradeoff */
178
179	pause("WAIT", hz);
180}
181#endif
182