Comment 60 for bug 1313904

Revision history for this message
Ugnius (rykien) wrote :

Also having the issue on a fresh 16.04.1. init-headphone 0.11 gets EBUSY on the first write to SMBus (modified to print out errno, diff below). Used to work on 15.04-15.10 on the same laptop.

$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 16.04.1 LTS
Release: 16.04
Codename: xenial

$ sudo init-headphone-errno
INFO:root:Version: 0.11
INFO:root:Trying to add module to the kernel: i2c_dev
INFO:root:Trying to add module to the kernel: i2c_i801
DEBUG:root:Available i2c busses: ['i915 gmbus ssc', 'i915 gmbus vga', 'i915 gmbus panel', 'i915 gmbus dpc', 'i915 gmbus dpb', 'i915 gmbus dpd', 'DPDDC-A', 'SMBus I801 adapter at f040']
DEBUG:root:Supported i2c bus names: ['SMBus I801 adapter']
DEBUG:root:Selected i2c bus: SMBus I801 adapter at f040
INFO:SMBus:Opening I2C bus: /dev/i2c-7
INFO:SMBus:Setting I2C slave address: 115
INFO:SMBus:Writing byte data on I2C bus: (device_cmd: 0xa, value: 0x41)
ERROR:SMBus:Can't transfer data on I2C bus [EBUSY]
INFO:SMBus:Closing I2C bus
ERROR:root:Operation failed
DEBUG:root:Exception occurred:
Traceback (most recent call last):
  File "/usr/sbin/init-headphone-errno", line 329, in <module>
    main()
  File "/usr/sbin/init-headphone-errno", line 315, in main
    init()
  File "/usr/sbin/init-headphone-errno", line 247, in init
    set_effect(DEFAULT_EFFECT)
  File "/usr/sbin/init-headphone-errno", line 263, in set_effect
    DATA_ENABLE_OUTPUT)
  File "/usr/sbin/init-headphone-errno", line 241, in write_data_to_device
    write_prolog(i2c_bus)
  File "/usr/sbin/init-headphone-errno", line 232, in write_prolog
    i2c_bus.write_byte_data(0x0a, 0x41)
  File "/usr/sbin/init-headphone-errno", line 149, in write_byte_data
    self.__access(I2C_SMBUS_WRITE, device_cmd, I2C_SMBUS_BYTE_DATA, data)
  File "/usr/sbin/init-headphone-errno", line 141, in __access
    raise RuntimeError("Can't transfer data on I2C bus [{}]".format(e))
RuntimeError: Can't transfer data on I2C bus [EBUSY]

$ sudo i2cdetect 7
WARNING! This program can confuse your I2C bus, cause data loss and worse!
I will probe file /dev/i2c-7.
I will probe address range 0x03-0x77.
Continue? [Y/n]
     0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --

$ diff -u /usr/sbin/init-headphone /usr/sbin/init-headphone-errno
--- /usr/sbin/init-headphone 2016-05-08 10:27:04.000000000 +0300
+++ /usr/sbin/init-headphone-errno 2016-10-21 16:58:45.292881695 +0300
@@ -82,6 +82,12 @@
                 ("size", ctypes.c_uint),
                 ("data", ctypes.POINTER(i2c_smbus_data))]

+_errno = ctypes.cdll.LoadLibrary("libc.so.6").__errno_location
+_errno.restype = ctypes.POINTER(ctypes.c_int)
+
+def get_errno():
+ import errno
+ return errno.errorcode[_errno()[0]]

 class SMBus(object):
     def __init__(self, path):
@@ -129,9 +135,10 @@
         args.size = size
         args.data = ctypes.pointer(data)
         err = self.__libc.ioctl(self.__fd, I2C_SMBUS, ctypes.byref(args))
+ e = get_errno()
         if err != 0:
- self.__logger.error("Can't transfer data on I2C bus")
- raise RuntimeError("Can't transfer data on I2C bus")
+ self.__logger.error("Can't transfer data on I2C bus [{}]".format(e))
+ raise RuntimeError("Can't transfer data on I2C bus [{}]".format(e))

     def write_byte_data(self, device_cmd, value):
         self.__logger.info("Writing byte data on I2C bus: "