aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/dvb/firesat/firesat_dvb.c
diff options
context:
space:
mode:
authorStefan Richter <stefanr@s5r6.in-berlin.de>2008-11-02 07:45:00 -0500
committerStefan Richter <stefanr@s5r6.in-berlin.de>2009-02-24 08:51:28 -0500
commit8ae83cdf3297d7da301af36bdb6ff45bd331c6d0 (patch)
tree0363a01f1b3655507bdaf7e1f55af6a3ee9d26b7 /drivers/media/dvb/firesat/firesat_dvb.c
parent00fc3072e484c1c6fdbd9c3b1851f866000a6cb9 (diff)
firedtv: cleanups and minor fixes
Combination of the following changes: Sun, 2 Nov 2008 13:45:00 +0100 (CET) firedtv: increase FCP frame length for DVB-S2 tune QSPK The last three bytes didn't go out to the wire. Effect of the fix not yet tested. Sun, 2 Nov 2008 13:45:00 +0100 (CET) firedtv: replace mdelay by msleep These functions can sleep (and in fact sleep for the duration of a whole FCP transaction). Hence msleep is more appropriate here. Sun, 2 Nov 2008 13:45:00 +0100 (CET) firedtv: trivial reorganization in avc_api Reduce nesting level by factoring code out of avc_tuner_dsd() into helper functions. Sun, 2 Nov 2008 13:45:00 +0100 (CET) firedtv: trivial cleanups in avc_api Use dev_err(), no CamelCase function names, adjust comment style, put #if 0 around unused code and add FIXME comments, standardize on lower-case hexadecimal constants, use ALIGN() for some frame length calculations, make a local function static... The code which writes FCP command frames and reads FCP response frames is not yet brought into canonical kernel coding style because this involves changes of typedefs (on-the-wire bitfields). Sun, 2 Nov 2008 13:45:00 +0100 (CET) firedtv: don't retry oPCR updates endlessly In the theoretical case that the target node wasn't handling the lock transactions as expected or there was continued interference by other initiating nodes, these functions wouldn't return for ages. Sun, 2 Nov 2008 13:45:00 +0100 (CET) firedtv: remove bitfield typedefs from cmp, fix for big endian CPUs Use macros/ inline functions/ standard byte order accessors to read and write oPCR register values (big endian bitfields, on-the-wire data). The new code may not be the ultimate optimum, but it doesn't occur in a hot path. This fixes the CMP code for big endian CPUs. So far I tested it only on a little endian CPU though. For now, include <asm/byteorder.h> instead of <linux/byteorder.h> because drivers/ieee1394/*.h also include the former. I will fix this in drivers/ieee1394 and firedtv later. Sun, 2 Nov 2008 13:45:00 +0100 (CET) firedtv: trivial cleanups in cmp Reduce nesting level by means of early exit and goto. Remove obsolete includes, use dev_err(), no CamelCase function names... Sun, 2 Nov 2008 13:45:00 +0100 (CET) firedtv: trivial cleanups in firesat-ci Whitespace, variable names, comment style... Also, use dvb_generic_open() and dvb_generic_release() directly as our hooks in struct file_operations because firedtv's wrappers merely called these generic functions. Sun, 2 Nov 2008 13:45:00 +0100 (CET) firedtv: remove CA debug code This looks like it is not necessary to have available for endusers who cannot patch kernels for bug reporting and tests of fixes. Sun, 2 Nov 2008 13:45:00 +0100 (CET) firedtv: remove AV/C debug code This looks like it is not necessary to have available for endusers who cannot patch kernels for bug reporting and tests of fixes. Sun, 2 Nov 2008 13:45:00 +0100 (CET) firedtv: remove various debug code Most of this was already commented out. And that which wasn't is not relevant in normal use. Mon, 29 Sep 2008 19:22:48 +0200 (CEST) firedtv: register input device as child of a FireWire device Instead of one virtual input device which exists for the whole lifetime of the driver and receives events from all connected FireDTVs, register one input device for each firedtv device. These input devices will show up as children of the respective firedtv devices in the sysfs hierarchy. However, the implementation falls short because of a bug in userspace: Udev's path_id script gets stuck with 100% CPU utilization, maybe because of an assumption about the maximum ieee1394 device hierarchy depth. To avoid this bug, we use the fw-host device instead of the proper unit_directory device as parent of the input device. There is hope that the port to the new firewire stack won't be inhibited by this userspace bug because there are no fw-host devices there. Mon, 29 Sep 2008 19:21:52 +0200 (CEST) firedtv: fix string comparison and a few sparse warnings Sparse found a bug: while ((kv_buf + kv_len - 1) == '\0') should have been while (kv_buf[kv_len - 1] == '\0') We fix it by a better implementation without a temporary copy. Also fix sparse warnings of 0 instead of NULL and signedness mismatches. Mon, 29 Sep 2008 19:21:20 +0200 (CEST) firedtv: remove unused struct members and redefine an int as a bool. Mon, 29 Sep 2008 19:20:36 +0200 (CEST) firedtv: fix initialization of dvb_frontend.ops There was a NULL pointer reference if no dvb_frontend_info was found. Also, don't directly assign struct typed values to struct typed variables. Instead write out assignments to individual strcut members. This reduces module size by about 1 kB. Mon, 29 Sep 2008 19:19:41 +0200 (CEST) firedtv: remove unused dual subunit code from initialization No FireDTVs with more than one subunit exists, hence simplify the initialization for the special case of one subunit. The driver was able to check for more than one subunit but was broken for more than two subunits. While we are at it, add several missing cleanups after failure, and include a few dynamically allocated structures diretly into struct firesat instead of allocating them separately. Mon, 29 Sep 2008 19:19:08 +0200 (CEST) firedtv: add vendor_id and version to driver match table Now that nodemgr was enhanced to match against the root directory's vendor ID if there isn't one in the unit directory, use this to prevent firedtv to be bound to wrong devices by accident. Also add the AV/C software version ID to the match flags for completeness; specifier ID and software only make sense as a pair. Mon, 29 Sep 2008 19:18:30 +0200 (CEST) firedtv: use hpsb_node_read(), _write(), _lock() because they are simpler and treat the node generation more correctly. While we are at it, clean up and simplify surrounding code. Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
Diffstat (limited to 'drivers/media/dvb/firesat/firesat_dvb.c')
-rw-r--r--drivers/media/dvb/firesat/firesat_dvb.c178
1 files changed, 73 insertions, 105 deletions
diff --git a/drivers/media/dvb/firesat/firesat_dvb.c b/drivers/media/dvb/firesat/firesat_dvb.c
index e944cee19f0..cfa3a2e8edd 100644
--- a/drivers/media/dvb/firesat/firesat_dvb.c
+++ b/drivers/media/dvb/firesat/firesat_dvb.c
@@ -34,8 +34,8 @@ static struct firesat_channel *firesat_channel_allocate(struct firesat *firesat)
34 return NULL; 34 return NULL;
35 35
36 for (k = 0; k < 16; k++) 36 for (k = 0; k < 16; k++)
37 if (firesat->channel[k].active == 0) { 37 if (!firesat->channel[k].active) {
38 firesat->channel[k].active = 1; 38 firesat->channel[k].active = true;
39 c = &firesat->channel[k]; 39 c = &firesat->channel[k];
40 break; 40 break;
41 } 41 }
@@ -52,7 +52,7 @@ static int firesat_channel_collect(struct firesat *firesat, int *pidc, u16 pid[]
52 return -EINTR; 52 return -EINTR;
53 53
54 for (k = 0; k < 16; k++) 54 for (k = 0; k < 16; k++)
55 if (firesat->channel[k].active == 1) 55 if (firesat->channel[k].active)
56 pid[l++] = firesat->channel[k].pid; 56 pid[l++] = firesat->channel[k].pid;
57 57
58 mutex_unlock(&firesat->demux_mutex); 58 mutex_unlock(&firesat->demux_mutex);
@@ -68,7 +68,7 @@ static int firesat_channel_release(struct firesat *firesat,
68 if (mutex_lock_interruptible(&firesat->demux_mutex)) 68 if (mutex_lock_interruptible(&firesat->demux_mutex))
69 return -EINTR; 69 return -EINTR;
70 70
71 channel->active = 0; 71 channel->active = false;
72 72
73 mutex_unlock(&firesat->demux_mutex); 73 mutex_unlock(&firesat->demux_mutex);
74 return 0; 74 return 0;
@@ -81,8 +81,6 @@ int firesat_start_feed(struct dvb_demux_feed *dvbdmxfeed)
81 int pidc,k; 81 int pidc,k;
82 u16 pids[16]; 82 u16 pids[16];
83 83
84// printk(KERN_INFO "%s (pid %u)\n", __func__, dvbdmxfeed->pid);
85
86 switch (dvbdmxfeed->type) { 84 switch (dvbdmxfeed->type) {
87 case DMX_TYPE_TS: 85 case DMX_TYPE_TS:
88 case DMX_TYPE_SEC: 86 case DMX_TYPE_SEC:
@@ -102,7 +100,7 @@ int firesat_start_feed(struct dvb_demux_feed *dvbdmxfeed)
102 case DMX_TS_PES_OTHER: 100 case DMX_TS_PES_OTHER:
103 //Dirty fix to keep firesat->channel pid-list up to date 101 //Dirty fix to keep firesat->channel pid-list up to date
104 for(k=0;k<16;k++){ 102 for(k=0;k<16;k++){
105 if(firesat->channel[k].active == 0) 103 if (!firesat->channel[k].active)
106 firesat->channel[k].pid = 104 firesat->channel[k].pid =
107 dvbdmxfeed->pid; 105 dvbdmxfeed->pid;
108 break; 106 break;
@@ -124,11 +122,7 @@ int firesat_start_feed(struct dvb_demux_feed *dvbdmxfeed)
124 } 122 }
125 123
126 dvbdmxfeed->priv = channel; 124 dvbdmxfeed->priv = channel;
127
128 channel->dvbdmxfeed = dvbdmxfeed;
129 channel->pid = dvbdmxfeed->pid; 125 channel->pid = dvbdmxfeed->pid;
130 channel->type = dvbdmxfeed->type;
131 channel->firesat = firesat;
132 126
133 if (firesat_channel_collect(firesat, &pidc, pids)) { 127 if (firesat_channel_collect(firesat, &pidc, pids)) {
134 firesat_channel_release(firesat, channel); 128 firesat_channel_release(firesat, channel);
@@ -136,16 +130,17 @@ int firesat_start_feed(struct dvb_demux_feed *dvbdmxfeed)
136 return -EINTR; 130 return -EINTR;
137 } 131 }
138 132
139 if(dvbdmxfeed->pid == 8192) { 133 if (dvbdmxfeed->pid == 8192) {
140 if((k = AVCTuner_GetTS(firesat))) { 134 k = avc_tuner_get_ts(firesat);
135 if (k) {
141 firesat_channel_release(firesat, channel); 136 firesat_channel_release(firesat, channel);
142 printk("%s: AVCTuner_GetTS failed with error %d\n", 137 printk("%s: AVCTuner_GetTS failed with error %d\n",
143 __func__, k); 138 __func__, k);
144 return k; 139 return k;
145 } 140 }
146 } 141 } else {
147 else { 142 k = avc_tuner_set_pids(firesat, pidc, pids);
148 if((k = AVCTuner_SetPIDs(firesat, pidc, pids))) { 143 if (k) {
149 firesat_channel_release(firesat, channel); 144 firesat_channel_release(firesat, channel);
150 printk("%s: AVCTuner_SetPIDs failed with error %d\n", 145 printk("%s: AVCTuner_SetPIDs failed with error %d\n",
151 __func__, k); 146 __func__, k);
@@ -164,8 +159,6 @@ int firesat_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
164 int k, l; 159 int k, l;
165 u16 pids[16]; 160 u16 pids[16];
166 161
167 //printk(KERN_INFO "%s (pid %u)\n", __func__, dvbdmxfeed->pid);
168
169 if (dvbdmxfeed->type == DMX_TYPE_TS && !((dvbdmxfeed->ts_type & TS_PACKET) && 162 if (dvbdmxfeed->type == DMX_TYPE_TS && !((dvbdmxfeed->ts_type & TS_PACKET) &&
170 (demux->dmx.frontend->source != DMX_MEMORY_FE))) { 163 (demux->dmx.frontend->source != DMX_MEMORY_FE))) {
171 164
@@ -177,7 +170,7 @@ int firesat_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
177 return -EINVAL; 170 return -EINVAL;
178 171
179 demux->pids[dvbdmxfeed->pes_type] |= 0x8000; 172 demux->pids[dvbdmxfeed->pes_type] |= 0x8000;
180 demux->pesfilter[dvbdmxfeed->pes_type] = 0; 173 demux->pesfilter[dvbdmxfeed->pes_type] = NULL;
181 } 174 }
182 175
183 if (!(dvbdmxfeed->ts_type & TS_DECODER && 176 if (!(dvbdmxfeed->ts_type & TS_DECODER &&
@@ -191,118 +184,93 @@ int firesat_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
191 184
192 /* list except channel to be removed */ 185 /* list except channel to be removed */
193 for (k = 0, l = 0; k < 16; k++) 186 for (k = 0, l = 0; k < 16; k++)
194 if (firesat->channel[k].active == 1) { 187 if (firesat->channel[k].active) {
195 if (&firesat->channel[k] != c) 188 if (&firesat->channel[k] != c)
196 pids[l++] = firesat->channel[k].pid; 189 pids[l++] = firesat->channel[k].pid;
197 else 190 else
198 firesat->channel[k].active = 0; 191 firesat->channel[k].active = false;
199 } 192 }
200 193
201 k = AVCTuner_SetPIDs(firesat, l, pids); 194 k = avc_tuner_set_pids(firesat, l, pids);
202 if (!k) 195 if (!k)
203 c->active = 0; 196 c->active = false;
204 197
205 mutex_unlock(&firesat->demux_mutex); 198 mutex_unlock(&firesat->demux_mutex);
206 return k; 199 return k;
207} 200}
208 201
209int firesat_dvbdev_init(struct firesat *firesat, 202int firesat_dvbdev_init(struct firesat *firesat, struct device *dev)
210 struct device *dev,
211 struct dvb_frontend *fe)
212{ 203{
213 int result; 204 int err;
214
215 firesat->adapter = kmalloc(sizeof(*firesat->adapter), GFP_KERNEL);
216 if (!firesat->adapter) {
217 printk(KERN_ERR "firedtv: couldn't allocate memory\n");
218 return -ENOMEM;
219 }
220
221 result = DVB_REGISTER_ADAPTER(firesat->adapter,
222 firedtv_model_names[firesat->type],
223 THIS_MODULE, dev, adapter_nr);
224 if (result < 0) {
225 printk(KERN_ERR "firedtv: dvb_register_adapter failed\n");
226 kfree(firesat->adapter);
227 return result;
228 }
229
230 memset(&firesat->demux, 0, sizeof(struct dvb_demux));
231 firesat->demux.dmx.capabilities = 0/*DMX_TS_FILTERING | DMX_SECTION_FILTERING*/;
232
233 firesat->demux.priv = (void *)firesat;
234 firesat->demux.filternum = 16;
235 firesat->demux.feednum = 16;
236 firesat->demux.start_feed = firesat_start_feed;
237 firesat->demux.stop_feed = firesat_stop_feed;
238 firesat->demux.write_to_decoder = NULL;
239 205
240 if ((result = dvb_dmx_init(&firesat->demux)) < 0) { 206 err = DVB_REGISTER_ADAPTER(&firesat->adapter,
241 printk("%s: dvb_dmx_init failed: error %d\n", __func__, 207 firedtv_model_names[firesat->type],
242 result); 208 THIS_MODULE, dev, adapter_nr);
209 if (err)
210 goto fail_log;
243 211
244 dvb_unregister_adapter(firesat->adapter); 212 /*DMX_TS_FILTERING | DMX_SECTION_FILTERING*/
213 firesat->demux.dmx.capabilities = 0;
245 214
246 return result; 215 firesat->demux.priv = (void *)firesat;
247 } 216 firesat->demux.filternum = 16;
248 217 firesat->demux.feednum = 16;
249 firesat->dmxdev.filternum = 16; 218 firesat->demux.start_feed = firesat_start_feed;
250 firesat->dmxdev.demux = &firesat->demux.dmx; 219 firesat->demux.stop_feed = firesat_stop_feed;
251 firesat->dmxdev.capabilities = 0; 220 firesat->demux.write_to_decoder = NULL;
252
253 if ((result = dvb_dmxdev_init(&firesat->dmxdev, firesat->adapter)) < 0) {
254 printk("%s: dvb_dmxdev_init failed: error %d\n",
255 __func__, result);
256 221
257 dvb_dmx_release(&firesat->demux); 222 err = dvb_dmx_init(&firesat->demux);
258 dvb_unregister_adapter(firesat->adapter); 223 if (err)
224 goto fail_unreg_adapter;
259 225
260 return result; 226 firesat->dmxdev.filternum = 16;
261 } 227 firesat->dmxdev.demux = &firesat->demux.dmx;
228 firesat->dmxdev.capabilities = 0;
262 229
263 firesat->frontend.source = DMX_FRONTEND_0; 230 err = dvb_dmxdev_init(&firesat->dmxdev, &firesat->adapter);
231 if (err)
232 goto fail_dmx_release;
264 233
265 if ((result = firesat->demux.dmx.add_frontend(&firesat->demux.dmx, 234 firesat->frontend.source = DMX_FRONTEND_0;
266 &firesat->frontend)) < 0) {
267 printk("%s: dvb_dmx_init failed: error %d\n", __func__,
268 result);
269 235
270 dvb_dmxdev_release(&firesat->dmxdev); 236 err = firesat->demux.dmx.add_frontend(&firesat->demux.dmx,
271 dvb_dmx_release(&firesat->demux); 237 &firesat->frontend);
272 dvb_unregister_adapter(firesat->adapter); 238 if (err)
239 goto fail_dmxdev_release;
273 240
274 return result; 241 err = firesat->demux.dmx.connect_frontend(&firesat->demux.dmx,
275 } 242 &firesat->frontend);
243 if (err)
244 goto fail_rem_frontend;
276 245
277 if ((result = firesat->demux.dmx.connect_frontend(&firesat->demux.dmx, 246 dvb_net_init(&firesat->adapter, &firesat->dvbnet, &firesat->demux.dmx);
278 &firesat->frontend)) < 0) {
279 printk("%s: dvb_dmx_init failed: error %d\n", __func__,
280 result);
281 247
282 firesat->demux.dmx.remove_frontend(&firesat->demux.dmx, &firesat->frontend); 248 firesat_frontend_init(firesat);
283 dvb_dmxdev_release(&firesat->dmxdev); 249 err = dvb_register_frontend(&firesat->adapter, &firesat->fe);
284 dvb_dmx_release(&firesat->demux); 250 if (err)
285 dvb_unregister_adapter(firesat->adapter); 251 goto fail_net_release;
286 252
287 return result; 253 err = firesat_ca_register(firesat);
288 } 254 if (err)
255 dev_info(dev, "Conditional Access Module not enabled\n");
289 256
290 dvb_net_init(firesat->adapter, &firesat->dvbnet, &firesat->demux.dmx); 257 return 0;
291
292// fe->ops = firesat_ops;
293// fe->dvb = firesat->adapter;
294 firesat_frontend_attach(firesat, fe);
295
296 fe->sec_priv = firesat; //IMPORTANT, functions depend on this!!!
297 if ((result= dvb_register_frontend(firesat->adapter, fe)) < 0) {
298 printk("%s: dvb_register_frontend_new failed: error %d\n", __func__, result);
299 /* ### cleanup */
300 return result;
301 }
302
303 firesat_ca_init(firesat);
304 258
305 return 0; 259fail_net_release:
260 dvb_net_release(&firesat->dvbnet);
261 firesat->demux.dmx.close(&firesat->demux.dmx);
262fail_rem_frontend:
263 firesat->demux.dmx.remove_frontend(&firesat->demux.dmx,
264 &firesat->frontend);
265fail_dmxdev_release:
266 dvb_dmxdev_release(&firesat->dmxdev);
267fail_dmx_release:
268 dvb_dmx_release(&firesat->demux);
269fail_unreg_adapter:
270 dvb_unregister_adapter(&firesat->adapter);
271fail_log:
272 dev_err(dev, "DVB initialization failed\n");
273 return err;
306} 274}
307 275
308 276