[3/7,media] dvb-core/dvb_ca_en50221.c: Add block read/write functions
Commit Message
From: Jasmin Jessich <jasmin@anw.at>
Some lower level drivers may work better when sending blocks of data instead
byte per byte. For this we need new function pointers in the dvb_ca_en50221
protocol structure (read_data, write_data) and the protocol needs to execute
them, if they are defined.
Block data transmission is done in all states expect LINKINIT.
Signed-off-by: Ralph Metzler <rjkm@metzlerbros.de>
Signed-off-by: Daniel Scheller <d.scheller@gmx.net>
Signed-off-by: Jasmin Jessich <jasmin@anw.at>
---
drivers/media/dvb-core/dvb_ca_en50221.c | 117 ++++++++++++++++++--------------
drivers/media/dvb-core/dvb_ca_en50221.h | 7 ++
2 files changed, 73 insertions(+), 51 deletions(-)
Comments
Em Sun, 7 May 2017 22:51:49 +0200
"Jasmin J." <jasmin@anw.at> escreveu:
> From: Jasmin Jessich <jasmin@anw.at>
>
> Some lower level drivers may work better when sending blocks of data instead
> byte per byte. For this we need new function pointers in the dvb_ca_en50221
> protocol structure (read_data, write_data) and the protocol needs to execute
> them, if they are defined.
> Block data transmission is done in all states expect LINKINIT.
>
> Signed-off-by: Ralph Metzler <rjkm@metzlerbros.de>
> Signed-off-by: Daniel Scheller <d.scheller@gmx.net>
> Signed-off-by: Jasmin Jessich <jasmin@anw.at>
Please check the patch with checkpatch.pl:
WARNING: Possible unwrapped commit description (prefer a maximum 75 chars per line)
#16:
Some lower level drivers may work better when sending blocks of data instead
WARNING: line over 80 characters
#54: FILE: drivers/media/dvb-core/dvb_ca_en50221.c:649:
+ if (ca->pub->read_data && (ca->slot_info[slot].slot_state != DVB_CA_SLOTSTATE_LINKINIT)) {
...
> ---
> drivers/media/dvb-core/dvb_ca_en50221.c | 117 ++++++++++++++++++--------------
> drivers/media/dvb-core/dvb_ca_en50221.h | 7 ++
> 2 files changed, 73 insertions(+), 51 deletions(-)
>
> diff --git a/drivers/media/dvb-core/dvb_ca_en50221.c b/drivers/media/dvb-core/dvb_ca_en50221.c
> index 1cdd80a..cc709c9 100644
> --- a/drivers/media/dvb-core/dvb_ca_en50221.c
> +++ b/drivers/media/dvb-core/dvb_ca_en50221.c
> @@ -646,66 +646,78 @@ static int dvb_ca_en50221_read_data(struct dvb_ca_private *ca, int slot, u8 * eb
> }
> }
>
> - /* check if there is data available */
> - if ((status = ca->pub->read_cam_control(ca->pub, slot, CTRLIF_STATUS)) < 0)
> - goto exit;
> - if (!(status & STATUSREG_DA)) {
> - /* no data */
> - status = 0;
> - goto exit;
> - }
> -
> - /* read the amount of data */
> - if ((status = ca->pub->read_cam_control(ca->pub, slot, CTRLIF_SIZE_HIGH)) < 0)
> - goto exit;
> - bytes_read = status << 8;
> - if ((status = ca->pub->read_cam_control(ca->pub, slot, CTRLIF_SIZE_LOW)) < 0)
> - goto exit;
> - bytes_read |= status;
> + if (ca->pub->read_data && (ca->slot_info[slot].slot_state != DVB_CA_SLOTSTATE_LINKINIT)) {
> + if (ebuf == NULL)
> + status = ca->pub->read_data(ca->pub, slot, buf, sizeof(buf));
> + else
> + status = ca->pub->read_data(ca->pub, slot, buf, ecount);
> + if (status < 0)
> + return status;
> + bytes_read = status;
> + if (status == 0)
> + goto exit;
> + } else {
>
> - /* check it will fit */
> - if (ebuf == NULL) {
> - if (bytes_read > ca->slot_info[slot].link_buf_size) {
> - pr_err("dvb_ca adapter %d: CAM tried to send a buffer larger than the link buffer size (%i > %i)!\n",
> - ca->dvbdev->adapter->num, bytes_read,
> - ca->slot_info[slot].link_buf_size);
> - ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_LINKINIT;
> - status = -EIO;
> + /* check if there is data available */
> + if ((status = ca->pub->read_cam_control(ca->pub, slot, CTRLIF_STATUS)) < 0)
> goto exit;
> - }
> - if (bytes_read < 2) {
> - pr_err("dvb_ca adapter %d: CAM sent a buffer that was less than 2 bytes!\n",
> - ca->dvbdev->adapter->num);
> - ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_LINKINIT;
> - status = -EIO;
> + if (!(status & STATUSREG_DA)) {
> + /* no data */
> + status = 0;
> goto exit;
> }
> - } else {
> - if (bytes_read > ecount) {
> - pr_err("dvb_ca adapter %d: CAM tried to send a buffer larger than the ecount size!\n",
> - ca->dvbdev->adapter->num);
> - status = -EIO;
> +
> + /* read the amount of data */
> + if ((status = ca->pub->read_cam_control(ca->pub, slot, CTRLIF_SIZE_HIGH)) < 0)
> + goto exit;
> + bytes_read = status << 8;
> + if ((status = ca->pub->read_cam_control(ca->pub, slot, CTRLIF_SIZE_LOW)) < 0)
> goto exit;
> + bytes_read |= status;
> +
> + /* check it will fit */
> + if (ebuf == NULL) {
> + if (bytes_read > ca->slot_info[slot].link_buf_size) {
> + pr_err("dvb_ca adapter %d: CAM tried to send a buffer larger than the link buffer size (%i > %i)!\n",
> + ca->dvbdev->adapter->num, bytes_read, ca->slot_info[slot].link_buf_size);
> + ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_LINKINIT;
> + status = -EIO;
> + goto exit;
> + }
> + if (bytes_read < 2) {
> + pr_err("dvb_ca adapter %d: CAM sent a buffer that was less than 2 bytes!\n",
> + ca->dvbdev->adapter->num);
> + ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_LINKINIT;
> + status = -EIO;
> + goto exit;
> + }
> + } else {
> + if (bytes_read > ecount) {
> + pr_err("dvb_ca adapter %d: CAM tried to send a buffer larger than the ecount size!\n",
> + ca->dvbdev->adapter->num);
> + status = -EIO;
> + goto exit;
> + }
> }
> - }
>
> - /* fill the buffer */
> - for (i = 0; i < bytes_read; i++) {
> - /* read byte and check */
> - if ((status = ca->pub->read_cam_control(ca->pub, slot, CTRLIF_DATA)) < 0)
> - goto exit;
> + /* fill the buffer */
> + for (i = 0; i < bytes_read; i++) {
> + /* read byte and check */
> + if ((status = ca->pub->read_cam_control(ca->pub, slot, CTRLIF_DATA)) < 0)
> + goto exit;
>
> - /* OK, store it in the buffer */
> - buf[i] = status;
> - }
> + /* OK, store it in the buffer */
> + buf[i] = status;
> + }
>
> - /* check for read error (RE should now be 0) */
> - if ((status = ca->pub->read_cam_control(ca->pub, slot, CTRLIF_STATUS)) < 0)
> - goto exit;
> - if (status & STATUSREG_RE) {
> - ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_LINKINIT;
> - status = -EIO;
> - goto exit;
> + /* check for read error (RE should now be 0) */
> + if ((status = ca->pub->read_cam_control(ca->pub, slot, CTRLIF_STATUS)) < 0)
> + goto exit;
> + if (status & STATUSREG_RE) {
> + ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_LINKINIT;
> + status = -EIO;
> + goto exit;
> + }
> }
>
> /* OK, add it to the receive buffer, or copy into external buffer if supplied */
> @@ -757,6 +769,9 @@ static int dvb_ca_en50221_write_data(struct dvb_ca_private *ca, int slot, u8 * b
> if (bytes_write > ca->slot_info[slot].link_buf_size)
> return -EINVAL;
>
> + if (ca->pub->write_data && (ca->slot_info[slot].slot_state != DVB_CA_SLOTSTATE_LINKINIT))
> + return ca->pub->write_data(ca->pub, slot, buf, bytes_write);
> +
> /* it is possible we are dealing with a single buffer implementation,
> thus if there is data available for read or if there is even a read
> already in progress, we do nothing but awake the kernel thread to
> diff --git a/drivers/media/dvb-core/dvb_ca_en50221.h b/drivers/media/dvb-core/dvb_ca_en50221.h
> index 1e4bbbd..82617ba 100644
> --- a/drivers/media/dvb-core/dvb_ca_en50221.h
> +++ b/drivers/media/dvb-core/dvb_ca_en50221.h
> @@ -41,6 +41,8 @@
> * @write_attribute_mem: function for writing attribute memory on the CAM
> * @read_cam_control: function for reading the control interface on the CAM
> * @write_cam_control: function for reading the control interface on the CAM
> + * @read_data: function for reading data (block mode)
> + * @write_data: function for writing data (block mode)
> * @slot_reset: function to reset the CAM slot
> * @slot_shutdown: function to shutdown a CAM slot
> * @slot_ts_enable: function to enable the Transport Stream on a CAM slot
> @@ -66,6 +68,11 @@ struct dvb_ca_en50221 {
> int (*write_cam_control)(struct dvb_ca_en50221 *ca,
> int slot, u8 address, u8 value);
>
> + int (*read_data)(struct dvb_ca_en50221 *ca,
> + int slot, u8 *ebuf, int ecount);
> + int (*write_data)(struct dvb_ca_en50221 *ca,
> + int slot, u8 *ebuf, int ecount);
> +
> int (*slot_reset)(struct dvb_ca_en50221 *ca, int slot);
> int (*slot_shutdown)(struct dvb_ca_en50221 *ca, int slot);
> int (*slot_ts_enable)(struct dvb_ca_en50221 *ca, int slot);
Thanks,
Mauro
Hello Mauro!
> Please check the patch with checkpatch.pl:
I am nearly finished with a V2 series of this set, where I partly changed
some of this issues.
We decided to split the monster thread function into a sub function to make it
more readable and also to overcome the 80 line length limit which gets even
worse because of the additional indention due to this patch.
See: https://www.spinics.net/lists/linux-media/msg116599.html
There you wrote:
The idea behind patch 04/11 makes sense to me. I'll review it carefully
after having everything applied.
Please re-send the first series, making sure that the authorship is
preserved.
I am nearly finished with the first series and THEN I plan to do parts of the
second series again including the splitting of the thread function.
BR,
Jasmin
Hello Mauro!
> We decided to split the monster thread function into a sub function to make
> it more readable and also to overcome the 80 line length limit ...
Sorry I mixed the patches. I will cleanup this patch to make checkpatch silent.
BR,
Jasmin
@@ -646,66 +646,78 @@ static int dvb_ca_en50221_read_data(struct dvb_ca_private *ca, int slot, u8 * eb
}
}
- /* check if there is data available */
- if ((status = ca->pub->read_cam_control(ca->pub, slot, CTRLIF_STATUS)) < 0)
- goto exit;
- if (!(status & STATUSREG_DA)) {
- /* no data */
- status = 0;
- goto exit;
- }
-
- /* read the amount of data */
- if ((status = ca->pub->read_cam_control(ca->pub, slot, CTRLIF_SIZE_HIGH)) < 0)
- goto exit;
- bytes_read = status << 8;
- if ((status = ca->pub->read_cam_control(ca->pub, slot, CTRLIF_SIZE_LOW)) < 0)
- goto exit;
- bytes_read |= status;
+ if (ca->pub->read_data && (ca->slot_info[slot].slot_state != DVB_CA_SLOTSTATE_LINKINIT)) {
+ if (ebuf == NULL)
+ status = ca->pub->read_data(ca->pub, slot, buf, sizeof(buf));
+ else
+ status = ca->pub->read_data(ca->pub, slot, buf, ecount);
+ if (status < 0)
+ return status;
+ bytes_read = status;
+ if (status == 0)
+ goto exit;
+ } else {
- /* check it will fit */
- if (ebuf == NULL) {
- if (bytes_read > ca->slot_info[slot].link_buf_size) {
- pr_err("dvb_ca adapter %d: CAM tried to send a buffer larger than the link buffer size (%i > %i)!\n",
- ca->dvbdev->adapter->num, bytes_read,
- ca->slot_info[slot].link_buf_size);
- ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_LINKINIT;
- status = -EIO;
+ /* check if there is data available */
+ if ((status = ca->pub->read_cam_control(ca->pub, slot, CTRLIF_STATUS)) < 0)
goto exit;
- }
- if (bytes_read < 2) {
- pr_err("dvb_ca adapter %d: CAM sent a buffer that was less than 2 bytes!\n",
- ca->dvbdev->adapter->num);
- ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_LINKINIT;
- status = -EIO;
+ if (!(status & STATUSREG_DA)) {
+ /* no data */
+ status = 0;
goto exit;
}
- } else {
- if (bytes_read > ecount) {
- pr_err("dvb_ca adapter %d: CAM tried to send a buffer larger than the ecount size!\n",
- ca->dvbdev->adapter->num);
- status = -EIO;
+
+ /* read the amount of data */
+ if ((status = ca->pub->read_cam_control(ca->pub, slot, CTRLIF_SIZE_HIGH)) < 0)
+ goto exit;
+ bytes_read = status << 8;
+ if ((status = ca->pub->read_cam_control(ca->pub, slot, CTRLIF_SIZE_LOW)) < 0)
goto exit;
+ bytes_read |= status;
+
+ /* check it will fit */
+ if (ebuf == NULL) {
+ if (bytes_read > ca->slot_info[slot].link_buf_size) {
+ pr_err("dvb_ca adapter %d: CAM tried to send a buffer larger than the link buffer size (%i > %i)!\n",
+ ca->dvbdev->adapter->num, bytes_read, ca->slot_info[slot].link_buf_size);
+ ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_LINKINIT;
+ status = -EIO;
+ goto exit;
+ }
+ if (bytes_read < 2) {
+ pr_err("dvb_ca adapter %d: CAM sent a buffer that was less than 2 bytes!\n",
+ ca->dvbdev->adapter->num);
+ ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_LINKINIT;
+ status = -EIO;
+ goto exit;
+ }
+ } else {
+ if (bytes_read > ecount) {
+ pr_err("dvb_ca adapter %d: CAM tried to send a buffer larger than the ecount size!\n",
+ ca->dvbdev->adapter->num);
+ status = -EIO;
+ goto exit;
+ }
}
- }
- /* fill the buffer */
- for (i = 0; i < bytes_read; i++) {
- /* read byte and check */
- if ((status = ca->pub->read_cam_control(ca->pub, slot, CTRLIF_DATA)) < 0)
- goto exit;
+ /* fill the buffer */
+ for (i = 0; i < bytes_read; i++) {
+ /* read byte and check */
+ if ((status = ca->pub->read_cam_control(ca->pub, slot, CTRLIF_DATA)) < 0)
+ goto exit;
- /* OK, store it in the buffer */
- buf[i] = status;
- }
+ /* OK, store it in the buffer */
+ buf[i] = status;
+ }
- /* check for read error (RE should now be 0) */
- if ((status = ca->pub->read_cam_control(ca->pub, slot, CTRLIF_STATUS)) < 0)
- goto exit;
- if (status & STATUSREG_RE) {
- ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_LINKINIT;
- status = -EIO;
- goto exit;
+ /* check for read error (RE should now be 0) */
+ if ((status = ca->pub->read_cam_control(ca->pub, slot, CTRLIF_STATUS)) < 0)
+ goto exit;
+ if (status & STATUSREG_RE) {
+ ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_LINKINIT;
+ status = -EIO;
+ goto exit;
+ }
}
/* OK, add it to the receive buffer, or copy into external buffer if supplied */
@@ -757,6 +769,9 @@ static int dvb_ca_en50221_write_data(struct dvb_ca_private *ca, int slot, u8 * b
if (bytes_write > ca->slot_info[slot].link_buf_size)
return -EINVAL;
+ if (ca->pub->write_data && (ca->slot_info[slot].slot_state != DVB_CA_SLOTSTATE_LINKINIT))
+ return ca->pub->write_data(ca->pub, slot, buf, bytes_write);
+
/* it is possible we are dealing with a single buffer implementation,
thus if there is data available for read or if there is even a read
already in progress, we do nothing but awake the kernel thread to
@@ -41,6 +41,8 @@
* @write_attribute_mem: function for writing attribute memory on the CAM
* @read_cam_control: function for reading the control interface on the CAM
* @write_cam_control: function for reading the control interface on the CAM
+ * @read_data: function for reading data (block mode)
+ * @write_data: function for writing data (block mode)
* @slot_reset: function to reset the CAM slot
* @slot_shutdown: function to shutdown a CAM slot
* @slot_ts_enable: function to enable the Transport Stream on a CAM slot
@@ -66,6 +68,11 @@ struct dvb_ca_en50221 {
int (*write_cam_control)(struct dvb_ca_en50221 *ca,
int slot, u8 address, u8 value);
+ int (*read_data)(struct dvb_ca_en50221 *ca,
+ int slot, u8 *ebuf, int ecount);
+ int (*write_data)(struct dvb_ca_en50221 *ca,
+ int slot, u8 *ebuf, int ecount);
+
int (*slot_reset)(struct dvb_ca_en50221 *ca, int slot);
int (*slot_shutdown)(struct dvb_ca_en50221 *ca, int slot);
int (*slot_ts_enable)(struct dvb_ca_en50221 *ca, int slot);