UIO(9) FreeBSD カーネル開発者マニュアル UIO(9)
名称
|
uio, uiomove − デバイスドライバ入出力ルーチン |
書式
|
#include <sys/types.h> struct uio {
|
|
struct |
iovec *uio_iov; |
||
|
int |
uio_iovcnt; |
||
|
off_t |
uio_offset; |
||
|
int |
uio_resid; |
||
|
enum |
uio_seg uio_segflg; |
||
|
enum |
uio_rw uio_rw; |
||
|
struct |
thread *uio_td; |
|
}; int |
|
uiomove(void *buf, int howmuch, struct uio *uiop); |
|
解説 |
|
uiomove() 関数は、ユーザ空間とカーネル空間の境界を越えることさえ可能で、 バッファと入出力ベクタ間のデータ転送の実行に使用されます。 文字型デバイスのドライバに渡された、あらゆる read(2), write(2), readv(2) ないし writev(2) システムコールの結果として、適切なドライバの d_read また は d_write エントリが struct uio 構造体のポインタを渡されて呼び出されま す。転送のリクエストは、この構造体の中にエンコードされます。ドライバ自身 もこの構造体の中のデータを取り出すために uiomove() を使用するべきです。 uio 構造体の各フィールドは下記のとおりです。 |
uio_iov
|
処理すべき入出力ベクタの配列です。散在的な入出力の場合には、 一つ以上のベクタとなるでしょう。 uio_iovcnt uio_offset uio_resid uio_segflg UIO_USERSPACE UIO_SYSSPACE UIO_NOCOPY uio_rw uio_procp 使用例 |
|
考え方として、ドライバはデータのためのプライベートなバッファの保守を行な い、このバッファの最大サイズのデータのかたまりの要求を処理します。下記の バッファの取り扱いはとても簡略化されていて恐らく動きません(バッファのポイ ンタは部分的な読み込みの場合進みません)し、 uio の取り扱いを実際にやって 見せているだけだ、ということに注意してください。 /* MIN() の定義はこの中にあります */ #include <sys/param.h> #define BUFSIZE 512 static char buffer[BUFSIZE]; |
|
static int data_available; |
/* 読み込めるデータ量 */ |
|
static int |
|
int rv, amnt; |
|||||||
|
rv = 0; |
|||||||
|
while (uio->uio_resid > 0) { |
|||||||
|
if (data_available > 0) { |
|||||||
|
amnt = MIN(uio->uio_resid, data_available); |
|||||||
|
rv = uiomove(buffer, amnt, uio); |
|||||||
|
if (rv != 0) |
|||||||
|
break; |
|||||||
|
data_available -= amnt; |
|||||||
|
} else |
|||||||
|
tsleep(...); |
/* より良い時期まで待つ */ |
||||||
|
} |
|||||||
|
if (rv != 0) { |
|||||||
|
/* エラーのクリーンアップをここで行なう */ |
|||||||
|
} |
|||||||
|
return (rv); |
|
} |
戻り値
|
uiomove() はプロセスのアドレス空間との転送の場合に、 copyin(9) または copyout(9) によって引き起こされた EFAULT を返すことがあります。 |
関連項目
|
read(2), readv(2), write(2), writev(2), copyin(9), copyout(9), sleep(9) |
歴史
|
uio の仕組みはある早期のバージョンの UNIX で登場しました。 |
作者
|
このマニュアルページは Jörg Wunsch が書きました。 FreeBSD 10.0 February 2, 1997 FreeBSD 10.0 |