Package: linux-2.6 Version: 2.6.18.dfsg.1-10 The standard kernel 2.6.18 (and also its debianized version) has a bug regarding the driver:
drivers/media/dvb/dvb-usb/dibusb-mb.c and drivers/media/dvb/dvb-usb/dibusb-common.c It results in using devices like the DVB-T TwinHan Magic box unusable since it does not tune anymore. The driover does not complain in any way while loading. It just does not work anymore. It worked in the kernels 2.6.17 and lower and is reported to work aganin in 2.6.19. The problem is in the first function of drivers/media/dvb/dvb-usb/dibusb-mb.c: stock 2.6.17 (also Debian) static int dibusb_dib3000mb_frontend_attach(struct dvb_usb_device *d) { struct dib3000_config demod_cfg; struct dibusb_state *st = d->priv; demod_cfg.demod_address = 0x8; demod_cfg.pll_set = dvb_usb_pll_set_i2c; demod_cfg.pll_init = dvb_usb_pll_init_i2c; if ((d->fe = dib3000mb_attach(&demod_cfg,&d->i2c_adap,&st->ops)) == NULL) return -ENODEV; d->tuner_pass_ctrl = st->ops.tuner_pass_ctrl; return 0; } stock 2.6.18 (as Debian, does NOT tune) static int dibusb_dib3000mb_frontend_attach(struct dvb_usb_device *d) { struct dib3000_config demod_cfg; struct dibusb_state *st = d->priv; demod_cfg.demod_address = 0x8; if ((d->fe = dib3000mb_attach(&demod_cfg,&d->i2c_adap,&st->ops)) == NULL) { d->fe->ops.tuner_ops.init = dvb_usb_tuner_init_i2c; d->fe->ops.tuner_ops.set_params = dvb_usb_tuner_set_params_i2c; return -ENODEV; } d->tuner_pass_ctrl = st->ops.tuner_pass_ctrl; return 0; } stock 2.6.19 (here the error was recognized and the tuner commands were moved outside the if-clause) static int dibusb_dib3000mb_frontend_attach(struct dvb_usb_adapter *adap) { struct dib3000_config demod_cfg; struct dibusb_state *st = adap->priv; demod_cfg.demod_address = 0x8; if ((adap->fe = dib3000mb_attach(&demod_cfg,&adap->dev->i2c_adap,&st->ops)) == NULL) return -ENODEV; adap->fe->ops.tuner_ops.init = dvb_usb_tuner_init_i2c; adap->fe->ops.tuner_ops.set_params = dvb_usb_tuner_set_params_i2c; adap->tuner_pass_ctrl = st->ops.tuner_pass_ctrl; return 0; } corrected version for 2.6.18: static int dibusb_dib3000mb_frontend_attach(struct dvb_usb_device *d) { struct dib3000_config demod_cfg; struct dibusb_state *st = d->priv; demod_cfg.demod_address = 0x8; if ((d->fe = dib3000mb_attach(&demod_cfg,&d->i2c_adap,&st->ops)) == NULL) return -ENODEV; d->fe->ops.tuner_ops.init = dvb_usb_tuner_init_i2c; d->fe->ops.tuner_ops.set_params = dvb_usb_tuner_set_params_i2c; d->tuner_pass_ctrl = st->ops.tuner_pass_ctrl; return 0; } In addition two lines in dibusb-common.c must be removed in the function dibusb_dib3000mc_frontend_attach. These are also new from 2.6.17 to .18 In 2.6.19 this function is completely changed. I have also a dib3000mc device (AverTV DVB-T USB2.0 A800) which still works fine after these changes. kernel 2.6.17: int dibusb_dib3000mc_frontend_attach(struct dvb_usb_device *d) { struct dib3000_config demod_cfg; struct dibusb_state *st = d->priv; demod_cfg.pll_set = dvb_usb_pll_set_i2c; demod_cfg.pll_init = dvb_usb_pll_init_i2c; for (demod_cfg.demod_address = 0x8; demod_cfg.demod_address < 0xd; demod_cfg.demod_address++) if ((d->fe = dib3000mc_attach(&demod_cfg,&d->i2c_adap,&st->ops)) != NULL) { d->tuner_pass_ctrl = st->ops.tuner_pass_ctrl; return 0; } return -ENODEV; } kernel 2.6.18 (also Debian) int dibusb_dib3000mc_frontend_attach(struct dvb_usb_device *d) { struct dib3000_config demod_cfg; struct dibusb_state *st = d->priv; for (demod_cfg.demod_address = 0x8; demod_cfg.demod_address < 0xd; demod_cfg.demod_address++) if ((d->fe = dib3000mc_attach(&demod_cfg,&d->i2c_adap,&st->ops)) != NULL) { d->fe->ops.tuner_ops.init = dvb_usb_tuner_init_i2c; d->fe->ops.tuner_ops.set_params = dvb_usb_tuner_set_params_i2c; d->tuner_pass_ctrl = st->ops.tuner_pass_ctrl; return 0; } return -ENODEV; } correct version for 2.6.18: int dibusb_dib3000mc_frontend_attach(struct dvb_usb_device *d) { struct dib3000_config demod_cfg; struct dibusb_state *st = d->priv; for (demod_cfg.demod_address = 0x8; demod_cfg.demod_address < 0xd; demod_cfg.demod_address++) if ((d->fe = dib3000mc_attach(&demod_cfg,&d->i2c_adap,&st->ops)) != NULL) { d->tuner_pass_ctrl = st->ops.tuner_pass_ctrl; return 0; } return -ENODEV; } I have attached a diff for the debian-kernel 2.6.18 If you have questions pleas do not hesitate to mail me: hwahl (at) hwahl (dot) de -- Hartmut Wahl <hwahl (at) hwahl (dot) de> www: http://www.hwahl.de PGP: http://www.hwahl.de/HartmutWahl.asc
diff -rc linux-source-2.6.18.org/drivers/media/dvb/dvb-usb/dibusb-common.c linux-source-2.6.18/drivers/media/dvb/dvb-usb/dibusb-common.c *** linux-source-2.6.18.org/drivers/media/dvb/dvb-usb/dibusb-common.c 2007-02-28 22:22:06.000000000 +0100 --- linux-source-2.6.18/drivers/media/dvb/dvb-usb/dibusb-common.c 2007-02-27 20:00:28.000000000 +0100 *************** *** 175,182 **** for (demod_cfg.demod_address = 0x8; demod_cfg.demod_address < 0xd; demod_cfg.demod_address++) if ((d->fe = dib3000mc_attach(&demod_cfg,&d->i2c_adap,&st->ops)) != NULL) { - d->fe->ops.tuner_ops.init = dvb_usb_tuner_init_i2c; - d->fe->ops.tuner_ops.set_params = dvb_usb_tuner_set_params_i2c; d->tuner_pass_ctrl = st->ops.tuner_pass_ctrl; return 0; } --- 175,180 ---- diff -rc linux-source-2.6.18.org/drivers/media/dvb/dvb-usb/dibusb-mb.c linux-source-2.6.18/drivers/media/dvb/dvb-usb/dibusb-mb.c *** linux-source-2.6.18.org/drivers/media/dvb/dvb-usb/dibusb-mb.c 2007-02-28 22:22:06.000000000 +0100 --- linux-source-2.6.18/drivers/media/dvb/dvb-usb/dibusb-mb.c 2007-02-27 19:59:05.000000000 +0100 *************** *** 21,31 **** demod_cfg.demod_address = 0x8; ! if ((d->fe = dib3000mb_attach(&demod_cfg,&d->i2c_adap,&st->ops)) == NULL) { ! d->fe->ops.tuner_ops.init = dvb_usb_tuner_init_i2c; ! d->fe->ops.tuner_ops.set_params = dvb_usb_tuner_set_params_i2c; return -ENODEV; ! } d->tuner_pass_ctrl = st->ops.tuner_pass_ctrl; --- 21,31 ---- demod_cfg.demod_address = 0x8; ! if ((d->fe = dib3000mb_attach(&demod_cfg,&d->i2c_adap,&st->ops)) == NULL) return -ENODEV; ! ! d->fe->ops.tuner_ops.init = dvb_usb_tuner_init_i2c; ! d->fe->ops.tuner_ops.set_params = dvb_usb_tuner_set_params_i2c; d->tuner_pass_ctrl = st->ops.tuner_pass_ctrl;