31 #include <linux/errno.h>
32 #include <linux/slab.h>
33 #include <linux/list.h>
34 #include <linux/module.h>
38 #include <linux/sched.h>
44 static int dvb_ca_en50221_debug;
49 #define dprintk if (dvb_ca_en50221_debug) printk
51 #define INIT_TIMEOUT_SECS 10
53 #define HOST_LINK_BUF_SIZE 0x200
55 #define RX_BUFFER_SIZE 65535
57 #define MAX_RX_PACKETS_PER_ITERATION 10
60 #define CTRLIF_COMMAND 1
61 #define CTRLIF_STATUS 1
62 #define CTRLIF_SIZE_LOW 2
63 #define CTRLIF_SIZE_HIGH 3
69 #define CMDREG_FRIE 0x40
70 #define CMDREG_DAIE 0x80
71 #define IRQEN (CMDREG_DAIE)
73 #define STATUSREG_RE 1
74 #define STATUSREG_WE 2
75 #define STATUSREG_FR 0x40
76 #define STATUSREG_DA 0x80
77 #define STATUSREG_TXERR (STATUSREG_RE|STATUSREG_WE)
80 #define DVB_CA_SLOTSTATE_NONE 0
81 #define DVB_CA_SLOTSTATE_UNINITIALISED 1
82 #define DVB_CA_SLOTSTATE_RUNNING 2
83 #define DVB_CA_SLOTSTATE_INVALID 3
84 #define DVB_CA_SLOTSTATE_WAITREADY 4
85 #define DVB_CA_SLOTSTATE_VALIDATE 5
86 #define DVB_CA_SLOTSTATE_WAITFR 6
87 #define DVB_CA_SLOTSTATE_LINKINIT 7
175 static char *findstr(
char * haystack,
int hlen,
char * needle,
int nlen)
182 for (i = 0; i <= hlen - nlen; i++) {
183 if (!
strncmp(haystack + i, needle, nlen))
211 slot_status = ca->
pub->poll_slot_status(ca->
pub, slot, ca->
open);
217 cam_changed = (cam_present_now != cam_present_old);
221 if (!cam_present_now) {
250 static int dvb_ca_en50221_wait_if_status(
struct dvb_ca_private *ca,
int slot,
251 u8 waitfor,
int timeout_hz)
260 timeout =
jiffies + timeout_hz;
269 dprintk(
"%s succeeded timeout:%lu\n", __func__, jiffies - start);
282 dprintk(
"%s failed timeout:%lu\n", __func__, jiffies - start);
297 static int dvb_ca_en50221_link_init(
struct dvb_ca_private *ca,
int slot)
315 if ((ret = dvb_ca_en50221_wait_if_status(ca, slot,
STATUSREG_DA,
HZ / 10)) != 0)
317 if ((ret = dvb_ca_en50221_read_data(ca, slot, buf, 2)) != 2)
323 buf_size = (buf[0] << 8) | buf[1];
327 buf[0] = buf_size >> 8;
328 buf[1] = buf_size & 0xff;
329 dprintk(
"Chosen link buffer size of %i\n", buf_size);
334 if ((ret = dvb_ca_en50221_wait_if_status(ca, slot,
STATUSREG_FR,
HZ / 10)) != 0)
336 if ((ret = dvb_ca_en50221_write_data(ca, slot, buf, 2)) != 2)
357 static int dvb_ca_en50221_read_tuple(
struct dvb_ca_private *ca,
int slot,
358 int *
address,
int *tupleType,
int *tupleLength,
u8 * tuple)
366 if ((_tupleType = ca->
pub->read_attribute_mem(ca->
pub, slot, _address)) < 0)
368 if (_tupleType == 0xff) {
369 dprintk(
"END OF CHAIN TUPLE type:0x%x\n", _tupleType);
371 *tupleType = _tupleType;
375 if ((_tupleLength = ca->
pub->read_attribute_mem(ca->
pub, slot, _address + 2)) < 0)
379 dprintk(
"TUPLE type:0x%x length:%i\n", _tupleType, _tupleLength);
382 for (i = 0; i < _tupleLength; i++) {
383 tuple[
i] = ca->
pub->read_attribute_mem(ca->
pub, slot, _address + (i * 2));
384 dprintk(
" 0x%02x: 0x%02x %c\n",
386 ((tuple[i] > 31) && (tuple[i] < 127)) ? tuple[i] :
'.');
388 _address += (_tupleLength * 2);
391 *tupleType = _tupleType;
392 *tupleLength = _tupleLength;
407 static int dvb_ca_en50221_parse_attributes(
struct dvb_ca_private *ca,
int slot)
416 int got_cftableentry = 0;
425 dvb_ca_en50221_read_tuple(ca, slot, &address, &tupleType, &tupleLength, tuple)) < 0)
427 if (tupleType != 0x1D)
434 dvb_ca_en50221_read_tuple(ca, slot, &address, &tupleType, &tupleLength, tuple)) < 0)
436 if (tupleType != 0x1C)
443 dvb_ca_en50221_read_tuple(ca, slot, &address, &tupleType, &tupleLength, tuple)) < 0)
445 if (tupleType != 0x15)
451 if ((status = dvb_ca_en50221_read_tuple(ca, slot, &address, &tupleType,
452 &tupleLength, tuple)) < 0)
454 if (tupleType != 0x20)
456 if (tupleLength != 4)
458 manfid = (tuple[1] << 8) | tuple[0];
459 devid = (tuple[3] << 8) | tuple[2];
464 if ((status = dvb_ca_en50221_read_tuple(ca, slot, &address, &tupleType,
465 &tupleLength, tuple)) < 0)
467 if (tupleType != 0x1A)
474 if (tupleLength < (3 + rasz + 14))
477 for (i = 0; i < rasz + 1; i++) {
482 dvb_str = findstr((
char *)tuple, tupleLength,
"DVB_CI_V", 8);
485 if (tupleLength < ((dvb_str - (
char *) tuple) + 12))
489 if (
strncmp(dvb_str + 8,
"1.00", 4)) {
490 printk(
"dvb_ca adapter %d: Unsupported DVB CAM module version %c%c%c%c\n",
491 ca->
dvbdev->adapter->num, dvb_str[8], dvb_str[9], dvb_str[10], dvb_str[11]);
496 while ((!end_chain) && (address < 0x1000)) {
497 if ((status = dvb_ca_en50221_read_tuple(ca, slot, &address, &tupleType,
498 &tupleLength, tuple)) < 0)
502 if (tupleLength < (2 + 11 + 17))
506 if (got_cftableentry)
513 if ((findstr((
char *)tuple, tupleLength,
"DVB_HOST", 8) ==
NULL) ||
514 (findstr((
char *)tuple, tupleLength,
"DVB_CI_MODULE", 13) ==
NULL))
517 got_cftableentry = 1;
528 dprintk(
"dvb_ca: Skipping unknown tuple type:0x%x length:0x%x\n", tupleType,
534 if ((address > 0x1000) || (!got_cftableentry))
537 dprintk(
"Valid DVB CAM detected MANID:%x DEVID:%x CONFIGBASE:0x%x CONFIGOPTION:0x%x\n",
551 static int dvb_ca_en50221_set_configoption(
struct dvb_ca_private *ca,
int slot)
558 ca->
pub->write_attribute_mem(ca->
pub, slot,
563 configoption = ca->
pub->read_attribute_mem(ca->
pub, slot, ca->
slot_info[slot].config_base);
564 dprintk(
"Set configoption 0x%x, read configoption 0x%x\n",
565 ca->
slot_info[slot].config_option, configoption & 0x3f);
586 static int dvb_ca_en50221_read_data(
struct dvb_ca_private *ca,
int slot,
u8 * ebuf,
int ecount)
623 bytes_read = status << 8;
630 if (bytes_read > ca->
slot_info[slot].link_buf_size) {
631 printk(
"dvb_ca adapter %d: CAM tried to send a buffer larger than the link buffer size (%i > %i)!\n",
632 ca->
dvbdev->adapter->num, bytes_read, ca->
slot_info[slot].link_buf_size);
637 if (bytes_read < 2) {
638 printk(
"dvb_ca adapter %d: CAM sent a buffer that was less than 2 bytes!\n",
639 ca->
dvbdev->adapter->num);
645 if (bytes_read > ecount) {
646 printk(
"dvb_ca adapter %d: CAM tried to send a buffer larger than the ecount size!\n",
647 ca->
dvbdev->adapter->num);
654 for (i = 0; i < bytes_read; i++) {
680 memcpy(ebuf, buf, bytes_read);
683 dprintk(
"Received CA packet for slot %i connection id 0x%x last_frag:%i size:0x%x\n", slot,
684 buf[0], (buf[1] & 0x80) == 0, bytes_read);
687 if ((buf[1] & 0x80) == 0x00) {
709 static int dvb_ca_en50221_write_data(
struct dvb_ca_private *ca,
int slot,
u8 * buf,
int bytes_write)
718 if (bytes_write > ca->
slot_info[slot].link_buf_size)
727 if (status & (STATUSREG_DA | STATUSREG_RE)) {
728 if (status & STATUSREG_DA)
729 dvb_ca_en50221_thread_wakeup(ca);
753 bytes_write & 0xff)) != 0)
757 for (i = 0; i < bytes_write; i++) {
758 if ((status = ca->
pub->write_cam_control(ca->
pub, slot,
CTRLIF_DATA, buf[i])) != 0)
770 status = bytes_write;
772 dprintk(
"Wrote CA packet for slot %i, connection id 0x%x last_frag:%i size:0x%x\n", slot,
773 buf[0], (buf[1] & 0x80) == 0, bytes_write);
795 static int dvb_ca_en50221_slot_shutdown(
struct dvb_ca_private *ca,
int slot)
799 ca->
pub->slot_shutdown(ca->
pub, slot);
806 dprintk(
"Slot %i shutdown\n", slot);
825 dprintk(
"CAMCHANGE IRQ slot:%i change_type:%i\n", slot, change_type);
827 switch (change_type) {
838 dvb_ca_en50221_thread_wakeup(ca);
853 dprintk(
"CAMREADY IRQ slot:%i\n", slot);
857 dvb_ca_en50221_thread_wakeup(ca);
873 dprintk(
"FR/DA IRQ slot:%i\n", slot);
875 switch (ca->
slot_info[slot].slot_state) {
878 if (flags & STATUSREG_DA) {
879 dprintk(
"CAM supports DA IRQ\n");
886 dvb_ca_en50221_thread_wakeup(ca);
901 static void dvb_ca_en50221_thread_wakeup(
struct dvb_ca_private *ca)
916 static void dvb_ca_en50221_thread_update_delay(
struct dvb_ca_private *ca)
919 int curdelay = 100000000;
925 for (slot = 0; slot < ca->
slot_count; slot++) {
926 switch (ca->
slot_info[slot].slot_state) {
952 if ((!ca->
slot_info[slot].da_irq_supported) ||
959 if (delay < curdelay)
963 ca->
delay = curdelay;
971 static int dvb_ca_en50221_thread(
void *
data)
983 dvb_ca_en50221_thread_update_delay(ca);
997 for (slot = 0; slot < ca->
slot_count; slot++) {
1002 while (dvb_ca_en50221_check_camstatus(ca, slot)) {
1005 dvb_ca_en50221_slot_shutdown(ca, slot);
1013 dvb_ca_en50221_thread_update_delay(ca);
1018 switch (ca->
slot_info[slot].slot_state) {
1026 ca->
pub->slot_reset(ca->
pub, slot);
1032 printk(
"dvb_ca adaptor %d: PC card did not respond :(\n",
1033 ca->
dvbdev->adapter->num);
1035 dvb_ca_en50221_thread_update_delay(ca);
1042 if (dvb_ca_en50221_parse_attributes(ca, slot) != 0) {
1045 (ca->
pub->poll_slot_status)) {
1046 status = ca->
pub->poll_slot_status(ca->
pub, slot, 0);
1049 dvb_ca_en50221_thread_update_delay(ca);
1054 printk(
"dvb_ca adapter %d: Invalid PC card inserted :(\n",
1055 ca->
dvbdev->adapter->num);
1057 dvb_ca_en50221_thread_update_delay(ca);
1060 if (dvb_ca_en50221_set_configoption(ca, slot) != 0) {
1061 printk(
"dvb_ca adapter %d: Unable to initialise CAM :(\n",
1062 ca->
dvbdev->adapter->num);
1064 dvb_ca_en50221_thread_update_delay(ca);
1067 if (ca->
pub->write_cam_control(ca->
pub, slot,
1069 printk(
"dvb_ca adapter %d: Unable to reset CAM IF\n",
1070 ca->
dvbdev->adapter->num);
1072 dvb_ca_en50221_thread_update_delay(ca);
1075 dprintk(
"DVB CAM validated successfully\n");
1084 printk(
"dvb_ca adapter %d: DVB CAM did not respond :(\n",
1085 ca->
dvbdev->adapter->num);
1087 dvb_ca_en50221_thread_update_delay(ca);
1092 if (flags & STATUSREG_FR) {
1099 if (dvb_ca_en50221_link_init(ca, slot) != 0) {
1102 (ca->
pub->poll_slot_status)) {
1103 status = ca->
pub->poll_slot_status(ca->
pub, slot, 0);
1106 dvb_ca_en50221_thread_update_delay(ca);
1111 printk(
"dvb_ca adapter %d: DVB CAM link initialisation failed :(\n", ca->
dvbdev->adapter->num);
1113 dvb_ca_en50221_thread_update_delay(ca);
1119 if (rxbuf ==
NULL) {
1120 printk(
"dvb_ca adapter %d: Unable to allocate CAM rx buffer :(\n", ca->
dvbdev->adapter->num);
1122 dvb_ca_en50221_thread_update_delay(ca);
1128 ca->
pub->slot_ts_enable(ca->
pub, slot);
1130 dvb_ca_en50221_thread_update_delay(ca);
1131 printk(
"dvb_ca adapter %d: DVB CAM detected and initialised successfully\n", ca->
dvbdev->adapter->num);
1140 while ((status = dvb_ca_en50221_read_data(ca, slot,
NULL, 0)) > 0) {
1145 if (dvb_ca_en50221_check_camstatus(ca, slot)) {
1184 static int dvb_ca_en50221_io_do_ioctl(
struct file *
file,
1185 unsigned int cmd,
void *parg)
1196 for (slot = 0; slot < ca->
slot_count; slot++) {
1199 dvb_ca_en50221_slot_shutdown(ca, slot);
1208 dvb_ca_en50221_thread_wakeup(ca);
1258 static long dvb_ca_en50221_io_ioctl(
struct file *file,
1259 unsigned int cmd,
unsigned long arg)
1261 return dvb_usercopy(file, cmd, arg, dvb_ca_en50221_io_do_ioctl);
1275 static ssize_t dvb_ca_en50221_io_write(
struct file *file,
1276 const char __user * buf,
size_t count, loff_t * ppos)
1285 unsigned long timeout;
1307 while (fragpos < count) {
1313 if ((count - fragpos) < fraglen)
1314 fraglen = count - fragpos;
1316 fragbuf[0] = connection_id;
1317 fragbuf[1] = ((fragpos + fraglen) < count) ? 0x80 : 0x00;
1334 status = dvb_ca_en50221_write_data(ca, slot, fragbuf, fraglen + 2);
1336 if (status == (fraglen + 2)) {
1362 static int dvb_ca_en50221_io_read_condition(
struct dvb_ca_private *ca,
1369 int connection_id = -1;
1374 while ((slot_count < ca->slot_count) && (!found)) {
1385 if (connection_id == -1)
1386 connection_id = hdr[0];
1387 if ((hdr[0] == connection_id) && ((hdr[1] & 0x80) == 0)) {
1416 static ssize_t dvb_ca_en50221_io_read(
struct file *file,
char __user * buf,
1417 size_t count, loff_t * ppos)
1425 int connection_id = -1;
1427 int last_fragment = 0;
1439 if ((status = dvb_ca_en50221_io_read_condition(ca, &result, &slot)) == 0) {
1447 dvb_ca_en50221_io_read_condition
1448 (ca, &result, &slot));
1450 if ((status < 0) || (result < 0)) {
1460 printk(
"dvb_ca adapter %d: BUG: read packet ended before last_fragment encountered\n", ca->
dvbdev->adapter->num);
1466 if (connection_id == -1)
1467 connection_id = hdr[0];
1468 if (hdr[0] == connection_id) {
1469 if (pktlen < count) {
1470 if ((pktlen + fraglen - 2) > count) {
1471 fraglen = count -
pktlen;
1477 buf + pktlen, fraglen)) < 0) {
1483 if ((hdr[1] & 0x80) == 0)
1493 }
while (!last_fragment);
1496 hdr[1] = connection_id;
1517 static int dvb_ca_en50221_io_open(
struct inode *
inode,
struct file *file)
1526 if (!try_module_get(ca->
pub->owner))
1531 module_put(ca->
pub->owner);
1547 dvb_ca_en50221_thread_update_delay(ca);
1548 dvb_ca_en50221_thread_wakeup(ca);
1562 static int dvb_ca_en50221_io_release(
struct inode *inode,
struct file *file)
1572 dvb_ca_en50221_thread_update_delay(ca);
1576 module_put(ca->
pub->owner);
1590 static unsigned int dvb_ca_en50221_io_poll(
struct file *file,
poll_table *
wait)
1594 unsigned int mask = 0;
1600 if (dvb_ca_en50221_io_read_condition(ca, &result, &slot) == 1) {
1611 if (dvb_ca_en50221_io_read_condition(ca, &result, &slot) == 1) {
1622 .read = dvb_ca_en50221_io_read,
1623 .write = dvb_ca_en50221_io_write,
1624 .unlocked_ioctl = dvb_ca_en50221_io_ioctl,
1625 .open = dvb_ca_en50221_io_open,
1626 .release = dvb_ca_en50221_io_release,
1627 .poll = dvb_ca_en50221_io_poll,
1636 .fops = &dvb_ca_fops,
1698 if (signal_pending(
current)) {
1707 if (IS_ERR(ca->
thread)) {
1708 ret = PTR_ERR(ca->
thread);
1709 printk(
"dvb_ca_init: failed to start kernel_thread (%d)\n",
1746 dvb_ca_en50221_slot_shutdown(ca, i);