/*
 * Driver for ST5481 USB ISDN modem
 *
 * Author       Frode Isaksen
 * Copyright    2001 by Frode Isaksen      <fisaksen@bewan.com>
 *              2001 by Kai Germaschewski  <kai.germaschewski@gmx.de>
 *
 * This software may be used and distributed according to the terms
 * of the GNU General Public License, incorporated herein by reference.
 *
 */

#include <linux/init.h>
#include <linux/usb.h>
#include <linux/slab.h>
#include "st5481.h"

static int st5481_isoc_flatten(struct urb *urb);

/* ======================================================================
 * control pipe
 */

/*
 * Send the next endpoint 0 request stored in the FIFO.
 * Called either by the completion or by usb_ctrl_msg.
 */
static void usb_next_ctrl_msg(struct urb *urb,
			      struct st5481_adapter *adapter)
{
	struct st5481_ctrl *ctrl = &adapter->ctrl;
	int r_index;

	if (test_and_set_bit(0, &ctrl->busy)) {
		return;
	}

	if ((r_index = fifo_remove(&ctrl->msg_fifo.f)) < 0) {
		test_and_clear_bit(0, &ctrl->busy);
		return;
	}
	urb->setup_packet =
		(unsigned char *)&ctrl->msg_fifo.data[r_index];

	DBG(1, "request=0x%02x,value=0x%04x,index=%x",
	    ((struct ctrl_msg *)urb->setup_packet)->dr.bRequest,
	    ((struct ctrl_msg *)urb->setup_packet)->dr.wValue,
	    ((struct ctrl_msg *)urb->setup_packet)->dr.wIndex);

	// Prepare the URB
	urb->dev = adapter->usb_dev;

	SUBMIT_URB(urb, GFP_ATOMIC);
}

/*
 * Asynchronous endpoint 0 request (async version of usb_control_msg).
 * The request will be queued up in a FIFO if the endpoint is busy.
 */
static void usb_ctrl_msg(struct st5481_adapter *adapter,
			 u8 request, u8 requesttype, u16 value, u16 index,
			 ctrl_complete_t complete, void *context)
{
	struct st5481_ctrl *ctrl = &adapter->ctrl;
	int w_index;
	struct ctrl_msg *ctrl_msg;

	if ((w_index = fifo_add(&ctrl->msg_fifo.f)) < 0) {
		WARNING("control msg FIFO full");
		return;
	}
	ctrl_msg = &ctrl->msg_fifo.data[w_index];

	ctrl_msg->dr.bRequestType = requesttype;
	ctrl_msg->dr.bRequest = request;
	ctrl_msg->dr.wValue = cpu_to_le16p(&value);
	ctrl_msg->dr.wIndex = cpu_to_le16p(&index);
	ctrl_msg->dr.wLength = 0;
	ctrl_msg->complete = complete;
	ctrl_msg->context = context;

	usb_next_ctrl_msg(ctrl->urb, adapter);
}

/*
 * Asynchronous endpoint 0 device request.
 */
void st5481_usb_device_ctrl_msg(struct st5481_adapter *adapter,
				u8 request, u16 value,
				ctrl_complete_t complete, void *context)
{
	usb_ctrl_msg(adapter, request,
		     USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
		     value, 0, complete, context);
}

/*
 * Asynchronous pipe reset (async version of usb_clear_halt).
 */
void st5481_usb_pipe_reset(struct st5481_adapter *adapter,
			   u_char pipe,
			   ctrl_complete_t complete, void *context)
{
	DBG(1, "pipe=%02x", pipe);

	usb_ctrl_msg(adapter,
		     USB_REQ_CLEAR_FEATURE, USB_DIR_OUT | USB_RECIP_ENDPOINT,
		     0, pipe, complete, context);
}


/*
  Physical level functions
*/

void st5481_ph_command(struct st5481_adapter *adapter, unsigned int command)
{
	DBG(8, "command=%s", ST5481_CMD_string(command));

	st5481_usb_device_ctrl_msg(adapter, TXCI, command, NULL, NULL);
}

/*
 * The request on endpoint 0 has completed.
 * Call the user provided completion routine and try
 * to send the next request.
 */
static void usb_ctrl_complete(struct urb *urb)
{
	struct st5481_adapter *adapter = urb->context;
	struct st5481_ctrl *ctrl = &adapter->ctrl;
	struct ctrl_msg *ctrl_msg;

	if (unlikely(urb->status < 0)) {
		switch (urb->status) {
		case -ENOENT:
		case -ESHUTDOWN:
		case -ECONNRESET:
			DBG(1, "urb killed status %d", urb->status);
			return; // Give up
		default:
			WARNING("urb status %d", urb->status);
			break;
		}
	}

	ctrl_msg = (struct ctrl_msg *)urb->setup_packet;

	if (ctrl_msg->dr.bRequest == USB_REQ_CLEAR_FEATURE) {
		/* Special case handling for pipe reset */
		le16_to_cpus(&ctrl_msg->dr.wIndex);
		usb_reset_endpoint(adapter->usb_dev, ctrl_msg->dr.wIndex);
	}

	if (ctrl_msg->complete)
		ctrl_msg->complete(ctrl_msg->context);

	clear_bit(0, &ctrl->busy);

	// Try to send next control message
	usb_next_ctrl_msg(urb, adapter);
	return;
}

/* ======================================================================
 * interrupt pipe
 */

/*
 * The interrupt endpoint will be called when any
 * of the 6 registers changes state (depending on masks).
 * Decode the register values and schedule a private event.
 * Called at interrupt.
 */
static void usb_int_complete(struct urb *urb)
{
	u8 *data = urb->transfer_buffer;
	u8 irqbyte;
	struct st5481_adapter *adapter = urb->context;
	int j;
	int status;

	switch (urb->status) {
	case 0:
		/* success */
		break;
	case -ECONNRESET:
	case -ENOENT:
	case -ESHUTDOWN:
		/* this urb is terminated, clean up */
		DBG(2, "urb shutting down with status: %d", urb->status);
		return;
	default:
		WARNING("nonzero urb status received: %d", urb->status);
		goto exit;
	}


	DBG_PACKET(2, data, INT_PKT_SIZE);

	if (urb->actual_length == 0) {
		goto exit;
	}

	irqbyte = data[MPINT];
	if (irqbyte & DEN_INT)
		FsmEvent(&adapter->d_out.fsm, EV_DOUT_DEN, NULL);

	if (irqbyte & DCOLL_INT)
		FsmEvent(&adapter->d_out.fsm, EV_DOUT_COLL, NULL);

	irqbyte = data[FFINT_D];
	if (irqbyte & OUT_UNDERRUN)
		FsmEvent(&adapter->d_out.fsm, EV_DOUT_UNDERRUN, NULL);

	if (irqbyte & OUT_DOWN)
		;//		printk("OUT_DOWN\n");

	irqbyte = data[MPINT];
	if (irqbyte & RXCI_INT)
		FsmEvent(&adapter->l1m, data[CCIST] & 0x0f, NULL);

	for (j = 0; j < 2; j++)
		adapter->bcs[j].b_out.flow_event |= data[FFINT_B1 + j];

	urb->actual_length = 0;

exit:
	status = usb_submit_urb(urb, GFP_ATOMIC);
	if (status)
		WARNING("usb_submit_urb failed with result %d", status);
}

/* ======================================================================
 * initialization
 */

int st5481_setup_usb(struct st5481_adapter *adapter)
{
	struct usb_device *dev = adapter->usb_dev;
	struct st5481_ctrl *ctrl = &adapter->ctrl;
	struct st5481_intr *intr = &adapter->intr;
	struct usb_interface *intf;
	struct usb_host_interface *altsetting = NULL;
	struct usb_host_endpoint *endpoint;
	int status;
	struct urb *urb;
	u8 *buf;

	DBG(2, "");

	if ((status = usb_reset_configuration(dev)) < 0) {
		WARNING("reset_configuration failed,status=%d", status);
		return status;
	}

	intf = usb_ifnum_to_if(dev, 0);
	if (intf)
		altsetting = usb_altnum_to_altsetting(intf, 3);
	if (!altsetting)
		return -ENXIO;

	// Check if the config is sane
	if (altsetting->desc.bNumEndpoints != 7) {
		WARNING("expecting 7 got %d endpoints!", altsetting->desc.bNumEndpoints);
		return -EINVAL;
	}

	// The descriptor is wrong for some early samples of the ST5481 chip
	altsetting->endpoint[3].desc.wMaxPacketSize = cpu_to_le16(32);
	altsetting->endpoint[4].desc.wMaxPacketSize = cpu_to_le16(32);

	// Use alternative setting 3 on interface 0 to have 2B+D
	if ((status = usb_set_interface(dev, 0, 3)) < 0) {
		WARNING("usb_set_interface failed,status=%d", status);
		return status;
	}

	// Allocate URB for control endpoint
	urb = usb_alloc_urb(0, GFP_KERNEL);
	if (!urb) {
		return -ENOMEM;
	}
	ctrl->urb = urb;

	// Fill the control URB
	usb_fill_control_urb(urb, dev,
			     usb_sndctrlpipe(dev, 0),
			     NULL, NULL, 0, usb_ctrl_complete, adapter);


	fifo_init(&ctrl->msg_fifo.f, ARRAY_SIZE(ctrl->msg_fifo.data));

	// Allocate URBs and buffers for interrupt endpoint
	urb = usb_alloc_urb(0, GFP_KERNEL);
	if (!urb) {
		goto err1;
	}
	intr->urb = urb;

	buf = kmalloc(INT_PKT_SIZE, GFP_KERNEL);
	if (!buf) {
		goto err2;
	}

	endpoint = &altsetting->endpoint[EP_INT-1];

	// Fill the interrupt URB
	usb_fill_int_urb(urb, dev,
			 usb_rcvintpipe(dev, endpoint->desc.bEndpointAddress),
			 buf, INT_PKT_SIZE,
			 usb_int_complete, adapter,
			 endpoint->desc.bInterval);

	return 0;
err2:
	usb_free_urb(intr->urb);
	intr->urb = NULL;
err1:
	usb_free_urb(ctrl->urb);
	ctrl->urb = NULL;

	return -ENOMEM;
}

/*
 * Release buffers and URBs for the interrupt and control
 * endpoint.
 */
void st5481_release_usb(struct st5481_adapter *adapter)
{
	struct st5481_intr *intr = &adapter->intr;
	struct st5481_ctrl *ctrl = &adapter->ctrl;

	DBG(1, "");

	// Stop and free Control and Interrupt URBs
	usb_kill_urb(ctrl->urb);
	kfree(ctrl->urb->transfer_buffer);
	usb_free_urb(ctrl->urb);
	ctrl->urb = NULL;

	usb_kill_urb(intr->urb);
	kfree(intr->urb->transfer_buffer);
	usb_free_urb(intr->urb);
	intr->urb = NULL;
}

/*
 *  Initialize the adapter.
 */
void st5481_start(struct st5481_adapter *adapter)
{
	static const u8 init_cmd_table[] = {
		SET_DEFAULT, 0,
		STT, 0,
		SDA_MIN, 0x0d,
		SDA_MAX, 0x29,
		SDELAY_VALUE, 0x14,
		GPIO_DIR, 0x01,
		GPIO_OUT, RED_LED,
//		FFCTRL_OUT_D,4,
//		FFCTRH_OUT_D,12,
		FFCTRL_OUT_B1, 6,
		FFCTRH_OUT_B1, 20,
		FFCTRL_OUT_B2, 6,
		FFCTRH_OUT_B2, 20,
		MPMSK, RXCI_INT + DEN_INT + DCOLL_INT,
		0
	};
	struct st5481_intr *intr = &adapter->intr;
	int i = 0;
	u8 request, value;

	DBG(8, "");

	adapter->leds = RED_LED;

	// Start receiving on the interrupt endpoint
	SUBMIT_URB(intr->urb, GFP_KERNEL);

	while ((request = init_cmd_table[i++])) {
		value = init_cmd_table[i++];
		st5481_usb_device_ctrl_msg(adapter, request, value, NULL, NULL);
	}
	st5481_ph_command(adapter, ST5481_CMD_PUP);
}

/*
 * Reset the adapter to default values.
 */
void st5481_stop(struct st5481_adapter *adapter)
{
	DBG(8, "");

	st5481_usb_device_ctrl_msg(adapter, SET_DEFAULT, 0, NULL, NULL);
}

/* ======================================================================
 * isochronous USB  helpers
 */

static void
fill_isoc_urb(struct urb *urb, struct usb_device *dev,
	      unsigned int pipe, void *buf, int num_packets,
	      int packet_size, usb_complete_t complete,
	      void *context)
{
	int k;

	urb->dev = dev;
	urb->pipe = pipe;
	urb->interval = 1;
	urb->transfer_buffer = buf;
	urb->number_of_packets = num_packets;
	urb->transfer_buffer_length = num_packets * packet_size;
	urb->actual_length = 0;
	urb->complete = complete;
	urb->context = context;
	urb->transfer_flags = URB_ISO_ASAP;
	for (k = 0; k < num_packets; k++) {
		urb->iso_frame_desc[k].offset = packet_size * k;
		urb->iso_frame_desc[k].length = packet_size;
		urb->iso_frame_desc[k].actual_length = 0;
	}
}

int
st5481_setup_isocpipes(struct urb *urb[2], struct usb_device *dev,
		       unsigned int pipe, int num_packets,
		       int packet_size, int buf_size,
		       usb_complete_t complete, void *context)
{
	int j, retval;
	unsigned char *buf;

	for (j = 0; j < 2; j++) {
		retval = -ENOMEM;
		urb[j] = usb_alloc_urb(num_packets, GFP_KERNEL);
		if (!urb[j])
			goto err;

		// Allocate memory for 2000bytes/sec (16Kb/s)
		buf = kmalloc(buf_size, GFP_KERNEL);
		if (!buf)
			goto err;

		// Fill the isochronous URB
		fill_isoc_urb(urb[j], dev, pipe, buf,
			      num_packets, packet_size, complete,
			      context);
	}
	return 0;

err:
	for (j = 0; j < 2; j++) {
		if (urb[j]) {
			kfree(urb[j]->transfer_buffer);
			urb[j]->transfer_buffer = NULL;
			usb_free_urb(urb[j]);
			urb[j] = NULL;
		}
	}
	return retval;
}

void st5481_release_isocpipes(struct urb *urb[2])
{
	int j;

	for (j = 0; j < 2; j++) {
		usb_kill_urb(urb[j]);
		kfree(urb[j]->transfer_buffer);
		usb_free_urb(urb[j]);
		urb[j] = NULL;
	}
}

/*
 * Decode frames received on the B/D channel.
 * Note that this function will be called continuously
 * with 64Kbit/s / 16Kbit/s of data and hence it will be
 * called 50 times per second with 20 ISOC descriptors.
 * Called at interrupt.
 */
static void usb_in_complete(struct urb *urb)
{
	struct st5481_in *in = urb->context;
	unsigned char *ptr;
	struct sk_buff *skb;
	int len, count, status;

	if (unlikely(urb->status < 0)) {
		switch (urb->status) {
		case -ENOENT:
		case -ESHUTDOWN:
		case -ECONNRESET:
			DBG(1, "urb killed status %d", urb->status);
			return; // Give up
		default:
			WARNING("urb status %d", urb->status);
			break;
		}
	}

	DBG_ISO_PACKET(0x80, urb);

	len = st5481_isoc_flatten(urb);
	ptr = urb->transfer_buffer;
	while (len > 0) {
		if (in->mode == L1_MODE_TRANS) {
			memcpy(in->rcvbuf, ptr, len);
			status = len;
			len = 0;
		} else {
			status = isdnhdlc_decode(&in->hdlc_state, ptr, len, &count,
						 in->rcvbuf, in->bufsize);
			ptr += count;
			len -= count;
		}

		if (status > 0) {
			// Good frame received
			DBG(4, "count=%d", status);
			DBG_PACKET(0x400, in->rcvbuf, status);
			if (!(skb = dev_alloc_skb(status))) {
				WARNING("receive out of memory\n");
				break;
			}
			memcpy(skb_put(skb, status), in->rcvbuf, status);
			in->hisax_if->l1l2(in->hisax_if, PH_DATA | INDICATION, skb);
		} else if (status == -HDLC_CRC_ERROR) {
			INFO("CRC error");
		} else if (status == -HDLC_FRAMING_ERROR) {
			INFO("framing error");
		} else if (status == -HDLC_LENGTH_ERROR) {
			INFO("length error");
		}
	}

	// Prepare URB for next transfer
	urb->dev = in->adapter->usb_dev;
	urb->actual_length = 0;

	SUBMIT_URB(urb, GFP_ATOMIC);
}

int st5481_setup_in(struct st5481_in *in)
{
	struct usb_device *dev = in->adapter->usb_dev;
	int retval;

	DBG(4, "");

	in->rcvbuf = kmalloc(in->bufsize, GFP_KERNEL);
	retval = -ENOMEM;
	if (!in->rcvbuf)
		goto err;

	retval = st5481_setup_isocpipes(in->urb, dev,
					usb_rcvisocpipe(dev, in->ep),
					in->num_packets,  in->packet_size,
					in->num_packets * in->packet_size,
					usb_in_complete, in);
	if (retval)
		goto err_free;
	return 0;

err_free:
	kfree(in->rcvbuf);
err:
	return retval;
}

void st5481_release_in(struct st5481_in *in)
{
	DBG(2, "");

	st5481_release_isocpipes(in->urb);
}

/*
 * Make the transfer_buffer contiguous by
 * copying from the iso descriptors if necessary.
 */
static int st5481_isoc_flatten(struct urb *urb)
{
	struct usb_iso_packet_descriptor *pipd, *pend;
	unsigned char *src, *dst;
	unsigned int len;

	if (urb->status < 0) {
		return urb->status;
	}
	for (pipd = &urb->iso_frame_desc[0],
		     pend = &urb->iso_frame_desc[urb->number_of_packets],
		     dst = urb->transfer_buffer;
	     pipd < pend;
	     pipd++) {

		if (pipd->status < 0) {
			return (pipd->status);
		}

		len = pipd->actual_length;
		pipd->actual_length = 0;
		src = urb->transfer_buffer + pipd->offset;

		if (src != dst) {
			// Need to copy since isoc buffers not full
			while (len--) {
				*dst++ = *src++;
			}
		} else {
			// No need to copy, just update destination buffer
			dst += len;
		}
	}
	// Return size of flattened buffer
	return (dst - (unsigned char *)urb->transfer_buffer);
}

static void st5481_start_rcv(void *context)
{
	struct st5481_in *in = context;
	struct st5481_adapter *adapter = in->adapter;

	DBG(4, "");

	in->urb[0]->dev = adapter->usb_dev;
	SUBMIT_URB(in->urb[0], GFP_KERNEL);

	in->urb[1]->dev = adapter->usb_dev;
	SUBMIT_URB(in->urb[1], GFP_KERNEL);
}

void st5481_in_mode(struct st5481_in *in, int mode)
{
	if (in->mode == mode)
		return;

	in->mode = mode;

	usb_unlink_urb(in->urb[0]);
	usb_unlink_urb(in->urb[1]);

	if (in->mode != L1_MODE_NULL) {
		if (in->mode != L1_MODE_TRANS) {
			u32 features = HDLC_BITREVERSE;

			if (in->mode == L1_MODE_HDLC_56K)
				features |= HDLC_56KBIT;
			isdnhdlc_rcv_init(&in->hdlc_state, features);
		}
		st5481_usb_pipe_reset(in->adapter, in->ep, NULL, NULL);
		st5481_usb_device_ctrl_msg(in->adapter, in->counter,
					   in->packet_size,
					   NULL, NULL);
		st5481_start_rcv(in);
	} else {
		st5481_usb_device_ctrl_msg(in->adapter, in->counter,
					   0, NULL, NULL);
	}
}
