示例#1
0
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;
}
示例#3
0
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
            {
示例#4
0
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;
}