LoginSignup
4

More than 5 years have passed since last update.

Linux から読み解く光学ドライブの自動開閉機能有無の判別技法

Posted at

概要

(☝ ՞ਊ ՞)☝ウイーン(光学ドライブを eject)するコードを書くがために調べ物をしていて思ったことのメモである。

Linux のソースや、Multi-Media Commands (MMC) の仕様書などを読み、ざっくりした説明を与えることで、Linux はどのように光学ドライブの自動開閉機能の有無を判別しているのかをざっくりと理解し、その問題点を見出すとともに、Linux 以外の OS にも応用できる新たな手法を提案するものである。

Linux の内部については詳しくないので誤りが含まれるかもしれない。コードの書き方は本質的ではないので触れない。

はじめに

Linux において、

r = ioctl(fd, CDROM_GET_CAPABILITY, 0);

というようなコードで光学ドライブの機能(自動開閉機能の有無を含む)を取得できる。一般にこれは MMC というコマンドセットを通じて行われるようである。

MODE SENSE (10)

仕様

この ioctl の戻り値に CDC_CLOSE_TRAYCDC_OPEN_TRAY などがセットされているわけだが、実際にどの関数でセットされているのかを調べると、pcd.cpcd_probe_capabilities 関数あるいは sr.cget_capabilities 関数が見つかる。

これらはともに MODE SENSE (10) コマンドの Page Code2A (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 Code0003 (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

Version0010 (bin) になり、さらに 4 バイト目の下から 4 ビット目に Load ビットが追加されている。また、ここでは深掘りしないが、DBML ビットというものもある。説明によると、Load ビットが立っていれば START STOP UNIT コマンドの LoEj ビット経由でロードつまりクローズ可能であることが期待できるというわけである。Eject ビットと対をなすものが現れたのだ。

実験

PIONEER BD-RW BDR-206 1.56 の場合、Version0001 であり、さらに Load ビットが立っている。同様に Tray type であり、Eject ビットを見ればオープン可能とのことである。また、MATSHITA UJDA740 DVD/CDRW 1.20 では、Version0000Load ビット部分(このバージョンにおいては Reserved)は 0 である。これまた同様に Tray type であり、オープン可能とのことである。

疑問

前者のドライブにおける Version0001 であるとは何事か。

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 ビットが追加されるとともに、Version1 となったのだ。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 ビットが追加され、Version2 となった。

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

問題点と提案

これまでの調査から、次のことがいえよう。

  1. 廃止された MODE SENSE (10) のみに頼る現状の Linux の実装は古い。
  2. さらにクローズ可能性については信憑性に欠く。
  3. 古すぎないデバイス相手では GET CONFIGURATION で代用できそうである。
  4. それを用いて Removable Medium Feature を取得すれば、Eject ビットを利用できる。
  5. 同様に、Load ビットが利用可能な場合がある
  6. それは Version1 以上(現状では 1 あるいは 2)の場合である。(後に 3 などになっても後方互換性を期待してもよさそう)

このことから、光学ドライブの自動開閉機能の有無を調べるコードを改めて書く際には、次のような手法を提案したい。

  1. GET CONFIGURATIONFeature Code = 0003h を取得する。
  2. Eject ビットが 0 であればオープン不可能、1 であればオープン可能とする。
  3. Version0 であれば、Loading Mechanism Type によって推測する。(Linux の実装を参考に)
  4. Version1 以上(1 あるいは 2)であれば、Load ビットを調べ、0 であればクローズ不可能、1 であればクローズ可能とする。
  5. 対象のデバイスが古すぎるなどのため、GET CONFIGURATION 失敗の場合は、必要に応じて MODE SENSE (10)Page Code = 2Ah による手法に切り替え、Loading Mechanism Type により推測、および Eject ビットの確認を行う。(あるいはそれを使用している従来の Linux の ioctl

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4