USB2 patches
Hans Petter Selasky
hselasky at c2i.net
Sun Feb 1 10:58:43 PST 2009
Hi Andrew,
Regarding using taskqueues.
Yes - USB2 can use taskqueues, but I would very much like to have the original
queueing mechanism intact.
How about:
struct task *
tasqueue_enqueue_pair(struct taskqueue *queue, struct task *t0, struct task
*t1);
Which does something similar to this:
void *
usb2_proc_msignal(struct usb2_process *up, void *_pm0, void *_pm1)
{
struct usb2_proc_msg *pm0 = _pm0;
struct usb2_proc_msg *pm1 = _pm1;
struct usb2_proc_msg *pm2;
uint32_t d;
uint8_t t;
mtx_assert(up->up_mtx, MA_OWNED);
t = 0;
if (pm0->pm_qentry.tqe_prev) {
t |= 1;
}
if (pm1->pm_qentry.tqe_prev) {
t |= 2;
}
if (t == 0) {
/*
* No entries are queued. Queue "pm0" and use the existing
* message number.
*/
pm2 = pm0;
} else if (t == 1) {
/* Check if we need to increment the message number. */
if (pm0->pm_num == up->up_msg_num) {
up->up_msg_num++;
}
pm2 = pm1;
} else if (t == 2) {
/* Check if we need to increment the message number. */
if (pm1->pm_num == up->up_msg_num) {
up->up_msg_num++;
}
pm2 = pm0;
} else if (t == 3) {
/*
* Both entries are queued. Re-queue the entry closest to
* the end.
*/
d = (pm1->pm_num - pm0->pm_num);
/* Check sign after subtraction */
if (d & 0x80000000) {
pm2 = pm0;
} else {
pm2 = pm1;
}
TAILQ_REMOVE(&up->up_qhead, pm2, pm_qentry);
} else {
pm2 = NULL; /* panic - should not happen */
}
DPRINTF(" t=%u, num=%u\n", t, up->up_msg_num);
/* Put message last on queue */
pm2->pm_num = up->up_msg_num;
TAILQ_INSERT_TAIL(&up->up_qhead, pm2, pm_qentry);
/* Check if we need to wakeup the USB process. */
if (up->up_msleep) {
up->up_msleep = 0; /* save "cv_signal()" calls */
usb2_cv_signal(&up->up_cv);
}
return (pm2);
}
--HPS
More information about the freebsd-usb
mailing list