仕様に従ってdio_read
メソッドを作成する。
宣言されたbdata
は1バイトデータを格納する変数である。
宣言されたpdio_res
はリソース情報構造体(DIO_RESOURCE
)を指す
ポインタ型の変数である。
dio_open
内で登録したリソース情報構造体のアドレスを確認する。
リソース情報構造体のアドレスが正常に登録されていなければ、すなわち
NULL
ならばエラー(-ENODEV
)を返して終了する。
正常に登録されていたらDIO_RESOURCE
のポインタ型にキャストして
pdio_res
に格納する。
カウント(count
)は、読み出しを行うデータのバイトサイズである。
負の場合はエラー(-EINVAL)を返して終了する。1バイト以上を要求された
場合は仕様と異なるので1バイトに切りつめる処理を行う。
次に、この1バイトデータをpdio_res
ポインタが指すI/Oポートから
inb
関数を使って読み出す。
pdio_res->io_address[0]
はI/Oポートアドレスである。
実験(12)では、初期化モジュール(dio_init())の中で、
dio_res.io_address[0]
からI/Oポートアドレスを取得したが、今回は、
pdio_res->io_address[0]
という形式でI/Oポートアドレスを取得してい
る。
この実験では、デバイスドライバのカーネルオブジェクトをロードすると、 初期化モジュール(dio_init())によってI/Oポートアドレスが次の ように表示された。
I/O Port 0 = CC00 h I/O Port 0 = 52224 d |
この16進数と10進数で表示されたI/Oポートアドレスの値は実験システムによっ
て異なるが、上記のI/Oポートアドレスを持つ実験システムでは
inb
関数を使って次のように1バイトデータを読み出すことができる。
または、
inb
関数はL.D.D.3の244ページの書式が示すようにportからデータの読み
出しをおこなうものである。portには、読み出しをおこなうI/Oポートアドレス
を指定する。
実際のプログラムではI/Oポートアドレスの値が実験システムによっ
て異なってもよいように、変数としてpdio_res->io_address[0]
を使い、
読み出した1バイトデータを変数bdataに代入することにする。
最後に、ユーザ空間のバッファを示すbuff
にカーネル空間で取得した汎
用入力データをコピーする。
カーネル空間内のデータをユーザ空間へコピーするばあいには、
copy_to_user
関数を使用する。このとき1バイトデータの入っている変
数bdataはポインタアドレス(&bdata)で指定する。
コピー完了後、転送を行なったデータサイズを戻り値としてdio_read
関
数を終了する。今回の実験ではcount
の値は1である。
以上の処理を全て使えば、1バイト入力のdio_read
メソッドは完成する。