示例#1
0
static void usb_class_audio_send_callback
(
/* [IN] Unused */
void* tr_ptr,
/* [IN] Pointer to the class interface instance */
void* param,
/* [IN] Data buffer */
uint8_t * buffer,
/* [IN] Length of buffer */
uint32_t len,
/* [IN] Error code (if any) */
usb_status status
)
{ /* Body */
    audio_stream_struct_t* audio_class = (audio_stream_struct_t*)param;
    usb_status usbstatus;

    usbstatus = usb_host_release_tr(audio_class->host_handle, (tr_struct_t*)tr_ptr);
    if (usbstatus != USB_OK)
    {
        USB_PRINTF("_usb_host_release_tr failed:%x\n",(unsigned int)usbstatus);
    }

    if (audio_class->send_callback)
    {
        audio_class->send_callback(NULL, audio_class->send_param, buffer, len, status);
    }

} /* Endbody */
示例#2
0
/*FUNCTION*----------------------------------------------------------------
*
* Function Name  : usb_class_video_cntrl_callback
* Returned Value : USB_OK if command has been passed on USB.
* Comments       :
*     This is the callback used when HID information is sent or received
*
*END*--------------------------------------------------------------------*/
static void usb_class_video_cntrl_callback
(
    /* [IN] Unused */
    void*     tr_ptr,
    /* [IN] Pointer to the class interface instance */
    void*     param,
    /* [IN] Data buffer */
    uint8_t *   buffer,
    /* [IN] Length of buffer */
    uint32_t     len,
    /* [IN] Error code (if any) */
    usb_status  status
)
{ /* Body */
    usb_video_control_struct_t*      video_control = (usb_video_control_struct_t*)param;

    if (usb_host_release_tr(video_control->host_handle, tr_ptr) != USB_OK)
    {
#ifdef _DEBUG
        USB_PRINTF("_usb_host_release_tr failed\n");
#endif
    }
    
    video_control->in_setup = FALSE; 
    if (video_control->ctrl_callback)
    {
        video_control->ctrl_callback(NULL, video_control->ctrl_param, buffer, len, status);
    }
} /* Endbody */
示例#3
0
static void usb_class_audio_control_recv_callback
(
/* [IN] Unused */
void* tr_ptr,
/* [IN] void*  to the class interface instance */
void* param,
/* [IN] Data buffer */
uint8_t * buffer,
/* [IN] Length of buffer */
uint32_t len,
/* [IN] Error code (if any) */
usb_status status
)
{ /* Body */
    audio_control_struct_t* audio_class = (audio_control_struct_t*)param;

    if (usb_host_release_tr(audio_class->host_handle, (tr_struct_t*)tr_ptr) != USB_OK)
    {
        USB_PRINTF("_usb_host_release_tr failed\n");
    }

    if (audio_class->interrupt_callback)
    {
        audio_class->interrupt_callback(NULL, audio_class->interrupt_callback_param, buffer, len, status);
    }

} /* Endbody */
示例#4
0
/*FUNCTION*----------------------------------------------------------------
*
* Function Name  : usb_class_hub_cntrl_callback
* Returned Value : USB_OK if command has been passed on USB.
* Comments       :
*     This is the callback used when hub information is sent or received
*
*END*--------------------------------------------------------------------*/
void usb_class_hub_int_callback
   (
      /* [IN] Unused */
      void*     tr_ptr,
      /* [IN] Pointer to the class interface instance */
      void*     param,
      /* [IN] Data buffer */
      uint8_t *   buffer,
      /* [IN] Length of buffer */
      uint32_t     len,
      /* [IN] Error code (if any) */
      usb_status  status
   )
{
    usb_hub_class_struct_t*      hub_class = (usb_hub_class_struct_t*)param;

    //USB_PRINTF("hub int\n");
    if (usb_host_release_tr(hub_class->host_handle, tr_ptr) != USB_OK)
    {
        USB_PRINTF("_usb_host_release_tr failed\n");
    }
    hub_class->in_interrupt = FALSE;
    
    if (hub_class->interrupt_callback)
    {
        hub_class->interrupt_callback(NULL, hub_class->interrupt_param, buffer, len, status);
    }
}
示例#5
0
usb_status usb_class_audio_send_data
(
/* [IN] audio control class interface pointer  */
audio_command_t* audio_ptr,

/* [IN] buffer pointer */
uint8_t * buffer,

/* [IN] data length */
uint32_t buf_size
)
{ /* Body */

    audio_stream_struct_t* audio_class;
    usb_status status = USBERR_ERROR;
    //uint16_t request_value;
    tr_struct_t* tr_ptr;
    //usb_audio_command_t* p_endpoint_command;

    if ((audio_ptr == NULL) || (audio_ptr->class_stream_handle == NULL))
    {
        USB_PRINTF("input parameter error\n");
        return USBERR_ERROR;
    }

    audio_class = (audio_stream_struct_t*)audio_ptr->class_stream_handle;
    if ((audio_class == NULL) || (buffer == NULL))
    {
        USB_PRINTF("get audio class parameter error\n");
        return USBERR_ERROR;
    }

    audio_class->send_callback = audio_ptr->callback_fn;
    audio_class->send_param = audio_ptr->callback_param;

    if (audio_class->dev_handle == NULL)
    {
        USB_PRINTF("get audio class dev handle error\n");
        return USBERR_ERROR;
    }
    if (usb_host_get_tr(audio_class->host_handle, usb_class_audio_send_callback, audio_class, &tr_ptr) != USB_OK)
    {
        USB_PRINTF("error to get tr\n");
        return USBERR_ERROR;
    }

    tr_ptr->tx_buffer = buffer;
    tr_ptr->tx_length = buf_size;
    status = usb_host_send_data(audio_class->host_handle, audio_class->iso_out_pipe, tr_ptr);
    if (status != USB_OK)
    {
        USB_PRINTF("\nError in _usb_host_send_data: %x", (unsigned int)status);
        usb_host_release_tr(audio_class->host_handle, tr_ptr);
        return USBERR_ERROR;
    }

    return USB_OK;

} /* Endbody */
示例#6
0
/*FUNCTION*----------------------------------------------------------------
*
* Function Name  : usb_class_video_control_recv_data
* Returned Value : USB_OK if command has been passed on USB.
* Comments       :
*     This function is used to recv interrupt data
*
*END*--------------------------------------------------------------------*/
usb_status usb_class_video_control_recv_data
(
    /* [IN] Class Interface structure pointer */
    video_command_t*         com_ptr,
    /* [IN] The buffer address */
    uint8_t *               buffer,
    /* [IN] The buffer address */
    uint16_t                length
)
{
    usb_video_control_struct_t*  video_control_ptr;
    tr_struct_t*             tr_ptr;
    usb_status                status;

    if ((com_ptr == NULL) || (com_ptr->class_control_handle == NULL))
    {
        return USBERR_ERROR;
    }

    video_control_ptr = (usb_video_control_struct_t*)com_ptr->class_control_handle;
    
    if ((video_control_ptr == NULL) || (buffer == NULL))
    {
#ifdef _DEBUG
        USB_PRINTF("input parameter error\n");
#endif
        return USBERR_ERROR;
    }

    video_control_ptr->recv_callback = com_ptr->callback_fn;
    video_control_ptr->recv_param = com_ptr->callback_param;

    if (video_control_ptr->dev_handle == NULL)
    {
        return USBERR_ERROR;
    }

    if (usb_host_get_tr(video_control_ptr->host_handle, usb_class_video_control_recv_callback, video_control_ptr, &tr_ptr) != USB_OK)
    {
#ifdef _DEBUG
        USB_PRINTF("error to get tr\n");
#endif
        return USBERR_ERROR;
    }
    
    tr_ptr->rx_buffer = buffer;
    tr_ptr->rx_length = length;
    status = usb_host_recv_data(video_control_ptr->host_handle, video_control_ptr->control_interrupt_in_pipe, tr_ptr);
    if (status != USB_OK)
    {
#ifdef _DEBUG
        USB_PRINTF("\nError in usb_class_video_recv_data: %x", status);
#endif
        usb_host_release_tr(video_control_ptr->host_handle, tr_ptr);
        return USBERR_ERROR;
    }
    return USB_OK;
}
示例#7
0
usb_status usb_class_cdc_init_ipipe
    (
        /* ACM interface instance */
        cdc_class_call_struct_t *      acm_instance
    )
{ /* Body */
    usb_status                     status = USBERR_NO_INTERFACE;
    usb_acm_class_intf_struct_t *  if_acm_ptr;
    tr_struct_t*                  tr_ptr;
    #ifdef _HOST_DEBUG_
        DEBUG_LOG_TRACE("usb_class_cdc_init_ipipe");
    #endif

    /* Validity checking, always needed when passing data to lower API */
    if (usb_class_cdc_intf_validate(acm_instance)) {
        if_acm_ptr = (usb_acm_class_intf_struct_t *) acm_instance->class_intf_handle;
        USB_CDC_ACM_lock();
        if (if_acm_ptr->interrupt_pipe != NULL) {
        
            if (usb_host_get_tr(if_acm_ptr->host_handle, usb_class_cdc_int_acm_callback, if_acm_ptr, &tr_ptr) != USB_OK)
            {
                printf("usb_class_cdc_init_ipipe: error to get tr\n");
                return USBERR_ERROR;
            }
            
            tr_ptr->rx_buffer = (uint8_t *) &if_acm_ptr->interrupt_buffer;
            tr_ptr->rx_length = sizeof(if_acm_ptr->interrupt_buffer);
            status = usb_host_recv_data(if_acm_ptr->host_handle, if_acm_ptr->interrupt_pipe, tr_ptr);
            if (status != USB_OK)
            {
                printf("\nError in usb_class_cdc_init_ipipe: %x", status);
                usb_host_release_tr(if_acm_ptr->host_handle, tr_ptr);
                return USBERR_ERROR;
            }
        }
        else{
            status = USBERR_OPEN_PIPE_FAILED;
        }
        USB_CDC_ACM_unlock();
    }

    #ifdef _HOST_DEBUG_
    if (!status) {
         DEBUG_LOG_TRACE("usb_class_cdc_init_ipipe, SUCCESSFUL");
    }
    else {
         DEBUG_LOG_TRACE("usb_class_cdc_init_ipipe, FAILED");
    }
    #endif
   
    return status;
}
示例#8
0
static void usb_class_cdc_cntrl_callback
   (
      /* [IN] Unused */
      void *     tr_ptr,
      /* [IN] pointer to the class interface instance */
      void *     param,
      /* [IN] Data buffer */
      uint8_t *   buffer,
      /* [IN] Length of buffer */
      uint32_t     len,
      /* [IN] Error code (if any) */
      usb_status  status
   )
{ /* Body */
    usb_data_class_intf_struct_t *      if_ptr;
 
    #ifdef _HOST_DEBUG_
        DEBUG_LOG_TRACE("usb_class_cdc_cntrl_callback");
    #endif
 
    /*
    ** There is no need for USB_lock in the callback function, and there is also no
    ** need to check if the device is still attached (otherwise this callback
    ** would never have been called!
    */
 
    /* Get class interface handle, reset IN_SETUP and call callback */
    if_ptr = (usb_data_class_intf_struct_t *)param;
 
	if (usb_host_release_tr(if_ptr->host_handle, tr_ptr) != USB_OK)
	{
		printf("usb_class_cdc_cntrl_callback: _usb_host_release_tr failed\n");
	}
	
    if (if_ptr->ctrl_callback) {
        if_ptr->ctrl_callback(tr_ptr, if_ptr->ctrl_callback_param, buffer, len, status);
    } /* Endif */
 
    #ifdef _HOST_DEBUG_
        DEBUG_LOG_TRACE("usb_class_cdc_cntrl_callback, SUCCESSFUL");
    #endif
} /* Endbody */
示例#9
0
/*FUNCTION*----------------------------------------------------------------
 *
 * Function Name  : usb_class_audio_cntrl_callback
 * Returned Value : USB_OK if command has been passed on USB.
 * Comments       :
 *     This is the callback used when audio control information is sent or received.
 *
 *END*--------------------------------------------------------------------*/
static void usb_class_audio_cntrl_callback
(
/* [IN] Unused */
void* tr_ptr,
/* [IN] void*  to the class interface instance */
void* param,
/* [IN] Data buffer */
uint8_t * buffer,
/* [IN] Length of buffer */
uint32_t len,
/* [IN] Error code (if any) */
usb_status status
)
{ /* Body */
    usb_status usbstatus;

    audio_control_struct_t* audio_class = (audio_control_struct_t*)param;

#ifdef _HOST_DEBUG_
    DEBUG_LOG_TRACE("usb_class_audio_cntrl_callback");
#endif
    usbstatus = usb_host_release_tr(audio_class->host_handle, (tr_struct_t*)tr_ptr);
    if (usbstatus != USB_OK)
    {
        USB_PRINTF("_usb_host_release_tr failed status:%d \r\n", (unsigned int)usbstatus);
    }

    audio_class->in_setup = FALSE;
    if (audio_class->ctrl_callback)
    {
        audio_class->ctrl_callback(NULL, audio_class->ctrl_param, buffer, len, status);
    }

#ifdef _HOST_DEBUG_
    DEBUG_LOG_TRACE("usb_class_audio_cntrl_callback, SUCCESSFUL");
#endif

} /* Endbody */
示例#10
0
void usb_class_hub_cntrl_callback
   (
      /* [IN] Unused */
      void*     tr_ptr,
      /* [IN] Pointer to the class interface instance */
      void*     param,
      /* [IN] Data buffer */
      uint8_t *   buffer,
      /* [IN] Length of buffer */
      uint32_t     len,
      /* [IN] Error code (if any) */
      usb_status  status
   )
{
    usb_hub_class_struct_t* hub_class = (usb_hub_class_struct_t*)param;

    //USB_PRINTF("ctrl c\n");
    #ifdef _HOST_DEBUG_
       DEBUG_LOG_TRACE("usb_class_hub_cntrl_callback");
    #endif

    if (usb_host_release_tr(hub_class->host_handle, tr_ptr) != USB_OK)
    {
        USB_PRINTF("_usb_host_release_tr failed\n");
    }

    hub_class->in_setup = FALSE;
    
    if (hub_class->ctrl_callback)
    {
        hub_class->ctrl_callback(NULL, hub_class->ctrl_param, buffer, len, status);
    }
    #ifdef _HOST_DEBUG_
       DEBUG_LOG_TRACE("usb_class_hub_cntrl_callback, SUCCESSFUL");
    #endif 
}
示例#11
0
static void usb_class_cdc_int_acm_callback
   (
      /* [IN] pointer to pipe */
      void *     tr_ptr,

      /* [IN] user-defined parameter */
      void *           param,

      /* [IN] buffer address */
      uint8_t *           buffer,

      /* [IN] length of data transferred */
      uint32_t           len,

      /* [IN] status, hopefully USB_OK or USB_DONE */
      uint32_t           status
   )
{ /* Body */
    //cdc_class_call_struct_t *	acm_parser;
    tr_struct_t*                  tr_int_ptr;
    usb_acm_class_intf_struct_t *  if_acm_ptr = (usb_acm_class_intf_struct_t *)param;
    
    #ifdef _HOST_DEBUG_
        DEBUG_LOG_TRACE("usb_class_cdc_int_acm_callback");
    #endif
    if(USB_OK == status)
    {
        if (usb_host_release_tr(if_acm_ptr->host_handle, tr_ptr) != USB_OK)
        {
            printf("usb_class_cdc_int_acm_callback: _usb_host_release_tr failed\n");
        }
    }
    else
    {
    	/* In case of error, e.g. KHCI_ATOM_TR_TO, need to re-issue tr for interrupt pipe */
		USB_CDC_ACM_lock();
        if (if_acm_ptr->interrupt_pipe != NULL) {
        
			if (usb_host_get_tr(if_acm_ptr->host_handle, usb_class_cdc_int_acm_callback, if_acm_ptr, &tr_int_ptr) != USB_OK)
			{
				printf("usb_class_cdc_int_acm_callback: error to get tr\n");
			}
			
			tr_int_ptr->rx_buffer = (uint8_t *) &if_acm_ptr->interrupt_buffer;
			tr_int_ptr->rx_length = sizeof(if_acm_ptr->interrupt_buffer);								   
			status = usb_host_recv_data(if_acm_ptr->host_handle, if_acm_ptr->interrupt_pipe, tr_int_ptr);
			if (status != USB_OK)
			{
				printf("\nError in usb_class_cdc_int_acm_callback: %x", status);
				usb_host_release_tr(if_acm_ptr->host_handle, tr_int_ptr);
			}
        }
        else{
            status = USBERR_OPEN_PIPE_FAILED;
		}
		USB_CDC_ACM_unlock();
    }
    /* we do not use USB_ACM_INT_PIPE_FREE in this version at all */
//    _lwevent_set(if_ptr->acm_event, USB_ACM_INT_PIPE_FREE); 

    #ifdef _HOST_DEBUG_
        DEBUG_LOG_TRACE("usb_class_cdc_int_acm_callback, SUCCESSFUL");
    #endif

} /*EndBody */
示例#12
0
/*FUNCTION*----------------------------------------------------------------
*
* Function Name  : usb_class_video_cntrl_common
* Returned Value : USB_OK if command has been passed on USB.
* Comments       :
*     This function is used to send a control request
*
*END*--------------------------------------------------------------------*/
static usb_status usb_class_video_cntrl_common
(
    /* [IN] The communication device common command structure */
    video_command_t*         com_ptr,
    /* [IN] Bitmask of the request type */
    uint8_t                  bmrequesttype,
    /* [IN] Request code */
    uint8_t                  brequest,
    /* [IN] Value to copy into wvalue field of the REQUEST */
    uint16_t                 wvalue,
    /* [IN] Value to copy into windex field of the REQUEST */
    uint16_t                 windex,
    /* [IN] Length of the data associated with REQUEST */
    uint16_t                 wlength,
    /* [IN] Pointer to data buffer used to send/recv */
    uint8_t*                 data
)
{ /* Body */
    usb_video_control_struct_t*         video_control = NULL;
    //usb_setup_t                        req;
    usb_status                       status = USB_OK;
    usb_pipe_handle                 pipe_handle;
    tr_struct_t*                    tr_ptr; 
      
    if ((com_ptr == NULL) || (com_ptr->class_control_handle == NULL))
    {
        return USBERR_ERROR;
    }

    video_control = (usb_video_control_struct_t*)com_ptr->class_control_handle;
    if (video_control->in_setup)
    {
        return USBERR_TRANSFER_IN_PROGRESS;
    }

    if (video_control->dev_handle == NULL)
    {
        #ifdef _HOST_DEBUG_
           DEBUG_LOG_TRACE("_usb_hostdev_cntrl_request, invalid device handle");
        #endif
        return USBERR_DEVICE_NOT_FOUND;
    }
    
    video_control->ctrl_callback = com_ptr->callback_fn;
    video_control->ctrl_param = com_ptr->callback_param;
     
    pipe_handle = usb_host_dev_mng_get_control_pipe(video_control->dev_handle);

    if (usb_host_get_tr(video_control->host_handle, usb_class_video_cntrl_callback, video_control, &tr_ptr) != USB_OK)
    {
#ifdef _DEBUG
        USB_PRINTF("error to get tr video\n");
#endif
        return USBERR_ERROR;
    }

    /* Set TR buffer length as required */
    if ((REQ_TYPE_IN & bmrequesttype) != 0)
    {
        tr_ptr->rx_buffer = data;
        tr_ptr->rx_length = wlength;
    }
    else
    {
        tr_ptr->tx_buffer = data;
        tr_ptr->tx_length = wlength;
    }
 
    tr_ptr->setup_packet.bmrequesttype = bmrequesttype;
    tr_ptr->setup_packet.brequest      = brequest;
    *(uint16_t*)tr_ptr->setup_packet.wvalue = USB_HOST_TO_LE_SHORT(wvalue);
    *(uint16_t*)tr_ptr->setup_packet.windex = USB_HOST_TO_LE_SHORT(windex);
    *(uint16_t*)tr_ptr->setup_packet.wlength = USB_HOST_TO_LE_SHORT(wlength);

    video_control->in_setup = TRUE;
    status = usb_host_send_setup(video_control->host_handle, pipe_handle, tr_ptr);  
    if (status != USB_OK)
    {
#ifdef _DEBUG
        USB_PRINTF("\nError in usb_class_video_cntrl_common: %x", status);
#endif
        video_control->in_setup = FALSE;
        usb_host_release_tr(video_control->host_handle, tr_ptr);
        return USBERR_ERROR;
    }
    return status;
} /* Endbody */
示例#13
0
static usb_status usb_class_cdc_cntrl_common
   (
      /* [IN] The communication device common command structure */
      cdc_command_t *           com_ptr,
      /* [IN] The communication device control interface */
      usb_acm_class_intf_struct_t * if_ctrl_ptr,
      /* [IN] Bitmask of the request type */
      uint8_t                    bmrequesttype,
      /* [IN] Request code */
      uint8_t                    brequest,
      /* [IN] Value to copy into wvalue field of the REQUEST */
      uint16_t                   wvalue,
      /* [IN] Length of the data associated with REQUEST */
      uint16_t                   wlength,
      /* [IN] Pointer to data buffer used to send/recv */
      uint8_t *                 data
   )
{ /* Body */
    usb_data_class_intf_struct_t *        if_ptr;
    //usb_setup_t                        req;
    usb_status                       status = USBERR_NO_INTERFACE;
    usb_pipe_handle                 pipe_handle;
    tr_struct_t*                    tr_ptr;
    #ifdef _HOST_DEBUG_
        DEBUG_LOG_TRACE("usb_class_cdc_cntrl_common");
    #endif
    
    if_ptr = (usb_data_class_intf_struct_t *) com_ptr->CLASS_PTR->class_intf_handle;
    
    /* Save the higher level callback and ID */
    if_ptr->ctrl_callback = com_ptr->CALLBACK_FN;
    if_ptr->ctrl_callback_param = com_ptr->CALLBACK_PARAM;
 
    pipe_handle = (usb_pipe_handle)usb_host_dev_mng_get_control_pipe(if_ptr->dev_handle);
    if (usb_host_get_tr(if_ptr->host_handle, usb_class_cdc_cntrl_callback, if_ptr, &tr_ptr) != USB_OK)
    {
        printf("usb_class_cdc_cntrl_common: error to get tr cdc\n");
        return USBERR_ERROR;
    }
    
    /* Set TR buffer length as required */
    if ((REQ_TYPE_IN & bmrequesttype) != 0)
    {
        tr_ptr->rx_buffer = data;
        tr_ptr->rx_length = wlength;
    }
    else
    {
        tr_ptr->tx_buffer = data;
        tr_ptr->tx_length = wlength;
    }
 
    tr_ptr->setup_packet.bmrequesttype = bmrequesttype;
    tr_ptr->setup_packet.brequest      = brequest;
    *(uint16_t*)tr_ptr->setup_packet.wvalue = USB_HOST_TO_LE_SHORT(wvalue);
    *(uint16_t*)tr_ptr->setup_packet.windex = USB_HOST_TO_LE_SHORT(if_ctrl_ptr->intf_num);
    *(uint16_t*)tr_ptr->setup_packet.wlength = USB_HOST_TO_LE_SHORT(wlength);
    /* Since this function is general, we must distinguish here interface class to perform
    ** appropriate action.
    ** Only ACM devices are supported now.
    */
    switch (((interface_descriptor_t*) if_ctrl_ptr->intf_handle)->bInterfaceSubClass) 
    {
        case USB_SUBCLASS_COM_DIRECT:
            break;
        case USB_SUBCLASS_COM_ABSTRACT:
			if (USB_OK == (status =
			usb_host_send_setup(if_ptr->host_handle, pipe_handle, tr_ptr)))	
			{
				status = USB_OK;
			}
			else
			{
				printf("\nError in usb_class_hid_cntrl_common: %x", status);
				usb_host_release_tr(if_ptr->host_handle, tr_ptr);
				status = USBERR_ERROR;
			}
            break;
        case USB_SUBCLASS_COM_TELEPHONE:
            break;
        case USB_SUBCLASS_COM_MULTICHAN:
            break;
        case USB_SUBCLASS_COM_CAPI:
            break;
        case USB_SUBCLASS_COM_ETHERNET:
            break;
        case USB_SUBCLASS_COM_ATM_NET:
            break;  
    }
 
    #ifdef _HOST_DEBUG_
    if (!status) {
        DEBUG_LOG_TRACE("usb_class_cdc_cntrl_common, SUCCESSFUL");
    }
    else {
        DEBUG_LOG_TRACE("usb_class_cdc_cntrl_common, FAILED");
    }
    #endif
    
    return status;
} /* Endbody */
示例#14
0
/*FUNCTION*----------------------------------------------------------------
* 
* Function Name  : usb_host_cntrl_transaction_done
* Returned Value : none
* Comments       :
*     Callback function to process transaction-done events
*     State machine for enumeration/subsequent transactions
*     Between states, the 8-byte buffer in device_instance
*        is used to save the first part of the configuration.
*     Pointer desc in various flavors (uint8_t *, cfig_ptr)
*        is used to parse this buffer in various ways. 
* 
*END*--------------------------------------------------------------------*/
static void  usb_host_cntrl_transaction_done
(
    /* [IN] Unused */
    void*           tr_ptr,
    /* [IN] The user parameter */
    void*           user_parm,
    /* [IN] the buffer */
    uint8_t *         buffer,
    /* [IN] The length of the transfer */
    uint32_t           length,
    /* [IN] status of the transfer */
    usb_status        status
)
{
    usb_host_state_struct_t*    usb_host_ptr;
    dev_instance_t*             dev_inst_ptr = (dev_instance_t*)user_parm;
    pipe_struct_t*              pipe_ptr = dev_inst_ptr->control_pipe;
    descriptor_union_t          desc;
    int32_t                     config_size = 0;

    uint32_t                   aligned_config_size = 0;
	usb_host_api_functions_struct_t* host_api;
#ifdef USBCFG_OTG
    static bool                otg_hnp_support;
#endif
    usb_host_ptr = (usb_host_state_struct_t*)dev_inst_ptr->host;

	host_api = (usb_host_api_functions_struct_t*)usb_host_ptr->host_controller_api;


    if (usb_host_release_tr(usb_host_ptr, tr_ptr) != USB_OK)
    {
        printf("_usb_host_release_tr failed\n");
    }

    switch (status)
    {
        case USB_OK:
            dev_inst_ptr->ctrl_retries = USBCFG_HOST_CTRL_RETRY;
            dev_inst_ptr->stall_retries = USBCFG_HOST_CTRL_RETRY;
            break;
  
        case USBERR_TR_FAILED:
        case USBERR_ENDPOINT_STALLED:
        
            //printf("TR failed buffer : %x\n\r", buffer);
            dev_inst_ptr->ctrl_retries--;
            dev_inst_ptr->stall_retries--;
            if ((status == USBERR_ENDPOINT_STALLED)&&(dev_inst_ptr->stall_retries))
            {
               printf("USBERR_ENDPOINT_STALLED\n");
               status = _usb_host_ch9_clear_feature((usb_device_instance_handle)dev_inst_ptr, REQ_TYPE_ENDPOINT, 0, ENDPOINT_HALT);
            }
            else if ((dev_inst_ptr->stall_retries == 0) || ((dev_inst_ptr->ctrl_retries)&&(status == USBERR_TR_FAILED)))
            {
                /* if hub level is 1 will do port reset */
				if(dev_inst_ptr->level == 1)
                {
                    host_api = (usb_host_api_functions_struct_t*)usb_host_ptr->host_controller_api;

                    if (host_api->host_bus_control != NULL)
                    {
                        host_api->host_bus_control(usb_host_ptr->controller_handle, 1);
                    }
                    status = _usb_host_ch9_get_descriptor((usb_device_instance_handle)dev_inst_ptr,
                                                              USB_DESC_TYPE_DEV << 8, 0, 8, 
                                                              (uint8_t *)buffer);
                    dev_inst_ptr->state = DEVSTATE_DEVDESC8;
                }
                else  
                {
#if USBCFG_HOST_HUB                   
                    usb_host_hub_Port_Reset(dev_inst_ptr->hub_instance, dev_inst_ptr->port_no);
                    usb_host_dev_mng_detach(dev_inst_ptr->host, dev_inst_ptr->hub_no, dev_inst_ptr->port_no);
#endif
                }
            }

            break;
  
        
        default:
            break;
    }

    if (status != USB_OK)
    {
        return;
    }

    /*----------------------------------------------------**
    ** Enumeration state machine -- cases are named after **
    ** the just-completed transactions.                   **
    **----------------------------------------------------*/

    switch (dev_inst_ptr->state)
    {
        case DEVSTATE_INITIAL:      /* initial device state = forever error state */
            break;   
        case DEVSTATE_DEVDESC8:     /* device descriptor [0..7]*/
            /* We must have received the first 8 bytes in 
                    * dev_inst_ptr->dev_descriptor which contains the 
                    * max packet size for this control endpoint 
                    */
            //printf("dev8\n");
            pipe_ptr->max_packet_size = dev_inst_ptr->dev_descriptor.bMaxPacketSize;
            //printf("DEVSTATE_DEVDESC8 %d\n",dev_inst_ptr->dev_descriptor.bMaxPacketSize);
              
            /* Notify device driver of MaxPacketSize0 for this device */
            status = _usb_host_update_max_packet_size_call_interface (usb_host_ptr, pipe_ptr);
           
            if (status != USB_OK)
            {
                printf("update max packet size error\n");
                usb_host_dev_mng_pre_detach(dev_inst_ptr->host,dev_inst_ptr->hub_no,dev_inst_ptr->port_no);
                break;
            }
            else
            {
                dev_inst_ptr->state = DEVSTATE_ADDR_SET;
            }
  
            /* Now set the address that we assigned when we initialized 
                    * the device instance struct for this device 
                    */
            status = _usb_host_ch9_set_address((usb_device_instance_handle)dev_inst_ptr);
            
            if (status != USB_OK)
            {
                printf("set address error\n");
                usb_host_dev_mng_pre_detach(dev_inst_ptr->host,dev_inst_ptr->hub_no,dev_inst_ptr->port_no);
                break;
            }
   
            break;
       case DEVSTATE_ADDR_SET:     /* address set */
            //pipe_ptr->DEVICE_ADDRESS = dev_inst_ptr->address;
         //   printf("add set %d\n", dev_inst_ptr->target_address);
            dev_inst_ptr->address = dev_inst_ptr->target_address;
            /* Notify device driver of USB device's new address */
            status = _usb_host_update_device_address_call_interface (usb_host_ptr, pipe_ptr);
            
            if (status != USB_OK)
            {
                printf("update device address error\n");
                usb_host_dev_mng_pre_detach(dev_inst_ptr->host,dev_inst_ptr->hub_no,dev_inst_ptr->port_no);
                break;
            }
            dev_inst_ptr->state = DEVSTATE_DEV_DESC;
            //printf("descriptor address 0x%x\n", &dev_inst_ptr->dev_descriptor);
            /* Now get the full descriptor */
            status = _usb_host_ch9_get_descriptor((usb_device_instance_handle)dev_inst_ptr,
                USB_DESC_TYPE_DEV << 8, 
                0, 
                USB_DESC_LEN_DEV,
                (uint8_t *)&dev_inst_ptr->dev_descriptor);
               
            if (status != USB_OK)
            {
                printf("get device descriptor error\n");
                usb_host_dev_mng_pre_detach(dev_inst_ptr->host,dev_inst_ptr->hub_no,dev_inst_ptr->port_no);
                break;
            }
   
            break;   
       case DEVSTATE_DEV_DESC:     /* full device descriptor received */
            /* Now lets get the first 9 bytes of the configuration descriptor 
                    */
            desc.pntr = &dev_inst_ptr->buffer;
            //printf("dev %d cfg, c %d 0x%x\n", dev_inst_ptr->dev_descriptor.bNumConfigurations, dev_inst_ptr->cfg_value, desc.pntr);
            dev_inst_ptr->state = DEVSTATE_GET_CFG9;
            status = _usb_host_ch9_get_descriptor((usb_device_instance_handle)dev_inst_ptr,
               USB_DESC_TYPE_CFG << 8 | dev_inst_ptr->cfg_value, 
               0, 
               sizeof(dev_inst_ptr->buffer),
               desc.bufr);
               
            if (status != USB_OK)
            {
                printf("get 9 byte configuration(%d) error\n", dev_inst_ptr->cfg_value);
                usb_host_dev_mng_pre_detach(dev_inst_ptr->host,dev_inst_ptr->hub_no,dev_inst_ptr->port_no);
                break;
            }
   
            break;
      case DEVSTATE_GET_CFG9:     /* Read 9 bytes of config descriptor */
          
            /* Now select the configuration as specified in the 
                    * descriptor 
                    */
            desc.cfig = (usb_configuration_descriptor_t*)dev_inst_ptr->buffer;
            config_size = USB_SHORT_UNALIGNED_LE_TO_HOST(desc.cfig->wTotalLength);
            
            /* for KHCI, the start address and the length should be 4 byte align */
            if ((config_size && 0x3) != 0)
            {
                aligned_config_size = (config_size & 0xFFFFFFFC) + 4;
            }

            if (dev_inst_ptr->lpConfiguration != NULL)
            {
                OS_Mem_free(dev_inst_ptr->lpConfiguration);
                dev_inst_ptr->lpConfiguration = NULL;
            }

            dev_inst_ptr->lpConfiguration = (void*)OS_Mem_alloc_uncached(aligned_config_size);
       
            if (dev_inst_ptr->lpConfiguration == NULL)
            {
                printf("get memory for full configuration(%d) error\n", dev_inst_ptr->cfg_value);
                usb_host_dev_mng_pre_detach(dev_inst_ptr->host,dev_inst_ptr->hub_no,dev_inst_ptr->port_no);
                break;
            }
           
            //printf("Get CFG9 %d %d %d\n",dev_inst_ptr->cfg_value, config_size,dev_inst_ptr->dev_descriptor.bNumConfigurations);
       
            /* We can only read one config descriptor at a time */
            status = _usb_host_ch9_get_descriptor((usb_device_instance_handle)dev_inst_ptr,
               (USB_DESC_TYPE_CFG << 8) | dev_inst_ptr->cfg_value, 
               0, 
               (uint16_t)config_size,
               dev_inst_ptr->lpConfiguration);
               
            if (status != USB_OK)
            {
                printf("get full configuration(%d) error\n", dev_inst_ptr->cfg_value);
                usb_host_dev_mng_pre_detach(dev_inst_ptr->host,dev_inst_ptr->hub_no,dev_inst_ptr->port_no);
                break;
            }    
#ifdef USBCFG_OTG
            dev_inst_ptr->state = DEVSTATE_CHK_OTG;
#else
            /*dev_inst_ptr->state = DEVSTATE_SET_CFG;*/
            dev_inst_ptr->state = DEVSTATE_CFG_READ;
#endif
           break;  

#ifdef USBCFG_OTG
        case DEVSTATE_CHK_OTG:
            otg_hnp_support = FALSE;
            /* Point to the memory owned by this device */
            /* FIXME: it is presumed that memlist points to the config descriptor */
            desc.pntr = dev_inst_ptr->lpConfiguration;

            /* We will always start with config desc so update the search pointer */
            config_size = USB_SHORT_UNALIGNED_LE_TO_HOST(desc.cfig->wTotalLength);
            config_size -= desc.cfig->bLength;
            desc.word += desc.cfig->bLength;
       
            while (config_size)
            {
                if (desc.otg->bDescriptorType == USB_DESC_TYPE_OTG)
                {
                    /* Found the OTG descriptor */
                    break;
                }
                config_size -= desc.intf->bLength;
                desc.word += desc.intf->bLength;
            }

            /* Check for an OTG descriptor */
            dev_inst_ptr->state = DEVSTATE_CFG_READ;
       
            if (config_size && desc.otg->bDescriptorType == USB_DESC_TYPE_OTG &&
               (desc.otg->bmAttributes & OTG_HNP_SUPPORT))
            {
                otg_hnp_support = TRUE;
                if(_usb_otg_host_get_otg_attribute(usb_host_ptr->otg_handle,desc.otg->bmAttributes) == USB_OK)
                {
                    if(_usb_otg_host_set_feature_required(usb_host_ptr->otg_handle))
                    {
                        status = _usb_host_ch9_set_feature(dev_inst_ptr, 0, 0, OTG_A_HNP_SUPPORT);
                       
                        if (status != USB_OK)
                        {
                            printf("set feature for otg error\n");
                            usb_host_dev_mng_pre_detach(dev_inst_ptr->host,dev_inst_ptr->hub_no,dev_inst_ptr->port_no);
                            break;
                        }
                        
                        else
                        {
                            dev_inst_ptr->state = DEVSTATE_SET_HNP;  
                            break;
                        }
                    }
                }
            }
        case DEVSTATE_SET_HNP:
            if (otg_hnp_support)
            {
                status = _usb_host_ch9_set_feature(dev_inst_ptr, 0, 0, OTG_B_HNP_ENABLE);
                if (status != USB_OK)
                {
                    dev_inst_ptr->state = DEVSTATE_INITIAL;
                }
                else
                {
                    dev_inst_ptr->state = DEVSTATE_SET_HNP_OK;
                }
                break; 
            }
        case  DEVSTATE_SET_HNP_OK:
            if(dev_inst_ptr->state == DEVSTATE_SET_HNP_OK)
            {
                _usb_otg_host_a_set_b_hnp_en(usb_host_ptr->otg_handle, TRUE);
            }
#endif  
        case DEVSTATE_CFG_READ:
            dev_inst_ptr->cfg_value++;
            //printf("cfg %d, %d\n", dev_inst_ptr->cfg_value,dev_inst_ptr->dev_descriptor.bNumConfigurations);
            if (usb_host_dev_mng_parse_configuration_descriptor(dev_inst_ptr) == USB_OK)
            {
                //printf("parse cfg\n");
                if (usb_host_dev_mng_check_configuration(dev_inst_ptr))
                {
                    //printf("check cfg\n");
                    usb_host_dev_notify(dev_inst_ptr, USB_ATTACH_EVENT);
                    /* enumeration done */
                    dev_inst_ptr->state = DEVSTATE_SET_CFG;
                    /* send set_configuration */
                    status = _usb_host_ch9_set_configuration(dev_inst_ptr, dev_inst_ptr->configuration.lpconfigurationDesc->bConfigurationValue);
                    if (status != USB_OK)
                    {
                        printf("set configuration(%d) error\n", dev_inst_ptr->cfg_value);
                        usb_host_dev_mng_pre_detach(dev_inst_ptr->host,dev_inst_ptr->hub_no,dev_inst_ptr->port_no);
                        break;
                    }
                }
                else
                {
                    //printf("cfg %d %d\n", dev_inst_ptr->cfg_value,dev_inst_ptr->dev_descriptor.bNumConfigurations);
                    /* get next configuration */
                    if (dev_inst_ptr->cfg_value < dev_inst_ptr->dev_descriptor.bNumConfigurations)
                    {
                        //printf("invalid cfg re\n");
                        desc.pntr = &dev_inst_ptr->buffer;
                        dev_inst_ptr->state = DEVSTATE_GET_CFG9;
                        status = _usb_host_ch9_get_descriptor((usb_device_instance_handle)dev_inst_ptr,
                            USB_DESC_TYPE_CFG << 8 | dev_inst_ptr->cfg_value, 
                            0, 
                            sizeof(dev_inst_ptr->buffer),
                            desc.bufr);
                        if (status != USB_OK)
                        {
                            printf("get 9 byte configuration(%d) error\n", dev_inst_ptr->cfg_value);
                            usb_host_dev_mng_pre_detach(dev_inst_ptr->host,dev_inst_ptr->hub_no,dev_inst_ptr->port_no);
                            break;
                        }
                   }
                   else
                   {
                       printf("unsupported device attached\n");
                       usb_host_dev_notify(dev_inst_ptr, USB_ATTACH_DEVICE_NOT_SUPPORT);
                       usb_host_dev_mng_pre_detach(dev_inst_ptr->host,dev_inst_ptr->hub_no,dev_inst_ptr->port_no);
                       break;
                   }
               }
            }
            else
            {
                printf("parse configuration(%d) error\n", dev_inst_ptr->cfg_value);
                usb_host_dev_mng_pre_detach(dev_inst_ptr->host,dev_inst_ptr->hub_no,dev_inst_ptr->port_no);
                break;
            }
            break;
        case DEVSTATE_SET_CFG:     /* config descriptor [0..8] */
            dev_inst_ptr->state = DEVSTATE_ENUM_OK;
            usb_host_dev_notify(dev_inst_ptr, USB_CONFIG_EVENT);
#ifdef USBCFG_OTG
            _usb_otg_host_on_interface_event(usb_host_ptr->otg_handle, dev_inst_ptr);
#endif
            break;

        case DEVSTATE_SET_INTF:    /* Select interface done */
            dev_inst_ptr->state = DEVSTATE_ENUM_OK;
            usb_host_dev_notify(dev_inst_ptr, USB_INTF_OPENED_EVENT);
            break;
        case DEVSTATE_ENUM_OK:   /* enumeration complete */
            if ((dev_inst_ptr->control_callback != NULL))
            {
                dev_inst_ptr->control_callback(tr_ptr, dev_inst_ptr->control_callback_param, buffer, length, status);
            }
            break;
        default:
            break;
    } /* EndSwitch */
} /* EndBody */
示例#15
0
/*FUNCTION*----------------------------------------------------------------
 *
 * Function Name  : usb_class_audio_cntrl_common
 * Returned Value : USB_OK if command has been passed on USB.
 * Comments       :
 *     This function is used to send a control request.
 *     It must be run with USB locked.
 *
 *END*--------------------------------------------------------------------*/
static usb_status usb_class_audio_cntrl_common
(
/* [IN] The communication device common command structure */
audio_command_t* com_ptr,

/* [IN] The audio control interface */
//audio_control_struct_t* if_ctrl_ptr,
/* [IN] Bitmask of the request type */
uint8_t bmrequesttype,

/* [IN] Request code */
uint8_t brequest,

/* [IN] Value to copy into wvalue field of the REQUEST */
uint16_t wvalue,

/* [IN] Value to copy into windex field of the REQUEST */
uint16_t windex,

/* [IN] Length of the data associated with REQUEST */
uint16_t wlength,

/* [IN] Pointer to data buffer used to send/recv */
uint8_t * data
)
{ /* Body */
    audio_control_struct_t* audio_class = NULL;
    //usb_setup_t                       req;
    usb_status status = USB_OK;
    usb_pipe_handle pipe_handle;
    tr_struct_t* tr_ptr;

    if ((com_ptr == NULL) || (com_ptr->class_control_handle == NULL))
    {
        return USBERR_ERROR;
    }
    audio_class = (audio_control_struct_t*)com_ptr->class_control_handle;

    if (audio_class->in_setup)
    {
        return USBERR_TRANSFER_IN_PROGRESS;
    }
    if (audio_class->dev_handle == NULL)
    {
        return USB_log_error(__FILE__,__LINE__,USBERR_DEVICE_NOT_FOUND);
    }

    audio_class->ctrl_callback = com_ptr->callback_fn;
    audio_class->ctrl_param = com_ptr->callback_param;
    pipe_handle = usb_host_dev_mng_get_control_pipe(audio_class->dev_handle);

    if (usb_host_get_tr(audio_class->host_handle, usb_class_audio_cntrl_callback, audio_class, &tr_ptr) != USB_OK)
    {
        USB_PRINTF("error to get tr audio \r\n");
        return USBERR_ERROR;
    }

    /* Set TR buffer length as required */
    if ((REQ_TYPE_IN & bmrequesttype) != 0)
    {
        tr_ptr->rx_buffer = data;
        tr_ptr->rx_length = wlength;
    }
    else
    {
        tr_ptr->tx_buffer = data;
        tr_ptr->tx_length = wlength;
    }

    tr_ptr->setup_packet.bmrequesttype = bmrequesttype;
    tr_ptr->setup_packet.brequest = brequest;
    *(uint16_t*)&(tr_ptr->setup_packet.wvalue[0]) = USB_HOST_TO_LE_SHORT(wvalue);
    *(uint16_t*)&(tr_ptr->setup_packet.windex[0]) = USB_HOST_TO_LE_SHORT(windex);  //USB_HOST_TO_LE_SHORT(((interface_descriptor_t*)(audio_class->intf_handle))->bInterfaceNumber);
    *(uint16_t*)&(tr_ptr->setup_packet.wlength[0]) = USB_HOST_TO_LE_SHORT(wlength);

    audio_class->in_setup = TRUE;
    status = usb_host_send_setup(audio_class->host_handle, pipe_handle, tr_ptr);
    if (status != USB_OK)
    {
        audio_class->in_setup = FALSE;
        USB_PRINTF("\nError in usb_class_audio_cntrl_common: %x", (unsigned int)status);
        usb_host_release_tr(audio_class->host_handle, tr_ptr);
    }
    return status;
} /* Endbody */
示例#16
0
/*FUNCTION*----------------------------------------------------------------
*
* Function Name  : usb_class_hub_recv_bitmap
* Returned Value : None
* Comments       :
*     Starts interrupt endpoint to poll for interrupt on specified hub
*END*--------------------------------------------------------------------*/
usb_status usb_class_hub_recv_bitmap
    (
      /* [IN] Class Interface structure pointer */
      hub_command_t*            com_ptr,
       /* [IN] The buffer address */
      uint8_t *                  buffer,
      /* size of buffer to be used */
      uint8_t                      length
    )
{
    usb_hub_class_struct_t*       hub_class;
    tr_struct_t*                  tr_ptr;
    usb_status                     status = USBERR_NO_INTERFACE;

    #ifdef _HOST_DEBUG_
       DEBUG_LOG_TRACE("usb_class_hub_recv_bitmap");
    #endif
    //USB_PRINTF("r \n");

    if ((com_ptr == NULL) || (com_ptr->class_ptr == NULL))
    {
        return USBERR_ERROR;
    }

    hub_class = (usb_hub_class_struct_t*)com_ptr->class_ptr;
    
    if ((hub_class == NULL) || (buffer == NULL))
    {
        USB_PRINTF("input parameter error\n");
        return USBERR_ERROR;
    }

    hub_class->interrupt_callback = com_ptr->callback_fn;
    hub_class->interrupt_param = com_ptr->callback_param;

    if (hub_class->dev_handle == NULL)
    {
        return USBERR_ERROR;
    }

    if (hub_class->in_interrupt)
    {
        return USBERR_ERROR;
    }

    if (usb_host_get_tr(hub_class->host_handle, usb_class_hub_int_callback, hub_class, &tr_ptr) != USB_OK)
    {
        USB_PRINTF("error to get tr\n");
        return USBERR_ERROR;
    }
    
    tr_ptr->rx_buffer = buffer;
    tr_ptr->rx_length = length;                                            
    status = usb_host_recv_data(hub_class->host_handle, hub_class->interrupt_pipe, tr_ptr);
    if (status != USB_OK)
    {
        USB_PRINTF("\nError in usb_class_hub_recv_bitmap: %x", (unsigned int)status);
        usb_host_release_tr(hub_class->host_handle, tr_ptr);
        return USBERR_ERROR;
    }
    hub_class->in_interrupt = TRUE;
    return USB_OK;
}
示例#17
0
usb_status usb_class_hub_cntrl_common
   (
      /* [IN] Class Interface structure pointer */
      hub_command_t*         com_ptr,
      /* [IN] Bitmask of the request type */
      uint8_t                  bmrequesttype,
      /* [IN] Request code */
      uint8_t                  brequest,
      /* [IN] Value to copy into wvalue field of the REQUEST */
      uint16_t                 wvalue,
      /* [IN] Length of the data associated with REQUEST */
      uint16_t                 windex,
      /* [IN] Index field of CTRL packet */
      uint16_t                 wlength,
      /* [IN] the buffer to be transfered */
      uint8_t *               data
   )
{
    usb_hub_class_struct_t*         hub_class = NULL;
    //usb_setup_t                        req;
    usb_status                       status = USB_OK;
    tr_struct_t*                    tr_ptr;

    if ((com_ptr == NULL) || (com_ptr->class_ptr == NULL))
    {
        return USBERR_ERROR;
    }

    hub_class = (usb_hub_class_struct_t*)com_ptr->class_ptr;
    if (hub_class->in_setup)
    {
        return USBERR_TRANSFER_IN_PROGRESS;
    }

    if (hub_class->dev_handle == NULL)
    {
        #ifdef _HOST_DEBUG_
           DEBUG_LOG_TRACE("usb_class_hub_cntrl_common, invalid device handle");
        #endif
        return USBERR_DEVICE_NOT_FOUND;
    }
    
    hub_class->ctrl_callback = com_ptr->callback_fn;
    hub_class->ctrl_param = com_ptr->callback_param;

    if (usb_host_get_tr(hub_class->host_handle, usb_class_hub_cntrl_callback, hub_class, &tr_ptr) != USB_OK)
    {
        USB_PRINTF("error to get tr hub\n");
        return USBERR_ERROR;
    }

    /* Set TR buffer length as required */
    if ((REQ_TYPE_IN & bmrequesttype) != 0)
    {
        tr_ptr->rx_buffer = data;
        tr_ptr->rx_length = wlength;
    }
    else
    {
        tr_ptr->tx_buffer = data;
        tr_ptr->tx_length = wlength;
    }
 
    tr_ptr->setup_packet.bmrequesttype = bmrequesttype;
    tr_ptr->setup_packet.brequest      = brequest;
    *(uint16_t*)tr_ptr->setup_packet.wvalue = USB_HOST_TO_LE_SHORT(wvalue);
    *(uint16_t*)tr_ptr->setup_packet.windex = USB_HOST_TO_LE_SHORT(windex);
    *(uint16_t*)tr_ptr->setup_packet.wlength = USB_HOST_TO_LE_SHORT(wlength);
 
    status = usb_host_send_setup(hub_class->host_handle, hub_class->control_pipe, tr_ptr);  
    if (status != USB_OK)
    {
        usb_host_release_tr(hub_class->host_handle, tr_ptr);
        return USBERR_ERROR;
    }
    hub_class->in_setup = TRUE;
    return USB_OK;
} /* Endbody */