aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/dvb/firewire/firedtv-iso.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/dvb/firewire/firedtv-iso.c')
-rw-r--r--drivers/media/dvb/firewire/firedtv-iso.c111
1 files changed, 111 insertions, 0 deletions
diff --git a/drivers/media/dvb/firewire/firedtv-iso.c b/drivers/media/dvb/firewire/firedtv-iso.c
new file mode 100644
index 000000000000..a72df228e7de
--- /dev/null
+++ b/drivers/media/dvb/firewire/firedtv-iso.c
@@ -0,0 +1,111 @@
1/*
2 * FireSAT DVB driver
3 *
4 * Copyright (C) 2008 Henrik Kurelid <henrik@kurelid.se>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation; either version 2 of
9 * the License, or (at your option) any later version.
10 */
11
12#include <linux/errno.h>
13#include <linux/kernel.h>
14#include <linux/list.h>
15#include <linux/spinlock.h>
16
17#include <dvb_demux.h>
18
19#include <dma.h>
20#include <iso.h>
21#include <nodemgr.h>
22
23#include "firedtv.h"
24
25static void rawiso_activity_cb(struct hpsb_iso *iso);
26
27void tear_down_iso_channel(struct firedtv *fdtv)
28{
29 if (fdtv->iso_handle != NULL) {
30 hpsb_iso_stop(fdtv->iso_handle);
31 hpsb_iso_shutdown(fdtv->iso_handle);
32 }
33 fdtv->iso_handle = NULL;
34}
35
36int setup_iso_channel(struct firedtv *fdtv)
37{
38 int result;
39 fdtv->iso_handle =
40 hpsb_iso_recv_init(fdtv->ud->ne->host,
41 256 * 200, //data_buf_size,
42 256, //buf_packets,
43 fdtv->isochannel,
44 HPSB_ISO_DMA_DEFAULT, //dma_mode,
45 -1, //stat.config.irq_interval,
46 rawiso_activity_cb);
47 if (fdtv->iso_handle == NULL) {
48 printk(KERN_ERR "Cannot initialize iso receive.\n");
49 return -EINVAL;
50 }
51 result = hpsb_iso_recv_start(fdtv->iso_handle, -1, -1, 0);
52 if (result != 0) {
53 printk(KERN_ERR "Cannot start iso receive.\n");
54 return -EINVAL;
55 }
56 return 0;
57}
58
59static void rawiso_activity_cb(struct hpsb_iso *iso)
60{
61 unsigned int num;
62 unsigned int i;
63 unsigned int packet;
64 unsigned long flags;
65 struct firedtv *fdtv = NULL;
66 struct firedtv *fdtv_iterator;
67
68 spin_lock_irqsave(&fdtv_list_lock, flags);
69 list_for_each_entry(fdtv_iterator, &fdtv_list, list) {
70 if(fdtv_iterator->iso_handle == iso) {
71 fdtv = fdtv_iterator;
72 break;
73 }
74 }
75 spin_unlock_irqrestore(&fdtv_list_lock, flags);
76
77 if (fdtv) {
78 packet = iso->first_packet;
79 num = hpsb_iso_n_ready(iso);
80 for (i = 0; i < num; i++,
81 packet = (packet + 1) % iso->buf_packets) {
82 unsigned char *buf =
83 dma_region_i(&iso->data_buf, unsigned char,
84 iso->infos[packet].offset +
85 sizeof(struct CIPHeader));
86 int count = (iso->infos[packet].len -
87 sizeof(struct CIPHeader)) /
88 (188 + sizeof(struct firewireheader));
89 if (iso->infos[packet].len <= sizeof(struct CIPHeader))
90 continue; // ignore empty packet
91
92 while (count --) {
93 if (buf[sizeof(struct firewireheader)] == 0x47)
94 dvb_dmx_swfilter_packets(&fdtv->demux,
95 &buf[sizeof(struct firewireheader)], 1);
96 else
97 printk("%s: invalid packet, skipping\n", __func__);
98 buf += 188 + sizeof(struct firewireheader);
99
100 }
101
102 }
103 hpsb_iso_recv_release_packets(iso, num);
104 }
105 else {
106 printk("%s: packets for unknown iso channel, skipping\n",
107 __func__);
108 hpsb_iso_recv_release_packets(iso, hpsb_iso_n_ready(iso));
109 }
110}
111