diff options
author | Holger Waechtler <devnull@localhost> | 2002-11-15 14:36:18 +0000 |
---|---|---|
committer | Holger Waechtler <devnull@localhost> | 2002-11-15 14:36:18 +0000 |
commit | 95d59f27fe9a34fe457ba3313f845a4cb9a80cd6 (patch) | |
tree | 32c9e4b84aa42227a41fa1f428d323714e28675e /linux/drivers/media/dvb | |
parent | fa11322bf2bcab6d953b79dc6fa61ce9cb8ff4df (diff) | |
download | mediapointer-dvb-s2-95d59f27fe9a34fe457ba3313f845a4cb9a80cd6.tar.gz mediapointer-dvb-s2-95d59f27fe9a34fe457ba3313f845a4cb9a80cd6.tar.bz2 |
frontend notification fixes by Florian Schirmer
Diffstat (limited to 'linux/drivers/media/dvb')
-rw-r--r-- | linux/drivers/media/dvb/dvb-core/dvb_frontend.c | 131 | ||||
-rw-r--r-- | linux/drivers/media/dvb/dvb-core/dvb_frontend.h | 2 |
2 files changed, 86 insertions, 47 deletions
diff --git a/linux/drivers/media/dvb/dvb-core/dvb_frontend.c b/linux/drivers/media/dvb/dvb-core/dvb_frontend.c index 1d0bdd5bc..614fa281b 100644 --- a/linux/drivers/media/dvb/dvb-core/dvb_frontend.c +++ b/linux/drivers/media/dvb/dvb-core/dvb_frontend.c @@ -52,18 +52,10 @@ struct dvb_fe_events { }; -struct dvb_fe_notifier_callbacks { - struct list_head list_head; - void (*callback) (fe_status_t s, void *data); - void *data; -}; - - struct dvb_frontend_data { struct dvb_frontend_info *info; struct dvb_frontend frontend; struct dvb_device *dvbdev; - struct list_head notifier_callbacks; struct dvb_frontend_parameters parameters; struct dvb_fe_events events; struct semaphore sem; @@ -92,8 +84,17 @@ struct dvb_frontend_ioctl_data { }; +struct dvb_frontend_notifier_data { + struct list_head list_head; + struct dvb_adapter *adapter; + void (*callback) (fe_status_t s, void *data); + void *data; +}; + + static LIST_HEAD(frontend_list); static LIST_HEAD(frontend_ioctl_list); +static LIST_HEAD(frontend_notifier_list); static DECLARE_MUTEX(frontend_mutex); @@ -192,9 +193,6 @@ static void dvb_call_frontend_notifiers (struct dvb_frontend_data *fe, fe_status_t s) { - struct list_head *e; - struct dvb_fe_notifier_callbacks *c; - dprintk ("%s\n", __FUNCTION__); if ((fe->status & FE_HAS_LOCK) && !(s & FE_HAS_LOCK)) @@ -211,10 +209,8 @@ void dvb_call_frontend_notifiers (struct dvb_frontend_data *fe, /** * now tell the Demux about the TS status changes... */ - list_for_each (e, &fe->notifier_callbacks) { - c = list_entry (e, struct dvb_fe_notifier_callbacks, list_head); - c->callback (fe->status, c->data); - } + if (fe->frontend.notifier_callback) + fe->frontend.notifier_callback(fe->status, fe->frontend.notifier_data); } @@ -472,7 +468,7 @@ int dvb_frontend_thread (void *data) fe->lost_sync_count = 0; } else { fe->lost_sync_count++; - if (fe->lost_sync_count < 10) /* XXX FIXME CHECKME! */ + if (fe->lost_sync_count < 4) /* XXX FIXME CHECKME! */ continue; dvb_frontend_recover (fe); delay = HZ/5; @@ -686,7 +682,7 @@ dvb_remove_frontend_ioctls (struct dvb_adapter *adapter, int (*after_ioctl) (struct dvb_frontend *frontend, unsigned int cmd, void *arg)) { - struct list_head *entry; + struct list_head *entry, *n; dprintk ("%s\n", __FUNCTION__); @@ -708,6 +704,22 @@ dvb_remove_frontend_ioctls (struct dvb_adapter *adapter, } } + list_for_each_safe (entry, n, &frontend_ioctl_list) { + struct dvb_frontend_ioctl_data *ioctl; + + ioctl = list_entry (entry, struct dvb_frontend_ioctl_data, list_head); + + if (ioctl->adapter == adapter && + ioctl->before_ioctl == before_ioctl && + ioctl->after_ioctl == after_ioctl) + { + list_del (&ioctl->list_head); + kfree (ioctl); + + break; + } + } + up (&frontend_mutex); } @@ -717,41 +729,45 @@ dvb_add_frontend_notifier (struct dvb_adapter *adapter, void (*callback) (fe_status_t s, void *data), void *data) { - struct list_head *entry; + struct dvb_frontend_notifier_data *notifier; + struct list_head *entry; + int frontend_count = 0; dprintk ("%s\n", __FUNCTION__); if (down_interruptible (&frontend_mutex)) return -ERESTARTSYS; - list_for_each (entry, &frontend_list) { - struct dvb_frontend_data *fe; + notifier = kmalloc (sizeof(struct dvb_frontend_notifier_data), GFP_KERNEL); - fe = list_entry (entry, struct dvb_frontend_data, list_head); + if (!notifier) { + up (&frontend_mutex); + return -ENOMEM; + } - if (fe->frontend.i2c->adapter == adapter) { - struct dvb_fe_notifier_callbacks *e; + notifier->adapter = adapter; + notifier->callback = callback; + notifier->data = data; - e = kmalloc (sizeof(struct dvb_fe_notifier_callbacks), - GFP_KERNEL); + list_add_tail (¬ifier->list_head, &frontend_notifier_list); - if (!e) { - up (&frontend_mutex); - return -ENOMEM; - } + list_for_each (entry, &frontend_list) { + struct dvb_frontend_data *fe; - e->callback = callback; - e->data = data; - list_add_tail (&e->list_head, &fe->notifier_callbacks); + fe = list_entry (entry, struct dvb_frontend_data, list_head); - up (&frontend_mutex); - return 0; + if (fe->frontend.i2c->adapter == adapter && + fe->frontend.notifier_callback == NULL) + { + fe->frontend.notifier_callback = callback; + fe->frontend.notifier_data = data; + frontend_count++; } } up (&frontend_mutex); - return -ENODEV; + return frontend_count; } @@ -759,7 +775,7 @@ void dvb_remove_frontend_notifier (struct dvb_adapter *adapter, void (*callback) (fe_status_t s, void *data)) { - struct list_head *entry; + struct list_head *entry, *n; dprintk ("%s\n", __FUNCTION__); @@ -771,18 +787,26 @@ dvb_remove_frontend_notifier (struct dvb_adapter *adapter, fe = list_entry (entry, struct dvb_frontend_data, list_head); - if (fe->frontend.i2c->adapter == adapter) { - struct list_head *e0, *n0; + if (fe->frontend.i2c->adapter == adapter && + fe->frontend.notifier_callback == callback) + { + fe->frontend.notifier_callback = NULL; - list_for_each_safe (e0, n0, &fe->notifier_callbacks) { - struct dvb_fe_notifier_callbacks *e; + } + } - e = list_entry (e0, - struct dvb_fe_notifier_callbacks, - list_head); - list_del (&e->list_head); - kfree (e); - } + list_for_each_safe (entry, n, &frontend_notifier_list) { + struct dvb_frontend_notifier_data *notifier; + + notifier = list_entry (entry, struct dvb_frontend_notifier_data, list_head); + + if (notifier->adapter == adapter && + notifier->callback == callback) + { + list_del (¬ifier->list_head); + kfree (notifier); + + break; } } @@ -835,7 +859,6 @@ dvb_register_frontend (int (*ioctl) (struct dvb_frontend *frontend, init_MUTEX (&fe->events.sem); fe->events.eventw = fe->events.eventr = 0; fe->events.overflow = 0; - INIT_LIST_HEAD (&fe->notifier_callbacks); fe->frontend.ioctl = ioctl; fe->frontend.i2c = i2c; @@ -857,6 +880,20 @@ dvb_register_frontend (int (*ioctl) (struct dvb_frontend *frontend, } } + list_for_each (entry, &frontend_notifier_list) { + struct dvb_frontend_notifier_data *notifier; + + notifier = list_entry (entry, + struct dvb_frontend_notifier_data, + list_head); + + if (notifier->adapter == i2c->adapter) { + fe->frontend.notifier_callback = notifier->callback; + fe->frontend.notifier_data = notifier->data; + break; + } + } + list_add_tail (&fe->list_head, &frontend_list); printk ("DVB: registering frontend %i:%i (%s)...\n", diff --git a/linux/drivers/media/dvb/dvb-core/dvb_frontend.h b/linux/drivers/media/dvb/dvb-core/dvb_frontend.h index 5c1950022..03a37b946 100644 --- a/linux/drivers/media/dvb/dvb-core/dvb_frontend.h +++ b/linux/drivers/media/dvb/dvb-core/dvb_frontend.h @@ -52,8 +52,10 @@ struct dvb_frontend { int (*before_ioctl) (struct dvb_frontend *frontend, unsigned int cmd, void *arg); int (*ioctl) (struct dvb_frontend *frontend, unsigned int cmd, void *arg); int (*after_ioctl) (struct dvb_frontend *frontend, unsigned int cmd, void *arg); + void (*notifier_callback) (fe_status_t s, void *data); struct dvb_i2c_bus *i2c; void *before_after_data; /* can be used by hardware module... */ + void *notifier_data; /* can be used by hardware module... */ void *data; /* can be used by hardware module... */ }; |