diff options
author | Henrik Kurelid <henke@kurelid.se> | 2008-08-01 04:00:45 -0400 |
---|---|---|
committer | Stefan Richter <stefanr@s5r6.in-berlin.de> | 2009-02-24 08:51:26 -0500 |
commit | df4846c35247a0d038c5359d502cddd59d04bc40 (patch) | |
tree | 40c58c28c389f238e3d26230f264782e8f4bcb1e /drivers/media/dvb/firesat/firesat_1394.c | |
parent | 2c22861459f094e899c034515a9bb92ac307ceae (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.c | 123 |
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); | |||
79 | static void firesat_remove_host(struct hpsb_host *host); | 79 | static void firesat_remove_host(struct hpsb_host *host); |
80 | static void firesat_host_reset(struct hpsb_host *host); | 80 | static void firesat_host_reset(struct hpsb_host *host); |
81 | 81 | ||
82 | /* | ||
83 | static void iso_receive(struct hpsb_host *host, int channel, quadlet_t *data, | ||
84 | size_t length); | ||
85 | */ | ||
86 | |||
87 | static void fcp_request(struct hpsb_host *host, | 82 | static 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 | ||
130 | struct 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 | |||
145 | struct 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 | |||
164 | struct 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 | ||
181 | static 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 | |||
224 | static void fcp_request(struct hpsb_host *host, | 124 | static 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 | ||
257 | static int firesat_probe(struct device *dev) | 159 | static 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) | |||
382 | static int firesat_remove(struct device *dev) | 284 | static 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]); |