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