コード例 #1
0
/**********************************************************************
* Outline 		: CBSetup
* Description 	: Callback from HAL when it has received a setup packet.
				  Responds with either an CONTROL IN, OUT, ACK or STALL.
				  If this layer can not deal with the setup packet
				  on its own it will call an upper layer to see if it
				  knows how to deal with it.
* Argument  	: _pSetupPacket - buffer containing the setup packet.
* Return value  : none
**********************************************************************/
static void CBSetup(const uint8_t(*_pSetupPacket)[USB_SETUP_PACKET_SIZE])
{
	USB_ERR err;
	uint16_t NumBytes;
	uint8_t* pBuffer;
	
	/*Populate the Setup Packet structure g_oSetupPacket */
	PopulateSetupPacket(_pSetupPacket);
	
	/*Process this setup packet*/
	err = ProcessSetupPacket(&NumBytes, &pBuffer);
							
	if(USB_ERR_UNKNOWN_REQUEST == err)
	{
		/*Can't handle this setup packet*/
		/*Let upper layer try - call registered callback*/
		err = g_fpCBSetupPacket(&g_oSetupPacket, &NumBytes, &pBuffer);
	}
	
	if(USB_ERR_OK == err)
	{
		/*Is there a data stage?*/
		if(0 != g_oSetupPacket.wLength)
		{
			/* Is this a Data IN or OUT */
			if(0 != EXTRACT_bmRequest_DIRECTION(g_oSetupPacket.bmRequest))
			{
				/*IN*/
				/*Don't send more data than host has requested*/
				if(NumBytes > g_oSetupPacket.wLength)
				{
					NumBytes = g_oSetupPacket.wLength; 
				}
			
				/*Send Data*/
				USBHAL_Control_IN(NumBytes, pBuffer);
			}
			else
			{
				/*OUT*/
				assert(g_oSetupPacket.wLength == NumBytes);
				
				USBHAL_Control_OUT(NumBytes, pBuffer, g_fpCBControlOut);
			}
		}
		else
		{
			/*No data stage - just need to send ACK*/
			USBHAL_Control_Status();
		}
	}
	else
	{
		/*Something wrong with this control pipe so stall it.*/
		USBHAL_Control_Stall();
	}
}
コード例 #2
0
ファイル: usbrndis.c プロジェクト: HITEG/TenByTen6410_SLC
// Called by RndisMin & UsbRndis to get "interesting" events from PDD
//
UINT32
UsbRndis_EventHandler(
    )
{
    USBDBG_MSG msg = USBDBG_MSG_NOMSG;
    DWORD retVal;
    DWORD epNum;
    static USB_DEVICE_REQUEST pendingUdr;
    static BOOL fProcessingSetupRequest = FALSE;


    USBDBGMSG(USBDBG_ZONE_EVENT, (L"usbdbg:+UsbRndis_EventHandler\r\n"));

    // call PDD to get any interesting events
    retVal = m_pddIfc.pfnEventHandler(&msg, &m_MsgParamBuf[0]);

    //quit if error
    if (retVal != ERROR_SUCCESS)
    {
        USBDBGMSG(USBDBG_ZONE_ERROR, (
            L"ERROR!usbdbg:UsbRndis_EventHandler\r\n"));
        goto clean;
    }

    switch (msg)
    {
        // a packet received on an EP
        case USBDBG_MSG_EP_RX_PKT:
        {
            epNum = *((DWORD*)m_MsgParamBuf);
            ContinueRxTransfer(epNum);
            break;
        }
        // a packet sent on an EP
        case USBDBG_MSG_EP_TX_PKT:
        {
            epNum = *((DWORD*)m_MsgParamBuf);
            ContinueTxTransfer(epNum);
            break;
        }
        // set up packet recvd
        case USBDBG_MSG_SETUP_PACKET:
        {
            USB_DEVICE_REQUEST udr = *((USB_DEVICE_REQUEST*) m_MsgParamBuf);
            BOOL fProcessRndisMsg = FALSE;

            // if a transfer is already in progress on EP0, mark this
            // setup packet pending and return to unwind stack.
            if (fProcessingSetupRequest)
            {
                m_fSetupCancelled = TRUE;
                pendingUdr = udr;

                // stop any transfers on EP0
                if (m_epTransfers[0].status & USBDBG_TRANSFER_STATUS_INPROGRESS)
                {
                    AbortTransfer(CONTROL_ENDPT, ENDPT_DIR_RX);
                    AbortTransfer(CONTROL_ENDPT, ENDPT_DIR_TX);
                }
                goto clean;
            }
            else
            {
                m_fSetupCancelled = FALSE;
            }


            fProcessingSetupRequest = TRUE;

            ProcessSetupPacket(&udr, &fProcessRndisMsg);

            fProcessingSetupRequest = FALSE;
            //rndis msg received?
            if (fProcessRndisMsg)
                ProcessRndisMsg(m_ep0MsgRxBuffer, udr.wLength);

            // while a setup packet was being processed another might have come
            // in. udr's processing was cancelled and the pending udr was stored
            // in m_pendingUdr.
            while (m_fSetupCancelled)
            {
                m_fSetupCancelled = FALSE;
                fProcessingSetupRequest = TRUE;
                ProcessSetupPacket(&pendingUdr, &fProcessRndisMsg);
                fProcessingSetupRequest = FALSE;
                if (fProcessRndisMsg)
                    ProcessRndisMsg(m_ep0MsgRxBuffer, udr.wLength);
            }

            break;
        }

        case USBDBG_MSG_BUS_EVENT_DETACH:
        case USBDBG_MSG_BUS_EVENT_SUSPEND:
        case USBDBG_MSG_BUS_EVENT_RESET:
        {
            // tell rndismin layer
            RndisPdd_SetRndisState(TRUE);

            // abort all transfers
            AbortTransfers(TRUE, TRUE);

            // bus speed is determined, update ep's maxpktsize
            UpdateUSBDesc();

            break;
        }

        default:
            break;
    }

clean:
    USBDBGMSG(USBDBG_ZONE_EVENT, (L"usbdbg:-UsbRndis_EventHandler.msg=%d\r\n",
                msg));
    return msg;
}