Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

dwc_otg: fiq_split: use TTs with more granularity #344

Merged
merged 1 commit into from
Jul 30, 2013
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 13 additions & 13 deletions drivers/usb/host/dwc_otg/dwc_otg_hcd.c
Original file line number Diff line number Diff line change
Expand Up @@ -1356,6 +1356,7 @@ dwc_otg_transaction_type_e dwc_otg_hcd_select_transactions(dwc_otg_hcd_t * hcd)
{
dwc_list_link_t *qh_ptr;
dwc_otg_qh_t *qh;
dwc_otg_qtd_t *qtd;
int num_channels;
dwc_irqflags_t flags;
dwc_spinlock_t *channel_lock = hcd->channel_lock;
Expand All @@ -1379,11 +1380,18 @@ dwc_otg_transaction_type_e dwc_otg_hcd_select_transactions(dwc_otg_hcd_t * hcd)

qh = DWC_LIST_ENTRY(qh_ptr, dwc_otg_qh_t, qh_list_entry);

if(qh->do_split && dwc_otg_hcd_allocate_port(hcd, qh))
{
qh_ptr = DWC_LIST_NEXT(qh_ptr);
g_next_sched_frame = dwc_frame_num_inc(dwc_otg_hcd_get_frame_number(hcd), 1);
continue;
if(qh->do_split) {
qtd = DWC_CIRCLEQ_FIRST(&qh->qtd_list);
if(!(qh->ep_type == UE_ISOCHRONOUS &&
(qtd->isoc_split_pos == DWC_HCSPLIT_XACTPOS_MID ||
qtd->isoc_split_pos == DWC_HCSPLIT_XACTPOS_END))) {
if(dwc_otg_hcd_allocate_port(hcd, qh))
{
qh_ptr = DWC_LIST_NEXT(qh_ptr);
g_next_sched_frame = dwc_frame_num_inc(dwc_otg_hcd_get_frame_number(hcd), 1);
continue;
}
}
}

if (microframe_schedule) {
Expand Down Expand Up @@ -1451,18 +1459,10 @@ dwc_otg_transaction_type_e dwc_otg_hcd_select_transactions(dwc_otg_hcd_t * hcd)
}
}

if (qh->do_split && dwc_otg_hcd_allocate_port(hcd, qh))
{
g_next_sched_frame = dwc_frame_num_inc(dwc_otg_hcd_get_frame_number(hcd), 1);
qh_ptr = DWC_LIST_NEXT(qh_ptr);
continue;
}

if (microframe_schedule) {
DWC_SPINLOCK_IRQSAVE(channel_lock, &flags);
if (hcd->available_host_channels < 1) {
DWC_SPINUNLOCK_IRQRESTORE(channel_lock, flags);
if(qh->do_split) dwc_otg_hcd_release_port(hcd, qh);
break;
}
hcd->available_host_channels--;
Expand Down
20 changes: 16 additions & 4 deletions drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c
Original file line number Diff line number Diff line change
Expand Up @@ -1328,10 +1328,20 @@ static void release_channel(dwc_otg_hcd_t * hcd,
#ifdef FIQ_DEBUG
int endp = qtd->urb ? qtd->urb->pipe_info.ep_num : 0;
#endif
int hog_port = 0;

DWC_DEBUGPL(DBG_HCDV, " %s: channel %d, halt_status %d, xfer_len %d\n",
__func__, hc->hc_num, halt_status, hc->xfer_len);

if(fiq_split_enable && hc->do_split) {
if(!hc->ep_is_in && hc->ep_type == UE_ISOCHRONOUS) {
if(hc->xact_pos == DWC_HCSPLIT_XACTPOS_MID ||
hc->xact_pos == DWC_HCSPLIT_XACTPOS_BEGIN) {
hog_port = 1;
}
}
}

switch (halt_status) {
case DWC_OTG_HC_XFER_URB_COMPLETE:
free_qtd = 1;
Expand Down Expand Up @@ -1417,12 +1427,14 @@ static void release_channel(dwc_otg_hcd_t * hcd,
fiq_print(FIQDBG_ERR, "PRTNOTAL");
//BUG();
}

hcd->hub_port[hc->hub_addr] &= ~(1 << hc->port_addr);
if(!hog_port && (hc->ep_type == DWC_OTG_EP_TYPE_ISOC ||
hc->ep_type == DWC_OTG_EP_TYPE_INTR)) {
hcd->hub_port[hc->hub_addr] &= ~(1 << hc->port_addr);
#ifdef FIQ_DEBUG
hcd->hub_port_alloc[hc->hub_addr * 16 + hc->port_addr] = -1;
hcd->hub_port_alloc[hc->hub_addr * 16 + hc->port_addr] = -1;
#endif
fiq_print(FIQDBG_PORTHUB, "H%dP%d:RR%d", hc->hub_addr, hc->port_addr, endp);
fiq_print(FIQDBG_PORTHUB, "H%dP%d:RR%d", hc->hub_addr, hc->port_addr, endp);
}
}

/* Try to queue more transfers now that there's a free channel. */
Expand Down