USB型のカードリーダでB-CASカードをリセットする方法を以前紹介しましたね。
sudo service pcscd restart
ですね。
この方法はコードがとても短く簡単にリスタートできる点が良いのですが、デメリットとして/var/log/messagesに pcscdがリスタートした履歴が残らないみたいなんです。 pcscdを
cat あるいはtail /var/log/messeges |grep 'pcscd'
でログをモニターしてカードの状態をチェックしているとpcscdエラーがカードのリセット後かリセット前か解りにくい所が難点です。
USBポートの電源をOn Offする
superuser モードで echo -n "1-1.4" > /sys/bus/usb/drivers/usb/unbind といったコマンドで特定のUSBポートの電源を停止することが出来ます。 (sudoでは動かなかったな〜)
ちなみにこの方法で電源オフ後にlsusb -tで確認しようとすると 「セグメンテーション違反です」とエラーがでてアンマウントされた事が確認出来ないです。 この状態でUSBのLEDが消えて電源が落ちます。 USBファンなどをコントロールするのにも使えるかもしれませんね。 その後/sys/bus/usb/drivers/usb/bindでマウントし直すことが出来ます。
この方法の問題点は、あらかじめlsusb -tで、USB card readerが刺さっているUSBポートを確認しておく必要して指定しておく必要がある点でしょうか? lsusb -t| grep 'Class=scard' でPort番号を取り出しても良いかもしれませんが、Bus番号が機種によって違うかもしれませんので自分で環境を確認して明示した方が良いでしょうね。 Applescriptで書くとこんな感じです。
on ReflesUSBCardReader2(q)
set q to q & {USBusPort:"1-1", action:"OffOn", Logging:true, foltia:"foltia", slack:true}
(* 1-5 はBus1のPort5 後方の左から2個目のポート*)
(* 1-7 はBus1のPort7 後方の左から3個目のポート*)
(* 1-1 はBus1のPort1 前方右側1個目青ポート*)
set L to load script file (((path to home folder from user domain) as string) & "Dropbox:Scripts:module:Logs_forConsole_pub.scpt") as alias
set cmd to "ssh -t -4 root@" & q's foltia & ".local \"echo -n " & quoted form of q's USBusPort & " > "
if q's action is "OffOn" or q's action is "Off" then
try
do shell script cmd & "/sys/bus/usb/drivers/usb/unbind\""
on error
LogOnConsole({cmt:"unbind に失敗", open_:false}) of L
end try
end if
if q's action is "OffOn" then delay 3
if q's action is "OffOn" or q's action is "On" then
try
do shell script cmd & "/sys/bus/usb/drivers/usb/bind\""
on error
LogOnConsole({cmt:"bind に失敗", open_:false}) of L
end try
end if
if q's slack then
LogOnConsole({cmt:"【注意!】Restart USB Card reader", open_:false}) of L
else
LogOnConsole({cmt:"【注】Restart USB Card readerー録画終了に伴う通常動作", open_:false}) of L
end if
return {}
end ReflesUSBCardReader2
これでunbind後にbindすることでB-CASカードが強制的に抜き差しと同じ挙動が取られ再起動してくれます。 これを行うと後で
Feb 14 01:32:12 foltia pcscd: ccid_usb.c:489:WriteUSB() usb_bulk_write(001/002): No such device
Feb 14 01:32:18 foltia pcscd: ifdhandler.c:102:IFDHCreateChannelByName() failed
Feb 14 01:32:18 foltia pcscd: readerfactory.c:1050:RFInitializeReader() Open Port 200001 Failed (usb:0bda/0169:libhal:/org/freedesktop/Hal/devices/usb_device_bda_169_20070818000000000_if0)
Feb 14 01:32:18 foltia pcscd: ifdhandler.c:102:IFDHCreateChannelByName() failed
Feb 14 01:32:18 foltia pcscd: readerfactory.c:1050:RFInitializeReader() Open Port 200001 Failed (usb:0bda/0169:libusb:001)
こんな感じのpcscdログが残るので、/var/log/messegesで監視して c177やc221以外のエラーが起こったらエラー蓄積カウンターをゼロにすることで過剰な自動リセットを回避することが出来ます。 USBの差し込み口を変える毎にqのUSBusPort番号の初期値を入れ直さないといけない点が面倒といえば面倒ではありますね。
アペンディクス:MacOSでのUSB電源供給オンオフ
これはfoltiaとは関係ありませんが、MacOSでUSB電源のOnOffを行う事は出来るでしょうか? これはたとえはSSD型のハードディスクが熱暴走してファインダーからアンマウントされることがあったときにそれを自動的にリセットして再マウントさせるといった目的に使うのですが、結論から言うと無理でした。
まずマックだと
echo -n "1-1.4" > /sys/bus/usb/drivers/usb/unbind
が使えないです。
単純な電源供給をしているUSBポートなら可能ですが、データーアクセス(ハングしていても)中のUSBデバイスのポートの電源を切ることは出来ないみたいです。 でもまあ一部使える機能もあるのでここで余談としてログを残しておきましょう。
MacOSでlsusbはどこ?
これですね ioreg -p IOUSB -l -w 0 でUSBの情報が見えます。 でもこれではUSBの電源のコントロールは出来ないです。 その代わりにuhubctlというコマンドを探してみましょう。 デフォルトではセットされていないので MacPortで uhubctl @2.5.0 (sysutils) などをインストールして見ましょうか?
これのポイントはこのコマンドでコントロール出来るのは対応したUSB-hubだけと言う事ですかね? 最近のIOやElecomのUSB-hubは対応してました。
mickey-happygolucky.hatenablog.com
先ずuhubctl でオプション無しでタイプするとリストが戻って来ます。 例えばこんな感じ
Current status for hub 0-5 [2109:0813 VIA Labs, Inc. USB3.0 Hub, USB 3.00, 4 ports, ppps]
Port 1: 02a0 power 5gbps Rx.Detect
Port 2: 02a0 power 5gbps Rx.Detect
Port 3: 0203 power 5gbps U0 enable connect [13fd:3456 sage 3639S 2222222222222222005B]
Port 4: 02a0 power 5gbps Rx.Detect
ハブ番号0-5の port 3番にハードがつながってるみたいです。
uhubctl -l 0-5 -p 3 -a 0 で電源が消え
uhubctl -l 0-5 -p 3 -a 1 で電源がつく
こんな感じですかね。
でも実際にFanや充電などの電源を落とすのは可能なのですが、ハード上のエラーでハングしているSSDなどの電源を落とすのは無理そうでしたわ。 まあ仕方ないので放熱対策した方がむしろ現実的だなw。