/* USB communication methods
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA
 */
#include "board.h"
#include "llist_irqsafe.h"
#include "usb_buf.h"
#include "utils.h"

#include <osmocom/core/linuxlist.h>
#include <osmocom/core/msgb.h>
#include <errno.h>

/***********************************************************************
 * USBD Integration API
 ***********************************************************************/

/* call-back after (successful?) transfer of a write buffer on IN EP */
static void usb_write_cb(uint8_t *arg, uint8_t status, uint32_t transferred,
			 uint32_t remaining)
{
	struct msgb *msg = (struct msgb *) arg;
	struct usb_buffered_ep *bep = msg->dst;
	uint16_t ep_size = USBD_GetEndpointSize(bep->ep);
	unsigned long x;

	TRACE_DEBUG("%s (EP=0x%02x)\r\n", __func__, bep->ep);

	if (((msgb_length(msg) % ep_size) == 0) && (transferred == ep_size)) {
		/* terminate with ZLP; pass in 'msg' again as 'arg' so we get
		 * called the second time and proceed with usb_buf_free below */
		USBD_Write(bep->ep, 0, 0, (TransferCallback) &usb_write_cb, msg);
		return;
	}

	local_irq_save(x);
	bep->in_progress--;
	local_irq_restore(x);
	TRACE_DEBUG("%u: in_progress=%lu\r\n", bep->ep, bep->in_progress);

	if (status != USBD_STATUS_SUCCESS)
		TRACE_ERROR("%s error, status=%d\r\n", __func__, status);

	usb_buf_free(msg);
}

/* check if the spcified IN endpoint is idle and submit the next buffer from queue */
int usb_refill_to_host(uint8_t ep)
{
	struct usb_buffered_ep *bep = usb_get_buf_ep(ep);
	struct msgb *msg;
	unsigned long x;
	int rc;

#if 0
	if (bep->out_from_host) {
		TRACE_ERROR("EP 0x%02x is not IN\r\n", bep->ep);
		return -EINVAL;
	}
#endif

	local_irq_save(x);
	if (bep->in_progress) {
		local_irq_restore(x);
		return 0;
	}

	if (llist_empty(&bep->queue)) {
		local_irq_restore(x);
		return 0;
	}

	bep->in_progress++;

	msg = msgb_dequeue_count(&bep->queue, &bep->queue_len);

	local_irq_restore(x);

	TRACE_DEBUG("%s (EP=0x%02x), in_progress=%lu\r\n", __func__, ep, bep->in_progress);

	msg->dst = bep;

	rc = USBD_Write(ep, msgb_data(msg), msgb_length(msg),
			(TransferCallback) &usb_write_cb, msg);
	if (rc != USBD_STATUS_SUCCESS) {
		TRACE_ERROR("%s error %x\r\n", __func__, rc);
		/* re-insert to head of queue */
		llist_add_irqsafe(&msg->list, &bep->queue);
		local_irq_save(x);
		bep->in_progress--;
		local_irq_restore(x);
		TRACE_DEBUG("%02x: in_progress=%lu\r\n", bep->ep, bep->in_progress);
		return 0;
	}

	return 1;
}

/* call-back after (successful?) read transfer of a buffer on OUT EP */
static void usb_read_cb(uint8_t *arg, uint8_t status, uint32_t transferred,
			uint32_t remaining)
{
	struct msgb *msg = (struct msgb *) arg;
	struct usb_buffered_ep *bep = msg->dst;

	TRACE_DEBUG("%s (EP=%u, len=%lu, q=%p)\r\n", __func__,
			bep->ep, transferred, &bep->queue);

	bep->in_progress = 0;

	if (status != USBD_STATUS_SUCCESS) {
		TRACE_ERROR("%s error, status=%d\r\n", __func__, status);
		usb_buf_free(msg);
		return;
	}
	msgb_put(msg, transferred);
	llist_add_tail_irqsafe(&msg->list, &bep->queue);
}

/* refill the read queue for data received from host PC on OUT EP, if needed */
int usb_refill_from_host(uint8_t ep)
{
	struct usb_buffered_ep *bep = usb_get_buf_ep(ep);
	struct msgb *msg;
	unsigned long x;
	int rc;

#if 0
	if (!bep->out_from_host) {
		TRACE_ERROR("EP 0x%02x is not OUT\r\n", bep->ep);
		return -EINVAL;
	}
#endif

	if (bep->in_progress)
		return 0;

	TRACE_DEBUG("%s (EP=0x%02x)\r\n", __func__, bep->ep);

	msg = usb_buf_alloc(bep->ep);
	if (!msg)
		return -ENOMEM;
	msg->dst = bep;
	msg->l1h = msg->head;

	bep->in_progress = 1;

	rc = USBD_Read(ep, msg->head, msgb_tailroom(msg),
			(TransferCallback) &usb_read_cb, msg);
	if (rc != USBD_STATUS_SUCCESS) {
		TRACE_ERROR("%s error %d\r\n", __func__, rc);
		usb_buf_free(msg);
		bep->in_progress = 0;
	}

	return 1;
}

/* drain any buffers from the queue of the endpoint and release their memory */
int usb_drain_queue(uint8_t ep)
{
	struct usb_buffered_ep *bep = usb_get_buf_ep(ep);
	struct msgb *msg;
	unsigned long x;
	int ret = 0;

	/* wait until no transfers are in progress anymore and block
	 * further interrupts */
	while (1) {
		local_irq_save(x);
		if (!bep->in_progress) {
			break;
		}
		local_irq_restore(x);
		/* retry */
	}

	/* free all queued msgbs */
	while ((msg = msgb_dequeue_count(&bep->queue, &bep->queue_len))) {
		usb_buf_free(msg);
		ret++;
	}

	/* re-enable interrupts and return number of free'd msgbs */
	local_irq_restore(x);

	return ret;
}
