Add defines to more easily allow a single threaded version of the FreeBSD

USB stack. This is useful for non-kernel purposes, like the loader.
This commit is contained in:
hselasky 2013-02-05 14:44:25 +00:00
parent 72c8e2de52
commit 2e6231f8eb
12 changed files with 64 additions and 96 deletions

View File

@ -60,4 +60,6 @@
#include <dev/usb/quirk/usb_quirk.h> #include <dev/usb/quirk/usb_quirk.h>
#include <dev/usb/template/usb_template.h> #include <dev/usb/template/usb_template.h>
extern struct usb_process usb_process[USB_PROC_MAX];
#endif /* _BSD_GLOBAL_H_ */ #endif /* _BSD_GLOBAL_H_ */

View File

@ -26,7 +26,8 @@
#include <bsd_global.h> #include <bsd_global.h>
static struct usb_process usb_process[USB_PROC_MAX]; struct usb_process usb_process[USB_PROC_MAX];
static device_t usb_pci_root; static device_t usb_pci_root;
/*------------------------------------------------------------------------* /*------------------------------------------------------------------------*
@ -977,41 +978,6 @@ repeat:
return (worked); return (worked);
} }
int
usb_proc_create(struct usb_process *up, struct mtx *p_mtx,
const char *pmesg, uint8_t prio)
{
#define USB_PROC_OFFSET(a,b) \
((int)(((long)&((struct usb_bus *)0)->a) - \
((long)&((struct usb_bus *)0)->b)))
/* figure out which process we are creating */
switch ((int)((long)up - (long)p_mtx)) {
case USB_PROC_OFFSET(giant_callback_proc, bus_mtx):
up->up_ptr = (void *)(usb_process + 2);
break;
case USB_PROC_OFFSET(non_giant_callback_proc, bus_mtx):
up->up_ptr = (void *)(usb_process + 2);
break;
case USB_PROC_OFFSET(explore_proc, bus_mtx):
up->up_ptr = (void *)(usb_process + 0);
break;
case USB_PROC_OFFSET(control_xfer_proc, bus_mtx):
up->up_ptr = (void *)(usb_process + 1);
break;
default:
up->up_ptr = (void *)(usb_process + 1);
break;
}
return (0); /* success */
}
void
usb_proc_free(struct usb_process *up)
{
/* NOP */
}
void * void *
usb_proc_msignal(struct usb_process *up, void *_pm0, void *_pm1) usb_proc_msignal(struct usb_process *up, void *_pm0, void *_pm1)
{ {
@ -1021,10 +987,6 @@ usb_proc_msignal(struct usb_process *up, void *_pm0, void *_pm1)
usb_size_t d; usb_size_t d;
uint8_t t; uint8_t t;
/* find the correct parent */
while (up->up_ptr != NULL)
up = (struct usb_process *)up->up_ptr;
t = 0; t = 0;
if (pm0->pm_qentry.tqe_prev) { if (pm0->pm_qentry.tqe_prev) {
@ -1104,10 +1066,6 @@ usb_proc_mwait(struct usb_process *up, void *_pm0, void *_pm1)
struct usb_proc_msg *pm0 = _pm0; struct usb_proc_msg *pm0 = _pm0;
struct usb_proc_msg *pm1 = _pm1; struct usb_proc_msg *pm1 = _pm1;
/* find the correct parent */
while (up->up_ptr != NULL)
up = (struct usb_process *)up->up_ptr;
/* Just remove the messages from the queue. */ /* Just remove the messages from the queue. */
if (pm0->pm_qentry.tqe_prev) { if (pm0->pm_qentry.tqe_prev) {
TAILQ_REMOVE(&up->up_qhead, pm0, pm_qentry); TAILQ_REMOVE(&up->up_qhead, pm0, pm_qentry);

View File

@ -40,6 +40,10 @@
#define M_USB 0 #define M_USB 0
#define M_USBDEV 0 #define M_USBDEV 0
#define USB_PROC_MAX 3 #define USB_PROC_MAX 3
#define USB_BUS_GIANT_PROC(bus) (usb_process + 2)
#define USB_BUS_NON_GIANT_PROC(bus) (usb_process + 2)
#define USB_BUS_EXPLORE_PROC(bus) (usb_process + 0)
#define USB_BUS_CONTROL_XFER_PROC(bus) (usb_process + 1)
#define SYSCTL_DECL(...) #define SYSCTL_DECL(...)
#define SYSCTL_NODE(name,...) struct { } name __used #define SYSCTL_NODE(name,...) struct { } name __used
#define SYSCTL_INT(...) #define SYSCTL_INT(...)

View File

@ -214,27 +214,29 @@ usb_detach(device_t dev)
USB_BUS_LOCK(bus); USB_BUS_LOCK(bus);
/* Queue detach job */ /* Queue detach job */
usb_proc_msignal(&bus->explore_proc, usb_proc_msignal(USB_BUS_EXPLORE_PROC(bus),
&bus->detach_msg[0], &bus->detach_msg[1]); &bus->detach_msg[0], &bus->detach_msg[1]);
/* Wait for detach to complete */ /* Wait for detach to complete */
usb_proc_mwait(&bus->explore_proc, usb_proc_mwait(USB_BUS_EXPLORE_PROC(bus),
&bus->detach_msg[0], &bus->detach_msg[1]); &bus->detach_msg[0], &bus->detach_msg[1]);
USB_BUS_UNLOCK(bus); USB_BUS_UNLOCK(bus);
#if USB_HAVE_PER_BUS_PROCESS
/* Get rid of USB callback processes */ /* Get rid of USB callback processes */
usb_proc_free(&bus->giant_callback_proc); usb_proc_free(USB_BUS_GIANT_PROC(bus));
usb_proc_free(&bus->non_giant_callback_proc); usb_proc_free(USB_BUS_NON_GIANT_PROC(bus));
/* Get rid of USB explore process */ /* Get rid of USB explore process */
usb_proc_free(&bus->explore_proc); usb_proc_free(USB_BUS_EXPLORE_PROC(bus));
/* Get rid of control transfer process */ /* Get rid of control transfer process */
usb_proc_free(&bus->control_xfer_proc); usb_proc_free(USB_BUS_CONTROL_XFER_PROC(bus));
#endif
#if USB_HAVE_PF #if USB_HAVE_PF
usbpf_detach(bus); usbpf_detach(bus);
@ -258,11 +260,11 @@ usb_suspend(device_t dev)
} }
USB_BUS_LOCK(bus); USB_BUS_LOCK(bus);
usb_proc_msignal(&bus->explore_proc, usb_proc_msignal(USB_BUS_EXPLORE_PROC(bus),
&bus->suspend_msg[0], &bus->suspend_msg[1]); &bus->suspend_msg[0], &bus->suspend_msg[1]);
if (usb_no_suspend_wait == 0) { if (usb_no_suspend_wait == 0) {
/* wait for suspend callback to be executed */ /* wait for suspend callback to be executed */
usb_proc_mwait(&bus->explore_proc, usb_proc_mwait(USB_BUS_EXPLORE_PROC(bus),
&bus->suspend_msg[0], &bus->suspend_msg[1]); &bus->suspend_msg[0], &bus->suspend_msg[1]);
} }
USB_BUS_UNLOCK(bus); USB_BUS_UNLOCK(bus);
@ -286,7 +288,7 @@ usb_resume(device_t dev)
} }
USB_BUS_LOCK(bus); USB_BUS_LOCK(bus);
usb_proc_msignal(&bus->explore_proc, usb_proc_msignal(USB_BUS_EXPLORE_PROC(bus),
&bus->resume_msg[0], &bus->resume_msg[1]); &bus->resume_msg[0], &bus->resume_msg[1]);
USB_BUS_UNLOCK(bus); USB_BUS_UNLOCK(bus);
@ -311,11 +313,11 @@ usb_shutdown(device_t dev)
device_printf(bus->bdev, "Controller shutdown\n"); device_printf(bus->bdev, "Controller shutdown\n");
USB_BUS_LOCK(bus); USB_BUS_LOCK(bus);
usb_proc_msignal(&bus->explore_proc, usb_proc_msignal(USB_BUS_EXPLORE_PROC(bus),
&bus->shutdown_msg[0], &bus->shutdown_msg[1]); &bus->shutdown_msg[0], &bus->shutdown_msg[1]);
if (usb_no_shutdown_wait == 0) { if (usb_no_shutdown_wait == 0) {
/* wait for shutdown callback to be executed */ /* wait for shutdown callback to be executed */
usb_proc_mwait(&bus->explore_proc, usb_proc_mwait(USB_BUS_EXPLORE_PROC(bus),
&bus->shutdown_msg[0], &bus->shutdown_msg[1]); &bus->shutdown_msg[0], &bus->shutdown_msg[1]);
} }
USB_BUS_UNLOCK(bus); USB_BUS_UNLOCK(bus);
@ -358,9 +360,9 @@ usb_bus_explore(struct usb_proc_msg *pm)
* The following three lines of code are only here to * The following three lines of code are only here to
* recover from DDB: * recover from DDB:
*/ */
usb_proc_rewakeup(&bus->control_xfer_proc); usb_proc_rewakeup(USB_BUS_CONTROL_XFER_PROC(bus));
usb_proc_rewakeup(&bus->giant_callback_proc); usb_proc_rewakeup(USB_BUS_GIANT_PROC(bus));
usb_proc_rewakeup(&bus->non_giant_callback_proc); usb_proc_rewakeup(USB_BUS_NON_GIANT_PROC(bus));
#endif #endif
USB_BUS_UNLOCK(bus); USB_BUS_UNLOCK(bus);
@ -585,7 +587,7 @@ usb_power_wdog(void *arg)
* The following line of code is only here to recover from * The following line of code is only here to recover from
* DDB: * DDB:
*/ */
usb_proc_rewakeup(&bus->explore_proc); /* recover from DDB */ usb_proc_rewakeup(USB_BUS_EXPLORE_PROC(bus)); /* recover from DDB */
#endif #endif
#if USB_HAVE_POWERD #if USB_HAVE_POWERD
@ -708,8 +710,6 @@ usb_bus_attach(struct usb_proc_msg *pm)
static void static void
usb_attach_sub(device_t dev, struct usb_bus *bus) usb_attach_sub(device_t dev, struct usb_bus *bus)
{ {
const char *pname = device_get_nameunit(dev);
mtx_lock(&Giant); mtx_lock(&Giant);
if (usb_devclass_ptr == NULL) if (usb_devclass_ptr == NULL)
usb_devclass_ptr = devclass_find("usbus"); usb_devclass_ptr = devclass_find("usbus");
@ -749,28 +749,31 @@ usb_attach_sub(device_t dev, struct usb_bus *bus)
bus->shutdown_msg[1].hdr.pm_callback = &usb_bus_shutdown; bus->shutdown_msg[1].hdr.pm_callback = &usb_bus_shutdown;
bus->shutdown_msg[1].bus = bus; bus->shutdown_msg[1].bus = bus;
#if USB_HAVE_PER_BUS_PROCESS
/* Create USB explore and callback processes */ /* Create USB explore and callback processes */
if (usb_proc_create(&bus->giant_callback_proc, if (usb_proc_create(USB_BUS_GIANT_PROC(bus),
&bus->bus_mtx, pname, USB_PRI_MED)) { &bus->bus_mtx, device_get_nameunit(dev), USB_PRI_MED)) {
device_printf(dev, "WARNING: Creation of USB Giant " device_printf(dev, "WARNING: Creation of USB Giant "
"callback process failed.\n"); "callback process failed.\n");
} else if (usb_proc_create(&bus->non_giant_callback_proc, } else if (usb_proc_create(USB_BUS_NON_GIANT_PROC(bus),
&bus->bus_mtx, pname, USB_PRI_HIGH)) { &bus->bus_mtx, device_get_nameunit(dev), USB_PRI_HIGH)) {
device_printf(dev, "WARNING: Creation of USB non-Giant " device_printf(dev, "WARNING: Creation of USB non-Giant "
"callback process failed.\n"); "callback process failed.\n");
} else if (usb_proc_create(&bus->explore_proc, } else if (usb_proc_create(USB_BUS_EXPLORE_PROC(bus),
&bus->bus_mtx, pname, USB_PRI_MED)) { &bus->bus_mtx, device_get_nameunit(dev), USB_PRI_MED)) {
device_printf(dev, "WARNING: Creation of USB explore " device_printf(dev, "WARNING: Creation of USB explore "
"process failed.\n"); "process failed.\n");
} else if (usb_proc_create(&bus->control_xfer_proc, } else if (usb_proc_create(USB_BUS_CONTROL_XFER_PROC(bus),
&bus->bus_mtx, pname, USB_PRI_MED)) { &bus->bus_mtx, device_get_nameunit(dev), USB_PRI_MED)) {
device_printf(dev, "WARNING: Creation of USB control transfer " device_printf(dev, "WARNING: Creation of USB control transfer "
"process failed.\n"); "process failed.\n");
} else { } else
#endif
{
/* Get final attach going */ /* Get final attach going */
USB_BUS_LOCK(bus); USB_BUS_LOCK(bus);
usb_proc_msignal(&bus->explore_proc, usb_proc_msignal(USB_BUS_EXPLORE_PROC(bus),
&bus->attach_msg[0], &bus->attach_msg[1]); &bus->attach_msg[0], &bus->attach_msg[1]);
USB_BUS_UNLOCK(bus); USB_BUS_UNLOCK(bus);
@ -778,7 +781,6 @@ usb_attach_sub(device_t dev, struct usb_bus *bus)
usb_needs_explore(bus, 1); usb_needs_explore(bus, 1);
} }
} }
SYSUNINIT(usb_bus_unload, SI_SUB_KLD, SI_ORDER_ANY, usb_bus_unload, NULL); SYSUNINIT(usb_bus_unload, SI_SUB_KLD, SI_ORDER_ANY, usb_bus_unload, NULL);
/*------------------------------------------------------------------------* /*------------------------------------------------------------------------*

View File

@ -547,19 +547,12 @@ xhci_init(struct xhci_softc *sc, device_t self)
sc->sc_config_msg[1].hdr.pm_callback = &xhci_configure_msg; sc->sc_config_msg[1].hdr.pm_callback = &xhci_configure_msg;
sc->sc_config_msg[1].bus = &sc->sc_bus; sc->sc_config_msg[1].bus = &sc->sc_bus;
if (usb_proc_create(&sc->sc_config_proc,
&sc->sc_bus.bus_mtx, device_get_nameunit(self), USB_PRI_MED)) {
printf("WARNING: Creation of XHCI configure "
"callback process failed.\n");
}
return (0); return (0);
} }
void void
xhci_uninit(struct xhci_softc *sc) xhci_uninit(struct xhci_softc *sc)
{ {
usb_proc_free(&sc->sc_config_proc);
usb_bus_mem_free_all(&sc->sc_bus, &xhci_iterate_hw_softc); usb_bus_mem_free_all(&sc->sc_bus, &xhci_iterate_hw_softc);
cv_destroy(&sc->sc_cmd_cv); cv_destroy(&sc->sc_cmd_cv);
@ -2684,7 +2677,7 @@ xhci_transfer_insert(struct usb_xfer *xfer)
DPRINTFN(8, "Not running\n"); DPRINTFN(8, "Not running\n");
/* start configuration */ /* start configuration */
(void)usb_proc_msignal(&sc->sc_config_proc, (void)usb_proc_msignal(USB_BUS_CONTROL_XFER_PROC(&sc->sc_bus),
&sc->sc_config_msg[0], &sc->sc_config_msg[1]); &sc->sc_config_msg[0], &sc->sc_config_msg[1]);
return (0); return (0);
} }
@ -3652,7 +3645,7 @@ xhci_start_dma_delay(struct usb_xfer *xfer)
/* put transfer on interrupt queue (again) */ /* put transfer on interrupt queue (again) */
usbd_transfer_enqueue(&sc->sc_bus.intr_q, xfer); usbd_transfer_enqueue(&sc->sc_bus.intr_q, xfer);
(void)usb_proc_msignal(&sc->sc_config_proc, (void)usb_proc_msignal(USB_BUS_CONTROL_XFER_PROC(&sc->sc_bus),
&sc->sc_config_msg[0], &sc->sc_config_msg[1]); &sc->sc_config_msg[0], &sc->sc_config_msg[1]);
} }

View File

@ -434,8 +434,7 @@ struct xhci_softc {
struct xhci_hw_softc sc_hw; struct xhci_hw_softc sc_hw;
/* base device */ /* base device */
struct usb_bus sc_bus; struct usb_bus sc_bus;
/* configure process */ /* configure message */
struct usb_process sc_config_proc;
struct usb_bus_msg sc_config_msg[2]; struct usb_bus_msg sc_config_msg[2];
union xhci_hub_desc sc_hub_desc; union xhci_hub_desc sc_hub_desc;

View File

@ -54,6 +54,13 @@ struct usb_bus {
#if USB_HAVE_ROOT_MOUNT_HOLD #if USB_HAVE_ROOT_MOUNT_HOLD
struct root_hold_token *bus_roothold; struct root_hold_token *bus_roothold;
#endif #endif
#if USB_HAVE_PER_BUS_PROCESS
#define USB_BUS_GIANT_PROC(bus) (&(bus)->giant_callback_proc)
#define USB_BUS_NON_GIANT_PROC(bus) (&(bus)->non_giant_callback_proc)
#define USB_BUS_EXPLORE_PROC(bus) (&(bus)->explore_proc)
#define USB_BUS_CONTROL_XFER_PROC(bus) (&(bus)->control_xfer_proc)
/* /*
* There are two callback processes. One for Giant locked * There are two callback processes. One for Giant locked
* callbacks. One for non-Giant locked callbacks. This should * callbacks. One for non-Giant locked callbacks. This should
@ -67,6 +74,7 @@ struct usb_bus {
/* Control request process */ /* Control request process */
struct usb_process control_xfer_proc; struct usb_process control_xfer_proc;
#endif
struct usb_bus_msg explore_msg[2]; struct usb_bus_msg explore_msg[2];
struct usb_bus_msg detach_msg[2]; struct usb_bus_msg detach_msg[2];

View File

@ -2128,7 +2128,7 @@ usb_free_device(struct usb_device *udev, uint8_t flag)
* anywhere: * anywhere:
*/ */
USB_BUS_LOCK(udev->bus); USB_BUS_LOCK(udev->bus);
usb_proc_mwait(&udev->bus->non_giant_callback_proc, usb_proc_mwait(USB_BUS_NON_GIANT_PROC(udev->bus),
&udev->cs_msg[0], &udev->cs_msg[1]); &udev->cs_msg[0], &udev->cs_msg[1]);
USB_BUS_UNLOCK(udev->bus); USB_BUS_UNLOCK(udev->bus);

View File

@ -44,6 +44,7 @@
#define USB_HAVE_PF 1 #define USB_HAVE_PF 1
#define USB_HAVE_ROOT_MOUNT_HOLD 1 #define USB_HAVE_ROOT_MOUNT_HOLD 1
#define USB_HAVE_ID_SECTION 1 #define USB_HAVE_ID_SECTION 1
#define USB_HAVE_PER_BUS_PROCESS 1
#define USB_TD_GET_PROC(td) (td)->td_proc #define USB_TD_GET_PROC(td) (td)->td_proc
#define USB_PROC_GET_GID(td) (td)->p_pgid #define USB_PROC_GET_GID(td) (td)->p_pgid

View File

@ -44,6 +44,7 @@
#define USB_HAVE_PF 0 #define USB_HAVE_PF 0
#define USB_HAVE_ROOT_MOUNT_HOLD 0 #define USB_HAVE_ROOT_MOUNT_HOLD 0
#define USB_HAVE_ID_SECTION 0 #define USB_HAVE_ID_SECTION 0
#define USB_HAVE_PER_BUS_PROCESS 0
#define USB_TD_GET_PROC(td) (td)->td_proc #define USB_TD_GET_PROC(td) (td)->td_proc
#define USB_PROC_GET_GID(td) (td)->p_pgid #define USB_PROC_GET_GID(td) (td)->p_pgid

View File

@ -1917,7 +1917,7 @@ usb_needs_explore(struct usb_bus *bus, uint8_t do_probe)
if (do_probe) { if (do_probe) {
bus->do_probe = 1; bus->do_probe = 1;
} }
if (usb_proc_msignal(&bus->explore_proc, if (usb_proc_msignal(USB_BUS_EXPLORE_PROC(bus),
&bus->explore_msg[0], &bus->explore_msg[1])) { &bus->explore_msg[0], &bus->explore_msg[1])) {
/* ignore */ /* ignore */
} }

View File

@ -966,13 +966,13 @@ usbd_transfer_setup(struct usb_device *udev,
*/ */
if (setup_start == usb_control_ep_cfg) if (setup_start == usb_control_ep_cfg)
info->done_p = info->done_p =
&udev->bus->control_xfer_proc; USB_BUS_CONTROL_XFER_PROC(udev->bus);
else if (xfer_mtx == &Giant) else if (xfer_mtx == &Giant)
info->done_p = info->done_p =
&udev->bus->giant_callback_proc; USB_BUS_GIANT_PROC(udev->bus);
else else
info->done_p = info->done_p =
&udev->bus->non_giant_callback_proc; USB_BUS_NON_GIANT_PROC(udev->bus);
} }
/* reset sizes */ /* reset sizes */
@ -2614,7 +2614,7 @@ usbd_pipe_start(struct usb_xfer_queue *pq)
} else if (udev->ctrl_xfer[1]) { } else if (udev->ctrl_xfer[1]) {
info = udev->ctrl_xfer[1]->xroot; info = udev->ctrl_xfer[1]->xroot;
usb_proc_msignal( usb_proc_msignal(
&info->bus->non_giant_callback_proc, USB_BUS_NON_GIANT_PROC(info->bus),
&udev->cs_msg[0], &udev->cs_msg[1]); &udev->cs_msg[0], &udev->cs_msg[1]);
} else { } else {
/* should not happen */ /* should not happen */
@ -3216,10 +3216,10 @@ usbd_transfer_poll(struct usb_xfer **ppxfer, uint16_t max)
} }
/* Make sure cv_signal() and cv_broadcast() is not called */ /* Make sure cv_signal() and cv_broadcast() is not called */
udev->bus->control_xfer_proc.up_msleep = 0; USB_BUS_CONTROL_XFER_PROC(udev->bus)->up_msleep = 0;
udev->bus->explore_proc.up_msleep = 0; USB_BUS_EXPLORE_PROC(udev->bus)->up_msleep = 0;
udev->bus->giant_callback_proc.up_msleep = 0; USB_BUS_GIANT_PROC(udev->bus)->up_msleep = 0;
udev->bus->non_giant_callback_proc.up_msleep = 0; USB_BUS_NON_GIANT_PROC(udev->bus)->up_msleep = 0;
/* poll USB hardware */ /* poll USB hardware */
(udev->bus->methods->xfer_poll) (udev->bus); (udev->bus->methods->xfer_poll) (udev->bus);