On 07-12-2011 13:50, Mauro Carvalho Chehab wrote:
It is hard to tell the exact problem without looking into the driver. Are you
handling the error codes returned by the register functions?
You can follow what's happening inside your driver by enabling tracepoints.
Here is one of the scripts I used when I need to know what functions are
called:
#!/bin/bash
cd /sys/kernel/debug/tracing
echo disabling trace
echo 0 tracing_enabled
echo getting funcs
FUNC=`cat /sys/kernel/debug/tracing/available_filter_functions|grep -i
drx`
echo setting functions
echo $FUNCset_ftrace_filter
echo set trace type
echo function_graph current_tracer
echo enabling trace
echo 1 tracing_enabled
(the above enables tracing only for functions with drx in the name - you'll
need to tailor it for your specific needs)
Of course, after finishing the device creation, you should disable the trace
and
get its results with:
#!/bin/bash
cd /sys/kernel/debug/tracing
echo 0 tracing_enabled
less trace
I suggest you to compare the trace for a device that is known to create all
dvb
nodes with your driver. This may give you a good hint about what is missing on
your driver.
Regards,
Mauro
I'm checking return error codes, no problems there, I also added traces within
the register functions and they all run fine. Here's my code that registers the
demux device (note that the net device works fine):
static struct dvb_demux demux;
static struct dmxdev dmxdev;
static struct dvb_net net;
static struct dmx_frontend fe_hw;
static struct dmx_frontend fe_mem;
static int test_start_feed(struct dvb_demux_feed *feed)
{
printk(KERN_INFO %s executed\n, __FUNCTION__);
return 0;
}
static int test_stop_feed(struct dvb_demux_feed *feed)
{
printk(KERN_INFO %s executed\n, __FUNCTION__);
return 0;
}
static int test_write_to_decoder(struct dvb_demux_feed *feed, const u8 *buf,
size_t len)
{
printk(KERN_INFO %s executed\n, __FUNCTION__);
return 0;
}
// initialization specific demux device
void test_demux_device_init(struct dvb_adapter* adapter)
{
int result;
printk(KERN_INFO %s executed\n, __FUNCTION__);
memset(demux, 0, sizeof(struct dvb_demux));
demux.dmx.capabilities = DMX_TS_FILTERING |
DMX_PES_FILTERING |
DMX_SECTION_FILTERING |
DMX_MEMORY_BASED_FILTERING |
DMX_CRC_CHECKING |
DMX_TS_DESCRAMBLING;
demux.priv = NULL;
demux.filternum = 31;
demux.feednum = 31;
demux.start_feed = test_start_feed;
demux.stop_feed = test_stop_feed;
demux.write_to_decoder = test_write_to_decoder;
printk(KERN_INFO %s call dvb_dmx_init\n, __FUNCTION__);
if ((result = dvb_dmx_init(demux)) 0)
{
printk(KERN_ERR %s: dvb_dmx_init failed\n, __FUNCTION__);
goto init_failed;
}
dmxdev.filternum = 31;
dmxdev.demux = demux.dmx;
dmxdev.capabilities = 0;
printk(KERN_INFO %s call dvb_dmxdev_init\n, __FUNCTION__);
if ((result = dvb_dmxdev_init(dmxdev, adapter)) 0)
{
printk(KERN_ERR %s: dvb_dmxdev_init failed (errno=%d)\n,
__FUNCTION__, result);
goto init_failed_dmx_release;
}
fe_hw.source = DMX_FRONTEND_0;
printk(KERN_INFO %s call add_frontend\n, __FUNCTION__);
if ((result = demux.dmx.add_frontend(demux.dmx, fe_hw)) 0)
{
printk(KERN_ERR %s: add_frontend (hw) failed (errno=%d)\n,
__FUNCTION__, result);
goto init_failed_dmxdev_release;
}
fe_mem.source = DMX_MEMORY_FE;
if ((result = demux.dmx.add_frontend(demux.dmx, fe_mem)) 0)
{
printk(KERN_ERR %s: add_frontend (mem) failed (errno=%d)\n,
__FUNCTION__, result);
goto init_failed_remove_hw_frontend;
}
if ((result = demux.dmx.connect_frontend(demux.dmx, fe_hw)) 0)
{
printk(KERN_ERR %s: connect_frontend failed (errno=%d)\n,
__FUNCTION__, result);
goto init_failed_remove_mem_frontend;
}
if ((result = dvb_net_init(adapter, net, demux.dmx)) 0)
{
printk(KERN_ERR %s: dvb_net_init failed (errno=%d)\n,
__FUNCTION__, result);
goto init_failed_disconnect_frontend;
}
init_failed_disconnect_frontend:
demux.dmx.disconnect_frontend(demux.dmx);
init_failed_remove_mem_frontend:
demux.dmx.remove_frontend(demux.dmx, fe_mem);
init_failed_remove_hw_frontend:
demux.dmx.remove_frontend(demux.dmx,