コード例 #1
0
ファイル: wlan_qct_wdi_cts.c プロジェクト: chunyeow/prima
/**
 @brief    This function is used by the DAL Core to close the
           Control Transport when its services are no longer
           needed. Full close notification will be receive
           asynchronously on the notification callback
           registered on Open


 @param wctsHandlehandle:  received upon open

 @see
 @return   0 for success
*/
wpt_uint32
WCTS_CloseTransport
(
   WCTS_HandleType      wctsHandle
)
{
   WCTS_ControlBlockType* pWCTSCb = (WCTS_ControlBlockType*) wctsHandle;
   wpt_list_node*      pNode = NULL;
   WCTS_BufferType*    pBufferQueue = NULL;
   void*               pBuffer = NULL;
   wpt_status          status;
   int                 smdstatus;

   /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

   if ((NULL == pWCTSCb) || (WCTS_CB_MAGIC != pWCTSCb->wctsMagic)) {
      WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
                 "WCTS_CloseTransport: Invalid parameters received.");
      return eWLAN_PAL_STATUS_E_INVAL;
   }

#ifdef FEATURE_R33D
   /* Not actually close port, just pretend */
   /* notified registered client that the channel is closed */
   pWCTSCb->wctsState = WCTS_STATE_CLOSED;
   pWCTSCb->wctsNotifyCB((WCTS_HandleType)pWCTSCb,
                         WCTS_EVENT_CLOSE,
                         pWCTSCb->wctsNotifyCBData);

   printk(KERN_ERR "R33D Not need to close");
   return eWLAN_PAL_STATUS_SUCCESS;
#endif /* FEATURE_R33D */

   /*Free the buffers in the pending queue.*/
   while (eWLAN_PAL_STATUS_SUCCESS ==
          wpal_list_remove_front(&pWCTSCb->wctsPendingQueue, &pNode)) {
      pBufferQueue = container_of(pNode, WCTS_BufferType, node);
      pBuffer = pBufferQueue->pBuffer;
      wpalMemoryFree(pBuffer);
      wpalMemoryFree(pBufferQueue);
   }

   /* Reset the state */
   pWCTSCb->wctsState = WCTS_STATE_CLOSED;

   wpalEventReset(&pWCTSCb->wctsEvent);
   smdstatus = smd_close(pWCTSCb->wctsChannel);
   if (0 != smdstatus) {
      WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
                 "%s: smd_close failed with status %d",
                 __func__, smdstatus);
      /* SMD did not successfully close the channel, therefore we
         won't receive an asynchronous close notification so don't
         bother to wait for an event that won't come */

   } else {
      /* close command was sent -- wait for the callback to complete */
      status = wpalEventWait(&pWCTSCb->wctsEvent, WCTS_SMD_CLOSE_TIMEOUT);
      if (eWLAN_PAL_STATUS_SUCCESS != status) {
         WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
                    "%s: failed to receive SMD_EVENT_REOPEN_READY",
                    __func__);
      }

      /* During the close sequence we deregistered from SMD.  As part
         of deregistration SMD will call back into our driver with an
         event to let us know the channel is closed.  We need to
         insert a brief delay to allow that thread of execution to
         exit our module.  Otherwise our module may be unloaded while
         there is still code running within the address space, and
         that code will crash when the memory is unmapped  */
      msleep(50);
   }

   /* channel has (hopefully) been closed */
   pWCTSCb->wctsNotifyCB((WCTS_HandleType)pWCTSCb,
                         WCTS_EVENT_CLOSE,
                         pWCTSCb->wctsNotifyCBData);

   /* release the resource */
   pWCTSCb->wctsMagic = 0;
   wpalMemoryFree(pWCTSCb);
   gwctsHandle = NULL;

   return eWLAN_PAL_STATUS_SUCCESS;

}/*WCTS_CloseTransport*/
コード例 #2
0
wpt_uint32
WCTS_CloseTransport
(
   WCTS_HandleType      wctsHandle
)
{
   WCTS_ControlBlockType* pWCTSCb = (WCTS_ControlBlockType*) wctsHandle;
   wpt_list_node*      pNode = NULL;
   WCTS_BufferType*    pBufferQueue = NULL;
   void*               pBuffer = NULL;
   wpt_status          status;
   int                 smdstatus;

   

   if ((NULL == pWCTSCb) || (WCTS_CB_MAGIC != pWCTSCb->wctsMagic)) {
      WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
                 "WCTS_CloseTransport: Invalid parameters received.");
      return eWLAN_PAL_STATUS_E_INVAL;
   }

#ifdef FEATURE_R33D
   
   
   pWCTSCb->wctsState = WCTS_STATE_CLOSED;
   pWCTSCb->wctsNotifyCB((WCTS_HandleType)pWCTSCb,
                         WCTS_EVENT_CLOSE,
                         pWCTSCb->wctsNotifyCBData);

   printk(KERN_ERR "R33D Not need to close");
   return eWLAN_PAL_STATUS_SUCCESS;
#endif 

   
   while (eWLAN_PAL_STATUS_SUCCESS ==
          wpal_list_remove_front(&pWCTSCb->wctsPendingQueue, &pNode)) {
      pBufferQueue = container_of(pNode, WCTS_BufferType, node);
      pBuffer = pBufferQueue->pBuffer;
      wpalMemoryFree(pBuffer);
      wpalMemoryFree(pBufferQueue);
   }

   
   pWCTSCb->wctsState = WCTS_STATE_CLOSED;

   wpalEventReset(&pWCTSCb->wctsEvent);
   smdstatus = smd_close(pWCTSCb->wctsChannel);
   if (0 != smdstatus) {
      WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
                 "%s: smd_close failed with status %d",
                 __func__, smdstatus);

   } else {
      
      status = wpalEventWait(&pWCTSCb->wctsEvent, WCTS_SMD_CLOSE_TIMEOUT);
      if (eWLAN_PAL_STATUS_SUCCESS != status) {
         WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
                    "%s: failed to receive SMD_EVENT_REOPEN_READY",
                    __func__);
      }

      msleep(50);
   }

   
   pWCTSCb->wctsNotifyCB((WCTS_HandleType)pWCTSCb,
                         WCTS_EVENT_CLOSE,
                         pWCTSCb->wctsNotifyCBData);

   
   pWCTSCb->wctsMagic = 0;
   wpalMemoryFree(pWCTSCb);
   gwctsHandle = NULL;

   return eWLAN_PAL_STATUS_SUCCESS;

}
コード例 #3
0
ファイル: wlan_qct_wdi_cts.c プロジェクト: chunyeow/prima
/**
 @brief     This function is used by the DAL Core to initialize the Control
            Transport for processing. It must be called prior to calling any
            other APIs of the Control Transport.


 @param szName:   unique name for the channel that is to be opened
         uSize:   size of the channel that must be opened (should fit the
                  largest size of  packet that the Dal Core wishes to send)
         wctsCBs:  a list of callbacks that the CT needs to use to send
                  notification and messages back to DAL

 @see
 @return  A handle that must be used for further communication with the CTS.
         This is an opaque structure for the caller and it will be used in
         all communications to and from the CTS.

*/
WCTS_HandleType
WCTS_OpenTransport
(
   const wpt_uint8*         szName,
   wpt_uint32               uSize,
   WCTS_TransportCBsType*   wctsCBs
)
{
   WCTS_ControlBlockType*    pWCTSCb;
   wpt_status                status;
   int                       smdstatus;

   /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/

   /*---------------------------------------------------------------------
     Sanity check
     ---------------------------------------------------------------------*/
   if ((NULL == wctsCBs) || (NULL == szName) ||
       (NULL == wctsCBs->wctsNotifyCB) || (NULL == wctsCBs->wctsRxMsgCB)) {
      WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
                 "WCTS_OpenTransport: Invalid parameters received.");

      return NULL;
   }

   /* This open is coming after a SSR, we don't need to reopen SMD,
    * the SMD port was never closed during SSR*/
   if (gwctsHandle) {
       WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO,
               "WCTS_OpenTransport port is already open\n");

       pWCTSCb = gwctsHandle;
       if (WCTS_CB_MAGIC != pWCTSCb->wctsMagic) {
           WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL,
                   "WCTS_OpenTransport: Invalid magic.");
           return NULL;
       }   
       pWCTSCb->wctsState = WCTS_STATE_OPEN;

       pWCTSCb->wctsNotifyCB((WCTS_HandleType)pWCTSCb,
               WCTS_EVENT_OPEN,
               pWCTSCb->wctsNotifyCBData);

       /* we initially don't want read interrupts
         (we only want them if we get into deferred write mode) */
       smd_disable_read_intr(pWCTSCb->wctsChannel);

       return (WCTS_HandleType)pWCTSCb;
   }

#ifdef FEATURE_R33D
   if(port_open)
   {
      /* Port open before, not need to open again */
      /* notified registered client that the channel is open */
      ctsCB->wctsState = WCTS_STATE_OPEN;
      ctsCB->wctsNotifyCB((WCTS_HandleType)ctsCB,
                           WCTS_EVENT_OPEN,
                           ctsCB->wctsNotifyCBData);
      return (WCTS_HandleType)ctsCB;
   }
#endif /* FEATURE_R33D */

   /* allocate a ControlBlock to hold all context */
   pWCTSCb = wpalMemoryAllocate(sizeof(*pWCTSCb));
   if (NULL == pWCTSCb) {
      WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
                 "WCTS_OpenTransport: Memory allocation failure.");
      return NULL;
   }

   /* make sure the control block is initialized.  in particular we need
      to make sure the embedded event and list structures are initialized
      to prevent "magic number" tests from being run against uninitialized
      values */
   wpalMemoryZero(pWCTSCb, sizeof(*pWCTSCb));

#ifdef FEATURE_R33D
   smd_init(0);
   port_open = 1;
   ctsCB = pWCTSCb;
#endif /* FEATURE_R33D */

   /*Initialise the event*/
   wpalEventInit(&pWCTSCb->wctsEvent);

   /* save the user-supplied information */
   pWCTSCb->wctsNotifyCB       = wctsCBs->wctsNotifyCB;
   pWCTSCb->wctsNotifyCBData   = wctsCBs->wctsNotifyCBData;
   pWCTSCb->wctsRxMsgCB        = wctsCBs->wctsRxMsgCB;
   pWCTSCb->wctsRxMsgCBData    = wctsCBs->wctsRxMsgCBData;

   /* initialize the remaining fields */
   wpal_list_init(&pWCTSCb->wctsPendingQueue);
   pWCTSCb->wctsMagic   = WCTS_CB_MAGIC;
   pWCTSCb->wctsState   = WCTS_STATE_OPEN_PENDING;
   pWCTSCb->wctsChannel = NULL;

   /* since SMD will callback in interrupt context, we will used
    * canned messages to serialize the SMD events into a thread
    * context
    */
   pWCTSCb->wctsOpenMsg.callback = WCTS_PALOpenCallback;
   pWCTSCb->wctsOpenMsg.pContext = pWCTSCb;

   pWCTSCb->wctsDataMsg.callback = WCTS_PALDataCallback;
   pWCTSCb->wctsDataMsg.pContext = pWCTSCb;

   /*---------------------------------------------------------------------
     Open the SMD channel
     ---------------------------------------------------------------------*/

   wpalEventReset(&pWCTSCb->wctsEvent);
   smdstatus = smd_named_open_on_edge(szName,
                                      SMD_APPS_WCNSS,
                                      &pWCTSCb->wctsChannel,
                                      pWCTSCb,
                                      WCTS_NotifyCallback);
   if (0 != smdstatus) {
      WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
                 "%s: smd_named_open_on_edge failed with status %d",
                 __func__, smdstatus);
      goto fail;
   }

   /* wait for the channel to be fully opened before we proceed */
   status = wpalEventWait(&pWCTSCb->wctsEvent, WCTS_SMD_OPEN_TIMEOUT);
   if (eWLAN_PAL_STATUS_SUCCESS != status) {
      WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
                 "%s: failed to receive SMD_EVENT_OPEN",
                 __func__);
      /* since we opened one end of the channel, close it */
      smdstatus = smd_close(pWCTSCb->wctsChannel);
      if (0 != smdstatus) {
         WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
                    "%s: smd_close failed with status %d",
                    __func__, smdstatus);
      }
      goto fail;
   }

   /* we initially don't want read interrupts
      (we only want them if we get into deferred write mode) */
   smd_disable_read_intr(pWCTSCb->wctsChannel);

   /* we have successfully opened the SMD channel */
   gwctsHandle = pWCTSCb;
   return (WCTS_HandleType)pWCTSCb;

 fail:
   /* we were unable to open the SMD channel */
   pWCTSCb->wctsMagic = 0;
   wpalMemoryFree(pWCTSCb);
   return NULL;

}/*WCTS_OpenTransport*/
コード例 #4
0
WCTS_HandleType
WCTS_OpenTransport
(
   const wpt_uint8*         szName,
   wpt_uint32               uSize,
   WCTS_TransportCBsType*   wctsCBs
)
{
   WCTS_ControlBlockType*    pWCTSCb;
   wpt_status                status;
   int                       smdstatus;

   

   if ((NULL == wctsCBs) || (NULL == szName) ||
       (NULL == wctsCBs->wctsNotifyCB) || (NULL == wctsCBs->wctsRxMsgCB)) {
      WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
                 "WCTS_OpenTransport: Invalid parameters received.");

      return NULL;
   }

   if (gwctsHandle) {
       WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO,
               "WCTS_OpenTransport port is already open");

       pWCTSCb = gwctsHandle;
       if (WCTS_CB_MAGIC != pWCTSCb->wctsMagic) {
           WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL,
                   "WCTS_OpenTransport: Invalid magic.");
           return NULL;
       }   
       pWCTSCb->wctsState = WCTS_STATE_OPEN;

       pWCTSCb->wctsNotifyCB((WCTS_HandleType)pWCTSCb,
               WCTS_EVENT_OPEN,
               pWCTSCb->wctsNotifyCBData);

       smd_disable_read_intr(pWCTSCb->wctsChannel);

       return (WCTS_HandleType)pWCTSCb;
   }

#ifdef FEATURE_R33D
   if(port_open)
   {
      
      
      ctsCB->wctsState = WCTS_STATE_OPEN;
      ctsCB->wctsNotifyCB((WCTS_HandleType)ctsCB,
                           WCTS_EVENT_OPEN,
                           ctsCB->wctsNotifyCBData);
      return (WCTS_HandleType)ctsCB;
   }
#endif 

   
   pWCTSCb = wpalMemoryAllocate(sizeof(*pWCTSCb));
   if (NULL == pWCTSCb) {
      WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
                 "WCTS_OpenTransport: Memory allocation failure.");
      return NULL;
   }

   wpalMemoryZero(pWCTSCb, sizeof(*pWCTSCb));

#ifdef FEATURE_R33D
   smd_init(0);
   port_open = 1;
   ctsCB = pWCTSCb;
#endif 

   
   wpalEventInit(&pWCTSCb->wctsEvent);

   
   pWCTSCb->wctsNotifyCB       = wctsCBs->wctsNotifyCB;
   pWCTSCb->wctsNotifyCBData   = wctsCBs->wctsNotifyCBData;
   pWCTSCb->wctsRxMsgCB        = wctsCBs->wctsRxMsgCB;
   pWCTSCb->wctsRxMsgCBData    = wctsCBs->wctsRxMsgCBData;

   
   wpal_list_init(&pWCTSCb->wctsPendingQueue);
   pWCTSCb->wctsMagic   = WCTS_CB_MAGIC;
   pWCTSCb->wctsState   = WCTS_STATE_OPEN_PENDING;
   pWCTSCb->wctsChannel = NULL;

   pWCTSCb->wctsOpenMsg.callback = WCTS_PALOpenCallback;
   pWCTSCb->wctsOpenMsg.pContext = pWCTSCb;
   pWCTSCb->wctsOpenMsg.type= WPAL_MC_MSG_SMD_NOTIF_OPEN_SIG;

   pWCTSCb->wctsDataMsg.callback = WCTS_PALDataCallback;
   pWCTSCb->wctsDataMsg.pContext = pWCTSCb;
   pWCTSCb-> wctsDataMsg.type= WPAL_MC_MSG_SMD_NOTIF_DATA_SIG;


   wpalEventReset(&pWCTSCb->wctsEvent);
   smdstatus = smd_named_open_on_edge(szName,
                                      SMD_APPS_WCNSS,
                                      &pWCTSCb->wctsChannel,
                                      pWCTSCb,
                                      WCTS_NotifyCallback);
   if (0 != smdstatus) {
      WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
                 "%s: smd_named_open_on_edge failed with status %d",
                 __func__, smdstatus);
      goto fail;
   }

   
   status = wpalEventWait(&pWCTSCb->wctsEvent, WCTS_SMD_OPEN_TIMEOUT);
   if (eWLAN_PAL_STATUS_SUCCESS != status) {
      WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
                 "%s: failed to receive SMD_EVENT_OPEN",
                 __func__);
      
      smdstatus = smd_close(pWCTSCb->wctsChannel);
      if (0 != smdstatus) {
         WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
                    "%s: smd_close failed with status %d",
                    __func__, smdstatus);
      }
      goto fail;
   }

   smd_disable_read_intr(pWCTSCb->wctsChannel);

   
   gwctsHandle = pWCTSCb;
   return (WCTS_HandleType)pWCTSCb;

 fail:
   
   pWCTSCb->wctsMagic = 0;
   wpalMemoryFree(pWCTSCb);
   return NULL;

}