]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blame - drivers/media/dvb-core/dvb_ca_en50221.c
[media] dvb_ca_en50221: use foo *bar, instead of foo * bar
[mirror_ubuntu-bionic-kernel.git] / drivers / media / dvb-core / dvb_ca_en50221.c
CommitLineData
1da177e4
LT
1/*
2 * dvb_ca.c: generic DVB functions for EN50221 CAM interfaces
3 *
4 * Copyright (C) 2004 Andrew de Quincey
5 *
6 * Parts of this file were based on sources as follows:
7 *
8 * Copyright (C) 2003 Ralph Metzler <rjkm@metzlerbros.de>
9 *
10 * based on code:
11 *
12 * Copyright (C) 1999-2002 Ralph Metzler
13 * & Marcus Metzler for convergence integrated media GmbH
14 *
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License
17 * as published by the Free Software Foundation; either version 2
18 * of the License, or (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
bcb63314
SA
24 * To obtain the license, point your browser to
25 * http://www.gnu.org/copyleft/gpl.html
1da177e4
LT
26 */
27
b3ad24d2
MCC
28#define pr_fmt(fmt) "dvb_ca_en50221: " fmt
29
1da177e4
LT
30#include <linux/errno.h>
31#include <linux/slab.h>
32#include <linux/list.h>
33#include <linux/module.h>
1da177e4
LT
34#include <linux/vmalloc.h>
35#include <linux/delay.h>
ded92846 36#include <linux/spinlock.h>
174cd4b1 37#include <linux/sched/signal.h>
9320874a 38#include <linux/kthread.h>
1da177e4
LT
39
40#include "dvb_ca_en50221.h"
41#include "dvb_ringbuffer.h"
42
43static int dvb_ca_en50221_debug;
44
45module_param_named(cam_debug, dvb_ca_en50221_debug, int, 0644);
46MODULE_PARM_DESC(cam_debug, "enable verbose debug messages");
47
b3ad24d2
MCC
48#define dprintk(fmt, arg...) do { \
49 if (dvb_ca_en50221_debug) \
50 printk(KERN_DEBUG pr_fmt("%s: " fmt), __func__, ##arg);\
51} while (0)
1da177e4 52
50b447d5 53#define INIT_TIMEOUT_SECS 10
1da177e4
LT
54
55#define HOST_LINK_BUF_SIZE 0x200
56
57#define RX_BUFFER_SIZE 65535
58
59#define MAX_RX_PACKETS_PER_ITERATION 10
60
61#define CTRLIF_DATA 0
62#define CTRLIF_COMMAND 1
63#define CTRLIF_STATUS 1
64#define CTRLIF_SIZE_LOW 2
65#define CTRLIF_SIZE_HIGH 3
66
67#define CMDREG_HC 1 /* Host control */
68#define CMDREG_SW 2 /* Size write */
69#define CMDREG_SR 4 /* Size read */
70#define CMDREG_RS 8 /* Reset interface */
71#define CMDREG_FRIE 0x40 /* Enable FR interrupt */
72#define CMDREG_DAIE 0x80 /* Enable DA interrupt */
73#define IRQEN (CMDREG_DAIE)
74
75#define STATUSREG_RE 1 /* read error */
76#define STATUSREG_WE 2 /* write error */
77#define STATUSREG_FR 0x40 /* module free */
78#define STATUSREG_DA 0x80 /* data available */
79#define STATUSREG_TXERR (STATUSREG_RE|STATUSREG_WE) /* general transfer error */
80
81
82#define DVB_CA_SLOTSTATE_NONE 0
83#define DVB_CA_SLOTSTATE_UNINITIALISED 1
84#define DVB_CA_SLOTSTATE_RUNNING 2
85#define DVB_CA_SLOTSTATE_INVALID 3
86#define DVB_CA_SLOTSTATE_WAITREADY 4
87#define DVB_CA_SLOTSTATE_VALIDATE 5
88#define DVB_CA_SLOTSTATE_WAITFR 6
89#define DVB_CA_SLOTSTATE_LINKINIT 7
90
91
92/* Information on a CA slot */
93struct dvb_ca_slot {
94
95 /* current state of the CAM */
96 int slot_state;
97
d7e43844
MD
98 /* mutex used for serializing access to one CI slot */
99 struct mutex slot_lock;
100
1da177e4
LT
101 /* Number of CAMCHANGES that have occurred since last processing */
102 atomic_t camchange_count;
103
104 /* Type of last CAMCHANGE */
105 int camchange_type;
106
107 /* base address of CAM config */
108 u32 config_base;
109
110 /* value to write into Config Control register */
111 u8 config_option;
112
113 /* if 1, the CAM supports DA IRQs */
114 u8 da_irq_supported:1;
115
116 /* size of the buffer to use when talking to the CAM */
117 int link_buf_size;
118
1da177e4
LT
119 /* buffer for incoming packets */
120 struct dvb_ringbuffer rx_buffer;
121
122 /* timer used during various states of the slot */
123 unsigned long timeout;
124};
125
126/* Private CA-interface information */
127struct dvb_ca_private {
da677fe1 128 struct kref refcount;
1da177e4
LT
129
130 /* pointer back to the public data structure */
131 struct dvb_ca_en50221 *pub;
132
133 /* the DVB device */
134 struct dvb_device *dvbdev;
135
136 /* Flags describing the interface (DVB_CA_FLAG_*) */
137 u32 flags;
138
139 /* number of slots supported by this CA interface */
140 unsigned int slot_count;
141
142 /* information on each slot */
143 struct dvb_ca_slot *slot_info;
144
145 /* wait queues for read() and write() operations */
146 wait_queue_head_t wait_queue;
147
148 /* PID of the monitoring thread */
9320874a 149 struct task_struct *thread;
1da177e4
LT
150
151 /* Flag indicating if the CA device is open */
152 unsigned int open:1;
153
154 /* Flag indicating the thread should wake up now */
155 unsigned int wakeup:1;
156
157 /* Delay the main thread should use */
158 unsigned long delay;
159
160 /* Slot to start looking for data to read from in the next user-space read operation */
161 int next_read_slot;
30ad64b8
NS
162
163 /* mutex serializing ioctls */
164 struct mutex ioctl_mutex;
1da177e4
LT
165};
166
bd3df3c5
MK
167static void dvb_ca_private_free(struct dvb_ca_private *ca)
168{
169 unsigned int i;
170
4d5030b6 171 dvb_free_device(ca->dvbdev);
bd3df3c5
MK
172 for (i = 0; i < ca->slot_count; i++)
173 vfree(ca->slot_info[i].rx_buffer.data);
174
175 kfree(ca->slot_info);
176 kfree(ca);
177}
178
da677fe1
MK
179static void dvb_ca_private_release(struct kref *ref)
180{
181 struct dvb_ca_private *ca = container_of(ref, struct dvb_ca_private, refcount);
182 dvb_ca_private_free(ca);
183}
184
185static void dvb_ca_private_get(struct dvb_ca_private *ca)
186{
187 kref_get(&ca->refcount);
188}
189
190static void dvb_ca_private_put(struct dvb_ca_private *ca)
191{
192 kref_put(&ca->refcount, dvb_ca_private_release);
193}
194
1da177e4 195static void dvb_ca_en50221_thread_wakeup(struct dvb_ca_private *ca);
8ec6107a
JJ
196static int dvb_ca_en50221_read_data(struct dvb_ca_private *ca, int slot,
197 u8 *ebuf, int ecount);
198static int dvb_ca_en50221_write_data(struct dvb_ca_private *ca, int slot,
199 u8 *ebuf, int ecount);
1da177e4
LT
200
201
202/**
203 * Safely find needle in haystack.
204 *
fbefb1a8
MCC
205 * @haystack: Buffer to look in.
206 * @hlen: Number of bytes in haystack.
207 * @needle: Buffer to find.
208 * @nlen: Number of bytes in needle.
1da177e4
LT
209 * @return Pointer into haystack needle was found at, or NULL if not found.
210 */
8ec6107a 211static char *findstr(char *haystack, int hlen, char *needle, int nlen)
1da177e4
LT
212{
213 int i;
214
215 if (hlen < nlen)
216 return NULL;
217
218 for (i = 0; i <= hlen - nlen; i++) {
219 if (!strncmp(haystack + i, needle, nlen))
220 return haystack + i;
221 }
222
223 return NULL;
224}
225
226
227
228/* ******************************************************************************** */
229/* EN50221 physical interface functions */
230
231
232/**
fbefb1a8 233 * dvb_ca_en50221_check_camstatus - Check CAM status.
1da177e4
LT
234 */
235static int dvb_ca_en50221_check_camstatus(struct dvb_ca_private *ca, int slot)
236{
237 int slot_status;
238 int cam_present_now;
239 int cam_changed;
240
241 /* IRQ mode */
242 if (ca->flags & DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE) {
243 return (atomic_read(&ca->slot_info[slot].camchange_count) != 0);
244 }
245
246 /* poll mode */
247 slot_status = ca->pub->poll_slot_status(ca->pub, slot, ca->open);
248
249 cam_present_now = (slot_status & DVB_CA_EN50221_POLL_CAM_PRESENT) ? 1 : 0;
250 cam_changed = (slot_status & DVB_CA_EN50221_POLL_CAM_CHANGED) ? 1 : 0;
251 if (!cam_changed) {
252 int cam_present_old = (ca->slot_info[slot].slot_state != DVB_CA_SLOTSTATE_NONE);
253 cam_changed = (cam_present_now != cam_present_old);
254 }
255
256 if (cam_changed) {
257 if (!cam_present_now) {
258 ca->slot_info[slot].camchange_type = DVB_CA_EN50221_CAMCHANGE_REMOVED;
259 } else {
260 ca->slot_info[slot].camchange_type = DVB_CA_EN50221_CAMCHANGE_INSERTED;
261 }
262 atomic_set(&ca->slot_info[slot].camchange_count, 1);
263 } else {
264 if ((ca->slot_info[slot].slot_state == DVB_CA_SLOTSTATE_WAITREADY) &&
265 (slot_status & DVB_CA_EN50221_POLL_CAM_READY)) {
266 // move to validate state if reset is completed
267 ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_VALIDATE;
268 }
269 }
270
271 return cam_changed;
272}
273
274
275/**
fbefb1a8
MCC
276 * dvb_ca_en50221_wait_if_status - Wait for flags to become set on the STATUS
277 * register on a CAM interface, checking for errors and timeout.
1da177e4 278 *
fbefb1a8
MCC
279 * @ca: CA instance.
280 * @slot: Slot on interface.
281 * @waitfor: Flags to wait for.
282 * @timeout_ms: Timeout in milliseconds.
1da177e4
LT
283 *
284 * @return 0 on success, nonzero on error.
285 */
286static int dvb_ca_en50221_wait_if_status(struct dvb_ca_private *ca, int slot,
287 u8 waitfor, int timeout_hz)
288{
289 unsigned long timeout;
290 unsigned long start;
291
46b4f7c1 292 dprintk("%s\n", __func__);
1da177e4
LT
293
294 /* loop until timeout elapsed */
295 start = jiffies;
296 timeout = jiffies + timeout_hz;
297 while (1) {
298 /* read the status and check for error */
299 int res = ca->pub->read_cam_control(ca->pub, slot, CTRLIF_STATUS);
300 if (res < 0)
301 return -EIO;
302
303 /* if we got the flags, it was successful! */
304 if (res & waitfor) {
b3ad24d2
MCC
305 dprintk("%s succeeded timeout:%lu\n",
306 __func__, jiffies - start);
1da177e4
LT
307 return 0;
308 }
309
310 /* check for timeout */
311 if (time_after(jiffies, timeout)) {
312 break;
313 }
314
315 /* wait for a bit */
316 msleep(1);
317 }
318
46b4f7c1 319 dprintk("%s failed timeout:%lu\n", __func__, jiffies - start);
1da177e4
LT
320
321 /* if we get here, we've timed out */
322 return -ETIMEDOUT;
323}
324
325
326/**
fbefb1a8 327 * dvb_ca_en50221_link_init - Initialise the link layer connection to a CAM.
1da177e4 328 *
fbefb1a8
MCC
329 * @ca: CA instance.
330 * @slot: Slot id.
1da177e4
LT
331 *
332 * @return 0 on success, nonzero on failure.
333 */
334static int dvb_ca_en50221_link_init(struct dvb_ca_private *ca, int slot)
335{
336 int ret;
337 int buf_size;
338 u8 buf[2];
339
46b4f7c1 340 dprintk("%s\n", __func__);
1da177e4
LT
341
342 /* we'll be determining these during this function */
343 ca->slot_info[slot].da_irq_supported = 0;
344
345 /* set the host link buffer size temporarily. it will be overwritten with the
346 * real negotiated size later. */
347 ca->slot_info[slot].link_buf_size = 2;
348
349 /* read the buffer size from the CAM */
350 if ((ret = ca->pub->write_cam_control(ca->pub, slot, CTRLIF_COMMAND, IRQEN | CMDREG_SR)) != 0)
351 return ret;
352 if ((ret = dvb_ca_en50221_wait_if_status(ca, slot, STATUSREG_DA, HZ / 10)) != 0)
353 return ret;
354 if ((ret = dvb_ca_en50221_read_data(ca, slot, buf, 2)) != 2)
355 return -EIO;
356 if ((ret = ca->pub->write_cam_control(ca->pub, slot, CTRLIF_COMMAND, IRQEN)) != 0)
357 return ret;
358
359 /* store it, and choose the minimum of our buffer and the CAM's buffer size */
360 buf_size = (buf[0] << 8) | buf[1];
361 if (buf_size > HOST_LINK_BUF_SIZE)
362 buf_size = HOST_LINK_BUF_SIZE;
363 ca->slot_info[slot].link_buf_size = buf_size;
364 buf[0] = buf_size >> 8;
365 buf[1] = buf_size & 0xff;
366 dprintk("Chosen link buffer size of %i\n", buf_size);
367
368 /* write the buffer size to the CAM */
369 if ((ret = ca->pub->write_cam_control(ca->pub, slot, CTRLIF_COMMAND, IRQEN | CMDREG_SW)) != 0)
370 return ret;
371 if ((ret = dvb_ca_en50221_wait_if_status(ca, slot, STATUSREG_FR, HZ / 10)) != 0)
372 return ret;
373 if ((ret = dvb_ca_en50221_write_data(ca, slot, buf, 2)) != 2)
374 return -EIO;
375 if ((ret = ca->pub->write_cam_control(ca->pub, slot, CTRLIF_COMMAND, IRQEN)) != 0)
376 return ret;
377
378 /* success */
379 return 0;
380}
381
382/**
fbefb1a8 383 * dvb_ca_en50221_read_tuple - Read a tuple from attribute memory.
1da177e4 384 *
fbefb1a8
MCC
385 * @ca: CA instance.
386 * @slot: Slot id.
387 * @address: Address to read from. Updated.
388 * @tupleType: Tuple id byte. Updated.
389 * @tupleLength: Tuple length. Updated.
390 * @tuple: Dest buffer for tuple (must be 256 bytes). Updated.
1da177e4
LT
391 *
392 * @return 0 on success, nonzero on error.
393 */
394static int dvb_ca_en50221_read_tuple(struct dvb_ca_private *ca, int slot,
8ec6107a
JJ
395 int *address, int *tupleType,
396 int *tupleLength, u8 *tuple)
1da177e4
LT
397{
398 int i;
399 int _tupleType;
400 int _tupleLength;
401 int _address = *address;
402
403 /* grab the next tuple length and type */
404 if ((_tupleType = ca->pub->read_attribute_mem(ca->pub, slot, _address)) < 0)
405 return _tupleType;
406 if (_tupleType == 0xff) {
407 dprintk("END OF CHAIN TUPLE type:0x%x\n", _tupleType);
408 *address += 2;
409 *tupleType = _tupleType;
410 *tupleLength = 0;
411 return 0;
412 }
413 if ((_tupleLength = ca->pub->read_attribute_mem(ca->pub, slot, _address + 2)) < 0)
414 return _tupleLength;
415 _address += 4;
416
417 dprintk("TUPLE type:0x%x length:%i\n", _tupleType, _tupleLength);
418
419 /* read in the whole tuple */
420 for (i = 0; i < _tupleLength; i++) {
421 tuple[i] = ca->pub->read_attribute_mem(ca->pub, slot, _address + (i * 2));
422 dprintk(" 0x%02x: 0x%02x %c\n",
423 i, tuple[i] & 0xff,
424 ((tuple[i] > 31) && (tuple[i] < 127)) ? tuple[i] : '.');
425 }
426 _address += (_tupleLength * 2);
427
428 // success
429 *tupleType = _tupleType;
430 *tupleLength = _tupleLength;
431 *address = _address;
432 return 0;
433}
434
435
436/**
fbefb1a8
MCC
437 * dvb_ca_en50221_parse_attributes - Parse attribute memory of a CAM module,
438 * extracting Config register, and checking it is a DVB CAM module.
1da177e4 439 *
fbefb1a8
MCC
440 * @ca: CA instance.
441 * @slot: Slot id.
1da177e4
LT
442 *
443 * @return 0 on success, <0 on failure.
444 */
445static int dvb_ca_en50221_parse_attributes(struct dvb_ca_private *ca, int slot)
446{
447 int address = 0;
448 int tupleLength;
449 int tupleType;
450 u8 tuple[257];
451 char *dvb_str;
452 int rasz;
453 int status;
454 int got_cftableentry = 0;
455 int end_chain = 0;
456 int i;
457 u16 manfid = 0;
458 u16 devid = 0;
459
460
461 // CISTPL_DEVICE_0A
462 if ((status =
463 dvb_ca_en50221_read_tuple(ca, slot, &address, &tupleType, &tupleLength, tuple)) < 0)
464 return status;
465 if (tupleType != 0x1D)
466 return -EINVAL;
467
468
469
470 // CISTPL_DEVICE_0C
471 if ((status =
472 dvb_ca_en50221_read_tuple(ca, slot, &address, &tupleType, &tupleLength, tuple)) < 0)
473 return status;
474 if (tupleType != 0x1C)
475 return -EINVAL;
476
477
478
479 // CISTPL_VERS_1
480 if ((status =
481 dvb_ca_en50221_read_tuple(ca, slot, &address, &tupleType, &tupleLength, tuple)) < 0)
482 return status;
483 if (tupleType != 0x15)
484 return -EINVAL;
485
486
487
488 // CISTPL_MANFID
489 if ((status = dvb_ca_en50221_read_tuple(ca, slot, &address, &tupleType,
490 &tupleLength, tuple)) < 0)
491 return status;
492 if (tupleType != 0x20)
493 return -EINVAL;
494 if (tupleLength != 4)
495 return -EINVAL;
496 manfid = (tuple[1] << 8) | tuple[0];
497 devid = (tuple[3] << 8) | tuple[2];
498
499
500
501 // CISTPL_CONFIG
502 if ((status = dvb_ca_en50221_read_tuple(ca, slot, &address, &tupleType,
503 &tupleLength, tuple)) < 0)
504 return status;
505 if (tupleType != 0x1A)
506 return -EINVAL;
507 if (tupleLength < 3)
508 return -EINVAL;
509
510 /* extract the configbase */
511 rasz = tuple[0] & 3;
512 if (tupleLength < (3 + rasz + 14))
513 return -EINVAL;
514 ca->slot_info[slot].config_base = 0;
515 for (i = 0; i < rasz + 1; i++) {
516 ca->slot_info[slot].config_base |= (tuple[2 + i] << (8 * i));
517 }
518
519 /* check it contains the correct DVB string */
260f8d7c 520 dvb_str = findstr((char *)tuple, tupleLength, "DVB_CI_V", 8);
1da177e4
LT
521 if (dvb_str == NULL)
522 return -EINVAL;
523 if (tupleLength < ((dvb_str - (char *) tuple) + 12))
524 return -EINVAL;
525
526 /* is it a version we support? */
527 if (strncmp(dvb_str + 8, "1.00", 4)) {
b3ad24d2
MCC
528 pr_err("dvb_ca adapter %d: Unsupported DVB CAM module version %c%c%c%c\n",
529 ca->dvbdev->adapter->num, dvb_str[8], dvb_str[9],
530 dvb_str[10], dvb_str[11]);
1da177e4
LT
531 return -EINVAL;
532 }
533
534 /* process the CFTABLE_ENTRY tuples, and any after those */
535 while ((!end_chain) && (address < 0x1000)) {
536 if ((status = dvb_ca_en50221_read_tuple(ca, slot, &address, &tupleType,
afd1a0c9 537 &tupleLength, tuple)) < 0)
1da177e4
LT
538 return status;
539 switch (tupleType) {
540 case 0x1B: // CISTPL_CFTABLE_ENTRY
541 if (tupleLength < (2 + 11 + 17))
542 break;
543
544 /* if we've already parsed one, just use it */
545 if (got_cftableentry)
546 break;
547
548 /* get the config option */
549 ca->slot_info[slot].config_option = tuple[0] & 0x3f;
550
551 /* OK, check it contains the correct strings */
260f8d7c
OE
552 if ((findstr((char *)tuple, tupleLength, "DVB_HOST", 8) == NULL) ||
553 (findstr((char *)tuple, tupleLength, "DVB_CI_MODULE", 13) == NULL))
1da177e4
LT
554 break;
555
556 got_cftableentry = 1;
557 break;
558
559 case 0x14: // CISTPL_NO_LINK
560 break;
561
562 case 0xFF: // CISTPL_END
563 end_chain = 1;
564 break;
565
566 default: /* Unknown tuple type - just skip this tuple and move to the next one */
b3ad24d2
MCC
567 dprintk("dvb_ca: Skipping unknown tuple type:0x%x length:0x%x\n",
568 tupleType, tupleLength);
1da177e4
LT
569 break;
570 }
571 }
572
573 if ((address > 0x1000) || (!got_cftableentry))
574 return -EINVAL;
575
576 dprintk("Valid DVB CAM detected MANID:%x DEVID:%x CONFIGBASE:0x%x CONFIGOPTION:0x%x\n",
b3ad24d2
MCC
577 manfid, devid, ca->slot_info[slot].config_base,
578 ca->slot_info[slot].config_option);
1da177e4
LT
579
580 // success!
581 return 0;
582}
583
584
585/**
fbefb1a8 586 * dvb_ca_en50221_set_configoption - Set CAM's configoption correctly.
1da177e4 587 *
fbefb1a8
MCC
588 * @ca: CA instance.
589 * @slot: Slot containing the CAM.
1da177e4
LT
590 */
591static int dvb_ca_en50221_set_configoption(struct dvb_ca_private *ca, int slot)
592{
593 int configoption;
594
46b4f7c1 595 dprintk("%s\n", __func__);
1da177e4
LT
596
597 /* set the config option */
598 ca->pub->write_attribute_mem(ca->pub, slot,
599 ca->slot_info[slot].config_base,
600 ca->slot_info[slot].config_option);
601
602 /* check it */
603 configoption = ca->pub->read_attribute_mem(ca->pub, slot, ca->slot_info[slot].config_base);
604 dprintk("Set configoption 0x%x, read configoption 0x%x\n",
605 ca->slot_info[slot].config_option, configoption & 0x3f);
606
607 /* fine! */
608 return 0;
609
610}
611
612
613/**
fbefb1a8
MCC
614 * dvb_ca_en50221_read_data - This function talks to an EN50221 CAM control
615 * interface. It reads a buffer of data from the CAM. The data can either
616 * be stored in a supplied buffer, or automatically be added to the slot's
617 * rx_buffer.
1da177e4 618 *
fbefb1a8
MCC
619 * @ca: CA instance.
620 * @slot: Slot to read from.
621 * @ebuf: If non-NULL, the data will be written to this buffer. If NULL,
1da177e4 622 * the data will be added into the buffering system as a normal fragment.
fbefb1a8 623 * @ecount: Size of ebuf. Ignored if ebuf is NULL.
1da177e4
LT
624 *
625 * @return Number of bytes read, or < 0 on error
626 */
8ec6107a
JJ
627static int dvb_ca_en50221_read_data(struct dvb_ca_private *ca, int slot,
628 u8 *ebuf, int ecount)
1da177e4
LT
629{
630 int bytes_read;
631 int status;
632 u8 buf[HOST_LINK_BUF_SIZE];
633 int i;
634
46b4f7c1 635 dprintk("%s\n", __func__);
1da177e4
LT
636
637 /* check if we have space for a link buf in the rx_buffer */
638 if (ebuf == NULL) {
639 int buf_free;
640
1da177e4 641 if (ca->slot_info[slot].rx_buffer.data == NULL) {
1da177e4
LT
642 status = -EIO;
643 goto exit;
644 }
645 buf_free = dvb_ringbuffer_free(&ca->slot_info[slot].rx_buffer);
1da177e4
LT
646
647 if (buf_free < (ca->slot_info[slot].link_buf_size + DVB_RINGBUFFER_PKTHDRSIZE)) {
648 status = -EAGAIN;
649 goto exit;
650 }
651 }
652
653 /* check if there is data available */
654 if ((status = ca->pub->read_cam_control(ca->pub, slot, CTRLIF_STATUS)) < 0)
655 goto exit;
656 if (!(status & STATUSREG_DA)) {
657 /* no data */
658 status = 0;
659 goto exit;
660 }
661
662 /* read the amount of data */
663 if ((status = ca->pub->read_cam_control(ca->pub, slot, CTRLIF_SIZE_HIGH)) < 0)
664 goto exit;
665 bytes_read = status << 8;
666 if ((status = ca->pub->read_cam_control(ca->pub, slot, CTRLIF_SIZE_LOW)) < 0)
667 goto exit;
668 bytes_read |= status;
669
670 /* check it will fit */
671 if (ebuf == NULL) {
672 if (bytes_read > ca->slot_info[slot].link_buf_size) {
b3ad24d2
MCC
673 pr_err("dvb_ca adapter %d: CAM tried to send a buffer larger than the link buffer size (%i > %i)!\n",
674 ca->dvbdev->adapter->num, bytes_read,
675 ca->slot_info[slot].link_buf_size);
1da177e4
LT
676 ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_LINKINIT;
677 status = -EIO;
678 goto exit;
679 }
680 if (bytes_read < 2) {
b3ad24d2 681 pr_err("dvb_ca adapter %d: CAM sent a buffer that was less than 2 bytes!\n",
1da177e4
LT
682 ca->dvbdev->adapter->num);
683 ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_LINKINIT;
684 status = -EIO;
685 goto exit;
686 }
687 } else {
688 if (bytes_read > ecount) {
b3ad24d2 689 pr_err("dvb_ca adapter %d: CAM tried to send a buffer larger than the ecount size!\n",
1da177e4
LT
690 ca->dvbdev->adapter->num);
691 status = -EIO;
692 goto exit;
693 }
694 }
695
696 /* fill the buffer */
697 for (i = 0; i < bytes_read; i++) {
698 /* read byte and check */
699 if ((status = ca->pub->read_cam_control(ca->pub, slot, CTRLIF_DATA)) < 0)
700 goto exit;
701
702 /* OK, store it in the buffer */
703 buf[i] = status;
704 }
705
706 /* check for read error (RE should now be 0) */
707 if ((status = ca->pub->read_cam_control(ca->pub, slot, CTRLIF_STATUS)) < 0)
708 goto exit;
709 if (status & STATUSREG_RE) {
710 ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_LINKINIT;
711 status = -EIO;
712 goto exit;
713 }
714
715 /* OK, add it to the receive buffer, or copy into external buffer if supplied */
716 if (ebuf == NULL) {
1da177e4 717 if (ca->slot_info[slot].rx_buffer.data == NULL) {
1da177e4
LT
718 status = -EIO;
719 goto exit;
720 }
721 dvb_ringbuffer_pkt_write(&ca->slot_info[slot].rx_buffer, buf, bytes_read);
1da177e4
LT
722 } else {
723 memcpy(ebuf, buf, bytes_read);
724 }
725
726 dprintk("Received CA packet for slot %i connection id 0x%x last_frag:%i size:0x%x\n", slot,
727 buf[0], (buf[1] & 0x80) == 0, bytes_read);
728
729 /* wake up readers when a last_fragment is received */
730 if ((buf[1] & 0x80) == 0x00) {
731 wake_up_interruptible(&ca->wait_queue);
732 }
733 status = bytes_read;
734
735exit:
736 return status;
737}
738
739
740/**
fbefb1a8
MCC
741 * dvb_ca_en50221_write_data - This function talks to an EN50221 CAM control
742 * interface. It writes a buffer of data to a CAM.
1da177e4 743 *
fbefb1a8
MCC
744 * @ca: CA instance.
745 * @slot: Slot to write to.
746 * @ebuf: The data in this buffer is treated as a complete link-level packet to
1da177e4 747 * be written.
fbefb1a8 748 * @count: Size of ebuf.
1da177e4
LT
749 *
750 * @return Number of bytes written, or < 0 on error.
751 */
8ec6107a
JJ
752static int dvb_ca_en50221_write_data(struct dvb_ca_private *ca, int slot,
753 u8 *buf, int bytes_write)
1da177e4
LT
754{
755 int status;
756 int i;
757
46b4f7c1 758 dprintk("%s\n", __func__);
1da177e4
LT
759
760
d7e43844 761 /* sanity check */
1da177e4
LT
762 if (bytes_write > ca->slot_info[slot].link_buf_size)
763 return -EINVAL;
764
d7e43844
MD
765 /* it is possible we are dealing with a single buffer implementation,
766 thus if there is data available for read or if there is even a read
767 already in progress, we do nothing but awake the kernel thread to
768 process the data if necessary. */
1da177e4
LT
769 if ((status = ca->pub->read_cam_control(ca->pub, slot, CTRLIF_STATUS)) < 0)
770 goto exitnowrite;
771 if (status & (STATUSREG_DA | STATUSREG_RE)) {
d7e43844
MD
772 if (status & STATUSREG_DA)
773 dvb_ca_en50221_thread_wakeup(ca);
774
1da177e4
LT
775 status = -EAGAIN;
776 goto exitnowrite;
777 }
778
779 /* OK, set HC bit */
780 if ((status = ca->pub->write_cam_control(ca->pub, slot, CTRLIF_COMMAND,
781 IRQEN | CMDREG_HC)) != 0)
782 goto exit;
783
784 /* check if interface is still free */
785 if ((status = ca->pub->read_cam_control(ca->pub, slot, CTRLIF_STATUS)) < 0)
786 goto exit;
787 if (!(status & STATUSREG_FR)) {
788 /* it wasn't free => try again later */
789 status = -EAGAIN;
790 goto exit;
791 }
792
e7080d44
J
793 /*
794 * It may need some time for the CAM to settle down, or there might
795 * be a race condition between the CAM, writing HC and our last
796 * check for DA. This happens, if the CAM asserts DA, just after
797 * checking DA before we are setting HC. In this case it might be
798 * a bug in the CAM to keep the FR bit, the lower layer/HW
799 * communication requires a longer timeout or the CAM needs more
800 * time internally. But this happens in reality!
801 * We need to read the status from the HW again and do the same
802 * we did for the previous check for DA
803 */
804 status = ca->pub->read_cam_control(ca->pub, slot, CTRLIF_STATUS);
805 if (status < 0)
806 goto exit;
807
808 if (status & (STATUSREG_DA | STATUSREG_RE)) {
809 if (status & STATUSREG_DA)
810 dvb_ca_en50221_thread_wakeup(ca);
811
812 status = -EAGAIN;
813 goto exit;
814 }
815
1da177e4
LT
816 /* send the amount of data */
817 if ((status = ca->pub->write_cam_control(ca->pub, slot, CTRLIF_SIZE_HIGH, bytes_write >> 8)) != 0)
818 goto exit;
819 if ((status = ca->pub->write_cam_control(ca->pub, slot, CTRLIF_SIZE_LOW,
820 bytes_write & 0xff)) != 0)
821 goto exit;
822
823 /* send the buffer */
824 for (i = 0; i < bytes_write; i++) {
825 if ((status = ca->pub->write_cam_control(ca->pub, slot, CTRLIF_DATA, buf[i])) != 0)
826 goto exit;
827 }
828
829 /* check for write error (WE should now be 0) */
830 if ((status = ca->pub->read_cam_control(ca->pub, slot, CTRLIF_STATUS)) < 0)
831 goto exit;
832 if (status & STATUSREG_WE) {
833 ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_LINKINIT;
834 status = -EIO;
835 goto exit;
836 }
837 status = bytes_write;
838
839 dprintk("Wrote CA packet for slot %i, connection id 0x%x last_frag:%i size:0x%x\n", slot,
840 buf[0], (buf[1] & 0x80) == 0, bytes_write);
841
842exit:
843 ca->pub->write_cam_control(ca->pub, slot, CTRLIF_COMMAND, IRQEN);
844
845exitnowrite:
846 return status;
847}
848EXPORT_SYMBOL(dvb_ca_en50221_camchange_irq);
849
850
851
852/* ******************************************************************************** */
853/* EN50221 higher level functions */
854
855
856/**
fbefb1a8 857 * dvb_ca_en50221_camready_irq - A CAM has been removed => shut it down.
1da177e4 858 *
fbefb1a8
MCC
859 * @ca: CA instance.
860 * @slot: Slot to shut down.
1da177e4
LT
861 */
862static int dvb_ca_en50221_slot_shutdown(struct dvb_ca_private *ca, int slot)
863{
46b4f7c1 864 dprintk("%s\n", __func__);
1da177e4 865
1da177e4
LT
866 ca->pub->slot_shutdown(ca->pub, slot);
867 ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_NONE;
1da177e4
LT
868
869 /* need to wake up all processes to check if they're now
870 trying to write to a defunct CAM */
871 wake_up_interruptible(&ca->wait_queue);
872
873 dprintk("Slot %i shutdown\n", slot);
874
875 /* success */
876 return 0;
877}
878EXPORT_SYMBOL(dvb_ca_en50221_camready_irq);
879
880
881/**
fbefb1a8 882 * dvb_ca_en50221_camready_irq - A CAMCHANGE IRQ has occurred.
1da177e4 883 *
fbefb1a8
MCC
884 * @ca: CA instance.
885 * @slot: Slot concerned.
886 * @change_type: One of the DVB_CA_CAMCHANGE_* values.
1da177e4
LT
887 */
888void dvb_ca_en50221_camchange_irq(struct dvb_ca_en50221 *pubca, int slot, int change_type)
889{
0c53c70f 890 struct dvb_ca_private *ca = pubca->private;
1da177e4
LT
891
892 dprintk("CAMCHANGE IRQ slot:%i change_type:%i\n", slot, change_type);
893
894 switch (change_type) {
895 case DVB_CA_EN50221_CAMCHANGE_REMOVED:
896 case DVB_CA_EN50221_CAMCHANGE_INSERTED:
897 break;
898
899 default:
900 return;
901 }
902
903 ca->slot_info[slot].camchange_type = change_type;
904 atomic_inc(&ca->slot_info[slot].camchange_count);
905 dvb_ca_en50221_thread_wakeup(ca);
906}
907EXPORT_SYMBOL(dvb_ca_en50221_frda_irq);
908
909
910/**
fbefb1a8 911 * dvb_ca_en50221_camready_irq - A CAMREADY IRQ has occurred.
1da177e4 912 *
fbefb1a8
MCC
913 * @ca: CA instance.
914 * @slot: Slot concerned.
1da177e4
LT
915 */
916void dvb_ca_en50221_camready_irq(struct dvb_ca_en50221 *pubca, int slot)
917{
0c53c70f 918 struct dvb_ca_private *ca = pubca->private;
1da177e4
LT
919
920 dprintk("CAMREADY IRQ slot:%i\n", slot);
921
922 if (ca->slot_info[slot].slot_state == DVB_CA_SLOTSTATE_WAITREADY) {
923 ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_VALIDATE;
924 dvb_ca_en50221_thread_wakeup(ca);
925 }
926}
927
928
929/**
930 * An FR or DA IRQ has occurred.
931 *
fbefb1a8
MCC
932 * @ca: CA instance.
933 * @slot: Slot concerned.
1da177e4
LT
934 */
935void dvb_ca_en50221_frda_irq(struct dvb_ca_en50221 *pubca, int slot)
936{
0c53c70f 937 struct dvb_ca_private *ca = pubca->private;
1da177e4
LT
938 int flags;
939
940 dprintk("FR/DA IRQ slot:%i\n", slot);
941
942 switch (ca->slot_info[slot].slot_state) {
943 case DVB_CA_SLOTSTATE_LINKINIT:
944 flags = ca->pub->read_cam_control(pubca, slot, CTRLIF_STATUS);
945 if (flags & STATUSREG_DA) {
946 dprintk("CAM supports DA IRQ\n");
947 ca->slot_info[slot].da_irq_supported = 1;
948 }
949 break;
950
951 case DVB_CA_SLOTSTATE_RUNNING:
952 if (ca->open)
ded92846 953 dvb_ca_en50221_thread_wakeup(ca);
1da177e4
LT
954 break;
955 }
956}
957
958
959
960/* ******************************************************************************** */
961/* EN50221 thread functions */
962
963/**
964 * Wake up the DVB CA thread
965 *
fbefb1a8 966 * @ca: CA instance.
1da177e4
LT
967 */
968static void dvb_ca_en50221_thread_wakeup(struct dvb_ca_private *ca)
969{
970
46b4f7c1 971 dprintk("%s\n", __func__);
1da177e4
LT
972
973 ca->wakeup = 1;
974 mb();
9320874a 975 wake_up_process(ca->thread);
1da177e4
LT
976}
977
1da177e4
LT
978/**
979 * Update the delay used by the thread.
980 *
fbefb1a8 981 * @ca: CA instance.
1da177e4
LT
982 */
983static void dvb_ca_en50221_thread_update_delay(struct dvb_ca_private *ca)
984{
985 int delay;
986 int curdelay = 100000000;
987 int slot;
988
71a35fe2
RS
989 /* Beware of too high polling frequency, because one polling
990 * call might take several hundred milliseconds until timeout!
991 */
1da177e4
LT
992 for (slot = 0; slot < ca->slot_count; slot++) {
993 switch (ca->slot_info[slot].slot_state) {
994 default:
995 case DVB_CA_SLOTSTATE_NONE:
71a35fe2
RS
996 delay = HZ * 60; /* 60s */
997 if (!(ca->flags & DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE))
998 delay = HZ * 5; /* 5s */
999 break;
1da177e4 1000 case DVB_CA_SLOTSTATE_INVALID:
71a35fe2
RS
1001 delay = HZ * 60; /* 60s */
1002 if (!(ca->flags & DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE))
1003 delay = HZ / 10; /* 100ms */
1da177e4
LT
1004 break;
1005
1006 case DVB_CA_SLOTSTATE_UNINITIALISED:
1007 case DVB_CA_SLOTSTATE_WAITREADY:
1008 case DVB_CA_SLOTSTATE_VALIDATE:
1009 case DVB_CA_SLOTSTATE_WAITFR:
1010 case DVB_CA_SLOTSTATE_LINKINIT:
71a35fe2 1011 delay = HZ / 10; /* 100ms */
1da177e4
LT
1012 break;
1013
1014 case DVB_CA_SLOTSTATE_RUNNING:
71a35fe2
RS
1015 delay = HZ * 60; /* 60s */
1016 if (!(ca->flags & DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE))
1017 delay = HZ / 10; /* 100ms */
1da177e4
LT
1018 if (ca->open) {
1019 if ((!ca->slot_info[slot].da_irq_supported) ||
71a35fe2
RS
1020 (!(ca->flags & DVB_CA_EN50221_FLAG_IRQ_DA)))
1021 delay = HZ / 10; /* 100ms */
1da177e4
LT
1022 }
1023 break;
1024 }
1025
1026 if (delay < curdelay)
1027 curdelay = delay;
1028 }
1029
1030 ca->delay = curdelay;
1031}
1032
1033
1034
1035/**
1036 * Kernel thread which monitors CA slots for CAM changes, and performs data transfers.
1037 */
1038static int dvb_ca_en50221_thread(void *data)
1039{
0c53c70f 1040 struct dvb_ca_private *ca = data;
1da177e4
LT
1041 int slot;
1042 int flags;
1043 int status;
1044 int pktcount;
1045 void *rxbuf;
1046
46b4f7c1 1047 dprintk("%s\n", __func__);
1da177e4 1048
1da177e4
LT
1049 /* choose the correct initial delay */
1050 dvb_ca_en50221_thread_update_delay(ca);
1051
1052 /* main loop */
9320874a 1053 while (!kthread_should_stop()) {
1da177e4 1054 /* sleep for a bit */
a39a8ed7 1055 if (!ca->wakeup) {
9320874a
CH
1056 set_current_state(TASK_INTERRUPTIBLE);
1057 schedule_timeout(ca->delay);
1058 if (kthread_should_stop())
1059 return 0;
1da177e4
LT
1060 }
1061 ca->wakeup = 0;
1062
1063 /* go through all the slots processing them */
1064 for (slot = 0; slot < ca->slot_count; slot++) {
1065
d7e43844
MD
1066 mutex_lock(&ca->slot_info[slot].slot_lock);
1067
1da177e4
LT
1068 // check the cam status + deal with CAMCHANGEs
1069 while (dvb_ca_en50221_check_camstatus(ca, slot)) {
1070 /* clear down an old CI slot if necessary */
1071 if (ca->slot_info[slot].slot_state != DVB_CA_SLOTSTATE_NONE)
1072 dvb_ca_en50221_slot_shutdown(ca, slot);
1073
1074 /* if a CAM is NOW present, initialise it */
1075 if (ca->slot_info[slot].camchange_type == DVB_CA_EN50221_CAMCHANGE_INSERTED) {
1076 ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_UNINITIALISED;
1077 }
1078
1079 /* we've handled one CAMCHANGE */
1080 dvb_ca_en50221_thread_update_delay(ca);
1081 atomic_dec(&ca->slot_info[slot].camchange_count);
1082 }
1083
1084 // CAM state machine
1085 switch (ca->slot_info[slot].slot_state) {
1086 case DVB_CA_SLOTSTATE_NONE:
1087 case DVB_CA_SLOTSTATE_INVALID:
1088 // no action needed
1089 break;
1090
1091 case DVB_CA_SLOTSTATE_UNINITIALISED:
1092 ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_WAITREADY;
1093 ca->pub->slot_reset(ca->pub, slot);
1094 ca->slot_info[slot].timeout = jiffies + (INIT_TIMEOUT_SECS * HZ);
1095 break;
1096
1097 case DVB_CA_SLOTSTATE_WAITREADY:
1098 if (time_after(jiffies, ca->slot_info[slot].timeout)) {
b3ad24d2 1099 pr_err("dvb_ca adaptor %d: PC card did not respond :(\n",
1da177e4
LT
1100 ca->dvbdev->adapter->num);
1101 ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_INVALID;
1102 dvb_ca_en50221_thread_update_delay(ca);
1103 break;
1104 }
1105 // no other action needed; will automatically change state when ready
1106 break;
1107
1108 case DVB_CA_SLOTSTATE_VALIDATE:
5c1208ba
AQ
1109 if (dvb_ca_en50221_parse_attributes(ca, slot) != 0) {
1110 /* we need this extra check for annoying interfaces like the budget-av */
1111 if ((!(ca->flags & DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE)) &&
1112 (ca->pub->poll_slot_status)) {
c6eb8eaf 1113 status = ca->pub->poll_slot_status(ca->pub, slot, 0);
5c1208ba
AQ
1114 if (!(status & DVB_CA_EN50221_POLL_CAM_PRESENT)) {
1115 ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_NONE;
1116 dvb_ca_en50221_thread_update_delay(ca);
1117 break;
1118 }
1119 }
1120
b3ad24d2 1121 pr_err("dvb_ca adapter %d: Invalid PC card inserted :(\n",
1da177e4
LT
1122 ca->dvbdev->adapter->num);
1123 ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_INVALID;
1124 dvb_ca_en50221_thread_update_delay(ca);
1125 break;
1126 }
1127 if (dvb_ca_en50221_set_configoption(ca, slot) != 0) {
b3ad24d2 1128 pr_err("dvb_ca adapter %d: Unable to initialise CAM :(\n",
1da177e4
LT
1129 ca->dvbdev->adapter->num);
1130 ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_INVALID;
1131 dvb_ca_en50221_thread_update_delay(ca);
1132 break;
1133 }
1134 if (ca->pub->write_cam_control(ca->pub, slot,
1135 CTRLIF_COMMAND, CMDREG_RS) != 0) {
b3ad24d2 1136 pr_err("dvb_ca adapter %d: Unable to reset CAM IF\n",
1da177e4
LT
1137 ca->dvbdev->adapter->num);
1138 ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_INVALID;
1139 dvb_ca_en50221_thread_update_delay(ca);
1140 break;
1141 }
1142 dprintk("DVB CAM validated successfully\n");
1143
1144 ca->slot_info[slot].timeout = jiffies + (INIT_TIMEOUT_SECS * HZ);
1145 ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_WAITFR;
1146 ca->wakeup = 1;
1147 break;
1148
1149 case DVB_CA_SLOTSTATE_WAITFR:
1150 if (time_after(jiffies, ca->slot_info[slot].timeout)) {
b3ad24d2 1151 pr_err("dvb_ca adapter %d: DVB CAM did not respond :(\n",
1da177e4
LT
1152 ca->dvbdev->adapter->num);
1153 ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_INVALID;
1154 dvb_ca_en50221_thread_update_delay(ca);
1155 break;
1156 }
1157
1158 flags = ca->pub->read_cam_control(ca->pub, slot, CTRLIF_STATUS);
1159 if (flags & STATUSREG_FR) {
1160 ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_LINKINIT;
1161 ca->wakeup = 1;
1162 }
1163 break;
1164
1165 case DVB_CA_SLOTSTATE_LINKINIT:
1166 if (dvb_ca_en50221_link_init(ca, slot) != 0) {
5c1208ba
AQ
1167 /* we need this extra check for annoying interfaces like the budget-av */
1168 if ((!(ca->flags & DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE)) &&
1169 (ca->pub->poll_slot_status)) {
c6eb8eaf 1170 status = ca->pub->poll_slot_status(ca->pub, slot, 0);
5c1208ba
AQ
1171 if (!(status & DVB_CA_EN50221_POLL_CAM_PRESENT)) {
1172 ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_NONE;
1173 dvb_ca_en50221_thread_update_delay(ca);
1174 break;
1175 }
1176 }
1177
b3ad24d2
MCC
1178 pr_err("dvb_ca adapter %d: DVB CAM link initialisation failed :(\n",
1179 ca->dvbdev->adapter->num);
1da177e4
LT
1180 ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_INVALID;
1181 dvb_ca_en50221_thread_update_delay(ca);
1182 break;
1183 }
1184
ded92846
AQ
1185 if (ca->slot_info[slot].rx_buffer.data == NULL) {
1186 rxbuf = vmalloc(RX_BUFFER_SIZE);
1187 if (rxbuf == NULL) {
b3ad24d2
MCC
1188 pr_err("dvb_ca adapter %d: Unable to allocate CAM rx buffer :(\n",
1189 ca->dvbdev->adapter->num);
ded92846
AQ
1190 ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_INVALID;
1191 dvb_ca_en50221_thread_update_delay(ca);
1192 break;
1193 }
1194 dvb_ringbuffer_init(&ca->slot_info[slot].rx_buffer, rxbuf, RX_BUFFER_SIZE);
1da177e4 1195 }
1da177e4
LT
1196
1197 ca->pub->slot_ts_enable(ca->pub, slot);
1198 ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_RUNNING;
1199 dvb_ca_en50221_thread_update_delay(ca);
b3ad24d2
MCC
1200 pr_err("dvb_ca adapter %d: DVB CAM detected and initialised successfully\n",
1201 ca->dvbdev->adapter->num);
1da177e4
LT
1202 break;
1203
1204 case DVB_CA_SLOTSTATE_RUNNING:
1205 if (!ca->open)
d7e43844 1206 break;
1da177e4 1207
ded92846 1208 // poll slots for data
1da177e4
LT
1209 pktcount = 0;
1210 while ((status = dvb_ca_en50221_read_data(ca, slot, NULL, 0)) > 0) {
1211 if (!ca->open)
1212 break;
1213
1214 /* if a CAMCHANGE occurred at some point, do not do any more processing of this slot */
1215 if (dvb_ca_en50221_check_camstatus(ca, slot)) {
1216 // we dont want to sleep on the next iteration so we can handle the cam change
1217 ca->wakeup = 1;
1218 break;
1219 }
1220
1221 /* check if we've hit our limit this time */
1222 if (++pktcount >= MAX_RX_PACKETS_PER_ITERATION) {
1223 // dont sleep; there is likely to be more data to read
1224 ca->wakeup = 1;
1225 break;
1226 }
1227 }
1228 break;
1229 }
d7e43844
MD
1230
1231 mutex_unlock(&ca->slot_info[slot].slot_lock);
1da177e4
LT
1232 }
1233 }
1234
1da177e4
LT
1235 return 0;
1236}
1237
1238
1239
1240/* ******************************************************************************** */
1241/* EN50221 IO interface functions */
1242
1243/**
1244 * Real ioctl implementation.
1245 * NOTE: CA_SEND_MSG/CA_GET_MSG ioctls have userspace buffers passed to them.
1246 *
fbefb1a8
MCC
1247 * @inode: Inode concerned.
1248 * @file: File concerned.
1249 * @cmd: IOCTL command.
1250 * @arg: Associated argument.
1da177e4
LT
1251 *
1252 * @return 0 on success, <0 on error.
1253 */
16ef8def 1254static int dvb_ca_en50221_io_do_ioctl(struct file *file,
1da177e4
LT
1255 unsigned int cmd, void *parg)
1256{
0c53c70f
JS
1257 struct dvb_device *dvbdev = file->private_data;
1258 struct dvb_ca_private *ca = dvbdev->priv;
1da177e4
LT
1259 int err = 0;
1260 int slot;
1261
46b4f7c1 1262 dprintk("%s\n", __func__);
1da177e4 1263
30ad64b8
NS
1264 if (mutex_lock_interruptible(&ca->ioctl_mutex))
1265 return -ERESTARTSYS;
1266
1da177e4
LT
1267 switch (cmd) {
1268 case CA_RESET:
1269 for (slot = 0; slot < ca->slot_count; slot++) {
d7e43844 1270 mutex_lock(&ca->slot_info[slot].slot_lock);
1da177e4
LT
1271 if (ca->slot_info[slot].slot_state != DVB_CA_SLOTSTATE_NONE) {
1272 dvb_ca_en50221_slot_shutdown(ca, slot);
1273 if (ca->flags & DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE)
1274 dvb_ca_en50221_camchange_irq(ca->pub,
1275 slot,
1276 DVB_CA_EN50221_CAMCHANGE_INSERTED);
1277 }
d7e43844 1278 mutex_unlock(&ca->slot_info[slot].slot_lock);
1da177e4
LT
1279 }
1280 ca->next_read_slot = 0;
1281 dvb_ca_en50221_thread_wakeup(ca);
1282 break;
1283
1284 case CA_GET_CAP: {
0c53c70f 1285 struct ca_caps *caps = parg;
1da177e4
LT
1286
1287 caps->slot_num = ca->slot_count;
1288 caps->slot_type = CA_CI_LINK;
1289 caps->descr_num = 0;
1290 caps->descr_type = 0;
1291 break;
1292 }
1293
1294 case CA_GET_SLOT_INFO: {
0c53c70f 1295 struct ca_slot_info *info = parg;
1da177e4 1296
c4fe29a3
DC
1297 if ((info->num > ca->slot_count) || (info->num < 0)) {
1298 err = -EINVAL;
1299 goto out_unlock;
1300 }
1da177e4
LT
1301
1302 info->type = CA_CI_LINK;
1303 info->flags = 0;
1304 if ((ca->slot_info[info->num].slot_state != DVB_CA_SLOTSTATE_NONE)
1305 && (ca->slot_info[info->num].slot_state != DVB_CA_SLOTSTATE_INVALID)) {
1306 info->flags = CA_CI_MODULE_PRESENT;
1307 }
1308 if (ca->slot_info[info->num].slot_state == DVB_CA_SLOTSTATE_RUNNING) {
1309 info->flags |= CA_CI_MODULE_READY;
1310 }
1311 break;
1312 }
1313
1314 default:
1315 err = -EINVAL;
1316 break;
1317 }
1318
c4fe29a3 1319out_unlock:
30ad64b8 1320 mutex_unlock(&ca->ioctl_mutex);
1da177e4
LT
1321 return err;
1322}
1323
1324
1325/**
1326 * Wrapper for ioctl implementation.
1327 *
fbefb1a8
MCC
1328 * @inode: Inode concerned.
1329 * @file: File concerned.
1330 * @cmd: IOCTL command.
1331 * @arg: Associated argument.
1da177e4
LT
1332 *
1333 * @return 0 on success, <0 on error.
1334 */
16ef8def
AB
1335static long dvb_ca_en50221_io_ioctl(struct file *file,
1336 unsigned int cmd, unsigned long arg)
1da177e4 1337{
72024f1e 1338 return dvb_usercopy(file, cmd, arg, dvb_ca_en50221_io_do_ioctl);
1da177e4
LT
1339}
1340
1341
1342/**
1343 * Implementation of write() syscall.
1344 *
fbefb1a8
MCC
1345 * @file: File structure.
1346 * @buf: Source buffer.
1347 * @count: Size of source buffer.
1348 * @ppos: Position in file (ignored).
1da177e4
LT
1349 *
1350 * @return Number of bytes read, or <0 on error.
1351 */
1352static ssize_t dvb_ca_en50221_io_write(struct file *file,
8ec6107a
JJ
1353 const char __user *buf, size_t count,
1354 loff_t *ppos)
1da177e4 1355{
0c53c70f
JS
1356 struct dvb_device *dvbdev = file->private_data;
1357 struct dvb_ca_private *ca = dvbdev->priv;
1da177e4
LT
1358 u8 slot, connection_id;
1359 int status;
260f8d7c 1360 u8 fragbuf[HOST_LINK_BUF_SIZE];
1da177e4
LT
1361 int fragpos = 0;
1362 int fraglen;
1363 unsigned long timeout;
1364 int written;
1365
46b4f7c1 1366 dprintk("%s\n", __func__);
1da177e4
LT
1367
1368 /* Incoming packet has a 2 byte header. hdr[0] = slot_id, hdr[1] = connection_id */
1369 if (count < 2)
1370 return -EINVAL;
1371
1372 /* extract slot & connection id */
1373 if (copy_from_user(&slot, buf, 1))
1374 return -EFAULT;
1375 if (copy_from_user(&connection_id, buf + 1, 1))
1376 return -EFAULT;
1377 buf += 2;
1378 count -= 2;
1379
1380 /* check if the slot is actually running */
1381 if (ca->slot_info[slot].slot_state != DVB_CA_SLOTSTATE_RUNNING)
1382 return -EINVAL;
1383
1384 /* fragment the packets & store in the buffer */
1385 while (fragpos < count) {
1386 fraglen = ca->slot_info[slot].link_buf_size - 2;
624f0c18
MCC
1387 if (fraglen < 0)
1388 break;
1389 if (fraglen > HOST_LINK_BUF_SIZE - 2)
1390 fraglen = HOST_LINK_BUF_SIZE - 2;
1da177e4
LT
1391 if ((count - fragpos) < fraglen)
1392 fraglen = count - fragpos;
1393
1394 fragbuf[0] = connection_id;
1395 fragbuf[1] = ((fragpos + fraglen) < count) ? 0x80 : 0x00;
e252984c
DC
1396 status = copy_from_user(fragbuf + 2, buf + fragpos, fraglen);
1397 if (status) {
1398 status = -EFAULT;
1da177e4 1399 goto exit;
e252984c 1400 }
1da177e4
LT
1401
1402 timeout = jiffies + HZ / 2;
1403 written = 0;
1404 while (!time_after(jiffies, timeout)) {
1405 /* check the CAM hasn't been removed/reset in the meantime */
1406 if (ca->slot_info[slot].slot_state != DVB_CA_SLOTSTATE_RUNNING) {
1407 status = -EIO;
1408 goto exit;
1409 }
1410
d7e43844 1411 mutex_lock(&ca->slot_info[slot].slot_lock);
1da177e4 1412 status = dvb_ca_en50221_write_data(ca, slot, fragbuf, fraglen + 2);
d7e43844 1413 mutex_unlock(&ca->slot_info[slot].slot_lock);
1da177e4
LT
1414 if (status == (fraglen + 2)) {
1415 written = 1;
1416 break;
1417 }
1418 if (status != -EAGAIN)
1419 goto exit;
1420
1421 msleep(1);
1422 }
1423 if (!written) {
1424 status = -EIO;
1425 goto exit;
1426 }
1427
1428 fragpos += fraglen;
1429 }
1430 status = count + 2;
1431
1432exit:
1433 return status;
1434}
1435
1436
1437/**
1438 * Condition for waking up in dvb_ca_en50221_io_read_condition
1439 */
ded92846
AQ
1440static int dvb_ca_en50221_io_read_condition(struct dvb_ca_private *ca,
1441 int *result, int *_slot)
1da177e4
LT
1442{
1443 int slot;
1444 int slot_count = 0;
1445 int idx;
ded92846 1446 size_t fraglen;
1da177e4
LT
1447 int connection_id = -1;
1448 int found = 0;
1449 u8 hdr[2];
1450
1451 slot = ca->next_read_slot;
1452 while ((slot_count < ca->slot_count) && (!found)) {
1453 if (ca->slot_info[slot].slot_state != DVB_CA_SLOTSTATE_RUNNING)
1454 goto nextslot;
1455
1da177e4 1456 if (ca->slot_info[slot].rx_buffer.data == NULL) {
1da177e4
LT
1457 return 0;
1458 }
1459
1460 idx = dvb_ringbuffer_pkt_next(&ca->slot_info[slot].rx_buffer, -1, &fraglen);
1461 while (idx != -1) {
b0ba0e3a 1462 dvb_ringbuffer_pkt_read(&ca->slot_info[slot].rx_buffer, idx, 0, hdr, 2);
1da177e4
LT
1463 if (connection_id == -1)
1464 connection_id = hdr[0];
1465 if ((hdr[0] == connection_id) && ((hdr[1] & 0x80) == 0)) {
1466 *_slot = slot;
1467 found = 1;
1468 break;
1469 }
1470
1471 idx = dvb_ringbuffer_pkt_next(&ca->slot_info[slot].rx_buffer, idx, &fraglen);
1472 }
1473
ded92846 1474nextslot:
1da177e4
LT
1475 slot = (slot + 1) % ca->slot_count;
1476 slot_count++;
1477 }
1478
1479 ca->next_read_slot = slot;
1480 return found;
1481}
1482
1483
1484/**
1485 * Implementation of read() syscall.
1486 *
fbefb1a8
MCC
1487 * @file: File structure.
1488 * @buf: Destination buffer.
1489 * @count: Size of destination buffer.
1490 * @ppos: Position in file (ignored).
1da177e4
LT
1491 *
1492 * @return Number of bytes read, or <0 on error.
1493 */
8ec6107a
JJ
1494static ssize_t dvb_ca_en50221_io_read(struct file *file, char __user *buf,
1495 size_t count, loff_t *ppos)
1da177e4 1496{
0c53c70f
JS
1497 struct dvb_device *dvbdev = file->private_data;
1498 struct dvb_ca_private *ca = dvbdev->priv;
1da177e4
LT
1499 int status;
1500 int result = 0;
1501 u8 hdr[2];
1502 int slot;
1503 int connection_id = -1;
1504 size_t idx, idx2;
1505 int last_fragment = 0;
1506 size_t fraglen;
1507 int pktlen;
1508 int dispose = 0;
1509
46b4f7c1 1510 dprintk("%s\n", __func__);
1da177e4
LT
1511
1512 /* Outgoing packet has a 2 byte header. hdr[0] = slot_id, hdr[1] = connection_id */
1513 if (count < 2)
1514 return -EINVAL;
1515
1516 /* wait for some data */
1517 if ((status = dvb_ca_en50221_io_read_condition(ca, &result, &slot)) == 0) {
1518
1519 /* if we're in nonblocking mode, exit immediately */
1520 if (file->f_flags & O_NONBLOCK)
1521 return -EWOULDBLOCK;
1522
1523 /* wait for some data */
1524 status = wait_event_interruptible(ca->wait_queue,
1525 dvb_ca_en50221_io_read_condition
1526 (ca, &result, &slot));
1527 }
1528 if ((status < 0) || (result < 0)) {
1529 if (result)
1530 return result;
1531 return status;
1532 }
1533
1534 idx = dvb_ringbuffer_pkt_next(&ca->slot_info[slot].rx_buffer, -1, &fraglen);
1535 pktlen = 2;
1536 do {
1537 if (idx == -1) {
b3ad24d2
MCC
1538 pr_err("dvb_ca adapter %d: BUG: read packet ended before last_fragment encountered\n",
1539 ca->dvbdev->adapter->num);
1da177e4
LT
1540 status = -EIO;
1541 goto exit;
1542 }
1543
b0ba0e3a 1544 dvb_ringbuffer_pkt_read(&ca->slot_info[slot].rx_buffer, idx, 0, hdr, 2);
1da177e4
LT
1545 if (connection_id == -1)
1546 connection_id = hdr[0];
1547 if (hdr[0] == connection_id) {
1548 if (pktlen < count) {
1549 if ((pktlen + fraglen - 2) > count) {
1550 fraglen = count - pktlen;
1551 } else {
1552 fraglen -= 2;
1553 }
1554
b0ba0e3a
AV
1555 if ((status = dvb_ringbuffer_pkt_read_user(&ca->slot_info[slot].rx_buffer, idx, 2,
1556 buf + pktlen, fraglen)) < 0) {
1da177e4
LT
1557 goto exit;
1558 }
1559 pktlen += fraglen;
1560 }
1561
1562 if ((hdr[1] & 0x80) == 0)
1563 last_fragment = 1;
1564 dispose = 1;
1565 }
1566
1567 idx2 = dvb_ringbuffer_pkt_next(&ca->slot_info[slot].rx_buffer, idx, &fraglen);
1568 if (dispose)
1569 dvb_ringbuffer_pkt_dispose(&ca->slot_info[slot].rx_buffer, idx);
1570 idx = idx2;
1571 dispose = 0;
1572 } while (!last_fragment);
1573
1574 hdr[0] = slot;
1575 hdr[1] = connection_id;
e252984c
DC
1576 status = copy_to_user(buf, hdr, 2);
1577 if (status) {
1578 status = -EFAULT;
1da177e4 1579 goto exit;
e252984c 1580 }
1da177e4
LT
1581 status = pktlen;
1582
ded92846 1583exit:
1da177e4
LT
1584 return status;
1585}
1586
1587
1588/**
1589 * Implementation of file open syscall.
1590 *
fbefb1a8
MCC
1591 * @inode: Inode concerned.
1592 * @file: File concerned.
1da177e4
LT
1593 *
1594 * @return 0 on success, <0 on failure.
1595 */
1596static int dvb_ca_en50221_io_open(struct inode *inode, struct file *file)
1597{
0c53c70f
JS
1598 struct dvb_device *dvbdev = file->private_data;
1599 struct dvb_ca_private *ca = dvbdev->priv;
1da177e4
LT
1600 int err;
1601 int i;
1602
46b4f7c1 1603 dprintk("%s\n", __func__);
1da177e4
LT
1604
1605 if (!try_module_get(ca->pub->owner))
1606 return -EIO;
1607
1608 err = dvb_generic_open(inode, file);
226835d7
MS
1609 if (err < 0) {
1610 module_put(ca->pub->owner);
1da177e4 1611 return err;
226835d7 1612 }
1da177e4
LT
1613
1614 for (i = 0; i < ca->slot_count; i++) {
1615
1616 if (ca->slot_info[i].slot_state == DVB_CA_SLOTSTATE_RUNNING) {
1da177e4 1617 if (ca->slot_info[i].rx_buffer.data != NULL) {
ded92846
AQ
1618 /* it is safe to call this here without locks because
1619 * ca->open == 0. Data is not read in this case */
1da177e4
LT
1620 dvb_ringbuffer_flush(&ca->slot_info[i].rx_buffer);
1621 }
1da177e4
LT
1622 }
1623 }
1624
1625 ca->open = 1;
1626 dvb_ca_en50221_thread_update_delay(ca);
1627 dvb_ca_en50221_thread_wakeup(ca);
1628
da677fe1
MK
1629 dvb_ca_private_get(ca);
1630
1da177e4
LT
1631 return 0;
1632}
1633
1634
1635/**
1636 * Implementation of file close syscall.
1637 *
fbefb1a8
MCC
1638 * @inode: Inode concerned.
1639 * @file: File concerned.
1da177e4
LT
1640 *
1641 * @return 0 on success, <0 on failure.
1642 */
1643static int dvb_ca_en50221_io_release(struct inode *inode, struct file *file)
1644{
0c53c70f
JS
1645 struct dvb_device *dvbdev = file->private_data;
1646 struct dvb_ca_private *ca = dvbdev->priv;
0c12c1bf 1647 int err;
1da177e4 1648
46b4f7c1 1649 dprintk("%s\n", __func__);
1da177e4
LT
1650
1651 /* mark the CA device as closed */
1652 ca->open = 0;
1653 dvb_ca_en50221_thread_update_delay(ca);
1654
1655 err = dvb_generic_release(inode, file);
1656
1657 module_put(ca->pub->owner);
1658
da677fe1
MK
1659 dvb_ca_private_put(ca);
1660
0c12c1bf 1661 return err;
1da177e4
LT
1662}
1663
1664
1665/**
1666 * Implementation of poll() syscall.
1667 *
fbefb1a8
MCC
1668 * @file: File concerned.
1669 * @wait: poll wait table.
1da177e4
LT
1670 *
1671 * @return Standard poll mask.
1672 */
8ec6107a 1673static unsigned int dvb_ca_en50221_io_poll(struct file *file, poll_table *wait)
1da177e4 1674{
0c53c70f
JS
1675 struct dvb_device *dvbdev = file->private_data;
1676 struct dvb_ca_private *ca = dvbdev->priv;
1da177e4
LT
1677 unsigned int mask = 0;
1678 int slot;
1679 int result = 0;
1680
46b4f7c1 1681 dprintk("%s\n", __func__);
1da177e4
LT
1682
1683 if (dvb_ca_en50221_io_read_condition(ca, &result, &slot) == 1) {
1da177e4
LT
1684 mask |= POLLIN;
1685 }
1686
1687 /* if there is something, return now */
1688 if (mask)
1689 return mask;
1690
1691 /* wait for something to happen */
1692 poll_wait(file, &ca->wait_queue, wait);
1693
1694 if (dvb_ca_en50221_io_read_condition(ca, &result, &slot) == 1) {
1da177e4
LT
1695 mask |= POLLIN;
1696 }
1697
1698 return mask;
1699}
1700EXPORT_SYMBOL(dvb_ca_en50221_init);
1701
1702
784e29d2 1703static const struct file_operations dvb_ca_fops = {
1da177e4
LT
1704 .owner = THIS_MODULE,
1705 .read = dvb_ca_en50221_io_read,
1706 .write = dvb_ca_en50221_io_write,
16ef8def 1707 .unlocked_ioctl = dvb_ca_en50221_io_ioctl,
1da177e4
LT
1708 .open = dvb_ca_en50221_io_open,
1709 .release = dvb_ca_en50221_io_release,
1710 .poll = dvb_ca_en50221_io_poll,
6038f373 1711 .llseek = noop_llseek,
1da177e4
LT
1712};
1713
738a1b1e 1714static const struct dvb_device dvbdev_ca = {
1da177e4
LT
1715 .priv = NULL,
1716 .users = 1,
1717 .readers = 1,
1718 .writers = 1,
738a1b1e 1719#if defined(CONFIG_MEDIA_CONTROLLER_DVB)
e4fd3bc5 1720 .name = "dvb-ca-en50221",
738a1b1e 1721#endif
1da177e4
LT
1722 .fops = &dvb_ca_fops,
1723};
1724
1da177e4
LT
1725/* ******************************************************************************** */
1726/* Initialisation/shutdown functions */
1727
1728
1729/**
1730 * Initialise a new DVB CA EN50221 interface device.
1731 *
fbefb1a8
MCC
1732 * @dvb_adapter: DVB adapter to attach the new CA device to.
1733 * @ca: The dvb_ca instance.
1734 * @flags: Flags describing the CA device (DVB_CA_FLAG_*).
1735 * @slot_count: Number of slots supported.
1da177e4
LT
1736 *
1737 * @return 0 on success, nonzero on failure
1738 */
1739int dvb_ca_en50221_init(struct dvb_adapter *dvb_adapter,
1740 struct dvb_ca_en50221 *pubca, int flags, int slot_count)
1741{
1742 int ret;
1743 struct dvb_ca_private *ca = NULL;
1744 int i;
1745
46b4f7c1 1746 dprintk("%s\n", __func__);
1da177e4
LT
1747
1748 if (slot_count < 1)
1749 return -EINVAL;
1750
1751 /* initialise the system data */
7408187d 1752 if ((ca = kzalloc(sizeof(struct dvb_ca_private), GFP_KERNEL)) == NULL) {
1da177e4 1753 ret = -ENOMEM;
a2bbf5d0 1754 goto exit;
1da177e4 1755 }
da677fe1 1756 kref_init(&ca->refcount);
1da177e4
LT
1757 ca->pub = pubca;
1758 ca->flags = flags;
1759 ca->slot_count = slot_count;
7408187d 1760 if ((ca->slot_info = kcalloc(slot_count, sizeof(struct dvb_ca_slot), GFP_KERNEL)) == NULL) {
1da177e4 1761 ret = -ENOMEM;
a2bbf5d0 1762 goto free_ca;
1da177e4 1763 }
1da177e4 1764 init_waitqueue_head(&ca->wait_queue);
1da177e4
LT
1765 ca->open = 0;
1766 ca->wakeup = 0;
1767 ca->next_read_slot = 0;
1768 pubca->private = ca;
1769
1770 /* register the DVB device */
df2f94e5 1771 ret = dvb_register_device(dvb_adapter, &ca->dvbdev, &dvbdev_ca, ca, DVB_DEVICE_CA, 0);
1da177e4 1772 if (ret)
a2bbf5d0 1773 goto free_slot_info;
1da177e4
LT
1774
1775 /* now initialise each slot */
1776 for (i = 0; i < slot_count; i++) {
1777 memset(&ca->slot_info[i], 0, sizeof(struct dvb_ca_slot));
1778 ca->slot_info[i].slot_state = DVB_CA_SLOTSTATE_NONE;
1779 atomic_set(&ca->slot_info[i].camchange_count, 0);
1780 ca->slot_info[i].camchange_type = DVB_CA_EN50221_CAMCHANGE_REMOVED;
d7e43844 1781 mutex_init(&ca->slot_info[i].slot_lock);
1da177e4
LT
1782 }
1783
30ad64b8
NS
1784 mutex_init(&ca->ioctl_mutex);
1785
1da177e4
LT
1786 if (signal_pending(current)) {
1787 ret = -EINTR;
a2bbf5d0 1788 goto unregister_device;
1da177e4
LT
1789 }
1790 mb();
1791
1792 /* create a kthread for monitoring this CA device */
9320874a
CH
1793 ca->thread = kthread_run(dvb_ca_en50221_thread, ca, "kdvb-ca-%i:%i",
1794 ca->dvbdev->adapter->num, ca->dvbdev->id);
1795 if (IS_ERR(ca->thread)) {
1796 ret = PTR_ERR(ca->thread);
b3ad24d2
MCC
1797 pr_err("dvb_ca_init: failed to start kernel_thread (%d)\n",
1798 ret);
a2bbf5d0 1799 goto unregister_device;
1da177e4 1800 }
1da177e4
LT
1801 return 0;
1802
a2bbf5d0
ME
1803unregister_device:
1804 dvb_unregister_device(ca->dvbdev);
1805free_slot_info:
1806 kfree(ca->slot_info);
1807free_ca:
1808 kfree(ca);
1809exit:
1da177e4
LT
1810 pubca->private = NULL;
1811 return ret;
1812}
1813EXPORT_SYMBOL(dvb_ca_en50221_release);
1814
1815
1816
1817/**
1818 * Release a DVB CA EN50221 interface device.
1819 *
fbefb1a8
MCC
1820 * @ca_dev: The dvb_device_t instance for the CA device.
1821 * @ca: The associated dvb_ca instance.
1da177e4
LT
1822 */
1823void dvb_ca_en50221_release(struct dvb_ca_en50221 *pubca)
1824{
0c53c70f 1825 struct dvb_ca_private *ca = pubca->private;
1da177e4
LT
1826 int i;
1827
46b4f7c1 1828 dprintk("%s\n", __func__);
1da177e4
LT
1829
1830 /* shutdown the thread if there was one */
9320874a 1831 kthread_stop(ca->thread);
1da177e4
LT
1832
1833 for (i = 0; i < ca->slot_count; i++) {
1834 dvb_ca_en50221_slot_shutdown(ca, i);
1835 }
4d5030b6 1836 dvb_remove_device(ca->dvbdev);
da677fe1 1837 dvb_ca_private_put(ca);
1da177e4
LT
1838 pubca->private = NULL;
1839}