Jun 18, 1999 onl50t: Solaris 2.6 cc ドライバのデバッグ. cc ドライバのデバッグ#01(その2) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ (http://www-online.kek.jp/~inoue/CAMAC/ onl50t-sol2.6/Desktop/debug-step02.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ファイルを入手してデバッグを始めた。 (2). ここでやるべきこと icc_ioctlルーチンのデバッグをする。 (3). icc_ioctlルーチン中の splコールの見直し 株式会社ロジックハウスの高橋さんからのメール。 ---ここから >spl5()、splx(s)はSunOS4.xでは使用していましたが >Solaris2.xへ移行する際にはmutex_enter()、mutex_exit()へ >置きかえることを Solaris2.x Writing Device Driverでは >推奨しています。 >次のように変更するのが望ましいかと思います。 >---------------------------------------------------------- > case CCIOC_WAIT_LAM : > cc->interrupt = 0; > cc->k->lamc = CC_INT_AUTO_CLEAR | CC_INT_ENABLE | intrpri; > >mutex_enter(&cc->mutex); /* start MUTEX */ > > if (cc->interrupt & CC_INT_LAM) { > cc->interrupt &= ~CC_INT_LAM; > return 0; > } > >cc->timeout_id = timeout(cc_timeout, (caddr_t)&unit, *(int *)data * hz); > > /* wait interrupt */ >/* > cv_timedwait(&cc->cv, &cc->mutex, timeout); > if (cc->interrupt == 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 */ > > > if( cc->interrupt & CC_INT_LAM ) { > cc->interrupt &= ~CC_INT_LAM; > } else if( cc->interrupt & CC_INT_TIMEOUT ) { > cc->interrupt &= ~CC_INT_TIMEOUT; > return CC_STA_SINGLE_TIMEOUT; /* set value to "errno" */ > } > break; >------------------------------------------------------- ---ここまで 株式会社ロジックハウスの高橋さんからのメール(その2)。 ---ここから どうやら、ioctl()でのargの取りこみ時に copyin()を使用していないようです。 変更したcc_ioctl()を以下の示しますのでお験し下さい。 /****************************************************** * ccioctl * ******************************************************/ static int cc_ioctl(dev_t dev, int cmd, int arg, int flag, cred_t *cred_p, int *rval_p) { /* register struct cc_device *cc = &ccdevice[0]; */ register struct cc_device *cc; /* register struct K_REG *k = cc->k; */ u_short sdat; /* int idat, *data = (int *)arg; */ int idat, data; int s; minor_t unit; unit = getminor(dev); cc = ddi_get_soft_state(cc_state,unit); copyin((caddr_t)arg,(caddr_t)&data,sizeof(data)); switch (cmd) { case CCIOC_CHK_BRANCH: data = cc->max_branch; break; case CCIOC_SET_BRANCH: if (data >= 0 && data < cc->max_branch) cc->cur_branch = data; break; case CCIOC_SET_CRATE: if (data >= 0 && data < MAX_CRATE) cc->cur_crate = data; break; case CCIOC_WAIT_LAM : cc->interrupt = 0; cc->k->lamc = CC_INT_AUTO_CLEAR | CC_INT_ENABLE | intrpri; /* lock out clock */ /* by E.Inoue s = spl5(); */ if (cc->interrupt & CC_INT_LAM) { cc->interrupt &= ~CC_INT_LAM; return 0; } /* mutex_enter(&cc->mutex); */ /* start MUTEX */ cc->timeout_id = timeout(cc_timeout, (caddr_t)&unit, data * hz); mutex_enter(&cc->mutex); /* start MUTEX */ /* wait interrupt */ /* cv_timedwait(&cc->cv, &cc->mutex, timeout); if (cc->interrupt == 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 */ /* by E.Inoue splx(s); */ if( cc->interrupt & CC_INT_LAM ) { cc->interrupt &= ~CC_INT_LAM; } else if( cc->interrupt & CC_INT_TIMEOUT ) { cc->interrupt &= ~CC_INT_TIMEOUT; return CC_STA_SINGLE_TIMEOUT; /* set value to "errno" */ } break; case CCIOC_ENABLE_LAM : camac_s(unit, CC_BIT24, NAF(30, 13, 17), (u_short *)data); camac_s(unit, CC_BIT16, NAF(30, 0, 1), &sdat); sdat |= 0x100; camac_s(unit, CC_BIT16, NAF(30, 0, 17), &sdat); break; case CCIOC_DISABLE_LAM : cc->k->lamc = CC_INT_AUTO_CLEAR | intrpri; idat = 0; camac_s(unit, CC_BIT24, NAF(30, 13, 17), (u_short *)&idat); camac_s(unit, CC_BIT16, NAF(30, 0, 1), &sdat); sdat &= ~0x100; camac_s(unit, CC_BIT16, NAF(30, 0, 17), &sdat); break; case CCIOC_REG_DUMP : /* data[0] = k->cser; data[1] = k->docr; data[2] = k->sccr; data[3] = k->mtc; data[4] = k->machi; data[5] = k->maclo; data[6] = k->lamc; data[7] = k->donc; data[8] = k->empc; data[9] = k->aboc; data[10] = k->lamv; data[11] = k->donv; data[12] = k->empv; data[13] = k->abov; data[14] = k->amr; data[15] = k->cma; data[16] = k->cwc; data[17] = k->srr; data[18] = k->csr; */ break; case CCIOC_RESET : cc->k->csr = CC_RST; /* by E.Inoue from >>> */ /* set interrupt registers of K2917 */ cc->k->lamc = (u_short)(CC_INT_AUTO_CLEAR | intrpri); cc->k->donc = (u_short)(CC_INT_AUTO_CLEAR | intrpri); cc->k->empc = (u_short)(CC_INT_AUTO_CLEAR | intrpri); cc->k->aboc = (u_short)(CC_INT_AUTO_CLEAR | intrpri); cc->k->lamv = (u_short)intrvec; cc->k->donv = (u_short)intrvec; cc->k->empv = (u_short)intrvec; cc->k->abov = (u_short)intrvec; /* to <<< */ break; case CCIOC_READ_STATUS : /* data[0] = k->cser; data[1] = k->docr; data[2] = k->sccr; data[3] = k->mtc; data[4] = k->machi; data[5] = k->maclo; data[6] = k->lamc; data[7] = k->donc; data[8] = k->empc; data[9] = k->aboc; data[10] = k->lamv; data[11] = k->donv; data[12] = k->empv; data[13] = k->abov; data[14] = k->amr; data[15] = k->cma; data[16] = k->cwc; data[17] = k->srr; data[18] = k->csr; */ /* k->csr = CC_RST; */ break; case CCIOC_KINIT : ptr_dir = 0; ptr_cma = CC_KLIST_CMAINIT; break; default : break; } return 0; } ---ここまで 参考資料. (3-1). 上記の項目(3)の修正をやってみる (3-1-1). cc.cファイルを修正する onl50t[40]% vi cc.c : /****************************************************** * ccioctl * ******************************************************/ static int cc_ioctl(dev_t dev, int cmd, int arg, int flag, cred_t *cred_p, int *rval_p) { /* register struct cc_device *cc = &ccdevice[0]; */ register struct cc_device *cc; /* register struct K_REG *k = cc->k; */ u_short sdat; /* int idat, *data = (int *)arg; */ int idat, data; int s; minor_t unit; unit = getminor(dev); cc = ddi_get_soft_state(cc_state,unit); copyin((caddr_t)arg,(caddr_t)&data,sizeof(data)); switch (cmd) { case CCIOC_CHK_BRANCH: data = cc->max_branch; break; case CCIOC_SET_BRANCH: if (data >= 0 && data < cc->max_branch) cc->cur_branch = data; break; case CCIOC_SET_CRATE: if (data >= 0 && data < MAX_CRATE) cc->cur_crate = data; break; case CCIOC_WAIT_LAM : cc->interrupt = 0; cc->k->lamc = CC_INT_AUTO_CLEAR | CC_INT_ENABLE | intrpri; /* lock out clock */ /* by E.Inoue s = spl5(); */ if (cc->interrupt & CC_INT_LAM) { cc->interrupt &= ~CC_INT_LAM; return 0; } /* mutex_enter(&cc->mutex); */ /* start MUTEX */ cc->timeout_id = timeout(cc_timeout, (caddr_t)&unit, data * hz); mutex_enter(&cc->mutex); /* start MUTEX */ /* wait interrupt */ /* cv_timedwait(&cc->cv, &cc->mutex, timeout); if (cc->interrupt == 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 */ /* by E.Inoue splx(s); */ if( cc->interrupt & CC_INT_LAM ) { cc->interrupt &= ~CC_INT_LAM; } else if( cc->interrupt & CC_INT_TIMEOUT ) { cc->interrupt &= ~CC_INT_TIMEOUT; return CC_STA_SINGLE_TIMEOUT; /* set value to "errno" */ } break; case CCIOC_ENABLE_LAM : camac_s(unit, CC_BIT24, NAF(30, 13, 17), (u_short *)data); camac_s(unit, CC_BIT16, NAF(30, 0, 1), &sdat); sdat |= 0x100; camac_s(unit, CC_BIT16, NAF(30, 0, 17), &sdat); break; case CCIOC_DISABLE_LAM : cc->k->lamc = CC_INT_AUTO_CLEAR | intrpri; idat = 0; camac_s(unit, CC_BIT24, NAF(30, 13, 17), (u_short *)&idat); camac_s(unit, CC_BIT16, NAF(30, 0, 1), &sdat); sdat &= ~0x100; camac_s(unit, CC_BIT16, NAF(30, 0, 17), &sdat); break; case CCIOC_REG_DUMP : /* data[0] = k->cser; data[1] = k->docr; data[2] = k->sccr; data[3] = k->mtc; data[4] = k->machi; data[5] = k->maclo; data[6] = k->lamc; data[7] = k->donc; data[8] = k->empc; data[9] = k->aboc; data[10] = k->lamv; data[11] = k->donv; data[12] = k->empv; data[13] = k->abov; data[14] = k->amr; data[15] = k->cma; data[16] = k->cwc; data[17] = k->srr; data[18] = k->csr; */ break; case CCIOC_RESET : cc->k->csr = CC_RST; /* by E.Inoue from >>> */ /* set interrupt registers of K2917 */ cc->k->lamc = (u_short)(CC_INT_AUTO_CLEAR | intrpri); cc->k->donc = (u_short)(CC_INT_AUTO_CLEAR | intrpri); cc->k->empc = (u_short)(CC_INT_AUTO_CLEAR | intrpri); cc->k->aboc = (u_short)(CC_INT_AUTO_CLEAR | intrpri); cc->k->lamv = (u_short)intrvec; cc->k->donv = (u_short)intrvec; cc->k->empv = (u_short)intrvec; cc->k->abov = (u_short)intrvec; /* to <<< */ break; case CCIOC_READ_STATUS : /* data[0] = k->cser; data[1] = k->docr; data[2] = k->sccr; data[3] = k->mtc; data[4] = k->machi; data[5] = k->maclo; data[6] = k->lamc; data[7] = k->donc; data[8] = k->empc; data[9] = k->aboc; data[10] = k->lamv; data[11] = k->donv; data[12] = k->empv; data[13] = k->abov; data[14] = k->amr; data[15] = k->cma; data[16] = k->cwc; data[17] = k->srr; data[18] = k->csr; */ /* k->csr = CC_RST; */ break; case CCIOC_KINIT : ptr_dir = 0; ptr_cma = CC_KLIST_CMAINIT; break; default : break; } return 0; } (3-1-2). cc.cファイルをコンパイルし直す onl50t[51]% pwd /export/home/onl50t/inoue/CAMAC/Driver/FORCE-5V-sol2.5 onl50t[52]% make ./script/cc_build.sh [Building for sun4u] rm -f cc.o onl50t[53]% (3-1-3). ccドライバをロードし直す onl50t# pwd /export/home/onl50t/inoue/CAMAC/Driver/FORCE-5V-sol2.5 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# (3-1-3). cam1プログラムを実行する onl50t[38]% cam1 cam1: step1 cam1: step2 cam1: step3 cam1: step4 cam1: step5 cam1: step6 cam1: step7 Input n a f (data)>3 0 0 N=3 A=0 F=0 Q=1 X=1 Data:000000(Hex) 00000000(Dec) Input n a f (data)>3 0 16 5555 N=3 A=0 F=16 Q=1 X=1 Data:0015B3(Hex) 00005555(Dec) Input n a f (data)>3 0 0 N=3 A=0 F=0 Q=1 X=1 Data:0015B3(Hex) 00005555(Dec) Input n a f (data)>3 0 16 8888 N=3 A=0 F=16 Q=1 X=1 Data:0022B8(Hex) 00008888(Dec) Input n a f (data)>3 0 0 N=3 A=0 F=0 Q=1 X=1 Data:0022B8(Hex) 00008888(Dec) Input n a f (data)>^Conl50t[39]% onl50t[39]% onl50t[39]% onl50t[39]% cam1 5 cam1: step1 cam1: step2 cam1: step3 cam1: step4 cam1: step5 cam1: step6 cam1: step7 Input n a f (data)>3 0 0 N=3 A=0 F=0 Q=1 X=1 Data:000000(Hex) 00000000(Dec) Input n a f (data)>3 0 16 7777 N=3 A=0 F=16 Q=1 X=1 Data:001E61(Hex) 00007777(Dec) Input n a f (data)>3 0 0 N=3 A=0 F=0 Q=1 X=1 Data:001E61(Hex) 00007777(Dec) Input n a f (data)>3 0 16 3333 N=3 A=0 F=16 Q=1 X=1 Data:000D05(Hex) 00003333(Dec) Input n a f (data)>3 0 0 N=3 A=0 F=0 Q=1 X=1 Data:000D05(Hex) 00003333(Dec) onl50t[40]% ok. cam1プログラムは正常に実行できた。 ---xxxx ここまでやった(継続中) --- (6). セクション (6-1). サブセクション (6-1-1). サブサブセクション