LCOV - code coverage report
Current view: top level - drivers/usb/host/dwc_otg - dwc_otg_pcd_intr.c (source / functions) Hit Total Coverage
Test: gcov_data_raspi2_qemu_modules_combined.info Lines: 5 1574 0.3 %
Date: 2020-09-30 20:25:01 Functions: 1 47 2.1 %
Branches: 2 897 0.2 %

           Branch data     Line data    Source code
       1                 :            : /* ==========================================================================
       2                 :            :  * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_pcd_intr.c $
       3                 :            :  * $Revision: #116 $
       4                 :            :  * $Date: 2012/08/10 $
       5                 :            :  * $Change: 2047372 $
       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                 :            : 
      35                 :            : #include "dwc_otg_pcd.h"
      36                 :            : 
      37                 :            : #ifdef DWC_UTE_CFI
      38                 :            : #include "dwc_otg_cfi.h"
      39                 :            : #endif
      40                 :            : 
      41                 :            : #ifdef DWC_UTE_PER_IO
      42                 :            : extern void complete_xiso_ep(dwc_otg_pcd_ep_t * ep);
      43                 :            : #endif
      44                 :            : //#define PRINT_CFI_DMA_DESCS
      45                 :            : 
      46                 :            : #define DEBUG_EP0
      47                 :            : 
      48                 :            : /**
      49                 :            :  * This function updates OTG.
      50                 :            :  */
      51                 :            : static void dwc_otg_pcd_update_otg(dwc_otg_pcd_t * pcd, const unsigned reset)
      52                 :            : {
      53                 :            : 
      54                 :            :         if (reset) {
      55                 :          0 :                 pcd->b_hnp_enable = 0;
      56                 :          0 :                 pcd->a_hnp_support = 0;
      57                 :          0 :                 pcd->a_alt_hnp_support = 0;
      58                 :            :         }
      59                 :            : 
      60   [ #  #  #  #  :          0 :         if (pcd->fops->hnp_changed) {
          #  #  #  #  #  
                      # ]
      61                 :          0 :                 pcd->fops->hnp_changed(pcd);
      62                 :            :         }
      63                 :            : }
      64                 :            : 
      65                 :            : /** @file
      66                 :            :  * This file contains the implementation of the PCD Interrupt handlers.
      67                 :            :  *
      68                 :            :  * The PCD handles the device interrupts.  Many conditions can cause a
      69                 :            :  * device interrupt. When an interrupt occurs, the device interrupt
      70                 :            :  * service routine determines the cause of the interrupt and
      71                 :            :  * dispatches handling to the appropriate function. These interrupt
      72                 :            :  * handling functions are described below.
      73                 :            :  * All interrupt registers are processed from LSB to MSB.
      74                 :            :  */
      75                 :            : 
      76                 :            : /**
      77                 :            :  * This function prints the ep0 state for debug purposes.
      78                 :            :  */
      79                 :            : static inline void print_ep0_state(dwc_otg_pcd_t * pcd)
      80                 :            : {
      81                 :            : #ifdef DEBUG
      82                 :            :         char str[40];
      83                 :            : 
      84                 :            :         switch (pcd->ep0state) {
      85                 :            :         case EP0_DISCONNECT:
      86                 :            :                 dwc_strcpy(str, "EP0_DISCONNECT");
      87                 :            :                 break;
      88                 :            :         case EP0_IDLE:
      89                 :            :                 dwc_strcpy(str, "EP0_IDLE");
      90                 :            :                 break;
      91                 :            :         case EP0_IN_DATA_PHASE:
      92                 :            :                 dwc_strcpy(str, "EP0_IN_DATA_PHASE");
      93                 :            :                 break;
      94                 :            :         case EP0_OUT_DATA_PHASE:
      95                 :            :                 dwc_strcpy(str, "EP0_OUT_DATA_PHASE");
      96                 :            :                 break;
      97                 :            :         case EP0_IN_STATUS_PHASE:
      98                 :            :                 dwc_strcpy(str, "EP0_IN_STATUS_PHASE");
      99                 :            :                 break;
     100                 :            :         case EP0_OUT_STATUS_PHASE:
     101                 :            :                 dwc_strcpy(str, "EP0_OUT_STATUS_PHASE");
     102                 :            :                 break;
     103                 :            :         case EP0_STALL:
     104                 :            :                 dwc_strcpy(str, "EP0_STALL");
     105                 :            :                 break;
     106                 :            :         default:
     107                 :            :                 dwc_strcpy(str, "EP0_INVALID");
     108                 :            :         }
     109                 :            : 
     110                 :            :         DWC_DEBUGPL(DBG_ANY, "%s(%d)\n", str, pcd->ep0state);
     111                 :            : #endif
     112                 :            : }
     113                 :            : 
     114                 :            : /**
     115                 :            :  * This function calculate the size of the payload in the memory
     116                 :            :  * for out endpoints and prints size for debug purposes(used in
     117                 :            :  * 2.93a DevOutNak feature).
     118                 :            :  */
     119                 :            : static inline void print_memory_payload(dwc_otg_pcd_t * pcd,  dwc_ep_t * ep)
     120                 :            : {
     121                 :            : #ifdef DEBUG
     122                 :            :         deptsiz_data_t deptsiz_init = {.d32 = 0 };
     123                 :            :         deptsiz_data_t deptsiz_updt = {.d32 = 0 };
     124                 :            :         int pack_num;
     125                 :            :         unsigned payload;
     126                 :            : 
     127                 :            :         deptsiz_init.d32 = pcd->core_if->start_doeptsiz_val[ep->num];
     128                 :            :         deptsiz_updt.d32 =
     129                 :            :                 DWC_READ_REG32(&pcd->core_if->dev_if->
     130                 :            :                                                 out_ep_regs[ep->num]->doeptsiz);
     131                 :            :         /* Payload will be */
     132                 :            :         payload = deptsiz_init.b.xfersize - deptsiz_updt.b.xfersize;
     133                 :            :         /* Packet count is decremented every time a packet
     134                 :            :          * is written to the RxFIFO not in to the external memory
     135                 :            :          * So, if payload == 0, then it means no packet was sent to ext memory*/
     136                 :            :         pack_num = (!payload) ? 0 : (deptsiz_init.b.pktcnt - deptsiz_updt.b.pktcnt);
     137                 :            :         DWC_DEBUGPL(DBG_PCDV,
     138                 :            :                 "Payload for EP%d-%s\n",
     139                 :            :                 ep->num, (ep->is_in ? "IN" : "OUT"));
     140                 :            :         DWC_DEBUGPL(DBG_PCDV,
     141                 :            :                 "Number of transfered bytes = 0x%08x\n", payload);
     142                 :            :         DWC_DEBUGPL(DBG_PCDV,
     143                 :            :                 "Number of transfered packets = %d\n", pack_num);
     144                 :            : #endif
     145                 :            : }
     146                 :            : 
     147                 :            : 
     148                 :            : #ifdef DWC_UTE_CFI
     149                 :            : static inline void print_desc(struct dwc_otg_dma_desc *ddesc,
     150                 :            :                               const uint8_t * epname, int descnum)
     151                 :            : {
     152                 :            :         CFI_INFO
     153                 :            :             ("%s DMA_DESC(%d) buf=0x%08x bytes=0x%04x; sp=0x%x; l=0x%x; sts=0x%02x; bs=0x%02x\n",
     154                 :            :              epname, descnum, ddesc->buf, ddesc->status.b.bytes,
     155                 :            :              ddesc->status.b.sp, ddesc->status.b.l, ddesc->status.b.sts,
     156                 :            :              ddesc->status.b.bs);
     157                 :            : }
     158                 :            : #endif
     159                 :            : 
     160                 :            : /**
     161                 :            :  * This function returns pointer to in ep struct with number ep_num
     162                 :            :  */
     163                 :            : static inline dwc_otg_pcd_ep_t *get_in_ep(dwc_otg_pcd_t * pcd, uint32_t ep_num)
     164                 :            : {
     165                 :            :         int i;
     166                 :          0 :         int num_in_eps = GET_CORE_IF(pcd)->dev_if->num_in_eps;
     167   [ #  #  #  #  :          0 :         if (ep_num == 0) {
          #  #  #  #  #  
             #  #  #  #  
                      # ]
     168                 :          0 :                 return &pcd->ep0;
     169                 :            :         } else {
     170   [ #  #  #  #  :          0 :                 for (i = 0; i < num_in_eps; ++i) {
          #  #  #  #  #  
             #  #  #  #  
                      # ]
     171   [ #  #  #  #  :          0 :                         if (pcd->in_ep[i].dwc_ep.num == ep_num)
          #  #  #  #  #  
             #  #  #  #  
                      # ]
     172                 :          0 :                                 return &pcd->in_ep[i];
     173                 :            :                 }
     174                 :            :                 return 0;
     175                 :            :         }
     176                 :            : }
     177                 :            : 
     178                 :            : /**
     179                 :            :  * This function returns pointer to out ep struct with number ep_num
     180                 :            :  */
     181                 :            : static inline dwc_otg_pcd_ep_t *get_out_ep(dwc_otg_pcd_t * pcd, uint32_t ep_num)
     182                 :            : {
     183                 :            :         int i;
     184                 :          0 :         int num_out_eps = GET_CORE_IF(pcd)->dev_if->num_out_eps;
     185   [ #  #  #  # ]:          0 :         if (ep_num == 0) {
     186                 :          0 :                 return &pcd->ep0;
     187                 :            :         } else {
     188   [ #  #  #  # ]:          0 :                 for (i = 0; i < num_out_eps; ++i) {
     189   [ #  #  #  # ]:          0 :                         if (pcd->out_ep[i].dwc_ep.num == ep_num)
     190                 :          0 :                                 return &pcd->out_ep[i];
     191                 :            :                 }
     192                 :            :                 return 0;
     193                 :            :         }
     194                 :            : }
     195                 :            : 
     196                 :            : /**
     197                 :            :  * This functions gets a pointer to an EP from the wIndex address
     198                 :            :  * value of the control request.
     199                 :            :  */
     200                 :          0 : dwc_otg_pcd_ep_t *get_ep_by_addr(dwc_otg_pcd_t * pcd, u16 wIndex)
     201                 :            : {
     202                 :            :         dwc_otg_pcd_ep_t *ep;
     203                 :          0 :         uint32_t ep_num = UE_GET_ADDR(wIndex);
     204                 :            : 
     205   [ #  #  #  #  :          0 :         if (ep_num == 0) {
             #  #  #  # ]
     206                 :          0 :                 ep = &pcd->ep0;
     207   [ #  #  #  #  :          0 :         } else if (UE_GET_DIR(wIndex) == UE_DIR_IN) {   /* in ep */
             #  #  #  # ]
     208                 :          0 :                 ep = &pcd->in_ep[ep_num - 1];
     209                 :            :         } else {
     210                 :          0 :                 ep = &pcd->out_ep[ep_num - 1];
     211                 :            :         }
     212                 :            : 
     213                 :          0 :         return ep;
     214                 :            : }
     215                 :            : 
     216                 :            : /**
     217                 :            :  * This function checks the EP request queue, if the queue is not
     218                 :            :  * empty the next request is started.
     219                 :            :  */
     220                 :          0 : void start_next_request(dwc_otg_pcd_ep_t * ep)
     221                 :            : {
     222                 :            :         dwc_otg_pcd_request_t *req = 0;
     223                 :          0 :         uint32_t max_transfer =
     224                 :          0 :             GET_CORE_IF(ep->pcd)->core_params->max_transfer_size;
     225                 :            : 
     226                 :            : #ifdef DWC_UTE_CFI
     227                 :            :         struct dwc_otg_pcd *pcd;
     228                 :            :         pcd = ep->pcd;
     229                 :            : #endif
     230                 :            : 
     231         [ #  # ]:          0 :         if (!DWC_CIRCLEQ_EMPTY(&ep->queue)) {
     232                 :            :                 req = DWC_CIRCLEQ_FIRST(&ep->queue);
     233                 :            : 
     234                 :            : #ifdef DWC_UTE_CFI
     235                 :            :                 if (ep->dwc_ep.buff_mode != BM_STANDARD) {
     236                 :            :                         ep->dwc_ep.cfi_req_len = req->length;
     237                 :            :                         pcd->cfi->ops.build_descriptors(pcd->cfi, pcd, ep, req);
     238                 :            :                 } else {
     239                 :            : #endif
     240                 :            :                         /* Setup and start the Transfer */
     241         [ #  # ]:          0 :                         if (req->dw_align_buf) {
     242                 :          0 :                                 ep->dwc_ep.dma_addr = req->dw_align_buf_dma;
     243                 :          0 :                                 ep->dwc_ep.start_xfer_buff = req->dw_align_buf;
     244                 :          0 :                                 ep->dwc_ep.xfer_buff = req->dw_align_buf;
     245                 :            :                         } else {
     246                 :          0 :                                 ep->dwc_ep.dma_addr = req->dma;
     247                 :          0 :                                 ep->dwc_ep.start_xfer_buff = req->buf;
     248                 :          0 :                                 ep->dwc_ep.xfer_buff = req->buf;
     249                 :            :                         }
     250                 :          0 :                         ep->dwc_ep.sent_zlp = 0;
     251                 :          0 :                         ep->dwc_ep.total_len = req->length;
     252                 :          0 :                         ep->dwc_ep.xfer_len = 0;
     253                 :          0 :                         ep->dwc_ep.xfer_count = 0;
     254                 :            : 
     255                 :          0 :                         ep->dwc_ep.maxxfer = max_transfer;
     256         [ #  # ]:          0 :                         if (GET_CORE_IF(ep->pcd)->dma_desc_enable) {
     257                 :            :                                 uint32_t out_max_xfer = DDMA_MAX_TRANSFER_SIZE
     258                 :            :                                     - (DDMA_MAX_TRANSFER_SIZE % 4);
     259         [ #  # ]:          0 :                                 if (ep->dwc_ep.is_in) {
     260         [ #  # ]:          0 :                                         if (ep->dwc_ep.maxxfer >
     261                 :            :                                             DDMA_MAX_TRANSFER_SIZE) {
     262                 :          0 :                                                 ep->dwc_ep.maxxfer =
     263                 :            :                                                     DDMA_MAX_TRANSFER_SIZE;
     264                 :            :                                         }
     265                 :            :                                 } else {
     266         [ #  # ]:          0 :                                         if (ep->dwc_ep.maxxfer > out_max_xfer) {
     267                 :          0 :                                                 ep->dwc_ep.maxxfer =
     268                 :            :                                                     out_max_xfer;
     269                 :            :                                         }
     270                 :            :                                 }
     271                 :            :                         }
     272         [ #  # ]:          0 :                         if (ep->dwc_ep.maxxfer < ep->dwc_ep.total_len) {
     273                 :          0 :                                 ep->dwc_ep.maxxfer -=
     274                 :          0 :                                     (ep->dwc_ep.maxxfer % ep->dwc_ep.maxpacket);
     275                 :            :                         }
     276         [ #  # ]:          0 :                         if (req->sent_zlp) {
     277         [ #  # ]:          0 :                                 if ((ep->dwc_ep.total_len %
     278                 :          0 :                                      ep->dwc_ep.maxpacket == 0)
     279         [ #  # ]:          0 :                                     && (ep->dwc_ep.total_len != 0)) {
     280                 :          0 :                                         ep->dwc_ep.sent_zlp = 1;
     281                 :            :                                 }
     282                 :            : 
     283                 :            :                         }
     284                 :            : #ifdef DWC_UTE_CFI
     285                 :            :                 }
     286                 :            : #endif
     287                 :          0 :                 dwc_otg_ep_start_transfer(GET_CORE_IF(ep->pcd), &ep->dwc_ep);
     288         [ #  # ]:          0 :         } else if (ep->dwc_ep.type == DWC_OTG_EP_TYPE_ISOC) {
     289                 :          0 :                 DWC_PRINTF("There are no more ISOC requests \n");
     290                 :          0 :                 ep->dwc_ep.frame_num = 0xFFFFFFFF;
     291                 :            :         }
     292                 :          0 : }
     293                 :            : 
     294                 :            : /**
     295                 :            :  * This function handles the SOF Interrupts. At this time the SOF
     296                 :            :  * Interrupt is disabled.
     297                 :            :  */
     298                 :          0 : int32_t dwc_otg_pcd_handle_sof_intr(dwc_otg_pcd_t * pcd)
     299                 :            : {
     300                 :          0 :         dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
     301                 :            : 
     302                 :            :         gintsts_data_t gintsts;
     303                 :            : 
     304                 :            :         DWC_DEBUGPL(DBG_PCD, "SOF\n");
     305                 :            : 
     306                 :            :         /* Clear interrupt */
     307                 :          0 :         gintsts.d32 = 0;
     308                 :          0 :         gintsts.b.sofintr = 1;
     309                 :          0 :         DWC_WRITE_REG32(&core_if->core_global_regs->gintsts, gintsts.d32);
     310                 :            : 
     311                 :          0 :         return 1;
     312                 :            : }
     313                 :            : 
     314                 :            : /**
     315                 :            :  * This function handles the Rx Status Queue Level Interrupt, which
     316                 :            :  * indicates that there is a least one packet in the Rx FIFO.  The
     317                 :            :  * packets are moved from the FIFO to memory, where they will be
     318                 :            :  * processed when the Endpoint Interrupt Register indicates Transfer
     319                 :            :  * Complete or SETUP Phase Done.
     320                 :            :  *
     321                 :            :  * Repeat the following until the Rx Status Queue is empty:
     322                 :            :  *       -# Read the Receive Status Pop Register (GRXSTSP) to get Packet
     323                 :            :  *              info
     324                 :            :  *       -# If Receive FIFO is empty then skip to step Clear the interrupt
     325                 :            :  *              and exit
     326                 :            :  *       -# If SETUP Packet call dwc_otg_read_setup_packet to copy the
     327                 :            :  *              SETUP data to the buffer
     328                 :            :  *       -# If OUT Data Packet call dwc_otg_read_packet to copy the data
     329                 :            :  *              to the destination buffer
     330                 :            :  */
     331                 :          0 : int32_t dwc_otg_pcd_handle_rx_status_q_level_intr(dwc_otg_pcd_t * pcd)
     332                 :            : {
     333                 :          0 :         dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
     334                 :          0 :         dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
     335                 :          0 :         gintmsk_data_t gintmask = {.d32 = 0 };
     336                 :            :         device_grxsts_data_t status;
     337                 :            :         dwc_otg_pcd_ep_t *ep;
     338                 :            :         gintsts_data_t gintsts;
     339                 :            : #ifdef DEBUG
     340                 :            :         static char *dpid_str[] = { "D0", "D2", "D1", "MDATA" };
     341                 :            : #endif
     342                 :            : 
     343                 :            :         //DWC_DEBUGPL(DBG_PCDV, "%s(%p)\n", __func__, _pcd);
     344                 :            :         /* Disable the Rx Status Queue Level interrupt */
     345                 :          0 :         gintmask.b.rxstsqlvl = 1;
     346                 :          0 :         DWC_MODIFY_REG32(&global_regs->gintmsk, gintmask.d32, 0);
     347                 :            : 
     348                 :            :         /* Get the Status from the top of the FIFO */
     349                 :          0 :         status.d32 = DWC_READ_REG32(&global_regs->grxstsp);
     350                 :            : 
     351                 :            :         DWC_DEBUGPL(DBG_PCD, "EP:%d BCnt:%d DPID:%s "
     352                 :            :                     "pktsts:%x Frame:%d(0x%0x)\n",
     353                 :            :                     status.b.epnum, status.b.bcnt,
     354                 :            :                     dpid_str[status.b.dpid],
     355                 :            :                     status.b.pktsts, status.b.fn, status.b.fn);
     356                 :            :         /* Get pointer to EP structure */
     357                 :          0 :         ep = get_out_ep(pcd, status.b.epnum);
     358                 :            : 
     359      [ #  #  # ]:          0 :         switch (status.b.pktsts) {
     360                 :            :         case DWC_DSTS_GOUT_NAK:
     361                 :            :                 DWC_DEBUGPL(DBG_PCDV, "Global OUT NAK\n");
     362                 :            :                 break;
     363                 :            :         case DWC_STS_DATA_UPDT:
     364                 :            :                 DWC_DEBUGPL(DBG_PCDV, "OUT Data Packet\n");
     365   [ #  #  #  # ]:          0 :                 if (status.b.bcnt && ep->dwc_ep.xfer_buff) {
     366                 :            :                         /** @todo NGS Check for buffer overflow? */
     367                 :          0 :                         dwc_otg_read_packet(core_if,
     368                 :            :                                             ep->dwc_ep.xfer_buff,
     369                 :          0 :                                             status.b.bcnt);
     370                 :          0 :                         ep->dwc_ep.xfer_count += status.b.bcnt;
     371                 :          0 :                         ep->dwc_ep.xfer_buff += status.b.bcnt;
     372                 :            :                 }
     373                 :            :                 break;
     374                 :            :         case DWC_STS_XFER_COMP:
     375                 :            :                 DWC_DEBUGPL(DBG_PCDV, "OUT Complete\n");
     376                 :            :                 break;
     377                 :            :         case DWC_DSTS_SETUP_COMP:
     378                 :            : #ifdef DEBUG_EP0
     379                 :            :                 DWC_DEBUGPL(DBG_PCDV, "Setup Complete\n");
     380                 :            : #endif
     381                 :            :                 break;
     382                 :            :         case DWC_DSTS_SETUP_UPDT:
     383                 :          0 :                 dwc_otg_read_setup_packet(core_if, pcd->setup_pkt->d32);
     384                 :            : #ifdef DEBUG_EP0
     385                 :            :                 DWC_DEBUGPL(DBG_PCD,
     386                 :            :                             "SETUP PKT: %02x.%02x v%04x i%04x l%04x\n",
     387                 :            :                             pcd->setup_pkt->req.bmRequestType,
     388                 :            :                             pcd->setup_pkt->req.bRequest,
     389                 :            :                             UGETW(pcd->setup_pkt->req.wValue),
     390                 :            :                             UGETW(pcd->setup_pkt->req.wIndex),
     391                 :            :                             UGETW(pcd->setup_pkt->req.wLength));
     392                 :            : #endif
     393                 :          0 :                 ep->dwc_ep.xfer_count += status.b.bcnt;
     394                 :          0 :                 break;
     395                 :            :         default:
     396                 :            :                 DWC_DEBUGPL(DBG_PCDV, "Invalid Packet Status (0x%0x)\n",
     397                 :            :                             status.b.pktsts);
     398                 :            :                 break;
     399                 :            :         }
     400                 :            : 
     401                 :            :         /* Enable the Rx Status Queue Level interrupt */
     402                 :          0 :         DWC_MODIFY_REG32(&global_regs->gintmsk, 0, gintmask.d32);
     403                 :            :         /* Clear interrupt */
     404                 :          0 :         gintsts.d32 = 0;
     405                 :          0 :         gintsts.b.rxstsqlvl = 1;
     406                 :          0 :         DWC_WRITE_REG32(&global_regs->gintsts, gintsts.d32);
     407                 :            : 
     408                 :            :         //DWC_DEBUGPL(DBG_PCDV, "EXIT: %s\n", __func__);
     409                 :          0 :         return 1;
     410                 :            : }
     411                 :            : 
     412                 :            : /**
     413                 :            :  * This function examines the Device IN Token Learning Queue to
     414                 :            :  * determine the EP number of the last IN token received.  This
     415                 :            :  * implementation is for the Mass Storage device where there are only
     416                 :            :  * 2 IN EPs (Control-IN and BULK-IN).
     417                 :            :  *
     418                 :            :  * The EP numbers for the first six IN Tokens are in DTKNQR1 and there
     419                 :            :  * are 8 EP Numbers in each of the other possible DTKNQ Registers.
     420                 :            :  *
     421                 :            :  * @param core_if Programming view of DWC_otg controller.
     422                 :            :  *
     423                 :            :  */
     424                 :          0 : static inline int get_ep_of_last_in_token(dwc_otg_core_if_t * core_if)
     425                 :            : {
     426                 :          0 :         dwc_otg_device_global_regs_t *dev_global_regs =
     427                 :          0 :             core_if->dev_if->dev_global_regs;
     428                 :          0 :         const uint32_t TOKEN_Q_DEPTH = core_if->hwcfg2.b.dev_token_q_depth;
     429                 :            :         /* Number of Token Queue Registers */
     430                 :          0 :         const int DTKNQ_REG_CNT = (TOKEN_Q_DEPTH + 7) / 8;
     431                 :            :         dtknq1_data_t dtknqr1;
     432                 :            :         uint32_t in_tkn_epnums[4];
     433                 :            :         int ndx = 0;
     434                 :            :         int i = 0;
     435                 :          0 :         volatile uint32_t *addr = &dev_global_regs->dtknqr1;
     436                 :            :         int epnum = 0;
     437                 :            : 
     438                 :            :         //DWC_DEBUGPL(DBG_PCD,"dev_token_q_depth=%d\n",TOKEN_Q_DEPTH);
     439                 :            : 
     440                 :            :         /* Read the DTKNQ Registers */
     441         [ #  # ]:          0 :         for (i = 0; i < DTKNQ_REG_CNT; i++) {
     442                 :          0 :                 in_tkn_epnums[i] = DWC_READ_REG32(addr);
     443                 :            :                 DWC_DEBUGPL(DBG_PCDV, "DTKNQR%d=0x%08x\n", i + 1,
     444                 :            :                             in_tkn_epnums[i]);
     445         [ #  # ]:          0 :                 if (addr == &dev_global_regs->dvbusdis) {
     446                 :          0 :                         addr = &dev_global_regs->dtknqr3_dthrctl;
     447                 :            :                 } else {
     448                 :          0 :                         ++addr;
     449                 :            :                 }
     450                 :            : 
     451                 :            :         }
     452                 :            : 
     453                 :            :         /* Copy the DTKNQR1 data to the bit field. */
     454                 :          0 :         dtknqr1.d32 = in_tkn_epnums[0];
     455                 :            :         /* Get the EP numbers */
     456                 :          0 :         in_tkn_epnums[0] = dtknqr1.b.epnums0_5;
     457                 :          0 :         ndx = dtknqr1.b.intknwptr - 1;
     458                 :            : 
     459                 :            :         //DWC_DEBUGPL(DBG_PCDV,"ndx=%d\n",ndx);
     460         [ #  # ]:          0 :         if (ndx == -1) {
     461                 :            :                 /** @todo Find a simpler way to calculate the max
     462                 :            :                  * queue position.*/
     463                 :            :                 int cnt = TOKEN_Q_DEPTH;
     464         [ #  # ]:          0 :                 if (TOKEN_Q_DEPTH <= 6) {
     465                 :          0 :                         cnt = TOKEN_Q_DEPTH - 1;
     466         [ #  # ]:          0 :                 } else if (TOKEN_Q_DEPTH <= 14) {
     467                 :          0 :                         cnt = TOKEN_Q_DEPTH - 7;
     468         [ #  # ]:          0 :                 } else if (TOKEN_Q_DEPTH <= 22) {
     469                 :          0 :                         cnt = TOKEN_Q_DEPTH - 15;
     470                 :            :                 } else {
     471                 :          0 :                         cnt = TOKEN_Q_DEPTH - 23;
     472                 :            :                 }
     473                 :          0 :                 epnum = (in_tkn_epnums[DTKNQ_REG_CNT - 1] >> (cnt * 4)) & 0xF;
     474                 :            :         } else {
     475         [ #  # ]:          0 :                 if (ndx <= 5) {
     476                 :          0 :                         epnum = (in_tkn_epnums[0] >> (ndx * 4)) & 0xF;
     477         [ #  # ]:          0 :                 } else if (ndx <= 13) {
     478                 :          0 :                         ndx -= 6;
     479                 :          0 :                         epnum = (in_tkn_epnums[1] >> (ndx * 4)) & 0xF;
     480         [ #  # ]:          0 :                 } else if (ndx <= 21) {
     481                 :          0 :                         ndx -= 14;
     482                 :          0 :                         epnum = (in_tkn_epnums[2] >> (ndx * 4)) & 0xF;
     483         [ #  # ]:          0 :                 } else if (ndx <= 29) {
     484                 :          0 :                         ndx -= 22;
     485                 :          0 :                         epnum = (in_tkn_epnums[3] >> (ndx * 4)) & 0xF;
     486                 :            :                 }
     487                 :            :         }
     488                 :            :         //DWC_DEBUGPL(DBG_PCD,"epnum=%d\n",epnum);
     489                 :          0 :         return epnum;
     490                 :            : }
     491                 :            : 
     492                 :            : /**
     493                 :            :  * This interrupt occurs when the non-periodic Tx FIFO is half-empty.
     494                 :            :  * The active request is checked for the next packet to be loaded into
     495                 :            :  * the non-periodic Tx FIFO.
     496                 :            :  */
     497                 :          0 : int32_t dwc_otg_pcd_handle_np_tx_fifo_empty_intr(dwc_otg_pcd_t * pcd)
     498                 :            : {
     499                 :          0 :         dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
     500                 :          0 :         dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
     501                 :            :         dwc_otg_dev_in_ep_regs_t *ep_regs;
     502                 :            :         gnptxsts_data_t txstatus = {.d32 = 0 };
     503                 :            :         gintsts_data_t gintsts;
     504                 :            : 
     505                 :            :         int epnum = 0;
     506                 :            :         dwc_otg_pcd_ep_t *ep = 0;
     507                 :            :         uint32_t len = 0;
     508                 :            :         int dwords;
     509                 :            : 
     510                 :            :         /* Get the epnum from the IN Token Learning Queue. */
     511                 :          0 :         epnum = get_ep_of_last_in_token(core_if);
     512                 :          0 :         ep = get_in_ep(pcd, epnum);
     513                 :            : 
     514                 :            :         DWC_DEBUGPL(DBG_PCD, "NP TxFifo Empty: %d \n", epnum);
     515                 :            : 
     516                 :            :         ep_regs = core_if->dev_if->in_ep_regs[epnum];
     517                 :            : 
     518                 :          0 :         len = ep->dwc_ep.xfer_len - ep->dwc_ep.xfer_count;
     519         [ #  # ]:          0 :         if (len > ep->dwc_ep.maxpacket) {
     520                 :            :                 len = ep->dwc_ep.maxpacket;
     521                 :            :         }
     522                 :          0 :         dwords = (len + 3) / 4;
     523                 :            : 
     524                 :            :         /* While there is space in the queue and space in the FIFO and
     525                 :            :          * More data to tranfer, Write packets to the Tx FIFO */
     526                 :          0 :         txstatus.d32 = DWC_READ_REG32(&global_regs->gnptxsts);
     527                 :            :         DWC_DEBUGPL(DBG_PCDV, "b4 GNPTXSTS=0x%08x\n", txstatus.d32);
     528                 :            : 
     529   [ #  #  #  # ]:          0 :         while (txstatus.b.nptxqspcavail > 0 &&
     530         [ #  # ]:          0 :                txstatus.b.nptxfspcavail > dwords &&
     531                 :          0 :                ep->dwc_ep.xfer_count < ep->dwc_ep.xfer_len) {
     532                 :            :                 /* Write the FIFO */
     533                 :          0 :                 dwc_otg_ep_write_packet(core_if, &ep->dwc_ep, 0);
     534                 :          0 :                 len = ep->dwc_ep.xfer_len - ep->dwc_ep.xfer_count;
     535                 :            : 
     536         [ #  # ]:          0 :                 if (len > ep->dwc_ep.maxpacket) {
     537                 :            :                         len = ep->dwc_ep.maxpacket;
     538                 :            :                 }
     539                 :            : 
     540                 :          0 :                 dwords = (len + 3) / 4;
     541                 :          0 :                 txstatus.d32 = DWC_READ_REG32(&global_regs->gnptxsts);
     542                 :            :                 DWC_DEBUGPL(DBG_PCDV, "GNPTXSTS=0x%08x\n", txstatus.d32);
     543                 :            :         }
     544                 :            : 
     545                 :            :         DWC_DEBUGPL(DBG_PCDV, "GNPTXSTS=0x%08x\n",
     546                 :            :                     DWC_READ_REG32(&global_regs->gnptxsts));
     547                 :            : 
     548                 :            :         /* Clear interrupt */
     549                 :          0 :         gintsts.d32 = 0;
     550                 :          0 :         gintsts.b.nptxfempty = 1;
     551                 :          0 :         DWC_WRITE_REG32(&global_regs->gintsts, gintsts.d32);
     552                 :            : 
     553                 :          0 :         return 1;
     554                 :            : }
     555                 :            : 
     556                 :            : /**
     557                 :            :  * This function is called when dedicated Tx FIFO Empty interrupt occurs.
     558                 :            :  * The active request is checked for the next packet to be loaded into
     559                 :            :  * apropriate Tx FIFO.
     560                 :            :  */
     561                 :          0 : static int32_t write_empty_tx_fifo(dwc_otg_pcd_t * pcd, uint32_t epnum)
     562                 :            : {
     563                 :          0 :         dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
     564                 :          0 :         dwc_otg_dev_if_t *dev_if = core_if->dev_if;
     565                 :            :         dwc_otg_dev_in_ep_regs_t *ep_regs;
     566                 :            :         dtxfsts_data_t txstatus = {.d32 = 0 };
     567                 :            :         dwc_otg_pcd_ep_t *ep = 0;
     568                 :            :         uint32_t len = 0;
     569                 :            :         int dwords;
     570                 :            : 
     571                 :            :         ep = get_in_ep(pcd, epnum);
     572                 :            : 
     573                 :            :         DWC_DEBUGPL(DBG_PCD, "Dedicated TxFifo Empty: %d \n", epnum);
     574                 :            : 
     575                 :            :         ep_regs = core_if->dev_if->in_ep_regs[epnum];
     576                 :            : 
     577                 :          0 :         len = ep->dwc_ep.xfer_len - ep->dwc_ep.xfer_count;
     578                 :            : 
     579         [ #  # ]:          0 :         if (len > ep->dwc_ep.maxpacket) {
     580                 :            :                 len = ep->dwc_ep.maxpacket;
     581                 :            :         }
     582                 :            : 
     583                 :          0 :         dwords = (len + 3) / 4;
     584                 :            : 
     585                 :            :         /* While there is space in the queue and space in the FIFO and
     586                 :            :          * More data to tranfer, Write packets to the Tx FIFO */
     587                 :          0 :         txstatus.d32 = DWC_READ_REG32(&dev_if->in_ep_regs[epnum]->dtxfsts);
     588                 :            :         DWC_DEBUGPL(DBG_PCDV, "b4 dtxfsts[%d]=0x%08x\n", epnum, txstatus.d32);
     589                 :            : 
     590   [ #  #  #  # ]:          0 :         while (txstatus.b.txfspcavail > dwords &&
     591         [ #  # ]:          0 :                ep->dwc_ep.xfer_count < ep->dwc_ep.xfer_len &&
     592                 :          0 :                ep->dwc_ep.xfer_len != 0) {
     593                 :            :                 /* Write the FIFO */
     594                 :          0 :                 dwc_otg_ep_write_packet(core_if, &ep->dwc_ep, 0);
     595                 :            : 
     596                 :          0 :                 len = ep->dwc_ep.xfer_len - ep->dwc_ep.xfer_count;
     597         [ #  # ]:          0 :                 if (len > ep->dwc_ep.maxpacket) {
     598                 :            :                         len = ep->dwc_ep.maxpacket;
     599                 :            :                 }
     600                 :            : 
     601                 :          0 :                 dwords = (len + 3) / 4;
     602                 :          0 :                 txstatus.d32 =
     603                 :          0 :                     DWC_READ_REG32(&dev_if->in_ep_regs[epnum]->dtxfsts);
     604                 :            :                 DWC_DEBUGPL(DBG_PCDV, "dtxfsts[%d]=0x%08x\n", epnum,
     605                 :            :                             txstatus.d32);
     606                 :            :         }
     607                 :            : 
     608                 :            :         DWC_DEBUGPL(DBG_PCDV, "b4 dtxfsts[%d]=0x%08x\n", epnum,
     609                 :            :                     DWC_READ_REG32(&dev_if->in_ep_regs[epnum]->dtxfsts));
     610                 :            : 
     611                 :          0 :         return 1;
     612                 :            : }
     613                 :            : 
     614                 :            : /**
     615                 :            :  * This function is called when the Device is disconnected. It stops
     616                 :            :  * any active requests and informs the Gadget driver of the
     617                 :            :  * disconnect.
     618                 :            :  */
     619                 :          0 : void dwc_otg_pcd_stop(dwc_otg_pcd_t * pcd)
     620                 :            : {
     621                 :            :         int i, num_in_eps, num_out_eps;
     622                 :            :         dwc_otg_pcd_ep_t *ep;
     623                 :            : 
     624                 :          0 :         gintmsk_data_t intr_mask = {.d32 = 0 };
     625                 :            : 
     626                 :          0 :         DWC_SPINLOCK(pcd->lock);
     627                 :            : 
     628                 :          0 :         num_in_eps = GET_CORE_IF(pcd)->dev_if->num_in_eps;
     629                 :          0 :         num_out_eps = GET_CORE_IF(pcd)->dev_if->num_out_eps;
     630                 :            : 
     631                 :            :         DWC_DEBUGPL(DBG_PCDV, "%s() \n", __func__);
     632                 :            :         /* don't disconnect drivers more than once */
     633         [ #  # ]:          0 :         if (pcd->ep0state == EP0_DISCONNECT) {
     634                 :            :                 DWC_DEBUGPL(DBG_ANY, "%s() Already Disconnected\n", __func__);
     635                 :          0 :                 DWC_SPINUNLOCK(pcd->lock);
     636                 :          0 :                 return;
     637                 :            :         }
     638                 :          0 :         pcd->ep0state = EP0_DISCONNECT;
     639                 :            : 
     640                 :            :         /* Reset the OTG state. */
     641                 :            :         dwc_otg_pcd_update_otg(pcd, 1);
     642                 :            : 
     643                 :            :         /* Disable the NP Tx Fifo Empty Interrupt. */
     644                 :          0 :         intr_mask.b.nptxfempty = 1;
     645                 :          0 :         DWC_MODIFY_REG32(&GET_CORE_IF(pcd)->core_global_regs->gintmsk,
     646                 :            :                          intr_mask.d32, 0);
     647                 :            : 
     648                 :            :         /* Flush the FIFOs */
     649                 :            :         /**@todo NGS Flush Periodic FIFOs */
     650                 :          0 :         dwc_otg_flush_tx_fifo(GET_CORE_IF(pcd), 0x10);
     651                 :          0 :         dwc_otg_flush_rx_fifo(GET_CORE_IF(pcd));
     652                 :            : 
     653                 :            :         /* prevent new request submissions, kill any outstanding requests  */
     654                 :          0 :         ep = &pcd->ep0;
     655                 :          0 :         dwc_otg_request_nuke(ep);
     656                 :            :         /* prevent new request submissions, kill any outstanding requests  */
     657         [ #  # ]:          0 :         for (i = 0; i < num_in_eps; i++) {
     658                 :          0 :                 dwc_otg_pcd_ep_t *ep = &pcd->in_ep[i];
     659                 :          0 :                 dwc_otg_request_nuke(ep);
     660                 :            :         }
     661                 :            :         /* prevent new request submissions, kill any outstanding requests  */
     662         [ #  # ]:          0 :         for (i = 0; i < num_out_eps; i++) {
     663                 :          0 :                 dwc_otg_pcd_ep_t *ep = &pcd->out_ep[i];
     664                 :          0 :                 dwc_otg_request_nuke(ep);
     665                 :            :         }
     666                 :            : 
     667                 :            :         /* report disconnect; the driver is already quiesced */
     668         [ #  # ]:          0 :         if (pcd->fops->disconnect) {
     669                 :          0 :                 DWC_SPINUNLOCK(pcd->lock);
     670                 :          0 :                 pcd->fops->disconnect(pcd);
     671                 :          0 :                 DWC_SPINLOCK(pcd->lock);
     672                 :            :         }
     673                 :          0 :         DWC_SPINUNLOCK(pcd->lock);
     674                 :            : }
     675                 :            : 
     676                 :            : /**
     677                 :            :  * This interrupt indicates that ...
     678                 :            :  */
     679                 :          0 : int32_t dwc_otg_pcd_handle_i2c_intr(dwc_otg_pcd_t * pcd)
     680                 :            : {
     681                 :          0 :         gintmsk_data_t intr_mask = {.d32 = 0 };
     682                 :            :         gintsts_data_t gintsts;
     683                 :            : 
     684                 :          0 :         DWC_PRINTF("INTERRUPT Handler not implemented for %s\n", "i2cintr");
     685                 :          0 :         intr_mask.b.i2cintr = 1;
     686                 :          0 :         DWC_MODIFY_REG32(&GET_CORE_IF(pcd)->core_global_regs->gintmsk,
     687                 :            :                          intr_mask.d32, 0);
     688                 :            : 
     689                 :            :         /* Clear interrupt */
     690                 :          0 :         gintsts.d32 = 0;
     691                 :          0 :         gintsts.b.i2cintr = 1;
     692                 :          0 :         DWC_WRITE_REG32(&GET_CORE_IF(pcd)->core_global_regs->gintsts,
     693                 :            :                         gintsts.d32);
     694                 :          0 :         return 1;
     695                 :            : }
     696                 :            : 
     697                 :            : /**
     698                 :            :  * This interrupt indicates that ...
     699                 :            :  */
     700                 :          0 : int32_t dwc_otg_pcd_handle_early_suspend_intr(dwc_otg_pcd_t * pcd)
     701                 :            : {
     702                 :            :         gintsts_data_t gintsts;
     703                 :            : #if defined(VERBOSE)
     704                 :            :         DWC_PRINTF("Early Suspend Detected\n");
     705                 :            : #endif
     706                 :            : 
     707                 :            :         /* Clear interrupt */
     708                 :          0 :         gintsts.d32 = 0;
     709                 :          0 :         gintsts.b.erlysuspend = 1;
     710                 :          0 :         DWC_WRITE_REG32(&GET_CORE_IF(pcd)->core_global_regs->gintsts,
     711                 :            :                         gintsts.d32);
     712                 :          0 :         return 1;
     713                 :            : }
     714                 :            : 
     715                 :            : /**
     716                 :            :  * This function configures EPO to receive SETUP packets.
     717                 :            :  *
     718                 :            :  * @todo NGS: Update the comments from the HW FS.
     719                 :            :  *
     720                 :            :  *      -# Program the following fields in the endpoint specific registers
     721                 :            :  *      for Control OUT EP 0, in order to receive a setup packet
     722                 :            :  *      - DOEPTSIZ0.Packet Count = 3 (To receive up to 3 back to back
     723                 :            :  *        setup packets)
     724                 :            :  *      - DOEPTSIZE0.Transfer Size = 24 Bytes (To receive up to 3 back
     725                 :            :  *        to back setup packets)
     726                 :            :  *              - In DMA mode, DOEPDMA0 Register with a memory address to
     727                 :            :  *                store any setup packets received
     728                 :            :  *
     729                 :            :  * @param core_if Programming view of DWC_otg controller.
     730                 :            :  * @param pcd     Programming view of the PCD.
     731                 :            :  */
     732                 :          0 : static inline void ep0_out_start(dwc_otg_core_if_t * core_if,
     733                 :            :                                  dwc_otg_pcd_t * pcd)
     734                 :            : {
     735                 :          0 :         dwc_otg_dev_if_t *dev_if = core_if->dev_if;
     736                 :          0 :         deptsiz0_data_t doeptsize0 = {.d32 = 0 };
     737                 :            :         dwc_otg_dev_dma_desc_t *dma_desc;
     738                 :            :         depctl_data_t doepctl = {.d32 = 0 };
     739                 :            : 
     740                 :            : #ifdef VERBOSE
     741                 :            :         DWC_DEBUGPL(DBG_PCDV, "%s() doepctl0=%0x\n", __func__,
     742                 :            :                     DWC_READ_REG32(&dev_if->out_ep_regs[0]->doepctl));
     743                 :            : #endif
     744         [ #  # ]:          0 :         if (core_if->snpsid >= OTG_CORE_REV_3_00a) {
     745                 :          0 :                 doepctl.d32 = DWC_READ_REG32(&dev_if->out_ep_regs[0]->doepctl);
     746         [ #  # ]:          0 :                 if (doepctl.b.epena) {
     747                 :          0 :                         return;
     748                 :            :                 }
     749                 :            :         }
     750                 :            : 
     751                 :          0 :         doeptsize0.b.supcnt = 3;
     752                 :          0 :         doeptsize0.b.pktcnt = 1;
     753                 :          0 :         doeptsize0.b.xfersize = 8 * 3;
     754                 :            : 
     755         [ #  # ]:          0 :         if (core_if->dma_enable) {
     756         [ #  # ]:          0 :                 if (!core_if->dma_desc_enable) {
     757                 :            :                         /** put here as for Hermes mode deptisz register should not be written */
     758                 :          0 :                         DWC_WRITE_REG32(&dev_if->out_ep_regs[0]->doeptsiz,
     759                 :            :                                         doeptsize0.d32);
     760                 :            : 
     761                 :            :                         /** @todo dma needs to handle multiple setup packets (up to 3) */
     762                 :          0 :                         DWC_WRITE_REG32(&dev_if->out_ep_regs[0]->doepdma,
     763                 :            :                                         pcd->setup_pkt_dma_handle);
     764                 :            :                 } else {
     765                 :          0 :                         dev_if->setup_desc_index =
     766                 :          0 :                             (dev_if->setup_desc_index + 1) & 1;
     767                 :          0 :                         dma_desc =
     768                 :            :                             dev_if->setup_desc_addr[dev_if->setup_desc_index];
     769                 :            : 
     770                 :            :                         /** DMA Descriptor Setup */
     771                 :          0 :                         dma_desc->status.b.bs = BS_HOST_BUSY;
     772         [ #  # ]:          0 :                         if (core_if->snpsid >= OTG_CORE_REV_3_00a) {
     773                 :          0 :                                 dma_desc->status.b.sr = 0;
     774                 :          0 :                                 dma_desc->status.b.mtrf = 0;
     775                 :            :                         }
     776                 :          0 :                         dma_desc->status.b.l = 1;
     777                 :          0 :                         dma_desc->status.b.ioc = 1;
     778                 :          0 :                         dma_desc->status.b.bytes = pcd->ep0.dwc_ep.maxpacket;
     779                 :          0 :                         dma_desc->buf = pcd->setup_pkt_dma_handle;
     780                 :          0 :                         dma_desc->status.b.sts = 0;
     781                 :          0 :                         dma_desc->status.b.bs = BS_HOST_READY;
     782                 :            : 
     783                 :            :                         /** DOEPDMA0 Register write */
     784                 :          0 :                         DWC_WRITE_REG32(&dev_if->out_ep_regs[0]->doepdma,
     785                 :            :                                         dev_if->dma_setup_desc_addr
     786                 :          0 :                                         [dev_if->setup_desc_index]);
     787                 :            :                 }
     788                 :            : 
     789                 :            :         } else {
     790                 :            :                 /** put here as for Hermes mode deptisz register should not be written */
     791                 :          0 :                 DWC_WRITE_REG32(&dev_if->out_ep_regs[0]->doeptsiz,
     792                 :            :                                 doeptsize0.d32);
     793                 :            :         }
     794                 :            : 
     795                 :            :         /** DOEPCTL0 Register write cnak will be set after setup interrupt */
     796                 :          0 :         doepctl.d32 = 0;
     797                 :          0 :         doepctl.b.epena = 1;
     798         [ #  # ]:          0 :         if (core_if->snpsid <= OTG_CORE_REV_2_94a) {
     799                 :          0 :         doepctl.b.cnak = 1;
     800                 :          0 :         DWC_WRITE_REG32(&dev_if->out_ep_regs[0]->doepctl, doepctl.d32);
     801                 :            :         } else {
     802                 :          0 :                 DWC_MODIFY_REG32(&dev_if->out_ep_regs[0]->doepctl, 0, doepctl.d32);
     803                 :            :         }
     804                 :            : 
     805                 :            : #ifdef VERBOSE
     806                 :            :         DWC_DEBUGPL(DBG_PCDV, "doepctl0=%0x\n",
     807                 :            :                     DWC_READ_REG32(&dev_if->out_ep_regs[0]->doepctl));
     808                 :            :         DWC_DEBUGPL(DBG_PCDV, "diepctl0=%0x\n",
     809                 :            :                     DWC_READ_REG32(&dev_if->in_ep_regs[0]->diepctl));
     810                 :            : #endif
     811                 :            : }
     812                 :            : 
     813                 :            : /**
     814                 :            :  * This interrupt occurs when a USB Reset is detected. When the USB
     815                 :            :  * Reset Interrupt occurs the device state is set to DEFAULT and the
     816                 :            :  * EP0 state is set to IDLE.
     817                 :            :  *      -#      Set the NAK bit for all OUT endpoints (DOEPCTLn.SNAK = 1)
     818                 :            :  *      -#      Unmask the following interrupt bits
     819                 :            :  *              - DAINTMSK.INEP0 = 1 (Control 0 IN endpoint)
     820                 :            :  *      - DAINTMSK.OUTEP0 = 1 (Control 0 OUT endpoint)
     821                 :            :  *      - DOEPMSK.SETUP = 1
     822                 :            :  *      - DOEPMSK.XferCompl = 1
     823                 :            :  *      - DIEPMSK.XferCompl = 1
     824                 :            :  *      - DIEPMSK.TimeOut = 1
     825                 :            :  *      -# Program the following fields in the endpoint specific registers
     826                 :            :  *      for Control OUT EP 0, in order to receive a setup packet
     827                 :            :  *      - DOEPTSIZ0.Packet Count = 3 (To receive up to 3 back to back
     828                 :            :  *        setup packets)
     829                 :            :  *      - DOEPTSIZE0.Transfer Size = 24 Bytes (To receive up to 3 back
     830                 :            :  *        to back setup packets)
     831                 :            :  *              - In DMA mode, DOEPDMA0 Register with a memory address to
     832                 :            :  *                store any setup packets received
     833                 :            :  * At this point, all the required initialization, except for enabling
     834                 :            :  * the control 0 OUT endpoint is done, for receiving SETUP packets.
     835                 :            :  */
     836                 :          0 : int32_t dwc_otg_pcd_handle_usb_reset_intr(dwc_otg_pcd_t * pcd)
     837                 :            : {
     838                 :          0 :         dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
     839                 :          0 :         dwc_otg_dev_if_t *dev_if = core_if->dev_if;
     840                 :          0 :         depctl_data_t doepctl = {.d32 = 0 };
     841                 :            :         depctl_data_t diepctl = {.d32 = 0 };
     842                 :          0 :         daint_data_t daintmsk = {.d32 = 0 };
     843                 :          0 :         doepmsk_data_t doepmsk = {.d32 = 0 };
     844                 :          0 :         diepmsk_data_t diepmsk = {.d32 = 0 };
     845                 :            :         dcfg_data_t dcfg = {.d32 = 0 };
     846                 :          0 :         grstctl_t resetctl = {.d32 = 0 };
     847                 :          0 :         dctl_data_t dctl = {.d32 = 0 };
     848                 :            :         int i = 0;
     849                 :            :         gintsts_data_t gintsts;
     850                 :            :         pcgcctl_data_t power = {.d32 = 0 };
     851                 :            : 
     852                 :          0 :         power.d32 = DWC_READ_REG32(core_if->pcgcctl);
     853         [ #  # ]:          0 :         if (power.b.stoppclk) {
     854                 :          0 :                 power.d32 = 0;
     855                 :          0 :                 power.b.stoppclk = 1;
     856                 :          0 :                 DWC_MODIFY_REG32(core_if->pcgcctl, power.d32, 0);
     857                 :            : 
     858                 :          0 :                 power.b.pwrclmp = 1;
     859                 :          0 :                 DWC_MODIFY_REG32(core_if->pcgcctl, power.d32, 0);
     860                 :            : 
     861                 :          0 :                 power.b.rstpdwnmodule = 1;
     862                 :          0 :                 DWC_MODIFY_REG32(core_if->pcgcctl, power.d32, 0);
     863                 :            :         }
     864                 :            : 
     865                 :          0 :         core_if->lx_state = DWC_OTG_L0;
     866                 :            : 
     867                 :          0 :         DWC_PRINTF("USB RESET\n");
     868                 :            : #ifdef DWC_EN_ISOC
     869                 :            :         for (i = 1; i < 16; ++i) {
     870                 :            :                 dwc_otg_pcd_ep_t *ep;
     871                 :            :                 dwc_ep_t *dwc_ep;
     872                 :            :                 ep = get_in_ep(pcd, i);
     873                 :            :                 if (ep != 0) {
     874                 :            :                         dwc_ep = &ep->dwc_ep;
     875                 :            :                         dwc_ep->next_frame = 0xffffffff;
     876                 :            :                 }
     877                 :            :         }
     878                 :            : #endif /* DWC_EN_ISOC */
     879                 :            : 
     880                 :            :         /* reset the HNP settings */
     881                 :            :         dwc_otg_pcd_update_otg(pcd, 1);
     882                 :            : 
     883                 :            :         /* Clear the Remote Wakeup Signalling */
     884                 :          0 :         dctl.b.rmtwkupsig = 1;
     885                 :          0 :         DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->dctl, dctl.d32, 0);
     886                 :            : 
     887                 :            :         /* Set NAK for all OUT EPs */
     888                 :          0 :         doepctl.b.snak = 1;
     889         [ #  # ]:          0 :         for (i = 0; i <= dev_if->num_out_eps; i++) {
     890                 :          0 :                 DWC_WRITE_REG32(&dev_if->out_ep_regs[i]->doepctl, doepctl.d32);
     891                 :            :         }
     892                 :            : 
     893                 :            :         /* Flush the NP Tx FIFO */
     894                 :          0 :         dwc_otg_flush_tx_fifo(core_if, 0x10);
     895                 :            :         /* Flush the Learning Queue */
     896                 :          0 :         resetctl.b.intknqflsh = 1;
     897                 :          0 :         DWC_WRITE_REG32(&core_if->core_global_regs->grstctl, resetctl.d32);
     898                 :            : 
     899   [ #  #  #  # ]:          0 :         if (!core_if->core_params->en_multiple_tx_fifo && core_if->dma_enable) {
     900                 :          0 :                 core_if->start_predict = 0;
     901         [ #  # ]:          0 :                 for (i = 0; i<= core_if->dev_if->num_in_eps; ++i) {
     902                 :          0 :                         core_if->nextep_seq[i] = 0xff;       // 0xff - EP not active
     903                 :            :                 }
     904                 :          0 :                 core_if->nextep_seq[0] = 0;
     905                 :          0 :                 core_if->first_in_nextep_seq = 0;
     906                 :          0 :                 diepctl.d32 = DWC_READ_REG32(&dev_if->in_ep_regs[0]->diepctl);
     907                 :          0 :                 diepctl.b.nextep = 0;
     908                 :          0 :                 DWC_WRITE_REG32(&dev_if->in_ep_regs[0]->diepctl, diepctl.d32);
     909                 :            : 
     910                 :            :                 /* Update IN Endpoint Mismatch Count by active IN NP EP count + 1 */
     911                 :          0 :                 dcfg.d32 = DWC_READ_REG32(&dev_if->dev_global_regs->dcfg);
     912                 :          0 :                 dcfg.b.epmscnt = 2;
     913                 :          0 :                 DWC_WRITE_REG32(&dev_if->dev_global_regs->dcfg, dcfg.d32);
     914                 :            : 
     915                 :            :                 DWC_DEBUGPL(DBG_PCDV,
     916                 :            :                             "%s first_in_nextep_seq= %2d; nextep_seq[]:\n",
     917                 :            :                         __func__, core_if->first_in_nextep_seq);
     918         [ #  # ]:          0 :                 for (i=0; i <= core_if->dev_if->num_in_eps; i++) {
     919                 :            :                         DWC_DEBUGPL(DBG_PCDV, "%2d\n", core_if->nextep_seq[i]);
     920                 :            :                 }
     921                 :            :         }
     922                 :            : 
     923         [ #  # ]:          0 :         if (core_if->multiproc_int_enable) {
     924                 :          0 :                 daintmsk.b.inep0 = 1;
     925                 :          0 :                 daintmsk.b.outep0 = 1;
     926                 :          0 :                 DWC_WRITE_REG32(&dev_if->dev_global_regs->deachintmsk,
     927                 :            :                                 daintmsk.d32);
     928                 :            : 
     929                 :          0 :                 doepmsk.b.setup = 1;
     930                 :          0 :                 doepmsk.b.xfercompl = 1;
     931                 :          0 :                 doepmsk.b.ahberr = 1;
     932                 :          0 :                 doepmsk.b.epdisabled = 1;
     933                 :            : 
     934   [ #  #  #  # ]:          0 :                 if ((core_if->dma_desc_enable) ||
     935                 :          0 :                     (core_if->dma_enable
     936         [ #  # ]:          0 :                      && core_if->snpsid >= OTG_CORE_REV_3_00a)) {
     937                 :          0 :                         doepmsk.b.stsphsercvd = 1;
     938                 :            :                 }
     939         [ #  # ]:          0 :                 if (core_if->dma_desc_enable)
     940                 :          0 :                         doepmsk.b.bna = 1;
     941                 :            : /*
     942                 :            :                 doepmsk.b.babble = 1;
     943                 :            :                 doepmsk.b.nyet = 1;
     944                 :            : 
     945                 :            :                 if (core_if->dma_enable) {
     946                 :            :                         doepmsk.b.nak = 1;
     947                 :            :                 }
     948                 :            : */
     949                 :          0 :                 DWC_WRITE_REG32(&dev_if->dev_global_regs->doepeachintmsk[0],
     950                 :            :                                 doepmsk.d32);
     951                 :            : 
     952                 :          0 :                 diepmsk.b.xfercompl = 1;
     953                 :          0 :                 diepmsk.b.timeout = 1;
     954                 :          0 :                 diepmsk.b.epdisabled = 1;
     955                 :          0 :                 diepmsk.b.ahberr = 1;
     956                 :          0 :                 diepmsk.b.intknepmis = 1;
     957   [ #  #  #  # ]:          0 :                 if (!core_if->en_multiple_tx_fifo && core_if->dma_enable)
     958                 :          0 :                         diepmsk.b.intknepmis = 0;
     959                 :            : 
     960                 :            : /*              if (core_if->dma_desc_enable) {
     961                 :            :                         diepmsk.b.bna = 1;
     962                 :            :                 }
     963                 :            : */
     964                 :            : /*
     965                 :            :                 if (core_if->dma_enable) {
     966                 :            :                         diepmsk.b.nak = 1;
     967                 :            :                 }
     968                 :            : */
     969                 :          0 :                 DWC_WRITE_REG32(&dev_if->dev_global_regs->diepeachintmsk[0],
     970                 :            :                                 diepmsk.d32);
     971                 :            :         } else {
     972                 :          0 :                 daintmsk.b.inep0 = 1;
     973                 :          0 :                 daintmsk.b.outep0 = 1;
     974                 :          0 :                 DWC_WRITE_REG32(&dev_if->dev_global_regs->daintmsk,
     975                 :            :                                 daintmsk.d32);
     976                 :            : 
     977                 :          0 :                 doepmsk.b.setup = 1;
     978                 :          0 :                 doepmsk.b.xfercompl = 1;
     979                 :          0 :                 doepmsk.b.ahberr = 1;
     980                 :          0 :                 doepmsk.b.epdisabled = 1;
     981                 :            : 
     982   [ #  #  #  # ]:          0 :                 if ((core_if->dma_desc_enable) ||
     983                 :          0 :                     (core_if->dma_enable
     984         [ #  # ]:          0 :                      && core_if->snpsid >= OTG_CORE_REV_3_00a)) {
     985                 :          0 :                         doepmsk.b.stsphsercvd = 1;
     986                 :            :                 }
     987         [ #  # ]:          0 :                 if (core_if->dma_desc_enable)
     988                 :          0 :                         doepmsk.b.bna = 1;
     989                 :          0 :                 DWC_WRITE_REG32(&dev_if->dev_global_regs->doepmsk, doepmsk.d32);
     990                 :            : 
     991                 :          0 :                 diepmsk.b.xfercompl = 1;
     992                 :          0 :                 diepmsk.b.timeout = 1;
     993                 :          0 :                 diepmsk.b.epdisabled = 1;
     994                 :          0 :                 diepmsk.b.ahberr = 1;
     995   [ #  #  #  # ]:          0 :                 if (!core_if->en_multiple_tx_fifo && core_if->dma_enable)
     996                 :          0 :                         diepmsk.b.intknepmis = 0;
     997                 :            : /*
     998                 :            :                 if (core_if->dma_desc_enable) {
     999                 :            :                         diepmsk.b.bna = 1;
    1000                 :            :                 }
    1001                 :            : */
    1002                 :            : 
    1003                 :          0 :                 DWC_WRITE_REG32(&dev_if->dev_global_regs->diepmsk, diepmsk.d32);
    1004                 :            :         }
    1005                 :            : 
    1006                 :            :         /* Reset Device Address */
    1007                 :          0 :         dcfg.d32 = DWC_READ_REG32(&dev_if->dev_global_regs->dcfg);
    1008                 :          0 :         dcfg.b.devaddr = 0;
    1009                 :          0 :         DWC_WRITE_REG32(&dev_if->dev_global_regs->dcfg, dcfg.d32);
    1010                 :            : 
    1011                 :            :         /* setup EP0 to receive SETUP packets */
    1012         [ #  # ]:          0 :         if (core_if->snpsid <= OTG_CORE_REV_2_94a)
    1013                 :          0 :                 ep0_out_start(core_if, pcd);
    1014                 :            : 
    1015                 :            :         /* Clear interrupt */
    1016                 :          0 :         gintsts.d32 = 0;
    1017                 :          0 :         gintsts.b.usbreset = 1;
    1018                 :          0 :         DWC_WRITE_REG32(&core_if->core_global_regs->gintsts, gintsts.d32);
    1019                 :            : 
    1020                 :          0 :         return 1;
    1021                 :            : }
    1022                 :            : 
    1023                 :            : /**
    1024                 :            :  * Get the device speed from the device status register and convert it
    1025                 :            :  * to USB speed constant.
    1026                 :            :  *
    1027                 :            :  * @param core_if Programming view of DWC_otg controller.
    1028                 :            :  */
    1029                 :          0 : static int get_device_speed(dwc_otg_core_if_t * core_if)
    1030                 :            : {
    1031                 :            :         dsts_data_t dsts;
    1032                 :            :         int speed = 0;
    1033                 :          0 :         dsts.d32 = DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dsts);
    1034                 :            : 
    1035      [ #  #  # ]:          0 :         switch (dsts.b.enumspd) {
    1036                 :            :         case DWC_DSTS_ENUMSPD_HS_PHY_30MHZ_OR_60MHZ:
    1037                 :            :                 speed = USB_SPEED_HIGH;
    1038                 :            :                 break;
    1039                 :            :         case DWC_DSTS_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ:
    1040                 :            :         case DWC_DSTS_ENUMSPD_FS_PHY_48MHZ:
    1041                 :            :                 speed = USB_SPEED_FULL;
    1042                 :          0 :                 break;
    1043                 :            : 
    1044                 :            :         case DWC_DSTS_ENUMSPD_LS_PHY_6MHZ:
    1045                 :            :                 speed = USB_SPEED_LOW;
    1046                 :          0 :                 break;
    1047                 :            :         }
    1048                 :            : 
    1049                 :          0 :         return speed;
    1050                 :            : }
    1051                 :            : 
    1052                 :            : /**
    1053                 :            :  * Read the device status register and set the device speed in the
    1054                 :            :  * data structure.
    1055                 :            :  * Set up EP0 to receive SETUP packets by calling dwc_ep0_activate.
    1056                 :            :  */
    1057                 :          0 : int32_t dwc_otg_pcd_handle_enum_done_intr(dwc_otg_pcd_t * pcd)
    1058                 :            : {
    1059                 :            :         dwc_otg_pcd_ep_t *ep0 = &pcd->ep0;
    1060                 :            :         gintsts_data_t gintsts;
    1061                 :            :         gusbcfg_data_t gusbcfg;
    1062                 :          0 :         dwc_otg_core_global_regs_t *global_regs =
    1063                 :          0 :             GET_CORE_IF(pcd)->core_global_regs;
    1064                 :            :         uint8_t utmi16b, utmi8b;
    1065                 :            :         int speed;
    1066                 :            :         DWC_DEBUGPL(DBG_PCD, "SPEED ENUM\n");
    1067                 :            : 
    1068         [ #  # ]:          0 :         if (GET_CORE_IF(pcd)->snpsid >= OTG_CORE_REV_2_60a) {
    1069                 :            :                 utmi16b = 6;    //vahrama old value was 6;
    1070                 :            :                 utmi8b = 9;
    1071                 :            :         } else {
    1072                 :            :                 utmi16b = 4;
    1073                 :            :                 utmi8b = 8;
    1074                 :            :         }
    1075                 :          0 :         dwc_otg_ep0_activate(GET_CORE_IF(pcd), &ep0->dwc_ep);
    1076         [ #  # ]:          0 :         if (GET_CORE_IF(pcd)->snpsid >= OTG_CORE_REV_3_00a) {
    1077                 :          0 :                 ep0_out_start(GET_CORE_IF(pcd), pcd);
    1078                 :            :         }
    1079                 :            : 
    1080                 :            : #ifdef DEBUG_EP0
    1081                 :            :         print_ep0_state(pcd);
    1082                 :            : #endif
    1083                 :            : 
    1084         [ #  # ]:          0 :         if (pcd->ep0state == EP0_DISCONNECT) {
    1085                 :          0 :                 pcd->ep0state = EP0_IDLE;
    1086         [ #  # ]:          0 :         } else if (pcd->ep0state == EP0_STALL) {
    1087                 :          0 :                 pcd->ep0state = EP0_IDLE;
    1088                 :            :         }
    1089                 :            : 
    1090                 :          0 :         pcd->ep0state = EP0_IDLE;
    1091                 :            : 
    1092                 :          0 :         ep0->stopped = 0;
    1093                 :            : 
    1094                 :          0 :         speed = get_device_speed(GET_CORE_IF(pcd));
    1095                 :          0 :         pcd->fops->connect(pcd, speed);
    1096                 :            : 
    1097                 :            :         /* Set USB turnaround time based on device speed and PHY interface. */
    1098                 :          0 :         gusbcfg.d32 = DWC_READ_REG32(&global_regs->gusbcfg);
    1099         [ #  # ]:          0 :         if (speed == USB_SPEED_HIGH) {
    1100         [ #  # ]:          0 :                 if (GET_CORE_IF(pcd)->hwcfg2.b.hs_phy_type ==
    1101                 :            :                     DWC_HWCFG2_HS_PHY_TYPE_ULPI) {
    1102                 :            :                         /* ULPI interface */
    1103                 :          0 :                         gusbcfg.b.usbtrdtim = 9;
    1104                 :            :                 }
    1105         [ #  # ]:          0 :                 if (GET_CORE_IF(pcd)->hwcfg2.b.hs_phy_type ==
    1106                 :            :                     DWC_HWCFG2_HS_PHY_TYPE_UTMI) {
    1107                 :            :                         /* UTMI+ interface */
    1108         [ #  # ]:          0 :                         if (GET_CORE_IF(pcd)->hwcfg4.b.utmi_phy_data_width == 0) {
    1109                 :          0 :                                 gusbcfg.b.usbtrdtim = utmi8b;
    1110         [ #  # ]:          0 :                         } else if (GET_CORE_IF(pcd)->hwcfg4.
    1111                 :            :                                    b.utmi_phy_data_width == 1) {
    1112                 :          0 :                                 gusbcfg.b.usbtrdtim = utmi16b;
    1113         [ #  # ]:          0 :                         } else if (GET_CORE_IF(pcd)->
    1114                 :          0 :                                    core_params->phy_utmi_width == 8) {
    1115                 :          0 :                                 gusbcfg.b.usbtrdtim = utmi8b;
    1116                 :            :                         } else {
    1117                 :          0 :                                 gusbcfg.b.usbtrdtim = utmi16b;
    1118                 :            :                         }
    1119                 :            :                 }
    1120         [ #  # ]:          0 :                 if (GET_CORE_IF(pcd)->hwcfg2.b.hs_phy_type ==
    1121                 :            :                     DWC_HWCFG2_HS_PHY_TYPE_UTMI_ULPI) {
    1122                 :            :                         /* UTMI+  OR  ULPI interface */
    1123         [ #  # ]:          0 :                         if (gusbcfg.b.ulpi_utmi_sel == 1) {
    1124                 :            :                                 /* ULPI interface */
    1125                 :          0 :                                 gusbcfg.b.usbtrdtim = 9;
    1126                 :            :                         } else {
    1127                 :            :                                 /* UTMI+ interface */
    1128         [ #  # ]:          0 :                                 if (GET_CORE_IF(pcd)->
    1129                 :          0 :                                     core_params->phy_utmi_width == 16) {
    1130                 :          0 :                                         gusbcfg.b.usbtrdtim = utmi16b;
    1131                 :            :                                 } else {
    1132                 :          0 :                                         gusbcfg.b.usbtrdtim = utmi8b;
    1133                 :            :                                 }
    1134                 :            :                         }
    1135                 :            :                 }
    1136                 :            :         } else {
    1137                 :            :                 /* Full or low speed */
    1138                 :          0 :                 gusbcfg.b.usbtrdtim = 9;
    1139                 :            :         }
    1140                 :          0 :         DWC_WRITE_REG32(&global_regs->gusbcfg, gusbcfg.d32);
    1141                 :            : 
    1142                 :            :         /* Clear interrupt */
    1143                 :          0 :         gintsts.d32 = 0;
    1144                 :          0 :         gintsts.b.enumdone = 1;
    1145                 :          0 :         DWC_WRITE_REG32(&GET_CORE_IF(pcd)->core_global_regs->gintsts,
    1146                 :            :                         gintsts.d32);
    1147                 :          0 :         return 1;
    1148                 :            : }
    1149                 :            : 
    1150                 :            : /**
    1151                 :            :  * This interrupt indicates that the ISO OUT Packet was dropped due to
    1152                 :            :  * Rx FIFO full or Rx Status Queue Full.  If this interrupt occurs
    1153                 :            :  * read all the data from the Rx FIFO.
    1154                 :            :  */
    1155                 :          0 : int32_t dwc_otg_pcd_handle_isoc_out_packet_dropped_intr(dwc_otg_pcd_t * pcd)
    1156                 :            : {
    1157                 :          0 :         gintmsk_data_t intr_mask = {.d32 = 0 };
    1158                 :            :         gintsts_data_t gintsts;
    1159                 :            : 
    1160                 :          0 :         DWC_WARN("INTERRUPT Handler not implemented for %s\n",
    1161                 :            :                  "ISOC Out Dropped");
    1162                 :            : 
    1163                 :          0 :         intr_mask.b.isooutdrop = 1;
    1164                 :          0 :         DWC_MODIFY_REG32(&GET_CORE_IF(pcd)->core_global_regs->gintmsk,
    1165                 :            :                          intr_mask.d32, 0);
    1166                 :            : 
    1167                 :            :         /* Clear interrupt */
    1168                 :          0 :         gintsts.d32 = 0;
    1169                 :          0 :         gintsts.b.isooutdrop = 1;
    1170                 :          0 :         DWC_WRITE_REG32(&GET_CORE_IF(pcd)->core_global_regs->gintsts,
    1171                 :            :                         gintsts.d32);
    1172                 :            : 
    1173                 :          0 :         return 1;
    1174                 :            : }
    1175                 :            : 
    1176                 :            : /**
    1177                 :            :  * This interrupt indicates the end of the portion of the micro-frame
    1178                 :            :  * for periodic transactions.  If there is a periodic transaction for
    1179                 :            :  * the next frame, load the packets into the EP periodic Tx FIFO.
    1180                 :            :  */
    1181                 :          0 : int32_t dwc_otg_pcd_handle_end_periodic_frame_intr(dwc_otg_pcd_t * pcd)
    1182                 :            : {
    1183                 :          0 :         gintmsk_data_t intr_mask = {.d32 = 0 };
    1184                 :            :         gintsts_data_t gintsts;
    1185                 :          0 :         DWC_PRINTF("INTERRUPT Handler not implemented for %s\n", "EOP");
    1186                 :            : 
    1187                 :          0 :         intr_mask.b.eopframe = 1;
    1188                 :          0 :         DWC_MODIFY_REG32(&GET_CORE_IF(pcd)->core_global_regs->gintmsk,
    1189                 :            :                          intr_mask.d32, 0);
    1190                 :            : 
    1191                 :            :         /* Clear interrupt */
    1192                 :          0 :         gintsts.d32 = 0;
    1193                 :          0 :         gintsts.b.eopframe = 1;
    1194                 :          0 :         DWC_WRITE_REG32(&GET_CORE_IF(pcd)->core_global_regs->gintsts,
    1195                 :            :                         gintsts.d32);
    1196                 :            : 
    1197                 :          0 :         return 1;
    1198                 :            : }
    1199                 :            : 
    1200                 :            : /**
    1201                 :            :  * This interrupt indicates that EP of the packet on the top of the
    1202                 :            :  * non-periodic Tx FIFO does not match EP of the IN Token received.
    1203                 :            :  *
    1204                 :            :  * The "Device IN Token Queue" Registers are read to determine the
    1205                 :            :  * order the IN Tokens have been received. The non-periodic Tx FIFO
    1206                 :            :  * is flushed, so it can be reloaded in the order seen in the IN Token
    1207                 :            :  * Queue.
    1208                 :            :  */
    1209                 :          0 : int32_t dwc_otg_pcd_handle_ep_mismatch_intr(dwc_otg_pcd_t * pcd)
    1210                 :            : {
    1211                 :            :         gintsts_data_t gintsts;
    1212                 :          0 :         dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
    1213                 :            :         dctl_data_t dctl;
    1214                 :          0 :         gintmsk_data_t intr_mask = {.d32 = 0 };
    1215                 :            : 
    1216   [ #  #  #  # ]:          0 :         if (!core_if->en_multiple_tx_fifo && core_if->dma_enable) {
    1217                 :          0 :                 core_if->start_predict = 1;
    1218                 :            : 
    1219                 :            :                 DWC_DEBUGPL(DBG_PCDV, "%s(%p)\n", __func__, core_if);
    1220                 :            : 
    1221                 :          0 :                 gintsts.d32 = DWC_READ_REG32(&core_if->core_global_regs->gintsts);
    1222         [ #  # ]:          0 :                 if (!gintsts.b.ginnakeff) {
    1223                 :            :                         /* Disable EP Mismatch interrupt */
    1224                 :            :                         intr_mask.d32 = 0;
    1225                 :          0 :                         intr_mask.b.epmismatch = 1;
    1226                 :          0 :                         DWC_MODIFY_REG32(&core_if->core_global_regs->gintmsk, intr_mask.d32, 0);
    1227                 :            :                         /* Enable the Global IN NAK Effective Interrupt */
    1228                 :          0 :                         intr_mask.d32 = 0;
    1229                 :          0 :                         intr_mask.b.ginnakeff = 1;
    1230                 :          0 :                         DWC_MODIFY_REG32(&core_if->core_global_regs->gintmsk, 0, intr_mask.d32);
    1231                 :            :                         /* Set the global non-periodic IN NAK handshake */
    1232                 :          0 :                         dctl.d32 = DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dctl);
    1233                 :          0 :                         dctl.b.sgnpinnak = 1;
    1234                 :          0 :                         DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->dctl, dctl.d32);
    1235                 :            :                 } else {
    1236                 :          0 :                         DWC_PRINTF("gintsts.b.ginnakeff = 1! dctl.b.sgnpinnak not set\n");
    1237                 :            :                 }
    1238                 :            :                 /* Disabling of all EP's will be done in dwc_otg_pcd_handle_in_nak_effective()
    1239                 :            :                  * handler after Global IN NAK Effective interrupt will be asserted */
    1240                 :            :         }
    1241                 :            :         /* Clear interrupt */
    1242                 :          0 :         gintsts.d32 = 0;
    1243                 :          0 :         gintsts.b.epmismatch = 1;
    1244                 :          0 :         DWC_WRITE_REG32(&core_if->core_global_regs->gintsts, gintsts.d32);
    1245                 :            : 
    1246                 :          0 :         return 1;
    1247                 :            : }
    1248                 :            : 
    1249                 :            : /**
    1250                 :            :  * This interrupt is valid only in DMA mode. This interrupt indicates that the
    1251                 :            :  * core has stopped fetching data for IN endpoints due to the unavailability of
    1252                 :            :  * TxFIFO space or Request Queue space. This interrupt is used by the
    1253                 :            :  * application for an endpoint mismatch algorithm.
    1254                 :            :  *
    1255                 :            :  * @param pcd The PCD
    1256                 :            :  */
    1257                 :          0 : int32_t dwc_otg_pcd_handle_ep_fetsusp_intr(dwc_otg_pcd_t * pcd)
    1258                 :            : {
    1259                 :            :         gintsts_data_t gintsts;
    1260                 :            :         gintmsk_data_t gintmsk_data;
    1261                 :            :         dctl_data_t dctl;
    1262                 :          0 :         dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
    1263                 :            :         DWC_DEBUGPL(DBG_PCDV, "%s(%p)\n", __func__, core_if);
    1264                 :            : 
    1265                 :            :         /* Clear the global non-periodic IN NAK handshake */
    1266                 :          0 :         dctl.d32 = 0;
    1267                 :          0 :         dctl.b.cgnpinnak = 1;
    1268                 :          0 :         DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->dctl, dctl.d32, dctl.d32);
    1269                 :            : 
    1270                 :            :         /* Mask GINTSTS.FETSUSP interrupt */
    1271                 :          0 :         gintmsk_data.d32 = DWC_READ_REG32(&core_if->core_global_regs->gintmsk);
    1272                 :          0 :         gintmsk_data.b.fetsusp = 0;
    1273                 :          0 :         DWC_WRITE_REG32(&core_if->core_global_regs->gintmsk, gintmsk_data.d32);
    1274                 :            : 
    1275                 :            :         /* Clear interrupt */
    1276                 :          0 :         gintsts.d32 = 0;
    1277                 :          0 :         gintsts.b.fetsusp = 1;
    1278                 :          0 :         DWC_WRITE_REG32(&core_if->core_global_regs->gintsts, gintsts.d32);
    1279                 :            : 
    1280                 :          0 :         return 1;
    1281                 :            : }
    1282                 :            : /**
    1283                 :            :  * This funcion stalls EP0.
    1284                 :            :  */
    1285                 :          0 : static inline void ep0_do_stall(dwc_otg_pcd_t * pcd, const int err_val)
    1286                 :            : {
    1287                 :            :         dwc_otg_pcd_ep_t *ep0 = &pcd->ep0;
    1288                 :          0 :         usb_device_request_t *ctrl = &pcd->setup_pkt->req;
    1289                 :          0 :         DWC_WARN("req %02x.%02x protocol STALL; err %d\n",
    1290                 :            :                  ctrl->bmRequestType, ctrl->bRequest, err_val);
    1291                 :            : 
    1292                 :          0 :         ep0->dwc_ep.is_in = 1;
    1293                 :          0 :         dwc_otg_ep_set_stall(GET_CORE_IF(pcd), &ep0->dwc_ep);
    1294                 :          0 :         pcd->ep0.stopped = 1;
    1295                 :          0 :         pcd->ep0state = EP0_IDLE;
    1296                 :          0 :         ep0_out_start(GET_CORE_IF(pcd), pcd);
    1297                 :          0 : }
    1298                 :            : 
    1299                 :            : /**
    1300                 :            :  * This functions delegates the setup command to the gadget driver.
    1301                 :            :  */
    1302                 :          0 : static inline void do_gadget_setup(dwc_otg_pcd_t * pcd,
    1303                 :            :                                    usb_device_request_t * ctrl)
    1304                 :            : {
    1305                 :            :         int ret = 0;
    1306                 :          0 :         DWC_SPINUNLOCK(pcd->lock);
    1307                 :          0 :         ret = pcd->fops->setup(pcd, (uint8_t *) ctrl);
    1308                 :          0 :         DWC_SPINLOCK(pcd->lock);
    1309         [ #  # ]:          0 :         if (ret < 0) {
    1310                 :          0 :                 ep0_do_stall(pcd, ret);
    1311                 :            :         }
    1312                 :            : 
    1313                 :            :         /** @todo This is a g_file_storage gadget driver specific
    1314                 :            :          * workaround: a DELAYED_STATUS result from the fsg_setup
    1315                 :            :          * routine will result in the gadget queueing a EP0 IN status
    1316                 :            :          * phase for a two-stage control transfer. Exactly the same as
    1317                 :            :          * a SET_CONFIGURATION/SET_INTERFACE except that this is a class
    1318                 :            :          * specific request.  Need a generic way to know when the gadget
    1319                 :            :          * driver will queue the status phase. Can we assume when we
    1320                 :            :          * call the gadget driver setup() function that it will always
    1321                 :            :          * queue and require the following flag? Need to look into
    1322                 :            :          * this.
    1323                 :            :          */
    1324                 :            : 
    1325         [ #  # ]:          0 :         if (ret == 256 + 999) {
    1326                 :          0 :                 pcd->request_config = 1;
    1327                 :            :         }
    1328                 :          0 : }
    1329                 :            : 
    1330                 :            : #ifdef DWC_UTE_CFI
    1331                 :            : /**
    1332                 :            :  * This functions delegates the CFI setup commands to the gadget driver.
    1333                 :            :  * This function will return a negative value to indicate a failure.
    1334                 :            :  */
    1335                 :            : static inline int cfi_gadget_setup(dwc_otg_pcd_t * pcd,
    1336                 :            :                                    struct cfi_usb_ctrlrequest *ctrl_req)
    1337                 :            : {
    1338                 :            :         int ret = 0;
    1339                 :            : 
    1340                 :            :         if (pcd->fops && pcd->fops->cfi_setup) {
    1341                 :            :                 DWC_SPINUNLOCK(pcd->lock);
    1342                 :            :                 ret = pcd->fops->cfi_setup(pcd, ctrl_req);
    1343                 :            :                 DWC_SPINLOCK(pcd->lock);
    1344                 :            :                 if (ret < 0) {
    1345                 :            :                         ep0_do_stall(pcd, ret);
    1346                 :            :                         return ret;
    1347                 :            :                 }
    1348                 :            :         }
    1349                 :            : 
    1350                 :            :         return ret;
    1351                 :            : }
    1352                 :            : #endif
    1353                 :            : 
    1354                 :            : /**
    1355                 :            :  * This function starts the Zero-Length Packet for the IN status phase
    1356                 :            :  * of a 2 stage control transfer.
    1357                 :            :  */
    1358                 :          0 : static inline void do_setup_in_status_phase(dwc_otg_pcd_t * pcd)
    1359                 :            : {
    1360                 :            :         dwc_otg_pcd_ep_t *ep0 = &pcd->ep0;
    1361         [ #  # ]:          0 :         if (pcd->ep0state == EP0_STALL) {
    1362                 :          0 :                 return;
    1363                 :            :         }
    1364                 :            : 
    1365                 :          0 :         pcd->ep0state = EP0_IN_STATUS_PHASE;
    1366                 :            : 
    1367                 :            :         /* Prepare for more SETUP Packets */
    1368                 :            :         DWC_DEBUGPL(DBG_PCD, "EP0 IN ZLP\n");
    1369         [ #  # ]:          0 :         if ((GET_CORE_IF(pcd)->snpsid >= OTG_CORE_REV_3_00a)
    1370         [ #  # ]:          0 :             && (pcd->core_if->dma_desc_enable)
    1371         [ #  # ]:          0 :             && (ep0->dwc_ep.xfer_count < ep0->dwc_ep.total_len)) {
    1372                 :            :                 DWC_DEBUGPL(DBG_PCDV,
    1373                 :            :                             "Data terminated wait next packet in out_desc_addr\n");
    1374                 :          0 :                 pcd->backup_buf = phys_to_virt(ep0->dwc_ep.dma_addr);
    1375                 :          0 :                 pcd->data_terminated = 1;
    1376                 :            :         }
    1377                 :          0 :         ep0->dwc_ep.xfer_len = 0;
    1378                 :          0 :         ep0->dwc_ep.xfer_count = 0;
    1379                 :          0 :         ep0->dwc_ep.is_in = 1;
    1380                 :          0 :         ep0->dwc_ep.dma_addr = pcd->setup_pkt_dma_handle;
    1381                 :          0 :         dwc_otg_ep0_start_transfer(GET_CORE_IF(pcd), &ep0->dwc_ep);
    1382                 :            : 
    1383                 :            :         /* Prepare for more SETUP Packets */
    1384                 :            :         //ep0_out_start(GET_CORE_IF(pcd), pcd);
    1385                 :            : }
    1386                 :            : 
    1387                 :            : /**
    1388                 :            :  * This function starts the Zero-Length Packet for the OUT status phase
    1389                 :            :  * of a 2 stage control transfer.
    1390                 :            :  */
    1391                 :          0 : static inline void do_setup_out_status_phase(dwc_otg_pcd_t * pcd)
    1392                 :            : {
    1393                 :            :         dwc_otg_pcd_ep_t *ep0 = &pcd->ep0;
    1394         [ #  # ]:          0 :         if (pcd->ep0state == EP0_STALL) {
    1395                 :            :                 DWC_DEBUGPL(DBG_PCD, "EP0 STALLED\n");
    1396                 :          0 :                 return;
    1397                 :            :         }
    1398                 :          0 :         pcd->ep0state = EP0_OUT_STATUS_PHASE;
    1399                 :            : 
    1400                 :            :         DWC_DEBUGPL(DBG_PCD, "EP0 OUT ZLP\n");
    1401                 :          0 :         ep0->dwc_ep.xfer_len = 0;
    1402                 :          0 :         ep0->dwc_ep.xfer_count = 0;
    1403                 :          0 :         ep0->dwc_ep.is_in = 0;
    1404                 :          0 :         ep0->dwc_ep.dma_addr = pcd->setup_pkt_dma_handle;
    1405                 :          0 :         dwc_otg_ep0_start_transfer(GET_CORE_IF(pcd), &ep0->dwc_ep);
    1406                 :            : 
    1407                 :            :         /* Prepare for more SETUP Packets */
    1408         [ #  # ]:          0 :         if (GET_CORE_IF(pcd)->dma_enable == 0) {
    1409                 :          0 :                 ep0_out_start(GET_CORE_IF(pcd), pcd);
    1410                 :            :         }
    1411                 :            : }
    1412                 :            : 
    1413                 :            : /**
    1414                 :            :  * Clear the EP halt (STALL) and if pending requests start the
    1415                 :            :  * transfer.
    1416                 :            :  */
    1417                 :          0 : static inline void pcd_clear_halt(dwc_otg_pcd_t * pcd, dwc_otg_pcd_ep_t * ep)
    1418                 :            : {
    1419         [ #  # ]:          0 :         if (ep->dwc_ep.stall_clear_flag == 0)
    1420                 :          0 :                 dwc_otg_ep_clear_stall(GET_CORE_IF(pcd), &ep->dwc_ep);
    1421                 :            : 
    1422                 :            :         /* Reactive the EP */
    1423                 :          0 :         dwc_otg_ep_activate(GET_CORE_IF(pcd), &ep->dwc_ep);
    1424         [ #  # ]:          0 :         if (ep->stopped) {
    1425                 :          0 :                 ep->stopped = 0;
    1426                 :            :                 /* If there is a request in the EP queue start it */
    1427                 :            : 
    1428                 :            :                 /** @todo FIXME: this causes an EP mismatch in DMA mode.
    1429                 :            :                  * epmismatch not yet implemented. */
    1430                 :            : 
    1431                 :            :                 /*
    1432                 :            :                  * Above fixme is solved by implmenting a tasklet to call the
    1433                 :            :                  * start_next_request(), outside of interrupt context at some
    1434                 :            :                  * time after the current time, after a clear-halt setup packet.
    1435                 :            :                  * Still need to implement ep mismatch in the future if a gadget
    1436                 :            :                  * ever uses more than one endpoint at once
    1437                 :            :                  */
    1438                 :          0 :                 ep->queue_sof = 1;
    1439                 :          0 :                 DWC_TASK_SCHEDULE(pcd->start_xfer_tasklet);
    1440                 :            :         }
    1441                 :            :         /* Start Control Status Phase */
    1442                 :          0 :         do_setup_in_status_phase(pcd);
    1443                 :          0 : }
    1444                 :            : 
    1445                 :            : /**
    1446                 :            :  * This function is called when the SET_FEATURE TEST_MODE Setup packet
    1447                 :            :  * is sent from the host.  The Device Control register is written with
    1448                 :            :  * the Test Mode bits set to the specified Test Mode.  This is done as
    1449                 :            :  * a tasklet so that the "Status" phase of the control transfer
    1450                 :            :  * completes before transmitting the TEST packets.
    1451                 :            :  *
    1452                 :            :  * @todo This has not been tested since the tasklet struct was put
    1453                 :            :  * into the PCD struct!
    1454                 :            :  *
    1455                 :            :  */
    1456                 :          0 : void do_test_mode(void *data)
    1457                 :            : {
    1458                 :            :         dctl_data_t dctl;
    1459                 :            :         dwc_otg_pcd_t *pcd = (dwc_otg_pcd_t *) data;
    1460                 :          0 :         dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
    1461                 :          0 :         int test_mode = pcd->test_mode;
    1462                 :            : 
    1463                 :            : //        DWC_WARN("%s() has not been tested since being rewritten!\n", __func__);
    1464                 :            : 
    1465                 :          0 :         dctl.d32 = DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dctl);
    1466   [ #  #  #  #  :          0 :         switch (test_mode) {
                   #  # ]
    1467                 :            :         case 1:         // TEST_J
    1468                 :          0 :                 dctl.b.tstctl = 1;
    1469                 :          0 :                 break;
    1470                 :            : 
    1471                 :            :         case 2:         // TEST_K
    1472                 :          0 :                 dctl.b.tstctl = 2;
    1473                 :          0 :                 break;
    1474                 :            : 
    1475                 :            :         case 3:         // TEST_SE0_NAK
    1476                 :          0 :                 dctl.b.tstctl = 3;
    1477                 :          0 :                 break;
    1478                 :            : 
    1479                 :            :         case 4:         // TEST_PACKET
    1480                 :          0 :                 dctl.b.tstctl = 4;
    1481                 :          0 :                 break;
    1482                 :            : 
    1483                 :            :         case 5:         // TEST_FORCE_ENABLE
    1484                 :          0 :                 dctl.b.tstctl = 5;
    1485                 :          0 :                 break;
    1486                 :            :         }
    1487                 :          0 :         DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->dctl, dctl.d32);
    1488                 :          0 : }
    1489                 :            : 
    1490                 :            : /**
    1491                 :            :  * This function process the GET_STATUS Setup Commands.
    1492                 :            :  */
    1493                 :          0 : static inline void do_get_status(dwc_otg_pcd_t * pcd)
    1494                 :            : {
    1495                 :          0 :         usb_device_request_t ctrl = pcd->setup_pkt->req;
    1496                 :            :         dwc_otg_pcd_ep_t *ep;
    1497                 :            :         dwc_otg_pcd_ep_t *ep0 = &pcd->ep0;
    1498                 :          0 :         uint16_t *status = pcd->status_buf;
    1499                 :          0 :         dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
    1500                 :            : 
    1501                 :            : #ifdef DEBUG_EP0
    1502                 :            :         DWC_DEBUGPL(DBG_PCD,
    1503                 :            :                     "GET_STATUS %02x.%02x v%04x i%04x l%04x\n",
    1504                 :            :                     ctrl.bmRequestType, ctrl.bRequest,
    1505                 :            :                     UGETW(ctrl.wValue), UGETW(ctrl.wIndex),
    1506                 :            :                     UGETW(ctrl.wLength));
    1507                 :            : #endif
    1508                 :            : 
    1509   [ #  #  #  # ]:          0 :         switch (UT_GET_RECIPIENT(ctrl.bmRequestType)) {
    1510                 :            :         case UT_DEVICE:
    1511         [ #  # ]:          0 :                 if(UGETW(ctrl.wIndex) == 0xF000) { /* OTG Status selector */
    1512                 :          0 :                         DWC_PRINTF("wIndex - %d\n", UGETW(ctrl.wIndex));
    1513                 :          0 :                         DWC_PRINTF("OTG VERSION - %d\n", core_if->otg_ver);
    1514                 :          0 :                         DWC_PRINTF("OTG CAP - %d, %d\n",
    1515                 :          0 :                                    core_if->core_params->otg_cap,
    1516                 :            :                                                 DWC_OTG_CAP_PARAM_HNP_SRP_CAPABLE);
    1517         [ #  # ]:          0 :                         if (core_if->otg_ver == 1
    1518         [ #  # ]:          0 :                             && core_if->core_params->otg_cap ==
    1519                 :            :                             DWC_OTG_CAP_PARAM_HNP_SRP_CAPABLE) {
    1520                 :          0 :                                 uint8_t *otgsts = (uint8_t*)pcd->status_buf;
    1521                 :          0 :                                 *otgsts = (core_if->otg_sts & 0x1);
    1522                 :          0 :                                 pcd->ep0_pending = 1;
    1523                 :          0 :                                 ep0->dwc_ep.start_xfer_buff =
    1524                 :            :                                     (uint8_t *) otgsts;
    1525                 :          0 :                                 ep0->dwc_ep.xfer_buff = (uint8_t *) otgsts;
    1526                 :          0 :                                 ep0->dwc_ep.dma_addr =
    1527                 :          0 :                                     pcd->status_buf_dma_handle;
    1528                 :          0 :                                 ep0->dwc_ep.xfer_len = 1;
    1529                 :          0 :                                 ep0->dwc_ep.xfer_count = 0;
    1530                 :          0 :                                 ep0->dwc_ep.total_len = ep0->dwc_ep.xfer_len;
    1531                 :          0 :                                 dwc_otg_ep0_start_transfer(GET_CORE_IF(pcd),
    1532                 :            :                                                            &ep0->dwc_ep);
    1533                 :          0 :                                 return;
    1534                 :            :                         } else {
    1535                 :          0 :                                 ep0_do_stall(pcd, -DWC_E_NOT_SUPPORTED);
    1536                 :          0 :                                 return;
    1537                 :            :                         }
    1538                 :            :                         break;
    1539                 :            :                 } else {
    1540                 :          0 :                         *status = 0x1;  /* Self powered */
    1541                 :          0 :                         *status |= pcd->remote_wakeup_enable << 1;
    1542                 :          0 :                         break;
    1543                 :            :                 }
    1544                 :            :         case UT_INTERFACE:
    1545                 :          0 :                 *status = 0;
    1546                 :          0 :                 break;
    1547                 :            : 
    1548                 :            :         case UT_ENDPOINT:
    1549                 :          0 :                 ep = get_ep_by_addr(pcd, UGETW(ctrl.wIndex));
    1550   [ #  #  #  # ]:          0 :                 if (ep == 0 || UGETW(ctrl.wLength) > 2) {
    1551                 :          0 :                         ep0_do_stall(pcd, -DWC_E_NOT_SUPPORTED);
    1552                 :          0 :                         return;
    1553                 :            :                 }
    1554                 :            :                 /** @todo check for EP stall */
    1555                 :          0 :                 *status = ep->stopped;
    1556                 :          0 :                 break;
    1557                 :            :         }
    1558                 :          0 :         pcd->ep0_pending = 1;
    1559                 :          0 :         ep0->dwc_ep.start_xfer_buff = (uint8_t *) status;
    1560                 :          0 :         ep0->dwc_ep.xfer_buff = (uint8_t *) status;
    1561                 :          0 :         ep0->dwc_ep.dma_addr = pcd->status_buf_dma_handle;
    1562                 :          0 :         ep0->dwc_ep.xfer_len = 2;
    1563                 :          0 :         ep0->dwc_ep.xfer_count = 0;
    1564                 :          0 :         ep0->dwc_ep.total_len = ep0->dwc_ep.xfer_len;
    1565                 :          0 :         dwc_otg_ep0_start_transfer(GET_CORE_IF(pcd), &ep0->dwc_ep);
    1566                 :            : }
    1567                 :            : 
    1568                 :            : /**
    1569                 :            :  * This function process the SET_FEATURE Setup Commands.
    1570                 :            :  */
    1571                 :          0 : static inline void do_set_feature(dwc_otg_pcd_t * pcd)
    1572                 :            : {
    1573                 :          0 :         dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
    1574                 :          0 :         dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
    1575                 :          0 :         usb_device_request_t ctrl = pcd->setup_pkt->req;
    1576                 :            :         dwc_otg_pcd_ep_t *ep = 0;
    1577                 :          0 :         int32_t otg_cap_param = core_if->core_params->otg_cap;
    1578                 :          0 :         gotgctl_data_t gotgctl = {.d32 = 0 };
    1579                 :            : 
    1580                 :            :         DWC_DEBUGPL(DBG_PCD, "SET_FEATURE:%02x.%02x v%04x i%04x l%04x\n",
    1581                 :            :                     ctrl.bmRequestType, ctrl.bRequest,
    1582                 :            :                     UGETW(ctrl.wValue), UGETW(ctrl.wIndex),
    1583                 :            :                     UGETW(ctrl.wLength));
    1584                 :            :         DWC_DEBUGPL(DBG_PCD, "otg_cap=%d\n", otg_cap_param);
    1585                 :            : 
    1586   [ #  #  #  # ]:          0 :         switch (UT_GET_RECIPIENT(ctrl.bmRequestType)) {
    1587                 :            :         case UT_DEVICE:
    1588   [ #  #  #  #  :          0 :                 switch (UGETW(ctrl.wValue)) {
                   #  # ]
    1589                 :            :                 case UF_DEVICE_REMOTE_WAKEUP:
    1590                 :          0 :                         pcd->remote_wakeup_enable = 1;
    1591                 :          0 :                         break;
    1592                 :            : 
    1593                 :            :                 case UF_TEST_MODE:
    1594                 :            :                         /* Setup the Test Mode tasklet to do the Test
    1595                 :            :                          * Packet generation after the SETUP Status
    1596                 :            :                          * phase has completed. */
    1597                 :            : 
    1598                 :            :                         /** @todo This has not been tested since the
    1599                 :            :                          * tasklet struct was put into the PCD
    1600                 :            :                          * struct! */
    1601                 :          0 :                         pcd->test_mode = UGETW(ctrl.wIndex) >> 8;
    1602                 :          0 :                         DWC_TASK_SCHEDULE(pcd->test_mode_tasklet);
    1603                 :          0 :                         break;
    1604                 :            : 
    1605                 :            :                 case UF_DEVICE_B_HNP_ENABLE:
    1606                 :            :                         DWC_DEBUGPL(DBG_PCDV,
    1607                 :            :                                     "SET_FEATURE: USB_DEVICE_B_HNP_ENABLE\n");
    1608                 :            : 
    1609                 :            :                         /* dev may initiate HNP */
    1610         [ #  # ]:          0 :                         if (otg_cap_param == DWC_OTG_CAP_PARAM_HNP_SRP_CAPABLE) {
    1611                 :          0 :                                 pcd->b_hnp_enable = 1;
    1612                 :            :                                 dwc_otg_pcd_update_otg(pcd, 0);
    1613                 :            :                                 DWC_DEBUGPL(DBG_PCD, "Request B HNP\n");
    1614                 :            :                                 /**@todo Is the gotgctl.devhnpen cleared
    1615                 :            :                                  * by a USB Reset? */
    1616                 :          0 :                                 gotgctl.b.devhnpen = 1;
    1617                 :          0 :                                 gotgctl.b.hnpreq = 1;
    1618                 :          0 :                                 DWC_WRITE_REG32(&global_regs->gotgctl,
    1619                 :            :                                                 gotgctl.d32);
    1620                 :            :                         } else {
    1621                 :          0 :                                 ep0_do_stall(pcd, -DWC_E_NOT_SUPPORTED);
    1622                 :          0 :                                 return;
    1623                 :            :                         }
    1624                 :          0 :                         break;
    1625                 :            : 
    1626                 :            :                 case UF_DEVICE_A_HNP_SUPPORT:
    1627                 :            :                         /* RH port supports HNP */
    1628                 :            :                         DWC_DEBUGPL(DBG_PCDV,
    1629                 :            :                                     "SET_FEATURE: USB_DEVICE_A_HNP_SUPPORT\n");
    1630         [ #  # ]:          0 :                         if (otg_cap_param == DWC_OTG_CAP_PARAM_HNP_SRP_CAPABLE) {
    1631                 :          0 :                                 pcd->a_hnp_support = 1;
    1632                 :            :                                 dwc_otg_pcd_update_otg(pcd, 0);
    1633                 :            :                         } else {
    1634                 :          0 :                                 ep0_do_stall(pcd, -DWC_E_NOT_SUPPORTED);
    1635                 :          0 :                                 return;
    1636                 :            :                         }
    1637                 :            :                         break;
    1638                 :            : 
    1639                 :            :                 case UF_DEVICE_A_ALT_HNP_SUPPORT:
    1640                 :            :                         /* other RH port does */
    1641                 :            :                         DWC_DEBUGPL(DBG_PCDV,
    1642                 :            :                                     "SET_FEATURE: USB_DEVICE_A_ALT_HNP_SUPPORT\n");
    1643         [ #  # ]:          0 :                         if (otg_cap_param == DWC_OTG_CAP_PARAM_HNP_SRP_CAPABLE) {
    1644                 :          0 :                                 pcd->a_alt_hnp_support = 1;
    1645                 :            :                                 dwc_otg_pcd_update_otg(pcd, 0);
    1646                 :            :                         } else {
    1647                 :          0 :                                 ep0_do_stall(pcd, -DWC_E_NOT_SUPPORTED);
    1648                 :          0 :                                 return;
    1649                 :            :                         }
    1650                 :            :                         break;
    1651                 :            : 
    1652                 :            :                 default:
    1653                 :          0 :                         ep0_do_stall(pcd, -DWC_E_NOT_SUPPORTED);
    1654                 :          0 :                         return;
    1655                 :            : 
    1656                 :            :                 }
    1657                 :          0 :                 do_setup_in_status_phase(pcd);
    1658                 :          0 :                 break;
    1659                 :            : 
    1660                 :            :         case UT_INTERFACE:
    1661                 :          0 :                 do_gadget_setup(pcd, &ctrl);
    1662                 :          0 :                 break;
    1663                 :            : 
    1664                 :            :         case UT_ENDPOINT:
    1665         [ #  # ]:          0 :                 if (UGETW(ctrl.wValue) == UF_ENDPOINT_HALT) {
    1666                 :          0 :                         ep = get_ep_by_addr(pcd, UGETW(ctrl.wIndex));
    1667         [ #  # ]:          0 :                         if (ep == 0) {
    1668                 :          0 :                                 ep0_do_stall(pcd, -DWC_E_NOT_SUPPORTED);
    1669                 :          0 :                                 return;
    1670                 :            :                         }
    1671                 :          0 :                         ep->stopped = 1;
    1672                 :          0 :                         dwc_otg_ep_set_stall(core_if, &ep->dwc_ep);
    1673                 :            :                 }
    1674                 :          0 :                 do_setup_in_status_phase(pcd);
    1675                 :          0 :                 break;
    1676                 :            :         }
    1677                 :            : }
    1678                 :            : 
    1679                 :            : /**
    1680                 :            :  * This function process the CLEAR_FEATURE Setup Commands.
    1681                 :            :  */
    1682                 :          0 : static inline void do_clear_feature(dwc_otg_pcd_t * pcd)
    1683                 :            : {
    1684                 :          0 :         usb_device_request_t ctrl = pcd->setup_pkt->req;
    1685                 :            :         dwc_otg_pcd_ep_t *ep = 0;
    1686                 :            : 
    1687                 :            :         DWC_DEBUGPL(DBG_PCD,
    1688                 :            :                     "CLEAR_FEATURE:%02x.%02x v%04x i%04x l%04x\n",
    1689                 :            :                     ctrl.bmRequestType, ctrl.bRequest,
    1690                 :            :                     UGETW(ctrl.wValue), UGETW(ctrl.wIndex),
    1691                 :            :                     UGETW(ctrl.wLength));
    1692                 :            : 
    1693      [ #  #  # ]:          0 :         switch (UT_GET_RECIPIENT(ctrl.bmRequestType)) {
    1694                 :            :         case UT_DEVICE:
    1695      [ #  #  # ]:          0 :                 switch (UGETW(ctrl.wValue)) {
    1696                 :            :                 case UF_DEVICE_REMOTE_WAKEUP:
    1697                 :          0 :                         pcd->remote_wakeup_enable = 0;
    1698                 :          0 :                         break;
    1699                 :            : 
    1700                 :            :                 case UF_TEST_MODE:
    1701                 :            :                         /** @todo Add CLEAR_FEATURE for TEST modes. */
    1702                 :            :                         break;
    1703                 :            : 
    1704                 :            :                 default:
    1705                 :          0 :                         ep0_do_stall(pcd, -DWC_E_NOT_SUPPORTED);
    1706                 :          0 :                         return;
    1707                 :            :                 }
    1708                 :          0 :                 do_setup_in_status_phase(pcd);
    1709                 :          0 :                 break;
    1710                 :            : 
    1711                 :            :         case UT_ENDPOINT:
    1712                 :          0 :                 ep = get_ep_by_addr(pcd, UGETW(ctrl.wIndex));
    1713         [ #  # ]:          0 :                 if (ep == 0) {
    1714                 :          0 :                         ep0_do_stall(pcd, -DWC_E_NOT_SUPPORTED);
    1715                 :          0 :                         return;
    1716                 :            :                 }
    1717                 :            : 
    1718                 :          0 :                 pcd_clear_halt(pcd, ep);
    1719                 :            : 
    1720                 :          0 :                 break;
    1721                 :            :         }
    1722                 :            : }
    1723                 :            : 
    1724                 :            : /**
    1725                 :            :  * This function process the SET_ADDRESS Setup Commands.
    1726                 :            :  */
    1727                 :          0 : static inline void do_set_address(dwc_otg_pcd_t * pcd)
    1728                 :            : {
    1729                 :          0 :         dwc_otg_dev_if_t *dev_if = GET_CORE_IF(pcd)->dev_if;
    1730                 :          0 :         usb_device_request_t ctrl = pcd->setup_pkt->req;
    1731                 :            : 
    1732         [ #  # ]:          0 :         if (ctrl.bmRequestType == UT_DEVICE) {
    1733                 :          0 :                 dcfg_data_t dcfg = {.d32 = 0 };
    1734                 :            : 
    1735                 :            : #ifdef DEBUG_EP0
    1736                 :            : //                      DWC_DEBUGPL(DBG_PCDV, "SET_ADDRESS:%d\n", ctrl.wValue);
    1737                 :            : #endif
    1738                 :          0 :                 dcfg.b.devaddr = UGETW(ctrl.wValue);
    1739                 :          0 :                 DWC_MODIFY_REG32(&dev_if->dev_global_regs->dcfg, 0, dcfg.d32);
    1740                 :          0 :                 do_setup_in_status_phase(pcd);
    1741                 :            :         }
    1742                 :          0 : }
    1743                 :            : 
    1744                 :            : /**
    1745                 :            :  *      This function processes SETUP commands. In Linux, the USB Command
    1746                 :            :  *      processing is done in two places - the first being the PCD and the
    1747                 :            :  *      second in the Gadget Driver (for example, the File-Backed Storage
    1748                 :            :  *      Gadget Driver).
    1749                 :            :  *
    1750                 :            :  * <table>
    1751                 :            :  * <tr><td>Command  </td><td>Driver </td><td>Description</td></tr>
    1752                 :            :  *
    1753                 :            :  * <tr><td>GET_STATUS </td><td>PCD </td><td>Command is processed as
    1754                 :            :  * defined in chapter 9 of the USB 2.0 Specification chapter 9
    1755                 :            :  * </td></tr>
    1756                 :            :  *
    1757                 :            :  * <tr><td>CLEAR_FEATURE </td><td>PCD </td><td>The Device and Endpoint
    1758                 :            :  * requests are the ENDPOINT_HALT feature is procesed, all others the
    1759                 :            :  * interface requests are ignored.</td></tr>
    1760                 :            :  *
    1761                 :            :  * <tr><td>SET_FEATURE </td><td>PCD </td><td>The Device and Endpoint
    1762                 :            :  * requests are processed by the PCD.  Interface requests are passed
    1763                 :            :  * to the Gadget Driver.</td></tr>
    1764                 :            :  *
    1765                 :            :  * <tr><td>SET_ADDRESS </td><td>PCD </td><td>Program the DCFG reg,
    1766                 :            :  * with device address received </td></tr>
    1767                 :            :  *
    1768                 :            :  * <tr><td>GET_DESCRIPTOR </td><td>Gadget Driver </td><td>Return the
    1769                 :            :  * requested descriptor</td></tr>
    1770                 :            :  *
    1771                 :            :  * <tr><td>SET_DESCRIPTOR </td><td>Gadget Driver </td><td>Optional -
    1772                 :            :  * not implemented by any of the existing Gadget Drivers.</td></tr>
    1773                 :            :  *
    1774                 :            :  * <tr><td>SET_CONFIGURATION </td><td>Gadget Driver </td><td>Disable
    1775                 :            :  * all EPs and enable EPs for new configuration.</td></tr>
    1776                 :            :  *
    1777                 :            :  * <tr><td>GET_CONFIGURATION </td><td>Gadget Driver </td><td>Return
    1778                 :            :  * the current configuration</td></tr>
    1779                 :            :  *
    1780                 :            :  * <tr><td>SET_INTERFACE </td><td>Gadget Driver </td><td>Disable all
    1781                 :            :  * EPs and enable EPs for new configuration.</td></tr>
    1782                 :            :  *
    1783                 :            :  * <tr><td>GET_INTERFACE </td><td>Gadget Driver </td><td>Return the
    1784                 :            :  * current interface.</td></tr>
    1785                 :            :  *
    1786                 :            :  * <tr><td>SYNC_FRAME </td><td>PCD </td><td>Display debug
    1787                 :            :  * message.</td></tr>
    1788                 :            :  * </table>
    1789                 :            :  *
    1790                 :            :  * When the SETUP Phase Done interrupt occurs, the PCD SETUP commands are
    1791                 :            :  * processed by pcd_setup. Calling the Function Driver's setup function from
    1792                 :            :  * pcd_setup processes the gadget SETUP commands.
    1793                 :            :  */
    1794                 :          0 : static inline void pcd_setup(dwc_otg_pcd_t * pcd)
    1795                 :            : {
    1796                 :          0 :         dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
    1797                 :          0 :         dwc_otg_dev_if_t *dev_if = core_if->dev_if;
    1798                 :          0 :         usb_device_request_t ctrl = pcd->setup_pkt->req;
    1799                 :          0 :         dwc_otg_pcd_ep_t *ep0 = &pcd->ep0;
    1800                 :            : 
    1801                 :            :         deptsiz0_data_t doeptsize0 = {.d32 = 0 };
    1802                 :            : 
    1803                 :            : #ifdef DWC_UTE_CFI
    1804                 :            :         int retval = 0;
    1805                 :            :         struct cfi_usb_ctrlrequest cfi_req;
    1806                 :            : #endif
    1807                 :            : 
    1808                 :          0 :         doeptsize0.d32 = DWC_READ_REG32(&dev_if->out_ep_regs[0]->doeptsiz);
    1809                 :            : 
    1810                 :            :         /** In BDMA more then 1 setup packet is not supported till 3.00a */
    1811   [ #  #  #  # ]:          0 :         if (core_if->dma_enable && core_if->dma_desc_enable == 0
    1812         [ #  # ]:          0 :             && (doeptsize0.b.supcnt < 2)
    1813         [ #  # ]:          0 :             && (core_if->snpsid < OTG_CORE_REV_2_94a)) {
    1814                 :          0 :                 DWC_ERROR
    1815                 :            :                     ("\n\n-----------       CANNOT handle > 1 setup packet in DMA mode\n\n");
    1816                 :            :         }
    1817         [ #  # ]:          0 :         if ((core_if->snpsid >= OTG_CORE_REV_3_00a)
    1818         [ #  # ]:          0 :             && (core_if->dma_enable == 1) && (core_if->dma_desc_enable == 0)) {
    1819                 :          0 :                 ctrl =
    1820                 :          0 :                     (pcd->setup_pkt +
    1821                 :          0 :                      (3 - doeptsize0.b.supcnt - 1 +
    1822                 :          0 :                       ep0->dwc_ep.stp_rollover))->req;
    1823                 :            :         }
    1824                 :            : #ifdef DEBUG_EP0
    1825                 :            :         DWC_DEBUGPL(DBG_PCD, "SETUP %02x.%02x v%04x i%04x l%04x\n",
    1826                 :            :                     ctrl.bmRequestType, ctrl.bRequest,
    1827                 :            :                     UGETW(ctrl.wValue), UGETW(ctrl.wIndex),
    1828                 :            :                     UGETW(ctrl.wLength));
    1829                 :            : #endif
    1830                 :            : 
    1831                 :            :         /* Clean up the request queue */
    1832                 :          0 :         dwc_otg_request_nuke(ep0);
    1833                 :          0 :         ep0->stopped = 0;
    1834                 :            : 
    1835         [ #  # ]:          0 :         if (ctrl.bmRequestType & UE_DIR_IN) {
    1836                 :          0 :                 ep0->dwc_ep.is_in = 1;
    1837                 :          0 :                 pcd->ep0state = EP0_IN_DATA_PHASE;
    1838                 :            :         } else {
    1839                 :          0 :                 ep0->dwc_ep.is_in = 0;
    1840                 :          0 :                 pcd->ep0state = EP0_OUT_DATA_PHASE;
    1841                 :            :         }
    1842                 :            : 
    1843         [ #  # ]:          0 :         if (UGETW(ctrl.wLength) == 0) {
    1844                 :          0 :                 ep0->dwc_ep.is_in = 1;
    1845                 :          0 :                 pcd->ep0state = EP0_IN_STATUS_PHASE;
    1846                 :            :         }
    1847                 :            : 
    1848         [ #  # ]:          0 :         if (UT_GET_TYPE(ctrl.bmRequestType) != UT_STANDARD) {
    1849                 :            : 
    1850                 :            : #ifdef DWC_UTE_CFI
    1851                 :            :                 DWC_MEMCPY(&cfi_req, &ctrl, sizeof(usb_device_request_t));
    1852                 :            : 
    1853                 :            :                 //printk(KERN_ALERT "CFI: req_type=0x%02x; req=0x%02x\n",
    1854                 :            :                                 ctrl.bRequestType, ctrl.bRequest);
    1855                 :            :                 if (UT_GET_TYPE(cfi_req.bRequestType) == UT_VENDOR) {
    1856                 :            :                         if (cfi_req.bRequest > 0xB0 && cfi_req.bRequest < 0xBF) {
    1857                 :            :                                 retval = cfi_setup(pcd, &cfi_req);
    1858                 :            :                                 if (retval < 0) {
    1859                 :            :                                         ep0_do_stall(pcd, retval);
    1860                 :            :                                         pcd->ep0_pending = 0;
    1861                 :            :                                         return;
    1862                 :            :                                 }
    1863                 :            : 
    1864                 :            :                                 /* if need gadget setup then call it and check the retval */
    1865                 :            :                                 if (pcd->cfi->need_gadget_att) {
    1866                 :            :                                         retval =
    1867                 :            :                                             cfi_gadget_setup(pcd,
    1868                 :            :                                                              &pcd->
    1869                 :            :                                                              cfi->ctrl_req);
    1870                 :            :                                         if (retval < 0) {
    1871                 :            :                                                 pcd->ep0_pending = 0;
    1872                 :            :                                                 return;
    1873                 :            :                                         }
    1874                 :            :                                 }
    1875                 :            : 
    1876                 :            :                                 if (pcd->cfi->need_status_in_complete) {
    1877                 :            :                                         do_setup_in_status_phase(pcd);
    1878                 :            :                                 }
    1879                 :            :                                 return;
    1880                 :            :                         }
    1881                 :            :                 }
    1882                 :            : #endif
    1883                 :            : 
    1884                 :            :                 /* handle non-standard (class/vendor) requests in the gadget driver */
    1885                 :          0 :                 do_gadget_setup(pcd, &ctrl);
    1886                 :          0 :                 return;
    1887                 :            :         }
    1888                 :            : 
    1889                 :            :         /** @todo NGS: Handle bad setup packet? */
    1890                 :            : 
    1891                 :            : ///////////////////////////////////////////
    1892                 :            : //// --- Standard Request handling --- ////
    1893                 :            : 
    1894   [ #  #  #  #  :          0 :         switch (ctrl.bRequest) {
                #  #  # ]
    1895                 :            :         case UR_GET_STATUS:
    1896                 :          0 :                 do_get_status(pcd);
    1897                 :          0 :                 break;
    1898                 :            : 
    1899                 :            :         case UR_CLEAR_FEATURE:
    1900                 :          0 :                 do_clear_feature(pcd);
    1901                 :          0 :                 break;
    1902                 :            : 
    1903                 :            :         case UR_SET_FEATURE:
    1904                 :          0 :                 do_set_feature(pcd);
    1905                 :          0 :                 break;
    1906                 :            : 
    1907                 :            :         case UR_SET_ADDRESS:
    1908                 :          0 :                 do_set_address(pcd);
    1909                 :          0 :                 break;
    1910                 :            : 
    1911                 :            :         case UR_SET_INTERFACE:
    1912                 :            :         case UR_SET_CONFIG:
    1913                 :            : //              _pcd->request_config = 1;       /* Configuration changed */
    1914                 :          0 :                 do_gadget_setup(pcd, &ctrl);
    1915                 :          0 :                 break;
    1916                 :            : 
    1917                 :            :         case UR_SYNCH_FRAME:
    1918                 :          0 :                 do_gadget_setup(pcd, &ctrl);
    1919                 :          0 :                 break;
    1920                 :            : 
    1921                 :            :         default:
    1922                 :            :                 /* Call the Gadget Driver's setup functions */
    1923                 :          0 :                 do_gadget_setup(pcd, &ctrl);
    1924                 :          0 :                 break;
    1925                 :            :         }
    1926                 :            : }
    1927                 :            : 
    1928                 :            : /**
    1929                 :            :  * This function completes the ep0 control transfer.
    1930                 :            :  */
    1931                 :          0 : static int32_t ep0_complete_request(dwc_otg_pcd_ep_t * ep)
    1932                 :            : {
    1933                 :          0 :         dwc_otg_core_if_t *core_if = GET_CORE_IF(ep->pcd);
    1934                 :          0 :         dwc_otg_dev_if_t *dev_if = core_if->dev_if;
    1935                 :          0 :         dwc_otg_dev_in_ep_regs_t *in_ep_regs =
    1936                 :          0 :             dev_if->in_ep_regs[ep->dwc_ep.num];
    1937                 :            : #ifdef DEBUG_EP0
    1938                 :          0 :         dwc_otg_dev_out_ep_regs_t *out_ep_regs =
    1939                 :            :             dev_if->out_ep_regs[ep->dwc_ep.num];
    1940                 :            : #endif
    1941                 :            :         deptsiz0_data_t deptsiz;
    1942                 :            :         dev_dma_desc_sts_t desc_sts;
    1943                 :            :         dwc_otg_pcd_request_t *req;
    1944                 :            :         int is_last = 0;
    1945                 :            :         dwc_otg_pcd_t *pcd = ep->pcd;
    1946                 :            : 
    1947                 :            : #ifdef DWC_UTE_CFI
    1948                 :            :         struct cfi_usb_ctrlrequest *ctrlreq;
    1949                 :            :         int retval = -DWC_E_NOT_SUPPORTED;
    1950                 :            : #endif
    1951                 :            : 
    1952                 :            :         desc_sts.b.bytes = 0;
    1953                 :            : 
    1954   [ #  #  #  # ]:          0 :         if (pcd->ep0_pending && DWC_CIRCLEQ_EMPTY(&ep->queue)) {
    1955         [ #  # ]:          0 :                 if (ep->dwc_ep.is_in) {
    1956                 :            : #ifdef DEBUG_EP0
    1957                 :            :                         DWC_DEBUGPL(DBG_PCDV, "Do setup OUT status phase\n");
    1958                 :            : #endif
    1959                 :          0 :                         do_setup_out_status_phase(pcd);
    1960                 :            :                 } else {
    1961                 :            : #ifdef DEBUG_EP0
    1962                 :            :                         DWC_DEBUGPL(DBG_PCDV, "Do setup IN status phase\n");
    1963                 :            : #endif
    1964                 :            : 
    1965                 :            : #ifdef DWC_UTE_CFI
    1966                 :            :                         ctrlreq = &pcd->cfi->ctrl_req;
    1967                 :            : 
    1968                 :            :                         if (UT_GET_TYPE(ctrlreq->bRequestType) == UT_VENDOR) {
    1969                 :            :                                 if (ctrlreq->bRequest > 0xB0
    1970                 :            :                                     && ctrlreq->bRequest < 0xBF) {
    1971                 :            : 
    1972                 :            :                                         /* Return if the PCD failed to handle the request */
    1973                 :            :                                         if ((retval =
    1974                 :            :                                              pcd->cfi->ops.
    1975                 :            :                                              ctrl_write_complete(pcd->cfi,
    1976                 :            :                                                                  pcd)) < 0) {
    1977                 :            :                                                 CFI_INFO
    1978                 :            :                                                     ("ERROR setting a new value in the PCD(%d)\n",
    1979                 :            :                                                      retval);
    1980                 :            :                                                 ep0_do_stall(pcd, retval);
    1981                 :            :                                                 pcd->ep0_pending = 0;
    1982                 :            :                                                 return 0;
    1983                 :            :                                         }
    1984                 :            : 
    1985                 :            :                                         /* If the gadget needs to be notified on the request */
    1986                 :            :                                         if (pcd->cfi->need_gadget_att == 1) {
    1987                 :            :                                                 //retval = do_gadget_setup(pcd, &pcd->cfi->ctrl_req);
    1988                 :            :                                                 retval =
    1989                 :            :                                                     cfi_gadget_setup(pcd,
    1990                 :            :                                                                      &pcd->cfi->
    1991                 :            :                                                                      ctrl_req);
    1992                 :            : 
    1993                 :            :                                                 /* Return from the function if the gadget failed to process
    1994                 :            :                                                  * the request properly - this should never happen !!!
    1995                 :            :                                                  */
    1996                 :            :                                                 if (retval < 0) {
    1997                 :            :                                                         CFI_INFO
    1998                 :            :                                                             ("ERROR setting a new value in the gadget(%d)\n",
    1999                 :            :                                                              retval);
    2000                 :            :                                                         pcd->ep0_pending = 0;
    2001                 :            :                                                         return 0;
    2002                 :            :                                                 }
    2003                 :            :                                         }
    2004                 :            : 
    2005                 :            :                                         CFI_INFO("%s: RETVAL=%d\n", __func__,
    2006                 :            :                                                  retval);
    2007                 :            :                                         /* If we hit here then the PCD and the gadget has properly
    2008                 :            :                                          * handled the request - so send the ZLP IN to the host.
    2009                 :            :                                          */
    2010                 :            :                                         /* @todo: MAS - decide whether we need to start the setup
    2011                 :            :                                          * stage based on the need_setup value of the cfi object
    2012                 :            :                                          */
    2013                 :            :                                         do_setup_in_status_phase(pcd);
    2014                 :            :                                         pcd->ep0_pending = 0;
    2015                 :            :                                         return 1;
    2016                 :            :                                 }
    2017                 :            :                         }
    2018                 :            : #endif
    2019                 :            : 
    2020                 :          0 :                         do_setup_in_status_phase(pcd);
    2021                 :            :                 }
    2022                 :          0 :                 pcd->ep0_pending = 0;
    2023                 :          0 :                 return 1;
    2024                 :            :         }
    2025                 :            : 
    2026         [ #  # ]:          0 :         if (DWC_CIRCLEQ_EMPTY(&ep->queue)) {
    2027                 :            :                 return 0;
    2028                 :            :         }
    2029                 :            :         req = DWC_CIRCLEQ_FIRST(&ep->queue);
    2030                 :            : 
    2031         [ #  # ]:          0 :         if (pcd->ep0state == EP0_OUT_STATUS_PHASE
    2032                 :          0 :             || pcd->ep0state == EP0_IN_STATUS_PHASE) {
    2033                 :            :                 is_last = 1;
    2034         [ #  # ]:          0 :         } else if (ep->dwc_ep.is_in) {
    2035                 :          0 :                 deptsiz.d32 = DWC_READ_REG32(&in_ep_regs->dieptsiz);
    2036         [ #  # ]:          0 :                 if (core_if->dma_desc_enable != 0)
    2037                 :          0 :                         desc_sts = dev_if->in_desc_addr->status;
    2038                 :            : #ifdef DEBUG_EP0
    2039                 :            :                 DWC_DEBUGPL(DBG_PCDV, "%d len=%d  xfersize=%d pktcnt=%d\n",
    2040                 :            :                             ep->dwc_ep.num, ep->dwc_ep.xfer_len,
    2041                 :            :                             deptsiz.b.xfersize, deptsiz.b.pktcnt);
    2042                 :            : #endif
    2043                 :            : 
    2044         [ #  # ]:          0 :                 if (((core_if->dma_desc_enable == 0)
    2045         [ #  # ]:          0 :                      && (deptsiz.b.xfersize == 0))
    2046         [ #  # ]:          0 :                     || ((core_if->dma_desc_enable != 0)
    2047         [ #  # ]:          0 :                         && (desc_sts.b.bytes == 0))) {
    2048                 :          0 :                         req->actual = ep->dwc_ep.xfer_count;
    2049                 :            :                         /* Is a Zero Len Packet needed? */
    2050         [ #  # ]:          0 :                         if (req->sent_zlp) {
    2051                 :            : #ifdef DEBUG_EP0
    2052                 :            :                                 DWC_DEBUGPL(DBG_PCD, "Setup Rx ZLP\n");
    2053                 :            : #endif
    2054                 :          0 :                                 req->sent_zlp = 0;
    2055                 :            :                         }
    2056                 :          0 :                         do_setup_out_status_phase(pcd);
    2057                 :            :                 }
    2058                 :            :         } else {
    2059                 :            :                 /* ep0-OUT */
    2060                 :            : #ifdef DEBUG_EP0
    2061                 :          0 :                 deptsiz.d32 = DWC_READ_REG32(&out_ep_regs->doeptsiz);
    2062                 :            :                 DWC_DEBUGPL(DBG_PCDV, "%d len=%d xsize=%d pktcnt=%d\n",
    2063                 :            :                             ep->dwc_ep.num, ep->dwc_ep.xfer_len,
    2064                 :            :                             deptsiz.b.xfersize, deptsiz.b.pktcnt);
    2065                 :            : #endif
    2066                 :          0 :                 req->actual = ep->dwc_ep.xfer_count;
    2067                 :            : 
    2068                 :            :                 /* Is a Zero Len Packet needed? */
    2069         [ #  # ]:          0 :                 if (req->sent_zlp) {
    2070                 :            : #ifdef DEBUG_EP0
    2071                 :            :                         DWC_DEBUGPL(DBG_PCDV, "Setup Tx ZLP\n");
    2072                 :            : #endif
    2073                 :          0 :                         req->sent_zlp = 0;
    2074                 :            :                 }
    2075                 :            :                 /* For older cores do setup in status phase in Slave/BDMA modes,
    2076                 :            :                  * starting from 3.00 do that only in slave, and for DMA modes
    2077                 :            :                  * just re-enable ep 0 OUT here*/
    2078         [ #  # ]:          0 :                 if (core_if->dma_enable == 0
    2079         [ #  # ]:          0 :                     || (core_if->dma_desc_enable == 0
    2080         [ #  # ]:          0 :                         && core_if->snpsid <= OTG_CORE_REV_2_94a)) {
    2081                 :          0 :                         do_setup_in_status_phase(pcd);
    2082         [ #  # ]:          0 :                 } else if (core_if->snpsid >= OTG_CORE_REV_3_00a) {
    2083                 :            :                         DWC_DEBUGPL(DBG_PCDV,
    2084                 :            :                                     "Enable out ep before in status phase\n");
    2085                 :          0 :                         ep0_out_start(core_if, pcd);
    2086                 :            :                 }
    2087                 :            :         }
    2088                 :            : 
    2089                 :            :         /* Complete the request */
    2090         [ #  # ]:          0 :         if (is_last) {
    2091                 :          0 :                 dwc_otg_request_done(ep, req, 0);
    2092                 :          0 :                 ep->dwc_ep.start_xfer_buff = 0;
    2093                 :          0 :                 ep->dwc_ep.xfer_buff = 0;
    2094                 :          0 :                 ep->dwc_ep.xfer_len = 0;
    2095                 :          0 :                 return 1;
    2096                 :            :         }
    2097                 :            :         return 0;
    2098                 :            : }
    2099                 :            : 
    2100                 :            : #ifdef DWC_UTE_CFI
    2101                 :            : /**
    2102                 :            :  * This function calculates traverses all the CFI DMA descriptors and
    2103                 :            :  * and accumulates the bytes that are left to be transfered.
    2104                 :            :  *
    2105                 :            :  * @return The total bytes left to transfered, or a negative value as failure
    2106                 :            :  */
    2107                 :            : static inline int cfi_calc_desc_residue(dwc_otg_pcd_ep_t * ep)
    2108                 :            : {
    2109                 :            :         int32_t ret = 0;
    2110                 :            :         int i;
    2111                 :            :         struct dwc_otg_dma_desc *ddesc = NULL;
    2112                 :            :         struct cfi_ep *cfiep;
    2113                 :            : 
    2114                 :            :         /* See if the pcd_ep has its respective cfi_ep mapped */
    2115                 :            :         cfiep = get_cfi_ep_by_pcd_ep(ep->pcd->cfi, ep);
    2116                 :            :         if (!cfiep) {
    2117                 :            :                 CFI_INFO("%s: Failed to find ep\n", __func__);
    2118                 :            :                 return -1;
    2119                 :            :         }
    2120                 :            : 
    2121                 :            :         ddesc = ep->dwc_ep.descs;
    2122                 :            : 
    2123                 :            :         for (i = 0; (i < cfiep->desc_count) && (i < MAX_DMA_DESCS_PER_EP); i++) {
    2124                 :            : 
    2125                 :            : #if defined(PRINT_CFI_DMA_DESCS)
    2126                 :            :                 print_desc(ddesc, ep->ep.name, i);
    2127                 :            : #endif
    2128                 :            :                 ret += ddesc->status.b.bytes;
    2129                 :            :                 ddesc++;
    2130                 :            :         }
    2131                 :            : 
    2132                 :            :         if (ret)
    2133                 :            :                 CFI_INFO("!!!!!!!!!! WARNING (%s) - residue=%d\n", __func__,
    2134                 :            :                          ret);
    2135                 :            : 
    2136                 :            :         return ret;
    2137                 :            : }
    2138                 :            : #endif
    2139                 :            : 
    2140                 :            : /**
    2141                 :            :  * This function completes the request for the EP. If there are
    2142                 :            :  * additional requests for the EP in the queue they will be started.
    2143                 :            :  */
    2144                 :          0 : static void complete_ep(dwc_otg_pcd_ep_t * ep)
    2145                 :            : {
    2146                 :          0 :         dwc_otg_core_if_t *core_if = GET_CORE_IF(ep->pcd);
    2147                 :            :         struct device *dev = dwc_otg_pcd_to_dev(ep->pcd);
    2148                 :          0 :         dwc_otg_dev_if_t *dev_if = core_if->dev_if;
    2149                 :          0 :         dwc_otg_dev_in_ep_regs_t *in_ep_regs =
    2150                 :          0 :             dev_if->in_ep_regs[ep->dwc_ep.num];
    2151                 :            :         deptsiz_data_t deptsiz;
    2152                 :            :         dev_dma_desc_sts_t desc_sts;
    2153                 :            :         dwc_otg_pcd_request_t *req = 0;
    2154                 :            :         dwc_otg_dev_dma_desc_t *dma_desc;
    2155                 :            :         uint32_t byte_count = 0;
    2156                 :            :         int is_last = 0;
    2157                 :            :         int i;
    2158                 :            : 
    2159                 :            :         DWC_DEBUGPL(DBG_PCDV, "%s() %d-%s\n", __func__, ep->dwc_ep.num,
    2160                 :            :                     (ep->dwc_ep.is_in ? "IN" : "OUT"));
    2161                 :            : 
    2162                 :            :         /* Get any pending requests */
    2163         [ #  # ]:          0 :         if (!DWC_CIRCLEQ_EMPTY(&ep->queue)) {
    2164                 :            :                 req = DWC_CIRCLEQ_FIRST(&ep->queue);
    2165         [ #  # ]:          0 :                 if (!req) {
    2166                 :          0 :                         DWC_PRINTF("complete_ep 0x%p, req = NULL!\n", ep);
    2167                 :          0 :                         return;
    2168                 :            :                 }
    2169                 :            :         } else {
    2170                 :          0 :                 DWC_PRINTF("complete_ep 0x%p, ep->queue empty!\n", ep);
    2171                 :          0 :                 return;
    2172                 :            :         }
    2173                 :            : 
    2174                 :            :         DWC_DEBUGPL(DBG_PCD, "Requests %d\n", ep->pcd->request_pending);
    2175                 :            : 
    2176         [ #  # ]:          0 :         if (ep->dwc_ep.is_in) {
    2177                 :          0 :                 deptsiz.d32 = DWC_READ_REG32(&in_ep_regs->dieptsiz);
    2178                 :            : 
    2179         [ #  # ]:          0 :                 if (core_if->dma_enable) {
    2180         [ #  # ]:          0 :                         if (core_if->dma_desc_enable == 0) {
    2181         [ #  # ]:          0 :                                 if (deptsiz.b.xfersize == 0
    2182                 :          0 :                                     && deptsiz.b.pktcnt == 0) {
    2183                 :          0 :                                         byte_count =
    2184                 :          0 :                                             ep->dwc_ep.xfer_len -
    2185                 :          0 :                                             ep->dwc_ep.xfer_count;
    2186                 :            : 
    2187                 :          0 :                                         ep->dwc_ep.xfer_buff += byte_count;
    2188                 :          0 :                                         ep->dwc_ep.dma_addr += byte_count;
    2189                 :          0 :                                         ep->dwc_ep.xfer_count += byte_count;
    2190                 :            : 
    2191                 :            :                                         DWC_DEBUGPL(DBG_PCDV,
    2192                 :            :                                                     "%d-%s len=%d  xfersize=%d pktcnt=%d\n",
    2193                 :            :                                                     ep->dwc_ep.num,
    2194                 :            :                                                     (ep->dwc_ep.
    2195                 :            :                                                      is_in ? "IN" : "OUT"),
    2196                 :            :                                                     ep->dwc_ep.xfer_len,
    2197                 :            :                                                     deptsiz.b.xfersize,
    2198                 :            :                                                     deptsiz.b.pktcnt);
    2199                 :            : 
    2200         [ #  # ]:          0 :                                         if (ep->dwc_ep.xfer_len <
    2201                 :          0 :                                             ep->dwc_ep.total_len) {
    2202                 :          0 :                                                 dwc_otg_ep_start_transfer
    2203                 :            :                                                     (core_if, &ep->dwc_ep);
    2204         [ #  # ]:          0 :                                         } else if (ep->dwc_ep.sent_zlp) {
    2205                 :            :                                                 /*
    2206                 :            :                                                  * This fragment of code should initiate 0
    2207                 :            :                                                  * length transfer in case if it is queued
    2208                 :            :                                                  * a transfer with size divisible to EPs max
    2209                 :            :                                                  * packet size and with usb_request zero field
    2210                 :            :                                                  * is set, which means that after data is transfered,
    2211                 :            :                                                  * it is also should be transfered
    2212                 :            :                                                  * a 0 length packet at the end. For Slave and
    2213                 :            :                                                  * Buffer DMA modes in this case SW has
    2214                 :            :                                                  * to initiate 2 transfers one with transfer size,
    2215                 :            :                                                  * and the second with 0 size. For Descriptor
    2216                 :            :                                                  * DMA mode SW is able to initiate a transfer,
    2217                 :            :                                                  * which will handle all the packets including
    2218                 :            :                                                  * the last  0 length.
    2219                 :            :                                                  */
    2220                 :          0 :                                                 ep->dwc_ep.sent_zlp = 0;
    2221                 :          0 :                                                 dwc_otg_ep_start_zl_transfer
    2222                 :            :                                                     (core_if, &ep->dwc_ep);
    2223                 :            :                                         } else {
    2224                 :            :                                                 is_last = 1;
    2225                 :            :                                         }
    2226                 :            :                                 } else {
    2227         [ #  # ]:          0 :                                         if (ep->dwc_ep.type ==
    2228                 :            :                                             DWC_OTG_EP_TYPE_ISOC) {
    2229                 :          0 :                                                 req->actual = 0;
    2230                 :          0 :                                                 dwc_otg_request_done(ep, req, 0);
    2231                 :            : 
    2232                 :          0 :                                                 ep->dwc_ep.start_xfer_buff = 0;
    2233                 :          0 :                                                 ep->dwc_ep.xfer_buff = 0;
    2234                 :          0 :                                                 ep->dwc_ep.xfer_len = 0;
    2235                 :            : 
    2236                 :            :                                                 /* If there is a request in the queue start it. */
    2237                 :          0 :                                                 start_next_request(ep);
    2238                 :            :                                         } else
    2239         [ #  # ]:          0 :                                                 DWC_WARN
    2240                 :            :                                                 ("Incomplete transfer (%d - %s [siz=%d pkt=%d])\n",
    2241                 :            :                                                 ep->dwc_ep.num,
    2242                 :            :                                                 (ep->dwc_ep.is_in ? "IN" : "OUT"),
    2243                 :            :                                                 deptsiz.b.xfersize,
    2244                 :            :                                                 deptsiz.b.pktcnt);
    2245                 :            :                                 }
    2246                 :            :                         } else {
    2247                 :          0 :                                 dma_desc = ep->dwc_ep.desc_addr;
    2248                 :            :                                 byte_count = 0;
    2249                 :          0 :                                 ep->dwc_ep.sent_zlp = 0;
    2250                 :            : 
    2251                 :            : #ifdef DWC_UTE_CFI
    2252                 :            :                                 CFI_INFO("%s: BUFFER_MODE=%d\n", __func__,
    2253                 :            :                                          ep->dwc_ep.buff_mode);
    2254                 :            :                                 if (ep->dwc_ep.buff_mode != BM_STANDARD) {
    2255                 :            :                                         int residue;
    2256                 :            : 
    2257                 :            :                                         residue = cfi_calc_desc_residue(ep);
    2258                 :            :                                         if (residue < 0)
    2259                 :            :                                                 return;
    2260                 :            : 
    2261                 :            :                                         byte_count = residue;
    2262                 :            :                                 } else {
    2263                 :            : #endif
    2264         [ #  # ]:          0 :                                         for (i = 0; i < ep->dwc_ep.desc_cnt;
    2265                 :          0 :                                              ++i) {
    2266                 :          0 :                                         desc_sts = dma_desc->status;
    2267                 :          0 :                                         byte_count += desc_sts.b.bytes;
    2268                 :          0 :                                         dma_desc++;
    2269                 :            :                                 }
    2270                 :            : #ifdef DWC_UTE_CFI
    2271                 :            :                                 }
    2272                 :            : #endif
    2273         [ #  # ]:          0 :                                 if (byte_count == 0) {
    2274                 :          0 :                                         ep->dwc_ep.xfer_count =
    2275                 :          0 :                                             ep->dwc_ep.total_len;
    2276                 :            :                                         is_last = 1;
    2277                 :            :                                 } else {
    2278                 :          0 :                                         DWC_WARN("Incomplete transfer\n");
    2279                 :            :                                 }
    2280                 :            :                         }
    2281                 :            :                 } else {
    2282         [ #  # ]:          0 :                         if (deptsiz.b.xfersize == 0 && deptsiz.b.pktcnt == 0) {
    2283                 :            :                                 DWC_DEBUGPL(DBG_PCDV,
    2284                 :            :                                             "%d-%s len=%d  xfersize=%d pktcnt=%d\n",
    2285                 :            :                                             ep->dwc_ep.num,
    2286                 :            :                                             ep->dwc_ep.is_in ? "IN" : "OUT",
    2287                 :            :                                             ep->dwc_ep.xfer_len,
    2288                 :            :                                             deptsiz.b.xfersize,
    2289                 :            :                                             deptsiz.b.pktcnt);
    2290                 :            : 
    2291                 :            :                                 /*      Check if the whole transfer was completed,
    2292                 :            :                                  *      if no, setup transfer for next portion of data
    2293                 :            :                                  */
    2294         [ #  # ]:          0 :                                 if (ep->dwc_ep.xfer_len < ep->dwc_ep.total_len) {
    2295                 :          0 :                                         dwc_otg_ep_start_transfer(core_if,
    2296                 :            :                                                                   &ep->dwc_ep);
    2297         [ #  # ]:          0 :                                 } else if (ep->dwc_ep.sent_zlp) {
    2298                 :            :                                         /*
    2299                 :            :                                          * This fragment of code should initiate 0
    2300                 :            :                                          * length trasfer in case if it is queued
    2301                 :            :                                          * a trasfer with size divisible to EPs max
    2302                 :            :                                          * packet size and with usb_request zero field
    2303                 :            :                                          * is set, which means that after data is transfered,
    2304                 :            :                                          * it is also should be transfered
    2305                 :            :                                          * a 0 length packet at the end. For Slave and
    2306                 :            :                                          * Buffer DMA modes in this case SW has
    2307                 :            :                                          * to initiate 2 transfers one with transfer size,
    2308                 :            :                                          * and the second with 0 size. For Desriptor
    2309                 :            :                                          * DMA mode SW is able to initiate a transfer,
    2310                 :            :                                          * which will handle all the packets including
    2311                 :            :                                          * the last  0 legth.
    2312                 :            :                                          */
    2313                 :          0 :                                         ep->dwc_ep.sent_zlp = 0;
    2314                 :          0 :                                         dwc_otg_ep_start_zl_transfer(core_if,
    2315                 :            :                                                                      &ep->dwc_ep);
    2316                 :            :                                 } else {
    2317                 :            :                                         is_last = 1;
    2318                 :            :                                 }
    2319                 :            :                         } else {
    2320         [ #  # ]:          0 :                                 DWC_WARN
    2321                 :            :                                     ("Incomplete transfer (%d-%s [siz=%d pkt=%d])\n",
    2322                 :            :                                      ep->dwc_ep.num,
    2323                 :            :                                      (ep->dwc_ep.is_in ? "IN" : "OUT"),
    2324                 :            :                                      deptsiz.b.xfersize, deptsiz.b.pktcnt);
    2325                 :            :                         }
    2326                 :            :                 }
    2327                 :            :         } else {
    2328                 :          0 :                 dwc_otg_dev_out_ep_regs_t *out_ep_regs =
    2329                 :            :                     dev_if->out_ep_regs[ep->dwc_ep.num];
    2330                 :            :                 desc_sts.d32 = 0;
    2331         [ #  # ]:          0 :                 if (core_if->dma_enable) {
    2332         [ #  # ]:          0 :                         if (core_if->dma_desc_enable) {
    2333                 :          0 :                                 dma_desc = ep->dwc_ep.desc_addr;
    2334                 :            :                                 byte_count = 0;
    2335                 :          0 :                                 ep->dwc_ep.sent_zlp = 0;
    2336                 :            : 
    2337                 :            : #ifdef DWC_UTE_CFI
    2338                 :            :                                 CFI_INFO("%s: BUFFER_MODE=%d\n", __func__,
    2339                 :            :                                          ep->dwc_ep.buff_mode);
    2340                 :            :                                 if (ep->dwc_ep.buff_mode != BM_STANDARD) {
    2341                 :            :                                         int residue;
    2342                 :            :                                         residue = cfi_calc_desc_residue(ep);
    2343                 :            :                                         if (residue < 0)
    2344                 :            :                                                 return;
    2345                 :            :                                         byte_count = residue;
    2346                 :            :                                 } else {
    2347                 :            : #endif
    2348                 :            : 
    2349         [ #  # ]:          0 :                                         for (i = 0; i < ep->dwc_ep.desc_cnt;
    2350                 :          0 :                                              ++i) {
    2351                 :          0 :                                                 desc_sts = dma_desc->status;
    2352                 :          0 :                                                 byte_count += desc_sts.b.bytes;
    2353                 :          0 :                                                 dma_desc++;
    2354                 :            :                                         }
    2355                 :            : 
    2356                 :            : #ifdef DWC_UTE_CFI
    2357                 :            :                                 }
    2358                 :            : #endif
    2359                 :            :                                 /* Checking for interrupt Out transfers with not
    2360                 :            :                                  * dword aligned mps sizes
    2361                 :            :                                  */
    2362   [ #  #  #  # ]:          0 :                                 if (ep->dwc_ep.type == DWC_OTG_EP_TYPE_INTR &&
    2363                 :          0 :                                                         (ep->dwc_ep.maxpacket%4)) {
    2364                 :          0 :                                         ep->dwc_ep.xfer_count =
    2365                 :          0 :                                             ep->dwc_ep.total_len - byte_count;
    2366         [ #  # ]:          0 :                                         if ((ep->dwc_ep.xfer_len %
    2367                 :            :                                              ep->dwc_ep.maxpacket)
    2368         [ #  # ]:          0 :                                             && (ep->dwc_ep.xfer_len /
    2369                 :            :                                                 ep->dwc_ep.maxpacket <
    2370                 :            :                                                 MAX_DMA_DESC_CNT))
    2371                 :          0 :                                                 ep->dwc_ep.xfer_len -=
    2372                 :          0 :                                                     (ep->dwc_ep.desc_cnt -
    2373                 :          0 :                                                      1) * ep->dwc_ep.maxpacket +
    2374                 :            :                                                     ep->dwc_ep.xfer_len %
    2375                 :            :                                                     ep->dwc_ep.maxpacket;
    2376                 :            :                                         else
    2377                 :          0 :                                                 ep->dwc_ep.xfer_len -=
    2378                 :          0 :                                                     ep->dwc_ep.desc_cnt *
    2379                 :            :                                                     ep->dwc_ep.maxpacket;
    2380         [ #  # ]:          0 :                                         if (ep->dwc_ep.xfer_len > 0) {
    2381                 :          0 :                                                 dwc_otg_ep_start_transfer
    2382                 :            :                                                     (core_if, &ep->dwc_ep);
    2383                 :            :                                         } else {
    2384                 :            :                                                 is_last = 1;
    2385                 :            :                                         }
    2386                 :            :                                 } else {
    2387                 :          0 :                                         ep->dwc_ep.xfer_count =
    2388                 :          0 :                                             ep->dwc_ep.total_len - byte_count +
    2389                 :            :                                             ((4 -
    2390                 :            :                                               (ep->dwc_ep.
    2391                 :            :                                                total_len & 0x3)) & 0x3);
    2392                 :            :                                         is_last = 1;
    2393                 :            :                                 }
    2394                 :            :                         } else {
    2395                 :            :                                 deptsiz.d32 = 0;
    2396                 :          0 :                                 deptsiz.d32 =
    2397                 :          0 :                                     DWC_READ_REG32(&out_ep_regs->doeptsiz);
    2398                 :            : 
    2399                 :          0 :                                 byte_count = (ep->dwc_ep.xfer_len -
    2400                 :          0 :                                               ep->dwc_ep.xfer_count -
    2401                 :          0 :                                               deptsiz.b.xfersize);
    2402                 :          0 :                                 ep->dwc_ep.xfer_buff += byte_count;
    2403                 :          0 :                                 ep->dwc_ep.dma_addr += byte_count;
    2404                 :          0 :                                 ep->dwc_ep.xfer_count += byte_count;
    2405                 :            : 
    2406                 :            :                                 /*      Check if the whole transfer was completed,
    2407                 :            :                                  *      if no, setup transfer for next portion of data
    2408                 :            :                                  */
    2409         [ #  # ]:          0 :                                 if (ep->dwc_ep.xfer_len < ep->dwc_ep.total_len) {
    2410                 :          0 :                                         dwc_otg_ep_start_transfer(core_if,
    2411                 :            :                                                                   &ep->dwc_ep);
    2412         [ #  # ]:          0 :                                 } else if (ep->dwc_ep.sent_zlp) {
    2413                 :            :                                         /*
    2414                 :            :                                          * This fragment of code should initiate 0
    2415                 :            :                                          * length trasfer in case if it is queued
    2416                 :            :                                          * a trasfer with size divisible to EPs max
    2417                 :            :                                          * packet size and with usb_request zero field
    2418                 :            :                                          * is set, which means that after data is transfered,
    2419                 :            :                                          * it is also should be transfered
    2420                 :            :                                          * a 0 length packet at the end. For Slave and
    2421                 :            :                                          * Buffer DMA modes in this case SW has
    2422                 :            :                                          * to initiate 2 transfers one with transfer size,
    2423                 :            :                                          * and the second with 0 size. For Desriptor
    2424                 :            :                                          * DMA mode SW is able to initiate a transfer,
    2425                 :            :                                          * which will handle all the packets including
    2426                 :            :                                          * the last  0 legth.
    2427                 :            :                                          */
    2428                 :          0 :                                         ep->dwc_ep.sent_zlp = 0;
    2429                 :          0 :                                         dwc_otg_ep_start_zl_transfer(core_if,
    2430                 :            :                                                                      &ep->dwc_ep);
    2431                 :            :                                 } else {
    2432                 :            :                                         is_last = 1;
    2433                 :            :                                 }
    2434                 :            :                         }
    2435                 :            :                 } else {
    2436                 :            :                         /*      Check if the whole transfer was completed,
    2437                 :            :                          *      if no, setup transfer for next portion of data
    2438                 :            :                          */
    2439         [ #  # ]:          0 :                         if (ep->dwc_ep.xfer_len < ep->dwc_ep.total_len) {
    2440                 :          0 :                                 dwc_otg_ep_start_transfer(core_if, &ep->dwc_ep);
    2441         [ #  # ]:          0 :                         } else if (ep->dwc_ep.sent_zlp) {
    2442                 :            :                                 /*
    2443                 :            :                                  * This fragment of code should initiate 0
    2444                 :            :                                  * length transfer in case if it is queued
    2445                 :            :                                  * a transfer with size divisible to EPs max
    2446                 :            :                                  * packet size and with usb_request zero field
    2447                 :            :                                  * is set, which means that after data is transfered,
    2448                 :            :                                  * it is also should be transfered
    2449                 :            :                                  * a 0 length packet at the end. For Slave and
    2450                 :            :                                  * Buffer DMA modes in this case SW has
    2451                 :            :                                  * to initiate 2 transfers one with transfer size,
    2452                 :            :                                  * and the second with 0 size. For Descriptor
    2453                 :            :                                  * DMA mode SW is able to initiate a transfer,
    2454                 :            :                                  * which will handle all the packets including
    2455                 :            :                                  * the last  0 length.
    2456                 :            :                                  */
    2457                 :          0 :                                 ep->dwc_ep.sent_zlp = 0;
    2458                 :          0 :                                 dwc_otg_ep_start_zl_transfer(core_if,
    2459                 :            :                                                              &ep->dwc_ep);
    2460                 :            :                         } else {
    2461                 :            :                                 is_last = 1;
    2462                 :            :                         }
    2463                 :            :                 }
    2464                 :            : 
    2465                 :            :                 DWC_DEBUGPL(DBG_PCDV,
    2466                 :            :                             "addr %p,       %d-%s len=%d cnt=%d xsize=%d pktcnt=%d\n",
    2467                 :            :                             &out_ep_regs->doeptsiz, ep->dwc_ep.num,
    2468                 :            :                             ep->dwc_ep.is_in ? "IN" : "OUT",
    2469                 :            :                             ep->dwc_ep.xfer_len, ep->dwc_ep.xfer_count,
    2470                 :            :                             deptsiz.b.xfersize, deptsiz.b.pktcnt);
    2471                 :            :         }
    2472                 :            : 
    2473                 :            :         /* Complete the request */
    2474         [ #  # ]:          0 :         if (is_last) {
    2475                 :            : #ifdef DWC_UTE_CFI
    2476                 :            :                 if (ep->dwc_ep.buff_mode != BM_STANDARD) {
    2477                 :            :                         req->actual = ep->dwc_ep.cfi_req_len - byte_count;
    2478                 :            :                 } else {
    2479                 :            : #endif
    2480                 :          0 :                         req->actual = ep->dwc_ep.xfer_count;
    2481                 :            : #ifdef DWC_UTE_CFI
    2482                 :            :                 }
    2483                 :            : #endif
    2484         [ #  # ]:          0 :                 if (req->dw_align_buf) {
    2485         [ #  # ]:          0 :                         if (!ep->dwc_ep.is_in) {
    2486                 :          0 :                                 dwc_memcpy(req->buf, req->dw_align_buf, req->length);
    2487                 :            :                         }
    2488                 :          0 :                         DWC_DMA_FREE(dev, req->length, req->dw_align_buf,
    2489                 :            :                                      req->dw_align_buf_dma);
    2490                 :            :                 }
    2491                 :            : 
    2492                 :          0 :                 dwc_otg_request_done(ep, req, 0);
    2493                 :            : 
    2494                 :          0 :                 ep->dwc_ep.start_xfer_buff = 0;
    2495                 :          0 :                 ep->dwc_ep.xfer_buff = 0;
    2496                 :          0 :                 ep->dwc_ep.xfer_len = 0;
    2497                 :            : 
    2498                 :            :                 /* If there is a request in the queue start it. */
    2499                 :          0 :                 start_next_request(ep);
    2500                 :            :         }
    2501                 :            : }
    2502                 :            : 
    2503                 :            : #ifdef DWC_EN_ISOC
    2504                 :            : 
    2505                 :            : /**
    2506                 :            :  * This function BNA interrupt for Isochronous EPs
    2507                 :            :  *
    2508                 :            :  */
    2509                 :            : static void dwc_otg_pcd_handle_iso_bna(dwc_otg_pcd_ep_t * ep)
    2510                 :            : {
    2511                 :            :         dwc_ep_t *dwc_ep = &ep->dwc_ep;
    2512                 :            :         volatile uint32_t *addr;
    2513                 :            :         depctl_data_t depctl = {.d32 = 0 };
    2514                 :            :         dwc_otg_pcd_t *pcd = ep->pcd;
    2515                 :            :         dwc_otg_dev_dma_desc_t *dma_desc;
    2516                 :            :         int i;
    2517                 :            : 
    2518                 :            :         dma_desc =
    2519                 :            :             dwc_ep->iso_desc_addr + dwc_ep->desc_cnt * (dwc_ep->proc_buf_num);
    2520                 :            : 
    2521                 :            :         if (dwc_ep->is_in) {
    2522                 :            :                 dev_dma_desc_sts_t sts = {.d32 = 0 };
    2523                 :            :                 for (i = 0; i < dwc_ep->desc_cnt; ++i, ++dma_desc) {
    2524                 :            :                         sts.d32 = dma_desc->status.d32;
    2525                 :            :                         sts.b_iso_in.bs = BS_HOST_READY;
    2526                 :            :                         dma_desc->status.d32 = sts.d32;
    2527                 :            :                 }
    2528                 :            :         } else {
    2529                 :            :                 dev_dma_desc_sts_t sts = {.d32 = 0 };
    2530                 :            :                 for (i = 0; i < dwc_ep->desc_cnt; ++i, ++dma_desc) {
    2531                 :            :                         sts.d32 = dma_desc->status.d32;
    2532                 :            :                         sts.b_iso_out.bs = BS_HOST_READY;
    2533                 :            :                         dma_desc->status.d32 = sts.d32;
    2534                 :            :                 }
    2535                 :            :         }
    2536                 :            : 
    2537                 :            :         if (dwc_ep->is_in == 0) {
    2538                 :            :                 addr =
    2539                 :            :                     &GET_CORE_IF(pcd)->dev_if->out_ep_regs[dwc_ep->
    2540                 :            :                                                            num]->doepctl;
    2541                 :            :         } else {
    2542                 :            :                 addr =
    2543                 :            :                     &GET_CORE_IF(pcd)->dev_if->in_ep_regs[dwc_ep->num]->diepctl;
    2544                 :            :         }
    2545                 :            :         depctl.b.epena = 1;
    2546                 :            :         DWC_MODIFY_REG32(addr, depctl.d32, depctl.d32);
    2547                 :            : }
    2548                 :            : 
    2549                 :            : /**
    2550                 :            :  * This function sets latest iso packet information(non-PTI mode)
    2551                 :            :  *
    2552                 :            :  * @param core_if Programming view of DWC_otg controller.
    2553                 :            :  * @param ep The EP to start the transfer on.
    2554                 :            :  *
    2555                 :            :  */
    2556                 :            : void set_current_pkt_info(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
    2557                 :            : {
    2558                 :            :         deptsiz_data_t deptsiz = {.d32 = 0 };
    2559                 :            :         dma_addr_t dma_addr;
    2560                 :            :         uint32_t offset;
    2561                 :            : 
    2562                 :            :         if (ep->proc_buf_num)
    2563                 :            :                 dma_addr = ep->dma_addr1;
    2564                 :            :         else
    2565                 :            :                 dma_addr = ep->dma_addr0;
    2566                 :            : 
    2567                 :            :         if (ep->is_in) {
    2568                 :            :                 deptsiz.d32 =
    2569                 :            :                     DWC_READ_REG32(&core_if->dev_if->
    2570                 :            :                                    in_ep_regs[ep->num]->dieptsiz);
    2571                 :            :                 offset = ep->data_per_frame;
    2572                 :            :         } else {
    2573                 :            :                 deptsiz.d32 =
    2574                 :            :                     DWC_READ_REG32(&core_if->dev_if->
    2575                 :            :                                    out_ep_regs[ep->num]->doeptsiz);
    2576                 :            :                 offset =
    2577                 :            :                     ep->data_per_frame +
    2578                 :            :                     (0x4 & (0x4 - (ep->data_per_frame & 0x3)));
    2579                 :            :         }
    2580                 :            : 
    2581                 :            :         if (!deptsiz.b.xfersize) {
    2582                 :            :                 ep->pkt_info[ep->cur_pkt].length = ep->data_per_frame;
    2583                 :            :                 ep->pkt_info[ep->cur_pkt].offset =
    2584                 :            :                     ep->cur_pkt_dma_addr - dma_addr;
    2585                 :            :                 ep->pkt_info[ep->cur_pkt].status = 0;
    2586                 :            :         } else {
    2587                 :            :                 ep->pkt_info[ep->cur_pkt].length = ep->data_per_frame;
    2588                 :            :                 ep->pkt_info[ep->cur_pkt].offset =
    2589                 :            :                     ep->cur_pkt_dma_addr - dma_addr;
    2590                 :            :                 ep->pkt_info[ep->cur_pkt].status = -DWC_E_NO_DATA;
    2591                 :            :         }
    2592                 :            :         ep->cur_pkt_addr += offset;
    2593                 :            :         ep->cur_pkt_dma_addr += offset;
    2594                 :            :         ep->cur_pkt++;
    2595                 :            : }
    2596                 :            : 
    2597                 :            : /**
    2598                 :            :  * This function sets latest iso packet information(DDMA mode)
    2599                 :            :  *
    2600                 :            :  * @param core_if Programming view of DWC_otg controller.
    2601                 :            :  * @param dwc_ep The EP to start the transfer on.
    2602                 :            :  *
    2603                 :            :  */
    2604                 :            : static void set_ddma_iso_pkts_info(dwc_otg_core_if_t * core_if,
    2605                 :            :                                    dwc_ep_t * dwc_ep)
    2606                 :            : {
    2607                 :            :         dwc_otg_dev_dma_desc_t *dma_desc;
    2608                 :            :         dev_dma_desc_sts_t sts = {.d32 = 0 };
    2609                 :            :         iso_pkt_info_t *iso_packet;
    2610                 :            :         uint32_t data_per_desc;
    2611                 :            :         uint32_t offset;
    2612                 :            :         int i, j;
    2613                 :            : 
    2614                 :            :         iso_packet = dwc_ep->pkt_info;
    2615                 :            : 
    2616                 :            :         /** Reinit closed DMA Descriptors*/
    2617                 :            :         /** ISO OUT EP */
    2618                 :            :         if (dwc_ep->is_in == 0) {
    2619                 :            :                 dma_desc =
    2620                 :            :                     dwc_ep->iso_desc_addr +
    2621                 :            :                     dwc_ep->desc_cnt * dwc_ep->proc_buf_num;
    2622                 :            :                 offset = 0;
    2623                 :            : 
    2624                 :            :                 for (i = 0; i < dwc_ep->desc_cnt - dwc_ep->pkt_per_frm;
    2625                 :            :                      i += dwc_ep->pkt_per_frm) {
    2626                 :            :                         for (j = 0; j < dwc_ep->pkt_per_frm; ++j) {
    2627                 :            :                                 data_per_desc =
    2628                 :            :                                     ((j + 1) * dwc_ep->maxpacket >
    2629                 :            :                                      dwc_ep->
    2630                 :            :                                      data_per_frame) ? dwc_ep->data_per_frame -
    2631                 :            :                                     j * dwc_ep->maxpacket : dwc_ep->maxpacket;
    2632                 :            :                                 data_per_desc +=
    2633                 :            :                                     (data_per_desc % 4) ? (4 -
    2634                 :            :                                                            data_per_desc %
    2635                 :            :                                                            4) : 0;
    2636                 :            : 
    2637                 :            :                                 sts.d32 = dma_desc->status.d32;
    2638                 :            : 
    2639                 :            :                                 /* Write status in iso_packet_decsriptor  */
    2640                 :            :                                 iso_packet->status =
    2641                 :            :                                     sts.b_iso_out.rxsts +
    2642                 :            :                                     (sts.b_iso_out.bs ^ BS_DMA_DONE);
    2643                 :            :                                 if (iso_packet->status) {
    2644                 :            :                                         iso_packet->status = -DWC_E_NO_DATA;
    2645                 :            :                                 }
    2646                 :            : 
    2647                 :            :                                 /* Received data length */
    2648                 :            :                                 if (!sts.b_iso_out.rxbytes) {
    2649                 :            :                                         iso_packet->length =
    2650                 :            :                                             data_per_desc -
    2651                 :            :                                             sts.b_iso_out.rxbytes;
    2652                 :            :                                 } else {
    2653                 :            :                                         iso_packet->length =
    2654                 :            :                                             data_per_desc -
    2655                 :            :                                             sts.b_iso_out.rxbytes + (4 -
    2656                 :            :                                                                      dwc_ep->data_per_frame
    2657                 :            :                                                                      % 4);
    2658                 :            :                                 }
    2659                 :            : 
    2660                 :            :                                 iso_packet->offset = offset;
    2661                 :            : 
    2662                 :            :                                 offset += data_per_desc;
    2663                 :            :                                 dma_desc++;
    2664                 :            :                                 iso_packet++;
    2665                 :            :                         }
    2666                 :            :                 }
    2667                 :            : 
    2668                 :            :                 for (j = 0; j < dwc_ep->pkt_per_frm - 1; ++j) {
    2669                 :            :                         data_per_desc =
    2670                 :            :                             ((j + 1) * dwc_ep->maxpacket >
    2671                 :            :                              dwc_ep->data_per_frame) ? dwc_ep->data_per_frame -
    2672                 :            :                             j * dwc_ep->maxpacket : dwc_ep->maxpacket;
    2673                 :            :                         data_per_desc +=
    2674                 :            :                             (data_per_desc % 4) ? (4 - data_per_desc % 4) : 0;
    2675                 :            : 
    2676                 :            :                         sts.d32 = dma_desc->status.d32;
    2677                 :            : 
    2678                 :            :                         /* Write status in iso_packet_decsriptor  */
    2679                 :            :                         iso_packet->status =
    2680                 :            :                             sts.b_iso_out.rxsts +
    2681                 :            :                             (sts.b_iso_out.bs ^ BS_DMA_DONE);
    2682                 :            :                         if (iso_packet->status) {
    2683                 :            :                                 iso_packet->status = -DWC_E_NO_DATA;
    2684                 :            :                         }
    2685                 :            : 
    2686                 :            :                         /* Received data length */
    2687                 :            :                         iso_packet->length =
    2688                 :            :                             dwc_ep->data_per_frame - sts.b_iso_out.rxbytes;
    2689                 :            : 
    2690                 :            :                         iso_packet->offset = offset;
    2691                 :            : 
    2692                 :            :                         offset += data_per_desc;
    2693                 :            :                         iso_packet++;
    2694                 :            :                         dma_desc++;
    2695                 :            :                 }
    2696                 :            : 
    2697                 :            :                 sts.d32 = dma_desc->status.d32;
    2698                 :            : 
    2699                 :            :                 /* Write status in iso_packet_decsriptor  */
    2700                 :            :                 iso_packet->status =
    2701                 :            :                     sts.b_iso_out.rxsts + (sts.b_iso_out.bs ^ BS_DMA_DONE);
    2702                 :            :                 if (iso_packet->status) {
    2703                 :            :                         iso_packet->status = -DWC_E_NO_DATA;
    2704                 :            :                 }
    2705                 :            :                 /* Received data length */
    2706                 :            :                 if (!sts.b_iso_out.rxbytes) {
    2707                 :            :                         iso_packet->length =
    2708                 :            :                             dwc_ep->data_per_frame - sts.b_iso_out.rxbytes;
    2709                 :            :                 } else {
    2710                 :            :                         iso_packet->length =
    2711                 :            :                             dwc_ep->data_per_frame - sts.b_iso_out.rxbytes +
    2712                 :            :                             (4 - dwc_ep->data_per_frame % 4);
    2713                 :            :                 }
    2714                 :            : 
    2715                 :            :                 iso_packet->offset = offset;
    2716                 :            :         } else {
    2717                 :            : /** ISO IN EP */
    2718                 :            : 
    2719                 :            :                 dma_desc =
    2720                 :            :                     dwc_ep->iso_desc_addr +
    2721                 :            :                     dwc_ep->desc_cnt * dwc_ep->proc_buf_num;
    2722                 :            : 
    2723                 :            :                 for (i = 0; i < dwc_ep->desc_cnt - 1; i++) {
    2724                 :            :                         sts.d32 = dma_desc->status.d32;
    2725                 :            : 
    2726                 :            :                         /* Write status in iso packet descriptor */
    2727                 :            :                         iso_packet->status =
    2728                 :            :                             sts.b_iso_in.txsts +
    2729                 :            :                             (sts.b_iso_in.bs ^ BS_DMA_DONE);
    2730                 :            :                         if (iso_packet->status != 0) {
    2731                 :            :                                 iso_packet->status = -DWC_E_NO_DATA;
    2732                 :            : 
    2733                 :            :                         }
    2734                 :            :                         /* Bytes has been transfered */
    2735                 :            :                         iso_packet->length =
    2736                 :            :                             dwc_ep->data_per_frame - sts.b_iso_in.txbytes;
    2737                 :            : 
    2738                 :            :                         dma_desc++;
    2739                 :            :                         iso_packet++;
    2740                 :            :                 }
    2741                 :            : 
    2742                 :            :                 sts.d32 = dma_desc->status.d32;
    2743                 :            :                 while (sts.b_iso_in.bs == BS_DMA_BUSY) {
    2744                 :            :                         sts.d32 = dma_desc->status.d32;
    2745                 :            :                 }
    2746                 :            : 
    2747                 :            :                 /* Write status in iso packet descriptor ??? do be done with ERROR codes */
    2748                 :            :                 iso_packet->status =
    2749                 :            :                     sts.b_iso_in.txsts + (sts.b_iso_in.bs ^ BS_DMA_DONE);
    2750                 :            :                 if (iso_packet->status != 0) {
    2751                 :            :                         iso_packet->status = -DWC_E_NO_DATA;
    2752                 :            :                 }
    2753                 :            : 
    2754                 :            :                 /* Bytes has been transfered */
    2755                 :            :                 iso_packet->length =
    2756                 :            :                     dwc_ep->data_per_frame - sts.b_iso_in.txbytes;
    2757                 :            :         }
    2758                 :            : }
    2759                 :            : 
    2760                 :            : /**
    2761                 :            :  * This function reinitialize DMA Descriptors for Isochronous transfer
    2762                 :            :  *
    2763                 :            :  * @param core_if Programming view of DWC_otg controller.
    2764                 :            :  * @param dwc_ep The EP to start the transfer on.
    2765                 :            :  *
    2766                 :            :  */
    2767                 :            : static void reinit_ddma_iso_xfer(dwc_otg_core_if_t * core_if, dwc_ep_t * dwc_ep)
    2768                 :            : {
    2769                 :            :         int i, j;
    2770                 :            :         dwc_otg_dev_dma_desc_t *dma_desc;
    2771                 :            :         dma_addr_t dma_ad;
    2772                 :            :         volatile uint32_t *addr;
    2773                 :            :         dev_dma_desc_sts_t sts = {.d32 = 0 };
    2774                 :            :         uint32_t data_per_desc;
    2775                 :            : 
    2776                 :            :         if (dwc_ep->is_in == 0) {
    2777                 :            :                 addr = &core_if->dev_if->out_ep_regs[dwc_ep->num]->doepctl;
    2778                 :            :         } else {
    2779                 :            :                 addr = &core_if->dev_if->in_ep_regs[dwc_ep->num]->diepctl;
    2780                 :            :         }
    2781                 :            : 
    2782                 :            :         if (dwc_ep->proc_buf_num == 0) {
    2783                 :            :                 /** Buffer 0 descriptors setup */
    2784                 :            :                 dma_ad = dwc_ep->dma_addr0;
    2785                 :            :         } else {
    2786                 :            :                 /** Buffer 1 descriptors setup */
    2787                 :            :                 dma_ad = dwc_ep->dma_addr1;
    2788                 :            :         }
    2789                 :            : 
    2790                 :            :         /** Reinit closed DMA Descriptors*/
    2791                 :            :         /** ISO OUT EP */
    2792                 :            :         if (dwc_ep->is_in == 0) {
    2793                 :            :                 dma_desc =
    2794                 :            :                     dwc_ep->iso_desc_addr +
    2795                 :            :                     dwc_ep->desc_cnt * dwc_ep->proc_buf_num;
    2796                 :            : 
    2797                 :            :                 sts.b_iso_out.bs = BS_HOST_READY;
    2798                 :            :                 sts.b_iso_out.rxsts = 0;
    2799                 :            :                 sts.b_iso_out.l = 0;
    2800                 :            :                 sts.b_iso_out.sp = 0;
    2801                 :            :                 sts.b_iso_out.ioc = 0;
    2802                 :            :                 sts.b_iso_out.pid = 0;
    2803                 :            :                 sts.b_iso_out.framenum = 0;
    2804                 :            : 
    2805                 :            :                 for (i = 0; i < dwc_ep->desc_cnt - dwc_ep->pkt_per_frm;
    2806                 :            :                      i += dwc_ep->pkt_per_frm) {
    2807                 :            :                         for (j = 0; j < dwc_ep->pkt_per_frm; ++j) {
    2808                 :            :                                 data_per_desc =
    2809                 :            :                                     ((j + 1) * dwc_ep->maxpacket >
    2810                 :            :                                      dwc_ep->
    2811                 :            :                                      data_per_frame) ? dwc_ep->data_per_frame -
    2812                 :            :                                     j * dwc_ep->maxpacket : dwc_ep->maxpacket;
    2813                 :            :                                 data_per_desc +=
    2814                 :            :                                     (data_per_desc % 4) ? (4 -
    2815                 :            :                                                            data_per_desc %
    2816                 :            :                                                            4) : 0;
    2817                 :            :                                 sts.b_iso_out.rxbytes = data_per_desc;
    2818                 :            :                                 dma_desc->buf = dma_ad;
    2819                 :            :                                 dma_desc->status.d32 = sts.d32;
    2820                 :            : 
    2821                 :            :                                 dma_ad += data_per_desc;
    2822                 :            :                                 dma_desc++;
    2823                 :            :                         }
    2824                 :            :                 }
    2825                 :            : 
    2826                 :            :                 for (j = 0; j < dwc_ep->pkt_per_frm - 1; ++j) {
    2827                 :            : 
    2828                 :            :                         data_per_desc =
    2829                 :            :                             ((j + 1) * dwc_ep->maxpacket >
    2830                 :            :                              dwc_ep->data_per_frame) ? dwc_ep->data_per_frame -
    2831                 :            :                             j * dwc_ep->maxpacket : dwc_ep->maxpacket;
    2832                 :            :                         data_per_desc +=
    2833                 :            :                             (data_per_desc % 4) ? (4 - data_per_desc % 4) : 0;
    2834                 :            :                         sts.b_iso_out.rxbytes = data_per_desc;
    2835                 :            : 
    2836                 :            :                         dma_desc->buf = dma_ad;
    2837                 :            :                         dma_desc->status.d32 = sts.d32;
    2838                 :            : 
    2839                 :            :                         dma_desc++;
    2840                 :            :                         dma_ad += data_per_desc;
    2841                 :            :                 }
    2842                 :            : 
    2843                 :            :                 sts.b_iso_out.ioc = 1;
    2844                 :            :                 sts.b_iso_out.l = dwc_ep->proc_buf_num;
    2845                 :            : 
    2846                 :            :                 data_per_desc =
    2847                 :            :                     ((j + 1) * dwc_ep->maxpacket >
    2848                 :            :                      dwc_ep->data_per_frame) ? dwc_ep->data_per_frame -
    2849                 :            :                     j * dwc_ep->maxpacket : dwc_ep->maxpacket;
    2850                 :            :                 data_per_desc +=
    2851                 :            :                     (data_per_desc % 4) ? (4 - data_per_desc % 4) : 0;
    2852                 :            :                 sts.b_iso_out.rxbytes = data_per_desc;
    2853                 :            : 
    2854                 :            :                 dma_desc->buf = dma_ad;
    2855                 :            :                 dma_desc->status.d32 = sts.d32;
    2856                 :            :         } else {
    2857                 :            : /** ISO IN EP */
    2858                 :            : 
    2859                 :            :                 dma_desc =
    2860                 :            :                     dwc_ep->iso_desc_addr +
    2861                 :            :                     dwc_ep->desc_cnt * dwc_ep->proc_buf_num;
    2862                 :            : 
    2863                 :            :                 sts.b_iso_in.bs = BS_HOST_READY;
    2864                 :            :                 sts.b_iso_in.txsts = 0;
    2865                 :            :                 sts.b_iso_in.sp = 0;
    2866                 :            :                 sts.b_iso_in.ioc = 0;
    2867                 :            :                 sts.b_iso_in.pid = dwc_ep->pkt_per_frm;
    2868                 :            :                 sts.b_iso_in.framenum = dwc_ep->next_frame;
    2869                 :            :                 sts.b_iso_in.txbytes = dwc_ep->data_per_frame;
    2870                 :            :                 sts.b_iso_in.l = 0;
    2871                 :            : 
    2872                 :            :                 for (i = 0; i < dwc_ep->desc_cnt - 1; i++) {
    2873                 :            :                         dma_desc->buf = dma_ad;
    2874                 :            :                         dma_desc->status.d32 = sts.d32;
    2875                 :            : 
    2876                 :            :                         sts.b_iso_in.framenum += dwc_ep->bInterval;
    2877                 :            :                         dma_ad += dwc_ep->data_per_frame;
    2878                 :            :                         dma_desc++;
    2879                 :            :                 }
    2880                 :            : 
    2881                 :            :                 sts.b_iso_in.ioc = 1;
    2882                 :            :                 sts.b_iso_in.l = dwc_ep->proc_buf_num;
    2883                 :            : 
    2884                 :            :                 dma_desc->buf = dma_ad;
    2885                 :            :                 dma_desc->status.d32 = sts.d32;
    2886                 :            : 
    2887                 :            :                 dwc_ep->next_frame =
    2888                 :            :                     sts.b_iso_in.framenum + dwc_ep->bInterval * 1;
    2889                 :            :         }
    2890                 :            :         dwc_ep->proc_buf_num = (dwc_ep->proc_buf_num ^ 1) & 0x1;
    2891                 :            : }
    2892                 :            : 
    2893                 :            : /**
    2894                 :            :  * This function is to handle Iso EP transfer complete interrupt
    2895                 :            :  * in case Iso out packet was dropped
    2896                 :            :  *
    2897                 :            :  * @param core_if Programming view of DWC_otg controller.
    2898                 :            :  * @param dwc_ep The EP for wihich transfer complete was asserted
    2899                 :            :  *
    2900                 :            :  */
    2901                 :            : static uint32_t handle_iso_out_pkt_dropped(dwc_otg_core_if_t * core_if,
    2902                 :            :                                            dwc_ep_t * dwc_ep)
    2903                 :            : {
    2904                 :            :         uint32_t dma_addr;
    2905                 :            :         uint32_t drp_pkt;
    2906                 :            :         uint32_t drp_pkt_cnt;
    2907                 :            :         deptsiz_data_t deptsiz = {.d32 = 0 };
    2908                 :            :         depctl_data_t depctl = {.d32 = 0 };
    2909                 :            :         int i;
    2910                 :            : 
    2911                 :            :         deptsiz.d32 =
    2912                 :            :             DWC_READ_REG32(&core_if->dev_if->
    2913                 :            :                            out_ep_regs[dwc_ep->num]->doeptsiz);
    2914                 :            : 
    2915                 :            :         drp_pkt = dwc_ep->pkt_cnt - deptsiz.b.pktcnt;
    2916                 :            :         drp_pkt_cnt = dwc_ep->pkt_per_frm - (drp_pkt % dwc_ep->pkt_per_frm);
    2917                 :            : 
    2918                 :            :         /* Setting dropped packets status */
    2919                 :            :         for (i = 0; i < drp_pkt_cnt; ++i) {
    2920                 :            :                 dwc_ep->pkt_info[drp_pkt].status = -DWC_E_NO_DATA;
    2921                 :            :                 drp_pkt++;
    2922                 :            :                 deptsiz.b.pktcnt--;
    2923                 :            :         }
    2924                 :            : 
    2925                 :            :         if (deptsiz.b.pktcnt > 0) {
    2926                 :            :                 deptsiz.b.xfersize =
    2927                 :            :                     dwc_ep->xfer_len - (dwc_ep->pkt_cnt -
    2928                 :            :                                         deptsiz.b.pktcnt) * dwc_ep->maxpacket;
    2929                 :            :         } else {
    2930                 :            :                 deptsiz.b.xfersize = 0;
    2931                 :            :                 deptsiz.b.pktcnt = 0;
    2932                 :            :         }
    2933                 :            : 
    2934                 :            :         DWC_WRITE_REG32(&core_if->dev_if->out_ep_regs[dwc_ep->num]->doeptsiz,
    2935                 :            :                         deptsiz.d32);
    2936                 :            : 
    2937                 :            :         if (deptsiz.b.pktcnt > 0) {
    2938                 :            :                 if (dwc_ep->proc_buf_num) {
    2939                 :            :                         dma_addr =
    2940                 :            :                             dwc_ep->dma_addr1 + dwc_ep->xfer_len -
    2941                 :            :                             deptsiz.b.xfersize;
    2942                 :            :                 } else {
    2943                 :            :                         dma_addr =
    2944                 :            :                             dwc_ep->dma_addr0 + dwc_ep->xfer_len -
    2945                 :            :                             deptsiz.b.xfersize;;
    2946                 :            :                 }
    2947                 :            : 
    2948                 :            :                 DWC_WRITE_REG32(&core_if->dev_if->
    2949                 :            :                                 out_ep_regs[dwc_ep->num]->doepdma, dma_addr);
    2950                 :            : 
    2951                 :            :                 /** Re-enable endpoint, clear nak  */
    2952                 :            :                 depctl.d32 = 0;
    2953                 :            :                 depctl.b.epena = 1;
    2954                 :            :                 depctl.b.cnak = 1;
    2955                 :            : 
    2956                 :            :                 DWC_MODIFY_REG32(&core_if->dev_if->
    2957                 :            :                                  out_ep_regs[dwc_ep->num]->doepctl, depctl.d32,
    2958                 :            :                                  depctl.d32);
    2959                 :            :                 return 0;
    2960                 :            :         } else {
    2961                 :            :                 return 1;
    2962                 :            :         }
    2963                 :            : }
    2964                 :            : 
    2965                 :            : /**
    2966                 :            :  * This function sets iso packets information(PTI mode)
    2967                 :            :  *
    2968                 :            :  * @param core_if Programming view of DWC_otg controller.
    2969                 :            :  * @param ep The EP to start the transfer on.
    2970                 :            :  *
    2971                 :            :  */
    2972                 :            : static uint32_t set_iso_pkts_info(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
    2973                 :            : {
    2974                 :            :         int i, j;
    2975                 :            :         dma_addr_t dma_ad;
    2976                 :            :         iso_pkt_info_t *packet_info = ep->pkt_info;
    2977                 :            :         uint32_t offset;
    2978                 :            :         uint32_t frame_data;
    2979                 :            :         deptsiz_data_t deptsiz;
    2980                 :            : 
    2981                 :            :         if (ep->proc_buf_num == 0) {
    2982                 :            :                 /** Buffer 0 descriptors setup */
    2983                 :            :                 dma_ad = ep->dma_addr0;
    2984                 :            :         } else {
    2985                 :            :                 /** Buffer 1 descriptors setup */
    2986                 :            :                 dma_ad = ep->dma_addr1;
    2987                 :            :         }
    2988                 :            : 
    2989                 :            :         if (ep->is_in) {
    2990                 :            :                 deptsiz.d32 =
    2991                 :            :                     DWC_READ_REG32(&core_if->dev_if->in_ep_regs[ep->num]->
    2992                 :            :                                    dieptsiz);
    2993                 :            :         } else {
    2994                 :            :                 deptsiz.d32 =
    2995                 :            :                     DWC_READ_REG32(&core_if->dev_if->out_ep_regs[ep->num]->
    2996                 :            :                                    doeptsiz);
    2997                 :            :         }
    2998                 :            : 
    2999                 :            :         if (!deptsiz.b.xfersize) {
    3000                 :            :                 offset = 0;
    3001                 :            :                 for (i = 0; i < ep->pkt_cnt; i += ep->pkt_per_frm) {
    3002                 :            :                         frame_data = ep->data_per_frame;
    3003                 :            :                         for (j = 0; j < ep->pkt_per_frm; ++j) {
    3004                 :            : 
    3005                 :            :                                 /* Packet status - is not set as initially
    3006                 :            :                                  * it is set to 0 and if packet was sent
    3007                 :            :                                  successfully, status field will remain 0*/
    3008                 :            : 
    3009                 :            :                                 /* Bytes has been transfered */
    3010                 :            :                                 packet_info->length =
    3011                 :            :                                     (ep->maxpacket <
    3012                 :            :                                      frame_data) ? ep->maxpacket : frame_data;
    3013                 :            : 
    3014                 :            :                                 /* Received packet offset */
    3015                 :            :                                 packet_info->offset = offset;
    3016                 :            :                                 offset += packet_info->length;
    3017                 :            :                                 frame_data -= packet_info->length;
    3018                 :            : 
    3019                 :            :                                 packet_info++;
    3020                 :            :                         }
    3021                 :            :                 }
    3022                 :            :                 return 1;
    3023                 :            :         } else {
    3024                 :            :                 /* This is a workaround for in case of Transfer Complete with
    3025                 :            :                  * PktDrpSts interrupts merging - in this case Transfer complete
    3026                 :            :                  * interrupt for Isoc Out Endpoint is asserted without PktDrpSts
    3027                 :            :                  * set and with DOEPTSIZ register non zero. Investigations showed,
    3028                 :            :                  * that this happens when Out packet is dropped, but because of
    3029                 :            :                  * interrupts merging during first interrupt handling PktDrpSts
    3030                 :            :                  * bit is cleared and for next merged interrupts it is not reset.
    3031                 :            :                  * In this case SW hadles the interrupt as if PktDrpSts bit is set.
    3032                 :            :                  */
    3033                 :            :                 if (ep->is_in) {
    3034                 :            :                         return 1;
    3035                 :            :                 } else {
    3036                 :            :                         return handle_iso_out_pkt_dropped(core_if, ep);
    3037                 :            :                 }
    3038                 :            :         }
    3039                 :            : }
    3040                 :            : 
    3041                 :            : /**
    3042                 :            :  * This function is to handle Iso EP transfer complete interrupt
    3043                 :            :  *
    3044                 :            :  * @param pcd The PCD
    3045                 :            :  * @param ep The EP for which transfer complete was asserted
    3046                 :            :  *
    3047                 :            :  */
    3048                 :            : static void complete_iso_ep(dwc_otg_pcd_t * pcd, dwc_otg_pcd_ep_t * ep)
    3049                 :            : {
    3050                 :            :         dwc_otg_core_if_t *core_if = GET_CORE_IF(ep->pcd);
    3051                 :            :         dwc_ep_t *dwc_ep = &ep->dwc_ep;
    3052                 :            :         uint8_t is_last = 0;
    3053                 :            : 
    3054                 :            :         if (ep->dwc_ep.next_frame == 0xffffffff) {
    3055                 :            :                 DWC_WARN("Next frame is not set!\n");
    3056                 :            :                 return;
    3057                 :            :         }
    3058                 :            : 
    3059                 :            :         if (core_if->dma_enable) {
    3060                 :            :                 if (core_if->dma_desc_enable) {
    3061                 :            :                         set_ddma_iso_pkts_info(core_if, dwc_ep);
    3062                 :            :                         reinit_ddma_iso_xfer(core_if, dwc_ep);
    3063                 :            :                         is_last = 1;
    3064                 :            :                 } else {
    3065                 :            :                         if (core_if->pti_enh_enable) {
    3066                 :            :                                 if (set_iso_pkts_info(core_if, dwc_ep)) {
    3067                 :            :                                         dwc_ep->proc_buf_num =
    3068                 :            :                                             (dwc_ep->proc_buf_num ^ 1) & 0x1;
    3069                 :            :                                         dwc_otg_iso_ep_start_buf_transfer
    3070                 :            :                                             (core_if, dwc_ep);
    3071                 :            :                                         is_last = 1;
    3072                 :            :                                 }
    3073                 :            :                         } else {
    3074                 :            :                                 set_current_pkt_info(core_if, dwc_ep);
    3075                 :            :                                 if (dwc_ep->cur_pkt >= dwc_ep->pkt_cnt) {
    3076                 :            :                                         is_last = 1;
    3077                 :            :                                         dwc_ep->cur_pkt = 0;
    3078                 :            :                                         dwc_ep->proc_buf_num =
    3079                 :            :                                             (dwc_ep->proc_buf_num ^ 1) & 0x1;
    3080                 :            :                                         if (dwc_ep->proc_buf_num) {
    3081                 :            :                                                 dwc_ep->cur_pkt_addr =
    3082                 :            :                                                     dwc_ep->xfer_buff1;
    3083                 :            :                                                 dwc_ep->cur_pkt_dma_addr =
    3084                 :            :                                                     dwc_ep->dma_addr1;
    3085                 :            :                                         } else {
    3086                 :            :                                                 dwc_ep->cur_pkt_addr =
    3087                 :            :                                                     dwc_ep->xfer_buff0;
    3088                 :            :                                                 dwc_ep->cur_pkt_dma_addr =
    3089                 :            :                                                     dwc_ep->dma_addr0;
    3090                 :            :                                         }
    3091                 :            : 
    3092                 :            :                                 }
    3093                 :            :                                 dwc_otg_iso_ep_start_frm_transfer(core_if,
    3094                 :            :                                                                   dwc_ep);
    3095                 :            :                         }
    3096                 :            :                 }
    3097                 :            :         } else {
    3098                 :            :                 set_current_pkt_info(core_if, dwc_ep);
    3099                 :            :                 if (dwc_ep->cur_pkt >= dwc_ep->pkt_cnt) {
    3100                 :            :                         is_last = 1;
    3101                 :            :                         dwc_ep->cur_pkt = 0;
    3102                 :            :                         dwc_ep->proc_buf_num = (dwc_ep->proc_buf_num ^ 1) & 0x1;
    3103                 :            :                         if (dwc_ep->proc_buf_num) {
    3104                 :            :                                 dwc_ep->cur_pkt_addr = dwc_ep->xfer_buff1;
    3105                 :            :                                 dwc_ep->cur_pkt_dma_addr = dwc_ep->dma_addr1;
    3106                 :            :                         } else {
    3107                 :            :                                 dwc_ep->cur_pkt_addr = dwc_ep->xfer_buff0;
    3108                 :            :                                 dwc_ep->cur_pkt_dma_addr = dwc_ep->dma_addr0;
    3109                 :            :                         }
    3110                 :            : 
    3111                 :            :                 }
    3112                 :            :                 dwc_otg_iso_ep_start_frm_transfer(core_if, dwc_ep);
    3113                 :            :         }
    3114                 :            :         if (is_last)
    3115                 :            :                 dwc_otg_iso_buffer_done(pcd, ep, ep->iso_req_handle);
    3116                 :            : }
    3117                 :            : #endif /* DWC_EN_ISOC */
    3118                 :            : 
    3119                 :            : /**
    3120                 :            :  * This function handle BNA interrupt for Non Isochronous EPs
    3121                 :            :  *
    3122                 :            :  */
    3123                 :          0 : static void dwc_otg_pcd_handle_noniso_bna(dwc_otg_pcd_ep_t * ep)
    3124                 :            : {
    3125                 :            :         dwc_ep_t *dwc_ep = &ep->dwc_ep;
    3126                 :            :         volatile uint32_t *addr;
    3127                 :          0 :         depctl_data_t depctl = {.d32 = 0 };
    3128                 :          0 :         dwc_otg_pcd_t *pcd = ep->pcd;
    3129                 :            :         dwc_otg_dev_dma_desc_t *dma_desc;
    3130                 :            :         dev_dma_desc_sts_t sts = {.d32 = 0 };
    3131                 :          0 :         dwc_otg_core_if_t *core_if = ep->pcd->core_if;
    3132                 :            :         int i, start;
    3133                 :            : 
    3134         [ #  # ]:          0 :         if (!dwc_ep->desc_cnt)
    3135         [ #  # ]:          0 :                 DWC_WARN("Ep%d %s Descriptor count = %d \n", dwc_ep->num,
    3136                 :            :                          (dwc_ep->is_in ? "IN" : "OUT"), dwc_ep->desc_cnt);
    3137                 :            : 
    3138   [ #  #  #  # ]:          0 :         if (core_if->core_params->cont_on_bna && !dwc_ep->is_in
    3139         [ #  # ]:          0 :                                                         && dwc_ep->type != DWC_OTG_EP_TYPE_CONTROL) {
    3140                 :            :                 uint32_t doepdma;
    3141                 :          0 :                 dwc_otg_dev_out_ep_regs_t *out_regs =
    3142                 :          0 :                         core_if->dev_if->out_ep_regs[dwc_ep->num];
    3143                 :          0 :                 doepdma = DWC_READ_REG32(&(out_regs->doepdma));
    3144                 :          0 :                 start = (doepdma - dwc_ep->dma_desc_addr)/sizeof(dwc_otg_dev_dma_desc_t);
    3145                 :          0 :                 dma_desc = &(dwc_ep->desc_addr[start]);
    3146                 :            :         } else {
    3147                 :            :                 start = 0;
    3148                 :          0 :                 dma_desc = dwc_ep->desc_addr;
    3149                 :            :         }
    3150                 :            : 
    3151                 :            : 
    3152         [ #  # ]:          0 :         for (i = start; i < dwc_ep->desc_cnt; ++i, ++dma_desc) {
    3153                 :          0 :                 sts.d32 = dma_desc->status.d32;
    3154                 :          0 :                 sts.b.bs = BS_HOST_READY;
    3155                 :          0 :                 dma_desc->status.d32 = sts.d32;
    3156                 :            :         }
    3157                 :            : 
    3158         [ #  # ]:          0 :         if (dwc_ep->is_in == 0) {
    3159                 :          0 :                 addr =
    3160                 :          0 :                     &GET_CORE_IF(pcd)->dev_if->out_ep_regs[dwc_ep->num]->
    3161                 :            :                     doepctl;
    3162                 :            :         } else {
    3163                 :          0 :                 addr =
    3164                 :          0 :                     &GET_CORE_IF(pcd)->dev_if->in_ep_regs[dwc_ep->num]->diepctl;
    3165                 :            :         }
    3166                 :          0 :         depctl.b.epena = 1;
    3167                 :          0 :         depctl.b.cnak = 1;
    3168                 :          0 :         DWC_MODIFY_REG32(addr, 0, depctl.d32);
    3169                 :          0 : }
    3170                 :            : 
    3171                 :            : /**
    3172                 :            :  * This function handles EP0 Control transfers.
    3173                 :            :  *
    3174                 :            :  * The state of the control transfers are tracked in
    3175                 :            :  * <code>ep0state</code>.
    3176                 :            :  */
    3177                 :          0 : static void handle_ep0(dwc_otg_pcd_t * pcd)
    3178                 :            : {
    3179                 :          0 :         dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
    3180                 :          0 :         dwc_otg_pcd_ep_t *ep0 = &pcd->ep0;
    3181                 :            :         dev_dma_desc_sts_t desc_sts;
    3182                 :            :         deptsiz0_data_t deptsiz;
    3183                 :            :         uint32_t byte_count;
    3184                 :            : 
    3185                 :            : #ifdef DEBUG_EP0
    3186                 :            :         DWC_DEBUGPL(DBG_PCDV, "%s()\n", __func__);
    3187                 :            :         print_ep0_state(pcd);
    3188                 :            : #endif
    3189                 :            : 
    3190                 :            : //      DWC_PRINTF("HANDLE EP0\n");
    3191                 :            : 
    3192   [ #  #  #  #  :          0 :         switch (pcd->ep0state) {
                   #  # ]
    3193                 :            :         case EP0_DISCONNECT:
    3194                 :            :                 break;
    3195                 :            : 
    3196                 :            :         case EP0_IDLE:
    3197                 :          0 :                 pcd->request_config = 0;
    3198                 :            : 
    3199                 :          0 :                 pcd_setup(pcd);
    3200                 :          0 :                 break;
    3201                 :            : 
    3202                 :            :         case EP0_IN_DATA_PHASE:
    3203                 :            : #ifdef DEBUG_EP0
    3204                 :            :                 DWC_DEBUGPL(DBG_PCD, "DATA_IN EP%d-%s: type=%d, mps=%d\n",
    3205                 :            :                             ep0->dwc_ep.num, (ep0->dwc_ep.is_in ? "IN" : "OUT"),
    3206                 :            :                             ep0->dwc_ep.type, ep0->dwc_ep.maxpacket);
    3207                 :            : #endif
    3208                 :            : 
    3209         [ #  # ]:          0 :                 if (core_if->dma_enable != 0) {
    3210                 :            :                         /*
    3211                 :            :                          * For EP0 we can only program 1 packet at a time so we
    3212                 :            :                          * need to do the make calculations after each complete.
    3213                 :            :                          * Call write_packet to make the calculations, as in
    3214                 :            :                          * slave mode, and use those values to determine if we
    3215                 :            :                          * can complete.
    3216                 :            :                          */
    3217         [ #  # ]:          0 :                         if (core_if->dma_desc_enable == 0) {
    3218                 :          0 :                                 deptsiz.d32 =
    3219                 :          0 :                                     DWC_READ_REG32(&core_if->
    3220                 :          0 :                                                    dev_if->in_ep_regs[0]->
    3221                 :            :                                                    dieptsiz);
    3222                 :          0 :                                 byte_count =
    3223                 :          0 :                                     ep0->dwc_ep.xfer_len - deptsiz.b.xfersize;
    3224                 :            :                         } else {
    3225                 :          0 :                                 desc_sts =
    3226                 :          0 :                                     core_if->dev_if->in_desc_addr->status;
    3227                 :          0 :                                 byte_count =
    3228                 :          0 :                                     ep0->dwc_ep.xfer_len - desc_sts.b.bytes;
    3229                 :            :                         }
    3230                 :          0 :                         ep0->dwc_ep.xfer_count += byte_count;
    3231                 :          0 :                         ep0->dwc_ep.xfer_buff += byte_count;
    3232                 :          0 :                         ep0->dwc_ep.dma_addr += byte_count;
    3233                 :            :                 }
    3234         [ #  # ]:          0 :                 if (ep0->dwc_ep.xfer_count < ep0->dwc_ep.total_len) {
    3235                 :          0 :                         dwc_otg_ep0_continue_transfer(GET_CORE_IF(pcd),
    3236                 :            :                                                       &ep0->dwc_ep);
    3237                 :            :                         DWC_DEBUGPL(DBG_PCD, "CONTINUE TRANSFER\n");
    3238         [ #  # ]:          0 :                 } else if (ep0->dwc_ep.sent_zlp) {
    3239                 :          0 :                         dwc_otg_ep0_continue_transfer(GET_CORE_IF(pcd),
    3240                 :            :                                                       &ep0->dwc_ep);
    3241                 :          0 :                         ep0->dwc_ep.sent_zlp = 0;
    3242                 :            :                         DWC_DEBUGPL(DBG_PCD, "CONTINUE TRANSFER sent zlp\n");
    3243                 :            :                 } else {
    3244                 :          0 :                         ep0_complete_request(ep0);
    3245                 :            :                         DWC_DEBUGPL(DBG_PCD, "COMPLETE TRANSFER\n");
    3246                 :            :                 }
    3247                 :            :                 break;
    3248                 :            :         case EP0_OUT_DATA_PHASE:
    3249                 :            : #ifdef DEBUG_EP0
    3250                 :            :                 DWC_DEBUGPL(DBG_PCD, "DATA_OUT EP%d-%s: type=%d, mps=%d\n",
    3251                 :            :                             ep0->dwc_ep.num, (ep0->dwc_ep.is_in ? "IN" : "OUT"),
    3252                 :            :                             ep0->dwc_ep.type, ep0->dwc_ep.maxpacket);
    3253                 :            : #endif
    3254         [ #  # ]:          0 :                 if (core_if->dma_enable != 0) {
    3255         [ #  # ]:          0 :                         if (core_if->dma_desc_enable == 0) {
    3256                 :          0 :                                 deptsiz.d32 =
    3257                 :          0 :                                     DWC_READ_REG32(&core_if->
    3258                 :          0 :                                                    dev_if->out_ep_regs[0]->
    3259                 :            :                                                    doeptsiz);
    3260                 :          0 :                                 byte_count =
    3261                 :          0 :                                     ep0->dwc_ep.maxpacket - deptsiz.b.xfersize;
    3262                 :            :                         } else {
    3263                 :          0 :                                 desc_sts =
    3264                 :          0 :                                     core_if->dev_if->out_desc_addr->status;
    3265                 :          0 :                                 byte_count =
    3266                 :          0 :                                     ep0->dwc_ep.maxpacket - desc_sts.b.bytes;
    3267                 :            :                         }
    3268                 :          0 :                         ep0->dwc_ep.xfer_count += byte_count;
    3269                 :          0 :                         ep0->dwc_ep.xfer_buff += byte_count;
    3270                 :          0 :                         ep0->dwc_ep.dma_addr += byte_count;
    3271                 :            :                 }
    3272         [ #  # ]:          0 :                 if (ep0->dwc_ep.xfer_count < ep0->dwc_ep.total_len) {
    3273                 :          0 :                         dwc_otg_ep0_continue_transfer(GET_CORE_IF(pcd),
    3274                 :            :                                                       &ep0->dwc_ep);
    3275                 :            :                         DWC_DEBUGPL(DBG_PCD, "CONTINUE TRANSFER\n");
    3276         [ #  # ]:          0 :                 } else if (ep0->dwc_ep.sent_zlp) {
    3277                 :          0 :                         dwc_otg_ep0_continue_transfer(GET_CORE_IF(pcd),
    3278                 :            :                                                       &ep0->dwc_ep);
    3279                 :          0 :                         ep0->dwc_ep.sent_zlp = 0;
    3280                 :            :                         DWC_DEBUGPL(DBG_PCD, "CONTINUE TRANSFER sent zlp\n");
    3281                 :            :                 } else {
    3282                 :          0 :                         ep0_complete_request(ep0);
    3283                 :            :                         DWC_DEBUGPL(DBG_PCD, "COMPLETE TRANSFER\n");
    3284                 :            :                 }
    3285                 :            :                 break;
    3286                 :            : 
    3287                 :            :         case EP0_IN_STATUS_PHASE:
    3288                 :            :         case EP0_OUT_STATUS_PHASE:
    3289                 :            :                 DWC_DEBUGPL(DBG_PCD, "CASE: EP0_STATUS\n");
    3290                 :          0 :                 ep0_complete_request(ep0);
    3291                 :          0 :                 pcd->ep0state = EP0_IDLE;
    3292                 :          0 :                 ep0->stopped = 1;
    3293                 :          0 :                 ep0->dwc_ep.is_in = 0;       /* OUT for next SETUP */
    3294                 :            : 
    3295                 :            :                 /* Prepare for more SETUP Packets */
    3296         [ #  # ]:          0 :                 if (core_if->dma_enable) {
    3297                 :          0 :                         ep0_out_start(core_if, pcd);
    3298                 :            :                 }
    3299                 :            :                 break;
    3300                 :            : 
    3301                 :            :         case EP0_STALL:
    3302                 :          0 :                 DWC_ERROR("EP0 STALLed, should not get here pcd_setup()\n");
    3303                 :          0 :                 break;
    3304                 :            :         }
    3305                 :            : #ifdef DEBUG_EP0
    3306                 :            :         print_ep0_state(pcd);
    3307                 :            : #endif
    3308                 :          0 : }
    3309                 :            : 
    3310                 :            : /**
    3311                 :            :  * Restart transfer
    3312                 :            :  */
    3313                 :          0 : static void restart_transfer(dwc_otg_pcd_t * pcd, const uint32_t epnum)
    3314                 :            : {
    3315                 :            :         dwc_otg_core_if_t *core_if;
    3316                 :            :         dwc_otg_dev_if_t *dev_if;
    3317                 :            :         deptsiz_data_t dieptsiz = {.d32 = 0 };
    3318                 :            :         dwc_otg_pcd_ep_t *ep;
    3319                 :            : 
    3320                 :            :         ep = get_in_ep(pcd, epnum);
    3321                 :            : 
    3322                 :            : #ifdef DWC_EN_ISOC
    3323                 :            :         if (ep->dwc_ep.type == DWC_OTG_EP_TYPE_ISOC) {
    3324                 :            :                 return;
    3325                 :            :         }
    3326                 :            : #endif /* DWC_EN_ISOC  */
    3327                 :            : 
    3328                 :            :         core_if = GET_CORE_IF(pcd);
    3329                 :            :         dev_if = core_if->dev_if;
    3330                 :            : 
    3331                 :          0 :         dieptsiz.d32 = DWC_READ_REG32(&dev_if->in_ep_regs[epnum]->dieptsiz);
    3332                 :            : 
    3333                 :            :         DWC_DEBUGPL(DBG_PCD, "xfer_buff=%p xfer_count=%0x xfer_len=%0x"
    3334                 :            :                     " stopped=%d\n", ep->dwc_ep.xfer_buff,
    3335                 :            :                     ep->dwc_ep.xfer_count, ep->dwc_ep.xfer_len, ep->stopped);
    3336                 :            :         /*
    3337                 :            :          * If xfersize is 0 and pktcnt in not 0, resend the last packet.
    3338                 :            :          */
    3339   [ #  #  #  #  :          0 :         if (dieptsiz.b.pktcnt && dieptsiz.b.xfersize == 0 &&
                   #  # ]
    3340                 :          0 :             ep->dwc_ep.start_xfer_buff != 0) {
    3341         [ #  # ]:          0 :                 if (ep->dwc_ep.total_len <= ep->dwc_ep.maxpacket) {
    3342                 :          0 :                         ep->dwc_ep.xfer_count = 0;
    3343                 :          0 :                         ep->dwc_ep.xfer_buff = ep->dwc_ep.start_xfer_buff;
    3344                 :          0 :                         ep->dwc_ep.xfer_len = ep->dwc_ep.xfer_count;
    3345                 :            :                 } else {
    3346                 :          0 :                         ep->dwc_ep.xfer_count -= ep->dwc_ep.maxpacket;
    3347                 :            :                         /* convert packet size to dwords. */
    3348                 :          0 :                         ep->dwc_ep.xfer_buff -= ep->dwc_ep.maxpacket;
    3349                 :          0 :                         ep->dwc_ep.xfer_len = ep->dwc_ep.xfer_count;
    3350                 :            :                 }
    3351                 :          0 :                 ep->stopped = 0;
    3352                 :            :                 DWC_DEBUGPL(DBG_PCD, "xfer_buff=%p xfer_count=%0x "
    3353                 :            :                             "xfer_len=%0x stopped=%d\n",
    3354                 :            :                             ep->dwc_ep.xfer_buff,
    3355                 :            :                             ep->dwc_ep.xfer_count, ep->dwc_ep.xfer_len,
    3356                 :            :                             ep->stopped);
    3357         [ #  # ]:          0 :                 if (epnum == 0) {
    3358                 :          0 :                         dwc_otg_ep0_start_transfer(core_if, &ep->dwc_ep);
    3359                 :            :                 } else {
    3360                 :          0 :                         dwc_otg_ep_start_transfer(core_if, &ep->dwc_ep);
    3361                 :            :                 }
    3362                 :            :         }
    3363                 :          0 : }
    3364                 :            : 
    3365                 :            : /*
    3366                 :            :  * This function create new nextep sequnce based on Learn Queue.
    3367                 :            :  *
    3368                 :            :  * @param core_if Programming view of DWC_otg controller
    3369                 :            :  */
    3370                 :          0 : void predict_nextep_seq( dwc_otg_core_if_t * core_if)
    3371                 :            : {
    3372                 :          0 :         dwc_otg_device_global_regs_t *dev_global_regs =
    3373                 :          0 :             core_if->dev_if->dev_global_regs;
    3374                 :          0 :         const uint32_t TOKEN_Q_DEPTH = core_if->hwcfg2.b.dev_token_q_depth;
    3375                 :            :         /* Number of Token Queue Registers */
    3376                 :          0 :         const int DTKNQ_REG_CNT = (TOKEN_Q_DEPTH + 7) / 8;
    3377                 :            :         dtknq1_data_t dtknqr1;
    3378                 :            :         uint32_t in_tkn_epnums[4];
    3379                 :            :         uint8_t seqnum[MAX_EPS_CHANNELS];
    3380                 :          0 :         uint8_t intkn_seq[TOKEN_Q_DEPTH];
    3381                 :            :         grstctl_t resetctl = {.d32 = 0 };
    3382                 :            :         uint8_t temp;
    3383                 :            :         int ndx = 0;
    3384                 :            :         int start = 0;
    3385                 :            :         int end = 0;
    3386                 :            :         int sort_done = 0;
    3387                 :            :         int i = 0;
    3388                 :          0 :         volatile uint32_t *addr = &dev_global_regs->dtknqr1;
    3389                 :            : 
    3390                 :            : 
    3391                 :            :         DWC_DEBUGPL(DBG_PCD,"dev_token_q_depth=%d\n",TOKEN_Q_DEPTH);
    3392                 :            : 
    3393                 :            :         /* Read the DTKNQ Registers */
    3394         [ #  # ]:          0 :         for (i = 0; i < DTKNQ_REG_CNT; i++) {
    3395                 :          0 :                 in_tkn_epnums[i] = DWC_READ_REG32(addr);
    3396                 :            :                 DWC_DEBUGPL(DBG_PCDV, "DTKNQR%d=0x%08x\n", i + 1,
    3397                 :            :                             in_tkn_epnums[i]);
    3398         [ #  # ]:          0 :                 if (addr == &dev_global_regs->dvbusdis) {
    3399                 :          0 :                         addr = &dev_global_regs->dtknqr3_dthrctl;
    3400                 :            :                 } else {
    3401                 :          0 :                         ++addr;
    3402                 :            :                 }
    3403                 :            : 
    3404                 :            :         }
    3405                 :            : 
    3406                 :            :         /* Copy the DTKNQR1 data to the bit field. */
    3407                 :          0 :         dtknqr1.d32 = in_tkn_epnums[0];
    3408         [ #  # ]:          0 :         if (dtknqr1.b.wrap_bit) {
    3409                 :          0 :                 ndx = dtknqr1.b.intknwptr;
    3410                 :            :                 end = ndx -1;
    3411                 :            :                 if (end < 0)
    3412                 :            :                         end = TOKEN_Q_DEPTH -1;
    3413                 :            :         } else {
    3414                 :            :                 ndx = 0;
    3415                 :            :                 end = dtknqr1.b.intknwptr -1;
    3416                 :            :                 if (end < 0)
    3417                 :            :                         end = 0;
    3418                 :            :         }
    3419                 :            :         start = ndx;
    3420                 :            : 
    3421                 :            :         /* Fill seqnum[] by initial values: EP number + 31 */
    3422         [ #  # ]:          0 :         for (i=0; i <= core_if->dev_if->num_in_eps; i++) {
    3423                 :          0 :                 seqnum[i] = i +31;
    3424                 :            :         }
    3425                 :            : 
    3426                 :            :         /* Fill intkn_seq[] from in_tkn_epnums[0] */
    3427         [ #  # ]:          0 :         for (i=0; i < 6; i++)
    3428                 :          0 :                 intkn_seq[i] = (in_tkn_epnums[0] >> ((7-i) * 4)) & 0xf;
    3429                 :            : 
    3430         [ #  # ]:          0 :         if (TOKEN_Q_DEPTH > 6) {
    3431                 :            :                 /* Fill intkn_seq[] from in_tkn_epnums[1] */
    3432         [ #  # ]:          0 :                 for (i=6; i < 14; i++)
    3433                 :          0 :                         intkn_seq[i] =
    3434                 :          0 :                             (in_tkn_epnums[1] >> ((7 - (i - 6)) * 4)) & 0xf;
    3435                 :            :         }
    3436                 :            : 
    3437         [ #  # ]:          0 :         if (TOKEN_Q_DEPTH > 14) {
    3438                 :            :                 /* Fill intkn_seq[] from in_tkn_epnums[1] */
    3439         [ #  # ]:          0 :                 for (i=14; i < 22; i++)
    3440                 :          0 :                         intkn_seq[i] =
    3441                 :          0 :                             (in_tkn_epnums[2] >> ((7 - (i - 14)) * 4)) & 0xf;
    3442                 :            :         }
    3443                 :            : 
    3444         [ #  # ]:          0 :         if (TOKEN_Q_DEPTH > 22) {
    3445                 :            :                 /* Fill intkn_seq[] from in_tkn_epnums[1] */
    3446         [ #  # ]:          0 :                 for (i=22; i < 30; i++)
    3447                 :          0 :                         intkn_seq[i] =
    3448                 :          0 :                             (in_tkn_epnums[3] >> ((7 - (i - 22)) * 4)) & 0xf;
    3449                 :            :         }
    3450                 :            : 
    3451                 :            :         DWC_DEBUGPL(DBG_PCDV, "%s start=%d end=%d intkn_seq[]:\n", __func__,
    3452                 :            :                     start, end);
    3453                 :            :         for (i=0; i<TOKEN_Q_DEPTH; i++)
    3454                 :            :                 DWC_DEBUGPL(DBG_PCDV,"%d\n", intkn_seq[i]);
    3455                 :            : 
    3456                 :            :         /* Update seqnum based on intkn_seq[] */
    3457                 :            :         i = 0;
    3458                 :            :         do {
    3459                 :          0 :                 seqnum[intkn_seq[ndx]] = i;
    3460                 :          0 :                 ndx++;
    3461                 :          0 :                 i++;
    3462         [ #  # ]:          0 :                 if (ndx == TOKEN_Q_DEPTH)
    3463                 :            :                         ndx = 0;
    3464         [ #  # ]:          0 :         } while ( i < TOKEN_Q_DEPTH );
    3465                 :            : 
    3466                 :            :         /* Mark non active EP's in seqnum[] by 0xff */
    3467         [ #  # ]:          0 :         for (i=0; i<=core_if->dev_if->num_in_eps; i++) {
    3468         [ #  # ]:          0 :                 if (core_if->nextep_seq[i] == 0xff )
    3469                 :          0 :                         seqnum[i] = 0xff;
    3470                 :            :         }
    3471                 :            : 
    3472                 :            :         /* Sort seqnum[] */
    3473                 :            :         sort_done = 0;
    3474         [ #  # ]:          0 :         while (!sort_done) {
    3475                 :            :                 sort_done = 1;
    3476         [ #  # ]:          0 :                 for (i=0; i<core_if->dev_if->num_in_eps; i++) {
    3477         [ #  # ]:          0 :                         if (seqnum[i] > seqnum[i+1]) {
    3478                 :            :                                 temp = seqnum[i];
    3479                 :          0 :                                 seqnum[i] = seqnum[i+1];
    3480                 :          0 :                                 seqnum[i+1] = temp;
    3481                 :            :                                 sort_done = 0;
    3482                 :            :                         }
    3483                 :            :                 }
    3484                 :            :         }
    3485                 :            : 
    3486                 :          0 :         ndx = start + seqnum[0];
    3487         [ #  # ]:          0 :         if (ndx >= TOKEN_Q_DEPTH)
    3488                 :          0 :                 ndx = ndx % TOKEN_Q_DEPTH;
    3489                 :          0 :         core_if->first_in_nextep_seq = intkn_seq[ndx];
    3490                 :            : 
    3491                 :            :         /* Update seqnum[] by EP numbers  */
    3492         [ #  # ]:          0 :         for (i=0; i<=core_if->dev_if->num_in_eps; i++) {
    3493                 :            :                 ndx = start + i;
    3494         [ #  # ]:          0 :                 if (seqnum[i] < 31) {
    3495                 :          0 :                         ndx = start + seqnum[i];
    3496         [ #  # ]:          0 :                         if (ndx >= TOKEN_Q_DEPTH)
    3497                 :          0 :                                 ndx = ndx % TOKEN_Q_DEPTH;
    3498                 :          0 :                         seqnum[i] = intkn_seq[ndx];
    3499                 :            :                 } else {
    3500         [ #  # ]:          0 :                         if (seqnum[i] < 0xff) {
    3501                 :          0 :                                 seqnum[i] = seqnum[i] - 31;
    3502                 :            :                         } else {
    3503                 :            :                                 break;
    3504                 :            :                         }
    3505                 :            :                 }
    3506                 :            :         }
    3507                 :            : 
    3508                 :            :         /* Update nextep_seq[] based on seqnum[] */
    3509         [ #  # ]:          0 :         for (i=0; i<core_if->dev_if->num_in_eps; i++) {
    3510         [ #  # ]:          0 :                 if (seqnum[i] != 0xff) {
    3511         [ #  # ]:          0 :                         if (seqnum[i+1] != 0xff) {
    3512                 :          0 :                                 core_if->nextep_seq[seqnum[i]] = seqnum[i+1];
    3513                 :            :                         } else {
    3514                 :          0 :                                 core_if->nextep_seq[seqnum[i]] = core_if->first_in_nextep_seq;
    3515                 :          0 :                                 break;
    3516                 :            :                         }
    3517                 :            :                 } else {
    3518                 :            :                         break;
    3519                 :            :                 }
    3520                 :            :         }
    3521                 :            : 
    3522                 :            :         DWC_DEBUGPL(DBG_PCDV, "%s first_in_nextep_seq= %2d; nextep_seq[]:\n",
    3523                 :            :                 __func__, core_if->first_in_nextep_seq);
    3524         [ #  # ]:          0 :         for (i=0; i <= core_if->dev_if->num_in_eps; i++) {
    3525                 :            :                 DWC_DEBUGPL(DBG_PCDV,"%2d\n", core_if->nextep_seq[i]);
    3526                 :            :         }
    3527                 :            : 
    3528                 :            :         /* Flush the Learning Queue */
    3529                 :          0 :         resetctl.d32 = DWC_READ_REG32(&core_if->core_global_regs->grstctl);
    3530                 :          0 :         resetctl.b.intknqflsh = 1;
    3531                 :          0 :         DWC_WRITE_REG32(&core_if->core_global_regs->grstctl, resetctl.d32);
    3532                 :            : 
    3533                 :            : 
    3534                 :          0 : }
    3535                 :            : 
    3536                 :            : /**
    3537                 :            :  * handle the IN EP disable interrupt.
    3538                 :            :  */
    3539                 :          0 : static inline void handle_in_ep_disable_intr(dwc_otg_pcd_t * pcd,
    3540                 :            :                                              const uint32_t epnum)
    3541                 :            : {
    3542                 :          0 :         dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
    3543                 :          0 :         dwc_otg_dev_if_t *dev_if = core_if->dev_if;
    3544                 :            :         deptsiz_data_t dieptsiz = {.d32 = 0 };
    3545                 :          0 :         dctl_data_t dctl = {.d32 = 0 };
    3546                 :            :         dwc_otg_pcd_ep_t *ep;
    3547                 :            :         dwc_ep_t *dwc_ep;
    3548                 :            :         gintmsk_data_t gintmsk_data;
    3549                 :            :         depctl_data_t depctl;
    3550                 :            :         uint32_t diepdma;
    3551                 :            :         uint32_t remain_to_transfer = 0;
    3552                 :            :         uint8_t i;
    3553                 :            :         uint32_t xfer_size;
    3554                 :            : 
    3555                 :            :         ep = get_in_ep(pcd, epnum);
    3556                 :            :         dwc_ep = &ep->dwc_ep;
    3557                 :            : 
    3558         [ #  # ]:          0 :         if (dwc_ep->type == DWC_OTG_EP_TYPE_ISOC) {
    3559                 :          0 :                 dwc_otg_flush_tx_fifo(core_if, dwc_ep->tx_fifo_num);
    3560                 :          0 :                 complete_ep(ep);
    3561                 :          0 :                 return;
    3562                 :            :         }
    3563                 :            : 
    3564                 :            :         DWC_DEBUGPL(DBG_PCD, "diepctl%d=%0x\n", epnum,
    3565                 :            :                     DWC_READ_REG32(&dev_if->in_ep_regs[epnum]->diepctl));
    3566                 :          0 :         dieptsiz.d32 = DWC_READ_REG32(&dev_if->in_ep_regs[epnum]->dieptsiz);
    3567                 :          0 :         depctl.d32 = DWC_READ_REG32(&dev_if->in_ep_regs[epnum]->diepctl);
    3568                 :            : 
    3569                 :            :         DWC_DEBUGPL(DBG_ANY, "pktcnt=%d size=%d\n",
    3570                 :            :                     dieptsiz.b.pktcnt, dieptsiz.b.xfersize);
    3571                 :            : 
    3572   [ #  #  #  # ]:          0 :         if ((core_if->start_predict == 0) || (depctl.b.eptype & 1)) {
    3573         [ #  # ]:          0 :                 if (ep->stopped) {
    3574         [ #  # ]:          0 :                         if (core_if->en_multiple_tx_fifo)
    3575                 :            :                                 /* Flush the Tx FIFO */
    3576                 :          0 :                                 dwc_otg_flush_tx_fifo(core_if, dwc_ep->tx_fifo_num);
    3577                 :            :                         /* Clear the Global IN NP NAK */
    3578                 :            :                         dctl.d32 = 0;
    3579                 :          0 :                         dctl.b.cgnpinnak = 1;
    3580                 :          0 :                         DWC_MODIFY_REG32(&dev_if->dev_global_regs->dctl, dctl.d32, dctl.d32);
    3581                 :            :                         /* Restart the transaction */
    3582         [ #  # ]:          0 :                         if (dieptsiz.b.pktcnt != 0 || dieptsiz.b.xfersize != 0) {
    3583                 :          0 :                                 restart_transfer(pcd, epnum);
    3584                 :            :                         }
    3585                 :            :                 } else {
    3586                 :            :                         /* Restart the transaction */
    3587         [ #  # ]:          0 :                         if (dieptsiz.b.pktcnt != 0 || dieptsiz.b.xfersize != 0) {
    3588                 :          0 :                                 restart_transfer(pcd, epnum);
    3589                 :            :                         }
    3590                 :            :                         DWC_DEBUGPL(DBG_ANY, "STOPPED!!!\n");
    3591                 :            :                 }
    3592                 :            :                 return;
    3593                 :            :         }
    3594                 :            : 
    3595         [ #  # ]:          0 :         if (core_if->start_predict > 2) { // NP IN EP
    3596                 :          0 :                 core_if->start_predict--;
    3597                 :          0 :                 return;
    3598                 :            :         }
    3599                 :            : 
    3600                 :          0 :         core_if->start_predict--;
    3601                 :            : 
    3602         [ #  # ]:          0 :         if (core_if->start_predict == 1) {   // All NP IN Ep's disabled now
    3603                 :            : 
    3604                 :          0 :                 predict_nextep_seq(core_if);
    3605                 :            : 
    3606                 :            :                 /* Update all active IN EP's NextEP field based of nextep_seq[] */
    3607         [ #  # ]:          0 :                 for ( i = 0; i <= core_if->dev_if->num_in_eps; i++) {
    3608                 :          0 :                         depctl.d32 =
    3609                 :          0 :                             DWC_READ_REG32(&dev_if->in_ep_regs[i]->diepctl);
    3610         [ #  # ]:          0 :                         if (core_if->nextep_seq[i] != 0xff) {        // Active NP IN EP
    3611                 :          0 :                                 depctl.b.nextep = core_if->nextep_seq[i];
    3612                 :          0 :                                 DWC_WRITE_REG32(&dev_if->in_ep_regs[i]->diepctl, depctl.d32);
    3613                 :            :                         }
    3614                 :            :                 }
    3615                 :            :                 /* Flush Shared NP TxFIFO */
    3616                 :          0 :                 dwc_otg_flush_tx_fifo(core_if, 0);
    3617                 :            :                 /* Rewind buffers */
    3618         [ #  # ]:          0 :                 if (!core_if->dma_desc_enable) {
    3619                 :          0 :                         i = core_if->first_in_nextep_seq;
    3620                 :            :                         do {
    3621                 :          0 :                                 ep = get_in_ep(pcd, i);
    3622                 :          0 :                                 dieptsiz.d32 = DWC_READ_REG32(&dev_if->in_ep_regs[i]->dieptsiz);
    3623                 :          0 :                                 xfer_size = ep->dwc_ep.total_len - ep->dwc_ep.xfer_count;
    3624         [ #  # ]:          0 :                                 if (xfer_size > ep->dwc_ep.maxxfer)
    3625                 :            :                                         xfer_size = ep->dwc_ep.maxxfer;
    3626                 :          0 :                                 depctl.d32 = DWC_READ_REG32(&dev_if->in_ep_regs[i]->diepctl);
    3627         [ #  # ]:          0 :                                 if (dieptsiz.b.pktcnt != 0) {
    3628         [ #  # ]:          0 :                                         if (xfer_size == 0) {
    3629                 :            :                                                 remain_to_transfer = 0;
    3630                 :            :                                         } else {
    3631         [ #  # ]:          0 :                                                 if ((xfer_size % ep->dwc_ep.maxpacket) == 0) {
    3632                 :          0 :                                                         remain_to_transfer =
    3633                 :          0 :                                                                 dieptsiz.b.pktcnt * ep->dwc_ep.maxpacket;
    3634                 :            :                                                 } else {
    3635                 :          0 :                                                         remain_to_transfer = ((dieptsiz.b.pktcnt -1) * ep->dwc_ep.maxpacket)
    3636                 :          0 :                                                                 + (xfer_size % ep->dwc_ep.maxpacket);
    3637                 :            :                                                 }
    3638                 :            :                                         }
    3639                 :          0 :                                         diepdma = DWC_READ_REG32(&dev_if->in_ep_regs[i]->diepdma);
    3640                 :          0 :                                         dieptsiz.b.xfersize = remain_to_transfer;
    3641                 :          0 :                                         DWC_WRITE_REG32(&dev_if->in_ep_regs[i]->dieptsiz, dieptsiz.d32);
    3642                 :          0 :                                         diepdma = ep->dwc_ep.dma_addr + (xfer_size - remain_to_transfer);
    3643                 :          0 :                                         DWC_WRITE_REG32(&dev_if->in_ep_regs[i]->diepdma, diepdma);
    3644                 :            :                                 }
    3645                 :          0 :                                 i = core_if->nextep_seq[i];
    3646         [ #  # ]:          0 :                         } while (i != core_if->first_in_nextep_seq);
    3647                 :            :                 } else { // dma_desc_enable
    3648                 :          0 :                                 DWC_PRINTF("%s Learning Queue not supported in DDMA\n", __func__);
    3649                 :            :                 }
    3650                 :            : 
    3651                 :            :                 /* Restart transfers in predicted sequences */
    3652                 :          0 :                 i = core_if->first_in_nextep_seq;
    3653                 :            :                 do {
    3654                 :          0 :                         dieptsiz.d32 = DWC_READ_REG32(&dev_if->in_ep_regs[i]->dieptsiz);
    3655                 :          0 :                         depctl.d32 = DWC_READ_REG32(&dev_if->in_ep_regs[i]->diepctl);
    3656         [ #  # ]:          0 :                         if (dieptsiz.b.pktcnt != 0) {
    3657                 :          0 :                                 depctl.d32 = DWC_READ_REG32(&dev_if->in_ep_regs[i]->diepctl);
    3658                 :          0 :                                 depctl.b.epena = 1;
    3659                 :          0 :                                 depctl.b.cnak = 1;
    3660                 :          0 :                                 DWC_WRITE_REG32(&dev_if->in_ep_regs[i]->diepctl, depctl.d32);
    3661                 :            :                         }
    3662                 :          0 :                         i = core_if->nextep_seq[i];
    3663         [ #  # ]:          0 :                 } while (i != core_if->first_in_nextep_seq);
    3664                 :            : 
    3665                 :            :                 /* Clear the global non-periodic IN NAK handshake */
    3666                 :          0 :                 dctl.d32 = 0;
    3667                 :          0 :                 dctl.b.cgnpinnak = 1;
    3668                 :          0 :                 DWC_MODIFY_REG32(&dev_if->dev_global_regs->dctl, dctl.d32, dctl.d32);
    3669                 :            : 
    3670                 :            :                 /* Unmask EP Mismatch interrupt */
    3671                 :          0 :                 gintmsk_data.d32 = 0;
    3672                 :          0 :                 gintmsk_data.b.epmismatch = 1;
    3673                 :          0 :                 DWC_MODIFY_REG32(&core_if->core_global_regs->gintmsk, 0, gintmsk_data.d32);
    3674                 :            : 
    3675                 :          0 :                 core_if->start_predict = 0;
    3676                 :            : 
    3677                 :            :         }
    3678                 :            : }
    3679                 :            : 
    3680                 :            : /**
    3681                 :            :  * Handler for the IN EP timeout handshake interrupt.
    3682                 :            :  */
    3683                 :          0 : static inline void handle_in_ep_timeout_intr(dwc_otg_pcd_t * pcd,
    3684                 :            :                                              const uint32_t epnum)
    3685                 :            : {
    3686                 :          0 :         dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
    3687                 :          0 :         dwc_otg_dev_if_t *dev_if = core_if->dev_if;
    3688                 :            : 
    3689                 :            : #ifdef DEBUG
    3690                 :            :         deptsiz_data_t dieptsiz = {.d32 = 0 };
    3691                 :            :         uint32_t num = 0;
    3692                 :            : #endif
    3693                 :          0 :         dctl_data_t dctl = {.d32 = 0 };
    3694                 :            :         dwc_otg_pcd_ep_t *ep;
    3695                 :            : 
    3696                 :          0 :         gintmsk_data_t intr_mask = {.d32 = 0 };
    3697                 :            : 
    3698                 :            :         ep = get_in_ep(pcd, epnum);
    3699                 :            : 
    3700                 :            :         /* Disable the NP Tx Fifo Empty Interrrupt */
    3701         [ #  # ]:          0 :         if (!core_if->dma_enable) {
    3702                 :          0 :                 intr_mask.b.nptxfempty = 1;
    3703                 :          0 :                 DWC_MODIFY_REG32(&core_if->core_global_regs->gintmsk,
    3704                 :            :                                  intr_mask.d32, 0);
    3705                 :            :         }
    3706                 :            :         /** @todo NGS Check EP type.
    3707                 :            :          * Implement for Periodic EPs */
    3708                 :            :         /*
    3709                 :            :          * Non-periodic EP
    3710                 :            :          */
    3711                 :            :         /* Enable the Global IN NAK Effective Interrupt */
    3712                 :          0 :         intr_mask.b.ginnakeff = 1;
    3713                 :          0 :         DWC_MODIFY_REG32(&core_if->core_global_regs->gintmsk, 0, intr_mask.d32);
    3714                 :            : 
    3715                 :            :         /* Set Global IN NAK */
    3716                 :          0 :         dctl.b.sgnpinnak = 1;
    3717                 :          0 :         DWC_MODIFY_REG32(&dev_if->dev_global_regs->dctl, dctl.d32, dctl.d32);
    3718                 :            : 
    3719                 :          0 :         ep->stopped = 1;
    3720                 :            : 
    3721                 :            : #ifdef DEBUG
    3722                 :            :         dieptsiz.d32 = DWC_READ_REG32(&dev_if->in_ep_regs[num]->dieptsiz);
    3723                 :            :         DWC_DEBUGPL(DBG_ANY, "pktcnt=%d size=%d\n",
    3724                 :            :                     dieptsiz.b.pktcnt, dieptsiz.b.xfersize);
    3725                 :            : #endif
    3726                 :            : 
    3727                 :            : #ifdef DISABLE_PERIODIC_EP
    3728                 :            :         /*
    3729                 :            :          * Set the NAK bit for this EP to
    3730                 :            :          * start the disable process.
    3731                 :            :          */
    3732                 :            :         diepctl.d32 = 0;
    3733                 :            :         diepctl.b.snak = 1;
    3734                 :            :         DWC_MODIFY_REG32(&dev_if->in_ep_regs[num]->diepctl, diepctl.d32,
    3735                 :            :                          diepctl.d32);
    3736                 :            :         ep->disabling = 1;
    3737                 :            :         ep->stopped = 1;
    3738                 :            : #endif
    3739                 :          0 : }
    3740                 :            : 
    3741                 :            : /**
    3742                 :            :  * Handler for the IN EP NAK interrupt.
    3743                 :            :  */
    3744                 :            : static inline int32_t handle_in_ep_nak_intr(dwc_otg_pcd_t * pcd,
    3745                 :            :                                             const uint32_t epnum)
    3746                 :            : {
    3747                 :            :         /** @todo implement ISR */
    3748                 :            :         dwc_otg_core_if_t *core_if;
    3749                 :            :         diepmsk_data_t intr_mask = {.d32 = 0 };
    3750                 :            : 
    3751                 :            :         DWC_PRINTF("INTERRUPT Handler not implemented for %s\n", "IN EP NAK");
    3752                 :            :         core_if = GET_CORE_IF(pcd);
    3753                 :            :         intr_mask.b.nak = 1;
    3754                 :            : 
    3755                 :            :         if (core_if->multiproc_int_enable) {
    3756                 :            :                 DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->
    3757                 :            :                                  diepeachintmsk[epnum], intr_mask.d32, 0);
    3758                 :            :         } else {
    3759                 :            :                 DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->diepmsk,
    3760                 :            :                                  intr_mask.d32, 0);
    3761                 :            :         }
    3762                 :            : 
    3763                 :            :         return 1;
    3764                 :            : }
    3765                 :            : 
    3766                 :            : /**
    3767                 :            :  * Handler for the OUT EP Babble interrupt.
    3768                 :            :  */
    3769                 :          0 : static inline int32_t handle_out_ep_babble_intr(dwc_otg_pcd_t * pcd,
    3770                 :            :                                                 const uint32_t epnum)
    3771                 :            : {
    3772                 :            :         /** @todo implement ISR */
    3773                 :            :         dwc_otg_core_if_t *core_if;
    3774                 :          0 :         doepmsk_data_t intr_mask = {.d32 = 0 };
    3775                 :            : 
    3776                 :          0 :         DWC_PRINTF("INTERRUPT Handler not implemented for %s\n",
    3777                 :            :                    "OUT EP Babble");
    3778                 :          0 :         core_if = GET_CORE_IF(pcd);
    3779                 :          0 :         intr_mask.b.babble = 1;
    3780                 :            : 
    3781         [ #  # ]:          0 :         if (core_if->multiproc_int_enable) {
    3782                 :          0 :                 DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->
    3783                 :            :                                  doepeachintmsk[epnum], intr_mask.d32, 0);
    3784                 :            :         } else {
    3785                 :          0 :                 DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->doepmsk,
    3786                 :            :                                  intr_mask.d32, 0);
    3787                 :            :         }
    3788                 :            : 
    3789                 :          0 :         return 1;
    3790                 :            : }
    3791                 :            : 
    3792                 :            : /**
    3793                 :            :  * Handler for the OUT EP NAK interrupt.
    3794                 :            :  */
    3795                 :          0 : static inline int32_t handle_out_ep_nak_intr(dwc_otg_pcd_t * pcd,
    3796                 :            :                                              const uint32_t epnum)
    3797                 :            : {
    3798                 :            :         /** @todo implement ISR */
    3799                 :            :         dwc_otg_core_if_t *core_if;
    3800                 :          0 :         doepmsk_data_t intr_mask = {.d32 = 0 };
    3801                 :            : 
    3802                 :            :         DWC_DEBUGPL(DBG_ANY, "INTERRUPT Handler not implemented for %s\n", "OUT EP NAK");
    3803                 :          0 :         core_if = GET_CORE_IF(pcd);
    3804                 :          0 :         intr_mask.b.nak = 1;
    3805                 :            : 
    3806         [ #  # ]:          0 :         if (core_if->multiproc_int_enable) {
    3807                 :          0 :                 DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->
    3808                 :            :                                  doepeachintmsk[epnum], intr_mask.d32, 0);
    3809                 :            :         } else {
    3810                 :          0 :                 DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->doepmsk,
    3811                 :            :                                  intr_mask.d32, 0);
    3812                 :            :         }
    3813                 :            : 
    3814                 :          0 :         return 1;
    3815                 :            : }
    3816                 :            : 
    3817                 :            : /**
    3818                 :            :  * Handler for the OUT EP NYET interrupt.
    3819                 :            :  */
    3820                 :          0 : static inline int32_t handle_out_ep_nyet_intr(dwc_otg_pcd_t * pcd,
    3821                 :            :                                               const uint32_t epnum)
    3822                 :            : {
    3823                 :            :         /** @todo implement ISR */
    3824                 :            :         dwc_otg_core_if_t *core_if;
    3825                 :          0 :         doepmsk_data_t intr_mask = {.d32 = 0 };
    3826                 :            : 
    3827                 :          0 :         DWC_PRINTF("INTERRUPT Handler not implemented for %s\n", "OUT EP NYET");
    3828                 :          0 :         core_if = GET_CORE_IF(pcd);
    3829                 :          0 :         intr_mask.b.nyet = 1;
    3830                 :            : 
    3831         [ #  # ]:          0 :         if (core_if->multiproc_int_enable) {
    3832                 :          0 :                 DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->
    3833                 :            :                                  doepeachintmsk[epnum], intr_mask.d32, 0);
    3834                 :            :         } else {
    3835                 :          0 :                 DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->doepmsk,
    3836                 :            :                                  intr_mask.d32, 0);
    3837                 :            :         }
    3838                 :            : 
    3839                 :          0 :         return 1;
    3840                 :            : }
    3841                 :            : 
    3842                 :            : /**
    3843                 :            :  * This interrupt indicates that an IN EP has a pending Interrupt.
    3844                 :            :  * The sequence for handling the IN EP interrupt is shown below:
    3845                 :            :  * -#   Read the Device All Endpoint Interrupt register
    3846                 :            :  * -#   Repeat the following for each IN EP interrupt bit set (from
    3847                 :            :  *              LSB to MSB).
    3848                 :            :  * -#   Read the Device Endpoint Interrupt (DIEPINTn) register
    3849                 :            :  * -#   If "Transfer Complete" call the request complete function
    3850                 :            :  * -#   If "Endpoint Disabled" complete the EP disable procedure.
    3851                 :            :  * -#   If "AHB Error Interrupt" log error
    3852                 :            :  * -#   If "Time-out Handshake" log error
    3853                 :            :  * -#   If "IN Token Received when TxFIFO Empty" write packet to Tx
    3854                 :            :  *              FIFO.
    3855                 :            :  * -#   If "IN Token EP Mismatch" (disable, this is handled by EP
    3856                 :            :  *              Mismatch Interrupt)
    3857                 :            :  */
    3858                 :          0 : static int32_t dwc_otg_pcd_handle_in_ep_intr(dwc_otg_pcd_t * pcd)
    3859                 :            : {
    3860                 :            : #define CLEAR_IN_EP_INTR(__core_if,__epnum,__intr) \
    3861                 :            : do { \
    3862                 :            :                 diepint_data_t diepint = {.d32=0}; \
    3863                 :            :                 diepint.b.__intr = 1; \
    3864                 :            :                 DWC_WRITE_REG32(&__core_if->dev_if->in_ep_regs[__epnum]->diepint, \
    3865                 :            :                 diepint.d32); \
    3866                 :            : } while (0)
    3867                 :            : 
    3868                 :          0 :         dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
    3869                 :          0 :         dwc_otg_dev_if_t *dev_if = core_if->dev_if;
    3870                 :            :         diepint_data_t diepint = {.d32 = 0 };
    3871                 :            :         depctl_data_t depctl = {.d32 = 0 };
    3872                 :            :         uint32_t ep_intr;
    3873                 :            :         uint32_t epnum = 0;
    3874                 :            :         dwc_otg_pcd_ep_t *ep;
    3875                 :            :         dwc_ep_t *dwc_ep;
    3876                 :          0 :         gintmsk_data_t intr_mask = {.d32 = 0 };
    3877                 :            : 
    3878                 :            :         DWC_DEBUGPL(DBG_PCDV, "%s(%p)\n", __func__, pcd);
    3879                 :            : 
    3880                 :            :         /* Read in the device interrupt bits */
    3881                 :          0 :         ep_intr = dwc_otg_read_dev_all_in_ep_intr(core_if);
    3882                 :            : 
    3883                 :            :         /* Service the Device IN interrupts for each endpoint */
    3884         [ #  # ]:          0 :         while (ep_intr) {
    3885         [ #  # ]:          0 :                 if (ep_intr & 0x1) {
    3886                 :            :                         uint32_t empty_msk;
    3887                 :            :                         /* Get EP pointer */
    3888                 :            :                         ep = get_in_ep(pcd, epnum);
    3889                 :          0 :                         dwc_ep = &ep->dwc_ep;
    3890                 :            : 
    3891                 :            :                         depctl.d32 =
    3892                 :          0 :                             DWC_READ_REG32(&dev_if->in_ep_regs[epnum]->diepctl);
    3893                 :          0 :                         empty_msk =
    3894                 :          0 :                             DWC_READ_REG32(&dev_if->
    3895                 :            :                                            dev_global_regs->dtknqr4_fifoemptymsk);
    3896                 :            : 
    3897                 :            :                         DWC_DEBUGPL(DBG_PCDV,
    3898                 :            :                                     "IN EP INTERRUPT - %d\nepmty_msk - %8x  diepctl - %8x\n",
    3899                 :            :                                     epnum, empty_msk, depctl.d32);
    3900                 :            : 
    3901                 :            :                         DWC_DEBUGPL(DBG_PCD,
    3902                 :            :                                     "EP%d-%s: type=%d, mps=%d\n",
    3903                 :            :                                     dwc_ep->num, (dwc_ep->is_in ? "IN" : "OUT"),
    3904                 :            :                                     dwc_ep->type, dwc_ep->maxpacket);
    3905                 :            : 
    3906                 :            :                         diepint.d32 =
    3907                 :          0 :                             dwc_otg_read_dev_in_ep_intr(core_if, dwc_ep);
    3908                 :            : 
    3909                 :            :                         DWC_DEBUGPL(DBG_PCDV,
    3910                 :            :                                     "EP %d Interrupt Register - 0x%x\n", epnum,
    3911                 :            :                                     diepint.d32);
    3912                 :            :                         /* Transfer complete */
    3913         [ #  # ]:          0 :                         if (diepint.b.xfercompl) {
    3914                 :            :                                 /* Disable the NP Tx FIFO Empty
    3915                 :            :                                  * Interrupt */
    3916         [ #  # ]:          0 :                                 if (core_if->en_multiple_tx_fifo == 0) {
    3917                 :          0 :                                         intr_mask.b.nptxfempty = 1;
    3918                 :          0 :                                         DWC_MODIFY_REG32
    3919                 :          0 :                                             (&core_if->core_global_regs->gintmsk,
    3920                 :            :                                              intr_mask.d32, 0);
    3921                 :            :                                 } else {
    3922                 :            :                                         /* Disable the Tx FIFO Empty Interrupt for this EP */
    3923                 :          0 :                                         uint32_t fifoemptymsk =
    3924                 :          0 :                                             0x1 << dwc_ep->num;
    3925                 :          0 :                                         DWC_MODIFY_REG32(&core_if->
    3926                 :          0 :                                                          dev_if->dev_global_regs->dtknqr4_fifoemptymsk,
    3927                 :            :                                                          fifoemptymsk, 0);
    3928                 :            :                                 }
    3929                 :            :                                 /* Clear the bit in DIEPINTn for this interrupt */
    3930                 :          0 :                                 CLEAR_IN_EP_INTR(core_if, epnum, xfercompl);
    3931                 :            : 
    3932                 :            :                                 /* Complete the transfer */
    3933         [ #  # ]:          0 :                                 if (epnum == 0) {
    3934                 :          0 :                                         handle_ep0(pcd);
    3935                 :            :                                 }
    3936                 :            : #ifdef DWC_EN_ISOC
    3937                 :            :                                 else if (dwc_ep->type == DWC_OTG_EP_TYPE_ISOC) {
    3938                 :            :                                         if (!ep->stopped)
    3939                 :            :                                                 complete_iso_ep(pcd, ep);
    3940                 :            :                                 }
    3941                 :            : #endif /* DWC_EN_ISOC */
    3942                 :            : #ifdef DWC_UTE_PER_IO
    3943                 :            :                                 else if (dwc_ep->type == DWC_OTG_EP_TYPE_ISOC) {
    3944                 :            :                                         if (!ep->stopped)
    3945                 :            :                                                 complete_xiso_ep(ep);
    3946                 :            :                                 }
    3947                 :            : #endif /* DWC_UTE_PER_IO */
    3948                 :            :                                 else {
    3949   [ #  #  #  # ]:          0 :                                         if (dwc_ep->type == DWC_OTG_EP_TYPE_ISOC &&
    3950                 :          0 :                                                         dwc_ep->bInterval > 1) {
    3951                 :          0 :                                                 dwc_ep->frame_num += dwc_ep->bInterval;
    3952         [ #  # ]:          0 :                                                 if (dwc_ep->frame_num > 0x3FFF)
    3953                 :            :                                                 {
    3954                 :          0 :                                                         dwc_ep->frm_overrun = 1;
    3955                 :          0 :                                                         dwc_ep->frame_num &= 0x3FFF;
    3956                 :            :                                                 } else
    3957                 :          0 :                                                         dwc_ep->frm_overrun = 0;
    3958                 :            :                                         }
    3959                 :          0 :                                         complete_ep(ep);
    3960         [ #  # ]:          0 :                                         if(diepint.b.nak)
    3961                 :          0 :                                                 CLEAR_IN_EP_INTR(core_if, epnum, nak);
    3962                 :            :                                 }
    3963                 :            :                         }
    3964                 :            :                         /* Endpoint disable      */
    3965         [ #  # ]:          0 :                         if (diepint.b.epdisabled) {
    3966                 :            :                                 DWC_DEBUGPL(DBG_ANY, "EP%d IN disabled\n",
    3967                 :            :                                             epnum);
    3968                 :          0 :                                 handle_in_ep_disable_intr(pcd, epnum);
    3969                 :            : 
    3970                 :            :                                 /* Clear the bit in DIEPINTn for this interrupt */
    3971                 :          0 :                                 CLEAR_IN_EP_INTR(core_if, epnum, epdisabled);
    3972                 :            :                         }
    3973                 :            :                         /* AHB Error */
    3974         [ #  # ]:          0 :                         if (diepint.b.ahberr) {
    3975                 :          0 :                                 DWC_ERROR("EP%d IN AHB Error\n", epnum);
    3976                 :            :                                 /* Clear the bit in DIEPINTn for this interrupt */
    3977                 :          0 :                                 CLEAR_IN_EP_INTR(core_if, epnum, ahberr);
    3978                 :            :                         }
    3979                 :            :                         /* TimeOUT Handshake (non-ISOC IN EPs) */
    3980         [ #  # ]:          0 :                         if (diepint.b.timeout) {
    3981                 :          0 :                                 DWC_ERROR("EP%d IN Time-out\n", epnum);
    3982                 :          0 :                                 handle_in_ep_timeout_intr(pcd, epnum);
    3983                 :            : 
    3984                 :          0 :                                 CLEAR_IN_EP_INTR(core_if, epnum, timeout);
    3985                 :            :                         }
    3986                 :            :                         /** IN Token received with TxF Empty */
    3987         [ #  # ]:          0 :                         if (diepint.b.intktxfemp) {
    3988                 :            :                                 DWC_DEBUGPL(DBG_ANY,
    3989                 :            :                                             "EP%d IN TKN TxFifo Empty\n",
    3990                 :            :                                             epnum);
    3991   [ #  #  #  # ]:          0 :                                 if (!ep->stopped && epnum != 0) {
    3992                 :            : 
    3993                 :          0 :                                         diepmsk_data_t diepmsk = {.d32 = 0 };
    3994                 :          0 :                                         diepmsk.b.intktxfemp = 1;
    3995                 :            : 
    3996         [ #  # ]:          0 :                                         if (core_if->multiproc_int_enable) {
    3997                 :          0 :                                                 DWC_MODIFY_REG32
    3998                 :          0 :                                                     (&dev_if->dev_global_regs->diepeachintmsk
    3999                 :            :                                                      [epnum], diepmsk.d32, 0);
    4000                 :            :                                         } else {
    4001                 :          0 :                                                 DWC_MODIFY_REG32
    4002                 :          0 :                                                     (&dev_if->dev_global_regs->diepmsk,
    4003                 :            :                                                      diepmsk.d32, 0);
    4004                 :            :                                         }
    4005         [ #  # ]:          0 :                                 } else if (core_if->dma_desc_enable
    4006         [ #  # ]:          0 :                                            && epnum == 0
    4007         [ #  # ]:          0 :                                            && pcd->ep0state ==
    4008                 :            :                                            EP0_OUT_STATUS_PHASE) {
    4009                 :            :                                         // EP0 IN set STALL
    4010                 :          0 :                                         depctl.d32 =
    4011                 :          0 :                                             DWC_READ_REG32(&dev_if->in_ep_regs
    4012                 :          0 :                                                            [epnum]->diepctl);
    4013                 :            : 
    4014                 :            :                                         /* set the disable and stall bits */
    4015         [ #  # ]:          0 :                                         if (depctl.b.epena) {
    4016                 :          0 :                                                 depctl.b.epdis = 1;
    4017                 :            :                                         }
    4018                 :          0 :                                         depctl.b.stall = 1;
    4019                 :          0 :                                         DWC_WRITE_REG32(&dev_if->in_ep_regs
    4020                 :          0 :                                                         [epnum]->diepctl,
    4021                 :            :                                                         depctl.d32);
    4022                 :            :                                 }
    4023                 :          0 :                                 CLEAR_IN_EP_INTR(core_if, epnum, intktxfemp);
    4024                 :            :                         }
    4025                 :            :                         /** IN Token Received with EP mismatch */
    4026         [ #  # ]:          0 :                         if (diepint.b.intknepmis) {
    4027                 :            :                                 DWC_DEBUGPL(DBG_ANY,
    4028                 :            :                                             "EP%d IN TKN EP Mismatch\n", epnum);
    4029                 :          0 :                                 CLEAR_IN_EP_INTR(core_if, epnum, intknepmis);
    4030                 :            :                         }
    4031                 :            :                         /** IN Endpoint NAK Effective */
    4032         [ #  # ]:          0 :                         if (diepint.b.inepnakeff) {
    4033                 :            :                                 DWC_DEBUGPL(DBG_ANY,
    4034                 :            :                                             "EP%d IN EP NAK Effective\n",
    4035                 :            :                                             epnum);
    4036                 :            :                                 /* Periodic EP */
    4037         [ #  # ]:          0 :                                 if (ep->disabling) {
    4038                 :          0 :                                         depctl.d32 = 0;
    4039                 :          0 :                                         depctl.b.snak = 1;
    4040                 :          0 :                                         depctl.b.epdis = 1;
    4041                 :          0 :                                         DWC_MODIFY_REG32(&dev_if->in_ep_regs
    4042                 :          0 :                                                          [epnum]->diepctl,
    4043                 :            :                                                          depctl.d32,
    4044                 :            :                                                          depctl.d32);
    4045                 :            :                                 }
    4046                 :          0 :                                 CLEAR_IN_EP_INTR(core_if, epnum, inepnakeff);
    4047                 :            : 
    4048                 :            :                         }
    4049                 :            : 
    4050                 :            :                         /** IN EP Tx FIFO Empty Intr */
    4051         [ #  # ]:          0 :                         if (diepint.b.emptyintr) {
    4052                 :            :                                 DWC_DEBUGPL(DBG_ANY,
    4053                 :            :                                             "EP%d Tx FIFO Empty Intr \n",
    4054                 :            :                                             epnum);
    4055                 :          0 :                                 write_empty_tx_fifo(pcd, epnum);
    4056                 :            : 
    4057                 :          0 :                                 CLEAR_IN_EP_INTR(core_if, epnum, emptyintr);
    4058                 :            : 
    4059                 :            :                         }
    4060                 :            : 
    4061                 :            :                         /** IN EP BNA Intr */
    4062         [ #  # ]:          0 :                         if (diepint.b.bna) {
    4063                 :          0 :                                 CLEAR_IN_EP_INTR(core_if, epnum, bna);
    4064         [ #  # ]:          0 :                                 if (core_if->dma_desc_enable) {
    4065                 :            : #ifdef DWC_EN_ISOC
    4066                 :            :                                         if (dwc_ep->type ==
    4067                 :            :                                             DWC_OTG_EP_TYPE_ISOC) {
    4068                 :            :                                                 /*
    4069                 :            :                                                  * This checking is performed to prevent first "false" BNA
    4070                 :            :                                                  * handling occuring right after reconnect
    4071                 :            :                                                  */
    4072                 :            :                                                 if (dwc_ep->next_frame !=
    4073                 :            :                                                     0xffffffff)
    4074                 :            :                                                         dwc_otg_pcd_handle_iso_bna(ep);
    4075                 :            :                                         } else
    4076                 :            : #endif                          /* DWC_EN_ISOC */
    4077                 :            :                                         {
    4078                 :          0 :                                                 dwc_otg_pcd_handle_noniso_bna(ep);
    4079                 :            :                                         }
    4080                 :            :                                 }
    4081                 :            :                         }
    4082                 :            :                         /* NAK Interrutp */
    4083         [ #  # ]:          0 :                         if (diepint.b.nak) {
    4084                 :            :                                 DWC_DEBUGPL(DBG_ANY, "EP%d IN NAK Interrupt\n",
    4085                 :            :                                             epnum);
    4086         [ #  # ]:          0 :                                 if (ep->dwc_ep.type == DWC_OTG_EP_TYPE_ISOC) {
    4087                 :            :                                         depctl_data_t depctl;
    4088         [ #  # ]:          0 :                                         if (ep->dwc_ep.frame_num == 0xFFFFFFFF) {
    4089                 :          0 :                                                 ep->dwc_ep.frame_num = core_if->frame_num;
    4090         [ #  # ]:          0 :                                                 if (ep->dwc_ep.bInterval > 1) {
    4091                 :            :                                                         depctl.d32 = 0;
    4092                 :          0 :                                                         depctl.d32 = DWC_READ_REG32(&dev_if->in_ep_regs[epnum]->diepctl);
    4093         [ #  # ]:          0 :                                                         if (ep->dwc_ep.frame_num & 0x1) {
    4094                 :          0 :                                                                 depctl.b.setd1pid = 1;
    4095                 :          0 :                                                                 depctl.b.setd0pid = 0;
    4096                 :            :                                                         } else {
    4097                 :          0 :                                                                 depctl.b.setd0pid = 1;
    4098                 :          0 :                                                                 depctl.b.setd1pid = 0;
    4099                 :            :                                                         }
    4100                 :          0 :                                                         DWC_WRITE_REG32(&dev_if->in_ep_regs[epnum]->diepctl, depctl.d32);
    4101                 :            :                                                 }
    4102                 :          0 :                                                 start_next_request(ep);
    4103                 :            :                                         }
    4104                 :          0 :                                         ep->dwc_ep.frame_num += ep->dwc_ep.bInterval;
    4105         [ #  # ]:          0 :                                         if (dwc_ep->frame_num > 0x3FFF)   {
    4106                 :          0 :                                                 dwc_ep->frm_overrun = 1;
    4107                 :          0 :                                                 dwc_ep->frame_num &= 0x3FFF;
    4108                 :            :                                         } else
    4109                 :          0 :                                                 dwc_ep->frm_overrun = 0;
    4110                 :            :                                 }
    4111                 :            : 
    4112                 :          0 :                                 CLEAR_IN_EP_INTR(core_if, epnum, nak);
    4113                 :            :                         }
    4114                 :            :                 }
    4115                 :          0 :                 epnum++;
    4116                 :          0 :                 ep_intr >>= 1;
    4117                 :            :         }
    4118                 :            : 
    4119                 :          0 :         return 1;
    4120                 :            : #undef CLEAR_IN_EP_INTR
    4121                 :            : }
    4122                 :            : 
    4123                 :            : /**
    4124                 :            :  * This interrupt indicates that an OUT EP has a pending Interrupt.
    4125                 :            :  * The sequence for handling the OUT EP interrupt is shown below:
    4126                 :            :  * -#   Read the Device All Endpoint Interrupt register
    4127                 :            :  * -#   Repeat the following for each OUT EP interrupt bit set (from
    4128                 :            :  *              LSB to MSB).
    4129                 :            :  * -#   Read the Device Endpoint Interrupt (DOEPINTn) register
    4130                 :            :  * -#   If "Transfer Complete" call the request complete function
    4131                 :            :  * -#   If "Endpoint Disabled" complete the EP disable procedure.
    4132                 :            :  * -#   If "AHB Error Interrupt" log error
    4133                 :            :  * -#   If "Setup Phase Done" process Setup Packet (See Standard USB
    4134                 :            :  *              Command Processing)
    4135                 :            :  */
    4136                 :          0 : static int32_t dwc_otg_pcd_handle_out_ep_intr(dwc_otg_pcd_t * pcd)
    4137                 :            : {
    4138                 :            : #define CLEAR_OUT_EP_INTR(__core_if,__epnum,__intr) \
    4139                 :            : do { \
    4140                 :            :                 doepint_data_t doepint = {.d32=0}; \
    4141                 :            :                 doepint.b.__intr = 1; \
    4142                 :            :                 DWC_WRITE_REG32(&__core_if->dev_if->out_ep_regs[__epnum]->doepint, \
    4143                 :            :                 doepint.d32); \
    4144                 :            : } while (0)
    4145                 :            : 
    4146                 :          0 :         dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
    4147                 :            :         uint32_t ep_intr;
    4148                 :            :         doepint_data_t doepint = {.d32 = 0 };
    4149                 :            :         uint32_t epnum = 0;
    4150                 :            :         dwc_otg_pcd_ep_t *ep;
    4151                 :            :         dwc_ep_t *dwc_ep;
    4152                 :            :         dctl_data_t dctl = {.d32 = 0 };
    4153                 :          0 :         gintmsk_data_t gintmsk = {.d32 = 0 };
    4154                 :            : 
    4155                 :            : 
    4156                 :            :         DWC_DEBUGPL(DBG_PCDV, "%s()\n", __func__);
    4157                 :            : 
    4158                 :            :         /* Read in the device interrupt bits */
    4159                 :          0 :         ep_intr = dwc_otg_read_dev_all_out_ep_intr(core_if);
    4160                 :            : 
    4161         [ #  # ]:          0 :         while (ep_intr) {
    4162         [ #  # ]:          0 :                 if (ep_intr & 0x1) {
    4163                 :            :                         /* Get EP pointer */
    4164                 :            :                         ep = get_out_ep(pcd, epnum);
    4165                 :          0 :                         dwc_ep = &ep->dwc_ep;
    4166                 :            : 
    4167                 :            : #ifdef VERBOSE
    4168                 :            :                         DWC_DEBUGPL(DBG_PCDV,
    4169                 :            :                                     "EP%d-%s: type=%d, mps=%d\n",
    4170                 :            :                                     dwc_ep->num, (dwc_ep->is_in ? "IN" : "OUT"),
    4171                 :            :                                     dwc_ep->type, dwc_ep->maxpacket);
    4172                 :            : #endif
    4173                 :          0 :                         doepint.d32 =
    4174                 :          0 :                             dwc_otg_read_dev_out_ep_intr(core_if, dwc_ep);
    4175                 :            :                         /* Moved this interrupt upper due to core deffect of asserting
    4176                 :            :                          * OUT EP 0 xfercompl along with stsphsrcvd in BDMA */
    4177         [ #  # ]:          0 :                         if (doepint.b.stsphsercvd) {
    4178                 :            :                                 deptsiz0_data_t deptsiz;
    4179                 :          0 :                                 CLEAR_OUT_EP_INTR(core_if, epnum, stsphsercvd);
    4180                 :            :                                 deptsiz.d32 =
    4181                 :          0 :                                     DWC_READ_REG32(&core_if->dev_if->
    4182                 :          0 :                                                    out_ep_regs[0]->doeptsiz);
    4183         [ #  # ]:          0 :                                 if (core_if->snpsid >= OTG_CORE_REV_3_00a
    4184         [ #  # ]:          0 :                                     && core_if->dma_enable
    4185         [ #  # ]:          0 :                                     && core_if->dma_desc_enable == 0
    4186         [ #  # ]:          0 :                                     && doepint.b.xfercompl
    4187         [ #  # ]:          0 :                                     && deptsiz.b.xfersize == 24) {
    4188                 :          0 :                                         CLEAR_OUT_EP_INTR(core_if, epnum,
    4189                 :            :                                                           xfercompl);
    4190                 :          0 :                                         doepint.b.xfercompl = 0;
    4191                 :          0 :                                         ep0_out_start(core_if, pcd);
    4192                 :            :                                 }
    4193   [ #  #  #  # ]:          0 :                                 if ((core_if->dma_desc_enable) ||
    4194                 :          0 :                                     (core_if->dma_enable
    4195         [ #  # ]:          0 :                                      && core_if->snpsid >=
    4196                 :            :                                      OTG_CORE_REV_3_00a)) {
    4197                 :          0 :                                         do_setup_in_status_phase(pcd);
    4198                 :            :                                 }
    4199                 :            :                         }
    4200                 :            :                         /* Transfer complete */
    4201         [ #  # ]:          0 :                         if (doepint.b.xfercompl) {
    4202                 :            : 
    4203         [ #  # ]:          0 :                                 if (epnum == 0) {
    4204                 :            :                                         /* Clear the bit in DOEPINTn for this interrupt */
    4205                 :          0 :                                         CLEAR_OUT_EP_INTR(core_if, epnum, xfercompl);
    4206         [ #  # ]:          0 :                                         if (core_if->snpsid >= OTG_CORE_REV_3_00a) {
    4207                 :            :                                                 DWC_DEBUGPL(DBG_PCDV, "DOEPINT=%x doepint=%x\n",
    4208                 :            :                                                         DWC_READ_REG32(&core_if->dev_if->out_ep_regs[0]->doepint),
    4209                 :            :                                                         doepint.d32);
    4210                 :            :                                                 DWC_DEBUGPL(DBG_PCDV, "DOEPCTL=%x \n",
    4211                 :            :                                                         DWC_READ_REG32(&core_if->dev_if->out_ep_regs[0]->doepctl));
    4212                 :            : 
    4213         [ #  # ]:          0 :                                                 if (core_if->snpsid >= OTG_CORE_REV_3_00a
    4214         [ #  # ]:          0 :                                                         && core_if->dma_enable == 0) {
    4215                 :            :                                                         doepint_data_t doepint;
    4216                 :          0 :                                                         doepint.d32 = DWC_READ_REG32(&core_if->dev_if->
    4217                 :          0 :                                                                                                                 out_ep_regs[0]->doepint);
    4218   [ #  #  #  # ]:          0 :                                                         if (pcd->ep0state == EP0_IDLE && doepint.b.sr) {
    4219                 :          0 :                                                                 CLEAR_OUT_EP_INTR(core_if, epnum, sr);
    4220                 :            :                                                                 goto exit_xfercompl;
    4221                 :            :                                                         }
    4222                 :            :                                                 }
    4223                 :            :                                                 /* In case of DDMA  look at SR bit to go to the Data Stage */
    4224         [ #  # ]:          0 :                                                 if (core_if->dma_desc_enable) {
    4225                 :            :                                                         dev_dma_desc_sts_t status = {.d32 = 0};
    4226         [ #  # ]:          0 :                                                         if (pcd->ep0state == EP0_IDLE) {
    4227                 :          0 :                                                                 status.d32 = core_if->dev_if->setup_desc_addr[core_if->
    4228                 :          0 :                                                                                         dev_if->setup_desc_index]->status.d32;
    4229         [ #  # ]:          0 :                                                                 if(pcd->data_terminated) {
    4230                 :          0 :                                                                          pcd->data_terminated = 0;
    4231                 :          0 :                                                                          status.d32 = core_if->dev_if->out_desc_addr->status.d32;
    4232                 :          0 :                                                                          dwc_memcpy(&pcd->setup_pkt->req, pcd->backup_buf, 8);
    4233                 :            :                                                                 }
    4234         [ #  # ]:          0 :                                                                 if (status.b.sr) {
    4235         [ #  # ]:          0 :                                                                         if (doepint.b.setup) {
    4236                 :            :                                                                                 DWC_DEBUGPL(DBG_PCDV, "DMA DESC EP0_IDLE SR=1 setup=1\n");
    4237                 :            :                                                                                 /* Already started data stage, clear setup */
    4238                 :          0 :                                                                                 CLEAR_OUT_EP_INTR(core_if, epnum, setup);
    4239                 :          0 :                                                                                 doepint.b.setup = 0;
    4240                 :          0 :                                                                                 handle_ep0(pcd);
    4241                 :            :                                                                                 /* Prepare for more setup packets */
    4242         [ #  # ]:          0 :                                                                                 if (pcd->ep0state == EP0_IN_STATUS_PHASE ||
    4243                 :            :                                                                                         pcd->ep0state == EP0_IN_DATA_PHASE) {
    4244                 :          0 :                                                                                         ep0_out_start(core_if, pcd);
    4245                 :            :                                                                                 }
    4246                 :            : 
    4247                 :            :                                                                                 goto exit_xfercompl;
    4248                 :            :                                                                         } else {
    4249                 :            :                                                                                 /* Prepare for more setup packets */
    4250                 :            :                                                                                 DWC_DEBUGPL(DBG_PCDV,
    4251                 :            :                                                                                         "EP0_IDLE SR=1 setup=0 new setup comes\n");
    4252                 :          0 :                                                                                 ep0_out_start(core_if, pcd);
    4253                 :            :                                                                         }
    4254                 :            :                                                                 }
    4255                 :            :                                                         } else {
    4256                 :            :                                                                 dwc_otg_pcd_request_t *req;
    4257                 :            :                                                                 dev_dma_desc_sts_t status = {.d32 = 0};
    4258                 :            :                                                                 diepint_data_t diepint0;
    4259                 :          0 :                                                                 diepint0.d32 = DWC_READ_REG32(&core_if->dev_if->
    4260                 :          0 :                                                                                                                         in_ep_regs[0]->diepint);
    4261                 :            : 
    4262         [ #  # ]:          0 :                                                                 if (pcd->ep0state == EP0_STALL || pcd->ep0state == EP0_DISCONNECT) {
    4263                 :          0 :                                                                         DWC_ERROR("EP0 is stalled/disconnected\n");
    4264                 :            :                                                                 }
    4265                 :            : 
    4266                 :            :                                                                 /* Clear IN xfercompl if set */
    4267   [ #  #  #  # ]:          0 :                                                                 if (diepint0.b.xfercompl && (pcd->ep0state == EP0_IN_STATUS_PHASE
    4268                 :          0 :                                                                         || pcd->ep0state == EP0_IN_DATA_PHASE)) {
    4269                 :          0 :                                                                         DWC_WRITE_REG32(&core_if->dev_if->
    4270                 :          0 :                                                                                 in_ep_regs[0]->diepint, diepint0.d32);
    4271                 :            :                                                                 }
    4272                 :            : 
    4273                 :          0 :                                                                 status.d32 = core_if->dev_if->setup_desc_addr[core_if->
    4274                 :          0 :                                                                         dev_if->setup_desc_index]->status.d32;
    4275                 :            : 
    4276         [ #  # ]:          0 :                                                                 if (ep->dwc_ep.xfer_count != ep->dwc_ep.total_len
    4277         [ #  # ]:          0 :                                                                         && (pcd->ep0state == EP0_OUT_DATA_PHASE))
    4278                 :          0 :                                                                         status.d32 = core_if->dev_if->out_desc_addr->status.d32;
    4279         [ #  # ]:          0 :                                                                 if (pcd->ep0state == EP0_OUT_STATUS_PHASE)
    4280                 :          0 :                                                                         status.d32 = core_if->dev_if->
    4281                 :          0 :                                                                         out_desc_addr->status.d32;
    4282                 :            : 
    4283         [ #  # ]:          0 :                                                                 if (status.b.sr) {
    4284         [ #  # ]:          0 :                                                                         if (DWC_CIRCLEQ_EMPTY(&ep->queue)) {
    4285                 :            :                                                                                 DWC_DEBUGPL(DBG_PCDV, "Request queue empty!!\n");
    4286                 :            :                                                                         } else {
    4287                 :            :                                                                                 DWC_DEBUGPL(DBG_PCDV, "complete req!!\n");
    4288                 :            :                                                                                 req = DWC_CIRCLEQ_FIRST(&ep->queue);
    4289   [ #  #  #  # ]:          0 :                                                                                 if (ep->dwc_ep.xfer_count != ep->dwc_ep.total_len &&
    4290                 :            :                                                                                         pcd->ep0state == EP0_OUT_DATA_PHASE) {
    4291                 :            :                                                                                                 /* Read arrived setup packet from req->buf */
    4292                 :          0 :                                                                                                 dwc_memcpy(&pcd->setup_pkt->req,
    4293                 :          0 :                                                                                                         req->buf + ep->dwc_ep.xfer_count, 8);
    4294                 :            :                                                                                 }
    4295                 :          0 :                                                                                 req->actual = ep->dwc_ep.xfer_count;
    4296                 :          0 :                                                                                 dwc_otg_request_done(ep, req, -ECONNRESET);
    4297                 :          0 :                                                                                 ep->dwc_ep.start_xfer_buff = 0;
    4298                 :          0 :                                                                                 ep->dwc_ep.xfer_buff = 0;
    4299                 :          0 :                                                                                 ep->dwc_ep.xfer_len = 0;
    4300                 :            :                                                                         }
    4301                 :          0 :                                                                         pcd->ep0state = EP0_IDLE;
    4302         [ #  # ]:          0 :                                                                         if (doepint.b.setup) {
    4303                 :            :                                                                                 DWC_DEBUGPL(DBG_PCDV, "EP0_IDLE SR=1 setup=1\n");
    4304                 :            :                                                                                 /* Data stage started, clear setup */
    4305                 :          0 :                                                                                 CLEAR_OUT_EP_INTR(core_if, epnum, setup);
    4306                 :          0 :                                                                                 doepint.b.setup = 0;
    4307                 :          0 :                                                                                 handle_ep0(pcd);
    4308                 :            :                                                                                 /* Prepare for setup packets if ep0in was enabled*/
    4309         [ #  # ]:          0 :                                                                                 if (pcd->ep0state == EP0_IN_STATUS_PHASE) {
    4310                 :          0 :                                                                                         ep0_out_start(core_if, pcd);
    4311                 :            :                                                                                 }
    4312                 :            : 
    4313                 :            :                                                                                 goto exit_xfercompl;
    4314                 :            :                                                                         } else {
    4315                 :            :                                                                                 /* Prepare for more setup packets */
    4316                 :            :                                                                                 DWC_DEBUGPL(DBG_PCDV,
    4317                 :            :                                                                                         "EP0_IDLE SR=1 setup=0 new setup comes 2\n");
    4318                 :          0 :                                                                                 ep0_out_start(core_if, pcd);
    4319                 :            :                                                                         }
    4320                 :            :                                                                 }
    4321                 :            :                                                         }
    4322                 :            :                                                 }
    4323   [ #  #  #  # ]:          0 :                                                 if (core_if->snpsid >= OTG_CORE_REV_2_94a && core_if->dma_enable
    4324         [ #  # ]:          0 :                                                         && core_if->dma_desc_enable == 0) {
    4325                 :            :                                                         doepint_data_t doepint_temp = {.d32 = 0};
    4326                 :            :                                                         deptsiz0_data_t doeptsize0 = {.d32 = 0 };
    4327                 :          0 :                                                         doepint_temp.d32 = DWC_READ_REG32(&core_if->dev_if->
    4328                 :          0 :                                                                                                                         out_ep_regs[ep->dwc_ep.num]->doepint);
    4329                 :          0 :                                                         doeptsize0.d32 = DWC_READ_REG32(&core_if->dev_if->
    4330                 :          0 :                                                                                                                         out_ep_regs[ep->dwc_ep.num]->doeptsiz);
    4331         [ #  # ]:          0 :                                                         if (pcd->ep0state == EP0_IDLE) {
    4332         [ #  # ]:          0 :                                                                 if (doepint_temp.b.sr) {
    4333                 :          0 :                                                                         CLEAR_OUT_EP_INTR(core_if, epnum, sr);
    4334                 :            :                                                                 }
    4335                 :          0 :                                                                         doepint.d32 = DWC_READ_REG32(&core_if->dev_if->
    4336                 :          0 :                                                                                                                                         out_ep_regs[0]->doepint);
    4337         [ #  # ]:          0 :                                                                         if (doeptsize0.b.supcnt == 3) {
    4338                 :            :                                                                                 DWC_DEBUGPL(DBG_ANY, "Rolling over!!!!!!!\n");
    4339                 :          0 :                                                                                 ep->dwc_ep.stp_rollover = 1;
    4340                 :            :                                                                         }
    4341         [ #  # ]:          0 :                                                                         if (doepint.b.setup) {
    4342                 :            : retry:
    4343                 :            :                                                                                 /* Already started data stage, clear setup */
    4344                 :          0 :                                                                                 CLEAR_OUT_EP_INTR(core_if, epnum, setup);
    4345                 :          0 :                                                                                 doepint.b.setup = 0;
    4346                 :          0 :                                                                                 handle_ep0(pcd);
    4347                 :          0 :                                                                                 ep->dwc_ep.stp_rollover = 0;
    4348                 :            :                                                                                 /* Prepare for more setup packets */
    4349         [ #  # ]:          0 :                                                                                 if (pcd->ep0state == EP0_IN_STATUS_PHASE ||
    4350                 :            :                                                                                         pcd->ep0state == EP0_IN_DATA_PHASE) {
    4351                 :          0 :                                                                                         ep0_out_start(core_if, pcd);
    4352                 :            :                                                                                 }
    4353                 :          0 :                                                                                 goto exit_xfercompl;
    4354                 :            :                                                                         } else {
    4355                 :            :                                                                                 /* Prepare for more setup packets */
    4356                 :            :                                                                                 DWC_DEBUGPL(DBG_ANY,
    4357                 :            :                                                                                         "EP0_IDLE SR=1 setup=0 new setup comes\n");
    4358                 :          0 :                                                                                 doepint.d32 = DWC_READ_REG32(&core_if->dev_if->
    4359                 :          0 :                                                                                                                                         out_ep_regs[0]->doepint);
    4360         [ #  # ]:          0 :                                                                                 if(doepint.b.setup)
    4361                 :            :                                                                                         goto retry;
    4362                 :          0 :                                                                                 ep0_out_start(core_if, pcd);
    4363                 :            :                                                                         }
    4364                 :            :                                                         } else {
    4365                 :            :                                                                 dwc_otg_pcd_request_t *req;
    4366                 :            :                                                                 diepint_data_t diepint0 = {.d32 = 0};
    4367                 :            :                                                                 doepint_data_t doepint_temp = {.d32 = 0};
    4368                 :            :                                                                 depctl_data_t diepctl0;
    4369                 :          0 :                                                                 diepint0.d32 = DWC_READ_REG32(&core_if->dev_if->
    4370                 :          0 :                                                                                                                                 in_ep_regs[0]->diepint);
    4371                 :          0 :                                                                 diepctl0.d32 = DWC_READ_REG32(&core_if->dev_if->
    4372                 :          0 :                                                                                                                                 in_ep_regs[0]->diepctl);
    4373                 :            : 
    4374         [ #  # ]:          0 :                                                                 if (pcd->ep0state == EP0_IN_DATA_PHASE
    4375                 :          0 :                                                                         || pcd->ep0state == EP0_IN_STATUS_PHASE) {
    4376         [ #  # ]:          0 :                                                                         if (diepint0.b.xfercompl) {
    4377                 :          0 :                                                                                 DWC_WRITE_REG32(&core_if->dev_if->
    4378                 :          0 :                                                                                         in_ep_regs[0]->diepint, diepint0.d32);
    4379                 :            :                                                                         }
    4380         [ #  # ]:          0 :                                                                         if (diepctl0.b.epena) {
    4381                 :            :                                                                                 diepint_data_t diepint = {.d32 = 0};
    4382                 :          0 :                                                                                 diepctl0.b.snak = 1;
    4383                 :          0 :                                                                                 DWC_WRITE_REG32(&core_if->dev_if->
    4384                 :          0 :                                                                                                                 in_ep_regs[0]->diepctl, diepctl0.d32);
    4385                 :            :                                                                                 do {
    4386                 :          0 :                                                                                         dwc_udelay(10);
    4387                 :          0 :                                                                                         diepint.d32 = DWC_READ_REG32(&core_if->dev_if->
    4388                 :          0 :                                                                                                 in_ep_regs[0]->diepint);
    4389         [ #  # ]:          0 :                                                                                 } while (!diepint.b.inepnakeff);
    4390                 :          0 :                                                                                 diepint.b.inepnakeff = 1;
    4391                 :          0 :                                                                                 DWC_WRITE_REG32(&core_if->dev_if->
    4392                 :          0 :                                                                                         in_ep_regs[0]->diepint, diepint.d32);
    4393                 :          0 :                                                                                 diepctl0.d32 = 0;
    4394                 :          0 :                                                                                 diepctl0.b.epdis = 1;
    4395                 :          0 :                                                                                 DWC_WRITE_REG32(&core_if->dev_if->in_ep_regs[0]->diepctl,
    4396                 :            :                                                                                                                 diepctl0.d32);
    4397                 :            :                                                                                 do {
    4398                 :          0 :                                                                                         dwc_udelay(10);
    4399                 :          0 :                                                                                         diepint.d32 = DWC_READ_REG32(&core_if->dev_if->
    4400                 :          0 :                                                                                                 in_ep_regs[0]->diepint);
    4401         [ #  # ]:          0 :                                                                                 } while (!diepint.b.epdisabled);
    4402                 :          0 :                                                                                 diepint.b.epdisabled = 1;
    4403                 :          0 :                                                                                 DWC_WRITE_REG32(&core_if->dev_if->in_ep_regs[0]->diepint,
    4404                 :            :                                                                                                                         diepint.d32);
    4405                 :            :                                                                         }
    4406                 :            :                                                                 }
    4407                 :          0 :                                                                 doepint_temp.d32 = DWC_READ_REG32(&core_if->dev_if->
    4408                 :          0 :                                                                                                                                 out_ep_regs[ep->dwc_ep.num]->doepint);
    4409         [ #  # ]:          0 :                                                                 if (doepint_temp.b.sr) {
    4410                 :          0 :                                                                         CLEAR_OUT_EP_INTR(core_if, epnum, sr);
    4411         [ #  # ]:          0 :                                                                         if (DWC_CIRCLEQ_EMPTY(&ep->queue)) {
    4412                 :            :                                                                                 DWC_DEBUGPL(DBG_PCDV, "Request queue empty!!\n");
    4413                 :            :                                                                         } else {
    4414                 :            :                                                                                 DWC_DEBUGPL(DBG_PCDV, "complete req!!\n");
    4415                 :            :                                                                                 req = DWC_CIRCLEQ_FIRST(&ep->queue);
    4416   [ #  #  #  # ]:          0 :                                                                                 if (ep->dwc_ep.xfer_count != ep->dwc_ep.total_len &&
    4417                 :          0 :                                                                                         pcd->ep0state == EP0_OUT_DATA_PHASE) {
    4418                 :            :                                                                                                 /* Read arrived setup packet from req->buf */
    4419                 :          0 :                                                                                                 dwc_memcpy(&pcd->setup_pkt->req,
    4420                 :          0 :                                                                                                         req->buf + ep->dwc_ep.xfer_count, 8);
    4421                 :            :                                                                                 }
    4422                 :          0 :                                                                                 req->actual = ep->dwc_ep.xfer_count;
    4423                 :          0 :                                                                                 dwc_otg_request_done(ep, req, -ECONNRESET);
    4424                 :          0 :                                                                                 ep->dwc_ep.start_xfer_buff = 0;
    4425                 :          0 :                                                                                 ep->dwc_ep.xfer_buff = 0;
    4426                 :          0 :                                                                                 ep->dwc_ep.xfer_len = 0;
    4427                 :            :                                                                         }
    4428                 :          0 :                                                                         pcd->ep0state = EP0_IDLE;
    4429         [ #  # ]:          0 :                                                                         if (doepint.b.setup) {
    4430                 :            :                                                                                 DWC_DEBUGPL(DBG_PCDV, "EP0_IDLE SR=1 setup=1\n");
    4431                 :            :                                                                                 /* Data stage started, clear setup */
    4432                 :          0 :                                                                                 CLEAR_OUT_EP_INTR(core_if, epnum, setup);
    4433                 :          0 :                                                                                 doepint.b.setup = 0;
    4434                 :          0 :                                                                                 handle_ep0(pcd);
    4435                 :            :                                                                                 /* Prepare for setup packets if ep0in was enabled*/
    4436         [ #  # ]:          0 :                                                                                 if (pcd->ep0state == EP0_IN_STATUS_PHASE) {
    4437                 :          0 :                                                                                         ep0_out_start(core_if, pcd);
    4438                 :            :                                                                                 }
    4439                 :          0 :                                                                                 goto exit_xfercompl;
    4440                 :            :                                                                         } else {
    4441                 :            :                                                                                 /* Prepare for more setup packets */
    4442                 :            :                                                                                 DWC_DEBUGPL(DBG_PCDV,
    4443                 :            :                                                                                         "EP0_IDLE SR=1 setup=0 new setup comes 2\n");
    4444                 :          0 :                                                                                 ep0_out_start(core_if, pcd);
    4445                 :            :                                                                         }
    4446                 :            :                                                                 }
    4447                 :            :                                                         }
    4448                 :            :                                                 }
    4449   [ #  #  #  # ]:          0 :                                                 if (core_if->dma_enable == 0 || pcd->ep0state != EP0_IDLE)
    4450                 :          0 :                                                         handle_ep0(pcd);
    4451                 :            : exit_xfercompl:
    4452                 :            :                                                 DWC_DEBUGPL(DBG_PCDV, "DOEPINT=%x doepint=%x\n",
    4453                 :            :                                                         dwc_otg_read_dev_out_ep_intr(core_if, dwc_ep), doepint.d32);
    4454                 :            :                                         } else {
    4455         [ #  # ]:          0 :                                         if (core_if->dma_desc_enable == 0
    4456         [ #  # ]:          0 :                                             || pcd->ep0state != EP0_IDLE)
    4457                 :          0 :                                                 handle_ep0(pcd);
    4458                 :            :                                         }
    4459                 :            : #ifdef DWC_EN_ISOC
    4460                 :            :                                 } else if (dwc_ep->type == DWC_OTG_EP_TYPE_ISOC) {
    4461                 :            :                                         if (doepint.b.pktdrpsts == 0) {
    4462                 :            :                                                 /* Clear the bit in DOEPINTn for this interrupt */
    4463                 :            :                                                 CLEAR_OUT_EP_INTR(core_if,
    4464                 :            :                                                                   epnum,
    4465                 :            :                                                                   xfercompl);
    4466                 :            :                                                 complete_iso_ep(pcd, ep);
    4467                 :            :                                         } else {
    4468                 :            : 
    4469                 :            :                                                 doepint_data_t doepint = {.d32 = 0 };
    4470                 :            :                                                 doepint.b.xfercompl = 1;
    4471                 :            :                                                 doepint.b.pktdrpsts = 1;
    4472                 :            :                                                 DWC_WRITE_REG32
    4473                 :            :                                                     (&core_if->dev_if->out_ep_regs
    4474                 :            :                                                      [epnum]->doepint,
    4475                 :            :                                                      doepint.d32);
    4476                 :            :                                                 if (handle_iso_out_pkt_dropped
    4477                 :            :                                                     (core_if, dwc_ep)) {
    4478                 :            :                                                         complete_iso_ep(pcd,
    4479                 :            :                                                                         ep);
    4480                 :            :                                                 }
    4481                 :            :                                         }
    4482                 :            : #endif /* DWC_EN_ISOC */
    4483                 :            : #ifdef DWC_UTE_PER_IO
    4484                 :            :                                 } else if (dwc_ep->type == DWC_OTG_EP_TYPE_ISOC) {
    4485                 :            :                                         CLEAR_OUT_EP_INTR(core_if, epnum, xfercompl);
    4486                 :            :                                         if (!ep->stopped)
    4487                 :            :                                                 complete_xiso_ep(ep);
    4488                 :            : #endif /* DWC_UTE_PER_IO */
    4489                 :            :                                 } else {
    4490                 :            :                                         /* Clear the bit in DOEPINTn for this interrupt */
    4491                 :          0 :                                         CLEAR_OUT_EP_INTR(core_if, epnum,
    4492                 :            :                                                           xfercompl);
    4493                 :            : 
    4494         [ #  # ]:          0 :                                         if (core_if->core_params->dev_out_nak) {
    4495                 :          0 :                                                 DWC_TIMER_CANCEL(pcd->core_if->ep_xfer_timer[epnum]);
    4496                 :          0 :                                                 pcd->core_if->ep_xfer_info[epnum].state = 0;
    4497                 :            : #ifdef DEBUG
    4498                 :            :                                                 print_memory_payload(pcd, dwc_ep);
    4499                 :            : #endif
    4500                 :            :                                         }
    4501                 :          0 :                                         complete_ep(ep);
    4502                 :            :                                 }
    4503                 :            : 
    4504                 :            :                         }
    4505                 :            : 
    4506                 :            :                         /* Endpoint disable      */
    4507         [ #  # ]:          0 :                         if (doepint.b.epdisabled) {
    4508                 :            : 
    4509                 :            :                                 /* Clear the bit in DOEPINTn for this interrupt */
    4510                 :          0 :                                 CLEAR_OUT_EP_INTR(core_if, epnum, epdisabled);
    4511         [ #  # ]:          0 :                                 if (core_if->core_params->dev_out_nak) {
    4512                 :            : #ifdef DEBUG
    4513                 :            :                                         print_memory_payload(pcd, dwc_ep);
    4514                 :            : #endif
    4515                 :            :                                         /* In case of timeout condition */
    4516         [ #  # ]:          0 :                                         if (core_if->ep_xfer_info[epnum].state == 2) {
    4517                 :          0 :                                                 dctl.d32 = DWC_READ_REG32(&core_if->dev_if->
    4518                 :            :                                                                                 dev_global_regs->dctl);
    4519                 :          0 :                                                 dctl.b.cgoutnak = 1;
    4520                 :          0 :                                                 DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->dctl,
    4521                 :            :                                                                                                                                 dctl.d32);
    4522                 :            :                                                 /* Unmask goutnakeff interrupt which was masked
    4523                 :            :                                                  * during handle nak out interrupt */
    4524                 :          0 :                                                 gintmsk.b.goutnakeff = 1;
    4525                 :          0 :                                                 DWC_MODIFY_REG32(&core_if->core_global_regs->gintmsk,
    4526                 :            :                                                                                                                                 0, gintmsk.d32);
    4527                 :            : 
    4528                 :          0 :                                                 complete_ep(ep);
    4529                 :            :                                         }
    4530                 :            :                                 }
    4531         [ #  # ]:          0 :                                 if (ep->dwc_ep.type == DWC_OTG_EP_TYPE_ISOC)
    4532                 :            :                                 {
    4533                 :            :                                         dctl_data_t dctl;
    4534                 :            :                                         gintmsk_data_t intr_mask = {.d32 = 0};
    4535                 :            :                                         dwc_otg_pcd_request_t *req = 0;
    4536                 :            : 
    4537                 :          0 :                                         dctl.d32 = DWC_READ_REG32(&core_if->dev_if->
    4538                 :            :                                                 dev_global_regs->dctl);
    4539                 :          0 :                                         dctl.b.cgoutnak = 1;
    4540                 :          0 :                                         DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->dctl,
    4541                 :            :                                                 dctl.d32);
    4542                 :            : 
    4543                 :            :                                         intr_mask.d32 = 0;
    4544                 :            :                                         intr_mask.b.incomplisoout = 1;
    4545                 :            : 
    4546                 :            :                                         /* Get any pending requests */
    4547         [ #  # ]:          0 :                                         if (!DWC_CIRCLEQ_EMPTY(&ep->queue)) {
    4548                 :            :                                                 req = DWC_CIRCLEQ_FIRST(&ep->queue);
    4549         [ #  # ]:          0 :                                                 if (!req) {
    4550                 :          0 :                                                         DWC_PRINTF("complete_ep 0x%p, req = NULL!\n", ep);
    4551                 :            :                                                 } else {
    4552                 :          0 :                                                         dwc_otg_request_done(ep, req, 0);
    4553                 :          0 :                                                         start_next_request(ep);
    4554                 :            :                                                 }
    4555                 :            :                                         } else {
    4556                 :          0 :                                                 DWC_PRINTF("complete_ep 0x%p, ep->queue empty!\n", ep);
    4557                 :            :                                         }
    4558                 :            :                                 }
    4559                 :            :                         }
    4560                 :            :                         /* AHB Error */
    4561         [ #  # ]:          0 :                         if (doepint.b.ahberr) {
    4562                 :          0 :                                 DWC_ERROR("EP%d OUT AHB Error\n", epnum);
    4563                 :          0 :                                 DWC_ERROR("EP%d DEPDMA=0x%08x \n",
    4564                 :            :                                           epnum, core_if->dev_if->out_ep_regs[epnum]->doepdma);
    4565                 :          0 :                                 CLEAR_OUT_EP_INTR(core_if, epnum, ahberr);
    4566                 :            :                         }
    4567                 :            :                         /* Setup Phase Done (contorl EPs) */
    4568         [ #  # ]:          0 :                         if (doepint.b.setup) {
    4569                 :            : #ifdef DEBUG_EP0
    4570                 :            :                                 DWC_DEBUGPL(DBG_PCD, "EP%d SETUP Done\n", epnum);
    4571                 :            : #endif
    4572                 :          0 :                                 CLEAR_OUT_EP_INTR(core_if, epnum, setup);
    4573                 :            : 
    4574                 :          0 :                                 handle_ep0(pcd);
    4575                 :            :                         }
    4576                 :            : 
    4577                 :            :                         /** OUT EP BNA Intr */
    4578         [ #  # ]:          0 :                         if (doepint.b.bna) {
    4579                 :          0 :                                 CLEAR_OUT_EP_INTR(core_if, epnum, bna);
    4580         [ #  # ]:          0 :                                 if (core_if->dma_desc_enable) {
    4581                 :            : #ifdef DWC_EN_ISOC
    4582                 :            :                                         if (dwc_ep->type ==
    4583                 :            :                                             DWC_OTG_EP_TYPE_ISOC) {
    4584                 :            :                                                 /*
    4585                 :            :                                                  * This checking is performed to prevent first "false" BNA
    4586                 :            :                                                  * handling occuring right after reconnect
    4587                 :            :                                                  */
    4588                 :            :                                                 if (dwc_ep->next_frame !=
    4589                 :            :                                                     0xffffffff)
    4590                 :            :                                                         dwc_otg_pcd_handle_iso_bna(ep);
    4591                 :            :                                         } else
    4592                 :            : #endif                          /* DWC_EN_ISOC */
    4593                 :            :                                         {
    4594                 :          0 :                                                 dwc_otg_pcd_handle_noniso_bna(ep);
    4595                 :            :                                         }
    4596                 :            :                                 }
    4597                 :            :                         }
    4598                 :            :                         /* Babble Interrupt */
    4599         [ #  # ]:          0 :                         if (doepint.b.babble) {
    4600                 :            :                                 DWC_DEBUGPL(DBG_ANY, "EP%d OUT Babble\n",
    4601                 :            :                                             epnum);
    4602                 :          0 :                                 handle_out_ep_babble_intr(pcd, epnum);
    4603                 :            : 
    4604                 :          0 :                                 CLEAR_OUT_EP_INTR(core_if, epnum, babble);
    4605                 :            :                         }
    4606         [ #  # ]:          0 :                         if (doepint.b.outtknepdis) {
    4607                 :            :                                 DWC_DEBUGPL(DBG_ANY, "EP%d OUT Token received when EP is \
    4608                 :            :                                         disabled\n",epnum);
    4609         [ #  # ]:          0 :                                 if (ep->dwc_ep.type == DWC_OTG_EP_TYPE_ISOC) {
    4610                 :          0 :                                         doepmsk_data_t doepmsk = {.d32 = 0};
    4611                 :          0 :                                         ep->dwc_ep.frame_num = core_if->frame_num;
    4612         [ #  # ]:          0 :                                         if (ep->dwc_ep.bInterval > 1) {
    4613                 :            :                                                 depctl_data_t depctl;
    4614                 :          0 :                                                 depctl.d32 = DWC_READ_REG32(&core_if->dev_if->
    4615                 :          0 :                                                                                                         out_ep_regs[epnum]->doepctl);
    4616         [ #  # ]:          0 :                                                 if (ep->dwc_ep.frame_num & 0x1) {
    4617                 :          0 :                                                         depctl.b.setd1pid = 1;
    4618                 :          0 :                                                         depctl.b.setd0pid = 0;
    4619                 :            :                                                 } else {
    4620                 :          0 :                                                         depctl.b.setd0pid = 1;
    4621                 :          0 :                                                         depctl.b.setd1pid = 0;
    4622                 :            :                                                 }
    4623                 :          0 :                                                 DWC_WRITE_REG32(&core_if->dev_if->
    4624                 :          0 :                                                                                 out_ep_regs[epnum]->doepctl, depctl.d32);
    4625                 :            :                                         }
    4626                 :          0 :                                         start_next_request(ep);
    4627                 :          0 :                                         doepmsk.b.outtknepdis = 1;
    4628                 :          0 :                                         DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->doepmsk,
    4629                 :            :                                                                  doepmsk.d32, 0);
    4630                 :            :                                 }
    4631                 :          0 :                                 CLEAR_OUT_EP_INTR(core_if, epnum, outtknepdis);
    4632                 :            :                         }
    4633                 :            : 
    4634                 :            :                         /* NAK Interrutp */
    4635         [ #  # ]:          0 :                         if (doepint.b.nak) {
    4636                 :            :                                 DWC_DEBUGPL(DBG_ANY, "EP%d OUT NAK\n", epnum);
    4637                 :          0 :                                 handle_out_ep_nak_intr(pcd, epnum);
    4638                 :            : 
    4639                 :          0 :                                 CLEAR_OUT_EP_INTR(core_if, epnum, nak);
    4640                 :            :                         }
    4641                 :            :                         /* NYET Interrutp */
    4642         [ #  # ]:          0 :                         if (doepint.b.nyet) {
    4643                 :            :                                 DWC_DEBUGPL(DBG_ANY, "EP%d OUT NYET\n", epnum);
    4644                 :          0 :                                 handle_out_ep_nyet_intr(pcd, epnum);
    4645                 :            : 
    4646                 :          0 :                                 CLEAR_OUT_EP_INTR(core_if, epnum, nyet);
    4647                 :            :                         }
    4648                 :            :                 }
    4649                 :            : 
    4650                 :          0 :                 epnum++;
    4651                 :          0 :                 ep_intr >>= 1;
    4652                 :            :         }
    4653                 :            : 
    4654                 :          0 :         return 1;
    4655                 :            : 
    4656                 :            : #undef CLEAR_OUT_EP_INTR
    4657                 :            : }
    4658                 :            : static int drop_transfer(uint32_t trgt_fr, uint32_t curr_fr, uint8_t frm_overrun)
    4659                 :            : {
    4660                 :            :         int retval = 0;
    4661         [ #  # ]:          0 :         if(!frm_overrun && curr_fr >= trgt_fr)
    4662                 :            :                 retval = 1;
    4663         [ #  # ]:          0 :         else if (frm_overrun
    4664         [ #  # ]:          0 :                  && (curr_fr >= trgt_fr && ((curr_fr - trgt_fr) < 0x3FFF / 2)))
    4665                 :            :                 retval = 1;
    4666                 :            :         return retval;
    4667                 :            : }
    4668                 :            : /**
    4669                 :            :  * Incomplete ISO IN Transfer Interrupt.
    4670                 :            :  * This interrupt indicates one of the following conditions occurred
    4671                 :            :  * while transmitting an ISOC transaction.
    4672                 :            :  * - Corrupted IN Token for ISOC EP.
    4673                 :            :  * - Packet not complete in FIFO.
    4674                 :            :  * The follow actions will be taken:
    4675                 :            :  *      -#      Determine the EP
    4676                 :            :  *      -#      Set incomplete flag in dwc_ep structure
    4677                 :            :  *      -#      Disable EP; when "Endpoint Disabled" interrupt is received
    4678                 :            :  *              Flush FIFO
    4679                 :            :  */
    4680                 :          0 : int32_t dwc_otg_pcd_handle_incomplete_isoc_in_intr(dwc_otg_pcd_t * pcd)
    4681                 :            : {
    4682                 :            :         gintsts_data_t gintsts;
    4683                 :            : 
    4684                 :            : #ifdef DWC_EN_ISOC
    4685                 :            :         dwc_otg_dev_if_t *dev_if;
    4686                 :            :         deptsiz_data_t deptsiz = {.d32 = 0 };
    4687                 :            :         depctl_data_t depctl = {.d32 = 0 };
    4688                 :            :         dsts_data_t dsts = {.d32 = 0 };
    4689                 :            :         dwc_ep_t *dwc_ep;
    4690                 :            :         int i;
    4691                 :            : 
    4692                 :            :         dev_if = GET_CORE_IF(pcd)->dev_if;
    4693                 :            : 
    4694                 :            :         for (i = 1; i <= dev_if->num_in_eps; ++i) {
    4695                 :            :                 dwc_ep = &pcd->in_ep[i].dwc_ep;
    4696                 :            :                 if (dwc_ep->active && dwc_ep->type == DWC_OTG_EP_TYPE_ISOC) {
    4697                 :            :                         deptsiz.d32 =
    4698                 :            :                             DWC_READ_REG32(&dev_if->in_ep_regs[i]->dieptsiz);
    4699                 :            :                         depctl.d32 =
    4700                 :            :                             DWC_READ_REG32(&dev_if->in_ep_regs[i]->diepctl);
    4701                 :            : 
    4702                 :            :                         if (depctl.b.epdis && deptsiz.d32) {
    4703                 :            :                                 set_current_pkt_info(GET_CORE_IF(pcd), dwc_ep);
    4704                 :            :                                 if (dwc_ep->cur_pkt >= dwc_ep->pkt_cnt) {
    4705                 :            :                                         dwc_ep->cur_pkt = 0;
    4706                 :            :                                         dwc_ep->proc_buf_num =
    4707                 :            :                                             (dwc_ep->proc_buf_num ^ 1) & 0x1;
    4708                 :            : 
    4709                 :            :                                         if (dwc_ep->proc_buf_num) {
    4710                 :            :                                                 dwc_ep->cur_pkt_addr =
    4711                 :            :                                                     dwc_ep->xfer_buff1;
    4712                 :            :                                                 dwc_ep->cur_pkt_dma_addr =
    4713                 :            :                                                     dwc_ep->dma_addr1;
    4714                 :            :                                         } else {
    4715                 :            :                                                 dwc_ep->cur_pkt_addr =
    4716                 :            :                                                     dwc_ep->xfer_buff0;
    4717                 :            :                                                 dwc_ep->cur_pkt_dma_addr =
    4718                 :            :                                                     dwc_ep->dma_addr0;
    4719                 :            :                                         }
    4720                 :            : 
    4721                 :            :                                 }
    4722                 :            : 
    4723                 :            :                                 dsts.d32 =
    4724                 :            :                                     DWC_READ_REG32(&GET_CORE_IF(pcd)->dev_if->
    4725                 :            :                                                    dev_global_regs->dsts);
    4726                 :            :                                 dwc_ep->next_frame = dsts.b.soffn;
    4727                 :            : 
    4728                 :            :                                 dwc_otg_iso_ep_start_frm_transfer(GET_CORE_IF
    4729                 :            :                                                                   (pcd),
    4730                 :            :                                                                   dwc_ep);
    4731                 :            :                         }
    4732                 :            :                 }
    4733                 :            :         }
    4734                 :            : 
    4735                 :            : #else
    4736                 :            :         depctl_data_t depctl = {.d32 = 0 };
    4737                 :            :         dwc_ep_t *dwc_ep;
    4738                 :            :         dwc_otg_dev_if_t *dev_if;
    4739                 :            :         int i;
    4740                 :          0 :         dev_if = GET_CORE_IF(pcd)->dev_if;
    4741                 :            : 
    4742                 :            :         DWC_DEBUGPL(DBG_PCD,"Incomplete ISO IN \n");
    4743                 :            : 
    4744         [ #  # ]:          0 :         for (i = 1; i <= dev_if->num_in_eps; ++i) {
    4745                 :          0 :                 dwc_ep = &pcd->in_ep[i-1].dwc_ep;
    4746                 :          0 :                 depctl.d32 =
    4747                 :          0 :                         DWC_READ_REG32(&dev_if->in_ep_regs[i]->diepctl);
    4748   [ #  #  #  # ]:          0 :                 if (depctl.b.epena && dwc_ep->type == DWC_OTG_EP_TYPE_ISOC) {
    4749         [ #  # ]:          0 :                         if (drop_transfer(dwc_ep->frame_num, GET_CORE_IF(pcd)->frame_num,
    4750                 :            :                                                         dwc_ep->frm_overrun))
    4751                 :            :                         {
    4752                 :          0 :                                 depctl.d32 =
    4753                 :          0 :                                         DWC_READ_REG32(&dev_if->in_ep_regs[i]->diepctl);
    4754                 :          0 :                                 depctl.b.snak = 1;
    4755                 :          0 :                                 depctl.b.epdis = 1;
    4756                 :          0 :                                 DWC_MODIFY_REG32(&dev_if->in_ep_regs[i]->diepctl, depctl.d32, depctl.d32);
    4757                 :            :                         }
    4758                 :            :                 }
    4759                 :            :         }
    4760                 :            : 
    4761                 :            :         /*intr_mask.b.incomplisoin = 1;
    4762                 :            :         DWC_MODIFY_REG32(&GET_CORE_IF(pcd)->core_global_regs->gintmsk,
    4763                 :            :                          intr_mask.d32, 0);      */
    4764                 :            : #endif                          //DWC_EN_ISOC
    4765                 :            : 
    4766                 :            :         /* Clear interrupt */
    4767                 :          0 :         gintsts.d32 = 0;
    4768                 :          0 :         gintsts.b.incomplisoin = 1;
    4769                 :          0 :         DWC_WRITE_REG32(&GET_CORE_IF(pcd)->core_global_regs->gintsts,
    4770                 :            :                         gintsts.d32);
    4771                 :            : 
    4772                 :          0 :         return 1;
    4773                 :            : }
    4774                 :            : 
    4775                 :            : /**
    4776                 :            :  * Incomplete ISO OUT Transfer Interrupt.
    4777                 :            :  *
    4778                 :            :  * This interrupt indicates that the core has dropped an ISO OUT
    4779                 :            :  * packet. The following conditions can be the cause:
    4780                 :            :  * - FIFO Full, the entire packet would not fit in the FIFO.
    4781                 :            :  * - CRC Error
    4782                 :            :  * - Corrupted Token
    4783                 :            :  * The follow actions will be taken:
    4784                 :            :  *      -#      Determine the EP
    4785                 :            :  *      -#      Set incomplete flag in dwc_ep structure
    4786                 :            :  *      -#      Read any data from the FIFO
    4787                 :            :  *      -#      Disable EP. When "Endpoint Disabled" interrupt is received
    4788                 :            :  *              re-enable EP.
    4789                 :            :  */
    4790                 :          0 : int32_t dwc_otg_pcd_handle_incomplete_isoc_out_intr(dwc_otg_pcd_t * pcd)
    4791                 :            : {
    4792                 :            : 
    4793                 :            :         gintsts_data_t gintsts;
    4794                 :            : 
    4795                 :            : #ifdef DWC_EN_ISOC
    4796                 :            :         dwc_otg_dev_if_t *dev_if;
    4797                 :            :         deptsiz_data_t deptsiz = {.d32 = 0 };
    4798                 :            :         depctl_data_t depctl = {.d32 = 0 };
    4799                 :            :         dsts_data_t dsts = {.d32 = 0 };
    4800                 :            :         dwc_ep_t *dwc_ep;
    4801                 :            :         int i;
    4802                 :            : 
    4803                 :            :         dev_if = GET_CORE_IF(pcd)->dev_if;
    4804                 :            : 
    4805                 :            :         for (i = 1; i <= dev_if->num_out_eps; ++i) {
    4806                 :            :                 dwc_ep = &pcd->in_ep[i].dwc_ep;
    4807                 :            :                 if (pcd->out_ep[i].dwc_ep.active &&
    4808                 :            :                     pcd->out_ep[i].dwc_ep.type == DWC_OTG_EP_TYPE_ISOC) {
    4809                 :            :                         deptsiz.d32 =
    4810                 :            :                             DWC_READ_REG32(&dev_if->out_ep_regs[i]->doeptsiz);
    4811                 :            :                         depctl.d32 =
    4812                 :            :                             DWC_READ_REG32(&dev_if->out_ep_regs[i]->doepctl);
    4813                 :            : 
    4814                 :            :                         if (depctl.b.epdis && deptsiz.d32) {
    4815                 :            :                                 set_current_pkt_info(GET_CORE_IF(pcd),
    4816                 :            :                                                      &pcd->out_ep[i].dwc_ep);
    4817                 :            :                                 if (dwc_ep->cur_pkt >= dwc_ep->pkt_cnt) {
    4818                 :            :                                         dwc_ep->cur_pkt = 0;
    4819                 :            :                                         dwc_ep->proc_buf_num =
    4820                 :            :                                             (dwc_ep->proc_buf_num ^ 1) & 0x1;
    4821                 :            : 
    4822                 :            :                                         if (dwc_ep->proc_buf_num) {
    4823                 :            :                                                 dwc_ep->cur_pkt_addr =
    4824                 :            :                                                     dwc_ep->xfer_buff1;
    4825                 :            :                                                 dwc_ep->cur_pkt_dma_addr =
    4826                 :            :                                                     dwc_ep->dma_addr1;
    4827                 :            :                                         } else {
    4828                 :            :                                                 dwc_ep->cur_pkt_addr =
    4829                 :            :                                                     dwc_ep->xfer_buff0;
    4830                 :            :                                                 dwc_ep->cur_pkt_dma_addr =
    4831                 :            :                                                     dwc_ep->dma_addr0;
    4832                 :            :                                         }
    4833                 :            : 
    4834                 :            :                                 }
    4835                 :            : 
    4836                 :            :                                 dsts.d32 =
    4837                 :            :                                     DWC_READ_REG32(&GET_CORE_IF(pcd)->dev_if->
    4838                 :            :                                                    dev_global_regs->dsts);
    4839                 :            :                                 dwc_ep->next_frame = dsts.b.soffn;
    4840                 :            : 
    4841                 :            :                                 dwc_otg_iso_ep_start_frm_transfer(GET_CORE_IF
    4842                 :            :                                                                   (pcd),
    4843                 :            :                                                                   dwc_ep);
    4844                 :            :                         }
    4845                 :            :                 }
    4846                 :            :         }
    4847                 :            : #else
    4848                 :            :         /** @todo implement ISR */
    4849                 :            :         gintmsk_data_t intr_mask = {.d32 = 0 };
    4850                 :            :         dwc_otg_core_if_t *core_if;
    4851                 :            :         deptsiz_data_t deptsiz = {.d32 = 0 };
    4852                 :            :         depctl_data_t depctl = {.d32 = 0 };
    4853                 :            :         dctl_data_t dctl = {.d32 = 0 };
    4854                 :            :         dwc_ep_t *dwc_ep = NULL;
    4855                 :            :         int i;
    4856                 :          0 :         core_if = GET_CORE_IF(pcd);
    4857                 :            : 
    4858         [ #  # ]:          0 :         for (i = 0; i < core_if->dev_if->num_out_eps; ++i) {
    4859                 :          0 :                 dwc_ep = &pcd->out_ep[i].dwc_ep;
    4860                 :          0 :                 depctl.d32 =
    4861                 :          0 :                         DWC_READ_REG32(&core_if->dev_if->out_ep_regs[dwc_ep->num]->doepctl);
    4862   [ #  #  #  # ]:          0 :                 if (depctl.b.epena && depctl.b.dpid == (core_if->frame_num & 0x1)) {
    4863                 :          0 :                         core_if->dev_if->isoc_ep = dwc_ep;
    4864                 :            :                         deptsiz.d32 =
    4865                 :          0 :                                         DWC_READ_REG32(&core_if->dev_if->out_ep_regs[dwc_ep->num]->doeptsiz);
    4866                 :          0 :                                 break;
    4867                 :            :                 }
    4868                 :            :         }
    4869                 :          0 :         dctl.d32 = DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dctl);
    4870                 :          0 :         gintsts.d32 = DWC_READ_REG32(&core_if->core_global_regs->gintsts);
    4871                 :          0 :         intr_mask.d32 = DWC_READ_REG32(&core_if->core_global_regs->gintmsk);
    4872                 :            : 
    4873         [ #  # ]:          0 :         if (!intr_mask.b.goutnakeff) {
    4874                 :            :                 /* Unmask it */
    4875                 :          0 :                 intr_mask.b.goutnakeff = 1;
    4876                 :          0 :                 DWC_WRITE_REG32(&core_if->core_global_regs->gintmsk, intr_mask.d32);
    4877                 :            :         }
    4878         [ #  # ]:          0 :         if (!gintsts.b.goutnakeff) {
    4879                 :          0 :                 dctl.b.sgoutnak = 1;
    4880                 :            :         }
    4881                 :          0 :         DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->dctl, dctl.d32);
    4882                 :            : 
    4883                 :          0 :         depctl.d32 = DWC_READ_REG32(&core_if->dev_if->out_ep_regs[dwc_ep->num]->doepctl);
    4884         [ #  # ]:          0 :         if (depctl.b.epena) {
    4885                 :          0 :                 depctl.b.epdis = 1;
    4886                 :          0 :                 depctl.b.snak = 1;
    4887                 :            :         }
    4888                 :          0 :         DWC_WRITE_REG32(&core_if->dev_if->out_ep_regs[dwc_ep->num]->doepctl, depctl.d32);
    4889                 :            : 
    4890                 :            :         intr_mask.d32 = 0;
    4891                 :            :         intr_mask.b.incomplisoout = 1;
    4892                 :            : 
    4893                 :            : #endif /* DWC_EN_ISOC */
    4894                 :            : 
    4895                 :            :         /* Clear interrupt */
    4896                 :          0 :         gintsts.d32 = 0;
    4897                 :          0 :         gintsts.b.incomplisoout = 1;
    4898                 :          0 :         DWC_WRITE_REG32(&GET_CORE_IF(pcd)->core_global_regs->gintsts,
    4899                 :            :                         gintsts.d32);
    4900                 :            : 
    4901                 :          0 :         return 1;
    4902                 :            : }
    4903                 :            : 
    4904                 :            : /**
    4905                 :            :  * This function handles the Global IN NAK Effective interrupt.
    4906                 :            :  *
    4907                 :            :  */
    4908                 :          0 : int32_t dwc_otg_pcd_handle_in_nak_effective(dwc_otg_pcd_t * pcd)
    4909                 :            : {
    4910                 :          0 :         dwc_otg_dev_if_t *dev_if = GET_CORE_IF(pcd)->dev_if;
    4911                 :            :         depctl_data_t diepctl = {.d32 = 0 };
    4912                 :          0 :         gintmsk_data_t intr_mask = {.d32 = 0 };
    4913                 :            :         gintsts_data_t gintsts;
    4914                 :            :         dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
    4915                 :            :         int i;
    4916                 :            : 
    4917                 :            :         DWC_DEBUGPL(DBG_PCD, "Global IN NAK Effective\n");
    4918                 :            : 
    4919                 :            :         /* Disable all active IN EPs */
    4920         [ #  # ]:          0 :         for (i = 0; i <= dev_if->num_in_eps; i++) {
    4921                 :          0 :                 diepctl.d32 = DWC_READ_REG32(&dev_if->in_ep_regs[i]->diepctl);
    4922   [ #  #  #  # ]:          0 :                 if (!(diepctl.b.eptype & 1) && diepctl.b.epena) {
    4923         [ #  # ]:          0 :                         if (core_if->start_predict > 0)
    4924                 :          0 :                                 core_if->start_predict++;
    4925                 :          0 :                         diepctl.b.epdis = 1;
    4926                 :          0 :                         diepctl.b.snak = 1;
    4927                 :          0 :                         DWC_WRITE_REG32(&dev_if->in_ep_regs[i]->diepctl, diepctl.d32);
    4928                 :            :                 }
    4929                 :            :         }
    4930                 :            : 
    4931                 :            : 
    4932                 :            :         /* Disable the Global IN NAK Effective Interrupt */
    4933                 :          0 :         intr_mask.b.ginnakeff = 1;
    4934                 :          0 :         DWC_MODIFY_REG32(&GET_CORE_IF(pcd)->core_global_regs->gintmsk,
    4935                 :            :                          intr_mask.d32, 0);
    4936                 :            : 
    4937                 :            :         /* Clear interrupt */
    4938                 :          0 :         gintsts.d32 = 0;
    4939                 :          0 :         gintsts.b.ginnakeff = 1;
    4940                 :          0 :         DWC_WRITE_REG32(&GET_CORE_IF(pcd)->core_global_regs->gintsts,
    4941                 :            :                         gintsts.d32);
    4942                 :            : 
    4943                 :          0 :         return 1;
    4944                 :            : }
    4945                 :            : 
    4946                 :            : /**
    4947                 :            :  * OUT NAK Effective.
    4948                 :            :  *
    4949                 :            :  */
    4950                 :          0 : int32_t dwc_otg_pcd_handle_out_nak_effective(dwc_otg_pcd_t * pcd)
    4951                 :            : {
    4952                 :          0 :         dwc_otg_dev_if_t *dev_if = GET_CORE_IF(pcd)->dev_if;
    4953                 :          0 :         gintmsk_data_t intr_mask = {.d32 = 0 };
    4954                 :            :         gintsts_data_t gintsts;
    4955                 :            :         depctl_data_t doepctl;
    4956                 :            :         int i;
    4957                 :            : 
    4958                 :            :         /* Disable the Global OUT NAK Effective Interrupt */
    4959                 :          0 :         intr_mask.b.goutnakeff = 1;
    4960                 :          0 :         DWC_MODIFY_REG32(&GET_CORE_IF(pcd)->core_global_regs->gintmsk,
    4961                 :            :                 intr_mask.d32, 0);
    4962                 :            : 
    4963                 :            :         /* If DEV OUT NAK enabled*/
    4964         [ #  # ]:          0 :         if (pcd->core_if->core_params->dev_out_nak) {
    4965                 :            :                 /* Run over all out endpoints to determine the ep number on
    4966                 :            :                  * which the timeout has happened
    4967                 :            :                  */
    4968         [ #  # ]:          0 :                 for (i = 0; i <= dev_if->num_out_eps; i++) {
    4969         [ #  # ]:          0 :                         if ( pcd->core_if->ep_xfer_info[i].state == 2 )
    4970                 :            :                                 break;
    4971                 :            :                 }
    4972         [ #  # ]:          0 :                 if (i > dev_if->num_out_eps) {
    4973                 :            :                         dctl_data_t dctl;
    4974                 :          0 :                         dctl.d32 =
    4975                 :          0 :                             DWC_READ_REG32(&dev_if->dev_global_regs->dctl);
    4976                 :          0 :                         dctl.b.cgoutnak = 1;
    4977                 :          0 :                         DWC_WRITE_REG32(&dev_if->dev_global_regs->dctl,
    4978                 :            :                                 dctl.d32);
    4979                 :            :                         goto out;
    4980                 :            :                 }
    4981                 :            : 
    4982                 :            :                 /* Disable the endpoint */
    4983                 :          0 :                 doepctl.d32 = DWC_READ_REG32(&dev_if->out_ep_regs[i]->doepctl);
    4984         [ #  # ]:          0 :                 if (doepctl.b.epena) {
    4985                 :          0 :                         doepctl.b.epdis = 1;
    4986                 :          0 :                         doepctl.b.snak = 1;
    4987                 :            :                 }
    4988                 :          0 :                 DWC_WRITE_REG32(&dev_if->out_ep_regs[i]->doepctl, doepctl.d32);
    4989                 :          0 :                 return 1;
    4990                 :            :         }
    4991                 :            :         /* We come here from Incomplete ISO OUT handler */
    4992         [ #  # ]:          0 :         if (dev_if->isoc_ep) {
    4993                 :            :                 dwc_ep_t *dwc_ep = (dwc_ep_t *)dev_if->isoc_ep;
    4994                 :          0 :                 uint32_t epnum = dwc_ep->num;
    4995                 :            :                 doepint_data_t doepint;
    4996                 :            :                 doepint.d32 =
    4997                 :          0 :                     DWC_READ_REG32(&dev_if->out_ep_regs[dwc_ep->num]->doepint);
    4998                 :          0 :                 dev_if->isoc_ep = NULL;
    4999                 :          0 :                 doepctl.d32 =
    5000                 :          0 :                     DWC_READ_REG32(&dev_if->out_ep_regs[epnum]->doepctl);
    5001                 :          0 :                 DWC_PRINTF("Before disable DOEPCTL = %08x\n", doepctl.d32);
    5002         [ #  # ]:          0 :                 if (doepctl.b.epena) {
    5003                 :          0 :                         doepctl.b.epdis = 1;
    5004                 :          0 :                         doepctl.b.snak = 1;
    5005                 :            :                 }
    5006                 :          0 :                 DWC_WRITE_REG32(&dev_if->out_ep_regs[epnum]->doepctl,
    5007                 :            :                                 doepctl.d32);
    5008                 :            :                 return 1;
    5009                 :            :         } else
    5010                 :          0 :                 DWC_PRINTF("INTERRUPT Handler not implemented for %s\n",
    5011                 :            :                            "Global OUT NAK Effective\n");
    5012                 :            : 
    5013                 :            : out:
    5014                 :            :         /* Clear interrupt */
    5015                 :          0 :         gintsts.d32 = 0;
    5016                 :          0 :         gintsts.b.goutnakeff = 1;
    5017                 :          0 :         DWC_WRITE_REG32(&GET_CORE_IF(pcd)->core_global_regs->gintsts,
    5018                 :            :                         gintsts.d32);
    5019                 :            : 
    5020                 :          0 :         return 1;
    5021                 :            : }
    5022                 :            : 
    5023                 :            : /**
    5024                 :            :  * PCD interrupt handler.
    5025                 :            :  *
    5026                 :            :  * The PCD handles the device interrupts.  Many conditions can cause a
    5027                 :            :  * device interrupt. When an interrupt occurs, the device interrupt
    5028                 :            :  * service routine determines the cause of the interrupt and
    5029                 :            :  * dispatches handling to the appropriate function. These interrupt
    5030                 :            :  * handling functions are described below.
    5031                 :            :  *
    5032                 :            :  * All interrupt registers are processed from LSB to MSB.
    5033                 :            :  *
    5034                 :            :  */
    5035                 :  134679048 : int32_t dwc_otg_pcd_handle_intr(dwc_otg_pcd_t * pcd)
    5036                 :            : {
    5037                 :  134679048 :         dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
    5038                 :            : #ifdef VERBOSE
    5039                 :            :         dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
    5040                 :            : #endif
    5041                 :            :         gintsts_data_t gintr_status;
    5042                 :            :         int32_t retval = 0;
    5043                 :            : 
    5044                 :            :         /* Exit from ISR if core is hibernated */
    5045         [ +  - ]:  134679048 :         if (core_if->hibernation_suspend == 1) {
    5046                 :            :                 return retval;
    5047                 :            :         }
    5048                 :            : #ifdef VERBOSE
    5049                 :            :         DWC_DEBUGPL(DBG_ANY, "%s() gintsts=%08x     gintmsk=%08x\n",
    5050                 :            :                     __func__,
    5051                 :            :                     DWC_READ_REG32(&global_regs->gintsts),
    5052                 :            :                     DWC_READ_REG32(&global_regs->gintmsk));
    5053                 :            : #endif
    5054                 :            : 
    5055         [ -  + ]:  134679048 :         if (dwc_otg_is_device_mode(core_if)) {
    5056                 :          0 :                 DWC_SPINLOCK(pcd->lock);
    5057                 :            : #ifdef VERBOSE
    5058                 :            :                 DWC_DEBUGPL(DBG_PCDV, "%s() gintsts=%08x  gintmsk=%08x\n",
    5059                 :            :                             __func__,
    5060                 :            :                             DWC_READ_REG32(&global_regs->gintsts),
    5061                 :            :                             DWC_READ_REG32(&global_regs->gintmsk));
    5062                 :            : #endif
    5063                 :            : 
    5064                 :          0 :                 gintr_status.d32 = dwc_otg_read_core_intr(core_if);
    5065                 :            : 
    5066                 :            :                 DWC_DEBUGPL(DBG_PCDV, "%s: gintsts&gintmsk=%08x\n",
    5067                 :            :                             __func__, gintr_status.d32);
    5068                 :            : 
    5069         [ #  # ]:          0 :                 if (gintr_status.b.sofintr) {
    5070                 :            :                         retval |= dwc_otg_pcd_handle_sof_intr(pcd);
    5071                 :            :                 }
    5072         [ #  # ]:          0 :                 if (gintr_status.b.rxstsqlvl) {
    5073                 :          0 :                         retval |=
    5074                 :          0 :                             dwc_otg_pcd_handle_rx_status_q_level_intr(pcd);
    5075                 :            :                 }
    5076         [ #  # ]:          0 :                 if (gintr_status.b.nptxfempty) {
    5077                 :          0 :                         retval |= dwc_otg_pcd_handle_np_tx_fifo_empty_intr(pcd);
    5078                 :            :                 }
    5079         [ #  # ]:          0 :                 if (gintr_status.b.goutnakeff) {
    5080                 :          0 :                         retval |= dwc_otg_pcd_handle_out_nak_effective(pcd);
    5081                 :            :                 }
    5082         [ #  # ]:          0 :                 if (gintr_status.b.i2cintr) {
    5083                 :          0 :                         retval |= dwc_otg_pcd_handle_i2c_intr(pcd);
    5084                 :            :                 }
    5085         [ #  # ]:          0 :                 if (gintr_status.b.erlysuspend) {
    5086                 :          0 :                         retval |= dwc_otg_pcd_handle_early_suspend_intr(pcd);
    5087                 :            :                 }
    5088         [ #  # ]:          0 :                 if (gintr_status.b.usbreset) {
    5089                 :          0 :                         retval |= dwc_otg_pcd_handle_usb_reset_intr(pcd);
    5090                 :            :                 }
    5091         [ #  # ]:          0 :                 if (gintr_status.b.enumdone) {
    5092                 :          0 :                         retval |= dwc_otg_pcd_handle_enum_done_intr(pcd);
    5093                 :            :                 }
    5094         [ #  # ]:          0 :                 if (gintr_status.b.isooutdrop) {
    5095                 :          0 :                         retval |=
    5096                 :          0 :                             dwc_otg_pcd_handle_isoc_out_packet_dropped_intr
    5097                 :            :                             (pcd);
    5098                 :            :                 }
    5099         [ #  # ]:          0 :                 if (gintr_status.b.eopframe) {
    5100                 :          0 :                         retval |=
    5101                 :          0 :                             dwc_otg_pcd_handle_end_periodic_frame_intr(pcd);
    5102                 :            :                 }
    5103         [ #  # ]:          0 :                 if (gintr_status.b.inepint) {
    5104         [ #  # ]:          0 :                         if (!core_if->multiproc_int_enable) {
    5105                 :          0 :                                 retval |= dwc_otg_pcd_handle_in_ep_intr(pcd);
    5106                 :            :                         }
    5107                 :            :                 }
    5108         [ #  # ]:          0 :                 if (gintr_status.b.outepintr) {
    5109         [ #  # ]:          0 :                         if (!core_if->multiproc_int_enable) {
    5110                 :          0 :                                 retval |= dwc_otg_pcd_handle_out_ep_intr(pcd);
    5111                 :            :                         }
    5112                 :            :                 }
    5113         [ #  # ]:          0 :                 if (gintr_status.b.epmismatch) {
    5114                 :          0 :                         retval |= dwc_otg_pcd_handle_ep_mismatch_intr(pcd);
    5115                 :            :                 }
    5116         [ #  # ]:          0 :                 if (gintr_status.b.fetsusp) {
    5117                 :          0 :                         retval |= dwc_otg_pcd_handle_ep_fetsusp_intr(pcd);
    5118                 :            :                 }
    5119         [ #  # ]:          0 :                 if (gintr_status.b.ginnakeff) {
    5120                 :          0 :                         retval |= dwc_otg_pcd_handle_in_nak_effective(pcd);
    5121                 :            :                 }
    5122         [ #  # ]:          0 :                 if (gintr_status.b.incomplisoin) {
    5123                 :          0 :                         retval |=
    5124                 :          0 :                             dwc_otg_pcd_handle_incomplete_isoc_in_intr(pcd);
    5125                 :            :                 }
    5126         [ #  # ]:          0 :                 if (gintr_status.b.incomplisoout) {
    5127                 :          0 :                         retval |=
    5128                 :          0 :                             dwc_otg_pcd_handle_incomplete_isoc_out_intr(pcd);
    5129                 :            :                 }
    5130                 :            : 
    5131                 :            :                 /* In MPI mode Device Endpoints interrupts are asserted
    5132                 :            :                  * without setting outepintr and inepint bits set, so these
    5133                 :            :                  * Interrupt handlers are called without checking these bit-fields
    5134                 :            :                  */
    5135         [ #  # ]:          0 :                 if (core_if->multiproc_int_enable) {
    5136                 :          0 :                         retval |= dwc_otg_pcd_handle_in_ep_intr(pcd);
    5137                 :          0 :                         retval |= dwc_otg_pcd_handle_out_ep_intr(pcd);
    5138                 :            :                 }
    5139                 :            : #ifdef VERBOSE
    5140                 :            :                 DWC_DEBUGPL(DBG_PCDV, "%s() gintsts=%0x\n", __func__,
    5141                 :            :                             DWC_READ_REG32(&global_regs->gintsts));
    5142                 :            : #endif
    5143                 :          0 :                 DWC_SPINUNLOCK(pcd->lock);
    5144                 :            :         }
    5145                 :  134679048 :         return retval;
    5146                 :            : }
    5147                 :            : 
    5148                 :            : #endif /* DWC_HOST_ONLY */

Generated by: LCOV version 1.14