{
dwc_otg_qtd_t *qtd;
struct list_head *pos;
+
unsigned long flags;
+ local_irq_save(flags);
+
/* Free each QTD in the QTD list */
- local_irq_save (flags);
for (pos = _qh->qtd_list.next;
pos != &_qh->qtd_list;
pos = _qh->qtd_list.next)
{
list_del (pos);
qtd = dwc_list_to_qtd (pos);
+ if(qtd->urb)
+ {
+ qtd->urb->hcpriv =NULL;
+ qtd->urb->ep->hcpriv = NULL;
+ }
dwc_otg_hcd_qtd_free (qtd);
+ qtd=NULL;
}
- local_irq_restore (flags);
-
+
kfree (_qh);
+ _qh = NULL;
+ local_irq_restore(flags);
return;
}
_qh->maxp = usb_maxpacket(_urb->dev, _urb->pipe, !(usb_pipein(_urb->pipe)));
INIT_LIST_HEAD(&_qh->qtd_list);
INIT_LIST_HEAD(&_qh->qh_list_entry);
- _qh->channel = NULL;
/* FS/LS Enpoint on HS Hub
* NOT virtual root hub */
_qh->do_split = 0;
- /* yk@rk 20100625
- * _urb->dev->tt->hub may be null
- */
if (((_urb->dev->speed == USB_SPEED_LOW) ||
(_urb->dev->speed == USB_SPEED_FULL)) &&
(_urb->dev->tt) && (_urb->dev->tt->hub)&&
/** @todo Account for split transfers in the bus time. */
int bytecount = dwc_hb_mult(_qh->maxp) * dwc_max_packet(_qh->maxp);
+ /*
+ * The results from usb_calc_bus_time are in nanosecs,
+ * so divide the result by 1000 to convert to
+ * microsecs expected by this driver
+ */
_qh->usecs = usb_calc_bus_time(_urb->dev->speed,
usb_pipein(_urb->pipe),
(_qh->ep_type == USB_ENDPOINT_XFER_ISOC),
- bytecount);
+ bytecount) / 1000;
/* Start in a slightly future (micro)frame. */
_qh->sched_frame = dwc_frame_num_inc(_hcd->frame_number,
* non-periodic transactions.
*/
int status;
+#if defined(CONFIG_ARCH_RK30) || defined(CONFIG_ARCH_RK3188)
int num_channels;
num_channels = _hcd->core_if->core_params->host_channels;
_hcd->non_periodic_channels);
status = -ENOSPC;
}
-
+#else
+ status = 0;
+#endif
return status;
}
/* Always start in the inactive schedule. */
list_add_tail(&_qh->qh_list_entry, &_hcd->periodic_sched_inactive);
+ _qh->qh_state = QH_INACTIVE;
/* Reserve the periodic channel. */
_hcd->periodic_channels++;
*/
int dwc_otg_hcd_qh_add (dwc_otg_hcd_t *_hcd, dwc_otg_qh_t *_qh)
{
- //unsigned long flags;
+ unsigned long flags;
int status = 0;
- //local_irq_save(flags);
+ local_irq_save(flags);
if (!list_empty(&_qh->qh_list_entry)) {
/* QH already in a schedule. */
}
done:
- //local_irq_restore(flags);
+ local_irq_restore(flags);
return status;
}
if (!list_empty(&_qh->qtd_list)) {
/* Add back to inactive non-periodic schedule. */
dwc_otg_hcd_qh_add(_hcd, _qh);
+ return;
}
} else {
uint16_t frame_number = dwc_otg_hcd_get_frame_number(dwc_otg_hcd_to_hcd(_hcd));
* appropriate queue.
*/
if (_qh->sched_frame == frame_number) {
- list_move(&_qh->qh_list_entry,
- &_hcd->periodic_sched_ready);
+ //list_move_tail(&_qh->qh_list_entry,
+ // &_hcd->periodic_sched_ready);
+ _qh->qh_state = QH_READY;
} else {
- list_move(&_qh->qh_list_entry,
- &_hcd->periodic_sched_inactive);
+ //list_move_tail(&_qh->qh_list_entry,
+ // &_hcd->periodic_sched_inactive);
+ _qh->qh_state = QH_INACTIVE;
}
}
}
{
struct usb_host_endpoint *ep;
dwc_otg_qh_t *qh;
- //unsigned long flags;
+ unsigned long flags;
int retval = 0;
struct urb *urb = _qtd->urb;
- //local_irq_save(flags);
-
/*
* Get the QH which holds the QTD-list to insert to. Create QH if it
* doesn't exist.
}
ep->hcpriv = qh;
}
-
+ spin_lock_irqsave(&_dwc_otg_hcd->global_lock, flags);
retval = dwc_otg_hcd_qh_add(_dwc_otg_hcd, qh);
if (retval == 0) {
list_add_tail(&_qtd->qtd_list_entry, &qh->qtd_list);
}
+ spin_unlock_irqrestore(&_dwc_otg_hcd->global_lock, flags);
+
done:
- //local_irq_restore(flags);
return retval;
}