次のページ 前のページ 目次へ

3. カードサービス関数解説

カードサービスは一般に次の形で呼びます。:

#include "cs_types.h"
#include "cs.h"

int CardServices(int subfunc, void *arg1, void *arg2, ...);

いくつかのカードサービス関数は #include 文を追加する必要があります。 特殊な下位の関数は引数の数を認識します。CS_SUCCESS の戻り値は呼出が 成功した事を示しています。その他の戻り値は失敗を示しています。

3.1 クライアント管理関数

カードサービス関数を使うデバイスドライバを``クライアント''と呼びます。 デバイスドライバは他のサービスを使用する前に RegisterClient を呼び出 してクライアントハンドルを取得しなければいけません。カードを抜く前に ドライバを DeregisterClient を使用して抹消する必要があります。

RegisterClient

int CardServices(RegisterClient, client_handle_t *client, client_reg_t *reg);
client_reg_t データ構造体の定義は次のとおり:
typedef struct client_reg_t {
        dev_info_t              *dev_info;
        u_long                  Attributes;
        u_long                  EventMask;
        int                     (*event_handler)(event_t event, int priority,
                                                event_callback_args_t *args);
        event_callback_args_t   event_callback_args;
        u_long                  Version;
} client_reg_t;

RegisterClient はクライアントドライバとカードサービスの結合を確立し クライアントに適切なソケットを接続します。 dev_info パラメタはソケットと関数をクライアントに合わせるのに カードサービスが使います。この対応を BindDevice を呼ぶ事を通して ドライバサービスによって確立します。対応が確立したら、クライアント ハンドルが client に返ります。

次のフラグが属性に指定できます。:

INFO_MASTER_CLIENT

ドライバサービスクライアントだけが使用します。他に、ソケットから カードを抜いた時はクライアントが自動でなく解放しなければいけませ ん。

INFO_IO_CLIENT

クライアントが入出力カードドライバの場合に指定します。

INFO_MEM_CLIENT

クライアントがメモリテクノロジドライバの場合に指定します。

INFO_MEM_CLIENT

クライアントがメモリカードドライバの場合に指定します。

INFO_CARD_SHARE

互換性の為に入っています。何もしません。

INFO_CARD_EXCL

互換性の為に入っています。何もしません。

EventMask はクライアントに何が起こっているか通知する時に指定します。 event_handler の項目は EventMask で処理されるとカードサービス によって 呼ばれます。event_handler_args 構造体はイベントハンドラに渡される 構造体の雛型 (テンプレートr) です。Version パラメタはこのドライバが 要求するカードサービスのバージョンレベルを示します。これは現在無視 されます。

ドライバが RegisterClient を呼び出す前にカードサービスを扱う準備を 行なう必要があります。この呼び出しはいつも CS_REGISTRATION_COMPLETE イベントを生成し、ソケットが現在使用している場合は、わざと CS_CARD_INSERTION イベントを生成します。

戻り値 :

CS_OUT_OF_RESOURCE

ドライバに必要な適切なドライバが見つかりません。

DeregisterClient

int CardServices(DeregisterClient, client_handle_t client);

DeregisterClient はクライアントとカードサービスの連結を行ないます。 クライアントが割り当てられたリソースを解放した後で呼びます。 連結が切れたら、BindDevice を他のクライアントが呼ぶまで再確立出来ま せん。

戻り値 :

CS_BAD_HANDLE

クライアントハンドルが無効です。

CS_IN_USE

クライアントに入出力ポート領域や割り込みなどのリソースが 割り当てられているかソケット構成がロックされています。

SetEventMask

int CardServices(SetEventMask, client_handle_t client, eventmask_t *mask);
eventmask_t 構造体の定義は次のとおり:
typedef struct eventmask_t {
        u_long          Attributes;
        u_long          EventMask;
} eventmask_t;

SetEventMask はクライアントに通知されたイベントを認識するようにマスクを 更新します。

戻り値 :

CS_BAD_HANDLE

クライアントハンドルが無効です。

BindDevice

int CardServices(BindDevice, bind_req_t *req);
bind_req 構造体の定義は次のとおり:
typedef struct bind_req_t {
        socket_t        Socket;
        u_char          Function;
        dev_info_t      *dev_info;
} bind_req_t;

BindDevice でデバイスドライバと適切なソケットを関係づけます。通常、 新規に挿入されたカードが認識できた後でデバイスサービスから呼ばれます。 一旦、ドライバがソケットと接続されると、そのソケットのクライアントと としてドライバを登録するのに適格でしょう。この呼び出しは引数がクライ アントハンドルではないことに注意して下さい。カードサービス呼び出しだ けはソケット番号を引数に用いています。

Function 変数はドライバに結合したい多機能カードのうちの機能 (複数可 ) を指定します。Function 番号はカードの CISTPL_LONGLINK_MFC タプル に相当します。Function を BIND_FN_ALL に設定した場合は、ドライバは カードの全ての機能を接続します。ドライバは CIS タプルに相当する機能 に接続する事だけが可能です。

戻り値 :

CS_BAD_SOCKET

指定したソケット番号は無効です。

3.2 ソケット状態管理

これらの関数は多かれ少なかれ現在のソケットの状態の獲得と設定に関与して います。GetStatus は現在のソケット状態を返します。ResetCard はハード リセット信号をソケットに送ります。SuspendCardResumeCard は電源オフ と電源オンを現在接続しているドライバを切り離す事なしに行ないます。 EjectCardInsertCard は本質的に実際にカードの排出と挿入 イベントを真似します。

GetStatus

int CardServices(GetStatus, client_handle_t client, status_t *status);
status_t データ構造体の定義は次のとおり:
typedef struct status_t {
        u_char          Function;
        u_long          CardState;
        u_long          SocketState;
} status_t;

GetStatus はクライアントのソケットの現在の状態を返します。入出力モード に設定されているカードでは、GetStatus はピン代替レジスタと拡張状態 レジスタをカード状態を認識するのに使っています。通常のクライアントには Function 変数は無視されますが、 BIND_FN_ALL を指定している クライアントではこの変数で指定した機能の構成レジスタでソケット状態を 決定するのに使用します。 CardState には次のフラグを定義しています。:

CS_EVENT_CARD_DETECT

指定したソケットを使用します。

CS_EVENT_WRITE_PROTECT

指定したカードを書き込み禁止にしました。

CS_EVENT_BATTERY_LOW

指定したカードの電池が不足しました。

CS_EVENT_BATTERY_DEAD

指定したカードは電池切れです。

CS_EVENT_READY_CHANGE

指定したカードは準備完了です。

CS_EVENT_PM_SUSPEND

指定したソケットは停止しました。

CS_EVENT_REQUEST_ATTENTION

指定した拡張状態レジスタ内の要求命令ビットを設定しました。

SocketState は現在使われていませんが、原則的には CardState の状態変数の中に組み込まれていくでしょう。

戻り値 :

CS_BAD_HANDLE

クライアントハンドルは無効です。

ResetCard

int CardServices(ResetCard, client_handle_t client);

ResetCard はクライアントのソケットのリセットを要求します。この呼び出し が発生した時、カードサービスは全てのクライアントに CS_EVENT_RESET_REQUEST イベントを送ります。クライアントがこの要求を拒否した場合は、カードサービス クライアントを初期化する為に CS_EVENT_RESET_COMPLETE イベントを event_callback_args.info にクライアントの要求拒否の返り値を設定して クライアントに送ります。

全てのクライアントがこの要求に同意すると、カードサービスは CS_EVENT_RESET_PHYSICAL イベントを送り、ソケットをリセットします。 ソケット信号が準備完了になると、CS_EVENT_CARD_RESET イベントを 生成します。最後に CS_EVENT_RESET_COMPLETE イベントを event_callback_args.info にゼロを設定して初期化するクライアントに 送ります。

戻り値 :

CS_BAD_HANDLE

クライアントハンドルは無効です。

CS_NO_CARD

クライアントに割り付けたソケットは現在使われていません。

CS_IN_USE

ソケットは現在リセットしています。

SuspendCard

int CardServices(SuspendCard, client_handle_t client);

カードサービスは全てのクライアントに CS_EVENT_PM_SUSPEND イベントを 送ります。ソケットをシャットダウンと電源オフさせます。

戻り値 :

CS_BAD_HANDLE

クライアントハンドルは無効です。

CS_NO_CARD

クライアントに割り付けたソケットは現在使われていません。

CS_IN_USE

ソケットは既に中止しています。

ResumeCard

int CardServices(ResumeCard, client_handle_t client);

ソケットが電源オフした後、カードサービスは全てのクライアントに CS_EVENT_PM_RESUME イベントを送ります。

戻り値 :

CS_BAD_HANDLE

クライアントハンドルは無効です。

CS_NO_CARD

クライアントに割り付けたソケットは現在使われていません。

CS_IN_USE

ソケットは既に中止しています。

EjectCard

int CardServices(EjectCard, client_handle_t client);

カードサービスは全てのクライアントに 排出 (イジェクト) イベントを 送ります。ソケットをシャットダウンと電源オフさせます。全てのクライアント がドライバサービスがソケットを切り離す為にイベントを受け取ります。

戻り値 :

CS_BAD_HANDLE

クライアントハンドルは無効です。

CS_NO_CARD

クライアントに割り付けたソケットは現在使われていません。

InsertCard

int CardServices(InsertCard, client_handle_t client);

カードサービスは挿入イベントを全てのソケットのクライアントに送ります。 (通常、ドライバサービス限定です)

戻り値 :

CS_BAD_HANDLE

クライアントハンドルは無効です。

CS_NO_CARD

クライアントに割り付けたソケットは現在使われていません。

CS_IN_USE

ソケットは既に設定しています。

3.3 入出力カードの設定関数

普通のイベントの順番はドライバ用に入出力ポートと RequestIORequestIR を呼び出して割り込み線を予約します。そして、 RequestConfiguration を呼び出して実際のソケットを設定します。 これらの呼び出しに失敗したら、うまく予約ができるようにリソースを 解放するようにドライバを確認して下さい。

多機能カードはそれぞれの機能を分離して設定しましょう。しかしながら 他の機能と調和している必要があります。それぞれのカード機能はその自身の レジスタのセットを持ち、それぞれのソケットは一つの割り込み線と二つの 連続した入出力ポート番号を割り当てます。

RequestIO

int CardServices(RequestIO, client_handle_t client, io_req_t *req);
io_req_t 構造体の定義は次のとおり:
typedef struct io_req_t {
        ioaddr_t        BasePort1;
        ioaddr_t        NumPorts1;
        u_long          Attributes1;
        ioaddr_t        BasePort2;
        ioaddr_t        NumPorts2;
        u_long          Attributes2;
        u_long          IOAddrLines;
} io_req_t;

RequestIO はカード用入出力領域を予約します。BasePort1 がゼロでない 場合は、予約する領域の入出力ポートアドレスです。ゼロの場合は、 カードサービスが利用できる領域をみつけて、BasePort1 にそのアドレス を設定することです。NumPorts2 がゼロでない場合は、2番目の入出力ポート 領域も予約します。IOAddrLines は PCMCIA カードで実際にデコードする アドレス線の数を指定します。これは現在使われていません。

多機能カードではこの呼び出しでそれぞれの物理ポートに対応する 2 つ の低層入出力領域を割り付けそれぞれのカード機能に対応した全てのポート に入出力ポートを割り当てます。例えば、仮に4機能カードの場合 8 ポートを 所有する1つの入出力領域をドライバは割り当て、カードサービスは 1 つの 連続した 32-ポートブロックに統合します。

この呼び出しは実際のソケットの入出力領域を設定するものではありません。 続いて RequestConfiguration を呼び出して設定して下さい。

次のフラグは Attributes1Attributes2 に指定します。:

IO_DATA_PATH_WIDTH

この変数は 16 ビットアクセス用の IO_DATA_PATH_WIDTH_16 もしくは 8 ビットアクセス用の IO_DATA_PATH_WIDTH_8 もしくは アクセスするバスの大きさに合わせた動的な領域の大きさを決める IO_DATA_PATH_WIDTH_AUTO のどちらか一方に設定します。

戻り値 :

CS_BAD_HANDLE

クライアントハンドルは無効です。

CS_NO_CARD

クライアントに割り付けたソケットは現在使われていません。

CS_IN_USE

ソケットの入出力領域は既に予約されています。

CS_CONFIGURATION_LOCKED

ソケットの構成は RequestConfiguration によってロックされています。

CS_BAD_ATTRIBUTE

サポートしていない属性フラグが指定されました。

ReleaseIO

int CardServices(ReleaseIO, client_handle_t client, io_req_t *req);

ReleaseIORequestIO が呼ばれる前に割り当てられていた入出力ポート 領域を解放します。req 変数は RequestIO にそのまま渡します。 いくつかのカードの機能が大きな入出力ポート領域を共有している場合、 一つの機能がポートを解放しても全てのカードの機能が入出力ポートを 解放するまでは他が使っているポートを使えなくしてしまってはいけません。

戻り値 :

CS_BAD_HANDLE

クライアントハンドルは無効です。

CS_CONFIGURATION_LOCKED

ソケットの構成は RequestConfiguration によってロックされてい ます。その構成は ReleaseIO を呼ぶ前に解放されています。

CS_BAD_ARGS

req に入っている変数が RequestIO に渡されたものと一致してい ません。

RequestIRQ

int CardServices(RequestIRQ, client_handle_t client, irq_req_t *req);
irq_req_t 構造体の定義は次のとおり:
typedef struct irq_req_t {
        u_long          Attributes;
        u_long          AssignedIRQ;
        u_long          IRQInfo1, IRQInfo2;
        void            *(Handler)(int, struct pt_regs *);
        void            *Instance
} irq_req_t;

RequestIRQ は PCMCIA カードが使用する割り込み線を予約します。 IRQInfo1IRQInfo2 変数は CFTABLE_ENTRY タプル内の 割り込み記述語 と一致しています。IRQ_INFO2_VALIDIRQInfo1 に設定して いるならば IRQInfo2 を割り込みの数値を考慮したビットマップマスクを設定しましょ う。それぞれのビットは一つの割り込み線と一致しています。例えば ビット 0 は割り込み 0 、ビット 1 は割り込み 1 などです。従って、 0x1100 というマスクは割り込み 12 と割り込み 8 を使う事を意味してい ます。IRQ_INFO2_VALID を設定していない場合は、IRQInfo1 は割り込み 番号を指定する必要があります。この呼び出しが成功した時は、AssignedIRQ に予約された割り込み番号が返ってきます。

IRQ_HANDLER_PRESENT フラグを設定すると、その時この呼び出しが 割り込みが有効になっている時に割り込みハンドラを導入することを 示しています。RequestConfiguration が呼ばれた時、Handler で指定した割り込みハンドラが導入されます。カーネル 2.0 以降では 割り込みハンドラは Instance で与えられる ``実体'' の ドライバと共に導入されます。カーネル 2.1.60 以前では、 カーネルの irq2dev_map テーブルも更新するでしょう。 多機能カードでは、割り込みは共有モードで 割り当てられ、ハンドラは割り込みを受け取った時カードに機能を認識さ せる役割を負います。クライアントがカードサービスを迂回する為に 独自の割り込みサービスルーチンを導入する場合は、クライアントが 多機能カードと結合するには共有モードで割り当てましょう。

Attributes で指定できるフラグは次のとおり:

IRQ_FORCED_PULSE

指定する割り込みは標準のレベルモードよりはパルスモードで設定 しましょう。

IRQ_TYPE_TIME

指定する割り込みは他のカードサービスドライバで時分割で行ない ましょう。一つのドライバではいつでも割り込み可能になります。

IRQ_FIRST_SHARED

IRQ_TYPE_TIME と組み合わせて、最初のドライバを共有割り込みする ように設定します。

IRQ_HANDLER_PRESENT

Handler 変数が導入済みの割り込みサービスルーチンを指すようにし ます。

戻り値 :

CS_BAD_HANDLE

クライアントハンドルは無効です。

CS_NO_CARD

クライアントに割り付けたソケットは現在使われていません。

CS_IN_USE

ソケットの入出力領域は既に予約されているか、要求した割り込みは 使用できません。

CS_CONFIGURATION_LOCKED

ソケットの構成は RequestConfiguration によってロックされています。

CS_BAD_ATTRIBUTE

サポートしていない属性フラグが指定されました。

ReleaseIRQ

int CardServices(ReleaseIRQ, client_handle_t client, irq_req_t *req);

ReleaseIRQ はそれ以前に割り当てられている割り込みの予約解除をします。 req 構造体は RequestIRQ に渡される構造体と同じものです。ハンドラを RequestIRQ 呼び出しで指定した場合は、この時点で登録解除されます。

戻り値 :

CS_BAD_HANDLE

クライアントハンドルは無効です。

CS_CONFIGURATION_LOCKED

ソケットの構成は RequestConfiguration によってロックされてい ます。構成は ReleaseIRQ が呼ばれる前に解除されています。

CS_BAD_IRQ

req で指定したパラメータが RequestIRQ に渡されていたものと 一致していません。

RequestConfiguration

int CardServices(RequestConfiguration, client_handle_t client, config_req_t *req);
config_req_t 構造体の定義は次のとおり:
typedef struct config_req_t {
        u_long          Attributes;
        u_long          Vcc, Vpp1, Vpp2;
        u_long          IntType;
        caddr_t         ConfigBase;
        u_char          Status, Pin, Copy, ExtStatus;
        u_char          ConfigIndex;
        u_long          Present;
} config_req_t;

RequestConfiguration は実際にソケットの構成を行ないます。これは電圧の 設定、 CIS 構成レジスタの設定、入出力ポート領域の設定、割り込みの設定 を行ないます。

IntType は使用するカードのインターフェースの型を指定します。 その型は INT_MEMORY または INT_MEMORY_AND_IO のいずれかを 指定します。 Voltages は 1/10 ボルトの単位で指定します。現在は、Vpp1Vpp2 は同じである必要があります.

多機能カードではそれぞれのカード機能は別々に構成します。それぞれの 機能は CIS 構成レジスタの組み合わせで行ないます。しかしながら、 全ての機能は同じ電源とインタフェースで構成しなければいけません。

次のフラグは Attributes で指定するものです。DMA とスピーカ制御は全て のシステムでサポートはしていません。

CONF_ENABLE_IRQ

RequestIRQ 以前を入出力割り込みを予約可能にします。

CONF_ENABLE_DMA

ソケット用に DMA アクセスを有効にします。

CONF_ENABLE_SPKR

ソケットからスピーカ出力を有効にします。

Present 変数はカードに実装している CIS 構成レジスタで指定するビット マップです。ConfigBase は属性メモリ内の構成レジスタのオフセットで 与えます。次のレジスタで指定します。:

PRESENT_OPTION

現在の構成オプションレジスタ(COR) を指定します。 COR レジスタは ConfigIndex 変数を使って指定します。

PRESENT_STATUS

現在のカード構成(CC) と 状態レジスタ(SR) を指定します。 CCSR は Status 変数で初期化します。

PRESENT_PIN_REPLACE

現在のピン代替レジスタ(PRR) を指定します。PRR は Pin 変数で 初期化します。

PRESENT_COPY

現在のソケット(S) とコピーレジスタ(CR) を指定します。SCR は Copy 変数で初期化します。

PRESENT_EXT_STATUS

現在の拡張状態レジスタ(ESR) を指定します。ESR は ExtStatus 変数で初期化します。

戻り値 :

CS_BAD_HANDLE

クライアントハンドルは無効です。

CS_NO_CARD

クライアントに割り付けたソケットは現在使われていません。

CS_OUT_OF_RESOURCE

カードサービスはカードの構成レジスタにアクセスするメモリ領域 が割り当てできません。

CS_CONFIGURATION_LOCKED

カードの構成は RequestConfiguration によってロックされています。

CS_BAD_VCC

要求された Vcc 電圧はサポートしていません。

CS_BAD_VPP

要求された Vpp1/Vpp2 電圧はサポートしていません。

ModifyConfiguration

int CardServices(ModifyConfiguration, client_handle_t client, modconf_t *mod);
modconf_t 構造体の定義は次のとおり:
typedef struct modconf_t {
        u_long          Attributes;
        u_long          Vcc, Vpp1, Vpp2;
} modconf_t;

ModifyConfigurationRequestConfiguration を呼び出して設定した ソケットの属性を変更します。

Attributes で指定できるフラグは次のとおり:

CONF_IRQ_CHANGE_VALID

CONF_ENABLE_IRQ の設定を変更する事を表しています。

CONF_ENABLE_IRQ

ソケットに有効になっている入出力割り込みを指定します。

CONF_VCC_CHANGE_VALID

Vcc を変更することを表しています。

CONF_VPP1_CHANGE_VALID

Vpp1 を変更することを表しています。

CONF_VPP2_CHANGE_VALID

Vpp2 を変更することを表しています。

現在、Vpp1 と Vpp2 は常に同じ値でなければいけません。従って、2つの 値は同時に変更する必要があります。

戻り値 :

CS_BAD_HANDLE

クライアントハンドルは無効です。

CS_NO_CARD

クライアントに割り付けたソケットは現在使われていません。

CS_CONFIGURATION_LOCKED

実際には、ソケットはロックされていません

CS_BAD_VCC

要求された Vcc 電圧はサポートしていません。

CS_BAD_VPP

要求された Vpp1/Vpp2 電圧はサポートしていません。

ReleaseConfiguration

int CardServices(ReleaseConfiguration, client_handle_t client, config_req_t *req);

ReleaseConfiguration はそれ以前に設定されている構成の解除をします。 req 構造体は ソケットを設定するときと同じものです。

戻り値 :

CS_BAD_HANDLE

クライアントハンドルが無効か、ソケットが設定されていません。

GetConfigurationInfo

int CardServices(GetConfigurationInfo, client_handle_t client, config_info_t *config);
config_info_t 構造体の定義は次のとおり:
typedef struct config_info_t {
        u_char          Function;
        u_long          Attributes;
        u_long          Vcc, Vpp1, Vpp2;
        u_long          IntType;
        caddr_t         ConfigBase;
        u_char          Status, Pin, Copy, Option, ExtStatus;
        u_long          Present;
        u_long          AssignedIRQ;
        u_long          IRQAttributes;
        ioaddr_t        BasePort1;
        ioaddr_t        NumPorts1;
        u_long          Attributes1;
        ioaddr_t        BasePort2;
        ioaddr_t        NumPorts2;
        u_long          Attributes2;
        u_long          IOAddrLines;
} config_info_t;

GetConfigurationInfoRequestIO, RequestIRQRequestConfiguration で設定した現在のソケットの構成を返します。完全に構成したソケットに対 して適応してください。単機能のカードに結合しているクライアントでは、 Function 変数は無視され、クライアントが指定している機能のデータを返し ます。BIND_FN_ALL と結合しているクライアントではこの変数は指定した 関数の構成データを返します。

戻り値 :

CS_BAD_HANDLE

クライアントハンドルが無効か、ソケットが設定されていません。

CS_NO_CARD

クライアントに割り付けたソケットは現在使われていません。

CS_CONFIGURATION_LOCKED

実際には、ソケットはロックされていません

3.4 カード情報構造体 (CIS) 使用法

カード情報構造体 (CIS) は PCMCIA 標準の中で最も分かりにくいところです。 全ての第 2 版の PCMCIA カードはここでどう設定するか説明する CIS を持っ ています。CIS はカードの属性メモリ空間の中の``タプル (tuples)''の連結 リストです。タプルは識別コード、データ長と一連のデータからなります。 いくつかのタプルでのデータの配置はことごとく全てのビットを使うような 明らかな努力を必要とするほど、かなり複雑です。

ValidateCIS 呼び出しは正当な CIS を使っているカードかどうか調べます。 GetFirstTupleGetNextTuple 呼び出しは CIS タプルリストを移動する 方法です。GetTupleData はタプルからデータを取り出します。そして ParseTuple は特に重要な限られた数のタプルを解釈します。

GetFirstTuple, GetNextTuple

#include "cistpl.h"

int CardServices(GetFirstTuple, client_handle_t client, tuple_t *tuple);
int CardServices(GetNextTuple, client_handle_t client, tuple_t *tuple);
tuple_t データ構造体の定義は次のとおり:
typedef struct tuple_t {
        u_long          Attributes;
        cis_data_t      DesiredTuple;
        u_long          Flags;
        cisdata_t       TupleCode;
        u_long          TupleLink;
        cisdata_t       TupleOffset;
        cisdata_t       TupleDataMax;
        cisdata_t       TupleDataLen;
        cisdata_t       *TupleData;
} tuple_t;

GetFirstTupleDesiredTuple に一致する最初のタプルコード をカードの CIS から探します。特別な RETURN_FIRST_TUPLE コードはどんな種類の タプルに一致します。TupleCode を最初に一致したタプルのコードに設定 します。TupleLink は属性メモリ内のタプルのアドレスです。

GetNextTuple は事前に実行した GetFirstTuple が返す tuple_t 構造体 を与えることを除いて GetFirstTuple に似ています。 また、GetNextTuple は次に一致させたいタプルを DesiredTuple に返します。

これらの関数は自動的に CIS 内のリンクタプルを全て手繰って調査します。 多機能カードでは CISTPL_LONGLINK_MFC タプルを持っているのは、これらの 関数がクライアントドライバの指している機能を指定した CIS だけを自動的 に追跡できるようにするためです。クライアントが BIND_FN_ALL を結合して いる場合は、全てのタプルが返るでしょう。

Attributes で指定できるフラグは次のとおり:

TUPLE_RETURN_LINK

リンクタプル (CISTPL_LONGLINK_A, CISTPL_LONGLINK_C, CISTPL_LONGLINK_MFC, CISTPL_NOLINK, CISTPL_LINKTARGET) を返すことを表しています。 普通はこれらのタプルは暗黙のうちに処理されます。

TUPLE_RETURN_COMMON

多機能 CIS の``共有'' CIS セクションのタプルを返すことを表しています。 このフラグがない時は通常、カードサービスはクライアントに結合させる 機能を表すタプルを返します.

戻り値 :

CS_BAD_HANDLE

クライアントハンドルが無効です。

CS_OUT_OF_RESOURCE

カードサービスはメモリ領域をカードの CIS に割り付けできません でした。

CS_NO_MORE_ITEMS

DesiredTuple に一致するタプルはありません。

GetTupleData

#include "cistpl.h"

int CardServices(GetTupleData, client_handle_t client, tuple_t *tuple);

GetTupleData は一連のデータを事前に呼んだ GetFirstTuple または GetNextTuple の返してきた指定されたタプルから取り出します。 TupleDataMax の最大長は TupleData バッファにコピーされて、 TupleOffset のオフセットから始まります。コピーされたバイト数は TupleDataLen に 入っています。

戻り値 :

CS_BAD_HANDLE

クライアントハンドルが無効です。

CS_OUT_OF_RESOURCE

カードサービスはメモリ領域をカードの CIS に割り付けできません でした。

CS_NO_MORE_ITEMS

タプルには何もデータが格納されていません。TuppleOffset は タプルの長さと等しいかより大きいです。

ParseTuple

#include "cistpl.h"

int CardServices(ParseTuple, client_handle_t client, tuple_t *tuple, cisparse_t *parse);
cisparse_t データ 構造体は次のとおり:
typedef union cisparse_t {
        cistpl_device_t         device;
        cistpl_checksum_t       checksum;
        cistpl_longlink_t       longlink;
        cistpl_longlink_mfc_t   longlink_mfc;
        cistpl_vers_1_t         version_1;
        cistpl_altstr_t         altstr;
        cistpl_jedec_t          jedec;
        cistpl_manfid_t         manfid;
        cistpl_funcid_t         funcid;
        cistpl_config_t         config;
        cistpl_cftable_entry_t  cftable_entry;
        cistpl_device_geo_t     device_geo;
        cistpl_vers_2_t         version_2;
        cistpl_org_t            org;
} cisparse_t;

ParseTuple は事前に呼んだ GetTupleData が返してきたタプルのデータを 解釈します。返ってきた構造体は解析したタプルの型に依存します。 これらの構造体の定義は cistpl.h ファイルを参照して下さい。 そのうちのいくつかは大変複雑なものです。

戻り値 :

CS_BAD_TUPLE

タプルの解析中にエラーが発生しました。タプルが不完全か、 書式が正しくありません。

CS_UNSUPPORTED_FUNCTION

ParseTuple が指定されたタプルの型を解析できません。

ValidateCIS

int CardServices(ValidateCIS, client_handle_t client, cisinfo_t *cisinfo);
cisinfo_t 構造体は次のとおり:
typedef struct cisinfo_t {
        u_long          Chains;
} cisinfo_t;

ValidateCIS はカードが妥当なカード情報構造体(CIS) を持っているか検証し ます。Chains に見つかったタプルの数が返ってきます。CIS が解釈不能だと 思えたら、Chains を 0 に設定します。

戻り値 :

CS_BAD_HANDLE

クライアントハンドルが無効です。

CS_OUT_OF_RESOURCE

カードサービスはメモリ領域をカードの CIS に割り付けできません でした。

3.5 メモリ領域制御

それぞれのソケットは4つ以上のメモリ領域を持て、PCMCIA メモリの一部を ホストのアドレス空間に割り付けます。PCMCIA 機器は一般メモリと属性 メモリの両方に 16MB 程度アクセスできます。領域は一般に 2 のべき乗の 大きさをしていますが、ホストとカードのアドレス空間では領域の大きさの 倍数に境界調整しています。

メモリ領域は RequestWindow を呼び出して初期化します。いくつかの 領域属性は ModifyWindow を使用して変更を行ないます。領域に割り付け られたカードメモリの一部は MapMemPage を使用して変更します。 領域は ReleaseWindow で解放します。他のカードサービス関数とは異なっ て、client_handle_t ハンドルでなく window_handle_t ハンドルで 動作します。

RequestWindow

int CardServices(RequestWindow, client_handle_t *handle, win_req_t *req);
win_req_t 構造体は次のとおり:
typedef struct win_req_t {
        u_long          Attributes;
        caddr_t         Base;
        u_long          Size;
        u_long          AccessSpeed;
} win_req_t;

RequestWindow はカードメモリの領域をシステムメモリへ割り当てます。 呼ぶ前に、handle 変数が有効なクライアントハンドルを指すようにします。 返ってきたら、この後呼ばれる ModifyWindowMapMemPageReleaseWindow で使用する window_handle_t ハンドルで置き換えられます。

Attributes で指定できるフラグは次のとおり:

WIN_MEMORY_TYPE

この変数は一般メモリでは WIN_MEMORY_TYPE_CM 、属性メモリでは WIN_MEMORY_TYPE_AM のいずれかになります。

WIN_DATA_WIDTH

16 ビットアクセスでは WIN_DATA_WIDTH_16 、8 ビットアクセス なら WIN_DATA_WIDTH_8 のいずれかになります。

WIN_ENABLE

これを設定すると、領域が使用可能になります。

WIN_USE_WAIT

制御装置がカードの MWAIT 信号を監視するように指定します。

Base はシステムメモリでの領域の基底アドレスを指定します。NULL の場合 は、カードサービスは最初に見つかった利用可能な領域のアドレスを設定し ます。Size は領域の大きさをバイト単位で指定します。AccessSpeed は メモリアクセススピードをナノ秒単位で指定します。

戻り値 :

CS_BAD_HANDLE

クライアントハンドルが無効です。

CS_NO_CARD

クライアントに割り付けたソケットは現在使われていません。

CS_BAD_ATTRIBUTE

サポートしていない領域の属性が指定されました。

CS_OUT_OF_RESOURCE

そのソケットに対するメモリ領域の最大数は使用済みです。

CS_IN_USE

RequestWindow はシステムメモリのあき領域が見つけられません。

ModifyWindow

int CardServices(ModifyWindow, window_handle_t, modwin_t *);
modwin_t 構造体は次のとおり:
typedef struct modwin_t {
        u_long          Attributes;
        u_long          AccessSpeed;
} modwin_t;

ModifyWindow は事前に呼んだ RequestWindow から返ってきた領域ハンドル の属性を変更します。変更できる属性は次のとおり:

WIN_MEMORY_TYPE

この変数は一般メモリでは WIN_MEMORY_TYPE_CM 、属性メモリでは WIN_MEMORY_TYPE_AM のいずれかになります。

WIN_DATA_WIDTH

16 ビットアクセスでは WIN_DATA_WIDTH_16 、8 ビットアクセス なら WIN_DATA_WIDTH_8 のいずれかになります。

WIN_ENABLE

これを設定すると、領域が使用可能になります。

AccessSpeed はメモリアクセススピードをナノ秒単位で指定します。

戻り値 :

CS_BAD_HANDLE

領域ハンドルは無効です。

MapMemPage

int CardServices(MapMemPage, window_handle_t, memreq_t *);
memreq_t 構造体は次のとおり:
typedef struct memreq_t {
        u_long          CardOffset;
        page_t          Page;
} memreq_t;

MapMemPageCardOffset で割り付けたメモリ領域の基底 アドレスをカード メモリのアドレスに設定します。領域は RequestWindow を呼び出して作成し ておきましょう。Page 変数はこの版では実装していませんので、0 に設定し てください。

戻り値 :

CS_BAD_HANDLE

領域ハンドルは無効です。

CS_BAD_PAGE

Page の値がゼロ以外です。

ReleaseWindow

int CardServices(ReleaseWindow, window_handle_t handle);

ReleaseWindow は事前に RequestWindow で割り当てたメモリ領域を解放 します。

戻り値 :

CS_BAD_HANDLE

領域ハンドルは無効です。

3.6 大容量メモリサービス

大容量メモリサービスはメモリ領域サービスで提供しているインターフェース よりメモリ領域にアクセスするインターフェースはより高度になっています。 大容量メモリ呼び出しを使用するクライアントは背後にあるメモリの機構や アクセス法についての知識は必要ありません。機器に依存したプログラムは メモリテクノロジドライバ(MTD) と呼ばれる特殊なカードサービスに入れて います。

RegisterMTD

int CardServices(RegisterMTD, client_handle_t handle, mtd_reg_t *reg);

mtd_reg_t データ 構造体は次のとおり:

typedef union mtd_reg_t {
        u_long          Attributes;
        u_long          Offset;
        u_long          MediaID;
} mtd_reg_t;

RegisterMTD はカードサービスにクライアントの MTD が指定したメモリ 領域を扱う要求を通知します。Offset 変数はメモリ領域の開始アドレスを 指定します。Attributes で指定できる内容は次のとおり:

REGION_TYPE

一般メモリでは REGION_TYPE_CM もしくは 属性メモリでは REGION_TYPE_AM のどちらかを指定します。

MediaID 変数はカードサービスが書き込みます。MTD にこのメモリ領域を 参照する時の要求の一部として渡します。

一旦、MTD がこの呼び出しでメモリ領域に結合すると、DeregisterClient を呼び出すまで結合しつづけます。

戻り値 :

CS_BAD_HANDLE

クライアントハンドルが無効です。

CS_BAD_OFFSET

有効なカードのメモリ領域とオフセットが一致しないか、他の MTD が既にこのメモリ領域を登録しています。

GetFirstRegion, GetNextRegion

int CardServices(GetFirstRegion, client_handle_t handle, region_info_t *region);
int CardServices(GetNextRegion, client_handle_t handle, region_info_t *region);

region_info_t データ 構造体は次のとおり:

typedef union region_info_t {
        u_long          Attributes;
        u_long          CardOffset;
        u_long          RegionSize;
        u_long          AccessSpeed;
        u_long          BlockSize;
        u_long          PartMultiple;
        u_char          JedecMfr, JedecInfo;
        memory_handle_t next;
} region_info_t;

GetFirstRegionGetNextRegion はカードの CISTPL_DEVICE, CISTPL_JEDEC, と CISTPL_DEVICE_GEO タプルの情報を要約します。CardOffset は領域の開始 アドレスを提供します。RegionSize は領域の大きさをバイト単位で提供します。 AccessSpeed は機器のサイクル時間をナノ秒単位で提供します。 BlockSize は 消去ブロックの大きさをバイト単位で提供し、PartMultiple は区画の最小の 大きさを BlockSize 単位で提供します。JedecMfrJedecInfo は 領域が JEDEC に準拠している証明情報を提供します。

Attributes で指定できる変数は次のとおり:

REGION_TYPE

一般メモリでは REGION_TYPE_CM もしくは 属性メモリでは REGION_TYPE_AM のどちらかを指定します。

これらの呼び出しが MTD クライアントによって行なわれた時、BindMTD を呼び出したクライアントに BindMTD が返すメモリを結合させます。

戻り値 :

CS_BAD_HANDLE

クライアントハンドルが無効です。

CS_NO_MORE_ITEMS

メモリ領域が定義されていません。

OpenMemory

int CardServices(OpenMemory, client_handle_t *handle, open_mem_t *req);
pen_mem_t 構造体は次のとおり:
typedef struct open_mem_t {
        u_long          Attributes;
        u_long          Offset;
} open_mem_t;

OpenMemory は他の大容量メモリサービス経由でメモリ領域をアクセスする ハンドルを獲得します。Offset 変数はアクセスするメモリ領域の基底アド レスを指定します。うまくいったら、クライアントハンドル引数は新しい メモリハンドルに置き換わります。

Attributes で指定できる変数は次のとおり:

MEMORY_TYPE

この引数は一般メモリでは MEMORY_TYPE_CM 、属性メモリでは MEMORY_TYPE_AM のいずれかになります。

MEMORY_EXCLUSIVE

クライアントがメモリ領域を排他的にアクセスする為に指定しま す。

戻り値 :

CS_BAD_HANDLE

領域ハンドルが無効です。

CS_BAD_OFFSET

有効な領域のオフセットが指定されていないか、大容量メモリ要求と 関連づける MTD の大容量メモリサービスに領域がありません。

CloseMemory

int CardServices(CloseMemory, memory_handle_t handle);

CloseMemory は 以前に呼び出した OpenMemory が返したメモリハンドルを 解放します。クライアントは DeregisterClient を呼び出す前に全ての メモリハンドルを解放しましょう。

戻り値 :

CS_BAD_HANDLE

メモリハンドルが無効です。

ReadMemory, WriteMemory

int CardServices(ReadMemory, memory_handle_t handle mem_op_t *req, caddr_t buf);
int CardServices(WriteMemory, memory_handle_t handle, mem_op_t *req, caddr_t buf);
mem_io_t 構造体は次のとおり:
typedef struct mem_op_t {
        u_long          Attributes;
        u_long          Offset;
        u_long          Count;
} mem_op_t;

ReadMemoryWriteMemory は以前に呼び出した OpenMemory が返した 指定したメモリハンドルで指定したカードメモリ領域を読み書きします。 Offset 変数はカードメモリ領域の開始アドレスを指定します。 Count 変数は 転送するバイト数を指定します。buf 変数は ReadMemory 操作用の 対象又は WriteMemory 操作の対象となるホストメモリのバッファを指します。

Attributes で指定できる変数は次のとおり:

MEM_OP_BUFFER

ホストバッファがユーザメモリセグメントにある時は MEM_OP_BUFFER_USER もしくはホストバッファがカーネルメモリにある 時は MEM_OP_BUFFER_KERNEL を指定します。

MEM_OP_DISABLE_ERASE

カード領域を書き込む前に消去しないように指定します。

MEM_OP_VERIFY

書き込みの時に検証するときに指定します。

戻り値 :

CS_BAD_HANDLE

領域ハンドルが無効です。

CS_BAD_OFFSET

指定したカードオフセットがメモリ領域の終了アドレスを越えていま す。

CS_BAD_SIZE

指定した転送サイズがメモリ領域の終了アドレスを越えています。

RegisterEraseQueue

int CardServices(RegisterEraseQueue, client_handle_t *handle, eraseq_hdr_t *header);
eraceq_hdr_t 構造体は次のとおり:
typedef struct erase_queue_header_t {
        int             QueueEntryCount;
        eraseq_entry_t  *QueueEntryArray;
} eraseq_hdr_t;

この呼び出しはカードサービスの消去キューを登録します。 eraseq_handle_t ハンドルは *handle に返ります。クライアントが CheckEraseQueue を呼び出した時、カードサービスがキューを調べて 新しい要求の非同期処理を開始します。

eraseq_entry_t 構造体は次のとおり:

typedef struct eraseq_entry_t {
        memory_handle_t Handle;
        u_char          State;
        u_long          Size;
        u_long          Offset;
        u_long          *Optional;
} eraseq_entry_t;

消去キューの登録には、Header 変数は以前に呼ばれた OpenMemory が 返したメモリハンドルを入れます。State 変数は消去キューの状態を 示します。次の値が定義されています。:

ERASE_QUEUED

新規に要求をした時クライアントが設定します。

ERASE_IDLE

登録がアクティブでない時クライアントが設定します。

ERASE_PASSED

消去がうまく完了した時 MTD が設定します。

ERASE_FAILED

消去に失敗した時 MTD が設定します。

ERASE_MEDIA_WRPROT

領域が書き込み禁止になっている事を示しています。

ERASE_NOT_ERASABLE

領域が消去をサポートしていない事を示しています。

ERASE_BAD_OFFSET

消去が消去ブロックの境界で始まっていない事を示しています。

ERASE_BAD_SIZE

要求している消去の大きさが消去ブロックの倍数になっていない事 を示しています。

ERASE_BAD_SOCKET

MTD がカードがない事を示しています。

加えて、ERASE_IN_PROGRESS() マクロは処理している消去の State の 値の真の状態を返します。

Size 変数は消去要求を大きさをバイト単位で与えます。Offset 変数は 領域の開始位置からのオフセットで与えます。大きさとオフセットは 消去ブロック境界に境界調整しておきます。Optional 変数はカードサービス では使われていませんが、クライアントドライバで使われています。

戻り値 :

CS_BAD_HANDLE

クライアントハンドルが無効です。

DeregisterEraseQueue

int CardServices(DeregisterEraseQueue, eraseq_handle_t handle);

DeregisterEraseQueue は以前に RegisterEraseQueue により登録された キューを解放します。指定されたキューに処理中のキューがある場合は、 呼び出しは失敗します。

戻り値 :

CS_BAD_HANDLE

消去キューハンドルが無効です。

CS_BUSY

消去キューが消去処理中です。

CheckEraseQueue

int CardServices(CheckEraseQueue, eraseq_handle_t handle);

この呼び出しは以前に RegisterEraseQueue で登録された新しい消去要求 をカードサービスに通知します。

例によって、クライアントは最初にそれぞれのキューに ERASE_IDLE 状態を割り当てます。キューに新しい要求が追加された時は、クライアントは キューの状態を ERASE_QUEUED にして、CheckEraseQueue を呼びます。 クライアントが消去完了イベントを受け取った場合は、要求が成功したか 状態変数を確認します。

戻り値 :

CS_BAD_HANDLE

消去キューハンドルが無効です。

3.7 各種呼び出し

GetCardServicesInfo

int CardServices(GetCardServicesInfo, servinfo_t *info);
servinfo_t 構造体は次のとおり:
typedef struct servinfo_t {
        char            Signature[2];
        u_long          Count;
        u_long          Revision;
        u_long          CSLevel;
        char            *VendorString;
} servinfo_t;

GetCardServicesInfo はこのカードサービスのバージョンの修正情報を 返します。Signature は ``CS'' に設定します。Count は 現状構成のソケットの数を設定します。 Revision にはカードサービスパッケージの修正レベルを設定し CSLevel は PCMCIA 標準に準じたレベルを設定します。BCD 数で表記 しています。VendorString は RCS 識別文字列へのポインタを設定 します。

この呼び出しは常に成功します。

AccessConfigurationRegister

#include "cisreg.h"

int CardServices(AccessConfigurationRegister, client_handle_t handle, conf_reg_t *reg);
<tt/conf_reg_t/ 構造体は次のとおり:
typedef struct conf_reg_t {
        u_char          Function;
        u_long          Action;
        off_t           Offset;
        u_long          Value;
} conf_reg_t;

あるカードの機能に割り当てられた一般的なクライアントでは、Function 変数は無視されます。BIND_FN_ALL に割り当てられたクライアントでは、 この変数はアクセスする機能の構成レジスタを指定します。

Action 変数は次の内の一つを指定します。

CS_READ

指定した構成レジスタを読み出して Value に値を返します。

CS_WRITE

指定した構成レジスタに Value の値を書き込みます。

AccessConfigurationRegister は構成レジスタ領域の開始アドレスからの Offset 分のオフセットに CIS 構成レジスタの1バイトを読み書きします。 RequestConfiguration で構成したソケットだけで使えます。

cistpl.h で定義している Offset の値は次のとおり :

CISREG_COR

構成オプションレジスタ(COR)。

CISREG_CCSR

カード構成(CC) と状態レジスタ(SR)。

CISREG_PRR

ピン代替レジスタ(PRR)。

CISREG_SCR

ソケット(S) とコピーレジスタ(CR)。

CISREG_ESR

拡張状態レジスタ(ESR)。

CISREG_IOBASE0..CISREG_IOBASE3

入出力基底レジスタ。

CISREG_IOSIZE

入出力サイズレジスタ。

戻り値 :

CS_BAD_HANDLE

クライアントハンドルが無効です。

CS_BAD_ARGS

指定した Action はサポートされていません。

CS_CONFIGURATION_LOCKED

実際に構成がロックされている事を意味しています。

CS_OUT_OF_RESOURCE

カードサービスはカードの構成レジスタをアクセスするメモリ領域 を割り当てを使えないようにします。

AdjustResourceInfo

int CardServices(AdjustResourceInfo, client_handle_t handle, adjust_t *adj);
adjust_t 構造体は次のとおり:
typedef struct adjust_t {
        u_long          Action;
        u_long          Resource;
        u_long          Attributes;
        union {
                struct memory {
                        caddr_t         Base;
                        u_long          Size;
                } memory;
                struct io {
                        ioaddr_t        BasePort;
                        ioaddr_t        NumPorts;
                        u_long          IOAddrLines;
                } io;
                struct irq {
                        u_long          IRQ;
                } irq;
        } resource;
} adjust_t;

AdjustResourceInfo はカードサービスに資源を PCMCIA デバイスが割り当て るか割り当てないかを問い合わせます。通常の Linux の資源管理システム ( *_region が呼び出す入出力ポート、割り込み割り当て)はカードサービス で管理していますが、この関数はユーザに他の管理レベルを提供します。

Action 変数は次の内の一つを指定します。

ADD_MANAGED_RESOURCE

カードサービス管理下におく資源を指定します。従って PCMCIA デバイスが割り当てるものです。

REMOVE_MANAGED_RESOURCE

カードサービス管理から削除する資源を指定します.

初期化時に、カードサービス全ての使用可能な割り込みを使用できるよう にしますが、入出力ポートとメモリ領域は ADD_MANAGED_RESOURCE で 明示的に指定する必要があります。

Resource 変数は次の値をとります。:

RES_MEMORY_RANGE

adj->resource.memory で記述したメモリの範囲を指定します。

RES_IO_RANGE

adj->resource.io で記述した入出力ポートを指定します。

RES_IRQ

adj->resource.irq で記述した割り込みを指定します。

Attributes で指定できる内容は次のとおり:

RES_RESERVED

PCMCIA ドライバ用に要求し,予約した資源を示しています。利用可能 なカードサービスの問い合わせしたデバイス用の資源ではありません。 これは未だ実装していません。

戻り値 :

CS_UNSUPPORTED_FUNCTION

指定した Action と Resource はサポートしていません。

CS_BAD_BASE

指定した入出力アドレスは範囲外です。

CS_BAD_SIZE

指定したメモリまたは入出力領域のサイズは範囲外です。

CS_IN_USE

指定した割り込みは現在カードサービスクライアントが使用中 です。

ReportError

int CardServices(ReportError, client_handle_t handle, error_info_t *err);
error_info_T 構造体の定義は次のとおり:
typedef struct error_info_t {
       int             func;
       int             retcode;
} error_info_t;

ReportError は指定した prefix 文字列とカードサービスの機能コードと 戻り値を含んだカーネルエラーメッセージを生成します。 例を挙げると :

error_info_t err = { RequestIO, CS_BAD_HANDLE };
CardServices(ReportError, handle, &err);
は次のメッセージを生成します。:
serial_cs: RequestIO: Bad handle

この呼び出しは常に正常終了します。


次のページ 前のページ 目次へ