LinuxÒÁµéÔ°ÂÛ̳'s Archiver

wbtxuan ·¢±íÓÚ 2007-2-9 16:55

uhci-hcd.cÖÐuhci_insert_qhº¯ÊýµÄÎÊÌâ

static void uhci_insert_qh(struct uhci_hcd *uhci, struct uhci_qh *skelqh, struct urb *urb)
{
struct urb_priv *urbp = (struct urb_priv *)urb->hcpriv;
struct urb_priv *turbp;
struct uhci_qh *lqh;

/* Grab the last QH */
lqh = list_entry(skelqh->list.prev, struct uhci_qh, list);

/* Point to the next skelqh */
urbp->qh->link = lqh->link;
wmb(); /* Ordering is important */

/*
* Patch QHs for previous endpoint's queued URBs? HC goes
* here next, not to the next skelqh it now points to.
*
* lqh --> td ... --> qh ... --> td --> qh ... --> td
* | | |
* v v v
* +<----------------+-----------------+
* v
* newqh --> td ... --> td
* |
* v
* ...
*
* The HC could see (and use!) any of these as we write them.
*/

lqh->link = cpu_to_le32(urbp->qh->dma_handle) | UHCI_PTR_QH;
if (lqh->urbp) {
list_for_each_entry(turbp, &lqh->urbp->queue_list, queue_list)
turbp->qh->link = lqh->link;
}

list_add_tail(&urbp->qh->list, &skelqh->list);
}

²»Àí½âÒÔÏ´úÂ룺
if (lqh->urbp) {
list_for_each_entry(turbp, &lqh->urbp->queue_list, queue_list)
turbp->qh->link = lqh->link;
}

ÎÒÈÏΪ£º
lqh = list_entry(skelqh->list.prev, struct uhci_qh, list);
ËùÒÔ±éÀúlqh->urbp->queue_list,ʵ¼ÊÉϾÍÊDZéÀúskelqh->list£¬
²»Ã÷°×Ϊʲô°Ñskelgh->listÖÐËùÓеÄqh->link¶¼Ö¸Ïòlqh->link

Ò³: [1]

Powered by Discuz! Archiver 6.1.0  © 2001-2007 Comsenz Inc.