/* * This routine is used to notify the framework the result of * an asynchronous request handled by a provider. Valid error * codes are the same as the CRYPTO_* errors defined in common.h. * * This routine can be called from user or interrupt context. */ void crypto_op_notification(crypto_req_handle_t handle, int error) { kcf_call_type_t ctype; if (handle == NULL) return; if ((ctype = GET_REQ_TYPE(handle)) == CRYPTO_SYNCH) { kcf_sreq_node_t *sreq = (kcf_sreq_node_t *)handle; if (error != CRYPTO_SUCCESS) sreq->sn_provider->pd_sched_info.ks_nfails++; KCF_PROV_IREFRELE(sreq->sn_provider); kcf_sop_done(sreq, error); } else { kcf_areq_node_t *areq = (kcf_areq_node_t *)handle; ASSERT(ctype == CRYPTO_ASYNCH); if (error != CRYPTO_SUCCESS) areq->an_provider->pd_sched_info.ks_nfails++; KCF_PROV_IREFRELE(areq->an_provider); kcf_aop_done(areq, error); } }
void process_setup_req() { u32_t* p; u32_t request_type; // DEBUG_OUT('s'); bRequestError = NO; uCurrentCtrlBlockNum = 0; uNeedDoProcCtrlBlockNum = 0; uControlStage = SETUP_STAGE; // clear previous buffer /* writew( readw( UDC_TX0CON ) | TxCLR, UDC_TX0CON ); writew( readw( UDC_TX0CON ) & ~TxCLR, UDC_TX0CON ); writew( readw( UDC_RX0CON ) | RxCLR, UDC_RX0CON ); writew( readw( UDC_RX0CON ) & ~RxCLR, UDC_RX0CON ); */ // read setup data p = (u32_t*)&SetupRequestData; *p++ = *(volatile u32_t *)UDC_SETUP1; *p = *(volatile u32_t *)UDC_SETUP2; // identify standard request request_type = GET_REQ_TYPE(SetupRequestData.bmRequestType); if (request_type == REQ_TYPE_STANDARD) { if (SetupRequestData.bRequest == GET_DESCRIPTOR ) { fn_get_descriptor(); } } else if (request_type == REQ_TYPE_CLASS ) { if (SetupRequestData.bRequest == GET_DEVICE_ID) { ;//printf("process_setup_req() - get device id!\n"); fn_get_device_id(); } } else if (request_type == REQ_TYPE_VENDOR ) { if (SetupRequestData.bRequest == VENDOR_TEST_OUT0 ) { ;//printf("process_setup_req() - vendor test out!\n"); fn_vendor_test_out0(); } else if ( SetupRequestData.bRequest == VENDOR_TEST_IN0 ) { ;//printf("process_setup_req() - vendor test in!\n"); fn_vendor_test_in0(); } } uControlStage = DATA_STAGE ; }
/* * This routine is called by the taskq associated with * each hardware provider. We notify the kernel consumer * via the callback routine in case of CRYPTO_SUCCESS or * a failure. * * A request can be of type kcf_areq_node_t or of type * kcf_sreq_node_t. */ static void process_req_hwp(void *ireq) { int error = 0; crypto_ctx_t *ctx; kcf_call_type_t ctype; kcf_provider_desc_t *pd; kcf_areq_node_t *areq = (kcf_areq_node_t *)ireq; kcf_sreq_node_t *sreq = (kcf_sreq_node_t *)ireq; pd = ((ctype = GET_REQ_TYPE(ireq)) == CRYPTO_SYNCH) ? sreq->sn_provider : areq->an_provider; /* * Wait if flow control is in effect for the provider. A * CRYPTO_PROVIDER_READY or CRYPTO_PROVIDER_FAILED * notification will signal us. We also get signaled if * the provider is unregistering. */ if (pd->pd_state == KCF_PROV_BUSY) { mutex_enter(&pd->pd_lock); while (pd->pd_state == KCF_PROV_BUSY) cv_wait(&pd->pd_resume_cv, &pd->pd_lock); mutex_exit(&pd->pd_lock); } /* * Bump the internal reference count while the request is being * processed. This is how we know when it's safe to unregister * a provider. This step must precede the pd_state check below. */ KCF_PROV_IREFHOLD(pd); /* * Fail the request if the provider has failed. We return a * recoverable error and the notified clients attempt any * recovery. For async clients this is done in kcf_aop_done() * and for sync clients it is done in the k-api routines. */ if (pd->pd_state >= KCF_PROV_FAILED) { error = CRYPTO_DEVICE_ERROR; goto bail; } if (ctype == CRYPTO_SYNCH) { mutex_enter(&sreq->sn_lock); sreq->sn_state = REQ_INPROGRESS; mutex_exit(&sreq->sn_lock); ctx = sreq->sn_context ? &sreq->sn_context->kc_glbl_ctx : NULL; error = common_submit_request(sreq->sn_provider, ctx, sreq->sn_params, sreq); } else { kcf_context_t *ictx; ASSERT(ctype == CRYPTO_ASYNCH); /* * We are in the per-hardware provider thread context and * hence can sleep. Note that the caller would have done * a taskq_dispatch(..., TQ_NOSLEEP) and would have returned. */ ctx = (ictx = areq->an_context) ? &ictx->kc_glbl_ctx : NULL; mutex_enter(&areq->an_lock); /* * We need to maintain ordering for multi-part requests. * an_is_my_turn is set to B_TRUE initially for a request * when it is enqueued and there are no other requests * for that context. It is set later from kcf_aop_done() when * the request before us in the chain of requests for the * context completes. We get signaled at that point. */ if (ictx != NULL) { ASSERT(ictx->kc_prov_desc == areq->an_provider); while (areq->an_is_my_turn == B_FALSE) { cv_wait(&areq->an_turn_cv, &areq->an_lock); } } areq->an_state = REQ_INPROGRESS; mutex_exit(&areq->an_lock); error = common_submit_request(areq->an_provider, ctx, &areq->an_params, areq); } bail: if (error == CRYPTO_QUEUED) { /* * The request is queued by the provider and we should * get a crypto_op_notification() from the provider later. * We notify the consumer at that time. */ return; } else { /* CRYPTO_SUCCESS or other failure */ KCF_PROV_IREFRELE(pd); if (ctype == CRYPTO_SYNCH) kcf_sop_done(sreq, error); else kcf_aop_done(areq, error); } }
void process_setup_req() { u32_t* p; u32_t request_type; UINT ch; // channel number int i; // DEBUG_OUT('s'); bRequestError = NO; uCurrentCtrlBlockNum = 0; uNeedDoProcCtrlBlockNum = 0; uControlStage = SETUP_STAGE; if (ResetFlag == 1) { if ( IS_HIGH_SPEED() ) { ;//printf(" USB connect with HIGH Speed!\n"); bIsFullSpeed = 0; uBulkBlockSize = HI_SPEED_BULK_PACKET_SIZE; uCurrentCtrlPacketSize = HI_SPEED_CTRL_PACKET_SIZE; uCurrentBulklPacketSize = HI_SPEED_BULK_PACKET_SIZE; } else { ;//printf(" USB connect with FULL Speed!\n"); bIsFullSpeed = 1; uBulkBlockSize = FULL_SPEED_BULK_PACKET_SIZE; uCurrentCtrlPacketSize = FULL_SPEED_CTRL_PACKET_SIZE; uCurrentBulklPacketSize = FULL_SPEED_BULK_PACKET_SIZE; } uMaxBlockNumber = (BK_BUF_SIZE / uBulkBlockSize); // change device MaxPacketSize of descriptor scusbDscr[7] = uCurrentCtrlPacketSize; ResetFlag = 0; for (ch = 0; ch < NUM_OF_USB_CHANNEL; ch++) { ChannelSet[ch].uLoopbackCount = 0; ChannelSet[ch].uIntrINCount = 0; // start receive from Bulk_OUT pipe writew(virt_to_phy( (u32_t)ChannelSet[ch].pBulkOutBuffer), UDC_DMALM_OADDR(ChannelSet[ch].uBulk_OUT)); writew( ENP_DMA_START, UDC_DMACTRLO(ChannelSet[ch].uBulk_OUT)); } for (i = 0; i < NUM_OF_USB_CHANNEL; i++) ChannelSet[i].uCurrentBulkInBlockNum = ChannelSet[i].uCurrentBulkOutBlockNum = ChannelSet[i].uCurrentIntrInBlockNum = 0; } // clear previous buffer /* writew( readw( UDC_TX0CON ) | TxCLR, UDC_TX0CON ); writew( readw( UDC_TX0CON ) & ~TxCLR, UDC_TX0CON ); writew( readw( UDC_RX0CON ) | RxCLR, UDC_RX0CON ); writew( readw( UDC_RX0CON ) & ~RxCLR, UDC_RX0CON ); */ // read setup data p = (u32_t*)&SetupRequestData; *p++ = *(volatile u32_t *)UDC_SETUP1; *p = *(volatile u32_t *)UDC_SETUP2; // identify standard request request_type = GET_REQ_TYPE(SetupRequestData.bmRequestType); if (request_type == REQ_TYPE_STANDARD) { if (SetupRequestData.bRequest == GET_DESCRIPTOR ) { fn_get_descriptor(); } } else if (request_type == REQ_TYPE_CLASS ) { if (SetupRequestData.bRequest == GET_DEVICE_ID) { ;//printf("process_setup_req() - get device id!\n"); fn_get_device_id(); } } else if (request_type == REQ_TYPE_VENDOR ) { if (SetupRequestData.bRequest == VENDOR_TEST_OUT0 ) { ;//printf("process_setup_req() - vendor test out!\n"); fn_vendor_test_out0(); } else if ( SetupRequestData.bRequest == VENDOR_TEST_IN0 ) { ;//printf("process_setup_req() - vendor test in!\n"); fn_vendor_test_in0(); } } uControlStage = DATA_STAGE ; }