Пример #1
0
static void _WMI_SendEvent(wmi_handle_t handle, adf_nbuf_t pEvt,
                           A_UINT16 EventId, A_UINT16 SeqNo, int Length)
{
	WMI_SVC_CONTEXT *pWMI = (WMI_SVC_CONTEXT *)handle;
	A_UINT8 *pBuffer;

	pBuffer = adf_nbuf_push_head(pEvt, sizeof(WMI_CMD_HDR));
	A_SET_UINT16_FIELD(pBuffer, WMI_CMD_HDR, commandId, adf_os_htons(EventId));
	A_SET_UINT16_FIELD(pBuffer, WMI_CMD_HDR, seqNo, adf_os_htons(SeqNo));

	HTC_SendMsg(pWMI->HtcHandle, pWMI->ControlEp, pEvt);
}
Пример #2
0
LOCAL void HTCProcessConfigPipeMsg(HTC_CONTEXT *pHTC, HTC_CONFIG_PIPE_MSG *pMsg)
{
	adf_nbuf_t pBuffer;
	HTC_CONFIG_PIPE_RESPONSE_MSG *pRspMsg;
        
	pBuffer = HTCAllocMsgBuffer(pHTC);
       
	/* note : this will be aligned */
	pRspMsg = (HTC_CONFIG_PIPE_RESPONSE_MSG *)
                adf_nbuf_put_tail(pBuffer, sizeof(HTC_CONFIG_PIPE_RESPONSE_MSG));    
              
	A_MEMZERO(pRspMsg,sizeof(HTC_CONFIG_PIPE_RESPONSE_MSG));
    
	pRspMsg->MessageID = adf_os_htons(HTC_MSG_CONFIG_PIPE_RESPONSE_ID);
	/* reflect the service ID for this connect attempt */
	pRspMsg->PipeID = pMsg->PipeID;

	if ( HIF_is_pipe_supported(pHTC->hifHandle, pMsg->PipeID) ) {
		pRspMsg->Status = 0;            
	} else {
		pRspMsg->Status = 1; 
		goto config_done;
	}

	if ( (pHTC->TotalCreditsAssigned + pMsg->CreditCount) <= pHTC->TotalCredits ) {
		pHTC->TotalCreditsAssigned += pMsg->CreditCount;
	} else {
		pRspMsg->Status = 2;
		goto config_done;
	}
    
	HIF_config_pipe(pHTC->hifHandle, pMsg->PipeID, pMsg->CreditCount);
    
config_done:      
	/* send out the response message */
	HTC_SendMsg(pHTC, ENDPOINT0, pBuffer);             
}
Пример #3
0
LOCAL void _HTC_Ready(htc_handle_t htcHandle)
{
	adf_nbuf_t pBuffer;
	HTC_READY_MSG *pReady;
	a_uint8_t *addr;
	HTC_CONTEXT *pHTC = (HTC_CONTEXT *)htcHandle;
    
	pBuffer = HTCAllocMsgBuffer(pHTC);
       
	/* an optimization... the header length is chosen to
	 * be aligned on a 16 bit bounday, the fields in the message are designed to
	 * be aligned */
	addr = adf_nbuf_put_tail(pBuffer, sizeof(HTC_READY_MSG));       
	pReady = (HTC_READY_MSG *)addr;     
	A_MEMZERO(pReady,sizeof(HTC_READY_MSG));  
	pReady->MessageID = adf_os_htons(HTC_MSG_READY_ID);
	pReady->CreditSize = adf_os_htons((A_UINT16)pHTC->RecvBufferSize);
	pReady->CreditCount = adf_os_htons((A_UINT16)pHTC->TotalCredits);
	pReady->MaxEndpoints = ENDPOINT_MAX;
       
	/* send out the message */
	HTC_SendMsg(pHTC, ENDPOINT0, pBuffer);
	/* now we need to wait for service connection requests */
}
Пример #4
0
/* called in response to the arrival of a service connection message */
LOCAL void HTCProcessConnectMsg(HTC_CONTEXT *pHTC, HTC_CONNECT_SERVICE_MSG *pMsg)
{
	HTC_SERVICE *pService = pHTC->pServiceList;
	A_UINT8 connectStatus = HTC_SERVICE_NOT_FOUND;
	adf_nbuf_t pBuffer;
	HTC_CONNECT_SERVICE_RESPONSE_MSG *pRspMsg;
	int metaDataOutLen = 0;
	A_UINT16 serviceId = adf_os_ntohs(pMsg->ServiceID);
    
	pBuffer = HTCAllocMsgBuffer(pHTC);
	/* note : this will be aligned */
	pRspMsg = (HTC_CONNECT_SERVICE_RESPONSE_MSG *)
                adf_nbuf_put_tail(pBuffer, sizeof(HTC_CONNECT_SERVICE_RESPONSE_MSG));
                                 
	A_MEMZERO(pRspMsg,sizeof(HTC_CONNECT_SERVICE_RESPONSE_MSG));
	pRspMsg->MessageID = adf_os_htons(HTC_MSG_CONNECT_SERVICE_RESPONSE_ID);
	/* reflect the service ID for this connect attempt */
	pRspMsg->ServiceID = adf_os_htons(serviceId);

	while (pService) {
        
		if (pHTC->CurrentEpIndex >= ENDPOINT_MAX) {
			/* no more endpoints */
			connectStatus = HTC_SERVICE_NO_RESOURCES;
			break;    
		}

		if (serviceId == pService->ServiceID) {
			/* we found a match */             
			A_UINT8 *pMetaDataIN = NULL; 
			A_UINT8 *pMetaDataOut;
            
			/* outgoing meta data resides in the space after the response message */
			pMetaDataOut = ((A_UINT8 *)pRspMsg) + sizeof(HTC_CONNECT_SERVICE_RESPONSE_MSG);
            
			if (pMsg->ServiceMetaLength != 0) {
				/* the meta data follows the connect service message */
				pMetaDataIN = ((A_UINT8 *)pMsg) + sizeof(HTC_CONNECT_SERVICE_MSG);
			}

			/* call the connect callback with the endpoint to use and pointers to meta data */
			connectStatus = pService->ProcessConnect(pService,
								 pHTC->CurrentEpIndex,
								 pMetaDataIN,
								 pMsg->ServiceMetaLength,
								 pMetaDataOut,
								 &metaDataOutLen);
            
			/* check if the service accepted this connection request */
			if (HTC_SERVICE_SUCCESS == connectStatus) {
				/* set the length of the response meta data going back to the host */
				pRspMsg->ServiceMetaLength = (A_UINT8)metaDataOutLen;
				/* set the endpoint ID the host will now communicate over */
				pRspMsg->EndpointID = pHTC->CurrentEpIndex;
				/* return the maximum message size for this service */
				pRspMsg->MaxMsgSize = adf_os_htons((A_UINT16)pService->MaxSvcMsgSize);
				/* assign this endpoint to this service, this will be used in routing messages */
				pHTC->Endpoints[pHTC->CurrentEpIndex].pService = pService;
				/* set connection flags */
				pHTC->Endpoints[pHTC->CurrentEpIndex].ConnectionFlags = pMsg->ConnectionFlags;
                
				pHTC->Endpoints[pHTC->CurrentEpIndex].DownLinkPipeID = pMsg->DownLinkPipeID;
				pHTC->Endpoints[pHTC->CurrentEpIndex].UpLinkPipeID = pMsg->UpLinkPipeID;
                
				/* mark that we are now connected */
				pService->ServiceFlags |= HTC_SERVICE_FLAGS_CONNECTED;
				/* bump up our index, this EP is now in use */
				pHTC->CurrentEpIndex++;   
			}

			break;
		}       
        
		pService = pService->pNext;   
	}
                   
	pRspMsg->Status = connectStatus;    
    
	/* send out the response message */
	HTC_SendMsg(pHTC, ENDPOINT0, pBuffer); 
}
Пример #5
0
LOCAL void HTCCheckAndSendCreditReport(HTC_CONTEXT *pHTC, A_UINT32 EpMask,
				       HTC_ENDPOINT *pEndpoint, HTC_ENDPOINT_ID Eid)
{
	adf_nbuf_t pCredBuffer;
	HTC_BUF_CONTEXT *ctx;    
        
	do {
		/* check if host needs credits */
		if (!(pHTC->EpHostNeedsCreditMap & EpMask)) {
			/* host does not need any credits for this set */
			break;    
		}
		/* check if any are pending */
		if (!(pHTC->EpCreditPendingMap & EpMask)) {
			/* nothing to send up */
			break;    
		}  
		/* was an endpoint specified? */
		if (pEndpoint != NULL) {
			/* see if a threshold is in effect for this endpoint */
			if (pEndpoint->CreditReturnThreshhold != 0) {
				if (pEndpoint->CreditsToReturn < pEndpoint->CreditReturnThreshhold) {
					/* this endpoint is using a threshold to prevent credits from dribbling
					 * back to the host */
					break;
				}
			}
         
			if (pEndpoint->PendingCreditReports >= pHTC->MaxEpPendingCreditRpts) {
				/* this endpoint already has some reports outstanding */
				/* flag that as soon as a buffer is reaped, we issue a credit update to
				 * pick up this credit that is being held up because the endpoint has already
				 * exceeded the max outstanding credit report limit */    
				pHTC->StateFlags |= HTC_SEND_CREDIT_UPDATE_SOON;
				break;    
			}                         
		}
        
		/* if we get here we have some credits to send up */
                        
		/* allocate a message buffer for the trailer */
		pCredBuffer = HTCAllocMsgBuffer(pHTC);
		if (NULL == pCredBuffer) {
			/* no buffers left to send an empty message with trailers, host will just
			 * have to wait until we get our endpoint 0 messages back.. */
			/* mark that we need to send an update as soon as we can get a buffer back */
			pHTC->StateFlags |= HTC_SEND_CREDIT_UPDATE_SOON;
			break;    
		}
        
		ctx = (HTC_BUF_CONTEXT *)adf_nbuf_get_priv(pCredBuffer);
		if (pEndpoint != NULL) {
			/* keep track of pending reports */
			pEndpoint->PendingCreditReports++; 
			/* save the endpoint in order to decrement the count when the send completes */
			ctx->htc_flags = Eid | HTC_FLAGS_CREDIT_RPT;
		}   
            
		/* this is an empty message, the HTC_SendMsg will tack on a trailer in the remaining
		 * space, NOTE: no need to flush the cache, the header and trailers are assembled
		 * using uncached addresses */
		HTC_SendMsg(pHTC, ENDPOINT0, pCredBuffer);    
    
	} while (FALSE);      
}