RealforceがLinuxで認識しなかった時の対処法

# 症状

* 東プレ製のキーボード"Realforce"を筐体に挿しても、Ubuntu上でキーが反応しない
  * BIOSやgrubブートメニューではキーが反応する

## 環境

| Name | Description |
| :-- | :-- |
| キーボード | [Realforce104UB-S](https://www.diatec.co.jp/shop/det.php?prod_c=2172) |
| PC筐体 | [DELL OptiPlex 7060](https://japancatalog.dell.com/pd/optiplex-7060.html) | 
| OS | Ubuntu 16.04.6 LTS (xenial) |
| Kernel | 4.15.0 |

## dmesg

* dmesgを叩くと次のようなエラーが出ている

```bash
$ dmesg
〜中略〜
[  126.722472] usb 1-1: new full-speed USB device number 5 using xhci_hcd
[  126.872029] usb 1-1: unable to read config index 0 descriptor/start: -32
[  126.872047] usb 1-1: chopping to 0 config(s)
[  126.872958] usb 1-1: New USB device found, idVendor=0853, idProduct=011b
[  126.872963] usb 1-1: New USB device strings: Mfr=1, Product=2, SerialNumber=0
[  126.872967] usb 1-1: Product: Realforce
[  126.872970] usb 1-1: Manufacturer: Topre Corporation
[  126.873214] usb 1-1: no configuration chosen from 0 choices
```


# 有効だった解決法

## 自分でカーネルにパッチを当てる

* 似た症状の人のバグレポートを参考にして、カーネルソースを書き換えてビルドした
  * [Bug #1678477 “Kernel has troule recognizing Corsair Strafe RGB k...” : Bugs : linux package : Ubuntu](https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1678477)
* 自分の環境がUbuntuだったのでそれに従って手順を書くが、他のディストリビューションでも同じ問題が起きることがわかったので、各ディストリビューションでのカーネルビルドの方法に従っていただきたい

## 手順

### 必要なライブラリをインストール

```bash
$ sudo apt install -y git build-essential kernel-package fakeroot libncurses5-dev libssl-dev ccache
```

### カーネルのソースコードを取得 

* 僕の環境では`4.15.0`だったので対応するもの（`4.15.y`）を利用
  * バージョン名は適宜読み変えてください

```bash
$ cd ~
$ mkdir -p kernel-build
$ cd kernel-build
$ git clone -b linux-4.15.y git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git
$ cd linux-stable
```

### USBに関するソースコードの書き換え

* `drivers/usb/core/quirks.c`に定義されている`usb_quirk_list`に、利用したいキーボードに関するエントリを追加する

```diff
diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c
index 54b019e..060c47a 100644
--- a/drivers/usb/core/quirks.c
+++ b/drivers/usb/core/quirks.c
@@ -256,6 +256,10 @@ static const struct usb_device_id usb_quirk_list[] = {
 	/* INTEL VALUE SSD */
 	{ USB_DEVICE(0x8086, 0xf1a5), .driver_info = USB_QUIRK_RESET_RESUME },
 
+	/* Realforce104UB-S */
+	{ USB_DEVICE(0x0853, 0x011b), .driver_info = USB_QUIRK_DELAY_INIT |
+ USB_QUIRK_NO_LPM | USB_QUIRK_DEVICE_QUALIFIER },
+
 	{ }  /* terminating entry must be last */
 };
```

* `USB_DEVICE(0x0853, 0x011b)`のところは、それぞれVendorIDとProductIDを入れる
  * VendorIDとProductIDは、`dmesg`か`lsusb`で確認できる

### カーネルのビルド

* 先に、現在使っているカーネルの設定を引き継ぐ

```
$ cp /boot/config-$(uname -r) ./.config
$ yes '' | make oldconfig
```

* ビルド（大体1時間くらいかかる）
  * `LOCALVERSION`はsuffixの指定なので、好きなように変える
    * 例だとバージョン表記が`4.15.18-kbdfix`となる

```bash
$ sudo make -j $(getconf _NPROCESSORS_ONLN) deb-pkg LOCALVERSION=-kbdfix
```

* ビルドが完了したらパッケージをインストール

```bash
$ cd ..
$ sudo dpkg -i linux-libc-dev_4.15.18-kbdfix-1_amd64.deb
$ sudo dpkg -i linux-headers-4.15.18-kbdfix_4.15.18-custom-1_amd64.deb
$ sudo dpkg -i linux-image-4.15.18-kbdfix-dbg_4.15.18-kbdfix-1_amd64.deb
$ sudo dpkg -i linux-image-4.15.18-kbdfix_4.15.18-kbdfix-1_amd64.deb
```

* 再起動して`uname -r`で新しいバージョンになっていればインストール完了
* 僕の場合は問題なく反応するようになった

## 参考

* [初心者向けKernelのビルド手順 | ガジェット好きの日記](https://mongonta.com/f258-howto-build-linux-kernel/)
* [How to Build a Custom Kernel on Ubuntu - Make Tech Easier](https://www.maketecheasier.com/build-custom-kernel-ubuntu/)


# 試したがダメだった解決法

## xserver-xorg-input-allのインストール

```
$ sudo apt-get install xserver-xorg-input-all
```

* 参考: [Keyboard not working after update to 18.04 - Ask Ubuntu](https://askubuntu.com/questions/1033767/keyboard-not-working-after-update-to-18-04)
* 既に最新だった

## カーネルバージョンの更新

```
$ sudo apt install linux-generic-hwe-16.04
```

* 16.04用に提供されている中で最新のカーネルへ更新
  * `4.15.0-15`から`4.15.0-47`に更新された
* 再起動してキーボードをUSB3.0のポートに繋ぎ直すと一時的にキーボードが反応するように
* しかしポートを再び繋ぎ変えると、それ以降また反応しなくなった