|
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,实际上就是遍历skelqh->list,
不明白为什么把skelgh->list中所有的qh->link都指向lqh->link |
|