tizen 2.4 release
[kernel/u-boot-tm1.git] / drivers / usb / gadget / dwc_otg / dwc_otg_pcd_intr.c
1 /* ==========================================================================
2  * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_pcd_intr.c $
3  * $Revision: #90 $
4  * $Date: 2009/02/16 $
5  * $Change: 1189014 $
6  *
7  * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
8  * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
9  * otherwise expressly agreed to in writing between Synopsys and you.
10  *
11  * The Software IS NOT an item of Licensed Software or Licensed Product under
12  * any End User Software License Agreement or Agreement for Licensed Product
13  * with Synopsys or any supplement thereto. You are permitted to use and
14  * redistribute this Software in source and binary forms, with or without
15  * modification, provided that redistributions of source code must retain this
16  * notice. You may not view, use, disclose, copy or distribute this file or
17  * any information contained herein except pursuant to this license grant from
18  * Synopsys. If you do not agree with this notice, including the disclaimer
19  * below, then you are not authorized to use the Software.
20  *
21  * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
22  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
25  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
31  * DAMAGE.
32  * ========================================================================== */
33 #ifndef DWC_HOST_ONLY
34 #include "dwc_otg_pcd.h"
35
36 #ifdef DWC_UTE_CFI
37 #include "dwc_otg_cfi.h"
38 #endif
39
40 //#define PRINT_CFI_DMA_DESCS
41
42 #define DEBUG_EP0
43
44 //#define VERBOSE
45
46 /**
47  * This function updates OTG.
48  */
49 static void dwc_otg_pcd_update_otg(dwc_otg_pcd_t * pcd, const unsigned reset)
50 {
51
52         if (reset) {
53                 pcd->b_hnp_enable = 0;
54                 pcd->a_hnp_support = 0;
55                 pcd->a_alt_hnp_support = 0;
56         }
57
58         if (pcd->fops->hnp_changed) {
59                 pcd->fops->hnp_changed(pcd);
60         }
61 }
62
63 /** @file
64  * This file contains the implementation of the PCD Interrupt handlers.
65  *
66  * The PCD handles the device interrupts.  Many conditions can cause a
67  * device interrupt. When an interrupt occurs, the device interrupt
68  * service routine determines the cause of the interrupt and
69  * dispatches handling to the appropriate function. These interrupt
70  * handling functions are described below.
71  * All interrupt registers are processed from LSB to MSB.
72  */
73
74 /**
75  * This function prints the ep0 state for debug purposes.
76  */
77 static inline void print_ep0_state(dwc_otg_pcd_t * pcd)
78 {
79 #ifdef DEBUG
80         char str[40];
81
82         switch (pcd->ep0state) {
83         case EP0_DISCONNECT:
84                 dwc_strcpy(str, "EP0_DISCONNECT");
85                 break;
86         case EP0_IDLE:
87                 dwc_strcpy(str, "EP0_IDLE");
88                 break;
89         case EP0_IN_DATA_PHASE:
90                 dwc_strcpy(str, "EP0_IN_DATA_PHASE");
91                 break;
92         case EP0_OUT_DATA_PHASE:
93                 dwc_strcpy(str, "EP0_OUT_DATA_PHASE");
94                 break;
95         case EP0_IN_STATUS_PHASE:
96                 dwc_strcpy(str, "EP0_IN_STATUS_PHASE");
97                 break;
98         case EP0_OUT_STATUS_PHASE:
99                 dwc_strcpy(str, "EP0_OUT_STATUS_PHASE");
100                 break;
101         case EP0_STALL:
102                 dwc_strcpy(str, "EP0_STALL");
103                 break;
104         default:
105                 dwc_strcpy(str, "EP0_INVALID");
106         }
107
108         DWC_DEBUGPL(DBG_ANY, "%s(%d)\n", str, pcd->ep0state);
109 #endif
110 }
111
112 #ifdef DWC_UTE_CFI
113 static inline void print_desc(struct dwc_otg_dma_desc *ddesc,
114                               const uint8_t * epname, int descnum)
115 {
116         CFI_INFO
117             ("%s DMA_DESC(%d) buf=0x%08x bytes=0x%04x; sp=0x%x; l=0x%x; sts=0x%02x; bs=0x%02x\n",
118              epname, descnum, ddesc->buf, ddesc->status.b.bytes,
119              ddesc->status.b.sp, ddesc->status.b.l, ddesc->status.b.sts,
120              ddesc->status.b.bs);
121 }
122 #endif
123
124 /**
125  * This function returns pointer to in ep struct with number ep_num
126  */
127 static inline dwc_otg_pcd_ep_t *get_in_ep(dwc_otg_pcd_t * pcd, uint32_t ep_num)
128 {
129         int i;
130         int num_in_eps = GET_CORE_IF(pcd)->dev_if->num_in_eps;
131         if (ep_num == 0) {
132                 return &pcd->ep0;
133         } else {
134                 for (i = 0; i < num_in_eps; ++i) {
135                         if (pcd->in_ep[i].dwc_ep.num == ep_num)
136                                 return &pcd->in_ep[i];
137                 }
138                 return 0;
139         }
140 }
141
142 /**
143  * This function returns pointer to out ep struct with number ep_num
144  */
145 static inline dwc_otg_pcd_ep_t *get_out_ep(dwc_otg_pcd_t * pcd, uint32_t ep_num)
146 {
147         int i;
148         int num_out_eps = GET_CORE_IF(pcd)->dev_if->num_out_eps;
149         if (ep_num == 0) {
150                 return &pcd->ep0;
151         } else {
152                 for (i = 0; i < num_out_eps; ++i) {
153                         if (pcd->out_ep[i].dwc_ep.num == ep_num)
154                                 return &pcd->out_ep[i];
155                 }
156                 return 0;
157         }
158 }
159
160 /**
161  * This functions gets a pointer to an EP from the wIndex address
162  * value of the control request.
163  */
164 dwc_otg_pcd_ep_t *get_ep_by_addr(dwc_otg_pcd_t * pcd, u16 wIndex)
165 {
166         dwc_otg_pcd_ep_t *ep;
167         uint32_t ep_num = UE_GET_ADDR(wIndex);
168
169         if (ep_num == 0) {
170                 ep = &pcd->ep0;
171         } else if (UE_GET_DIR(wIndex) == UE_DIR_IN) {   /* in ep */
172                 ep = &pcd->in_ep[ep_num - 1];
173         } else {
174                 ep = &pcd->out_ep[ep_num - 1];
175         }
176
177         return ep;
178 }
179
180 /**
181  * This function checks the EP request queue, if the queue is not
182  * empty the next request is started.
183  */
184 void start_next_request(dwc_otg_pcd_ep_t * ep)
185 {
186         dwc_otg_pcd_request_t *req = 0;
187         uint32_t max_transfer =
188             GET_CORE_IF(ep->pcd)->core_params->max_transfer_size;
189
190 #ifdef DWC_UTE_CFI
191         struct dwc_otg_pcd *pcd;
192         pcd = ep->pcd;
193 #endif
194
195         if (!DWC_CIRCLEQ_EMPTY(&ep->queue)) {
196                 req = DWC_CIRCLEQ_FIRST(&ep->queue);
197
198 #ifdef DWC_UTE_CFI
199                 if (ep->dwc_ep.buff_mode != BM_STANDARD) {
200                         ep->dwc_ep.cfi_req_len = req->length;
201                         pcd->cfi->ops.build_descriptors(pcd->cfi, pcd, ep, req);
202                 } else {
203 #endif
204                         /* Setup and start the Transfer */
205                         ep->dwc_ep.dma_addr = req->dma;
206                         ep->dwc_ep.start_xfer_buff = req->buf;
207                         ep->dwc_ep.xfer_buff = req->buf;
208                         ep->dwc_ep.sent_zlp = 0;
209                         ep->dwc_ep.total_len = req->length;
210                         ep->dwc_ep.xfer_len = 0;
211                         ep->dwc_ep.xfer_count = 0;
212
213                         ep->dwc_ep.maxxfer = max_transfer;
214                         if (GET_CORE_IF(ep->pcd)->dma_desc_enable) {
215                                 uint32_t out_max_xfer = DDMA_MAX_TRANSFER_SIZE
216                                     - (DDMA_MAX_TRANSFER_SIZE % 4);
217                                 if (ep->dwc_ep.is_in) {
218                                         if (ep->dwc_ep.maxxfer >
219                                             DDMA_MAX_TRANSFER_SIZE) {
220                                                 ep->dwc_ep.maxxfer =
221                                                     DDMA_MAX_TRANSFER_SIZE;
222                                         }
223                                 } else {
224                                         if (ep->dwc_ep.maxxfer > out_max_xfer) {
225                                                 ep->dwc_ep.maxxfer =
226                                                     out_max_xfer;
227                                         }
228                                 }
229                         }
230                         if (ep->dwc_ep.maxxfer < ep->dwc_ep.total_len) {
231                                 ep->dwc_ep.maxxfer -=
232                                     (ep->dwc_ep.maxxfer % ep->dwc_ep.maxpacket);
233                         }
234                         if (req->sent_zlp) {
235                                 if ((ep->dwc_ep.total_len %
236                                      ep->dwc_ep.maxpacket == 0)
237                                     && (ep->dwc_ep.total_len != 0)) {
238                                         ep->dwc_ep.sent_zlp = 1;
239                                 }
240
241                         }
242 #ifdef DWC_UTE_CFI
243                 }
244 #endif
245                 dwc_otg_ep_start_transfer(GET_CORE_IF(ep->pcd), &ep->dwc_ep);
246         }
247 }
248
249 /**
250  * This function handles the SOF Interrupts. At this time the SOF
251  * Interrupt is disabled.
252  */
253 int32_t dwc_otg_pcd_handle_sof_intr(dwc_otg_pcd_t * pcd)
254 {
255         dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
256
257         gintsts_data_t gintsts;
258
259         DWC_DEBUGPL(DBG_PCD, "SOF\n");
260
261         /* Clear interrupt */
262         gintsts.d32 = 0;
263         gintsts.b.sofintr = 1;
264         dwc_write_reg32(&core_if->core_global_regs->gintsts, gintsts.d32);
265
266         return 1;
267 }
268
269 /**
270  * This function handles the Rx Status Queue Level Interrupt, which
271  * indicates that there is a least one packet in the Rx FIFO.  The
272  * packets are moved from the FIFO to memory, where they will be
273  * processed when the Endpoint Interrupt Register indicates Transfer
274  * Complete or SETUP Phase Done.
275  *
276  * Repeat the following until the Rx Status Queue is empty:
277  *       -# Read the Receive Status Pop Register (GRXSTSP) to get Packet
278  *              info
279  *       -# If Receive FIFO is empty then skip to step Clear the interrupt
280  *              and exit
281  *       -# If SETUP Packet call dwc_otg_read_setup_packet to copy the
282  *              SETUP data to the buffer
283  *       -# If OUT Data Packet call dwc_otg_read_packet to copy the data
284  *              to the destination buffer
285  */
286 int32_t dwc_otg_pcd_handle_rx_status_q_level_intr(dwc_otg_pcd_t * pcd)
287 {
288         dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
289         dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
290         gintmsk_data_t gintmask = {.d32 = 0 };
291         device_grxsts_data_t status;
292         dwc_otg_pcd_ep_t *ep;
293         gintsts_data_t gintsts;
294 #ifdef DEBUG
295         static char *dpid_str[] = { "D0", "D2", "D1", "MDATA" };
296 #endif
297
298         //DWC_DEBUGPL(DBG_PCDV, "%s(%p)\n", __func__, _pcd);
299         /* Disable the Rx Status Queue Level interrupt */
300         gintmask.b.rxstsqlvl = 1;
301         dwc_modify_reg32(&global_regs->gintmsk, gintmask.d32, 0);
302
303         /* Get the Status from the top of the FIFO */
304         status.d32 = dwc_read_reg32(&global_regs->grxstsp);
305
306         DWC_DEBUGPL(DBG_PCD, "EP:%d BCnt:%d DPID:%s "
307                     "pktsts:%x Frame:%d(0x%0x)\n",
308                     status.b.epnum, status.b.bcnt,
309                     dpid_str[status.b.dpid],
310                     status.b.pktsts, status.b.fn, status.b.fn);
311         /* Get pointer to EP structure */
312         ep = get_out_ep(pcd, status.b.epnum);
313
314         switch (status.b.pktsts) {
315         case DWC_DSTS_GOUT_NAK:
316                 DWC_DEBUGPL(DBG_PCDV, "Global OUT NAK\n");
317                 break;
318         case DWC_STS_DATA_UPDT:
319                 DWC_DEBUGPL(DBG_PCDV, "OUT Data Packet\n");
320                 if (status.b.bcnt && ep->dwc_ep.xfer_buff) {
321                         /** @todo NGS Check for buffer overflow? */
322                         dwc_otg_read_packet(core_if,
323                                             ep->dwc_ep.xfer_buff,
324                                             status.b.bcnt);
325                         ep->dwc_ep.xfer_count += status.b.bcnt;
326                         ep->dwc_ep.xfer_buff += status.b.bcnt;
327                 }
328                 break;
329         case DWC_STS_XFER_COMP:
330                 DWC_DEBUGPL(DBG_PCDV, "OUT Complete\n");
331                 break;
332         case DWC_DSTS_SETUP_COMP:
333 #ifdef DEBUG_EP0
334                 DWC_DEBUGPL(DBG_PCDV, "Setup Complete\n");
335 #endif
336                 break;
337         case DWC_DSTS_SETUP_UPDT:
338                 dwc_otg_read_setup_packet(core_if, pcd->setup_pkt->d32);
339 #ifdef DEBUG_EP0
340                 DWC_DEBUGPL(DBG_PCD,
341                             "SETUP PKT: %02x.%02x v%04x i%04x l%04x\n",
342                             pcd->setup_pkt->req.bmRequestType,
343                             pcd->setup_pkt->req.bRequest,
344                             UGETW(pcd->setup_pkt->req.wValue),
345                             UGETW(pcd->setup_pkt->req.wIndex),
346                             UGETW(pcd->setup_pkt->req.wLength));
347 #endif
348                 ep->dwc_ep.xfer_count += status.b.bcnt;
349                 break;
350         default:
351                 DWC_DEBUGPL(DBG_PCDV, "Invalid Packet Status (0x%0x)\n",
352                             status.b.pktsts);
353                 break;
354         }
355
356         /* Enable the Rx Status Queue Level interrupt */
357         dwc_modify_reg32(&global_regs->gintmsk, 0, gintmask.d32);
358         /* Clear interrupt */
359         gintsts.d32 = 0;
360         gintsts.b.rxstsqlvl = 1;
361         dwc_write_reg32(&global_regs->gintsts, gintsts.d32);
362
363         //DWC_DEBUGPL(DBG_PCDV, "EXIT: %s\n", __func__);
364         return 1;
365 }
366
367 /**
368  * This function examines the Device IN Token Learning Queue to
369  * determine the EP number of the last IN token received.  This
370  * implementation is for the Mass Storage device where there are only
371  * 2 IN EPs (Control-IN and BULK-IN).
372  *
373  * The EP numbers for the first six IN Tokens are in DTKNQR1 and there
374  * are 8 EP Numbers in each of the other possible DTKNQ Registers.
375  *
376  * @param core_if Programming view of DWC_otg controller.
377  *
378  */
379 static inline int get_ep_of_last_in_token(dwc_otg_core_if_t * core_if)
380 {
381         dwc_otg_device_global_regs_t *dev_global_regs =
382             core_if->dev_if->dev_global_regs;
383         const uint32_t TOKEN_Q_DEPTH = core_if->hwcfg2.b.dev_token_q_depth;
384         /* Number of Token Queue Registers */
385         const int DTKNQ_REG_CNT = (TOKEN_Q_DEPTH + 7) / 8;
386         dtknq1_data_t dtknqr1;
387         uint32_t in_tkn_epnums[4];
388         int ndx = 0;
389         int i = 0;
390         volatile uint32_t *addr = &dev_global_regs->dtknqr1;
391         int epnum = 0;
392
393         //DWC_DEBUGPL(DBG_PCD,"dev_token_q_depth=%d\n",TOKEN_Q_DEPTH);
394
395         /* Read the DTKNQ Registers */
396         for (i = 0; i < DTKNQ_REG_CNT; i++) {
397                 in_tkn_epnums[i] = dwc_read_reg32(addr);
398                 DWC_DEBUGPL(DBG_PCDV, "DTKNQR%d=0x%08x\n", i + 1,
399                             in_tkn_epnums[i]);
400                 if (addr == &dev_global_regs->dvbusdis) {
401                         addr = &dev_global_regs->dtknqr3_dthrctl;
402                 } else {
403                         ++addr;
404                 }
405
406         }
407
408         /* Copy the DTKNQR1 data to the bit field. */
409         dtknqr1.d32 = in_tkn_epnums[0];
410         /* Get the EP numbers */
411         in_tkn_epnums[0] = dtknqr1.b.epnums0_5;
412         ndx = dtknqr1.b.intknwptr - 1;
413
414         //DWC_DEBUGPL(DBG_PCDV,"ndx=%d\n",ndx);
415         if (ndx == -1) {
416                 /** @todo Find a simpler way to calculate the max
417                  * queue position.*/
418                 int cnt = TOKEN_Q_DEPTH;
419                 if (TOKEN_Q_DEPTH <= 6) {
420                         cnt = TOKEN_Q_DEPTH - 1;
421                 } else if (TOKEN_Q_DEPTH <= 14) {
422                         cnt = TOKEN_Q_DEPTH - 7;
423                 } else if (TOKEN_Q_DEPTH <= 22) {
424                         cnt = TOKEN_Q_DEPTH - 15;
425                 } else {
426                         cnt = TOKEN_Q_DEPTH - 23;
427                 }
428                 epnum = (in_tkn_epnums[DTKNQ_REG_CNT - 1] >> (cnt * 4)) & 0xF;
429         } else {
430                 if (ndx <= 5) {
431                         epnum = (in_tkn_epnums[0] >> (ndx * 4)) & 0xF;
432                 } else if (ndx <= 13) {
433                         ndx -= 6;
434                         epnum = (in_tkn_epnums[1] >> (ndx * 4)) & 0xF;
435                 } else if (ndx <= 21) {
436                         ndx -= 14;
437                         epnum = (in_tkn_epnums[2] >> (ndx * 4)) & 0xF;
438                 } else if (ndx <= 29) {
439                         ndx -= 22;
440                         epnum = (in_tkn_epnums[3] >> (ndx * 4)) & 0xF;
441                 }
442         }
443         //DWC_DEBUGPL(DBG_PCD,"epnum=%d\n",epnum);
444         return epnum;
445 }
446
447 /**
448  * This interrupt occurs when the non-periodic Tx FIFO is half-empty.
449  * The active request is checked for the next packet to be loaded into
450  * the non-periodic Tx FIFO.
451  */
452 int32_t dwc_otg_pcd_handle_np_tx_fifo_empty_intr(dwc_otg_pcd_t * pcd)
453 {
454         dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
455         dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
456         dwc_otg_dev_in_ep_regs_t *ep_regs;
457         gnptxsts_data_t txstatus = {.d32 = 0 };
458         gintsts_data_t gintsts;
459
460         int epnum = 0;
461         dwc_otg_pcd_ep_t *ep = 0;
462         uint32_t len = 0;
463         int dwords;
464
465         /* Get the epnum from the IN Token Learning Queue. */
466         epnum = get_ep_of_last_in_token(core_if);
467         ep = get_in_ep(pcd, epnum);
468
469         DWC_DEBUGPL(DBG_PCD, "NP TxFifo Empty: %d \n", epnum);
470
471         ep_regs = core_if->dev_if->in_ep_regs[epnum];
472
473         len = ep->dwc_ep.xfer_len - ep->dwc_ep.xfer_count;
474         if (len > ep->dwc_ep.maxpacket) {
475                 len = ep->dwc_ep.maxpacket;
476         }
477         dwords = (len + 3) / 4;
478
479         /* While there is space in the queue and space in the FIFO and
480          * More data to tranfer, Write packets to the Tx FIFO */
481         txstatus.d32 = dwc_read_reg32(&global_regs->gnptxsts);
482         DWC_DEBUGPL(DBG_PCDV, "b4 GNPTXSTS=0x%08x\n", txstatus.d32);
483
484         while (txstatus.b.nptxqspcavail > 0 &&
485                txstatus.b.nptxfspcavail > dwords &&
486                ep->dwc_ep.xfer_count < ep->dwc_ep.xfer_len) {
487                 /* Write the FIFO */
488                 dwc_otg_ep_write_packet(core_if, &ep->dwc_ep, 0);
489                 len = ep->dwc_ep.xfer_len - ep->dwc_ep.xfer_count;
490
491                 if (len > ep->dwc_ep.maxpacket) {
492                         len = ep->dwc_ep.maxpacket;
493                 }
494
495                 dwords = (len + 3) / 4;
496                 txstatus.d32 = dwc_read_reg32(&global_regs->gnptxsts);
497                 DWC_DEBUGPL(DBG_PCDV, "GNPTXSTS=0x%08x\n", txstatus.d32);
498         }
499
500         DWC_DEBUGPL(DBG_PCDV, "GNPTXSTS=0x%08x\n",
501                     dwc_read_reg32(&global_regs->gnptxsts));
502
503         /* Clear interrupt */
504         gintsts.d32 = 0;
505         gintsts.b.nptxfempty = 1;
506         dwc_write_reg32(&global_regs->gintsts, gintsts.d32);
507
508         return 1;
509 }
510
511 /**
512  * This function is called when dedicated Tx FIFO Empty interrupt occurs.
513  * The active request is checked for the next packet to be loaded into
514  * apropriate Tx FIFO.
515  */
516 static int32_t write_empty_tx_fifo(dwc_otg_pcd_t * pcd, uint32_t epnum)
517 {
518         dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
519         dwc_otg_dev_if_t *dev_if = core_if->dev_if;
520         dwc_otg_dev_in_ep_regs_t *ep_regs;
521         dtxfsts_data_t txstatus = {.d32 = 0 };
522         dwc_otg_pcd_ep_t *ep = 0;
523         uint32_t len = 0;
524         int dwords;
525
526         ep = get_in_ep(pcd, epnum);
527
528         DWC_DEBUGPL(DBG_PCD, "Dedicated TxFifo Empty: %d \n", epnum);
529
530         ep_regs = core_if->dev_if->in_ep_regs[epnum];
531
532         len = ep->dwc_ep.xfer_len - ep->dwc_ep.xfer_count;
533
534         if (len > ep->dwc_ep.maxpacket) {
535                 len = ep->dwc_ep.maxpacket;
536         }
537
538         dwords = (len + 3) / 4;
539
540         /* While there is space in the queue and space in the FIFO and
541          * More data to tranfer, Write packets to the Tx FIFO */
542         txstatus.d32 = dwc_read_reg32(&dev_if->in_ep_regs[epnum]->dtxfsts);
543         DWC_DEBUGPL(DBG_PCDV, "b4 dtxfsts[%d]=0x%08x\n", epnum, txstatus.d32);
544
545         while (txstatus.b.txfspcavail > dwords &&
546                ep->dwc_ep.xfer_count < ep->dwc_ep.xfer_len &&
547                ep->dwc_ep.xfer_len != 0) {
548                 /* Write the FIFO */
549                 dwc_otg_ep_write_packet(core_if, &ep->dwc_ep, 0);
550
551                 len = ep->dwc_ep.xfer_len - ep->dwc_ep.xfer_count;
552                 if (len > ep->dwc_ep.maxpacket) {
553                         len = ep->dwc_ep.maxpacket;
554                 }
555
556                 dwords = (len + 3) / 4;
557                 txstatus.d32 =
558                     dwc_read_reg32(&dev_if->in_ep_regs[epnum]->dtxfsts);
559                 DWC_DEBUGPL(DBG_PCDV, "dtxfsts[%d]=0x%08x\n", epnum,
560                             txstatus.d32);
561         }
562
563         DWC_DEBUGPL(DBG_PCDV, "b4 dtxfsts[%d]=0x%08x\n", epnum,
564                     dwc_read_reg32(&dev_if->in_ep_regs[epnum]->dtxfsts));
565
566         return 1;
567 }
568
569 /**
570  * This function is called when the Device is disconnected. It stops
571  * any active requests and informs the Gadget driver of the
572  * disconnect.
573  */
574 void dwc_otg_pcd_stop(dwc_otg_pcd_t * pcd)
575 {
576         int i, num_in_eps, num_out_eps;
577         dwc_otg_pcd_ep_t *ep;
578         unsigned long flags;
579
580         gintmsk_data_t intr_mask = {.d32 = 0 };
581
582         DWC_SPINLOCK_IRQSAVE(pcd->lock, &flags);
583
584         num_in_eps = GET_CORE_IF(pcd)->dev_if->num_in_eps;
585         num_out_eps = GET_CORE_IF(pcd)->dev_if->num_out_eps;
586
587         DWC_DEBUGPL(DBG_PCDV, "%s() \n", __func__);
588         /* don't disconnect drivers more than once */
589         if (pcd->ep0state == EP0_DISCONNECT) {
590                 DWC_DEBUGPL(DBG_ANY, "%s() Already Disconnected\n", __func__);
591                 return;
592         }
593         pcd->ep0state = EP0_DISCONNECT;
594
595         /* Reset the OTG state. */
596         dwc_otg_pcd_update_otg(pcd, 1);
597
598         /* Disable the NP Tx Fifo Empty Interrupt. */
599         intr_mask.b.nptxfempty = 1;
600         dwc_modify_reg32(&GET_CORE_IF(pcd)->core_global_regs->gintmsk,
601                          intr_mask.d32, 0);
602
603         /* Flush the FIFOs */
604         /**@todo NGS Flush Periodic FIFOs */
605         dwc_otg_flush_tx_fifo(GET_CORE_IF(pcd), 0x10);
606         dwc_otg_flush_rx_fifo(GET_CORE_IF(pcd));
607
608         /* prevent new request submissions, kill any outstanding requests  */
609         ep = &pcd->ep0;
610         dwc_otg_request_nuke(ep);
611         /* prevent new request submissions, kill any outstanding requests  */
612         for (i = 0; i < num_in_eps; i++) {
613                 dwc_otg_pcd_ep_t *ep = &pcd->in_ep[i];
614                 dwc_otg_request_nuke(ep);
615         }
616         /* prevent new request submissions, kill any outstanding requests  */
617         for (i = 0; i < num_out_eps; i++) {
618                 dwc_otg_pcd_ep_t *ep = &pcd->out_ep[i];
619                 dwc_otg_request_nuke(ep);
620         }
621
622         /* report disconnect; the driver is already quiesced */
623         if (pcd->fops->disconnect) {
624                 DWC_SPINUNLOCK(pcd->lock);
625                 pcd->fops->disconnect(pcd);
626                 DWC_SPINLOCK(pcd->lock);
627         }
628         DWC_SPINUNLOCK_IRQRESTORE(pcd->lock, flags);
629 }
630
631 /**
632  * This interrupt indicates that ...
633  */
634 int32_t dwc_otg_pcd_handle_i2c_intr(dwc_otg_pcd_t * pcd)
635 {
636         gintmsk_data_t intr_mask = {.d32 = 0 };
637         gintsts_data_t gintsts;
638
639         DWC_DEBUGPL(DBG_CIL,"INTERRUPT Handler not implemented for %s\n", "i2cintr");
640         intr_mask.b.i2cintr = 1;
641         dwc_modify_reg32(&GET_CORE_IF(pcd)->core_global_regs->gintmsk,
642                          intr_mask.d32, 0);
643
644         /* Clear interrupt */
645         gintsts.d32 = 0;
646         gintsts.b.i2cintr = 1;
647         dwc_write_reg32(&GET_CORE_IF(pcd)->core_global_regs->gintsts,
648                         gintsts.d32);
649         return 1;
650 }
651
652 /**
653  * This interrupt indicates that ...
654  */
655 int32_t dwc_otg_pcd_handle_early_suspend_intr(dwc_otg_pcd_t * pcd)
656 {
657         gintsts_data_t gintsts;
658 #if defined(VERBOSE)
659         DWC_DEBUGPL(DBG_CIL,"Early Suspend Detected\n");
660 #endif
661         /* Clear interrupt */
662         gintsts.d32 = 0;
663         gintsts.b.erlysuspend = 1;
664         dwc_write_reg32(&GET_CORE_IF(pcd)->core_global_regs->gintsts,
665                         gintsts.d32);
666         return 1;
667 }
668
669 /**
670  * This function configures EPO to receive SETUP packets.
671  *
672  * @todo NGS: Update the comments from the HW FS.
673  *
674  *      -# Program the following fields in the endpoint specific registers
675  *      for Control OUT EP 0, in order to receive a setup packet
676  *      - DOEPTSIZ0.Packet Count = 3 (To receive up to 3 back to back
677  *        setup packets)
678  *      - DOEPTSIZE0.Transfer Size = 24 Bytes (To receive up to 3 back
679  *        to back setup packets)
680  *              - In DMA mode, DOEPDMA0 Register with a memory address to
681  *                store any setup packets received
682  *
683  * @param core_if Programming view of DWC_otg controller.
684  * @param pcd     Programming view of the PCD.
685  */
686 static inline void ep0_out_start(dwc_otg_core_if_t * core_if,
687                                  dwc_otg_pcd_t * pcd)
688 {
689         dwc_otg_dev_if_t *dev_if = core_if->dev_if;
690         deptsiz0_data_t doeptsize0 = {.d32 = 0 };
691         dwc_otg_dma_desc_t *dma_desc;
692         depctl_data_t doepctl = {.d32 = 0 };
693
694 #ifdef VERBOSE
695         DWC_DEBUGPL(DBG_PCDV, "%s() doepctl0=%0x\n", __func__,
696                     dwc_read_reg32(&dev_if->out_ep_regs[0]->doepctl));
697 #endif
698
699         doeptsize0.b.supcnt = 3;
700         doeptsize0.b.pktcnt = 1;
701         doeptsize0.b.xfersize = 8 * 3;
702
703         if (core_if->dma_enable) {
704                 if (!core_if->dma_desc_enable) {
705                         /** put here as for Hermes mode deptisz register should not be written */
706                         dwc_write_reg32(&dev_if->out_ep_regs[0]->doeptsiz,
707                                         doeptsize0.d32);
708
709                         /** @todo dma needs to handle multiple setup packets (up to 3) */
710                         dwc_write_reg32(&dev_if->out_ep_regs[0]->doepdma,
711                                         pcd->setup_pkt_dma_handle);
712                 } else {
713                         dev_if->setup_desc_index =
714                             (dev_if->setup_desc_index + 1) & 1;
715                         dma_desc =
716                             dev_if->setup_desc_addr[dev_if->setup_desc_index];
717
718                         /** DMA Descriptor Setup */
719                         dma_desc->status.b.bs = BS_HOST_BUSY;
720                         dma_desc->status.b.l = 1;
721                         dma_desc->status.b.ioc = 1;
722                         dma_desc->status.b.bytes = pcd->ep0.dwc_ep.maxpacket;
723                         dma_desc->buf = pcd->setup_pkt_dma_handle;
724                         dma_desc->status.b.bs = BS_HOST_READY;
725
726                         /** DOEPDMA0 Register write */
727                         dwc_write_reg32(&dev_if->out_ep_regs[0]->doepdma,
728                                         dev_if->dma_setup_desc_addr[dev_if->
729                                                                     setup_desc_index]);
730                 }
731
732         } else {
733                 /** put here as for Hermes mode deptisz register should not be written */
734                 dwc_write_reg32(&dev_if->out_ep_regs[0]->doeptsiz,
735                                 doeptsize0.d32);
736         }
737
738         /** DOEPCTL0 Register write */
739         doepctl.b.epena = 1;
740         doepctl.b.cnak = 1;
741         //doepctl.b.snak = 1;
742         dwc_write_reg32(&dev_if->out_ep_regs[0]->doepctl, doepctl.d32);
743
744 #ifdef VERBOSE
745         DWC_DEBUGPL(DBG_PCDV, "doepctl0=%0x\n",
746                     dwc_read_reg32(&dev_if->out_ep_regs[0]->doepctl));
747         DWC_DEBUGPL(DBG_PCDV, "diepctl0=%0x\n",
748                     dwc_read_reg32(&dev_if->in_ep_regs[0]->diepctl));
749 #endif
750 }
751
752 /**
753  * This interrupt occurs when a USB Reset is detected.  When the USB
754  * Reset Interrupt occurs the device state is set to DEFAULT and the
755  * EP0 state is set to IDLE.
756  *      -#      Set the NAK bit for all OUT endpoints (DOEPCTLn.SNAK = 1)
757  *      -#      Unmask the following interrupt bits
758  *              - DAINTMSK.INEP0 = 1 (Control 0 IN endpoint)
759  *      - DAINTMSK.OUTEP0 = 1 (Control 0 OUT endpoint)
760  *      - DOEPMSK.SETUP = 1
761  *      - DOEPMSK.XferCompl = 1
762  *      - DIEPMSK.XferCompl = 1
763  *      - DIEPMSK.TimeOut = 1
764  *      -# Program the following fields in the endpoint specific registers
765  *      for Control OUT EP 0, in order to receive a setup packet
766  *      - DOEPTSIZ0.Packet Count = 3 (To receive up to 3 back to back
767  *        setup packets)
768  *      - DOEPTSIZE0.Transfer Size = 24 Bytes (To receive up to 3 back
769  *        to back setup packets)
770  *              - In DMA mode, DOEPDMA0 Register with a memory address to
771  *                store any setup packets received
772  * At this point, all the required initialization, except for enabling
773  * the control 0 OUT endpoint is done, for receiving SETUP packets.
774  */
775 int32_t dwc_otg_pcd_handle_usb_reset_intr(dwc_otg_pcd_t * pcd)
776 {
777         dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
778         dwc_otg_dev_if_t *dev_if = core_if->dev_if;
779         depctl_data_t doepctl = {.d32 = 0 };
780         depctl_data_t diepctl = {.d32 = 0 };
781         daint_data_t daintmsk = {.d32 = 0 };
782         doepmsk_data_t doepmsk = {.d32 = 0 };
783         diepmsk_data_t diepmsk = {.d32 = 0 };
784         dcfg_data_t dcfg = {.d32 = 0 };
785         grstctl_t resetctl = {.d32 = 0 };
786         dctl_data_t dctl = {.d32 = 0 };
787         int i = 0;
788         gintsts_data_t gintsts;
789         pcgcctl_data_t power = {.d32 = 0 };
790
791         power.d32 = dwc_read_reg32(core_if->pcgcctl);
792         if (power.b.stoppclk) {
793                 power.d32 = 0;
794                 power.b.stoppclk = 1;
795                 dwc_modify_reg32(core_if->pcgcctl, power.d32, 0);
796
797                 power.b.pwrclmp = 1;
798                 dwc_modify_reg32(core_if->pcgcctl, power.d32, 0);
799
800                 power.b.rstpdwnmodule = 1;
801                 dwc_modify_reg32(core_if->pcgcctl, power.d32, 0);
802         }
803
804         core_if->lx_state = DWC_OTG_L0;
805
806         DWC_DEBUGPL(DBG_CIL,"USB RESET\n");
807 #ifdef DWC_EN_ISOC
808         for (i = 1; i < 16; ++i) {
809                 dwc_otg_pcd_ep_t *ep;
810                 dwc_ep_t *dwc_ep;
811                 ep = get_in_ep(pcd, i);
812                 if (ep != 0) {
813                         dwc_ep = &ep->dwc_ep;
814                         dwc_ep->next_frame = 0xffffffff;
815                 }
816         }
817 #endif                          /* DWC_EN_ISOC */
818
819         /* reset the HNP settings */
820         dwc_otg_pcd_update_otg(pcd, 1);
821
822         /* Clear the Remote Wakeup Signalling */
823         dctl.b.rmtwkupsig = 1;
824         dwc_modify_reg32(&core_if->dev_if->dev_global_regs->dctl, dctl.d32, 0);
825
826         /* Set NAK for all OUT EPs */
827         doepctl.b.snak = 1;
828         for (i = 0; i <= dev_if->num_out_eps; i++) {
829                 dwc_write_reg32(&dev_if->out_ep_regs[i]->doepctl, doepctl.d32);
830         }
831
832         /* Set data pid0 for all eps except for ep0 */
833         doepctl.b.setd0pid = 1;
834         for (i = 1; i <= dev_if->num_out_eps; i++) {
835                 dwc_write_reg32(&dev_if->out_ep_regs[i]->doepctl, doepctl.d32);
836         }
837
838         diepctl.b.setd0pid = 1;
839         for (i = 1; i <= dev_if->num_in_eps; i++) {
840                 dwc_write_reg32(&dev_if->in_ep_regs[i]->diepctl, diepctl.d32);
841         }
842         /* Flush the NP Tx FIFO */
843         dwc_otg_flush_tx_fifo(core_if, 0x10);
844         /* Flush the NP Rx FIFO */
845         dwc_otg_flush_rx_fifo(core_if);
846         /* Flush the Learning Queue */
847         resetctl.b.intknqflsh = 1;
848         dwc_write_reg32(&core_if->core_global_regs->grstctl, resetctl.d32);
849
850         if (core_if->multiproc_int_enable) {
851                 daintmsk.b.inep0 = 1;
852                 daintmsk.b.outep0 = 1;
853                 dwc_write_reg32(&dev_if->dev_global_regs->deachintmsk,
854                                 daintmsk.d32);
855
856                 doepmsk.b.setup = 1;
857                 doepmsk.b.xfercompl = 1;
858                 doepmsk.b.ahberr = 1;
859                 doepmsk.b.epdisabled = 1;
860
861                 if (core_if->dma_desc_enable) {
862                         doepmsk.b.stsphsercvd = 1;
863                         doepmsk.b.bna = 1;
864                 }
865 /*              
866                 doepmsk.b.babble = 1;
867                 doepmsk.b.nyet = 1;
868                 
869                 if(core_if->dma_enable) {
870                         doepmsk.b.nak = 1;
871                 }
872 */
873                 dwc_write_reg32(&dev_if->dev_global_regs->doepeachintmsk[0],
874                                 doepmsk.d32);
875
876                 diepmsk.b.xfercompl = 1;
877                 diepmsk.b.timeout = 1;
878                 diepmsk.b.epdisabled = 1;
879                 diepmsk.b.ahberr = 1;
880                 diepmsk.b.intknepmis = 1;
881
882                 if (core_if->dma_desc_enable) {
883                         diepmsk.b.bna = 1;
884                 }
885 /*              
886                 if(core_if->dma_enable) {
887                         diepmsk.b.nak = 1;
888                 }
889 */
890                 dwc_write_reg32(&dev_if->dev_global_regs->diepeachintmsk[0],
891                                 diepmsk.d32);
892         } else {
893                 daintmsk.b.inep0 = 1;
894                 daintmsk.b.outep0 = 1;
895                 dwc_write_reg32(&dev_if->dev_global_regs->daintmsk,
896                                 daintmsk.d32);
897
898                 doepmsk.b.setup = 1;
899                 doepmsk.b.xfercompl = 1;
900                 doepmsk.b.ahberr = 1;
901                 doepmsk.b.epdisabled = 1;
902
903                 if (core_if->dma_desc_enable) {
904                         doepmsk.b.stsphsercvd = 1;
905                         doepmsk.b.bna = 1;
906                 }
907                 dwc_write_reg32(&dev_if->dev_global_regs->doepmsk, doepmsk.d32);
908
909                 diepmsk.b.xfercompl = 1;
910                 diepmsk.b.timeout = 1;
911                 diepmsk.b.epdisabled = 1;
912                 diepmsk.b.ahberr = 1;
913                 diepmsk.b.intknepmis = 1;
914
915                 if (core_if->dma_desc_enable) {
916                         diepmsk.b.bna = 1;
917                 }
918
919                 dwc_write_reg32(&dev_if->dev_global_regs->diepmsk, diepmsk.d32);
920         }
921
922         /* Reset Device Address */
923         dcfg.d32 = dwc_read_reg32(&dev_if->dev_global_regs->dcfg);
924         dcfg.b.devaddr = 0;
925         dwc_write_reg32(&dev_if->dev_global_regs->dcfg, dcfg.d32);
926
927         /* setup EP0 to receive SETUP packets */
928         ep0_out_start(core_if, pcd);
929
930         /* Clear interrupt */
931         gintsts.d32 = 0;
932         gintsts.b.usbreset = 1;
933         dwc_write_reg32(&core_if->core_global_regs->gintsts, gintsts.d32);
934
935         return 1;
936 }
937
938 /**
939  * Get the device speed from the device status register and convert it
940  * to USB speed constant.
941  *
942  * @param core_if Programming view of DWC_otg controller.
943  */
944 static int get_device_speed(dwc_otg_core_if_t * core_if)
945 {
946         dsts_data_t dsts;
947         int speed = 0;
948         dsts.d32 = dwc_read_reg32(&core_if->dev_if->dev_global_regs->dsts);
949
950         switch (dsts.b.enumspd) {
951         case DWC_DSTS_ENUMSPD_HS_PHY_30MHZ_OR_60MHZ:
952                 speed = USB_SPEED_HIGH;
953                 break;
954         case DWC_DSTS_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ:
955         case DWC_DSTS_ENUMSPD_FS_PHY_48MHZ:
956                 speed = USB_SPEED_FULL;
957                 break;
958
959         case DWC_DSTS_ENUMSPD_LS_PHY_6MHZ:
960                 speed = USB_SPEED_LOW;
961                 break;
962         }
963
964         return speed;
965 }
966
967 /**
968  * Read the device status register and set the device speed in the
969  * data structure.
970  * Set up EP0 to receive SETUP packets by calling dwc_ep0_activate.
971  */
972 int32_t dwc_otg_pcd_handle_enum_done_intr(dwc_otg_pcd_t * pcd)
973 {
974         dwc_otg_pcd_ep_t *ep0 = &pcd->ep0;
975         gintsts_data_t gintsts;
976         gusbcfg_data_t gusbcfg;
977         dwc_otg_core_global_regs_t *global_regs =
978             GET_CORE_IF(pcd)->core_global_regs;
979         uint8_t utmi16b, utmi8b;
980         int speed;
981         DWC_DEBUGPL(DBG_PCD, "SPEED ENUM\n");
982
983         if (GET_CORE_IF(pcd)->snpsid >= 0x4f54260a) {
984                 utmi16b = 6;
985                 utmi8b = 9;
986         } else {
987                 utmi16b = 4;
988                 utmi8b = 8;
989         }
990         dwc_otg_ep0_activate(GET_CORE_IF(pcd), &ep0->dwc_ep);
991
992 #ifdef DEBUG_EP0
993         print_ep0_state(pcd);
994 #endif
995
996
997         pcd->ep0state = EP0_IDLE;
998
999         ep0->stopped = 0;
1000
1001         speed = get_device_speed(GET_CORE_IF(pcd));
1002         pcd->fops->connect(pcd, speed);
1003
1004         /* Set USB turnaround time based on device speed and PHY interface. */
1005         gusbcfg.d32 = dwc_read_reg32(&global_regs->gusbcfg);
1006         if (speed == USB_SPEED_HIGH) {
1007                 if (GET_CORE_IF(pcd)->hwcfg2.b.hs_phy_type ==
1008                     DWC_HWCFG2_HS_PHY_TYPE_ULPI) {
1009                         /* ULPI interface */
1010                         gusbcfg.b.usbtrdtim = 9;
1011                 }
1012                 if (GET_CORE_IF(pcd)->hwcfg2.b.hs_phy_type ==
1013                     DWC_HWCFG2_HS_PHY_TYPE_UTMI) {
1014                         /* UTMI+ interface */
1015                         if (GET_CORE_IF(pcd)->hwcfg4.b.utmi_phy_data_width == 0) {
1016                                 gusbcfg.b.usbtrdtim = utmi8b;
1017                         } else if (GET_CORE_IF(pcd)->hwcfg4.b.
1018                                    utmi_phy_data_width == 1) {
1019                                 gusbcfg.b.usbtrdtim = utmi16b;
1020                         } else if (GET_CORE_IF(pcd)->core_params->
1021                                    phy_utmi_width == 8) {
1022                                 gusbcfg.b.usbtrdtim = utmi8b;
1023                         } else {
1024                                 gusbcfg.b.usbtrdtim = utmi16b;
1025                         }
1026                 }
1027                 if (GET_CORE_IF(pcd)->hwcfg2.b.hs_phy_type ==
1028                     DWC_HWCFG2_HS_PHY_TYPE_UTMI_ULPI) {
1029                         /* UTMI+  OR  ULPI interface */
1030                         if (gusbcfg.b.ulpi_utmi_sel == 1) {
1031                                 /* ULPI interface */
1032                                 gusbcfg.b.usbtrdtim = 9;
1033                         } else {
1034                                 /* UTMI+ interface */
1035                                 if (GET_CORE_IF(pcd)->core_params->
1036                                     phy_utmi_width == 16) {
1037                                         gusbcfg.b.usbtrdtim = utmi16b;
1038                                 } else {
1039                                         gusbcfg.b.usbtrdtim = utmi8b;
1040                                 }
1041                         }
1042                 }
1043         } else {
1044                 /* Full or low speed */
1045                 gusbcfg.b.usbtrdtim = 9;
1046         }
1047         dwc_write_reg32(&global_regs->gusbcfg, gusbcfg.d32);
1048
1049         /* Clear interrupt */
1050         gintsts.d32 = 0;
1051         gintsts.b.enumdone = 1;
1052         dwc_write_reg32(&GET_CORE_IF(pcd)->core_global_regs->gintsts,
1053                         gintsts.d32);
1054         return 1;
1055 }
1056
1057 /**
1058  * This interrupt indicates that the ISO OUT Packet was dropped due to
1059  * Rx FIFO full or Rx Status Queue Full.  If this interrupt occurs
1060  * read all the data from the Rx FIFO.
1061  */
1062 int32_t dwc_otg_pcd_handle_isoc_out_packet_dropped_intr(dwc_otg_pcd_t * pcd)
1063 {
1064         gintmsk_data_t intr_mask = {.d32 = 0 };
1065         gintsts_data_t gintsts;
1066
1067         DWC_DEBUGPL(DBG_CIL,"INTERRUPT Handler not implemented for %s\n",
1068                    "ISOC Out Dropped");
1069
1070         intr_mask.b.isooutdrop = 1;
1071         dwc_modify_reg32(&GET_CORE_IF(pcd)->core_global_regs->gintmsk,
1072                          intr_mask.d32, 0);
1073
1074         /* Clear interrupt */
1075         gintsts.d32 = 0;
1076         gintsts.b.isooutdrop = 1;
1077         dwc_write_reg32(&GET_CORE_IF(pcd)->core_global_regs->gintsts,
1078                         gintsts.d32);
1079
1080         return 1;
1081 }
1082
1083 /**
1084  * This interrupt indicates the end of the portion of the micro-frame
1085  * for periodic transactions.  If there is a periodic transaction for
1086  * the next frame, load the packets into the EP periodic Tx FIFO.
1087  */
1088 int32_t dwc_otg_pcd_handle_end_periodic_frame_intr(dwc_otg_pcd_t * pcd)
1089 {
1090         gintmsk_data_t intr_mask = {.d32 = 0 };
1091         gintsts_data_t gintsts;
1092         DWC_DEBUGPL(DBG_CIL,"INTERRUPT Handler not implemented for %s\n", "EOP");
1093
1094         intr_mask.b.eopframe = 1;
1095         dwc_modify_reg32(&GET_CORE_IF(pcd)->core_global_regs->gintmsk,
1096                          intr_mask.d32, 0);
1097
1098         /* Clear interrupt */
1099         gintsts.d32 = 0;
1100         gintsts.b.eopframe = 1;
1101         dwc_write_reg32(&GET_CORE_IF(pcd)->core_global_regs->gintsts,
1102                         gintsts.d32);
1103
1104         return 1;
1105 }
1106
1107 /**
1108  * This interrupt indicates that EP of the packet on the top of the
1109  * non-periodic Tx FIFO does not match EP of the IN Token received.
1110  *
1111  * The "Device IN Token Queue" Registers are read to determine the
1112  * order the IN Tokens have been received.      The non-periodic Tx FIFO
1113  * is flushed, so it can be reloaded in the order seen in the IN Token
1114  * Queue.
1115  */
1116 int32_t dwc_otg_pcd_handle_ep_mismatch_intr(dwc_otg_core_if_t * core_if)
1117 {
1118         gintsts_data_t gintsts;
1119         DWC_DEBUGPL(DBG_PCDV, "%s(%p)\n", __func__, core_if);
1120
1121         /* Clear interrupt */
1122         gintsts.d32 = 0;
1123         gintsts.b.epmismatch = 1;
1124         dwc_write_reg32(&core_if->core_global_regs->gintsts, gintsts.d32);
1125
1126         return 1;
1127 }
1128
1129 /**
1130  * This funcion stalls EP0.
1131  */
1132 static inline void ep0_do_stall(dwc_otg_pcd_t * pcd, const int err_val)
1133 {
1134         dwc_otg_pcd_ep_t *ep0 = &pcd->ep0;
1135         usb_device_request_t *ctrl = &pcd->setup_pkt->req;
1136         DWC_WARN("req %02x.%02x protocol STALL; err %d\n",
1137                  ctrl->bmRequestType, ctrl->bRequest, err_val);
1138
1139         ep0->dwc_ep.is_in = 1;
1140         dwc_otg_ep_set_stall(GET_CORE_IF(pcd), &ep0->dwc_ep);
1141         pcd->ep0.stopped = 1;
1142         pcd->ep0state = EP0_IDLE;
1143         ep0_out_start(GET_CORE_IF(pcd), pcd);
1144 }
1145
1146 /**
1147  * This functions delegates the setup command to the gadget driver.
1148  */
1149 static inline void do_gadget_setup(dwc_otg_pcd_t * pcd,
1150                                    usb_device_request_t * ctrl)
1151 {
1152         int ret = 0;
1153         DWC_SPINUNLOCK(pcd->lock);
1154         ret = pcd->fops->setup(pcd, (uint8_t *) ctrl);
1155         DWC_SPINLOCK(pcd->lock);
1156         if (ret < 0) {
1157                 ep0_do_stall(pcd, ret);
1158         }
1159
1160         /** @todo This is a g_file_storage gadget driver specific
1161          * workaround: a DELAYED_STATUS result from the fsg_setup
1162          * routine will result in the gadget queueing a EP0 IN status
1163          * phase for a two-stage control transfer.      Exactly the same as
1164          * a SET_CONFIGURATION/SET_INTERFACE except that this is a class
1165          * specific request.  Need a generic way to know when the gadget
1166          * driver will queue the status phase.  Can we assume when we
1167          * call the gadget driver setup() function that it will always
1168          * queue and require the following flag?  Need to look into
1169          * this.
1170          */
1171
1172         if (ret == 256 + 999) {
1173                 pcd->request_config = 1;
1174         }
1175 }
1176
1177 #ifdef DWC_UTE_CFI
1178 /**
1179  * This functions delegates the CFI setup commands to the gadget driver.
1180  * This function will return a negative value to indicate a failure.
1181  */
1182 static inline int cfi_gadget_setup(dwc_otg_pcd_t * pcd,
1183                                    struct cfi_usb_ctrlrequest *ctrl_req)
1184 {
1185         int ret = 0;
1186
1187         if (pcd->fops && pcd->fops->cfi_setup) {
1188                 DWC_SPINUNLOCK(pcd->lock);
1189                 ret = pcd->fops->cfi_setup(pcd, ctrl_req);
1190                 DWC_SPINLOCK(pcd->lock);
1191                 if (ret < 0) {
1192                         ep0_do_stall(pcd, ret);
1193                         return ret;
1194                 }
1195         }
1196
1197         return ret;
1198 }
1199 #endif
1200
1201 /**
1202  * This function starts the Zero-Length Packet for the IN status phase
1203  * of a 2 stage control transfer.
1204  */
1205 static inline void do_setup_in_status_phase(dwc_otg_pcd_t * pcd)
1206 {
1207         dwc_otg_pcd_ep_t *ep0 = &pcd->ep0;
1208         if (pcd->ep0state == EP0_STALL) {
1209                 return;
1210         }
1211
1212         pcd->ep0state = EP0_IN_STATUS_PHASE;
1213
1214         /* Prepare for more SETUP Packets */
1215         DWC_DEBUGPL(DBG_PCD, "EP0 IN ZLP\n");
1216         ep0->dwc_ep.xfer_len = 0;
1217         ep0->dwc_ep.xfer_count = 0;
1218         ep0->dwc_ep.is_in = 1;
1219         ep0->dwc_ep.dma_addr = pcd->setup_pkt_dma_handle;
1220         dwc_otg_ep0_start_transfer(GET_CORE_IF(pcd), &ep0->dwc_ep);
1221
1222         /* Prepare for more SETUP Packets */
1223         //ep0_out_start(GET_CORE_IF(pcd), pcd);
1224 }
1225
1226 /**
1227  * This function starts the Zero-Length Packet for the OUT status phase
1228  * of a 2 stage control transfer.
1229  */
1230 static inline void do_setup_out_status_phase(dwc_otg_pcd_t * pcd)
1231 {
1232         dwc_otg_pcd_ep_t *ep0 = &pcd->ep0;
1233         if (pcd->ep0state == EP0_STALL) {
1234                 DWC_DEBUGPL(DBG_PCD, "EP0 STALLED\n");
1235                 return;
1236         }
1237         pcd->ep0state = EP0_OUT_STATUS_PHASE;
1238
1239         DWC_DEBUGPL(DBG_PCD, "EP0 OUT ZLP\n");
1240         ep0->dwc_ep.xfer_len = 0;
1241         ep0->dwc_ep.xfer_count = 0;
1242         ep0->dwc_ep.is_in = 0;
1243         ep0->dwc_ep.dma_addr = pcd->setup_pkt_dma_handle;
1244         dwc_otg_ep0_start_transfer(GET_CORE_IF(pcd), &ep0->dwc_ep);
1245
1246         /* Prepare for more SETUP Packets */
1247         if (GET_CORE_IF(pcd)->dma_enable == 0) {
1248                 ep0_out_start(GET_CORE_IF(pcd), pcd);
1249         }
1250 }
1251
1252 /**
1253  * Clear the EP halt (STALL) and if pending requests start the
1254  * transfer.
1255  */
1256 static inline void pcd_clear_halt(dwc_otg_pcd_t * pcd, dwc_otg_pcd_ep_t * ep)
1257 {
1258         if (ep->dwc_ep.stall_clear_flag == 0)
1259                 dwc_otg_ep_clear_stall(GET_CORE_IF(pcd), &ep->dwc_ep);
1260
1261         /* Reactive the EP */
1262         dwc_otg_ep_activate(GET_CORE_IF(pcd), &ep->dwc_ep);
1263         if (ep->stopped) {
1264                 ep->stopped = 0;
1265                 /* If there is a request in the EP queue start it */
1266
1267                 /** @todo FIXME: this causes an EP mismatch in DMA mode.
1268                  * epmismatch not yet implemented. */
1269
1270                 /*
1271                  * Above fixme is solved by implmenting a tasklet to call the
1272                  * start_next_request(), outside of interrupt context at some
1273                  * time after the current time, after a clear-halt setup packet.
1274                  * Still need to implement ep mismatch in the future if a gadget
1275                  * ever uses more than one endpoint at once
1276                  */
1277                 ep->queue_sof = 1;
1278                 DWC_TASK_SCHEDULE(pcd->start_xfer_tasklet);
1279         }
1280         /* Start Control Status Phase */
1281         do_setup_in_status_phase(pcd);
1282 }
1283
1284 /**
1285  * This function is called when the SET_FEATURE TEST_MODE Setup packet
1286  * is sent from the host.  The Device Control register is written with
1287  * the Test Mode bits set to the specified Test Mode.  This is done as
1288  * a tasklet so that the "Status" phase of the control transfer
1289  * completes before transmitting the TEST packets.
1290  *
1291  * @todo This has not been tested since the tasklet struct was put
1292  * into the PCD struct!
1293  *
1294  */
1295 void do_test_mode(void *data)
1296 {
1297         dctl_data_t dctl;
1298         dwc_otg_pcd_t *pcd = (dwc_otg_pcd_t *) data;
1299         dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
1300         int test_mode = pcd->test_mode;
1301
1302 //        DWC_WARN("%s() has not been tested since being rewritten!\n", __func__);
1303
1304         dctl.d32 = dwc_read_reg32(&core_if->dev_if->dev_global_regs->dctl);
1305         switch (test_mode) {
1306         case 1:         // TEST_J
1307                 dctl.b.tstctl = 1;
1308                 break;
1309
1310         case 2:         // TEST_K
1311                 dctl.b.tstctl = 2;
1312                 break;
1313
1314         case 3:         // TEST_SE0_NAK
1315                 dctl.b.tstctl = 3;
1316                 break;
1317
1318         case 4:         // TEST_PACKET
1319                 dctl.b.tstctl = 4;
1320                 break;
1321
1322         case 5:         // TEST_FORCE_ENABLE
1323                 dctl.b.tstctl = 5;
1324                 break;
1325         }
1326         dwc_write_reg32(&core_if->dev_if->dev_global_regs->dctl, dctl.d32);
1327 }
1328
1329 /**
1330  * This function process the GET_STATUS Setup Commands.
1331  */
1332 static inline void do_get_status(dwc_otg_pcd_t * pcd)
1333 {
1334         usb_device_request_t ctrl = pcd->setup_pkt->req;
1335         dwc_otg_pcd_ep_t *ep;
1336         dwc_otg_pcd_ep_t *ep0 = &pcd->ep0;
1337         uint16_t *status = pcd->status_buf;
1338
1339 #ifdef DEBUG_EP0
1340         DWC_DEBUGPL(DBG_PCD,
1341                     "GET_STATUS %02x.%02x v%04x i%04x l%04x\n",
1342                     ctrl.bmRequestType, ctrl.bRequest,
1343                     UGETW(ctrl.wValue), UGETW(ctrl.wIndex),
1344                     UGETW(ctrl.wLength));
1345 #endif
1346
1347         switch (UT_GET_RECIPIENT(ctrl.bmRequestType)) {
1348         case UT_DEVICE:
1349                 *status = 0x1;  /* Self powered */
1350                 *status |= pcd->remote_wakeup_enable << 1;
1351                 break;
1352
1353         case UT_INTERFACE:
1354                 *status = 0;
1355                 break;
1356
1357         case UT_ENDPOINT:
1358                 ep = get_ep_by_addr(pcd, UGETW(ctrl.wIndex));
1359                 if (ep == 0 || UGETW(ctrl.wLength) > 2) {
1360                         ep0_do_stall(pcd, -DWC_E_NOT_SUPPORTED);
1361                         return;
1362                 }
1363                 /** @todo check for EP stall */
1364                 *status = ep->stopped;
1365                 break;
1366         }
1367         pcd->ep0_pending = 1;
1368         ep0->dwc_ep.start_xfer_buff = (uint8_t *) status;
1369         ep0->dwc_ep.xfer_buff = (uint8_t *) status;
1370         ep0->dwc_ep.dma_addr = pcd->status_buf_dma_handle;
1371         ep0->dwc_ep.xfer_len = 2;
1372         ep0->dwc_ep.xfer_count = 0;
1373         ep0->dwc_ep.total_len = ep0->dwc_ep.xfer_len;
1374         dwc_otg_ep0_start_transfer(GET_CORE_IF(pcd), &ep0->dwc_ep);
1375 }
1376
1377 /**
1378  * This function process the SET_FEATURE Setup Commands.
1379  */
1380 static inline void do_set_feature(dwc_otg_pcd_t * pcd)
1381 {
1382         dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
1383         dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
1384         usb_device_request_t ctrl = pcd->setup_pkt->req;
1385         dwc_otg_pcd_ep_t *ep = 0;
1386         int32_t otg_cap_param = core_if->core_params->otg_cap;
1387         gotgctl_data_t gotgctl = {.d32 = 0 };
1388
1389         DWC_DEBUGPL(DBG_PCD, "SET_FEATURE:%02x.%02x v%04x i%04x l%04x\n",
1390                     ctrl.bmRequestType, ctrl.bRequest,
1391                     UGETW(ctrl.wValue), UGETW(ctrl.wIndex),
1392                     UGETW(ctrl.wLength));
1393         DWC_DEBUGPL(DBG_PCD, "otg_cap=%d\n", otg_cap_param);
1394
1395         switch (UT_GET_RECIPIENT(ctrl.bmRequestType)) {
1396         case UT_DEVICE:
1397                 switch (UGETW(ctrl.wValue)) {
1398                 case UF_DEVICE_REMOTE_WAKEUP:
1399                         pcd->remote_wakeup_enable = 1;
1400                         break;
1401
1402                 case UF_TEST_MODE:
1403                         /* Setup the Test Mode tasklet to do the Test
1404                          * Packet generation after the SETUP Status
1405                          * phase has completed. */
1406
1407                         /** @todo This has not been tested since the
1408                          * tasklet struct was put into the PCD
1409                          * struct! */
1410                         pcd->test_mode = UGETW(ctrl.wIndex) >> 8;
1411                         DWC_TASK_SCHEDULE(pcd->test_mode_tasklet);
1412                         break;
1413
1414                 case UF_DEVICE_B_HNP_ENABLE:
1415                         DWC_DEBUGPL(DBG_PCDV,
1416                                     "SET_FEATURE: USB_DEVICE_B_HNP_ENABLE\n");
1417
1418                         /* dev may initiate HNP */
1419                         if (otg_cap_param == DWC_OTG_CAP_PARAM_HNP_SRP_CAPABLE) {
1420                                 pcd->b_hnp_enable = 1;
1421                                 dwc_otg_pcd_update_otg(pcd, 0);
1422                                 DWC_DEBUGPL(DBG_PCD, "Request B HNP\n");
1423                                 /**@todo Is the gotgctl.devhnpen cleared
1424                                  * by a USB Reset? */
1425                                 gotgctl.b.devhnpen = 1;
1426                                 gotgctl.b.hnpreq = 1;
1427                                 dwc_write_reg32(&global_regs->gotgctl,
1428                                                 gotgctl.d32);
1429                         } else {
1430                                 ep0_do_stall(pcd, -DWC_E_NOT_SUPPORTED);
1431                         }
1432                         break;
1433
1434                 case UF_DEVICE_A_HNP_SUPPORT:
1435                         /* RH port supports HNP */
1436                         DWC_DEBUGPL(DBG_PCDV,
1437                                     "SET_FEATURE: USB_DEVICE_A_HNP_SUPPORT\n");
1438                         if (otg_cap_param == DWC_OTG_CAP_PARAM_HNP_SRP_CAPABLE) {
1439                                 pcd->a_hnp_support = 1;
1440                                 dwc_otg_pcd_update_otg(pcd, 0);
1441                         } else {
1442                                 ep0_do_stall(pcd, -DWC_E_NOT_SUPPORTED);
1443                         }
1444                         break;
1445
1446                 case UF_DEVICE_A_ALT_HNP_SUPPORT:
1447                         /* other RH port does */
1448                         dwc_debug(
1449                                     "SET_FEATURE: USB_DEVICE_A_ALT_HNP_SUPPORT\n");
1450                         if (otg_cap_param == DWC_OTG_CAP_PARAM_HNP_SRP_CAPABLE) {
1451                                 pcd->a_alt_hnp_support = 1;
1452                                 dwc_otg_pcd_update_otg(pcd, 0);
1453                         } else {
1454                                 ep0_do_stall(pcd, -DWC_E_NOT_SUPPORTED);
1455                         }
1456                         break;
1457                 }
1458                 do_setup_in_status_phase(pcd);
1459                 break;
1460
1461         case UT_INTERFACE:
1462                 do_gadget_setup(pcd, &ctrl);
1463                 break;
1464
1465         case UT_ENDPOINT:
1466                 if (UGETW(ctrl.wValue) == UF_ENDPOINT_HALT) {
1467                         ep = get_ep_by_addr(pcd, UGETW(ctrl.wIndex));
1468                         if (ep == 0) {
1469                                 ep0_do_stall(pcd, -DWC_E_NOT_SUPPORTED);
1470                                 return;
1471                         }
1472                         ep->stopped = 1;
1473                         dwc_otg_ep_set_stall(core_if, &ep->dwc_ep);
1474                 }
1475                 do_setup_in_status_phase(pcd);
1476                 break;
1477         }
1478 }
1479
1480 /**
1481  * This function process the CLEAR_FEATURE Setup Commands.
1482  */
1483 static inline void do_clear_feature(dwc_otg_pcd_t * pcd)
1484 {
1485         usb_device_request_t ctrl = pcd->setup_pkt->req;
1486         dwc_otg_pcd_ep_t *ep = 0;
1487
1488         DWC_DEBUGPL(DBG_PCD,
1489                     "CLEAR_FEATURE:%02x.%02x v%04x i%04x l%04x\n",
1490                     ctrl.bmRequestType, ctrl.bRequest,
1491                     UGETW(ctrl.wValue), UGETW(ctrl.wIndex),
1492                     UGETW(ctrl.wLength));
1493
1494         switch (UT_GET_RECIPIENT(ctrl.bmRequestType)) {
1495         case UT_DEVICE:
1496                 switch (UGETW(ctrl.wValue)) {
1497                 case UF_DEVICE_REMOTE_WAKEUP:
1498                         pcd->remote_wakeup_enable = 0;
1499                         break;
1500
1501                 case UF_TEST_MODE:
1502                         /** @todo Add CLEAR_FEATURE for TEST modes. */
1503                         break;
1504                 }
1505                 do_setup_in_status_phase(pcd);
1506                 break;
1507
1508         case UT_ENDPOINT:
1509                 ep = get_ep_by_addr(pcd, UGETW(ctrl.wIndex));
1510                 if (ep == 0) {
1511                         ep0_do_stall(pcd, -DWC_E_NOT_SUPPORTED);
1512                         return;
1513                 }
1514
1515                 pcd_clear_halt(pcd, ep);
1516
1517                 break;
1518         }
1519 }
1520
1521 /**
1522  * This function process the SET_ADDRESS Setup Commands.
1523  */
1524 static inline void do_set_address(dwc_otg_pcd_t * pcd)
1525 {
1526         dwc_otg_dev_if_t *dev_if = GET_CORE_IF(pcd)->dev_if;
1527         usb_device_request_t ctrl = pcd->setup_pkt->req;
1528
1529         if (ctrl.bmRequestType == UT_DEVICE) {
1530                 dcfg_data_t dcfg = {.d32 = 0 };
1531
1532 #ifdef DEBUG_EP0
1533 //                      DWC_DEBUGPL(DBG_PCDV, "SET_ADDRESS:%d\n", ctrl.wValue);
1534 #endif
1535                 dcfg.b.devaddr = UGETW(ctrl.wValue);
1536                 dwc_modify_reg32(&dev_if->dev_global_regs->dcfg, 0, dcfg.d32);
1537                 do_setup_in_status_phase(pcd);
1538         }
1539 }
1540
1541 /**
1542  *      This function processes SETUP commands.  In Linux, the USB Command
1543  *      processing is done in two places - the first being the PCD and the
1544  *      second in the Gadget Driver (for example, the File-Backed Storage
1545  *      Gadget Driver).
1546  *
1547  * <table>
1548  * <tr><td>Command      </td><td>Driver </td><td>Description</td></tr>
1549  *
1550  * <tr><td>GET_STATUS </td><td>PCD </td><td>Command is processed as
1551  * defined in chapter 9 of the USB 2.0 Specification chapter 9
1552  * </td></tr>
1553  *
1554  * <tr><td>CLEAR_FEATURE </td><td>PCD </td><td>The Device and Endpoint
1555  * requests are the ENDPOINT_HALT feature is procesed, all others the
1556  * interface requests are ignored.</td></tr>
1557  *
1558  * <tr><td>SET_FEATURE </td><td>PCD </td><td>The Device and Endpoint
1559  * requests are processed by the PCD.  Interface requests are passed
1560  * to the Gadget Driver.</td></tr>
1561  *
1562  * <tr><td>SET_ADDRESS </td><td>PCD </td><td>Program the DCFG reg,
1563  * with device address received </td></tr>
1564  *
1565  * <tr><td>GET_DESCRIPTOR </td><td>Gadget Driver </td><td>Return the
1566  * requested descriptor</td></tr>
1567  *
1568  * <tr><td>SET_DESCRIPTOR </td><td>Gadget Driver </td><td>Optional -
1569  * not implemented by any of the existing Gadget Drivers.</td></tr>
1570  *
1571  * <tr><td>SET_CONFIGURATION </td><td>Gadget Driver </td><td>Disable
1572  * all EPs and enable EPs for new configuration.</td></tr>
1573  *
1574  * <tr><td>GET_CONFIGURATION </td><td>Gadget Driver </td><td>Return
1575  * the current configuration</td></tr>
1576  *
1577  * <tr><td>SET_INTERFACE </td><td>Gadget Driver </td><td>Disable all
1578  * EPs and enable EPs for new configuration.</td></tr>
1579  *
1580  * <tr><td>GET_INTERFACE </td><td>Gadget Driver </td><td>Return the
1581  * current interface.</td></tr>
1582  *
1583  * <tr><td>SYNC_FRAME </td><td>PCD </td><td>Display debug
1584  * message.</td></tr>
1585  * </table>
1586  *
1587  * When the SETUP Phase Done interrupt occurs, the PCD SETUP commands are
1588  * processed by pcd_setup. Calling the Function Driver's setup function from
1589  * pcd_setup processes the gadget SETUP commands.
1590  */
1591 static inline void pcd_setup(dwc_otg_pcd_t * pcd)
1592 {
1593         dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
1594         dwc_otg_dev_if_t *dev_if = core_if->dev_if;
1595         usb_device_request_t ctrl = pcd->setup_pkt->req;
1596         dwc_otg_pcd_ep_t *ep0 = &pcd->ep0;
1597
1598         deptsiz0_data_t doeptsize0 = {.d32 = 0 };
1599
1600 #ifdef DWC_UTE_CFI
1601         int retval = 0;
1602         struct cfi_usb_ctrlrequest cfi_req;
1603 #endif
1604
1605 #ifdef DEBUG_EP0
1606         DWC_DEBUGPL(DBG_PCD, "SETUP %02x.%02x v%04x i%04x l%04x\n",
1607                     ctrl.bmRequestType, ctrl.bRequest,
1608                     UGETW(ctrl.wValue), UGETW(ctrl.wIndex),
1609                     UGETW(ctrl.wLength));
1610 #endif
1611
1612         doeptsize0.d32 = dwc_read_reg32(&dev_if->out_ep_regs[0]->doeptsiz);
1613
1614         /** @todo handle > 1 setup packet , assert error for now */
1615
1616         if (core_if->dma_enable && core_if->dma_desc_enable == 0
1617             && (doeptsize0.b.supcnt < 2)) {
1618                 DWC_ERROR
1619                     ("\n\n-----------    CANNOT handle > 1 setup packet in DMA mode\n\n");
1620         }
1621
1622         /* Clean up the request queue */
1623         dwc_otg_request_nuke(ep0);
1624         ep0->stopped = 0;
1625
1626         if (ctrl.bmRequestType & UE_DIR_IN) {
1627                 ep0->dwc_ep.is_in = 1;
1628                 pcd->ep0state = EP0_IN_DATA_PHASE;
1629         } else {
1630                 ep0->dwc_ep.is_in = 0;
1631                 pcd->ep0state = EP0_OUT_DATA_PHASE;
1632         }
1633
1634         if (UGETW(ctrl.wLength) == 0) {
1635                 ep0->dwc_ep.is_in = 1;
1636                 pcd->ep0state = EP0_IN_STATUS_PHASE;
1637         }
1638
1639         if (UT_GET_TYPE(ctrl.bmRequestType) != UT_STANDARD) {
1640
1641 #ifdef DWC_UTE_CFI
1642                 DWC_MEMCPY(&cfi_req, &ctrl, sizeof(usb_device_request_t));
1643
1644                 //printk(KERN_ALERT "CFI: req_type=0x%02x; req=0x%02x\n", ctrl.bRequestType, ctrl.bRequest);
1645                 if (UT_GET_TYPE(cfi_req.bRequestType) == UT_VENDOR) {
1646                         if (cfi_req.bRequest > 0xB0 && cfi_req.bRequest < 0xBF) {
1647                                 retval = cfi_setup(pcd, &cfi_req);
1648                                 if (retval < 0) {
1649                                         ep0_do_stall(pcd, retval);
1650                                         pcd->ep0_pending = 0;
1651                                         return;
1652                                 }
1653
1654                                 /* if need gadget setup then call it and check the retval */
1655                                 if (pcd->cfi->need_gadget_att) {
1656                                         retval =
1657                                             cfi_gadget_setup(pcd,
1658                                                              &pcd->cfi->
1659                                                              ctrl_req);
1660                                         if (retval < 0) {
1661                                                 pcd->ep0_pending = 0;
1662                                                 return;
1663                                         }
1664                                 }
1665
1666                                 if (pcd->cfi->need_status_in_complete) {
1667                                         do_setup_in_status_phase(pcd);
1668                                 }
1669                                 return;
1670                         }
1671                 }
1672 #endif
1673
1674                 /* handle non-standard (class/vendor) requests in the gadget driver */
1675                 do_gadget_setup(pcd, &ctrl);
1676                 return;
1677         }
1678
1679         /** @todo NGS: Handle bad setup packet? */
1680
1681 ///////////////////////////////////////////
1682 //// --- Standard Request handling --- ////
1683
1684         switch (ctrl.bRequest) {
1685         case UR_GET_STATUS:
1686                 do_get_status(pcd);
1687                 break;
1688
1689         case UR_CLEAR_FEATURE:
1690                 do_clear_feature(pcd);
1691                 break;
1692
1693         case UR_SET_FEATURE:
1694                 do_set_feature(pcd);
1695                 break;
1696
1697         case UR_SET_ADDRESS:
1698                 do_set_address(pcd);
1699                 break;
1700
1701         case UR_SET_INTERFACE:
1702         case UR_SET_CONFIG:
1703 //              _pcd->request_config = 1;       /* Configuration changed */
1704                 do_gadget_setup(pcd, &ctrl);
1705                 break;
1706
1707         case UR_SYNCH_FRAME:
1708                 do_gadget_setup(pcd, &ctrl);
1709                 break;
1710
1711         default:
1712                 /* Call the Gadget Driver's setup functions */
1713                 do_gadget_setup(pcd, &ctrl);
1714                 break;
1715         }
1716 }
1717
1718 /**
1719  * This function completes the ep0 control transfer.
1720  */
1721 static int32_t ep0_complete_request(dwc_otg_pcd_ep_t * ep)
1722 {
1723         dwc_otg_core_if_t *core_if = GET_CORE_IF(ep->pcd);
1724         dwc_otg_dev_if_t *dev_if = core_if->dev_if;
1725         dwc_otg_dev_in_ep_regs_t *in_ep_regs =
1726             dev_if->in_ep_regs[ep->dwc_ep.num];
1727 #ifdef DEBUG_EP0
1728         dwc_otg_dev_out_ep_regs_t *out_ep_regs =
1729             dev_if->out_ep_regs[ep->dwc_ep.num];
1730 #endif
1731         deptsiz0_data_t deptsiz;
1732         desc_sts_data_t desc_sts;
1733         dwc_otg_pcd_request_t *req;
1734         int is_last = 0;
1735         dwc_otg_pcd_t *pcd = ep->pcd;
1736
1737 #ifdef DWC_UTE_CFI
1738         struct cfi_usb_ctrlrequest *ctrlreq;
1739         int retval = -DWC_E_NOT_SUPPORTED;
1740 #endif
1741
1742         if (pcd->ep0_pending && DWC_CIRCLEQ_EMPTY(&ep->queue)) {
1743                 if (ep->dwc_ep.is_in) {
1744 #ifdef DEBUG_EP0
1745                         DWC_DEBUGPL(DBG_PCDV, "Do setup OUT status phase\n");
1746 #endif
1747                         do_setup_out_status_phase(pcd);
1748                 } else {
1749 #ifdef DEBUG_EP0
1750                         DWC_DEBUGPL(DBG_PCDV, "Do setup IN status phase\n");
1751 #endif
1752
1753 #ifdef DWC_UTE_CFI
1754                         ctrlreq = &pcd->cfi->ctrl_req;
1755
1756                         if (UT_GET_TYPE(ctrlreq->bRequestType) == UT_VENDOR) {
1757                                 if (ctrlreq->bRequest > 0xB0
1758                                     && ctrlreq->bRequest < 0xBF) {
1759
1760                                         /* Return if the PCD failed to handle the request */
1761                                         if ((retval =
1762                                              pcd->cfi->ops.
1763                                              ctrl_write_complete(pcd->cfi,
1764                                                                  pcd)) < 0) {
1765                                                 CFI_INFO
1766                                                     ("ERROR setting a new value in the PCD(%d)\n",
1767                                                      retval);
1768                                                 ep0_do_stall(pcd, retval);
1769                                                 pcd->ep0_pending = 0;
1770                                                 return 0;
1771                                         }
1772
1773                                         /* If the gadget needs to be notified on the request */
1774                                         if (pcd->cfi->need_gadget_att == 1) {
1775                                                 //retval = do_gadget_setup(pcd, &pcd->cfi->ctrl_req);
1776                                                 retval =
1777                                                     cfi_gadget_setup(pcd,
1778                                                                      &pcd->cfi->
1779                                                                      ctrl_req);
1780
1781                                                 /* Return from the function if the gadget failed to process
1782                                                  * the request properly - this should never happen !!!
1783                                                  */
1784                                                 if (retval < 0) {
1785                                                         CFI_INFO
1786                                                             ("ERROR setting a new value in the gadget(%d)\n",
1787                                                              retval);
1788                                                         pcd->ep0_pending = 0;
1789                                                         return 0;
1790                                                 }
1791                                         }
1792
1793                                         CFI_INFO("%s: RETVAL=%d\n", __func__,
1794                                                  retval);
1795                                         /* If we hit here then the PCD and the gadget has properly
1796                                          * handled the request - so send the ZLP IN to the host.
1797                                          */
1798                                         /* @todo: MAS - decide whether we need to start the setup
1799                                          * stage based on the need_setup value of the cfi object
1800                                          */
1801                                         do_setup_in_status_phase(pcd);
1802                                         pcd->ep0_pending = 0;
1803                                         return 1;
1804                                 }
1805                         }
1806 #endif
1807
1808                         do_setup_in_status_phase(pcd);
1809                 }
1810                 pcd->ep0_pending = 0;
1811                 return 1;
1812         }
1813
1814         if (DWC_CIRCLEQ_EMPTY(&ep->queue)) {
1815                 return 0;
1816         }
1817         req = DWC_CIRCLEQ_FIRST(&ep->queue);
1818
1819         if (pcd->ep0state == EP0_OUT_STATUS_PHASE
1820             || pcd->ep0state == EP0_IN_STATUS_PHASE) {
1821                 is_last = 1;
1822         } else if (ep->dwc_ep.is_in) {
1823                 deptsiz.d32 = dwc_read_reg32(&in_ep_regs->dieptsiz);
1824                 if (core_if->dma_desc_enable != 0)
1825                         desc_sts = dev_if->in_desc_addr->status;
1826 #ifdef DEBUG_EP0
1827                 DWC_DEBUGPL(DBG_PCDV, "%d len=%d  xfersize=%d pktcnt=%d\n",
1828                             ep->dwc_ep.num, ep->dwc_ep.xfer_len,
1829                             deptsiz.b.xfersize, deptsiz.b.pktcnt);
1830 #endif
1831
1832                 if (((core_if->dma_desc_enable == 0)
1833                      && (deptsiz.b.xfersize == 0))
1834                     || ((core_if->dma_desc_enable != 0)
1835                         && (desc_sts.b.bytes == 0))) {
1836                         req->actual = ep->dwc_ep.xfer_count;
1837                         /* Is a Zero Len Packet needed? */
1838                         if (req->sent_zlp) {
1839 #ifdef DEBUG_EP0
1840                                 DWC_DEBUGPL(DBG_PCD, "Setup Rx ZLP\n");
1841 #endif
1842                                 req->sent_zlp = 0;
1843                         }
1844                         do_setup_out_status_phase(pcd);
1845                 }
1846         } else {
1847                 /* ep0-OUT */
1848 #ifdef DEBUG_EP0
1849                 deptsiz.d32 = dwc_read_reg32(&out_ep_regs->doeptsiz);
1850                 DWC_DEBUGPL(DBG_PCDV, "%d len=%d xsize=%d pktcnt=%d\n",
1851                             ep->dwc_ep.num, ep->dwc_ep.xfer_len,
1852                             deptsiz.b.xfersize, deptsiz.b.pktcnt);
1853 #endif
1854                 req->actual = ep->dwc_ep.xfer_count;
1855
1856                 /* Is a Zero Len Packet needed? */
1857                 if (req->sent_zlp) {
1858 #ifdef DEBUG_EP0
1859                         DWC_DEBUGPL(DBG_PCDV, "Setup Tx ZLP\n");
1860 #endif
1861                         req->sent_zlp = 0;
1862                 }
1863                 if (core_if->dma_desc_enable == 0)
1864                         do_setup_in_status_phase(pcd);
1865         }
1866
1867         /* Complete the request */
1868         if (is_last) {
1869                 dwc_otg_request_done(ep, req, 0);
1870                 ep->dwc_ep.start_xfer_buff = 0;
1871                 ep->dwc_ep.xfer_buff = 0;
1872                 ep->dwc_ep.xfer_len = 0;
1873                 return 1;
1874         }
1875         return 0;
1876 }
1877
1878 #ifdef DWC_UTE_CFI
1879 /**
1880  * This function calculates traverses all the CFI DMA descriptors and
1881  * and accumulates the bytes that are left to be transfered.
1882  *
1883  * @return The total bytes left to transfered, or a negative value as failure
1884  */
1885 static inline int cfi_calc_desc_residue(dwc_otg_pcd_ep_t * ep)
1886 {
1887         int32_t ret = 0;
1888         int i;
1889         struct dwc_otg_dma_desc *ddesc = NULL;
1890         struct cfi_ep *cfiep;
1891
1892         /* See if the pcd_ep has its respective cfi_ep mapped */
1893         cfiep = get_cfi_ep_by_pcd_ep(ep->pcd->cfi, ep);
1894         if (!cfiep) {
1895                 CFI_INFO("%s: Failed to find ep\n", __func__);
1896                 return -1;
1897         }
1898
1899         ddesc = ep->dwc_ep.descs;
1900
1901         for (i = 0; (i < cfiep->desc_count) && (i < MAX_DMA_DESCS_PER_EP); i++) {
1902
1903 #if defined(PRINT_CFI_DMA_DESCS)
1904                 print_desc(ddesc, ep->ep.name, i);
1905 #endif
1906                 ret += ddesc->status.b.bytes;
1907                 ddesc++;
1908         }
1909
1910         if (ret)
1911                 CFI_INFO("!!!!!!!!!! WARNING (%s) - residue=%d\n", __func__,
1912                          ret);
1913
1914         return ret;
1915 }
1916 #endif
1917
1918 /**
1919  * This function completes the request for the EP.      If there are
1920  * additional requests for the EP in the queue they will be started.
1921  */
1922 static void complete_ep(dwc_otg_pcd_ep_t * ep)
1923 {
1924         dwc_otg_core_if_t *core_if = GET_CORE_IF(ep->pcd);
1925         dwc_otg_dev_if_t *dev_if = core_if->dev_if;
1926         dwc_otg_dev_in_ep_regs_t *in_ep_regs =
1927             dev_if->in_ep_regs[ep->dwc_ep.num];
1928         deptsiz_data_t deptsiz;
1929         desc_sts_data_t desc_sts;
1930         dwc_otg_pcd_request_t *req = 0;
1931         dwc_otg_dma_desc_t *dma_desc;
1932         uint32_t byte_count = 0;
1933         int is_last = 0;
1934         int i;
1935
1936         DWC_DEBUGPL(DBG_PCDV, "%s() %d-%s\n", __func__, ep->dwc_ep.num,
1937                     (ep->dwc_ep.is_in ? "IN" : "OUT"));
1938
1939         /* Get any pending requests */
1940         if (!DWC_CIRCLEQ_EMPTY(&ep->queue)) {
1941                 req = DWC_CIRCLEQ_FIRST(&ep->queue);
1942                 if (!req) {
1943                         DWC_DEBUGPL(DBG_CIL,"complete_ep 0x%p, req = NULL!\n", ep);
1944                         return;
1945                 }
1946         } else {
1947                 DWC_DEBUGPL(DBG_CIL,"complete_ep 0x%p, ep->queue empty!\n", ep);
1948                 return;
1949         }
1950
1951         DWC_DEBUGPL(DBG_PCD, "Requests %d\n", ep->pcd->request_pending);
1952
1953         if (ep->dwc_ep.is_in) {
1954                 deptsiz.d32 = dwc_read_reg32(&in_ep_regs->dieptsiz);
1955
1956                 if (core_if->dma_enable) {
1957                         if (core_if->dma_desc_enable == 0) {
1958                                 if (deptsiz.b.xfersize == 0
1959                                     && deptsiz.b.pktcnt == 0) {
1960                                         byte_count =
1961                                             ep->dwc_ep.xfer_len -
1962                                             ep->dwc_ep.xfer_count;
1963
1964                                         ep->dwc_ep.xfer_buff += byte_count;
1965                                         ep->dwc_ep.dma_addr += byte_count;
1966                                         ep->dwc_ep.xfer_count += byte_count;
1967
1968                                         DWC_DEBUGPL(DBG_PCDV,
1969                                                     "%d-%s len=%d  xfersize=%d pktcnt=%d\n",
1970                                                     ep->dwc_ep.num,
1971                                                     (ep->dwc_ep.
1972                                                      is_in ? "IN" : "OUT"),
1973                                                     ep->dwc_ep.xfer_len,
1974                                                     deptsiz.b.xfersize,
1975                                                     deptsiz.b.pktcnt);
1976
1977                                         if (ep->dwc_ep.xfer_len <
1978                                             ep->dwc_ep.total_len) {
1979                                                 dwc_otg_ep_start_transfer
1980                                                     (core_if, &ep->dwc_ep);
1981                                         } else if (ep->dwc_ep.sent_zlp) {
1982                                                 /*      
1983                                                  * This fragment of code should initiate 0 
1984                                                  * length trasfer in case if it is queued
1985                                                  * a trasfer with size divisible to EPs max 
1986                                                  * packet size and with usb_request zero field 
1987                                                  * is set, which means that after data is transfered, 
1988                                                  * it is also should be transfered 
1989                                                  * a 0 length packet at the end. For Slave and 
1990                                                  * Buffer DMA modes in this case SW has 
1991                                                  * to initiate 2 transfers one with transfer size, 
1992                                                  * and the second with 0 size. For Desriptor 
1993                                                  * DMA mode SW is able to initiate a transfer, 
1994                                                  * which will handle all the packets including 
1995                                                  * the last  0 legth.
1996                                                  */
1997                                                 ep->dwc_ep.sent_zlp = 0;
1998                                                 dwc_otg_ep_start_zl_transfer
1999                                                     (core_if, &ep->dwc_ep);
2000                                         } else {
2001                                                 is_last = 1;
2002                                         }
2003                                 } else {
2004                                         DWC_WARN
2005                                             ("Incomplete transfer (%d - %s [siz=%d pkt=%d])\n",
2006                                              ep->dwc_ep.num,
2007                                              (ep->dwc_ep.is_in ? "IN" : "OUT"),
2008                                              deptsiz.b.xfersize,
2009                                              deptsiz.b.pktcnt);
2010                                 }
2011                         } else {
2012                                 dma_desc = ep->dwc_ep.desc_addr;
2013                                 byte_count = 0;
2014                                 ep->dwc_ep.sent_zlp = 0;
2015
2016 #ifdef DWC_UTE_CFI
2017                                 CFI_INFO("%s: BUFFER_MODE=%d\n", __func__,
2018                                          ep->dwc_ep.buff_mode);
2019                                 if (ep->dwc_ep.buff_mode != BM_STANDARD) {
2020                                         int residue;
2021
2022                                         residue = cfi_calc_desc_residue(ep);
2023                                         if (residue < 0)
2024                                                 return;
2025
2026                                         byte_count = residue;
2027                                 } else {
2028 #endif
2029                                         for (i = 0; i < ep->dwc_ep.desc_cnt;
2030                                              ++i) {
2031                                                 desc_sts = dma_desc->status;
2032                                                 byte_count += desc_sts.b.bytes;
2033                                                 dma_desc++;
2034                                         }
2035 #ifdef DWC_UTE_CFI
2036                                 }
2037 #endif
2038                                 if (byte_count == 0) {
2039                                         ep->dwc_ep.xfer_count =
2040                                             ep->dwc_ep.total_len;
2041                                         is_last = 1;
2042                                 } else {
2043                                         DWC_WARN("Incomplete transfer\n");
2044                                 }
2045                         }
2046                 } else {
2047                         if (deptsiz.b.xfersize == 0 && deptsiz.b.pktcnt == 0) {
2048                                 DWC_DEBUGPL(DBG_PCDV,
2049                                             "%d-%s len=%d  xfersize=%d pktcnt=%d\n",
2050                                             ep->dwc_ep.num,
2051                                             ep->dwc_ep.is_in ? "IN" : "OUT",
2052                                             ep->dwc_ep.xfer_len,
2053                                             deptsiz.b.xfersize,
2054                                             deptsiz.b.pktcnt);
2055
2056                                 /*      Check if the whole transfer was completed,  
2057                                  *      if no, setup transfer for next portion of data
2058                                  */
2059                                 if (ep->dwc_ep.xfer_len < ep->dwc_ep.total_len) {
2060                                         dwc_otg_ep_start_transfer(core_if,
2061                                                                   &ep->dwc_ep);
2062                                 } else if (ep->dwc_ep.sent_zlp) {
2063                                         /*      
2064                                          * This fragment of code should initiate 0 
2065                                          * length trasfer in case if it is queued
2066                                          * a trasfer with size divisible to EPs max 
2067                                          * packet size and with usb_request zero field 
2068                                          * is set, which means that after data is transfered, 
2069                                          * it is also should be transfered 
2070                                          * a 0 length packet at the end. For Slave and 
2071                                          * Buffer DMA modes in this case SW has 
2072                                          * to initiate 2 transfers one with transfer size, 
2073                                          * and the second with 0 size. For Desriptor 
2074                                          * DMA mode SW is able to initiate a transfer, 
2075                                          * which will handle all the packets including 
2076                                          * the last  0 legth.
2077                                          */
2078                                         ep->dwc_ep.sent_zlp = 0;
2079                                         dwc_otg_ep_start_zl_transfer(core_if,
2080                                                                      &ep->
2081                                                                      dwc_ep);
2082                                 } else {
2083                                         is_last = 1;
2084                                 }
2085                         } else {
2086                                 DWC_WARN
2087                                     ("Incomplete transfer (%d-%s [siz=%d pkt=%d])\n",
2088                                      ep->dwc_ep.num,
2089                                      (ep->dwc_ep.is_in ? "IN" : "OUT"),
2090                                      deptsiz.b.xfersize, deptsiz.b.pktcnt);
2091                         }
2092                 }
2093         } else {
2094                 dwc_otg_dev_out_ep_regs_t *out_ep_regs =
2095                     dev_if->out_ep_regs[ep->dwc_ep.num];
2096                 desc_sts.d32 = 0;
2097                 if (core_if->dma_enable) {
2098                         if (core_if->dma_desc_enable) {
2099                                 dma_desc = ep->dwc_ep.desc_addr;
2100                                 byte_count = 0;
2101                                 ep->dwc_ep.sent_zlp = 0;
2102
2103 #ifdef DWC_UTE_CFI
2104                                 CFI_INFO("%s: BUFFER_MODE=%d\n", __func__,
2105                                          ep->dwc_ep.buff_mode);
2106                                 if (ep->dwc_ep.buff_mode != BM_STANDARD) {
2107                                         int residue;
2108                                         residue = cfi_calc_desc_residue(ep);
2109                                         if (residue < 0)
2110                                                 return;
2111                                         byte_count = residue;
2112                                 } else {
2113 #endif
2114
2115                                         for (i = 0; i < ep->dwc_ep.desc_cnt;
2116                                              ++i) {
2117                                                 desc_sts = dma_desc->status;
2118                                                 byte_count += desc_sts.b.bytes;
2119                                                 dma_desc++;
2120                                         }
2121
2122 #ifdef DWC_UTE_CFI
2123                                 }
2124 #endif
2125                                 ep->dwc_ep.xfer_count = ep->dwc_ep.total_len
2126                                     - byte_count +
2127                                     ((4 - (ep->dwc_ep.total_len & 0x3)) & 0x3);
2128                                 is_last = 1;
2129                         } else {
2130                                 deptsiz.d32 = 0;
2131                                 deptsiz.d32 =
2132                                     dwc_read_reg32(&out_ep_regs->doeptsiz);
2133
2134                                 byte_count = (ep->dwc_ep.xfer_len -
2135                                               ep->dwc_ep.xfer_count -
2136                                               deptsiz.b.xfersize);
2137                                 ep->dwc_ep.xfer_buff += byte_count;
2138                                 ep->dwc_ep.dma_addr += byte_count;
2139                                 ep->dwc_ep.xfer_count += byte_count;
2140
2141                                 /*      Check if the whole transfer was completed,  
2142                                  *      if no, setup transfer for next portion of data
2143                                  */
2144                                 if (ep->dwc_ep.xfer_len < ep->dwc_ep.total_len) {
2145                                         dwc_otg_ep_start_transfer(core_if,
2146                                                                   &ep->dwc_ep);
2147                                 } else if (ep->dwc_ep.sent_zlp) {
2148                                         /*      
2149                                          * This fragment of code should initiate 0 
2150                                          * length trasfer in case if it is queued
2151                                          * a trasfer with size divisible to EPs max 
2152                                          * packet size and with usb_request zero field 
2153                                          * is set, which means that after data is transfered, 
2154                                          * it is also should be transfered 
2155                                          * a 0 length packet at the end. For Slave and 
2156                                          * Buffer DMA modes in this case SW has 
2157                                          * to initiate 2 transfers one with transfer size, 
2158                                          * and the second with 0 size. For Desriptor 
2159                                          * DMA mode SW is able to initiate a transfer, 
2160                                          * which will handle all the packets including 
2161                                          * the last  0 legth.
2162                                          */
2163                                         ep->dwc_ep.sent_zlp = 0;
2164                                         dwc_otg_ep_start_zl_transfer(core_if,
2165                                                                      &ep->
2166                                                                      dwc_ep);
2167                                 } else {
2168                                         is_last = 1;
2169                                 }
2170                         }
2171                 } else {
2172                         /*      Check if the whole transfer was completed,  
2173                          *      if no, setup transfer for next portion of data
2174                          */
2175                         if (ep->dwc_ep.xfer_len < ep->dwc_ep.total_len) {
2176                                 dwc_otg_ep_start_transfer(core_if, &ep->dwc_ep);
2177                         } else if (ep->dwc_ep.sent_zlp) {
2178                                 /*      
2179                                  * This fragment of code should initiate 0 
2180                                  * length trasfer in case if it is queued
2181                                  * a trasfer with size divisible to EPs max 
2182                                  * packet size and with usb_request zero field 
2183                                  * is set, which means that after data is transfered, 
2184                                  * it is also should be transfered 
2185                                  * a 0 length packet at the end. For Slave and 
2186                                  * Buffer DMA modes in this case SW has 
2187                                  * to initiate 2 transfers one with transfer size, 
2188                                  * and the second with 0 size. For Desriptor 
2189                                  * DMA mode SW is able to initiate a transfer, 
2190                                  * which will handle all the packets including 
2191                                  * the last  0 legth.
2192                                  */
2193                                 ep->dwc_ep.sent_zlp = 0;
2194                                 dwc_otg_ep_start_zl_transfer(core_if,
2195                                                              &ep->dwc_ep);
2196                         } else {
2197                                 is_last = 1;
2198                         }
2199                 }
2200
2201                 DWC_DEBUGPL(DBG_PCDV,
2202                             "addr %p,    %d-%s len=%d cnt=%d xsize=%d pktcnt=%d\n",
2203                             &out_ep_regs->doeptsiz, ep->dwc_ep.num,
2204                             ep->dwc_ep.is_in ? "IN" : "OUT",
2205                             ep->dwc_ep.xfer_len, ep->dwc_ep.xfer_count,
2206                             deptsiz.b.xfersize, deptsiz.b.pktcnt);
2207         }
2208
2209         /* Complete the request */
2210         if (is_last) {
2211 #ifdef DWC_UTE_CFI
2212                 if (ep->dwc_ep.buff_mode != BM_STANDARD) {
2213                         req->actual = ep->dwc_ep.cfi_req_len - byte_count;
2214                 } else {
2215 #endif
2216                         req->actual = ep->dwc_ep.xfer_count;
2217 #ifdef DWC_UTE_CFI
2218                 }
2219 #endif
2220
2221                 dwc_otg_request_done(ep, req, 0);
2222
2223                 ep->dwc_ep.start_xfer_buff = 0;
2224                 ep->dwc_ep.xfer_buff = 0;
2225                 ep->dwc_ep.xfer_len = 0;
2226
2227                 /* If there is a request in the queue start it. */
2228                 start_next_request(ep);
2229         }
2230 }
2231
2232 #ifdef DWC_EN_ISOC
2233
2234 /**
2235  * This function BNA interrupt for Isochronous EPs
2236  *
2237  */
2238 static void dwc_otg_pcd_handle_iso_bna(dwc_otg_pcd_ep_t * ep)
2239 {
2240         dwc_ep_t *dwc_ep = &ep->dwc_ep;
2241         volatile uint32_t *addr;
2242         depctl_data_t depctl = {.d32 = 0 };
2243         dwc_otg_pcd_t *pcd = ep->pcd;
2244         dwc_otg_dma_desc_t *dma_desc;
2245         int i;
2246
2247         dma_desc =
2248             dwc_ep->iso_desc_addr + dwc_ep->desc_cnt * (dwc_ep->proc_buf_num);
2249
2250         if (dwc_ep->is_in) {
2251                 desc_sts_data_t sts = {.d32 = 0 };
2252                 for (i = 0; i < dwc_ep->desc_cnt; ++i, ++dma_desc) {
2253                         sts.d32 = dma_desc->status.d32;
2254                         sts.b_iso_in.bs = BS_HOST_READY;
2255                         dma_desc->status.d32 = sts.d32;
2256                 }
2257         } else {
2258                 desc_sts_data_t sts = {.d32 = 0 };
2259                 for (i = 0; i < dwc_ep->desc_cnt; ++i, ++dma_desc) {
2260                         sts.d32 = dma_desc->status.d32;
2261                         sts.b_iso_out.bs = BS_HOST_READY;
2262                         dma_desc->status.d32 = sts.d32;
2263                 }
2264         }
2265
2266         if (dwc_ep->is_in == 0) {
2267                 addr =
2268                     &GET_CORE_IF(pcd)->dev_if->out_ep_regs[dwc_ep->num]->
2269                     doepctl;
2270         } else {
2271                 addr =
2272                     &GET_CORE_IF(pcd)->dev_if->in_ep_regs[dwc_ep->num]->diepctl;
2273         }
2274         depctl.b.epena = 1;
2275         dwc_modify_reg32(addr, depctl.d32, depctl.d32);
2276 }
2277
2278 /**
2279  * This function sets latest iso packet information(non-PTI mode)
2280  *
2281  * @param core_if Programming view of DWC_otg controller.
2282  * @param ep The EP to start the transfer on.
2283  *
2284  */
2285 void set_current_pkt_info(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
2286 {
2287         deptsiz_data_t deptsiz = {.d32 = 0 };
2288         dma_addr_t dma_addr;
2289         uint32_t offset;
2290
2291         if (ep->proc_buf_num)
2292                 dma_addr = ep->dma_addr1;
2293         else
2294                 dma_addr = ep->dma_addr0;
2295
2296         if (ep->is_in) {
2297                 deptsiz.d32 =
2298                     dwc_read_reg32(&core_if->dev_if->in_ep_regs[ep->num]->
2299                                    dieptsiz);
2300                 offset = ep->data_per_frame;
2301         } else {
2302                 deptsiz.d32 =
2303                     dwc_read_reg32(&core_if->dev_if->out_ep_regs[ep->num]->
2304                                    doeptsiz);
2305                 offset =
2306                     ep->data_per_frame +
2307                     (0x4 & (0x4 - (ep->data_per_frame & 0x3)));
2308         }
2309
2310         if (!deptsiz.b.xfersize) {
2311                 ep->pkt_info[ep->cur_pkt].length = ep->data_per_frame;
2312                 ep->pkt_info[ep->cur_pkt].offset =
2313                     ep->cur_pkt_dma_addr - dma_addr;
2314                 ep->pkt_info[ep->cur_pkt].status = 0;
2315         } else {
2316                 ep->pkt_info[ep->cur_pkt].length = ep->data_per_frame;
2317                 ep->pkt_info[ep->cur_pkt].offset =
2318                     ep->cur_pkt_dma_addr - dma_addr;
2319                 ep->pkt_info[ep->cur_pkt].status = -DWC_E_NO_DATA;
2320         }
2321         ep->cur_pkt_addr += offset;
2322         ep->cur_pkt_dma_addr += offset;
2323         ep->cur_pkt++;
2324 }
2325
2326 /**
2327  * This function sets latest iso packet information(DDMA mode)
2328  *
2329  * @param core_if Programming view of DWC_otg controller.
2330  * @param dwc_ep The EP to start the transfer on.
2331  *
2332  */
2333 static void set_ddma_iso_pkts_info(dwc_otg_core_if_t * core_if,
2334                                    dwc_ep_t * dwc_ep)
2335 {
2336         dwc_otg_dma_desc_t *dma_desc;
2337         desc_sts_data_t sts = {.d32 = 0 };
2338         iso_pkt_info_t *iso_packet;
2339         uint32_t data_per_desc;
2340         uint32_t offset;
2341         int i, j;
2342
2343         iso_packet = dwc_ep->pkt_info;
2344
2345         /** Reinit closed DMA Descriptors*/
2346         /** ISO OUT EP */
2347         if (dwc_ep->is_in == 0) {
2348                 dma_desc =
2349                     dwc_ep->iso_desc_addr +
2350                     dwc_ep->desc_cnt * dwc_ep->proc_buf_num;
2351                 offset = 0;
2352
2353                 for (i = 0; i < dwc_ep->desc_cnt - dwc_ep->pkt_per_frm;
2354                      i += dwc_ep->pkt_per_frm) {
2355                         for (j = 0; j < dwc_ep->pkt_per_frm; ++j) {
2356                                 data_per_desc =
2357                                     ((j + 1) * dwc_ep->maxpacket >
2358                                      dwc_ep->data_per_frame) ? dwc_ep->
2359                                     data_per_frame -
2360                                     j * dwc_ep->maxpacket : dwc_ep->maxpacket;
2361                                 data_per_desc +=
2362                                     (data_per_desc % 4) ? (4 -
2363                                                            data_per_desc %
2364                                                            4) : 0;
2365
2366                                 sts.d32 = dma_desc->status.d32;
2367
2368                                 /* Write status in iso_packet_decsriptor  */
2369                                 iso_packet->status =
2370                                     sts.b_iso_out.rxsts +
2371                                     (sts.b_iso_out.bs ^ BS_DMA_DONE);
2372                                 if (iso_packet->status) {
2373                                         iso_packet->status = -DWC_E_NO_DATA;
2374                                 }
2375
2376                                 /* Received data length */
2377                                 if (!sts.b_iso_out.rxbytes) {
2378                                         iso_packet->length =
2379                                             data_per_desc -
2380                                             sts.b_iso_out.rxbytes;
2381                                 } else {
2382                                         iso_packet->length =
2383                                             data_per_desc -
2384                                             sts.b_iso_out.rxbytes + (4 -
2385                                                                      dwc_ep->
2386                                                                      data_per_frame
2387                                                                      % 4);
2388                                 }
2389
2390                                 iso_packet->offset = offset;
2391
2392                                 offset += data_per_desc;
2393                                 dma_desc++;
2394                                 iso_packet++;
2395                         }
2396                 }
2397
2398                 for (j = 0; j < dwc_ep->pkt_per_frm - 1; ++j) {
2399                         data_per_desc =
2400                             ((j + 1) * dwc_ep->maxpacket >
2401                              dwc_ep->data_per_frame) ? dwc_ep->data_per_frame -
2402                             j * dwc_ep->maxpacket : dwc_ep->maxpacket;
2403                         data_per_desc +=
2404                             (data_per_desc % 4) ? (4 - data_per_desc % 4) : 0;
2405
2406                         sts.d32 = dma_desc->status.d32;
2407
2408                         /* Write status in iso_packet_decsriptor  */
2409                         iso_packet->status =
2410                             sts.b_iso_out.rxsts +
2411                             (sts.b_iso_out.bs ^ BS_DMA_DONE);
2412                         if (iso_packet->status) {
2413                                 iso_packet->status = -DWC_E_NO_DATA;
2414                         }
2415
2416                         /* Received data length */
2417                         iso_packet->length =
2418                             dwc_ep->data_per_frame - sts.b_iso_out.rxbytes;
2419
2420                         iso_packet->offset = offset;
2421
2422                         offset += data_per_desc;
2423                         iso_packet++;
2424                         dma_desc++;
2425                 }
2426
2427                 sts.d32 = dma_desc->status.d32;
2428
2429                 /* Write status in iso_packet_decsriptor  */
2430                 iso_packet->status =
2431                     sts.b_iso_out.rxsts + (sts.b_iso_out.bs ^ BS_DMA_DONE);
2432                 if (iso_packet->status) {
2433                         iso_packet->status = -DWC_E_NO_DATA;
2434                 }
2435                 /* Received data length */
2436                 if (!sts.b_iso_out.rxbytes) {
2437                         iso_packet->length =
2438                             dwc_ep->data_per_frame - sts.b_iso_out.rxbytes;
2439                 } else {
2440                         iso_packet->length =
2441                             dwc_ep->data_per_frame - sts.b_iso_out.rxbytes +
2442                             (4 - dwc_ep->data_per_frame % 4);
2443                 }
2444
2445                 iso_packet->offset = offset;
2446         } else {
2447 /** ISO IN EP */
2448
2449                 dma_desc =
2450                     dwc_ep->iso_desc_addr +
2451                     dwc_ep->desc_cnt * dwc_ep->proc_buf_num;
2452
2453                 for (i = 0; i < dwc_ep->desc_cnt - 1; i++) {
2454                         sts.d32 = dma_desc->status.d32;
2455
2456                         /* Write status in iso packet descriptor */
2457                         iso_packet->status =
2458                             sts.b_iso_in.txsts +
2459                             (sts.b_iso_in.bs ^ BS_DMA_DONE);
2460                         if (iso_packet->status != 0) {
2461                                 iso_packet->status = -DWC_E_NO_DATA;
2462
2463                         }
2464                         /* Bytes has been transfered */
2465                         iso_packet->length =
2466                             dwc_ep->data_per_frame - sts.b_iso_in.txbytes;
2467
2468                         dma_desc++;
2469                         iso_packet++;
2470                 }
2471
2472                 sts.d32 = dma_desc->status.d32;
2473                 while (sts.b_iso_in.bs == BS_DMA_BUSY) {
2474                         sts.d32 = dma_desc->status.d32;
2475                 }
2476
2477                 /* Write status in iso packet descriptor ??? do be done with ERROR codes */
2478                 iso_packet->status =
2479                     sts.b_iso_in.txsts + (sts.b_iso_in.bs ^ BS_DMA_DONE);
2480                 if (iso_packet->status != 0) {
2481                         iso_packet->status = -DWC_E_NO_DATA;
2482                 }
2483
2484                 /* Bytes has been transfered */
2485                 iso_packet->length =
2486                     dwc_ep->data_per_frame - sts.b_iso_in.txbytes;
2487         }
2488 }
2489
2490 /**
2491  * This function reinitialize DMA Descriptors for Isochronous transfer
2492  *
2493  * @param core_if Programming view of DWC_otg controller.
2494  * @param dwc_ep The EP to start the transfer on.
2495  *
2496  */
2497 static void reinit_ddma_iso_xfer(dwc_otg_core_if_t * core_if, dwc_ep_t * dwc_ep)
2498 {
2499         int i, j;
2500         dwc_otg_dma_desc_t *dma_desc;
2501         dma_addr_t dma_ad;
2502         volatile uint32_t *addr;
2503         desc_sts_data_t sts = {.d32 = 0 };
2504         uint32_t data_per_desc;
2505
2506         if (dwc_ep->is_in == 0) {
2507                 addr = &core_if->dev_if->out_ep_regs[dwc_ep->num]->doepctl;
2508         } else {
2509                 addr = &core_if->dev_if->in_ep_regs[dwc_ep->num]->diepctl;
2510         }
2511
2512         if (dwc_ep->proc_buf_num == 0) {
2513                 /** Buffer 0 descriptors setup */
2514                 dma_ad = dwc_ep->dma_addr0;
2515         } else {
2516                 /** Buffer 1 descriptors setup */
2517                 dma_ad = dwc_ep->dma_addr1;
2518         }
2519
2520         /** Reinit closed DMA Descriptors*/
2521         /** ISO OUT EP */
2522         if (dwc_ep->is_in == 0) {
2523                 dma_desc =
2524                     dwc_ep->iso_desc_addr +
2525                     dwc_ep->desc_cnt * dwc_ep->proc_buf_num;
2526
2527                 sts.b_iso_out.bs = BS_HOST_READY;
2528                 sts.b_iso_out.rxsts = 0;
2529                 sts.b_iso_out.l = 0;
2530                 sts.b_iso_out.sp = 0;
2531                 sts.b_iso_out.ioc = 0;
2532                 sts.b_iso_out.pid = 0;
2533                 sts.b_iso_out.framenum = 0;
2534
2535                 for (i = 0; i < dwc_ep->desc_cnt - dwc_ep->pkt_per_frm;
2536                      i += dwc_ep->pkt_per_frm) {
2537                         for (j = 0; j < dwc_ep->pkt_per_frm; ++j) {
2538                                 data_per_desc =
2539                                     ((j + 1) * dwc_ep->maxpacket >
2540                                      dwc_ep->data_per_frame) ? dwc_ep->
2541                                     data_per_frame -
2542                                     j * dwc_ep->maxpacket : dwc_ep->maxpacket;
2543                                 data_per_desc +=
2544                                     (data_per_desc % 4) ? (4 -
2545                                                            data_per_desc %
2546                                                            4) : 0;
2547                                 sts.b_iso_out.rxbytes = data_per_desc;
2548                                 dma_desc->buf = dma_ad;
2549                                 dma_desc->status.d32 = sts.d32;
2550
2551                                 dma_ad += data_per_desc;
2552                                 dma_desc++;
2553                         }
2554                 }
2555
2556                 for (j = 0; j < dwc_ep->pkt_per_frm - 1; ++j) {
2557
2558                         data_per_desc =
2559                             ((j + 1) * dwc_ep->maxpacket >
2560                              dwc_ep->data_per_frame) ? dwc_ep->data_per_frame -
2561                             j * dwc_ep->maxpacket : dwc_ep->maxpacket;
2562                         data_per_desc +=
2563                             (data_per_desc % 4) ? (4 - data_per_desc % 4) : 0;
2564                         sts.b_iso_out.rxbytes = data_per_desc;
2565
2566                         dma_desc->buf = dma_ad;
2567                         dma_desc->status.d32 = sts.d32;
2568
2569                         dma_desc++;
2570                         dma_ad += data_per_desc;
2571                 }
2572
2573                 sts.b_iso_out.ioc = 1;
2574                 sts.b_iso_out.l = dwc_ep->proc_buf_num;
2575
2576                 data_per_desc =
2577                     ((j + 1) * dwc_ep->maxpacket >
2578                      dwc_ep->data_per_frame) ? dwc_ep->data_per_frame -
2579                     j * dwc_ep->maxpacket : dwc_ep->maxpacket;
2580                 data_per_desc +=
2581                     (data_per_desc % 4) ? (4 - data_per_desc % 4) : 0;
2582                 sts.b_iso_out.rxbytes = data_per_desc;
2583
2584                 dma_desc->buf = dma_ad;
2585                 dma_desc->status.d32 = sts.d32;
2586         } else {
2587 /** ISO IN EP */
2588
2589                 dma_desc =
2590                     dwc_ep->iso_desc_addr +
2591                     dwc_ep->desc_cnt * dwc_ep->proc_buf_num;
2592
2593                 sts.b_iso_in.bs = BS_HOST_READY;
2594                 sts.b_iso_in.txsts = 0;
2595                 sts.b_iso_in.sp = 0;
2596                 sts.b_iso_in.ioc = 0;
2597                 sts.b_iso_in.pid = dwc_ep->pkt_per_frm;
2598                 sts.b_iso_in.framenum = dwc_ep->next_frame;
2599                 sts.b_iso_in.txbytes = dwc_ep->data_per_frame;
2600                 sts.b_iso_in.l = 0;
2601
2602                 for (i = 0; i < dwc_ep->desc_cnt - 1; i++) {
2603                         dma_desc->buf = dma_ad;
2604                         dma_desc->status.d32 = sts.d32;
2605
2606                         sts.b_iso_in.framenum += dwc_ep->bInterval;
2607                         dma_ad += dwc_ep->data_per_frame;
2608                         dma_desc++;
2609                 }
2610
2611                 sts.b_iso_in.ioc = 1;
2612                 sts.b_iso_in.l = dwc_ep->proc_buf_num;
2613
2614                 dma_desc->buf = dma_ad;
2615                 dma_desc->status.d32 = sts.d32;
2616
2617                 dwc_ep->next_frame =
2618                     sts.b_iso_in.framenum + dwc_ep->bInterval * 1;
2619         }
2620         dwc_ep->proc_buf_num = (dwc_ep->proc_buf_num ^ 1) & 0x1;
2621 }
2622
2623 /**
2624  * This function is to handle Iso EP transfer complete interrupt
2625  * in case Iso out packet was dropped
2626  *
2627  * @param core_if Programming view of DWC_otg controller.
2628  * @param dwc_ep The EP for wihich transfer complete was asserted
2629  *
2630  */
2631 static uint32_t handle_iso_out_pkt_dropped(dwc_otg_core_if_t * core_if,
2632                                            dwc_ep_t * dwc_ep)
2633 {
2634         uint32_t dma_addr;
2635         uint32_t drp_pkt;
2636         uint32_t drp_pkt_cnt;
2637         deptsiz_data_t deptsiz = {.d32 = 0 };
2638         depctl_data_t depctl = {.d32 = 0 };
2639         int i;
2640
2641         deptsiz.d32 =
2642             dwc_read_reg32(&core_if->dev_if->out_ep_regs[dwc_ep->num]->
2643                            doeptsiz);
2644
2645         drp_pkt = dwc_ep->pkt_cnt - deptsiz.b.pktcnt;
2646         drp_pkt_cnt = dwc_ep->pkt_per_frm - (drp_pkt % dwc_ep->pkt_per_frm);
2647
2648         /* Setting dropped packets status */
2649         for (i = 0; i < drp_pkt_cnt; ++i) {
2650                 dwc_ep->pkt_info[drp_pkt].status = -DWC_E_NO_DATA;
2651                 drp_pkt++;
2652                 deptsiz.b.pktcnt--;
2653         }
2654
2655         if (deptsiz.b.pktcnt > 0) {
2656                 deptsiz.b.xfersize =
2657                     dwc_ep->xfer_len - (dwc_ep->pkt_cnt -
2658                                         deptsiz.b.pktcnt) * dwc_ep->maxpacket;
2659         } else {
2660                 deptsiz.b.xfersize = 0;
2661                 deptsiz.b.pktcnt = 0;
2662         }
2663
2664         dwc_write_reg32(&core_if->dev_if->out_ep_regs[dwc_ep->num]->doeptsiz,
2665                         deptsiz.d32);
2666
2667         if (deptsiz.b.pktcnt > 0) {
2668                 if (dwc_ep->proc_buf_num) {
2669                         dma_addr =
2670                             dwc_ep->dma_addr1 + dwc_ep->xfer_len -
2671                             deptsiz.b.xfersize;
2672                 } else {
2673                         dma_addr =
2674                             dwc_ep->dma_addr0 + dwc_ep->xfer_len -
2675                             deptsiz.b.xfersize;;
2676                 }
2677
2678                 dwc_write_reg32(&core_if->dev_if->out_ep_regs[dwc_ep->num]->
2679                                 doepdma, dma_addr);
2680
2681                 /** Re-enable endpoint, clear nak  */
2682                 depctl.d32 = 0;
2683                 depctl.b.epena = 1;
2684                 depctl.b.cnak = 1;
2685
2686                 dwc_modify_reg32(&core_if->dev_if->out_ep_regs[dwc_ep->num]->
2687                                  doepctl, depctl.d32, depctl.d32);
2688                 return 0;
2689         } else {
2690                 return 1;
2691         }
2692 }
2693
2694 /**
2695  * This function sets iso packets information(PTI mode)
2696  *
2697  * @param core_if Programming view of DWC_otg controller.
2698  * @param ep The EP to start the transfer on.
2699  *
2700  */
2701 static uint32_t set_iso_pkts_info(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
2702 {
2703         int i, j;
2704         dma_addr_t dma_ad;
2705         iso_pkt_info_t *packet_info = ep->pkt_info;
2706         uint32_t offset;
2707         uint32_t frame_data;
2708         deptsiz_data_t deptsiz;
2709
2710         if (ep->proc_buf_num == 0) {
2711                 /** Buffer 0 descriptors setup */
2712                 dma_ad = ep->dma_addr0;
2713         } else {
2714                 /** Buffer 1 descriptors setup */
2715                 dma_ad = ep->dma_addr1;
2716         }
2717
2718         if (ep->is_in) {
2719                 deptsiz.d32 =
2720                     dwc_read_reg32(&core_if->dev_if->in_ep_regs[ep->num]->
2721                                    dieptsiz);
2722         } else {
2723                 deptsiz.d32 =
2724                     dwc_read_reg32(&core_if->dev_if->out_ep_regs[ep->num]->
2725                                    doeptsiz);
2726         }
2727
2728         if (!deptsiz.b.xfersize) {
2729                 offset = 0;
2730                 for (i = 0; i < ep->pkt_cnt; i += ep->pkt_per_frm) {
2731                         frame_data = ep->data_per_frame;
2732                         for (j = 0; j < ep->pkt_per_frm; ++j) {
2733
2734                                 /* Packet status - is not set as initially 
2735                                  * it is set to 0 and if packet was sent 
2736                                  successfully, status field will remain 0*/
2737
2738                                 /* Bytes has been transfered */
2739                                 packet_info->length =
2740                                     (ep->maxpacket <
2741                                      frame_data) ? ep->maxpacket : frame_data;
2742
2743                                 /* Received packet offset */
2744                                 packet_info->offset = offset;
2745                                 offset += packet_info->length;
2746                                 frame_data -= packet_info->length;
2747
2748                                 packet_info++;
2749                         }
2750                 }
2751                 return 1;
2752         } else {
2753                 /* This is a workaround for in case of Transfer Complete with 
2754                  * PktDrpSts interrupts merging - in this case Transfer complete 
2755                  * interrupt for Isoc Out Endpoint is asserted without PktDrpSts 
2756                  * set and with DOEPTSIZ register non zero. Investigations showed,
2757                  * that this happens when Out packet is dropped, but because of 
2758                  * interrupts merging during first interrupt handling PktDrpSts
2759                  * bit is cleared and for next merged interrupts it is not reset.
2760                  * In this case SW hadles the interrupt as if PktDrpSts bit is set.
2761                  */
2762                 if (ep->is_in) {
2763                         return 1;
2764                 } else {
2765                         return handle_iso_out_pkt_dropped(core_if, ep);
2766                 }
2767         }
2768 }
2769
2770 /**
2771  * This function is to handle Iso EP transfer complete interrupt
2772  *
2773  * @param pcd The PCD
2774  * @param ep The EP for which transfer complete was asserted
2775  *
2776  */
2777 static void complete_iso_ep(dwc_otg_pcd_t * pcd, dwc_otg_pcd_ep_t * ep)
2778 {
2779         dwc_otg_core_if_t *core_if = GET_CORE_IF(ep->pcd);
2780         dwc_ep_t *dwc_ep = &ep->dwc_ep;
2781         uint8_t is_last = 0;
2782
2783         if (core_if->dma_enable) {
2784                 if (core_if->dma_desc_enable) {
2785                         set_ddma_iso_pkts_info(core_if, dwc_ep);
2786                         reinit_ddma_iso_xfer(core_if, dwc_ep);
2787                         is_last = 1;
2788                 } else {
2789                         if (core_if->pti_enh_enable) {
2790                                 if (set_iso_pkts_info(core_if, dwc_ep)) {
2791                                         dwc_ep->proc_buf_num =
2792                                             (dwc_ep->proc_buf_num ^ 1) & 0x1;
2793                                         dwc_otg_iso_ep_start_buf_transfer
2794                                             (core_if, dwc_ep);
2795                                         is_last = 1;
2796                                 }
2797                         } else {
2798                                 set_current_pkt_info(core_if, dwc_ep);
2799                                 if (dwc_ep->cur_pkt >= dwc_ep->pkt_cnt) {
2800                                         is_last = 1;
2801                                         dwc_ep->cur_pkt = 0;
2802                                         dwc_ep->proc_buf_num =
2803                                             (dwc_ep->proc_buf_num ^ 1) & 0x1;
2804                                         if (dwc_ep->proc_buf_num) {
2805                                                 dwc_ep->cur_pkt_addr =
2806                                                     dwc_ep->xfer_buff1;
2807                                                 dwc_ep->cur_pkt_dma_addr =
2808                                                     dwc_ep->dma_addr1;
2809                                         } else {
2810                                                 dwc_ep->cur_pkt_addr =
2811                                                     dwc_ep->xfer_buff0;
2812                                                 dwc_ep->cur_pkt_dma_addr =
2813                                                     dwc_ep->dma_addr0;
2814                                         }
2815
2816                                 }
2817                                 dwc_otg_iso_ep_start_frm_transfer(core_if,
2818                                                                   dwc_ep);
2819                         }
2820                 }
2821         } else {
2822                 set_current_pkt_info(core_if, dwc_ep);
2823                 if (dwc_ep->cur_pkt >= dwc_ep->pkt_cnt) {
2824                         is_last = 1;
2825                         dwc_ep->cur_pkt = 0;
2826                         dwc_ep->proc_buf_num = (dwc_ep->proc_buf_num ^ 1) & 0x1;
2827                         if (dwc_ep->proc_buf_num) {
2828                                 dwc_ep->cur_pkt_addr = dwc_ep->xfer_buff1;
2829                                 dwc_ep->cur_pkt_dma_addr = dwc_ep->dma_addr1;
2830                         } else {
2831                                 dwc_ep->cur_pkt_addr = dwc_ep->xfer_buff0;
2832                                 dwc_ep->cur_pkt_dma_addr = dwc_ep->dma_addr0;
2833                         }
2834
2835                 }
2836                 dwc_otg_iso_ep_start_frm_transfer(core_if, dwc_ep);
2837         }
2838         if (is_last)
2839                 dwc_otg_iso_buffer_done(pcd, ep, ep->iso_req_handle);
2840 }
2841 #endif                          /* DWC_EN_ISOC */
2842
2843 /**
2844  * This function handles EP0 Control transfers.
2845  *
2846  * The state of the control tranfers are tracked in
2847  * <code>ep0state</code>.
2848  */
2849 static void handle_ep0(dwc_otg_pcd_t * pcd)
2850 {
2851         dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
2852         dwc_otg_pcd_ep_t *ep0 = &pcd->ep0;
2853         desc_sts_data_t desc_sts;
2854         deptsiz0_data_t deptsiz;
2855         uint32_t byte_count;
2856
2857 #ifdef DEBUG_EP0
2858         DWC_DEBUGPL(DBG_PCDV, "%s()\n", __func__);
2859         print_ep0_state(pcd);
2860 #endif
2861
2862 //      DWC_DEBUGPL(DBG_CIL,"HANDLE EP0\n");
2863
2864         switch (pcd->ep0state) {
2865         case EP0_DISCONNECT:
2866                 break;
2867
2868         case EP0_IDLE:
2869                 pcd->request_config = 0;
2870
2871                 pcd_setup(pcd);
2872                 break;
2873
2874         case EP0_IN_DATA_PHASE:
2875 #ifdef DEBUG_EP0
2876                 DWC_DEBUGPL(DBG_PCD, "DATA_IN EP%d-%s: type=%d, mps=%d\n",
2877                             ep0->dwc_ep.num, (ep0->dwc_ep.is_in ? "IN" : "OUT"),
2878                             ep0->dwc_ep.type, ep0->dwc_ep.maxpacket);
2879 #endif
2880
2881                 if (core_if->dma_enable != 0) {
2882                         /*
2883                          * For EP0 we can only program 1 packet at a time so we
2884                          * need to do the make calculations after each complete.
2885                          * Call write_packet to make the calculations, as in
2886                          * slave mode, and use those values to determine if we
2887                          * can complete.
2888                          */
2889                         if (core_if->dma_desc_enable == 0) {
2890                                 deptsiz.d32 =
2891                                     dwc_read_reg32(&core_if->dev_if->
2892                                                    in_ep_regs[0]->dieptsiz);
2893                                 byte_count =
2894                                     ep0->dwc_ep.xfer_len - deptsiz.b.xfersize;
2895                         } else {
2896                                 desc_sts =
2897                                     core_if->dev_if->in_desc_addr->status;
2898                                 byte_count =
2899                                     ep0->dwc_ep.xfer_len - desc_sts.b.bytes;
2900                         }
2901                         ep0->dwc_ep.xfer_count += byte_count;
2902                         ep0->dwc_ep.xfer_buff += byte_count;
2903                         ep0->dwc_ep.dma_addr += byte_count;
2904                 }
2905                 if (ep0->dwc_ep.xfer_count < ep0->dwc_ep.total_len) {
2906                         dwc_otg_ep0_continue_transfer(GET_CORE_IF(pcd),
2907                                                       &ep0->dwc_ep);
2908                         DWC_DEBUGPL(DBG_PCD, "CONTINUE TRANSFER\n");
2909                 } else if (ep0->dwc_ep.sent_zlp) {
2910                         dwc_otg_ep0_continue_transfer(GET_CORE_IF(pcd),
2911                                                       &ep0->dwc_ep);
2912                         ep0->dwc_ep.sent_zlp = 0;
2913                         DWC_DEBUGPL(DBG_PCD, "CONTINUE TRANSFER\n");
2914                 } else {
2915                         ep0_complete_request(ep0);
2916                         DWC_DEBUGPL(DBG_PCD, "COMPLETE TRANSFER\n");
2917                 }
2918                 break;
2919         case EP0_OUT_DATA_PHASE:
2920 #ifdef DEBUG_EP0
2921                 DWC_DEBUGPL(DBG_PCD, "DATA_OUT EP%d-%s: type=%d, mps=%d\n",
2922                             ep0->dwc_ep.num, (ep0->dwc_ep.is_in ? "IN" : "OUT"),
2923                             ep0->dwc_ep.type, ep0->dwc_ep.maxpacket);
2924 #endif
2925                 if (core_if->dma_enable != 0) {
2926                         if (core_if->dma_desc_enable == 0) {
2927                                 deptsiz.d32 =
2928                                     dwc_read_reg32(&core_if->dev_if->
2929                                                    out_ep_regs[0]->doeptsiz);
2930                                 byte_count =
2931                                     ep0->dwc_ep.maxpacket - deptsiz.b.xfersize;
2932                         } else {
2933                                 desc_sts =
2934                                     core_if->dev_if->out_desc_addr->status;
2935                                 byte_count =
2936                                     ep0->dwc_ep.maxpacket - desc_sts.b.bytes;
2937                         }
2938                         ep0->dwc_ep.xfer_count += byte_count;
2939                         ep0->dwc_ep.xfer_buff += byte_count;
2940                         ep0->dwc_ep.dma_addr += byte_count;
2941                 }
2942                 if (ep0->dwc_ep.xfer_count < ep0->dwc_ep.total_len) {
2943                         dwc_otg_ep0_continue_transfer(GET_CORE_IF(pcd),
2944                                                       &ep0->dwc_ep);
2945                         DWC_DEBUGPL(DBG_PCD, "CONTINUE TRANSFER\n");
2946                 } else if (ep0->dwc_ep.sent_zlp) {
2947                         dwc_otg_ep0_continue_transfer(GET_CORE_IF(pcd),
2948                                                       &ep0->dwc_ep);
2949                         ep0->dwc_ep.sent_zlp = 0;
2950                         DWC_DEBUGPL(DBG_PCD, "CONTINUE TRANSFER\n");
2951                 } else {
2952                         ep0_complete_request(ep0);
2953                         DWC_DEBUGPL(DBG_PCD, "COMPLETE TRANSFER\n");
2954                 }
2955                 break;
2956
2957         case EP0_IN_STATUS_PHASE:
2958         case EP0_OUT_STATUS_PHASE:
2959                 DWC_DEBUGPL(DBG_PCD, "CASE: EP0_STATUS\n");
2960                 ep0_complete_request(ep0);
2961                 pcd->ep0state = EP0_IDLE;
2962                 ep0->stopped = 1;
2963                 ep0->dwc_ep.is_in = 0;  /* OUT for next SETUP */
2964
2965                 /* Prepare for more SETUP Packets */
2966                 if (core_if->dma_enable) {
2967                         ep0_out_start(core_if, pcd);
2968                 }
2969                 break;
2970
2971         case EP0_STALL:
2972                 DWC_ERROR("EP0 STALLed, should not get here pcd_setup()\n");
2973                 break;
2974         }
2975 #ifdef DEBUG_EP0
2976         print_ep0_state(pcd);
2977 #endif
2978 }
2979
2980 /**
2981  * Restart transfer
2982  */
2983 static void restart_transfer(dwc_otg_pcd_t * pcd, const uint32_t epnum)
2984 {
2985         dwc_otg_core_if_t *core_if;
2986         dwc_otg_dev_if_t *dev_if;
2987         deptsiz_data_t dieptsiz = {.d32 = 0 };
2988         dwc_otg_pcd_ep_t *ep;
2989
2990         ep = get_in_ep(pcd, epnum);
2991
2992 #ifdef DWC_EN_ISOC
2993         if (ep->dwc_ep.type == DWC_OTG_EP_TYPE_ISOC) {
2994                 return;
2995         }
2996 #endif                          /* DWC_EN_ISOC  */
2997
2998         core_if = GET_CORE_IF(pcd);
2999         dev_if = core_if->dev_if;
3000
3001         dieptsiz.d32 = dwc_read_reg32(&dev_if->in_ep_regs[epnum]->dieptsiz);
3002
3003         DWC_DEBUGPL(DBG_PCD, "xfer_buff=%p xfer_count=%0x xfer_len=%0x"
3004                     " stopped=%d\n", ep->dwc_ep.xfer_buff,
3005                     ep->dwc_ep.xfer_count, ep->dwc_ep.xfer_len, ep->stopped);
3006         /*
3007          * If xfersize is 0 and pktcnt in not 0, resend the last packet.
3008          */
3009         if (dieptsiz.b.pktcnt && dieptsiz.b.xfersize == 0 &&
3010             ep->dwc_ep.start_xfer_buff != 0) {
3011                 if (ep->dwc_ep.total_len <= ep->dwc_ep.maxpacket) {
3012                         ep->dwc_ep.xfer_count = 0;
3013                         ep->dwc_ep.xfer_buff = ep->dwc_ep.start_xfer_buff;
3014                         ep->dwc_ep.xfer_len = ep->dwc_ep.xfer_count;
3015                 } else {
3016                         ep->dwc_ep.xfer_count -= ep->dwc_ep.maxpacket;
3017                         /* convert packet size to dwords. */
3018                         ep->dwc_ep.xfer_buff -= ep->dwc_ep.maxpacket;
3019                         ep->dwc_ep.xfer_len = ep->dwc_ep.xfer_count;
3020                 }
3021                 ep->stopped = 0;
3022                 DWC_DEBUGPL(DBG_PCD, "xfer_buff=%p xfer_count=%0x "
3023                             "xfer_len=%0x stopped=%d\n",
3024                             ep->dwc_ep.xfer_buff,
3025                             ep->dwc_ep.xfer_count, ep->dwc_ep.xfer_len,
3026                             ep->stopped);
3027                 if (epnum == 0) {
3028                         dwc_otg_ep0_start_transfer(core_if, &ep->dwc_ep);
3029                 } else {
3030                         dwc_otg_ep_start_transfer(core_if, &ep->dwc_ep);
3031                 }
3032         }
3033 }
3034
3035 /**
3036  * handle the IN EP disable interrupt.
3037  */
3038 static inline void handle_in_ep_disable_intr(dwc_otg_pcd_t * pcd,
3039                                              const uint32_t epnum)
3040 {
3041         dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
3042         dwc_otg_dev_if_t *dev_if = core_if->dev_if;
3043         deptsiz_data_t dieptsiz = {.d32 = 0 };
3044         dctl_data_t dctl = {.d32 = 0 };
3045         dwc_otg_pcd_ep_t *ep;
3046         dwc_ep_t *dwc_ep;
3047
3048         ep = get_in_ep(pcd, epnum);
3049         dwc_ep = &ep->dwc_ep;
3050
3051         if (dwc_ep->type == DWC_OTG_EP_TYPE_ISOC) {
3052                 dwc_otg_flush_tx_fifo(core_if, dwc_ep->tx_fifo_num);
3053                 return;
3054         }
3055
3056         DWC_DEBUGPL(DBG_PCD, "diepctl%d=%0x\n", epnum,
3057                     dwc_read_reg32(&dev_if->in_ep_regs[epnum]->diepctl));
3058         dieptsiz.d32 = dwc_read_reg32(&dev_if->in_ep_regs[epnum]->dieptsiz);
3059
3060         DWC_DEBUGPL(DBG_ANY, "pktcnt=%d size=%d\n",
3061                     dieptsiz.b.pktcnt, dieptsiz.b.xfersize);
3062
3063         if (ep->stopped) {
3064                 /* Flush the Tx FIFO */
3065                 dwc_otg_flush_tx_fifo(core_if, dwc_ep->tx_fifo_num);
3066                 /* Clear the Global IN NP NAK */
3067                 dctl.d32 = 0;
3068                 dctl.b.cgnpinnak = 1;
3069                 dwc_modify_reg32(&dev_if->dev_global_regs->dctl, dctl.d32, 0);
3070                 /* Restart the transaction */
3071                 if (dieptsiz.b.pktcnt != 0 || dieptsiz.b.xfersize != 0) {
3072                         restart_transfer(pcd, epnum);
3073                 }
3074         } else {
3075                 /* Restart the transaction */
3076                 if (dieptsiz.b.pktcnt != 0 || dieptsiz.b.xfersize != 0) {
3077                         restart_transfer(pcd, epnum);
3078                 }
3079                 DWC_DEBUGPL(DBG_ANY, "STOPPED!!!\n");
3080         }
3081 }
3082
3083 /**
3084  * Handler for the IN EP timeout handshake interrupt.
3085  */
3086 static inline void handle_in_ep_timeout_intr(dwc_otg_pcd_t * pcd,
3087                                              const uint32_t epnum)
3088 {
3089         dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
3090         dwc_otg_dev_if_t *dev_if = core_if->dev_if;
3091
3092 #ifdef DEBUG
3093         deptsiz_data_t dieptsiz = {.d32 = 0 };
3094         uint32_t num = 0;
3095 #endif
3096         dctl_data_t dctl = {.d32 = 0 };
3097         dwc_otg_pcd_ep_t *ep;
3098
3099         gintmsk_data_t intr_mask = {.d32 = 0 };
3100
3101         ep = get_in_ep(pcd, epnum);
3102
3103         /* Disable the NP Tx Fifo Empty Interrrupt */
3104         if (!core_if->dma_enable) {
3105                 intr_mask.b.nptxfempty = 1;
3106                 dwc_modify_reg32(&core_if->core_global_regs->gintmsk,
3107                                  intr_mask.d32, 0);
3108         }
3109         /** @todo NGS Check EP type.
3110          * Implement for Periodic EPs */
3111         /*
3112          * Non-periodic EP
3113          */
3114         /* Enable the Global IN NAK Effective Interrupt */
3115         intr_mask.b.ginnakeff = 1;
3116         dwc_modify_reg32(&core_if->core_global_regs->gintmsk, 0, intr_mask.d32);
3117
3118         /* Set Global IN NAK */
3119         dctl.b.sgnpinnak = 1;
3120         dwc_modify_reg32(&dev_if->dev_global_regs->dctl, dctl.d32, dctl.d32);
3121
3122         ep->stopped = 1;
3123
3124 #ifdef DEBUG
3125         dieptsiz.d32 = dwc_read_reg32(&dev_if->in_ep_regs[num]->dieptsiz);
3126         DWC_DEBUGPL(DBG_ANY, "pktcnt=%d size=%d\n",
3127                     dieptsiz.b.pktcnt, dieptsiz.b.xfersize);
3128 #endif
3129
3130 #ifdef DISABLE_PERIODIC_EP
3131         /*
3132          * Set the NAK bit for this EP to
3133          * start the disable process.
3134          */
3135         diepctl.d32 = 0;
3136         diepctl.b.snak = 1;
3137         dwc_modify_reg32(&dev_if->in_ep_regs[num]->diepctl, diepctl.d32,
3138                          diepctl.d32);
3139         ep->disabling = 1;
3140         ep->stopped = 1;
3141 #endif
3142 }
3143
3144 /**
3145  * Handler for the IN EP NAK interrupt. 
3146  */
3147 static inline int32_t handle_in_ep_nak_intr(dwc_otg_pcd_t * pcd,
3148                                             const uint32_t epnum)
3149 {
3150         /** @todo implement ISR */
3151         dwc_otg_core_if_t *core_if;
3152         diepmsk_data_t intr_mask = {.d32 = 0 };
3153
3154         DWC_DEBUGPL(DBG_CIL,"INTERRUPT Handler not implemented for %s\n", "IN EP NAK");
3155         core_if = GET_CORE_IF(pcd);
3156         intr_mask.b.nak = 1;
3157
3158         if (core_if->multiproc_int_enable) {
3159                 dwc_modify_reg32(&core_if->dev_if->dev_global_regs->
3160                                  diepeachintmsk[epnum], intr_mask.d32, 0);
3161         } else {
3162                 dwc_modify_reg32(&core_if->dev_if->dev_global_regs->diepmsk,
3163                                  intr_mask.d32, 0);
3164         }
3165
3166         return 1;
3167 }
3168
3169 /**
3170  * Handler for the OUT EP Babble interrupt. 
3171  */
3172 static inline int32_t handle_out_ep_babble_intr(dwc_otg_pcd_t * pcd,
3173                                                 const uint32_t epnum)
3174 {
3175         /** @todo implement ISR */
3176         dwc_otg_core_if_t *core_if;
3177         doepmsk_data_t intr_mask = {.d32 = 0 };
3178
3179         DWC_DEBUGPL(DBG_CIL,"INTERRUPT Handler not implemented for %s\n",
3180                    "OUT EP Babble");
3181         core_if = GET_CORE_IF(pcd);
3182         intr_mask.b.babble = 1;
3183
3184         if (core_if->multiproc_int_enable) {
3185                 dwc_modify_reg32(&core_if->dev_if->dev_global_regs->
3186                                  doepeachintmsk[epnum], intr_mask.d32, 0);
3187         } else {
3188                 dwc_modify_reg32(&core_if->dev_if->dev_global_regs->doepmsk,
3189                                  intr_mask.d32, 0);
3190         }
3191
3192         return 1;
3193 }
3194
3195 /**
3196  * Handler for the OUT EP NAK interrupt. 
3197  */
3198 static inline int32_t handle_out_ep_nak_intr(dwc_otg_pcd_t * pcd,
3199                                              const uint32_t epnum)
3200 {
3201         /** @todo implement ISR */
3202         dwc_otg_core_if_t *core_if;
3203         doepmsk_data_t intr_mask = {.d32 = 0 };
3204
3205         DWC_DEBUGPL(DBG_CIL,"INTERRUPT Handler not implemented for %s\n", "OUT EP NAK");
3206         core_if = GET_CORE_IF(pcd);
3207         intr_mask.b.nak = 1;
3208
3209         if (core_if->multiproc_int_enable) {
3210                 dwc_modify_reg32(&core_if->dev_if->dev_global_regs->
3211                                  doepeachintmsk[epnum], intr_mask.d32, 0);
3212         } else {
3213                 dwc_modify_reg32(&core_if->dev_if->dev_global_regs->doepmsk,
3214                                  intr_mask.d32, 0);
3215         }
3216
3217         return 1;
3218 }
3219
3220 /**
3221  * Handler for the OUT EP NYET interrupt. 
3222  */
3223 static inline int32_t handle_out_ep_nyet_intr(dwc_otg_pcd_t * pcd,
3224                                               const uint32_t epnum)
3225 {
3226         /** @todo implement ISR */
3227         dwc_otg_core_if_t *core_if;
3228         doepmsk_data_t intr_mask = {.d32 = 0 };
3229
3230         DWC_DEBUGPL(DBG_CIL,"INTERRUPT Handler not implemented for %s\n", "OUT EP NYET");
3231         core_if = GET_CORE_IF(pcd);
3232         intr_mask.b.nyet = 1;
3233
3234         if (core_if->multiproc_int_enable) {
3235                 dwc_modify_reg32(&core_if->dev_if->dev_global_regs->
3236                                  doepeachintmsk[epnum], intr_mask.d32, 0);
3237         } else {
3238                 dwc_modify_reg32(&core_if->dev_if->dev_global_regs->doepmsk,
3239                                  intr_mask.d32, 0);
3240         }
3241
3242         return 1;
3243 }
3244
3245 /**
3246  * This interrupt indicates that an IN EP has a pending Interrupt.
3247  * The sequence for handling the IN EP interrupt is shown below:
3248  * -#   Read the Device All Endpoint Interrupt register
3249  * -#   Repeat the following for each IN EP interrupt bit set (from
3250  *              LSB to MSB).
3251  * -#   Read the Device Endpoint Interrupt (DIEPINTn) register
3252  * -#   If "Transfer Complete" call the request complete function
3253  * -#   If "Endpoint Disabled" complete the EP disable procedure.
3254  * -#   If "AHB Error Interrupt" log error
3255  * -#   If "Time-out Handshake" log error
3256  * -#   If "IN Token Received when TxFIFO Empty" write packet to Tx
3257  *              FIFO.
3258  * -#   If "IN Token EP Mismatch" (disable, this is handled by EP
3259  *              Mismatch Interrupt)
3260  */
3261 static int32_t dwc_otg_pcd_handle_in_ep_intr(dwc_otg_pcd_t * pcd)
3262 {
3263 #define CLEAR_IN_EP_INTR(__core_if,__epnum,__intr) \
3264 do { \
3265                 diepint_data_t diepint = {.d32=0}; \
3266                 diepint.b.__intr = 1; \
3267                 dwc_write_reg32(&__core_if->dev_if->in_ep_regs[__epnum]->diepint, \
3268                 diepint.d32); \
3269 } while (0)
3270
3271         dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
3272         dwc_otg_dev_if_t *dev_if = core_if->dev_if;
3273         diepint_data_t diepint = {.d32 = 0 };
3274         dctl_data_t dctl = {.d32 = 0 };
3275         depctl_data_t depctl = {.d32 = 0 };
3276         uint32_t ep_intr;
3277         uint32_t epnum = 0;
3278         dwc_otg_pcd_ep_t *ep;
3279         dwc_ep_t *dwc_ep;
3280         gintmsk_data_t intr_mask = {.d32 = 0 };
3281
3282         DWC_DEBUGPL(DBG_PCDV, "%s(%p)\n", __func__, pcd);
3283
3284         /* Read in the device interrupt bits */
3285         ep_intr = dwc_otg_read_dev_all_in_ep_intr(core_if);
3286
3287         /* Service the Device IN interrupts for each endpoint */
3288         while (ep_intr) {
3289                 if (ep_intr & 0x1) {
3290                         uint32_t empty_msk;
3291                         /* Get EP pointer */
3292                         ep = get_in_ep(pcd, epnum);
3293                         dwc_ep = &ep->dwc_ep;
3294
3295                         depctl.d32 =
3296                             dwc_read_reg32(&dev_if->in_ep_regs[epnum]->diepctl);
3297                         empty_msk =
3298                             dwc_read_reg32(&dev_if->dev_global_regs->
3299                                            dtknqr4_fifoemptymsk);
3300
3301                         DWC_DEBUGPL(DBG_PCDV,
3302                                     "IN EP INTERRUPT - %d\nepmty_msk - %8x  diepctl - %8x\n",
3303                                     epnum, empty_msk, depctl.d32);
3304
3305                         DWC_DEBUGPL(DBG_PCD,
3306                                     "EP%d-%s: type=%d, mps=%d\n",
3307                                     dwc_ep->num, (dwc_ep->is_in ? "IN" : "OUT"),
3308                                     dwc_ep->type, dwc_ep->maxpacket);
3309
3310                         diepint.d32 =
3311                             dwc_otg_read_dev_in_ep_intr(core_if, dwc_ep);
3312
3313                         DWC_DEBUGPL(DBG_PCDV,
3314                                     "EP %d Interrupt Register - 0x%x\n", epnum,
3315                                     diepint.d32);
3316                         /* Transfer complete */
3317                         if (diepint.b.xfercompl) {
3318                                 /* Disable the NP Tx FIFO Empty
3319                                  * Interrrupt */
3320                                 if (core_if->en_multiple_tx_fifo == 0) {
3321                                         intr_mask.b.nptxfempty = 1;
3322                                         dwc_modify_reg32(&core_if->
3323                                                          core_global_regs->
3324                                                          gintmsk, intr_mask.d32,
3325                                                          0);
3326                                 } else {
3327                                         /* Disable the Tx FIFO Empty Interrupt for this EP */
3328                                         uint32_t fifoemptymsk =
3329                                             0x1 << dwc_ep->num;
3330                                         dwc_modify_reg32(&core_if->dev_if->
3331                                                          dev_global_regs->
3332                                                          dtknqr4_fifoemptymsk,
3333                                                          fifoemptymsk, 0);
3334                                 }
3335                                 /* Clear the bit in DIEPINTn for this interrupt */
3336                                 CLEAR_IN_EP_INTR(core_if, epnum, xfercompl);
3337
3338                                 /* Complete the transfer */
3339                                 if (epnum == 0) {
3340                                         handle_ep0(pcd);
3341                                 }
3342 #ifdef DWC_EN_ISOC
3343                                 else if (dwc_ep->type == DWC_OTG_EP_TYPE_ISOC) {
3344                                         if (!ep->stopped)
3345                                                 complete_iso_ep(pcd, ep);
3346                                 }
3347 #endif                          /* DWC_EN_ISOC */
3348                                 else {
3349
3350                                         complete_ep(ep);
3351                                 }
3352                         }
3353                         /* Endpoint disable      */
3354                         if (diepint.b.epdisabled) {
3355                                 DWC_DEBUGPL(DBG_ANY, "EP%d IN disabled\n",
3356                                             epnum);
3357                                 handle_in_ep_disable_intr(pcd, epnum);
3358
3359                                 /* Clear the bit in DIEPINTn for this interrupt */
3360                                 CLEAR_IN_EP_INTR(core_if, epnum, epdisabled);
3361                         }
3362                         /* AHB Error */
3363                         if (diepint.b.ahberr) {
3364                                 DWC_DEBUGPL(DBG_ANY, "EP%d IN AHB Error\n",
3365                                             epnum);
3366                                 /* Clear the bit in DIEPINTn for this interrupt */
3367                                 CLEAR_IN_EP_INTR(core_if, epnum, ahberr);
3368                         }
3369                         /* TimeOUT Handshake (non-ISOC IN EPs) */
3370                         if (diepint.b.timeout) {
3371                                 DWC_DEBUGPL(DBG_ANY, "EP%d IN Time-out\n",
3372                                             epnum);
3373                                 handle_in_ep_timeout_intr(pcd, epnum);
3374
3375                                 CLEAR_IN_EP_INTR(core_if, epnum, timeout);
3376                         }
3377                         /** IN Token received with TxF Empty */
3378                         if (diepint.b.intktxfemp) {
3379                                 DWC_DEBUGPL(DBG_ANY,
3380                                             "EP%d IN TKN TxFifo Empty\n",
3381                                             epnum);
3382                                 if (!ep->stopped && epnum != 0) {
3383
3384                                         diepmsk_data_t diepmsk = {.d32 = 0 };
3385                                         diepmsk.b.intktxfemp = 1;
3386
3387                                         if (core_if->multiproc_int_enable) {
3388                                                 dwc_modify_reg32(&dev_if->
3389                                                                  dev_global_regs->
3390                                                                  diepeachintmsk
3391                                                                  [epnum],
3392                                                                  diepmsk.d32,
3393                                                                  0);
3394                                         } else {
3395                                                 dwc_modify_reg32(&dev_if->
3396                                                                  dev_global_regs->
3397                                                                  diepmsk,
3398                                                                  diepmsk.d32,
3399                                                                  0);
3400                                         }
3401                                 } else if (core_if->dma_desc_enable
3402                                            && epnum == 0
3403                                            && pcd->ep0state ==
3404                                            EP0_OUT_STATUS_PHASE) {
3405                                         // EP0 IN set STALL
3406                                         depctl.d32 =
3407                                             dwc_read_reg32(&dev_if->
3408                                                            in_ep_regs[epnum]->
3409                                                            diepctl);
3410
3411                                         /* set the disable and stall bits */
3412                                         if (depctl.b.epena) {
3413                                                 depctl.b.epdis = 1;
3414                                         }
3415                                         depctl.b.stall = 1;
3416                                         dwc_write_reg32(&dev_if->
3417                                                         in_ep_regs[epnum]->
3418                                                         diepctl, depctl.d32);
3419                                 }
3420                                 CLEAR_IN_EP_INTR(core_if, epnum, intktxfemp);
3421                         }
3422                         /** IN Token Received with EP mismatch */
3423                         if (diepint.b.intknepmis) {
3424                                 DWC_DEBUGPL(DBG_ANY,
3425                                             "EP%d IN TKN EP Mismatch\n", epnum);
3426                                 CLEAR_IN_EP_INTR(core_if, epnum, intknepmis);
3427                         }
3428                         /** IN Endpoint NAK Effective */
3429                         if (diepint.b.inepnakeff) {
3430                                 DWC_DEBUGPL(DBG_ANY,
3431                                             "EP%d IN EP NAK Effective\n",
3432                                             epnum);
3433                                 /* Periodic EP */
3434                                 if (ep->disabling) {
3435                                         depctl.d32 = 0;
3436                                         depctl.b.snak = 1;
3437                                         depctl.b.epdis = 1;
3438                                         dwc_modify_reg32(&dev_if->
3439                                                          in_ep_regs[epnum]->
3440                                                          diepctl, depctl.d32,
3441                                                          depctl.d32);
3442                                 }
3443                                 CLEAR_IN_EP_INTR(core_if, epnum, inepnakeff);
3444
3445                         }
3446
3447                         /** IN EP Tx FIFO Empty Intr */
3448                         if (diepint.b.emptyintr) {
3449                                 DWC_DEBUGPL(DBG_ANY,
3450                                             "EP%d Tx FIFO Empty Intr \n",
3451                                             epnum);
3452                                 write_empty_tx_fifo(pcd, epnum);
3453
3454                                 CLEAR_IN_EP_INTR(core_if, epnum, emptyintr);
3455
3456                         }
3457
3458                         /** IN EP BNA Intr */
3459                         if (diepint.b.bna) {
3460                                 CLEAR_IN_EP_INTR(core_if, epnum, bna);
3461                                 if (core_if->dma_desc_enable) {
3462 #ifdef DWC_EN_ISOC
3463                                         if (dwc_ep->type ==
3464                                             DWC_OTG_EP_TYPE_ISOC) {
3465                                                 /*
3466                                                  * This checking is performed to prevent first "false" BNA 
3467                                                  * handling occuring right after reconnect 
3468                                                  */
3469                                                 if (dwc_ep->next_frame !=
3470                                                     0xffffffff)
3471                                                         dwc_otg_pcd_handle_iso_bna
3472                                                             (ep);
3473                                         } else
3474 #endif                          /* DWC_EN_ISOC */
3475                                         {
3476                                                 dctl.d32 =
3477                                                     dwc_read_reg32(&dev_if->
3478                                                                    dev_global_regs->
3479                                                                    dctl);
3480
3481                                                 /* If Global Continue on BNA is disabled - disable EP */
3482                                                 if (!dctl.b.gcontbna) {
3483                                                         depctl.d32 = 0;
3484                                                         depctl.b.snak = 1;
3485                                                         depctl.b.epdis = 1;
3486                                                         dwc_modify_reg32
3487                                                             (&dev_if->
3488                                                              in_ep_regs[epnum]->
3489                                                              diepctl,
3490                                                              depctl.d32,
3491                                                              depctl.d32);
3492                                                 } else {
3493                                                         start_next_request(ep);
3494                                                 }
3495                                         }
3496                                 }
3497                         }
3498                         /* NAK Interrutp */
3499                         if (diepint.b.nak) {
3500                                 DWC_DEBUGPL(DBG_ANY, "EP%d IN NAK Interrupt\n",
3501                                             epnum);
3502                                 handle_in_ep_nak_intr(pcd, epnum);
3503
3504                                 CLEAR_IN_EP_INTR(core_if, epnum, nak);
3505                         }
3506                 }
3507                 epnum++;
3508                 ep_intr >>= 1;
3509         }
3510
3511         return 1;
3512 #undef CLEAR_IN_EP_INTR
3513 }
3514
3515 /**
3516  * This interrupt indicates that an OUT EP has a pending Interrupt.
3517  * The sequence for handling the OUT EP interrupt is shown below:
3518  * -#   Read the Device All Endpoint Interrupt register
3519  * -#   Repeat the following for each OUT EP interrupt bit set (from
3520  *              LSB to MSB).
3521  * -#   Read the Device Endpoint Interrupt (DOEPINTn) register
3522  * -#   If "Transfer Complete" call the request complete function
3523  * -#   If "Endpoint Disabled" complete the EP disable procedure.
3524  * -#   If "AHB Error Interrupt" log error
3525  * -#   If "Setup Phase Done" process Setup Packet (See Standard USB
3526  *              Command Processing)
3527  */
3528 static int32_t dwc_otg_pcd_handle_out_ep_intr(dwc_otg_pcd_t * pcd)
3529 {
3530 #define CLEAR_OUT_EP_INTR(__core_if,__epnum,__intr) \
3531 do { \
3532                 doepint_data_t doepint = {.d32=0}; \
3533                 doepint.b.__intr = 1; \
3534                 dwc_write_reg32(&__core_if->dev_if->out_ep_regs[__epnum]->doepint, \
3535                 doepint.d32); \
3536 } while (0)
3537
3538         dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
3539         dwc_otg_dev_if_t *dev_if = core_if->dev_if;
3540         uint32_t ep_intr;
3541         doepint_data_t doepint = {.d32 = 0 };
3542         dctl_data_t dctl = {.d32 = 0 };
3543         depctl_data_t doepctl = {.d32 = 0 };
3544         uint32_t epnum = 0;
3545         dwc_otg_pcd_ep_t *ep;
3546         dwc_ep_t *dwc_ep;
3547
3548         DWC_DEBUGPL(DBG_PCDV, "%s()\n", __func__);
3549
3550         /* Read in the device interrupt bits */
3551         ep_intr = dwc_otg_read_dev_all_out_ep_intr(core_if);
3552
3553         while (ep_intr) {
3554                 if (ep_intr & 0x1) {
3555                         /* Get EP pointer */
3556                         ep = get_out_ep(pcd, epnum);
3557                         dwc_ep = &ep->dwc_ep;
3558
3559 #ifdef VERBOSE
3560                         DWC_DEBUGPL(DBG_PCDV,
3561                                     "EP%d-%s: type=%d, mps=%d\n",
3562                                     dwc_ep->num, (dwc_ep->is_in ? "IN" : "OUT"),
3563                                     dwc_ep->type, dwc_ep->maxpacket);
3564 #endif
3565                         doepint.d32 =
3566                             dwc_otg_read_dev_out_ep_intr(core_if, dwc_ep);
3567
3568                         /* Transfer complete */
3569                         if (doepint.b.xfercompl) {
3570
3571                                 if (epnum == 0) {
3572                                         /* Clear the bit in DOEPINTn for this interrupt */
3573                                         CLEAR_OUT_EP_INTR(core_if, epnum,
3574                                                           xfercompl);
3575                                         if (pcd->ep0state != EP0_IDLE)
3576                                                 handle_ep0(pcd);
3577 #ifdef DWC_EN_ISOC
3578                                 } else if (dwc_ep->type == DWC_OTG_EP_TYPE_ISOC) {
3579                                         if (doepint.b.pktdrpsts == 0) {
3580                                                 /* Clear the bit in DOEPINTn for this interrupt */
3581                                                 CLEAR_OUT_EP_INTR(core_if,
3582                                                                   epnum,
3583                                                                   xfercompl);
3584                                                 complete_iso_ep(pcd, ep);
3585                                         } else {
3586
3587                                                 doepint_data_t doepint = {.d32 =
3588                                                             0 };
3589                                                 doepint.b.xfercompl = 1;
3590                                                 doepint.b.pktdrpsts = 1;
3591                                                 dwc_write_reg32(&core_if->
3592                                                                 dev_if->
3593                                                                 out_ep_regs
3594                                                                 [epnum]->
3595                                                                 doepint,
3596                                                                 doepint.d32);
3597                                                 if (handle_iso_out_pkt_dropped
3598                                                     (core_if, dwc_ep)) {
3599                                                         complete_iso_ep(pcd,
3600                                                                         ep);
3601                                                 }
3602                                         }
3603 #endif                          /* DWC_EN_ISOC */
3604                                 } else {
3605                                         /* Clear the bit in DOEPINTn for this interrupt */
3606                                         CLEAR_OUT_EP_INTR(core_if, epnum,
3607                                                           xfercompl);
3608                                         complete_ep(ep);
3609                                 }
3610
3611                         }
3612
3613                         /* Endpoint disable      */
3614                         if (doepint.b.epdisabled) {
3615
3616                                 /* Clear the bit in DOEPINTn for this interrupt */
3617                                 CLEAR_OUT_EP_INTR(core_if, epnum, epdisabled);
3618                         }
3619                         /* AHB Error */
3620                         if (doepint.b.ahberr) {
3621                                 DWC_DEBUGPL(DBG_PCD, "EP%d OUT AHB Error\n",
3622                                             epnum);
3623                                 DWC_DEBUGPL(DBG_PCD, "EP DMA REG         %d \n",
3624                                             core_if->dev_if->
3625                                             out_ep_regs[epnum]->doepdma);
3626                                 CLEAR_OUT_EP_INTR(core_if, epnum, ahberr);
3627                         }
3628                         /* Setup Phase Done (contorl EPs) */
3629                         if (doepint.b.setup) {
3630 #ifdef DEBUG_EP0
3631                                 DWC_DEBUGPL(DBG_PCD, "EP%d SETUP Done\n",
3632                                             epnum);
3633 #endif
3634                                 CLEAR_OUT_EP_INTR(core_if, epnum, setup);
3635
3636                                 handle_ep0(pcd);
3637                         }
3638
3639                         /** OUT EP BNA Intr */
3640                         if (doepint.b.bna) {
3641                                 CLEAR_OUT_EP_INTR(core_if, epnum, bna);
3642                                 if (core_if->dma_desc_enable) {
3643 #ifdef DWC_EN_ISOC
3644                                         if (dwc_ep->type ==
3645                                             DWC_OTG_EP_TYPE_ISOC) {
3646                                                 /*
3647                                                  * This checking is performed to prevent first "false" BNA 
3648                                                  * handling occuring right after reconnect 
3649                                                  */
3650                                                 if (dwc_ep->next_frame !=
3651                                                     0xffffffff)
3652                                                         dwc_otg_pcd_handle_iso_bna
3653                                                             (ep);
3654                                         } else
3655 #endif                          /* DWC_EN_ISOC */
3656                                         {
3657                                                 dctl.d32 =
3658                                                     dwc_read_reg32(&dev_if->
3659                                                                    dev_global_regs->
3660                                                                    dctl);
3661
3662                                                 /* If Global Continue on BNA is disabled - disable EP */
3663                                                 if (!dctl.b.gcontbna) {
3664                                                         doepctl.d32 = 0;
3665                                                         doepctl.b.snak = 1;
3666                                                         doepctl.b.epdis = 1;
3667                                                         dwc_modify_reg32
3668                                                             (&dev_if->
3669                                                              out_ep_regs
3670                                                              [epnum]->doepctl,
3671                                                              doepctl.d32,
3672                                                              doepctl.d32);
3673                                                 } else {
3674                                                         start_next_request(ep);
3675                                                 }
3676                                         }
3677                                 }
3678                         }
3679                         if (doepint.b.stsphsercvd) {
3680                                 CLEAR_OUT_EP_INTR(core_if, epnum, stsphsercvd);
3681                                 if (core_if->dma_desc_enable) {
3682                                         do_setup_in_status_phase(pcd);
3683                                 }
3684                         }
3685                         /* Babble Interrutp */
3686                         if (doepint.b.babble) {
3687                                 DWC_DEBUGPL(DBG_ANY, "EP%d OUT Babble\n",
3688                                             epnum);
3689                                 handle_out_ep_babble_intr(pcd, epnum);
3690
3691                                 CLEAR_OUT_EP_INTR(core_if, epnum, babble);
3692                         }
3693                         /* NAK Interrutp */
3694                         if (doepint.b.nak) {
3695                                 DWC_DEBUGPL(DBG_ANY, "EP%d OUT NAK\n", epnum);
3696                                 handle_out_ep_nak_intr(pcd, epnum);
3697
3698                                 CLEAR_OUT_EP_INTR(core_if, epnum, nak);
3699                         }
3700                         /* NYET Interrutp */
3701                         if (doepint.b.nyet) {
3702                                 DWC_DEBUGPL(DBG_ANY, "EP%d OUT NYET\n", epnum);
3703                                 handle_out_ep_nyet_intr(pcd, epnum);
3704
3705                                 CLEAR_OUT_EP_INTR(core_if, epnum, nyet);
3706                         }
3707                 }
3708
3709                 epnum++;
3710                 ep_intr >>= 1;
3711         }
3712
3713         return 1;
3714
3715 #undef CLEAR_OUT_EP_INTR
3716 }
3717
3718 /**
3719  * Incomplete ISO IN Transfer Interrupt.
3720  * This interrupt indicates one of the following conditions occurred
3721  * while transmitting an ISOC transaction.
3722  * - Corrupted IN Token for ISOC EP.
3723  * - Packet not complete in FIFO.
3724  * The follow actions will be taken:
3725  *      -#      Determine the EP
3726  *      -#      Set incomplete flag in dwc_ep structure
3727  *      -#      Disable EP; when "Endpoint Disabled" interrupt is received
3728  *              Flush FIFO
3729  */
3730 int32_t dwc_otg_pcd_handle_incomplete_isoc_in_intr(dwc_otg_pcd_t * pcd)
3731 {
3732         gintsts_data_t gintsts;
3733
3734 #ifdef DWC_EN_ISOC
3735         dwc_otg_dev_if_t *dev_if;
3736         deptsiz_data_t deptsiz = {.d32 = 0 };
3737         depctl_data_t depctl = {.d32 = 0 };
3738         dsts_data_t dsts = {.d32 = 0 };
3739         dwc_ep_t *dwc_ep;
3740         int i;
3741
3742         dev_if = GET_CORE_IF(pcd)->dev_if;
3743
3744         for (i = 1; i <= dev_if->num_in_eps; ++i) {
3745                 dwc_ep = &pcd->in_ep[i].dwc_ep;
3746                 if (dwc_ep->active && dwc_ep->type == DWC_OTG_EP_TYPE_ISOC) {
3747                         deptsiz.d32 =
3748                             dwc_read_reg32(&dev_if->in_ep_regs[i]->dieptsiz);
3749                         depctl.d32 =
3750                             dwc_read_reg32(&dev_if->in_ep_regs[i]->diepctl);
3751
3752                         if (depctl.b.epdis && deptsiz.d32) {
3753                                 set_current_pkt_info(GET_CORE_IF(pcd), dwc_ep);
3754                                 if (dwc_ep->cur_pkt >= dwc_ep->pkt_cnt) {
3755                                         dwc_ep->cur_pkt = 0;
3756                                         dwc_ep->proc_buf_num =
3757                                             (dwc_ep->proc_buf_num ^ 1) & 0x1;
3758
3759                                         if (dwc_ep->proc_buf_num) {
3760                                                 dwc_ep->cur_pkt_addr =
3761                                                     dwc_ep->xfer_buff1;
3762                                                 dwc_ep->cur_pkt_dma_addr =
3763                                                     dwc_ep->dma_addr1;
3764                                         } else {
3765                                                 dwc_ep->cur_pkt_addr =
3766                                                     dwc_ep->xfer_buff0;
3767                                                 dwc_ep->cur_pkt_dma_addr =
3768                                                     dwc_ep->dma_addr0;
3769                                         }
3770
3771                                 }
3772
3773                                 dsts.d32 =
3774                                     dwc_read_reg32(&GET_CORE_IF(pcd)->dev_if->
3775                                                    dev_global_regs->dsts);
3776                                 dwc_ep->next_frame = dsts.b.soffn;
3777
3778                                 dwc_otg_iso_ep_start_frm_transfer(GET_CORE_IF
3779                                                                   (pcd),
3780                                                                   dwc_ep);
3781                         }
3782                 }
3783         }
3784
3785 #else
3786         gintmsk_data_t intr_mask = {.d32 = 0 };
3787         DWC_DEBUGPL(DBG_CIL,"INTERRUPT Handler not implemented for %s\n",
3788                    "IN ISOC Incomplete");
3789
3790         intr_mask.b.incomplisoin = 1;
3791         dwc_modify_reg32(&GET_CORE_IF(pcd)->core_global_regs->gintmsk,
3792                          intr_mask.d32, 0);
3793 #endif                          //DWC_EN_ISOC
3794
3795         /* Clear interrupt */
3796         gintsts.d32 = 0;
3797         gintsts.b.incomplisoin = 1;
3798         dwc_write_reg32(&GET_CORE_IF(pcd)->core_global_regs->gintsts,
3799                         gintsts.d32);
3800
3801         return 1;
3802 }
3803
3804 /**
3805  * Incomplete ISO OUT Transfer Interrupt.
3806  *
3807  * This interrupt indicates that the core has dropped an ISO OUT
3808  * packet.      The following conditions can be the cause:
3809  * - FIFO Full, the entire packet would not fit in the FIFO.
3810  * - CRC Error
3811  * - Corrupted Token
3812  * The follow actions will be taken:
3813  *      -#      Determine the EP
3814  *      -#      Set incomplete flag in dwc_ep structure
3815  *      -#      Read any data from the FIFO
3816  *      -#      Disable EP.      when "Endpoint Disabled" interrupt is received
3817  *              re-enable EP.
3818  */
3819 int32_t dwc_otg_pcd_handle_incomplete_isoc_out_intr(dwc_otg_pcd_t * pcd)
3820 {
3821
3822         gintsts_data_t gintsts;
3823
3824 #ifdef DWC_EN_ISOC
3825         dwc_otg_dev_if_t *dev_if;
3826         deptsiz_data_t deptsiz = {.d32 = 0 };
3827         depctl_data_t depctl = {.d32 = 0 };
3828         dsts_data_t dsts = {.d32 = 0 };
3829         dwc_ep_t *dwc_ep;
3830         int i;
3831
3832         dev_if = GET_CORE_IF(pcd)->dev_if;
3833
3834         for (i = 1; i <= dev_if->num_out_eps; ++i) {
3835                 dwc_ep = &pcd->in_ep[i].dwc_ep;
3836                 if (pcd->out_ep[i].dwc_ep.active &&
3837                     pcd->out_ep[i].dwc_ep.type == DWC_OTG_EP_TYPE_ISOC) {
3838                         deptsiz.d32 =
3839                             dwc_read_reg32(&dev_if->out_ep_regs[i]->doeptsiz);
3840                         depctl.d32 =
3841                             dwc_read_reg32(&dev_if->out_ep_regs[i]->doepctl);
3842
3843                         if (depctl.b.epdis && deptsiz.d32) {
3844                                 set_current_pkt_info(GET_CORE_IF(pcd),
3845                                                      &pcd->out_ep[i].dwc_ep);
3846                                 if (dwc_ep->cur_pkt >= dwc_ep->pkt_cnt) {
3847                                         dwc_ep->cur_pkt = 0;
3848                                         dwc_ep->proc_buf_num =
3849                                             (dwc_ep->proc_buf_num ^ 1) & 0x1;
3850
3851                                         if (dwc_ep->proc_buf_num) {
3852                                                 dwc_ep->cur_pkt_addr =
3853                                                     dwc_ep->xfer_buff1;
3854                                                 dwc_ep->cur_pkt_dma_addr =
3855                                                     dwc_ep->dma_addr1;
3856                                         } else {
3857                                                 dwc_ep->cur_pkt_addr =
3858                                                     dwc_ep->xfer_buff0;
3859                                                 dwc_ep->cur_pkt_dma_addr =
3860                                                     dwc_ep->dma_addr0;
3861                                         }
3862
3863                                 }
3864
3865                                 dsts.d32 =
3866                                     dwc_read_reg32(&GET_CORE_IF(pcd)->dev_if->
3867                                                    dev_global_regs->dsts);
3868                                 dwc_ep->next_frame = dsts.b.soffn;
3869
3870                                 dwc_otg_iso_ep_start_frm_transfer(GET_CORE_IF
3871                                                                   (pcd),
3872                                                                   dwc_ep);
3873                         }
3874                 }
3875         }
3876 #else
3877         /** @todo implement ISR */
3878         gintmsk_data_t intr_mask = {.d32 = 0 };
3879
3880         DWC_DEBUGPL(DBG_CIL,"INTERRUPT Handler not implemented for %s\n",
3881                    "OUT ISOC Incomplete");
3882
3883         intr_mask.b.incomplisoout = 1;
3884         dwc_modify_reg32(&GET_CORE_IF(pcd)->core_global_regs->gintmsk,
3885                          intr_mask.d32, 0);
3886
3887 #endif                          /* DWC_EN_ISOC */
3888
3889         /* Clear interrupt */
3890         gintsts.d32 = 0;
3891         gintsts.b.incomplisoout = 1;
3892         dwc_write_reg32(&GET_CORE_IF(pcd)->core_global_regs->gintsts,
3893                         gintsts.d32);
3894
3895         return 1;
3896 }
3897
3898 /**
3899  * This function handles the Global IN NAK Effective interrupt.
3900  *
3901  */
3902 int32_t dwc_otg_pcd_handle_in_nak_effective(dwc_otg_pcd_t * pcd)
3903 {
3904         dwc_otg_dev_if_t *dev_if = GET_CORE_IF(pcd)->dev_if;
3905         depctl_data_t diepctl = {.d32 = 0 };
3906         depctl_data_t diepctl_rd = {.d32 = 0 };
3907         gintmsk_data_t intr_mask = {.d32 = 0 };
3908         gintsts_data_t gintsts;
3909         int i;
3910
3911         DWC_DEBUGPL(DBG_PCD, "Global IN NAK Effective\n");
3912
3913         /* Disable all active IN EPs */
3914         diepctl.b.epdis = 1;
3915         diepctl.b.snak = 1;
3916
3917         for (i = 0; i <= dev_if->num_in_eps; i++) {
3918                 diepctl_rd.d32 =
3919                     dwc_read_reg32(&dev_if->in_ep_regs[i]->diepctl);
3920                 if (diepctl_rd.b.epena) {
3921                         dwc_write_reg32(&dev_if->in_ep_regs[i]->diepctl,
3922                                         diepctl.d32);
3923                 }
3924         }
3925         /* Disable the Global IN NAK Effective Interrupt */
3926         intr_mask.b.ginnakeff = 1;
3927         dwc_modify_reg32(&GET_CORE_IF(pcd)->core_global_regs->gintmsk,
3928                          intr_mask.d32, 0);
3929
3930         /* Clear interrupt */
3931         gintsts.d32 = 0;
3932         gintsts.b.ginnakeff = 1;
3933         dwc_write_reg32(&GET_CORE_IF(pcd)->core_global_regs->gintsts,
3934                         gintsts.d32);
3935
3936         return 1;
3937 }
3938
3939 /**
3940  * OUT NAK Effective.
3941  *
3942  */
3943 int32_t dwc_otg_pcd_handle_out_nak_effective(dwc_otg_pcd_t * pcd)
3944 {
3945         gintmsk_data_t intr_mask = {.d32 = 0 };
3946         gintsts_data_t gintsts;
3947
3948         DWC_DEBUGPL(DBG_CIL,"INTERRUPT Handler not implemented for %s\n",
3949                    "Global IN NAK Effective\n");
3950         /* Disable the Global IN NAK Effective Interrupt */
3951         intr_mask.b.goutnakeff = 1;
3952         dwc_modify_reg32(&GET_CORE_IF(pcd)->core_global_regs->gintmsk,
3953                          intr_mask.d32, 0);
3954
3955         /* Clear interrupt */
3956         gintsts.d32 = 0;
3957         gintsts.b.goutnakeff = 1;
3958         dwc_write_reg32(&GET_CORE_IF(pcd)->core_global_regs->gintsts,
3959                         gintsts.d32);
3960
3961         return 1;
3962 }
3963
3964 /**
3965  * PCD interrupt handler.
3966  *
3967  * The PCD handles the device interrupts.  Many conditions can cause a
3968  * device interrupt. When an interrupt occurs, the device interrupt
3969  * service routine determines the cause of the interrupt and
3970  * dispatches handling to the appropriate function. These interrupt
3971  * handling functions are described below.
3972  *
3973  * All interrupt registers are processed from LSB to MSB.
3974  *
3975  */
3976 extern int32_t dwc_otg_handle_usb_suspend_intr(dwc_otg_core_if_t * core_if);
3977 extern int32_t dwc_otg_handle_wakeup_detected_intr(dwc_otg_core_if_t * core_if);
3978
3979 int32_t dwc_otg_pcd_handle_intr(dwc_otg_pcd_t * pcd)
3980 {
3981         dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
3982 #ifdef VERBOSE
3983         dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
3984 #endif
3985         gintsts_data_t gintr_status;
3986         int32_t retval = 0;
3987
3988 #ifdef VERBOSE
3989         DWC_DEBUGPL(DBG_ANY, "%s() gintsts=%08x  gintmsk=%08x\n",
3990                     __func__,
3991                     dwc_read_reg32(&global_regs->gintsts),
3992                     dwc_read_reg32(&global_regs->gintmsk));
3993 #endif
3994
3995         if (dwc_otg_is_device_mode(core_if)) {
3996                 DWC_SPINLOCK(pcd->lock);
3997
3998                 gintr_status.d32 = dwc_otg_read_core_intr(core_if);
3999 /*
4000                 DWC_DEBUGPL(DBG_PCDV, "%s: gintsts&gintmsk=%08x\n",
4001                             __func__, gintr_status.d32);
4002 */
4003                 if (gintr_status.b.sofintr) {
4004                         retval |= dwc_otg_pcd_handle_sof_intr(pcd);
4005                 }
4006                 if (gintr_status.b.rxstsqlvl) {
4007                         retval |=
4008                             dwc_otg_pcd_handle_rx_status_q_level_intr(pcd);
4009                 }
4010                 if (gintr_status.b.nptxfempty) {
4011                         retval |= dwc_otg_pcd_handle_np_tx_fifo_empty_intr(pcd);
4012                 }
4013                 if (gintr_status.b.ginnakeff) {
4014                         retval |= dwc_otg_pcd_handle_in_nak_effective(pcd);
4015                 }
4016                 if (gintr_status.b.goutnakeff) {
4017                         retval |= dwc_otg_pcd_handle_out_nak_effective(pcd);
4018                 }
4019                 if (gintr_status.b.i2cintr) {
4020                         retval |= dwc_otg_pcd_handle_i2c_intr(pcd);
4021                 }
4022                 if (gintr_status.b.erlysuspend) {
4023                         retval |= dwc_otg_pcd_handle_early_suspend_intr(pcd);
4024                 }
4025                 if (gintr_status.b.usbreset) {
4026                         retval |= dwc_otg_pcd_handle_usb_reset_intr(pcd);
4027                 }
4028                 if (gintr_status.b.enumdone) {
4029                         retval |= dwc_otg_pcd_handle_enum_done_intr(pcd);
4030                 }
4031                 if (gintr_status.b.isooutdrop) {
4032                         retval |=
4033                             dwc_otg_pcd_handle_isoc_out_packet_dropped_intr
4034                             (pcd);
4035                 }
4036                 if (gintr_status.b.eopframe) {
4037                         retval |=
4038                             dwc_otg_pcd_handle_end_periodic_frame_intr(pcd);
4039                 }
4040                 if (gintr_status.b.epmismatch) {
4041                         retval |= dwc_otg_pcd_handle_ep_mismatch_intr(core_if);
4042                 }
4043                 if (gintr_status.b.inepint) {
4044                         if (!core_if->multiproc_int_enable) {
4045                                 retval |= dwc_otg_pcd_handle_in_ep_intr(pcd);
4046                         }
4047                 }
4048                 if (gintr_status.b.outepintr) {
4049                         if (!core_if->multiproc_int_enable) {
4050                                 retval |= dwc_otg_pcd_handle_out_ep_intr(pcd);
4051                         }
4052                 }
4053                 if (gintr_status.b.incomplisoin) {
4054                         retval |=
4055                             dwc_otg_pcd_handle_incomplete_isoc_in_intr(pcd);
4056                 }
4057                 if (gintr_status.b.incomplisoout) {
4058                         retval |=
4059                             dwc_otg_pcd_handle_incomplete_isoc_out_intr(pcd);
4060                 }
4061
4062                 if (gintr_status.b.usbsuspend) {
4063                         retval |= dwc_otg_handle_usb_suspend_intr(core_if);
4064                 }       
4065                 if (gintr_status.b.wkupintr) {
4066                         retval |= dwc_otg_handle_wakeup_detected_intr(core_if);
4067                 }
4068                 /* In MPI mode De vice Endpoints intterrupts are asserted 
4069                  * without setting outepintr and inepint bits set, so these
4070                  * Interrupt handlers are called without checking these bit-fields
4071                  */
4072                 if (core_if->multiproc_int_enable) {
4073                         retval |= dwc_otg_pcd_handle_in_ep_intr(pcd);
4074                         retval |= dwc_otg_pcd_handle_out_ep_intr(pcd);
4075                 }
4076 #ifdef VERBOSE
4077 //              dwc_debug( "() gintsts=%0x\n", 
4078 //                          dwc_read_reg32(&global_regs->gintsts));
4079 #endif
4080                 DWC_SPINUNLOCK(pcd->lock);
4081         }
4082         return retval;
4083 }
4084
4085 #endif                          /* DWC_HOST_ONLY */