/*
 * Freescale UUT driver
 *
 * Copyright 2008-2016 Freescale Semiconductor, Inc.
 * Copyright 2008-2009 Embedded Alley Solutions, Inc All Rights Reserved.
 * Copyright 2017 NXP
 */

/*
 * The code contained herein is licensed under the GNU General Public
 * License. You may obtain a copy of the GNU General Public License
 * Version 2 or later at the following locations:
 *
 * http://www.opensource.org/licenses/gpl-license.html
 * http://www.gnu.org/copyleft/gpl.html
 */

static bool is_utp_device(struct fsg_dev *fsg)
{
	struct usb_device_descriptor *pdesc;

	if (!fsg || !fsg->common || !fsg->common->cdev)
		return false;

	pdesc = &fsg->common->cdev->desc;
	if (pdesc->idVendor == UTP_IDVENDOR &&
		pdesc->idProduct == UTP_IDPRODUCT)
		return true;

	return false;
}

static u64 get_be64(u8 *buf)
{
	return ((u64)get_unaligned_be32(buf) << 32) |
		get_unaligned_be32(buf + 4);
}

static int utp_init(struct fsg_dev *fsg)
{
	init_waitqueue_head(&utp_context.wq);
	init_waitqueue_head(&utp_context.list_full_wq);

	INIT_LIST_HEAD(&utp_context.read);
	INIT_LIST_HEAD(&utp_context.write);
	mutex_init(&utp_context.lock);

	/* the max message is 64KB */
	utp_context.buffer = vmalloc(0x10000);
	if (!utp_context.buffer)
		return -EIO;
	utp_context.utp_version = 0x1ull;
	fsg->utp = &utp_context;
	return misc_register(&utp_dev);
}

static void utp_exit(struct fsg_dev *fsg)
{
	vfree(utp_context.buffer);
	misc_deregister(&utp_dev);
}

static struct utp_user_data *utp_user_data_alloc(size_t size)
{
	struct utp_user_data *uud;

	uud = vmalloc(size + sizeof(*uud));
	if (!uud)
		return uud;
	memset(uud, 0, size + sizeof(*uud));
	uud->data.size = size + sizeof(uud->data);
	INIT_LIST_HEAD(&uud->link);
	return uud;
}

static void utp_user_data_free(struct utp_user_data *uud)
{
	mutex_lock(&utp_context.lock);
	list_del(&uud->link);
	mutex_unlock(&utp_context.lock);
	vfree(uud);
}

/* Get the number of element for list */
static u32 count_list(struct list_head *l)
{
	u32 count = 0;
	struct list_head *tmp;

	mutex_lock(&utp_context.lock);
	list_for_each(tmp, l) {
		count++;
	}
	mutex_unlock(&utp_context.lock);

	return count;
}
/* The routine will not go on if utp_context.queue is empty */
#define WAIT_ACTIVITY(queue) \
 wait_event_interruptible(utp_context.wq, !list_empty(&utp_context.queue))

/* Called by userspace program (uuc) */
static ssize_t utp_file_read(struct file *file,
			     char __user *buf,
			     size_t size,
			     loff_t *off)
{
	struct utp_user_data *uud;
	size_t size_to_put;
	int free = 0;

	WAIT_ACTIVITY(read);

	mutex_lock(&utp_context.lock);
	uud = list_first_entry(&utp_context.read, struct utp_user_data, link);
	mutex_unlock(&utp_context.lock);
	size_to_put = uud->data.size;

	if (size >= size_to_put)
		free = !0;
	if (copy_to_user(buf, &uud->data, size_to_put)) {
		printk(KERN_INFO "[ %s ] copy error\n", __func__);
		return -EACCES;
	}
	if (free)
		utp_user_data_free(uud);
	else {
		pr_info("sizeof = %zd, size = %zd\n",
			sizeof(uud->data),
			uud->data.size);

		pr_err("Will not free utp_user_data, because buffer size = %zd need to put %zd\n",
					size, size_to_put);
	}

	/*
	 * The user program has already finished data process,
	 * go on getting data from the host
	 */
	wake_up(&utp_context.list_full_wq);

	return size_to_put;
}

static ssize_t utp_file_write(struct file *file, const char __user *buf,
				size_t size, loff_t *off)
{
	struct utp_user_data *uud;

	if (size < sizeof(uud->data))
		return -EINVAL;
	uud = utp_user_data_alloc(size);
	if (uud == NULL)
		return -ENOMEM;
	if (copy_from_user(&uud->data, buf, size)) {
		printk(KERN_INFO "[ %s ] copy error!\n", __func__);
		vfree(uud);
		return -EACCES;
	}
	mutex_lock(&utp_context.lock);
	list_add_tail(&uud->link, &utp_context.write);
	/* Go on EXEC routine process */
	wake_up(&utp_context.wq);
	mutex_unlock(&utp_context.lock);
	return size;
}

/*
 * uuc should change to use soc bus infrastructure to soc information
 * /sys/devices/soc0/soc_id
 * this function can be removed.
 */
static long
utp_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
	int cpu_id = 0;

	switch (cmd) {
	case UTP_GET_CPU_ID:
		return put_user(cpu_id, (int __user *)arg);
	default:
		return -ENOIOCTLCMD;
	}
}

/* Will be called when the host wants to get the sense data */
static int utp_get_sense(struct fsg_dev *fsg)
{
	if (UTP_CTX(fsg)->processed == 0)
		return -1;

	UTP_CTX(fsg)->processed = 0;
	return 0;
}

static int utp_do_read(struct fsg_dev *fsg, void *data, size_t size)
{
	struct fsg_buffhd	*bh;
	int			rc;
	u32			amount_left;
	unsigned int		amount;

	/* Get the starting Logical Block Address and check that it's
	 * not too big */

	amount_left = size;
	if (unlikely(amount_left == 0))
		return -EIO;		/* No default reply*/

	pr_debug("%s: sending %zd\n", __func__, size);
	for (;;) {
		/* Figure out how much we need to read:
		 * Try to read the remaining amount.
		 * But don't read more than the buffer size.
		 * And don't try to read past the end of the file.
		 * Finally, if we're not at a page boundary, don't read past
		 *	the next page.
		 * If this means reading 0 then we were asked to read past
		 *	the end of file. */
		amount = min((unsigned int) amount_left, FSG_BUFLEN);

		/* Wait for the next buffer to become available */
		bh = fsg->common->next_buffhd_to_fill;
		while (bh->state != BUF_STATE_EMPTY) {
			rc = sleep_thread(fsg->common, true);
			if (rc)
				return rc;
		}

		/* If we were asked to read past the end of file,
		 * end with an empty buffer. */
		if (amount == 0) {
			bh->inreq->length = 0;
			bh->state = BUF_STATE_FULL;
			break;
		}

		/* Perform the read */
		pr_info("Copied to %p, %d bytes started from %zd\n",
				bh->buf, amount, size - amount_left);
		/* from upt buffer to file_storeage buffer */
		memcpy(bh->buf, data + size - amount_left, amount);
		amount_left  -= amount;
		fsg->common->residue -= amount;

		bh->inreq->length = amount;
		bh->state = BUF_STATE_FULL;

		/* Send this buffer and go read some more */
		bh->inreq->zero = 0;

		/* USB Physical transfer: Data from device to host */
		start_transfer(fsg, fsg->bulk_in, bh->inreq,
				&bh->inreq_busy, &bh->state);

		fsg->common->next_buffhd_to_fill = bh->next;

		if (amount_left <= 0)
			break;
	}

	return size - amount_left;
}

static int utp_do_write(struct fsg_dev *fsg, void *data, size_t size)
{
	struct fsg_buffhd	*bh;
	int			get_some_more;
	u32			amount_left_to_req, amount_left_to_write;
	unsigned int		amount;
	int			rc;
	loff_t			offset;

	/* Carry out the file writes */
	get_some_more = 1;
	amount_left_to_req = amount_left_to_write = size;

	if (unlikely(amount_left_to_write == 0))
		return -EIO;

	offset = 0;
	while (amount_left_to_write > 0) {

		/* Queue a request for more data from the host */
		bh = fsg->common->next_buffhd_to_fill;
		if (bh->state == BUF_STATE_EMPTY && get_some_more) {

			/* Figure out how much we want to get:
			 * Try to get the remaining amount.
			 * But don't get more than the buffer size.
			 * And don't try to go past the end of the file.
			 * If we're not at a page boundary,
			 *	don't go past the next page.
			 * If this means getting 0, then we were asked
			 *	to write past the end of file.
			 * Finally, round down to a block boundary. */
			amount = min(amount_left_to_req, FSG_BUFLEN);

			if (amount == 0) {
				get_some_more = 0;
				/* cry now */
				continue;
			}

			/* Get the next buffer */
			amount_left_to_req -= amount;
			if (amount_left_to_req == 0)
				get_some_more = 0;

			/* amount is always divisible by 512, hence by
			 * the bulk-out maxpacket size */
			set_bulk_out_req_length(fsg->common, bh, amount);
			bh->outreq->short_not_ok = 1;
			start_transfer(fsg, fsg->bulk_out, bh->outreq,
					&bh->outreq_busy, &bh->state);
			fsg->common->next_buffhd_to_fill = bh->next;
			continue;
		}

		/* Write the received data to the backing file */
		bh = fsg->common->next_buffhd_to_drain;
		if (bh->state == BUF_STATE_EMPTY && !get_some_more)
			break;			/* We stopped early */
		if (bh->state == BUF_STATE_FULL) {
			smp_rmb();
			fsg->common->next_buffhd_to_drain = bh->next;
			bh->state = BUF_STATE_EMPTY;

			/* Did something go wrong with the transfer? */
			if (bh->outreq->status != 0)
				/* cry again, COMMUNICATION_FAILURE */
				break;

			amount = bh->outreq->actual;

			/* Perform the write */
			memcpy(data + offset, bh->buf, amount);

			offset += amount;
			if (signal_pending(current))
				return -EINTR;		/* Interrupted!*/
			amount_left_to_write -= amount;
			fsg->common->residue -= amount;

			/* Did the host decide to stop early? */
			if (bh->outreq->actual != bh->outreq->length) {
				fsg->common->short_packet_received = 1;
				break;
			}
			continue;
		}

		/* Wait for something to happen */
		rc = sleep_thread(fsg->common, true);
		if (rc)
			return rc;
	}

	return -EIO;
}

static inline void utp_set_sense(struct fsg_dev *fsg, u16 code, u64 reply)
{
	UTP_CTX(fsg)->processed = true;
	UTP_CTX(fsg)->sdinfo = reply & 0xFFFFFFFF;
	UTP_CTX(fsg)->sdinfo_h = (reply >> 32) & 0xFFFFFFFF;
	UTP_CTX(fsg)->sd = (UTP_SENSE_KEY << 16) | code;
}

static void utp_poll(struct fsg_dev *fsg)
{
	struct utp_context *ctx = UTP_CTX(fsg);
	struct utp_user_data *uud = NULL;

	mutex_lock(&ctx->lock);
	if (!list_empty(&ctx->write))
		uud = list_first_entry(&ctx->write, struct utp_user_data, link);
	mutex_unlock(&ctx->lock);

	if (uud) {
		if (uud->data.flags & UTP_FLAG_STATUS) {
			printk(KERN_WARNING "%s: exit with status %d\n",
					__func__, uud->data.status);
			UTP_SS_EXIT(fsg, uud->data.status);
		} else if (uud->data.flags & UTP_FLAG_REPORT_BUSY) {
			UTP_SS_BUSY(fsg, --ctx->counter);
		} else {
			printk("%s: pass returned.\n", __func__);
			UTP_SS_PASS(fsg);
		}
		utp_user_data_free(uud);
	} else {
		if (utp_context.cur_state & UTP_FLAG_DATA) {
			if (count_list(&ctx->read) < 7) {
				pr_debug("%s: pass returned in POLL stage. \n", __func__);
				UTP_SS_PASS(fsg);
				utp_context.cur_state = 0;
				return;
			}
		}
		UTP_SS_BUSY(fsg, --ctx->counter);
	}
}

static int utp_exec(struct fsg_dev *fsg,
		    char *command,
		    int cmdsize,
		    unsigned long long payload)
{
	struct utp_user_data *uud = NULL, *uud2r;
	struct utp_context *ctx = UTP_CTX(fsg);

	ctx->counter = 0xFFFF;
	uud2r = utp_user_data_alloc(cmdsize + 1);
	if (!uud2r)
		return -ENOMEM;
	uud2r->data.flags = UTP_FLAG_COMMAND;
	uud2r->data.payload = payload;
	strncpy(uud2r->data.command, command, cmdsize);

	mutex_lock(&ctx->lock);
	list_add_tail(&uud2r->link, &ctx->read);
	mutex_unlock(&ctx->lock);
	/* wake up the read routine */
	wake_up(&ctx->wq);

	if (command[0] == '!')	/* there will be no response */
		return 0;

	/*
	 * the user program (uuc) will return utp_message
	 * and add list to write list
	 */
	WAIT_ACTIVITY(write);

	mutex_lock(&ctx->lock);
	if (!list_empty(&ctx->write)) {
		uud = list_first_entry(&ctx->write, struct utp_user_data, link);
#ifdef DEBUG
		pr_info("UUD:\n\tFlags = %02X\n", uud->data.flags);
		if (uud->data.flags & UTP_FLAG_DATA) {
			pr_info("\tbufsize = %d\n", uud->data.bufsize);
			print_hex_dump(KERN_DEBUG, "\t", DUMP_PREFIX_NONE,
				16, 2, uud->data.data, uud->data.bufsize, true);
		}
		if (uud->data.flags & UTP_FLAG_REPORT_BUSY)
			pr_info("\tBUSY\n");
#endif
	} else {
		pr_err("UTP write list is empty.\n");
		mutex_unlock(&ctx->lock);
		return 0;
	}
	mutex_unlock(&ctx->lock);

	if (uud->data.flags & UTP_FLAG_DATA) {
		memcpy(ctx->buffer, uud->data.data, uud->data.bufsize);
		UTP_SS_SIZE(fsg, uud->data.bufsize);
	} else if (uud->data.flags & UTP_FLAG_REPORT_BUSY) {
		UTP_SS_BUSY(fsg, ctx->counter);
	} else if (uud->data.flags & UTP_FLAG_STATUS) {
		printk(KERN_WARNING "%s: exit with status %d\n", __func__,
				uud->data.status);
		UTP_SS_EXIT(fsg, uud->data.status);
	} else {
		pr_debug("%s: pass returned in EXEC stage. \n", __func__);
		UTP_SS_PASS(fsg);
	}
	utp_user_data_free(uud);
	return 0;
}

static int utp_send_status(struct fsg_dev *fsg)
{
	struct fsg_buffhd	*bh;
	u8			status = US_BULK_STAT_OK;
	struct bulk_cs_wrap	*csw;
	int			rc;

	/* Wait for the next buffer to become available */
	bh = fsg->common->next_buffhd_to_fill;
	while (bh->state != BUF_STATE_EMPTY) {
		rc = sleep_thread(fsg->common, true);
		if (rc)
			return rc;
	}

	if (fsg->common->phase_error) {
		DBG(fsg, "sending phase-error status\n");
		status = US_BULK_STAT_PHASE;

	} else if ((UTP_CTX(fsg)->sd & 0xFFFF) != UTP_REPLY_PASS) {
		status = US_BULK_STAT_FAIL;
	}

	csw = bh->buf;

	/* Store and send the Bulk-only CSW */
	csw->Signature = __constant_cpu_to_le32(US_BULK_CS_SIGN);
	csw->Tag = fsg->common->tag;
	csw->Residue = cpu_to_le32(fsg->common->residue);
	csw->Status = status;

	bh->inreq->length = US_BULK_CS_WRAP_LEN;
	bh->inreq->zero = 0;
	start_transfer(fsg, fsg->bulk_in, bh->inreq,
			&bh->inreq_busy, &bh->state);
	fsg->common->next_buffhd_to_fill = bh->next;
	return 0;
}

static int utp_handle_message(struct fsg_dev *fsg,
			      char *cdb_data,
			      int default_reply)
{
	struct utp_msg *m = (struct utp_msg *)cdb_data;
	void *data = NULL;
	int r;
	struct utp_user_data *uud2r;
	unsigned long long param;
	unsigned long tag;

	if (m->f0 != 0xF0)
		return default_reply;

	tag = get_unaligned_be32((void *)&m->utp_msg_tag);
	param = get_be64((void *)&m->param);
	pr_debug("Type 0x%x, tag 0x%08lx, param %llx\n",
			m->utp_msg_type, tag, param);

	switch ((enum utp_msg_type)m->utp_msg_type) {

	case UTP_POLL:
		if (get_be64((void *)&m->param) == 1) {
			pr_debug("%s: version request\n", __func__);
			UTP_SS_EXIT(fsg, UTP_CTX(fsg)->utp_version);
			break;
		}
		utp_poll(fsg);
		break;
	case UTP_EXEC:
		pr_debug("%s: EXEC\n", __func__);
		data = vmalloc(fsg->common->data_size);
		memset(data, 0, fsg->common->data_size);
		/* copy data from usb buffer to utp buffer */
		utp_do_write(fsg, data, fsg->common->data_size);
		utp_exec(fsg, data, fsg->common->data_size, param);
		vfree(data);
		break;
	case UTP_GET: /* data from device to host */
		pr_debug("%s: GET, %d bytes\n", __func__,
					fsg->common->data_size);
		r = utp_do_read(fsg, UTP_CTX(fsg)->buffer,
					fsg->common->data_size);
		UTP_SS_PASS(fsg);
		break;
	case UTP_PUT:
		utp_context.cur_state =  UTP_FLAG_DATA;
		pr_debug("%s: PUT, Received %d bytes\n", __func__, fsg->common->data_size);/* data from host to device */
		uud2r = utp_user_data_alloc(fsg->common->data_size);
		if (!uud2r)
			return -ENOMEM;
		uud2r->data.bufsize = fsg->common->data_size;
		uud2r->data.flags = UTP_FLAG_DATA;
		utp_do_write(fsg, uud2r->data.data, fsg->common->data_size);
		/* don't know what will be written */
		mutex_lock(&UTP_CTX(fsg)->lock);
		list_add_tail(&uud2r->link, &UTP_CTX(fsg)->read);
		mutex_unlock(&UTP_CTX(fsg)->lock);
		wake_up(&UTP_CTX(fsg)->wq);
		/*
		 * Return PASS or FAIL according to uuc's status
		 * Please open it if need to check uuc's status
		 * and use another version uuc
		 */
#if 0
		struct utp_user_data *uud = NULL;
		struct utp_context *ctx;
		WAIT_ACTIVITY(write);
		ctx = UTP_CTX(fsg);
		mutex_lock(&ctx->lock);

		if (!list_empty(&ctx->write))
			uud = list_first_entry(&ctx->write,
					struct utp_user_data, link);

		mutex_unlock(&ctx->lock);
		if (uud) {
			if (uud->data.flags & UTP_FLAG_STATUS) {
				printk(KERN_WARNING "%s: exit with status %d\n",
					 __func__, uud->data.status);
				UTP_SS_EXIT(fsg, uud->data.status);
			} else {
				pr_debug("%s: pass\n", __func__);
				UTP_SS_PASS(fsg);
			}
			utp_user_data_free(uud);
		} else{
			UTP_SS_PASS(fsg);
		}
#endif
		if (count_list(&UTP_CTX(fsg)->read) < 7) {
			utp_context.cur_state = 0;
			UTP_SS_PASS(fsg);
		} else
			UTP_SS_BUSY(fsg, UTP_CTX(fsg)->counter);

		break;
	}

	utp_send_status(fsg);
	return -1;
}
