ユーザープロセスが mmap(2) を使用してデバイスへのマッピングを要求すると、ドライバの segmap (9E) エントリポイントが呼び出されます。ドライバでデバイスコンテキストを管理する必要がある場合、ドライバはメモリーマッピングの設定時に ddi_devmap_segmap(9F) または devmap_setup(9F) を使用する必要があります。どちらの関数もドライバの devmap(9E) エントリポイントを呼び出しますが、このエントリポイントでは、devmap_devmem_setup(9F) を使用してデバイスメモリーとユーザーマッピングが関連付けられます。デバイスメモリーのマッピング方法の詳細については、Chapter 10, Mapping Device and Kernel Memoryを参照してください。
ドライバは、ユーザーマッピングへのアクセスの通知を受け取ることができるように、devmap_callback_ctl(9S) のエントリポイントの情報をシステムに知らせる必要があります。ドライバは、システムに情報を知らせるために、devmap_callback_ctl(9S) 構造体へのポインタを devmap_devmem_setup(9F) に指定します。devmap_callback_ctl(9S) 構造体は、一連のコンテキスト管理用エントリポイントを記述します。これらのエントリポイントがシステムによって呼び出され、デバイスマッピングに関するイベントを管理するようにデバイスドライバに通知されます。
システムは、各マッピングにマッピングハンドルを関連付けます。このハンドルは、コンテキスト管理用の各エントリポイントに渡されます。マッピングハンドルを使用すると、マッピング変換を無効化および有効化できます。ドライバがマッピング変換を無効化すると、その後マッピングへのアクセスが発生するたびに、それがドライバに通知されます。ドライバがマッピング変換を有効化すると、マッピングへのアクセスが発生してもドライバにはそれが通知されなくなります。マッピングの作成時には常にマッピング変換が無効化されますが、これは、マッピングへのアクセスがはじめて発生したときにドライバに通知が届くようにするためです。
次の例は、デバイスコンテキスト管理インタフェースを使用してマッピングを設定する方法を示したものです。
使用例 11-6 コンテキスト管理サポート付きの devmap (9E) エントリポイントstatic struct devmap_callback_ctl xx_callback_ctl = {
DEVMAP_OPS_REV, xxdevmap_map, xxdevmap_access,
xxdevmap_dup, xxdevmap_unmap
};
static int
xxdevmap(dev_t dev, devmap_cookie_t handle, offset_t off,
size_t len, size_t *maplen, uint_t model)
{
struct xxstate *xsp;
uint_t rnumber;
int error;
/* Setup data access attribute structure */
struct ddi_device_acc_attr xx_acc_attr = {
DDI_DEVICE_ATTR_V0,
DDI_NEVERSWAP_ACC,
DDI_STRICTORDER_ACC
};
xsp = ddi_get_soft_state(statep, getminor(dev));
if (xsp == NULL)
return (ENXIO);
len = ptob(btopr(len));
rnumber = 0;
/* Set up the device mapping */
error = devmap_devmem_setup(handle, xsp->dip, &xx_callback_ctl,
rnumber, off, len, PROT_ALL, 0, &xx_acc_attr);
*maplen = len;
return (error);
}