DVB cleanups and documentation improvements
Subsystems (2)
cover DVB cleanups and documentation improvements
This patch series comes after a previous patchset with DVB fixes. both series are there at:
https://git.linuxtv.org/mchehab/experimental.git/log/?h=dvb-fixes-v3
It is mainly focused on improving the DVB kAPI documentation, making it (finally!) in sync with the current implementation. It also contains a patch getting rid of the legacy (non-working) uAPI examples.
While reviewing the code implementation, I noticed some struct fields that aren't used at all by any DVB driver or core. So, the series gets rid of them. Others are used only on av7110, and are documented as such.
After this patch series, both DVB uAPI and kAPI are fully documented (except for the legacy video/audio/osd uAPI, that doesn't have any kAPI associated to them).
Granted, some things could be improved at the documentation, but at least it doesn't carry anymore any big gap or conflict!
Please review and test.
PS.: there is one patch in this series that really belongs to kernel-doc tree. I sent it already in separate, but, as without it several kernel-doc markups are ignored, I'm adding it here for consistency.
Mauro Carvalho Chehab (24):
media: dvb_frontend: better document the -EPERM condition
media: dvb_frontend: fix return values for FE_SET_PROPERTY
media: dvbdev: convert DVB device types into an enum
media: dvbdev: fully document its functions
media: dvb_frontend.h: improve kernel-doc markups
media: dtv-core.rst: add chapters and introductory tests for common
parts
media: dtv-core.rst: split into multiple files
media: dtv-demux.rst: minor markup improvements
media: dvb_demux.h: add an enum for DMX_TYPE_* and document
media: dvb_demux.h: add an enum for DMX_STATE_* and document
media: dvb_demux.h: get rid of unused timer at struct dvb_demux_filter
media: dvb_demux: mark a boolean field as such
media: dvb_demux: dvb_demux_feed.pusi_seen is boolean
media: dvb_demux.h: get rid of DMX_FEED_ENTRY() macro
media: dvb_demux: fix type of dvb_demux_feed.ts_type
media: dvb_demux: document dvb_demux_filter and dvb_demux_feed
media: dvb_frontend: get rid of dtv_get_property_dump()
media: dvb_demux.h: document structs defined on it
media: dvb_demux.h: document functions
scripts: kernel-doc: fix nexted handling
media: dmxdev.h: add kernel-doc markups for data types and functions
media: dtv-demux.rst: parse other demux headers with kernel-doc
media: dvb-net.rst: document DVB network kAPI interface
media: dvb uAPI docs: get rid of examples section
Satendra Singh Thakur (1):
media: dvb_frontend: dtv_property_process_set() cleanups
Documentation/media/kapi/dtv-ca.rst | 4 + Documentation/media/kapi/dtv-common.rst | 55 +++ Documentation/media/kapi/dtv-core.rst | 574 +---------------------- Documentation/media/kapi/dtv-demux.rst | 82 ++++ Documentation/media/kapi/dtv-frontend.rst | 443 +++++++++++++++++ Documentation/media/kapi/dtv-net.rst | 4 + Documentation/media/uapi/dvb/examples.rst | 378 +-------------- Documentation/media/uapi/dvb/fe-get-property.rst | 7 +- drivers/media/dvb-core/dmxdev.h | 90 +++- drivers/media/dvb-core/dvb_demux.c | 17 +- drivers/media/dvb-core/dvb_demux.h | 248 +++++++++- drivers/media/dvb-core/dvb_frontend.c | 180 +++---- drivers/media/dvb-core/dvb_frontend.h | 94 ++-- drivers/media/dvb-core/dvb_net.h | 34 +- drivers/media/dvb-core/dvbdev.c | 34 +- drivers/media/dvb-core/dvbdev.h | 137 +++++- drivers/media/pci/ttpci/av7110.c | 2 +- drivers/media/pci/ttpci/budget-core.c | 2 +- include/uapi/linux/dvb/frontend.h | 2 +- scripts/kernel-doc | 2 +- 20 files changed, 1248 insertions(+), 1141 deletions(-) create mode 100644 Documentation/media/kapi/dtv-ca.rst create mode 100644 Documentation/media/kapi/dtv-common.rst create mode 100644 Documentation/media/kapi/dtv-demux.rst create mode 100644 Documentation/media/kapi/dtv-frontend.rst create mode 100644 Documentation/media/kapi/dtv-net.rst
Signature · 1 line
2.13.5
PATCH 1/25 media: dvb_frontend: better document the -EPERM condition
Two readonly ioctls can't be allowed if the frontend device is opened in read only mode. Explain why.
--- drivers/media/dvb-core/dvb_frontend.c | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-)
drivers/media/dvb-core/dvb_frontend.c +17 -3
@@ -1940,9 +1940,23 @@ static int dvb_frontend_ioctl(struct file *file, unsigned int cmd, void *parg)return -ENODEV ; } -if ((file->f_flags &O_ACCMODE ) ==O_RDONLY && - (_IOC_DIR (cmd) != _IOC_READ || cmd ==FE_GET_EVENT || - cmd ==FE_DISEQC_RECV_SLAVE_REPLY )) { +/* +* If the frontend is opened in read-only mode, only the ioctls +* that don't interfere at the tune logic should be accepted. +* That allows an external application to monitor the DVB QoS and +* statistics parameters. +* +* That matches all _IOR() ioctls, except for two special cases: +* - FE_GET_EVENT is part of the tuning logic on a DVB application; +* - FE_DISEQC_RECV_SLAVE_REPLY is part of DiSEqC 2.0 +* setup +* So, those two ioctls should also return -EPERM, as otherwise +* reading from them would interfere with a DVB tune application +*/ +if ((file->f_flags &O_ACCMODE ) ==O_RDONLY + && (_IOC_DIR (cmd) != _IOC_READ + || cmd ==FE_GET_EVENT + || cmd ==FE_DISEQC_RECV_SLAVE_REPLY )) {up (&fepriv->sem);return -EPERM ; }
Signature · 1 line
2.13.5
Re: [PATCH 01/25] media: dvb_frontend: better document the -EPERM condition
Quoted 13 lines · Mauro Carvalho Chehab
Two readonly ioctls can't be allowed if the frontend device is opened in read only mode. Explain why.
Signed-off-by Mauro Carvalho Chehab <[email protected]>--- drivers/media/dvb-core/dvb_frontend.c | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-)drivers/media/dvb-core/dvb_frontend.c +0
-0
drivers/media/dvb-core/dvb_frontend.c static int dvb_frontend_ioctl(struct file *file, unsigned int cmd, void *parg) · line 1945
Quoted 9 lines
drivers/media/dvb-core/dvb_frontend.c +3
-3@@ -1940,9 +1940,23 @@ static int dvb_frontend_ioctl(struct file *file, unsigned int cmd, void *parg)return -ENODEV ; } -if ((file->f_flags &O_ACCMODE ) ==O_RDONLY && - (_IOC_DIR (cmd) != _IOC_READ || cmd ==FE_GET_EVENT || - cmd ==FE_DISEQC_RECV_SLAVE_REPLY )) { +/* +* If the frontend is opened in read-only mode, only the ioctls +* that don't interfere at the tune logic should be accepted.
Nit:
with the tune logic
Quoted 7 lines
drivers/media/dvb-core/dvb_frontend.c +6
-0+* That allows an external application to monitor the DVB QoS and +* statistics parameters. +*> + * That matches all _IOR() ioctls, except for two special cases: +* - FE_GET_EVENT is part of the tuning logic on a DVB application; +* - FE_DISEQC_RECV_SLAVE_REPLY is part of DiSEqC 2.0 +* setup
drivers/media/dvb-core/dvb_frontend.c static int dvb_frontend_ioctl(struct file *file, unsigned int cmd, void *parg) · line 1962
Quoted 10 lines
drivers/media/dvb-core/dvb_frontend.c +7
-0+* So, those two ioctls should also return -EPERM, as otherwise +* reading from them would interfere with a DVB tune application +*/ +if ((file->f_flags &O_ACCMODE ) ==O_RDONLY + && (_IOC_DIR (cmd) != _IOC_READ + || cmd ==FE_GET_EVENT + || cmd ==FE_DISEQC_RECV_SLAVE_REPLY )) {up (&fepriv->sem);return -EPERM ; }
Same comment from your previous series. I started looking at the old series and now the latest. Didn't realize the series has been revised. :(
Looks good to me
Reviewed by: Shuah Khan <[email protected]>
thanks,
-- Shuah
PATCH 2/25 media: dvb_frontend: fix return values for FE_SET_PROPERTY
In reply to Mauro Carvalho ChehabThere are several problems with regards to the return of FE_SET_PROPERTY. The original idea were to return per-property return codes via tvp->result field, and to return an updated set of values.
However, that never worked. What's actually implemented is:
- the FE_SET_PROPERTY implementation doesn't call .get_frontend callback in order to get the actual parameters after return;
- the tvp->result field is only filled if there's no error. So, it is always filled with zero;
- FE_SET_PROPERTY doesn't call memdup_user() nor any other copy_to_user() function. So, any changes at the properies will be lost;
- FE_SET_PROPERTY is declared as a write-only ioctl (IOW).
While we could fix the above, it could cause regressions.
So, let's just assume what the code really does, updating the documentation accordingly and removing the logic that would update the discarded tvp->result.
--- Documentation/media/uapi/dvb/fe-get-property.rst | 7 +++++-- drivers/media/dvb-core/dvb_frontend.c | 2 -- include/uapi/linux/dvb/frontend.h | 2 +- 3 files changed, 6 insertions(+), 5 deletions(-)
Documentation/media/uapi/dvb/fe-get-property.rst +5 -2
@@ -48,8 +48,11 @@ depends on the delivery system and on the device: - This call requires read/write access to the device. - - At return, the values are updated to reflect the actual parameters - used. +.. note:: + + At return, the values aren't updated to reflect the actual + parameters used. If the actual parameters are needed, an explicit + call to ``FE_GET_PROPERTY`` is needed. - ``FE_GET_PROPERTY:``
drivers/media/dvb-core/dvb_frontend.c +0 -2
@@ -2142,7 +2142,6 @@ static int dvb_frontend_handle_ioctl(struct file *file,kfree (tvp);return err; } - (tvp + i)->result = err; }kfree (tvp);break ;
@@ -2187,7 +2186,6 @@ static int dvb_frontend_handle_ioctl(struct file *file,kfree (tvp);return err; } - (tvp + i)->result = err; } if (copy_to_user((void __user *)tvps->props, tvp,
include/uapi/linux/dvb/frontend.h +1 -1
@@ -830,7 +830,7 @@ struct dtv_fe_stats {* @cmd: Digital TV command. * @reserved: Not used. * @u: Union with the values for the command. -* @result: Result of the command set (currently unused). +* @result: Unused * * The @u union may have either one of the values below: *
Signature · 1 line
2.13.5
Re: [PATCH 02/25] media: dvb_frontend: fix return values for FE_SET_PROPERTY
Quoted 7 lines · Mauro Carvalho Chehab
There are several problems with regards to the return of
FE_SET_PROPERTY. The original idea were to return per-property return codes viatvp->resultfield, and to return an updated set of values.However, that never worked. What's actually implemented is:
Quoted 8 lines
- the
FE_SET_PROPERTYimplementation doesn't call .get_frontend callback in order to get the actual parameters after return;- the
tvp->resultfield is only filled if there's no error. So, it is always filled with zero;-
FE_SET_PROPERTYdoesn't callmemdup_user()nor any othercopy_to_user()function. So, any changes at the properies
Spelling - properties
Nit: to the properties
Quoted 11 lines
will be lost;
-
FE_SET_PROPERTYis declared as a write-only ioctl (IOW).While we could fix the above, it could cause regressions.
So, let's just assume what the code really does, updating the documentation accordingly and removing the logic that would update the discarded
tvp->result.Signed-off-by Mauro Carvalho Chehab <[email protected]>
The rest looks good.
Quoted 50 lines
--- Documentation/media/uapi/dvb/fe-get-property.rst | 7 +++++-- drivers/media/dvb-core/dvb_frontend.c | 2 -- include/uapi/linux/dvb/frontend.h | 2 +- 3 files changed, 6 insertions(+), 5 deletions(-)Documentation/media/uapi/dvb/fe-get-property.rst +5
-2@@ -48,8 +48,11 @@ depends on the delivery system and on the device: - This call requires read/write access to the device. - - At return, the values are updated to reflect the actual parameters - used. +.. note:: + + At return, the values aren't updated to reflect the actual + parameters used. If the actual parameters are needed, an explicit + call to ``FE_GET_PROPERTY`` is needed. - ``FE_GET_PROPERTY:``drivers/media/dvb-core/dvb_frontend.c +0
-2@@ -2142,7 +2142,6 @@ static int dvb_frontend_handle_ioctl(struct file *file,kfree (tvp);return err; } - (tvp + i)->result = err; }kfree (tvp);break ;@@ -2187,7 +2186,6 @@ static int dvb_frontend_handle_ioctl(struct file *file,kfree (tvp);return err; } - (tvp + i)->result = err; } if (copy_to_user((void __user *)tvps->props, tvp,include/uapi/linux/dvb/frontend.h +0
-0
include/uapi/linux/dvb/frontend.h struct dtv_fe_stats { · line 836
Quoted 8 lines
include/uapi/linux/dvb/frontend.h +1
-1@@ -830,7 +830,7 @@ struct dtv_fe_stats {* @cmd: Digital TV command. * @reserved: Not used. * @u: Union with the values for the command. -* @result: Result of the command set (currently unused). +* @result: Unused * * The @u union may have either one of the values below: *
thanks,
-- Shuah
PATCH 3/25 media: dvbdev: convert DVB device types into an enum
In reply to Mauro Carvalho ChehabEnums can be documented via kernel-doc. So, convert the DVB_DEVICE_* macros to an enum.
--- drivers/media/dvb-core/dvbdev.c | 34 +++++++++++++++++++++++---- drivers/media/dvb-core/dvbdev.h | 51 ++++++++++++++++++++++++++++------------- 2 files changed, 64 insertions(+), 21 deletions(-)
drivers/media/dvb-core/dvbdev.c +29 -5
@@ -51,8 +51,15 @@ static LIST_HEAD(dvb_adapter_list);static DEFINE_MUTEX (dvbdev_register_lock);static const char *const dnames[] = { -"video" ,"audio" ,"sec" ,"frontend" ,"demux" ,"dvr" ,"ca" , -"net" ,"osd" + [DVB_DEVICE_VIDEO ] ="video" , + [DVB_DEVICE_AUDIO ] ="audio" , + [DVB_DEVICE_SEC ] ="sec" , + [DVB_DEVICE_FRONTEND ] ="frontend" , + [DVB_DEVICE_DEMUX ] ="demux" , + [DVB_DEVICE_DVR ] ="dvr" , + [DVB_DEVICE_CA ] ="ca" , + [DVB_DEVICE_NET ] ="net" , + [DVB_DEVICE_OSD ] ="osd" };#ifdef CONFIG_DVB_DYNAMIC_MINORS
@@ -60,7 +67,24 @@ static const char * const dnames[] = {#define DVB_MAX_IDS MAX_DVB_MINORS#else #define DVB_MAX_IDS 4 -#define nums2minor (num, type, id) ((num << 6) | (id << 4) | type) + +static int nums2minor (int num,enum dvb_device_type type,int id) +{ +int n = (num <<6 ) | (id <<4 ); + +switch (type) { +case DVB_DEVICE_VIDEO :return n; +case DVB_DEVICE_AUDIO :return n |1 ; +case DVB_DEVICE_SEC :return n |2 ; +case DVB_DEVICE_FRONTEND :return n |3 ; +case DVB_DEVICE_DEMUX :return n |4 ; +case DVB_DEVICE_DVR :return n |5 ; +case DVB_DEVICE_CA :return n |6 ; +case DVB_DEVICE_NET :return n |7 ; +case DVB_DEVICE_OSD :return n |8 ; + } +} +#define MAX_DVB_MINORS (DVB_MAX_ADAPTERS*64)#endif
@@ -426,8 +450,8 @@ static int dvb_register_media_device(struct dvb_device *dvbdev, }int dvb_register_device (struct dvb_adapter *adap,struct dvb_device **pdvbdev, -const struct dvb_device *template,void *priv,int type, -int demux_sink_pads) +const struct dvb_device *template,void *priv, +enum dvb_device_type type,int demux_sink_pads) {struct dvb_device *dvbdev;struct file_operations *dvbdevfops;
drivers/media/dvb-core/dvbdev.h +35 -16
81 lines not on this page · raw message
Signature · 1 line
2.13.5
Re: [PATCH 03/25] media: dvbdev: convert DVB device types into an enum
Quoted 106 lines · Mauro Carvalho Chehab
Enums can be documented via kernel-doc. So, convert the DVB_DEVICE_* macros to an enum.
Signed-off-by Mauro Carvalho Chehab <[email protected]>--- drivers/media/dvb-core/dvbdev.c | 34 +++++++++++++++++++++++---- drivers/media/dvb-core/dvbdev.h | 51 ++++++++++++++++++++++++++++------------- 2 files changed, 64 insertions(+), 21 deletions(-)drivers/media/dvb-core/dvbdev.c +29
-5@@ -51,8 +51,15 @@ static LIST_HEAD(dvb_adapter_list);static DEFINE_MUTEX (dvbdev_register_lock);static const char *const dnames[] = { -"video" ,"audio" ,"sec" ,"frontend" ,"demux" ,"dvr" ,"ca" , -"net" ,"osd" + [DVB_DEVICE_VIDEO ] ="video" , + [DVB_DEVICE_AUDIO ] ="audio" , + [DVB_DEVICE_SEC ] ="sec" , + [DVB_DEVICE_FRONTEND ] ="frontend" , + [DVB_DEVICE_DEMUX ] ="demux" , + [DVB_DEVICE_DVR ] ="dvr" , + [DVB_DEVICE_CA ] ="ca" , + [DVB_DEVICE_NET ] ="net" , + [DVB_DEVICE_OSD ] ="osd" };#ifdef CONFIG_DVB_DYNAMIC_MINORS @@ -60,7 +67,24 @@ static const char * const dnames[] = {#define DVB_MAX_IDS MAX_DVB_MINORS#else #define DVB_MAX_IDS 4 -#define nums2minor (num, type, id) ((num << 6) | (id << 4) | type) + +static int nums2minor (int num,enum dvb_device_type type,int id) +{ +int n = (num <<6 ) | (id <<4 ); + +switch (type) { +case DVB_DEVICE_VIDEO :return n; +case DVB_DEVICE_AUDIO :return n |1 ; +case DVB_DEVICE_SEC :return n |2 ; +case DVB_DEVICE_FRONTEND :return n |3 ; +case DVB_DEVICE_DEMUX :return n |4 ; +case DVB_DEVICE_DVR :return n |5 ; +case DVB_DEVICE_CA :return n |6 ; +case DVB_DEVICE_NET :return n |7 ; +case DVB_DEVICE_OSD :return n |8 ; + } +} +#define MAX_DVB_MINORS (DVB_MAX_ADAPTERS*64)#endif @@ -426,8 +450,8 @@ static int dvb_register_media_device(struct dvb_device *dvbdev, }int dvb_register_device (struct dvb_adapter *adap,struct dvb_device **pdvbdev, -const struct dvb_device *template,void *priv,int type, -int demux_sink_pads) +const struct dvb_device *template,void *priv, +enum dvb_device_type type,int demux_sink_pads) {struct dvb_device *dvbdev;struct file_operations *dvbdevfops;drivers/media/dvb-core/dvbdev.h +21
-9@@ -35,15 +35,37 @@#define DVB_UNSET (-1) -#define DVB_DEVICE_VIDEO 0 -#define DVB_DEVICE_AUDIO 1 -#define DVB_DEVICE_SEC 2 -#define DVB_DEVICE_FRONTEND 3 -#define DVB_DEVICE_DEMUX 4 -#define DVB_DEVICE_DVR 5 -#define DVB_DEVICE_CA 6 -#define DVB_DEVICE_NET 7 -#define DVB_DEVICE_OSD 8 +/* List of DVB device types */ + +/** +* enum dvb_device_type - type of the Digital TV device +* +* @DVB_DEVICE_SEC: Digital TV standalone Common Interface (CI) +* @DVB_DEVICE_FRONTEND: Digital TV frontend. +* @DVB_DEVICE_DEMUX: Digital TV demux. +* @DVB_DEVICE_DVR: Digital TV digital video record (DVR). +* @DVB_DEVICE_CA: Digital TV Conditional Access (CA). +* @DVB_DEVICE_NET: Digital TV network. +* +* @DVB_DEVICE_VIDEO: Digital TV video decoder. +* Deprecated. Used only on av7110-av. +* @DVB_DEVICE_AUDIO: Digital TV audio decoder. +* Deprecated. Used only on av7110-av. +* @DVB_DEVICE_OSD: Digital TV On Screen Display (OSD). +* Deprecated. Used only on av7110. +*/ +enum dvb_device_type { +DVB_DEVICE_SEC ,
drivers/media/dvb-core/dvbdev.h line 68
Quoted 10 lines
drivers/media/dvb-core/dvbdev.h +10
-0+DVB_DEVICE_FRONTEND , +DVB_DEVICE_DEMUX , +DVB_DEVICE_DVR , +DVB_DEVICE_CA , +DVB_DEVICE_NET , + +DVB_DEVICE_VIDEO , +DVB_DEVICE_AUDIO , + DVB_DEVICE_OSD, +};
maybe instead:
```
enum dvb_device_type {
DVB_DEVICE_SEC = 0,
DVB_DEVICE_FRONTEND = 1,
DVB_DEVICE_DEMUX = 2,
DVB_DEVICE_DVR = 3,
DVB_DEVICE_CA = 4,
DVB_DEVICE_NET = 5,
DVB_DEVICE_VIDEO = 6,
DVB_DEVICE_AUDIO = 7,
DVB_DEVICE_OSD = 8,
};
```...and then maybe nums2minor() can be optimized to take advantage of that assignment.
Quoted 45 lines
drivers/media/dvb-core/dvbdev.h +4
-8#define DVB_DEFINE_MOD_OPT_ADAPTER_NR (adapter_nr) \ static short adapter_nr[] = \@@ -104,8 +126,7 @@ struct dvb_adapter {* @list_head: List head with all DVB devices * @fops: pointer to struct file_operations * @adapter: pointer to the adapter that holds this device node -* @type: type of the device: DVB_DEVICE_SEC, DVB_DEVICE_FRONTEND, -* DVB_DEVICE_DEMUX, DVB_DEVICE_DVR, DVB_DEVICE_CA, DVB_DEVICE_NET +* @type: type of the device, as defined by &enum dvb_device_type. * @minor: devnode minor number. Major number is always DVB_MAJOR. * @id: device ID number, inside the adapter * @readers: Initialized by the caller. Each call to open() in Read Only mode @@ -135,7 +156,7 @@ struct dvb_device {struct list_head list_head;const struct file_operations *fops;struct dvb_adapter *adapter; -int type; +enum dvb_device_type type;int minor;u32 id;@@ -194,9 +215,7 @@ int dvb_unregister_adapter(struct dvb_adapter *adap);* stored * @template: Template used to create &pdvbdev; * @priv: private data -* @type: type of the device: %DVB_DEVICE_SEC, %DVB_DEVICE_FRONTEND, -* %DVB_DEVICE_DEMUX, %DVB_DEVICE_DVR, %DVB_DEVICE_CA, -* %DVB_DEVICE_NET +* @type: type of the device, as defined by &enum dvb_device_type. * @demux_sink_pads: Number of demux outputs, to be used to create the TS * outputs via the Media Controller. */ @@ -204,7 +223,7 @@ int dvb_register_device(struct dvb_adapter *adap,struct dvb_device **pdvbdev, const struct dvb_device *template, void *priv, - int type, + enum dvb_device_type type, int demux_sink_pads);/** -- 2.13.5
Re: [PATCH 03/25] media: dvbdev: convert DVB device types into an enum
Em Thu, 21 Sep 2017 09:06:54 -0400
Michael Ira Krufky <[email protected]> escreveu:
Quoted 32 lines
Review
Quoted 12 lines · Mauro Carvalho Chehab
(quoted diff) +12
-0+enum dvb_device_type { + DVB_DEVICE_SEC, + DVB_DEVICE_FRONTEND, + DVB_DEVICE_DEMUX, + DVB_DEVICE_DVR, + DVB_DEVICE_CA, + DVB_DEVICE_NET, + + DVB_DEVICE_VIDEO, + DVB_DEVICE_AUDIO, + DVB_DEVICE_OSD, +};maybe instead:
``` enum dvb_device_type { DVB_DEVICE_SEC = 0, DVB_DEVICE_FRONTEND = 1, DVB_DEVICE_DEMUX = 2, DVB_DEVICE_DVR = 3, DVB_DEVICE_CA = 4, DVB_DEVICE_NET = 5, DVB_DEVICE_VIDEO = 6, DVB_DEVICE_AUDIO = 7, DVB_DEVICE_OSD = 8, }; ```
Quoted 2 lines
...and then maybe
nums2minor()can be optimized to take advantage of that assignment.
That will break userspace :-) The DVB minor ranges are (from Documentation/drivers.txt):
212 char LinuxTV.org DVB driver subsystem
0 = /dev/dvb/adapter0/video0 first video decoder of first c
ard
1 = /dev/dvb/adapter0/audio0 first audio decoder of first c
ard
2 = /dev/dvb/adapter0/sec0 (obsolete/unused)
3 = /dev/dvb/adapter0/frontend0 first frontend device of first
card
4 = /dev/dvb/adapter0/demux0 first demux device of first ca
rd
5 = /dev/dvb/adapter0/dvr0 first digital video recoder de
vice of first card
6 = /dev/dvb/adapter0/ca0 first common access port of fi
rst card
7 = /dev/dvb/adapter0/net0 first network device of first
card
8 = /dev/dvb/adapter0/osd0 first on-screen-display device
of first card
Btw, the main reason to add a switch at nums2minor() is due to that:
it requires an specific number for each device type, and it is very easy to forget about that when looking at the implementation.
As some day we may get rid of video/audio/osd types, it sounded worth to add an extra code. Please notice, however, that nums2minor only exists if !CONFIG_DVB_DYNAMIC_MINORS.
I suspect that, except for some embedded devices, the default is to have it enabled everywhere.
Yet, after revisiting it and checking the generated assembly code, I guess we could fold the enclosed patch, in order to simplify the static minor support of the DVB core:
drivers/media/dvb-core/dvbdev.c +13 -15
@@ -68,22 +68,20 @@ static const char * const dnames[] = {#else #define DVB_MAX_IDS 4 -static int nums2minor (int num,enum dvb_device_type type,int id) -{ -int n = (num <<6 ) | (id <<4 ); +static const u8 minor_type[] = { + [DVB_DEVICE_VIDEO ] =0 , + [DVB_DEVICE_AUDIO ] =1 , + [DVB_DEVICE_SEC ] =2 , + [DVB_DEVICE_FRONTEND ] =3 , + [DVB_DEVICE_DEMUX ] =4 , + [DVB_DEVICE_DVR ] =5 , + [DVB_DEVICE_CA ] =6 , + [DVB_DEVICE_NET ] =7 , + [DVB_DEVICE_OSD ] =8 , +}; -switch (type) { -case DVB_DEVICE_VIDEO :return n; -case DVB_DEVICE_AUDIO :return n |1 ; -case DVB_DEVICE_SEC :return n |2 ; -case DVB_DEVICE_FRONTEND :return n |3 ; -case DVB_DEVICE_DEMUX :return n |4 ; -case DVB_DEVICE_DVR :return n |5 ; -case DVB_DEVICE_CA :return n |6 ; -case DVB_DEVICE_NET :return n |7 ; -case DVB_DEVICE_OSD :return n |8 ; - } -} +#define nums2minor (num, type, id) \ + (((num) << 6) | ((id) << 4) | minor_type[type])#define MAX_DVB_MINORS (DVB_MAX_ADAPTERS*64)#endif
With the above change, it seems that the code is likely only a few bytes longer than the original code, and make it clearer about the static minor numbering requirements.
The generated i386 asm code at the read only data segment is:
minor_type:
.byte 2 .byte 3 .byte 4 .byte 5 .byte 6 .byte 7 .byte 0 .byte 1 .byte 8
And at the code segment:
# drivers/media/dvb-core/dvbdev.c:511: minor = nums2minor(adap->num, type, id); .loc 1 511 0 movl -20(%ebp), %eax # %sfp, adap .LVL295: movl (%eax), %eax # adap_29(D)->num, adap_29(D)->num .LVL296: movl %eax, -24(%ebp) # adap_29(D)->num, %sfp movl %eax, %edx # adap_29(D)->num, adap_29(D)->num movl 12(%ebp), %eax # type, tmp265 sall $6, %edx #, adap_29(D)->num movzbl minor_type(%eax), %eax # minor_type, tmp193 orl %eax, %edx # tmp193, tmp194 movl -16(%ebp), %eax # %sfp, tmp195 movl %edx, %edi # tmp194, tmp194 sall $4, %eax #, tmp195 orl %eax, %edi # tmp195, tmp194
That seems good enough on my eyes.
Thanks,
Mauro
PATCH 4/25 media: dvbdev: fully document its functions
In reply to Mauro Carvalho ChehabThere are several functions at the dvbdev that are common to all digital TV device nodes with aren't documented.
Add documentation for them. No functional changes.
--- drivers/media/dvb-core/dvbdev.h | 86 +++++++++++++++++++++++++++++++++++++---- 1 file changed, 78 insertions(+), 8 deletions(-)
drivers/media/dvb-core/dvbdev.h +78 -8
@@ -261,7 +261,7 @@ void dvb_unregister_device(struct dvb_device *dvbdev);* dvb_create_media_graph - Creates media graph for the Digital TV part of the * device. * -* @adap: pointer to struct dvb_adapter +* @adap: pointer to &struct dvb_adapter * @create_rf_connector: if true, it creates the RF connector too * * This function checks all DVB-related functions at the media controller
@@ -274,12 +274,23 @@ void dvb_unregister_device(struct dvb_device *dvbdev);__must_check int dvb_create_media_graph (struct dvb_adapter *adap,bool create_rf_connector); +/** +* dvb_register_media_controller - registers a media controller at DVB adapter +* +* @adap: pointer to &struct dvb_adapter +* @mdev: pointer to &struct media_device +*/ static inline void dvb_register_media_controller (struct dvb_adapter *adap,struct media_device *mdev) { adap->mdev = mdev; } +/** +* dvb_get_media_controller - gets the associated media controller +* +* @adap: pointer to &struct dvb_adapter +*/ static inline struct media_device *dvb_get_media_controller (struct dvb_adapter *adap) {
@@ -296,20 +307,71 @@ int dvb_create_media_graph(struct dvb_adapter *adap,#define dvb_get_media_controller (a) NULL#endif -int dvb_generic_open (struct inode *inode,struct file *file); -int dvb_generic_release (struct inode *inode,struct file *file); -long dvb_generic_ioctl (struct file *file, -unsigned int cmd,unsigned long arg); +/** +* dvb_generic_open - Digital TV open function, used by DVB devices +* +* @inode: pointer to &struct inode. +* @file: pointer to &struct file. +* +* Checks if a DVB devnode is still valid, and if the permissions are +* OK and increment negative use count. +*/ +int dvb_generic_open (struct inode *inode,struct file *file); -/* we don't mess with video_usercopy() any more, -we simply define out own dvb_usercopy(), which will hopefully become -generic_usercopy() someday... */ +/** +* dvb_generic_close - Digital TV close function, used by DVB devices +* +* @inode: pointer to &struct inode. +* @file: pointer to &struct file. +* +* Checks if a DVB devnode is still valid, and if the permissions are +* OK and decrement negative use count. +*/ +int dvb_generic_release (struct inode *inode,struct file *file); +/** +* dvb_generic_ioctl - Digital TV close function, used by DVB devices +* +* @file: pointer to &struct file. +* @cmd: Ioctl name. +* @arg: Ioctl argument. +* +* Checks if a DVB devnode and struct dvbdev.kernel_ioctl is still valid. +* If so, calls dvb_usercopy(). +*/ +long dvb_generic_ioctl (struct file *file, +unsigned int cmd,unsigned long arg); + +/** +* dvb_usercopy - copies data from/to userspace memory when an ioctl is +* issued. +* +* @file: Pointer to struct &file. +* @cmd: Ioctl name. +* @arg: Ioctl argument. +* @func: function that will actually handle the ioctl +* +* Ancillary function that uses ioctl direction and size to copy from +* userspace. Then, it calls @func, and, if needed, data is copied back +* to userspace. +*/ int dvb_usercopy (struct file *file,unsigned int cmd,unsigned long arg,int (*func)(struct file *file,unsigned int cmd,void *arg));/** generic DVB attach function. */ #ifdef CONFIG_MEDIA_ATTACH + +/** +* dvb_attach - attaches a DVB frontend into the DVB core. +* +* @FUNCTION: function on a frontend module to be called. +* @ARGS...: @FUNCTION arguments. +* +* This ancillary function loads a frontend module in runtime and runs +* the @FUNCTION function there, with @ARGS. +* As it increments symbol usage cont, at unregister, dvb_detach() +* should be called. +*/ #define dvb_attach(FUNCTION, ARGS...) ({ \ void *__r = NULL; \ typeof(&FUNCTION) __a = symbol_request(FUNCTION); \
@@ -323,6 +385,14 @@ int dvb_usercopy(struct file *file, unsigned int cmd, unsigned long arg, __r; \ }) +/** +* dvb_detach - detaches a DVB frontend loaded via dvb_attach() +* +* @FUNC: attach function +* +* Decrements usage count for a function previously called via dvb_attach(). +*/ +#define dvb_detach (FUNC ) symbol_put_addr(FUNC)#else
Signature · 1 line
2.13.5
PATCH 5/25 media: dvb_frontend.h: improve kernel-doc markups
In reply to Mauro Carvalho ChehabSeveral minor adjustments at the kernel-doc markups:
- some syntax fixes;
- some cross-references;
- add cross-references for the mentioned ioctls;
- some constants marked as such.
No functional changes.
--- drivers/media/dvb-core/dvb_frontend.h | 94 +++++++++++++++++------------------ 1 file changed, 47 insertions(+), 47 deletions(-)
drivers/media/dvb-core/dvb_frontend.h +47 -47
@@ -180,8 +180,8 @@ enum dvbfe_search {/** * struct dvb_tuner_ops - Tuner information and callbacks * -* @info: embedded struct dvb_tuner_info with tuner properties -* @release: callback function called when frontend is dettached. +* @info: embedded &struct dvb_tuner_info with tuner properties +* @release: callback function called when frontend is detached. * drivers should free any allocated memory. * @init: callback function used to initialize the tuner device. * @sleep: callback function used to put the tuner to sleep.
@@ -191,14 +191,14 @@ enum dvbfe_search {* resuming from suspend. * @set_params: callback function used to inform the tuner to tune * into a digital TV channel. The properties to be used -* are stored at @dvb_frontend.dtv_property_cache;. The -* tuner demod can change the parameters to reflect the -* changes needed for the channel to be tuned, and +* are stored at &struct dvb_frontend.dtv_property_cache. +* The tuner demod can change the parameters to reflect +* the changes needed for the channel to be tuned, and * update statistics. This is the recommended way to set * the tuner parameters and should be used on newer * drivers. * @set_analog_params: callback function used to tune into an analog TV -* channel on hybrid tuners. It passes @analog_parameters; +* channel on hybrid tuners. It passes @analog_parameters * to the driver. * @set_config: callback function used to send some tuner-specific * parameters.
@@ -207,9 +207,9 @@ enum dvbfe_search {* @get_if_frequency: get the Intermediate Frequency, in Hz. For baseband, * should return 0. * @get_status: returns the frontend lock status -* @get_rf_strength: returns the RF signal strengh. Used mostly to support +* @get_rf_strength: returns the RF signal strength. Used mostly to support * analog TV and radio. Digital TV should report, instead, -* via DVBv5 API (@dvb_frontend.dtv_property_cache;). +* via DVBv5 API (&struct dvb_frontend.dtv_property_cache). * @get_afc: Used only by analog TV core. Reports the frequency * drift due to AFC. * @calc_regs: callback function used to pass register data settings
@@ -217,7 +217,7 @@ enum dvbfe_search {* @set_frequency: Set a new frequency. Shouldn't be used on newer drivers. * @set_bandwidth: Set a new frequency. Shouldn't be used on newer drivers. * -* NOTE: frequencies used on get_frequency and set_frequency are in Hz for +* NOTE: frequencies used on @get_frequency and @set_frequency are in Hz for * terrestrial/cable or kHz for satellite. * */
@@ -283,14 +283,14 @@ struct analog_demod_info {* @set_params: callback function used to inform the demod to set the * demodulator parameters needed to decode an analog or * radio channel. The properties are passed via -* struct @analog_params;. +* &struct analog_params. * @has_signal: returns 0xffff if has signal, or 0 if it doesn't. * @get_afc: Used only by analog TV core. Reports the frequency * drift due to AFC. * @tuner_status: callback function that returns tuner status bits, e. g. -* TUNER_STATUS_LOCKED and TUNER_STATUS_STEREO. +* %TUNER_STATUS_LOCKED and %TUNER_STATUS_STEREO. * @standby: set the tuner to standby mode. -* @release: callback function called when frontend is dettached. +* @release: callback function called when frontend is detached. * drivers should free any allocated memory. * @i2c_gate_ctrl: controls the I2C gate. Newer drivers should use I2C * mux support instead.
@@ -321,10 +321,10 @@ struct dtv_frontend_properties;* struct dvb_frontend_ops - Demodulation information and callbacks for * ditialt TV * -* @info: embedded struct dvb_tuner_info with tuner properties +* @info: embedded &struct dvb_tuner_info with tuner properties * @delsys: Delivery systems supported by the frontend * @detach: callback function called when frontend is detached. -* drivers should clean up, but not yet free the struct +* drivers should clean up, but not yet free the &struct * dvb_frontend allocation. * @release: callback function called when frontend is ready to be * freed.
@@ -338,57 +338,57 @@ struct dtv_frontend_properties;* allow other drivers to write data into their registers. * Should not be used on new drivers. * @tune: callback function used by demod drivers that use -* @DVBFE_ALGO_HW; to tune into a frequency. +* @DVBFE_ALGO_HW to tune into a frequency. * @get_frontend_algo: returns the desired hardware algorithm. * @set_frontend: callback function used to inform the demod to set the * parameters for demodulating a digital TV channel. -* The properties to be used are stored at -* @dvb_frontend.dtv_property_cache;. The demod can change +* The properties to be used are stored at &struct +* dvb_frontend.dtv_property_cache. The demod can change * the parameters to reflect the changes needed for the * channel to be decoded, and update statistics. * @get_tune_settings: callback function * @get_frontend: callback function used to inform the parameters * actuall in use. The properties to be used are stored at -* @dvb_frontend.dtv_property_cache; and update +* &struct dvb_frontend.dtv_property_cache and update * statistics. Please notice that it should not return * an error code if the statistics are not available * because the demog is not locked. * @read_status: returns the locking status of the frontend. * @read_ber: legacy callback function to return the bit error rate. * Newer drivers should provide such info via DVBv5 API, -* e. g. @set_frontend;/@get_frontend;, implementing this +* e. g. @set_frontend;/@get_frontend, implementing this * callback only if DVBv3 API compatibility is wanted. * @read_signal_strength: legacy callback function to return the signal * strength. Newer drivers should provide such info via -* DVBv5 API, e. g. @set_frontend;/@get_frontend;, +* DVBv5 API, e. g. @set_frontend/@get_frontend, * implementing this callback only if DVBv3 API * compatibility is wanted. * @read_snr: legacy callback function to return the Signal/Noise * rate. Newer drivers should provide such info via -* DVBv5 API, e. g. @set_frontend;/@get_frontend;, +* DVBv5 API, e. g. @set_frontend/@get_frontend, * implementing this callback only if DVBv3 API * compatibility is wanted. * @read_ucblocks: legacy callback function to return the Uncorrected Error * Blocks. Newer drivers should provide such info via -* DVBv5 API, e. g. @set_frontend;/@get_frontend;, +* DVBv5 API, e. g. @set_frontend/@get_frontend, * implementing this callback only if DVBv3 API * compatibility is wanted. * @diseqc_reset_overload: callback function to implement the -* FE_DISEQC_RESET_OVERLOAD ioctl (only Satellite) +* FE_DISEQC_RESET_OVERLOAD() ioctl (only Satellite) * @diseqc_send_master_cmd: callback function to implement the -* FE_DISEQC_SEND_MASTER_CMD ioctl (only Satellite). +* FE_DISEQC_SEND_MASTER_CMD() ioctl (only Satellite). * @diseqc_recv_slave_reply: callback function to implement the -* FE_DISEQC_RECV_SLAVE_REPLY ioctl (only Satellite) +* FE_DISEQC_RECV_SLAVE_REPLY() ioctl (only Satellite) * @diseqc_send_burst: callback function to implement the -* FE_DISEQC_SEND_BURST ioctl (only Satellite). +* FE_DISEQC_SEND_BURST() ioctl (only Satellite). * @set_tone: callback function to implement the -* FE_SET_TONE ioctl (only Satellite). +* FE_SET_TONE() ioctl (only Satellite). * @set_voltage: callback function to implement the -* FE_SET_VOLTAGE ioctl (only Satellite). +* FE_SET_VOLTAGE() ioctl (only Satellite). * @enable_high_lnb_voltage: callback function to implement the -* FE_ENABLE_HIGH_LNB_VOLTAGE ioctl (only Satellite). +* FE_ENABLE_HIGH_LNB_VOLTAGE() ioctl (only Satellite). * @dishnetwork_send_legacy_command: callback function to implement the -* FE_DISHNETWORK_SEND_LEGACY_CMD ioctl (only Satellite). +* FE_DISHNETWORK_SEND_LEGACY_CMD() ioctl (only Satellite). * Drivers should not use this, except when the DVB * core emulation fails to provide proper support (e.g. * if @set_voltage takes more than 8ms to work), and
@@ -399,8 +399,8 @@ struct dtv_frontend_properties;* @ts_bus_ctrl: callback function used to take control of the TS bus. * @set_lna: callback function to power on/off/auto the LNA. * @search: callback function used on some custom algo search algos. -* @tuner_ops: pointer to struct dvb_tuner_ops -* @analog_ops: pointer to struct analog_demod_ops +* @tuner_ops: pointer to &struct dvb_tuner_ops +* @analog_ops: pointer to &struct analog_demod_ops */ struct dvb_frontend_ops {struct dvb_frontend_info info;
@@ -630,16 +630,16 @@ struct dtv_frontend_properties {/** * struct dvb_frontend - Frontend structure to be used on drivers. * -* @refcount: refcount to keep track of struct dvb_frontend +* @refcount: refcount to keep track of &struct dvb_frontend * references -* @ops: embedded struct dvb_frontend_ops -* @dvb: pointer to struct dvb_adapter +* @ops: embedded &struct dvb_frontend_ops +* @dvb: pointer to &struct dvb_adapter * @demodulator_priv: demod private data * @tuner_priv: tuner private data * @frontend_priv: frontend private data * @sec_priv: SEC private data * @analog_demod_priv: Analog demod private data -* @dtv_property_cache: embedded struct dtv_frontend_properties +* @dtv_property_cache: embedded &struct dtv_frontend_properties * @callback: callback function used on some drivers to call * either the tuner or the demodulator. * @id: Frontend ID
@@ -668,8 +668,8 @@ struct dvb_frontend {/** * dvb_register_frontend() - Registers a DVB frontend at the adapter * -* @dvb: pointer to the dvb adapter -* @fe: pointer to the frontend struct +* @dvb: pointer to &struct dvb_adapter +* @fe: pointer to &struct dvb_frontend * * Allocate and initialize the private data needed by the frontend core to * manage the frontend and calls dvb_register_device() to register a new
@@ -682,7 +682,7 @@ int dvb_register_frontend(struct dvb_adapter *dvb,/** * dvb_unregister_frontend() - Unregisters a DVB frontend * -* @fe: pointer to the frontend struct +* @fe: pointer to &struct dvb_frontend * * Stops the frontend kthread, calls dvb_unregister_device() and frees the * private frontend data allocated by dvb_register_frontend().
@@ -696,14 +696,14 @@ int dvb_unregister_frontend(struct dvb_frontend *fe);/** * dvb_frontend_detach() - Detaches and frees frontend specific data * -* @fe: pointer to the frontend struct +* @fe: pointer to &struct dvb_frontend * * This function should be called after dvb_unregister_frontend(). It * calls the SEC, tuner and demod release functions: * &dvb_frontend_ops.release_sec, &dvb_frontend_ops.tuner_ops.release, * &dvb_frontend_ops.analog_ops.release and &dvb_frontend_ops.release. * -* If the driver is compiled with CONFIG_MEDIA_ATTACH, it also decreases +* If the driver is compiled with %CONFIG_MEDIA_ATTACH, it also decreases * the module reference count, needed to allow userspace to remove the * previously used DVB frontend modules. */
@@ -712,7 +712,7 @@ void dvb_frontend_detach(struct dvb_frontend *fe);/** * dvb_frontend_suspend() - Suspends a Digital TV frontend * -* @fe: pointer to the frontend struct +* @fe: pointer to &struct dvb_frontend * * This function prepares a Digital TV frontend to suspend. *
@@ -730,7 +730,7 @@ int dvb_frontend_suspend(struct dvb_frontend *fe);/** * dvb_frontend_resume() - Resumes a Digital TV frontend * -* @fe: pointer to the frontend struct +* @fe: pointer to &struct dvb_frontend * * This function resumes the usual operation of the tuner after resume. *
@@ -751,7 +751,7 @@ int dvb_frontend_resume(struct dvb_frontend *fe);/** * dvb_frontend_reinitialise() - forces a reinitialisation at the frontend * -* @fe: pointer to the frontend struct +* @fe: pointer to &struct dvb_frontend * * Calls &dvb_frontend_ops.init\(\) and &dvb_frontend_ops.tuner_ops.init\(\), * and resets SEC tone and voltage (for Satellite systems).
@@ -766,16 +766,16 @@ void dvb_frontend_reinitialise(struct dvb_frontend *fe);* dvb_frontend_sleep_until() - Sleep for the amount of time given by * add_usec parameter * -* @waketime: pointer to a struct ktime_t +* @waketime: pointer to &struct ktime_t * @add_usec: time to sleep, in microseconds * * This function is used to measure the time required for the -* %FE_DISHNETWORK_SEND_LEGACY_CMD ioctl to work. It needs to be as precise +* FE_DISHNETWORK_SEND_LEGACY_CMD() ioctl to work. It needs to be as precise * as possible, as it affects the detection of the dish tone command at the * satellite subsystem. * * Its used internally by the DVB frontend core, in order to emulate -* %FE_DISHNETWORK_SEND_LEGACY_CMD using the &dvb_frontend_ops.set_voltage\(\) +* FE_DISHNETWORK_SEND_LEGACY_CMD() using the &dvb_frontend_ops.set_voltage\(\) * callback. * * NOTE: it should not be used at the drivers, as the emulation for the
Signature · 1 line
2.13.5
PATCH 6/25 media: dtv-core.rst: add chapters and introductory tests for common parts
In reply to Mauro Carvalho ChehabBetter document the DVB common parts by adding two sections and an introductory text for each.
--- Documentation/media/kapi/dtv-core.rst | 12 ++++++++++++ 1 file changed, 12 insertions(+)
Documentation/media/kapi/dtv-core.rst +12 -0
@@ -29,8 +29,20 @@ I2C bus. Digital TV Common functions --------------------------- +Math functions +~~~~~~~~~~~~~~ + +Provide some commonly-used math functions, usually required in order to +estimate signal strength and signal to noise measurements in dB. + .. kernel-doc:: drivers/media/dvb-core/dvb_math.h + +DVB devices +~~~~~~~~~~~ + +Those functions are responsible for handling the DVB device nodes. + .. kernel-doc:: drivers/media/dvb-core/dvbdev.h Digital TV Ring buffer
Signature · 1 line
2.13.5
PATCH 7/25 media: dtv-core.rst: split into multiple files
In reply to Mauro Carvalho ChehabInstead of document all kAPI into a single file, split it on multiple ones. That makes easier to maintain each part.
As a side effect, it will produce multiple html pages, with is a good idea.
No changes at the text. Just some chapter levels changed.
--- Documentation/media/kapi/dtv-ca.rst | 4 + Documentation/media/kapi/dtv-common.rst | 55 +++ Documentation/media/kapi/dtv-core.rst | 585 +----------------------------- Documentation/media/kapi/dtv-demux.rst | 71 ++++ Documentation/media/kapi/dtv-frontend.rst | 443 ++++++++++++++++++++++ 5 files changed, 579 insertions(+), 579 deletions(-) create mode 100644 Documentation/media/kapi/dtv-ca.rst create mode 100644 Documentation/media/kapi/dtv-common.rst create mode 100644 Documentation/media/kapi/dtv-demux.rst create mode 100644 Documentation/media/kapi/dtv-frontend.rst
Documentation/media/kapi/dtv-ca.rst new file +4 -0
@@ -0,0 +1,4 @@ +Digital TV Conditional Access kABI +---------------------------------- + +.. kernel-doc:: drivers/media/dvb-core/dvb_ca_en50221.h
Documentation/media/kapi/dtv-common.rst new file +55 -0
55 lines not on this page · raw message
Documentation/media/kapi/dtv-core.rst +6 -579
590 lines not on this page · raw message
Documentation/media/kapi/dtv-demux.rst new file +71 -0
71 lines not on this page · raw message
Documentation/media/kapi/dtv-frontend.rst new file +443 -0
443 lines not on this page · raw message
Signature · 1 line
2.13.5
PATCH 8/25 media: dtv-demux.rst: minor markup improvements
In reply to Mauro Carvalho ChehabAdd a cross-reference to a mentioned structure and split the kernel-doc stuff on a separate chapter.
--- Documentation/media/kapi/dtv-demux.rst | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-)
Documentation/media/kapi/dtv-demux.rst +6 -5
@@ -7,8 +7,8 @@ Digital TV Demux The Kernel Digital TV Demux kABI defines a driver-internal interface for registering low-level, hardware specific driver to a hardware independent demux layer. It is only of interest for Digital TV device driver writers. -The header file for this kABI is named demux.h and located in -drivers/media/dvb-core. +The header file for this kABI is named ``demux.h`` and located in +``drivers/media/dvb-core``. The demux kABI should be implemented for each demux in the system. It is used to select the TS source of a demux and to manage the demux resources.
@@ -27,7 +27,7 @@ tuning, are devined via the Digital TV Frontend kABI. The functions that implement the abstract interface demux should be defined static or module private and registered to the Demux core for external access. It is not necessary to implement every function in the struct -&dmx_demux. For example, a demux interface might support Section filtering, +:c:type:`dmx_demux`. For example, a demux interface might support Section filtering, but not PES filtering. The kABI client is expected to check the value of any function pointer before calling the function: the value of ``NULL`` means that the function is not available.
@@ -43,8 +43,6 @@ Linux Kernel calls the functions of a network device interface from a bottom half context. Thus, if a demux kABI function is called from network device code, the function must not sleep. - - Demux Callback API ~~~~~~~~~~~~~~~~~~
@@ -68,4 +66,7 @@ function call directly from a hardware interrupt. This mechanism is implemented by :c:func:`dmx_ts_cb()` and :c:func:`dmx_section_cb()` callbacks. +Digital TV Demux functions and types +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + .. kernel-doc:: drivers/media/dvb-core/demux.h
Signature · 1 line
2.13.5
PATCH 9/25 media: dvb_demux.h: add an enum for DMX_TYPE_* and document
In reply to Mauro Carvalho Chehabkernel-doc allows documenting enums. Also, it makes clearer about the meaning of each field on structures.
So, convert DMX_TYPE_* to an enum.
While here, get rid of the unused DMX_TYPE_PES.
--- drivers/media/dvb-core/dvb_demux.h | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-)
drivers/media/dvb-core/dvb_demux.h +12 -5
@@ -26,9 +26,16 @@#include "demux.h" -#define DMX_TYPE_TS 0 -#define DMX_TYPE_SEC 1 -#define DMX_TYPE_PES 2 +/** +* enum dvb_dmx_filter_type - type of demux feed. +* +* @DMX_TYPE_TS: feed is in TS mode. +* @DMX_TYPE_SEC: feed is in Section mode. +*/ +enum dvb_dmx_filter_type { +DMX_TYPE_TS , +DMX_TYPE_SEC , +};#define DMX_STATE_FREE 0#define DMX_STATE_ALLOCATED 1
@@ -52,7 +59,7 @@ struct dvb_demux_filter {struct dvb_demux_feed *feed;int index;int state; -int type; +enum dvb_dmx_filter_type type;u16 hw_handle;struct timer_list timer;
@@ -73,7 +80,7 @@ struct dvb_demux_feed {struct dvb_demux *demux;void *priv; -int type; +enum dvb_dmx_filter_type type;int state;u16 pid;
Signature · 1 line
2.13.5
PATCH 10/25 media: dvb_demux.h: add an enum for DMX_STATE_* and document
In reply to Mauro Carvalho Chehabkernel-doc allows documenting enums. Also, it makes clearer about the meaning of each field on structures.
So, convert DMX_STATE_* to an enum.
While here, get rid of the unused DMX_STATE_SET.
--- drivers/media/dvb-core/dvb_demux.h | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-)
drivers/media/dvb-core/dvb_demux.h +18 -7
@@ -37,11 +37,22 @@ enum dvb_dmx_filter_type { DMX_TYPE_SEC, }; -#define DMX_STATE_FREE 0 -#define DMX_STATE_ALLOCATED 1 -#define DMX_STATE_SET 2 -#define DMX_STATE_READY 3 -#define DMX_STATE_GO 4 +/** +* enum dvb_dmx_state - state machine for a demux filter. +* +* @DMX_STATE_FREE: indicates that the filter is freed. +* @DMX_STATE_ALLOCATED: indicates that the filter was allocated +* to be used. +* @DMX_STATE_READY: indicates that the filter is ready +* to be used. +* @DMX_STATE_GO: indicates that the filter is running. +*/ +enum dvb_dmx_state { +DMX_STATE_FREE , +DMX_STATE_ALLOCATED , +DMX_STATE_READY , +DMX_STATE_GO , +};#define DVB_DEMUX_MASK_MAX 18
@@ -58,7 +69,7 @@ struct dvb_demux_filter {struct dvb_demux_filter *next;struct dvb_demux_feed *feed;int index; -int state; +enum dvb_dmx_state state;enum dvb_dmx_filter_type type;u16 hw_handle;
@@ -81,7 +92,7 @@ struct dvb_demux_feed {struct dvb_demux *demux;void *priv;enum dvb_dmx_filter_type type; -int state; +enum dvb_dmx_state state;u16 pid;ktime_t timeout;
Signature · 1 line
2.13.5
PATCH 11/25 media: dvb_demux.h: get rid of unused timer at struct dvb_demux_filter
In reply to Mauro Carvalho ChehabThis field is not used. So, get rid of it.
--- drivers/media/dvb-core/dvb_demux.h | 1 - 1 file changed, 1 deletion(-)
drivers/media/dvb-core/dvb_demux.h +0 -1
@@ -73,7 +73,6 @@ struct dvb_demux_filter {enum dvb_dmx_filter_type type;u16 hw_handle; -struct timer_list timer; };#define DMX_FEED_ENTRY (pos) list_entry(pos, struct dvb_demux_feed, list_head)
Signature · 1 line
2.13.5
PATCH 12/25 media: dvb_demux: mark a boolean field as such
In reply to Mauro Carvalho ChehabThe struct dvb_demux_filter.doneq is a boolean.
Mark it as such, as it helps to understand what it does.
--- drivers/media/dvb-core/dvb_demux.c | 4 ++-- drivers/media/dvb-core/dvb_demux.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-)
drivers/media/dvb-core/dvb_demux.c +2 -2
@@ -898,14 +898,14 @@ static void prepare_secfilters(struct dvb_demux_feed *dvbdmxfeed)return ;do { sf = &f->filter; - doneq =0 ; + doneq = false;for (i =0 ; i <DVB_DEMUX_MASK_MAX ; i++) { mode = sf->filter_mode[i]; mask = sf->filter_mask[i]; f->maskandmode[i] = mask & mode; doneq |= f->maskandnotmode[i] = mask & ~mode; } - f->doneq = doneq ?1 :0 ; + f->doneq = doneq ? true : false; }while ((f = f->next)); }
drivers/media/dvb-core/dvb_demux.h +1 -1
@@ -64,7 +64,7 @@ struct dvb_demux_filter {struct dmx_section_filter filter;u8 maskandmode[DMX_MAX_FILTER_SIZE ];u8 maskandnotmode[DMX_MAX_FILTER_SIZE ]; -int doneq; +bool doneq;struct dvb_demux_filter *next;struct dvb_demux_feed *feed;
Signature · 1 line
2.13.5
PATCH 13/25 media: dvb_demux: dvb_demux_feed.pusi_seen is boolean
In reply to Mauro Carvalho ChehabInstead of using an integer to represent it, use boolean, as this better describes what this field really means.
--- drivers/media/dvb-core/dvb_demux.c | 12 ++++++------ drivers/media/dvb-core/dvb_demux.h | 2 +- drivers/media/pci/ttpci/av7110.c | 2 +- drivers/media/pci/ttpci/budget-core.c | 2 +- 4 files changed, 9 insertions(+), 9 deletions(-)
drivers/media/dvb-core/dvb_demux.c +6 -6
@@ -223,10 +223,10 @@ static void dvb_dmx_swfilter_section_new(struct dvb_demux_feed *feed)* when the second packet arrives. * * Fix: -* when demux is started, let feed->pusi_seen = 0 to +* when demux is started, let feed->pusi_seen = false to * prevent initial feeding of garbage from the end of * previous section. When you for the first time see PUSI=1 -* then set feed->pusi_seen = 1 +* then set feed->pusi_seen = true */ static int dvb_dmx_swfilter_section_copy_dump (struct dvb_demux_feed *feed,const u8 *buf,u8 len)
@@ -318,10 +318,10 @@ static int dvb_dmx_swfilter_section_packet(struct dvb_demux_feed *feed,*/ #endif /* -* Discontinuity detected. Reset pusi_seen = 0 to +* Discontinuity detected. Reset pusi_seen to * stop feeding of suspicious data until next PUSI=1 arrives */ - feed->pusi_seen =0 ; + feed->pusi_seen = false;dvb_dmx_swfilter_section_new (feed); }
@@ -335,8 +335,8 @@ static int dvb_dmx_swfilter_section_packet(struct dvb_demux_feed *feed,dvb_dmx_swfilter_section_copy_dump (feed, before, before_len); -/* before start of new section, set pusi_seen = 1 */ - feed->pusi_seen =1 ; +/* before start of new section, set pusi_seen */ + feed->pusi_seen = true;dvb_dmx_swfilter_section_new (feed);dvb_dmx_swfilter_section_copy_dump (feed, after, after_len);
drivers/media/dvb-core/dvb_demux.h +1 -1
@@ -101,7 +101,7 @@ struct dvb_demux_feed {enum dmx_ts_pes pes_type;int cc; -int pusi_seen;/* prevents feeding of garbage from previous section */ +bool pusi_seen;/* prevents feeding of garbage from previous section */ u16 peslen;
drivers/media/pci/ttpci/av7110.c +1 -1
@@ -1224,7 +1224,7 @@ static int budget_start_feed(struct dvb_demux_feed *feed)dprintk (2 ,"av7110: %p\n" , budget);spin_lock (&budget->feedlock1); - feed->pusi_seen =0 ;/* have a clean section start */ + feed->pusi_seen = false;/* have a clean section start */ status =start_ts_capture (budget);spin_unlock (&budget->feedlock1);return status;
drivers/media/pci/ttpci/budget-core.c +1 -1
@@ -330,7 +330,7 @@ static int budget_start_feed(struct dvb_demux_feed *feed)return -EINVAL ;spin_lock (&budget->feedlock); - feed->pusi_seen =0 ;/* have a clean section start */ + feed->pusi_seen = false;/* have a clean section start */ if (budget->feeding++ ==0 ) status =start_ts_capture (budget);spin_unlock (&budget->feedlock);
Signature · 1 line
2.13.5
PATCH 14/25 media: dvb_demux.h: get rid of DMX_FEED_ENTRY() macro
In reply to Mauro Carvalho ChehabThis isn't used anywere. Get rid of it.
--- drivers/media/dvb-core/dvb_demux.h | 2 -- 1 file changed, 2 deletions(-)
drivers/media/dvb-core/dvb_demux.h +0 -2
@@ -75,8 +75,6 @@ struct dvb_demux_filter {u16 hw_handle; }; -#define DMX_FEED_ENTRY (pos) list_entry(pos, struct dvb_demux_feed, list_head) - struct dvb_demux_feed { union { struct dmx_ts_feed ts;
Signature · 1 line
2.13.5
PATCH 15/25 media: dvb_demux: fix type of dvb_demux_feed.ts_type
In reply to Mauro Carvalho ChehabJust like pes_type, this field represents an enum. Properly identify it as such.
--- drivers/media/dvb-core/dvb_demux.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/media/dvb-core/dvb_demux.h +1 -1
@@ -95,7 +95,7 @@ struct dvb_demux_feed {ktime_t timeout;struct dvb_demux_filter *filter; -int ts_type; +enum ts_filter_type ts_type;enum dmx_ts_pes pes_type;int cc;
Signature · 1 line
2.13.5
PATCH 16/25 media: dvb_demux: document dvb_demux_filter and dvb_demux_feed
In reply to Mauro Carvalho ChehabDocument those two structs using kernel-doc markups.
--- drivers/media/dvb-core/dvb_demux.h | 49 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 47 insertions(+), 2 deletions(-)
drivers/media/dvb-core/dvb_demux.h +47 -2
@@ -60,6 +60,21 @@ enum dvb_dmx_state {#define SPEED_PKTS_INTERVAL 50000 +/** +* struct dvb_demux_filter - Describes a DVB demux section filter. +* +* @filter: Section filter as defined by &struct dmx_section_filter. +* @maskandmode: logical ``and`` bit mask. +* @maskandnotmode: logical ``and not`` bit mask. +* @doneq: flag that indicates when a filter is ready. +* @next: pointer to the next section filter. +* @feed: &struct dvb_demux_feed pointer. +* @index: index of the used demux filter. +* @state: state of the filter as described by &enum dvb_dmx_state. +* @type: type of the filter as described +* by &enum dvb_dmx_filter_type. +*/ +struct dvb_demux_filter {struct dmx_section_filter filter;u8 maskandmode[DMX_MAX_FILTER_SIZE ];
@@ -72,9 +87,39 @@ struct dvb_demux_filter {enum dvb_dmx_state state;enum dvb_dmx_filter_type type; +/* private: used only by av7110 */ u16 hw_handle; }; +/** +* struct dvb_demux_feed - describes a DVB field +* +* @feed: a digital TV feed. It can either be a TS or a section feed: +* - if the feed is TS, it contains &struct dvb_ts_feed; +* - if the feed is section, it contains +* &struct dmx_section_feed. +* @cb: digital TV callbacks. depending on the feed type, it can be: +* - if the feed is TS, it contains a dmx_ts_cb() callback; +* - if the feed is section, it contains a dmx_section_cb() callback. +* +* @demux: pointer to &struct dvb_demux. +* @priv: private data for the filter handling routine. +* @type: type of the filter, as defined by &enum dvb_dmx_filter_type. +* @state: state of the filter as defined by &enum dvb_dmx_state. +* @pid: PID to be filtered. +* @timeout: feed timeout. +* @filter: pointer to &struct dvb_demux_filter. +* @ts_type: type of TS, as defined by &enum ts_filter_type. +* @pes_type: type of PES, as defined by &enum dmx_ts_pes. +* @cc: MPEG-TS packet continuity counter +* @pusi_seen: if true, indicates that a discontinuity was detected. +* it is used to prevent feeding of garbage from previous section. +* @peslen: length of the PES (Packet Elementary Stream). +* @list_head: head for the list of digital TV demux feeds. +* @index: a unique index for each feed. Can be used as hardware +* pid filter index. +* +*/ struct dvb_demux_feed { union { struct dmx_ts_feed ts;
@@ -99,12 +144,12 @@ struct dvb_demux_feed {enum dmx_ts_pes pes_type;int cc; -bool pusi_seen;/* prevents feeding of garbage from previous section */ +bool pusi_seen;u16 peslen;struct list_head list_head; -unsigned int index;/* a unique index for each feed (can be used as hardware pid filter index) */ +unsigned int index; };struct dvb_demux {
Signature · 1 line
2.13.5
PATCH 17/25 media: dvb_frontend: dtv_property_process_set() cleanups
In reply to Mauro Carvalho ChehabFrom: Satendra Singh Thakur <[email protected]>
Since all properties in the func dtv_property_process_set() use at most 4 bytes arguments, change the code to pass
u32 cmd and u32 data as function arguments, instead of passing a pointer to the entire struct dtv_property *tvp.
Instead of having a generic dtv_property_dump(), added its own properties debug logic at dtv_property_process_set().
--- drivers/media/dvb-core/dvb_frontend.c | 125 ++++++++++++++++++++-------------- 1 file changed, 72 insertions(+), 53 deletions(-)
drivers/media/dvb-core/dvb_frontend.c +72 -53
@@ -1107,22 +1107,19 @@ static struct dtv_cmds_h dtv_cmds[DTV_MAX_COMMAND + 1] = { _DTV_CMD(DTV_STAT_TOTAL_BLOCK_COUNT, 0, 0), }; -static void dtv_property_dump (struct dvb_frontend *fe, -bool is_set, +static void dtv_get_property_dump (struct dvb_frontend *fe,struct dtv_property *tvp) {int i;if (tvp->cmd <=0 || tvp->cmd >DTV_MAX_COMMAND ) { -dev_warn (fe->dvb->device,"%s: %s tvp.cmd = 0x%08x undefined\n" , - __func__, - is_set ?"SET" :"GET" , +dev_warn (fe->dvb->device,"%s: GET tvp.cmd = 0x%08x undefined\n" + , __func__, tvp->cmd);return ; } -dev_dbg (fe->dvb->device,"%s: %s tvp.cmd = 0x%08x (%s)\n" , __func__, - is_set ?"SET" :"GET" , +dev_dbg (fe->dvb->device,"%s: GET tvp.cmd = 0x%08x (%s)\n" , __func__, tvp->cmd, dtv_cmds[tvp->cmd].name);
@@ -1532,7 +1529,7 @@ static int dtv_property_process_get(struct dvb_frontend *fe,return -EINVAL ; } -dtv_property_dump (fe, false, tvp); +dtv_get_property_dump (fe, tvp);return 0 ; }
@@ -1755,16 +1752,36 @@ static int dvbv3_set_delivery_system(struct dvb_frontend *fe)return emulate_delivery_system (fe, delsys); } +/** +* dtv_property_process_set - Sets a single DTV property +* @fe: Pointer to &struct dvb_frontend +* @file: Pointer to &struct file +* @cmd: Digital TV command +* @data: An unsigned 32-bits number +* +* This routine assigns the property +* value to the corresponding member of +* &struct dtv_frontend_properties +* +* Returns: +* Zero on success, negative errno on failure. +*/ static int dtv_property_process_set (struct dvb_frontend *fe, -struct dtv_property *tvp, -struct file *file) +struct file *file, +u32 cmd,u32 data) {int r =0 ;struct dtv_frontend_properties *c = &fe->dtv_property_cache; -dtv_property_dump (fe, true, tvp); - -switch (tvp->cmd) { +/** Dump DTV command name and value*/ +if (!cmd || cmd >DTV_MAX_COMMAND ) +dev_warn (fe->dvb->device,"%s: SET cmd 0x%08x undefined\n" , + __func__, cmd); +else +dev_dbg (fe->dvb->device, +"%s: SET cmd 0x%08x (%s) to 0x%08x\n" , + __func__, cmd, dtv_cmds[cmd].name, data); +switch (cmd) {case DTV_CLEAR :/* * Reset a cache of data specific to the frontend here. This does
@@ -1784,133 +1801,133 @@ static int dtv_property_process_set(struct dvb_frontend *fe, r =dtv_set_frontend (fe);break ;case DTV_FREQUENCY : - c->frequency = tvp->u.data; + c->frequency = data;break ;case DTV_MODULATION : - c->modulation = tvp->u.data; + c->modulation = data;break ;case DTV_BANDWIDTH_HZ : - c->bandwidth_hz = tvp->u.data; + c->bandwidth_hz = data;break ;case DTV_INVERSION : - c->inversion = tvp->u.data; + c->inversion = data;break ;case DTV_SYMBOL_RATE : - c->symbol_rate = tvp->u.data; + c->symbol_rate = data;break ;case DTV_INNER_FEC : - c->fec_inner = tvp->u.data; + c->fec_inner = data;break ;case DTV_PILOT : - c->pilot = tvp->u.data; + c->pilot = data;break ;case DTV_ROLLOFF : - c->rolloff = tvp->u.data; + c->rolloff = data;break ;case DTV_DELIVERY_SYSTEM : - r =dvbv5_set_delivery_system (fe, tvp->u.data); + r =dvbv5_set_delivery_system (fe, data);break ;case DTV_VOLTAGE : - c->voltage = tvp->u.data; + c->voltage = data; r =dvb_frontend_handle_ioctl (file,FE_SET_VOLTAGE , (void *)c->voltage);break ;case DTV_TONE : - c->sectone = tvp->u.data; + c->sectone = data; r =dvb_frontend_handle_ioctl (file,FE_SET_TONE , (void *)c->sectone);break ;case DTV_CODE_RATE_HP : - c->code_rate_HP = tvp->u.data; + c->code_rate_HP = data;break ;case DTV_CODE_RATE_LP : - c->code_rate_LP = tvp->u.data; + c->code_rate_LP = data;break ;case DTV_GUARD_INTERVAL : - c->guard_interval = tvp->u.data; + c->guard_interval = data;break ;case DTV_TRANSMISSION_MODE : - c->transmission_mode = tvp->u.data; + c->transmission_mode = data;break ;case DTV_HIERARCHY : - c->hierarchy = tvp->u.data; + c->hierarchy = data;break ;case DTV_INTERLEAVING : - c->interleaving = tvp->u.data; + c->interleaving = data;break ;/* ISDB-T Support here */ case DTV_ISDBT_PARTIAL_RECEPTION : - c->isdbt_partial_reception = tvp->u.data; + c->isdbt_partial_reception = data;break ;case DTV_ISDBT_SOUND_BROADCASTING : - c->isdbt_sb_mode = tvp->u.data; + c->isdbt_sb_mode = data;break ;case DTV_ISDBT_SB_SUBCHANNEL_ID : - c->isdbt_sb_subchannel = tvp->u.data; + c->isdbt_sb_subchannel = data;break ;case DTV_ISDBT_SB_SEGMENT_IDX : - c->isdbt_sb_segment_idx = tvp->u.data; + c->isdbt_sb_segment_idx = data;break ;case DTV_ISDBT_SB_SEGMENT_COUNT : - c->isdbt_sb_segment_count = tvp->u.data; + c->isdbt_sb_segment_count = data;break ;case DTV_ISDBT_LAYER_ENABLED : - c->isdbt_layer_enabled = tvp->u.data; + c->isdbt_layer_enabled = data;break ;case DTV_ISDBT_LAYERA_FEC : - c->layer[0 ].fec = tvp->u.data; + c->layer[0 ].fec = data;break ;case DTV_ISDBT_LAYERA_MODULATION : - c->layer[0 ].modulation = tvp->u.data; + c->layer[0 ].modulation = data;break ;case DTV_ISDBT_LAYERA_SEGMENT_COUNT : - c->layer[0 ].segment_count = tvp->u.data; + c->layer[0 ].segment_count = data;break ;case DTV_ISDBT_LAYERA_TIME_INTERLEAVING : - c->layer[0 ].interleaving = tvp->u.data; + c->layer[0 ].interleaving = data;break ;case DTV_ISDBT_LAYERB_FEC : - c->layer[1 ].fec = tvp->u.data; + c->layer[1 ].fec = data;break ;case DTV_ISDBT_LAYERB_MODULATION : - c->layer[1 ].modulation = tvp->u.data; + c->layer[1 ].modulation = data;break ;case DTV_ISDBT_LAYERB_SEGMENT_COUNT : - c->layer[1 ].segment_count = tvp->u.data; + c->layer[1 ].segment_count = data;break ;case DTV_ISDBT_LAYERB_TIME_INTERLEAVING : - c->layer[1 ].interleaving = tvp->u.data; + c->layer[1 ].interleaving = data;break ;case DTV_ISDBT_LAYERC_FEC : - c->layer[2 ].fec = tvp->u.data; + c->layer[2 ].fec = data;break ;case DTV_ISDBT_LAYERC_MODULATION : - c->layer[2 ].modulation = tvp->u.data; + c->layer[2 ].modulation = data;break ;case DTV_ISDBT_LAYERC_SEGMENT_COUNT : - c->layer[2 ].segment_count = tvp->u.data; + c->layer[2 ].segment_count = data;break ;case DTV_ISDBT_LAYERC_TIME_INTERLEAVING : - c->layer[2 ].interleaving = tvp->u.data; + c->layer[2 ].interleaving = data;break ;/* Multistream support */ case DTV_STREAM_ID :case DTV_DVBT2_PLP_ID_LEGACY : - c->stream_id = tvp->u.data; + c->stream_id = data;break ;/* ATSC-MH */ case DTV_ATSCMH_PARADE_ID : - fe->dtv_property_cache.atscmh_parade_id = tvp->u.data; + fe->dtv_property_cache.atscmh_parade_id = data;break ;case DTV_ATSCMH_RS_FRAME_ENSEMBLE : - fe->dtv_property_cache.atscmh_rs_frame_ensemble = tvp->u.data; + fe->dtv_property_cache.atscmh_rs_frame_ensemble = data;break ;case DTV_LNA : - c->lna = tvp->u.data; + c->lna = data;if (fe->ops.set_lna) r = fe->ops.set_lna (fe);if (r <0 )
@@ -2137,7 +2154,9 @@ static int dvb_frontend_handle_ioctl(struct file *file,return PTR_ERR (tvp);for (i =0 ; i < tvps->num; i++) { - err =dtv_property_process_set (fe, tvp + i, file); + err =dtv_property_process_set (fe, file, + (tvp + i)->cmd, + (tvp + i)->u.data);if (err <0 ) {kfree (tvp);return err;
Signature · 1 line
2.13.5
Re: [PATCH 17/25] media: dvb_frontend: dtv_property_process_set() cleanups
Quoted 9 lines · Mauro Carvalho Chehab
From: Satendra Singh Thakur <[email protected]>
Since all properties in the func
dtv_property_process_set()use at most 4 bytes arguments, change the code to pass
u32 cmd and u32 data as function arguments, instead of passing a pointer to the entire structdtv_property*tvp.Instead of having a generic
dtv_property_dump(), added its own properties debug logic atdtv_property_process_set().
Nit: in the dtv_property_process_set()
Quoted 48 lines
Signed-off-by Satendra Singh Thakur <[email protected]>Signed-off-by Mauro Carvalho Chehab <[email protected]>--- drivers/media/dvb-core/dvb_frontend.c | 125 ++++++++++++++++++++-------------- 1 file changed, 72 insertions(+), 53 deletions(-)drivers/media/dvb-core/dvb_frontend.c +5
-8@@ -1107,22 +1107,19 @@ static struct dtv_cmds_h dtv_cmds[DTV_MAX_COMMAND + 1] = { _DTV_CMD(DTV_STAT_TOTAL_BLOCK_COUNT, 0, 0), }; -static void dtv_property_dump (struct dvb_frontend *fe, -bool is_set, +static void dtv_get_property_dump (struct dvb_frontend *fe,struct dtv_property *tvp) {int i;if (tvp->cmd <=0 || tvp->cmd >DTV_MAX_COMMAND ) { -dev_warn (fe->dvb->device,"%s: %s tvp.cmd = 0x%08x undefined\n" , - __func__, - is_set ?"SET" :"GET" , +dev_warn (fe->dvb->device,"%s: GET tvp.cmd = 0x%08x undefined\n" + , __func__, tvp->cmd);return ; } -dev_dbg (fe->dvb->device,"%s: %s tvp.cmd = 0x%08x (%s)\n" , __func__, - is_set ?"SET" :"GET" , +dev_dbg (fe->dvb->device,"%s: GET tvp.cmd = 0x%08x (%s)\n" , __func__, tvp->cmd, dtv_cmds[tvp->cmd].name);@@ -1532,7 +1529,7 @@ static int dtv_property_process_get(struct dvb_frontend *fe,return -EINVAL ; } -dtv_property_dump (fe, false, tvp); +dtv_get_property_dump (fe, tvp);return 0 ; }
drivers/media/dvb-core/dvb_frontend.c static int dvbv3_set_delivery_system(struct dvb_frontend *fe) · line 1757
Quoted 6 lines
drivers/media/dvb-core/dvb_frontend.c +3
-0@@ -1755,16 +1752,36 @@ static int dvbv3_set_delivery_system(struct dvb_frontend *fe)return emulate_delivery_system (fe, delsys); } +/** +* dtv_property_process_set - Sets a single DTV property +* @fe: Pointer to &struct dvb_frontend
Nit: extra tab looks like:
Quoted 11 lines
drivers/media/dvb-core/dvb_frontend.c +11
-0+* @file: Pointer to &struct file +* @cmd: Digital TV command +* @data: An unsigned 32-bits number +* +* This routine assigns the property +* value to the corresponding member of +* &struct dtv_frontend_properties +* +* Returns: +* Zero on success, negative errno on failure. +*/
drivers/media/dvb-core/dvb_frontend.c static int dvbv3_set_delivery_system(struct dvb_frontend *fe) · line 1765
Quoted 10 lines
drivers/media/dvb-core/dvb_frontend.c +2
-3static int dtv_property_process_set (struct dvb_frontend *fe, -struct dtv_property *tvp, -struct file *file) +struct file *file, +u32 cmd,u32 data) {int r =0 ;struct dtv_frontend_properties *c = &fe->dtv_property_cache; -dtv_property_dump (fe, true, tvp);
Why not keep dtv_property_dump() the way it is? I am not seeing the value of this change.
drivers/media/dvb-core/dvb_frontend.c static int dvbv3_set_delivery_system(struct dvb_frontend *fe) · line 1783
Quoted 10 lines
drivers/media/dvb-core/dvb_frontend.c +8
-2- -switch (tvp->cmd) { +/** Dump DTV command name and value*/ +if (!cmd || cmd >DTV_MAX_COMMAND ) +dev_warn (fe->dvb->device,"%s: SET cmd 0x%08x undefined\n" , + __func__, cmd); +else +dev_dbg (fe->dvb->device, +"%s: SET cmd 0x%08x (%s) to 0x%08x\n" , + __func__, cmd, dtv_cmds[cmd].name, data);
The code looked simpler before this change? Why add almost identical duplicate code here?
Quoted 179 lines
drivers/media/dvb-core/dvb_frontend.c +40
-39+switch (cmd) {case DTV_CLEAR :/* * Reset a cache of data specific to the frontend here. This does @@ -1784,133 +1801,133 @@ static int dtv_property_process_set(struct dvb_frontend *fe, r =dtv_set_frontend (fe);break ;case DTV_FREQUENCY : - c->frequency = tvp->u.data; + c->frequency = data;break ;case DTV_MODULATION : - c->modulation = tvp->u.data; + c->modulation = data;break ;case DTV_BANDWIDTH_HZ : - c->bandwidth_hz = tvp->u.data; + c->bandwidth_hz = data;break ;case DTV_INVERSION : - c->inversion = tvp->u.data; + c->inversion = data;break ;case DTV_SYMBOL_RATE : - c->symbol_rate = tvp->u.data; + c->symbol_rate = data;break ;case DTV_INNER_FEC : - c->fec_inner = tvp->u.data; + c->fec_inner = data;break ;case DTV_PILOT : - c->pilot = tvp->u.data; + c->pilot = data;break ;case DTV_ROLLOFF : - c->rolloff = tvp->u.data; + c->rolloff = data;break ;case DTV_DELIVERY_SYSTEM : - r =dvbv5_set_delivery_system (fe, tvp->u.data); + r =dvbv5_set_delivery_system (fe, data);break ;case DTV_VOLTAGE : - c->voltage = tvp->u.data; + c->voltage = data; r =dvb_frontend_handle_ioctl (file,FE_SET_VOLTAGE , (void *)c->voltage);break ;case DTV_TONE : - c->sectone = tvp->u.data; + c->sectone = data; r =dvb_frontend_handle_ioctl (file,FE_SET_TONE , (void *)c->sectone);break ;case DTV_CODE_RATE_HP : - c->code_rate_HP = tvp->u.data; + c->code_rate_HP = data;break ;case DTV_CODE_RATE_LP : - c->code_rate_LP = tvp->u.data; + c->code_rate_LP = data;break ;case DTV_GUARD_INTERVAL : - c->guard_interval = tvp->u.data; + c->guard_interval = data;break ;case DTV_TRANSMISSION_MODE : - c->transmission_mode = tvp->u.data; + c->transmission_mode = data;break ;case DTV_HIERARCHY : - c->hierarchy = tvp->u.data; + c->hierarchy = data;break ;case DTV_INTERLEAVING : - c->interleaving = tvp->u.data; + c->interleaving = data;break ;/* ISDB-T Support here */ case DTV_ISDBT_PARTIAL_RECEPTION : - c->isdbt_partial_reception = tvp->u.data; + c->isdbt_partial_reception = data;break ;case DTV_ISDBT_SOUND_BROADCASTING : - c->isdbt_sb_mode = tvp->u.data; + c->isdbt_sb_mode = data;break ;case DTV_ISDBT_SB_SUBCHANNEL_ID : - c->isdbt_sb_subchannel = tvp->u.data; + c->isdbt_sb_subchannel = data;break ;case DTV_ISDBT_SB_SEGMENT_IDX : - c->isdbt_sb_segment_idx = tvp->u.data; + c->isdbt_sb_segment_idx = data;break ;case DTV_ISDBT_SB_SEGMENT_COUNT : - c->isdbt_sb_segment_count = tvp->u.data; + c->isdbt_sb_segment_count = data;break ;case DTV_ISDBT_LAYER_ENABLED : - c->isdbt_layer_enabled = tvp->u.data; + c->isdbt_layer_enabled = data;break ;case DTV_ISDBT_LAYERA_FEC : - c->layer[0 ].fec = tvp->u.data; + c->layer[0 ].fec = data;break ;case DTV_ISDBT_LAYERA_MODULATION : - c->layer[0 ].modulation = tvp->u.data; + c->layer[0 ].modulation = data;break ;case DTV_ISDBT_LAYERA_SEGMENT_COUNT : - c->layer[0 ].segment_count = tvp->u.data; + c->layer[0 ].segment_count = data;break ;case DTV_ISDBT_LAYERA_TIME_INTERLEAVING : - c->layer[0 ].interleaving = tvp->u.data; + c->layer[0 ].interleaving = data;break ;case DTV_ISDBT_LAYERB_FEC : - c->layer[1 ].fec = tvp->u.data; + c->layer[1 ].fec = data;break ;case DTV_ISDBT_LAYERB_MODULATION : - c->layer[1 ].modulation = tvp->u.data; + c->layer[1 ].modulation = data;break ;case DTV_ISDBT_LAYERB_SEGMENT_COUNT : - c->layer[1 ].segment_count = tvp->u.data; + c->layer[1 ].segment_count = data;break ;case DTV_ISDBT_LAYERB_TIME_INTERLEAVING : - c->layer[1 ].interleaving = tvp->u.data; + c->layer[1 ].interleaving = data;break ;case DTV_ISDBT_LAYERC_FEC : - c->layer[2 ].fec = tvp->u.data; + c->layer[2 ].fec = data;break ;case DTV_ISDBT_LAYERC_MODULATION : - c->layer[2 ].modulation = tvp->u.data; + c->layer[2 ].modulation = data;break ;case DTV_ISDBT_LAYERC_SEGMENT_COUNT : - c->layer[2 ].segment_count = tvp->u.data; + c->layer[2 ].segment_count = data;break ;case DTV_ISDBT_LAYERC_TIME_INTERLEAVING : - c->layer[2 ].interleaving = tvp->u.data; + c->layer[2 ].interleaving = data;break ;/* Multistream support */ case DTV_STREAM_ID :case DTV_DVBT2_PLP_ID_LEGACY : - c->stream_id = tvp->u.data; + c->stream_id = data;break ;/* ATSC-MH */ case DTV_ATSCMH_PARADE_ID : - fe->dtv_property_cache.atscmh_parade_id = tvp->u.data; + fe->dtv_property_cache.atscmh_parade_id = data;break ;case DTV_ATSCMH_RS_FRAME_ENSEMBLE : - fe->dtv_property_cache.atscmh_rs_frame_ensemble = tvp->u.data; + fe->dtv_property_cache.atscmh_rs_frame_ensemble = data;break ;case DTV_LNA : - c->lna = tvp->u.data; + c->lna = data;if (fe->ops.set_lna) r = fe->ops.set_lna (fe);if (r <0 )
drivers/media/dvb-core/dvb_frontend.c static int dvb_frontend_handle_ioctl(struct file *file, · line 2162
Quoted 10 lines
drivers/media/dvb-core/dvb_frontend.c +3
-1@@ -2137,7 +2154,9 @@ static int dvb_frontend_handle_ioctl(struct file *file,return PTR_ERR (tvp);for (i =0 ; i < tvps->num; i++) { - err =dtv_property_process_set (fe, tvp + i, file); + err =dtv_property_process_set (fe, file, + (tvp + i)->cmd, + (tvp + i)->u.data);if (err <0 ) {kfree (tvp);return err;
The rest looks good. Once the other comments are addressed and/or explained.
thanks,
-- Shuah
Re: [PATCH 17/25] media: dvb_frontend: dtv_property_process_set() cleanups
Em Thu, 21 Sep 2017 08:32:25 -0600
Shuah Khan <[email protected]> escreveu:
Quoted 90 lines · Mauro Carvalho Chehab
Quoted 9 lines
From: Satendra Singh Thakur <[email protected]>
Since all properties in the func
dtv_property_process_set()use at most 4 bytes arguments, change the code to pass
u32 cmd and u32 data as function arguments, instead of passing a pointer to the entire structdtv_property*tvp.Instead of having a generic
dtv_property_dump(), added its own properties debug logic atdtv_property_process_set().Nit: in the
dtv_property_process_set()Quoted 48 lines
Signed-off-by Satendra Singh Thakur <[email protected]>Signed-off-by Mauro Carvalho Chehab <[email protected]>--- drivers/media/dvb-core/dvb_frontend.c | 125 ++++++++++++++++++++-------------- 1 file changed, 72 insertions(+), 53 deletions(-)drivers/media/dvb-core/dvb_frontend.c +5
-8@@ -1107,22 +1107,19 @@ static struct dtv_cmds_h dtv_cmds[DTV_MAX_COMMAND + 1] = { _DTV_CMD(DTV_STAT_TOTAL_BLOCK_COUNT, 0, 0), }; -static void dtv_property_dump (struct dvb_frontend *fe, -bool is_set, +static void dtv_get_property_dump (struct dvb_frontend *fe,struct dtv_property *tvp) {int i;if (tvp->cmd <=0 || tvp->cmd >DTV_MAX_COMMAND ) { -dev_warn (fe->dvb->device,"%s: %s tvp.cmd = 0x%08x undefined\n" , - __func__, - is_set ?"SET" :"GET" , +dev_warn (fe->dvb->device,"%s: GET tvp.cmd = 0x%08x undefined\n" + , __func__, tvp->cmd);return ; } -dev_dbg (fe->dvb->device,"%s: %s tvp.cmd = 0x%08x (%s)\n" , __func__, - is_set ?"SET" :"GET" , +dev_dbg (fe->dvb->device,"%s: GET tvp.cmd = 0x%08x (%s)\n" , __func__, tvp->cmd, dtv_cmds[tvp->cmd].name);@@ -1532,7 +1529,7 @@ static int dtv_property_process_get(struct dvb_frontend *fe,return -EINVAL ; } -dtv_property_dump (fe, false, tvp); +dtv_get_property_dump (fe, tvp);return 0 ; }drivers/media/dvb-core/dvb_frontend.c static int dvbv3_set_delivery_system(struct dvb_frontend *fe) · line 1757
Quoted 6 lines
drivers/media/dvb-core/dvb_frontend.c +3
-0@@ -1755,16 +1752,36 @@ static int dvbv3_set_delivery_system(struct dvb_frontend *fe)return emulate_delivery_system (fe, delsys); } +/** +* dtv_property_process_set - Sets a single DTV property +* @fe: Pointer to &struct dvb_frontend Nit: extra tab looks like:
Quoted 20 lines
drivers/media/dvb-core/dvb_frontend.c +13
-2+* @file: Pointer to &struct file +* @cmd: Digital TV command +* @data: An unsigned 32-bits number +* +* This routine assigns the property +* value to the corresponding member of +* &struct dtv_frontend_properties +* +* Returns: +* Zero on success, negative errno on failure. +*/ static int dtv_property_process_set (struct dvb_frontend *fe, -struct dtv_property *tvp, -struct file *file) +struct file *file, +u32 cmd,u32 data) {int r =0 ;struct dtv_frontend_properties *c = &fe->dtv_property_cache;
Quoted 5 lines
drivers/media/dvb-core/dvb_frontend.c static int dvbv3_set_delivery_system(struct dvb_frontend *fe) · line 1765
Quoted 1 line
drivers/media/dvb-core/dvb_frontend.c +0
-1-dtv_property_dump (fe, true, tvp);Why not keep
dtv_property_dump()the way it is? I am not seeing the value of this change.
See below.
Quoted 5 lines
Quoted 5 lines
drivers/media/dvb-core/dvb_frontend.c +3
-2- -switch (tvp->cmd) { +/** Dump DTV command name and value*/ +if (!cmd || cmd >DTV_MAX_COMMAND ) + dev_warn(fe->dvb->device, "%s: SET cmd 0x%08x undefined\n",
Quoted 8 lines
drivers/media/dvb-core/dvb_frontend.c static int dvbv3_set_delivery_system(struct dvb_frontend *fe) · line 1783
Quoted 5 lines
drivers/media/dvb-core/dvb_frontend.c +5
-0+ __func__, cmd); + else + dev_dbg(fe->dvb->device, +"%s: SET cmd 0x%08x (%s) to 0x%08x\n" , + __func__, cmd, dtv_cmds[cmd].name, data);The code looked simpler before this change? Why add almost identical duplicate code here?
Looking on each separate patch (17 and 18) makes harder to see the value :-)
Basically, after the changes we have, at dtv_property_process_set():
int r = 0; struct dtv_frontend_properties *c = &fe->dtv_property_cache; /** Dump DTV command name and value*/ if (!cmd || cmd > DTV_MAX_COMMAND) dev_warn(fe->dvb->device, "%s: SET cmd 0x%08x undefined\n", __func__, cmd); else dev_dbg(fe->dvb->device, "%s: SET cmd 0x%08x (%s) to 0x%08x\n", __func__, cmd, dtv_cmds[cmd].name, data);
As here the prints happen before setting the property, the code needs to check if the command is at the range, printing an dvb_warn() on such case.
At dtv_property_process_get():
int ncaps;
switch(tvp->cmd) {
...
default:
dev_dbg(fe->dvb->device,
"%s: FE property %d doesn't exist\n",
__func__, tvp->cmd);
return -EINVAL;
}
if (!dtv_cmds[tvp->cmd].buffer)
dev_dbg(fe->dvb->device,
"%s: GET cmd 0x%08x (%s) = 0x%08x\n",
__func__, tvp->cmd, dtv_cmds[tvp->cmd].name,
tvp->u.data);
else
dev_dbg(fe->dvb->device,
"%s: GET cmd 0x%08x (%s) len %d: %*ph\n",
__func__,
tvp->cmd, dtv_cmds[tvp->cmd].name,
tvp->u.buffer.len,
tvp->u.buffer.len, tvp->u.buffer.data);As the debugs are after the switch(), we don't need anymore to check for invalid values, as the switch() code will return -EINVAL.
On the other hand, here, it can't assume that the message has just one u32 data, as it may have multiple ones.
So, in other words, after getting rid of dtv_property_dump(), the debug logic is actually different and there isn't much gain on putting them at the same routine.
BTW, I have to double-check, but I guess the "if" there should be doing:
if (!dtv_cmds[tvp->cmd].buffer.len)
Anyway, if this is a bug, it is a pre-existent one, and should be addressed on a separate patch.
Quoted 193 lines
Quoted 180 lines
drivers/media/dvb-core/dvb_frontend.c +40
-39+switch (cmd) {case DTV_CLEAR :/* * Reset a cache of data specific to the frontend here. This does @@ -1784,133 +1801,133 @@ static int dtv_property_process_set(struct dvb_frontend *fe, r =dtv_set_frontend (fe);break ;case DTV_FREQUENCY : - c->frequency = tvp->u.data; + c->frequency = data;break ;case DTV_MODULATION : - c->modulation = tvp->u.data; + c->modulation = data;break ;case DTV_BANDWIDTH_HZ : - c->bandwidth_hz = tvp->u.data; + c->bandwidth_hz = data;break ;case DTV_INVERSION : - c->inversion = tvp->u.data; + c->inversion = data;break ;case DTV_SYMBOL_RATE : - c->symbol_rate = tvp->u.data; + c->symbol_rate = data;break ;case DTV_INNER_FEC : - c->fec_inner = tvp->u.data; + c->fec_inner = data;break ;case DTV_PILOT : - c->pilot = tvp->u.data; + c->pilot = data;break ;case DTV_ROLLOFF : - c->rolloff = tvp->u.data; + c->rolloff = data;break ;case DTV_DELIVERY_SYSTEM : - r =dvbv5_set_delivery_system (fe, tvp->u.data); + r =dvbv5_set_delivery_system (fe, data);break ;case DTV_VOLTAGE : - c->voltage = tvp->u.data; + c->voltage = data; r =dvb_frontend_handle_ioctl (file,FE_SET_VOLTAGE , (void *)c->voltage);break ;case DTV_TONE : - c->sectone = tvp->u.data; + c->sectone = data; r =dvb_frontend_handle_ioctl (file,FE_SET_TONE , (void *)c->sectone);break ;case DTV_CODE_RATE_HP : - c->code_rate_HP = tvp->u.data; + c->code_rate_HP = data;break ;case DTV_CODE_RATE_LP : - c->code_rate_LP = tvp->u.data; + c->code_rate_LP = data;break ;case DTV_GUARD_INTERVAL : - c->guard_interval = tvp->u.data; + c->guard_interval = data;break ;case DTV_TRANSMISSION_MODE : - c->transmission_mode = tvp->u.data; + c->transmission_mode = data;break ;case DTV_HIERARCHY : - c->hierarchy = tvp->u.data; + c->hierarchy = data;break ;case DTV_INTERLEAVING : - c->interleaving = tvp->u.data; + c->interleaving = data;break ;/* ISDB-T Support here */ case DTV_ISDBT_PARTIAL_RECEPTION : - c->isdbt_partial_reception = tvp->u.data; + c->isdbt_partial_reception = data;break ;case DTV_ISDBT_SOUND_BROADCASTING : - c->isdbt_sb_mode = tvp->u.data; + c->isdbt_sb_mode = data;break ;case DTV_ISDBT_SB_SUBCHANNEL_ID : - c->isdbt_sb_subchannel = tvp->u.data; + c->isdbt_sb_subchannel = data;break ;case DTV_ISDBT_SB_SEGMENT_IDX : - c->isdbt_sb_segment_idx = tvp->u.data; + c->isdbt_sb_segment_idx = data;break ;case DTV_ISDBT_SB_SEGMENT_COUNT : - c->isdbt_sb_segment_count = tvp->u.data; + c->isdbt_sb_segment_count = data;break ;case DTV_ISDBT_LAYER_ENABLED : - c->isdbt_layer_enabled = tvp->u.data; + c->isdbt_layer_enabled = data;break ;case DTV_ISDBT_LAYERA_FEC : - c->layer[0 ].fec = tvp->u.data; + c->layer[0 ].fec = data;break ;case DTV_ISDBT_LAYERA_MODULATION : - c->layer[0 ].modulation = tvp->u.data; + c->layer[0 ].modulation = data;break ;case DTV_ISDBT_LAYERA_SEGMENT_COUNT : - c->layer[0 ].segment_count = tvp->u.data; + c->layer[0 ].segment_count = data;break ;case DTV_ISDBT_LAYERA_TIME_INTERLEAVING : - c->layer[0 ].interleaving = tvp->u.data; + c->layer[0 ].interleaving = data;break ;case DTV_ISDBT_LAYERB_FEC : - c->layer[1 ].fec = tvp->u.data; + c->layer[1 ].fec = data;break ;case DTV_ISDBT_LAYERB_MODULATION : - c->layer[1 ].modulation = tvp->u.data; + c->layer[1 ].modulation = data;break ;case DTV_ISDBT_LAYERB_SEGMENT_COUNT : - c->layer[1 ].segment_count = tvp->u.data; + c->layer[1 ].segment_count = data;break ;case DTV_ISDBT_LAYERB_TIME_INTERLEAVING : - c->layer[1 ].interleaving = tvp->u.data; + c->layer[1 ].interleaving = data;break ;case DTV_ISDBT_LAYERC_FEC : - c->layer[2 ].fec = tvp->u.data; + c->layer[2 ].fec = data;break ;case DTV_ISDBT_LAYERC_MODULATION : - c->layer[2 ].modulation = tvp->u.data; + c->layer[2 ].modulation = data;break ;case DTV_ISDBT_LAYERC_SEGMENT_COUNT : - c->layer[2 ].segment_count = tvp->u.data; + c->layer[2 ].segment_count = data;break ;case DTV_ISDBT_LAYERC_TIME_INTERLEAVING : - c->layer[2 ].interleaving = tvp->u.data; + c->layer[2 ].interleaving = data;break ;/* Multistream support */ case DTV_STREAM_ID :case DTV_DVBT2_PLP_ID_LEGACY : - c->stream_id = tvp->u.data; + c->stream_id = data;break ;/* ATSC-MH */ case DTV_ATSCMH_PARADE_ID : - fe->dtv_property_cache.atscmh_parade_id = tvp->u.data; + fe->dtv_property_cache.atscmh_parade_id = data;break ;case DTV_ATSCMH_RS_FRAME_ENSEMBLE : - fe->dtv_property_cache.atscmh_rs_frame_ensemble = tvp->u.data; + fe->dtv_property_cache.atscmh_rs_frame_ensemble = data;break ;case DTV_LNA : - c->lna = tvp->u.data; + c->lna = data;if (fe->ops.set_lna) r = fe->ops.set_lna (fe);if (r <0 )drivers/media/dvb-core/dvb_frontend.c static int dvb_frontend_handle_ioctl(struct file *file, · line 2162
Quoted 10 lines
drivers/media/dvb-core/dvb_frontend.c +3
-1@@ -2137,7 +2154,9 @@ static int dvb_frontend_handle_ioctl(struct file *file,return PTR_ERR (tvp);for (i =0 ; i < tvps->num; i++) { - err =dtv_property_process_set (fe, tvp + i, file); + err =dtv_property_process_set (fe, file, + (tvp + i)->cmd, + (tvp + i)->u.data);if (err <0 ) {kfree (tvp);return err;The rest looks good. Once the other comments are addressed and/or explained.
Quoted 4 lines
Reviewed-by Shuah Khan <[email protected]>thanks,
-- Shuah
Thanks,
Mauro
PATCH 18/25 media: dvb_frontend: get rid of dtv_get_property_dump()
In reply to Mauro Carvalho ChehabSimplify the get property handling and move it to the existing code at dtv_property_process_get() directly.
--- drivers/media/dvb-core/dvb_frontend.c | 43 ++++++++++------------------------- 1 file changed, 12 insertions(+), 31 deletions(-)
drivers/media/dvb-core/dvb_frontend.c +12 -31
@@ -1107,36 +1107,6 @@ static struct dtv_cmds_h dtv_cmds[DTV_MAX_COMMAND + 1] = { _DTV_CMD(DTV_STAT_TOTAL_BLOCK_COUNT, 0, 0), }; -static void dtv_get_property_dump (struct dvb_frontend *fe, -struct dtv_property *tvp) -{ -int i; - -if (tvp->cmd <=0 || tvp->cmd >DTV_MAX_COMMAND ) { -dev_warn (fe->dvb->device,"%s: GET tvp.cmd = 0x%08x undefined\n" - , __func__, - tvp->cmd); -return ; - } - -dev_dbg (fe->dvb->device,"%s: GET tvp.cmd = 0x%08x (%s)\n" , __func__, - tvp->cmd, - dtv_cmds[tvp->cmd].name); - -if (dtv_cmds[tvp->cmd].buffer) { -dev_dbg (fe->dvb->device,"%s: tvp.u.buffer.len = 0x%02x\n" , - __func__, tvp->u.buffer.len); - -for (i =0 ; i < tvp->u.buffer.len; i++) -dev_dbg (fe->dvb->device, -"%s: tvp.u.buffer.data[0x%02x] = 0x%02x\n" , - __func__, i, tvp->u.buffer.data[i]); - }else { -dev_dbg (fe->dvb->device,"%s: tvp.u.data = 0x%08x\n" , __func__, - tvp->u.data); - } -} -/* Synchronise the legacy tuning parameters into the cache, so that demodulator * drivers can use a single set_frontend tuning function, regardless of whether * it's being used for the legacy or new API, reducing code and complexity.
@@ -1529,7 +1499,18 @@ static int dtv_property_process_get(struct dvb_frontend *fe,return -EINVAL ; } -dtv_get_property_dump (fe, tvp); +if (!dtv_cmds[tvp->cmd].buffer) +dev_dbg (fe->dvb->device, +"%s: GET cmd 0x%08x (%s) = 0x%08x\n" , + __func__, tvp->cmd, dtv_cmds[tvp->cmd].name, + tvp->u.data); +else +dev_dbg (fe->dvb->device, +"%s: GET cmd 0x%08x (%s) len %d: %*ph\n" , + __func__, + tvp->cmd, dtv_cmds[tvp->cmd].name, + tvp->u.buffer.len, + tvp->u.buffer.len, tvp->u.buffer.data);return 0 ; }
Signature · 1 line
2.13.5
Re: [PATCH 18/25] media: dvb_frontend: get rid of dtv_get_property_dump()
Quoted 60 lines · Mauro Carvalho Chehab
Simplify the get property handling and move it to the existing code at
dtv_property_process_get()directly.Signed-off-by Mauro Carvalho Chehab <[email protected]>--- drivers/media/dvb-core/dvb_frontend.c | 43 ++++++++++------------------------- 1 file changed, 12 insertions(+), 31 deletions(-)drivers/media/dvb-core/dvb_frontend.c +5
-31@@ -1107,36 +1107,6 @@ static struct dtv_cmds_h dtv_cmds[DTV_MAX_COMMAND + 1] = { _DTV_CMD(DTV_STAT_TOTAL_BLOCK_COUNT, 0, 0), }; -static void dtv_get_property_dump (struct dvb_frontend *fe, -struct dtv_property *tvp) -{ -int i; - -if (tvp->cmd <=0 || tvp->cmd >DTV_MAX_COMMAND ) { -dev_warn (fe->dvb->device,"%s: GET tvp.cmd = 0x%08x undefined\n" - , __func__, - tvp->cmd); -return ; - } - -dev_dbg (fe->dvb->device,"%s: GET tvp.cmd = 0x%08x (%s)\n" , __func__, - tvp->cmd, - dtv_cmds[tvp->cmd].name); - -if (dtv_cmds[tvp->cmd].buffer) { -dev_dbg (fe->dvb->device,"%s: tvp.u.buffer.len = 0x%02x\n" , - __func__, tvp->u.buffer.len); - -for (i =0 ; i < tvp->u.buffer.len; i++) -dev_dbg (fe->dvb->device, -"%s: tvp.u.buffer.data[0x%02x] = 0x%02x\n" , - __func__, i, tvp->u.buffer.data[i]); - }else { -dev_dbg (fe->dvb->device,"%s: tvp.u.data = 0x%08x\n" , __func__, - tvp->u.data); - } -} -/* Synchronise the legacy tuning parameters into the cache, so that demodulator * drivers can use a single set_frontend tuning function, regardless of whether * it's being used for the legacy or new API, reducing code and complexity. @@ -1529,7 +1499,18 @@ static int dtv_property_process_get(struct dvb_frontend *fe,return -EINVAL ; } -dtv_get_property_dump (fe, tvp); +if (!dtv_cmds[tvp->cmd].buffer) +dev_dbg (fe->dvb->device, +"%s: GET cmd 0x%08x (%s) = 0x%08x\n" , + __func__, tvp->cmd, dtv_cmds[tvp->cmd].name, + tvp->u.data);
drivers/media/dvb-core/dvb_frontend.c static int dtv_property_process_get(struct dvb_frontend *fe, · line 1516
Quoted 10 lines
drivers/media/dvb-core/dvb_frontend.c +7
-0+else +dev_dbg (fe->dvb->device, +"%s: GET cmd 0x%08x (%s) len %d: %*ph\n" , + __func__, + tvp->cmd, dtv_cmds[tvp->cmd].name, + tvp->u.buffer.len, + tvp->u.buffer.len, tvp->u.buffer.data);return 0 ; }
Why not keep common dtv_property_dum(0 and make these enhancements to add more information to the dump in a common routine so both get and set are covered.
I think this change coupled with the change in 17/25 is moving away from common simpler code to embedded debug code. I am not clear on the value it adds.
thanks,
-- Shuah
PATCH 19/25 media: dvb_demux.h: document structs defined on it
In reply to Mauro Carvalho ChehabThere are three structs defined inside dvb_demux.h. None of them are currently documented.
Add documentation for them.
--- drivers/media/dvb-core/dvb_demux.c | 1 + drivers/media/dvb-core/dvb_demux.h | 58 ++++++++++++++++++++++++++++++++------ 2 files changed, 50 insertions(+), 9 deletions(-)
drivers/media/dvb-core/dvb_demux.c +1 -0
@@ -367,6 +367,7 @@ static inline void dvb_dmx_swfilter_packet_type(struct dvb_demux_feed *feed,else feed->cb.ts (buf,188 ,NULL ,0 , &feed->feed.ts); } +/* Used only on full-featured devices */ if (feed->ts_type &TS_DECODER )if (feed->demux->write_to_decoder) feed->demux->write_to_decoder (feed, buf,188 );
drivers/media/dvb-core/dvb_demux.h +49 -9
91 lines not on this page · raw message
Signature · 1 line
2.13.5
PATCH 20/25 media: dvb_demux.h: document functions
In reply to Mauro Carvalho ChehabThe functions used on dvb_demux.h are largely used on DVB drivers. Yet, none of them are documented.
No functional changes.
--- drivers/media/dvb-core/dvb_demux.h | 106 +++++++++++++++++++++++++++++++++++-- 1 file changed, 103 insertions(+), 3 deletions(-)
drivers/media/dvb-core/dvb_demux.h +103 -3
@@ -232,13 +232,113 @@ struct dvb_demux {int recording; }; -int dvb_dmx_init (struct dvb_demux *dvbdemux); -void dvb_dmx_release (struct dvb_demux *dvbdemux); -void dvb_dmx_swfilter_packets (struct dvb_demux *dvbdmx,const u8 *buf, +/** +* dvb_dmx_init - initialize a digital TV demux struct. +* +* @demux: &struct dvb_demux to be initialized. +* +* Before being able to register a digital TV demux struct, drivers +* should call this routine. On its typical usage, some fields should +* be initialized at the driver before calling it. +* +* A typical usecase is:: +* +* dvb->demux.dmx.capabilities = +* DMX_TS_FILTERING | DMX_SECTION_FILTERING | +* DMX_MEMORY_BASED_FILTERING; +* dvb->demux.priv = dvb; +* dvb->demux.filternum = 256; +* dvb->demux.feednum = 256; +* dvb->demux.start_feed = driver_start_feed; +* dvb->demux.stop_feed = driver_stop_feed; +* ret = dvb_dmx_init(&dvb->demux); +* if (ret < 0) +* return ret; +*/ +int dvb_dmx_init (struct dvb_demux *demux); + +/** +* dvb_dmx_release - releases a digital TV demux internal buffers. +* +* @demux: &struct dvb_demux to be released. +* +* The DVB core internally allocates data at @demux. This routine +* releases those data. Please notice that the struct itelf is not +* released, as it can be embedded on other structs. +*/ +void dvb_dmx_release (struct dvb_demux *demux); + +/** +* dvb_dmx_swfilter_packets - use dvb software filter for a buffer with +* multiple MPEG-TS packets with 188 bytes each. +* +* @demux: pointer to &struct dvb_demux +* @buf: buffer with data to be filtered +* @count: number of MPEG-TS packets with size of 188. +* +* The routine will discard a DVB packet that don't start with 0x47. +* +* Use this routine if the DVB demux fills MPEG-TS buffers that are +* already aligned. +* +* NOTE: The @buf size should have size equal to ``count * 188``. +*/ +void dvb_dmx_swfilter_packets (struct dvb_demux *demux,const u8 *buf,size_t count); + +/** +* dvb_dmx_swfilter - use dvb software filter for a buffer with +* multiple MPEG-TS packets with 188 bytes each. +* +* @demux: pointer to &struct dvb_demux +* @buf: buffer with data to be filtered +* @count: number of MPEG-TS packets with size of 188. +* +* If a DVB packet doesn't start with 0x47, it will seek for the first +* byte that starts with 0x47. +* +* Use this routine if the DVB demux fill buffers that may not start with +* a packet start mark (0x47). +* +* NOTE: The @buf size should have size equal to ``count * 188``. +*/ void dvb_dmx_swfilter (struct dvb_demux *demux,const u8 *buf,size_t count); + +/** +* dvb_dmx_swfilter_204 - use dvb software filter for a buffer with +* multiple MPEG-TS packets with 204 bytes each. +* +* @demux: pointer to &struct dvb_demux +* @buf: buffer with data to be filtered +* @count: number of MPEG-TS packets with size of 204. +* +* If a DVB packet doesn't start with 0x47, it will seek for the first +* byte that starts with 0x47. +* +* Use this routine if the DVB demux fill buffers that may not start with +* a packet start mark (0x47). +* +* NOTE: The @buf size should have size equal to ``count * 204``. +*/ void dvb_dmx_swfilter_204 (struct dvb_demux *demux,const u8 *buf,size_t count); + +/** +* dvb_dmx_swfilter_raw - make the raw data available to userspace without +* filtering +* +* @demux: pointer to &struct dvb_demux +* @buf: buffer with data +* @count: number of packets to be passed. The actual size of each packet +* depends on the &dvb_demux->feed->cb.ts logic. +* +* Use it if the driver needs to deliver the raw payload to userspace without +* passing through the kernel demux. That is meant to support some +* delivery systems that aren't based on MPEG-TS. +* +* This function relies on &dvb_demux->feed->cb.ts to actually handle the +* buffer. +*/ void dvb_dmx_swfilter_raw (struct dvb_demux *demux,const u8 *buf,size_t count);
Signature · 1 line
2.13.5
PATCH 21/25 scripts: kernel-doc: fix nexted handling
In reply to Mauro Carvalho ChehabAt DVB, we have, at some structs, things like (see struct dvb_demux_feed, at dvb_demux.h):
union {
struct dmx_ts_feed ts;
struct dmx_section_feed sec;
} feed;
union {
dmx_ts_cb ts;
dmx_section_cb sec;
} cb;Fix the nested parser to avoid it to eat the first union.
--- scripts/kernel-doc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
scripts/kernel-doc +1 -1
@@ -2173,7 +2173,7 @@ sub dump_struct($$) { my $members = $3; # ignore embedded structs or unions - $members =~ s/({.*})//g; + $members =~ s/({[^\}]*})//g; $nested = $1; # ignore members marked private:
Signature · 1 line
2.13.5
PATCH 22/25 media: dmxdev.h: add kernel-doc markups for data types and functions
In reply to Mauro Carvalho ChehabDespite being used by DVB drivers, this header was not documented.
Document it.
--- drivers/media/dvb-core/dmxdev.h | 90 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 88 insertions(+), 2 deletions(-)
drivers/media/dvb-core/dmxdev.h +88 -2
@@ -36,12 +36,33 @@#include "demux.h" #include "dvb_ringbuffer.h" +/** +* enum dmxdev_type - type of demux filter type. +* +* @DMXDEV_TYPE_NONE: no filter set. +* @DMXDEV_TYPE_SEC: section filter. +* @DMXDEV_TYPE_PES: Program Elementary Stream (PES) filter. +*/ enum dmxdev_type {DMXDEV_TYPE_NONE ,DMXDEV_TYPE_SEC ,DMXDEV_TYPE_PES , }; +/** +* enum dmxdev_state - state machine for the dmxdev. +* +* @DMXDEV_STATE_FREE: indicates that the filter is freed. +* @DMXDEV_STATE_ALLOCATED: indicates that the filter was allocated +* to be used. +* @DMXDEV_STATE_SET: indicates that the filter parameters are set. +* @DMXDEV_STATE_GO: indicates that the filter is running. +* @DMXDEV_STATE_DONE: indicates that a packet was already filtered +* and the filter is now disabled. +* Set only if %DMX_ONESHOT. See +* &dmx_sct_filter_params. +* @DMXDEV_STATE_TIMEDOUT: Indicates a timeout condition. +*/ enum dmxdev_state {DMXDEV_STATE_FREE ,DMXDEV_STATE_ALLOCATED ,
@@ -51,12 +72,49 @@ enum dmxdev_state {DMXDEV_STATE_TIMEDOUT }; +/** +* struct dmxdev_feed - digital TV dmxdev feed +* +* @pid: Program ID to be filtered +* @ts: pointer to &struct dmx_ts_feed +* @next: &struct list_head pointing to the next feed. +*/ +struct dmxdev_feed {u16 pid;struct dmx_ts_feed *ts;struct list_head next; }; +/** +* struct dmxdev_filter - digital TV dmxdev filter +* +* @filter: a dmxdev filter. Currently used only for section filter: +* if the filter is Section, it contains a +* &struct dmx_section_filter @sec pointer. +* @feed: a dmxdev feed. Depending on the feed type, it can be: +* for TS feed: a &struct list_head @ts list of TS and PES +* feeds; +* for section feed: a &struct dmx_section_feed @sec pointer. +* @params: dmxdev filter parameters. Depending on the feed type, it +* can be: +* for section filter: a &struct dmx_sct_filter_params @sec +* embedded struct; +* for a TS filter: a &struct dmx_pes_filter_params @pes +* embedded struct. +* @type: type of the dmxdev filter, as defined by &enum dmxdev_type. +* @state: state of the dmxdev filter, as defined by &enum dmxdev_state. +* @dev: pointer to &struct dmxdev. +* @buffer: an embedded &struct dvb_ringbuffer buffer. +* @mutex: protects the access to &struct dmxdev_filter. +* @timer: &struct timer_list embedded timer, used to check for +* feed timeouts. +* Only for section filter. +* @todo: index for the @secheader. +* Only for section filter. +* @secheader: buffer cache to parse the section header. +* Only for section filter. +*/ struct dmxdev_filter {union {struct dmx_section_filter *sec;
@@ -86,7 +144,23 @@ struct dmxdev_filter {u8 secheader[3 ]; }; - +/** +* struct dmxdev - Describes a digital TV demux device. +* +* @dvbdev: pointer to &struct dvb_device associated with +* the demux device node. +* @dvr_dvbdev: pointer to &struct dvb_device associated with +* the dvr device node. +* @filter: pointer to &struct dmxdev_filter. +* @demux: pointer to &struct dmx_demux. +* @filternum: number of filters. +* @capabilities: demux capabilities as defined by &enum dmx_demux_caps. +* @exit: flag to indicate that the demux is being released. +* @dvr_orig_fe: pointer to &struct dmx_frontend. +* @dvr_buffer: embedded &struct dvb_ringbuffer for DVB output. +* @mutex: protects the usage of this structure. +* @lock: protects access to &dmxdev->filter->data. +*/ struct dmxdev {struct dvb_device *dvbdev;struct dvb_device *dvr_dvbdev;
@@ -108,8 +182,20 @@ struct dmxdev { spinlock_t lock; }; +/** +* dvb_dmxdev_init - initializes a digital TV demux and registers both demux +* and DVR devices. +* +* @dmxdev: pointer to &struct dmxdev. +* @adap: pointer to &struct dvb_adapter. +*/ +int dvb_dmxdev_init (struct dmxdev *dmxdev,struct dvb_adapter *adap); -int dvb_dmxdev_init (struct dmxdev *dmxdev,struct dvb_adapter *); +/** +* dvb_dmxdev_release - releases a digital TV demux and unregisters it. +* +* @dmxdev: pointer to &struct dmxdev. +*/ void dvb_dmxdev_release (struct dmxdev *dmxdev);#endif /* _DMXDEV_H_ */
Signature · 1 line
2.13.5
PATCH 23/25 media: dtv-demux.rst: parse other demux headers with kernel-doc
In reply to Mauro Carvalho ChehabNow that we have kernel-doc markups at dvb_demux.h and dmxdev.h, parse them.
--- Documentation/media/kapi/dtv-demux.rst | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-)
Documentation/media/kapi/dtv-demux.rst +12 -2
@@ -66,7 +66,17 @@ function call directly from a hardware interrupt. This mechanism is implemented by :c:func:`dmx_ts_cb()` and :c:func:`dmx_section_cb()` callbacks. -Digital TV Demux functions and types -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Digital TV Demux device registration functions and data structures +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. kernel-doc:: drivers/media/dvb-core/dmxdev.h + +High-level Digital TV demux interface +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. kernel-doc:: drivers/media/dvb-core/dvb_demux.h + +Driver-internal low-level hardware specific driver demux interface +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. kernel-doc:: drivers/media/dvb-core/demux.h
Signature · 1 line
2.13.5
PATCH 24/25 media: dvb-net.rst: document DVB network kAPI interface
In reply to Mauro Carvalho ChehabThat's the last DVB kAPI that misses documentation.
--- Documentation/media/kapi/dtv-core.rst | 1 + Documentation/media/kapi/dtv-net.rst | 4 ++++ drivers/media/dvb-core/dvb_net.h | 34 ++++++++++++++++++++++++++++++++-- 3 files changed, 37 insertions(+), 2 deletions(-) create mode 100644 Documentation/media/kapi/dtv-net.rst
Documentation/media/kapi/dtv-core.rst +1 -0
@@ -34,3 +34,4 @@ I2C bus. dtv-frontend dtv-demux dtv-ca + dtv-net
Documentation/media/kapi/dtv-net.rst new file +4 -0
@@ -0,0 +1,4 @@ +Digital TV Network kABI +----------------------- + +.. kernel-doc:: drivers/media/dvb-core/dvb_net.h
drivers/media/dvb-core/dvb_net.h +32 -2
@@ -30,6 +30,22 @@ #ifdef CONFIG_DVB_NET +/** + * struct dvb_net - describes a DVB network interface + * + * @dvbdev: pointer to &struct dvb_device. + * @device: array of pointers to &struct net_device. + * @state: array of integers to each net device. A value + * different than zero means that the interface is + * in usage. + * @exit: flag to indicate when the device is being removed. + * @demux: pointer to &struct dmx_demux. + * @ioctl_mutex: protect access to this struct. + * + * Currently, the core supports up to %DVB_NET_DEVICES_MAX (10) network + * devices. + */ + struct dvb_net { struct dvb_device *dvbdev; struct net_device *device[DVB_NET_DEVICES_MAX];
@@ -39,8 +55,22 @@ struct dvb_net { struct mutex ioctl_mutex; }; -void dvb_net_release (struct dvb_net *); -int dvb_net_init (struct dvb_adapter *,struct dvb_net *,struct dmx_demux *); +/** +* dvb_net_init - nitializes a digital TV network device and registers it. +* +* @adap: pointer to &struct dvb_adapter. +* @dvbnet: pointer to &struct dvb_net. +* @dmxdemux: pointer to &struct dmx_demux. +*/ +int dvb_net_init (struct dvb_adapter *adap,struct dvb_net *dvbnet, +struct dmx_demux *dmxdemux); + +/** +* dvb_net_release - releases a digital TV network device and unregisters it. +* +* @dvbnet: pointer to &struct dvb_net. +*/ +void dvb_net_release (struct dvb_net *dvbnet);#else
Signature · 1 line
2.13.5
PATCH 25/25 media: dvb uAPI docs: get rid of examples section
In reply to Mauro Carvalho ChehabThat section is too outdated and got superseded by DVBv5 and by libdvbv5.
Maybe some day we'll end adding updated examples there, but while nobody has time or interest of doing that, just mention that there and get rid of the current examples for good.
--- Documentation/media/uapi/dvb/examples.rst | 378 +----------------------------- 1 file changed, 6 insertions(+), 372 deletions(-)
Documentation/media/uapi/dvb/examples.rst +6 -372
@@ -6,377 +6,11 @@ Examples ******** -In this section we would like to present some examples for using the Digital -TV API. +In the past, we used to have a set of examples here. However, those +examples got out of date and doesn't even compile nowadays. -.. note:: +Also, nowadays, the best is to use the libdvbv5 DVB API nowadays, +with is fully documented. - This section is out of date, and the code below won't even - compile. Please refer to the - `libdvbv5 <https://linuxtv.org/docs/libdvbv5/index.html>`__ for - updated/recommended examples. - - -.. _tuning: - -Example: 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 -tuners, but can easily be adjusted for QAM. - - -.. code-block:: c - - #include <sys/ioctl.h> - #include <stdio.h> - #include <stdint.h> - #include <sys/types.h> - #include <sys/stat.h> - #include <fcntl.h> - #include <time.h> - #include <unistd.h> - - #include <linux/dvb/dmx.h> - #include <linux/dvb/frontend.h> - #include <linux/dvb/sec.h> - #include <sys/poll.h> - - #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, fe_status_t *stat) - { - int ans; - - if ( (ans = ioctl(fd,FE_READ_STATUS,stat) < 0)){ - perror("FE READ STATUS: "); - return -1; - } - - if (*stat & FE_HAS_POWER) - printf("FE HAS POWER\\n"); - - if (*stat & FE_HAS_SIGNAL) - printf("FE HAS SIGNAL\\n"); - - if (*stat & FE_SPECTRUM_INV) - printf("SPEKTRUM INV\\n"); - - return 0; - } - - - /* tune qpsk */ - /* freq: frequency of transponder */ - /* vpid, apid, tpid: PIDs of video, audio and teletext TS packets */ - /* diseqc: DiSEqC address of the used LNB */ - /* pol: Polarisation */ - /* srate: Symbol Rate */ - /* fec. FEC */ - /* lnb_lof1: local frequency of lower LNB band */ - /* lnb_lof2: local frequency of upper LNB band */ - /* lnb_slof: switch frequency of LNB */ - - int set_qpsk_channel(int freq, int vpid, int apid, int tpid, - int diseqc, int pol, int srate, int fec, int lnb_lof1, - int lnb_lof2, int lnb_slof) - { - struct secCommand scmd; - struct secCmdSequence scmds; - struct dmx_pes_filter_params pesFilterParams; - FrontendParameters frp; - struct pollfd pfd[1]; - FrontendEvent event; - int demux1, demux2, demux3, front; - - frequency = (uint32_t) freq; - symbolrate = (uint32_t) srate; - - if((front = open(FRONT,O_RDWR)) < 0){ - perror("FRONTEND DEVICE: "); - return -1; - } - - if((sec = open(SEC,O_RDWR)) < 0){ - perror("SEC DEVICE: "); - return -1; - } - - if (demux1 < 0){ - if ((demux1=open(DMX, O_RDWR|O_NONBLOCK)) - < 0){ - perror("DEMUX DEVICE: "); - return -1; - } - } - - if (demux2 < 0){ - if ((demux2=open(DMX, O_RDWR|O_NONBLOCK)) - < 0){ - perror("DEMUX DEVICE: "); - return -1; - } - } - - if (demux3 < 0){ - if ((demux3=open(DMX, O_RDWR|O_NONBLOCK)) - < 0){ - perror("DEMUX DEVICE: "); - return -1; - } - } - - if (freq < lnb_slof) { - frp.Frequency = (freq - lnb_lof1); - scmds.continuousTone = SEC_TONE_OFF; - } else { - frp.Frequency = (freq - lnb_lof2); - scmds.continuousTone = SEC_TONE_ON; - } - frp.Inversion = INVERSION_AUTO; - if (pol) scmds.voltage = SEC_VOLTAGE_18; - else scmds.voltage = SEC_VOLTAGE_13; - - scmd.type=0; - scmd.u.diseqc.addr=0x10; - scmd.u.diseqc.cmd=0x38; - scmd.u.diseqc.numParams=1; - scmd.u.diseqc.params[0] = 0xF0 | ((diseqc * 4) & 0x0F) | - (scmds.continuousTone == SEC_TONE_ON ? 1 : 0) | - (scmds.voltage==SEC_VOLTAGE_18 ? 2 : 0); - - scmds.miniCommand=SEC_MINI_NONE; - scmds.numCommands=1; - scmds.commands=&scmd; - if (ioctl(sec, SEC_SEND_SEQUENCE, &scmds) < 0){ - perror("SEC SEND: "); - return -1; - } - - if (ioctl(sec, SEC_SEND_SEQUENCE, &scmds) < 0){ - perror("SEC SEND: "); - return -1; - } - - frp.u.qpsk.SymbolRate = srate; - frp.u.qpsk.FEC_inner = fec; - - if (ioctl(front, FE_SET_FRONTEND, &frp) < 0){ - perror("QPSK TUNE: "); - return -1; - } - - pfd[0].fd = front; - pfd[0].events = POLLIN; - - if (poll(pfd,1,3000)){ - if (pfd[0].revents & POLLIN){ - printf("Getting QPSK event\\n"); - if ( ioctl(front, FE_GET_EVENT, &event) - - == -EOVERFLOW){ - perror("qpsk get event"); - return -1; - } - printf("Received "); - switch(event.type){ - case FE_UNEXPECTED_EV: - printf("unexpected event\\n"); - return -1; - case FE_FAILURE_EV: - printf("failure event\\n"); - return -1; - - case FE_COMPLETION_EV: - printf("completion event\\n"); - } - } - } - - - pesFilterParams.pid = vpid; - pesFilterParams.input = DMX_IN_FRONTEND; - pesFilterParams.output = DMX_OUT_DECODER; - pesFilterParams.pes_type = DMX_PES_VIDEO; - pesFilterParams.flags = DMX_IMMEDIATE_START; - if (ioctl(demux1, DMX_SET_PES_FILTER, &pesFilterParams) < 0){ - perror("set_vpid"); - return -1; - } - - pesFilterParams.pid = apid; - pesFilterParams.input = DMX_IN_FRONTEND; - pesFilterParams.output = DMX_OUT_DECODER; - pesFilterParams.pes_type = DMX_PES_AUDIO; - pesFilterParams.flags = DMX_IMMEDIATE_START; - if (ioctl(demux2, DMX_SET_PES_FILTER, &pesFilterParams) < 0){ - perror("set_apid"); - return -1; - } - - pesFilterParams.pid = tpid; - pesFilterParams.input = DMX_IN_FRONTEND; - pesFilterParams.output = DMX_OUT_DECODER; - pesFilterParams.pes_type = DMX_PES_TELETEXT; - pesFilterParams.flags = DMX_IMMEDIATE_START; - if (ioctl(demux3, DMX_SET_PES_FILTER, &pesFilterParams) < 0){ - perror("set_tpid"); - return -1; - } - - return has_signal(fds); - } - -The program assumes that you are using a universal LNB and a standard -DiSEqC switch with up to 4 addresses. Of course, you could build in some -more checking if tuning was successful and maybe try to repeat the -tuning process. Depending on the external hardware, i.e. LNB and DiSEqC -switch, and weather conditions this may be necessary. - - -.. _the_dvr_device: - -Example: The DVR device -======================== - -The following program code shows how to use the DVR device for -recording. - - -.. code-block:: c - - #include <sys/ioctl.h> - #include <stdio.h> - #include <stdint.h> - #include <sys/types.h> - #include <sys/stat.h> - #include <fcntl.h> - #include <time.h> - #include <unistd.h> - - #include <linux/dvb/dmx.h> - #include <linux/dvb/video.h> - #include <sys/poll.h> - #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 */ - - - /* switch the demuxes to recording, assuming the transponder is tuned */ - - /* demux1, demux2: file descriptor of video and audio filters */ - /* vpid, apid: PIDs of video and audio channels */ - - int switch_to_record(int demux1, int demux2, uint16_t vpid, uint16_t apid) - { - struct dmx_pes_filter_params pesFilterParams; - - if (demux1 < 0){ - if ((demux1=open(DMX, O_RDWR|O_NONBLOCK)) - < 0){ - perror("DEMUX DEVICE: "); - return -1; - } - } - - if (demux2 < 0){ - if ((demux2=open(DMX, O_RDWR|O_NONBLOCK)) - < 0){ - perror("DEMUX DEVICE: "); - return -1; - } - } - - pesFilterParams.pid = vpid; - pesFilterParams.input = DMX_IN_FRONTEND; - pesFilterParams.output = DMX_OUT_TS_TAP; - pesFilterParams.pes_type = DMX_PES_VIDEO; - pesFilterParams.flags = DMX_IMMEDIATE_START; - if (ioctl(demux1, DMX_SET_PES_FILTER, &pesFilterParams) < 0){ - perror("DEMUX DEVICE"); - return -1; - } - pesFilterParams.pid = apid; - pesFilterParams.input = DMX_IN_FRONTEND; - pesFilterParams.output = DMX_OUT_TS_TAP; - pesFilterParams.pes_type = DMX_PES_AUDIO; - pesFilterParams.flags = DMX_IMMEDIATE_START; - if (ioctl(demux2, DMX_SET_PES_FILTER, &pesFilterParams) < 0){ - perror("DEMUX DEVICE"); - return -1; - } - return 0; - } - - /* start recording MAX_LENGTH , assuming the transponder is tuned */ - - /* demux1, demux2: file descriptor of video and audio filters */ - /* vpid, apid: PIDs of video and audio channels */ - int record_dvr(int demux1, int demux2, uint16_t vpid, uint16_t apid) - { - int i; - int len; - int written; - uint8_t buf[BUFFY]; - uint64_t length; - struct pollfd pfd[1]; - int dvr, dvr_out; - - /* open dvr device */ - if ((dvr = open(DVR, O_RDONLY|O_NONBLOCK)) < 0){ - perror("DVR DEVICE"); - return -1; - } - - /* switch video and audio demuxes to dvr */ - printf ("Switching dvr on\\n"); - i = switch_to_record(demux1, demux2, vpid, apid); - printf("finished: "); - - printf("Recording %2.0f MB of test file in TS format\\n", - MAX_LENGTH/(1024.0*1024.0)); - length = 0; - - /* open output file */ - if ((dvr_out = open(DVR_FILE,O_WRONLY|O_CREAT - |O_TRUNC, S_IRUSR|S_IWUSR - |S_IRGRP|S_IWGRP|S_IROTH| - S_IWOTH)) < 0){ - perror("Can't open file for dvr test"); - return -1; - } - - pfd[0].fd = dvr; - pfd[0].events = POLLIN; - - /* poll for dvr data and write to file */ - while (length < MAX_LENGTH ) { - if (poll(pfd,1,1)){ - if (pfd[0].revents & POLLIN){ - len = read(dvr, buf, BUFFY); - if (len < 0){ - perror("recording"); - return -1; - } - if (len > 0){ - written = 0; - while (written < len) - written += - write (dvr_out, - buf, len); - length += len; - printf("written %2.0f MB\\r", - length/1024./1024.); - } - } - } - } - return 0; - } +Please refer to the `libdvbv5 <https://linuxtv.org/docs/libdvbv5/index.html>`__ +for updated/recommended examples.
Signature · 1 line
2.13.5