KolibriOSでのUSBサポヌト内郚には䜕がありたすか パヌト3ホストコントロヌラヌサポヌトコヌド

抂芁で説明したように、ホストコントロヌラヌのサポヌトレベルは、特定のむベントが発生したずきに高いレベルを匕き起こし、高いレベルが機胜するために必芁な機胜を提䟛するはずです。

䟿宜䞊、サポヌトコヌドのさたざたな芁玠に぀いお、制埡を受ける順序で説明したす。



USBサブシステムの起動



準備PCIデバむスのリストにあるUSBコントロヌラヌ



USBサブシステムは、システムの起動䞭にusb_init



からusb_initを呌び出すこずで開始されたす。



USBが起動するたでに、芋぀かったpcidev_list



PCIデバむスのリストはすでに準備されおいたす。 USBコントロヌラは、クラス、サブクラス、およびむンタヌフェむスコヌドによっおすべおのPCIデバむス間で認識されたす。
皮類 クラス サブクラス むンタヌフェヌス
UHCI 0Ch 03h 00h
OHCI 0Ch 03h 10時間
゚ヌチ 0Ch 03h 20時間
Xhci 0Ch 03h 30時間
usb_init



は、USBデバむスを匷調衚瀺するたびに、PCIデバむスのリストを数回usb_init



たす。



BIOSコントロヌルを無効にする



䞀郚のBIOSは、USBマりス、USBキヌボヌド、およびUSBフラッシュドラむブを凊理でき、USBを知らないオペレヌティングシステムにデヌタを提䟛したす。 マりスずキヌボヌドからのデヌタはPS / 2圢匏に倉換され、䜕らかの方法でオペレヌティングシステムに持ち蟌たれたす。これは、システムに実際のPS / 2マりスやキヌボヌドが存圚する堎合ず同じです。 int 13h



の芳点からは、USBフラッシュドラむブはハヌドドラむブのように芋えたす。このようなサポヌトは、フラッシュドラむブからダりンロヌドするために必芁なため、マりスのサポヌトよりも頻繁に芋぀かりたす。

オペレヌティングシステムは、任意のプロセッサモヌドを䜿甚しお、それ自䜓で䞭断を凊理できたす。 このような条件䞋でBIOSが予枬可胜な環境で制埡できるように、486に戻っお正確にはi386SLの特別なバヌゞョンから、IntelはBIOSが動䜜しお動䜜を䞭断する特別なプロセッサモヌドSystem Management ModeSMMを考案したしたシステム。 プロセッサ自䜓を䜿甚しおSMMに入るこずは䞍可胜です。 マザヌボヌドハヌドりェアが特別なシステム管理割り蟌みSMI信号を送信するず、プロセッサはこのモヌドに入りたす。 原則ずしお、チップセットに組み蟌たれたUSBコントロヌラヌは、蚭定に応じお、䞭断する代わりにSMIを生成できたす。



pcidev_list



の最初のパスは、USBコントロヌラヌがオペレヌティングシステムの制埡䞋にあるこずをBIOSに䌝えるこずです。したがっお、BIOSはそれらに察しお䜕もしたせん。



このパスでは、すべおのコンパニオンがペアのEHCIコントロヌラヌに凊理されるこずが重芁です。 たずえば、昇順のPCI座暙を走査するず、これが保蚌されたす。 コヌドの最初のバヌゞョンでは、このパッセヌゞは個別に割り圓おられず、すべおのEHCIコントロヌラヌが最初に凊理されたした。 これは倚くの構成で機胜したしたが、 テスト䞭にすべおのBIOSが正しく曞き蟌たれおいるわけではなく、間違った順序でSMM内のシステムがクラッシュする可胜性があるこずがわかりたした。 具䜓的には、次のシナリオが可胜です。

EHCIの前にコンパニオンを凊理するず、このシナリオの可胜性がなくなりたす。



コントロヌラを譲枡する必芁があるこずをBIOSに報告する方法は、コントロヌラによっお異なりたす。 察応する関数は{u,o,e}hci_kickoff_bios



ず呌ばれたす。 UHCIは時系列的に最初のむンタヌフェむスであるため、特別なメッセヌゞを提䟛しないため、 uhci_kickoff_bios



単にSMI生成をオフにし、コントロヌラヌを停止したす。 OHCIおよびEHCIでは、BIOSず通信する手順は理論的に仕様で説明されおいたすが、実際には...詳现がありたす。 どちらの堎合も、手順は次のずおりです。あるレゞスタにあるビットを蚭定し、別のビットの目的の状態を埅ちたす。 BIOSがコントロヌラヌで動䜜する堎合、コントロヌラヌはSMIを生成し、プロセッサヌはSMMに切り替えおBIOSを呌び出し、BIOSはコントロヌラヌを解攟し、他のビットを目的の状態にしお、SMMを終了したす。 OHCIの手順の詳现は、 テスト䞭に刀明したため、BIOSが割り蟌み゜ヌスをオンにしたたたコントロヌラヌを攟眮する可胜性があるこずです。 むベントが割り蟌みを生成し、OHCIドラむバヌがそのハンドラヌをむンストヌルする前に割り蟌みが割り蟌みコントロヌラヌでマスクされおいる堎合、システムは再びハングしたす-OHCIは䜕床も割り蟌みを生成したすが、これは誰も凊理したせん。 したがっお、 ohci_kickoff_bios



は、BIOSずの䌚話䞭の割り蟌みを犁止し、䌚話の終了時にすべおのOHCI割り蟌み゜ヌスをオフにしたす。 EHCIでは、実際に「オペレヌティングシステムがコントロヌラヌの所有暩を芁求したした」ずいうビットを実際に蚭定するこずはできたせん。たず、BIOSがコントロヌラヌを所有しおいるこずを確認する必芁がありたす。 䞀郚のBIOSは、システムを起動する前でもコントロヌラヌを「解攟」し、それを忘れ、SMI生成ビットを削陀せず、芁求を凊理できたせん。SMIが䜕床も生成されるため、システムは再びハングしたす。



コントロヌラヌの初期化



最初のパスでusb_init



がUSBコントロヌラヌを怜出しない堎合、䜜業を停止したす。 USBコントロヌラヌがある堎合、 usb_init



はUSB凊理に割り圓おられたストリヌムを䜜成し、PCIデバむスのリストをさらに2回パスし、各USBコントロヌラヌに察しおusb_init_controller



を呌び出し、 usb_hardware_func



適切なusb_hardware_func



構造䜓ぞのポむンタヌを枡したす。 2番目のパスはEHCIを凊理し、3番目のパスはUHCIずOHCIを凊理したす。 ここでEHCIはコンパニオンの前で凊理されるため、HSデバむスはコンパニオンに自分自身に信号を送っおすぐに圌から奪われるのではなく、EHCIの制埡䞋にありたす。



usb_init_controller



関数はhccommon.incにありたす。 *hci_controller



/ usb_controller



ペアにメモリを割り圓お、䞡方をれロで初期化し、 usb_controller



フィヌルドを初期化したす。そのうちusb_hardware_func



指すHardwareFunc



個別に蚘録する必芁がありたす。 さらに、コントロヌラヌ固有のusb_hardware_func.Init



初期化も呌び出したす。 最埌のアクションで゚ラヌが発生しなかった堎合、 usb_init_controller



はコントロヌラヌを䞀般的なusb_init_controller



登録し、USBストリヌムを起動しお、次の起動時間に関する情報を曎新できるようにしたす。



usb_hardware_func.Init



の特定の初期化はusb_hardware_func.Init



こずを行いたす。



割り蟌みチャネルのバむナリツリヌは、すべおのコントロヌラヌで同じ構造を持っおいたす 。 前の蚘事で説明したした。 残りのタむプのチャネル間の接続は、コントロヌラヌによっお異なりたす。



チャネル間の通信UHCI





UHCIは、幎代順で最も単玔なハヌドりェアを備えた最初のコントロヌラヌです。 UhciBaseAddressReg



のテヌブルを指すポむンタヌUhciBaseAddressReg



1぀だけありたす。 各フレヌム鉄は、テヌブルの察応する芁玠をロヌドし、リンクをたどり始めたす。 定期的な送信のチェヌンの最埌は、各フレヌムで凊理される割り蟌みチャネルのリストです。 リストの最埌のチャネルから、リンクは制埡䌝送のリストの最初のチャネルに぀ながりたす。 制埡䌝送のすべおのチャネルずデヌタ配列の䌝送は、リングで接続されおいたす。 コントロヌラヌがすべおの非呚期的チャネルの凊理を完了するず、コントロヌラヌは非呚期的チャネルのリストの先頭に戻りたす。 このスキヌムでは、次のフレヌムを埅たずに、新しい非呚期的な送信がすぐに凊理され始めたす。



この方匏の明らかな利点は、凊理の優先順䜍に関するUSB​​仕様の芁件に完党に準拠しながら、アむロンがシンプルであるこずです。 短所重い負荷では、コントロヌラヌがフレヌムの終わりたですべおの転送を凊理する時間がないずき、同じタむプのチャンネルは等しくありたせん-リストの最䞊䜍にいる幞運な人は倧きな利点を受け取りたす-そしお、小さな負荷ではコントロヌラヌは垞にメモリからの読み取りに忙しいです新しい仕事がないこずを確認したす。 次のコントロヌラヌの開発者は、UHCIの欠点を考慮したした。



チャネル間の通信OHCI





OHCIには7぀の敎数レゞスタがあり、そのうち6぀はチャネルに関連付けられおいたす。 OhciHCCAReg



のレゞスタの1぀は、他のコントロヌラヌアむ゜クロナス転送甚に調敎ず同様の呚期チャンネルのテヌブルを指し、2番目のOhciPeriodCurrentEDReg



は珟圚の呚期チャンネルを瀺しおいるため、図には瀺されおいたせん。



制埡チャネルずデヌタ配列のチャネルは、独立したリストに収集されたす。 各リストには2぀のポむンタヌがありたす。リストの先頭ぞのポむンタヌOhci{Control,Bulk}HeadEDReg



ず、珟圚のチャンネルOhci{Control,Bulk}CurrentEDReg



ぞのポむンタヌです。 コントロヌラヌは、互いに独立しお3぀のリストで移動できたす。 優先床リストはUSB芁件に沿っおいたす。 各フレヌムコントロヌラヌは定期的なチャンネルのリストを実行したすが、UHCIずは異なり、他のリストの䜍眮を倱うこずはありたせん。したがっお、同じリスト内のすべおのチャンネルは等しくなりたす。 これにより、UHCIの最初のマむナスが閉じられたす。 OHCIレゞスタには、「リストに新しい䌝送がありたす」ずいう2ビットもありたす。1぀は制埡チャネルのリスト、もう1぀はデヌタ配列のチャネルのリストです。゜フトりェアは新しい䌝送を远加するずきに察応するビットを蚭定する必芁がありたす。 コントロヌラがリストの怜玢を開始するず、ビットがリセットされたす。 コントロヌラがリストの最埌に到達するず、ビットを確認したす。 ビットが蚭定されおいる堎合、コントロヌラヌはリストの先頭に移動し、そうでない堎合はリストの凊理を停止したす。 これにより、UHCIの2番目のマむナスが閉じられたす。



チャネル間のリンクEHCI





EHCIは2぀のポむンタレゞスタに制限されおいたす。 それらの1぀であるEhciPeriodicListReg



、他のコントロヌラヌず同様に、呚期的なチャネルのテヌブルを指したす。 別のEhciAsyncListReg



は、珟圚の非呚期的なチャネルを指したす。 非呚期的なチャネルはすべおリングで閉じられたすが、これは可胜な実装の1぀であるUHCIずは異なり、これが前提条件です。 呚期的チャネルず非呚期的チャネルに沿ったりォヌクは互いに独立しおいるため、すべおの非呚期的チャネルが等しくなりたす。 むンテルは、ここでデヌタ配列チャネルに察する制埡チャネル特暩の芁件を無芖するこずにしたした。 コントロヌラヌは、非呚期的なチャネルで䜜業がない堎合、メモリからの無限の読み取りにあたり熱心ではないため、リング内のチャネルの1぀がリングの「開始」ずしおマヌクされたす。 コントロヌラヌがアクティブなギアを怜出せずにリングの「開始」に2回䌚うず、コントロヌラヌはしばらくリングの凊理を停止したす。



USBデバむスの操䜜



デバむスのさたざたな状態ずそれらの間の遷移を説明するUSB​​仕様の写真





デバむス接続



初期化䞭に、OHCIおよびEHCIコントロヌラヌは、デバむスが接続たたは切断されたずきに割り蟌みを生成するように構成されたす。 UHCIでは、残念ながらこれは䞍可胜です。したがっお、UHCIコントロヌラヌでは、USBストリヌムが定期的に自動的に起動し、コントロヌラヌポヌトをポヌリングしお、接続状態の倉化をチェックしたす。 ポヌリング間隔はUHCI_POLL_INTERVAL



タむマヌティックで、珟圚の倀では1秒です。



接続されたUSBデバむスは、電源が入った状態でホストコントロヌラヌずの察話を開始したす。



新しいUSBデバむスの初期化は、100ミリ秒の䞀時停止で始たりたす。 USBデバむスは動的に接続されるため、接続するず、連絡先のチャタリングや、いく぀かの連続した接続/切断むベントが発生する可胜性がありたす。 同じポヌトで新しいむベントが発生するたびに、カりントダりンが再開されたす。 Powered状態が連続しお100ミリ秒続くず、接続は安定しおいるず芋なされ、コヌドは次の初期化ステヌゞ*hci_new_port



たす。



少し埌で説明する理由により、接続を凊理する次のいく぀かの段階は、いく぀かのデバむスに察しお䞊行しお実行するこずはできたせん。 したがっお、次の手順の前に、新しいUSBデバむスは、珟圚のデバむスがこれらの手順をすべお完了するたで埅機する必芁がありたす。 埅機の終了は*hci_new_port.reset



でマヌクされたす。これは、埅機が䞍芁であるこずが刀明した堎合に*hci_new_port



内郚関数の䞀郚であり、同時にusb_hardware_func.InitiateReset



より高いレベルのむンタヌフェヌスに配眮されたす。



次に、 *hci_new_port.reset



コヌドは、新しいデバむスのポヌトのリセット信号を有効にする*hci_new_port.reset



コントロヌラヌに*hci_new_port.reset



たす。 仕様によるず、リセットは少なくずも10ミリ秒続く必芁がありたす。 OHCIはそれ自䜓で時間をカりントし、むンタヌバルの終わりにリセット信号をオフにしお割り蟌みを生成したす。割り蟌みのハンドラヌはUSBストリヌムに信号を送り、次のステヌゞに進みたす。 UHCIずEHCIでは、プログラムで時間を読む必芁がありたす。 アむドルスタンバむサむクルでプロセッサをロヌドしないために、リセット信号をオンにした埌のUSBストリヌムは、システムタむマヌに埓っお起動し、スリヌプ状態になる予定です。 KolibriOSのタむマヌは、10ミリ秒ごずに1回、100 Hzの呚波数で䜜動したす。 最䜎10ミリ秒のリセットを保蚌するために、コヌドは2぀のタむマヌサンプルを埅機したす。 タむマヌの2番目のティックの埌、コヌドは新しいデバむスのポヌト*hci_port_reset_done



のリセット信号をオフにし、次のステップに進みたす。



USB2では、リセットプロセスがデバむスの速床を決定したす。 EHCIはHighSpeedデバむスでのみ動䜜し、USB1速床のいずれかで動䜜するすべおのデバむスはUSB1コンパニオンたたはハブに転送される必芁があるこずを前のパヌトから思い出したす。 ゜フトりェアの芳点からは、リセットの終了埌、EHCIはポヌトぞのデヌタ転送を蚱可するかどうかを決定したす。 リセット埌にポヌトが無効のたたになっおいる堎合、接続されたデバむスはUSB2の速床で動䜜したせん。 この堎合、コンパニオンぞのポヌト転送の所有者を遞択するロゞックに通知するだけです。 その埌、コンパニオンは通垞の接続むベントを確認しお凊理したす。



リセット埌、倚くのデバむスはすでにより高いレベルで蚭定する準備ができおいたす。 しかし、すべおではありたせん。 仕様では、リセット埌少なくずも10ミリ秒の䞀時停止が必芁です。 テストが瀺すように、䞀郚のデバむスでは実際にこの䞀時停止が必芁です。 前のステップず同様に、USBストリヌムは2぀のタむマヌカりントでスリヌプ状態になりたすが、今回はOHCIを含むすべおのコントロヌラヌに察しおです。



リセットずそれに続く䞀時停止の埌、デバむスは電源が入った状態からデフォルト状態に切り替わりたす。デバむスがれロ゚ンドポむントのデヌタを送受信する準備ができおいるが、ただ完党に初期化されおいないずきの2぀の「ハヌフワヌキング」状態の1぀です。 デフォルト状態では、デバむスはUSBバスのれロアドレスに応答したす。 これが、2぀のデバむスのリセットを䞊行しお実行できない理由です。そうしないず、2぀のデバむスが刀明し、それぞれが埌続の蚭定が特に適甚されるず考えられたす。



デバむスのれロ゚ンドポむントが動䜜する準備ができたした。チャネルを開くずきです。 チャネル構造には、チャネル自䜓の特性たずえば、タむプずデバむス特性デバむス速床、バス䞊のデバむスアドレス、 usb_controller



ぞのポむンタヌがusb_controller



たす。 この段階で呌び出される*hci_port_init



コヌドは、 usb_hardware_func.NewDevice



ハブのAPIで䜜成される*hci_new_device



関数の操䜜を委任したす。 埌者は、デバむスの特性が正しく満たされる擬䌌チャネル構造を準備し、チャネルの特性の倀は重芁ではありたせん。 これで、ホストコントロヌラヌサポヌトコヌドは独立したアクションを完了し、論理デバむスレベルのusb_new_device



関数に制埡を移したす。 さらに、デバむスの電源がオフになるたで、ホストコントロヌラヌサポヌトコヌドはより高いレベルからのリク゚ストのみを実行したす。



チャンネル開蚭ずチャンネル送信





コントロヌラヌの芳点から芋るず、送信蚘述子のキュヌ1぀の蚘述子は送信党䜓、たたはコントロヌラヌに応じお䞀郚が単䞀リンクリストずしお線成され、最初の蚘述子の物理アドレスはチャネル構造にあり、次の蚘述子の物理アドレスは前の蚘述子にありたす。 コントロヌラヌが1぀のディスクリプタヌの凊理を終了するず、次のディスクリプタヌのアドレスをそこに曞き蟌むこずにより、チャネル構造を曎新したす。 䌝送キュヌが実行されおいる堎合、ホストコントロヌラヌサポヌトコヌドは、ハヌドりェアずの競合状態を回避するために、次の蚘述子自䜓のアドレスを曎新できたせん。 䜜業を敎理するには、キュヌの最埌に远加の空の蚘述子が必芁です。 空のハンドルは、コントロヌラヌに察しお非アクティブずしおマヌクされたす。 コヌドが蚘述子を远加する堎合、珟圚の空の蚘述子を埋め、次の空の蚘述子を遞択し、叀い蚘述子に新しい蚘述子ぞのリンクを配眮し、最埌のアクションで叀い蚘述子をアクティブにしたす-これはすべお、コントロヌラヌずレコヌドを亀差させたせん。 コントロヌラヌが非アクティブな蚘述子に達するず、キュヌの凊理を停止し、チャネル構造内に非アクティブな蚘述子ぞのリンクを残したす。



空の蚘述子の必芁性を認識した埌、チャネルを開いお送信をキュヌに入れるのはかなり簡単です。 usb_hardware_func.InitPipe = *hci_init_pipe



を開くずきusb_hardware_func.InitPipe = *hci_init_pipe



次のものが必芁です。 定期的なチャネルの堎合、目的のリストを遞択する必芁がありたす。 これはプランナヌのタスクであり、次の蚘事で説明したす。 キュヌぞの転送の远加は、転送usb_hardware_func.AllocTransfer = *hci_alloc_transfer



1ステヌゞの充填蚘述子に分割されたす。これは、制埡転送のために2回たたは3回呌び出され、転送usb_hardware_func.InsertTransfer = *hci_insert_transfer



アクティブ化のためにusb_hardware_func.InsertTransfer = *hci_insert_transfer



たす。 AllocTransfer



, . InsertTransfer



.



IOC, Interrupt on completion. IOC, . - .

OHCI - , ( IOC) : , . ohci_controller



, , . OHCI «» , .

UHCI EHCI , UHCI EHCI , , , .

USB, *hci_process_finalized_td



. — , ; . — , callback- , .





. , , — ( « » ). , usb_hardware_func.SetDeviceAddress



: . , usb_hardware_func.SetEndpointPacketSize



: . UHCI — , , . , . , . EHCI , , , . , : , , , , .



OHCI EHCI , , . , . OHCI . EHCI Interrupt on Async Advance Doorbell : « , » . , . , .





: — OHCI EHCI, UHCI — usb_device_disconnected



, . , 100 , .





1:

2: -

3: -

4:

5:

6:



All Articles