/*FUNCTION*------------------------------------------------------------- * * Function Name : _usb_host_new_tr_element * Returned Value : pointer to new host tr struct, NULL if error * Comments : * This function will allocate and link a new TR element in the * list of TRs for the specified pipe. It is assumed the caller has issued * USB_lock() before entry. * *END*-----------------------------------------------------------------*/ static TR_STRUCT_PTR _usb_host_new_tr_element ( /* [IN] the pipe handle */ _usb_pipe_handle pipe_handle ) { /* Body */ PIPE_STRUCT_PTR pipe_ptr = (PIPE_STRUCT_PTR) pipe_handle; DEV_INSTANCE_PTR dev_ptr = (DEV_INSTANCE_PTR) pipe_ptr->DEV_INSTANCE; USB_HOST_STATE_STRUCT_PTR host_ptr = (USB_HOST_STATE_STRUCT_PTR) dev_ptr->host; TR_STRUCT_PTR tr_ptr, temp_tr_ptr; #ifdef _HOST_DEBUG_ DEBUG_LOG_TRACE("_usb_host_new_tr_element"); #endif tr_ptr = (TR_STRUCT_PTR)USB_mem_alloc_uncached_zero(host_ptr->TR_SIZE); if (tr_ptr == NULL) { #ifdef _HOST_DEBUG_ DEBUG_LOG_TRACE("_usb_host_new_tr_element malloc failed"); #endif return NULL; } _mem_set_type(tr_ptr, MEM_TYPE_USB_HOST_PIPE_TR_STRUCT); /* Link pipe's TR structs in circular list of 1 or more items, ** where the pipe descriptor's tr list pointer holds the ** address of the next struct for scheduling (i.e. the ** "beginning" of the list). */ temp_tr_ptr = pipe_ptr->tr_list_ptr; if (temp_tr_ptr == NULL) { /* No existing items, make a circle of one */ pipe_ptr->tr_list_ptr = tr_ptr->NEXT = tr_ptr; } else { /* Add new item to the "end" of the existing list */ while (temp_tr_ptr->NEXT != pipe_ptr->tr_list_ptr) temp_tr_ptr = temp_tr_ptr->NEXT; temp_tr_ptr->NEXT = tr_ptr; tr_ptr->NEXT = pipe_ptr->tr_list_ptr; } /* EndIf */ #ifdef _HOST_DEBUG_ DEBUG_LOG_TRACE("_usb_host_new_tr_element SUCCESSFUL"); #endif return tr_ptr; } /* Endbody */
/*FUNCTION*---------------------------------------------------------------- * * Function Name : usb_dev_list_get_mem * Returned Value : USB_OK if memory allocated, else error code * Comments : * Memory is added at the end of a linked list, whose * anchor is device.memlist * *END*--------------------------------------------------------------------*/ USB_STATUS usb_dev_list_get_mem ( /* [IN] Pointer to the USB device */ DEV_INSTANCE_PTR dev_ptr, /* [IN] Size of memory payload required */ uint_32 mem_size, /* [IN] Type of memory payload required */ memory_type mem_type, /* [IN] Alignment required */ uint_32 align, /* [OUT] Pointer to memory block's header */ DEV_MEMORY_PTR _PTR_ header_ptr ) { /* Body */ DEV_MEMORY_PTR mem_ptr, list_ptr; USB_STATUS error; #ifdef _HOST_DEBUG_ DEBUG_LOG_TRACE("usb_dev_list_get_mem"); #endif if (align > 256) { #ifdef _HOST_DEBUG_ DEBUG_LOG_TRACE("usb_dev_list_get_mem invalid alignment"); #endif return USB_log_error(__FILE__,__LINE__,USBERR_BAD_ALIGNMENT); } if ((mem_type <= USB_MEMTYPE_MIN_VALUE) || (mem_type >= USB_MEMTYPE_MAX_VALUE)) { #ifdef _HOST_DEBUG_ DEBUG_LOG_TRACE("usb_dev_list_get_mem invalid memory type"); #endif return USB_log_error(__FILE__,__LINE__,USBERR_INVALID_MEM_TYPE); } USB_lock(); error = usb_hostdev_validate((_usb_device_instance_handle)dev_ptr); if (error != USB_OK) { USB_unlock(); #ifdef _HOST_DEBUG_ DEBUG_LOG_TRACE("usb_dev_list_get_mem invalid device handle"); #endif return USB_log_error(__FILE__,__LINE__,error); } /* get memory for header + payload, rounded up to align bytes */ mem_ptr = (DEV_MEMORY_PTR) USB_mem_alloc_uncached_zero(MEM_HEADER_LEN + mem_size + align - 1); if (mem_ptr == NULL) { USB_unlock(); #ifdef _HOST_DEBUG_ DEBUG_LOG_TRACE("usb_dev_list_get_mem malloc FAILED"); #endif return USB_log_error(__FILE__,__LINE__,USBERR_GET_MEMORY_FAILED); } _mem_set_type(mem_ptr, MEM_TYPE_USB_LIST_MEM_BUFF); if (dev_ptr->memlist == NULL) { dev_ptr->memlist = mem_ptr; } else { list_ptr = dev_ptr->memlist; while (list_ptr->next != NULL) list_ptr = list_ptr->next; list_ptr->next = mem_ptr; } /* EndIf */ mem_ptr->next = NULL; mem_ptr->blktype = mem_type; mem_ptr->blksize = mem_size; mem_ptr->offset = (~(uint_32) mem_ptr->payload.data + 1) & (align - 1); if (mem_ptr->offset) { /* Real payload is by offset bytes shifted from original payload. We want to write offset in the byte just before ** real payload. */ mem_ptr->payload.data[mem_ptr->offset - 1] = mem_ptr->offset; /* write offset value also 1 byte before payload */ } *header_ptr = (pointer)mem_ptr; USB_unlock(); #ifdef _HOST_DEBUG_ DEBUG_LOG_TRACE("usb_dev_list_get_mem SUCCESSFUL"); #endif return USB_OK; } /* Endbody */