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.c115
1 files changed, 20 insertions, 95 deletions
diff --git a/drivers/media/dvb/bt8xx/dst_ca.c b/drivers/media/dvb/bt8xx/dst_ca.c
index bfaacd5fc20f..d2e0b1cb39d9 100644
--- a/drivers/media/dvb/bt8xx/dst_ca.c
+++ b/drivers/media/dvb/bt8xx/dst_ca.c
@@ -260,8 +260,6 @@ static int ca_get_slot_info(struct dst_state *state, struct ca_slot_info *p_ca_s
260} 260}
261 261
262 262
263
264
265static int ca_get_message(struct dst_state *state, struct ca_msg *p_ca_message, void *arg) 263static int ca_get_message(struct dst_state *state, struct ca_msg *p_ca_message, void *arg)
266{ 264{
267 u8 i = 0; 265 u8 i = 0;
@@ -298,10 +296,14 @@ static int ca_get_message(struct dst_state *state, struct ca_msg *p_ca_message,
298static int handle_dst_tag(struct dst_state *state, struct ca_msg *p_ca_message, struct ca_msg *hw_buffer, u32 length) 296static int handle_dst_tag(struct dst_state *state, struct ca_msg *p_ca_message, struct ca_msg *hw_buffer, u32 length)
299{ 297{
300 if (state->dst_hw_cap & DST_TYPE_HAS_SESSION) { 298 if (state->dst_hw_cap & DST_TYPE_HAS_SESSION) {
301 hw_buffer->msg[2] = p_ca_message->msg[1]; /* MSB */ 299 hw_buffer->msg[2] = p_ca_message->msg[1]; /* MSB */
302 hw_buffer->msg[3] = p_ca_message->msg[2]; /* LSB */ 300 hw_buffer->msg[3] = p_ca_message->msg[2]; /* LSB */
303 } 301 } else {
304 else { 302 if (length > 247) {
303 dprintk("%s: Message too long ! *** Bailing Out *** !\n", __FUNCTION__);
304 return -1;
305 }
306
305 hw_buffer->msg[0] = (length & 0xff) + 7; 307 hw_buffer->msg[0] = (length & 0xff) + 7;
306 hw_buffer->msg[1] = 0x40; 308 hw_buffer->msg[1] = 0x40;
307 hw_buffer->msg[2] = 0x03; 309 hw_buffer->msg[2] = 0x03;
@@ -309,6 +311,11 @@ static int handle_dst_tag(struct dst_state *state, struct ca_msg *p_ca_message,
309 hw_buffer->msg[4] = 0x03; 311 hw_buffer->msg[4] = 0x03;
310 hw_buffer->msg[5] = length & 0xff; 312 hw_buffer->msg[5] = length & 0xff;
311 hw_buffer->msg[6] = 0x00; 313 hw_buffer->msg[6] = 0x00;
314 /*
315 * Need to compute length for EN50221 section 8.3.2, for the time being
316 * assuming 8.3.2 is not applicable
317 */
318 memcpy(&hw_buffer->msg[7], &p_ca_message->msg[4], length);
312 } 319 }
313 return 0; 320 return 0;
314} 321}
@@ -348,15 +355,6 @@ u32 asn_1_decode(u8 *asn_1_array)
348 return length; 355 return length;
349} 356}
350 357
351static int init_buffer(u8 *buffer, u32 length)
352{
353 u32 i;
354 for (i = 0; i < length; i++)
355 buffer[i] = 0;
356
357 return 0;
358}
359
360static int debug_string(u8 *msg, u32 length, u32 offset) 358static int debug_string(u8 *msg, u32 length, u32 offset)
361{ 359{
362 u32 i; 360 u32 i;
@@ -369,95 +367,22 @@ static int debug_string(u8 *msg, u32 length, u32 offset)
369 return 0; 367 return 0;
370} 368}
371 369
372static int copy_string(u8 *destination, u8 *source, u32 dest_offset, u32 source_offset, u32 length)
373{
374 u32 i;
375 dprintk("%s: Copying [", __FUNCTION__);
376 for (i = 0; i < length; i++) {
377 destination[i + dest_offset] = source[i + source_offset];
378 dprintk(" %02x", source[i + source_offset]);
379 }
380 dprintk("]\n");
381
382 return i;
383}
384
385static int modify_4_bits(u8 *message, u32 pos)
386{
387 message[pos] &= 0x0f;
388
389 return 0;
390}
391
392
393
394static int ca_set_pmt(struct dst_state *state, struct ca_msg *p_ca_message, struct ca_msg *hw_buffer, u8 reply, u8 query) 370static int ca_set_pmt(struct dst_state *state, struct ca_msg *p_ca_message, struct ca_msg *hw_buffer, u8 reply, u8 query)
395{ 371{
396 u32 length = 0, count = 0; 372 u32 length = 0;
397 u8 asn_1_words, program_header_length; 373 u8 tag_length = 8;
398 u16 program_info_length = 0, es_info_length = 0;
399 u32 hw_offset = 0, buf_offset = 0, i;
400 u8 dst_tag_length;
401 374
402 length = asn_1_decode(&p_ca_message->msg[3]); 375 length = asn_1_decode(&p_ca_message->msg[3]);
403 dprintk("%s: CA Message length=[%d]\n", __FUNCTION__, length); 376 dprintk("%s: CA Message length=[%d]\n", __FUNCTION__, length);
404 dprintk("%s: ASN.1 ", __FUNCTION__); 377 dprintk("%s: ASN.1 ", __FUNCTION__);
405 debug_string(&p_ca_message->msg[4], length, 0); // length does not include tag and length 378 debug_string(&p_ca_message->msg[4], length, 0); /* length is excluding tag & length */
406 379
407 init_buffer(hw_buffer->msg, length); 380 memset(hw_buffer->msg, '\0', length);
408 handle_dst_tag(state, p_ca_message, hw_buffer, length); 381 handle_dst_tag(state, p_ca_message, hw_buffer, length);
382 put_checksum(hw_buffer->msg, hw_buffer->msg[0]);
409 383
410 hw_offset = 7; 384 debug_string(hw_buffer->msg, (length + tag_length), 0); /* tags too */
411 asn_1_words = 1; // just a hack to test, should compute this one 385 write_to_8820(state, hw_buffer, (length + tag_length), reply);
412 buf_offset = 3;
413 program_header_length = 6;
414 dst_tag_length = 7;
415
416// debug_twinhan_ca_params(state, p_ca_message, hw_buffer, reply, query, length, hw_offset, buf_offset);
417// dprintk("%s: Program Header(BUF)", __FUNCTION__);
418// debug_string(&p_ca_message->msg[4], program_header_length, 0);
419// dprintk("%s: Copying Program header\n", __FUNCTION__);
420 copy_string(hw_buffer->msg, p_ca_message->msg, hw_offset, (buf_offset + asn_1_words), program_header_length);
421 buf_offset += program_header_length, hw_offset += program_header_length;
422 modify_4_bits(hw_buffer->msg, (hw_offset - 2));
423 if (state->type_flags & DST_TYPE_HAS_INC_COUNT) { // workaround
424 dprintk("%s: Probably an ASIC bug !!!\n", __FUNCTION__);
425 debug_string(hw_buffer->msg, (hw_offset + program_header_length), 0);
426 hw_buffer->msg[hw_offset - 1] += 1;
427 }
428
429// dprintk("%s: Program Header(HW), Count=[%d]", __FUNCTION__, count);
430// debug_string(hw_buffer->msg, hw_offset, 0);
431
432 program_info_length = ((program_info_length | (p_ca_message->msg[buf_offset - 1] & 0x0f)) << 8) | p_ca_message->msg[buf_offset];
433 dprintk("%s: Program info length=[%02x]\n", __FUNCTION__, program_info_length);
434 if (program_info_length) {
435 count = copy_string(hw_buffer->msg, p_ca_message->msg, hw_offset, (buf_offset + 1), (program_info_length + 1) ); // copy next elem, not current
436 buf_offset += count, hw_offset += count;
437// dprintk("%s: Program level ", __FUNCTION__);
438// debug_string(hw_buffer->msg, hw_offset, 0);
439 }
440
441 buf_offset += 1;// hw_offset += 1;
442 for (i = buf_offset; i < length; i++) {
443// dprintk("%s: Stream Header ", __FUNCTION__);
444 count = copy_string(hw_buffer->msg, p_ca_message->msg, hw_offset, buf_offset, 5);
445 modify_4_bits(hw_buffer->msg, (hw_offset + 3));
446
447 hw_offset += 5, buf_offset += 5, i += 4;
448// debug_string(hw_buffer->msg, hw_offset, (hw_offset - 5));
449 es_info_length = ((es_info_length | (p_ca_message->msg[buf_offset - 1] & 0x0f)) << 8) | p_ca_message->msg[buf_offset];
450 dprintk("%s: ES info length=[%02x]\n", __FUNCTION__, es_info_length);
451 if (es_info_length) {
452 // copy descriptors @ STREAM level
453 dprintk("%s: Descriptors @ STREAM level...!!! \n", __FUNCTION__);
454 }
455
456 }
457 hw_buffer->msg[length + dst_tag_length] = dst_check_sum(hw_buffer->msg, (length + dst_tag_length));
458// dprintk("%s: Total length=[%d], Checksum=[%02x]\n", __FUNCTION__, (length + dst_tag_length), hw_buffer->msg[length + dst_tag_length]);
459 debug_string(hw_buffer->msg, (length + dst_tag_length + 1), 0); // dst tags also
460 write_to_8820(state, hw_buffer, (length + dst_tag_length + 1), reply); // checksum
461 386
462 return 0; 387 return 0;
463} 388}