アットウィキロゴ

reset_timer

名称

reset_timer -

書式

static void
reset_timer(
    unsigned long arg);

引数

arg
mic_ctx_t *

説明

カードのリセットが完了したか確認するための周回起動ハンドラ。

処理開始に、メッセージ "MIC <カード番号> Resetting (Post Code <POST コード文字列>" を出力する。

RESET_FAIL_TIME 回目に起動されたとき、context の状態を MIC_RESETFAIL にして、resetwq で待っているスレッドを起床させ、処理を終える。
カードの POST が RESET_FAILED_F2 あるいは RESET_FAILED_F4 になっていた場合、
resetworkq が設定されていればそれを使って attempt_reset を起動し、さらに自身を 1 秒後に起動するように設定し処理を終える。
resetworkq が設定されていない場合、context の状態を MIC_RESETFAIL にして、resetwq で待っているスレッドを起床させ、処理を終える。
カードの bootstrap が完了していた場合、以下の設定をし、resetwq で待っているスレッドを起床させ、処理を終える。
  • context の状態を MIC_READY にする
  • mic_enable_msi_interrupts (mic_ctx->msie != 0 の場合のみ)
  • mic_enable_interrupts
  • mic_smpt_restore
  • micscif_start

カードの bootstrap が完了しておらず、POST も RESET_FAILED_F2 でも RESET_FAILED_F4 でもなく、
RESET_FAIL_TIME 回未満の起動の場合、
1 秒後に自身が呼び出されるように設定し、処理を終える。

POST が RESET_FAILED_F2 あるいは RESET_FAILED_F4 になった場合は、
bootstrap が完了することはないと仮定。

戻り値

なし

参照


実装

host/driver/uos_download.c
927 /* Perform hardware reset of the device */
928 static void
929 reset_timer(unsigned long arg)
930 {
931         mic_ctx_t *mic_ctx = (mic_ctx_t *)arg;
932         uint32_t scratch2 = 0;
933         uint32_t postcode = mic_getpostcode(mic_ctx);
934
935         printk("MIC %d Resetting (Post Code %c%c)\n", mic_ctx->bi_id,
936                     postcode & 0xff, (postcode >> 8) & 0xff);
937         mic_ctx->reset_count++;
938
939         /* Assuming that the bootstrap takes around 90 seconds to reset,
940          * we fail after 300 seconds, thus allowing 3 attempts to reset
941          */
942         if (mic_ctx->reset_count == RESET_FAIL_TIME) {
943                 mic_ctx->reset_count = 0;
944                 mic_setstate(&mic_ctx->state, MIC_RESETFAIL);
945                 wake_up(&mic_ctx->resetwq);
946                 return;
947         }
948
949         /* check for F2 or F4 error codes from bootstrap */
950         if ((postcode == RESET_FAILED_F2) || (postcode == RESET_FAILED_F4)) {
951                 if (mic_ctx->resetworkq) {
952                         queue_work(mic_ctx->resetworkq, &mic_ctx->resetwork);
953                 } else {
954                         mic_ctx->reset_count = 0;
955                         mic_setstate(&mic_ctx->state, MIC_RESETFAIL);
956                         wake_up(&mic_ctx->resetwq);
957                         return;
958                 }
959         }
960
961         /* checking if bootstrap is ready or still resetting */
962         scratch2 = SBOX_READ(mic_ctx->mmio.va, [[SBOX_SCRATCH2]]);
963         if (SCRATCH2_DOWNLOAD_STATUS(scratch2)) {
964                 mic_ctx->boot_start = 0;
965                 mic_setstate(&mic_ctx->state, MIC_READY);
966
967                 if (mic_ctx->msie)
968                         mic_enable_msi_interrupts(mic_ctx);
969                 mic_enable_interrupts(mic_ctx);
970                 mic_smpt_restore(mic_ctx);
971                 micscif_start(mic_ctx);
972
973                 wake_up(&mic_ctx->resetwq);
974                 mic_ctx->reset_count = 0;
975                 return;
976         }
977
978         mic_ctx->boot_timer.function = reset_timer;
979         mic_ctx->boot_timer.data = (unsigned long)mic_ctx;
980         mic_ctx->boot_timer.expires = jiffies + HZ;
981
982         add_timer(&mic_ctx->boot_timer);
983 }

起動直後に呼び出し回数のチェックをしているので、最後の 1 秒間の間に bootstrap が完了したときに、リセット失敗と判断してしまう。
977 行目付近で回数チェックをするのが好みなのだが、そうすると 952 行目で resetwork を起動していた時面倒そう。
最終更新:2012年11月18日 17:05