PERFORCE change 131257 for review
Hans Petter Selasky
hselasky at FreeBSD.org
Wed Dec 19 13:56:35 PST 2007
http://perforce.freebsd.org/chv.cgi?CH=131257
Change 131257 by hselasky at hselasky_laptop001 on 2007/12/19 21:55:33
Switch over to using kthread instead of SWI's.
I caught several panics when using "intr_event_destroy".
Suggested by "John Baldwin".
Affected files ...
.. //depot/projects/usb/src/sys/dev/usb/usb_subr.h#81 edit
.. //depot/projects/usb/src/sys/dev/usb/usb_transfer.c#80 edit
Differences ...
==== //depot/projects/usb/src/sys/dev/usb/usb_subr.h#81 (text+ko) ====
@@ -632,8 +632,7 @@
LIST_HEAD(, usbd_xfer) dma_head;
LIST_HEAD(, usbd_xfer) done_head;
- struct intr_event *done_event; /* software interrupt event */
- void *done_cookie; /* software interrupt thread cookie */
+ struct proc *done_thread;
void *memory_base;
struct mtx *priv_mtx;
struct mtx *usb_mtx;
@@ -659,6 +658,7 @@
* called */
uint8_t dma_tag_max;
+ uint8_t done_sleep; /* set if done thread is sleeping */
};
struct usbd_mbuf {
==== //depot/projects/usb/src/sys/dev/usb/usb_transfer.c#80 (text+ko) ====
@@ -43,8 +43,8 @@
#include <sys/kernel.h>
#include <sys/lock.h>
#include <sys/malloc.h>
-#include <sys/bus.h>
-#include <sys/interrupt.h>
+#include <sys/kthread.h>
+#include <sys/unistd.h>
#include <dev/usb/usb_port.h>
#include <dev/usb/usb.h>
@@ -55,15 +55,16 @@
static void usbd_pipe_enter_wrapper(struct usbd_xfer *xfer);
static void usbd_compute_max_frame_size(struct usbd_xfer *xfer);
-static void usbd_drop_refcount(struct usbd_memory_info *info, uint8_t dropcount);
static uint8_t usbd_start_hardware_sub(struct usbd_xfer *xfer);
static void usbd_premature_callback(struct usbd_xfer *xfer, usbd_status_t error);
static void usbd_delayed_transfer_start(void *arg);
static void usbd_bdma_work_loop(struct usbd_memory_info *info);
static void usbd_bdma_cancel_event(struct usbd_xfer *xfer);
static usbd_status_t usbd_handle_request(struct usbd_xfer *xfer);
-static driver_intr_t usbd_callback_intr_td;
+static void usbd_callback_intr_td(void *arg);
static void usbd_transfer_unsetup_sub(struct usbd_memory_info *info);
+static void usbd_callback_intr_sched(struct usbd_memory_info *info);
+
#ifdef USB_DEBUG
void
@@ -835,12 +836,10 @@
LIST_INIT(&(info->done_head));
- /* create our interrupt thread */
- if (swi_add(&(info->done_event), "usbcb",
- &usbd_callback_intr_td, info, SWI_CAMBIO,
- INTR_MPSAFE, &(info->done_cookie))) {
- info->done_cookie = NULL;
- info->done_event = NULL;
+ if (usb_thread_create
+ (&usbd_callback_intr_td, info,
+ &(info->done_thread), "USB interrupt thread")) {
+ info->done_thread = NULL;
parm.err = USBD_NO_INTR_THREAD;
goto done;
}
@@ -1018,23 +1017,6 @@
}
/*------------------------------------------------------------------------*
- * usbd_drop_refcount
- *
- * This function is called from various places, and its job is to
- * wakeup "usbd_transfer_unsetup", when is safe to free the memory.
- *------------------------------------------------------------------------*/
-static void
-usbd_drop_refcount(struct usbd_memory_info *info, uint8_t dropcount)
-{
- mtx_assert(info->usb_mtx, MA_OWNED);
-
- if ((info->memory_refcount -= dropcount) == 0) {
- wakeup(info);
- }
- return;
-}
-
-/*------------------------------------------------------------------------*
* usbd_dma_delay
*
* The following function is called when we need to
@@ -1075,16 +1057,16 @@
usbd_transfer_unsetup_sub(struct usbd_memory_info *info)
{
struct usbd_page_cache *pc;
- int error;
+
+ /* wait for interrupt thread to exit */
+
+ while (info->done_thread) {
- /*
- * wait for any USB callbacks to
- * return
- */
+ usbd_callback_intr_sched(info);
- while (info->memory_refcount > 0) {
- error = mtx_sleep(info, info->usb_mtx, 0,
- "usbdwait", 0);
+ if (mtx_sleep(&(info->done_thread), info->usb_mtx,
+ 0, "usbdwait", 0)) {
+ }
}
mtx_unlock(info->usb_mtx);
@@ -1110,11 +1092,6 @@
usbd_dma_tag_unsetup(info->dma_tag_p,
info->dma_tag_max);
- /* teardown the interrupt thread, if any */
- if (info->done_cookie) {
- swi_remove(info->done_cookie);
- intr_event_destroy(info->done_event);
- }
/*
* free the "memory_base" last,
* hence the "info" structure is
@@ -2116,6 +2093,18 @@
return;
}
+static void
+usbd_callback_intr_sched(struct usbd_memory_info *info)
+{
+ mtx_assert(info->usb_mtx, MA_OWNED);
+
+ if (info->done_sleep) {
+ info->done_sleep = 0;
+ wakeup(info);
+ }
+ return;
+}
+
/*------------------------------------------------------------------------*
* usbd_callback_intr_td
*
@@ -2190,12 +2179,23 @@
mtx_unlock(info->priv_mtx);
mtx_lock(info->usb_mtx);
- usbd_drop_refcount(info, dropcount);
+ info->memory_refcount -= dropcount;
goto repeat;
} else {
- mtx_unlock(info->usb_mtx);
+ if (info->memory_refcount != 0) {
+ info->done_sleep = 1;
+ if (mtx_sleep(info, info->usb_mtx, 0, "usbdone", 0)) {
+ /* should not happen */
+ }
+ goto repeat;
+ }
}
+
+ wakeup(&(info->done_thread));
+ info->done_thread = NULL;
+ mtx_unlock(info->usb_mtx);
+ usb_thread_exit(0);
return;
}
@@ -2313,7 +2313,7 @@
info->memory_refcount++;
LIST_INSERT_HEAD(&(info->done_head), xfer, done_list);
- swi_sched(info->done_cookie, 0);
+ usbd_callback_intr_sched(info);
}
return;
} else {
More information about the p4-projects
mailing list