Merge branch 'topic/line6-cleanup' into for-next

Pull LINE6 driver cleanups and fixes.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
Takashi Iwai 2019-05-28 09:42:23 +02:00
commit 968e8e9fde
6 changed files with 110 additions and 275 deletions

View File

@ -195,17 +195,6 @@ static int line6_send_raw_message_async_part(struct message *msg,
return retval;
}
/*
Setup and start timer.
*/
void line6_start_timer(struct timer_list *timer, unsigned long msecs,
void (*function)(struct timer_list *t))
{
timer->function = function;
mod_timer(timer, jiffies + msecs_to_jiffies(msecs));
}
EXPORT_SYMBOL_GPL(line6_start_timer);
/*
Asynchronously send raw message.
*/
@ -720,6 +709,15 @@ static int line6_init_cap_control(struct usb_line6 *line6)
return 0;
}
static void line6_startup_work(struct work_struct *work)
{
struct usb_line6 *line6 =
container_of(work, struct usb_line6, startup_work.work);
if (line6->startup)
line6->startup(line6);
}
/*
Probe USB device.
*/
@ -755,6 +753,7 @@ int line6_probe(struct usb_interface *interface,
line6->properties = properties;
line6->usbdev = usbdev;
line6->ifcdev = &interface->dev;
INIT_DELAYED_WORK(&line6->startup_work, line6_startup_work);
strcpy(card->id, properties->id);
strcpy(card->driver, driver_name);
@ -825,6 +824,8 @@ void line6_disconnect(struct usb_interface *interface)
if (WARN_ON(usbdev != line6->usbdev))
return;
cancel_delayed_work(&line6->startup_work);
if (line6->urb_listen != NULL)
line6_stop_listen(line6);

View File

@ -68,13 +68,6 @@
#define LINE6_CHANNEL_MASK 0x0f
#define CHECK_STARTUP_PROGRESS(x, n) \
do { \
if ((x) >= (n)) \
return; \
x = (n); \
} while (0)
extern const unsigned char line6_midi_id[3];
static const int SYSEX_DATA_OFS = sizeof(line6_midi_id) + 3;
@ -178,11 +171,15 @@ struct usb_line6 {
fifo;
} messages;
/* Work for delayed PCM startup */
struct delayed_work startup_work;
/* If MIDI is supported, buffer_message contains the pre-processed data;
* otherwise the data is only in urb_listen (buffer_incoming).
*/
void (*process_message)(struct usb_line6 *);
void (*disconnect)(struct usb_line6 *line6);
void (*startup)(struct usb_line6 *line6);
};
extern char *line6_alloc_sysex_buffer(struct usb_line6 *line6, int code1,
@ -197,8 +194,6 @@ 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 long msecs,
void (*function)(struct timer_list *t));
extern int line6_version_request_async(struct usb_line6 *line6);
extern int line6_write_data(struct usb_line6 *line6, unsigned address,
void *data, unsigned datalen);

View File

@ -39,11 +39,9 @@
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
POD_STARTUP_DONE,
};
enum {
@ -63,12 +61,6 @@ struct usb_line6_pod {
/* Instrument monitor level */
int monitor_level;
/* Timer for device initialization */
struct timer_list startup_timer;
/* Work handler for device initialization */
struct work_struct startup_work;
/* Current progress in startup procedure */
int startup_progress;
@ -82,6 +74,8 @@ struct usb_line6_pod {
int device_id;
};
#define line6_to_pod(x) container_of(x, struct usb_line6_pod, line6)
#define POD_SYSEX_CODE 3
/* *INDENT-OFF* */
@ -173,10 +167,6 @@ static const char pod_version_header[] = {
0xf2, 0x7e, 0x7f, 0x06, 0x02
};
/* forward declarations: */
static void pod_startup2(struct timer_list *t);
static void pod_startup3(struct usb_line6_pod *pod);
static char *pod_alloc_sysex_buffer(struct usb_line6_pod *pod, int code,
int size)
{
@ -189,14 +179,17 @@ static char *pod_alloc_sysex_buffer(struct usb_line6_pod *pod, int code,
*/
static void line6_pod_process_message(struct usb_line6 *line6)
{
struct usb_line6_pod *pod = (struct usb_line6_pod *) line6;
struct usb_line6_pod *pod = line6_to_pod(line6);
const unsigned char *buf = pod->line6.buffer_message;
if (memcmp(buf, pod_version_header, sizeof(pod_version_header)) == 0) {
pod->firmware_version = buf[13] * 100 + buf[14] * 10 + buf[15];
pod->device_id = ((int)buf[8] << 16) | ((int)buf[9] << 8) |
(int) buf[10];
pod_startup3(pod);
if (pod->startup_progress == POD_STARTUP_VERSIONREQ) {
pod->startup_progress = POD_STARTUP_SETUP;
schedule_delayed_work(&line6->startup_work, 0);
}
return;
}
@ -281,47 +274,27 @@ static ssize_t device_id_show(struct device *dev,
context). After the last one has finished, the device is ready to use.
*/
static void pod_startup1(struct usb_line6_pod *pod)
static void pod_startup(struct usb_line6 *line6)
{
CHECK_STARTUP_PROGRESS(pod->startup_progress, POD_STARTUP_INIT);
struct usb_line6_pod *pod = line6_to_pod(line6);
/* delay startup procedure: */
line6_start_timer(&pod->startup_timer, POD_STARTUP_DELAY, pod_startup2);
}
switch (pod->startup_progress) {
case POD_STARTUP_VERSIONREQ:
/* request firmware version: */
line6_version_request_async(line6);
break;
case POD_STARTUP_SETUP:
/* serial number: */
line6_read_serial_number(&pod->line6, &pod->serial_number);
static void pod_startup2(struct timer_list *t)
{
struct usb_line6_pod *pod = from_timer(pod, t, startup_timer);
struct usb_line6 *line6 = &pod->line6;
CHECK_STARTUP_PROGRESS(pod->startup_progress, POD_STARTUP_VERSIONREQ);
/* request firmware version: */
line6_version_request_async(line6);
}
static void pod_startup3(struct usb_line6_pod *pod)
{
CHECK_STARTUP_PROGRESS(pod->startup_progress, POD_STARTUP_WORKQUEUE);
/* schedule work for global work queue: */
schedule_work(&pod->startup_work);
}
static void pod_startup4(struct work_struct *work)
{
struct usb_line6_pod *pod =
container_of(work, struct usb_line6_pod, startup_work);
struct usb_line6 *line6 = &pod->line6;
CHECK_STARTUP_PROGRESS(pod->startup_progress, POD_STARTUP_SETUP);
/* serial number: */
line6_read_serial_number(&pod->line6, &pod->serial_number);
/* ALSA audio interface: */
if (snd_card_register(line6->card))
dev_err(line6->ifcdev, "Failed to register POD card.\n");
/* ALSA audio interface: */
if (snd_card_register(line6->card))
dev_err(line6->ifcdev, "Failed to register POD card.\n");
pod->startup_progress = POD_STARTUP_DONE;
break;
default:
break;
}
}
/* POD special files: */
@ -357,7 +330,7 @@ static int snd_pod_control_monitor_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol);
struct usb_line6_pod *pod = (struct usb_line6_pod *)line6pcm->line6;
struct usb_line6_pod *pod = line6_to_pod(line6pcm->line6);
ucontrol->value.integer.value[0] = pod->monitor_level;
return 0;
@ -368,7 +341,7 @@ static int snd_pod_control_monitor_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol);
struct usb_line6_pod *pod = (struct usb_line6_pod *)line6pcm->line6;
struct usb_line6_pod *pod = line6_to_pod(line6pcm->line6);
if (ucontrol->value.integer.value[0] == pod->monitor_level)
return 0;
@ -390,17 +363,6 @@ static const struct snd_kcontrol_new pod_control_monitor = {
.put = snd_pod_control_monitor_put
};
/*
POD device disconnected.
*/
static void line6_pod_disconnect(struct usb_line6 *line6)
{
struct usb_line6_pod *pod = (struct usb_line6_pod *)line6;
del_timer_sync(&pod->startup_timer);
cancel_work_sync(&pod->startup_work);
}
/*
Try to init POD device.
*/
@ -408,13 +370,10 @@ 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;
struct usb_line6_pod *pod = line6_to_pod(line6);
line6->process_message = line6_pod_process_message;
line6->disconnect = line6_pod_disconnect;
timer_setup(&pod->startup_timer, NULL, 0);
INIT_WORK(&pod->startup_work, pod_startup4);
line6->startup = pod_startup;
/* create sysfs entries: */
err = snd_card_add_dev_attr(line6->card, &pod_dev_attr_group);
@ -447,7 +406,8 @@ static int pod_init(struct usb_line6 *line6,
pod->monitor_level = POD_SYSTEM_INVALID;
/* initiate startup procedure: */
pod_startup1(pod);
schedule_delayed_work(&line6->startup_work,
msecs_to_jiffies(POD_STARTUP_DELAY));
}
return 0;

View File

@ -22,16 +22,6 @@
#define PODHD_STARTUP_DELAY 500
/*
* Stages of POD startup procedure
*/
enum {
PODHD_STARTUP_INIT = 1,
PODHD_STARTUP_SCHEDULE_WORKQUEUE,
PODHD_STARTUP_SETUP,
PODHD_STARTUP_LAST = PODHD_STARTUP_SETUP - 1
};
enum {
LINE6_PODHD300,
LINE6_PODHD400,
@ -47,15 +37,6 @@ struct usb_line6_podhd {
/* Generic Line 6 USB data */
struct usb_line6 line6;
/* Timer for device initialization */
struct timer_list startup_timer;
/* Work handler for device initialization */
struct work_struct startup_work;
/* Current progress in startup procedure */
int startup_progress;
/* Serial number of device */
u32 serial_number;
@ -63,6 +44,8 @@ struct usb_line6_podhd {
int firmware_version;
};
#define line6_to_podhd(x) container_of(x, struct usb_line6_podhd, line6)
static struct snd_ratden podhd_ratden = {
.num_min = 48000,
.num_max = 48000,
@ -158,10 +141,6 @@ static struct line6_pcm_properties podx3_pcm_properties = {
};
static struct usb_driver podhd_driver;
static void podhd_startup_start_workqueue(struct timer_list *t);
static void podhd_startup_workqueue(struct work_struct *work);
static int podhd_startup_finalize(struct usb_line6_podhd *pod);
static ssize_t serial_number_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
@ -202,26 +181,6 @@ static const struct attribute_group podhd_dev_attr_group = {
* audio nor bulk interfaces to work.
*/
static void podhd_startup(struct usb_line6_podhd *pod)
{
CHECK_STARTUP_PROGRESS(pod->startup_progress, PODHD_STARTUP_INIT);
/* delay startup procedure: */
line6_start_timer(&pod->startup_timer, PODHD_STARTUP_DELAY,
podhd_startup_start_workqueue);
}
static void podhd_startup_start_workqueue(struct timer_list *t)
{
struct usb_line6_podhd *pod = from_timer(pod, t, startup_timer);
CHECK_STARTUP_PROGRESS(pod->startup_progress,
PODHD_STARTUP_SCHEDULE_WORKQUEUE);
/* schedule work for global work queue: */
schedule_work(&pod->startup_work);
}
static int podhd_dev_start(struct usb_line6_podhd *pod)
{
int ret;
@ -272,37 +231,23 @@ static int podhd_dev_start(struct usb_line6_podhd *pod)
return ret;
}
static void podhd_startup_workqueue(struct work_struct *work)
static void podhd_startup(struct usb_line6 *line6)
{
struct usb_line6_podhd *pod =
container_of(work, struct usb_line6_podhd, startup_work);
CHECK_STARTUP_PROGRESS(pod->startup_progress, PODHD_STARTUP_SETUP);
struct usb_line6_podhd *pod = line6_to_podhd(line6);
podhd_dev_start(pod);
line6_read_serial_number(&pod->line6, &pod->serial_number);
podhd_startup_finalize(pod);
}
static int podhd_startup_finalize(struct usb_line6_podhd *pod)
{
struct usb_line6 *line6 = &pod->line6;
/* ALSA audio interface: */
return snd_card_register(line6->card);
if (snd_card_register(line6->card))
dev_err(line6->ifcdev, "Failed to register POD HD card.\n");
}
static void podhd_disconnect(struct usb_line6 *line6)
{
struct usb_line6_podhd *pod = (struct usb_line6_podhd *)line6;
struct usb_line6_podhd *pod = line6_to_podhd(line6);
if (pod->line6.properties->capabilities & LINE6_CAP_CONTROL_INFO) {
struct usb_interface *intf;
del_timer_sync(&pod->startup_timer);
cancel_work_sync(&pod->startup_work);
intf = usb_ifnum_to_if(line6->usbdev,
pod->line6.properties->ctrl_if);
if (intf)
@ -317,13 +262,11 @@ static int podhd_init(struct usb_line6 *line6,
const struct usb_device_id *id)
{
int err;
struct usb_line6_podhd *pod = (struct usb_line6_podhd *) line6;
struct usb_line6_podhd *pod = line6_to_podhd(line6);
struct usb_interface *intf;
line6->disconnect = podhd_disconnect;
timer_setup(&pod->startup_timer, NULL, 0);
INIT_WORK(&pod->startup_work, podhd_startup_workqueue);
line6->startup = podhd_startup;
if (pod->line6.properties->capabilities & LINE6_CAP_CONTROL) {
/* claim the data interface */
@ -362,11 +305,12 @@ static int podhd_init(struct usb_line6 *line6,
if (!(pod->line6.properties->capabilities & LINE6_CAP_CONTROL_INFO)) {
/* register USB audio system directly */
return podhd_startup_finalize(pod);
return snd_card_register(line6->card);
}
/* init device and delay registering */
podhd_startup(pod);
schedule_delayed_work(&line6->startup_work,
msecs_to_jiffies(PODHD_STARTUP_DELAY));
return 0;
}

View File

@ -54,9 +54,6 @@ struct usb_line6_toneport {
/* Firmware version (x 100) */
u8 firmware_version;
/* Work for delayed PCM startup */
struct delayed_work pcm_work;
/* Device type */
enum line6_device_type type;
@ -64,6 +61,8 @@ struct usb_line6_toneport {
struct toneport_led leds[2];
};
#define line6_to_toneport(x) container_of(x, struct usb_line6_toneport, line6)
static int toneport_send_cmd(struct usb_device *usbdev, int cmd1, int cmd2);
#define TONEPORT_PCM_DELAY 1
@ -214,8 +213,8 @@ static int snd_toneport_source_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol);
struct usb_line6_toneport *toneport =
(struct usb_line6_toneport *)line6pcm->line6;
struct usb_line6_toneport *toneport = line6_to_toneport(line6pcm->line6);
ucontrol->value.enumerated.item[0] = toneport->source;
return 0;
}
@ -225,8 +224,7 @@ static int snd_toneport_source_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol);
struct usb_line6_toneport *toneport =
(struct usb_line6_toneport *)line6pcm->line6;
struct usb_line6_toneport *toneport = line6_to_toneport(line6pcm->line6);
unsigned int source;
source = ucontrol->value.enumerated.item[0];
@ -241,12 +239,8 @@ static int snd_toneport_source_put(struct snd_kcontrol *kcontrol,
return 1;
}
static void toneport_start_pcm(struct work_struct *work)
static void toneport_startup(struct usb_line6 *line6)
{
struct usb_line6_toneport *toneport =
container_of(work, struct usb_line6_toneport, pcm_work.work);
struct usb_line6 *line6 = &toneport->line6;
line6_pcm_acquire(line6->line6pcm, LINE6_STREAM_MONITOR, true);
}
@ -394,7 +388,7 @@ static int toneport_setup(struct usb_line6_toneport *toneport)
if (toneport_has_led(toneport))
toneport_update_led(toneport);
schedule_delayed_work(&toneport->pcm_work,
schedule_delayed_work(&toneport->line6.startup_work,
msecs_to_jiffies(TONEPORT_PCM_DELAY * 1000));
return 0;
}
@ -404,10 +398,7 @@ static int toneport_setup(struct usb_line6_toneport *toneport)
*/
static void line6_toneport_disconnect(struct usb_line6 *line6)
{
struct usb_line6_toneport *toneport =
(struct usb_line6_toneport *)line6;
cancel_delayed_work_sync(&toneport->pcm_work);
struct usb_line6_toneport *toneport = line6_to_toneport(line6);
if (toneport_has_led(toneport))
toneport_remove_leds(toneport);
@ -421,12 +412,12 @@ 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;
struct usb_line6_toneport *toneport = line6_to_toneport(line6);
toneport->type = id->driver_info;
INIT_DELAYED_WORK(&toneport->pcm_work, toneport_start_pcm);
line6->disconnect = line6_toneport_disconnect;
line6->startup = toneport_startup;
/* initialize PCM subsystem: */
err = line6_init_pcm(line6, &toneport_pcm_properties);

View File

@ -26,13 +26,9 @@
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 {
@ -47,17 +43,12 @@ struct usb_line6_variax {
/* Buffer for activation code */
unsigned char *buffer_activate;
/* Handler for device initialization */
struct work_struct startup_work;
/* Timers for device initialization */
struct timer_list startup_timer1;
struct timer_list startup_timer2;
/* Current progress in startup procedure */
int startup_progress;
};
#define line6_to_variax(x) container_of(x, struct usb_line6_variax, line6)
#define VARIAX_OFFSET_ACTIVATE 7
/*
@ -81,11 +72,6 @@ static const char variax_activate[] = {
0xf7
};
/* forward declarations: */
static void variax_startup2(struct timer_list *t);
static void variax_startup4(struct timer_list *t);
static void variax_startup5(struct timer_list *t);
static void variax_activate_async(struct usb_line6_variax *variax, int a)
{
variax->buffer_activate[VARIAX_OFFSET_ACTIVATE] = a;
@ -100,74 +86,30 @@ static void variax_activate_async(struct usb_line6_variax *variax, int a)
context). After the last one has finished, the device is ready to use.
*/
static void variax_startup1(struct usb_line6_variax *variax)
static void variax_startup(struct usb_line6 *line6)
{
CHECK_STARTUP_PROGRESS(variax->startup_progress, VARIAX_STARTUP_INIT);
struct usb_line6_variax *variax = line6_to_variax(line6);
/* delay startup procedure: */
line6_start_timer(&variax->startup_timer1, VARIAX_STARTUP_DELAY1,
variax_startup2);
}
static void variax_startup2(struct timer_list *t)
{
struct usb_line6_variax *variax = from_timer(variax, t, startup_timer1);
struct usb_line6 *line6 = &variax->line6;
/* schedule another startup procedure until startup is complete: */
if (variax->startup_progress >= VARIAX_STARTUP_LAST)
return;
variax->startup_progress = VARIAX_STARTUP_VERSIONREQ;
line6_start_timer(&variax->startup_timer1, VARIAX_STARTUP_DELAY1,
variax_startup2);
/* request firmware version: */
line6_version_request_async(line6);
}
static void variax_startup3(struct usb_line6_variax *variax)
{
CHECK_STARTUP_PROGRESS(variax->startup_progress, VARIAX_STARTUP_WAIT);
/* delay startup procedure: */
line6_start_timer(&variax->startup_timer2, VARIAX_STARTUP_DELAY3,
variax_startup4);
}
static void variax_startup4(struct timer_list *t)
{
struct usb_line6_variax *variax = from_timer(variax, t, startup_timer2);
CHECK_STARTUP_PROGRESS(variax->startup_progress,
VARIAX_STARTUP_ACTIVATE);
/* activate device: */
variax_activate_async(variax, 1);
line6_start_timer(&variax->startup_timer2, VARIAX_STARTUP_DELAY4,
variax_startup5);
}
static void variax_startup5(struct timer_list *t)
{
struct usb_line6_variax *variax = from_timer(variax, t, startup_timer2);
CHECK_STARTUP_PROGRESS(variax->startup_progress,
VARIAX_STARTUP_WORKQUEUE);
/* schedule work for global work queue: */
schedule_work(&variax->startup_work);
}
static void variax_startup6(struct work_struct *work)
{
struct usb_line6_variax *variax =
container_of(work, struct usb_line6_variax, startup_work);
CHECK_STARTUP_PROGRESS(variax->startup_progress, VARIAX_STARTUP_SETUP);
/* ALSA audio interface: */
snd_card_register(variax->line6.card);
switch (variax->startup_progress) {
case VARIAX_STARTUP_VERSIONREQ:
/* repeat request until getting the response */
schedule_delayed_work(&line6->startup_work,
msecs_to_jiffies(VARIAX_STARTUP_DELAY1));
/* request firmware version: */
line6_version_request_async(line6);
break;
case VARIAX_STARTUP_ACTIVATE:
/* activate device: */
variax_activate_async(variax, 1);
variax->startup_progress = VARIAX_STARTUP_SETUP;
schedule_delayed_work(&line6->startup_work,
msecs_to_jiffies(VARIAX_STARTUP_DELAY4));
break;
case VARIAX_STARTUP_SETUP:
/* ALSA audio interface: */
snd_card_register(variax->line6.card);
break;
}
}
/*
@ -175,7 +117,7 @@ static void variax_startup6(struct work_struct *work)
*/
static void line6_variax_process_message(struct usb_line6 *line6)
{
struct usb_line6_variax *variax = (struct usb_line6_variax *) line6;
struct usb_line6_variax *variax = line6_to_variax(line6);
const unsigned char *buf = variax->line6.buffer_message;
switch (buf[0]) {
@ -186,11 +128,19 @@ static void line6_variax_process_message(struct usb_line6 *line6)
case LINE6_SYSEX_BEGIN:
if (memcmp(buf + 1, variax_init_version + 1,
sizeof(variax_init_version) - 1) == 0) {
variax_startup3(variax);
if (variax->startup_progress >= VARIAX_STARTUP_ACTIVATE)
break;
variax->startup_progress = VARIAX_STARTUP_ACTIVATE;
cancel_delayed_work(&line6->startup_work);
schedule_delayed_work(&line6->startup_work,
msecs_to_jiffies(VARIAX_STARTUP_DELAY3));
} else if (memcmp(buf + 1, variax_init_done + 1,
sizeof(variax_init_done) - 1) == 0) {
/* notify of complete initialization: */
variax_startup4(&variax->startup_timer2);
if (variax->startup_progress >= VARIAX_STARTUP_SETUP)
break;
cancel_delayed_work(&line6->startup_work);
schedule_delayed_work(&line6->startup_work, 0);
}
break;
}
@ -201,11 +151,7 @@ static void line6_variax_process_message(struct usb_line6 *line6)
*/
static void line6_variax_disconnect(struct usb_line6 *line6)
{
struct usb_line6_variax *variax = (struct usb_line6_variax *)line6;
del_timer(&variax->startup_timer1);
del_timer(&variax->startup_timer2);
cancel_work_sync(&variax->startup_work);
struct usb_line6_variax *variax = line6_to_variax(line6);
kfree(variax->buffer_activate);
}
@ -216,15 +162,12 @@ static void line6_variax_disconnect(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;
struct usb_line6_variax *variax = line6_to_variax(line6);
int err;
line6->process_message = line6_variax_process_message;
line6->disconnect = line6_variax_disconnect;
timer_setup(&variax->startup_timer1, NULL, 0);
timer_setup(&variax->startup_timer2, NULL, 0);
INIT_WORK(&variax->startup_work, variax_startup6);
line6->startup = variax_startup;
/* initialize USB buffers: */
variax->buffer_activate = kmemdup(variax_activate,
@ -239,7 +182,8 @@ static int variax_init(struct usb_line6 *line6,
return err;
/* initiate startup procedure: */
variax_startup1(variax);
schedule_delayed_work(&line6->startup_work,
msecs_to_jiffies(VARIAX_STARTUP_DELAY1));
return 0;
}