aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/dvb/firewire/firedtv-dvb.c
diff options
context:
space:
mode:
authorStefan Richter <stefanr@s5r6.in-berlin.de>2009-02-23 08:21:10 -0500
committerStefan Richter <stefanr@s5r6.in-berlin.de>2009-02-24 08:51:29 -0500
commit154907957f9391b1af997b57507b16c018cc4995 (patch)
treef9033e7dc29d5406e871b8102ba0b588d34b50ec /drivers/media/dvb/firewire/firedtv-dvb.c
parenta70f81c1c0dac113ac4705e7701e2676e67905cd (diff)
firedtv: massive refactoring
Combination of the following changes: Mon, 23 Feb 2009 14:21:10 +0100 (CET) firedtv: reinstate debug logging option Henrik Kurelid tells me that FCP debug logging (which I removed during cleanups) is still useful when working on driver issues together with end users. So bring it back in an updated form with only 60% of the original code footprint. Logging can be enabled with # echo -1 > /sys/module/firedtv/parameters/debug 1 instead of -1 enables only FCP header logging, 2 instead of -1 enables only hexdumps of the entire FCP frames. 0 switches logging off again. Fri, 20 Feb 2009 20:54:27 +0100 (CET) firedtv: build fix for INPUT=m and DVB_FIREDTV=y Thu, 19 Feb 2009 20:40:39 +0100 firedtv: use msecs_to_jiffies Pointed out by Mauro Carvalho Chehab. Sun Feb 15 20:50:46 CET 2009 firedtv: some more housekeeping Fix an old checkpatch warning and a new compiler warning. Sun Feb 15 15:33:17 CET 2009 firedtv: rename a file once more At the moment, about a third of avc.c is specific to FireDTVs rather than generic AV/C code. Rename it to firedtv-avc.c. Sun Feb 15 15:33:17 CET 2009 firedtv: dvb demux: more compact channels backing store Replace struct firedtv_channel { bool active; int pid; } channel[16]; by unsigned long channel_active; u16 channel_pid[16];. Sun Feb 15 15:33:17 CET 2009 firedtv: dvb demux: some simplifications c->active was unnecessarily cleared twice. Also, by marking the channel inactive before the for loop, the loop becomes identical with fdtv_channel_collect(). Sun Feb 15 15:33:17 CET 2009 firedtv: dvb demux: remove a bogus loop This loop is unnecessary because - only active channel[].pid's will be sent to the device, - when a channel is activated, its pid is set to dvbdmxfeed->pid. Perhaps the original code was there because it was initially not fully covered by the fdtv->demux_mutex. Sun Feb 15 15:33:17 CET 2009 firedtv: dvb demux: fix mutex protection fdtv_start_feed() accessed the channel list unsafely. Fully serialize it with itself and fdtv_stop_feed(). Sun Feb 15 15:33:17 CET 2009 firedtv: dvb demux: fix missing braces Original code was: ... case DMX_TS_PES_OTHER: //Dirty fix to keep firesat->channel pid-list up to date for(k=0;k<16;k++){ if(firesat->channel[k].active == 0) firesat->channel[k].pid = dvbdmxfeed->pid; break; } channel = firesat_channel_allocate(firesat); break; default: ... Looks bogus in several respects. For now let's just add braces to the if because that seems to be what the author meant. Sun Feb 15 15:33:17 CET 2009 firedtv: allow build without input subsystem !CONFIG_INPUT is very unlikely on systems on which firedtv is of interest. But we can easily support it. Sun Feb 15 15:33:17 CET 2009 firedtv: replace EXTRA_CFLAGS by ccflags The former are deprecated. The latter can depend on Kconfig variables. Sun Feb 15 15:33:17 CET 2009 firedtv: concentrate ieee1394 dependencies Move the entire interface with drivers/ieee1394 to firedtv-1394.c. Move 1394-independent module initialization code to firedtv-dvb.c. This prepares interfacing with drivers/firewire. Sun Feb 15 15:33:17 CET 2009 firedtv: amend Kconfig menu prompt Sun Feb 15 15:33:17 CET 2009 firedtv: remove kernel version compatibility macro Sun Feb 15 15:33:17 CET 2009 firedtv: combine header files avc.h and firedtv-*.h are small and currently not shared with other drivers, hence concatenate them all into firedtv.h. Sun Feb 15 15:33:17 CET 2009 firedtv: misc style touch-ups Standardize on lower-case hexadecimal constants. Adjust whitespace. Omit unnecessary pointer type casts and an unnecessary list head initialization. Use dev_printk. Wed Feb 11 21:21:04 CET 2009 firedtv: avc, ci: remove unused constants Wed Feb 11 21:21:04 CET 2009 firedtv: avc: remove bitfields from read descriptor response operands Don't use bitfields in struct types of on-the-wire data. Wed Feb 11 21:21:04 CET 2009 firedtv: avc: remove bitfields from DSD command operands Don't use bitfields in struct types of on-the-wire data. Wed Feb 11 21:21:04 CET 2009 firedtv: avc: header file cleanup Remove unused constants and declarations. Move privately used constants into .c files. Wed Feb 11 21:21:04 CET 2009 firedtv: avc: remove bitfields from FCP frame types Don't use bitfields in struct types of on-the-wire data. Also move many privately used constants from avc.h to avc.c and remove some unused constants. Sun, 18 Jan 2009 16:30:00 +0100 (CET) firedtv: avc: fix offset in avc_tuner_get_ts The parentheses were wrong. It didn't matter though because this code only writes a 0 into an area which is already initialized to 0. Sun, 18 Jan 2009 16:30:00 +0100 (CET) firedtv: avc: reduce stack usage, remove two typedefs It is safe to share a memory buffer for command frame and response frame because the response data come in after the command frame was last used. Even less stack would be required if only the actual required frame size instead of the entire FCP register size was allocated. Also, rename the defined types AVCCmdFrm and AVCRspFrm to struct avc_command_frame and struct avc_response_frame. TODO: Remove the bitfields in these types. Sun, 18 Jan 2009 16:30:00 +0100 (CET) firedtv: cmp: move code to avc Sun, 18 Jan 2009 16:30:00 +0100 (CET) firedtv: iso: move code to firedtv-1394 Sun, 18 Jan 2009 16:30:00 +0100 (CET) firedtv: iso: remove unnecessary struct type definitions Sun, 18 Jan 2009 16:30:00 +0100 (CET) firedtv: iso: style changes and fixlets Add cleanup after failure in setup_iso_channel. Replace printk() by dv_err(). Decrease indentation level in rawiso_activity_cb(). Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
Diffstat (limited to 'drivers/media/dvb/firewire/firedtv-dvb.c')
-rw-r--r--drivers/media/dvb/firewire/firedtv-dvb.c328
1 files changed, 208 insertions, 120 deletions
diff --git a/drivers/media/dvb/firewire/firedtv-dvb.c b/drivers/media/dvb/firewire/firedtv-dvb.c
index 1823058696f2..9d308dd32a5c 100644
--- a/drivers/media/dvb/firewire/firedtv-dvb.c
+++ b/drivers/media/dvb/firewire/firedtv-dvb.c
@@ -10,75 +10,55 @@
10 * the License, or (at your option) any later version. 10 * the License, or (at your option) any later version.
11 */ 11 */
12 12
13#include <linux/bitops.h>
14#include <linux/device.h>
13#include <linux/errno.h> 15#include <linux/errno.h>
14#include <linux/kernel.h> 16#include <linux/kernel.h>
17#include <linux/mod_devicetable.h>
18#include <linux/module.h>
15#include <linux/mutex.h> 19#include <linux/mutex.h>
20#include <linux/slab.h>
21#include <linux/string.h>
16#include <linux/types.h> 22#include <linux/types.h>
23#include <linux/wait.h>
24#include <linux/workqueue.h>
17 25
26#include <dmxdev.h>
18#include <dvb_demux.h> 27#include <dvb_demux.h>
19#include <dvb_frontend.h>
20#include <dvbdev.h> 28#include <dvbdev.h>
29#include <dvb_frontend.h>
21 30
22#include "avc.h"
23#include "firedtv.h" 31#include "firedtv.h"
24#include "firedtv-ci.h"
25
26DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
27 32
28static struct firedtv_channel *fdtv_channel_allocate(struct firedtv *fdtv) 33static int alloc_channel(struct firedtv *fdtv)
29{ 34{
30 struct firedtv_channel *c = NULL; 35 int i;
31 int k;
32 36
33 if (mutex_lock_interruptible(&fdtv->demux_mutex)) 37 for (i = 0; i < 16; i++)
34 return NULL; 38 if (!__test_and_set_bit(i, &fdtv->channel_active))
35
36 for (k = 0; k < 16; k++)
37 if (!fdtv->channel[k].active) {
38 fdtv->channel[k].active = true;
39 c = &fdtv->channel[k];
40 break; 39 break;
41 } 40 return i;
42
43 mutex_unlock(&fdtv->demux_mutex);
44 return c;
45} 41}
46 42
47static int fdtv_channel_collect(struct firedtv *fdtv, int *pidc, u16 pid[]) 43static void collect_channels(struct firedtv *fdtv, int *pidc, u16 pid[])
48{ 44{
49 int k, l = 0; 45 int i, n;
50
51 if (mutex_lock_interruptible(&fdtv->demux_mutex))
52 return -EINTR;
53
54 for (k = 0; k < 16; k++)
55 if (fdtv->channel[k].active)
56 pid[l++] = fdtv->channel[k].pid;
57
58 mutex_unlock(&fdtv->demux_mutex);
59 46
60 *pidc = l; 47 for (i = 0, n = 0; i < 16; i++)
61 48 if (test_bit(i, &fdtv->channel_active))
62 return 0; 49 pid[n++] = fdtv->channel_pid[i];
50 *pidc = n;
63} 51}
64 52
65static int fdtv_channel_release(struct firedtv *fdtv, 53static inline void dealloc_channel(struct firedtv *fdtv, int i)
66 struct firedtv_channel *channel)
67{ 54{
68 if (mutex_lock_interruptible(&fdtv->demux_mutex)) 55 __clear_bit(i, &fdtv->channel_active);
69 return -EINTR;
70
71 channel->active = false;
72
73 mutex_unlock(&fdtv->demux_mutex);
74 return 0;
75} 56}
76 57
77int fdtv_start_feed(struct dvb_demux_feed *dvbdmxfeed) 58int fdtv_start_feed(struct dvb_demux_feed *dvbdmxfeed)
78{ 59{
79 struct firedtv *fdtv = (struct firedtv*)dvbdmxfeed->demux->priv; 60 struct firedtv *fdtv = dvbdmxfeed->demux->priv;
80 struct firedtv_channel *channel; 61 int pidc, c, ret;
81 int pidc,k;
82 u16 pids[16]; 62 u16 pids[16];
83 63
84 switch (dvbdmxfeed->type) { 64 switch (dvbdmxfeed->type) {
@@ -86,11 +66,14 @@ int fdtv_start_feed(struct dvb_demux_feed *dvbdmxfeed)
86 case DMX_TYPE_SEC: 66 case DMX_TYPE_SEC:
87 break; 67 break;
88 default: 68 default:
89 printk(KERN_ERR "%s: invalid type %u\n", 69 dev_err(fdtv->device, "can't start dmx feed: invalid type %u\n",
90 __func__, dvbdmxfeed->type); 70 dvbdmxfeed->type);
91 return -EINVAL; 71 return -EINVAL;
92 } 72 }
93 73
74 if (mutex_lock_interruptible(&fdtv->demux_mutex))
75 return -EINTR;
76
94 if (dvbdmxfeed->type == DMX_TYPE_TS) { 77 if (dvbdmxfeed->type == DMX_TYPE_TS) {
95 switch (dvbdmxfeed->pes_type) { 78 switch (dvbdmxfeed->pes_type) {
96 case DMX_TS_PES_VIDEO: 79 case DMX_TS_PES_VIDEO:
@@ -98,75 +81,64 @@ int fdtv_start_feed(struct dvb_demux_feed *dvbdmxfeed)
98 case DMX_TS_PES_TELETEXT: 81 case DMX_TS_PES_TELETEXT:
99 case DMX_TS_PES_PCR: 82 case DMX_TS_PES_PCR:
100 case DMX_TS_PES_OTHER: 83 case DMX_TS_PES_OTHER:
101 //Dirty fix to keep fdtv->channel pid-list up to date 84 c = alloc_channel(fdtv);
102 for(k=0;k<16;k++){
103 if (!fdtv->channel[k].active)
104 fdtv->channel[k].pid =
105 dvbdmxfeed->pid;
106 break;
107 }
108 channel = fdtv_channel_allocate(fdtv);
109 break; 85 break;
110 default: 86 default:
111 printk(KERN_ERR "%s: invalid pes type %u\n", 87 dev_err(fdtv->device,
112 __func__, dvbdmxfeed->pes_type); 88 "can't start dmx feed: invalid pes type %u\n",
113 return -EINVAL; 89 dvbdmxfeed->pes_type);
90 ret = -EINVAL;
91 goto out;
114 } 92 }
115 } else { 93 } else {
116 channel = fdtv_channel_allocate(fdtv); 94 c = alloc_channel(fdtv);
117 } 95 }
118 96
119 if (!channel) { 97 if (c > 15) {
120 printk(KERN_ERR "%s: busy!\n", __func__); 98 dev_err(fdtv->device, "can't start dmx feed: busy\n");
121 return -EBUSY; 99 ret = -EBUSY;
100 goto out;
122 } 101 }
123 102
124 dvbdmxfeed->priv = channel; 103 dvbdmxfeed->priv = (typeof(dvbdmxfeed->priv))(unsigned long)c;
125 channel->pid = dvbdmxfeed->pid; 104 fdtv->channel_pid[c] = dvbdmxfeed->pid;
126 105 collect_channels(fdtv, &pidc, pids);
127 if (fdtv_channel_collect(fdtv, &pidc, pids)) {
128 fdtv_channel_release(fdtv, channel);
129 printk(KERN_ERR "%s: could not collect pids!\n", __func__);
130 return -EINTR;
131 }
132 106
133 if (dvbdmxfeed->pid == 8192) { 107 if (dvbdmxfeed->pid == 8192) {
134 k = avc_tuner_get_ts(fdtv); 108 ret = avc_tuner_get_ts(fdtv);
135 if (k) { 109 if (ret) {
136 fdtv_channel_release(fdtv, channel); 110 dealloc_channel(fdtv, c);
137 printk("%s: AVCTuner_GetTS failed with error %d\n", 111 dev_err(fdtv->device, "can't get TS\n");
138 __func__, k); 112 goto out;
139 return k;
140 } 113 }
141 } else { 114 } else {
142 k = avc_tuner_set_pids(fdtv, pidc, pids); 115 ret = avc_tuner_set_pids(fdtv, pidc, pids);
143 if (k) { 116 if (ret) {
144 fdtv_channel_release(fdtv, channel); 117 dealloc_channel(fdtv, c);
145 printk("%s: AVCTuner_SetPIDs failed with error %d\n", 118 dev_err(fdtv->device, "can't set PIDs\n");
146 __func__, k); 119 goto out;
147 return k;
148 } 120 }
149 } 121 }
122out:
123 mutex_unlock(&fdtv->demux_mutex);
150 124
151 return 0; 125 return ret;
152} 126}
153 127
154int fdtv_stop_feed(struct dvb_demux_feed *dvbdmxfeed) 128int fdtv_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
155{ 129{
156 struct dvb_demux *demux = dvbdmxfeed->demux; 130 struct dvb_demux *demux = dvbdmxfeed->demux;
157 struct firedtv *fdtv = (struct firedtv*)demux->priv; 131 struct firedtv *fdtv = demux->priv;
158 struct firedtv_channel *c = dvbdmxfeed->priv; 132 int pidc, c, ret;
159 int k, l;
160 u16 pids[16]; 133 u16 pids[16];
161 134
162 if (dvbdmxfeed->type == DMX_TYPE_TS && !((dvbdmxfeed->ts_type & TS_PACKET) && 135 if (dvbdmxfeed->type == DMX_TYPE_TS &&
163 (demux->dmx.frontend->source != DMX_MEMORY_FE))) { 136 !((dvbdmxfeed->ts_type & TS_PACKET) &&
137 (demux->dmx.frontend->source != DMX_MEMORY_FE))) {
164 138
165 if (dvbdmxfeed->ts_type & TS_DECODER) { 139 if (dvbdmxfeed->ts_type & TS_DECODER) {
166
167 if (dvbdmxfeed->pes_type >= DMX_TS_PES_OTHER || 140 if (dvbdmxfeed->pes_type >= DMX_TS_PES_OTHER ||
168 !demux->pesfilter[dvbdmxfeed->pes_type]) 141 !demux->pesfilter[dvbdmxfeed->pes_type])
169
170 return -EINVAL; 142 return -EINVAL;
171 143
172 demux->pids[dvbdmxfeed->pes_type] |= 0x8000; 144 demux->pids[dvbdmxfeed->pes_type] |= 0x8000;
@@ -174,38 +146,32 @@ int fdtv_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
174 } 146 }
175 147
176 if (!(dvbdmxfeed->ts_type & TS_DECODER && 148 if (!(dvbdmxfeed->ts_type & TS_DECODER &&
177 dvbdmxfeed->pes_type < DMX_TS_PES_OTHER)) 149 dvbdmxfeed->pes_type < DMX_TS_PES_OTHER))
178
179 return 0; 150 return 0;
180 } 151 }
181 152
182 if (mutex_lock_interruptible(&fdtv->demux_mutex)) 153 if (mutex_lock_interruptible(&fdtv->demux_mutex))
183 return -EINTR; 154 return -EINTR;
184 155
185 /* list except channel to be removed */ 156 c = (unsigned long)dvbdmxfeed->priv;
186 for (k = 0, l = 0; k < 16; k++) 157 dealloc_channel(fdtv, c);
187 if (fdtv->channel[k].active) { 158 collect_channels(fdtv, &pidc, pids);
188 if (&fdtv->channel[k] != c)
189 pids[l++] = fdtv->channel[k].pid;
190 else
191 fdtv->channel[k].active = false;
192 }
193 159
194 k = avc_tuner_set_pids(fdtv, l, pids); 160 ret = avc_tuner_set_pids(fdtv, pidc, pids);
195 if (!k)
196 c->active = false;
197 161
198 mutex_unlock(&fdtv->demux_mutex); 162 mutex_unlock(&fdtv->demux_mutex);
199 return k; 163
164 return ret;
200} 165}
201 166
202int fdtv_dvbdev_init(struct firedtv *fdtv, struct device *dev) 167DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
168
169int fdtv_dvb_register(struct firedtv *fdtv)
203{ 170{
204 int err; 171 int err;
205 172
206 err = DVB_REGISTER_ADAPTER(&fdtv->adapter, 173 err = dvb_register_adapter(&fdtv->adapter, fdtv_model_names[fdtv->type],
207 fdtv_model_names[fdtv->type], 174 THIS_MODULE, fdtv->device, adapter_nr);
208 THIS_MODULE, dev, adapter_nr);
209 if (err < 0) 175 if (err < 0)
210 goto fail_log; 176 goto fail_log;
211 177
@@ -223,9 +189,9 @@ int fdtv_dvbdev_init(struct firedtv *fdtv, struct device *dev)
223 if (err) 189 if (err)
224 goto fail_unreg_adapter; 190 goto fail_unreg_adapter;
225 191
226 fdtv->dmxdev.filternum = 16; 192 fdtv->dmxdev.filternum = 16;
227 fdtv->dmxdev.demux = &fdtv->demux.dmx; 193 fdtv->dmxdev.demux = &fdtv->demux.dmx;
228 fdtv->dmxdev.capabilities = 0; 194 fdtv->dmxdev.capabilities = 0;
229 195
230 err = dvb_dmxdev_init(&fdtv->dmxdev, &fdtv->adapter); 196 err = dvb_dmxdev_init(&fdtv->dmxdev, &fdtv->adapter);
231 if (err) 197 if (err)
@@ -233,13 +199,12 @@ int fdtv_dvbdev_init(struct firedtv *fdtv, struct device *dev)
233 199
234 fdtv->frontend.source = DMX_FRONTEND_0; 200 fdtv->frontend.source = DMX_FRONTEND_0;
235 201
236 err = fdtv->demux.dmx.add_frontend(&fdtv->demux.dmx, 202 err = fdtv->demux.dmx.add_frontend(&fdtv->demux.dmx, &fdtv->frontend);
237 &fdtv->frontend);
238 if (err) 203 if (err)
239 goto fail_dmxdev_release; 204 goto fail_dmxdev_release;
240 205
241 err = fdtv->demux.dmx.connect_frontend(&fdtv->demux.dmx, 206 err = fdtv->demux.dmx.connect_frontend(&fdtv->demux.dmx,
242 &fdtv->frontend); 207 &fdtv->frontend);
243 if (err) 208 if (err)
244 goto fail_rem_frontend; 209 goto fail_rem_frontend;
245 210
@@ -252,16 +217,15 @@ int fdtv_dvbdev_init(struct firedtv *fdtv, struct device *dev)
252 217
253 err = fdtv_ca_register(fdtv); 218 err = fdtv_ca_register(fdtv);
254 if (err) 219 if (err)
255 dev_info(dev, "Conditional Access Module not enabled\n"); 220 dev_info(fdtv->device,
256 221 "Conditional Access Module not enabled\n");
257 return 0; 222 return 0;
258 223
259fail_net_release: 224fail_net_release:
260 dvb_net_release(&fdtv->dvbnet); 225 dvb_net_release(&fdtv->dvbnet);
261 fdtv->demux.dmx.close(&fdtv->demux.dmx); 226 fdtv->demux.dmx.close(&fdtv->demux.dmx);
262fail_rem_frontend: 227fail_rem_frontend:
263 fdtv->demux.dmx.remove_frontend(&fdtv->demux.dmx, 228 fdtv->demux.dmx.remove_frontend(&fdtv->demux.dmx, &fdtv->frontend);
264 &fdtv->frontend);
265fail_dmxdev_release: 229fail_dmxdev_release:
266 dvb_dmxdev_release(&fdtv->dmxdev); 230 dvb_dmxdev_release(&fdtv->dmxdev);
267fail_dmx_release: 231fail_dmx_release:
@@ -269,8 +233,132 @@ fail_dmx_release:
269fail_unreg_adapter: 233fail_unreg_adapter:
270 dvb_unregister_adapter(&fdtv->adapter); 234 dvb_unregister_adapter(&fdtv->adapter);
271fail_log: 235fail_log:
272 dev_err(dev, "DVB initialization failed\n"); 236 dev_err(fdtv->device, "DVB initialization failed\n");
273 return err; 237 return err;
274} 238}
275 239
240void fdtv_dvb_unregister(struct firedtv *fdtv)
241{
242 fdtv_ca_release(fdtv);
243 dvb_unregister_frontend(&fdtv->fe);
244 dvb_net_release(&fdtv->dvbnet);
245 fdtv->demux.dmx.close(&fdtv->demux.dmx);
246 fdtv->demux.dmx.remove_frontend(&fdtv->demux.dmx, &fdtv->frontend);
247 dvb_dmxdev_release(&fdtv->dmxdev);
248 dvb_dmx_release(&fdtv->demux);
249 dvb_unregister_adapter(&fdtv->adapter);
250}
251
252const char *fdtv_model_names[] = {
253 [FIREDTV_UNKNOWN] = "unknown type",
254 [FIREDTV_DVB_S] = "FireDTV S/CI",
255 [FIREDTV_DVB_C] = "FireDTV C/CI",
256 [FIREDTV_DVB_T] = "FireDTV T/CI",
257 [FIREDTV_DVB_S2] = "FireDTV S2 ",
258};
259
260struct firedtv *fdtv_alloc(struct device *dev,
261 const struct firedtv_backend *backend,
262 const char *name, size_t name_len)
263{
264 struct firedtv *fdtv;
265 int i;
266
267 fdtv = kzalloc(sizeof(*fdtv), GFP_KERNEL);
268 if (!fdtv)
269 return NULL;
270
271 dev->driver_data = fdtv;
272 fdtv->device = dev;
273 fdtv->isochannel = -1;
274 fdtv->voltage = 0xff;
275 fdtv->tone = 0xff;
276 fdtv->backend = backend;
277
278 mutex_init(&fdtv->avc_mutex);
279 init_waitqueue_head(&fdtv->avc_wait);
280 fdtv->avc_reply_received = true;
281 mutex_init(&fdtv->demux_mutex);
282 INIT_WORK(&fdtv->remote_ctrl_work, avc_remote_ctrl_work);
283
284 for (i = ARRAY_SIZE(fdtv_model_names); --i; )
285 if (strlen(fdtv_model_names[i]) <= name_len &&
286 strncmp(name, fdtv_model_names[i], name_len) == 0)
287 break;
288 fdtv->type = i;
289
290 return fdtv;
291}
292
293#define MATCH_FLAGS (IEEE1394_MATCH_VENDOR_ID | IEEE1394_MATCH_MODEL_ID | \
294 IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION)
295
296#define DIGITAL_EVERYWHERE_OUI 0x001287
297#define AVC_UNIT_SPEC_ID_ENTRY 0x00a02d
298#define AVC_SW_VERSION_ENTRY 0x010001
299
300static struct ieee1394_device_id fdtv_id_table[] = {
301 {
302 /* FloppyDTV S/CI and FloppyDTV S2 */
303 .match_flags = MATCH_FLAGS,
304 .vendor_id = DIGITAL_EVERYWHERE_OUI,
305 .model_id = 0x000024,
306 .specifier_id = AVC_UNIT_SPEC_ID_ENTRY,
307 .version = AVC_SW_VERSION_ENTRY,
308 }, {
309 /* FloppyDTV T/CI */
310 .match_flags = MATCH_FLAGS,
311 .vendor_id = DIGITAL_EVERYWHERE_OUI,
312 .model_id = 0x000025,
313 .specifier_id = AVC_UNIT_SPEC_ID_ENTRY,
314 .version = AVC_SW_VERSION_ENTRY,
315 }, {
316 /* FloppyDTV C/CI */
317 .match_flags = MATCH_FLAGS,
318 .vendor_id = DIGITAL_EVERYWHERE_OUI,
319 .model_id = 0x000026,
320 .specifier_id = AVC_UNIT_SPEC_ID_ENTRY,
321 .version = AVC_SW_VERSION_ENTRY,
322 }, {
323 /* FireDTV S/CI and FloppyDTV S2 */
324 .match_flags = MATCH_FLAGS,
325 .vendor_id = DIGITAL_EVERYWHERE_OUI,
326 .model_id = 0x000034,
327 .specifier_id = AVC_UNIT_SPEC_ID_ENTRY,
328 .version = AVC_SW_VERSION_ENTRY,
329 }, {
330 /* FireDTV T/CI */
331 .match_flags = MATCH_FLAGS,
332 .vendor_id = DIGITAL_EVERYWHERE_OUI,
333 .model_id = 0x000035,
334 .specifier_id = AVC_UNIT_SPEC_ID_ENTRY,
335 .version = AVC_SW_VERSION_ENTRY,
336 }, {
337 /* FireDTV C/CI */
338 .match_flags = MATCH_FLAGS,
339 .vendor_id = DIGITAL_EVERYWHERE_OUI,
340 .model_id = 0x000036,
341 .specifier_id = AVC_UNIT_SPEC_ID_ENTRY,
342 .version = AVC_SW_VERSION_ENTRY,
343 }, {}
344};
345MODULE_DEVICE_TABLE(ieee1394, fdtv_id_table);
346
347static int __init fdtv_init(void)
348{
349 return fdtv_1394_init(fdtv_id_table);
350}
351
352static void __exit fdtv_exit(void)
353{
354 fdtv_1394_exit();
355}
356
357module_init(fdtv_init);
358module_exit(fdtv_exit);
276 359
360MODULE_AUTHOR("Andreas Monitzer <andy@monitzer.com>");
361MODULE_AUTHOR("Ben Backx <ben@bbackx.com>");
362MODULE_DESCRIPTION("FireDTV DVB Driver");
363MODULE_LICENSE("GPL");
364MODULE_SUPPORTED_DEVICE("FireDTV DVB");