/*
 * Line6 Linux USB driver - 0.8.0
 *
 * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at)
 *
 *	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, version 2.
 *
 */

#include "driver.h"

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/usb.h>

#include "audio.h"
#include "capture.h"
#include "control.h"
#include "midi.h"
#include "playback.h"
#include "pod.h"
#include "revision.h"
#include "toneport.h"
#include "usbdefs.h"
#include "variax.h"


#define DRIVER_AUTHOR  "Markus Grabner <grabner@icg.tugraz.at>"
#define DRIVER_DESC    "Line6 USB Driver"
#define DRIVER_VERSION "0.8.0"


/* table of devices that work with this driver */
static struct usb_device_id line6_id_table[] = {
	{ USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_BASSPODXT) },
	{ USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_BASSPODXTLIVE) },
	{ USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_BASSPODXTPRO) },
	{ USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_GUITARPORT) },
	{ USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_POCKETPOD) },
	{ USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_PODX3) },
	{ USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_PODX3LIVE) },
	{ USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_PODXT) },
	{ USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_PODXTLIVE) },
	{ USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_PODXTPRO) },
	{ USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_TONEPORT_GX) },
	{ USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_TONEPORT_UX1) },
	{ USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_TONEPORT_UX2) },
	{ USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_VARIAX) },
	{ },
};
MODULE_DEVICE_TABLE(usb, line6_id_table);

static struct line6_properties line6_properties_table[] = {
	{ "BassPODxt",        LINE6_BIT_BASSPODXT,     LINE6_BIT_CONTROL_PCM },
	{ "BassPODxt Live",   LINE6_BIT_BASSPODXTLIVE, LINE6_BIT_CONTROL_PCM },
	{ "BassPODxt Pro",    LINE6_BIT_BASSPODXTPRO,  LINE6_BIT_CONTROL_PCM },
	{ "GuitarPort",       LINE6_BIT_GUITARPORT,    LINE6_BIT_PCM         },
	{ "Pocket POD",       LINE6_BIT_POCKETPOD,     LINE6_BIT_CONTROL_PCM },
	{ "POD X3",           LINE6_BIT_PODX3,         LINE6_BIT_PCM         },
	{ "POD X3 Live",      LINE6_BIT_PODX3LIVE,     LINE6_BIT_PCM         },
	{ "PODxt",            LINE6_BIT_PODXT,         LINE6_BIT_CONTROL_PCM },
	{ "PODxt Live",       LINE6_BIT_PODXTLIVE,     LINE6_BIT_CONTROL_PCM },
	{ "PODxt Pro",        LINE6_BIT_PODXTPRO,      LINE6_BIT_CONTROL_PCM },
	{ "TonePort GX",      LINE6_BIT_TONEPORT_GX,   LINE6_BIT_PCM         },
	{ "TonePort UX1",     LINE6_BIT_TONEPORT_UX1,  LINE6_BIT_PCM         },
	{ "TonePort UX2",     LINE6_BIT_TONEPORT_UX2,  LINE6_BIT_PCM         },
	{ "Variax Workbench", LINE6_BIT_VARIAX,        LINE6_BIT_CONTROL     }
};


/*
	This is Line6's MIDI manufacturer ID.
*/
const unsigned char line6_midi_id[] = { 0x00, 0x01, 0x0c };

struct usb_line6 *line6_devices[LINE6_MAX_DEVICES];
struct workqueue_struct *line6_workqueue;


/**
	 Class for asynchronous messages.
*/
struct message {
	struct usb_line6 *line6;
	const char *buffer;
	int size;
	int done;
};


/*
	Forward declarations.
*/
static void line6_data_received(struct urb *urb);
static int line6_send_raw_message_async_part(struct message *msg,
					     struct urb *urb);


/*
	Start to listen on endpoint.
*/
static int line6_start_listen(struct usb_line6 *line6)
{
	usb_fill_int_urb(line6->urb_listen, line6->usbdev,
			 usb_rcvintpipe(line6->usbdev, line6->ep_control_read),
			 line6->buffer_listen, LINE6_BUFSIZE_LISTEN,
			 line6_data_received, line6, line6->interval);
	line6->urb_listen->actual_length = 0;
	return usb_submit_urb(line6->urb_listen, GFP_KERNEL);
}

#if DO_DUMP_ANY
/*
	Write hexdump to syslog.
*/
void line6_write_hexdump(struct usb_line6 *line6, char dir,
			 const unsigned char *buffer, int size)
{
	static const int BYTES_PER_LINE = 8;
	char hexdump[100];
	char asc[BYTES_PER_LINE + 1];
	int i, j;

	for (i = 0; i < size; i += BYTES_PER_LINE) {
		int hexdumpsize = sizeof(hexdump);
		char *p = hexdump;
		int n = min(size - i, BYTES_PER_LINE);
		asc[n] = 0;

		for (j = 0; j < BYTES_PER_LINE; ++j) {
			int bytes;

			if (j < n) {
				unsigned char val = buffer[i + j];
				bytes = snprintf(p, hexdumpsize, " %02X", val);
				asc[j] = ((val >= 0x20) && (val < 0x7f)) ? val : '.';
			} else
				bytes = snprintf(p, hexdumpsize, "   ");

			if (bytes > hexdumpsize)
				break;  /* buffer overflow */

			p += bytes;
			hexdumpsize -= bytes;
		}

		dev_info(line6->ifcdev, "%c%04X:%s %s\n", dir, i, hexdump, asc);
	}
}
#endif

#if DO_DUMP_URB_RECEIVE
/*
	Dump URB data to syslog.
*/
static void line6_dump_urb(struct urb *urb)
{
	struct usb_line6 *line6 = (struct usb_line6 *)urb->context;

	if (urb->status < 0)
		return;

	line6_write_hexdump(line6, 'R', (unsigned char *)urb->transfer_buffer,
			    urb->actual_length);
}
#endif

/*
	Send raw message in pieces of max_packet_size bytes.
*/
int line6_send_raw_message(struct usb_line6 *line6, const char *buffer,
			   int size)
{
	int i, done = 0;
	int actual_size;

#if DO_DUMP_URB_SEND
	line6_write_hexdump(line6, 'S', buffer, size);
#endif

	for (i = 0; i < size; i += actual_size) {
		const char *frag_buf = buffer + i;
		int frag_size = min(line6->max_packet_size, size - i);
		int retval;

		retval = usb_interrupt_msg(line6->usbdev,
					   usb_sndintpipe(line6->usbdev,
							  line6->ep_control_write),
					   (char *)frag_buf, frag_size,
					   &actual_size, LINE6_TIMEOUT * HZ);

		if (retval) {
			dev_err(line6->ifcdev,
				"usb_interrupt_msg failed (%d)\n", retval);
			break;
		}

		done += actual_size;
	}

	return done;
}

/*
	Notification of completion of asynchronous request transmission.
*/
static void line6_async_request_sent(struct urb *urb)
{
	struct message *msg = (struct message *)urb->context;

	if (msg->done >= msg->size) {
		usb_free_urb(urb);
		kfree(msg);
	} else
		line6_send_raw_message_async_part(msg, urb);
}

/*
	Asynchronously send part of a raw message.
*/
static int line6_send_raw_message_async_part(struct message *msg,
					     struct urb *urb)
{
	int retval;
	struct usb_line6 *line6 = msg->line6;
	int done = msg->done;
	int bytes = min(msg->size - done, line6->max_packet_size);

	usb_fill_int_urb(urb, line6->usbdev,
			 usb_sndintpipe(line6->usbdev, line6->ep_control_write),
			 (char *)msg->buffer + done, bytes,
			 line6_async_request_sent, msg, line6->interval);

#if DO_DUMP_URB_SEND
	line6_write_hexdump(line6, 'S', (char *)msg->buffer + done, bytes);
#endif

	msg->done += bytes;
	retval = usb_submit_urb(urb, GFP_ATOMIC);

	if (retval < 0) {
		dev_err(line6->ifcdev, "%s: usb_submit_urb failed (%d)\n",
			__func__, retval);
		usb_free_urb(urb);
		kfree(msg);
		return -EINVAL;
	}

	return 0;
}

/*
	Asynchronously send raw message.
*/
int line6_send_raw_message_async(struct usb_line6 *line6, const char *buffer,
				 int size)
{
	struct message *msg;
	struct urb *urb;

	/* create message: */
	msg = kmalloc(sizeof(struct message), GFP_ATOMIC);

	if (msg == NULL) {
		dev_err(line6->ifcdev, "Out of memory\n");
		return -ENOMEM;
	}

	/* create URB: */
	urb = usb_alloc_urb(0, GFP_ATOMIC);

	if (urb == NULL) {
		kfree(msg);
		dev_err(line6->ifcdev, "Out of memory\n");
		return -ENOMEM;
	}

	/* set message data: */
	msg->line6 = line6;
	msg->buffer = buffer;
	msg->size = size;
	msg->done = 0;

	/* start sending: */
	return line6_send_raw_message_async_part(msg, urb);
}

/*
	Send sysex message in pieces of wMaxPacketSize bytes.
*/
int line6_send_sysex_message(struct usb_line6 *line6, const char *buffer,
			     int size)
{
	return line6_send_raw_message(line6, buffer, size + SYSEX_EXTRA_SIZE) - SYSEX_EXTRA_SIZE;
}

/*
	Allocate buffer for sysex message and prepare header.
	@param code sysex message code
	@param size number of bytes between code and sysex end
*/
char *line6_alloc_sysex_buffer(struct usb_line6 *line6, int code1, int code2,
			       int size)
{
	char *buffer = kmalloc(size + SYSEX_EXTRA_SIZE, GFP_KERNEL);

	if (!buffer) {
		dev_err(line6->ifcdev, "out of memory\n");
		return NULL;
	}

	buffer[0] = LINE6_SYSEX_BEGIN;
	memcpy(buffer + 1, line6_midi_id, sizeof(line6_midi_id));
	buffer[sizeof(line6_midi_id) + 1] = code1;
	buffer[sizeof(line6_midi_id) + 2] = code2;
	buffer[sizeof(line6_midi_id) + 3 + size] = LINE6_SYSEX_END;
	return buffer;
}

/*
	Notification of data received from the Line6 device.
*/
static void line6_data_received(struct urb *urb)
{
	struct usb_line6 *line6 = (struct usb_line6 *)urb->context;
	struct MidiBuffer *mb = &line6->line6midi->midibuf_in;
	int done;

	if (urb->status == -ESHUTDOWN)
		return;

#if DO_DUMP_URB_RECEIVE
	line6_dump_urb(urb);
#endif

	done = midibuf_write(mb, urb->transfer_buffer, urb->actual_length);

	if (done < urb->actual_length) {
		midibuf_ignore(mb, done);
		DEBUG_MESSAGES(dev_err(line6->ifcdev, "%d %d buffer overflow - message skipped\n", done, urb->actual_length));
	}

	for (;;) {
		done = midibuf_read(mb, line6->buffer_message, LINE6_MESSAGE_MAXLEN);

		if (done == 0)
			break;

		/* MIDI input filter */
		if (midibuf_skip_message(mb, line6->line6midi->midi_mask_receive))
			continue;

		line6->message_length = done;
#if DO_DUMP_MIDI_RECEIVE
		line6_write_hexdump(line6, 'r', line6->buffer_message, done);
#endif
		line6_midi_receive(line6, line6->buffer_message, done);

		switch (line6->usbdev->descriptor.idProduct) {
		case LINE6_DEVID_BASSPODXT:
		case LINE6_DEVID_BASSPODXTLIVE:
		case LINE6_DEVID_BASSPODXTPRO:
		case LINE6_DEVID_PODXT:
		case LINE6_DEVID_PODXTPRO:
		case LINE6_DEVID_POCKETPOD:
			pod_process_message((struct usb_line6_pod *)line6);
			break;

		case LINE6_DEVID_PODXTLIVE:
			switch (line6->interface_number) {
			case PODXTLIVE_INTERFACE_POD:
				pod_process_message((struct usb_line6_pod *)line6);
				break;

			case PODXTLIVE_INTERFACE_VARIAX:
				variax_process_message((struct usb_line6_variax *)line6);
				break;

			default:
				dev_err(line6->ifcdev, "PODxt Live interface %d not supported\n", line6->interface_number);
			}
			break;

		case LINE6_DEVID_VARIAX:
			variax_process_message((struct usb_line6_variax *)line6);
			break;

		default:
			MISSING_CASE;
		}
	}

	line6_start_listen(line6);
}

static int line6_send(struct usb_line6 *line6, unsigned char *buf, size_t len)
{
	int retval;
	unsigned int partial;

#if DO_DUMP_URB_SEND
	line6_write_hexdump(line6, 'S', buf, len);
#endif

	retval = usb_interrupt_msg(line6->usbdev,
				   usb_sndintpipe(line6->usbdev,
						  line6->ep_control_write),
				   buf, len, &partial,
				   LINE6_TIMEOUT * HZ);

	if (retval) {
		dev_err(line6->ifcdev,
			"usb_interrupt_msg failed (%d)\n", retval);
	}

	if (partial != len) {
		dev_err(line6->ifcdev,
			"usb_interrupt_msg sent partial message (%d)\n",
			 retval);
	}

	return retval;
}

/*
	Send channel number (i.e., switch to a different sound).
*/
int line6_send_program(struct usb_line6 *line6, int value)
{
	unsigned char *buffer;
	size_t len = 2;

	buffer = kmalloc(len, GFP_KERNEL);
	if (!buffer) {
		dev_err(line6->ifcdev, "out of memory\n");
		return -ENOMEM;
	}

	buffer[0] = LINE6_PROGRAM_CHANGE | LINE6_CHANNEL_HOST;
	buffer[1] = value;

	return line6_send(line6, buffer, len);
}

/*
	Transmit Line6 control parameter.
*/
int line6_transmit_parameter(struct usb_line6 *line6, int param, int value)
{
	unsigned char *buffer;
	size_t len = 3;

	buffer = kmalloc(len, GFP_KERNEL);
	if (!buffer) {
		dev_err(line6->ifcdev, "out of memory\n");
		return -ENOMEM;
	}

	buffer[0] = LINE6_PARAM_CHANGE | LINE6_CHANNEL_HOST;
	buffer[1] = param;
	buffer[2] = value;

	return line6_send(line6, buffer, len);
}

/*
	Read data from device.
*/
int line6_read_data(struct usb_line6 *line6, int address, void *data, size_t datalen)
{
	struct usb_device *usbdev = line6->usbdev;
	int ret;
	unsigned char len;

	/* query the serial number: */
	ret = usb_control_msg(usbdev, usb_sndctrlpipe(usbdev, 0), 0x67,
				      USB_TYPE_VENDOR | USB_RECIP_DEVICE
				      | USB_DIR_OUT,
				      (datalen << 8) | 0x21, address,
				      NULL, 0, LINE6_TIMEOUT * HZ);

	if (ret < 0) {
		dev_err(line6->ifcdev, "read request failed (error %d)\n", ret);
		return ret;
	}

	/* Wait for data length. We'll get a couple of 0xff until length arrives. */
	do {
		ret = usb_control_msg(usbdev, usb_rcvctrlpipe(usbdev, 0), 0x67,
				      USB_TYPE_VENDOR | USB_RECIP_DEVICE |
				      USB_DIR_IN,
				      0x0012, 0x0000, &len, 1,
				      LINE6_TIMEOUT * HZ);
		if (ret < 0) {
			dev_err(line6->ifcdev,
				"receive length failed (error %d)\n", ret);
			return ret;
		}
	} while (len == 0xff);

	if (len != datalen) {
		/* should be equal or something went wrong */
		dev_err(line6->ifcdev,
			"length mismatch (expected %d, got %d)\n",
			(int)datalen, (int)len);
		return -EINVAL;
	}

	/* receive the result: */
	ret = usb_control_msg(usbdev, usb_rcvctrlpipe(usbdev, 0), 0x67,
			      USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
			      0x0013, 0x0000, data, datalen,
			      LINE6_TIMEOUT * HZ);

	if (ret < 0) {
		dev_err(line6->ifcdev, "read failed (error %d)\n", ret);
		return ret;
	}

	return 0;
}

/*
	Write data to device.
*/
int line6_write_data(struct usb_line6 *line6, int address, void *data,
		     size_t datalen)
{
	struct usb_device *usbdev = line6->usbdev;
	int ret;
	unsigned char status;

	ret = usb_control_msg(usbdev, usb_sndctrlpipe(usbdev, 0), 0x67,
			      USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT,
			      0x0022, address, data, datalen,
			      LINE6_TIMEOUT * HZ);

	if (ret < 0) {
		dev_err(line6->ifcdev,
			"write request failed (error %d)\n", ret);
		return ret;
	}

	do {
		ret = usb_control_msg(usbdev, usb_rcvctrlpipe(usbdev, 0),
				      0x67,
				      USB_TYPE_VENDOR | USB_RECIP_DEVICE |
				      USB_DIR_IN,
				      0x0012, 0x0000,
				      &status, 1, LINE6_TIMEOUT * HZ);

		if (ret < 0) {
			dev_err(line6->ifcdev,
				"receiving status failed (error %d)\n", ret);
			return ret;
		}
	}
	while (status == 0xff)
		;

	if (status != 0) {
		dev_err(line6->ifcdev, "write failed (error %d)\n", ret);
		return -EINVAL;
	}

	return 0;
}

/*
	Read Line6 device serial number.
	(POD, TonePort, GuitarPort)
*/
int line6_read_serial_number(struct usb_line6 *line6, int *serial_number)
{
	return line6_read_data(line6, 0x80d0, serial_number, sizeof(*serial_number));
}

/*
	No operation (i.e., unsupported).
*/
ssize_t line6_nop_read(struct device *dev, struct device_attribute *attr,
		       char *buf)
{
	return 0;
}

/*
	No operation (i.e., unsupported).
*/
ssize_t line6_nop_write(struct device *dev, struct device_attribute *attr,
			const char *buf, size_t count)
{
	return count;
}

/*
	"write" request on "raw" special file.
*/
#if CREATE_RAW_FILE
ssize_t line6_set_raw(struct device *dev, struct device_attribute *attr,
		      const char *buf, size_t count)
{
	struct usb_interface *interface = to_usb_interface(dev);
	struct usb_line6 *line6 = usb_get_intfdata(interface);
	line6_send_raw_message(line6, buf, count);
	return count;
}
#endif

/*
	Generic destructor.
*/
static void line6_destruct(struct usb_interface *interface)
{
	struct usb_line6 *line6;

	if (interface == NULL)
		return;
	line6 = usb_get_intfdata(interface);
	if (line6 == NULL)
		return;

	/* free buffer memory first: */
	kfree(line6->buffer_message);
	kfree(line6->buffer_listen);

	/* then free URBs: */
	usb_free_urb(line6->urb_listen);

	/* make sure the device isn't destructed twice: */
	usb_set_intfdata(interface, NULL);

	/* free interface data: */
	kfree(line6);
}

static void line6_list_devices(void)
{
	int i;

	for (i = 0; i < LINE6_MAX_DEVICES; ++i) {
		struct usb_line6 *dev = line6_devices[i];
		printk(KERN_INFO "Line6 device %d: ", i);

		if (dev == NULL)
			printk("(not used)\n");
		else
			printk("%s:%d\n", dev->properties->name, dev->interface_number);
	}
}

/*
	Probe USB device.
*/
static int line6_probe(struct usb_interface *interface, const struct usb_device_id *id)
{
	int devtype;
	struct usb_device *usbdev = NULL;
	struct usb_line6 *line6 = NULL;
	const struct line6_properties *properties;
	int devnum;
	int interface_number, alternate = 0;
	int product;
	int size = 0;
	int ep_read = 0, ep_write = 0;
	int ret;

	if (interface == NULL)
		return -ENODEV;
	usbdev = interface_to_usbdev(interface);
	if (usbdev == NULL)
		return -ENODEV;

	/* increment reference counters: */
	usb_get_intf(interface);
	usb_get_dev(usbdev);

	/* we don't handle multiple configurations */
	if (usbdev->descriptor.bNumConfigurations != 1)
		return -ENODEV;

	/* check vendor and product id */
	for (devtype = ARRAY_SIZE(line6_id_table) - 1; devtype--;) {
		u16 vendor = le16_to_cpu(usbdev->descriptor.idVendor);
		u16 product = le16_to_cpu(usbdev->descriptor.idProduct);

		if (vendor == line6_id_table[devtype].idVendor
		     && product == line6_id_table[devtype].idProduct)
			break;
	}

	if (devtype < 0)
		return -ENODEV;

	/* find free slot in device table: */
	for (devnum = 0; devnum < LINE6_MAX_DEVICES; ++devnum)
		if (line6_devices[devnum] == NULL)
			break;

	if (devnum == LINE6_MAX_DEVICES)
		return -ENODEV;

	/* initialize device info: */
	properties = &line6_properties_table[devtype];
	dev_info(&interface->dev, "Line6 %s found\n", properties->name);
	product = le16_to_cpu(usbdev->descriptor.idProduct);

	/* query interface number */
	interface_number = interface->cur_altsetting->desc.bInterfaceNumber;

	switch (product) {
	case LINE6_DEVID_BASSPODXTLIVE:
	case LINE6_DEVID_POCKETPOD:
	case LINE6_DEVID_PODXTLIVE:
	case LINE6_DEVID_VARIAX:
		alternate = 1;
		break;

	case LINE6_DEVID_PODX3:
	case LINE6_DEVID_PODX3LIVE:
		switch (interface_number) {
		case 0:
			alternate = 1;
			break;
		case 1:
			alternate = 0;
			break;
		default:
			MISSING_CASE;
		}
		break;

	case LINE6_DEVID_BASSPODXT:
	case LINE6_DEVID_BASSPODXTPRO:
	case LINE6_DEVID_PODXT:
	case LINE6_DEVID_PODXTPRO:
		alternate = 5;
		break;

	case LINE6_DEVID_TONEPORT_GX:
	case LINE6_DEVID_GUITARPORT:
		alternate = 2;  /* 1..4 seem to be ok */
		break;

	case LINE6_DEVID_TONEPORT_UX1:
	case LINE6_DEVID_TONEPORT_UX2:
		switch (interface_number) {
		case 0:
			/* defaults to 44.1kHz, 16-bit */
			alternate = 2;
			break;
		case 1:
			alternate = 0;
			break;
		default:
			MISSING_CASE;
		}
		break;

	default:
		MISSING_CASE;
		return -ENODEV;
	}

	ret = usb_set_interface(usbdev, interface_number, alternate);
	if (ret < 0) {
		dev_err(&interface->dev, "set_interface failed\n");
		return ret;
	}

	/* initialize device data based on product id: */
	switch (product) {
	case LINE6_DEVID_BASSPODXT:
	case LINE6_DEVID_BASSPODXTLIVE:
	case LINE6_DEVID_BASSPODXTPRO:
	case LINE6_DEVID_POCKETPOD:
	case LINE6_DEVID_PODXT:
	case LINE6_DEVID_PODXTPRO:
		size = sizeof(struct usb_line6_pod);
		ep_read  = 0x84;
		ep_write = 0x03;
		break;

	case LINE6_DEVID_PODX3:
	case LINE6_DEVID_PODX3LIVE:
		/* currently unused! */
		size = sizeof(struct usb_line6_pod);
		ep_read  = 0x81;
		ep_write = 0x01;
		break;

	case LINE6_DEVID_TONEPORT_GX:
	case LINE6_DEVID_TONEPORT_UX1:
	case LINE6_DEVID_TONEPORT_UX2:
	case LINE6_DEVID_GUITARPORT:
		size = sizeof(struct usb_line6_toneport);
		/* these don't have a control channel */
		break;

	case LINE6_DEVID_PODXTLIVE:
		switch (interface_number) {
		case PODXTLIVE_INTERFACE_POD:
			size = sizeof(struct usb_line6_pod);
			ep_read  = 0x84;
			ep_write = 0x03;
			break;

		case PODXTLIVE_INTERFACE_VARIAX:
			size = sizeof(struct usb_line6_variax);
			ep_read  = 0x86;
			ep_write = 0x05;
			break;

		default:
			return -ENODEV;
		}
		break;

	case LINE6_DEVID_VARIAX:
		size = sizeof(struct usb_line6_variax);
		ep_read  = 0x82;
		ep_write = 0x01;
		break;

	default:
		MISSING_CASE;
		return -ENODEV;
	}

	if (size == 0) {
		dev_err(line6->ifcdev, "driver bug: interface data size not set\n");
		return -ENODEV;
	}

	line6 = kzalloc(size, GFP_KERNEL);

	if (line6 == NULL) {
		dev_err(&interface->dev, "Out of memory\n");
		return -ENOMEM;
	}

	/* store basic data: */
	line6->interface_number = interface_number;
	line6->properties = properties;
	line6->usbdev = usbdev;
	line6->ifcdev = &interface->dev;
	line6->ep_control_read = ep_read;
	line6->ep_control_write = ep_write;
	line6->product = product;

	/* get data from endpoint descriptor (see usb_maxpacket): */
	{
		struct usb_host_endpoint *ep;
		unsigned epnum = usb_pipeendpoint(usb_rcvintpipe(usbdev, ep_read));
		ep = usbdev->ep_in[epnum];

		if (ep != NULL) {
			line6->interval = ep->desc.bInterval;
			line6->max_packet_size = le16_to_cpu(ep->desc.wMaxPacketSize);
		} else {
			line6->interval = LINE6_FALLBACK_INTERVAL;
			line6->max_packet_size = LINE6_FALLBACK_MAXPACKETSIZE;
			dev_err(line6->ifcdev, "endpoint not available, using fallback values");
		}
	}

	usb_set_intfdata(interface, line6);

	if (properties->capabilities & LINE6_BIT_CONTROL) {
		/* initialize USB buffers: */
		line6->buffer_listen = kmalloc(LINE6_BUFSIZE_LISTEN, GFP_KERNEL);

		if (line6->buffer_listen == NULL) {
			dev_err(&interface->dev, "Out of memory\n");
			line6_destruct(interface);
			return -ENOMEM;
		}

		line6->buffer_message = kmalloc(LINE6_MESSAGE_MAXLEN, GFP_KERNEL);

		if (line6->buffer_message == NULL) {
			dev_err(&interface->dev, "Out of memory\n");
			line6_destruct(interface);
			return -ENOMEM;
		}

		line6->urb_listen = usb_alloc_urb(0, GFP_KERNEL);

		if (line6->urb_listen == NULL) {
			dev_err(&interface->dev, "Out of memory\n");
			line6_destruct(interface);
			return -ENOMEM;
		}

		ret = line6_start_listen(line6);
		if (ret < 0) {
			dev_err(&interface->dev, "%s: usb_submit_urb failed\n",
				__func__);
			line6_destruct(interface);
			return ret;
		}
	}

	/* initialize device data based on product id: */
	switch (product) {
	case LINE6_DEVID_BASSPODXT:
	case LINE6_DEVID_BASSPODXTLIVE:
	case LINE6_DEVID_BASSPODXTPRO:
	case LINE6_DEVID_POCKETPOD:
	case LINE6_DEVID_PODX3:
	case LINE6_DEVID_PODX3LIVE:
	case LINE6_DEVID_PODXT:
	case LINE6_DEVID_PODXTPRO:
		ret = pod_init(interface, (struct usb_line6_pod *)line6);
		break;

	case LINE6_DEVID_PODXTLIVE:
		switch (interface_number) {
		case PODXTLIVE_INTERFACE_POD:
			ret = pod_init(interface, (struct usb_line6_pod *)line6);
			break;

		case PODXTLIVE_INTERFACE_VARIAX:
			ret = variax_init(interface, (struct usb_line6_variax *)line6);
			break;

		default:
			dev_err(&interface->dev,
				"PODxt Live interface %d not supported\n",
				interface_number);
			ret = -ENODEV;
		}

		break;

	case LINE6_DEVID_VARIAX:
		ret = variax_init(interface, (struct usb_line6_variax *)line6);
		break;

	case LINE6_DEVID_TONEPORT_GX:
	case LINE6_DEVID_TONEPORT_UX1:
	case LINE6_DEVID_TONEPORT_UX2:
	case LINE6_DEVID_GUITARPORT:
		ret = toneport_init(interface, (struct usb_line6_toneport *)line6);
		break;

	default:
		MISSING_CASE;
		ret = -ENODEV;
	}

	if (ret < 0) {
		line6_destruct(interface);
		return ret;
	}

	ret = sysfs_create_link(&interface->dev.kobj, &usbdev->dev.kobj,
				"usb_device");
	if (ret < 0) {
		line6_destruct(interface);
		return ret;
	}

	dev_info(&interface->dev, "Line6 %s now attached\n",
		 line6->properties->name);
	line6_devices[devnum] = line6;
	line6_list_devices();
	return ret;
}

/*
	Line6 device disconnected.
*/
static void line6_disconnect(struct usb_interface *interface)
{
	struct usb_line6 *line6;
	struct usb_device *usbdev;
	int interface_number, i;

	if (interface == NULL)
		return;
	usbdev = interface_to_usbdev(interface);
	if (usbdev == NULL)
		return;

	sysfs_remove_link(&interface->dev.kobj, "usb_device");

	interface_number = interface->cur_altsetting->desc.bInterfaceNumber;
	line6 = usb_get_intfdata(interface);

	if (line6 != NULL) {
		if (line6->urb_listen != NULL)
			usb_kill_urb(line6->urb_listen);

		if (usbdev != line6->usbdev)
			dev_err(line6->ifcdev,
				"driver bug: inconsistent usb device\n");

		switch (line6->usbdev->descriptor.idProduct) {
		case LINE6_DEVID_BASSPODXT:
		case LINE6_DEVID_BASSPODXTLIVE:
		case LINE6_DEVID_BASSPODXTPRO:
		case LINE6_DEVID_POCKETPOD:
		case LINE6_DEVID_PODX3:
		case LINE6_DEVID_PODX3LIVE:
		case LINE6_DEVID_PODXT:
		case LINE6_DEVID_PODXTPRO:
			pod_disconnect(interface);
			break;

		case LINE6_DEVID_PODXTLIVE:
			switch (interface_number) {
			case PODXTLIVE_INTERFACE_POD:
				pod_disconnect(interface);
				break;

			case PODXTLIVE_INTERFACE_VARIAX:
				variax_disconnect(interface);
				break;
			}

			break;

		case LINE6_DEVID_VARIAX:
			variax_disconnect(interface);
			break;

		case LINE6_DEVID_TONEPORT_GX:
		case LINE6_DEVID_TONEPORT_UX1:
		case LINE6_DEVID_TONEPORT_UX2:
		case LINE6_DEVID_GUITARPORT:
			toneport_disconnect(interface);
			break;

		default:
			MISSING_CASE;
		}

		dev_info(&interface->dev, "Line6 %s now disconnected\n", line6->properties->name);

		for (i = LINE6_MAX_DEVICES; i--;) {
			if (line6_devices[i] == line6)
				line6_devices[i] = NULL;
		}
	}

	line6_destruct(interface);

	/* decrement reference counters: */
	usb_put_intf(interface);
	usb_put_dev(usbdev);

	line6_list_devices();
}

static struct usb_driver line6_driver = {
	.name = DRIVER_NAME,
	.probe = line6_probe,
	.disconnect = line6_disconnect,
	.id_table = line6_id_table,
};

/*
	Module initialization.
*/
static int __init line6_init(void)
{
	int i, retval;

	printk(KERN_INFO "%s driver version %s%s\n",
	       DRIVER_NAME, DRIVER_VERSION, DRIVER_REVISION);
	line6_workqueue = create_workqueue(DRIVER_NAME);

	if (line6_workqueue == NULL) {
		err("couldn't create workqueue");
		return -EINVAL;
	}

	for (i = LINE6_MAX_DEVICES; i--;)
		line6_devices[i] = NULL;

	retval = usb_register(&line6_driver);

	if (retval)
		err("usb_register failed. Error number %d", retval);

	return retval;
}

/*
	Module cleanup.
*/
static void __exit line6_exit(void)
{
	destroy_workqueue(line6_workqueue);
	usb_deregister(&line6_driver);
}

module_init(line6_init);
module_exit(line6_exit);

MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL");
MODULE_VERSION(DRIVER_VERSION);
