29#ifdef USB_GLOBAL_INCLUDE_FILE
30#include USB_GLOBAL_INCLUDE_FILE
34#include <sys/stdint.h>
35#include <sys/stddef.h>
40#include <sys/kernel.h>
42#include <sys/module.h>
45#include <sys/condvar.h>
46#include <sys/sysctl.h>
48#include <sys/unistd.h>
49#include <sys/callout.h>
50#include <sys/malloc.h>
56#define USB_DEBUG_VAR usb_ctrl_debug
87static int usb_ctrl_debug = 0;
89static SYSCTL_NODE(_hw_usb, OID_AUTO,
ctrl, CTLFLAG_RW | CTLFLAG_MPSAFE, 0,
91SYSCTL_INT(_hw_usb_ctrl, OID_AUTO,
debug, CTLFLAG_RWTUN, &usb_ctrl_debug, 0,
95#if USB_HAVE_ROOT_MOUNT_HOLD
96static int usb_no_boot_wait = 0;
97SYSCTL_INT(_hw_usb, OID_AUTO, no_boot_wait, CTLFLAG_RDTUN, &usb_no_boot_wait, 0,
98 "No USB device enumerate waiting at boot.");
106SYSCTL_INT(_hw_usb, OID_AUTO, no_shutdown_wait, CTLFLAG_RWTUN,
155#if USB_HAVE_ROOT_MOUNT_HOLD
157usb_root_mount_rel(
struct usb_bus *bus)
159 if (
bus->bus_roothold != NULL) {
160 DPRINTF(
"Releasing root mount hold %p\n",
bus->bus_roothold);
161 root_mount_rel(
bus->bus_roothold);
162 bus->bus_roothold = NULL;
178 device_printf(
dev,
"USB device has no ivars\n");
182#if USB_HAVE_ROOT_MOUNT_HOLD
183 if (usb_no_boot_wait == 0) {
185 bus->bus_roothold = root_mount_hold(device_get_nameunit(
dev));
210#if USB_HAVE_ROOT_MOUNT_HOLD
212 usb_root_mount_rel(
bus);
219 &
bus->detach_msg[0], &
bus->detach_msg[1]);
223 &
bus->detach_msg[0], &
bus->detach_msg[1]);
228 &
bus->cleanup_msg[0], &
bus->cleanup_msg[1]);
232#if USB_HAVE_PER_BUS_PROCESS
271 &
bus->suspend_msg[0], &
bus->suspend_msg[1]);
275 &
bus->suspend_msg[0], &
bus->suspend_msg[1]);
299 &
bus->resume_msg[0], &
bus->resume_msg[1]);
315 if (
bus->reset_msg[0].hdr.pm_qentry.tqe_prev != NULL ||
316 bus->reset_msg[1].hdr.pm_qentry.tqe_prev != NULL) {
317 DPRINTF(
"Reset already pending\n");
321 device_printf(
bus->parent,
"Resetting controller\n");
324 &
bus->reset_msg[0], &
bus->reset_msg[1]);
342 DPRINTF(
"%s: Controller shutdown\n", device_get_nameunit(
bus->bdev));
346 &
bus->shutdown_msg[0], &
bus->shutdown_msg[1]);
350 &
bus->shutdown_msg[0], &
bus->shutdown_msg[1]);
354 DPRINTF(
"%s: Controller shutdown complete\n",
355 device_get_nameunit(
bus->bdev));
383 if (udev != NULL && udev->
hub != NULL) {
416#if USB_HAVE_ROOT_MOUNT_HOLD
417 usb_root_mount_rel(
bus);
437 device_set_softc(
dev, NULL);
442 bus_generic_detach(
dev);
473 if (udev == NULL ||
bus->
bdev == NULL)
487 bus_generic_shutdown(
bus->
bdev);
493 device_printf(
bus->
bdev,
"Could not unconfigure root HUB\n");
530 if (udev == NULL ||
bus->
bdev == NULL)
537 DEVMETHOD(usb_take_controller, NULL);
539 USB_TAKE_CONTROLLER(device_get_parent(
bus->
bdev));
560 device_printf(
bus->
bdev,
"Could not configure root HUB\n");
565 device_printf(
bus->
bdev,
"Could not probe and "
566 "attach root HUB\n");
613 if (udev == NULL ||
bus->
bdev == NULL)
618 bus_generic_shutdown(
bus->
bdev);
624 device_printf(
bus->
bdev,
"Could not unconfigure root HUB\n");
657 while ((pd = LIST_FIRST(&
bus->pd_cleanup_list)) != NULL) {
658 LIST_REMOVE(pd, pd_next);
661 usb_destroy_dev_sync(pd);
717 device_printf(
bus->
bdev,
"12Mbps Full Speed USB v1.0\n");
722 device_printf(
bus->
bdev,
"12Mbps Full Speed USB v1.1\n");
727 device_printf(
bus->
bdev,
"480Mbps High Speed USB v2.0\n");
732 device_printf(
bus->
bdev,
"480Mbps Wireless USB v2.5\n");
737 device_printf(
bus->
bdev,
"5.0Gbps Super Speed USB v3.0\n");
741 device_printf(
bus->
bdev,
"Unsupported USB revision\n");
742#if USB_HAVE_ROOT_MOUNT_HOLD
743 usb_root_mount_rel(
bus);
784 device_printf(
bus->
bdev,
"Root HUB problem, error=%s\n",
786#if USB_HAVE_ROOT_MOUNT_HOLD
787 usb_root_mount_rel(
bus);
792 device_set_softc(
dev,
bus);
851 LIST_INIT(&
bus->pd_cleanup_list);
852 bus->cleanup_msg[0].hdr.pm_callback = &usb_bus_cleanup;
853 bus->cleanup_msg[0].bus =
bus;
854 bus->cleanup_msg[1].hdr.pm_callback = &usb_bus_cleanup;
855 bus->cleanup_msg[1].bus =
bus;
858#if USB_HAVE_PER_BUS_PROCESS
863 device_printf(
dev,
"WARNING: Creation of USB Giant "
864 "callback process failed.\n");
867 device_printf(
dev,
"WARNING: Creation of USB non-Giant ISOC "
868 "callback process failed.\n");
871 device_printf(
dev,
"WARNING: Creation of USB non-Giant BULK "
872 "callback process failed.\n");
875 device_printf(
dev,
"WARNING: Creation of USB explore "
876 "process failed.\n");
879 device_printf(
dev,
"WARNING: Creation of USB control transfer "
880 "process failed.\n");
916 cb(
bus, &usb_bus_mem_flush_all_cb);
952 "usb_def_mtx", MTX_DEF | MTX_RECURSE);
955 "usb_spin_mtx", MTX_SPIN | MTX_RECURSE);
969 DPRINTFN(0,
"Devices field has not been "
970 "initialised properly\n");
975 cb(
bus, &usb_bus_mem_alloc_all_cb);
1004 cb(
bus, &usb_bus_mem_free_all_cb);
static SYSCTL_NODE(_hw_usb, OID_AUTO, dwc_otg, CTLFLAG_RW|CTLFLAG_MPSAFE, 0, "USB DWC OTG")
void(* set_hw_power)(struct usb_bus *)
void(* set_hw_power_sleep)(struct usb_bus *, uint32_t)
struct usb_bus_msg shutdown_msg[2]
struct usb_bus_msg suspend_msg[2]
struct usb_bus_msg resume_msg[2]
struct usb_callout power_wdog
uint8_t driver_added_refcount
struct usb_bus_msg reset_msg[2]
usb_power_mask_t hw_power_state
const struct usb_bus_methods * methods
struct usb_device ** devices
struct usb_bus_msg explore_msg[2]
struct usb_bus_msg attach_msg[2]
struct usb_bus_msg detach_msg[2]
struct usb_xfer_queue intr_q
usb_error_t(* explore)(struct usb_device *hub)
struct usb_dma_parent_tag * tag_parent
usb_proc_callback_t * pm_callback
#define USB_UNCONFIG_INDEX
#define USB_ROOT_HUB_ADDR
#define USB_IFACE_INDEX_ANY
void usb_pc_free_mem(struct usb_page_cache *pc)
void usb_dma_tag_setup(struct usb_dma_parent_tag *udpt, struct usb_dma_tag *udt, bus_dma_tag_t dmat, struct mtx *mtx, usb_dma_callback_t *func, uint8_t ndmabits, uint8_t nudt)
void usb_dma_tag_unsetup(struct usb_dma_parent_tag *udpt)
void usb_pc_cpu_flush(struct usb_page_cache *pc)
uint8_t usb_pc_alloc_mem(struct usb_page_cache *pc, struct usb_page *pg, usb_size_t size, usb_size_t align)
static int usb_no_shutdown_wait
static device_shutdown_t usb_shutdown
void usb_bus_mem_free_all(struct usb_bus *bus, usb_bus_mem_cb_t *cb)
static void usb_bus_suspend(struct usb_proc_msg *pm)
static device_probe_t usb_probe
void * usb_proc_explore_msignal(struct usb_device *udev, void *pm1, void *pm2)
static devclass_t usb_devclass
static device_method_t usb_methods[]
SYSCTL_INT(_hw_usb, OID_AUTO, no_suspend_wait, CTLFLAG_RWTUN, &usb_no_suspend_wait, 0, "No USB device waiting at system suspend.")
static int usb_no_suspend_wait
static void usb_attach_sub(device_t, struct usb_bus *)
uint8_t usb_bus_mem_alloc_all(struct usb_bus *bus, bus_dma_tag_t dmat, usb_bus_mem_cb_t *cb)
static device_suspend_t usb_suspend
static device_resume_t usb_resume
void usb_proc_explore_mwait(struct usb_device *udev, void *pm1, void *pm2)
static device_attach_t usb_attach
static void usb_bus_reset(struct usb_proc_msg *pm)
static void usb_bus_detach(struct usb_proc_msg *pm)
static void usb_bus_shutdown(struct usb_proc_msg *pm)
void usb_proc_explore_unlock(struct usb_device *udev)
static void usb_bus_resume(struct usb_proc_msg *pm)
static void usb_bus_explore(struct usb_proc_msg *pm)
void usb_proc_explore_lock(struct usb_device *udev)
static device_detach_t usb_detach
SYSUNINIT(usb_bus_unload, SI_SUB_KLD, SI_ORDER_ANY, usb_bus_unload, NULL)
static driver_t usb_driver
DRIVER_MODULE(usbus, ohci, usb_driver, usb_devclass, 0, 0)
static void usb_power_wdog(void *arg)
static void usb_bus_attach(struct usb_proc_msg *pm)
void usb_bus_reset_async_locked(struct usb_bus *bus)
#define USB_HW_POWER_RESUME
void usb_bus_mem_flush_all(struct usb_bus *bus, usb_bus_mem_cb_t *cb)
#define USB_BUS_DMA_TAG_MAX
#define USB_HW_POWER_BULK
#define USB_HW_POWER_NON_ROOT_HUB
#define USB_HW_POWER_CONTROL
#define USB_HW_POWER_SUSPEND
void() usb_bus_mem_cb_t(struct usb_bus *bus, usb_bus_mem_sub_cb_t *scb)
#define USB_HW_POWER_SHUTDOWN
#define USB_HW_POWER_ISOC
#define USB_HW_POWER_INTERRUPT
#define USB_BUS_UNLOCK(_b)
#define USB_BUS_LOCK_ASSERT(_b, _t)
uint8_t usbd_enum_lock(struct usb_device *udev)
usb_error_t usb_probe_and_attach(struct usb_device *udev, uint8_t iface_index)
usb_error_t usbd_set_config_index(struct usb_device *udev, uint8_t index)
void usb_free_device(struct usb_device *udev, uint8_t flag)
void usbd_enum_unlock(struct usb_device *udev)
struct usb_device * usb_alloc_device(device_t parent_dev, struct usb_bus *bus, struct usb_device *parent_hub, uint8_t depth, uint8_t port_index, uint8_t port_no, enum usb_dev_speed speed, enum usb_hc_mode mode)
devclass_t usb_devclass_ptr
void usb_bus_unload(void *arg)
const char * usbd_errstr(usb_error_t err)
void usb_needs_explore(struct usb_bus *bus, uint8_t do_probe)
void uhub_explore_handle_re_enumerate(struct usb_device *child)
void usb_bus_powerd(struct usb_bus *bus)
void usb_bus_power_update(struct usb_bus *bus)
void usbpf_attach(struct usb_bus *ubus)
void usbpf_detach(struct usb_bus *ubus)
int usb_proc_create(struct usb_process *up, struct mtx *p_mtx, const char *pmesg, uint8_t prio)
void usb_proc_mwait(struct usb_process *up, void *_pm0, void *_pm1)
void * usb_proc_msignal(struct usb_process *up, void *_pm0, void *_pm1)
void usb_proc_rewakeup(struct usb_process *up)
void usb_proc_free(struct usb_process *up)
#define usb_callout_init_mtx(c, m, f)
#define usb_callout_reset(c,...)
#define usb_callout_drain(c)