/*FUNCTION*------------------------------------------------------------- * * Function Name : VNIC_Send_PCB_Free * Returned Value : None * Comments : * Free nic_pcb * *END*-----------------------------------------------------------------*/ void VNIC_Send_PCB_Free(PCB_PTR nic_pcb) { if(nic_pcb != NULL) { /* ethernet_frame_ptr is ((PCB_PTR)nic_pcb)->FRAG[0].FRAGMENT used in VNIC_FEC_Send rndis_pkt_msg_data_ptr is ethernet_frame_ptr - RNDIS_USB_OVERHEAD_SIZE used in USB_Notif_Callback*/ USB_mem_free(((PCB_PTR)nic_pcb)->FRAG[0].FRAGMENT - RNDIS_USB_OVERHEAD_SIZE); USB_mem_free((void*)nic_pcb); } }
/*FUNCTION*------------------------------------------------------------- * * Function Name : _usb_device_shutdown * Returned Value : USB_OK or error code * Comments : * Shutdown an initialized USB device * *END*-----------------------------------------------------------------*/ uint_8 _usb_device_shutdown ( /* [IN] the USB_USB_dev_initialize state structure */ _usb_device_handle handle ) { uint_8 error; volatile USB_DEV_STATE_STRUCT_PTR usb_dev_ptr; if (handle == NULL) { #if _DEBUG printf("_usb_device_shutdowna: handle is NULL\n"); #endif return USBERR_ERROR; } usb_dev_ptr = (USB_DEV_STATE_STRUCT_PTR)handle; if ( ((USB_DEV_CALLBACK_FUNCTIONS_STRUCT_PTR)\ usb_dev_ptr->CALLBACK_STRUCT_PTR)->DEV_SHUTDOWN != NULL) { error = ((USB_DEV_CALLBACK_FUNCTIONS_STRUCT_PTR)\ usb_dev_ptr->CALLBACK_STRUCT_PTR)->DEV_SHUTDOWN(usb_dev_ptr); } else { #if _DEBUG printf("_usb_device_shutdown: DEV_SHUTDOWN is NULL\n"); #endif return USBERR_ERROR; } /* Free all the Callback function structure memory */ USB_mem_free((pointer)usb_dev_ptr->SERVICE_HEAD_PTR); /* Free all internal transfer descriptors */ USB_mem_free((pointer)usb_dev_ptr->XD_BASE); /* Free all XD scratch memory */ USB_mem_free((pointer)usb_dev_ptr->XD_SCRATCH_STRUCT_BASE); /* Free the temp ep init XD */ USB_mem_free((pointer)usb_dev_ptr->TEMP_XD_PTR); /* Free the USB state structure */ USB_mem_free((pointer)usb_dev_ptr); return error; } /* EndBody */
static void _usb_host_open_pipe_cleanup( /* [IN] the USB Host state structure */ _usb_host_handle handle, PIPE_STRUCT_PTR pipe_ptr, boolean close_pipe_call ) { /* Body */ TR_STRUCT_PTR temp; if (close_pipe_call) { _usb_host_close_pipe_call_interface (handle, pipe_ptr); } while (pipe_ptr->tr_list_ptr != NULL) { temp = pipe_ptr->tr_list_ptr; pipe_ptr->tr_list_ptr = pipe_ptr->tr_list_ptr->NEXT; USB_mem_free((pointer)temp); } pipe_ptr->OPEN = FALSE; #ifdef _HOST_DEBUG_ if (close_pipe_call) { DEBUG_LOG_TRACE("_usb_host_open_pipe bandwidth alloc failed"); } else { DEBUG_LOG_TRACE("_usb_host_open_pipe callback failed"); } #endif }
/*FUNCTION*---------------------------------------------------------------- * * Function Name : usb_dev_list_free_memory * Returned Value : USB_OK if valid device, else error code * Comments : * Close pipes & free memory on device's linked list, whose * anchor is device.memlist--> * *END*--------------------------------------------------------------------*/ USB_STATUS usb_dev_list_free_memory ( /* [IN] Handle for the USB device */ _usb_device_instance_handle dev_handle ) { /* Body */ DEV_INSTANCE_PTR dev; DEV_MEMORY_PTR mem_ptr, list_ptr; USB_STATUS error; uint_8 intf_no; error = usb_hostdev_validate(dev_handle); /* EAI - missing {} so failed if debug on */ if (error != USB_OK) { return error; } dev = (DEV_INSTANCE_PTR)dev_handle; /* Deleting interfaces closes their pipes */ for (intf_no = 0; intf_no < dev->num_of_interfaces; intf_no++) usb_hostdev_delete_interface(dev, dev->intf_descriptor[intf_no]); /* Free memory blocks on this device's list */ USB_lock(); mem_ptr = dev->memlist; #if 0 list_ptr = mem_ptr->next; do { USB_mem_free(mem_ptr); mem_ptr = list_ptr; list_ptr = mem_ptr->next; } while (mem_ptr != NULL); #else /* << EST: above code will crash if list has more than one entry */ while(mem_ptr!=NULL) { list_ptr = mem_ptr->next; USB_mem_free(mem_ptr); mem_ptr = list_ptr; } #endif dev->memlist = NULL; USB_unlock(); return USB_OK; } /* Endbody */
static int_32 USB_Cdc_Free_Handle(CDC_HANDLE handle) { if ((handle < 0) || (handle > MAX_CDC_DEVICE)) return USBERR_ERROR; USB_mem_free((void *)cdc_device_array[handle]); cdc_device_array[handle] = NULL; return USB_OK; }
/*FUNCTION*------------------------------------------------------------- * * Function Name : _usb_host_shutdown * Returned Value : USB_OK or error code * Comments : * Shutdown an initialized USB Host * *END*-----------------------------------------------------------------*/ void _usb_host_shutdown ( /* [IN] the USB_host handle */ _usb_host_handle hci_handle ) { /* Body */ USB_STATUS status; USB_HOST_STATE_STRUCT_PTR usb_host_ptr; usb_host_ptr = (USB_HOST_STATE_STRUCT_PTR)hci_handle; /* De-initialize and disconnect the host hardware from the bus */ status = _usb_host_shutdown_call_interface (hci_handle); UNUSED(status); /* Free all Pipe Descriptors */ USB_mem_free((pointer)usb_host_ptr->PIPE_DESCRIPTOR_BASE_PTR); /* Free the USB state structure */ USB_mem_free(hci_handle); } /* EndBody */
/*************************************************************************//*! * * @name USB_Phdc_Free_Handle * * @brief The function releases entry in device array . * * @param handle index in device array to be released.. * @return returns and error code or USB_OK. * *****************************************************************************/ static int32_t USB_Phdc_Free_Handle(PHDC_HANDLE handle) { if (/*(handle < 0) || */(handle > MAX_PHDC_OBJECT)) return USBERR_ERROR; USB_mem_free((void *)phdc_object_array[handle]); phdc_object_array[handle] = NULL; return USB_OK; }
static int_32 USB_Class_Fw_Free_Handle(USB_CLASS_FW_HANDLE handle) { if (handle > USB_MAX_CLASS_FW_OBJECT) return USBERR_ERROR; USB_mem_free((void *)usb_class_fw_object[handle]); usb_class_fw_object[handle] = NULL; return USB_OK; }
static int32_t USB_Hid_Free_Handle(HID_HANDLE handle) { if (/*(handle < 0) || */ (handle > MAX_HID_DEVICE)) return USBERR_ERROR; USB_mem_free((void *)device_array[handle]); device_array[handle] = NULL; return USB_OK; }
int_32 _io_usb_mfs_uninstall_internal ( /* [IN] The device to uninstall */ IO_DEVICE_STRUCT_PTR io_dev_ptr ) { IO_USB_MFS_STRUCT_PTR info_ptr = (IO_USB_MFS_STRUCT_PTR)io_dev_ptr->DRIVER_INIT_PTR; _lwsem_destroy(&info_ptr->COMMAND_DONE); _lwsem_destroy(&info_ptr->LWSEM); USB_mem_free(info_ptr); return MQX_OK; }
/*FUNCTION*------------------------------------------------------------- * * Function Name : _usb_device_deinit * Returned Value : USB_OK or error code * Comments : * uninitializes the USB device specific data structures and calls * the low-level device controller chip initialization routine. * *END*-----------------------------------------------------------------*/ uint_8 _usb_device_deinit ( /* [OUT] the USB_USB_dev_initialize state structure */ _usb_device_handle handle ) { /* Body */ USB_DEV_STATE_STRUCT_PTR usb_dev_ptr; uint_8 error; error = _usb_device_shutdown(handle); USB_mem_free((void*)(handle)); return error; } /* EndBody */
/*FUNCTION*---------------------------------------------------------------- * * Function Name : _usb_host_unregister_service * Returned Value : USB_OK or error code * Comments : * Unregisters a callback routine for a specified event or endpoint. * *END*--------------------------------------------------------------------*/ USB_STATUS _usb_host_unregister_service ( /* [IN] Handle to the USB device */ _usb_host_handle handle, /* [IN] type of event or endpoint number to service */ uint_8 type ) { /* Body */ USB_HOST_STATE_STRUCT_PTR usb_host_ptr; USB_SERVICE_STRUCT_PTR service_ptr; USB_SERVICE_STRUCT_PTR _PTR_ search_ptr; #ifdef _HOST_DEBUG_ DEBUG_LOG_TRACE("_usb_host_unregister_service"); #endif usb_host_ptr = (USB_HOST_STATE_STRUCT_PTR)handle; /* Needs mutual exclusion */ USB_lock(); /* Search for an existing entry for type */ for (search_ptr = &usb_host_ptr->SERVICE_HEAD_PTR; *search_ptr; search_ptr = &(*search_ptr)->NEXT) { if ((*search_ptr)->TYPE == type) { /* Found an existing entry - delete it */ break; } /* Endif */ } /* Endfor */ /* No existing entry found */ if (!*search_ptr) { USB_unlock(); #ifdef _HOST_DEBUG_ DEBUG_LOG_TRACE("_usb_host_unregister_service no service found"); #endif return USB_log_error(__FILE__,__LINE__,USBERR_CLOSED_SERVICE); } /* Endif */ service_ptr = *search_ptr; *search_ptr = service_ptr->NEXT; USB_unlock(); USB_mem_free((pointer)service_ptr); #ifdef _HOST_DEBUG_ DEBUG_LOG_TRACE("_usb_host_unregister_service SUCCESSFUL"); #endif return USB_OK; } /* EndBody */
/*FUNCTION*------------------------------------------------------------- * * Function Name : _usb_host_close_all_pipes * Returned Value : None * Comments : * _usb_host_close_all_pipes routine removes the pipe from the open pipe list * *END*-----------------------------------------------------------------*/ void _usb_host_close_all_pipes ( /* [IN] the USB Host state structure */ _usb_host_handle handle ) { /* Body */ USB_HOST_STATE_STRUCT_PTR usb_host_ptr; PIPE_STRUCT_PTR pipe_ptr, pipe_bkp_ptr; TR_STRUCT_PTR tr_ptr, tr_ptr_next; usb_host_ptr = (USB_HOST_STATE_STRUCT_PTR)handle; #ifdef _HOST_DEBUG_ DEBUG_LOG_TRACE("_usb_host_close_all_pipes"); #endif USB_lock(); for (pipe_ptr = usb_host_ptr->PIPE_DESCRIPTOR_BASE_PTR; pipe_ptr != NULL; pipe_ptr = pipe_ptr->NEXT) { if (pipe_ptr->OPEN) { /* Call the low-level routine to free the controller specific resources for this pipe */ _usb_host_close_pipe_call_interface (handle, pipe_ptr); /* before cleaning pipe_ptr struct we need to deallocate structures in the circullar list */ if (pipe_ptr->tr_list_ptr != NULL) { tr_ptr = pipe_ptr->tr_list_ptr; do { tr_ptr_next = tr_ptr->NEXT; /* free transaction belonging to this pipe */ USB_mem_free(tr_ptr); tr_ptr = tr_ptr_next; } while (tr_ptr != pipe_ptr->tr_list_ptr); //pipe_ptr->tr_list_ptr = NULL; //this will be done later by zeroing pipe_ptr } /* de-initialise the pipe descriptor, but prevent the chain */ pipe_bkp_ptr = pipe_ptr->NEXT; USB_mem_zero(pipe_ptr, sizeof(PIPE_STRUCT)); /* restore the chain */ pipe_ptr->NEXT = pipe_bkp_ptr; } /* Endif */ } /* Endfor */ USB_unlock(); #ifdef _HOST_DEBUG_ DEBUG_LOG_TRACE("_usb_host_close_all_pipes SUCCESSFUL"); #endif } /* Endbody */
/*FUNCTION*---------------------------------------------------------------- * * Function Name : _usb_device_unregister_service * Returned Value : USB_OK or error code * Comments : * Unregisters a callback routine for a specified event or endpoint. * *END*--------------------------------------------------------------------*/ USB_STATUS _usb_device_unregister_service ( /* [IN] Handle to the USB device */ _usb_device_handle handle, /* [IN] type of event or endpoint number to service */ uint_8 type ) { /* Body */ USB_DEV_STATE_STRUCT_PTR usb_dev_ptr; SERVICE_STRUCT_PTR service_ptr; SERVICE_STRUCT_PTR _PTR_ search_ptr; if (handle == NULL) { return USBERR_ERROR; } usb_dev_ptr = (USB_DEV_STATE_STRUCT_PTR)handle; /* Needs mutual exclusion */ USB_lock(); /* Search for an existing entry for type */ for (search_ptr = &usb_dev_ptr->SERVICE_HEAD_PTR; *search_ptr; search_ptr = &(*search_ptr)->NEXT) { if ((*search_ptr)->TYPE == type) { /* Found an existing entry - delete it */ break; } /* Endif */ } /* Endfor */ /* No existing entry found */ if (!*search_ptr) { USB_unlock(); return USBERR_CLOSED_SERVICE; } /* Endif */ service_ptr = *search_ptr; *search_ptr = service_ptr->NEXT; USB_mem_free((pointer)service_ptr); USB_unlock(); return USB_OK; } /* EndBody */
/*FUNCTION*---------------------------------------------------------------- * * Function Name : usb_host_printer_pcl5_write_callback * Returned Value : None * Comments : * Called when an interrupt pipe transfer is completed. *END*--------------------------------------------------------------------*/ static void usb_host_printer_pcl5_write_callback( _usb_pipe_handle pipe_handle, pointer user_parm, uchar_ptr buffer, uint_32 buflen, uint_32 status ) { if(NULL != g_printer_plc5_write_callback) { g_printer_plc5_write_callback(pipe_handle,user_parm,buffer,buflen,status); } if(NULL != buffer) USB_mem_free(buffer); }
/**************************************************************************//*! * * @name USB_Framework_Deinit * * @brief The funtion deinitializes the Class Module * * @param handle : handle to Identify the controller * @param fw_handle: Framework handle * * @return status * USB_OK : When Successfull * Others : Errors * *****************************************************************************/ uint_8 USB_Framework_Deinit ( _usb_device_handle handle, /*[IN]*/ USB_CLASS_FW_HANDLE fw_handle /*[IN]*/ ) { USB_CLASS_FW_OBJECT_STRUCT_PTR usb_fw_ptr = NULL; uint_8 error = USB_OK; usb_fw_ptr = Get_Usb_Class_Fw_Object_Ptr(fw_handle); USB_mem_free((void *)(usb_fw_ptr->ext_req_to_host)); error = _usb_device_unregister_service(handle, USB_SERVICE_EP0); USB_Class_Fw_Free_Handle(fw_handle); return error; }
/*FUNCTION*---------------------------------------------------------------- * * Function Name : usb_dev_list_free_memlist * Returned Value : USB_OK if valid device, else error code * Comments : * Close pipes & free memory on device's linked list, whose * anchor is dev_handle-->memlist * *END*--------------------------------------------------------------------*/ USB_STATUS usb_dev_list_free_memlist ( /* [IN] Handle for the USB device */ _usb_device_instance_handle dev_handle ) { /* Body */ DEV_INSTANCE_PTR dev; DEV_MEMORY_PTR mem_ptr, list_ptr; USB_STATUS error; uint_8 intf_no; #ifdef _HOST_DEBUG_ DEBUG_LOG_TRACE("usb_dev_list_free_memlist"); #endif error = usb_hostdev_validate(dev_handle); // EAI - missing {} so failed if debug on if (error != USB_OK) { #ifdef _HOST_DEBUG_ DEBUG_LOG_TRACE("usb_dev_list_free_memlist invalid device handle"); #endif return USB_log_error(__FILE__,__LINE__,error); } dev = (DEV_INSTANCE_PTR)dev_handle; /* Deleting interfaces closes their pipes */ for (intf_no = 0; intf_no < dev->num_of_interfaces; intf_no++) usb_hostdev_delete_interface(dev, dev->intf_descriptor[intf_no]); /* Free memory blocks on this device's list */ USB_lock(); mem_ptr = dev->memlist; while (mem_ptr != NULL) { list_ptr = mem_ptr->next; USB_mem_free(mem_ptr); mem_ptr = list_ptr; } dev->memlist = NULL; USB_unlock(); #ifdef _HOST_DEBUG_ DEBUG_LOG_TRACE("usb_dev_list_free_memlist SUCCESSFUL"); #endif return USB_OK; } /* Endbody */
void _usb_host_iso_packet_desc_pool_destroy (void) { USB_mem_free(usb_host_iso_packet_desc_pool.mem_ptr); }
/**************************************************************************//*! * * @name USB_Framework_Init * * @brief The funtion initializes the Class Module * * @param handle : handle to Identify the controller * @param class_callback: event callback * @param other_req_callback: callback for vendor or usb framework class req * * @return status * USB_OK : When Successfull * Others : Errors * *****************************************************************************/ USB_CLASS_FW_HANDLE USB_Framework_Init ( _usb_device_handle handle, /*[IN]*/ USB_CLASS_CALLBACK class_callback,/*[IN]*/ USB_REQ_FUNC other_req_callback,/*[IN]*/ pointer callback_data,/*[IN]*/ int_32 data,/*[IN]*/ DESC_CALLBACK_FUNCTIONS_STRUCT_PTR desc_callback_ptr /*[IN]*/ ) { USB_CLASS_FW_OBJECT_STRUCT_PTR usb_fw_ptr = NULL; USB_CLASS_FW_HANDLE fw_handle; uint_8 error=USB_OK; usb_fw_ptr = (USB_CLASS_FW_OBJECT_STRUCT_PTR)USB_mem_alloc_zero( sizeof(USB_CLASS_FW_OBJECT_STRUCT)); if (NULL == usb_fw_ptr) { #ifdef _DEV_DEBUG printf("USB_Framework_Init: Memalloc failed\n"); #endif return USBERR_ALLOC; } if (USBERR_DEVICE_BUSY == USB_Class_Fw_Allocate_Handle(&fw_handle)) { USB_mem_free((void *)usb_fw_ptr); usb_fw_ptr = NULL; return USBERR_ERROR; } /* save input parameters */ usb_fw_ptr->class_handle = data; usb_fw_ptr->ext_req_to_host = NULL; /* reserve memory for setup token and data received */ usb_fw_ptr->ext_req_to_host = (uint_8*)USB_mem_alloc_zero(MAX_EXPECTED_CONTROL_OUT_SIZE); if (NULL == usb_fw_ptr->ext_req_to_host) { #ifdef _DEV_DEBUG printf("ext_req_to_host malloc failed: USB_Framework_Init\n"); #endif return USBERR_ALLOC; } usb_fw_ptr->controller_handle = handle; usb_fw_ptr->other_req_callback.callback = other_req_callback; usb_fw_ptr->other_req_callback.arg = callback_data; usb_fw_ptr->class_callback.callback = class_callback; usb_fw_ptr->class_callback.arg = callback_data; USB_mem_copy( desc_callback_ptr,&usb_fw_ptr->desc, sizeof(DESC_CALLBACK_FUNCTIONS_STRUCT)); /* Register CONTROL service */ error = _usb_device_register_service(handle, USB_SERVICE_EP0, #ifdef DELAYED_PROCESSING USB_Control_Service_Callback, #else USB_Control_Service, #endif (pointer)usb_fw_ptr ); usb_class_fw_object[fw_handle] = usb_fw_ptr; return fw_handle; }
void _usb_ehci_close_interrupt_pipe ( /* [IN] the USB Host state structure */ _usb_host_handle handle, /* The pipe descriptor to queue */ PIPE_DESCRIPTOR_STRUCT_PTR pipe_descr_ptr ) { USB_HOST_STATE_STRUCT_PTR usb_host_ptr; EHCI_QH_STRUCT_PTR QH_ptr,temp_QH_ptr; ACTIVE_QH_MGMT_STRUCT_PTR active_list_member_ptr; ACTIVE_QH_MGMT_STRUCT_PTR temp_active_list_member_ptr,prev_active_list_member_ptr; EHCI_QTD_STRUCT_PTR QTD_ptr, temp_QTD_ptr; uint_8_ptr frame_list_bw_ptr; USB_Uncached uint_32 _PTR_ periodic_list_base_ptr; #if 1 USB_Uncached uint_32 _PTR_ transfer_data_struct_ptr; USB_Uncached uint_32 _PTR_ prev_transfer_data_struct_ptr; #else USB_Uncached uint_32_ptr transfer_data_struct_ptr; USB_Uncached uint_32_ptr prev_transfer_data_struct_ptr; #endif EHCI_ITD_STRUCT_PTR ITD_ptr; EHCI_SITD_STRUCT_PTR SITD_ptr; EHCI_FSTN_STRUCT_PTR FSTN_ptr; int i; boolean unlinked; usb_host_ptr = (USB_HOST_STATE_STRUCT_PTR)handle; /**************************************************************************** Obtain the QH for this pipe ****************************************************************************/ QH_ptr = (EHCI_QH_STRUCT_PTR) pipe_descr_ptr->QH_FOR_THIS_PIPE; if(QH_ptr == NULL) return; /**************************************************************************** First Search the periodic list and unlink this QH from the list. ****************************************************************************/ frame_list_bw_ptr = usb_host_ptr->PERIODIC_FRAME_LIST_BW_PTR; periodic_list_base_ptr = (USB_Uncached uint_32 _PTR_)(usb_host_ptr->ALIGNED_PERIODIC_LIST_BASE_ADDR); /******************************************************************* Start from fram 0 till end of the list and unlink the QH if found. Note that we should not unlink when the QH is active but current code does not take this in account. ********************************************************************/ for(i=0;i< usb_host_ptr->FRAME_LIST_SIZE;i++) { transfer_data_struct_ptr = (USB_Uncached uint_32 _PTR_) periodic_list_base_ptr + i; prev_transfer_data_struct_ptr = transfer_data_struct_ptr; unlinked = FALSE; /******************************************************************* Traverse the frame i and unlink the QH if found in it. ********************************************************************/ while ((!(*((USB_Uncached uint_32 _PTR_)transfer_data_struct_ptr) & EHCI_FRAME_LIST_ELEMENT_POINTER_T_BIT)) && (unlinked == FALSE)) { switch (EHCI_GET_TYPE(transfer_data_struct_ptr)) { case EHCI_ELEMENT_TYPE_ITD: ITD_ptr = (EHCI_ITD_STRUCT_PTR)((*transfer_data_struct_ptr)& EHCI_HORIZ_PHY_ADDRESS_MASK); prev_transfer_data_struct_ptr = transfer_data_struct_ptr; transfer_data_struct_ptr = (pointer) (ITD_ptr->NEXT_LINK_PTR & EHCI_HORIZ_PHY_ADDRESS_MASK); break; case EHCI_ELEMENT_TYPE_QH: temp_QH_ptr = (EHCI_QH_STRUCT_PTR)((*transfer_data_struct_ptr) & EHCI_HORIZ_PHY_ADDRESS_MASK); if(temp_QH_ptr == QH_ptr) { /************************************************************* Unlink this QH now. *************************************************************/ USB_lock(); reclaim_band_width( handle, (uint_32)i, (USB_Uncached uint_32 _PTR_) transfer_data_struct_ptr, pipe_descr_ptr); unlink_periodic_data_structure_from_frame ( (USB_Uncached uint_32 _PTR_) prev_transfer_data_struct_ptr, (USB_Uncached uint_32 _PTR_) transfer_data_struct_ptr); USB_unlock(); /*exit out of loop since there can be only 1 QH of same pipe in this frame */ unlinked = TRUE; } prev_transfer_data_struct_ptr = transfer_data_struct_ptr; transfer_data_struct_ptr = (pointer) (temp_QH_ptr->HORIZ_LINK_PTR & EHCI_HORIZ_PHY_ADDRESS_MASK); break; case EHCI_ELEMENT_TYPE_SITD: SITD_ptr = (EHCI_SITD_STRUCT_PTR)((*transfer_data_struct_ptr) & EHCI_HORIZ_PHY_ADDRESS_MASK); prev_transfer_data_struct_ptr = transfer_data_struct_ptr; transfer_data_struct_ptr = (pointer) (SITD_ptr->NEXT_LINK_PTR & EHCI_HORIZ_PHY_ADDRESS_MASK); break; case EHCI_ELEMENT_TYPE_FSTN: FSTN_ptr = (EHCI_FSTN_STRUCT_PTR)((*transfer_data_struct_ptr) & EHCI_HORIZ_PHY_ADDRESS_MASK); prev_transfer_data_struct_ptr = transfer_data_struct_ptr; transfer_data_struct_ptr = (pointer) (FSTN_ptr->NORMAL_PATH_LINK_PTR & EHCI_HORIZ_PHY_ADDRESS_MASK); break; default: break; } /* EndSwitch */ } /*while */ } /* for */ /**************************************************************************** Search the list of active interrupt transfers to find if this QH aleady exists in the list. If it exists we should free QH and all QTD associated with it. **************************************************************************/ active_list_member_ptr = (ACTIVE_QH_MGMT_STRUCT_PTR) \ usb_host_ptr->ACTIVE_INTERRUPT_PERIODIC_LIST_PTR; /*point to itself to start with */ prev_active_list_member_ptr = active_list_member_ptr; /*count the number of elements in the list, if None, set the list to NULL*/ i=0; while (active_list_member_ptr) { if(active_list_member_ptr->QH_PTR == QH_ptr) { /* don't want to get interrupted when changing the QTD and QH list */ USB_lock(); /*********************************************** Do the freeing stuff disable this QH so that there are no more QTDs executed. ***********************************************************/ QH_ptr->NEXT_QTD_LINK_PTR = EHCI_QTD_T_BIT; /*********************************************** free all the QTDs if any. ************************************************/ QTD_ptr = active_list_member_ptr->FIRST_QTD_PTR; while ((!(((uint_32)QTD_ptr) & EHCI_QTD_T_BIT)) && (QTD_ptr != NULL)) { temp_QTD_ptr = QTD_ptr; QTD_ptr = (EHCI_QTD_STRUCT_PTR)QTD_ptr->NEXT_QTD_PTR; _usb_hci_vusb20_free_QTD(handle, (pointer)temp_QTD_ptr); } /*free QH */ _usb_hci_vusb20_free_QH(handle, (pointer) QH_ptr); QH_ptr=NULL; /*ensure that all pointers are NULL in this structure */ active_list_member_ptr->QH_PTR = NULL; active_list_member_ptr->FIRST_QTD_PTR = NULL; /* store the pointer temporarily before freeing it */ temp_active_list_member_ptr = active_list_member_ptr; /* move on to the next member of the list */ active_list_member_ptr = (ACTIVE_QH_MGMT_STRUCT_PTR) \ active_list_member_ptr->NEXT_ACTIVE_QH_MGMT_STRUCT_PTR; /*connect previous to next */ ((ACTIVE_QH_MGMT_STRUCT_PTR)prev_active_list_member_ptr)->NEXT_ACTIVE_QH_MGMT_STRUCT_PTR = active_list_member_ptr; /* we should free this ACTIVE Q MGMT structure */ USB_mem_free(temp_active_list_member_ptr); USB_unlock(); break; } else { prev_active_list_member_ptr = active_list_member_ptr; active_list_member_ptr = (ACTIVE_QH_MGMT_STRUCT_PTR) \ active_list_member_ptr->NEXT_ACTIVE_QH_MGMT_STRUCT_PTR; i++; } } if(i == 0) /* if list is empty make sure to initialize the pointer */ { usb_host_ptr->ACTIVE_INTERRUPT_PERIODIC_LIST_PTR = NULL; } if (QH_ptr != NULL) { _usb_hci_vusb20_free_QH(handle, (pointer) QH_ptr); } return; }
/**************************************************************************//*! * * @name USB_Class_CDC_Init * * @brief The funtion initializes the Device and Controller layer * * @param *cdc_config_ptr[IN]: This structure contians configuration parameter * send by APP to configure CDC class. * * @return status * USB_OK : When Successfull * Others : Errors ****************************************************************************** * *This function initializes the CDC Class layer and layers it is dependednt on * *****************************************************************************/ uint_32 USB_Class_CDC_Init ( CDC_CONFIG_STRUCT_PTR cdc_config_ptr ) { #if IMPLEMENT_QUEUING uint_8 index; #endif uint_8 error; CDC_HANDLE cdc_handle; CDC_DEVICE_STRUCT_PTR devicePtr = NULL; USB_ENDPOINTS *usb_ep_data; if (NULL == (void *)cdc_config_ptr) return USBERR_ERROR; devicePtr = (CDC_DEVICE_STRUCT_PTR)USB_mem_alloc_zero(sizeof(CDC_DEVICE_STRUCT)); if (NULL == devicePtr) { #if _DEBUG printf("memalloc failed in USB_Class_CDC_Init\n"); #endif return USBERR_ALLOC; } cdc_handle = USB_Cdc_Allocate_Handle(); if (USBERR_DEVICE_BUSY == cdc_handle) { USB_mem_free(devicePtr); devicePtr = NULL; return USBERR_INIT_FAILED; } /* initialize the Global Variable Structure */ USB_mem_zero(devicePtr, sizeof(CDC_DEVICE_STRUCT)); devicePtr->ep = cdc_config_ptr->ep; usb_ep_data = cdc_config_ptr->usb_ep_data; devicePtr->max_supported_interfaces = cdc_config_ptr->max_supported_interfaces; #if RNDIS_SUPPORT USB_mem_copy(cdc_config_ptr->mac_address, devicePtr->mac_address, sizeof(_enet_address)); devicePtr->ip_address = cdc_config_ptr->ip_address; devicePtr->rndis_max_frame_size = cdc_config_ptr->rndis_max_frame_size; #endif /* Initialize the device layer*/ error = _usb_device_init(USBCFG_DEFAULT_DEVICE_CONTROLLER, &devicePtr->controller_handle, (uint_8)(usb_ep_data->count+1)); /* +1 is for Control Endpoint */ if(error != USB_OK) { goto error1; } cdc_config_ptr->desc_callback_ptr->handle = cdc_handle; /* Initialize the generic class functions */ devicePtr->class_handle = USB_Class_Init(devicePtr->controller_handle, USB_Class_CDC_Event,USB_CDC_Other_Requests,(void *)devicePtr, cdc_config_ptr->desc_callback_ptr); /* Initialize the generic class functions */ #if PSTN_SUBCLASS_NOTIF_SUPPORT /* Initialize the pstn subclass functions */ error = USB_Pstn_Init(devicePtr,&cdc_config_ptr->param_callback); if(error != USB_OK) { goto error2; } #endif devicePtr->usb_ep_data = usb_ep_data; #if IMPLEMENT_QUEUING for(index = 0; index < usb_ep_data->count; index++) { devicePtr->ep[index].endpoint = usb_ep_data->ep[index].ep_num; devicePtr->ep[index].type = usb_ep_data->ep[index].type; devicePtr->ep[index].bin_consumer = 0x00; devicePtr->ep[index].bin_producer = 0x00; } #endif /* save the callback pointer */ devicePtr->cdc_class_cb.callback = cdc_config_ptr->cdc_class_cb.callback; devicePtr->cdc_class_cb.arg = cdc_config_ptr->cdc_class_cb.arg; /* save the callback pointer */ devicePtr->vendor_req_callback.callback = cdc_config_ptr->vendor_req_callback.callback; devicePtr->vendor_req_callback.arg = cdc_config_ptr->vendor_req_callback.arg; /* save the callback pointer */ devicePtr->param_callback.callback = cdc_config_ptr->param_callback.callback; devicePtr->param_callback.arg = cdc_config_ptr->param_callback.arg; devicePtr->comm_feature_data_size = cdc_config_ptr->comm_feature_data_size; devicePtr->cic_send_endpoint = cdc_config_ptr->cic_send_endpoint; devicePtr->cic_recv_endpoint = USB_CONTROL_ENDPOINT; devicePtr->dic_send_endpoint = cdc_config_ptr->dic_send_endpoint; devicePtr->dic_recv_endpoint = cdc_config_ptr->dic_recv_endpoint; devicePtr->dic_recv_pkt_size = cdc_config_ptr->dic_recv_pkt_size; devicePtr->dic_send_pkt_size = cdc_config_ptr->dic_send_pkt_size; devicePtr->cic_send_pkt_size = cdc_config_ptr->cic_send_pkt_size; devicePtr->cdc_handle = cdc_handle; cdc_device_array[cdc_handle] = devicePtr; return cdc_handle; error2: /* Implement Denit class and invoke here*/ error1: USB_Cdc_Free_Handle(cdc_handle); USB_mem_free(devicePtr); devicePtr = NULL; return error; }
/*FUNCTION*---------------------------------------------------------------- * * Function Name : usb_dev_list_attach_device * Returned Value : * Comments : * This function will be called when attach interrupt happens, to * add onto the device list and do common initialization. * *END*--------------------------------------------------------------------*/ USB_STATUS usb_dev_list_attach_device ( _usb_host_handle handle, uint_8 speed, uint_8 hub_no, uint_8 port_no ) { /* Body */ USB_STATUS status; DEV_INSTANCE_PTR dev_instance_ptr; PIPE_INIT_PARAM_STRUCT ctrl_pipe_init_params; USB_HOST_STATE_STRUCT_PTR usb_host_ptr; DEV_INSTANCE_PTR device_root = NULL; usb_host_ptr = (USB_HOST_STATE_STRUCT_PTR)handle; /* Allocate new device instance */ dev_instance_ptr = (DEV_INSTANCE_PTR) USB_mem_alloc_word_aligned(sizeof(DEV_INSTANCE)); if (dev_instance_ptr == NULL) { return USBERR_GET_MEMORY_FAILED; } /* EndIf */ memset(dev_instance_ptr, 0, sizeof(DEV_INSTANCE)); dev_instance_ptr->host = handle; dev_instance_ptr->speed = speed; dev_instance_ptr->hub_no = hub_no; dev_instance_ptr->port_no = port_no; dev_instance_ptr->cfg_value = 0; /* We don't know yet what the ** device's default configuration is */ USB_lock(); /* Insert instance in pushdown list of devices */ dev_instance_ptr->next = (DEV_INSTANCE_PTR)usb_host_ptr->DEVICE_LIST_PTR; /* existing list */ usb_host_ptr->DEVICE_LIST_PTR = (pointer)dev_instance_ptr; /* root = new device */ device_root = dev_instance_ptr; /* Find unused address from 1 - 127 for this host */ device_root->address = 1; do { dev_instance_ptr = device_root->next; /* 2nd device, if any */ while (dev_instance_ptr != NULL) { /* step through list */ if (device_root->address == dev_instance_ptr->address) { device_root->address++; break; } /* EndIf */ dev_instance_ptr = dev_instance_ptr->next; } /* EndWhile */ } while ((dev_instance_ptr != NULL) && (device_root->address <= 127)); dev_instance_ptr = device_root; /* If all 127 addresses used up, delete instance & bail out */ if (dev_instance_ptr->address > 127) { usb_host_ptr->DEVICE_LIST_PTR = (pointer)\ dev_instance_ptr->next; /* pop off list */ USB_unlock(); USB_mem_free((pointer)dev_instance_ptr); return USBERR_ADDRESS_ALLOC_FAILED; } /* EndIf */ USB_unlock(); /*-----------------------------------------------------------** ** Open control pipe, get first 8 bytes of device descriptor ** ** The host_ch9 routine internally sets the callback to ** ** usb_host_cntrl_transaction_done (in usb_host_ch9.c) ** ** where the action resumes on completion of the get. ** **-----------------------------------------------------------*/ ctrl_pipe_init_params = pipe_init_params_prototype; ctrl_pipe_init_params.DEV_INSTANCE = dev_instance_ptr; ctrl_pipe_init_params.PIPETYPE = USB_CONTROL_PIPE; ctrl_pipe_init_params.SPEED = dev_instance_ptr->speed; if (USB_OK != _usb_host_open_pipe(dev_instance_ptr->host, &ctrl_pipe_init_params, &dev_instance_ptr->control_pipe)) { USB_mem_free((pointer)dev_instance_ptr); return USBERR_PIPE_OPENED_FAILED; } /* Endif */ /* Set state to enter after transaction completion */ dev_instance_ptr->state = DEVSTATE_DEVDESC8; status = _usb_host_ch9_get_descriptor((pointer)dev_instance_ptr, USB_DESC_TYPE_DEV << 8, 0, 8, (uchar_ptr)&dev_instance_ptr->dev_descriptor); if (status != USB_STATUS_TRANSFER_QUEUED) { dev_instance_ptr->state = DEVSTATE_INITIAL; return USBERR_NO_DESCRIPTOR; } return USB_OK; } /* EndBody */
/*FUNCTION*---------------------------------------------------------------- * * Function Name : usb_host_hub_device_event * Returned Value : None * Comments : * called when a hub has been attached, detached, etc. *END*--------------------------------------------------------------------*/ void usb_host_hub_device_event ( /* [IN] pointer to device instance */ _usb_device_instance_handle dev_handle, /* [IN] pointer to interface descriptor */ _usb_interface_descriptor_handle intf_handle, /* [IN] code number for event causing callback */ uint_32 event_code ) { HUB_DEVICE_STRUCT_PTR hub_instance; switch (event_code) { case USB_CONFIG_EVENT: /* Drop through into attach, same processing */ case USB_ATTACH_EVENT: /* Create 'unsafe' application struct */ if (NULL != (hub_instance = USB_mem_alloc_zero(sizeof(HUB_DEVICE_STRUCT)))) { _usb_hostdev_select_interface(dev_handle, intf_handle, (pointer)&hub_instance->CCS); } break; case USB_INTF_EVENT: if (USB_OK != usb_class_hub_get_app(dev_handle, intf_handle, (CLASS_CALL_STRUCT_PTR *) &hub_instance)) break; /* set we are in process of getting hub descriptor */ hub_instance->STATE = HUB_GET_DESCRIPTOR_TINY_PROCESS; /* here, we should retrieve information from the hub */ usb_class_hub_get_descriptor(&hub_instance->CCS, (tr_callback) usb_host_hub_device_sm, (pointer) hub_instance, 7); break; case USB_DETACH_EVENT: { DEV_INSTANCE_PTR dev_ptr; _mqx_int i; if (USB_OK != usb_class_hub_get_app(dev_handle, intf_handle, (CLASS_CALL_STRUCT_PTR *) &hub_instance)) break; dev_ptr = (DEV_INSTANCE_PTR) dev_handle; /* detach all the devices connected to all the ports of found hub */ for (i = 0; i < hub_instance->HUB_PORT_NR; i++) { if ((hub_instance->HUB_PORTS + i)->APP_STATUS & HUB_PORT_ATTACHED) /* We will access dev_ptr without validation process (usb_hostdev_validate), because ** USB_DETACH_EVENT is synced call, so we can do that. dev_ptr is still valid pointer to device. */ usb_dev_list_detach_device(dev_ptr->host, dev_ptr->address, i + 1); } if (hub_instance->HUB_PORTS != NULL) USB_mem_free(hub_instance->HUB_PORTS); } break; default: break; } /* EndSwitch */ } /* Enbbody */
/*FUNCTION*---------------------------------------------------------------- * * Function Name : usb_dev_list_detach_device * Returned Value : * Comments : * This function will be called when detach interrupt happens. * *END*--------------------------------------------------------------------*/ void usb_dev_list_detach_device ( _usb_host_handle handle, uint_8 hub_no, uint_8 port_no ) { /* Body */ USB_HOST_STATE_STRUCT_PTR usb_host_ptr = (USB_HOST_STATE_STRUCT_PTR)handle; DEV_INSTANCE_PTR dev_instance_ptr; DEV_INSTANCE_PTR _PTR_ device_root = (DEV_INSTANCE_PTR _PTR_)&usb_host_ptr->DEVICE_LIST_PTR; #ifdef __USB_OTG__ uint_32 state; #endif #ifdef _HOST_DEBUG_ DEBUG_LOG_TRACE("usb_dev_list_detach_device"); #endif /* search device list for the one being detached */ USB_lock(); for (dev_instance_ptr = *device_root; dev_instance_ptr != NULL; dev_instance_ptr = dev_instance_ptr->next) { if (dev_instance_ptr->port_no != port_no) continue; if (dev_instance_ptr->hub_no != hub_no) continue; if (dev_instance_ptr->host != handle) continue; break; } /* EndFor */ USB_unlock(); if (dev_instance_ptr == NULL) { #ifdef _HOST_DEBUG_ DEBUG_LOG_TRACE("usb_dev_list_detach_device NULL device pointer"); #endif return; /* No match, abandon ship! */ } /* Endif */ /* SGarg 09/23/2003 . Sometimes a detach could come even before a attach is finished. This means that we should make sure that device memory is not NULL before we try to clean it up. For example this happens with OPT tester test 4.10.*/ if(dev_instance_ptr->memlist != NULL) { /* Notify the application of unavailable interfaces */ usb_hostdev_attach_detach(dev_instance_ptr, USB_DETACH_EVENT); } /* Unlink device from the instance list */ dev_instance_ptr->control_callback = NULL; /* no surprises */ /* Close control pipe */ usb_dev_list_close_pipe(handle, (PIPE_STRUCT_PTR)dev_instance_ptr->control_pipe); /* SGarg 09/24/2003 . Sometimes a detach could come even before a attach is finished. This means that we should make sure that device memory is not NULL before we try to clean it up. For example this happens with OPT tester test 4.10.*/ if(dev_instance_ptr->memlist != NULL) { usb_dev_list_free_memlist((_usb_device_instance_handle)dev_instance_ptr); } USB_lock(); /* Find the address of the "pointer to the detached device" */ while (*device_root != dev_instance_ptr) { device_root = &(*device_root)->next; } /* Endwhile */ /* Remove the device */ *device_root = dev_instance_ptr->next; USB_mem_free(dev_instance_ptr); #ifdef __USB_OTG__ _usb_otg_get_status((pointer)usb_otg_state_struct_ptr, USB_OTG_STATE, &state); if (state < B_IDLE) { _usb_otg_get_status((pointer)usb_otg_state_struct_ptr, USB_OTG_B_CONN, &state); if (state) { _usb_otg_set_status((pointer)usb_otg_state_struct_ptr, USB_OTG_B_CONN, FALSE); } /* Endif */ } else { _usb_otg_get_status((pointer)usb_otg_state_struct_ptr, USB_OTG_A_CONN, &state); if (state) { _usb_otg_set_status((pointer)usb_otg_state_struct_ptr, USB_OTG_A_CONN, FALSE); } /* Endif */ } /* Endif */ #endif USB_unlock(); #ifdef _HOST_DEBUG_ DEBUG_LOG_TRACE("usb_dev_list_detach_device SUCCESSFUL"); #endif } /* EndBody */
/*FUNCTION*---------------------------------------------------------------- * * Function Name : usb_dev_list_attach_device * Returned Value : * Comments : * This function will be called when attach interrupt happens, to * add onto the device list and do common initialization. * *END*--------------------------------------------------------------------*/ USB_STATUS usb_dev_list_attach_device ( _usb_host_handle handle, uint_8 speed, uint_8 hub_no, uint_8 port_no ) { /* Body */ USB_STATUS status; DEV_INSTANCE_PTR new_instance_ptr, dev_instance_ptr, dev_instance_prev_ptr; PIPE_INIT_PARAM_STRUCT ctrl_pipe_init_params; USB_HOST_STATE_STRUCT_PTR usb_host_ptr; DEV_INSTANCE_PTR device_root = NULL; #ifdef __USB_OTG__ uint_32 state; #endif #ifdef _HOST_DEBUG_ DEBUG_LOG_TRACE("usb_dev_list_attach_device attach device"); #endif usb_host_ptr = (USB_HOST_STATE_STRUCT_PTR)handle; /* Allocate new device instance */ new_instance_ptr = (DEV_INSTANCE_PTR) USB_mem_alloc_uncached(sizeof(DEV_INSTANCE)); if (new_instance_ptr == NULL) { #ifdef _HOST_DEBUG_ DEBUG_LOG_TRACE("usb_dev_list_attach_device failed to malloc device handle"); #endif return USB_log_error(__FILE__,__LINE__, USBERR_GET_MEMORY_FAILED); } /* EndIf */ _mem_set_type(new_instance_ptr, MEM_TYPE_USB_HOST_STATE_STRUCT); USB_mem_zero(new_instance_ptr, sizeof(DEV_INSTANCE)); new_instance_ptr->host = handle; new_instance_ptr->speed = speed; new_instance_ptr->hub_no = hub_no; new_instance_ptr->port_no = port_no; new_instance_ptr->cfg_value = 0; /* We don't know yet what the device's default configuration is */ USB_lock(); /* Find unused address from 1 - 127 for this host */ dev_instance_ptr = usb_host_ptr->DEVICE_LIST_PTR; if ((dev_instance_ptr == NULL) || (dev_instance_ptr->address != 1)) { /* Insert at the beginning of list */ new_instance_ptr->address = 1; new_instance_ptr->next = dev_instance_ptr; usb_host_ptr->DEVICE_LIST_PTR = new_instance_ptr; } else { dev_instance_prev_ptr = dev_instance_ptr; /* Searching for a 'hole' in devices instance adresses */ while (dev_instance_ptr->address <= (dev_instance_prev_ptr->address + 1)) { new_instance_ptr->address = dev_instance_ptr->address; dev_instance_prev_ptr = dev_instance_ptr; dev_instance_ptr = dev_instance_ptr->next; if (dev_instance_ptr == NULL) break; } /* EndWhile */ if (new_instance_ptr->address >= 127) { /* If all 127 addresses used up, delete instance & bail out */ USB_unlock(); USB_mem_free((pointer)new_instance_ptr); #ifdef _HOST_DEBUG_ DEBUG_LOG_TRACE("usb_dev_list_attach_device out of addresses"); #endif return USB_log_error(__FILE__,__LINE__, USBERR_ADDRESS_ALLOC_FAILED); } /* EndIf */ new_instance_ptr->address++; new_instance_ptr->next = dev_instance_ptr; dev_instance_prev_ptr->next = new_instance_ptr; }; USB_unlock(); /*-----------------------------------------------------------** ** Open control pipe, get first 8 bytes of device descriptor ** ** The host_ch9 routine internally sets the callback to ** ** usb_host_cntrl_transaction_done (in usb_host_ch9.c) ** ** where the action resumes on completion of the get. ** **-----------------------------------------------------------*/ ctrl_pipe_init_params = pipe_init_params_prototype; ctrl_pipe_init_params.G.DEV_INSTANCE = new_instance_ptr; ctrl_pipe_init_params.G.PIPETYPE = USB_CONTROL_PIPE; ctrl_pipe_init_params.G.SPEED = new_instance_ptr->speed; ctrl_pipe_init_params.G.HUB_DEVICE_ADDR = hub_no; ctrl_pipe_init_params.G.HUB_PORT_NUM = port_no; #ifdef __USB_OTG__ _usb_otg_get_status((pointer)usb_otg_state_struct_ptr, USB_OTG_STATE, &state); if (state < B_IDLE) { _usb_otg_set_status((pointer)usb_otg_state_struct_ptr, USB_OTG_A_BUS_REQ, TRUE); _usb_otg_set_status((pointer)usb_otg_state_struct_ptr, USB_OTG_B_CONN, TRUE); } else { _usb_otg_set_status((pointer)usb_otg_state_struct_ptr, USB_OTG_A_CONN, TRUE); } /* Endif */ #endif if (USB_OK != _usb_host_open_pipe(new_instance_ptr->host, &ctrl_pipe_init_params, &new_instance_ptr->control_pipe)) { USB_mem_free((pointer)new_instance_ptr); #ifdef _HOST_DEBUG_ DEBUG_LOG_TRACE("usb_dev_list_attach_device open pipe failed"); #endif return USB_log_error(__FILE__,__LINE__, USBERR_PIPE_OPENED_FAILED); } /* Endif */ /* Set state to enter after transaction completion */ new_instance_ptr->state = DEVSTATE_DEVDESC8; status = _usb_host_ch9_get_descriptor((_usb_device_instance_handle)new_instance_ptr, USB_DESC_TYPE_DEV << 8, 0, 8, (uchar_ptr)&new_instance_ptr->dev_descriptor); if (status != USB_STATUS_TRANSFER_QUEUED) { new_instance_ptr->state = DEVSTATE_INITIAL; #ifdef _HOST_DEBUG_ DEBUG_LOG_TRACE("usb_dev_list_attach_device FAILED"); #endif return USB_log_error(__FILE__,__LINE__, USBERR_NO_DESCRIPTOR); } #ifdef _HOST_DEBUG_ DEBUG_LOG_TRACE("usb_dev_list_attach_device SUCCESSFUL"); #endif return USB_OK; } /* EndBody */
/****************************************************************************** * * @name Bridge_Callback * * @brief This function handles the callback * * @param None * * @return None * *****************************************************************************/ void Bridge_Callback(uint_8 event_type,void* val,pointer arg) { switch(event_type) { case BRDIGE_DATA_RECEIVED: { PTR_USB_APP_EVENT_DATA_RECIEVED data_recv_ptr = (PTR_USB_APP_EVENT_DATA_RECIEVED)val; (void)USB_Class_PHDC_Send_Data (g_bridge.handle, FALSE, 0, SEND_DATA_QOS, data_recv_ptr->buffer_ptr, data_recv_ptr->size); if(g_hdr_flag == TRUE) { g_bridge_rx_size = (uint_32)(*((uint_16_ptr)data_recv_ptr->buffer_ptr + 1)) + APDU_HEADER_SIZE - data_recv_ptr->size; /*data yet to be received */ if(g_bridge_rx_size) { /* call for more data to recv on BRidge */ g_hdr_flag = FALSE; if(_lwevent_set(&lwevent,BRIDGE_RECV_EVENT) != MQX_OK) { #if _DEBUG printf("BRDIGE_DATA_RECEIVED: Set Event failed : Bridge_Callback\n"); #endif _task_block(); } } else if(!(data_recv_ptr->size % PHDC_BULK_IN_EP_SIZE)) { /* Entire data was received in one transaction but its mutiple of PHDC_BULK_IN_EP_SIZE, therefore, need to send zero byte data */ (void)USB_Class_PHDC_Send_Data (g_bridge.handle, FALSE, 0, SEND_DATA_QOS, data_recv_ptr->buffer_ptr, 0); /* buffer pointer is immaterial in this case */ } } else { g_bridge_rx_size -= data_recv_ptr->size; if((!g_bridge_rx_size)&&((!(data_recv_ptr->size % PHDC_BULK_IN_EP_SIZE)))) { /* entire data frrom bridge has been received and last transaction was multiple of PHDC_BULK_IN_EP_SIZE, therfore need to send zero byte data */ (void)USB_Class_PHDC_Send_Data (g_bridge.handle, FALSE, 0, SEND_DATA_QOS, data_recv_ptr->buffer_ptr, 0); /* buffer pointer is immaterial in this case */ g_hdr_flag = TRUE; } else if(data_recv_ptr->size < PHDC_BULK_IN_EP_SIZE) { /* Short packet */ g_hdr_flag = TRUE; } else { /* there is more data to recv from Bridge Interface */ if(_lwevent_set(&lwevent,BRIDGE_RECV_EVENT) != MQX_OK) { #if _DEBUG printf("BRDIGE_DATA_RECEIVED: Set Event failed : Bridge_Callback\n"); #endif _task_block(); } } } } break; case BRDIGE_DATA_SEND : { PTR_USB_APP_EVENT_DATA_RECIEVED data_send_ptr = (PTR_USB_APP_EVENT_DATA_RECIEVED)val; USB_mem_free(data_send_ptr->buffer_ptr); /* Queue another recv on USB BUS */ (void)USB_Class_PHDC_Recv_Data(g_bridge.handle, PHDC_BULK_OUT_QOS, g_usb_rx_buff_ptr, PHDC_BULK_OUT_EP_SIZE); } break; case BRIDGE_CONNECTION_ESTABLISHED : g_connection_present = TRUE; if(_lwevent_set(&lwevent,BRIDGE_RECV_EVENT) != MQX_OK) { #if _DEBUG printf("BRIDGE_CONNECTION_ESTABLISHED: Set Event failed : Bridge_Callback\n"); #endif _task_block(); } break; case BRIDGE_CONNECTION_TERMINATED : g_connection_present = FALSE; if(g_bridge.usb_enum_complete == TRUE) { /* this if condition prevents call of send data when USB INTERFACE is absent */ (void)USB_Class_PHDC_Send_Data (g_bridge.handle, FALSE, 0, SEND_DATA_QOS, abort_msg, ABORT_MESSAGE_SIZE); } break; } return; }
USB_STATUS _usb_host_init ( /* [IN] address if the callback functions structure */ struct usb_host_if_struct *usb_if, /* [OUT] the USB host handle */ _usb_host_handle _PTR_ handle ) { /* Body */ USB_STATUS error; USB_HOST_IF_STRUCT_PTR usb_c; USB_HOST_CALLBACK_FUNCTIONS_STRUCT_PTR host_if; USB_HOST_STATE_STRUCT_PTR usb_host_ptr = NULL; _mqx_int i; #ifdef _HOST_DEBUG_ DEBUG_LOG_TRACE("_usb_host_init"); #endif /* Check usb_if structure */ if (usb_if == NULL) { #ifdef _HOST_DEBUG_ DEBUG_LOG_TRACE("_usb_host_init no interface given"); #endif return USB_log_error(__FILE__,__LINE__,USBERR_DEVICE_NOT_FOUND); } if (usb_if->HOST_IF == NULL) { /* The interface does not support host functionality */ #ifdef _HOST_DEBUG_ DEBUG_LOG_TRACE("_usb_host_init interface not supporting host"); #endif return USB_log_error(__FILE__,__LINE__,USBERR_DEVICE_NOT_FOUND); } USB_lock(); usb_c = _mqx_get_io_component_handle(IO_USB_COMPONENT); /* Check if the interface is registered */ if (!usb_c) { /* No interface was registered yet */ USB_unlock(); #ifdef _HOST_DEBUG_ DEBUG_LOG_TRACE("_usb_host_init no interface registered"); #endif return USB_log_error(__FILE__,__LINE__,USBERR_DEVICE_NOT_FOUND); } else { /* Find out if the interface has been installed */ for (i = 0; i < USBCFG_MAX_DRIVERS; i++) { if (usb_c[i].HOST_INIT_PARAM == usb_if->HOST_INIT_PARAM) { /* Found installed device */ break; } } } if (i == USBCFG_MAX_DRIVERS) { /* The interface has not been registered, so it cannot be initialized */ USB_unlock(); #ifdef _HOST_DEBUG_ DEBUG_LOG_TRACE("_usb_host_init not installed"); #endif return USB_log_error(__FILE__,__LINE__,USBERR_DEVICE_NOT_FOUND); } else { /* check if the registered interface was already initialized */ if (usb_c[i].HOST_HANDLE != NULL) { /* The interface was already installed- return handle and USBERR_DEVICE_BUSY value */ *handle = (_usb_host_handle) usb_c[i].HOST_HANDLE; USB_unlock(); #ifdef _HOST_DEBUG_ DEBUG_LOG_TRACE("_usb_host_init already initialized - returning handle"); #endif return USBERR_DEVICE_BUSY; } } host_if = (USB_HOST_CALLBACK_FUNCTIONS_STRUCT_PTR) usb_c[i].HOST_IF; /* Initialize the USB interface. */ if (host_if->HOST_PREINIT != NULL) { error = host_if->HOST_PREINIT((_usb_host_handle _PTR_) &usb_host_ptr); } if (error || usb_host_ptr == NULL || usb_host_ptr->PIPE_DESCRIPTOR_BASE_PTR == NULL) { #ifdef _HOST_DEBUG_ DEBUG_LOG_TRACE("_usb_host_init preinit failure"); #endif return USB_log_error(__FILE__,__LINE__,USBERR_ALLOC); } /* Endif */ usb_host_ptr->CALLBACK_STRUCT_PTR = usb_c[i].HOST_IF; usb_host_ptr->INIT_PARAM = usb_c[i].HOST_INIT_PARAM; _mem_set_type(usb_host_ptr, MEM_TYPE_USB_HOST_STATE_STRUCT); _mem_set_type(usb_host_ptr->PIPE_DESCRIPTOR_BASE_PTR, MEM_TYPE_USB_HOST_PIPE_DESCRIPTORS); /* No devices attached yet */ /* ** We should maintain device lists per controller handle */ usb_host_ptr->DEVICE_LIST_PTR = NULL; usb_host_ptr->FRAME_LIST_SIZE = 1024; #if (USBCFG_HOST_NUM_ISO_PACKET_DESCRIPTORS != 0) error = _usb_host_iso_packet_desc_pool_create(USBCFG_HOST_NUM_ISO_PACKET_DESCRIPTORS); if (error != USB_OK) { USB_mem_free(usb_host_ptr->PIPE_DESCRIPTOR_BASE_PTR); USB_mem_free(usb_host_ptr); USB_unlock(); #ifdef _HOST_DEBUG_ DEBUG_LOG_TRACE("_usb_host_init: isochronous packet descriptor pool allocation failure"); #endif return USB_log_error(__FILE__,__LINE__,USBERR_ALLOC); } #endif error = _bsp_usb_host_init(&usb_c[i]); if (error != MQX_OK) { #if (USBCFG_HOST_NUM_ISO_PACKET_DESCRIPTORS != 0) _usb_host_iso_packet_desc_pool_destroy (); #endif USB_mem_free(usb_host_ptr->PIPE_DESCRIPTOR_BASE_PTR); USB_mem_free(usb_host_ptr); USB_unlock(); #ifdef _HOST_DEBUG_ DEBUG_LOG_TRACE("_usb_host_init: BSP-specific USB initialization failure"); #endif return USB_log_error(__FILE__,__LINE__,USBERR_UNKNOWN_ERROR); } error = _usb_host_init_call_interface(usb_host_ptr); USB_unlock(); if (error != USB_OK) { #if (USBCFG_HOST_NUM_ISO_PACKET_DESCRIPTORS != 0) _usb_host_iso_packet_desc_pool_destroy (); #endif USB_mem_free(usb_host_ptr->PIPE_DESCRIPTOR_BASE_PTR); USB_mem_free(usb_host_ptr); #ifdef _HOST_DEBUG_ DEBUG_LOG_TRACE("_usb_host_init returning error status"); #endif return USB_log_error(__FILE__,__LINE__,error); } /* Endif */ usb_c[i].HOST_HANDLE = *handle = (pointer)usb_host_ptr; #ifdef _HOST_DEBUG_ DEBUG_LOG_TRACE("_usb_host_init SUCCESSFULL"); #endif return USB_OK; } /* Endbody */
void Main_Task ( uint_32 param ) { /* Body */ USB_STATUS status = USB_OK; _int_disable(); _int_install_unexpected_isr(); status = _usb_host_driver_install(HOST_CONTROLLER_NUMBER, (pointer)&_bsp_usb_host_callback_table); if (status) { _int_enable(); printf("ERROR: %ls", status); exit(1); } /* Endif */ status = _usb_host_init (HOST_CONTROLLER_NUMBER, /* Use value in header file */ MAX_FRAME_SIZE, /* Frame size per USB spec */ &host_handle); /* Returned pointer */ if (status != USB_OK) { _int_enable(); printf("\nUSB Host Initialization failed. STATUS: %x", status); fflush(stdout); goto Error_Cleanup; } /* Endif */ /* ** Since we are going to act as the host driver, register ** the driver information for wanted class/subclass/protocols */ status = _usb_host_driver_info_register(host_handle, DriverInfoTable); if (status != USB_OK) { _int_enable(); printf("\nDriver Registration failed. STATUS: %x", status); fflush(stdout); goto Error_Cleanup; } _int_enable(); pCmd = (COMMAND_OBJECT_PTR) USB_mem_alloc_zero(sizeof(COMMAND_OBJECT_STRUCT)); if (pCmd == NULL) { printf ("\nUnable to allocate Command Object"); fflush (stdout); goto Error_Cleanup; } pCmd->CBW_PTR = (CBW_STRUCT_PTR) USB_mem_alloc_zero(sizeof(CBW_STRUCT)); if (pCmd->CBW_PTR == NULL) { printf ("\nUnable to allocate Command Block Wrapper"); fflush (stdout); goto Error_Cleanup; } pCmd->CSW_PTR = (CSW_STRUCT_PTR) USB_mem_alloc_zero(sizeof(CSW_STRUCT)); if (pCmd->CSW_PTR == NULL) { printf ("\nUnable to allocate Command Status Wrapper"); fflush (stdout); goto Error_Cleanup; } buff_in = (uchar_ptr)USB_mem_alloc_uncached(0x400C); if (buff_in == NULL) { printf ("\nUnable to allocate Input Buffer"); fflush (stdout); goto Error_Cleanup; } _mem_zero(buff_in, 0x400C); buff_out = (uchar_ptr) USB_mem_alloc_uncached(0x0F); if (buff_out == NULL) { printf ("\nUnable to allocate Output Buffer"); fflush (stdout); goto Error_Cleanup; } _mem_zero(buff_out, 0x0F); printf("\nPlease insert Mass Storage Device.\n"); /*----------------------------------------------------** ** Infinite loop, waiting for events requiring action ** **----------------------------------------------------*/ for ( ; ; ) { switch ( mass_device.dev_state ) { case USB_DEVICE_IDLE: break ; case USB_DEVICE_ATTACHED: printf( "Mass Storage Device Attached\n" ); fflush(stdout); mass_device.dev_state = USB_DEVICE_SET_INTERFACE_STARTED; status = _usb_hostdev_select_interface(mass_device.dev_handle, mass_device.intf_handle, (pointer)&mass_device.class_intf); break ; case USB_DEVICE_SET_INTERFACE_STARTED: break; case USB_DEVICE_INTERFACED: usb_host_mass_test_storage(); mass_device.dev_state = USB_DEVICE_OTHER; break ; case USB_DEVICE_DETACHED: printf ( "\nMass Storage Device Detached\n" ); fflush(stdout); mass_device.dev_state = USB_DEVICE_IDLE; break; case USB_DEVICE_OTHER: break ; default: printf ( "Unknown Mass Storage Device State = %d\n",\ mass_device.dev_state ); fflush(stdout); break ; } /* Endswitch */ } /* Endfor */ Error_Cleanup: { if (pCmd != NULL) { if (pCmd->CSW_PTR != NULL) { USB_mem_free(pCmd->CSW_PTR); } if (pCmd->CBW_PTR != NULL) { USB_mem_free(pCmd->CBW_PTR); } USB_mem_free(pCmd); } if (buff_in != NULL) { USB_mem_free(buff_in); } if (buff_out != NULL) { USB_mem_free(buff_out); } if (host_handle != NULL) { _usb_host_shutdown (host_handle); } } } /* Endbody */
/*FUNCTION*---------------------------------------------------------------- * * Function Name : usb_dev_list_free_mem * Returned Value : USB_OK if memory is freed, else error code * Comments : * Memory is unlinked and freed from dev_ptr->memlist * *END*--------------------------------------------------------------------*/ USB_STATUS usb_dev_list_free_mem ( /* [IN] Pointer to the USB device */ DEV_INSTANCE_PTR dev_ptr, /* [IN] Pointer to memory */ DEV_MEMORY_PTR header_ptr ) { /* Body */ DEV_MEMORY_PTR mem_ptr, list_ptr; DEV_MEMORY_PTR prev_ptr = NULL; USB_STATUS error; #ifdef _HOST_DEBUG_ DEBUG_LOG_TRACE("usb_dev_list_free_mem"); #endif USB_lock(); error = usb_hostdev_validate((_usb_device_instance_handle)dev_ptr); USB_unlock(); if (error != USB_OK) { #ifdef _HOST_DEBUG_ DEBUG_LOG_TRACE("usb_dev_list_free_mem invalid device handle"); #endif return USB_log_error(__FILE__,__LINE__,error); } mem_ptr = (DEV_MEMORY_PTR) header_ptr; if (mem_ptr == NULL) { #ifdef _HOST_DEBUG_ DEBUG_LOG_TRACE("usb_dev_list_free_mem invalid memory pointer"); #endif return USB_log_error(__FILE__,__LINE__,USBERR_INVALID_MEM_TYPE); } /* Endif */ for (list_ptr = dev_ptr->memlist; list_ptr != NULL; list_ptr = list_ptr->next) { if (list_ptr == mem_ptr) break; prev_ptr = list_ptr; } if (list_ptr == NULL) { #ifdef _HOST_DEBUG_ DEBUG_LOG_TRACE("usb_dev_list_free_mem not found"); #endif return USB_log_error(__FILE__,__LINE__,USBERR_NOT_FOUND); } /* Unlink the buffer from the list */ if (dev_ptr->memlist == mem_ptr) { /* Unlink from anchor */ /* WARNING!!! The first buffer in the chain is the full configuration descriptor, ** so there is probably some issue if there is attempt to free it, because ** configuration descriptor must have its lifetime till the device's detach or ** till selecting another configuration. */ dev_ptr->memlist = mem_ptr->next; } else { if(prev_ptr != NULL) { /* Unlink from chain */ prev_ptr->next = mem_ptr->next; } } /* Free associated memory */ USB_mem_free(mem_ptr); #ifdef _HOST_DEBUG_ DEBUG_LOG_TRACE("usb_dev_list_free_mem SUCCESSFUL"); #endif return USB_OK; } /* Endbody */
/*FUNCTION*---------------------------------------------------------------- * * Function Name : usb_dev_list_detach_device * Returned Value : * Comments : * This function will be called when detach interrupt happens. * *END*--------------------------------------------------------------------*/ void usb_dev_list_detach_device ( _usb_host_handle handle, uint_8 hub_no, uint_8 port_no ) { /* Body */ USB_HOST_STATE_STRUCT_PTR usb_host_ptr = (USB_HOST_STATE_STRUCT_PTR)handle; DEV_INSTANCE_PTR dev_instance_ptr; DEV_INSTANCE_PTR _PTR_ device_root = (DEV_INSTANCE_PTR _PTR_)&usb_host_ptr->DEVICE_LIST_PTR; /* search device list for the one being detached */ USB_lock(); for (dev_instance_ptr = *device_root; dev_instance_ptr != NULL; dev_instance_ptr = dev_instance_ptr->next) { if (dev_instance_ptr->port_no != port_no) continue; if (dev_instance_ptr->hub_no != hub_no) continue; if (dev_instance_ptr->host != handle) continue; break; } /* EndFor */ USB_unlock(); if (dev_instance_ptr == NULL) { return; /* No match, abandon ship! */ } /* Endif */ /* SGarg 09/23/2003 . Sometimes a detach could come even before a attach is finished. This means that we should make sure that device memory is not NULL before we try to clean it up. For example this happens with OPT tester test 4.10.*/ if(dev_instance_ptr->memlist != NULL) { /* Notify the application of unavailable interfaces */ usb_hostdev_attach_detach(dev_instance_ptr, USB_DETACH_EVENT); } /* Unlink device from the instance list */ dev_instance_ptr->control_callback = NULL; /* no surprises */ /* Close control pipe */ usb_dev_list_close_pipe(handle, (PIPE_DESCRIPTOR_STRUCT_PTR)dev_instance_ptr->control_pipe); /* SGarg 09/24/2003 . Sometimes a detach could come even before a attach is finished. This means that we should make sure that device memory is not NULL before we try to clean it up. For example this happens with OPT tester test 4.10.*/ if(dev_instance_ptr->memlist != NULL) { usb_dev_list_free_memory((pointer)dev_instance_ptr); } USB_lock(); /* Find the address of the "pointer to the detached device" */ while (*device_root != dev_instance_ptr) { device_root = &(*device_root)->next; } /* Endwhile */ /* Remove the device */ *device_root = dev_instance_ptr->next; USB_mem_free(dev_instance_ptr); USB_unlock(); } /* EndBody */