メモリテクノロジドライバ (``MTD'') は、ある種のメモリデバイスでさまざま
なメモリサービスを実現するために、カードサービスが使用します。
MTD は、RegisterClient
を呼び出して、通常のカードサービスのクライアント
として登録しなければなりません。カード挿入のイベントを受け取ったら、
管理するメモリの範囲を知るために、GetFirstRegion
と GetNextRegion
を
呼び出します。そうしたら、RegisterMTD
を使ってそれらの範囲を制御し
ます。MTD の読み出し、書き込み、消去の要求は、カードサービスに
よって CS_EVENT_MTD_REQUEST
にパッケージ化され、MTD のイベントハンドラ
に渡されて処理されます。
MTD は、カードサービスからの要求を CS_EVENT_MTD_REQUEST
イベント
として受け取ります。カードサービスは、要求の内容をイベントコール
バックの引き数の mtdrequest
変数に入れて渡します。データをホストと受け
渡しする要求については、ホストのバッファのアドレスが buffer
変数
に渡されます。
mtd_request_t
構造体の定義は次のとおり:
typedef struct mtd_request_t {
u_long SrcCardOffset;
u_long DestCardOffset;
u_long TransferLength;
u_long Function;
u_long MediaID;
u_long Status;
u_long Timeout;
} mtd_request_t;
Function
の変数はビットマップで、この要求で実行される動作を示し
ています。
MTD_REQ_ACTION
MTD_REQ_ERASE
, MTD_REQ_READ
, MTD_REQ_WRITE
,
MTD_REQ_COPY
のいずれか。
MTD_REQ_NOERASE
ブロックの境界と大きさがにぴったりはまるような書込みコマンド のとき、消去が不要なことを示します。
MTD_REQ_VERIFY
書き込み確認(verify) を指定します。
MTD_REQ_READY
この要求が、前回の要求がカードが準備完了を返すまで延期された後 の再試行であることを示します。
MTD_REQ_TIMEOUT
この要求が、前回の要求が時間切れで延期された後の再試行であ ることを示します。
MTD_REQ_FIRST
この要求が、一連の要求の最初のものであることを示します。
MTD_REQ_LAST
この要求が、一連の要求の最後のものであることを示します。
MTD_REQ_KERNEL
読み書きコマンドのホストバッファが、ユーザメモリでなくカーネル メモリ中にあることを示します。
MediaID
変数は、このメモリ範囲を表わすために RegisterMTD
要求の
中で指定された値です。Status
変数は、デバイスが何らかの処理を実行中で
要求に応えることができなかったことを表わすために MTD が使います。MTD
要求は、通常は封鎖しません。要求が通常は封鎖するような場合でも、
実際には封鎖せず、エラーコードとして CS_BUSY
を返し、Status
に次のいずれかの値を設定するはずです。
訳注:「封鎖」は「block」の訳語です。「塊」の意味の「ブロック」
(「データブロック」など) との混同を避けるために使っています。
使用例:宇津宮孝一・福田晃共訳「オペレーティングシステムの概念」
(1987年・倍風館)
MTD_WAITREQ
現在実行中の別の要求の処理が正常終了した後に、要求を再試行すべき であることを示します。
MTD_WAITTIMER
timeout
変数で示される時間が経過した後に、要求を継続すべきである
ことを示します。
MTD_WAITRDY
カードが準備完了
状態になるか,あるいは timeout
変数で
示される時間が経過するか、どちらかが先に起った後に、要求を継続
すべきであることを示します。
MTD_WAITPOWER
ソケットの電源の供給に影響する何事かが起った後に、要求を再試行 すべきであることを示します。
MTD_WAITTIMER
と MTD_WAITRDY
では、Timeout
変数の値は
ミリ秒単位のタイムアウトの時間です。
MTD はカードサービスが発生する要求を処理するので、MTD のイベントハンド ラから安全に実行できるカードサービス呼び出しの種類には制限があるかも しれません。 MTD の支援関数は、MTD が必要とするかもしれないが通常のカードサービス 呼び出しを使って実現するとすると扱いにくいであろう特別なサービスを、 限定されたセットとして提供します。 Linux における PCMCIA の実装では、ほとんどのカードサービス呼び出しは MTD から安全に呼び出すことができますが、互換性のために MTD の支援 インターフェイスが含まれています。
#include "cs_types.h"
#include "cs.h"
#include "bulkmem.h"
int MTDHelperEntry(int subfunc, void *arg1, void *arg2);
int MTDHelperEntry(MTDRequestWindow, client_handle_t *handle, win_req_t *mod);
int MTDHelperEntry(MTDReleaseWindow, window_handle_t handle);
These services are identical to the standard Card Services
RequestWindow
and ReleaseWindow
calls.
int MTDHelperEntry(MTDModifyWindow, memory_handle_t handle, mtd_mod_req_t *mod);
mtd_mod_req_t
の構造体は次のとおり:
typedef struct mtd_mod_req_t {
u_long Attributes;
u_long AccessSpeed;
u_long CardOffset;
} mtd_mod_req_t;
MTDModifyWindow
は、通常の ModifyWindow
と MapMemPage
の呼出しを使うのと本質的に同じです。
Attributes
で指定できる内容は次のとおり。:
WIN_MEMORY_TYPE
WIN_MEMORY_TYPE_CM
で一般メモリを示すか、または
WIN_MEMORY_TYPE_AM
で属性メモリを示します。
WIN_USE_WAIT
コントローラがカードの MWAIT 信号を監視する必要があること を示します。
MTDModifyWindow
で設定された領域は常に使用可能であり、16 ビットの
データ幅を持ちます。
戻り値 :
CS_BAD_HANDLE
メモリハンドルが不正です。
int MTDHelperEntry(MTDSetVpp, client_handle_t client, mtd_vpp_req_t *req);
typedef struct mtd_vpp_req_t {
u_char Vpp1, Vpp2;
} mtd_vpp_req_t;
MTDSetVpp
はソケットのプログラム電圧を変更します。Vpp1
と
Vpp2
は 1/10
ボルト単位で与えられます。現在のところ、Vpp1
と Vpp2
は
常に等しくなければなりません。
戻り値 :
CS_BAD_HANDLE
クライアントハンドルが不正です。
CS_BAD_VPP
指定された Vpp が正しくないか、または Vpp1 と Vpp2 が等しくない。
int MTDHelperEntry(MTDRDYMask, client_handle_t client, mtd_rdy_req_t *req);
typedef struct mtd_rdy_req_t {
u_long Mask;
} mtd_rdy_req_t;
MTDRDYMask
は、CS_EVENT_READY_CHANGE
イベントを使用できる
ようにするかどうかを選択します。クライアントは、RegisterClient
又は
SetEventMask
のいずれかの呼出しを使って、カードサービスに対してこれらのイベントを
受け取ることを表明しておかなければなりません。Mask
引き数の
CS_EVENT_READY_CHANGE
ビットがセットされていると、イベントの変更が
できるようになります。
戻り値 :
CS_BAD_HANDLE
クライアントハンドルが不正です。