// HandleRequest status_t KernelRequestHandler::HandleRequest(Request* request) { if (request->GetType() == fExpectedReply) { fDone = true; return B_OK; } switch (request->GetType()) { // notifications case NOTIFY_LISTENER_REQUEST: return _HandleRequest((NotifyListenerRequest*)request); case NOTIFY_SELECT_EVENT_REQUEST: return _HandleRequest((NotifySelectEventRequest*)request); case NOTIFY_QUERY_REQUEST: return _HandleRequest((NotifyQueryRequest*)request); // vnodes case GET_VNODE_REQUEST: return _HandleRequest((GetVNodeRequest*)request); case PUT_VNODE_REQUEST: return _HandleRequest((PutVNodeRequest*)request); case ACQUIRE_VNODE_REQUEST: return _HandleRequest((AcquireVNodeRequest*)request); case NEW_VNODE_REQUEST: return _HandleRequest((NewVNodeRequest*)request); case PUBLISH_VNODE_REQUEST: return _HandleRequest((PublishVNodeRequest*)request); case REMOVE_VNODE_REQUEST: return _HandleRequest((RemoveVNodeRequest*)request); case UNREMOVE_VNODE_REQUEST: return _HandleRequest((UnremoveVNodeRequest*)request); case GET_VNODE_REMOVED_REQUEST: return _HandleRequest((GetVNodeRemovedRequest*)request); // file cache case FILE_CACHE_CREATE_REQUEST: return _HandleRequest((FileCacheCreateRequest*)request); case FILE_CACHE_DELETE_REQUEST: return _HandleRequest((FileCacheDeleteRequest*)request); case FILE_CACHE_SET_ENABLED_REQUEST: return _HandleRequest((FileCacheSetEnabledRequest*)request); case FILE_CACHE_SET_SIZE_REQUEST: return _HandleRequest((FileCacheSetSizeRequest*)request); case FILE_CACHE_SYNC_REQUEST: return _HandleRequest((FileCacheSyncRequest*)request); case FILE_CACHE_READ_REQUEST: return _HandleRequest((FileCacheReadRequest*)request); case FILE_CACHE_WRITE_REQUEST: return _HandleRequest((FileCacheWriteRequest*)request); // I/O case DO_ITERATIVE_FD_IO_REQUEST: return _HandleRequest((DoIterativeFDIORequest*)request); case READ_FROM_IO_REQUEST_REQUEST: return _HandleRequest((ReadFromIORequestRequest*)request); case WRITE_TO_IO_REQUEST_REQUEST: return _HandleRequest((WriteToIORequestRequest*)request); case NOTIFY_IO_REQUEST_REQUEST: return _HandleRequest((NotifyIORequestRequest*)request); // node monitoring case ADD_NODE_LISTENER_REQUEST: return _HandleRequest((AddNodeListenerRequest*)request); case REMOVE_NODE_LISTENER_REQUEST: return _HandleRequest((RemoveNodeListenerRequest*)request); } PRINT(("KernelRequestHandler::HandleRequest(): unexpected request: %" B_PRIu32 "\n", request->GetType())); return B_BAD_DATA; }
/** * Handles IN/OUT transfers on EP0 * * @param [in] bEP Endpoint address * @param [in] bEPStat Endpoint status */ void USBHandleControlTransfer(U8 bEP, U8 bEPStat) { int iChunk, iType; if (bEP == 0x00) { // OUT transfer if (bEPStat & EP_STATUS_SETUP) { // setup packet, reset request message state machine USBHwEPRead(0x00, (U8 *)&Setup, sizeof(Setup)); DBG("S%x", Setup.bRequest); // defaults for data pointer and residue iType = REQTYPE_GET_TYPE(Setup.bmRequestType); pbData = apbDataStore[iType]; iResidue = Setup.wLength; iLen = Setup.wLength; if ((Setup.wLength == 0) || (REQTYPE_GET_DIR(Setup.bmRequestType) == REQTYPE_DIR_TO_HOST)) { // ask installed handler to process request if (!_HandleRequest(&Setup, &iLen, &pbData)) { DBG("_HandleRequest1 failed\n"); StallControlPipe(bEPStat); return; } // send smallest of requested and offered length iResidue = MIN(iLen, Setup.wLength); // send first part (possibly a zero-length status message) DataIn(); } } else { if (iResidue > 0) { // store data iChunk = USBHwEPRead(0x00, pbData, iResidue); if (iChunk < 0) { StallControlPipe(bEPStat); return; } pbData += iChunk; iResidue -= iChunk; if (iResidue == 0) { // received all, send data to handler iType = REQTYPE_GET_TYPE(Setup.bmRequestType); pbData = apbDataStore[iType]; if (!_HandleRequest(&Setup, &iLen, &pbData)) { DBG("_HandleRequest2 failed\n"); StallControlPipe(bEPStat); return; } // send status to host DataIn(); } } else { // absorb zero-length status message iChunk = USBHwEPRead(0x00, NULL, 0); DBG(iChunk > 0 ? "?" : ""); } } } else if (bEP == 0x80) { // IN transfer // send more data if available (possibly a 0-length packet) DataIn(); } else { ASSERT(FALSE); } }
/************************************************************************* USBHandleControlTransfer ======================== Handles IN/OUT transfers on EP0 **************************************************************************/ void USBHandleControlTransfer(U8 bEP, U8 bEPStat) { int iChunk; if (bEP == 0x00) { // OUT transfer if (bEPStat & EP_STATUS_SETUP) { // setup packet, reset request message state machine USBHwEPRead(0x00, (U8 *)&Setup, &iLen); //mmmm DBG("S%x", Setup.bRequest); // defaults for data pointer and residue pbData = abControlData; iResidue = Setup.wLength; iLen = Setup.wLength; // ask installed handler to pre process request if (!_PreHandleRequest(&Setup, &iLen, &pbData)) { // silently ignore non installed handler } if ((Setup.wLength == 0) || (REQTYPE_GET_DIR(Setup.bmRequestType) == REQTYPE_DIR_TO_HOST)) { // ask installed handler to process request if (!_HandleRequest(&Setup, &iLen, &pbData)) { DBG("_HandleRequest1 failed\n"); StallControlPipe(bEPStat); return; } // send smallest of requested and offered length iResidue = MIN(iLen, Setup.wLength); // send first part (possibly a zero-length status message) DataIn(); } if ((Setup.wLength != 0) && (REQTYPE_GET_DIR(Setup.bmRequestType) == REQTYPE_DIR_TO_DEVICE)) { if (!_PreHandleRequest(&Setup, &iLen, &pbData)) { // this is not a must, might fail } } } else { if (iResidue > 0) { // store data iChunk = 0; USBHwEPRead(0x00, pbData, &iChunk); pbData += iChunk; iResidue -= iChunk; if (iResidue == 0) { // received all, send data to handler // TODO set pointer correctly pbData = abControlData; if (!_HandleRequest(&Setup, &iLen, &pbData)) { StallControlPipe(bEPStat); DBG("_HandleRequest2 failed\n"); return; } // send status to host DataIn(); } } else { // absorb zero-length status message USBHwEPRead(0x00, NULL, &iChunk); DBG(iChunk > 0 ? "?" : ""); } } } else if (bEP == 0x80) { // IN transfer // send more data if available (possibly a 0-length packet) DataIn(); } else { ASSERT(FALSE); } }