Lions' 本読み (141)
らふてーを製造しつつ、rkintr を読む大晦日。
ええと、rkintr 手続きが続きの rkstart 手続きを呼び出しているので
- rkstart 手続きで I/O キューから取り出して要求
- devstart でレジスタに書き込み
- rkintr で後処理をして rkstart 呼び出し
という一連の処理は同期的である、という理解で良いのかな。これを前提 (?) に中身を確認してみます。とりあえず以下な部分は保険なのかどうか。
5455 if (rktab.d_active == 0) 5456 return;
で、ここからが本番なのかどうか。とりあえず I/O キューの先頭を取り出してます。
5457 bp = rktab.d_actf;
基本的には rkstart 手続き関連で処理対象になったもの、という前提か。別途割り込み関連については確認しておく必要あり。rkintr なディスク割り込みはどの程度の優先度を持って実行されるのか、とか。
で、次の行で rktab.d_active が 0 で初期化されてエラー処理な記述があります。昨日エントリの引用 (テキスト 383p な記述) にあるステイタス情報が使われています。
5458 rktab.d_active = 0; 5459 if (RKADDR->rkcs < 0) { /* エラービット */ 5460 deverror(bp, RKADDR->rker, RKADDR->rkds);
あわわ、ここの記述も凄いスね。
5461 RKADDR->rkcs = RESET|GO; 5462 while((RKADDR->rkcs&CTLRDY) == 0) ;
テキストによれば_数マイクロ秒_て。そしてリトライしたりしてますね。
5463 if (++rktab.d_errcnt <= 10) { 5464 rkstart(); 5465 return; 5466 }
10 回リトライしてそれでも駄目な場合、諦めています。ここのリトライがあるから I/O キューはこの後に再設定、ということなのか。
5467 bp->b_flags =| B_ERROR;
で、以降がある意味正常系なんですね。
5469 rktab.d_errcnt = 0; 5470 rktab.d_actf = bp->av_forw; 5471 iodone(bp); 5472 rkstart();
d_errcnt 属性を 0 にして d_actf を更新しています。I/O キューは
- d_actf が先頭
- リンクは av_forw 属性のみを使っている
- 最後尾は d_actl に格納
という規則があるみたいなんですが、d_actl てどこで使ってるのだろうか。
iodone 手続き
基本的には引数で渡される struct buf なオブジェクトについて名前の通り、_I/O が終わった_状態に、というのがテキスト 385p に記述されてます。
宿題
- rkintr な割り込みハンドラの優先度確認
- 割り込みハンドラ自体の優先度も確認
- d_actl の使途
色々ヤりながら 17 以降も読む方向ですがどうなるやら。