
ã¯ããã«
ã©ãªãã§ãæè¿ããŸãã ä»æ¥ãç§ã¯èªåã®çµéšãå ±æããããšæããŸãããããã§ããç§ã®æèŠã§ã¯ãUSB 2.0ãã¹ãã³ã³ãããŒã©ãŒã®ç°¡åãªæšæºã«ã€ããŠãäžèŠããã ãã§æ確ã«èª¬æããŠããŸãã
æåã¯ãUSB 2.0ããŒãã¯4ãã³ã ãã§ããã®ãã¡ã®2ã€ãããŒã¿ãéä¿¡ããã ãïŒããšãã°COMããŒãã®ããã«ïŒã§ãããšæ³åã§ããŸãããå®éã¯ããã§ã¯ãªãããŸã£ããéã§ãã USBã³ã³ãããŒã©ãŒã¯ãååãšããŠãéåžžã®COMããŒãçµç±ã§ããŒã¿ã転éããããšãèš±å¯ããŸããã EHCIã¯ããœãããŠã§ã¢ããããã€ã¹èªäœãžãããã³å察æ¹åãžã®ä¿¡é Œæ§ã®é«ãé«éããŒã¿è»¢éãå¯èœã«ããããªãè€éãªæšæºã§ãã
ãã®èšäºã¯ãããšãã°ããã©ã€ããŒã®ååãªã©ã€ãã£ã³ã°ã¹ãã«ãããŒããŠã§ã¢ã®ããã¥ã¡ã³ããèªãããšãã§ããªãå Žåã«åœ¹ç«ã€ããšããããŸãã ç°¡åãªäŸïŒWindowsãä»ã®Linuxãã£ã¹ããªãã¥ãŒã·ã§ã³ãããŒããŠã§ã¢ãããŠã³ããŒãããªãããã«ãããPCçšã«OSãäœæãããã®ãã¯ãŒããã¹ãŠèªåã®ç®çã«ã®ã¿äœ¿çšãããå Žåã
EHCIãšã¯äœã§ããïŒ
ãããå§ããŸãããã EHCI-Enhanced Host Controller Interfaceã¯ãããŒã¿ãšå¶åŸ¡èŠæ±ãUSBããã€ã¹ã«è»¢éããããã«èšèšãããŠãããä»ã®æ¹åã§ã99ïŒ ã®å Žåãä»»æã®ãœãããŠã§ã¢ãšç©çããã€ã¹éã®ãªã³ã¯ã§ãã EHCIã¯PCIããã€ã¹ãšããŠåäœãããããMMIOïŒMemory-Mapped-IOïŒã䜿çšããŠã³ã³ãããŒã©ãŒãå¶åŸ¡ããŸãïŒã¯ããäžéšã®PCIããã€ã¹ã¯ããŒãã䜿çšããããšãç¥ã£ãŠããŸãããããã§ã¯ãã¹ãŠãäžè¬åããŸããïŒã Intelã®ããã¥ã¡ã³ãã«ã¯ãåäœåçã®ã¿ãèšèŒãããŠãããå°ãªããšãæ¬äŒŒã³ãŒãã§èšè¿°ããããã¹ãŠã®ã¢ã«ãŽãªãºã ã«ã€ããŠã®ãã³ãã¯ãããŸããã EHCIã«ã¯ãæ©èœãšåäœã®2çš®é¡ã®MMIOã¬ãžã¹ã¿ããããŸãã åè ã¯ã³ã³ãããŒã©ãŒã®ç¹æ§ãååŸããã®ã«åœ¹ç«ã¡ãåŸè ã¯ã³ã³ãããŒã©ãŒãå¶åŸ¡ããã®ã«åœ¹ç«ã¡ãŸãã å®éããœãããŠã§ã¢ãšEHCIã³ã³ãããŒã©ãŒéã®æ¥ç¶ã®æ¬è³ªãæ·»ä»ããŸãã

åEHCIã³ã³ãããŒã©ãŒã«ã¯è€æ°ã®ããŒãããããåããŒãã¯ä»»æã®USBããã€ã¹ã«æ¥ç¶ã§ããŸãã ãŸããEHCIã¯UHCIã®æ¹è¯çã§ãããæ°å¹Žåã«Intelã«ãã£ãŠéçºãããããšã«ã泚æããŠãã ããã äžäœäºææ§ã®ããã«ãEHCIãããäœãããŒãžã§ã³ãæã€UHCI / OHCIã³ã³ãããŒã©ãŒã¯ãEHCIã®ã³ã³ãããªã³ã«ãªããŸãã ããšãã°ãUSB 1.1ã§åäœããUSBââããŒããŒãïŒãããŸã§ã®ã»ãšãã©ã®ããŒããŒãã¯ããã«äŒŒãŠããŸããïŒïŒUSB 1.1ã®æ倧é床ã¯æ¯ç§12ã¡ã¬ãããã§ãFullSpeed USB 2.0ã«ã¯åž¯åå¹ ãããããšã«æ³šæããŠãã ããïŒæ倧480 MbpsïŒã§ãUSB 2.0ããŒããåããã³ã³ãã¥ãŒã¿ãŒã䜿çšããŠããå ŽåãããŒããŒããã³ã³ãã¥ãŒã¿ãŒã«æ¥ç¶ãããšãEHCIãã¹ãã³ã³ãããŒã©ãŒã¯USB 1.1ã§ã©ã®ããã«åäœããŸãã ãã®ã¢ãã«ã次ã®å³ã«ç€ºããŸãã

ãŸããå°æ¥çã«ã¯ããã®ãããªäžæ¡çãªç¶æ³ã®ããã«ãã©ã€ããŒãæ£ããåäœããªãå¯èœæ§ãããããšãããã«èŠåããŸãïŒUHCIãEHCIãåæåãã2ã€ã®åäžã®ããã€ã¹ãè¿œå ããããŒãææè å¶åŸ¡ããããããŒãã¬ãžã¹ã¿ã«èšå®ãã EHCIãèªåçã«ããŒãããã©ãã°ããUHCIã®ããŒããå¿çãåæ¢ãããããUHCIã¯åäœãåæ¢ããŸããããã®ç¶æ³ãç£èŠããå¿ èŠããããŸãã
ãŸããEHCIã¢ãŒããã¯ãã£èªäœã瀺ãå³ãèŠãŠã¿ãŸãããã

å³åŽã«ã¯ãã¥ãŒã«ã€ããŠæžãããŠããŸã-ãããã«ã€ããŠã¯å°ãåŸã§ã
EHCIã³ã³ãããŒã©ãŒã®ã¬ãžã¹ã¿ãŒ
ãŸãããããã®ã¬ãžã¹ã¿ãä»ããŠããã€ã¹ãå¶åŸ¡ããããããããã¯éåžžã«éèŠã§ããããããããªããã°EHCIããã°ã©ãã³ã°ã¯äžå¯èœã§ããããšãããäžåºŠæ確ã«ããããšæããŸãã
æåã«ããã®ã³ã³ãããŒã©ãŒã«äžããããMMIOã¢ãã¬ã¹ãååŸããå¿ èŠããããŸãããªãã»ãã+ 0x10ã§ãåŸ æã®ã¬ãžã¹ã¿ãŒã®ã¢ãã¬ã¹ã«ãªããŸãã 1ã€ãããŸãïŒæåã«ãæ©èœã¬ãžã¹ã¿ã移åãããã®åŸã«ã®ã¿-æäœå¯èœãªããããªãã»ãã0ïŒEHCIã®MMIOã®éå§ç¹ã«å¯ŸããŠãªãã»ãã0x10ã§åä¿¡ããåã®ã¢ãã¬ã¹ããïŒã«1ãã€ã-æ©èœã¬ãžã¹ã¿ã®é·ãããããŸãã
æ©èœã¬ãžã¹ã¿
ãªãã»ãã2ã«ã¯ã HCIVERSIONã¬ãžã¹ã¿ããããŸã -ãã®HCã®ãªããžã§ã³çªå·ã2ãã€ããå æãããªããžã§ã³ã®BCDããŒãžã§ã³ïŒWikipediaã«ããBCDãå«ãïŒãå«ãã§ããŸãã
ãªãã»ãã+4ã§ã HCSPARAMSã¬ãžã¹ã¿ãé 眮ãã ããã®ãµã€ãºã¯2ã¯ãŒãã§ãããã€ã¹ã®æ§é ãã©ã¡ãŒã¿ãŒãå«ãŸãããã®ãããã¯ä»¥äžã瀺ããŸãã
- ããã16-ããŒãã€ã³ãžã±ãŒã¿-æ¥ç¶ãããUSBããã€ã¹ã§äœ¿çšå¯èœãªLEDã
- ããã15:12-ãã®ã³ã³ãããŒã©ãŒã«å²ãåœãŠãããŠããã³ã³ãããªã³ã³ã³ãããŒã©ãŒã®çªå·
- ããã11ïŒ8-ã³ã³ãããªã³ã³ã³ãããŒã©ãŒã®ããŒãæ°
- ããã7-ããŒãã«ãŒãã£ã³ã°ã«ãŒã«-ãããã®ããŒããã³ã³ãããªã³ããŒãã«ããããããæ¹æ³ã瀺ããŸã
- ããã4-ããŒãé»åå¶åŸ¡-åããŒãã®é»æºããªã³ã«ããå¿ èŠããããã©ããã瀺ããŸãã0-é»æºã¯èªåçã«äŸçµŠãããŸã
- ããã3ïŒ0-ãã®ã³ã³ãããŒã©ãŒã®ããŒãã®æ°ã
- ãªãã»ãã+8ã«HCCPARAMSã¬ãžã¹ã¿ããããŸã-äºææ§ãã©ã¡ãŒã¿ãŒã瀺ãããã®ãããã¯æ¬¡ã®ããšãæå³ããŸãã
- ããã2-éåæãã¥ãŒã®å¯çšæ§ã
- ããã1-å®æçïŒé 次ïŒãã¥ãŒã®å¯çšæ§
- ããã0ã64ãããã®äºææ§
æäœã¬ãžã¹ã¿
ãªãã»ãã0ã§ã¯ã USBCMDã¬ãžã¹ã¿ã¯ã³ã³ãããŒã©ã®ã³ãã³ãã¬ãžã¹ã¿ã§ããããã®ãããã¯æ¬¡ãæå³ããŸãã
- ããã23:16-å²ã蟌ã¿ãããå€å¶åŸ¡-1ã€ã®éåžžã®ãã¬ãŒã ã«äœ¿çšããããã€ã¯ããã¬ãŒã ã®æ°ã瀺ããŸãã 倧ããã»ã©é«éã§ããã8ãè¶ ããå Žåããã€ã¯ããã¬ãŒã ã¯8ãšåãé床ã§åŠçãããŸãã
- ããã6-éåæãã¥ãŒå ã®åãã©ã³ã¶ã¯ã·ã§ã³ã®åŸã«å²ã蟌ã¿ã
- ããã5-䜿çšãããéåæãã¥ãŒ
- ããã4-é 次ãã¥ãŒã®äœ¿çšã
- ããã3ïŒ2-FrameList'aã®ãµã€ãºïŒåŸã§è©³ãã説æããŸãïŒã 0ã¯1024èŠçŽ ã1-512ã2-256ã3-äºçŽãæå³ããŸã
- ããã1 âãã¹ãã³ã³ãããŒã©ãŒã®ãªã»ãããå®è¡ããããã«èšå®ããŸãã
- ããã0-å®è¡/åæ¢
次ã«ããªãã»ãã+4ã«USBSTSã¬ãžã¹ã¿ããããŸã-ãã¹ãã³ã³ãããŒã©ãŒã®ã¹ããŒã¿ã¹ã
- ããã15ã¯ãéåæãã¥ãŒã䜿çšãããŠãããã©ããã瀺ããŸãã
- ããã14ã¯ãé 次ãã¥ãŒã䜿çšãããŠãããã©ããã瀺ããŸãã
- ããã13-空ã®éåæãã¥ãŒãæ€åºãããããšã瀺ããŸãã
- ãã©ã³ã¶ã¯ã·ã§ã³ã®åŠçäžã«ãšã©ãŒãçºçããå Žåãããã12ã¯1ã«èšå®ããããã¹ãã³ã³ãããŒã©ãŒã¯ãã¹ãŠã®ãã¥ãŒãåæ¢ããŸãã
- ããã4ã¯1ã«èšå®ãããé倧ãªãšã©ãŒãçºçããå Žåããã¹ãã³ã³ãããŒã©ãŒã¯ãã¹ãŠã®ãã¥ãŒãåæ¢ããŸãã
- ããã3 FrameListïŒã¬ãžã¹ã¿ïŒããŒã«ãªãŒããŒ-ãã¹ãã³ã³ãããŒã©ãŒãframeListå šäœãåŠçãããšãã«1ã«èšå®ãããŸãã
- ããã1-USBãšã©ãŒå²ã蟌ã¿-ãšã©ãŒå²ã蟌ã¿ãçæããŸããïŒ
- ããã0-USBå²ã蟌ã¿-TDã«IOCãã€ã³ã¹ããŒã«ãããŠããå Žåããã©ã³ã¶ã¯ã·ã§ã³åŠçãæåããåŸã«èšå®
ç²ããŠããªãïŒ ããªãã¯èªåã«åŒ·ãã«ã¢ã¡ã泚ããèèãããããããšãã§ããŸããç§ãã¡ã¯ãŸãã«å§ãŸãã§ãïŒ
ãªãã»ãã+8ã«ã¯ã USBINTRã¬ãžã¹ã¿ããããŸã-å²ã蟌ã¿ã€ããŒãã«ã¬ãžã¹ã¿
é·æéæžã蟌ãŸãªãããã«ããããã«ãããã«é·ãéèªã¿åããªãããã«ããããã«ããã®ã¬ãžã¹ã¿ã®ãããã®å€ã¯ä»æ§ã§èŠã€ããããšãã§ããŸãããã®ãªã³ã¯ã¯ä»¥äžã«æ®ãããŸãã ããã§ã¯ã0ãæžã蟌ãã ãã§ãã ç§ã¯ãã³ãã©ãŒããããå²ã蟌ã¿ãªã©ãæžãããšã絶察ã«æãã§ããªãã®ã§ãããã¯ã»ãšãã©å®å šã«ç¡æå³ã ãšæããŸãã
ãªãã»ãã+12ïŒ0x0CïŒã§ã¯ã FRINDEXã¬ãžã¹ã¿ããã ãçŸåšã®ãã¬ãŒã çªå·ãåçŽã«ååšããŸããæåŸã®4ãããã¯ãã€ã¯ããã¬ãŒã çªå·ã瀺ããäžäœ28ãããã§ã¯ãã¬ãŒã çªå·ã瀺ããŸãïŒå€ã¯å¿ ãããframeListãµã€ãºããå°ãããšã¯éããŸããïŒãã ããã€ã³ããã¯ã¹ãå¿ èŠãªå Žåã¯ã0x3FFïŒãŸãã¯0x1FFãªã©ïŒã®ãã¹ã¯ã䜿çšããŠååŸããããšããå§ãããŸãã
CTRLDSSEGMENTã¬ãžã¹ã¿ã¯ãªãã»ãã+ 0x10ã«ããããã¹ãã³ã³ãããŒã©ãŒã«ãã¬ãŒã ã·ãŒãã®ã¢ãã¬ã¹ã®æäžäœ32ãããã衚瀺ããŸãã
PERIODICLISTBASEã¬ãžã¹ã¿ã«ã¯+ 0x14ã®ãªãã»ããããããŸãããã¬ãŒã ã·ãŒãã®äžäœ32ããããé 眮ã§ããŸããã¢ãã¬ã¹ã¯ã¡ã¢ãªããŒãžã®ãµã€ãºïŒ4096ïŒã«æããå¿ èŠãããããšã«æ³šæããŠãã ããã
ASYNCLISTADDRã¬ãžã¹ã¿ã«ã¯+ 0x18ã®ãªãã»ããããããŸããéåæãã¥ãŒã®ã¢ãã¬ã¹ãå ¥ããããšãã§ããŸãã32ãã€ãã®å¢çã«é 眮ããå¿ èŠããããŸãããç©çã¡ã¢ãªã®æåã®4ã®ã¬ãã€ãã«ããå¿ èŠããããŸãã
CONFIGFLAGã¬ãžã¹ã¿ã¯ãããã€ã¹ãæ§æãããŠãããã©ããã瀺ããŸãã ããã€ã¹ã®ã»ããã¢ãããå®äºããããããã0ãèšå®ããå¿ èŠããããŸãããªãã»ããã¯+ 0x40ã§ãã
ããŒãã¬ãžã¹ã¿ã«ç§»ããŸãããã åããŒãã«ã¯ç¬èªã®ã³ãã³ãã¹ããŒã¿ã¹ã¬ãžã¹ã¿ããããåããŒãã¬ãžã¹ã¿ã¯ãªãã»ãã+ 0x44 +ïŒPortNumber-1ïŒ* 4㧠ããã®ãããã¯æ¬¡ã®ããšãæå³ããŸãã
- ããã12-ããŒãé»æºã1-é»æºãäŸçµŠãããŠããã0-ãããã
- ããã8-ããŒãã¬ã¹ã-ããã€ã¹ããªã»ããããããã«èšå®ãããŸãã
- ããã3-ããŒãã®æå¹å/ç¡å¹åã®å€æŽ-ããŒãã®ãå å«ãã®ã¹ããŒã¿ã¹ãå€æŽãããšãã«èšå®ããŸãã
- ããã2-ããŒãã®ãªã³/ãªãã
- ããã1-æ¥ç¶ã¹ããŒã¿ã¹ãå€æŽããŸããããšãã°ãUSBããã€ã¹ãæ¥ç¶ãŸãã¯åæããå Žåã1ã«èšå®ãããŸãã
- ããã0-æ¥ç¶ã¹ããŒã¿ã¹ã1-æ¥ç¶æžã¿ã0-ãããã
ããã§ã¯ããžã¥ãŒã¹ãã®ãã®ã«ç§»ããŸãããã
ããŒã¿è»¢éãšã¯ãšãªæ§é
èŠæ±ãåŠçããããã®æ§é ã®ç·šæã«ã¯ããã¥ãŒãšè»¢éèšè¿°åïŒTDïŒãå«ãŸããŸãã
çŸæç¹ã§ã¯ã3ã€ã®æ§é ã®ã¿ãèæ ®ããŸãã
ã·ãŒã±ã³ã·ã£ã«ãªã¹ã
ã·ãŒã±ã³ã·ã£ã«ïŒå®æçãå®æçïŒãªã¹ãã¯æ¬¡ã®ããã«æ§æãããŠããŸãã

å³ãããããããã«ãåŠçã¯ã·ãŒããã¬ãŒã ããç®çã®ãã¬ãŒã ãååŸããããšããå§ãŸããŸããåèŠçŽ ã¯4ãã€ãã§ã次ã®æ§é ãæã£ãŠããŸãã

å³ã§ãããããã«ãèšè¿°åã®ãã¥ãŒã¢ãã¬ã¹/転éã¯32ãã€ãã®å¢çã«é 眮ãããŸããããã0ã¯ãã¹ãã³ã³ãããŒã©ãŒããã®èŠçŽ ãåŠçããªãããšãæå³ããŸããããã3ïŒ1ã¯ãã¹ãã³ã³ãããŒã©ãŒãåŠçãããã®ã®ã¿ã€ãã瀺ããŸãã ïŒiTDïŒã1-ãã®èšäºã®1ã2ã3ãæ€èšããŸããã
éåæãã¥ãŒ
ãã¹ãã³ã³ãããŒã©ãŒã¯ãã·ãŒã±ã³ã·ã£ã«ãã¬ãŒã ã空ã§ãããããã¹ãã³ã³ãããŒã©ãŒãã·ãªã¢ã«ãªã¹ãå šäœãåŠçããå Žåã«ã®ã¿ããã®ãã¥ãŒãåŠçããŸãã
éåæãã¥ãŒã¯ãåŠçãå¿ èŠãªä»ã®ãã¥ãŒãå«ããã¥ãŒãžã®ãã€ã³ã¿ãŒã§ãã ã¹ããŒã ïŒ

qTDïŒãã¥ãŒèŠçŽ 転éèšè¿°åïŒ
ãã®TDã®æ§é ã¯æ¬¡ã®ãšããã§ãã

次ã®qTDãã€ã³ã¿ãŒ -åŠçã®ããã®ãã¥ãŒã®ç¶ç¶ãžã®ãã€ã³ã¿ãŒ ïŒæ°Žå¹³å®è¡ã®å ŽåïŒãããã0次ã®qTDãã€ã³ã¿ãŒã¯ããã¥ãŒããªãããšã瀺ããŸãã
qTDããŒã¯ã³ -TDããŒã¯ã³ãããŒã¿è»¢éãã©ã¡ãŒã¿ãŒã瀺ããŸãã
- ããã31-ããŒã¿ã®åãæ¿ãïŒè©³çŽ°ã¯åŸã»ã©ïŒ
- ããã30:16-転éããããŒã¿ã®éããã©ã³ã¶ã¯ã·ã§ã³ãå®äºããåŸã転éãããããŒã¿ã®éã ãå€ãæžå°ããŸãã
- ããã15-IOC-å®äºæã«å²ã蟌ã¿-èšè¿°ååŠçãå®äºããåŸã«å²ã蟌ã¿ãçºçãããŸãã
- ããã14:12ã¯ãããŒã¿ã®äº€æå ãšãªãçŸåšã®ãããã¡ã®çªå·ã瀺ããŸããããã«ã€ããŠã¯åŸã§è©³ãã説æããŸãã
- ããã11:10-èš±å¯ããããšã©ãŒã®æ°ã 次ã®è¡šã¯ããšã©ãŒã«ãŠã³ããæžå°ããã¿ã€ãã³ã°ã瀺ããŠããŸãã
è泚1-BabbleãŸãã¯Stallãæ€åºãããšããã¥ãŒã®å é ã®å®è¡ãèªåçã«åæ¢ããŸãã è泚3-ããŒã¿ãããã¡ãšã©ãŒã¯ãã¹ãã®åé¡ã§ãã ããã€ã¹ã®åè©Šè¡ã¯èæ ®ãããŸããã - 9ïŒ8-PIDã³ãŒã-ããŒã¯ã³ã®ã¿ã€ãïŒ0-å ¥åãžã®ããŒã¯ã³ïŒãã¹ãããããã€ã¹ãžïŒã1-åºåãžã®ããŒã¯ã³ïŒããã€ã¹ãããã¹ããžïŒã2-ãã»ããã¢ãããããŒã¯ã³
- ããã7ïŒ0ã¯TDã¹ããŒã¿ã¹ã瀺ããŸãïŒ
ããã7ã¯ããã®TDãã¢ã¯ãã£ãç¶æ ã§ããããšã瀺ããŸãïŒã€ãŸãããã¹ãã³ã³ãããŒã©ãŒããã®TDãåŠçããŠããŸãïŒ
ããã6-åæ¢-ãšã©ãŒãçºçããTDã®å®è¡ãåæ¢ããããšã瀺ããŸãã
ããã4-æ€åºãããããã«-ããã€ã¹ã«éä¿¡ããããŒã¿ã®éããŸãã¯1å転ãããã®ããŒã¿éãéä¿¡éããå°ãªããã€ãŸããããšãã°ãããã€ã¹ã100ãã€ãã®ããŒã¿ãéä¿¡ãã50ãã€ãã ããèªã¿åã£ãåŸãããã«50ãã€ããèªã¿åã£ããã®ãããã1ã«èšå®ãããŠããå Žåãåæ¢ããããèšå®ãããŸãã
ããã3-ãã©ã³ã¶ã¯ã·ã§ã³ãšã©ãŒ-ãã©ã³ã¶ã¯ã·ã§ã³äžã«ãšã©ãŒãçºçããŸããã
qTDãããã¡ãŒããŒãžãã€ã³ã¿ãŒãªã¹ã -5ã€ã®ãããã¡ãŒã®ããããã ã¡ã¢ãªå ã®ãã©ã³ã¶ã¯ã·ã§ã³ãè¡ãããå ŽæïŒããã€ã¹ãžã®ããŒã¿ã®éä¿¡/ããã€ã¹ããã®ããŒã¿ã®åä¿¡ïŒãžã®ãªã³ã¯ãå«ãŸããæåã®ãããã¡ãé€ããããã¡å ã®ãã¹ãŠã®ã¢ãã¬ã¹ãããŒãžã®ãµã€ãºïŒ4096ãã€ãïŒã«æããããå¿ èŠããããŸãã
è¡é
ãã¥ãŒãããã®æ§é ã¯æ¬¡ã®ãšããã§ãã

ãã¥ãŒãããæ°Žå¹³ãªã³ã¯ãã€ã³ã¿ãŒ -次ã®ãã¥ãŒãžã®ãã€ã³ã¿ãŒ ãããã2ïŒ1ã«ã¯ãã¥ãŒã®ã¿ã€ãã«å¿ããŠæ¬¡ã®å€ããããŸãã

ãšã³ããã€ã³ãæ©èœ/ç¹æ§ -ãã¥ãŒã®ç¹æ§ïŒ
- ããã26:16ã«ã¯ãéä¿¡çšã®æ倧ãã±ãããµã€ãºãå«ãŸããŸã
- ããã14ïŒããŒã¿ãã°ã«å¶åŸ¡-ãã¹ãã³ã³ãããŒã©ãŒãåæããŒã¿ãã°ã«å€ãååŸããå Žæã瀺ããŸãã0-qTDã®DTããããç¡èŠãããã¥ãŒãããã®DTããããä¿åããŸãã
- ããã13:12-äŒéé床ç¹æ§ïŒ
- ããã11ïŒ8-èŠæ±ãè¡ããããšã³ããã€ã³ãã®çªå·
- ããã6ïŒ0-ããã€ã¹ã¢ãã¬ã¹
ãšã³ããã€ã³ãæ©èœïŒãã¥ãŒãããDWord 2-åã®ããã«ã¯ãŒãã®ç¶ãïŒ
- ããã29:23-ããçªå·
- ããã22:16-ããã¢ãã¬ã¹
çŸåšã®qTDãªã³ã¯ãã€ã³ã¿ãŒ -çŸåšã®qTDãžã®ãã€ã³ã¿ãŒã
æãèå³æ·±ããã®ã«æž¡ããŸãã
EHCIãã©ã€ããŒ
EHCIãã©ã®ãããªãªã¯ãšã¹ããåŠçã§ãããããå§ããŸãããã ãªã¯ãšã¹ãã«ã¯2ã€ã®ã¿ã€ãããããŸããããšãã°ãã³ã³ãããŒã«-aã³ãã³ããããã³ãã«ã¯-ãšã³ããã€ã³ããžã®ããŒã¿äº€æã§ããããšãã°ã倧éšåã®USBãã©ãã·ã¥ãã©ã€ãïŒUSB MassStorageïŒã¯ããŒã¿è»¢éã¿ã€ãBulk / Bulk / Bulkã䜿çšããŸãã ããŠã¹ãšããŒããŒãããããŒã¿è»¢éã«ãã«ã¯èŠæ±ã䜿çšããŸãã
EHCIãåæåããéåæããã³é 次ãã¥ãŒãæ§æããŸãã
// Base I/O Address PciBar bar; PciGetBar(&bar, id, 0); EhciController *hc = VMAlloc(sizeof(EhciController)); hc->capRegs = (EhciCapRegs *)(uintptr_t)bar.u.address; hc->opRegs = (EhciOpRegs *)(uintptr_t)(bar.u.address + hc->capRegs->capLength); // Read the Command register // uint cmd = ROR(usbCmdO); // Write it back, setting bit 2 (the Reset bit) // , 2(Reset) // and making sure the two schedule Enable bits are clear. // , 2 WOR(usbCmdO, 2 | cmd & ~(CMD_ASE | CMD_PSE)); // A small delay here would be good. You don't want to read // , // the register before it has a chance to actually set the bit // , ROR(usbCmdO); // Now wait for the controller to clear the reset bit. // Reset while (ROR(usbCmdO) & 2); // Again, a small delay here would be good to allow the // reset to actually become complete. // ROR(usbCmdO); // wait for the halted bit to become set // Halted while (!(ROR(usbStsO) & STS_HCHALTED)); // , // , 128 hc->frameList = (u32 *)VMAlloc(1024 * sizeof(u32) + 8192 * 4); hc->frameList = (((uint)hc->frameList) / 16384) * 16384 + 16384; hc->qhPool = (EhciQH *)VMAlloc(sizeof(EhciQH) * MAX_QH + 8192 * 4); hc->tdPool = (EhciTD *)VMAlloc(sizeof(EhciTD) * MAX_TD + 8192 * 4); hc->qhPool = (((uint)hc->qhPool) / 16384) * 16384 + 16384; hc->tdPool = (((uint)hc->tdPool) / 16384) * 16384 + 16384; // Asynchronous queue setup // EhciQH *qh = EhciAllocQH(hc); // , // , qh->qhlp = (u32)(uintptr_t)qh | PTR_QH; // , , qh->ch = QH_CH_H; qh->caps = 0; qh->curLink = 0; qh->nextLink = PTR_TERMINATE; qh->altLink = 0; qh->token = 0; // for (uint i = 0; i < 5; ++i) { qh->buffer[i] = 0; qh->extBuffer[i] = 0; } hc->asyncQH = qh; // Periodic list queue setup // qh = EhciAllocQH(hc); // qh->qhlp = PTR_TERMINATE; qh->ch = 0; qh->caps = 0; qh->curLink = 0; qh->nextLink = PTR_TERMINATE; qh->altLink = 0; qh->token = 0; // for (uint i = 0; i < 5; ++i) { qh->buffer[i] = 0; qh->extBuffer[i] = 0; } qh->transfer = 0; qh->qhLink.prev = &qh->qhLink; qh->qhLink.next = &qh->qhLink; hc->periodicQH = qh; // for (uint i = 0; i < 1024; ++i) hc->frameList[i] = PTR_QH | (u32)(uintptr_t)qh; kprintf("FrameList filled. Turning off Legacy BIOS support..."); // Check extended capabilities // BIOS Legacy support uint eecp = (RCR(hccParamsO) & HCCPARAMS_EECP_MASK) >> HCCPARAMS_EECP_SHIFT; if (eecp >= 0x40) { // Disable BIOS legacy support uint legsup = PciRead32(id, eecp + USBLEGSUP); kprintf("."); if (legsup & USBLEGSUP_HC_BIOS) { PciWrite32(id, eecp + USBLEGSUP, legsup | USBLEGSUP_HC_OS); kprintf("."); for (;;) { legsup = PciRead32(id, eecp + USBLEGSUP); kprintf("."); if (~legsup & USBLEGSUP_HC_BIOS && legsup & USBLEGSUP_HC_OS) { break; } } } } kprintf("Done\n"); // Disable interrupts // //hc->opRegs->usbIntr = 0; MWIR(ehcibase, usbIntrO, 0); // Setup frame list // //hc->opRegs->frameIndex = 0; WOR(frameIndexO, 0); //hc->opRegs->periodicListBase = (u32)(uintptr_t)hc->frameList; WOR(periodicListBaseO, (u32)(uintptr_t)hc->frameList); // //hc->opRegs->asyncListAddr = (u32)(uintptr_t)hc->asyncQH; WOR(asyncListAddrO, (u32)(uintptr_t)hc->asyncQH); // 0 //hc->opRegs->ctrlDsSegment = 0; WOR(ctrlDsSegmentO, 0); // Clear status // //hc->opRegs->usbSts = ~0; WOR(usbStsO, ~0); // Enable controller // , 8 -, // //hc->opRegs->usbCmd = (8 << CMD_ITC_SHIFT) | CMD_PSE | CMD_ASE | CMD_RS; WOR(usbCmdO, (8 << CMD_ITC_SHIFT) | CMD_PSE | CMD_ASE | CMD_RS); while (ROR(usbStsO)&STS_HCHALTED); // Configure all devices to be managed by the EHCI // , //hc->opRegs->configFlag = 1; WOR(configFlagO, 1);\ // Probe devices // EhciProbe(hc);
å®éã«ã¯ãããŒããå ã®ç¶æ ã«ãªã»ããããããã®ã³ãŒãïŒ
volatile u32 *reg = &hc->opRegs->ports[port]; // , 100 *reg|=(1<<12)|(1<<20); Wait(100); // , 50 EhciPortSet(reg, PORT_RESET | (1<<12) | (1<<20) | (1<<6)); Wait(50); EhciPortClr(reg, PORT_RESET); // Wait 100ms for port to enable (TODO - what is appropriate length of time?) // 100 , , // 100 uint status = 0; for (uint i = 0; i < 10; ++i) { // Delay Wait(10); // Get current status // status = *reg; // Check if device is attached to port // if (~status & PORT_CONNECTION) break; // Acknowledge change in status // - if (status & (PORT_ENABLE_CHANGE | PORT_CONNECTION_CHANGE)) { EhciPortClr(reg, PORT_ENABLE_CHANGE | PORT_CONNECTION_CHANGE); continue; } // Check if device is enabled // , if (status & PORT_ENABLE) break; } return status;
ããã€ã¹ãžã®å¶åŸ¡èŠæ±ïŒ
static void EhciDevControl(UsbDevice *dev, UsbTransfer *t) { EhciController *hc = (EhciController *)dev->hc; UsbDevReq *req = t->req; // Determine transfer properties // uint speed = dev->speed; uint addr = dev->addr; uint maxSize = dev->maxPacketSize; uint type = req->type; uint len = req->len; // Create queue of transfer descriptors // TDs EhciTD *td = EhciAllocTD(hc); if (!td) return; EhciTD *head = td; EhciTD *prev = 0; // Setup packet // uint toggle = 0; uint packetType = USB_PACKET_SETUP; uint packetSize = sizeof(UsbDevReq); EhciInitTD(td, prev, toggle, packetType, packetSize, req); prev = td; // Data in/out packets packetType = type & RT_DEV_TO_HOST ? USB_PACKET_IN : USB_PACKET_OUT; u8 *it = (u8 *)t->data; u8 *end = it + len; //EhciPrintTD(td); while (it < end) { td = EhciAllocTD(hc); if (!td) return; toggle ^= 1; packetSize = end - it; if (packetSize > maxSize) packetSize = maxSize; EhciInitTD(td, prev, toggle, packetType, packetSize, it); it += packetSize; prev = td; } // Status packet // td = EhciAllocTD(hc); if (!td) return; toggle = 1; packetType = type & RT_DEV_TO_HOST ? USB_PACKET_OUT : USB_PACKET_IN; EhciInitTD(td, prev, toggle, packetType, 0, 0); // Initialize queue head // : EhciQH *qh = EhciAllocQH(hc); EhciInitQH(qh, t, head, dev->parent, false, speed, addr, 0, maxSize); // Wait until queue has been processed // EhciInsertAsyncQH(hc->asyncQH, qh); EhciWaitForQH(hc, qh); }
ãã¥ãŒåŠçã³ãŒãïŒ
if (qh->token & TD_TOK_HALTED) { t->success = false; t->complete = true; } else if (qh->nextLink & PTR_TERMINATE) if (~qh->token & TD_TOK_ACTIVE) { if (qh->token & TD_TOK_DATABUFFER) kprintf(" Data Buffer Error\n"); if (qh->token & TD_TOK_BABBLE) kprintf(" Babble Detected\n"); if (qh->token & TD_TOK_XACT) kprintf(" Transaction Error\n"); if (qh->token & TD_TOK_MMF) kprintf(" Missed Micro-Frame\n"); t->success = true; t->complete = true; } if (t->complete) ....
ãããŠä»ããšã³ããã€ã³ãèŠæ±ïŒãã«ã¯èŠæ±ïŒ
static void EhciDevIntr(UsbDevice *dev, UsbTransfer *t) { EhciController *hc = (EhciController *)dev->hc; // Determine transfer properties // uint speed = dev->speed; uint addr = dev->addr; uint maxSize = t->endp->desc->maxPacketSize; uint endp = t->endp->desc->addr & 0xf; EhciTD *td = EhciAllocTD(hc); if (!td) { t->success = false; t->complete = true; return; } EhciTD *head = td; EhciTD *prev = 0; // Data in/out packets uint toggle = t->endp->toggle; uint packetType = t->endp->desc->addr & 0x80 ? USB_PACKET_IN : USB_PACKET_OUT; uint packetSize = t->len; EhciInitTD(td, prev, toggle, packetType, packetSize, t->data); // Initialize queue head // EhciQH *qh = EhciAllocQH(hc); EhciInitQH(qh, t, head, dev->parent, true, speed, addr, endp, maxSize); //printQh(qh); // Schedule queue // EhciInsertPeriodicQH(hc->periodicQH, qh); }
ãã®ãããã¯ã¯éåžžã«èå³æ·±ããšæããŸãããã·ã¢èªã®ã€ã³ã¿ãŒãããäžã§ã¯ããã®ãããã¯ã«é¢ããããã¥ã¡ã³ãã説æãèšäºã¯ã»ãšãã©ãªããååšããå Žåã¯éåžžã«ãŒãããŠããŸãã ããŒããŠã§ã¢ãšOSéçºã®äœæ¥ã®ãããã¯ãèå³æ·±ãå Žåãå€ãã®ããšãäŒããå¿ èŠããããŸãã
ããã¯ïŒ ä»æ§