diff options
author | Andrew de Quincy <devnull@localhost> | 2004-04-08 14:39:31 +0000 |
---|---|---|
committer | Andrew de Quincy <devnull@localhost> | 2004-04-08 14:39:31 +0000 |
commit | 5dbf87200da4841d544b18c967c3f2237c8a258a (patch) | |
tree | 2cd3966e1558b5725fa743c479da286516c85e7b | |
parent | 58b1e61e934285c18557d0e48d8deda6aee7ba24 (diff) | |
download | mediapointer-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.c | 36 |
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); |