static void *vsfusbh_uvc_init(struct vsfusbh_t *usbh, struct vsfusbh_device_t *dev) { struct vsfusbh_class_data_t *cdata; struct vsfusbh_uvc_t *hdata; cdata = vsf_bufmgr_malloc(sizeof(struct vsfusbh_class_data_t)); if (NULL == cdata) return NULL; hdata = vsf_bufmgr_malloc(sizeof(struct vsfusbh_uvc_t)); if (NULL == hdata) { vsf_bufmgr_free(cdata); return NULL; } memset(cdata, 0, sizeof(struct vsfusbh_class_data_t)); memset(hdata, 0, sizeof(struct vsfusbh_uvc_t)); cdata->dev = dev; hdata->dev = dev; hdata->usbh = usbh; cdata->param = hdata; hdata->video_payload.type = VSFUSBH_UVC_PAYLOAD_VIDEO; hdata->video_payload.buf = hdata->video_urb_buf; hdata->init_sm.init_state.evt_handler = uvc_evt_handler_init; hdata->init_sm.user_data = (void*)hdata; hdata->init_pt.thread = uvc_init_thread; hdata->init_pt.user_data = hdata; hdata->init_pt.sm = &hdata->init_sm; hdata->init_pt.state = 0; hdata->ctrl_sm.init_state.evt_handler = uvc_evt_handler_ctrl; hdata->ctrl_sm.user_data = (void*)hdata; hdata->ctrl_pt.thread = uvc_ctrl_thread; hdata->ctrl_pt.user_data = hdata; hdata->ctrl_pt.sm = &hdata->ctrl_sm; hdata->ctrl_pt.state = 0; hdata->ctrl_urb.vsfdev = dev; hdata->ctrl_urb.timeout = 200; hdata->ctrl_urb.sm = &hdata->init_sm; hdata->video_sm.init_state.evt_handler = uvc_evt_handler_video; hdata->video_sm.user_data = (void*)hdata; hdata->video_urb.vsfdev = dev; hdata->video_urb.timeout = 200; hdata->video_urb.sm = &hdata->video_sm; vsfsm_init(&hdata->init_sm); vsfsm_init(&hdata->ctrl_sm); vsfsm_init(&hdata->video_sm); return cdata; }
struct vsfusbh_device_t *vsfusbh_alloc_device(struct vsfusbh_t *usbh) { vsf_err_t err; struct vsfusbh_device_t *dev; dev = vsf_bufmgr_malloc(sizeof(struct vsfusbh_device_t)); if (NULL == dev) return NULL; memset(dev, 0, sizeof(struct vsfusbh_device_t)); err = usbh->hcd->alloc_device(usbh->hcd_data, dev); if (err != VSFERR_NONE) { vsf_bufmgr_free(dev); return NULL; } dev->devnum = mskarr_ffz(usbh->device_bitmap, USB_MAX_DEVICE); if (dev->devnum == 0) { vsf_bufmgr_free(dev); return NULL; } mskarr_set(usbh->device_bitmap, dev->devnum); return dev; }
void main(void) { struct vsf_module_t *module; struct vsf_module_info_t *minfo = (struct vsf_module_info_t *)APPCFG_MODULES_ADDR; int32_t pagesize; vsf_enter_critical(); vsfhal_core_init(NULL); vsfhal_flash_capacity(0, (uint32_t*)&pagesize, NULL); pagesize = msb(pagesize); vsf_bufmgr_init(app.bufmgr_buffer, sizeof(app.bufmgr_buffer)); // register modules while (minfo->entry != 0xFFFFFFFF) { module = vsf_bufmgr_malloc(sizeof(struct vsf_module_t)); if (NULL == module) { break; } module->flash = minfo; minfo = (struct vsf_module_info_t *)((uint8_t *)minfo +\ ((minfo->size + (1 << pagesize) - 1) & ~((1 << pagesize) - 1))); vsf_module_register(module); } vsf_module_load("vsf.os", true); // vsfos module SHALL never return; }
static struct vsfsm_state_t *uvc_evt_handler_video(struct vsfsm_t *sm, vsfsm_evt_t evt) { vsf_err_t err; struct vsfusbh_uvc_t *hdata = (struct vsfusbh_uvc_t *)sm->user_data; struct vsfusbh_t *usbh = hdata->usbh; struct vsfusbh_urb_t *vsfurb = &hdata->video_urb; switch (evt) { case VSFSM_EVT_INIT: break; case UAV_ISO_ENABLE: if (hdata->video_urb_buf == NULL) { vsfurb->vsfdev->epmaxpacketin[hdata->video_iso_ep] = hdata->video_iso_packet_len; hdata->video_urb_buf = vsf_bufmgr_malloc(hdata->video_iso_packet_len); if (hdata->video_urb_buf == NULL) return NULL; vsfurb->transfer_buffer = hdata->video_urb_buf; vsfurb->transfer_length = hdata->video_iso_packet_len; vsfurb->pipe = usb_rcvisocpipe(vsfurb->vsfdev, hdata->video_iso_ep); vsfurb->transfer_flags |= USB_ISO_ASAP; vsfurb->number_of_packets = 1; vsfurb->iso_frame_desc[0].offset = 0; vsfurb->iso_frame_desc[0].length = hdata->video_iso_packet_len; err = vsfusbh_submit_urb(usbh, vsfurb); if (err != VSFERR_NONE) goto error; } break; case UAV_ISO_DISABLE: // TODO break; case VSFSM_EVT_URB_COMPLETE: if (vsfurb->status == URB_OK) { hdata->video_payload.len = vsfurb->actual_length; vsfusbh_uvc_report(hdata, &hdata->cur_param, &hdata->video_payload); } else { goto error; } err = vsfusbh_relink_urb(usbh, vsfurb); if (err != VSFERR_NONE) goto error; break; default: break; } return NULL; error: vsf_bufmgr_free(hdata->video_urb_buf); hdata->video_urb_buf = NULL; return NULL; }
vsf_err_t vsfip_telnetd_modinit(struct vsf_module_t *module, struct app_hwcfg_t const *cfg) { struct vsfip_telnetd_modifs_t *ifs; ifs = vsf_bufmgr_malloc(sizeof(struct vsfip_telnetd_modifs_t)); if (!ifs) return VSFERR_FAIL; memset(ifs, 0, sizeof(*ifs)); ifs->start = vsfip_telnetd_start; module->ifs = ifs; return VSFERR_NONE; }
vsf_err_t crc_modinit(struct vsf_module_t *module, struct app_hwcfg_t const *cfg) { struct crc_modifs_t *ifs; ifs = vsf_bufmgr_malloc(sizeof(struct crc_modifs_t)); if (!ifs) return VSFERR_FAIL; memset(ifs, 0, sizeof(*ifs)); ifs->calc = crc_calc; module->ifs = ifs; return VSFERR_NONE; }
vsf_err_t vsfdbg_modinit(struct vsf_module_t *module, struct app_hwcfg_t const *cfg) { struct vsfdbg_modifs_t *ifs; ifs = vsf_bufmgr_malloc(sizeof(struct vsfdbg_modifs_t)); if (!ifs) return VSFERR_FAIL; memset(ifs, 0, sizeof(*ifs)); ifs->init = debug_init; ifs->fini = debug_fini; ifs->debug = debug; module->ifs = ifs; return VSFERR_NONE; }
vsf_err_t vsfusbd_CDCACM_modinit(struct vsf_module_t *module, struct app_hwcfg_t const *cfg) { struct vsfusbd_CDCACM_modifs_t *ifs; ifs = vsf_bufmgr_malloc(sizeof(struct vsfusbd_CDCACM_modifs_t)); if (!ifs) return VSFERR_FAIL; memset(ifs, 0, sizeof(*ifs)); ifs->control_protocol.request_prepare = vsfusbd_CDCACMControl_request_prepare; ifs->control_protocol.request_process = vsfusbd_CDCACMControl_request_process; ifs->data_protocol.init = vsfusbd_CDCACMData_class_init; module->ifs = ifs; return VSFERR_NONE; }
void* vsf_module_load(char *name, bool dead) { struct vsf_module_t *module = vsf_module_get(name); vsf_err_t (*mod_entry)(struct vsf_module_t *, struct app_hwcfg_t const *); if ((module != NULL) && module->flash->entry) { if (module->code_buff != NULL) { goto succeed; } #ifdef VSFCFG_MODULE_ALLOC_RAM if (module->flash->size > 0) { module->code_buff = vsf_bufmgr_malloc(module->flash->size); if (NULL == module->code_buff) { goto fail; } memcpy(module->code_buff, module->flash, module->flash->size); } else { module->code_buff = (uint8_t *)module->flash; } #else module->code_buff = (uint8_t *)module->flash; #endif mod_entry = (vsf_err_t (*)(struct vsf_module_t *, struct app_hwcfg_t const *)) (module->code_buff + module->flash->entry); if (mod_entry(module, &app_hwcfg)) { #ifdef VSFCFG_MODULE_ALLOC_RAM if (module->flash->size > 0) { vsf_bufmgr_free(module->code_buff); } #endif module->code_buff = NULL; goto fail; } succeed: return module->ifs; } fail: if (dead) while (1); return NULL; }
vsf_err_t vsfusbh_uvc_modinit(struct vsf_module_t *module, struct app_hwcfg_t const *cfg) { struct vsfusbh_uvc_modifs_t *ifs; ifs = vsf_bufmgr_malloc(sizeof(struct vsfusbh_uvc_modifs_t)); if (!ifs) return VSFERR_FAIL; memset(ifs, 0, sizeof(*ifs)); ifs->drv.name = "uvc"; ifs->set = vsfusbh_uvc_set; ifs->report = vsfusbh_uvc_report; module->ifs = ifs; return VSFERR_NONE; }
vsf_err_t vsfusbh_hub_modinit(struct vsf_module_t *module, struct app_hwcfg_t const *cfg) { struct vsfusbh_hub_modifs_t *ifs; ifs = vsf_bufmgr_malloc(sizeof(struct vsfusbh_hub_modifs_t)); if (!ifs) return VSFERR_FAIL; memset(ifs, 0, sizeof(*ifs)); ifs->drv.name = "hub"; ifs->drv.id_table = vsfusbh_hub_id_table; ifs->drv.probe = vsfusbh_hub_probe; ifs->drv.disconnect = vsfusbh_hub_disconnect; module->ifs = ifs; return VSFERR_NONE; }
vsf_err_t vsfusbh_register_driver(struct vsfusbh_t *usbh, const struct vsfusbh_class_drv_t *drv) { struct vsfusbh_class_drv_list *drv_list; drv_list = (struct vsfusbh_class_drv_list *)\ vsf_bufmgr_malloc(sizeof(struct vsfusbh_class_drv_list)); if (drv_list == NULL) { return VSFERR_FAIL; } memset(drv_list, 0, sizeof(struct vsfusbh_class_drv_list)); drv_list->drv = drv; sllist_append(&usbh->drv_list, &drv_list->list); return VSFERR_NONE; }
vsf_err_t vsfusbh_modinit(struct vsf_module_t *module, struct app_hwcfg_t const *cfg) { struct vsfusbh_modifs_t *ifs; ifs = vsf_bufmgr_malloc(sizeof(struct vsfusbh_modifs_t)); if (!ifs) return VSFERR_FAIL; memset(ifs, 0, sizeof(*ifs)); ifs->init = vsfusbh_init; ifs->fini = vsfusbh_fini; ifs->register_driver = vsfusbh_register_driver; ifs->submit_urb = vsfusbh_submit_urb; ifs->relink_urb = vsfusbh_relink_urb; module->ifs = ifs; return VSFERR_NONE; }
static vsf_err_t vsfshell_new_handler_thread(struct vsfshell_t *shell, char *cmd) { struct vsfshell_handler_param_t *param = (struct vsfshell_handler_param_t *)vsf_bufmgr_malloc(sizeof(*param)); struct vsfshell_handler_t *handler; vsf_err_t err = VSFERR_NONE; if (NULL == param) { goto exit; } memset(param, 0, sizeof(*param)); param->shell = shell; param->output_pt.sm = ¶m->sm; param->output_pt.thread = (vsfsm_pt_thread_t)vsfshell_output_thread; param->output_pt.user_data = shell; // parse command line param->argc = dimof(param->argv); if (vsfshell_parse_cmd(cmd, param)) { goto exit_free_argv; } // search handler handler = vsfshell_search_handler(shell, param->argv[0]); if (NULL == handler) { goto exit_free_argv; } param->context = handler->context; param->pt.thread = handler->thread; param->pt.user_data = param; param->pt.sm = ¶m->sm; shell->input_sm = ¶m->sm; vsfsm_pt_init(¶m->sm, ¶m->pt); goto exit; exit_free_argv: vsfshell_free_param(param); err = VSFERR_FAIL; exit: return err; }
vsf_err_t embflash_modinit(struct vsf_module_t *module, struct app_hwcfg_t const *cfg) { struct embflash_modifs_t *ifs; ifs = vsf_bufmgr_malloc(sizeof(struct embflash_modifs_t)); if (!ifs) return VSFERR_FAIL; memset(ifs, 0, sizeof(*ifs)); ifs->mal.drv.block_size = embflash_maldrv_blocksize; ifs->mal.drv.init = embflash_maldrv_init; ifs->mal.drv.fini = embflash_maldrv_fini; ifs->mal.drv.erase = embflash_maldrv_erase; ifs->mal.drv.read = embflash_maldrv_read; ifs->mal.drv.write = embflash_maldrv_write; module->ifs = ifs; return VSFERR_NONE; }
static void *vsfusbh_hub_probe(struct vsfusbh_t *usbh, struct vsfusbh_device_t *dev, struct usb_interface_t *interface, const struct vsfusbh_device_id_t *id) { struct usb_interface_desc_t *intf_desc; struct usb_endpoint_desc_t *ep_desc; struct vsfusbh_hub_t *hub; intf_desc = interface->altsetting + interface->act_altsetting; if ((intf_desc->bInterfaceSubClass != 0) && (intf_desc->bInterfaceSubClass != 1)) return NULL; if (intf_desc -> bNumEndpoints != 1) return NULL; ep_desc = intf_desc->ep_desc; if ((ep_desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_INT) return NULL; hub = vsf_bufmgr_malloc(sizeof(struct vsfusbh_hub_t)); if (NULL == hub) return NULL; memset(hub, 0, sizeof(struct vsfusbh_hub_t)); hub->vsfurb = usbh->hcd->alloc_urb(); if (hub->vsfurb == NULL) { vsf_bufmgr_free(hub); return NULL; } hub->usbh = usbh; hub->dev = dev; hub->vsfurb->vsfdev = dev; hub->vsfurb->timeout = 200; hub->sm.init_state.evt_handler = vsfusbh_hub_evt_handler_init; hub->sm.user_data = hub; vsfsm_init(&hub->sm); return hub; }
vsf_err_t vsfscsi_modinit(struct vsf_module_t *module, struct app_hwcfg_t const *cfg) { struct vsfscsi_modifs_t *ifs; ifs = vsf_bufmgr_malloc(sizeof(struct vsfscsi_modifs_t)); if (!ifs) return VSFERR_FAIL; memset(ifs, 0, sizeof(*ifs)); ifs->init = vsfscsi_init; ifs->execute = vsfscsi_execute; ifs->cancel_transact = vsfscsi_cancel_transact; ifs->release_transact = vsfscsi_release_transact; ifs->mal2scsi.op.init = vsf_mal2scsi_init; ifs->mal2scsi.op.execute = vsf_mal2scsi_execute; ifs->scsi2mal.op.block_size = vsf_scsi2mal_blocksize; ifs->scsi2mal.op.init = vsf_scsi2mal_init; ifs->scsi2mal.op.fini = vsf_scsi2mal_fini; ifs->scsi2mal.op.read = vsf_scsi2mal_read; ifs->scsi2mal.op.write = vsf_scsi2mal_write; module->ifs = ifs; return VSFERR_NONE; }
static struct vsfsm_state_t *uvc_evt_handler_ctrl(struct vsfsm_t *sm, vsfsm_evt_t evt) { vsf_err_t err; struct vsfusbh_uvc_t *hdata = (struct vsfusbh_uvc_t *)sm->user_data; switch (evt) { case VSFSM_EVT_INIT: break; case UAV_RESET_STREAM_PARAM: hdata->ctrl_pt.state = 0; if (hdata->ctrl_urb_buf == NULL) { hdata->ctrl_urb_buf = vsf_bufmgr_malloc(UVC_PROBE_CRTL_DATA_SIZE); if (hdata->ctrl_urb_buf == NULL) return NULL; } case VSFSM_EVT_URB_COMPLETE: case VSFSM_EVT_DELAY_DONE: err = hdata->ctrl_pt.thread(&hdata->ctrl_pt, evt); if (err < 0) { // TODO vsf_bufmgr_free(hdata->ctrl_urb_buf); hdata->ctrl_urb_buf = NULL; } else if (err == 0) { vsf_bufmgr_free(hdata->ctrl_urb_buf); hdata->ctrl_urb_buf = NULL; } break; default: break; } return NULL; }
static void *vsfusbh_uvc_init(struct vsfusbh_t *usbh, struct vsfusbh_device_t *dev) { struct vsfusbh_class_data_t *cdata; struct vsfusbh_uvc_t *hdata; cdata = vsf_bufmgr_malloc(sizeof(struct vsfusbh_class_data_t)); if (NULL == cdata) return NULL; hdata = vsf_bufmgr_malloc(sizeof(struct vsfusbh_uvc_t)); if (NULL == hdata) { vsf_bufmgr_free(cdata); return NULL; } memset(cdata, 0, sizeof(struct vsfusbh_class_data_t)); memset(hdata, 0, sizeof(struct vsfusbh_uvc_t)); cdata->dev = dev; hdata->dev = dev; hdata->usbh = usbh; cdata->param = hdata; //hdata->init_sm.init_state.evt_handler = uvc_evt_handler_init; //hdata->init_sm.user_data = (void*)hdata; //hdata->init_pt.thread = uvc_init_thread; hdata->ctrl_sm.init_state.evt_handler = uvc_evt_handler_ctrl; hdata->ctrl_sm.user_data = (void*)hdata; hdata->ctrl_pt.thread = uvc_ctrl_thread; hdata->ctrl_pt.user_data = hdata; hdata->ctrl_pt.sm = &hdata->ctrl_sm; hdata->ctrl_pt.state = 0; hdata->ctrl_urb.vsfdev = dev; hdata->ctrl_urb.timeout = 200; hdata->ctrl_urb.sm = &hdata->ctrl_sm; hdata->video_sm.init_state.evt_handler = uvc_evt_handler_video; hdata->video_sm.user_data = (void*)hdata; hdata->video_urb.vsfdev = dev; hdata->video_urb.timeout = 200; hdata->video_urb.sm = &hdata->video_sm; hdata->audio_sm.init_state.evt_handler = uvc_evt_handler_audio; hdata->audio_sm.user_data = (void*)hdata; hdata->audio_urb.vsfdev = dev; hdata->audio_urb.timeout = 200; hdata->audio_urb.sm = &hdata->audio_sm; // test #if 1 hdata->set_param.connected = 1; hdata->set_param.video_enable = 1; #endif // 1 vsfsm_init(&hdata->ctrl_sm); vsfsm_init(&hdata->video_sm); vsfsm_init(&hdata->audio_sm); return cdata; }
static vsf_err_t vsfshell_parse_cmd(char *cmd, struct vsfshell_handler_param_t *param) { uint8_t cmd_len, argv_num; uint16_t i; char *argv_tmp; memset(param->argv, 0, sizeof(param->argv)); cmd_len = strlen(cmd); argv_num = 0; i = 0; while (i < cmd_len) { while (isspace((int)cmd[i])) { i++; } if ('\0' == cmd[i]) { break; } if (('\'' == cmd[i]) || ('"' == cmd[i])) { uint8_t j; char div = cmd[i]; j = i + 1; argv_tmp = &cmd[j]; while (cmd[j] != div) { if ('\0' == cmd[j]) { return VSFERR_FAIL; } j++; } i = j; } else { argv_tmp = &cmd[i]; while (!isspace((int)cmd[i]) && (cmd[i] != '\0')) { i++; } } cmd[i++] = '\0'; if (argv_num >= param->argc) { // can not accept more argv break; } // allocate buffer for argv_tmp param->argv[argv_num] = vsf_bufmgr_malloc(strlen(argv_tmp) + 1); if (NULL == param->argv[argv_num]) { return VSFERR_FAIL; } strcpy(param->argv[argv_num], argv_tmp); argv_num++; } param->argc = argv_num; return VSFERR_NONE; }
vsf_err_t vsfos_modinit(struct vsf_module_t *module, struct app_hwcfg_t const *cfg) { struct vsfos_modifs_t *ifs; ifs = vsf_bufmgr_malloc(sizeof(struct vsfos_modifs_t)); if (!ifs) return VSFERR_FAIL; memset(ifs, 0, sizeof(*ifs)); ifs->hwcfg = cfg; ifs->pendsvq.size = dimof(ifs->pendsvq_ele); ifs->pendsvq.queue = ifs->pendsvq_ele; ifs->pendsvq.activate = vsfos_pendsv_activate; // init vsftimer ifs->vsftimer_memop.alloc = vsftimer_memop_alloc; ifs->vsftimer_memop.free = vsftimer_memop_free; // init fakefat32_fs ifs->fakefat32_fs.Windows_dir[0].memfile.file.name = "."; ifs->fakefat32_fs.Windows_dir[0].memfile.file.attr = VSFILE_ATTR_DIRECTORY; ifs->fakefat32_fs.Windows_dir[1].memfile.file.name = ".."; ifs->fakefat32_fs.Windows_dir[1].memfile.file.attr = VSFILE_ATTR_DIRECTORY; ifs->fakefat32_fs.Windows_dir[2].memfile.file.name = "VSFCDC.inf"; ifs->fakefat32_fs.Windows_dir[2].memfile.file.size = sizeof(vsfcdc_inf) - 1; ifs->fakefat32_fs.Windows_dir[2].memfile.file.attr = VSFILE_ATTR_ARCHIVE | VSFILE_ATTR_READONLY; ifs->fakefat32_fs.Windows_dir[2].memfile.f.buff = (uint8_t *)vsfcdc_inf; ifs->fakefat32_fs.Windows_dir[3].memfile.file.name = "VSFRNDIS.inf"; ifs->fakefat32_fs.Windows_dir[3].memfile.file.size = sizeof(vsfrndis_inf) - 1; ifs->fakefat32_fs.Windows_dir[3].memfile.file.attr = VSFILE_ATTR_ARCHIVE | VSFILE_ATTR_READONLY; ifs->fakefat32_fs.Windows_dir[3].memfile.f.buff = (uint8_t *)vsfrndis_inf; ifs->fakefat32_fs.Driver_dir[0].memfile.file.name = "."; ifs->fakefat32_fs.Driver_dir[0].memfile.file.attr = VSFILE_ATTR_DIRECTORY; ifs->fakefat32_fs.Driver_dir[1].memfile.file.name = ".."; ifs->fakefat32_fs.Driver_dir[1].memfile.file.attr = VSFILE_ATTR_DIRECTORY; ifs->fakefat32_fs.Driver_dir[2].memfile.file.name = "Windows"; ifs->fakefat32_fs.Driver_dir[2].memfile.file.attr = VSFILE_ATTR_DIRECTORY; ifs->fakefat32_fs.Driver_dir[2].memfile.d.child = (struct vsfile_memfile_t *)ifs->fakefat32_fs.Windows_dir; ifs->fakefat32_fs.LOSTDIR_dir[0].memfile.file.name = "."; ifs->fakefat32_fs.LOSTDIR_dir[0].memfile.file.attr = VSFILE_ATTR_DIRECTORY; ifs->fakefat32_fs.LOSTDIR_dir[1].memfile.file.name = ".."; ifs->fakefat32_fs.LOSTDIR_dir[1].memfile.file.attr = VSFILE_ATTR_DIRECTORY; ifs->fakefat32_fs.RECYCLEBIN_dir[0].memfile.file.name = "."; ifs->fakefat32_fs.RECYCLEBIN_dir[0].memfile.file.attr = VSFILE_ATTR_DIRECTORY; ifs->fakefat32_fs.RECYCLEBIN_dir[1].memfile.file.name = ".."; ifs->fakefat32_fs.RECYCLEBIN_dir[1].memfile.file.attr = VSFILE_ATTR_DIRECTORY; ifs->fakefat32_fs.RECYCLEBIN_dir[2].memfile.file.name = "DESKTOP.INI"; ifs->fakefat32_fs.RECYCLEBIN_dir[2].memfile.file.size = sizeof(Win_recycle_DESKTOP_INI) - 1; ifs->fakefat32_fs.RECYCLEBIN_dir[2].memfile.file.attr = VSFILE_ATTR_ARCHIVE | VSFILE_ATTR_READONLY; ifs->fakefat32_fs.RECYCLEBIN_dir[2].memfile.f.buff = (uint8_t *)Win_recycle_DESKTOP_INI; ifs->fakefat32_fs.SVI_dir[0].memfile.file.name = "."; ifs->fakefat32_fs.SVI_dir[0].memfile.file.attr = VSFILE_ATTR_DIRECTORY; ifs->fakefat32_fs.SVI_dir[1].memfile.file.name = ".."; ifs->fakefat32_fs.SVI_dir[1].memfile.file.attr = VSFILE_ATTR_DIRECTORY; ifs->fakefat32_fs.SVI_dir[2].memfile.file.name = "IndexerVolumeGuid"; ifs->fakefat32_fs.SVI_dir[2].memfile.file.size = sizeof(Win10_IndexerVolumeGuid); ifs->fakefat32_fs.SVI_dir[2].memfile.file.attr = VSFILE_ATTR_ARCHIVE | VSFILE_ATTR_READONLY | VSFILE_ATTR_SYSTEM | VSFILE_ATTR_HIDDEN, ifs->fakefat32_fs.SVI_dir[2].memfile.f.buff = (uint8_t *)Win10_IndexerVolumeGuid; ifs->fakefat32_fs.SVI_dir[3].memfile.file.name = "WPSettings.dat"; ifs->fakefat32_fs.SVI_dir[3].memfile.file.size = sizeof(Win10_WPSettings_dat); ifs->fakefat32_fs.SVI_dir[3].memfile.file.attr = VSFILE_ATTR_ARCHIVE | VSFILE_ATTR_READONLY | VSFILE_ATTR_SYSTEM | VSFILE_ATTR_HIDDEN, ifs->fakefat32_fs.SVI_dir[3].memfile.f.buff = (uint8_t *)Win10_WPSettings_dat; ifs->fakefat32_fs.root_dir[0].memfile.file.name = "VSFDriver"; ifs->fakefat32_fs.root_dir[0].memfile.file.attr = VSFILE_ATTR_VOLUMID; ifs->fakefat32_fs.root_dir[1].memfile.file.name = "LOST.DIR"; ifs->fakefat32_fs.root_dir[1].memfile.file.attr = VSFILE_ATTR_DIRECTORY | VSFILE_ATTR_SYSTEM | VSFILE_ATTR_HIDDEN; ifs->fakefat32_fs.root_dir[1].memfile.d.child = (struct vsfile_memfile_t *)ifs->fakefat32_fs.LOSTDIR_dir; ifs->fakefat32_fs.root_dir[2].memfile.file.name = "$RECYCLE.BIN"; ifs->fakefat32_fs.root_dir[2].memfile.file.attr = VSFILE_ATTR_DIRECTORY | VSFILE_ATTR_SYSTEM | VSFILE_ATTR_HIDDEN; ifs->fakefat32_fs.root_dir[2].memfile.d.child = (struct vsfile_memfile_t *)ifs->fakefat32_fs.RECYCLEBIN_dir; ifs->fakefat32_fs.root_dir[3].memfile.file.name = "System Volume Information"; ifs->fakefat32_fs.root_dir[3].memfile.file.attr = VSFILE_ATTR_DIRECTORY | VSFILE_ATTR_SYSTEM | VSFILE_ATTR_HIDDEN; ifs->fakefat32_fs.root_dir[3].memfile.d.child = (struct vsfile_memfile_t *)ifs->fakefat32_fs.SVI_dir; ifs->fakefat32_fs.root_dir[4].memfile.file.name = "Driver"; ifs->fakefat32_fs.root_dir[4].memfile.file.attr = VSFILE_ATTR_DIRECTORY; ifs->fakefat32_fs.root_dir[4].memfile.d.child = (struct vsfile_memfile_t *)ifs->fakefat32_fs.Driver_dir; // init fakefat32 ifs->mal.fakefat32.sector_size = 512; ifs->mal.fakefat32.sector_number = 0x1000; ifs->mal.fakefat32.sectors_per_cluster = 8; ifs->mal.fakefat32.volume_id = 0xDEADBEEF; ifs->mal.fakefat32.disk_id = 0xBABECAFE; ifs->mal.fakefat32.root[0].memfile.file.name = "ROOT"; ifs->mal.fakefat32.root[0].memfile.d.child = (struct vsfile_memfile_t *)ifs->fakefat32_fs.root_dir, // init mal ifs->mal.mal.drv = &fakefat32_mal_drv; ifs->mal.mal.param = &ifs->mal.fakefat32; ifs->mal.pbuffer[0] = ifs->mal.buffer[0]; ifs->mal.pbuffer[1] = ifs->mal.buffer[1]; // init file ifs->fs.memop.alloc_vfs = vsfos_vsfile_alloc_vfs; ifs->fs.memop.free_vfs = vsfos_vsfile_free_vfs; // init mal2scsi ifs->mal.scsistream.mbuf.count = dimof(ifs->mal.buffer); ifs->mal.scsistream.mbuf.size = sizeof(ifs->mal.buffer[0]); ifs->mal.scsistream.mbuf.buffer_list = ifs->mal.pbuffer; ifs->mal.mal2scsi.malstream.mal = &ifs->mal.mal; ifs->mal.mal2scsi.cparam.block_size = 512; ifs->mal.mal2scsi.cparam.removable = false; memcpy(ifs->mal.mal2scsi.cparam.vendor, "Simon ", 8); memcpy(ifs->mal.mal2scsi.cparam.product, "VSFDriver ", 16); memcpy(ifs->mal.mal2scsi.cparam.revision, "1.00", 4); ifs->mal.mal2scsi.cparam.type = SCSI_PDT_DIRECT_ACCESS_BLOCK; // init scsi device ifs->mal.lun[0].op = &vsf_mal2scsi_op; ifs->mal.lun[0].stream = (struct vsf_stream_t *)&ifs->mal.scsistream; ifs->mal.lun[0].param = &ifs->mal.mal2scsi; ifs->mal.scsi_dev.max_lun = 0; ifs->mal.scsi_dev.lun = ifs->mal.lun; // init rndis ifs->usbd.rndis.param.CDCACM.CDC.ep_notify = 1; ifs->usbd.rndis.param.CDCACM.CDC.ep_out = 2; ifs->usbd.rndis.param.CDCACM.CDC.ep_in = 2; ifs->usbd.rndis.param.mac.size = 6; ifs->usbd.rndis.param.mac.addr.s_addr64 = 0x0605040302E0; ifs->usbd.rndis.param.netif.macaddr.size = 6; ifs->usbd.rndis.param.netif.macaddr.addr.s_addr64 = 0x0E0D0C0B0AE0; ifs->usbd.rndis.param.cb.param = &ifs->usbd.rndis; ifs->usbd.rndis.param.cb.on_connect = vsfos_rndis_on_connect; if (0) { ifs->usbd.rndis.param.netif.ipaddr.size = 4; ifs->usbd.rndis.param.netif.ipaddr.addr.s_addr = 0x01202020; ifs->usbd.rndis.param.netif.netmask.size = 4; ifs->usbd.rndis.param.netif.netmask.addr.s_addr = 0x00FFFFFF; ifs->usbd.rndis.param.netif.gateway.size = 4; ifs->usbd.rndis.param.netif.gateway.addr.s_addr = 0x01202020; } // init cdc ifs->usbd.cdc.stream_tx.stream.op = &fifostream_op; ifs->usbd.cdc.stream_tx.mem.buffer.buffer = ifs->usbd.cdc.txbuff; ifs->usbd.cdc.stream_tx.mem.buffer.size = sizeof(ifs->usbd.cdc.txbuff); ifs->usbd.cdc.stream_rx.stream.op = &fifostream_op; ifs->usbd.cdc.stream_rx.mem.buffer.buffer = ifs->usbd.cdc.rxbuff; ifs->usbd.cdc.stream_rx.mem.buffer.size = sizeof(ifs->usbd.cdc.rxbuff); ifs->usbd.cdc.param.CDC.ep_notify = 3; ifs->usbd.cdc.param.CDC.ep_out = 4; ifs->usbd.cdc.param.CDC.ep_in = 4; ifs->usbd.cdc.param.CDC.stream_tx = (struct vsf_stream_t *)&ifs->usbd.cdc.stream_tx; ifs->usbd.cdc.param.CDC.stream_rx = (struct vsf_stream_t *)&ifs->usbd.cdc.stream_rx; ifs->usbd.cdc.param.line_coding.bitrate = 115200; ifs->usbd.cdc.param.line_coding.stopbittype = 0; ifs->usbd.cdc.param.line_coding.paritytype = 0; ifs->usbd.cdc.param.line_coding.datatype = 8; // init msc ifs->usbd.msc.param.ep_in = 5; ifs->usbd.msc.param.ep_out = 5; ifs->usbd.msc.param.scsi_dev = &ifs->mal.scsi_dev; // init usbd ifs->usbd.desc[0] = (struct vsfusbd_desc_filter_t)VSFUSBD_DESC_DEVICE(0, USB_DeviceDescriptor, sizeof(USB_DeviceDescriptor)); ifs->usbd.desc[1] = (struct vsfusbd_desc_filter_t)VSFUSBD_DESC_CONFIG(0, 0, USB_ConfigDescriptor, sizeof(USB_ConfigDescriptor)); ifs->usbd.desc[2] = (struct vsfusbd_desc_filter_t)VSFUSBD_DESC_STRING(0, 0, USB_StringLangID, sizeof(USB_StringLangID)); ifs->usbd.desc[3] = (struct vsfusbd_desc_filter_t)VSFUSBD_DESC_STRING(0x0409, 1, USB_StringVendor, sizeof(USB_StringVendor)); ifs->usbd.desc[4] = (struct vsfusbd_desc_filter_t)VSFUSBD_DESC_STRING(0x0409, 2, USB_StringProduct, sizeof(USB_StringProduct)); ifs->usbd.desc[5] = (struct vsfusbd_desc_filter_t)VSFUSBD_DESC_STRING(0x0409, 3, USB_StringSerial, sizeof(USB_StringSerial)); ifs->usbd.desc[6] = (struct vsfusbd_desc_filter_t)VSFUSBD_DESC_STRING(0x0409, 4, RNDIS_StringFunc, sizeof(RNDIS_StringFunc)); ifs->usbd.desc[7] = (struct vsfusbd_desc_filter_t)VSFUSBD_DESC_STRING(0x0409, 5, CDC_StringFunc, sizeof(CDC_StringFunc)); ifs->usbd.desc[8] = (struct vsfusbd_desc_filter_t)VSFUSBD_DESC_STRING(0x0409, 6, MSC_StringFunc, sizeof(MSC_StringFunc)); ifs->usbd.ifaces[0].class_protocol = (struct vsfusbd_class_protocol_t *)&vsfusbd_RNDISControl_class; ifs->usbd.ifaces[0].protocol_param = &ifs->usbd.rndis.param; ifs->usbd.ifaces[1].class_protocol = (struct vsfusbd_class_protocol_t *)&vsfusbd_RNDISData_class; ifs->usbd.ifaces[1].protocol_param = &ifs->usbd.rndis.param; ifs->usbd.ifaces[2].class_protocol = (struct vsfusbd_class_protocol_t *)&vsfusbd_CDCACMControl_class; ifs->usbd.ifaces[2].protocol_param = &ifs->usbd.cdc.param; ifs->usbd.ifaces[3].class_protocol = (struct vsfusbd_class_protocol_t *)&vsfusbd_CDCACMData_class; ifs->usbd.ifaces[3].protocol_param = &ifs->usbd.cdc.param; ifs->usbd.ifaces[4].class_protocol = (struct vsfusbd_class_protocol_t *)&vsfusbd_MSCBOT_class; ifs->usbd.ifaces[4].protocol_param = &ifs->usbd.msc.param; ifs->usbd.config[0].num_of_ifaces = dimof(ifs->usbd.ifaces); ifs->usbd.config[0].iface = ifs->usbd.ifaces; ifs->usbd.device.num_of_configuration = dimof(ifs->usbd.config); ifs->usbd.device.config = ifs->usbd.config; ifs->usbd.device.desc_filter = ifs->usbd.desc; ifs->usbd.device.device_class_iface = 0; ifs->usbd.device.drv = vsfhal_usbd_if; ifs->usbd.device.int_priority = 0x01; // init telnetd ifs->tcpip.telnetd.telnetd.port = 23; ifs->tcpip.telnetd.telnetd.session_num = dimof(ifs->tcpip.telnetd.sessions); ifs->tcpip.telnetd.sessions[0].session.stream_tx = (struct vsf_stream_t *)&ifs->tcpip.telnetd.sessions[0].stream_tx; ifs->tcpip.telnetd.sessions[0].session.stream_rx = (struct vsf_stream_t *)&ifs->tcpip.telnetd.sessions[0].stream_rx; ifs->tcpip.telnetd.sessions[0].stream_tx.stream.op = &fifostream_op; ifs->tcpip.telnetd.sessions[0].stream_tx.mem.buffer.buffer = (uint8_t *)ifs->tcpip.telnetd.sessions[0].txbuff; ifs->tcpip.telnetd.sessions[0].stream_tx.mem.buffer.size = sizeof(ifs->tcpip.telnetd.sessions[0].txbuff); ifs->tcpip.telnetd.sessions[0].stream_rx.stream.op = &fifostream_op; ifs->tcpip.telnetd.sessions[0].stream_rx.mem.buffer.buffer = (uint8_t *)ifs->tcpip.telnetd.sessions[0].rxbuff; ifs->tcpip.telnetd.sessions[0].stream_rx.mem.buffer.size = sizeof(ifs->tcpip.telnetd.sessions[0].rxbuff); // init tcpip ifs->tcpip.mem_op.get_buffer = vsfos_vsfip_get_buffer; ifs->tcpip.mem_op.release_buffer = vsfos_vsfip_release_buffer; ifs->tcpip.mem_op.get_socket = vsfos_vsfip_get_socket; ifs->tcpip.mem_op.release_socket = vsfos_vsfip_release_socket; ifs->tcpip.mem_op.get_tcppcb = vsfos_vsfip_get_tcppcb; ifs->tcpip.mem_op.release_tcppcb = vsfos_vsfip_release_tcppcb; // init shell ifs->shell.echo = true; ifs->shell.stream_tx = (struct vsf_stream_t *)&ifs->usbd.cdc.stream_tx; ifs->shell.stream_rx = (struct vsf_stream_t *)&ifs->usbd.cdc.stream_rx; ifs->pt.user_data = ifs; ifs->pt.thread = vsfos_thread; module->ifs = ifs; vsfsm_evtq_init(&ifs->pendsvq); vsfsm_evtq_set(&ifs->pendsvq); vsfsm_pt_init(&ifs->sm, &ifs->pt); vsfhal_core_pendsv_config(vsfos_on_pendsv, &ifs->pendsvq); vsf_leave_critical(); vsfsm_evtq_set(NULL); while (1) { // no thread runs in mainq, just sleep in main loop vsfhal_core_sleep(0); } }
static vsf_err_t parse_configuration(struct usb_config_t *config, uint8_t *buffer) { int i, retval, size; struct usb_descriptor_header_t *header; memcpy(config, buffer, USB_DT_CONFIG_SIZE); size = config->wTotalLength; #ifdef USB_MAXINTERFACES if (config->bNumInterfaces > USB_MAXINTERFACES) return VSFERR_FAIL; #endif config->interface = vsf_bufmgr_malloc(sizeof(struct usb_interface_t) * config->bNumInterfaces); if (config->interface == NULL) return VSFERR_NOT_ENOUGH_RESOURCES; memset(config->interface, 0, sizeof(struct usb_interface_t) * config->bNumInterfaces); buffer += config->bLength; size -= config->bLength; //config->extra = NULL; //config->extralen = 0; for (i = 0; i < config->bNumInterfaces; i++) { int32_t numskipped; //int32_t len; //uint8_t *begin; /* Skip over the rest of the Class Specific or Vendor */ /* Specific descriptors */ //begin = buffer; numskipped = 0; while (size >= sizeof(struct usb_descriptor_header_t)) { header = (struct usb_descriptor_header_t *)buffer; if ((header->bLength > size) || (header->bLength < 2)) { return VSFERR_FAIL; } /* If we find another "proper" descriptor then we're done */ if ((header->bDescriptorType == USB_DT_ENDPOINT) || (header->bDescriptorType == USB_DT_INTERFACE) || (header->bDescriptorType == USB_DT_CONFIG) || (header->bDescriptorType == USB_DT_DEVICE)) break; numskipped++; buffer += header->bLength; size -= header->bLength; } /* len = (int32_t)(buffer - begin); if (len) { if (config->extralen == 0) { // info } else { config->extra = begin; config->extralen = len; } } */ retval = parse_interface(config->interface + i, buffer, size); if (retval < 0) return VSFERR_FAIL; buffer += retval; size -= retval; } return VSFERR_NONE; }
static int parse_interface(struct usb_interface_t *interface, unsigned char *buffer, int size) { int i, len, numskipped, retval, parsed = 0; struct usb_descriptor_header_t *header; struct usb_interface_desc_t *ifp; uint32_t begin; interface->act_altsetting = 0; interface->num_altsetting = 0; interface->max_altsetting = USB_ALTSETTINGALLOC; interface->altsetting = vsf_bufmgr_malloc\ (sizeof(struct usb_interface_desc_t) * interface->max_altsetting); if (!interface->altsetting) { return -1; } while (size > 0) { if (interface->num_altsetting >= interface->max_altsetting) { void *ptr; int oldmas; oldmas = interface->max_altsetting; interface->max_altsetting += USB_ALTSETTINGALLOC; #ifdef USB_MAXALTSETTING if (interface->max_altsetting > USB_MAXALTSETTING) { return -1; } #endif ptr = interface->altsetting; interface->altsetting = vsf_bufmgr_malloc\ (sizeof(struct usb_interface_desc_t) * interface->max_altsetting); if (!interface->altsetting) { interface->altsetting = ptr; return -1; } memcpy(interface->altsetting, ptr, sizeof(struct usb_interface_desc_t) * oldmas); vsf_bufmgr_free(ptr); } ifp = interface->altsetting + interface->num_altsetting; interface->num_altsetting++; memcpy(ifp, buffer, USB_DT_INTERFACE_SIZE); /* Skip over the interface */ buffer += ifp->bLength; parsed += ifp->bLength; size -= ifp->bLength; begin = (uint32_t)buffer; numskipped = 0; /* Skip over any interface, class or vendor descriptors */ while (size >= sizeof(struct usb_descriptor_header_t)) { header = (struct usb_descriptor_header_t *)buffer; if (header->bLength < 2) { return -1; } /* If we find another "proper" descriptor then we're done */ if ((header->bDescriptorType == USB_DT_INTERFACE) || (header->bDescriptorType == USB_DT_ENDPOINT) || (header->bDescriptorType == USB_DT_CONFIG) || (header->bDescriptorType == USB_DT_DEVICE)) break; numskipped++; buffer += header->bLength; parsed += header->bLength; size -= header->bLength; } len = (int)((uint32_t)buffer - begin); if (len) { ifp->extra = (void *)begin; ifp->extralen = len; } else { ifp->extra = NULL; ifp->extralen = 0; } /* Did we hit an unexpected descriptor? */ header = (struct usb_descriptor_header_t *)buffer; if ((size >= sizeof(struct usb_descriptor_header_t)) && ((header->bDescriptorType == USB_DT_CONFIG) || (header->bDescriptorType == USB_DT_DEVICE))) return parsed; if (ifp->bNumEndpoints > USB_MAXENDPOINTS) { return -1; } if (ifp->bNumEndpoints != 0) { ifp->ep_desc = vsf_bufmgr_malloc(ifp->bNumEndpoints * sizeof(struct usb_endpoint_desc_t)); if (!ifp->ep_desc) { return -1; } memset(ifp->ep_desc, 0, ifp->bNumEndpoints * sizeof(struct usb_endpoint_desc_t)); for (i = 0; i < ifp->bNumEndpoints; i++) { header = (struct usb_descriptor_header_t *)buffer; if (header->bLength > size) { return -1; } retval = parse_endpoint(ifp->ep_desc + i, buffer, size); if (retval < 0) return retval; buffer += retval; parsed += retval; size -= retval; } } /* We check to see if it's an alternate to this one */ ifp = (struct usb_interface_desc_t *)buffer; if (size < USB_DT_INTERFACE_SIZE || ifp->bDescriptorType != USB_DT_INTERFACE || !ifp->bAlternateSetting) return parsed; } return parsed; }
vsf_err_t vsfusbh_probe_thread(struct vsfsm_pt_t *pt, vsfsm_evt_t evt) { vsf_err_t err; uint32_t len; struct vsfusbh_t *usbh = (struct vsfusbh_t *)pt->user_data; struct vsfusbh_urb_t *probe_urb = usbh->probe_urb; struct vsfusbh_device_t *dev = usbh->new_dev; vsfsm_pt_begin(pt); dev->devnum_temp = dev->devnum; dev->devnum = 0; dev->epmaxpacketin[0] = 8; dev->epmaxpacketout[0] = 8; probe_urb->vsfdev = dev; probe_urb->sm = &usbh->sm; probe_urb->timeout = DEFAULT_TIMEOUT; // get 8 bytes device descriptor probe_urb->transfer_buffer = &dev->descriptor; probe_urb->transfer_length = 8; err = vsfusbh_get_descriptor(usbh, probe_urb, USB_DT_DEVICE, 0); if (err != VSFERR_NONE) return err; vsfsm_pt_wfe(pt, VSFSM_EVT_URB_COMPLETE); if (probe_urb->status != URB_OK) return VSFERR_FAIL; dev->epmaxpacketin[0] = dev->descriptor.bMaxPacketSize0; dev->epmaxpacketout[0] = dev->descriptor.bMaxPacketSize0; // set address dev->devnum = dev->devnum_temp; probe_urb->transfer_buffer = NULL; probe_urb->transfer_length = 0; err = vsfusbh_set_address(usbh, probe_urb); if (err != VSFERR_NONE) return err; vsfsm_pt_wfe(pt, VSFSM_EVT_URB_COMPLETE); if (probe_urb->status != URB_OK) return VSFERR_FAIL; vsfsm_pt_delay(pt, 10); // get full device descriptor probe_urb->transfer_buffer = &dev->descriptor; probe_urb->transfer_length = sizeof(dev->descriptor); err = vsfusbh_get_descriptor(usbh, probe_urb, USB_DT_DEVICE, 0); if (err != VSFERR_NONE) return err; vsfsm_pt_wfe(pt, VSFSM_EVT_URB_COMPLETE); if (probe_urb->status != URB_OK) return VSFERR_FAIL; // NOTE: only probe first configuration if (dev->descriptor.bNumConfigurations < 1) return VSFERR_FAIL; dev->num_config = 1; // NOTE: not min(USB_MAXCONFIG, dev->descriptor.bNumConfigurations) len = sizeof(struct usb_config_t) * dev->num_config; dev->config = vsf_bufmgr_malloc_aligned(len, 4); if (dev->config == NULL) { vsf_bufmgr_free(probe_urb->transfer_buffer); return VSFERR_FAIL; } memset(dev->config, 0, sizeof(struct usb_config_t) * dev->num_config); for (dev->temp_u8 = 0; dev->temp_u8 < dev->num_config; dev->temp_u8++) { // get 9 bytes configuration probe_urb->transfer_buffer = vsf_bufmgr_malloc(9); if (probe_urb->transfer_buffer == NULL) goto get_config_fail; probe_urb->transfer_length = 9; err = vsfusbh_get_descriptor(usbh, probe_urb, USB_DT_CONFIG, dev->temp_u8); if (err != VSFERR_NONE) goto get_config_fail; vsfsm_pt_wfe(pt, VSFSM_EVT_URB_COMPLETE); if (probe_urb->status != URB_OK) goto get_config_fail; // get wTotalLength len = GET_U16_LSBFIRST(&((uint8_t *)(probe_urb->transfer_buffer))[2]); vsf_bufmgr_free(probe_urb->transfer_buffer); // get full configuation probe_urb->transfer_buffer = vsf_bufmgr_malloc(len); if (probe_urb->transfer_buffer == NULL) goto get_config_fail; probe_urb->transfer_length = len; err = vsfusbh_get_descriptor(usbh, probe_urb, USB_DT_CONFIG, dev->temp_u8); if (err != VSFERR_NONE) goto get_config_fail; vsfsm_pt_wfe(pt, VSFSM_EVT_URB_COMPLETE); if (probe_urb->status != URB_OK) goto get_config_fail; // check wTotalLength len = GET_U16_LSBFIRST(&((uint8_t *)(probe_urb->transfer_buffer))[2]); if (probe_urb->actual_length != len) goto get_config_fail; err = parse_configuration(dev->config + dev->temp_u8, probe_urb->transfer_buffer); if (err != VSFERR_NONE) goto get_config_fail; dev->config[dev->temp_u8].config_buffer = probe_urb->transfer_buffer; probe_urb->transfer_buffer = NULL; continue; get_config_fail: if (probe_urb->transfer_buffer != NULL) { vsf_bufmgr_free(probe_urb->transfer_buffer); probe_urb->transfer_buffer = NULL; } // NOTE: do not free dev->config here !!! return VSFERR_FAIL; } // set the default configuration probe_urb->transfer_buffer = NULL; probe_urb->transfer_length = 0; err = vsfusbh_set_configuration(usbh, probe_urb, dev->config->bConfigurationValue); if (err != VSFERR_NONE) return err; vsfsm_pt_wfe(pt, VSFSM_EVT_URB_COMPLETE); if (probe_urb->status != URB_OK) return VSFERR_FAIL; dev->actconfig = dev->config; vsfusbh_set_maxpacket_ep(dev); vsfsm_pt_end(pt); return VSFERR_NONE; }