Aug 1, 2000 onl50t: Solaris 2.6 cc ドライバのデバッグ. cc ドライバのデバッグ#04(その6) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ (http://www-online.kek.jp/~inoue/CAMAC/ onl50t-sol2.6/Desktop/debug-list-step06.txt) 高エネルギー加速器研究機構 素粒子原子核研究所 物理、オンライングループ 井上 栄二 (1). 現状確認 (A). 株式会社ロジックハウスの白田様より SPARC CPU-50T を借用した。 (B). FORCE,CPU-50(UltraSPARC-IIi 300MHz)、に Solaris2.6 のシステムを インストールした。 (C). /etc の下の各設定、および /export/home の作成をやった。 (D). "Solaris2.6 Hardware: 5/98 SMCC Desktop 日本語版 SPARC版"では ディスクレス・クライアントを設定することはできないことを確認した。 (E). CPU-50T に Solaris2.6用の VMEドライバ、FRCvme-2.3.1 をインストール した。 (F). onl50t に ccドライバをインストールした。 (G). サンプル・プログラムを実行した。 (1). cam1、シングル・アクション 24ビット camac read/write の実行 NG. システムはパニックを起こしてリブートしてしまう。 (2). cam3、camac LAM割り込み処理の実行 NG. システムはパニックを起こしてリブートしてしまう。 (3). cam2、ブロック転送 16ビット read/write の実行 ok. 正常に実行できた。 (4). cam2、ブロック転送 24ビット read/write の実行 ok. 正常に実行できた。 (H). クラッシュ時の savecoreファイルを入手してデバッグを始めた。 (I). cam1プログラムのデバッグ、icc_ioctlルーチンを修正した。 ok. cam1プログラムは正常に実行できた。 (J). cam3プログラムのデバッグを始めた。 camac_s()ルーチンの中で "cc->k->dhr = *dat;" を実行したところでエラーになっている。 message構造体をcc_device構造体の中に入れてみたが改善されない。 (K). cam3プログラムは正常に動作できるようになった。 (L). cam3プログラムのデバッグ時に付加したゴミをはずして最終的な動作確認 をやった。 ok. (M). onl50t 上でデバッグしたcamacドライバをfrc7v-cl2 上で動作確認した。 ok. (N). onl50t 上でデバッグしたcamacドライバを onl7v2、スタンドアロン Solaris2.6 上で動作確認した。 ok. (O). onl50t 上でデバッグしたcamacドライバを frc8vt、ディスクレス・サーバ Solaris2.6 上で動作確認した。 ok. (P). onl50t 上でデバッグしたcamacドライバを onl8v1、スタンドアロン Solaris2.6 上で動作確認した。 ok. (Q). onl50t 上でデバッグしたcamacドライバを onl5v4、スタンドアロン Solaris2.6 上で動作確認した。 ok. (R). スタンドアロン Solaris2.6、onl50t 上で、シングルアクションの実行 速度を測定時に、camac_s()コールを連続実行すると不正割り込みが かかってしまった。 (S). camac_s()コールを連続実行しても不正割り込みはかからないように なった。 ok. -------------------- リスト処理 (A). 公開版のcamacドライバ、"FORCE-50T-sol2.6" を使ってリスト処理の テストを始める。 (B). KEKリスト処理で camacシングルアクション read/write、LAM割り込み 処理、DMA camacブロック転送の現状確認をした。 (C). Kineticリスト処理で camacシングルアクション read の現状確認をした。 (D). KEKリスト処理、Kineticリスト処理両方をとおしてソースプログラム上で 明らかに問題と思われる部分を修正した。 (E). KEKリスト処理でシングルアクション read/write が正常に実行できて いることを確認した。 (F). KEKリスト処理で DMA camacブロック転送 read が正常に実行できて いることを確認した。 (2). ここでやるべきこと KEKリスト処理で LAM割り込み処理が正常に実行できるようにする。 (3). 現状確認 (3-1). オリジナルの camtest4int.asm による実行 onl50t[185]% pwd /export/home/onl50t/inoue/CAMAC/Driver/Kit-test/CAMAC-list/FORCE-50T-sol2.6/camlist onl50t[186]% cat camtest4int.asm ; File name : camtest4int.asm ; Creation date : July 1992 ; Author : Y.Yasu, Online group, Physics department, KEK SW equ 3 ; CAMAC SWITCH REGISTER MEM equ 4 ; CAMAC BUFFER MEMORY MOUDLE INT equ 5 ; CAMAC INTERRUPT REGISTER LEN equ 10 ; 10 words ; SETCRATE #0 GENZ GENC SETI REMI ; ENBINT MOVE.l #1000,T NDT (26,INT,0) LOOPIN1 WAITINT ; GENC NDT (9,INT,0) MOVE.l T,A WRITE.l A,(16,SW,0) SUB #1,T BGT #0,LOOPIN1 LOAD COUNT MOVE.l A,(PTR)+ LOAD PTR MOVE.l A,(PTR)+ MOVE.l #1000,T LOOPIN2 WAITEVENT ; GENC NDT (9,INT,0) MOVE.l T,A WRITE.l A,(16,SW,0) SUB #1,T BGT #0,LOOPIN2 LOAD COUNT MOVE.l A,(PTR)+ LOAD PTR MOVE.l A,(PTR)+ DSBINT ; STOP end onl50t[187]% onl50t[190]% rm camtest4int.obj onl50t[191]% make camtest4int.obj ../camasm/camasm camtest4int.asm CAMASM macro assembler V0.1 --- KEK online group --- Modified by Y.T Oct-1991 onl50t[192]% cat camtest4int.obj 0034 020B 0000 010C 010D 010F 010E 0110 032B 03E8 0000 0209 0A1A 0153 0209 0A09 0127 0208 0610 034A 0001 0000 0458 000D 0000 0000 0136 012D 0133 012D 032B 03E8 0000 0154 0209 0A09 0127 0208 0610 034A 0001 0000 0458 0021 0000 0000 0136 012D 0133 012D 0111 0100 0000 onl50t[193]% onl50t[197]% cat camtest5c1.c /* File name : camtest5c1.c * Creation date : July 1992 * Author : Y.Yasu, Online group, Physics department, KEK * Modified : August 1994, Y.Yasu * For HP-RT * Modified : June 30, E.Inue */ /* System headers */ #include #include /* Local headers */ #include "camlib.h" /* Macros */ #define MAXLENBUF 10000 #define MAXLENLIST 1000 #ifdef HP_RT extern char *sys_errlist[]; #endif /* Functions */ error_exit(status) int status; { #ifdef HP_RT perror(sys_errlist[status]); #else perror((const char *)strerror(status)); #endif exit(status); } /* Main */ main(argc, argv) int argc; char *argv[]; { int status, Error, i; int Lenlis, action; unsigned short List[MAXLENLIST], Buffer[MAXLENBUF], *PtrBuffer; struct cc_iosb Iosb; char Filename[30]; /* strcpy(Filename, "camtest4.obj"); */ strcpy(Filename, "camtest4int.obj"); /* strcpy(Filename, "camtest4single.obj"); */ /* strcpy(Filename, "camtest4dma.obj"); */ if (argc > 1) action = atoi(argv[1]); else action = 0xf; Iosb.s_reg = action; if (status = CAM_Open()) error_exit(status); if (status = CamReaLIST(Filename, List, MAXLENLIST, &Lenlis, &Error)) error_exit(status); printf("CamReaLIST : OK\n"); printf("lenlist = %d\n", Lenlis); printf("list = %x %x %x %x %x\n", List[0], List[1], List[2], List[3]); if (status = CamLisExeWAIt(List, Lenlis, Buffer, MAXLENBUF, &Iosb)) error_exit(status); printf("CamLisExeWAIt : OK\n"); printf("contents of iosb :\n"); printf("iosb.status = %x iosb.ret_length = %x iosb.s_reg = %x ", Iosb.status, Iosb.ret_length, Iosb.s_reg); printf(" iosb.devinfo = %x\n", Iosb.devinfo); printf("contents of buffer :\n"); for( i = 0; i < 12 ;i++) printf("%6x %6x %6x %6x %6x %6x %6x %6x %6x %6x\n", Buffer[10*i+0], Buffer[10*i+1], Buffer[10*i+2], Buffer[10*i+3], Buffer[10*i+4], Buffer[10*i+5], Buffer[10*i+6], Buffer[10*i+7], Buffer[10*i+8], Buffer[10*i+9]); if (status = CAM_Close()) error_exit(status); } onl50t[198]% onl50t[199]% rm camtest5c1 onl50t[200]% make camtest5c1 cc -o camtest5c1 camtest5c1.c -I.. -L.. -lcamac onl50t[201]% onl50t[54]% camtest5c1 CamReaLIST : OK lenlist = 52 list = 20b 0 10c 10d ef7a6080 <---- ここで wait し、しばらくの後タイムアウト で以降の処理が実行される。 CamLisExeWAIt : OK contents of iosb : iosb.status = fffffff5 iosb.ret_length = 0 iosb.s_reg = f iosb.devinfo = c0a2 c0a2 contents of buffer : 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 onl50t[55]% この時のコンソール上のメッセージは以下のとおり。 NOTICE: cc_write: CC_CMD_LOADDOLIST: enter CC_CMD_LOADDOLIST NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, code = 0xb NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, cc->status = 0x0 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, code = 0xc NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, cc->status = 0x0 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, code = 0xd NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, cc->status = 0x0 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, code = 0xf NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, cc->status = 0x0 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, code = 0xe NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, cc->status = 0x0 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, code = 0x10 NOTICE: cc_enbint: NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, cc->status = 0x0 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, code = 0x2b NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, cc->status = 0x0 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, code = 0x9 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, cc->status = 0x0 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, code = 0x53 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, cc->status = 0xfffffff5 NOTICE: cc_write: CC_CMD_LOADDOLIST: out while, cc->status = 0xfffffff5 NOTICE: cc_write: CC_CMD_LOADDOLIST: out while #2, cc->status = 0xfffffff5 実行結果を確認すると次のようになる。 (1). コード 0xb = cc_setcrate (2). コード 0xc = cc_genz (3). コード 0xd = cc_genc (4). コード 0xf = cc_seti (5). コード 0xe = cc_remi (6). コード 0x10 = cc_enbint (7). コード 0x2b = cc_move32_t (8). コード 0x9 = cc_ndt (9). コード 0x53 = cc_waitint 9命令目の cc_waitint を実行したところで cc->status = 0xfffffff5 のエラー "CC_STA_LIST_TIMEOUT" になって以降のリスト処理を中断して終わっている。 この時 2917 の LED は "No Q"、と "ERR" が点灯している。 問題が起きているのは、インタラプト・モジュールをアクセスした時の "No Q" のためではなくて、cc_waitint()ルーチンのあたりに在ると思われる。 (4). cc.cファイルの修正 ENBINT()、DSBINT()、WAITINT() および WAITEVENT()ルーチンをチェックする。 (4-1). cc.cファイルを修正する : /* cc_enbint(cc) E.Inoue */ cc_enbint(int unit) /* struct cc_device *cc; E.Inoue */ { /* E.Inoue */ struct cc_device *cc; /* end */ register int status; /* E.Inoue int dat; */ u_short sdat; /* E.Inoue */ cc = ddi_get_soft_state(cc_state,unit); mutex_enter(&cc->mutex); /* end */ cmn_err(CE_NOTE," cc_enbint: "); #ifdef CC_SPARC_LIST_EXTENSION /* E.Inoue dat = cc->a_reg; */ cc->data1 = cc->a_reg; #else /* E.Inoue dat = 0xFFFFFF; */ /* mask */ cc->data1 = 0xFFFFFF; #endif /* if (status = camac_s(getminor(cc->dev), CC_BIT24, NAF(30, 13, 17), (u_shor t *)&dat)) E.Inoue */ if (status = camac_s(unit, CC_BIT24, NAF(30, 13, 17), (u_short *)&cc->data1) ) { mutex_exit(&cc->mutex); return status; } /* if (status = camac_s(getminor(cc->dev), CC_BIT24, NAF(30, 0, 1), (u_short *)&dat)) E.Inoue */ if (status = camac_s(unit, CC_BIT16, NAF(30, 0, 1), &sdat)) { mutex_exit(&cc->mutex); return status; } sdat |= 0x0100; /* return camac_s(getminor(cc->dev), CC_BIT24, NAF(30, 0, 17), (u_short *)&da t); E.Inoue */ status = camac_s(unit, CC_BIT16, NAF(30, 0, 17), &sdat); mutex_exit(&cc->mutex); return status; } /* cc_dsbint(cc) E.Inoue */ cc_dsbint(int unit) /* struct cc_device *cc; E.Inoue */ { /* E.Inoue */ struct cc_device *cc; /* end */ register int status; int dat; u_short sdat; /* E.Inoue */ cc = ddi_get_soft_state(cc_state,unit); /* end */ /* disable LAM */ cc->k->lamc = CC_INT_AUTO_CLEAR | intrpri; dat = 0x0; /* mask */ /* if (status = camac_s(getminor(cc->dev), CC_BIT24, NAF(30, 13, 17), (u_shor t *)&dat)) E.Inoue */ if (status = camac_s(unit, CC_BIT24, NAF(30, 13, 17), (u_short *)&dat)) return status; /* if (status = camac_s(getminor(cc->dev), CC_BIT24, NAF(30, 0, 1), (u_short *)&dat)) E.Inoue */ if (status = camac_s(unit, CC_BIT16, NAF(30, 0, 1), &sdat)) return status; sdat &= ~0x0100; /* return camac_s(getminor(cc->dev), CC_BIT24, NAF(30, 0, 17), (u_short *)&da t); E.Inoue */ return camac_s(unit, CC_BIT16, NAF(30, 0, 17), &sdat); } : /* int cc_waitint(cc) E.Inoue */ int cc_waitint(int unit) /* struct cc_device *cc; E.inoue */ { /* E.Inoue */ struct cc_device *cc; /* end */ int s; /* E.Inoue u_long tick, timeout; */ cmn_err(CE_NOTE," cc_waitint: enter"); /* E.Inoue */ cc = ddi_get_soft_state(cc_state,unit); mutex_enter(&cc->mutex); /* start MUTEX */ /* end */ cc->interrupt = 0; cc->k->lamc = CC_INT_AUTO_CLEAR | CC_INT_ENABLE | intrpri; /* lock out clock */ /* s = spl5(); E.Inoue */ if (cc->interrupt & CC_INT_LAM) { cc->interrupt &= ~CC_INT_LAM; return 0; } /* mutex_enter(&cc->mutex); E.Inoue */ /* start MUTEX */ /* E.Inoue drv_getparm(LBOLT, &tick); */ #ifdef CC_SPARC_LIST_EXTENSION /* E.Inoue timeout = tick + cc->a_reg * hz; */ cmn_err(CE_NOTE," cc_waitint: set timeout: cc->a_reg = 0x%x", cc->a_reg); cc->timeout_id = timeout(cc_timeout, (caddr_t)&unit, cc->a_reg * hz); #else /* E.Inoue timeout = tick + CC_TIMEOUT_LAM * hz; */ cc->timeout_id = timeout(cc_timeout, (caddr_t)&unit, CC_TIMEOUT_LAM * hz); #endif /* wait interrupt */ /* E.Inoue if (cv_timedwait(&cc->cv, &cc->mutex, timeout) == 0) cc->interrupt |= CC_INT_TIMEOUT; end */ cmn_err(CE_NOTE," cc_waitint: before cv_wait_sig"); if (cv_wait_sig(&cc->cv, &cc->mutex) == 0) { untimeout(cc->timeout_id); mutex_exit(&cc->mutex); /* end MUTEX */ return EINTR; } mutex_exit(&cc->mutex); /* end MUTEX */ /* splx(s); E.Inoue */ cmn_err(CE_NOTE," cc_waitint: after cv_wait_sig"); if (cc->interrupt & CC_INT_LAM) { cc->interrupt &= ~CC_INT_LAM; return 0; } else if( cc->interrupt & CC_INT_TIMEOUT ) { cc->interrupt &= ~CC_INT_TIMEOUT; return CC_STA_LIST_TIMEOUT; } } /* int cc_waitevent(cc) E.Inoue */ int cc_waitevent(int unit) /* struct cc_device *cc; E.Inoue */ { /* E.Inoue */ struct cc_device *cc; /* end */ int s; /* E.Inoue u_long tick, timeout; */ /* E.Inoue */ cc = ddi_get_soft_state(cc_state,unit); mutex_enter(&cc->mutex); /* start MUTEX */ /* end */ cc->interrupt = 0; cc->k->lamc = CC_INT_AUTO_CLEAR | CC_INT_ENABLE | intrpri; /* lock out clock */ /* s = spl5(); E.Inoue */ if (cc->interrupt & CC_INT_LAM) { cc->interrupt &= ~CC_INT_LAM; cc->event_count++; return 0; } /* mutex_enter(&cc->mutex); E.Inoue */ /* start MUTEX */ /* drv_getparm(LBOLT, &tick); */ #ifdef CC_SPARC_LIST_EXTENSION /* E.Inoue timeout = tick + cc->a_reg * hz; */ cc->timeout_id = timeout(cc_timeout, (caddr_t)&unit, cc->a_reg * hz); #else /* E.Inoue timeout = tick + CC_TIMEOUT_LAM * hz; */ cc->timeout_id = timeout(cc_timeout, (caddr_t)&unit, CC_TIMEOUT_LAM * hz); #endif /* wait interrupt */ /* E.Inoue if (cv_timedwait(&cc->cv, &cc->mutex, timeout) == 0) cc->interrupt |= CC_INT_TIMEOUT; */ if (cv_wait_sig(&cc->cv, &cc->mutex) == 0) { untimeout(cc->timeout_id); mutex_exit(&cc->mutex); /* end MUTEX */ return EINTR; } mutex_exit(&cc->mutex); /* end MUTEX */ /* splx(s); E.Inoue */ if (cc->interrupt & CC_INT_LAM) { cc->interrupt &= ~CC_INT_LAM; cc->event_count++; return 0; } else if( cc->interrupt & CC_INT_TIMEOUT ) { cc->interrupt &= ~CC_INT_TIMEOUT; return CC_STA_LIST_TIMEOUT; } } : (4-2). ccドライバの再構成 & インタラプト例題プログラムの実行 onl50t[84]% pwd /export/home/onl50t/inoue/CAMAC/Driver/Kit-test/CAMAC-list/FORCE-50T-sol2.6 onl50t[85]% make clean \rm -f cc *.o libcamac.a cam1 cam2 cam3 *~ core onl50t[86]% make ./script/cc_build.sh [Building for sun4u] 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 f77 -fast -O3 -u cam2.f -o cam2 -I. -L. -lcamac cam2.f: MAIN: cc -O cam3.c -o cam3 -I. -L. -lcamac onl50t[87]% onl50t# make unload ./script/cc_unload.sh [Removing CAMAC device driver] [Removing CAMAC device driver from system] [Deleting CAMAC device files] onl50t# make load ./script/cc_load.sh [Installing CAMAC device driver] [Adding CAMAC device driver to system] [Configuring CAMAC device driver] [Making CAMAC device files] sun4u onl50t# onl50t[99]% camtest5c1 CamReaLIST : OK lenlist = 52 list = 20b 0 10c 10d ef7a6080 CamLisExeWAIt : OK contents of iosb : iosb.status = fffffff5 iosb.ret_length = 0 iosb.s_reg = f iosb.devinfo = c0a2 c0a2 contents of buffer : 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 onl50t[100]% CAMAC device driver V1.4x, 1991-1993 by Y.TAKEUCHI (T.I.T.) cc0 at vme0: vme16d16 0xff00 VME level 4 vector 0xff sparc ipl 7 NOTICE: cc_write: CC_CMD_LOADDOLIST: enter CC_CMD_LOADDOLIST NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, code = 0xb NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, cc->status = 0x0 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, code = 0xc NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, cc->status = 0x0 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, code = 0xd NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, cc->status = 0x0 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, code = 0xf NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, cc->status = 0x0 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, code = 0xe NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, cc->status = 0x0 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, code = 0x10 NOTICE: cc_enbint: NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, cc->status = 0x0 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, code = 0x2b NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, cc->status = 0x0 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, code = 0x9 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, cc->status = 0x0 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, code = 0x53 NOTICE: cc_waitint: enter NOTICE: cc_waitint: set timeout: cc->a_reg = 0x0 NOTICE: cc_waitint: before cv_wait_sig NOTICE: cc_waitint: after cv_wait_sig NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, cc->status = 0xfffffff5 NOTICE: cc_write: CC_CMD_LOADDOLIST: out while, cc->status = 0xfffffff5 NOTICE: cc_write: CC_CMD_LOADDOLIST: out while #2, cc->status = 0xfffffff5 camtest5c1プログラムを起動すると timeout時間を待つこともしないで瞬時に camtest5c1プログラムは終了してしまった。 timeoutの設定に問題がありそう。 コンソール上のメッセージを見ると、wait すべき clock ticks数がゼロに なっている。 cc_waitint を実行する前に Aレジスタに必要な ticks数をセット する必要がありそうだ。 上記(3-1)で実行した時には cc_waitint のところで、少しだけ wait が入った がこれはたまたまゴミデータが Aレジスタにあった為か。 (4-3). camtest4int.asmファイルを修正して再実行 onl50t[92]% vi camtest4int.asm : ; File name : camtest4int.asm ; Creation date : July 1992 ; Author : Y.Yasu, Online group, Physics department, KEK ; Modified : Jul 26,2000 E.Inoue SW equ 3 ; CAMAC SWITCH REGISTER MEM equ 4 ; CAMAC BUFFER MEMORY MOUDLE INT equ 5 ; CAMAC INTERRUPT REGISTER LEN equ 10 ; 10 words ; SETCRATE #0 GENZ GENC SETI REMI ; ENBINT MOVE.l #1000,T NDT (26,INT,0) ; LOOPIN1 WAITINT LOOPIN1 MOVE.l #0xa,A WAITINT ; GENC NDT (9,INT,0) MOVE.l T,A WRITE.l A,(16,SW,0) SUB #1,T BGT #0,LOOPIN1 LOAD COUNT MOVE.l A,(PTR)+ LOAD PTR MOVE.l A,(PTR)+ MOVE.l #1000,T ;LOOPIN2 WAITEVENT LOOPIN2 MOVE.l #0xa,A WAITEVENT ; GENC NDT (9,INT,0) MOVE.l T,A WRITE.l A,(16,SW,0) SUB #1,T BGT #0,LOOPIN2 LOAD COUNT MOVE.l A,(PTR)+ LOAD PTR MOVE.l A,(PTR)+ DSBINT ; STOP end onl50t[93]% nl50t[99]% rm camtest4int.obj onl50t[100]% make camtest4int.obj ../camasm/camasm camtest4int.asm CAMASM macro assembler V0.1 --- KEK online group --- Modified by Y.T Oct-1991 onl50t[101]% onl50t[101]% camtest5c1 CamReaLIST : OK lenlist = 58 list = 20b 0 10c 10d ef7a6080 <---- ここで wait するようになった。 CamLisExeWAIt : OK contents of iosb : iosb.status = fffffff5 iosb.ret_length = 0 iosb.s_reg = f iosb.devinfo = c0a2 c0a2 contents of buffer : 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 onl50t[102]% NOTICE: cc_write: CC_CMD_LOADDOLIST: enter CC_CMD_LOADDOL IST NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, code = 0xb NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, cc->status = 0x0 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, code = 0xc NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, cc->status = 0x0 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, code = 0xd NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, cc->status = 0x0 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, code = 0xf NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, cc->status = 0x0 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, code = 0xe NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, cc->status = 0x0 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, code = 0x10 NOTICE: cc_enbint: NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, cc->status = 0x0 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, code = 0x2b NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, cc->status = 0x0 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, code = 0x9 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, cc->status = 0x0 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, code = 0x29 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, cc->status = 0x0 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, code = 0x53 NOTICE: cc_waitint: enter NOTICE: cc_waitint: set timeout: cc->a_reg = 0xa NOTICE: cc_waitint: before cv_wait_sig NOTICE: cc_waitint: after cv_wait_sig NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, cc->status = 0xfffffff5 NOTICE: cc_write: CC_CMD_LOADDOLIST: out while, cc->status = 0xfffffff5 NOTICE: cc_write: CC_CMD_LOADDOLIST: out while #2, cc->status = 0xfffffff5 ok. Aレジスタに ticks数 0xa をセットしてから timeout を設定するように 変更したら、数秒間 wait が行われるようになった。 しかし、依然として LAM 割り込みはかからない。 (4-4). camtest4int.asmファイルを修正して再実行 スイッチレジスタに対してアクセスしてみる。 cam1プログラムでアクセスする 場合と、camtest5c1プログラムでアクセスする場合とでどのような違いがある か調べる。 : ; File name : camtest4int.asm ; Creation date : July 1992 ; Author : Y.Yasu, Online group, Physics department, KEK ; Modified : Jul 26,2000 E.Inoue SW equ 3 ; CAMAC SWITCH REGISTER MEM equ 4 ; CAMAC BUFFER MEMORY MOUDLE INT equ 5 ; CAMAC INTERRUPT REGISTER LEN equ 10 ; 10 words ; SETCRATE #0 GENZ GENC SETI REMI ; ; MOVE #0x3,A ; ENBINT ; MOVE.l #1000,T MOVE.l #3,T ; NDT (10,SW,0) NDT (26,SW,0) ; LOOPIN1 WAITINT LOOPIN1 MOVE #0xa,A WAITINT ; GENC NDT (10,SW,0) MOVE.l T,A WRITE.l A,(16,SW,0) SUB #1,T BGT #0,LOOPIN1 LOAD COUNT MOVE.l A,(PTR)+ LOAD PTR MOVE.l A,(PTR)+ ; MOVE.l #1000,T MOVE.l #3,T ;LOOPIN2 WAITEVENT LOOPIN2 MOVE #0xa,A WAITEVENT ; GENC NDT (10,SW,0) MOVE.l T,A WRITE.l A,(16,SW,0) SUB #1,T BGT #0,LOOPIN2 LOAD COUNT MOVE.l A,(PTR)+ LOAD PTR MOVE.l A,(PTR)+ DSBINT ; STOP end : cam1プログラムを使って、スイッチレジスタを LAM enable した時の様子。 onl50t[47]% cam1 Input n a f (data)>3 0 26 N=3 A=0 F=26 Q=1 X=1 Data:000005(Hex) 00000005(Dec) Input n a f (data)>^Conl50t[48]% camac_s: mode = 0x0 NOTICE: camac_s: naf = 0x3c01 NOTICE: camac_s: mode = 0x0 NOTICE: camac_s: naf = 0x3c11 NOTICE: camac_s: mode = 0x0 NOTICE: camac_s: naf = 0x3c01 NOTICE: camac_s: mode = 0x0 NOTICE: camac_s: naf = 0x3c11 NOTICE: camac_s: mode = 0x0 NOTICE: camac_s: naf = 0x3c01 NOTICE: camac_s: mode = 0x0 NOTICE: camac_s: naf = 0x3c11 NOTICE: camac_s: mode = 0x0 NOTICE: camac_s: naf = 0x3c01 NOTICE: camac_s: mode = 0x0 NOTICE: camac_s: naf = 0x3c11 NOTICE: camac_s: mode = 0x0 <--- N=3,SA=0,F=26 を実行した時に値 NOTICE: camac_s: naf = 0x61a <--- N=3,SA=0,F=26 を実行した時に値 camtest5c1プログラムを使って、スイッチレジスタを LAM enable した時の 様子。 onl50t[45]% camtest5c1 CamReaLIST : OK lenlist = 57 list = 20b 0 10c 10d ef7a6080 CamLisExeWAIt : OK contents of iosb : iosb.status = fffffff5 iosb.ret_length = 0 iosb.s_reg = f iosb.devinfo = a000 a0 contents of buffer : 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 onl50t[46]% NOTICE: cc_write: CC_CMD_LOADDOLIST: enter CC_CMD_LOADDOL IST NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, code = 0xb NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, cc->status = 0x0 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, code = 0xc NOTICE: camac_s: mode = 0x0 NOTICE: camac_s: naf = 0x3c01 NOTICE: camac_s: mode = 0x0 NOTICE: camac_s: naf = 0x3c11 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, cc->status = 0x0 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, code = 0xd NOTICE: camac_s: mode = 0x0 NOTICE: camac_s: naf = 0x3c01 NOTICE: camac_s: mode = 0x0 NOTICE: camac_s: naf = 0x3c11 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, cc->status = 0x0 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, code = 0xf NOTICE: camac_s: mode = 0x0 NOTICE: camac_s: naf = 0x3c01 NOTICE: camac_s: mode = 0x0 NOTICE: camac_s: naf = 0x3c11 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, cc->status = 0x0 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, code = 0xe NOTICE: camac_s: mode = 0x0 NOTICE: camac_s: naf = 0x3c01 NOTICE: camac_s: mode = 0x0 NOTICE: camac_s: naf = 0x3c11 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, cc->status = 0x0 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, code = 0x2b NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, cc->status = 0x0 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, code = 0x9 NOTICE: camac_s: mode = 0x2 <--- N=3,SA=0,F=26を実行した時の値 NOTICE: camac_s: naf = 0x61a <--- N=3,SA=0,F=26を実行した時の値 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, cc->status = 0x0 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, code = 0x29 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, cc->status = 0x0 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, code = 0x53 NOTICE: cc_waitint: enter NOTICE: cc_waitint: set timeout: cc->a_reg = 0xa NOTICE: cc_waitint: before cv_wait_sig NOTICE: cc_waitint: after cv_wait_sig NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, cc->status = 0xfffffff5 NOTICE: cc_write: CC_CMD_LOADDOLIST: out while, cc->status = 0xfffffff5 NOTICE: cc_write: CC_CMD_LOADDOLIST: out while #2, cc->status = 0xfffffff5 cam1プログラムでN=3,SA=0,F=26を実行した時には、camac_s()ルーチンに mode = 0x0 が渡されているが、camtest5c1プログラムでN=3,SA=0,F=26を実行 した時には、mode = 0x2 が渡されている。 (4-5). cc.cファイルを修正して再実行 : /* cc_ndt(cc) E.Inoue */ cc_ndt(int unit) /* struct cc_device *cc; E.Inoue */ { /* E.Inoue */ struct cc_device *cc; /* end */ u_short dummy; /* E.Inoue */ cc = ddi_get_soft_state(cc_state,unit); /* end */ /* return camac_s(getminor(cc->dev), CC_BIT16, cc->ptr_list[1], &dummy); E.In oue */ return camac_s(unit, CC_BIT24, cc->ptr_list[1], &dummy); } : onl50t[57]% cam1 Input n a f (data)>3 0 26 N=3 A=0 F=26 Q=1 X=1 Data:000005(Hex) 00000005(Dec) Input n a f (data)>^Conl50t[58]% NOTICE: camac_s: mode = 0x0 NOTICE: camac_s: naf = 0x3c01 NOTICE: camac_s: mode = 0x0 NOTICE: camac_s: naf = 0x3c11 NOTICE: camac_s: mode = 0x0 NOTICE: camac_s: naf = 0x3c01 NOTICE: camac_s: mode = 0x0 NOTICE: camac_s: naf = 0x3c11 NOTICE: camac_s: mode = 0x0 NOTICE: camac_s: naf = 0x3c01 NOTICE: camac_s: mode = 0x0 NOTICE: camac_s: naf = 0x3c11 NOTICE: camac_s: mode = 0x0 NOTICE: camac_s: naf = 0x3c01 NOTICE: camac_s: mode = 0x0 NOTICE: camac_s: naf = 0x3c11 NOTICE: camac_s: mode = 0x0 NOTICE: camac_s: naf = 0x61a onl50t[49]% camtest5c1 CamReaLIST : OK lenlist = 57 list = 20b 0 10c 10d ef7a6080 CamLisExeWAIt : OK contents of iosb : iosb.status = fffffff5 iosb.ret_length = 0 iosb.s_reg = f iosb.devinfo = a000 a0 contents of buffer : 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 onl50t[50]% NOTICE: cc_write: CC_CMD_LOADDOLIST: enter CC_CMD_LOADDOL IST NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, code = 0xb NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, cc->status = 0x0 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, code = 0xc NOTICE: camac_s: mode = 0x0 NOTICE: camac_s: naf = 0x3c01 NOTICE: camac_s: mode = 0x0 NOTICE: camac_s: naf = 0x3c11 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, cc->status = 0x0 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, code = 0xd NOTICE: camac_s: mode = 0x0 NOTICE: camac_s: naf = 0x3c01 NOTICE: camac_s: mode = 0x0 NOTICE: camac_s: naf = 0x3c11 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, cc->status = 0x0 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, code = 0xf NOTICE: camac_s: mode = 0x0 NOTICE: camac_s: naf = 0x3c01 NOTICE: camac_s: mode = 0x0 NOTICE: camac_s: naf = 0x3c11 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, cc->status = 0x0 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, code = 0xe NOTICE: camac_s: mode = 0x0 NOTICE: camac_s: naf = 0x3c01 NOTICE: camac_s: mode = 0x0 NOTICE: camac_s: naf = 0x3c11 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, cc->status = 0x0 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, code = 0x2b NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, cc->status = 0x0 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, code = 0x9 NOTICE: camac_s: mode = 0x0 NOTICE: camac_s: naf = 0x61a NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, cc->status = 0x0 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, code = 0x29 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, cc->status = 0x0 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, code = 0x53 NOTICE: cc_waitint: enter NOTICE: cc_waitint: set timeout: cc->a_reg = 0xa NOTICE: cc_waitint: before cv_wait_sig NOTICE: cc_waitint: after cv_wait_sig NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, cc->status = 0xfffffff5 NOTICE: cc_write: CC_CMD_LOADDOLIST: out while, cc->status = 0xfffffff5 NOTICE: cc_write: CC_CMD_LOADDOLIST: out while #2, cc->status = 0xfffffff5 ok. camtest5c1 を実行時に camac_s()ルーチンには mode = 0x0 が渡される ようになった。 cc_waitint時にスイッチレジスタモジュールから LAM を発行 しても クレートコントローラの SLP LED は点灯しない。 注. 選択された LAMが出された時に SLP LED は点灯する。 enbint()ルーチンに問題ありか。 チェック。 リスト処理を使わないで LAM割り込み処理をやった場合の CCIOC_ENABLE_LAM コマンドの辺りをトレースする。 NOTICE: ioctl: CCIOC_ENABLE_LAM: cc->data1 = 0x4 NOTICE: camac_s: cc->cur_crate = 0x0 NOTICE: camac_s: mode = 0x0 NOTICE: camac_s: naf = 0x3db1 NOTICE: camac_s: cc->cur_crate = 0x0 NOTICE: camac_s: mode = 0x2 NOTICE: camac_s: naf = 0x3c01 NOTICE: ioctl: CCIOC_ENABLE_LAM: sdat = 0x100 NOTICE: camac_s: cc->cur_crate = 0x0 NOTICE: camac_s: mode = 0x2 NOTICE: camac_s: naf = 0x3c11 NOTICE: cc_ioctl: CCIOC_WAIT_LAM: before cv_wait_sig: cc->data1 = 0xa NOTICE: CC_intr: cc->interrupt = 0xf NOTICE: cc_ioctl: CCIOC_WAIT_LAM: after cv_wait_sig NOTICE: camac_s: cc->cur_crate = 0x0 NOTICE: camac_s: mode = 0x0 NOTICE: camac_s: naf = 0x60a NOTICE: cc_ioctl: CCIOC_WAIT_LAM: before cv_wait_sig: cc->data1 = 0xa NOTICE: CC_timeout: enter NOTICE: cc_ioctl: CCIOC_WAIT_LAM: after cv_wait_sig NOTICE: camac_s: cc->cur_crate = 0x0 NOTICE: camac_s: mode = 0x0 NOTICE: camac_s: naf = 0x60a NOTICE: camac_s: cc->cur_crate = 0x0 NOTICE: camac_s: mode = 0x0 NOTICE: camac_s: naf = 0x3db1 NOTICE: camac_s: cc->cur_crate = 0x0 NOTICE: camac_s: mode = 0x2 NOTICE: camac_s: naf = 0x3c01 NOTICE: camac_s: cc->cur_crate = 0x0 NOTICE: camac_s: mode = 0x2 NOTICE: camac_s: naf = 0x3c11 リスト処理を使って LAM割り込み処理をやった場合の cc_enbint()ルーチン の辺りをトレースする。 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, code = 0x10 NOTICE: cc_enbint: enter NOTICE: cc_enbint: cc->data1 = 0x3 NOTICE: camac_s: cc->cur_crate = 0x0 NOTICE: camac_s: mode = 0x0 NOTICE: camac_s: naf = 0x3db1 NOTICE: camac_s: cc->cur_crate = 0x0 NOTICE: camac_s: mode = 0x2 NOTICE: camac_s: naf = 0x3c01 NOTICE: cc_enbint: sdat = 0x100 NOTICE: camac_s: cc->cur_crate = 0x0 NOTICE: camac_s: mode = 0x2 NOTICE: camac_s: naf = 0x3c11 : NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, code = 0x53 NOTICE: cc_waitint: enter NOTICE: cc_waitint: set timeout: cc->a_reg = 0xa NOTICE: cc_waitint: before cv_wait_sig NOTICE: CC_timeout: enter NOTICE: cc_waitint: after cv_wait_sig NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, cc->status = 0xfffffff5 リスト処理を使わないで LAM割り込み処理をやった場合の CCIOC_ENABLE_LAM コマンドの部分では、"Write LAM Mask"、NAF(30,13,17)を実行時のデータが cc->data1 = 0x4 になっているのに対して、リスト処理を使って LAM割り込み 処理をやった場合の cc_enbint()ルーチンでの "Write LAM Mask"、 NAF(30,13,17)を実行時のデータが cc->data1 = 0x3 になっている。 LAM Mask データを指定し間違えている。 現在、スイッチレジスタ・モジュールは camac ステーション#3にセットしてある。 従って、LAM Maskデータは 0x4 に 設定するのが正しい。 bit 4 3 2 1 --+--------+--------+---------+ | | | 0 1 0 0 | --+--------+--------+---------+ station number 3 camtest4int.asmファイルを修正して再度 camtest5c1プログラムを実行する。 : MOVE #0x4,A ENBINT : onl50t[75]% rm camtest4int.obj onl50t[76]% make camtest4int.obj ../camasm/camasm camtest4int.asm CAMASM macro assembler V0.1 --- KEK online group --- Modified by Y.T Oct-1991 onl50t[77]% onl50t[82]% camtest5c1 CamReaLIST : OK lenlist = 61 list = 20b 0 10c 10d ef7a6080 <---- ここで wait している間に、スイッチレジスタ モジュールのマニュアル LAM ボタンを 6回 以上押した。 CamLisExeWAIt : OK contents of iosb : iosb.status = fffffff6 iosb.ret_length = 8 iosb.s_reg = f iosb.devinfo = a000 a0 contents of buffer : 0 f 0 2 0 12 0 6 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 onl50t[83]% NOTICE: cc_write: CC_CMD_LOADDOLIST: enter CC_CMD_LOADDOL IST NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, code = 0xb NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, cc->status = 0x0 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, code = 0xc NOTICE: camac_s: cc->cur_crate = 0x0 NOTICE: camac_s: mode = 0x0 NOTICE: camac_s: naf = 0x3c01 NOTICE: camac_s: cc->cur_crate = 0x0 NOTICE: camac_s: mode = 0x0 NOTICE: camac_s: naf = 0x3c11 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, cc->status = 0x0 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, code = 0xd NOTICE: camac_s: cc->cur_crate = 0x0 NOTICE: camac_s: mode = 0x0 NOTICE: camac_s: naf = 0x3c01 NOTICE: camac_s: cc->cur_crate = 0x0 NOTICE: camac_s: mode = 0x0 NOTICE: camac_s: naf = 0x3c11 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, cc->status = 0x0 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, code = 0xf NOTICE: camac_s: cc->cur_crate = 0x0 NOTICE: camac_s: mode = 0x0 NOTICE: camac_s: naf = 0x3c01 NOTICE: camac_s: cc->cur_crate = 0x0 NOTICE: camac_s: mode = 0x0 NOTICE: camac_s: naf = 0x3c11 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, cc->status = 0x0 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, code = 0xe NOTICE: camac_s: cc->cur_crate = 0x0 NOTICE: camac_s: mode = 0x0 NOTICE: camac_s: naf = 0x3c01 NOTICE: camac_s: cc->cur_crate = 0x0 NOTICE: camac_s: mode = 0x0 NOTICE: camac_s: naf = 0x3c11 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, cc->status = 0x0 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, code = 0x29 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, cc->status = 0x0 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, code = 0x10 NOTICE: cc_enbint: enter NOTICE: cc_enbint: cc->data1 = 0x4 NOTICE: camac_s: cc->cur_crate = 0x0 NOTICE: camac_s: mode = 0x0 NOTICE: camac_s: naf = 0x3db1 NOTICE: camac_s: cc->cur_crate = 0x0 NOTICE: camac_s: mode = 0x2 NOTICE: camac_s: naf = 0x3c01 NOTICE: cc_enbint: sdat = 0x100 NOTICE: camac_s: cc->cur_crate = 0x0 NOTICE: camac_s: mode = 0x2 NOTICE: camac_s: naf = 0x3c11 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, cc->status = 0x0 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, code = 0x2b NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, cc->status = 0x0 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, code = 0x9 NOTICE: camac_s: cc->cur_crate = 0x0 NOTICE: camac_s: mode = 0x0 NOTICE: camac_s: naf = 0x61a NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, cc->status = 0x0 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, code = 0x29 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, cc->status = 0x0 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, code = 0x53 NOTICE: cc_waitint: enter NOTICE: cc_waitint: set timeout: cc->a_reg = 0xa NOTICE: cc_waitint: before cv_wait_sig NOTICE: CC_intr: cc->interrupt = 0xf NOTICE: cc_waitint: after cv_wait_sig NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, cc->status = 0x0 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, code = 0x9 NOTICE: camac_s: cc->cur_crate = 0x0 NOTICE: camac_s: mode = 0x0 NOTICE: camac_s: naf = 0x60a NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, cc->status = 0x0 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, code = 0x27 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, cc->status = 0x0 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, code = 0x8 NOTICE: camac_s: cc->cur_crate = 0x0 NOTICE: camac_s: mode = 0x0 NOTICE: camac_s: naf = 0x610 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, cc->status = 0x0 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, code = 0x4a NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, cc->status = 0x0 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, code = 0x58 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, cc->status = 0x0 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, code = 0x29 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, cc->status = 0x0 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, code = 0x53 NOTICE: cc_waitint: enter NOTICE: cc_waitint: set timeout: cc->a_reg = 0xa NOTICE: cc_waitint: before cv_wait_sig NOTICE: CC_intr: cc->interrupt = 0xf NOTICE: cc_waitint: after cv_wait_sig NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, cc->status = 0x0 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, code = 0x9 NOTICE: camac_s: cc->cur_crate = 0x0 NOTICE: camac_s: mode = 0x0 NOTICE: camac_s: naf = 0x60a NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, cc->status = 0x0 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, code = 0x27 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, cc->status = 0x0 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, code = 0x8 NOTICE: camac_s: cc->cur_crate = 0x0 NOTICE: camac_s: mode = 0x0 NOTICE: camac_s: naf = 0x610 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, cc->status = 0x0 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, code = 0x4a NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, cc->status = 0x0 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, code = 0x58 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, cc->status = 0x0 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, code = 0x29 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, cc->status = 0x0 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, code = 0x53 NOTICE: cc_waitint: enter NOTICE: cc_waitint: set timeout: cc->a_reg = 0xa NOTICE: cc_waitint: before cv_wait_sig NOTICE: CC_intr: cc->interrupt = 0xf NOTICE: cc_waitint: after cv_wait_sig NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, cc->status = 0x0 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, code = 0x9 NOTICE: camac_s: cc->cur_crate = 0x0 NOTICE: camac_s: mode = 0x0 NOTICE: camac_s: naf = 0x60a NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, cc->status = 0x0 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, code = 0x27 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, cc->status = 0x0 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, code = 0x8 NOTICE: camac_s: cc->cur_crate = 0x0 NOTICE: camac_s: mode = 0x0 NOTICE: camac_s: naf = 0x610 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, cc->status = 0x0 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, code = 0x4a NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, cc->status = 0x0 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, code = 0x58 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, cc->status = 0x0 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, code = 0x36 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, cc->status = 0x0 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, code = 0x2d NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, cc->status = 0x0 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, code = 0x33 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, cc->status = 0x0 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, code = 0x2d NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, cc->status = 0x0 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, code = 0x2b NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, cc->status = 0x0 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, code = 0x29 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, cc->status = 0x0 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, code = 0x54 NOTICE: CC_intr: cc->interrupt = 0xf NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, cc->status = 0x0 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, code = 0x9 NOTICE: camac_s: cc->cur_crate = 0x0 NOTICE: camac_s: mode = 0x0 NOTICE: camac_s: naf = 0x60a NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, cc->status = 0x0 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, code = 0x27 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, cc->status = 0x0 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, code = 0x8 NOTICE: camac_s: cc->cur_crate = 0x0 NOTICE: camac_s: mode = 0x0 NOTICE: camac_s: naf = 0x610 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, cc->status = 0x0 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, code = 0x4a NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, cc->status = 0x0 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, code = 0x58 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, cc->status = 0x0 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, code = 0x29 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, cc->status = 0x0 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, code = 0x54 NOTICE: CC_intr: cc->interrupt = 0xf NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, cc->status = 0x0 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, code = 0x9 NOTICE: camac_s: cc->cur_crate = 0x0 NOTICE: camac_s: mode = 0x0 NOTICE: camac_s: naf = 0x60a NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, cc->status = 0x0 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, code = 0x27 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, cc->status = 0x0 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, code = 0x8 NOTICE: camac_s: cc->cur_crate = 0x0 NOTICE: camac_s: mode = 0x0 NOTICE: camac_s: naf = 0x610 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, cc->status = 0x0 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, code = 0x4a NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, cc->status = 0x0 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, code = 0x58 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, cc->status = 0x0 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, code = 0x29 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, cc->status = 0x0 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, code = 0x54 NOTICE: CC_intr: cc->interrupt = 0xf NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, cc->status = 0x0 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, code = 0x9 NOTICE: camac_s: cc->cur_crate = 0x0 NOTICE: camac_s: mode = 0x0 NOTICE: camac_s: naf = 0x60a NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, cc->status = 0x0 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, code = 0x27 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, cc->status = 0x0 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, code = 0x8 NOTICE: camac_s: cc->cur_crate = 0x0 NOTICE: camac_s: mode = 0x0 NOTICE: camac_s: naf = 0x610 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, cc->status = 0x0 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, code = 0x4a NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, cc->status = 0x0 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, code = 0x58 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, cc->status = 0x0 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, code = 0x36 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, cc->status = 0x0 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, code = 0x2d NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, cc->status = 0x0 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, code = 0x33 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, cc->status = 0x0 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, code = 0x2d NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, cc->status = 0x0 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, code = 0x11 NOTICE: camac_s: cc->cur_crate = 0x0 NOTICE: camac_s: mode = 0x0 NOTICE: camac_s: naf = 0x3db1 NOTICE: camac_s: cc->cur_crate = 0x0 NOTICE: camac_s: mode = 0x2 NOTICE: camac_s: naf = 0x3c01 NOTICE: camac_s: cc->cur_crate = 0x0 NOTICE: camac_s: mode = 0x2 NOTICE: camac_s: naf = 0x3c11 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, cc->status = 0x0 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, code = 0x0 NOTICE: cc_write: CC_CMD_LOADDOLIST: in while, cc->status = 0xfffffff6 NOTICE: cc_write: CC_CMD_LOADDOLIST: out while, cc->status = 0xfffffff6 NOTICE: cc_write: CC_CMD_LOADDOLIST: out while #2, cc->status = 0xfffffff6 ok. (4-6). インタラプトモジュールを使ってテストする (4-6-1). camtest4int.asmファイルを修正 : ; File name : camtest4int.asm ; Creation date : July 1992 ; Author : Y.Yasu, Online group, Physics department, KEK ; Modified : Jul 31,2000 E.Inoue SW equ 3 ; CAMAC SWITCH REGISTER MEM equ 4 ; CAMAC BUFFER MEMORY MOUDLE INT equ 5 ; CAMAC INTERRUPT REGISTER LEN equ 10 ; 10 words ; SETCRATE #0 GENZ GENC SETI REMI ; MOVE #0x10,A ; INT module's LAM mask. Station # = 5. ENBINT MOVE.l #1000,T NDT (26,INT,0) ;LOOPIN1 WAITINT LOOPIN1 MOVE #0xa,A ; Setting up timeout time. WAITINT ; GENC NDT (9,INT,0) MOVE.l T,A WRITE.l A,(16,SW,0) SUB #1,T BGT #0,LOOPIN1 LOAD COUNT MOVE.l A,(PTR)+ LOAD PTR MOVE.l A,(PTR)+ MOVE.l #1000,T ;LOOPIN2 WAITEVENT LOOPIN2 MOVE #0xa,A ; Setting up timeout time. WAITEVENT ; GENC NDT (9,INT,0) MOVE.l T,A WRITE.l A,(16,SW,0) SUB #1,T BGT #0,LOOPIN2 LOAD COUNT MOVE.l A,(PTR)+ LOAD PTR MOVE.l A,(PTR)+ DSBINT ; STOP end : onl50t[71]% rm camtest4int.obj onl50t[72]% make camtest4int.obj ../camasm/camasm camtest4int.asm CAMASM macro assembler V0.1 --- KEK online group --- Modified by Y.T Oct-1991 onl50t[73]% onl50t[74]% cat camtest4int.obj 003D 020B 0000 010C 010D 010F 010E 0329 0010 0000 0110 032B 03E8 0000 0209 0A1A 0329 000A 0000 0153 0209 0A09 0127 0208 0610 034A 0001 0000 0458 0010 0000 0000 0136 012D 0133 012D 032B 03E8 0000 0329 000A 0000 0154 0209 0A09 0127 0208 0610 034A 0001 0000 0458 0027 0000 0000 0136 012D 0133 012D 0111 0100 onl50t[75]% (4-6-2). cc.cファイルを修正して再実行 この例題プログラムでは、割り込みが 2000回かかるので、デバッグ用の出力文 が邪魔になる。 コメントアウトしておく。 onl50t[75]% make clean \rm -f cc *.o libcamac.a cam1 cam2 cam3 *~ core onl50t[76]% make ./script/cc_build.sh [Building for sun4u] 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 f77 -fast -O3 -u cam2.f -o cam2 -I. -L. -lcamac cam2.f: MAIN: cc -O cam3.c -o cam3 -I. -L. -lcamac onl50t[77]% onl50t# make unload ./script/cc_unload.sh [Removing CAMAC device driver] [Removing CAMAC device driver from system] [Deleting CAMAC device files] onl50t# make load ./script/cc_load.sh [Installing CAMAC device driver] [Adding CAMAC device driver to system] [Configuring CAMAC device driver] [Making CAMAC device files] sun4u onl50t# onl50t[76]% camtest5c1 CamReaLIST : OK lenlist = 61 list = 20b 0 10c 10d ef7a6080 CamLisExeWAIt : OK contents of iosb : iosb.status = fffffff6 iosb.ret_length = 8 iosb.s_reg = f iosb.devinfo = a000 a0 contents of buffer : 0 0 0 2 0 3e8 0 6 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 onl50t[77]% onl50t[77]% onl50t[77]% camtest5c1 CamReaLIST : OK lenlist = 61 list = 20b 0 10c 10d ef7a6080 CamLisExeWAIt : OK contents of iosb : iosb.status = fffffff6 iosb.ret_length = 8 iosb.s_reg = f iosb.devinfo = a000 a0 contents of buffer : 0 3e8 0 2 0 7d0 0 6 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 onl50t[78]% CAMAC device driver V1.4x, 1991-1993 by Y.TAKEUCHI (T.I.T.) cc0 at vme0: vme16d16 0xff00 VME level 4 vector 0xff sparc ipl 7 NOTICE: cc_enbint: enter NOTICE: cc_enbint: cc->data1 = 0x10 NOTICE: cc_enbint: sdat = 0x100 onl50t console login: onl50t console login: onl50t console login: onl50t console login: NOTICE: cc_enbint: enter NOTICE: cc_enbint: cc->data1 = 0x10 NOTICE: cc_enbint: sdat = 0x100 注. 0x3e8 = 1000(dec) 0x7d0 = 2000(dec) ok. インタラプト・モジュールを使った、KEKリスト処理による LAM割り込み 処理は正常に実行できた (6). 関連する man 等 (6-1). timeout(9f) Kernel Functions for Drivers timeout(9F) NAME timeout - execute a function after a specified length of time SYNOPSIS #include #include int timeout(void (*func )(), caddr_t arg, clock_t ticks); INTERFACE LEVEL Architecture independent level 1 (DDI/DKI). ARGUMENTS func Kernel function to invoke when the time increment expires. arg Argument to the function. ticks Number of clock ticks to wait before the function is called. DESCRIPTION The timeout() function schedules the specified function to be called after a specified time interval. The exact time interval over which the timeout takes effect cannot be guaranteed, but the value given is a close approximation. The function called by timeout() must adhere to the same restrictions as a driver soft interrupt handler. The timeout() function returns an identifier that may be passed to the untimeout(9F) function to cancel a pending request. timeout() can be called from user or interrupt context. The function called by timeout() is run in interrupt context and must not sleep or call other functions which may sleep. RETURN VALUES Under normal conditions, timeout() returns an integer timeout identifier not equal to zero. If, however, the timeout table is full, the system will panic with the fol- lowing panic message: PANIC: Timeout table overflow CONTEXT timeout() can be called from user or interrupt context. SunOS 5.6 Last change: 19 Sep 1996 1 Kernel Functions for Drivers timeout(9F) EXAMPLES In the following example, the device driver has issued an IO request and is waiting for the device to respond. If the device does not respond within 5 seconds, the device driver will print out an error message to the console. static void xxtimeout_handler(caddr_t arg) { struct xxstate *xsp = (struct xxstate *)arg; mutex_enter(&xsp->lock); cv_signal(&xsp->cv); xsp->flags |= TIMED_OUT; mutex_exit(&xsp->lock); xsp->timeout_id = 0; } static u_int xxintr(caddr_t arg) { struct xxstate *xsp = (struct xxstate *)arg; . . . mutex_enter(&xsp->lock); /* Service interrupt */ cv_signal(&xsp->cv); mutex_exit(&xsp->lock); if (xsp->timeout_id != 0) { (void) untimeout(xsp->timeout_id); xsp->timeout_id = 0; } return(DDI_INTR_CLAIMED); } static void xxcheckcond(struct xxstate *xsp) { . . . xsp->timeout_id = timeout(xxtimeout_handler, (caddr_t)xsp, 5 * drv_usectohz(1000000)); mutex_enter(&xsp->lock); while (/* Waiting for interrupt or timeout*/) SunOS 5.6 Last change: 19 Sep 1996 2 Kernel Functions for Drivers timeout(9F) cv_wait(&xsp->cv, &xsp->lock); if (xsp->flags & TIMED_OUT) cmn_err(CE_WARN, "Device not responding"); . . . mutex_exit(&xsp->lock); . . . } SEE ALSO bufcall(9F), delay(9F), untimeout(9F) Writing Device Drivers SunOS 5.6 Last change: 19 Sep 1996 3 ---xxxx ここまでやった(継続中) --- (6). 項目タイトル (6-1). サブ項目タイトル (6-1-1). サブサブ項目タイトル