Commit f324c82b authored by Christophe Massiot's avatar Christophe Massiot

* modules/access/dvb: Fixed a bug with CAMs which take a long time to

   initialize.
parent ea928459
...@@ -102,7 +102,6 @@ int E_(CAMPoll)( access_t * ); ...@@ -102,7 +102,6 @@ int E_(CAMPoll)( access_t * );
int E_(CAMSet)( access_t *, uint8_t **, int ); int E_(CAMSet)( access_t *, uint8_t **, int );
void E_(CAMClose)( access_t * ); void E_(CAMClose)( access_t * );
int E_(en50221_Init)( access_t * );
int E_(en50221_Poll)( access_t * ); int E_(en50221_Poll)( access_t * );
int E_(en50221_SetCAPMT)( access_t *, uint8_t **, int ); int E_(en50221_SetCAPMT)( access_t *, uint8_t **, int );
void E_(en50221_End)( access_t * ); void E_(en50221_End)( access_t * );
......
...@@ -36,6 +36,12 @@ ...@@ -36,6 +36,12 @@
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/poll.h> #include <sys/poll.h>
/* DVB Card Drivers */
#include <linux/dvb/version.h>
#include <linux/dvb/dmx.h>
#include <linux/dvb/frontend.h>
#include <linux/dvb/ca.h>
#include "dvb.h" #include "dvb.h"
#undef DEBUG_TPDU #undef DEBUG_TPDU
...@@ -907,61 +913,61 @@ static void MMIOpen( access_t * p_access, int i_session_id ) ...@@ -907,61 +913,61 @@ static void MMIOpen( access_t * p_access, int i_session_id )
/* /*
* External entry points * Hardware handling
*/ */
/***************************************************************************** /*****************************************************************************
* en50221_Init : Open the transport layer * InitSlot: Open the transport layer
*****************************************************************************/ *****************************************************************************/
#define MAX_TC_RETRIES 20 #define MAX_TC_RETRIES 20
int E_(en50221_Init)( access_t * p_access ) static int InitSlot( access_t * p_access, int i_slot )
{ {
access_sys_t *p_sys = p_access->p_sys; access_sys_t *p_sys = p_access->p_sys;
int i_slot, i_active_slots = 0; int i;
for ( i_slot = 0; i_slot < p_sys->i_nb_slots; i_slot++ ) if ( TPDUSend( p_access, i_slot, T_CREATE_TC, NULL, 0 )
!= VLC_SUCCESS )
{ {
int i; msg_Err( p_access, "en50221_Init: couldn't send TPDU on slot %d",
if ( !p_sys->pb_active_slot[i_slot] ) i_slot );
continue; return VLC_EGENERIC;
p_sys->pb_active_slot[i_slot] = VLC_FALSE; }
/* This is out of the spec */
for ( i = 0; i < MAX_TC_RETRIES; i++ )
{
uint8_t i_tag;
if ( TPDURecv( p_access, i_slot, &i_tag, NULL, NULL ) == VLC_SUCCESS
&& i_tag == T_CTC_REPLY )
{
p_sys->pb_active_slot[i_slot] = VLC_TRUE;
break;
}
if ( TPDUSend( p_access, i_slot, T_CREATE_TC, NULL, 0 ) if ( TPDUSend( p_access, i_slot, T_CREATE_TC, NULL, 0 )
!= VLC_SUCCESS ) != VLC_SUCCESS )
{ {
msg_Err( p_access, "en50221_Init: couldn't send TPDU on slot %d", msg_Err( p_access,
"en50221_Init: couldn't send TPDU on slot %d",
i_slot ); i_slot );
continue; continue;
} }
/* This is out of the spec */
for ( i = 0; i < MAX_TC_RETRIES; i++ )
{
uint8_t i_tag;
if ( TPDURecv( p_access, i_slot, &i_tag, NULL, NULL ) == VLC_SUCCESS
&& i_tag == T_CTC_REPLY )
{
p_sys->pb_active_slot[i_slot] = VLC_TRUE;
i_active_slots++;
break;
}
if ( TPDUSend( p_access, i_slot, T_CREATE_TC, NULL, 0 )
!= VLC_SUCCESS )
{
msg_Err( p_access,
"en50221_Init: couldn't send TPDU on slot %d",
i_slot );
continue;
}
}
} }
p_sys->i_ca_timeout = 1000; if ( p_sys->pb_active_slot[i_slot] )
{
p_sys->i_ca_timeout = 1000;
return VLC_SUCCESS;
}
return i_active_slots; return VLC_EGENERIC;
} }
/*
* External entry points
*/
/***************************************************************************** /*****************************************************************************
* en50221_Poll : Poll the CAM for TPDUs * en50221_Poll : Poll the CAM for TPDUs
*****************************************************************************/ *****************************************************************************/
...@@ -976,7 +982,27 @@ int E_(en50221_Poll)( access_t * p_access ) ...@@ -976,7 +982,27 @@ int E_(en50221_Poll)( access_t * p_access )
uint8_t i_tag; uint8_t i_tag;
if ( !p_sys->pb_active_slot[i_slot] ) if ( !p_sys->pb_active_slot[i_slot] )
continue; {
ca_slot_info_t sinfo;
sinfo.num = i_slot;
if ( ioctl( p_sys->i_ca_handle, CA_GET_SLOT_INFO, &sinfo ) != 0 )
{
msg_Err( p_access, "en50221_Poll: couldn't get info on slot %d",
i_slot );
continue;
}
if ( sinfo.flags & CA_CI_MODULE_READY )
{
msg_Dbg( p_access, "en50221_Poll: slot %d is active",
i_slot );
p_sys->pb_active_slot[i_slot] = VLC_TRUE;
}
else
continue;
InitSlot( p_access, i_slot );
}
if ( !p_sys->pb_tc_has_data[i_slot] ) if ( !p_sys->pb_tc_has_data[i_slot] )
{ {
...@@ -1061,7 +1087,7 @@ int E_(en50221_SetCAPMT)( access_t * p_access, uint8_t **pp_capmts, ...@@ -1061,7 +1087,7 @@ int E_(en50221_SetCAPMT)( access_t * p_access, uint8_t **pp_capmts,
access_sys_t *p_sys = p_access->p_sys; access_sys_t *p_sys = p_access->p_sys;
int i_session_id; int i_session_id;
for ( i_session_id = 0; i_session_id < MAX_SESSIONS; i_session_id++ ) for ( i_session_id = 1; i_session_id <= MAX_SESSIONS; i_session_id++ )
{ {
int i; int i;
......
...@@ -47,7 +47,6 @@ ...@@ -47,7 +47,6 @@
#include "dvb.h" #include "dvb.h"
#define DMX_BUFFER_SIZE (1024 * 1024) #define DMX_BUFFER_SIZE (1024 * 1024)
#define CA_MAX_STATE_RETRY 5
/* /*
* Frontends * Frontends
...@@ -1116,7 +1115,7 @@ int E_(CAMOpen)( access_t *p_access ) ...@@ -1116,7 +1115,7 @@ int E_(CAMOpen)( access_t *p_access )
{ {
access_sys_t *p_sys = p_access->p_sys; access_sys_t *p_sys = p_access->p_sys;
char ca[128]; char ca[128];
int i_adapter, i_device, i_slot, i_active_slots = 0; int i_adapter, i_device, i_slot;
ca_caps_t caps; ca_caps_t caps;
i_adapter = var_GetInteger( p_access, "dvb-adapter" ); i_adapter = var_GetInteger( p_access, "dvb-adapter" );
...@@ -1133,6 +1132,7 @@ int E_(CAMOpen)( access_t *p_access ) ...@@ -1133,6 +1132,7 @@ int E_(CAMOpen)( access_t *p_access )
{ {
msg_Err( p_access, "CAMInit: opening device failed (%s)", msg_Err( p_access, "CAMInit: opening device failed (%s)",
strerror(errno) ); strerror(errno) );
p_sys->i_ca_handle = 0;
return VLC_EGENERIC; return VLC_EGENERIC;
} }
...@@ -1150,45 +1150,18 @@ int E_(CAMOpen)( access_t *p_access ) ...@@ -1150,45 +1150,18 @@ int E_(CAMOpen)( access_t *p_access )
for ( i_slot = 0; i_slot < p_sys->i_nb_slots; i_slot++ ) for ( i_slot = 0; i_slot < p_sys->i_nb_slots; i_slot++ )
{ {
ca_slot_info_t sinfo;
int i;
if ( ioctl( p_sys->i_ca_handle, CA_RESET, 1 << i_slot) != 0 ) if ( ioctl( p_sys->i_ca_handle, CA_RESET, 1 << i_slot) != 0 )
{ {
msg_Err( p_access, "CAMInit: couldn't reset slot %d", i_slot ); msg_Err( p_access, "CAMInit: couldn't reset slot %d", i_slot );
continue;
}
for ( i = 0; i < CA_MAX_STATE_RETRY; i++ )
{
msleep(100000);
sinfo.num = i_slot;
if ( ioctl( p_sys->i_ca_handle, CA_GET_SLOT_INFO, &sinfo ) != 0 )
{
msg_Err( p_access, "CAMInit: couldn't get info on slot %d",
i_slot );
continue;
}
if ( sinfo.flags & CA_CI_MODULE_READY )
{
p_sys->pb_active_slot[i_slot] = VLC_TRUE;
}
} }
} }
i_active_slots = E_(en50221_Init)( p_access ); msg_Dbg( p_access, "CAMInit: found a CI handler with %d slots",
p_sys->i_nb_slots );
msg_Dbg( p_access, "CAMInit: found a CI handler with %d slots, %d active", p_sys->i_ca_timeout = 100000;
p_sys->i_nb_slots, i_active_slots ); /* Wait a bit otherwise it doesn't initialize properly... */
msleep( 1000000 );
if ( !i_active_slots )
{
close( p_sys->i_ca_handle );
p_sys->i_ca_handle = 0;
return VLC_EGENERIC;
}
return VLC_SUCCESS; return VLC_SUCCESS;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment