X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=drivers%2Fusb%2Fdwc_otg%2Fdwc_otg_hcd_queue.c;h=a0b9357626584c2d4af78a6a60524ea78ab42ee9;hb=70e7e8b6dd204f0ac5bb35fc6a7a938ca83d5648;hp=120080356f653d6f95972020352fbd5a8b748dff;hpb=6251d862ded47e760c464a5400433f4c285c92a0;p=firefly-linux-kernel-4.4.55.git diff --git a/drivers/usb/dwc_otg/dwc_otg_hcd_queue.c b/drivers/usb/dwc_otg/dwc_otg_hcd_queue.c index 120080356f65..a0b935762658 100755 --- a/drivers/usb/dwc_otg/dwc_otg_hcd_queue.c +++ b/drivers/usb/dwc_otg/dwc_otg_hcd_queue.c @@ -87,6 +87,10 @@ void dwc_otg_hcd_qh_free (dwc_otg_qh_t *_qh) dwc_otg_qtd_t *qtd; struct list_head *pos; + unsigned long flags; + + local_irq_save(flags); + /* Free each QTD in the QTD list */ for (pos = _qh->qtd_list.next; pos != &_qh->qtd_list; @@ -94,10 +98,18 @@ void dwc_otg_hcd_qh_free (dwc_otg_qh_t *_qh) { 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; } - + kfree (_qh); + _qh = NULL; + local_irq_restore(flags); return; } @@ -133,17 +145,11 @@ void dwc_otg_hcd_qh_init(dwc_otg_hcd_t *_hcd, dwc_otg_qh_t *_qh, struct urb *_ur _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->tt)&&(!_urb->dev->tt->hub)) - printk("%s tt->hub null!\n",__func__); if (((_urb->dev->speed == USB_SPEED_LOW) || (_urb->dev->speed == USB_SPEED_FULL)) && (_urb->dev->tt) && (_urb->dev->tt->hub)&& @@ -241,9 +247,9 @@ static int periodic_channel_available(dwc_otg_hcd_t *_hcd) * non-periodic transactions. */ int status; -/*yk@rk modified for usb host 1.1*/ -#if 0 +#if defined(CONFIG_ARCH_RK30) || defined(CONFIG_ARCH_RK3188) int num_channels; + num_channels = _hcd->core_if->core_params->host_channels; if ((_hcd->periodic_channels + _hcd->non_periodic_channels < num_channels) && (_hcd->periodic_channels < num_channels - 1)) { @@ -368,6 +374,7 @@ static int schedule_periodic(dwc_otg_hcd_t *_hcd, dwc_otg_qh_t *_qh) /* 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++; @@ -399,12 +406,10 @@ static int schedule_periodic(dwc_otg_hcd_t *_hcd, dwc_otg_qh_t *_qh) */ int dwc_otg_hcd_qh_add (dwc_otg_hcd_t *_hcd, dwc_otg_qh_t *_qh) { + unsigned long flags; int status = 0; - if (!spin_is_locked(&_hcd->global_lock)) { - //pr_err("%s don't have hcd->global_lock\n", __func__); - //BUG(); - } + local_irq_save(flags); if (!list_empty(&_qh->qh_list_entry)) { /* QH already in a schedule. */ @@ -420,7 +425,7 @@ int dwc_otg_hcd_qh_add (dwc_otg_hcd_t *_hcd, dwc_otg_qh_t *_qh) } done: - //local_irq_restore(flags); + local_irq_restore(flags); return status; } @@ -463,10 +468,9 @@ static void deschedule_periodic(dwc_otg_hcd_t *_hcd, dwc_otg_qh_t *_qh) * @param[in] _qh QH to remove from schedule. */ void dwc_otg_hcd_qh_remove (dwc_otg_hcd_t *_hcd, dwc_otg_qh_t *_qh) { - if (!spin_is_locked(&_hcd->global_lock)) { - //pr_err("%s don't have hcd->global_lock\n", __func__); - //BUG(); - } + unsigned long flags; + + local_irq_save(flags); if (list_empty(&_qh->qh_list_entry)) { /* QH is not in a schedule. */ @@ -483,7 +487,7 @@ void dwc_otg_hcd_qh_remove (dwc_otg_hcd_t *_hcd, dwc_otg_qh_t *_qh) } done: - ; + local_irq_restore(flags); } /** @@ -501,10 +505,9 @@ void dwc_otg_hcd_qh_remove (dwc_otg_hcd_t *_hcd, dwc_otg_qh_t *_qh) */ void dwc_otg_hcd_qh_deactivate(dwc_otg_hcd_t *_hcd, dwc_otg_qh_t *_qh, int sched_next_periodic_split) { - if (!spin_is_locked(&_hcd->global_lock)) { - //pr_err("%s don't have hcd->global_lock\n", __func__); - //BUG(); - } + unsigned long flags; + local_irq_save(flags); + if (dwc_qh_is_non_per(_qh)) { dwc_otg_hcd_qh_remove(_hcd, _qh); if (!list_empty(&_qh->qtd_list)) { @@ -557,16 +560,18 @@ void dwc_otg_hcd_qh_deactivate(dwc_otg_hcd_t *_hcd, dwc_otg_qh_t *_qh, int sched * 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; } } } - + local_irq_restore(flags); } /** @@ -634,13 +639,11 @@ int dwc_otg_hcd_qtd_add (dwc_otg_qtd_t *_qtd, { 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. @@ -655,14 +658,15 @@ int dwc_otg_hcd_qtd_add (dwc_otg_qtd_t *_qtd, } 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; }