Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Segfault with K70 RGB in BIOS mode. #48

Closed
tatokis opened this issue Jan 30, 2017 · 23 comments
Closed

Segfault with K70 RGB in BIOS mode. #48

tatokis opened this issue Jan 30, 2017 · 23 comments

Comments

@tatokis
Copy link
Collaborator

tatokis commented Jan 30, 2017

Thread 6 "ckb-daemon" received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7ffff5be1700 (LWP 25990)]
0x00000000004094da in os_inputmain (context=0x8) at usb_linux.c:105
105	        urbs[2].buffer_length = MSG_SIZE;
(gdb) bt full
#0  0x00000000004094da in os_inputmain (context=0x8) at usb_linux.c:105
        kb = 0x624a38 <keyboard+248>
        fd = 3
        vendor = 6940
        product = 6931
        index = 1
        urbcount = 0
        urbs = 0x7fff00000015
#1  0x00007ffff7bc16ba in start_thread (arg=0x7ffff5be1700) at pthread_create.c:333
        __res = <optimized out>
        pd = 0x7ffff5be1700
        now = <optimized out>
        unwind_buf = {cancel_jmp_buf = {{jmp_buf = {140737316263680, 1718746363551489728, 0, 140737335160399, 140737316264384, 140737219939488, -1718723823047860544, -1718728203071054144}, 
              mask_was_saved = 0}}, priv = {pad = {0x0, 0x0, 0x0, 0x0}, data = {prev = 0x0, cleanup = 0x0, canceltype = 0}}}
        not_first_call = <optimized out>
        pagesize_m1 = <optimized out>
        sp = <optimized out>
        freesize = <optimized out>
        __PRETTY_FUNCTION__ = "start_thread"
#2  0x00007ffff78f782d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:109

From what I've gathered so far, the urbcount isn't supposed to be 0.
This broke ever since ccMSC updated the USB handling code to work with newer firmware versions.

@frickler24
Copy link
Collaborator

@tatokis I'm wondering on the vendor and product numbers. seems to be some problems with the stack?
the urbs-array has dynamic dimension, depending on a value epcount in the kb struct:

    int urbcount = IS_RGB(vendor, product) ? (kb->epcount - 1) : kb->epcount;
    struct usbdevfs_urb urbs[urbcount];

with urbcount = 0 you get an undefined array and with this a segv.
So the question is: who destroyed the content of the kb struct (the pointer seems to be ok)?

@tatokis
Copy link
Collaborator Author

tatokis commented Jan 30, 2017 via email

@frickler24
Copy link
Collaborator

Ah, sorry, the vendor / product info is in decimal.
With RGB devices the minimum size of the array in the code must be 3. I'll have a look, what ccMSC changed in the past.

@tatokis
Copy link
Collaborator Author

tatokis commented Jan 30, 2017

While I did try it earlier, I tried it again.

tatokis@tatokis-PC:~/ckb-next/ckb-next$ sudo ./bin/ckb-daemon 
[sudo] password for tatokis: 
    ckb: Corsair RGB driver beta-v0.2.7
[I] Root controller ready at /dev/input/ckb0
[I] Connecting Corsair K70 RGB Gaming Keyboard at /dev/input/ckb1
[I] Starting input thread for /dev/input/ckb1
[I] Setup finished for /dev/input/ckb1
[I] Stopping input thread for /dev/input/ckb1
[E] os_usbsend (via led_keyboard.c:131): No such device
[I] Attempting reset...
[E] os_resetusb (via usb.c:169): resetusb failed: No such device
[E] usb_tryreset (usb.c:177): Reset failed. Disconnecting.
[I] Disconnecting /dev/input/ckb1
[I] Removed device path /dev/input/ckb1
[I] Connecting Corsair K70 RGB Gaming Keyboard at /dev/input/ckb1
[I] Starting input thread for /dev/input/ckb1
eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee[E] os_usbrecv (via firmware.c:15): Connection timed out
[W] _start_dev (device.c:24): Unable to load firmware version/poll rate
[I] Setup finished for /dev/input/ckb1
ee[E] os_usbsend (via device_keyboard.c:38): No such file or directory
[I] Attempting reset...
[E] os_resetusb (via usb.c:169): resetusb failed: No such device
[E] usb_tryreset (usb.c:177): Reset failed. Disconnecting.
[I] Disconnecting /dev/input/ckb1
[I] Stopping input thread for /dev/input/ckb1
*** stack smashing detected ***: ./bin/ckb-daemon terminated
Ακυρώθηκε
tatokis@tatokis-PC:~/ckb-next/ckb-next$ eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee

I switched the keyboard to BIOS mode at "[I] Removed device path /dev/input/ckb1".
Funny thing is how my keyboard kept inputting the "e" key, the super key was also stuck afterwards before it hit a SIGABRT.

Basically, it is not an easy fix. We need to find the root cause of it. Not 100% sure, but I think it's supposed to have 3 URBs for RGB keyboards.

@tatokis
Copy link
Collaborator Author

tatokis commented Jan 30, 2017

Ah, just saw your new reply. I can probably find the relevant commits.

@tatokis
Copy link
Collaborator Author

tatokis commented Jan 30, 2017

I think this might be related ccMSC/ckb@dfc2fab

@frickler24
Copy link
Collaborator

Yes, this one and ccMSC/ckb@7eaf1ae.
With this switch in mind, it seems that we may define 3 urbs, but we get input only from urb1.
Should we try a first hack in usb_linux.c after reading the number of epcounts:
if (urbcount == 0) urbcount = 3;

Maybe we get a runtime error in line 113 (in the for-loop with ioctl). with this we have the value kb->epcount still 1.

@tatokis
Copy link
Collaborator Author

tatokis commented Jan 30, 2017

It just keeps trying to reset the keyboard while leaving it in an unusable state.

[E] os_usbrecv (via firmware.c:15): Connection timed out
[W] _start_dev (device.c:24): Unable to load firmware version/poll rate
[I] Setup finished for /dev/input/ckb1
[E] os_usbsend (via device_keyboard.c:38): No such file or directory
[I] Attempting reset...
[E] os_resetusb (via usb.c:169): resetusb failed: No such device
[E] usb_tryreset (usb.c:177): Reset failed. Disconnecting.

@frickler24
Copy link
Collaborator

yes, I tried it also.
Session was as follows:

Running normal ckb-daemon and KB with 1ms. (I have a K95RGB).
Then switching to BIOS.
Daemon closes channel 1

If I restart ckb-daemon, I get every time the same error:```

(gdb) run
Starting program: /home/lutz/Projekte/ckb-next/bin/ckb-daemon
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
ckb: Corsair RGB driver beta-v0.2.7
[I] Root controller ready at /dev/input/ckb0
[New Thread 0x7ffff75e8700 (LWP 32721)]
[I] Connecting Corsair K95 RGB Gaming Keyboard at /dev/input/ckb1
[W] os_setupusb (usb_linux.c:293): Unable to read endpoint count from udev, assuming 4...
[E] os_setupusb (usb_linux.c:296): Failed to claim interfaces: No such file or directory
[I] Disconnecting /dev/input/ckb1
[I] Removed device path /dev/input/ckb1
[Thread 0x7ffff75e8700 (LWP 32721) exited]


@frickler24
Copy link
Collaborator

Just un- / replugging KB with running daemon gives the same error
New Thread 0x7ffff6de7700 (LWP 443)]
[I] Connecting Corsair K95 RGB Gaming Keyboard at /dev/input/ckb1
[W] os_setupusb (usb_linux.c:293): Unable to read endpoint count from udev, assuming 4...
[E] os_setupusb (usb_linux.c:296): Failed to claim interfaces: No such file or directory
[I] Disconnecting /dev/input/ckb1
[I] Removed device path /dev/input/ckb1
[Thread 0x7ffff6de7700 (LWP 443) exited]

@frickler24
Copy link
Collaborator

Closing daemon, un- /replugging KB and then starting daemon is ok:
(gdb) run
Starting program: /home/lutz/Projekte/ckb-next/bin/ckb-daemon
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
ckb: Corsair RGB driver beta-v0.2.7
[I] Root controller ready at /dev/input/ckb0
[New Thread 0x7ffff75e8700 (LWP 526)]
[I] Connecting Corsair K95 RGB Gaming Keyboard at /dev/input/ckb1
[New Thread 0x7ffff6de7700 (LWP 537)]
[I] Starting input thread for /dev/input/ckb1
[New Thread 0x7ffff65e6700 (LWP 539)]
[I] Setup finished for /dev/input/ckb1

Now I try another thing: Resetting daemon at runtime

@tatokis
Copy link
Collaborator Author

tatokis commented Jan 30, 2017

What I think happened is that with the new firmware, corsair changed the endpoints and ccMSC only updated the code for the normal (non BIOS) mode.

@frickler24
Copy link
Collaborator

yes, this might be the reason.
I'm just wondering why we have to restart daemon and Keyboard to fix it. Why not only resetting KB?

@frickler24
Copy link
Collaborator

I did some hack into the daemon at the point it says "... assuming...". The driver gives an empty string as number of endpoints:
W] os_setupusb (usb_linux.c:293): Unable to read endpoint count from udev, assuming 4 and reading >><<...
[E

@frickler24
Copy link
Collaborator

disconnecting the kb, waiting some seconds and reconnecting brings sometimes the still running daemon to reconnect. All depends on the return value of
const char* ep_str = udev_device_get_sysattr_value(dev, "bNumInterfaces");

maybe dev is corrupt, I will check next.

@frickler24
Copy link
Collaborator

The kernel logging gives some hints, that the KB is not recognized correctly while the daemon is running:
30.01.17 22:36 Mainfrix mtp-probe bus: 3, device: 35 was not an MTP device
30.01.17 22:37 Mainfrix kernel [17215.995062] usb 3-4: USB disconnect, device number 35
30.01.17 22:37 Mainfrix kernel [17225.678092] usb 3-4: new full-speed USB device number 36 using xhci_hcd
30.01.17 22:37 Mainfrix kernel [17235.805760] usb 3-4: string descriptor 0 read error: -110
30.01.17 22:37 Mainfrix kernel [17235.805764] usb 3-4: New USB device found, idVendor=1b1c, idProduct=1b11
30.01.17 22:37 Mainfrix kernel [17235.805766] usb 3-4: New USB device strings: Mfr=1, Product=2, SerialNumber=3
30.01.17 22:37 Mainfrix kernel [17240.805896] usb 3-4: can't set config #1, error -110
30.01.17 22:37 Mainfrix mtp-probe checking bus 3, device 36: "/sys/devices/pci0000:00/0000:00:14.0/usb3/3-4"
30.01.17 22:37 Mainfrix mtp-probe bus: 3, device: 36 was not an MTP device

@frickler24
Copy link
Collaborator

This is the correct kernel info when reconnecting the KB:
30.01.17 22:44 Mainfrix kernel [17649.638944] usb 3-4: new full-speed USB device number 40 using xhci_hcd
30.01.17 22:44 Mainfrix kernel [17649.768451] usb 3-4: New USB device found, idVendor=1b1c, idProduct=1b11
30.01.17 22:44 Mainfrix kernel [17649.768453] usb 3-4: New USB device strings: Mfr=1, Product=2, SerialNumber=3
30.01.17 22:44 Mainfrix kernel [17649.768454] usb 3-4: Product: Corsair K95 RGB Gaming Keyboard
30.01.17 22:44 Mainfrix kernel [17649.768455] usb 3-4: Manufacturer: Corsair
30.01.17 22:44 Mainfrix kernel [17649.768456] usb 3-4: SerialNumber: 0F022014AE3B9406537275B6F5001945
30.01.17 22:44 Mainfrix kernel [17654.767687] input: Corsair Corsair K95 RGB Gaming Keyboard as /devices/pci0000:00/0000:00:14.0/usb3/3-4/3-4:1.0/0003:1B1C:1B11.001B/input/input63
30.01.17 22:44 Mainfrix kernel [17654.767970] hid-generic 0003:1B1C:1B11.001B: input,hidraw8: USB HID v1.11 Keyboard [Corsair Corsair K95 RGB Gaming Keyboard ] on usb-0000:00:14.0-4/input0
30.01.17 22:44 Mainfrix kernel [17654.768910] input: Corsair Corsair K95 RGB Gaming Keyboard as /devices/pci0000:00/0000:00:14.0/usb3/3-4/3-4:1.1/0003:1B1C:1B11.001C/input/input64
30.01.17 22:44 Mainfrix kernel [17654.769032] hid-generic 0003:1B1C:1B11.001C: input,hiddev0,hidraw9: USB HID v1.11 Keyboard [Corsair Corsair K95 RGB Gaming Keyboard ] on usb-0000:00:14.0-4/input1
30.01.17 22:44 Mainfrix kernel [17654.769091] usbhid 3-4:1.2: couldn't find an input interrupt endpoint
30.01.17 22:44 Mainfrix mtp-probe checking bus 3, device 40: "/sys/devices/pci0000:00/0000:00:14.0/usb3/3-4"
30.01.17 22:44 Mainfrix mtp-probe bus: 3, device: 40 was not an MTP device

@frickler24
Copy link
Collaborator

IN the opening function setupusb, I get only the firmware number. None of the Name of the KB or the serialNo.
This may be OK, because the kernel does not recognize the KB as a valid device.

Some ggogling gave me a hint, which might fit to our scenario:
link
Has switching to BIOS mode something to do with legacy USB modes? Ill have a look tomorrow.

@tatokis
Copy link
Collaborator Author

tatokis commented Jan 30, 2017

I noticed [1118663.458830] usbhid 8-1:1.2: couldn't find an input interrupt endpoint in dmesg
So I decided to compare the endpoints lsusb sees in both BIOS and non-BIOS modes.
BIOS:

$ lsusb -vd '1b1c:'

Bus 008 Device 011: ID 1b1c:1b13 Corsair 
Couldn't open device, some information will be missing
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            2.05
  iManufacturer           1 
  iProduct                2 
  iSerial                 3 
  bNumConfigurations      1
  Configuration Descriptor:
    bLength                 9
    bDescriptorType         2
    wTotalLength           34
    bNumInterfaces          1
    bConfigurationValue     1
    iConfiguration          0 
    bmAttributes         0xa0
      (Bus Powered)
      Remote Wakeup
    MaxPower              500mA
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        0
      bAlternateSetting       0
      bNumEndpoints           1
      bInterfaceClass         3 Human Interface Device
      bInterfaceSubClass      1 Boot Interface Subclass
      bInterfaceProtocol      1 Keyboard
      iInterface              0 
        HID Device Descriptor:
          bLength                 9
          bDescriptorType        33
          bcdHID               1.11
          bCountryCode            0 Not supported
          bNumDescriptors         1
          bDescriptorType        34 Report
          wDescriptorLength      67
         Report Descriptors: 
           ** UNAVAILABLE **
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x81  EP 1 IN
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0008  1x 8 bytes
        bInterval               8

Normal:

$ lsusb -vd '1b1c:'

Bus 008 Device 012: ID 1b1c:1b13 Corsair 
Couldn't open device, some information will be missing
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            2.05
  iManufacturer           1 
  iProduct                2 
  iSerial                 3 
  bNumConfigurations      1
  Configuration Descriptor:
    bLength                 9
    bDescriptorType         2
    wTotalLength           84
    bNumInterfaces          3
    bConfigurationValue     1
    iConfiguration          0 
    bmAttributes         0xa0
      (Bus Powered)
      Remote Wakeup
    MaxPower              500mA
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        0
      bAlternateSetting       0
      bNumEndpoints           1
      bInterfaceClass         3 Human Interface Device
      bInterfaceSubClass      1 Boot Interface Subclass
      bInterfaceProtocol      1 Keyboard
      iInterface              0 
        HID Device Descriptor:
          bLength                 9
          bDescriptorType        33
          bcdHID               1.11
          bCountryCode            0 Not supported
          bNumDescriptors         1
          bDescriptorType        34 Report
          wDescriptorLength      67
         Report Descriptors: 
           ** UNAVAILABLE **
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x81  EP 1 IN
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0008  1x 8 bytes
        bInterval               8
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        1
      bAlternateSetting       0
      bNumEndpoints           1
      bInterfaceClass         3 Human Interface Device
      bInterfaceSubClass      0 No Subclass
      bInterfaceProtocol      0 None
      iInterface              0 
        HID Device Descriptor:
          bLength                 9
          bDescriptorType        33
          bcdHID               1.11
          bCountryCode            0 Not supported
          bNumDescriptors         1
          bDescriptorType        34 Report
          wDescriptorLength     112
         Report Descriptors: 
           ** UNAVAILABLE **
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x82  EP 2 IN
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0040  1x 64 bytes
        bInterval               1
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        2
      bAlternateSetting       0
      bNumEndpoints           1
      bInterfaceClass         3 Human Interface Device
      bInterfaceSubClass      0 No Subclass
      bInterfaceProtocol      0 None
      iInterface              0 
        HID Device Descriptor:
          bLength                 9
          bDescriptorType        33
          bcdHID               1.11
          bCountryCode            0 Not supported
          bNumDescriptors         1
          bDescriptorType        34 Report
          wDescriptorLength      25
         Report Descriptors: 
           ** UNAVAILABLE **
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x03  EP 3 OUT
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0040  1x 64 bytes
        bInterval               1

It is clear that it only exposes a single endpoint in BIOS mode, so forcing the daemon to use more than one will most likely not work.
Maybe we should just not grab the keyboard when in BIOS mode? It seems to be pretty useless in that mode, as you can only read input from it.

@frickler24
Copy link
Collaborator

I believe that would be the best.
Also I did some testing without ckb-daemon running: Switching modes sometimes kills the KB in the usb driver.
In this status only unplug / replug helps.

KB-logfileSwitchingStates.txt

@frickler24
Copy link
Collaborator

The corsair page shows the following info belonging to switching modes while running:

However, if you have our keyboard with a polling rate selector switch near the USB cable, you can perform a "soft" reset by sliding the switch to BIOS then back to 1, 2, 4, or 8.
here

@frickler24
Copy link
Collaborator

For now I did some debugging info and I have a solution for the following cases:

  1. Zero endpoints given from KB (happens when switching fails internally): Closing channel, KB is working.
  2. One endpoint is given: Seems to be in BIOS mode
  3. two endpoints are defined: I Can't test this, because I have an RGB KB only. But I didn't change anything for this condition (hopefully).
  4. 3/4 endpoints are normal in RGB state. are running as before.

Next two days I will do some more testing, then I'll post a PReq. There are a lot of combinations with switching modes while plugged in and switching while unplugged.

@tatokis
Copy link
Collaborator Author

tatokis commented Feb 1, 2017 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants