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