JF Linux Kernel 2.6 Documentation: /usr/src/linux/Documentation/usb/uhci.txt


新しい UHCI ドライバの 仕様と内部 [プレインテキスト版]

linux-2.6.14/Documentation/usb/uhci.txt の和訳
翻訳団体: JF プロジェクト < http://www.linux.or.jp/JF/ >
更新日 : 2005/11/13
原著作者: Georg Acher < acher at in dot tum dot de >
	Deti Fliegl < deti at fliegl dot de >
	Thomas Sailer < sailer at ife dot ee dot ethz dot ch >
翻訳者 : Hiroshi.Suzuki < setter at reset dot jp >
校正者 : Chie Nakatani さん <jeanne at mbox dot kyoto-inet dot or dot jp>
	Masanori Kobayasi さん <zap03216 at nifty dot ne dot jp>
	Seiji Kaneko さん <skaneko at a2 dot mbn dot or dot jp>

Specification and Internals for the New UHCI Driver (Whitepaper...)

新しい UHCI ドライバの 仕様と内部 (白書...)

	brought to you by

	Georg Acher, acher at in dot tum dot de (executive slave) (base guitar)
	Deti Fliegl, deti at fliegl dot de (executive slave) (lead voice)
	Thomas Sailer, sailer at ife dot ee dot ethz dot ch (chief consultant) (cheer leader)


	Georg Acher, acher at in dot tum dot de (実務担当) (ベースギター)
	Deti Fliegl, deti at fliegl dot de (実務担当) (リードボーカル)
	Thomas Sailer, sailer at ife dot ee dot ethz dot ch (主相談役) (チアリーダー)

	$ Id: README.uhci,v 1.1 1999/12/14 14:03:02 fliegl Exp $

This document and the new uhci sources can be found on

この説明書と、最新の uhci のソースは、次の場所にあります。


1. General issues

1. 一般的な問題

1.1 Why a new UHCI driver, we already have one?!?

1.1 すでにドライバがあるのに、なぜ、新しい UHCI ドライバを?!?

Correct, but its internal structure got more and more mixed up by the (still
ongoing) efforts to get isochronous transfers (ISO) to work.
Since there is an increasing need for reliable ISO-transfers (especially
for USB-audio needed by TS and for a DAB-USB-Receiver build by GA and DF),
this state was a bit unsatisfying in our opinion, so we've decided (based
on knowledge and experiences with the old UHCI driver) to start
from scratch with a new approach, much simpler but at the same time more
It is inspired by the way Win98/Win2000 handles USB requests via URBs,
but it's definitely 100% free of MS-code and doesn't crash while
unplugging an used ISO-device like Win98 ;-)
Some code for HW setup and root hub management was taken from the
original UHCI driver, but heavily modified to fit into the new code.
The invention of the basic concept, and major coding were completed in two
days (and nights) on the 16th and 17th of October 1999, now known as the
great USB-October-Revolution started by GA, DF, and TS ;-)

おっしゃる通り。でも、内部構造は、アイソクロナス転送 (ISO) を動かすための
(現在も続けられている) 努力により、ますます混乱しています。
一方、安定した ISO 転送はますます必要
(特に、TS(Thomas Sailer 氏) が必要な USB オーディオと、GA(Georg Acher 氏) と、
DF(Deti Fliegl 氏) の作った DAB-USB レシーバのために) となっています。この状態
に、(私達の意見として) 少々納得できませんでしたので、単純でかつ強力な新しいアプ
ローチを用いて (古い UHCI ドライバの知識と経験を基本にして) ゼロから作りはじめ
ることを決定しました。URB により USB リクエストを扱う Win98/Win2000 の方法に
刺激を受けましたが、MS コードからは、明確に、100% フリーで、しかも、Win98 のよ
うに、ISO デバイスを取り外すときにクラッシュしたりしません ;-)
HW の設定とルートハブを管理するいくつかのコードは、元の UHCI ドライバのコード
基本構想で創造した主要部分のコーディングは、1999年10月16と17日の二日 (夜も含め
て) で完成させました。現在、GA, DF, TS によってはじめられた、偉大な USB 10月
革命として知られています ;-)

Since the concept is in no way UHCI dependent, we hope that it will also be
transferred to the OHCI-driver, so both drivers share a common API.

考え方は、UHCI に依存していないので、それが、OHCI ドライバにも転用され、
両方のドライバが、共通の API を共有するようになることを望んでいます。

1.2. Advantages and disadvantages

1.2. 利点と欠点

+ All USB transfer types work now!
+ Asynchronous operation
+ Simple, but powerful interface (only two calls for start and cancel)
+ Easy migration to the new API, simplified by a compatibility API
+ Simple usage of ISO transfers
+ Automatic linking of requests
+ ISO transfers allow variable length for each frame and striping
+ No CPU dependent and non-portable atomic memory access, no asm()-inlines
+ Tested on x86 and Alpha

+ 現在 すべての種類の USB 転送 が動作します!
+ 非同期処理
+ 単純で強力なインタフェース (開始と取消のため、2回呼び出すだけで良い)
+ 新しい API への移行が簡単 (互換 API による簡略化)
+ 単純な ISO 転送の使用法
+ リクエストの自動連結
+ ISO 転送は、それぞれのフレームとストライピングを可変長にできます。
+ CPU に依存しない、移植できないアトミックなメモリアクセスを使わない、
  インライン asm() を使わない。
+ x86 と、Alpha でテストしています。

- Rewriting for ISO transfers needed

- ISO 転送を使うには、書き換えが必要です

1.3. Is there some compatibility to the old API?

1.3. 古い API との互換性はありますか?

Yes, but only for control, bulk and interrupt transfers. We've implemented
some wrapper calls for these transfer types. The usbcore works fine with
these wrappers. For ISO there's no compatibility, because the old ISO-API
and its semantics were unnecessary complicated in our opinion.

これら転送タイプを呼び出す、いくつかのラッパを実装しました。usbcore はこれら
ラッパとうまく動作します。ISO には互換性を持たせていません。なぜなら、古い
ISO API の書式は、私達の見解では、不必要に複雑だったからです。

1.4. What's really working?

1.4. 何が実際に動いていますか?

As said above, CTRL and BULK already work fine even with the wrappers,
so legacy code wouldn't notice the change.
Regarding to Thomas, ISO transfers now run stable with USB audio.
INT transfers (e.g. mouse driver) work fine, too.

上述したように、CTRL と BULK がそれぞれ、ラッパを用いた状態でもうまく動いてい
Thomas 担当関連では、ISO 転送は、現在 USB オーディオで安定動作しています。
INT 転送 (マウスドライバなど) も、うまく動きます。

1.5. Are there any bugs?

1.5. どんなバグがありますか?

No ;-)
Well, of course this implementation needs extensive testing on all available
hardware, but we believe that any fixes shouldn't harm the overall concept.

ありません ;-)

1.6. What should be done next?

1.6. 次にしなければならないことは?

A large part of the request handling seems to be identical for UHCI and
OHCI, so it would be a good idea to extract the common parts and have only
the HW specific stuff in uhci.c. Furthermore, all other USB device drivers
should need URBification, if they use isochronous or interrupt transfers.
One thing missing in the current implementation (and the old UHCI driver)
is fair queueing for BULK transfers. Since this would need (in principle)
the alteration of already constructed TD chains (to switch from depth to
breadth execution), another way has to be found. Maybe some simple
heuristics work with the same effect.

UHCI と OHCI でのリクエストの取扱いの大部分は同じようなので、共通部分を取り出
して、uhci.c 内のハードウェア特有のものだけにするのが良いと思います。さらに、
すべての他の USB デバイスドライバは、アイソクロナス転送もしくはインタラプト転送
を使うなら、URB 化しなければいけません。現在の実装 (と、古い UHCI ドライバ) で
欠けているものは、BULK 転送のための公平な待ち行列です。これに関しては、すでに
構築された TD チェイン (深さから幅への変更を実行する) の変更を (原理的には)


2. Internal structure and mechanisms

2. 内部構造としくみ

To get quickly familiar with the internal structures, here's a short
description how the new UHCI driver works. However, the ultimate source of
truth is only uhci.c!

内部構造を早く馴染んでもらうため、新しい UHCI ドライバがどのように動くかを手短
かに説明します。しかしながら、真実を知るための最高の情報源は、uhci.c だけです!

2.1. Descriptor structure (QHs and TDs)

2.1. ディスクリプタの構造 (QH と TD)

During initialization, the following skeleton is allocated in init_skel:

初期化中、以下の骨組みが、init_skel 内に配置されます。

	 framespecific           |           common chain

         フレーム明細            |           共通チェイン

[  0 ]-----> TD --> TD -------\
[  1 ]-----> TD --> TD --------> TD ----> QH -------> QH -------> QH ---> NULL
  ...        TD --> TD -------/
[1023]-----> TD --> TD ------/
	     ^^     ^^           ^^       ^^          ^^          ^^
   1024 TDs for   7 TDs for    1 TD for   Start of    Start of    End Chain
	    ISO  INT (2-128ms) 1ms-INT    CTRL Chain  BULK Chain

   ISO 用 TD     INT (2-128ms) 1ms-INT 用 CTRL        BULK        終了チェイン
     1024個       用 TD 7個     TD 1個    チェイン    チェイン
                                          の始まり    の始まり

For each CTRL or BULK transfer a new QH is allocated and the containing data
transfers are appended as (vertical) TDs. After building the whole QH with its
dangling TDs, the QH is inserted before the BULK Chain QH (for CTRL) or
before the End Chain QH (for BULK). Since only the QH->next pointers are
affected, no atomic memory operation is required. The three QHs in the
common chain are never equipped with TDs!

CTRL 転送や BULK 転送それぞれには、新しい QH が割り当てられ、転送されるデータ
は、TD として、(垂直方向に) 追加されます。TD が付けられた QH 全体を構築したあと、
QH は、BULK チェインの QH の前 (CTRL 転送) 、または、End チェインの QH の前
(BULK 転送) に挿入されます。このとき QH->next ポインタだけが影響を受けるため、
アトミックなメモリ処理を必要としません。共通チェインの3つの QH は、TD を持ちま

For ISO or INT, the TD for each frame is simply inserted into the appropriate
ISO/INT-TD-chain for the desired frame. The 7 skeleton INT-TDs are scattered
among the 1024 frames similar to the old UHCI driver.

ISO または、INTで、それぞれのフレームのための TD は、希望するフレームの
適切な ISO/INT-TD チェインに単に挿入されるだけです。7つの 骨組みの INT-TD は、
古い UHCI ドライバと同様に 1024 フレームに分散されます。

For CTRL/BULK/ISO, the last TD in the transfer has the IOC-bit set. For INT,
every TD (there is only one...) has the IOC-bit set.

CTRL/BULK/ISO で、転送中、最後の TD は、IOC ビットがセットされています。
INT で、すべての TD (といってもひとつですが...) は、IOC ビットがセットされています。

Besides the data for the UHCI controller (2 or 4 32bit words), the descriptors
are double-linked through the .vertical and .horizontal elements in the
SW data of the descriptor (using the double-linked list structures and
operations), but SW-linking occurs only in closed domains, i.e. for each of
the 1024 ISO-chains and the 8 INT-chains there is a closed cycle. This
simplifies all insertions and unlinking operations and avoids costly

UHCI コントローラのためのデータ (2 または 4 32ビットワード) に加えて、
ディスクリプタは、ディスクリプタ (ダブルリンクリストの構造体と処理を使う) の
SW データ内の .vertical と、.horizontal 要素により、ダブルリンクされていますが、
SW データによるリンクは閉じた領域内だけで発生します。すなわち、1024 ISO チェイ
ンと、8 INT チェインで、各々閉じた輪になっています。これは、すべての挿入とアン
リンク処理を簡略化し、高価な bus_to_virt() の呼び出しを回避します。

2.2. URB structure and linking to QH/TDs

2.2. URB 構造体と QH/TD への連結

During assembly of the QH and TDs of the requested action, these descriptors
are stored in urb->urb_list, so the allocated QH/TD descriptors are bound to
this URB.
If the assembly was successful and the descriptors were added to the HW chain,
the corresponding URB is inserted into a global URB list for this controller.
This list stores all pending URBs.

要求された動作に対して QH と TD の組み立て中、これらディスクリプタは、
urb->urb_list に保存されるので、割り当てられた QH/TD ディスクリプタは、この
URB に結びつけられます。組み立てに成功し、ディスクリプタが HW チェインに追加さ
れたなら、対応する URB は、このコントローラ用の、グローバル URB リストに追加さ
れます。このリストには、すべてのペンディングである URB が記憶されています。

2.3. Interrupt processing

2.3. 割り込み処理

Since UHCI provides no means to directly detect completed transactions, the
following is done in each UHCI interrupt (uhci_interrupt()):

UHCI は、終了したトランザクションを直接検知する手段を提供していないので、
それぞれの UHCI 割り込み (uhci_interrupt()) に対して以下の処理が行われます:

For each URB in the pending queue (process_urb()), the ACTIVE-flag of the
associated TDs are processed (depending on the transfer type
process_{transfer|interrupt|iso}()). If the TDs are not active anymore,
they indicate the completion of the transaction and the status is calculated.
Inactive QH/TDs are removed from the HW chain (since the host controller
already removed the TDs from the QH, no atomic access is needed) and
eventually the URB is marked as completed (OK or errors) and removed from the
pending queue. Then the next linked URB is submitted. After (or immediately
before) that, the completion handler is called.

ペンディングキュー (process_urb()) にある、それぞれの URB で、関連した TD の
ACTIVE フラグが処理されます (転送タイプ process_{transfer|interrupt|iso}()
に従って)。その TD が動作中でないなら、それはトランザクションの完了を示しており、
終了ステータスを計算します。動作中でない QH/TD は、HW チェインから削除し (ホス
トコントローラはすでに QH から TD を削除済みなので、アトミックなアクセスは必要
ありません)、最終的に、その URB は、完了したとして印 (OK または、error) を付け
られ、待ち行列から取り除かれます。その後、次のリンクされている URB が投入され
ます。その後 (または、直前) 、完了ハンドラが呼び出されます。

2.4. Unlinking URBs

2.4. URB のアンリンク

First, all QH/TDs stored in the URB are unlinked from the HW chain.
To ensure that the host controller really left a vertical TD chain, we
wait for one frame. After that, the TDs are physically destroyed.

最初に、URB に保存されたすべての QH/TD は、HW チェインから、切り離されます。
ホストコントローラが、垂直 TD チェインをほんとうに捨てたのを確認するため、
1つのフレームの間待ちます。その後、TD は物理的に破壊されます。

2.5. URB linking and the consequences

2.5. URB 連結とその影響

Since URBs can be linked and the corresponding submit_urb is called in
the UHCI-interrupt, all work associated with URB/QH/TD assembly has to be
interrupt save. This forces kmalloc to use GFP_ATOMIC in the interrupt.

URB は連結でき、関連する submit_urb が、UHCI 割り込みで呼び出されるので、
URB/QH/TD 組み立てに関連したすべての動作は、割り込みセーフでなければなりませ
ん。このため、割り込みで、GFP_ATOMIC を使う場合は kmalloc が必須になります。

Linux カーネル 2.6 付属文書一覧へ戻る