← Back to team overview

kernel-packages team mailing list archive

[Bug 1291459] Re: ioctl FE_GET_INFO hangs with DViCO FusionHDTV DVB-T Dual Digital 4 card

 

I have poked around in the source code and found some inconsistencies.

=====================================
Summary:
There are multiple definitions of MAX_XFER_SIZE in the drivers/media sub-directory, containing values such as 64, 80, 128, 256.
The definition that appears to matter is in 
drivers/media/usb/dvb-usb/cxusb.c
#define MAX_XFER_SIZE  64
It seems that passing a larger msg.len to cxusb_i2c_xfer causes the errors noted in this report.
The buffer size is declared separately in various places, having many different sizes. It seems that there are many ways that this error could be caused.

I have changed MAX_XFER_SIZE in tuner-xc2028.c from 80 to 64. With this
change, the kernel logs no longer contain an error when the firmare is
loaded. Indeed, the firmware appears to load successfully.

However, I have not yet been able to test whether a DVB signal can be
received and decoded.

These tests were performed after upgrading to trusty 14.04, using kernel 3.13.0-24-generic.
=====================================

Notes

Initial testing performed using 3.14.0-031400rc6-generic on Ubuntu 14.04 (same kernel as used previously, but the rest of the OS was upgraded).
Apr 29 14:56:17 mythtv kernel: [ 2385.788462] cxusb: No IR receiver detected on this device.
Apr 29 14:56:17 mythtv kernel: [ 2385.788472] usb 3-2: DVB: registering adapter 2 frontend 0 (Zarlink ZL10353 DVB-T)...
Apr 29 14:56:17 mythtv kernel: [ 2385.788565] xc2028 11-0061: creating new instance
Apr 29 14:56:17 mythtv kernel: [ 2385.788568] xc2028 11-0061: type set to XCeive xc2028/xc3028 tuner
Apr 29 14:56:17 mythtv kernel: [ 2385.790357] xc2028 11-0061: Loading 80 firmware images from xc3028-v27.fw, type: xc2028 firmware, ver 2.7
Apr 29 14:56:17 mythtv kernel: [ 2385.790714] dvb-usb: DViCO FusionHDTV DVB-T Dual Digital 4 successfully initialized and connected.
Apr 29 14:56:17 mythtv kernel: [ 2385.790760] usbcore: registered new interface driver dvb_usb_cxusb

Apr 29 14:58:32 mythtv kernel: [ 2520.932221] xc2028 10-0061: Loading firmware for type=BASE F8MHZ (3), id 0000000000000000.
Apr 29 14:58:32 mythtv kernel: [ 2520.944221] cxusb: i2c wr: len=64 is too big!
Apr 29 14:58:32 mythtv kernel: [ 2520.944221] 
Apr 29 14:58:32 mythtv kernel: [ 2520.944226] xc2028 10-0061: i2c output error: rc = -95 (should be 64)
Apr 29 14:58:32 mythtv kernel: [ 2520.944228] xc2028 10-0061: -95 returned from send
Apr 29 14:58:32 mythtv kernel: [ 2520.944231] xc2028 10-0061: Error -22 while loading base firmware
<repeats 8 times>

I have located the origin of each of these messages:

Apr 29 14:58:32 mythtv kernel: [ 2520.932221] xc2028 10-0061: Loading firmware for type=BASE F8MHZ (3), id 0000000000000000.
drivers/media/tuners/tuner-xc2028.c
static int load_firmware(struct dvb_frontend *fe, unsigned int type,
			 v4l2_std_id *id)

	tuner_info("Loading firmware for type=");
	dump_firm_type(priv->firm[pos].type);
	printk("(%x), id %016llx.\n", priv->firm[pos].type,
	       (unsigned long long)*id);

further down

		/* Sends message chunks */
		while (size > 0) {
			int len = (size < priv->ctrl.max_len - 1) ?
				   size : priv->ctrl.max_len - 1;

                        memcpy(buf + 1, p, len);

			rc = i2c_send(priv, buf, len + 1);
			if (rc < 0) {
				tuner_err("%d returned from send\n", rc);
				return -EINVAL;
			}

			p += len;
			size -= len;
		}

i2c_send is a macro, defined near the top of tuner-xc2028.c

#define i2c_send(priv, buf, size) ({					\
	int _rc;							\
	_rc = tuner_i2c_xfer_send(&priv->i2c_props, buf, size);		\
	if (size != _rc)						\
		tuner_info("i2c output error: rc = %d (should be %d)\n",\
			   _rc, (int)size);				\
	if (priv->ctrl.msleep)						\
		msleep(priv->ctrl.msleep);				\
	_rc;								\
})

tuner_i2c_xfer_send
drivers/media/tuners/tuner-i2c.h

static inline int tuner_i2c_xfer_send(struct tuner_i2c_props *props, char *buf, int len)
{
	struct i2c_msg msg = { .addr = props->addr, .flags = 0,
			       .buf = buf, .len = len };
	int ret = i2c_transfer(props->adap, &msg, 1);

	return (ret == 1) ? len : ret;
}

FIXME I don't understand how it gets from there to what comes next.
These messages must be produced by i2c_transfer!

Apr 29 14:58:32 mythtv kernel: [ 2520.944221] cxusb: i2c wr: len=64 is
too big!

drivers/media/usb/dvb-usb/cxusb.c
static int cxusb_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
			  int num)
			  
			/* write only */
			u8 obuf[MAX_XFER_SIZE], ibuf;

			if (2 + msg[i].len > sizeof(obuf)) {
				warn("i2c wr: len=%d is too big!\n",
				     msg[i].len);
				ret = -EOPNOTSUPP;
				goto unlock;
			}

			
Apr 29 14:58:32 mythtv kernel: [ 2520.944221] 

FIXME I don't understand where this line comes from.

Apr 29 14:58:32 mythtv kernel: [ 2520.944226] xc2028 10-0061: i2c output
error: rc = -95 (should be 64)

This message comes from tuner-xc2028.c
i2c_send macro
-95 is the return code of tuner_i2c_xfer_send, which in turn is the return code of i2c_transfer.
include/uapi/asm-generic/errno.h
#define	EOPNOTSUPP	95	/* Operation not supported on transport endpoint */

Apr 29 14:58:32 mythtv kernel: [ 2520.944228] xc2028 10-0061: -95 returned from send
drivers/media/tuners/tuner-xc2028.c load_firmware
		/* Sends message chunks */
		while (size > 0) {
			int len = (size < priv->ctrl.max_len - 1) ?
				   size : priv->ctrl.max_len - 1;

                        memcpy(buf + 1, p, len);

			rc = i2c_send(priv, buf, len + 1);
			if (rc < 0) {
				tuner_err("%d returned from send\n", rc);
				return -EINVAL;
			}

			p += len;
			size -= len;
		}


Apr 29 14:58:32 mythtv kernel: [ 2520.944231] xc2028 10-0061: Error -22 while loading base firmware
include/uapi/asm-generic/errno-base.h
#define	EINVAL		22	/* Invalid argument */


It seems that the MAX_XFER_SIZE is inconsistent between several places:

drivers/media/tuners/tuner-xc2028.c
/* Max transfer size done by I2C transfer functions */
#define MAX_XFER_SIZE  80

drivers/media/usb/dvb-usb/cxusb.c
/* Max transfer size done by I2C transfer functions */
#define MAX_XFER_SIZE  64

In fact, it would seem that tuner-xc2028.c should have 
/* Max transfer size done by I2C transfer functions */
#define MAX_XFER_SIZE  62
because cxusb_i2c_xfer requires 2 extra bytes for its own purposes.

There are a great many definitions of MAX_XFER_SIZE under drivers/media .
Many are 64, some are 128, some are 256! There needs to be consistency!!!
It seems that the macro should be defined in ONE place instead of
separately in every .c file!


After making this change, the system logs appear as follows:
=============================================================
Apr 29 21:06:35 mythtv kernel: [  155.767660] dvb-usb: found a 'DViCO FusionHDTV DVB-T Dual Digital 4' in warm state.
Apr 29 21:06:35 mythtv kernel: [  155.767793] dvb-usb: will pass the complete MPEG2 transport stream to the software demuxer.
Apr 29 21:06:35 mythtv kernel: [  155.798893] DVB: registering new adapter (DViCO FusionHDTV DVB-T Dual Digital 4)
Apr 29 21:06:35 mythtv kernel: [  155.949154] usb 3-1: DVB: registering adapter 1 frontend 0 (Zarlink ZL10353 DVB-T)...
Apr 29 21:06:35 mythtv kernel: [  155.964139] xc2028 10-0061: creating new instance
Apr 29 21:06:35 mythtv kernel: [  155.964143] xc2028 10-0061: type set to XCeive xc2028/xc3028 tuner
Apr 29 21:06:35 mythtv kernel: [  155.964714] input: IR-receiver inside an USB DVB receiver as /devices/pci0000:00/0000:00:1e.0/0000:05:01.2/usb3/3-1/input/input16
Apr 29 21:06:35 mythtv kernel: [  155.964838] dvb-usb: schedule remote query interval to 100 msecs.
Apr 29 21:06:35 mythtv kernel: [  155.964901] dvb-usb: DViCO FusionHDTV DVB-T Dual Digital 4 successfully initialized and connected.
Apr 29 21:06:35 mythtv kernel: [  155.964923] dvb-usb: found a 'DViCO FusionHDTV DVB-T Dual Digital 4' in warm state.
Apr 29 21:06:35 mythtv kernel: [  155.965068] dvb-usb: will pass the complete MPEG2 transport stream to the software demuxer.
Apr 29 21:06:35 mythtv kernel: [  155.973845] xc2028 10-0061: Loading 80 firmware images from xc3028-v27.fw, type: xc2028 firmware, ver 2.7
Apr 29 21:06:35 mythtv kernel: [  155.996183] DVB: registering new adapter (DViCO FusionHDTV DVB-T Dual Digital 4)
Apr 29 21:06:35 mythtv kernel: [  156.044540] cxusb: No IR receiver detected on this device.
Apr 29 21:06:35 mythtv kernel: [  156.044549] usb 3-2: DVB: registering adapter 2 frontend 0 (Zarlink ZL10353 DVB-T)...
Apr 29 21:06:35 mythtv kernel: [  156.044633] xc2028 11-0061: creating new instance
Apr 29 21:06:35 mythtv kernel: [  156.044636] xc2028 11-0061: type set to XCeive xc2028/xc3028 tuner
Apr 29 21:06:35 mythtv kernel: [  156.045705] xc2028 11-0061: Loading 80 firmware images from xc3028-v27.fw, type: xc2028 firmware, ver 2.7
Apr 29 21:06:35 mythtv kernel: [  156.046917] dvb-usb: DViCO FusionHDTV DVB-T Dual Digital 4 successfully initialized and connected.
Apr 29 21:06:35 mythtv kernel: [  156.046957] usbcore: registered new interface driver dvb_usb_cxusb
=============================================================

It appears that the firmware has been loaded successfully.

-- 
You received this bug notification because you are a member of Kernel
Packages, which is subscribed to linux in Ubuntu.
https://bugs.launchpad.net/bugs/1291459

Title:
  ioctl FE_GET_INFO hangs with DViCO FusionHDTV DVB-T Dual Digital 4
  card

Status in “linux” package in Ubuntu:
  Confirmed
Status in “linux-firmware” package in Ubuntu:
  Confirmed

Bug description:
  Top level symptom:
  mythtv-backend fails to listen for client connections.
  It stops at: (strace mythbackend)
  open("/dev/dvb/adapter1/frontend0", O_RDWR|O_NONBLOCK) = 16
  ioctl(16, FE_GET_INFO

  me-tv also hangs in a similar manner.

  I expected the ioctl call to succeed, and for the top level
  applications to function properly. Instead, they hang.

  The machine has 3 dvb tuners as follows:
  **************** Adapter 0
  Mar 12 22:32:53 mythtv kernel: [   17.428195] input: Budget-CI dvb ir receiver saa7146 (0) as /devices/pci0000:00/0000:00:1e.0/0000:05
  :00.0/rc/rc0/input13
  Mar 12 22:32:53 mythtv kernel: [   17.428251] rc0: Budget-CI dvb ir receiver saa7146 (0) as /devices/pci0000:00/0000:00:1e.0/0000:05:0
  0.0/rc/rc0
  Mar 12 22:32:53 mythtv kernel: [   17.432801] budget_ci dvb 0000:05:00.0: DVB: registering adapter 0 frontend 0 (Philips TDA10045H DVB
  -T)...
  **************** Adapter 1
  Mar 12 22:32:53 mythtv kernel: [   17.646727] DVB: registering new adapter (DViCO FusionHDTV DVB-T Dual Digital 4)
  Mar 12 22:32:53 mythtv kernel: [   17.797366] usb 3-1: DVB: registering adapter 1 frontend 0 (Zarlink ZL10353 DVB-T)...
  **************** Adapter 2
  Mar 12 22:32:53 mythtv kernel: [   17.831769] DVB: registering new adapter (DViCO FusionHDTV DVB-T Dual Digital 4)
  Mar 12 22:32:53 mythtv kernel: [   17.882250] cxusb: No IR receiver detected on this device.
  Mar 12 22:32:53 mythtv kernel: [   17.882258] usb 3-2: DVB: registering adapter 2 frontend 0 (Zarlink ZL10353 DVB-T)...

  There appears to be a problem loading the firmware for the xc2028 in
  the DViCO FusionHDTV card:

  Mar 13 02:07:59 mythtv kernel: [   37.348226] xc2028 10-0061: Loading firmware for type=BASE F8MHZ (3), id 0000000000000000.
  Mar 13 02:07:59 mythtv kernel: [   37.360226] cxusb: i2c wr: len=64 is too big!
  Mar 13 02:07:59 mythtv kernel: [   37.360226] 
  Mar 13 02:07:59 mythtv kernel: [   37.360230] xc2028 10-0061: i2c output error: rc = -95 (should be 64)
  Mar 13 02:07:59 mythtv kernel: [   37.360231] xc2028 10-0061: -95 returned from send
  Mar 13 02:07:59 mythtv kernel: [   37.360234] xc2028 10-0061: Error -22 while loading base firmware
  Mar 13 02:07:59 mythtv kernel: [   37.412233] xc2028 11-0061: Loading firmware for type=BASE F8MHZ (3), id 0000000000000000.
  Mar 13 02:07:59 mythtv kernel: [   37.424360] cxusb: i2c wr: len=64 is too big!
  Mar 13 02:07:59 mythtv kernel: [   37.424360] 
  Mar 13 02:07:59 mythtv kernel: [   37.424364] xc2028 11-0061: i2c output error: rc = -95 (should be 64)
  Mar 13 02:07:59 mythtv kernel: [   37.424365] xc2028 11-0061: -95 returned from send
  Mar 13 02:07:59 mythtv kernel: [   37.424368] xc2028 11-0061: Error -22 while loading base firmware
  Mar 13 02:07:59 mythtv kernel: [   37.428486] xc2028 10-0061: Loading firmware for type=BASE F8MHZ (3), id 0000000000000000.
  Mar 13 02:07:59 mythtv kernel: [   37.492247] xc2028 11-0061: Loading firmware for type=BASE F8MHZ (3), id 0000000000000000.

  The firmware is loaded from the file xc3028-v27.fw:
  Mar 13 02:07:42 mythtv kernel: [   18.108746] xc2028 11-0061: creating new instance
  Mar 13 02:07:42 mythtv kernel: [   18.108748] xc2028 11-0061: type set to XCeive xc2028/xc3028 tuner
  Mar 13 02:07:42 mythtv kernel: [   18.108801] xc2028 11-0061: Loading 80 firmware images from xc3028-v27.fw, type: xc2028 firmware, ver 2.7
  Mar 13 02:07:42 mythtv kernel: [   18.109670] dvb-usb: DViCO FusionHDTV DVB-T Dual Digital 4 successfully initialized and connected.

  The firmware file /lib/firmware/xc3028-v27.fw belongs to the linux-firmware-nonfree 1.14.ubuntu1 package. I have located instructions on the origin of this file (http://www.linuxtv.org/wiki/index.php/Xceive_XC3028/XC2028#How_to_Obtain_the_Firmware)
  and I have verified that the firmware file is identical to the one obtained by that method.

  The DViCO FusionHDTV card has been used for several years in this
  machine. This problem only occurred after upgrading to saucy
  salamander.

  ProblemType: Bug
  DistroRelease: Ubuntu 13.10
  Package: linux-image-3.11.0-18-generic 3.11.0-18.32
  ProcVersionSignature: Ubuntu 3.11.0-18.32-generic 3.11.10.4
  Uname: Linux 3.11.0-18-generic x86_64
  ApportVersion: 2.12.5-0ubuntu2.2
  Architecture: amd64
  AudioDevicesInUse:
   USER        PID ACCESS COMMAND
   /dev/snd/controlC1:  loungeroom   2246 F.... pulseaudio
   /dev/snd/controlC0:  loungeroom   2246 F.... pulseaudio
  Date: Thu Mar 13 02:28:43 2014
  HibernationDevice: RESUME=UUID=335a7d97-3ccb-47e1-a25a-78717e9f04a7
  IwConfig:
   eth1      no wireless extensions.
   
   lo        no wireless extensions.
  MachineType: Gigabyte Technology Co., Ltd. EP43-DS3L
  MarkForUpload: True
  ProcEnviron:
   TERM=xterm
   PATH=(custom, no user)
   LANG=en_AU.UTF-8
   SHELL=/bin/bash
  ProcFB: 0 radeondrmfb
  ProcKernelCmdLine: BOOT_IMAGE=/vmlinuz-3.11.0-18-generic root=/dev/mapper/Ubuntu-precise_root ro radeon.audio=1 crashkernel=384M-2G:64M,2G-:128M quiet splash vt.handoff=7
  PulseList:
   Error: command ['pacmd', 'list'] failed with exit code 1: Home directory not accessible: Permission denied
   No PulseAudio daemon running, or not running as session daemon.
  RelatedPackageVersions:
   linux-restricted-modules-3.11.0-18-generic N/A
   linux-backports-modules-3.11.0-18-generic  N/A
   linux-firmware                             1.116.2
  RfKill: Error: [Errno 2] No such file or directory: 'rfkill'
  SourcePackage: linux
  UpgradeStatus: Upgraded to saucy on 2014-02-20 (20 days ago)
  WifiSyslog:
   
  dmi.bios.date: 09/22/2008
  dmi.bios.vendor: Award Software International, Inc.
  dmi.bios.version: F8
  dmi.board.name: EP43-DS3L
  dmi.board.vendor: Gigabyte Technology Co., Ltd.
  dmi.chassis.type: 3
  dmi.chassis.vendor: Gigabyte Technology Co., Ltd.
  dmi.modalias: dmi:bvnAwardSoftwareInternational,Inc.:bvrF8:bd09/22/2008:svnGigabyteTechnologyCo.,Ltd.:pnEP43-DS3L:pvr:rvnGigabyteTechnologyCo.,Ltd.:rnEP43-DS3L:rvr:cvnGigabyteTechnologyCo.,Ltd.:ct3:cvr:
  dmi.product.name: EP43-DS3L
  dmi.sys.vendor: Gigabyte Technology Co., Ltd.

To manage notifications about this bug go to:
https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1291459/+subscriptions


References