From 61864d844c296933d40c02683252bbea5193b101 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 12 Jan 2015 22:29:57 +0100 Subject: ALSA: move line6 usb driver into sound/usb Promote line6 driver from staging to sound/usb/line6 directory, and maintain through sound subsystem tree. This commit just moves the code and adapts Makefile / Kconfig. The further renames and misc cleanups will follow. Signed-off-by: Takashi Iwai --- sound/usb/line6/driver.c | 1114 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1114 insertions(+) create mode 100644 sound/usb/line6/driver.c (limited to 'sound/usb/line6/driver.c') diff --git a/sound/usb/line6/driver.c b/sound/usb/line6/driver.c new file mode 100644 index 000000000000..fc852f6ab8bc --- /dev/null +++ b/sound/usb/line6/driver.c @@ -0,0 +1,1114 @@ +/* + * Line6 Linux USB driver - 0.9.1beta + * + * Copyright (C) 2004-2010 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 +#include +#include +#include + +#include "audio.h" +#include "capture.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" +#include "variax.h" + +#define DRIVER_AUTHOR "Markus Grabner " +#define DRIVER_DESC "Line6 USB Driver" +#define DRIVER_VERSION "0.9.1beta" DRIVER_REVISION + +#define LINE6_DEVICE(prod) USB_DEVICE(0x0e41, prod) +#define LINE6_IF_NUM(prod, n) USB_DEVICE_INTERFACE_NUMBER(0x0e41, prod, n) + +/* table of devices that work with this driver */ +static const struct usb_device_id line6_id_table[] = { + { LINE6_DEVICE(0x4250), .driver_info = LINE6_BASSPODXT }, + { LINE6_DEVICE(0x4642), .driver_info = LINE6_BASSPODXTLIVE }, + { LINE6_DEVICE(0x4252), .driver_info = LINE6_BASSPODXTPRO }, + { LINE6_DEVICE(0x4750), .driver_info = LINE6_GUITARPORT }, + { LINE6_IF_NUM(0x5051, 1), .driver_info = LINE6_POCKETPOD }, + { LINE6_DEVICE(0x5057), .driver_info = LINE6_PODHD300 }, + { LINE6_DEVICE(0x5058), .driver_info = LINE6_PODHD400 }, + { LINE6_IF_NUM(0x414D, 0), .driver_info = LINE6_PODHD500_0 }, + { LINE6_IF_NUM(0x414D, 1), .driver_info = LINE6_PODHD500_1 }, + { LINE6_DEVICE(0x4153), .driver_info = LINE6_PODSTUDIO_GX }, + { LINE6_DEVICE(0x4150), .driver_info = LINE6_PODSTUDIO_UX1 }, + { LINE6_IF_NUM(0x4151, 0), .driver_info = LINE6_PODSTUDIO_UX2 }, + { LINE6_DEVICE(0x5044), .driver_info = LINE6_PODXT }, + { LINE6_IF_NUM(0x4650, 0), .driver_info = LINE6_PODXTLIVE_POD }, + { LINE6_IF_NUM(0x4650, 1), .driver_info = LINE6_PODXTLIVE_VARIAX }, + { LINE6_DEVICE(0x5050), .driver_info = LINE6_PODXTPRO }, + { LINE6_DEVICE(0x4147), .driver_info = LINE6_TONEPORT_GX }, + { LINE6_DEVICE(0x4141), .driver_info = LINE6_TONEPORT_UX1 }, + { LINE6_IF_NUM(0x4142, 0), .driver_info = LINE6_TONEPORT_UX2 }, + { LINE6_DEVICE(0x534d), .driver_info = LINE6_VARIAX }, + {} +}; + +MODULE_DEVICE_TABLE(usb, line6_id_table); + +static const struct line6_properties line6_properties_table[] = { + [LINE6_BASSPODXT] = { + .id = "BassPODxt", + .name = "BassPODxt", + .capabilities = LINE6_CAP_CONTROL + | LINE6_CAP_PCM + | LINE6_CAP_HWMON, + .altsetting = 5, + .ep_ctrl_r = 0x84, + .ep_ctrl_w = 0x03, + .ep_audio_r = 0x82, + .ep_audio_w = 0x01, + }, + [LINE6_BASSPODXTLIVE] = { + .id = "BassPODxtLive", + .name = "BassPODxt Live", + .capabilities = LINE6_CAP_CONTROL + | LINE6_CAP_PCM + | LINE6_CAP_HWMON, + .altsetting = 1, + .ep_ctrl_r = 0x84, + .ep_ctrl_w = 0x03, + .ep_audio_r = 0x82, + .ep_audio_w = 0x01, + }, + [LINE6_BASSPODXTPRO] = { + .id = "BassPODxtPro", + .name = "BassPODxt Pro", + .capabilities = LINE6_CAP_CONTROL + | LINE6_CAP_PCM + | LINE6_CAP_HWMON, + .altsetting = 5, + .ep_ctrl_r = 0x84, + .ep_ctrl_w = 0x03, + .ep_audio_r = 0x82, + .ep_audio_w = 0x01, + }, + [LINE6_GUITARPORT] = { + .id = "GuitarPort", + .name = "GuitarPort", + .capabilities = LINE6_CAP_PCM, + .altsetting = 2, /* 1..4 seem to be ok */ + /* no control channel */ + .ep_audio_r = 0x82, + .ep_audio_w = 0x01, + }, + [LINE6_POCKETPOD] = { + .id = "PocketPOD", + .name = "Pocket POD", + .capabilities = LINE6_CAP_CONTROL, + .altsetting = 0, + .ep_ctrl_r = 0x82, + .ep_ctrl_w = 0x02, + /* no audio channel */ + }, + [LINE6_PODHD300] = { + .id = "PODHD300", + .name = "POD HD300", + .capabilities = LINE6_CAP_CONTROL + | LINE6_CAP_PCM + | LINE6_CAP_HWMON, + .altsetting = 5, + .ep_ctrl_r = 0x84, + .ep_ctrl_w = 0x03, + .ep_audio_r = 0x82, + .ep_audio_w = 0x01, + }, + [LINE6_PODHD400] = { + .id = "PODHD400", + .name = "POD HD400", + .capabilities = LINE6_CAP_CONTROL + | LINE6_CAP_PCM + | LINE6_CAP_HWMON, + .altsetting = 5, + .ep_ctrl_r = 0x84, + .ep_ctrl_w = 0x03, + .ep_audio_r = 0x82, + .ep_audio_w = 0x01, + }, + [LINE6_PODHD500_0] = { + .id = "PODHD500", + .name = "POD HD500", + .capabilities = LINE6_CAP_CONTROL + | LINE6_CAP_PCM + | LINE6_CAP_HWMON, + .altsetting = 1, + .ep_ctrl_r = 0x81, + .ep_ctrl_w = 0x01, + .ep_audio_r = 0x86, + .ep_audio_w = 0x02, + }, + [LINE6_PODHD500_1] = { + .id = "PODHD500", + .name = "POD HD500", + .capabilities = LINE6_CAP_CONTROL + | LINE6_CAP_PCM + | LINE6_CAP_HWMON, + .altsetting = 1, + .ep_ctrl_r = 0x81, + .ep_ctrl_w = 0x01, + .ep_audio_r = 0x86, + .ep_audio_w = 0x02, + }, + [LINE6_PODSTUDIO_GX] = { + .id = "PODStudioGX", + .name = "POD Studio GX", + .capabilities = LINE6_CAP_PCM, + .altsetting = 2, /* 1..4 seem to be ok */ + /* no control channel */ + .ep_audio_r = 0x82, + .ep_audio_w = 0x01, + }, + [LINE6_PODSTUDIO_UX1] = { + .id = "PODStudioUX1", + .name = "POD Studio UX1", + .capabilities = LINE6_CAP_PCM, + .altsetting = 2, /* 1..4 seem to be ok */ + /* no control channel */ + .ep_audio_r = 0x82, + .ep_audio_w = 0x01, + }, + [LINE6_PODSTUDIO_UX2] = { + .id = "PODStudioUX2", + .name = "POD Studio UX2", + .capabilities = LINE6_CAP_PCM, + .altsetting = 2, /* defaults to 44.1kHz, 16-bit */ + /* no control channel */ + .ep_audio_r = 0x82, + .ep_audio_w = 0x01, + }, + [LINE6_PODXT] = { + .id = "PODxt", + .name = "PODxt", + .capabilities = LINE6_CAP_CONTROL + | LINE6_CAP_PCM + | LINE6_CAP_HWMON, + .altsetting = 5, + .ep_ctrl_r = 0x84, + .ep_ctrl_w = 0x03, + .ep_audio_r = 0x82, + .ep_audio_w = 0x01, + }, + [LINE6_PODXTLIVE_POD] = { + .id = "PODxtLive", + .name = "PODxt Live", + .capabilities = LINE6_CAP_CONTROL + | LINE6_CAP_PCM + | LINE6_CAP_HWMON, + .altsetting = 1, + .ep_ctrl_r = 0x84, + .ep_ctrl_w = 0x03, + .ep_audio_r = 0x82, + .ep_audio_w = 0x01, + }, + [LINE6_PODXTLIVE_VARIAX] = { + .id = "PODxtLive", + .name = "PODxt Live", + .capabilities = LINE6_CAP_CONTROL + | LINE6_CAP_PCM + | LINE6_CAP_HWMON, + .altsetting = 1, + .ep_ctrl_r = 0x86, + .ep_ctrl_w = 0x05, + .ep_audio_r = 0x82, + .ep_audio_w = 0x01, + }, + [LINE6_PODXTPRO] = { + .id = "PODxtPro", + .name = "PODxt Pro", + .capabilities = LINE6_CAP_CONTROL + | LINE6_CAP_PCM + | LINE6_CAP_HWMON, + .altsetting = 5, + .ep_ctrl_r = 0x84, + .ep_ctrl_w = 0x03, + .ep_audio_r = 0x82, + .ep_audio_w = 0x01, + }, + [LINE6_TONEPORT_GX] = { + .id = "TonePortGX", + .name = "TonePort GX", + .capabilities = LINE6_CAP_PCM, + .altsetting = 2, /* 1..4 seem to be ok */ + /* no control channel */ + .ep_audio_r = 0x82, + .ep_audio_w = 0x01, + }, + [LINE6_TONEPORT_UX1] = { + .id = "TonePortUX1", + .name = "TonePort UX1", + .capabilities = LINE6_CAP_PCM, + .altsetting = 2, /* 1..4 seem to be ok */ + /* no control channel */ + .ep_audio_r = 0x82, + .ep_audio_w = 0x01, + }, + [LINE6_TONEPORT_UX2] = { + .id = "TonePortUX2", + .name = "TonePort UX2", + .capabilities = LINE6_CAP_PCM, + .altsetting = 2, /* defaults to 44.1kHz, 16-bit */ + /* no control channel */ + .ep_audio_r = 0x82, + .ep_audio_w = 0x01, + }, + [LINE6_VARIAX] = { + .id = "Variax", + .name = "Variax Workbench", + .capabilities = LINE6_CAP_CONTROL, + .altsetting = 1, + .ep_ctrl_r = 0x82, + .ep_ctrl_w = 0x01, + /* no audio channel */ + } +}; + +/* + This is Line6's MIDI manufacturer ID. +*/ +const unsigned char line6_midi_id[] = { + 0x00, 0x01, 0x0c +}; + +/* + Code to request version of POD, Variax interface + (and maybe other devices). +*/ +static const char line6_request_version[] = { + 0xf0, 0x7e, 0x7f, 0x06, 0x01, 0xf7 +}; + +/** + 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) +{ + int err; + + usb_fill_int_urb(line6->urb_listen, line6->usbdev, + usb_rcvintpipe(line6->usbdev, line6->properties->ep_ctrl_r), + line6->buffer_listen, LINE6_BUFSIZE_LISTEN, + line6_data_received, line6, line6->interval); + line6->urb_listen->actual_length = 0; + err = usb_submit_urb(line6->urb_listen, GFP_ATOMIC); + return err; +} + +/* + Stop listening on endpoint. +*/ +static void line6_stop_listen(struct usb_line6 *line6) +{ + usb_kill_urb(line6->urb_listen); +} + +/* + Send raw message in pieces of wMaxPacketSize bytes. +*/ +int line6_send_raw_message(struct usb_line6 *line6, const char *buffer, + int size) +{ + int i, done = 0; + + for (i = 0; i < size; i += line6->max_packet_size) { + int partial; + 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->properties->ep_ctrl_w), + (char *)frag_buf, frag_size, + &partial, LINE6_TIMEOUT * HZ); + + if (retval) { + dev_err(line6->ifcdev, + "usb_interrupt_msg failed (%d)\n", retval); + break; + } + + done += frag_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->properties->ep_ctrl_w), + (char *)msg->buffer + done, bytes, + line6_async_request_sent, msg, line6->interval); + + 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 retval; + } + + return 0; +} + +/* + Setup and start timer. +*/ +void line6_start_timer(struct timer_list *timer, unsigned int msecs, + void (*function)(unsigned long), unsigned long data) +{ + setup_timer(timer, function, data); + timer->expires = jiffies + msecs * HZ / 1000; + add_timer(timer); +} + +/* + 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) + 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 asynchronous device version request. +*/ +int line6_version_request_async(struct usb_line6 *line6) +{ + 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; +} + +/* + 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_ATOMIC); + + if (!buffer) + 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 midi_buffer *mb = &line6->line6midi->midibuf_in; + int done; + + if (urb->status == -ESHUTDOWN) + return; + + done = + line6_midibuf_write(mb, urb->transfer_buffer, urb->actual_length); + + if (done < urb->actual_length) { + line6_midibuf_ignore(mb, done); + dev_dbg(line6->ifcdev, "%d %d buffer overflow - message skipped\n", + done, urb->actual_length); + } + + for (;;) { + done = + line6_midibuf_read(mb, line6->buffer_message, + LINE6_MESSAGE_MAXLEN); + + if (done == 0) + break; + + line6->message_length = done; + line6_midi_receive(line6, line6->buffer_message, done); + + if (line6->process_message) + line6->process_message(line6); + } + + line6_start_listen(line6); +} + +/* + Send channel number (i.e., switch to a different sound). +*/ +int line6_send_program(struct usb_line6 *line6, u8 value) +{ + int retval; + unsigned char *buffer; + int partial; + + buffer = kmalloc(2, GFP_KERNEL); + if (!buffer) + return -ENOMEM; + + buffer[0] = LINE6_PROGRAM_CHANGE | LINE6_CHANNEL_HOST; + buffer[1] = value; + + retval = usb_interrupt_msg(line6->usbdev, + usb_sndintpipe(line6->usbdev, + line6->properties->ep_ctrl_w), + buffer, 2, &partial, LINE6_TIMEOUT * HZ); + + if (retval) + dev_err(line6->ifcdev, "usb_interrupt_msg failed (%d)\n", + retval); + + kfree(buffer); + return retval; +} + +/* + Transmit Line6 control parameter. +*/ +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) + return -ENOMEM; + + buffer[0] = LINE6_PARAM_CHANGE | LINE6_CHANNEL_HOST; + buffer[1] = param; + buffer[2] = value; + + retval = usb_interrupt_msg(line6->usbdev, + usb_sndintpipe(line6->usbdev, + line6->properties->ep_ctrl_w), + buffer, 3, &partial, LINE6_TIMEOUT * HZ); + + if (retval) + dev_err(line6->ifcdev, "usb_interrupt_msg failed (%d)\n", + retval); + + kfree(buffer); + return retval; +} + +/* + 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 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; +} + +/* + 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); +} + +/* + Probe USB device. +*/ +static int line6_probe(struct usb_interface *interface, + const struct usb_device_id *id) +{ + enum line6_device_type devtype; + struct usb_device *usbdev; + struct usb_line6 *line6; + const struct line6_properties *properties; + int interface_number; + int size = 0; + int ret; + + if (interface == NULL) + return -ENODEV; + usbdev = interface_to_usbdev(interface); + if (usbdev == NULL) + return -ENODEV; + + /* we don't handle multiple configurations */ + if (usbdev->descriptor.bNumConfigurations != 1) { + ret = -ENODEV; + goto err_put; + } + + devtype = id->driver_info; + + /* initialize device info: */ + properties = &line6_properties_table[devtype]; + dev_info(&interface->dev, "Line6 %s found\n", properties->name); + + /* query interface number */ + interface_number = interface->cur_altsetting->desc.bInterfaceNumber; + + ret = usb_set_interface(usbdev, interface_number, + properties->altsetting); + if (ret < 0) { + dev_err(&interface->dev, "set_interface failed\n"); + goto err_put; + } + + /* initialize device data based on device: */ + switch (devtype) { + case LINE6_BASSPODXT: + case LINE6_BASSPODXTLIVE: + case LINE6_BASSPODXTPRO: + case LINE6_PODXT: + case LINE6_PODXTPRO: + size = sizeof(struct usb_line6_pod); + break; + + case LINE6_PODHD300: + case LINE6_PODHD400: + size = sizeof(struct usb_line6_podhd); + break; + + case LINE6_PODHD500_0: + case LINE6_PODHD500_1: + size = sizeof(struct usb_line6_podhd); + break; + + case LINE6_POCKETPOD: + size = sizeof(struct usb_line6_pod); + break; + + case LINE6_PODSTUDIO_GX: + case LINE6_PODSTUDIO_UX1: + case LINE6_PODSTUDIO_UX2: + case LINE6_TONEPORT_GX: + case LINE6_TONEPORT_UX1: + case LINE6_TONEPORT_UX2: + case LINE6_GUITARPORT: + size = sizeof(struct usb_line6_toneport); + break; + + case LINE6_PODXTLIVE_POD: + size = sizeof(struct usb_line6_pod); + break; + + case LINE6_PODXTLIVE_VARIAX: + size = sizeof(struct usb_line6_variax); + break; + + case LINE6_VARIAX: + size = sizeof(struct usb_line6_variax); + break; + + default: + MISSING_CASE; + ret = -ENODEV; + goto err_put; + } + + if (size == 0) { + 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) { + ret = -ENODEV; + goto err_put; + } + + /* store basic data: */ + line6->properties = properties; + line6->usbdev = usbdev; + line6->ifcdev = &interface->dev; + line6->type = devtype; + + /* get data from endpoint descriptor (see usb_maxpacket): */ + { + struct usb_host_endpoint *ep; + unsigned pipe = usb_rcvintpipe(usbdev, properties->ep_ctrl_r); + unsigned epnum = usb_pipeendpoint(pipe); + 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_CAP_CONTROL) { + /* initialize USB buffers: */ + line6->buffer_listen = + kmalloc(LINE6_BUFSIZE_LISTEN, GFP_KERNEL); + if (line6->buffer_listen == NULL) { + ret = -ENOMEM; + goto err_destruct; + } + + line6->buffer_message = + kmalloc(LINE6_MESSAGE_MAXLEN, GFP_KERNEL); + if (line6->buffer_message == NULL) { + ret = -ENOMEM; + goto err_destruct; + } + + 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); + ret = -ENOMEM; + goto err_destruct; + } + + ret = line6_start_listen(line6); + if (ret < 0) { + dev_err(&interface->dev, "%s: usb_submit_urb failed\n", + __func__); + goto err_destruct; + } + } + + /* initialize device data based on device: */ + switch (devtype) { + case LINE6_BASSPODXT: + case LINE6_BASSPODXTLIVE: + case LINE6_BASSPODXTPRO: + case LINE6_POCKETPOD: + case LINE6_PODXT: + case LINE6_PODXTPRO: + ret = line6_pod_init(interface, line6); + break; + + case LINE6_PODHD300: + case LINE6_PODHD400: + case LINE6_PODHD500_0: + case LINE6_PODHD500_1: + ret = line6_podhd_init(interface, line6); + break; + + case LINE6_PODXTLIVE_POD: + ret = line6_pod_init(interface, line6); + break; + + case LINE6_PODXTLIVE_VARIAX: + ret = line6_variax_init(interface, line6); + break; + + case LINE6_VARIAX: + ret = line6_variax_init(interface, line6); + break; + + case LINE6_PODSTUDIO_GX: + case LINE6_PODSTUDIO_UX1: + case LINE6_PODSTUDIO_UX2: + case LINE6_TONEPORT_GX: + case LINE6_TONEPORT_UX1: + case LINE6_TONEPORT_UX2: + case LINE6_GUITARPORT: + ret = line6_toneport_init(interface, line6); + break; + + default: + MISSING_CASE; + ret = -ENODEV; + } + + if (ret < 0) + goto err_destruct; + + ret = sysfs_create_link(&interface->dev.kobj, &usbdev->dev.kobj, + "usb_device"); + if (ret < 0) + goto err_destruct; + + /* creation of additional special files should go here */ + + dev_info(&interface->dev, "Line6 %s now attached\n", + line6->properties->name); + + /* increment reference counters: */ + usb_get_intf(interface); + usb_get_dev(usbdev); + + return 0; + +err_destruct: + line6_destruct(interface); +err_put: + return ret; +} + +/* + Line6 device disconnected. +*/ +static void line6_disconnect(struct usb_interface *interface) +{ + struct usb_line6 *line6; + struct usb_device *usbdev; + int interface_number; + + if (interface == NULL) + return; + usbdev = interface_to_usbdev(interface); + if (usbdev == NULL) + return; + + /* removal of additional special files should go here */ + + 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) + line6_stop_listen(line6); + + if (usbdev != line6->usbdev) + dev_err(line6->ifcdev, + "driver bug: inconsistent usb device\n"); + + line6->disconnect(interface); + + dev_info(&interface->dev, "Line6 %s now disconnected\n", + line6->properties->name); + } + + line6_destruct(interface); + + /* decrement reference counters: */ + usb_put_intf(interface); + usb_put_dev(usbdev); +} + +#ifdef CONFIG_PM + +/* + Suspend Line6 device. +*/ +static int line6_suspend(struct usb_interface *interface, pm_message_t message) +{ + struct usb_line6 *line6 = usb_get_intfdata(interface); + struct snd_line6_pcm *line6pcm = line6->line6pcm; + + snd_power_change_state(line6->card, SNDRV_CTL_POWER_D3hot); + + if (line6->properties->capabilities & LINE6_CAP_CONTROL) + line6_stop_listen(line6); + + if (line6pcm != NULL) { + snd_pcm_suspend_all(line6pcm->pcm); + line6_pcm_disconnect(line6pcm); + line6pcm->flags = 0; + } + + return 0; +} + +/* + Resume Line6 device. +*/ +static int line6_resume(struct usb_interface *interface) +{ + struct usb_line6 *line6 = usb_get_intfdata(interface); + + if (line6->properties->capabilities & LINE6_CAP_CONTROL) + line6_start_listen(line6); + + snd_power_change_state(line6->card, SNDRV_CTL_POWER_D0); + return 0; +} + +/* + Resume Line6 device after reset. +*/ +static int line6_reset_resume(struct usb_interface *interface) +{ + struct usb_line6 *line6 = usb_get_intfdata(interface); + + switch (line6->type) { + case LINE6_PODSTUDIO_GX: + case LINE6_PODSTUDIO_UX1: + case LINE6_PODSTUDIO_UX2: + case LINE6_TONEPORT_GX: + case LINE6_TONEPORT_UX1: + case LINE6_TONEPORT_UX2: + case LINE6_GUITARPORT: + line6_toneport_reset_resume((struct usb_line6_toneport *)line6); + + default: + break; + } + + return line6_resume(interface); +} + +#endif /* CONFIG_PM */ + +static struct usb_driver line6_driver = { + .name = DRIVER_NAME, + .probe = line6_probe, + .disconnect = line6_disconnect, +#ifdef CONFIG_PM + .suspend = line6_suspend, + .resume = line6_resume, + .reset_resume = line6_reset_resume, +#endif + .id_table = line6_id_table, +}; + +module_usb_driver(line6_driver); + +MODULE_AUTHOR(DRIVER_AUTHOR); +MODULE_DESCRIPTION(DRIVER_DESC); +MODULE_LICENSE("GPL"); +MODULE_VERSION(DRIVER_VERSION); -- cgit v1.2.3 From 0f2524b347b1ce16ce6a34cb194445e25bc6ae42 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 19 Jan 2015 11:44:40 +0100 Subject: ALSA: line6: Use setup_timer() and mod_timer() No functional change, refactoring with the standard helpers. Signed-off-by: Takashi Iwai --- sound/usb/line6/driver.c | 3 +-- sound/usb/line6/toneport.c | 8 +++----- 2 files changed, 4 insertions(+), 7 deletions(-) (limited to 'sound/usb/line6/driver.c') diff --git a/sound/usb/line6/driver.c b/sound/usb/line6/driver.c index fc852f6ab8bc..19904d677114 100644 --- a/sound/usb/line6/driver.c +++ b/sound/usb/line6/driver.c @@ -415,8 +415,7 @@ void line6_start_timer(struct timer_list *timer, unsigned int msecs, void (*function)(unsigned long), unsigned long data) { setup_timer(timer, function, data); - timer->expires = jiffies + msecs * HZ / 1000; - add_timer(timer); + mod_timer(timer, jiffies + msecs * HZ / 1000); } /* diff --git a/sound/usb/line6/toneport.c b/sound/usb/line6/toneport.c index aae78d8a82d9..7f97f4a812a7 100644 --- a/sound/usb/line6/toneport.c +++ b/sound/usb/line6/toneport.c @@ -433,11 +433,9 @@ static int toneport_try_init(struct usb_interface *interface, toneport_setup(toneport); - init_timer(&toneport->timer); - toneport->timer.expires = jiffies + TONEPORT_PCM_DELAY * HZ; - toneport->timer.function = toneport_start_pcm; - toneport->timer.data = (unsigned long)toneport; - add_timer(&toneport->timer); + setup_timer(&toneport->timer, toneport_start_pcm, + (unsigned long)toneport); + mod_timer(&toneport->timer, jiffies + TONEPORT_PCM_DELAY * HZ); return 0; } -- cgit v1.2.3 From ccddbe4a99536154e61d16c0f1c2df8a6d63f52a Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 15 Jan 2015 08:22:31 +0100 Subject: ALSA: line6: Split to each driver Split to each individual driver for POD, PODHD, TonePort and Variax with a core LINE6 helper module. The new modules follow the standard ALSA naming rule with snd prefix: snd-usb-pod, snd-usb-podhd, snd-usb-toneport and snd-usb-variax, together with the corresponding CONFIG_SND_USB_* Kconfig items. Tested-by: Chris Rorvick Signed-off-by: Takashi Iwai --- sound/usb/Makefile | 2 +- sound/usb/line6/Kconfig | 36 ++-- sound/usb/line6/Makefile | 21 ++- sound/usb/line6/audio.c | 3 + sound/usb/line6/capture.c | 1 - sound/usb/line6/driver.c | 452 ++++----------------------------------------- sound/usb/line6/driver.h | 39 ++-- sound/usb/line6/midi.c | 3 +- sound/usb/line6/pcm.c | 6 +- sound/usb/line6/playback.c | 1 - sound/usb/line6/pod.c | 224 +++++++++++++++++++++- sound/usb/line6/pod.h | 92 --------- sound/usb/line6/podhd.c | 124 ++++++++++++- sound/usb/line6/podhd.h | 29 --- sound/usb/line6/toneport.c | 188 ++++++++++++++++++- sound/usb/line6/toneport.h | 51 ----- sound/usb/line6/variax.c | 133 ++++++++++++- sound/usb/line6/variax.h | 70 ------- 18 files changed, 748 insertions(+), 727 deletions(-) delete mode 100644 sound/usb/line6/pod.h delete mode 100644 sound/usb/line6/podhd.h delete mode 100644 sound/usb/line6/toneport.h delete mode 100644 sound/usb/line6/variax.h (limited to 'sound/usb/line6/driver.c') diff --git a/sound/usb/Makefile b/sound/usb/Makefile index 54045b745d11..2d2d122b069f 100644 --- a/sound/usb/Makefile +++ b/sound/usb/Makefile @@ -25,4 +25,4 @@ obj-$(CONFIG_SND_USB_USX2Y) += snd-usbmidi-lib.o obj-$(CONFIG_SND_USB_US122L) += snd-usbmidi-lib.o obj-$(CONFIG_SND) += misc/ usx2y/ caiaq/ 6fire/ hiface/ bcd2000/ -obj-$(CONFIG_LINE6_USB) += line6/ +obj-$(CONFIG_SND_USB_LINE6) += line6/ diff --git a/sound/usb/line6/Kconfig b/sound/usb/line6/Kconfig index 4f1219b4c692..33deb419dde8 100644 --- a/sound/usb/line6/Kconfig +++ b/sound/usb/line6/Kconfig @@ -1,12 +1,14 @@ -menuconfig LINE6_USB - tristate "Line6 USB support" - depends on USB && SND +config SND_USB_LINE6 + tristate select SND_RAWMIDI select SND_PCM + +config SND_USB_POD + tristate "Line6 POD USB support" + select SND_USB_LINE6 help - This is a driver for the guitar amp, cab, and effects modeller - PODxt Pro by Line6 (and similar devices), supporting the - following features: + This is a driver for PODxt and other similar devices, + supporting the following features: * Reading/writing individual parameters * Reading/writing complete channel, effects setup, and amp setup data @@ -18,14 +20,27 @@ menuconfig LINE6_USB * Signal routing (record clean/processed guitar signal, re-amping) - Preliminary support for the Variax Workbench and TonePort - devices is included. +config SND_USB_PODHD + tristate "Line6 POD HD300/400/500 USB support" + select SND_USB_LINE6 + help + This is a driver for POD HD300, 400 and 500 devices. -if LINE6_USB +config SND_USB_TONEPORT + tristate "TonePort GX, UX1 and UX2 USB support" + select SND_USB_LINE6 + help + This is a driver for TonePort GX, UX1 and UX2 devices. + +config SND_USB_VARIAX + tristate "Variax Workbench USB support" + select SND_USB_LINE6 + help + This is a driver for Variax Workbench device. config LINE6_USB_IMPULSE_RESPONSE bool "measure impulse response" - default n + depends on SND_USB_LINE6 help Say Y here to add code to measure the impulse response of a Line6 device. This is more accurate than user-space methods since it @@ -35,4 +50,3 @@ config LINE6_USB_IMPULSE_RESPONSE If unsure, say N. -endif # LINE6_USB diff --git a/sound/usb/line6/Makefile b/sound/usb/line6/Makefile index ae5c374b0f87..fa3a78dac097 100644 --- a/sound/usb/line6/Makefile +++ b/sound/usb/line6/Makefile @@ -1,14 +1,19 @@ -obj-$(CONFIG_LINE6_USB) += line6usb.o - -line6usb-y := \ +snd-usb-line6-y := \ audio.o \ capture.o \ driver.o \ midi.o \ midibuf.o \ pcm.o \ - playback.o \ - pod.o \ - toneport.o \ - variax.o \ - podhd.o + playback.o + +snd-usb-pod-y := pod.o +snd-usb-podhd-y := podhd.o +snd-usb-toneport-y := toneport.o +snd-usb-variax-y := variax.o + +obj-$(CONFIG_SND_USB_LINE6) += snd-usb-line6.o +obj-$(CONFIG_SND_USB_POD) += snd-usb-pod.o +obj-$(CONFIG_SND_USB_PODHD) += snd-usb-podhd.o +obj-$(CONFIG_SND_USB_TONEPORT) += snd-usb-toneport.o +obj-$(CONFIG_SND_USB_VARIAX) += snd-usb-variax.o diff --git a/sound/usb/line6/audio.c b/sound/usb/line6/audio.c index 171d80c1b020..95686e5af4bd 100644 --- a/sound/usb/line6/audio.c +++ b/sound/usb/line6/audio.c @@ -40,6 +40,7 @@ int line6_init_audio(struct usb_line6 *line6) dev_name(line6->ifcdev)); return 0; } +EXPORT_SYMBOL_GPL(line6_init_audio); /* Register the Line6 USB audio system. @@ -54,6 +55,7 @@ int line6_register_audio(struct usb_line6 *line6) return 0; } +EXPORT_SYMBOL_GPL(line6_register_audio); /* Cleanup the Line6 USB audio system. @@ -69,3 +71,4 @@ void line6_cleanup_audio(struct usb_line6 *line6) snd_card_free(card); line6->card = NULL; } +EXPORT_SYMBOL_GPL(line6_cleanup_audio); diff --git a/sound/usb/line6/capture.c b/sound/usb/line6/capture.c index f24c7c5e0a3e..da4ab013ea8e 100644 --- a/sound/usb/line6/capture.c +++ b/sound/usb/line6/capture.c @@ -18,7 +18,6 @@ #include "capture.h" #include "driver.h" #include "pcm.h" -#include "pod.h" /* Find a free URB and submit it. diff --git a/sound/usb/line6/driver.c b/sound/usb/line6/driver.c index 19904d677114..149c393c7302 100644 --- a/sound/usb/line6/driver.c +++ b/sound/usb/line6/driver.c @@ -11,6 +11,7 @@ #include #include +#include #include #include @@ -19,269 +20,20 @@ #include "driver.h" #include "midi.h" #include "playback.h" -#include "pod.h" -#include "podhd.h" #include "revision.h" -#include "toneport.h" #include "usbdefs.h" -#include "variax.h" #define DRIVER_AUTHOR "Markus Grabner " #define DRIVER_DESC "Line6 USB Driver" #define DRIVER_VERSION "0.9.1beta" DRIVER_REVISION -#define LINE6_DEVICE(prod) USB_DEVICE(0x0e41, prod) -#define LINE6_IF_NUM(prod, n) USB_DEVICE_INTERFACE_NUMBER(0x0e41, prod, n) - -/* table of devices that work with this driver */ -static const struct usb_device_id line6_id_table[] = { - { LINE6_DEVICE(0x4250), .driver_info = LINE6_BASSPODXT }, - { LINE6_DEVICE(0x4642), .driver_info = LINE6_BASSPODXTLIVE }, - { LINE6_DEVICE(0x4252), .driver_info = LINE6_BASSPODXTPRO }, - { LINE6_DEVICE(0x4750), .driver_info = LINE6_GUITARPORT }, - { LINE6_IF_NUM(0x5051, 1), .driver_info = LINE6_POCKETPOD }, - { LINE6_DEVICE(0x5057), .driver_info = LINE6_PODHD300 }, - { LINE6_DEVICE(0x5058), .driver_info = LINE6_PODHD400 }, - { LINE6_IF_NUM(0x414D, 0), .driver_info = LINE6_PODHD500_0 }, - { LINE6_IF_NUM(0x414D, 1), .driver_info = LINE6_PODHD500_1 }, - { LINE6_DEVICE(0x4153), .driver_info = LINE6_PODSTUDIO_GX }, - { LINE6_DEVICE(0x4150), .driver_info = LINE6_PODSTUDIO_UX1 }, - { LINE6_IF_NUM(0x4151, 0), .driver_info = LINE6_PODSTUDIO_UX2 }, - { LINE6_DEVICE(0x5044), .driver_info = LINE6_PODXT }, - { LINE6_IF_NUM(0x4650, 0), .driver_info = LINE6_PODXTLIVE_POD }, - { LINE6_IF_NUM(0x4650, 1), .driver_info = LINE6_PODXTLIVE_VARIAX }, - { LINE6_DEVICE(0x5050), .driver_info = LINE6_PODXTPRO }, - { LINE6_DEVICE(0x4147), .driver_info = LINE6_TONEPORT_GX }, - { LINE6_DEVICE(0x4141), .driver_info = LINE6_TONEPORT_UX1 }, - { LINE6_IF_NUM(0x4142, 0), .driver_info = LINE6_TONEPORT_UX2 }, - { LINE6_DEVICE(0x534d), .driver_info = LINE6_VARIAX }, - {} -}; - -MODULE_DEVICE_TABLE(usb, line6_id_table); - -static const struct line6_properties line6_properties_table[] = { - [LINE6_BASSPODXT] = { - .id = "BassPODxt", - .name = "BassPODxt", - .capabilities = LINE6_CAP_CONTROL - | LINE6_CAP_PCM - | LINE6_CAP_HWMON, - .altsetting = 5, - .ep_ctrl_r = 0x84, - .ep_ctrl_w = 0x03, - .ep_audio_r = 0x82, - .ep_audio_w = 0x01, - }, - [LINE6_BASSPODXTLIVE] = { - .id = "BassPODxtLive", - .name = "BassPODxt Live", - .capabilities = LINE6_CAP_CONTROL - | LINE6_CAP_PCM - | LINE6_CAP_HWMON, - .altsetting = 1, - .ep_ctrl_r = 0x84, - .ep_ctrl_w = 0x03, - .ep_audio_r = 0x82, - .ep_audio_w = 0x01, - }, - [LINE6_BASSPODXTPRO] = { - .id = "BassPODxtPro", - .name = "BassPODxt Pro", - .capabilities = LINE6_CAP_CONTROL - | LINE6_CAP_PCM - | LINE6_CAP_HWMON, - .altsetting = 5, - .ep_ctrl_r = 0x84, - .ep_ctrl_w = 0x03, - .ep_audio_r = 0x82, - .ep_audio_w = 0x01, - }, - [LINE6_GUITARPORT] = { - .id = "GuitarPort", - .name = "GuitarPort", - .capabilities = LINE6_CAP_PCM, - .altsetting = 2, /* 1..4 seem to be ok */ - /* no control channel */ - .ep_audio_r = 0x82, - .ep_audio_w = 0x01, - }, - [LINE6_POCKETPOD] = { - .id = "PocketPOD", - .name = "Pocket POD", - .capabilities = LINE6_CAP_CONTROL, - .altsetting = 0, - .ep_ctrl_r = 0x82, - .ep_ctrl_w = 0x02, - /* no audio channel */ - }, - [LINE6_PODHD300] = { - .id = "PODHD300", - .name = "POD HD300", - .capabilities = LINE6_CAP_CONTROL - | LINE6_CAP_PCM - | LINE6_CAP_HWMON, - .altsetting = 5, - .ep_ctrl_r = 0x84, - .ep_ctrl_w = 0x03, - .ep_audio_r = 0x82, - .ep_audio_w = 0x01, - }, - [LINE6_PODHD400] = { - .id = "PODHD400", - .name = "POD HD400", - .capabilities = LINE6_CAP_CONTROL - | LINE6_CAP_PCM - | LINE6_CAP_HWMON, - .altsetting = 5, - .ep_ctrl_r = 0x84, - .ep_ctrl_w = 0x03, - .ep_audio_r = 0x82, - .ep_audio_w = 0x01, - }, - [LINE6_PODHD500_0] = { - .id = "PODHD500", - .name = "POD HD500", - .capabilities = LINE6_CAP_CONTROL - | LINE6_CAP_PCM - | LINE6_CAP_HWMON, - .altsetting = 1, - .ep_ctrl_r = 0x81, - .ep_ctrl_w = 0x01, - .ep_audio_r = 0x86, - .ep_audio_w = 0x02, - }, - [LINE6_PODHD500_1] = { - .id = "PODHD500", - .name = "POD HD500", - .capabilities = LINE6_CAP_CONTROL - | LINE6_CAP_PCM - | LINE6_CAP_HWMON, - .altsetting = 1, - .ep_ctrl_r = 0x81, - .ep_ctrl_w = 0x01, - .ep_audio_r = 0x86, - .ep_audio_w = 0x02, - }, - [LINE6_PODSTUDIO_GX] = { - .id = "PODStudioGX", - .name = "POD Studio GX", - .capabilities = LINE6_CAP_PCM, - .altsetting = 2, /* 1..4 seem to be ok */ - /* no control channel */ - .ep_audio_r = 0x82, - .ep_audio_w = 0x01, - }, - [LINE6_PODSTUDIO_UX1] = { - .id = "PODStudioUX1", - .name = "POD Studio UX1", - .capabilities = LINE6_CAP_PCM, - .altsetting = 2, /* 1..4 seem to be ok */ - /* no control channel */ - .ep_audio_r = 0x82, - .ep_audio_w = 0x01, - }, - [LINE6_PODSTUDIO_UX2] = { - .id = "PODStudioUX2", - .name = "POD Studio UX2", - .capabilities = LINE6_CAP_PCM, - .altsetting = 2, /* defaults to 44.1kHz, 16-bit */ - /* no control channel */ - .ep_audio_r = 0x82, - .ep_audio_w = 0x01, - }, - [LINE6_PODXT] = { - .id = "PODxt", - .name = "PODxt", - .capabilities = LINE6_CAP_CONTROL - | LINE6_CAP_PCM - | LINE6_CAP_HWMON, - .altsetting = 5, - .ep_ctrl_r = 0x84, - .ep_ctrl_w = 0x03, - .ep_audio_r = 0x82, - .ep_audio_w = 0x01, - }, - [LINE6_PODXTLIVE_POD] = { - .id = "PODxtLive", - .name = "PODxt Live", - .capabilities = LINE6_CAP_CONTROL - | LINE6_CAP_PCM - | LINE6_CAP_HWMON, - .altsetting = 1, - .ep_ctrl_r = 0x84, - .ep_ctrl_w = 0x03, - .ep_audio_r = 0x82, - .ep_audio_w = 0x01, - }, - [LINE6_PODXTLIVE_VARIAX] = { - .id = "PODxtLive", - .name = "PODxt Live", - .capabilities = LINE6_CAP_CONTROL - | LINE6_CAP_PCM - | LINE6_CAP_HWMON, - .altsetting = 1, - .ep_ctrl_r = 0x86, - .ep_ctrl_w = 0x05, - .ep_audio_r = 0x82, - .ep_audio_w = 0x01, - }, - [LINE6_PODXTPRO] = { - .id = "PODxtPro", - .name = "PODxt Pro", - .capabilities = LINE6_CAP_CONTROL - | LINE6_CAP_PCM - | LINE6_CAP_HWMON, - .altsetting = 5, - .ep_ctrl_r = 0x84, - .ep_ctrl_w = 0x03, - .ep_audio_r = 0x82, - .ep_audio_w = 0x01, - }, - [LINE6_TONEPORT_GX] = { - .id = "TonePortGX", - .name = "TonePort GX", - .capabilities = LINE6_CAP_PCM, - .altsetting = 2, /* 1..4 seem to be ok */ - /* no control channel */ - .ep_audio_r = 0x82, - .ep_audio_w = 0x01, - }, - [LINE6_TONEPORT_UX1] = { - .id = "TonePortUX1", - .name = "TonePort UX1", - .capabilities = LINE6_CAP_PCM, - .altsetting = 2, /* 1..4 seem to be ok */ - /* no control channel */ - .ep_audio_r = 0x82, - .ep_audio_w = 0x01, - }, - [LINE6_TONEPORT_UX2] = { - .id = "TonePortUX2", - .name = "TonePort UX2", - .capabilities = LINE6_CAP_PCM, - .altsetting = 2, /* defaults to 44.1kHz, 16-bit */ - /* no control channel */ - .ep_audio_r = 0x82, - .ep_audio_w = 0x01, - }, - [LINE6_VARIAX] = { - .id = "Variax", - .name = "Variax Workbench", - .capabilities = LINE6_CAP_CONTROL, - .altsetting = 1, - .ep_ctrl_r = 0x82, - .ep_ctrl_w = 0x01, - /* no audio channel */ - } -}; - /* This is Line6's MIDI manufacturer ID. */ const unsigned char line6_midi_id[] = { 0x00, 0x01, 0x0c }; +EXPORT_SYMBOL_GPL(line6_midi_id); /* Code to request version of POD, Variax interface @@ -417,6 +169,7 @@ void line6_start_timer(struct timer_list *timer, unsigned int msecs, setup_timer(timer, function, data); mod_timer(timer, jiffies + msecs * HZ / 1000); } +EXPORT_SYMBOL_GPL(line6_start_timer); /* Asynchronously send raw message. @@ -450,6 +203,7 @@ int line6_send_raw_message_async(struct usb_line6 *line6, const char *buffer, /* start sending: */ return line6_send_raw_message_async_part(msg, urb); } +EXPORT_SYMBOL_GPL(line6_send_raw_message_async); /* Send asynchronous device version request. @@ -471,6 +225,7 @@ int line6_version_request_async(struct usb_line6 *line6) kfree(buffer); return retval; } +EXPORT_SYMBOL_GPL(line6_version_request_async); /* Send sysex message in pieces of wMaxPacketSize bytes. @@ -482,6 +237,7 @@ int line6_send_sysex_message(struct usb_line6 *line6, const char *buffer, size + SYSEX_EXTRA_SIZE) - SYSEX_EXTRA_SIZE; } +EXPORT_SYMBOL_GPL(line6_send_sysex_message); /* Allocate buffer for sysex message and prepare header. @@ -503,6 +259,7 @@ char *line6_alloc_sysex_buffer(struct usb_line6 *line6, int code1, int code2, buffer[sizeof(line6_midi_id) + 3 + size] = LINE6_SYSEX_END; return buffer; } +EXPORT_SYMBOL_GPL(line6_alloc_sysex_buffer); /* Notification of data received from the Line6 device. @@ -658,6 +415,7 @@ int line6_read_data(struct usb_line6 *line6, int address, void *data, return 0; } +EXPORT_SYMBOL_GPL(line6_read_data); /* Write data to device. @@ -702,6 +460,7 @@ int line6_write_data(struct usb_line6 *line6, int address, void *data, return 0; } +EXPORT_SYMBOL_GPL(line6_write_data); /* Read Line6 device serial number. @@ -712,6 +471,7 @@ int line6_read_serial_number(struct usb_line6 *line6, int *serial_number) return line6_read_data(line6, 0x80d0, serial_number, sizeof(*serial_number)); } +EXPORT_SYMBOL_GPL(line6_read_serial_number); /* No operation (i.e., unsupported). @@ -721,6 +481,7 @@ ssize_t line6_nop_read(struct device *dev, struct device_attribute *attr, { return 0; } +EXPORT_SYMBOL_GPL(line6_nop_read); /* Generic destructor. @@ -744,30 +505,29 @@ static void line6_destruct(struct usb_interface *interface) /* make sure the device isn't destructed twice: */ usb_set_intfdata(interface, NULL); - - /* free interface data: */ - kfree(line6); } /* Probe USB device. */ -static int line6_probe(struct usb_interface *interface, - const struct usb_device_id *id) +int line6_probe(struct usb_interface *interface, + struct usb_line6 *line6, + const struct line6_properties *properties, + int (*private_init)(struct usb_interface *, struct usb_line6 *)) { - enum line6_device_type devtype; struct usb_device *usbdev; - struct usb_line6 *line6; - const struct line6_properties *properties; int interface_number; - int size = 0; int ret; - if (interface == NULL) - return -ENODEV; + if (!interface) { + ret = -ENODEV; + goto err_put; + } usbdev = interface_to_usbdev(interface); - if (usbdev == NULL) - return -ENODEV; + if (!usbdev) { + ret = -ENODEV; + goto err_put; + } /* we don't handle multiple configurations */ if (usbdev->descriptor.bNumConfigurations != 1) { @@ -775,10 +535,7 @@ static int line6_probe(struct usb_interface *interface, goto err_put; } - devtype = id->driver_info; - /* initialize device info: */ - properties = &line6_properties_table[devtype]; dev_info(&interface->dev, "Line6 %s found\n", properties->name); /* query interface number */ @@ -791,76 +548,10 @@ static int line6_probe(struct usb_interface *interface, goto err_put; } - /* initialize device data based on device: */ - switch (devtype) { - case LINE6_BASSPODXT: - case LINE6_BASSPODXTLIVE: - case LINE6_BASSPODXTPRO: - case LINE6_PODXT: - case LINE6_PODXTPRO: - size = sizeof(struct usb_line6_pod); - break; - - case LINE6_PODHD300: - case LINE6_PODHD400: - size = sizeof(struct usb_line6_podhd); - break; - - case LINE6_PODHD500_0: - case LINE6_PODHD500_1: - size = sizeof(struct usb_line6_podhd); - break; - - case LINE6_POCKETPOD: - size = sizeof(struct usb_line6_pod); - break; - - case LINE6_PODSTUDIO_GX: - case LINE6_PODSTUDIO_UX1: - case LINE6_PODSTUDIO_UX2: - case LINE6_TONEPORT_GX: - case LINE6_TONEPORT_UX1: - case LINE6_TONEPORT_UX2: - case LINE6_GUITARPORT: - size = sizeof(struct usb_line6_toneport); - break; - - case LINE6_PODXTLIVE_POD: - size = sizeof(struct usb_line6_pod); - break; - - case LINE6_PODXTLIVE_VARIAX: - size = sizeof(struct usb_line6_variax); - break; - - case LINE6_VARIAX: - size = sizeof(struct usb_line6_variax); - break; - - default: - MISSING_CASE; - ret = -ENODEV; - goto err_put; - } - - if (size == 0) { - 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) { - ret = -ENODEV; - goto err_put; - } - /* store basic data: */ line6->properties = properties; line6->usbdev = usbdev; line6->ifcdev = &interface->dev; - line6->type = devtype; /* get data from endpoint descriptor (see usb_maxpacket): */ { @@ -903,7 +594,6 @@ static int line6_probe(struct usb_interface *interface, if (line6->urb_listen == NULL) { dev_err(&interface->dev, "Out of memory\n"); - line6_destruct(interface); ret = -ENOMEM; goto err_destruct; } @@ -917,50 +607,7 @@ static int line6_probe(struct usb_interface *interface, } /* initialize device data based on device: */ - switch (devtype) { - case LINE6_BASSPODXT: - case LINE6_BASSPODXTLIVE: - case LINE6_BASSPODXTPRO: - case LINE6_POCKETPOD: - case LINE6_PODXT: - case LINE6_PODXTPRO: - ret = line6_pod_init(interface, line6); - break; - - case LINE6_PODHD300: - case LINE6_PODHD400: - case LINE6_PODHD500_0: - case LINE6_PODHD500_1: - ret = line6_podhd_init(interface, line6); - break; - - case LINE6_PODXTLIVE_POD: - ret = line6_pod_init(interface, line6); - break; - - case LINE6_PODXTLIVE_VARIAX: - ret = line6_variax_init(interface, line6); - break; - - case LINE6_VARIAX: - ret = line6_variax_init(interface, line6); - break; - - case LINE6_PODSTUDIO_GX: - case LINE6_PODSTUDIO_UX1: - case LINE6_PODSTUDIO_UX2: - case LINE6_TONEPORT_GX: - case LINE6_TONEPORT_UX1: - case LINE6_TONEPORT_UX2: - case LINE6_GUITARPORT: - ret = line6_toneport_init(interface, line6); - break; - - default: - MISSING_CASE; - ret = -ENODEV; - } - + ret = private_init(interface, line6); if (ret < 0) goto err_destruct; @@ -985,11 +632,12 @@ err_destruct: err_put: return ret; } +EXPORT_SYMBOL_GPL(line6_probe); /* Line6 device disconnected. */ -static void line6_disconnect(struct usb_interface *interface) +void line6_disconnect(struct usb_interface *interface) { struct usb_line6 *line6; struct usb_device *usbdev; @@ -1024,17 +672,21 @@ static void line6_disconnect(struct usb_interface *interface) line6_destruct(interface); + /* free interface data: */ + kfree(line6); + /* decrement reference counters: */ usb_put_intf(interface); usb_put_dev(usbdev); } +EXPORT_SYMBOL_GPL(line6_disconnect); #ifdef CONFIG_PM /* Suspend Line6 device. */ -static int line6_suspend(struct usb_interface *interface, pm_message_t message) +int line6_suspend(struct usb_interface *interface, pm_message_t message) { struct usb_line6 *line6 = usb_get_intfdata(interface); struct snd_line6_pcm *line6pcm = line6->line6pcm; @@ -1052,11 +704,12 @@ static int line6_suspend(struct usb_interface *interface, pm_message_t message) return 0; } +EXPORT_SYMBOL_GPL(line6_suspend); /* Resume Line6 device. */ -static int line6_resume(struct usb_interface *interface) +int line6_resume(struct usb_interface *interface) { struct usb_line6 *line6 = usb_get_intfdata(interface); @@ -1066,47 +719,10 @@ static int line6_resume(struct usb_interface *interface) snd_power_change_state(line6->card, SNDRV_CTL_POWER_D0); return 0; } - -/* - Resume Line6 device after reset. -*/ -static int line6_reset_resume(struct usb_interface *interface) -{ - struct usb_line6 *line6 = usb_get_intfdata(interface); - - switch (line6->type) { - case LINE6_PODSTUDIO_GX: - case LINE6_PODSTUDIO_UX1: - case LINE6_PODSTUDIO_UX2: - case LINE6_TONEPORT_GX: - case LINE6_TONEPORT_UX1: - case LINE6_TONEPORT_UX2: - case LINE6_GUITARPORT: - line6_toneport_reset_resume((struct usb_line6_toneport *)line6); - - default: - break; - } - - return line6_resume(interface); -} +EXPORT_SYMBOL_GPL(line6_resume); #endif /* CONFIG_PM */ -static struct usb_driver line6_driver = { - .name = DRIVER_NAME, - .probe = line6_probe, - .disconnect = line6_disconnect, -#ifdef CONFIG_PM - .suspend = line6_suspend, - .resume = line6_resume, - .reset_resume = line6_reset_resume, -#endif - .id_table = line6_id_table, -}; - -module_usb_driver(line6_driver); - MODULE_AUTHOR(DRIVER_AUTHOR); MODULE_DESCRIPTION(DRIVER_DESC); MODULE_LICENSE("GPL"); diff --git a/sound/usb/line6/driver.h b/sound/usb/line6/driver.h index ad203f197e80..31cd318369e9 100644 --- a/sound/usb/line6/driver.h +++ b/sound/usb/line6/driver.h @@ -20,29 +20,6 @@ #define DRIVER_NAME "line6usb" -enum line6_device_type { - LINE6_BASSPODXT, - LINE6_BASSPODXTLIVE, - LINE6_BASSPODXTPRO, - LINE6_GUITARPORT, - LINE6_POCKETPOD, - LINE6_PODHD300, - LINE6_PODHD400, - LINE6_PODHD500_0, - LINE6_PODHD500_1, - LINE6_PODSTUDIO_GX, - LINE6_PODSTUDIO_UX1, - LINE6_PODSTUDIO_UX2, - LINE6_PODXT, - LINE6_PODXTLIVE_POD, - LINE6_PODXTLIVE_VARIAX, - LINE6_PODXTPRO, - LINE6_TONEPORT_GX, - LINE6_TONEPORT_UX1, - LINE6_TONEPORT_UX2, - LINE6_VARIAX -}; - #define LINE6_TIMEOUT 1 #define LINE6_BUFSIZE_LISTEN 32 #define LINE6_MESSAGE_MAXLEN 256 @@ -134,11 +111,6 @@ struct usb_line6 { */ struct usb_device *usbdev; - /** - Device type. - */ - enum line6_device_type type; - /** Properties. */ @@ -225,4 +197,15 @@ extern int line6_version_request_async(struct usb_line6 *line6); extern int line6_write_data(struct usb_line6 *line6, int address, void *data, size_t datalen); +int line6_probe(struct usb_interface *interface, + struct usb_line6 *line6, + const struct line6_properties *properties, + int (*private_init)(struct usb_interface *, struct usb_line6 *)); +void line6_disconnect(struct usb_interface *interface); + +#ifdef CONFIG_PM +int line6_suspend(struct usb_interface *interface, pm_message_t message); +int line6_resume(struct usb_interface *interface); +#endif + #endif diff --git a/sound/usb/line6/midi.c b/sound/usb/line6/midi.c index c9d725ae85a0..2a42d533f49c 100644 --- a/sound/usb/line6/midi.c +++ b/sound/usb/line6/midi.c @@ -11,13 +11,13 @@ #include #include +#include #include #include #include "audio.h" #include "driver.h" #include "midi.h" -#include "pod.h" #include "usbdefs.h" #define line6_rawmidi_substream_midi(substream) \ @@ -319,3 +319,4 @@ int line6_init_midi(struct usb_line6 *line6) spin_lock_init(&line6midi->midi_transmit_lock); return 0; } +EXPORT_SYMBOL_GPL(line6_init_midi); diff --git a/sound/usb/line6/pcm.c b/sound/usb/line6/pcm.c index 6d4e5cd0482c..b7348b031bf7 100644 --- a/sound/usb/line6/pcm.c +++ b/sound/usb/line6/pcm.c @@ -10,6 +10,7 @@ */ #include +#include #include #include #include @@ -19,7 +20,6 @@ #include "capture.h" #include "driver.h" #include "playback.h" -#include "pod.h" #ifdef CONFIG_LINE6_USB_IMPULSE_RESPONSE @@ -195,6 +195,7 @@ pcm_acquire_error: line6_pcm_release(line6pcm, flags_final & channels); return err; } +EXPORT_SYMBOL_GPL(line6_pcm_acquire); int line6_pcm_release(struct snd_line6_pcm *line6pcm, int channels) { @@ -223,6 +224,7 @@ int line6_pcm_release(struct snd_line6_pcm *line6pcm, int channels) return 0; } +EXPORT_SYMBOL_GPL(line6_pcm_release); /* trigger callback */ int snd_line6_trigger(struct snd_pcm_substream *substream, int cmd) @@ -408,6 +410,7 @@ void line6_pcm_disconnect(struct snd_line6_pcm *line6pcm) line6_unlink_wait_clear_audio_out_urbs(line6pcm); line6_unlink_wait_clear_audio_in_urbs(line6pcm); } +EXPORT_SYMBOL_GPL(line6_pcm_disconnect); /* Create and register the PCM device and mixer entries. @@ -490,6 +493,7 @@ int line6_init_pcm(struct usb_line6 *line6, return 0; } +EXPORT_SYMBOL_GPL(line6_init_pcm); /* prepare pcm callback */ int snd_line6_prepare(struct snd_pcm_substream *substream) diff --git a/sound/usb/line6/playback.c b/sound/usb/line6/playback.c index da2e3b8876b8..0a874105ccef 100644 --- a/sound/usb/line6/playback.c +++ b/sound/usb/line6/playback.c @@ -18,7 +18,6 @@ #include "capture.h" #include "driver.h" #include "pcm.h" -#include "pod.h" #include "playback.h" /* diff --git a/sound/usb/line6/pod.c b/sound/usb/line6/pod.c index 85a43631996e..dde9c2b8ad0f 100644 --- a/sound/usb/line6/pod.c +++ b/sound/usb/line6/pod.c @@ -11,13 +11,94 @@ #include #include +#include +#include +#include + +#include #include #include "audio.h" #include "capture.h" #include "driver.h" #include "playback.h" -#include "pod.h" +#include "usbdefs.h" + +/* + Locate name in binary program dump +*/ +#define POD_NAME_OFFSET 0 +#define POD_NAME_LENGTH 16 + +/* + Other constants +*/ +#define POD_CONTROL_SIZE 0x80 +#define POD_BUFSIZE_DUMPREQ 7 +#define POD_STARTUP_DELAY 1000 + +/* + Stages of POD startup procedure +*/ +enum { + POD_STARTUP_INIT = 1, + POD_STARTUP_VERSIONREQ, + POD_STARTUP_WORKQUEUE, + POD_STARTUP_SETUP, + POD_STARTUP_LAST = POD_STARTUP_SETUP - 1 +}; + +enum { + LINE6_BASSPODXT, + LINE6_BASSPODXTLIVE, + LINE6_BASSPODXTPRO, + LINE6_POCKETPOD, + LINE6_PODXT, + LINE6_PODXTLIVE_POD, + LINE6_PODXTPRO, +}; + +struct usb_line6_pod { + /** + Generic Line6 USB data. + */ + struct usb_line6 line6; + + /** + Instrument monitor level. + */ + int monitor_level; + + /** + Timer for device initializaton. + */ + struct timer_list startup_timer; + + /** + Work handler for device initializaton. + */ + struct work_struct startup_work; + + /** + Current progress in startup procedure. + */ + int startup_progress; + + /** + Serial number of device. + */ + int serial_number; + + /** + Firmware version (x 100). + */ + int firmware_version; + + /** + Device ID. + */ + int device_id; +}; #define POD_SYSEX_CODE 3 #define POD_BYTES_PER_FRAME 6 /* 24bit audio (stereo) */ @@ -442,7 +523,8 @@ static int pod_try_init(struct usb_interface *interface, /* Init POD device (and clean up in case of failure). */ -int line6_pod_init(struct usb_interface *interface, struct usb_line6 *line6) +static int pod_init(struct usb_interface *interface, + struct usb_line6 *line6) { int err = pod_try_init(interface, line6); @@ -451,3 +533,141 @@ int line6_pod_init(struct usb_interface *interface, struct usb_line6 *line6) return err; } + +#define LINE6_DEVICE(prod) USB_DEVICE(0x0e41, prod) +#define LINE6_IF_NUM(prod, n) USB_DEVICE_INTERFACE_NUMBER(0x0e41, prod, n) + +/* table of devices that work with this driver */ +static const struct usb_device_id pod_id_table[] = { + { LINE6_DEVICE(0x4250), .driver_info = LINE6_BASSPODXT }, + { LINE6_DEVICE(0x4642), .driver_info = LINE6_BASSPODXTLIVE }, + { LINE6_DEVICE(0x4252), .driver_info = LINE6_BASSPODXTPRO }, + { LINE6_IF_NUM(0x5051, 1), .driver_info = LINE6_POCKETPOD }, + { LINE6_DEVICE(0x5044), .driver_info = LINE6_PODXT }, + { LINE6_IF_NUM(0x4650, 0), .driver_info = LINE6_PODXTLIVE_POD }, + { LINE6_DEVICE(0x5050), .driver_info = LINE6_PODXTPRO }, + {} +}; + +MODULE_DEVICE_TABLE(usb, pod_id_table); + +static const struct line6_properties pod_properties_table[] = { + [LINE6_BASSPODXT] = { + .id = "BassPODxt", + .name = "BassPODxt", + .capabilities = LINE6_CAP_CONTROL + | LINE6_CAP_PCM + | LINE6_CAP_HWMON, + .altsetting = 5, + .ep_ctrl_r = 0x84, + .ep_ctrl_w = 0x03, + .ep_audio_r = 0x82, + .ep_audio_w = 0x01, + }, + [LINE6_BASSPODXTLIVE] = { + .id = "BassPODxtLive", + .name = "BassPODxt Live", + .capabilities = LINE6_CAP_CONTROL + | LINE6_CAP_PCM + | LINE6_CAP_HWMON, + .altsetting = 1, + .ep_ctrl_r = 0x84, + .ep_ctrl_w = 0x03, + .ep_audio_r = 0x82, + .ep_audio_w = 0x01, + }, + [LINE6_BASSPODXTPRO] = { + .id = "BassPODxtPro", + .name = "BassPODxt Pro", + .capabilities = LINE6_CAP_CONTROL + | LINE6_CAP_PCM + | LINE6_CAP_HWMON, + .altsetting = 5, + .ep_ctrl_r = 0x84, + .ep_ctrl_w = 0x03, + .ep_audio_r = 0x82, + .ep_audio_w = 0x01, + }, + [LINE6_POCKETPOD] = { + .id = "PocketPOD", + .name = "Pocket POD", + .capabilities = LINE6_CAP_CONTROL, + .altsetting = 0, + .ep_ctrl_r = 0x82, + .ep_ctrl_w = 0x02, + /* no audio channel */ + }, + [LINE6_PODXT] = { + .id = "PODxt", + .name = "PODxt", + .capabilities = LINE6_CAP_CONTROL + | LINE6_CAP_PCM + | LINE6_CAP_HWMON, + .altsetting = 5, + .ep_ctrl_r = 0x84, + .ep_ctrl_w = 0x03, + .ep_audio_r = 0x82, + .ep_audio_w = 0x01, + }, + [LINE6_PODXTLIVE_POD] = { + .id = "PODxtLive", + .name = "PODxt Live", + .capabilities = LINE6_CAP_CONTROL + | LINE6_CAP_PCM + | LINE6_CAP_HWMON, + .altsetting = 1, + .ep_ctrl_r = 0x84, + .ep_ctrl_w = 0x03, + .ep_audio_r = 0x82, + .ep_audio_w = 0x01, + }, + [LINE6_PODXTPRO] = { + .id = "PODxtPro", + .name = "PODxt Pro", + .capabilities = LINE6_CAP_CONTROL + | LINE6_CAP_PCM + | LINE6_CAP_HWMON, + .altsetting = 5, + .ep_ctrl_r = 0x84, + .ep_ctrl_w = 0x03, + .ep_audio_r = 0x82, + .ep_audio_w = 0x01, + }, +}; + +/* + Probe USB device. +*/ +static int pod_probe(struct usb_interface *interface, + const struct usb_device_id *id) +{ + struct usb_line6_pod *pod; + int err; + + pod = kzalloc(sizeof(*pod), GFP_KERNEL); + if (!pod) + return -ENODEV; + err = line6_probe(interface, &pod->line6, + &pod_properties_table[id->driver_info], + pod_init); + if (err < 0) + kfree(pod); + return err; +} + +static struct usb_driver pod_driver = { + .name = KBUILD_MODNAME, + .probe = pod_probe, + .disconnect = line6_disconnect, +#ifdef CONFIG_PM + .suspend = line6_suspend, + .resume = line6_resume, + .reset_resume = line6_resume, +#endif + .id_table = pod_id_table, +}; + +module_usb_driver(pod_driver); + +MODULE_DESCRIPTION("Line6 POD USB driver"); +MODULE_LICENSE("GPL"); diff --git a/sound/usb/line6/pod.h b/sound/usb/line6/pod.h deleted file mode 100644 index 87a8f0fa9cba..000000000000 --- a/sound/usb/line6/pod.h +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Line6 Linux USB driver - 0.9.1beta - * - * Copyright (C) 2004-2010 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. - * - */ - -#ifndef POD_H -#define POD_H - -#include -#include -#include - -#include - -#include "driver.h" - -/* - Locate name in binary program dump -*/ -#define POD_NAME_OFFSET 0 -#define POD_NAME_LENGTH 16 - -/* - Other constants -*/ -#define POD_CONTROL_SIZE 0x80 -#define POD_BUFSIZE_DUMPREQ 7 -#define POD_STARTUP_DELAY 1000 - -/* - Stages of POD startup procedure -*/ -enum { - POD_STARTUP_INIT = 1, - POD_STARTUP_VERSIONREQ, - POD_STARTUP_WORKQUEUE, - POD_STARTUP_SETUP, - POD_STARTUP_LAST = POD_STARTUP_SETUP - 1 -}; - -struct usb_line6_pod { - /** - Generic Line6 USB data. - */ - struct usb_line6 line6; - - /** - Instrument monitor level. - */ - int monitor_level; - - /** - Timer for device initializaton. - */ - struct timer_list startup_timer; - - /** - Work handler for device initializaton. - */ - struct work_struct startup_work; - - /** - Current progress in startup procedure. - */ - int startup_progress; - - /** - Serial number of device. - */ - int serial_number; - - /** - Firmware version (x 100). - */ - int firmware_version; - - /** - Device ID. - */ - int device_id; -}; - -extern int line6_pod_init(struct usb_interface *interface, - struct usb_line6 *line6); - -#endif diff --git a/sound/usb/line6/podhd.c b/sound/usb/line6/podhd.c index 27c5402cece8..84096326694c 100644 --- a/sound/usb/line6/podhd.c +++ b/sound/usb/line6/podhd.c @@ -9,13 +9,30 @@ * */ +#include +#include +#include #include #include #include "audio.h" #include "driver.h" #include "pcm.h" -#include "podhd.h" +#include "usbdefs.h" + +enum { + LINE6_PODHD300, + LINE6_PODHD400, + LINE6_PODHD500_0, + LINE6_PODHD500_1, +}; + +struct usb_line6_podhd { + /** + Generic Line6 USB data. + */ + struct usb_line6 line6; +}; #define PODHD_BYTES_PER_FRAME 6 /* 24bit audio (stereo) */ @@ -141,10 +158,76 @@ static int podhd_try_init(struct usb_interface *interface, return err; } +#define LINE6_DEVICE(prod) USB_DEVICE(0x0e41, prod) +#define LINE6_IF_NUM(prod, n) USB_DEVICE_INTERFACE_NUMBER(0x0e41, prod, n) + +/* table of devices that work with this driver */ +static const struct usb_device_id podhd_id_table[] = { + { LINE6_DEVICE(0x5057), .driver_info = LINE6_PODHD300 }, + { LINE6_DEVICE(0x5058), .driver_info = LINE6_PODHD400 }, + { LINE6_IF_NUM(0x414D, 0), .driver_info = LINE6_PODHD500_0 }, + { LINE6_IF_NUM(0x414D, 1), .driver_info = LINE6_PODHD500_1 }, + {} +}; + +MODULE_DEVICE_TABLE(usb, podhd_id_table); + +static const struct line6_properties podhd_properties_table[] = { + [LINE6_PODHD300] = { + .id = "PODHD300", + .name = "POD HD300", + .capabilities = LINE6_CAP_CONTROL + | LINE6_CAP_PCM + | LINE6_CAP_HWMON, + .altsetting = 5, + .ep_ctrl_r = 0x84, + .ep_ctrl_w = 0x03, + .ep_audio_r = 0x82, + .ep_audio_w = 0x01, + }, + [LINE6_PODHD400] = { + .id = "PODHD400", + .name = "POD HD400", + .capabilities = LINE6_CAP_CONTROL + | LINE6_CAP_PCM + | LINE6_CAP_HWMON, + .altsetting = 5, + .ep_ctrl_r = 0x84, + .ep_ctrl_w = 0x03, + .ep_audio_r = 0x82, + .ep_audio_w = 0x01, + }, + [LINE6_PODHD500_0] = { + .id = "PODHD500", + .name = "POD HD500", + .capabilities = LINE6_CAP_CONTROL + | LINE6_CAP_PCM + | LINE6_CAP_HWMON, + .altsetting = 1, + .ep_ctrl_r = 0x81, + .ep_ctrl_w = 0x01, + .ep_audio_r = 0x86, + .ep_audio_w = 0x02, + }, + [LINE6_PODHD500_1] = { + .id = "PODHD500", + .name = "POD HD500", + .capabilities = LINE6_CAP_CONTROL + | LINE6_CAP_PCM + | LINE6_CAP_HWMON, + .altsetting = 1, + .ep_ctrl_r = 0x81, + .ep_ctrl_w = 0x01, + .ep_audio_r = 0x86, + .ep_audio_w = 0x02, + }, +}; + /* Init POD HD device (and clean up in case of failure). */ -int line6_podhd_init(struct usb_interface *interface, struct usb_line6 *line6) +static int podhd_init(struct usb_interface *interface, + struct usb_line6 *line6) { struct usb_line6_podhd *podhd = (struct usb_line6_podhd *) line6; int err = podhd_try_init(interface, podhd); @@ -154,3 +237,40 @@ int line6_podhd_init(struct usb_interface *interface, struct usb_line6 *line6) return err; } + +/* + Probe USB device. +*/ +static int podhd_probe(struct usb_interface *interface, + const struct usb_device_id *id) +{ + struct usb_line6_podhd *podhd; + int err; + + podhd = kzalloc(sizeof(*podhd), GFP_KERNEL); + if (!podhd) + return -ENODEV; + err = line6_probe(interface, &podhd->line6, + &podhd_properties_table[id->driver_info], + podhd_init); + if (err < 0) + kfree(podhd); + return err; +} + +static struct usb_driver podhd_driver = { + .name = KBUILD_MODNAME, + .probe = podhd_probe, + .disconnect = line6_disconnect, +#ifdef CONFIG_PM + .suspend = line6_suspend, + .resume = line6_resume, + .reset_resume = line6_resume, +#endif + .id_table = podhd_id_table, +}; + +module_usb_driver(podhd_driver); + +MODULE_DESCRIPTION("Line6 PODHD USB driver"); +MODULE_LICENSE("GPL"); diff --git a/sound/usb/line6/podhd.h b/sound/usb/line6/podhd.h deleted file mode 100644 index a14f711f9725..000000000000 --- a/sound/usb/line6/podhd.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Line6 Pod HD - * - * Copyright (C) 2011 Stefan Hajnoczi - * - * 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. - * - */ - -#ifndef PODHD_H -#define PODHD_H - -#include - -#include "driver.h" - -struct usb_line6_podhd { - /** - Generic Line6 USB data. - */ - struct usb_line6 line6; -}; - -extern int line6_podhd_init(struct usb_interface *interface, - struct usb_line6 *line6); - -#endif /* PODHD_H */ diff --git a/sound/usb/line6/toneport.c b/sound/usb/line6/toneport.c index 7f97f4a812a7..4f07643e47f2 100644 --- a/sound/usb/line6/toneport.c +++ b/sound/usb/line6/toneport.c @@ -11,13 +11,59 @@ */ #include +#include +#include +#include +#include #include #include "audio.h" #include "capture.h" #include "driver.h" #include "playback.h" -#include "toneport.h" +#include "usbdefs.h" + +enum line6_device_type { + LINE6_GUITARPORT, + LINE6_PODSTUDIO_GX, + LINE6_PODSTUDIO_UX1, + LINE6_PODSTUDIO_UX2, + LINE6_TONEPORT_GX, + LINE6_TONEPORT_UX1, + LINE6_TONEPORT_UX2, +}; + +struct usb_line6_toneport { + /** + Generic Line6 USB data. + */ + struct usb_line6 line6; + + /** + Source selector. + */ + int source; + + /** + Serial number of device. + */ + int serial_number; + + /** + Firmware version (x 100). + */ + int firmware_version; + + /** + Timer for delayed PCM startup. + */ + struct timer_list timer; + + /** + Device type. + */ + enum line6_device_type type; +}; static int toneport_send_cmd(struct usb_device *usbdev, int cmd1, int cmd2); @@ -319,7 +365,7 @@ static void toneport_setup(struct usb_line6_toneport *toneport) toneport_send_cmd(usbdev, 0x0301, 0x0000); /* initialize source select: */ - switch (line6->type) { + switch (toneport->type) { case LINE6_TONEPORT_UX1: case LINE6_TONEPORT_UX2: case LINE6_PODSTUDIO_UX1: @@ -331,7 +377,7 @@ static void toneport_setup(struct usb_line6_toneport *toneport) break; } - if (toneport_has_led(line6->type)) + if (toneport_has_led(toneport->type)) toneport_update_led(&usbdev->dev); } @@ -400,7 +446,7 @@ static int toneport_try_init(struct usb_interface *interface, return err; /* register source select control: */ - switch (line6->type) { + switch (toneport->type) { case LINE6_TONEPORT_UX1: case LINE6_TONEPORT_UX2: case LINE6_PODSTUDIO_UX1: @@ -424,7 +470,7 @@ static int toneport_try_init(struct usb_interface *interface, line6_read_serial_number(line6, &toneport->serial_number); line6_read_data(line6, 0x80c2, &toneport->firmware_version, 1); - if (toneport_has_led(line6->type)) { + if (toneport_has_led(toneport->type)) { CHECK_RETURN(device_create_file (&interface->dev, &dev_attr_led_red)); CHECK_RETURN(device_create_file @@ -443,8 +489,8 @@ static int toneport_try_init(struct usb_interface *interface, /* Init Toneport device (and clean up in case of failure). */ -int line6_toneport_init(struct usb_interface *interface, - struct usb_line6 *line6) +static int toneport_init(struct usb_interface *interface, + struct usb_line6 *line6) { int err = toneport_try_init(interface, line6); @@ -454,10 +500,134 @@ int line6_toneport_init(struct usb_interface *interface, return err; } +#ifdef CONFIG_PM /* Resume Toneport device after reset. */ -void line6_toneport_reset_resume(struct usb_line6_toneport *toneport) +static int toneport_reset_resume(struct usb_interface *interface) { - toneport_setup(toneport); + toneport_setup(usb_get_intfdata(interface)); + return line6_resume(interface); } +#endif + +#define LINE6_DEVICE(prod) USB_DEVICE(0x0e41, prod) +#define LINE6_IF_NUM(prod, n) USB_DEVICE_INTERFACE_NUMBER(0x0e41, prod, n) + +/* table of devices that work with this driver */ +static const struct usb_device_id toneport_id_table[] = { + { LINE6_DEVICE(0x4750), .driver_info = LINE6_GUITARPORT }, + { LINE6_DEVICE(0x4153), .driver_info = LINE6_PODSTUDIO_GX }, + { LINE6_DEVICE(0x4150), .driver_info = LINE6_PODSTUDIO_UX1 }, + { LINE6_IF_NUM(0x4151, 0), .driver_info = LINE6_PODSTUDIO_UX2 }, + { LINE6_DEVICE(0x4147), .driver_info = LINE6_TONEPORT_GX }, + { LINE6_DEVICE(0x4141), .driver_info = LINE6_TONEPORT_UX1 }, + { LINE6_IF_NUM(0x4142, 0), .driver_info = LINE6_TONEPORT_UX2 }, + {} +}; + +MODULE_DEVICE_TABLE(usb, toneport_id_table); + +static const struct line6_properties toneport_properties_table[] = { + [LINE6_GUITARPORT] = { + .id = "GuitarPort", + .name = "GuitarPort", + .capabilities = LINE6_CAP_PCM, + .altsetting = 2, /* 1..4 seem to be ok */ + /* no control channel */ + .ep_audio_r = 0x82, + .ep_audio_w = 0x01, + }, + [LINE6_PODSTUDIO_GX] = { + .id = "PODStudioGX", + .name = "POD Studio GX", + .capabilities = LINE6_CAP_PCM, + .altsetting = 2, /* 1..4 seem to be ok */ + /* no control channel */ + .ep_audio_r = 0x82, + .ep_audio_w = 0x01, + }, + [LINE6_PODSTUDIO_UX1] = { + .id = "PODStudioUX1", + .name = "POD Studio UX1", + .capabilities = LINE6_CAP_PCM, + .altsetting = 2, /* 1..4 seem to be ok */ + /* no control channel */ + .ep_audio_r = 0x82, + .ep_audio_w = 0x01, + }, + [LINE6_PODSTUDIO_UX2] = { + .id = "PODStudioUX2", + .name = "POD Studio UX2", + .capabilities = LINE6_CAP_PCM, + .altsetting = 2, /* defaults to 44.1kHz, 16-bit */ + /* no control channel */ + .ep_audio_r = 0x82, + .ep_audio_w = 0x01, + }, + [LINE6_TONEPORT_GX] = { + .id = "TonePortGX", + .name = "TonePort GX", + .capabilities = LINE6_CAP_PCM, + .altsetting = 2, /* 1..4 seem to be ok */ + /* no control channel */ + .ep_audio_r = 0x82, + .ep_audio_w = 0x01, + }, + [LINE6_TONEPORT_UX1] = { + .id = "TonePortUX1", + .name = "TonePort UX1", + .capabilities = LINE6_CAP_PCM, + .altsetting = 2, /* 1..4 seem to be ok */ + /* no control channel */ + .ep_audio_r = 0x82, + .ep_audio_w = 0x01, + }, + [LINE6_TONEPORT_UX2] = { + .id = "TonePortUX2", + .name = "TonePort UX2", + .capabilities = LINE6_CAP_PCM, + .altsetting = 2, /* defaults to 44.1kHz, 16-bit */ + /* no control channel */ + .ep_audio_r = 0x82, + .ep_audio_w = 0x01, + }, +}; + +/* + Probe USB device. +*/ +static int toneport_probe(struct usb_interface *interface, + const struct usb_device_id *id) +{ + struct usb_line6_toneport *toneport; + int err; + + toneport = kzalloc(sizeof(*toneport), GFP_KERNEL); + if (!toneport) + return -ENODEV; + toneport->type = id->driver_info; + err = line6_probe(interface, &toneport->line6, + &toneport_properties_table[id->driver_info], + toneport_init); + if (err < 0) + kfree(toneport); + return err; +} + +static struct usb_driver toneport_driver = { + .name = KBUILD_MODNAME, + .probe = toneport_probe, + .disconnect = line6_disconnect, +#ifdef CONFIG_PM + .suspend = line6_suspend, + .resume = line6_resume, + .reset_resume = toneport_reset_resume, +#endif + .id_table = toneport_id_table, +}; + +module_usb_driver(toneport_driver); + +MODULE_DESCRIPTION("TonePort USB driver"); +MODULE_LICENSE("GPL"); diff --git a/sound/usb/line6/toneport.h b/sound/usb/line6/toneport.h deleted file mode 100644 index 8cb14426f6ae..000000000000 --- a/sound/usb/line6/toneport.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Line6 Linux USB driver - 0.9.1beta - * - * Copyright (C) 2004-2010 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. - * - */ - -#ifndef TONEPORT_H -#define TONEPORT_H - -#include -#include - -#include "driver.h" - -struct usb_line6_toneport { - /** - Generic Line6 USB data. - */ - struct usb_line6 line6; - - /** - Source selector. - */ - int source; - - /** - Serial number of device. - */ - int serial_number; - - /** - Firmware version (x 100). - */ - int firmware_version; - - /** - Timer for delayed PCM startup. - */ - struct timer_list timer; -}; - -extern int line6_toneport_init(struct usb_interface *interface, - struct usb_line6 *line6); -extern void line6_toneport_reset_resume(struct usb_line6_toneport *toneport); - -#endif diff --git a/sound/usb/line6/variax.c b/sound/usb/line6/variax.c index b4a41b0ad0ea..0c852bb1e76c 100644 --- a/sound/usb/line6/variax.c +++ b/sound/usb/line6/variax.c @@ -10,10 +10,65 @@ */ #include +#include +#include +#include +#include +#include #include "audio.h" #include "driver.h" -#include "variax.h" +#include "usbdefs.h" + +#define VARIAX_STARTUP_DELAY1 1000 +#define VARIAX_STARTUP_DELAY3 100 +#define VARIAX_STARTUP_DELAY4 100 + +/* + Stages of Variax startup procedure +*/ +enum { + VARIAX_STARTUP_INIT = 1, + VARIAX_STARTUP_VERSIONREQ, + VARIAX_STARTUP_WAIT, + VARIAX_STARTUP_ACTIVATE, + VARIAX_STARTUP_WORKQUEUE, + VARIAX_STARTUP_SETUP, + VARIAX_STARTUP_LAST = VARIAX_STARTUP_SETUP - 1 +}; + +enum { + LINE6_PODXTLIVE_VARIAX, + LINE6_VARIAX +}; + +struct usb_line6_variax { + /** + Generic Line6 USB data. + */ + struct usb_line6 line6; + + /** + Buffer for activation code. + */ + unsigned char *buffer_activate; + + /** + Handler for device initializaton. + */ + struct work_struct startup_work; + + /** + Timers for device initializaton. + */ + struct timer_list startup_timer1; + struct timer_list startup_timer2; + + /** + Current progress in startup procedure. + */ + int startup_progress; +}; #define VARIAX_OFFSET_ACTIVATE 7 @@ -228,7 +283,8 @@ static int variax_try_init(struct usb_interface *interface, /* Init workbench device (and clean up in case of failure). */ -int line6_variax_init(struct usb_interface *interface, struct usb_line6 *line6) +static int variax_init(struct usb_interface *interface, + struct usb_line6 *line6) { int err = variax_try_init(interface, line6); @@ -237,3 +293,76 @@ int line6_variax_init(struct usb_interface *interface, struct usb_line6 *line6) return err; } + +#define LINE6_DEVICE(prod) USB_DEVICE(0x0e41, prod) +#define LINE6_IF_NUM(prod, n) USB_DEVICE_INTERFACE_NUMBER(0x0e41, prod, n) + +/* table of devices that work with this driver */ +static const struct usb_device_id variax_id_table[] = { + { LINE6_IF_NUM(0x4650, 1), .driver_info = LINE6_PODXTLIVE_VARIAX }, + { LINE6_DEVICE(0x534d), .driver_info = LINE6_VARIAX }, + {} +}; + +MODULE_DEVICE_TABLE(usb, variax_id_table); + +static const struct line6_properties variax_properties_table[] = { + [LINE6_PODXTLIVE_VARIAX] = { + .id = "PODxtLive", + .name = "PODxt Live", + .capabilities = LINE6_CAP_CONTROL + | LINE6_CAP_PCM + | LINE6_CAP_HWMON, + .altsetting = 1, + .ep_ctrl_r = 0x86, + .ep_ctrl_w = 0x05, + .ep_audio_r = 0x82, + .ep_audio_w = 0x01, + }, + [LINE6_VARIAX] = { + .id = "Variax", + .name = "Variax Workbench", + .capabilities = LINE6_CAP_CONTROL, + .altsetting = 1, + .ep_ctrl_r = 0x82, + .ep_ctrl_w = 0x01, + /* no audio channel */ + } +}; + +/* + Probe USB device. +*/ +static int variax_probe(struct usb_interface *interface, + const struct usb_device_id *id) +{ + struct usb_line6_variax *variax; + int err; + + variax = kzalloc(sizeof(*variax), GFP_KERNEL); + if (!variax) + return -ENODEV; + err = line6_probe(interface, &variax->line6, + &variax_properties_table[id->driver_info], + variax_init); + if (err < 0) + kfree(variax); + return err; +} + +static struct usb_driver variax_driver = { + .name = KBUILD_MODNAME, + .probe = variax_probe, + .disconnect = line6_disconnect, +#ifdef CONFIG_PM + .suspend = line6_suspend, + .resume = line6_resume, + .reset_resume = line6_resume, +#endif + .id_table = variax_id_table, +}; + +module_usb_driver(variax_driver); + +MODULE_DESCRIPTION("Vairax Workbench USB driver"); +MODULE_LICENSE("GPL"); diff --git a/sound/usb/line6/variax.h b/sound/usb/line6/variax.h deleted file mode 100644 index dfb94e574cc4..000000000000 --- a/sound/usb/line6/variax.h +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Line6 Linux USB driver - 0.9.1beta - * - * Copyright (C) 2004-2010 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. - * - */ - -#ifndef VARIAX_H -#define VARIAX_H - -#include -#include -#include -#include - -#include "driver.h" - -#define VARIAX_STARTUP_DELAY1 1000 -#define VARIAX_STARTUP_DELAY3 100 -#define VARIAX_STARTUP_DELAY4 100 - -/* - Stages of Variax startup procedure -*/ -enum { - VARIAX_STARTUP_INIT = 1, - VARIAX_STARTUP_VERSIONREQ, - VARIAX_STARTUP_WAIT, - VARIAX_STARTUP_ACTIVATE, - VARIAX_STARTUP_WORKQUEUE, - VARIAX_STARTUP_SETUP, - VARIAX_STARTUP_LAST = VARIAX_STARTUP_SETUP - 1 -}; - -struct usb_line6_variax { - /** - Generic Line6 USB data. - */ - struct usb_line6 line6; - - /** - Buffer for activation code. - */ - unsigned char *buffer_activate; - - /** - Handler for device initializaton. - */ - struct work_struct startup_work; - - /** - Timers for device initializaton. - */ - struct timer_list startup_timer1; - struct timer_list startup_timer2; - - /** - Current progress in startup procedure. - */ - int startup_progress; -}; - -extern int line6_variax_init(struct usb_interface *interface, - struct usb_line6 *line6); - -#endif -- cgit v1.2.3 From 45a82f18913fd9b959f0703ed47750733840e92a Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 19 Jan 2015 15:02:30 +0100 Subject: ALSA: line6: Drop usb_device sysfs symlink It's non-standard and rather superfluous. Tested-by: Chris Rorvick Signed-off-by: Takashi Iwai --- sound/usb/line6/driver.c | 9 --------- 1 file changed, 9 deletions(-) (limited to 'sound/usb/line6/driver.c') diff --git a/sound/usb/line6/driver.c b/sound/usb/line6/driver.c index 149c393c7302..23d504f4b6bc 100644 --- a/sound/usb/line6/driver.c +++ b/sound/usb/line6/driver.c @@ -611,11 +611,6 @@ int line6_probe(struct usb_interface *interface, if (ret < 0) goto err_destruct; - ret = sysfs_create_link(&interface->dev.kobj, &usbdev->dev.kobj, - "usb_device"); - if (ret < 0) - goto err_destruct; - /* creation of additional special files should go here */ dev_info(&interface->dev, "Line6 %s now attached\n", @@ -649,10 +644,6 @@ void line6_disconnect(struct usb_interface *interface) if (usbdev == NULL) return; - /* removal of additional special files should go here */ - - sysfs_remove_link(&interface->dev.kobj, "usb_device"); - interface_number = interface->cur_altsetting->desc.bInterfaceNumber; line6 = usb_get_intfdata(interface); -- cgit v1.2.3 From a019f5e8c522f5b5f8b3419a1e56d142ea4c7621 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 19 Jan 2015 15:05:10 +0100 Subject: ALSA: line6: Remove superfluous out-of-memory error messages Kernel already shows the error in the common path. Tested-by: Chris Rorvick Signed-off-by: Takashi Iwai --- sound/usb/line6/capture.c | 4 +--- sound/usb/line6/driver.c | 6 +----- sound/usb/line6/midi.c | 5 +---- sound/usb/line6/playback.c | 4 +--- sound/usb/line6/variax.c | 4 +--- 5 files changed, 5 insertions(+), 18 deletions(-) (limited to 'sound/usb/line6/driver.c') diff --git a/sound/usb/line6/capture.c b/sound/usb/line6/capture.c index 1970ab57cb6f..727b31876d48 100644 --- a/sound/usb/line6/capture.c +++ b/sound/usb/line6/capture.c @@ -402,10 +402,8 @@ int line6_create_audio_in_urbs(struct snd_line6_pcm *line6pcm) urb = line6pcm->urb_audio_in[i] = usb_alloc_urb(LINE6_ISO_PACKETS, GFP_KERNEL); - if (urb == NULL) { - dev_err(line6->ifcdev, "Out of memory\n"); + if (urb == NULL) return -ENOMEM; - } urb->dev = line6->usbdev; urb->pipe = diff --git a/sound/usb/line6/driver.c b/sound/usb/line6/driver.c index 23d504f4b6bc..b8f5134dcec2 100644 --- a/sound/usb/line6/driver.c +++ b/sound/usb/line6/driver.c @@ -190,7 +190,6 @@ int line6_send_raw_message_async(struct usb_line6 *line6, const char *buffer, if (urb == NULL) { kfree(msg); - dev_err(line6->ifcdev, "Out of memory\n"); return -ENOMEM; } @@ -215,10 +214,8 @@ int line6_version_request_async(struct usb_line6 *line6) buffer = kmemdup(line6_request_version, sizeof(line6_request_version), GFP_ATOMIC); - if (buffer == NULL) { - dev_err(line6->ifcdev, "Out of memory"); + if (buffer == NULL) return -ENOMEM; - } retval = line6_send_raw_message_async(line6, buffer, sizeof(line6_request_version)); @@ -593,7 +590,6 @@ int line6_probe(struct usb_interface *interface, line6->urb_listen = usb_alloc_urb(0, GFP_KERNEL); if (line6->urb_listen == NULL) { - dev_err(&interface->dev, "Out of memory\n"); ret = -ENOMEM; goto err_destruct; } diff --git a/sound/usb/line6/midi.c b/sound/usb/line6/midi.c index ebca5ebcfecc..f333cef5d2d7 100644 --- a/sound/usb/line6/midi.c +++ b/sound/usb/line6/midi.c @@ -121,16 +121,13 @@ static int send_midi_async(struct usb_line6 *line6, unsigned char *data, urb = usb_alloc_urb(0, GFP_ATOMIC); - if (urb == NULL) { - dev_err(line6->ifcdev, "Out of memory\n"); + if (urb == NULL) return -ENOMEM; - } transfer_buffer = kmemdup(data, length, GFP_ATOMIC); if (transfer_buffer == NULL) { usb_free_urb(urb); - dev_err(line6->ifcdev, "Out of memory\n"); return -ENOMEM; } diff --git a/sound/usb/line6/playback.c b/sound/usb/line6/playback.c index 8fc2dedbeb52..5a7fe409a3b9 100644 --- a/sound/usb/line6/playback.c +++ b/sound/usb/line6/playback.c @@ -558,10 +558,8 @@ int line6_create_audio_out_urbs(struct snd_line6_pcm *line6pcm) urb = line6pcm->urb_audio_out[i] = usb_alloc_urb(LINE6_ISO_PACKETS, GFP_KERNEL); - if (urb == NULL) { - dev_err(line6->ifcdev, "Out of memory\n"); + if (urb == NULL) return -ENOMEM; - } urb->dev = line6->usbdev; urb->pipe = diff --git a/sound/usb/line6/variax.c b/sound/usb/line6/variax.c index 0c852bb1e76c..9a9c7e48e24f 100644 --- a/sound/usb/line6/variax.c +++ b/sound/usb/line6/variax.c @@ -260,10 +260,8 @@ static int variax_try_init(struct usb_interface *interface, variax->buffer_activate = kmemdup(variax_activate, sizeof(variax_activate), GFP_KERNEL); - if (variax->buffer_activate == NULL) { - dev_err(&interface->dev, "Out of memory\n"); + if (variax->buffer_activate == NULL) return -ENOMEM; - } /* initialize audio system: */ err = line6_init_audio(&variax->line6); -- cgit v1.2.3 From 85a9339becf0af4d547ceb6bb16d1893b05fbce4 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 19 Jan 2015 15:54:00 +0100 Subject: ALSA: line6: Reorganize card resource handling This is a fairly big rewrite regarding the card resource management in line6 drivers: - The card creation is moved into line6_probe(). This adds the global destructor to private_free, so that each driver doesn't have to call it any longer. - The USB disconnect callback handles the card release, thus each driver needs to concentrate on only its own resources. No need to snd_card_*() call in the destructor. - Fix the potential stall in disconnection by removing snd_card_free(). It's replaced with snd_card_free_when_closed() for asynchronous release. - The only remaining operation for the card in each driver is the call of snd_card_register(). All the rest are dealt in the common module by itself. - These ended up with removal of audio.[ch] as a result of a reduction of one layer. Each driver just needs to call line6_probe(). Tested-by: Chris Rorvick Signed-off-by: Takashi Iwai --- sound/usb/line6/Makefile | 1 - sound/usb/line6/audio.c | 74 ----------------------------------------- sound/usb/line6/audio.h | 21 ------------ sound/usb/line6/capture.c | 1 - sound/usb/line6/driver.c | 82 +++++++++++++++++++++++++++------------------- sound/usb/line6/midi.c | 1 - sound/usb/line6/pcm.c | 1 - sound/usb/line6/playback.c | 1 - sound/usb/line6/pod.c | 60 +++++---------------------------- sound/usb/line6/podhd.c | 75 ++++-------------------------------------- sound/usb/line6/toneport.c | 65 ++++-------------------------------- sound/usb/line6/variax.c | 58 ++++++++------------------------ 12 files changed, 85 insertions(+), 355 deletions(-) delete mode 100644 sound/usb/line6/audio.c delete mode 100644 sound/usb/line6/audio.h (limited to 'sound/usb/line6/driver.c') diff --git a/sound/usb/line6/Makefile b/sound/usb/line6/Makefile index fa3a78dac097..b8b3b2a543d8 100644 --- a/sound/usb/line6/Makefile +++ b/sound/usb/line6/Makefile @@ -1,5 +1,4 @@ snd-usb-line6-y := \ - audio.o \ capture.o \ driver.o \ midi.o \ diff --git a/sound/usb/line6/audio.c b/sound/usb/line6/audio.c deleted file mode 100644 index 95686e5af4bd..000000000000 --- a/sound/usb/line6/audio.c +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Line6 Linux USB driver - 0.9.1beta - * - * Copyright (C) 2004-2010 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 -#include -#include - -#include "driver.h" -#include "audio.h" - -/* - Initialize the Line6 USB audio system. -*/ -int line6_init_audio(struct usb_line6 *line6) -{ - struct snd_card *card; - int err; - - err = snd_card_new(line6->ifcdev, - SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1, - THIS_MODULE, 0, &card); - if (err < 0) - return err; - - line6->card = card; - - strcpy(card->id, line6->properties->id); - strcpy(card->driver, DRIVER_NAME); - strcpy(card->shortname, line6->properties->name); - /* longname is 80 chars - see asound.h */ - sprintf(card->longname, "Line6 %s at USB %s", line6->properties->name, - dev_name(line6->ifcdev)); - return 0; -} -EXPORT_SYMBOL_GPL(line6_init_audio); - -/* - Register the Line6 USB audio system. -*/ -int line6_register_audio(struct usb_line6 *line6) -{ - int err; - - err = snd_card_register(line6->card); - if (err < 0) - return err; - - return 0; -} -EXPORT_SYMBOL_GPL(line6_register_audio); - -/* - Cleanup the Line6 USB audio system. -*/ -void line6_cleanup_audio(struct usb_line6 *line6) -{ - struct snd_card *card = line6->card; - - if (card == NULL) - return; - - snd_card_disconnect(card); - snd_card_free(card); - line6->card = NULL; -} -EXPORT_SYMBOL_GPL(line6_cleanup_audio); diff --git a/sound/usb/line6/audio.h b/sound/usb/line6/audio.h deleted file mode 100644 index 5f8a09a0fa95..000000000000 --- a/sound/usb/line6/audio.h +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Line6 Linux USB driver - 0.9.1beta - * - * Copyright (C) 2004-2010 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. - * - */ - -#ifndef AUDIO_H -#define AUDIO_H - -#include "driver.h" - -extern void line6_cleanup_audio(struct usb_line6 *); -extern int line6_init_audio(struct usb_line6 *); -extern int line6_register_audio(struct usb_line6 *); - -#endif diff --git a/sound/usb/line6/capture.c b/sound/usb/line6/capture.c index 727b31876d48..e8c54ede9227 100644 --- a/sound/usb/line6/capture.c +++ b/sound/usb/line6/capture.c @@ -14,7 +14,6 @@ #include #include -#include "audio.h" #include "capture.h" #include "driver.h" #include "pcm.h" diff --git a/sound/usb/line6/driver.c b/sound/usb/line6/driver.c index b8f5134dcec2..8b6a658a8a58 100644 --- a/sound/usb/line6/driver.c +++ b/sound/usb/line6/driver.c @@ -15,7 +15,9 @@ #include #include -#include "audio.h" +#include +#include + #include "capture.h" #include "driver.h" #include "midi.h" @@ -481,17 +483,16 @@ ssize_t line6_nop_read(struct device *dev, struct device_attribute *attr, EXPORT_SYMBOL_GPL(line6_nop_read); /* - Generic destructor. + Card destructor. */ -static void line6_destruct(struct usb_interface *interface) +static void line6_destruct(struct snd_card *card) { - struct usb_line6 *line6; + struct usb_line6 *line6 = card->private_data; + struct usb_device *usbdev; - if (interface == NULL) - return; - line6 = usb_get_intfdata(interface); - if (line6 == NULL) + if (!line6) return; + usbdev = line6->usbdev; /* free buffer memory first: */ kfree(line6->buffer_message); @@ -500,8 +501,11 @@ static void line6_destruct(struct usb_interface *interface) /* 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); + + /* decrement reference counters: */ + usb_put_dev(usbdev); } /* @@ -513,6 +517,7 @@ int line6_probe(struct usb_interface *interface, int (*private_init)(struct usb_interface *, struct usb_line6 *)) { struct usb_device *usbdev; + struct snd_card *card; int interface_number; int ret; @@ -569,8 +574,26 @@ int line6_probe(struct usb_interface *interface, } } + ret = snd_card_new(line6->ifcdev, + SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1, + THIS_MODULE, 0, &card); + if (ret < 0) + goto err_put; + + line6->card = card; + strcpy(card->id, line6->properties->id); + strcpy(card->driver, DRIVER_NAME); + strcpy(card->shortname, line6->properties->name); + sprintf(card->longname, "Line6 %s at USB %s", line6->properties->name, + dev_name(line6->ifcdev)); + card->private_data = line6; + card->private_free = line6_destruct; + usb_set_intfdata(interface, line6); + /* increment reference counters: */ + usb_get_dev(usbdev); + if (properties->capabilities & LINE6_CAP_CONTROL) { /* initialize USB buffers: */ line6->buffer_listen = @@ -612,15 +635,11 @@ int line6_probe(struct usb_interface *interface, dev_info(&interface->dev, "Line6 %s now attached\n", line6->properties->name); - /* increment reference counters: */ - usb_get_intf(interface); - usb_get_dev(usbdev); - return 0; -err_destruct: - line6_destruct(interface); -err_put: + err_destruct: + snd_card_free(card); + err_put: return ret; } EXPORT_SYMBOL_GPL(line6_probe); @@ -642,29 +661,26 @@ void line6_disconnect(struct usb_interface *interface) interface_number = interface->cur_altsetting->desc.bInterfaceNumber; line6 = usb_get_intfdata(interface); + if (!line6) + return; - if (line6 != NULL) { - if (line6->urb_listen != NULL) - line6_stop_listen(line6); + if (line6->urb_listen != NULL) + line6_stop_listen(line6); - if (usbdev != line6->usbdev) - dev_err(line6->ifcdev, - "driver bug: inconsistent usb device\n"); + if (usbdev != line6->usbdev) + dev_err(line6->ifcdev, "driver bug: inconsistent usb device\n"); + snd_card_disconnect(line6->card); + if (line6->disconnect) line6->disconnect(interface); - dev_info(&interface->dev, "Line6 %s now disconnected\n", - line6->properties->name); - } - - line6_destruct(interface); + dev_info(&interface->dev, "Line6 %s now disconnected\n", + line6->properties->name); - /* free interface data: */ - kfree(line6); + /* make sure the device isn't destructed twice: */ + usb_set_intfdata(interface, NULL); - /* decrement reference counters: */ - usb_put_intf(interface); - usb_put_dev(usbdev); + snd_card_free_when_closed(line6->card); } EXPORT_SYMBOL_GPL(line6_disconnect); diff --git a/sound/usb/line6/midi.c b/sound/usb/line6/midi.c index f333cef5d2d7..68793cc5dc1e 100644 --- a/sound/usb/line6/midi.c +++ b/sound/usb/line6/midi.c @@ -15,7 +15,6 @@ #include #include -#include "audio.h" #include "driver.h" #include "midi.h" #include "usbdefs.h" diff --git a/sound/usb/line6/pcm.c b/sound/usb/line6/pcm.c index edab3cd7c048..1e77d0d9da17 100644 --- a/sound/usb/line6/pcm.c +++ b/sound/usb/line6/pcm.c @@ -16,7 +16,6 @@ #include #include -#include "audio.h" #include "capture.h" #include "driver.h" #include "playback.h" diff --git a/sound/usb/line6/playback.c b/sound/usb/line6/playback.c index 5a7fe409a3b9..ec2384c875a7 100644 --- a/sound/usb/line6/playback.c +++ b/sound/usb/line6/playback.c @@ -14,7 +14,6 @@ #include #include -#include "audio.h" #include "capture.h" #include "driver.h" #include "pcm.h" diff --git a/sound/usb/line6/pod.c b/sound/usb/line6/pod.c index d6bc5a1ab7f4..6b30deb6b157 100644 --- a/sound/usb/line6/pod.c +++ b/sound/usb/line6/pod.c @@ -18,7 +18,6 @@ #include #include -#include "audio.h" #include "capture.h" #include "driver.h" #include "playback.h" @@ -340,7 +339,7 @@ static void pod_startup4(struct work_struct *work) line6_read_serial_number(&pod->line6, &pod->serial_number); /* ALSA audio interface: */ - line6_register_audio(line6); + snd_card_register(line6->card); } /* POD special files: */ @@ -397,21 +396,6 @@ static struct snd_kcontrol_new pod_control_monitor = { .put = snd_pod_control_monitor_put }; -/* - POD destructor. -*/ -static void pod_destruct(struct usb_interface *interface) -{ - struct usb_line6_pod *pod = usb_get_intfdata(interface); - - if (pod == NULL) - return; - line6_cleanup_audio(&pod->line6); - - del_timer(&pod->startup_timer); - cancel_work_sync(&pod->startup_work); -} - /* POD device disconnected. */ @@ -424,21 +408,18 @@ static void line6_pod_disconnect(struct usb_interface *interface) pod = usb_get_intfdata(interface); if (pod != NULL) { - struct snd_line6_pcm *line6pcm = pod->line6.line6pcm; struct device *dev = &interface->dev; - if (line6pcm != NULL) - line6_pcm_disconnect(line6pcm); - if (dev != NULL) { /* remove sysfs entries: */ device_remove_file(dev, &dev_attr_device_id); device_remove_file(dev, &dev_attr_firmware_version); device_remove_file(dev, &dev_attr_serial_number); } - } - pod_destruct(interface); + del_timer_sync(&pod->startup_timer); + cancel_work_sync(&pod->startup_work); + } } /* @@ -457,8 +438,8 @@ static int pod_create_files2(struct device *dev) /* Try to init POD device. */ -static int pod_try_init(struct usb_interface *interface, - struct usb_line6 *line6) +static int pod_init(struct usb_interface *interface, + struct usb_line6 *line6) { int err; struct usb_line6_pod *pod = (struct usb_line6_pod *) line6; @@ -477,11 +458,6 @@ static int pod_try_init(struct usb_interface *interface, if (err < 0) return err; - /* initialize audio system: */ - err = line6_init_audio(line6); - if (err < 0) - return err; - /* initialize MIDI subsystem: */ err = line6_init_midi(line6); if (err < 0) @@ -514,20 +490,6 @@ static int pod_try_init(struct usb_interface *interface, return 0; } -/* - Init POD device (and clean up in case of failure). -*/ -static int pod_init(struct usb_interface *interface, - struct usb_line6 *line6) -{ - int err = pod_try_init(interface, line6); - - if (err < 0) - pod_destruct(interface); - - return err; -} - #define LINE6_DEVICE(prod) USB_DEVICE(0x0e41, prod) #define LINE6_IF_NUM(prod, n) USB_DEVICE_INTERFACE_NUMBER(0x0e41, prod, n) @@ -636,17 +598,13 @@ static int pod_probe(struct usb_interface *interface, const struct usb_device_id *id) { struct usb_line6_pod *pod; - int err; pod = kzalloc(sizeof(*pod), GFP_KERNEL); if (!pod) return -ENODEV; - err = line6_probe(interface, &pod->line6, - &pod_properties_table[id->driver_info], - pod_init); - if (err < 0) - kfree(pod); - return err; + return line6_probe(interface, &pod->line6, + &pod_properties_table[id->driver_info], + pod_init); } static struct usb_driver pod_driver = { diff --git a/sound/usb/line6/podhd.c b/sound/usb/line6/podhd.c index 8f4ca1d20b62..1d11185780e3 100644 --- a/sound/usb/line6/podhd.c +++ b/sound/usb/line6/podhd.c @@ -15,7 +15,6 @@ #include #include -#include "audio.h" #include "driver.h" #include "pcm.h" #include "usbdefs.h" @@ -85,58 +84,18 @@ static struct line6_pcm_properties podhd_pcm_properties = { .bytes_per_frame = PODHD_BYTES_PER_FRAME }; -/* - POD HD destructor. -*/ -static void podhd_destruct(struct usb_interface *interface) -{ - struct usb_line6_podhd *podhd = usb_get_intfdata(interface); - - if (podhd == NULL) - return; - line6_cleanup_audio(&podhd->line6); -} - -/* - POD HD device disconnected. -*/ -static void line6_podhd_disconnect(struct usb_interface *interface) -{ - struct usb_line6_podhd *podhd; - - if (interface == NULL) - return; - podhd = usb_get_intfdata(interface); - - if (podhd != NULL) { - struct snd_line6_pcm *line6pcm = podhd->line6.line6pcm; - - if (line6pcm != NULL) - line6_pcm_disconnect(line6pcm); - } - - podhd_destruct(interface); -} - /* Try to init POD HD device. */ -static int podhd_try_init(struct usb_interface *interface, - struct usb_line6_podhd *podhd) +static int podhd_init(struct usb_interface *interface, + struct usb_line6 *line6) { + struct usb_line6_podhd *podhd = (struct usb_line6_podhd *) line6; int err; - struct usb_line6 *line6 = &podhd->line6; if ((interface == NULL) || (podhd == NULL)) return -ENODEV; - line6->disconnect = line6_podhd_disconnect; - - /* initialize audio system: */ - err = line6_init_audio(line6); - if (err < 0) - return err; - /* initialize MIDI subsystem: */ err = line6_init_midi(line6); if (err < 0) @@ -148,8 +107,7 @@ static int podhd_try_init(struct usb_interface *interface, return err; /* register USB audio system: */ - err = line6_register_audio(line6); - return err; + return snd_card_register(line6->card); } #define LINE6_DEVICE(prod) USB_DEVICE(0x0e41, prod) @@ -217,21 +175,6 @@ static const struct line6_properties podhd_properties_table[] = { }, }; -/* - Init POD HD device (and clean up in case of failure). -*/ -static int podhd_init(struct usb_interface *interface, - struct usb_line6 *line6) -{ - struct usb_line6_podhd *podhd = (struct usb_line6_podhd *) line6; - int err = podhd_try_init(interface, podhd); - - if (err < 0) - podhd_destruct(interface); - - return err; -} - /* Probe USB device. */ @@ -239,17 +182,13 @@ static int podhd_probe(struct usb_interface *interface, const struct usb_device_id *id) { struct usb_line6_podhd *podhd; - int err; podhd = kzalloc(sizeof(*podhd), GFP_KERNEL); if (!podhd) return -ENODEV; - err = line6_probe(interface, &podhd->line6, - &podhd_properties_table[id->driver_info], - podhd_init); - if (err < 0) - kfree(podhd); - return err; + return line6_probe(interface, &podhd->line6, + &podhd_properties_table[id->driver_info], + podhd_init); } static struct usb_driver podhd_driver = { diff --git a/sound/usb/line6/toneport.c b/sound/usb/line6/toneport.c index 6ec3268a6153..3097a75a9bec 100644 --- a/sound/usb/line6/toneport.c +++ b/sound/usb/line6/toneport.c @@ -17,7 +17,6 @@ #include #include -#include "audio.h" #include "capture.h" #include "driver.h" #include "playback.h" @@ -330,18 +329,6 @@ static struct snd_kcontrol_new toneport_control_source = { .put = snd_toneport_source_put }; -/* - Toneport destructor. -*/ -static void toneport_destruct(struct usb_interface *interface) -{ - struct usb_line6_toneport *toneport = usb_get_intfdata(interface); - - if (toneport == NULL) - return; - line6_cleanup_audio(&toneport->line6); -} - /* Setup Toneport device. */ @@ -394,25 +381,14 @@ static void line6_toneport_disconnect(struct usb_interface *interface) device_remove_file(&interface->dev, &dev_attr_led_red); device_remove_file(&interface->dev, &dev_attr_led_green); } - - if (toneport != NULL) { - struct snd_line6_pcm *line6pcm = toneport->line6.line6pcm; - - if (line6pcm != NULL) { - line6_pcm_release(line6pcm, LINE6_BITS_PCM_MONITOR); - line6_pcm_disconnect(line6pcm); - } - } - - toneport_destruct(interface); } /* Try to init Toneport device. */ -static int toneport_try_init(struct usb_interface *interface, - struct usb_line6 *line6) +static int toneport_init(struct usb_interface *interface, + struct usb_line6 *line6) { int err; struct usb_line6_toneport *toneport = (struct usb_line6_toneport *) line6; @@ -422,11 +398,6 @@ static int toneport_try_init(struct usb_interface *interface, line6->disconnect = line6_toneport_disconnect; - /* initialize audio system: */ - err = line6_init_audio(line6); - if (err < 0) - return err; - /* initialize PCM subsystem: */ err = line6_init_pcm(line6, &toneport_pcm_properties); if (err < 0) @@ -456,11 +427,6 @@ static int toneport_try_init(struct usb_interface *interface, break; } - /* register audio system: */ - err = line6_register_audio(line6); - if (err < 0) - return err; - line6_read_serial_number(line6, &toneport->serial_number); line6_read_data(line6, 0x80c2, &toneport->firmware_version, 1); @@ -477,21 +443,8 @@ static int toneport_try_init(struct usb_interface *interface, (unsigned long)toneport); mod_timer(&toneport->timer, jiffies + TONEPORT_PCM_DELAY * HZ); - return 0; -} - -/* - Init Toneport device (and clean up in case of failure). -*/ -static int toneport_init(struct usb_interface *interface, - struct usb_line6 *line6) -{ - int err = toneport_try_init(interface, line6); - - if (err < 0) - toneport_destruct(interface); - - return err; + /* register audio system: */ + return snd_card_register(line6->card); } #ifdef CONFIG_PM @@ -595,18 +548,14 @@ static int toneport_probe(struct usb_interface *interface, const struct usb_device_id *id) { struct usb_line6_toneport *toneport; - int err; toneport = kzalloc(sizeof(*toneport), GFP_KERNEL); if (!toneport) return -ENODEV; toneport->type = id->driver_info; - err = line6_probe(interface, &toneport->line6, - &toneport_properties_table[id->driver_info], - toneport_init); - if (err < 0) - kfree(toneport); - return err; + return line6_probe(interface, &toneport->line6, + &toneport_properties_table[id->driver_info], + toneport_init); } static struct usb_driver toneport_driver = { diff --git a/sound/usb/line6/variax.c b/sound/usb/line6/variax.c index 9a9c7e48e24f..a591c2c5794f 100644 --- a/sound/usb/line6/variax.c +++ b/sound/usb/line6/variax.c @@ -16,7 +16,6 @@ #include #include -#include "audio.h" #include "driver.h" #include "usbdefs.h" @@ -179,7 +178,7 @@ static void variax_startup6(struct work_struct *work) CHECK_STARTUP_PROGRESS(variax->startup_progress, VARIAX_STARTUP_SETUP); /* ALSA audio interface: */ - line6_register_audio(&variax->line6); + snd_card_register(variax->line6.card); } /* @@ -211,13 +210,16 @@ static void line6_variax_process_message(struct usb_line6 *line6) /* Variax destructor. */ -static void variax_destruct(struct usb_interface *interface) +static void line6_variax_disconnect(struct usb_interface *interface) { - struct usb_line6_variax *variax = usb_get_intfdata(interface); + struct usb_line6_variax *variax; + + if (!interface) + return; - if (variax == NULL) + variax = usb_get_intfdata(interface); + if (!variax) return; - line6_cleanup_audio(&variax->line6); del_timer(&variax->startup_timer1); del_timer(&variax->startup_timer2); @@ -226,22 +228,11 @@ static void variax_destruct(struct usb_interface *interface) kfree(variax->buffer_activate); } -/* - Workbench device disconnected. -*/ -static void line6_variax_disconnect(struct usb_interface *interface) -{ - if (interface == NULL) - return; - - variax_destruct(interface); -} - /* Try to init workbench device. */ -static int variax_try_init(struct usb_interface *interface, - struct usb_line6 *line6) +static int variax_init(struct usb_interface *interface, + struct usb_line6 *line6) { struct usb_line6_variax *variax = (struct usb_line6_variax *) line6; int err; @@ -263,11 +254,6 @@ static int variax_try_init(struct usb_interface *interface, if (variax->buffer_activate == NULL) return -ENOMEM; - /* initialize audio system: */ - err = line6_init_audio(&variax->line6); - if (err < 0) - return err; - /* initialize MIDI subsystem: */ err = line6_init_midi(&variax->line6); if (err < 0) @@ -278,20 +264,6 @@ static int variax_try_init(struct usb_interface *interface, return 0; } -/* - Init workbench device (and clean up in case of failure). -*/ -static int variax_init(struct usb_interface *interface, - struct usb_line6 *line6) -{ - int err = variax_try_init(interface, line6); - - if (err < 0) - variax_destruct(interface); - - return err; -} - #define LINE6_DEVICE(prod) USB_DEVICE(0x0e41, prod) #define LINE6_IF_NUM(prod, n) USB_DEVICE_INTERFACE_NUMBER(0x0e41, prod, n) @@ -335,17 +307,13 @@ static int variax_probe(struct usb_interface *interface, const struct usb_device_id *id) { struct usb_line6_variax *variax; - int err; variax = kzalloc(sizeof(*variax), GFP_KERNEL); if (!variax) return -ENODEV; - err = line6_probe(interface, &variax->line6, - &variax_properties_table[id->driver_info], - variax_init); - if (err < 0) - kfree(variax); - return err; + return line6_probe(interface, &variax->line6, + &variax_properties_table[id->driver_info], + variax_init); } static struct usb_driver variax_driver = { -- cgit v1.2.3 From 2cd53fa9d38b98ea5ae4268e021c4f4cd68227a5 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 19 Jan 2015 16:02:36 +0100 Subject: ALSA: line6: Remove driver version string This is rather useless for a driver that has been already merged into the official tree. Tested-by: Chris Rorvick Signed-off-by: Takashi Iwai --- sound/usb/line6/driver.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'sound/usb/line6/driver.c') diff --git a/sound/usb/line6/driver.c b/sound/usb/line6/driver.c index 8b6a658a8a58..6a3ec07d869f 100644 --- a/sound/usb/line6/driver.c +++ b/sound/usb/line6/driver.c @@ -27,7 +27,6 @@ #define DRIVER_AUTHOR "Markus Grabner " #define DRIVER_DESC "Line6 USB Driver" -#define DRIVER_VERSION "0.9.1beta" DRIVER_REVISION /* This is Line6's MIDI manufacturer ID. @@ -729,4 +728,3 @@ EXPORT_SYMBOL_GPL(line6_resume); MODULE_AUTHOR(DRIVER_AUTHOR); MODULE_DESCRIPTION(DRIVER_DESC); MODULE_LICENSE("GPL"); -MODULE_VERSION(DRIVER_VERSION); -- cgit v1.2.3 From 31ca192139a152fcc550b9ebfb0e2d2d6247585e Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 19 Jan 2015 16:12:19 +0100 Subject: ALSA: line6: Remove superfluous disconnect call in suspend handler Calling line6_pcm_disconnect() at suspend callback is superfluous and rather confusing. Let's get rid of it. Tested-by: Chris Rorvick Signed-off-by: Takashi Iwai --- sound/usb/line6/driver.c | 1 - 1 file changed, 1 deletion(-) (limited to 'sound/usb/line6/driver.c') diff --git a/sound/usb/line6/driver.c b/sound/usb/line6/driver.c index 6a3ec07d869f..f222d9ffeca5 100644 --- a/sound/usb/line6/driver.c +++ b/sound/usb/line6/driver.c @@ -700,7 +700,6 @@ int line6_suspend(struct usb_interface *interface, pm_message_t message) if (line6pcm != NULL) { snd_pcm_suspend_all(line6pcm->pcm); - line6_pcm_disconnect(line6pcm); line6pcm->flags = 0; } -- cgit v1.2.3 From 5a4753112afc4d418ec6023bac757a9ec3eb7a32 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 19 Jan 2015 16:15:54 +0100 Subject: ALSA: line6: Sync PCM stop at disconnect Call line6_pcm_disconnect() at disconnect to make sure that all URBs are cleared. Also reduce the superfluous snd_pcm_stop() calls from the function (and remove the unused function) since the streams are guaranteed to be stopped at this point via snd_card_disconnect(). Tested-by: Chris Rorvick Signed-off-by: Takashi Iwai --- sound/usb/line6/driver.c | 2 ++ sound/usb/line6/pcm.c | 19 +------------------ 2 files changed, 3 insertions(+), 18 deletions(-) (limited to 'sound/usb/line6/driver.c') diff --git a/sound/usb/line6/driver.c b/sound/usb/line6/driver.c index f222d9ffeca5..1193d16396a0 100644 --- a/sound/usb/line6/driver.c +++ b/sound/usb/line6/driver.c @@ -670,6 +670,8 @@ void line6_disconnect(struct usb_interface *interface) dev_err(line6->ifcdev, "driver bug: inconsistent usb device\n"); snd_card_disconnect(line6->card); + if (line6->line6pcm) + line6_pcm_disconnect(line6->line6pcm); if (line6->disconnect) line6->disconnect(interface); diff --git a/sound/usb/line6/pcm.c b/sound/usb/line6/pcm.c index 39034c7681da..08fa9753a680 100644 --- a/sound/usb/line6/pcm.c +++ b/sound/usb/line6/pcm.c @@ -379,30 +379,13 @@ static int snd_line6_new_pcm(struct usb_line6 *line6, struct snd_pcm **pcm_ret) } /* - Stop substream if still running. -*/ -static void pcm_disconnect_substream(struct snd_pcm_substream *substream) -{ - if (substream->runtime && snd_pcm_running(substream)) { - snd_pcm_stream_lock_irq(substream); - snd_pcm_stop(substream, SNDRV_PCM_STATE_DISCONNECTED); - snd_pcm_stream_unlock_irq(substream); - } -} - -/* - Stop PCM stream. + Sync with PCM stream stops. */ void line6_pcm_disconnect(struct snd_line6_pcm *line6pcm) { - pcm_disconnect_substream(get_substream - (line6pcm, SNDRV_PCM_STREAM_CAPTURE)); - pcm_disconnect_substream(get_substream - (line6pcm, SNDRV_PCM_STREAM_PLAYBACK)); line6_unlink_wait_clear_audio_out_urbs(line6pcm); line6_unlink_wait_clear_audio_in_urbs(line6pcm); } -EXPORT_SYMBOL_GPL(line6_pcm_disconnect); /* Create and register the PCM device and mixer entries. -- cgit v1.2.3 From 73723190282d2d6dcb831b3d98f760337d83408c Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 19 Jan 2015 16:36:21 +0100 Subject: ALSA: line6: Make line6_send_raw_message() static It's used only locally. Tested-by: Chris Rorvick Signed-off-by: Takashi Iwai --- sound/usb/line6/driver.c | 4 ++-- sound/usb/line6/driver.h | 2 -- 2 files changed, 2 insertions(+), 4 deletions(-) (limited to 'sound/usb/line6/driver.c') diff --git a/sound/usb/line6/driver.c b/sound/usb/line6/driver.c index 1193d16396a0..a2f72cc2bf96 100644 --- a/sound/usb/line6/driver.c +++ b/sound/usb/line6/driver.c @@ -88,8 +88,8 @@ static void line6_stop_listen(struct usb_line6 *line6) /* Send raw message in pieces of wMaxPacketSize bytes. */ -int line6_send_raw_message(struct usb_line6 *line6, const char *buffer, - int size) +static int line6_send_raw_message(struct usb_line6 *line6, const char *buffer, + int size) { int i, done = 0; diff --git a/sound/usb/line6/driver.h b/sound/usb/line6/driver.h index f484aa09840b..8fd65f2e1f06 100644 --- a/sound/usb/line6/driver.h +++ b/sound/usb/line6/driver.h @@ -169,8 +169,6 @@ extern int line6_read_data(struct usb_line6 *line6, int address, void *data, extern int line6_read_serial_number(struct usb_line6 *line6, int *serial_number); extern int line6_send_program(struct usb_line6 *line6, u8 value); -extern int line6_send_raw_message(struct usb_line6 *line6, const char *buffer, - int size); extern int line6_send_raw_message_async(struct usb_line6 *line6, const char *buffer, int size); extern int line6_send_sysex_message(struct usb_line6 *line6, -- cgit v1.2.3 From 4d79fb1ed2487f204a185b59895e9a92ac4b475a Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 19 Jan 2015 16:38:23 +0100 Subject: ALSA: line6: Drop line6_send_program() and line6_transmit_parameter() Both functions are used nowhere. Tested-by: Chris Rorvick Signed-off-by: Takashi Iwai --- sound/usb/line6/driver.c | 59 ------------------------------------------------ sound/usb/line6/driver.h | 3 --- 2 files changed, 62 deletions(-) (limited to 'sound/usb/line6/driver.c') diff --git a/sound/usb/line6/driver.c b/sound/usb/line6/driver.c index a2f72cc2bf96..a3da18b876d1 100644 --- a/sound/usb/line6/driver.c +++ b/sound/usb/line6/driver.c @@ -298,65 +298,6 @@ static void line6_data_received(struct urb *urb) line6_start_listen(line6); } -/* - Send channel number (i.e., switch to a different sound). -*/ -int line6_send_program(struct usb_line6 *line6, u8 value) -{ - int retval; - unsigned char *buffer; - int partial; - - buffer = kmalloc(2, GFP_KERNEL); - if (!buffer) - return -ENOMEM; - - buffer[0] = LINE6_PROGRAM_CHANGE | LINE6_CHANNEL_HOST; - buffer[1] = value; - - retval = usb_interrupt_msg(line6->usbdev, - usb_sndintpipe(line6->usbdev, - line6->properties->ep_ctrl_w), - buffer, 2, &partial, LINE6_TIMEOUT * HZ); - - if (retval) - dev_err(line6->ifcdev, "usb_interrupt_msg failed (%d)\n", - retval); - - kfree(buffer); - return retval; -} - -/* - Transmit Line6 control parameter. -*/ -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) - return -ENOMEM; - - buffer[0] = LINE6_PARAM_CHANGE | LINE6_CHANNEL_HOST; - buffer[1] = param; - buffer[2] = value; - - retval = usb_interrupt_msg(line6->usbdev, - usb_sndintpipe(line6->usbdev, - line6->properties->ep_ctrl_w), - buffer, 3, &partial, LINE6_TIMEOUT * HZ); - - if (retval) - dev_err(line6->ifcdev, "usb_interrupt_msg failed (%d)\n", - retval); - - kfree(buffer); - return retval; -} - /* Read data from device. */ diff --git a/sound/usb/line6/driver.h b/sound/usb/line6/driver.h index 8fd65f2e1f06..d539c11d333d 100644 --- a/sound/usb/line6/driver.h +++ b/sound/usb/line6/driver.h @@ -168,7 +168,6 @@ extern int line6_read_data(struct usb_line6 *line6, int address, void *data, size_t datalen); extern int line6_read_serial_number(struct usb_line6 *line6, int *serial_number); -extern int line6_send_program(struct usb_line6 *line6, u8 value); extern int line6_send_raw_message_async(struct usb_line6 *line6, const char *buffer, int size); extern int line6_send_sysex_message(struct usb_line6 *line6, @@ -178,8 +177,6 @@ extern ssize_t line6_set_raw(struct device *dev, struct device_attribute *attr, extern void line6_start_timer(struct timer_list *timer, unsigned int msecs, void (*function)(unsigned long), unsigned long data); -extern int line6_transmit_parameter(struct usb_line6 *line6, int param, - u8 value); extern int line6_version_request_async(struct usb_line6 *line6); extern int line6_write_data(struct usb_line6 *line6, int address, void *data, size_t datalen); -- cgit v1.2.3 From 35ae48a3f40cff8a418b4f2061de3e2bc432e663 Mon Sep 17 00:00:00 2001 From: Chris Rorvick Date: Tue, 20 Jan 2015 02:20:48 -0600 Subject: ALSA: line6: Remove superfluous NULL checks Signed-off-by: Chris Rorvick Signed-off-by: Takashi Iwai --- sound/usb/line6/driver.c | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) (limited to 'sound/usb/line6/driver.c') diff --git a/sound/usb/line6/driver.c b/sound/usb/line6/driver.c index a3da18b876d1..3757b0c03054 100644 --- a/sound/usb/line6/driver.c +++ b/sound/usb/line6/driver.c @@ -456,21 +456,11 @@ int line6_probe(struct usb_interface *interface, const struct line6_properties *properties, int (*private_init)(struct usb_interface *, struct usb_line6 *)) { - struct usb_device *usbdev; + struct usb_device *usbdev = interface_to_usbdev(interface); struct snd_card *card; int interface_number; int ret; - if (!interface) { - ret = -ENODEV; - goto err_put; - } - usbdev = interface_to_usbdev(interface); - if (!usbdev) { - ret = -ENODEV; - goto err_put; - } - /* we don't handle multiple configurations */ if (usbdev->descriptor.bNumConfigurations != 1) { ret = -ENODEV; -- cgit v1.2.3 From c6fffce92e1a8cda8c1b552f5a24295839f3f93a Mon Sep 17 00:00:00 2001 From: Chris Rorvick Date: Tue, 20 Jan 2015 02:20:49 -0600 Subject: ALSA: line6: Refer to manufacturer as "Line 6" The correct spelling includes the space. Fix this in strings and comments that refer to the manufacturer. Signed-off-by: Chris Rorvick Signed-off-by: Takashi Iwai --- sound/usb/line6/Kconfig | 4 ++-- sound/usb/line6/capture.c | 2 +- sound/usb/line6/capture.h | 2 +- sound/usb/line6/driver.c | 24 ++++++++++++------------ sound/usb/line6/driver.h | 14 +++++++------- sound/usb/line6/midi.c | 6 +++--- sound/usb/line6/midi.h | 4 ++-- sound/usb/line6/midibuf.c | 4 ++-- sound/usb/line6/midibuf.h | 2 +- sound/usb/line6/pcm.c | 2 +- sound/usb/line6/pcm.h | 10 +++++----- sound/usb/line6/playback.c | 2 +- sound/usb/line6/playback.h | 2 +- sound/usb/line6/pod.c | 6 +++--- sound/usb/line6/podhd.c | 6 +++--- sound/usb/line6/toneport.c | 4 ++-- sound/usb/line6/usbdefs.h | 2 +- sound/usb/line6/variax.c | 4 ++-- 18 files changed, 50 insertions(+), 50 deletions(-) (limited to 'sound/usb/line6/driver.c') diff --git a/sound/usb/line6/Kconfig b/sound/usb/line6/Kconfig index 8287ae6a2c26..af20947e0bda 100644 --- a/sound/usb/line6/Kconfig +++ b/sound/usb/line6/Kconfig @@ -4,7 +4,7 @@ config SND_USB_LINE6 select SND_PCM config SND_USB_POD - tristate "Line6 POD USB support" + tristate "Line 6 POD USB support" select SND_USB_LINE6 help This is a driver for PODxt and other similar devices, @@ -21,7 +21,7 @@ config SND_USB_POD re-amping) config SND_USB_PODHD - tristate "Line6 POD HD300/400/500 USB support" + tristate "Line 6 POD HD300/400/500 USB support" select SND_USB_LINE6 help This is a driver for POD HD300, 400 and 500 devices. diff --git a/sound/usb/line6/capture.c b/sound/usb/line6/capture.c index e8c54ede9227..9da31175dfed 100644 --- a/sound/usb/line6/capture.c +++ b/sound/usb/line6/capture.c @@ -1,5 +1,5 @@ /* - * Line6 Linux USB driver - 0.9.1beta + * Line 6 Linux USB driver - 0.9.1beta * * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at) * diff --git a/sound/usb/line6/capture.h b/sound/usb/line6/capture.h index 4157bcb598a9..ff172fb5bad9 100644 --- a/sound/usb/line6/capture.h +++ b/sound/usb/line6/capture.h @@ -1,5 +1,5 @@ /* - * Line6 Linux USB driver - 0.9.1beta + * Line 6 Linux USB driver - 0.9.1beta * * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at) * diff --git a/sound/usb/line6/driver.c b/sound/usb/line6/driver.c index 3757b0c03054..c668e0755fc4 100644 --- a/sound/usb/line6/driver.c +++ b/sound/usb/line6/driver.c @@ -1,5 +1,5 @@ /* - * Line6 Linux USB driver - 0.9.1beta + * Line 6 Linux USB driver - 0.9.1beta * * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at) * @@ -26,10 +26,10 @@ #include "usbdefs.h" #define DRIVER_AUTHOR "Markus Grabner " -#define DRIVER_DESC "Line6 USB Driver" +#define DRIVER_DESC "Line 6 USB Driver" /* - This is Line6's MIDI manufacturer ID. + This is Line 6's MIDI manufacturer ID. */ const unsigned char line6_midi_id[] = { 0x00, 0x01, 0x0c @@ -260,7 +260,7 @@ char *line6_alloc_sysex_buffer(struct usb_line6 *line6, int code1, int code2, EXPORT_SYMBOL_GPL(line6_alloc_sysex_buffer); /* - Notification of data received from the Line6 device. + Notification of data received from the Line 6 device. */ static void line6_data_received(struct urb *urb) { @@ -402,7 +402,7 @@ int line6_write_data(struct usb_line6 *line6, int address, void *data, EXPORT_SYMBOL_GPL(line6_write_data); /* - Read Line6 device serial number. + Read Line 6 device serial number. (POD, TonePort, GuitarPort) */ int line6_read_serial_number(struct usb_line6 *line6, int *serial_number) @@ -468,7 +468,7 @@ int line6_probe(struct usb_interface *interface, } /* initialize device info: */ - dev_info(&interface->dev, "Line6 %s found\n", properties->name); + dev_info(&interface->dev, "Line 6 %s found\n", properties->name); /* query interface number */ interface_number = interface->cur_altsetting->desc.bInterfaceNumber; @@ -514,7 +514,7 @@ int line6_probe(struct usb_interface *interface, strcpy(card->id, line6->properties->id); strcpy(card->driver, DRIVER_NAME); strcpy(card->shortname, line6->properties->name); - sprintf(card->longname, "Line6 %s at USB %s", line6->properties->name, + sprintf(card->longname, "Line 6 %s at USB %s", line6->properties->name, dev_name(line6->ifcdev)); card->private_data = line6; card->private_free = line6_destruct; @@ -562,7 +562,7 @@ int line6_probe(struct usb_interface *interface, /* creation of additional special files should go here */ - dev_info(&interface->dev, "Line6 %s now attached\n", + dev_info(&interface->dev, "Line 6 %s now attached\n", line6->properties->name); return 0; @@ -575,7 +575,7 @@ int line6_probe(struct usb_interface *interface, EXPORT_SYMBOL_GPL(line6_probe); /* - Line6 device disconnected. + Line 6 device disconnected. */ void line6_disconnect(struct usb_interface *interface) { @@ -606,7 +606,7 @@ void line6_disconnect(struct usb_interface *interface) if (line6->disconnect) line6->disconnect(interface); - dev_info(&interface->dev, "Line6 %s now disconnected\n", + dev_info(&interface->dev, "Line 6 %s now disconnected\n", line6->properties->name); /* make sure the device isn't destructed twice: */ @@ -619,7 +619,7 @@ EXPORT_SYMBOL_GPL(line6_disconnect); #ifdef CONFIG_PM /* - Suspend Line6 device. + Suspend Line 6 device. */ int line6_suspend(struct usb_interface *interface, pm_message_t message) { @@ -641,7 +641,7 @@ int line6_suspend(struct usb_interface *interface, pm_message_t message) EXPORT_SYMBOL_GPL(line6_suspend); /* - Resume Line6 device. + Resume Line 6 device. */ int line6_resume(struct usb_interface *interface) { diff --git a/sound/usb/line6/driver.h b/sound/usb/line6/driver.h index d539c11d333d..ff52169bb5a1 100644 --- a/sound/usb/line6/driver.h +++ b/sound/usb/line6/driver.h @@ -1,5 +1,5 @@ /* - * Line6 Linux USB driver - 0.9.1beta + * Line 6 Linux USB driver - 0.9.1beta * * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at) * @@ -25,7 +25,7 @@ #define LINE6_MESSAGE_MAXLEN 256 /* - Line6 MIDI control commands + Line 6 MIDI control commands */ #define LINE6_PARAM_CHANGE 0xb0 #define LINE6_PROGRAM_CHANGE 0xc0 @@ -61,7 +61,7 @@ static const int SYSEX_DATA_OFS = sizeof(line6_midi_id) + 3; static const int SYSEX_EXTRA_SIZE = sizeof(line6_midi_id) + 4; /** - Common properties of Line6 devices. + Common properties of Line 6 devices. */ struct line6_properties { /** @@ -91,7 +91,7 @@ struct line6_properties { }; /** - Common data shared by all Line6 devices. + Common data shared by all Line 6 devices. Corresponds to a pair of USB endpoints. */ struct usb_line6 { @@ -121,18 +121,18 @@ struct usb_line6 { struct device *ifcdev; /** - Line6 sound card data structure. + Line 6 sound card data structure. Each device has at least MIDI or PCM. */ struct snd_card *card; /** - Line6 PCM device data structure. + Line 6 PCM device data structure. */ struct snd_line6_pcm *line6pcm; /** - Line6 MIDI device data structure. + Line 6 MIDI device data structure. */ struct snd_line6_midi *line6midi; diff --git a/sound/usb/line6/midi.c b/sound/usb/line6/midi.c index 68793cc5dc1e..64e242b9ce82 100644 --- a/sound/usb/line6/midi.c +++ b/sound/usb/line6/midi.c @@ -1,5 +1,5 @@ /* - * Line6 Linux USB driver - 0.9.1beta + * Line 6 Linux USB driver - 0.9.1beta * * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at) * @@ -226,7 +226,7 @@ static int snd_line6_new_midi(struct usb_line6 *line6, struct snd_rawmidi *rmidi; int err; - err = snd_rawmidi_new(line6->card, "Line6 MIDI", 0, 1, 1, rmidi_ret); + err = snd_rawmidi_new(line6->card, "Line 6 MIDI", 0, 1, 1, rmidi_ret); if (err < 0) return err; @@ -256,7 +256,7 @@ static void snd_line6_midi_free(struct snd_rawmidi *rmidi) } /* - Initialize the Line6 MIDI subsystem. + Initialize the Line 6 MIDI subsystem. */ int line6_init_midi(struct usb_line6 *line6) { diff --git a/sound/usb/line6/midi.h b/sound/usb/line6/midi.h index 78f903fb4d41..68e7d3a19139 100644 --- a/sound/usb/line6/midi.h +++ b/sound/usb/line6/midi.h @@ -1,5 +1,5 @@ /* - * Line6 Linux USB driver - 0.9.1beta + * Line 6 Linux USB driver - 0.9.1beta * * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at) * @@ -20,7 +20,7 @@ struct snd_line6_midi { /** - Pointer back to the Line6 driver data structure. + Pointer back to the Line 6 driver data structure. */ struct usb_line6 *line6; diff --git a/sound/usb/line6/midibuf.c b/sound/usb/line6/midibuf.c index 1ff856989fd6..55df0da5f919 100644 --- a/sound/usb/line6/midibuf.c +++ b/sound/usb/line6/midibuf.c @@ -1,5 +1,5 @@ /* - * Line6 Linux USB driver - 0.9.1beta + * Line 6 Linux USB driver - 0.9.1beta * * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at) * @@ -26,7 +26,7 @@ static int midibuf_message_length(unsigned char code) } else { /* Note that according to the MIDI specification 0xf2 is - the "Song Position Pointer", but this is used by Line6 + the "Song Position Pointer", but this is used by Line 6 to send sysex messages to the host. */ static const int length[] = { -1, 2, -1, 2, -1, -1, 1, 1, 1, 1, diff --git a/sound/usb/line6/midibuf.h b/sound/usb/line6/midibuf.h index 707482b940e4..18eed7565e05 100644 --- a/sound/usb/line6/midibuf.h +++ b/sound/usb/line6/midibuf.h @@ -1,5 +1,5 @@ /* - * Line6 Linux USB driver - 0.9.1beta + * Line 6 Linux USB driver - 0.9.1beta * * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at) * diff --git a/sound/usb/line6/pcm.c b/sound/usb/line6/pcm.c index 08fa9753a680..a31a86be2c77 100644 --- a/sound/usb/line6/pcm.c +++ b/sound/usb/line6/pcm.c @@ -1,5 +1,5 @@ /* - * Line6 Linux USB driver - 0.9.1beta + * Line 6 Linux USB driver - 0.9.1beta * * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at) * diff --git a/sound/usb/line6/pcm.h b/sound/usb/line6/pcm.h index 9328e6ffb191..715e84b3057c 100644 --- a/sound/usb/line6/pcm.h +++ b/sound/usb/line6/pcm.h @@ -1,5 +1,5 @@ /* - * Line6 Linux USB driver - 0.9.1beta + * Line 6 Linux USB driver - 0.9.1beta * * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at) * @@ -26,7 +26,7 @@ /* number of USB frames per URB - The Line6 Windows driver always transmits two frames per packet, but + The Line 6 Windows driver always transmits two frames per packet, but the Linux driver performs significantly better (i.e., lower latency) with only one frame per packet. */ @@ -38,7 +38,7 @@ #define LINE6_IMPULSE_DEFAULT_PERIOD 100 /* - Get substream from Line6 PCM data structure + Get substream from Line 6 PCM data structure */ #define get_substream(line6pcm, stream) \ (line6pcm->pcm->streams[stream].substream) @@ -46,7 +46,7 @@ /* PCM mode bits. - There are several features of the Line6 USB driver which require PCM + There are several features of the Line 6 USB driver which require PCM data to be exchanged with the device: *) PCM playback and capture via ALSA *) software monitoring (for devices without hardware monitoring) @@ -167,7 +167,7 @@ struct line6_pcm_properties { struct snd_line6_pcm { /** - Pointer back to the Line6 driver data structure. + Pointer back to the Line 6 driver data structure. */ struct usb_line6 *line6; diff --git a/sound/usb/line6/playback.c b/sound/usb/line6/playback.c index ec2384c875a7..660094b46753 100644 --- a/sound/usb/line6/playback.c +++ b/sound/usb/line6/playback.c @@ -1,5 +1,5 @@ /* - * Line6 Linux USB driver - 0.9.1beta + * Line 6 Linux USB driver - 0.9.1beta * * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at) * diff --git a/sound/usb/line6/playback.h b/sound/usb/line6/playback.h index 743bd6f74c57..0dfca5e42490 100644 --- a/sound/usb/line6/playback.h +++ b/sound/usb/line6/playback.h @@ -1,5 +1,5 @@ /* - * Line6 Linux USB driver - 0.9.1beta + * Line 6 Linux USB driver - 0.9.1beta * * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at) * diff --git a/sound/usb/line6/pod.c b/sound/usb/line6/pod.c index 6f4b09982589..7766f5349324 100644 --- a/sound/usb/line6/pod.c +++ b/sound/usb/line6/pod.c @@ -1,5 +1,5 @@ /* - * Line6 Linux USB driver - 0.9.1beta + * Line 6 Linux USB driver - 0.9.1beta * * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at) * @@ -59,7 +59,7 @@ enum { struct usb_line6_pod { /** - Generic Line6 USB data. + Generic Line 6 USB data. */ struct usb_line6 line6; @@ -627,5 +627,5 @@ static struct usb_driver pod_driver = { module_usb_driver(pod_driver); -MODULE_DESCRIPTION("Line6 POD USB driver"); +MODULE_DESCRIPTION("Line 6 POD USB driver"); MODULE_LICENSE("GPL"); diff --git a/sound/usb/line6/podhd.c b/sound/usb/line6/podhd.c index 1d11185780e3..7217fa7e5db1 100644 --- a/sound/usb/line6/podhd.c +++ b/sound/usb/line6/podhd.c @@ -1,5 +1,5 @@ /* - * Line6 Pod HD + * Line 6 Pod HD * * Copyright (C) 2011 Stefan Hajnoczi * @@ -28,7 +28,7 @@ enum { struct usb_line6_podhd { /** - Generic Line6 USB data. + Generic Line 6 USB data. */ struct usb_line6 line6; }; @@ -205,5 +205,5 @@ static struct usb_driver podhd_driver = { module_usb_driver(podhd_driver); -MODULE_DESCRIPTION("Line6 PODHD USB driver"); +MODULE_DESCRIPTION("Line 6 PODHD USB driver"); MODULE_LICENSE("GPL"); diff --git a/sound/usb/line6/toneport.c b/sound/usb/line6/toneport.c index 24544b7ab476..77ad98c1a948 100644 --- a/sound/usb/line6/toneport.c +++ b/sound/usb/line6/toneport.c @@ -1,5 +1,5 @@ /* - * Line6 Linux USB driver - 0.9.1beta + * Line 6 Linux USB driver - 0.9.1beta * * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at) * Emil Myhrman (emil.myhrman@gmail.com) @@ -34,7 +34,7 @@ enum line6_device_type { struct usb_line6_toneport { /** - Generic Line6 USB data. + Generic Line 6 USB data. */ struct usb_line6 line6; diff --git a/sound/usb/line6/usbdefs.h b/sound/usb/line6/usbdefs.h index f4d080e69abc..3aab2e7cbd63 100644 --- a/sound/usb/line6/usbdefs.h +++ b/sound/usb/line6/usbdefs.h @@ -1,5 +1,5 @@ /* - * Line6 Linux USB driver - 0.9.1beta + * Line 6 Linux USB driver - 0.9.1beta * * Copyright (C) 2005-2008 Markus Grabner (grabner@icg.tugraz.at) * diff --git a/sound/usb/line6/variax.c b/sound/usb/line6/variax.c index a591c2c5794f..5e4da466da50 100644 --- a/sound/usb/line6/variax.c +++ b/sound/usb/line6/variax.c @@ -1,5 +1,5 @@ /* - * Line6 Linux USB driver - 0.9.1beta + * Line 6 Linux USB driver - 0.9.1beta * * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at) * @@ -43,7 +43,7 @@ enum { struct usb_line6_variax { /** - Generic Line6 USB data. + Generic Line 6 USB data. */ struct usb_line6 line6; -- cgit v1.2.3 From c078a4aac2944cb9cac5cdb4e9a482623435578b Mon Sep 17 00:00:00 2001 From: Chris Rorvick Date: Tue, 20 Jan 2015 02:20:50 -0600 Subject: ALSA: line6: Remove driver version from header comment The driver version string was removed in an ealier commit for being useless. These are equally useless. Signed-off-by: Chris Rorvick Signed-off-by: Takashi Iwai --- sound/usb/line6/capture.c | 2 +- sound/usb/line6/capture.h | 2 +- sound/usb/line6/driver.c | 2 +- sound/usb/line6/driver.h | 2 +- sound/usb/line6/midi.c | 2 +- sound/usb/line6/midi.h | 2 +- sound/usb/line6/midibuf.c | 2 +- sound/usb/line6/midibuf.h | 2 +- sound/usb/line6/pcm.c | 2 +- sound/usb/line6/pcm.h | 2 +- sound/usb/line6/playback.c | 2 +- sound/usb/line6/playback.h | 2 +- sound/usb/line6/pod.c | 2 +- sound/usb/line6/toneport.c | 2 +- sound/usb/line6/usbdefs.h | 2 +- sound/usb/line6/variax.c | 2 +- 16 files changed, 16 insertions(+), 16 deletions(-) (limited to 'sound/usb/line6/driver.c') diff --git a/sound/usb/line6/capture.c b/sound/usb/line6/capture.c index 9da31175dfed..5a010ba163fa 100644 --- a/sound/usb/line6/capture.c +++ b/sound/usb/line6/capture.c @@ -1,5 +1,5 @@ /* - * Line 6 Linux USB driver - 0.9.1beta + * Line 6 Linux USB driver * * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at) * diff --git a/sound/usb/line6/capture.h b/sound/usb/line6/capture.h index ff172fb5bad9..0939f400a405 100644 --- a/sound/usb/line6/capture.h +++ b/sound/usb/line6/capture.h @@ -1,5 +1,5 @@ /* - * Line 6 Linux USB driver - 0.9.1beta + * Line 6 Linux USB driver * * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at) * diff --git a/sound/usb/line6/driver.c b/sound/usb/line6/driver.c index c668e0755fc4..93cd4daa56bc 100644 --- a/sound/usb/line6/driver.c +++ b/sound/usb/line6/driver.c @@ -1,5 +1,5 @@ /* - * Line 6 Linux USB driver - 0.9.1beta + * Line 6 Linux USB driver * * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at) * diff --git a/sound/usb/line6/driver.h b/sound/usb/line6/driver.h index ff52169bb5a1..efd58ac3215b 100644 --- a/sound/usb/line6/driver.h +++ b/sound/usb/line6/driver.h @@ -1,5 +1,5 @@ /* - * Line 6 Linux USB driver - 0.9.1beta + * Line 6 Linux USB driver * * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at) * diff --git a/sound/usb/line6/midi.c b/sound/usb/line6/midi.c index 64e242b9ce82..b5a58a7fe11a 100644 --- a/sound/usb/line6/midi.c +++ b/sound/usb/line6/midi.c @@ -1,5 +1,5 @@ /* - * Line 6 Linux USB driver - 0.9.1beta + * Line 6 Linux USB driver * * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at) * diff --git a/sound/usb/line6/midi.h b/sound/usb/line6/midi.h index 68e7d3a19139..ba6bf3828aa5 100644 --- a/sound/usb/line6/midi.h +++ b/sound/usb/line6/midi.h @@ -1,5 +1,5 @@ /* - * Line 6 Linux USB driver - 0.9.1beta + * Line 6 Linux USB driver * * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at) * diff --git a/sound/usb/line6/midibuf.c b/sound/usb/line6/midibuf.c index 55df0da5f919..b5c4d79de031 100644 --- a/sound/usb/line6/midibuf.c +++ b/sound/usb/line6/midibuf.c @@ -1,5 +1,5 @@ /* - * Line 6 Linux USB driver - 0.9.1beta + * Line 6 Linux USB driver * * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at) * diff --git a/sound/usb/line6/midibuf.h b/sound/usb/line6/midibuf.h index 18eed7565e05..05dbf11a4d63 100644 --- a/sound/usb/line6/midibuf.h +++ b/sound/usb/line6/midibuf.h @@ -1,5 +1,5 @@ /* - * Line 6 Linux USB driver - 0.9.1beta + * Line 6 Linux USB driver * * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at) * diff --git a/sound/usb/line6/pcm.c b/sound/usb/line6/pcm.c index a31a86be2c77..8a6059adef69 100644 --- a/sound/usb/line6/pcm.c +++ b/sound/usb/line6/pcm.c @@ -1,5 +1,5 @@ /* - * Line 6 Linux USB driver - 0.9.1beta + * Line 6 Linux USB driver * * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at) * diff --git a/sound/usb/line6/pcm.h b/sound/usb/line6/pcm.h index 715e84b3057c..c742b33666eb 100644 --- a/sound/usb/line6/pcm.h +++ b/sound/usb/line6/pcm.h @@ -1,5 +1,5 @@ /* - * Line 6 Linux USB driver - 0.9.1beta + * Line 6 Linux USB driver * * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at) * diff --git a/sound/usb/line6/playback.c b/sound/usb/line6/playback.c index 660094b46753..1c9f95a370ff 100644 --- a/sound/usb/line6/playback.c +++ b/sound/usb/line6/playback.c @@ -1,5 +1,5 @@ /* - * Line 6 Linux USB driver - 0.9.1beta + * Line 6 Linux USB driver * * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at) * diff --git a/sound/usb/line6/playback.h b/sound/usb/line6/playback.h index 0dfca5e42490..78a885113221 100644 --- a/sound/usb/line6/playback.h +++ b/sound/usb/line6/playback.h @@ -1,5 +1,5 @@ /* - * Line 6 Linux USB driver - 0.9.1beta + * Line 6 Linux USB driver * * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at) * diff --git a/sound/usb/line6/pod.c b/sound/usb/line6/pod.c index 7766f5349324..bf027fc70cba 100644 --- a/sound/usb/line6/pod.c +++ b/sound/usb/line6/pod.c @@ -1,5 +1,5 @@ /* - * Line 6 Linux USB driver - 0.9.1beta + * Line 6 Linux USB driver * * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at) * diff --git a/sound/usb/line6/toneport.c b/sound/usb/line6/toneport.c index 77ad98c1a948..c1f61cde52ab 100644 --- a/sound/usb/line6/toneport.c +++ b/sound/usb/line6/toneport.c @@ -1,5 +1,5 @@ /* - * Line 6 Linux USB driver - 0.9.1beta + * Line 6 Linux USB driver * * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at) * Emil Myhrman (emil.myhrman@gmail.com) diff --git a/sound/usb/line6/usbdefs.h b/sound/usb/line6/usbdefs.h index 3aab2e7cbd63..5ef7bcd24e18 100644 --- a/sound/usb/line6/usbdefs.h +++ b/sound/usb/line6/usbdefs.h @@ -1,5 +1,5 @@ /* - * Line 6 Linux USB driver - 0.9.1beta + * Line 6 Linux USB driver * * Copyright (C) 2005-2008 Markus Grabner (grabner@icg.tugraz.at) * diff --git a/sound/usb/line6/variax.c b/sound/usb/line6/variax.c index 5e4da466da50..99a58cbfd2da 100644 --- a/sound/usb/line6/variax.c +++ b/sound/usb/line6/variax.c @@ -1,5 +1,5 @@ /* - * Line 6 Linux USB driver - 0.9.1beta + * Line 6 Linux USB driver * * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at) * -- cgit v1.2.3 From 270fd9c7f91fe8be900ede740ceeaa4abefa5d98 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 20 Jan 2015 08:40:51 +0100 Subject: ALSA: line6: Yet more cleanup of superfluous NULL checks ... in line6_disconnect() as well. Tested-by: Chris Rorvick Signed-off-by: Takashi Iwai --- sound/usb/line6/driver.c | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) (limited to 'sound/usb/line6/driver.c') diff --git a/sound/usb/line6/driver.c b/sound/usb/line6/driver.c index 93cd4daa56bc..e8d51381ffdb 100644 --- a/sound/usb/line6/driver.c +++ b/sound/usb/line6/driver.c @@ -579,18 +579,9 @@ EXPORT_SYMBOL_GPL(line6_probe); */ void line6_disconnect(struct usb_interface *interface) { - struct usb_line6 *line6; - struct usb_device *usbdev; - int interface_number; - - if (interface == NULL) - return; - usbdev = interface_to_usbdev(interface); - if (usbdev == NULL) - return; + struct usb_line6 *line6 = usb_get_intfdata(interface); + struct usb_device *usbdev = interface_to_usbdev(interface); - interface_number = interface->cur_altsetting->desc.bInterfaceNumber; - line6 = usb_get_intfdata(interface); if (!line6) return; -- cgit v1.2.3 From 2a324fcdb568f4d7b0b65b271039beb987f6e1cd Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 20 Jan 2015 09:58:54 +0100 Subject: ALSA: line6: Abort if inconsistent usbdev is found at disconnect It's utterly unsafe to proceed further the disconnect procedure if the assigned usbdev is inconsistent with the expected object. Better to put a WARN_ON() for more cautions and abort immediately. Tested-by: Chris Rorvick Signed-off-by: Takashi Iwai --- sound/usb/line6/driver.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'sound/usb/line6/driver.c') diff --git a/sound/usb/line6/driver.c b/sound/usb/line6/driver.c index e8d51381ffdb..625272fe227a 100644 --- a/sound/usb/line6/driver.c +++ b/sound/usb/line6/driver.c @@ -585,12 +585,12 @@ void line6_disconnect(struct usb_interface *interface) if (!line6) return; + if (WARN_ON(usbdev != line6->usbdev)) + return; + if (line6->urb_listen != NULL) line6_stop_listen(line6); - if (usbdev != line6->usbdev) - dev_err(line6->ifcdev, "driver bug: inconsistent usb device\n"); - snd_card_disconnect(line6->card); if (line6->line6pcm) line6_pcm_disconnect(line6->line6pcm); -- cgit v1.2.3 From eedd0e95d355c7bc09df1481ef92511f631832b3 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 20 Jan 2015 09:09:27 +0100 Subject: ALSA: line6: Don't forget to call driver's destructor at error path Currently disconnect callback is used as a driver's destructor, and this has to be called not only at the disconnection time but also at the error paths during probe. Tested-by: Chris Rorvick Signed-off-by: Takashi Iwai --- sound/usb/line6/driver.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'sound/usb/line6/driver.c') diff --git a/sound/usb/line6/driver.c b/sound/usb/line6/driver.c index 625272fe227a..e7f9a99e1949 100644 --- a/sound/usb/line6/driver.c +++ b/sound/usb/line6/driver.c @@ -568,6 +568,8 @@ int line6_probe(struct usb_interface *interface, return 0; err_destruct: + if (line6->disconnect) + line6->disconnect(interface); snd_card_free(card); err_put: return ret; -- cgit v1.2.3 From 644d90850c65c6ac5698e4fadb01682196a25eea Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 23 Jan 2015 12:24:03 +0100 Subject: ALSA: line6: Minor refactoring Split some codes in the lengthy line6_probe(). Tested-by: Chris Rorvick Signed-off-by: Takashi Iwai --- sound/usb/line6/driver.c | 94 +++++++++++++++++++++++++----------------------- 1 file changed, 49 insertions(+), 45 deletions(-) (limited to 'sound/usb/line6/driver.c') diff --git a/sound/usb/line6/driver.c b/sound/usb/line6/driver.c index e7f9a99e1949..b783c0788e45 100644 --- a/sound/usb/line6/driver.c +++ b/sound/usb/line6/driver.c @@ -448,6 +448,52 @@ static void line6_destruct(struct snd_card *card) usb_put_dev(usbdev); } +/* get data from endpoint descriptor (see usb_maxpacket): */ +static void line6_get_interval(struct usb_line6 *line6) +{ + struct usb_device *usbdev = line6->usbdev; + struct usb_host_endpoint *ep; + unsigned pipe = usb_rcvintpipe(usbdev, line6->properties->ep_ctrl_r); + unsigned epnum = usb_pipeendpoint(pipe); + + ep = usbdev->ep_in[epnum]; + if (ep) { + line6->interval = ep->desc.bInterval; + line6->max_packet_size = le16_to_cpu(ep->desc.wMaxPacketSize); + } else { + dev_err(line6->ifcdev, + "endpoint not available, using fallback values"); + line6->interval = LINE6_FALLBACK_INTERVAL; + line6->max_packet_size = LINE6_FALLBACK_MAXPACKETSIZE; + } +} + +static int line6_init_cap_control(struct usb_line6 *line6) +{ + int ret; + + /* initialize USB buffers: */ + line6->buffer_listen = kmalloc(LINE6_BUFSIZE_LISTEN, GFP_KERNEL); + if (!line6->buffer_listen) + return -ENOMEM; + + line6->buffer_message = kmalloc(LINE6_MESSAGE_MAXLEN, GFP_KERNEL); + if (!line6->buffer_message) + return -ENOMEM; + + line6->urb_listen = usb_alloc_urb(0, GFP_KERNEL); + if (!line6->urb_listen) + return -ENOMEM; + + ret = line6_start_listen(line6); + if (ret < 0) { + dev_err(line6->ifcdev, "cannot start listening: %d\n", ret); + return ret; + } + + return 0; +} + /* Probe USB device. */ @@ -485,24 +531,7 @@ int line6_probe(struct usb_interface *interface, line6->usbdev = usbdev; line6->ifcdev = &interface->dev; - /* get data from endpoint descriptor (see usb_maxpacket): */ - { - struct usb_host_endpoint *ep; - unsigned pipe = usb_rcvintpipe(usbdev, properties->ep_ctrl_r); - unsigned epnum = usb_pipeendpoint(pipe); - 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"); - } - } + line6_get_interval(line6); ret = snd_card_new(line6->ifcdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1, @@ -525,34 +554,9 @@ int line6_probe(struct usb_interface *interface, usb_get_dev(usbdev); if (properties->capabilities & LINE6_CAP_CONTROL) { - /* initialize USB buffers: */ - line6->buffer_listen = - kmalloc(LINE6_BUFSIZE_LISTEN, GFP_KERNEL); - if (line6->buffer_listen == NULL) { - ret = -ENOMEM; - goto err_destruct; - } - - line6->buffer_message = - kmalloc(LINE6_MESSAGE_MAXLEN, GFP_KERNEL); - if (line6->buffer_message == NULL) { - ret = -ENOMEM; + ret = line6_init_cap_control(line6); + if (ret < 0) goto err_destruct; - } - - line6->urb_listen = usb_alloc_urb(0, GFP_KERNEL); - - if (line6->urb_listen == NULL) { - ret = -ENOMEM; - goto err_destruct; - } - - ret = line6_start_listen(line6); - if (ret < 0) { - dev_err(&interface->dev, "%s: usb_submit_urb failed\n", - __func__); - goto err_destruct; - } } /* initialize device data based on device: */ -- cgit v1.2.3 From 6b562f63dd603443c97c885daa2b88bff700b2dc Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 23 Jan 2015 12:27:39 +0100 Subject: ALSA: line6: Fix memory leak at probe error path Fix memory leak at probe error path by rearranging the call order in line6_destruct() so that the common destructor is always called. Also this simplifies the error path to a single goto label. Tested-by: Chris Rorvick Signed-off-by: Takashi Iwai --- sound/usb/line6/driver.c | 59 ++++++++++++++++++++++++------------------------ 1 file changed, 30 insertions(+), 29 deletions(-) (limited to 'sound/usb/line6/driver.c') diff --git a/sound/usb/line6/driver.c b/sound/usb/line6/driver.c index b783c0788e45..bf9630cd2395 100644 --- a/sound/usb/line6/driver.c +++ b/sound/usb/line6/driver.c @@ -507,39 +507,20 @@ int line6_probe(struct usb_interface *interface, int interface_number; int ret; - /* we don't handle multiple configurations */ - if (usbdev->descriptor.bNumConfigurations != 1) { - ret = -ENODEV; - goto err_put; - } - - /* initialize device info: */ - dev_info(&interface->dev, "Line 6 %s found\n", properties->name); - - /* query interface number */ - interface_number = interface->cur_altsetting->desc.bInterfaceNumber; - - ret = usb_set_interface(usbdev, interface_number, - properties->altsetting); + ret = snd_card_new(&interface->dev, + SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1, + THIS_MODULE, 0, &card); if (ret < 0) { - dev_err(&interface->dev, "set_interface failed\n"); - goto err_put; + kfree(line6); + return ret; } /* store basic data: */ + line6->card = card; line6->properties = properties; line6->usbdev = usbdev; line6->ifcdev = &interface->dev; - line6_get_interval(line6); - - ret = snd_card_new(line6->ifcdev, - SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1, - THIS_MODULE, 0, &card); - if (ret < 0) - goto err_put; - - line6->card = card; strcpy(card->id, line6->properties->id); strcpy(card->driver, DRIVER_NAME); strcpy(card->shortname, line6->properties->name); @@ -553,16 +534,37 @@ int line6_probe(struct usb_interface *interface, /* increment reference counters: */ usb_get_dev(usbdev); + /* we don't handle multiple configurations */ + if (usbdev->descriptor.bNumConfigurations != 1) { + ret = -ENODEV; + goto error; + } + + /* initialize device info: */ + dev_info(&interface->dev, "Line 6 %s found\n", properties->name); + + /* query interface number */ + interface_number = interface->cur_altsetting->desc.bInterfaceNumber; + + ret = usb_set_interface(usbdev, interface_number, + properties->altsetting); + if (ret < 0) { + dev_err(&interface->dev, "set_interface failed\n"); + goto error; + } + + line6_get_interval(line6); + if (properties->capabilities & LINE6_CAP_CONTROL) { ret = line6_init_cap_control(line6); if (ret < 0) - goto err_destruct; + goto error; } /* initialize device data based on device: */ ret = private_init(interface, line6); if (ret < 0) - goto err_destruct; + goto error; /* creation of additional special files should go here */ @@ -571,11 +573,10 @@ int line6_probe(struct usb_interface *interface, return 0; - err_destruct: + error: if (line6->disconnect) line6->disconnect(interface); snd_card_free(card); - err_put: return ret; } EXPORT_SYMBOL_GPL(line6_probe); -- cgit v1.2.3 From b55004f9fdee80de1b6982b3e99ebaeb7d1e7a6c Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 23 Jan 2015 12:30:48 +0100 Subject: ALSA: line6: Remove unused line6_nop_read() The function isn't used any longer after rewriting from sysfs to leds class in toneport.c. Tested-by: Chris Rorvick Signed-off-by: Takashi Iwai --- sound/usb/line6/driver.c | 10 ---------- sound/usb/line6/driver.h | 2 -- 2 files changed, 12 deletions(-) (limited to 'sound/usb/line6/driver.c') diff --git a/sound/usb/line6/driver.c b/sound/usb/line6/driver.c index bf9630cd2395..4d2d233d0505 100644 --- a/sound/usb/line6/driver.c +++ b/sound/usb/line6/driver.c @@ -412,16 +412,6 @@ int line6_read_serial_number(struct usb_line6 *line6, int *serial_number) } EXPORT_SYMBOL_GPL(line6_read_serial_number); -/* - No operation (i.e., unsupported). -*/ -ssize_t line6_nop_read(struct device *dev, struct device_attribute *attr, - char *buf) -{ - return 0; -} -EXPORT_SYMBOL_GPL(line6_nop_read); - /* Card destructor. */ diff --git a/sound/usb/line6/driver.h b/sound/usb/line6/driver.h index efd58ac3215b..a6c0b2f08ba8 100644 --- a/sound/usb/line6/driver.h +++ b/sound/usb/line6/driver.h @@ -162,8 +162,6 @@ struct usb_line6 { extern char *line6_alloc_sysex_buffer(struct usb_line6 *line6, int code1, int code2, int size); -extern ssize_t line6_nop_read(struct device *dev, - struct device_attribute *attr, char *buf); extern int line6_read_data(struct usb_line6 *line6, int address, void *data, size_t datalen); extern int line6_read_serial_number(struct usb_line6 *line6, -- cgit v1.2.3 From f66fd990c5db177d6b9f0eae301ca6b15882eb2e Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Sun, 25 Jan 2015 18:22:58 +0100 Subject: ALSA: line6: Drop interface argument from private_init and disconnect callbacks The interface argument is used just for retrieving the assigned device, which can be already found in line6->ifcdev. Drop them from the callbacks. Also, pass the usb id to private_init so that the driver can deal with it there. This is a preliminary work for the further cleanup to move the whole allocation into driver.c. Tested-by: Chris Rorvick Signed-off-by: Takashi Iwai --- sound/usb/line6/driver.c | 9 +++++---- sound/usb/line6/driver.h | 6 ++++-- sound/usb/line6/pod.c | 14 +++++++------- sound/usb/line6/podhd.c | 6 +++--- sound/usb/line6/toneport.c | 14 +++++++------- sound/usb/line6/variax.c | 12 +++++------- 6 files changed, 31 insertions(+), 30 deletions(-) (limited to 'sound/usb/line6/driver.c') diff --git a/sound/usb/line6/driver.c b/sound/usb/line6/driver.c index 4d2d233d0505..e2fbff05c1b1 100644 --- a/sound/usb/line6/driver.c +++ b/sound/usb/line6/driver.c @@ -488,9 +488,10 @@ static int line6_init_cap_control(struct usb_line6 *line6) Probe USB device. */ int line6_probe(struct usb_interface *interface, + const struct usb_device_id *id, struct usb_line6 *line6, const struct line6_properties *properties, - int (*private_init)(struct usb_interface *, struct usb_line6 *)) + int (*private_init)(struct usb_line6 *, const struct usb_device_id *id)) { struct usb_device *usbdev = interface_to_usbdev(interface); struct snd_card *card; @@ -552,7 +553,7 @@ int line6_probe(struct usb_interface *interface, } /* initialize device data based on device: */ - ret = private_init(interface, line6); + ret = private_init(line6, id); if (ret < 0) goto error; @@ -565,7 +566,7 @@ int line6_probe(struct usb_interface *interface, error: if (line6->disconnect) - line6->disconnect(interface); + line6->disconnect(line6); snd_card_free(card); return ret; } @@ -592,7 +593,7 @@ void line6_disconnect(struct usb_interface *interface) if (line6->line6pcm) line6_pcm_disconnect(line6->line6pcm); if (line6->disconnect) - line6->disconnect(interface); + line6->disconnect(line6); dev_info(&interface->dev, "Line 6 %s now disconnected\n", line6->properties->name); diff --git a/sound/usb/line6/driver.h b/sound/usb/line6/driver.h index a6c0b2f08ba8..4dc6c28e8224 100644 --- a/sound/usb/line6/driver.h +++ b/sound/usb/line6/driver.h @@ -157,7 +157,7 @@ struct usb_line6 { int message_length; void (*process_message)(struct usb_line6 *); - void (*disconnect)(struct usb_interface *); + void (*disconnect)(struct usb_line6 *line6); }; extern char *line6_alloc_sysex_buffer(struct usb_line6 *line6, int code1, @@ -180,9 +180,11 @@ extern int line6_write_data(struct usb_line6 *line6, int address, void *data, size_t datalen); int line6_probe(struct usb_interface *interface, + const struct usb_device_id *id, struct usb_line6 *line6, const struct line6_properties *properties, - int (*private_init)(struct usb_interface *, struct usb_line6 *)); + int (*private_init)(struct usb_line6 *, const struct usb_device_id *id)); + void line6_disconnect(struct usb_interface *interface); #ifdef CONFIG_PM diff --git a/sound/usb/line6/pod.c b/sound/usb/line6/pod.c index 26ecf26a33ec..d1e952fbcae7 100644 --- a/sound/usb/line6/pod.c +++ b/sound/usb/line6/pod.c @@ -399,10 +399,10 @@ static struct snd_kcontrol_new pod_control_monitor = { /* POD device disconnected. */ -static void line6_pod_disconnect(struct usb_interface *interface) +static void line6_pod_disconnect(struct usb_line6 *line6) { - struct usb_line6_pod *pod = usb_get_intfdata(interface); - struct device *dev = &interface->dev; + struct usb_line6_pod *pod = (struct usb_line6_pod *)line6; + struct device *dev = line6->ifcdev; /* remove sysfs entries: */ device_remove_file(dev, &dev_attr_device_id); @@ -435,8 +435,8 @@ static int pod_create_files2(struct device *dev) /* Try to init POD device. */ -static int pod_init(struct usb_interface *interface, - struct usb_line6 *line6) +static int pod_init(struct usb_line6 *line6, + const struct usb_device_id *id) { int err; struct usb_line6_pod *pod = (struct usb_line6_pod *) line6; @@ -448,7 +448,7 @@ static int pod_init(struct usb_interface *interface, INIT_WORK(&pod->startup_work, pod_startup4); /* create sysfs entries: */ - err = pod_create_files2(&interface->dev); + err = pod_create_files2(line6->ifcdev); if (err < 0) return err; @@ -596,7 +596,7 @@ static int pod_probe(struct usb_interface *interface, pod = kzalloc(sizeof(*pod), GFP_KERNEL); if (!pod) return -ENODEV; - return line6_probe(interface, &pod->line6, + return line6_probe(interface, id, &pod->line6, &pod_properties_table[id->driver_info], pod_init); } diff --git a/sound/usb/line6/podhd.c b/sound/usb/line6/podhd.c index 59abbd92624e..21d7edcfa272 100644 --- a/sound/usb/line6/podhd.c +++ b/sound/usb/line6/podhd.c @@ -87,8 +87,8 @@ static struct line6_pcm_properties podhd_pcm_properties = { /* Try to init POD HD device. */ -static int podhd_init(struct usb_interface *interface, - struct usb_line6 *line6) +static int podhd_init(struct usb_line6 *line6, + const struct usb_device_id *id) { int err; @@ -182,7 +182,7 @@ static int podhd_probe(struct usb_interface *interface, podhd = kzalloc(sizeof(*podhd), GFP_KERNEL); if (!podhd) return -ENODEV; - return line6_probe(interface, &podhd->line6, + return line6_probe(interface, id, &podhd->line6, &podhd_properties_table[id->driver_info], podhd_init); } diff --git a/sound/usb/line6/toneport.c b/sound/usb/line6/toneport.c index 9a769463f7bf..8e7020df0d10 100644 --- a/sound/usb/line6/toneport.c +++ b/sound/usb/line6/toneport.c @@ -387,11 +387,11 @@ static void toneport_setup(struct usb_line6_toneport *toneport) /* Toneport device disconnected. */ -static void line6_toneport_disconnect(struct usb_interface *interface) +static void line6_toneport_disconnect(struct usb_line6 *line6) { - struct usb_line6_toneport *toneport; + struct usb_line6_toneport *toneport = + (struct usb_line6_toneport *)line6; - toneport = usb_get_intfdata(interface); del_timer_sync(&toneport->timer); if (toneport_has_led(toneport->type)) @@ -402,12 +402,13 @@ static void line6_toneport_disconnect(struct usb_interface *interface) /* Try to init Toneport device. */ -static int toneport_init(struct usb_interface *interface, - struct usb_line6 *line6) +static int toneport_init(struct usb_line6 *line6, + const struct usb_device_id *id) { int err; struct usb_line6_toneport *toneport = (struct usb_line6_toneport *) line6; + toneport->type = id->driver_info; setup_timer(&toneport->timer, toneport_start_pcm, (unsigned long)toneport); @@ -562,8 +563,7 @@ static int toneport_probe(struct usb_interface *interface, toneport = kzalloc(sizeof(*toneport), GFP_KERNEL); if (!toneport) return -ENODEV; - toneport->type = id->driver_info; - return line6_probe(interface, &toneport->line6, + return line6_probe(interface, id, &toneport->line6, &toneport_properties_table[id->driver_info], toneport_init); } diff --git a/sound/usb/line6/variax.c b/sound/usb/line6/variax.c index cd3adeffde02..ba6e85eed2ba 100644 --- a/sound/usb/line6/variax.c +++ b/sound/usb/line6/variax.c @@ -210,11 +210,9 @@ static void line6_variax_process_message(struct usb_line6 *line6) /* Variax destructor. */ -static void line6_variax_disconnect(struct usb_interface *interface) +static void line6_variax_disconnect(struct usb_line6 *line6) { - struct usb_line6_variax *variax; - - variax = usb_get_intfdata(interface); + struct usb_line6_variax *variax = (struct usb_line6_variax *)line6; del_timer(&variax->startup_timer1); del_timer(&variax->startup_timer2); @@ -226,8 +224,8 @@ static void line6_variax_disconnect(struct usb_interface *interface) /* Try to init workbench device. */ -static int variax_init(struct usb_interface *interface, - struct usb_line6 *line6) +static int variax_init(struct usb_line6 *line6, + const struct usb_device_id *id) { struct usb_line6_variax *variax = (struct usb_line6_variax *) line6; int err; @@ -303,7 +301,7 @@ static int variax_probe(struct usb_interface *interface, variax = kzalloc(sizeof(*variax), GFP_KERNEL); if (!variax) return -ENODEV; - return line6_probe(interface, &variax->line6, + return line6_probe(interface, id, &variax->line6, &variax_properties_table[id->driver_info], variax_init); } -- cgit v1.2.3 From aca514b82356dcc3575da33453382bd27593aea1 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Sun, 25 Jan 2015 18:36:29 +0100 Subject: ALSA: line6: Let snd_card_new() allocate private data Instead of allocating the private data individually in each driver's probe at first, let snd_card_new() allocate the data that is called in line6_probe(). This simplifies the primary probe functions. Tested-by: Chris Rorvick Signed-off-by: Takashi Iwai --- sound/usb/line6/driver.c | 25 ++++++++++--------------- sound/usb/line6/driver.h | 4 ++-- sound/usb/line6/pod.c | 9 ++------- sound/usb/line6/podhd.c | 9 ++------- sound/usb/line6/toneport.c | 9 ++------- sound/usb/line6/variax.c | 9 ++------- 6 files changed, 20 insertions(+), 45 deletions(-) (limited to 'sound/usb/line6/driver.c') diff --git a/sound/usb/line6/driver.c b/sound/usb/line6/driver.c index e2fbff05c1b1..c696f9773cbb 100644 --- a/sound/usb/line6/driver.c +++ b/sound/usb/line6/driver.c @@ -418,11 +418,7 @@ EXPORT_SYMBOL_GPL(line6_read_serial_number); static void line6_destruct(struct snd_card *card) { struct usb_line6 *line6 = card->private_data; - struct usb_device *usbdev; - - if (!line6) - return; - usbdev = line6->usbdev; + struct usb_device *usbdev = line6->usbdev; /* free buffer memory first: */ kfree(line6->buffer_message); @@ -431,9 +427,6 @@ static void line6_destruct(struct snd_card *card) /* then free URBs: */ usb_free_urb(line6->urb_listen); - /* free interface data: */ - kfree(line6); - /* decrement reference counters: */ usb_put_dev(usbdev); } @@ -489,24 +482,27 @@ static int line6_init_cap_control(struct usb_line6 *line6) */ int line6_probe(struct usb_interface *interface, const struct usb_device_id *id, - struct usb_line6 *line6, const struct line6_properties *properties, - int (*private_init)(struct usb_line6 *, const struct usb_device_id *id)) + int (*private_init)(struct usb_line6 *, const struct usb_device_id *id), + size_t data_size) { struct usb_device *usbdev = interface_to_usbdev(interface); struct snd_card *card; + struct usb_line6 *line6; int interface_number; int ret; + if (WARN_ON(data_size < sizeof(*line6))) + return -EINVAL; + ret = snd_card_new(&interface->dev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1, - THIS_MODULE, 0, &card); - if (ret < 0) { - kfree(line6); + THIS_MODULE, data_size, &card); + if (ret < 0) return ret; - } /* store basic data: */ + line6 = card->private_data; line6->card = card; line6->properties = properties; line6->usbdev = usbdev; @@ -517,7 +513,6 @@ int line6_probe(struct usb_interface *interface, strcpy(card->shortname, line6->properties->name); sprintf(card->longname, "Line 6 %s at USB %s", line6->properties->name, dev_name(line6->ifcdev)); - card->private_data = line6; card->private_free = line6_destruct; usb_set_intfdata(interface, line6); diff --git a/sound/usb/line6/driver.h b/sound/usb/line6/driver.h index 4dc6c28e8224..fce10f12f0d3 100644 --- a/sound/usb/line6/driver.h +++ b/sound/usb/line6/driver.h @@ -181,9 +181,9 @@ extern int line6_write_data(struct usb_line6 *line6, int address, void *data, int line6_probe(struct usb_interface *interface, const struct usb_device_id *id, - struct usb_line6 *line6, const struct line6_properties *properties, - int (*private_init)(struct usb_line6 *, const struct usb_device_id *id)); + int (*private_init)(struct usb_line6 *, const struct usb_device_id *id), + size_t data_size); void line6_disconnect(struct usb_interface *interface); diff --git a/sound/usb/line6/pod.c b/sound/usb/line6/pod.c index d1e952fbcae7..6f7cd585f2d8 100644 --- a/sound/usb/line6/pod.c +++ b/sound/usb/line6/pod.c @@ -591,14 +591,9 @@ static const struct line6_properties pod_properties_table[] = { static int pod_probe(struct usb_interface *interface, const struct usb_device_id *id) { - struct usb_line6_pod *pod; - - pod = kzalloc(sizeof(*pod), GFP_KERNEL); - if (!pod) - return -ENODEV; - return line6_probe(interface, id, &pod->line6, + return line6_probe(interface, id, &pod_properties_table[id->driver_info], - pod_init); + pod_init, sizeof(struct usb_line6_pod)); } static struct usb_driver pod_driver = { diff --git a/sound/usb/line6/podhd.c b/sound/usb/line6/podhd.c index 21d7edcfa272..43c39886597e 100644 --- a/sound/usb/line6/podhd.c +++ b/sound/usb/line6/podhd.c @@ -177,14 +177,9 @@ static const struct line6_properties podhd_properties_table[] = { static int podhd_probe(struct usb_interface *interface, const struct usb_device_id *id) { - struct usb_line6_podhd *podhd; - - podhd = kzalloc(sizeof(*podhd), GFP_KERNEL); - if (!podhd) - return -ENODEV; - return line6_probe(interface, id, &podhd->line6, + return line6_probe(interface, id, &podhd_properties_table[id->driver_info], - podhd_init); + podhd_init, sizeof(struct usb_line6_podhd)); } static struct usb_driver podhd_driver = { diff --git a/sound/usb/line6/toneport.c b/sound/usb/line6/toneport.c index 8e7020df0d10..33d16ecf18a0 100644 --- a/sound/usb/line6/toneport.c +++ b/sound/usb/line6/toneport.c @@ -558,14 +558,9 @@ static const struct line6_properties toneport_properties_table[] = { static int toneport_probe(struct usb_interface *interface, const struct usb_device_id *id) { - struct usb_line6_toneport *toneport; - - toneport = kzalloc(sizeof(*toneport), GFP_KERNEL); - if (!toneport) - return -ENODEV; - return line6_probe(interface, id, &toneport->line6, + return line6_probe(interface, id, &toneport_properties_table[id->driver_info], - toneport_init); + toneport_init, sizeof(struct usb_line6_toneport)); } static struct usb_driver toneport_driver = { diff --git a/sound/usb/line6/variax.c b/sound/usb/line6/variax.c index ba6e85eed2ba..9701ffa61365 100644 --- a/sound/usb/line6/variax.c +++ b/sound/usb/line6/variax.c @@ -296,14 +296,9 @@ static const struct line6_properties variax_properties_table[] = { static int variax_probe(struct usb_interface *interface, const struct usb_device_id *id) { - struct usb_line6_variax *variax; - - variax = kzalloc(sizeof(*variax), GFP_KERNEL); - if (!variax) - return -ENODEV; - return line6_probe(interface, id, &variax->line6, + return line6_probe(interface, id, &variax_properties_table[id->driver_info], - variax_init); + variax_init, sizeof(struct usb_line6_variax)); } static struct usb_driver variax_driver = { -- cgit v1.2.3 From d6ca69d82522cb0e59777deea3673c85c7db7f45 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Sun, 25 Jan 2015 18:41:26 +0100 Subject: ALSA: line6: Minor tidy up in line6_probe() Move the check of multi configurations before snd_card_new() as a short path, and reduce superfluous pointer references. Tested-by: Chris Rorvick Signed-off-by: Takashi Iwai --- sound/usb/line6/driver.c | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) (limited to 'sound/usb/line6/driver.c') diff --git a/sound/usb/line6/driver.c b/sound/usb/line6/driver.c index c696f9773cbb..a0436993a167 100644 --- a/sound/usb/line6/driver.c +++ b/sound/usb/line6/driver.c @@ -495,6 +495,10 @@ int line6_probe(struct usb_interface *interface, if (WARN_ON(data_size < sizeof(*line6))) return -EINVAL; + /* we don't handle multiple configurations */ + if (usbdev->descriptor.bNumConfigurations != 1) + return -ENODEV; + ret = snd_card_new(&interface->dev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1, THIS_MODULE, data_size, &card); @@ -508,10 +512,10 @@ int line6_probe(struct usb_interface *interface, line6->usbdev = usbdev; line6->ifcdev = &interface->dev; - strcpy(card->id, line6->properties->id); + strcpy(card->id, properties->id); strcpy(card->driver, DRIVER_NAME); - strcpy(card->shortname, line6->properties->name); - sprintf(card->longname, "Line 6 %s at USB %s", line6->properties->name, + strcpy(card->shortname, properties->name); + sprintf(card->longname, "Line 6 %s at USB %s", properties->name, dev_name(line6->ifcdev)); card->private_free = line6_destruct; @@ -520,12 +524,6 @@ int line6_probe(struct usb_interface *interface, /* increment reference counters: */ usb_get_dev(usbdev); - /* we don't handle multiple configurations */ - if (usbdev->descriptor.bNumConfigurations != 1) { - ret = -ENODEV; - goto error; - } - /* initialize device info: */ dev_info(&interface->dev, "Line 6 %s found\n", properties->name); @@ -533,7 +531,7 @@ int line6_probe(struct usb_interface *interface, interface_number = interface->cur_altsetting->desc.bInterfaceNumber; ret = usb_set_interface(usbdev, interface_number, - properties->altsetting); + properties->altsetting); if (ret < 0) { dev_err(&interface->dev, "set_interface failed\n"); goto error; @@ -555,7 +553,7 @@ int line6_probe(struct usb_interface *interface, /* creation of additional special files should go here */ dev_info(&interface->dev, "Line 6 %s now attached\n", - line6->properties->name); + properties->name); return 0; -- cgit v1.2.3 From cddbd4f17078530b4914a42f6d7f3e543b5fad0e Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 28 Jan 2015 14:43:11 +0100 Subject: ALSA: line6: Tidy up and typo fixes in comments Just reformatting the comments and typos fixed, no functional changes. Particularly, - avoid the kerneldoc marker "/**", - reduce multiple comment lines into single lines, - corrected wrongly referred function names Signed-off-by: Takashi Iwai --- sound/usb/line6/driver.c | 2 +- sound/usb/line6/driver.h | 73 ++++++++++++++-------------------------------- sound/usb/line6/midi.h | 32 +++++--------------- sound/usb/line6/pcm.h | 52 +++++++++------------------------ sound/usb/line6/pod.c | 32 +++++--------------- sound/usb/line6/podhd.c | 4 +-- sound/usb/line6/toneport.c | 24 ++++----------- sound/usb/line6/variax.c | 20 ++++--------- 8 files changed, 65 insertions(+), 174 deletions(-) (limited to 'sound/usb/line6/driver.c') diff --git a/sound/usb/line6/driver.c b/sound/usb/line6/driver.c index a0436993a167..f46da99c44b3 100644 --- a/sound/usb/line6/driver.c +++ b/sound/usb/line6/driver.c @@ -44,7 +44,7 @@ static const char line6_request_version[] = { 0xf0, 0x7e, 0x7f, 0x06, 0x01, 0xf7 }; -/** +/* Class for asynchronous messages. */ struct message { diff --git a/sound/usb/line6/driver.h b/sound/usb/line6/driver.h index fce10f12f0d3..80d42a0fd889 100644 --- a/sound/usb/line6/driver.h +++ b/sound/usb/line6/driver.h @@ -60,26 +60,20 @@ extern const unsigned char line6_midi_id[3]; static const int SYSEX_DATA_OFS = sizeof(line6_midi_id) + 3; static const int SYSEX_EXTRA_SIZE = sizeof(line6_midi_id) + 4; -/** +/* Common properties of Line 6 devices. */ struct line6_properties { - /** - Card id string (maximum 16 characters). - This can be used to address the device in ALSA programs as - "default:CARD=" - */ + /* Card id string (maximum 16 characters). + * This can be used to address the device in ALSA programs as + * "default:CARD=" + */ const char *id; - /** - Card short name (maximum 32 characters). - */ + /* Card short name (maximum 32 characters) */ const char *name; - /** - Bit vector defining this device's capabilities in the - line6usb driver. - */ + /* Bit vector defining this device's capabilities in line6usb driver */ int capabilities; int altsetting; @@ -90,70 +84,47 @@ struct line6_properties { unsigned ep_audio_w; }; -/** +/* Common data shared by all Line 6 devices. Corresponds to a pair of USB endpoints. */ struct usb_line6 { - /** - USB device. - */ + /* USB device */ struct usb_device *usbdev; - /** - Properties. - */ + /* Properties */ const struct line6_properties *properties; - /** - Interval (ms). - */ + /* Interval (ms) */ int interval; - /** - Maximum size of USB packet. - */ + /* Maximum size of USB packet */ int max_packet_size; - /** - Device representing the USB interface. - */ + /* Device representing the USB interface */ struct device *ifcdev; - /** - Line 6 sound card data structure. - Each device has at least MIDI or PCM. - */ + /* Line 6 sound card data structure. + * Each device has at least MIDI or PCM. + */ struct snd_card *card; - /** - Line 6 PCM device data structure. - */ + /* Line 6 PCM device data structure */ struct snd_line6_pcm *line6pcm; - /** - Line 6 MIDI device data structure. - */ + /* Line 6 MIDI device data structure */ struct snd_line6_midi *line6midi; - /** - URB for listening to PODxt Pro control endpoint. - */ + /* URB for listening to PODxt Pro control endpoint */ struct urb *urb_listen; - /** - Buffer for listening to PODxt Pro control endpoint. - */ + /* Buffer for listening to PODxt Pro control endpoint */ unsigned char *buffer_listen; - /** - Buffer for message to be processed. - */ + /* Buffer for message to be processed */ unsigned char *buffer_message; - /** - Length of message to be processed. - */ + /* Length of message to be processed */ int message_length; void (*process_message)(struct usb_line6 *); diff --git a/sound/usb/line6/midi.h b/sound/usb/line6/midi.h index 9d9467b2613c..cf82d69e2747 100644 --- a/sound/usb/line6/midi.h +++ b/sound/usb/line6/midi.h @@ -19,44 +19,28 @@ #define MIDI_BUFFER_SIZE 1024 struct snd_line6_midi { - /** - Pointer back to the Line 6 driver data structure. - */ + /* Pointer back to the Line 6 driver data structure */ struct usb_line6 *line6; - /** - MIDI substream for receiving (or NULL if not active). - */ + /* MIDI substream for receiving (or NULL if not active) */ struct snd_rawmidi_substream *substream_receive; - /** - MIDI substream for transmitting (or NULL if not active). - */ + /* MIDI substream for transmitting (or NULL if not active) */ struct snd_rawmidi_substream *substream_transmit; - /** - Number of currently active MIDI send URBs. - */ + /* Number of currently active MIDI send URBs */ int num_active_send_urbs; - /** - Spin lock to protect MIDI buffer handling. - */ + /* Spin lock to protect MIDI buffer handling */ spinlock_t lock; - /** - Wait queue for MIDI transmission. - */ + /* Wait queue for MIDI transmission */ wait_queue_head_t send_wait; - /** - Buffer for incoming MIDI stream. - */ + /* Buffer for incoming MIDI stream */ struct midi_buffer midibuf_in; - /** - Buffer for outgoing MIDI stream. - */ + /* Buffer for outgoing MIDI stream */ struct midi_buffer midibuf_out; }; diff --git a/sound/usb/line6/pcm.h b/sound/usb/line6/pcm.h index 42d3e6fc2c61..19c12f0a9008 100644 --- a/sound/usb/line6/pcm.h +++ b/sound/usb/line6/pcm.h @@ -66,8 +66,8 @@ the running flag indicates whether the stream is running. For monitor or impulse operations, the driver needs to call - snd_line6_duplex_acquire() or snd_line6_duplex_release() with the - appropriate LINE6_STREAM_* flag. + line6_pcm_acquire() or line6_pcm_release() with the appropriate + LINE6_STREAM_* flag. */ /* stream types */ @@ -139,19 +139,13 @@ struct line6_pcm_stream { }; struct snd_line6_pcm { - /** - Pointer back to the Line 6 driver data structure. - */ + /* Pointer back to the Line 6 driver data structure */ struct usb_line6 *line6; - /** - Properties. - */ + /* Properties. */ struct line6_pcm_properties *properties; - /** - ALSA pcm stream - */ + /* ALSA pcm stream */ struct snd_pcm *pcm; /* protection to state changes of in/out streams */ @@ -161,49 +155,31 @@ struct snd_line6_pcm { struct line6_pcm_stream in; struct line6_pcm_stream out; - /** - Previously captured frame (for software monitoring). - */ + /* Previously captured frame (for software monitoring) */ unsigned char *prev_fbuf; - /** - Size of previously captured frame (for software monitoring). - */ + /* Size of previously captured frame (for software monitoring) */ int prev_fsize; - /** - Maximum size of USB packet. - */ + /* Maximum size of USB packet */ int max_packet_size; - /** - PCM playback volume (left and right). - */ + /* PCM playback volume (left and right) */ int volume_playback[2]; - /** - PCM monitor volume. - */ + /* PCM monitor volume */ int volume_monitor; - /** - Volume of impulse response test signal (if zero, test is disabled). - */ + /* Volume of impulse response test signal (if zero, test is disabled) */ int impulse_volume; - /** - Period of impulse response test signal. - */ + /* Period of impulse response test signal */ int impulse_period; - /** - Counter for impulse response test signal. - */ + /* Counter for impulse response test signal */ int impulse_count; - /** - Several status bits (see LINE6_FLAG_*). - */ + /* Several status bits (see LINE6_FLAG_*) */ unsigned long flags; }; diff --git a/sound/usb/line6/pod.c b/sound/usb/line6/pod.c index 6f7cd585f2d8..bc20cf141719 100644 --- a/sound/usb/line6/pod.c +++ b/sound/usb/line6/pod.c @@ -58,44 +58,28 @@ enum { }; struct usb_line6_pod { - /** - Generic Line 6 USB data. - */ + /* Generic Line 6 USB data */ struct usb_line6 line6; - /** - Instrument monitor level. - */ + /* Instrument monitor level */ int monitor_level; - /** - Timer for device initializaton. - */ + /* Timer for device initialization */ struct timer_list startup_timer; - /** - Work handler for device initializaton. - */ + /* Work handler for device initialization */ struct work_struct startup_work; - /** - Current progress in startup procedure. - */ + /* Current progress in startup procedure */ int startup_progress; - /** - Serial number of device. - */ + /* Serial number of device */ int serial_number; - /** - Firmware version (x 100). - */ + /* Firmware version (x 100) */ int firmware_version; - /** - Device ID. - */ + /* Device ID */ int device_id; }; diff --git a/sound/usb/line6/podhd.c b/sound/usb/line6/podhd.c index 43c39886597e..c4e83ab33a21 100644 --- a/sound/usb/line6/podhd.c +++ b/sound/usb/line6/podhd.c @@ -27,9 +27,7 @@ enum { }; struct usb_line6_podhd { - /** - Generic Line 6 USB data. - */ + /* Generic Line 6 USB data */ struct usb_line6 line6; }; diff --git a/sound/usb/line6/toneport.c b/sound/usb/line6/toneport.c index 819e06b3f3db..9024acb2b850 100644 --- a/sound/usb/line6/toneport.c +++ b/sound/usb/line6/toneport.c @@ -43,34 +43,22 @@ struct toneport_led { }; struct usb_line6_toneport { - /** - Generic Line 6 USB data. - */ + /* Generic Line 6 USB data */ struct usb_line6 line6; - /** - Source selector. - */ + /* Source selector */ int source; - /** - Serial number of device. - */ + /* Serial number of device */ int serial_number; - /** - Firmware version (x 100). - */ + /* Firmware version (x 100) */ int firmware_version; - /** - Timer for delayed PCM startup. - */ + /* Timer for delayed PCM startup */ struct timer_list timer; - /** - Device type. - */ + /* Device type */ enum line6_device_type type; /* LED instances */ diff --git a/sound/usb/line6/variax.c b/sound/usb/line6/variax.c index 9701ffa61365..44042cbdef01 100644 --- a/sound/usb/line6/variax.c +++ b/sound/usb/line6/variax.c @@ -42,30 +42,20 @@ enum { }; struct usb_line6_variax { - /** - Generic Line 6 USB data. - */ + /* Generic Line 6 USB data */ struct usb_line6 line6; - /** - Buffer for activation code. - */ + /* Buffer for activation code */ unsigned char *buffer_activate; - /** - Handler for device initializaton. - */ + /* Handler for device initialization */ struct work_struct startup_work; - /** - Timers for device initializaton. - */ + /* Timers for device initialization */ struct timer_list startup_timer1; struct timer_list startup_timer2; - /** - Current progress in startup procedure. - */ + /* Current progress in startup procedure */ int startup_progress; }; -- cgit v1.2.3 From fd9301d33fef67e6dbcab29f3666c76efd97b762 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 28 Jan 2015 14:45:22 +0100 Subject: ALSA: line6: Remove revision.h The definition is no longer used. Signed-off-by: Takashi Iwai --- sound/usb/line6/driver.c | 1 - sound/usb/line6/revision.h | 4 ---- 2 files changed, 5 deletions(-) delete mode 100644 sound/usb/line6/revision.h (limited to 'sound/usb/line6/driver.c') diff --git a/sound/usb/line6/driver.c b/sound/usb/line6/driver.c index f46da99c44b3..786b38159ad6 100644 --- a/sound/usb/line6/driver.c +++ b/sound/usb/line6/driver.c @@ -22,7 +22,6 @@ #include "driver.h" #include "midi.h" #include "playback.h" -#include "revision.h" #include "usbdefs.h" #define DRIVER_AUTHOR "Markus Grabner " diff --git a/sound/usb/line6/revision.h b/sound/usb/line6/revision.h deleted file mode 100644 index b4eee2b73831..000000000000 --- a/sound/usb/line6/revision.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifndef DRIVER_REVISION -/* current subversion revision */ -#define DRIVER_REVISION " (904)" -#endif -- cgit v1.2.3 From 129b3be6895c01e137dbb88c699f9f706bdc6c9d Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 28 Jan 2015 14:50:08 +0100 Subject: ALSA: line6: Move the contents of usbdefs.h into driver.h Most of them are rather relevant with the definitions in driver.h, and there are only a few lines, so just rip it off. Signed-off-by: Takashi Iwai --- sound/usb/line6/driver.c | 1 - sound/usb/line6/driver.h | 16 ++++++++++++++++ sound/usb/line6/midi.c | 1 - sound/usb/line6/pcm.h | 1 - sound/usb/line6/pod.c | 1 - sound/usb/line6/podhd.c | 1 - sound/usb/line6/toneport.c | 1 - sound/usb/line6/usbdefs.h | 27 --------------------------- sound/usb/line6/variax.c | 1 - 9 files changed, 16 insertions(+), 34 deletions(-) delete mode 100644 sound/usb/line6/usbdefs.h (limited to 'sound/usb/line6/driver.c') diff --git a/sound/usb/line6/driver.c b/sound/usb/line6/driver.c index 786b38159ad6..2328ec9a1ca8 100644 --- a/sound/usb/line6/driver.c +++ b/sound/usb/line6/driver.c @@ -22,7 +22,6 @@ #include "driver.h" #include "midi.h" #include "playback.h" -#include "usbdefs.h" #define DRIVER_AUTHOR "Markus Grabner " #define DRIVER_DESC "Line 6 USB Driver" diff --git a/sound/usb/line6/driver.h b/sound/usb/line6/driver.h index 80d42a0fd889..fa877a345860 100644 --- a/sound/usb/line6/driver.h +++ b/sound/usb/line6/driver.h @@ -20,6 +20,12 @@ #define DRIVER_NAME "line6usb" +#define USB_INTERVALS_PER_SECOND 1000 + +/* Fallback USB interval and max packet size values */ +#define LINE6_FALLBACK_INTERVAL 10 +#define LINE6_FALLBACK_MAXPACKETSIZE 16 + #define LINE6_TIMEOUT 1 #define LINE6_BUFSIZE_LISTEN 32 #define LINE6_MESSAGE_MAXLEN 256 @@ -84,6 +90,16 @@ struct line6_properties { unsigned ep_audio_w; }; +/* Capability bits */ +enum { + /* device supports settings parameter via USB */ + LINE6_CAP_CONTROL = 1 << 0, + /* device supports PCM input/output via USB */ + LINE6_CAP_PCM = 1 << 1, + /* device support hardware monitoring */ + LINE6_CAP_HWMON = 1 << 2, +}; + /* Common data shared by all Line 6 devices. Corresponds to a pair of USB endpoints. diff --git a/sound/usb/line6/midi.c b/sound/usb/line6/midi.c index beeedf9a2cbe..cebea9b7f769 100644 --- a/sound/usb/line6/midi.c +++ b/sound/usb/line6/midi.c @@ -17,7 +17,6 @@ #include "driver.h" #include "midi.h" -#include "usbdefs.h" #define line6_rawmidi_substream_midi(substream) \ ((struct snd_line6_midi *)((substream)->rmidi->private_data)) diff --git a/sound/usb/line6/pcm.h b/sound/usb/line6/pcm.h index 19c12f0a9008..3a3cfba40ec7 100644 --- a/sound/usb/line6/pcm.h +++ b/sound/usb/line6/pcm.h @@ -19,7 +19,6 @@ #include #include "driver.h" -#include "usbdefs.h" /* number of URBs */ #define LINE6_ISO_BUFFERS 2 diff --git a/sound/usb/line6/pod.c b/sound/usb/line6/pod.c index bc20cf141719..3f7ff661b3dd 100644 --- a/sound/usb/line6/pod.c +++ b/sound/usb/line6/pod.c @@ -21,7 +21,6 @@ #include "capture.h" #include "driver.h" #include "playback.h" -#include "usbdefs.h" /* Locate name in binary program dump diff --git a/sound/usb/line6/podhd.c b/sound/usb/line6/podhd.c index c4e83ab33a21..5e4e02c1f4b5 100644 --- a/sound/usb/line6/podhd.c +++ b/sound/usb/line6/podhd.c @@ -17,7 +17,6 @@ #include "driver.h" #include "pcm.h" -#include "usbdefs.h" enum { LINE6_PODHD300, diff --git a/sound/usb/line6/toneport.c b/sound/usb/line6/toneport.c index 9024acb2b850..cffcd7f83bfd 100644 --- a/sound/usb/line6/toneport.c +++ b/sound/usb/line6/toneport.c @@ -21,7 +21,6 @@ #include "capture.h" #include "driver.h" #include "playback.h" -#include "usbdefs.h" enum line6_device_type { LINE6_GUITARPORT, diff --git a/sound/usb/line6/usbdefs.h b/sound/usb/line6/usbdefs.h deleted file mode 100644 index 5ef7bcd24e18..000000000000 --- a/sound/usb/line6/usbdefs.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Line 6 Linux USB driver - * - * Copyright (C) 2005-2008 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. - * - */ - -#ifndef USBDEFS_H -#define USBDEFS_H - -#define USB_INTERVALS_PER_SECOND 1000 - -/* device supports settings parameter via USB */ -#define LINE6_CAP_CONTROL (1 << 0) -/* device supports PCM input/output via USB */ -#define LINE6_CAP_PCM (1 << 1) -/* device support hardware monitoring */ -#define LINE6_CAP_HWMON (1 << 2) - -#define LINE6_FALLBACK_INTERVAL 10 -#define LINE6_FALLBACK_MAXPACKETSIZE 16 - -#endif diff --git a/sound/usb/line6/variax.c b/sound/usb/line6/variax.c index 44042cbdef01..9dfbe7916d99 100644 --- a/sound/usb/line6/variax.c +++ b/sound/usb/line6/variax.c @@ -17,7 +17,6 @@ #include #include "driver.h" -#include "usbdefs.h" #define VARIAX_STARTUP_DELAY1 1000 #define VARIAX_STARTUP_DELAY3 100 -- cgit v1.2.3 From 695758c6c4d67955f7d73bc9fd39288acfd4b222 Mon Sep 17 00:00:00 2001 From: Nicholas Mc Guire Date: Tue, 3 Feb 2015 02:38:39 -0500 Subject: ALSA: line6: use msecs_to_jiffies for conversion This is only an API consolidation and should make things more readable it replaces var * HZ / 1000 by msecs_to_jiffies(var). Signed-off-by: Nicholas Mc Guire Signed-off-by: Takashi Iwai --- sound/usb/line6/driver.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sound/usb/line6/driver.c') diff --git a/sound/usb/line6/driver.c b/sound/usb/line6/driver.c index 2328ec9a1ca8..3cf12ccdd72e 100644 --- a/sound/usb/line6/driver.c +++ b/sound/usb/line6/driver.c @@ -166,7 +166,7 @@ void line6_start_timer(struct timer_list *timer, unsigned int msecs, void (*function)(unsigned long), unsigned long data) { setup_timer(timer, function, data); - mod_timer(timer, jiffies + msecs * HZ / 1000); + mod_timer(timer, jiffies + msecs_to_jiffies(msecs)); } EXPORT_SYMBOL_GPL(line6_start_timer); -- cgit v1.2.3 From 6ccd93bdb989507717edb375d40534f1177822c5 Mon Sep 17 00:00:00 2001 From: Nicholas Mc Guire Date: Tue, 3 Feb 2015 02:38:56 -0500 Subject: ALSA: line6: fixup of line6_start_timer argument type line6_start_timer passes an unsigned int as argument to be used in mod_timer which is then used by mod_timer as unsigned long, this just fixes up the argument type. This change helps make static code checkers happy. Signed-off-by: Nicholas Mc Guire Signed-off-by: Takashi Iwai --- sound/usb/line6/driver.c | 2 +- sound/usb/line6/driver.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'sound/usb/line6/driver.c') diff --git a/sound/usb/line6/driver.c b/sound/usb/line6/driver.c index 3cf12ccdd72e..e2a2603a1ca3 100644 --- a/sound/usb/line6/driver.c +++ b/sound/usb/line6/driver.c @@ -162,7 +162,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 line6_start_timer(struct timer_list *timer, unsigned long msecs, void (*function)(unsigned long), unsigned long data) { setup_timer(timer, function, data); diff --git a/sound/usb/line6/driver.h b/sound/usb/line6/driver.h index fa877a345860..2276b78f3562 100644 --- a/sound/usb/line6/driver.h +++ b/sound/usb/line6/driver.h @@ -159,7 +159,7 @@ extern int line6_send_sysex_message(struct usb_line6 *line6, const char *buffer, int size); extern ssize_t line6_set_raw(struct device *dev, struct device_attribute *attr, const char *buf, size_t count); -extern void line6_start_timer(struct timer_list *timer, unsigned int msecs, +extern void line6_start_timer(struct timer_list *timer, unsigned long msecs, void (*function)(unsigned long), unsigned long data); extern int line6_version_request_async(struct usb_line6 *line6); -- cgit v1.2.3 From 12865cac38cc9e808ce8b479f4bb12fd00bfee7c Mon Sep 17 00:00:00 2001 From: Chris Rorvick Date: Sat, 7 Feb 2015 10:43:19 -0600 Subject: ALSA: line6: Pass driver name to line6_probe() Provide a unique name for each driver instead of using "line6usb" for all of them. This will allow for different configurations based on the driver type. Signed-off-by: Chris Rorvick Signed-off-by: Takashi Iwai --- sound/usb/line6/driver.c | 3 ++- sound/usb/line6/driver.h | 3 +-- sound/usb/line6/pod.c | 2 +- sound/usb/line6/podhd.c | 2 +- sound/usb/line6/toneport.c | 2 +- sound/usb/line6/variax.c | 2 +- 6 files changed, 7 insertions(+), 7 deletions(-) (limited to 'sound/usb/line6/driver.c') diff --git a/sound/usb/line6/driver.c b/sound/usb/line6/driver.c index e2a2603a1ca3..626b0c3244cf 100644 --- a/sound/usb/line6/driver.c +++ b/sound/usb/line6/driver.c @@ -480,6 +480,7 @@ static int line6_init_cap_control(struct usb_line6 *line6) */ int line6_probe(struct usb_interface *interface, const struct usb_device_id *id, + const char *driver_name, const struct line6_properties *properties, int (*private_init)(struct usb_line6 *, const struct usb_device_id *id), size_t data_size) @@ -511,7 +512,7 @@ int line6_probe(struct usb_interface *interface, line6->ifcdev = &interface->dev; strcpy(card->id, properties->id); - strcpy(card->driver, DRIVER_NAME); + strcpy(card->driver, driver_name); strcpy(card->shortname, properties->name); sprintf(card->longname, "Line 6 %s at USB %s", properties->name, dev_name(line6->ifcdev)); diff --git a/sound/usb/line6/driver.h b/sound/usb/line6/driver.h index 2276b78f3562..92a662a0469e 100644 --- a/sound/usb/line6/driver.h +++ b/sound/usb/line6/driver.h @@ -18,8 +18,6 @@ #include "midi.h" -#define DRIVER_NAME "line6usb" - #define USB_INTERVALS_PER_SECOND 1000 /* Fallback USB interval and max packet size values */ @@ -168,6 +166,7 @@ extern int line6_write_data(struct usb_line6 *line6, int address, void *data, int line6_probe(struct usb_interface *interface, const struct usb_device_id *id, + const char *driver_name, const struct line6_properties *properties, int (*private_init)(struct usb_line6 *, const struct usb_device_id *id), size_t data_size); diff --git a/sound/usb/line6/pod.c b/sound/usb/line6/pod.c index feec7070eaca..09017bc9615b 100644 --- a/sound/usb/line6/pod.c +++ b/sound/usb/line6/pod.c @@ -561,7 +561,7 @@ static const struct line6_properties pod_properties_table[] = { static int pod_probe(struct usb_interface *interface, const struct usb_device_id *id) { - return line6_probe(interface, id, + return line6_probe(interface, id, "Line6-POD", &pod_properties_table[id->driver_info], pod_init, sizeof(struct usb_line6_pod)); } diff --git a/sound/usb/line6/podhd.c b/sound/usb/line6/podhd.c index 9c3c7441fd11..63dcaef41ac3 100644 --- a/sound/usb/line6/podhd.c +++ b/sound/usb/line6/podhd.c @@ -169,7 +169,7 @@ static const struct line6_properties podhd_properties_table[] = { static int podhd_probe(struct usb_interface *interface, const struct usb_device_id *id) { - return line6_probe(interface, id, + return line6_probe(interface, id, "Line6-PODHD", &podhd_properties_table[id->driver_info], podhd_init, sizeof(struct usb_line6)); } diff --git a/sound/usb/line6/toneport.c b/sound/usb/line6/toneport.c index 2420d2fc8aa2..1a0a485b6654 100644 --- a/sound/usb/line6/toneport.c +++ b/sound/usb/line6/toneport.c @@ -557,7 +557,7 @@ static const struct line6_properties toneport_properties_table[] = { static int toneport_probe(struct usb_interface *interface, const struct usb_device_id *id) { - return line6_probe(interface, id, + return line6_probe(interface, id, "Line6-TonePort", &toneport_properties_table[id->driver_info], toneport_init, sizeof(struct usb_line6_toneport)); } diff --git a/sound/usb/line6/variax.c b/sound/usb/line6/variax.c index b1c1de65d584..ddc23ddf0750 100644 --- a/sound/usb/line6/variax.c +++ b/sound/usb/line6/variax.c @@ -283,7 +283,7 @@ static const struct line6_properties variax_properties_table[] = { static int variax_probe(struct usb_interface *interface, const struct usb_device_id *id) { - return line6_probe(interface, id, + return line6_probe(interface, id, "Line6-Variax", &variax_properties_table[id->driver_info], variax_init, sizeof(struct usb_line6_variax)); } -- cgit v1.2.3 From e64e94df9916a1db6c85a3677e20926c99a1d0b3 Mon Sep 17 00:00:00 2001 From: Chris Rorvick Date: Tue, 10 Feb 2015 23:03:13 -0600 Subject: ALSA: line6: Add delay before reading status The device indicates the result of a read/write operation by making the status available on a subsequent request from the driver. This is not ready immediately, though, so the driver is currently slamming the device with hundreds of pointless requests before getting the expected response. Add a two millisecond delay before each attempt. This is approximately the behavior observed with version 4.2.7.1 of the Windows driver. Signed-off-by: Chris Rorvick Signed-off-by: Takashi Iwai --- sound/usb/line6/driver.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'sound/usb/line6/driver.c') diff --git a/sound/usb/line6/driver.c b/sound/usb/line6/driver.c index 626b0c3244cf..2f9b74e7accb 100644 --- a/sound/usb/line6/driver.c +++ b/sound/usb/line6/driver.c @@ -296,6 +296,8 @@ static void line6_data_received(struct urb *urb) line6_start_listen(line6); } +#define LINE6_READ_WRITE_STATUS_DELAY 2 /* milliseconds */ + /* Read data from device. */ @@ -319,6 +321,8 @@ int line6_read_data(struct usb_line6 *line6, int address, void *data, /* Wait for data length. We'll get 0xff until length arrives. */ do { + mdelay(LINE6_READ_WRITE_STATUS_DELAY); + ret = usb_control_msg(usbdev, usb_rcvctrlpipe(usbdev, 0), 0x67, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, @@ -376,6 +380,8 @@ int line6_write_data(struct usb_line6 *line6, int address, void *data, } do { + mdelay(LINE6_READ_WRITE_STATUS_DELAY); + ret = usb_control_msg(usbdev, usb_rcvctrlpipe(usbdev, 0), 0x67, USB_TYPE_VENDOR | USB_RECIP_DEVICE | -- cgit v1.2.3 From f3dfd1be08cc55f930f32e714fb1967630c47991 Mon Sep 17 00:00:00 2001 From: Chris Rorvick Date: Tue, 10 Feb 2015 23:03:14 -0600 Subject: ALSA: line6: Return error if device not responding Put an upper bound on how long we will wait for the device to respond to a read/write request (i.e., 100 milliseconds) and return an error if this is reached. Signed-off-by: Chris Rorvick Signed-off-by: Takashi Iwai --- sound/usb/line6/driver.c | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) (limited to 'sound/usb/line6/driver.c') diff --git a/sound/usb/line6/driver.c b/sound/usb/line6/driver.c index 2f9b74e7accb..f2ee8046271a 100644 --- a/sound/usb/line6/driver.c +++ b/sound/usb/line6/driver.c @@ -297,6 +297,7 @@ static void line6_data_received(struct urb *urb) } #define LINE6_READ_WRITE_STATUS_DELAY 2 /* milliseconds */ +#define LINE6_READ_WRITE_MAX_RETRIES 50 /* Read data from device. @@ -307,6 +308,7 @@ int line6_read_data(struct usb_line6 *line6, int address, void *data, struct usb_device *usbdev = line6->usbdev; int ret; unsigned char len; + unsigned count; /* query the serial number: */ ret = usb_control_msg(usbdev, usb_sndctrlpipe(usbdev, 0), 0x67, @@ -320,7 +322,7 @@ int line6_read_data(struct usb_line6 *line6, int address, void *data, } /* Wait for data length. We'll get 0xff until length arrives. */ - do { + for (count = 0; count < LINE6_READ_WRITE_MAX_RETRIES; count++) { mdelay(LINE6_READ_WRITE_STATUS_DELAY); ret = usb_control_msg(usbdev, usb_rcvctrlpipe(usbdev, 0), 0x67, @@ -333,9 +335,16 @@ int line6_read_data(struct usb_line6 *line6, int address, void *data, "receive length failed (error %d)\n", ret); return ret; } - } while (len == 0xff); - if (len != datalen) { + if (len != 0xff) + break; + } + + if (len == 0xff) { + dev_err(line6->ifcdev, "read failed after %d retries\n", + count); + return -EIO; + } else if (len != datalen) { /* should be equal or something went wrong */ dev_err(line6->ifcdev, "length mismatch (expected %d, got %d)\n", @@ -367,6 +376,7 @@ int line6_write_data(struct usb_line6 *line6, int address, void *data, struct usb_device *usbdev = line6->usbdev; int ret; unsigned char status; + int count; ret = usb_control_msg(usbdev, usb_sndctrlpipe(usbdev, 0), 0x67, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT, @@ -379,7 +389,7 @@ int line6_write_data(struct usb_line6 *line6, int address, void *data, return ret; } - do { + for (count = 0; count < LINE6_READ_WRITE_MAX_RETRIES; count++) { mdelay(LINE6_READ_WRITE_STATUS_DELAY); ret = usb_control_msg(usbdev, usb_rcvctrlpipe(usbdev, 0), @@ -394,9 +404,16 @@ int line6_write_data(struct usb_line6 *line6, int address, void *data, "receiving status failed (error %d)\n", ret); return ret; } - } while (status == 0xff); - if (status != 0) { + if (status != 0xff) + break; + } + + if (status == 0xff) { + dev_err(line6->ifcdev, "write failed after %d retries\n", + count); + return -EIO; + } else if (status != 0) { dev_err(line6->ifcdev, "write failed (error %d)\n", ret); return -EINVAL; } -- cgit v1.2.3 From e474e7fd404b9e516f1c90a1c3f485e21be34c15 Mon Sep 17 00:00:00 2001 From: Chris Rorvick Date: Tue, 10 Feb 2015 23:03:15 -0600 Subject: ALSA: line6: Return EIO if read/write not successful Signed-off-by: Chris Rorvick Signed-off-by: Takashi Iwai --- sound/usb/line6/driver.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'sound/usb/line6/driver.c') diff --git a/sound/usb/line6/driver.c b/sound/usb/line6/driver.c index f2ee8046271a..6c2d418b53f1 100644 --- a/sound/usb/line6/driver.c +++ b/sound/usb/line6/driver.c @@ -349,7 +349,7 @@ int line6_read_data(struct usb_line6 *line6, int address, void *data, dev_err(line6->ifcdev, "length mismatch (expected %d, got %d)\n", (int)datalen, (int)len); - return -EINVAL; + return -EIO; } /* receive the result: */ @@ -415,7 +415,7 @@ int line6_write_data(struct usb_line6 *line6, int address, void *data, return -EIO; } else if (status != 0) { dev_err(line6->ifcdev, "write failed (error %d)\n", ret); - return -EINVAL; + return -EIO; } return 0; -- cgit v1.2.3 From 12b00157fd8572ee1f54b70bbf496641a1608924 Mon Sep 17 00:00:00 2001 From: Chris Rorvick Date: Tue, 10 Feb 2015 23:03:16 -0600 Subject: ALSA: line6: Use explicit type for serial number The serial number (aka ESN) is a 32-bit value. Signed-off-by: Chris Rorvick Signed-off-by: Takashi Iwai --- sound/usb/line6/driver.c | 2 +- sound/usb/line6/driver.h | 2 +- sound/usb/line6/pod.c | 4 ++-- sound/usb/line6/toneport.c | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) (limited to 'sound/usb/line6/driver.c') diff --git a/sound/usb/line6/driver.c b/sound/usb/line6/driver.c index 6c2d418b53f1..99b63a7902f3 100644 --- a/sound/usb/line6/driver.c +++ b/sound/usb/line6/driver.c @@ -426,7 +426,7 @@ EXPORT_SYMBOL_GPL(line6_write_data); Read Line 6 device serial number. (POD, TonePort, GuitarPort) */ -int line6_read_serial_number(struct usb_line6 *line6, int *serial_number) +int line6_read_serial_number(struct usb_line6 *line6, u32 *serial_number) { return line6_read_data(line6, 0x80d0, serial_number, sizeof(*serial_number)); diff --git a/sound/usb/line6/driver.h b/sound/usb/line6/driver.h index 92a662a0469e..5d20294d64f4 100644 --- a/sound/usb/line6/driver.h +++ b/sound/usb/line6/driver.h @@ -150,7 +150,7 @@ extern char *line6_alloc_sysex_buffer(struct usb_line6 *line6, int code1, extern int line6_read_data(struct usb_line6 *line6, int address, void *data, size_t datalen); extern int line6_read_serial_number(struct usb_line6 *line6, - int *serial_number); + u32 *serial_number); extern int line6_send_raw_message_async(struct usb_line6 *line6, const char *buffer, int size); extern int line6_send_sysex_message(struct usb_line6 *line6, diff --git a/sound/usb/line6/pod.c b/sound/usb/line6/pod.c index 09017bc9615b..daf81d169a42 100644 --- a/sound/usb/line6/pod.c +++ b/sound/usb/line6/pod.c @@ -73,7 +73,7 @@ struct usb_line6_pod { int startup_progress; /* Serial number of device */ - int serial_number; + u32 serial_number; /* Firmware version (x 100) */ int firmware_version; @@ -247,7 +247,7 @@ static ssize_t serial_number_show(struct device *dev, struct usb_interface *interface = to_usb_interface(dev); struct usb_line6_pod *pod = usb_get_intfdata(interface); - return sprintf(buf, "%d\n", pod->serial_number); + return sprintf(buf, "%u\n", pod->serial_number); } /* diff --git a/sound/usb/line6/toneport.c b/sound/usb/line6/toneport.c index 1a0a485b6654..ddf7368c2001 100644 --- a/sound/usb/line6/toneport.c +++ b/sound/usb/line6/toneport.c @@ -49,7 +49,7 @@ struct usb_line6_toneport { int source; /* Serial number of device */ - int serial_number; + u32 serial_number; /* Firmware version (x 100) */ int firmware_version; -- cgit v1.2.3