概要
(☝ ՞ਊ ՞)☝ウイーン(光学ドライブを eject)するコードを書くがために調べ物をしていて思ったことのメモである。
Linux のソースや、Multi-Media Commands (MMC) の仕様書などを読み、ざっくりした説明を与えることで、Linux はどのように光学ドライブの自動開閉機能の有無を判別しているのかをざっくりと理解し、その問題点を見出すとともに、Linux 以外の OS にも応用できる新たな手法を提案するものである。
Linux の内部については詳しくないので誤りが含まれるかもしれない。コードの書き方は本質的ではないので触れない。
はじめに
Linux において、
r = ioctl(fd, CDROM_GET_CAPABILITY, 0);
というようなコードで光学ドライブの機能(自動開閉機能の有無を含む)を取得できる。一般にこれは MMC というコマンドセットを通じて行われるようである。
- https://en.wikipedia.org/wiki/SCSI_Multimedia_Commands
- http://www.13thmonkey.org/documentation/SCSI/
MODE SENSE (10)
仕様
この ioctl
の戻り値に CDC_CLOSE_TRAY
や CDC_OPEN_TRAY
などがセットされているわけだが、実際にどの関数でセットされているのかを調べると、pcd.c の pcd_probe_capabilities
関数あるいは sr.c の get_capabilities
関数が見つかる。
これらはともに MODE SENSE (10)
コマンドの Page Code
が 2A
(hex) であるものを使っているようで、これはデバイスの機能などを取得するコマンドであるが、CDC_OPEN_TRAY
に関してはともにコマンド実行結果の同じビットを調べている。
たとえば MMC-3 (Revision 10g / November 12, 2001) の 6.3.11 にある Table 361 – CD/DVD Capabilities and Mechanical Status Page における、6 バイト目の下から 3 ビット目にあたる(0 オリジン)、Eject (Individual or Magazine)
ビットである。
MMC-3 によれば、このビットが立っていれば START STOP UNIT
コマンドの LoEj
ビット経由で Eject 可能であることが期待できる。MMC-2 (Revision 11a / August 30, 1999) の 5.5.10 における Table 137 – CD Capabilities and Mechanical Status Page でも同様である。
それらの表から抜粋するとこうである。
Byte | Bit | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
---|---|---|---|---|---|---|---|---|
6 | Loading Mechanism Type | Reserved | Eject (Individual or Magazine) | Prevent Jumper | Lock State | Lock |
また、この上位 3 ビットで占められる Loading Mechanism Type
フィールドについては次のようになる。
7 6 5 | Loading Mechanism Type |
---|---|
0 0 0 | Caddy type loading mechanism |
0 0 1 | Tray type loading mechanism |
0 1 0 | Popup type loading mechanism |
0 1 1 | Reserved |
1 0 0 | Changer with individually changeable discs |
1 0 1 | Changer using a Magazine mechanism |
1 1 0 | Reserved |
1 1 1 | Reserved |
CDC_CLOSE_TRAY
に関しては両関数でやや異なる。
pcd_probe_capabilities
関数では符号付き char
型である 6 バイト目を 6 ビットだけ右シフトした結果が 0
でなければ ioctl
の結果において CDC_CLOSE_TRAY
ビットが立つ(関数内ではできない機能にビットを立てる処理であることに注意)。つまり、上表によれば、上位 2 ビットのどちらかが非 0
である場合である。よくある旧来の光学ドライブは Tray type であろうが、その場合はクローズ不可ということになるのだが。
一方、get_capabilities
関数では、符号なし char
型である 6 バイト目を 5 ビットだけ右シフトした結果が 0
でなければ、結果として CDC_CLOSE_TRAY
ビットが立つ(関数内においては先述の処理と同様)。当該ソースコードのコメントにも記載されているが、Caddy type 以外はクローズ可能という結果になる。
前者の関数の判定はバグのように見えるがどうなのか。ただ、疑問は、これらの処理でクローズ可能性を判断するのは妥当かどうかということである。
実験
実際に調べてみると、PIONEER BD-RW BDR-206 1.56 における 当該バイト部分は 00101001
(bin) であって、Tray type であり Eject
ビットが立っており、かつ ioctl
の結果は CDC_CLOSE_TRAY
ビット、CDC_OPEN_TRAY
ビットがともに立っている。後者の実装によるものと思われる。普通のよくあるタイプなので自動開閉可能である。
また、古いノートに付けている MATSHITA UJDA740 DVD/CDRW 1.20 という古い DVD ドライブでも同様に 00101001
であるが、Linux が入っていないので ioctl
がどういう結果になるかはわからない。よくある手動でクローズするタイプである。
GET CONFIGURATION
仕様
しかしながら、この MODE SENSE (10)
コマンドによる機能の取得は MMC-4 (Revision 5a / 3 May 2004) では削除されているのである。
そこで有効なのが GET CONFIGURATION
コマンドである。これもデバイスの機能などを取得するコマンドである。このコマンドは MMC-2 Revision 7.0E で追加された模様であるので、大昔のデバイス相手には使えない。DVD の登場により、MODE SENSE (10)
による手法では今後の拡張が見込めないための登場と思われる。
GET CONFIGURATION
コマンドが使えるのであれば、実行結果のうち、Feature Code
が 0003
(hex) であるものを見ればよい。
MMC-4, MMC-5
MMC-4 の Table 75 - Feature Codes から抜粋する。
Feature Code | Feature Name | Description |
---|---|---|
0003h | Removable Medium | The medium may be removed from the device |
さて、MMC-4 の 5.3.4 Removable Medium Feature (0003h) を見ると、4 バイト目に先ほど見たものに似たものがある。Table 84 - Removable Medium Feature Descriptor Format より抜粋する。
Byte | Bit | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
---|---|---|---|---|---|---|---|---|
2 | Reserved | Version | Persistent | Current | ||||
4 | Loading Mechanism Type | Reserved | Eject | Pvnt Jmpr | Reserved | Lock |
2 バイト目の Version
フィールドは 0000
(bin) とすることになっており、Eject
ビットについては先ほどと同様の説明である。
また、Table 85 - Loading Mechanism Type を載せるが、書き方の違いはあれど先述のものと同様の内容である。
Loading Mechanism Type | Description |
---|---|
000b | Caddy/Slot type loading mechanism |
001b | Tray type loading mechanism |
010b | Pop-up type loading mechanism |
011b | Reserved |
100b | Embedded changer with individually changeable discs |
101b | Embedded changer using a magazine mechanism |
110b - 111b | Reserved |
これらは MMC-5 (Revision 4 / 24 October 2006) においても同じである。
MMC-6
では、MMC-6 (Revision 2g / 11 December 2009) を見てみると、5.3.4 Removable Medium Feature (0003h) にある Table 98 - Removable Medium Feature Descriptor Format に変更点がある。
Byte | Bit | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
---|---|---|---|---|---|---|---|---|
2 | Reserved | Version = 0010b | Persistent | Current | ||||
4 | Loading Mechanism Type | Load | Eject | Pvnt Jmpr | DBML | Lock |
Version
が 0010
(bin) になり、さらに 4 バイト目の下から 4 ビット目に Load
ビットが追加されている。また、ここでは深掘りしないが、DBML
ビットというものもある。説明によると、Load
ビットが立っていれば START STOP UNIT
コマンドの LoEj
ビット経由でロードつまりクローズ可能であることが期待できるというわけである。Eject
ビットと対をなすものが現れたのだ。
実験
PIONEER BD-RW BDR-206 1.56 の場合、Version
は 0001
であり、さらに Load
ビットが立っている。同様に Tray type であり、Eject
ビットを見ればオープン可能とのことである。また、MATSHITA UJDA740 DVD/CDRW 1.20 では、Version
は 0000
で Load
ビット部分(このバージョンにおいては Reserved
)は 0
である。これまた同様に Tray type であり、オープン可能とのことである。
疑問
前者のドライブにおける Version
が 0001
であるとは何事か。
Mt. Fuji
Mt. Fuji Commands for Multimedia Devices という、MMC のような何かがある。
詳しいことはわからないが、どうやら MMC とは切っても切り離せない関係らしい。
Version 6
Mt. Fuji Commands for Multimedia Devices Version 6 (Revision 1.0 / Final /
February 8, 2006) を見てみる。これにおける 17.4.2.4 Feature 0003h: Removable Medium を見ると、当該 descriptor 部分は MMC-5 と同様の構成である。
Version 7
Revision 0.6
Mt. Fuji Commands for Multimedia Devices Version 7 (Revision 0.6 / Draft for Review / August 1、2006) を見てみる。公開されている最初のリビジョンであろうが、特に変化がない。
Revision 0.7
次のリビジョンであろう、Mt. Fuji Commands for Multimedia Devices Version 7 (Revision 0.7 / Draft for Review / May 7, 2007) の 17.4.2.4 Feature 0003h: Removable Medium を見る。
Table 324 - Removable Medium Feature Descriptor より抜粋してみる。
Byte | Bit | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
---|---|---|---|---|---|---|---|---|
2 | Reserved | Version = 1h | Persistent | Current | ||||
4 | Loading Mechanism Type | Load | Eject | Pvnt Jmpr | Reserved | Lock |
ここで Load
ビットが追加されるとともに、Version
が 1
となったのだ。Load
ビットについては MMC-6 と同様の説明である。
Revision 1.20
やや飛ばして、Mt. Fuji Commands for Multimedia Devices Version 7 (Revision 1.20 / Final / September 24, 2009) を見る。17.4.2.4 Feature 0003h: Removable Medium において変更点がある。DBML
ビットが追加され、Version
が 2
となった。
Table 350 - Removable Medium Feature Descriptor より抜粋してみる。
Byte | Bit | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
---|---|---|---|---|---|---|---|---|
2 | Reserved | Version = 2h | Persistent | Current | ||||
4 | Loading Mechanism Type | Load | Eject | Pvnt Jmpr | DBML | Lock |
ここで MMC-6 同様の構成になっており、現時点で最新の Mt. Fuji Commands for Multimedia Devices Version 9 (Revision 1.00 / Final / October 13, 2015) まで変わりはない。
考察
以上のことから、謎の Version = 1
とは、Mt. Fuji Commands for Multimedia Devices Version 7 完成過程で登場したバージョンであり、MMC-6 においては Revision 2g が制定されるまでのどこかのリビジョンに存在しているかもしれないものであろうと考えられる。
まとめ
Removable Medium Feature Descriptor 年表
以上の出来事を時系列順に並べてみる。
年月日 | 仕様, リビジョン |
Version フィールド (dec) |
機能 |
---|---|---|---|
1997/5/6 | MMC-1, 10A | N/A | N/A |
1999/8/30 | MMC-2, 11a | 0 | - |
2001/11/12 | MMC-3, 10g | 0 | - |
2004/5/3 | MMC-4, 5a | 0 | - |
2006/8/1 | Mt. Fuji 7, 0.6 | 0 | - | 2006/10/24 | MMC-5, 4 | 0 | - |
2007/5/7 | Mt. Fuji 7, 0.7 | 1 | Load |
2009/9/24 | Mt. Fuji 7, 1.20 | 2 | Load, DBML |
2009/12/11 | MMC-6, 2g | 2 | Load, DBML |
2015/10/13 | Mt. Fuji 9, 1.00 | 2 | Load, DBML |
問題点と提案
これまでの調査から、次のことがいえよう。
- 廃止された
MODE SENSE (10)
のみに頼る現状の Linux の実装は古い。 - さらにクローズ可能性については信憑性に欠く。
-
古すぎないデバイス相手では
GET CONFIGURATION
で代用できそうである。 - それを用いて Removable Medium Feature を取得すれば、
Eject
ビットを利用できる。 - 同様に、
Load
ビットが利用可能な場合がある。 - それは
Version
が1
以上(現状では1
あるいは2
)の場合である。(後に3
などになっても後方互換性を期待してもよさそう)
このことから、光学ドライブの自動開閉機能の有無を調べるコードを改めて書く際には、次のような手法を提案したい。
-
GET CONFIGURATION
でFeature Code = 0003h
を取得する。 -
Eject
ビットが0
であればオープン不可能、1
であればオープン可能とする。 -
Version
が0
であれば、Loading Mechanism Type
によって推測する。(Linux の実装を参考に) -
Version
が1
以上(1
あるいは2
)であれば、Load
ビットを調べ、0
であればクローズ不可能、1
であればクローズ可能とする。 - 対象のデバイスが古すぎるなどのため、
GET CONFIGURATION
失敗の場合は、必要に応じてMODE SENSE (10)
のPage Code = 2Ah
による手法に切り替え、Loading Mechanism Type
により推測、およびEject
ビットの確認を行う。(あるいはそれを使用している従来の Linux のioctl
)