Lines Matching +full:ctrl +full:- +full:len

2  * f_dfu.c -- Device Firmware Update USB function
8 * Based on OpenMoko u-boot: drivers/usb/usbdfu.c
13 * (C) Copyright 2006 by Harald Welte <hwelte at hmw-consulting.de>
15 * SPDX-License-Identifier: GPL-2.0+
89 * static strings, in UTF-8
99 .language = 0x0409, /* en-us */
112 .language = 0x0409, /* en-us */
142 dstat->bwPollTimeout[0] = 0; in dfu_set_poll_timeout()
143 dstat->bwPollTimeout[1] = 0; in dfu_set_poll_timeout()
144 dstat->bwPollTimeout[2] = 0; in dfu_set_poll_timeout()
149 dstat->bwPollTimeout[0] = *p++; in dfu_set_poll_timeout()
150 dstat->bwPollTimeout[1] = *p++; in dfu_set_poll_timeout()
151 dstat->bwPollTimeout[2] = *p; in dfu_set_poll_timeout()
154 /*-------------------------------------------------------------------------*/
158 struct f_dfu *f_dfu = req->context; in dnload_request_complete()
161 ret = dfu_write(dfu_get_entity(f_dfu->altsetting), req->buf, in dnload_request_complete()
162 req->actual, f_dfu->blk_seq_num); in dnload_request_complete()
164 f_dfu->dfu_status = DFU_STATUS_errUNKNOWN; in dnload_request_complete()
165 f_dfu->dfu_state = DFU_STATE_dfuERROR; in dnload_request_complete()
171 struct f_dfu *f_dfu = req->context; in dnload_request_flush()
172 dfu_set_defer_flush(dfu_get_entity(f_dfu->altsetting)); in dnload_request_flush()
177 return dfu->poll_timeout ? dfu->poll_timeout(dfu) : in dfu_get_manifest_timeout()
183 struct dfu_status *dstat = (struct dfu_status *)req->buf; in handle_getstatus()
184 struct f_dfu *f_dfu = req->context; in handle_getstatus()
185 struct dfu_entity *dfu = dfu_get_entity(f_dfu->altsetting); in handle_getstatus()
189 switch (f_dfu->dfu_state) { in handle_getstatus()
192 f_dfu->dfu_state = DFU_STATE_dfuDNLOAD_IDLE; in handle_getstatus()
195 f_dfu->dfu_state = DFU_STATE_dfuMANIFEST; in handle_getstatus()
204 if (f_dfu->poll_timeout) in handle_getstatus()
205 if (!(f_dfu->blk_seq_num % in handle_getstatus()
207 dfu_set_poll_timeout(dstat, f_dfu->poll_timeout); in handle_getstatus()
210 dstat->bStatus = f_dfu->dfu_status; in handle_getstatus()
211 dstat->bState = f_dfu->dfu_state; in handle_getstatus()
212 dstat->iString = 0; in handle_getstatus()
219 struct f_dfu *f_dfu = req->context; in handle_getstate()
221 ((u8 *)req->buf)[0] = f_dfu->dfu_state; in handle_getstate()
227 f_dfu->usb_function.strings = dfu_strings; in to_dfu_mode()
228 f_dfu->usb_function.hs_descriptors = f_dfu->function; in to_dfu_mode()
229 f_dfu->usb_function.descriptors = f_dfu->function; in to_dfu_mode()
230 f_dfu->dfu_state = DFU_STATE_dfuIDLE; in to_dfu_mode()
235 f_dfu->usb_function.strings = NULL; in to_runtime_mode()
236 f_dfu->usb_function.hs_descriptors = dfu_runtime_descs; in to_runtime_mode()
237 f_dfu->usb_function.descriptors = dfu_runtime_descs; in to_runtime_mode()
240 static int handle_upload(struct usb_request *req, u16 len) in handle_upload() argument
242 struct f_dfu *f_dfu = req->context; in handle_upload()
244 return dfu_read(dfu_get_entity(f_dfu->altsetting), req->buf, in handle_upload()
245 req->length, f_dfu->blk_seq_num); in handle_upload()
248 static int handle_dnload(struct usb_gadget *gadget, u16 len) in handle_dnload() argument
251 struct usb_request *req = cdev->req; in handle_dnload()
252 struct f_dfu *f_dfu = req->context; in handle_dnload()
254 if (len == 0) in handle_dnload()
255 f_dfu->dfu_state = DFU_STATE_dfuMANIFEST_SYNC; in handle_dnload()
257 req->complete = dnload_request_complete; in handle_dnload()
259 return len; in handle_dnload()
262 /*-------------------------------------------------------------------------*/
265 const struct usb_ctrlrequest *ctrl, in state_app_idle() argument
271 switch (ctrl->bRequest) { in state_app_idle()
279 f_dfu->dfu_state = DFU_STATE_appDETACH; in state_app_idle()
292 const struct usb_ctrlrequest *ctrl, in state_app_detach() argument
298 switch (ctrl->bRequest) { in state_app_detach()
306 f_dfu->dfu_state = DFU_STATE_appIDLE; in state_app_detach()
315 const struct usb_ctrlrequest *ctrl, in state_dfu_idle() argument
319 u16 w_value = le16_to_cpu(ctrl->wValue); in state_dfu_idle()
320 u16 len = le16_to_cpu(ctrl->wLength); in state_dfu_idle() local
323 switch (ctrl->bRequest) { in state_dfu_idle()
325 if (len == 0) { in state_dfu_idle()
326 f_dfu->dfu_state = DFU_STATE_dfuERROR; in state_dfu_idle()
330 f_dfu->dfu_state = DFU_STATE_dfuDNLOAD_SYNC; in state_dfu_idle()
331 f_dfu->blk_seq_num = w_value; in state_dfu_idle()
332 value = handle_dnload(gadget, len); in state_dfu_idle()
335 f_dfu->dfu_state = DFU_STATE_dfuUPLOAD_IDLE; in state_dfu_idle()
336 f_dfu->blk_seq_num = 0; in state_dfu_idle()
337 value = handle_upload(req, len); in state_dfu_idle()
358 f_dfu->dfu_state = in state_dfu_idle()
361 f_dfu->dfu_state = DFU_STATE_appIDLE; in state_dfu_idle()
366 f_dfu->dfu_state = DFU_STATE_dfuERROR; in state_dfu_idle()
375 const struct usb_ctrlrequest *ctrl, in state_dfu_dnload_sync() argument
381 switch (ctrl->bRequest) { in state_dfu_dnload_sync()
389 f_dfu->dfu_state = DFU_STATE_dfuERROR; in state_dfu_dnload_sync()
398 const struct usb_ctrlrequest *ctrl, in state_dfu_dnbusy() argument
404 switch (ctrl->bRequest) { in state_dfu_dnbusy()
409 f_dfu->dfu_state = DFU_STATE_dfuERROR; in state_dfu_dnbusy()
418 const struct usb_ctrlrequest *ctrl, in state_dfu_dnload_idle() argument
422 u16 w_value = le16_to_cpu(ctrl->wValue); in state_dfu_dnload_idle()
423 u16 len = le16_to_cpu(ctrl->wLength); in state_dfu_dnload_idle() local
426 switch (ctrl->bRequest) { in state_dfu_dnload_idle()
428 f_dfu->dfu_state = DFU_STATE_dfuDNLOAD_SYNC; in state_dfu_dnload_idle()
429 f_dfu->blk_seq_num = w_value; in state_dfu_dnload_idle()
430 value = handle_dnload(gadget, len); in state_dfu_dnload_idle()
433 f_dfu->dfu_state = DFU_STATE_dfuIDLE; in state_dfu_dnload_idle()
443 f_dfu->dfu_state = DFU_STATE_dfuERROR; in state_dfu_dnload_idle()
452 const struct usb_ctrlrequest *ctrl, in state_dfu_manifest_sync() argument
458 switch (ctrl->bRequest) { in state_dfu_manifest_sync()
461 f_dfu->dfu_state = DFU_STATE_dfuMANIFEST; in state_dfu_manifest_sync()
463 f_dfu->blk_seq_num = 0; in state_dfu_manifest_sync()
464 req->complete = dnload_request_flush; in state_dfu_manifest_sync()
470 f_dfu->dfu_state = DFU_STATE_dfuERROR; in state_dfu_manifest_sync()
479 const struct usb_ctrlrequest *ctrl, in state_dfu_manifest() argument
485 switch (ctrl->bRequest) { in state_dfu_manifest()
488 f_dfu->dfu_state = DFU_STATE_dfuIDLE; in state_dfu_manifest()
490 f_dfu->blk_seq_num = 0; in state_dfu_manifest()
497 f_dfu->dfu_state = DFU_STATE_dfuERROR; in state_dfu_manifest()
505 const struct usb_ctrlrequest *ctrl, in state_dfu_upload_idle() argument
509 u16 w_value = le16_to_cpu(ctrl->wValue); in state_dfu_upload_idle()
510 u16 len = le16_to_cpu(ctrl->wLength); in state_dfu_upload_idle() local
513 switch (ctrl->bRequest) { in state_dfu_upload_idle()
516 f_dfu->blk_seq_num = w_value; in state_dfu_upload_idle()
517 value = handle_upload(req, len); in state_dfu_upload_idle()
518 if (value >= 0 && value < len) in state_dfu_upload_idle()
519 f_dfu->dfu_state = DFU_STATE_dfuIDLE; in state_dfu_upload_idle()
522 f_dfu->dfu_state = DFU_STATE_dfuIDLE; in state_dfu_upload_idle()
533 f_dfu->dfu_state = DFU_STATE_dfuERROR; in state_dfu_upload_idle()
542 const struct usb_ctrlrequest *ctrl, in state_dfu_error() argument
548 switch (ctrl->bRequest) { in state_dfu_error()
556 f_dfu->dfu_state = DFU_STATE_dfuIDLE; in state_dfu_error()
557 f_dfu->dfu_status = DFU_STATUS_OK; in state_dfu_error()
562 f_dfu->dfu_state = DFU_STATE_dfuERROR; in state_dfu_error()
585 dfu_handle(struct usb_function *f, const struct usb_ctrlrequest *ctrl) in dfu_handle() argument
587 struct usb_gadget *gadget = f->config->cdev->gadget; in dfu_handle()
588 struct usb_request *req = f->config->cdev->req; in dfu_handle()
589 struct f_dfu *f_dfu = f->config->cdev->req->context; in dfu_handle()
590 u16 len = le16_to_cpu(ctrl->wLength); in dfu_handle() local
591 u16 w_value = le16_to_cpu(ctrl->wValue); in dfu_handle()
593 u8 req_type = ctrl->bRequestType & USB_TYPE_MASK; in dfu_handle()
595 debug("w_value: 0x%x len: 0x%x\n", w_value, len); in dfu_handle()
596 debug("req_type: 0x%x ctrl->bRequest: 0x%x f_dfu->dfu_state: 0x%x\n", in dfu_handle()
597 req_type, ctrl->bRequest, f_dfu->dfu_state); in dfu_handle()
600 if (ctrl->bRequest == USB_REQ_GET_DESCRIPTOR && in dfu_handle()
602 value = min(len, (u16) sizeof(dfu_func)); in dfu_handle()
603 memcpy(req->buf, &dfu_func, value); in dfu_handle()
606 value = dfu_state[f_dfu->dfu_state] (f_dfu, ctrl, gadget, req); in dfu_handle()
609 req->length = value; in dfu_handle()
610 req->zero = value < len; in dfu_handle()
611 value = usb_ep_queue(gadget->ep0, req, 0); in dfu_handle()
613 debug("ep_queue --> %d\n", value); in dfu_handle()
614 req->status = 0; in dfu_handle()
621 /*-------------------------------------------------------------------------*/
629 f_dfu->strings = calloc(sizeof(struct usb_string), n + 1); in dfu_prepare_strings()
630 if (!f_dfu->strings) in dfu_prepare_strings()
631 return -ENOMEM; in dfu_prepare_strings()
635 f_dfu->strings[i].s = de->name; in dfu_prepare_strings()
638 f_dfu->strings[i].id = 0; in dfu_prepare_strings()
639 f_dfu->strings[i].s = NULL; in dfu_prepare_strings()
649 f_dfu->function = calloc(sizeof(struct usb_descriptor_header *), n + 2); in dfu_prepare_function()
650 if (!f_dfu->function) in dfu_prepare_function()
658 d->bLength = sizeof(*d); in dfu_prepare_function()
659 d->bDescriptorType = USB_DT_INTERFACE; in dfu_prepare_function()
660 d->bAlternateSetting = i; in dfu_prepare_function()
661 d->bNumEndpoints = 0; in dfu_prepare_function()
662 d->bInterfaceClass = USB_CLASS_APP_SPEC; in dfu_prepare_function()
663 d->bInterfaceSubClass = 1; in dfu_prepare_function()
664 d->bInterfaceProtocol = 2; in dfu_prepare_function()
666 f_dfu->function[i] = (struct usb_descriptor_header *)d; in dfu_prepare_function()
670 f_dfu->function[i] = calloc(sizeof(dfu_func), 1); in dfu_prepare_function()
671 if (!f_dfu->function[i]) in dfu_prepare_function()
673 memcpy(f_dfu->function[i], &dfu_func, sizeof(dfu_func)); in dfu_prepare_function()
676 f_dfu->function[i] = NULL; in dfu_prepare_function()
682 free(f_dfu->function[--i]); in dfu_prepare_function()
683 f_dfu->function[i] = NULL; in dfu_prepare_function()
685 free(f_dfu->function); in dfu_prepare_function()
687 return -ENOMEM; in dfu_prepare_function()
692 struct usb_composite_dev *cdev = c->cdev; in dfu_bind()
703 f_dfu->dfu_state = DFU_STATE_appIDLE; in dfu_bind()
704 f_dfu->dfu_status = DFU_STATUS_OK; in dfu_bind()
717 f_dfu->strings[i].id = id; in dfu_bind()
718 ((struct usb_interface_descriptor *)f_dfu->function[i]) in dfu_bind()
719 ->iInterface = id; in dfu_bind()
724 stringtab_dfu.strings = f_dfu->strings; in dfu_bind()
726 cdev->req->context = f_dfu; in dfu_bind()
742 if (f_dfu->strings) { in dfu_unbind()
745 f_dfu->strings[--i].s = NULL; in dfu_unbind()
747 free(f_dfu->strings); in dfu_unbind()
750 if (f_dfu->function) { in dfu_unbind()
754 free(f_dfu->function[--i]); in dfu_unbind()
755 f_dfu->function[i] = NULL; in dfu_unbind()
757 free(f_dfu->function); in dfu_unbind()
769 f_dfu->altsetting = alt; in dfu_set_alt()
770 f_dfu->dfu_state = DFU_STATE_dfuIDLE; in dfu_set_alt()
771 f_dfu->dfu_status = DFU_STATUS_OK; in dfu_set_alt()
780 return f_dfu->altsetting; in __dfu_get_alt()
787 if (f_dfu->config == 0) in dfu_disable()
792 f_dfu->config = 0; in dfu_disable()
802 return -ENOMEM; in dfu_bind_config()
803 f_dfu->usb_function.name = "dfu"; in dfu_bind_config()
804 f_dfu->usb_function.hs_descriptors = dfu_runtime_descs; in dfu_bind_config()
805 f_dfu->usb_function.descriptors = dfu_runtime_descs; in dfu_bind_config()
806 f_dfu->usb_function.bind = dfu_bind; in dfu_bind_config()
807 f_dfu->usb_function.unbind = dfu_unbind; in dfu_bind_config()
808 f_dfu->usb_function.set_alt = dfu_set_alt; in dfu_bind_config()
809 f_dfu->usb_function.get_alt = __dfu_get_alt; in dfu_bind_config()
810 f_dfu->usb_function.disable = dfu_disable; in dfu_bind_config()
811 f_dfu->usb_function.strings = dfu_generic_strings; in dfu_bind_config()
812 f_dfu->usb_function.setup = dfu_handle; in dfu_bind_config()
813 f_dfu->poll_timeout = DFU_DEFAULT_POLL_TIMEOUT; in dfu_bind_config()
815 status = usb_add_function(c, &f_dfu->usb_function); in dfu_bind_config()
826 id = usb_string_id(c->cdev); in dfu_add()
832 debug("%s: cdev: 0x%p gadget:0x%p gadget->ep0: 0x%p\n", __func__, in dfu_add()
833 c->cdev, c->cdev->gadget, c->cdev->gadget->ep0); in dfu_add()