[b-free: 215] Device Driver Message (1/2)

青木 義彦 (PBC03033@niftyserve.or.jp)
Thu, 06 Apr 1995 15:04:00 +0900

皆さんこんにちは。

さて、次回のミーティングですが、急な仕事で10日までにドキュメントを書き上げなく
てはいけなくなってしまったので、申し訳有りませんが、欠席させて下さい。

宿題であった、メッセージフォーマットを(かなり手抜きですが)作成したので、UP
しておきます。時間がありましたら、問題点が有るかどうかを検討していただきたいと
思います。(300行越えてしまったので2分割してます)

もちろん、メールリストでのご意見でも結構です (^^;;

なお、要求メッセージ全体のフォーマットは、以前に木元さんからいただいた資料にあ
った構造体(下記参照)に準拠し、その中の arg[]の部分のみを書いてあります。

typedef struct {
ID mbfid; // 応答メッセージを送信するメッセージバッファ?
WORD msgtyp; // メッセージ識別番号
ID tskid; // メッセージを送信したタスク
WORD len; // 独自パラメタのサイズ(バイト数?配列数?)
UWORD arg[0]; // 独自パラメタ
} SVC_REQ;

デバイスの登録
struct {
ID pid; // システムコールを発行したプロセス
DEV_INFO info;
DEV_STAT stat;
};

・デバイス名の指定は「種別」のみとする。
・周辺核(ファイルマネージャ等)から要求を出す場合は、プロセスIDとして特
殊な値を指定することにします。(全てのシステムコールに共通)

デバイスの登録(の応答)
struct {
WORD errcd;
WORD devno; // デバイス番号
};

  ・正常終了した場合にはerrcdにユニット番号が返却される
”hd”という種別でデバイス登録が要求されて、0が返却されたら、そのデバ
イスは”hda”となる。
OSのブート毎にデバイス名が変わる可能性があるが、デバイス(ユニット)名
を一意にするための工夫はデバイスドライバマネージャの外部で行われることを
前提としている。
・ユニット番号は英字1文字で表現するので同じ種別のデバイスは最大26ユニッ
トまでしか登録できない。(暫定)

デバイスの再登録(今の所、実装の予定はない)
struct {
ID pid; // システムコールを発行したプロセス
TCODE dev[8]; // 置き換える(古い)デバイス名(論理デバイス名orユニット
名)
DEV_INFO info; // 新しく定義するデバイスの情報
DEV_STAT stat; // 新しく定義するデバイスの情報
};

・新しいデバイス名の指定は「種別」のみとする。
・古いデバイス名の指定は「論理デバイス名orユニット名」である。
・デバイスを排他モードでオープンしたときと同じ検査を行い、成功した場合にの
み再登録が可能。(どこからもオープンされていない状態)
・デバイスドライバの登録情報はスタック状にネストして行われるので、再登録し
たデバイスドライバを削除すれば、再登録以前の(古い)デバイスドライバが使
用されることになる。
・古いデバイス名にユニット名を指定した場合は、デバイス全体が新しいデバイス
に置き変わるが、古いデバイス名に論理デバイス名を指定した場合は、古いデバ
イス内の1つのサブユニットのみが新しく定義される。したがって、残りのサブ
ユニットは、再登録以前と変わらずにアクセスすることが可能である。
・古いデバイスドライバには、「イベント通知先変更」のメッセージが送られます

例)PCMCIAスロットにSCSIカードが接続され、そこにHDが接続される
場合は、以下の手順でデバイスドライバを登録する
(1) PCMCIAドライバを登録する。
(2) PCMCIAの1つのサブユニットに対してSCSIドライバを再登
録する。
(3) SCSIの1つのサブユニット(ID)にたいしてHDドライバを再
登録する。

上記の状態で、SCSIの未使用サブユニットに(例えば)プリンタドライバ
をさらに再登録することが可能である。
また、PCMCIAの未使用サブユニットにモデム(SIO)ドライバを再登
録することも可能である。(PCMCIAドライバのサブユニット数は、使用
される可能性のあるカードの種類分登録される事を前提としている)

この方法の欠点は、任意順序でデバイスドライバを登録できないことです。

デバイスの再登録(の応答)
struct {
WORD errcd;
WORD devno; // デバイス番号
ID mbfid; // 古いデバドラへメッセージを送信するためのメッセージバッフ

};

 ・正常終了した場合にはerrcdにユニット番号が返却される
・古いデバイスドライバへメッセージを送るかどうかは、新しいデバイスドライバ
に依存する。(古いデバイスドライバを拡張する事を前提としてこの機能を用意
するので、メッセージを送らないということは考えにくい)
・デバイスドライバ間のメッセージ通信は直接行われ、デバイスドライバマネージ
ャは関与しない。

デバイス登録解除
struct {
ID pid; // システムコールを発行したプロセス
TCODE dev[8]; // デバイス名(ユニット名)
};

・ユニット名で指定されたデバイスの登録情報を削除する。
・削除した時点でデバイスの処理待ちになっているプロセスには、エラーが返却さ
れる。
・削除した時点でデバイスをオープンしているプロセスが有った場合、強制的にク
ローズされる。ただしプロセスに対しては何の通知も行われず、そのプロセスが
デバイスドライバマネージャになんらかの要求を発行した時点でエラー(E_DD)が
返却されることになる。
・削除されたデバイスのユニット番号は欠番となり、次にデバイスが登録されても
同じユニット番号が使用されることは無い。

デバイスオープン(opn_dev)
struct {
ID pid; // システムコールを発行したプロセス
TCODE dev[8]; // デバイス名(論理デバイス名)
UWORD o_mode;
};

デバイスオープン(デバイスドライバへ送るメッセージ)
struct {
WORD dd; // デバイスドライバマネージャ管理情報
// デバイスドライバはこの値を使用せず,応答メッセージの
// 先頭に登録する
};

・デバイスドライバは必要が無ければ何の処理を行う必要もない。

デバイスオープン(デバイスドライバマネージャへの応答)
struct {
WORD dd; // デバイスドライバマネージャ管理情報
WORD errcd;
WORD errinfo; // エラー詳細情報
};

デバイスオープン(LowLibへの応答)
struct {
WORD errcd;
WORD errinfo; // エラー詳細情報
};

 ・正常終了した場合にはerrcdにデバイスディスクリプタが返却される

デバイスクローズ(cls_dev)
struct {
ID pid; // システムコールを発行したプロセス
WORD dd;
WORD eject; // イジェクト指定\
};

デバイスクローズ(デバイスドライバへ送るメッセージ)
struct {
WORD dd; // デバイスドライバマネージャ管理情報
// デバイスドライバはこの値を使用せず,応答メッセージの
// 先頭に登録する
WORD eject; // イジェクト指定\
};

デバイスクローズ(デバイスドライバマネージャへの応答)
struct {
WORD dd; // デバイスドライバマネージャ管理情報
WORD errcd;
WORD errinfo; // エラー詳細情報
};

デバイスクローズ(LowLibへの応答)
struct {
WORD errcd;
WORD errinfo; // エラー詳細情報
};

デバイスからの読み込み(rea_dev)
struct {
ID pid; // システムコールを発行したプロセス
WORD dd; // デバイスディスクリプタ
LONG start; // デバイスの先頭からの位置(物理ブロック単位)
LONG size; // 読み込む量(物理ブロック単位)
};

・LowLibは、自分の用意しているメッセージバッファのサイズ以上の要求を
発行してはいけない。(LowLib内で分割して発行する)

デバイスからの読み込み(デバイスドライバへ送るメッセージ)
struct {
WORD dd; // デバイスドライバマネージャ管理情報
// デバイスドライバはこの値を使用せず,応答メッセージの
// 先頭に登録する
LONG start; // デバイスの先頭からの位置(物理ブロック単位)
LONG size; // 書き込み量(物理ブロック単位)
};

デバイスからの読み込み(デバイスドライバマネージャへの応答)
struct {
WORD dd; // デバイスドライバマネージャ管理情報
WORD errcd;
WORD errinfo; // エラー詳細情報
WORD split; // 分割情報
LONG a_size; // 実際に読み込んだブロック数
BYTE dt[0]; // 読み込んだデータ
};

・デバイスドライバは指定されたサイズのデータを一度に読み込んでも良いし、ブ
ロック単位に分割して読み込んでもよい。分割して読み込む場合は分割情報(先
頭ブロックフラグと最終ブロックフラグ)を最初のブロックと最後のブロックに
登録する。一度に読み込む場合は、先頭ブロックフラグと最終ブロックフラグの
両方を登録する。

デバイスからの読み込み(LowLibへの応答)
struct {
WORD errcd;
WORD errinfo; // エラー詳細情報
WORD split; // 分割情報
LONG a_size; // 実際に読み込んだブロック数
BYTE dt[0]; // 読み込んだデータ
};