Project

General

Profile

RE: [Solved] Tvheadend fails initialize HW CAM correctly,... ยป tvheadend-4.2.2-tbs5980-cam-init-fix.patch

Tvheadend CAM Initialization Workaround for TBS5980 - Jon Murdock, 2017-07-15 16:03

View differences:

tvheadend-4.2.2/src/input/mpegts/linuxdvb/linuxdvb_ca.c 2017-06-09 22:39:44.856427300 +0000
37 37
#include "descrambler/caid.h"
38 38
#include "descrambler/dvbcam.h"
39 39

  
40
/* Seconds to wait for a slot to become ready */
41
#define MAX_SLOT_READY_WAIT_SECS 10
42

  
40 43
typedef enum {
41 44
  CA_SLOT_STATE_EMPTY = 0,
42 45
  CA_SLOT_STATE_MODULE_PRESENT,
......
666 669
{
667 670
  linuxdvb_ca_t *lca = aux;
668 671
  int slot_id, lasterror = 0;
672
  int i;
673
  ca_slot_info_t csi;
669 674

  
670 675
  lca->lca_tl = en50221_tl_create(5, 32);
671 676
  if (!lca->lca_tl) {
......
673 678
    return NULL;
674 679
  }
675 680

  
681
  /* Fix - Step 1: Issue a reset of the slot */
682
  if (ioctl(lca->lca_ca_fd, CA_RESET, (1 << lca->lca_number))) {
683
    tvherror(LS_EN50221, "unable to reset ca%u %s", 
684
             lca->lca_number, lca->lca_ca_path);
685
    return NULL;
686
  }
687

  
688
  /* Fix - Step 2: Poll the slot until it becomes ready */
689
  csi.num = lca->lca_number;
690
  for (i=0; i <= (MAX_SLOT_READY_WAIT_SECS * 1000); i++) {
691
    /* sleep 1ms */
692
    tvh_safe_usleep(1000);
693
    /* get slot information */
694
    if(ioctl(lca->lca_ca_fd, CA_GET_SLOT_INFO, &csi)) {
695
      tvherror(LS_EN50221, "unable to get slot info for CAM #%d, path: %s",
696
               lca->lca_number, lca->lca_ca_path);
697
      return NULL;
698
    }
699
    /* check for slot being ready */
700
    if(csi.flags & CA_CI_MODULE_READY) {
701
      tvhtrace(LS_EN50221, "slot ready on CAM #%d after ~%d msecs, path: %s",
702
              lca->lca_number, i, lca->lca_ca_path);
703
      break;
704
    }
705
  }
706

  
707
  /* Fix - Step 3: If the slot fails to initialise, give up */
708
  if(i >= (MAX_SLOT_READY_WAIT_SECS * 1000)) {
709
    tvherror(LS_EN50221, "timeout after ~%d msecs to get slot info for CAM #%d, path: %s", 
710
             i, lca->lca_number, lca->lca_ca_path);
711
    return NULL;
712
  }
713

  
676 714
  slot_id = en50221_tl_register_slot(lca->lca_tl, lca->lca_ca_fd, 0, 1000, 100);
677 715
  if (slot_id < 0) {
678 716
    tvherror(LS_EN50221, "slot registration failed");
......
766 804
                csi.num, lca->lca_state_str);
767 805
      idnode_notify_title_changed(&lca->lca_id, NULL);
768 806
      lca->lca_state = state;
807
      lca->lca_state_wait = 0;
769 808
    }
770 809

  
771 810
    if ((!lca->lca_en50221_thread_running) &&
......
774 813
      lca->lca_en50221_thread_running = 1;
775 814
      tvhthread_create(&lca->lca_en50221_thread, NULL,
776 815
                       linuxdvb_ca_en50221_thread, lca, "lnxdvb-ca");
816
    } else if (lca->lca_en50221_thread_running && 
817
	       (state == CA_SLOT_STATE_MODULE_PRESENT) &&
818
               lca->lca_state_wait < (MAX_SLOT_READY_WAIT_SECS * 4))
819
    {
820
      /* wait for the slot to move from PRESENT to READY */
821
      lca->lca_state_wait++;
777 822
    } else if (lca->lca_en50221_thread_running &&
778 823
               (state != CA_SLOT_STATE_MODULE_READY))
779 824
    {
tvheadend-4.2.2/src/input/mpegts/linuxdvb/linuxdvb_private.h 2017-06-04 13:40:15.663449402 +0000
211 211
  char                     *lca_ca_path;
212 212
  int                      lca_state;
213 213
  const char               *lca_state_str;
214
  int                      lca_state_wait;
214 215
  linuxdvb_ca_capmt_queue_t lca_capmt_queue;
215 216
  /*
216 217
   * CAM module info
    (1-1/1)