/*
 * Copyright (c) 2022 Nordic Semiconductor ASA
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <errno.h>
#include <zephyr/kernel.h>
#include <zephyr/usb/usbd.h>
#include <zephyr/drivers/usb/udc.h>
#include <zephyr/sys/byteorder.h>
#include <zephyr/sys/slist.h>

#include "usbd_device.h"
#include "usbd_desc.h"
#include "usbd_ch9.h"
#include "usbd_config.h"
#include "usbd_class.h"
#include "usbd_class_api.h"
#include "usbd_interface.h"

#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(usbd_ch9, CONFIG_USBD_LOG_LEVEL);

#define CTRL_AWAIT_SETUP_DATA		0
#define CTRL_AWAIT_STATUS_STAGE		1

static bool reqtype_is_to_host(const struct usb_setup_packet *const setup)
{
	return setup->wLength && USB_REQTYPE_GET_DIR(setup->bmRequestType);
}

static bool reqtype_is_to_device(const struct usb_setup_packet *const setup)
{
	return !reqtype_is_to_host(setup);
}

static void ch9_set_ctrl_type(struct usbd_contex *const uds_ctx,
				   const int type)
{
	uds_ctx->ch9_data.ctrl_type = type;
}

static int ch9_get_ctrl_type(struct usbd_contex *const uds_ctx)
{
	return uds_ctx->ch9_data.ctrl_type;
}

static int set_address_after_status_stage(struct usbd_contex *const uds_ctx)
{
	struct usb_setup_packet *setup = usbd_get_setup_pkt(uds_ctx);
	int ret;

	ret = udc_set_address(uds_ctx->dev, setup->wValue);
	if (ret) {
		LOG_ERR("Failed to set device address 0x%x", setup->wValue);
		return ret;
	}

	uds_ctx->ch9_data.new_address = false;

	return ret;
}

static int sreq_set_address(struct usbd_contex *const uds_ctx)
{
	struct usb_setup_packet *setup = usbd_get_setup_pkt(uds_ctx);

	/* Not specified if wLength is non-zero, treat as error */
	if (setup->wValue > 127 || setup->wLength) {
		errno = -ENOTSUP;
		return 0;
	}

	if (setup->RequestType.recipient != USB_REQTYPE_RECIPIENT_DEVICE) {
		errno = -ENOTSUP;
		return 0;
	}

	if (usbd_state_is_configured(uds_ctx)) {
		errno = -EPERM;
		return 0;
	}

	uds_ctx->ch9_data.new_address = true;
	if (usbd_state_is_address(uds_ctx) && setup->wValue == 0) {
		uds_ctx->ch9_data.state = USBD_STATE_DEFAULT;
	} else {
		uds_ctx->ch9_data.state = USBD_STATE_ADDRESS;
	}


	return 0;
}

static int sreq_set_configuration(struct usbd_contex *const uds_ctx)
{
	struct usb_setup_packet *setup = usbd_get_setup_pkt(uds_ctx);
	int ret;

	LOG_INF("Set Configuration Request value %u", setup->wValue);

	/* Not specified if wLength is non-zero, treat as error */
	if (setup->wValue > UINT8_MAX || setup->wLength) {
		errno = -ENOTSUP;
		return 0;
	}

	if (setup->RequestType.recipient != USB_REQTYPE_RECIPIENT_DEVICE) {
		errno = -ENOTSUP;
		return 0;
	}

	if (usbd_state_is_default(uds_ctx)) {
		errno = -EPERM;
		return 0;
	}

	if (setup->wValue && !usbd_config_exist(uds_ctx, setup->wValue)) {
		errno = -EPERM;
		return 0;
	}

	if (setup->wValue == usbd_get_config_value(uds_ctx)) {
		LOG_DBG("Already in the configuration %u", setup->wValue);
		return 0;
	}

	ret = usbd_config_set(uds_ctx, setup->wValue);
	if (ret) {
		LOG_ERR("Failed to set configuration %u, %d",
			setup->wValue, ret);
		return ret;
	}

	if (setup->wValue == 0) {
		/* Enter address state */
		uds_ctx->ch9_data.state = USBD_STATE_ADDRESS;
	} else {
		uds_ctx->ch9_data.state = USBD_STATE_CONFIGURED;
	}

	return ret;
}

static int sreq_set_interface(struct usbd_contex *const uds_ctx)
{
	struct usb_setup_packet *setup = usbd_get_setup_pkt(uds_ctx);
	uint8_t cur_alt;
	int ret;

	if (setup->RequestType.recipient != USB_REQTYPE_RECIPIENT_INTERFACE) {
		errno = -ENOTSUP;
		return 0;
	}

	/* Not specified if wLength is non-zero, treat as error */
	if (setup->wLength) {
		errno = -ENOTSUP;
		return 0;
	}

	if (setup->wValue > UINT8_MAX || setup->wIndex > UINT8_MAX) {
		errno = -ENOTSUP;
		return 0;
	}

	if (!usbd_state_is_configured(uds_ctx)) {
		errno = -EPERM;
		return 0;
	}

	if (usbd_get_alt_value(uds_ctx, setup->wIndex, &cur_alt)) {
		errno = -ENOTSUP;
		return 0;
	}

	LOG_INF("Set Interfaces %u, alternate %u -> %u",
		setup->wIndex, cur_alt, setup->wValue);

	if (setup->wValue == cur_alt) {
		return 0;
	}

	ret = usbd_interface_set(uds_ctx, setup->wIndex, setup->wValue);
	if (ret == -ENOENT) {
		LOG_INF("Interface alternate does not exist");
		errno = ret;
		ret = 0;
	}

	return ret;
}

static int sreq_clear_feature(struct usbd_contex *const uds_ctx)
{
	struct usb_setup_packet *setup = usbd_get_setup_pkt(uds_ctx);
	uint8_t ep = setup->wIndex;
	int ret = 0;

	/* Not specified if wLength is non-zero, treat as error */
	if (setup->wLength) {
		errno = -ENOTSUP;
		return 0;
	}

	/* Not specified in default state, treat as error */
	if (usbd_state_is_default(uds_ctx)) {
		errno = -EPERM;
		return 0;
	}

	if (usbd_state_is_address(uds_ctx) && setup->wIndex) {
		errno = -EPERM;
		return 0;
	}

	switch (setup->RequestType.recipient) {
	case USB_REQTYPE_RECIPIENT_DEVICE:
		if (setup->wIndex != 0) {
			errno = -EPERM;
			return 0;
		}

		if (setup->wValue == USB_SFS_REMOTE_WAKEUP) {
			LOG_DBG("Clear feature remote wakeup");
			uds_ctx->status.rwup = false;
		}
		break;
	case USB_REQTYPE_RECIPIENT_ENDPOINT:
		if (setup->wValue == USB_SFS_ENDPOINT_HALT) {
			/* UDC checks if endpoint is enabled */
			errno = usbd_ep_clear_halt(uds_ctx, ep);
			ret = (errno == -EPERM) ? errno : 0;
			/* TODO: notify class instance */
			break;
		}
		break;
	case USB_REQTYPE_RECIPIENT_INTERFACE:
	default:
		break;
	}

	return ret;
}

static int sreq_set_feature(struct usbd_contex *const uds_ctx)
{
	struct usb_setup_packet *setup = usbd_get_setup_pkt(uds_ctx);
	uint8_t ep = setup->wIndex;
	int ret = 0;

	/* Not specified if wLength is non-zero, treat as error */
	if (setup->wLength) {
		errno = -ENOTSUP;
		return 0;
	}

	/*
	 * TEST_MODE is not supported yet, other are not specified
	 * in default state, treat as error.
	 */
	if (usbd_state_is_default(uds_ctx)) {
		errno = -EPERM;
		return 0;
	}

	if (usbd_state_is_address(uds_ctx) && setup->wIndex) {
		errno = -EPERM;
		return 0;
	}

	switch (setup->RequestType.recipient) {
	case USB_REQTYPE_RECIPIENT_DEVICE:
		if (setup->wIndex != 0) {
			errno = -EPERM;
			return 0;
		}

		if (setup->wValue == USB_SFS_REMOTE_WAKEUP) {
			LOG_DBG("Set feature remote wakeup");
			uds_ctx->status.rwup = true;
		}
		break;
	case USB_REQTYPE_RECIPIENT_ENDPOINT:
		if (setup->wValue == USB_SFS_ENDPOINT_HALT) {
			/* UDC checks if endpoint is enabled */
			errno = usbd_ep_set_halt(uds_ctx, ep);
			ret = (errno == -EPERM) ? errno : 0;
			/* TODO: notify class instance */
			break;
		}
		break;
	case USB_REQTYPE_RECIPIENT_INTERFACE:
	default:
		break;
	}

	return ret;
}

static int std_request_to_device(struct usbd_contex *const uds_ctx,
				 struct net_buf *const buf)
{
	struct usb_setup_packet *setup = usbd_get_setup_pkt(uds_ctx);
	int ret;

	switch (setup->bRequest) {
	case USB_SREQ_SET_ADDRESS:
		ret = sreq_set_address(uds_ctx);
		break;
	case USB_SREQ_SET_CONFIGURATION:
		ret = sreq_set_configuration(uds_ctx);
		break;
	case USB_SREQ_SET_INTERFACE:
		ret = sreq_set_interface(uds_ctx);
		break;
	case USB_SREQ_CLEAR_FEATURE:
		ret = sreq_clear_feature(uds_ctx);
		break;
	case USB_SREQ_SET_FEATURE:
		ret = sreq_set_feature(uds_ctx);
		break;
	default:
		errno = -ENOTSUP;
		ret = 0;
		break;
	}

	return ret;
}

static int sreq_get_status(struct usbd_contex *const uds_ctx,
			   struct net_buf *const buf)
{
	struct usb_setup_packet *setup = usbd_get_setup_pkt(uds_ctx);
	uint8_t ep = setup->wIndex;
	uint16_t response = 0;

	if (setup->wLength != sizeof(response)) {
		errno = -ENOTSUP;
		return 0;
	}

	/* Not specified in default state, treat as error */
	if (usbd_state_is_default(uds_ctx)) {
		errno = -EPERM;
		return 0;
	}

	if (usbd_state_is_address(uds_ctx) && setup->wIndex) {
		errno = -EPERM;
		return 0;
	}

	switch (setup->RequestType.recipient) {
	case USB_REQTYPE_RECIPIENT_DEVICE:
		if (setup->wIndex != 0) {
			errno = -EPERM;
			return 0;
		}

		response = uds_ctx->status.rwup ?
			   USB_GET_STATUS_REMOTE_WAKEUP : 0;
		break;
	case USB_REQTYPE_RECIPIENT_ENDPOINT:
		response = usbd_ep_is_halted(uds_ctx, ep) ? BIT(0) : 0;
		break;
	case USB_REQTYPE_RECIPIENT_INTERFACE:
		/* Response is always reset to zero.
		 * TODO: add check if interface exist?
		 */
		break;
	default:
		break;
	}

	if (net_buf_tailroom(buf) < setup->wLength) {
		errno = -ENOMEM;
		return 0;
	}

	LOG_DBG("Get Status response 0x%04x", response);
	net_buf_add_le16(buf, response);

	return 0;
}

static int sreq_get_desc_cfg(struct usbd_contex *const uds_ctx,
			     struct net_buf *const buf,
			     const uint8_t idx)
{
	struct usb_setup_packet *setup = usbd_get_setup_pkt(uds_ctx);
	struct usb_cfg_descriptor *cfg_desc;
	struct usbd_config_node *cfg_nd;
	struct usbd_class_node *c_nd;
	uint16_t len;

	cfg_nd = usbd_config_get(uds_ctx, idx + 1);
	if (cfg_nd == NULL) {
		LOG_ERR("Configuration descriptor %u not found", idx + 1);
		errno = -ENOTSUP;
		return 0;
	}

	cfg_desc = cfg_nd->desc;
	len = MIN(setup->wLength, net_buf_tailroom(buf));
	net_buf_add_mem(buf, cfg_desc, MIN(len, cfg_desc->bLength));

	SYS_SLIST_FOR_EACH_CONTAINER(&cfg_nd->class_list, c_nd, node) {
		struct usb_desc_header *head = c_nd->data->desc;
		size_t desc_len = usbd_class_desc_len(c_nd);

		len = MIN(setup->wLength, net_buf_tailroom(buf));
		net_buf_add_mem(buf, head, MIN(len, desc_len));
	}

	LOG_DBG("Get Configuration descriptor %u, len %u", idx, buf->len);

	return 0;
}

static int sreq_get_desc(struct usbd_contex *const uds_ctx,
			 struct net_buf *const buf,
			 const uint8_t type, const uint8_t idx)
{
	struct usb_setup_packet *setup = usbd_get_setup_pkt(uds_ctx);
	struct usb_desc_header *head;
	size_t len;

	if (type == USB_DESC_DEVICE) {
		head = uds_ctx->desc;
	} else {
		head = usbd_get_descriptor(uds_ctx, type, idx);
	}

	if (head == NULL) {
		errno = -ENOTSUP;
		return 0;
	}

	len = MIN(setup->wLength, net_buf_tailroom(buf));
	net_buf_add_mem(buf, head, MIN(len, head->bLength));

	return 0;
}

static int sreq_get_descriptor(struct usbd_contex *const uds_ctx,
			       struct net_buf *const buf)
{
	struct usb_setup_packet *setup = usbd_get_setup_pkt(uds_ctx);
	uint8_t desc_type = USB_GET_DESCRIPTOR_TYPE(setup->wValue);
	uint8_t desc_idx = USB_GET_DESCRIPTOR_INDEX(setup->wValue);

	LOG_DBG("Get Descriptor request type %u index %u",
		desc_type, desc_idx);

	switch (desc_type) {
	case USB_DESC_DEVICE:
		return sreq_get_desc(uds_ctx, buf, USB_DESC_DEVICE, 0);
	case USB_DESC_CONFIGURATION:
		return sreq_get_desc_cfg(uds_ctx, buf, desc_idx);
	case USB_DESC_STRING:
		return sreq_get_desc(uds_ctx, buf, USB_DESC_STRING, desc_idx);
	case USB_DESC_INTERFACE:
	case USB_DESC_ENDPOINT:
	case USB_DESC_OTHER_SPEED:
	default:
		break;
	}

	errno = -ENOTSUP;
	return 0;
}

static int sreq_get_configuration(struct usbd_contex *const uds_ctx,
				  struct net_buf *const buf)

{
	struct usb_setup_packet *setup = usbd_get_setup_pkt(uds_ctx);
	uint8_t cfg = usbd_get_config_value(uds_ctx);

	/* Not specified in default state, treat as error */
	if (usbd_state_is_default(uds_ctx)) {
		errno = -EPERM;
		return 0;
	}

	if (setup->wLength != sizeof(cfg)) {
		errno = -ENOTSUP;
		return 0;
	}

	if (net_buf_tailroom(buf) < setup->wLength) {
		errno = -ENOMEM;
		return 0;
	}

	net_buf_add_u8(buf, cfg);

	return 0;
}

static int sreq_get_interface(struct usbd_contex *const uds_ctx,
			      struct net_buf *const buf)
{
	struct usb_setup_packet *setup = usbd_get_setup_pkt(uds_ctx);
	struct usb_cfg_descriptor *cfg_desc;
	struct usbd_config_node *cfg_nd;
	uint8_t cur_alt;

	if (setup->RequestType.recipient != USB_REQTYPE_RECIPIENT_INTERFACE) {
		errno = -EPERM;
		return 0;
	}

	cfg_nd = usbd_config_get_current(uds_ctx);
	cfg_desc = cfg_nd->desc;

	if (setup->wIndex > UINT8_MAX ||
	    setup->wIndex > cfg_desc->bNumInterfaces) {
		errno = -ENOTSUP;
		return 0;
	}

	if (usbd_get_alt_value(uds_ctx, setup->wIndex, &cur_alt)) {
		errno = -ENOTSUP;
		return 0;
	}

	LOG_DBG("Get Interfaces %u, alternate %u",
		setup->wIndex, cur_alt);

	if (setup->wLength != sizeof(cur_alt)) {
		errno = -ENOTSUP;
		return 0;
	}

	if (net_buf_tailroom(buf) < setup->wLength) {
		errno = -ENOMEM;
		return 0;
	}

	net_buf_add_u8(buf, cur_alt);

	return 0;
}

static int std_request_to_host(struct usbd_contex *const uds_ctx,
			       struct net_buf *const buf)
{
	struct usb_setup_packet *setup = usbd_get_setup_pkt(uds_ctx);
	int ret;

	switch (setup->bRequest) {
	case USB_SREQ_GET_STATUS:
		ret = sreq_get_status(uds_ctx, buf);
		break;
	case USB_SREQ_GET_DESCRIPTOR:
		ret = sreq_get_descriptor(uds_ctx, buf);
		break;
	case USB_SREQ_GET_CONFIGURATION:
		ret = sreq_get_configuration(uds_ctx, buf);
		break;
	case USB_SREQ_GET_INTERFACE:
		ret = sreq_get_interface(uds_ctx, buf);
		break;
	default:
		errno = -ENOTSUP;
		ret = 0;
		break;
	}

	return ret;
}

static int nonstd_request(struct usbd_contex *const uds_ctx,
			  struct net_buf *const dbuf)
{
	struct usb_setup_packet *setup = usbd_get_setup_pkt(uds_ctx);
	struct usbd_class_node *c_nd = NULL;
	int ret = 0;

	switch (setup->RequestType.recipient) {
	case USB_REQTYPE_RECIPIENT_ENDPOINT:
		c_nd = usbd_class_get_by_ep(uds_ctx, setup->wIndex);
		break;
	case USB_REQTYPE_RECIPIENT_INTERFACE:
		c_nd = usbd_class_get_by_iface(uds_ctx, setup->wIndex);
		break;
	case USB_REQTYPE_RECIPIENT_DEVICE:
		c_nd = usbd_class_get_by_req(uds_ctx, setup->bRequest);
		break;
	default:
		break;
	}

	if (c_nd != NULL) {
		if (reqtype_is_to_device(setup)) {
			ret = usbd_class_control_to_dev(c_nd, setup, dbuf);
		} else {
			ret = usbd_class_control_to_host(c_nd, setup, dbuf);
		}
	} else {
		errno = -ENOTSUP;
	}

	return ret;
}

static int handle_setup_request(struct usbd_contex *const uds_ctx,
				struct net_buf *const buf)
{
	struct usb_setup_packet *setup = usbd_get_setup_pkt(uds_ctx);
	int ret;

	errno = 0;

	switch (setup->RequestType.type) {
	case USB_REQTYPE_TYPE_STANDARD:
		if (reqtype_is_to_device(setup)) {
			ret = std_request_to_device(uds_ctx, buf);
		} else {
			ret = std_request_to_host(uds_ctx, buf);
		}
		break;
	case USB_REQTYPE_TYPE_CLASS:
	case USB_REQTYPE_TYPE_VENDOR:
		ret = nonstd_request(uds_ctx, buf);
		break;
	default:
		errno = -ENOTSUP;
		ret = 0;
	}

	if (errno) {
		LOG_INF("protocol error:");
		LOG_HEXDUMP_INF(setup, sizeof(*setup), "setup:");
		if (errno == -ENOTSUP) {
			LOG_INF("not supported");
		}
		if (errno == -EPERM) {
			LOG_INF("not permitted in device state %u",
				uds_ctx->ch9_data.state);
		}
	}

	return ret;
}

static int ctrl_xfer_get_setup(struct usbd_contex *const uds_ctx,
			       struct net_buf *const buf)
{
	struct usb_setup_packet *setup = usbd_get_setup_pkt(uds_ctx);
	struct net_buf *buf_b;
	struct udc_buf_info *bi, *bi_b;

	if (buf->len < sizeof(struct usb_setup_packet)) {
		return -EINVAL;
	}

	memcpy(setup, buf->data, sizeof(struct usb_setup_packet));

	setup->wValue = sys_le16_to_cpu(setup->wValue);
	setup->wIndex = sys_le16_to_cpu(setup->wIndex);
	setup->wLength = sys_le16_to_cpu(setup->wLength);

	bi = udc_get_buf_info(buf);

	buf_b = buf->frags;
	if (buf_b == NULL) {
		LOG_ERR("Buffer for data|status is missing");
		return -ENODATA;
	}

	bi_b = udc_get_buf_info(buf_b);

	if (reqtype_is_to_device(setup)) {
		if (setup->wLength) {
			if (!bi_b->data) {
				LOG_ERR("%p is not data", buf_b);
				return -EINVAL;
			}
		} else {
			if (!bi_b->status) {
				LOG_ERR("%p is not status", buf_b);
				return -EINVAL;
			}
		}
	} else {
		if (!setup->wLength) {
			LOG_ERR("device-to-host with wLength zero");
			return -ENOTSUP;
		}

		if (!bi_b->data) {
			LOG_ERR("%p is not data", buf_b);
			return -EINVAL;
		}

	}

	return 0;
}

static struct net_buf *spool_data_out(struct net_buf *const buf)
{
	struct net_buf *next_buf = buf;
	struct udc_buf_info *bi;

	while (next_buf) {
		LOG_INF("spool %p", next_buf);
		next_buf = net_buf_frag_del(NULL, next_buf);
		if (next_buf) {
			bi = udc_get_buf_info(next_buf);
			if (bi->status) {
				return next_buf;
			}
		}
	}

	return NULL;
}

int usbd_handle_ctrl_xfer(struct usbd_contex *const uds_ctx,
			  struct net_buf *const buf, const int err)
{
	struct usb_setup_packet *setup = usbd_get_setup_pkt(uds_ctx);
	struct udc_buf_info *bi;
	int ret = 0;

	bi = udc_get_buf_info(buf);
	if (USB_EP_GET_IDX(bi->ep)) {
		LOG_ERR("Can only handle control requests");
		return -EIO;
	}

	if (err && err != -ENOMEM && !bi->setup) {
		LOG_ERR("Control transfer for 0x%02x has error %d, halt",
			bi->ep, err);
		net_buf_unref(buf);
		return err;
	}

	LOG_INF("Handle control %p ep 0x%02x, len %u, s:%u d:%u s:%u",
		buf, bi->ep, buf->len, bi->setup, bi->data, bi->status);

	if (bi->setup && bi->ep == USB_CONTROL_EP_OUT) {
		struct net_buf *next_buf;

		if (ctrl_xfer_get_setup(uds_ctx, buf)) {
			LOG_ERR("Malformed setup packet");
			net_buf_unref(buf);
			goto ctrl_xfer_stall;
		}

		/* Remove setup packet buffer from the chain */
		next_buf = net_buf_frag_del(NULL, buf);
		if (next_buf == NULL) {
			LOG_ERR("Buffer for data|status is missing");
			goto ctrl_xfer_stall;
		}

		/*
		 * Handle request and data stage, next_buf is either
		 * data+status or status buffers.
		 */
		ret = handle_setup_request(uds_ctx, next_buf);
		if (ret) {
			net_buf_unref(next_buf);
			return ret;
		}

		if (errno) {
			/*
			 * Halt, only protocol errors are recoverable.
			 * Free data stage and linked status stage buffer.
			 */
			net_buf_unref(next_buf);
			goto ctrl_xfer_stall;
		}

		ch9_set_ctrl_type(uds_ctx, CTRL_AWAIT_STATUS_STAGE);
		if (reqtype_is_to_device(setup) && setup->wLength) {
			/* Enqueue STATUS (IN) buffer */
			next_buf = spool_data_out(next_buf);
			if (next_buf == NULL) {
				LOG_ERR("Buffer for status is missing");
				goto ctrl_xfer_stall;
			}

			ret = usbd_ep_ctrl_enqueue(uds_ctx, next_buf);
		} else {
			/* Enqueue DATA (IN) or STATUS (OUT) buffer */
			ret = usbd_ep_ctrl_enqueue(uds_ctx, next_buf);
		}

		return ret;
	}

	if (bi->status && bi->ep == USB_CONTROL_EP_OUT) {
		if (ch9_get_ctrl_type(uds_ctx) == CTRL_AWAIT_STATUS_STAGE) {
			LOG_INF("s-in-status finished");
		} else {
			LOG_WRN("Awaited s-in-status not finished");
		}

		net_buf_unref(buf);

		return 0;
	}

	if (bi->status && bi->ep == USB_CONTROL_EP_IN) {
		if (ch9_get_ctrl_type(uds_ctx) == CTRL_AWAIT_STATUS_STAGE) {
			LOG_INF("s-(out)-status finished");
			if (unlikely(uds_ctx->ch9_data.new_address)) {
				return set_address_after_status_stage(uds_ctx);
			}
		} else {
			LOG_WRN("Awaited s-(out)-status not finished");
		}

		net_buf_unref(buf);

		return ret;
	}

ctrl_xfer_stall:
	/*
	 * Halt only the endpoint over which the host expects
	 * data or status stage. This facilitates the work of the drivers.
	 *
	 * In the case there is -ENOMEM for data OUT stage halt
	 * control OUT endpoint.
	 */
	if (reqtype_is_to_host(setup)) {
		ret = udc_ep_set_halt(uds_ctx->dev, USB_CONTROL_EP_IN);
	} else if (setup->wLength) {
		uint8_t ep = (err == -ENOMEM) ? USB_CONTROL_EP_OUT : USB_CONTROL_EP_IN;

		ret = udc_ep_set_halt(uds_ctx->dev, ep);
	} else {
		ret = udc_ep_set_halt(uds_ctx->dev, USB_CONTROL_EP_IN);
	}

	ch9_set_ctrl_type(uds_ctx, CTRL_AWAIT_SETUP_DATA);

	return ret;
}

int usbd_init_control_pipe(struct usbd_contex *const uds_ctx)
{
	uds_ctx->ch9_data.state = USBD_STATE_DEFAULT;
	ch9_set_ctrl_type(uds_ctx, CTRL_AWAIT_SETUP_DATA);

	return 0;
}
