static void _usb_device_cleanup(USB_DEV_STATE_STRUCT_PTR usb_dev_ptr) { /* Free all internal transfer descriptors */ if(usb_dev_ptr->XD_BASE != NULL) { USB_memfree((pointer)usb_dev_ptr->XD_BASE); } /* Free all XD scratch memory */ if(usb_dev_ptr->XD_SCRATCH_STRUCT_BASE != NULL) { USB_memfree((pointer)usb_dev_ptr->XD_SCRATCH_STRUCT_BASE); } /* Free the temp ep init XD */ if(usb_dev_ptr->TEMP_XD_PTR != NULL) { USB_memfree((pointer)usb_dev_ptr->TEMP_XD_PTR); } if(usb_dev_ptr->STATUS_UNAIGNED_PTR != NULL) USB_memfree((pointer)usb_dev_ptr->STATUS_UNAIGNED_PTR); if(usb_dev_ptr->TEST_PKT_UNAIGNED_PTR != NULL) USB_memfree((pointer)usb_dev_ptr->TEST_PKT_UNAIGNED_PTR); /* Free the USB state structure */ USB_memfree((pointer)usb_dev_ptr); }
/*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; #ifdef _HOST_DEBUG_ DEBUG_LOG_TRACE("usb_dev_list_free_memory"); DEBUGMSG(USB_DBG_LEVEL, ("usb_dev_list_free_memory\n")); #endif error = usb_hostdev_validate(dev_handle); if (error != USB_OK) #ifdef _HOST_DEBUG_ DEBUG_LOG_TRACE("usb_dev_list_free_memory invalid device handle"); #endif 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; list_ptr = mem_ptr->next; do { USB_memfree(mem_ptr); mem_ptr = list_ptr; list_ptr = mem_ptr->next; } while (mem_ptr != NULL); dev->memlist = NULL; USB_unlock(); #ifdef _HOST_DEBUG_ DEBUG_LOG_TRACE("usb_dev_list_free_memory SUCCESSFUL"); #endif return USB_OK; } /* 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*--------------------------------------------------------------------*/ uint_8 _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; int lockKey; usb_dev_ptr = (USB_DEV_STATE_STRUCT_PTR)handle; /* Needs mutual exclusion */ lockKey = 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(lockKey); USB_printf("_usb_device_unregister_service, no service found\n"); return USBERR_CLOSED_SERVICE; } /* Endif */ service_ptr = *search_ptr; *search_ptr = service_ptr->NEXT; USB_memfree((pointer)service_ptr); USB_unlock(lockKey); return USB_OK; } /* EndBody */
/*FUNCTION*------------------------------------------------------------- * * Function Name : _usb_device_shutdown * Returned Value : USB_OK or error code * Comments : * Shutdown an initialized USB device * *END*-----------------------------------------------------------------*/ void _usb_device_shutdown(_usb_device_handle handle) { /* Body */ USB_DEV_STATE_STRUCT_PTR usb_dev_ptr; SERVICE_STRUCT_PTR service_ptr; int ep; ARC_DEBUG_TRACE(ARC_DEBUG_FLAG_CTRL, "shutdown\n"); usb_dev_ptr = (USB_DEV_STATE_STRUCT_PTR)handle; for(ep=0; ep<(usb_dev_ptr->MAX_ENDPOINTS); ep++) { /* Cancel all transfers on all endpoints */ while(_usb_device_get_transfer_status(handle, ep, ARC_USB_RECV) != ARC_USB_STATUS_IDLE) { _usb_device_cancel_transfer(handle, ep, ARC_USB_RECV); } while(_usb_device_get_transfer_status(handle, ep, ARC_USB_SEND) != ARC_USB_STATUS_IDLE) { _usb_device_cancel_transfer(handle, ep, ARC_USB_SEND); } } _usb_dci_vusb20_shutdown(usb_dev_ptr); /* Free all the Callback function structure memory */ for( service_ptr = usb_dev_ptr->SERVICE_HEAD_PTR; service_ptr; service_ptr = service_ptr->NEXT) { USB_printf("_usb_device_shutdown: free service_ptr = 0x%x\n", service_ptr); USB_memfree(service_ptr); } usb_dev_ptr->SERVICE_HEAD_PTR = NULL; _usb_device_cleanup(usb_dev_ptr); } /* 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; // clean warning DEV_INSTANCE_PTR _PTR_ device_root = &(DEV_INSTANCE_PTR)usb_host_ptr->DEVICE_LIST_PTR; DEV_INSTANCE_PTR _PTR_ device_root; // clean warning uint_32 state; device_root = (DEV_INSTANCE_PTR _PTR_)(&usb_host_ptr->DEVICE_LIST_PTR); #ifdef _HOST_DEBUG_ DEBUG_LOG_TRACE("usb_dev_list_detach_device"); DEBUGMSG(USB_DBG_LEVEL, ("usb_dev_list_detach_device\n")); #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, 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_memfree(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*--------------------------------------------------------------------*/ void usb_dev_list_attach_device ( _usb_host_handle handle, uint_8 speed, uint_8 hub_no, uint_8 port_no ) { /* Body */ 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; // clean warning uint_32 state; #ifdef _HOST_DEBUG_ DEBUG_LOG_TRACE("usb_dev_list_attach_device attach device"); DEBUGMSG(USB_DBG_LEVEL, ("usb_dev_list_attach_device attach device\n")); #endif //DEBUGMSG(1,("d")); //DEBUGMSG(TTC_DBG_LEVEL,("usb_dev_list_attach_device attach device\r\n")); usb_host_ptr = (USB_HOST_STATE_STRUCT_PTR)handle; /* Allocate new device instance */ dev_instance_ptr = (DEV_INSTANCE_PTR)\ USB_Uncached_memalloc(sizeof(DEV_INSTANCE)); if (dev_instance_ptr == NULL) { #ifdef _HOST_DEBUG_ DEBUG_LOG_TRACE("usb_dev_list_attach_device failed to malloc device handle"); #endif //DEBUGMSG(TTC_DBG_LEVEL,("usb_dev_list_attach_device failed to malloc device handle\r\n")); return; } /* EndIf */ USB_memzero(dev_instance_ptr, 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 = 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_memfree((pointer)dev_instance_ptr); #ifdef _HOST_DEBUG_ DEBUG_LOG_TRACE("usb_dev_list_attach_device out of addresses"); #endif //DEBUGMSG(TTC_DBG_LEVEL,("usb_dev_list_attach_device out of addresses\r\n")); return; } /* 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; #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(dev_instance_ptr->host, &ctrl_pipe_init_params, &dev_instance_ptr->control_pipe)) { #ifdef _HOST_DEBUG_ DEBUG_LOG_TRACE("usb_dev_list_attach_device open pipe failed"); DEBUGMSG(USB_DBG_LEVEL, ("usb_dev_list_attach_device attach device open pipe failed\n")); #endif //DEBUGMSG(TTC_DBG_LEVEL,("usb_dev_list_attach_device open pipe failed\r\n")); return; } /* Endif */ /* Set state to enter after transaction completion */ dev_instance_ptr->state = DEVSTATE_DEVDESC8; _usb_host_ch9_get_descriptor((pointer)dev_instance_ptr, DESCTYPE_DEVICE<<8, 0, 8, (uchar_ptr)&dev_instance_ptr->dev_descriptor); #ifdef _HOST_DEBUG_ DEBUG_LOG_TRACE("usb_dev_list_attach_device SUCCESSFUL"); DEBUGMSG(USB_DBG_LEVEL, ("usb_dev_list_attach_device SUCCESSFUL\n")); #endif //DEBUGMSG(TTC_DBG_LEVEL,("usb_dev_list_attach_device SUCCESSFUL\r\n")); } /* EndBody */
USB_STATUS _usb_hci_vusb20_shutdown ( /* [IN] the USB Host state structure */ _usb_host_handle handle ) { /* Body */ USB_HOST_STATE_STRUCT_PTR usb_host_ptr; VUSB20_REG_STRUCT_PTR dev_ptr; ACTIVE_QH_MGMT_STRUCT_PTR active_list_member_ptr, temp_ptr = NULL; usb_host_ptr = (USB_HOST_STATE_STRUCT_PTR)handle; dev_ptr = (VUSB20_REG_STRUCT_PTR)usb_host_ptr->DEV_PTR; /* Disable interrupts */ dev_ptr->REGISTERS.OPERATIONAL_HOST_REGISTERS.USB_INTR &= ~VUSB20_HOST_INTR_EN_BITS; /* Stop the controller */ dev_ptr->REGISTERS.OPERATIONAL_HOST_REGISTERS.USB_CMD &= ~EHCI_CMD_RUN_STOP; /* Reset the controller to get default values */ dev_ptr->REGISTERS.OPERATIONAL_HOST_REGISTERS.USB_CMD = EHCI_CMD_CTRL_RESET; /********************************************************** ensure that periodic list in uninitilized. **********************************************************/ usb_host_ptr->ITD_LIST_INITIALIZED = FALSE; usb_host_ptr->SITD_LIST_INITIALIZED = FALSE; usb_host_ptr->PERIODIC_LIST_INITIALIZED = FALSE; usb_host_ptr->ALIGNED_PERIODIC_LIST_BASE_ADDR = NULL; /********************************************************** Free all memory occupied by active transfers **********************************************************/ active_list_member_ptr = usb_host_ptr->ACTIVE_ASYNC_LIST_PTR; while(active_list_member_ptr) { temp_ptr = active_list_member_ptr; active_list_member_ptr = (ACTIVE_QH_MGMT_STRUCT_PTR)active_list_member_ptr->NEXT_ACTIVE_QH_MGMT_STRUCT_PTR; USB_mem_free(temp_ptr); } active_list_member_ptr = usb_host_ptr->ACTIVE_INTERRUPT_PERIODIC_LIST_PTR; while(active_list_member_ptr) { temp_ptr = active_list_member_ptr; active_list_member_ptr = (ACTIVE_QH_MGMT_STRUCT_PTR) \ active_list_member_ptr->NEXT_ACTIVE_QH_MGMT_STRUCT_PTR; USB_mem_free(temp_ptr); } /* Free all controller specific memory */ USB_mem_free((pointer)usb_host_ptr->CONTROLLER_MEMORY); #if 0 /* Free all controller specific memory */ USB_memfree(__FILE__,__LINE__,(pointer)usb_host_ptr->PERIODIC_FRAME_LIST_BW_PTR); USB_memfree(__FILE__,__LINE__,(pointer)usb_host_ptr->ASYNC_LIST_BASE_ADDR); USB_memfree(__FILE__,__LINE__,(pointer)usb_host_ptr->ITD_BASE_PTR); USB_memfree(__FILE__,__LINE__,(pointer)usb_host_ptr->ITD_SCRATCH_STRUCT_BASE); USB_memfree(__FILE__,__LINE__,(pointer)usb_host_ptr->SITD_BASE_PTR); USB_memfree(__FILE__,__LINE__,(pointer)usb_host_ptr->QTD_BASE_PTR); USB_memfree(__FILE__,__LINE__,(pointer)usb_host_ptr->QTD_SCRATCH_STRUCT_BASE); USB_memfree(__FILE__,__LINE__,(pointer)usb_host_ptr->SITD_SCRATCH_STRUCT_BASE); USB_memfree(__FILE__,__LINE__,(pointer)usb_host_ptr->PERIODIC_LIST_BASE_ADDR); USB_memfree(__FILE__,__LINE__,(pointer)usb_host_ptr->QH_SCRATCH_STRUCT_BASE); #endif return USB_OK; } /* EndBody */