1
0
mirror of https://github.com/DigitalDevices/dddvb.git synced 2023-10-10 13:37:43 +02:00

adapt to mainline kernel version

This commit is contained in:
none 2020-01-16 10:53:26 +01:00
parent b3848a362d
commit 2610424e1c

View File

@ -1,3 +1,4 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/* /*
* dvb_ca.c: generic DVB functions for EN50221 CAM interfaces * dvb_ca.c: generic DVB functions for EN50221 CAM interfaces
* *
@ -11,18 +12,6 @@
* *
* Copyright (C) 1999-2002 Ralph Metzler * Copyright (C) 1999-2002 Ralph Metzler
* & Marcus Metzler for convergence integrated media GmbH * & Marcus Metzler for convergence integrated media GmbH
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* To obtain the license, point your browser to
* http://www.gnu.org/copyleft/gpl.html
*/ */
#define pr_fmt(fmt) "dvb_ca_en50221: " fmt #define pr_fmt(fmt) "dvb_ca_en50221: " fmt
@ -31,10 +20,13 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/list.h> #include <linux/list.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/version.h>
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 18))
#include <linux/nospec.h>
#endif
#include <linux/vmalloc.h> #include <linux/vmalloc.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/spinlock.h> #include <linux/spinlock.h>
#include <linux/version.h>
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0)) #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0))
#include <linux/sched/signal.h> #include <linux/sched/signal.h>
#else #else
@ -211,7 +203,7 @@ static int dvb_ca_en50221_write_data(struct dvb_ca_private *ca, int slot,
* @hlen: Number of bytes in haystack. * @hlen: Number of bytes in haystack.
* @needle: Buffer to find. * @needle: Buffer to find.
* @nlen: Number of bytes in needle. * @nlen: Number of bytes in needle.
* @return Pointer into haystack needle was found at, or NULL if not found. * return: Pointer into haystack needle was found at, or NULL if not found.
*/ */
static char *findstr(char *haystack, int hlen, char *needle, int nlen) static char *findstr(char *haystack, int hlen, char *needle, int nlen)
{ {
@ -231,7 +223,7 @@ static char *findstr(char *haystack, int hlen, char *needle, int nlen)
/* ************************************************************************** */ /* ************************************************************************** */
/* EN50221 physical interface functions */ /* EN50221 physical interface functions */
/** /*
* dvb_ca_en50221_check_camstatus - Check CAM status. * dvb_ca_en50221_check_camstatus - Check CAM status.
*/ */
static int dvb_ca_en50221_check_camstatus(struct dvb_ca_private *ca, int slot) static int dvb_ca_en50221_check_camstatus(struct dvb_ca_private *ca, int slot)
@ -280,9 +272,9 @@ static int dvb_ca_en50221_check_camstatus(struct dvb_ca_private *ca, int slot)
* @ca: CA instance. * @ca: CA instance.
* @slot: Slot on interface. * @slot: Slot on interface.
* @waitfor: Flags to wait for. * @waitfor: Flags to wait for.
* @timeout_ms: Timeout in milliseconds. * @timeout_hz: Timeout in milliseconds.
* *
* @return 0 on success, nonzero on error. * return: 0 on success, nonzero on error.
*/ */
static int dvb_ca_en50221_wait_if_status(struct dvb_ca_private *ca, int slot, static int dvb_ca_en50221_wait_if_status(struct dvb_ca_private *ca, int slot,
u8 waitfor, int timeout_hz) u8 waitfor, int timeout_hz)
@ -330,7 +322,7 @@ static int dvb_ca_en50221_wait_if_status(struct dvb_ca_private *ca, int slot,
* @ca: CA instance. * @ca: CA instance.
* @slot: Slot id. * @slot: Slot id.
* *
* @return 0 on success, nonzero on failure. * return: 0 on success, nonzero on failure.
*/ */
static int dvb_ca_en50221_link_init(struct dvb_ca_private *ca, int slot) static int dvb_ca_en50221_link_init(struct dvb_ca_private *ca, int slot)
{ {
@ -402,11 +394,11 @@ static int dvb_ca_en50221_link_init(struct dvb_ca_private *ca, int slot)
* @ca: CA instance. * @ca: CA instance.
* @slot: Slot id. * @slot: Slot id.
* @address: Address to read from. Updated. * @address: Address to read from. Updated.
* @tupleType: Tuple id byte. Updated. * @tuple_type: Tuple id byte. Updated.
* @tupleLength: Tuple length. Updated. * @tuple_length: Tuple length. Updated.
* @tuple: Dest buffer for tuple (must be 256 bytes). Updated. * @tuple: Dest buffer for tuple (must be 256 bytes). Updated.
* *
* @return 0 on success, nonzero on error. * return: 0 on success, nonzero on error.
*/ */
static int dvb_ca_en50221_read_tuple(struct dvb_ca_private *ca, int slot, static int dvb_ca_en50221_read_tuple(struct dvb_ca_private *ca, int slot,
int *address, int *tuple_type, int *address, int *tuple_type,
@ -460,7 +452,7 @@ static int dvb_ca_en50221_read_tuple(struct dvb_ca_private *ca, int slot,
* @ca: CA instance. * @ca: CA instance.
* @slot: Slot id. * @slot: Slot id.
* *
* @return 0 on success, <0 on failure. * return: 0 on success, <0 on failure.
*/ */
static int dvb_ca_en50221_parse_attributes(struct dvb_ca_private *ca, int slot) static int dvb_ca_en50221_parse_attributes(struct dvb_ca_private *ca, int slot)
{ {
@ -637,10 +629,11 @@ static int dvb_ca_en50221_set_configoption(struct dvb_ca_private *ca, int slot)
* @ca: CA instance. * @ca: CA instance.
* @slot: Slot to read from. * @slot: Slot to read from.
* @ebuf: If non-NULL, the data will be written to this buffer. If NULL, * @ebuf: If non-NULL, the data will be written to this buffer. If NULL,
* the data will be added into the buffering system as a normal fragment. * the data will be added into the buffering system as a normal
* fragment.
* @ecount: Size of ebuf. Ignored if ebuf is NULL. * @ecount: Size of ebuf. Ignored if ebuf is NULL.
* *
* @return Number of bytes read, or < 0 on error * return: Number of bytes read, or < 0 on error
*/ */
static int dvb_ca_en50221_read_data(struct dvb_ca_private *ca, int slot, static int dvb_ca_en50221_read_data(struct dvb_ca_private *ca, int slot,
u8 *ebuf, int ecount) u8 *ebuf, int ecount)
@ -789,11 +782,11 @@ exit:
* *
* @ca: CA instance. * @ca: CA instance.
* @slot: Slot to write to. * @slot: Slot to write to.
* @ebuf: The data in this buffer is treated as a complete link-level packet to * @buf: The data in this buffer is treated as a complete link-level packet to
* be written. * be written.
* @count: Size of ebuf. * @bytes_write: Size of ebuf.
* *
* @return Number of bytes written, or < 0 on error. * return: Number of bytes written, or < 0 on error.
*/ */
static int dvb_ca_en50221_write_data(struct dvb_ca_private *ca, int slot, static int dvb_ca_en50221_write_data(struct dvb_ca_private *ca, int slot,
u8 *buf, int bytes_write) u8 *buf, int bytes_write)
@ -938,7 +931,7 @@ static int dvb_ca_en50221_slot_shutdown(struct dvb_ca_private *ca, int slot)
/** /**
* dvb_ca_en50221_camchange_irq - A CAMCHANGE IRQ has occurred. * dvb_ca_en50221_camchange_irq - A CAMCHANGE IRQ has occurred.
* *
* @ca: CA instance. * @pubca: CA instance.
* @slot: Slot concerned. * @slot: Slot concerned.
* @change_type: One of the DVB_CA_CAMCHANGE_* values. * @change_type: One of the DVB_CA_CAMCHANGE_* values.
*/ */
@ -968,7 +961,7 @@ EXPORT_SYMBOL(dvb_ca_en50221_camchange_irq);
/** /**
* dvb_ca_en50221_camready_irq - A CAMREADY IRQ has occurred. * dvb_ca_en50221_camready_irq - A CAMREADY IRQ has occurred.
* *
* @ca: CA instance. * @pubca: CA instance.
* @slot: Slot concerned. * @slot: Slot concerned.
*/ */
void dvb_ca_en50221_camready_irq(struct dvb_ca_en50221 *pubca, int slot) void dvb_ca_en50221_camready_irq(struct dvb_ca_en50221 *pubca, int slot)
@ -988,7 +981,7 @@ EXPORT_SYMBOL(dvb_ca_en50221_camready_irq);
/** /**
* dvb_ca_en50221_frda_irq - An FR or DA IRQ has occurred. * dvb_ca_en50221_frda_irq - An FR or DA IRQ has occurred.
* *
* @ca: CA instance. * @pubca: CA instance.
* @slot: Slot concerned. * @slot: Slot concerned.
*/ */
void dvb_ca_en50221_frda_irq(struct dvb_ca_en50221 *pubca, int slot) void dvb_ca_en50221_frda_irq(struct dvb_ca_en50221 *pubca, int slot)
@ -1096,7 +1089,7 @@ static void dvb_ca_en50221_thread_update_delay(struct dvb_ca_private *ca)
* *
* @ca: CA instance. * @ca: CA instance.
* @slot: Slot to process. * @slot: Slot to process.
* @return: 0 .. no change * return:: 0 .. no change
* 1 .. CAM state changed * 1 .. CAM state changed
*/ */
@ -1274,7 +1267,7 @@ static void dvb_ca_en50221_thread_state_machine(struct dvb_ca_private *ca,
ca->pub->slot_ts_enable(ca->pub, slot); ca->pub->slot_ts_enable(ca->pub, slot);
sl->slot_state = DVB_CA_SLOTSTATE_RUNNING; sl->slot_state = DVB_CA_SLOTSTATE_RUNNING;
dvb_ca_en50221_thread_update_delay(ca); dvb_ca_en50221_thread_update_delay(ca);
pr_err("dvb_ca adapter %d: DVB CAM detected and initialised successfully\n", pr_info("dvb_ca adapter %d: DVB CAM detected and initialised successfully\n",
ca->dvbdev->adapter->num); ca->dvbdev->adapter->num);
break; break;
@ -1317,7 +1310,7 @@ static void dvb_ca_en50221_thread_state_machine(struct dvb_ca_private *ca,
mutex_unlock(&sl->slot_lock); mutex_unlock(&sl->slot_lock);
} }
/** /*
* Kernel thread which monitors CA slots for CAM changes, and performs data * Kernel thread which monitors CA slots for CAM changes, and performs data
* transfers. * transfers.
*/ */
@ -1357,12 +1350,11 @@ static int dvb_ca_en50221_thread(void *data)
* Real ioctl implementation. * Real ioctl implementation.
* NOTE: CA_SEND_MSG/CA_GET_MSG ioctls have userspace buffers passed to them. * NOTE: CA_SEND_MSG/CA_GET_MSG ioctls have userspace buffers passed to them.
* *
* @inode: Inode concerned.
* @file: File concerned. * @file: File concerned.
* @cmd: IOCTL command. * @cmd: IOCTL command.
* @arg: Associated argument. * @parg: Associated argument.
* *
* @return 0 on success, <0 on error. * return: 0 on success, <0 on error.
*/ */
static int dvb_ca_en50221_io_do_ioctl(struct file *file, static int dvb_ca_en50221_io_do_ioctl(struct file *file,
unsigned int cmd, void *parg) unsigned int cmd, void *parg)
@ -1411,7 +1403,7 @@ static int dvb_ca_en50221_io_do_ioctl(struct file *file,
struct dvb_ca_slot *sl; struct dvb_ca_slot *sl;
slot = info->num; slot = info->num;
if ((slot > ca->slot_count) || (slot < 0)) { if ((slot >= ca->slot_count) || (slot < 0)) {
err = -EINVAL; err = -EINVAL;
goto out_unlock; goto out_unlock;
} }
@ -1441,12 +1433,11 @@ out_unlock:
/** /**
* Wrapper for ioctl implementation. * Wrapper for ioctl implementation.
* *
* @inode: Inode concerned.
* @file: File concerned. * @file: File concerned.
* @cmd: IOCTL command. * @cmd: IOCTL command.
* @arg: Associated argument. * @arg: Associated argument.
* *
* @return 0 on success, <0 on error. * return: 0 on success, <0 on error.
*/ */
static long dvb_ca_en50221_io_ioctl(struct file *file, static long dvb_ca_en50221_io_ioctl(struct file *file,
unsigned int cmd, unsigned long arg) unsigned int cmd, unsigned long arg)
@ -1462,7 +1453,7 @@ static long dvb_ca_en50221_io_ioctl(struct file *file,
* @count: Size of source buffer. * @count: Size of source buffer.
* @ppos: Position in file (ignored). * @ppos: Position in file (ignored).
* *
* @return Number of bytes read, or <0 on error. * return: Number of bytes read, or <0 on error.
*/ */
static ssize_t dvb_ca_en50221_io_write(struct file *file, static ssize_t dvb_ca_en50221_io_write(struct file *file,
const char __user *buf, size_t count, const char __user *buf, size_t count,
@ -1495,6 +1486,11 @@ static ssize_t dvb_ca_en50221_io_write(struct file *file,
return -EFAULT; return -EFAULT;
buf += 2; buf += 2;
count -= 2; count -= 2;
if (slot >= ca->slot_count)
return -EINVAL;
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 18))
slot = array_index_nospec(slot, ca->slot_count);
#endif
sl = &ca->slot_info[slot]; sl = &ca->slot_info[slot];
/* check if the slot is actually running */ /* check if the slot is actually running */
@ -1557,7 +1553,7 @@ exit:
return status; return status;
} }
/** /*
* Condition for waking up in dvb_ca_en50221_io_read_condition * Condition for waking up in dvb_ca_en50221_io_read_condition
*/ */
static int dvb_ca_en50221_io_read_condition(struct dvb_ca_private *ca, static int dvb_ca_en50221_io_read_condition(struct dvb_ca_private *ca,
@ -1614,7 +1610,7 @@ nextslot:
* @count: Size of destination buffer. * @count: Size of destination buffer.
* @ppos: Position in file (ignored). * @ppos: Position in file (ignored).
* *
* @return Number of bytes read, or <0 on error. * return: Number of bytes read, or <0 on error.
*/ */
static ssize_t dvb_ca_en50221_io_read(struct file *file, char __user *buf, static ssize_t dvb_ca_en50221_io_read(struct file *file, char __user *buf,
size_t count, loff_t *ppos) size_t count, loff_t *ppos)
@ -1723,7 +1719,7 @@ exit:
* @inode: Inode concerned. * @inode: Inode concerned.
* @file: File concerned. * @file: File concerned.
* *
* @return 0 on success, <0 on failure. * return: 0 on success, <0 on failure.
*/ */
static int dvb_ca_en50221_io_open(struct inode *inode, struct file *file) static int dvb_ca_en50221_io_open(struct inode *inode, struct file *file)
{ {
@ -1773,7 +1769,7 @@ static int dvb_ca_en50221_io_open(struct inode *inode, struct file *file)
* @inode: Inode concerned. * @inode: Inode concerned.
* @file: File concerned. * @file: File concerned.
* *
* @return 0 on success, <0 on failure. * return: 0 on success, <0 on failure.
*/ */
static int dvb_ca_en50221_io_release(struct inode *inode, struct file *file) static int dvb_ca_en50221_io_release(struct inode *inode, struct file *file)
{ {
@ -1802,30 +1798,33 @@ static int dvb_ca_en50221_io_release(struct inode *inode, struct file *file)
* @file: File concerned. * @file: File concerned.
* @wait: poll wait table. * @wait: poll wait table.
* *
* @return Standard poll mask. * return: Standard poll mask.
*/ */
static unsigned int dvb_ca_en50221_io_poll(struct file *file, poll_table *wait) #if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 16, 0))
typedef unsigned int __poll_t;
#define EPOLLIN POLLIN
#endif
static __poll_t dvb_ca_en50221_io_poll(struct file *file, poll_table *wait)
{ {
struct dvb_device *dvbdev = file->private_data; struct dvb_device *dvbdev = file->private_data;
struct dvb_ca_private *ca = dvbdev->priv; struct dvb_ca_private *ca = dvbdev->priv;
unsigned int mask = 0; __poll_t mask = 0;
int slot; int slot;
int result = 0; int result = 0;
dprintk("%s\n", __func__); dprintk("%s\n", __func__);
poll_wait(file, &ca->wait_queue, wait);
if (dvb_ca_en50221_io_read_condition(ca, &result, &slot) == 1) if (dvb_ca_en50221_io_read_condition(ca, &result, &slot) == 1)
mask |= POLLIN; mask |= EPOLLIN;
/* if there is something, return now */ /* if there is something, return now */
if (mask) if (mask)
return mask; return mask;
/* wait for something to happen */
poll_wait(file, &ca->wait_queue, wait);
if (dvb_ca_en50221_io_read_condition(ca, &result, &slot) == 1) if (dvb_ca_en50221_io_read_condition(ca, &result, &slot) == 1)
mask |= POLLIN; mask |= EPOLLIN;
return mask; return mask;
} }
@ -1859,11 +1858,11 @@ static const struct dvb_device dvbdev_ca = {
* Initialise a new DVB CA EN50221 interface device. * Initialise a new DVB CA EN50221 interface device.
* *
* @dvb_adapter: DVB adapter to attach the new CA device to. * @dvb_adapter: DVB adapter to attach the new CA device to.
* @ca: The dvb_ca instance. * @pubca: The dvb_ca instance.
* @flags: Flags describing the CA device (DVB_CA_FLAG_*). * @flags: Flags describing the CA device (DVB_CA_FLAG_*).
* @slot_count: Number of slots supported. * @slot_count: Number of slots supported.
* *
* @return 0 on success, nonzero on failure * return: 0 on success, nonzero on failure
*/ */
int dvb_ca_en50221_init(struct dvb_adapter *dvb_adapter, int dvb_ca_en50221_init(struct dvb_adapter *dvb_adapter,
struct dvb_ca_en50221 *pubca, int flags, int slot_count) struct dvb_ca_en50221 *pubca, int flags, int slot_count)
@ -1950,8 +1949,7 @@ EXPORT_SYMBOL(dvb_ca_en50221_init);
/** /**
* Release a DVB CA EN50221 interface device. * Release a DVB CA EN50221 interface device.
* *
* @ca_dev: The dvb_device_t instance for the CA device. * @pubca: The associated dvb_ca instance.
* @ca: The associated dvb_ca instance.
*/ */
void dvb_ca_en50221_release(struct dvb_ca_en50221 *pubca) void dvb_ca_en50221_release(struct dvb_ca_en50221 *pubca)
{ {