-static int
-uhci_tx_pkt_now (struct uhci_eop_info *ue, int token, void *pkt, int sz)
-{
- struct tx_descriptor *td;
- struct uhci_dev_info *ud;
-
- ud = ue->ud;
-
- uhci_lock (ud->ui);
-
- td = uhci_acquire_td (ud->ui);
- memset (td, 0, sizeof (struct tx_descriptor));
- uhci_setup_td (td, ud->dev_addr, token, ue->eop, pkt, sz, ue->toggle,
- ud->low_speed);
- td->control.ioc = 1;
-
- uhci_stop (ud->ui);
-
- uhci_add_td_to_qh (ud->qh, td);
- td->flags = TD_FL_ASYNC | TD_FL_USED;
-
- uhci_run (ud->ui);
- uhci_unlock (ud->ui);
-
- ue->toggle ^= 1;
- return USB_HOST_ERR_NONE;
-}
-
-static int
-uhci_tx_pkt_wait (struct uhci_eop_info *ue, int token, void *pkt,
- int max_sz, int *in_sz)
-{
- enum intr_level old_lvl;
- struct tx_descriptor *td;
- struct usb_wait w;
- int err;
- struct uhci_dev_info *ud;
-
- ud = ue->ud;
-
- uhci_lock (ud->ui);
-
- td = uhci_acquire_td (ud->ui);
- memset (td, 0, sizeof (struct tx_descriptor));
-
- uhci_setup_td (td, ud->dev_addr, token, ue->eop, pkt, max_sz, ue->toggle,
- ud->low_speed);
- td->control.ioc = 1;
-
- w.td = td;
- w.ud = ud;
- sema_init (&w.sem, 0);
-
- uhci_stop (ud->ui);
-
- /* put into device's queue and add to waiting packet list */
- uhci_add_td_to_qh (ud->qh, td);
- td->flags = TD_FL_USED;
-
- list_push_back (&ud->ui->waiting, &w.peers);
-
- /* reactivate controller and wait */
- old_lvl = intr_disable ();
- uhci_run (ud->ui);
- uhci_unlock (ud->ui);
- sema_down (&w.sem);
- intr_set_level (old_lvl);
-
- if (in_sz != NULL)
- {
- if (w.td->control.actual_len == 0x7ff)
- *in_sz = 0;
- else
- *in_sz = w.td->control.actual_len + 1;
- }
-
- if (w.td->control.bitstuff)
- err = USB_HOST_ERR_BITSTUFF;
- else if (w.td->control.timeout)
- err = USB_HOST_ERR_TIMEOUT;
- else if (w.td->control.nak)
- err = USB_HOST_ERR_NAK;
- else if (w.td->control.babble)
- err = USB_HOST_ERR_BABBLE;
- else if (w.td->control.buffer_error)
- err = USB_HOST_ERR_BUFFER;
- else if (w.td->control.stalled)
- err = USB_HOST_ERR_STALL;
- else
- {
- err = USB_HOST_ERR_NONE;
- ue->toggle ^= 1;
- }
-
- uhci_release_td (ud->ui, td);
-
- return err;
-}
-
-static void
-uhci_add_td_to_qh (struct queue_head *qh, struct tx_descriptor *td)
-{
- struct frame_list_ptr *fp;
-
- ASSERT (td != NULL);
-
- td->head = &qh->qelp;
- if (qh->qelp.terminate == 1)
- {
- /* queue is empty */
- td->flp.terminate = 1;
- barrier ();
- td->flp.flp = 0;
- qh->qelp.flp = ptr_to_flp (vtop (td));
- qh->qelp.terminate = 0;
- }
- else
- {
- /* find the last element in the queue */
- fp = ptov (flp_to_ptr (qh->qelp.flp));
- ASSERT (qh->qelp.terminate == 0);
- while (!fp->terminate)
- {
- fp = ptov (flp_to_ptr (fp->flp));
- }
-
- /* set TD to terminated ptr */
- td->flp = *fp;
-
- fp->qh_select = 0;
- fp->depth_select = 0;
- fp->flp = ptr_to_flp (vtop (td));
- barrier ();
- fp->terminate = 0;
- }
-}
-