aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/dvb/bt8xx/dst_ca.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/dvb/bt8xx/dst_ca.c')
-rw-r--r--drivers/media/dvb/bt8xx/dst_ca.c123
1 files changed, 69 insertions, 54 deletions
diff --git a/drivers/media/dvb/bt8xx/dst_ca.c b/drivers/media/dvb/bt8xx/dst_ca.c
index 6776a592045f..e6541aff3996 100644
--- a/drivers/media/dvb/bt8xx/dst_ca.c
+++ b/drivers/media/dvb/bt8xx/dst_ca.c
@@ -69,62 +69,53 @@ static int ca_set_pid(void)
69} 69}
70 70
71 71
72static int put_checksum(u8 *check_string, int length) 72static void put_checksum(u8 *check_string, int length)
73{ 73{
74 u8 i = 0, checksum = 0; 74 dprintk(verbose, DST_CA_DEBUG, 1, " Computing string checksum.");
75 75 dprintk(verbose, DST_CA_DEBUG, 1, " -> string length : 0x%02x", length);
76 dprintk(verbose, DST_CA_DEBUG, 1, " ========================= Checksum calculation ==========================="); 76 check_string[length] = dst_check_sum (check_string, length);
77 dprintk(verbose, DST_CA_DEBUG, 1, " String Length=[0x%02x]", length); 77 dprintk(verbose, DST_CA_DEBUG, 1, " -> checksum : 0x%02x", check_string[length]);
78 dprintk(verbose, DST_CA_DEBUG, 1, " String=[");
79
80 while (i < length) {
81 dprintk(verbose, DST_CA_DEBUG, 0, " %02x", check_string[i]);
82 checksum += check_string[i];
83 i++;
84 }
85 dprintk(verbose, DST_CA_DEBUG, 0, " ]\n");
86 dprintk(verbose, DST_CA_DEBUG, 1, "Sum=[%02x]\n", checksum);
87 check_string[length] = ~checksum + 1;
88 dprintk(verbose, DST_CA_DEBUG, 1, " Checksum=[%02x]", check_string[length]);
89 dprintk(verbose, DST_CA_DEBUG, 1, " ==========================================================================");
90
91 return 0;
92} 78}
93 79
94static int dst_ci_command(struct dst_state* state, u8 * data, u8 *ca_string, u8 len, int read) 80static int dst_ci_command(struct dst_state* state, u8 * data, u8 *ca_string, u8 len, int read)
95{ 81{
96 u8 reply; 82 u8 reply;
97 83
84 down(&state->dst_mutex);
98 dst_comm_init(state); 85 dst_comm_init(state);
99 msleep(65); 86 msleep(65);
100 87
101 if (write_dst(state, data, len)) { 88 if (write_dst(state, data, len)) {
102 dprintk(verbose, DST_CA_INFO, 1, " Write not successful, trying to recover"); 89 dprintk(verbose, DST_CA_INFO, 1, " Write not successful, trying to recover");
103 dst_error_recovery(state); 90 dst_error_recovery(state);
104 return -1; 91 goto error;
105 } 92 }
106 if ((dst_pio_disable(state)) < 0) { 93 if ((dst_pio_disable(state)) < 0) {
107 dprintk(verbose, DST_CA_ERROR, 1, " DST PIO disable failed."); 94 dprintk(verbose, DST_CA_ERROR, 1, " DST PIO disable failed.");
108 return -1; 95 goto error;
109 } 96 }
110 if (read_dst(state, &reply, GET_ACK) < 0) { 97 if (read_dst(state, &reply, GET_ACK) < 0) {
111 dprintk(verbose, DST_CA_INFO, 1, " Read not successful, trying to recover"); 98 dprintk(verbose, DST_CA_INFO, 1, " Read not successful, trying to recover");
112 dst_error_recovery(state); 99 dst_error_recovery(state);
113 return -1; 100 goto error;
114 } 101 }
115 if (read) { 102 if (read) {
116 if (! dst_wait_dst_ready(state, LONG_DELAY)) { 103 if (! dst_wait_dst_ready(state, LONG_DELAY)) {
117 dprintk(verbose, DST_CA_NOTICE, 1, " 8820 not ready"); 104 dprintk(verbose, DST_CA_NOTICE, 1, " 8820 not ready");
118 return -1; 105 goto error;
119 } 106 }
120 if (read_dst(state, ca_string, 128) < 0) { /* Try to make this dynamic */ 107 if (read_dst(state, ca_string, 128) < 0) { /* Try to make this dynamic */
121 dprintk(verbose, DST_CA_INFO, 1, " Read not successful, trying to recover"); 108 dprintk(verbose, DST_CA_INFO, 1, " Read not successful, trying to recover");
122 dst_error_recovery(state); 109 dst_error_recovery(state);
123 return -1; 110 goto error;
124 } 111 }
125 } 112 }
126 113 up(&state->dst_mutex);
127 return 0; 114 return 0;
115
116error:
117 up(&state->dst_mutex);
118 return -EIO;
128} 119}
129 120
130 121
@@ -166,7 +157,7 @@ static int ca_get_app_info(struct dst_state *state)
166 return 0; 157 return 0;
167} 158}
168 159
169static int ca_get_slot_caps(struct dst_state *state, struct ca_caps *p_ca_caps, void *arg) 160static int ca_get_slot_caps(struct dst_state *state, struct ca_caps *p_ca_caps, void __user *arg)
170{ 161{
171 int i; 162 int i;
172 u8 slot_cap[256]; 163 u8 slot_cap[256];
@@ -192,25 +183,25 @@ static int ca_get_slot_caps(struct dst_state *state, struct ca_caps *p_ca_caps,
192 p_ca_caps->descr_num = slot_cap[7]; 183 p_ca_caps->descr_num = slot_cap[7];
193 p_ca_caps->descr_type = 1; 184 p_ca_caps->descr_type = 1;
194 185
195 if (copy_to_user((struct ca_caps *)arg, p_ca_caps, sizeof (struct ca_caps))) 186 if (copy_to_user(arg, p_ca_caps, sizeof (struct ca_caps)))
196 return -EFAULT; 187 return -EFAULT;
197 188
198 return 0; 189 return 0;
199} 190}
200 191
201/* Need some more work */ 192/* Need some more work */
202static int ca_get_slot_descr(struct dst_state *state, struct ca_msg *p_ca_message, void *arg) 193static int ca_get_slot_descr(struct dst_state *state, struct ca_msg *p_ca_message, void __user *arg)
203{ 194{
204 return -EOPNOTSUPP; 195 return -EOPNOTSUPP;
205} 196}
206 197
207 198
208static int ca_get_slot_info(struct dst_state *state, struct ca_slot_info *p_ca_slot_info, void *arg) 199static int ca_get_slot_info(struct dst_state *state, struct ca_slot_info *p_ca_slot_info, void __user *arg)
209{ 200{
210 int i; 201 int i;
211 static u8 slot_command[8] = {0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff}; 202 static u8 slot_command[8] = {0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff};
212 203
213 u8 *slot_info = state->rxbuffer; 204 u8 *slot_info = state->messages;
214 205
215 put_checksum(&slot_command[0], 7); 206 put_checksum(&slot_command[0], 7);
216 if ((dst_put_ci(state, slot_command, sizeof (slot_command), slot_info, GET_REPLY)) < 0) { 207 if ((dst_put_ci(state, slot_command, sizeof (slot_command), slot_info, GET_REPLY)) < 0) {
@@ -238,19 +229,19 @@ static int ca_get_slot_info(struct dst_state *state, struct ca_slot_info *p_ca_s
238 } else 229 } else
239 p_ca_slot_info->flags = 0; 230 p_ca_slot_info->flags = 0;
240 231
241 if (copy_to_user((struct ca_slot_info *)arg, p_ca_slot_info, sizeof (struct ca_slot_info))) 232 if (copy_to_user(arg, p_ca_slot_info, sizeof (struct ca_slot_info)))
242 return -EFAULT; 233 return -EFAULT;
243 234
244 return 0; 235 return 0;
245} 236}
246 237
247 238
248static int ca_get_message(struct dst_state *state, struct ca_msg *p_ca_message, void *arg) 239static int ca_get_message(struct dst_state *state, struct ca_msg *p_ca_message, void __user *arg)
249{ 240{
250 u8 i = 0; 241 u8 i = 0;
251 u32 command = 0; 242 u32 command = 0;
252 243
253 if (copy_from_user(p_ca_message, (void *)arg, sizeof (struct ca_msg))) 244 if (copy_from_user(p_ca_message, arg, sizeof (struct ca_msg)))
254 return -EFAULT; 245 return -EFAULT;
255 246
256 if (p_ca_message->msg) { 247 if (p_ca_message->msg) {
@@ -266,7 +257,7 @@ static int ca_get_message(struct dst_state *state, struct ca_msg *p_ca_message,
266 switch (command) { 257 switch (command) {
267 case CA_APP_INFO: 258 case CA_APP_INFO:
268 memcpy(p_ca_message->msg, state->messages, 128); 259 memcpy(p_ca_message->msg, state->messages, 128);
269 if (copy_to_user((void *)arg, p_ca_message, sizeof (struct ca_msg)) ) 260 if (copy_to_user(arg, p_ca_message, sizeof (struct ca_msg)) )
270 return -EFAULT; 261 return -EFAULT;
271 break; 262 break;
272 } 263 }
@@ -315,7 +306,7 @@ static int write_to_8820(struct dst_state *state, struct ca_msg *hw_buffer, u8 l
315 return 0; 306 return 0;
316} 307}
317 308
318u32 asn_1_decode(u8 *asn_1_array) 309static u32 asn_1_decode(u8 *asn_1_array)
319{ 310{
320 u8 length_field = 0, word_count = 0, count = 0; 311 u8 length_field = 0, word_count = 0, count = 0;
321 u32 length = 0; 312 u32 length = 0;
@@ -328,7 +319,8 @@ u32 asn_1_decode(u8 *asn_1_array)
328 } else { 319 } else {
329 word_count = length_field & 0x7f; 320 word_count = length_field & 0x7f;
330 for (count = 0; count < word_count; count++) { 321 for (count = 0; count < word_count; count++) {
331 length = (length | asn_1_array[count + 1]) << 8; 322 length = length << 8;
323 length += asn_1_array[count + 1];
332 dprintk(verbose, DST_CA_DEBUG, 1, " Length=[%04x]", length); 324 dprintk(verbose, DST_CA_DEBUG, 1, " Length=[%04x]", length);
333 } 325 }
334 } 326 }
@@ -399,13 +391,14 @@ static int dst_check_ca_pmt(struct dst_state *state, struct ca_msg *p_ca_message
399 return 0; 391 return 0;
400} 392}
401 393
402static int ca_send_message(struct dst_state *state, struct ca_msg *p_ca_message, void *arg) 394static int ca_send_message(struct dst_state *state, struct ca_msg *p_ca_message, void __user *arg)
403{ 395{
404 int i = 0; 396 int i = 0;
405 unsigned int ca_message_header_len; 397 unsigned int ca_message_header_len;
406 398
407 u32 command = 0; 399 u32 command = 0;
408 struct ca_msg *hw_buffer; 400 struct ca_msg *hw_buffer;
401 int result = 0;
409 402
410 if ((hw_buffer = (struct ca_msg *) kmalloc(sizeof (struct ca_msg), GFP_KERNEL)) == NULL) { 403 if ((hw_buffer = (struct ca_msg *) kmalloc(sizeof (struct ca_msg), GFP_KERNEL)) == NULL) {
411 dprintk(verbose, DST_CA_ERROR, 1, " Memory allocation failure"); 404 dprintk(verbose, DST_CA_ERROR, 1, " Memory allocation failure");
@@ -413,8 +406,11 @@ static int ca_send_message(struct dst_state *state, struct ca_msg *p_ca_message,
413 } 406 }
414 dprintk(verbose, DST_CA_DEBUG, 1, " "); 407 dprintk(verbose, DST_CA_DEBUG, 1, " ");
415 408
416 if (copy_from_user(p_ca_message, (void *)arg, sizeof (struct ca_msg))) 409 if (copy_from_user(p_ca_message, (void *)arg, sizeof (struct ca_msg))) {
417 return -EFAULT; 410 result = -EFAULT;
411 goto free_mem_and_exit;
412 }
413
418 414
419 if (p_ca_message->msg) { 415 if (p_ca_message->msg) {
420 ca_message_header_len = p_ca_message->length; /* Restore it back when you are done */ 416 ca_message_header_len = p_ca_message->length; /* Restore it back when you are done */
@@ -433,7 +429,8 @@ static int ca_send_message(struct dst_state *state, struct ca_msg *p_ca_message,
433 dprintk(verbose, DST_CA_DEBUG, 1, "Command = SEND_CA_PMT"); 429 dprintk(verbose, DST_CA_DEBUG, 1, "Command = SEND_CA_PMT");
434 if ((ca_set_pmt(state, p_ca_message, hw_buffer, 0, 0)) < 0) { // code simplification started 430 if ((ca_set_pmt(state, p_ca_message, hw_buffer, 0, 0)) < 0) { // code simplification started
435 dprintk(verbose, DST_CA_ERROR, 1, " -->CA_PMT Failed !"); 431 dprintk(verbose, DST_CA_ERROR, 1, " -->CA_PMT Failed !");
436 return -1; 432 result = -1;
433 goto free_mem_and_exit;
437 } 434 }
438 dprintk(verbose, DST_CA_INFO, 1, " -->CA_PMT Success !"); 435 dprintk(verbose, DST_CA_INFO, 1, " -->CA_PMT Success !");
439 break; 436 break;
@@ -442,7 +439,8 @@ static int ca_send_message(struct dst_state *state, struct ca_msg *p_ca_message,
442 /* Have to handle the 2 basic types of cards here */ 439 /* Have to handle the 2 basic types of cards here */
443 if ((dst_check_ca_pmt(state, p_ca_message, hw_buffer)) < 0) { 440 if ((dst_check_ca_pmt(state, p_ca_message, hw_buffer)) < 0) {
444 dprintk(verbose, DST_CA_ERROR, 1, " -->CA_PMT_REPLY Failed !"); 441 dprintk(verbose, DST_CA_ERROR, 1, " -->CA_PMT_REPLY Failed !");
445 return -1; 442 result = -1;
443 goto free_mem_and_exit;
446 } 444 }
447 dprintk(verbose, DST_CA_INFO, 1, " -->CA_PMT_REPLY Success !"); 445 dprintk(verbose, DST_CA_INFO, 1, " -->CA_PMT_REPLY Success !");
448 break; 446 break;
@@ -451,22 +449,28 @@ static int ca_send_message(struct dst_state *state, struct ca_msg *p_ca_message,
451 449
452 if ((ca_get_app_info(state)) < 0) { 450 if ((ca_get_app_info(state)) < 0) {
453 dprintk(verbose, DST_CA_ERROR, 1, " -->CA_APP_INFO_ENQUIRY Failed !"); 451 dprintk(verbose, DST_CA_ERROR, 1, " -->CA_APP_INFO_ENQUIRY Failed !");
454 return -1; 452 result = -1;
453 goto free_mem_and_exit;
455 } 454 }
456 dprintk(verbose, DST_CA_INFO, 1, " -->CA_APP_INFO_ENQUIRY Success !"); 455 dprintk(verbose, DST_CA_INFO, 1, " -->CA_APP_INFO_ENQUIRY Success !");
457 break; 456 break;
458 } 457 }
459 } 458 }
460 return 0; 459free_mem_and_exit:
460 kfree (hw_buffer);
461
462 return result;
461} 463}
462 464
463static int dst_ca_ioctl(struct inode *inode, struct file *file, unsigned int cmd, void *arg) 465static int dst_ca_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long ioctl_arg)
464{ 466{
465 struct dvb_device* dvbdev = (struct dvb_device*) file->private_data; 467 struct dvb_device* dvbdev = (struct dvb_device*) file->private_data;
466 struct dst_state* state = (struct dst_state*) dvbdev->priv; 468 struct dst_state* state = (struct dst_state*) dvbdev->priv;
467 struct ca_slot_info *p_ca_slot_info; 469 struct ca_slot_info *p_ca_slot_info;
468 struct ca_caps *p_ca_caps; 470 struct ca_caps *p_ca_caps;
469 struct ca_msg *p_ca_message; 471 struct ca_msg *p_ca_message;
472 void __user *arg = (void __user *)ioctl_arg;
473 int result = 0;
470 474
471 if ((p_ca_message = (struct ca_msg *) kmalloc(sizeof (struct ca_msg), GFP_KERNEL)) == NULL) { 475 if ((p_ca_message = (struct ca_msg *) kmalloc(sizeof (struct ca_msg), GFP_KERNEL)) == NULL) {
472 dprintk(verbose, DST_CA_ERROR, 1, " Memory allocation failure"); 476 dprintk(verbose, DST_CA_ERROR, 1, " Memory allocation failure");
@@ -486,14 +490,16 @@ static int dst_ca_ioctl(struct inode *inode, struct file *file, unsigned int cmd
486 dprintk(verbose, DST_CA_INFO, 1, " Sending message"); 490 dprintk(verbose, DST_CA_INFO, 1, " Sending message");
487 if ((ca_send_message(state, p_ca_message, arg)) < 0) { 491 if ((ca_send_message(state, p_ca_message, arg)) < 0) {
488 dprintk(verbose, DST_CA_ERROR, 1, " -->CA_SEND_MSG Failed !"); 492 dprintk(verbose, DST_CA_ERROR, 1, " -->CA_SEND_MSG Failed !");
489 return -1; 493 result = -1;
494 goto free_mem_and_exit;
490 } 495 }
491 break; 496 break;
492 case CA_GET_MSG: 497 case CA_GET_MSG:
493 dprintk(verbose, DST_CA_INFO, 1, " Getting message"); 498 dprintk(verbose, DST_CA_INFO, 1, " Getting message");
494 if ((ca_get_message(state, p_ca_message, arg)) < 0) { 499 if ((ca_get_message(state, p_ca_message, arg)) < 0) {
495 dprintk(verbose, DST_CA_ERROR, 1, " -->CA_GET_MSG Failed !"); 500 dprintk(verbose, DST_CA_ERROR, 1, " -->CA_GET_MSG Failed !");
496 return -1; 501 result = -1;
502 goto free_mem_and_exit;
497 } 503 }
498 dprintk(verbose, DST_CA_INFO, 1, " -->CA_GET_MSG Success !"); 504 dprintk(verbose, DST_CA_INFO, 1, " -->CA_GET_MSG Success !");
499 break; 505 break;
@@ -506,7 +512,8 @@ static int dst_ca_ioctl(struct inode *inode, struct file *file, unsigned int cmd
506 dprintk(verbose, DST_CA_INFO, 1, " Getting Slot info"); 512 dprintk(verbose, DST_CA_INFO, 1, " Getting Slot info");
507 if ((ca_get_slot_info(state, p_ca_slot_info, arg)) < 0) { 513 if ((ca_get_slot_info(state, p_ca_slot_info, arg)) < 0) {
508 dprintk(verbose, DST_CA_ERROR, 1, " -->CA_GET_SLOT_INFO Failed !"); 514 dprintk(verbose, DST_CA_ERROR, 1, " -->CA_GET_SLOT_INFO Failed !");
509 return -1; 515 result = -1;
516 goto free_mem_and_exit;
510 } 517 }
511 dprintk(verbose, DST_CA_INFO, 1, " -->CA_GET_SLOT_INFO Success !"); 518 dprintk(verbose, DST_CA_INFO, 1, " -->CA_GET_SLOT_INFO Success !");
512 break; 519 break;
@@ -514,7 +521,8 @@ static int dst_ca_ioctl(struct inode *inode, struct file *file, unsigned int cmd
514 dprintk(verbose, DST_CA_INFO, 1, " Getting Slot capabilities"); 521 dprintk(verbose, DST_CA_INFO, 1, " Getting Slot capabilities");
515 if ((ca_get_slot_caps(state, p_ca_caps, arg)) < 0) { 522 if ((ca_get_slot_caps(state, p_ca_caps, arg)) < 0) {
516 dprintk(verbose, DST_CA_ERROR, 1, " -->CA_GET_CAP Failed !"); 523 dprintk(verbose, DST_CA_ERROR, 1, " -->CA_GET_CAP Failed !");
517 return -1; 524 result = -1;
525 goto free_mem_and_exit;
518 } 526 }
519 dprintk(verbose, DST_CA_INFO, 1, " -->CA_GET_CAP Success !"); 527 dprintk(verbose, DST_CA_INFO, 1, " -->CA_GET_CAP Success !");
520 break; 528 break;
@@ -522,7 +530,8 @@ static int dst_ca_ioctl(struct inode *inode, struct file *file, unsigned int cmd
522 dprintk(verbose, DST_CA_INFO, 1, " Getting descrambler description"); 530 dprintk(verbose, DST_CA_INFO, 1, " Getting descrambler description");
523 if ((ca_get_slot_descr(state, p_ca_message, arg)) < 0) { 531 if ((ca_get_slot_descr(state, p_ca_message, arg)) < 0) {
524 dprintk(verbose, DST_CA_ERROR, 1, " -->CA_GET_DESCR_INFO Failed !"); 532 dprintk(verbose, DST_CA_ERROR, 1, " -->CA_GET_DESCR_INFO Failed !");
525 return -1; 533 result = -1;
534 goto free_mem_and_exit;
526 } 535 }
527 dprintk(verbose, DST_CA_INFO, 1, " -->CA_GET_DESCR_INFO Success !"); 536 dprintk(verbose, DST_CA_INFO, 1, " -->CA_GET_DESCR_INFO Success !");
528 break; 537 break;
@@ -530,7 +539,8 @@ static int dst_ca_ioctl(struct inode *inode, struct file *file, unsigned int cmd
530 dprintk(verbose, DST_CA_INFO, 1, " Setting descrambler"); 539 dprintk(verbose, DST_CA_INFO, 1, " Setting descrambler");
531 if ((ca_set_slot_descr()) < 0) { 540 if ((ca_set_slot_descr()) < 0) {
532 dprintk(verbose, DST_CA_ERROR, 1, " -->CA_SET_DESCR Failed !"); 541 dprintk(verbose, DST_CA_ERROR, 1, " -->CA_SET_DESCR Failed !");
533 return -1; 542 result = -1;
543 goto free_mem_and_exit;
534 } 544 }
535 dprintk(verbose, DST_CA_INFO, 1, " -->CA_SET_DESCR Success !"); 545 dprintk(verbose, DST_CA_INFO, 1, " -->CA_SET_DESCR Success !");
536 break; 546 break;
@@ -538,14 +548,19 @@ static int dst_ca_ioctl(struct inode *inode, struct file *file, unsigned int cmd
538 dprintk(verbose, DST_CA_INFO, 1, " Setting PID"); 548 dprintk(verbose, DST_CA_INFO, 1, " Setting PID");
539 if ((ca_set_pid()) < 0) { 549 if ((ca_set_pid()) < 0) {
540 dprintk(verbose, DST_CA_ERROR, 1, " -->CA_SET_PID Failed !"); 550 dprintk(verbose, DST_CA_ERROR, 1, " -->CA_SET_PID Failed !");
541 return -1; 551 result = -1;
552 goto free_mem_and_exit;
542 } 553 }
543 dprintk(verbose, DST_CA_INFO, 1, " -->CA_SET_PID Success !"); 554 dprintk(verbose, DST_CA_INFO, 1, " -->CA_SET_PID Success !");
544 default: 555 default:
545 return -EOPNOTSUPP; 556 result = -EOPNOTSUPP;
546 }; 557 };
558 free_mem_and_exit:
559 kfree (p_ca_message);
560 kfree (p_ca_slot_info);
561 kfree (p_ca_caps);
547 562
548 return 0; 563 return result;
549} 564}
550 565
551static int dst_ca_open(struct inode *inode, struct file *file) 566static int dst_ca_open(struct inode *inode, struct file *file)
@@ -582,7 +597,7 @@ static int dst_ca_write(struct file *file, const char __user *buffer, size_t len
582 597
583static struct file_operations dst_ca_fops = { 598static struct file_operations dst_ca_fops = {
584 .owner = THIS_MODULE, 599 .owner = THIS_MODULE,
585 .ioctl = (void *)dst_ca_ioctl, 600 .ioctl = dst_ca_ioctl,
586 .open = dst_ca_open, 601 .open = dst_ca_open,
587 .release = dst_ca_release, 602 .release = dst_ca_release,
588 .read = dst_ca_read, 603 .read = dst_ca_read,