00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #ifndef DWC_DEVICE_ONLY
00034
00035 #include "dwc_otg_hcd.h"
00036 #include "dwc_otg_regs.h"
00037
00043 int32_t dwc_otg_hcd_handle_intr(dwc_otg_hcd_t * dwc_otg_hcd)
00044 {
00045 int retval = 0;
00046
00047 dwc_otg_core_if_t *core_if = dwc_otg_hcd->core_if;
00048 gintsts_data_t gintsts;
00049 #ifdef DEBUG
00050 dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
00051 #endif
00052
00053
00054 if (core_if->hibernation_suspend == 1) {
00055 return retval;
00056 }
00057 DWC_SPINLOCK(dwc_otg_hcd->lock);
00058
00059 if (dwc_otg_is_host_mode(core_if)) {
00060 gintsts.d32 = dwc_otg_read_core_intr(core_if);
00061 if (!gintsts.d32) {
00062 DWC_SPINUNLOCK(dwc_otg_hcd->lock);
00063 return 0;
00064 }
00065 #ifdef DEBUG
00066
00067 #ifndef DEBUG_SOF
00068 if (gintsts.d32 != DWC_SOF_INTR_MASK)
00069 #endif
00070 DWC_DEBUGPL(DBG_HCD, "\n");
00071 #endif
00072
00073 #ifdef DEBUG
00074 #ifndef DEBUG_SOF
00075 if (gintsts.d32 != DWC_SOF_INTR_MASK)
00076 #endif
00077 DWC_DEBUGPL(DBG_HCD,
00078 "DWC OTG HCD Interrupt Detected gintsts&gintmsk=0x%08x\n",
00079 gintsts.d32);
00080 #endif
00081
00082 if (gintsts.b.sofintr) {
00083 retval |= dwc_otg_hcd_handle_sof_intr(dwc_otg_hcd);
00084 }
00085 if (gintsts.b.rxstsqlvl) {
00086 retval |=
00087 dwc_otg_hcd_handle_rx_status_q_level_intr
00088 (dwc_otg_hcd);
00089 }
00090 if (gintsts.b.nptxfempty) {
00091 retval |=
00092 dwc_otg_hcd_handle_np_tx_fifo_empty_intr
00093 (dwc_otg_hcd);
00094 }
00095 if (gintsts.b.i2cintr) {
00097 }
00098 if (gintsts.b.portintr) {
00099 retval |= dwc_otg_hcd_handle_port_intr(dwc_otg_hcd);
00100 }
00101 if (gintsts.b.hcintr) {
00102 retval |= dwc_otg_hcd_handle_hc_intr(dwc_otg_hcd);
00103 }
00104 if (gintsts.b.ptxfempty) {
00105 retval |=
00106 dwc_otg_hcd_handle_perio_tx_fifo_empty_intr
00107 (dwc_otg_hcd);
00108 }
00109 #ifdef DEBUG
00110 #ifndef DEBUG_SOF
00111 if (gintsts.d32 != DWC_SOF_INTR_MASK)
00112 #endif
00113 {
00114 DWC_DEBUGPL(DBG_HCD,
00115 "DWC OTG HCD Finished Servicing Interrupts\n");
00116 DWC_DEBUGPL(DBG_HCDV, "DWC OTG HCD gintsts=0x%08x\n",
00117 DWC_READ_REG32(&global_regs->gintsts));
00118 DWC_DEBUGPL(DBG_HCDV, "DWC OTG HCD gintmsk=0x%08x\n",
00119 DWC_READ_REG32(&global_regs->gintmsk));
00120 }
00121 #endif
00122
00123 #ifdef DEBUG
00124 #ifndef DEBUG_SOF
00125 if (gintsts.d32 != DWC_SOF_INTR_MASK)
00126 #endif
00127 DWC_DEBUGPL(DBG_HCD, "\n");
00128 #endif
00129
00130 }
00131 DWC_SPINUNLOCK(dwc_otg_hcd->lock);
00132 return retval;
00133 }
00134
00135 #ifdef DWC_TRACK_MISSED_SOFS
00136 #warning Compiling code to track missed SOFs
00137 #define FRAME_NUM_ARRAY_SIZE 1000
00138
00141 static inline void track_missed_sofs(uint16_t curr_frame_number)
00142 {
00143 static uint16_t frame_num_array[FRAME_NUM_ARRAY_SIZE];
00144 static uint16_t last_frame_num_array[FRAME_NUM_ARRAY_SIZE];
00145 static int frame_num_idx = 0;
00146 static uint16_t last_frame_num = DWC_HFNUM_MAX_FRNUM;
00147 static int dumped_frame_num_array = 0;
00148
00149 if (frame_num_idx < FRAME_NUM_ARRAY_SIZE) {
00150 if (((last_frame_num + 1) & DWC_HFNUM_MAX_FRNUM) !=
00151 curr_frame_number) {
00152 frame_num_array[frame_num_idx] = curr_frame_number;
00153 last_frame_num_array[frame_num_idx++] = last_frame_num;
00154 }
00155 } else if (!dumped_frame_num_array) {
00156 int i;
00157 DWC_PRINTF("Frame Last Frame\n");
00158 DWC_PRINTF("----- ----------\n");
00159 for (i = 0; i < FRAME_NUM_ARRAY_SIZE; i++) {
00160 DWC_PRINTF("0x%04x 0x%04x\n",
00161 frame_num_array[i], last_frame_num_array[i]);
00162 }
00163 dumped_frame_num_array = 1;
00164 }
00165 last_frame_num = curr_frame_number;
00166 }
00167 #endif
00168
00175 int32_t dwc_otg_hcd_handle_sof_intr(dwc_otg_hcd_t * hcd)
00176 {
00177 hfnum_data_t hfnum;
00178 dwc_list_link_t *qh_entry;
00179 dwc_otg_qh_t *qh;
00180 dwc_otg_transaction_type_e tr_type;
00181 gintsts_data_t gintsts = {.d32 = 0 };
00182
00183 hfnum.d32 =
00184 DWC_READ_REG32(&hcd->core_if->host_if->host_global_regs->hfnum);
00185
00186 #ifdef DEBUG_SOF
00187 DWC_DEBUGPL(DBG_HCD, "--Start of Frame Interrupt--\n");
00188 #endif
00189 hcd->frame_number = hfnum.b.frnum;
00190
00191 #ifdef DEBUG
00192 hcd->frrem_accum += hfnum.b.frrem;
00193 hcd->frrem_samples++;
00194 #endif
00195
00196 #ifdef DWC_TRACK_MISSED_SOFS
00197 track_missed_sofs(hcd->frame_number);
00198 #endif
00199
00200 qh_entry = DWC_LIST_FIRST(&hcd->periodic_sched_inactive);
00201 while (qh_entry != &hcd->periodic_sched_inactive) {
00202 qh = DWC_LIST_ENTRY(qh_entry, dwc_otg_qh_t, qh_list_entry);
00203 qh_entry = qh_entry->next;
00204 if (dwc_frame_num_le(qh->sched_frame, hcd->frame_number)) {
00205
00206
00207
00208
00209 DWC_LIST_MOVE_HEAD(&hcd->periodic_sched_ready,
00210 &qh->qh_list_entry);
00211 }
00212 }
00213 tr_type = dwc_otg_hcd_select_transactions(hcd);
00214 if (tr_type != DWC_OTG_TRANSACTION_NONE) {
00215 dwc_otg_hcd_queue_transactions(hcd, tr_type);
00216 }
00217
00218
00219 gintsts.b.sofintr = 1;
00220 DWC_WRITE_REG32(&hcd->core_if->core_global_regs->gintsts, gintsts.d32);
00221
00222 return 1;
00223 }
00224
00228 int32_t dwc_otg_hcd_handle_rx_status_q_level_intr(dwc_otg_hcd_t * dwc_otg_hcd)
00229 {
00230 host_grxsts_data_t grxsts;
00231 dwc_hc_t *hc = NULL;
00232
00233 DWC_DEBUGPL(DBG_HCD, "--RxStsQ Level Interrupt--\n");
00234
00235 grxsts.d32 =
00236 DWC_READ_REG32(&dwc_otg_hcd->core_if->core_global_regs->grxstsp);
00237
00238 hc = dwc_otg_hcd->hc_ptr_array[grxsts.b.chnum];
00239 if (!hc) {
00240 DWC_ERROR("Unable to get corresponding channel\n");
00241 return 0;
00242 }
00243
00244
00245 DWC_DEBUGPL(DBG_HCDV, " Ch num = %d\n", grxsts.b.chnum);
00246 DWC_DEBUGPL(DBG_HCDV, " Count = %d\n", grxsts.b.bcnt);
00247 DWC_DEBUGPL(DBG_HCDV, " DPID = %d, hc.dpid = %d\n", grxsts.b.dpid,
00248 hc->data_pid_start);
00249 DWC_DEBUGPL(DBG_HCDV, " PStatus = %d\n", grxsts.b.pktsts);
00250
00251 switch (grxsts.b.pktsts) {
00252 case DWC_GRXSTS_PKTSTS_IN:
00253
00254 if (grxsts.b.bcnt > 0) {
00255 dwc_otg_read_packet(dwc_otg_hcd->core_if,
00256 hc->xfer_buff, grxsts.b.bcnt);
00257
00258
00259 hc->xfer_count += grxsts.b.bcnt;
00260 hc->xfer_buff += grxsts.b.bcnt;
00261 }
00262
00263 case DWC_GRXSTS_PKTSTS_IN_XFER_COMP:
00264 case DWC_GRXSTS_PKTSTS_DATA_TOGGLE_ERR:
00265 case DWC_GRXSTS_PKTSTS_CH_HALTED:
00266
00267 break;
00268 default:
00269 DWC_ERROR("RX_STS_Q Interrupt: Unknown status %d\n",
00270 grxsts.b.pktsts);
00271 break;
00272 }
00273
00274 return 1;
00275 }
00276
00281 int32_t dwc_otg_hcd_handle_np_tx_fifo_empty_intr(dwc_otg_hcd_t * dwc_otg_hcd)
00282 {
00283 DWC_DEBUGPL(DBG_HCD, "--Non-Periodic TxFIFO Empty Interrupt--\n");
00284 dwc_otg_hcd_queue_transactions(dwc_otg_hcd,
00285 DWC_OTG_TRANSACTION_NON_PERIODIC);
00286 return 1;
00287 }
00288
00293 int32_t dwc_otg_hcd_handle_perio_tx_fifo_empty_intr(dwc_otg_hcd_t * dwc_otg_hcd)
00294 {
00295 DWC_DEBUGPL(DBG_HCD, "--Periodic TxFIFO Empty Interrupt--\n");
00296 dwc_otg_hcd_queue_transactions(dwc_otg_hcd,
00297 DWC_OTG_TRANSACTION_PERIODIC);
00298 return 1;
00299 }
00300
00304 int32_t dwc_otg_hcd_handle_port_intr(dwc_otg_hcd_t * dwc_otg_hcd)
00305 {
00306 int retval = 0;
00307 hprt0_data_t hprt0;
00308 hprt0_data_t hprt0_modify;
00309
00310 hprt0.d32 = DWC_READ_REG32(dwc_otg_hcd->core_if->host_if->hprt0);
00311 hprt0_modify.d32 = DWC_READ_REG32(dwc_otg_hcd->core_if->host_if->hprt0);
00312
00313
00314
00315
00316 hprt0_modify.b.prtena = 0;
00317 hprt0_modify.b.prtconndet = 0;
00318 hprt0_modify.b.prtenchng = 0;
00319 hprt0_modify.b.prtovrcurrchng = 0;
00320
00321
00322
00323 if (dwc_otg_hcd->core_if->hibernation_suspend == 1) {
00324
00325 hprt0_modify.b.prtconndet = 1;
00326 hprt0_modify.b.prtenchng = 1;
00327 DWC_WRITE_REG32(dwc_otg_hcd->core_if->host_if->hprt0, hprt0_modify.d32);
00328 hprt0.d32 = DWC_READ_REG32(dwc_otg_hcd->core_if->host_if->hprt0);
00329 return retval;
00330 }
00331
00332 if (hprt0.b.prtconndet) {
00334 if (dwc_otg_hcd->core_if->adp_enable &&
00335 dwc_otg_hcd->core_if->adp.vbuson_timer_started == 1) {
00336 DWC_PRINTF("PORT CONNECT DETECTED ----------------\n");
00337 DWC_TIMER_CANCEL(dwc_otg_hcd->core_if->adp.vbuson_timer);
00338 dwc_otg_hcd->core_if->adp.vbuson_timer_started = 0;
00339
00340
00341
00342
00343
00344
00345
00346
00347 } else {
00348
00349 DWC_DEBUGPL(DBG_HCD, "--Port Interrupt HPRT0=0x%08x "
00350 "Port Connect Detected--\n", hprt0.d32);
00351 dwc_otg_hcd->flags.b.port_connect_status_change = 1;
00352 dwc_otg_hcd->flags.b.port_connect_status = 1;
00353 hprt0_modify.b.prtconndet = 1;
00354
00355
00356 DWC_TIMER_CANCEL(dwc_otg_hcd->conn_timer);
00357 }
00358
00359
00360 retval |= 1;
00361 }
00362
00363
00364
00365 if (hprt0.b.prtenchng) {
00366 DWC_DEBUGPL(DBG_HCD, " --Port Interrupt HPRT0=0x%08x "
00367 "Port Enable Changed--\n", hprt0.d32);
00368 hprt0_modify.b.prtenchng = 1;
00369 if (hprt0.b.prtena == 1) {
00370 hfir_data_t hfir;
00371 int do_reset = 0;
00372 dwc_otg_core_params_t *params =
00373 dwc_otg_hcd->core_if->core_params;
00374 dwc_otg_core_global_regs_t *global_regs =
00375 dwc_otg_hcd->core_if->core_global_regs;
00376 dwc_otg_host_if_t *host_if =
00377 dwc_otg_hcd->core_if->host_if;
00378
00379
00380
00381
00382 hfir.d32 = DWC_READ_REG32(&host_if->host_global_regs->hfir);
00383 hfir.b.frint = calc_frame_interval(dwc_otg_hcd->core_if);
00384 DWC_WRITE_REG32(&host_if->host_global_regs->hfir, hfir.d32);
00385
00386
00387
00388 if (params->host_support_fs_ls_low_power) {
00389 gusbcfg_data_t usbcfg;
00390
00391 usbcfg.d32 =
00392 DWC_READ_REG32(&global_regs->gusbcfg);
00393
00394 if (hprt0.b.prtspd == DWC_HPRT0_PRTSPD_LOW_SPEED
00395 || hprt0.b.prtspd ==
00396 DWC_HPRT0_PRTSPD_FULL_SPEED) {
00397
00398
00399
00400 hcfg_data_t hcfg;
00401 if (usbcfg.b.phylpwrclksel == 0) {
00402
00403 usbcfg.b.phylpwrclksel = 1;
00404 DWC_WRITE_REG32
00405 (&global_regs->gusbcfg,
00406 usbcfg.d32);
00407 do_reset = 1;
00408 }
00409
00410 hcfg.d32 =
00411 DWC_READ_REG32
00412 (&host_if->host_global_regs->hcfg);
00413
00414 if (hprt0.b.prtspd ==
00415 DWC_HPRT0_PRTSPD_LOW_SPEED
00416 && params->host_ls_low_power_phy_clk
00417 ==
00418 DWC_HOST_LS_LOW_POWER_PHY_CLK_PARAM_6MHZ)
00419 {
00420
00421 DWC_DEBUGPL(DBG_CIL,
00422 "FS_PHY programming HCFG to 6 MHz (Low Power)\n");
00423 if (hcfg.b.fslspclksel !=
00424 DWC_HCFG_6_MHZ) {
00425 hcfg.b.fslspclksel =
00426 DWC_HCFG_6_MHZ;
00427 DWC_WRITE_REG32
00428 (&host_if->host_global_regs->hcfg,
00429 hcfg.d32);
00430 do_reset = 1;
00431 }
00432 } else {
00433
00434 DWC_DEBUGPL(DBG_CIL,
00435 "FS_PHY programming HCFG to 48 MHz ()\n");
00436 if (hcfg.b.fslspclksel !=
00437 DWC_HCFG_48_MHZ) {
00438 hcfg.b.fslspclksel =
00439 DWC_HCFG_48_MHZ;
00440 DWC_WRITE_REG32
00441 (&host_if->host_global_regs->hcfg,
00442 hcfg.d32);
00443 do_reset = 1;
00444 }
00445 }
00446 } else {
00447
00448
00449
00450 if (usbcfg.b.phylpwrclksel == 1) {
00451 usbcfg.b.phylpwrclksel = 0;
00452 DWC_WRITE_REG32
00453 (&global_regs->gusbcfg,
00454 usbcfg.d32);
00455 do_reset = 1;
00456 }
00457 }
00458
00459 if (do_reset) {
00460 DWC_TASK_SCHEDULE(dwc_otg_hcd->reset_tasklet);
00461 }
00462 }
00463
00464 if (!do_reset) {
00465
00466 dwc_otg_hcd->flags.b.port_reset_change = 1;
00467 }
00468 } else {
00469 dwc_otg_hcd->flags.b.port_enable_change = 1;
00470 }
00471 retval |= 1;
00472 }
00473
00475 if (hprt0.b.prtovrcurrchng) {
00476 DWC_DEBUGPL(DBG_HCD, " --Port Interrupt HPRT0=0x%08x "
00477 "Port Overcurrent Changed--\n", hprt0.d32);
00478 dwc_otg_hcd->flags.b.port_over_current_change = 1;
00479 hprt0_modify.b.prtovrcurrchng = 1;
00480 retval |= 1;
00481 }
00482
00483
00484 DWC_WRITE_REG32(dwc_otg_hcd->core_if->host_if->hprt0, hprt0_modify.d32);
00485
00486 return retval;
00487 }
00488
00493 int32_t dwc_otg_hcd_handle_hc_intr(dwc_otg_hcd_t * dwc_otg_hcd)
00494 {
00495 int i;
00496 int retval = 0;
00497 haint_data_t haint;
00498
00499
00500
00501
00502 haint.d32 = dwc_otg_read_host_all_channels_intr(dwc_otg_hcd->core_if);
00503
00504 for (i = 0; i < dwc_otg_hcd->core_if->core_params->host_channels; i++) {
00505 if (haint.b2.chint & (1 << i)) {
00506 retval |= dwc_otg_hcd_handle_hc_n_intr(dwc_otg_hcd, i);
00507 }
00508 }
00509
00510 return retval;
00511 }
00512
00523 static uint32_t get_actual_xfer_length(dwc_hc_t * hc,
00524 dwc_otg_hc_regs_t * hc_regs,
00525 dwc_otg_qtd_t * qtd,
00526 dwc_otg_halt_status_e halt_status,
00527 int *short_read)
00528 {
00529 hctsiz_data_t hctsiz;
00530 uint32_t length;
00531
00532 if (short_read != NULL) {
00533 *short_read = 0;
00534 }
00535 hctsiz.d32 = DWC_READ_REG32(&hc_regs->hctsiz);
00536
00537 if (halt_status == DWC_OTG_HC_XFER_COMPLETE) {
00538 if (hc->ep_is_in) {
00539 length = hc->xfer_len - hctsiz.b.xfersize;
00540 if (short_read != NULL) {
00541 *short_read = (hctsiz.b.xfersize != 0);
00542 }
00543 } else if (hc->qh->do_split) {
00544 length = qtd->ssplit_out_xfer_count;
00545 } else {
00546 length = hc->xfer_len;
00547 }
00548 } else {
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558 length =
00559 (hc->start_pkt_count - hctsiz.b.pktcnt) * hc->max_packet;
00560 }
00561
00562 return length;
00563 }
00564
00574 static int update_urb_state_xfer_comp(dwc_hc_t * hc,
00575 dwc_otg_hc_regs_t * hc_regs,
00576 dwc_otg_hcd_urb_t * urb,
00577 dwc_otg_qtd_t * qtd)
00578 {
00579 int xfer_done = 0;
00580 int short_read = 0;
00581
00582 int xfer_length;
00583
00584 xfer_length = get_actual_xfer_length(hc, hc_regs, qtd,
00585 DWC_OTG_HC_XFER_COMPLETE,
00586 &short_read);
00587
00588
00589
00590 if (hc->align_buff && xfer_length && hc->ep_is_in) {
00591 dwc_memcpy(urb->buf + urb->actual_length, hc->qh->dw_align_buf,
00592 xfer_length);
00593 }
00594
00595 urb->actual_length += xfer_length;
00596
00597 if (xfer_length && (hc->ep_type == DWC_OTG_EP_TYPE_BULK) &&
00598 (urb->flags & URB_SEND_ZERO_PACKET)
00599 && (urb->actual_length == urb->length)
00600 && !(urb->length % hc->max_packet)) {
00601 xfer_done = 0;
00602 } else if (short_read || urb->actual_length == urb->length) {
00603 xfer_done = 1;
00604 urb->status = 0;
00605 }
00606
00607 #ifdef DEBUG
00608 {
00609 hctsiz_data_t hctsiz;
00610 hctsiz.d32 = DWC_READ_REG32(&hc_regs->hctsiz);
00611 DWC_DEBUGPL(DBG_HCDV, "DWC_otg: %s: %s, channel %d\n",
00612 __func__, (hc->ep_is_in ? "IN" : "OUT"),
00613 hc->hc_num);
00614 DWC_DEBUGPL(DBG_HCDV, " hc->xfer_len %d\n", hc->xfer_len);
00615 DWC_DEBUGPL(DBG_HCDV, " hctsiz.xfersize %d\n",
00616 hctsiz.b.xfersize);
00617 DWC_DEBUGPL(DBG_HCDV, " urb->transfer_buffer_length %d\n",
00618 urb->length);
00619 DWC_DEBUGPL(DBG_HCDV, " urb->actual_length %d\n",
00620 urb->actual_length);
00621 DWC_DEBUGPL(DBG_HCDV, " short_read %d, xfer_done %d\n",
00622 short_read, xfer_done);
00623 }
00624 #endif
00625
00626 return xfer_done;
00627 }
00628
00629
00630
00631
00632
00633
00634 void dwc_otg_hcd_save_data_toggle(dwc_hc_t * hc,
00635 dwc_otg_hc_regs_t * hc_regs, dwc_otg_qtd_t * qtd)
00636 {
00637 hctsiz_data_t hctsiz;
00638 hctsiz.d32 = DWC_READ_REG32(&hc_regs->hctsiz);
00639
00640 if (hc->ep_type != DWC_OTG_EP_TYPE_CONTROL) {
00641 dwc_otg_qh_t *qh = hc->qh;
00642 if (hctsiz.b.pid == DWC_HCTSIZ_DATA0) {
00643 qh->data_toggle = DWC_OTG_HC_PID_DATA0;
00644 } else {
00645 qh->data_toggle = DWC_OTG_HC_PID_DATA1;
00646 }
00647 } else {
00648 if (hctsiz.b.pid == DWC_HCTSIZ_DATA0) {
00649 qtd->data_toggle = DWC_OTG_HC_PID_DATA0;
00650 } else {
00651 qtd->data_toggle = DWC_OTG_HC_PID_DATA1;
00652 }
00653 }
00654 }
00655
00665 static dwc_otg_halt_status_e
00666 update_isoc_urb_state(dwc_otg_hcd_t * hcd,
00667 dwc_hc_t * hc,
00668 dwc_otg_hc_regs_t * hc_regs,
00669 dwc_otg_qtd_t * qtd, dwc_otg_halt_status_e halt_status)
00670 {
00671 dwc_otg_hcd_urb_t *urb = qtd->urb;
00672 dwc_otg_halt_status_e ret_val = halt_status;
00673 struct dwc_otg_hcd_iso_packet_desc *frame_desc;
00674
00675 frame_desc = &urb->iso_descs[qtd->isoc_frame_index];
00676 switch (halt_status) {
00677 case DWC_OTG_HC_XFER_COMPLETE:
00678 frame_desc->status = 0;
00679 frame_desc->actual_length =
00680 get_actual_xfer_length(hc, hc_regs, qtd, halt_status, NULL);
00681
00682
00683 if (hc->align_buff && frame_desc->actual_length && hc->ep_is_in) {
00684 dwc_memcpy(urb->buf + frame_desc->offset + qtd->isoc_split_offset,
00685 hc->qh->dw_align_buf, frame_desc->actual_length);
00686 }
00687
00688 break;
00689 case DWC_OTG_HC_XFER_FRAME_OVERRUN:
00690 urb->error_count++;
00691 if (hc->ep_is_in) {
00692 frame_desc->status = -DWC_E_NO_STREAM_RES;
00693 } else {
00694 frame_desc->status = -DWC_E_COMMUNICATION;
00695 }
00696 frame_desc->actual_length = 0;
00697 break;
00698 case DWC_OTG_HC_XFER_BABBLE_ERR:
00699 urb->error_count++;
00700 frame_desc->status = -DWC_E_OVERFLOW;
00701
00702 break;
00703 case DWC_OTG_HC_XFER_XACT_ERR:
00704 urb->error_count++;
00705 frame_desc->status = -DWC_E_PROTOCOL;
00706 frame_desc->actual_length =
00707 get_actual_xfer_length(hc, hc_regs, qtd, halt_status, NULL);
00708
00709
00710 if (hc->align_buff && frame_desc->actual_length && hc->ep_is_in) {
00711 dwc_memcpy(urb->buf + frame_desc->offset + qtd->isoc_split_offset,
00712 hc->qh->dw_align_buf, frame_desc->actual_length);
00713 }
00714
00715 if (hc->qh->do_split && (hc->ep_type == DWC_OTG_EP_TYPE_ISOC) &&
00716 hc->ep_is_in && hcd->core_if->dma_enable) {
00717 qtd->complete_split = 0;
00718 qtd->isoc_split_offset = 0;
00719 }
00720
00721 break;
00722 default:
00723 DWC_ASSERT(1, "Unhandled _halt_status (%d)\n", halt_status);
00724 break;
00725 }
00726 if (++qtd->isoc_frame_index == urb->packet_count) {
00727
00728
00729
00730
00731 hcd->fops->complete(hcd, urb->priv, urb, 0);
00732 ret_val = DWC_OTG_HC_XFER_URB_COMPLETE;
00733 } else {
00734 ret_val = DWC_OTG_HC_XFER_COMPLETE;
00735 }
00736 return ret_val;
00737 }
00738
00746 static void deactivate_qh(dwc_otg_hcd_t * hcd, dwc_otg_qh_t * qh, int free_qtd)
00747 {
00748 int continue_split = 0;
00749 dwc_otg_qtd_t *qtd;
00750
00751 DWC_DEBUGPL(DBG_HCDV, " %s(%p,%p,%d)\n", __func__, hcd, qh, free_qtd);
00752
00753 qtd = DWC_CIRCLEQ_FIRST(&qh->qtd_list);
00754
00755 if (qtd->complete_split) {
00756 continue_split = 1;
00757 } else if (qtd->isoc_split_pos == DWC_HCSPLIT_XACTPOS_MID ||
00758 qtd->isoc_split_pos == DWC_HCSPLIT_XACTPOS_END) {
00759 continue_split = 1;
00760 }
00761
00762 if (free_qtd) {
00763 dwc_otg_hcd_qtd_remove_and_free(hcd, qtd, qh);
00764 continue_split = 0;
00765 }
00766
00767 qh->channel = NULL;
00768 dwc_otg_hcd_qh_deactivate(hcd, qh, continue_split);
00769 }
00770
00782 static void release_channel(dwc_otg_hcd_t * hcd,
00783 dwc_hc_t * hc,
00784 dwc_otg_qtd_t * qtd,
00785 dwc_otg_halt_status_e halt_status)
00786 {
00787 dwc_otg_transaction_type_e tr_type;
00788 int free_qtd;
00789
00790 DWC_DEBUGPL(DBG_HCDV, " %s: channel %d, halt_status %d\n",
00791 __func__, hc->hc_num, halt_status);
00792
00793 switch (halt_status) {
00794 case DWC_OTG_HC_XFER_URB_COMPLETE:
00795 free_qtd = 1;
00796 break;
00797 case DWC_OTG_HC_XFER_AHB_ERR:
00798 case DWC_OTG_HC_XFER_STALL:
00799 case DWC_OTG_HC_XFER_BABBLE_ERR:
00800 free_qtd = 1;
00801 break;
00802 case DWC_OTG_HC_XFER_XACT_ERR:
00803 if (qtd->error_count >= 3) {
00804 DWC_DEBUGPL(DBG_HCDV,
00805 " Complete URB with transaction error\n");
00806 free_qtd = 1;
00807 qtd->urb->status = -DWC_E_PROTOCOL;
00808 hcd->fops->complete(hcd, qtd->urb->priv,
00809 qtd->urb, -DWC_E_PROTOCOL);
00810 } else {
00811 free_qtd = 0;
00812 }
00813 break;
00814 case DWC_OTG_HC_XFER_URB_DEQUEUE:
00815
00816
00817
00818
00819
00820 goto cleanup;
00821 case DWC_OTG_HC_XFER_NO_HALT_STATUS:
00822 free_qtd = 0;
00823 break;
00824 case DWC_OTG_HC_XFER_PERIODIC_INCOMPLETE:
00825 DWC_DEBUGPL(DBG_HCDV,
00826 " Complete URB with I/O error\n");
00827 free_qtd = 1;
00828 qtd->urb->status = -DWC_E_IO;
00829 hcd->fops->complete(hcd, qtd->urb->priv,
00830 qtd->urb, -DWC_E_IO);
00831 break;
00832 default:
00833 free_qtd = 0;
00834 break;
00835 }
00836
00837 deactivate_qh(hcd, hc->qh, free_qtd);
00838
00839 cleanup:
00840
00841
00842
00843
00844
00845 dwc_otg_hc_cleanup(hcd->core_if, hc);
00846 DWC_CIRCLEQ_INSERT_TAIL(&hcd->free_hc_list, hc, hc_list_entry);
00847
00848 switch (hc->ep_type) {
00849 case DWC_OTG_EP_TYPE_CONTROL:
00850 case DWC_OTG_EP_TYPE_BULK:
00851 hcd->non_periodic_channels--;
00852 break;
00853
00854 default:
00855
00856
00857
00858
00859
00860 break;
00861 }
00862
00863
00864 tr_type = dwc_otg_hcd_select_transactions(hcd);
00865 if (tr_type != DWC_OTG_TRANSACTION_NONE) {
00866 dwc_otg_hcd_queue_transactions(hcd, tr_type);
00867 }
00868 }
00869
00880 static void halt_channel(dwc_otg_hcd_t * hcd,
00881 dwc_hc_t * hc,
00882 dwc_otg_qtd_t * qtd, dwc_otg_halt_status_e halt_status)
00883 {
00884 if (hcd->core_if->dma_enable) {
00885 release_channel(hcd, hc, qtd, halt_status);
00886 return;
00887 }
00888
00889
00890 dwc_otg_hc_halt(hcd->core_if, hc, halt_status);
00891
00892 if (hc->halt_on_queue) {
00893 gintmsk_data_t gintmsk = {.d32 = 0 };
00894 dwc_otg_core_global_regs_t *global_regs;
00895 global_regs = hcd->core_if->core_global_regs;
00896
00897 if (hc->ep_type == DWC_OTG_EP_TYPE_CONTROL ||
00898 hc->ep_type == DWC_OTG_EP_TYPE_BULK) {
00899
00900
00901
00902
00903
00904 gintmsk.b.nptxfempty = 1;
00905 DWC_MODIFY_REG32(&global_regs->gintmsk, 0, gintmsk.d32);
00906 } else {
00907
00908
00909
00910
00911
00912
00913 DWC_LIST_MOVE_HEAD(&hcd->periodic_sched_assigned,
00914 &hc->qh->qh_list_entry);
00915
00916
00917
00918
00919
00920
00921 gintmsk.b.ptxfempty = 1;
00922 DWC_MODIFY_REG32(&global_regs->gintmsk, 0, gintmsk.d32);
00923 }
00924 }
00925 }
00926
00932 static void complete_non_periodic_xfer(dwc_otg_hcd_t * hcd,
00933 dwc_hc_t * hc,
00934 dwc_otg_hc_regs_t * hc_regs,
00935 dwc_otg_qtd_t * qtd,
00936 dwc_otg_halt_status_e halt_status)
00937 {
00938 hcint_data_t hcint;
00939
00940 qtd->error_count = 0;
00941
00942 hcint.d32 = DWC_READ_REG32(&hc_regs->hcint);
00943 if (hcint.b.nyet) {
00944
00945
00946
00947
00948
00949 hc->qh->ping_state = 1;
00950 clear_hc_int(hc_regs, nyet);
00951 }
00952
00953
00954
00955
00956
00957
00958
00959
00960
00961
00962
00963 if (hc->ep_is_in) {
00964
00965
00966
00967
00968
00969 halt_channel(hcd, hc, qtd, halt_status);
00970 } else {
00971
00972
00973
00974
00975 release_channel(hcd, hc, qtd, halt_status);
00976 }
00977 }
00978
00984 static void complete_periodic_xfer(dwc_otg_hcd_t * hcd,
00985 dwc_hc_t * hc,
00986 dwc_otg_hc_regs_t * hc_regs,
00987 dwc_otg_qtd_t * qtd,
00988 dwc_otg_halt_status_e halt_status)
00989 {
00990 hctsiz_data_t hctsiz;
00991 qtd->error_count = 0;
00992
00993 hctsiz.d32 = DWC_READ_REG32(&hc_regs->hctsiz);
00994 if (!hc->ep_is_in || hctsiz.b.pktcnt == 0) {
00995
00996 release_channel(hcd, hc, qtd, halt_status);
00997 } else {
00998
00999 halt_channel(hcd, hc, qtd, halt_status);
01000 }
01001 }
01002
01003 static int32_t handle_xfercomp_isoc_split_in(dwc_otg_hcd_t * hcd,
01004 dwc_hc_t * hc,
01005 dwc_otg_hc_regs_t * hc_regs,
01006 dwc_otg_qtd_t * qtd)
01007 {
01008 uint32_t len;
01009 struct dwc_otg_hcd_iso_packet_desc *frame_desc;
01010 frame_desc = &qtd->urb->iso_descs[qtd->isoc_frame_index];
01011
01012 len = get_actual_xfer_length(hc, hc_regs, qtd,
01013 DWC_OTG_HC_XFER_COMPLETE, NULL);
01014
01015 if (!len) {
01016 qtd->complete_split = 0;
01017 qtd->isoc_split_offset = 0;
01018 return 0;
01019 }
01020 frame_desc->actual_length += len;
01021
01022 if (hc->align_buff && len)
01023 dwc_memcpy(qtd->urb->buf + frame_desc->offset +
01024 qtd->isoc_split_offset, hc->qh->dw_align_buf, len);
01025 qtd->isoc_split_offset += len;
01026
01027 if (frame_desc->length == frame_desc->actual_length) {
01028 frame_desc->status = 0;
01029 qtd->isoc_frame_index++;
01030 qtd->complete_split = 0;
01031 qtd->isoc_split_offset = 0;
01032 }
01033
01034 if (qtd->isoc_frame_index == qtd->urb->packet_count) {
01035 hcd->fops->complete(hcd, qtd->urb->priv, qtd->urb, 0);
01036 release_channel(hcd, hc, qtd, DWC_OTG_HC_XFER_URB_COMPLETE);
01037 } else {
01038 release_channel(hcd, hc, qtd, DWC_OTG_HC_XFER_NO_HALT_STATUS);
01039 }
01040
01041 return 1;
01042 }
01043
01048 static int32_t handle_hc_xfercomp_intr(dwc_otg_hcd_t * hcd,
01049 dwc_hc_t * hc,
01050 dwc_otg_hc_regs_t * hc_regs,
01051 dwc_otg_qtd_t * qtd)
01052 {
01053 int urb_xfer_done;
01054 dwc_otg_halt_status_e halt_status = DWC_OTG_HC_XFER_COMPLETE;
01055 dwc_otg_hcd_urb_t *urb = qtd->urb;
01056 int pipe_type = dwc_otg_hcd_get_pipe_type(&urb->pipe_info);
01057
01058 DWC_DEBUGPL(DBG_HCD, "--Host Channel %d Interrupt: "
01059 "Transfer Complete--\n", hc->hc_num);
01060
01061 if (hcd->core_if->dma_desc_enable) {
01062 dwc_otg_hcd_complete_xfer_ddma(hcd, hc, hc_regs, halt_status);
01063 if (pipe_type == UE_ISOCHRONOUS) {
01064
01065 clear_hc_int(hc_regs, xfercomp);
01066 return 1;
01067 }
01068 goto handle_xfercomp_done;
01069 }
01070
01071
01072
01073
01074
01075 if (hc->qh->do_split) {
01076 if ((hc->ep_type == DWC_OTG_EP_TYPE_ISOC) && hc->ep_is_in
01077 && hcd->core_if->dma_enable) {
01078 if (qtd->complete_split
01079 && handle_xfercomp_isoc_split_in(hcd, hc, hc_regs,
01080 qtd))
01081 goto handle_xfercomp_done;
01082 } else {
01083 qtd->complete_split = 0;
01084 }
01085 }
01086
01087
01088 switch (pipe_type) {
01089 case UE_CONTROL:
01090 switch (qtd->control_phase) {
01091 case DWC_OTG_CONTROL_SETUP:
01092 if (urb->length > 0) {
01093 qtd->control_phase = DWC_OTG_CONTROL_DATA;
01094 } else {
01095 qtd->control_phase = DWC_OTG_CONTROL_STATUS;
01096 }
01097 DWC_DEBUGPL(DBG_HCDV,
01098 " Control setup transaction done\n");
01099 halt_status = DWC_OTG_HC_XFER_COMPLETE;
01100 break;
01101 case DWC_OTG_CONTROL_DATA:{
01102 urb_xfer_done =
01103 update_urb_state_xfer_comp(hc, hc_regs, urb,
01104 qtd);
01105 if (urb_xfer_done) {
01106 qtd->control_phase =
01107 DWC_OTG_CONTROL_STATUS;
01108 DWC_DEBUGPL(DBG_HCDV,
01109 " Control data transfer done\n");
01110 } else {
01111 dwc_otg_hcd_save_data_toggle(hc, hc_regs, qtd);
01112 }
01113 halt_status = DWC_OTG_HC_XFER_COMPLETE;
01114 break;
01115 }
01116 case DWC_OTG_CONTROL_STATUS:
01117 DWC_DEBUGPL(DBG_HCDV, " Control transfer complete\n");
01118 if (urb->status == -DWC_E_IN_PROGRESS) {
01119 urb->status = 0;
01120 }
01121 hcd->fops->complete(hcd, urb->priv, urb, urb->status);
01122 halt_status = DWC_OTG_HC_XFER_URB_COMPLETE;
01123 break;
01124 }
01125
01126 complete_non_periodic_xfer(hcd, hc, hc_regs, qtd, halt_status);
01127 break;
01128 case UE_BULK:
01129 DWC_DEBUGPL(DBG_HCDV, " Bulk transfer complete\n");
01130 urb_xfer_done =
01131 update_urb_state_xfer_comp(hc, hc_regs, urb, qtd);
01132 if (urb_xfer_done) {
01133 hcd->fops->complete(hcd, urb->priv, urb, urb->status);
01134 halt_status = DWC_OTG_HC_XFER_URB_COMPLETE;
01135 } else {
01136 halt_status = DWC_OTG_HC_XFER_COMPLETE;
01137 }
01138
01139 dwc_otg_hcd_save_data_toggle(hc, hc_regs, qtd);
01140 complete_non_periodic_xfer(hcd, hc, hc_regs, qtd, halt_status);
01141 break;
01142 case UE_INTERRUPT:
01143 DWC_DEBUGPL(DBG_HCDV, " Interrupt transfer complete\n");
01144 urb_xfer_done =
01145 update_urb_state_xfer_comp(hc, hc_regs, urb, qtd);
01146
01147
01148
01149
01150
01151 if (urb_xfer_done) {
01152 hcd->fops->complete(hcd, urb->priv, urb, urb->status);
01153 halt_status = DWC_OTG_HC_XFER_URB_COMPLETE;
01154 } else {
01155 halt_status = DWC_OTG_HC_XFER_COMPLETE;
01156 }
01157
01158 dwc_otg_hcd_save_data_toggle(hc, hc_regs, qtd);
01159 complete_periodic_xfer(hcd, hc, hc_regs, qtd, halt_status);
01160 break;
01161 case UE_ISOCHRONOUS:
01162 DWC_DEBUGPL(DBG_HCDV, " Isochronous transfer complete\n");
01163 if (qtd->isoc_split_pos == DWC_HCSPLIT_XACTPOS_ALL) {
01164 halt_status =
01165 update_isoc_urb_state(hcd, hc, hc_regs, qtd,
01166 DWC_OTG_HC_XFER_COMPLETE);
01167 }
01168 complete_periodic_xfer(hcd, hc, hc_regs, qtd, halt_status);
01169 break;
01170 }
01171
01172 handle_xfercomp_done:
01173 disable_hc_int(hc_regs, xfercompl);
01174
01175 return 1;
01176 }
01177
01182 static int32_t handle_hc_stall_intr(dwc_otg_hcd_t * hcd,
01183 dwc_hc_t * hc,
01184 dwc_otg_hc_regs_t * hc_regs,
01185 dwc_otg_qtd_t * qtd)
01186 {
01187 dwc_otg_hcd_urb_t *urb = qtd->urb;
01188 int pipe_type = dwc_otg_hcd_get_pipe_type(&urb->pipe_info);
01189
01190 DWC_DEBUGPL(DBG_HCD, "--Host Channel %d Interrupt: "
01191 "STALL Received--\n", hc->hc_num);
01192
01193 if (hcd->core_if->dma_desc_enable) {
01194 dwc_otg_hcd_complete_xfer_ddma(hcd, hc, hc_regs, DWC_OTG_HC_XFER_STALL);
01195 goto handle_stall_done;
01196 }
01197
01198 if (pipe_type == UE_CONTROL) {
01199 hcd->fops->complete(hcd, urb->priv, urb, -DWC_E_PIPE);
01200 }
01201
01202 if (pipe_type == UE_BULK || pipe_type == UE_INTERRUPT) {
01203 hcd->fops->complete(hcd, urb->priv, urb, -DWC_E_PIPE);
01204
01205
01206
01207
01208
01209
01210
01211 hc->qh->data_toggle = 0;
01212 }
01213
01214 halt_channel(hcd, hc, qtd, DWC_OTG_HC_XFER_STALL);
01215
01216 handle_stall_done:
01217 disable_hc_int(hc_regs, stall);
01218
01219 return 1;
01220 }
01221
01222
01223
01224
01225
01226
01227
01228 static void update_urb_state_xfer_intr(dwc_hc_t * hc,
01229 dwc_otg_hc_regs_t * hc_regs,
01230 dwc_otg_hcd_urb_t * urb,
01231 dwc_otg_qtd_t * qtd,
01232 dwc_otg_halt_status_e halt_status)
01233 {
01234 uint32_t bytes_transferred = get_actual_xfer_length(hc, hc_regs, qtd,
01235 halt_status, NULL);
01236
01237 if (hc->align_buff && bytes_transferred && hc->ep_is_in) {
01238 dwc_memcpy(urb->buf + urb->actual_length, hc->qh->dw_align_buf,
01239 bytes_transferred);
01240 }
01241
01242 urb->actual_length += bytes_transferred;
01243
01244 #ifdef DEBUG
01245 {
01246 hctsiz_data_t hctsiz;
01247 hctsiz.d32 = DWC_READ_REG32(&hc_regs->hctsiz);
01248 DWC_DEBUGPL(DBG_HCDV, "DWC_otg: %s: %s, channel %d\n",
01249 __func__, (hc->ep_is_in ? "IN" : "OUT"),
01250 hc->hc_num);
01251 DWC_DEBUGPL(DBG_HCDV, " hc->start_pkt_count %d\n",
01252 hc->start_pkt_count);
01253 DWC_DEBUGPL(DBG_HCDV, " hctsiz.pktcnt %d\n", hctsiz.b.pktcnt);
01254 DWC_DEBUGPL(DBG_HCDV, " hc->max_packet %d\n", hc->max_packet);
01255 DWC_DEBUGPL(DBG_HCDV, " bytes_transferred %d\n",
01256 bytes_transferred);
01257 DWC_DEBUGPL(DBG_HCDV, " urb->actual_length %d\n",
01258 urb->actual_length);
01259 DWC_DEBUGPL(DBG_HCDV, " urb->transfer_buffer_length %d\n",
01260 urb->length);
01261 }
01262 #endif
01263 }
01264
01269 static int32_t handle_hc_nak_intr(dwc_otg_hcd_t * hcd,
01270 dwc_hc_t * hc,
01271 dwc_otg_hc_regs_t * hc_regs,
01272 dwc_otg_qtd_t * qtd)
01273 {
01274 DWC_DEBUGPL(DBG_HCD, "--Host Channel %d Interrupt: "
01275 "NAK Received--\n", hc->hc_num);
01276
01277
01278
01279
01280
01281 if (hc->do_split) {
01282 if (hc->complete_split) {
01283 qtd->error_count = 0;
01284 }
01285 qtd->complete_split = 0;
01286 halt_channel(hcd, hc, qtd, DWC_OTG_HC_XFER_NAK);
01287 goto handle_nak_done;
01288 }
01289
01290 switch (dwc_otg_hcd_get_pipe_type(&qtd->urb->pipe_info)) {
01291 case UE_CONTROL:
01292 case UE_BULK:
01293 if (hcd->core_if->dma_enable && hc->ep_is_in) {
01294
01295
01296
01297
01298
01299
01300 qtd->error_count = 0;
01301 goto handle_nak_done;
01302 }
01303
01304
01305
01306
01307
01308
01309 qtd->error_count = 0;
01310
01311 if (!hc->qh->ping_state) {
01312 update_urb_state_xfer_intr(hc, hc_regs,
01313 qtd->urb, qtd,
01314 DWC_OTG_HC_XFER_NAK);
01315 dwc_otg_hcd_save_data_toggle(hc, hc_regs, qtd);
01316
01317 if (hc->speed == DWC_OTG_EP_SPEED_HIGH)
01318 hc->qh->ping_state = 1;
01319 }
01320
01321
01322
01323
01324
01325
01326 halt_channel(hcd, hc, qtd, DWC_OTG_HC_XFER_NAK);
01327 break;
01328 case UE_INTERRUPT:
01329 qtd->error_count = 0;
01330 halt_channel(hcd, hc, qtd, DWC_OTG_HC_XFER_NAK);
01331 break;
01332 case UE_ISOCHRONOUS:
01333
01334 DWC_ASSERT(1, "NACK interrupt for ISOC transfer\n");
01335 break;
01336 }
01337
01338 handle_nak_done:
01339 disable_hc_int(hc_regs, nak);
01340
01341 return 1;
01342 }
01343
01349 static int32_t handle_hc_ack_intr(dwc_otg_hcd_t * hcd,
01350 dwc_hc_t * hc,
01351 dwc_otg_hc_regs_t * hc_regs,
01352 dwc_otg_qtd_t * qtd)
01353 {
01354 DWC_DEBUGPL(DBG_HCD, "--Host Channel %d Interrupt: "
01355 "ACK Received--\n", hc->hc_num);
01356
01357 if (hc->do_split) {
01358
01359
01360
01361
01362 if (!hc->ep_is_in && hc->data_pid_start != DWC_OTG_HC_PID_SETUP) {
01363 qtd->ssplit_out_xfer_count = hc->xfer_len;
01364 }
01365 if (!(hc->ep_type == DWC_OTG_EP_TYPE_ISOC && !hc->ep_is_in)) {
01366
01367 qtd->complete_split = 1;
01368 }
01369
01370
01371 if (hc->ep_type == DWC_OTG_EP_TYPE_ISOC && !hc->ep_is_in) {
01372 switch (hc->xact_pos) {
01373 case DWC_HCSPLIT_XACTPOS_ALL:
01374 break;
01375 case DWC_HCSPLIT_XACTPOS_END:
01376 qtd->isoc_split_pos = DWC_HCSPLIT_XACTPOS_ALL;
01377 qtd->isoc_split_offset = 0;
01378 break;
01379 case DWC_HCSPLIT_XACTPOS_BEGIN:
01380 case DWC_HCSPLIT_XACTPOS_MID:
01381
01382
01383
01384
01385
01386 {
01387 struct dwc_otg_hcd_iso_packet_desc
01388 *frame_desc;
01389
01390 frame_desc =
01391 &qtd->urb->
01392 iso_descs[qtd->isoc_frame_index];
01393 qtd->isoc_split_offset += 188;
01394
01395 if ((frame_desc->length -
01396 qtd->isoc_split_offset) <= 188) {
01397 qtd->isoc_split_pos =
01398 DWC_HCSPLIT_XACTPOS_END;
01399 } else {
01400 qtd->isoc_split_pos =
01401 DWC_HCSPLIT_XACTPOS_MID;
01402 }
01403
01404 }
01405 break;
01406 }
01407 } else {
01408 halt_channel(hcd, hc, qtd, DWC_OTG_HC_XFER_ACK);
01409 }
01410 } else {
01411 qtd->error_count = 0;
01412
01413 if (hc->qh->ping_state) {
01414 hc->qh->ping_state = 0;
01415
01416
01417
01418
01419
01420
01421
01422 halt_channel(hcd, hc, qtd, DWC_OTG_HC_XFER_ACK);
01423 }
01424 }
01425
01426
01427
01428
01429
01430
01431 disable_hc_int(hc_regs, ack);
01432
01433 return 1;
01434 }
01435
01443 static int32_t handle_hc_nyet_intr(dwc_otg_hcd_t * hcd,
01444 dwc_hc_t * hc,
01445 dwc_otg_hc_regs_t * hc_regs,
01446 dwc_otg_qtd_t * qtd)
01447 {
01448 DWC_DEBUGPL(DBG_HCD, "--Host Channel %d Interrupt: "
01449 "NYET Received--\n", hc->hc_num);
01450
01451
01452
01453
01454
01455 if (hc->do_split && hc->complete_split) {
01456 if (hc->ep_is_in && (hc->ep_type == DWC_OTG_EP_TYPE_ISOC)
01457 && hcd->core_if->dma_enable) {
01458 qtd->complete_split = 0;
01459 qtd->isoc_split_offset = 0;
01460 if (++qtd->isoc_frame_index == qtd->urb->packet_count) {
01461 hcd->fops->complete(hcd, qtd->urb->priv, qtd->urb, 0);
01462 release_channel(hcd, hc, qtd, DWC_OTG_HC_XFER_URB_COMPLETE);
01463 }
01464 else
01465 release_channel(hcd, hc, qtd, DWC_OTG_HC_XFER_NO_HALT_STATUS);
01466 goto handle_nyet_done;
01467 }
01468
01469 if (hc->ep_type == DWC_OTG_EP_TYPE_INTR ||
01470 hc->ep_type == DWC_OTG_EP_TYPE_ISOC) {
01471 int frnum = dwc_otg_hcd_get_frame_number(hcd);
01472
01473 if (dwc_full_frame_num(frnum) !=
01474 dwc_full_frame_num(hc->qh->sched_frame)) {
01475
01476
01477
01478
01479 #if 0
01480
01486 qtd->error_count++;
01487 #endif
01488 qtd->complete_split = 0;
01489 halt_channel(hcd, hc, qtd,
01490 DWC_OTG_HC_XFER_XACT_ERR);
01492 goto handle_nyet_done;
01493 }
01494 }
01495
01496 halt_channel(hcd, hc, qtd, DWC_OTG_HC_XFER_NYET);
01497 goto handle_nyet_done;
01498 }
01499
01500 hc->qh->ping_state = 1;
01501 qtd->error_count = 0;
01502
01503 update_urb_state_xfer_intr(hc, hc_regs, qtd->urb, qtd,
01504 DWC_OTG_HC_XFER_NYET);
01505 dwc_otg_hcd_save_data_toggle(hc, hc_regs, qtd);
01506
01507
01508
01509
01510
01511 halt_channel(hcd, hc, qtd, DWC_OTG_HC_XFER_NYET);
01512
01513 handle_nyet_done:
01514 disable_hc_int(hc_regs, nyet);
01515 return 1;
01516 }
01517
01522 static int32_t handle_hc_babble_intr(dwc_otg_hcd_t * hcd,
01523 dwc_hc_t * hc,
01524 dwc_otg_hc_regs_t * hc_regs,
01525 dwc_otg_qtd_t * qtd)
01526 {
01527 DWC_DEBUGPL(DBG_HCD, "--Host Channel %d Interrupt: "
01528 "Babble Error--\n", hc->hc_num);
01529
01530 if (hcd->core_if->dma_desc_enable) {
01531 dwc_otg_hcd_complete_xfer_ddma(hcd, hc, hc_regs,
01532 DWC_OTG_HC_XFER_BABBLE_ERR);
01533 goto handle_babble_done;
01534 }
01535
01536 if (hc->ep_type != DWC_OTG_EP_TYPE_ISOC) {
01537 hcd->fops->complete(hcd, qtd->urb->priv,
01538 qtd->urb, -DWC_E_OVERFLOW);
01539 halt_channel(hcd, hc, qtd, DWC_OTG_HC_XFER_BABBLE_ERR);
01540 } else {
01541 dwc_otg_halt_status_e halt_status;
01542 halt_status = update_isoc_urb_state(hcd, hc, hc_regs, qtd,
01543 DWC_OTG_HC_XFER_BABBLE_ERR);
01544 halt_channel(hcd, hc, qtd, halt_status);
01545 }
01546
01547 handle_babble_done:
01548 disable_hc_int(hc_regs, bblerr);
01549 return 1;
01550 }
01551
01556 static int32_t handle_hc_ahberr_intr(dwc_otg_hcd_t * hcd,
01557 dwc_hc_t * hc,
01558 dwc_otg_hc_regs_t * hc_regs,
01559 dwc_otg_qtd_t * qtd)
01560 {
01561 hcchar_data_t hcchar;
01562 hcsplt_data_t hcsplt;
01563 hctsiz_data_t hctsiz;
01564 uint32_t hcdma;
01565 char *pipetype, *speed;
01566
01567 dwc_otg_hcd_urb_t *urb = qtd->urb;
01568
01569 DWC_DEBUGPL(DBG_HCD, "--Host Channel %d Interrupt: "
01570 "AHB Error--\n", hc->hc_num);
01571
01572 hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
01573 hcsplt.d32 = DWC_READ_REG32(&hc_regs->hcsplt);
01574 hctsiz.d32 = DWC_READ_REG32(&hc_regs->hctsiz);
01575 hcdma = DWC_READ_REG32(&hc_regs->hcdma);
01576
01577 DWC_ERROR("AHB ERROR, Channel %d\n", hc->hc_num);
01578 DWC_ERROR(" hcchar 0x%08x, hcsplt 0x%08x\n", hcchar.d32, hcsplt.d32);
01579 DWC_ERROR(" hctsiz 0x%08x, hcdma 0x%08x\n", hctsiz.d32, hcdma);
01580 DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD URB Enqueue\n");
01581 DWC_ERROR(" Device address: %d\n",
01582 dwc_otg_hcd_get_dev_addr(&urb->pipe_info));
01583 DWC_ERROR(" Endpoint: %d, %s\n",
01584 dwc_otg_hcd_get_ep_num(&urb->pipe_info),
01585 (dwc_otg_hcd_is_pipe_in(&urb->pipe_info) ? "IN" : "OUT"));
01586
01587 switch (dwc_otg_hcd_get_pipe_type(&urb->pipe_info)) {
01588 case UE_CONTROL:
01589 pipetype = "CONTROL";
01590 break;
01591 case UE_BULK:
01592 pipetype = "BULK";
01593 break;
01594 case UE_INTERRUPT:
01595 pipetype = "INTERRUPT";
01596 break;
01597 case UE_ISOCHRONOUS:
01598 pipetype = "ISOCHRONOUS";
01599 break;
01600 default:
01601 pipetype = "UNKNOWN";
01602 break;
01603 }
01604
01605 DWC_ERROR(" Endpoint type: %s\n", pipetype);
01606
01607 switch (hc->speed) {
01608 case DWC_OTG_EP_SPEED_HIGH:
01609 speed = "HIGH";
01610 break;
01611 case DWC_OTG_EP_SPEED_FULL:
01612 speed = "FULL";
01613 break;
01614 case DWC_OTG_EP_SPEED_LOW:
01615 speed = "LOW";
01616 break;
01617 default:
01618 speed = "UNKNOWN";
01619 break;
01620 };
01621
01622 DWC_ERROR(" Speed: %s\n", speed);
01623
01624 DWC_ERROR(" Max packet size: %d\n",
01625 dwc_otg_hcd_get_mps(&urb->pipe_info));
01626 DWC_ERROR(" Data buffer length: %d\n", urb->length);
01627 DWC_ERROR(" Transfer buffer: %p, Transfer DMA: %p\n",
01628 urb->buf, (void *)urb->dma);
01629 DWC_ERROR(" Setup buffer: %p, Setup DMA: %p\n",
01630 urb->setup_packet, (void *)urb->setup_dma);
01631 DWC_ERROR(" Interval: %d\n", urb->interval);
01632
01633
01634 if (hcd->core_if->dma_desc_enable) {
01635 dwc_otg_hcd_complete_xfer_ddma(hcd, hc, hc_regs,
01636 DWC_OTG_HC_XFER_AHB_ERR);
01637 goto handle_ahberr_done;
01638 }
01639
01640 hcd->fops->complete(hcd, urb->priv, urb, -DWC_E_IO);
01641
01642
01643
01644
01645
01646 dwc_otg_hc_halt(hcd->core_if, hc, DWC_OTG_HC_XFER_AHB_ERR);
01647 handle_ahberr_done:
01648 disable_hc_int(hc_regs, ahberr);
01649 return 1;
01650 }
01651
01656 static int32_t handle_hc_xacterr_intr(dwc_otg_hcd_t * hcd,
01657 dwc_hc_t * hc,
01658 dwc_otg_hc_regs_t * hc_regs,
01659 dwc_otg_qtd_t * qtd)
01660 {
01661 DWC_DEBUGPL(DBG_HCD, "--Host Channel %d Interrupt: "
01662 "Transaction Error--\n", hc->hc_num);
01663
01664 if (hcd->core_if->dma_desc_enable) {
01665 dwc_otg_hcd_complete_xfer_ddma(hcd, hc, hc_regs,
01666 DWC_OTG_HC_XFER_XACT_ERR);
01667 goto handle_xacterr_done;
01668 }
01669
01670 switch (dwc_otg_hcd_get_pipe_type(&qtd->urb->pipe_info)) {
01671 case UE_CONTROL:
01672 case UE_BULK:
01673 qtd->error_count++;
01674 if (!hc->qh->ping_state) {
01675
01676 update_urb_state_xfer_intr(hc, hc_regs,
01677 qtd->urb, qtd,
01678 DWC_OTG_HC_XFER_XACT_ERR);
01679 dwc_otg_hcd_save_data_toggle(hc, hc_regs, qtd);
01680 if (!hc->ep_is_in && hc->speed == DWC_OTG_EP_SPEED_HIGH) {
01681 hc->qh->ping_state = 1;
01682 }
01683 }
01684
01685
01686
01687
01688
01689 halt_channel(hcd, hc, qtd, DWC_OTG_HC_XFER_XACT_ERR);
01690 break;
01691 case UE_INTERRUPT:
01692 qtd->error_count++;
01693 if (hc->do_split && hc->complete_split) {
01694 qtd->complete_split = 0;
01695 }
01696 halt_channel(hcd, hc, qtd, DWC_OTG_HC_XFER_XACT_ERR);
01697 break;
01698 case UE_ISOCHRONOUS:
01699 {
01700 dwc_otg_halt_status_e halt_status;
01701 halt_status =
01702 update_isoc_urb_state(hcd, hc, hc_regs, qtd,
01703 DWC_OTG_HC_XFER_XACT_ERR);
01704
01705 halt_channel(hcd, hc, qtd, halt_status);
01706 }
01707 break;
01708 }
01709 handle_xacterr_done:
01710 disable_hc_int(hc_regs, xacterr);
01711
01712 return 1;
01713 }
01714
01719 static int32_t handle_hc_frmovrun_intr(dwc_otg_hcd_t * hcd,
01720 dwc_hc_t * hc,
01721 dwc_otg_hc_regs_t * hc_regs,
01722 dwc_otg_qtd_t * qtd)
01723 {
01724 DWC_DEBUGPL(DBG_HCD, "--Host Channel %d Interrupt: "
01725 "Frame Overrun--\n", hc->hc_num);
01726
01727 switch (dwc_otg_hcd_get_pipe_type(&qtd->urb->pipe_info)) {
01728 case UE_CONTROL:
01729 case UE_BULK:
01730 break;
01731 case UE_INTERRUPT:
01732 halt_channel(hcd, hc, qtd, DWC_OTG_HC_XFER_FRAME_OVERRUN);
01733 break;
01734 case UE_ISOCHRONOUS:
01735 {
01736 dwc_otg_halt_status_e halt_status;
01737 halt_status =
01738 update_isoc_urb_state(hcd, hc, hc_regs, qtd,
01739 DWC_OTG_HC_XFER_FRAME_OVERRUN);
01740
01741 halt_channel(hcd, hc, qtd, halt_status);
01742 }
01743 break;
01744 }
01745
01746 disable_hc_int(hc_regs, frmovrun);
01747
01748 return 1;
01749 }
01750
01755 static int32_t handle_hc_datatglerr_intr(dwc_otg_hcd_t * hcd,
01756 dwc_hc_t * hc,
01757 dwc_otg_hc_regs_t * hc_regs,
01758 dwc_otg_qtd_t * qtd)
01759 {
01760 DWC_DEBUGPL(DBG_HCD, "--Host Channel %d Interrupt: "
01761 "Data Toggle Error--\n", hc->hc_num);
01762
01763 if (hc->ep_is_in) {
01764 qtd->error_count = 0;
01765 } else {
01766 DWC_ERROR("Data Toggle Error on OUT transfer,"
01767 "channel %d\n", hc->hc_num);
01768 }
01769
01770 disable_hc_int(hc_regs, datatglerr);
01771
01772 return 1;
01773 }
01774
01775 #ifdef DEBUG
01776
01782 static inline int halt_status_ok(dwc_otg_hcd_t * hcd,
01783 dwc_hc_t * hc,
01784 dwc_otg_hc_regs_t * hc_regs,
01785 dwc_otg_qtd_t * qtd)
01786 {
01787 hcchar_data_t hcchar;
01788 hctsiz_data_t hctsiz;
01789 hcint_data_t hcint;
01790 hcintmsk_data_t hcintmsk;
01791 hcsplt_data_t hcsplt;
01792
01793 if (hc->halt_status == DWC_OTG_HC_XFER_NO_HALT_STATUS) {
01794
01795
01796
01797
01798 hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
01799 hctsiz.d32 = DWC_READ_REG32(&hc_regs->hctsiz);
01800 hcint.d32 = DWC_READ_REG32(&hc_regs->hcint);
01801 hcintmsk.d32 = DWC_READ_REG32(&hc_regs->hcintmsk);
01802 hcsplt.d32 = DWC_READ_REG32(&hc_regs->hcsplt);
01803 DWC_WARN
01804 ("%s: hc->halt_status == DWC_OTG_HC_XFER_NO_HALT_STATUS, "
01805 "channel %d, hcchar 0x%08x, hctsiz 0x%08x, "
01806 "hcint 0x%08x, hcintmsk 0x%08x, "
01807 "hcsplt 0x%08x, qtd->complete_split %d\n", __func__,
01808 hc->hc_num, hcchar.d32, hctsiz.d32, hcint.d32,
01809 hcintmsk.d32, hcsplt.d32, qtd->complete_split);
01810
01811 DWC_WARN("%s: no halt status, channel %d, ignoring interrupt\n",
01812 __func__, hc->hc_num);
01813 DWC_WARN("\n");
01814 clear_hc_int(hc_regs, chhltd);
01815 return 0;
01816 }
01817
01818
01819
01820
01821
01822
01823 hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
01824 if (hcchar.b.chdis) {
01825 DWC_WARN("%s: hcchar.chdis set unexpectedly, "
01826 "hcchar 0x%08x, trying to halt again\n",
01827 __func__, hcchar.d32);
01828 clear_hc_int(hc_regs, chhltd);
01829 hc->halt_pending = 0;
01830 halt_channel(hcd, hc, qtd, hc->halt_status);
01831 return 0;
01832 }
01833
01834 return 1;
01835 }
01836 #endif
01837
01842 static void handle_hc_chhltd_intr_dma(dwc_otg_hcd_t * hcd,
01843 dwc_hc_t * hc,
01844 dwc_otg_hc_regs_t * hc_regs,
01845 dwc_otg_qtd_t * qtd)
01846 {
01847 hcint_data_t hcint;
01848 hcintmsk_data_t hcintmsk;
01849 int out_nak_enh = 0;
01850
01851
01852
01853
01854 if (hcd->core_if->snpsid >= OTG_CORE_REV_2_71a) {
01855 if (hc->speed == DWC_OTG_EP_SPEED_HIGH && !hc->ep_is_in &&
01856 (hc->ep_type == DWC_OTG_EP_TYPE_CONTROL ||
01857 hc->ep_type == DWC_OTG_EP_TYPE_BULK)) {
01858 out_nak_enh = 1;
01859 }
01860 }
01861
01862 if (hc->halt_status == DWC_OTG_HC_XFER_URB_DEQUEUE ||
01863 (hc->halt_status == DWC_OTG_HC_XFER_AHB_ERR
01864 && !hcd->core_if->dma_desc_enable)) {
01865
01866
01867
01868
01869
01870
01871 if (hcd->core_if->dma_desc_enable)
01872 dwc_otg_hcd_complete_xfer_ddma(hcd, hc, hc_regs,
01873 hc->halt_status);
01874 else
01875 release_channel(hcd, hc, qtd, hc->halt_status);
01876 return;
01877 }
01878
01879
01880 hcint.d32 = DWC_READ_REG32(&hc_regs->hcint);
01881 hcintmsk.d32 = DWC_READ_REG32(&hc_regs->hcintmsk);
01882
01883 if (hcint.b.xfercomp) {
01890 if (hc->ep_type == DWC_OTG_EP_TYPE_ISOC && !hc->ep_is_in) {
01891 handle_hc_ack_intr(hcd, hc, hc_regs, qtd);
01892 }
01893 handle_hc_xfercomp_intr(hcd, hc, hc_regs, qtd);
01894 } else if (hcint.b.stall) {
01895 handle_hc_stall_intr(hcd, hc, hc_regs, qtd);
01896 } else if (hcint.b.xacterr && !hcd->core_if->dma_desc_enable) {
01897 if (out_nak_enh) {
01898 if (hcint.b.nyet || hcint.b.nak || hcint.b.ack) {
01899 DWC_DEBUG("XactErr with NYET/NAK/ACK\n");
01900 qtd->error_count = 0;
01901 } else {
01902 DWC_DEBUG("XactErr without NYET/NAK/ACK\n");
01903 }
01904 }
01905
01906
01907
01908
01909
01910
01911 handle_hc_xacterr_intr(hcd, hc, hc_regs, qtd);
01912 } else if (hcint.b.xcs_xact && hcd->core_if->dma_desc_enable) {
01913 handle_hc_xacterr_intr(hcd, hc, hc_regs, qtd);
01914 } else if (hcint.b.ahberr && hcd->core_if->dma_desc_enable) {
01915 handle_hc_ahberr_intr(hcd, hc, hc_regs, qtd);
01916 } else if (hcint.b.bblerr) {
01917 handle_hc_babble_intr(hcd, hc, hc_regs, qtd);
01918 } else if (hcint.b.frmovrun) {
01919 handle_hc_frmovrun_intr(hcd, hc, hc_regs, qtd);
01920 } else if (!out_nak_enh) {
01921 if (hcint.b.nyet) {
01922
01923
01924
01925
01926
01927 handle_hc_nyet_intr(hcd, hc, hc_regs, qtd);
01928 } else if (hcint.b.nak && !hcintmsk.b.nak) {
01929
01930
01931
01932
01933
01934
01935
01936 handle_hc_nak_intr(hcd, hc, hc_regs, qtd);
01937 } else if (hcint.b.ack && !hcintmsk.b.ack) {
01938
01939
01940
01941
01942
01943
01944 handle_hc_ack_intr(hcd, hc, hc_regs, qtd);
01945 } else {
01946 if (hc->ep_type == DWC_OTG_EP_TYPE_INTR ||
01947 hc->ep_type == DWC_OTG_EP_TYPE_ISOC) {
01948
01949
01950
01951
01952
01953
01954 #ifdef DEBUG
01955 DWC_PRINTF
01956 ("%s: Halt channel %d (assume incomplete periodic transfer)\n",
01957 __func__, hc->hc_num);
01958 #endif
01959 halt_channel(hcd, hc, qtd,
01960 DWC_OTG_HC_XFER_PERIODIC_INCOMPLETE);
01961 } else {
01962 DWC_ERROR
01963 ("%s: Channel %d, DMA Mode -- ChHltd set, but reason "
01964 "for halting is unknown, hcint 0x%08x, intsts 0x%08x\n",
01965 __func__, hc->hc_num, hcint.d32,
01966 DWC_READ_REG32(&hcd->
01967 core_if->core_global_regs->
01968 gintsts));
01969 }
01970
01971 }
01972 } else {
01973 DWC_PRINTF("NYET/NAK/ACK/other in non-error case, 0x%08x\n",
01974 hcint.d32);
01975 }
01976 }
01977
01989 static int32_t handle_hc_chhltd_intr(dwc_otg_hcd_t * hcd,
01990 dwc_hc_t * hc,
01991 dwc_otg_hc_regs_t * hc_regs,
01992 dwc_otg_qtd_t * qtd)
01993 {
01994 DWC_DEBUGPL(DBG_HCD, "--Host Channel %d Interrupt: "
01995 "Channel Halted--\n", hc->hc_num);
01996
01997 if (hcd->core_if->dma_enable) {
01998 handle_hc_chhltd_intr_dma(hcd, hc, hc_regs, qtd);
01999 } else {
02000 #ifdef DEBUG
02001 if (!halt_status_ok(hcd, hc, hc_regs, qtd)) {
02002 return 1;
02003 }
02004 #endif
02005 release_channel(hcd, hc, qtd, hc->halt_status);
02006 }
02007
02008 return 1;
02009 }
02010
02012 int32_t dwc_otg_hcd_handle_hc_n_intr(dwc_otg_hcd_t * dwc_otg_hcd, uint32_t num)
02013 {
02014 int retval = 0;
02015 hcint_data_t hcint;
02016 hcintmsk_data_t hcintmsk;
02017 dwc_hc_t *hc;
02018 dwc_otg_hc_regs_t *hc_regs;
02019 dwc_otg_qtd_t *qtd;
02020
02021 DWC_DEBUGPL(DBG_HCDV, "--Host Channel Interrupt--, Channel %d\n", num);
02022
02023 hc = dwc_otg_hcd->hc_ptr_array[num];
02024 hc_regs = dwc_otg_hcd->core_if->host_if->hc_regs[num];
02025 qtd = DWC_CIRCLEQ_FIRST(&hc->qh->qtd_list);
02026
02027 hcint.d32 = DWC_READ_REG32(&hc_regs->hcint);
02028 hcintmsk.d32 = DWC_READ_REG32(&hc_regs->hcintmsk);
02029 DWC_DEBUGPL(DBG_HCDV,
02030 " hcint 0x%08x, hcintmsk 0x%08x, hcint&hcintmsk 0x%08x\n",
02031 hcint.d32, hcintmsk.d32, (hcint.d32 & hcintmsk.d32));
02032 hcint.d32 = hcint.d32 & hcintmsk.d32;
02033
02034 if (!dwc_otg_hcd->core_if->dma_enable) {
02035 if (hcint.b.chhltd && hcint.d32 != 0x2) {
02036 hcint.b.chhltd = 0;
02037 }
02038 }
02039
02040 if (hcint.b.xfercomp) {
02041 retval |=
02042 handle_hc_xfercomp_intr(dwc_otg_hcd, hc, hc_regs, qtd);
02043
02044
02045
02046
02047
02048 hcint.b.nyet = 0;
02049 }
02050 if (hcint.b.chhltd) {
02051 retval |= handle_hc_chhltd_intr(dwc_otg_hcd, hc, hc_regs, qtd);
02052 }
02053 if (hcint.b.ahberr) {
02054 retval |= handle_hc_ahberr_intr(dwc_otg_hcd, hc, hc_regs, qtd);
02055 }
02056 if (hcint.b.stall) {
02057 retval |= handle_hc_stall_intr(dwc_otg_hcd, hc, hc_regs, qtd);
02058 }
02059 if (hcint.b.nak) {
02060 retval |= handle_hc_nak_intr(dwc_otg_hcd, hc, hc_regs, qtd);
02061 }
02062 if (hcint.b.ack) {
02063 retval |= handle_hc_ack_intr(dwc_otg_hcd, hc, hc_regs, qtd);
02064 }
02065 if (hcint.b.nyet) {
02066 retval |= handle_hc_nyet_intr(dwc_otg_hcd, hc, hc_regs, qtd);
02067 }
02068 if (hcint.b.xacterr) {
02069 retval |= handle_hc_xacterr_intr(dwc_otg_hcd, hc, hc_regs, qtd);
02070 }
02071 if (hcint.b.bblerr) {
02072 retval |= handle_hc_babble_intr(dwc_otg_hcd, hc, hc_regs, qtd);
02073 }
02074 if (hcint.b.frmovrun) {
02075 retval |=
02076 handle_hc_frmovrun_intr(dwc_otg_hcd, hc, hc_regs, qtd);
02077 }
02078 if (hcint.b.datatglerr) {
02079 retval |=
02080 handle_hc_datatglerr_intr(dwc_otg_hcd, hc, hc_regs, qtd);
02081 }
02082
02083 return retval;
02084 }
02085
02086 #endif