Deleted Added
full compact
usb_controller.c (184610) usb_controller.c (184824)
1/* $FreeBSD: head/sys/dev/usb2/controller/usb2_controller.c 184610 2008-11-04 02:31:03Z alfred $ */
1/* $FreeBSD: head/sys/dev/usb2/controller/usb2_controller.c 184824 2008-11-10 20:54:31Z thompsa $ */
2/*-
3 * Copyright (c) 2008 Hans Petter Selasky. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 */
26
27#include <dev/usb2/include/usb2_mfunc.h>
28#include <dev/usb2/include/usb2_defs.h>
29#include <dev/usb2/include/usb2_error.h>
30#include <dev/usb2/include/usb2_standard.h>
31
32#define USB_DEBUG_VAR usb2_ctrl_debug
33
34#include <dev/usb2/core/usb2_core.h>
35#include <dev/usb2/core/usb2_debug.h>
36#include <dev/usb2/core/usb2_process.h>
37#include <dev/usb2/core/usb2_busdma.h>
38#include <dev/usb2/core/usb2_dynamic.h>
39#include <dev/usb2/core/usb2_device.h>
40#include <dev/usb2/core/usb2_hub.h>
41
42#include <dev/usb2/controller/usb2_controller.h>
43#include <dev/usb2/controller/usb2_bus.h>
44
45/* function prototypes */
46
47static device_probe_t usb2_probe;
48static device_attach_t usb2_attach;
49static device_detach_t usb2_detach;
50
51static void usb2_attach_sub(device_t dev, struct usb2_bus *bus);
52static void usb2_post_init(void *arg);
53static void usb2_bus_mem_flush_all_cb(struct usb2_bus *bus, struct usb2_page_cache *pc, struct usb2_page *pg, uint32_t size, uint32_t align);
54static void usb2_bus_mem_alloc_all_cb(struct usb2_bus *bus, struct usb2_page_cache *pc, struct usb2_page *pg, uint32_t size, uint32_t align);
55static void usb2_bus_mem_free_all_cb(struct usb2_bus *bus, struct usb2_page_cache *pc, struct usb2_page *pg, uint32_t size, uint32_t align);
56
57/* static variables */
58
59#if USB_DEBUG
60static int usb2_ctrl_debug = 0;
61
62SYSCTL_NODE(_hw_usb2, OID_AUTO, ctrl, CTLFLAG_RW, 0, "USB controller");
63SYSCTL_INT(_hw_usb2_ctrl, OID_AUTO, debug, CTLFLAG_RW, &usb2_ctrl_debug, 0,
64 "Debug level");
65#endif
66
67static uint8_t usb2_post_init_called = 0;
68
69static devclass_t usb2_devclass;
70
71static device_method_t usb2_methods[] = {
72 DEVMETHOD(device_probe, usb2_probe),
73 DEVMETHOD(device_attach, usb2_attach),
74 DEVMETHOD(device_detach, usb2_detach),
75 DEVMETHOD(device_suspend, bus_generic_suspend),
76 DEVMETHOD(device_resume, bus_generic_resume),
77 DEVMETHOD(device_shutdown, bus_generic_shutdown),
78 {0, 0}
79};
80
81static driver_t usb2_driver = {
82 .name = "usbus",
83 .methods = usb2_methods,
84 .size = 0,
85};
86
87DRIVER_MODULE(usbus, ohci, usb2_driver, usb2_devclass, 0, 0);
88DRIVER_MODULE(usbus, uhci, usb2_driver, usb2_devclass, 0, 0);
89DRIVER_MODULE(usbus, ehci, usb2_driver, usb2_devclass, 0, 0);
90DRIVER_MODULE(usbus, at91_udp, usb2_driver, usb2_devclass, 0, 0);
91DRIVER_MODULE(usbus, uss820, usb2_driver, usb2_devclass, 0, 0);
92
93MODULE_DEPEND(usb2_controller, usb2_core, 1, 1, 1);
94MODULE_VERSION(usb2_controller, 1);
95
96/*------------------------------------------------------------------------*
97 * usb2_probe
98 *
99 * This function is called from "{ehci,ohci,uhci}_pci_attach()".
100 *------------------------------------------------------------------------*/
101static int
102usb2_probe(device_t dev)
103{
104 DPRINTF("\n");
105 return (0);
106}
107
108/*------------------------------------------------------------------------*
109 * usb2_attach
110 *------------------------------------------------------------------------*/
111static int
112usb2_attach(device_t dev)
113{
114 struct usb2_bus *bus = device_get_ivars(dev);
115
116 DPRINTF("\n");
117
118 if (bus == NULL) {
119 DPRINTFN(0, "USB device has no ivars\n");
120 return (ENXIO);
121 }
122 if (usb2_post_init_called) {
123 mtx_lock(&Giant);
124 usb2_attach_sub(dev, bus);
125 mtx_unlock(&Giant);
126 usb2_needs_explore(bus, 1);
127 }
128 return (0); /* return success */
129}
130
131/*------------------------------------------------------------------------*
132 * usb2_detach
133 *------------------------------------------------------------------------*/
134static int
135usb2_detach(device_t dev)
136{
137 struct usb2_bus *bus = device_get_softc(dev);
138
139 DPRINTF("\n");
140
141 if (bus == NULL) {
142 /* was never setup properly */
143 return (0);
144 }
145 /* Let the USB explore process detach all devices. */
146
2/*-
3 * Copyright (c) 2008 Hans Petter Selasky. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 */
26
27#include <dev/usb2/include/usb2_mfunc.h>
28#include <dev/usb2/include/usb2_defs.h>
29#include <dev/usb2/include/usb2_error.h>
30#include <dev/usb2/include/usb2_standard.h>
31
32#define USB_DEBUG_VAR usb2_ctrl_debug
33
34#include <dev/usb2/core/usb2_core.h>
35#include <dev/usb2/core/usb2_debug.h>
36#include <dev/usb2/core/usb2_process.h>
37#include <dev/usb2/core/usb2_busdma.h>
38#include <dev/usb2/core/usb2_dynamic.h>
39#include <dev/usb2/core/usb2_device.h>
40#include <dev/usb2/core/usb2_hub.h>
41
42#include <dev/usb2/controller/usb2_controller.h>
43#include <dev/usb2/controller/usb2_bus.h>
44
45/* function prototypes */
46
47static device_probe_t usb2_probe;
48static device_attach_t usb2_attach;
49static device_detach_t usb2_detach;
50
51static void usb2_attach_sub(device_t dev, struct usb2_bus *bus);
52static void usb2_post_init(void *arg);
53static void usb2_bus_mem_flush_all_cb(struct usb2_bus *bus, struct usb2_page_cache *pc, struct usb2_page *pg, uint32_t size, uint32_t align);
54static void usb2_bus_mem_alloc_all_cb(struct usb2_bus *bus, struct usb2_page_cache *pc, struct usb2_page *pg, uint32_t size, uint32_t align);
55static void usb2_bus_mem_free_all_cb(struct usb2_bus *bus, struct usb2_page_cache *pc, struct usb2_page *pg, uint32_t size, uint32_t align);
56
57/* static variables */
58
59#if USB_DEBUG
60static int usb2_ctrl_debug = 0;
61
62SYSCTL_NODE(_hw_usb2, OID_AUTO, ctrl, CTLFLAG_RW, 0, "USB controller");
63SYSCTL_INT(_hw_usb2_ctrl, OID_AUTO, debug, CTLFLAG_RW, &usb2_ctrl_debug, 0,
64 "Debug level");
65#endif
66
67static uint8_t usb2_post_init_called = 0;
68
69static devclass_t usb2_devclass;
70
71static device_method_t usb2_methods[] = {
72 DEVMETHOD(device_probe, usb2_probe),
73 DEVMETHOD(device_attach, usb2_attach),
74 DEVMETHOD(device_detach, usb2_detach),
75 DEVMETHOD(device_suspend, bus_generic_suspend),
76 DEVMETHOD(device_resume, bus_generic_resume),
77 DEVMETHOD(device_shutdown, bus_generic_shutdown),
78 {0, 0}
79};
80
81static driver_t usb2_driver = {
82 .name = "usbus",
83 .methods = usb2_methods,
84 .size = 0,
85};
86
87DRIVER_MODULE(usbus, ohci, usb2_driver, usb2_devclass, 0, 0);
88DRIVER_MODULE(usbus, uhci, usb2_driver, usb2_devclass, 0, 0);
89DRIVER_MODULE(usbus, ehci, usb2_driver, usb2_devclass, 0, 0);
90DRIVER_MODULE(usbus, at91_udp, usb2_driver, usb2_devclass, 0, 0);
91DRIVER_MODULE(usbus, uss820, usb2_driver, usb2_devclass, 0, 0);
92
93MODULE_DEPEND(usb2_controller, usb2_core, 1, 1, 1);
94MODULE_VERSION(usb2_controller, 1);
95
96/*------------------------------------------------------------------------*
97 * usb2_probe
98 *
99 * This function is called from "{ehci,ohci,uhci}_pci_attach()".
100 *------------------------------------------------------------------------*/
101static int
102usb2_probe(device_t dev)
103{
104 DPRINTF("\n");
105 return (0);
106}
107
108/*------------------------------------------------------------------------*
109 * usb2_attach
110 *------------------------------------------------------------------------*/
111static int
112usb2_attach(device_t dev)
113{
114 struct usb2_bus *bus = device_get_ivars(dev);
115
116 DPRINTF("\n");
117
118 if (bus == NULL) {
119 DPRINTFN(0, "USB device has no ivars\n");
120 return (ENXIO);
121 }
122 if (usb2_post_init_called) {
123 mtx_lock(&Giant);
124 usb2_attach_sub(dev, bus);
125 mtx_unlock(&Giant);
126 usb2_needs_explore(bus, 1);
127 }
128 return (0); /* return success */
129}
130
131/*------------------------------------------------------------------------*
132 * usb2_detach
133 *------------------------------------------------------------------------*/
134static int
135usb2_detach(device_t dev)
136{
137 struct usb2_bus *bus = device_get_softc(dev);
138
139 DPRINTF("\n");
140
141 if (bus == NULL) {
142 /* was never setup properly */
143 return (0);
144 }
145 /* Let the USB explore process detach all devices. */
146
147 mtx_lock(&bus->mtx);
147 USB_BUS_LOCK(bus);
148 if (usb2_proc_msignal(&bus->explore_proc,
149 &bus->detach_msg[0], &bus->detach_msg[1])) {
150 /* ignore */
151 }
152 /* Wait for detach to complete */
153
154 usb2_proc_mwait(&bus->explore_proc,
155 &bus->detach_msg[0], &bus->detach_msg[1]);
156
148 if (usb2_proc_msignal(&bus->explore_proc,
149 &bus->detach_msg[0], &bus->detach_msg[1])) {
150 /* ignore */
151 }
152 /* Wait for detach to complete */
153
154 usb2_proc_mwait(&bus->explore_proc,
155 &bus->detach_msg[0], &bus->detach_msg[1]);
156
157 mtx_unlock(&bus->mtx);
157 USB_BUS_UNLOCK(bus);
158
159 /* Get rid of USB explore process */
160
161 usb2_proc_unsetup(&bus->explore_proc);
162
163 return (0);
164}
165
166/*------------------------------------------------------------------------*
167 * usb2_bus_explore
168 *
169 * This function is used to explore the device tree from the root.
170 *------------------------------------------------------------------------*/
171static void
172usb2_bus_explore(struct usb2_proc_msg *pm)
173{
174 struct usb2_bus *bus;
175 struct usb2_device *udev;
176
177 bus = ((struct usb2_bus_msg *)pm)->bus;
178 udev = bus->devices[USB_ROOT_HUB_ADDR];
179
180 if (udev && udev->hub) {
181
182 if (bus->do_probe) {
183 bus->do_probe = 0;
184 bus->driver_added_refcount++;
185 }
186 if (bus->driver_added_refcount == 0) {
187 /* avoid zero, hence that is memory default */
188 bus->driver_added_refcount = 1;
189 }
158
159 /* Get rid of USB explore process */
160
161 usb2_proc_unsetup(&bus->explore_proc);
162
163 return (0);
164}
165
166/*------------------------------------------------------------------------*
167 * usb2_bus_explore
168 *
169 * This function is used to explore the device tree from the root.
170 *------------------------------------------------------------------------*/
171static void
172usb2_bus_explore(struct usb2_proc_msg *pm)
173{
174 struct usb2_bus *bus;
175 struct usb2_device *udev;
176
177 bus = ((struct usb2_bus_msg *)pm)->bus;
178 udev = bus->devices[USB_ROOT_HUB_ADDR];
179
180 if (udev && udev->hub) {
181
182 if (bus->do_probe) {
183 bus->do_probe = 0;
184 bus->driver_added_refcount++;
185 }
186 if (bus->driver_added_refcount == 0) {
187 /* avoid zero, hence that is memory default */
188 bus->driver_added_refcount = 1;
189 }
190 mtx_unlock(&bus->mtx);
190 USB_BUS_UNLOCK(bus);
191
192 mtx_lock(&Giant);
193
194 /*
195 * Explore the Root USB HUB. This call can sleep,
196 * exiting Giant, which is actually Giant.
197 */
198 (udev->hub->explore) (udev);
199
200 mtx_unlock(&Giant);
201
191
192 mtx_lock(&Giant);
193
194 /*
195 * Explore the Root USB HUB. This call can sleep,
196 * exiting Giant, which is actually Giant.
197 */
198 (udev->hub->explore) (udev);
199
200 mtx_unlock(&Giant);
201
202 mtx_lock(&bus->mtx);
202 USB_BUS_LOCK(bus);
203 }
204 return;
205}
206
207/*------------------------------------------------------------------------*
208 * usb2_bus_detach
209 *
210 * This function is used to detach the device tree from the root.
211 *------------------------------------------------------------------------*/
212static void
213usb2_bus_detach(struct usb2_proc_msg *pm)
214{
215 struct usb2_bus *bus;
216 struct usb2_device *udev;
217 device_t dev;
218
219 bus = ((struct usb2_bus_msg *)pm)->bus;
220 udev = bus->devices[USB_ROOT_HUB_ADDR];
221 dev = bus->bdev;
222 /* clear the softc */
223 device_set_softc(dev, NULL);
203 }
204 return;
205}
206
207/*------------------------------------------------------------------------*
208 * usb2_bus_detach
209 *
210 * This function is used to detach the device tree from the root.
211 *------------------------------------------------------------------------*/
212static void
213usb2_bus_detach(struct usb2_proc_msg *pm)
214{
215 struct usb2_bus *bus;
216 struct usb2_device *udev;
217 device_t dev;
218
219 bus = ((struct usb2_bus_msg *)pm)->bus;
220 udev = bus->devices[USB_ROOT_HUB_ADDR];
221 dev = bus->bdev;
222 /* clear the softc */
223 device_set_softc(dev, NULL);
224 mtx_unlock(&bus->mtx);
224 USB_BUS_UNLOCK(bus);
225
226 mtx_lock(&Giant);
227
228 /* detach children first */
229 bus_generic_detach(dev);
230
231 /*
232 * Free USB Root device, but not any sub-devices, hence they
233 * are freed by the caller of this function:
234 */
235 usb2_detach_device(udev, USB_IFACE_INDEX_ANY, 0);
236 usb2_free_device(udev);
237
238 mtx_unlock(&Giant);
225
226 mtx_lock(&Giant);
227
228 /* detach children first */
229 bus_generic_detach(dev);
230
231 /*
232 * Free USB Root device, but not any sub-devices, hence they
233 * are freed by the caller of this function:
234 */
235 usb2_detach_device(udev, USB_IFACE_INDEX_ANY, 0);
236 usb2_free_device(udev);
237
238 mtx_unlock(&Giant);
239 mtx_lock(&bus->mtx);
239 USB_BUS_LOCK(bus);
240 /* clear bdev variable last */
241 bus->bdev = NULL;
242 return;
243}
244
245/*------------------------------------------------------------------------*
246 * usb2_attach_sub
247 *
248 * This function is the real USB bus attach code. It is factored out,
249 * hence it can be called at two different places in time. During
250 * bootup this function is called from "usb2_post_init". During
251 * hot-plug it is called directly from the "usb2_attach()" method.
252 *------------------------------------------------------------------------*/
253static void
254usb2_attach_sub(device_t dev, struct usb2_bus *bus)
255{
256 struct usb2_device *child;
257 usb2_error_t err;
258 uint8_t speed;
259
260 DPRINTF("\n");
261
262 mtx_assert(&Giant, MA_OWNED);
263
264 switch (bus->usbrev) {
265 case USB_REV_1_0:
266 speed = USB_SPEED_FULL;
267 device_printf(bus->bdev, "12Mbps Full Speed USB v1.0\n");
268 break;
269
270 case USB_REV_1_1:
271 speed = USB_SPEED_FULL;
272 device_printf(bus->bdev, "12Mbps Full Speed USB v1.1\n");
273 break;
274
275 case USB_REV_2_0:
276 speed = USB_SPEED_HIGH;
277 device_printf(bus->bdev, "480Mbps High Speed USB v2.0\n");
278 break;
279
280 case USB_REV_2_5:
281 speed = USB_SPEED_VARIABLE;
282 device_printf(bus->bdev, "480Mbps Wireless USB v2.5\n");
283 break;
284
285 default:
286 device_printf(bus->bdev, "Unsupported USB revision!\n");
287 return;
288 }
289
290 /* Allocate the Root USB device */
291
292 child = usb2_alloc_device(bus->bdev, bus, NULL, 0, 0, 1,
293 speed, USB_MODE_HOST);
294 if (child) {
295 err = usb2_probe_and_attach(child,
296 USB_IFACE_INDEX_ANY);
297 if (!err) {
298 if (!bus->devices[USB_ROOT_HUB_ADDR]->hub) {
299 err = USB_ERR_NO_ROOT_HUB;
300 }
301 }
302 } else {
303 err = USB_ERR_NOMEM;
304 }
305
306 if (err) {
307 device_printf(bus->bdev, "Root HUB problem, error=%s\n",
308 usb2_errstr(err));
309 }
310 /* Initialise USB process messages */
311 bus->explore_msg[0].hdr.pm_callback = &usb2_bus_explore;
312 bus->explore_msg[0].bus = bus;
313 bus->explore_msg[1].hdr.pm_callback = &usb2_bus_explore;
314 bus->explore_msg[1].bus = bus;
315
316 bus->detach_msg[0].hdr.pm_callback = &usb2_bus_detach;
317 bus->detach_msg[0].bus = bus;
318 bus->detach_msg[1].hdr.pm_callback = &usb2_bus_detach;
319 bus->detach_msg[1].bus = bus;
320
321 /* Create a new USB process */
322 if (usb2_proc_setup(&bus->explore_proc,
240 /* clear bdev variable last */
241 bus->bdev = NULL;
242 return;
243}
244
245/*------------------------------------------------------------------------*
246 * usb2_attach_sub
247 *
248 * This function is the real USB bus attach code. It is factored out,
249 * hence it can be called at two different places in time. During
250 * bootup this function is called from "usb2_post_init". During
251 * hot-plug it is called directly from the "usb2_attach()" method.
252 *------------------------------------------------------------------------*/
253static void
254usb2_attach_sub(device_t dev, struct usb2_bus *bus)
255{
256 struct usb2_device *child;
257 usb2_error_t err;
258 uint8_t speed;
259
260 DPRINTF("\n");
261
262 mtx_assert(&Giant, MA_OWNED);
263
264 switch (bus->usbrev) {
265 case USB_REV_1_0:
266 speed = USB_SPEED_FULL;
267 device_printf(bus->bdev, "12Mbps Full Speed USB v1.0\n");
268 break;
269
270 case USB_REV_1_1:
271 speed = USB_SPEED_FULL;
272 device_printf(bus->bdev, "12Mbps Full Speed USB v1.1\n");
273 break;
274
275 case USB_REV_2_0:
276 speed = USB_SPEED_HIGH;
277 device_printf(bus->bdev, "480Mbps High Speed USB v2.0\n");
278 break;
279
280 case USB_REV_2_5:
281 speed = USB_SPEED_VARIABLE;
282 device_printf(bus->bdev, "480Mbps Wireless USB v2.5\n");
283 break;
284
285 default:
286 device_printf(bus->bdev, "Unsupported USB revision!\n");
287 return;
288 }
289
290 /* Allocate the Root USB device */
291
292 child = usb2_alloc_device(bus->bdev, bus, NULL, 0, 0, 1,
293 speed, USB_MODE_HOST);
294 if (child) {
295 err = usb2_probe_and_attach(child,
296 USB_IFACE_INDEX_ANY);
297 if (!err) {
298 if (!bus->devices[USB_ROOT_HUB_ADDR]->hub) {
299 err = USB_ERR_NO_ROOT_HUB;
300 }
301 }
302 } else {
303 err = USB_ERR_NOMEM;
304 }
305
306 if (err) {
307 device_printf(bus->bdev, "Root HUB problem, error=%s\n",
308 usb2_errstr(err));
309 }
310 /* Initialise USB process messages */
311 bus->explore_msg[0].hdr.pm_callback = &usb2_bus_explore;
312 bus->explore_msg[0].bus = bus;
313 bus->explore_msg[1].hdr.pm_callback = &usb2_bus_explore;
314 bus->explore_msg[1].bus = bus;
315
316 bus->detach_msg[0].hdr.pm_callback = &usb2_bus_detach;
317 bus->detach_msg[0].bus = bus;
318 bus->detach_msg[1].hdr.pm_callback = &usb2_bus_detach;
319 bus->detach_msg[1].bus = bus;
320
321 /* Create a new USB process */
322 if (usb2_proc_setup(&bus->explore_proc,
323 &bus->mtx, USB_PRI_MED)) {
323 &bus->bus_mtx, USB_PRI_MED)) {
324 printf("WARNING: Creation of USB explore process failed.\n");
325 }
326 /* set softc - we are ready */
327 device_set_softc(dev, bus);
328 return;
329}
330
331/*------------------------------------------------------------------------*
332 * usb2_post_init
333 *
334 * This function is called to attach all USB busses that were found
335 * during bootup.
336 *------------------------------------------------------------------------*/
337static void
338usb2_post_init(void *arg)
339{
340 struct usb2_bus *bus;
341 devclass_t dc;
342 device_t dev;
343 int max;
344 int n;
345
346 mtx_lock(&Giant);
347
348 usb2_devclass_ptr = devclass_find("usbus");
349
350 dc = usb2_devclass_ptr;
351 if (dc) {
352 max = devclass_get_maxunit(dc) + 1;
353 for (n = 0; n != max; n++) {
354 dev = devclass_get_device(dc, n);
355 if (dev && device_is_attached(dev)) {
356 bus = device_get_ivars(dev);
357 if (bus) {
358 mtx_lock(&Giant);
359 usb2_attach_sub(dev, bus);
360 mtx_unlock(&Giant);
361 }
362 }
363 }
364 } else {
365 DPRINTFN(0, "no devclass\n");
366 }
367 usb2_post_init_called = 1;
368
369 /* explore all USB busses in parallell */
370
371 usb2_needs_explore_all();
372
373 mtx_unlock(&Giant);
374
375 return;
376}
377
378SYSINIT(usb2_post_init, SI_SUB_KICK_SCHEDULER, SI_ORDER_ANY, usb2_post_init, NULL);
379SYSUNINIT(usb2_bus_unload, SI_SUB_KLD, SI_ORDER_ANY, usb2_bus_unload, NULL);
380
381/*------------------------------------------------------------------------*
382 * usb2_bus_mem_flush_all_cb
383 *------------------------------------------------------------------------*/
384static void
385usb2_bus_mem_flush_all_cb(struct usb2_bus *bus, struct usb2_page_cache *pc,
386 struct usb2_page *pg, uint32_t size, uint32_t align)
387{
388 usb2_pc_cpu_flush(pc);
389 return;
390}
391
392/*------------------------------------------------------------------------*
393 * usb2_bus_mem_flush_all - factored out code
394 *------------------------------------------------------------------------*/
395void
396usb2_bus_mem_flush_all(struct usb2_bus *bus, usb2_bus_mem_cb_t *cb)
397{
398 if (cb) {
399 cb(bus, &usb2_bus_mem_flush_all_cb);
400 }
401 return;
402}
403
404/*------------------------------------------------------------------------*
405 * usb2_bus_mem_alloc_all_cb
406 *------------------------------------------------------------------------*/
407static void
408usb2_bus_mem_alloc_all_cb(struct usb2_bus *bus, struct usb2_page_cache *pc,
409 struct usb2_page *pg, uint32_t size, uint32_t align)
410{
411 /* need to initialize the page cache */
412 pc->tag_parent = bus->dma_parent_tag;
413
414 if (usb2_pc_alloc_mem(pc, pg, size, align)) {
415 bus->alloc_failed = 1;
416 }
417 return;
418}
419
420/*------------------------------------------------------------------------*
421 * usb2_bus_mem_alloc_all - factored out code
422 *
423 * Returns:
424 * 0: Success
425 * Else: Failure
426 *------------------------------------------------------------------------*/
427uint8_t
428usb2_bus_mem_alloc_all(struct usb2_bus *bus, bus_dma_tag_t dmat,
429 usb2_bus_mem_cb_t *cb)
430{
431 bus->alloc_failed = 0;
432
433 bus->devices_max = USB_MAX_DEVICES;
434
324 printf("WARNING: Creation of USB explore process failed.\n");
325 }
326 /* set softc - we are ready */
327 device_set_softc(dev, bus);
328 return;
329}
330
331/*------------------------------------------------------------------------*
332 * usb2_post_init
333 *
334 * This function is called to attach all USB busses that were found
335 * during bootup.
336 *------------------------------------------------------------------------*/
337static void
338usb2_post_init(void *arg)
339{
340 struct usb2_bus *bus;
341 devclass_t dc;
342 device_t dev;
343 int max;
344 int n;
345
346 mtx_lock(&Giant);
347
348 usb2_devclass_ptr = devclass_find("usbus");
349
350 dc = usb2_devclass_ptr;
351 if (dc) {
352 max = devclass_get_maxunit(dc) + 1;
353 for (n = 0; n != max; n++) {
354 dev = devclass_get_device(dc, n);
355 if (dev && device_is_attached(dev)) {
356 bus = device_get_ivars(dev);
357 if (bus) {
358 mtx_lock(&Giant);
359 usb2_attach_sub(dev, bus);
360 mtx_unlock(&Giant);
361 }
362 }
363 }
364 } else {
365 DPRINTFN(0, "no devclass\n");
366 }
367 usb2_post_init_called = 1;
368
369 /* explore all USB busses in parallell */
370
371 usb2_needs_explore_all();
372
373 mtx_unlock(&Giant);
374
375 return;
376}
377
378SYSINIT(usb2_post_init, SI_SUB_KICK_SCHEDULER, SI_ORDER_ANY, usb2_post_init, NULL);
379SYSUNINIT(usb2_bus_unload, SI_SUB_KLD, SI_ORDER_ANY, usb2_bus_unload, NULL);
380
381/*------------------------------------------------------------------------*
382 * usb2_bus_mem_flush_all_cb
383 *------------------------------------------------------------------------*/
384static void
385usb2_bus_mem_flush_all_cb(struct usb2_bus *bus, struct usb2_page_cache *pc,
386 struct usb2_page *pg, uint32_t size, uint32_t align)
387{
388 usb2_pc_cpu_flush(pc);
389 return;
390}
391
392/*------------------------------------------------------------------------*
393 * usb2_bus_mem_flush_all - factored out code
394 *------------------------------------------------------------------------*/
395void
396usb2_bus_mem_flush_all(struct usb2_bus *bus, usb2_bus_mem_cb_t *cb)
397{
398 if (cb) {
399 cb(bus, &usb2_bus_mem_flush_all_cb);
400 }
401 return;
402}
403
404/*------------------------------------------------------------------------*
405 * usb2_bus_mem_alloc_all_cb
406 *------------------------------------------------------------------------*/
407static void
408usb2_bus_mem_alloc_all_cb(struct usb2_bus *bus, struct usb2_page_cache *pc,
409 struct usb2_page *pg, uint32_t size, uint32_t align)
410{
411 /* need to initialize the page cache */
412 pc->tag_parent = bus->dma_parent_tag;
413
414 if (usb2_pc_alloc_mem(pc, pg, size, align)) {
415 bus->alloc_failed = 1;
416 }
417 return;
418}
419
420/*------------------------------------------------------------------------*
421 * usb2_bus_mem_alloc_all - factored out code
422 *
423 * Returns:
424 * 0: Success
425 * Else: Failure
426 *------------------------------------------------------------------------*/
427uint8_t
428usb2_bus_mem_alloc_all(struct usb2_bus *bus, bus_dma_tag_t dmat,
429 usb2_bus_mem_cb_t *cb)
430{
431 bus->alloc_failed = 0;
432
433 bus->devices_max = USB_MAX_DEVICES;
434
435 mtx_init(&bus->mtx, "USB lock",
435 mtx_init(&bus->bus_mtx, "USB bus lock",
436 NULL, MTX_DEF | MTX_RECURSE);
437
438 TAILQ_INIT(&bus->intr_q.head);
439
440 usb2_dma_tag_setup(bus->dma_parent_tag, bus->dma_tags,
436 NULL, MTX_DEF | MTX_RECURSE);
437
438 TAILQ_INIT(&bus->intr_q.head);
439
440 usb2_dma_tag_setup(bus->dma_parent_tag, bus->dma_tags,
441 dmat, &bus->mtx, NULL, NULL, 32, USB_BUS_DMA_TAG_MAX);
441 dmat, &bus->bus_mtx, NULL, NULL, 32, USB_BUS_DMA_TAG_MAX);
442
443 if (cb) {
444 cb(bus, &usb2_bus_mem_alloc_all_cb);
445 }
446 if (bus->alloc_failed) {
447 usb2_bus_mem_free_all(bus, cb);
448 }
449 return (bus->alloc_failed);
450}
451
452/*------------------------------------------------------------------------*
453 * usb2_bus_mem_free_all_cb
454 *------------------------------------------------------------------------*/
455static void
456usb2_bus_mem_free_all_cb(struct usb2_bus *bus, struct usb2_page_cache *pc,
457 struct usb2_page *pg, uint32_t size, uint32_t align)
458{
459 usb2_pc_free_mem(pc);
460 return;
461}
462
463/*------------------------------------------------------------------------*
464 * usb2_bus_mem_free_all - factored out code
465 *------------------------------------------------------------------------*/
466void
467usb2_bus_mem_free_all(struct usb2_bus *bus, usb2_bus_mem_cb_t *cb)
468{
469 if (cb) {
470 cb(bus, &usb2_bus_mem_free_all_cb);
471 }
472 usb2_dma_tag_unsetup(bus->dma_parent_tag);
473
442
443 if (cb) {
444 cb(bus, &usb2_bus_mem_alloc_all_cb);
445 }
446 if (bus->alloc_failed) {
447 usb2_bus_mem_free_all(bus, cb);
448 }
449 return (bus->alloc_failed);
450}
451
452/*------------------------------------------------------------------------*
453 * usb2_bus_mem_free_all_cb
454 *------------------------------------------------------------------------*/
455static void
456usb2_bus_mem_free_all_cb(struct usb2_bus *bus, struct usb2_page_cache *pc,
457 struct usb2_page *pg, uint32_t size, uint32_t align)
458{
459 usb2_pc_free_mem(pc);
460 return;
461}
462
463/*------------------------------------------------------------------------*
464 * usb2_bus_mem_free_all - factored out code
465 *------------------------------------------------------------------------*/
466void
467usb2_bus_mem_free_all(struct usb2_bus *bus, usb2_bus_mem_cb_t *cb)
468{
469 if (cb) {
470 cb(bus, &usb2_bus_mem_free_all_cb);
471 }
472 usb2_dma_tag_unsetup(bus->dma_parent_tag);
473
474 mtx_destroy(&bus->mtx);
474 mtx_destroy(&bus->bus_mtx);
475
476 return;
477}
475
476 return;
477}