/********************************************************************** * 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(); } }
// 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; }