diff options
-rw-r--r-- | dvb-spec/HOWTO-use-the-demux-api | 207 | ||||
-rw-r--r-- | dvb-spec/HOWTO-use-the-frontend-api | 204 | ||||
-rw-r--r-- | dvb-spec/README.CABLE | 10 | ||||
-rw-r--r-- | dvb-spec/README.valgrind | 13 | ||||
-rw-r--r-- | dvb-spec/channel | 104 | ||||
-rw-r--r-- | dvb-spec/dvbapi/.cvsignore | 14 | ||||
-rw-r--r-- | dvb-spec/dvbapi/Makefile | 15 | ||||
-rw-r--r-- | dvb-spec/dvbapi/audio.tex | 98 | ||||
-rw-r--r-- | dvb-spec/dvbapi/ca.tex | 4 | ||||
-rw-r--r-- | dvb-spec/dvbapi/demux.tex | 151 | ||||
-rw-r--r-- | dvb-spec/dvbapi/devices.tex | 6 | ||||
-rw-r--r-- | dvb-spec/dvbapi/dvbapi.tex | 4 | ||||
-rw-r--r-- | dvb-spec/dvbapi/examples.tex | 46 | ||||
-rw-r--r-- | dvb-spec/dvbapi/frontend.tex | 730 | ||||
-rw-r--r-- | dvb-spec/dvbapi/intro.tex | 117 | ||||
-rw-r--r-- | dvb-spec/dvbapi/kdapi.tex | 9 | ||||
-rw-r--r-- | dvb-spec/dvbapi/net.tex | 19 | ||||
-rw-r--r-- | dvb-spec/dvbapi/sec.tex | 282 | ||||
-rw-r--r-- | dvb-spec/dvbapi/title.tex | 13 | ||||
-rw-r--r-- | dvb-spec/dvbapi/video.tex | 155 | ||||
-rw-r--r-- | dvb-spec/valgrind-1.0.4.diff | 357 | ||||
-rw-r--r-- | dvb-spec/valgrind-1.9.4.diff | 356 | ||||
-rw-r--r-- | dvb-spec/valgrind-20030716.diff | 361 |
23 files changed, 2247 insertions, 1028 deletions
diff --git a/dvb-spec/HOWTO-use-the-demux-api b/dvb-spec/HOWTO-use-the-demux-api new file mode 100644 index 000000000..ee782db6d --- /dev/null +++ b/dvb-spec/HOWTO-use-the-demux-api @@ -0,0 +1,207 @@ + +------------------------------------------------------------------------------- + +What has changed since the old Nokia OST API? + + device node naming: + - /dev/ost directory is now called /dev/dvb + - each DVB adapter has it's own directory /dev/dvb/adapterX + - the devfs devices names are identical to those + creatd by the makedev.napi script on non-devfs systems + - here you'll find a number of demux devices /dev/dvb/adapterX/dmxY + - driver header directory is located now in /usr/include/linux/dvb/ + - we have a linux/dvb/version.h file, this is included by all headers which + don't use the original OST API anymore + + struct naming: + - we follow the kernel naming scheme and try to get the namespace clean, + these changes are mostly syntactical + + new feature: + - section filters have a mode field now, you can set not-equal filters + where you will get only notified when the related bits change + +------------------------------------------------------------------------------- + +How to determine the API version? + + Check in your configure script for #include <linux/dvb/version.h>, + include it and check the DVB_API_VERSION #define. + + Currently we use version 3, it will be incremented whenever an API change + meets the CVS main branch. + +------------------------------------------------------------------------------- + +What is a demultiplexer? + + The demultiplexer in your DVB system cares about the routing of an MPEG2 + stream you feed into the DVB adapter either by read/write system calls, + by using stream inputs of the demultiplexer or the frontend(s). + + Using the demux API you can set up the stream routing and set up filters to + filter the interesting parts of the input streams only. + +------------------------------------------------------------------------------- + +I have set up the frontend and now I want to see some video! +What do I have to do? + + When you have an MPEG video decoder on board you can set up the demultiplexer + to feed the related PES packets into the MPEG decoder: + + #include <linux/dvb/dmx.h> + + struct dmx_pes_filter_params pesfilter; + + if ((fd = open("/dev/dvb/adapter0/demux0", O_RDWR) < 0) { + perror ("open failed"); + return -1; + } + + pesfilter.pid = pid; + pesfilter.input = DMX_IN_FRONTEND; + pesfilter.output = DMX_OUT_DECODER; + pesfilter.pes_type = DMX_PES_VIDEO; + pesfilter.flags = DMX_IMMEDIATE_START; + + if (ioctl(fd, DMX_SET_PES_FILTER, &pesfilter) < 0) { + perror ("ioctl DMX_SET_PES_FILTER failed"); + return -1; + } + + This will unpack the payload from all transport stream packets with + packet ID <pid> and feed it into the MPEG decoder. When pes_type is set + to DMX_PES_VIDEO it will be handled as video data. Other types are + DMX_PES_AUDIO, DMX_PES_TELETEXT, DMX_PES_SUBTITLE which will be fed into + the corresponding decoders (if these deocders exist in hardware or firmware). + DMX_PES_TELETEXT usually means VBI insertion by the PAL/NTSC encoder for display + on a connected TV set. If you want to avoid sending the data to one of the + decoders, use pes_type = DMX_PES_OTHER. + + You must open the demux device once for each PES filter you want to set. + E.g. if you want audio and video, you must have two distinct file descriptors + for the two filters. + + DMX_PES_PCR is used by the decoder to achieve a correct timing syncronisation + between the audio/video/... substreams. + + Note that you have to keep the frontend and demux filedescriptor open until + you are not interested in the stream anymore. Old API versions did not shut + down the demodulator and decoder, new driver versions can be configured to + power down after the device is closed. + +------------------------------------------------------------------------------- + +I want to record a stream to disk! How? + + Set up a filter for each substream you want to record as above but set + the pesfilter.output field to DMX_OUT_TAP. Then you can use read() calls + to receive PES data. + + When you want to receive transport stream packets use DMX_OUT_TS_TAP and + read the stream from /dev/dvb/adapterX/dvrY. The dvr device gives you + a multiplex of all filtered PES data with DMX_OUT_TS_TAP. E.g. if you + want to record video and audio, open demuxX twice and set two PEs filters + with DMX_OUT_TS_TAP, and open dvrX once to read the TS. + + [ The current API does not allow you to specify you an input/output + routing for section filters. So you can't get multiplexed section + data from the dvr device. ] + + Don't forget to keep all device filedescriptors you use open. + +------------------------------------------------------------------------------- + +I want to play back a recorded stream from disk! How? + + Just do the opposite as above. pesfilter.input is now DMX_IN_DVR. + Write your transport stream into the dvr device. + +------------------------------------------------------------------------------- + +What the heck are section filters? + + On some pid's in an MPEG2 stream data is transmitted in form of sections. + These sections describe the stream content, provider data, service + information and other things. + + Here a short list of some pid's where section data is transmitted on DVB + streams: + + 0x00 PAT (Program Association Table - refers to PMT's) + 0x10 NIT (Network Information Table - frequency lists etc) + 0x11 SDT (Service Description Table - service names etc) + 0x12 EIT (Event Information Table - event descriptions etc) + 0x14 TDT/TOT (Time and Date Table, Time Offset Table - time and timezone) + + For a complete list look into the ITU H222.0 (MPEG2) and ETSI EN300468 + standards, there you also find some informations how to parse these sections. + + When you want to receive this data the simple way you can set up a section + filter. + +------------------------------------------------------------------------------- + +How to set up a section filter? + + #include <linux/dvb/dmx.h> + + struct dmx_sct_filter_params sctfilter; + + if ((fd = open("/dev/dvb/adapter0/demux0", O_RDWR) < 0) { + perror ("open failed"); + return -1; + } + + memset(&sctfilter, 0, sizeof(struct dmx_sct_filter_params)); + + sctfilter.pid = pid; + sctfilter.flags = DMX_IMMEDIATE_START; + + if (ioctl(fd, DMX_SET_FILTER, &sctfilter) < 0) { + perror ("ioctl DMX_SET_FILTER failed"); + return -1; + } + + Now start subsequent read() calls to receive your sections and parse them. + Your read-buffer should be at least 4096 bytes if you want to receive complete + sections, otherwise you have to put the parts together manually. + + If your read() call returns -EOVERFLOW you were not fast enough to read/ + process the section data, the internal driver ringbuffer was overflown. + + This error is usually not critical since section data is transmitted + periodically. Anyway, you can adjust the ringbuffer size with the + DMX_SET_BUFFER_SIZE ioctl. + +------------------------------------------------------------------------------- + +How to do table id filtering? + + The struct dmx_sct_filter_params contains two fields filter.filter and + filter.mask. set those mask bits to '1' which should be equal to the filter + bits you set: + + /* set up a TDT filter, table id 0x70 */ + sctfilter.pid = pid; + sctfilter.filter.filter[0] = 0x70; + sctfilter.filter.mask[0] = 0xff; + sctfilter.flags = DMX_IMMEDIATE_START; + + Then submit the DMX_SET_FILTER ioctl. + + The filter comprises 16 bytes covering byte 0 and byte 3..17 in a section, + thus excluding bytes 1 and 2 (the length field of a section). + +------------------------------------------------------------------------------- + +What are not-equal filters? + + When you want to get notified about a new version of a section you can set + up a not-equal filter. Set those filter.mode bits to '1' for which the filter + should pass a section when the corresponding section bit is not equal to the + corresponding filter bit. + +------------------------------------------------------------------------------- + diff --git a/dvb-spec/HOWTO-use-the-frontend-api b/dvb-spec/HOWTO-use-the-frontend-api new file mode 100644 index 000000000..7f5456d1e --- /dev/null +++ b/dvb-spec/HOWTO-use-the-frontend-api @@ -0,0 +1,204 @@ + +------------------------------------------------------------------------------- + +What has changed since the old Nokia OST API? + + file naming: + - /dev/ost directory is now called /dev/dvb + - each DVB adapter has it's own directory /dev/dvb/adapterX + - here you'll find a number of frontend devices /dev/dvb/adapterX/frontendY + - driver header directory is located now in /usr/include/linux/dvb/ + - we have a linux/dvb/version.h file, this is included by all headers which + don't use the original OST API anymore + + struct naming: + - we follow the kernel naming scheme and try to get the namespace clean, + these changes are mostly syntactical + + DiSEqC: + - DiSEqC 2.0 ioctls + - the sec-device is gone, DiSEqC ioctls are passed to the frontend + filedescriptor - this matches the hardware better + - the old secCmdSequence is replaced by lowlevel FE_DISEQC_XXX ioctls, + this allows asynchronous DiSEqC, DiSEqC 2.0 and more flexibility for + cascaded devices and exotic setup + + frontend events: + - the event struct is simplified, you get an event now whenever one of the + frontend status bits changes + + ioctls: + - FE_SELFTEST is gone, was a noop anyway + - FE_GET_NEXT_FREQUENCY and FE_GET_NEXT_SYMBOL_RATE are gone, + this information can be obtained with FE_GET_INFO + - FE_SET_POWER_STATE is gone, powermanagement is done implicitly by device + open()/close() calls + +------------------------------------------------------------------------------- + +How to determine the API version? + + Check in your configure script for #include <linux/dvb/version.h>, + include it and check the DVB_API_VERSION #define. + + Currently we use version 3, it will be incremented whenever an API change + meets the CVS main branch. + +------------------------------------------------------------------------------- + +What is a DVB frontend? + + the term 'frontend' refers to this part of the DVB adapter which receives + an MPEG transport stream and will feed it later into the Demultiplexer. + Whenever you want to receive MPEG streams via satellite, antenna or cable + you have to set up your frontend first. + + When you watch on your DVB card or into your SetTopBox the frontend is usually + the combination of a demodulator chip and a small silver metal box with the + HF electronic. Usually the demodulator is built into this metal box. + +------------------------------------------------------------------------------- + +What do you have to do to set up your frontend? + + First you should try to determine the type of your frontend. + + #include <linux/dvb/frontend.h> + + struct dvb_frontend_info info; + int fd; + + if ((fd = open ("/dev/dvb/adapter0/frontend0", O_RDWR)) < 0) { + perror ("open failed"); + return -1; + } + + ioctl (fd, FE_GET_INFO, &info); + + Now the info.type field contains either FE_QPSK for a satellite frontend, + FE_QAM for a cable frontend or FE_OFDM for a terrestrial frontend. + + The info.name field contains a human readable vendor string of your frontend. + You might want to show this in your GUI to make support easier. + + The info struct also contains the frequency limits, frontend capabilities, + the frequency and symbol rate tolerance the AFC or timing recovery loop can + compensate and some fields you are not interested in. + +------------------------------------------------------------------------------- + +How to set up a cable or terrestrial frontend? + + Fill a dvb_frontend_parameters struct according to the data in your channel + list. For cable frontends, you have to fill the qam field of the union, for + terrestrial frontends it's the ofdm field. + + Apply it using the FE_SET_FRONTEND_PARAMETERS ioctl. That's all. + +------------------------------------------------------------------------------- + +How to set up a satellite frontend? + + Before you set the frontend parameters you have to setup DiSEqC switches and + the LNB. Modern LNB's switch their polarisation depending of the DC component + of their input (13V for vertical polarisation, 18V for horizontal). When they + see a 22kHz signal at their input they switch into the high band and use a + somewhat higher intermediate frequency to downconvert the signal. + + When your satellite equipment contains a DiSEqC switch device to switch + between different satellites you have to send the according DiSEqC commands, + usually command 0x38. Take a look into the DiSEqC spec available at + http://www.eutelsat.org/ for the complete list of commands. + + The burst signal is used in old equipments and by cheap satellite A/B + switches. + + Voltage, burst and 22kHz tone have to be consistent to the values encoded in + the DiSEqC commands. + + The complete sequence to set up switch and LNB according to the DiSEqC spec + looks like this: + + - stop continous tone + - setup polarisation voltage + - wait at least 15ms. + - send your DiSEqC commands using the FE_DISEQC_SEND_MASTER_CMD ioctl + - wait another 15ms + - send burst + - wait 15ms + - start the 22kHz tone when you tune to a transponder in the high band + + You can copy'n'paste this code sniplets from szap.c or diseqc.c, both + test programs are distributed with the linuxtv DVB driver source. All + DiSEqC related ioctls are passed to the frontend device filedescriptor. + + Depending on the equipment setup, you may or may not have to repeat the + DiSEqC commands (only commands, not the whole sequence) for cascaded devices + and can pack committed/uncommitted switch messages. See the DiSEqC spec for + details. + + In an advanced program, you probably want to send this sequence using an + asynchonous thread. Since sleep() and similiar calls are pthread + cancellation points, it's really simple to stop a running DiSEqC thread + before submitting a new sequence. + + Now you have set up switch and LNB, a valid RF signal of the requested + satellite should be at the input of the demodulator. + + Fill a dvb_frontend_parameters struct using the qpsk field in the union and + apply it using the FE_SET_FRONTEND_PARAMETERS ioctl. + +------------------------------------------------------------------------------- + +How do I check the frontend status? + + You can perform a poll()/select() on the frontend file descriptor. Whenever + one of the frontend status bits toggles the poll returns. Now you can + submit the FE_GET_EVENT ioctl to receive the new status bits. When you used + one of the XXX_AUTO parameters you might want to use the event.parameters + field to determine the correct tuned parameters and update your channel list. + + If you want to simulate the old FE_FAILURE_EV frontend event behaviour you + should check the FE_TIMEDOUT bit, this will be set when the tuning was not + successful within a few seconds. + + When you get a FE_REINIT event the frontend was reinitialized. You should + send the DiSEqC sequence again if you use a QPSK frontend. + + The FE_READ_SIGNAL_STRENGTH ioctl will fill the signal strength into the + 16 LSBs of the passed argument. The signal strength range is from 0 (bad) + to 65535 (too good to be true). + + FE_READ_SNR returns the signal noise ratio. range 0 (bad) to 65535 (not real). + For both the signal strength and signal noise ratio a value of about 60-70% + means a good signal. + + Not all FE_READ_XXX ioctl()s are supported by all hardware. Check the ioctl + return value, if it's less than 0 this ioctl is not supported. + +------------------------------------------------------------------------------- + +What does FE_ENABLE_HIGH_LNB_VOLTAGE? + + some STBs (the dbox2 for example) support somewhat higher LNB voltages than + 13 and 18V. They add about 0.5V to compensate voltage drop on long cables. + + This ioctl is not supported on all boxes. You probably want to show an extra + menu item in your GUI when this ioctl returns a zero value. + +------------------------------------------------------------------------------- + +How to do powermanagement, the FE_SET_POWER_STATE ioctls are gone? + + An open() call on the frontend device powers up and initializes the + demodulator and switches on LNB power if necessairy. The DiSEqC bus won't + be resetted, do this manually if you think you need to. + + Some seconds after the device is closed (and was not opened by a new process) + LNB power and the demodulator are shut down into sleep mode. + + You can configure the shutdown timeout using the shutdown_timeout module + parameter. To disable power management set shutdown_timeout=0. + +------------------------------------------------------------------------------- + diff --git a/dvb-spec/README.CABLE b/dvb-spec/README.CABLE index de13af020..0a8466f6d 100644 --- a/dvb-spec/README.CABLE +++ b/dvb-spec/README.CABLE @@ -1,5 +1,5 @@ -- The analog module is not fully supported yet. - The MSP3400 module will have to be extended to handle then audio and - video switching for the module. - If you want sound you will have to remove the module for now. - +- The analog module of the DVB-C should be detected automatically. + +- If you are using a Technotrend/Hauppauge DVB-C card *without* analog module, + you might have to use module parameter adac=-1 (dvb-ttpci.o). + diff --git a/dvb-spec/README.valgrind b/dvb-spec/README.valgrind new file mode 100644 index 000000000..c1ce7c994 --- /dev/null +++ b/dvb-spec/README.valgrind @@ -0,0 +1,13 @@ +valgrind-1.0pre3-dvb.patch enables checking correct usage +of the the Linux DVB API ioctls with valgrind +(http://developer.kde.org/~sewardj/). Or, more to the point, +it allows you to check your DVB software with valgrind +without getting all those "unknown ioctl" warnings. + +Notes: +- only frontend and demux ioctls are currently implemented +- some ioctls take structs as arguments; due to padding, valgrind + will complain about uninitialized data passed to the ioctl unless + you memset() the whole struct to some defined value + +Johannes Stezenbach <js@convergence.de> diff --git a/dvb-spec/channel b/dvb-spec/channel deleted file mode 100644 index f17e8cb19..000000000 --- a/dvb-spec/channel +++ /dev/null @@ -1,104 +0,0 @@ -This file describes the format of the new channel config file. - -Comments start with # -Each section starts with one of the identifiers: LNB, DISEQC, ROTOR, ... - -IDs are either the official transponder, network, etc. id if it exists -and is unique, otherwise it is just a consecutive number assigned by -the application. -An LNB can also describe a cable TV outlet or a terrestrial antenna. -Names (as all parameters in brackets) are optional. In this case the -application should use the ID as name. - -The application should offer selection sorted by channel number, network, -satellite, bouquet. - - -# satellite definition -SAT - ID satid # ID = xxxy, sat is at position xxx.y degrees - [NAME name] - LNBID lnbid # LNB this sat is received with - [ROTORID rotorid] # rotor commands to position it on this sat - -# LNB definition -LNB - ID lnbid - [NAME name] - [INPUT input] # input of card which the lnb is connected to (default 0) - TYPE type # LNB, CATV or terrestrial antenna? - LOF1 offset1 # local oscillator frequency 1 - LOF2 offset2 # local oscillator frequency 2 - SLOF switchfreq # switching frequency - [DISEQCNR diseqcnr] # simple 2- or 4-switch DiSEqC - [DISEQCID diseqcid] - [INPUT input] - [SWITCHID switchid] - -# A transponder definition -TRANSPONDER - ID tpid - TYPE type # digital (DVB-S(1), C(2) or T(3)) or analog(0) ? - SATID satid - [NAME name] # if analog this is the channel name - FREQ freq - POL H/V - [QAM qam] # only needed if DVB-C - [SRATE sr] # only if DVB - [FEC fec] # only if DVB - [PICID picid] # picture attributes for all channels on this transponder - -# channel definition (only if DVB) -CHANNEL - ID channelid - [NAME name] - TPID tpid - TYPE type - PNR pnr - VPID vpid - APID apid - TPID tpid - [PMTPID pmtpid] - [PCRPID pcrpid] - [APID apid2 APID apid3 ... APID apidn] # more audio PIDs for several languages - [AC3PID ac3] - [NETWID networkid] - [BOUQID bouquetid] - [PICID picid] - -# network definition -NETWORK - ID nwid - [NAME name] - -# bouquet definition -BOUQUET - ID bqid - [NAME name] - - - -# These will be implemented later - -# DiSEqC command sequence -DISEQC - ID disid - [NAME name] - MESSAGE data1 [ ... datan ] BURST 0/1 END - [MESSAGE data1 [ ... datan ] BURST 0/1 END ...] - -# DiSEqC switch -SWITCH - ID switchid - SWITCHID switchid # next "higher" switch - [NAME name] - MESSAGE data1 [ ... datan ] BURST 0/1 END - - -# DiSEqC rotor command sequence leading to a certain rotor position -ROTOR - ID rotid - POS degrees - MESSAGE data1 [ ... datan ] BURST 0/1 END - [MESSAGE data1 [ ... datan ] BURST 0/1 END ...] - diff --git a/dvb-spec/dvbapi/.cvsignore b/dvb-spec/dvbapi/.cvsignore new file mode 100644 index 000000000..89f9afcb7 --- /dev/null +++ b/dvb-spec/dvbapi/.cvsignore @@ -0,0 +1,14 @@ +dvbapi.ps +dvbstb.ps +dvbstb.pst +dvbapi.bbl +dvbapi.aux +dvbapi.blg +dvbapi.dvi +dvbapi.log +dvbapi.pdf +dvbapi.out +dvbapi.toc +dvbapi.ind +dvbapi.ilg +dvbapi diff --git a/dvb-spec/dvbapi/Makefile b/dvb-spec/dvbapi/Makefile index fe9827cff..e741df6da 100644 --- a/dvb-spec/dvbapi/Makefile +++ b/dvb-spec/dvbapi/Makefile @@ -1,19 +1,16 @@ all: dvbapi.ps dvbapi.pdf -TEXS= dvbapi.tex devices.tex video.tex audio.tex ca.tex sec.tex frontend.tex \ - intro.tex title.tex dvbstb.ps +TEXS= dvbapi.tex devices.tex video.tex audio.tex ca.tex net.tex frontend.tex \ + demux.tex kdapi.tex examples.tex intro.tex title.tex dvbstb.ps dvbapi.pdf: dvbapi.dvi - dvipdf $< $@ + dvipdf $< $@ dvbapi.ps: dvbapi.dvi - dvips -o $@ $< + dvips -f $< -o $@ dvbapi.dvi: dvbapi.bbl $(TEXS) -latex dvbapi - -bibtex dvbapi - -makeindex dvbapi - -latex dvbapi -latex dvbapi dvbapi.bbl: $(TEXS) @@ -21,6 +18,9 @@ dvbapi.bbl: $(TEXS) -bibtex dvbapi -makeindex dvbapi +html: dvbapi.dvi + latex2html -address "LinuxTV DVB API" -long_titles 4 -split 3 dvbapi.tex + %.ps: %.fig ./fig2pstex $< @@ -28,3 +28,4 @@ clean: rm -f dvbapi.dvi rm -f *.aux *.bbl *.blg *.idx *.ilg *.ind *.log *.out *.toc rm -f *.pdf *.pst *.ps + rm -rf dvbapi diff --git a/dvb-spec/dvbapi/audio.tex b/dvb-spec/dvbapi/audio.tex index e81dd2f89..05c23e56f 100644 --- a/dvb-spec/dvbapi/audio.tex +++ b/dvb-spec/dvbapi/audio.tex @@ -1,7 +1,13 @@ \devsec{DVB Audio Device} The DVB audio device controls the MPEG2 audio decoder of the DVB hardware. -It can be accessed through \texttt{/dev/ost/audio}. +It can be accessed through \texttt{/dev/dvb/adapter0/audio0}. +Data types and and ioctl definitions can be accessed by including +\texttt{linux/dvb/video.h} in your application. + +Please note that some DVB cards don't have their own +MPEG decoder, which results in the omission of the audio and video +device. \devsubsec{Audio Data Types} @@ -9,16 +15,16 @@ It can be accessed through \texttt{/dev/ost/audio}. This section describes the structures, data types and defines used when talking to the audio device. -\devsubsubsec{audioStreamSource\_t} +\devsubsubsec{audio\_stream\_source\_t} \label{audiostreamsource} The audio stream source is set through the AUDIO\_SELECT\_SOURCE call and can take the following values, depending on whether we are -replaying from an internal (demuxer) or external (user write) source. +replaying from an internal (demux) or external (user write) source. \begin{verbatim} typedef enum { AUDIO_SOURCE_DEMUX, AUDIO_SOURCE_MEMORY -} audioStreamSource_t; +} audio_stream_source_t; \end{verbatim} AUDIO\_SOURCE\_DEMUX selects the demultiplexer (fed either by the frontend or the DVR device) as the source of @@ -27,7 +33,7 @@ If AUDIO\_SOURCE\_MEMORY is selected the stream comes from the application through the \texttt{write()} system call. -\devsubsubsec{audioPlayState\_t} +\devsubsubsec{audio\_play\_state\_t} The following values can be returned by the AUDIO\_GET\_STATUS call representing the state of audio playback. \label{audioplaystate} @@ -36,45 +42,45 @@ typedef enum { AUDIO_STOPPED, AUDIO_PLAYING, AUDIO_PAUSED -} audioPlayState_t; +} audio_play_state_t; \end{verbatim} -\devsubsubsec{audioChannelSelect\_t} +\devsubsubsec{audio\_channel\_select\_t} \label{audiochannelselect} The audio channel selected via AUDIO\_CHANNEL\_SELECT is determined by -the following values. +the following values. \begin{verbatim} typedef enum { AUDIO_STEREO, AUDIO_MONO_LEFT, AUDIO_MONO_RIGHT, -} audioChannelSelect_t; +} audio_channel_select_t; \end{verbatim} -\devsubsubsec{audioStatus\_t} +\devsubsubsec{struct audio\_status} \label{audiostatus} The AUDIO\_GET\_STATUS call returns the following structure informing about various states of the playback operation. \begin{verbatim} -typedef struct audioStatus { - boolean AVSyncState; - boolean muteState; - audioPlayState_t playState; - audioStreamSource_t streamSource; - audioChannelSelect_t channelSelect; - boolean bypassMode; -} audioStatus_t; +typedef struct audio_status { + boolean AV_sync_state; + boolean mute_state; + audio_play_state_t play_state; + audio_stream_source_t stream_source; + audio_channel_select_t channel_select; + boolean bypass_mode; +} audio_status_t; \end{verbatim} -\devsubsubsec{audioMixer\_t} +\devsubsubsec{struct audio\_mixer} \label{audiomixer} The following structure is used by the AUDIO\_SET\_MIXER call to set the audio volume. \begin{verbatim} -typedef struct audioMixer { +typedef struct audio_mixer { unsigned int volume_left; unsigned int volume_right; -} audioMixer_t; +} audio_mixer_t; \end{verbatim} \devsubsubsec{audio encodings} @@ -94,25 +100,31 @@ the following bits set according to the hardwares capabilities. \end{verbatim} -\devsubsubsec{audio karaoke} +\devsubsubsec{struct audio\_karaoke} \label{audiokaraoke} The ioctl AUDIO\_SET\_KARAOKE uses the following format: \begin{verbatim} typedef -struct audioKaraoke{ /* if Vocal1 or Vocal2 are non-zero, they get mixed */ - int vocal1; /* into left and right t at 70% each */ - int vocal2; /* if both, Vocal1 and Vocal2 are non-zero, Vocal1 gets */ - int melody; /* mixed into the left channel and */ - /* Vocal2 into the right channel at 100% each. */ - /* if Melody is non-zero, the melody channel gets mixed */ /* into left and right */ -} audioKaraoke_t; +struct audio_karaoke{ + int vocal1; + int vocal2; + int melody; +} audio_karaoke_t; \end{verbatim} +If Vocal1 or Vocal2 are non-zero, they get mixed +into left and right t at 70\% each. +If both, Vocal1 and Vocal2 are non-zero, Vocal1 gets +mixed into the left channel and +Vocal2 into the right channel at 100\% each. +Ff Melody is non-zero, the melody channel gets mixed +into left and right. + \devsubsubsec{audio attributes} \label{aattrib} The following attributes can be set by a call to AUDIO\_SET\_ATTRIBUTES: \begin{verbatim} -typedef uint16_t audioAttributes_t; +typedef uint16_t audio_attributes_t; /* bits: descr. */ /* 15-13 audio coding mode (0=ac3, 2=mpeg1, 3=mpeg2ext, 4=LPCM, 6=DTS, */ /* 12 multichannel extension */ @@ -130,7 +142,7 @@ typedef uint16_t audioAttributes_t; \function{open()}{ int open(const char *deviceName, int flags);}{ - This system call opens a named audio device (e.g. /dev/ost/audio) for subsequent + This system call opens a named audio device (e.g. /dev/dvb/adapter0/audio0) for subsequent use. When an open() call has succeeded, the device will be ready for use. The significance of blocking or non-blocking mode is described in the documentation for functions where there is a difference. It does not affect @@ -225,7 +237,7 @@ typedef uint16_t audioAttributes_t; \ifunction{AUDIO\_SELECT\_SOURCE}{ int ioctl(int fd, int request = AUDIO\_SELECT\_SOURCE, - audioStreamSource\_t source);}{ + audio\_stream\_source\_t source);}{ This ioctl call informs the audio device which source shall be used for the input data. The possible sources are demux or memory. If AUDIO\_SOURCE\_MEMORY @@ -233,7 +245,7 @@ typedef uint16_t audioAttributes_t; }{ int fd & File descriptor returned by a previous call to open().\\ int request & Equals AUDIO\_SELECT\_SOURCE for this command.\\ - audioStreamSource\_t source& Indicates the source that shall be used for the + audio\_stream\_source\_t source& Indicates the source that shall be used for the Audio stream. }{ EBADF& fd is not a valid open file descriptor.\\ @@ -295,13 +307,13 @@ typedef uint16_t audioAttributes_t; \ifunction{AUDIO\_CHANNEL\_SELECT}{ int ioctl(int fd, int request = AUDIO\_CHANNEL\_SELECT, - audioChannelSelect\_t);}{ + audio\_channel\_select\_t);}{ This ioctl call asks the Audio Device to select the requested channel if possible. }{ int fd & File descriptor returned by a previous call to open().\\ int request & Equals AUDIO\_CHANNEL\_SELECT for this command.\\ - audioChannelSelect\_t ch & + audio\_channel\_select\_t ch & Select the output format of the audio (mono left/right, stereo). }{ EBADF& fd is not a valid open file descriptor.\\ @@ -311,13 +323,13 @@ typedef uint16_t audioAttributes_t; \ifunction{AUDIO\_GET\_STATUS}{ int ioctl(int fd, int request = AUDIO\_GET\_STATUS, - struct audioStatus *status);}{ + struct audio\_status *status);}{ This ioctl call asks the Audio Device to return the current state of the Audio Device. }{ int fd & File descriptor returned by a previous call to open().\\ int request & Equals AUDIO\_GET\_STATUS for this command.\\ - struct audioStatus *status & Returns the current state of Audio Device. + struct audio\_status *status & Returns the current state of Audio Device. }{ EBADF& fd is not a valid open file descriptor.\\ EINTERNAL & Internal error.\\ @@ -371,12 +383,12 @@ typedef uint16_t audioAttributes_t; } \ifunction{AUDIO\_SET\_MIXER}{ - int ioctl(int fd, int request = AUDIO\_SET\_MIXER, audioMixer\_t *mix);}{ + int ioctl(int fd, int request = AUDIO\_SET\_MIXER, audio\_mixer\_t *mix);}{ This ioctl lets you adjust the mixer settings of the audio decoder. }{ int fd & File descriptor returned by a previous call to open().\\ int request & Equals AUDIO\_SET\_ID for this command.\\ - audioMixer\_t *mix& mixer settings. + audio\_mixer\_t *mix& mixer settings. }{ EBADF& fd is not a valid open file descriptor.\\ EINTERNAL & Internal error.\\ @@ -412,25 +424,25 @@ typedef uint16_t audioAttributes_t; } \ifunction{AUDIO\_SET\_ATTRIBUTES}{ - int ioctl(fd, int request = AUDIO\_SET\_ATTRIBUTES, audioAttributes\_t attr );}{ + int ioctl(fd, int request = AUDIO\_SET\_ATTRIBUTES, audio\_attributes\_t attr );}{ This ioctl is intended for DVD playback and allows you to set certain information about the audio stream. }{ int fd & File descriptor returned by a previous call to open().\\ int request & Equals AUDIO\_SET\_ATTRIBUTES for this command.\\ - iaudioAttributes\_t attr & audio attributes according to section \ref{aattrib}\\ + audio\_attributes\_t attr & audio attributes according to section \ref{aattrib}\\ }{ EBADF& fd is not a valid open file descriptor \\ EINVAL& attr is not a valid or supported attribute setting.\\ } \ifunction{AUDIO\_SET\_KARAOKE}{ - int ioctl(fd, int request = AUDIO\_SET\_STREAMTYPE, audioKaraoke\_t *karaoke);}{ + int ioctl(fd, int request = AUDIO\_SET\_STREAMTYPE, audio\_karaoke\_t *karaoke);}{ This ioctl allows one to set the mixer settings for a karaoke DVD. }{ int fd & File descriptor returned by a previous call to open().\\ int request & Equals AUDIO\_SET\_STREAMTYPE for this command.\\ - audioKaraoke\_t *karaoke & karaoke settings according to section \ref{audiokaraoke}.\\ + audio\_karaoke\_t *karaoke & karaoke settings according to section \ref{audiokaraoke}.\\ }{ EBADF & fd is not a valid open file descriptor \\ EINVAL& karaoke is not a valid or supported karaoke setting.\\ diff --git a/dvb-spec/dvbapi/ca.tex b/dvb-spec/dvbapi/ca.tex index eba512b1b..fe76da454 100644 --- a/dvb-spec/dvbapi/ca.tex +++ b/dvb-spec/dvbapi/ca.tex @@ -1,7 +1,9 @@ \devsec{DVB CA Device} The DVB CA device controls the conditional access hardware. -It can be accessed through \texttt{/dev/ost/ca}. +It can be accessed through \texttt{/dev/dvb/adapter0/ca0}. +Data types and and ioctl definitions can be accessed by including +\texttt{linux/dvb/ca.h} in your application. \devsubsec{CA Data Types} diff --git a/dvb-spec/dvbapi/demux.tex b/dvb-spec/dvbapi/demux.tex index 541ee633a..882463090 100644 --- a/dvb-spec/dvbapi/demux.tex +++ b/dvb-spec/dvbapi/demux.tex @@ -1,16 +1,14 @@ \devsec{DVB Demux Device} The DVB demux device controls the filters of the DVB hardware/software. -It can be accessed through \texttt{/dev/ost/demux}. +It can be accessed through \texttt{/dev/adapter0/demux0}. +Data types and and ioctl definitions can be accessed by including +\texttt{linux/dvb/dmx.h} in your application. \devsubsec{Demux Data Types} -\begin{verbatim} -typedef uint16_t dvb_pid_t; -\end{verbatim} - -\devsubsubsec{dmxOutput\_t} +\devsubsubsec{dmx\_output\_t} \label{dmxoutput} \begin{verbatim} @@ -19,26 +17,30 @@ typedef enum DMX_OUT_DECODER, DMX_OUT_TAP, DMX_OUT_TS_TAP -} dmxOutput_t; +} dmx_output_t; \end{verbatim} -/* Output multiplexed into a new TS */ -/* (to be retrieved by reading from the */ -/* logical DVR device). */ + +\noindent\texttt{DMX\_OUT\_TAP} delivers the stream output to the demux device +on which the ioctl is called. + +\noindent\texttt{DMX\_OUT\_TS\_TAP} routes output to the logical DVR device +\texttt{/dev/dvb/adapter0/dvr0}, which delivers a TS multiplexed from +all filters for which \texttt{DMX\_OUT\_TS\_TAP} was specified. -\devsubsubsec{dmxInput\_t} +\devsubsubsec{dmx\_input\_t} \label{dmxinput} \begin{verbatim} typedef enum { - DMX_IN_FRONTEND, /* Input from a front-end device. */ - DMX_IN_DVR /* Input from the logical DVR device. */ -} dmxInput_t; + DMX_IN_FRONTEND, + DMX_IN_DVR +} dmx_input_t; \end{verbatim} -\devsubsubsec{dmxPesType\_t} +\devsubsubsec{dmx\_pes\_type\_t} \label{dmxpestype} \begin{verbatim} @@ -50,11 +52,11 @@ typedef enum DMX_PES_SUBTITLE, DMX_PES_PCR, DMX_PES_OTHER -} dmxPesType_t; +} dmx_pes_type_t; \end{verbatim} -\devsubsubsec{dmxEvent\_t} +\devsubsubsec{dmx\_event\_t} \label{dmxeventt} \begin{verbatim} @@ -62,11 +64,11 @@ typedef enum { DMX_SCRAMBLING_EV, DMX_FRONTEND_EV -} dmxEvent_t; +} dmx_event_t; \end{verbatim} -\devsubsubsec{dmxScramblingStatus\_t} +\devsubsubsec{dmx\_scrambling\_status\_t} \label{dmxscramblingstatus} \begin{verbatim} @@ -74,32 +76,32 @@ typedef enum { DMX_SCRAMBLING_OFF, DMX_SCRAMBLING_ON -} dmxScramblingStatus_t; +} dmx_scrambling_status_t; \end{verbatim} -\devsubsubsec{dmxFilter\_t} +\devsubsubsec{struct dmx\_filter} \label{dmxfilter} \begin{verbatim} -typedef struct dmxFilter +typedef struct dmx_filter { uint8_t filter[DMX_FILTER_SIZE]; uint8_t mask[DMX_FILTER_SIZE]; -} dmxFilter_t; +} dmx_filter_t; \end{verbatim} -\devsubsubsec{dmxSctFilterParams} +\devsubsubsec{struct dmx\_sct\_filter\_params} \label{dmxsctfilterparams} \begin{verbatim} -struct dmxSctFilterParams +struct dmx_sct_filter_params { - dvb_pid_t pid; - dmxFilter_t filter; - uint32_t timeout; - uint32_t flags; + uint16_t pid; + dmx_filter_t filter; + uint32_t timeout; + uint32_t flags; #define DMX_CHECK_CRC 1 #define DMX_ONESHOT 2 #define DMX_IMMEDIATE_START 4 @@ -107,51 +109,61 @@ struct dmxSctFilterParams \end{verbatim} -\devsubsubsec{dmxPesFilterParams} +\devsubsubsec{struct dmx\_pes\_filter\_params} \label{dmxpesfilterparams} \begin{verbatim} -struct dmxPesFilterParams +struct dmx_pes_filter_params { - dvb_pid_t pid; - dmxInput_t input; - dmxOutput_t output; - dmxPesType_t pesType; - uint32_t flags; + uint16_t pid; + dmx_input_t input; + dmx_output_t output; + dmx_pes_type_t pes_type; + uint32_t flags; }; \end{verbatim} -\devsubsubsec{dmxEvent} +\devsubsubsec{struct dmx\_event} \label{dmxevent} \begin{verbatim} -struct dmxEvent +struct dmx_event { - dmxEvent_t event; - time_t timeStamp; + dmx_event_t event; + time_t timeStamp; union { - dmxScramblingStatus_t scrambling; + dmx_scrambling_status_t scrambling; } u; }; \end{verbatim} +\devsubsubsec{struct dmx\_stc} +\label{dmxstc} + +\begin{verbatim} +struct dmx_stc { + unsigned int num; /* input : which STC? 0..N */ + unsigned int base; /* output: divisor for stc to get 90 kHz clock */ + uint64_t stc; /* output: stc in 'base'*90 kHz units */ +}; +\end{verbatim} + \clearpage \devsubsec{Demux Function Calls} \function{open()}{ int open(const char *deviceName, int flags);}{ - This system call, used with a device name of /dev/ost/demuxn, where n - denotes the specific demux device to be opened, allocates a new filter + This system call, used with a device name of /dev/dvb/adapter0/demux0, + allocates a new filter and returns a handle which can be used for subsequent control of that filter. This call has to be made for each filter to be used, i.e. every returned file descriptor is a reference to a single filter. - /dev/ost/dvrn is a logical device to be used for retrieving Transport - Streams for digital video recording. n identifies the physical demux - device that provides the actual DVR functionality. When reading from + /dev/dvb/adapter0/dvr0 is a logical device to be used for retrieving Transport + Streams for digital video recording. When reading from this device a transport stream containing the packets from all PES - filters set in the corresponding demux device (/dev/ost/demuxn) + filters set in the corresponding demux device (/dev/dvb/adapter0/demux0) having the output set to DMX\_OUT\_TS\_TAP. A recorded Transport Stream is replayed by writing to this device. % This device can only be opened in read-write mode. @@ -200,7 +212,7 @@ struct dmxEvent sized sections) by default. The size of this buffer may be changed by using the DMX\_SET\_BUFFER\_SIZE function. If the buffer is not large enough, or if the read operations are not performed fast enough, this may result - in a buffer overflow error. In this case EBUFFEROVERFLOW will be returned, + in a buffer overflow error. In this case EOVERFLOW will be returned, and the circular buffer will be emptied. This call is blocking if there is no data to return, i.e. the process will be put to sleep waiting for data, unless the O\_NONBLOCK flag is @@ -211,7 +223,7 @@ struct dmxEvent ioctl function or by setting the DMX\_IMMEDIATE\_START flag. If the reading is done from a logical DVR demux device, the data will constitute a Transport Stream including the packets from all PES filters - in the corresponding demux device /dev/ost/demuxn having the output set + in the corresponding demux device /dev/dvb/adapter0/demux0 having the output set to DMX\_OUT\_TS\_TAP. }{ int fd & File descriptor returned by a previous call to open().\\ @@ -222,7 +234,7 @@ struct dmxEvent EBADF & fd is not a valid open file descriptor.\\ ECRC & Last section had a CRC error - no data returned. The buffer is flushed.\\ - EBUFFEROVERFLOW & \\ + EOVERFLOW & \\ & The filtered data was not read from the buffer in due time, resulting in non-read data being lost. The buffer is flushed.\\ @@ -236,11 +248,11 @@ struct dmxEvent \function{write()}{ ssize\_t write(int fd, const void *buf, size\_t count); }{ - This system call is only provided by the logical device /dev/ost/dvrn, - where n identifies the physical demux device that provides the actual + This system call is only provided by the logical device /dev/dvb/adapter0/dvr0, + associated with the physical demux device that provides the actual DVR functionality. It is used for replay of a digitally recorded Transport Stream. Matching filters have to be defined in the - corresponding physical demux device, /dev/ost/demuxn. + corresponding physical demux device, /dev/dvb/adapter0/demux0. The amount of data to be transferred is implied by count. }{ int fd & File descriptor returned by a previous call to open().\\ @@ -295,7 +307,7 @@ struct dmxEvent } \ifunction{DMX\_SET\_FILTER}{ - int ioctl( int fd, int request = DMX\_SET\_FILTER, struct dmxSctFilterParams *params); + int ioctl( int fd, int request = DMX\_SET\_FILTER, struct dmx\_sct\_filter\_params *params); }{ This ioctl call sets up a filter according to the filter and mask parameters provided. A timeout may be defined stating number of seconds @@ -310,7 +322,7 @@ struct dmxEvent }{ int fd & File descriptor returned by a previous call to open().\\ int request & Equals DMX\_SET\_FILTER for this command.\\ - struct dmxSctFilterParams *params + struct dmx\_sct\_filter\_params *params & Pointer to structure containing filter parameters.\\ }{ EBADF & fd is not a valid file descriptor.\\ @@ -319,7 +331,7 @@ struct dmxEvent \ifunction{DMX\_SET\_PES\_FILTER}{ int ioctl( int fd, int request = DMX\_SET\_PES\_FILTER, - struct dmxPesFilterParams *params); + struct dmx\_pes\_filter\_params *params); }{ This ioctl call sets up a PES filter according to the parameters provided. By a PES filter is meant a filter that is based just on the packet @@ -335,7 +347,7 @@ struct dmxEvent }{ int fd & File descriptor returned by a previous call to open().\\ int request & Equals DMX\_SET\_PES\_FILTER for this command.\\ - struct dmxPesFilterParams *params + struct dmx\_pes\_filter\_params *params & Pointer to structure containing filter parameters.\\ }{ EBADF & fd is not a valid file descriptor.\\ @@ -364,9 +376,9 @@ struct dmxEvent } \ifunction{DMX\_GET\_EVENT}{ - int ioctl( int fd, int request = DMX\_GET\_EVENT, struct dmxEvent *ev); + int ioctl( int fd, int request = DMX\_GET\_EVENT, struct dmx\_event *ev); }{ - This ioctl call returns an event if available. If an event is not + This ioctl call returns an event if available. If an event is not available, the behavior depends on whether the device is in blocking or non-blocking mode. In the latter case, the call fails immediately with errno set to EWOULDBLOCK. In the former case, the call blocks until an @@ -379,13 +391,32 @@ struct dmxEvent }{ int fd & File descriptor returned by a previous call to open().\\ int request & Equals DMX\_GET\_EVENT for this command.\\ - struct dmxEvent *ev & Pointer to the location where the event is to be stored.\\ + struct dmx\_event *ev & Pointer to the location where the event is to be stored.\\ }{ EBADF & fd is not a valid file descriptor.\\ EFAULT & ev points to an invalid address.\\ EWOULDBLOCK & There is no event pending, and the device is in non-blocking mode.\\ } +\ifunction{DMX\_GET\_STC}{ + int ioctl( int fd, int request = DMX\_GET\_STC, struct dmx\_stc *stc); + }{ + This ioctl call returns the current value of the system time counter + (which is driven by a PES filter of type DMX\_PES\_PCR). Some hardware + supports more than one STC, so you must specify which one by setting + the num field of stc before the ioctl (range 0...n). The result is returned in form + of a ratio with a 64 bit numerator and a 32 bit denominator, so the + real 90kHz STC value is \begin{ttfamily}stc->stc / stc->base\end{ttfamily}. + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals DMX\_GET\_STC for this command.\\ + struct dmx\_stc *stc & Pointer to the location where the stc is to be stored.\\ + }{ + EBADF & fd is not a valid file descriptor.\\ + EFAULT & stc points to an invalid address.\\ + EINVAL & Invalid stc number.\\ +} + %%% Local Variables: %%% mode: latex %%% TeX-master: "dvbapi" diff --git a/dvb-spec/dvbapi/devices.tex b/dvb-spec/dvbapi/devices.tex index 9c561e853..11eccd897 100644 --- a/dvb-spec/dvbapi/devices.tex +++ b/dvb-spec/dvbapi/devices.tex @@ -1,9 +1,9 @@ -\input{video.tex} -\input{audio.tex} \input{frontend.tex} -\input{sec.tex} \input{demux.tex} +\input{video.tex} +\input{audio.tex} \input{ca.tex} +\input{net.tex} \input{kdapi.tex} %%% Local Variables: diff --git a/dvb-spec/dvbapi/dvbapi.tex b/dvb-spec/dvbapi/dvbapi.tex index e81940093..d75c2417f 100644 --- a/dvb-spec/dvbapi/dvbapi.tex +++ b/dvb-spec/dvbapi/dvbapi.tex @@ -1,4 +1,4 @@ -\documentclass[10pt]{book} +\documentclass[a4paper,10pt]{book} \usepackage[dvips,colorlinks=true]{hyperref} \usepackage{times} @@ -131,7 +131,7 @@ \renewcommand{\sectionmark}[1]{\markright{\thesection.\ #1}{}} \lhead[\fancyplain{}{\bfseries \thepage}]{\bfseries \rightmark} \rhead[\fancyplain{}{\bfseries \leftmark}]{\bfseries \thepage} -\cfoot{\copyright\ 2002 Convergence GmbH} +%\cfoot{\copyright\ 2002, 2003 Convergence GmbH} \input{intro.tex} diff --git a/dvb-spec/dvbapi/examples.tex b/dvb-spec/dvbapi/examples.tex index 114579b80..c9a19ba29 100644 --- a/dvb-spec/dvbapi/examples.tex +++ b/dvb-spec/dvbapi/examples.tex @@ -1,6 +1,10 @@ \chapter{Examples} In this section we would like to present some examples for using the DVB API. +Maintainer note: This section is out of date. Please refer to the sample +programs packaged with the driver distribution from +\texttt{http://linuxtv.org/}. + \section{Tuning} We will start with a generic tuning subroutine that uses the frontend and SEC, as well as the demux devices. The example is given for QPSK @@ -17,17 +21,17 @@ tuners, but can easily be adjusted for QAM. #include <time.h> #include <unistd.h> -#include <ost/dmx.h> -#include <ost/frontend.h> -#include <ost/sec.h> +#include <linux/dvb/dmx.h> +#include <linux/dvb/frontend.h> +#include <linux/dvb/sec.h> #include <sys/poll.h> -#define DMX "/dev/ost/demux" -#define FRONT "/dev/ost/frontend" -#define SEC "/dev/ost/sec" +#define DMX "/dev/dvb/adapter0/demux1" +#define FRONT "/dev/dvb/adapter0/frontend1" +#define SEC "/dev/dvb/adapter0/sec1" /* routine for checking if we have a signal and other status information*/ -int FEReadStatus(int fd, FrontendStatus *stat) +int FEReadStatus(int fd, fe_status_t *stat) { int ans; @@ -66,11 +70,11 @@ int set_qpsk_channel(int freq, int vpid, int apid, int tpid, { struct secCommand scmd; struct secCmdSequence scmds; - struct dmxPesFilterParams pesFilterParams; + struct dmx_pes_filter_params pesFilterParams; FrontendParameters frp; struct pollfd pfd[1]; FrontendEvent event; - int demux1, dmeux2, demux3, front, + int demux1, demux2, demux3, front; frequency = (uint32_t) freq; symbolrate = (uint32_t) srate; @@ -157,7 +161,7 @@ int set_qpsk_channel(int freq, int vpid, int apid, int tpid, printf("Getting QPSK event\n"); if ( ioctl(front, FE_GET_EVENT, &event) - == -EBUFFEROVERFLOW){ + == -EOVERFLOW){ perror("qpsk get event"); return -1; } @@ -180,7 +184,7 @@ int set_qpsk_channel(int freq, int vpid, int apid, int tpid, pesFilterParams.pid = vpid; pesFilterParams.input = DMX_IN_FRONTEND; pesFilterParams.output = DMX_OUT_DECODER; - pesFilterParams.pesType = DMX_PES_VIDEO; + pesFilterParams.pes_type = DMX_PES_VIDEO; pesFilterParams.flags = DMX_IMMEDIATE_START; if (ioctl(demux1, DMX_SET_PES_FILTER, &pesFilterParams) < 0){ perror("set_vpid"); @@ -190,7 +194,7 @@ int set_qpsk_channel(int freq, int vpid, int apid, int tpid, pesFilterParams.pid = apid; pesFilterParams.input = DMX_IN_FRONTEND; pesFilterParams.output = DMX_OUT_DECODER; - pesFilterParams.pesType = DMX_PES_AUDIO; + pesFilterParams.pes_type = DMX_PES_AUDIO; pesFilterParams.flags = DMX_IMMEDIATE_START; if (ioctl(demux2, DMX_SET_PES_FILTER, &pesFilterParams) < 0){ perror("set_apid"); @@ -200,7 +204,7 @@ int set_qpsk_channel(int freq, int vpid, int apid, int tpid, pesFilterParams.pid = tpid; pesFilterParams.input = DMX_IN_FRONTEND; pesFilterParams.output = DMX_OUT_DECODER; - pesFilterParams.pesType = DMX_PES_TELETEXT; + pesFilterParams.pes_type = DMX_PES_TELETEXT; pesFilterParams.flags = DMX_IMMEDIATE_START; if (ioctl(demux3, DMX_SET_PES_FILTER, &pesFilterParams) < 0){ perror("set_tpid"); @@ -234,12 +238,12 @@ recording. #include <time.h> #include <unistd.h> -#include <ost/dmx.h> -#include <ost/video.h> +#include <linux/dvb/dmx.h> +#include <linux/dvb/video.h> #include <sys/poll.h> -#define DVR "/dev/ost/dvr" -#define AUDIO "/dev/ost/audio" -#define VIDEO "/dev/ost/video" +#define DVR "/dev/dvb/adapter0/dvr1" +#define AUDIO "/dev/dvb/adapter0/audio1" +#define VIDEO "/dev/dvb/adapter0/video1" #define BUFFY (188*20) #define MAX_LENGTH (1024*1024*5) /* record 5MB */ @@ -252,7 +256,7 @@ recording. int switch_to_record(int demux1, int demux2, uint16_t vpid, uint16_t apid) { - struct dmxPesFilterParams pesFilterParams; + struct dmx_pes_filter_params pesFilterParams; if (demux1 < 0){ if ((demux1=open(DMX, O_RDWR|O_NONBLOCK)) @@ -273,7 +277,7 @@ int switch_to_record(int demux1, int demux2, uint16_t vpid, uint16_t apid) pesFilterParams.pid = vpid; pesFilterParams.input = DMX_IN_FRONTEND; pesFilterParams.output = DMX_OUT_TS_TAP; - pesFilterParams.pesType = DMX_PES_VIDEO; + pesFilterParams.pes_type = DMX_PES_VIDEO; pesFilterParams.flags = DMX_IMMEDIATE_START; if (ioctl(demux1, DMX_SET_PES_FILTER, &pesFilterParams) < 0){ perror("DEMUX DEVICE"); @@ -282,7 +286,7 @@ int switch_to_record(int demux1, int demux2, uint16_t vpid, uint16_t apid) pesFilterParams.pid = apid; pesFilterParams.input = DMX_IN_FRONTEND; pesFilterParams.output = DMX_OUT_TS_TAP; - pesFilterParams.pesType = DMX_PES_AUDIO; + pesFilterParams.pes_type = DMX_PES_AUDIO; pesFilterParams.flags = DMX_IMMEDIATE_START; if (ioctl(demux2, DMX_SET_PES_FILTER, &pesFilterParams) < 0){ perror("DEMUX DEVICE"); diff --git a/dvb-spec/dvbapi/frontend.tex b/dvb-spec/dvbapi/frontend.tex index ceb2f93db..9ae8a343e 100644 --- a/dvb-spec/dvbapi/frontend.tex +++ b/dvb-spec/dvbapi/frontend.tex @@ -1,52 +1,182 @@ \devsec{DVB Frontend API} The DVB frontend device controls the tuner and DVB demodulator hardware. -It can be accessed through \texttt{/dev/ost/frontend}. -If you are using \texttt{devfs} you can use \texttt{/dev/dvb/card0/frontend}. -The frontend device will only be made visible through \texttt{devfs} -if the corresponding card actually has a frontend. Cards which support -the DVB API but, e.g., only can play back recordings, will not offer the -frontend device. +It can be accessed through \texttt{/dev/dvb/adapter0/frontend0}. +Data types and and ioctl definitions can be accessed by including +\texttt{linux/dvb/frontend.h} in your application. + +DVB frontends come in three varieties: DVB-S (satellite), DVB-C (cable) +and DVB-T (terrestrial). Transmission via the internet (DVB-IP) is +not yet handled by this API but a future extension is possible. +For DVB-S the frontend device also supports satellite equipment control +(SEC) via DiSEqC and V-SEC protocols. The DiSEqC (digital SEC) specification +is available from Eutelsat \texttt{http://www.eutelsat.org/}. + +Note that the DVB API may also be used for MPEG decoder-only PCI cards, +in which case there exists no frontend device. \devsubsec{Frontend Data Types} -\devsubsubsec{frontend status} -\label{frontendstatus} +\devsubsubsec{frontend type} +\label{frontendtype} + +For historical reasons frontend types are named after the +type of modulation used in transmission. -Several functions of the frontend device use the feStatus data -type defined by \begin{verbatim} -typedef uint32_t feStatus; +typedef enum fe_type { + FE_QPSK, /* DVB-S */ + FE_QAM, /* DVB-C */ + FE_OFDM /* DVB-T */ +} fe_type_t; \end{verbatim} -to indicate the current state and/or state changes of -the frontend hardware. -\noindent -It can take on the values +\devsubsubsec{frontend capabilities} +\label{frontendcaps} + +Capabilities describe what a frontend can do. Some capabilities +can only be supported for a specific frontend type. + +\begin{verbatim} +typedef enum fe_caps { + FE_IS_STUPID = 0, + FE_CAN_INVERSION_AUTO = 0x1, + FE_CAN_FEC_1_2 = 0x2, + FE_CAN_FEC_2_3 = 0x4, + FE_CAN_FEC_3_4 = 0x8, + FE_CAN_FEC_4_5 = 0x10, + FE_CAN_FEC_5_6 = 0x20, + FE_CAN_FEC_6_7 = 0x40, + FE_CAN_FEC_7_8 = 0x80, + FE_CAN_FEC_8_9 = 0x100, + FE_CAN_FEC_AUTO = 0x200, + FE_CAN_QPSK = 0x400, + FE_CAN_QAM_16 = 0x800, + FE_CAN_QAM_32 = 0x1000, + FE_CAN_QAM_64 = 0x2000, + FE_CAN_QAM_128 = 0x4000, + FE_CAN_QAM_256 = 0x8000, + FE_CAN_QAM_AUTO = 0x10000, + FE_CAN_TRANSMISSION_MODE_AUTO = 0x20000, + FE_CAN_BANDWIDTH_AUTO = 0x40000, + FE_CAN_GUARD_INTERVAL_AUTO = 0x80000, + FE_CAN_HIERARCHY_AUTO = 0x100000, + FE_CAN_MUTE_TS = 0x80000000, + FE_CAN_CLEAN_SETUP = 0x40000000 +} fe_caps_t; +\end{verbatim} + +\devsubsubsec{frontend information} +\label{frontendinfo} + +Information about the frontend ca be queried with +FE\_GET\_INFO (\ref{fegetinfo}). + +\begin{verbatim} +struct dvb_frontend_info { + char name[128]; + fe_type_t type; + uint32_t frequency_min; + uint32_t frequency_max; + uint32_t frequency_stepsize; + uint32_t frequency_tolerance; + uint32_t symbol_rate_min; + uint32_t symbol_rate_max; + uint32_t symbol_rate_tolerance; /* ppm */ + uint32_t notifier_delay; /* ms */ + fe_caps_t caps; +}; +\end{verbatim} + +\devsubsubsec{diseqc master command} +\label{diseqcmastercmd} + +A message sent from the frontend to DiSEqC capable equipment. + +\begin{verbatim} +struct dvb_diseqc_master_cmd { + uint8_t msg [6]; /* { framing, address, command, data[3] } */ + uint8_t msg_len; /* valid values are 3...6 */ +}; +\end{verbatim} + +\devsubsubsec{diseqc slave reply} +\label{diseqcslavereply} + +A reply to the frontend from DiSEqC 2.0 capable equipment. + +\begin{verbatim} +struct dvb_diseqc_slave_reply { + uint8_t msg [4]; /* { framing, data [3] } */ + uint8_t msg_len; /* valid values are 0...4, 0 means no msg */ + int timeout; /* return from ioctl after timeout ms with */ +}; /* errorcode when no message was received */ +\end{verbatim} + +\devsubsubsec{SEC voltage} +\label{secvoltage} + +The voltage is usually used with non-DiSEqC capable LNBs to +switch the polarzation (horizontal/vertical). +When using DiSEqC epuipment this voltage has to be switched consistently +to the DiSEqC commands as described in the DiSEqC spec. + +\begin{verbatim} +typedef enum fe_sec_voltage { + SEC_VOLTAGE_13, + SEC_VOLTAGE_18 +} fe_sec_voltage_t; +\end{verbatim} + +\devsubsubsec{SEC continuous tone} +\label{sectone} + +The continous 22KHz tone is usually used with non-DiSEqC capable LNBs to +switch the high/low band of a dual-band LNB. +When using DiSEqC epuipment this voltage has to be switched consistently +to the DiSEqC commands as described in the DiSEqC spec. + +\begin{verbatim} +typedef enum fe_sec_tone_mode { + SEC_TONE_ON, + SEC_TONE_OFF +} fe_sec_tone_mode_t; +\end{verbatim} + +\devsubsubsec{SEC tone burst} +\label{sectoneburst} + +The 22KHz tone burst is usually used with non-DiSEqC capable +switches to select between two connected LNBs/satellites. +When using DiSEqC epuipment this voltage has to be switched consistently +to the DiSEqC commands as described in the DiSEqC spec. + \begin{verbatim} -#define FE_HAS_POWER 1 -#define FE_HAS_SIGNAL 2 -#define FE_SPECTRUM_INV 4 -#define FE_HAS_LOCK 8 -#define FE_HAS_CARRIER 16 -#define FE_HAS_VITERBI 32 -#define FE_HAS_SYNC 64 -#define TUNER_HAS_LOCK 128 +typedef enum fe_sec_mini_cmd { + SEC_MINI_A, + SEC_MINI_B +} fe_sec_mini_cmd_t; \end{verbatim} -which can be ORed together and have the following meaning: -\medskip -\begin{tabular}{lp{11cm}} -FE\_HAS\_POWER & the frontend is powered up and is ready to be used\\ -FE\_HAS\_SIGNAL & the frontend detects a signal above the normal noise level\\ -FE\_SPECTRUM\_INV & spectrum inversion is enabled/was necessary for lock\\ -FE\_HAS\_LOCK & frontend successfully locked to a DVB signal \\ -FE\_HAS\_CARRIER & carrier detected in signal\\ -FE\_HAS\_VITERBI & lock at viterbi decoder stage\\ -FE\_HAS\_SYNC & TS sync bytes detected \\ -TUNER\_HAS\_LOCK & the tuner has a frequency lock -\end{tabular} +\devsubsubsec{frontend status} +\label{frontendstatus} + +Several functions of the frontend device use the fe\_status data +type defined by +\begin{verbatim} +typedef enum fe_status { + FE_HAS_SIGNAL = 0x01, /* found something above the noise level */ + FE_HAS_CARRIER = 0x02, /* found a DVB signal */ + FE_HAS_VITERBI = 0x04, /* FEC is stable */ + FE_HAS_SYNC = 0x08, /* found sync bytes */ + FE_HAS_LOCK = 0x10, /* everything's working... */ + FE_TIMEDOUT = 0x20, /* no lock within the last ~2 seconds */ + FE_REINIT = 0x40 /* frontend was reinitialized, */ +} fe_status_t; /* application is recommned to reset */ +\end{verbatim} +to indicate the current state and/or state changes of +the frontend hardware. \devsubsubsec{frontend parameters} @@ -57,128 +187,136 @@ depend on the kind of hardware you are using. All kinds of parameters are combined as a union in the FrontendParameters structure: \begin{verbatim} -typedef struct { - __u32 Frequency; /* (absolute) frequency in Hz for QAM/OFDM */ - /* intermediate frequency in kHz for QPSK */ - SpectralInversion Inversion; /* spectral inversion */ +struct dvb_frontend_parameters { + uint32_t frequency; /* (absolute) frequency in Hz for QAM/OFDM */ + /* intermediate frequency in kHz for QPSK */ + fe_spectral_inversion_t inversion; union { - QPSKParameters qpsk; - QAMParameters qam; - OFDMParameters ofdm; + struct dvb_qpsk_parameters qpsk; + struct dvb_qam_parameters qam; + struct dvb_ofdm_parameters ofdm; } u; -} FrontendParameters; +}; \end{verbatim} -For satellite QPSK frontends you have to use QPSKParameters defined by +For satellite QPSK frontends you have to use the \verb|QPSKParameters| member +defined by \begin{verbatim} -typedef struct { - __u32 SymbolRate; /* symbol rate in Symbols per second */ - CodeRate FEC_inner; /* forward error correction (see above) */ -} QPSKParameters; +struct dvb_qpsk_parameters { + uint32_t symbol_rate; /* symbol rate in Symbols per second */ + fe_code_rate_t fec_inner; /* forward error correction (see above) */ +}; \end{verbatim} -for cable QAM frontend you use the QAMParameters structure +for cable QAM frontend you use the \verb|QAMParameters| structure \begin{verbatim} -typedef struct { - __u32 SymbolRate; /* symbol rate in Symbols per second */ - CodeRate FEC_outer; /* forward error correction (see above) */ - CodeRate FEC_inner; /* forward error correction (see above) */ - Modulation QAM; /* modulation type (see above) */ -} QAMParameters; +struct dvb_qam_parameters { + uint32_t symbol_rate; /* symbol rate in Symbols per second */ + fe_code_rate_t fec_inner; /* forward error correction (see above) */ + fe_modulation_t modulation; /* modulation type (see above) */ +}; \end{verbatim} -DVB-T frontends are supported by the OFDMParamters structure +DVB-T frontends are supported by the \verb|OFDMParamters| structure \begin{verbatim} -typedef struct { - BandWidth bandWidth; - CodeRate HP_CodeRate; /* high priority stream code rate */ - CodeRate LP_CodeRate; /* low priority stream code rate */ - Modulation Constellation; /* modulation type (see above) */ - TransmitMode TransmissionMode; - GuardInterval guardInterval; - Hierarchy HierarchyInformation; -} OFDMParameters; +struct dvb_ofdm_parameters { + fe_bandwidth_t bandwidth; + fe_code_rate_t code_rate_HP; /* high priority stream code rate */ + fe_code_rate_t code_rate_LP; /* low priority stream code rate */ + fe_modulation_t constellation; /* modulation type (see above) */ + fe_transmit_mode_t transmission_mode; + fe_guard_interval_t guard_interval; + fe_hierarchy_t hierarchy_information; +}; \end{verbatim} -In the case of QPSK frontends the Frequency field specifies the intermediate -frequency, i.e. the offset which is effectively added to the local oscillator -frequency (LOF) of the LNB. +In the case of QPSK frontends the \verb|Frequency| field specifies the +intermediate frequency, i.e. the offset which is effectively added to the +local oscillator frequency (LOF) of the LNB. The intermediate frequency has to be specified in units of kHz. For QAM and OFDM frontends the Frequency specifies the absolute frequency and is given in Hz. The Inversion field can take one of these values: \begin{verbatim} -typedef enum { +typedef enum fe_spectral_inversion { INVERSION_OFF, INVERSION_ON, INVERSION_AUTO -} SpectralInversion; +} fe_spectral_inversion_t; \end{verbatim} It indicates if spectral inversion should be presumed or not. -In the automatic setting (\verb INVERSION_AUTO) the hardware will +In the automatic setting (\verb|INVERSION_AUTO|) the hardware will try to figure out the correct setting by itself. \noindent -The possible values for the FEC\_inner field are +The possible values for the \verb|FEC_inner| field are \begin{verbatim} -enum { - FEC_AUTO, +typedef enum fe_code_rate { + FEC_NONE = 0, FEC_1_2, FEC_2_3, FEC_3_4, + FEC_4_5, FEC_5_6, + FEC_6_7, FEC_7_8, - FEC_NONE -}; + FEC_8_9, + FEC_AUTO +} fe_code_rate_t; \end{verbatim} -which correspond to error correction rates of $1\over 2$, $2\over 3$, etc., +which correspond to error correction rates of 1/2, 2/3, etc., no error correction or auto detection. \noindent For cable and terrestrial frontends (QAM and OFDM) one also has to specify the quadrature modulation mode which can be one of the following: \begin{verbatim} -typedef enum -{ QPSK, +typedef enum fe_modulation { + QPSK, QAM_16, QAM_32, QAM_64, QAM_128, - QAM_256 -} QAM_TYPE; + QAM_256, + QAM_AUTO +} fe_modulation_t; \end{verbatim} Finally, there are several more parameters for OFDM: \begin{verbatim} -typedef enum { +typedef enum fe_transmit_mode { TRANSMISSION_MODE_2K, - TRANSMISSION_MODE_8K -} TransmitMode; + TRANSMISSION_MODE_8K, + TRANSMISSION_MODE_AUTO +} fe_transmit_mode_t; \end{verbatim} \begin{verbatim} -typedef enum { +typedef enum fe_bandwidth { BANDWIDTH_8_MHZ, BANDWIDTH_7_MHZ, - BANDWIDTH_6_MHZ -} BandWidth; + BANDWIDTH_6_MHZ, + BANDWIDTH_AUTO +} fe_bandwidth_t; \end{verbatim} \begin{verbatim} -typedef enum { +typedef enum fe_guard_interval { GUARD_INTERVAL_1_32, GUARD_INTERVAL_1_16, GUARD_INTERVAL_1_8, - GUARD_INTERVAL_1_4 -} GuardInterval; + GUARD_INTERVAL_1_4, + GUARD_INTERVAL_AUTO +} fe_guard_interval_t; \end{verbatim} \begin{verbatim} -typedef enum { +typedef enum fe_hierarchy { HIERARCHY_NONE, HIERARCHY_1, HIERARCHY_2, - HIERARCHY_4 -} Hierarchy; + HIERARCHY_4, + HIERARCHY_AUTO +} fe_hierarchy_t; \end{verbatim} @@ -186,78 +324,12 @@ typedef enum { \label{frontendevents} \begin{verbatim} -enum { - FE_UNEXPECTED_EV, - FE_COMPLETION_EV, - FE_FAILURE_EV +struct dvb_frontend_event { + fe_status_t status; + struct dvb_frontend_parameters parameters; }; \end{verbatim} -\begin{verbatim} -typedef struct { - EventType type; /* type of event, FE_UNEXPECTED_EV, ... */ - long timestamp; /* time in seconds since 1970-01-01 */ - - union { - struct { - FrontendStatus previousStatus; /* status before event */ - FrontendStatus currentStatus; /* status during event */ - } unexpectedEvent; - FrontendParameters completionEvent; /* parameters for which the - tuning succeeded */ - FrontendStatus failureEvent; /* status at failure (e.g. no lock) */ - } u; -} FrontendEvent; -\end{verbatim} - -\begin{verbatim} -struct qpskRegister { - uint8_t chipId; - uint8_t address; - uint8_t value; -}; -\end{verbatim} - -\begin{verbatim} -struct qamRegister { - uint8_t chipId; - uint8_t address; - uint8_t value; -}; -\end{verbatim} - -\begin{verbatim} -struct qpskFrontendInfo { - uint32_t minFrequency; - uint32_t maxFrequency; - uint32_t maxSymbolRate; - uint32_t minSymbolRate; - uint32_t hwType; - uint32_t hwVersion; -}; -\end{verbatim} - -\begin{verbatim} -struct qamFrontendInfo { - uint32_t minFrequency; - uint32_t maxFrequency; - uint32_t maxSymbolRate; - uint32_t minSymbolRate; - uint32_t hwType; - uint32_t hwVersion; -}; -\end{verbatim} - -\begin{verbatim} -typedef enum { - FE_POWER_ON, - FE_POWER_STANDBY, - FE_POWER_SUSPEND, - FE_POWER_OFF -} powerState_t; -\end{verbatim} - - \clearpage @@ -265,9 +337,9 @@ typedef enum { \function{open()}{ int open(const char *deviceName, int flags);}{ - This system call opens a named frontend device (e.g. /dev/ost/qpskfe - for a satellite frontend or /dev/ost/qamfe for a cable frontend) - for subsequent use. + This system call opens a named frontend device (/dev/dvb/adapter0/frontend0) + for subsequent use. Usually the first thing to do after a successful open + is to find out the frontend type with FE\_GET\_INFO. The device can be opened in read-only mode, which only allows monitoring of device status and statistics, or read/write mode, which allows @@ -303,119 +375,21 @@ typedef enum { int close(int fd);}{ This system call closes a previously opened front-end device. After closing a front-end device, its corresponding hardware might be - powered down automatically, but only when this is needed to open - another front-end device. - To affect an unconditional power down, it should be done explicitly using - the OST\_SET\_POWER\_STATE ioctl. + powered down automatically. }{ int fd & File descriptor returned by a previous call to open().\\ }{ EBADF & fd is not a valid open file descriptor.\\ } -\ifunction{OST\_SELFTEST}{ - int ioctl(int fd, int request = OST\_SELFTEST);}{ - This ioctl call initiates an automatic self-test of the front-end hardware. - This call requires read/write access to the device. - }{ - int fd & File descriptor returned by a previous call to open().\\ - int request & Equals OST\_SELFTEST for this command.\\ - }{ - -1& Self test failure.\\ -} - -\ifunction{OST\_SET\_POWER\_STATE}{ - int ioctl(int fd, int request = OST\_SET\_POWER\_STATE, uint32\_t state);}{ - This ioctl call, implemented in many OST device drivers, enables direct - control over the power state of the hardware device, which may be on, off, - standby, or suspend. The latter two are low-power modes, which disable all - functionality of the device until turned on again. In contrast to the off - state, however, the standby and suspend states resume operation in the same - state as when the device was active. The only difference between the standby - and suspend states is a different tradeoff between resume time and power - consumption. Power consumption may be lower in the suspend state at the - cost of a longer resume time.\\ - A device that implements this call does not necessarily support two low-power - modes. If it only supports one low-power state, or none at all, the - OST\_SET\_POWER\_STATE operation for the missing states will - still succeed, but - it will be mapped to an existing state as per this table: \\ - \begin{center} - \begin{tabular}[h]{cll} - number of low-power & requested state & resulting state\\ - states supported &&\\ - \\ - 1 & standby & suspend \\ - 1 & suspend & suspend \\ - 0 & standby & on \\ - 0 & suspend & on - \end{tabular} - \end{center}\\ - For other cases where a required state is missing, an error code will be - returned. This can happen if a device does not support the power-off state, - but nevertheless implements this ioctl operation for control of low-power - states. - When opening a device in read/write mode, the driver ensures that the - corresponding hardware device is turned on initially. If the device is - later turned off or put in suspend mode, it has to be explicitly turned on - again.\\ - This call requires read/write access to the device. (Note that the power - management driver can affect the power state of devices without using this - ioctl operation, so having exclusive read/write access to a device does not - imply total control over the power state.) - }{ - int fd & File descriptor returned by a previous call to open().\\ - int request & Equals OST\_SET\_POWER\_STATE for this command.\\ - uint32\_t state & Requested power state. One of: \\ - & - \begin{tabular}[h]{ll} - OST\_POWER\_ON& turn power on\\ - OST\_POWER\_STANDBY& set device in standby mode\\ - OST\_POWER\_SUSPEND& set device in suspend mode\\ - OST\_POWER\_OFF& turn power off\\ - \end{tabular} - }{ - EBADF& fd is not a valid open file descriptor.\\ - EINVAL& Illegal state, or not available on this device.\\ - EPERM & Permission denied (needs read/write access).\\ - ENOSYS& Function not available for this device. -} - -\ifunction{FE\_GET\_POWER\_STATE}{ - int ioctl(int fd, int request = OST\_GET\_POWER\_STATE, uint32\_t *state);}{ - This ioctl call, implemented in many OST device drivers, obtains the power - state of the hardware device, which may be on, off, standby, or suspend. - A device that implements this call does not necessarily support all four states. - If there is only one low-power state, the suspend state will be returned for - that state. If there is no low-power state, the on state will be reported - standby and suspend states will be equivalent to the on state. - For this command, read-only access to the device is sufficient. - }{ - int fd & File descriptor returned by a previous call to open().\\ - int request & Equals OST\_GET\_POWER\_STATE for this command.\\ - uint32\_t *state & Requested power state. One of: \\ - & - \begin{tabular}[h]{ll} - OST\_POWER\_ON& power is on\\ - OST\_POWER\_STANDBY& device in standby mode\\ - OST\_POWER\_SUSPEND& device in suspend mode\\ - OST\_POWER\_OFF& power is off\\ - \end{tabular} - }{ - EBADF& fd is not a valid open file descriptor.\\ - EINVAL& Illegal state, or not available on this device.\\ - EFAULT& state points to invalid address.\\ - ENOSYS& Function not available for this device. -} - \ifunction{FE\_READ\_STATUS}{ - int ioctl(int fd, int request = FE\_READ\_STATUS, feStatus *status);}{ + int ioctl(int fd, int request = FE\_READ\_STATUS, fe\_status\_t *status);}{ This ioctl call returns status information about the front-end. This call only requires read-only access to the device. }{ int fd & File descriptor returned by a previous call to open().\\ int request & Equals FE\_READ\_STATUS for this command.\\ - struct feStatus *status&Points to the location where the front-end + struct fe\_status\_t *status & Points to the location where the front-end status word is to be stored. }{ EBADF& fd is not a valid open file descriptor.\\ @@ -430,10 +404,7 @@ typedef enum { }{ int fd & File descriptor returned by a previous call to open().\\ int request & Equals FE\_READ\_BER for this command.\\ - uint32\_t *ber & The bit error rate, as a multiple of $10^{-9}$, - is stored into *ber.\\ - & Example: a value of 2500 corresponds to a bit error - rate of $2.5\cdot 10^{-6}$, or 1 error in 400000 bits. + uint32\_t *ber & The bit error rate is stored into *ber.\\ }{ EBADF& fd is not a valid open file descriptor.\\ EFAULT& ber points to invalid address.\\ @@ -443,17 +414,14 @@ typedef enum { } \ifunction{FE\_READ\_SNR}{ - int ioctl(int fd, int request = FE\_READ\_SNR, int32\_t *snr);}{ + int ioctl(int fd, int request = FE\_READ\_SNR, int16\_t *snr);}{ This ioctl call returns the signal-to-noise ratio for the signal currently received by the front-end. For this command, read-only access to the device is sufficient. }{ int fd & File descriptor returned by a previous call to open().\\ int request & Equals FE\_READ\_SNR for this command.\\ - int32\_t *snr& The signal-to-noise ratio, as a multiple of - $10^{-6}$ dB, is stored into *snr.\\ - & Example: a value of 12,300,000 corresponds - to a signal-to-noise ratio of 12.3 dB. + int16\_t *snr& The signal-to-noise ratio is stored into *snr.\\ }{ EBADF& fd is not a valid open file descriptor.\\ EFAULT& snr points to invalid address.\\ @@ -463,7 +431,7 @@ typedef enum { } \ifunction{FE\_READ\_SIGNAL\_STRENGTH}{ - int ioctl( int fd, int request = FE\_READ\_SIGNAL\_STRENGTH, int32\_t *strength); + int ioctl( int fd, int request = FE\_READ\_SIGNAL\_STRENGTH, int16\_t *strength); }{ This ioctl call returns the signal strength value for the signal currently received by the front-end. For this command, read-only access to the device @@ -471,11 +439,7 @@ is sufficient. }{ int fd & File descriptor returned by a previous call to open().\\ int request & Equals FE\_READ\_SIGNAL\_STRENGTH for this command.\\ -int32\_t *strength & The signal strength value, as a multiple of - $10^{-6 }$ dBm, - is stored into *strength. \\ - &Example: a value of -12,500,000 corresponds to a signal - strength value of -12.5 dBm. +int16\_t *strength & The signal strength value is stored into *strength.\\ }{ EBADF& fd is not a valid open file descriptor.\\ EFAULT& status points to invalid address.\\ @@ -505,59 +469,8 @@ by the driver so far. } -\ifunction{FE\_GET\_NEXT\_FREQUENCY}{ - int ioctl( int fd, int request = FE\_GET\_NEXT\_FREQUENCY, uint32\_t *freq);}{ - When scanning a frequency range, it is desirable to use a scanning step size - that is as large as possible, yet small enough to be able to lock to any signal - within the range. - This ioctl operation does just that - it increments a given frequency by a - step size suitable for efficient scanning. - The step size used by this function may be a quite complex function of the given - frequency, hardware capabilities, and parameter settings of the device. Thus, a - returned result is only valid for the current state of the device. - For this command, read-only access to the device is sufficient.\\ - Note that scanning may still be excruciatingly slow on some hardware, for - other reasons than a non-optimal scanning step size. - }{ - int fd & File descriptor returned by a previous call to open().\\ - int request & Equals FE\_GET\_NEXT\_FREQUENCY for this command.\\ - uint32\_t *freq& Input: a given frequency \\ - & Output: the frequency corresponding to - the next higher frequency setting.\\ - }{ - EBADF& fd is not a valid open file descriptor.\\ - EFAULT& freq points to invalid address.\\ - EINVAL& Maximum supported frequency reached.\\ - ENOSYS& Function not available for this device. -} - -\ifunction{FE\_GET\_NEXT\_SYMBOL\_RATE}{ - int ioctl( int fd, int request = FE\_GET\_NEXT\_SYMBOL\_RATE, uint32\_t *symbolRate); - }{ - When scanning a range of symbol rates (e.g. for "blind acquisition") it is - desirable to use a scanning step size that is as large as possible, yet - small enough to detect any valid signal within the range. This ioctl - operation does just that - it increments a given symbol rate by a step size - suitable for efficient scanning. - The step size used by this function may be a quite complex function of the given - symbol rate, hardware capabilities, and parameter settings of the device. - Thus, a returned result is only valid for the current state of the device. - For this command, read-only access to the device is sufficient. - }{ - int fd & File descriptor returned by a previous call to open().\\ - int request & Equals FE\_GET\_NEXT\_SYMBOL\_RATE for this command.\\ - uint32\_t *symbolRate& Input: a given symbol rate \\ - & Output: the symbol rate corresponding to - the next higher symbol rate.\\ - }{ - EBADF& fd is not a valid open file descriptor.\\ - EFAULT& symbolRate points to invalid address.\\ - EINVAL& Maximum supported symbol rate reached.\\ - ENOSYS& Function not available for this device. -} - \ifunction{FE\_SET\_FRONTEND}{ - int ioctl(int fd, int request = FE\_SET\_FRONTEND, struct FrontendParameters *p);}{ + int ioctl(int fd, int request = FE\_SET\_FRONTEND, struct dvb\_frontend\_parameters *p);}{ This ioctl call starts a tuning operation using specified parameters. The result of this call will be successful if the parameters were valid and the tuning could be initiated. @@ -571,7 +484,21 @@ by the driver so far. }{ int fd & File descriptor returned by a previous call to open().\\ int request & Equals FE\_SET\_FRONTEND for this command.\\ - struct FrontendParameters *p& Points to parameters for tuning operation.\\ + struct dvb\_frontend\_parameters *p& Points to parameters for tuning operation.\\ + }{ + EBADF& fd is not a valid open file descriptor.\\ + EFAULT& p points to invalid address.\\ + EINVAL& Maximum supported symbol rate reached.\\ +} + +\ifunction{FE\_GET\_FRONTEND}{ + int ioctl(int fd, int request = FE\_GET\_FRONTEND, struct dvb\_frontend\_parameters *p);}{ + This ioctl call queries the currently effective frontend parameters. + For this command, read-only access to the device is sufficient. + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals FE\_SET\_FRONTEND for this command.\\ + struct dvb\_frontend\_parameters *p& Points to parameters for tuning operation.\\ }{ EBADF& fd is not a valid open file descriptor.\\ EFAULT& p points to invalid address.\\ @@ -579,8 +506,8 @@ by the driver so far. } \ifunction{FE\_GET\_EVENT}{ - int ioctl(int fd, int request = QPSK\_GET\_EVENT, struct qpskEvent *ev);}{ - This ioctl call returns an event of type qpskEvent if available. If an event + int ioctl(int fd, int request = QPSK\_GET\_EVENT, struct dvb\_frontend\_event *ev);}{ + This ioctl call returns a frontend event if available. If an event is not available, the behavior depends on whether the device is in blocking or non-blocking mode. In the latter case, the call fails immediately with errno set to EWOULDBLOCK. In the former case, the call blocks until an event @@ -591,39 +518,156 @@ by the driver so far. POLLPRI should be specified as the wake-up condition. Since the event queue allocated is rather small (room for 8 events), the queue must be serviced regularly to avoid overflow. If an overflow happens, the - oldest event is discarded from the queue, and an error (EBUFFEROVERFLOW) occurs + oldest event is discarded from the queue, and an error (EOVERFLOW) occurs the next time the queue is read. After reporting the error condition in this - fashion, subsequent QPSK\_GET\_EVENT calls will return events from the queue as + fashion, subsequent FE\_GET\_EVENT calls will return events from the queue as usual.\\ For the sake of implementation simplicity, this command requires read/write access to the device. }{ int fd & File descriptor returned by a previous call to open().\\ - int request & Equals QPSK\_GET\_EVENT for this command.\\ - struct qpskEvent *ev&Points to the location where the event, if any, is to be stored. + int request & Equals FE\_GET\_EVENT for this command.\\ + struct dvb\_frontend\_event *ev & Points to the location where the event,\\ + & if any, is to be stored. }{ EBADF& fd is not a valid open file descriptor.\\ EFAULT& ev points to invalid address.\\ EWOULDBLOCK & There is no event pending, and the device is in non-blocking mode.\\ - EBUFFEROVERFLOW &\\ + EOVERFLOW &\\ & Overflow in event queue - one or more events were lost.\\ } \ifunction{FE\_GET\_INFO}{ - int ioctl(int fd, int request = FE\_GET\_INFO, struct FrontendInfo *info);}{ +\label{fegetinfo} + int ioctl(int fd, int request = FE\_GET\_INFO, struct dvb\_frontend\_info *info);}{ This ioctl call returns information about the front-end. This call only requires read-only access to the device. }{ int fd & File descriptor returned by a previous call to open().\\ int request & Equals FE\_GET\_INFO for this command.\\ - struct qpskFrontendInfo *info & Points to the location where the front-end + struct dvb\_frontend\_info *info & Points to the location where the front-end information is to be stored. }{ EBADF& fd is not a valid open file descriptor.\\ EFAULT& info points to invalid address.\\ } +\ifunction{FE\_DISEQC\_RESET\_OVERLOAD}{ + int ioctl(int fd, int request = FE\_DISEQC\_RESET\_OVERLOAD);}{ + If the bus has been automatically powered off due to power overload, this + ioctl call restores the power to the bus. The call requires read/write + access to the device. + This call has no effect if the device is manually powered off. + Not all DVB adapters support this ioctl. + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals FE\_DISEQC\_RESET\_OVERLOAD for this command.\\ + }{ + EBADF & fd is not a valid file descriptor.\\ + EPERM & Permission denied (needs read/write access).\\ + EINTERNAL & Internal error in the device driver.\\ +} + + +\ifunction{FE\_DISEQC\_SEND\_MASTER\_CMD}{ +int ioctl(int fd, int request = FE\_DISEQC\_SEND\_MASTER\_CMD, struct dvb\_diseqc\_master\_cmd *cmd);}{ + This ioctl call is used to send a a DiSEqC command.\\ + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals FE\_DISEQC\_SEND\_MASTER\_CMD for this command.\\ + struct dvb\_diseqc\_master\_cmd *cmd & Pointer to the command to be transmitted.\\ + }{ + EBADF & fd is not a valid file descriptor.\\ + EFAULT & Seq points to an invalid address.\\ + EINVAL & The data structure referred to by seq is invalid in some way.\\ + EPERM & Permission denied (needs read/write access).\\ + EINTERNAL & Internal error in the device driver.\\ +} + +\ifunction{FE\_DISEQC\_RECV\_SLAVE\_REPLY}{ +int ioctl(int fd, int request = FE\_DISEQC\_RECV\_SLAVE\_REPLY, struct dvb\_diseqc\_slave\_reply *reply);}{ +This ioctl call is used to receive reply to a DiSEqC 2.0 command.\\ + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals FE\_DISEQC\_RECV\_SLAVE\_REPLY for this command.\\ + struct dvb\_diseqc\_slave\_reply *reply & Pointer to the command to be received.\\ + }{ + EBADF & fd is not a valid file descriptor.\\ + EFAULT & Seq points to an invalid address.\\ + EINVAL & The data structure referred to by seq is invalid in some way.\\ + EPERM & Permission denied (needs read/write access).\\ + EINTERNAL & Internal error in the device driver.\\ +} + +\ifunction{FE\_DISEQC\_SEND\_BURST}{ +int ioctl(int fd, int request = FE\_DISEQC\_SEND\_BURST, fe\_sec\_mini\_cmd\_t burst);}{ +This ioctl call is used to send a 22KHz tone burst.\\ + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals FE\_DISEQC\_SEND\_BURST for this command.\\ + fe\_sec\_mini\_cmd\_t burst & burst A or B.\\ + }{ + EBADF & fd is not a valid file descriptor.\\ + EFAULT & Seq points to an invalid address.\\ + EINVAL & The data structure referred to by seq is invalid in some way.\\ + EPERM & Permission denied (needs read/write access).\\ + EINTERNAL & Internal error in the device driver.\\ +} + + +\ifunction{FE\_SET\_TONE}{ +int ioctl(int fd, int request = FE\_SET\_TONE, fe\_sec\_tone\_mode\_t tone);}{ +This call is used to set the generation of the continuous 22kHz tone. +This call requires read/write permissions. +}{ +int fd & File descriptor returned by a previous call to open().\\ +int request & Equals FE\_SET\_TONE for this command.\\ +fe\_sec\_tone\_mode\_t tone & The requested tone generation mode (on/off).\\ +}{ +ENODEV & Device driver not loaded/available.\\ +EBUSY & Device or resource busy.\\ +EINVAL & Invalid argument.\\ +EPERM & File not opened with read permissions.\\ +EINTERNAL & Internal error in the device driver.\\ +} + + +\ifunction{FE\_SET\_VOLTAGE}{ +int ioctl(int fd, int request = FE\_SET\_VOLTAGE, fe\_sec\_voltage\_t voltage);}{ +This call is used to set the bus voltage. +This call requires read/write permissions. +}{ +int fd & File descriptor returned by a previous call to open().\\ +int request & Equals FE\_SET\_VOLTAGE for this command.\\ +fe\_sec\_voltage\_t voltage & The requested bus voltage.\\ +}{ +ENODEV & Device driver not loaded/available.\\ +EBUSY & Device or resource busy.\\ +EINVAL & Invalid argument.\\ +EPERM & File not opened with read permissions.\\ +EINTERNAL & Internal error in the device driver.\\ +} + +\ifunction{FE\_ENABLE\_HIGH\_LNB\_VOLTAGE}{ +int ioctl(int fd, int request = FE\_ENABLE\_HIGH\_LNB\_VOLTAGE, int high);}{ +If high != 0 enables slightly higher voltages instead of 13/18V +(to compensate for long cables). +This call requires read/write permissions. +Not all DVB adapters support this ioctl. +}{ +int fd & File descriptor returned by a previous call to open().\\ +int request & Equals FE\_SET\_VOLTAGE for this command.\\ +int high & The requested bus voltage.\\ +}{ +ENODEV & Device driver not loaded/available.\\ +EBUSY & Device or resource busy.\\ +EINVAL & Invalid argument.\\ +EPERM & File not opened with read permissions.\\ +EINTERNAL & Internal error in the device driver.\\ +} + + %%% Local Variables: %%% mode: latex %%% TeX-master: "dvbapi" diff --git a/dvb-spec/dvbapi/intro.tex b/dvb-spec/dvbapi/intro.tex index 1d859fadb..613bcd6c8 100644 --- a/dvb-spec/dvbapi/intro.tex +++ b/dvb-spec/dvbapi/intro.tex @@ -1,15 +1,21 @@ \chapter{Introduction} %\addcontentsline{toc}{part}{Introduction} %\chaptermark{Introduction} + \section{What you need to know} + The reader of this document is required to have some knowledge in the area of digital video broadcasting (DVB) and should be familiar with -part I of ISO/IEC 13818, i.e you should know what a -program/transport stream (PS/TS) is and what is meant by a packetized elementary -stream (PES) or an I-frame. +part I of the MPEG2 specification ISO/IEC 13818 (aka ITU-T H.222), +i.e you should know what a program/transport stream (PS/TS) is and what is +meant by a packetized elementary stream (PES) or an I-frame. + +Various DVB standards documents are available from +\texttt{http://www.dvb.org/} and/or \texttt{http://www.etsi.org/}. It is also necessary to know how to access unix/linux devices and how to use ioctl calls. This also includes the knowledge of C or C++. + \section{History} The first API for DVB cards we used at Convergence in late 1999 @@ -26,11 +32,12 @@ Nokia and Convergence made it available to all Linux developers and published it on \texttt{http://www.linuxtv.org/} in September 2000. Convergence is the maintainer of the Linux DVB API. Together with the LinuxTV community (i.e. you, the reader of this document), -the Linux DVB API will be constantly reviewed and improved upon. +the Linux DVB API will be constantly reviewed and improved. With the Linux driver for the Siemens/Hauppauge DVB PCI card Convergence provides a first implementation of the Linux DVB API. +\newpage \section{Overview} \begin{figure}[htbp] @@ -49,14 +56,10 @@ main hardware components: Here the raw signal reaches the DVB hardware from a satellite dish or antenna or directly from cable. The frontend down-converts and demodulates -this signal into an MPEG transport stream (TS). - -\item SEC for controlling external hardware like LNBs and antennas - -This part of the hardware can send signals back through the satellite -cable to control the polarization of the LNB, to switch between -different LNBs or even to control the movements of a dish rotor. - +this signal into an MPEG transport stream (TS). In case of a satellite +frontend, this includes a facility for satellite equipment control (SEC), +which allows control of LNB polarization, multi feed switches or +dish rotors. \item Conditional Access (CA) hardware like CI adapters and smartcard slots @@ -74,10 +77,11 @@ or other streams of the same provider. \item MPEG2 audio and video decoder The main targets of the demultiplexer are the MPEG2 audio and video -decoders. After decoding the pass on the uncompressed audio +decoders. After decoding they pass on the uncompressed audio and video to the computer screen or (through a PAL/NTSC encoder) to a TV set. \end{itemize} + Figure \ref{fig:dvbstb} shows a crude schematic of the control and data flow between those components. @@ -91,11 +95,9 @@ Also not every card or STB provides conditional access hardware. The Linux DVB API lets you control these hardware components through currently six Unix-style character devices for -video, audio, frontend, SEC, demux and CA. +video, audio, frontend, demux, CA and IP-over-DVB networking. The video and audio devices control the MPEG2 decoder hardware, the frontend device the tuner and the DVB demodulator. -External hardware like DiSEqC switches and rotors can be controlled -through the SEC device. The demux device gives you control over the PES and section filters of the hardware. If the hardware does not support filtering these filters can be implemented in software. @@ -104,78 +106,41 @@ of the hardware. It can depend on the individual security requirements of the platform, if and how many of the CA functions are made available to the application through this device. +\smallskip All devices can be found in the \texttt{/dev} tree under -\texttt{/dev/ost}, where OST stands for Open Standards Terminal. -The individual devices are called +\texttt{/dev/dvb}. The individual devices are called \begin{itemize} -\item \texttt{/dev/ost/audio}, -\item \texttt{/dev/ost/video}, -\item \texttt{/dev/ost/frontend}, -\item \texttt{/dev/ost/sec}, -\item \texttt{/dev/ost/demux}, -\item \texttt{/dev/ost/ca}, +\item \texttt{/dev/dvb/adapterN/audioM}, +\item \texttt{/dev/dvb/adapterN/videoM}, +\item \texttt{/dev/dvb/adapterN/frontendM}, +\item \texttt{/dev/dvb/adapterN/netM}, +\item \texttt{/dev/dvb/adapterN/demuxM}, +\item \texttt{/dev/dvb/adapterN/caM}, \end{itemize} -but we will omit the ``\texttt{/dev/ost/}'' in the further dicussion of -these devices. - -If more than one card is present in the system the other cards -can be accessed through the corresponding devices with the -card's number appended. \texttt{/dev/ost/demux0} (which -is identical to \texttt{/dev/ost/demux}) would, e.g., control the -demultiplexer of the first card, while \texttt{/dev/ost/demux1} -would control the demultiplexer of the second card, and so on. +where N enumerates the DVB PCI cards in a system starting from~0, +and M enumerates the devices of each type within each adapter, starting +from~0, too. +We will omit the ``\texttt{/dev/dvb/adapterN/}'' in the further dicussion of +these devices. The naming scheme for the devices is the same wheter devfs +is used or not. More details about the data structures and function calls of all the devices are described in the following chapters. +\section{API include files} -\section{DVB Devices with Devfs} - -Recent Linux kernel versions support a special file system called -\textsl{devfs} which is a replacement for the traditional -device directory. -With devfs a Linux DVB driver will only create those device file entries -which actually exist. -It also makes dealing with more complex DVB hardware much easier. -The device structure described above is not well suited to deal -with multiple DVB cards with more than one frontend or demultiplexer. -Consider, e.g., two DVB cards, one with two frontends and -one demultiplexer, the other with one frontend and two demultiplexers. -If we just assign them consecutive numbers, there would be a demultiplexer -and a frontend which do not belong to the same card but have -the same number. - -With \textsl{devfs} we propose a different scheme for the device names. -The root directory for all DVB cards will be \texttt{/dev/dvb}. -Each card gets assigned a sub-directory with the name \texttt{/dev/card0}, -\texttt{/dev/card1}, etc. -The files created in these sub-directories will correspond directly to the -hardware actually present on the card. -Thus, if the first card has one QAM frontend, one demultiplexer -and otherwise no other hardware, -only \texttt{/dev/dvb/card0/qamfe0} and \texttt{/dev/dvb/card0/demux0} -will be created. -When a second DVB-S card with one frontend (including SEC) device, -two demultiplexers and an MPEG2 audio/video decoder is added, the -complete \texttt{/dev/dvb} tree will look like this: +For each of the DVB devices a corresponding include file +exists. The DVB API include files should be included +in application sources with a partial path like: \begin{verbatim} -/dev/dvb/card0/frontend0 - demux0 - -/dev/dvb/card1/video0 - audio0 - demux0 - demux1 - frontend0 - sec0 +#include <linux/dvb/frontend.h> \end{verbatim} - -\section{Using the Devices} - -\dots - +To enable applications to support different API version, an additional +include file \texttt{linux/dvb/version.h} exists, which defines the +constant \texttt{DVB\_API\_VERSION}. This document describes +\texttt{DVB\_API\_VERSION~3}. %%% Local Variables: %%% mode: latex diff --git a/dvb-spec/dvbapi/kdapi.tex b/dvb-spec/dvbapi/kdapi.tex index 59490299b..f7fc69353 100644 --- a/dvb-spec/dvbapi/kdapi.tex +++ b/dvb-spec/dvbapi/kdapi.tex @@ -1,6 +1,13 @@ \devsec{Kernel Demux API} -The kernel demux API +The kernel demux API defines a driver-internal interface +for registering low-level, hardware specific driver to a +hardware independent demux layer. It is only of interest +for DVB device driver writers. The header file for this +API is named \texttt{demux.h} and located in +\texttt{drivers/media/dvb/dvb-core}. + +Maintainer note: This section must be reviewed. It is probably out of date. \devsubsec{Kernel Demux Data Types} diff --git a/dvb-spec/dvbapi/net.tex b/dvb-spec/dvbapi/net.tex new file mode 100644 index 000000000..dc6566633 --- /dev/null +++ b/dvb-spec/dvbapi/net.tex @@ -0,0 +1,19 @@ +\devsec{DVB Network API} + +The DVB net device enables feeding of MPE (multi protocol +encapsulation) packets received via DVB into the Linux network +protocol stack, e.g. for internet via satellite applications. +It can be accessed through \texttt{/dev/dvb/adapter0/net0}. +Data types and and ioctl definitions can be accessed by including +\texttt{linux/dvb/net.h} in your application. + + +\devsubsec{DVB Net Data Types} + +To be written\dots + + +%%% Local Variables: +%%% mode: latex +%%% TeX-master: "dvbapi" +%%% End: diff --git a/dvb-spec/dvbapi/sec.tex b/dvb-spec/dvbapi/sec.tex deleted file mode 100644 index 88342c3a6..000000000 --- a/dvb-spec/dvbapi/sec.tex +++ /dev/null @@ -1,282 +0,0 @@ -\devsec{DVB SEC API} - -The DVB SEC device controls the Satellite Equipment Control of -the DVB hardware, i.e. DiSEqC and V-SEC. -It is accessed through \texttt{/dev/ost/sec}. - -\devsubsec{SEC Data Types} - -\devsubsubsec{secDiseqcCmd} -\label{secdiseqccmd} - -\begin{verbatim} -struct secDiseqcCmd { - uint8_t addr; - uint8_t cmd; - uint8_t numParams; - uint8_t params[SEC_MAX_DISEQC_PARAMS]; -}; -\end{verbatim} - - -\devsubsubsec{secVoltage} -\label{secvoltage} - -\begin{verbatim} -typedef uint32_t secVoltage; -\end{verbatim} -\begin{verbatim} -enum { - SEC_VOLTAGE_OFF, - SEC_VOLTAGE_LT, - SEC_VOLTAGE_13, - SEC_VOLTAGE_13_5, - SEC_VOLTAGE_18, - SEC_VOLTAGE_18_5 -}; -\end{verbatim} - - -\devsubsubsec{secToneMode} -\label{sectonemode} - -\begin{verbatim} -typedef uint32_t secToneMode; -\end{verbatim} -\begin{verbatim} -typedef enum { - SEC_TONE_ON, - SEC_TONE_OFF -} secToneMode_t; -\end{verbatim} - - -\devsubsubsec{secMiniCmd} -\label{secminicmd} - -\begin{verbatim} -typedef uint32_t secMiniCmd; -\end{verbatim} -\begin{verbatim} -typedef enum { - SEC_MINI_NONE, - SEC_MINI_A, - SEC_MINI_B -} secMiniCmd_t; -\end{verbatim} -\begin{verbatim} -struct secStatus { - int32_t busMode; - secVoltage selVolt; - secToneMode contTone; -}; -\end{verbatim} - -\begin{verbatim} -enum { - SEC_BUS_IDLE, - SEC_BUS_BUSY, - SEC_BUS_OFF, - SEC_BUS_OVERLOAD -}; -\end{verbatim} - - -\devsubsubsec{secCommand} -\label{seccommand} - -\begin{verbatim} -struct secCommand { - int32_t type; - union { - struct secDiseqcCmd diseqc; - uint8_t vsec; - uint32_t pause; - } u; -}; -\end{verbatim} - - -\devsubsubsec{secCmdSequence} -\label{seccmdsequence} - -\begin{verbatim} -struct secCmdSequence { - secVoltage voltage; - secMiniCmd miniCommand; - secToneMode continuousTone; - - uint32_t numCommands; - struct secCommand* commands; -}; -\end{verbatim} - -\begin{verbatim} -enum { - SEC_CMDTYPE_DISEQC, - SEC_CMDTYPE_VSEC, - SEC_CMDTYPE_PAUSE -}; -\end{verbatim} - -\begin{verbatim} -typedef enum { - SEC_DISEQC_SENT, - SEC_VSEC_SENT, - SEC_PAUSE_COMPLETE, - SEC_CALLBACK_ERROR -} secCallback_t; -\end{verbatim} - -\clearpage - -\devsubsec{SEC Function Calls} - -\function{open()}{ - int open(const char *deviceName, int flags);}{ - This system call opens a named SEC device for subsequent use. - If the device is opened in read-only mode, only status and statistics - monitoring is allowed. If the device is opened in read/write mode, all - types of operations can be performed. - Any number of applications can have simultaneous access to the device. - }{ - const char *deviceName & Name of specific SEC device.\\ - int flags & A bit-wise OR of the following flags:\\ - & \hspace{1em} O\_RDONLY read-only access\\ - & \hspace{1em} O\_RDWR read/write access\\ - & The optional flag O\_NONBLOCK is not supported. If O\_NONBLOCK is set, - open() and most other subsequent calls to the device will return -1 and - set errno to EWOULDBLOCK. - The communication with the peripheral devices is sequential by nature, - so it is probably preferable to use the device in synchronous mode. - This is the motivation for not going through the extra effort of - implementing asynchronous operation of the device. - }{ - ENODEV & Device driver not loaded/available.\\ - EFAULT & deviceName does not refer to a valid memory area.\\ - EBUSY & Device or resource busy.\\ - EINVAL & Invalid argument.\\ -} - -\function{close()}{ - int close(int fd);}{ - This system call closes a previously opened SEC device. - }{ - int fd & File descriptor returned by a previous call to open().\\ - }{ - EBADF & fd is not a valid open file descriptor.\\ -} - -\ifunction{SEC\_GET\_STATUS}{ - int ioctl(int fd, int request = SEC\_GET\_STATUS, struct secStatus* status);}{ - This call gets the status of the device. - }{ - int fd & File descriptor returned by a previous call to open().\\ - int request & Equals SEC\_GET\_STATUS for this command.\\ - struct secStatus* status & The status of the device.\\ - }{ - ENODEV & Device driver not loaded/available.\\ - EFAULT & status is an invalid pointer.\\ - EBUSY & Device or resource busy.\\ - EINVAL & Invalid argument.\\ - EPERM & File not opened with read permissions.\\ - EINTERNAL & Internal error in the device driver.\\ -} - -\ifunction{SEC\_RESET\_OVERLOAD}{ - int ioctl(int fd, int request = SEC\_RESET\_OVERLOAD);}{ - If the bus has been automatically powered off due to power overload, this - ioctl call restores the power to the bus. The call requires read/write - access to the device. - This call has no effect if the device is manually powered off. - }{ - int fd & File descriptor returned by a previous call to open().\\ - int request & Equals SEC\_RESET\_OVERLOAD for this command.\\ - }{ - EBADF & fd is not a valid file descriptor.\\ - EPERM & Permission denied (needs read/write access).\\ - EINTERNAL & Internal error in the device driver.\\ -} - -\ifunction{SEC\_SEND\_SEQUENCE}{ -int ioctl(int fd, int request = SEC\_SEND\_SEQUENCE, struct secCmdSequence *seq); -}{ -This ioctl call is used to send a sequence of DiSEqCTM and/or V-SEC -commands. The first version of the SEC device does not support V-SEC -signaling and it aborts the operation with an error code if a V-SEC -command is detected in the input data.\\ -\begin{itemize} -\item[$\bullet$] The call will fail with errno set to EBUSOVERLOAD if the bus is -overloaded. If the bus is overloaded, SEC\_RESET\_OVERLOAD can be -called and the operation can be retried. -\item[$\bullet$] If seq.numCommands equals 0 and seq.miniCommand equals SEC\_MINI\_NONE, -the bus voltage will be switched and the continuous 22kHz tone -generation enabled/disabled immediately. -\end{itemize}\\ -This operation is atomic. If several processes calls this ioctl -simultaneously, the operations will be serialized so a complete sequence -is sent at a time. - }{ - int fd & File descriptor returned by a previous call to open().\\ - int request & Equals SEC\_SEND\_SEQUENCE for this command.\\ - struct secCmdSequence *seq & Pointer to the command sequence to be transmitted.\\ - }{ - EBADF & fd is not a valid file descriptor.\\ - EFAULT & Seq points to an invalid address.\\ - EINVAL & The data structure referred to by seq is invalid in some way.\\ - EPERM & Permission denied (needs read/write access).\\ - EINTERNAL & Internal error in the device driver.\\ - EBUSMODE & The device is not prepared for transmission - (e.g. it might be manually powered off).\\ - EBUSOVERLOAD & Bus overload has occurred.\\ -} - - -\ifunction{SEC\_SET\_TONE}{ -int ioctl(int fd, int request = SEC\_SET\_TONE, secToneMode tone); -}{ -This call is used to set the generation of the continuous 22kHz tone. -The possibility to just change the tone mode is already provided by -ioctl SEC\_SEND\_SEQUENCE, but SEC\_SET\_TONE is an easier to use interface. -To keep the transmission of a command sequence as -an atomic operation, SEC\_SET\_TONE will block if a transmission is in -progress. This call requires read/write permissions. -}{ -int fd & File descriptor returned by a previous call to open().\\ -int request & Equals SEC\_SET\_TONE for this command.\\ -secToneMode tone & The requested tone generation mode (on/off).\\ -}{ -ENODEV & Device driver not loaded/available.\\ -EBUSY & Device or resource busy.\\ -EINVAL & Invalid argument.\\ -EPERM & File not opened with read permissions.\\ -EINTERNAL & Internal error in the device driver.\\ -} - - -\ifunction{SEC\_SET\_VOLTAGE}{ -int ioctl(int fd, int request = SEC\_SET\_VOLTAGE, secVoltage voltage); -}{ -This call is used to set the bus voltage. The possibility to just change -the bus voltage is already provided by ioctl SEC\_SEND\_SEQUENCE, but -SEC\_SET\_VOLTAGE is an easier to use interface. -To keep the transmission of a command sequence as -an atomic operation, SEC\_SET\_VOLTAGE will block if a transmission is in -progress. -This call requires read/write permissions. -}{ -int fd & File descriptor returned by a previous call to open().\\ -int request & Equals SEC\_SET\_VOLTAGE for this command.\\ -secVoltage voltage & The requested bus voltage.\\ -}{ -ENODEV & Device driver not loaded/available.\\ -EBUSY & Device or resource busy.\\ -EINVAL & Invalid argument.\\ -EPERM & File not opened with read permissions.\\ -EINTERNAL & Internal error in the device driver.\\ -} - -%%% Local Variables: -%%% mode: latex -%%% TeX-master: "dvbapi" -%%% End: diff --git a/dvb-spec/dvbapi/title.tex b/dvb-spec/dvbapi/title.tex index 693ed829d..857492b7e 100644 --- a/dvb-spec/dvbapi/title.tex +++ b/dvb-spec/dvbapi/title.tex @@ -1,18 +1,16 @@ \pagenumbering{arabic} \pagestyle{empty} -\title{\huge\textbf{LINUX DVB API}} +\title{\huge\textbf{LINUX DVB API Version 3}} \author{ \includegraphics{cimlogo.psi}\\ - Copyright \copyright 2002 Convergence GmbH\\\\ + Copyright 2002, 2003 Convergence GmbH\\\\ Written by Dr. Ralph J.K. Metzler\\ - \texttt{<rjkm@convergence.de>}\\\\ + \texttt{<rjkm@metzlerbros.de>}\\\\ and Dr. Marcus O.C. Metzler\\ - \texttt{<mocm@convergence.de>}\\ -% Rosenthalerstr. 51\\ -% 10178 Berlin\\Germany + \texttt{<mocm@metzlerbros.de>}\\ } -\date{10/01/2002\\V 0.9.5} +\date{24/07/2003\\V 1.0.0} \maketitle @@ -24,7 +22,6 @@ Free Documentation License". \newpage -%\end{titlepage} % Local Variables: % mode: latex % TeX-master: "dvbapi" diff --git a/dvb-spec/dvbapi/video.tex b/dvb-spec/dvbapi/video.tex index 2659db238..3fa066b87 100644 --- a/dvb-spec/dvbapi/video.tex +++ b/dvb-spec/dvbapi/video.tex @@ -1,32 +1,43 @@ \devsec{DVB Video Device} The DVB video device controls the MPEG2 video decoder of the DVB hardware. -It can be accessed through \texttt{/dev/ost/video}. -The include file \texttt{ost/video.h} defines the data types and lists -all I/O calls. Please note that some DVB cards don't have their own -MPEG decoder, which results in the omission of the audio and video -device as well as the video4linux device. +It can be accessed through \texttt{/dev/dvb/adapter0/video0}. +Data types and and ioctl definitions can be accessed by including +\texttt{linux/dvb/video.h} in your application. + + +Note that the DVB video device only controls decoding of the MPEG +video stream, not its presentation on the TV or computer screen. +On PCs this is typically handled by an associated video4linux device, e.g. +\texttt{/dev/video}, which allows scaling and defining output windows. + +Some DVB cards don't have their own MPEG decoder, which results in the omission +of the audio and video device as well as the video4linux device. + +The ioctls that deal with SPUs (sub picture units) and navigation +packets are only supported on some MPEG decoders made for DVD playback. + \devsubsec{Video Data Types} -\devsubsubsec{videoFormat\_t} +\devsubsubsec{video\_format\_t} \label{videoformat} -The \texttt{videoFormat\_t} data type defined by +The \texttt{video\_format\_t} data type defined by \begin{verbatim} typedef enum { VIDEO_FORMAT_4_3, VIDEO_FORMAT_16_9 -} videoFormat_t; +} video_format_t; \end{verbatim} is used in the VIDEO\_SET\_FORMAT function (\ref{videosetformat}) to tell the driver which aspect ratio the output hardware (e.g. TV) has. -It is also used in the data structures videoStatus (\ref{videostatus}) +It is also used in the data structures video\_status (\ref{videostatus}) returned by VIDEO\_GET\_STATUS (\ref{videogetstatus}) and -videoEvent (\ref{videoevent}) returned by VIDEO\_GET\_EVENT (\ref{videogetevent}) +video\_event (\ref{videoevent}) returned by VIDEO\_GET\_EVENT (\ref{videogetevent}) which report about the display format of the current video stream. -\devsubsubsec{videoDisplayFormat\_t} +\devsubsubsec{video\_display\_format\_t} \label{videodispformat} In case the display format of the video stream and of the @@ -39,7 +50,7 @@ typedef enum { VIDEO_PAN_SCAN, VIDEO_LETTER_BOX, VIDEO_CENTER_CUT_OUT -} videoDisplayFormat_t; +} video_display_format_t; \end{verbatim} as argument. @@ -53,7 +64,7 @@ replaying from an internal (demuxer) or external (user write) source. typedef enum { VIDEO_SOURCE_DEMUX, VIDEO_SOURCE_MEMORY -} videoStreamSource_t; +} video_stream_source_t; \end{verbatim} VIDEO\_SOURCE\_DEMUX selects the demultiplexer (fed either by the frontend or the DVR device) as the source of @@ -71,55 +82,55 @@ typedef enum { VIDEO_STOPPED, VIDEO_PLAYING, VIDEO_FREEZED -} videoPlayState_t; +} video_play_state_t; \end{verbatim} -\devsubsubsec{video event} +\devsubsubsec{struct video\_event} \label{videoevent} The following is the structure of a video event as it is returned by the VIDEO\_GET\_EVENT call. \begin{verbatim} -struct videoEvent { +struct video_event { int32_t type; time_t timestamp; union { - videoFormat_t videoFormat; + video_format_t video_format; } u; }; \end{verbatim} -\devsubsubsec{video status} +\devsubsubsec{struct video\_status} \label{videostatus} The VIDEO\_GET\_STATUS call returns the following structure informing about various states of the playback operation. \begin{verbatim} -struct videoStatus { - boolean videoBlank; - videoPlayState_t playState; - videoStreamSource_t streamSource; - videoFormat_t videoFormat; - videoDisplayFormat_t displayFormat; +struct video_status { + boolean video_blank; + video_play_state_t play_state; + video_stream_source_t stream_source; + video_format_t video_format; + video_displayformat_t display_format; }; \end{verbatim} -If videoBlank is set video will be blanked out if the channel is changed or +If video\_blank is set video will be blanked out if the channel is changed or if playback is stopped. Otherwise, the last picture will be displayed. -playState indicates if the video is currently frozen, stopped, or -being played back. The streamSource corresponds to the seleted source +play\_state indicates if the video is currently frozen, stopped, or +being played back. The stream\_source corresponds to the seleted source for the video stream. It can come either from the demultiplexer or from memory. -The videoFormat indicates the aspect ratio (one of 4:3 or 16:9) +The video\_format indicates the aspect ratio (one of 4:3 or 16:9) of the currently played video stream. -Finally, displayFormat corresponds to the selected cropping mode in case the +Finally, display\_format corresponds to the selected cropping mode in case the source video format is not the same as the format of the output device. -\devsubsubsec{video display still picture} +\devsubsubsec{struct video\_still\_picture} \label{videostill} An I-frame displayed via the VIDEO\_STILLPICTURE call is passed on within the following structure. \begin{verbatim} /* pointer to and size of a single iframe in memory */ -struct videoDisplayStillPicture { +struct video_still_picture { char *iFrame; int32_t size; }; @@ -162,19 +173,19 @@ typedef enum { VIDEO_SYSTEM_NTSC60, VIDEO_SYSTEM_PAL60, VIDEO_SYSTEM_PALM60 -} videoSystem_t; +} video_system_t; \end{verbatim} -\devsubsubsec{video highlights} +\devsubsubsec{struct video\_highlight} \label{vhilite} Calling the ioctl VIDEO\_SET\_HIGHLIGHTS posts the SPU highlight information. The call expects the following format for that information: - + \begin{verbatim} typedef -struct videoHighlight { +struct video_highlight { boolean active; /* 1=show highlight, 0=hide highlight */ uint8_t contrast1; /* 7- 4 Pattern pixel contrast */ /* 3- 0 Background pixel contrast */ @@ -190,7 +201,7 @@ struct videoHighlight { uint32_t xpos; /* 23-22 button color number */ /* 21-12 start x */ /* 9- 0 end x */ -} videoHighlight_t; +} video_highlight_t; \end{verbatim} @@ -200,10 +211,10 @@ Calling VIDEO\_SET\_SPU deactivates or activates SPU decoding, according to the following format: \begin{verbatim} typedef -struct videoSPU { +struct video_spu { boolean active; - int streamID; -} videoSPU_t; + int stream_id; +} video_spu_t; \end{verbatim} @@ -212,10 +223,10 @@ struct videoSPU { The following structure is used to set the SPU palette by calling VIDEO\_SPU\_PALETTE: \begin{verbatim} typedef -struct videoSPUPalette{ /* SPU Palette information */ +struct video_spu_palette{ int length; uint8_t *palette; -} videoSPUPalette_t; +} video_spu_palette_t; \end{verbatim} \devsubsubsec{video NAVI pack} @@ -224,10 +235,10 @@ In order to get the navigational data the following structure has to be passed to the ioctl VIDEO\_GET\_NAVI: \begin{verbatim} typedef -struct videoNaviPack{ - int length; /* 0 ... 1024 */ +struct video_navi_pack{ + int length; /* 0 ... 1024 */ uint8_t data[1024]; -} videoNaviPack_t; +} video_navi_pack_t; \end{verbatim} @@ -235,7 +246,7 @@ struct videoNaviPack{ \label{vattrib} The following attributes can be set by a call to VIDEO\_SET\_ATTRIBUTES: \begin{verbatim} -typedef uint16_t videoAttributes_t; +typedef uint16_t video_attributes_t; /* bits: descr. */ /* 15-14 Video compression mode (0=MPEG-1, 1=MPEG-2) */ /* 13-12 TV system (0=525/60, 1=625/50) */ @@ -255,7 +266,7 @@ typedef uint16_t videoAttributes_t; \function{open()}{ int open(const char *deviceName, int flags);}{ - This system call opens a named video device (e.g. /dev/ost/video) + This system call opens a named video device (e.g. /dev/dvb/adapter0/video0) for subsequent use. When an open() call has succeeded, the device will be ready for use. @@ -376,7 +387,7 @@ EINTERNAL & Internal error, possibly in the communication with \ifunction{VIDEO\_SELECT\_SOURCE}{ - int ioctl(fd, int request = VIDEO\_SELECT\_SOURCE, videoStreamSource\_t source);}{ + int ioctl(fd, int request = VIDEO\_SELECT\_SOURCE, video\_stream\_source\_t source);}{ This ioctl call informs the video device which source shall be used for the input data. The possible sources are demux or memory. If memory is selected, the data is fed to the video device through @@ -384,7 +395,7 @@ EINTERNAL & Internal error, possibly in the communication with }{ int fd & File descriptor returned by a previous call to open().\\ int request& Equals VIDEO\_SELECT\_SOURCE for this command. \\ - videoStreamSource\_t source&Indicates which source shall be used for the Video stream.\\ + video\_stream\_source\_t source&Indicates which source shall be used for the Video stream.\\ }{ EBADF& fd is not a valid open file descriptor \\ EINTERNAL & Internal error, possibly in the communication with the DVB subsystem.\\ @@ -406,12 +417,12 @@ EINVAL & Illegal input parameter\\ \ifunction{VIDEO\_GET\_STATUS}{ \label{videogetstatus} - int ioctl(fd, int request = VIDEO\_GET\_STATUS, struct videoStatus *status);}{ + int ioctl(fd, int request = VIDEO\_GET\_STATUS, struct video\_status *status);}{ This ioctl call asks the Video Device to return the current status of the device. }{ int fd & File descriptor returned by a previous call to open().\\ int request& Equals VIDEO\_GET\_STATUS for this command.\\ - struct videoStatus *status & Returns the current status of the Video Device.\\ + struct video\_status *status & Returns the current status of the Video Device.\\ }{ EBADF& fd is not a valid open file descriptor \\ EINTERNAL & Internal error, possibly in the communication with the DVB subsystem.\\ @@ -420,8 +431,8 @@ EFAULT & status points to invalid address\\ \ifunction{VIDEO\_GET\_EVENT}{ \label{videogetevent} - int ioctl(fd, int request = VIDEO\_GET\_EVENT, struct videoEvent *ev);}{ - This ioctl call returns an event of type videoEvent if available. + int ioctl(fd, int request = VIDEO\_GET\_EVENT, struct video\_event *ev);}{ + This ioctl call returns an event of type video\_event if available. If an event is not available, the behavior depends on whether the device is in blocking or non-blocking mode. In the latter case, the call fails immediately with errno set to EWOULDBLOCK. In the former case, the call blocks until an @@ -434,25 +445,25 @@ EFAULT & status points to invalid address\\ }{ int fd & File descriptor returned by a previous call to open().\\ int request& Equals VIDEO\_GET\_EVENT for this command.\\ - struct videoEvent *ev & Points to the location where the event, if any, is + struct video\_event *ev & Points to the location where the event, if any, is to be stored.\\ }{ EBADF & fd is not a valid open file descriptor \\ EFAULT & ev points to invalid address \\ EWOULDBLOCK & There is no event pending, and the device is in non-blocking mode.\\ -EBUFFEROVERFLOW & \\ +EOVERFLOW & \\ &Overflow in event queue - one or more events were lost.\\ } \ifunction{VIDEO\_SET\_DISPLAY\_FORMAT}{ \label{videosetdisplayformat} - int ioctl(fd, int request = VIDEO\_SET\_DISPLAY\_FORMAT, videoDisplayFormat\_t format);}{ + int ioctl(fd, int request = VIDEO\_SET\_DISPLAY\_FORMAT, video\_display\_format\_t format);}{ This ioctl call asks the Video Device to select the video format to be applied by the MPEG chip on the video. }{ int fd & File descriptor returned by a previous call to open().\\ int request & Equals VIDEO\_SET\_DISPLAY\_FORMAT for this command.\\ - videoDisplayFormat\_t format & Selects the video format to be used.\\ + video\_display\_format\_t format & Selects the video format to be used.\\ }{ EBADF& fd is not a valid open file descriptor \\ EINTERNAL & Internal error.\\ @@ -460,14 +471,14 @@ EBUFFEROVERFLOW & \\ } \ifunction{VIDEO\_STILLPICTURE}{ - int ioctl(fd, int request = VIDEO\_STILLPICTURE, struct videoDisplayStillPicture *sp);}{ + int ioctl(fd, int request = VIDEO\_STILLPICTURE, struct video\_still\_picture *sp);}{ This ioctl call asks the Video Device to display a still picture (I-frame). The input data shall contain an I-frame. If the pointer is NULL, then the current displayed still picture is blanked. }{ int fd & File descriptor returned by a previous call to open().\\ int request & Equals VIDEO\_STILLPICTURE for this command.\\ - struct videoDisplayStillPicture *sp& + struct video\_still\_picture *sp& Pointer to a location where an I-frame and size is stored.\\ }{ EBADF& fd is not a valid open file descriptor \\ @@ -562,7 +573,7 @@ EBUFFEROVERFLOW & \\ \ifunction{VIDEO\_SET\_FORMAT}{ \label{videosetformat} - int ioctl(fd, int request = VIDEO\_SET\_FORMAT, videoFormat\_t format); + int ioctl(fd, int request = VIDEO\_SET\_FORMAT, video\_format\_t format); }{ This ioctl sets the screen format (aspect ratio) of the connected output device (TV) so that the output of the decoder can @@ -570,7 +581,7 @@ EBUFFEROVERFLOW & \\ }{ int fd & File descriptor returned by a previous call to open().\\ int request & Equals VIDEO\_SET\_FORMAT for this command.\\ - videoFormat\_t format& video format of TV as defined in section \ref{videoformat}.\\ + video\_format\_t format& video format of TV as defined in section \ref{videoformat}.\\ }{ EBADF& fd is not a valid open file descriptor \\ EINVAL& format is not a valid video format.\\ @@ -578,7 +589,7 @@ EBUFFEROVERFLOW & \\ \ifunction{VIDEO\_SET\_SYSTEM}{ \label{videosetsystem} - int ioctl(fd, int request = VIDEO\_SET\_SYSTEM , videoSystem\_t system); + int ioctl(fd, int request = VIDEO\_SET\_SYSTEM , video\_system\_t system); }{ This ioctl sets the television output format. The format (see section \ref{videosys}) may vary from the color format of the displayed MPEG @@ -587,7 +598,7 @@ EBUFFEROVERFLOW & \\ }{ int fd & File descriptor returned by a previous call to open().\\ int request & Equals VIDEO\_SET\_FORMAT for this command.\\ - videoSystem\_t system& video system of TV output.\\ + video\_system\_t system& video system of TV output.\\ }{ EBADF& fd is not a valid open file descriptor \\ EINVAL& system is not a valid or supported video system.\\ @@ -595,14 +606,14 @@ EBUFFEROVERFLOW & \\ \ifunction{VIDEO\_SET\_HIGHLIGHT}{ \label{videosethighlight} - int ioctl(fd, int request = VIDEO\_SET\_HIGHLIGHT ,videoHighlight\_t *vhilite) + int ioctl(fd, int request = VIDEO\_SET\_HIGHLIGHT ,video\_highlight\_t *vhilite) }{ This ioctl sets the SPU highlight information for the menu access of a DVD. }{ int fd & File descriptor returned by a previous call to open().\\ int request & Equals VIDEO\_SET\_HIGHLIGHT for this command.\\ - videoHighlight\_t *vhilite& SPU Highlight information according to + video\_highlight\_t *vhilite& SPU Highlight information according to section \ref{vhilite}.\\ }{ EBADF& fd is not a valid open file descriptor. \\ @@ -612,7 +623,7 @@ EBUFFEROVERFLOW & \\ \ifunction{VIDEO\_SET\_SPU}{ \label{videosetspu} - int ioctl(fd, int request = VIDEO\_SET\_SPU , videoSPU\_t *spu) + int ioctl(fd, int request = VIDEO\_SET\_SPU , video\_spu\_t *spu) }{ This ioctl activates or deactivates SPU decoding in a DVD input stream. It can only be used, if the driver is able to handle a DVD @@ -620,7 +631,7 @@ EBUFFEROVERFLOW & \\ }{ int fd & File descriptor returned by a previous call to open().\\ int request & Equals VIDEO\_SET\_SPU for this command.\\ - videoSPU\_t *spu& SPU decoding (de)activation and subid setting + video\_spu\_t *spu& SPU decoding (de)activation and subid setting according to section \ref{videospu}.\\ }{ EBADF& fd is not a valid open file descriptor \\ @@ -630,13 +641,13 @@ EBUFFEROVERFLOW & \\ \ifunction{VIDEO\_SET\_SPU\_PALETTE}{ \label{videosetspupalette} - int ioctl(fd, int request = VIDEO\_SET\_SPU\_PALETTE ,videoSPUPalette\_t *palette ) + int ioctl(fd, int request = VIDEO\_SET\_SPU\_PALETTE ,video\_spu\_palette\_t *palette ) }{ This ioctl sets the SPU color palette. }{ int fd & File descriptor returned by a previous call to open().\\ int request & Equals VIDEO\_SET\_SPU\_PALETTE for this command.\\ - videoSPUPalette\_t *palette& SPU palette according to section \ref{vspupal}.\\ + video\_spu\_palette\_t *palette& SPU palette according to section \ref{vspupal}.\\ }{ EBADF& fd is not a valid open file descriptor \\ EINVAL& input is not a valid palette or driver doesn't handle SPU.\\ @@ -646,14 +657,14 @@ EBUFFEROVERFLOW & \\ \ifunction{VIDEO\_GET\_NAVI}{ \label{videosetnavi} - int ioctl(fd, int request = VIDEO\_GET\_NAVI , videoNaviPack\_t *navipack) + int ioctl(fd, int request = VIDEO\_GET\_NAVI , video\_navi\_pack\_t *navipack) }{ This ioctl returns navigational information from the DVD stream. This is especially needed if an encoded stream has to be decoded by the hardware. }{ int fd & File descriptor returned by a previous call to open().\\ int request & Equals VIDEO\_GET\_NAVI for this command.\\ - videoNaviPack\_t *navipack& PCI or DSI pack (private stream 2) + video\_navi\_pack\_t *navipack& PCI or DSI pack (private stream 2) according to section \ref{videonavi}.\\ }{ EBADF& fd is not a valid open file descriptor \\ @@ -663,7 +674,7 @@ EBUFFEROVERFLOW & \\ \ifunction{VIDEO\_SET\_ATTRIBUTES}{ \label{videosetattributes} - int ioctl(fd, int request = VIDEO\_SET\_ATTRIBUTE ,videoAttributes\_t + int ioctl(fd, int request = VIDEO\_SET\_ATTRIBUTE ,video\_attributes\_t vattr) }{ This ioctl is intended for DVD playback and allows you to set @@ -673,7 +684,7 @@ EBUFFEROVERFLOW & \\ }{ int fd & File descriptor returned by a previous call to open().\\ int request & Equals VIDEO\_SET\_ATTRIBUTE for this command.\\ - videoAttributes\_t vattr& video attributes according to section \ref{vattrib}.\\ + video\_attributes\_t vattr& video attributes according to section \ref{vattrib}.\\ }{ EBADF& fd is not a valid open file descriptor \\ EINVAL& input is not a valid attribute setting.\\ diff --git a/dvb-spec/valgrind-1.0.4.diff b/dvb-spec/valgrind-1.0.4.diff new file mode 100644 index 000000000..0e77afe14 --- /dev/null +++ b/dvb-spec/valgrind-1.0.4.diff @@ -0,0 +1,357 @@ +diff -Naur valgrind-1.0.4.orig/vg_syscall_mem.c valgrind-1.0.4/vg_syscall_mem.c +--- valgrind-1.0.4.orig/vg_syscall_mem.c 2002-10-13 17:04:49.000000000 +0200 ++++ valgrind-1.0.4/vg_syscall_mem.c 2003-03-03 07:34:50.000000000 +0100 +@@ -2323,6 +2323,336 @@ + sizeof(struct cdrom_msf)); + KERNEL_DO_SYSCALL(tid,res); + break; ++ ++ /* DVB (Digital Video Broadcasting) related stuff ++ * http://www.linuxtv.org ++ */ ++ case AUDIO_STOP: ++ case AUDIO_PLAY: ++ case AUDIO_PAUSE: ++ case AUDIO_CONTINUE: ++ case AUDIO_SELECT_SOURCE: ++ case AUDIO_SET_MUTE: ++ case AUDIO_SET_AV_SYNC: ++ case AUDIO_SET_BYPASS_MODE: ++ case AUDIO_CHANNEL_SELECT: ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case AUDIO_GET_STATUS: ++ must_be_writable(tst, "ioctl(AUDIO_GET_STATUS)", arg3, ++ sizeof(audio_status_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ make_readable (arg3, sizeof(audio_status_t)); ++ break; ++ case AUDIO_GET_CAPABILITIES: ++ must_be_writable(tst, "ioctl(AUDIO_GET_CAPABILITIES)", arg3, ++ sizeof(unsigned int)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ make_readable (arg3, sizeof(unsigned int)); ++ break; ++ case AUDIO_CLEAR_BUFFER: ++ case AUDIO_SET_ID: ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case AUDIO_SET_MIXER: ++ must_be_readable(tst, "ioctl(AUDIO_SET_MIXER)", arg3, ++ sizeof(audio_mixer_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case AUDIO_SET_STREAMTYPE: ++ case AUDIO_SET_EXT_ID: ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case AUDIO_SET_ATTRIBUTES: ++ must_be_readable(tst, "ioctl(AUDIO_SET_ATTRIBUTES)", arg3, ++ sizeof(audio_attributes_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case AUDIO_SET_KARAOKE: ++ must_be_readable(tst, "ioctl(AUDIO_SET_KARAOKE)", arg3, ++ sizeof(audio_karaoke_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case CA_RESET: ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case CA_GET_CAP: ++ must_be_writable(tst, "ioctl(CA_GET_CAP)", arg3, ++ sizeof(ca_caps_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ make_readable (arg3, sizeof(ca_caps_t)); ++ break; ++ case CA_GET_SLOT_INFO: ++ must_be_writable(tst, "ioctl(CA_GET_SLOT_INFO)", arg3, ++ sizeof(ca_slot_info_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ make_readable (arg3, sizeof(ca_slot_info_t)); ++ break; ++ case CA_GET_DESCR_INFO: ++ must_be_writable(tst, "ioctl(CA_GET_DESCR_INFO)", arg3, ++ sizeof(ca_descr_info_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ make_readable (arg3, sizeof(ca_descr_info_t)); ++ break; ++ case CA_GET_MSG: ++ must_be_writable(tst, "ioctl(CA_GET_MSG)", arg3, ++ sizeof(ca_msg_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ make_readable (arg3, sizeof(ca_msg_t)); ++ break; ++ case CA_SEND_MSG: ++ must_be_readable(tst, "ioctl(CA_SEND_MSG)", arg3, ++ sizeof(ca_msg_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case CA_SET_DESCR: ++ must_be_readable(tst, "ioctl(CA_SET_DESCR)", arg3, ++ sizeof(ca_descr_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case CA_SET_PID: ++ must_be_readable(tst, "ioctl(CA_SET_PID)", arg3, ++ sizeof(ca_pid_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case DMX_START: ++ case DMX_STOP: ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case DMX_SET_FILTER: ++ must_be_readable(tst, "ioctl(DMX_SET_FILTER)", arg3, ++ sizeof(struct dmx_sct_filter_params)); ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case DMX_SET_PES_FILTER: ++ must_be_readable(tst, "ioctl(DMX_SET_PES_FILTER)", arg3, ++ sizeof(struct dmx_pes_filter_params)); ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case DMX_SET_BUFFER_SIZE: ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case DMX_GET_EVENT: ++ must_be_writable(tst, "ioctl(DMX_GET_EVENT)", arg3, ++ sizeof(struct dmx_event)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ make_readable (arg3, sizeof(struct dmx_event)); ++ break; ++ case DMX_GET_PES_PIDS: ++ must_be_writable(tst, "ioctl(DMX_GET_PES_PIDS)", arg3, ++ 5*sizeof(uint16_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ make_readable (arg3, 5*sizeof(uint16_t)); ++ break; ++ case DMX_GET_CAPS: ++ must_be_writable(tst, "ioctl(DMX_GET_CAPS)", arg3, ++ sizeof(dmx_caps_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ make_readable (arg3, sizeof(dmx_caps_t)); ++ break; ++ case DMX_SET_SOURCE: ++ must_be_readable(tst, "ioctl(DMX_SET_SOURCE)", arg3, ++ sizeof(dmx_source_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case FE_GET_INFO: ++ must_be_writable(tst, "ioctl(FE_GET_INFO)", arg3, ++ sizeof(struct dvb_frontend_info)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ make_readable (arg3, sizeof(struct dvb_frontend_info)); ++ break; ++ case FE_DISEQC_RESET_OVERLOAD: ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case FE_DISEQC_SEND_MASTER_CMD: ++ must_be_readable(tst, "ioctl(FE_DISEQC_SEND_MASTER_CMD)", arg3, ++ sizeof(struct dvb_diseqc_master_cmd)); ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case FE_DISEQC_RECV_SLAVE_REPLY: ++ must_be_writable(tst, "ioctl(FE_DISEQC_RECV_SLAVE_REPLY)", arg3, ++ sizeof(struct dvb_diseqc_slave_reply)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ make_readable (arg3, sizeof(struct dvb_diseqc_slave_reply)); ++ break; ++ case FE_DISEQC_SEND_BURST: ++ case FE_SET_TONE: ++ case FE_SET_VOLTAGE: ++ case FE_ENABLE_HIGH_LNB_VOLTAGE: ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case FE_READ_STATUS: ++ must_be_writable(tst, "ioctl(FE_READ_STATUS)", arg3, ++ sizeof(fe_status_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ make_readable (arg3, sizeof(fe_status_t)); ++ break; ++ case FE_READ_BER: ++ must_be_writable(tst, "ioctl(FE_READ_BER)", arg3, ++ sizeof(uint32_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ make_readable (arg3, sizeof(uint32_t)); ++ break; ++ case FE_READ_SIGNAL_STRENGTH: ++ must_be_writable(tst, "ioctl(FE_READ_SIGNAL_STRENGTH)", arg3, ++ sizeof(uint16_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ make_readable (arg3, sizeof(uint16_t)); ++ break; ++ case FE_READ_SNR: ++ must_be_writable(tst, "ioctl(FE_READ_SNR)", arg3, ++ sizeof(uint16_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ make_readable (arg3, sizeof(uint16_t)); ++ break; ++ case FE_READ_UNCORRECTED_BLOCKS: ++ must_be_writable(tst, "ioctl(FE_READ_UNCORRECTED_BLOCKS)", arg3, ++ sizeof(uint32_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ make_readable (arg3, sizeof(uint32_t)); ++ break; ++ case FE_SET_FRONTEND: ++ must_be_readable(tst, "ioctl(FE_SET_FRONTEND)", arg3, ++ sizeof(struct dvb_frontend_parameters)); ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case FE_GET_FRONTEND: ++ must_be_writable(tst, "ioctl(FE_GET_FRONTEND)", arg3, ++ sizeof(struct dvb_frontend_parameters)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ make_readable (arg3, sizeof(struct dvb_frontend_parameters)); ++ break; ++ case FE_GET_EVENT: ++ must_be_writable(tst, "ioctl(FE_GET_EVENT)", arg3, ++ sizeof(struct dvb_frontend_event)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ make_readable (arg3, sizeof(struct dvb_frontend_event)); ++ break; ++ case NET_ADD_IF: ++ must_be_readable(tst, "ioctl(NET_ADD_IF (pid, uint16_t))", ++ (int) &(((struct dvb_net_if *) arg3)->pid), ++ sizeof(((struct dvb_net_if *) arg3)->pid)); ++ must_be_writable(tst, "ioctl(NET_ADD_IF (if_num, uint16_t))", ++ (int) &(((struct dvb_net_if *) arg3)->if_num), ++ sizeof(((struct dvb_net_if *) arg3)->if_num)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ make_readable (arg3, sizeof(struct dvb_net_if)); ++ break; ++ case NET_REMOVE_IF: ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case NET_GET_IF: ++ must_be_readable(tst, "ioctl(NET_GET_IF (if_num, uint16_t))", ++ (int) &(((struct dvb_net_if *) arg3)->if_num), ++ sizeof(((struct dvb_net_if *) arg3)->if_num)); ++ must_be_writable(tst, "ioctl(NET_GET_IF (pid, uint16_t))", ++ (int) &(((struct dvb_net_if *) arg3)->pid), ++ sizeof(((struct dvb_net_if *) arg3)->pid)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ make_readable (arg3, sizeof(struct dvb_net_if)); ++ break; ++ case OSD_SEND_CMD: ++ must_be_readable(tst, "ioctl(OSD_SEND_CMD)", arg3, ++ sizeof(osd_cmd_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case VIDEO_STOP: ++ case VIDEO_PLAY: ++ case VIDEO_FREEZE: ++ case VIDEO_CONTINUE: ++ case VIDEO_SELECT_SOURCE: ++ case VIDEO_SET_BLANK: ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case VIDEO_GET_STATUS: ++ must_be_writable(tst, "ioctl(VIDEO_GET_STATUS)", arg3, ++ sizeof(struct video_status)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ make_readable (arg3, sizeof(struct video_status)); ++ break; ++ case VIDEO_GET_EVENT: ++ must_be_writable(tst, "ioctl(VIDEO_GET_EVENT)", arg3, ++ sizeof(struct video_event)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ make_readable (arg3, sizeof(struct video_event)); ++ break; ++ case VIDEO_SET_DISPLAY_FORMAT: ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case VIDEO_STILLPICTURE: ++ must_be_readable(tst, "ioctl(VIDEO_STILLPICTURE)", arg3, ++ sizeof(struct video_still_picture)); ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case VIDEO_FAST_FORWARD: ++ case VIDEO_SLOWMOTION: ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case VIDEO_GET_CAPABILITIES: ++ must_be_writable(tst, "ioctl(VIDEO_GET_CAPABILITIES)", arg3, ++ sizeof(unsigned int)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ make_readable (arg3, sizeof(unsigned int)); ++ break; ++ case VIDEO_CLEAR_BUFFER: ++ case VIDEO_SET_ID: ++ case VIDEO_SET_STREAMTYPE: ++ case VIDEO_SET_FORMAT: ++ case VIDEO_SET_SYSTEM: ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case VIDEO_SET_HIGHLIGHT: ++ must_be_readable(tst, "ioctl(VIDEO_SET_HIGHLIGHT)", arg3, ++ sizeof(video_highlight_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case VIDEO_SET_SPU: ++ must_be_readable(tst, "ioctl(VIDEO_SET_SPU)", arg3, ++ sizeof(video_spu_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case VIDEO_SET_SPU_PALETTE: ++ must_be_readable(tst, "ioctl(VIDEO_SET_SPU_PALETTE)", arg3, ++ sizeof(video_spu_palette_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case VIDEO_GET_NAVI: ++ must_be_writable(tst, "ioctl(VIDEO_GET_NAVI)", arg3, ++ sizeof(video_navi_pack_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ make_readable (arg3, sizeof(video_navi_pack_t)); ++ break; ++#if 0 ++ /* FIXME: conflicts with NET_REMOVE_IF - both are _IO('o', 53) */ ++ case VIDEO_SET_ATTRIBUTES: ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++#endif ++ + /* We don't have any specific information on it, so + try to do something reasonable based on direction and + size bits. The encoding scheme is described in +diff -Naur valgrind-1.0.4.orig/vg_unsafe.h valgrind-1.0.4/vg_unsafe.h +--- valgrind-1.0.4.orig/vg_unsafe.h 2002-09-17 16:31:08.000000000 +0200 ++++ valgrind-1.0.4/vg_unsafe.h 2003-03-03 06:12:23.000000000 +0100 +@@ -86,6 +86,13 @@ + + #include <sys/poll.h> + ++#include <linux/dvb/audio.h> ++#include <linux/dvb/ca.h> ++#include <linux/dvb/dmx.h> ++#include <linux/dvb/frontend.h> ++#include <linux/dvb/net.h> ++#include <linux/dvb/osd.h> ++#include <linux/dvb/video.h> + + /*--------------------------------------------------------------------*/ + /*--- end vg_unsafe.h ---*/ diff --git a/dvb-spec/valgrind-1.9.4.diff b/dvb-spec/valgrind-1.9.4.diff new file mode 100644 index 000000000..bcc9de6ea --- /dev/null +++ b/dvb-spec/valgrind-1.9.4.diff @@ -0,0 +1,356 @@ +diff -Naur valgrind-1.9.4.orig/coregrind/vg_syscalls.c valgrind-1.9.4/coregrind/vg_syscalls.c +--- valgrind-1.9.4.orig/coregrind/vg_syscalls.c 2003-02-24 22:58:01.000000000 +0100 ++++ valgrind-1.9.4/coregrind/vg_syscalls.c 2003-03-03 07:25:43.000000000 +0100 +@@ -2365,6 +2365,335 @@ + KERNEL_DO_SYSCALL(tid,res); + break; + ++ /* DVB (Digital Video Broadcasting) related stuff ++ * http://www.linuxtv.org ++ */ ++ case AUDIO_STOP: ++ case AUDIO_PLAY: ++ case AUDIO_PAUSE: ++ case AUDIO_CONTINUE: ++ case AUDIO_SELECT_SOURCE: ++ case AUDIO_SET_MUTE: ++ case AUDIO_SET_AV_SYNC: ++ case AUDIO_SET_BYPASS_MODE: ++ case AUDIO_CHANNEL_SELECT: ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case AUDIO_GET_STATUS: ++ SYSCALL_TRACK( pre_mem_write,tst, "ioctl(AUDIO_GET_STATUS)", arg3, ++ sizeof(audio_status_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ VG_TRACK( post_mem_write,arg3, sizeof(audio_status_t)); ++ break; ++ case AUDIO_GET_CAPABILITIES: ++ SYSCALL_TRACK( pre_mem_write,tst, "ioctl(AUDIO_GET_CAPABILITIES)", arg3, ++ sizeof(unsigned int)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ VG_TRACK( post_mem_write,arg3, sizeof(unsigned int)); ++ break; ++ case AUDIO_CLEAR_BUFFER: ++ case AUDIO_SET_ID: ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case AUDIO_SET_MIXER: ++ SYSCALL_TRACK( pre_mem_read,tst, "ioctl(AUDIO_SET_MIXER)", arg3, ++ sizeof(audio_mixer_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case AUDIO_SET_STREAMTYPE: ++ case AUDIO_SET_EXT_ID: ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case AUDIO_SET_ATTRIBUTES: ++ SYSCALL_TRACK( pre_mem_read,tst, "ioctl(AUDIO_SET_ATTRIBUTES)", arg3, ++ sizeof(audio_attributes_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case AUDIO_SET_KARAOKE: ++ SYSCALL_TRACK( pre_mem_read,tst, "ioctl(AUDIO_SET_KARAOKE)", arg3, ++ sizeof(audio_karaoke_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case CA_RESET: ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case CA_GET_CAP: ++ SYSCALL_TRACK( pre_mem_write,tst, "ioctl(CA_GET_CAP)", arg3, ++ sizeof(ca_caps_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ VG_TRACK( post_mem_write,arg3, sizeof(ca_caps_t)); ++ break; ++ case CA_GET_SLOT_INFO: ++ SYSCALL_TRACK( pre_mem_write,tst, "ioctl(CA_GET_SLOT_INFO)", arg3, ++ sizeof(ca_slot_info_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ VG_TRACK( post_mem_write,arg3, sizeof(ca_slot_info_t)); ++ break; ++ case CA_GET_DESCR_INFO: ++ SYSCALL_TRACK( pre_mem_write,tst, "ioctl(CA_GET_DESCR_INFO)", arg3, ++ sizeof(ca_descr_info_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ VG_TRACK( post_mem_write,arg3, sizeof(ca_descr_info_t)); ++ break; ++ case CA_GET_MSG: ++ SYSCALL_TRACK( pre_mem_write,tst, "ioctl(CA_GET_MSG)", arg3, ++ sizeof(ca_msg_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ VG_TRACK( post_mem_write,arg3, sizeof(ca_msg_t)); ++ break; ++ case CA_SEND_MSG: ++ SYSCALL_TRACK( pre_mem_read,tst, "ioctl(CA_SEND_MSG)", arg3, ++ sizeof(ca_msg_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case CA_SET_DESCR: ++ SYSCALL_TRACK( pre_mem_read,tst, "ioctl(CA_SET_DESCR)", arg3, ++ sizeof(ca_descr_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case CA_SET_PID: ++ SYSCALL_TRACK( pre_mem_read,tst, "ioctl(CA_SET_PID)", arg3, ++ sizeof(ca_pid_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case DMX_START: ++ case DMX_STOP: ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case DMX_SET_FILTER: ++ SYSCALL_TRACK( pre_mem_read,tst, "ioctl(DMX_SET_FILTER)", arg3, ++ sizeof(struct dmx_sct_filter_params)); ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case DMX_SET_PES_FILTER: ++ SYSCALL_TRACK( pre_mem_read,tst, "ioctl(DMX_SET_PES_FILTER)", arg3, ++ sizeof(struct dmx_pes_filter_params)); ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case DMX_SET_BUFFER_SIZE: ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case DMX_GET_EVENT: ++ SYSCALL_TRACK( pre_mem_write,tst, "ioctl(DMX_GET_EVENT)", arg3, ++ sizeof(struct dmx_event)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ VG_TRACK( post_mem_write,arg3, sizeof(struct dmx_event)); ++ break; ++ case DMX_GET_PES_PIDS: ++ SYSCALL_TRACK( pre_mem_write,tst, "ioctl(DMX_GET_PES_PIDS)", arg3, ++ 5*sizeof(uint16_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ VG_TRACK( post_mem_write,arg3, 5*sizeof(uint16_t)); ++ break; ++ case DMX_GET_CAPS: ++ SYSCALL_TRACK( pre_mem_write,tst, "ioctl(DMX_GET_CAPS)", arg3, ++ sizeof(dmx_caps_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ VG_TRACK( post_mem_write,arg3, sizeof(dmx_caps_t)); ++ break; ++ case DMX_SET_SOURCE: ++ SYSCALL_TRACK( pre_mem_read,tst, "ioctl(DMX_SET_SOURCE)", arg3, ++ sizeof(dmx_source_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case FE_GET_INFO: ++ SYSCALL_TRACK( pre_mem_write,tst, "ioctl(FE_GET_INFO)", arg3, ++ sizeof(struct dvb_frontend_info)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ VG_TRACK( post_mem_write,arg3, sizeof(struct dvb_frontend_info)); ++ break; ++ case FE_DISEQC_RESET_OVERLOAD: ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case FE_DISEQC_SEND_MASTER_CMD: ++ SYSCALL_TRACK( pre_mem_read,tst, "ioctl(FE_DISEQC_SEND_MASTER_CMD)", arg3, ++ sizeof(struct dvb_diseqc_master_cmd)); ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case FE_DISEQC_RECV_SLAVE_REPLY: ++ SYSCALL_TRACK( pre_mem_write,tst, "ioctl(FE_DISEQC_RECV_SLAVE_REPLY)", arg3, ++ sizeof(struct dvb_diseqc_slave_reply)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ VG_TRACK( post_mem_write,arg3, sizeof(struct dvb_diseqc_slave_reply)); ++ break; ++ case FE_DISEQC_SEND_BURST: ++ case FE_SET_TONE: ++ case FE_SET_VOLTAGE: ++ case FE_ENABLE_HIGH_LNB_VOLTAGE: ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case FE_READ_STATUS: ++ SYSCALL_TRACK( pre_mem_write,tst, "ioctl(FE_READ_STATUS)", arg3, ++ sizeof(fe_status_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ VG_TRACK( post_mem_write,arg3, sizeof(fe_status_t)); ++ break; ++ case FE_READ_BER: ++ SYSCALL_TRACK( pre_mem_write,tst, "ioctl(FE_READ_BER)", arg3, ++ sizeof(uint32_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ VG_TRACK( post_mem_write,arg3, sizeof(uint32_t)); ++ break; ++ case FE_READ_SIGNAL_STRENGTH: ++ SYSCALL_TRACK( pre_mem_write,tst, "ioctl(FE_READ_SIGNAL_STRENGTH)", arg3, ++ sizeof(uint16_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ VG_TRACK( post_mem_write,arg3, sizeof(uint16_t)); ++ break; ++ case FE_READ_SNR: ++ SYSCALL_TRACK( pre_mem_write,tst, "ioctl(FE_READ_SNR)", arg3, ++ sizeof(uint16_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ VG_TRACK( post_mem_write,arg3, sizeof(uint16_t)); ++ break; ++ case FE_READ_UNCORRECTED_BLOCKS: ++ SYSCALL_TRACK( pre_mem_write,tst, "ioctl(FE_READ_UNCORRECTED_BLOCKS)", arg3, ++ sizeof(uint32_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ VG_TRACK( post_mem_write,arg3, sizeof(uint32_t)); ++ break; ++ case FE_SET_FRONTEND: ++ SYSCALL_TRACK( pre_mem_read,tst, "ioctl(FE_SET_FRONTEND)", arg3, ++ sizeof(struct dvb_frontend_parameters)); ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case FE_GET_FRONTEND: ++ SYSCALL_TRACK( pre_mem_write,tst, "ioctl(FE_GET_FRONTEND)", arg3, ++ sizeof(struct dvb_frontend_parameters)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ VG_TRACK( post_mem_write,arg3, sizeof(struct dvb_frontend_parameters)); ++ break; ++ case FE_GET_EVENT: ++ SYSCALL_TRACK( pre_mem_write,tst, "ioctl(FE_GET_EVENT)", arg3, ++ sizeof(struct dvb_frontend_event)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ VG_TRACK( post_mem_write,arg3, sizeof(struct dvb_frontend_event)); ++ break; ++ case NET_ADD_IF: ++ SYSCALL_TRACK( pre_mem_read,tst, "ioctl(NET_ADD_IF (pid, uint16_t))", ++ (int) &(((struct dvb_net_if *) arg3)->pid), ++ sizeof(((struct dvb_net_if *) arg3)->pid)); ++ SYSCALL_TRACK( pre_mem_write,tst, "ioctl(NET_ADD_IF (if_num, uint16_t))", ++ (int) &(((struct dvb_net_if *) arg3)->if_num), ++ sizeof(((struct dvb_net_if *) arg3)->if_num)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ VG_TRACK( post_mem_write,arg3, sizeof(struct dvb_net_if)); ++ break; ++ case NET_REMOVE_IF: ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case NET_GET_IF: ++ SYSCALL_TRACK( pre_mem_read,tst, "ioctl(NET_GET_IF (if_num, uint16_t))", ++ (int) &(((struct dvb_net_if *) arg3)->if_num), ++ sizeof(((struct dvb_net_if *) arg3)->if_num)); ++ SYSCALL_TRACK( pre_mem_write,tst, "ioctl(NET_GET_IF (pid, uint16_t))", ++ (int) &(((struct dvb_net_if *) arg3)->pid), ++ sizeof(((struct dvb_net_if *) arg3)->pid)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ VG_TRACK( post_mem_write,arg3, sizeof(struct dvb_net_if)); ++ break; ++ case OSD_SEND_CMD: ++ SYSCALL_TRACK( pre_mem_read,tst, "ioctl(OSD_SEND_CMD)", arg3, ++ sizeof(osd_cmd_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case VIDEO_STOP: ++ case VIDEO_PLAY: ++ case VIDEO_FREEZE: ++ case VIDEO_CONTINUE: ++ case VIDEO_SELECT_SOURCE: ++ case VIDEO_SET_BLANK: ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case VIDEO_GET_STATUS: ++ SYSCALL_TRACK( pre_mem_write,tst, "ioctl(VIDEO_GET_STATUS)", arg3, ++ sizeof(struct video_status)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ VG_TRACK( post_mem_write,arg3, sizeof(struct video_status)); ++ break; ++ case VIDEO_GET_EVENT: ++ SYSCALL_TRACK( pre_mem_write,tst, "ioctl(VIDEO_GET_EVENT)", arg3, ++ sizeof(struct video_event)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ VG_TRACK( post_mem_write,arg3, sizeof(struct video_event)); ++ break; ++ case VIDEO_SET_DISPLAY_FORMAT: ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case VIDEO_STILLPICTURE: ++ SYSCALL_TRACK( pre_mem_read,tst, "ioctl(VIDEO_STILLPICTURE)", arg3, ++ sizeof(struct video_still_picture)); ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case VIDEO_FAST_FORWARD: ++ case VIDEO_SLOWMOTION: ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case VIDEO_GET_CAPABILITIES: ++ SYSCALL_TRACK( pre_mem_write,tst, "ioctl(VIDEO_GET_CAPABILITIES)", arg3, ++ sizeof(unsigned int)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ VG_TRACK( post_mem_write,arg3, sizeof(unsigned int)); ++ break; ++ case VIDEO_CLEAR_BUFFER: ++ case VIDEO_SET_ID: ++ case VIDEO_SET_STREAMTYPE: ++ case VIDEO_SET_FORMAT: ++ case VIDEO_SET_SYSTEM: ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case VIDEO_SET_HIGHLIGHT: ++ SYSCALL_TRACK( pre_mem_read,tst, "ioctl(VIDEO_SET_HIGHLIGHT)", arg3, ++ sizeof(video_highlight_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case VIDEO_SET_SPU: ++ SYSCALL_TRACK( pre_mem_read,tst, "ioctl(VIDEO_SET_SPU)", arg3, ++ sizeof(video_spu_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case VIDEO_SET_SPU_PALETTE: ++ SYSCALL_TRACK( pre_mem_read,tst, "ioctl(VIDEO_SET_SPU_PALETTE)", arg3, ++ sizeof(video_spu_palette_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case VIDEO_GET_NAVI: ++ SYSCALL_TRACK( pre_mem_write,tst, "ioctl(VIDEO_GET_NAVI)", arg3, ++ sizeof(video_navi_pack_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ VG_TRACK( post_mem_write,arg3, sizeof(video_navi_pack_t)); ++ break; ++#if 0 ++ /* FIXME: conflicts with NET_REMOVE_IF - both are _IO('o', 53) */ ++ case VIDEO_SET_ATTRIBUTES: ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++#endif ++ + /* We don't have any specific information on it, so + try to do something reasonable based on direction and + size bits. The encoding scheme is described in +diff -Naur valgrind-1.9.4.orig/coregrind/vg_unsafe.h valgrind-1.9.4/coregrind/vg_unsafe.h +--- valgrind-1.9.4.orig/coregrind/vg_unsafe.h 2002-10-05 17:18:27.000000000 +0200 ++++ valgrind-1.9.4/coregrind/vg_unsafe.h 2003-03-03 07:00:37.000000000 +0100 +@@ -86,6 +86,13 @@ + + #include <sys/poll.h> + ++#include <linux/dvb/audio.h> ++#include <linux/dvb/ca.h> ++#include <linux/dvb/dmx.h> ++#include <linux/dvb/frontend.h> ++#include <linux/dvb/net.h> ++#include <linux/dvb/osd.h> ++#include <linux/dvb/video.h> + + /*--------------------------------------------------------------------*/ + /*--- end vg_unsafe.h ---*/ diff --git a/dvb-spec/valgrind-20030716.diff b/dvb-spec/valgrind-20030716.diff new file mode 100644 index 000000000..af0adc806 --- /dev/null +++ b/dvb-spec/valgrind-20030716.diff @@ -0,0 +1,361 @@ +--- valgrind-20030716/coregrind/vg_syscalls.c.orig 2003-07-05 17:44:45.000000000 +0200 ++++ valgrind-20030716/coregrind/vg_syscalls.c 2003-07-24 18:26:48.000000000 +0200 +@@ -2430,6 +2430,342 @@ void VG_(perform_assumed_nonblocking_sys + KERNEL_DO_SYSCALL(tid,res); + break; + ++ /* DVB (Digital Video Broadcasting) related stuff ++ * http://www.linuxtv.org ++ */ ++ case AUDIO_STOP: ++ case AUDIO_PLAY: ++ case AUDIO_PAUSE: ++ case AUDIO_CONTINUE: ++ case AUDIO_SELECT_SOURCE: ++ case AUDIO_SET_MUTE: ++ case AUDIO_SET_AV_SYNC: ++ case AUDIO_SET_BYPASS_MODE: ++ case AUDIO_CHANNEL_SELECT: ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case AUDIO_GET_STATUS: ++ SYSCALL_TRACK( pre_mem_write,tst, "ioctl(AUDIO_GET_STATUS)", arg3, ++ sizeof(audio_status_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ VG_TRACK( post_mem_write,arg3, sizeof(audio_status_t)); ++ break; ++ case AUDIO_GET_CAPABILITIES: ++ SYSCALL_TRACK( pre_mem_write,tst, "ioctl(AUDIO_GET_CAPABILITIES)", arg3, ++ sizeof(unsigned int)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ VG_TRACK( post_mem_write,arg3, sizeof(unsigned int)); ++ break; ++ case AUDIO_CLEAR_BUFFER: ++ case AUDIO_SET_ID: ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case AUDIO_SET_MIXER: ++ SYSCALL_TRACK( pre_mem_read,tst, "ioctl(AUDIO_SET_MIXER)", arg3, ++ sizeof(audio_mixer_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case AUDIO_SET_STREAMTYPE: ++ case AUDIO_SET_EXT_ID: ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case AUDIO_SET_ATTRIBUTES: ++ SYSCALL_TRACK( pre_mem_read,tst, "ioctl(AUDIO_SET_ATTRIBUTES)", arg3, ++ sizeof(audio_attributes_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case AUDIO_SET_KARAOKE: ++ SYSCALL_TRACK( pre_mem_read,tst, "ioctl(AUDIO_SET_KARAOKE)", arg3, ++ sizeof(audio_karaoke_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case CA_RESET: ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case CA_GET_CAP: ++ SYSCALL_TRACK( pre_mem_write,tst, "ioctl(CA_GET_CAP)", arg3, ++ sizeof(ca_caps_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ VG_TRACK( post_mem_write,arg3, sizeof(ca_caps_t)); ++ break; ++ case CA_GET_SLOT_INFO: ++ SYSCALL_TRACK( pre_mem_write,tst, "ioctl(CA_GET_SLOT_INFO)", arg3, ++ sizeof(ca_slot_info_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ VG_TRACK( post_mem_write,arg3, sizeof(ca_slot_info_t)); ++ break; ++ case CA_GET_DESCR_INFO: ++ SYSCALL_TRACK( pre_mem_write,tst, "ioctl(CA_GET_DESCR_INFO)", arg3, ++ sizeof(ca_descr_info_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ VG_TRACK( post_mem_write,arg3, sizeof(ca_descr_info_t)); ++ break; ++ case CA_GET_MSG: ++ SYSCALL_TRACK( pre_mem_write,tst, "ioctl(CA_GET_MSG)", arg3, ++ sizeof(ca_msg_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ VG_TRACK( post_mem_write,arg3, sizeof(ca_msg_t)); ++ break; ++ case CA_SEND_MSG: ++ SYSCALL_TRACK( pre_mem_read,tst, "ioctl(CA_SEND_MSG)", arg3, ++ sizeof(ca_msg_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case CA_SET_DESCR: ++ SYSCALL_TRACK( pre_mem_read,tst, "ioctl(CA_SET_DESCR)", arg3, ++ sizeof(ca_descr_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case CA_SET_PID: ++ SYSCALL_TRACK( pre_mem_read,tst, "ioctl(CA_SET_PID)", arg3, ++ sizeof(ca_pid_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case DMX_START: ++ case DMX_STOP: ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case DMX_SET_FILTER: ++ SYSCALL_TRACK( pre_mem_read,tst, "ioctl(DMX_SET_FILTER)", arg3, ++ sizeof(struct dmx_sct_filter_params)); ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case DMX_SET_PES_FILTER: ++ SYSCALL_TRACK( pre_mem_read,tst, "ioctl(DMX_SET_PES_FILTER)", arg3, ++ sizeof(struct dmx_pes_filter_params)); ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case DMX_SET_BUFFER_SIZE: ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case DMX_GET_EVENT: ++ SYSCALL_TRACK( pre_mem_write,tst, "ioctl(DMX_GET_EVENT)", arg3, ++ sizeof(struct dmx_event)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ VG_TRACK( post_mem_write,arg3, sizeof(struct dmx_event)); ++ break; ++ case DMX_GET_PES_PIDS: ++ SYSCALL_TRACK( pre_mem_write,tst, "ioctl(DMX_GET_PES_PIDS)", arg3, ++ 5*sizeof(uint16_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ VG_TRACK( post_mem_write,arg3, 5*sizeof(uint16_t)); ++ break; ++ case DMX_GET_CAPS: ++ SYSCALL_TRACK( pre_mem_write,tst, "ioctl(DMX_GET_CAPS)", arg3, ++ sizeof(dmx_caps_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ VG_TRACK( post_mem_write,arg3, sizeof(dmx_caps_t)); ++ break; ++ case DMX_GET_STC: ++ SYSCALL_TRACK( pre_mem_write,tst, "ioctl(DMX_GET_STC)", arg3, ++ sizeof(struct dmx_stc)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ VG_TRACK( post_mem_write,arg3, sizeof(struct dmx_stc)); ++ break; ++ case DMX_SET_SOURCE: ++ SYSCALL_TRACK( pre_mem_read,tst, "ioctl(DMX_SET_SOURCE)", arg3, ++ sizeof(dmx_source_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case FE_GET_INFO: ++ SYSCALL_TRACK( pre_mem_write,tst, "ioctl(FE_GET_INFO)", arg3, ++ sizeof(struct dvb_frontend_info)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ VG_TRACK( post_mem_write,arg3, sizeof(struct dvb_frontend_info)); ++ break; ++ case FE_DISEQC_RESET_OVERLOAD: ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case FE_DISEQC_SEND_MASTER_CMD: ++ SYSCALL_TRACK( pre_mem_read,tst, "ioctl(FE_DISEQC_SEND_MASTER_CMD)", arg3, ++ sizeof(struct dvb_diseqc_master_cmd)); ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case FE_DISEQC_RECV_SLAVE_REPLY: ++ SYSCALL_TRACK( pre_mem_write,tst, "ioctl(FE_DISEQC_RECV_SLAVE_REPLY)", arg3, ++ sizeof(struct dvb_diseqc_slave_reply)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ VG_TRACK( post_mem_write,arg3, sizeof(struct dvb_diseqc_slave_reply)); ++ break; ++ case FE_DISEQC_SEND_BURST: ++ case FE_SET_TONE: ++ case FE_SET_VOLTAGE: ++ case FE_ENABLE_HIGH_LNB_VOLTAGE: ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case FE_READ_STATUS: ++ SYSCALL_TRACK( pre_mem_write,tst, "ioctl(FE_READ_STATUS)", arg3, ++ sizeof(fe_status_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ VG_TRACK( post_mem_write,arg3, sizeof(fe_status_t)); ++ break; ++ case FE_READ_BER: ++ SYSCALL_TRACK( pre_mem_write,tst, "ioctl(FE_READ_BER)", arg3, ++ sizeof(uint32_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ VG_TRACK( post_mem_write,arg3, sizeof(uint32_t)); ++ break; ++ case FE_READ_SIGNAL_STRENGTH: ++ SYSCALL_TRACK( pre_mem_write,tst, "ioctl(FE_READ_SIGNAL_STRENGTH)", arg3, ++ sizeof(uint16_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ VG_TRACK( post_mem_write,arg3, sizeof(uint16_t)); ++ break; ++ case FE_READ_SNR: ++ SYSCALL_TRACK( pre_mem_write,tst, "ioctl(FE_READ_SNR)", arg3, ++ sizeof(uint16_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ VG_TRACK( post_mem_write,arg3, sizeof(uint16_t)); ++ break; ++ case FE_READ_UNCORRECTED_BLOCKS: ++ SYSCALL_TRACK( pre_mem_write,tst, "ioctl(FE_READ_UNCORRECTED_BLOCKS)", arg3, ++ sizeof(uint32_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ VG_TRACK( post_mem_write,arg3, sizeof(uint32_t)); ++ break; ++ case FE_SET_FRONTEND: ++ SYSCALL_TRACK( pre_mem_read,tst, "ioctl(FE_SET_FRONTEND)", arg3, ++ sizeof(struct dvb_frontend_parameters)); ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case FE_GET_FRONTEND: ++ SYSCALL_TRACK( pre_mem_write,tst, "ioctl(FE_GET_FRONTEND)", arg3, ++ sizeof(struct dvb_frontend_parameters)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ VG_TRACK( post_mem_write,arg3, sizeof(struct dvb_frontend_parameters)); ++ break; ++ case FE_GET_EVENT: ++ SYSCALL_TRACK( pre_mem_write,tst, "ioctl(FE_GET_EVENT)", arg3, ++ sizeof(struct dvb_frontend_event)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ VG_TRACK( post_mem_write,arg3, sizeof(struct dvb_frontend_event)); ++ break; ++ case NET_ADD_IF: ++ SYSCALL_TRACK( pre_mem_read,tst, "ioctl(NET_ADD_IF (pid, uint16_t))", ++ (int) &(((struct dvb_net_if *) arg3)->pid), ++ sizeof(((struct dvb_net_if *) arg3)->pid)); ++ SYSCALL_TRACK( pre_mem_write,tst, "ioctl(NET_ADD_IF (if_num, uint16_t))", ++ (int) &(((struct dvb_net_if *) arg3)->if_num), ++ sizeof(((struct dvb_net_if *) arg3)->if_num)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ VG_TRACK( post_mem_write,arg3, sizeof(struct dvb_net_if)); ++ break; ++ case NET_REMOVE_IF: ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case NET_GET_IF: ++ SYSCALL_TRACK( pre_mem_read,tst, "ioctl(NET_GET_IF (if_num, uint16_t))", ++ (int) &(((struct dvb_net_if *) arg3)->if_num), ++ sizeof(((struct dvb_net_if *) arg3)->if_num)); ++ SYSCALL_TRACK( pre_mem_write,tst, "ioctl(NET_GET_IF (pid, uint16_t))", ++ (int) &(((struct dvb_net_if *) arg3)->pid), ++ sizeof(((struct dvb_net_if *) arg3)->pid)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ VG_TRACK( post_mem_write,arg3, sizeof(struct dvb_net_if)); ++ break; ++ case OSD_SEND_CMD: ++ SYSCALL_TRACK( pre_mem_read,tst, "ioctl(OSD_SEND_CMD)", arg3, ++ sizeof(osd_cmd_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case VIDEO_STOP: ++ case VIDEO_PLAY: ++ case VIDEO_FREEZE: ++ case VIDEO_CONTINUE: ++ case VIDEO_SELECT_SOURCE: ++ case VIDEO_SET_BLANK: ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case VIDEO_GET_STATUS: ++ SYSCALL_TRACK( pre_mem_write,tst, "ioctl(VIDEO_GET_STATUS)", arg3, ++ sizeof(struct video_status)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ VG_TRACK( post_mem_write,arg3, sizeof(struct video_status)); ++ break; ++ case VIDEO_GET_EVENT: ++ SYSCALL_TRACK( pre_mem_write,tst, "ioctl(VIDEO_GET_EVENT)", arg3, ++ sizeof(struct video_event)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ VG_TRACK( post_mem_write,arg3, sizeof(struct video_event)); ++ break; ++ case VIDEO_SET_DISPLAY_FORMAT: ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case VIDEO_STILLPICTURE: ++ SYSCALL_TRACK( pre_mem_read,tst, "ioctl(VIDEO_STILLPICTURE)", arg3, ++ sizeof(struct video_still_picture)); ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case VIDEO_FAST_FORWARD: ++ case VIDEO_SLOWMOTION: ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case VIDEO_GET_CAPABILITIES: ++ SYSCALL_TRACK( pre_mem_write,tst, "ioctl(VIDEO_GET_CAPABILITIES)", arg3, ++ sizeof(unsigned int)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ VG_TRACK( post_mem_write,arg3, sizeof(unsigned int)); ++ break; ++ case VIDEO_CLEAR_BUFFER: ++ case VIDEO_SET_ID: ++ case VIDEO_SET_STREAMTYPE: ++ case VIDEO_SET_FORMAT: ++ case VIDEO_SET_SYSTEM: ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case VIDEO_SET_HIGHLIGHT: ++ SYSCALL_TRACK( pre_mem_read,tst, "ioctl(VIDEO_SET_HIGHLIGHT)", arg3, ++ sizeof(video_highlight_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case VIDEO_SET_SPU: ++ SYSCALL_TRACK( pre_mem_read,tst, "ioctl(VIDEO_SET_SPU)", arg3, ++ sizeof(video_spu_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case VIDEO_SET_SPU_PALETTE: ++ SYSCALL_TRACK( pre_mem_read,tst, "ioctl(VIDEO_SET_SPU_PALETTE)", arg3, ++ sizeof(video_spu_palette_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case VIDEO_GET_NAVI: ++ SYSCALL_TRACK( pre_mem_write,tst, "ioctl(VIDEO_GET_NAVI)", arg3, ++ sizeof(video_navi_pack_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ VG_TRACK( post_mem_write,arg3, sizeof(video_navi_pack_t)); ++ break; ++#if 0 ++ /* FIXME: conflicts with NET_REMOVE_IF - both are _IO('o', 53) */ ++ case VIDEO_SET_ATTRIBUTES: ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++#endif ++ + /* We don't have any specific information on it, so + try to do something reasonable based on direction and + size bits. The encoding scheme is described in +--- valgrind-20030716/coregrind/vg_unsafe.h.orig 2003-06-14 10:50:27.000000000 +0200 ++++ valgrind-20030716/coregrind/vg_unsafe.h 2003-07-24 18:22:55.000000000 +0200 +@@ -88,6 +88,13 @@ + + #include <sys/poll.h> + ++#include <linux/dvb/audio.h> ++#include <linux/dvb/ca.h> ++#include <linux/dvb/dmx.h> ++#include <linux/dvb/frontend.h> ++#include <linux/dvb/net.h> ++#include <linux/dvb/osd.h> ++#include <linux/dvb/video.h> + + /*--------------------------------------------------------------------*/ + /*--- end vg_unsafe.h ---*/ |