⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hostctrl.c

📁 Usb Host/Periphel Control TD1120 codes
💻 C
📖 第 1 页 / 共 5 页
字号:
         if (etdIntrStatusY & pos)
            {
            OTG242ETD_NextPacket(&hc->etdBank[index]);
            etdIntrStatusY &= ~pos;
            }

         pos <<= 1;
         index++;
         }
      }

   ohciIntStatus= 0;

   hc->frameNo = OTG242HC_ReadReg(hc, OTG242HC_FRAME_NUMBER);
   if (NULL != hc->hcca)
   {
      *OTG242HC_HCCA_FRAME_NUMBER(hc) = (U16)hc->frameNo;
   }

   /***********************************************************
      Receiving Resume detect event.
   ************************************************************/
   if (status & OTG242HC_INTR_RESUME_DETECT)
      {
      
      OS_DEBUG_MSG1(OS_ZONE_INIT, "Otg242Hc: HC resume S32\r\n");

      ohciIntStatus |= OHCI_HC_INTR_STATUS_RD;
      }
   
   
   /************************************************************
     if there was an interrupt due to a completed TD list, or
      a lingering TD from an IRP cancel is on the Done queue and 
     must be removed before we signal the client driver
   ************************************************************/
    if (status & OTG242HC_INTR_WRITE_DONE_HEAD)
      {
      
      /* Return pointer to done ETD */
      doneQueue = OTG242HC_ReadReg(hc, OTG242HC_ENDPOINTDONESTATUS);

      if (doneQueue)
         {
         for (index = 0, pos = 1; index < OTG242ETD_MAX; index++, pos <<= 1)
            {
            if (doneQueue & pos)
               {
               
               /* Clear endpoint done status */
               OTG242HC_WriteReg(hc, OTG242HC_ENDPOINTDONESTATUS, doneQueue & pos);
               
               /* Clear endpoint done enable */
               Read = OTG242HC_ReadReg(hc, OTG242HC_ETDDONEENABLE);
               OTG242HC_WriteReg(hc, OTG242HC_ETDDONEENABLE, Read & ~(doneQueue & pos));
               
               
               hc->etdIntrEnable &= ~(OTG242ETD_XYIntrEnable(index));

               /* Adjust iso TD sequence */
               etd = &hc->etdBank[index];
               if (etd->nextEtd != NULL)
                  {
#if HC_MASS_STORAGE_NEW
                  td = (OhciTd*)OS_PhysicalToVirtual((void*)etd->nextEtd->td->nextTd);
#else
                  td = (OhciTd*)OS_PhysicalToVirtual(etd->nextEtd->td->nextTd);
#endif
                  if (td == etd->td)
                     {
                     etd = etd->nextEtd;
                     hc->etdIntrEnable &= ~(OTG242ETD_XYIntrEnable(etd->index));
                     OTG242ETD_EtdDone(etd);
                     doneQueue &= ~(1 << etd->index);
                     etd = &hc->etdBank[index];
                     }
                  }

               OTG242ETD_EtdDone(etd);

               doneQueue &= ~pos;
               if (0 == doneQueue)
                  {
                  break;
                  }
               }
            }
         }

      OTG242HC_WriteReg(hc, OTG242HC_INTR_STATUS, OTG242HC_INTR_WRITE_DONE_HEAD);
      }

   doneHead = OTG242HC_GetHcDoneHead(hc);
   if (doneHead)
      {
      oldOhciStatus = OTG242HC_GetHcIntrStatus(hc);
      if (!(oldOhciStatus & OHCI_HC_INTR_STATUS_DH))
         {
         *OTG242HC_HCCA_DONE_HEAD(hc) = OTG242HC_GetHcDoneHead(hc);
         OTG242HC_SetHcDoneHead(hc, 0);

         if (status & ~OTG242HC_INTR_WRITE_DONE_HEAD)
            {
            *OTG242HC_HCCA_DONE_HEAD(hc) |= 1;
            }

         ohciIntStatus |= OHCI_HC_INTR_STATUS_DH;
         }
      else
         {
         OS_DEBUG_MSG1(OS_ZONE_INTR, "Otg242Hc: Previous DoneQueue not finished\r\n");
         }
      }

    /*****************************************************************
      this code must follow the HandleWriteback done code so that
      all TD associated with the EDs listed in the removal procedures
      are removed from the done list
   *******************************************************************/

    
   if (status & OTG242HC_INTR_START_OF_FRAME)
      {
      U32 control;


      control = hc->ohciReg[OHCI_HC_CTRL / sizeof(U32)];
      if ((control & OHCI_HC_CTRL_IE) && hc->freeEtdCount > 0)
         {
         OTG242HC_DoIsocList(hc);
         }

      if ((control & OHCI_HC_CTRL_PLE) && hc->freeEtdCount > 0)
         {
         OTG242HC_DoPeriodicList(hc);
         }

      if ((control & OHCI_HC_CTRL_CLE) && hc->freeEtdCount > 0)
         {
         OTG242HC_DoCtrlList(hc);
         }

      if ((control & OHCI_HC_CTRL_BLE) && hc->freeEtdCount > 0)
         {
         OTG242HC_DoBulkList(hc);
         }
#if HC_MASS_STORAGE_NEW
      OTG242HC_CancelEtd(hc);
#endif
      ohciIntStatus |= OHCI_HC_INTR_STATUS_SF;
      }

    if (status & OTG242HC_INTR_ROOT_HUB_STATUS_CHANGE)
      {
      U32 hnpStatus;
            
/*      
      PRINTI1("Otg242Hc: RootHub Status Change\n");
*/

      /********************************************************
         This will happen when a mini A is plugged in and we 
         are in A_WAIT_BCON state. After checking this is 
         plugged to otg downstream port, we will   enter A_HOST 
         state. we will enable the pull down resister and the 
         disable pull up resister, however those have set as 
         default. Sof is generated already This doesn't tally 
         with spec. Spec says SOF should  only be generated 
         after entering A_HOST stage.
      *********************************************************/
         
      val = OTG242HC_ReadReg(hc, OTG242HC_RH_PORT_STATUS(OTG242HC_RH_OTG_PORT));

       if (val & OTG242HC_RH_PORT_STATUS_CSC) /* Connect Status Change */
         {
         /*************************************************
            We got a connection event on otg port, go to
            host stage. 
          **************************************************/
         if (val & OTG242HC_RH_PORT_STATUS_CCS) /* Cur Connect Status */
            {

            hnpStatus = OTG242HC_ReadReg(hc, OTG242HNP_CTRL);

            OS_DEBUG_MSG2(OS_ZONE_INTR, "Otg242Hc:Connect on otg port 0x%08X\r\n", hnpStatus);
                  
            if ((hnpStatus & OTG242HNP_CTRL_HNP_STATE) == OTG242HNP_CTRL_HNP_A_VBUS_ERR)
               {
               /*********************************************
                  A temporary hnp condition vbus error, just
                  clear it by writing 1 to hnpcontrol status
                *********************************************/
               hnpStatus |= OTG242HNP_CTRL_CLEAR_ERROR;
               OTG242HC_WriteReg(hc, OTG242HNP_CTRL, hnpStatus);
                  
               OS_DEBUG_MSG1(OS_ZONE_INTR, "Otg242Hc: ClearErr Restart Srp \r\n");
               }
               
            }
         else  
            {
            /********************************************************
               We got a disconnection event on otg port, and we 
               are in A-DEVICE at this time, if we are in B-DEVICE,
               we can't get this interrupt. Disconnection means a 
               transition to B-device, therefore, we need to power
               off the otg port, and also remove the bus request.
             ********************************************************/
            OS_DEBUG_MSG1(OS_ZONE_INTR, "Otg242Hc:Disconnect on otg port \r\n");
               
            hnpStatus = OTG242HC_ReadReg(hc, OTG242HNP_CTRL);
            hnpStatus &= ~OTG242HNP_CTRL_BUS_REQUEST;
            OTG242HC_WriteReg(hc, OTG242HNP_CTRL, hnpStatus);
            }
         }

      for( index = 0; index < OTG242HC_RH_PORT_MAX; index++ )
         {
         val = OTG242HC_ReadReg(hc,
         OTG242HC_RH_PORT_STATUS(OTG242HC_RH_OTG_PORT+index));

         val &= OTG242HC_RH_PORT_STATUS_CHANGE;
         OTG242HC_PortStatusChange[index] |= val;
         if(val)
            {
            OTG242HC_WriteReg(hc, 
               OTG242HC_RH_PORT_STATUS(OTG242HC_RH_OTG_PORT+index), val);
            }
         }

      ohciIntStatus |= OHCI_HC_INTR_STATUS_RHSC;
      }
 

    if (status & OTG242HC_INTR_SCHEDULE_OVERRUN) 
      {
      OS_DEBUG_MSG1(OS_ZONE_INTR, "Otg242Hc: Schedule overrun\r\n");

      ohciIntStatus |= OHCI_HC_INTR_STATUS_SO;
      }

    if (status & OTG242HC_INTR_UNRECOVERABLE_ERROR)
      {
            
      OS_DEBUG_MSG1(OS_ZONE_INTR, "Otg242Hc: Unrecoverable Error\r\n");

      ohciIntStatus |= OHCI_HC_INTR_STATUS_UE;
      }

    if (status & OTG242HC_INTR_FRAME_NO_OVERFLOW)
      {
      OS_DEBUG_MSG1(OS_ZONE_INTR, "Otg242Hc: Frame number overflow\r\n");

      ohciIntStatus |= OHCI_HC_INTR_STATUS_FNO;
      }
   
   OTG242HC_SetHcIntrStatus(hc, ohciIntStatus);

   return(0);
   }


void OTG242HC_DoIsocList(Otg242Hc *hc)
   {
   OhciEd*     ed;
   OhciTd*     td;
   Otg242EtdBank* etd;

   for
      (
#if HC_MASS_STORAGE_NEW
      ed = (OhciEd*)OS_PhysicalToVirtual((void*)(*(hc->hcca)));
#else
      ed = (OhciEd*)OS_PhysicalToVirtual(*(hc->hcca));
#endif
      ed;
      ed = (OHCIED_IsEof(ed->nextEd)) ? 0 :
#if HC_MASS_STORAGE_NEW
         (OhciEd*)OS_PhysicalToVirtual((void*)(ed->nextEd & OHCIED_POINTER))
#else
         (OhciEd*)OS_PhysicalToVirtual(ed->nextEd & OHCIED_POINTER)
#endif
      )
      {
      if ((ed->desc & OHCIED_SKIP) || !(ed->desc & OHCIED_FORMAT) ||
         (ed->headP & OHCIED_HALTED))
         {
         continue;
         }

      if ((ed->headP & OHCIED_POINTER) == (ed->tailP & OHCIED_POINTER))
         {
         /* No TD for this ED */
         continue;
         }
#if HC_MASS_STORAGE_NEW
      td = (OhciTd*)OS_PhysicalToVirtual((void*)(ed->headP & OHCIED_POINTER));
#else
      td = (OhciTd*)OS_PhysicalToVirtual((U32)ed->headP & OHCIED_POINTER);
#endif
      etd = OTG242ETD_IsInChip(hc->etdBank, ed);
      if (NULL == etd)
         {
         /* Find TD, find an empty slot */
         etd = OTG242ETD_Allocate(hc->etdBank);
         if (NULL == etd)
            {
            /* Run out of ETDs */
            break;
            }

         etd->ed = ed;
         etd->td = td;
         etd->type = EpTypeIsoc;

         OTG242ETD_FillEtdIsoc(etd);

         hc->etdIntrEnable |= OTG242ETD_XYIntrEnable(etd->index) ;

         if (hc->freeEtdCount == 0)
            {
            /* Can't process more TD, exit */
            return;
            }
         }

      if (NULL != etd->nextEtd)
         {
         continue;
         }

      if (td->nextTd == (ed->tailP & OHCIED_POINTER))
         {
         continue;
         }

      etd->nextEtd = OTG242ETD_Allocate(hc->etdBank);
      if (NULL == etd->nextEtd)
         {
         break;
         }
      
      etd->nextEtd->nextEtd = etd;
      etd = etd->nextEtd;

      etd->ed = ed;
#if HC_MASS_STORAGE_NEW
      td = (OhciTd*)OS_PhysicalToVirtual((void*)td->nextTd);
#else
      td = (OhciTd*)OS_PhysicalToVirtual((U32)td->nextTd);
#endif
      etd->td = td;
      etd->type = EpTypeIsoc;

      OTG242ETD_FillEtdIsoc(etd);

      hc->etdIntrEnable |= OTG242ETD_XYIntrEnable(etd->index) ;

      if (hc->freeEtdCount == 0)
         {
         return;
         }
      }
   }

U32 OTG242HC_DoList(Otg242Hc *hc, U32 startEd, EpType type)
   {
   U32         currentEd;
   OhciEd*        ed;
   Otg242EtdBank* etd;
   SctBool        rc;

   currentEd = startEd;


   
   for
      (
#if HC_MASS_STORAGE_NEW
      ed = (OhciEd*)OS_PhysicalToVirtual((void*)currentEd);
#else
      ed = (OhciEd*)OS_PhysicalToVirtual(currentEd);
#endif
      ed;
      currentEd = ed->nextEd,
         ed = (OHCIED_IsEof(currentEd)) ? 0 :
#if HC_MASS_STORAGE_NEW
         (OhciEd*)OS_PhysicalToVirtual((void*)(currentEd & OHCIED_POINTER))
#else
         (OhciEd*)OS_PhysicalToVirtual(currentEd & OHCIED_POINTER)
#endif
      )
      {
      
      if (ed->desc & OHCIED_SKIP)
         {
         continue;
         }

      if (ed->headP & OHCIED_HALTED)
         {
         continue;
         }

      if ((ed->headP & OHCIED_POINTER) == (ed->tailP & OHCIED_POINTER) ||
          (ed->headP & OHCIED_POINTER) == 0)
         {
         /* No TD for this ED */
         continue;
         }

      if (type == EpTypeCtrl)
         {
         OTG242HC_AddHcCommandStatus(hc, OHCI_HC_CMD_STATUS_CLF);
         }
      else
         {
         OTG242HC_AddHcCommandStatus(hc, OHCI_HC_CMD_STATUS_BLF);
         }
      
      etd = OTG242ETD_IsInChip(hc->etdBank, ed);
      if (etd != NULL)
         {
         continue;
         }

      /* Find TD, find an empty slot */
      etd = OTG242ETD_Allocate(hc->etdBank);
      if (NULL == etd)
         {
         /* Run out of ETDs */
         return currentEd;
         }

      etd->ed = ed;
#if HC_MASS_STORAGE_NEW
      etd->td = (OhciTd*)OS_PhysicalToVirtual((void*)(ed->headP & OHCIED_POINTER));
#else
      etd->td = (OhciTd*)OS_PhysicalToVirtual((U32)ed->headP & OHCIED_POINTER);
#endif
      etd->type = type;

      rc = OTG242ETD_FillEtd(etd);
      if (rc == SCC_FALSE)
         {
         /* Run out of memory etc. */
         OTG242ETD_Free(etd);
         return currentEd;
         }

      hc->etdIntrEnable |= OTG242ETD_XYIntrEnable(etd->index) ;

      if (hc->freeEtdCount == 0)
         {
         /* Can't process more TD, exit */
         return currentEd;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -