next up previous
次へ: dio_readメソッドの登録 上へ: システムコールとメソッド(その2: dio_read) 戻る: readメソッド

dio_readメソッドの作成

仕様に従ってdio_readメソッドを作成する。


\begin{boxedminipage}{\textwidth}
\begin{verbatim}ssize_t dio_read(struct fil...
... pdio_res = (PDIO_RESOURCE)filp->private_data;\end{verbatim}
\end{boxedminipage}

宣言されたbdataは1バイトデータを格納する変数である。
宣言されたpdio_resはリソース情報構造体(DIO_RESOURCE)を指す ポインタ型の変数である。

dio_open内で登録したリソース情報構造体のアドレスを確認する。 リソース情報構造体のアドレスが正常に登録されていなければ、すなわち NULLならばエラー(-ENODEV)を返して終了する。 正常に登録されていたらDIO_RESOURCEのポインタ型にキャストして pdio_resに格納する。


\begin{boxedminipage}{\textwidth}
\begin{verbatim}if (count < 0)
return -EINVAL;if (count > 1)
count = 1;\end{verbatim}
\end{boxedminipage}

カウント(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バイトデータを読み出すことができる。


\begin{boxedminipage}{8cm}
\begin{verbatim}inb(0xcc00); // 16進数の場合\end{verbatim}
\end{boxedminipage}

または、


\begin{boxedminipage}{8cm}
\begin{verbatim}inb(52224); // 10進数の場合\end{verbatim}
\end{boxedminipage}

inb関数はL.D.D.3の244ページの書式が示すようにportからデータの読み 出しをおこなうものである。portには、読み出しをおこなうI/Oポートアドレス を指定する。

実際のプログラムではI/Oポートアドレスの値が実験システムによっ て異なってもよいように、変数としてpdio_res->io_address[0]を使い、 読み出した1バイトデータを変数bdataに代入することにする。


\begin{boxedminipage}{\textwidth}
\begin{verbatim}bdata = inb(pdio_res->io_address[0]);\end{verbatim}
\end{boxedminipage}


最後に、ユーザ空間のバッファを示すbuffにカーネル空間で取得した汎 用入力データをコピーする。
カーネル空間内のデータをユーザ空間へコピーするばあいには、 copy_to_user関数を使用する。このとき1バイトデータの入っている変 数bdataはポインタアドレス(&bdata)で指定する。


\begin{boxedminipage}{\textwidth}
\begin{verbatim}if (copy_to_user(buff, &bdata, count))
return -EFAULT;return count;
}\end{verbatim}
\end{boxedminipage}

コピー完了後、転送を行なったデータサイズを戻り値としてdio_read関 数を終了する。今回の実験ではcountの値は1である。

以上の処理を全て使えば、1バイト入力のdio_readメソッドは完成する。



MANOME Yoichi 平成19年1月6日