aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/dvb/firesat/firesat_1394.c
diff options
context:
space:
mode:
authorHenrik Kurelid <henke@kurelid.se>2008-08-01 04:00:45 -0400
committerStefan Richter <stefanr@s5r6.in-berlin.de>2009-02-24 08:51:26 -0500
commitdf4846c35247a0d038c5359d502cddd59d04bc40 (patch)
tree40c58c28c389f238e3d26230f264782e8f4bcb1e /drivers/media/dvb/firesat/firesat_1394.c
parent2c22861459f094e899c034515a9bb92ac307ceae (diff)
firesat: update isochronous interface, add CI support
I have finally managed to get the CI support for the card working. The implementation is a bare minimum to get encrypted channels to work in kaffeine. It works fine with my T/CI card. Now and then I get an AVC timeout and have to retune a channel in order to get it to work. Once the CAM seemed to hang so I needed to remove and insert it again. I.e. there are a number of glitches. The latest version contains the following changes: - Implemented the new hpsb iso interface so that data can be received from the card - Reduced some timers for demux setup which caused scanning to timeout - Added possibility to unload driver - Added support for getting C/N ratio - Added two debug parameters to the driver; ca_debug and avc_comm_debug. - Added CI support that works for me in kaffeine - Started working on CI MMI support. It now supports: o Enter menu o Receiving MMI objects - Added support for 64-bit platforms - Corrected DVB-C modulations problems Signed-off-by: Henrik Kurelid <henrik@kurelid.se> Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de> (rebased, whitespace)
Diffstat (limited to 'drivers/media/dvb/firesat/firesat_1394.c')
-rw-r--r--drivers/media/dvb/firesat/firesat_1394.c123
1 files changed, 8 insertions, 115 deletions
diff --git a/drivers/media/dvb/firesat/firesat_1394.c b/drivers/media/dvb/firesat/firesat_1394.c
index dcac70a2991e..04ad31666fb9 100644
--- a/drivers/media/dvb/firesat/firesat_1394.c
+++ b/drivers/media/dvb/firesat/firesat_1394.c
@@ -3,6 +3,7 @@
3 * 3 *
4 * Copyright (c) 2004 Andreas Monitzer <andy@monitzer.com> 4 * Copyright (c) 2004 Andreas Monitzer <andy@monitzer.com>
5 * Copyright (c) 2007-2008 Ben Backx <ben@bbackx.com> 5 * Copyright (c) 2007-2008 Ben Backx <ben@bbackx.com>
6 * Copyright (c) 2008 Henrik Kurelid <henrik@kurelid.se>
6 * 7 *
7 * This program is free software; you can redistribute it and/or 8 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as 9 * modify it under the terms of the GNU General Public License as
@@ -18,7 +19,6 @@
18#include <linux/time.h> 19#include <linux/time.h>
19#include <linux/errno.h> 20#include <linux/errno.h>
20#include <linux/interrupt.h> 21#include <linux/interrupt.h>
21#include <linux/semaphore.h>
22#include <ieee1394_hotplug.h> 22#include <ieee1394_hotplug.h>
23#include <nodemgr.h> 23#include <nodemgr.h>
24#include <highlevel.h> 24#include <highlevel.h>
@@ -79,11 +79,6 @@ static void firesat_add_host(struct hpsb_host *host);
79static void firesat_remove_host(struct hpsb_host *host); 79static void firesat_remove_host(struct hpsb_host *host);
80static void firesat_host_reset(struct hpsb_host *host); 80static void firesat_host_reset(struct hpsb_host *host);
81 81
82/*
83static void iso_receive(struct hpsb_host *host, int channel, quadlet_t *data,
84 size_t length);
85*/
86
87static void fcp_request(struct hpsb_host *host, 82static void fcp_request(struct hpsb_host *host,
88 int nodeid, 83 int nodeid,
89 int direction, 84 int direction,
@@ -96,7 +91,6 @@ static struct hpsb_highlevel firesat_highlevel = {
96 .add_host = firesat_add_host, 91 .add_host = firesat_add_host,
97 .remove_host = firesat_remove_host, 92 .remove_host = firesat_remove_host,
98 .host_reset = firesat_host_reset, 93 .host_reset = firesat_host_reset,
99// FIXME .iso_receive = iso_receive,
100 .fcp_request = fcp_request, 94 .fcp_request = fcp_request,
101}; 95};
102 96
@@ -127,100 +121,6 @@ static void firesat_host_reset(struct hpsb_host *host)
127 printk(KERN_INFO "FireSAT host_reset (nodeid = 0x%x, hosts active = %d)\n",host->node_id,host->nodes_active); 121 printk(KERN_INFO "FireSAT host_reset (nodeid = 0x%x, hosts active = %d)\n",host->node_id,host->nodes_active);
128} 122}
129 123
130struct firewireheader {
131 union {
132 struct {
133 unsigned char tcode:4;
134 unsigned char sy:4;
135 unsigned char tag:2;
136 unsigned char channel:6;
137
138 unsigned char length_l;
139 unsigned char length_h;
140 } hdr;
141 unsigned long val;
142 };
143};
144
145struct CIPHeader {
146 union {
147 struct {
148 unsigned char syncbits:2;
149 unsigned char sid:6;
150 unsigned char dbs;
151 unsigned char fn:2;
152 unsigned char qpc:3;
153 unsigned char sph:1;
154 unsigned char rsv:2;
155 unsigned char dbc;
156 unsigned char syncbits2:2;
157 unsigned char fmt:6;
158 unsigned long fdf:24;
159 } cip;
160 unsigned long long val;
161 };
162};
163
164struct MPEG2Header {
165 union {
166 struct {
167 unsigned char sync; // must be 0x47
168 unsigned char transport_error_indicator:1;
169 unsigned char payload_unit_start_indicator:1;
170 unsigned char transport_priority:1;
171 unsigned short pid:13;
172 unsigned char transport_scrambling_control:2;
173 unsigned char adaption_field_control:2;
174 unsigned char continuity_counter:4;
175 } hdr;
176 unsigned long val;
177 };
178};
179
180#if 0
181static void iso_receive(struct hpsb_host *host,
182 int channel,
183 quadlet_t *data,
184 size_t length)
185{
186 struct firesat *firesat = NULL;
187 struct firesat *firesat_entry;
188 unsigned long flags;
189
190// printk(KERN_INFO "FireSAT iso_receive: channel %d, length = %d\n", channel, length);
191
192 if (length <= 12)
193 return; // ignore empty packets
194 else {
195
196 spin_lock_irqsave(&firesat_list_lock, flags);
197 list_for_each_entry(firesat_entry,&firesat_list,list) {
198 if(firesat_entry->host == host && firesat_entry->isochannel == channel) {
199 firesat=firesat_entry;
200 break;
201 }
202 }
203 spin_unlock_irqrestore(&firesat_list_lock, flags);
204
205 if (firesat) {
206 char *buf= ((char*)data) + sizeof(struct firewireheader)+sizeof(struct CIPHeader);
207 int count = (length-sizeof(struct CIPHeader)) / 192;
208
209// printk(KERN_INFO "%s: length = %u\n data[0] = %08x\n data[1] = %08x\n data[2] = %08x\n data[3] = %08x\n data[4] = %08x\n",__func__, length, data[0],data[1],data[2],data[3],data[4]);
210
211 while (count--) {
212
213 if (buf[sizeof(quadlet_t) /*timestamp*/] == 0x47)
214 dvb_dmx_swfilter_packets(&firesat->demux, &buf[sizeof(quadlet_t)], 1);
215 else
216 printk("%s: invalid packet, skipping\n", __func__);
217 buf += 188 + sizeof (quadlet_t) /* timestamp */;
218 }
219 }
220 }
221}
222#endif
223
224static void fcp_request(struct hpsb_host *host, 124static void fcp_request(struct hpsb_host *host,
225 int nodeid, 125 int nodeid,
226 int direction, 126 int direction,
@@ -251,7 +151,9 @@ static void fcp_request(struct hpsb_host *host,
251 AVCRecv(firesat,data,length); 151 AVCRecv(firesat,data,length);
252 else 152 else
253 printk("%s: received fcp request from unknown source, ignored\n", __func__); 153 printk("%s: received fcp request from unknown source, ignored\n", __func__);
254 } // else ignore 154 }
155 else
156 printk("%s: received invalid fcp request, ignored\n", __func__);
255} 157}
256 158
257static int firesat_probe(struct device *dev) 159static int firesat_probe(struct device *dev)
@@ -260,7 +162,6 @@ static int firesat_probe(struct device *dev)
260 struct firesat *firesat; 162 struct firesat *firesat;
261 struct dvb_frontend *fe; 163 struct dvb_frontend *fe;
262 unsigned long flags; 164 unsigned long flags;
263 int result;
264 unsigned char subunitcount = 0xff, subunit; 165 unsigned char subunitcount = 0xff, subunit;
265 struct firesat **firesats = kmalloc(sizeof (void*) * 2,GFP_KERNEL); 166 struct firesat **firesats = kmalloc(sizeof (void*) * 2,GFP_KERNEL);
266 int kv_len; 167 int kv_len;
@@ -298,6 +199,7 @@ static int firesat_probe(struct device *dev)
298 firesat->isochannel = -1; 199 firesat->isochannel = -1;
299 firesat->tone = 0xff; 200 firesat->tone = 0xff;
300 firesat->voltage = 0xff; 201 firesat->voltage = 0xff;
202 firesat->fe = fe;
301 203
302 if (!(firesat->respfrm = kmalloc(sizeof (AVCRspFrm), GFP_KERNEL))) { 204 if (!(firesat->respfrm = kmalloc(sizeof (AVCRspFrm), GFP_KERNEL))) {
303 printk("%s: couldn't allocate memory.\n", __func__); 205 printk("%s: couldn't allocate memory.\n", __func__);
@@ -357,7 +259,7 @@ static int firesat_probe(struct device *dev)
357 } 259 }
358 kfree(kv_buf); 260 kfree(kv_buf);
359 261
360 if (AVCIdentifySubunit(firesat, NULL, (int*)&firesat->type, &firesat->has_ci)) { 262 if (AVCIdentifySubunit(firesat, NULL, (int*)&firesat->type)) {
361 printk("%s: cannot identify subunit %d\n", __func__, subunit); 263 printk("%s: cannot identify subunit %d\n", __func__, subunit);
362 spin_lock_irqsave(&firesat_list_lock, flags); 264 spin_lock_irqsave(&firesat_list_lock, flags);
363 list_del(&firesat->list); 265 list_del(&firesat->list);
@@ -382,7 +284,6 @@ static int firesat_probe(struct device *dev)
382static int firesat_remove(struct device *dev) 284static int firesat_remove(struct device *dev)
383{ 285{
384 struct unit_directory *ud = container_of(dev, struct unit_directory, device); 286 struct unit_directory *ud = container_of(dev, struct unit_directory, device);
385 struct dvb_frontend* fe;
386 struct firesat **firesats = ud->device.driver_data; 287 struct firesat **firesats = ud->device.driver_data;
387 int k; 288 int k;
388 unsigned long flags; 289 unsigned long flags;
@@ -390,18 +291,9 @@ static int firesat_remove(struct device *dev)
390 if (firesats) { 291 if (firesats) {
391 for (k = 0; k < 2; k++) 292 for (k = 0; k < 2; k++)
392 if (firesats[k]) { 293 if (firesats[k]) {
393 if (firesats[k]->has_ci)
394 firesat_ca_release(firesats[k]); 294 firesat_ca_release(firesats[k]);
395 295
396#if 0 296 dvb_unregister_frontend(firesats[k]->fe);
397 if (!(fe = kmalloc(sizeof (struct dvb_frontend), GFP_KERNEL))) {
398 fe->ops = firesat_ops;
399 fe->dvb = firesats[k]->adapter;
400
401 dvb_unregister_frontend(fe);
402 kfree(fe);
403 }
404#endif
405 dvb_net_release(&firesats[k]->dvbnet); 297 dvb_net_release(&firesats[k]->dvbnet);
406 firesats[k]->demux.dmx.close(&firesats[k]->demux.dmx); 298 firesats[k]->demux.dmx.close(&firesats[k]->demux.dmx);
407 firesats[k]->demux.dmx.remove_frontend(&firesats[k]->demux.dmx, &firesats[k]->frontend); 299 firesats[k]->demux.dmx.remove_frontend(&firesats[k]->demux.dmx, &firesats[k]->frontend);
@@ -413,6 +305,7 @@ static int firesat_remove(struct device *dev)
413 list_del(&firesats[k]->list); 305 list_del(&firesats[k]->list);
414 spin_unlock_irqrestore(&firesat_list_lock, flags); 306 spin_unlock_irqrestore(&firesat_list_lock, flags);
415 307
308 kfree(firesats[k]->fe);
416 kfree(firesats[k]->adapter); 309 kfree(firesats[k]->adapter);
417 kfree(firesats[k]->respfrm); 310 kfree(firesats[k]->respfrm);
418 kfree(firesats[k]); 311 kfree(firesats[k]);