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