FreeBSDでOkaConsole Quadを使えるようにした

検証環境用のコンソール接続に、OkaConsole Quadを使わせてもらってます。

Chiba Sweet Sounds Jazz Orchestra - OkaConsole Quad

今もまだ作ってらっしゃるのかな…このハードは個人制作のアイテムなのですが

  • USB-シリアル4ポート変換アダプタ(FTDI社のFT4232Hを使用)
  • ポケットに入るほどの小ささ
  • UTPケーブル(ストレート)をそのまま利用可能
  • CiscoなどのRJ-45のコンソールポートに直結可能
  • ボーレート 115200 bpsで4つ同時に通信してもデータ化けなどしない

という、とてつもなく便利なUSB-シリアル変換アダプタなのです。可能ならもう1個ほしいぐらい。

FreeBSDでは使えない?

このOkaConsole QuadをRaspberry Pi 3 model B+に接続してなんちゃってコンソールサーバにしてたのですが、「FreeBSDの勉強がしたい!常時稼働環境つくりたい!」という理由だけで、RaspbianからFreeBSDに乗り換えをしてしまいまして。急遽環境を作り直すことに。

ところがOkaConsole Quad、Linuxでは手を入れずに4ポートのUSBシリアルポートであることを認識して /dev/ttyUSB[0-3] として使えるのですが、FreeBSDではそのままでは認識できません。dmesgでみても

# dmesg | grep OkaConsole
ugen0.4: <Okada OkaConsole Quad> at usbus0

としか見えてません。デバイスとしてはちゃんと見えているので、

# usbconfig -d ugen0.4 dump_device_desc
ugen0.4: <Okada OkaConsole Quad> at usbus0, cfg=0 md=HOST spd=HIGH (480Mbps) pwr=ON (100mA)

bLength = 0x0012
bDescriptorType = 0x0001
bcdUSB = 0x0200
bDeviceClass = 0x0000 <Probed by interface class>
bDeviceSubClass = 0x0000
bDeviceProtocol = 0x0000
bMaxPacketSize0 = 0x0040
idVendor = 0x0403
idProduct = 0x9a99
bcdDevice = 0x0800
iManufacturer = 0x0001 <Okada>
iProduct = 0x0002 <OkaConsole Quad>
iSerialNumber = 0x0003 <CNS40016>
bNumConfigurations = 0x0001

と、情報も取得できます。

ここまで見えてるならあとはドライバだけの話(の、はず…)なので、FreeBSDよくわからないのにカーネルに手を入れることを決断しました。

ソースの旅

といっても、どこに手を入れればいいかわからない。まずは「FreeBSD FTDI」とかで調べてみると、uftdi(4) が一発で見つかりました。

uftdi(4)

ここを見るとFT4232Hもサポートしていることが確認できたので、ドライバ(uftdi)にはOkaConsole Quadを制御する能力があると判断できます。ではこのドライバで認識できてるのかというと?

# dmesg | grep uftdi
#

認識できてない…となると、あとはuftdi(4)で正しくデバイスを認識できるようにすれば行けるはず!

ということでカーネルソースから検索。

# cd /usr/src/sys
# find . -name 'uftdi*'
./dev/usb/serial/uftdi_reg.h
./dev/usb/serial/uftdi.c
./dev/usb/uftdiio.h
./modules/usb/uftdi

多分これかなーってことで、 /usr/src/sys/dev/usb/serial/uftdi.c を確認。眺めてみると…

(略)
270 static const STRUCT_USB_HOST_ID uftdi_devs[] = {
271 #define UFTDI_DEV(v, p, i) \
272 { USB_VPI(USB_VENDOR_##v, USB_PRODUCT_##v##_##p, i) }
273 UFTDI_DEV(ACTON, SPECTRAPRO, 0),
274 UFTDI_DEV(ALTI2, N3, 0),
275 UFTDI_DEV(ANALOGDEVICES, GNICE, UFTDI_JTAG_IFACE(0)),
276 UFTDI_DEV(ANALOGDEVICES, GNICEPLUS, UFTDI_JTAG_IFACE(0)),
277 UFTDI_DEV(ATMEL, STK541, 0),
278 UFTDI_DEV(BAYER, CONTOUR_CABLE, 0),
279 UFTDI_DEV(BBELECTRONICS, 232USB9M, 0),
280 UFTDI_DEV(BBELECTRONICS, 485USB9F_2W, 0),
(略)

おう?ベンダID、プロダクトIDの情報をここで登録してるっぽいな。てことはこの辺の情報がどっかに書いてあるのかも?探そう

# pwd
/usr/src/sys
# grep -l -R SPECTRAPRO *
dev/usb/serial/uftdi.c
dev/usb/usbdevs

みーつけた! /usr/src/sys/dev/usb/usbdevs ね。

# grep vendor /usr/src/sys/dev/usb/usbdevs | grep FTDI
vendor FTDI 0x0403 Future Technology Devices

うんうん、FTDIの0x0403ってベンダーIDはさっきusbconfigで確認したよね。

# usbconfig -d ugen0.4 dump_device_desc
(略)
idVendor = 0x0403
idProduct = 0x9a99

ってことはプロダクトIDがあるかどうかか。

# grep FTDI /usr/src/sys/dev/usb/usbdevs | grep 9a99
#

ないじゃん。これが原因かな。

カーネルいじるぜ!

ってことで想定通りドライバをいじればいけそうだったので

  •  /usr/src/sys/dev/usb/usbdevs にOkaConsole Quadの情報追加
  •  /usr/src/sys/dev/usb/serial/uftdi.c に追加したデバイス情報を登録

することに。修正内容は以下の通り。

# pwd
/usr/src/sys
# svnlite diff
Index: dev/usb/serial/uftdi.c
===================================================================
--- dev/usb/serial/uftdi.c (revision 355412)
+++ dev/usb/serial/uftdi.c (working copy)
@@ -909,6 +909,7 @@
UFTDI_DEV(TML, USB_SERIAL, 0),
UFTDI_DEV(TTI, QL355P, 0),
UFTDI_DEV(UNKNOWN4, NF_RIC, 0),
+ UFTDI_DEV(FTDI, OKACONSOLE_QUAD, 0),
#undef UFTDI_DEV
};

Index: dev/usb/usbdevs
===================================================================
--- dev/usb/usbdevs (revision 355412)
+++ dev/usb/usbdevs (working copy)
@@ -2232,6 +2232,9 @@
product FTDI XM_RADIO 0x937a FTDI compatible adapter
product FTDI YEI_SERVOCENTER31 0xe050 FTDI compatible adapter

+/* OkaConsole Quad (FTDI 4232H chip) */
+product FTDI OKACONSOLE_QUAD 0x9a99 OkaConsole Quad
+
/* Fuji photo products */
product FUJIPHOTO MASS0100 0x0100 Mass Storage

修正後に以下の通りカーネルのビルドとインストールを実施。

# cd /usr/src
# make -j 8 buildkernel KERNCONF=GENERIC
# make installkernel KERNCONF=GENERIC

新しいカーネルのビルドとインストールにおよそ4時間…

結果!

# dmesg | grep uftdi
uftdi0 on uhub1
uftdi0: <OkaConsole Quad> on usbus0
uftdi1 on uhub1
uftdi1: <OkaConsole Quad> on usbus0
uftdi2 on uhub1
uftdi2: <OkaConsole Quad> on usbus0
uftdi3 on uhub1
uftdi3: <OkaConsole Quad> on usbus0
# ls /dev/ttyU*
/dev/ttyU0 /dev/ttyU0.lock /dev/ttyU1.init /dev/ttyU2 /dev/ttyU2.lock /dev/ttyU3.init
/dev/ttyU0.init /dev/ttyU1 /dev/ttyU1.lock /dev/ttyU2.init /dev/ttyU3 /dev/ttyU3.lock
# ls /dev/cuaU*
/dev/cuaU0 /dev/cuaU0.lock /dev/cuaU1.init /dev/cuaU2 /dev/cuaU2.lock /dev/cuaU3.init
/dev/cuaU0.init /dev/cuaU1 /dev/cuaU1.lock /dev/cuaU2.init /dev/cuaU3 /dev/cuaU3.lock

想定通り!これでFreeBSD 12.1 on Raspberry Pi でもOkaConsole Quad使えるようになりました!

まとめ

使えない!で終わらせないで、頑張って調べればなんとかなる!

ということで、FreeBSDの常時稼働環境を充実させて、運用面でのお勉強も進めていきたいと思います。

コメント

タイトルとURLをコピーしました