PERFORCE change 103161 for review
Hans Petter Selasky
hselasky at FreeBSD.org
Fri Aug 4 11:59:01 UTC 2006
http://perforce.freebsd.org/chv.cgi?CH=103161
Change 103161 by hselasky at hselasky_mini_itx on 2006/08/04 11:58:01
Improve the config thread layer by not allowing "kthread_exit()"
calls from subroutines. When the thread is being torn down, sleep
calls and USB request calls should just return immediately and
perform no operation. To check if the config thread is gone,
there is a new function, usbd_config_td_is_gone().
Affected files ...
.. //depot/projects/usb/src/sys/dev/usb/if_ural.c#8 edit
.. //depot/projects/usb/src/sys/dev/usb/usb_subr.c#13 edit
.. //depot/projects/usb/src/sys/dev/usb/usb_subr.h#18 edit
Differences ...
==== //depot/projects/usb/src/sys/dev/usb/if_ural.c#8 (text+ko) ====
@@ -627,19 +627,24 @@
ural_cfg_do_request(struct ural_softc *sc, usb_device_request_t *req,
void *data)
{
+ u_int16_t length;
usbd_status err;
+ if (usbd_config_td_is_gone(&(sc->sc_config_td))) {
+ goto error;
+ }
+
err = usbd_do_request_flags_mtx(sc->sc_udev, &(sc->sc_mtx), req,
data, 0, NULL, 1000);
- usbd_config_td_check_gone(&(sc->sc_config_td));
-
if (err) {
- u_int16_t length = UGETW(req->wLength);
printf("%s: device request failed, err=%s "
"(ignored)\n", sc->sc_name, usbd_errstr(err));
+ error:
+ length = UGETW(req->wLength);
+
if ((req->bmRequestType & UT_READ) && length) {
bzero(data, length);
}
@@ -1962,10 +1967,12 @@
while (sc->sc_flags & (URAL_FLAG_SEND_BYTE_FRAME|
URAL_FLAG_SEND_BCN_FRAME)) {
+ if (usbd_config_td_is_gone(&(sc->sc_config_td))) {
+ break;
+ }
+
error = msleep(&(sc->sc_wakeup_bcn), &(sc->sc_mtx),
0, "ural beacon sleep", 0);
-
- usbd_config_td_check_gone(&(sc->sc_config_td));
}
}
return;
@@ -2471,7 +2478,9 @@
if (ural_cfg_bbp_read(sc, RAL_BBP_VERSION) != 0) {
break;
}
- usbd_config_td_sleep(&(sc->sc_config_td), hz/100);
+ if (usbd_config_td_sleep(&(sc->sc_config_td), hz/100)) {
+ break;
+ }
} else {
printf("%s: timeout waiting for BBP\n",
sc->sc_name);
@@ -2556,7 +2565,9 @@
(RAL_BBP_AWAKE | RAL_RF_AWAKE)) {
break;
}
- usbd_config_td_sleep(&(sc->sc_config_td), hz/100);
+ if (usbd_config_td_sleep(&(sc->sc_config_td), hz/100)) {
+ break;
+ }
} else {
printf("%s: timeout waiting for "
"BBP/RF to wakeup\n", sc->sc_name);
==== //depot/projects/usb/src/sys/dev/usb/usb_subr.c#13 (text+ko) ====
@@ -2366,7 +2366,9 @@
while(1) {
- usbd_config_td_check_gone(ctd);
+ if (ctd->flag_config_td_gone) {
+ break;
+ }
USBD_IF_DEQUEUE(&(ctd->cmd_used), m);
@@ -2396,6 +2398,8 @@
ctd->config_thread = NULL;
+ wakeup(&(ctd->wakeup_config_td_gone));
+
mtx_unlock(ctd->p_mtx);
kthread_exit(0);
@@ -2591,41 +2595,39 @@
}
/*---------------------------------------------------------------------------*
- * usbd_config_td_check_gone
+ * usbd_config_td_is_gone
*
- * NOTE: this function can only be called from the config thread
+ * Return values:
+ * 0: config thread is running
+ * else: config thread is gone
*---------------------------------------------------------------------------*/
-void
-usbd_config_td_check_gone(struct usbd_config_td *ctd)
+u_int8_t
+usbd_config_td_is_gone(struct usbd_config_td *ctd)
{
- u_int32_t level;
-
mtx_assert(ctd->p_mtx, MA_OWNED);
- if (ctd->flag_config_td_gone) {
-
- ctd->config_thread = NULL;
-
- wakeup(&(ctd->wakeup_config_td_gone));
-
- level = mtx_drop_recurse(ctd->p_mtx);
-
- mtx_unlock(ctd->p_mtx);
-
- kthread_exit(0);
- }
- return;
+ return ctd->flag_config_td_gone ? 1 : 0;
}
/*---------------------------------------------------------------------------*
* usbd_config_td_sleep
*
* NOTE: this function can only be called from the config thread
+ *
+ * Return values:
+ * 0: normal delay
+ * else: config thread is gone
*---------------------------------------------------------------------------*/
-void
+u_int8_t
usbd_config_td_sleep(struct usbd_config_td *ctd, u_int32_t timeout)
{
register int error;
+ u_int8_t is_gone = usbd_config_td_is_gone(ctd);
+ u_int32_t level;
+
+ if (is_gone) {
+ goto done;
+ }
if (timeout == 0) {
/* zero means no timeout,
@@ -2635,12 +2637,15 @@
timeout = 1;
}
+ level = mtx_drop_recurse(ctd->p_mtx);
+
error = msleep(ctd, ctd->p_mtx, 0,
"config td sleep", timeout);
- usbd_config_td_check_gone(ctd);
+ mtx_pickup_recurse(ctd->p_mtx, level);
- return;
+ done:
+ return is_gone;
}
/*---------------------------------------------------------------------------*
==== //depot/projects/usb/src/sys/dev/usb/usb_subr.h#18 (text+ko) ====
@@ -769,10 +769,10 @@
usbd_config_td_queue_command(struct usbd_config_td *ctd,
usbd_config_td_command_t *command_func,
u_int16_t command_ref);
-void
-usbd_config_td_check_gone(struct usbd_config_td *ctd);
+u_int8_t
+usbd_config_td_is_gone(struct usbd_config_td *ctd);
-void
+u_int8_t
usbd_config_td_sleep(struct usbd_config_td *ctd, u_int32_t timeout);
struct mbuf *
More information about the p4-projects
mailing list