Skip navigation

Monthly Archives: November 2015

GDChart is a fairly old PHP extension, it’s origins are somewhere in 2003 and doesn’t seem to have been updated since 2006. The standard PECL sources won’t compile under any version of PHP greater than 5.3 due to a few changes in the Zend engine and GD dependencies. If you try, you’ll get a few error messages:
/gdchart-0.2.0/gdchart.c:195: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘gdchart_functions’
/gdchart-0.2.0/gdchart.c: In function ‘gdc_objects_new’:
/gdchart-0.2.0/gdchart.c:303: error: ‘zend_class_entry’ has no member named ‘default_properties’
/gdchart-0.2.0/gdchart.c: At top level:
/gdchart-0.2.0/gdchart.c:360: error: ‘gdchart_functions’ undeclared here (not in a function)

If you’re in a hurry or your C/C++ is a little rusty you’re in luck, this is how to fix it. In the source file gdchart-0.2.0/gdchart.c perform these replacements:

195c195
< function_entry gdchart_functions[] = {
---
> zend_function_entry gdchart_functions[] = {
303c303
< 	zend_hash_copy(intern->zo.properties, &class_type->default_properties, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *));
---
> 	object_properties_init((zend_object*) &(intern->zo), class_type);

Then perform the usual extension compilation routine:
gdchart-0.2.0]$ phpize
gdchart-0.2.0]$ ./configure
gdchart-0.2.0]$ make && make test

As you can see, you’re not done. Don’t try to install this module yet it won’t load, failing with PHP Warning: PHP Startup: Unable to load dynamic library '/home/jack/build/gdchart-0.2.0/modules/gdchart.so' - /home/jack/build/gdchart-0.2.0/modules/gdchart.so: undefined symbol: php_gd_gdFontMediumBold in Unknown on line 0

Now we have to patch some PHP GD core files to accommodate changes in the visibility of a few GD resources, fortunately we have a patch for that here:https://github.com/arete/t2/blob/master/package/php/php/libgd-symbol-visibility.patch.

After patching the PHP sources, recompile and install along with the GDChart extension. Or do what any sane person would do and use a more recent and maintained visualization library like PHPlot, pChart or Google Charts.

This was a real annoyance to sort out, and I’ll likely need to do this again on the next kernel update so I’m documenting it here. The Corsair K70 is a great device, ignoring the pretty lights it’s a solid input device though it does have one particularly annoying functional aspect in various versions of Linux and that is an approximate 12-30 second delay during boot where the USB polling routine fails to enumerate the device (during report ret.) and time out before continuing. The following pertains to Ubuntu and Fedora/CentOS.

In your boot log (/var/log/boot.log) you will see a series of logged events similar to this:

workstation kernel: [   11.945167] hid-generic 0003:1B1C:1B13.0002: usb_submit_urb(ctrl) failed: -1
workstation kernel: [   11.945175] hid-generic 0003:1B1C:1B13.0002: timeout initializing reports
workstation kernel: [   11.945284] input: Corsair Corsair K70 RGB Gaming Keyboard  as /devices/pci0000:00/0000:00:14.0/usb2/2-10/2-10:1.1/0003:1B1C:1B13.0002/input/input15
workstation kernel: [   11.945373] hid-generic 0003:1B1C:1B13.0002: input,hidraw1: USB HID v1.11 Keyboard [Corsair Corsair K70 RGB Gaming Keyboard ] on usb-0000:00:14.0-10/input1
workstation kernel: [   21.954441] hid-generic 0003:1B1C:1B13.0003: timeout initializing reports
workstation kernel: [   21.954651] hid-generic 0003:1B1C:1B13.0003: hiddev0,hidraw2: USB HID v1.11 Device [Corsair Corsair K70 RGB Gaming Keyboard ] on usb-0000:00:14.0-10/input2
workstation kernel: [   31.967629] hid-generic 0003:1B1C:1B13.0004: usb_submit_urb(ctrl) failed: -1
workstation kernel: [   31.967642] hid-generic 0003:1B1C:1B13.0004: timeout initializing reports
workstation kernel: [   31.967762] hid-generic 0003:1B1C:1B13.0004: hiddev0,hidraw3: USB HID v1.11 Device [Corsair Corsair K70 RGB Gaming Keyboard ] on usb-0000:00:14.0-10/input3

As you can see the K70 is actually composed of 3 different input devices. The first being the light controller, the second being the the media controls and the third is the keyboard device which eventually loads. The first two fail during report retrieval and are the cause of the delay, this is likely a kernel bug and may take time before support is added. In the meantime we can get around the problem by introducing a usb “quirks” directive to instruct the kernel to not wait for these devices to be recognized/reported and continue.

To do this, find the devices vendor and device IDs:
~$ lsusb -v
which gives something like
Bus 002 Device 003: ID 1b1c:1b13 Corsair
Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 2.00
bDeviceClass 0 (Defined at Interface level)
bDeviceSubClass 0
bDeviceProtocol 0
bMaxPacketSize0 64
idVendor 0x1b1c Corsair
idProduct 0x1b13

bcdDevice 1.30
iManufacturer 1
iProduct 2
iSerial 3
bNumConfigurations 1
Configuration Descriptor:
<<<******etc, etc******>>>

We need the ‘idVendor’ and ‘idProduct’ values to construct the quirks directive. Now open a terminal and use vim/nano/gedit/*whatever to open ‘/etc/modprobe.d/usbhid.conf’ and add the following:
options usbhid quirks=0x1B1C:0x1B13:0x20000000

The syntax of this directive is ‘usbhid quirks=vendor:product:quirk’, where ‘quirk’ is the defined instruction “HID_QUIRK_NO_INIT_REPORTS” defined in the 3.16 kernel sources ‘linux/hid.h’ -> #define HID_QUIRK_NO_INIT_REPORTS 0x20000000 This simply instructs the kernel not to attempt to generate a device report for the K70 on boot.

Now we need to rebuild initramfs to include the change in the root file system.
Ubuntu:~$ sudo update-initramfs -u
Fedora:~$ sudo dracut -f

Now reboot and notice there’s no more delay.