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