📄 usb.c
字号:
{ // data not acquired yet - do nothing. return S_USB_FSM_END; } else if ( usb_fsm_background.state == FSM_ERROR ) { // error during data acqusition - signal upwards (?) usb_fsm_mtp.state = FSM_ERROR; usb_fsm_mtp.error_reason = usb_fsm_background.error_reason; event_usb_set_data(usb_fsm_mtp.error_reason); return S_USB_FSM_MORE; } /* data acquired */ local_data_size = ((pUSB_temp_buf[0]|(pUSB_temp_buf[1]<<8)|(pUSB_temp_buf[2]<<16)|(pUSB_temp_buf[3]<<24)) - 12/*Header size*/); if ((local_usb_cmd_event.command_params.mtp_params.mtp_cmdcode == OPCODE_GETNEXTDATABLOCK/*0x9172*/) || (local_usb_cmd_event.command_params.mtp_params.mtp_cmdcode == OPCODE_GETPARTIALOBJECT/*0x101B*/)) { /* 0x9172 or 0x101B mtp command, Upper layer prepare data buffer pointer to be stored. */ memcpy(local_usb_cmd_event.command_params.mtp_params.cbMessageReceived, &local_data_size, 4);#if (0 != HAVE_WMDRM_LARGE_BUFFER) /* Copy data to external device with 16 bits data size. */ memcpy16(local_usb_cmd_event.command_params.mtp_params.pbMessageReceived, pUSB_temp_buf+12, ((local_data_size&0x1) ? local_data_size+1 : local_data_size));#else memcpy((uint8*)(local_usb_cmd_event.command_params.mtp_params.pbMessageReceived), pUSB_temp_buf+12, local_data_size);#endif } else if (*local_usb_cmd_event.command_params.mtp_params.cbMessageReceived) /* this means read data from device */ { pbMessageReceived = local_usb_cmd_event.command_params.mtp_params.pbMessageReceived; *pbMessageReceived = (uint8*)MALLOC( local_data_size ); if (*pbMessageReceived) { memcpy(local_usb_cmd_event.command_params.mtp_params.cbMessageReceived, &local_data_size, 4); memcpy(*pbMessageReceived, pUSB_temp_buf+12, local_data_size); } } usb_fsm_mtp.state = FSM_DONE; event_usb_set_data(READY); return S_USB_FSM_MORE; default: usb_fsm_mtp.state = FSM_ERROR; event_usb_set_data(READY); return S_USB_FSM_END; }}#endif // HAVE_WMDRM/******************************************************************************//* Function: usb_xfer_transision_check_error *//* *//*! \brief try to stop any pending MSD data transfer* * \param1 t_fsm* usb_fsm* \param2 t_usb_state err* \return teUsbFsmCompl - completion flag* \remark*******************************************************************************/teUsbFsmCompl usb_xfer_transision_check_error(t_fsm* usb_fsm, t_usb_state err){ static uint16 read_attempts = 0; if(err != USB_OK) //TBD - ?! if error is during the first transfer { if(err == E_USB_BUSY) { if(read_attempts < C_USB_MAX_READ_ATTEMPTS) { read_attempts++; return S_USB_FSM_MORE; } else { DBG_PRINTF("usb: *E - Xfer: all read attempts failed\r\n"); } }#ifdef _USB_DEBUG USB_debug.xfer_transition_sebug.usb_read_error_1++;#endif /*_USB_DEBUG*/ USB_SetErrorForController(usb_fsm, E_USB_FORCED_UNPLUG); return S_USB_FSM_END; }#ifdef _USB_DEBUG if(read_attempts > 40) { DBG_PRINTF("usb: *W - xfer transition: read_attempts=%d\r\n", read_attempts); }#endif /*_USB_DEBUG*/ read_attempts = 0; return S_USB_FSM_END;}/******************************************************************************//* Function: usb_xfer_transition *//* *//*! \brief try to stop any pending MSD data transfer* * \param* \return teUsbFsmCompl - completion flag* \remark*******************************************************************************/teUsbFsmCompl usb_xfer_transition(void){ t_usb_state err; teUsbFsmCompl fsm_compl; static uint32 trans_sector_count; t_child_xfer_event* XferParams = &(local_usb_cmd_event.command_params.xfer_params); t_child_xfer_event XferParamsTmp;#ifdef _B32_BACK_COMPATIBILITY tUsbMsdVolume* pUsbMsdVolume = (tUsbMsdVolume*)(gUsbDevice.apUsbVolumes[0]); //!!! be carefull !!!#else /*_B32_BACK_COMPATIBILITY*/ tUsbMsdVolume* pUsbMsdVolume = USB_GetVolume(S_USB_TYPE_MSD, S_USB_GET_POSITION, <pevent->usb_vol_ID>) //TBD - usb_vol_ID from cmd event#endif /*_B32_BACK_COMPATIBILITY*/ if(!pUsbMsdVolume) { USB_SetErrorForController(&usb_fsm_xfer, E_USB_READ_FATAL); return S_USB_FSM_END; }#ifdef _USB_DEBUG DBG_PRINTF("usb: \tusb_xfer_transition\r\n");#endif /*_USB_DEBUG*/ switch (usb_fsm_xfer.transition) { case S_USB_GET_DATA_FSM_IDLE: { if(XferParams->offset) { /* USB block is not required from beginning */ /* send data request to USB */ err = USB_Read(pUsbMsdVolume, XferParams->sector_start, 0, 1, pUSB_temp_buf/*,NULL,FALSE*/); fsm_compl = usb_xfer_transision_check_error(&usb_fsm_xfer, err); if (err == USB_OK) usb_fsm_xfer.transition = S_USB_GET_DATA_FSM_WAIT_1ST; else return fsm_compl; } else { /* USB block is required from beginning */ if(XferParams->count < XferParams->sector_size) { /* less data is required than in one USB block */ err = USB_Read(pUsbMsdVolume, XferParams->sector_start, 0, 1, pUSB_temp_buf/*,NULL,FALSE*/); fsm_compl = usb_xfer_transision_check_error(&usb_fsm_xfer, err); if (err == USB_OK) usb_fsm_xfer.transition = S_USB_GET_DATA_FSM_WAIT_LAST; else return fsm_compl; } else { /* more data is required than in one USB block */ trans_sector_count = (XferParams->count >> get_val_log2(XferParams->sector_size));#ifdef _USB_DEBUG USB_debug.xfer_transition_sebug.b3 = 1;#endif /*_USB_DEBUG*/ err = USB_Read(pUsbMsdVolume, XferParams->sector_start, 0, trans_sector_count, XferParams->dest/*,NULL,FALSE*/); fsm_compl = usb_xfer_transision_check_error(&usb_fsm_xfer, err); if (err == USB_OK) usb_fsm_xfer.transition = S_USB_GET_DATA_FSM_WAIT_MIDDLE; else return fsm_compl;#ifdef _USB_DEBUG USB_debug.xfer_transition_sebug.b3 = 0;#endif /*_USB_DEBUG*/ } } return S_USB_FSM_END; } case S_USB_GET_DATA_FSM_WAIT_1ST: { if ( usb_fsm_background.state == FSM_RUN ) { /* data not acruired yet - do nothing. */ return S_USB_FSM_END; } else if ( usb_fsm_background.state == FSM_ERROR ) //[MC] { /* error during data acqusition - signal upwards (?) */ usb_fsm_xfer.state = FSM_ERROR; usb_fsm_xfer.error_reason = usb_fsm_background.error_reason; event_usb_set_data(usb_fsm_xfer.error_reason); return S_USB_FSM_MORE; } /* data acquired */ /* copy part of USB block to FB */ if(XferParams->count > (XferParams->sector_size - XferParams->offset)) { /* more data is required than in one USB block */// memcpy(XferParams->dest, pUSB_temp_buf+XferParams->offset, XferParams->sector_size-XferParams->offset); /* update USB media position */ XferParamsTmp = *XferParams; XferParamsTmp.sector_start += 1; XferParamsTmp.dest += XferParamsTmp.sector_size - XferParamsTmp.offset; XferParamsTmp.count -= XferParamsTmp.sector_size - XferParamsTmp.offset; XferParamsTmp.offset = 0; if(XferParamsTmp.count < XferParamsTmp.sector_size) { /* from next block less data required than block size */ err = USB_Read(pUsbMsdVolume, XferParamsTmp.sector_start, 0, 1, pUSB_temp_buf/*,NULL,FALSE*/); fsm_compl = usb_xfer_transision_check_error(&usb_fsm_xfer, err); if (err == USB_OK) usb_fsm_xfer.transition = S_USB_GET_DATA_FSM_WAIT_LAST; else return fsm_compl; } else { /* more than 1 USB block required */ trans_sector_count = (XferParamsTmp.count >> get_val_log2(XferParamsTmp.sector_size));#ifdef _USB_DEBUG USB_debug.xfer_transition_sebug.b5 = 1;#endif /*_USB_DEBUG*/ err = USB_Read(pUsbMsdVolume, XferParamsTmp.sector_start, 0, trans_sector_count, XferParamsTmp.dest/*,NULL,FALSE*/); fsm_compl = usb_xfer_transision_check_error(&usb_fsm_xfer, err); if (err == USB_OK) usb_fsm_xfer.transition = S_USB_GET_DATA_FSM_WAIT_MIDDLE; else return fsm_compl;#ifdef _USB_DEBUG USB_debug.xfer_transition_sebug.b5 = 0;#endif /*_USB_DEBUG*/ } memcpy(XferParams->dest, pUSB_temp_buf+XferParams->offset, XferParams->sector_size-XferParams->offset); /* update USB media position */// *XferParams = XferParamsTmp; XferParams->sector_start = XferParamsTmp.sector_start; XferParams->dest = XferParamsTmp.dest; XferParams->count = XferParamsTmp.count; XferParams->offset = XferParamsTmp.offset; return S_USB_FSM_END; } else { /* less data is required than in one USB block */ memcpy(XferParams->dest, pUSB_temp_buf+XferParams->offset, XferParams->count); usb_fsm_xfer.state = FSM_DONE; event_usb_set_data(READY); return S_USB_FSM_MORE; } } case S_USB_GET_DATA_FSM_WAIT_MIDDLE: { if ( usb_fsm_background.state == FSM_RUN ) { /* data not acruired yet - do nothing. */ return S_USB_FSM_END; } else if ( usb_fsm_background.state == FSM_ERROR ) //[MC] { /* error during data acqusition - signal upwards (?) */ usb_fsm_xfer.state = FSM_ERROR; usb_fsm_xfer.error_reason = usb_fsm_background.error_reason; event_usb_set_data(usb_fsm_xfer.error_reason); return S_USB_FSM_MORE; } /* data acquired */ /* update USB media position */ XferParamsTmp = *XferParams; XferParamsTmp.sector_start += trans_sector_count; XferParamsTmp.dest += (trans_sector_count * XferParamsTmp.sector_size); XferParamsTmp.count -= (trans_sector_count * XferParamsTmp.sector_size); if(XferParamsTmp.count) { /* still some data to be transfered (less than USB block size) */ err = USB_Read(pUsbMsdVolume, XferParamsTmp.sector_start, 0, 1, pUSB_temp_buf/*,NULL,FALSE*/); fsm_compl = usb_xfer_transision_check_error(&usb_fsm_xfer, err); if (err == USB_OK) {// *XferParams = XferParamsTmp; XferParams->sector_start = XferParamsTmp.sector_start; XferParams->dest = XferParamsTmp.dest; XferParams->count = XferParamsTmp.count; usb_fsm_xfer.transition = S_USB_GET_DATA_FSM_WAIT_LAST; return S_USB_FSM_END; //:) missing } else return fsm_compl; } else { /* transfer finished */ usb_fsm_xfer.state = FSM_DONE; event_usb_set_data(READY); return S_USB_FSM_MORE; } } case S_USB_GET_DATA_FSM_WAIT_LAST: { if ( usb_fsm_background.state == FSM_RUN ) { /* data not acruired yet - do nothing. */ return S_USB_FSM_END; } else if ( usb_fsm_background.state == FSM_ERROR ) //[MC] { /* error during data acqusition - signal upwards (?) */ usb_fsm_xfer.state = FSM_ERROR; usb_fsm_xfer.error_reason = usb_fsm_background.error_reason; event_usb_set_data(usb_fsm_xfer.error_reason); return S_USB_FSM_MORE; } /* data acquired */ /* copy part of USB block to FB */ memcpy(XferParams->dest, pUSB_temp_buf, XferParams->count); usb_fsm_xfer.state = FSM_DONE; event_usb_set_data(READY); return S_USB_FSM_MORE; } default: { usb_fsm_xfer.state = FSM_ERROR; event_usb_set_data(READY); return S_USB_FSM_END; } }}/******************************************************************************//* Function: usb_background_transition *//* *//*! \brief pure calling for the BSR* * \param* \return teUsbFsmCompl - completion flag* \remark*******************************************************************************/teUsbFsmCompl usb_background_transition(void){ USB_RunBackground(); return S_USB_FSM_END;}/******************************************************************************//* Function: usb_state_handling *//* *//*! \brief pure calling for the BSR* * \param* \return teUsbFsmCompl - completion flag* \remark to handle events one-in-turn*******************************************************************************/teUsbFsmCompl usb_state_handling(void){ //static uint8 need_to_reinit = FALSE; /*!!! used to identify when the USBtask will be reinitialized in order to pass LS device usb certification tests */ uint8 count = 0;#ifdef _B32_BACK_COMPATIBILITY uint8 zero = 0;#endif /*_B32_BACK_COMPATIBILITY*/ teUsbFsmCompl is_awaited = S_USB_FSM_MORE; t_usb_state err; t_usb_status_event *pout_event = (t_usb_status_event*) pevent_get_out(USB_STATUS_EVENT); uint32 out_event = 0; //TBD#if ((0!=IPOD_PASSTHROUGH) || (0!=IPOD_AP)) //[LL]new t_usb_downstream_status_event local_usb_downstream_status;#endif /*IPOD_PASSTHROUGH || IPOD_AP*/ tUsbMsdVolume* pUsbMsdVolume; tUsbMsdReadParams* pLastReadParams;#if ((0!=IPOD_PASSTHROUGH) || (0!=IPOD_AP)) //[LL]new tUsbIpodVolume* pUsbIpodVolume;#endif /*IPOD_PASSTHROUGH || IPOD_AP*/#if (1 == HAVE_WMDRM) tUsbMtpVolume* pUsbMtpVolume;#endif /* if some usb error */ if( M_IS_USB_ERROR(gUsbDevice.flag_error) ) { err = gUsbDevice.flag_error; gUsbDevice.flag_error = USB_OK; DBG_PRINTF("usb: *E - "); /* events handling */ pout_event->USB_state = err; switch(err) { case E_USB_MOUNT: /* USB mount error */ DBG_PRINTF("Mount error (0x%04x)\r\n", err); /* events handling */ event_set_out(USB_STATUS_EVENT); break; case E_USB_MOUNT_TIMEOUT: /* mount timeout */ DBG_PRINTF("Mount timeout (0x%04x)\r\n", err); if(gUsbOn == TRUE) { /* events handling */ event_set_out(USB_STATUS_EVENT); USB_ReinitializeUsb(); } break; case E_USB_IPOD_MOUNT: /* iPod mount error */ DBG_PRINTF("iPod mount error (0x%04x)\r\n", err); /* events handling */ event_set_out(USB_STATUS_EVENT); break;#if 0 //TBD - will be removed case E_USB_READ_FATAL: read_error_counter = C_USB_READ_ERROR_COUNT; /* nothing to try again */#endif#if 0 //TBD - will be removed case E_USB_READ: /* error in USB xfer */ DBG_PRINTF("Read error (0x%04x)\r\n", err);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -