diff options
Diffstat (limited to 'drivers/staging/line6/driver.c')
| -rw-r--r-- | drivers/staging/line6/driver.c | 374 | 
1 files changed, 103 insertions, 271 deletions
diff --git a/drivers/staging/line6/driver.c b/drivers/staging/line6/driver.c index ea9209d9ceb..ef511c76a6e 100644 --- a/drivers/staging/line6/driver.c +++ b/drivers/staging/line6/driver.c @@ -16,11 +16,11 @@  #include "audio.h"  #include "capture.h" -#include "control.h"  #include "driver.h"  #include "midi.h"  #include "playback.h"  #include "pod.h" +#include "podhd.h"  #include "revision.h"  #include "toneport.h"  #include "usbdefs.h" @@ -37,6 +37,9 @@ static const struct usb_device_id line6_id_table[] = {  	{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_PODHD300)}, +	{USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_PODHD400)}, +	{USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_PODHD500)},  	{USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_PODSTUDIO_GX)},  	{USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_PODSTUDIO_UX1)},  	{USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_PODSTUDIO_UX2)}, @@ -54,25 +57,32 @@ static const struct usb_device_id line6_id_table[] = {  MODULE_DEVICE_TABLE(usb, line6_id_table); +#define L6PROP(dev_bit, dev_id, dev_name, dev_cap)\ +	{.device_bit = LINE6_BIT_##dev_bit, .id = dev_id,\ +	 .name = dev_name, .capabilities = LINE6_BIT_##dev_cap} +  /* *INDENT-OFF* */ -static struct line6_properties line6_properties_table[] = { -	{ "BassPODxt",     "BassPODxt",        LINE6_BIT_BASSPODXT,     LINE6_BIT_CONTROL_PCM_HWMON }, -	{ "BassPODxtLive", "BassPODxt Live",   LINE6_BIT_BASSPODXTLIVE, LINE6_BIT_CONTROL_PCM_HWMON }, -	{ "BassPODxtPro",  "BassPODxt Pro",    LINE6_BIT_BASSPODXTPRO,  LINE6_BIT_CONTROL_PCM_HWMON }, -	{ "GuitarPort",    "GuitarPort",       LINE6_BIT_GUITARPORT,    LINE6_BIT_PCM               }, -	{ "PocketPOD",     "Pocket POD",       LINE6_BIT_POCKETPOD,     LINE6_BIT_CONTROL           }, -	{ "PODStudioGX",   "POD Studio GX",    LINE6_BIT_PODSTUDIO_GX,  LINE6_BIT_PCM               }, -	{ "PODStudioUX1",  "POD Studio UX1",   LINE6_BIT_PODSTUDIO_UX1, LINE6_BIT_PCM               }, -	{ "PODStudioUX2",  "POD Studio UX2",   LINE6_BIT_PODSTUDIO_UX2, LINE6_BIT_PCM               }, -	{ "PODX3",         "POD X3",           LINE6_BIT_PODX3,         LINE6_BIT_PCM               }, -	{ "PODX3Live",     "POD X3 Live",      LINE6_BIT_PODX3LIVE,     LINE6_BIT_PCM               }, -	{ "PODxt",         "PODxt",            LINE6_BIT_PODXT,         LINE6_BIT_CONTROL_PCM_HWMON }, -	{ "PODxtLive",     "PODxt Live",       LINE6_BIT_PODXTLIVE,     LINE6_BIT_CONTROL_PCM_HWMON }, -	{ "PODxtPro",      "PODxt Pro",        LINE6_BIT_PODXTPRO,      LINE6_BIT_CONTROL_PCM_HWMON }, -	{ "TonePortGX",    "TonePort GX",      LINE6_BIT_TONEPORT_GX,   LINE6_BIT_PCM               }, -	{ "TonePortUX1",   "TonePort UX1",     LINE6_BIT_TONEPORT_UX1,  LINE6_BIT_PCM               }, -	{ "TonePortUX2",   "TonePort UX2",     LINE6_BIT_TONEPORT_UX2,  LINE6_BIT_PCM               }, -	{ "Variax",        "Variax Workbench", LINE6_BIT_VARIAX,        LINE6_BIT_CONTROL           } +static const struct line6_properties line6_properties_table[] = { +	L6PROP(BASSPODXT,     "BassPODxt",     "BassPODxt",        CTRL_PCM_HW), +	L6PROP(BASSPODXTLIVE, "BassPODxtLive", "BassPODxt Live",   CTRL_PCM_HW), +	L6PROP(BASSPODXTPRO,  "BassPODxtPro",  "BassPODxt Pro",    CTRL_PCM_HW), +	L6PROP(GUITARPORT,    "GuitarPort",    "GuitarPort",       PCM), +	L6PROP(POCKETPOD,     "PocketPOD",     "Pocket POD",       CONTROL), +	L6PROP(PODHD300,      "PODHD300",      "POD HD300",        CTRL_PCM_HW), +	L6PROP(PODHD400,      "PODHD400",      "POD HD400",        CTRL_PCM_HW), +	L6PROP(PODHD500,      "PODHD500",      "POD HD500",        CTRL_PCM_HW), +	L6PROP(PODSTUDIO_GX,  "PODStudioGX",   "POD Studio GX",    PCM), +	L6PROP(PODSTUDIO_UX1, "PODStudioUX1",  "POD Studio UX1",   PCM), +	L6PROP(PODSTUDIO_UX2, "PODStudioUX2",  "POD Studio UX2",   PCM), +	L6PROP(PODX3,         "PODX3",         "POD X3",           PCM), +	L6PROP(PODX3LIVE,     "PODX3Live",     "POD X3 Live",      PCM), +	L6PROP(PODXT,         "PODxt",         "PODxt",            CTRL_PCM_HW), +	L6PROP(PODXTLIVE,     "PODxtLive",     "PODxt Live",       CTRL_PCM_HW), +	L6PROP(PODXTPRO,      "PODxtPro",      "PODxt Pro",        CTRL_PCM_HW), +	L6PROP(TONEPORT_GX,   "TonePortGX",    "TonePort GX",      PCM), +	L6PROP(TONEPORT_UX1,  "TonePortUX1",   "TonePort UX1",     PCM), +	L6PROP(TONEPORT_UX2,  "TonePortUX2",   "TonePort UX2",     PCM), +	L6PROP(VARIAX,        "Variax",        "Variax Workbench", CONTROL),  };  /* *INDENT-ON* */ @@ -87,17 +97,10 @@ const unsigned char line6_midi_id[] = {  	Code to request version of POD, Variax interface  	(and maybe other devices).  */ -static const char line6_request_version0[] = { +static const char line6_request_version[] = {  	0xf0, 0x7e, 0x7f, 0x06, 0x01, 0xf7  }; -/* -	Copy of version request code with GFP_KERNEL flag for use in URB. -*/ -static const char *line6_request_version; - -struct usb_line6 *line6_devices[LINE6_MAX_DEVICES]; -  /**  	 Class for asynchronous messages.  */ @@ -121,6 +124,7 @@ static int line6_send_raw_message_async_part(struct message *msg,  static int line6_start_listen(struct usb_line6 *line6)  {  	int err; +  	usb_fill_int_urb(line6->urb_listen, line6->usbdev,  			 usb_rcvintpipe(line6->usbdev, line6->ep_control_read),  			 line6->buffer_listen, LINE6_BUFSIZE_LISTEN, @@ -138,63 +142,6 @@ static void line6_stop_listen(struct usb_line6 *line6)  	usb_kill_urb(line6->urb_listen);  } -#ifdef CONFIG_LINE6_USB_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 - -#ifdef CONFIG_LINE6_USB_DUMP_CTRL -/* -	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 wMaxPacketSize bytes.  */ @@ -203,10 +150,6 @@ int line6_send_raw_message(struct usb_line6 *line6, const char *buffer,  {  	int i, done = 0; -#ifdef CONFIG_LINE6_USB_DUMP_CTRL -	line6_write_hexdump(line6, 'S', buffer, size); -#endif -  	for (i = 0; i < size; i += line6->max_packet_size) {  		int partial;  		const char *frag_buf = buffer + i; @@ -214,10 +157,10 @@ int line6_send_raw_message(struct usb_line6 *line6, const char *buffer,  		int retval;  		retval = usb_interrupt_msg(line6->usbdev, -					   usb_sndintpipe(line6->usbdev, -							  line6->ep_control_write), -					   (char *)frag_buf, frag_size, -					   &partial, LINE6_TIMEOUT * HZ); +					usb_sndintpipe(line6->usbdev, +						line6->ep_control_write), +					(char *)frag_buf, frag_size, +					&partial, LINE6_TIMEOUT * HZ);  		if (retval) {  			dev_err(line6->ifcdev, @@ -261,10 +204,6 @@ static int line6_send_raw_message_async_part(struct message *msg,  			 (char *)msg->buffer + done, bytes,  			 line6_async_request_sent, msg, line6->interval); -#ifdef CONFIG_LINE6_USB_DUMP_CTRL -	line6_write_hexdump(line6, 'S', (char *)msg->buffer + done, bytes); -#endif -  	msg->done += bytes;  	retval = usb_submit_urb(urb, GFP_ATOMIC); @@ -273,7 +212,7 @@ static int line6_send_raw_message_async_part(struct message *msg,  			__func__, retval);  		usb_free_urb(urb);  		kfree(msg); -		return -EINVAL; +		return retval;  	}  	return 0; @@ -283,7 +222,7 @@ static int line6_send_raw_message_async_part(struct message *msg,  	Setup and start timer.  */  void line6_start_timer(struct timer_list *timer, unsigned int msecs, -		       void (*function) (unsigned long), unsigned long data) +		       void (*function)(unsigned long), unsigned long data)  {  	setup_timer(timer, function, data);  	timer->expires = jiffies + msecs * HZ / 1000; @@ -301,11 +240,8 @@ int line6_send_raw_message_async(struct usb_line6 *line6, const char *buffer,  	/* create message: */  	msg = kmalloc(sizeof(struct message), GFP_ATOMIC); - -	if (msg == NULL) { -		dev_err(line6->ifcdev, "Out of memory\n"); +	if (msg == NULL)  		return -ENOMEM; -	}  	/* create URB: */  	urb = usb_alloc_urb(0, GFP_ATOMIC); @@ -331,8 +267,20 @@ int line6_send_raw_message_async(struct usb_line6 *line6, const char *buffer,  */  int line6_version_request_async(struct usb_line6 *line6)  { -	return line6_send_raw_message_async(line6, line6_request_version, -					    sizeof(line6_request_version0)); +	char *buffer; +	int retval; + +	buffer = kmemdup(line6_request_version, +			sizeof(line6_request_version), GFP_ATOMIC); +	if (buffer == NULL) { +		dev_err(line6->ifcdev, "Out of memory"); +		return -ENOMEM; +	} + +	retval = line6_send_raw_message_async(line6, buffer, +					      sizeof(line6_request_version)); +	kfree(buffer); +	return retval;  }  /* @@ -347,17 +295,6 @@ int line6_send_sysex_message(struct usb_line6 *line6, const char *buffer,  }  /* -	Send sysex message in pieces of wMaxPacketSize bytes. -*/ -int line6_send_sysex_message_async(struct usb_line6 *line6, const char *buffer, -				   int size) -{ -	return line6_send_raw_message_async(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 @@ -367,10 +304,8 @@ char *line6_alloc_sysex_buffer(struct usb_line6 *line6, int code1, int code2,  {  	char *buffer = kmalloc(size + SYSEX_EXTRA_SIZE, GFP_ATOMIC); -	if (!buffer) { -		dev_err(line6->ifcdev, "out of memory\n"); +	if (!buffer)  		return NULL; -	}  	buffer[0] = LINE6_SYSEX_BEGIN;  	memcpy(buffer + 1, line6_midi_id, sizeof(line6_midi_id)); @@ -386,25 +321,19 @@ char *line6_alloc_sysex_buffer(struct usb_line6 *line6, int code1, int code2,  static void line6_data_received(struct urb *urb)  {  	struct usb_line6 *line6 = (struct usb_line6 *)urb->context; -	struct MidiBuffer *mb = &line6->line6midi->midibuf_in; +	struct midi_buffer *mb = &line6->line6midi->midibuf_in;  	int done;  	if (urb->status == -ESHUTDOWN)  		return; -#ifdef CONFIG_LINE6_USB_DUMP_CTRL -	line6_dump_urb(urb); -#endif -  	done =  	    line6_midibuf_write(mb, urb->transfer_buffer, urb->actual_length);  	if (done < urb->actual_length) {  		line6_midibuf_ignore(mb, done); -		DEBUG_MESSAGES(dev_err -			       (line6->ifcdev, -				"%d %d buffer overflow - message skipped\n", -				done, urb->actual_length)); +		dev_dbg(line6->ifcdev, "%d %d buffer overflow - message skipped\n", +			done, urb->actual_length);  	}  	for (;;) { @@ -415,18 +344,10 @@ static void line6_data_received(struct urb *urb)  		if (done == 0)  			break; -		/* MIDI input filter */ -		if (line6_midibuf_skip_message -		    (mb, line6->line6midi->midi_mask_receive)) -			continue; -  		line6->message_length = done; -#ifdef CONFIG_LINE6_USB_DUMP_MIDI -		line6_write_hexdump(line6, 'r', line6->buffer_message, done); -#endif  		line6_midi_receive(line6, line6->buffer_message, done); -		switch (line6->usbdev->descriptor.idProduct) { +		switch (le16_to_cpu(line6->usbdev->descriptor.idProduct)) {  		case LINE6_DEVID_BASSPODXT:  		case LINE6_DEVID_BASSPODXTLIVE:  		case LINE6_DEVID_BASSPODXTPRO: @@ -437,6 +358,11 @@ static void line6_data_received(struct urb *urb)  						  line6);  			break; +		case LINE6_DEVID_PODHD300: +		case LINE6_DEVID_PODHD400: +		case LINE6_DEVID_PODHD500: +			break; /* let userspace handle MIDI */ +  		case LINE6_DEVID_PODXTLIVE:  			switch (line6->interface_number) {  			case PODXTLIVE_INTERFACE_POD: @@ -473,26 +399,19 @@ static void line6_data_received(struct urb *urb)  /*  	Send channel number (i.e., switch to a different sound).  */ -int line6_send_program(struct usb_line6 *line6, int value) +int line6_send_program(struct usb_line6 *line6, u8 value)  {  	int retval;  	unsigned char *buffer;  	int partial;  	buffer = kmalloc(2, GFP_KERNEL); - -	if (!buffer) { -		dev_err(line6->ifcdev, "out of memory\n"); +	if (!buffer)  		return -ENOMEM; -	}  	buffer[0] = LINE6_PROGRAM_CHANGE | LINE6_CHANNEL_HOST;  	buffer[1] = value; -#ifdef CONFIG_LINE6_USB_DUMP_CTRL -	line6_write_hexdump(line6, 'S', buffer, 2); -#endif -  	retval = usb_interrupt_msg(line6->usbdev,  				   usb_sndintpipe(line6->usbdev,  						  line6->ep_control_write), @@ -509,27 +428,20 @@ int line6_send_program(struct usb_line6 *line6, int value)  /*  	Transmit Line6 control parameter.  */ -int line6_transmit_parameter(struct usb_line6 *line6, int param, int value) +int line6_transmit_parameter(struct usb_line6 *line6, int param, u8 value)  {  	int retval;  	unsigned char *buffer;  	int partial;  	buffer = kmalloc(3, GFP_KERNEL); - -	if (!buffer) { -		dev_err(line6->ifcdev, "out of memory\n"); +	if (!buffer)  		return -ENOMEM; -	}  	buffer[0] = LINE6_PARAM_CHANGE | LINE6_CHANNEL_HOST;  	buffer[1] = param;  	buffer[2] = value; -#ifdef CONFIG_LINE6_USB_DUMP_CTRL -	line6_write_hexdump(line6, 'S', buffer, 3); -#endif -  	retval = usb_interrupt_msg(line6->usbdev,  				   usb_sndintpipe(line6->usbdev,  						  line6->ep_control_write), @@ -564,7 +476,7 @@ int line6_read_data(struct usb_line6 *line6, int address, void *data,  		return ret;  	} -	/* Wait for data length. We'll get a couple of 0xff until length arrives. */ +	/* Wait for data length. We'll get 0xff until length arrives. */  	do {  		ret = usb_control_msg(usbdev, usb_rcvctrlpipe(usbdev, 0), 0x67,  				      USB_TYPE_VENDOR | USB_RECIP_DEVICE | @@ -664,29 +576,6 @@ ssize_t line6_nop_read(struct device *dev, struct device_attribute *attr,  }  /* -	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. -*/ -#ifdef CONFIG_LINE6_USB_RAW -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) @@ -720,10 +609,9 @@ 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; +	struct usb_device *usbdev; +	struct usb_line6 *line6;  	const struct line6_properties *properties; -	int devnum;  	int interface_number, alternate = 0;  	int product;  	int size = 0; @@ -757,16 +645,6 @@ static int line6_probe(struct usb_interface *interface,  		goto err_put;  	} -	/* 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) { -		ret = -ENODEV; -		goto err_put; -	} -  	/* initialize device info: */  	properties = &line6_properties_table[devtype];  	dev_info(&interface->dev, "Line6 %s found\n", properties->name); @@ -794,6 +672,7 @@ static int line6_probe(struct usb_interface *interface,  		}  		break; +	case LINE6_DEVID_PODHD500:  	case LINE6_DEVID_PODX3:  	case LINE6_DEVID_PODX3LIVE:  		switch (interface_number) { @@ -812,6 +691,8 @@ static int line6_probe(struct usb_interface *interface,  	case LINE6_DEVID_BASSPODXTPRO:  	case LINE6_DEVID_PODXT:  	case LINE6_DEVID_PODXTPRO: +	case LINE6_DEVID_PODHD300: +	case LINE6_DEVID_PODHD400:  		alternate = 5;  		break; @@ -865,6 +746,19 @@ static int line6_probe(struct usb_interface *interface,  		ep_write = 0x03;  		break; +	case LINE6_DEVID_PODHD300: +	case LINE6_DEVID_PODHD400: +		size = sizeof(struct usb_line6_podhd); +		ep_read = 0x84; +		ep_write = 0x03; +		break; + +	case LINE6_DEVID_PODHD500: +		size = sizeof(struct usb_line6_podhd); +		ep_read = 0x81; +		ep_write = 0x01; +		break; +  	case LINE6_DEVID_POCKETPOD:  		size = sizeof(struct usb_line6_pod);  		ep_read = 0x82; @@ -923,16 +817,14 @@ static int line6_probe(struct usb_interface *interface,  	}  	if (size == 0) { -		dev_err(line6->ifcdev, +		dev_err(&interface->dev,  			"driver bug: interface data size not set\n");  		ret = -ENODEV;  		goto err_put;  	}  	line6 = kzalloc(size, GFP_KERNEL); -  	if (line6 == NULL) { -		dev_err(&interface->dev, "Out of memory\n");  		ret = -ENODEV;  		goto err_put;  	} @@ -971,18 +863,14 @@ static int line6_probe(struct usb_interface *interface,  		/* 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");  			ret = -ENOMEM;  			goto err_destruct;  		}  		line6->buffer_message =  		    kmalloc(LINE6_MESSAGE_MAXLEN, GFP_KERNEL); -  		if (line6->buffer_message == NULL) { -			dev_err(&interface->dev, "Out of memory\n");  			ret = -ENOMEM;  			goto err_destruct;  		} @@ -1017,6 +905,13 @@ static int line6_probe(struct usb_interface *interface,  		ret = line6_pod_init(interface, (struct usb_line6_pod *)line6);  		break; +	case LINE6_DEVID_PODHD300: +	case LINE6_DEVID_PODHD400: +	case LINE6_DEVID_PODHD500: +		ret = line6_podhd_init(interface, +				       (struct usb_line6_podhd *)line6); +		break; +  	case LINE6_DEVID_PODXTLIVE:  		switch (interface_number) {  		case PODXTLIVE_INTERFACE_POD: @@ -1075,7 +970,6 @@ static int line6_probe(struct usb_interface *interface,  	dev_info(&interface->dev, "Line6 %s now attached\n",  		 line6->properties->name); -	line6_devices[devnum] = line6;  	switch (product) {  	case LINE6_DEVID_PODX3: @@ -1094,8 +988,6 @@ static int line6_probe(struct usb_interface *interface,  err_destruct:  	line6_destruct(interface);  err_put: -	usb_put_intf(interface); -	usb_put_dev(usbdev);  	return ret;  } @@ -1106,7 +998,7 @@ static void line6_disconnect(struct usb_interface *interface)  {  	struct usb_line6 *line6;  	struct usb_device *usbdev; -	int interface_number, i; +	int interface_number;  	if (interface == NULL)  		return; @@ -1129,7 +1021,7 @@ static void line6_disconnect(struct usb_interface *interface)  			dev_err(line6->ifcdev,  				"driver bug: inconsistent usb device\n"); -		switch (line6->usbdev->descriptor.idProduct) { +		switch (le16_to_cpu(line6->usbdev->descriptor.idProduct)) {  		case LINE6_DEVID_BASSPODXT:  		case LINE6_DEVID_BASSPODXTLIVE:  		case LINE6_DEVID_BASSPODXTPRO: @@ -1141,6 +1033,12 @@ static void line6_disconnect(struct usb_interface *interface)  			line6_pod_disconnect(interface);  			break; +		case LINE6_DEVID_PODHD300: +		case LINE6_DEVID_PODHD400: +		case LINE6_DEVID_PODHD500: +			line6_podhd_disconnect(interface); +			break; +  		case LINE6_DEVID_PODXTLIVE:  			switch (interface_number) {  			case PODXTLIVE_INTERFACE_POD: @@ -1174,10 +1072,6 @@ static void line6_disconnect(struct usb_interface *interface)  		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); @@ -1232,7 +1126,7 @@ static int line6_reset_resume(struct usb_interface *interface)  {  	struct usb_line6 *line6 = usb_get_intfdata(interface); -	switch (line6->usbdev->descriptor.idProduct) { +	switch (le16_to_cpu(line6->usbdev->descriptor.idProduct)) {  	case LINE6_DEVID_PODSTUDIO_GX:  	case LINE6_DEVID_PODSTUDIO_UX1:  	case LINE6_DEVID_PODSTUDIO_UX2: @@ -1260,69 +1154,7 @@ static struct usb_driver line6_driver = {  	.id_table = line6_id_table,  }; -/* -	Module initialization. -*/ -static int __init line6_init(void) -{ -	int i, retval; - -	printk(KERN_INFO "%s driver version %s\n", DRIVER_NAME, DRIVER_VERSION); - -	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; -	} - -	line6_request_version = kmalloc(sizeof(line6_request_version0), -					GFP_KERNEL); - -	if (line6_request_version == NULL) { -		err("Out of memory"); -		return -ENOMEM; -	} - -	memcpy((char *)line6_request_version, line6_request_version0, -	       sizeof(line6_request_version0)); - -	return retval; -} - -/* -	Module cleanup. -*/ -static void __exit line6_exit(void) -{ -	int i; -	struct usb_line6 *line6; -	struct snd_line6_pcm *line6pcm; - -	/* stop all PCM channels */ -	for (i = LINE6_MAX_DEVICES; i--;) { -		line6 = line6_devices[i]; - -		if (line6 == NULL) -			continue; - -		line6pcm = line6->line6pcm; - -		if (line6pcm == NULL) -			continue; - -		line6_pcm_stop(line6pcm, ~0); -	} - -	usb_deregister(&line6_driver); -	kfree(line6_request_version); -} - -module_init(line6_init); -module_exit(line6_exit); +module_usb_driver(line6_driver);  MODULE_AUTHOR(DRIVER_AUTHOR);  MODULE_DESCRIPTION(DRIVER_DESC);  | 
