Skip to contentSkip to conversation

DVB cleanups and documentation improvements

PATCH Superseded Mauro Carvalho Chehab 3 participants 33 messages Sep 20, 2017 – Sep 21, 2017

Subsystems (2)

v1 of 2 Superseded Latest is v2 →

lore
Share & tools
lore
#0 lore raw

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
#1 lore raw

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
index 01bd19fd4c57..7dda5acea3f2 100644
@@ -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
#2 lore raw

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.

---
 drivers/media/dvb-core/dvb_frontend.c | 20 +++++++++++++++++---
 1 file changed, 17 insertions(+), 3 deletions(-)
drivers/media/dvb-core/dvb_frontend.c +0 -0
index 01bd19fd4c57..7dda5acea3f2 100644

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

#3 lore raw

PATCH 2/25 media: dvb_frontend: fix return values for FE_SET_PROPERTY

In reply to 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 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
index 948d2ba84f2c..b69741d9cedf 100644
@@ -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
index 7dda5acea3f2..bd60a490ce0f 100644
@@ -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
index 861cacd5711f..6bc26f35217b 100644
@@ -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
Reviewed-by on v1 2/25
#4 lore raw

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 via tvp->result field, and to return an updated set of values.

However, that never worked. What's actually implemented is:

Quoted 8 lines

- 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

Spelling - properties

Nit: to the properties

Quoted 11 lines

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.

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
index 948d2ba84f2c..b69741d9cedf 100644
@@ -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
index 7dda5acea3f2..bd60a490ce0f 100644
@@ -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
index 861cacd5711f..6bc26f35217b 100644

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

#5 lore raw

PATCH 3/25 media: dvbdev: convert DVB device types into an enum

In reply to Mauro Carvalho Chehab

Enums 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
index 41aad0f99d73..7b4cdcfbb02c 100644
@@ -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
#6 lore raw

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.

---
 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
index 41aad0f99d73..7b4cdcfbb02c 100644
@@ -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
index 49189392cf3b..53058da83873 100644
@@ -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

#7 lore raw

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

#8 lore raw

PATCH 4/25 media: dvbdev: fully document its functions

In reply to Mauro Carvalho Chehab

There 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
index 53058da83873..bbc1c20c0529 100644
@@ -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
#9 lore raw

PATCH 5/25 media: dvb_frontend.h: improve kernel-doc markups

In reply to Mauro Carvalho Chehab

Several 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
index d273ed2f72c9..ace0c2fb26c2 100644
@@ -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
#10 lore raw

PATCH 6/25 media: dtv-core.rst: add chapters and introductory tests for common parts

In reply to Mauro Carvalho Chehab

Better 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
index de9a228aca8a..4cf9cf63bafd 100644
@@ -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
#11 lore raw

PATCH 7/25 media: dtv-core.rst: split into multiple files

In reply to Mauro Carvalho Chehab

Instead 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
new file mode 100644
index 000000000000..a4dd700189b0
@@ -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
#12 lore raw

PATCH 8/25 media: dtv-demux.rst: minor markup improvements

In reply to Mauro Carvalho Chehab

Add 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
index 8169c479156e..3ee69266e206 100644
@@ -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
#13 lore raw

PATCH 9/25 media: dvb_demux.h: add an enum for DMX_TYPE_* and document

In reply to Mauro Carvalho Chehab

kernel-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
index 6f572ca8d339..6bc4b27dbff3 100644
@@ -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
#14 lore raw

PATCH 10/25 media: dvb_demux.h: add an enum for DMX_STATE_* and document

In reply to Mauro Carvalho Chehab

kernel-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
index 6bc4b27dbff3..b24d69b5a20f 100644
@@ -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
#15 lore raw

PATCH 11/25 media: dvb_demux.h: get rid of unused timer at struct dvb_demux_filter

In reply to Mauro Carvalho Chehab

This 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
index b24d69b5a20f..045f7fd1a8b1 100644
@@ -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
#16 lore raw

PATCH 12/25 media: dvb_demux: mark a boolean field as such

In reply to Mauro Carvalho Chehab

The 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
index 6628f80d184f..68e93362c081 100644
@@ -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
index 045f7fd1a8b1..700887938145 100644
@@ -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
#17 lore raw

PATCH 13/25 media: dvb_demux: dvb_demux_feed.pusi_seen is boolean

In reply to Mauro Carvalho Chehab

Instead 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
index 68e93362c081..b9360cbc3519 100644
@@ -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
index 700887938145..9db3c2b7c64e 100644
@@ -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
index f46947d8adf8..f89fb23f6c57 100644
@@ -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
index 97499b2af714..b3dc45b91101 100644
@@ -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
#18 lore raw

PATCH 14/25 media: dvb_demux.h: get rid of DMX_FEED_ENTRY() macro

In reply to Mauro Carvalho Chehab

This 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
index 9db3c2b7c64e..d9b30d669bf3 100644
@@ -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
#19 lore raw

PATCH 15/25 media: dvb_demux: fix type of dvb_demux_feed.ts_type

In reply to Mauro Carvalho Chehab

Just 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
index d9b30d669bf3..c9e94bc3a2e5 100644
@@ -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
#20 lore raw

PATCH 16/25 media: dvb_demux: document dvb_demux_filter and dvb_demux_feed

In reply to Mauro Carvalho Chehab

Document 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
index c9e94bc3a2e5..5b05e6320e33 100644
@@ -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
#21 lore raw

PATCH 17/25 media: dvb_frontend: dtv_property_process_set() cleanups

In reply to 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 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
index bd60a490ce0f..b7094c7a405f 100644
@@ -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
Reviewed-by on v1 17/25
#22 lore raw

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 struct dtv_property *tvp.

Instead of having a generic dtv_property_dump(), added its own properties debug logic at dtv_property_process_set().

Nit: in the dtv_property_process_set()

Quoted 48 lines
---
 drivers/media/dvb-core/dvb_frontend.c | 125 ++++++++++++++++++++--------------
 1 file changed, 72 insertions(+), 53 deletions(-)
drivers/media/dvb-core/dvb_frontend.c +5 -8
index bd60a490ce0f..b7094c7a405f 100644
@@ -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 -3
 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);

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

#23 lore raw

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 struct dtv_property *tvp.

Instead of having a generic dtv_property_dump(), added its own properties debug logic at dtv_property_process_set().

Nit: in the dtv_property_process_set()

Quoted 48 lines
---
 drivers/media/dvb-core/dvb_frontend.c | 125 ++++++++++++++++++++--------------
 1 file changed, 72 insertions(+), 53 deletions(-)
drivers/media/dvb-core/dvb_frontend.c +5 -8
index bd60a490ce0f..b7094c7a405f 100644
@@ -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

thanks,
-- Shuah

Thanks,
Mauro

#24 lore raw

PATCH 18/25 media: dvb_frontend: get rid of dtv_get_property_dump()

In reply to Mauro Carvalho Chehab

Simplify 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
index b7094c7a405f..607eaf3db052 100644
@@ -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
#25 lore raw

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.

---
 drivers/media/dvb-core/dvb_frontend.c | 43 ++++++++++-------------------------
 1 file changed, 12 insertions(+), 31 deletions(-)
drivers/media/dvb-core/dvb_frontend.c +5 -31
index b7094c7a405f..607eaf3db052 100644
@@ -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

#26 lore raw

PATCH 19/25 media: dvb_demux.h: document structs defined on it

In reply to Mauro Carvalho Chehab

There 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
index b9360cbc3519..acade7543b82 100644
@@ -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
#27 lore raw

PATCH 20/25 media: dvb_demux.h: document functions

In reply to Mauro Carvalho Chehab

The 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
index 43b0cab2e932..15ee2ea23efe 100644
@@ -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
#28 lore raw

PATCH 21/25 scripts: kernel-doc: fix nexted handling

In reply to Mauro Carvalho Chehab

At 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
index 9d3eafea58f0..15f934a23d1d 100755
@@ -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
#29 lore raw

PATCH 22/25 media: dmxdev.h: add kernel-doc markups for data types and functions

In reply to Mauro Carvalho Chehab

Despite 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
index 054fd4eb6192..9aa3ce3fc407 100644
@@ -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
#30 lore raw

PATCH 23/25 media: dtv-demux.rst: parse other demux headers with kernel-doc

In reply to Mauro Carvalho Chehab

Now 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
index 3ee69266e206..7aa865a2b43f 100644
@@ -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
#31 lore raw

PATCH 24/25 media: dvb-net.rst: document DVB network kAPI interface

In reply to Mauro Carvalho Chehab

That'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
index 8ee384f61fa0..bca743dc6b43 100644
@@ -34,3 +34,4 @@ I2C bus.
     dtv-frontend
     dtv-demux
     dtv-ca
+    dtv-net
Documentation/media/kapi/dtv-net.rst new file +4 -0
new file mode 100644
index 000000000000..ced991b73d69
@@ -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
index e9b18aa03e02..1eae8bad7cc1 100644
@@ -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
#32 lore raw

PATCH 25/25 media: dvb uAPI docs: get rid of examples section

In reply to Mauro Carvalho Chehab

That 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
index e0f627ca2e4d..16dd90fa9e94 100644
@@ -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