// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright (C) 2015 Karol Kosik <karo9@interia.eu>
 * Copyright (C) 2015-2016 Samsung Electronics
 *               Igor Kotrasinski <i.kotrasinsk@samsung.com>
 *               Krzysztof Opasiak <k.opasiak@samsung.com>
 */

#include <linux/device.h>
#include <linux/list.h>
#include <linux/usb/gadget.h>
#include <linux/usb/ch9.h>
#include <linux/sysfs.h>
#include <linux/kthread.h>
#include <linux/byteorder/generic.h>

#include "usbip_common.h"
#include "vudc.h"

#include <net/sock.h>

/* called with udc->lock held */
int get_gadget_descs(struct vudc *udc)
{
	struct vrequest *usb_req;
	struct vep *ep0 = to_vep(udc->gadget.ep0);
	struct usb_device_descriptor *ddesc = &udc->dev_desc;
	struct usb_ctrlrequest req;
	int ret;

	if (!udc->driver || !udc->pullup)
		return -EINVAL;

	req.bRequestType = USB_DIR_IN | USB_TYPE_STANDARD | USB_RECIP_DEVICE;
	req.bRequest = USB_REQ_GET_DESCRIPTOR;
	req.wValue = cpu_to_le16(USB_DT_DEVICE << 8);
	req.wIndex = cpu_to_le16(0);
	req.wLength = cpu_to_le16(sizeof(*ddesc));

	spin_unlock(&udc->lock);
	ret = udc->driver->setup(&(udc->gadget), &req);
	spin_lock(&udc->lock);
	if (ret < 0)
		goto out;

	/* assuming request queue is empty; request is now on top */
	usb_req = list_last_entry(&ep0->req_queue, struct vrequest, req_entry);
	list_del(&usb_req->req_entry);

	if (usb_req->req.length > sizeof(*ddesc)) {
		ret = -EOVERFLOW;
		goto giveback_req;
	}

	memcpy(ddesc, usb_req->req.buf, sizeof(*ddesc));
	udc->desc_cached = 1;
	ret = 0;
giveback_req:
	usb_req->req.status = 0;
	usb_req->req.actual = usb_req->req.length;
	usb_gadget_giveback_request(&(ep0->ep), &(usb_req->req));
out:
	return ret;
}

/*
 * Exposes device descriptor from the gadget driver.
 */
static ssize_t dev_desc_read(struct file *file, struct kobject *kobj,
			     struct bin_attribute *attr, char *out,
			     loff_t off, size_t count)
{
	struct device *dev = kobj_to_dev(kobj);
	struct vudc *udc = (struct vudc *)dev_get_drvdata(dev);
	char *desc_ptr = (char *) &udc->dev_desc;
	unsigned long flags;
	int ret;

	spin_lock_irqsave(&udc->lock, flags);
	if (!udc->desc_cached) {
		ret = -ENODEV;
		goto unlock;
	}

	memcpy(out, desc_ptr + off, count);
	ret = count;
unlock:
	spin_unlock_irqrestore(&udc->lock, flags);
	return ret;
}
static BIN_ATTR_RO(dev_desc, sizeof(struct usb_device_descriptor));

static ssize_t usbip_sockfd_store(struct device *dev, struct device_attribute *attr,
		     const char *in, size_t count)
{
	struct vudc *udc = (struct vudc *) dev_get_drvdata(dev);
	int rv;
	int sockfd = 0;
	int err;
	struct socket *socket;
	unsigned long flags;
	int ret;

	rv = kstrtoint(in, 0, &sockfd);
	if (rv != 0)
		return -EINVAL;

	if (!udc) {
		dev_err(dev, "no device");
		return -ENODEV;
	}
	spin_lock_irqsave(&udc->lock, flags);
	/* Don't export what we don't have */
	if (!udc->driver || !udc->pullup) {
		dev_err(dev, "gadget not bound");
		ret = -ENODEV;
		goto unlock;
	}

	if (sockfd != -1) {
		if (udc->connected) {
			dev_err(dev, "Device already connected");
			ret = -EBUSY;
			goto unlock;
		}

		spin_lock_irq(&udc->ud.lock);

		if (udc->ud.status != SDEV_ST_AVAILABLE) {
			ret = -EINVAL;
			goto unlock_ud;
		}

		socket = sockfd_lookup(sockfd, &err);
		if (!socket) {
			dev_err(dev, "failed to lookup sock");
			ret = -EINVAL;
			goto unlock_ud;
		}

		udc->ud.tcp_socket = socket;

		spin_unlock_irq(&udc->ud.lock);
		spin_unlock_irqrestore(&udc->lock, flags);

		udc->ud.tcp_rx = kthread_get_run(&v_rx_loop,
						    &udc->ud, "vudc_rx");
		udc->ud.tcp_tx = kthread_get_run(&v_tx_loop,
						    &udc->ud, "vudc_tx");

		spin_lock_irqsave(&udc->lock, flags);
		spin_lock_irq(&udc->ud.lock);
		udc->ud.status = SDEV_ST_USED;
		spin_unlock_irq(&udc->ud.lock);

		ktime_get_ts64(&udc->start_time);
		v_start_timer(udc);
		udc->connected = 1;
	} else {
		if (!udc->connected) {
			dev_err(dev, "Device not connected");
			ret = -EINVAL;
			goto unlock;
		}

		spin_lock_irq(&udc->ud.lock);
		if (udc->ud.status != SDEV_ST_USED) {
			ret = -EINVAL;
			goto unlock_ud;
		}
		spin_unlock_irq(&udc->ud.lock);

		usbip_event_add(&udc->ud, VUDC_EVENT_DOWN);
	}

	spin_unlock_irqrestore(&udc->lock, flags);

	return count;

unlock_ud:
	spin_unlock_irq(&udc->ud.lock);
unlock:
	spin_unlock_irqrestore(&udc->lock, flags);

	return ret;
}
static DEVICE_ATTR_WO(usbip_sockfd);

static ssize_t usbip_status_show(struct device *dev,
			       struct device_attribute *attr, char *out)
{
	struct vudc *udc = (struct vudc *) dev_get_drvdata(dev);
	int status;

	if (!udc) {
		dev_err(dev, "no device");
		return -ENODEV;
	}
	spin_lock_irq(&udc->ud.lock);
	status = udc->ud.status;
	spin_unlock_irq(&udc->ud.lock);

	return snprintf(out, PAGE_SIZE, "%d\n", status);
}
static DEVICE_ATTR_RO(usbip_status);

static struct attribute *dev_attrs[] = {
	&dev_attr_usbip_sockfd.attr,
	&dev_attr_usbip_status.attr,
	NULL,
};

static struct bin_attribute *dev_bin_attrs[] = {
	&bin_attr_dev_desc,
	NULL,
};

static const struct attribute_group vudc_attr_group = {
	.attrs = dev_attrs,
	.bin_attrs = dev_bin_attrs,
};

const struct attribute_group *vudc_groups[] = {
	&vudc_attr_group,
	NULL,
};
