2.1. Digital TV Common functions

2.1.1. Math functions

Provide some commonly-used math functions, usually required in order to estimate signal strength and signal to noise measurements in dB.

unsigned int intlog2(u32 value)

computes log2 of a value; the result is shifted left by 24 bits

Parameters

u32 value
The value (must be != 0)

Description

to use rational values you can use the following method:

intlog2(value) = intlog2(value * 2^x) - x * 2^24

Some usecase examples:

intlog2(8) will give 3 << 24 = 3 * 2^24

intlog2(9) will give 3 << 24 + ... = 3.16... * 2^24

intlog2(1.5) = intlog2(3) - 2^24 = 0.584... * 2^24

Return

log2(value) * 2^24

unsigned int intlog10(u32 value)

computes log10 of a value; the result is shifted left by 24 bits

Parameters

u32 value
The value (must be != 0)

Description

to use rational values you can use the following method:

intlog10(value) = intlog10(value * 10^x) - x * 2^24

An usecase example:

intlog10(1000) will give 3 << 24 = 3 * 2^24

due to the implementation intlog10(1000) might be not exactly 3 * 2^24

look at intlog2 for similar examples

Return

log10(value) * 2^24

2.1.2. DVB devices

Those functions are responsible for handling the DVB device nodes.

enum dvb_device_type

type of the Digital TV device

Constants

DVB_DEVICE_SEC
Digital TV standalone Common Interface (CI)
DVB_DEVICE_FRONTEND
Digital TV frontend.
DVB_DEVICE_DEMUX
Digital TV demux.
DVB_DEVICE_DVR
Digital TV digital video record (DVR).
DVB_DEVICE_CA
Digital TV Conditional Access (CA).
DVB_DEVICE_NET
Digital TV network.
DVB_DEVICE_VIDEO
Digital TV video decoder. Deprecated. Used only on av7110-av.
DVB_DEVICE_AUDIO
Digital TV audio decoder. Deprecated. Used only on av7110-av.
DVB_DEVICE_OSD
Digital TV On Screen Display (OSD). Deprecated. Used only on av7110.
struct dvb_adapter

represents a Digital TV adapter using Linux DVB API

Definition

struct dvb_adapter {
  int num;
  struct list_head list_head;
  struct list_head device_list;
  const char * name;
  u8 proposed_mac;
  void * priv;
  struct device * device;
  struct module * module;
  int mfe_shared;
  struct dvb_device * mfe_dvbdev;
  struct mutex mfe_lock;
#if defined(CONFIG_MEDIA_CONTROLLER_DVB
  struct media_device * mdev;
  struct media_entity * conn;
  struct media_pad * conn_pads;
#endif
};

Members

num
Number of the adapter
list_head
List with the DVB adapters
device_list
List with the DVB devices
name
Name of the adapter
proposed_mac
proposed MAC address for the adapter
priv
private data
device
pointer to struct device
module
pointer to struct module
mfe_shared
mfe shared: indicates mutually exclusive frontends Thie usage of this flag is currently deprecated
mfe_dvbdev
Frontend device in use, in the case of MFE
mfe_lock
Lock to prevent using the other frontends when MFE is used.
mdev
pointer to struct media_device, used when the media controller is used.
conn
RF connector. Used only if the device has no separate tuner.
conn_pads
pointer to struct media_pad associated with conn;
struct dvb_device

represents a DVB device node

Definition

struct dvb_device {
  struct list_head list_head;
  const struct file_operations * fops;
  struct dvb_adapter * adapter;
  enum dvb_device_type type;
  int minor;
  u32 id;
  int readers;
  int writers;
  int users;
  wait_queue_head_t wait_queue;
  int (* kernel_ioctl) (struct file *file, unsigned int cmd, void *arg);
#if defined(CONFIG_MEDIA_CONTROLLER_DVB
  const char * name;
  struct media_intf_devnode * intf_devnode;
  unsigned tsout_num_entities;
  struct media_entity * entity;
  struct media_entity * tsout_entity;
  struct media_pad * pads;
  struct media_pad * tsout_pads;
#endif
  void * priv;
};

Members

list_head
List head with all DVB devices
fops
pointer to struct file_operations
adapter
pointer to the adapter that holds this device node
type
type of the device, as defined by enum dvb_device_type.
minor
devnode minor number. Major number is always DVB_MAJOR.
id
device ID number, inside the adapter
readers
Initialized by the caller. Each call to open() in Read Only mode decreases this counter by one.
writers
Initialized by the caller. Each call to open() in Read/Write mode decreases this counter by one.
users
Initialized by the caller. Each call to open() in any mode decreases this counter by one.
wait_queue
wait queue, used to wait for certain events inside one of the DVB API callers
kernel_ioctl
callback function used to handle ioctl calls from userspace.
name
Name to be used for the device at the Media Controller
intf_devnode
Pointer to media_intf_devnode. Used by the dvbdev core to store the MC device node interface
tsout_num_entities
Number of Transport Stream output entities
entity
pointer to struct media_entity associated with the device node
tsout_entity
array with MC entities associated to each TS output node
pads
pointer to struct media_pad associated with entity;
tsout_pads
array with the source pads for each tsout_entity
priv
private data

Description

This structure is used by the DVB core (frontend, CA, net, demux) in order to create the device nodes. Usually, driver should not initialize this struct diretly.

int dvb_register_adapter(struct dvb_adapter * adap, const char * name, struct module * module, struct device * device, short * adapter_nums)

Registers a new DVB adapter

Parameters

struct dvb_adapter * adap
pointer to struct dvb_adapter
const char * name
Adapter’s name
struct module * module
initialized with THIS_MODULE at the caller
struct device * device
pointer to struct device that corresponds to the device driver
short * adapter_nums
Array with a list of the numbers for dvb_register_adapter; to select among them. Typically, initialized with: DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nums)
int dvb_unregister_adapter(struct dvb_adapter * adap)

Unregisters a DVB adapter

Parameters

struct dvb_adapter * adap
pointer to struct dvb_adapter
int dvb_register_device(struct dvb_adapter * adap, struct dvb_device ** pdvbdev, const struct dvb_device * template, void * priv, enum dvb_device_type type, int demux_sink_pads)

Registers a new DVB device

Parameters

struct dvb_adapter * adap
pointer to struct dvb_adapter
struct dvb_device ** pdvbdev
pointer to the place where the new struct dvb_device will be stored
const struct dvb_device * template
Template used to create pdvbdev;
void * priv
private data
enum dvb_device_type type
type of the device, as defined by enum dvb_device_type.
int demux_sink_pads
Number of demux outputs, to be used to create the TS outputs via the Media Controller.
void dvb_remove_device(struct dvb_device * dvbdev)

Remove a registered DVB device

Parameters

struct dvb_device * dvbdev
pointer to struct dvb_device

Description

This does not free memory. To do that, call dvb_free_device().

void dvb_free_device(struct dvb_device * dvbdev)

Free memory occupied by a DVB device.

Parameters

struct dvb_device * dvbdev
pointer to struct dvb_device

Description

Call dvb_unregister_device() before calling this function.

void dvb_unregister_device(struct dvb_device * dvbdev)

Unregisters a DVB device

Parameters

struct dvb_device * dvbdev
pointer to struct dvb_device

Description

This is a combination of dvb_remove_device() and dvb_free_device(). Using this function is usually a mistake, and is often an indicator for a use-after-free bug (when a userspace process keeps a file handle to a detached device).

int dvb_create_media_graph(struct dvb_adapter * adap, bool create_rf_connector)

Creates media graph for the Digital TV part of the device.

Parameters

struct dvb_adapter * adap
pointer to struct dvb_adapter
bool create_rf_connector
if true, it creates the RF connector too

Description

This function checks all DVB-related functions at the media controller entities and creates the needed links for the media graph. It is capable of working with multiple tuners or multiple frontends, but it won’t create links if the device has multiple tuners and multiple frontends or if the device has multiple muxes. In such case, the caller driver should manually create the remaining links.

void dvb_register_media_controller(struct dvb_adapter * adap, struct media_device * mdev)

registers a media controller at DVB adapter

Parameters

struct dvb_adapter * adap
pointer to struct dvb_adapter
struct media_device * mdev
pointer to struct media_device
struct media_device * dvb_get_media_controller(struct dvb_adapter * adap)

gets the associated media controller

Parameters

struct dvb_adapter * adap
pointer to struct dvb_adapter
int dvb_generic_open(struct inode * inode, struct file * file)

Digital TV open function, used by DVB devices

Parameters

struct inode * inode
pointer to struct inode.
struct file * file
pointer to struct file.

Description

Checks if a DVB devnode is still valid, and if the permissions are OK and increment negative use count.

int dvb_generic_release(struct inode * inode, struct file * file)

Digital TV close function, used by DVB devices

Parameters

struct inode * inode
pointer to struct inode.
struct file * file
pointer to struct file.

Description

Checks if a DVB devnode is still valid, and if the permissions are OK and decrement negative use count.

long dvb_generic_ioctl(struct file * file, unsigned int cmd, unsigned long arg)

Digital TV close function, used by DVB devices

Parameters

struct file * file
pointer to struct file.
unsigned int cmd
Ioctl name.
unsigned long arg
Ioctl argument.

Description

Checks if a DVB devnode and struct dvbdev.kernel_ioctl is still valid. If so, calls dvb_usercopy().

int dvb_usercopy(struct file * file, unsigned int cmd, unsigned long arg, int (*func) (struct file *file, unsigned int cmd, void *arg)

copies data from/to userspace memory when an ioctl is issued.

Parameters

struct file * file
Pointer to struct file.
unsigned int cmd
Ioctl name.
unsigned long arg
Ioctl argument.
int (*)(struct file *file, unsigned int cmd, void *arg) func
function that will actually handle the ioctl

Description

Ancillary function that uses ioctl direction and size to copy from userspace. Then, it calls func, and, if needed, data is copied back to userspace.

dvb_attach(FUNCTION, ARGS...)

attaches a DVB frontend into the DVB core.

Parameters

FUNCTION
function on a frontend module to be called.
ARGS...
FUNCTION arguments.

Description

This ancillary function loads a frontend module in runtime and runs the FUNCTION function there, with ARGS. As it increments symbol usage cont, at unregister, dvb_detach() should be called.

dvb_detach(FUNC)

detaches a DVB frontend loaded via dvb_attach()

Parameters

FUNC
attach function

Description

Decrements usage count for a function previously called via dvb_attach().

2.1.3. Digital TV Ring buffer

Those routines implement ring buffers used to handle digital TV data and copy it from/to userspace.

Note

  1. For performance reasons read and write routines don’t check buffer sizes and/or number of bytes free/available. This has to be done before these routines are called. For example:
/* write @buflen: bytes */
free = dvb_ringbuffer_free(rbuf);
if (free >= buflen)
        count = dvb_ringbuffer_write(rbuf, buffer, buflen);
else
        /* do something */

/* read min. 1000, max. @bufsize: bytes */
avail = dvb_ringbuffer_avail(rbuf);
if (avail >= 1000)
        count = dvb_ringbuffer_read(rbuf, buffer, min(avail, bufsize));
else
        /* do something */
  1. If there is exactly one reader and one writer, there is no need to lock read or write operations. Two or more readers must be locked against each other. Flushing the buffer counts as a read operation. Resetting the buffer counts as a read and write operation. Two or more writers must be locked against each other.
struct dvb_ringbuffer

Describes a ring buffer used at DVB framework

Definition

struct dvb_ringbuffer {
  u8 * data;
  ssize_t size;
  ssize_t pread;
  ssize_t pwrite;
  int error;
  wait_queue_head_t queue;
  spinlock_t lock;
};

Members

data
Area were the ringbuffer data is written
size
size of the ringbuffer
pread
next position to read
pwrite
next position to write
error
used by ringbuffer clients to indicate that an error happened.
queue
Wait queue used by ringbuffer clients to indicate when buffer was filled
lock
Spinlock used to protect the ringbuffer
void dvb_ringbuffer_init(struct dvb_ringbuffer * rbuf, void * data, size_t len)

initialize ring buffer, lock and queue

Parameters

struct dvb_ringbuffer * rbuf
pointer to struct dvb_ringbuffer
void * data
pointer to the buffer where the data will be stored
size_t len
bytes from ring buffer into buf
int dvb_ringbuffer_empty(struct dvb_ringbuffer * rbuf)

test whether buffer is empty

Parameters

struct dvb_ringbuffer * rbuf
pointer to struct dvb_ringbuffer
ssize_t dvb_ringbuffer_free(struct dvb_ringbuffer * rbuf)

returns the number of free bytes in the buffer

Parameters

struct dvb_ringbuffer * rbuf
pointer to struct dvb_ringbuffer

Return

number of free bytes in the buffer

ssize_t dvb_ringbuffer_avail(struct dvb_ringbuffer * rbuf)

returns the number of bytes waiting in the buffer

Parameters

struct dvb_ringbuffer * rbuf
pointer to struct dvb_ringbuffer

Return

number of bytes waiting in the buffer

void dvb_ringbuffer_reset(struct dvb_ringbuffer * rbuf)

resets the ringbuffer to initial state

Parameters

struct dvb_ringbuffer * rbuf
pointer to struct dvb_ringbuffer

Description

Resets the read and write pointers to zero and flush the buffer.

This counts as a read and write operation

void dvb_ringbuffer_flush(struct dvb_ringbuffer * rbuf)

flush buffer

Parameters

struct dvb_ringbuffer * rbuf
pointer to struct dvb_ringbuffer
void dvb_ringbuffer_flush_spinlock_wakeup(struct dvb_ringbuffer * rbuf)

flush buffer protected by spinlock and wake-up waiting task(s)

Parameters

struct dvb_ringbuffer * rbuf
pointer to struct dvb_ringbuffer
DVB_RINGBUFFER_PEEK(rbuf, offs)

peek at byte offs in the buffer

Parameters

rbuf
pointer to struct dvb_ringbuffer
offs
offset inside the ringbuffer
DVB_RINGBUFFER_SKIP(rbuf, num)

advance read ptr by num bytes

Parameters

rbuf
pointer to struct dvb_ringbuffer
num
number of bytes to advance
ssize_t dvb_ringbuffer_read_user(struct dvb_ringbuffer * rbuf, u8 __user * buf, size_t len)

Reads a buffer into a user pointer

Parameters

struct dvb_ringbuffer * rbuf
pointer to struct dvb_ringbuffer
u8 __user * buf
pointer to the buffer where the data will be stored
size_t len
bytes from ring buffer into buf

Description

This variant assumes that the buffer is a memory at the userspace. So, it will internally call copy_to_user().

Return

number of bytes transferred or -EFAULT

void dvb_ringbuffer_read(struct dvb_ringbuffer * rbuf, u8 * buf, size_t len)

Reads a buffer into a pointer

Parameters

struct dvb_ringbuffer * rbuf
pointer to struct dvb_ringbuffer
u8 * buf
pointer to the buffer where the data will be stored
size_t len
bytes from ring buffer into buf

Description

This variant assumes that the buffer is a memory at the Kernel space

Return

number of bytes transferred or -EFAULT

DVB_RINGBUFFER_WRITE_BYTE(rbuf, byte)

write single byte to ring buffer

Parameters

rbuf
pointer to struct dvb_ringbuffer
byte
byte to write
ssize_t dvb_ringbuffer_write(struct dvb_ringbuffer * rbuf, const u8 * buf, size_t len)

Writes a buffer into the ringbuffer

Parameters

struct dvb_ringbuffer * rbuf
pointer to struct dvb_ringbuffer
const u8 * buf
pointer to the buffer where the data will be read
size_t len
bytes from ring buffer into buf

Description

This variant assumes that the buffer is a memory at the Kernel space

Return

number of bytes transferred or -EFAULT

ssize_t dvb_ringbuffer_write_user(struct dvb_ringbuffer * rbuf, const u8 __user * buf, size_t len)

Writes a buffer received via a user pointer

Parameters

struct dvb_ringbuffer * rbuf
pointer to struct dvb_ringbuffer
const u8 __user * buf
pointer to the buffer where the data will be read
size_t len
bytes from ring buffer into buf

Description

This variant assumes that the buffer is a memory at the userspace. So, it will internally call copy_from_user().

Return

number of bytes transferred or -EFAULT

ssize_t dvb_ringbuffer_pkt_write(struct dvb_ringbuffer * rbuf, u8 * buf, size_t len)

Write a packet into the ringbuffer.

Parameters

struct dvb_ringbuffer * rbuf
Ringbuffer to write to.
u8 * buf
Buffer to write.
size_t len
Length of buffer (currently limited to 65535 bytes max).

Return

Number of bytes written, or -EFAULT, -ENOMEM, -EVINAL.

ssize_t dvb_ringbuffer_pkt_read_user(struct dvb_ringbuffer * rbuf, size_t idx, int offset, u8 __user * buf, size_t len)

Read from a packet in the ringbuffer.

Parameters

struct dvb_ringbuffer * rbuf
Ringbuffer concerned.
size_t idx
Packet index as returned by dvb_ringbuffer_pkt_next().
int offset
Offset into packet to read from.
u8 __user * buf
Destination buffer for data.
size_t len
Size of destination buffer.

Return

Number of bytes read, or -EFAULT.

Note

unlike dvb_ringbuffer_read(), this does NOT update the read pointer in the ringbuffer. You must use dvb_ringbuffer_pkt_dispose() to mark a packet as no longer required.

ssize_t dvb_ringbuffer_pkt_read(struct dvb_ringbuffer * rbuf, size_t idx, int offset, u8 * buf, size_t len)

Read from a packet in the ringbuffer.

Parameters

struct dvb_ringbuffer * rbuf
Ringbuffer concerned.
size_t idx
Packet index as returned by dvb_ringbuffer_pkt_next().
int offset
Offset into packet to read from.
u8 * buf
Destination buffer for data.
size_t len
Size of destination buffer.

Note

unlike dvb_ringbuffer_read_user(), this DOES update the read pointer in the ringbuffer.

Return

Number of bytes read, or -EFAULT.

void dvb_ringbuffer_pkt_dispose(struct dvb_ringbuffer * rbuf, size_t idx)

Dispose of a packet in the ring buffer.

Parameters

struct dvb_ringbuffer * rbuf
Ring buffer concerned.
size_t idx
Packet index as returned by dvb_ringbuffer_pkt_next().
ssize_t dvb_ringbuffer_pkt_next(struct dvb_ringbuffer * rbuf, size_t idx, size_t * pktlen)

Get the index of the next packet in a ringbuffer.

Parameters

struct dvb_ringbuffer * rbuf
Ringbuffer concerned.
size_t idx
Previous packet index, or -1 to return the first packet index.
size_t * pktlen
On success, will be updated to contain the length of the packet in bytes. returns Packet index (if >=0), or -1 if no packets available.