Linux/drivers/staging/b3dfg/b3dfg.c

  1  /*
  2  * Brontes PCI frame grabber driver
  3  *
  4  * Copyright (C) 2008 3M Company
  5  * Contact: Justin Bronder <jsbronder@brontes3d.com>
  6  * Original Authors: Daniel Drake <ddrake@brontes3d.com>
  7  *                   Duane Griffin <duaneg@dghda.com>
  8  *
  9  * This program is free software; you can redistribute it and/or modify
 10  * it under the terms of the GNU General Public License as published by
 11  * the Free Software Foundation; either version 2 of the License, or
 12  * (at your option) any later version.
 13  *
 14  * This program is distributed in the hope that it will be useful,
 15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 17  * GNU General Public License for more details.
 18  *
 19  * You should have received a copy of the GNU General Public License
 20  * along with this program; if not, write to the Free Software
 21  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 22  */
 23 
 24 #include <linux/device.h>
 25 #include <linux/fs.h>
 26 #include <linux/interrupt.h>
 27 #include <linux/spinlock.h>
 28 #include <linux/ioctl.h>
 29 #include <linux/kernel.h>
 30 #include <linux/module.h>
 31 #include <linux/pci.h>
 32 #include <linux/types.h>
 33 #include <linux/cdev.h>
 34 #include <linux/list.h>
 35 #include <linux/poll.h>
 36 #include <linux/wait.h>
 37 #include <linux/mm.h>
 38 #include <linux/uaccess.h>
 39 #include <linux/sched.h>
 40 
 41 static unsigned int b3dfg_nbuf = 2;
 42 
 43 module_param_named(buffer_count, b3dfg_nbuf, uint, 0444);
 44 
 45 MODULE_PARM_DESC(buffer_count, "Number of buffers (min 2, default 2)");
 46 
 47 MODULE_AUTHOR("Daniel Drake <ddrake@brontes3d.com>");
 48 MODULE_DESCRIPTION("Brontes frame grabber driver");
 49 MODULE_LICENSE("GPL");
 50 
 51 #define DRIVER_NAME "b3dfg"
 52 #define B3DFG_MAX_DEVS 4
 53 #define B3DFG_FRAMES_PER_BUFFER 3
 54 
 55 #define B3DFG_BAR_REGS  0
 56 #define B3DFG_REGS_LENGTH 0x10000
 57 
 58 #define B3DFG_IOC_MAGIC         0xb3 /* dfg :-) */
 59 #define B3DFG_IOCGFRMSZ         _IOR(B3DFG_IOC_MAGIC, 1, int)
 60 #define B3DFG_IOCTNUMBUFS       _IO(B3DFG_IOC_MAGIC, 2)
 61 #define B3DFG_IOCTTRANS         _IO(B3DFG_IOC_MAGIC, 3)
 62 #define B3DFG_IOCTQUEUEBUF      _IO(B3DFG_IOC_MAGIC, 4)
 63 #define B3DFG_IOCTPOLLBUF       _IOWR(B3DFG_IOC_MAGIC, 5, struct b3dfg_poll)
 64 #define B3DFG_IOCTWAITBUF       _IOWR(B3DFG_IOC_MAGIC, 6, struct b3dfg_wait)
 65 #define B3DFG_IOCGWANDSTAT      _IOR(B3DFG_IOC_MAGIC, 7, int)
 66 
 67 enum {
 68         /* number of 4kb pages per frame */
 69         B3D_REG_FRM_SIZE = 0x0,
 70 
 71         /* bit 0: set to enable interrupts
 72          * bit 1: set to enable cable status change interrupts */
 73         B3D_REG_HW_CTRL = 0x4,
 74 
 75         /* bit 0-1 - 1-based ID of next pending frame transfer (0 = none)
 76          * bit 2 indicates the previous DMA transfer has completed
 77          * bit 3 indicates wand cable status change
 78          * bit 8:15 - counter of number of discarded triplets */
 79         B3D_REG_DMA_STS = 0x8,
 80 
 81         /* bit 0: wand status (1 = present, 0 = disconnected) */
 82         B3D_REG_WAND_STS = 0xc,
 83 
 84         /* bus address for DMA transfers. lower 2 bits must be zero because DMA
 85          * works with 32 bit word size. */
 86         B3D_REG_EC220_DMA_ADDR = 0x8000,
 87 
 88         /* bit 20:0 - number of 32 bit words to be transferred
 89          * bit 21:31 - reserved */
 90         B3D_REG_EC220_TRF_SIZE = 0x8004,
 91 
 92         /* bit 0 - error bit
 93          * bit 1 - interrupt bit (set to generate interrupt at end of transfer)
 94          * bit 2 - start bit (set to start transfer)
 95          * bit 3 - direction (0 = DMA_TO_DEVICE, 1 = DMA_FROM_DEVICE
 96          * bit 4:31 - reserved */
 97         B3D_REG_EC220_DMA_STS = 0x8008,
 98 };
 99 
100 enum b3dfg_buffer_state {
101         B3DFG_BUFFER_POLLED = 0,
102         B3DFG_BUFFER_PENDING,
103         B3DFG_BUFFER_POPULATED,
104 };
105 
106 struct b3dfg_buffer {
107         unsigned char *frame[B3DFG_FRAMES_PER_BUFFER];
108         struct list_head list;
109         u8 state;
110 };
111 
112 struct b3dfg_dev {
113 
114         /* no protection needed: all finalized at initialization time */
115         struct pci_dev *pdev;
116         struct cdev chardev;
117         struct device *dev;
118         void __iomem *regs;
119         unsigned int frame_size;
120 
121         /*
122          * Protects buffer state, including buffer_queue, triplet_ready,
123          * cur_dma_frame_idx & cur_dma_frame_addr.
124          */
125         spinlock_t buffer_lock;
126         struct b3dfg_buffer *buffers;
127         struct list_head buffer_queue;
128 
129         /* Last frame in triplet transferred (-1 if none). */
130         int cur_dma_frame_idx;
131 
132         /* Current frame's address for DMA. */
133         dma_addr_t cur_dma_frame_addr;
134 
135         /*
136          * Protects cstate_tstamp.
137          * Nests inside buffer_lock.
138          */
139         spinlock_t cstate_lock;
140         unsigned long cstate_tstamp;
141 
142         /*
143          * Protects triplets_dropped.
144          * Nests inside buffers_lock.
145          */
146         spinlock_t triplets_dropped_lock;
147         unsigned int triplets_dropped;
148 
149         wait_queue_head_t buffer_waitqueue;
150 
151         unsigned int transmission_enabled:1;
152         unsigned int triplet_ready:1;
153 };
154 
155 static u8 b3dfg_devices[B3DFG_MAX_DEVS];
156 
157 static struct class *b3dfg_class;
158 static dev_t b3dfg_devt;
159 
160 static const struct pci_device_id b3dfg_ids[] __devinitdata = {
161         { PCI_DEVICE(0x0b3d, 0x0001) },
162         { },
163 };
164 
165 MODULE_DEVICE_TABLE(pci, b3dfg_ids);
166 
167 /***** user-visible types *****/
168 
169 struct b3dfg_poll {
170         int buffer_idx;
171         unsigned int triplets_dropped;
172 };
173 
174 struct b3dfg_wait {
175         int buffer_idx;
176         unsigned int timeout;
177         unsigned int triplets_dropped;
178 };
179 
180 /**** register I/O ****/
181 
182 static u32 b3dfg_read32(struct b3dfg_dev *fgdev, u16 reg)
183 {
184         return ioread32(fgdev->regs + reg);
185 }
186 
187 static void b3dfg_write32(struct b3dfg_dev *fgdev, u16 reg, u32 value)
188 {
189         iowrite32(value, fgdev->regs + reg);
190 }
191 
192 /**** buffer management ****/
193 
194 /*
195  * Program EC220 for transfer of a specific frame.
196  * Called with buffer_lock held.
197  */
198 static int setup_frame_transfer(struct b3dfg_dev *fgdev,
199         struct b3dfg_buffer *buf, int frame)
200 {
201         unsigned char *frm_addr;
202         dma_addr_t frm_addr_dma;
203         unsigned int frm_size = fgdev->frame_size;
204 
205         frm_addr = buf->frame[frame];
206         frm_addr_dma = pci_map_single(fgdev->pdev, frm_addr,
207                                           frm_size, PCI_DMA_FROMDEVICE);
208         if (pci_dma_mapping_error(fgdev->pdev, frm_addr_dma))
209                 return -ENOMEM;
210 
211         fgdev->cur_dma_frame_addr = frm_addr_dma;
212         fgdev->cur_dma_frame_idx = frame;
213 
214         b3dfg_write32(fgdev, B3D_REG_EC220_DMA_ADDR,
215                                         cpu_to_le32(frm_addr_dma));
216         b3dfg_write32(fgdev, B3D_REG_EC220_TRF_SIZE,
217                                         cpu_to_le32(frm_size >> 2));
218         b3dfg_write32(fgdev, B3D_REG_EC220_DMA_STS, 0xf);
219 
220         return 0;
221 }
222 
223 /* Caller should hold buffer lock */
224 static void dequeue_all_buffers(struct b3dfg_dev *fgdev)
225 {
226         int i;
227         for (i = 0; i < b3dfg_nbuf; i++) {
228                 struct b3dfg_buffer *buf = &fgdev->buffers[i];
229                 buf->state = B3DFG_BUFFER_POLLED;
230                 list_del_init(&buf->list);
231         }
232 }
233 
234 /* queue a buffer to receive data */
235 static int queue_buffer(struct b3dfg_dev *fgdev, int bufidx)
236 {
237         struct device *dev = &fgdev->pdev->dev;
238         struct b3dfg_buffer *buf;
239         unsigned long flags;
240         int r = 0;
241 
242         spin_lock_irqsave(&fgdev->buffer_lock, flags);
243         if (bufidx < 0 || bufidx >= b3dfg_nbuf) {
244                 dev_dbg(dev, "Invalid buffer index, %d\n", bufidx);
245                 r = -ENOENT;
246                 goto out;
247         }
248         buf = &fgdev->buffers[bufidx];
249 
250         if (unlikely(buf->state == B3DFG_BUFFER_PENDING)) {
251                 dev_dbg(dev, "buffer %d is already queued\n", bufidx);
252                 r = -EINVAL;
253                 goto out;
254         }
255 
256         buf->state = B3DFG_BUFFER_PENDING;
257         list_add_tail(&buf->list, &fgdev->buffer_queue);
258 
259         if (fgdev->transmission_enabled && fgdev->triplet_ready) {
260                 dev_dbg(dev, "triplet is ready, pushing immediately\n");
261                 fgdev->triplet_ready = 0;
262                 r = setup_frame_transfer(fgdev, buf, 0);
263                 if (r)
264                         dev_err(dev, "unable to map DMA buffer\n");
265         }
266 
267 out:
268         spin_unlock_irqrestore(&fgdev->buffer_lock, flags);
269         return r;
270 }
271 
272 /* non-blocking buffer poll. returns 1 if data is present in the buffer,
273  * 0 otherwise */
274 static int poll_buffer(struct b3dfg_dev *fgdev, void __user *arg)
275 {
276         struct device *dev = &fgdev->pdev->dev;
277         struct b3dfg_poll p;
278         struct b3dfg_buffer *buf;
279         unsigned long flags;
280         int r = 1;
281         int arg_out = 0;
282 
283         if (copy_from_user(&p, arg, sizeof(p)))
284                 return -EFAULT;
285 
286         if (unlikely(!fgdev->transmission_enabled)) {
287                 dev_dbg(dev, "cannot poll, transmission disabled\n");
288                 return -EINVAL;
289         }
290 
291         if (p.buffer_idx < 0 || p.buffer_idx >= b3dfg_nbuf)
292                 return -ENOENT;
293 
294         buf = &fgdev->buffers[p.buffer_idx];
295 
296         spin_lock_irqsave(&fgdev->buffer_lock, flags);
297 
298         if (likely(buf->state == B3DFG_BUFFER_POPULATED)) {
299                 arg_out = 1;
300                 buf->state = B3DFG_BUFFER_POLLED;
301 
302                 /* IRQs already disabled by spin_lock_irqsave above. */
303                 spin_lock(&fgdev->triplets_dropped_lock);
304                 p.triplets_dropped = fgdev->triplets_dropped;
305                 fgdev->triplets_dropped = 0;
306                 spin_unlock(&fgdev->triplets_dropped_lock);
307         } else {
308                 r = 0;
309         }
310 
311         spin_unlock_irqrestore(&fgdev->buffer_lock, flags);
312 
313         if (arg_out && copy_to_user(arg, &p, sizeof(p)))
314                 r = -EFAULT;
315 
316         return r;
317 }
318 
319 static unsigned long get_cstate_change(struct b3dfg_dev *fgdev)
320 {
321         unsigned long flags, when;
322 
323         spin_lock_irqsave(&fgdev->cstate_lock, flags);
324         when = fgdev->cstate_tstamp;
325         spin_unlock_irqrestore(&fgdev->cstate_lock, flags);
326         return when;
327 }
328 
329 static int is_event_ready(struct b3dfg_dev *fgdev, struct b3dfg_buffer *buf,
330                           unsigned long when)
331 {
332         int result;
333         unsigned long flags;
334 
335         spin_lock_irqsave(&fgdev->buffer_lock, flags);
336         spin_lock(&fgdev->cstate_lock);
337         result = (!fgdev->transmission_enabled ||
338                   buf->state == B3DFG_BUFFER_POPULATED ||
339                   when != fgdev->cstate_tstamp);
340         spin_unlock(&fgdev->cstate_lock);
341         spin_unlock_irqrestore(&fgdev->buffer_lock, flags);
342 
343         return result;
344 }
345 
346 /* sleep until a specific buffer becomes populated */
347 static int wait_buffer(struct b3dfg_dev *fgdev, void __user *arg)
348 {
349         struct device *dev = &fgdev->pdev->dev;
350         struct b3dfg_wait w;
351         struct b3dfg_buffer *buf;
352         unsigned long flags, when;
353         int r;
354 
355         if (copy_from_user(&w, arg, sizeof(w)))
356                 return -EFAULT;
357 
358         if (!fgdev->transmission_enabled) {
359                 dev_dbg(dev, "cannot wait, transmission disabled\n");
360                 return -EINVAL;
361         }
362 
363         if (w.buffer_idx < 0 || w.buffer_idx >= b3dfg_nbuf)
364                 return -ENOENT;
365 
366         buf = &fgdev->buffers[w.buffer_idx];
367 
368         spin_lock_irqsave(&fgdev->buffer_lock, flags);
369 
370         if (buf->state == B3DFG_BUFFER_POPULATED) {
371                 r = w.timeout;
372                 goto out_triplets_dropped;
373         }
374 
375         spin_unlock_irqrestore(&fgdev->buffer_lock, flags);
376 
377         when = get_cstate_change(fgdev);
378         if (w.timeout > 0) {
379                 r = wait_event_interruptible_timeout(fgdev->buffer_waitqueue,
380                         is_event_ready(fgdev, buf, when),
381                         (w.timeout * HZ) / 1000);
382 
383                 if (unlikely(r < 0))
384                         goto out;
385 
386                 w.timeout = r * 1000 / HZ;
387         } else {
388                 r = wait_event_interruptible(fgdev->buffer_waitqueue,
389                         is_event_ready(fgdev, buf, when));
390 
391                 if (unlikely(r)) {
392                         r = -ERESTARTSYS;
393                         goto out;
394                 }
395         }
396 
397         /* TODO: Inform the user via field(s) in w? */
398         if (!fgdev->transmission_enabled || when != get_cstate_change(fgdev)) {
399                 r = -EINVAL;
400                 goto out;
401         }
402 
403         spin_lock_irqsave(&fgdev->buffer_lock, flags);
404 
405         if (buf->state != B3DFG_BUFFER_POPULATED) {
406                 r = -ETIMEDOUT;
407                 goto out_unlock;
408         }
409 
410         buf->state = B3DFG_BUFFER_POLLED;
411 
412 out_triplets_dropped:
413 
414         /* IRQs already disabled by spin_lock_irqsave above. */
415         spin_lock(&fgdev->triplets_dropped_lock);
416         w.triplets_dropped = fgdev->triplets_dropped;
417         fgdev->triplets_dropped = 0;
418         spin_unlock(&fgdev->triplets_dropped_lock);
419 
420 out_unlock:
421         spin_unlock_irqrestore(&fgdev->buffer_lock, flags);
422         if (copy_to_user(arg, &w, sizeof(w)))
423                 r = -EFAULT;
424 out:
425         return r;
426 }
427 
428 /* mmap page fault handler */
429 static int b3dfg_vma_fault(struct vm_area_struct *vma,
430         struct vm_fault *vmf)
431 {
432         struct b3dfg_dev *fgdev = vma->vm_file->private_data;
433         unsigned long off = vmf->pgoff << PAGE_SHIFT;
434         unsigned int frame_size = fgdev->frame_size;
435         unsigned int buf_size = frame_size * B3DFG_FRAMES_PER_BUFFER;
436         unsigned char *addr;
437 
438         /* determine which buffer the offset lies within */
439         unsigned int buf_idx = off / buf_size;
440         /* and the offset into the buffer */
441         unsigned int buf_off = off % buf_size;
442 
443         /* determine which frame inside the buffer the offset lies in */
444         unsigned int frm_idx = buf_off / frame_size;
445         /* and the offset into the frame */
446         unsigned int frm_off = buf_off % frame_size;
447 
448         if (unlikely(buf_idx >= b3dfg_nbuf))
449                 return VM_FAULT_SIGBUS;
450 
451         addr = fgdev->buffers[buf_idx].frame[frm_idx] + frm_off;
452         vm_insert_pfn(vma, (unsigned long)vmf->virtual_address,
453                           virt_to_phys(addr) >> PAGE_SHIFT);
454 
455         return VM_FAULT_NOPAGE;
456 }
457 
458 static struct vm_operations_struct b3dfg_vm_ops = {
459         .fault = b3dfg_vma_fault,
460 };
461 
462 static int get_wand_status(struct b3dfg_dev *fgdev, int __user *arg)
463 {
464         u32 wndstat = b3dfg_read32(fgdev, B3D_REG_WAND_STS);
465         dev_dbg(&fgdev->pdev->dev, "wand status %x\n", wndstat);
466         return __put_user(wndstat & 0x1, arg);
467 }
468 
469 static int enable_transmission(struct b3dfg_dev *fgdev)
470 {
471         unsigned long flags;
472         struct device *dev = &fgdev->pdev->dev;
473 
474         dev_dbg(dev, "enable transmission\n");
475 
476         /* check the cable is plugged in. */
477         if (!b3dfg_read32(fgdev, B3D_REG_WAND_STS)) {
478                 dev_dbg(dev, "cannot start transmission without wand\n");
479                 return -EINVAL;
480         }
481 
482         spin_lock_irqsave(&fgdev->buffer_lock, flags);
483 
484         /* Handle racing enable_transmission calls. */
485         if (fgdev->transmission_enabled) {
486                 spin_unlock_irqrestore(&fgdev->buffer_lock, flags);
487                 goto out;
488         }
489 
490         spin_lock(&fgdev->triplets_dropped_lock);
491         fgdev->triplets_dropped = 0;
492         spin_unlock(&fgdev->triplets_dropped_lock);
493 
494         fgdev->triplet_ready = 0;
495         fgdev->cur_dma_frame_idx = -1;
496         fgdev->transmission_enabled = 1;
497 
498         spin_unlock_irqrestore(&fgdev->buffer_lock, flags);
499 
500         /* Enable DMA and cable status interrupts. */
501         b3dfg_write32(fgdev, B3D_REG_HW_CTRL, 0x03);
502 
503 out:
504         return 0;
505 }
506 
507 static void disable_transmission(struct b3dfg_dev *fgdev)
508 {
509         struct device *dev = &fgdev->pdev->dev;
510         unsigned long flags;
511         u32 tmp;
512 
513         dev_dbg(dev, "disable transmission\n");
514 
515         /* guarantee that no more interrupts will be serviced */
516         spin_lock_irqsave(&fgdev->buffer_lock, flags);
517         fgdev->transmission_enabled = 0;
518 
519         b3dfg_write32(fgdev, B3D_REG_HW_CTRL, 0);
520 
521         /* FIXME: temporary debugging only. if the board stops transmitting,
522          * hitting ctrl+c and seeing this message is useful for determining
523          * the state of the board. */
524         tmp = b3dfg_read32(fgdev, B3D_REG_DMA_STS);
525         dev_dbg(dev, "DMA_STS reads %x after TX stopped\n", tmp);
526 
527         dequeue_all_buffers(fgdev);
528         spin_unlock_irqrestore(&fgdev->buffer_lock, flags);
529 
530         wake_up_interruptible(&fgdev->buffer_waitqueue);
531 }
532 
533 static int set_transmission(struct b3dfg_dev *fgdev, int enabled)
534 {
535         int res = 0;
536 
537         if (enabled && !fgdev->transmission_enabled)
538                 res = enable_transmission(fgdev);
539         else if (!enabled && fgdev->transmission_enabled)
540                 disable_transmission(fgdev);
541 
542         return res;
543 }
544 
545 /* Called in interrupt context. */
546 static void handle_cstate_unplug(struct b3dfg_dev *fgdev)
547 {
548         /* Disable all interrupts. */
549         b3dfg_write32(fgdev, B3D_REG_HW_CTRL, 0);
550 
551         /* Stop transmission. */
552         spin_lock(&fgdev->buffer_lock);
553         fgdev->transmission_enabled = 0;
554 
555         fgdev->cur_dma_frame_idx = -1;
556         fgdev->triplet_ready = 0;
557         if (fgdev->cur_dma_frame_addr) {
558                 pci_unmap_single(fgdev->pdev, fgdev->cur_dma_frame_addr,
559                                  fgdev->frame_size, PCI_DMA_FROMDEVICE);
560                 fgdev->cur_dma_frame_addr = 0;
561         }
562         dequeue_all_buffers(fgdev);
563         spin_unlock(&fgdev->buffer_lock);
564 }
565 
566 /* Called in interrupt context. */
567 static void handle_cstate_change(struct b3dfg_dev *fgdev)
568 {
569         u32 cstate = b3dfg_read32(fgdev, B3D_REG_WAND_STS);
570         unsigned long when;
571         struct device *dev = &fgdev->pdev->dev;
572 
573         dev_dbg(dev, "cable state change: %u\n", cstate);
574 
575         /*
576          * When the wand is unplugged we reset our state. The hardware will
577          * have done the same internally.
578          *
579          * Note we should never see a cable *plugged* event, as interrupts
580          * should only be enabled when transmitting, which requires the cable
581          * to be plugged. If we do see one it probably means the cable has been
582          * unplugged and re-plugged very rapidly. Possibly because it has a
583          * broken wire and is momentarily losing contact.
584          *
585          * TODO: At the moment if you plug in the cable then enable transmission
586          * the hardware will raise a couple of spurious interrupts, so
587          * just ignore them for now.
588          *
589          * Once the hardware is fixed we should complain and treat it as an
590          * unplug. Or at least track how frequently it is happening and do
591          * so if too many come in.
592          */
593         if (cstate) {
594                 dev_warn(dev, "ignoring unexpected plug event\n");
595                 return;
596         }
597         handle_cstate_unplug(fgdev);
598 
599         /*
600          * Record cable state change timestamp & wake anyone waiting
601          * on a cable state change. Be paranoid about ensuring events
602          * are not missed if we somehow get two interrupts in a jiffy.
603          */
604         spin_lock(&fgdev->cstate_lock);
605         when = jiffies_64;
606         if (when <= fgdev->cstate_tstamp)
607                 when = fgdev->cstate_tstamp + 1;
608         fgdev->cstate_tstamp = when;
609         wake_up_interruptible(&fgdev->buffer_waitqueue);
610         spin_unlock(&fgdev->cstate_lock);
611 }
612 
613 /* Called with buffer_lock held. */
614 static void transfer_complete(struct b3dfg_dev *fgdev)
615 {
616         struct b3dfg_buffer *buf;
617         struct device *dev = &fgdev->pdev->dev;
618 
619         pci_unmap_single(fgdev->pdev, fgdev->cur_dma_frame_addr,
620                          fgdev->frame_size, PCI_DMA_FROMDEVICE);
621         fgdev->cur_dma_frame_addr = 0;
622 
623         buf = list_entry(fgdev->buffer_queue.next, struct b3dfg_buffer, list);
624 
625         dev_dbg(dev, "handle frame completion\n");
626         if (fgdev->cur_dma_frame_idx == B3DFG_FRAMES_PER_BUFFER - 1) {
627 
628                 /* last frame of that triplet completed */
629                 dev_dbg(dev, "triplet completed\n");
630                 buf->state = B3DFG_BUFFER_POPULATED;
631                 list_del_init(&buf->list);
632                 wake_up_interruptible(&fgdev->buffer_waitqueue);
633         }
634 }
635 
636 /*
637  * Called with buffer_lock held.
638  *
639  * Note that idx is the (1-based) *next* frame to be transferred, while
640  * cur_dma_frame_idx is the (0-based) *last* frame to have been transferred (or
641  * -1 if none). Thus there should be a difference of 2 between them.
642  */
643 static bool setup_next_frame_transfer(struct b3dfg_dev *fgdev, int idx)
644 {
645         struct b3dfg_buffer *buf;
646         struct device *dev = &fgdev->pdev->dev;
647         bool need_ack = 1;
648 
649         dev_dbg(dev, "program DMA transfer for next frame: %d\n", idx);
650 
651         buf = list_entry(fgdev->buffer_queue.next, struct b3dfg_buffer, list);
652         if (idx == fgdev->cur_dma_frame_idx + 2) {
653                 if (setup_frame_transfer(fgdev, buf, idx - 1))
654                         dev_err(dev, "unable to map DMA buffer\n");
655                 need_ack = 0;
656         } else {
657                 dev_err(dev, "frame mismatch, got %d, expected %d\n",
658                         idx, fgdev->cur_dma_frame_idx + 2);
659 
660                 /* FIXME: handle dropped triplets here */
661         }
662 
663         return need_ack;
664 }
665 
666 static irqreturn_t b3dfg_intr(int irq, void *dev_id)
667 {
668         struct b3dfg_dev *fgdev = dev_id;
669         struct device *dev = &fgdev->pdev->dev;
670         u32 sts;
671         u8 dropped;
672         bool need_ack = 1;
673         irqreturn_t res = IRQ_HANDLED;
674 
675         sts = b3dfg_read32(fgdev, B3D_REG_DMA_STS);
676         if (unlikely(sts == 0)) {
677                 dev_warn(dev, "ignore interrupt, DMA status is 0\n");
678                 res = IRQ_NONE;
679                 goto out;
680         }
681 
682         if (unlikely(!fgdev->transmission_enabled)) {
683                 dev_warn(dev, "ignore interrupt, TX disabled\n");
684                 res = IRQ_HANDLED;
685                 goto out;
686         }
687 
688         /* Handle dropped frames, as reported by the hardware. */
689         dropped = (sts >> 8) & 0xff;
690         dev_dbg(dev, "intr: DMA_STS=%08x (drop=%d comp=%d next=%d)\n",
691                 sts, dropped, !!(sts & 0x4), sts & 0x3);
692         if (unlikely(dropped > 0)) {
693                 spin_lock(&fgdev->triplets_dropped_lock);
694                 fgdev->triplets_dropped += dropped;
695                 spin_unlock(&fgdev->triplets_dropped_lock);
696         }
697 
698         /* Handle a cable state change (i.e. the wand being unplugged). */
699         if (sts & 0x08) {
700                 handle_cstate_change(fgdev);
701                 goto out;
702         }
703 
704         spin_lock(&fgdev->buffer_lock);
705         if (unlikely(list_empty(&fgdev->buffer_queue))) {
706 
707                 /* FIXME need more sanity checking here */
708                 dev_info(dev, "buffer not ready for next transfer\n");
709                 fgdev->triplet_ready = 1;
710                 goto out_unlock;
711         }
712 
713         /* Has a frame transfer been completed? */
714         if (sts & 0x4) {
715                 u32 dma_status = b3dfg_read32(fgdev, B3D_REG_EC220_DMA_STS);
716 
717                 /* Check for DMA errors reported by the hardware. */
718                 if (unlikely(dma_status & 0x1)) {
719                         dev_err(dev, "EC220 error: %08x\n", dma_status);
720 
721                         /* FIXME flesh out error handling */
722                         goto out_unlock;
723                 }
724 
725                 /* Sanity check, we should have a frame index at this point. */
726                 if (unlikely(fgdev->cur_dma_frame_idx == -1)) {
727                         dev_err(dev, "completed but no last idx?\n");
728 
729                         /* FIXME flesh out error handling */
730                         goto out_unlock;
731                 }
732 
733                 transfer_complete(fgdev);
734         }
735 
736         /* Is there another frame transfer pending? */
737         if (sts & 0x3)
738                 need_ack = setup_next_frame_transfer(fgdev, sts & 0x3);
739         else
740                 fgdev->cur_dma_frame_idx = -1;
741 
742 out_unlock:
743         spin_unlock(&fgdev->buffer_lock);
744 out:
745         if (need_ack) {
746                 dev_dbg(dev, "acknowledging interrupt\n");
747                 b3dfg_write32(fgdev, B3D_REG_EC220_DMA_STS, 0x0b);
748         }
749         return res;
750 }
751 
752 static int b3dfg_open(struct inode *inode, struct file *filp)
753 {
754         struct b3dfg_dev *fgdev =
755                 container_of(inode->i_cdev, struct b3dfg_dev, chardev);
756 
757         dev_dbg(&fgdev->pdev->dev, "open\n");
758         filp->private_data = fgdev;
759         return 0;
760 }
761 
762 static int b3dfg_release(struct inode *inode, struct file *filp)
763 {
764         struct b3dfg_dev *fgdev = filp->private_data;
765         dev_dbg(&fgdev->pdev->dev, "release\n");
766         disable_transmission(fgdev);
767         return 0;
768 }
769 
770 static long b3dfg_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
771 {
772         struct b3dfg_dev *fgdev = filp->private_data;
773 
774         switch (cmd) {
775         case B3DFG_IOCGFRMSZ:
776                 return __put_user(fgdev->frame_size, (int __user *) arg);
777         case B3DFG_IOCGWANDSTAT:
778                 return get_wand_status(fgdev, (int __user *) arg);
779         case B3DFG_IOCTTRANS:
780                 return set_transmission(fgdev, (int) arg);
781         case B3DFG_IOCTQUEUEBUF:
782                 return queue_buffer(fgdev, (int) arg);
783         case B3DFG_IOCTPOLLBUF:
784                 return poll_buffer(fgdev, (void __user *) arg);
785         case B3DFG_IOCTWAITBUF:
786                 return wait_buffer(fgdev, (void __user *) arg);
787         default:
788                 dev_dbg(&fgdev->pdev->dev, "unrecognised ioctl %x\n", cmd);
789                 return -EINVAL;
790         }
791 }
792 
793 static unsigned int b3dfg_poll(struct file *filp, poll_table *poll_table)
794 {
795         struct b3dfg_dev *fgdev = filp->private_data;
796         unsigned long flags, when;
797         int i;
798         int r = 0;
799 
800         when = get_cstate_change(fgdev);
801         poll_wait(filp, &fgdev->buffer_waitqueue, poll_table);
802 
803         spin_lock_irqsave(&fgdev->buffer_lock, flags);
804         for (i = 0; i < b3dfg_nbuf; i++) {
805                 if (fgdev->buffers[i].state == B3DFG_BUFFER_POPULATED) {
806                         r = POLLIN | POLLRDNORM;
807                         break;
808                 }
809         }
810         spin_unlock_irqrestore(&fgdev->buffer_lock, flags);
811 
812         /* TODO: Confirm this is how we want to communicate the change. */
813         if (!fgdev->transmission_enabled || when != get_cstate_change(fgdev))
814                 r = POLLERR;
815 
816         return r;
817 }
818 
819 static int b3dfg_mmap(struct file *filp, struct vm_area_struct *vma)
820 {
821         struct b3dfg_dev *fgdev = filp->private_data;
822         unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
823         unsigned long vsize = vma->vm_end - vma->vm_start;
824         unsigned long bufdatalen = b3dfg_nbuf * fgdev->frame_size * 3;
825         unsigned long psize = bufdatalen - offset;
826         int r = 0;
827 
828         if (vsize <= psize) {
829                 vma->vm_flags |= VM_IO | VM_RESERVED | VM_CAN_NONLINEAR |
830                                  VM_PFNMAP;
831                 vma->vm_ops = &b3dfg_vm_ops;
832         } else {
833                 r = -EINVAL;
834         }
835 
836         return r;
837 }
838 
839 static struct file_operations b3dfg_fops = {
840         .owner = THIS_MODULE,
841         .open = b3dfg_open,
842         .release = b3dfg_release,
843         .unlocked_ioctl = b3dfg_ioctl,
844         .poll = b3dfg_poll,
845         .mmap = b3dfg_mmap,
846 };
847 
848 static void free_all_frame_buffers(struct b3dfg_dev *fgdev)
849 {
850         int i, j;
851         for (i = 0; i < b3dfg_nbuf; i++)
852                 for (j = 0; j < B3DFG_FRAMES_PER_BUFFER; j++)
853                         kfree(fgdev->buffers[i].frame[j]);
854         kfree(fgdev->buffers);
855 }
856 
857 /* initialize device and any data structures. called before any interrupts
858  * are enabled. */
859 static int b3dfg_init_dev(struct b3dfg_dev *fgdev)
860 {
861         int i, j;
862         u32 frm_size = b3dfg_read32(fgdev, B3D_REG_FRM_SIZE);
863 
864         /* Disable interrupts. In abnormal circumstances (e.g. after a crash)
865          * the board may still be transmitting from the previous session. If we
866          * ensure that interrupts are disabled before we later enable them, we
867          * are sure to capture a triplet from the start, rather than starting
868          * from frame 2 or 3. Disabling interrupts causes the FG to throw away
869          * all buffered data and stop buffering more until interrupts are
870          * enabled again.
871          */
872         b3dfg_write32(fgdev, B3D_REG_HW_CTRL, 0);
873 
874         fgdev->frame_size = frm_size * 4096;
875         fgdev->buffers = kzalloc(sizeof(struct b3dfg_buffer) * b3dfg_nbuf,
876                                  GFP_KERNEL);
877         if (!fgdev->buffers)
878                 goto err_no_buf;
879         for (i = 0; i < b3dfg_nbuf; i++) {
880                 struct b3dfg_buffer *buf = &fgdev->buffers[i];
881                 for (j = 0; j < B3DFG_FRAMES_PER_BUFFER; j++) {
882                         buf->frame[j] = kmalloc(fgdev->frame_size, GFP_KERNEL);
883                         if (!buf->frame[j])
884                                 goto err_no_mem;
885                 }
886                 INIT_LIST_HEAD(&buf->list);
887         }
888 
889         INIT_LIST_HEAD(&fgdev->buffer_queue);
890         init_waitqueue_head(&fgdev->buffer_waitqueue);
891         spin_lock_init(&fgdev->buffer_lock);
892         spin_lock_init(&fgdev->cstate_lock);
893         spin_lock_init(&fgdev->triplets_dropped_lock);
894         return 0;
895 
896 err_no_mem:
897         free_all_frame_buffers(fgdev);
898 err_no_buf:
899         return -ENOMEM;
900 }
901 
902 /* find next free minor number, returns -1 if none are availabile */
903 static int get_free_minor(void)
904 {
905         int i;
906         for (i = 0; i < B3DFG_MAX_DEVS; i++) {
907                 if (b3dfg_devices[i] == 0)
908                         return i;
909         }
910         return -1;
911 }
912 
913 static int __devinit b3dfg_probe(struct pci_dev *pdev,
914         const struct pci_device_id *id)
915 {
916         struct b3dfg_dev *fgdev = kzalloc(sizeof(*fgdev), GFP_KERNEL);
917         int r = 0;
918         int minor = get_free_minor();
919         dev_t devno = MKDEV(MAJOR(b3dfg_devt), minor);
920         unsigned long res_len;
921         resource_size_t res_base;
922 
923         if (fgdev == NULL)
924                 return -ENOMEM;
925 
926         if (minor < 0) {
927                 dev_err(&pdev->dev, "too many devices found!\n");
928                 r = -EIO;
929                 goto err_free;
930         }
931 
932         b3dfg_devices[minor] = 1;
933         dev_info(&pdev->dev, "probe device with IRQ %d\n", pdev->irq);
934 
935         cdev_init(&fgdev->chardev, &b3dfg_fops);
936         fgdev->chardev.owner = THIS_MODULE;
937 
938         r = cdev_add(&fgdev->chardev, devno, 1);
939         if (r) {
940                 dev_err(&pdev->dev, "cannot add char device\n");
941                 goto err_release_minor;
942         }
943 
944         fgdev->dev = device_create(
945                 b3dfg_class,
946                 &pdev->dev,
947                 devno,
948                 dev_get_drvdata(&pdev->dev),
949                 DRIVER_NAME "%d", minor);
950 
951         if (IS_ERR(fgdev->dev)) {
952                 dev_err(&pdev->dev, "cannot create device\n");
953                 r = PTR_ERR(fgdev->dev);
954                 goto err_del_cdev;
955         }
956 
957         r = pci_enable_device(pdev);
958         if (r) {
959                 dev_err(&pdev->dev, "cannot enable PCI device\n");
960                 goto err_dev_unreg;
961         }
962 
963         res_len = pci_resource_len(pdev, B3DFG_BAR_REGS);
964         if (res_len != B3DFG_REGS_LENGTH) {
965                 dev_err(&pdev->dev, "invalid register resource size\n");
966                 r = -EIO;
967                 goto err_disable;
968         }
969 
970         if (pci_resource_flags(pdev, B3DFG_BAR_REGS)
971                                 != (IORESOURCE_MEM | IORESOURCE_SIZEALIGN)) {
972                 dev_err(&pdev->dev, "invalid resource flags\n");
973                 r = -EIO;
974                 goto err_disable;
975         }
976         r = pci_request_regions(pdev, DRIVER_NAME);
977         if (r) {
978                 dev_err(&pdev->dev, "cannot obtain PCI resources\n");
979                 goto err_disable;
980         }
981 
982         pci_set_master(pdev);
983 
984         r = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
985         if (r) {
986                 dev_err(&pdev->dev, "no usable DMA configuration\n");
987                 goto err_free_res;
988         }
989 
990         res_base = pci_resource_start(pdev, B3DFG_BAR_REGS);
991         fgdev->regs = ioremap_nocache(res_base, res_len);
992         if (!fgdev->regs) {
993                 dev_err(&pdev->dev, "regs ioremap failed\n");
994                 r = -EIO;
995                 goto err_free_res;
996         }
997 
998         fgdev->pdev = pdev;
999         pci_set_drvdata(pdev, fgdev);
1000         r = b3dfg_init_dev(fgdev);
1001         if (r < 0) {
1002                 dev_err(&pdev->dev, "failed to initalize device\n");
1003                 goto err_unmap;
1004         }
1005 
1006         r = request_irq(pdev->irq, b3dfg_intr, IRQF_SHARED, DRIVER_NAME, fgdev);
1007         if (r) {
1008                 dev_err(&pdev->dev, "couldn't request irq %d\n", pdev->irq);
1009                 goto err_free_bufs;
1010         }
1011 
1012         return 0;
1013 
1014 err_free_bufs:
1015         free_all_frame_buffers(fgdev);
1016 err_unmap:
1017         iounmap(fgdev->regs);
1018 err_free_res:
1019         pci_release_regions(pdev);
1020 err_disable:
1021         pci_disable_device(pdev);
1022 err_dev_unreg:
1023         device_destroy(b3dfg_class, devno);
1024 err_del_cdev:
1025         cdev_del(&fgdev->chardev);
1026 err_release_minor:
1027         b3dfg_devices[minor] = 0;
1028 err_free:
1029         kfree(fgdev);
1030         return r;
1031 }
1032 
1033 static void __devexit b3dfg_remove(struct pci_dev *pdev)
1034 {
1035         struct b3dfg_dev *fgdev = pci_get_drvdata(pdev);
1036         unsigned int minor = MINOR(fgdev->chardev.dev);
1037 
1038         dev_dbg(&pdev->dev, "remove\n");
1039 
1040         free_irq(pdev->irq, fgdev);
1041         iounmap(fgdev->regs);
1042         pci_release_regions(pdev);
1043         pci_disable_device(pdev);
1044         device_destroy(b3dfg_class, MKDEV(MAJOR(b3dfg_devt), minor));
1045         cdev_del(&fgdev->chardev);
1046         free_all_frame_buffers(fgdev);
1047         kfree(fgdev);
1048         b3dfg_devices[minor] = 0;
1049 }
1050 
1051 static struct pci_driver b3dfg_driver = {
1052         .name = DRIVER_NAME,
1053         .id_table = b3dfg_ids,
1054         .probe = b3dfg_probe,
1055         .remove = __devexit_p(b3dfg_remove),
1056 };
1057 
1058 static int __init b3dfg_module_init(void)
1059 {
1060         int r;
1061 
1062         if (b3dfg_nbuf < 2) {
1063                 printk(KERN_ERR DRIVER_NAME
1064                            ": buffer_count is out of range (must be >= 2)");
1065                 return -EINVAL;
1066         }
1067 
1068         printk(KERN_INFO DRIVER_NAME ": loaded\n");
1069 
1070         b3dfg_class = class_create(THIS_MODULE, DRIVER_NAME);
1071         if (IS_ERR(b3dfg_class))
1072                 return PTR_ERR(b3dfg_class);
1073 
1074         r = alloc_chrdev_region(&b3dfg_devt, 0, B3DFG_MAX_DEVS, DRIVER_NAME);
1075         if (r)
1076                 goto err1;
1077 
1078         r = pci_register_driver(&b3dfg_driver);
1079         if (r)
1080                 goto err2;
1081 
1082         return r;
1083 
1084 err2:
1085         unregister_chrdev_region(b3dfg_devt, B3DFG_MAX_DEVS);
1086 err1:
1087         class_destroy(b3dfg_class);
1088         return r;
1089 }
1090 
1091 static void __exit b3dfg_module_exit(void)
1092 {
1093         printk(KERN_INFO DRIVER_NAME ": unloaded\n");
1094         pci_unregister_driver(&b3dfg_driver);
1095         unregister_chrdev_region(b3dfg_devt, B3DFG_MAX_DEVS);
1096         class_destroy(b3dfg_class);
1097 }
1098 
1099 module_init(b3dfg_module_init);
1100 module_exit(b3dfg_module_exit);
1101 

This page was automatically generated by LXR 0.3.1.  •  Linux is a registered trademark of Linus Torvalds