Linux-libre 3.10.72-gnu
[librecmc/linux-libre.git] / drivers / staging / comedi / drivers / usbdux.c
1 /*
2    comedi/drivers/usbdux.c
3    Copyright (C) 2003-2007 Bernd Porr, Bernd.Porr@f2s.com
4
5    This program is free software; you can redistribute it and/or modify
6    it under the terms of the GNU General Public License as published by
7    the Free Software Foundation; either version 2 of the License, or
8    (at your option) any later version.
9
10    This program is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13    GNU General Public License for more details.
14
15    You should have received a copy of the GNU General Public License
16    along with this program; if not, write to the Free Software
17    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18
19  */
20 /*
21 Driver: usbdux
22 Description: University of Stirling USB DAQ & INCITE Technology Limited
23 Devices: [ITL] USB-DUX (usbdux.o)
24 Author: Bernd Porr <BerndPorr@f2s.com>
25 Updated: 8 Dec 2008
26 Status: Stable
27 Configuration options:
28   You have to upload firmware with the -i option. The
29   firmware is usually installed under /usr/share/usb or
30   /usr/local/share/usb or /lib/firmware.
31
32 Connection scheme for the counter at the digital port:
33   0=/CLK0, 1=UP/DOWN0, 2=RESET0, 4=/CLK1, 5=UP/DOWN1, 6=RESET1.
34   The sampling rate of the counter is approximately 500Hz.
35
36 Please note that under USB2.0 the length of the channel list determines
37 the max sampling rate. If you sample only one channel you get 8kHz
38 sampling rate. If you sample two channels you get 4kHz and so on.
39 */
40 /*
41  * I must give credit here to Chris Baugher who
42  * wrote the driver for AT-MIO-16d. I used some parts of this
43  * driver. I also must give credits to David Brownell
44  * who supported me with the USB development.
45  *
46  * Bernd Porr
47  *
48  *
49  * Revision history:
50  * 0.94: D/A output should work now with any channel list combinations
51  * 0.95: .owner commented out for kernel vers below 2.4.19
52  *       sanity checks in ai/ao_cmd
53  * 0.96: trying to get it working with 2.6, moved all memory alloc to comedi's
54  *       attach final USB IDs
55  *       moved memory allocation completely to the corresponding comedi
56  *       functions firmware upload is by fxload and no longer by comedi (due to
57  *       enumeration)
58  * 0.97: USB IDs received, adjusted table
59  * 0.98: SMP, locking, memory alloc: moved all usb memory alloc
60  *       to the usb subsystem and moved all comedi related memory
61  *       alloc to comedi.
62  *       | kernel | registration | usbdux-usb | usbdux-comedi | comedi |
63  * 0.99: USB 2.0: changed protocol to isochronous transfer
64  *                IRQ transfer is too buggy and too risky in 2.0
65  *                for the high speed ISO transfer is now a working version
66  *                available
67  * 0.99b: Increased the iso transfer buffer for high sp.to 10 buffers. Some VIA
68  *        chipsets miss out IRQs. Deeper buffering is needed.
69  * 1.00: full USB 2.0 support for the A/D converter. Now: max 8kHz sampling
70  *       rate.
71  *       Firmware vers 1.00 is needed for this.
72  *       Two 16 bit up/down/reset counter with a sampling rate of 1kHz
73  *       And loads of cleaning up, in particular streamlining the
74  *       bulk transfers.
75  * 1.1:  moved EP4 transfers to EP1 to make space for a PWM output on EP4
76  * 1.2:  added PWM support via EP4
77  * 2.0:  PWM seems to be stable and is not interfering with the other functions
78  * 2.1:  changed PWM API
79  * 2.2:  added firmware kernel request to fix an udev problem
80  * 2.3:  corrected a bug in bulk timeouts which were far too short
81  * 2.4:  fixed a bug which causes the driver to hang when it ran out of data.
82  *       Thanks to Jan-Matthias Braun and Ian to spot the bug and fix it.
83  *
84  */
85
86 /* generates loads of debug info */
87 /* #define NOISY_DUX_DEBUGBUG */
88
89 #include <linux/kernel.h>
90 #include <linux/module.h>
91 #include <linux/init.h>
92 #include <linux/slab.h>
93 #include <linux/input.h>
94 #include <linux/usb.h>
95 #include <linux/fcntl.h>
96 #include <linux/compiler.h>
97 #include <linux/firmware.h>
98
99 #include "../comedidev.h"
100
101 #include "comedi_fc.h"
102
103 /* timeout for the USB-transfer in ms*/
104 #define BULK_TIMEOUT 1000
105
106 /* constants for "firmware" upload and download */
107 #define FIRMWARE "/*(DEBLOBBED)*/"
108 #define USBDUXSUB_FIRMWARE 0xA0
109 #define VENDOR_DIR_IN  0xC0
110 #define VENDOR_DIR_OUT 0x40
111
112 /* internal addresses of the 8051 processor */
113 #define USBDUXSUB_CPUCS 0xE600
114
115 /*
116  * the minor device number, major is 180 only for debugging purposes and to
117  * upload special firmware (programming the eeprom etc) which is not compatible
118  * with the comedi framwork
119  */
120 #define USBDUXSUB_MINOR 32
121
122 /* max lenghth of the transfer-buffer for software upload */
123 #define TB_LEN 0x2000
124
125 /* Input endpoint number: ISO/IRQ */
126 #define ISOINEP           6
127
128 /* Output endpoint number: ISO/IRQ */
129 #define ISOOUTEP          2
130
131 /* This EP sends DUX commands to USBDUX */
132 #define COMMAND_OUT_EP     1
133
134 /* This EP receives the DUX commands from USBDUX */
135 #define COMMAND_IN_EP        8
136
137 /* Output endpoint for PWM */
138 #define PWM_EP         4
139
140 /* 300Hz max frequ under PWM */
141 #define MIN_PWM_PERIOD  ((long)(1E9/300))
142
143 /* Default PWM frequency */
144 #define PWM_DEFAULT_PERIOD ((long)(1E9/100))
145
146 /* Number of channels */
147 #define NUMCHANNELS       8
148
149 /* Size of one A/D value */
150 #define SIZEADIN          ((sizeof(int16_t)))
151
152 /*
153  * Size of the input-buffer IN BYTES
154  * Always multiple of 8 for 8 microframes which is needed in the highspeed mode
155  */
156 #define SIZEINBUF         ((8*SIZEADIN))
157
158 /* 16 bytes. */
159 #define SIZEINSNBUF       16
160
161 /* Number of DA channels */
162 #define NUMOUTCHANNELS    8
163
164 /* size of one value for the D/A converter: channel and value */
165 #define SIZEDAOUT          ((sizeof(int8_t)+sizeof(int16_t)))
166
167 /*
168  * Size of the output-buffer in bytes
169  * Actually only the first 4 triplets are used but for the
170  * high speed mode we need to pad it to 8 (microframes).
171  */
172 #define SIZEOUTBUF         ((8*SIZEDAOUT))
173
174 /*
175  * Size of the buffer for the dux commands: just now max size is determined
176  * by the analogue out + command byte + panic bytes...
177  */
178 #define SIZEOFDUXBUFFER    ((8*SIZEDAOUT+2))
179
180 /* Number of in-URBs which receive the data: min=2 */
181 #define NUMOFINBUFFERSFULL     5
182
183 /* Number of out-URBs which send the data: min=2 */
184 #define NUMOFOUTBUFFERSFULL    5
185
186 /* Number of in-URBs which receive the data: min=5 */
187 /* must have more buffers due to buggy USB ctr */
188 #define NUMOFINBUFFERSHIGH     10
189
190 /* Number of out-URBs which send the data: min=5 */
191 /* must have more buffers due to buggy USB ctr */
192 #define NUMOFOUTBUFFERSHIGH    10
193
194 /* Total number of usbdux devices */
195 #define NUMUSBDUX             16
196
197 /* Analogue in subdevice */
198 #define SUBDEV_AD             0
199
200 /* Analogue out subdevice */
201 #define SUBDEV_DA             1
202
203 /* Digital I/O */
204 #define SUBDEV_DIO            2
205
206 /* counter */
207 #define SUBDEV_COUNTER        3
208
209 /* timer aka pwm output */
210 #define SUBDEV_PWM            4
211
212 /* number of retries to get the right dux command */
213 #define RETRIES 10
214
215 /**************************************************/
216 /* comedi constants */
217 static const struct comedi_lrange range_usbdux_ai_range = { 4, {
218                                                                 BIP_RANGE
219                                                                 (4.096),
220                                                                 BIP_RANGE(4.096
221                                                                           / 2),
222                                                                 UNI_RANGE
223                                                                 (4.096),
224                                                                 UNI_RANGE(4.096
225                                                                           / 2)
226                                                                 }
227 };
228
229 static const struct comedi_lrange range_usbdux_ao_range = { 2, {
230                                                                 BIP_RANGE
231                                                                 (4.096),
232                                                                 UNI_RANGE
233                                                                 (4.096),
234                                                                 }
235 };
236
237 /*
238  * private structure of one subdevice
239  */
240
241 /*
242  * This is the structure which holds all the data of
243  * this driver one sub device just now: A/D
244  */
245 struct usbduxsub {
246         /* attached? */
247         int attached;
248         /* is it associated with a subdevice? */
249         int probed;
250         /* pointer to the usb-device */
251         struct usb_device *usbdev;
252         /* actual number of in-buffers */
253         int num_in_buffers;
254         /* actual number of out-buffers */
255         int num_out_buffers;
256         /* ISO-transfer handling: buffers */
257         struct urb **urb_in;
258         struct urb **urb_out;
259         /* pwm-transfer handling */
260         struct urb *urb_pwm;
261         /* PWM period */
262         unsigned int pwm_period;
263         /* PWM internal delay for the GPIF in the FX2 */
264         int8_t pwn_delay;
265         /* size of the PWM buffer which holds the bit pattern */
266         int size_pwm_buf;
267         /* input buffer for the ISO-transfer */
268         int16_t *in_buffer;
269         /* input buffer for single insn */
270         int16_t *insn_buffer;
271         /* output buffer for single DA outputs */
272         int16_t *out_buffer;
273         /* interface number */
274         int ifnum;
275         /* interface structure in 2.6 */
276         struct usb_interface *interface;
277         /* comedi device for the interrupt context */
278         struct comedi_device *comedidev;
279         /* is it USB_SPEED_HIGH or not? */
280         short int high_speed;
281         /* asynchronous command is running */
282         short int ai_cmd_running;
283         short int ao_cmd_running;
284         /* pwm is running */
285         short int pwm_cmd_running;
286         /* continous acquisition */
287         short int ai_continous;
288         short int ao_continous;
289         /* number of samples to acquire */
290         int ai_sample_count;
291         int ao_sample_count;
292         /* time between samples in units of the timer */
293         unsigned int ai_timer;
294         unsigned int ao_timer;
295         /* counter between aquisitions */
296         unsigned int ai_counter;
297         unsigned int ao_counter;
298         /* interval in frames/uframes */
299         unsigned int ai_interval;
300         /* D/A commands */
301         int8_t *dac_commands;
302         /* commands */
303         int8_t *dux_commands;
304         struct semaphore sem;
305 };
306
307 /*
308  * The pointer to the private usb-data of the driver is also the private data
309  * for the comedi-device.  This has to be global as the usb subsystem needs
310  * global variables. The other reason is that this structure must be there
311  * _before_ any comedi command is issued. The usb subsystem must be initialised
312  * before comedi can access it.
313  */
314 static struct usbduxsub usbduxsub[NUMUSBDUX];
315
316 static DEFINE_SEMAPHORE(start_stop_sem);
317
318 /*
319  * Stops the data acquision
320  * It should be safe to call this function from any context
321  */
322 static int usbduxsub_unlink_inurbs(struct usbduxsub *usbduxsub_tmp)
323 {
324         int i = 0;
325         int err = 0;
326
327         if (usbduxsub_tmp && usbduxsub_tmp->urb_in) {
328                 for (i = 0; i < usbduxsub_tmp->num_in_buffers; i++) {
329                         if (usbduxsub_tmp->urb_in[i]) {
330                                 /* We wait here until all transfers have been
331                                  * cancelled. */
332                                 usb_kill_urb(usbduxsub_tmp->urb_in[i]);
333                         }
334                         dev_dbg(&usbduxsub_tmp->interface->dev,
335                                 "comedi: usbdux: unlinked InURB %d, err=%d\n",
336                                 i, err);
337                 }
338         }
339         return err;
340 }
341
342 /*
343  * This will stop a running acquisition operation
344  * Is called from within this driver from both the
345  * interrupt context and from comedi
346  */
347 static int usbdux_ai_stop(struct usbduxsub *this_usbduxsub, int do_unlink)
348 {
349         int ret = 0;
350
351         if (!this_usbduxsub) {
352                 pr_err("comedi?: usbdux_ai_stop: this_usbduxsub=NULL!\n");
353                 return -EFAULT;
354         }
355         dev_dbg(&this_usbduxsub->interface->dev, "comedi: usbdux_ai_stop\n");
356
357         if (do_unlink) {
358                 /* stop aquistion */
359                 ret = usbduxsub_unlink_inurbs(this_usbduxsub);
360         }
361
362         this_usbduxsub->ai_cmd_running = 0;
363
364         return ret;
365 }
366
367 /*
368  * This will cancel a running acquisition operation.
369  * This is called by comedi but never from inside the driver.
370  */
371 static int usbdux_ai_cancel(struct comedi_device *dev,
372                             struct comedi_subdevice *s)
373 {
374         struct usbduxsub *this_usbduxsub;
375         int res = 0;
376
377         /* force unlink of all urbs */
378         this_usbduxsub = dev->private;
379         if (!this_usbduxsub)
380                 return -EFAULT;
381
382         dev_dbg(&this_usbduxsub->interface->dev, "comedi: usbdux_ai_cancel\n");
383
384         /* prevent other CPUs from submitting new commands just now */
385         down(&this_usbduxsub->sem);
386         if (!(this_usbduxsub->probed)) {
387                 up(&this_usbduxsub->sem);
388                 return -ENODEV;
389         }
390         /* unlink only if the urb really has been submitted */
391         res = usbdux_ai_stop(this_usbduxsub, this_usbduxsub->ai_cmd_running);
392         up(&this_usbduxsub->sem);
393         return res;
394 }
395
396 /* analogue IN - interrupt service routine */
397 static void usbduxsub_ai_isoc_irq(struct urb *urb)
398 {
399         int i, err, n;
400         struct usbduxsub *this_usbduxsub;
401         struct comedi_device *this_comedidev;
402         struct comedi_subdevice *s;
403
404         /* the context variable points to the subdevice */
405         this_comedidev = urb->context;
406         /* the private structure of the subdevice is struct usbduxsub */
407         this_usbduxsub = this_comedidev->private;
408         /* subdevice which is the AD converter */
409         s = &this_comedidev->subdevices[SUBDEV_AD];
410
411         /* first we test if something unusual has just happened */
412         switch (urb->status) {
413         case 0:
414                 /* copy the result in the transfer buffer */
415                 memcpy(this_usbduxsub->in_buffer,
416                        urb->transfer_buffer, SIZEINBUF);
417                 break;
418         case -EILSEQ:
419                 /* error in the ISOchronous data */
420                 /* we don't copy the data into the transfer buffer */
421                 /* and recycle the last data byte */
422                 dev_dbg(&urb->dev->dev,
423                         "comedi%d: usbdux: CRC error in ISO IN stream.\n",
424                         this_usbduxsub->comedidev->minor);
425
426                 break;
427
428         case -ECONNRESET:
429         case -ENOENT:
430         case -ESHUTDOWN:
431         case -ECONNABORTED:
432                 /* happens after an unlink command */
433                 if (this_usbduxsub->ai_cmd_running) {
434                         /* we are still running a command */
435                         /* tell this comedi */
436                         s->async->events |= COMEDI_CB_EOA;
437                         s->async->events |= COMEDI_CB_ERROR;
438                         comedi_event(this_usbduxsub->comedidev, s);
439                         /* stop the transfer w/o unlink */
440                         usbdux_ai_stop(this_usbduxsub, 0);
441                 }
442                 return;
443
444         default:
445                 /* a real error on the bus */
446                 /* pass error to comedi if we are really running a command */
447                 if (this_usbduxsub->ai_cmd_running) {
448                         dev_err(&urb->dev->dev,
449                                 "Non-zero urb status received in ai intr "
450                                 "context: %d\n", urb->status);
451                         s->async->events |= COMEDI_CB_EOA;
452                         s->async->events |= COMEDI_CB_ERROR;
453                         comedi_event(this_usbduxsub->comedidev, s);
454                         /* don't do an unlink here */
455                         usbdux_ai_stop(this_usbduxsub, 0);
456                 }
457                 return;
458         }
459
460         /*
461          * at this point we are reasonably sure that nothing dodgy has happened
462          * are we running a command?
463          */
464         if (unlikely((!(this_usbduxsub->ai_cmd_running)))) {
465                 /*
466                  * not running a command, do not continue execution if no
467                  * asynchronous command is running in particular not resubmit
468                  */
469                 return;
470         }
471
472         urb->dev = this_usbduxsub->usbdev;
473
474         /* resubmit the urb */
475         err = usb_submit_urb(urb, GFP_ATOMIC);
476         if (unlikely(err < 0)) {
477                 dev_err(&urb->dev->dev,
478                         "comedi_: urb resubmit failed in int-context! err=%d\n",
479                         err);
480                 if (err == -EL2NSYNC)
481                         dev_err(&urb->dev->dev,
482                                 "buggy USB host controller or bug in IRQ "
483                                 "handler!\n");
484                 s->async->events |= COMEDI_CB_EOA;
485                 s->async->events |= COMEDI_CB_ERROR;
486                 comedi_event(this_usbduxsub->comedidev, s);
487                 /* don't do an unlink here */
488                 usbdux_ai_stop(this_usbduxsub, 0);
489                 return;
490         }
491
492         this_usbduxsub->ai_counter--;
493         if (likely(this_usbduxsub->ai_counter > 0))
494                 return;
495
496         /* timer zero, transfer measurements to comedi */
497         this_usbduxsub->ai_counter = this_usbduxsub->ai_timer;
498
499         /* test, if we transmit only a fixed number of samples */
500         if (!(this_usbduxsub->ai_continous)) {
501                 /* not continuous, fixed number of samples */
502                 this_usbduxsub->ai_sample_count--;
503                 /* all samples received? */
504                 if (this_usbduxsub->ai_sample_count < 0) {
505                         /* prevent a resubmit next time */
506                         usbdux_ai_stop(this_usbduxsub, 0);
507                         /* say comedi that the acquistion is over */
508                         s->async->events |= COMEDI_CB_EOA;
509                         comedi_event(this_usbduxsub->comedidev, s);
510                         return;
511                 }
512         }
513         /* get the data from the USB bus and hand it over to comedi */
514         n = s->async->cmd.chanlist_len;
515         for (i = 0; i < n; i++) {
516                 /* transfer data */
517                 if (CR_RANGE(s->async->cmd.chanlist[i]) <= 1) {
518                         err = comedi_buf_put
519                             (s->async,
520                              le16_to_cpu(this_usbduxsub->in_buffer[i]) ^ 0x800);
521                 } else {
522                         err = comedi_buf_put
523                             (s->async,
524                              le16_to_cpu(this_usbduxsub->in_buffer[i]));
525                 }
526                 if (unlikely(err == 0)) {
527                         /* buffer overflow */
528                         usbdux_ai_stop(this_usbduxsub, 0);
529                         return;
530                 }
531         }
532         /* tell comedi that data is there */
533         s->async->events |= COMEDI_CB_BLOCK | COMEDI_CB_EOS;
534         comedi_event(this_usbduxsub->comedidev, s);
535 }
536
537 static int usbduxsub_unlink_outurbs(struct usbduxsub *usbduxsub_tmp)
538 {
539         int i = 0;
540         int err = 0;
541
542         if (usbduxsub_tmp && usbduxsub_tmp->urb_out) {
543                 for (i = 0; i < usbduxsub_tmp->num_out_buffers; i++) {
544                         if (usbduxsub_tmp->urb_out[i])
545                                 usb_kill_urb(usbduxsub_tmp->urb_out[i]);
546
547                         dev_dbg(&usbduxsub_tmp->interface->dev,
548                                 "comedi: usbdux: unlinked OutURB %d: res=%d\n",
549                                 i, err);
550                 }
551         }
552         return err;
553 }
554
555 /* This will cancel a running acquisition operation
556  * in any context.
557  */
558 static int usbdux_ao_stop(struct usbduxsub *this_usbduxsub, int do_unlink)
559 {
560         int ret = 0;
561
562         if (!this_usbduxsub)
563                 return -EFAULT;
564         dev_dbg(&this_usbduxsub->interface->dev, "comedi: usbdux_ao_cancel\n");
565
566         if (do_unlink)
567                 ret = usbduxsub_unlink_outurbs(this_usbduxsub);
568
569         this_usbduxsub->ao_cmd_running = 0;
570
571         return ret;
572 }
573
574 /* force unlink, is called by comedi */
575 static int usbdux_ao_cancel(struct comedi_device *dev,
576                             struct comedi_subdevice *s)
577 {
578         struct usbduxsub *this_usbduxsub = dev->private;
579         int res = 0;
580
581         if (!this_usbduxsub)
582                 return -EFAULT;
583
584         /* prevent other CPUs from submitting a command just now */
585         down(&this_usbduxsub->sem);
586         if (!(this_usbduxsub->probed)) {
587                 up(&this_usbduxsub->sem);
588                 return -ENODEV;
589         }
590         /* unlink only if it is really running */
591         res = usbdux_ao_stop(this_usbduxsub, this_usbduxsub->ao_cmd_running);
592         up(&this_usbduxsub->sem);
593         return res;
594 }
595
596 static void usbduxsub_ao_isoc_irq(struct urb *urb)
597 {
598         int i, ret;
599         int8_t *datap;
600         struct usbduxsub *this_usbduxsub;
601         struct comedi_device *this_comedidev;
602         struct comedi_subdevice *s;
603
604         /* the context variable points to the subdevice */
605         this_comedidev = urb->context;
606         /* the private structure of the subdevice is struct usbduxsub */
607         this_usbduxsub = this_comedidev->private;
608
609         s = &this_comedidev->subdevices[SUBDEV_DA];
610
611         switch (urb->status) {
612         case 0:
613                 /* success */
614                 break;
615
616         case -ECONNRESET:
617         case -ENOENT:
618         case -ESHUTDOWN:
619         case -ECONNABORTED:
620                 /* after an unlink command, unplug, ... etc */
621                 /* no unlink needed here. Already shutting down. */
622                 if (this_usbduxsub->ao_cmd_running) {
623                         s->async->events |= COMEDI_CB_EOA;
624                         comedi_event(this_usbduxsub->comedidev, s);
625                         usbdux_ao_stop(this_usbduxsub, 0);
626                 }
627                 return;
628
629         default:
630                 /* a real error */
631                 if (this_usbduxsub->ao_cmd_running) {
632                         dev_err(&urb->dev->dev,
633                                 "comedi_: Non-zero urb status received in ao "
634                                 "intr context: %d\n", urb->status);
635                         s->async->events |= COMEDI_CB_ERROR;
636                         s->async->events |= COMEDI_CB_EOA;
637                         comedi_event(this_usbduxsub->comedidev, s);
638                         /* we do an unlink if we are in the high speed mode */
639                         usbdux_ao_stop(this_usbduxsub, 0);
640                 }
641                 return;
642         }
643
644         /* are we actually running? */
645         if (!(this_usbduxsub->ao_cmd_running))
646                 return;
647
648         /* normal operation: executing a command in this subdevice */
649         this_usbduxsub->ao_counter--;
650         if ((int)this_usbduxsub->ao_counter <= 0) {
651                 /* timer zero */
652                 this_usbduxsub->ao_counter = this_usbduxsub->ao_timer;
653
654                 /* handle non continous acquisition */
655                 if (!(this_usbduxsub->ao_continous)) {
656                         /* fixed number of samples */
657                         this_usbduxsub->ao_sample_count--;
658                         if (this_usbduxsub->ao_sample_count < 0) {
659                                 /* all samples transmitted */
660                                 usbdux_ao_stop(this_usbduxsub, 0);
661                                 s->async->events |= COMEDI_CB_EOA;
662                                 comedi_event(this_usbduxsub->comedidev, s);
663                                 /* no resubmit of the urb */
664                                 return;
665                         }
666                 }
667                 /* transmit data to the USB bus */
668                 ((uint8_t *) (urb->transfer_buffer))[0] =
669                     s->async->cmd.chanlist_len;
670                 for (i = 0; i < s->async->cmd.chanlist_len; i++) {
671                         short temp;
672                         if (i >= NUMOUTCHANNELS)
673                                 break;
674
675                         /* pointer to the DA */
676                         datap =
677                             (&(((int8_t *) urb->transfer_buffer)[i * 3 + 1]));
678                         /* get the data from comedi */
679                         ret = comedi_buf_get(s->async, &temp);
680                         datap[0] = temp;
681                         datap[1] = temp >> 8;
682                         datap[2] = this_usbduxsub->dac_commands[i];
683                         /* printk("data[0]=%x, data[1]=%x, data[2]=%x\n", */
684                         /* datap[0],datap[1],datap[2]); */
685                         if (ret < 0) {
686                                 dev_err(&urb->dev->dev,
687                                         "comedi: buffer underflow\n");
688                                 s->async->events |= COMEDI_CB_EOA;
689                                 s->async->events |= COMEDI_CB_OVERFLOW;
690                         }
691                         /* transmit data to comedi */
692                         s->async->events |= COMEDI_CB_BLOCK;
693                         comedi_event(this_usbduxsub->comedidev, s);
694                 }
695         }
696         urb->transfer_buffer_length = SIZEOUTBUF;
697         urb->dev = this_usbduxsub->usbdev;
698         urb->status = 0;
699         if (this_usbduxsub->ao_cmd_running) {
700                 if (this_usbduxsub->high_speed) {
701                         /* uframes */
702                         urb->interval = 8;
703                 } else {
704                         /* frames */
705                         urb->interval = 1;
706                 }
707                 urb->number_of_packets = 1;
708                 urb->iso_frame_desc[0].offset = 0;
709                 urb->iso_frame_desc[0].length = SIZEOUTBUF;
710                 urb->iso_frame_desc[0].status = 0;
711                 ret = usb_submit_urb(urb, GFP_ATOMIC);
712                 if (ret < 0) {
713                         dev_err(&urb->dev->dev,
714                                 "comedi_: ao urb resubm failed in int-cont. "
715                                 "ret=%d", ret);
716                         if (ret == EL2NSYNC)
717                                 dev_err(&urb->dev->dev,
718                                         "buggy USB host controller or bug in "
719                                         "IRQ handling!\n");
720
721                         s->async->events |= COMEDI_CB_EOA;
722                         s->async->events |= COMEDI_CB_ERROR;
723                         comedi_event(this_usbduxsub->comedidev, s);
724                         /* don't do an unlink here */
725                         usbdux_ao_stop(this_usbduxsub, 0);
726                 }
727         }
728 }
729
730 static int usbduxsub_start(struct usbduxsub *usbduxsub)
731 {
732         int errcode = 0;
733         uint8_t *local_transfer_buffer;
734
735         local_transfer_buffer = kmalloc(1, GFP_KERNEL);
736         if (!local_transfer_buffer)
737                 return -ENOMEM;
738
739         /* 7f92 to zero */
740         *local_transfer_buffer = 0;
741         errcode = usb_control_msg(usbduxsub->usbdev,
742                                   /* create a pipe for a control transfer */
743                                   usb_sndctrlpipe(usbduxsub->usbdev, 0),
744                                   /* bRequest, "Firmware" */
745                                   USBDUXSUB_FIRMWARE,
746                                   /* bmRequestType */
747                                   VENDOR_DIR_OUT,
748                                   /* Value */
749                                   USBDUXSUB_CPUCS,
750                                   /* Index */
751                                   0x0000,
752                                   /* address of the transfer buffer */
753                                   local_transfer_buffer,
754                                   /* Length */
755                                   1,
756                                   /* Timeout */
757                                   BULK_TIMEOUT);
758         if (errcode < 0)
759                 dev_err(&usbduxsub->interface->dev,
760                         "comedi_: control msg failed (start)\n");
761
762         kfree(local_transfer_buffer);
763         return errcode;
764 }
765
766 static int usbduxsub_stop(struct usbduxsub *usbduxsub)
767 {
768         int errcode = 0;
769         uint8_t *local_transfer_buffer;
770
771         local_transfer_buffer = kmalloc(1, GFP_KERNEL);
772         if (!local_transfer_buffer)
773                 return -ENOMEM;
774
775         /* 7f92 to one */
776         *local_transfer_buffer = 1;
777         errcode = usb_control_msg(usbduxsub->usbdev,
778                                   usb_sndctrlpipe(usbduxsub->usbdev, 0),
779                                   /* bRequest, "Firmware" */
780                                   USBDUXSUB_FIRMWARE,
781                                   /* bmRequestType */
782                                   VENDOR_DIR_OUT,
783                                   /* Value */
784                                   USBDUXSUB_CPUCS,
785                                   /* Index */
786                                   0x0000, local_transfer_buffer,
787                                   /* Length */
788                                   1,
789                                   /* Timeout */
790                                   BULK_TIMEOUT);
791         if (errcode < 0)
792                 dev_err(&usbduxsub->interface->dev,
793                         "comedi_: control msg failed (stop)\n");
794
795         kfree(local_transfer_buffer);
796         return errcode;
797 }
798
799 static int usbduxsub_upload(struct usbduxsub *usbduxsub,
800                             uint8_t *local_transfer_buffer,
801                             unsigned int start_addr, unsigned int len)
802 {
803         int errcode;
804
805         errcode = usb_control_msg(usbduxsub->usbdev,
806                                   usb_sndctrlpipe(usbduxsub->usbdev, 0),
807                                   /* brequest, firmware */
808                                   USBDUXSUB_FIRMWARE,
809                                   /* bmRequestType */
810                                   VENDOR_DIR_OUT,
811                                   /* value */
812                                   start_addr,
813                                   /* index */
814                                   0x0000,
815                                   /* our local safe buffer */
816                                   local_transfer_buffer,
817                                   /* length */
818                                   len,
819                                   /* timeout */
820                                   BULK_TIMEOUT);
821         dev_dbg(&usbduxsub->interface->dev, "comedi_: result=%d\n", errcode);
822         if (errcode < 0) {
823                 dev_err(&usbduxsub->interface->dev, "comedi_: upload failed\n");
824                 return errcode;
825         }
826         return 0;
827 }
828
829 #define FIRMWARE_MAX_LEN 0x2000
830
831 static int firmware_upload(struct usbduxsub *usbduxsub,
832                           const u8 *firmware_binary, int size_firmware)
833 {
834         int ret;
835         uint8_t *fw_buf;
836
837         if (!firmware_binary)
838                 return 0;
839
840         if (size_firmware > FIRMWARE_MAX_LEN) {
841                 dev_err(&usbduxsub->interface->dev,
842                         "usbdux firmware binary it too large for FX2.\n");
843                 return -ENOMEM;
844         }
845
846         /* we generate a local buffer for the firmware */
847         fw_buf = kmemdup(firmware_binary, size_firmware, GFP_KERNEL);
848         if (!fw_buf) {
849                 dev_err(&usbduxsub->interface->dev,
850                         "comedi_: mem alloc for firmware failed\n");
851                 return -ENOMEM;
852         }
853
854         ret = usbduxsub_stop(usbduxsub);
855         if (ret < 0) {
856                 dev_err(&usbduxsub->interface->dev,
857                         "comedi_: can not stop firmware\n");
858                 kfree(fw_buf);
859                 return ret;
860         }
861
862         ret = usbduxsub_upload(usbduxsub, fw_buf, 0, size_firmware);
863         if (ret < 0) {
864                 dev_err(&usbduxsub->interface->dev,
865                         "comedi_: firmware upload failed\n");
866                 kfree(fw_buf);
867                 return ret;
868         }
869         ret = usbduxsub_start(usbduxsub);
870         if (ret < 0) {
871                 dev_err(&usbduxsub->interface->dev,
872                         "comedi_: can not start firmware\n");
873                 kfree(fw_buf);
874                 return ret;
875         }
876         kfree(fw_buf);
877         return 0;
878 }
879
880 static int usbduxsub_submit_inurbs(struct usbduxsub *usbduxsub)
881 {
882         int i, err_flag;
883
884         if (!usbduxsub)
885                 return -EFAULT;
886
887         /* Submit all URBs and start the transfer on the bus */
888         for (i = 0; i < usbduxsub->num_in_buffers; i++) {
889                 /* in case of a resubmission after an unlink... */
890                 usbduxsub->urb_in[i]->interval = usbduxsub->ai_interval;
891                 usbduxsub->urb_in[i]->context = usbduxsub->comedidev;
892                 usbduxsub->urb_in[i]->dev = usbduxsub->usbdev;
893                 usbduxsub->urb_in[i]->status = 0;
894                 usbduxsub->urb_in[i]->transfer_flags = URB_ISO_ASAP;
895                 dev_dbg(&usbduxsub->interface->dev,
896                         "comedi%d: submitting in-urb[%d]: %p,%p intv=%d\n",
897                         usbduxsub->comedidev->minor, i,
898                         (usbduxsub->urb_in[i]->context),
899                         (usbduxsub->urb_in[i]->dev),
900                         (usbduxsub->urb_in[i]->interval));
901                 err_flag = usb_submit_urb(usbduxsub->urb_in[i], GFP_ATOMIC);
902                 if (err_flag) {
903                         dev_err(&usbduxsub->interface->dev,
904                                 "comedi_: ai: usb_submit_urb(%d) error %d\n",
905                                 i, err_flag);
906                         return err_flag;
907                 }
908         }
909         return 0;
910 }
911
912 static int usbduxsub_submit_outurbs(struct usbduxsub *usbduxsub)
913 {
914         int i, err_flag;
915
916         if (!usbduxsub)
917                 return -EFAULT;
918
919         for (i = 0; i < usbduxsub->num_out_buffers; i++) {
920                 dev_dbg(&usbduxsub->interface->dev,
921                         "comedi_: submitting out-urb[%d]\n", i);
922                 /* in case of a resubmission after an unlink... */
923                 usbduxsub->urb_out[i]->context = usbduxsub->comedidev;
924                 usbduxsub->urb_out[i]->dev = usbduxsub->usbdev;
925                 usbduxsub->urb_out[i]->status = 0;
926                 usbduxsub->urb_out[i]->transfer_flags = URB_ISO_ASAP;
927                 err_flag = usb_submit_urb(usbduxsub->urb_out[i], GFP_ATOMIC);
928                 if (err_flag) {
929                         dev_err(&usbduxsub->interface->dev,
930                                 "comedi_: ao: usb_submit_urb(%d) error %d\n",
931                                 i, err_flag);
932                         return err_flag;
933                 }
934         }
935         return 0;
936 }
937
938 static int usbdux_ai_cmdtest(struct comedi_device *dev,
939                              struct comedi_subdevice *s, struct comedi_cmd *cmd)
940 {
941         struct usbduxsub *this_usbduxsub = dev->private;
942         int err = 0, i;
943         unsigned int tmp_timer;
944
945         if (!(this_usbduxsub->probed))
946                 return -ENODEV;
947
948         /* Step 1 : check if triggers are trivially valid */
949
950         err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_INT);
951         err |= cfc_check_trigger_src(&cmd->scan_begin_src, TRIG_TIMER);
952         err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_NOW);
953         err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
954         err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
955
956         if (err)
957                 return 1;
958
959         /* Step 2a : make sure trigger sources are unique */
960
961         err |= cfc_check_trigger_is_unique(cmd->start_src);
962         err |= cfc_check_trigger_is_unique(cmd->stop_src);
963
964         /* Step 2b : and mutually compatible */
965
966         if (err)
967                 return 2;
968
969         /* Step 3: check if arguments are trivially valid */
970
971         err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
972
973         if (cmd->scan_begin_src == TRIG_FOLLOW) /* internal trigger */
974                 err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
975
976         if (cmd->scan_begin_src == TRIG_TIMER) {
977                 if (this_usbduxsub->high_speed) {
978                         /*
979                          * In high speed mode microframes are possible.
980                          * However, during one microframe we can roughly
981                          * sample one channel. Thus, the more channels
982                          * are in the channel list the more time we need.
983                          */
984                         i = 1;
985                         /* find a power of 2 for the number of channels */
986                         while (i < (cmd->chanlist_len))
987                                 i = i * 2;
988
989                         err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
990                                                          1000000 / 8 * i);
991                         /* now calc the real sampling rate with all the
992                          * rounding errors */
993                         tmp_timer =
994                             ((unsigned int)(cmd->scan_begin_arg / 125000)) *
995                             125000;
996                 } else {
997                         /* full speed */
998                         /* 1kHz scans every USB frame */
999                         err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
1000                                                          1000000);
1001                         /*
1002                          * calc the real sampling rate with the rounding errors
1003                          */
1004                         tmp_timer = ((unsigned int)(cmd->scan_begin_arg /
1005                                                    1000000)) * 1000000;
1006                 }
1007                 err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg,
1008                                                 tmp_timer);
1009         }
1010
1011         err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
1012
1013         if (cmd->stop_src == TRIG_COUNT) {
1014                 /* any count is allowed */
1015         } else {
1016                 /* TRIG_NONE */
1017                 err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
1018         }
1019
1020         if (err)
1021                 return 3;
1022
1023         return 0;
1024 }
1025
1026 /*
1027  * creates the ADC command for the MAX1271
1028  * range is the range value from comedi
1029  */
1030 static int8_t create_adc_command(unsigned int chan, int range)
1031 {
1032         int8_t p = (range <= 1);
1033         int8_t r = ((range % 2) == 0);
1034         return (chan << 4) | ((p == 1) << 2) | ((r == 1) << 3);
1035 }
1036
1037 /* bulk transfers to usbdux */
1038
1039 #define SENDADCOMMANDS            0
1040 #define SENDDACOMMANDS            1
1041 #define SENDDIOCONFIGCOMMAND      2
1042 #define SENDDIOBITSCOMMAND        3
1043 #define SENDSINGLEAD              4
1044 #define READCOUNTERCOMMAND        5
1045 #define WRITECOUNTERCOMMAND       6
1046 #define SENDPWMON                 7
1047 #define SENDPWMOFF                8
1048
1049 static int send_dux_commands(struct usbduxsub *this_usbduxsub, int cmd_type)
1050 {
1051         int result, nsent;
1052
1053         this_usbduxsub->dux_commands[0] = cmd_type;
1054 #ifdef NOISY_DUX_DEBUGBUG
1055         printk(KERN_DEBUG "comedi%d: usbdux: dux_commands: ",
1056                this_usbduxsub->comedidev->minor);
1057         for (result = 0; result < SIZEOFDUXBUFFER; result++)
1058                 printk(" %02x", this_usbduxsub->dux_commands[result]);
1059         printk("\n");
1060 #endif
1061         result = usb_bulk_msg(this_usbduxsub->usbdev,
1062                               usb_sndbulkpipe(this_usbduxsub->usbdev,
1063                                               COMMAND_OUT_EP),
1064                               this_usbduxsub->dux_commands, SIZEOFDUXBUFFER,
1065                               &nsent, BULK_TIMEOUT);
1066         if (result < 0)
1067                 dev_err(&this_usbduxsub->interface->dev, "comedi%d: "
1068                         "could not transmit dux_command to the usb-device, "
1069                         "err=%d\n", this_usbduxsub->comedidev->minor, result);
1070
1071         return result;
1072 }
1073
1074 static int receive_dux_commands(struct usbduxsub *this_usbduxsub, int command)
1075 {
1076         int result = (-EFAULT);
1077         int nrec;
1078         int i;
1079
1080         for (i = 0; i < RETRIES; i++) {
1081                 result = usb_bulk_msg(this_usbduxsub->usbdev,
1082                                       usb_rcvbulkpipe(this_usbduxsub->usbdev,
1083                                                       COMMAND_IN_EP),
1084                                       this_usbduxsub->insn_buffer, SIZEINSNBUF,
1085                                       &nrec, BULK_TIMEOUT);
1086                 if (result < 0) {
1087                         dev_err(&this_usbduxsub->interface->dev, "comedi%d: "
1088                                 "insn: USB error %d while receiving DUX command"
1089                                 "\n", this_usbduxsub->comedidev->minor, result);
1090                         return result;
1091                 }
1092                 if (le16_to_cpu(this_usbduxsub->insn_buffer[0]) == command)
1093                         return result;
1094         }
1095         /* this is only reached if the data has been requested a couple of
1096          * times */
1097         dev_err(&this_usbduxsub->interface->dev, "comedi%d: insn: "
1098                 "wrong data returned from firmware: want cmd %d, got cmd %d.\n",
1099                 this_usbduxsub->comedidev->minor, command,
1100                 le16_to_cpu(this_usbduxsub->insn_buffer[0]));
1101         return -EFAULT;
1102 }
1103
1104 static int usbdux_ai_inttrig(struct comedi_device *dev,
1105                              struct comedi_subdevice *s, unsigned int trignum)
1106 {
1107         int ret;
1108         struct usbduxsub *this_usbduxsub = dev->private;
1109         if (!this_usbduxsub)
1110                 return -EFAULT;
1111
1112         down(&this_usbduxsub->sem);
1113         if (!(this_usbduxsub->probed)) {
1114                 up(&this_usbduxsub->sem);
1115                 return -ENODEV;
1116         }
1117         dev_dbg(&this_usbduxsub->interface->dev,
1118                 "comedi%d: usbdux_ai_inttrig\n", dev->minor);
1119
1120         if (trignum != 0) {
1121                 dev_err(&this_usbduxsub->interface->dev,
1122                         "comedi%d: usbdux_ai_inttrig: invalid trignum\n",
1123                         dev->minor);
1124                 up(&this_usbduxsub->sem);
1125                 return -EINVAL;
1126         }
1127         if (!(this_usbduxsub->ai_cmd_running)) {
1128                 this_usbduxsub->ai_cmd_running = 1;
1129                 ret = usbduxsub_submit_inurbs(this_usbduxsub);
1130                 if (ret < 0) {
1131                         dev_err(&this_usbduxsub->interface->dev,
1132                                 "comedi%d: usbdux_ai_inttrig: "
1133                                 "urbSubmit: err=%d\n", dev->minor, ret);
1134                         this_usbduxsub->ai_cmd_running = 0;
1135                         up(&this_usbduxsub->sem);
1136                         return ret;
1137                 }
1138                 s->async->inttrig = NULL;
1139         } else {
1140                 dev_err(&this_usbduxsub->interface->dev,
1141                         "comedi%d: ai_inttrig but acqu is already running\n",
1142                         dev->minor);
1143         }
1144         up(&this_usbduxsub->sem);
1145         return 1;
1146 }
1147
1148 static int usbdux_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
1149 {
1150         struct comedi_cmd *cmd = &s->async->cmd;
1151         unsigned int chan, range;
1152         int i, ret;
1153         struct usbduxsub *this_usbduxsub = dev->private;
1154         int result;
1155
1156         if (!this_usbduxsub)
1157                 return -EFAULT;
1158
1159         dev_dbg(&this_usbduxsub->interface->dev,
1160                 "comedi%d: usbdux_ai_cmd\n", dev->minor);
1161
1162         /* block other CPUs from starting an ai_cmd */
1163         down(&this_usbduxsub->sem);
1164
1165         if (!(this_usbduxsub->probed)) {
1166                 up(&this_usbduxsub->sem);
1167                 return -ENODEV;
1168         }
1169         if (this_usbduxsub->ai_cmd_running) {
1170                 dev_err(&this_usbduxsub->interface->dev, "comedi%d: "
1171                         "ai_cmd not possible. Another ai_cmd is running.\n",
1172                         dev->minor);
1173                 up(&this_usbduxsub->sem);
1174                 return -EBUSY;
1175         }
1176         /* set current channel of the running acquisition to zero */
1177         s->async->cur_chan = 0;
1178
1179         this_usbduxsub->dux_commands[1] = cmd->chanlist_len;
1180         for (i = 0; i < cmd->chanlist_len; ++i) {
1181                 chan = CR_CHAN(cmd->chanlist[i]);
1182                 range = CR_RANGE(cmd->chanlist[i]);
1183                 if (i >= NUMCHANNELS) {
1184                         dev_err(&this_usbduxsub->interface->dev,
1185                                 "comedi%d: channel list too long\n",
1186                                 dev->minor);
1187                         break;
1188                 }
1189                 this_usbduxsub->dux_commands[i + 2] =
1190                     create_adc_command(chan, range);
1191         }
1192
1193         dev_dbg(&this_usbduxsub->interface->dev,
1194                 "comedi %d: sending commands to the usb device: size=%u\n",
1195                 dev->minor, NUMCHANNELS);
1196
1197         result = send_dux_commands(this_usbduxsub, SENDADCOMMANDS);
1198         if (result < 0) {
1199                 up(&this_usbduxsub->sem);
1200                 return result;
1201         }
1202
1203         if (this_usbduxsub->high_speed) {
1204                 /*
1205                  * every channel gets a time window of 125us. Thus, if we
1206                  * sample all 8 channels we need 1ms. If we sample only one
1207                  * channel we need only 125us
1208                  */
1209                 this_usbduxsub->ai_interval = 1;
1210                 /* find a power of 2 for the interval */
1211                 while ((this_usbduxsub->ai_interval) < (cmd->chanlist_len)) {
1212                         this_usbduxsub->ai_interval =
1213                             (this_usbduxsub->ai_interval) * 2;
1214                 }
1215                 this_usbduxsub->ai_timer = cmd->scan_begin_arg / (125000 *
1216                                                           (this_usbduxsub->
1217                                                            ai_interval));
1218         } else {
1219                 /* interval always 1ms */
1220                 this_usbduxsub->ai_interval = 1;
1221                 this_usbduxsub->ai_timer = cmd->scan_begin_arg / 1000000;
1222         }
1223         if (this_usbduxsub->ai_timer < 1) {
1224                 dev_err(&this_usbduxsub->interface->dev, "comedi%d: ai_cmd: "
1225                         "timer=%d, scan_begin_arg=%d. "
1226                         "Not properly tested by cmdtest?\n", dev->minor,
1227                         this_usbduxsub->ai_timer, cmd->scan_begin_arg);
1228                 up(&this_usbduxsub->sem);
1229                 return -EINVAL;
1230         }
1231         this_usbduxsub->ai_counter = this_usbduxsub->ai_timer;
1232
1233         if (cmd->stop_src == TRIG_COUNT) {
1234                 /* data arrives as one packet */
1235                 this_usbduxsub->ai_sample_count = cmd->stop_arg;
1236                 this_usbduxsub->ai_continous = 0;
1237         } else {
1238                 /* continous acquisition */
1239                 this_usbduxsub->ai_continous = 1;
1240                 this_usbduxsub->ai_sample_count = 0;
1241         }
1242
1243         if (cmd->start_src == TRIG_NOW) {
1244                 /* enable this acquisition operation */
1245                 this_usbduxsub->ai_cmd_running = 1;
1246                 ret = usbduxsub_submit_inurbs(this_usbduxsub);
1247                 if (ret < 0) {
1248                         this_usbduxsub->ai_cmd_running = 0;
1249                         /* fixme: unlink here?? */
1250                         up(&this_usbduxsub->sem);
1251                         return ret;
1252                 }
1253                 s->async->inttrig = NULL;
1254         } else {
1255                 /* TRIG_INT */
1256                 /* don't enable the acquision operation */
1257                 /* wait for an internal signal */
1258                 s->async->inttrig = usbdux_ai_inttrig;
1259         }
1260         up(&this_usbduxsub->sem);
1261         return 0;
1262 }
1263
1264 /* Mode 0 is used to get a single conversion on demand */
1265 static int usbdux_ai_insn_read(struct comedi_device *dev,
1266                                struct comedi_subdevice *s,
1267                                struct comedi_insn *insn, unsigned int *data)
1268 {
1269         int i;
1270         unsigned int one = 0;
1271         int chan, range;
1272         int err;
1273         struct usbduxsub *this_usbduxsub = dev->private;
1274
1275         if (!this_usbduxsub)
1276                 return 0;
1277
1278         dev_dbg(&this_usbduxsub->interface->dev,
1279                 "comedi%d: ai_insn_read, insn->n=%d, insn->subdev=%d\n",
1280                 dev->minor, insn->n, insn->subdev);
1281
1282         down(&this_usbduxsub->sem);
1283         if (!(this_usbduxsub->probed)) {
1284                 up(&this_usbduxsub->sem);
1285                 return -ENODEV;
1286         }
1287         if (this_usbduxsub->ai_cmd_running) {
1288                 dev_err(&this_usbduxsub->interface->dev,
1289                         "comedi%d: ai_insn_read not possible. "
1290                         "Async Command is running.\n", dev->minor);
1291                 up(&this_usbduxsub->sem);
1292                 return 0;
1293         }
1294
1295         /* sample one channel */
1296         chan = CR_CHAN(insn->chanspec);
1297         range = CR_RANGE(insn->chanspec);
1298         /* set command for the first channel */
1299         this_usbduxsub->dux_commands[1] = create_adc_command(chan, range);
1300
1301         /* adc commands */
1302         err = send_dux_commands(this_usbduxsub, SENDSINGLEAD);
1303         if (err < 0) {
1304                 up(&this_usbduxsub->sem);
1305                 return err;
1306         }
1307
1308         for (i = 0; i < insn->n; i++) {
1309                 err = receive_dux_commands(this_usbduxsub, SENDSINGLEAD);
1310                 if (err < 0) {
1311                         up(&this_usbduxsub->sem);
1312                         return 0;
1313                 }
1314                 one = le16_to_cpu(this_usbduxsub->insn_buffer[1]);
1315                 if (CR_RANGE(insn->chanspec) <= 1)
1316                         one = one ^ 0x800;
1317
1318                 data[i] = one;
1319         }
1320         up(&this_usbduxsub->sem);
1321         return i;
1322 }
1323
1324 /************************************/
1325 /* analog out */
1326
1327 static int usbdux_ao_insn_read(struct comedi_device *dev,
1328                                struct comedi_subdevice *s,
1329                                struct comedi_insn *insn, unsigned int *data)
1330 {
1331         int i;
1332         int chan = CR_CHAN(insn->chanspec);
1333         struct usbduxsub *this_usbduxsub = dev->private;
1334
1335         if (!this_usbduxsub)
1336                 return -EFAULT;
1337
1338         down(&this_usbduxsub->sem);
1339         if (!(this_usbduxsub->probed)) {
1340                 up(&this_usbduxsub->sem);
1341                 return -ENODEV;
1342         }
1343         for (i = 0; i < insn->n; i++)
1344                 data[i] = this_usbduxsub->out_buffer[chan];
1345
1346         up(&this_usbduxsub->sem);
1347         return i;
1348 }
1349
1350 static int usbdux_ao_insn_write(struct comedi_device *dev,
1351                                 struct comedi_subdevice *s,
1352                                 struct comedi_insn *insn, unsigned int *data)
1353 {
1354         int i, err;
1355         int chan = CR_CHAN(insn->chanspec);
1356         struct usbduxsub *this_usbduxsub = dev->private;
1357
1358         if (!this_usbduxsub)
1359                 return -EFAULT;
1360
1361         dev_dbg(&this_usbduxsub->interface->dev,
1362                 "comedi%d: ao_insn_write\n", dev->minor);
1363
1364         down(&this_usbduxsub->sem);
1365         if (!(this_usbduxsub->probed)) {
1366                 up(&this_usbduxsub->sem);
1367                 return -ENODEV;
1368         }
1369         if (this_usbduxsub->ao_cmd_running) {
1370                 dev_err(&this_usbduxsub->interface->dev,
1371                         "comedi%d: ao_insn_write: "
1372                         "ERROR: asynchronous ao_cmd is running\n", dev->minor);
1373                 up(&this_usbduxsub->sem);
1374                 return 0;
1375         }
1376
1377         for (i = 0; i < insn->n; i++) {
1378                 dev_dbg(&this_usbduxsub->interface->dev,
1379                         "comedi%d: ao_insn_write: data[chan=%d,i=%d]=%d\n",
1380                         dev->minor, chan, i, data[i]);
1381
1382                 /* number of channels: 1 */
1383                 this_usbduxsub->dux_commands[1] = 1;
1384                 /* one 16 bit value */
1385                 *((int16_t *) (this_usbduxsub->dux_commands + 2)) =
1386                     cpu_to_le16(data[i]);
1387                 this_usbduxsub->out_buffer[chan] = data[i];
1388                 /* channel number */
1389                 this_usbduxsub->dux_commands[4] = (chan << 6);
1390                 err = send_dux_commands(this_usbduxsub, SENDDACOMMANDS);
1391                 if (err < 0) {
1392                         up(&this_usbduxsub->sem);
1393                         return err;
1394                 }
1395         }
1396         up(&this_usbduxsub->sem);
1397
1398         return i;
1399 }
1400
1401 static int usbdux_ao_inttrig(struct comedi_device *dev,
1402                              struct comedi_subdevice *s, unsigned int trignum)
1403 {
1404         int ret;
1405         struct usbduxsub *this_usbduxsub = dev->private;
1406
1407         if (!this_usbduxsub)
1408                 return -EFAULT;
1409
1410         down(&this_usbduxsub->sem);
1411         if (!(this_usbduxsub->probed)) {
1412                 up(&this_usbduxsub->sem);
1413                 return -ENODEV;
1414         }
1415         if (trignum != 0) {
1416                 dev_err(&this_usbduxsub->interface->dev,
1417                         "comedi%d: usbdux_ao_inttrig: invalid trignum\n",
1418                         dev->minor);
1419                 up(&this_usbduxsub->sem);
1420                 return -EINVAL;
1421         }
1422         if (!(this_usbduxsub->ao_cmd_running)) {
1423                 this_usbduxsub->ao_cmd_running = 1;
1424                 ret = usbduxsub_submit_outurbs(this_usbduxsub);
1425                 if (ret < 0) {
1426                         dev_err(&this_usbduxsub->interface->dev,
1427                                 "comedi%d: usbdux_ao_inttrig: submitURB: "
1428                                 "err=%d\n", dev->minor, ret);
1429                         this_usbduxsub->ao_cmd_running = 0;
1430                         up(&this_usbduxsub->sem);
1431                         return ret;
1432                 }
1433                 s->async->inttrig = NULL;
1434         } else {
1435                 dev_err(&this_usbduxsub->interface->dev,
1436                         "comedi%d: ao_inttrig but acqu is already running.\n",
1437                         dev->minor);
1438         }
1439         up(&this_usbduxsub->sem);
1440         return 1;
1441 }
1442
1443 static int usbdux_ao_cmdtest(struct comedi_device *dev,
1444                              struct comedi_subdevice *s, struct comedi_cmd *cmd)
1445 {
1446         struct usbduxsub *this_usbduxsub = dev->private;
1447         int err = 0;
1448         unsigned int flags;
1449
1450         if (!this_usbduxsub)
1451                 return -EFAULT;
1452
1453         if (!(this_usbduxsub->probed))
1454                 return -ENODEV;
1455
1456         /* Step 1 : check if triggers are trivially valid */
1457
1458         err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_INT);
1459
1460         if (0) {                /* (this_usbduxsub->high_speed) */
1461                 /* the sampling rate is set by the coversion rate */
1462                 flags = TRIG_FOLLOW;
1463         } else {
1464                 /* start a new scan (output at once) with a timer */
1465                 flags = TRIG_TIMER;
1466         }
1467         err |= cfc_check_trigger_src(&cmd->scan_begin_src, flags);
1468
1469         if (0) {                /* (this_usbduxsub->high_speed) */
1470                 /*
1471                  * in usb-2.0 only one conversion it transmitted
1472                  * but with 8kHz/n
1473                  */
1474                 flags = TRIG_TIMER;
1475         } else {
1476                 /*
1477                  * all conversion events happen simultaneously with
1478                  * a rate of 1kHz/n
1479                  */
1480                 flags = TRIG_NOW;
1481         }
1482         err |= cfc_check_trigger_src(&cmd->convert_src, flags);
1483
1484         err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
1485         err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
1486
1487         if (err)
1488                 return 1;
1489
1490         /* Step 2a : make sure trigger sources are unique */
1491
1492         err |= cfc_check_trigger_is_unique(cmd->start_src);
1493         err |= cfc_check_trigger_is_unique(cmd->stop_src);
1494
1495         /* Step 2b : and mutually compatible */
1496
1497         if (err)
1498                 return 2;
1499
1500         /* Step 3: check if arguments are trivially valid */
1501
1502         err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
1503
1504         if (cmd->scan_begin_src == TRIG_FOLLOW) /* internal trigger */
1505                 err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
1506
1507         if (cmd->scan_begin_src == TRIG_TIMER)
1508                 err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
1509                                                  1000000);
1510
1511         /* not used now, is for later use */
1512         if (cmd->convert_src == TRIG_TIMER)
1513                 err |= cfc_check_trigger_arg_min(&cmd->convert_arg, 125000);
1514
1515         err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
1516
1517         if (cmd->stop_src == TRIG_COUNT) {
1518                 /* any count is allowed */
1519         } else {
1520                 /* TRIG_NONE */
1521                 err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
1522         }
1523
1524         if (err)
1525                 return 3;
1526
1527         return 0;
1528 }
1529
1530 static int usbdux_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
1531 {
1532         struct comedi_cmd *cmd = &s->async->cmd;
1533         unsigned int chan, gain;
1534         int i, ret;
1535         struct usbduxsub *this_usbduxsub = dev->private;
1536
1537         if (!this_usbduxsub)
1538                 return -EFAULT;
1539
1540         down(&this_usbduxsub->sem);
1541         if (!(this_usbduxsub->probed)) {
1542                 up(&this_usbduxsub->sem);
1543                 return -ENODEV;
1544         }
1545         dev_dbg(&this_usbduxsub->interface->dev,
1546                 "comedi%d: %s\n", dev->minor, __func__);
1547
1548         /* set current channel of the running acquisition to zero */
1549         s->async->cur_chan = 0;
1550         for (i = 0; i < cmd->chanlist_len; ++i) {
1551                 chan = CR_CHAN(cmd->chanlist[i]);
1552                 gain = CR_RANGE(cmd->chanlist[i]);
1553                 if (i >= NUMOUTCHANNELS) {
1554                         dev_err(&this_usbduxsub->interface->dev,
1555                                 "comedi%d: %s: channel list too long\n",
1556                                 dev->minor, __func__);
1557                         break;
1558                 }
1559                 this_usbduxsub->dac_commands[i] = (chan << 6);
1560                 dev_dbg(&this_usbduxsub->interface->dev,
1561                         "comedi%d: dac command for ch %d is %x\n",
1562                         dev->minor, i, this_usbduxsub->dac_commands[i]);
1563         }
1564
1565         /* we count in steps of 1ms (125us) */
1566         /* 125us mode not used yet */
1567         if (0) {                /* (this_usbduxsub->high_speed) */
1568                 /* 125us */
1569                 /* timing of the conversion itself: every 125 us */
1570                 this_usbduxsub->ao_timer = cmd->convert_arg / 125000;
1571         } else {
1572                 /* 1ms */
1573                 /* timing of the scan: we get all channels at once */
1574                 this_usbduxsub->ao_timer = cmd->scan_begin_arg / 1000000;
1575                 dev_dbg(&this_usbduxsub->interface->dev,
1576                         "comedi%d: scan_begin_src=%d, scan_begin_arg=%d, "
1577                         "convert_src=%d, convert_arg=%d\n", dev->minor,
1578                         cmd->scan_begin_src, cmd->scan_begin_arg,
1579                         cmd->convert_src, cmd->convert_arg);
1580                 dev_dbg(&this_usbduxsub->interface->dev,
1581                         "comedi%d: ao_timer=%d (ms)\n",
1582                         dev->minor, this_usbduxsub->ao_timer);
1583                 if (this_usbduxsub->ao_timer < 1) {
1584                         dev_err(&this_usbduxsub->interface->dev,
1585                                 "comedi%d: usbdux: ao_timer=%d, "
1586                                 "scan_begin_arg=%d. "
1587                                 "Not properly tested by cmdtest?\n",
1588                                 dev->minor, this_usbduxsub->ao_timer,
1589                                 cmd->scan_begin_arg);
1590                         up(&this_usbduxsub->sem);
1591                         return -EINVAL;
1592                 }
1593         }
1594         this_usbduxsub->ao_counter = this_usbduxsub->ao_timer;
1595
1596         if (cmd->stop_src == TRIG_COUNT) {
1597                 /* not continuous */
1598                 /* counter */
1599                 /* high speed also scans everything at once */
1600                 if (0) {        /* (this_usbduxsub->high_speed) */
1601                         this_usbduxsub->ao_sample_count =
1602                             (cmd->stop_arg) * (cmd->scan_end_arg);
1603                 } else {
1604                         /* there's no scan as the scan has been */
1605                         /* perf inside the FX2 */
1606                         /* data arrives as one packet */
1607                         this_usbduxsub->ao_sample_count = cmd->stop_arg;
1608                 }
1609                 this_usbduxsub->ao_continous = 0;
1610         } else {
1611                 /* continous acquisition */
1612                 this_usbduxsub->ao_continous = 1;
1613                 this_usbduxsub->ao_sample_count = 0;
1614         }
1615
1616         if (cmd->start_src == TRIG_NOW) {
1617                 /* enable this acquisition operation */
1618                 this_usbduxsub->ao_cmd_running = 1;
1619                 ret = usbduxsub_submit_outurbs(this_usbduxsub);
1620                 if (ret < 0) {
1621                         this_usbduxsub->ao_cmd_running = 0;
1622                         /* fixme: unlink here?? */
1623                         up(&this_usbduxsub->sem);
1624                         return ret;
1625                 }
1626                 s->async->inttrig = NULL;
1627         } else {
1628                 /* TRIG_INT */
1629                 /* submit the urbs later */
1630                 /* wait for an internal signal */
1631                 s->async->inttrig = usbdux_ao_inttrig;
1632         }
1633
1634         up(&this_usbduxsub->sem);
1635         return 0;
1636 }
1637
1638 static int usbdux_dio_insn_config(struct comedi_device *dev,
1639                                   struct comedi_subdevice *s,
1640                                   struct comedi_insn *insn, unsigned int *data)
1641 {
1642         int chan = CR_CHAN(insn->chanspec);
1643
1644         /* The input or output configuration of each digital line is
1645          * configured by a special insn_config instruction.  chanspec
1646          * contains the channel to be changed, and data[0] contains the
1647          * value COMEDI_INPUT or COMEDI_OUTPUT. */
1648
1649         switch (data[0]) {
1650         case INSN_CONFIG_DIO_OUTPUT:
1651                 s->io_bits |= 1 << chan;        /* 1 means Out */
1652                 break;
1653         case INSN_CONFIG_DIO_INPUT:
1654                 s->io_bits &= ~(1 << chan);
1655                 break;
1656         case INSN_CONFIG_DIO_QUERY:
1657                 data[1] =
1658                     (s->io_bits & (1 << chan)) ? COMEDI_OUTPUT : COMEDI_INPUT;
1659                 break;
1660         default:
1661                 return -EINVAL;
1662                 break;
1663         }
1664         /* we don't tell the firmware here as it would take 8 frames */
1665         /* to submit the information. We do it in the insn_bits. */
1666         return insn->n;
1667 }
1668
1669 static int usbdux_dio_insn_bits(struct comedi_device *dev,
1670                                 struct comedi_subdevice *s,
1671                                 struct comedi_insn *insn, unsigned int *data)
1672 {
1673
1674         struct usbduxsub *this_usbduxsub = dev->private;
1675         int err;
1676
1677         if (!this_usbduxsub)
1678                 return -EFAULT;
1679
1680         down(&this_usbduxsub->sem);
1681
1682         if (!(this_usbduxsub->probed)) {
1683                 up(&this_usbduxsub->sem);
1684                 return -ENODEV;
1685         }
1686
1687         /* The insn data is a mask in data[0] and the new data
1688          * in data[1], each channel cooresponding to a bit. */
1689         s->state &= ~data[0];
1690         s->state |= data[0] & data[1];
1691         this_usbduxsub->dux_commands[1] = s->io_bits;
1692         this_usbduxsub->dux_commands[2] = s->state;
1693
1694         /* This command also tells the firmware to return */
1695         /* the digital input lines */
1696         err = send_dux_commands(this_usbduxsub, SENDDIOBITSCOMMAND);
1697         if (err < 0) {
1698                 up(&this_usbduxsub->sem);
1699                 return err;
1700         }
1701         err = receive_dux_commands(this_usbduxsub, SENDDIOBITSCOMMAND);
1702         if (err < 0) {
1703                 up(&this_usbduxsub->sem);
1704                 return err;
1705         }
1706
1707         data[1] = le16_to_cpu(this_usbduxsub->insn_buffer[1]);
1708         up(&this_usbduxsub->sem);
1709         return insn->n;
1710 }
1711
1712 /* reads the 4 counters, only two are used just now */
1713 static int usbdux_counter_read(struct comedi_device *dev,
1714                                struct comedi_subdevice *s,
1715                                struct comedi_insn *insn, unsigned int *data)
1716 {
1717         struct usbduxsub *this_usbduxsub = dev->private;
1718         int chan = insn->chanspec;
1719         int err;
1720
1721         if (!this_usbduxsub)
1722                 return -EFAULT;
1723
1724         down(&this_usbduxsub->sem);
1725
1726         if (!(this_usbduxsub->probed)) {
1727                 up(&this_usbduxsub->sem);
1728                 return -ENODEV;
1729         }
1730
1731         err = send_dux_commands(this_usbduxsub, READCOUNTERCOMMAND);
1732         if (err < 0) {
1733                 up(&this_usbduxsub->sem);
1734                 return err;
1735         }
1736
1737         err = receive_dux_commands(this_usbduxsub, READCOUNTERCOMMAND);
1738         if (err < 0) {
1739                 up(&this_usbduxsub->sem);
1740                 return err;
1741         }
1742
1743         data[0] = le16_to_cpu(this_usbduxsub->insn_buffer[chan + 1]);
1744         up(&this_usbduxsub->sem);
1745         return 1;
1746 }
1747
1748 static int usbdux_counter_write(struct comedi_device *dev,
1749                                 struct comedi_subdevice *s,
1750                                 struct comedi_insn *insn, unsigned int *data)
1751 {
1752         struct usbduxsub *this_usbduxsub = dev->private;
1753         int err;
1754
1755         if (!this_usbduxsub)
1756                 return -EFAULT;
1757
1758         down(&this_usbduxsub->sem);
1759
1760         if (!(this_usbduxsub->probed)) {
1761                 up(&this_usbduxsub->sem);
1762                 return -ENODEV;
1763         }
1764
1765         this_usbduxsub->dux_commands[1] = insn->chanspec;
1766         *((int16_t *) (this_usbduxsub->dux_commands + 2)) = cpu_to_le16(*data);
1767
1768         err = send_dux_commands(this_usbduxsub, WRITECOUNTERCOMMAND);
1769         if (err < 0) {
1770                 up(&this_usbduxsub->sem);
1771                 return err;
1772         }
1773
1774         up(&this_usbduxsub->sem);
1775
1776         return 1;
1777 }
1778
1779 static int usbdux_counter_config(struct comedi_device *dev,
1780                                  struct comedi_subdevice *s,
1781                                  struct comedi_insn *insn, unsigned int *data)
1782 {
1783         /* nothing to do so far */
1784         return 2;
1785 }
1786
1787 /***********************************/
1788 /* PWM */
1789
1790 static int usbduxsub_unlink_pwm_urbs(struct usbduxsub *usbduxsub_tmp)
1791 {
1792         int err = 0;
1793
1794         if (usbduxsub_tmp && usbduxsub_tmp->urb_pwm) {
1795                 if (usbduxsub_tmp->urb_pwm)
1796                         usb_kill_urb(usbduxsub_tmp->urb_pwm);
1797                 dev_dbg(&usbduxsub_tmp->interface->dev,
1798                         "comedi: unlinked PwmURB: res=%d\n", err);
1799         }
1800         return err;
1801 }
1802
1803 /* This cancels a running acquisition operation
1804  * in any context.
1805  */
1806 static int usbdux_pwm_stop(struct usbduxsub *this_usbduxsub, int do_unlink)
1807 {
1808         int ret = 0;
1809
1810         if (!this_usbduxsub)
1811                 return -EFAULT;
1812
1813         dev_dbg(&this_usbduxsub->interface->dev, "comedi: %s\n", __func__);
1814         if (do_unlink)
1815                 ret = usbduxsub_unlink_pwm_urbs(this_usbduxsub);
1816
1817         this_usbduxsub->pwm_cmd_running = 0;
1818
1819         return ret;
1820 }
1821
1822 /* force unlink - is called by comedi */
1823 static int usbdux_pwm_cancel(struct comedi_device *dev,
1824                              struct comedi_subdevice *s)
1825 {
1826         struct usbduxsub *this_usbduxsub = dev->private;
1827         int res = 0;
1828
1829         /* unlink only if it is really running */
1830         res = usbdux_pwm_stop(this_usbduxsub, this_usbduxsub->pwm_cmd_running);
1831
1832         dev_dbg(&this_usbduxsub->interface->dev,
1833                 "comedi %d: sending pwm off command to the usb device.\n",
1834                 dev->minor);
1835
1836         return send_dux_commands(this_usbduxsub, SENDPWMOFF);
1837 }
1838
1839 static void usbduxsub_pwm_irq(struct urb *urb)
1840 {
1841         int ret;
1842         struct usbduxsub *this_usbduxsub;
1843         struct comedi_device *this_comedidev;
1844         struct comedi_subdevice *s;
1845
1846         /* printk(KERN_DEBUG "PWM: IRQ\n"); */
1847
1848         /* the context variable points to the subdevice */
1849         this_comedidev = urb->context;
1850         /* the private structure of the subdevice is struct usbduxsub */
1851         this_usbduxsub = this_comedidev->private;
1852
1853         s = &this_comedidev->subdevices[SUBDEV_DA];
1854
1855         switch (urb->status) {
1856         case 0:
1857                 /* success */
1858                 break;
1859
1860         case -ECONNRESET:
1861         case -ENOENT:
1862         case -ESHUTDOWN:
1863         case -ECONNABORTED:
1864                 /*
1865                  * after an unlink command, unplug, ... etc
1866                  * no unlink needed here. Already shutting down.
1867                  */
1868                 if (this_usbduxsub->pwm_cmd_running)
1869                         usbdux_pwm_stop(this_usbduxsub, 0);
1870
1871                 return;
1872
1873         default:
1874                 /* a real error */
1875                 if (this_usbduxsub->pwm_cmd_running) {
1876                         dev_err(&this_usbduxsub->interface->dev,
1877                                 "comedi_: Non-zero urb status received in "
1878                                 "pwm intr context: %d\n", urb->status);
1879                         usbdux_pwm_stop(this_usbduxsub, 0);
1880                 }
1881                 return;
1882         }
1883
1884         /* are we actually running? */
1885         if (!(this_usbduxsub->pwm_cmd_running))
1886                 return;
1887
1888         urb->transfer_buffer_length = this_usbduxsub->size_pwm_buf;
1889         urb->dev = this_usbduxsub->usbdev;
1890         urb->status = 0;
1891         if (this_usbduxsub->pwm_cmd_running) {
1892                 ret = usb_submit_urb(urb, GFP_ATOMIC);
1893                 if (ret < 0) {
1894                         dev_err(&this_usbduxsub->interface->dev,
1895                                 "comedi_: pwm urb resubm failed in int-cont. "
1896                                 "ret=%d", ret);
1897                         if (ret == EL2NSYNC)
1898                                 dev_err(&this_usbduxsub->interface->dev,
1899                                         "buggy USB host controller or bug in "
1900                                         "IRQ handling!\n");
1901
1902                         /* don't do an unlink here */
1903                         usbdux_pwm_stop(this_usbduxsub, 0);
1904                 }
1905         }
1906 }
1907
1908 static int usbduxsub_submit_pwm_urbs(struct usbduxsub *usbduxsub)
1909 {
1910         int err_flag;
1911
1912         if (!usbduxsub)
1913                 return -EFAULT;
1914
1915         dev_dbg(&usbduxsub->interface->dev, "comedi_: submitting pwm-urb\n");
1916
1917         /* in case of a resubmission after an unlink... */
1918         usb_fill_bulk_urb(usbduxsub->urb_pwm,
1919                           usbduxsub->usbdev,
1920                           usb_sndbulkpipe(usbduxsub->usbdev, PWM_EP),
1921                           usbduxsub->urb_pwm->transfer_buffer,
1922                           usbduxsub->size_pwm_buf, usbduxsub_pwm_irq,
1923                           usbduxsub->comedidev);
1924
1925         err_flag = usb_submit_urb(usbduxsub->urb_pwm, GFP_ATOMIC);
1926         if (err_flag) {
1927                 dev_err(&usbduxsub->interface->dev,
1928                         "comedi_: usbdux: pwm: usb_submit_urb error %d\n",
1929                         err_flag);
1930                 return err_flag;
1931         }
1932         return 0;
1933 }
1934
1935 static int usbdux_pwm_period(struct comedi_device *dev,
1936                              struct comedi_subdevice *s, unsigned int period)
1937 {
1938         struct usbduxsub *this_usbduxsub = dev->private;
1939         int fx2delay = 255;
1940
1941         if (period < MIN_PWM_PERIOD) {
1942                 dev_err(&this_usbduxsub->interface->dev,
1943                         "comedi%d: illegal period setting for pwm.\n",
1944                         dev->minor);
1945                 return -EAGAIN;
1946         } else {
1947                 fx2delay = period / ((int)(6 * 512 * (1.0 / 0.033))) - 6;
1948                 if (fx2delay > 255) {
1949                         dev_err(&this_usbduxsub->interface->dev,
1950                                 "comedi%d: period %d for pwm is too low.\n",
1951                                 dev->minor, period);
1952                         return -EAGAIN;
1953                 }
1954         }
1955         this_usbduxsub->pwn_delay = fx2delay;
1956         this_usbduxsub->pwm_period = period;
1957         dev_dbg(&this_usbduxsub->interface->dev, "%s: frequ=%d, period=%d\n",
1958                 __func__, period, fx2delay);
1959         return 0;
1960 }
1961
1962 /* is called from insn so there's no need to do all the sanity checks */
1963 static int usbdux_pwm_start(struct comedi_device *dev,
1964                             struct comedi_subdevice *s)
1965 {
1966         int ret, i;
1967         struct usbduxsub *this_usbduxsub = dev->private;
1968
1969         dev_dbg(&this_usbduxsub->interface->dev, "comedi%d: %s\n",
1970                 dev->minor, __func__);
1971
1972         if (this_usbduxsub->pwm_cmd_running) {
1973                 /* already running */
1974                 return 0;
1975         }
1976
1977         this_usbduxsub->dux_commands[1] = ((int8_t) this_usbduxsub->pwn_delay);
1978         ret = send_dux_commands(this_usbduxsub, SENDPWMON);
1979         if (ret < 0)
1980                 return ret;
1981
1982         /* initialise the buffer */
1983         for (i = 0; i < this_usbduxsub->size_pwm_buf; i++)
1984                 ((char *)(this_usbduxsub->urb_pwm->transfer_buffer))[i] = 0;
1985
1986         this_usbduxsub->pwm_cmd_running = 1;
1987         ret = usbduxsub_submit_pwm_urbs(this_usbduxsub);
1988         if (ret < 0) {
1989                 this_usbduxsub->pwm_cmd_running = 0;
1990                 return ret;
1991         }
1992         return 0;
1993 }
1994
1995 /* generates the bit pattern for PWM with the optional sign bit */
1996 static int usbdux_pwm_pattern(struct comedi_device *dev,
1997                               struct comedi_subdevice *s, int channel,
1998                               unsigned int value, unsigned int sign)
1999 {
2000         struct usbduxsub *this_usbduxsub = dev->private;
2001         int i, szbuf;
2002         char *p_buf;
2003         char pwm_mask;
2004         char sgn_mask;
2005         char c;
2006
2007         if (!this_usbduxsub)
2008                 return -EFAULT;
2009
2010         /* this is the DIO bit which carries the PWM data */
2011         pwm_mask = (1 << channel);
2012         /* this is the DIO bit which carries the optional direction bit */
2013         sgn_mask = (16 << channel);
2014         /* this is the buffer which will be filled with the with bit */
2015         /* pattern for one period */
2016         szbuf = this_usbduxsub->size_pwm_buf;
2017         p_buf = (char *)(this_usbduxsub->urb_pwm->transfer_buffer);
2018         for (i = 0; i < szbuf; i++) {
2019                 c = *p_buf;
2020                 /* reset bits */
2021                 c = c & (~pwm_mask);
2022                 /* set the bit as long as the index is lower than the value */
2023                 if (i < value)
2024                         c = c | pwm_mask;
2025                 /* set the optional sign bit for a relay */
2026                 if (!sign) {
2027                         /* positive value */
2028                         c = c & (~sgn_mask);
2029                 } else {
2030                         /* negative value */
2031                         c = c | sgn_mask;
2032                 }
2033                 *(p_buf++) = c;
2034         }
2035         return 1;
2036 }
2037
2038 static int usbdux_pwm_write(struct comedi_device *dev,
2039                             struct comedi_subdevice *s,
2040                             struct comedi_insn *insn, unsigned int *data)
2041 {
2042         struct usbduxsub *this_usbduxsub = dev->private;
2043
2044         if (!this_usbduxsub)
2045                 return -EFAULT;
2046
2047         if ((insn->n) != 1) {
2048                 /*
2049                  * doesn't make sense to have more than one value here because
2050                  * it would just overwrite the PWM buffer a couple of times
2051                  */
2052                 return -EINVAL;
2053         }
2054
2055         /*
2056          * the sign is set via a special INSN only, this gives us 8 bits for
2057          * normal operation
2058          * relay sign 0 by default
2059          */
2060         return usbdux_pwm_pattern(dev, s, CR_CHAN(insn->chanspec), data[0], 0);
2061 }
2062
2063 static int usbdux_pwm_read(struct comedi_device *x1,
2064                            struct comedi_subdevice *x2, struct comedi_insn *x3,
2065                            unsigned int *x4)
2066 {
2067         /* not needed */
2068         return -EINVAL;
2069 };
2070
2071 /* switches on/off PWM */
2072 static int usbdux_pwm_config(struct comedi_device *dev,
2073                              struct comedi_subdevice *s,
2074                              struct comedi_insn *insn, unsigned int *data)
2075 {
2076         struct usbduxsub *this_usbduxsub = dev->private;
2077         switch (data[0]) {
2078         case INSN_CONFIG_ARM:
2079                 /* switch it on */
2080                 dev_dbg(&this_usbduxsub->interface->dev,
2081                         "comedi%d: %s: pwm on\n", dev->minor, __func__);
2082                 /*
2083                  * if not zero the PWM is limited to a certain time which is
2084                  * not supported here
2085                  */
2086                 if (data[1] != 0)
2087                         return -EINVAL;
2088                 return usbdux_pwm_start(dev, s);
2089         case INSN_CONFIG_DISARM:
2090                 dev_dbg(&this_usbduxsub->interface->dev,
2091                         "comedi%d: %s: pwm off\n", dev->minor, __func__);
2092                 return usbdux_pwm_cancel(dev, s);
2093         case INSN_CONFIG_GET_PWM_STATUS:
2094                 /*
2095                  * to check if the USB transmission has failed or in case PWM
2096                  * was limited to n cycles to check if it has terminated
2097                  */
2098                 data[1] = this_usbduxsub->pwm_cmd_running;
2099                 return 0;
2100         case INSN_CONFIG_PWM_SET_PERIOD:
2101                 dev_dbg(&this_usbduxsub->interface->dev,
2102                         "comedi%d: %s: setting period\n", dev->minor, __func__);
2103                 return usbdux_pwm_period(dev, s, data[1]);
2104         case INSN_CONFIG_PWM_GET_PERIOD:
2105                 data[1] = this_usbduxsub->pwm_period;
2106                 return 0;
2107         case INSN_CONFIG_PWM_SET_H_BRIDGE:
2108                 /* value in the first byte and the sign in the second for a
2109                    relay */
2110                 return usbdux_pwm_pattern(dev, s,
2111                                           /* the channel number */
2112                                           CR_CHAN(insn->chanspec),
2113                                           /* actual PWM data */
2114                                           data[1],
2115                                           /* just a sign */
2116                                           (data[2] != 0));
2117         case INSN_CONFIG_PWM_GET_H_BRIDGE:
2118                 /* values are not kept in this driver, nothing to return here */
2119                 return -EINVAL;
2120         }
2121         return -EINVAL;
2122 }
2123
2124 /* end of PWM */
2125 /*****************************************************************/
2126
2127 static void tidy_up(struct usbduxsub *usbduxsub_tmp)
2128 {
2129         int i;
2130
2131         if (!usbduxsub_tmp)
2132                 return;
2133         dev_dbg(&usbduxsub_tmp->interface->dev, "comedi_: tiding up\n");
2134
2135         /* shows the usb subsystem that the driver is down */
2136         if (usbduxsub_tmp->interface)
2137                 usb_set_intfdata(usbduxsub_tmp->interface, NULL);
2138
2139         usbduxsub_tmp->probed = 0;
2140
2141         if (usbduxsub_tmp->urb_in) {
2142                 if (usbduxsub_tmp->ai_cmd_running) {
2143                         usbduxsub_tmp->ai_cmd_running = 0;
2144                         usbduxsub_unlink_inurbs(usbduxsub_tmp);
2145                 }
2146                 for (i = 0; i < usbduxsub_tmp->num_in_buffers; i++) {
2147                         kfree(usbduxsub_tmp->urb_in[i]->transfer_buffer);
2148                         usbduxsub_tmp->urb_in[i]->transfer_buffer = NULL;
2149                         usb_kill_urb(usbduxsub_tmp->urb_in[i]);
2150                         usb_free_urb(usbduxsub_tmp->urb_in[i]);
2151                         usbduxsub_tmp->urb_in[i] = NULL;
2152                 }
2153                 kfree(usbduxsub_tmp->urb_in);
2154                 usbduxsub_tmp->urb_in = NULL;
2155         }
2156         if (usbduxsub_tmp->urb_out) {
2157                 if (usbduxsub_tmp->ao_cmd_running) {
2158                         usbduxsub_tmp->ao_cmd_running = 0;
2159                         usbduxsub_unlink_outurbs(usbduxsub_tmp);
2160                 }
2161                 for (i = 0; i < usbduxsub_tmp->num_out_buffers; i++) {
2162                         kfree(usbduxsub_tmp->urb_out[i]->transfer_buffer);
2163                         usbduxsub_tmp->urb_out[i]->transfer_buffer = NULL;
2164                         if (usbduxsub_tmp->urb_out[i]) {
2165                                 usb_kill_urb(usbduxsub_tmp->urb_out[i]);
2166                                 usb_free_urb(usbduxsub_tmp->urb_out[i]);
2167                                 usbduxsub_tmp->urb_out[i] = NULL;
2168                         }
2169                 }
2170                 kfree(usbduxsub_tmp->urb_out);
2171                 usbduxsub_tmp->urb_out = NULL;
2172         }
2173         if (usbduxsub_tmp->urb_pwm) {
2174                 if (usbduxsub_tmp->pwm_cmd_running) {
2175                         usbduxsub_tmp->pwm_cmd_running = 0;
2176                         usbduxsub_unlink_pwm_urbs(usbduxsub_tmp);
2177                 }
2178                 kfree(usbduxsub_tmp->urb_pwm->transfer_buffer);
2179                 usbduxsub_tmp->urb_pwm->transfer_buffer = NULL;
2180                 usb_kill_urb(usbduxsub_tmp->urb_pwm);
2181                 usb_free_urb(usbduxsub_tmp->urb_pwm);
2182                 usbduxsub_tmp->urb_pwm = NULL;
2183         }
2184         kfree(usbduxsub_tmp->in_buffer);
2185         usbduxsub_tmp->in_buffer = NULL;
2186         kfree(usbduxsub_tmp->insn_buffer);
2187         usbduxsub_tmp->insn_buffer = NULL;
2188         kfree(usbduxsub_tmp->out_buffer);
2189         usbduxsub_tmp->out_buffer = NULL;
2190         kfree(usbduxsub_tmp->dac_commands);
2191         usbduxsub_tmp->dac_commands = NULL;
2192         kfree(usbduxsub_tmp->dux_commands);
2193         usbduxsub_tmp->dux_commands = NULL;
2194         usbduxsub_tmp->ai_cmd_running = 0;
2195         usbduxsub_tmp->ao_cmd_running = 0;
2196         usbduxsub_tmp->pwm_cmd_running = 0;
2197 }
2198
2199 static int usbdux_attach_common(struct comedi_device *dev,
2200                                 struct usbduxsub *udev)
2201 {
2202         int ret;
2203         struct comedi_subdevice *s = NULL;
2204         int n_subdevs;
2205
2206         down(&udev->sem);
2207         /* pointer back to the corresponding comedi device */
2208         udev->comedidev = dev;
2209
2210         /* set number of subdevices */
2211         if (udev->high_speed) {
2212                 /* with pwm */
2213                 n_subdevs = 5;
2214         } else {
2215                 /* without pwm */
2216                 n_subdevs = 4;
2217         }
2218
2219         ret = comedi_alloc_subdevices(dev, n_subdevs);
2220         if (ret) {
2221                 up(&udev->sem);
2222                 return ret;
2223         }
2224
2225         /* private structure is also simply the usb-structure */
2226         dev->private = udev;
2227
2228         /* the first subdevice is the A/D converter */
2229         s = &dev->subdevices[SUBDEV_AD];
2230         /* the URBs get the comedi subdevice */
2231         /* which is responsible for reading */
2232         /* this is the subdevice which reads data */
2233         dev->read_subdev = s;
2234         /* the subdevice receives as private structure the */
2235         /* usb-structure */
2236         s->private = NULL;
2237         /* analog input */
2238         s->type = COMEDI_SUBD_AI;
2239         /* readable and ref is to ground */
2240         s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_CMD_READ;
2241         /* 8 channels */
2242         s->n_chan = 8;
2243         /* length of the channellist */
2244         s->len_chanlist = 8;
2245         /* callback functions */
2246         s->insn_read = usbdux_ai_insn_read;
2247         s->do_cmdtest = usbdux_ai_cmdtest;
2248         s->do_cmd = usbdux_ai_cmd;
2249         s->cancel = usbdux_ai_cancel;
2250         /* max value from the A/D converter (12bit) */
2251         s->maxdata = 0xfff;
2252         /* range table to convert to physical units */
2253         s->range_table = (&range_usbdux_ai_range);
2254
2255         /* analog out */
2256         s = &dev->subdevices[SUBDEV_DA];
2257         /* analog out */
2258         s->type = COMEDI_SUBD_AO;
2259         /* backward pointer */
2260         dev->write_subdev = s;
2261         /* the subdevice receives as private structure the */
2262         /* usb-structure */
2263         s->private = NULL;
2264         /* are writable */
2265         s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_CMD_WRITE;
2266         /* 4 channels */
2267         s->n_chan = 4;
2268         /* length of the channellist */
2269         s->len_chanlist = 4;
2270         /* 12 bit resolution */
2271         s->maxdata = 0x0fff;
2272         /* bipolar range */
2273         s->range_table = (&range_usbdux_ao_range);
2274         /* callback */
2275         s->do_cmdtest = usbdux_ao_cmdtest;
2276         s->do_cmd = usbdux_ao_cmd;
2277         s->cancel = usbdux_ao_cancel;
2278         s->insn_read = usbdux_ao_insn_read;
2279         s->insn_write = usbdux_ao_insn_write;
2280
2281         /* digital I/O */
2282         s = &dev->subdevices[SUBDEV_DIO];
2283         s->type = COMEDI_SUBD_DIO;
2284         s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
2285         s->n_chan = 8;
2286         s->maxdata = 1;
2287         s->range_table = (&range_digital);
2288         s->insn_bits = usbdux_dio_insn_bits;
2289         s->insn_config = usbdux_dio_insn_config;
2290         /* we don't use it */
2291         s->private = NULL;
2292
2293         /* counter */
2294         s = &dev->subdevices[SUBDEV_COUNTER];
2295         s->type = COMEDI_SUBD_COUNTER;
2296         s->subdev_flags = SDF_WRITABLE | SDF_READABLE;
2297         s->n_chan = 4;
2298         s->maxdata = 0xFFFF;
2299         s->insn_read = usbdux_counter_read;
2300         s->insn_write = usbdux_counter_write;
2301         s->insn_config = usbdux_counter_config;
2302
2303         if (udev->high_speed) {
2304                 /* timer / pwm */
2305                 s = &dev->subdevices[SUBDEV_PWM];
2306                 s->type = COMEDI_SUBD_PWM;
2307                 s->subdev_flags = SDF_WRITABLE | SDF_PWM_HBRIDGE;
2308                 s->n_chan = 8;
2309                 /* this defines the max duty cycle resolution */
2310                 s->maxdata = udev->size_pwm_buf;
2311                 s->insn_write = usbdux_pwm_write;
2312                 s->insn_read = usbdux_pwm_read;
2313                 s->insn_config = usbdux_pwm_config;
2314                 usbdux_pwm_period(dev, s, PWM_DEFAULT_PERIOD);
2315         }
2316         /* finally decide that it's attached */
2317         udev->attached = 1;
2318
2319         up(&udev->sem);
2320
2321         dev_info(&udev->interface->dev, "comedi%d: attached to usbdux.\n",
2322                  dev->minor);
2323
2324         return 0;
2325 }
2326
2327 static int usbdux_auto_attach(struct comedi_device *dev,
2328                               unsigned long context_unused)
2329 {
2330         struct usb_interface *uinterf = comedi_to_usb_interface(dev);
2331         int ret;
2332         struct usbduxsub *this_usbduxsub;
2333
2334         dev->private = NULL;
2335
2336         down(&start_stop_sem);
2337         this_usbduxsub = usb_get_intfdata(uinterf);
2338         if (!this_usbduxsub || !this_usbduxsub->probed) {
2339                 dev_err(dev->class_dev,
2340                         "usbdux: error: auto_attach failed, not connected\n");
2341                 ret = -ENODEV;
2342         } else if (this_usbduxsub->attached) {
2343                 dev_err(dev->class_dev,
2344                         "error: auto_attach failed, already attached\n");
2345                 ret = -ENODEV;
2346         } else
2347                 ret = usbdux_attach_common(dev, this_usbduxsub);
2348         up(&start_stop_sem);
2349         return ret;
2350 }
2351
2352 static void usbdux_detach(struct comedi_device *dev)
2353 {
2354         struct usbduxsub *usb = dev->private;
2355
2356         if (usb) {
2357                 down(&usb->sem);
2358                 dev->private = NULL;
2359                 usb->attached = 0;
2360                 usb->comedidev = NULL;
2361                 up(&usb->sem);
2362         }
2363 }
2364
2365 static struct comedi_driver usbdux_driver = {
2366         .driver_name    = "usbdux",
2367         .module         = THIS_MODULE,
2368         .auto_attach    = usbdux_auto_attach,
2369         .detach         = usbdux_detach,
2370 };
2371
2372 static void usbdux_firmware_request_complete_handler(const struct firmware *fw,
2373                                                      void *context)
2374 {
2375         struct usbduxsub *usbduxsub_tmp = context;
2376         struct usb_interface *uinterf = usbduxsub_tmp->interface;
2377         int ret;
2378
2379         if (fw == NULL) {
2380                 dev_err(&uinterf->dev,
2381                         "Firmware complete handler without firmware!\n");
2382                 return;
2383         }
2384
2385         /*
2386          * we need to upload the firmware here because fw will be
2387          * freed once we've left this function
2388          */
2389         ret = firmware_upload(usbduxsub_tmp, fw->data, fw->size);
2390
2391         if (ret) {
2392                 dev_err(&uinterf->dev,
2393                         "Could not upload firmware (err=%d)\n", ret);
2394                 goto out;
2395         }
2396         comedi_usb_auto_config(uinterf, &usbdux_driver, 0);
2397  out:
2398         release_firmware(fw);
2399 }
2400
2401 static int usbdux_usb_probe(struct usb_interface *uinterf,
2402                             const struct usb_device_id *id)
2403 {
2404         struct usb_device *udev = interface_to_usbdev(uinterf);
2405         struct device *dev = &uinterf->dev;
2406         int i;
2407         int index;
2408         int ret;
2409
2410         dev_dbg(dev, "comedi_: usbdux_: "
2411                 "finding a free structure for the usb-device\n");
2412
2413         down(&start_stop_sem);
2414         /* look for a free place in the usbdux array */
2415         index = -1;
2416         for (i = 0; i < NUMUSBDUX; i++) {
2417                 if (!(usbduxsub[i].probed)) {
2418                         index = i;
2419                         break;
2420                 }
2421         }
2422
2423         /* no more space */
2424         if (index == -1) {
2425                 dev_err(dev, "Too many usbdux-devices connected.\n");
2426                 up(&start_stop_sem);
2427                 return -EMFILE;
2428         }
2429         dev_dbg(dev, "comedi_: usbdux: "
2430                 "usbduxsub[%d] is ready to connect to comedi.\n", index);
2431
2432         sema_init(&(usbduxsub[index].sem), 1);
2433         /* save a pointer to the usb device */
2434         usbduxsub[index].usbdev = udev;
2435
2436         /* 2.6: save the interface itself */
2437         usbduxsub[index].interface = uinterf;
2438         /* get the interface number from the interface */
2439         usbduxsub[index].ifnum = uinterf->altsetting->desc.bInterfaceNumber;
2440         /* hand the private data over to the usb subsystem */
2441         /* will be needed for disconnect */
2442         usb_set_intfdata(uinterf, &(usbduxsub[index]));
2443
2444         dev_dbg(dev, "comedi_: usbdux: ifnum=%d\n", usbduxsub[index].ifnum);
2445
2446         /* test if it is high speed (USB 2.0) */
2447         usbduxsub[index].high_speed =
2448             (usbduxsub[index].usbdev->speed == USB_SPEED_HIGH);
2449
2450         /* create space for the commands of the DA converter */
2451         usbduxsub[index].dac_commands = kzalloc(NUMOUTCHANNELS, GFP_KERNEL);
2452         if (!usbduxsub[index].dac_commands) {
2453                 tidy_up(&(usbduxsub[index]));
2454                 up(&start_stop_sem);
2455                 return -ENOMEM;
2456         }
2457         /* create space for the commands going to the usb device */
2458         usbduxsub[index].dux_commands = kzalloc(SIZEOFDUXBUFFER, GFP_KERNEL);
2459         if (!usbduxsub[index].dux_commands) {
2460                 tidy_up(&(usbduxsub[index]));
2461                 up(&start_stop_sem);
2462                 return -ENOMEM;
2463         }
2464         /* create space for the in buffer and set it to zero */
2465         usbduxsub[index].in_buffer = kzalloc(SIZEINBUF, GFP_KERNEL);
2466         if (!(usbduxsub[index].in_buffer)) {
2467                 tidy_up(&(usbduxsub[index]));
2468                 up(&start_stop_sem);
2469                 return -ENOMEM;
2470         }
2471         /* create space of the instruction buffer */
2472         usbduxsub[index].insn_buffer = kzalloc(SIZEINSNBUF, GFP_KERNEL);
2473         if (!(usbduxsub[index].insn_buffer)) {
2474                 tidy_up(&(usbduxsub[index]));
2475                 up(&start_stop_sem);
2476                 return -ENOMEM;
2477         }
2478         /* create space for the outbuffer */
2479         usbduxsub[index].out_buffer = kzalloc(SIZEOUTBUF, GFP_KERNEL);
2480         if (!(usbduxsub[index].out_buffer)) {
2481                 tidy_up(&(usbduxsub[index]));
2482                 up(&start_stop_sem);
2483                 return -ENOMEM;
2484         }
2485         /* setting to alternate setting 3: enabling iso ep and bulk ep. */
2486         i = usb_set_interface(usbduxsub[index].usbdev,
2487                               usbduxsub[index].ifnum, 3);
2488         if (i < 0) {
2489                 dev_err(dev, "comedi_: usbdux%d: "
2490                         "could not set alternate setting 3 in high speed.\n",
2491                         index);
2492                 tidy_up(&(usbduxsub[index]));
2493                 up(&start_stop_sem);
2494                 return -ENODEV;
2495         }
2496         if (usbduxsub[index].high_speed)
2497                 usbduxsub[index].num_in_buffers = NUMOFINBUFFERSHIGH;
2498         else
2499                 usbduxsub[index].num_in_buffers = NUMOFINBUFFERSFULL;
2500
2501         usbduxsub[index].urb_in =
2502                 kcalloc(usbduxsub[index].num_in_buffers, sizeof(struct urb *),
2503                         GFP_KERNEL);
2504         if (!(usbduxsub[index].urb_in)) {
2505                 tidy_up(&(usbduxsub[index]));
2506                 up(&start_stop_sem);
2507                 return -ENOMEM;
2508         }
2509         for (i = 0; i < usbduxsub[index].num_in_buffers; i++) {
2510                 /* one frame: 1ms */
2511                 usbduxsub[index].urb_in[i] = usb_alloc_urb(1, GFP_KERNEL);
2512                 if (usbduxsub[index].urb_in[i] == NULL) {
2513                         dev_err(dev, "comedi_: usbdux%d: "
2514                                 "Could not alloc. urb(%d)\n", index, i);
2515                         tidy_up(&(usbduxsub[index]));
2516                         up(&start_stop_sem);
2517                         return -ENOMEM;
2518                 }
2519                 usbduxsub[index].urb_in[i]->dev = usbduxsub[index].usbdev;
2520                 /* will be filled later with a pointer to the comedi-device */
2521                 /* and ONLY then the urb should be submitted */
2522                 usbduxsub[index].urb_in[i]->context = NULL;
2523                 usbduxsub[index].urb_in[i]->pipe =
2524                     usb_rcvisocpipe(usbduxsub[index].usbdev, ISOINEP);
2525                 usbduxsub[index].urb_in[i]->transfer_flags = URB_ISO_ASAP;
2526                 usbduxsub[index].urb_in[i]->transfer_buffer =
2527                     kzalloc(SIZEINBUF, GFP_KERNEL);
2528                 if (!(usbduxsub[index].urb_in[i]->transfer_buffer)) {
2529                         tidy_up(&(usbduxsub[index]));
2530                         up(&start_stop_sem);
2531                         return -ENOMEM;
2532                 }
2533                 usbduxsub[index].urb_in[i]->complete = usbduxsub_ai_isoc_irq;
2534                 usbduxsub[index].urb_in[i]->number_of_packets = 1;
2535                 usbduxsub[index].urb_in[i]->transfer_buffer_length = SIZEINBUF;
2536                 usbduxsub[index].urb_in[i]->iso_frame_desc[0].offset = 0;
2537                 usbduxsub[index].urb_in[i]->iso_frame_desc[0].length = SIZEINBUF;
2538         }
2539
2540         /* out */
2541         if (usbduxsub[index].high_speed)
2542                 usbduxsub[index].num_out_buffers = NUMOFOUTBUFFERSHIGH;
2543         else
2544                 usbduxsub[index].num_out_buffers = NUMOFOUTBUFFERSFULL;
2545
2546         usbduxsub[index].urb_out =
2547                 kcalloc(usbduxsub[index].num_out_buffers, sizeof(struct urb *),
2548                         GFP_KERNEL);
2549         if (!(usbduxsub[index].urb_out)) {
2550                 tidy_up(&(usbduxsub[index]));
2551                 up(&start_stop_sem);
2552                 return -ENOMEM;
2553         }
2554         for (i = 0; i < usbduxsub[index].num_out_buffers; i++) {
2555                 /* one frame: 1ms */
2556                 usbduxsub[index].urb_out[i] = usb_alloc_urb(1, GFP_KERNEL);
2557                 if (usbduxsub[index].urb_out[i] == NULL) {
2558                         dev_err(dev, "comedi_: usbdux%d: "
2559                                 "Could not alloc. urb(%d)\n", index, i);
2560                         tidy_up(&(usbduxsub[index]));
2561                         up(&start_stop_sem);
2562                         return -ENOMEM;
2563                 }
2564                 usbduxsub[index].urb_out[i]->dev = usbduxsub[index].usbdev;
2565                 /* will be filled later with a pointer to the comedi-device */
2566                 /* and ONLY then the urb should be submitted */
2567                 usbduxsub[index].urb_out[i]->context = NULL;
2568                 usbduxsub[index].urb_out[i]->pipe =
2569                     usb_sndisocpipe(usbduxsub[index].usbdev, ISOOUTEP);
2570                 usbduxsub[index].urb_out[i]->transfer_flags = URB_ISO_ASAP;
2571                 usbduxsub[index].urb_out[i]->transfer_buffer =
2572                     kzalloc(SIZEOUTBUF, GFP_KERNEL);
2573                 if (!(usbduxsub[index].urb_out[i]->transfer_buffer)) {
2574                         tidy_up(&(usbduxsub[index]));
2575                         up(&start_stop_sem);
2576                         return -ENOMEM;
2577                 }
2578                 usbduxsub[index].urb_out[i]->complete = usbduxsub_ao_isoc_irq;
2579                 usbduxsub[index].urb_out[i]->number_of_packets = 1;
2580                 usbduxsub[index].urb_out[i]->transfer_buffer_length = SIZEOUTBUF;
2581                 usbduxsub[index].urb_out[i]->iso_frame_desc[0].offset = 0;
2582                 usbduxsub[index].urb_out[i]->iso_frame_desc[0].length =
2583                     SIZEOUTBUF;
2584                 if (usbduxsub[index].high_speed) {
2585                         /* uframes */
2586                         usbduxsub[index].urb_out[i]->interval = 8;
2587                 } else {
2588                         /* frames */
2589                         usbduxsub[index].urb_out[i]->interval = 1;
2590                 }
2591         }
2592
2593         /* pwm */
2594         if (usbduxsub[index].high_speed) {
2595                 /* max bulk ep size in high speed */
2596                 usbduxsub[index].size_pwm_buf = 512;
2597                 usbduxsub[index].urb_pwm = usb_alloc_urb(0, GFP_KERNEL);
2598                 if (usbduxsub[index].urb_pwm == NULL) {
2599                         dev_err(dev, "comedi_: usbdux%d: "
2600                                 "Could not alloc. pwm urb\n", index);
2601                         tidy_up(&(usbduxsub[index]));
2602                         up(&start_stop_sem);
2603                         return -ENOMEM;
2604                 }
2605                 usbduxsub[index].urb_pwm->transfer_buffer =
2606                     kzalloc(usbduxsub[index].size_pwm_buf, GFP_KERNEL);
2607                 if (!(usbduxsub[index].urb_pwm->transfer_buffer)) {
2608                         tidy_up(&(usbduxsub[index]));
2609                         up(&start_stop_sem);
2610                         return -ENOMEM;
2611                 }
2612         } else {
2613                 usbduxsub[index].urb_pwm = NULL;
2614                 usbduxsub[index].size_pwm_buf = 0;
2615         }
2616
2617         usbduxsub[index].ai_cmd_running = 0;
2618         usbduxsub[index].ao_cmd_running = 0;
2619         usbduxsub[index].pwm_cmd_running = 0;
2620
2621         /* we've reached the bottom of the function */
2622         usbduxsub[index].probed = 1;
2623         up(&start_stop_sem);
2624
2625         ret = reject_firmware_nowait(THIS_MODULE,
2626                                       FW_ACTION_HOTPLUG,
2627                                       FIRMWARE,
2628                                       &udev->dev,
2629                                       GFP_KERNEL,
2630                                       usbduxsub + index,
2631                                       usbdux_firmware_request_complete_handler);
2632
2633         if (ret) {
2634                 dev_err(dev, "Could not load firmware (err=%d)\n", ret);
2635                 return ret;
2636         }
2637
2638         dev_info(dev, "comedi_: usbdux%d "
2639                  "has been successfully initialised.\n", index);
2640         /* success */
2641         return 0;
2642 }
2643
2644 static void usbdux_usb_disconnect(struct usb_interface *intf)
2645 {
2646         struct usbduxsub *usbduxsub_tmp = usb_get_intfdata(intf);
2647         struct usb_device *udev = interface_to_usbdev(intf);
2648
2649         if (!usbduxsub_tmp) {
2650                 dev_err(&intf->dev,
2651                         "comedi_: disconnect called with null pointer.\n");
2652                 return;
2653         }
2654         if (usbduxsub_tmp->usbdev != udev) {
2655                 dev_err(&intf->dev, "comedi_: BUG! called with wrong ptr!!!\n");
2656                 return;
2657         }
2658         comedi_usb_auto_unconfig(intf);
2659         down(&start_stop_sem);
2660         down(&usbduxsub_tmp->sem);
2661         tidy_up(usbduxsub_tmp);
2662         up(&usbduxsub_tmp->sem);
2663         up(&start_stop_sem);
2664         dev_dbg(&intf->dev, "comedi_: disconnected from the usb\n");
2665 }
2666
2667 static const struct usb_device_id usbdux_usb_table[] = {
2668         { USB_DEVICE(0x13d8, 0x0001) },
2669         { USB_DEVICE(0x13d8, 0x0002) },
2670         { }
2671 };
2672
2673 MODULE_DEVICE_TABLE(usb, usbdux_usb_table);
2674
2675 static struct usb_driver usbdux_usb_driver = {
2676         .name           = "usbdux",
2677         .probe          = usbdux_usb_probe,
2678         .disconnect     = usbdux_usb_disconnect,
2679         .id_table       = usbdux_usb_table,
2680 };
2681 module_comedi_usb_driver(usbdux_driver, usbdux_usb_driver);
2682
2683 MODULE_AUTHOR("Bernd Porr, BerndPorr@f2s.com");
2684 MODULE_DESCRIPTION("Stirling/ITL USB-DUX -- Bernd.Porr@f2s.com");
2685 MODULE_LICENSE("GPL");
2686 /*(DEBLOBBED)*/