スポンサーリンク

UIO(9) FreeBSD カーネル開発者マニュアル UIO(9)

名称

uio, uiomove − デバイスドライバ入出力ルーチン

書式

#include <sys/types.h>
#include <sys/uio.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_READ または UIO_WRITE です。

uio_procp
スレッドに関連付けられた struct thread 構造体へのポインタで す。 uio_segflg がプロセスのアドレス空間との転送をすべきであ ると示している場合に使用されます。

使用例

考え方として、ドライバはデータのためのプライベートなバッファの保守を行な い、このバッファの最大サイズのデータのかたまりの要求を処理します。下記の バッファの取り扱いはとても簡略化されていて恐らく動きません(バッファのポイ ンタは部分的な読み込みの場合進みません)し、 uio の取り扱いを実際にやって 見せているだけだ、ということに注意してください。

/* MIN() の定義はこの中にあります */
#include <sys/param.h>

#define BUFSIZE 512
static char buffer[BUFSIZE];

static int data_available;

/* 読み込めるデータ量 */

static int
fooread(dev_t dev, struct uio *uio, int flag)
{

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

スポンサーリンク