next up previous
次へ: システムコールの再実装(dio_write) 上へ: システムコールの再実装(dio_read) 戻る: システムコールの再実装(dio_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[32]は要求されたビット数のデータを格納する配列変数 である。

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

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

正常に登録されていたらDIO_RESOURCEのポインタ型にキャストして pdio_resに格納する。



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

カウント(count)は、読み出しを行うデータのビットサイズである。 負の場合はエラー(-EINVAL)を返して終了する。32ビット以上を要求された 場合は仕様と異なるので32ビットに切りつめる処理を行う。



\begin{boxedminipage}{\textwidth}
\begin{verbatim}uldata = inl(pdio_res->io_a...
...t; i++) {
bdata[i] = (uldata >> i) & 0x01;
}\end{verbatim}
\end{boxedminipage}

pdio_resポインタが指すI/Oポートのデータをinl関数で読み出す。

pdio_res->io_address[0]はI/Oポートアドレスである。

uldataの32ビットデータは1ビットづつシフトして、要求されたcount数だけ配列bdataに代入する。



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

最後に、ユーザ空間のバッファを示すbuffにカーネル空間で取得した汎 用入力データをコピーする。

カーネル空間内のデータをユーザ空間へコピーするばあいには、 copy_to_user関数を使用する。

コピー完了後、転送を行なったデータサイズを戻り値としてdio_read関 数を終了する。

以上の処理を全て使えば、任意のビットを入力するdio_read関数が完成する。



MANOME Yoichi 平成18年12月26日