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