static void usbc_core_handle_set_address() { usbc_core_t* pUsbCore = usbc_core_get_instance(); kal_uint16 wValue = pUsbCore->setup_packet.wValue; usbc_core_printf("=========>usbcore_handle_set_address\r\n"); usbc_trace_info(USBCORE_SET_ADDRESS, (wValue & 0x7f)); usbc_core_set_usb_address(wValue & 0x7f); usbc_core_set_control_request(NULL, 0, USBC_CONTROL_REQUEST_TYPE_RECEIVE); }
static kal_bool usbc_class_device_submit_io_request_priv(hif_queue_type_e core_queue_hif_type, usbc_core_queue_t *pQueue, usbc_io_request_t *io_request) { usbc_io_request_t *current_request = io_request; usbc_io_request_t *next_request; qbm_gpd *first_gpd = NULL; qbm_gpd *last_gpd = NULL; qbm_gpd *current_gpd = NULL; while ( current_request != NULL ) { next_request = current_request->next_request; first_gpd = current_request->first_gpd; last_gpd = current_request->last_gpd; current_gpd = first_gpd; /* try to traverse gpd list if last_gpd is not filled */ if (last_gpd == NULL) { while ( current_gpd->p_next != NULL ) { current_gpd = current_gpd->p_next; } last_gpd = current_gpd; } #ifdef __USBCORE_DEBUG__ usbc_core_printf("[USBCORE] submit type %d queue no %d first gpd %x last gpd %x\r\n", core_queue_hif_type, HIFUSB_EPNO_2_QNO(pQueue->ep_no), first_gpd, last_gpd); //usbc_core_dump_gpd_list(first_gpd, last_gpd); #endif usbc_core_set_usbhifq_gpd(core_queue_hif_type, HIFUSB_EPNO_2_QNO(pQueue->ep_no), first_gpd, last_gpd); current_request = next_request; } return KAL_TRUE; }
static void usbc_core_handle_set_feature() { usbc_core_t* pUsbCore = usbc_core_get_instance(); usbc_control_request_type_e type = USBC_CONTROL_REQUEST_TYPE_STALL; kal_uint8 bRecip = pUsbCore->setup_packet.bmRequestType & USBC_REQUEST_RECIP_MASK; kal_uint16 wIndex = pUsbCore->setup_packet.wIndex; kal_uint16 wValue = pUsbCore->setup_packet.wValue; kal_bool is_tx = KAL_TRUE; usbc_core_printf("=========>usbcore_handle_set_feature\r\n"); usbc_trace_info(USBCORE_SET_FEATURE, bRecip, wIndex, wValue); if ( bRecip == USBC_REQUEST_RECIP_DEVICE ) { usbc_ind_t ind_to_enqueue; usbc_func_state_e state; kal_uint8 i; if ( pUsbCore->speed == USBC_USB_SPEED_USB30 ) { if ( pUsbCore->state <= USBC_USB_STATE_ATTACHING ) { type = USBC_CONTROL_REQUEST_TYPE_STALL; } else if ( wValue == USBC_FEATURE_U1_ENABLE ) { pUsbCore->is_device_u1_enable = KAL_TRUE; usbc_core_set_ss_dev_init_u1_en(KAL_TRUE); type = USBC_CONTROL_REQUEST_TYPE_RECEIVE; } else if ( wValue == USBC_FEATURE_U2_ENABLE ) { pUsbCore->is_device_u2_enable = KAL_TRUE; usbc_core_set_ss_dev_init_u2_en(KAL_TRUE); type = USBC_CONTROL_REQUEST_TYPE_RECEIVE; } else if ( wValue == USBC_FEATURE_LTM_ENABLE ) { pUsbCore->is_device_ltm_enable = KAL_TRUE; // TODO: set LTM enabled if support type = USBC_CONTROL_REQUEST_TYPE_RECEIVE; } #if _USB30_DEVICE_REMOTE_WK_SUPPORT_ else if ( wValue == USBC_FEATURE_DEVICE_REMOTE_WAKEUP ) { // enable function remote wakeup for capable functions in enabling device remote wakeup state = USBC_FUNC_WK_ENABLE; for( i=0; i<pUsbCore->total_class_devices; i++) { if ( NULL != pUsbCore->class_device[i].query_func_wk_status && pUsbCore->class_device[i].query_func_wk_status(i) & ((kal_uint8)0x01) ) { ind_to_enqueue.type = USBC_IND_FUNC_EVENT; ind_to_enqueue.ext = i; ind_to_enqueue.data = (kal_uint8)state; usbc_enqueue_ind(&ind_to_enqueue); } } hmu_hifeg_set(HIF_DRV_EG_USBC_IND_EVENT); type = USBC_CONTROL_REQUEST_TYPE_RECEIVE; } #endif else { type = USBC_CONTROL_REQUEST_TYPE_STALL; } } else { if ( wValue == USBC_FEATURE_DEVICE_REMOTE_WAKEUP ) { // enable function remote wakeup for capable functions in enabling device remote wakeup state = USBC_FUNC_WK_ENABLE; for( i=0; i<pUsbCore->total_class_devices; i++) { if ( NULL != pUsbCore->class_device[i].query_func_wk_status && pUsbCore->class_device[i].query_func_wk_status(i) & ((kal_uint8)0x01) ) { ind_to_enqueue.type = USBC_IND_FUNC_EVENT; ind_to_enqueue.ext = i; ind_to_enqueue.data = (kal_uint8)state; usbc_enqueue_ind(&ind_to_enqueue); } } hmu_hifeg_set(HIF_DRV_EG_USBC_IND_EVENT); type = USBC_CONTROL_REQUEST_TYPE_RECEIVE; } else if ( wValue == USBC_FEATURE_TEST_MODE ) { usbc_core_set_usb_testmode((hifusb_test_mode_e)(wIndex >> 8)); type = USBC_CONTROL_REQUEST_TYPE_RECEIVE; } else {
static void usbc_core_handle_get_status() { usbc_core_t* pUsbCore = usbc_core_get_instance(); usbc_control_request_type_e type = USBC_CONTROL_REQUEST_TYPE_STALL; kal_uint8 bRecip = pUsbCore->setup_packet.bmRequestType & USBC_REQUEST_RECIP_MASK; //kal_uint16 wIndex = pUsbCore->setup_packet.wIndex; kal_uint8* pBuffer = pUsbCore->control_request_buffer; kal_uint32 length = 0; usbc_core_printf("=========>usbcore_handle_get_status\r\n"); usbc_trace_info(USBCORE_GET_STATUS, bRecip); if ( bRecip == USBC_REQUEST_RECIP_DEVICE ) { kal_uint8 i; /* D0: Self Powered, D1: Remote Wakeup */ pBuffer[0] = 0; //Bus Power pBuffer[1] = 0; //No Remote Wakeup length = 2; type = USBC_CONTROL_REQUEST_TYPE_SEND; // report remote wakeup status in USB 1.1 and USB 2.0 (0 in USB 3.0) if( pUsbCore->speed != USBC_USB_SPEED_USB30 ) { for( i=0; i<pUsbCore->total_class_devices; i++) { if ( NULL != pUsbCore->class_device[i].query_func_wk_status && pUsbCore->class_device[i].query_func_wk_status(i) & 0x0002 ) { pBuffer[0] |= ((kal_uint8)0x01 << 1); break; } } } else { // USB 3.0 U1 enable status (0 in USB 2.0) if ( pUsbCore->is_device_u1_enable ) { pBuffer[0] |= ((kal_uint8)0x01 << 2); } // USB 3.0 U2 enable status ( 0 in USB 3.0) if( pUsbCore->is_device_u2_enable ) { pBuffer[0] |= ((kal_uint8)0x01 << 3); } // USB 3.0 LTM enable status ( 0 in USB 3.0) if( pUsbCore->is_device_ltm_enable ) { pBuffer[0] |= ((kal_uint8)0x01 << 4); } } } else if ( bRecip == USBC_REQUEST_RECIP_INTERFACE ) { kal_uint8 nInterface = (kal_uint8)pUsbCore->setup_packet.wIndex; kal_uint8 class_device_id = pUsbCore->class_interface[nInterface].class_device_id; /* return two bytes of 0x00, 0x00. Both bytes are reserved for future use */ pBuffer[0] = 0; pBuffer[1] = 0; length = 2; type = USBC_CONTROL_REQUEST_TYPE_SEND; if ( pUsbCore->speed == USBC_USB_SPEED_USB30 && usbc_core_is_1st_interface(nInterface) && NULL != pUsbCore->class_device[class_device_id].query_func_wk_status ) { /* if the requested interface is the first one of a function, report the function remote wakeup capability and state */ pBuffer[0] = pUsbCore->class_device[class_device_id].query_func_wk_status(class_device_id) & ((kal_uint8)0xFF); } } else if ( bRecip == USBC_REQUEST_RECIP_ENDPOINT ) { /* D0: HALT, D1: Reserve */ kal_uint8 nEnd = pUsbCore->setup_packet.wIndex & USBC_EP_ADDR_NUM_MASK; /* TODO: It's error-prone to use en_no instead of endpoint address. */ usbc_core_queue_t* pQueue = NULL; kal_uint8 i = 0; if ( (pUsbCore->setup_packet.wIndex & USBC_EP_ADDR_DIR_IN) ) { for ( i=0; i<MAX_USBCORE_QUEUE_NUM; i++ ) { if ( (pUsbCore->tx_queue[i].ep_no == nEnd) && (pUsbCore->tx_queue[i].state > USBC_CORE_QUEUE_STATE_INITIATED) ) { pQueue = &pUsbCore->tx_queue[i]; break; } } } else { for ( i=0; i<MAX_USBCORE_QUEUE_NUM; i++ ) { if ( (pUsbCore->rx_queue[i].ep_no == nEnd) && (pUsbCore->rx_queue[i].state > USBC_CORE_QUEUE_STATE_INITIATED) ) { pQueue = &pUsbCore->rx_queue[i]; break; } } } /* D0: HALT, D1: Reserve */ if ( pQueue == NULL ) { length = 0; type = USBC_CONTROL_REQUEST_TYPE_STALL; if( nEnd == 0) { pBuffer[0] = 0; pBuffer[1] = 0; length = 2; type = USBC_CONTROL_REQUEST_TYPE_SEND; } } else { switch (pQueue->state) { case USBC_CORE_QUEUE_STATE_ACTIVE: { pBuffer[0] = 0; pBuffer[1] = 0; length = 2; type = USBC_CONTROL_REQUEST_TYPE_SEND; break; } case USBC_CORE_QUEUE_STATE_STALL: { pBuffer[0] = 1; pBuffer[1] = 0; length = 2; type = USBC_CONTROL_REQUEST_TYPE_SEND; break; } default: { ASSERT(0); length = 0; type = USBC_CONTROL_REQUEST_TYPE_STALL; break; } } } } else { ASSERT(0); type = USBC_CONTROL_REQUEST_TYPE_STALL; } usbc_core_set_control_request(pBuffer, length, type); }
kal_bool usbc_class_device_flush_io_request( kal_uint8 class_device_id, kal_uint8 queue_no) { usbc_core_queue_t* pQueue = NULL; hif_queue_type_e core_queue_hif_type; hif_flush_type_e core_queue_flush_type; qbm_gpd* first_gpd = NULL; qbm_gpd* last_gpd = NULL; kal_uint32 num = 0; USBC_NON_EXCEPTION_MODE_CHECK(); USBC_CLASS_DEVICE_CONTEXT_CHECK(); if (!usbc_core_get_queue_info(class_device_id, queue_no, &pQueue, &core_queue_hif_type)) { return KAL_FALSE; } if ( pQueue->notify_complete == NULL ) { core_queue_flush_type = HIFQ_FLUSH_FREE; } else { core_queue_flush_type = HIFQ_FLUSH_DEQ; } // Flush GPDs that are buffered in DRAM, and give GPDs back to uppoer layers num = hifusbq_pwrsave_flush_gpd(core_queue_hif_type, HIFUSB_EPNO_2_QNO(pQueue->ep_no), core_queue_flush_type, (void**)&first_gpd, (void**)&last_gpd); if ( num != 0 ) { #ifdef __USBCORE_DEBUG__ usbc_core_printf("[USBCORE] flush type %d queue no %d first gpd %x last gpd %x\r\n", core_queue_hif_type, HIFUSB_EPNO_2_QNO(pQueue->ep_no), first_gpd, last_gpd); //usbc_core_dump_gpd_list(first_gpd, last_gpd); #endif if ( pQueue->notify_complete != NULL ) { if ( first_gpd == NULL ) { /* just indicate a notification */ usbc_data_trace(USBCORE_CLASS_FLUSH_SW_QUEUE, queue_no, num, 0x00, 0x00); pQueue->notify_complete(pQueue->class_device_id, NULL); } else { usbc_io_request_t* request = NULL; usbc_data_trace(USBCORE_CLASS_FLUSH_SW_QUEUE, queue_no, num, first_gpd, last_gpd); request = (usbc_io_request_t*)QBM_DES_GET_SW_CTRL_FIELD(first_gpd); request->next_request = NULL; request->first_gpd = first_gpd; request->last_gpd = last_gpd; pQueue->notify_complete(pQueue->class_device_id, request); } } } // Flush GPDs that are configured in hardware, and give GPDs back to uppoer layers num = hifusbq_flush_gpd(core_queue_hif_type, HIFUSB_EPNO_2_QNO(pQueue->ep_no), core_queue_flush_type, (void**)&first_gpd, (void**)&last_gpd); if ( num != 0 ) { #ifdef __USBCORE_DEBUG__ usbc_core_printf("[USBCORE] flush type %d queue no %d first gpd %x last gpd %x\r\n", core_queue_hif_type, HIFUSB_EPNO_2_QNO(pQueue->ep_no), first_gpd, last_gpd); //usbc_core_dump_gpd_list(first_gpd, last_gpd); #endif if ( pQueue->notify_complete != NULL ) { if ( first_gpd == NULL ) { /* just indicate a notification */ usbc_data_trace(USBCORE_CLASS_FLUSH_HW_QUEUE, queue_no, num, 0x00, 0x00); pQueue->notify_complete(pQueue->class_device_id, NULL); } else { usbc_io_request_t* request = NULL; usbc_data_trace(USBCORE_CLASS_FLUSH_HW_QUEUE, queue_no, num, first_gpd, last_gpd); request = (usbc_io_request_t*)QBM_DES_GET_SW_CTRL_FIELD(first_gpd); request->next_request = NULL; request->first_gpd = first_gpd; request->last_gpd = last_gpd; pQueue->notify_complete(pQueue->class_device_id, request); } } } return KAL_TRUE; }