Hi Andreas, On Saturday 17 July 2004 07:43, Andreas Witte wrote: > Tried the latest cvs-grab and want to give you feedback for your work. > It seems something is damaged with the mt352 frontend. > > Im also using the latest video4linux driver. I hope that the error isnt > rooted here. With a cvs-grab 2 days ago the mt352 was working perfect. > > Below the feedback i got from dmesg while loading the mt352: > > *** > Jul 17 07:37:59 GentooLinux dvbfe_mt352: Trying to attach to adapter > 0x10005:bt878 #0 [hw]. > Jul 17 07:37:59 GentooLinux dvbfe_mt352: Setup for Avermedia 771. > Jul 17 07:37:59 GentooLinux ------------[ cut here ]------------ > Jul 17 07:37:59 GentooLinux kernel BUG at > drivers/media/dvb/frontends/mt352.c:823! [snip] > Is that any help for you?
It was expected, as the bt878 driver has not been updated yet. Anyways, I have had a look at the bttv driver and there's really no clean way of using the FE_REGISTER/FE_UNREGISTER i2c client commands. As I see it, ideally the frontends should not have to know about a dvb_adapter at all. I've attached a couple of patches for dvb-core, av7110 and stv0299 that implement this change. Is this an ok method of solving this problem? Kenneth
Index: ttpci/av7110.c =================================================================== RCS file: /cvs/linuxtv/dvb-kernel/linux/drivers/media/dvb/ttpci/av7110.c,v retrieving revision 1.132 diff -u -r1.132 av7110.c --- ttpci/av7110.c 12 Jul 2004 18:15:36 -0000 1.132 +++ ttpci/av7110.c 17 Jul 2004 17:53:20 -0000 @@ -1450,8 +1450,6 @@ return ret; } - dvb_register_adapter(&av7110->dvb_adapter, av7110->card_name, THIS_MODULE); - /* the Siemens DVB needs this if you want to have the i2c chips get recognized before the main driver is fully loaded */ saa7146_write(dev, GPIO_CTRL, 0x500000); @@ -1465,6 +1463,10 @@ .class = I2C_CLASS_TV_DIGITAL, #endif }; + + dvb_register_adapter(&av7110->dvb_adapter, av7110->card_name, + &av7110->i2c_adap, THIS_MODULE); + strlcpy(av7110->i2c_adap.name, pci_ext->ext_priv, sizeof(av7110->i2c_adap.name)); saa7146_i2c_adapter_prepare(dev, &av7110->i2c_adap, SAA7146_I2C_BUS_BIT_RATE_120); /* 275 kHz */
Index: dvb-core/dvb_frontend.c =================================================================== RCS file: /cvs/linuxtv/dvb-kernel/linux/drivers/media/dvb/dvb-core/dvb_frontend.c,v retrieving revision 1.83 diff -u -r1.83 dvb_frontend.c --- dvb-core/dvb_frontend.c 16 Jul 2004 19:24:59 -0000 1.83 +++ dvb-core/dvb_frontend.c 17 Jul 2004 17:50:23 -0000 @@ -1064,12 +1064,11 @@ .release = dvb_frontend_release }; -int -dvb_register_frontend (int (*ioctl) (struct dvb_frontend *frontend, - unsigned int cmd, void *arg), - struct dvb_i2c_bus *i2c, - void *data, - struct dvb_frontend_info *info) +int dvb_register_frontend(int (*ioctl) (struct dvb_frontend *frontend, + unsigned int cmd, void *arg), + struct dvb_i2c_bus *i2c, + void *data, + struct dvb_frontend_info *info) { struct list_head *entry; struct dvb_frontend_data *fe; @@ -1183,16 +1182,16 @@ return -EINVAL; } -int -dvb_register_frontend_new (int (*ioctl) (struct dvb_frontend *frontend, - unsigned int cmd, void *arg), - struct dvb_adapter *dvb_adapter, - void *data, - struct dvb_frontend_info *info, - struct module *module) +int dvb_register_frontend_new (int (*ioctl) (struct dvb_frontend *frontend, + unsigned int cmd, void *arg), + struct i2c_adapter *i2c_adapter, + void *data, + struct dvb_frontend_info *info, + struct module *module) { struct list_head *entry; struct dvb_frontend_data *fe; + struct dvb_adapter *dvb_adapter; static const struct dvb_device dvbdev_template = { .users = ~0, .writers = 1, @@ -1206,6 +1205,11 @@ if (down_interruptible (&frontend_mutex)) return -ERESTARTSYS; + if (!(dvb_adapter = find_dvb_adapter(i2c_adapter))) { + up (&frontend_mutex); + return -EFAULT; + } + if (!(fe = kmalloc (sizeof (struct dvb_frontend_data), GFP_KERNEL))) { up (&frontend_mutex); return -ENOMEM; @@ -1275,12 +1279,17 @@ int dvb_unregister_frontend_new (int (*ioctl) (struct dvb_frontend *frontend, unsigned int cmd, void *arg), - struct dvb_adapter *dvb_adapter) + struct i2c_adapter *i2c_adapter) { + struct dvb_adapter *dvb_adapter; struct list_head *entry, *n; dprintk ("%s\n", __FUNCTION__); + if (!(dvb_adapter = find_dvb_adapter(i2c_adapter))) { + return -EFAULT; + } + down (&frontend_mutex); list_for_each_safe (entry, n, &frontend_list) { Index: dvb-core/dvb_frontend.h =================================================================== RCS file: /cvs/linuxtv/dvb-kernel/linux/drivers/media/dvb/dvb-core/dvb_frontend.h,v retrieving revision 1.12 diff -u -r1.12 dvb_frontend.h --- dvb-core/dvb_frontend.h 12 Jul 2004 18:19:36 -0000 1.12 +++ dvb-core/dvb_frontend.h 17 Jul 2004 17:50:26 -0000 @@ -94,16 +94,16 @@ extern int dvb_register_frontend_new (int (*ioctl) (struct dvb_frontend *frontend, - unsigned int cmd, void *arg), - struct dvb_adapter *dvb_adapter, - void *data, - struct dvb_frontend_info *info, - struct module *module); + unsigned int cmd, void *arg), + struct i2c_adapter *i2c_adapter, + void *data, + struct dvb_frontend_info *info, + struct module *module); extern int dvb_unregister_frontend_new (int (*ioctl) (struct dvb_frontend *frontend, - unsigned int cmd, void *arg), - struct dvb_adapter *dvb_adapter); + unsigned int cmd, void *arg), + struct i2c_adapter *i2c_adapter); /** Index: dvb-core/dvbdev.c =================================================================== RCS file: /cvs/linuxtv/dvb-kernel/linux/drivers/media/dvb/dvb-core/dvbdev.c,v retrieving revision 1.28 diff -u -r1.28 dvbdev.c --- dvb-core/dvbdev.c 3 May 2004 16:29:27 -0000 1.28 +++ dvb-core/dvbdev.c 17 Jul 2004 17:50:30 -0000 @@ -68,6 +68,19 @@ return NULL; } +struct dvb_adapter* find_dvb_adapter(struct i2c_adapter *i2c_adapter) +{ + struct list_head *entry; + + list_for_each (entry, &dvb_adapter_list) { + struct dvb_adapter *adap; + adap = list_entry (entry, struct dvb_adapter, list_head); + if (adap->i2c_adapter == i2c_adapter) + return adap; + } + + return NULL; +} static int dvb_device_open(struct inode *inode, struct file *file) { @@ -260,7 +273,10 @@ } -int dvb_register_adapter(struct dvb_adapter **padap, const char *name, struct module *module) +int dvb_register_adapter(struct dvb_adapter **padap, + const char *name, + struct i2c_adapter *i2c_adapter, + struct module *module) { struct dvb_adapter *adap; int num; @@ -287,6 +303,7 @@ adap->num = num; adap->name = name; adap->module = module; + adap->i2c_adapter = i2c_adapter; list_add_tail (&adap->list_head, &dvb_adapter_list); Index: dvb-core/dvbdev.h =================================================================== RCS file: /cvs/linuxtv/dvb-kernel/linux/drivers/media/dvb/dvb-core/dvbdev.h,v retrieving revision 1.20 diff -u -r1.20 dvbdev.h --- dvb-core/dvbdev.h 3 May 2004 16:29:27 -0000 1.20 +++ dvb-core/dvbdev.h 17 Jul 2004 17:50:31 -0000 @@ -47,6 +47,7 @@ struct list_head list_head; struct list_head device_list; const char *name; + struct i2c_adapter *i2c_adapter; u8 proposed_mac [6]; struct module *module; @@ -74,7 +75,12 @@ }; -extern int dvb_register_adapter (struct dvb_adapter **padap, const char *name, struct module *module); +extern struct dvb_adapter* find_dvb_adapter(struct i2c_adapter *i2c_adapter); +extern int dvb_register_adapter (struct dvb_adapter **padap, + const char *name, + struct i2c_adapter *adapter, + struct module *module); + extern int dvb_unregister_adapter (struct dvb_adapter *adap); extern int dvb_register_device (struct dvb_adapter *adap,
Index: frontends/stv0299.c =================================================================== RCS file: /cvs/linuxtv/dvb-kernel/linux/drivers/media/dvb/frontends/stv0299.c,v retrieving revision 1.53 diff -u -r1.53 stv0299.c --- frontends/stv0299.c 17 Jul 2004 14:51:41 -0000 1.53 +++ frontends/stv0299.c 17 Jul 2004 17:52:57 -0000 @@ -118,7 +118,6 @@ u32 symbol_rate; fe_code_rate_t fec_inner; struct i2c_adapter *i2c; - struct dvb_adapter *dvb; }; @@ -1398,10 +1397,8 @@ kfree(state); return -EFAULT; } - - BUG_ON(!state->dvb); - ret = dvb_register_frontend_new(uni0299_ioctl, state->dvb, state, + ret = dvb_register_frontend_new(uni0299_ioctl, adapter, state, &uni0299_info, THIS_MODULE); if (ret) { i2c_detach_client(client); @@ -1417,33 +1414,13 @@ { struct stv0299_state *state = (struct stv0299_state*)i2c_get_clientdata(client); - dvb_unregister_frontend_new (uni0299_ioctl, state->dvb); + dvb_unregister_frontend_new (uni0299_ioctl, client->adapter); i2c_detach_client(client); kfree(client); kfree(state); return 0; } -static int command (struct i2c_client *client, unsigned int cmd, void *arg) -{ - struct stv0299_state *data = (struct stv0299_state*)i2c_get_clientdata(client); - dprintk ("%s\n", __FUNCTION__); - - switch (cmd) { - case FE_REGISTER: { - data->dvb = (struct dvb_adapter*)arg; - break; - } - case FE_UNREGISTER: { - data->dvb = NULL; - break; - } - default: - return -EOPNOTSUPP; - } - return 0; -} - static struct i2c_driver driver = { .owner = THIS_MODULE, .name = FRONTEND_NAME, @@ -1451,7 +1428,6 @@ .flags = I2C_DF_NOTIFY, .attach_adapter = attach_adapter, .detach_client = detach_client, - .command = command, }; static struct i2c_client client_template = {