FreeBSDでuhubctlというオープンソースがビルドはできるのですが、正常に動作しないので調べたところusbconfigとusb_hubにその機能が実装されているため、コンフリクトして上手く動かないようです。FreeBSD/amd64 13Rで確認しました。
ワインをこぼしてつぶしてしまったApple ProキーボードにはAlcor Micro社のAU9432というチップが使われています。なにかに使えるかと思って基板だけとってありました。
このチップはHUBを内蔵していて、その下にキーボードとUSBポートが2つ出ています。
2ポートのUSBにはそれぞれGANGPWRN(39),DP2PWRUP(41)が出ているのでPer-Port(Individualモード)でもギャング(まとめて処理する方式)でもPowerコントロールできます。
Apple ProキーボードはAnalog Integrations社のAIC1525というSOP8のPowerコントロールチップを使っていて、このチップは一系統しか制御できないのでギャングになります。AIC1525のCTLはAU9432のGANGPWRNにつながっています。
当初このチップはEEPROMかと思っていたのですが、EEPROMなら本体チップ(AU9432)のすぐ近くに置くはずが、すこし離れていて、よく見たらPowerコントロールチップでした。
そもそもFreeBSDのusbconfigでのPowerコントロールはギャングにしか対応していなくて試してみると以下のようになります。
ugen0.2: <Mitsumi Electric Hub in Apple Extended USB Keyboard> at usbus0, cfg=0 md=HOST spd=FULL (12Mbps) pwr=SAVE (50mA)
ugen0.3: <Mitsumi Electric Apple Extended USB Keyboard> at usbus0, cfg=255 md=HOST spd=FULL (12Mbps) pwr=OFF (50mA)
ugen0.4: <Ralink 802.11 n WLAN> at usbus0, cfg=255 md=HOST spd=FULL (12Mbps) pwr=OFF (100mA)
この状態で、
% sudo usbconfig -d ugen0.2 power_off
するとギャングが実行されて、ugen0.3,ugen0.4が見えなくなって、USBポートの電源の5Vも出なくなっているのが確認できます。
同じ状態でugen0.4をpower_offするとデバイスがPowerオフになりますが、給電はされたままです。
usbconfigのmanページに
Power off the device on USB bus 1 at address 2:
usbconfig ugen1.2 power_off
-dが抜けています。おそらく誰も使ってないんでしょうね。
Powerコントロールが無いHUBでpower_offすると給電は行われたまま、ロジックがオフになり、接続されたデバイスが見えなくなるようです。
FreeBSD/mips 12-STABLE(RT3883,AR9341)でも同じように動きました。
usbconfigの今の仕様だとPer-Portをサポートできないので、こうなってしまっているのかもしれません。
大抵のHUBのチップはギャングかPer-Portをサポートしていますが、Powerコントロールが実装されていないケースが多いので、実質的に使えないのも混乱している一因です。
誰かPer-Portのサポート方法を考えてみませんか?
USBの電源でON/OFFできるタップがあるようです。ちょっとお高いようなので、秋月のSSRで自作してみたいと思っています。