Main Page | Data Structures | File List | Data Fields | Globals | Related Pages

dwc_otg_pcd_intr.c

Go to the documentation of this file.
00001 /* ==========================================================================
00002  * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_pcd_intr.c $
00003  * $Revision: #113 $
00004  * $Date: 2011/10/24 $
00005  * $Change: 1871160 $
00006  *
00007  * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
00008  * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
00009  * otherwise expressly agreed to in writing between Synopsys and you.
00010  *
00011  * The Software IS NOT an item of Licensed Software or Licensed Product under
00012  * any End User Software License Agreement or Agreement for Licensed Product
00013  * with Synopsys or any supplement thereto. You are permitted to use and
00014  * redistribute this Software in source and binary forms, with or without
00015  * modification, provided that redistributions of source code must retain this
00016  * notice. You may not view, use, disclose, copy or distribute this file or
00017  * any information contained herein except pursuant to this license grant from
00018  * Synopsys. If you do not agree with this notice, including the disclaimer
00019  * below, then you are not authorized to use the Software.
00020  *
00021  * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
00022  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00023  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00024  * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
00025  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00026  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
00027  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00028  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00029  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00030  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
00031  * DAMAGE.
00032  * ========================================================================== */
00033 #ifndef DWC_HOST_ONLY
00034 
00035 #include "dwc_otg_pcd.h"
00036 
00037 #ifdef DWC_UTE_CFI
00038 #include "dwc_otg_cfi.h"
00039 #endif
00040 
00041 #ifdef DWC_UTE_PER_IO
00042 extern void complete_xiso_ep(dwc_otg_pcd_ep_t * ep);
00043 #endif
00044 //#define PRINT_CFI_DMA_DESCS
00045 
00046 #define DEBUG_EP0
00047 
00051 static void dwc_otg_pcd_update_otg(dwc_otg_pcd_t * pcd, const unsigned reset)
00052 {
00053 
00054         if (reset) {
00055                 pcd->b_hnp_enable = 0;
00056                 pcd->a_hnp_support = 0;
00057                 pcd->a_alt_hnp_support = 0;
00058         }
00059 
00060         if (pcd->fops->hnp_changed) {
00061                 pcd->fops->hnp_changed(pcd);
00062         }
00063 }
00064 
00079 static inline void print_ep0_state(dwc_otg_pcd_t * pcd)
00080 {
00081 #ifdef DEBUG
00082         char str[40];
00083 
00084         switch (pcd->ep0state) {
00085         case EP0_DISCONNECT:
00086                 dwc_strcpy(str, "EP0_DISCONNECT");
00087                 break;
00088         case EP0_IDLE:
00089                 dwc_strcpy(str, "EP0_IDLE");
00090                 break;
00091         case EP0_IN_DATA_PHASE:
00092                 dwc_strcpy(str, "EP0_IN_DATA_PHASE");
00093                 break;
00094         case EP0_OUT_DATA_PHASE:
00095                 dwc_strcpy(str, "EP0_OUT_DATA_PHASE");
00096                 break;
00097         case EP0_IN_STATUS_PHASE:
00098                 dwc_strcpy(str, "EP0_IN_STATUS_PHASE");
00099                 break;
00100         case EP0_OUT_STATUS_PHASE:
00101                 dwc_strcpy(str, "EP0_OUT_STATUS_PHASE");
00102                 break;
00103         case EP0_STALL:
00104                 dwc_strcpy(str, "EP0_STALL");
00105                 break;
00106         default:
00107                 dwc_strcpy(str, "EP0_INVALID");
00108         }
00109 
00110         DWC_DEBUGPL(DBG_ANY, "%s(%d)\n", str, pcd->ep0state);
00111 #endif
00112 }
00113 
00119 static inline void print_memory_payload(dwc_otg_pcd_t * pcd,  dwc_ep_t * ep)
00120 {
00121 #ifdef DEBUG
00122         deptsiz_data_t deptsiz_init = {.d32 = 0 };
00123         deptsiz_data_t deptsiz_updt = {.d32 = 0 };
00124         int pack_num;
00125         unsigned payload;
00126         
00127         deptsiz_init.d32 = pcd->core_if->start_doeptsiz_val[ep->num];
00128         deptsiz_updt.d32 =
00129                 DWC_READ_REG32(&pcd->core_if->dev_if->
00130                                                 out_ep_regs[ep->num]->doeptsiz);
00131         /* Payload will be */
00132         payload = deptsiz_init.b.xfersize - deptsiz_updt.b.xfersize;
00133         /* Packet count is decremented every time a packet
00134          * is written to the RxFIFO not in to the external memory
00135          * So, if payload == 0, then it means no packet was sent to ext memory*/
00136         pack_num = (!payload) ? 0 : (deptsiz_init.b.pktcnt - deptsiz_updt.b.pktcnt);
00137         DWC_DEBUGPL(DBG_PCDV,
00138                 "Payload for EP%d-%s\n",
00139                 ep->num, (ep->is_in ? "IN" : "OUT"));
00140         DWC_DEBUGPL(DBG_PCDV,
00141                 "Number of transfered bytes = 0x%08x\n", payload);
00142         DWC_DEBUGPL(DBG_PCDV,
00143                 "Number of transfered packets = %d\n", pack_num);       
00144 #endif  
00145 }
00146 
00147 
00148 #ifdef DWC_UTE_CFI
00149 static inline void print_desc(struct dwc_otg_dma_desc *ddesc,
00150                               const uint8_t * epname, int descnum)
00151 {
00152         CFI_INFO
00153             ("%s DMA_DESC(%d) buf=0x%08x bytes=0x%04x; sp=0x%x; l=0x%x; sts=0x%02x; bs=0x%02x\n",
00154              epname, descnum, ddesc->buf, ddesc->status.b.bytes,
00155              ddesc->status.b.sp, ddesc->status.b.l, ddesc->status.b.sts,
00156              ddesc->status.b.bs);
00157 }
00158 #endif
00159 
00163 static inline dwc_otg_pcd_ep_t *get_in_ep(dwc_otg_pcd_t * pcd, uint32_t ep_num)
00164 {
00165         int i;
00166         int num_in_eps = GET_CORE_IF(pcd)->dev_if->num_in_eps;
00167         if (ep_num == 0) {
00168                 return &pcd->ep0;
00169         } else {
00170                 for (i = 0; i < num_in_eps; ++i) {
00171                         if (pcd->in_ep[i].dwc_ep.num == ep_num)
00172                                 return &pcd->in_ep[i];
00173                 }
00174                 return 0;
00175         }
00176 }
00177 
00181 static inline dwc_otg_pcd_ep_t *get_out_ep(dwc_otg_pcd_t * pcd, uint32_t ep_num)
00182 {
00183         int i;
00184         int num_out_eps = GET_CORE_IF(pcd)->dev_if->num_out_eps;
00185         if (ep_num == 0) {
00186                 return &pcd->ep0;
00187         } else {
00188                 for (i = 0; i < num_out_eps; ++i) {
00189                         if (pcd->out_ep[i].dwc_ep.num == ep_num)
00190                                 return &pcd->out_ep[i];
00191                 }
00192                 return 0;
00193         }
00194 }
00195 
00200 dwc_otg_pcd_ep_t *get_ep_by_addr(dwc_otg_pcd_t * pcd, u16 wIndex)
00201 {
00202         dwc_otg_pcd_ep_t *ep;
00203         uint32_t ep_num = UE_GET_ADDR(wIndex);
00204 
00205         if (ep_num == 0) {
00206                 ep = &pcd->ep0;
00207         } else if (UE_GET_DIR(wIndex) == UE_DIR_IN) {   /* in ep */
00208                 ep = &pcd->in_ep[ep_num - 1];
00209         } else {
00210                 ep = &pcd->out_ep[ep_num - 1];
00211         }
00212 
00213         return ep;
00214 }
00215 
00220 void start_next_request(dwc_otg_pcd_ep_t * ep)
00221 {
00222         dwc_otg_pcd_request_t *req = 0;
00223         uint32_t max_transfer =
00224             GET_CORE_IF(ep->pcd)->core_params->max_transfer_size;
00225 
00226 #ifdef DWC_UTE_CFI
00227         struct dwc_otg_pcd *pcd;
00228         pcd = ep->pcd;
00229 #endif
00230 
00231         if (!DWC_CIRCLEQ_EMPTY(&ep->queue)) {
00232                 req = DWC_CIRCLEQ_FIRST(&ep->queue);
00233 
00234 #ifdef DWC_UTE_CFI
00235                 if (ep->dwc_ep.buff_mode != BM_STANDARD) {
00236                         ep->dwc_ep.cfi_req_len = req->length;
00237                         pcd->cfi->ops.build_descriptors(pcd->cfi, pcd, ep, req);
00238                 } else {
00239 #endif
00240                         /* Setup and start the Transfer */
00241                         if (req->dw_align_buf) {
00242                                 ep->dwc_ep.dma_addr = req->dw_align_buf_dma;
00243                                 ep->dwc_ep.start_xfer_buff = req->dw_align_buf;
00244                                 ep->dwc_ep.xfer_buff = req->dw_align_buf;
00245                         } else {
00246                                 ep->dwc_ep.dma_addr = req->dma;
00247                                 ep->dwc_ep.start_xfer_buff = req->buf;
00248                                 ep->dwc_ep.xfer_buff = req->buf;
00249                         }
00250                         ep->dwc_ep.sent_zlp = 0;
00251                         ep->dwc_ep.total_len = req->length;
00252                         ep->dwc_ep.xfer_len = 0;
00253                         ep->dwc_ep.xfer_count = 0;
00254 
00255                         ep->dwc_ep.maxxfer = max_transfer;
00256                         if (GET_CORE_IF(ep->pcd)->dma_desc_enable) {
00257                                 uint32_t out_max_xfer = DDMA_MAX_TRANSFER_SIZE
00258                                     - (DDMA_MAX_TRANSFER_SIZE % 4);
00259                                 if (ep->dwc_ep.is_in) {
00260                                         if (ep->dwc_ep.maxxfer >
00261                                             DDMA_MAX_TRANSFER_SIZE) {
00262                                                 ep->dwc_ep.maxxfer =
00263                                                     DDMA_MAX_TRANSFER_SIZE;
00264                                         }
00265                                 } else {
00266                                         if (ep->dwc_ep.maxxfer > out_max_xfer) {
00267                                                 ep->dwc_ep.maxxfer =
00268                                                     out_max_xfer;
00269                                         }
00270                                 }
00271                         }
00272                         if (ep->dwc_ep.maxxfer < ep->dwc_ep.total_len) {
00273                                 ep->dwc_ep.maxxfer -=
00274                                     (ep->dwc_ep.maxxfer % ep->dwc_ep.maxpacket);
00275                         }
00276                         if (req->sent_zlp) {
00277                                 if ((ep->dwc_ep.total_len %
00278                                      ep->dwc_ep.maxpacket == 0)
00279                                     && (ep->dwc_ep.total_len != 0)) {
00280                                         ep->dwc_ep.sent_zlp = 1;
00281                                 }
00282 
00283                         }
00284 #ifdef DWC_UTE_CFI
00285                 }
00286 #endif
00287                 dwc_otg_ep_start_transfer(GET_CORE_IF(ep->pcd), &ep->dwc_ep);
00288         } else if (ep->dwc_ep.type == DWC_OTG_EP_TYPE_ISOC) {
00289                 DWC_PRINTF("There are no more ISOC requests \n");
00290                 ep->dwc_ep.frame_num = 0xFFFFFFFF;
00291         }
00292 }
00293 
00298 int32_t dwc_otg_pcd_handle_sof_intr(dwc_otg_pcd_t * pcd)
00299 {
00300         dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
00301 
00302         gintsts_data_t gintsts;
00303 
00304         DWC_DEBUGPL(DBG_PCD, "SOF\n");
00305 
00306         /* Clear interrupt */
00307         gintsts.d32 = 0;
00308         gintsts.b.sofintr = 1;
00309         DWC_WRITE_REG32(&core_if->core_global_regs->gintsts, gintsts.d32);
00310 
00311         return 1;
00312 }
00313 
00331 int32_t dwc_otg_pcd_handle_rx_status_q_level_intr(dwc_otg_pcd_t * pcd)
00332 {
00333         dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
00334         dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
00335         gintmsk_data_t gintmask = {.d32 = 0 };
00336         device_grxsts_data_t status;
00337         dwc_otg_pcd_ep_t *ep;
00338         gintsts_data_t gintsts;
00339 #ifdef DEBUG
00340         static char *dpid_str[] = { "D0", "D2", "D1", "MDATA" };
00341 #endif
00342 
00343         //DWC_DEBUGPL(DBG_PCDV, "%s(%p)\n", __func__, _pcd);
00344         /* Disable the Rx Status Queue Level interrupt */
00345         gintmask.b.rxstsqlvl = 1;
00346         DWC_MODIFY_REG32(&global_regs->gintmsk, gintmask.d32, 0);
00347 
00348         /* Get the Status from the top of the FIFO */
00349         status.d32 = DWC_READ_REG32(&global_regs->grxstsp);
00350 
00351         DWC_DEBUGPL(DBG_PCD, "EP:%d BCnt:%d DPID:%s "
00352                     "pktsts:%x Frame:%d(0x%0x)\n",
00353                     status.b.epnum, status.b.bcnt,
00354                     dpid_str[status.b.dpid],
00355                     status.b.pktsts, status.b.fn, status.b.fn);
00356         /* Get pointer to EP structure */
00357         ep = get_out_ep(pcd, status.b.epnum);
00358 
00359         switch (status.b.pktsts) {
00360         case DWC_DSTS_GOUT_NAK:
00361                 DWC_DEBUGPL(DBG_PCDV, "Global OUT NAK\n");
00362                 break;
00363         case DWC_STS_DATA_UPDT:
00364                 DWC_DEBUGPL(DBG_PCDV, "OUT Data Packet\n");
00365                 if (status.b.bcnt && ep->dwc_ep.xfer_buff) {
00367                         dwc_otg_read_packet(core_if,
00368                                             ep->dwc_ep.xfer_buff,
00369                                             status.b.bcnt);
00370                         ep->dwc_ep.xfer_count += status.b.bcnt;
00371                         ep->dwc_ep.xfer_buff += status.b.bcnt;
00372                 }
00373                 break;
00374         case DWC_STS_XFER_COMP:
00375                 DWC_DEBUGPL(DBG_PCDV, "OUT Complete\n");
00376                 break;
00377         case DWC_DSTS_SETUP_COMP:
00378 #ifdef DEBUG_EP0
00379                 DWC_DEBUGPL(DBG_PCDV, "Setup Complete\n");
00380 #endif
00381                 break;
00382         case DWC_DSTS_SETUP_UPDT:
00383                 dwc_otg_read_setup_packet(core_if, pcd->setup_pkt->d32);
00384 #ifdef DEBUG_EP0
00385                 DWC_DEBUGPL(DBG_PCD,
00386                             "SETUP PKT: %02x.%02x v%04x i%04x l%04x\n",
00387                             pcd->setup_pkt->req.bmRequestType,
00388                             pcd->setup_pkt->req.bRequest,
00389                             UGETW(pcd->setup_pkt->req.wValue),
00390                             UGETW(pcd->setup_pkt->req.wIndex),
00391                             UGETW(pcd->setup_pkt->req.wLength));
00392 #endif
00393                 ep->dwc_ep.xfer_count += status.b.bcnt;
00394                 break;
00395         default:
00396                 DWC_DEBUGPL(DBG_PCDV, "Invalid Packet Status (0x%0x)\n",
00397                             status.b.pktsts);
00398                 break;
00399         }
00400 
00401         /* Enable the Rx Status Queue Level interrupt */
00402         DWC_MODIFY_REG32(&global_regs->gintmsk, 0, gintmask.d32);
00403         /* Clear interrupt */
00404         gintsts.d32 = 0;
00405         gintsts.b.rxstsqlvl = 1;
00406         DWC_WRITE_REG32(&global_regs->gintsts, gintsts.d32);
00407 
00408         //DWC_DEBUGPL(DBG_PCDV, "EXIT: %s\n", __func__);
00409         return 1;
00410 }
00411 
00424 static inline int get_ep_of_last_in_token(dwc_otg_core_if_t * core_if)
00425 {
00426         dwc_otg_device_global_regs_t *dev_global_regs =
00427             core_if->dev_if->dev_global_regs;
00428         const uint32_t TOKEN_Q_DEPTH = core_if->hwcfg2.b.dev_token_q_depth;
00429         /* Number of Token Queue Registers */
00430         const int DTKNQ_REG_CNT = (TOKEN_Q_DEPTH + 7) / 8;
00431         dtknq1_data_t dtknqr1;
00432         uint32_t in_tkn_epnums[4];
00433         int ndx = 0;
00434         int i = 0;
00435         volatile uint32_t *addr = &dev_global_regs->dtknqr1;
00436         int epnum = 0;
00437 
00438         //DWC_DEBUGPL(DBG_PCD,"dev_token_q_depth=%d\n",TOKEN_Q_DEPTH);
00439 
00440         /* Read the DTKNQ Registers */
00441         for (i = 0; i < DTKNQ_REG_CNT; i++) {
00442                 in_tkn_epnums[i] = DWC_READ_REG32(addr);
00443                 DWC_DEBUGPL(DBG_PCDV, "DTKNQR%d=0x%08x\n", i + 1,
00444                             in_tkn_epnums[i]);
00445                 if (addr == &dev_global_regs->dvbusdis) {
00446                         addr = &dev_global_regs->dtknqr3_dthrctl;
00447                 } else {
00448                         ++addr;
00449                 }
00450 
00451         }
00452 
00453         /* Copy the DTKNQR1 data to the bit field. */
00454         dtknqr1.d32 = in_tkn_epnums[0];
00455         /* Get the EP numbers */
00456         in_tkn_epnums[0] = dtknqr1.b.epnums0_5;
00457         ndx = dtknqr1.b.intknwptr - 1;
00458 
00459         //DWC_DEBUGPL(DBG_PCDV,"ndx=%d\n",ndx);
00460         if (ndx == -1) {
00463                 int cnt = TOKEN_Q_DEPTH;
00464                 if (TOKEN_Q_DEPTH <= 6) {
00465                         cnt = TOKEN_Q_DEPTH - 1;
00466                 } else if (TOKEN_Q_DEPTH <= 14) {
00467                         cnt = TOKEN_Q_DEPTH - 7;
00468                 } else if (TOKEN_Q_DEPTH <= 22) {
00469                         cnt = TOKEN_Q_DEPTH - 15;
00470                 } else {
00471                         cnt = TOKEN_Q_DEPTH - 23;
00472                 }
00473                 epnum = (in_tkn_epnums[DTKNQ_REG_CNT - 1] >> (cnt * 4)) & 0xF;
00474         } else {
00475                 if (ndx <= 5) {
00476                         epnum = (in_tkn_epnums[0] >> (ndx * 4)) & 0xF;
00477                 } else if (ndx <= 13) {
00478                         ndx -= 6;
00479                         epnum = (in_tkn_epnums[1] >> (ndx * 4)) & 0xF;
00480                 } else if (ndx <= 21) {
00481                         ndx -= 14;
00482                         epnum = (in_tkn_epnums[2] >> (ndx * 4)) & 0xF;
00483                 } else if (ndx <= 29) {
00484                         ndx -= 22;
00485                         epnum = (in_tkn_epnums[3] >> (ndx * 4)) & 0xF;
00486                 }
00487         }
00488         //DWC_DEBUGPL(DBG_PCD,"epnum=%d\n",epnum);
00489         return epnum;
00490 }
00491 
00497 int32_t dwc_otg_pcd_handle_np_tx_fifo_empty_intr(dwc_otg_pcd_t * pcd)
00498 {
00499         dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
00500         dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
00501         dwc_otg_dev_in_ep_regs_t *ep_regs;
00502         gnptxsts_data_t txstatus = {.d32 = 0 };
00503         gintsts_data_t gintsts;
00504 
00505         int epnum = 0;
00506         dwc_otg_pcd_ep_t *ep = 0;
00507         uint32_t len = 0;
00508         int dwords;
00509 
00510         /* Get the epnum from the IN Token Learning Queue. */
00511         epnum = get_ep_of_last_in_token(core_if);
00512         ep = get_in_ep(pcd, epnum);
00513 
00514         DWC_DEBUGPL(DBG_PCD, "NP TxFifo Empty: %d \n", epnum);
00515 
00516         ep_regs = core_if->dev_if->in_ep_regs[epnum];
00517 
00518         len = ep->dwc_ep.xfer_len - ep->dwc_ep.xfer_count;
00519         if (len > ep->dwc_ep.maxpacket) {
00520                 len = ep->dwc_ep.maxpacket;
00521         }
00522         dwords = (len + 3) / 4;
00523 
00524         /* While there is space in the queue and space in the FIFO and
00525          * More data to tranfer, Write packets to the Tx FIFO */
00526         txstatus.d32 = DWC_READ_REG32(&global_regs->gnptxsts);
00527         DWC_DEBUGPL(DBG_PCDV, "b4 GNPTXSTS=0x%08x\n", txstatus.d32);
00528 
00529         while (txstatus.b.nptxqspcavail > 0 &&
00530                txstatus.b.nptxfspcavail > dwords &&
00531                ep->dwc_ep.xfer_count < ep->dwc_ep.xfer_len) {
00532                 /* Write the FIFO */
00533                 dwc_otg_ep_write_packet(core_if, &ep->dwc_ep, 0);
00534                 len = ep->dwc_ep.xfer_len - ep->dwc_ep.xfer_count;
00535 
00536                 if (len > ep->dwc_ep.maxpacket) {
00537                         len = ep->dwc_ep.maxpacket;
00538                 }
00539 
00540                 dwords = (len + 3) / 4;
00541                 txstatus.d32 = DWC_READ_REG32(&global_regs->gnptxsts);
00542                 DWC_DEBUGPL(DBG_PCDV, "GNPTXSTS=0x%08x\n", txstatus.d32);
00543         }
00544 
00545         DWC_DEBUGPL(DBG_PCDV, "GNPTXSTS=0x%08x\n",
00546                     DWC_READ_REG32(&global_regs->gnptxsts));
00547 
00548         /* Clear interrupt */
00549         gintsts.d32 = 0;
00550         gintsts.b.nptxfempty = 1;
00551         DWC_WRITE_REG32(&global_regs->gintsts, gintsts.d32);
00552 
00553         return 1;
00554 }
00555 
00561 static int32_t write_empty_tx_fifo(dwc_otg_pcd_t * pcd, uint32_t epnum)
00562 {
00563         dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
00564         dwc_otg_dev_if_t *dev_if = core_if->dev_if;
00565         dwc_otg_dev_in_ep_regs_t *ep_regs;
00566         dtxfsts_data_t txstatus = {.d32 = 0 };
00567         dwc_otg_pcd_ep_t *ep = 0;
00568         uint32_t len = 0;
00569         int dwords;
00570 
00571         ep = get_in_ep(pcd, epnum);
00572 
00573         DWC_DEBUGPL(DBG_PCD, "Dedicated TxFifo Empty: %d \n", epnum);
00574 
00575         ep_regs = core_if->dev_if->in_ep_regs[epnum];
00576 
00577         len = ep->dwc_ep.xfer_len - ep->dwc_ep.xfer_count;
00578 
00579         if (len > ep->dwc_ep.maxpacket) {
00580                 len = ep->dwc_ep.maxpacket;
00581         }
00582 
00583         dwords = (len + 3) / 4;
00584 
00585         /* While there is space in the queue and space in the FIFO and
00586          * More data to tranfer, Write packets to the Tx FIFO */
00587         txstatus.d32 = DWC_READ_REG32(&dev_if->in_ep_regs[epnum]->dtxfsts);
00588         DWC_DEBUGPL(DBG_PCDV, "b4 dtxfsts[%d]=0x%08x\n", epnum, txstatus.d32);
00589 
00590         while (txstatus.b.txfspcavail > dwords &&
00591                ep->dwc_ep.xfer_count < ep->dwc_ep.xfer_len &&
00592                ep->dwc_ep.xfer_len != 0) {
00593                 /* Write the FIFO */
00594                 dwc_otg_ep_write_packet(core_if, &ep->dwc_ep, 0);
00595 
00596                 len = ep->dwc_ep.xfer_len - ep->dwc_ep.xfer_count;
00597                 if (len > ep->dwc_ep.maxpacket) {
00598                         len = ep->dwc_ep.maxpacket;
00599                 }
00600 
00601                 dwords = (len + 3) / 4;
00602                 txstatus.d32 =
00603                     DWC_READ_REG32(&dev_if->in_ep_regs[epnum]->dtxfsts);
00604                 DWC_DEBUGPL(DBG_PCDV, "dtxfsts[%d]=0x%08x\n", epnum,
00605                             txstatus.d32);
00606         }
00607 
00608         DWC_DEBUGPL(DBG_PCDV, "b4 dtxfsts[%d]=0x%08x\n", epnum,
00609                     DWC_READ_REG32(&dev_if->in_ep_regs[epnum]->dtxfsts));
00610 
00611         return 1;
00612 }
00613 
00619 void dwc_otg_pcd_stop(dwc_otg_pcd_t * pcd)
00620 {
00621         int i, num_in_eps, num_out_eps;
00622         dwc_otg_pcd_ep_t *ep;
00623 
00624         gintmsk_data_t intr_mask = {.d32 = 0 };
00625 
00626         DWC_SPINLOCK(pcd->lock);
00627 
00628         num_in_eps = GET_CORE_IF(pcd)->dev_if->num_in_eps;
00629         num_out_eps = GET_CORE_IF(pcd)->dev_if->num_out_eps;
00630 
00631         DWC_DEBUGPL(DBG_PCDV, "%s() \n", __func__);
00632         /* don't disconnect drivers more than once */
00633         if (pcd->ep0state == EP0_DISCONNECT) {
00634                 DWC_DEBUGPL(DBG_ANY, "%s() Already Disconnected\n", __func__);
00635                 DWC_SPINUNLOCK(pcd->lock);
00636                 return;
00637         }
00638         pcd->ep0state = EP0_DISCONNECT;
00639 
00640         /* Reset the OTG state. */
00641         dwc_otg_pcd_update_otg(pcd, 1);
00642 
00643         /* Disable the NP Tx Fifo Empty Interrupt. */
00644         intr_mask.b.nptxfempty = 1;
00645         DWC_MODIFY_REG32(&GET_CORE_IF(pcd)->core_global_regs->gintmsk,
00646                          intr_mask.d32, 0);
00647 
00648         /* Flush the FIFOs */
00650         dwc_otg_flush_tx_fifo(GET_CORE_IF(pcd), 0x10);
00651         dwc_otg_flush_rx_fifo(GET_CORE_IF(pcd));
00652 
00653         /* prevent new request submissions, kill any outstanding requests  */
00654         ep = &pcd->ep0;
00655         dwc_otg_request_nuke(ep);
00656         /* prevent new request submissions, kill any outstanding requests  */
00657         for (i = 0; i < num_in_eps; i++) {
00658                 dwc_otg_pcd_ep_t *ep = &pcd->in_ep[i];
00659                 dwc_otg_request_nuke(ep);
00660         }
00661         /* prevent new request submissions, kill any outstanding requests  */
00662         for (i = 0; i < num_out_eps; i++) {
00663                 dwc_otg_pcd_ep_t *ep = &pcd->out_ep[i];
00664                 dwc_otg_request_nuke(ep);
00665         }
00666 
00667         /* report disconnect; the driver is already quiesced */
00668         if (pcd->fops->disconnect) {
00669                 DWC_SPINUNLOCK(pcd->lock);
00670                 pcd->fops->disconnect(pcd);
00671                 DWC_SPINLOCK(pcd->lock);
00672         }
00673         DWC_SPINUNLOCK(pcd->lock);
00674 }
00675 
00679 int32_t dwc_otg_pcd_handle_i2c_intr(dwc_otg_pcd_t * pcd)
00680 {
00681         gintmsk_data_t intr_mask = {.d32 = 0 };
00682         gintsts_data_t gintsts;
00683 
00684         DWC_PRINTF("INTERRUPT Handler not implemented for %s\n", "i2cintr");
00685         intr_mask.b.i2cintr = 1;
00686         DWC_MODIFY_REG32(&GET_CORE_IF(pcd)->core_global_regs->gintmsk,
00687                          intr_mask.d32, 0);
00688 
00689         /* Clear interrupt */
00690         gintsts.d32 = 0;
00691         gintsts.b.i2cintr = 1;
00692         DWC_WRITE_REG32(&GET_CORE_IF(pcd)->core_global_regs->gintsts,
00693                         gintsts.d32);
00694         return 1;
00695 }
00696 
00700 int32_t dwc_otg_pcd_handle_early_suspend_intr(dwc_otg_pcd_t * pcd)
00701 {
00702         gintsts_data_t gintsts;
00703 #if defined(VERBOSE)
00704         DWC_PRINTF("Early Suspend Detected\n");
00705 #endif
00706 
00707         /* Clear interrupt */
00708         gintsts.d32 = 0;
00709         gintsts.b.erlysuspend = 1;
00710         DWC_WRITE_REG32(&GET_CORE_IF(pcd)->core_global_regs->gintsts,
00711                         gintsts.d32);
00712         return 1;
00713 }
00714 
00732 static inline void ep0_out_start(dwc_otg_core_if_t * core_if,
00733                                  dwc_otg_pcd_t * pcd)
00734 {
00735         dwc_otg_dev_if_t *dev_if = core_if->dev_if;
00736         deptsiz0_data_t doeptsize0 = {.d32 = 0 };
00737         dwc_otg_dev_dma_desc_t *dma_desc;
00738         depctl_data_t doepctl = {.d32 = 0 };
00739 
00740 #ifdef VERBOSE
00741         DWC_DEBUGPL(DBG_PCDV, "%s() doepctl0=%0x\n", __func__,
00742                     DWC_READ_REG32(&dev_if->out_ep_regs[0]->doepctl));
00743 #endif
00744 
00745         doeptsize0.b.supcnt = 3;
00746         doeptsize0.b.pktcnt = 1;
00747         doeptsize0.b.xfersize = 8 * 3;
00748 
00749         if (core_if->dma_enable) {
00750                 if (!core_if->dma_desc_enable) {
00752                         DWC_WRITE_REG32(&dev_if->out_ep_regs[0]->doeptsiz,
00753                                         doeptsize0.d32);
00754 
00756                         DWC_WRITE_REG32(&dev_if->out_ep_regs[0]->doepdma,
00757                                         pcd->setup_pkt_dma_handle);
00758                 } else {
00759                         dev_if->setup_desc_index =
00760                             (dev_if->setup_desc_index + 1) & 1;
00761                         dma_desc =
00762                             dev_if->setup_desc_addr[dev_if->setup_desc_index];
00763 
00765                         dma_desc->status.b.bs = BS_HOST_BUSY;
00766                         dma_desc->status.b.l = 1;
00767                         dma_desc->status.b.ioc = 1;
00768                         dma_desc->status.b.bytes = pcd->ep0.dwc_ep.maxpacket;
00769                         dma_desc->buf = pcd->setup_pkt_dma_handle;
00770                         dma_desc->status.b.sts = 0;
00771                         dma_desc->status.b.bs = BS_HOST_READY;
00772 
00774                         DWC_WRITE_REG32(&dev_if->out_ep_regs[0]->doepdma,
00775                                         dev_if->
00776                                         dma_setup_desc_addr
00777                                         [dev_if->setup_desc_index]);
00778                 }
00779 
00780         } else {
00782                 DWC_WRITE_REG32(&dev_if->out_ep_regs[0]->doeptsiz,
00783                                 doeptsize0.d32);
00784         }
00785 
00787         doepctl.b.epena = 1;
00788         doepctl.b.cnak = 1;
00789         DWC_WRITE_REG32(&dev_if->out_ep_regs[0]->doepctl, doepctl.d32);
00790 
00791 #ifdef VERBOSE
00792         DWC_DEBUGPL(DBG_PCDV, "doepctl0=%0x\n",
00793                     DWC_READ_REG32(&dev_if->out_ep_regs[0]->doepctl));
00794         DWC_DEBUGPL(DBG_PCDV, "diepctl0=%0x\n",
00795                     DWC_READ_REG32(&dev_if->in_ep_regs[0]->diepctl));
00796 #endif
00797 }
00798 
00822 int32_t dwc_otg_pcd_handle_usb_reset_intr(dwc_otg_pcd_t * pcd)
00823 {
00824         dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
00825         dwc_otg_dev_if_t *dev_if = core_if->dev_if;
00826         depctl_data_t doepctl = {.d32 = 0 };
00827         depctl_data_t diepctl = {.d32 = 0 };
00828         daint_data_t daintmsk = {.d32 = 0 };
00829         doepmsk_data_t doepmsk = {.d32 = 0 };
00830         diepmsk_data_t diepmsk = {.d32 = 0 };
00831         dcfg_data_t dcfg = {.d32 = 0 };
00832         grstctl_t resetctl = {.d32 = 0 };
00833         dctl_data_t dctl = {.d32 = 0 };
00834         int i = 0;
00835         gintsts_data_t gintsts;
00836         pcgcctl_data_t power = {.d32 = 0 };
00837 
00838         power.d32 = DWC_READ_REG32(core_if->pcgcctl);
00839         if (power.b.stoppclk) {
00840                 power.d32 = 0;
00841                 power.b.stoppclk = 1;
00842                 DWC_MODIFY_REG32(core_if->pcgcctl, power.d32, 0);
00843 
00844                 power.b.pwrclmp = 1;
00845                 DWC_MODIFY_REG32(core_if->pcgcctl, power.d32, 0);
00846 
00847                 power.b.rstpdwnmodule = 1;
00848                 DWC_MODIFY_REG32(core_if->pcgcctl, power.d32, 0);
00849         }
00850 
00851         core_if->lx_state = DWC_OTG_L0;
00852 
00853         DWC_PRINTF("USB RESET\n");
00854 #ifdef DWC_EN_ISOC
00855         for (i = 1; i < 16; ++i) {
00856                 dwc_otg_pcd_ep_t *ep;
00857                 dwc_ep_t *dwc_ep;
00858                 ep = get_in_ep(pcd, i);
00859                 if (ep != 0) {
00860                         dwc_ep = &ep->dwc_ep;
00861                         dwc_ep->next_frame = 0xffffffff;
00862                 }
00863         }
00864 #endif /* DWC_EN_ISOC */
00865 
00866         /* reset the HNP settings */
00867         dwc_otg_pcd_update_otg(pcd, 1);
00868 
00869         /* Clear the Remote Wakeup Signalling */
00870         dctl.b.rmtwkupsig = 1;
00871         DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->dctl, dctl.d32, 0);
00872 
00873         /* Set NAK for all OUT EPs */
00874         doepctl.b.snak = 1;
00875         for (i = 0; i <= dev_if->num_out_eps; i++) {
00876                 DWC_WRITE_REG32(&dev_if->out_ep_regs[i]->doepctl, doepctl.d32);
00877         }
00878 
00879         /* Flush the NP Tx FIFO */
00880         dwc_otg_flush_tx_fifo(core_if, 0x10);
00881         /* Flush the Learning Queue */
00882         resetctl.b.intknqflsh = 1;
00883         DWC_WRITE_REG32(&core_if->core_global_regs->grstctl, resetctl.d32);
00884 
00885         if (!core_if->core_params->en_multiple_tx_fifo && core_if->dma_enable) {
00886                 core_if->start_predict = 0;
00887                 for (i = 0; i<= core_if->dev_if->num_in_eps; ++i) {
00888                         core_if->nextep_seq[i] = 0xff;  // 0xff - EP not active
00889                 }
00890                 core_if->nextep_seq[0] = 0;     
00891                 core_if->first_in_nextep_seq = 0;
00892                 diepctl.d32 = DWC_READ_REG32(&dev_if->in_ep_regs[0]->diepctl);
00893                 diepctl.b.nextep = 0;
00894                 DWC_WRITE_REG32(&dev_if->in_ep_regs[0]->diepctl, diepctl.d32);
00895                 
00896                 /* Update IN Endpoint Mismatch Count by active IN NP EP count + 1 */
00897                 dcfg.d32 = DWC_READ_REG32(&dev_if->dev_global_regs->dcfg);
00898                 dcfg.b.epmscnt = 2;
00899                 DWC_WRITE_REG32(&dev_if->dev_global_regs->dcfg, dcfg.d32);
00900 
00901                 DWC_DEBUGPL(DBG_PCDV,"%s first_in_nextep_seq= %2d; nextep_seq[]:\n", 
00902                         __func__, core_if->first_in_nextep_seq);
00903                 for (i=0; i <= core_if->dev_if->num_in_eps; i++) {
00904                         DWC_DEBUGPL(DBG_PCDV, "%2d\n", core_if->nextep_seq[i]);
00905                 }
00906         }
00907 
00908         if (core_if->multiproc_int_enable) {
00909                 daintmsk.b.inep0 = 1;
00910                 daintmsk.b.outep0 = 1;
00911                 DWC_WRITE_REG32(&dev_if->dev_global_regs->deachintmsk,
00912                                 daintmsk.d32);
00913 
00914                 doepmsk.b.setup = 1;
00915                 doepmsk.b.xfercompl = 1;
00916                 doepmsk.b.ahberr = 1;
00917                 doepmsk.b.epdisabled = 1;
00918 
00919                 if (core_if->dma_desc_enable) {
00920                         doepmsk.b.stsphsercvd = 1;
00921                         doepmsk.b.bna = 1;
00922                 }
00923 /*              
00924                 doepmsk.b.babble = 1;
00925                 doepmsk.b.nyet = 1;
00926                 
00927                 if (core_if->dma_enable) {
00928                         doepmsk.b.nak = 1;
00929                 }
00930 */
00931                 DWC_WRITE_REG32(&dev_if->dev_global_regs->doepeachintmsk[0],
00932                                 doepmsk.d32);
00933 
00934                 diepmsk.b.xfercompl = 1;
00935                 diepmsk.b.timeout = 1;
00936                 diepmsk.b.epdisabled = 1;
00937                 diepmsk.b.ahberr = 1;
00938                 diepmsk.b.intknepmis = 1; 
00939                 if (!core_if->en_multiple_tx_fifo && core_if->dma_enable)
00940                         diepmsk.b.intknepmis = 0; 
00941 
00942 /*              if (core_if->dma_desc_enable) {
00943                         diepmsk.b.bna = 1;
00944                 }
00945 */
00946 /*              
00947                 if (core_if->dma_enable) {
00948                         diepmsk.b.nak = 1;
00949                 }
00950 */
00951                 DWC_WRITE_REG32(&dev_if->dev_global_regs->diepeachintmsk[0],
00952                                 diepmsk.d32);
00953         } else {
00954                 daintmsk.b.inep0 = 1;
00955                 daintmsk.b.outep0 = 1;
00956                 DWC_WRITE_REG32(&dev_if->dev_global_regs->daintmsk,
00957                                 daintmsk.d32);
00958 
00959                 doepmsk.b.setup = 1;
00960                 doepmsk.b.xfercompl = 1;
00961                 doepmsk.b.ahberr = 1;
00962                 doepmsk.b.epdisabled = 1;
00963 
00964                 if (core_if->dma_desc_enable) {
00965                         doepmsk.b.stsphsercvd = 1;
00966                         doepmsk.b.bna = 1;
00967                 }
00968                 DWC_WRITE_REG32(&dev_if->dev_global_regs->doepmsk, doepmsk.d32);
00969 
00970                 diepmsk.b.xfercompl = 1;
00971                 diepmsk.b.timeout = 1;
00972                 diepmsk.b.epdisabled = 1;
00973                 diepmsk.b.ahberr = 1;
00974                 if (!core_if->en_multiple_tx_fifo && core_if->dma_enable)
00975                         diepmsk.b.intknepmis = 0; 
00976 /*
00977                 if (core_if->dma_desc_enable) {
00978                         diepmsk.b.bna = 1;
00979                 }
00980 */
00981 
00982                 DWC_WRITE_REG32(&dev_if->dev_global_regs->diepmsk, diepmsk.d32);
00983         }
00984 
00985         /* Reset Device Address */
00986         dcfg.d32 = DWC_READ_REG32(&dev_if->dev_global_regs->dcfg);
00987         dcfg.b.devaddr = 0;
00988         DWC_WRITE_REG32(&dev_if->dev_global_regs->dcfg, dcfg.d32);
00989 
00990         /* setup EP0 to receive SETUP packets */
00991         ep0_out_start(core_if, pcd);
00992 
00993         /* Clear interrupt */
00994         gintsts.d32 = 0;
00995         gintsts.b.usbreset = 1;
00996         DWC_WRITE_REG32(&core_if->core_global_regs->gintsts, gintsts.d32);
00997 
00998         return 1;
00999 }
01000 
01007 static int get_device_speed(dwc_otg_core_if_t * core_if)
01008 {
01009         dsts_data_t dsts;
01010         int speed = 0;
01011         dsts.d32 = DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dsts);
01012 
01013         switch (dsts.b.enumspd) {
01014         case DWC_DSTS_ENUMSPD_HS_PHY_30MHZ_OR_60MHZ:
01015                 speed = USB_SPEED_HIGH;
01016                 break;
01017         case DWC_DSTS_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ:
01018         case DWC_DSTS_ENUMSPD_FS_PHY_48MHZ:
01019                 speed = USB_SPEED_FULL;
01020                 break;
01021 
01022         case DWC_DSTS_ENUMSPD_LS_PHY_6MHZ:
01023                 speed = USB_SPEED_LOW;
01024                 break;
01025         }
01026 
01027         return speed;
01028 }
01029 
01035 int32_t dwc_otg_pcd_handle_enum_done_intr(dwc_otg_pcd_t * pcd)
01036 {
01037         dwc_otg_pcd_ep_t *ep0 = &pcd->ep0;
01038         gintsts_data_t gintsts;
01039         gusbcfg_data_t gusbcfg;
01040         dwc_otg_core_global_regs_t *global_regs =
01041             GET_CORE_IF(pcd)->core_global_regs;
01042         uint8_t utmi16b, utmi8b;
01043         int speed;
01044         DWC_DEBUGPL(DBG_PCD, "SPEED ENUM\n");
01045 
01046         if (GET_CORE_IF(pcd)->snpsid >= OTG_CORE_REV_2_60a) {
01047                 utmi16b = 6;    //vahrama old value was 6;
01048                 utmi8b = 9;
01049         } else {
01050                 utmi16b = 4;
01051                 utmi8b = 8;
01052         }
01053         dwc_otg_ep0_activate(GET_CORE_IF(pcd), &ep0->dwc_ep);
01054 
01055 #ifdef DEBUG_EP0
01056         print_ep0_state(pcd);
01057 #endif
01058 
01059         if (pcd->ep0state == EP0_DISCONNECT) {
01060                 pcd->ep0state = EP0_IDLE;
01061         } else if (pcd->ep0state == EP0_STALL) {
01062                 pcd->ep0state = EP0_IDLE;
01063         }
01064 
01065         pcd->ep0state = EP0_IDLE;
01066 
01067         ep0->stopped = 0;
01068 
01069         speed = get_device_speed(GET_CORE_IF(pcd));
01070         pcd->fops->connect(pcd, speed);
01071 
01072         /* Set USB turnaround time based on device speed and PHY interface. */
01073         gusbcfg.d32 = DWC_READ_REG32(&global_regs->gusbcfg);
01074         if (speed == USB_SPEED_HIGH) {
01075                 if (GET_CORE_IF(pcd)->hwcfg2.b.hs_phy_type ==
01076                     DWC_HWCFG2_HS_PHY_TYPE_ULPI) {
01077                         /* ULPI interface */
01078                         gusbcfg.b.usbtrdtim = 9;
01079                 }
01080                 if (GET_CORE_IF(pcd)->hwcfg2.b.hs_phy_type ==
01081                     DWC_HWCFG2_HS_PHY_TYPE_UTMI) {
01082                         /* UTMI+ interface */
01083                         if (GET_CORE_IF(pcd)->hwcfg4.b.utmi_phy_data_width == 0) {
01084                                 gusbcfg.b.usbtrdtim = utmi8b;
01085                         } else if (GET_CORE_IF(pcd)->hwcfg4.
01086                                    b.utmi_phy_data_width == 1) {
01087                                 gusbcfg.b.usbtrdtim = utmi16b;
01088                         } else if (GET_CORE_IF(pcd)->
01089                                    core_params->phy_utmi_width == 8) {
01090                                 gusbcfg.b.usbtrdtim = utmi8b;
01091                         } else {
01092                                 gusbcfg.b.usbtrdtim = utmi16b;
01093                         }
01094                 }
01095                 if (GET_CORE_IF(pcd)->hwcfg2.b.hs_phy_type ==
01096                     DWC_HWCFG2_HS_PHY_TYPE_UTMI_ULPI) {
01097                         /* UTMI+  OR  ULPI interface */
01098                         if (gusbcfg.b.ulpi_utmi_sel == 1) {
01099                                 /* ULPI interface */
01100                                 gusbcfg.b.usbtrdtim = 9;
01101                         } else {
01102                                 /* UTMI+ interface */
01103                                 if (GET_CORE_IF(pcd)->
01104                                     core_params->phy_utmi_width == 16) {
01105                                         gusbcfg.b.usbtrdtim = utmi16b;
01106                                 } else {
01107                                         gusbcfg.b.usbtrdtim = utmi8b;
01108                                 }
01109                         }
01110                 }
01111         } else {
01112                 /* Full or low speed */
01113                 gusbcfg.b.usbtrdtim = 9;
01114         }
01115         DWC_WRITE_REG32(&global_regs->gusbcfg, gusbcfg.d32);
01116 
01117         /* Clear interrupt */
01118         gintsts.d32 = 0;
01119         gintsts.b.enumdone = 1;
01120         DWC_WRITE_REG32(&GET_CORE_IF(pcd)->core_global_regs->gintsts,
01121                         gintsts.d32);
01122         return 1;
01123 }
01124 
01130 int32_t dwc_otg_pcd_handle_isoc_out_packet_dropped_intr(dwc_otg_pcd_t * pcd)
01131 {
01132         gintmsk_data_t intr_mask = {.d32 = 0 };
01133         gintsts_data_t gintsts;
01134 
01135         DWC_WARN("INTERRUPT Handler not implemented for %s\n",
01136                  "ISOC Out Dropped");
01137 
01138         intr_mask.b.isooutdrop = 1;
01139         DWC_MODIFY_REG32(&GET_CORE_IF(pcd)->core_global_regs->gintmsk,
01140                          intr_mask.d32, 0);
01141 
01142         /* Clear interrupt */
01143         gintsts.d32 = 0;
01144         gintsts.b.isooutdrop = 1;
01145         DWC_WRITE_REG32(&GET_CORE_IF(pcd)->core_global_regs->gintsts,
01146                         gintsts.d32);
01147 
01148         return 1;
01149 }
01150 
01156 int32_t dwc_otg_pcd_handle_end_periodic_frame_intr(dwc_otg_pcd_t * pcd)
01157 {
01158         gintmsk_data_t intr_mask = {.d32 = 0 };
01159         gintsts_data_t gintsts;
01160         DWC_PRINTF("INTERRUPT Handler not implemented for %s\n", "EOP");
01161 
01162         intr_mask.b.eopframe = 1;
01163         DWC_MODIFY_REG32(&GET_CORE_IF(pcd)->core_global_regs->gintmsk,
01164                          intr_mask.d32, 0);
01165 
01166         /* Clear interrupt */
01167         gintsts.d32 = 0;
01168         gintsts.b.eopframe = 1;
01169         DWC_WRITE_REG32(&GET_CORE_IF(pcd)->core_global_regs->gintsts,
01170                         gintsts.d32);
01171 
01172         return 1;
01173 }
01174 
01184 int32_t dwc_otg_pcd_handle_ep_mismatch_intr(dwc_otg_pcd_t * pcd)
01185 {
01186         gintsts_data_t gintsts;
01187         dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
01188         dctl_data_t dctl;
01189         gintmsk_data_t intr_mask = {.d32 = 0 };
01190 
01191         if (!core_if->en_multiple_tx_fifo && core_if->dma_enable) {
01192                 core_if->start_predict = 1;
01193         
01194                 DWC_DEBUGPL(DBG_PCDV, "%s(%p)\n", __func__, core_if);
01195         
01196                 gintsts.d32 = DWC_READ_REG32(&core_if->core_global_regs->gintsts);
01197                 if (!gintsts.b.ginnakeff) {
01198                         /* Disable EP Mismatch interrupt */
01199                         intr_mask.d32 = 0;
01200                         intr_mask.b.epmismatch = 1;
01201                         DWC_MODIFY_REG32(&core_if->core_global_regs->gintmsk, intr_mask.d32, 0);
01202                         /* Enable the Global IN NAK Effective Interrupt */
01203                         intr_mask.d32 = 0;
01204                         intr_mask.b.ginnakeff = 1;
01205                         DWC_MODIFY_REG32(&core_if->core_global_regs->gintmsk, 0, intr_mask.d32);
01206                         /* Set the global non-periodic IN NAK handshake */
01207                         dctl.d32 = DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dctl);
01208                         dctl.b.sgnpinnak = 1;
01209                         DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->dctl, dctl.d32);
01210                 } else {
01211                         DWC_PRINTF("gintsts.b.ginnakeff = 1! dctl.b.sgnpinnak not set\n");
01212                 }
01213                 /* Disabling of all EP's will be done in dwc_otg_pcd_handle_in_nak_effective()
01214                  * handler after Global IN NAK Effective interrupt will be asserted */
01215         }
01216         /* Clear interrupt */
01217         gintsts.d32 = 0;
01218         gintsts.b.epmismatch = 1;
01219         DWC_WRITE_REG32(&core_if->core_global_regs->gintsts, gintsts.d32);
01220 
01221         return 1;
01222 }
01223 
01232 int32_t dwc_otg_pcd_handle_ep_fetsusp_intr(dwc_otg_pcd_t * pcd)
01233 {
01234         gintsts_data_t gintsts;
01235         gintmsk_data_t gintmsk_data;
01236         dctl_data_t dctl;
01237         dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
01238         DWC_DEBUGPL(DBG_PCDV, "%s(%p)\n", __func__, core_if);
01239         
01240         /* Clear the global non-periodic IN NAK handshake */
01241         dctl.d32 = 0;
01242         dctl.b.cgnpinnak = 1;
01243         DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->dctl, dctl.d32, dctl.d32); 
01244         
01245         /* Mask GINTSTS.FETSUSP interrupt */
01246         gintmsk_data.d32 = DWC_READ_REG32(&core_if->core_global_regs->gintmsk);
01247         gintmsk_data.b.fetsusp = 0;
01248         DWC_WRITE_REG32(&core_if->core_global_regs->gintmsk, gintmsk_data.d32);
01249 
01250         /* Clear interrupt */
01251         gintsts.d32 = 0;
01252         gintsts.b.fetsusp = 1;
01253         DWC_WRITE_REG32(&core_if->core_global_regs->gintsts, gintsts.d32);
01254 
01255         return 1;
01256 }
01260 static inline void ep0_do_stall(dwc_otg_pcd_t * pcd, const int err_val)
01261 {
01262         dwc_otg_pcd_ep_t *ep0 = &pcd->ep0;
01263         usb_device_request_t *ctrl = &pcd->setup_pkt->req;
01264         DWC_WARN("req %02x.%02x protocol STALL; err %d\n",
01265                  ctrl->bmRequestType, ctrl->bRequest, err_val);
01266 
01267         ep0->dwc_ep.is_in = 1;
01268         dwc_otg_ep_set_stall(GET_CORE_IF(pcd), &ep0->dwc_ep);
01269         pcd->ep0.stopped = 1;
01270         pcd->ep0state = EP0_IDLE;
01271         ep0_out_start(GET_CORE_IF(pcd), pcd);
01272 }
01273 
01277 static inline void do_gadget_setup(dwc_otg_pcd_t * pcd,
01278                                    usb_device_request_t * ctrl)
01279 {
01280         int ret = 0;
01281         DWC_SPINUNLOCK(pcd->lock);
01282         ret = pcd->fops->setup(pcd, (uint8_t *) ctrl);
01283         DWC_SPINLOCK(pcd->lock);
01284         if (ret < 0) {
01285                 ep0_do_stall(pcd, ret);
01286         }
01287 
01300         if (ret == 256 + 999) {
01301                 pcd->request_config = 1;
01302         }
01303 }
01304 
01305 #ifdef DWC_UTE_CFI
01306 
01310 static inline int cfi_gadget_setup(dwc_otg_pcd_t * pcd,
01311                                    struct cfi_usb_ctrlrequest *ctrl_req)
01312 {
01313         int ret = 0;
01314 
01315         if (pcd->fops && pcd->fops->cfi_setup) {
01316                 DWC_SPINUNLOCK(pcd->lock);
01317                 ret = pcd->fops->cfi_setup(pcd, ctrl_req);
01318                 DWC_SPINLOCK(pcd->lock);
01319                 if (ret < 0) {
01320                         ep0_do_stall(pcd, ret);
01321                         return ret;
01322                 }
01323         }
01324 
01325         return ret;
01326 }
01327 #endif
01328 
01333 static inline void do_setup_in_status_phase(dwc_otg_pcd_t * pcd)
01334 {
01335         dwc_otg_pcd_ep_t *ep0 = &pcd->ep0;
01336         if (pcd->ep0state == EP0_STALL) {
01337                 return;
01338         }
01339 
01340         pcd->ep0state = EP0_IN_STATUS_PHASE;
01341 
01342         /* Prepare for more SETUP Packets */
01343         DWC_DEBUGPL(DBG_PCD, "EP0 IN ZLP\n");
01344         ep0->dwc_ep.xfer_len = 0;
01345         ep0->dwc_ep.xfer_count = 0;
01346         ep0->dwc_ep.is_in = 1;
01347         ep0->dwc_ep.dma_addr = pcd->setup_pkt_dma_handle;
01348         dwc_otg_ep0_start_transfer(GET_CORE_IF(pcd), &ep0->dwc_ep);
01349 
01350         /* Prepare for more SETUP Packets */
01351         //ep0_out_start(GET_CORE_IF(pcd), pcd);
01352 }
01353 
01358 static inline void do_setup_out_status_phase(dwc_otg_pcd_t * pcd)
01359 {
01360         dwc_otg_pcd_ep_t *ep0 = &pcd->ep0;
01361         if (pcd->ep0state == EP0_STALL) {
01362                 DWC_DEBUGPL(DBG_PCD, "EP0 STALLED\n");
01363                 return;
01364         }
01365         pcd->ep0state = EP0_OUT_STATUS_PHASE;
01366 
01367         DWC_DEBUGPL(DBG_PCD, "EP0 OUT ZLP\n");
01368         ep0->dwc_ep.xfer_len = 0;
01369         ep0->dwc_ep.xfer_count = 0;
01370         ep0->dwc_ep.is_in = 0;
01371         ep0->dwc_ep.dma_addr = pcd->setup_pkt_dma_handle;
01372         dwc_otg_ep0_start_transfer(GET_CORE_IF(pcd), &ep0->dwc_ep);
01373 
01374         /* Prepare for more SETUP Packets */
01375         if (GET_CORE_IF(pcd)->dma_enable == 0) {
01376                 ep0_out_start(GET_CORE_IF(pcd), pcd);
01377         }
01378 }
01379 
01384 static inline void pcd_clear_halt(dwc_otg_pcd_t * pcd, dwc_otg_pcd_ep_t * ep)
01385 {
01386         if (ep->dwc_ep.stall_clear_flag == 0)
01387                 dwc_otg_ep_clear_stall(GET_CORE_IF(pcd), &ep->dwc_ep);
01388 
01389         /* Reactive the EP */
01390         dwc_otg_ep_activate(GET_CORE_IF(pcd), &ep->dwc_ep);
01391         if (ep->stopped) {
01392                 ep->stopped = 0;
01393                 /* If there is a request in the EP queue start it */
01394 
01398                 /*
01399                  * Above fixme is solved by implmenting a tasklet to call the
01400                  * start_next_request(), outside of interrupt context at some
01401                  * time after the current time, after a clear-halt setup packet.
01402                  * Still need to implement ep mismatch in the future if a gadget
01403                  * ever uses more than one endpoint at once
01404                  */
01405                 ep->queue_sof = 1;
01406                 DWC_TASK_SCHEDULE(pcd->start_xfer_tasklet);
01407         }
01408         /* Start Control Status Phase */
01409         do_setup_in_status_phase(pcd);
01410 }
01411 
01423 void do_test_mode(void *data)
01424 {
01425         dctl_data_t dctl;
01426         dwc_otg_pcd_t *pcd = (dwc_otg_pcd_t *) data;
01427         dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
01428         int test_mode = pcd->test_mode;
01429 
01430 //        DWC_WARN("%s() has not been tested since being rewritten!\n", __func__);
01431 
01432         dctl.d32 = DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dctl);
01433         switch (test_mode) {
01434         case 1:         // TEST_J
01435                 dctl.b.tstctl = 1;
01436                 break;
01437 
01438         case 2:         // TEST_K
01439                 dctl.b.tstctl = 2;
01440                 break;
01441 
01442         case 3:         // TEST_SE0_NAK
01443                 dctl.b.tstctl = 3;
01444                 break;
01445 
01446         case 4:         // TEST_PACKET
01447                 dctl.b.tstctl = 4;
01448                 break;
01449 
01450         case 5:         // TEST_FORCE_ENABLE
01451                 dctl.b.tstctl = 5;
01452                 break;
01453         }
01454         DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->dctl, dctl.d32);
01455 }
01456 
01460 static inline void do_get_status(dwc_otg_pcd_t * pcd)
01461 {
01462         usb_device_request_t ctrl = pcd->setup_pkt->req;
01463         dwc_otg_pcd_ep_t *ep;
01464         dwc_otg_pcd_ep_t *ep0 = &pcd->ep0;
01465         uint16_t *status = pcd->status_buf;
01466         dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
01467 
01468 #ifdef DEBUG_EP0
01469         DWC_DEBUGPL(DBG_PCD,
01470                     "GET_STATUS %02x.%02x v%04x i%04x l%04x\n",
01471                     ctrl.bmRequestType, ctrl.bRequest,
01472                     UGETW(ctrl.wValue), UGETW(ctrl.wIndex),
01473                     UGETW(ctrl.wLength));
01474 #endif
01475 
01476         switch (UT_GET_RECIPIENT(ctrl.bmRequestType)) {
01477         case UT_DEVICE:
01478                 if(UGETW(ctrl.wIndex) == 0xF000) { /* OTG Status selector */
01479                         DWC_PRINTF("wIndex - %d\n", UGETW(ctrl.wIndex));
01480                         DWC_PRINTF("OTG VERSION - %d\n", core_if->otg_ver);
01481                         DWC_PRINTF("OTG CAP - %d, %d\n", core_if->core_params->otg_cap,
01482                                                 DWC_OTG_CAP_PARAM_HNP_SRP_CAPABLE);
01483                         if(core_if->otg_ver == 1 && 
01484                         core_if->core_params->otg_cap == DWC_OTG_CAP_PARAM_HNP_SRP_CAPABLE) {
01485                                 uint8_t *otgsts = (uint8_t*)pcd->status_buf;
01486                                 *otgsts = (core_if->otg_sts & 0x1);
01487                                 pcd->ep0_pending = 1;
01488                                 ep0->dwc_ep.start_xfer_buff = (uint8_t *) otgsts;
01489                                 ep0->dwc_ep.xfer_buff = (uint8_t *) otgsts;
01490                                 ep0->dwc_ep.dma_addr = pcd->status_buf_dma_handle;
01491                                 ep0->dwc_ep.xfer_len = 1;
01492                                 ep0->dwc_ep.xfer_count = 0;
01493                                 ep0->dwc_ep.total_len = ep0->dwc_ep.xfer_len;
01494                                 dwc_otg_ep0_start_transfer(GET_CORE_IF(pcd), &ep0->dwc_ep);
01495                                 return;
01496                         } else {
01497                                 ep0_do_stall(pcd, -DWC_E_NOT_SUPPORTED);
01498                                 return;
01499                         }
01500                         break;
01501                 } else {
01502                         *status = 0x1;  /* Self powered */
01503                         *status |= pcd->remote_wakeup_enable << 1;
01504                         break;
01505                 }
01506         case UT_INTERFACE:
01507                 *status = 0;
01508                 break;
01509 
01510         case UT_ENDPOINT:
01511                 ep = get_ep_by_addr(pcd, UGETW(ctrl.wIndex));
01512                 if (ep == 0 || UGETW(ctrl.wLength) > 2) {
01513                         ep0_do_stall(pcd, -DWC_E_NOT_SUPPORTED);
01514                         return;
01515                 }
01517                 *status = ep->stopped;
01518                 break;
01519         }
01520         pcd->ep0_pending = 1;
01521         ep0->dwc_ep.start_xfer_buff = (uint8_t *) status;
01522         ep0->dwc_ep.xfer_buff = (uint8_t *) status;
01523         ep0->dwc_ep.dma_addr = pcd->status_buf_dma_handle;
01524         ep0->dwc_ep.xfer_len = 2;
01525         ep0->dwc_ep.xfer_count = 0;
01526         ep0->dwc_ep.total_len = ep0->dwc_ep.xfer_len;
01527         dwc_otg_ep0_start_transfer(GET_CORE_IF(pcd), &ep0->dwc_ep);
01528 }
01529 
01533 static inline void do_set_feature(dwc_otg_pcd_t * pcd)
01534 {
01535         dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
01536         dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
01537         usb_device_request_t ctrl = pcd->setup_pkt->req;
01538         dwc_otg_pcd_ep_t *ep = 0;
01539         int32_t otg_cap_param = core_if->core_params->otg_cap;
01540         gotgctl_data_t gotgctl = {.d32 = 0 };
01541 
01542         DWC_DEBUGPL(DBG_PCD, "SET_FEATURE:%02x.%02x v%04x i%04x l%04x\n",
01543                     ctrl.bmRequestType, ctrl.bRequest,
01544                     UGETW(ctrl.wValue), UGETW(ctrl.wIndex),
01545                     UGETW(ctrl.wLength));
01546         DWC_DEBUGPL(DBG_PCD, "otg_cap=%d\n", otg_cap_param);
01547 
01548         switch (UT_GET_RECIPIENT(ctrl.bmRequestType)) {
01549         case UT_DEVICE:
01550                 switch (UGETW(ctrl.wValue)) {
01551                 case UF_DEVICE_REMOTE_WAKEUP:
01552                         pcd->remote_wakeup_enable = 1;
01553                         break;
01554 
01555                 case UF_TEST_MODE:
01556                         /* Setup the Test Mode tasklet to do the Test
01557                          * Packet generation after the SETUP Status
01558                          * phase has completed. */
01559 
01563                         pcd->test_mode = UGETW(ctrl.wIndex) >> 8;
01564                         DWC_TASK_SCHEDULE(pcd->test_mode_tasklet);
01565                         break;
01566 
01567                 case UF_DEVICE_B_HNP_ENABLE:
01568                         DWC_DEBUGPL(DBG_PCDV,
01569                                     "SET_FEATURE: USB_DEVICE_B_HNP_ENABLE\n");
01570 
01571                         /* dev may initiate HNP */
01572                         if (otg_cap_param == DWC_OTG_CAP_PARAM_HNP_SRP_CAPABLE) {
01573                                 pcd->b_hnp_enable = 1;
01574                                 dwc_otg_pcd_update_otg(pcd, 0);
01575                                 DWC_DEBUGPL(DBG_PCD, "Request B HNP\n");
01578                                 gotgctl.b.devhnpen = 1;
01579                                 gotgctl.b.hnpreq = 1;
01580                                 DWC_WRITE_REG32(&global_regs->gotgctl,
01581                                                 gotgctl.d32);
01582                         } else {
01583                                 ep0_do_stall(pcd, -DWC_E_NOT_SUPPORTED);
01584                                 return;
01585                         }
01586                         break;
01587 
01588                 case UF_DEVICE_A_HNP_SUPPORT:
01589                         /* RH port supports HNP */
01590                         DWC_DEBUGPL(DBG_PCDV,
01591                                     "SET_FEATURE: USB_DEVICE_A_HNP_SUPPORT\n");
01592                         if (otg_cap_param == DWC_OTG_CAP_PARAM_HNP_SRP_CAPABLE) {
01593                                 pcd->a_hnp_support = 1;
01594                                 dwc_otg_pcd_update_otg(pcd, 0);
01595                         } else {
01596                                 ep0_do_stall(pcd, -DWC_E_NOT_SUPPORTED);
01597                                 return;
01598                         }
01599                         break;
01600 
01601                 case UF_DEVICE_A_ALT_HNP_SUPPORT:
01602                         /* other RH port does */
01603                         DWC_DEBUGPL(DBG_PCDV,
01604                                     "SET_FEATURE: USB_DEVICE_A_ALT_HNP_SUPPORT\n");
01605                         if (otg_cap_param == DWC_OTG_CAP_PARAM_HNP_SRP_CAPABLE) {
01606                                 pcd->a_alt_hnp_support = 1;
01607                                 dwc_otg_pcd_update_otg(pcd, 0);
01608                         } else {
01609                                 ep0_do_stall(pcd, -DWC_E_NOT_SUPPORTED);
01610                                 return;
01611                         }
01612                         break;
01613 
01614                 default:
01615                         ep0_do_stall(pcd, -DWC_E_NOT_SUPPORTED);
01616                         return;
01617 
01618                 }
01619                 do_setup_in_status_phase(pcd);
01620                 break;
01621 
01622         case UT_INTERFACE:
01623                 do_gadget_setup(pcd, &ctrl);
01624                 break;
01625 
01626         case UT_ENDPOINT:
01627                 if (UGETW(ctrl.wValue) == UF_ENDPOINT_HALT) {
01628                         ep = get_ep_by_addr(pcd, UGETW(ctrl.wIndex));
01629                         if (ep == 0) {
01630                                 ep0_do_stall(pcd, -DWC_E_NOT_SUPPORTED);
01631                                 return;
01632                         }
01633                         ep->stopped = 1;
01634                         dwc_otg_ep_set_stall(core_if, &ep->dwc_ep);
01635                 }
01636                 do_setup_in_status_phase(pcd);
01637                 break;
01638         }
01639 }
01640 
01644 static inline void do_clear_feature(dwc_otg_pcd_t * pcd)
01645 {
01646         usb_device_request_t ctrl = pcd->setup_pkt->req;
01647         dwc_otg_pcd_ep_t *ep = 0;
01648 
01649         DWC_DEBUGPL(DBG_PCD,
01650                     "CLEAR_FEATURE:%02x.%02x v%04x i%04x l%04x\n",
01651                     ctrl.bmRequestType, ctrl.bRequest,
01652                     UGETW(ctrl.wValue), UGETW(ctrl.wIndex),
01653                     UGETW(ctrl.wLength));
01654 
01655         switch (UT_GET_RECIPIENT(ctrl.bmRequestType)) {
01656         case UT_DEVICE:
01657                 switch (UGETW(ctrl.wValue)) {
01658                 case UF_DEVICE_REMOTE_WAKEUP:
01659                         pcd->remote_wakeup_enable = 0;
01660                         break;
01661 
01662                 case UF_TEST_MODE:
01664                         break;
01665 
01666                 default:
01667                         ep0_do_stall(pcd, -DWC_E_NOT_SUPPORTED);
01668                         return;
01669                 }
01670                 do_setup_in_status_phase(pcd);
01671                 break;
01672 
01673         case UT_ENDPOINT:
01674                 ep = get_ep_by_addr(pcd, UGETW(ctrl.wIndex));
01675                 if (ep == 0) {
01676                         ep0_do_stall(pcd, -DWC_E_NOT_SUPPORTED);
01677                         return;
01678                 }
01679 
01680                 pcd_clear_halt(pcd, ep);
01681 
01682                 break;
01683         }
01684 }
01685 
01689 static inline void do_set_address(dwc_otg_pcd_t * pcd)
01690 {
01691         dwc_otg_dev_if_t *dev_if = GET_CORE_IF(pcd)->dev_if;
01692         usb_device_request_t ctrl = pcd->setup_pkt->req;
01693 
01694         if (ctrl.bmRequestType == UT_DEVICE) {
01695                 dcfg_data_t dcfg = {.d32 = 0 };
01696 
01697 #ifdef DEBUG_EP0
01698 //                      DWC_DEBUGPL(DBG_PCDV, "SET_ADDRESS:%d\n", ctrl.wValue);
01699 #endif
01700                 dcfg.b.devaddr = UGETW(ctrl.wValue);
01701                 DWC_MODIFY_REG32(&dev_if->dev_global_regs->dcfg, 0, dcfg.d32);
01702                 do_setup_in_status_phase(pcd);
01703         }
01704 }
01705 
01756 static inline void pcd_setup(dwc_otg_pcd_t * pcd)
01757 {
01758         dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
01759         dwc_otg_dev_if_t *dev_if = core_if->dev_if;
01760         usb_device_request_t ctrl = pcd->setup_pkt->req;
01761         dwc_otg_pcd_ep_t *ep0 = &pcd->ep0;
01762 
01763         deptsiz0_data_t doeptsize0 = {.d32 = 0 };
01764 
01765 #ifdef DWC_UTE_CFI
01766         int retval = 0;
01767         struct cfi_usb_ctrlrequest cfi_req;
01768 #endif
01769 
01770 #ifdef DEBUG_EP0
01771         DWC_DEBUGPL(DBG_PCD, "SETUP %02x.%02x v%04x i%04x l%04x\n",
01772                     ctrl.bmRequestType, ctrl.bRequest,
01773                     UGETW(ctrl.wValue), UGETW(ctrl.wIndex),
01774                     UGETW(ctrl.wLength));
01775 #endif
01776 
01777         doeptsize0.d32 = DWC_READ_REG32(&dev_if->out_ep_regs[0]->doeptsiz);
01778 
01781         if (core_if->dma_enable && core_if->dma_desc_enable == 0
01782             && (doeptsize0.b.supcnt < 2)) {
01783                 DWC_ERROR
01784                     ("\n\n-----------    CANNOT handle > 1 setup packet in DMA mode\n\n");
01785         }
01786 
01787         /* Clean up the request queue */
01788         dwc_otg_request_nuke(ep0);
01789         ep0->stopped = 0;
01790 
01791         if (ctrl.bmRequestType & UE_DIR_IN) {
01792                 ep0->dwc_ep.is_in = 1;
01793                 pcd->ep0state = EP0_IN_DATA_PHASE;
01794         } else {
01795                 ep0->dwc_ep.is_in = 0;
01796                 pcd->ep0state = EP0_OUT_DATA_PHASE;
01797         }
01798 
01799         if (UGETW(ctrl.wLength) == 0) {
01800                 ep0->dwc_ep.is_in = 1;
01801                 pcd->ep0state = EP0_IN_STATUS_PHASE;
01802         }
01803 
01804         if (UT_GET_TYPE(ctrl.bmRequestType) != UT_STANDARD) {
01805 
01806 #ifdef DWC_UTE_CFI
01807                 DWC_MEMCPY(&cfi_req, &ctrl, sizeof(usb_device_request_t));
01808 
01809                 //printk(KERN_ALERT "CFI: req_type=0x%02x; req=0x%02x\n", 
01810                                 ctrl.bRequestType, ctrl.bRequest);
01811                 if (UT_GET_TYPE(cfi_req.bRequestType) == UT_VENDOR) {
01812                         if (cfi_req.bRequest > 0xB0 && cfi_req.bRequest < 0xBF) {
01813                                 retval = cfi_setup(pcd, &cfi_req);
01814                                 if (retval < 0) {
01815                                         ep0_do_stall(pcd, retval);
01816                                         pcd->ep0_pending = 0;
01817                                         return;
01818                                 }
01819 
01820                                 /* if need gadget setup then call it and check the retval */
01821                                 if (pcd->cfi->need_gadget_att) {
01822                                         retval =
01823                                             cfi_gadget_setup(pcd,
01824                                                              &pcd->
01825                                                              cfi->ctrl_req);
01826                                         if (retval < 0) {
01827                                                 pcd->ep0_pending = 0;
01828                                                 return;
01829                                         }
01830                                 }
01831 
01832                                 if (pcd->cfi->need_status_in_complete) {
01833                                         do_setup_in_status_phase(pcd);
01834                                 }
01835                                 return;
01836                         }
01837                 }
01838 #endif
01839 
01840                 /* handle non-standard (class/vendor) requests in the gadget driver */
01841                 do_gadget_setup(pcd, &ctrl);
01842                 return;
01843         }
01844 
01847 
01848 
01849 
01850         switch (ctrl.bRequest) {
01851         case UR_GET_STATUS:
01852                 do_get_status(pcd);
01853                 break;
01854 
01855         case UR_CLEAR_FEATURE:
01856                 do_clear_feature(pcd);
01857                 break;
01858 
01859         case UR_SET_FEATURE:
01860                 do_set_feature(pcd);
01861                 break;
01862 
01863         case UR_SET_ADDRESS:
01864                 do_set_address(pcd);
01865                 break;
01866 
01867         case UR_SET_INTERFACE:
01868         case UR_SET_CONFIG:
01869 //              _pcd->request_config = 1;       /* Configuration changed */
01870                 do_gadget_setup(pcd, &ctrl);
01871                 break;
01872 
01873         case UR_SYNCH_FRAME:
01874                 do_gadget_setup(pcd, &ctrl);
01875                 break;
01876 
01877         default:
01878                 /* Call the Gadget Driver's setup functions */
01879                 do_gadget_setup(pcd, &ctrl);
01880                 break;
01881         }
01882 }
01883 
01887 static int32_t ep0_complete_request(dwc_otg_pcd_ep_t * ep)
01888 {
01889         dwc_otg_core_if_t *core_if = GET_CORE_IF(ep->pcd);
01890         dwc_otg_dev_if_t *dev_if = core_if->dev_if;
01891         dwc_otg_dev_in_ep_regs_t *in_ep_regs =
01892             dev_if->in_ep_regs[ep->dwc_ep.num];
01893 #ifdef DEBUG_EP0
01894         dwc_otg_dev_out_ep_regs_t *out_ep_regs =
01895             dev_if->out_ep_regs[ep->dwc_ep.num];
01896 #endif
01897         deptsiz0_data_t deptsiz;
01898         dev_dma_desc_sts_t desc_sts;
01899         dwc_otg_pcd_request_t *req;
01900         int is_last = 0;
01901         dwc_otg_pcd_t *pcd = ep->pcd;
01902 
01903 #ifdef DWC_UTE_CFI
01904         struct cfi_usb_ctrlrequest *ctrlreq;
01905         int retval = -DWC_E_NOT_SUPPORTED;
01906 #endif
01907 
01908         if (pcd->ep0_pending && DWC_CIRCLEQ_EMPTY(&ep->queue)) {
01909                 if (ep->dwc_ep.is_in) {
01910 #ifdef DEBUG_EP0
01911                         DWC_DEBUGPL(DBG_PCDV, "Do setup OUT status phase\n");
01912 #endif
01913                         do_setup_out_status_phase(pcd);
01914                 } else {
01915 #ifdef DEBUG_EP0
01916                         DWC_DEBUGPL(DBG_PCDV, "Do setup IN status phase\n");
01917 #endif
01918 
01919 #ifdef DWC_UTE_CFI
01920                         ctrlreq = &pcd->cfi->ctrl_req;
01921 
01922                         if (UT_GET_TYPE(ctrlreq->bRequestType) == UT_VENDOR) {
01923                                 if (ctrlreq->bRequest > 0xB0
01924                                     && ctrlreq->bRequest < 0xBF) {
01925 
01926                                         /* Return if the PCD failed to handle the request */
01927                                         if ((retval =
01928                                              pcd->cfi->ops.
01929                                              ctrl_write_complete(pcd->cfi,
01930                                                                  pcd)) < 0) {
01931                                                 CFI_INFO
01932                                                     ("ERROR setting a new value in the PCD(%d)\n",
01933                                                      retval);
01934                                                 ep0_do_stall(pcd, retval);
01935                                                 pcd->ep0_pending = 0;
01936                                                 return 0;
01937                                         }
01938 
01939                                         /* If the gadget needs to be notified on the request */
01940                                         if (pcd->cfi->need_gadget_att == 1) {
01941                                                 //retval = do_gadget_setup(pcd, &pcd->cfi->ctrl_req);
01942                                                 retval =
01943                                                     cfi_gadget_setup(pcd,
01944                                                                      &pcd->cfi->
01945                                                                      ctrl_req);
01946 
01947                                                 /* Return from the function if the gadget failed to process
01948                                                  * the request properly - this should never happen !!!
01949                                                  */
01950                                                 if (retval < 0) {
01951                                                         CFI_INFO
01952                                                             ("ERROR setting a new value in the gadget(%d)\n",
01953                                                              retval);
01954                                                         pcd->ep0_pending = 0;
01955                                                         return 0;
01956                                                 }
01957                                         }
01958 
01959                                         CFI_INFO("%s: RETVAL=%d\n", __func__,
01960                                                  retval);
01961                                         /* If we hit here then the PCD and the gadget has properly
01962                                          * handled the request - so send the ZLP IN to the host.
01963                                          */
01964                                         /* @todo: MAS - decide whether we need to start the setup
01965                                          * stage based on the need_setup value of the cfi object
01966                                          */
01967                                         do_setup_in_status_phase(pcd);
01968                                         pcd->ep0_pending = 0;
01969                                         return 1;
01970                                 }
01971                         }
01972 #endif
01973 
01974                         do_setup_in_status_phase(pcd);
01975                 }
01976                 pcd->ep0_pending = 0;
01977                 return 1;
01978         }
01979 
01980         if (DWC_CIRCLEQ_EMPTY(&ep->queue)) {
01981                 return 0;
01982         }
01983         req = DWC_CIRCLEQ_FIRST(&ep->queue);
01984 
01985         if (pcd->ep0state == EP0_OUT_STATUS_PHASE
01986             || pcd->ep0state == EP0_IN_STATUS_PHASE) {
01987                 is_last = 1;
01988         } else if (ep->dwc_ep.is_in) {
01989                 deptsiz.d32 = DWC_READ_REG32(&in_ep_regs->dieptsiz);
01990                 if (core_if->dma_desc_enable != 0)
01991                         desc_sts = dev_if->in_desc_addr->status;
01992 #ifdef DEBUG_EP0
01993                 DWC_DEBUGPL(DBG_PCDV, "%d len=%d  xfersize=%d pktcnt=%d\n",
01994                             ep->dwc_ep.num, ep->dwc_ep.xfer_len,
01995                             deptsiz.b.xfersize, deptsiz.b.pktcnt);
01996 #endif
01997 
01998                 if (((core_if->dma_desc_enable == 0)
01999                      && (deptsiz.b.xfersize == 0))
02000                     || ((core_if->dma_desc_enable != 0)
02001                         && (desc_sts.b.bytes == 0))) {
02002                         req->actual = ep->dwc_ep.xfer_count;
02003                         /* Is a Zero Len Packet needed? */
02004                         if (req->sent_zlp) {
02005 #ifdef DEBUG_EP0
02006                                 DWC_DEBUGPL(DBG_PCD, "Setup Rx ZLP\n");
02007 #endif
02008                                 req->sent_zlp = 0;
02009                         }
02010                         do_setup_out_status_phase(pcd);
02011                 }
02012         } else {
02013                 /* ep0-OUT */
02014 #ifdef DEBUG_EP0
02015                 deptsiz.d32 = DWC_READ_REG32(&out_ep_regs->doeptsiz);
02016                 DWC_DEBUGPL(DBG_PCDV, "%d len=%d xsize=%d pktcnt=%d\n",
02017                             ep->dwc_ep.num, ep->dwc_ep.xfer_len,
02018                             deptsiz.b.xfersize, deptsiz.b.pktcnt);
02019 #endif
02020                 req->actual = ep->dwc_ep.xfer_count;
02021 
02022                 /* Is a Zero Len Packet needed? */
02023                 if (req->sent_zlp) {
02024 #ifdef DEBUG_EP0
02025                         DWC_DEBUGPL(DBG_PCDV, "Setup Tx ZLP\n");
02026 #endif
02027                         req->sent_zlp = 0;
02028                 }
02029                 if (core_if->dma_desc_enable == 0)
02030                         do_setup_in_status_phase(pcd);
02031         }
02032 
02033         /* Complete the request */
02034         if (is_last) {
02035                 dwc_otg_request_done(ep, req, 0);
02036                 ep->dwc_ep.start_xfer_buff = 0;
02037                 ep->dwc_ep.xfer_buff = 0;
02038                 ep->dwc_ep.xfer_len = 0;
02039                 return 1;
02040         }
02041         return 0;
02042 }
02043 
02044 #ifdef DWC_UTE_CFI
02045 
02051 static inline int cfi_calc_desc_residue(dwc_otg_pcd_ep_t * ep)
02052 {
02053         int32_t ret = 0;
02054         int i;
02055         struct dwc_otg_dma_desc *ddesc = NULL;
02056         struct cfi_ep *cfiep;
02057 
02058         /* See if the pcd_ep has its respective cfi_ep mapped */
02059         cfiep = get_cfi_ep_by_pcd_ep(ep->pcd->cfi, ep);
02060         if (!cfiep) {
02061                 CFI_INFO("%s: Failed to find ep\n", __func__);
02062                 return -1;
02063         }
02064 
02065         ddesc = ep->dwc_ep.descs;
02066 
02067         for (i = 0; (i < cfiep->desc_count) && (i < MAX_DMA_DESCS_PER_EP); i++) {
02068 
02069 #if defined(PRINT_CFI_DMA_DESCS)
02070                 print_desc(ddesc, ep->ep.name, i);
02071 #endif
02072                 ret += ddesc->status.b.bytes;
02073                 ddesc++;
02074         }
02075 
02076         if (ret)
02077                 CFI_INFO("!!!!!!!!!! WARNING (%s) - residue=%d\n", __func__,
02078                          ret);
02079 
02080         return ret;
02081 }
02082 #endif
02083 
02088 static void complete_ep(dwc_otg_pcd_ep_t * ep)
02089 {
02090         dwc_otg_core_if_t *core_if = GET_CORE_IF(ep->pcd);
02091         dwc_otg_dev_if_t *dev_if = core_if->dev_if;
02092         dwc_otg_dev_in_ep_regs_t *in_ep_regs =
02093             dev_if->in_ep_regs[ep->dwc_ep.num];
02094         deptsiz_data_t deptsiz;
02095         dev_dma_desc_sts_t desc_sts;
02096         dwc_otg_pcd_request_t *req = 0;
02097         dwc_otg_dev_dma_desc_t *dma_desc;
02098         uint32_t byte_count = 0;
02099         int is_last = 0;
02100         int i;
02101 
02102         DWC_DEBUGPL(DBG_PCDV, "%s() %d-%s\n", __func__, ep->dwc_ep.num,
02103                     (ep->dwc_ep.is_in ? "IN" : "OUT"));
02104 
02105         /* Get any pending requests */
02106         if (!DWC_CIRCLEQ_EMPTY(&ep->queue)) {
02107                 req = DWC_CIRCLEQ_FIRST(&ep->queue);
02108                 if (!req) {
02109                         DWC_PRINTF("complete_ep 0x%p, req = NULL!\n", ep);
02110                         return;
02111                 }
02112         } else {
02113                 DWC_PRINTF("complete_ep 0x%p, ep->queue empty!\n", ep);
02114                 return;
02115         }
02116 
02117         DWC_DEBUGPL(DBG_PCD, "Requests %d\n", ep->pcd->request_pending);
02118 
02119         if (ep->dwc_ep.is_in) {
02120                 deptsiz.d32 = DWC_READ_REG32(&in_ep_regs->dieptsiz);
02121 
02122                 if (core_if->dma_enable) {
02123                         if (core_if->dma_desc_enable == 0) {
02124                                 if (deptsiz.b.xfersize == 0
02125                                     && deptsiz.b.pktcnt == 0) {
02126                                         byte_count =
02127                                             ep->dwc_ep.xfer_len -
02128                                             ep->dwc_ep.xfer_count;
02129 
02130                                         ep->dwc_ep.xfer_buff += byte_count;
02131                                         ep->dwc_ep.dma_addr += byte_count;
02132                                         ep->dwc_ep.xfer_count += byte_count;
02133 
02134                                         DWC_DEBUGPL(DBG_PCDV,
02135                                                     "%d-%s len=%d  xfersize=%d pktcnt=%d\n",
02136                                                     ep->dwc_ep.num,
02137                                                     (ep->dwc_ep.
02138                                                      is_in ? "IN" : "OUT"),
02139                                                     ep->dwc_ep.xfer_len,
02140                                                     deptsiz.b.xfersize,
02141                                                     deptsiz.b.pktcnt);
02142 
02143                                         if (ep->dwc_ep.xfer_len <
02144                                             ep->dwc_ep.total_len) {
02145                                                 dwc_otg_ep_start_transfer
02146                                                     (core_if, &ep->dwc_ep);
02147                                         } else if (ep->dwc_ep.sent_zlp) {
02148                                                 /*     
02149                                                  * This fragment of code should initiate 0
02150                                                  * length transfer in case if it is queued
02151                                                  * a transfer with size divisible to EPs max
02152                                                  * packet size and with usb_request zero field
02153                                                  * is set, which means that after data is transfered,
02154                                                  * it is also should be transfered
02155                                                  * a 0 length packet at the end. For Slave and
02156                                                  * Buffer DMA modes in this case SW has
02157                                                  * to initiate 2 transfers one with transfer size,
02158                                                  * and the second with 0 size. For Descriptor
02159                                                  * DMA mode SW is able to initiate a transfer,
02160                                                  * which will handle all the packets including
02161                                                  * the last  0 length.
02162                                                  */
02163                                                 ep->dwc_ep.sent_zlp = 0;
02164                                                 dwc_otg_ep_start_zl_transfer
02165                                                     (core_if, &ep->dwc_ep);
02166                                         } else {
02167                                                 is_last = 1;
02168                                         }
02169                                 } else {
02170                                         if(ep->dwc_ep.type == DWC_OTG_EP_TYPE_ISOC)
02171                                         {
02172                                                 req->actual = 0;
02173                                                 dwc_otg_request_done(ep, req, 0);
02174 
02175                                                 ep->dwc_ep.start_xfer_buff = 0;
02176                                                 ep->dwc_ep.xfer_buff = 0;
02177                                                 ep->dwc_ep.xfer_len = 0;
02178 
02179                                                 /* If there is a request in the queue start it. */
02180                                                 start_next_request(ep);
02181                                         } else
02182                                                 DWC_WARN
02183                                                 ("Incomplete transfer (%d - %s [siz=%d pkt=%d])\n",
02184                                                 ep->dwc_ep.num,
02185                                                 (ep->dwc_ep.is_in ? "IN" : "OUT"),
02186                                                 deptsiz.b.xfersize,
02187                                                 deptsiz.b.pktcnt);
02188                                 }
02189                         } else {
02190                                 dma_desc = ep->dwc_ep.desc_addr;
02191                                 byte_count = 0;
02192                                 ep->dwc_ep.sent_zlp = 0;
02193 
02194 #ifdef DWC_UTE_CFI
02195                                 CFI_INFO("%s: BUFFER_MODE=%d\n", __func__,
02196                                          ep->dwc_ep.buff_mode);
02197                                 if (ep->dwc_ep.buff_mode != BM_STANDARD) {
02198                                         int residue;
02199 
02200                                         residue = cfi_calc_desc_residue(ep);
02201                                         if (residue < 0)
02202                                                 return;
02203 
02204                                         byte_count = residue;
02205                                 } else {
02206 #endif
02207                                         for (i = 0; i < ep->dwc_ep.desc_cnt;
02208                                              ++i) {
02209                                         desc_sts = dma_desc->status;
02210                                         byte_count += desc_sts.b.bytes;
02211                                         dma_desc++;
02212                                 }
02213 #ifdef DWC_UTE_CFI
02214                                 }
02215 #endif
02216                                 if (byte_count == 0) {
02217                                         ep->dwc_ep.xfer_count =
02218                                             ep->dwc_ep.total_len;
02219                                         is_last = 1;
02220                                 } else {
02221                                         DWC_WARN("Incomplete transfer\n");
02222                                 }
02223                         }
02224                 } else {
02225                         if (deptsiz.b.xfersize == 0 && deptsiz.b.pktcnt == 0) {
02226                                 DWC_DEBUGPL(DBG_PCDV,
02227                                             "%d-%s len=%d  xfersize=%d pktcnt=%d\n",
02228                                             ep->dwc_ep.num,
02229                                             ep->dwc_ep.is_in ? "IN" : "OUT",
02230                                             ep->dwc_ep.xfer_len,
02231                                             deptsiz.b.xfersize,
02232                                             deptsiz.b.pktcnt);
02233 
02234                                 /*      Check if the whole transfer was completed, 
02235                                  *      if no, setup transfer for next portion of data
02236                                  */
02237                                 if (ep->dwc_ep.xfer_len < ep->dwc_ep.total_len) {
02238                                         dwc_otg_ep_start_transfer(core_if,
02239                                                                   &ep->dwc_ep);
02240                                 } else if (ep->dwc_ep.sent_zlp) {
02241                                         /*     
02242                                          * This fragment of code should initiate 0
02243                                          * length trasfer in case if it is queued
02244                                          * a trasfer with size divisible to EPs max
02245                                          * packet size and with usb_request zero field
02246                                          * is set, which means that after data is transfered,
02247                                          * it is also should be transfered
02248                                          * a 0 length packet at the end. For Slave and
02249                                          * Buffer DMA modes in this case SW has
02250                                          * to initiate 2 transfers one with transfer size,
02251                                          * and the second with 0 size. For Desriptor
02252                                          * DMA mode SW is able to initiate a transfer,
02253                                          * which will handle all the packets including
02254                                          * the last  0 legth.
02255                                          */
02256                                         ep->dwc_ep.sent_zlp = 0;
02257                                         dwc_otg_ep_start_zl_transfer(core_if,
02258                                                                      &ep->dwc_ep);
02259                                 } else {
02260                                         is_last = 1;
02261                                 }
02262                         } else {
02263                                 DWC_WARN
02264                                     ("Incomplete transfer (%d-%s [siz=%d pkt=%d])\n",
02265                                      ep->dwc_ep.num,
02266                                      (ep->dwc_ep.is_in ? "IN" : "OUT"),
02267                                      deptsiz.b.xfersize, deptsiz.b.pktcnt);
02268                         }
02269                 }
02270         } else {
02271                 dwc_otg_dev_out_ep_regs_t *out_ep_regs =
02272                     dev_if->out_ep_regs[ep->dwc_ep.num];
02273                 desc_sts.d32 = 0;
02274                 if (core_if->dma_enable) {
02275                         if (core_if->dma_desc_enable) {
02276                                 dma_desc = ep->dwc_ep.desc_addr;
02277                                 byte_count = 0;
02278                                 ep->dwc_ep.sent_zlp = 0;
02279 
02280 #ifdef DWC_UTE_CFI
02281                                 CFI_INFO("%s: BUFFER_MODE=%d\n", __func__,
02282                                          ep->dwc_ep.buff_mode);
02283                                 if (ep->dwc_ep.buff_mode != BM_STANDARD) {
02284                                         int residue;
02285                                         residue = cfi_calc_desc_residue(ep);
02286                                         if (residue < 0)
02287                                                 return;
02288                                         byte_count = residue;
02289                                 } else {
02290 #endif
02291 
02292                                         for (i = 0; i < ep->dwc_ep.desc_cnt;
02293                                              ++i) {
02294                                                 desc_sts = dma_desc->status;
02295                                                 byte_count += desc_sts.b.bytes;
02296                                                 dma_desc++;
02297                                         }
02298 
02299 #ifdef DWC_UTE_CFI
02300                                 }
02301 #endif
02302                                 /* Checking for interrupt Out transfers with not 
02303                                  * dword aligned mps sizes 
02304                                  */
02305                                 if (ep->dwc_ep.type == DWC_OTG_EP_TYPE_INTR &&
02306                                                         (ep->dwc_ep.maxpacket%4)) {
02307                                         ep->dwc_ep.xfer_count = ep->dwc_ep.total_len - byte_count;
02308                                         if ((ep->dwc_ep.xfer_len % ep->dwc_ep.maxpacket) &&
02309                                                 (ep->dwc_ep.xfer_len/ep->dwc_ep.maxpacket < MAX_DMA_DESC_CNT))
02310                                                 ep->dwc_ep.xfer_len -=
02311                                                         (ep->dwc_ep.desc_cnt - 1) * ep->dwc_ep.maxpacket +
02312                                                                         ep->dwc_ep.xfer_len % ep->dwc_ep.maxpacket;
02313                                         else                                            
02314                                                 ep->dwc_ep.xfer_len -=
02315                                                                         ep->dwc_ep.desc_cnt * ep->dwc_ep.maxpacket;
02316                                         if (ep->dwc_ep.xfer_len > 0) {
02317                                                 dwc_otg_ep_start_transfer(core_if,
02318                                                                   &ep->dwc_ep);
02319                                         } else {
02320                                                 is_last = 1;
02321                                         }
02322                                 } else {
02323                                         ep->dwc_ep.xfer_count = ep->dwc_ep.total_len
02324                                                 - byte_count +
02325                                                 ((4 - (ep->dwc_ep.total_len & 0x3)) & 0x3);
02326                                         is_last = 1;
02327                                 }       
02328                         } else {
02329                                 deptsiz.d32 = 0;
02330                                 deptsiz.d32 =
02331                                     DWC_READ_REG32(&out_ep_regs->doeptsiz);
02332 
02333                                 byte_count = (ep->dwc_ep.xfer_len -
02334                                               ep->dwc_ep.xfer_count -
02335                                               deptsiz.b.xfersize);
02336                                 ep->dwc_ep.xfer_buff += byte_count;
02337                                 ep->dwc_ep.dma_addr += byte_count;
02338                                 ep->dwc_ep.xfer_count += byte_count;
02339 
02340                                 /*      Check if the whole transfer was completed, 
02341                                  *      if no, setup transfer for next portion of data
02342                                  */
02343                                 if (ep->dwc_ep.xfer_len < ep->dwc_ep.total_len) {
02344                                         dwc_otg_ep_start_transfer(core_if,
02345                                                                   &ep->dwc_ep);
02346                                 } else if (ep->dwc_ep.sent_zlp) {
02347                                         /*     
02348                                          * This fragment of code should initiate 0
02349                                          * length trasfer in case if it is queued
02350                                          * a trasfer with size divisible to EPs max
02351                                          * packet size and with usb_request zero field
02352                                          * is set, which means that after data is transfered,
02353                                          * it is also should be transfered
02354                                          * a 0 length packet at the end. For Slave and
02355                                          * Buffer DMA modes in this case SW has
02356                                          * to initiate 2 transfers one with transfer size,
02357                                          * and the second with 0 size. For Desriptor
02358                                          * DMA mode SW is able to initiate a transfer,
02359                                          * which will handle all the packets including
02360                                          * the last  0 legth.
02361                                          */
02362                                         ep->dwc_ep.sent_zlp = 0;
02363                                         dwc_otg_ep_start_zl_transfer(core_if,
02364                                                                      &ep->dwc_ep);
02365                                 } else {
02366                                         is_last = 1;
02367                                 }
02368                         }
02369                 } else {
02370                         /*      Check if the whole transfer was completed, 
02371                          *      if no, setup transfer for next portion of data
02372                          */
02373                         if (ep->dwc_ep.xfer_len < ep->dwc_ep.total_len) {
02374                                 dwc_otg_ep_start_transfer(core_if, &ep->dwc_ep);
02375                         } else if (ep->dwc_ep.sent_zlp) {
02376                                 /*     
02377                                  * This fragment of code should initiate 0
02378                                  * length transfer in case if it is queued
02379                                  * a transfer with size divisible to EPs max
02380                                  * packet size and with usb_request zero field
02381                                  * is set, which means that after data is transfered,
02382                                  * it is also should be transfered
02383                                  * a 0 length packet at the end. For Slave and
02384                                  * Buffer DMA modes in this case SW has
02385                                  * to initiate 2 transfers one with transfer size,
02386                                  * and the second with 0 size. For Descriptor
02387                                  * DMA mode SW is able to initiate a transfer,
02388                                  * which will handle all the packets including
02389                                  * the last  0 length.
02390                                  */
02391                                 ep->dwc_ep.sent_zlp = 0;
02392                                 dwc_otg_ep_start_zl_transfer(core_if,
02393                                                              &ep->dwc_ep);
02394                         } else {
02395                                 is_last = 1;
02396                         }
02397                 }
02398 
02399                 DWC_DEBUGPL(DBG_PCDV,
02400                             "addr %p,    %d-%s len=%d cnt=%d xsize=%d pktcnt=%d\n",
02401                             &out_ep_regs->doeptsiz, ep->dwc_ep.num,
02402                             ep->dwc_ep.is_in ? "IN" : "OUT",
02403                             ep->dwc_ep.xfer_len, ep->dwc_ep.xfer_count,
02404                             deptsiz.b.xfersize, deptsiz.b.pktcnt);
02405         }
02406 
02407         /* Complete the request */
02408         if (is_last) {
02409 #ifdef DWC_UTE_CFI
02410                 if (ep->dwc_ep.buff_mode != BM_STANDARD) {
02411                         req->actual = ep->dwc_ep.cfi_req_len - byte_count;
02412                 } else {
02413 #endif
02414                         req->actual = ep->dwc_ep.xfer_count;
02415 #ifdef DWC_UTE_CFI
02416                 }
02417 #endif
02418                 if (req->dw_align_buf) {
02419                         if (!ep->dwc_ep.is_in) {
02420                                 dwc_memcpy(req->buf, req->dw_align_buf, req->length); 
02421                         }
02422                         DWC_DMA_FREE(req->length, req->dw_align_buf,
02423                                      req->dw_align_buf_dma);
02424                 }
02425 
02426                 dwc_otg_request_done(ep, req, 0);
02427 
02428                 ep->dwc_ep.start_xfer_buff = 0;
02429                 ep->dwc_ep.xfer_buff = 0;
02430                 ep->dwc_ep.xfer_len = 0;
02431 
02432                 /* If there is a request in the queue start it. */
02433                 start_next_request(ep);
02434         }
02435 }
02436 
02437 #ifdef DWC_EN_ISOC
02438 
02443 static void dwc_otg_pcd_handle_iso_bna(dwc_otg_pcd_ep_t * ep)
02444 {
02445         dwc_ep_t *dwc_ep = &ep->dwc_ep;
02446         volatile uint32_t *addr;
02447         depctl_data_t depctl = {.d32 = 0 };
02448         dwc_otg_pcd_t *pcd = ep->pcd;
02449         dwc_otg_dev_dma_desc_t *dma_desc;
02450         int i;
02451 
02452         dma_desc =
02453             dwc_ep->iso_desc_addr + dwc_ep->desc_cnt * (dwc_ep->proc_buf_num);
02454 
02455         if (dwc_ep->is_in) {
02456                 dev_dma_desc_sts_t sts = {.d32 = 0 };
02457                 for (i = 0; i < dwc_ep->desc_cnt; ++i, ++dma_desc) {
02458                         sts.d32 = dma_desc->status.d32;
02459                         sts.b_iso_in.bs = BS_HOST_READY;
02460                         dma_desc->status.d32 = sts.d32;
02461                 }
02462         } else {
02463                 dev_dma_desc_sts_t sts = {.d32 = 0 };
02464                 for (i = 0; i < dwc_ep->desc_cnt; ++i, ++dma_desc) {
02465                         sts.d32 = dma_desc->status.d32;
02466                         sts.b_iso_out.bs = BS_HOST_READY;
02467                         dma_desc->status.d32 = sts.d32;
02468                 }
02469         }
02470 
02471         if (dwc_ep->is_in == 0) {
02472                 addr =
02473                     &GET_CORE_IF(pcd)->dev_if->out_ep_regs[dwc_ep->
02474                                                            num]->doepctl;
02475         } else {
02476                 addr =
02477                     &GET_CORE_IF(pcd)->dev_if->in_ep_regs[dwc_ep->num]->diepctl;
02478         }
02479         depctl.b.epena = 1;
02480         DWC_MODIFY_REG32(addr, depctl.d32, depctl.d32);
02481 }
02482 
02490 void set_current_pkt_info(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
02491 {
02492         deptsiz_data_t deptsiz = {.d32 = 0 };
02493         dma_addr_t dma_addr;
02494         uint32_t offset;
02495 
02496         if (ep->proc_buf_num)
02497                 dma_addr = ep->dma_addr1;
02498         else
02499                 dma_addr = ep->dma_addr0;
02500 
02501         if (ep->is_in) {
02502                 deptsiz.d32 =
02503                     DWC_READ_REG32(&core_if->dev_if->
02504                                    in_ep_regs[ep->num]->dieptsiz);
02505                 offset = ep->data_per_frame;
02506         } else {
02507                 deptsiz.d32 =
02508                     DWC_READ_REG32(&core_if->dev_if->
02509                                    out_ep_regs[ep->num]->doeptsiz);
02510                 offset =
02511                     ep->data_per_frame +
02512                     (0x4 & (0x4 - (ep->data_per_frame & 0x3)));
02513         }
02514 
02515         if (!deptsiz.b.xfersize) {
02516                 ep->pkt_info[ep->cur_pkt].length = ep->data_per_frame;
02517                 ep->pkt_info[ep->cur_pkt].offset =
02518                     ep->cur_pkt_dma_addr - dma_addr;
02519                 ep->pkt_info[ep->cur_pkt].status = 0;
02520         } else {
02521                 ep->pkt_info[ep->cur_pkt].length = ep->data_per_frame;
02522                 ep->pkt_info[ep->cur_pkt].offset =
02523                     ep->cur_pkt_dma_addr - dma_addr;
02524                 ep->pkt_info[ep->cur_pkt].status = -DWC_E_NO_DATA;
02525         }
02526         ep->cur_pkt_addr += offset;
02527         ep->cur_pkt_dma_addr += offset;
02528         ep->cur_pkt++;
02529 }
02530 
02538 static void set_ddma_iso_pkts_info(dwc_otg_core_if_t * core_if,
02539                                    dwc_ep_t * dwc_ep)
02540 {
02541         dwc_otg_dev_dma_desc_t *dma_desc;
02542         dev_dma_desc_sts_t sts = {.d32 = 0 };
02543         iso_pkt_info_t *iso_packet;
02544         uint32_t data_per_desc;
02545         uint32_t offset;
02546         int i, j;
02547 
02548         iso_packet = dwc_ep->pkt_info;
02549 
02552         if (dwc_ep->is_in == 0) {
02553                 dma_desc =
02554                     dwc_ep->iso_desc_addr +
02555                     dwc_ep->desc_cnt * dwc_ep->proc_buf_num;
02556                 offset = 0;
02557 
02558                 for (i = 0; i < dwc_ep->desc_cnt - dwc_ep->pkt_per_frm;
02559                      i += dwc_ep->pkt_per_frm) {
02560                         for (j = 0; j < dwc_ep->pkt_per_frm; ++j) {
02561                                 data_per_desc =
02562                                     ((j + 1) * dwc_ep->maxpacket >
02563                                      dwc_ep->
02564                                      data_per_frame) ? dwc_ep->data_per_frame -
02565                                     j * dwc_ep->maxpacket : dwc_ep->maxpacket;
02566                                 data_per_desc +=
02567                                     (data_per_desc % 4) ? (4 -
02568                                                            data_per_desc %
02569                                                            4) : 0;
02570 
02571                                 sts.d32 = dma_desc->status.d32;
02572 
02573                                 /* Write status in iso_packet_decsriptor  */
02574                                 iso_packet->status =
02575                                     sts.b_iso_out.rxsts +
02576                                     (sts.b_iso_out.bs ^ BS_DMA_DONE);
02577                                 if (iso_packet->status) {
02578                                         iso_packet->status = -DWC_E_NO_DATA;
02579                                 }
02580 
02581                                 /* Received data length */
02582                                 if (!sts.b_iso_out.rxbytes) {
02583                                         iso_packet->length =
02584                                             data_per_desc -
02585                                             sts.b_iso_out.rxbytes;
02586                                 } else {
02587                                         iso_packet->length =
02588                                             data_per_desc -
02589                                             sts.b_iso_out.rxbytes + (4 -
02590                                                                      dwc_ep->data_per_frame
02591                                                                      % 4);
02592                                 }
02593 
02594                                 iso_packet->offset = offset;
02595 
02596                                 offset += data_per_desc;
02597                                 dma_desc++;
02598                                 iso_packet++;
02599                         }
02600                 }
02601 
02602                 for (j = 0; j < dwc_ep->pkt_per_frm - 1; ++j) {
02603                         data_per_desc =
02604                             ((j + 1) * dwc_ep->maxpacket >
02605                              dwc_ep->data_per_frame) ? dwc_ep->data_per_frame -
02606                             j * dwc_ep->maxpacket : dwc_ep->maxpacket;
02607                         data_per_desc +=
02608                             (data_per_desc % 4) ? (4 - data_per_desc % 4) : 0;
02609 
02610                         sts.d32 = dma_desc->status.d32;
02611 
02612                         /* Write status in iso_packet_decsriptor  */
02613                         iso_packet->status =
02614                             sts.b_iso_out.rxsts +
02615                             (sts.b_iso_out.bs ^ BS_DMA_DONE);
02616                         if (iso_packet->status) {
02617                                 iso_packet->status = -DWC_E_NO_DATA;
02618                         }
02619 
02620                         /* Received data length */
02621                         iso_packet->length =
02622                             dwc_ep->data_per_frame - sts.b_iso_out.rxbytes;
02623 
02624                         iso_packet->offset = offset;
02625 
02626                         offset += data_per_desc;
02627                         iso_packet++;
02628                         dma_desc++;
02629                 }
02630 
02631                 sts.d32 = dma_desc->status.d32;
02632 
02633                 /* Write status in iso_packet_decsriptor  */
02634                 iso_packet->status =
02635                     sts.b_iso_out.rxsts + (sts.b_iso_out.bs ^ BS_DMA_DONE);
02636                 if (iso_packet->status) {
02637                         iso_packet->status = -DWC_E_NO_DATA;
02638                 }
02639                 /* Received data length */
02640                 if (!sts.b_iso_out.rxbytes) {
02641                         iso_packet->length =
02642                             dwc_ep->data_per_frame - sts.b_iso_out.rxbytes;
02643                 } else {
02644                         iso_packet->length =
02645                             dwc_ep->data_per_frame - sts.b_iso_out.rxbytes +
02646                             (4 - dwc_ep->data_per_frame % 4);
02647                 }
02648 
02649                 iso_packet->offset = offset;
02650         } else {
02653                 dma_desc =
02654                     dwc_ep->iso_desc_addr +
02655                     dwc_ep->desc_cnt * dwc_ep->proc_buf_num;
02656 
02657                 for (i = 0; i < dwc_ep->desc_cnt - 1; i++) {
02658                         sts.d32 = dma_desc->status.d32;
02659 
02660                         /* Write status in iso packet descriptor */
02661                         iso_packet->status =
02662                             sts.b_iso_in.txsts +
02663                             (sts.b_iso_in.bs ^ BS_DMA_DONE);
02664                         if (iso_packet->status != 0) {
02665                                 iso_packet->status = -DWC_E_NO_DATA;
02666 
02667                         }
02668                         /* Bytes has been transfered */
02669                         iso_packet->length =
02670                             dwc_ep->data_per_frame - sts.b_iso_in.txbytes;
02671 
02672                         dma_desc++;
02673                         iso_packet++;
02674                 }
02675 
02676                 sts.d32 = dma_desc->status.d32;
02677                 while (sts.b_iso_in.bs == BS_DMA_BUSY) {
02678                         sts.d32 = dma_desc->status.d32;
02679                 }
02680 
02681                 /* Write status in iso packet descriptor ??? do be done with ERROR codes */
02682                 iso_packet->status =
02683                     sts.b_iso_in.txsts + (sts.b_iso_in.bs ^ BS_DMA_DONE);
02684                 if (iso_packet->status != 0) {
02685                         iso_packet->status = -DWC_E_NO_DATA;
02686                 }
02687 
02688                 /* Bytes has been transfered */
02689                 iso_packet->length =
02690                     dwc_ep->data_per_frame - sts.b_iso_in.txbytes;
02691         }
02692 }
02693 
02701 static void reinit_ddma_iso_xfer(dwc_otg_core_if_t * core_if, dwc_ep_t * dwc_ep)
02702 {
02703         int i, j;
02704         dwc_otg_dev_dma_desc_t *dma_desc;
02705         dma_addr_t dma_ad;
02706         volatile uint32_t *addr;
02707         dev_dma_desc_sts_t sts = {.d32 = 0 };
02708         uint32_t data_per_desc;
02709 
02710         if (dwc_ep->is_in == 0) {
02711                 addr = &core_if->dev_if->out_ep_regs[dwc_ep->num]->doepctl;
02712         } else {
02713                 addr = &core_if->dev_if->in_ep_regs[dwc_ep->num]->diepctl;
02714         }
02715 
02716         if (dwc_ep->proc_buf_num == 0) {
02718                 dma_ad = dwc_ep->dma_addr0;
02719         } else {
02721                 dma_ad = dwc_ep->dma_addr1;
02722         }
02723 
02726         if (dwc_ep->is_in == 0) {
02727                 dma_desc =
02728                     dwc_ep->iso_desc_addr +
02729                     dwc_ep->desc_cnt * dwc_ep->proc_buf_num;
02730 
02731                 sts.b_iso_out.bs = BS_HOST_READY;
02732                 sts.b_iso_out.rxsts = 0;
02733                 sts.b_iso_out.l = 0;
02734                 sts.b_iso_out.sp = 0;
02735                 sts.b_iso_out.ioc = 0;
02736                 sts.b_iso_out.pid = 0;
02737                 sts.b_iso_out.framenum = 0;
02738 
02739                 for (i = 0; i < dwc_ep->desc_cnt - dwc_ep->pkt_per_frm;
02740                      i += dwc_ep->pkt_per_frm) {
02741                         for (j = 0; j < dwc_ep->pkt_per_frm; ++j) {
02742                                 data_per_desc =
02743                                     ((j + 1) * dwc_ep->maxpacket >
02744                                      dwc_ep->
02745                                      data_per_frame) ? dwc_ep->data_per_frame -
02746                                     j * dwc_ep->maxpacket : dwc_ep->maxpacket;
02747                                 data_per_desc +=
02748                                     (data_per_desc % 4) ? (4 -
02749                                                            data_per_desc %
02750                                                            4) : 0;
02751                                 sts.b_iso_out.rxbytes = data_per_desc;
02752                                 dma_desc->buf = dma_ad;
02753                                 dma_desc->status.d32 = sts.d32;
02754 
02755                                 dma_ad += data_per_desc;
02756                                 dma_desc++;
02757                         }
02758                 }
02759 
02760                 for (j = 0; j < dwc_ep->pkt_per_frm - 1; ++j) {
02761 
02762                         data_per_desc =
02763                             ((j + 1) * dwc_ep->maxpacket >
02764                              dwc_ep->data_per_frame) ? dwc_ep->data_per_frame -
02765                             j * dwc_ep->maxpacket : dwc_ep->maxpacket;
02766                         data_per_desc +=
02767                             (data_per_desc % 4) ? (4 - data_per_desc % 4) : 0;
02768                         sts.b_iso_out.rxbytes = data_per_desc;
02769 
02770                         dma_desc->buf = dma_ad;
02771                         dma_desc->status.d32 = sts.d32;
02772 
02773                         dma_desc++;
02774                         dma_ad += data_per_desc;
02775                 }
02776 
02777                 sts.b_iso_out.ioc = 1;
02778                 sts.b_iso_out.l = dwc_ep->proc_buf_num;
02779 
02780                 data_per_desc =
02781                     ((j + 1) * dwc_ep->maxpacket >
02782                      dwc_ep->data_per_frame) ? dwc_ep->data_per_frame -
02783                     j * dwc_ep->maxpacket : dwc_ep->maxpacket;
02784                 data_per_desc +=
02785                     (data_per_desc % 4) ? (4 - data_per_desc % 4) : 0;
02786                 sts.b_iso_out.rxbytes = data_per_desc;
02787 
02788                 dma_desc->buf = dma_ad;
02789                 dma_desc->status.d32 = sts.d32;
02790         } else {
02793                 dma_desc =
02794                     dwc_ep->iso_desc_addr +
02795                     dwc_ep->desc_cnt * dwc_ep->proc_buf_num;
02796 
02797                 sts.b_iso_in.bs = BS_HOST_READY;
02798                 sts.b_iso_in.txsts = 0;
02799                 sts.b_iso_in.sp = 0;
02800                 sts.b_iso_in.ioc = 0;
02801                 sts.b_iso_in.pid = dwc_ep->pkt_per_frm;
02802                 sts.b_iso_in.framenum = dwc_ep->next_frame;
02803                 sts.b_iso_in.txbytes = dwc_ep->data_per_frame;
02804                 sts.b_iso_in.l = 0;
02805 
02806                 for (i = 0; i < dwc_ep->desc_cnt - 1; i++) {
02807                         dma_desc->buf = dma_ad;
02808                         dma_desc->status.d32 = sts.d32;
02809 
02810                         sts.b_iso_in.framenum += dwc_ep->bInterval;
02811                         dma_ad += dwc_ep->data_per_frame;
02812                         dma_desc++;
02813                 }
02814 
02815                 sts.b_iso_in.ioc = 1;
02816                 sts.b_iso_in.l = dwc_ep->proc_buf_num;
02817 
02818                 dma_desc->buf = dma_ad;
02819                 dma_desc->status.d32 = sts.d32;
02820 
02821                 dwc_ep->next_frame =
02822                     sts.b_iso_in.framenum + dwc_ep->bInterval * 1;
02823         }
02824         dwc_ep->proc_buf_num = (dwc_ep->proc_buf_num ^ 1) & 0x1;
02825 }
02826 
02835 static uint32_t handle_iso_out_pkt_dropped(dwc_otg_core_if_t * core_if,
02836                                            dwc_ep_t * dwc_ep)
02837 {
02838         uint32_t dma_addr;
02839         uint32_t drp_pkt;
02840         uint32_t drp_pkt_cnt;
02841         deptsiz_data_t deptsiz = {.d32 = 0 };
02842         depctl_data_t depctl = {.d32 = 0 };
02843         int i;
02844 
02845         deptsiz.d32 =
02846             DWC_READ_REG32(&core_if->dev_if->
02847                            out_ep_regs[dwc_ep->num]->doeptsiz);
02848 
02849         drp_pkt = dwc_ep->pkt_cnt - deptsiz.b.pktcnt;
02850         drp_pkt_cnt = dwc_ep->pkt_per_frm - (drp_pkt % dwc_ep->pkt_per_frm);
02851 
02852         /* Setting dropped packets status */
02853         for (i = 0; i < drp_pkt_cnt; ++i) {
02854                 dwc_ep->pkt_info[drp_pkt].status = -DWC_E_NO_DATA;
02855                 drp_pkt++;
02856                 deptsiz.b.pktcnt--;
02857         }
02858 
02859         if (deptsiz.b.pktcnt > 0) {
02860                 deptsiz.b.xfersize =
02861                     dwc_ep->xfer_len - (dwc_ep->pkt_cnt -
02862                                         deptsiz.b.pktcnt) * dwc_ep->maxpacket;
02863         } else {
02864                 deptsiz.b.xfersize = 0;
02865                 deptsiz.b.pktcnt = 0;
02866         }
02867 
02868         DWC_WRITE_REG32(&core_if->dev_if->out_ep_regs[dwc_ep->num]->doeptsiz,
02869                         deptsiz.d32);
02870 
02871         if (deptsiz.b.pktcnt > 0) {
02872                 if (dwc_ep->proc_buf_num) {
02873                         dma_addr =
02874                             dwc_ep->dma_addr1 + dwc_ep->xfer_len -
02875                             deptsiz.b.xfersize;
02876                 } else {
02877                         dma_addr =
02878                             dwc_ep->dma_addr0 + dwc_ep->xfer_len -
02879                             deptsiz.b.xfersize;;
02880                 }
02881 
02882                 DWC_WRITE_REG32(&core_if->dev_if->
02883                                 out_ep_regs[dwc_ep->num]->doepdma, dma_addr);
02884 
02886                 depctl.d32 = 0;
02887                 depctl.b.epena = 1;
02888                 depctl.b.cnak = 1;
02889 
02890                 DWC_MODIFY_REG32(&core_if->dev_if->
02891                                  out_ep_regs[dwc_ep->num]->doepctl, depctl.d32,
02892                                  depctl.d32);
02893                 return 0;
02894         } else {
02895                 return 1;
02896         }
02897 }
02898 
02906 static uint32_t set_iso_pkts_info(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
02907 {
02908         int i, j;
02909         dma_addr_t dma_ad;
02910         iso_pkt_info_t *packet_info = ep->pkt_info;
02911         uint32_t offset;
02912         uint32_t frame_data;
02913         deptsiz_data_t deptsiz;
02914 
02915         if (ep->proc_buf_num == 0) {
02917                 dma_ad = ep->dma_addr0;
02918         } else {
02920                 dma_ad = ep->dma_addr1;
02921         }
02922 
02923         if (ep->is_in) {
02924                 deptsiz.d32 =
02925                     DWC_READ_REG32(&core_if->dev_if->
02926                                    in_ep_regs[ep->num]->dieptsiz);
02927         } else {
02928                 deptsiz.d32 =
02929                     DWC_READ_REG32(&core_if->dev_if->
02930                                    out_ep_regs[ep->num]->doeptsiz);
02931         }
02932 
02933         if (!deptsiz.b.xfersize) {
02934                 offset = 0;
02935                 for (i = 0; i < ep->pkt_cnt; i += ep->pkt_per_frm) {
02936                         frame_data = ep->data_per_frame;
02937                         for (j = 0; j < ep->pkt_per_frm; ++j) {
02938 
02939                                 /* Packet status - is not set as initially
02940                                  * it is set to 0 and if packet was sent
02941                                  successfully, status field will remain 0*/
02942 
02943                                 /* Bytes has been transfered */
02944                                 packet_info->length =
02945                                     (ep->maxpacket <
02946                                      frame_data) ? ep->maxpacket : frame_data;
02947 
02948                                 /* Received packet offset */
02949                                 packet_info->offset = offset;
02950                                 offset += packet_info->length;
02951                                 frame_data -= packet_info->length;
02952 
02953                                 packet_info++;
02954                         }
02955                 }
02956                 return 1;
02957         } else {
02958                 /* This is a workaround for in case of Transfer Complete with
02959                  * PktDrpSts interrupts merging - in this case Transfer complete
02960                  * interrupt for Isoc Out Endpoint is asserted without PktDrpSts
02961                  * set and with DOEPTSIZ register non zero. Investigations showed,
02962                  * that this happens when Out packet is dropped, but because of
02963                  * interrupts merging during first interrupt handling PktDrpSts
02964                  * bit is cleared and for next merged interrupts it is not reset.
02965                  * In this case SW hadles the interrupt as if PktDrpSts bit is set.
02966                  */
02967                 if (ep->is_in) {
02968                         return 1;
02969                 } else {
02970                         return handle_iso_out_pkt_dropped(core_if, ep);
02971                 }
02972         }
02973 }
02974 
02982 static void complete_iso_ep(dwc_otg_pcd_t * pcd, dwc_otg_pcd_ep_t * ep)
02983 {
02984         dwc_otg_core_if_t *core_if = GET_CORE_IF(ep->pcd);
02985         dwc_ep_t *dwc_ep = &ep->dwc_ep;
02986         uint8_t is_last = 0;
02987 
02988         if (ep->dwc_ep.next_frame == 0xffffffff) {
02989                 DWC_WARN("Next frame is not set!\n");
02990                 return;
02991         }
02992 
02993         if (core_if->dma_enable) {
02994                 if (core_if->dma_desc_enable) {
02995                         set_ddma_iso_pkts_info(core_if, dwc_ep);
02996                         reinit_ddma_iso_xfer(core_if, dwc_ep);
02997                         is_last = 1;
02998                 } else {
02999                         if (core_if->pti_enh_enable) {
03000                                 if (set_iso_pkts_info(core_if, dwc_ep)) {
03001                                         dwc_ep->proc_buf_num =
03002                                             (dwc_ep->proc_buf_num ^ 1) & 0x1;
03003                                         dwc_otg_iso_ep_start_buf_transfer
03004                                             (core_if, dwc_ep);
03005                                         is_last = 1;
03006                                 }
03007                         } else {
03008                                 set_current_pkt_info(core_if, dwc_ep);
03009                                 if (dwc_ep->cur_pkt >= dwc_ep->pkt_cnt) {
03010                                         is_last = 1;
03011                                         dwc_ep->cur_pkt = 0;
03012                                         dwc_ep->proc_buf_num =
03013                                             (dwc_ep->proc_buf_num ^ 1) & 0x1;
03014                                         if (dwc_ep->proc_buf_num) {
03015                                                 dwc_ep->cur_pkt_addr =
03016                                                     dwc_ep->xfer_buff1;
03017                                                 dwc_ep->cur_pkt_dma_addr =
03018                                                     dwc_ep->dma_addr1;
03019                                         } else {
03020                                                 dwc_ep->cur_pkt_addr =
03021                                                     dwc_ep->xfer_buff0;
03022                                                 dwc_ep->cur_pkt_dma_addr =
03023                                                     dwc_ep->dma_addr0;
03024                                         }
03025 
03026                                 }
03027                                 dwc_otg_iso_ep_start_frm_transfer(core_if,
03028                                                                   dwc_ep);
03029                         }
03030                 }
03031         } else {
03032                 set_current_pkt_info(core_if, dwc_ep);
03033                 if (dwc_ep->cur_pkt >= dwc_ep->pkt_cnt) {
03034                         is_last = 1;
03035                         dwc_ep->cur_pkt = 0;
03036                         dwc_ep->proc_buf_num = (dwc_ep->proc_buf_num ^ 1) & 0x1;
03037                         if (dwc_ep->proc_buf_num) {
03038                                 dwc_ep->cur_pkt_addr = dwc_ep->xfer_buff1;
03039                                 dwc_ep->cur_pkt_dma_addr = dwc_ep->dma_addr1;
03040                         } else {
03041                                 dwc_ep->cur_pkt_addr = dwc_ep->xfer_buff0;
03042                                 dwc_ep->cur_pkt_dma_addr = dwc_ep->dma_addr0;
03043                         }
03044 
03045                 }
03046                 dwc_otg_iso_ep_start_frm_transfer(core_if, dwc_ep);
03047         }
03048         if (is_last)
03049                 dwc_otg_iso_buffer_done(pcd, ep, ep->iso_req_handle);
03050 }
03051 #endif /* DWC_EN_ISOC */
03052 
03057 static void dwc_otg_pcd_handle_noniso_bna(dwc_otg_pcd_ep_t * ep)
03058 {
03059         dwc_ep_t *dwc_ep = &ep->dwc_ep;
03060         volatile uint32_t *addr;
03061         depctl_data_t depctl = {.d32 = 0 };
03062         dwc_otg_pcd_t *pcd = ep->pcd;
03063         dwc_otg_dev_dma_desc_t *dma_desc;
03064         dev_dma_desc_sts_t sts = {.d32 = 0 };
03065         dwc_otg_core_if_t *core_if = ep->pcd->core_if;
03066         int i, start;
03067 
03068         if (!dwc_ep->desc_cnt)
03069                 DWC_WARN("Descriptor count = %d\n", dwc_ep->desc_cnt);
03070 
03071         if (core_if->core_params->cont_on_bna && !dwc_ep->is_in
03072                                                         && dwc_ep->type != DWC_OTG_EP_TYPE_CONTROL) {
03073                 uint32_t doepdma;
03074                 dwc_otg_dev_out_ep_regs_t *out_regs =
03075                         core_if->dev_if->out_ep_regs[dwc_ep->num];
03076                 doepdma = DWC_READ_REG32(&(out_regs->doepdma));
03077                 start = (doepdma - dwc_ep->dma_desc_addr)/sizeof(dwc_otg_dev_dma_desc_t);
03078                 dma_desc = &(dwc_ep->desc_addr[start]);
03079         } else {
03080                 start = 0;
03081                 dma_desc = dwc_ep->desc_addr;
03082         }
03083         
03084 
03085         for (i = start; i < dwc_ep->desc_cnt; ++i, ++dma_desc) {
03086                 sts.d32 = dma_desc->status.d32;
03087                 sts.b.bs = BS_HOST_READY;
03088                 dma_desc->status.d32 = sts.d32;
03089         }
03090 
03091         if (dwc_ep->is_in == 0) {
03092                 addr =
03093                     &GET_CORE_IF(pcd)->dev_if->out_ep_regs[dwc_ep->
03094                                                            num]->doepctl;
03095         } else {
03096                 addr =
03097                     &GET_CORE_IF(pcd)->dev_if->in_ep_regs[dwc_ep->num]->diepctl;
03098         }
03099         depctl.b.epena = 1;
03100         depctl.b.cnak = 1;
03101         DWC_MODIFY_REG32(addr, 0, depctl.d32);
03102 }
03103 
03110 static void handle_ep0(dwc_otg_pcd_t * pcd)
03111 {
03112         dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
03113         dwc_otg_pcd_ep_t *ep0 = &pcd->ep0;
03114         dev_dma_desc_sts_t desc_sts;
03115         deptsiz0_data_t deptsiz;
03116         uint32_t byte_count;
03117 
03118 #ifdef DEBUG_EP0
03119         DWC_DEBUGPL(DBG_PCDV, "%s()\n", __func__);
03120         print_ep0_state(pcd);
03121 #endif
03122 
03123 //      DWC_PRINTF("HANDLE EP0\n");
03124 
03125         switch (pcd->ep0state) {
03126         case EP0_DISCONNECT:
03127                 break;
03128 
03129         case EP0_IDLE:
03130                 pcd->request_config = 0;
03131 
03132                 pcd_setup(pcd);
03133                 break;
03134 
03135         case EP0_IN_DATA_PHASE:
03136 #ifdef DEBUG_EP0
03137                 DWC_DEBUGPL(DBG_PCD, "DATA_IN EP%d-%s: type=%d, mps=%d\n",
03138                             ep0->dwc_ep.num, (ep0->dwc_ep.is_in ? "IN" : "OUT"),
03139                             ep0->dwc_ep.type, ep0->dwc_ep.maxpacket);
03140 #endif
03141 
03142                 if (core_if->dma_enable != 0) {
03143                         /*
03144                          * For EP0 we can only program 1 packet at a time so we
03145                          * need to do the make calculations after each complete.
03146                          * Call write_packet to make the calculations, as in
03147                          * slave mode, and use those values to determine if we
03148                          * can complete.
03149                          */
03150                         if (core_if->dma_desc_enable == 0) {
03151                                 deptsiz.d32 =
03152                                     DWC_READ_REG32(&core_if->
03153                                                    dev_if->in_ep_regs[0]->
03154                                                    dieptsiz);
03155                                 byte_count =
03156                                     ep0->dwc_ep.xfer_len - deptsiz.b.xfersize;
03157                         } else {
03158                                 desc_sts =
03159                                     core_if->dev_if->in_desc_addr->status;
03160                                 byte_count =
03161                                     ep0->dwc_ep.xfer_len - desc_sts.b.bytes;
03162                         }
03163                         ep0->dwc_ep.xfer_count += byte_count;
03164                         ep0->dwc_ep.xfer_buff += byte_count;
03165                         ep0->dwc_ep.dma_addr += byte_count;
03166                 }
03167                 if (ep0->dwc_ep.xfer_count < ep0->dwc_ep.total_len) {
03168                         dwc_otg_ep0_continue_transfer(GET_CORE_IF(pcd),
03169                                                       &ep0->dwc_ep);
03170                         DWC_DEBUGPL(DBG_PCD, "CONTINUE TRANSFER\n");
03171                 } else if (ep0->dwc_ep.sent_zlp) {
03172                         dwc_otg_ep0_continue_transfer(GET_CORE_IF(pcd),
03173                                                       &ep0->dwc_ep);
03174                         ep0->dwc_ep.sent_zlp = 0;
03175                         DWC_DEBUGPL(DBG_PCD, "CONTINUE TRANSFER\n");
03176                 } else {
03177                         ep0_complete_request(ep0);
03178                         DWC_DEBUGPL(DBG_PCD, "COMPLETE TRANSFER\n");
03179                 }
03180                 break;
03181         case EP0_OUT_DATA_PHASE:
03182 #ifdef DEBUG_EP0
03183                 DWC_DEBUGPL(DBG_PCD, "DATA_OUT EP%d-%s: type=%d, mps=%d\n",
03184                             ep0->dwc_ep.num, (ep0->dwc_ep.is_in ? "IN" : "OUT"),
03185                             ep0->dwc_ep.type, ep0->dwc_ep.maxpacket);
03186 #endif
03187                 if (core_if->dma_enable != 0) {
03188                         if (core_if->dma_desc_enable == 0) {
03189                                 deptsiz.d32 =
03190                                     DWC_READ_REG32(&core_if->
03191                                                    dev_if->out_ep_regs[0]->
03192                                                    doeptsiz);
03193                                 byte_count =
03194                                     ep0->dwc_ep.maxpacket - deptsiz.b.xfersize;
03195                         } else {
03196                                 desc_sts =
03197                                     core_if->dev_if->out_desc_addr->status;
03198                                 byte_count =
03199                                     ep0->dwc_ep.maxpacket - desc_sts.b.bytes;
03200                         }
03201                         ep0->dwc_ep.xfer_count += byte_count;
03202                         ep0->dwc_ep.xfer_buff += byte_count;
03203                         ep0->dwc_ep.dma_addr += byte_count;
03204                 }
03205                 if (ep0->dwc_ep.xfer_count < ep0->dwc_ep.total_len) {
03206                         dwc_otg_ep0_continue_transfer(GET_CORE_IF(pcd),
03207                                                       &ep0->dwc_ep);
03208                         DWC_DEBUGPL(DBG_PCD, "CONTINUE TRANSFER\n");
03209                 } else if (ep0->dwc_ep.sent_zlp) {
03210                         dwc_otg_ep0_continue_transfer(GET_CORE_IF(pcd),
03211                                                       &ep0->dwc_ep);
03212                         ep0->dwc_ep.sent_zlp = 0;
03213                         DWC_DEBUGPL(DBG_PCD, "CONTINUE TRANSFER\n");
03214                 } else {
03215                         ep0_complete_request(ep0);
03216                         DWC_DEBUGPL(DBG_PCD, "COMPLETE TRANSFER\n");
03217                 }
03218                 break;
03219 
03220         case EP0_IN_STATUS_PHASE:
03221         case EP0_OUT_STATUS_PHASE:
03222                 DWC_DEBUGPL(DBG_PCD, "CASE: EP0_STATUS\n");
03223                 ep0_complete_request(ep0);
03224                 pcd->ep0state = EP0_IDLE;
03225                 ep0->stopped = 1;
03226                 ep0->dwc_ep.is_in = 0;  /* OUT for next SETUP */
03227 
03228                 /* Prepare for more SETUP Packets */
03229                 if (core_if->dma_enable) {
03230                         ep0_out_start(core_if, pcd);
03231                 }
03232                 break;
03233 
03234         case EP0_STALL:
03235                 DWC_ERROR("EP0 STALLed, should not get here pcd_setup()\n");
03236                 break;
03237         }
03238 #ifdef DEBUG_EP0
03239         print_ep0_state(pcd);
03240 #endif
03241 }
03242 
03246 static void restart_transfer(dwc_otg_pcd_t * pcd, const uint32_t epnum)
03247 {
03248         dwc_otg_core_if_t *core_if;
03249         dwc_otg_dev_if_t *dev_if;
03250         deptsiz_data_t dieptsiz = {.d32 = 0 };
03251         dwc_otg_pcd_ep_t *ep;
03252 
03253         ep = get_in_ep(pcd, epnum);
03254 
03255 #ifdef DWC_EN_ISOC
03256         if (ep->dwc_ep.type == DWC_OTG_EP_TYPE_ISOC) {
03257                 return;
03258         }
03259 #endif /* DWC_EN_ISOC  */
03260 
03261         core_if = GET_CORE_IF(pcd);
03262         dev_if = core_if->dev_if;
03263 
03264         dieptsiz.d32 = DWC_READ_REG32(&dev_if->in_ep_regs[epnum]->dieptsiz);
03265 
03266         DWC_DEBUGPL(DBG_PCD, "xfer_buff=%p xfer_count=%0x xfer_len=%0x"
03267                     " stopped=%d\n", ep->dwc_ep.xfer_buff,
03268                     ep->dwc_ep.xfer_count, ep->dwc_ep.xfer_len, ep->stopped);
03269         /*
03270          * If xfersize is 0 and pktcnt in not 0, resend the last packet.
03271          */
03272         if (dieptsiz.b.pktcnt && dieptsiz.b.xfersize == 0 &&
03273             ep->dwc_ep.start_xfer_buff != 0) {
03274                 if (ep->dwc_ep.total_len <= ep->dwc_ep.maxpacket) {
03275                         ep->dwc_ep.xfer_count = 0;
03276                         ep->dwc_ep.xfer_buff = ep->dwc_ep.start_xfer_buff;
03277                         ep->dwc_ep.xfer_len = ep->dwc_ep.xfer_count;
03278                 } else {
03279                         ep->dwc_ep.xfer_count -= ep->dwc_ep.maxpacket;
03280                         /* convert packet size to dwords. */
03281                         ep->dwc_ep.xfer_buff -= ep->dwc_ep.maxpacket;
03282                         ep->dwc_ep.xfer_len = ep->dwc_ep.xfer_count;
03283                 }
03284                 ep->stopped = 0;
03285                 DWC_DEBUGPL(DBG_PCD, "xfer_buff=%p xfer_count=%0x "
03286                             "xfer_len=%0x stopped=%d\n",
03287                             ep->dwc_ep.xfer_buff,
03288                             ep->dwc_ep.xfer_count, ep->dwc_ep.xfer_len,
03289                             ep->stopped);
03290                 if (epnum == 0) {
03291                         dwc_otg_ep0_start_transfer(core_if, &ep->dwc_ep);
03292                 } else {
03293                         dwc_otg_ep_start_transfer(core_if, &ep->dwc_ep);
03294                 }
03295         }
03296 }
03297 
03298 /*
03299  * This function create new nextep sequnce based on Learn Queue.
03300  *
03301  * @param core_if Programming view of DWC_otg controller
03302  */
03303 void predict_nextep_seq( dwc_otg_core_if_t * core_if)
03304 {
03305         dwc_otg_device_global_regs_t *dev_global_regs =
03306             core_if->dev_if->dev_global_regs;
03307         const uint32_t TOKEN_Q_DEPTH = core_if->hwcfg2.b.dev_token_q_depth;
03308         /* Number of Token Queue Registers */
03309         const int DTKNQ_REG_CNT = (TOKEN_Q_DEPTH + 7) / 8;
03310         dtknq1_data_t dtknqr1;
03311         uint32_t in_tkn_epnums[4];
03312         uint8_t seqnum[MAX_EPS_CHANNELS];
03313         uint8_t intkn_seq[TOKEN_Q_DEPTH];
03314         grstctl_t resetctl = {.d32 = 0 };
03315         uint8_t temp;
03316         int ndx = 0;
03317         int start = 0;
03318         int end = 0;
03319         int sort_done = 0;
03320         int i = 0;
03321         volatile uint32_t *addr = &dev_global_regs->dtknqr1;
03322 
03323 
03324         DWC_DEBUGPL(DBG_PCD,"dev_token_q_depth=%d\n",TOKEN_Q_DEPTH);
03325 
03326         /* Read the DTKNQ Registers */
03327         for (i = 0; i < DTKNQ_REG_CNT; i++) {
03328                 in_tkn_epnums[i] = DWC_READ_REG32(addr);
03329                 DWC_DEBUGPL(DBG_PCDV, "DTKNQR%d=0x%08x\n", i + 1,
03330                             in_tkn_epnums[i]);
03331                 if (addr == &dev_global_regs->dvbusdis) {
03332                         addr = &dev_global_regs->dtknqr3_dthrctl;
03333                 } else {
03334                         ++addr;
03335                 }
03336 
03337         }
03338 
03339         /* Copy the DTKNQR1 data to the bit field. */
03340         dtknqr1.d32 = in_tkn_epnums[0];
03341         if (dtknqr1.b.wrap_bit) {
03342                 ndx = dtknqr1.b.intknwptr;
03343                 end = ndx -1;
03344                 if (end < 0) 
03345                         end = TOKEN_Q_DEPTH -1;
03346         } else {
03347                 ndx = 0;
03348                 end = dtknqr1.b.intknwptr -1;
03349                 if (end < 0) 
03350                         end = 0;
03351         }
03352         start = ndx;
03353         
03354         /* Fill seqnum[] by initial values: EP number + 31 */
03355         for (i=0; i <= core_if->dev_if->num_in_eps; i++) {
03356                 seqnum[i] = i +31;
03357         }
03358         
03359         /* Fill intkn_seq[] from in_tkn_epnums[0] */
03360         for (i=0; i < 6; i++) 
03361                 intkn_seq[i] = (in_tkn_epnums[0] >> ((7-i) * 4)) & 0xf;
03362         
03363         if (TOKEN_Q_DEPTH > 6) {
03364                 /* Fill intkn_seq[] from in_tkn_epnums[1] */
03365                 for (i=6; i < 14; i++) 
03366                         intkn_seq[i] = (in_tkn_epnums[1] >> ((7-(i-6)) * 4)) & 0xf;
03367         }
03368         
03369         if (TOKEN_Q_DEPTH > 14) {
03370                 /* Fill intkn_seq[] from in_tkn_epnums[1] */
03371                 for (i=14; i < 22; i++) 
03372                         intkn_seq[i] = (in_tkn_epnums[2] >> ((7-(i-14)) * 4)) & 0xf;
03373         }
03374 
03375         if (TOKEN_Q_DEPTH > 22) {
03376                 /* Fill intkn_seq[] from in_tkn_epnums[1] */
03377                 for (i=22; i < 30; i++) 
03378                         intkn_seq[i] = (in_tkn_epnums[3] >> ((7-(i-22)) * 4)) & 0xf;
03379         }
03380 
03381         DWC_DEBUGPL(DBG_PCDV,"%s start=%d end=%d intkn_seq[]:\n", __func__, start, end);
03382         for (i=0; i<TOKEN_Q_DEPTH; i++) 
03383                 DWC_DEBUGPL(DBG_PCDV,"%d\n", intkn_seq[i]);
03384 
03385         /* Update seqnum based on intkn_seq[] */
03386         i = 0;
03387         do {
03388                 seqnum[intkn_seq[ndx]] = i;
03389                 ndx++;
03390                 i++;
03391                 if (ndx == TOKEN_Q_DEPTH) 
03392                         ndx = 0;
03393         } while ( i < TOKEN_Q_DEPTH );
03394         
03395         /* Mark non active EP's in seqnum[] by 0xff */
03396         for (i=0; i<=core_if->dev_if->num_in_eps; i++) {
03397                 if (core_if->nextep_seq[i] == 0xff )
03398                         seqnum[i] = 0xff;
03399         }
03400         
03401         /* Sort seqnum[] */
03402         sort_done = 0;
03403         while (!sort_done) {
03404                 sort_done = 1;
03405                 for (i=0; i<core_if->dev_if->num_in_eps; i++) {
03406                         if (seqnum[i] > seqnum[i+1]) {
03407                                 temp = seqnum[i];
03408                                 seqnum[i] = seqnum[i+1];
03409                                 seqnum[i+1] = temp;
03410                                 sort_done = 0;
03411                         }
03412                 }
03413         }
03414 
03415         ndx = start + seqnum[0];
03416         if (ndx >= TOKEN_Q_DEPTH) 
03417                 ndx = ndx % TOKEN_Q_DEPTH;
03418         core_if->first_in_nextep_seq = intkn_seq[ndx];
03419         
03420         /* Update seqnum[] by EP numbers  */
03421         for (i=0; i<=core_if->dev_if->num_in_eps; i++) {
03422                 ndx = start + i;
03423                 if (seqnum[i] < 31) {
03424                         ndx = start + seqnum[i];
03425                         if (ndx >= TOKEN_Q_DEPTH) 
03426                                 ndx = ndx % TOKEN_Q_DEPTH;
03427                         seqnum[i] = intkn_seq[ndx];
03428                 } else {
03429                         if (seqnum[i] < 0xff) {
03430                                 seqnum[i] = seqnum[i] - 31;
03431                         } else {
03432                                 break;
03433                         }
03434                 }
03435         }
03436 
03437         /* Update nextep_seq[] based on seqnum[] */
03438         for (i=0; i<core_if->dev_if->num_in_eps; i++) {
03439                 if (seqnum[i] != 0xff) {
03440                         if (seqnum[i+1] != 0xff) {
03441                                 core_if->nextep_seq[seqnum[i]] = seqnum[i+1];
03442                         } else {
03443                                 core_if->nextep_seq[seqnum[i]] = core_if->first_in_nextep_seq;
03444                                 break;
03445                         }
03446                 } else {
03447                         break;
03448                 }
03449         }
03450         
03451         DWC_DEBUGPL(DBG_PCDV, "%s first_in_nextep_seq= %2d; nextep_seq[]:\n", 
03452                 __func__, core_if->first_in_nextep_seq);
03453         for (i=0; i <= core_if->dev_if->num_in_eps; i++) {
03454                 DWC_DEBUGPL(DBG_PCDV,"%2d\n", core_if->nextep_seq[i]);
03455         }
03456 
03457         /* Flush the Learning Queue */
03458         resetctl.d32 = DWC_READ_REG32(&core_if->core_global_regs->grstctl);
03459         resetctl.b.intknqflsh = 1;
03460         DWC_WRITE_REG32(&core_if->core_global_regs->grstctl, resetctl.d32);
03461         
03462 
03463 }
03464 
03468 static inline void handle_in_ep_disable_intr(dwc_otg_pcd_t * pcd,
03469                                              const uint32_t epnum)
03470 {
03471         dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
03472         dwc_otg_dev_if_t *dev_if = core_if->dev_if;
03473         deptsiz_data_t dieptsiz = {.d32 = 0 };
03474         dctl_data_t dctl = {.d32 = 0 };
03475         dwc_otg_pcd_ep_t *ep;
03476         dwc_ep_t *dwc_ep;
03477         gintmsk_data_t gintmsk_data;
03478         depctl_data_t depctl;
03479         uint32_t diepdma;
03480         uint32_t remain_to_transfer = 0;
03481         uint8_t i;
03482         uint32_t xfer_size;
03483         
03484         ep = get_in_ep(pcd, epnum);
03485         dwc_ep = &ep->dwc_ep;
03486 
03487         if (dwc_ep->type == DWC_OTG_EP_TYPE_ISOC) {
03488                 dwc_otg_flush_tx_fifo(core_if, dwc_ep->tx_fifo_num);
03489                 complete_ep(ep);
03490                 return;
03491         }
03492 
03493         DWC_DEBUGPL(DBG_PCD, "diepctl%d=%0x\n", epnum,
03494                     DWC_READ_REG32(&dev_if->in_ep_regs[epnum]->diepctl));
03495         dieptsiz.d32 = DWC_READ_REG32(&dev_if->in_ep_regs[epnum]->dieptsiz);
03496         depctl.d32 = DWC_READ_REG32(&dev_if->in_ep_regs[epnum]->diepctl);
03497 
03498         DWC_DEBUGPL(DBG_ANY, "pktcnt=%d size=%d\n",
03499                     dieptsiz.b.pktcnt, dieptsiz.b.xfersize);
03500         
03501         if ((core_if->start_predict == 0) || (depctl.b.eptype & 1)) { 
03502                 if (ep->stopped) {
03503                         if (core_if->en_multiple_tx_fifo)
03504                                 /* Flush the Tx FIFO */
03505                                 dwc_otg_flush_tx_fifo(core_if, dwc_ep->tx_fifo_num);
03506                         /* Clear the Global IN NP NAK */
03507                         dctl.d32 = 0;
03508                         dctl.b.cgnpinnak = 1;
03509                         DWC_MODIFY_REG32(&dev_if->dev_global_regs->dctl, dctl.d32, dctl.d32); 
03510                         /* Restart the transaction */
03511                         if (dieptsiz.b.pktcnt != 0 || dieptsiz.b.xfersize != 0) {
03512                                 restart_transfer(pcd, epnum);
03513                         }
03514                 } else {
03515                         /* Restart the transaction */
03516                         if (dieptsiz.b.pktcnt != 0 || dieptsiz.b.xfersize != 0) {
03517                                 restart_transfer(pcd, epnum);
03518                         }
03519                         DWC_DEBUGPL(DBG_ANY, "STOPPED!!!\n");
03520                 }
03521                 return;
03522         }
03523 
03524         if (core_if->start_predict > 2) {       // NP IN EP
03525                 core_if->start_predict--;
03526                 return;
03527         }
03528 
03529         core_if->start_predict--;
03530         
03531         if (core_if->start_predict == 1) {      // All NP IN Ep's disabled now
03532 
03533                 predict_nextep_seq(core_if);
03534                         
03535                 /* Update all active IN EP's NextEP field based of nextep_seq[] */
03536                 for ( i = 0; i <= core_if->dev_if->num_in_eps; i++) {
03537                         depctl.d32 = DWC_READ_REG32(&dev_if->in_ep_regs[i]->diepctl);
03538                         if (core_if->nextep_seq[i] != 0xff) {   // Active NP IN EP
03539                                 depctl.b.nextep = core_if->nextep_seq[i];
03540                                 DWC_WRITE_REG32(&dev_if->in_ep_regs[i]->diepctl, depctl.d32);
03541                         }
03542                 }
03543                 /* Flush Shared NP TxFIFO */
03544                 dwc_otg_flush_tx_fifo(core_if, 0);
03545                 /* Rewind buffers */
03546                 if (!core_if->dma_desc_enable) {                
03547                         i = core_if->first_in_nextep_seq;
03548                         do {
03549                                 ep = get_in_ep(pcd, i);
03550                                 dieptsiz.d32 = DWC_READ_REG32(&dev_if->in_ep_regs[i]->dieptsiz);
03551                                 xfer_size = ep->dwc_ep.total_len - ep->dwc_ep.xfer_count;
03552                                 if (xfer_size > ep->dwc_ep.maxxfer) 
03553                                         xfer_size = ep->dwc_ep.maxxfer;
03554                                 depctl.d32 = DWC_READ_REG32(&dev_if->in_ep_regs[i]->diepctl);
03555                                 if (dieptsiz.b.pktcnt != 0) {
03556                                         if (xfer_size == 0) {
03557                                                 remain_to_transfer = 0;
03558                                         } else {
03559                                                 if ((xfer_size % ep->dwc_ep.maxpacket) == 0) {
03560                                                         remain_to_transfer = 
03561                                                                 dieptsiz.b.pktcnt * ep->dwc_ep.maxpacket;
03562                                                 } else {
03563                                                         remain_to_transfer = ((dieptsiz.b.pktcnt -1) * ep->dwc_ep.maxpacket) 
03564                                                                 + (xfer_size % ep->dwc_ep.maxpacket);
03565                                                 }
03566                                         }
03567                                         diepdma = DWC_READ_REG32(&dev_if->in_ep_regs[i]->diepdma);
03568                                         dieptsiz.b.xfersize = remain_to_transfer;
03569                                         DWC_WRITE_REG32(&dev_if->in_ep_regs[i]->dieptsiz, dieptsiz.d32);
03570                                         diepdma = ep->dwc_ep.dma_addr + (xfer_size - remain_to_transfer);
03571                                         DWC_WRITE_REG32(&dev_if->in_ep_regs[i]->diepdma, diepdma);
03572                                 }
03573                                 i = core_if->nextep_seq[i];
03574                         } while (i != core_if->first_in_nextep_seq);
03575                 } else { // dma_desc_enable
03576                                 DWC_PRINTF("%s Learning Queue not supported in DDMA\n", __func__);
03577                 }
03578                                 
03579                 /* Restart transfers in predicted sequences */
03580                 i = core_if->first_in_nextep_seq;
03581                 do {
03582                         dieptsiz.d32 = DWC_READ_REG32(&dev_if->in_ep_regs[i]->dieptsiz);
03583                         depctl.d32 = DWC_READ_REG32(&dev_if->in_ep_regs[i]->diepctl);
03584                         if (dieptsiz.b.pktcnt != 0) {
03585                                 depctl.d32 = DWC_READ_REG32(&dev_if->in_ep_regs[i]->diepctl);
03586                                 depctl.b.epena = 1;
03587                                 depctl.b.cnak = 1;
03588                                 DWC_WRITE_REG32(&dev_if->in_ep_regs[i]->diepctl, depctl.d32);
03589                         }
03590                         i = core_if->nextep_seq[i];
03591                 } while (i != core_if->first_in_nextep_seq);
03592 
03593                 /* Clear the global non-periodic IN NAK handshake */
03594                 dctl.d32 = 0;
03595                 dctl.b.cgnpinnak = 1;
03596                 DWC_MODIFY_REG32(&dev_if->dev_global_regs->dctl, dctl.d32, dctl.d32); 
03597                         
03598                 /* Unmask EP Mismatch interrupt */
03599                 gintmsk_data.d32 = 0;
03600                 gintmsk_data.b.epmismatch = 1;
03601                 DWC_MODIFY_REG32(&core_if->core_global_regs->gintmsk, 0, gintmsk_data.d32);
03602                 
03603                 core_if->start_predict = 0;
03604 
03605         } 
03606 }
03607 
03611 static inline void handle_in_ep_timeout_intr(dwc_otg_pcd_t * pcd,
03612                                              const uint32_t epnum)
03613 {
03614         dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
03615         dwc_otg_dev_if_t *dev_if = core_if->dev_if;
03616 
03617 #ifdef DEBUG
03618         deptsiz_data_t dieptsiz = {.d32 = 0 };
03619         uint32_t num = 0;
03620 #endif
03621         dctl_data_t dctl = {.d32 = 0 };
03622         dwc_otg_pcd_ep_t *ep;
03623 
03624         gintmsk_data_t intr_mask = {.d32 = 0 };
03625 
03626         ep = get_in_ep(pcd, epnum);
03627 
03628         /* Disable the NP Tx Fifo Empty Interrrupt */
03629         if (!core_if->dma_enable) {
03630                 intr_mask.b.nptxfempty = 1;
03631                 DWC_MODIFY_REG32(&core_if->core_global_regs->gintmsk,
03632                                  intr_mask.d32, 0);
03633         }
03636         /*
03637          * Non-periodic EP
03638          */
03639         /* Enable the Global IN NAK Effective Interrupt */
03640         intr_mask.b.ginnakeff = 1;
03641         DWC_MODIFY_REG32(&core_if->core_global_regs->gintmsk, 0, intr_mask.d32);
03642 
03643         /* Set Global IN NAK */
03644         dctl.b.sgnpinnak = 1;
03645         DWC_MODIFY_REG32(&dev_if->dev_global_regs->dctl, dctl.d32, dctl.d32);
03646 
03647         ep->stopped = 1;
03648 
03649 #ifdef DEBUG
03650         dieptsiz.d32 = DWC_READ_REG32(&dev_if->in_ep_regs[num]->dieptsiz);
03651         DWC_DEBUGPL(DBG_ANY, "pktcnt=%d size=%d\n",
03652                     dieptsiz.b.pktcnt, dieptsiz.b.xfersize);
03653 #endif
03654 
03655 #ifdef DISABLE_PERIODIC_EP
03656         /*
03657          * Set the NAK bit for this EP to
03658          * start the disable process.
03659          */
03660         diepctl.d32 = 0;
03661         diepctl.b.snak = 1;
03662         DWC_MODIFY_REG32(&dev_if->in_ep_regs[num]->diepctl, diepctl.d32,
03663                          diepctl.d32);
03664         ep->disabling = 1;
03665         ep->stopped = 1;
03666 #endif
03667 }
03668 
03672 static inline int32_t handle_in_ep_nak_intr(dwc_otg_pcd_t * pcd,
03673                                             const uint32_t epnum)
03674 {
03676         dwc_otg_core_if_t *core_if;
03677         diepmsk_data_t intr_mask = {.d32 = 0 };
03678 
03679         DWC_PRINTF("INTERRUPT Handler not implemented for %s\n", "IN EP NAK");
03680         core_if = GET_CORE_IF(pcd);
03681         intr_mask.b.nak = 1;
03682 
03683         if (core_if->multiproc_int_enable) {
03684                 DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->
03685                                  diepeachintmsk[epnum], intr_mask.d32, 0);
03686         } else {
03687                 DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->diepmsk,
03688                                  intr_mask.d32, 0);
03689         }
03690 
03691         return 1;
03692 }
03693 
03697 static inline int32_t handle_out_ep_babble_intr(dwc_otg_pcd_t * pcd,
03698                                                 const uint32_t epnum)
03699 {
03701         dwc_otg_core_if_t *core_if;
03702         doepmsk_data_t intr_mask = {.d32 = 0 };
03703 
03704         DWC_PRINTF("INTERRUPT Handler not implemented for %s\n",
03705                    "OUT EP Babble");
03706         core_if = GET_CORE_IF(pcd);
03707         intr_mask.b.babble = 1;
03708 
03709         if (core_if->multiproc_int_enable) {
03710                 DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->
03711                                  doepeachintmsk[epnum], intr_mask.d32, 0);
03712         } else {
03713                 DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->doepmsk,
03714                                  intr_mask.d32, 0);
03715         }
03716 
03717         return 1;
03718 }
03719 
03723 static inline int32_t handle_out_ep_nak_intr(dwc_otg_pcd_t * pcd,
03724                                              const uint32_t epnum)
03725 {
03727         dwc_otg_core_if_t *core_if;
03728         doepmsk_data_t intr_mask = {.d32 = 0 };
03729 
03730         DWC_PRINTF("INTERRUPT Handler not implemented for %s\n", "OUT EP NAK");
03731         core_if = GET_CORE_IF(pcd);
03732         intr_mask.b.nak = 1;
03733 
03734         if (core_if->multiproc_int_enable) {
03735                 DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->
03736                                  doepeachintmsk[epnum], intr_mask.d32, 0);
03737         } else {
03738                 DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->doepmsk,
03739                                  intr_mask.d32, 0);
03740         }
03741 
03742         return 1;
03743 }
03744 
03748 static inline int32_t handle_out_ep_nyet_intr(dwc_otg_pcd_t * pcd,
03749                                               const uint32_t epnum)
03750 {
03752         dwc_otg_core_if_t *core_if;
03753         doepmsk_data_t intr_mask = {.d32 = 0 };
03754 
03755         DWC_PRINTF("INTERRUPT Handler not implemented for %s\n", "OUT EP NYET");
03756         core_if = GET_CORE_IF(pcd);
03757         intr_mask.b.nyet = 1;
03758 
03759         if (core_if->multiproc_int_enable) {
03760                 DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->
03761                                  doepeachintmsk[epnum], intr_mask.d32, 0);
03762         } else {
03763                 DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->doepmsk,
03764                                  intr_mask.d32, 0);
03765         }
03766 
03767         return 1;
03768 }
03769 
03786 static int32_t dwc_otg_pcd_handle_in_ep_intr(dwc_otg_pcd_t * pcd)
03787 {
03788 #define CLEAR_IN_EP_INTR(__core_if,__epnum,__intr) \
03789 do { \
03790                 diepint_data_t diepint = {.d32=0}; \
03791                 diepint.b.__intr = 1; \
03792                 DWC_WRITE_REG32(&__core_if->dev_if->in_ep_regs[__epnum]->diepint, \
03793                 diepint.d32); \
03794 } while (0)
03795 
03796         dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
03797         dwc_otg_dev_if_t *dev_if = core_if->dev_if;
03798         diepint_data_t diepint = {.d32 = 0 };
03799         depctl_data_t depctl = {.d32 = 0 };
03800         uint32_t ep_intr;
03801         uint32_t epnum = 0;
03802         dwc_otg_pcd_ep_t *ep;
03803         dwc_ep_t *dwc_ep;
03804         gintmsk_data_t intr_mask = {.d32 = 0 };
03805 
03806         DWC_DEBUGPL(DBG_PCDV, "%s(%p)\n", __func__, pcd);
03807 
03808         /* Read in the device interrupt bits */
03809         ep_intr = dwc_otg_read_dev_all_in_ep_intr(core_if);
03810 
03811         /* Service the Device IN interrupts for each endpoint */
03812         while (ep_intr) {
03813                 if (ep_intr & 0x1) {
03814                         uint32_t empty_msk;
03815                         /* Get EP pointer */
03816                         ep = get_in_ep(pcd, epnum);
03817                         dwc_ep = &ep->dwc_ep;
03818 
03819                         depctl.d32 =
03820                             DWC_READ_REG32(&dev_if->in_ep_regs[epnum]->diepctl);
03821                         empty_msk =
03822                             DWC_READ_REG32(&dev_if->
03823                                            dev_global_regs->dtknqr4_fifoemptymsk);
03824 
03825                         DWC_DEBUGPL(DBG_PCDV,
03826                                     "IN EP INTERRUPT - %d\nepmty_msk - %8x  diepctl - %8x\n",
03827                                     epnum, empty_msk, depctl.d32);
03828 
03829                         DWC_DEBUGPL(DBG_PCD,
03830                                     "EP%d-%s: type=%d, mps=%d\n",
03831                                     dwc_ep->num, (dwc_ep->is_in ? "IN" : "OUT"),
03832                                     dwc_ep->type, dwc_ep->maxpacket);
03833 
03834                         diepint.d32 =
03835                             dwc_otg_read_dev_in_ep_intr(core_if, dwc_ep);
03836 
03837                         DWC_DEBUGPL(DBG_PCDV,
03838                                     "EP %d Interrupt Register - 0x%x\n", epnum,
03839                                     diepint.d32);
03840                         /* Transfer complete */
03841                         if (diepint.b.xfercompl) {
03842                                 /* Disable the NP Tx FIFO Empty
03843                                  * Interrrupt */
03844                                 if (core_if->en_multiple_tx_fifo == 0) {
03845                                         intr_mask.b.nptxfempty = 1;
03846                                         DWC_MODIFY_REG32
03847                                             (&core_if->core_global_regs->gintmsk,
03848                                              intr_mask.d32, 0);
03849                                 } else {
03850                                         /* Disable the Tx FIFO Empty Interrupt for this EP */
03851                                         uint32_t fifoemptymsk =
03852                                             0x1 << dwc_ep->num;
03853                                         DWC_MODIFY_REG32(&core_if->
03854                                                          dev_if->dev_global_regs->dtknqr4_fifoemptymsk,
03855                                                          fifoemptymsk, 0);
03856                                 }
03857                                 /* Clear the bit in DIEPINTn for this interrupt */
03858                                 CLEAR_IN_EP_INTR(core_if, epnum, xfercompl);
03859 
03860                                 /* Complete the transfer */
03861                                 if (epnum == 0) {
03862                                         handle_ep0(pcd);
03863                                 }
03864 #ifdef DWC_EN_ISOC
03865                                 else if (dwc_ep->type == DWC_OTG_EP_TYPE_ISOC) {
03866                                         if (!ep->stopped)
03867                                                 complete_iso_ep(pcd, ep);
03868                                 }
03869 #endif /* DWC_EN_ISOC */
03870 #ifdef DWC_UTE_PER_IO
03871                                 else if (dwc_ep->type == DWC_OTG_EP_TYPE_ISOC) {
03872                                         if (!ep->stopped)
03873                                                 complete_xiso_ep(ep);
03874                                 }
03875 #endif /* DWC_UTE_PER_IO */
03876                                 else {
03877                                         if (dwc_ep->type == DWC_OTG_EP_TYPE_ISOC && 
03878                                                         dwc_ep->bInterval > 1) {
03879                                                 dwc_ep->frame_num += dwc_ep->bInterval;
03880                                                 if (dwc_ep->frame_num > 0x3FFF)
03881                                                 {
03882                                                         dwc_ep->frm_overrun = 1;
03883                                                         dwc_ep->frame_num &= 0x3FFF;
03884                                                 } else 
03885                                                         dwc_ep->frm_overrun = 0;
03886                                         }
03887                                         complete_ep(ep);
03888                                         if(diepint.b.nak)
03889                                                 CLEAR_IN_EP_INTR(core_if, epnum, nak);
03890                                 }
03891                         }
03892                         /* Endpoint disable      */
03893                         if (diepint.b.epdisabled) {
03894                                 DWC_DEBUGPL(DBG_ANY, "EP%d IN disabled\n",
03895                                             epnum);
03896                                 handle_in_ep_disable_intr(pcd, epnum);
03897 
03898                                 /* Clear the bit in DIEPINTn for this interrupt */
03899                                 CLEAR_IN_EP_INTR(core_if, epnum, epdisabled);
03900                         }
03901                         /* AHB Error */
03902                         if (diepint.b.ahberr) {
03903                                 DWC_ERROR("EP%d IN AHB Error\n", epnum);
03904                                 /* Clear the bit in DIEPINTn for this interrupt */
03905                                 CLEAR_IN_EP_INTR(core_if, epnum, ahberr);
03906                         }
03907                         /* TimeOUT Handshake (non-ISOC IN EPs) */
03908                         if (diepint.b.timeout) {
03909                                 DWC_ERROR("EP%d IN Time-out\n", epnum);
03910                                 handle_in_ep_timeout_intr(pcd, epnum);
03911 
03912                                 CLEAR_IN_EP_INTR(core_if, epnum, timeout);
03913                         }
03915                         if (diepint.b.intktxfemp) {
03916                                 DWC_DEBUGPL(DBG_ANY,
03917                                             "EP%d IN TKN TxFifo Empty\n",
03918                                             epnum);
03919                                 if (!ep->stopped && epnum != 0) {
03920 
03921                                         diepmsk_data_t diepmsk = {.d32 = 0 };
03922                                         diepmsk.b.intktxfemp = 1;
03923 
03924                                         if (core_if->multiproc_int_enable) {
03925                                                 DWC_MODIFY_REG32
03926                                                     (&dev_if->dev_global_regs->diepeachintmsk
03927                                                      [epnum], diepmsk.d32, 0);
03928                                         } else {
03929                                                 DWC_MODIFY_REG32
03930                                                     (&dev_if->dev_global_regs->diepmsk,
03931                                                      diepmsk.d32, 0);
03932                                         }
03933                                 } else if (core_if->dma_desc_enable
03934                                            && epnum == 0
03935                                            && pcd->ep0state ==
03936                                            EP0_OUT_STATUS_PHASE) {
03937                                         // EP0 IN set STALL
03938                                         depctl.d32 =
03939                                             DWC_READ_REG32(&dev_if->in_ep_regs
03940                                                            [epnum]->diepctl);
03941 
03942                                         /* set the disable and stall bits */
03943                                         if (depctl.b.epena) {
03944                                                 depctl.b.epdis = 1;
03945                                         }
03946                                         depctl.b.stall = 1;
03947                                         DWC_WRITE_REG32(&dev_if->in_ep_regs
03948                                                         [epnum]->diepctl,
03949                                                         depctl.d32);
03950                                 }
03951                                 CLEAR_IN_EP_INTR(core_if, epnum, intktxfemp);
03952                         }
03954                         if (diepint.b.intknepmis) {
03955                                 DWC_DEBUGPL(DBG_ANY,
03956                                             "EP%d IN TKN EP Mismatch\n", epnum);
03957                                 CLEAR_IN_EP_INTR(core_if, epnum, intknepmis);                           
03958                         }
03960                         if (diepint.b.inepnakeff) {
03961                                 DWC_DEBUGPL(DBG_ANY,
03962                                             "EP%d IN EP NAK Effective\n",
03963                                             epnum);
03964                                 /* Periodic EP */
03965                                 if (ep->disabling) {
03966                                         depctl.d32 = 0;
03967                                         depctl.b.snak = 1;
03968                                         depctl.b.epdis = 1;
03969                                         DWC_MODIFY_REG32(&dev_if->in_ep_regs
03970                                                          [epnum]->diepctl,
03971                                                          depctl.d32,
03972                                                          depctl.d32);
03973                                 }
03974                                 CLEAR_IN_EP_INTR(core_if, epnum, inepnakeff);
03975 
03976                         }
03977 
03979                         if (diepint.b.emptyintr) {
03980                                 DWC_DEBUGPL(DBG_ANY,
03981                                             "EP%d Tx FIFO Empty Intr \n",
03982                                             epnum);
03983                                 write_empty_tx_fifo(pcd, epnum);
03984 
03985                                 CLEAR_IN_EP_INTR(core_if, epnum, emptyintr);
03986 
03987                         }
03988 
03990                         if (diepint.b.bna) {
03991                                 CLEAR_IN_EP_INTR(core_if, epnum, bna);
03992                                 if (core_if->dma_desc_enable) {
03993 #ifdef DWC_EN_ISOC
03994                                         if (dwc_ep->type ==
03995                                             DWC_OTG_EP_TYPE_ISOC) {
03996                                                 /*
03997                                                  * This checking is performed to prevent first "false" BNA
03998                                                  * handling occuring right after reconnect
03999                                                  */
04000                                                 if (dwc_ep->next_frame !=
04001                                                     0xffffffff)
04002                                                         dwc_otg_pcd_handle_iso_bna(ep);
04003                                         } else
04004 #endif                          /* DWC_EN_ISOC */
04005                                         {
04006                                                 dwc_otg_pcd_handle_noniso_bna(ep);
04007                                         }
04008                                 }
04009                         }
04010                         /* NAK Interrutp */
04011                         if (diepint.b.nak) {
04012                                 DWC_DEBUGPL(DBG_ANY, "EP%d IN NAK Interrupt\n",
04013                                             epnum);
04014                                 if (ep->dwc_ep.type == DWC_OTG_EP_TYPE_ISOC)
04015                                 {
04016                                         depctl_data_t depctl;
04017                                         if (ep->dwc_ep.frame_num == 0xFFFFFFFF) 
04018                                         {
04019                                                 ep->dwc_ep.frame_num = core_if->frame_num;
04020                                                 if (ep->dwc_ep.bInterval > 1) 
04021                                                 {
04022                                                         depctl.d32 = 0;
04023                                                         depctl.d32 = DWC_READ_REG32(&dev_if->in_ep_regs[epnum]->diepctl);
04024                                                         if (ep->dwc_ep.frame_num & 0x1) {
04025                                                                 depctl.b.setd1pid = 1;
04026                                                                 depctl.b.setd0pid = 0;
04027                                                         } else {
04028                                                                 depctl.b.setd0pid = 1;
04029                                                                 depctl.b.setd1pid = 0;
04030                                                         }
04031                                                         DWC_WRITE_REG32(&dev_if->in_ep_regs[epnum]->diepctl, depctl.d32);
04032                                                 }
04033                                                 start_next_request(ep);
04034                                         }
04035                                         ep->dwc_ep.frame_num += ep->dwc_ep.bInterval;
04036                                         if (dwc_ep->frame_num > 0x3FFF)
04037                                         {
04038                                                 dwc_ep->frm_overrun = 1;
04039                                                 dwc_ep->frame_num &= 0x3FFF;
04040                                         } else 
04041                                                 dwc_ep->frm_overrun = 0;
04042                                 }
04043 
04044                                 CLEAR_IN_EP_INTR(core_if, epnum, nak);
04045                         }
04046                 }
04047                 epnum++;
04048                 ep_intr >>= 1;
04049         }
04050 
04051         return 1;
04052 #undef CLEAR_IN_EP_INTR
04053 }
04054 
04068 static int32_t dwc_otg_pcd_handle_out_ep_intr(dwc_otg_pcd_t * pcd)
04069 {
04070 #define CLEAR_OUT_EP_INTR(__core_if,__epnum,__intr) \
04071 do { \
04072                 doepint_data_t doepint = {.d32=0}; \
04073                 doepint.b.__intr = 1; \
04074                 DWC_WRITE_REG32(&__core_if->dev_if->out_ep_regs[__epnum]->doepint, \
04075                 doepint.d32); \
04076 } while (0)
04077 
04078         dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
04079         uint32_t ep_intr;
04080         doepint_data_t doepint = {.d32 = 0 };
04081         uint32_t epnum = 0;
04082         dwc_otg_pcd_ep_t *ep;
04083         dwc_ep_t *dwc_ep;
04084         dctl_data_t dctl = {.d32 = 0 };
04085         gintmsk_data_t gintmsk = {.d32 = 0 };
04086 
04087 
04088         DWC_DEBUGPL(DBG_PCDV, "%s()\n", __func__);
04089 
04090         /* Read in the device interrupt bits */
04091         ep_intr = dwc_otg_read_dev_all_out_ep_intr(core_if);
04092 
04093         while (ep_intr) {
04094                 if (ep_intr & 0x1) {
04095                         /* Get EP pointer */
04096                         ep = get_out_ep(pcd, epnum);
04097                         dwc_ep = &ep->dwc_ep;
04098 
04099 #ifdef VERBOSE
04100                         DWC_DEBUGPL(DBG_PCDV,
04101                                     "EP%d-%s: type=%d, mps=%d\n",
04102                                     dwc_ep->num, (dwc_ep->is_in ? "IN" : "OUT"),
04103                                     dwc_ep->type, dwc_ep->maxpacket);
04104 #endif
04105                         doepint.d32 =
04106                             dwc_otg_read_dev_out_ep_intr(core_if, dwc_ep);
04107 
04108                         /* Transfer complete */
04109                         if (doepint.b.xfercompl) {
04110 
04111                                 if (epnum == 0) {
04112                                         /* Clear the bit in DOEPINTn for this interrupt */
04113                                         CLEAR_OUT_EP_INTR(core_if, epnum,
04114                                                           xfercompl);
04115                                         if (core_if->dma_desc_enable == 0
04116                                             || pcd->ep0state != EP0_IDLE)
04117                                                 handle_ep0(pcd);
04118 #ifdef DWC_EN_ISOC
04119                                 } else if (dwc_ep->type == DWC_OTG_EP_TYPE_ISOC) {
04120                                         if (doepint.b.pktdrpsts == 0) {
04121                                                 /* Clear the bit in DOEPINTn for this interrupt */
04122                                                 CLEAR_OUT_EP_INTR(core_if,
04123                                                                   epnum,
04124                                                                   xfercompl);
04125                                                 complete_iso_ep(pcd, ep);
04126                                         } else {
04127 
04128                                                 doepint_data_t doepint = {.d32 = 0 };
04129                                                 doepint.b.xfercompl = 1;
04130                                                 doepint.b.pktdrpsts = 1;
04131                                                 DWC_WRITE_REG32
04132                                                     (&core_if->dev_if->out_ep_regs
04133                                                      [epnum]->doepint,
04134                                                      doepint.d32);
04135                                                 if (handle_iso_out_pkt_dropped
04136                                                     (core_if, dwc_ep)) {
04137                                                         complete_iso_ep(pcd,
04138                                                                         ep);
04139                                                 }
04140                                         }
04141 #endif /* DWC_EN_ISOC */
04142 #ifdef DWC_UTE_PER_IO
04143                                 } else if (dwc_ep->type == DWC_OTG_EP_TYPE_ISOC) {
04144                                         CLEAR_OUT_EP_INTR(core_if, epnum, xfercompl);
04145                                         if (!ep->stopped)
04146                                                 complete_xiso_ep(ep);
04147 #endif /* DWC_UTE_PER_IO */
04148                                 } else {
04149                                         /* Clear the bit in DOEPINTn for this interrupt */
04150                                         CLEAR_OUT_EP_INTR(core_if, epnum,
04151                                                           xfercompl);
04152 
04153                                         if (core_if->core_params->dev_out_nak) {
04154                                                 DWC_TIMER_CANCEL(pcd->core_if->ep_xfer_timer[epnum]);
04155                                                 pcd->core_if->ep_xfer_info[epnum].state = 0;
04156 #ifdef DEBUG
04157                                                 print_memory_payload(pcd, dwc_ep);
04158 #endif
04159                                         }
04160                                         complete_ep(ep);                                                
04161                                 }
04162 
04163                         }
04164 
04165                         /* Endpoint disable      */
04166                         if (doepint.b.epdisabled) {
04167 
04168                                 /* Clear the bit in DOEPINTn for this interrupt */
04169                                 CLEAR_OUT_EP_INTR(core_if, epnum, epdisabled);
04170                                 if (core_if->core_params->dev_out_nak) {
04171 #ifdef DEBUG
04172                                         print_memory_payload(pcd, dwc_ep);
04173 #endif
04174                                         /* In case of timeout condition */
04175                                         if (core_if->ep_xfer_info[epnum].state == 2) {
04176                                                 dctl.d32 = DWC_READ_REG32(&core_if->dev_if->
04177                                                                                 dev_global_regs->dctl);
04178                                                 dctl.b.cgoutnak = 1;
04179                                                 DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->dctl,
04180                                                                                                                                 dctl.d32);
04181                                                 /* Unmask goutnakeff interrupt which was masked
04182                                                  * during handle nak out interrupt */
04183                                                 gintmsk.b.goutnakeff = 1;
04184                                                 DWC_MODIFY_REG32(&core_if->core_global_regs->gintmsk,
04185                                                                                                                                 0, gintmsk.d32);
04186                                         
04187                                                 complete_ep(ep);
04188                                         }
04189                                 }
04190                                 if (ep->dwc_ep.type == DWC_OTG_EP_TYPE_ISOC)
04191                                 {
04192                                         dctl_data_t dctl;
04193                                         gintmsk_data_t intr_mask = {.d32 = 0};
04194                                         dwc_otg_pcd_request_t *req = 0;
04195 
04196                                         dctl.d32 = DWC_READ_REG32(&core_if->dev_if->
04197                                                 dev_global_regs->dctl);
04198                                         dctl.b.cgoutnak = 1;
04199                                         DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->dctl,
04200                                                 dctl.d32);
04201 
04202                                         intr_mask.d32 = 0;
04203                                         intr_mask.b.incomplisoout = 1;     
04204 
04205                                         /* Get any pending requests */
04206                                         if (!DWC_CIRCLEQ_EMPTY(&ep->queue)) {
04207                                                 req = DWC_CIRCLEQ_FIRST(&ep->queue);
04208                                                 if (!req) {
04209                                                         DWC_PRINTF("complete_ep 0x%p, req = NULL!\n", ep);
04210                                                 } else {
04211                                                         dwc_otg_request_done(ep, req, 0);
04212                                                         start_next_request(ep);
04213                                                 }
04214                                         } else {
04215                                                 DWC_PRINTF("complete_ep 0x%p, ep->queue empty!\n", ep);
04216                                         }
04217                                 }
04218                         }
04219                         /* AHB Error */
04220                         if (doepint.b.ahberr) {
04221                                 DWC_ERROR("EP%d OUT AHB Error\n", epnum);
04222                                 DWC_ERROR("EP%d DEPDMA=0x%08x \n",
04223                                           epnum, core_if->dev_if->out_ep_regs[epnum]->doepdma);
04224                                 CLEAR_OUT_EP_INTR(core_if, epnum, ahberr);
04225                         }
04226                         /* Setup Phase Done (contorl EPs) */
04227                         if (doepint.b.setup) {
04228 #ifdef DEBUG_EP0
04229                                 DWC_DEBUGPL(DBG_PCD, "EP%d SETUP Done\n",
04230                                             epnum);
04231 #endif
04232                                 CLEAR_OUT_EP_INTR(core_if, epnum, setup);
04233 
04234                                 handle_ep0(pcd);
04235                         }
04236 
04238                         if (doepint.b.bna) {
04239                                 CLEAR_OUT_EP_INTR(core_if, epnum, bna);
04240                                 if (core_if->dma_desc_enable) {
04241 #ifdef DWC_EN_ISOC
04242                                         if (dwc_ep->type ==
04243                                             DWC_OTG_EP_TYPE_ISOC) {
04244                                                 /*
04245                                                  * This checking is performed to prevent first "false" BNA
04246                                                  * handling occuring right after reconnect
04247                                                  */
04248                                                 if (dwc_ep->next_frame !=
04249                                                     0xffffffff)
04250                                                         dwc_otg_pcd_handle_iso_bna(ep);
04251                                         } else
04252 #endif                          /* DWC_EN_ISOC */
04253                                         {
04254                                                 dwc_otg_pcd_handle_noniso_bna(ep);
04255                                         }
04256                                 }
04257                         }
04258                         if (doepint.b.stsphsercvd) {
04259                                 CLEAR_OUT_EP_INTR(core_if, epnum, stsphsercvd);
04260                                 if (core_if->dma_desc_enable) {
04261                                         do_setup_in_status_phase(pcd);
04262                                 }
04263                         }
04264                         /* Babble Interrutp */
04265                         if (doepint.b.babble) {
04266                                 DWC_DEBUGPL(DBG_ANY, "EP%d OUT Babble\n",
04267                                             epnum);
04268                                 handle_out_ep_babble_intr(pcd, epnum);
04269 
04270                                 CLEAR_OUT_EP_INTR(core_if, epnum, babble);
04271                         }
04272                         if (doepint.b.outtknepdis)
04273                         {
04274                                 DWC_DEBUGPL(DBG_ANY, "EP%d OUT Token received when EP is \
04275                                         disabled\n",epnum);
04276                                 if (ep->dwc_ep.type == DWC_OTG_EP_TYPE_ISOC)
04277                                 {
04278                                         doepmsk_data_t doepmsk = {.d32 = 0};
04279                                         ep->dwc_ep.frame_num = core_if->frame_num;
04280                                         if (ep->dwc_ep.bInterval > 1) 
04281                                         {
04282                                                 depctl_data_t depctl;
04283                                                 depctl.d32 = DWC_READ_REG32(&core_if->dev_if->
04284                                                                                                         out_ep_regs[epnum]->doepctl);
04285                                                 if (ep->dwc_ep.frame_num & 0x1) {
04286                                                         depctl.b.setd1pid = 1;
04287                                                         depctl.b.setd0pid = 0;
04288                                                 } else {
04289                                                         depctl.b.setd0pid = 1;
04290                                                         depctl.b.setd1pid = 0;
04291                                                 }
04292                                                 DWC_WRITE_REG32(&core_if->dev_if->
04293                                                                                 out_ep_regs[epnum]->doepctl, depctl.d32);
04294                                         }
04295                                         start_next_request(ep);
04296                                         doepmsk.b.outtknepdis = 1;
04297                                         DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->doepmsk, 
04298                                                                  doepmsk.d32, 0);
04299                                 }
04300                                 CLEAR_OUT_EP_INTR(core_if, epnum, outtknepdis);
04301                         }
04302                         
04303                         /* NAK Interrutp */
04304                         if (doepint.b.nak) {
04305                                 DWC_DEBUGPL(DBG_ANY, "EP%d OUT NAK\n", epnum);
04306                                 handle_out_ep_nak_intr(pcd, epnum);
04307 
04308                                 CLEAR_OUT_EP_INTR(core_if, epnum, nak);
04309                         }
04310                         /* NYET Interrutp */
04311                         if (doepint.b.nyet) {
04312                                 DWC_DEBUGPL(DBG_ANY, "EP%d OUT NYET\n", epnum);
04313                                 handle_out_ep_nyet_intr(pcd, epnum);
04314 
04315                                 CLEAR_OUT_EP_INTR(core_if, epnum, nyet);
04316                         }
04317                 }
04318 
04319                 epnum++;
04320                 ep_intr >>= 1;
04321         }
04322 
04323         return 1;
04324 
04325 #undef CLEAR_OUT_EP_INTR
04326 }
04327 static int drop_transfer(uint32_t trgt_fr, uint32_t curr_fr, uint8_t frm_overrun)
04328 {
04329         int retval = 0;
04330         if(!frm_overrun && curr_fr >= trgt_fr) 
04331                 retval = 1;
04332         else if (frm_overrun && (curr_fr >= trgt_fr && ((curr_fr - trgt_fr) < 0x3FFF/2)))
04333                 retval = 1;
04334         return retval;
04335 }
04348 int32_t dwc_otg_pcd_handle_incomplete_isoc_in_intr(dwc_otg_pcd_t * pcd)
04349 {
04350         gintsts_data_t gintsts;
04351 
04352 #ifdef DWC_EN_ISOC
04353         dwc_otg_dev_if_t *dev_if;
04354         deptsiz_data_t deptsiz = {.d32 = 0 };
04355         depctl_data_t depctl = {.d32 = 0 };
04356         dsts_data_t dsts = {.d32 = 0 };
04357         dwc_ep_t *dwc_ep;
04358         int i;
04359 
04360         dev_if = GET_CORE_IF(pcd)->dev_if;
04361 
04362         for (i = 1; i <= dev_if->num_in_eps; ++i) {
04363                 dwc_ep = &pcd->in_ep[i].dwc_ep;
04364                 if (dwc_ep->active && dwc_ep->type == DWC_OTG_EP_TYPE_ISOC) {
04365                         deptsiz.d32 =
04366                             DWC_READ_REG32(&dev_if->in_ep_regs[i]->dieptsiz);
04367                         depctl.d32 =
04368                             DWC_READ_REG32(&dev_if->in_ep_regs[i]->diepctl);
04369 
04370                         if (depctl.b.epdis && deptsiz.d32) {
04371                                 set_current_pkt_info(GET_CORE_IF(pcd), dwc_ep);
04372                                 if (dwc_ep->cur_pkt >= dwc_ep->pkt_cnt) {
04373                                         dwc_ep->cur_pkt = 0;
04374                                         dwc_ep->proc_buf_num =
04375                                             (dwc_ep->proc_buf_num ^ 1) & 0x1;
04376 
04377                                         if (dwc_ep->proc_buf_num) {
04378                                                 dwc_ep->cur_pkt_addr =
04379                                                     dwc_ep->xfer_buff1;
04380                                                 dwc_ep->cur_pkt_dma_addr =
04381                                                     dwc_ep->dma_addr1;
04382                                         } else {
04383                                                 dwc_ep->cur_pkt_addr =
04384                                                     dwc_ep->xfer_buff0;
04385                                                 dwc_ep->cur_pkt_dma_addr =
04386                                                     dwc_ep->dma_addr0;
04387                                         }
04388 
04389                                 }
04390 
04391                                 dsts.d32 =
04392                                     DWC_READ_REG32(&GET_CORE_IF(pcd)->dev_if->
04393                                                    dev_global_regs->dsts);
04394                                 dwc_ep->next_frame = dsts.b.soffn;
04395 
04396                                 dwc_otg_iso_ep_start_frm_transfer(GET_CORE_IF
04397                                                                   (pcd),
04398                                                                   dwc_ep);
04399                         }
04400                 }
04401         }
04402 
04403 #else
04404         depctl_data_t depctl = {.d32 = 0 };
04405         dwc_ep_t *dwc_ep;
04406         dwc_otg_dev_if_t *dev_if;
04407         int i;
04408         dev_if = GET_CORE_IF(pcd)->dev_if;
04409 
04410         DWC_DEBUGPL(DBG_PCD,"Incomplete ISO IN \n");
04411         
04412         for (i = 1; i <= dev_if->num_in_eps; ++i) {
04413                 dwc_ep = &pcd->in_ep[i-1].dwc_ep;
04414                 depctl.d32 =
04415                         DWC_READ_REG32(&dev_if->in_ep_regs[i]->diepctl);
04416                 if (depctl.b.epena && dwc_ep->type == DWC_OTG_EP_TYPE_ISOC) {
04417                         if (drop_transfer(dwc_ep->frame_num, GET_CORE_IF(pcd)->frame_num, 
04418                                                         dwc_ep->frm_overrun))
04419                         {
04420                                 depctl.d32 =
04421                                         DWC_READ_REG32(&dev_if->in_ep_regs[i]->diepctl);
04422                                 depctl.b.snak = 1;
04423                                 depctl.b.epdis = 1;
04424                                 DWC_MODIFY_REG32(&dev_if->in_ep_regs[i]->diepctl, depctl.d32, depctl.d32);
04425                         }
04426                 }
04427         }
04428 
04429         /*intr_mask.b.incomplisoin = 1;
04430         DWC_MODIFY_REG32(&GET_CORE_IF(pcd)->core_global_regs->gintmsk,
04431                          intr_mask.d32, 0);      */
04432 #endif                          //DWC_EN_ISOC
04433 
04434         /* Clear interrupt */
04435         gintsts.d32 = 0;
04436         gintsts.b.incomplisoin = 1;
04437         DWC_WRITE_REG32(&GET_CORE_IF(pcd)->core_global_regs->gintsts,
04438                         gintsts.d32);
04439 
04440         return 1;
04441 }
04442 
04458 int32_t dwc_otg_pcd_handle_incomplete_isoc_out_intr(dwc_otg_pcd_t * pcd)
04459 {
04460 
04461         gintsts_data_t gintsts;
04462 
04463 #ifdef DWC_EN_ISOC
04464         dwc_otg_dev_if_t *dev_if;
04465         deptsiz_data_t deptsiz = {.d32 = 0 };
04466         depctl_data_t depctl = {.d32 = 0 };
04467         dsts_data_t dsts = {.d32 = 0 };
04468         dwc_ep_t *dwc_ep;
04469         int i;
04470 
04471         dev_if = GET_CORE_IF(pcd)->dev_if;
04472 
04473         for (i = 1; i <= dev_if->num_out_eps; ++i) {
04474                 dwc_ep = &pcd->in_ep[i].dwc_ep;
04475                 if (pcd->out_ep[i].dwc_ep.active &&
04476                     pcd->out_ep[i].dwc_ep.type == DWC_OTG_EP_TYPE_ISOC) {
04477                         deptsiz.d32 =
04478                             DWC_READ_REG32(&dev_if->out_ep_regs[i]->doeptsiz);
04479                         depctl.d32 =
04480                             DWC_READ_REG32(&dev_if->out_ep_regs[i]->doepctl);
04481 
04482                         if (depctl.b.epdis && deptsiz.d32) {
04483                                 set_current_pkt_info(GET_CORE_IF(pcd),
04484                                                      &pcd->out_ep[i].dwc_ep);
04485                                 if (dwc_ep->cur_pkt >= dwc_ep->pkt_cnt) {
04486                                         dwc_ep->cur_pkt = 0;
04487                                         dwc_ep->proc_buf_num =
04488                                             (dwc_ep->proc_buf_num ^ 1) & 0x1;
04489 
04490                                         if (dwc_ep->proc_buf_num) {
04491                                                 dwc_ep->cur_pkt_addr =
04492                                                     dwc_ep->xfer_buff1;
04493                                                 dwc_ep->cur_pkt_dma_addr =
04494                                                     dwc_ep->dma_addr1;
04495                                         } else {
04496                                                 dwc_ep->cur_pkt_addr =
04497                                                     dwc_ep->xfer_buff0;
04498                                                 dwc_ep->cur_pkt_dma_addr =
04499                                                     dwc_ep->dma_addr0;
04500                                         }
04501 
04502                                 }
04503 
04504                                 dsts.d32 =
04505                                     DWC_READ_REG32(&GET_CORE_IF(pcd)->dev_if->
04506                                                    dev_global_regs->dsts);
04507                                 dwc_ep->next_frame = dsts.b.soffn;
04508 
04509                                 dwc_otg_iso_ep_start_frm_transfer(GET_CORE_IF
04510                                                                   (pcd),
04511                                                                   dwc_ep);
04512                         }
04513                 }
04514         }
04515 #else
04516 
04517         gintmsk_data_t intr_mask = {.d32 = 0 };
04518         dwc_otg_core_if_t *core_if;
04519         deptsiz_data_t deptsiz = {.d32 = 0 };
04520         depctl_data_t depctl = {.d32 = 0 };
04521         dctl_data_t dctl = {.d32 = 0 };
04522         dwc_ep_t *dwc_ep = NULL;
04523         int i;
04524         core_if = GET_CORE_IF(pcd);
04525 
04526         for (i = 0; i < core_if->dev_if->num_out_eps; ++i) {
04527                 dwc_ep = &pcd->out_ep[i].dwc_ep;
04528                 depctl.d32 =
04529                         DWC_READ_REG32(&core_if->dev_if->out_ep_regs[dwc_ep->num]->doepctl);
04530                 if (depctl.b.epena && depctl.b.dpid == (core_if->frame_num & 0x1)) {
04531                         core_if->dev_if->isoc_ep = dwc_ep;      
04532                         deptsiz.d32 =
04533                                         DWC_READ_REG32(&core_if->dev_if->out_ep_regs[dwc_ep->num]->doeptsiz);
04534                                 break;
04535                 }
04536         }
04537         dctl.d32 = DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dctl);
04538         gintsts.d32 = DWC_READ_REG32(&core_if->core_global_regs->gintsts);
04539         intr_mask.d32 = DWC_READ_REG32(&core_if->core_global_regs->gintmsk);
04540 
04541         if (!intr_mask.b.goutnakeff) {
04542                 /* Unmask it */
04543                 intr_mask.b.goutnakeff = 1;
04544                 DWC_WRITE_REG32(&core_if->core_global_regs->gintmsk, intr_mask.d32);
04545         }
04546         if (!gintsts.b.goutnakeff) {
04547                 dctl.b.sgoutnak = 1;
04548         }
04549         DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->dctl, dctl.d32);
04550 
04551         depctl.d32 = DWC_READ_REG32(&core_if->dev_if->out_ep_regs[dwc_ep->num]->doepctl);
04552         if (depctl.b.epena) {
04553                 depctl.b.epdis = 1;
04554                 depctl.b.snak = 1;
04555         }
04556         DWC_WRITE_REG32(&core_if->dev_if->out_ep_regs[dwc_ep->num]->doepctl, depctl.d32);
04557 
04558         intr_mask.d32 = 0;
04559         intr_mask.b.incomplisoout = 1;
04560                 
04561 #endif /* DWC_EN_ISOC */
04562 
04563         /* Clear interrupt */
04564         gintsts.d32 = 0;
04565         gintsts.b.incomplisoout = 1;
04566         DWC_WRITE_REG32(&GET_CORE_IF(pcd)->core_global_regs->gintsts,
04567                         gintsts.d32);
04568 
04569         return 1;
04570 }
04571 
04576 int32_t dwc_otg_pcd_handle_in_nak_effective(dwc_otg_pcd_t * pcd)
04577 {
04578         dwc_otg_dev_if_t *dev_if = GET_CORE_IF(pcd)->dev_if;
04579         depctl_data_t diepctl = {.d32 = 0 };
04580         gintmsk_data_t intr_mask = {.d32 = 0 };
04581         gintsts_data_t gintsts;
04582         dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
04583         int i;
04584 
04585         DWC_DEBUGPL(DBG_PCD, "Global IN NAK Effective\n");
04586 
04587         /* Disable all active IN EPs */
04588         for (i = 0; i <= dev_if->num_in_eps; i++) {
04589                 diepctl.d32 = DWC_READ_REG32(&dev_if->in_ep_regs[i]->diepctl);
04590                 if (!(diepctl.b.eptype & 1) && diepctl.b.epena) {
04591                         if (core_if->start_predict > 0)
04592                                 core_if->start_predict++;
04593                         diepctl.b.epdis = 1;
04594                         diepctl.b.snak = 1;
04595                         DWC_WRITE_REG32(&dev_if->in_ep_regs[i]->diepctl, diepctl.d32);
04596                 }                                               
04597         }
04598         
04599 
04600         /* Disable the Global IN NAK Effective Interrupt */
04601         intr_mask.b.ginnakeff = 1;
04602         DWC_MODIFY_REG32(&GET_CORE_IF(pcd)->core_global_regs->gintmsk,
04603                          intr_mask.d32, 0);
04604 
04605         /* Clear interrupt */
04606         gintsts.d32 = 0;
04607         gintsts.b.ginnakeff = 1;
04608         DWC_WRITE_REG32(&GET_CORE_IF(pcd)->core_global_regs->gintsts,
04609                         gintsts.d32);
04610 
04611         return 1;
04612 }
04613 
04618 int32_t dwc_otg_pcd_handle_out_nak_effective(dwc_otg_pcd_t * pcd)
04619 {
04620         dwc_otg_dev_if_t *dev_if = GET_CORE_IF(pcd)->dev_if;
04621         gintmsk_data_t intr_mask = {.d32 = 0 };
04622         gintsts_data_t gintsts;
04623         depctl_data_t doepctl;
04624         int i;
04625 
04626         /* Disable the Global OUT NAK Effective Interrupt */
04627         intr_mask.b.goutnakeff = 1;
04628         DWC_MODIFY_REG32(&GET_CORE_IF(pcd)->core_global_regs->gintmsk,
04629                 intr_mask.d32, 0);
04630         
04631         /* If DEV OUT NAK enabled*/
04632         if (pcd->core_if->core_params->dev_out_nak) {
04633                 /* Run over all out endpoints to determine the ep number on
04634                  * which the timeout has happened 
04635                  */
04636                 for (i = 0; i <= dev_if->num_out_eps; i++) {
04637                         if ( pcd->core_if->ep_xfer_info[i].state == 2 )
04638                                 break;
04639                 }
04640                 if (i > dev_if->num_out_eps) {
04641                         dctl_data_t dctl;
04642                         dctl.d32 = DWC_READ_REG32(&dev_if->
04643                                 dev_global_regs->dctl);
04644                         dctl.b.cgoutnak = 1;
04645                         DWC_WRITE_REG32(&dev_if->dev_global_regs->dctl,
04646                                 dctl.d32);
04647                         goto out;
04648                 }
04649 
04650                 /* Disable the endpoint */
04651                 doepctl.d32 = DWC_READ_REG32(&dev_if->
04652                                                                                 out_ep_regs[i]->doepctl);
04653                 if (doepctl.b.epena) {
04654                         doepctl.b.epdis = 1;
04655                         doepctl.b.snak = 1;
04656                 }
04657                 DWC_WRITE_REG32(&dev_if->out_ep_regs[i]->doepctl, doepctl.d32);
04658                 return 1;
04659         }
04660         /* We come here from Incomplete ISO OUT handler */
04661         if(dev_if->isoc_ep)
04662         {
04663                 dwc_ep_t *dwc_ep = (dwc_ep_t *)dev_if->isoc_ep;
04664                 uint32_t epnum = dwc_ep->num;
04665                 doepint_data_t doepint;
04666                 doepint.d32 = DWC_READ_REG32(&dev_if->out_ep_regs[dwc_ep->num]->doepint);
04667                 dev_if->isoc_ep = NULL;
04668                 doepctl.d32 = DWC_READ_REG32(&dev_if->out_ep_regs[epnum]->doepctl);
04669                 DWC_PRINTF("Before disable DOEPCTL = %08x\n", doepctl.d32);
04670                 if (doepctl.b.epena) {
04671                         doepctl.b.epdis = 1;
04672                         doepctl.b.snak = 1;
04673                 }
04674                 DWC_WRITE_REG32(&dev_if->out_ep_regs[epnum]->doepctl, doepctl.d32);
04675                 return 1;
04676         } else
04677                 DWC_PRINTF("INTERRUPT Handler not implemented for %s\n",
04678                            "Global OUT NAK Effective\n");
04679         
04680 out:
04681         /* Clear interrupt */
04682         gintsts.d32 = 0;
04683         gintsts.b.goutnakeff = 1;
04684         DWC_WRITE_REG32(&GET_CORE_IF(pcd)->core_global_regs->gintsts,
04685                         gintsts.d32);
04686 
04687         return 1;
04688 }
04689 
04702 int32_t dwc_otg_pcd_handle_intr(dwc_otg_pcd_t * pcd)
04703 {
04704         dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
04705 #ifdef VERBOSE
04706         dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
04707 #endif
04708         gintsts_data_t gintr_status;
04709         int32_t retval = 0;
04710 
04711         /* Exit from ISR if core is hibernated */
04712         if (core_if->hibernation_suspend == 1) {
04713                 return retval;
04714         }
04715 #ifdef VERBOSE
04716         DWC_DEBUGPL(DBG_ANY, "%s() gintsts=%08x  gintmsk=%08x\n",
04717                     __func__,
04718                     DWC_READ_REG32(&global_regs->gintsts),
04719                     DWC_READ_REG32(&global_regs->gintmsk));
04720 #endif
04721 
04722         if (dwc_otg_is_device_mode(core_if)) {
04723                 DWC_SPINLOCK(pcd->lock);
04724 #ifdef VERBOSE
04725                 DWC_DEBUGPL(DBG_PCDV, "%s() gintsts=%08x  gintmsk=%08x\n",
04726                             __func__,
04727                             DWC_READ_REG32(&global_regs->gintsts),
04728                             DWC_READ_REG32(&global_regs->gintmsk));
04729 #endif
04730 
04731                 gintr_status.d32 = dwc_otg_read_core_intr(core_if);
04732 
04733                 DWC_DEBUGPL(DBG_PCDV, "%s: gintsts&gintmsk=%08x\n",
04734                             __func__, gintr_status.d32);
04735 
04736                 if (gintr_status.b.sofintr) {
04737                         retval |= dwc_otg_pcd_handle_sof_intr(pcd);
04738                 }
04739                 if (gintr_status.b.rxstsqlvl) {
04740                         retval |=
04741                             dwc_otg_pcd_handle_rx_status_q_level_intr(pcd);
04742                 }
04743                 if (gintr_status.b.nptxfempty) {
04744                         retval |= dwc_otg_pcd_handle_np_tx_fifo_empty_intr(pcd);
04745                 }
04746                 if (gintr_status.b.goutnakeff) {
04747                         retval |= dwc_otg_pcd_handle_out_nak_effective(pcd);
04748                 }
04749                 if (gintr_status.b.i2cintr) {
04750                         retval |= dwc_otg_pcd_handle_i2c_intr(pcd);
04751                 }
04752                 if (gintr_status.b.erlysuspend) {
04753                         retval |= dwc_otg_pcd_handle_early_suspend_intr(pcd);
04754                 }
04755                 if (gintr_status.b.usbreset) {
04756                         retval |= dwc_otg_pcd_handle_usb_reset_intr(pcd);
04757                 }
04758                 if (gintr_status.b.enumdone) {
04759                         retval |= dwc_otg_pcd_handle_enum_done_intr(pcd);
04760                 }
04761                 if (gintr_status.b.isooutdrop) {
04762                         retval |=
04763                             dwc_otg_pcd_handle_isoc_out_packet_dropped_intr
04764                             (pcd);
04765                 }
04766                 if (gintr_status.b.eopframe) {
04767                         retval |=
04768                             dwc_otg_pcd_handle_end_periodic_frame_intr(pcd);
04769                 }
04770                 if (gintr_status.b.inepint) {
04771                         if (!core_if->multiproc_int_enable) {
04772                                 retval |= dwc_otg_pcd_handle_in_ep_intr(pcd);
04773                         }
04774                 }
04775                 if (gintr_status.b.outepintr) {
04776                         if (!core_if->multiproc_int_enable) {
04777                                 retval |= dwc_otg_pcd_handle_out_ep_intr(pcd);
04778                         }
04779                 }
04780                 if (gintr_status.b.epmismatch) {
04781                         retval |= dwc_otg_pcd_handle_ep_mismatch_intr(pcd);
04782                 }
04783                 if (gintr_status.b.fetsusp) {
04784                         retval |= dwc_otg_pcd_handle_ep_fetsusp_intr(pcd);
04785                 }
04786                 if (gintr_status.b.ginnakeff) {
04787                         retval |= dwc_otg_pcd_handle_in_nak_effective(pcd);
04788                 }
04789                 if (gintr_status.b.incomplisoin) {
04790                         retval |=
04791                             dwc_otg_pcd_handle_incomplete_isoc_in_intr(pcd);
04792                 }
04793                 if (gintr_status.b.incomplisoout) {
04794                         retval |=
04795                             dwc_otg_pcd_handle_incomplete_isoc_out_intr(pcd);
04796                 }
04797 
04798                 /* In MPI mode Device Endpoints interrupts are asserted
04799                  * without setting outepintr and inepint bits set, so these
04800                  * Interrupt handlers are called without checking these bit-fields
04801                  */
04802                 if (core_if->multiproc_int_enable) {
04803                         retval |= dwc_otg_pcd_handle_in_ep_intr(pcd);
04804                         retval |= dwc_otg_pcd_handle_out_ep_intr(pcd);
04805                 }
04806 #ifdef VERBOSE
04807                 DWC_DEBUGPL(DBG_PCDV, "%s() gintsts=%0x\n", __func__,
04808                             DWC_READ_REG32(&global_regs->gintsts));
04809 #endif
04810                 DWC_SPINUNLOCK(pcd->lock);
04811         }
04812         return retval;
04813 }
04814 
04815 #endif /* DWC_HOST_ONLY */

Generated on Thu Oct 27 03:56:38 2011 for DesignWare USB 2.0 OTG Controller (DWC_otg) Device Driver by  doxygen 1.3.9.1