Jan 28,1997 onl5v4: Solaris 2.5 cc ドライバのデバッグ. ローダブル・ドライバ・インターフェース部について ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ (http://www-online.kek.jp/~inoue/CAMAC/onl5v4-sol2.5/debug-step4-log.txt) (ftp://onl5v4.kek.jp/export/home/onl5v4/inoue/CAMAC/Log/step4.log) 高エネルギー加速器研究機構 素粒子原子核研究所 物理、オンライングループ 井上 栄二 (1). /usr/local/camac/camac.sol2.debug の下でデバッグする。 /usr/local/camac/camac.sol2 ディレクトリ下のファイルを /usr/local/camac/camac.sol2.debugディレクトリにコピーした (2). まず最初に調べるべき個所。 現状では以下の状況にある。 onl5v4# make load ./script/cc_load.sh [Installing CAMAC device driver] [Adding CAMAC device driver to system] drvconfig: System call 'modctl_modconfig' failed: No such device or address Warning: Driver (cc) configuration failed. System could not install driver. [Configuring CAMAC device driver] [Making CAMAC device files] onl5v4# したがって、Loadable Driver Interface 部を、まず調べる。 以下のファイルを参考にする。 /opt/SUNWDrvs/reloc/SUNWddk/ddk_2.5/driver_dev/pio/pio.c /opt/SUNWDrvs/reloc/SUNWddk/ddk_2.5/driver_dev/dma/sparc/dma.c (3). pio.c および dma.c の例に従って cc.c のヘッダ・ファイルの部分を 修正した。 onl5v4# date Mon Jan 20 14:21:29 JST 1997 onl5v4# diff cc.c.org cc.c 8a9 > #include 9a11,26 > #include > #include > #include > #include > #include > #include > #include > #include > #include > #include > #include > #include > #include > > /* by E.Inoue */ > /* 14,15d30 < #include < #include 17,18d31 < #include < #include 20d32 < #include 22,23d33 < #include < #include 28,29d37 < #include < #include 31d38 < #include 32a40,41 > */ > 34a44 > /* 36a47 > */ 144d154 < #include onl5v4# (4). ここで、cc ドライバを make し直してみる。 onl5v4[117]% make ./script/cc_build.sh [Building for sun4m] "cc.c", line 226: undefined struct/union member: regspec_addr "cc.c", line 957: warning: semantics of ">>" change in ANSI C; use explicit cast "cc.c", line 1203: warning: semantics of "<" change in ANSI C; use explicit cast "cc.c", line 1205: warning: semantics of ">=" change in ANSI C; use explicit cast "cc.c", line 1912: warning: semantics of ">" change in ANSI C; use explicit cast "cc.c", line 1922: warning: semantics of ">=" change in ANSI C; use explicit cast "cc.c", line 1932: warning: semantics of "<" change in ANSI C; use explicit cast "cc.c", line 1942: warning: semantics of "<=" change in ANSI C; use explicit cast "cc.c", line 2004: warning: semantics of ">=" change in ANSI C; use explicit cast "cc.c", line 2111: warning: semantics of "<=" change in ANSI C; use explicit cast cc: acomp failed for cc.c ld: fatal: file cc.o: cannot open file; errno=2 ld: fatal: File processing errors. No output written to cc *** Error code 1 make: Fatal error: Command failed for target `cc' onl5v4[118]% struct/union member: regspec_addr が未定義になってしまう。 チェック。 onl5v4[122]% grep regspec_addr * cc.c: rp->regspec_addr); cc.c.ORG: rp->regspec_addr); cc.c.org: rp->regspec_addr); onl5v4[123]% vi cc.c static int cc_probe(dev_info_t *dip) { int *reg, value; struct regspec *rp; register struct cc_device *cc = &ccdevice[0]; rp = ddi_rnumber_to_regspec(dip, 0); reg = (int *)0; /* Map in device registers */ if (ddi_map_regs(dip, (u_int)0, (caddr_t *)®, (off_t)0, 0)) { uprintf("cc_probe: unable to map registers for cc0\n"); goto failure; } /* initialize cc_device */ bzero((char *)cc, sizeof(struct cc_device)); cc->dip = dip; cc->k = (struct K_REG *)reg; /* check K2917 */ if (ddi_peeks(dip,(short *)&cc->k->csr,(short *)&value) == DDI_FAILURE) { uprintf("cc_probe: unable to find K2917 registers at 0x%X\n", rp->regspec_addr); goto failure; } /* return */ printf("%s\n",CC_START_MESSAGE); return (DDI_PROBE_SUCCESS); : : onl5v4[124]% 必要なファイルまで削除してしまったようだ。 (5). /usr/include/sys ディレクトリの下をチェック。 onl5v4[36]% grep regspec * ddi_impldefs.h:struct regspec { ddi_impldefs.h: u_int regspec_bustype; /* cookie for bus type it's on */ : : /usr/include/sys/ddi_impldefs.h ファイルをチェック。 /* * This structure represents one piece of bus space occupied by a given * device. It is used in an array for devices with multiple address windows. */ struct regspec { u_int regspec_bustype; /* cookie for bus type it's on */ u_int regspec_addr; /* address of reg relative to bus */ u_int regspec_size; /* size of this register set */ }; (6). /usr/include/sys/ddi_impldefs.h ファイルをインクルードしてみよう。 onl5v4[126]% vi cc.c : #include #include #include #include #include #include : (6). 再コンパイル&実行。 onl5v4[128]% make ./script/cc_build.sh [Building for sun4m] "cc.c", line 957: warning: semantics of ">>" change in ANSI C; use explicit cast "cc.c", line 1203: warning: semantics of "<" change in ANSI C; use explicit cast "cc.c", line 1205: warning: semantics of ">=" change in ANSI C; use explicit cast "cc.c", line 1912: warning: semantics of ">" change in ANSI C; use explicit cast "cc.c", line 1922: warning: semantics of ">=" change in ANSI C; use explicit cast "cc.c", line 1932: warning: semantics of "<" change in ANSI C; use explicit cast "cc.c", line 1942: warning: semantics of "<=" change in ANSI C; use explicit cast "cc.c", line 2004: warning: semantics of ">=" change in ANSI C; use explicit cast "cc.c", line 2111: warning: semantics of "<=" change in ANSI C; use explicit cast rm -f cc.o cc -O -c camlib.c -o camlib.o -I. cc -O -c forlib.c -o forlib.o -I. rm -f libcamac.a ar rcv libcamac.a camlib.o forlib.o a - camlib.o a - forlib.o ar: writing libcamac.a cc -O cam1.c -o cam1 -I. -L. -lcamac cc -O cam3.c -o cam3 -I. -L. -lcamac onl5v4[129]% ok. 正常にコンパイルは終った。 (7). ライブラリ、ヘッダファイルをインストールする。 onl5v4[129]% su Password: # csh onl5v4# source /.cshrc onl5v4# make install /usr/ucb/install -d /usr/local/vme/camac/include /usr/ucb/install -d /usr/local/vme/camac/lib /usr/ucb/install -m 644 camlib.h cc_config.h cc_common.h cc.h \ k2917.h /usr/local/vme/camac/include /usr/ucb/install -m 644 libcamac.a /usr/local/vme/camac/lib onl5v4# ok. 正常にインストールは終った。 (8). ドライバをロードする。 onl5v4# make load ./script/cc_load.sh [Installing CAMAC device driver] [Adding CAMAC device driver to system] drvconfig: System call 'modctl_modconfig' failed: No such device or address Warning: Driver (cc) configuration failed. System could not install driver. [Configuring CAMAC device driver] [Making CAMAC device files] onl5v4# NG. 以前と同じエラーになった。 ヘッダ部はこれでよしということにして、 次にLoadable Driver Interface 部を調べる。 (9). cc ドライバとDDK2.5の pio.c や dma.c の cb_ops の記述に違いがある。 cb_ops(9S) ストラクチャには、デバイス・ドライバのキャラクタ動作や ブロック動作のためのエントリ・ポイントが収容されている。 o cc ドライバの cb_ops static struct cb_ops cc_cb_ops = { cc_open, /* open */ cc_close, /* close */ nodev, /* strategy (not block device) */ nodev, /* print */ nodev, /* dump */ nodev, /* read */ cc_write, /* write */ cc_ioctl, /* ioctl */ nodev, /* devmap */ nodev, /* mmap */ nodev, /* segmap */ nochpoll, /* poll */ ddi_prop_op, /* cb_prop_op */ 0, /* streamtab */ D_NEW | D_MTSAFE /* Driver comaptibility flag */ }; o DDK2.5の pio.c の cb_ops static struct cb_ops pio_cb_ops = { pio_open, pio_close, nodev, /* not a block driver */ nodev, /* no print routine */ nodev, /* no dump routine */ nodev, /* no read routine; write-only device */ pio_write, pio_ioctl, nodev, /* no devmap routine */ nodev, /* no mmap routine */ nodev, /* no segmap routine */ nochpoll, /* no chpoll routine */ ddi_prop_op, 0, /* not a STREAMS driver */ D_NEW | D_MP, /* safe for multi-thread/multi-processor */ }; o cb_ops をチェック。 onl5v4[55]% cd /usr/include /usr/include onl5v4[56]% cd sys /usr/include/sys onl5v4[57]% grep cb_ops * conf.h:#define STREAMSTAB(maj) devopsp[(maj)]->devo_cb_ops->cb_str devops.h: * cb_ops: Leaf device drivers or bus nexus drivers supporting devops.h:struct cb_ops { : onl5v4[58]% less devops.h struct cb_ops { #ifdef __STDC__ int (*cb_open)(dev_t *devp, int flag, int otyp, cred_t *credp); int (*cb_close)(dev_t dev, int flag, int otyp, cred_t *credp); int (*cb_strategy)(struct buf *bp); int (*cb_print)(dev_t dev, char *str); int (*cb_dump)(dev_t dev, caddr_t addr, daddr_t blkno, int nblk); int (*cb_read)(dev_t dev, struct uio *uiop, cred_t *credp); int (*cb_write)(dev_t dev, struct uio *uiop, cred_t *credp); int (*cb_ioctl)(dev_t dev, int cmd, int arg, int mode, cred_t *credp, int *rvalp); int (*cb_devmap)(dev_t dev, dev_info_t *dip, ddi_devmap_data_t *dvdp, ddi_devmap_cmd_t cmd, off_t offset, unsigned int len, unsigned int prot, cred_t *credp); int (*cb_mmap)(dev_t dev, off_t off, int prot); int (*cb_segmap)(dev_t dev, off_t off, struct as *asp, caddr_t *addrp, off_t len, unsigned int prot, unsigned int maxprot, unsigned int flags, cred_t *credp); int (*cb_chpoll)(dev_t dev, short events, int anyyet, short *reventsp, struct pollhead **phpp); int (*cb_prop_op)(dev_t dev, dev_info_t *dip, ddi_prop_op_t prop_op, int mod_flags, char *name, caddr_t valuep, int *length); struct streamtab *cb_str; /* streams information */ /* * The cb_flag fields are here to tell the system a * bit about the device. The bit definitions are * in . */ int cb_flag; /* driver compatability flag */ int cb_rev; /* cb_ops version number */ int (*cb_aread)(dev_t dev, struct aio_req *aio, cred_t *credp); int (*cb_awrite)(dev_t dev, struct aio_req *aio, cred_t *credp); #else /* __STDC__ */ int (*cb_open)(); int (*cb_close)(); int (*cb_strategy)(); int (*cb_print)(); int (*cb_dump)(); int (*cb_read)(); int (*cb_write)(); int (*cb_ioctl)(); int (*cb_devmap)(); int (*cb_mmap)(); int (*cb_segmap)(); int (*cb_chpoll)(); int (*cb_prop_op)(); struct streamtab *cb_str; int cb_flag; int cb_rev; int (*cb_aread)(); int (*cb_awrite)(); #endif /* __STDC__ */ }; o D_NEW, D_MTSAFE, D_MP のチェック。 onl5v4[59]% grep D_NEW * conf.h:#define D_NEW 0x00 /* new-style driver */ onl5v4[60]% grep D_MTSAFE * conf.h: * D_MP (D_MTSAFE) and unsafe (D_MP not specified) applies to all drivers conf.h:#define D_MTSAFE 0x20 /* multi-threaded module or driver */ conf.h:#define D_MTSAFETY_MASK (D_MTINNER_MASK|D_MTOUTPERIM|D_MTPUTSHARED|\ conf.h:#define D_MP D_MTSAFE /* ddi/dki approved flag */ onl5v4[61]% grep D_MP * audiovar.h:#define AUD_MPROTO(A, M) (*(A)->distate->ops->mproto)(A, M) conf.h: * D_MP (D_MTSAFE) and unsafe (D_MP not specified) applies to all drivers conf.h: * D_MP - multithreaded driver. conf.h: * D_MTPERQ, D_MTQPAIR, and D_MP. conf.h:#define D_MTINNER_MASK (D_MP|D_MTPERQ|D_MTQPAIR|D_MTPERMOD) conf.h:#define D_MP D_MTSAFE /* ddi/dki approved flag */ onl5v4[62]% onl5v4[62]% less conf.h /* * Device flags. * * Bit 0 to bit 15 are reserved for kernel. * Bit 16 to bit 31 are reserved for different machines. */ #define D_NEW 0x00 /* new-style driver */ #define D_OLD 0x01 /* old-style driver */ #define D_TAPE 0x08 /* Magtape device (no bdwrite when cooked) */ /* * Added for pre-4.0 drivers backward compatibility. */ #define D_NOBRKUP 0x10 /* No breakup needed for new drivers */ /* * Added for MT-safe drivers (in DDI portion of flags). * * D_MP (D_MTSAFE) and unsafe (D_MP not specified) applies to all drivers * as well as STREAMS modules: * Unsafe - executes with the "unsafe_driver" mutex held. * D_MP - multithreaded driver. * * The remainder of the flags apply only to STREAMS modules and drivers. * * If a STREAMS driver or module is not unsafe then it can optionally select * inner and outer perimeters. The four mutually exclusive options that * define the presence and scope of the inner perimeter are: * D_MTPERMOD - per module single threaded. * D_MTQPAIR - per queue-pair single threaded. * D_MTPERQ - per queue instance single threaded. * (none of the above) - no inner perimeter restricting concurrency * * The presence of the outer perimeter is declared with: * D_MTOUTPERIM - a per-module outer perimeter. Can be combined with * D_MTPERQ, D_MTQPAIR, and D_MP. * * The concurrency when entering the different STREAMS entry points can be * modified with: * D_MTPUTSHARED - modifier for D_MTPERQ, D_MTQPAIR, and D_MTPERMOD * specifying that the put procedures should not be * single-threaded at the inner perimeter. * D_MTOCEXCL - modifier for D_MTOUTPERIM specifying that the open and * close procedures should be single-threaded at the outer * perimeter. */ #define D_MTOCEXCL 0x0800 /* modify: open/close are exclusive at outer */ #define D_MTPUTSHARED 0x1000 /* modify: put procedures are hot */ #define D_MTPERQ 0x2000 /* per queue instance single-threaded */ #define D_MTQPAIR 0x4000 /* per queue-pair instance single-threaded */ #define D_MTPERMOD 0x6000 /* per module single-threaded */ #define D_MTOUTPERIM 0x8000 /* r/w outer perimeter around whole modules */ #define D_MTSAFE 0x20 /* multi-threaded module or driver */ : : #define D_MP D_MTSAFE /* ddi/dki approved flag */ : ということなので、D_MP でも D_MTSAFE でも同じことであった。 (10). cc ドライバの方を D_MP に直しておくことにする。 onl5v4[132]% vi cc.c : ddi_prop_op, /* cb_prop_op */ 0, /* streamtab */ D_NEW | D_MTSAFE /* Driver comaptibility flag */ }; この部分を以下のように変更する。 ddi_prop_op, /* cb_prop_op */ 0, /* streamtab */ D_NEW | D_MP /* Driver comaptibility flag */ }; (11). cc ドライバとDDK2.5の pio.c や dma.c の dev_ops の記述に違いがある。 dev_ops(9S) ストラクチャは、カーネルがデバイス・ドライバのオート・ コンフィギュレーションのエントリ・ポイントを見つけられるようにする ためのものである。 o cc ドライバの dev_ops struct dev_ops cc_ops = { DEVO_REV, /* devo_rev, */ 0, /* refcnt */ cc_info, /* info */ cc_identify, /* identify */ cc_probe, /* probe */ cc_attach, /* attach */ cc_detach, /* detach */ nodev, /* reset (device reset routine) */ &cc_cb_ops, /* driver operations */ (struct bus_ops *)0 /* bus operations */ }; o DDK2.5の pio.c の dev_ops static struct dev_ops pio_ops = { DEVO_REV, /* DEVO_REV indicated by manual */ 0, /* device reference count */ pio_getinfo, pio_identify, #ifdef i386 pio_probe, #else nulldev, /* device probe for non-self-id */ #endif pio_attach, pio_detach, nodev, /* device reset routine */ &pio_cb_ops, (struct bus_ops *)0, /* bus operations */ }; (a). cc.c プログラムでは、cc_info と記述されているが、pio プログラムでは、pio_getinfo という記述になっている。 これは、cc_getinfo というエントリ・ポイント名でなければ いけないのか。 混乱を避けるために、cc_info という記述を cc_getinfo に 変更する。 : static int cc_getinfo(dev_info_t *, ddi_info_cmd_t , void *, void **); : struct dev_ops cc_ops = { DEVO_REV, /* devo_rev, */ 0, /* refcnt */ cc_getinfo, /* info */ cc_identify, /* identify */ : /* * Given the device number return the devinfo pointer. */ /* ARGSUSED */ static int cc_getinfo(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg, void **result) { register dev_t dev = (dev_t) arg; register int instance, error; register struct cc_device *cc = &ccdevice[0]; : (12). ここで、コンパイルをやりなおして、"make load" をやってみた。 症状は変わらない。 エラー。 (13). xx_probe 部について。 cc ドライバでは cc_probe エントリ・ポイントを指定している。 cc_identify, /* identify */ cc_probe, /* probe */ cc_attach, /* attach */ pio ドライバでは i386 の場合にだけcc_probe エントリ・ポイント指定 している。 pio_identify, #ifdef i386 pio_probe, #else nulldev, /* device probe for non-self-id */ #endif pio_attach, (a). xx_probe はどのような場合に指定すべきか。 WDD ドキュメントによると、以下のように書いてある。 各ドライバは、カーネルがデバイス・コンフィギュレーションで使用 するための5のエントリ・ポイントを用意しなければならない。 identify(9E),probe(9E),attach(9E),detach(9E),getinfo(9E) の5つ である。 それぞれのデバイス・ドライバは、identify(9E),attach(9E), および getinfo(9E) の各ルーチンを持たなければならない。 probe(9E)は、non self-identifying デバイスでだけ必要とされる。 (b). non self-identifying デバイスについて 自分自身を明らかにするための情報をシステムに提供することができない デバイスはnon self-identifying デバイスと呼ばれる。 このような デバイスは、デバイスが実際にそこにあるかどうかを決定するために つかわれるprobe(9E)ルーチンを持たなければならない。 さらに、デバイスについての情報をハードウェア・コンフィギュレー ション・ファイル(driver.conf(4)を参照)の中に用意しなければなら ない。 システムはこの情報とprobe(9E)を使ってデバイスにアクセス する。 VMEbus,ISA,EISA,および MicroChannelデバイスはnon self- identifying デバイスである。 参考までにあげると、SBus および PCI Local busデバイスはself-identifying デバイスである。 o cc ドライバは、VMEbusの leaf ドライバだからnon self-identifying デバイス出ある。 したがって、probe(9E)エントリ・ポイントを用意 しなければならない。 現在の cc ドライバの記述のままでよい。 (14). modlinkage 宣言部について。 この部分で cc ドライバと pio ドライバとで記述が異なっている。 o cc.c の modlinkage 宣言部 static struct modlinkage modlinkage = { MODREV_1, (void *)&modldrv, NULL }; o DDK2.5の pio.c の modlinkage 宣言部 static struct modlinkage modlinkage = { MODREV_1, /* MODREV_1 indicated by manual */ (void *)&modldrv, NULL, /* termination of list of linkage structures */ }; pio.c では、"NULL," となっているのに cc.c では "NULL" となっている。 これは意味が違ってくるのか。 onl5v4[55]% grep modlinkage * modctl.h: * that must be used in the modlinkage structure. modctl.h: * The modlinkage structure is the structure that the module writer modctl.h: * than 3 linkage structures (which is very unlikely), a modlinkage modctl.h:struct modlinkage { modctl.h: struct modlinkage *mod_linkage; : onl5v4[56]% less modctl.h /* * Revision number of loadable modules support. This is the value * that must be used in the modlinkage structure. */ #define MODREV_1 1 /* * The modlinkage structure is the structure that the module writer * provides to the routines to install, remove, and stat a module. * The ml_linkage element is an array of pointers to linkage structures. * For most modules there is only one linkage structure. We allocate * enough space for 3 linkage structures which happens to be the most * we have in any sun supplied module. For those modules with more * than 3 linkage structures (which is very unlikely), a modlinkage * structure must be kmem_alloc'd in the module wrapper to be big enough * for all of the linkage structures. */ struct modlinkage { int ml_rev; /* rev of loadable modules system */ void *ml_linkage[4]; /* NULL terminated list of */ /* linkage structures */ }; (a). modlinkage ストラクチャについて modlinkage ストラクチャ(module linkage structure)は、ドライバが ロードされる時にカーネルに対して export される。 このストラクチャはモジュールからの install, remove, and retrieve に関する情報のためのルーチンのために、モジュール作成者が提供する。 #include modlinkage() int ml_rev void *ml_linkage[4]; ml_rev フィールドはローダブル・モジュール・システムのバージョン 数を示す。 ここには、MODREV_1 とセットすべきである。 ドライバはただ1つのモジュールのみをサポートできる、だから ml_linkageの1番目のエレメント(ml_linkage[0])だけがmodldrv(9S) ストラクチャのアドレスにセットされるべきである。 ml_linkage[1] はNULLにセットされるべきである。 o "NULL" でも "NULL," でも上記の設定法を満たすのでどちらでもよい。 混乱を避けるために、cc.c の記述を "NULL" から "NULL," へ変更する。 (15). プログラムの書き方として。 pio.c プログラムでは、pio_identify(),pio_probe(),pio_attach(), pio_getinfo()ルーチンの後ろに _init(),_info(),_fini()ルーチンが 書いてある。 一方、cc.c プログラムでは、cc_identify(),cc_probe(), cc_attach(),cc_detach(),cc_getinfo()ルーチンの前に _init(),_info(), _fini()ルーチンが書いてある、ここでは cc.c プログラムのままにして おく。 (16). ここでコンパイルをやり直してみる。 症状は変わらない。 onl5v4# truss make load >& truss.log : sigaction(SIGHUP, 0xEFFFDAA8, 0xEFFFDBC8) = 0 sigprocmask(SIG_UNBLOCK, 0xEFFFDBF8, 0xEFFFDBE8) = 0 [Adding CAMAC device driver to system] drvconfig: System call 'modctl_modconfig' failed: No such device or address Warning: Driver (cc) configuration failed. System could not install driver. [Configuring CAMAC device driver] wait() (sleeping...) [Making CAMAC device files] Received signal #18, SIGCLD, in wait() [default] siginfo: SIGCLD CLD_EXITED pid=8797 status=0x0000 wait() = 8797 [0x0000] lstat(".make.state", 0xEFFFDC10) Err#2 ENOENT lstat("load", 0xEFFFDCD0) Err#2 ENOENT lstat(".DONE", 0xEFFFF190) Err#2 ENOENT lseek(0, 0, SEEK_CUR) = 12703 _exit(0) onl5v4# onl5v4# ls -l /dev/cc lrwxrwxrwx 1 root other 4 Jan 23 10:16 /dev/cc -> /:cc onl5v4# /dev/cc が正しく作られていないようだ。 チェック。 @@@ -- ここから-- @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ o ここで、少し視点を変えて vme ドライバは機能しているかどうかを 調べる。 現在、vme クレートに差してある k2917 の CSR レジスタを読んでみる。 onl5v4[87]% pwd /opt/FRCvme/examples onl5v4[88]% vmetest This is more an example than a real test program. Please look at the source and modify it for your needs. Do you want to perform the vme16d16 mmap test (y/n) ? y will now test vme16d16 memory mapping enter vme A16D16 address (hex): 0xff00 enter number of bytes to read (dec): 2 mapping 4 KByte at vme address 0xf000 Reading 2 bytes from vme address 0xff00 0000ff00: ff ff Reading 1 shorts from vme address 0xff00 0000ff00: 0000 Will read one 16bit word from an odd address 0xff01 Expecting a BUS ERROR, because UAT is not supported to continue 0000ff01: BUS ERROR to continue Testing Automatic Bus Sizing Reading one 32bit word from address 0xff00 0000ff00: 00000000 Do you want to perform the vme24d16 test (y/n) ? n Do you want to perform the vme32d32 mmap test (y/n) ? n Do you want to perform the vme32d32 test (y/n) ? n end of vmetest onl5v4[89]% read を実行した時、一瞬だけ K2917 の add-reg の LED が点灯した。 この LED は vme バスから K2917 がアドレスされた時に点灯するもの であるから、vme ドライバは正しく動作していると見てよいだろう。 @@@ -- ここまで -- @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ o ドライバのインストールと削除 ドライバが使われる前に、システムはそれが存在することを知らされて いなければならない。 正しくデバイス・ドライバをインストールする ために add_drv(1M) ユティリティが使われる。 一度、ドライバが インストールされると、再びに add_drv(1M) を使うことなしに、メモリ へのロード、アンロードができる。 o モジュール・ディレクトリへのドライバのコピー ドライバおよびコンフィギュレーション・ファイルを /usr/kernel/drv の drv ディレクトリへコピーしなければならない。 # cp cc /usr/kernel/drv # cp cc.conf /usr/kernel/drv (17). _init()ルーチンについて。 cc.c プログラムと pio.c プログラムとで_init()ルーチンの記述が異なって いる。 o cc.c の _init()ルーチン部 int _init(void) { return (mod_install(&modlinkage)); } o DDK2.5の pio.c の _init()ルーチン部 int _init(void) { register int error; if ((error = ddi_soft_state_init(&state_head, sizeof (Pio), 1)) != 0) return (error); if ((error = mod_install(&modlinkage)) != 0) ddi_soft_state_fini(&state_head); return (error); } o cc.c プログラムでは、ddi_soft_state_init()ルーチンが実行されて いないこの記述で正しいのか。 ddi_soft_state_init()ルーチンは実行 しなければならないのか。 o ローダブル・ドライバ・インターフェースについて デバイス・ドライバは動的にローダブルでなければならない。 そして、 メモリ資源を節約するためにアンローダブルにすべきである。 各デバイス・ドライバはローダブル・インターフェースを明確にする コード部をもつ。 このコード部はソフト・ステート・ルーチン用の スタティック・ポインタ、やデータ・ストラクチャおよびモジュールの ローディングに伴うルーチンを明確にする。 (18). ここで、気になったので driver configuration file をチェック。 <<< cc.conf >>> # Configuration file for a pseudo device on the VME bus # # This .conf file specifies that the device has the # following characteristics: # # VME Space: A16D16 == 0x2D # VME Address: 0xFF00 # Device Size: 0xFF bytes. # name="cc" parent="vme" reg=0x002D,0xFF00,0x00FF interrupts=4,0xFF; <<< vmeplus.conf >>> # @(#)vmeplus.conf 1.0 96/06/23 # # Example for interrupt properties. # The reg-specs must not be changed. # # interrupts=1,0x4c,6,0x50 # reg=0x2d,0,0x10000, 0x3d,0,0xff0000, 0x0d,0,0xff000000, 0x6d,0,0x10000, 0x7d,0,0xff0000, 0x4d,0,0xff000000 name="vmeplus" class="vme"; o cc.conf では parent="vme" となっている。 これを、class="vme" に 変更してみる。 (19). make load を実行。 onl5v4# make unload ./script/cc_unload.sh [Removing CAMAC device driver] [Removing CAMAC device driver from system] [Deleting CAMAC device files] onl5v4# onl5v4# make load ./script/cc_load.sh [Installing CAMAC device driver] [Adding CAMAC device driver to system] [Configuring CAMAC device driver] [Making CAMAC device files] by E.Inoue: check point 1 onl5v4# o ok. "drvconfig: System call 'modctl_modconfig' failed" のエラー は出なくなった。 (20). /dev/cc をチェック。 onl5v4[172]% ls -l /dev/cc lrwxrwxrwx 1 root other 4 Jan 27 16:40 /dev/cc -> /:cc onl5v4[173]% pwd /devices/iommu@0,10000000/VME@0,7ffffe00 onl5v4[174]% ls -l total 0 crw-rw-rw- 1 root sys 60, 0 Jan 27 16:39 cc@2d,ff00:cc crw-rw-rw- 1 root sys 113, 10 Dec 13 16:45 vmectl:vmectl crw------- 1 root sys 67, 1 Dec 13 16:45 vmemem@2d,0:a16d16 crw------- 1 root sys 67, 2 Dec 13 16:45 vmemem@3d,0:a24d16 crw------- 1 root sys 67, 3 Dec 13 16:45 vmemem@4d,0:a32d32 crw------- 1 root sys 67, 4 Dec 13 16:45 vmemem@6d,0:a16d32 crw------- 1 root sys 67, 5 Dec 13 16:45 vmemem@7d,0:a24d32 crw------- 1 root sys 67, 0 Dec 13 16:45 vmemem@d,0:a32d16 crw-rw-rw- 1 root sys 56, 0 Dec 13 16:45 vmeplus@2d,0:vme16d16 crw-rw-rw- 1 root sys 56, 3 Dec 13 16:45 vmeplus@2d,0:vme16d32 crw-rw-rw- 1 root sys 56, 1 Dec 13 16:45 vmeplus@2d,0:vme24d16 crw-rw-rw- 1 root sys 56, 4 Dec 13 16:45 vmeplus@2d,0:vme24d32 crw-rw-rw- 1 root sys 56, 2 Dec 13 16:45 vmeplus@2d,0:vme32d16 crw-rw-rw- 1 root sys 56, 5 Dec 17 14:54 vmeplus@2d,0:vme32d32 onl5v4[175]% /devices/iommu@0,10000000/VME@0,7ffffe00/cc@2d,ff00:cc は作られて いるが /dev/cc からのシンボリックリンクが正しく張られていない。