# 通知設計書 20-asmc SMS

## 概要

本ドキュメントは、FreeBSDカーネルにおけるACPI asmc SMS通知の設計を記述する。Apple SMC（System Management Controller）のSMS（Sudden Motion Sensor）が衝撃や自由落下を検出した際にdevctl(4)サブシステムを通じてユーザーランドに通知を送信する仕組みについて定義する。

### 本通知の処理概要

ACPI asmc SMS通知は、Apple SMCのSudden Motion Sensor（SMS）が物理的な衝撃や自由落下を検出した際にasmc_sms_task()関数内でdevctl_notifyにより発行されるカーネル通知である。SMSはMacBookやMacBook Proに搭載された加速度センサであり、ハードディスクの保護に使用される。

**業務上の目的・背景**：Apple MacBookシリーズに搭載されたSudden Motion Sensorは、デバイスの落下や強い衝撃を検出してハードディスクのヘッドを退避させる（パーキング）ための機能である。この検出イベントをユーザーランドに通知することで、ディスクヘッドの退避、データのフラッシュ、ユーザーへの警告表示などの保護アクションを実行できるようにする。

**通知の送信タイミング**：SMSハードウェア割り込みが発生し、asmc_sms_intrfast()で割り込みが処理された後、タスクキューのasmc_sms_task()内で送信される。割り込みハンドラは高速処理のため、実際の通知はタスクキュー経由で遅延実行される。

**通知の受信者**：devctl(4)デバイスをオープンしているユーザーランドプロセス。主にdevd(8)デーモンが受信する。

**通知内容の概要**：システム名「ACPI」、サブシステム名「asmc」、タイプ「SMS」、データとして割り込みタイプ（notify=0xNN：0=Shock、1=High Acceleration、2=Free Fall、255=Unknown）が通知される。

**期待されるアクション**：devd(8)がSMSイベントを検知し、ハードディスクヘッドの退避コマンドの発行、データバッファのフラッシュ、ユーザーへの警告通知などを行う。

## 通知種別

カーネルdevctl通知（devctl_notify経由）

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 非同期（devctl(4)キュー経由、タスクキュー経由） |
| 優先度 | 高（PI_REALTIME優先度でタスクキューに投入） |
| リトライ | なし |

### 送信先決定ロジック

devctl(4)デバイスファイル(/dev/devctl)をオープンしているすべてのプロセスに対してブロードキャスト送信される。

## 通知テンプレート

### devctl通知の場合

| 項目 | 内容 |
|-----|------|
| システム名 | ACPI |
| サブシステム名 | asmc |
| タイプ | SMS |
| データ | notify=0x{割り込みタイプ} |

### 本文テンプレート

```
!system=ACPI subsystem=asmc type=SMS  notify=0x{type}
```

注意：データ文字列の先頭にスペースが1つ含まれる（コード上の" notify=0x%x"フォーマット）。

### 添付ファイル

該当なし

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| type | 割り込みタイプ | sc->sc_sms_intrtype から変換 | Yes |

割り込みタイプの値：

| 割り込み種別 | 定数名 | 値 | typeマッピング |
|------------|--------|------|---------------|
| Free Fall | ASMC_SMS_INTFF | 0x60 | 2 |
| High Acceleration | ASMC_SMS_INTHA | 0x6f | 1 |
| Shock | ASMC_SMS_INTSH | 0x80 | 0 |
| Unknown | その他 | - | 255 |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| ハードウェア割り込み | SMSセンサからの割り込み | 常に送信 | asmc_sms_intrfast() -> タスクキュー -> asmc_sms_task() |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| なし | SMS割り込みが発生すれば常に通知が発行される |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[SMS割り込み発生] --> B[asmc_sms_intrfast]
    B --> C[sc_sms_intrtype記録]
    C --> D[taskqueue_enqueueでタスク登録]
    D --> E[asmc_sms_task実行]
    E --> F{sc_sms_intrtype判定}
    F -->|ASMC_SMS_INTFF 0x60| G[type = 2 Free Fall]
    F -->|ASMC_SMS_INTHA 0x6f| H[type = 1 High Acceleration]
    F -->|ASMC_SMS_INTSH 0x80| I[type = 0 Shock]
    F -->|その他| J[type = 255 Unknown]
    G --> K[notify_buf生成]
    H --> K
    I --> K
    J --> K
    K --> L[devctl_notify ACPI/asmc/SMS/notify_buf]
    L --> M[終了]
```

## データベース参照・更新仕様

該当なし（カーネル内メモリ構造体の操作のみ）

### 参照テーブル一覧

| テーブル名 | 用途 | 備考 |
|-----------|------|------|
| asmc_softc構造体 | SMCデバイス情報 | sc_sms_intrtype等 |

### テーブル別参照項目詳細

#### asmc_softc構造体

| 参照項目（カラム名） | 用途 | 取得条件 |
|-------------------|------|---------|
| sc_sms_intrtype | SMS割り込みタイプ | 割り込みハンドラで設定された値 |

### 更新テーブル一覧

該当なし（通知の発行のみ）

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| devctl送信失敗 | devctlキューが満杯 | 通知は破棄される |
| 不明な割り込みタイプ | 定義外の割り込み値 | type=255として通知 |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | なし |
| リトライ間隔 | 該当なし |
| リトライ対象エラー | 該当なし |

## 配信設定

### レート制限

| 項目 | 内容 |
|-----|------|
| 1分あたり上限 | 制限なし |
| 1日あたり上限 | 制限なし |

### 配信時間帯

制限なし。

## セキュリティ考慮事項

- devctl(4)デバイスへのアクセスにはroot権限が必要
- SMS割り込み情報は物理的な衝撃検出であり、プライバシー上のリスクは低い
- Free Fall（自由落下）検出は緊急性が高く、タスクキューのPI_REALTIME優先度で処理される

## 備考

- asmc_sms_task()関数はsys/dev/asmc/asmc.cの1531行目に定義されている
- devctl_notify()呼び出しは1552行目で行われる
- SMS割り込み定数はsys/dev/asmc/asmcvar.hの107-109行目で定義されている
  - ASMC_SMS_INTFF (0x60): Free Fall Interrupt
  - ASMC_SMS_INTHA (0x6f): High Acceleration Interrupt
  - ASMC_SMS_INTSH (0x80): Shock Interrupt
- タスクキュー使用の理由：割り込みコンテキストからdevctl_notify()を直接呼び出すことを避けるため
- 通知データの先頭にスペースが含まれるのは、コード上の" notify=0x%x"フォーマットによる
- asmcドライバはLinuxのapplesmc ドライバに触発されて開発された

---

## コードリーディングガイド

本通知を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

ASMC SMSの定数定義とasmc_softc構造体を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | asmcvar.h | `sys/dev/asmc/asmcvar.h` | ASMC_SMS_INTFF(0x60)、ASMC_SMS_INTHA(0x6f)、ASMC_SMS_INTSH(0x80)の定義（107-109行目） |
| 1-2 | asmcvar.h | `sys/dev/asmc/asmcvar.h` | asmc_softc構造体のsc_sms_intrtype、sc_sms_treeフィールド |

**読解のコツ**: SMSの割り込みタイプは3種類定義されており、それぞれ物理現象の重大度を表す。Free Fall(0x60)が最も重大で、Shock(0x80)が最も軽微である。

#### Step 2: 割り込みハンドラを理解する

asmc_sms_intrfast()がSMS割り込みの入口となる。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | asmc.c | `sys/dev/asmc/asmc.c` | asmc_sms_intrfast()関数（割り込みファストパス） |

**主要処理フロー**:
- 割り込みタイプをsc->sc_sms_intrtypeに保存
- taskqueue_enqueue()でasmc_sms_taskをキューに投入

#### Step 3: タスク処理とdevctl通知を理解する

asmc_sms_task()がタスクキュー上で実行され、devctl_notifyを呼び出す。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | asmc.c | `sys/dev/asmc/asmc.c` | asmc_sms_task()関数（1531-1553行目） |

**主要処理フロー**:
- **1533行目**: sc->sc_sms_intrtypeの取得
- **1537-1549行目**: switch文で割り込みタイプをtype値にマッピング
  - ASMC_SMS_INTFF -> type = 2
  - ASMC_SMS_INTHA -> type = 1
  - ASMC_SMS_INTSH -> type = 0
  - default -> type = 255
- **1551行目**: notify_buf生成（" notify=0x%x"フォーマット）
- **1552行目**: devctl_notify("ACPI", "asmc", "SMS", notify)

### プログラム呼び出し階層図

```
[SMS割り込み（ハードウェア）]
    |
    +-- asmc_sms_intrfast() [sys/dev/asmc/asmc.c]
           |
           +-- sc->sc_sms_intrtype = 割り込みタイプ
           +-- taskqueue_enqueue()
                  |
                  +-- asmc_sms_task() [sys/dev/asmc/asmc.c:1531]
                         |
                         +-- switch(sc_sms_intrtype) -> type変換
                         +-- devctl_notify("ACPI", "asmc", "SMS", notify)
```

### データフロー図

```
[入力]                       [処理]                          [出力]

SMSハードウェア    --->  asmc_sms_intrfast()        --->  タスクキュー
割り込み                 (割り込みコンテキスト)              |
                                                           v
                         asmc_sms_task()            --->  devctl(4)キュー
                         (タスクコンテキスト)               |
                         +-- 割り込みタイプ変換             +-- devd(8)
                         +-- devctl_notify
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| asmc.c | `sys/dev/asmc/asmc.c` | ソース | asmc_sms_task()の実装、devctl_notify呼び出し |
| asmcvar.h | `sys/dev/asmc/asmcvar.h` | ヘッダー | asmc_softc構造体、SMS割り込み定数の定義 |
| acpivar.h | `sys/dev/acpica/acpivar.h` | ヘッダー | ACPI変数定義 |
| devctl.h | `sys/sys/devctl.h` | ヘッダー | devctl_notify()のプロトタイプ |
| taskqueue.h | `sys/sys/taskqueue.h` | ヘッダー | タスクキューAPI定義 |
