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}
|