staging: comedi: 8255_pci: fix possible NULL deref during detach
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / staging / line6 / variax.c
1 /*
2 * Line6 Linux USB driver - 0.9.1beta
3 *
4 * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation, version 2.
9 *
10 */
11
12 #include <linux/slab.h>
13
14 #include "audio.h"
15 #include "control.h"
16 #include "driver.h"
17 #include "variax.h"
18
19 #define VARIAX_SYSEX_CODE 7
20 #define VARIAX_SYSEX_PARAM 0x3b
21 #define VARIAX_SYSEX_ACTIVATE 0x2a
22 #define VARIAX_MODEL_HEADER_LENGTH 7
23 #define VARIAX_MODEL_MESSAGE_LENGTH 199
24 #define VARIAX_OFFSET_ACTIVATE 7
25
26 /*
27 This message is sent by the device during initialization and identifies
28 the connected guitar model.
29 */
30 static const char variax_init_model[] = {
31 0xf0, 0x00, 0x01, 0x0c, 0x07, 0x00, 0x69, 0x02,
32 0x00
33 };
34
35 /*
36 This message is sent by the device during initialization and identifies
37 the connected guitar version.
38 */
39 static const char variax_init_version[] = {
40 0xf0, 0x7e, 0x7f, 0x06, 0x02, 0x00, 0x01, 0x0c,
41 0x07, 0x00, 0x00, 0x00
42 };
43
44 /*
45 This message is the last one sent by the device during initialization.
46 */
47 static const char variax_init_done[] = {
48 0xf0, 0x00, 0x01, 0x0c, 0x07, 0x00, 0x6b
49 };
50
51 static const char variax_activate[] = {
52 0xf0, 0x00, 0x01, 0x0c, 0x07, 0x00, 0x2a, 0x01,
53 0xf7
54 };
55
56 static const char variax_request_bank[] = {
57 0xf0, 0x00, 0x01, 0x0c, 0x07, 0x00, 0x6d, 0xf7
58 };
59
60 static const char variax_request_model1[] = {
61 0xf0, 0x00, 0x01, 0x0c, 0x07, 0x00, 0x3c, 0x00,
62 0x02, 0x00, 0x00, 0x00, 0x00, 0x03, 0x05, 0x03,
63 0x00, 0x00, 0x00, 0xf7
64 };
65
66 static const char variax_request_model2[] = {
67 0xf0, 0x00, 0x01, 0x0c, 0x07, 0x00, 0x3c, 0x00,
68 0x02, 0x00, 0x00, 0x00, 0x00, 0x03, 0x07, 0x03,
69 0x00, 0x00, 0x00, 0xf7
70 };
71
72 /* forward declarations: */
73 static int variax_create_files2(struct device *dev);
74 static void variax_startup2(unsigned long data);
75 static void variax_startup4(unsigned long data);
76 static void variax_startup5(unsigned long data);
77
78 /*
79 Decode data transmitted by workbench.
80 */
81 static void variax_decode(const unsigned char *raw_data, unsigned char *data,
82 int raw_size)
83 {
84 for (; raw_size > 0; raw_size -= 6) {
85 data[2] = raw_data[0] | (raw_data[1] << 4);
86 data[1] = raw_data[2] | (raw_data[3] << 4);
87 data[0] = raw_data[4] | (raw_data[5] << 4);
88 raw_data += 6;
89 data += 3;
90 }
91 }
92
93 static void variax_activate_async(struct usb_line6_variax *variax, int a)
94 {
95 variax->buffer_activate[VARIAX_OFFSET_ACTIVATE] = a;
96 line6_send_raw_message_async(&variax->line6, variax->buffer_activate,
97 sizeof(variax_activate));
98 }
99
100 /*
101 Variax startup procedure.
102 This is a sequence of functions with special requirements (e.g., must
103 not run immediately after initialization, must not run in interrupt
104 context). After the last one has finished, the device is ready to use.
105 */
106
107 static void variax_startup1(struct usb_line6_variax *variax)
108 {
109 CHECK_STARTUP_PROGRESS(variax->startup_progress, VARIAX_STARTUP_INIT);
110
111 /* delay startup procedure: */
112 line6_start_timer(&variax->startup_timer1, VARIAX_STARTUP_DELAY1,
113 variax_startup2, (unsigned long)variax);
114 }
115
116 static void variax_startup2(unsigned long data)
117 {
118 struct usb_line6_variax *variax = (struct usb_line6_variax *)data;
119 struct usb_line6 *line6 = &variax->line6;
120
121 /* schedule another startup procedure until startup is complete: */
122 if (variax->startup_progress >= VARIAX_STARTUP_LAST)
123 return;
124
125 variax->startup_progress = VARIAX_STARTUP_VERSIONREQ;
126 line6_start_timer(&variax->startup_timer1, VARIAX_STARTUP_DELAY1,
127 variax_startup2, (unsigned long)variax);
128
129 /* request firmware version: */
130 line6_version_request_async(line6);
131 }
132
133 static void variax_startup3(struct usb_line6_variax *variax)
134 {
135 CHECK_STARTUP_PROGRESS(variax->startup_progress, VARIAX_STARTUP_WAIT);
136
137 /* delay startup procedure: */
138 line6_start_timer(&variax->startup_timer2, VARIAX_STARTUP_DELAY3,
139 variax_startup4, (unsigned long)variax);
140 }
141
142 static void variax_startup4(unsigned long data)
143 {
144 struct usb_line6_variax *variax = (struct usb_line6_variax *)data;
145 CHECK_STARTUP_PROGRESS(variax->startup_progress,
146 VARIAX_STARTUP_ACTIVATE);
147
148 /* activate device: */
149 variax_activate_async(variax, 1);
150 line6_start_timer(&variax->startup_timer2, VARIAX_STARTUP_DELAY4,
151 variax_startup5, (unsigned long)variax);
152 }
153
154 static void variax_startup5(unsigned long data)
155 {
156 struct usb_line6_variax *variax = (struct usb_line6_variax *)data;
157 CHECK_STARTUP_PROGRESS(variax->startup_progress,
158 VARIAX_STARTUP_DUMPREQ);
159
160 /* current model dump: */
161 line6_dump_request_async(&variax->dumpreq, &variax->line6, 0,
162 VARIAX_DUMP_PASS1);
163 /* passes 2 and 3 are performed implicitly before entering variax_startup6 */
164 }
165
166 static void variax_startup6(struct usb_line6_variax *variax)
167 {
168 CHECK_STARTUP_PROGRESS(variax->startup_progress,
169 VARIAX_STARTUP_WORKQUEUE);
170
171 /* schedule work for global work queue: */
172 schedule_work(&variax->startup_work);
173 }
174
175 static void variax_startup7(struct work_struct *work)
176 {
177 struct usb_line6_variax *variax =
178 container_of(work, struct usb_line6_variax, startup_work);
179 struct usb_line6 *line6 = &variax->line6;
180
181 CHECK_STARTUP_PROGRESS(variax->startup_progress, VARIAX_STARTUP_SETUP);
182
183 /* ALSA audio interface: */
184 line6_register_audio(&variax->line6);
185
186 /* device files: */
187 line6_variax_create_files(0, 0, line6->ifcdev);
188 variax_create_files2(line6->ifcdev);
189 }
190
191 /*
192 Process a completely received message.
193 */
194 void line6_variax_process_message(struct usb_line6_variax *variax)
195 {
196 const unsigned char *buf = variax->line6.buffer_message;
197
198 switch (buf[0]) {
199 case LINE6_PARAM_CHANGE | LINE6_CHANNEL_HOST:
200 switch (buf[1]) {
201 case VARIAXMIDI_volume:
202 variax->volume = buf[2];
203 break;
204
205 case VARIAXMIDI_tone:
206 variax->tone = buf[2];
207 }
208
209 break;
210
211 case LINE6_PROGRAM_CHANGE | LINE6_CHANNEL_DEVICE:
212 case LINE6_PROGRAM_CHANGE | LINE6_CHANNEL_HOST:
213 variax->model = buf[1];
214 line6_dump_request_async(&variax->dumpreq, &variax->line6, 0,
215 VARIAX_DUMP_PASS1);
216 break;
217
218 case LINE6_RESET:
219 dev_info(variax->line6.ifcdev, "VARIAX reset\n");
220 break;
221
222 case LINE6_SYSEX_BEGIN:
223 if (memcmp(buf + 1, variax_request_model1 + 1,
224 VARIAX_MODEL_HEADER_LENGTH - 1) == 0) {
225 if (variax->line6.message_length ==
226 VARIAX_MODEL_MESSAGE_LENGTH) {
227 switch (variax->dumpreq.in_progress) {
228 case VARIAX_DUMP_PASS1:
229 variax_decode(buf +
230 VARIAX_MODEL_HEADER_LENGTH,
231 (unsigned char *)
232 &variax->model_data,
233 (sizeof
234 (variax->model_data.
235 name) +
236 sizeof(variax->
237 model_data.
238 control)
239 / 2) * 2);
240 line6_dump_request_async
241 (&variax->dumpreq, &variax->line6,
242 1, VARIAX_DUMP_PASS2);
243 break;
244
245 case VARIAX_DUMP_PASS2:
246 /* model name is transmitted twice, so skip it here: */
247 variax_decode(buf +
248 VARIAX_MODEL_HEADER_LENGTH,
249 (unsigned char *)
250 &variax->
251 model_data.control +
252 sizeof(variax->model_data.
253 control)
254 / 2,
255 sizeof(variax->model_data.
256 control)
257 / 2 * 2);
258 line6_dump_request_async
259 (&variax->dumpreq, &variax->line6,
260 2, VARIAX_DUMP_PASS3);
261 }
262 } else {
263 DEBUG_MESSAGES(dev_err
264 (variax->line6.ifcdev,
265 "illegal length %d of model data\n",
266 variax->line6.message_length));
267 line6_dump_finished(&variax->dumpreq);
268 }
269 } else if (memcmp(buf + 1, variax_request_bank + 1,
270 sizeof(variax_request_bank) - 2) == 0) {
271 memcpy(variax->bank,
272 buf + sizeof(variax_request_bank) - 1,
273 sizeof(variax->bank));
274 line6_dump_finished(&variax->dumpreq);
275 variax_startup6(variax);
276 } else if (memcmp(buf + 1, variax_init_model + 1,
277 sizeof(variax_init_model) - 1) == 0) {
278 memcpy(variax->guitar,
279 buf + sizeof(variax_init_model),
280 sizeof(variax->guitar));
281 } else if (memcmp(buf + 1, variax_init_version + 1,
282 sizeof(variax_init_version) - 1) == 0) {
283 variax_startup3(variax);
284 } else if (memcmp(buf + 1, variax_init_done + 1,
285 sizeof(variax_init_done) - 1) == 0) {
286 /* notify of complete initialization: */
287 variax_startup4((unsigned long)variax);
288 }
289
290 break;
291
292 case LINE6_SYSEX_END:
293 break;
294
295 default:
296 DEBUG_MESSAGES(dev_err
297 (variax->line6.ifcdev,
298 "Variax: unknown message %02X\n", buf[0]));
299 }
300 }
301
302 /*
303 "read" request on "volume" special file.
304 */
305 static ssize_t variax_get_volume(struct device *dev,
306 struct device_attribute *attr, char *buf)
307 {
308 struct usb_line6_variax *variax =
309 usb_get_intfdata(to_usb_interface(dev));
310 return sprintf(buf, "%d\n", variax->volume);
311 }
312
313 /*
314 "write" request on "volume" special file.
315 */
316 static ssize_t variax_set_volume(struct device *dev,
317 struct device_attribute *attr,
318 const char *buf, size_t count)
319 {
320 struct usb_line6_variax *variax =
321 usb_get_intfdata(to_usb_interface(dev));
322 u8 value;
323 int ret;
324
325 ret = kstrtou8(buf, 10, &value);
326 if (ret)
327 return ret;
328
329 if (line6_transmit_parameter(&variax->line6, VARIAXMIDI_volume,
330 value) == 0)
331 variax->volume = value;
332
333 return count;
334 }
335
336 /*
337 "read" request on "model" special file.
338 */
339 static ssize_t variax_get_model(struct device *dev,
340 struct device_attribute *attr, char *buf)
341 {
342 struct usb_line6_variax *variax =
343 usb_get_intfdata(to_usb_interface(dev));
344 return sprintf(buf, "%d\n", variax->model);
345 }
346
347 /*
348 "write" request on "model" special file.
349 */
350 static ssize_t variax_set_model(struct device *dev,
351 struct device_attribute *attr,
352 const char *buf, size_t count)
353 {
354 struct usb_line6_variax *variax =
355 usb_get_intfdata(to_usb_interface(dev));
356 u8 value;
357 int ret;
358
359 ret = kstrtou8(buf, 10, &value);
360 if (ret)
361 return ret;
362
363 if (line6_send_program(&variax->line6, value) == 0)
364 variax->model = value;
365
366 return count;
367 }
368
369 /*
370 "read" request on "active" special file.
371 */
372 static ssize_t variax_get_active(struct device *dev,
373 struct device_attribute *attr, char *buf)
374 {
375 struct usb_line6_variax *variax =
376 usb_get_intfdata(to_usb_interface(dev));
377 return sprintf(buf, "%d\n",
378 variax->buffer_activate[VARIAX_OFFSET_ACTIVATE]);
379 }
380
381 /*
382 "write" request on "active" special file.
383 */
384 static ssize_t variax_set_active(struct device *dev,
385 struct device_attribute *attr,
386 const char *buf, size_t count)
387 {
388 struct usb_line6_variax *variax =
389 usb_get_intfdata(to_usb_interface(dev));
390 u8 value;
391 int ret;
392
393 ret = kstrtou8(buf, 10, &value);
394 if (ret)
395 return ret;
396
397 variax_activate_async(variax, value ? 1 : 0);
398 return count;
399 }
400
401 /*
402 "read" request on "tone" special file.
403 */
404 static ssize_t variax_get_tone(struct device *dev,
405 struct device_attribute *attr, char *buf)
406 {
407 struct usb_line6_variax *variax =
408 usb_get_intfdata(to_usb_interface(dev));
409 return sprintf(buf, "%d\n", variax->tone);
410 }
411
412 /*
413 "write" request on "tone" special file.
414 */
415 static ssize_t variax_set_tone(struct device *dev,
416 struct device_attribute *attr,
417 const char *buf, size_t count)
418 {
419 struct usb_line6_variax *variax =
420 usb_get_intfdata(to_usb_interface(dev));
421 u8 value;
422 int ret;
423
424 ret = kstrtou8(buf, 10, &value);
425 if (ret)
426 return ret;
427
428 if (line6_transmit_parameter(&variax->line6, VARIAXMIDI_tone,
429 value) == 0)
430 variax->tone = value;
431
432 return count;
433 }
434
435 static ssize_t get_string(char *buf, const char *data, int length)
436 {
437 int i;
438 memcpy(buf, data, length);
439
440 for (i = length; i--;) {
441 char c = buf[i];
442
443 if ((c != 0) && (c != ' '))
444 break;
445 }
446
447 buf[i + 1] = '\n';
448 return i + 2;
449 }
450
451 /*
452 "read" request on "name" special file.
453 */
454 static ssize_t variax_get_name(struct device *dev,
455 struct device_attribute *attr, char *buf)
456 {
457 struct usb_line6_variax *variax =
458 usb_get_intfdata(to_usb_interface(dev));
459 line6_dump_wait_interruptible(&variax->dumpreq);
460 return get_string(buf, variax->model_data.name,
461 sizeof(variax->model_data.name));
462 }
463
464 /*
465 "read" request on "bank" special file.
466 */
467 static ssize_t variax_get_bank(struct device *dev,
468 struct device_attribute *attr, char *buf)
469 {
470 struct usb_line6_variax *variax =
471 usb_get_intfdata(to_usb_interface(dev));
472 line6_dump_wait_interruptible(&variax->dumpreq);
473 return get_string(buf, variax->bank, sizeof(variax->bank));
474 }
475
476 /*
477 "read" request on "dump" special file.
478 */
479 static ssize_t variax_get_dump(struct device *dev,
480 struct device_attribute *attr, char *buf)
481 {
482 struct usb_line6_variax *variax =
483 usb_get_intfdata(to_usb_interface(dev));
484 int retval;
485 retval = line6_dump_wait_interruptible(&variax->dumpreq);
486 if (retval < 0)
487 return retval;
488 memcpy(buf, &variax->model_data.control,
489 sizeof(variax->model_data.control));
490 return sizeof(variax->model_data.control);
491 }
492
493 /*
494 "read" request on "guitar" special file.
495 */
496 static ssize_t variax_get_guitar(struct device *dev,
497 struct device_attribute *attr, char *buf)
498 {
499 struct usb_line6_variax *variax =
500 usb_get_intfdata(to_usb_interface(dev));
501 return sprintf(buf, "%s\n", variax->guitar);
502 }
503
504 #ifdef CONFIG_LINE6_USB_RAW
505
506 static char *variax_alloc_sysex_buffer(struct usb_line6_variax *variax,
507 int code, int size)
508 {
509 return line6_alloc_sysex_buffer(&variax->line6, VARIAX_SYSEX_CODE, code,
510 size);
511 }
512
513 /*
514 "write" request on "raw" special file.
515 */
516 static ssize_t variax_set_raw2(struct device *dev,
517 struct device_attribute *attr,
518 const char *buf, size_t count)
519 {
520 struct usb_line6_variax *variax =
521 usb_get_intfdata(to_usb_interface(dev));
522 int size;
523 int i;
524 char *sysex;
525
526 count -= count % 3;
527 size = count * 2;
528 sysex = variax_alloc_sysex_buffer(variax, VARIAX_SYSEX_PARAM, size);
529
530 if (!sysex)
531 return 0;
532
533 for (i = 0; i < count; i += 3) {
534 const unsigned char *p1 = buf + i;
535 char *p2 = sysex + SYSEX_DATA_OFS + i * 2;
536 p2[0] = p1[2] & 0x0f;
537 p2[1] = p1[2] >> 4;
538 p2[2] = p1[1] & 0x0f;
539 p2[3] = p1[1] >> 4;
540 p2[4] = p1[0] & 0x0f;
541 p2[5] = p1[0] >> 4;
542 }
543
544 line6_send_sysex_message(&variax->line6, sysex, size);
545 kfree(sysex);
546 return count;
547 }
548
549 #endif
550
551 /* Variax workbench special files: */
552 static DEVICE_ATTR(model, S_IWUSR | S_IRUGO, variax_get_model,
553 variax_set_model);
554 static DEVICE_ATTR(volume, S_IWUSR | S_IRUGO, variax_get_volume,
555 variax_set_volume);
556 static DEVICE_ATTR(tone, S_IWUSR | S_IRUGO, variax_get_tone, variax_set_tone);
557 static DEVICE_ATTR(name, S_IRUGO, variax_get_name, line6_nop_write);
558 static DEVICE_ATTR(bank, S_IRUGO, variax_get_bank, line6_nop_write);
559 static DEVICE_ATTR(dump, S_IRUGO, variax_get_dump, line6_nop_write);
560 static DEVICE_ATTR(active, S_IWUSR | S_IRUGO, variax_get_active,
561 variax_set_active);
562 static DEVICE_ATTR(guitar, S_IRUGO, variax_get_guitar, line6_nop_write);
563
564 #ifdef CONFIG_LINE6_USB_RAW
565 static DEVICE_ATTR(raw, S_IWUSR, line6_nop_read, line6_set_raw);
566 static DEVICE_ATTR(raw2, S_IWUSR, line6_nop_read, variax_set_raw2);
567 #endif
568
569 /*
570 Variax destructor.
571 */
572 static void variax_destruct(struct usb_interface *interface)
573 {
574 struct usb_line6_variax *variax = usb_get_intfdata(interface);
575
576 if (variax == NULL)
577 return;
578 line6_cleanup_audio(&variax->line6);
579
580 del_timer(&variax->startup_timer1);
581 del_timer(&variax->startup_timer2);
582 cancel_work_sync(&variax->startup_work);
583
584 /* free dump request data: */
585 line6_dumpreq_destructbuf(&variax->dumpreq, 2);
586 line6_dumpreq_destructbuf(&variax->dumpreq, 1);
587 line6_dumpreq_destruct(&variax->dumpreq);
588
589 kfree(variax->buffer_activate);
590 }
591
592 /*
593 Create sysfs entries.
594 */
595 static int variax_create_files2(struct device *dev)
596 {
597 int err;
598 CHECK_RETURN(device_create_file(dev, &dev_attr_model));
599 CHECK_RETURN(device_create_file(dev, &dev_attr_volume));
600 CHECK_RETURN(device_create_file(dev, &dev_attr_tone));
601 CHECK_RETURN(device_create_file(dev, &dev_attr_name));
602 CHECK_RETURN(device_create_file(dev, &dev_attr_bank));
603 CHECK_RETURN(device_create_file(dev, &dev_attr_dump));
604 CHECK_RETURN(device_create_file(dev, &dev_attr_active));
605 CHECK_RETURN(device_create_file(dev, &dev_attr_guitar));
606 #ifdef CONFIG_LINE6_USB_RAW
607 CHECK_RETURN(device_create_file(dev, &dev_attr_raw));
608 CHECK_RETURN(device_create_file(dev, &dev_attr_raw2));
609 #endif
610 return 0;
611 }
612
613 /*
614 Try to init workbench device.
615 */
616 static int variax_try_init(struct usb_interface *interface,
617 struct usb_line6_variax *variax)
618 {
619 int err;
620
621 init_timer(&variax->startup_timer1);
622 init_timer(&variax->startup_timer2);
623 INIT_WORK(&variax->startup_work, variax_startup7);
624
625 if ((interface == NULL) || (variax == NULL))
626 return -ENODEV;
627
628 /* initialize USB buffers: */
629 err = line6_dumpreq_init(&variax->dumpreq, variax_request_model1,
630 sizeof(variax_request_model1));
631
632 if (err < 0) {
633 dev_err(&interface->dev, "Out of memory\n");
634 return err;
635 }
636
637 err = line6_dumpreq_initbuf(&variax->dumpreq, variax_request_model2,
638 sizeof(variax_request_model2), 1);
639
640 if (err < 0) {
641 dev_err(&interface->dev, "Out of memory\n");
642 return err;
643 }
644
645 err = line6_dumpreq_initbuf(&variax->dumpreq, variax_request_bank,
646 sizeof(variax_request_bank), 2);
647
648 if (err < 0) {
649 dev_err(&interface->dev, "Out of memory\n");
650 return err;
651 }
652
653 variax->buffer_activate = kmemdup(variax_activate,
654 sizeof(variax_activate), GFP_KERNEL);
655
656 if (variax->buffer_activate == NULL) {
657 dev_err(&interface->dev, "Out of memory\n");
658 return -ENOMEM;
659 }
660
661 /* initialize audio system: */
662 err = line6_init_audio(&variax->line6);
663 if (err < 0)
664 return err;
665
666 /* initialize MIDI subsystem: */
667 err = line6_init_midi(&variax->line6);
668 if (err < 0)
669 return err;
670
671 /* initiate startup procedure: */
672 variax_startup1(variax);
673 return 0;
674 }
675
676 /*
677 Init workbench device (and clean up in case of failure).
678 */
679 int line6_variax_init(struct usb_interface *interface,
680 struct usb_line6_variax *variax)
681 {
682 int err = variax_try_init(interface, variax);
683
684 if (err < 0)
685 variax_destruct(interface);
686
687 return err;
688 }
689
690 /*
691 Workbench device disconnected.
692 */
693 void line6_variax_disconnect(struct usb_interface *interface)
694 {
695 struct device *dev;
696
697 if (interface == NULL)
698 return;
699 dev = &interface->dev;
700
701 if (dev != NULL) {
702 /* remove sysfs entries: */
703 line6_variax_remove_files(0, 0, dev);
704 device_remove_file(dev, &dev_attr_model);
705 device_remove_file(dev, &dev_attr_volume);
706 device_remove_file(dev, &dev_attr_tone);
707 device_remove_file(dev, &dev_attr_name);
708 device_remove_file(dev, &dev_attr_bank);
709 device_remove_file(dev, &dev_attr_dump);
710 device_remove_file(dev, &dev_attr_active);
711 device_remove_file(dev, &dev_attr_guitar);
712 #ifdef CONFIG_LINE6_USB_RAW
713 device_remove_file(dev, &dev_attr_raw);
714 device_remove_file(dev, &dev_attr_raw2);
715 #endif
716 }
717
718 variax_destruct(interface);
719 }