summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew de Quincy <devnull@localhost>2004-04-08 14:39:31 +0000
committerAndrew de Quincy <devnull@localhost>2004-04-08 14:39:31 +0000
commit5dbf87200da4841d544b18c967c3f2237c8a258a (patch)
tree2cd3966e1558b5725fa743c479da286516c85e7b
parent58b1e61e934285c18557d0e48d8deda6aee7ba24 (diff)
downloadmediapointer-dvb-s2-5dbf87200da4841d544b18c967c3f2237c8a258a.tar.gz
mediapointer-dvb-s2-5dbf87200da4841d544b18c967c3f2237c8a258a.tar.bz2
Fix for 100% CPU usage on CAM failure
-rw-r--r--linux/drivers/media/dvb/dvb-core/dvb_ca_en50221.c36
1 files changed, 14 insertions, 22 deletions
diff --git a/linux/drivers/media/dvb/dvb-core/dvb_ca_en50221.c b/linux/drivers/media/dvb/dvb-core/dvb_ca_en50221.c
index 496caeb05..7f57ce152 100644
--- a/linux/drivers/media/dvb/dvb-core/dvb_ca_en50221.c
+++ b/linux/drivers/media/dvb/dvb-core/dvb_ca_en50221.c
@@ -156,9 +156,6 @@ struct dvb_ca_private {
/* Flag indicating the thread should wake up now */
int wakeup:1;
- /* One of the slots in this interface does not support IRQs */
- int needpolling:1;
-
/* Delay the main thread should use */
unsigned long delay;
@@ -875,18 +872,14 @@ static void dvb_ca_en50221_thread_wakeup(struct dvb_ca_private* ca)
*
* @param ca CA instance.
*/
-static int dvb_ca_en50221_thread_should_wakeup(struct dvb_ca_private* ca, int* iterations)
+static int dvb_ca_en50221_thread_should_wakeup(struct dvb_ca_private* ca)
{
if (ca->wakeup) {
ca->wakeup = 0;
return 1;
}
if (ca->exit) return 1;
- if (ca->needpolling) {
- if (*iterations) return 1;
- (*iterations)++;
- }
-
+
return 0;
}
@@ -902,7 +895,6 @@ static void dvb_ca_en50221_thread_update_delay(struct dvb_ca_private* ca)
int curdelay = 100000000;
int slot;
- ca->needpolling = 0;
for(slot=0; slot < ca->slot_count; slot++) {
switch(ca->slot_info[slot].slot_state) {
default:
@@ -910,7 +902,6 @@ static void dvb_ca_en50221_thread_update_delay(struct dvb_ca_private* ca)
case DVB_CA_SLOTSTATE_INVALID:
delay = HZ*60;
if (!(ca->flags & DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE)) {
- ca->needpolling = 1;
delay = HZ/10;
}
break;
@@ -920,20 +911,17 @@ static void dvb_ca_en50221_thread_update_delay(struct dvb_ca_private* ca)
case DVB_CA_SLOTSTATE_VALIDATE:
case DVB_CA_SLOTSTATE_WAITFR:
case DVB_CA_SLOTSTATE_LINKINIT:
- ca->needpolling = 1;
delay = HZ/10;
break;
case DVB_CA_SLOTSTATE_RUNNING:
delay = HZ*60;
if (!(ca->flags & DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE)) {
- ca->needpolling = 1;
delay = HZ/10;
}
if (ca->open) {
if ((!ca->slot_info[slot].da_irq_supported) ||
(!(ca->flags & DVB_CA_EN50221_FLAG_IRQ_DA))) {
- ca->needpolling = 1;
delay = HZ/100;
}
}
@@ -959,7 +947,6 @@ static int dvb_ca_en50221_thread(void* data)
int flags;
int pktcount;
void* rxbuf;
- int iterations;
dprintk ("%s\n", __FUNCTION__);
@@ -974,8 +961,7 @@ static int dvb_ca_en50221_thread(void* data)
while(!ca->exit) {
/* sleep for a bit */
if (!ca->wakeup) {
- iterations = 0;
- flags = wait_event_interruptible_timeout(ca->thread_queue, dvb_ca_en50221_thread_should_wakeup(ca, &iterations), ca->delay);
+ flags = wait_event_interruptible_timeout(ca->thread_queue, dvb_ca_en50221_thread_should_wakeup(ca), ca->delay);
if ((flags == -ERESTARTSYS) || ca->exit) {
/* got signal or quitting */
break;
@@ -1016,8 +1002,9 @@ static int dvb_ca_en50221_thread(void* data)
case DVB_CA_SLOTSTATE_WAITREADY:
if (time_after(jiffies, ca->slot_info[slot].timeout)) {
- printk("dvb_ca: PC card did not respond\n");
+ printk("dvb_ca: PC card did not respond :(\n");
ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_INVALID;
+ dvb_ca_en50221_thread_update_delay(ca);
break;
}
// no other action needed; will automatically change state when ready
@@ -1025,13 +1012,15 @@ static int dvb_ca_en50221_thread(void* data)
case DVB_CA_SLOTSTATE_VALIDATE:
if (dvb_ca_en50221_parse_attributes(ca, slot) != 0) {
- printk("dvb_ca: Invalid PC card inserted\n");
+ printk("dvb_ca: Invalid PC card inserted :(\n");
ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_INVALID;
+ dvb_ca_en50221_thread_update_delay(ca);
break;
}
if (dvb_ca_en50221_set_configoption(ca, slot) != 0) {
- printk("dvb_ca: Unable to initialise CAM\n");
+ printk("dvb_ca: Unable to initialise CAM :(\n");
ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_INVALID;
+ dvb_ca_en50221_thread_update_delay(ca);
break;
}
@@ -1044,8 +1033,9 @@ static int dvb_ca_en50221_thread(void* data)
case DVB_CA_SLOTSTATE_WAITFR:
if (time_after(jiffies, ca->slot_info[slot].timeout)) {
- printk("dvb_ca: DVB CAM did not respond\n");
+ printk("dvb_ca: DVB CAM did not respond :(\n");
ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_INVALID;
+ dvb_ca_en50221_thread_update_delay(ca);
break;
}
@@ -1060,13 +1050,15 @@ static int dvb_ca_en50221_thread(void* data)
if (dvb_ca_en50221_link_init(ca, slot) != 0) {
printk("dvb_ca: DVB CAM link initialisation failed :(\n");
ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_INVALID;
+ dvb_ca_en50221_thread_update_delay(ca);
break;
}
rxbuf = vmalloc(RX_BUFFER_SIZE);
if (rxbuf == NULL) {
- printk("dvb_ca: Unable to allocate CAM rx buffer\n");
+ printk("dvb_ca: Unable to allocate CAM rx buffer :(\n");
ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_INVALID;
+ dvb_ca_en50221_thread_update_delay(ca);
break;
}
dvb_ringbuffer_init(&ca->slot_info[slot].rx_buffer, rxbuf, RX_BUFFER_SIZE);