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; }
static void vsfusbh_uvc_free(struct vsfusbh_device_t *dev) { struct vsfusbh_class_data_t *cdata = (struct vsfusbh_class_data_t *)(dev->priv); struct vsfusbh_uvc_t *hdata = (struct vsfusbh_uvc_t *)cdata->param; // free urb vsf_bufmgr_free(hdata); vsf_bufmgr_free(cdata); }
static void vsfshell_free_param(struct vsfshell_handler_param_t *param) { uint32_t i; for (i = 0; i < dimof(param->argv); i++) { if (param->argv[i] != NULL) { vsf_bufmgr_free(param->argv[i]); } } vsf_bufmgr_free(param); }
void vsfusbh_disconnect_device(struct vsfusbh_t *usbh, struct vsfusbh_device_t **pdev) { struct vsfusbh_device_t *dev = *pdev; uint8_t i; if (!dev) return; *pdev = NULL; if (dev->actconfig) { for (i = 0; i < dev->actconfig->bNumInterfaces; i++) vsfusbh_remove_interface(usbh, dev, dev->actconfig->interface + i); } for (i = 0; i < USB_MAXCHILDREN; i++) { if (dev->children[i]) { vsfusbh_disconnect_device(usbh, &dev->children[i]); } } vsfusbh_free_device(usbh, dev); vsf_bufmgr_free(dev); }
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; }
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; }
void vsfusbh_free_device(struct vsfusbh_t *usbh, struct vsfusbh_device_t *dev) { uint8_t i, j, k; struct usb_config_t *config; struct usb_interface_t *interface; struct usb_interface_desc_t *itd; if (dev->devnum != 0) mskarr_clr(usbh->device_bitmap, dev->devnum); usbh->hcd->free_device(usbh->hcd_data, dev); if (dev->config != NULL) { config = dev->config; for (i = 0; i < dev->num_config; i++) { if (config[i].interface != NULL) { interface = config[i].interface; for (j = 0; j < config[i].bNumInterfaces; j++) { if (interface[j].altsetting != NULL) { itd = interface[j].altsetting; for (k = 0; k < interface[j].num_altsetting; k++) { if (itd[k].ep_desc != NULL) vsf_bufmgr_free(itd[k].ep_desc); } vsf_bufmgr_free(itd); } } vsf_bufmgr_free(interface); } if (dev->config[i].config_buffer != NULL) vsf_bufmgr_free(dev->config[i].config_buffer); } vsf_bufmgr_free(dev->config); dev->config = NULL; } }
static void vsfusbh_hub_disconnect(struct vsfusbh_t *usbh, struct vsfusbh_device_t *dev, void *priv) { struct vsfusbh_hub_t *hub = priv; if (hub->vsfurb != NULL) usbh->hcd->free_urb(usbh->hcd_data, &hub->vsfurb); vsfsm_fini(&hub->sm); vsf_bufmgr_free(hub); }
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; }
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; }
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; }
void vsf_module_unload(char *name) { struct vsf_module_t *module = vsf_module_get(name); vsf_err_t (*mod_exit)(struct vsf_module_t *); if ((module != NULL) && (module->code_buff != NULL)) { if (module->flash->exit) { mod_exit = (vsf_err_t (*)(struct vsf_module_t *)) (module->code_buff + module->flash->exit); mod_exit(module); } #ifdef VSFCFG_MODULE_ALLOC_RAM if (module->flash->size > 0) { vsf_bufmgr_free(module->code_buff); } #endif module->code_buff = NULL; } }
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; }
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; }
void vsfusbd_CDC_modexit(struct vsf_module_t *module) { vsf_bufmgr_free(module->ifs); module->ifs = NULL; }
vsf_err_t embflash_modexit(struct vsf_module_t *module) { vsf_bufmgr_free(module->ifs); module->ifs = NULL; return VSFERR_NONE; }
vsf_err_t vsfusbh_add_device(struct vsfusbh_t *usbh, struct vsfusbh_device_t *dev) { uint8_t i, j, k, claimed = 0; #if 0 uint8_t rejected = 0; #endif vsfsm_crit_init(&dev->ep0_crit, VSFSM_EVT_EP0_CRIT); for (i = 0; i < dev->actconfig->bNumInterfaces; i++) { if (dev->actconfig->interface[i].driver == NULL) { if (vsfusbh_find_intrface_driver(usbh, dev, i) == VSFERR_NONE) claimed++; #if 0 else rejected++; #endif } } // clear all 'extra' pointer // free config_buffer if (dev->config != NULL) { for (i = 0; i < dev->num_config; i++) { //dev->config[i].extra = NULL; if (dev->config[i].interface != NULL) { struct usb_interface_desc_t *altsetting = dev->config[i].interface->altsetting; if (altsetting != NULL) { for (j = 0; j < dev->config[i].interface->num_altsetting; j++) { altsetting[j].extra = NULL; if (altsetting[j].ep_desc != NULL) { for (k = 0; k < altsetting[j].bNumEndpoints; k++) { altsetting[j].ep_desc[k].extra = NULL; } } } } } if (dev->config[i].config_buffer != NULL) vsf_bufmgr_free(dev->config[i].config_buffer); dev->config[i].config_buffer = NULL; } } #if 0 if (rejected); // unhandled interfaces on device #endif if (claimed == 0) return VSFERR_NOT_SUPPORT; else return VSFERR_NONE; }
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; }
vsf_err_t vsfusbh_hub_modexit(struct vsf_module_t *module) { vsf_bufmgr_free(module->ifs); module->ifs = NULL; return VSFERR_NONE; }
static vsf_err_t uvc_ctrl_thread(struct vsfsm_pt_t *pt, vsfsm_evt_t evt) { vsf_err_t err; struct vsfusbh_uvc_t *hdata = (struct vsfusbh_uvc_t *)pt->user_data; struct vsfusbh_urb_t *vsfurb = &hdata->ctrl_urb; vsfsm_pt_begin(pt); if (hdata->set_param.video_enable) { // negotiate hdata->video_iso_packet_len = 1024; hdata->video_iso_ep = 1; // commit param vsfurb->transfer_buffer = hdata->ctrl_urb_buf; memcpy(vsfurb->transfer_buffer, negotiate_temp, 26); vsfurb->transfer_length = 26; vsfurb->pipe = usb_sndctrlpipe(vsfurb->vsfdev, 0); err = vsfusbh_control_msg(hdata->usbh, vsfurb, USB_TYPE_CLASS |USB_RECIP_INTERFACE | USB_DIR_OUT, SET_CUR, 0x0200, 0x0001); if (err != VSFERR_NONE) return err; vsfsm_pt_wfe(pt, VSFSM_EVT_URB_COMPLETE); if (vsfurb->status != URB_OK) return VSFERR_FAIL; // set interfaces vsfurb->transfer_buffer = NULL; vsfurb->transfer_length = 0; err = vsfusbh_set_interface(hdata->usbh, vsfurb, 1, 4); if (err != VSFERR_NONE) return err; vsfsm_pt_wfe(pt, VSFSM_EVT_URB_COMPLETE); if (vsfurb->status != URB_OK) return VSFERR_FAIL; // enable video vsfsm_post_evt_pending(&hdata->video_sm, UAV_ISO_ENABLE); } else { vsfurb->transfer_buffer = NULL; vsfurb->transfer_length = 0; err = vsfusbh_set_interface(hdata->usbh, vsfurb, 1, 0); if (err != VSFERR_NONE) return err; vsfsm_pt_wfe(pt, VSFSM_EVT_URB_COMPLETE); if (vsfurb->status != URB_OK) return VSFERR_FAIL; } vsf_bufmgr_free(hdata->ctrl_urb_buf); hdata->ctrl_urb_buf = NULL; memcpy(&hdata->cur_param, &hdata->set_param, sizeof(struct vsfusbh_uvc_param_t)); vsfusbh_uvc_report(hdata, &hdata->cur_param, NULL); vsfsm_pt_end(pt); return VSFERR_NONE; }