diff options
Diffstat (limited to 'drivers/media/dvb/firewire/firedtv-iso.c')
-rw-r--r-- | drivers/media/dvb/firewire/firedtv-iso.c | 111 |
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 | |||
25 | static void rawiso_activity_cb(struct hpsb_iso *iso); | ||
26 | |||
27 | void 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 | |||
36 | int 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 | |||
59 | static 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 | |||