Lines Matching +full:iso +full:- +full:out +full:- +full:mps

2  * Copyright (c) 2021-2022 Nordic Semiconductor ASA
4 * SPDX-License-Identifier: Apache-2.0
27 struct net_buf_pool *const buf_pool = net_buf_pool_get(buf->pool_id); in udc_pool_data_alloc()
28 struct k_heap *const pool = buf_pool->alloc->alloc_data; in udc_pool_data_alloc()
43 struct net_buf_pool *buf_pool = net_buf_pool_get(buf->pool_id); in udc_pool_data_unref()
44 struct k_heap *pool = buf_pool->alloc->alloc_data; in udc_pool_data_unref()
65 struct udc_data *data = dev->data; in udc_set_suspended()
71 atomic_set_bit_to(&data->status, UDC_STATUS_SUSPENDED, value); in udc_set_suspended()
76 struct udc_data *data = dev->data; in udc_get_ep_cfg()
78 return data->ep_lut[USB_EP_LUT_IDX(ep)]; in udc_get_ep_cfg()
88 return ep_cfg->stat.busy; in udc_ep_is_busy()
97 ep_cfg->stat.busy = busy; in udc_ep_set_busy()
102 struct udc_data *data = dev->data; in udc_register_ep()
106 return -EACCES; in udc_register_ep()
109 idx = USB_EP_LUT_IDX(cfg->addr); in udc_register_ep()
110 __ASSERT_NO_MSG(idx < ARRAY_SIZE(data->ep_lut)); in udc_register_ep()
112 data->ep_lut[idx] = cfg; in udc_register_ep()
113 k_fifo_init(&cfg->fifo); in udc_register_ep()
127 return k_fifo_get(&ep_cfg->fifo, K_NO_WAIT); in udc_buf_get()
140 buf = k_fifo_get(&ep_cfg->fifo, K_NO_WAIT); in udc_buf_get_all()
146 for (struct net_buf *n = buf; !k_fifo_is_empty(&ep_cfg->fifo); n = n->frags) { in udc_buf_get_all()
147 n->frags = k_fifo_get(&ep_cfg->fifo, K_NO_WAIT); in udc_buf_get_all()
148 LOG_DBG("|-> %p ", n->frags); in udc_buf_get_all()
149 if (n->frags == NULL) { in udc_buf_get_all()
166 return k_fifo_peek_head(&ep_cfg->fifo); in udc_buf_peek()
172 k_fifo_put(&ep_cfg->fifo, buf); in udc_buf_put()
179 bi->setup = 1; in udc_ep_buf_set_setup()
180 bi->data = 0; in udc_ep_buf_set_setup()
181 bi->status = 0; in udc_ep_buf_set_setup()
188 return bi->zlp; in udc_ep_buf_has_zlp()
195 bi->zlp = false; in udc_ep_buf_clear_zlp()
202 struct udc_data *data = dev->data; in udc_submit_event()
209 return data->event_cb(dev, &drv_evt); in udc_submit_event()
217 struct udc_data *data = dev->data; in udc_submit_ep_event()
225 return -EPERM; in udc_submit_ep_event()
228 bi->err = err; in udc_submit_ep_event()
230 return data->event_cb(dev, &drv_evt); in udc_submit_ep_event()
242 const uint16_t mps, in ep_check_config() argument
248 LOG_DBG("cfg d:%c|%c t:%c|%c|%c|%c, mps %u", in ep_check_config()
249 cfg->caps.in ? 'I' : '-', in ep_check_config()
250 cfg->caps.out ? 'O' : '-', in ep_check_config()
251 cfg->caps.iso ? 'S' : '-', in ep_check_config()
252 cfg->caps.bulk ? 'B' : '-', in ep_check_config()
253 cfg->caps.interrupt ? 'I' : '-', in ep_check_config()
254 cfg->caps.control ? 'C' : '-', in ep_check_config()
255 cfg->caps.mps); in ep_check_config()
257 if (dir_is_out && !cfg->caps.out) { in ep_check_config()
261 if (dir_is_in && !cfg->caps.in) { in ep_check_config()
265 if (USB_MPS_EP_SIZE(mps) > USB_MPS_EP_SIZE(cfg->caps.mps)) { in ep_check_config()
271 if (!cfg->caps.bulk) { in ep_check_config()
276 if (!cfg->caps.interrupt || in ep_check_config()
277 (USB_MPS_ADDITIONAL_TRANSACTIONS(mps) && in ep_check_config()
278 !cfg->caps.high_bandwidth)) { in ep_check_config()
283 if (!cfg->caps.iso || in ep_check_config()
284 (USB_MPS_ADDITIONAL_TRANSACTIONS(mps) && in ep_check_config()
285 !cfg->caps.high_bandwidth)) { in ep_check_config()
290 if (!cfg->caps.control) { in ep_check_config()
304 uint16_t *const mps) in ep_update_mps() argument
317 *mps = MIN(cfg->caps.mps, spec_bulk_mps); in ep_update_mps()
320 *mps = MIN(cfg->caps.mps, spec_int_mps); in ep_update_mps()
334 uint16_t *const mps, in udc_ep_try_config() argument
337 const struct udc_api *api = dev->api; in udc_ep_try_config()
343 return -ENODEV; in udc_ep_try_config()
346 api->lock(dev); in udc_ep_try_config()
348 ret = ep_check_config(dev, cfg, ep, attributes, *mps, interval); in udc_ep_try_config()
349 if (ret == true && *mps == 0U) { in udc_ep_try_config()
350 ep_update_mps(dev, cfg, attributes, mps); in udc_ep_try_config()
353 api->unlock(dev); in udc_ep_try_config()
355 return (ret == false) ? -ENOTSUP : 0; in udc_ep_try_config()
361 const uint16_t mps, in udc_ep_enable_internal() argument
364 const struct udc_api *api = dev->api; in udc_ep_enable_internal()
370 return -ENODEV; in udc_ep_enable_internal()
373 if (cfg->stat.enabled) { in udc_ep_enable_internal()
374 LOG_ERR("ep 0x%02x already enabled", cfg->addr); in udc_ep_enable_internal()
375 return -EALREADY; in udc_ep_enable_internal()
378 if (!ep_check_config(dev, cfg, ep, attributes, mps, interval)) { in udc_ep_enable_internal()
379 LOG_ERR("Endpoint 0x%02x validation failed", cfg->addr); in udc_ep_enable_internal()
380 return -ENODEV; in udc_ep_enable_internal()
383 cfg->attributes = attributes; in udc_ep_enable_internal()
384 cfg->mps = mps; in udc_ep_enable_internal()
385 cfg->interval = interval; in udc_ep_enable_internal()
387 cfg->stat.odd = 0; in udc_ep_enable_internal()
388 cfg->stat.halted = 0; in udc_ep_enable_internal()
389 cfg->stat.data1 = false; in udc_ep_enable_internal()
390 ret = api->ep_enable(dev, cfg); in udc_ep_enable_internal()
391 cfg->stat.enabled = ret ? false : true; in udc_ep_enable_internal()
399 const uint16_t mps, in udc_ep_enable() argument
402 const struct udc_api *api = dev->api; in udc_ep_enable()
406 return -EINVAL; in udc_ep_enable()
409 api->lock(dev); in udc_ep_enable()
412 ret = -EPERM; in udc_ep_enable()
416 ret = udc_ep_enable_internal(dev, ep, attributes, mps, interval); in udc_ep_enable()
419 api->unlock(dev); in udc_ep_enable()
426 const struct udc_api *api = dev->api; in udc_ep_disable_internal()
432 return -ENODEV; in udc_ep_disable_internal()
435 if (!cfg->stat.enabled) { in udc_ep_disable_internal()
436 LOG_ERR("ep 0x%02x already disabled", cfg->addr); in udc_ep_disable_internal()
437 return -EALREADY; in udc_ep_disable_internal()
440 ret = api->ep_disable(dev, cfg); in udc_ep_disable_internal()
441 cfg->stat.enabled = ret ? cfg->stat.enabled : false; in udc_ep_disable_internal()
448 const struct udc_api *api = dev->api; in udc_ep_disable()
452 return -EINVAL; in udc_ep_disable()
455 api->lock(dev); in udc_ep_disable()
458 ret = -EPERM; in udc_ep_disable()
465 api->unlock(dev); in udc_ep_disable()
472 const struct udc_api *api = dev->api; in udc_ep_set_halt()
476 api->lock(dev); in udc_ep_set_halt()
479 ret = -EPERM; in udc_ep_set_halt()
485 ret = -ENODEV; in udc_ep_set_halt()
489 if (!cfg->stat.enabled) { in udc_ep_set_halt()
490 ret = -ENODEV; in udc_ep_set_halt()
494 if (ep_attrib_get_transfer(cfg->attributes) == USB_EP_TYPE_ISO) { in udc_ep_set_halt()
495 ret = -ENOTSUP; in udc_ep_set_halt()
499 ret = api->ep_set_halt(dev, cfg); in udc_ep_set_halt()
502 api->unlock(dev); in udc_ep_set_halt()
509 const struct udc_api *api = dev->api; in udc_ep_clear_halt()
513 api->lock(dev); in udc_ep_clear_halt()
516 ret = -EPERM; in udc_ep_clear_halt()
522 ret = -ENODEV; in udc_ep_clear_halt()
526 if (!cfg->stat.enabled) { in udc_ep_clear_halt()
527 ret = -ENODEV; in udc_ep_clear_halt()
531 if (ep_attrib_get_transfer(cfg->attributes) == USB_EP_TYPE_ISO) { in udc_ep_clear_halt()
532 ret = -ENOTSUP; in udc_ep_clear_halt()
536 ret = api->ep_clear_halt(dev, cfg); in udc_ep_clear_halt()
538 cfg->stat.halted = false; in udc_ep_clear_halt()
542 api->unlock(dev); in udc_ep_clear_halt()
554 list.head = k_fifo_peek_head(&cfg->fifo); in udc_debug_ep_enqueue()
555 list.tail = k_fifo_peek_tail(&cfg->fifo); in udc_debug_ep_enqueue()
557 LOG_DBG("ep 0x%02x queue is empty", cfg->addr); in udc_debug_ep_enqueue()
561 LOG_DBG("[de]queue ep 0x%02x:", cfg->addr); in udc_debug_ep_enqueue()
565 LOG_DBG("|-> %p (%u) ->", buf, buf->size); in udc_debug_ep_enqueue()
571 const struct udc_api *api = dev->api; in udc_ep_enqueue()
576 api->lock(dev); in udc_ep_enqueue()
579 ret = -EPERM; in udc_ep_enqueue()
584 if (bi->ep == USB_CONTROL_EP_OUT) { in udc_ep_enqueue()
585 ret = -EPERM; in udc_ep_enqueue()
589 cfg = udc_get_ep_cfg(dev, bi->ep); in udc_ep_enqueue()
591 ret = -ENODEV; in udc_ep_enqueue()
595 if (!cfg->stat.enabled) { in udc_ep_enqueue()
596 ret = -ENODEV; in udc_ep_enqueue()
600 LOG_DBG("Queue ep 0x%02x %p len %u", cfg->addr, buf, in udc_ep_enqueue()
601 USB_EP_DIR_IS_IN(cfg->addr) ? buf->len : buf->size); in udc_ep_enqueue()
603 bi->setup = 0; in udc_ep_enqueue()
604 ret = api->ep_enqueue(dev, cfg, buf); in udc_ep_enqueue()
607 api->unlock(dev); in udc_ep_enqueue()
614 const struct udc_api *api = dev->api; in udc_ep_dequeue()
618 api->lock(dev); in udc_ep_dequeue()
621 ret = -EPERM; in udc_ep_dequeue()
627 ret = -ENODEV; in udc_ep_dequeue()
631 if (cfg->stat.enabled || cfg->stat.halted) { in udc_ep_dequeue()
632 LOG_INF("ep 0x%02x is not halted|disabled", cfg->addr); in udc_ep_dequeue()
639 if (k_fifo_is_empty(&cfg->fifo)) { in udc_ep_dequeue()
642 ret = api->ep_dequeue(dev, cfg); in udc_ep_dequeue()
646 api->unlock(dev); in udc_ep_dequeue()
655 const struct udc_api *api = dev->api; in udc_ep_buf_alloc()
659 api->lock(dev); in udc_ep_buf_alloc()
668 bi->ep = ep; in udc_ep_buf_alloc()
672 api->unlock(dev); in udc_ep_buf_alloc()
694 const struct udc_api *api = dev->api; in udc_ep_buf_free()
697 api->lock(dev); in udc_ep_buf_free()
699 api->unlock(dev); in udc_ep_buf_free()
706 const struct udc_api *api = dev->api; in udc_device_speed()
709 api->lock(dev); in udc_device_speed()
715 if (api->device_speed) { in udc_device_speed()
716 speed = api->device_speed(dev); in udc_device_speed()
723 api->unlock(dev); in udc_device_speed()
730 const struct udc_api *api = dev->api; in udc_enable()
731 struct udc_data *data = dev->data; in udc_enable()
734 api->lock(dev); in udc_enable()
737 ret = -EPERM; in udc_enable()
742 ret = -EALREADY; in udc_enable()
746 data->stage = CTRL_PIPE_STAGE_SETUP; in udc_enable()
748 ret = api->enable(dev); in udc_enable()
750 atomic_set_bit(&data->status, UDC_STATUS_ENABLED); in udc_enable()
754 api->unlock(dev); in udc_enable()
761 const struct udc_api *api = dev->api; in udc_disable()
762 struct udc_data *data = dev->data; in udc_disable()
765 api->lock(dev); in udc_disable()
768 ret = -EALREADY; in udc_disable()
772 ret = api->disable(dev); in udc_disable()
773 atomic_clear_bit(&data->status, UDC_STATUS_ENABLED); in udc_disable()
776 api->unlock(dev); in udc_disable()
784 const struct udc_api *api = dev->api; in udc_init()
785 struct udc_data *data = dev->data; in udc_init()
789 return -EINVAL; in udc_init()
792 api->lock(dev); in udc_init()
795 ret = -EALREADY; in udc_init()
799 data->event_cb = event_cb; in udc_init()
800 data->event_ctx = event_ctx; in udc_init()
802 ret = api->init(dev); in udc_init()
804 atomic_set_bit(&data->status, UDC_STATUS_INITIALIZED); in udc_init()
808 api->unlock(dev); in udc_init()
815 const struct udc_api *api = dev->api; in udc_shutdown()
816 struct udc_data *data = dev->data; in udc_shutdown()
819 api->lock(dev); in udc_shutdown()
822 ret = -EBUSY; in udc_shutdown()
827 ret = -EALREADY; in udc_shutdown()
831 ret = api->shutdown(dev); in udc_shutdown()
832 atomic_clear_bit(&data->status, UDC_STATUS_INITIALIZED); in udc_shutdown()
835 api->unlock(dev); in udc_shutdown()
871 bi->data = true; in udc_ctrl_alloc_data()
888 bi->status = true; in udc_ctrl_alloc_status()
898 struct udc_data *data = dev->data; in udc_ctrl_submit_s_out_status()
902 bi->data = true; in udc_ctrl_submit_s_out_status()
903 net_buf_frag_add(data->setup, dout); in udc_ctrl_submit_s_out_status()
907 ret = -ENOMEM; in udc_ctrl_submit_s_out_status()
910 return udc_submit_ep_event(dev, data->setup, ret); in udc_ctrl_submit_s_out_status()
915 struct udc_data *data = dev->data; in udc_ctrl_submit_s_in_status()
920 return -ENOTSUP; in udc_ctrl_submit_s_in_status()
924 buf = udc_ctrl_alloc_data(dev, data->setup, USB_CONTROL_EP_IN); in udc_ctrl_submit_s_in_status()
926 ret = -ENOMEM; in udc_ctrl_submit_s_in_status()
929 return udc_submit_ep_event(dev, data->setup, ret); in udc_ctrl_submit_s_in_status()
934 struct udc_data *data = dev->data; in udc_ctrl_submit_s_status()
939 buf = udc_ctrl_alloc_status(dev, data->setup, USB_CONTROL_EP_IN); in udc_ctrl_submit_s_status()
941 ret = -ENOMEM; in udc_ctrl_submit_s_status()
944 return udc_submit_ep_event(dev, data->setup, ret); in udc_ctrl_submit_s_status()
952 bi->status = true; in udc_ctrl_submit_status()
959 struct udc_data *data = dev->data; in udc_ctrl_stage_is_data_out()
961 return data->stage == CTRL_PIPE_STAGE_DATA_OUT ? true : false; in udc_ctrl_stage_is_data_out()
966 struct udc_data *data = dev->data; in udc_ctrl_stage_is_data_in()
968 return data->stage == CTRL_PIPE_STAGE_DATA_IN ? true : false; in udc_ctrl_stage_is_data_in()
973 struct udc_data *data = dev->data; in udc_ctrl_stage_is_status_out()
975 return data->stage == CTRL_PIPE_STAGE_STATUS_OUT ? true : false; in udc_ctrl_stage_is_status_out()
980 struct udc_data *data = dev->data; in udc_ctrl_stage_is_status_in()
982 return data->stage == CTRL_PIPE_STAGE_STATUS_IN ? true : false; in udc_ctrl_stage_is_status_in()
987 struct udc_data *data = dev->data; in udc_ctrl_stage_is_no_data()
989 return data->stage == CTRL_PIPE_STAGE_NO_DATA ? true : false; in udc_ctrl_stage_is_no_data()
994 struct usb_setup_packet *setup = (void *)buf->data; in udc_data_stage_to_host()
996 return USB_REQTYPE_GET_DIR(setup->bmRequestType); in udc_data_stage_to_host()
1005 struct udc_data *data = dev->data; in udc_ctrl_update_stage()
1007 __ASSERT(USB_EP_GET_IDX(bi->ep) == 0, in udc_ctrl_update_stage()
1008 "0x%02x is not a control endpoint", bi->ep); in udc_ctrl_update_stage()
1010 if (bi->setup && bi->ep == USB_CONTROL_EP_OUT) { in udc_ctrl_update_stage()
1013 data->setup = buf; in udc_ctrl_update_stage()
1015 if (data->stage != CTRL_PIPE_STAGE_SETUP) { in udc_ctrl_update_stage()
1016 LOG_INF("Sequence %u not completed", data->stage); in udc_ctrl_update_stage()
1017 data->stage = CTRL_PIPE_STAGE_SETUP; in udc_ctrl_update_stage()
1028 * complete sequence: s->status in udc_ctrl_update_stage()
1030 LOG_DBG("s->(status)"); in udc_ctrl_update_stage()
1035 * complete sequence: s->in->status in udc_ctrl_update_stage()
1037 LOG_DBG("s->(in)"); in udc_ctrl_update_stage()
1041 * Next is Data Stage (to device / OUT) in udc_ctrl_update_stage()
1042 * complete sequence: s->out->status in udc_ctrl_update_stage()
1044 LOG_DBG("s->(out)"); in udc_ctrl_update_stage()
1048 } else if (bi->ep == USB_CONTROL_EP_OUT) { in udc_ctrl_update_stage()
1049 if (data->stage == CTRL_PIPE_STAGE_DATA_OUT) { in udc_ctrl_update_stage()
1055 } else if (data->stage == CTRL_PIPE_STAGE_STATUS_OUT) { in udc_ctrl_update_stage()
1057 * End of a sequence: s->in->status, in udc_ctrl_update_stage()
1059 * submit a OUT request with the minimum length in udc_ctrl_update_stage()
1062 if (buf->len == 0) { in udc_ctrl_update_stage()
1063 LOG_DBG("s-in-status"); in udc_ctrl_update_stage()
1074 } else { /* if (bi->ep == USB_CONTROL_EP_IN) */ in udc_ctrl_update_stage()
1075 if (data->stage == CTRL_PIPE_STAGE_STATUS_IN) { in udc_ctrl_update_stage()
1077 * End of a sequence: setup->out->in in udc_ctrl_update_stage()
1079 LOG_DBG("s-out-status"); in udc_ctrl_update_stage()
1081 } else if (data->stage == CTRL_PIPE_STAGE_DATA_IN) { in udc_ctrl_update_stage()
1084 * is Status Stage (OUT ZLP status to device). in udc_ctrl_update_stage()
1085 * over-engineered controllers can send status in udc_ctrl_update_stage()
1089 LOG_DBG("s-in->[status]"); in udc_ctrl_update_stage()
1092 LOG_DBG("s-in->(status)"); in udc_ctrl_update_stage()
1095 } else if (data->stage == CTRL_PIPE_STAGE_NO_DATA) { in udc_ctrl_update_stage()
1097 * End of a sequence (setup->in) in udc_ctrl_update_stage()
1101 LOG_DBG("s-status"); in udc_ctrl_update_stage()
1110 if (next_stage == data->stage) { in udc_ctrl_update_stage()
1114 data->stage = next_stage; in udc_ctrl_update_stage()