// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * dvb_ca.c: generic DVB functions for EN50221 CAM interfaces
 *
 * Copyright (C) 2004 Andrew de Quincey
 *
 * Parts of this file were based on sources as follows:
 *
 * Copyright (C) 2003 Ralph Metzler <rjkm@metzlerbros.de>
 *
 * based on code:
 *
 * Copyright (C) 1999-2002 Ralph  Metzler
 *                       & Marcus Metzler for convergence integrated media GmbH
 */

#define pr_fmt(fmt) "dvb_ca_en50221: " fmt

#include <linux/errno.h>
#include <linux/slab.h>
#include <linux/list.h>
#include <linux/module.h>
#include <linux/nospec.h>
#include <linux/vmalloc.h>
#include <linux/delay.h>
#include <linux/spinlock.h>
#include <linux/sched/signal.h>
#include <linux/kthread.h>

#include <media/dvb_ca_en50221.h>
#include <media/dvb_ringbuffer.h>

static int dvb_ca_en50221_debug;

module_param_named(cam_debug, dvb_ca_en50221_debug, int, 0644);
MODULE_PARM_DESC(cam_debug, "enable verbose debug messages");

#define dprintk(fmt, arg...) do {					\
	if (dvb_ca_en50221_debug)					\
		printk(KERN_DEBUG pr_fmt("%s: " fmt), __func__, ##arg);\
} while (0)

#define INIT_TIMEOUT_SECS 10

#define HOST_LINK_BUF_SIZE 0x200

#define RX_BUFFER_SIZE 65535

#define MAX_RX_PACKETS_PER_ITERATION 10

#define CTRLIF_DATA      0
#define CTRLIF_COMMAND   1
#define CTRLIF_STATUS    1
#define CTRLIF_SIZE_LOW  2
#define CTRLIF_SIZE_HIGH 3

#define CMDREG_HC        1	/* Host control */
#define CMDREG_SW        2	/* Size write */
#define CMDREG_SR        4	/* Size read */
#define CMDREG_RS        8	/* Reset interface */
#define CMDREG_FRIE   0x40	/* Enable FR interrupt */
#define CMDREG_DAIE   0x80	/* Enable DA interrupt */
#define IRQEN (CMDREG_DAIE)

#define STATUSREG_RE     1	/* read error */
#define STATUSREG_WE     2	/* write error */
#define STATUSREG_FR  0x40	/* module free */
#define STATUSREG_DA  0x80	/* data available */

#define DVB_CA_SLOTSTATE_NONE           0
#define DVB_CA_SLOTSTATE_UNINITIALISED  1
#define DVB_CA_SLOTSTATE_RUNNING        2
#define DVB_CA_SLOTSTATE_INVALID        3
#define DVB_CA_SLOTSTATE_WAITREADY      4
#define DVB_CA_SLOTSTATE_VALIDATE       5
#define DVB_CA_SLOTSTATE_WAITFR         6
#define DVB_CA_SLOTSTATE_LINKINIT       7

/* Information on a CA slot */
struct dvb_ca_slot {
	/* current state of the CAM */
	int slot_state;

	/* mutex used for serializing access to one CI slot */
	struct mutex slot_lock;

	/* Number of CAMCHANGES that have occurred since last processing */
	atomic_t camchange_count;

	/* Type of last CAMCHANGE */
	int camchange_type;

	/* base address of CAM config */
	u32 config_base;

	/* value to write into Config Control register */
	u8 config_option;

	/* if 1, the CAM supports DA IRQs */
	u8 da_irq_supported:1;

	/* size of the buffer to use when talking to the CAM */
	int link_buf_size;

	/* buffer for incoming packets */
	struct dvb_ringbuffer rx_buffer;

	/* timer used during various states of the slot */
	unsigned long timeout;
};

/* Private CA-interface information */
struct dvb_ca_private {
	struct kref refcount;

	/* pointer back to the public data structure */
	struct dvb_ca_en50221 *pub;

	/* the DVB device */
	struct dvb_device *dvbdev;

	/* Flags describing the interface (DVB_CA_FLAG_*) */
	u32 flags;

	/* number of slots supported by this CA interface */
	unsigned int slot_count;

	/* information on each slot */
	struct dvb_ca_slot *slot_info;

	/* wait queues for read() and write() operations */
	wait_queue_head_t wait_queue;

	/* PID of the monitoring thread */
	struct task_struct *thread;

	/* Flag indicating if the CA device is open */
	unsigned int open:1;

	/* Flag indicating the thread should wake up now */
	unsigned int wakeup:1;

	/* Delay the main thread should use */
	unsigned long delay;

	/*
	 * Slot to start looking for data to read from in the next user-space
	 * read operation
	 */
	int next_read_slot;

	/* mutex serializing ioctls */
	struct mutex ioctl_mutex;
};

static void dvb_ca_private_free(struct dvb_ca_private *ca)
{
	unsigned int i;

	dvb_free_device(ca->dvbdev);
	for (i = 0; i < ca->slot_count; i++)
		vfree(ca->slot_info[i].rx_buffer.data);

	kfree(ca->slot_info);
	kfree(ca);
}

static void dvb_ca_private_release(struct kref *ref)
{
	struct dvb_ca_private *ca;

	ca = container_of(ref, struct dvb_ca_private, refcount);
	dvb_ca_private_free(ca);
}

static void dvb_ca_private_get(struct dvb_ca_private *ca)
{
	kref_get(&ca->refcount);
}

static void dvb_ca_private_put(struct dvb_ca_private *ca)
{
	kref_put(&ca->refcount, dvb_ca_private_release);
}

static void dvb_ca_en50221_thread_wakeup(struct dvb_ca_private *ca);
static int dvb_ca_en50221_read_data(struct dvb_ca_private *ca, int slot,
				    u8 *ebuf, int ecount);
static int dvb_ca_en50221_write_data(struct dvb_ca_private *ca, int slot,
				     u8 *ebuf, int ecount);

/**
 * findstr - Safely find needle in haystack.
 *
 * @haystack: Buffer to look in.
 * @hlen: Number of bytes in haystack.
 * @needle: Buffer to find.
 * @nlen: Number of bytes in needle.
 * return: Pointer into haystack needle was found at, or NULL if not found.
 */
static char *findstr(char *haystack, int hlen, char *needle, int nlen)
{
	int i;

	if (hlen < nlen)
		return NULL;

	for (i = 0; i <= hlen - nlen; i++) {
		if (!strncmp(haystack + i, needle, nlen))
			return haystack + i;
	}

	return NULL;
}

/* ************************************************************************** */
/* EN50221 physical interface functions */

/*
 * dvb_ca_en50221_check_camstatus - Check CAM status.
 */
static int dvb_ca_en50221_check_camstatus(struct dvb_ca_private *ca, int slot)
{
	struct dvb_ca_slot *sl = &ca->slot_info[slot];
	int slot_status;
	int cam_present_now;
	int cam_changed;

	/* IRQ mode */
	if (ca->flags & DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE)
		return (atomic_read(&sl->camchange_count) != 0);

	/* poll mode */
	slot_status = ca->pub->poll_slot_status(ca->pub, slot, ca->open);

	cam_present_now = (slot_status & DVB_CA_EN50221_POLL_CAM_PRESENT) ? 1 : 0;
	cam_changed = (slot_status & DVB_CA_EN50221_POLL_CAM_CHANGED) ? 1 : 0;
	if (!cam_changed) {
		int cam_present_old = (sl->slot_state != DVB_CA_SLOTSTATE_NONE);

		cam_changed = (cam_present_now != cam_present_old);
	}

	if (cam_changed) {
		if (!cam_present_now)
			sl->camchange_type = DVB_CA_EN50221_CAMCHANGE_REMOVED;
		else
			sl->camchange_type = DVB_CA_EN50221_CAMCHANGE_INSERTED;
		atomic_set(&sl->camchange_count, 1);
	} else {
		if ((sl->slot_state == DVB_CA_SLOTSTATE_WAITREADY) &&
		    (slot_status & DVB_CA_EN50221_POLL_CAM_READY)) {
			/* move to validate state if reset is completed */
			sl->slot_state = DVB_CA_SLOTSTATE_VALIDATE;
		}
	}

	return cam_changed;
}

/**
 * dvb_ca_en50221_wait_if_status - Wait for flags to become set on the STATUS
 *	 register on a CAM interface, checking for errors and timeout.
 *
 * @ca: CA instance.
 * @slot: Slot on interface.
 * @waitfor: Flags to wait for.
 * @timeout_hz: Timeout in milliseconds.
 *
 * return: 0 on success, nonzero on error.
 */
static int dvb_ca_en50221_wait_if_status(struct dvb_ca_private *ca, int slot,
					 u8 waitfor, int timeout_hz)
{
	unsigned long timeout;
	unsigned long start;

	dprintk("%s\n", __func__);

	/* loop until timeout elapsed */
	start = jiffies;
	timeout = jiffies + timeout_hz;
	while (1) {
		int res;

		/* read the status and check for error */
		res = ca->pub->read_cam_control(ca->pub, slot, CTRLIF_STATUS);
		if (res < 0)
			return -EIO;

		/* if we got the flags, it was successful! */
		if (res & waitfor) {
			dprintk("%s succeeded timeout:%lu\n",
				__func__, jiffies - start);
			return 0;
		}

		/* check for timeout */
		if (time_after(jiffies, timeout))
			break;

		/* wait for a bit */
		usleep_range(1000, 1100);
	}

	dprintk("%s failed timeout:%lu\n", __func__, jiffies - start);

	/* if we get here, we've timed out */
	return -ETIMEDOUT;
}

/**
 * dvb_ca_en50221_link_init - Initialise the link layer connection to a CAM.
 *
 * @ca: CA instance.
 * @slot: Slot id.
 *
 * return: 0 on success, nonzero on failure.
 */
static int dvb_ca_en50221_link_init(struct dvb_ca_private *ca, int slot)
{
	struct dvb_ca_slot *sl = &ca->slot_info[slot];
	int ret;
	int buf_size;
	u8 buf[2];

	dprintk("%s\n", __func__);

	/* we'll be determining these during this function */
	sl->da_irq_supported = 0;

	/*
	 * set the host link buffer size temporarily. it will be overwritten
	 * with the real negotiated size later.
	 */
	sl->link_buf_size = 2;

	/* read the buffer size from the CAM */
	ret = ca->pub->write_cam_control(ca->pub, slot, CTRLIF_COMMAND,
					 IRQEN | CMDREG_SR);
	if (ret)
		return ret;
	ret = dvb_ca_en50221_wait_if_status(ca, slot, STATUSREG_DA, HZ);
	if (ret)
		return ret;
	ret = dvb_ca_en50221_read_data(ca, slot, buf, 2);
	if (ret != 2)
		return -EIO;
	ret = ca->pub->write_cam_control(ca->pub, slot, CTRLIF_COMMAND, IRQEN);
	if (ret)
		return ret;

	/*
	 * store it, and choose the minimum of our buffer and the CAM's buffer
	 * size
	 */
	buf_size = (buf[0] << 8) | buf[1];
	if (buf_size > HOST_LINK_BUF_SIZE)
		buf_size = HOST_LINK_BUF_SIZE;
	sl->link_buf_size = buf_size;
	buf[0] = buf_size >> 8;
	buf[1] = buf_size & 0xff;
	dprintk("Chosen link buffer size of %i\n", buf_size);

	/* write the buffer size to the CAM */
	ret = ca->pub->write_cam_control(ca->pub, slot, CTRLIF_COMMAND,
					 IRQEN | CMDREG_SW);
	if (ret)
		return ret;
	ret = dvb_ca_en50221_wait_if_status(ca, slot, STATUSREG_FR, HZ / 10);
	if (ret)
		return ret;
	ret = dvb_ca_en50221_write_data(ca, slot, buf, 2);
	if (ret != 2)
		return -EIO;
	ret = ca->pub->write_cam_control(ca->pub, slot, CTRLIF_COMMAND, IRQEN);
	if (ret)
		return ret;

	/* success */
	return 0;
}

/**
 * dvb_ca_en50221_read_tuple - Read a tuple from attribute memory.
 *
 * @ca: CA instance.
 * @slot: Slot id.
 * @address: Address to read from. Updated.
 * @tuple_type: Tuple id byte. Updated.
 * @tuple_length: Tuple length. Updated.
 * @tuple: Dest buffer for tuple (must be 256 bytes). Updated.
 *
 * return: 0 on success, nonzero on error.
 */
static int dvb_ca_en50221_read_tuple(struct dvb_ca_private *ca, int slot,
				     int *address, int *tuple_type,
				     int *tuple_length, u8 *tuple)
{
	int i;
	int _tuple_type;
	int _tuple_length;
	int _address = *address;

	/* grab the next tuple length and type */
	_tuple_type = ca->pub->read_attribute_mem(ca->pub, slot, _address);
	if (_tuple_type < 0)
		return _tuple_type;
	if (_tuple_type == 0xff) {
		dprintk("END OF CHAIN TUPLE type:0x%x\n", _tuple_type);
		*address += 2;
		*tuple_type = _tuple_type;
		*tuple_length = 0;
		return 0;
	}
	_tuple_length = ca->pub->read_attribute_mem(ca->pub, slot,
						    _address + 2);
	if (_tuple_length < 0)
		return _tuple_length;
	_address += 4;

	dprintk("TUPLE type:0x%x length:%i\n", _tuple_type, _tuple_length);

	/* read in the whole tuple */
	for (i = 0; i < _tuple_length; i++) {
		tuple[i] = ca->pub->read_attribute_mem(ca->pub, slot,
						       _address + (i * 2));
		dprintk("  0x%02x: 0x%02x %c\n",
			i, tuple[i] & 0xff,
			((tuple[i] > 31) && (tuple[i] < 127)) ? tuple[i] : '.');
	}
	_address += (_tuple_length * 2);

	/* success */
	*tuple_type = _tuple_type;
	*tuple_length = _tuple_length;
	*address = _address;
	return 0;
}

/**
 * dvb_ca_en50221_parse_attributes - Parse attribute memory of a CAM module,
 *	extracting Config register, and checking it is a DVB CAM module.
 *
 * @ca: CA instance.
 * @slot: Slot id.
 *
 * return: 0 on success, <0 on failure.
 */
static int dvb_ca_en50221_parse_attributes(struct dvb_ca_private *ca, int slot)
{
	struct dvb_ca_slot *sl;
	int address = 0;
	int tuple_length;
	int tuple_type;
	u8 tuple[257];
	char *dvb_str;
	int rasz;
	int status;
	int got_cftableentry = 0;
	int end_chain = 0;
	int i;
	u16 manfid = 0;
	u16 devid = 0;

	/* CISTPL_DEVICE_0A */
	status = dvb_ca_en50221_read_tuple(ca, slot, &address, &tuple_type,
					   &tuple_length, tuple);
	if (status < 0)
		return status;
	if (tuple_type != 0x1D)
		return -EINVAL;

	/* CISTPL_DEVICE_0C */
	status = dvb_ca_en50221_read_tuple(ca, slot, &address, &tuple_type,
					   &tuple_length, tuple);
	if (status < 0)
		return status;
	if (tuple_type != 0x1C)
		return -EINVAL;

	/* CISTPL_VERS_1 */
	status = dvb_ca_en50221_read_tuple(ca, slot, &address, &tuple_type,
					   &tuple_length, tuple);
	if (status < 0)
		return status;
	if (tuple_type != 0x15)
		return -EINVAL;

	/* CISTPL_MANFID */
	status = dvb_ca_en50221_read_tuple(ca, slot, &address, &tuple_type,
					   &tuple_length, tuple);
	if (status < 0)
		return status;
	if (tuple_type != 0x20)
		return -EINVAL;
	if (tuple_length != 4)
		return -EINVAL;
	manfid = (tuple[1] << 8) | tuple[0];
	devid = (tuple[3] << 8) | tuple[2];

	/* CISTPL_CONFIG */
	status = dvb_ca_en50221_read_tuple(ca, slot, &address, &tuple_type,
					   &tuple_length, tuple);
	if (status < 0)
		return status;
	if (tuple_type != 0x1A)
		return -EINVAL;
	if (tuple_length < 3)
		return -EINVAL;

	/* extract the configbase */
	rasz = tuple[0] & 3;
	if (tuple_length < (3 + rasz + 14))
		return -EINVAL;
	sl = &ca->slot_info[slot];
	sl->config_base = 0;
	for (i = 0; i < rasz + 1; i++)
		sl->config_base |= (tuple[2 + i] << (8 * i));

	/* check it contains the correct DVB string */
	dvb_str = findstr((char *)tuple, tuple_length, "DVB_CI_V", 8);
	if (!dvb_str)
		return -EINVAL;
	if (tuple_length < ((dvb_str - (char *)tuple) + 12))
		return -EINVAL;

	/* is it a version we support? */
	if (strncmp(dvb_str + 8, "1.00", 4)) {
		pr_err("dvb_ca adapter %d: Unsupported DVB CAM module version %c%c%c%c\n",
		       ca->dvbdev->adapter->num, dvb_str[8], dvb_str[9],
		       dvb_str[10], dvb_str[11]);
		return -EINVAL;
	}

	/* process the CFTABLE_ENTRY tuples, and any after those */
	while ((!end_chain) && (address < 0x1000)) {
		status = dvb_ca_en50221_read_tuple(ca, slot, &address,
						   &tuple_type, &tuple_length,
						   tuple);
		if (status < 0)
			return status;
		switch (tuple_type) {
		case 0x1B:	/* CISTPL_CFTABLE_ENTRY */
			if (tuple_length < (2 + 11 + 17))
				break;

			/* if we've already parsed one, just use it */
			if (got_cftableentry)
				break;

			/* get the config option */
			sl->config_option = tuple[0] & 0x3f;

			/* OK, check it contains the correct strings */
			if (!findstr((char *)tuple, tuple_length,
				     "DVB_HOST", 8) ||
			    !findstr((char *)tuple, tuple_length,
				     "DVB_CI_MODULE", 13))
				break;

			got_cftableentry = 1;
			break;

		case 0x14:	/* CISTPL_NO_LINK */
			break;

		case 0xFF:	/* CISTPL_END */
			end_chain = 1;
			break;

		default:	/* Unknown tuple type - just skip this tuple */
			dprintk("dvb_ca: Skipping unknown tuple type:0x%x length:0x%x\n",
				tuple_type, tuple_length);
			break;
		}
	}

	if ((address > 0x1000) || (!got_cftableentry))
		return -EINVAL;

	dprintk("Valid DVB CAM detected MANID:%x DEVID:%x CONFIGBASE:0x%x CONFIGOPTION:0x%x\n",
		manfid, devid, sl->config_base, sl->config_option);

	/* success! */
	return 0;
}

/**
 * dvb_ca_en50221_set_configoption - Set CAM's configoption correctly.
 *
 * @ca: CA instance.
 * @slot: Slot containing the CAM.
 */
static int dvb_ca_en50221_set_configoption(struct dvb_ca_private *ca, int slot)
{
	struct dvb_ca_slot *sl = &ca->slot_info[slot];
	int configoption;

	dprintk("%s\n", __func__);

	/* set the config option */
	ca->pub->write_attribute_mem(ca->pub, slot, sl->config_base,
				     sl->config_option);

	/* check it */
	configoption = ca->pub->read_attribute_mem(ca->pub, slot,
						   sl->config_base);
	dprintk("Set configoption 0x%x, read configoption 0x%x\n",
		sl->config_option, configoption & 0x3f);

	/* fine! */
	return 0;
}

/**
 * dvb_ca_en50221_read_data - This function talks to an EN50221 CAM control
 *	interface. It reads a buffer of data from the CAM. The data can either
 *	be stored in a supplied buffer, or automatically be added to the slot's
 *	rx_buffer.
 *
 * @ca: CA instance.
 * @slot: Slot to read from.
 * @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.
 * @ecount: Size of ebuf. Ignored if ebuf is NULL.
 *
 * return: Number of bytes read, or < 0 on error
 */
static int dvb_ca_en50221_read_data(struct dvb_ca_private *ca, int slot,
				    u8 *ebuf, int ecount)
{
	struct dvb_ca_slot *sl = &ca->slot_info[slot];
	int bytes_read;
	int status;
	u8 buf[HOST_LINK_BUF_SIZE];
	int i;

	dprintk("%s\n", __func__);

	/* check if we have space for a link buf in the rx_buffer */
	if (!ebuf) {
		int buf_free;

		if (!sl->rx_buffer.data) {
			status = -EIO;
			goto exit;
		}
		buf_free = dvb_ringbuffer_free(&sl->rx_buffer);

		if (buf_free < (sl->link_buf_size +
				DVB_RINGBUFFER_PKTHDRSIZE)) {
			status = -EAGAIN;
			goto exit;
		}
	}

	if (ca->pub->read_data &&
	    (sl->slot_state != DVB_CA_SLOTSTATE_LINKINIT)) {
		if (!ebuf)
			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 if there is data available */
		status = ca->pub->read_cam_control(ca->pub, slot,
						   CTRLIF_STATUS);
		if (status < 0)
			goto exit;
		if (!(status & STATUSREG_DA)) {
			/* no data */
			status = 0;
			goto exit;
		}

		/* read the amount of data */
		status = ca->pub->read_cam_control(ca->pub, slot,
						   CTRLIF_SIZE_HIGH);
		if (status < 0)
			goto exit;
		bytes_read = status << 8;
		status = ca->pub->read_cam_control(ca->pub, slot,
						   CTRLIF_SIZE_LOW);
		if (status < 0)
			goto exit;
		bytes_read |= status;

		/* check it will fit */
		if (!ebuf) {
			if (bytes_read > sl->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,
				       sl->link_buf_size);
				sl->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);
				sl->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 */
			status = ca->pub->read_cam_control(ca->pub, slot,
							   CTRLIF_DATA);
			if (status < 0)
				goto exit;

			/* OK, store it in the buffer */
			buf[i] = status;
		}

		/* check for read error (RE should now be 0) */
		status = ca->pub->read_cam_control(ca->pub, slot,
						   CTRLIF_STATUS);
		if (status < 0)
			goto exit;
		if (status & STATUSREG_RE) {
			sl->slot_state = DVB_CA_SLOTSTATE_LINKINIT;
			status = -EIO;
			goto exit;
		}
	}

	/*
	 * OK, add it to the receive buffer, or copy into external buffer if
	 * supplied
	 */
	if (!ebuf) {
		if (!sl->rx_buffer.data) {
			status = -EIO;
			goto exit;
		}
		dvb_ringbuffer_pkt_write(&sl->rx_buffer, buf, bytes_read);
	} else {
		memcpy(ebuf, buf, bytes_read);
	}

	dprintk("Received CA packet for slot %i connection id 0x%x last_frag:%i size:0x%x\n", slot,
		buf[0], (buf[1] & 0x80) == 0, bytes_read);

	/* wake up readers when a last_fragment is received */
	if ((buf[1] & 0x80) == 0x00)
		wake_up_interruptible(&ca->wait_queue);

	status = bytes_read;

exit:
	return status;
}

/**
 * dvb_ca_en50221_write_data - This function talks to an EN50221 CAM control
 *				interface. It writes a buffer of data to a CAM.
 *
 * @ca: CA instance.
 * @slot: Slot to write to.
 * @buf: The data in this buffer is treated as a complete link-level packet to
 *	 be written.
 * @bytes_write: Size of ebuf.
 *
 * return: Number of bytes written, or < 0 on error.
 */
static int dvb_ca_en50221_write_data(struct dvb_ca_private *ca, int slot,
				     u8 *buf, int bytes_write)
{
	struct dvb_ca_slot *sl = &ca->slot_info[slot];
	int status;
	int i;

	dprintk("%s\n", __func__);

	/* sanity check */
	if (bytes_write > sl->link_buf_size)
		return -EINVAL;

	if (ca->pub->write_data &&
	    (sl->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
	 * process the data if necessary.
	 */
	status = ca->pub->read_cam_control(ca->pub, slot, CTRLIF_STATUS);
	if (status < 0)
		goto exitnowrite;
	if (status & (STATUSREG_DA | STATUSREG_RE)) {
		if (status & STATUSREG_DA)
			dvb_ca_en50221_thread_wakeup(ca);

		status = -EAGAIN;
		goto exitnowrite;
	}

	/* OK, set HC bit */
	status = ca->pub->write_cam_control(ca->pub, slot, CTRLIF_COMMAND,
					    IRQEN | CMDREG_HC);
	if (status)
		goto exit;

	/* check if interface is still free */
	status = ca->pub->read_cam_control(ca->pub, slot, CTRLIF_STATUS);
	if (status < 0)
		goto exit;
	if (!(status & STATUSREG_FR)) {
		/* it wasn't free => try again later */
		status = -EAGAIN;
		goto exit;
	}

	/*
	 * It may need some time for the CAM to settle down, or there might
	 * be a race condition between the CAM, writing HC and our last
	 * check for DA. This happens, if the CAM asserts DA, just after
	 * checking DA before we are setting HC. In this case it might be
	 * a bug in the CAM to keep the FR bit, the lower layer/HW
	 * communication requires a longer timeout or the CAM needs more
	 * time internally. But this happens in reality!
	 * We need to read the status from the HW again and do the same
	 * we did for the previous check for DA
	 */
	status = ca->pub->read_cam_control(ca->pub, slot, CTRLIF_STATUS);
	if (status < 0)
		goto exit;

	if (status & (STATUSREG_DA | STATUSREG_RE)) {
		if (status & STATUSREG_DA)
			dvb_ca_en50221_thread_wakeup(ca);

		status = -EAGAIN;
		goto exit;
	}

	/* send the amount of data */
	status = ca->pub->write_cam_control(ca->pub, slot, CTRLIF_SIZE_HIGH,
					    bytes_write >> 8);
	if (status)
		goto exit;
	status = ca->pub->write_cam_control(ca->pub, slot, CTRLIF_SIZE_LOW,
					    bytes_write & 0xff);
	if (status)
		goto exit;

	/* send the buffer */
	for (i = 0; i < bytes_write; i++) {
		status = ca->pub->write_cam_control(ca->pub, slot, CTRLIF_DATA,
						    buf[i]);
		if (status)
			goto exit;
	}

	/* check for write error (WE should now be 0) */
	status = ca->pub->read_cam_control(ca->pub, slot, CTRLIF_STATUS);
	if (status < 0)
		goto exit;
	if (status & STATUSREG_WE) {
		sl->slot_state = DVB_CA_SLOTSTATE_LINKINIT;
		status = -EIO;
		goto exit;
	}
	status = bytes_write;

	dprintk("Wrote CA packet for slot %i, connection id 0x%x last_frag:%i size:0x%x\n", slot,
		buf[0], (buf[1] & 0x80) == 0, bytes_write);

exit:
	ca->pub->write_cam_control(ca->pub, slot, CTRLIF_COMMAND, IRQEN);

exitnowrite:
	return status;
}

/* ************************************************************************** */
/* EN50221 higher level functions */

/**
 * dvb_ca_en50221_slot_shutdown - A CAM has been removed => shut it down.
 *
 * @ca: CA instance.
 * @slot: Slot to shut down.
 */
static int dvb_ca_en50221_slot_shutdown(struct dvb_ca_private *ca, int slot)
{
	dprintk("%s\n", __func__);

	ca->pub->slot_shutdown(ca->pub, slot);
	ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_NONE;

	/*
	 * need to wake up all processes to check if they're now trying to
	 * write to a defunct CAM
	 */
	wake_up_interruptible(&ca->wait_queue);

	dprintk("Slot %i shutdown\n", slot);

	/* success */
	return 0;
}

/**
 * dvb_ca_en50221_camchange_irq - A CAMCHANGE IRQ has occurred.
 *
 * @pubca: CA instance.
 * @slot: Slot concerned.
 * @change_type: One of the DVB_CA_CAMCHANGE_* values.
 */
void dvb_ca_en50221_camchange_irq(struct dvb_ca_en50221 *pubca, int slot,
				  int change_type)
{
	struct dvb_ca_private *ca = pubca->private;
	struct dvb_ca_slot *sl = &ca->slot_info[slot];

	dprintk("CAMCHANGE IRQ slot:%i change_type:%i\n", slot, change_type);

	switch (change_type) {
	case DVB_CA_EN50221_CAMCHANGE_REMOVED:
	case DVB_CA_EN50221_CAMCHANGE_INSERTED:
		break;

	default:
		return;
	}

	sl->camchange_type = change_type;
	atomic_inc(&sl->camchange_count);
	dvb_ca_en50221_thread_wakeup(ca);
}
EXPORT_SYMBOL(dvb_ca_en50221_camchange_irq);

/**
 * dvb_ca_en50221_camready_irq - A CAMREADY IRQ has occurred.
 *
 * @pubca: CA instance.
 * @slot: Slot concerned.
 */
void dvb_ca_en50221_camready_irq(struct dvb_ca_en50221 *pubca, int slot)
{
	struct dvb_ca_private *ca = pubca->private;
	struct dvb_ca_slot *sl = &ca->slot_info[slot];

	dprintk("CAMREADY IRQ slot:%i\n", slot);

	if (sl->slot_state == DVB_CA_SLOTSTATE_WAITREADY) {
		sl->slot_state = DVB_CA_SLOTSTATE_VALIDATE;
		dvb_ca_en50221_thread_wakeup(ca);
	}
}
EXPORT_SYMBOL(dvb_ca_en50221_camready_irq);

/**
 * dvb_ca_en50221_frda_irq - An FR or DA IRQ has occurred.
 *
 * @pubca: CA instance.
 * @slot: Slot concerned.
 */
void dvb_ca_en50221_frda_irq(struct dvb_ca_en50221 *pubca, int slot)
{
	struct dvb_ca_private *ca = pubca->private;
	struct dvb_ca_slot *sl = &ca->slot_info[slot];
	int flags;

	dprintk("FR/DA IRQ slot:%i\n", slot);

	switch (sl->slot_state) {
	case DVB_CA_SLOTSTATE_LINKINIT:
		flags = ca->pub->read_cam_control(pubca, slot, CTRLIF_STATUS);
		if (flags & STATUSREG_DA) {
			dprintk("CAM supports DA IRQ\n");
			sl->da_irq_supported = 1;
		}
		break;

	case DVB_CA_SLOTSTATE_RUNNING:
		if (ca->open)
			dvb_ca_en50221_thread_wakeup(ca);
		break;
	}
}
EXPORT_SYMBOL(dvb_ca_en50221_frda_irq);

/* ************************************************************************** */
/* EN50221 thread functions */

/**
 * dvb_ca_en50221_thread_wakeup - Wake up the DVB CA thread
 *
 * @ca: CA instance.
 */
static void dvb_ca_en50221_thread_wakeup(struct dvb_ca_private *ca)
{
	dprintk("%s\n", __func__);

	ca->wakeup = 1;
	mb();
	wake_up_process(ca->thread);
}

/**
 * dvb_ca_en50221_thread_update_delay - Update the delay used by the thread.
 *
 * @ca: CA instance.
 */
static void dvb_ca_en50221_thread_update_delay(struct dvb_ca_private *ca)
{
	int delay;
	int curdelay = 100000000;
	int slot;

	/*
	 * Beware of too high polling frequency, because one polling
	 * call might take several hundred milliseconds until timeout!
	 */
	for (slot = 0; slot < ca->slot_count; slot++) {
		struct dvb_ca_slot *sl = &ca->slot_info[slot];

		switch (sl->slot_state) {
		default:
		case DVB_CA_SLOTSTATE_NONE:
			delay = HZ * 60;  /* 60s */
			if (!(ca->flags & DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE))
				delay = HZ * 5;  /* 5s */
			break;
		case DVB_CA_SLOTSTATE_INVALID:
			delay = HZ * 60;  /* 60s */
			if (!(ca->flags & DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE))
				delay = HZ / 10;  /* 100ms */
			break;

		case DVB_CA_SLOTSTATE_UNINITIALISED:
		case DVB_CA_SLOTSTATE_WAITREADY:
		case DVB_CA_SLOTSTATE_VALIDATE:
		case DVB_CA_SLOTSTATE_WAITFR:
		case DVB_CA_SLOTSTATE_LINKINIT:
			delay = HZ / 10;  /* 100ms */
			break;

		case DVB_CA_SLOTSTATE_RUNNING:
			delay = HZ * 60;  /* 60s */
			if (!(ca->flags & DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE))
				delay = HZ / 10;  /* 100ms */
			if (ca->open) {
				if ((!sl->da_irq_supported) ||
				    (!(ca->flags & DVB_CA_EN50221_FLAG_IRQ_DA)))
					delay = HZ / 10;  /* 100ms */
			}
			break;
		}

		if (delay < curdelay)
			curdelay = delay;
	}

	ca->delay = curdelay;
}

/**
 * dvb_ca_en50221_poll_cam_gone - Poll if the CAM is gone.
 *
 * @ca: CA instance.
 * @slot: Slot to process.
 * return:: 0 .. no change
 *          1 .. CAM state changed
 */

static int dvb_ca_en50221_poll_cam_gone(struct dvb_ca_private *ca, int slot)
{
	int changed = 0;
	int status;

	/*
	 * we need this extra check for annoying interfaces like the
	 * budget-av
	 */
	if ((!(ca->flags & DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE)) &&
	    (ca->pub->poll_slot_status)) {
		status = ca->pub->poll_slot_status(ca->pub, slot, 0);
		if (!(status &
			DVB_CA_EN50221_POLL_CAM_PRESENT)) {
			ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_NONE;
			dvb_ca_en50221_thread_update_delay(ca);
			changed = 1;
		}
	}
	return changed;
}

/**
 * dvb_ca_en50221_thread_state_machine - Thread state machine for one CA slot
 *	to perform the data transfer.
 *
 * @ca: CA instance.
 * @slot: Slot to process.
 */
static void dvb_ca_en50221_thread_state_machine(struct dvb_ca_private *ca,
						int slot)
{
	struct dvb_ca_slot *sl = &ca->slot_info[slot];
	int flags;
	int pktcount;
	void *rxbuf;

	mutex_lock(&sl->slot_lock);

	/* check the cam status + deal with CAMCHANGEs */
	while (dvb_ca_en50221_check_camstatus(ca, slot)) {
		/* clear down an old CI slot if necessary */
		if (sl->slot_state != DVB_CA_SLOTSTATE_NONE)
			dvb_ca_en50221_slot_shutdown(ca, slot);

		/* if a CAM is NOW present, initialise it */
		if (sl->camchange_type == DVB_CA_EN50221_CAMCHANGE_INSERTED)
			sl->slot_state = DVB_CA_SLOTSTATE_UNINITIALISED;

		/* we've handled one CAMCHANGE */
		dvb_ca_en50221_thread_update_delay(ca);
		atomic_dec(&sl->camchange_count);
	}

	/* CAM state machine */
	switch (sl->slot_state) {
	case DVB_CA_SLOTSTATE_NONE:
	case DVB_CA_SLOTSTATE_INVALID:
		/* no action needed */
		break;

	case DVB_CA_SLOTSTATE_UNINITIALISED:
		sl->slot_state = DVB_CA_SLOTSTATE_WAITREADY;
		ca->pub->slot_reset(ca->pub, slot);
		sl->timeout = jiffies + (INIT_TIMEOUT_SECS * HZ);
		break;

	case DVB_CA_SLOTSTATE_WAITREADY:
		if (time_after(jiffies, sl->timeout)) {
			pr_err("dvb_ca adaptor %d: PC card did not respond :(\n",
			       ca->dvbdev->adapter->num);
			sl->slot_state = DVB_CA_SLOTSTATE_INVALID;
			dvb_ca_en50221_thread_update_delay(ca);
			break;
		}
		/*
		 * no other action needed; will automatically change state when
		 * ready
		 */
		break;

	case DVB_CA_SLOTSTATE_VALIDATE:
		if (dvb_ca_en50221_parse_attributes(ca, slot) != 0) {
			if (dvb_ca_en50221_poll_cam_gone(ca, slot))
				break;

			pr_err("dvb_ca adapter %d: Invalid PC card inserted :(\n",
			       ca->dvbdev->adapter->num);
			sl->slot_state = DVB_CA_SLOTSTATE_INVALID;
			dvb_ca_en50221_thread_update_delay(ca);
			break;
		}
		if (dvb_ca_en50221_set_configoption(ca, slot) != 0) {
			pr_err("dvb_ca adapter %d: Unable to initialise CAM :(\n",
			       ca->dvbdev->adapter->num);
			sl->slot_state = DVB_CA_SLOTSTATE_INVALID;
			dvb_ca_en50221_thread_update_delay(ca);
			break;
		}
		if (ca->pub->write_cam_control(ca->pub, slot,
					       CTRLIF_COMMAND,
					       CMDREG_RS) != 0) {
			pr_err("dvb_ca adapter %d: Unable to reset CAM IF\n",
			       ca->dvbdev->adapter->num);
			sl->slot_state = DVB_CA_SLOTSTATE_INVALID;
			dvb_ca_en50221_thread_update_delay(ca);
			break;
		}
		dprintk("DVB CAM validated successfully\n");

		sl->timeout = jiffies + (INIT_TIMEOUT_SECS * HZ);
		sl->slot_state = DVB_CA_SLOTSTATE_WAITFR;
		ca->wakeup = 1;
		break;

	case DVB_CA_SLOTSTATE_WAITFR:
		if (time_after(jiffies, sl->timeout)) {
			pr_err("dvb_ca adapter %d: DVB CAM did not respond :(\n",
			       ca->dvbdev->adapter->num);
			sl->slot_state = DVB_CA_SLOTSTATE_INVALID;
			dvb_ca_en50221_thread_update_delay(ca);
			break;
		}

		flags = ca->pub->read_cam_control(ca->pub, slot, CTRLIF_STATUS);
		if (flags & STATUSREG_FR) {
			sl->slot_state = DVB_CA_SLOTSTATE_LINKINIT;
			ca->wakeup = 1;
		}
		break;

	case DVB_CA_SLOTSTATE_LINKINIT:
		if (dvb_ca_en50221_link_init(ca, slot) != 0) {
			if (dvb_ca_en50221_poll_cam_gone(ca, slot))
				break;

			pr_err("dvb_ca adapter %d: DVB CAM link initialisation failed :(\n",
			       ca->dvbdev->adapter->num);
			sl->slot_state = DVB_CA_SLOTSTATE_UNINITIALISED;
			dvb_ca_en50221_thread_update_delay(ca);
			break;
		}

		if (!sl->rx_buffer.data) {
			rxbuf = vmalloc(RX_BUFFER_SIZE);
			if (!rxbuf) {
				pr_err("dvb_ca adapter %d: Unable to allocate CAM rx buffer :(\n",
				       ca->dvbdev->adapter->num);
				sl->slot_state = DVB_CA_SLOTSTATE_INVALID;
				dvb_ca_en50221_thread_update_delay(ca);
				break;
			}
			dvb_ringbuffer_init(&sl->rx_buffer, rxbuf,
					    RX_BUFFER_SIZE);
		}

		ca->pub->slot_ts_enable(ca->pub, slot);
		sl->slot_state = DVB_CA_SLOTSTATE_RUNNING;
		dvb_ca_en50221_thread_update_delay(ca);
		pr_info("dvb_ca adapter %d: DVB CAM detected and initialised successfully\n",
			ca->dvbdev->adapter->num);
		break;

	case DVB_CA_SLOTSTATE_RUNNING:
		if (!ca->open)
			break;

		/* poll slots for data */
		pktcount = 0;
		while (dvb_ca_en50221_read_data(ca, slot, NULL, 0) > 0) {
			if (!ca->open)
				break;

			/*
			 * if a CAMCHANGE occurred at some point, do not do any
			 * more processing of this slot
			 */
			if (dvb_ca_en50221_check_camstatus(ca, slot)) {
				/*
				 * we don't want to sleep on the next iteration
				 * so we can handle the cam change
				 */
				ca->wakeup = 1;
				break;
			}

			/* check if we've hit our limit this time */
			if (++pktcount >= MAX_RX_PACKETS_PER_ITERATION) {
				/*
				 * don't sleep; there is likely to be more data
				 * to read
				 */
				ca->wakeup = 1;
				break;
			}
		}
		break;
	}

	mutex_unlock(&sl->slot_lock);
}

/*
 * Kernel thread which monitors CA slots for CAM changes, and performs data
 * transfers.
 */
static int dvb_ca_en50221_thread(void *data)
{
	struct dvb_ca_private *ca = data;
	int slot;

	dprintk("%s\n", __func__);

	/* choose the correct initial delay */
	dvb_ca_en50221_thread_update_delay(ca);

	/* main loop */
	while (!kthread_should_stop()) {
		/* sleep for a bit */
		if (!ca->wakeup) {
			set_current_state(TASK_INTERRUPTIBLE);
			schedule_timeout(ca->delay);
			if (kthread_should_stop())
				return 0;
		}
		ca->wakeup = 0;

		/* go through all the slots processing them */
		for (slot = 0; slot < ca->slot_count; slot++)
			dvb_ca_en50221_thread_state_machine(ca, slot);
	}

	return 0;
}

/* ************************************************************************** */
/* EN50221 IO interface functions */

/**
 * dvb_ca_en50221_io_do_ioctl - Real ioctl implementation.
 *
 * @file: File concerned.
 * @cmd: IOCTL command.
 * @parg: Associated argument.
 *
 * NOTE: CA_SEND_MSG/CA_GET_MSG ioctls have userspace buffers passed to them.
 *
 * return: 0 on success, <0 on error.
 */
static int dvb_ca_en50221_io_do_ioctl(struct file *file,
				      unsigned int cmd, void *parg)
{
	struct dvb_device *dvbdev = file->private_data;
	struct dvb_ca_private *ca = dvbdev->priv;
	int err = 0;
	int slot;

	dprintk("%s\n", __func__);

	if (mutex_lock_interruptible(&ca->ioctl_mutex))
		return -ERESTARTSYS;

	switch (cmd) {
	case CA_RESET:
		for (slot = 0; slot < ca->slot_count; slot++) {
			struct dvb_ca_slot *sl = &ca->slot_info[slot];

			mutex_lock(&sl->slot_lock);
			if (sl->slot_state != DVB_CA_SLOTSTATE_NONE) {
				dvb_ca_en50221_slot_shutdown(ca, slot);
				if (ca->flags & DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE)
					dvb_ca_en50221_camchange_irq(ca->pub,
								     slot,
								     DVB_CA_EN50221_CAMCHANGE_INSERTED);
			}
			mutex_unlock(&sl->slot_lock);
		}
		ca->next_read_slot = 0;
		dvb_ca_en50221_thread_wakeup(ca);
		break;

	case CA_GET_CAP: {
		struct ca_caps *caps = parg;

		caps->slot_num = ca->slot_count;
		caps->slot_type = CA_CI_LINK;
		caps->descr_num = 0;
		caps->descr_type = 0;
		break;
	}

	case CA_GET_SLOT_INFO: {
		struct ca_slot_info *info = parg;
		struct dvb_ca_slot *sl;

		slot = info->num;
		if ((slot >= ca->slot_count) || (slot < 0)) {
			err = -EINVAL;
			goto out_unlock;
		}
		slot = array_index_nospec(slot, ca->slot_count);

		info->type = CA_CI_LINK;
		info->flags = 0;
		sl = &ca->slot_info[slot];
		if ((sl->slot_state != DVB_CA_SLOTSTATE_NONE) &&
		    (sl->slot_state != DVB_CA_SLOTSTATE_INVALID)) {
			info->flags = CA_CI_MODULE_PRESENT;
		}
		if (sl->slot_state == DVB_CA_SLOTSTATE_RUNNING)
			info->flags |= CA_CI_MODULE_READY;
		break;
	}

	default:
		err = -EINVAL;
		break;
	}

out_unlock:
	mutex_unlock(&ca->ioctl_mutex);
	return err;
}

/**
 * dvb_ca_en50221_io_ioctl - Wrapper for ioctl implementation.
 *
 * @file: File concerned.
 * @cmd: IOCTL command.
 * @arg: Associated argument.
 *
 * return: 0 on success, <0 on error.
 */
static long dvb_ca_en50221_io_ioctl(struct file *file,
				    unsigned int cmd, unsigned long arg)
{
	return dvb_usercopy(file, cmd, arg, dvb_ca_en50221_io_do_ioctl);
}

/**
 * dvb_ca_en50221_io_write - Implementation of write() syscall.
 *
 * @file: File structure.
 * @buf: Source buffer.
 * @count: Size of source buffer.
 * @ppos: Position in file (ignored).
 *
 * return: Number of bytes read, or <0 on error.
 */
static ssize_t dvb_ca_en50221_io_write(struct file *file,
				       const char __user *buf, size_t count,
				       loff_t *ppos)
{
	struct dvb_device *dvbdev = file->private_data;
	struct dvb_ca_private *ca = dvbdev->priv;
	struct dvb_ca_slot *sl;
	u8 slot, connection_id;
	int status;
	u8 fragbuf[HOST_LINK_BUF_SIZE];
	int fragpos = 0;
	int fraglen;
	unsigned long timeout;
	int written;

	dprintk("%s\n", __func__);

	/*
	 * Incoming packet has a 2 byte header.
	 * hdr[0] = slot_id, hdr[1] = connection_id
	 */
	if (count < 2)
		return -EINVAL;

	/* extract slot & connection id */
	if (copy_from_user(&slot, buf, 1))
		return -EFAULT;
	if (copy_from_user(&connection_id, buf + 1, 1))
		return -EFAULT;
	buf += 2;
	count -= 2;

	if (slot >= ca->slot_count)
		return -EINVAL;
	slot = array_index_nospec(slot, ca->slot_count);
	sl = &ca->slot_info[slot];

	/* check if the slot is actually running */
	if (sl->slot_state != DVB_CA_SLOTSTATE_RUNNING)
		return -EINVAL;

	/* fragment the packets & store in the buffer */
	while (fragpos < count) {
		fraglen = sl->link_buf_size - 2;
		if (fraglen < 0)
			break;
		if (fraglen > HOST_LINK_BUF_SIZE - 2)
			fraglen = HOST_LINK_BUF_SIZE - 2;
		if ((count - fragpos) < fraglen)
			fraglen = count - fragpos;

		fragbuf[0] = connection_id;
		fragbuf[1] = ((fragpos + fraglen) < count) ? 0x80 : 0x00;
		status = copy_from_user(fragbuf + 2, buf + fragpos, fraglen);
		if (status) {
			status = -EFAULT;
			goto exit;
		}

		timeout = jiffies + HZ / 2;
		written = 0;
		while (!time_after(jiffies, timeout)) {
			/*
			 * check the CAM hasn't been removed/reset in the
			 * meantime
			 */
			if (sl->slot_state != DVB_CA_SLOTSTATE_RUNNING) {
				status = -EIO;
				goto exit;
			}

			mutex_lock(&sl->slot_lock);
			status = dvb_ca_en50221_write_data(ca, slot, fragbuf,
							   fraglen + 2);
			mutex_unlock(&sl->slot_lock);
			if (status == (fraglen + 2)) {
				written = 1;
				break;
			}
			if (status != -EAGAIN)
				goto exit;

			usleep_range(1000, 1100);
		}
		if (!written) {
			status = -EIO;
			goto exit;
		}

		fragpos += fraglen;
	}
	status = count + 2;

exit:
	return status;
}

/*
 * Condition for waking up in dvb_ca_en50221_io_read_condition
 */
static int dvb_ca_en50221_io_read_condition(struct dvb_ca_private *ca,
					    int *result, int *_slot)
{
	int slot;
	int slot_count = 0;
	int idx;
	size_t fraglen;
	int connection_id = -1;
	int found = 0;
	u8 hdr[2];

	slot = ca->next_read_slot;
	while ((slot_count < ca->slot_count) && (!found)) {
		struct dvb_ca_slot *sl = &ca->slot_info[slot];

		if (sl->slot_state != DVB_CA_SLOTSTATE_RUNNING)
			goto nextslot;

		if (!sl->rx_buffer.data)
			return 0;

		idx = dvb_ringbuffer_pkt_next(&sl->rx_buffer, -1, &fraglen);
		while (idx != -1) {
			dvb_ringbuffer_pkt_read(&sl->rx_buffer, idx, 0, hdr, 2);
			if (connection_id == -1)
				connection_id = hdr[0];
			if ((hdr[0] == connection_id) &&
			    ((hdr[1] & 0x80) == 0)) {
				*_slot = slot;
				found = 1;
				break;
			}

			idx = dvb_ringbuffer_pkt_next(&sl->rx_buffer, idx,
						      &fraglen);
		}

nextslot:
		slot = (slot + 1) % ca->slot_count;
		slot_count++;
	}

	ca->next_read_slot = slot;
	return found;
}

/**
 * dvb_ca_en50221_io_read - Implementation of read() syscall.
 *
 * @file: File structure.
 * @buf: Destination buffer.
 * @count: Size of destination buffer.
 * @ppos: Position in file (ignored).
 *
 * return: Number of bytes read, or <0 on error.
 */
static ssize_t dvb_ca_en50221_io_read(struct file *file, char __user *buf,
				      size_t count, loff_t *ppos)
{
	struct dvb_device *dvbdev = file->private_data;
	struct dvb_ca_private *ca = dvbdev->priv;
	struct dvb_ca_slot *sl;
	int status;
	int result = 0;
	u8 hdr[2];
	int slot;
	int connection_id = -1;
	size_t idx, idx2;
	int last_fragment = 0;
	size_t fraglen;
	int pktlen;
	int dispose = 0;

	dprintk("%s\n", __func__);

	/*
	 * Outgoing packet has a 2 byte header.
	 * hdr[0] = slot_id, hdr[1] = connection_id
	 */
	if (count < 2)
		return -EINVAL;

	/* wait for some data */
	status = dvb_ca_en50221_io_read_condition(ca, &result, &slot);
	if (status == 0) {
		/* if we're in nonblocking mode, exit immediately */
		if (file->f_flags & O_NONBLOCK)
			return -EWOULDBLOCK;

		/* wait for some data */
		status = wait_event_interruptible(ca->wait_queue,
						  dvb_ca_en50221_io_read_condition
						  (ca, &result, &slot));
	}
	if ((status < 0) || (result < 0)) {
		if (result)
			return result;
		return status;
	}

	sl = &ca->slot_info[slot];
	idx = dvb_ringbuffer_pkt_next(&sl->rx_buffer, -1, &fraglen);
	pktlen = 2;
	do {
		if (idx == -1) {
			pr_err("dvb_ca adapter %d: BUG: read packet ended before last_fragment encountered\n",
			       ca->dvbdev->adapter->num);
			status = -EIO;
			goto exit;
		}

		dvb_ringbuffer_pkt_read(&sl->rx_buffer, idx, 0, hdr, 2);
		if (connection_id == -1)
			connection_id = hdr[0];
		if (hdr[0] == connection_id) {
			if (pktlen < count) {
				if ((pktlen + fraglen - 2) > count)
					fraglen = count - pktlen;
				else
					fraglen -= 2;

				status =
				   dvb_ringbuffer_pkt_read_user(&sl->rx_buffer,
								idx, 2,
								buf + pktlen,
								fraglen);
				if (status < 0)
					goto exit;

				pktlen += fraglen;
			}

			if ((hdr[1] & 0x80) == 0)
				last_fragment = 1;
			dispose = 1;
		}

		idx2 = dvb_ringbuffer_pkt_next(&sl->rx_buffer, idx, &fraglen);
		if (dispose)
			dvb_ringbuffer_pkt_dispose(&sl->rx_buffer, idx);
		idx = idx2;
		dispose = 0;
	} while (!last_fragment);

	hdr[0] = slot;
	hdr[1] = connection_id;
	status = copy_to_user(buf, hdr, 2);
	if (status) {
		status = -EFAULT;
		goto exit;
	}
	status = pktlen;

exit:
	return status;
}

/**
 * dvb_ca_en50221_io_open - Implementation of file open syscall.
 *
 * @inode: Inode concerned.
 * @file: File concerned.
 *
 * return: 0 on success, <0 on failure.
 */
static int dvb_ca_en50221_io_open(struct inode *inode, struct file *file)
{
	struct dvb_device *dvbdev = file->private_data;
	struct dvb_ca_private *ca = dvbdev->priv;
	int err;
	int i;

	dprintk("%s\n", __func__);

	if (!try_module_get(ca->pub->owner))
		return -EIO;

	err = dvb_generic_open(inode, file);
	if (err < 0) {
		module_put(ca->pub->owner);
		return err;
	}

	for (i = 0; i < ca->slot_count; i++) {
		struct dvb_ca_slot *sl = &ca->slot_info[i];

		if (sl->slot_state == DVB_CA_SLOTSTATE_RUNNING) {
			if (!sl->rx_buffer.data) {
				/*
				 * it is safe to call this here without locks
				 * because ca->open == 0. Data is not read in
				 * this case
				 */
				dvb_ringbuffer_flush(&sl->rx_buffer);
			}
		}
	}

	ca->open = 1;
	dvb_ca_en50221_thread_update_delay(ca);
	dvb_ca_en50221_thread_wakeup(ca);

	dvb_ca_private_get(ca);

	return 0;
}

/**
 * dvb_ca_en50221_io_release - Implementation of file close syscall.
 *
 * @inode: Inode concerned.
 * @file: File concerned.
 *
 * return: 0 on success, <0 on failure.
 */
static int dvb_ca_en50221_io_release(struct inode *inode, struct file *file)
{
	struct dvb_device *dvbdev = file->private_data;
	struct dvb_ca_private *ca = dvbdev->priv;
	int err;

	dprintk("%s\n", __func__);

	/* mark the CA device as closed */
	ca->open = 0;
	dvb_ca_en50221_thread_update_delay(ca);

	err = dvb_generic_release(inode, file);

	module_put(ca->pub->owner);

	dvb_ca_private_put(ca);

	return err;
}

/**
 * dvb_ca_en50221_io_poll - Implementation of poll() syscall.
 *
 * @file: File concerned.
 * @wait: poll wait table.
 *
 * return: Standard poll mask.
 */
static __poll_t dvb_ca_en50221_io_poll(struct file *file, poll_table *wait)
{
	struct dvb_device *dvbdev = file->private_data;
	struct dvb_ca_private *ca = dvbdev->priv;
	__poll_t mask = 0;
	int slot;
	int result = 0;

	dprintk("%s\n", __func__);

	poll_wait(file, &ca->wait_queue, wait);

	if (dvb_ca_en50221_io_read_condition(ca, &result, &slot) == 1)
		mask |= EPOLLIN;

	/* if there is something, return now */
	if (mask)
		return mask;

	if (dvb_ca_en50221_io_read_condition(ca, &result, &slot) == 1)
		mask |= EPOLLIN;

	return mask;
}

static const struct file_operations dvb_ca_fops = {
	.owner = THIS_MODULE,
	.read = dvb_ca_en50221_io_read,
	.write = dvb_ca_en50221_io_write,
	.unlocked_ioctl = dvb_ca_en50221_io_ioctl,
	.open = dvb_ca_en50221_io_open,
	.release = dvb_ca_en50221_io_release,
	.poll = dvb_ca_en50221_io_poll,
	.llseek = noop_llseek,
};

static const struct dvb_device dvbdev_ca = {
	.priv = NULL,
	.users = 1,
	.readers = 1,
	.writers = 1,
#if defined(CONFIG_MEDIA_CONTROLLER_DVB)
	.name = "dvb-ca-en50221",
#endif
	.fops = &dvb_ca_fops,
};

/* ************************************************************************** */
/* Initialisation/shutdown functions */

/**
 * dvb_ca_en50221_init - Initialise a new DVB CA EN50221 interface device.
 *
 * @dvb_adapter: DVB adapter to attach the new CA device to.
 * @pubca: The dvb_ca instance.
 * @flags: Flags describing the CA device (DVB_CA_FLAG_*).
 * @slot_count: Number of slots supported.
 *
 * return: 0 on success, nonzero on failure
 */
int dvb_ca_en50221_init(struct dvb_adapter *dvb_adapter,
			struct dvb_ca_en50221 *pubca, int flags, int slot_count)
{
	int ret;
	struct dvb_ca_private *ca = NULL;
	int i;

	dprintk("%s\n", __func__);

	if (slot_count < 1)
		return -EINVAL;

	/* initialise the system data */
	ca = kzalloc(sizeof(*ca), GFP_KERNEL);
	if (!ca) {
		ret = -ENOMEM;
		goto exit;
	}
	kref_init(&ca->refcount);
	ca->pub = pubca;
	ca->flags = flags;
	ca->slot_count = slot_count;
	ca->slot_info = kcalloc(slot_count, sizeof(struct dvb_ca_slot),
				GFP_KERNEL);
	if (!ca->slot_info) {
		ret = -ENOMEM;
		goto free_ca;
	}
	init_waitqueue_head(&ca->wait_queue);
	ca->open = 0;
	ca->wakeup = 0;
	ca->next_read_slot = 0;
	pubca->private = ca;

	/* register the DVB device */
	ret = dvb_register_device(dvb_adapter, &ca->dvbdev, &dvbdev_ca, ca,
				  DVB_DEVICE_CA, 0);
	if (ret)
		goto free_slot_info;

	/* now initialise each slot */
	for (i = 0; i < slot_count; i++) {
		struct dvb_ca_slot *sl = &ca->slot_info[i];

		memset(sl, 0, sizeof(struct dvb_ca_slot));
		sl->slot_state = DVB_CA_SLOTSTATE_NONE;
		atomic_set(&sl->camchange_count, 0);
		sl->camchange_type = DVB_CA_EN50221_CAMCHANGE_REMOVED;
		mutex_init(&sl->slot_lock);
	}

	mutex_init(&ca->ioctl_mutex);

	if (signal_pending(current)) {
		ret = -EINTR;
		goto unregister_device;
	}
	mb();

	/* create a kthread for monitoring this CA device */
	ca->thread = kthread_run(dvb_ca_en50221_thread, ca, "kdvb-ca-%i:%i",
				 ca->dvbdev->adapter->num, ca->dvbdev->id);
	if (IS_ERR(ca->thread)) {
		ret = PTR_ERR(ca->thread);
		pr_err("dvb_ca_init: failed to start kernel_thread (%d)\n",
		       ret);
		goto unregister_device;
	}
	return 0;

unregister_device:
	dvb_unregister_device(ca->dvbdev);
free_slot_info:
	kfree(ca->slot_info);
free_ca:
	kfree(ca);
exit:
	pubca->private = NULL;
	return ret;
}
EXPORT_SYMBOL(dvb_ca_en50221_init);

/**
 * dvb_ca_en50221_release - Release a DVB CA EN50221 interface device.
 *
 * @pubca: The associated dvb_ca instance.
 */
void dvb_ca_en50221_release(struct dvb_ca_en50221 *pubca)
{
	struct dvb_ca_private *ca = pubca->private;
	int i;

	dprintk("%s\n", __func__);

	/* shutdown the thread if there was one */
	kthread_stop(ca->thread);

	for (i = 0; i < ca->slot_count; i++)
		dvb_ca_en50221_slot_shutdown(ca, i);

	dvb_remove_device(ca->dvbdev);
	dvb_ca_private_put(ca);
	pubca->private = NULL;
}
EXPORT_SYMBOL(dvb_ca_en50221_release);
