/*FUNCTION*---------------------------------------------------------------- * * Function Name : _usb_host_register_ch9_callback * Returned Value : USB_OK, or error status * Comments : * This function registers a callback function that will be called * to notify the user of a ch9 command completion. This should be used * only after enumeration is completed * *END*--------------------------------------------------------------------*/ USB_STATUS _usb_host_register_ch9_callback ( /* usb device */ _usb_device_instance_handle dev_handle, /* Callback upon completion */ tr_callback callback, /* User provided callback param */ pointer callback_param ) { /* Body */ DEV_INSTANCE_PTR dev_inst_ptr; USB_STATUS error; /* Verify that device handle is valid */ USB_lock(); error = usb_hostdev_validate(dev_handle); if (error != USB_OK) { USB_unlock(); return USBERR_DEVICE_NOT_FOUND; } /* Endif */ dev_inst_ptr = (DEV_INSTANCE_PTR)dev_handle; /* This will be called if the device is already enumerated */ dev_inst_ptr->control_callback = callback; dev_inst_ptr->control_callback_param = callback_param; USB_unlock(); return USB_OK; } /* EndBody */
boolean usb_class_mass_storage_device_command_cancel ( /* Handle to class struct with the key */ CLASS_CALL_STRUCT_PTR ccs_ptr, /*Command */ COMMAND_OBJECT_PTR cmd_ptr ) { /* Body */ USB_MASS_CLASS_INTF_STRUCT_PTR intf_ptr; USB_STATUS error = USBERR_NO_INTERFACE; boolean result = FALSE; #ifdef _HOST_DEBUG_ DEBUG_LOG_TRACE("usb_class_mass_storage_device_command_cancel"); #endif /* Pointer validity-checking, clear memory, init header */ USB_lock(); if (usb_host_class_intf_validate(ccs_ptr)) { intf_ptr = (USB_MASS_CLASS_INTF_STRUCT_PTR) ccs_ptr->class_intf_handle; error = usb_hostdev_validate (intf_ptr->G.dev_handle); } /* Endif */ if ((error == USB_OK) || (error == USB_STATUS_TRANSFER_QUEUED)) { result = usb_class_mass_cancelq(intf_ptr, cmd_ptr); } USB_unlock(); #ifdef _HOST_DEBUG_ DEBUG_LOG_TRACE("usb_class_mass_storage_device_command_cancel, SUCCESSFUL"); #endif return result; } /* Endbody */
/*FUNCTION*---------------------------------------------------------------- * * Function Name : _usb_hostdev_cntrl_request * Returned Value : USB_OK, or error status * Comments : * Function to process class- or vendor-specific control pipe device * requests. * *END*--------------------------------------------------------------------*/ USB_STATUS _usb_hostdev_cntrl_request ( /* usb device */ _usb_device_instance_handle dev_handle, /* Device Request to send */ USB_SETUP_PTR devreq, /* buffer to send/receive */ uchar_ptr buff_ptr, /* callback upon completion */ tr_callback callback, /* [IN] the parameter to pass back to the callback function */ pointer callback_param ) { /* Body */ DEV_INSTANCE_PTR dev_ptr; _usb_pipe_handle pipe_handle; TR_INIT_PARAM_STRUCT tr; USB_STATUS error = USB_OK; /* Verify that device handle is valid */ USB_lock(); error = usb_hostdev_validate(dev_handle); if (error != USB_OK) { USB_unlock(); return USBERR_DEVICE_NOT_FOUND; } /* Endif */ dev_ptr = (DEV_INSTANCE_PTR)dev_handle; if (dev_ptr->state < DEVSTATE_ENUM_OK) { USB_unlock(); return USBERR_DEVICE_NOT_FOUND; } /* Endif */ pipe_handle = dev_ptr->control_pipe; usb_hostdev_tr_init(&tr, callback, callback_param); /* Set TR buffer length as required */ if ((REQ_TYPE_IN & devreq->BMREQUESTTYPE) != 0) { tr.RX_BUFFER = buff_ptr; tr.RX_LENGTH = utoh16(devreq->WLENGTH); } else { tr.TX_BUFFER = buff_ptr; tr.TX_LENGTH = utoh16(devreq->WLENGTH); } /* EndIf */ tr.DEV_REQ_PTR = (uchar_ptr)devreq; error = _usb_host_send_setup(dev_ptr->host, pipe_handle, &tr); USB_unlock(); return error; } /* EndBody */
static USB_STATUS usb_class_hid_cntrl_common ( /* [IN] The communication device common command structure */ HID_COMMAND_PTR com_ptr, /* [IN] Bitmask of the request type */ uint_8 bmrequesttype, /* [IN] Request code */ uint_8 brequest, /* [IN] Value to copy into WVALUE field of the REQUEST */ uint_16 wvalue, /* [IN] Length of the data associated with REQUEST */ uint_16 wlength, /* [IN] Pointer to data buffer used to send/recv */ uchar_ptr data ) { /* Body */ USB_HID_CLASS_INTF_STRUCT_PTR if_ptr; USB_SETUP req; USB_STATUS status = USBERR_NO_INTERFACE; #ifdef _HOST_DEBUG_ DEBUG_LOG_TRACE("usb_class_hid_cntrl_common"); #endif USB_lock(); /* Validity checking */ if (usb_host_class_intf_validate(com_ptr->CLASS_PTR)) { if_ptr = (USB_HID_CLASS_INTF_STRUCT_PTR)com_ptr->CLASS_PTR->class_intf_handle; status = usb_hostdev_validate(if_ptr->G.dev_handle); } /* Endif */ if (!status && if_ptr->IN_SETUP) { status = USBERR_TRANSFER_IN_PROGRESS; } /* Endif */ if (!status) { /* Save the higher level callback and ID */ if_ptr->USER_CALLBACK = com_ptr->CALLBACK_FN; if_ptr->USER_PARAM = com_ptr->CALLBACK_PARAM; /* Setup the request */ req.BMREQUESTTYPE = bmrequesttype; req.BREQUEST = brequest; *(uint_16*)req.WVALUE = HOST_TO_LE_SHORT(wvalue); *(uint_16*)req.WINDEX = HOST_TO_LE_SHORT(((INTERFACE_DESCRIPTOR_PTR)if_ptr->G.intf_handle)->bInterfaceNumber); *(uint_16*)req.WLENGTH = HOST_TO_LE_SHORT(wlength); status = _usb_hostdev_cntrl_request(if_ptr->G.dev_handle, &req, data, usb_class_hid_cntrl_callback, if_ptr); if (status == USB_STATUS_TRANSFER_QUEUED) { if_ptr->IN_SETUP = TRUE; } /* Endif */ } /* Endif */ USB_unlock(); #ifdef _HOST_DEBUG_ DEBUG_LOG_TRACE("usb_class_hid_cntrl_common, SUCCESSFUL"); #endif return status; } /* Endbody */
/*FUNCTION*---------------------------------------------------------------- * * Function Name : usb_dev_list_get_memory * 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_memory ( /* [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, /* [OUT] Pointer to memory block's header */ pointer2 _PTR_ header_ptr ) { /* Body */ DEV_MEMORY_PTR mem_ptr, list_ptr; USB_STATUS error; USB_lock(); error = usb_hostdev_validate((pointer2)dev_ptr); USB_unlock(); if (error != USB_OK) { return error; } if ((mem_type <= USB_MEMTYPE_MIN_VALUE) || (mem_type >= USB_MEMTYPE_MAX_VALUE)) { return USBERR_INVALID_MEM_TYPE; } /* Endif */ /* get memory for header + payload, rounded up to 4-byte */ mem_ptr = (DEV_MEMORY_PTR) malloc((mem_size+MEM_HEADER_LEN+3)&0xFFFC); if (mem_ptr == NULL) { return USBERR_GET_MEMORY_FAILED; } //_mem_set_type(mem_ptr, MEM_TYPE_USB_HOST_DEVICE); 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; *header_ptr = (pointer2)mem_ptr; return USB_OK; } /* Endbody */
USB_STATUS usb_class_mass_storage_device_command ( /* Handle to class struct with the key */ CLASS_CALL_STRUCT_PTR ccs_ptr, /*Command */ COMMAND_OBJECT_PTR cmd_ptr ) { /* Body */ USB_MASS_CLASS_INTF_STRUCT_PTR intf_ptr; int temp; USB_STATUS error = USBERR_NO_INTERFACE; CBW_STRUCT_PTR pCbw = (CBW_STRUCT_PTR) cmd_ptr->CBW_PTR; boolean empty; #ifdef _HOST_DEBUG_ DEBUG_LOG_TRACE("usb_class_mass_storage_device_command"); #endif /* Pointer validity-checking, clear memory, init header */ USB_lock(); if (usb_host_class_intf_validate(ccs_ptr)) { intf_ptr = (USB_MASS_CLASS_INTF_STRUCT_PTR) ccs_ptr->class_intf_handle; error = usb_hostdev_validate (intf_ptr->G.dev_handle); } /* Endif */ if ((error == USB_OK) || (error == USB_STATUS_TRANSFER_QUEUED)) { /* Fill in the remaining CBW fields as per the USB Mass Storage specs */ htou32(pCbw->DCBWSIGNATURE, CBW_SIGNATURE); /* CBW is ready so queue it and update status */ empty = USB_CLASS_MASS_IS_Q_EMPTY(intf_ptr); temp = usb_class_mass_q_insert(intf_ptr, cmd_ptr); if (temp >= 0) { cmd_ptr->STATUS = STATUS_QUEUED_IN_DRIVER; /* The tag for the command packet is its queue number. */ htou32(pCbw->DCBWTAG, temp); /* ** If queue was empty send CBW to USB immediately, otherwise it will be ** taken from queue later by a callback function */ if (empty) { error = usb_class_mass_pass_on_usb(intf_ptr); } /* Endif */ } else { error = (USB_STATUS)USB_MASS_QUEUE_FULL; } /* Endif */ } /* Endif */ USB_unlock(); #ifdef _HOST_DEBUG_ DEBUG_LOG_TRACE("usb_class_mass_storage_device_command, SUCCESSFUL"); #endif return error; } /* Endbody */
USB_STATUS usb_class_hub_cntrl_common ( /* [IN] The communication device common command structure */ HUB_COMMAND_PTR com_ptr, /* [IN] Bitmask of the request type */ uint_8 bmrequesttype, /* [IN] Request code */ uint_8 brequest, /* [IN] Value to copy into WVALUE field of the REQUEST */ uint_16 wvalue, /* [IN] Length of the data associated with REQUEST */ uint_16 windex, /* [IN] Index field of CTRL packet */ uint_16 wlength, /* [IN] Pointer to data buffer used to send/recv */ uchar_ptr data ) { /* Body */ USB_HUB_CLASS_INTF_STRUCT_PTR if_ptr; USB_SETUP req; USB_STATUS status = USBERR_NO_INTERFACE; USB_lock(); /* Validity checking */ if (usb_host_class_intf_validate(com_ptr->CLASS_PTR)) { if_ptr = (USB_HUB_CLASS_INTF_STRUCT_PTR)com_ptr->CLASS_PTR->class_intf_handle; status = usb_hostdev_validate(if_ptr->G.dev_handle); } /* Endif */ if (!status && if_ptr->IN_SETUP) { status = USBERR_TRANSFER_IN_PROGRESS; } /* Endif */ if (!status) { /* Save the higher level callback and ID */ if_ptr->USER_CALLBACK = com_ptr->CALLBACK_FN; if_ptr->USER_PARAM = com_ptr->CALLBACK_PARAM; /* Setup the request */ req.BMREQUESTTYPE = bmrequesttype; req.BREQUEST = brequest; htou16(req.WVALUE, wvalue); htou16(req.WINDEX, windex); htou16(req.WLENGTH, wlength); status = _usb_hostdev_cntrl_request(if_ptr->G.dev_handle, &req, data, usb_class_hub_cntrl_callback, if_ptr); if (status == USB_STATUS_TRANSFER_QUEUED) { if_ptr->IN_SETUP = TRUE; } /* Endif */ } /* Endif */ USB_unlock(); return status; } /* Endbody */
USB_STATUS usb_class_mass_getmaxlun_bulkonly ( CLASS_CALL_STRUCT_PTR ccs_ptr, uint_8_ptr pLUN, tr_callback callback ) { /* Body */ USB_STATUS status = USBERR_NO_INTERFACE; USB_SETUP request; USB_MASS_CLASS_INTF_STRUCT_PTR intf_ptr; #ifdef _HOST_DEBUG_ DEBUG_LOG_TRACE("usb_class_mass_getmaxlun_bulkonly"); #endif /* Pointer validity-checking, clear memory, init header */ USB_lock(); if (usb_host_class_intf_validate(ccs_ptr)) { intf_ptr = (USB_MASS_CLASS_INTF_STRUCT_PTR) ccs_ptr->class_intf_handle; status = usb_hostdev_validate(intf_ptr->G.dev_handle); } /* Endif */ if (status) { USB_unlock(); #ifdef _HOST_DEBUG_ DEBUG_LOG_TRACE("usb_class_mass_getmaxlun_bulkonly, error status"); #endif return status; } /* Endif */ /* Get the number of logical units on the device */ request.BMREQUESTTYPE = REQ_TYPE_CLASS | REQ_TYPE_INTERFACE | REQ_TYPE_IN; request.BREQUEST = GET_MAX_LUN; htou16(request.WVALUE, 0); htou16(request.WINDEX, ((INTERFACE_DESCRIPTOR_PTR)intf_ptr->G.intf_handle)->bInterfaceNumber); htou16(request.WLENGTH, 1); /* Send request */ status = _usb_hostdev_cntrl_request (intf_ptr->G.dev_handle, &request, (uchar_ptr)pLUN, callback, NULL); USB_unlock(); #ifdef _HOST_DEBUG_ DEBUG_LOG_TRACE("usb_class_mass_getmaxlun_bulkonly, SUCCESSFUL"); #endif return status; } /* Endbody */
/*FUNCTION*---------------------------------------------------------------- * * Function Name : usb_class_mass_get_app * Returned Value : CLASS_CALL_STRUCT_PTR if class found * Comments : * This function returns stored application handle as it was passed as * a param in select_interface. * *END*--------------------------------------------------------------------*/ USB_STATUS usb_class_mass_get_app ( /* [IN] handle of device */ _usb_device_instance_handle dev_ptr, /* [IN] pointer to interface descriptor */ _usb_interface_descriptor_handle intf_ptr, /* [OUT] pointer to CLASS_CALL_STRUCT to be filled in */ CLASS_CALL_STRUCT_PTR _PTR_ ccs_ptr ) { USB_STATUS error; GENERAL_CLASS_PTR parser; USB_lock(); error = usb_hostdev_validate (dev_ptr); if (error != USB_OK) { USB_unlock(); #ifdef _HOST_DEBUG_ DEBUG_LOG_TRACE("usb_class_hub_get_app, FAILED"); #endif return USB_log_error(__FILE__,__LINE__,error); } /* EndIf */ for (parser = (GENERAL_CLASS_PTR) mass_anchor; parser != NULL; parser = parser->next) { if (parser->dev_handle == dev_ptr && parser->intf_handle == intf_ptr) break; } if (parser != NULL) { USB_MASS_CLASS_INTF_STRUCT_PTR msd = (USB_MASS_CLASS_INTF_STRUCT_PTR) parser; *ccs_ptr = msd->APP; } else { USB_unlock(); #ifdef _HOST_DEBUG_ DEBUG_LOG_TRACE("usb_class_mass_get_app, not found"); #endif return USB_log_error(__FILE__,__LINE__,USBERR_NOT_FOUND); } USB_unlock(); #ifdef _HOST_DEBUG_ DEBUG_LOG_TRACE("usb_class_mass_get_app, SUCCESSFUL"); #endif return USB_OK; }
/*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 */
USB_STATUS usb_printer_class_verify ( /* [IN] class-interface data pointer + key */ CLASS_CALL_STRUCT_PTR cc_ptr, /* [IN] TR memory already allocated, initialized here */ TR_INIT_PARAM_STRUCT_PTR tr_ptr, /* [IN] callback for completion/status */ tr_callback callback, /* [IN] user parameter returned by callback */ pointer call_parm ) { /* Body */ PRINTER_INTERFACE_STRUCT_PTR pis_ptr; USB_STATUS error = USBERR_NO_INTERFACE; #ifdef _HOST_DEBUG_ DEBUG_LOG_TRACE("usb_printer_class_verify"); #endif USB_lock (); if (usb_host_class_intf_validate (cc_ptr)) { pis_ptr = (PRINTER_INTERFACE_STRUCT_PTR) cc_ptr->class_intf_handle; error = usb_hostdev_validate (pis_ptr->dev_handle); if (error == USB_OK) { if (callback == NULL) { error = USBERR_NULL_CALLBACK; } else { usb_hostdev_tr_init (tr_ptr, callback, call_parm); } /* Endif */ } /* EndIf */ } /* Endif */ USB_unlock (); #ifdef _HOST_DEBUG_ DEBUG_LOG_TRACE("usb_printer_class_verify, SUCCESSFUL"); #endif return error; } /* Endbody */
/*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 */
/*FUNCTION*---------------------------------------------------------------- * * Function Name : usb_class_audio_feature_command * Returned Value : USB_OK if command has been passed on USB * Comments : * This function is called by the application to get or set feature units * of audio device *END*--------------------------------------------------------------------*/ usb_status usb_class_audio_feature_command ( /* [IN] Class Interface structure pointer */ audio_command_t* com_ptr, /* [IN] channel number */ uint8_t channel_no, /* [IN] Buffer to send data */ void* buf, /* [IN] The command to perform */ uint32_t cmd ) { /* Body */ uint16_t windex; uint16_t request_value; audio_control_struct_t* if_ptr; usb_audio_command_t* p_feature_command; usb_status status = USBERR_ERROR; if_ptr = (audio_control_struct_t*)com_ptr->class_control_handle; /* Validity checking: for audio interface */ status = usb_hostdev_validate(if_ptr->dev_handle); if (USB_OK == status) { /* pointer to command */ p_feature_command = &(usb_audio_feature_commands[cmd]); /* get request value */ request_value = (uint16_t)((uint16_t)((uint16_t)p_feature_command->request_value << 8) | channel_no); windex = (uint16_t)((uint16_t)((uint16_t)(if_ptr->fu_desc->bunitid) << 8)|(if_ptr->ifnum)); /* Check whether this attribute valid or not */ status = check_valid_fu(if_ptr->fu_desc,p_feature_command->control_mask,if_ptr->fu_desc->bcontrolsize*channel_no); if (USB_OK == status) { status = usb_class_audio_cntrl_common(com_ptr, p_feature_command->request_type, p_feature_command->request_code, request_value, windex, p_feature_command->length, (uint8_t *)buf); } } return status; }
/*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 */
/*FUNCTION*---------------------------------------------------------------- * * Function Name : _usb_host_register_ch9_callback * Returned Value : USB_OK, or error status * Comments : * This function registers a callback function that will be called * to notify the user of a ch9 command completion. This should be used * only after enumeration is completed * *END*--------------------------------------------------------------------*/ USB_STATUS _usb_host_register_ch9_callback ( /* usb device */ _usb_device_instance_handle dev_handle, /* Callback upon completion */ tr_callback callback, /* User provided callback param */ pointer callback_param ) { /* Body */ DEV_INSTANCE_PTR dev_inst_ptr; USB_STATUS error; #ifdef _HOST_DEBUG_ DEBUG_LOG_TRACE("_usb_host_register_ch9_callback"); #endif /* Verify that device handle is valid */ USB_lock(); error = usb_hostdev_validate(dev_handle); if (error != USB_OK) { USB_unlock(); #ifdef _HOST_DEBUG_ DEBUG_LOG_TRACE("_usb_host_register_ch9_callback, device not found"); #endif return USB_log_error(__FILE__,__LINE__,USBERR_DEVICE_NOT_FOUND); } /* Endif */ dev_inst_ptr = (DEV_INSTANCE_PTR)dev_handle; /* This will be called if the device is already enumerated */ dev_inst_ptr->control_callback = callback; dev_inst_ptr->control_callback_param = callback_param; USB_unlock(); #ifdef _HOST_DEBUG_ DEBUG_LOG_TRACE("_usb_host_register_ch9_callback, SUCCESSFUL"); #endif return USB_OK; } /* 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_hostdev_cntrl_request * Returned Value : USB_OK, or error status * Comments : * Function to process class- or vendor-specific control pipe device * requests. * *END*--------------------------------------------------------------------*/ USB_STATUS _usb_hostdev_cntrl_request ( /* usb device */ _usb_device_instance_handle dev_handle, /* Device Request to send */ USB_SETUP_PTR devreq, /* buffer to send/receive */ uchar_ptr buff_ptr, /* callback upon completion */ tr_callback callback, /* [IN] the parameter to pass back to the callback function */ pointer callback_param ) { /* Body */ DEV_INSTANCE_PTR dev_ptr; _usb_pipe_handle pipe_handle; TR_INIT_PARAM_STRUCT tr; USB_STATUS error = USB_OK; #ifdef _HOST_DEBUG_ DEBUG_LOG_TRACE("_usb_hostdev_cntrl_request"); #endif /* Verify that device handle is valid */ USB_lock(); error = usb_hostdev_validate(dev_handle); if (error != USB_OK) { USB_unlock(); #ifdef _HOST_DEBUG_ DEBUG_LOG_TRACE("_usb_hostdev_cntrl_request, invalid device handle"); #endif return USB_log_error(__FILE__,__LINE__,USBERR_DEVICE_NOT_FOUND); } /* Endif */ dev_ptr = (DEV_INSTANCE_PTR)dev_handle; if (dev_ptr->state < DEVSTATE_ENUM_OK) { USB_unlock(); #ifdef _HOST_DEBUG_ DEBUG_LOG_TRACE("_usb_hostdev_cntrl_request, no device found"); #endif return USB_log_error(__FILE__,__LINE__,USBERR_DEVICE_NOT_FOUND); } /* Endif */ pipe_handle = dev_ptr->control_pipe; usb_hostdev_tr_init(&tr, callback, callback_param); /* Set TR buffer length as required */ if ((REQ_TYPE_IN & devreq->BMREQUESTTYPE) != 0) { tr.G.RX_BUFFER = buff_ptr; tr.G.RX_LENGTH = SHORT_LE_TO_HOST(*(uint_16*)devreq->WLENGTH); } else { tr.G.TX_BUFFER = buff_ptr; tr.G.TX_LENGTH = SHORT_LE_TO_HOST(*(uint_16*)devreq->WLENGTH); } /* EndIf */ tr.DEV_REQ_PTR = (uchar_ptr)devreq; error = _usb_host_send_setup(dev_ptr->host, pipe_handle, &tr); USB_unlock(); #ifdef _HOST_DEBUG_ DEBUG_LOG_TRACE("_usb_hostdev_cntrl_request,SUCCESSFUL"); #endif return USB_log_error(__FILE__,__LINE__,error); } /* EndBody */
/*FUNCTION*---------------------------------------------------------------- * * Function Name : usb_host_ch9_dev_req * Returned Value : USB_OK, or error status * Comments : * Function to process standard device requests in Chapter 9. * See Table 9-3 p. 250 of USB 2.0 specification. * This code does minimal error checking, on the assumption * that it is called only from wrappers in this file. * It is presumed that this function is called with USB interrupts disabled * *END*--------------------------------------------------------------------*/ static USB_STATUS usb_host_ch9_dev_req ( /* usb device */ _usb_device_instance_handle dev_handle, /* Device Request to send */ USB_SETUP_PTR devreq_ptr, /* buffer to send/receive */ uchar_ptr buff_ptr ) { /* Body */ DEV_INSTANCE_PTR dev_ptr; _usb_pipe_handle pipe_handle; TR_INIT_PARAM_STRUCT tr; USB_STATUS error; /* Verify that device handle is valid */ error = usb_hostdev_validate(dev_handle); if (error != USB_OK) { return USBERR_DEVICE_NOT_FOUND; } /* Endif */ dev_ptr = (DEV_INSTANCE_PTR)dev_handle; pipe_handle = dev_ptr->control_pipe; /* Initialize the TR with TR index and default control callback ** function if there is one registered */ usb_hostdev_tr_init(&tr, dev_ptr->control_callback, dev_ptr->control_callback_param); /* Set buffer length if required */ switch (devreq_ptr->BREQUEST) { case REQ_SET_DESCRIPTOR: tr.TX_BUFFER = buff_ptr; tr.TX_LENGTH = utoh16(devreq_ptr->WLENGTH); break; case REQ_GET_CONFIGURATION: case REQ_GET_DESCRIPTOR: case REQ_GET_INTERFACE: case REQ_GET_STATUS: case REQ_SYNCH_FRAME: tr.RX_BUFFER = buff_ptr; tr.RX_LENGTH = utoh16(devreq_ptr->WLENGTH); break; } /* EndSwitch */ tr.DEV_REQ_PTR = (uchar_ptr)(devreq_ptr); if ((dev_ptr->state < DEVSTATE_ENUM_OK) || (tr.CALLBACK == NULL)) { tr.CALLBACK = usb_host_cntrl_transaction_done; tr.CALLBACK_PARAM = NULL; } /* Endif */ error = _usb_host_send_setup(dev_ptr->host, pipe_handle, &tr); return error; } /* EndBody */
uint_32 _io_usb_mfs_install ( /* [IN] A string that identifies the device for fopen */ char_ptr identifier, /* [IN] Logical unit number which driver need to install */ uint_8 logical_unit, /* [IN] Interface Handle */ CLASS_CALL_STRUCT_PTR ccs_ptr ) { /* Body */ IO_USB_MFS_STRUCT_PTR info_ptr; USB_MASS_CLASS_INTF_STRUCT_PTR intf_ptr = NULL; USB_STATUS error = USBERR_ERROR; /* Pointer validity-checking, clear memory, init header */ USB_lock(); if (usb_host_class_intf_validate(ccs_ptr)) { intf_ptr = (USB_MASS_CLASS_INTF_STRUCT_PTR) ccs_ptr->class_intf_handle; if(intf_ptr != NULL) { error = usb_hostdev_validate (intf_ptr->G.dev_handle); } } /* Endif */ if (USB_OK != error) { /* Device was already detached or intf_ptr is NULL */ USB_unlock(); return MQX_OUT_OF_MEMORY; } if (USB_OK != _usb_hostdev_get_buffer(intf_ptr->G.dev_handle, sizeof(IO_USB_MFS_STRUCT), (pointer *) &info_ptr)) { USB_unlock(); return MQX_OUT_OF_MEMORY; } _mem_zero(info_ptr, sizeof(IO_USB_MFS_STRUCT)); _mem_set_type(info_ptr, MEM_TYPE_USB_MFS_STRUCT); USB_unlock(); /* Fill in the state structure with the info we know */ info_ptr->LUN = logical_unit; info_ptr->BLENGTH = USB_MFS_DEFAULT_SECTOR_SIZE; info_ptr->ERROR_CODE = IO_OK; info_ptr->BLOCK_MODE = TRUE; info_ptr->COMMAND.CBW_PTR = (CBW_STRUCT_PTR) &info_ptr->CBW; info_ptr->COMMAND.CSW_PTR = (CSW_STRUCT_PTR) &info_ptr->CSW; info_ptr->COMMAND.CALL_PTR = ccs_ptr; info_ptr->COMMAND.LUN = logical_unit; info_ptr->COMMAND.CALLBACK = _io_usb_mfs_callback; info_ptr->COMMAND_STATUS = MQX_OK; _lwsem_create(&info_ptr->LWSEM, 1); _lwsem_create(&info_ptr->COMMAND_DONE, 0); return (_io_dev_install_ext(identifier, (_mqx_int (_CODE_PTR_)(MQX_FILE_PTR, char_ptr, char_ptr))_io_usb_mfs_open, (_mqx_int (_CODE_PTR_)(MQX_FILE_PTR) )_io_usb_mfs_close, (_mqx_int (_CODE_PTR_)(MQX_FILE_PTR, char_ptr, int_32) )_io_usb_mfs_read, (_mqx_int (_CODE_PTR_)(MQX_FILE_PTR, char_ptr, int_32) )_io_usb_mfs_write, (_mqx_int (_CODE_PTR_)(MQX_FILE_PTR, _mqx_uint, pointer) ) _io_usb_mfs_ioctl, _io_usb_mfs_uninstall_internal, (pointer)info_ptr )); } /* Endbody */
/*FUNCTION*---------------------------------------------------------------- * * Function Name : _usb_hostdev_cntrl_request * Returned Value : USB_OK, or error status * Comments : * Function to process class- or vendor-specific control pipe device * requests. * *END*--------------------------------------------------------------------*/ usb_status _usb_hostdev_cntrl_request ( /* usb device */ usb_device_instance_handle dev_handle, /* Device Request to send */ usb_setup_t* devreq, /* buffer to send/receive */ uint8_t * buff_ptr, /* callback upon completion */ tr_callback callback, /* [IN] the parameter to pass back to the callback function */ void* callback_param ) { /* Body */ dev_instance_t* dev_ptr; usb_pipe_handle pipe_handle; tr_struct_t tr; usb_status error = USB_OK; #ifdef _HOST_DEBUG_ DEBUG_LOG_TRACE("_usb_hostdev_cntrl_request"); #endif /* Verify that device handle is valid */ OS_Lock(); error = usb_hostdev_validate(dev_handle); if (error != USB_OK) { OS_Unlock(); #ifdef _HOST_DEBUG_ DEBUG_LOG_TRACE("_usb_hostdev_cntrl_request, invalid device handle"); #endif return USB_log_error(__FILE__,__LINE__,USBERR_DEVICE_NOT_FOUND); } /* Endif */ dev_ptr = (dev_instance_t*)dev_handle; if (dev_ptr->state < DEVSTATE_ENUM_OK) { OS_Unlock(); #ifdef _HOST_DEBUG_ DEBUG_LOG_TRACE("_usb_hostdev_cntrl_request, no device found"); #endif return USB_log_error(__FILE__,__LINE__,USBERR_DEVICE_NOT_FOUND); } /* Endif */ pipe_handle = dev_ptr->control_pipe; usb_hostdev_tr_init(&tr, callback, callback_param); /* Set TR buffer length as required */ if ((REQ_TYPE_IN & devreq->bmrequesttype) != 0) { tr.rx_buffer = buff_ptr; tr.rx_length = USB_SHORT_UNALIGNED_LE_TO_HOST(devreq->wlength); } else { tr.TX_BUFFER = buff_ptr; tr.tx_length = USB_SHORT_UNALIGNED_LE_TO_HOST(devreq->wlength); } /* EndIf */ tr.setup_packet = *devreq; error = _usb_host_send_setup(dev_ptr->host, pipe_handle, &tr); OS_Unlock(); #ifdef _HOST_DEBUG_ DEBUG_LOG_TRACE("_usb_hostdev_cntrl_request,SUCCESSFUL"); #endif return USB_log_error(__FILE__,__LINE__,error); }
/*FUNCTION*---------------------------------------------------------------- * * Function Name : usb_host_ch9_dev_req * Returned Value : USB_OK, or error status * Comments : * Function to process standard device requests in Chapter 9. * See Table 9-3 p. 250 of USB 2.0 specification. * This code does minimal error checking, on the assumption * that it is called only from wrappers in this file. * It is presumed that this function is called with USB interrupts disabled * *END*--------------------------------------------------------------------*/ static usb_status usb_host_ch9_dev_req ( /* usb device */ usb_device_instance_handle dev_handle, /* Device Request to send */ usb_setup_t* devreq_ptr, /* buffer to send/receive */ uint8_t * buff_ptr ) { dev_instance_t* dev_ptr; usb_pipe_handle pipe_handle; tr_struct_t* tr_ptr; usb_status error; #ifdef _HOST_DEBUG_ DEBUG_LOG_TRACE("usb_host_ch9_dev_req"); #endif /* Verify that device handle is valid */ error = usb_hostdev_validate(dev_handle); if (error != USB_OK) { #ifdef _HOST_DEBUG_ DEBUG_LOG_TRACE("usb_host_ch9_dev_req device not found"); #endif return USB_log_error(__FILE__,__LINE__,USBERR_DEVICE_NOT_FOUND); } /* Endif */ dev_ptr = (dev_instance_t*)dev_handle; pipe_handle = dev_ptr->control_pipe; if (usb_host_get_tr(dev_ptr->host, dev_ptr->control_callback, dev_ptr->control_callback_param, &tr_ptr) != USB_OK) { printf("error to get tr ch9\n"); return USBERR_ERROR; } /* Set buffer length if required */ switch (devreq_ptr->brequest) { case REQ_SET_DESCRIPTOR: tr_ptr->tx_buffer = buff_ptr; tr_ptr->tx_length = USB_SHORT_UNALIGNED_LE_TO_HOST(devreq_ptr->wlength); break; case REQ_GET_CONFIGURATION: case REQ_GET_DESCRIPTOR: case REQ_GET_INTERFACE: case REQ_GET_STATUS: case REQ_SYNCH_FRAME: tr_ptr->rx_buffer = buff_ptr; tr_ptr->rx_length = USB_SHORT_UNALIGNED_LE_TO_HOST(devreq_ptr->wlength); break; } /* EndSwitch */ tr_ptr->setup_packet = *devreq_ptr; if ((dev_ptr->state < DEVSTATE_ENUM_OK) || (tr_ptr->callback == NULL)) { tr_ptr->callback = usb_host_cntrl_transaction_done; tr_ptr->callback_param = dev_ptr; } /* Endif */ #ifdef _HOST_DEBUG_ DEBUG_LOG_TRACE("usb_host_ch9_dev_req SUCCESSFUL"); #endif error = usb_host_send_setup(dev_ptr->host, pipe_handle, tr_ptr); return USB_log_error(__FILE__,__LINE__,error); } /* EndBody */
/*FUNCTION*---------------------------------------------------------------- * * Function Name : usb_dev_list_get_memory * 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_memory ( /* [IN] Pointer to the USB device */ DEV_INSTANCE_PTR dev_ptr, /* [IN] Size of memory payload required */ uint_16 mem_size, /* [IN] Type of memory payload required */ memory_type mem_type, /* [OUT] Pointer to memory block's header */ pointer _PTR_ header_ptr ) { /* Body */ DEV_MEMORY_PTR mem_ptr, list_ptr; USB_STATUS error; #ifdef _HOST_DEBUG_ DEBUG_LOG_TRACE("usb_dev_list_get_memory"); DEBUGMSG(USB_DBG_LEVEL, ("usb_dev_list_get_memory\n")); #endif USB_lock(); error = usb_hostdev_validate((pointer)dev_ptr); USB_unlock(); if (error != USB_OK) #ifdef _HOST_DEBUG_ DEBUG_LOG_TRACE("usb_dev_list_get_memory invalid device handle"); #endif return error; if ((mem_type <= USB_MEMTYPE_MIN_VALUE) || (mem_type >= USB_MEMTYPE_MAX_VALUE)) { #ifdef _HOST_DEBUG_ DEBUG_LOG_TRACE("usb_dev_list_get_memory invalid memory type"); #endif return USBERR_INVALID_MEM_TYPE; } /* Endif */ /* get memory for header + payload, rounded up to 4-byte */ mem_ptr = (DEV_MEMORY_PTR)\ USB_Uncached_memalloc((mem_size+MEM_HEADER_LEN+3)&0xFFFC); if (mem_ptr == NULL) { #ifdef _HOST_DEBUG_ DEBUG_LOG_TRACE("usb_dev_list_get_memory malloc failed"); #endif return USBERR_GET_MEMORY_FAILED; } 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; *header_ptr = (pointer)mem_ptr; #ifdef _HOST_DEBUG_ DEBUG_LOG_TRACE("usb_dev_list_get_memory SUCCESSFUL"); #endif return USB_OK; } /* 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 */