aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/dvb/firesat/firesat-ci.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-ci.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-ci.c')
-rw-r--r--drivers/media/dvb/firesat/firesat-ci.c244
1 files changed, 71 insertions, 173 deletions
diff --git a/drivers/media/dvb/firesat/firesat-ci.c b/drivers/media/dvb/firesat/firesat-ci.c
index 3ef25cc4bfdb..0deb47eefa10 100644
--- a/drivers/media/dvb/firesat/firesat-ci.c
+++ b/drivers/media/dvb/firesat/firesat-ci.c
@@ -20,29 +20,18 @@
20#include "firesat.h" 20#include "firesat.h"
21#include "firesat-ci.h" 21#include "firesat-ci.h"
22 22
23static unsigned int ca_debug = 0;
24module_param(ca_debug, int, 0644);
25MODULE_PARM_DESC(ca_debug, "debug logging of ca system, default is 0 (no)");
26
27static int firesat_ca_ready(ANTENNA_INPUT_INFO *info) 23static int firesat_ca_ready(ANTENNA_INPUT_INFO *info)
28{ 24{
29 if (ca_debug != 0)
30 printk("%s: CaMmi=%d, CaInit=%d, CaError=%d, CaDvb=%d, "
31 "CaModule=%d, CaAppInfo=%d, CaDateTime=%d, "
32 "CaPmt=%d\n", __func__, info->CaMmi,
33 info->CaInitializationStatus, info->CaErrorFlag,
34 info->CaDvbFlag, info->CaModulePresentStatus,
35 info->CaApplicationInfo,
36 info->CaDateTimeRequest, info->CaPmtReply);
37 return info->CaInitializationStatus == 1 && 25 return info->CaInitializationStatus == 1 &&
38 info->CaErrorFlag == 0 && 26 info->CaErrorFlag == 0 &&
39 info->CaDvbFlag == 1 && 27 info->CaDvbFlag == 1 &&
40 info->CaModulePresentStatus == 1; 28 info->CaModulePresentStatus == 1;
41} 29}
42 30
43static int firesat_get_ca_flags(ANTENNA_INPUT_INFO *info) 31static int firesat_get_ca_flags(ANTENNA_INPUT_INFO *info)
44{ 32{
45 int flags = 0; 33 int flags = 0;
34
46 if (info->CaModulePresentStatus == 1) 35 if (info->CaModulePresentStatus == 1)
47 flags |= CA_CI_MODULE_PRESENT; 36 flags |= CA_CI_MODULE_PRESENT;
48 if (info->CaInitializationStatus == 1 && 37 if (info->CaInitializationStatus == 1 &&
@@ -54,103 +43,63 @@ static int firesat_get_ca_flags(ANTENNA_INPUT_INFO *info)
54 43
55static int firesat_ca_reset(struct firesat *firesat) 44static int firesat_ca_reset(struct firesat *firesat)
56{ 45{
57 if (ca_debug) 46 return avc_ca_reset(firesat) ? -EFAULT : 0;
58 printk(KERN_INFO "%s: ioctl CA_RESET\n", __func__);
59 if (avc_ca_reset(firesat))
60 return -EFAULT;
61 return 0;
62} 47}
63 48
64static int firesat_ca_get_caps(struct firesat *firesat, void *arg) 49static int firesat_ca_get_caps(void *arg)
65{ 50{
66 struct ca_caps *cap_p = (struct ca_caps*)arg; 51 struct ca_caps *cap = arg;
67 int err = 0; 52
68 53 cap->slot_num = 1;
69 cap_p->slot_num = 1; 54 cap->slot_type = CA_CI;
70 cap_p->slot_type = CA_CI; 55 cap->descr_num = 1;
71 cap_p->descr_num = 1; 56 cap->descr_type = CA_ECD;
72 cap_p->descr_type = CA_ECD; 57 return 0;
73 if (ca_debug)
74 printk(KERN_INFO "%s: ioctl CA_GET_CAP\n", __func__);
75 return err;
76} 58}
77 59
78static int firesat_ca_get_slot_info(struct firesat *firesat, void *arg) 60static int firesat_ca_get_slot_info(struct firesat *firesat, void *arg)
79{ 61{
80 ANTENNA_INPUT_INFO info; 62 ANTENNA_INPUT_INFO info;
81 struct ca_slot_info *slot_p = (struct ca_slot_info*)arg; 63 struct ca_slot_info *slot = arg;
82 64
83 if (ca_debug) 65 if (avc_tuner_status(firesat, &info))
84 printk(KERN_INFO "%s: ioctl CA_GET_SLOT_INFO on slot %d.\n",
85 __func__, slot_p->num);
86 if (AVCTunerStatus(firesat, &info))
87 return -EFAULT; 66 return -EFAULT;
88 67
89 if (slot_p->num == 0) { 68 if (slot->num != 0)
90 slot_p->type = CA_CI;
91 slot_p->flags = firesat_get_ca_flags(&info);
92 }
93 else {
94 return -EFAULT; 69 return -EFAULT;
95 } 70
71 slot->type = CA_CI;
72 slot->flags = firesat_get_ca_flags(&info);
96 return 0; 73 return 0;
97} 74}
98 75
99static int firesat_ca_app_info(struct firesat *firesat, void *arg) 76static int firesat_ca_app_info(struct firesat *firesat, void *arg)
100{ 77{
101 struct ca_msg *reply_p = (struct ca_msg*)arg; 78 struct ca_msg *reply = arg;
102 int i;
103 79
104 if (avc_ca_app_info(firesat, reply_p->msg, &reply_p->length)) 80 return
105 return -EFAULT; 81 avc_ca_app_info(firesat, reply->msg, &reply->length) ? -EFAULT : 0;
106 if (ca_debug) {
107 printk(KERN_INFO "%s: Creating TAG_APP_INFO message:",
108 __func__);
109 for (i = 0; i < reply_p->length; i++)
110 printk("0x%02X, ", (unsigned char)reply_p->msg[i]);
111 printk("\n");
112 }
113 return 0;
114} 82}
115 83
116static int firesat_ca_info(struct firesat *firesat, void *arg) 84static int firesat_ca_info(struct firesat *firesat, void *arg)
117{ 85{
118 struct ca_msg *reply_p = (struct ca_msg*)arg; 86 struct ca_msg *reply = arg;
119 int i;
120 87
121 if (avc_ca_info(firesat, reply_p->msg, &reply_p->length)) 88 return avc_ca_info(firesat, reply->msg, &reply->length) ? -EFAULT : 0;
122 return -EFAULT;
123 if (ca_debug) {
124 printk(KERN_INFO "%s: Creating TAG_CA_INFO message:",
125 __func__);
126 for (i = 0; i < reply_p->length; i++)
127 printk("0x%02X, ", (unsigned char)reply_p->msg[i]);
128 printk("\n");
129 }
130 return 0;
131} 89}
132 90
133static int firesat_ca_get_mmi(struct firesat *firesat, void *arg) 91static int firesat_ca_get_mmi(struct firesat *firesat, void *arg)
134{ 92{
135 struct ca_msg *reply_p = (struct ca_msg*)arg; 93 struct ca_msg *reply = arg;
136 int i;
137 94
138 if (avc_ca_get_mmi(firesat, reply_p->msg, &reply_p->length)) 95 return
139 return -EFAULT; 96 avc_ca_get_mmi(firesat, reply->msg, &reply->length) ? -EFAULT : 0;
140 if (ca_debug) {
141 printk(KERN_INFO "%s: Creating MMI reply INFO message:",
142 __func__);
143 for (i = 0; i < reply_p->length; i++)
144 printk("0x%02X, ", (unsigned char)reply_p->msg[i]);
145 printk("\n");
146 }
147 return 0;
148} 97}
149 98
150static int firesat_ca_get_msg(struct firesat *firesat, void *arg) 99static int firesat_ca_get_msg(struct firesat *firesat, void *arg)
151{ 100{
152 int err;
153 ANTENNA_INPUT_INFO info; 101 ANTENNA_INPUT_INFO info;
102 int err;
154 103
155 switch (firesat->ca_last_command) { 104 switch (firesat->ca_last_command) {
156 case TAG_APP_INFO_ENQUIRY: 105 case TAG_APP_INFO_ENQUIRY:
@@ -160,11 +109,10 @@ static int firesat_ca_get_msg(struct firesat *firesat, void *arg)
160 err = firesat_ca_info(firesat, arg); 109 err = firesat_ca_info(firesat, arg);
161 break; 110 break;
162 default: 111 default:
163 if (AVCTunerStatus(firesat, &info)) 112 if (avc_tuner_status(firesat, &info))
164 err = -EFAULT; 113 err = -EFAULT;
165 else if (info.CaMmi == 1) { 114 else if (info.CaMmi == 1)
166 err = firesat_ca_get_mmi(firesat, arg); 115 err = firesat_ca_get_mmi(firesat, arg);
167 }
168 else { 116 else {
169 printk(KERN_INFO "%s: Unhandled message 0x%08X\n", 117 printk(KERN_INFO "%s: Unhandled message 0x%08X\n",
170 __func__, firesat->ca_last_command); 118 __func__, firesat->ca_last_command);
@@ -177,51 +125,39 @@ static int firesat_ca_get_msg(struct firesat *firesat, void *arg)
177 125
178static int firesat_ca_pmt(struct firesat *firesat, void *arg) 126static int firesat_ca_pmt(struct firesat *firesat, void *arg)
179{ 127{
180 struct ca_msg *msg_p = (struct ca_msg*)arg; 128 struct ca_msg *msg = arg;
181 int data_pos; 129 int data_pos;
182 130
183 if (msg_p->msg[3] & 0x80) 131 if (msg->msg[3] & 0x80)
184 data_pos = (msg_p->msg[4] && 0x7F) + 4; 132 data_pos = (msg->msg[4] && 0x7F) + 4;
185 else 133 else
186 data_pos = 4; 134 data_pos = 4;
187 if (avc_ca_pmt(firesat, &msg_p->msg[data_pos], 135
188 msg_p->length - data_pos)) 136 return avc_ca_pmt(firesat, &msg->msg[data_pos],
189 return -EFAULT; 137 msg->length - data_pos) ? -EFAULT : 0;
190 return 0;
191} 138}
192 139
193static int firesat_ca_send_msg(struct firesat *firesat, void *arg) 140static int firesat_ca_send_msg(struct firesat *firesat, void *arg)
194{ 141{
142 struct ca_msg *msg = arg;
195 int err; 143 int err;
196 struct ca_msg *msg_p = (struct ca_msg*)arg;
197 144
198 // Do we need a semaphore for this? 145 /* Do we need a semaphore for this? */
199 firesat->ca_last_command = 146 firesat->ca_last_command =
200 (msg_p->msg[0] << 16) + (msg_p->msg[1] << 8) + msg_p->msg[2]; 147 (msg->msg[0] << 16) + (msg->msg[1] << 8) + msg->msg[2];
201 switch (firesat->ca_last_command) { 148 switch (firesat->ca_last_command) {
202 case TAG_CA_PMT: 149 case TAG_CA_PMT:
203 if (ca_debug != 0)
204 printk(KERN_INFO "%s: Message received: TAG_CA_PMT\n",
205 __func__);
206 err = firesat_ca_pmt(firesat, arg); 150 err = firesat_ca_pmt(firesat, arg);
207 break; 151 break;
208 case TAG_APP_INFO_ENQUIRY: 152 case TAG_APP_INFO_ENQUIRY:
209 // This is all handled in ca_get_msg 153 /* handled in ca_get_msg */
210 if (ca_debug != 0)
211 printk(KERN_INFO "%s: Message received: "
212 "TAG_APP_INFO_ENQUIRY\n", __func__);
213 err = 0; 154 err = 0;
214 break; 155 break;
215 case TAG_CA_INFO_ENQUIRY: 156 case TAG_CA_INFO_ENQUIRY:
216 // This is all handled in ca_get_msg 157 /* handled in ca_get_msg */
217 if (ca_debug != 0)
218 printk(KERN_INFO "%s: Message received: "
219 "TAG_CA_APP_INFO_ENQUIRY\n", __func__);
220 err = 0; 158 err = 0;
221 break; 159 break;
222 case TAG_ENTER_MENU: 160 case TAG_ENTER_MENU:
223 if (ca_debug != 0)
224 printk(KERN_INFO "%s: Entering CA menu.\n", __func__);
225 err = avc_ca_enter_menu(firesat); 161 err = avc_ca_enter_menu(firesat);
226 break; 162 break;
227 default: 163 default:
@@ -235,17 +171,17 @@ static int firesat_ca_send_msg(struct firesat *firesat, void *arg)
235static int firesat_ca_ioctl(struct inode *inode, struct file *file, 171static int firesat_ca_ioctl(struct inode *inode, struct file *file,
236 unsigned int cmd, void *arg) 172 unsigned int cmd, void *arg)
237{ 173{
238 struct dvb_device* dvbdev = (struct dvb_device*) file->private_data; 174 struct dvb_device *dvbdev = file->private_data;
239 struct firesat *firesat = dvbdev->priv; 175 struct firesat *firesat = dvbdev->priv;
240 int err;
241 ANTENNA_INPUT_INFO info; 176 ANTENNA_INPUT_INFO info;
177 int err;
242 178
243 switch(cmd) { 179 switch(cmd) {
244 case CA_RESET: 180 case CA_RESET:
245 err = firesat_ca_reset(firesat); 181 err = firesat_ca_reset(firesat);
246 break; 182 break;
247 case CA_GET_CAP: 183 case CA_GET_CAP:
248 err = firesat_ca_get_caps(firesat, arg); 184 err = firesat_ca_get_caps(arg);
249 break; 185 break;
250 case CA_GET_SLOT_INFO: 186 case CA_GET_SLOT_INFO:
251 err = firesat_ca_get_slot_info(firesat, arg); 187 err = firesat_ca_get_slot_info(firesat, arg);
@@ -262,90 +198,52 @@ static int firesat_ca_ioctl(struct inode *inode, struct file *file,
262 err = -EOPNOTSUPP; 198 err = -EOPNOTSUPP;
263 } 199 }
264 200
265 if (AVCTunerStatus(firesat, &info)) 201 /* FIXME Is this necessary? */
266 return err; 202 avc_tuner_status(firesat, &info);
267
268 firesat_ca_ready(&info);
269 203
270 return err; 204 return err;
271} 205}
272 206
273static int firesat_get_date_time_request(struct firesat *firesat)
274{
275 if (ca_debug)
276 printk(KERN_INFO "%s: Retrieving Time/Date request\n",
277 __func__);
278 if (avc_ca_get_time_date(firesat, &firesat->ca_time_interval))
279 return -EFAULT;
280 if (ca_debug)
281 printk(KERN_INFO "%s: Time/Date interval is %d\n",
282 __func__, firesat->ca_time_interval);
283
284 return 0;
285}
286
287static int firesat_ca_io_open(struct inode *inode, struct file *file)
288{
289 if (ca_debug != 0)
290 printk(KERN_INFO "%s\n",__func__);
291 return dvb_generic_open(inode, file);
292}
293
294static int firesat_ca_io_release(struct inode *inode, struct file *file)
295{
296 if (ca_debug != 0)
297 printk(KERN_INFO "%s\n",__func__);
298 return dvb_generic_release(inode, file);
299}
300
301static unsigned int firesat_ca_io_poll(struct file *file, poll_table *wait) 207static unsigned int firesat_ca_io_poll(struct file *file, poll_table *wait)
302{ 208{
303 if (ca_debug != 0)
304 printk(KERN_INFO "%s\n",__func__);
305 return POLLIN; 209 return POLLIN;
306} 210}
307 211
308static struct file_operations firesat_ca_fops = { 212static struct file_operations firesat_ca_fops = {
309 .owner = THIS_MODULE, 213 .owner = THIS_MODULE,
310 .read = NULL, // There is no low level read anymore 214 .ioctl = dvb_generic_ioctl,
311 .write = NULL, // There is no low level write anymore 215 .open = dvb_generic_open,
312 .ioctl = dvb_generic_ioctl, 216 .release = dvb_generic_release,
313 .open = firesat_ca_io_open, 217 .poll = firesat_ca_io_poll,
314 .release = firesat_ca_io_release,
315 .poll = firesat_ca_io_poll,
316}; 218};
317 219
318static struct dvb_device firesat_ca = { 220static struct dvb_device firesat_ca = {
319 .priv = NULL, 221 .users = 1,
320 .users = 1, 222 .readers = 1,
321 .readers = 1, 223 .writers = 1,
322 .writers = 1, 224 .fops = &firesat_ca_fops,
323 .fops = &firesat_ca_fops, 225 .kernel_ioctl = firesat_ca_ioctl,
324 .kernel_ioctl = firesat_ca_ioctl,
325}; 226};
326 227
327int firesat_ca_init(struct firesat *firesat) 228int firesat_ca_register(struct firesat *firesat)
328{ 229{
329 int err;
330 ANTENNA_INPUT_INFO info; 230 ANTENNA_INPUT_INFO info;
231 int err;
331 232
332 if (AVCTunerStatus(firesat, &info)) 233 if (avc_tuner_status(firesat, &info))
333 return -EINVAL; 234 return -EINVAL;
334 235
335 if (firesat_ca_ready(&info)) { 236 if (!firesat_ca_ready(&info))
336 err = dvb_register_device(firesat->adapter, 237 return -EFAULT;
337 &firesat->cadev, 238
338 &firesat_ca, firesat, 239 err = dvb_register_device(&firesat->adapter, &firesat->cadev,
339 DVB_DEVICE_CA); 240 &firesat_ca, firesat, DVB_DEVICE_CA);
340 241
341 if (info.CaApplicationInfo == 0) 242 if (info.CaApplicationInfo == 0)
342 printk(KERN_ERR "%s: CaApplicationInfo is not set.\n", 243 printk(KERN_ERR "%s: CaApplicationInfo is not set.\n",
343 __func__); 244 __func__);
344 if (info.CaDateTimeRequest == 1) 245 if (info.CaDateTimeRequest == 1)
345 firesat_get_date_time_request(firesat); 246 avc_ca_get_time_date(firesat, &firesat->ca_time_interval);
346 }
347 else
348 err = -EFAULT;
349 247
350 return err; 248 return err;
351} 249}
@@ -353,5 +251,5 @@ int firesat_ca_init(struct firesat *firesat)
353void firesat_ca_release(struct firesat *firesat) 251void firesat_ca_release(struct firesat *firesat)
354{ 252{
355 if (firesat->cadev) 253 if (firesat->cadev)
356 dvb_unregister_device(firesat->cadev); 254 dvb_unregister_device(firesat->cadev);
357} 255}