Staging: dt3155: remove DT_3155_* errno defines
[firefly-linux-kernel-4.4.55.git] / drivers / staging / dt3155 / dt3155_drv.c
1 /*
2
3 Copyright 1996,2002,2005 Gregory D. Hager, Alfred A. Rizzi, Noah J. Cowan,
4                          Jason Lapenta, Scott Smedley, Greg Sharp
5
6 This file is part of the DT3155 Device Driver.
7
8 The DT3155 Device Driver is free software; you can redistribute it
9 and/or modify it under the terms of the GNU General Public License as
10 published by the Free Software Foundation; either version 2 of the
11 License, or (at your option) any later version.
12
13 The DT3155 Device Driver is distributed in the hope that it will be
14 useful, but WITHOUT ANY WARRANTY; without even the implied warranty
15 of 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 the DT3155 Device Driver; if not, write to the Free
20 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
21 MA 02111-1307 USA
22
23 -- Changes --
24
25   Date     Programmer   Description of changes made
26   -------------------------------------------------------------------
27   03-Jul-2000 JML       n/a
28   10-Oct-2001 SS        port to 2.4 kernel
29   02-Apr-2002 SS        Mods to use allocator as a standalone module;
30                         Merged John Roll's changes (john@cfa.harvard.edu)
31                         to make work with multiple boards.
32   02-Jul-2002 SS        Merged James Rose's chages (rosejr@purdue.edu) to:
33                          * fix successive interrupt-driven captures
34                          * add select/poll support.
35   10-Jul-2002 GCS       Add error check when ndevices > MAXBOARDS.
36   02-Aug-2002 GCS       Fix field mode so that odd (lower) field is stored
37                         in lower half of buffer.
38   05-Aug-2005 SS        port to 2.6 kernel.
39   26-Oct-2009 SS        port to 2.6.30 kernel.
40
41 -- Notes --
42
43 ** appended "mem=124" in lilo.conf to allow for 4megs free on my 128meg system.
44  * using allocator.c and allocator.h from o'reilly book (alessandro rubini)
45     ftp://ftp.systemy.it/pub/develop (see README.allocator)
46
47  + might want to get rid of MAXboards for allocating initial buffer.
48     confusing and not necessary
49
50  + in cleanup_module the MOD_IN_USE looks like it is check after it should
51
52  * GFP_DMA should not be set with a PCI system (pg 291)
53
54  - NJC why are only two buffers allowed? (see isr, approx line 358)
55
56 */
57
58 extern void printques(int);
59
60 #include <linux/module.h>
61 #include <linux/interrupt.h>
62 #include <linux/pci.h>
63 #include <linux/types.h>
64 #include <linux/poll.h>
65 #include <linux/sched.h>
66 #include <linux/smp_lock.h>
67
68 #include <asm/io.h>
69 #include <asm/uaccess.h>
70
71 #include "dt3155.h"
72 #include "dt3155_drv.h"
73 #include "dt3155_isr.h"
74 #include "dt3155_io.h"
75 #include "allocator.h"
76
77
78 MODULE_LICENSE("GPL");
79
80 /* Error variable.  Zero means no error. */
81 int dt3155_errno = 0;
82
83 #ifndef PCI_DEVICE_ID_INTEL_7116
84 #define PCI_DEVICE_ID_INTEL_7116 0x1223
85 #endif
86
87 #define DT3155_VENDORID    PCI_VENDOR_ID_INTEL
88 #define DT3155_DEVICEID    PCI_DEVICE_ID_INTEL_7116
89 #define MAXPCI    16
90
91 #ifdef DT_DEBUG
92 #define DT_3155_DEBUG_MSG(x,y) printk(x,y)
93 #else
94 #define DT_3155_DEBUG_MSG(x,y)
95 #endif
96
97 /* wait queue for interrupts */
98 wait_queue_head_t dt3155_read_wait_queue[MAXBOARDS];
99
100 /* set to dynamicaly allocate, but it is tunable: */
101 /* insmod DT_3155 dt3155 dt3155_major=XX */
102 int dt3155_major = 0;
103
104 /* The minor numbers are 0 and 1 ... they are not tunable.
105  * They are used as the indices for the structure vectors,
106  * and register address vectors
107  */
108
109 /* Global structures and variables */
110
111 /* Status of each device */
112 struct dt3155_status dt3155_status[MAXBOARDS];
113
114 /* kernel logical address of the board */
115 u8 *dt3155_lbase[MAXBOARDS] = { NULL
116 #if MAXBOARDS == 2
117                                       , NULL
118 #endif
119 };
120 /* DT3155 registers              */
121 u8 *dt3155_bbase = NULL;                  /* kernel logical address of the *
122                                            * buffer region                 */
123 u32  dt3155_dev_open[MAXBOARDS] = {0
124 #if MAXBOARDS == 2
125                                        , 0
126 #endif
127 };
128
129 u32  ndevices = 0;
130 u32 unique_tag = 0;;
131
132
133 /*
134  * Stops interrupt generation right away and resets the status
135  * to idle.  I don't know why this works and the other way doesn't.
136  * (James Rose)
137  */
138 static void quick_stop (int minor)
139 {
140   // TODO: scott was here
141 #if 1
142   ReadMReg((dt3155_lbase[minor] + INT_CSR), int_csr_r.reg);
143   /* disable interrupts */
144   int_csr_r.fld.FLD_END_EVE_EN = 0;
145   int_csr_r.fld.FLD_END_ODD_EN = 0;
146   WriteMReg((dt3155_lbase[minor] + INT_CSR), int_csr_r.reg);
147
148   dt3155_status[minor].state &= ~(DT3155_STATE_STOP|0xff);
149   /* mark the system stopped: */
150   dt3155_status[minor].state |= DT3155_STATE_IDLE;
151   dt3155_fbuffer[minor]->stop_acquire = 0;
152   dt3155_fbuffer[minor]->even_stopped = 0;
153 #else
154   dt3155_status[minor].state |= DT3155_STATE_STOP;
155   dt3155_status[minor].fbuffer.stop_acquire = 1;
156 #endif
157
158 }
159
160
161 /*****************************************************
162  *  dt3155_isr() Interrupt service routien
163  *
164  * - looks like this isr supports IRQ sharing (or could) JML
165  * - Assumes irq's are disabled, via SA_INTERRUPT flag
166  * being set in request_irq() call from init_module()
167  *****************************************************/
168 static void dt3155_isr(int irq, void *dev_id, struct pt_regs *regs)
169 {
170   int    minor = -1;
171   int    index;
172   unsigned long flags;
173   u32 buffer_addr;
174
175   /* find out who issued the interrupt */
176   for (index = 0; index < ndevices; index++) {
177     if(dev_id == (void*) &dt3155_status[index])
178       {
179         minor = index;
180         break;
181       }
182   }
183
184   /* hopefully we should not get here */
185   if (minor < 0 || minor >= MAXBOARDS) {
186     printk(KERN_ERR "dt3155_isr called with invalid dev_id\n");
187     return;
188   }
189
190   /* Check for corruption and set a flag if so */
191   ReadMReg((dt3155_lbase[minor] + CSR1), csr1_r.reg);
192
193   if ((csr1_r.fld.FLD_CRPT_EVE) || (csr1_r.fld.FLD_CRPT_ODD))
194     {
195       /* TODO: this should probably stop acquisition */
196       /* and set some flags so that dt3155_read      */
197       /* returns an error next time it is called     */
198       dt3155_errno = DT_ERR_CORRUPT;
199       printk("dt3155:  corrupt field\n");
200       return;
201     }
202
203   ReadMReg((dt3155_lbase[minor] + INT_CSR), int_csr_r.reg);
204
205   /* Handle the even field ... */
206   if (int_csr_r.fld.FLD_END_EVE)
207     {
208       if ((dt3155_status[minor].state & DT3155_STATE_MODE) ==
209            DT3155_STATE_FLD)
210         {
211           dt3155_fbuffer[minor]->frame_count++;
212         }
213
214       ReadI2C(dt3155_lbase[minor], EVEN_CSR, &i2c_even_csr.reg);
215
216       /* Clear the interrupt? */
217       int_csr_r.fld.FLD_END_EVE = 1;
218
219       /* disable the interrupt if last field */
220       if (dt3155_fbuffer[minor]->stop_acquire)
221         {
222           printk("dt3155:  even stopped.\n");
223           dt3155_fbuffer[minor]->even_stopped = 1;
224           if (i2c_even_csr.fld.SNGL_EVE)
225             {
226               int_csr_r.fld.FLD_END_EVE_EN = 0;
227             }
228           else
229             {
230               i2c_even_csr.fld.SNGL_EVE  = 1;
231             }
232         }
233
234       WriteMReg((dt3155_lbase[minor] + INT_CSR), int_csr_r.reg);
235
236       /* Set up next DMA if we are doing FIELDS */
237       if ((dt3155_status[minor].state & DT3155_STATE_MODE) ==
238            DT3155_STATE_FLD)
239         {
240           /* GCS (Aug 2, 2002) -- In field mode, dma the odd field
241              into the lower half of the buffer */
242           const u32 stride =  dt3155_status[minor].config.cols;
243           buffer_addr = dt3155_fbuffer[minor]->
244             frame_info[dt3155_fbuffer[minor]->active_buf].addr
245             + (DT3155_MAX_ROWS / 2) * stride;
246           local_save_flags(flags);
247           local_irq_disable();
248           wake_up_interruptible(&dt3155_read_wait_queue[minor]);
249
250           /* Set up the DMA address for the next field */
251           local_irq_restore(flags);
252           WriteMReg((dt3155_lbase[minor] + ODD_DMA_START), buffer_addr);
253         }
254
255       /* Check for errors. */
256       i2c_even_csr.fld.DONE_EVE = 1;
257       if (i2c_even_csr.fld.ERROR_EVE)
258         dt3155_errno = DT_ERR_OVERRUN;
259
260       WriteI2C(dt3155_lbase[minor], EVEN_CSR, i2c_even_csr.reg);
261
262       /* Note that we actually saw an even field meaning  */
263       /* that subsequent odd field complete the frame     */
264       dt3155_fbuffer[minor]->even_happened = 1;
265
266       /* recording the time that the even field finished, this should be */
267       /* about time in the middle of the frame */
268       do_gettimeofday(&(dt3155_fbuffer[minor]->
269                          frame_info[dt3155_fbuffer[minor]->
270                                      active_buf].time));
271       return;
272     }
273
274   /* ... now handle the odd field */
275   if (int_csr_r.fld.FLD_END_ODD)
276     {
277       ReadI2C(dt3155_lbase[minor], ODD_CSR, &i2c_odd_csr.reg);
278
279       /* Clear the interrupt? */
280       int_csr_r.fld.FLD_END_ODD = 1;
281
282       if (dt3155_fbuffer[minor]->even_happened ||
283           (dt3155_status[minor].state & DT3155_STATE_MODE) ==
284           DT3155_STATE_FLD)
285         {
286           dt3155_fbuffer[minor]->frame_count++;
287         }
288
289       if (dt3155_fbuffer[minor]->stop_acquire &&
290            dt3155_fbuffer[minor]->even_stopped)
291         {
292           printk(KERN_DEBUG "dt3155:  stopping odd..\n");
293           if (i2c_odd_csr.fld.SNGL_ODD)
294             {
295               /* disable interrupts */
296               int_csr_r.fld.FLD_END_ODD_EN = 0;
297               dt3155_status[minor].state &= ~(DT3155_STATE_STOP|0xff);
298
299               /* mark the system stopped: */
300               dt3155_status[minor].state |= DT3155_STATE_IDLE;
301               dt3155_fbuffer[minor]->stop_acquire = 0;
302               dt3155_fbuffer[minor]->even_stopped = 0;
303
304               printk(KERN_DEBUG "dt3155:  state is now %x\n",
305                      dt3155_status[minor].state);
306             }
307           else
308             {
309               i2c_odd_csr.fld.SNGL_ODD  = 1;
310             }
311         }
312
313       WriteMReg((dt3155_lbase[minor] + INT_CSR), int_csr_r.reg);
314
315       /* if the odd field has been acquired, then     */
316       /* change the next dma location for both fields */
317       /* and wake up the process if sleeping          */
318       if (dt3155_fbuffer[minor]->even_happened ||
319            (dt3155_status[minor].state & DT3155_STATE_MODE) ==
320            DT3155_STATE_FLD)
321         {
322
323           local_save_flags(flags);
324           local_irq_disable();
325
326 #ifdef DEBUG_QUES_B
327           printques(minor);
328 #endif
329           if (dt3155_fbuffer[minor]->nbuffers > 2)
330             {
331               if (!are_empty_buffers(minor))
332                 {
333                   /* The number of active + locked buffers is
334                    * at most 2, and since there are none empty, there
335                    * must be at least nbuffers-2 ready buffers.
336                    * This is where we 'drop frames', oldest first. */
337                   push_empty(pop_ready(minor),  minor);
338                 }
339
340               /* The ready_que can't be full, since we know
341                * there is one active buffer right now, so it's safe
342                * to push the active buf on the ready_que. */
343               push_ready(minor, dt3155_fbuffer[minor]->active_buf);
344               /* There's at least 1 empty -- make it active */
345               dt3155_fbuffer[minor]->active_buf = pop_empty(minor);
346               dt3155_fbuffer[minor]->
347                 frame_info[dt3155_fbuffer[minor]->
348                             active_buf].tag = ++unique_tag;
349             }
350           else /* nbuffers == 2, special case */
351             { /* There is 1 active buffer.
352                * If there is a locked buffer, keep the active buffer
353                * the same -- that means we drop a frame.
354                */
355               if (dt3155_fbuffer[minor]->locked_buf < 0)
356                 {
357                   push_ready(minor,
358                               dt3155_fbuffer[minor]->active_buf);
359                   if (are_empty_buffers(minor))
360                     {
361                       dt3155_fbuffer[minor]->active_buf =
362                         pop_empty(minor);
363                     }
364                   else
365                     { /* no empty or locked buffers, so use a readybuf */
366                       dt3155_fbuffer[minor]->active_buf =
367                         pop_ready(minor);
368                     }
369                 }
370             }
371
372 #ifdef DEBUG_QUES_B
373           printques(minor);
374 #endif
375
376           dt3155_fbuffer[minor]->even_happened = 0;
377
378           wake_up_interruptible(&dt3155_read_wait_queue[minor]);
379
380           local_irq_restore(flags);
381         }
382
383
384       /* Set up the DMA address for the next frame/field */
385       buffer_addr = dt3155_fbuffer[minor]->
386         frame_info[dt3155_fbuffer[minor]->active_buf].addr;
387       if ((dt3155_status[minor].state & DT3155_STATE_MODE) ==
388            DT3155_STATE_FLD)
389         {
390           WriteMReg((dt3155_lbase[minor] + EVEN_DMA_START), buffer_addr);
391         }
392       else
393         {
394           WriteMReg((dt3155_lbase[minor] + EVEN_DMA_START), buffer_addr);
395
396           WriteMReg((dt3155_lbase[minor] + ODD_DMA_START), buffer_addr
397                     + dt3155_status[minor].config.cols);
398         }
399
400       /* Do error checking */
401       i2c_odd_csr.fld.DONE_ODD = 1;
402       if (i2c_odd_csr.fld.ERROR_ODD)
403         dt3155_errno = DT_ERR_OVERRUN;
404
405       WriteI2C(dt3155_lbase[minor], ODD_CSR, i2c_odd_csr.reg);
406
407       return;
408     }
409   /* If we get here, the Odd Field wasn't it either... */
410   printk("neither even nor odd.  shared perhaps?\n");
411 }
412
413 /*****************************************************
414  * init_isr(int minor)
415  *   turns on interupt generation for the card
416  *   designated by "minor".
417  *   It is called *only* from inside ioctl().
418  *****************************************************/
419 static void dt3155_init_isr(int minor)
420 {
421   const u32 stride =  dt3155_status[minor].config.cols;
422
423   switch (dt3155_status[minor].state & DT3155_STATE_MODE)
424     {
425     case DT3155_STATE_FLD:
426       {
427         even_dma_start_r  = dt3155_status[minor].
428           fbuffer.frame_info[dt3155_status[minor].fbuffer.active_buf].addr;
429         even_dma_stride_r = 0;
430         odd_dma_stride_r  = 0;
431
432         WriteMReg((dt3155_lbase[minor] + EVEN_DMA_START),
433                   even_dma_start_r);
434         WriteMReg((dt3155_lbase[minor] + EVEN_DMA_STRIDE),
435                   even_dma_stride_r);
436         WriteMReg((dt3155_lbase[minor] + ODD_DMA_STRIDE),
437                   odd_dma_stride_r);
438         break;
439       }
440
441     case DT3155_STATE_FRAME:
442     default:
443       {
444         even_dma_start_r  = dt3155_status[minor].
445           fbuffer.frame_info[dt3155_status[minor].fbuffer.active_buf].addr;
446         odd_dma_start_r   =  even_dma_start_r + stride;
447         even_dma_stride_r =  stride;
448         odd_dma_stride_r  =  stride;
449
450         WriteMReg((dt3155_lbase[minor] + EVEN_DMA_START),
451                   even_dma_start_r);
452         WriteMReg((dt3155_lbase[minor] + ODD_DMA_START),
453                   odd_dma_start_r);
454         WriteMReg((dt3155_lbase[minor] + EVEN_DMA_STRIDE),
455                   even_dma_stride_r);
456         WriteMReg((dt3155_lbase[minor] + ODD_DMA_STRIDE),
457                   odd_dma_stride_r);
458         break;
459       }
460     }
461
462   /* 50/60 Hz should be set before this point but let's make sure it is */
463   /* right anyway */
464
465   ReadI2C(dt3155_lbase[minor], CSR2, &i2c_csr2.reg);
466   i2c_csr2.fld.HZ50 = FORMAT50HZ;
467   WriteI2C(dt3155_lbase[minor], CSR2, i2c_csr2.reg);
468
469   /* enable busmaster chip, clear flags */
470
471   /*
472    * TODO:
473    * shouldn't we be concered with continuous values of
474    * DT3155_SNAP & DT3155_ACQ here? (SS)
475    */
476
477   csr1_r.reg                = 0;
478   csr1_r.fld.CAP_CONT_EVE   = 1; /* use continuous capture bits to */
479   csr1_r.fld.CAP_CONT_ODD   = 1; /* enable */
480   csr1_r.fld.FLD_DN_EVE     = 1; /* writing a 1 clears flags */
481   csr1_r.fld.FLD_DN_ODD     = 1;
482   csr1_r.fld.SRST           = 1; /* reset        - must be 1 */
483   csr1_r.fld.FIFO_EN        = 1; /* fifo control - must be 1 */
484   csr1_r.fld.FLD_CRPT_EVE   = 1; /* writing a 1 clears flags */
485   csr1_r.fld.FLD_CRPT_ODD   = 1;
486
487   WriteMReg((dt3155_lbase[minor] + CSR1),csr1_r.reg);
488
489   /* Enable interrupts at the end of each field */
490
491   int_csr_r.reg = 0;
492   int_csr_r.fld.FLD_END_EVE_EN = 1;
493   int_csr_r.fld.FLD_END_ODD_EN = 1;
494   int_csr_r.fld.FLD_START_EN = 0;
495
496   WriteMReg((dt3155_lbase[minor] + INT_CSR), int_csr_r.reg);
497
498   /* start internal BUSY bits */
499
500   ReadI2C(dt3155_lbase[minor], CSR2, &i2c_csr2.reg);
501   i2c_csr2.fld.BUSY_ODD  = 1;
502   i2c_csr2.fld.BUSY_EVE  = 1;
503   WriteI2C(dt3155_lbase[minor], CSR2, i2c_csr2.reg);
504
505   /* Now its up to the interrupt routine!! */
506
507   return;
508 }
509
510
511 /*****************************************************
512  * ioctl()
513  *
514  *****************************************************/
515 static int dt3155_ioctl(struct inode *inode,
516                         struct file *file,
517                         unsigned int cmd,
518                         unsigned long arg)
519 {
520   int minor = MINOR(inode->i_rdev); /* What device are we ioctl()'ing? */
521   void __user *up = (void __user *)arg;
522
523   if (minor >= MAXBOARDS || minor < 0)
524     return -ENODEV;
525
526   /* make sure it is valid command */
527   if (_IOC_NR(cmd) > DT3155_IOC_MAXNR)
528     {
529       printk("DT3155: invalid IOCTL(0x%x)\n",cmd);
530       printk("DT3155: Valid commands (0x%x), (0x%x), (0x%x), (0x%x), (0x%x)\n",
531              (unsigned int)DT3155_GET_CONFIG,
532              (unsigned int)DT3155_SET_CONFIG,
533              (unsigned int)DT3155_START,
534              (unsigned int)DT3155_STOP,
535              (unsigned int)DT3155_FLUSH);
536       return -EINVAL;
537     }
538
539   switch (cmd)
540     {
541     case DT3155_SET_CONFIG:
542       {
543         if (dt3155_status[minor].state != DT3155_STATE_IDLE)
544           return -EBUSY;
545
546         {
547           struct dt3155_config tmp;
548           if (copy_from_user(&tmp, up, sizeof(tmp)))
549               return -EFAULT;
550           /* check for valid settings */
551           if (tmp.rows > DT3155_MAX_ROWS ||
552               tmp.cols > DT3155_MAX_COLS ||
553               (tmp.acq_mode != DT3155_MODE_FRAME &&
554                tmp.acq_mode != DT3155_MODE_FIELD) ||
555               (tmp.continuous != DT3155_SNAP &&
556                tmp.continuous != DT3155_ACQ))
557             {
558               return -EINVAL;
559             }
560           dt3155_status[minor].config = tmp;
561         }
562         return 0;
563       }
564     case DT3155_GET_CONFIG:
565       {
566         if (copy_to_user(up, &dt3155_status[minor],
567                      sizeof(struct dt3155_status)))
568             return -EFAULT;
569         return 0;
570       }
571     case DT3155_FLUSH: /* Flushes the buffers -- ensures fresh data */
572       {
573         if (dt3155_status[minor].state != DT3155_STATE_IDLE)
574           return -EBUSY;
575         return dt3155_flush(minor);
576       }
577     case DT3155_STOP:
578       {
579         if (dt3155_status[minor].state & DT3155_STATE_STOP ||
580             dt3155_status[minor].fbuffer.stop_acquire)
581           return -EBUSY;
582
583         if (dt3155_status[minor].state == DT3155_STATE_IDLE)
584           return 0;
585
586         quick_stop(minor);
587         if (copy_to_user(up, &dt3155_status[minor],
588                      sizeof(struct dt3155_status)))
589             return -EFAULT;
590         return 0;
591       }
592     case DT3155_START:
593       {
594         if (dt3155_status[minor].state != DT3155_STATE_IDLE)
595           return -EBUSY;
596
597         dt3155_status[minor].fbuffer.stop_acquire = 0;
598         dt3155_status[minor].fbuffer.frame_count = 0;
599
600         /* Set the MODE in the status -- we default to FRAME */
601         if (dt3155_status[minor].config.acq_mode == DT3155_MODE_FIELD)
602           {
603             dt3155_status[minor].state = DT3155_STATE_FLD;
604           }
605         else
606           {
607             dt3155_status[minor].state = DT3155_STATE_FRAME;
608           }
609
610         dt3155_init_isr(minor);
611         if (copy_to_user(up, &dt3155_status[minor],
612                       sizeof(struct dt3155_status)))
613             return -EFAULT;
614         return 0;
615       }
616     default:
617       {
618         printk("DT3155: invalid IOCTL(0x%x)\n",cmd);
619       printk("DT3155: Valid commands (0x%x), (0x%x), (0x%x), (0x%x), (0x%x)\n",
620              (unsigned int)DT3155_GET_CONFIG,
621              (unsigned int)DT3155_SET_CONFIG,
622              DT3155_START, DT3155_STOP, DT3155_FLUSH);
623         return -ENOSYS;
624       }
625     }
626   return -ENOSYS;
627 }
628
629 /*****************************************************
630  * mmap()
631  *
632  * only allow the user to mmap the registers and buffer
633  * It is quite possible that this is broken, since the
634  * addition of of the capacity for two cards!!!!!!!!
635  * It *looks* like it should work but since I'm not
636  * sure how to use it, I'm not actually sure. (NJC? ditto by SS)
637  *****************************************************/
638 static int dt3155_mmap (struct file * file, struct vm_area_struct * vma)
639 {
640   /* which device are we mmapping? */
641   int                           minor = MINOR(file->f_dentry->d_inode->i_rdev);
642   unsigned long offset;
643   offset = vma->vm_pgoff << PAGE_SHIFT;
644
645   if (offset >= __pa(high_memory) || (file->f_flags & O_SYNC))
646     vma->vm_flags |= VM_IO;
647
648   /* Don't try to swap out physical pages.. */
649   vma->vm_flags |= VM_RESERVED;
650
651   /* they are mapping the registers or the buffer */
652   if ((offset == dt3155_status[minor].reg_addr &&
653        vma->vm_end - vma->vm_start == PCI_PAGE_SIZE) ||
654       (offset == dt3155_status[minor].mem_addr &&
655        vma->vm_end - vma->vm_start == dt3155_status[minor].mem_size))
656     {
657       if (remap_pfn_range(vma,
658                         vma->vm_start,
659                         offset >> PAGE_SHIFT,
660                         vma->vm_end - vma->vm_start,
661                         vma->vm_page_prot)) {
662           printk("DT3155: remap_page_range() failed.\n");
663           return -EAGAIN;
664         }
665     }
666   else
667     {
668       printk("DT3155: dt3155_mmap() bad call.\n");
669       return -ENXIO;
670     }
671
672   return 0;
673 }
674
675
676 /*****************************************************
677  * open()
678  *
679  * Our special open code.
680  * MOD_INC_USE_COUNT make sure that the driver memory is not freed
681  * while the device is in use.
682  *****************************************************/
683 static int dt3155_open(struct inode* inode, struct file* filep)
684 {
685   int minor = MINOR(inode->i_rdev); /* what device are we opening? */
686   if (dt3155_dev_open[minor]) {
687     printk ("DT3155:  Already opened by another process.\n");
688     return -EBUSY;
689   }
690
691   if (dt3155_status[minor].device_installed==0)
692     {
693       printk("DT3155 Open Error: No such device dt3155 minor number %d\n",
694              minor);
695       return -EIO;
696     }
697
698   if (dt3155_status[minor].state != DT3155_STATE_IDLE) {
699     printk ("DT3155:  Not in idle state (state = %x)\n",
700             dt3155_status[minor].state);
701     return -EBUSY;
702   }
703
704   printk("DT3155: Device opened.\n");
705
706   dt3155_dev_open[minor] = 1 ;
707
708   dt3155_flush(minor);
709
710   /* Disable ALL interrupts */
711   int_csr_r.reg = 0;
712   WriteMReg((dt3155_lbase[minor] + INT_CSR), int_csr_r.reg);
713
714   init_waitqueue_head(&(dt3155_read_wait_queue[minor]));
715
716   return 0;
717 }
718
719
720 /*****************************************************
721  * close()
722  *
723  * Now decrement the use count.
724  *
725  *****************************************************/
726 static int dt3155_close(struct inode *inode, struct file *filep)
727 {
728   int minor;
729
730   minor = MINOR(inode->i_rdev); /* which device are we closing */
731   if (!dt3155_dev_open[minor])
732     {
733       printk("DT3155: attempt to CLOSE a not OPEN device\n");
734     }
735   else
736     {
737       dt3155_dev_open[minor] = 0;
738
739       if (dt3155_status[minor].state != DT3155_STATE_IDLE)
740         {
741           quick_stop(minor);
742         }
743     }
744   return 0;
745 }
746
747 /*****************************************************
748  * read()
749  *
750  *****************************************************/
751 static ssize_t dt3155_read(struct file *filep, char __user *buf,
752                            size_t count, loff_t *ppos)
753 {
754   /* which device are we reading from? */
755   int           minor = MINOR(filep->f_dentry->d_inode->i_rdev);
756   u32           offset;
757   int           frame_index;
758   struct frame_info     *frame_info;
759
760   /* TODO: this should check the error flag and */
761   /*   return an error on hardware failures */
762   if (count != sizeof(struct dt3155_read))
763     {
764       printk("DT3155 ERROR (NJC): count is not right\n");
765       return -EINVAL;
766     }
767
768
769   /* Hack here -- I'm going to allow reading even when idle.
770    * this is so that the frames can be read after STOP has
771    * been called.  Leaving it here, commented out, as a reminder
772    * for a short while to make sure there are no problems.
773    * Note that if the driver is not opened in non_blocking mode,
774    * and the device is idle, then it could sit here forever! */
775
776   /*  if (dt3155_status[minor].state == DT3155_STATE_IDLE)*/
777   /*    return -EBUSY;*/
778
779   /* non-blocking reads should return if no data */
780   if (filep->f_flags & O_NDELAY)
781     {
782       if ((frame_index = dt3155_get_ready_buffer(minor)) < 0) {
783         /*printk("dt3155:  no buffers available (?)\n");*/
784         /*              printques(minor); */
785         return -EAGAIN;
786       }
787     }
788   else
789     {
790       /*
791        * sleep till data arrives , or we get interrupted.
792        * Note that wait_event_interruptible() does not actually
793        * sleep/wait if it's condition evaluates to true upon entry.
794        */
795       wait_event_interruptible(dt3155_read_wait_queue[minor],
796                                (frame_index = dt3155_get_ready_buffer(minor))
797                                >= 0);
798
799       if (frame_index < 0)
800         {
801           printk ("DT3155: read: interrupted\n");
802           quick_stop (minor);
803           printques(minor);
804           return -EINTR;
805         }
806     }
807
808   frame_info = &dt3155_status[minor].fbuffer.frame_info[frame_index];
809
810   /* make this an offset */
811   offset = frame_info->addr - dt3155_status[minor].mem_addr;
812
813   put_user(offset, (unsigned int __user *)buf);
814   buf += sizeof(u32);
815   put_user(dt3155_status[minor].fbuffer.frame_count, (unsigned int __user *)buf);
816   buf += sizeof(u32);
817   put_user(dt3155_status[minor].state, (unsigned int __user *)buf);
818   buf += sizeof(u32);
819   if (copy_to_user(buf, frame_info, sizeof(*frame_info)))
820       return -EFAULT;
821
822   return sizeof(struct dt3155_read);
823 }
824
825 static unsigned int dt3155_poll (struct file * filp, poll_table *wait)
826 {
827   int minor = MINOR(filp->f_dentry->d_inode->i_rdev);
828
829   if (!is_ready_buf_empty(minor))
830     return POLLIN | POLLRDNORM;
831
832   poll_wait (filp, &dt3155_read_wait_queue[minor], wait);
833
834   return 0;
835 }
836
837 static long
838 dt3155_unlocked_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
839 {
840         int ret;
841
842         lock_kernel();
843         ret = dt3155_ioctl(file->f_path.dentry->d_inode, file, cmd, arg);
844         unlock_kernel();
845
846         return ret;
847 }
848
849 /*****************************************************
850  * file operations supported by DT3155 driver
851  *  needed by init_module
852  *  register_chrdev
853  *****************************************************/
854 static struct file_operations dt3155_fops = {
855         .read           = dt3155_read,
856         .unlocked_ioctl = dt3155_unlocked_ioctl,
857         .mmap           = dt3155_mmap,
858         .poll           = dt3155_poll,
859         .open           = dt3155_open,
860         .release        = dt3155_close
861 };
862
863
864 /*****************************************************
865  * find_PCI();
866  *
867  * PCI has been totally reworked in 2.1..
868  *****************************************************/
869 static int find_PCI (void)
870 {
871   struct pci_dev *pci_dev = NULL;
872   int error, pci_index = 0;
873   unsigned short rev_device;
874   unsigned long base;
875   unsigned char irq;
876
877   while ((pci_dev = pci_get_device
878           (DT3155_VENDORID, DT3155_DEVICEID, pci_dev)) != NULL)
879     {
880       pci_index ++;
881
882       /* Is it really there? */
883       if ((error =
884            pci_read_config_word(pci_dev, PCI_CLASS_DEVICE, &rev_device)))
885         continue;
886
887       /* Found a board */
888       DT_3155_DEBUG_MSG("DT3155: Device number %d \n", pci_index);
889
890       /* Make sure the driver was compiled with enough buffers to handle
891          this many boards */
892       if (pci_index > MAXBOARDS) {
893         printk("DT3155: ERROR - found %d devices, but driver only configured "
894                "for %d devices\n"
895                "DT3155: Please change MAXBOARDS in dt3155.h\n",
896                pci_index, MAXBOARDS);
897         goto err;
898       }
899
900       /* Now, just go out and make sure that this/these device(s) is/are
901          actually mapped into the kernel address space */
902       if ((error = pci_read_config_dword(pci_dev, PCI_BASE_ADDRESS_0,
903                                           (u32 *) &base)))
904         {
905           printk("DT3155: Was not able to find device \n");
906           goto err;
907         }
908
909       DT_3155_DEBUG_MSG("DT3155: Base address 0 for device is %lx \n", base);
910       dt3155_status[pci_index-1].reg_addr = base;
911
912       /* Remap the base address to a logical address through which we
913        * can access it. */
914       dt3155_lbase[pci_index - 1] = ioremap(base,PCI_PAGE_SIZE);
915       dt3155_status[pci_index - 1].reg_addr = base;
916       DT_3155_DEBUG_MSG("DT3155: New logical address is %p \n",
917                         dt3155_lbase[pci_index-1]);
918       if (!dt3155_lbase[pci_index-1])
919         {
920           printk("DT3155: Unable to remap control registers\n");
921           goto err;
922         }
923
924       if ((error = pci_read_config_byte(pci_dev, PCI_INTERRUPT_LINE, &irq)))
925         {
926           printk("DT3155: Was not able to find device \n");
927           goto err;
928         }
929
930       DT_3155_DEBUG_MSG("DT3155: IRQ is %d \n",irq);
931       dt3155_status[pci_index-1].irq = irq;
932       /* Set flag: kth device found! */
933       dt3155_status[pci_index-1].device_installed = 1;
934       printk("DT3155: Installing device %d w/irq %d and address %p\n",
935              pci_index,
936              dt3155_status[pci_index-1].irq,
937              dt3155_lbase[pci_index-1]);
938
939     }
940   ndevices = pci_index;
941
942   return 0;
943
944 err:
945   pci_dev_put(pci_dev);
946   return -EIO;
947 }
948
949 u32 allocatorAddr = 0;
950
951 /*****************************************************
952  * init_module()
953  *****************************************************/
954 int init_module(void)
955 {
956   int index;
957   int rcode = 0;
958   char *devname[MAXBOARDS];
959
960   devname[0] = "dt3155a";
961 #if MAXBOARDS == 2
962   devname[1] = "dt3155b";
963 #endif
964
965   printk("DT3155: Loading module...\n");
966
967   /* Register the device driver */
968   rcode = register_chrdev(dt3155_major, "dt3155", &dt3155_fops);
969   if(rcode < 0)
970     {
971       printk(KERN_INFO "DT3155: register_chrdev failed \n");
972       return rcode;
973     }
974
975   if(dt3155_major == 0)
976     dt3155_major = rcode; /* dynamic */
977
978
979   /* init the status variables.                     */
980   /* DMA memory is taken care of in setup_buffers() */
981   for (index = 0; index < MAXBOARDS; index++)
982     {
983       dt3155_status[index].config.acq_mode   = DT3155_MODE_FRAME;
984       dt3155_status[index].config.continuous = DT3155_ACQ;
985       dt3155_status[index].config.cols       = DT3155_MAX_COLS;
986       dt3155_status[index].config.rows       = DT3155_MAX_ROWS;
987       dt3155_status[index].state = DT3155_STATE_IDLE;
988
989       /* find_PCI() will check if devices are installed; */
990       /* first assume they're not:                       */
991       dt3155_status[index].mem_addr          = 0;
992       dt3155_status[index].mem_size          = 0;
993       dt3155_status[index].state             = DT3155_STATE_IDLE;
994       dt3155_status[index].device_installed  = 0;
995     }
996
997   /* Now let's find the hardware.  find_PCI() will set ndevices to the
998    * number of cards found in this machine. */
999     {
1000       if ((rcode = find_PCI()) != 0)
1001         {
1002           printk("DT3155 error: find_PCI() failed to find dt3155 board(s)\n");
1003           unregister_chrdev(dt3155_major, "dt3155");
1004           return rcode;
1005         }
1006     }
1007
1008   /* Ok, time to setup the frame buffers */
1009   if((rcode = dt3155_setup_buffers(&allocatorAddr)) < 0)
1010     {
1011       printk("DT3155: Error: setting up buffer not large enough.");
1012       unregister_chrdev(dt3155_major, "dt3155");
1013       return rcode;
1014     }
1015
1016   /* If we are this far, then there is enough RAM */
1017   /* for the buffers: Print the configuration.    */
1018   for( index = 0;  index < ndevices;  index++)
1019     {
1020       printk("DT3155: Device = %d; acq_mode = %d; "
1021              "continuous = %d; cols = %d; rows = %d;\n",
1022              index ,
1023              dt3155_status[index].config.acq_mode,
1024              dt3155_status[index].config.continuous,
1025              dt3155_status[index].config.cols,
1026              dt3155_status[index].config.rows);
1027       printk("DT3155: m_addr = 0x%x; m_size = %ld; "
1028              "state = %d; device_installed = %d\n",
1029              dt3155_status[index].mem_addr,
1030              (long int)dt3155_status[index].mem_size,
1031              dt3155_status[index].state,
1032              dt3155_status[index].device_installed);
1033     }
1034
1035   /* Disable ALL interrupts */
1036   int_csr_r.reg = 0;
1037   for( index = 0;  index < ndevices;  index++)
1038     {
1039       WriteMReg((dt3155_lbase[index] + INT_CSR), int_csr_r.reg);
1040       if(dt3155_status[index].device_installed)
1041         {
1042           /*
1043            * This driver *looks* like it can handle sharing interrupts,
1044            * but I can't actually test myself. I've had reports that it
1045            * DOES work so I'll enable it for now. This comment will remain
1046            * as a reminder in case any problems arise. (SS)
1047            */
1048           /* in older kernels flags are: SA_SHIRQ | SA_INTERRUPT */
1049           rcode = request_irq(dt3155_status[index].irq, (void *)dt3155_isr,
1050                                IRQF_SHARED | IRQF_DISABLED, devname[index],
1051                                (void*) &dt3155_status[index]);
1052           if(rcode < 0)
1053             {
1054               printk("DT3155: minor %d request_irq failed for IRQ %d\n",
1055                      index, dt3155_status[index].irq);
1056               unregister_chrdev(dt3155_major, "dt3155");
1057               return rcode;
1058             }
1059         }
1060     }
1061
1062   printk("DT3155: finished loading\n");
1063
1064   return 0;
1065 }
1066
1067 /*****************************************************
1068  * cleanup_module(void)
1069  *
1070  *****************************************************/
1071 void cleanup_module(void)
1072 {
1073   int index;
1074
1075   printk("DT3155:  cleanup_module called\n");
1076
1077   /* removed DMA allocated with the allocator */
1078 #ifdef STANDALONE_ALLOCATOR
1079   if (allocatorAddr != 0)
1080     allocator_free_dma(allocatorAddr);
1081 #else
1082   allocator_cleanup();
1083 #endif
1084
1085   unregister_chrdev(dt3155_major, "dt3155");
1086
1087   for(index = 0; index < ndevices; index++)
1088     {
1089       if(dt3155_status[index].device_installed == 1)
1090         {
1091           printk("DT3155: Freeing irq %d for device %d\n",
1092                   dt3155_status[index].irq, index);
1093           free_irq(dt3155_status[index].irq, (void*)&dt3155_status[index]);
1094         }
1095     }
1096 }
1097