musb.c 95 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747
  1. /*++
  2. Copyright (c) 2015 Minoca Corp. All Rights Reserved
  3. Module Name:
  4. musb.c
  5. Abstract:
  6. This module implements support for the Mentor Graphics USB 2.0 OTG
  7. controller.
  8. Author:
  9. Evan Green 11-Sep-2015
  10. Environment:
  11. Kernel
  12. --*/
  13. //
  14. // ------------------------------------------------------------------- Includes
  15. //
  16. #include <minoca/kernel/driver.h>
  17. #include <minoca/usb/usbhost.h>
  18. #include "musb.h"
  19. //
  20. // --------------------------------------------------------------------- Macros
  21. //
  22. #define MUSB_READ8(_Controller, _Register) \
  23. HlReadRegister8((_Controller)->ControllerBase + (_Register))
  24. #define MUSB_WRITE8(_Controller, _Register, _Value) \
  25. HlWriteRegister8((_Controller)->ControllerBase + (_Register), (_Value))
  26. #define MUSB_READ16(_Controller, _Register) \
  27. HlReadRegister16((_Controller)->ControllerBase + (_Register))
  28. #define MUSB_WRITE16(_Controller, _Register, _Value) \
  29. HlWriteRegister16((_Controller)->ControllerBase + (_Register), (_Value))
  30. //
  31. // ---------------------------------------------------------------- Definitions
  32. //
  33. //
  34. // ------------------------------------------------------ Data Type Definitions
  35. //
  36. //
  37. // ----------------------------------------------- Internal Function Prototypes
  38. //
  39. VOID
  40. MusbpCppiDmaCompletionCallback (
  41. PVOID Context,
  42. ULONG DmaEndpoint,
  43. BOOL Transmit
  44. );
  45. KSTATUS
  46. MusbpCreateEndpoint (
  47. PVOID HostControllerContext,
  48. PUSB_HOST_ENDPOINT_CREATION_REQUEST Endpoint,
  49. PVOID *EndpointContext
  50. );
  51. VOID
  52. MusbpResetEndpoint (
  53. PVOID HostControllerContext,
  54. PVOID EndpointContext,
  55. ULONG MaxPacketSize
  56. );
  57. KSTATUS
  58. MusbpFlushEndpoint (
  59. PVOID HostControllerContext,
  60. PVOID EndpointContext,
  61. PULONG TransferCount
  62. );
  63. VOID
  64. MusbpDestroyEndpoint (
  65. PVOID HostControllerContext,
  66. PVOID EndpointContext
  67. );
  68. KSTATUS
  69. MusbpCreateTransfer (
  70. PVOID HostControllerContext,
  71. PVOID EndpointContext,
  72. ULONG Flags,
  73. ULONG MaxBufferSize,
  74. PVOID *TransferContext
  75. );
  76. VOID
  77. MusbpDestroyTransfer (
  78. PVOID HostControllerContext,
  79. PVOID EndpointContext,
  80. PVOID TransferContext
  81. );
  82. KSTATUS
  83. MusbpSubmitTransfer (
  84. PVOID HostControllerContext,
  85. PVOID EndpointContext,
  86. PUSB_TRANSFER_INTERNAL Transfer,
  87. PVOID TransferContext
  88. );
  89. KSTATUS
  90. MusbpSubmitPolledTransfer (
  91. PVOID HostControllerContext,
  92. PVOID EndpointContext,
  93. PUSB_TRANSFER_INTERNAL Transfer,
  94. PVOID TransferContext
  95. );
  96. KSTATUS
  97. MusbpCancelTransfer (
  98. PVOID HostControllerContext,
  99. PVOID EndpointContext,
  100. PUSB_TRANSFER_INTERNAL Transfer,
  101. PVOID TransferContext
  102. );
  103. KSTATUS
  104. MusbpGetRootHubStatus (
  105. PVOID HostControllerContext,
  106. PUSB_HUB_STATUS HubStatus
  107. );
  108. KSTATUS
  109. MusbpSetRootHubStatus (
  110. PVOID HostControllerContext,
  111. PUSB_HUB_STATUS HubStatus
  112. );
  113. VOID
  114. MusbpProcessUsbInterrupts (
  115. PMUSB_CONTROLLER Controller,
  116. UCHAR UsbInterrupts
  117. );
  118. VOID
  119. MusbpProcessEndpointInterrupts (
  120. PMUSB_CONTROLLER Controller,
  121. ULONG EndpointInterrupts
  122. );
  123. KSTATUS
  124. MusbpInitializeTransfer (
  125. PMUSB_CONTROLLER Controller,
  126. PMUSB_SOFT_ENDPOINT SoftEndpoint,
  127. PUSB_TRANSFER_INTERNAL Transfer,
  128. PMUSB_TRANSFER_SET TransferSet
  129. );
  130. VOID
  131. MusbpExecuteNextTransfer (
  132. PMUSB_CONTROLLER Controller,
  133. PMUSB_HARD_ENDPOINT HardEndpoint
  134. );
  135. PMUSB_TRANSFER_SET
  136. MusbpProcessCompletedTransfer (
  137. PMUSB_CONTROLLER Controller,
  138. UCHAR HardwareIndex,
  139. PBOOL TransferCompleted
  140. );
  141. VOID
  142. MusbpFailAllTransfers (
  143. PMUSB_CONTROLLER Controller
  144. );
  145. VOID
  146. MusbpConfigureFifo (
  147. PMUSB_CONTROLLER Controller,
  148. PMUSB_FIFO_CONFIGURATION Configuration,
  149. PULONG Offset
  150. );
  151. VOID
  152. MusbpAbortTransfer (
  153. PMUSB_CONTROLLER Controller,
  154. UCHAR HardwareIndex,
  155. PMUSB_TRANSFER Transfer
  156. );
  157. VOID
  158. MusbpConfigureHardwareEndpoint (
  159. PMUSB_CONTROLLER Controller,
  160. PMUSB_SOFT_ENDPOINT SoftEndpoint
  161. );
  162. VOID
  163. MusbpUpdateDataToggle (
  164. PMUSB_CONTROLLER Controller,
  165. PMUSB_TRANSFER_SET TransferSet
  166. );
  167. VOID
  168. MusbpWriteFifo (
  169. PMUSB_CONTROLLER Controller,
  170. UCHAR EndpointIndex,
  171. PVOID Buffer,
  172. ULONG Size
  173. );
  174. VOID
  175. MusbpReadFifo (
  176. PMUSB_CONTROLLER Controller,
  177. UCHAR EndpointIndex,
  178. PVOID Buffer,
  179. ULONG BufferSize
  180. );
  181. VOID
  182. MusbpFlushFifo (
  183. PMUSB_CONTROLLER Controller,
  184. UCHAR HardwareIndex,
  185. BOOL HostOut
  186. );
  187. VOID
  188. MusbpAssignEndpoint (
  189. PMUSB_CONTROLLER Controller,
  190. PMUSB_SOFT_ENDPOINT SoftEndpoint
  191. );
  192. UCHAR
  193. MusbpReadIndexed8 (
  194. PMUSB_CONTROLLER Controller,
  195. UCHAR Index,
  196. MUSB_INDEXED_REGISTER Register
  197. );
  198. UCHAR
  199. MusbpReadIndexed16 (
  200. PMUSB_CONTROLLER Controller,
  201. UCHAR Index,
  202. MUSB_INDEXED_REGISTER Register
  203. );
  204. VOID
  205. MusbpWriteIndexed8 (
  206. PMUSB_CONTROLLER Controller,
  207. UCHAR Index,
  208. MUSB_INDEXED_REGISTER Register,
  209. UCHAR Value
  210. );
  211. VOID
  212. MusbpWriteIndexed16 (
  213. PMUSB_CONTROLLER Controller,
  214. UCHAR Index,
  215. MUSB_INDEXED_REGISTER Register,
  216. USHORT Value
  217. );
  218. VOID
  219. MusbpAcquireLock (
  220. PMUSB_CONTROLLER Controller
  221. );
  222. VOID
  223. MusbpReleaseLock (
  224. PMUSB_CONTROLLER Controller
  225. );
  226. //
  227. // -------------------------------------------------------------------- Globals
  228. //
  229. //
  230. // Set this boolean to disable DMA. This must be set before endpoint creation.
  231. //
  232. BOOL MusbDisableDma = FALSE;
  233. USB_HOST_CONTROLLER_INTERFACE MusbUsbHostInterfaceTemplate = {
  234. USB_HOST_CONTROLLER_INTERFACE_VERSION,
  235. NULL,
  236. NULL,
  237. NULL,
  238. 0,
  239. -1,
  240. UsbDeviceSpeedHigh,
  241. 1,
  242. MusbpCreateEndpoint,
  243. MusbpResetEndpoint,
  244. MusbpFlushEndpoint,
  245. MusbpDestroyEndpoint,
  246. MusbpCreateTransfer,
  247. MusbpDestroyTransfer,
  248. MusbpSubmitTransfer,
  249. MusbpSubmitPolledTransfer,
  250. MusbpCancelTransfer,
  251. MusbpGetRootHubStatus,
  252. MusbpSetRootHubStatus
  253. };
  254. MUSB_FIFO_CONFIGURATION MusbFifoConfiguration[] = {
  255. {1, MusbEndpointTx, 512},
  256. {1, MusbEndpointRx, 512},
  257. {2, MusbEndpointTx, 512},
  258. {2, MusbEndpointRx, 512},
  259. {3, MusbEndpointTx, 512},
  260. {3, MusbEndpointRx, 512},
  261. {4, MusbEndpointTx, 512},
  262. {4, MusbEndpointRx, 512},
  263. {5, MusbEndpointTx, 512},
  264. {5, MusbEndpointRx, 512},
  265. {6, MusbEndpointTx, 512},
  266. {6, MusbEndpointRx, 512},
  267. {7, MusbEndpointTx, 512},
  268. {7, MusbEndpointRx, 512},
  269. {8, MusbEndpointTx, 512},
  270. {8, MusbEndpointRx, 512},
  271. {9, MusbEndpointTx, 512},
  272. {9, MusbEndpointRx, 512},
  273. {10, MusbEndpointTx, 256},
  274. {10, MusbEndpointRx, 64},
  275. {11, MusbEndpointTx, 256},
  276. {11, MusbEndpointRx, 64},
  277. {12, MusbEndpointTx, 256},
  278. {12, MusbEndpointRx, 64},
  279. {13, MusbEndpointTx, 4096},
  280. {14, MusbEndpointRx, 1024},
  281. {15, MusbEndpointTx, 1024},
  282. {0, 0, 0}
  283. };
  284. //
  285. // ------------------------------------------------------------------ Functions
  286. //
  287. KSTATUS
  288. MusbInitializeControllerState (
  289. PMUSB_CONTROLLER Controller,
  290. PVOID RegisterBase,
  291. PDRIVER Driver,
  292. PHYSICAL_ADDRESS PhysicalBase,
  293. PCPPI_DMA_CONTROLLER DmaController,
  294. UCHAR Instance
  295. )
  296. /*++
  297. Routine Description:
  298. This routine initializes data structures for the Mentor USB controller.
  299. It's assumed the controller structure has already been properly zeroed.
  300. Arguments:
  301. Controller - Supplies a pointer to the controller structure, which has
  302. already been zeroed.
  303. RegisterBase - Supplies the virtual address of the registers for the
  304. device.
  305. Driver - Supplies a pointer to the driver that owns this device.
  306. PhysicalBase - Supplies the physical address of the controller.
  307. DmaController - Supplies an optional pointer to the DMA controller to use.
  308. Instance - Supplies the instance ID to pass into the potentially shared
  309. DMA controller.
  310. Return Value:
  311. Status code.
  312. --*/
  313. {
  314. PMUSB_HARD_ENDPOINT Endpoint;
  315. ULONG Index;
  316. KSTATUS Status;
  317. Controller->ControllerBase = RegisterBase;
  318. Controller->Driver = Driver;
  319. Controller->PhysicalBase = PhysicalBase;
  320. Controller->NextEndpointAssignment = 1;
  321. Controller->CppiDma = DmaController;
  322. Controller->Instance = Instance;
  323. KeInitializeSpinLock(&(Controller->Lock));
  324. for (Index = 0; Index < MUSB_MAX_ENDPOINTS; Index += 1) {
  325. Endpoint = &(Controller->Endpoints[Index]);
  326. INITIALIZE_LIST_HEAD(&(Endpoint->TransferList));
  327. Endpoint->CurrentEndpoint = NULL;
  328. }
  329. if (DmaController != NULL) {
  330. CppiRegisterCompletionCallback(DmaController,
  331. Instance,
  332. MusbpCppiDmaCompletionCallback,
  333. Controller);
  334. }
  335. Status = STATUS_SUCCESS;
  336. if (!KSUCCESS(Status)) {
  337. MusbDestroyControllerState(Controller);
  338. }
  339. return STATUS_SUCCESS;
  340. }
  341. KSTATUS
  342. MusbDestroyControllerState (
  343. PMUSB_CONTROLLER Controller
  344. )
  345. /*++
  346. Routine Description:
  347. This routine destroys the given Mentor USB controller structure, freeing
  348. all resources associated with the controller except the controller
  349. structure itself and the register base, which were passed in on initialize.
  350. Arguments:
  351. Controller - Supplies a pointer to the controller to destroy.
  352. Return Value:
  353. Status code.
  354. --*/
  355. {
  356. Controller->ControllerBase = NULL;
  357. return STATUS_SUCCESS;
  358. }
  359. KSTATUS
  360. MusbResetController (
  361. PMUSB_CONTROLLER Controller
  362. )
  363. /*++
  364. Routine Description:
  365. This routine resets and reinitializes the given controller.
  366. Arguments:
  367. Controller - Supplies a pointer to the controller.
  368. Return Value:
  369. Status code.
  370. --*/
  371. {
  372. PMUSB_FIFO_CONFIGURATION Configuration;
  373. UCHAR DeviceControl;
  374. UCHAR EndpointCount;
  375. ULONG Offset;
  376. UCHAR UsbInterrupts;
  377. MUSB_WRITE8(Controller, MusbSoftReset, MUSB_SOFT_RESET_SOFT_RESET);
  378. EndpointCount = MUSB_READ8(Controller, MusbEndpointInfo);
  379. //
  380. // Determine the number of hardware endpoints.
  381. //
  382. Controller->EndpointCount =
  383. EndpointCount & MUSB_ENDPOINT_INFO_TX_COUNT_MASK;
  384. ASSERT(((EndpointCount &
  385. MUSB_ENDPOINT_INFO_RX_COUNT_MASK) >>
  386. MUSB_ENDPOINT_INFO_RX_COUNT_SHIFT) == Controller->EndpointCount);
  387. //
  388. // Program the FIFO configuration for the endpoints. Endpoint 0 always gets
  389. // the first 64 bytes.
  390. //
  391. Offset = 64;
  392. Configuration = MusbFifoConfiguration;
  393. while (Configuration->MaxPacketSize != 0) {
  394. if (Configuration->Endpoint < Controller->EndpointCount) {
  395. MusbpConfigureFifo(Controller, Configuration, &Offset);
  396. }
  397. Configuration += 1;
  398. }
  399. //
  400. // Enable all endpoint interrupts, and all USB interrupts except start of
  401. // frame.
  402. //
  403. MUSB_WRITE16(Controller, MusbInterruptEnableTx, 0xFFFF);
  404. MUSB_WRITE16(Controller, MusbInterruptEnableRx, 0xFFFF);
  405. UsbInterrupts = MUSB_USB_INTERRUPT_SUSPEND |
  406. MUSB_USB_INTERRUPT_RESUME |
  407. MUSB_USB_INTERRUPT_RESET_BABBLE |
  408. MUSB_USB_INTERRUPT_CONNECT |
  409. MUSB_USB_INTERRUPT_DISCONNECT |
  410. MUSB_USB_INTERRUPT_SESSION |
  411. MUSB_USB_INTERRUPT_VBUS_ERROR;
  412. Controller->UsbInterruptEnable = UsbInterrupts;
  413. MUSB_WRITE8(Controller, MusbInterruptEnableUsb, UsbInterrupts);
  414. //
  415. // Enable a session.
  416. //
  417. DeviceControl = MUSB_READ8(Controller, MusbDeviceControl);
  418. DeviceControl |= MUSB_DEVICE_CONTROL_SESSION;
  419. MUSB_WRITE8(Controller, MusbDeviceControl, DeviceControl);
  420. return STATUS_SUCCESS;
  421. }
  422. KSTATUS
  423. MusbRegisterController (
  424. PMUSB_CONTROLLER Controller,
  425. PDEVICE Device
  426. )
  427. /*++
  428. Routine Description:
  429. This routine registers the started Mentor USB controller with the core USB
  430. library.
  431. Arguments:
  432. Controller - Supplies a pointer to the state of the controller to register.
  433. Device - Supplies a pointer to the device object.
  434. Return Value:
  435. Status code.
  436. --*/
  437. {
  438. USB_HOST_CONTROLLER_INTERFACE Interface;
  439. KSTATUS Status;
  440. //
  441. // Fill out the functions that the USB core library will use to control
  442. // the host controller.
  443. //
  444. RtlCopyMemory(&Interface,
  445. &MusbUsbHostInterfaceTemplate,
  446. sizeof(USB_HOST_CONTROLLER_INTERFACE));
  447. Interface.DriverObject = Controller->Driver;
  448. Interface.DeviceObject = Device;
  449. Interface.HostControllerContext = Controller;
  450. Interface.Identifier = Controller->PhysicalBase;
  451. Status = UsbHostRegisterController(&Interface,
  452. &(Controller->UsbCoreHandle));
  453. if (!KSUCCESS(Status)) {
  454. goto RegisterControllerEnd;
  455. }
  456. RegisterControllerEnd:
  457. return Status;
  458. }
  459. INTERRUPT_STATUS
  460. MusbInterruptService (
  461. PVOID Context
  462. )
  463. /*++
  464. Routine Description:
  465. This routine implements the MUSB interrupt service routine.
  466. Arguments:
  467. Context - Supplies the context pointer given to the system when the
  468. interrupt was connected. In this case, this points to the controller.
  469. Return Value:
  470. Interrupt status.
  471. --*/
  472. {
  473. PMUSB_CONTROLLER Controller;
  474. ULONG EndpointStatus;
  475. INTERRUPT_STATUS InterruptStatus;
  476. USHORT RxStatus;
  477. USHORT TxStatus;
  478. USHORT UsbStatus;
  479. Controller = (PMUSB_CONTROLLER)Context;
  480. InterruptStatus = InterruptStatusNotClaimed;
  481. //
  482. // Read the status register. If it's non-zero, this is USB's interrupt.
  483. //
  484. UsbStatus = MUSB_READ8(Controller, MusbInterruptUsb) &
  485. Controller->UsbInterruptEnable;
  486. if (UsbStatus != 0) {
  487. InterruptStatus = InterruptStatusClaimed;
  488. RtlAtomicOr32(&(Controller->PendingUsbInterrupts), UsbStatus);
  489. //
  490. // Clear the bits in the status register to acknowledge the interrupt.
  491. //
  492. MUSB_WRITE8(Controller, MusbInterruptUsb, UsbStatus);
  493. }
  494. RxStatus = MUSB_READ16(Controller, MusbInterruptRx);
  495. TxStatus = MUSB_READ16(Controller, MusbInterruptTx);
  496. EndpointStatus = (RxStatus << 16) | TxStatus;
  497. if (EndpointStatus != 0) {
  498. InterruptStatus = InterruptStatusClaimed;
  499. RtlAtomicOr32(&(Controller->PendingEndpointInterrupts), EndpointStatus);
  500. if (RxStatus != 0) {
  501. MUSB_WRITE16(Controller, MusbInterruptRx, RxStatus);
  502. }
  503. if (TxStatus != 0) {
  504. MUSB_WRITE16(Controller, MusbInterruptTx, TxStatus);
  505. }
  506. }
  507. return InterruptStatus;
  508. }
  509. INTERRUPT_STATUS
  510. MusbInterruptServiceDpc (
  511. PVOID Parameter
  512. )
  513. /*++
  514. Routine Description:
  515. This routine implements the MUSB dispatch level interrupt service.
  516. Arguments:
  517. Parameter - Supplies the context, in this case the controller structure.
  518. Return Value:
  519. None.
  520. --*/
  521. {
  522. PMUSB_CONTROLLER Controller;
  523. ULONG EndpointInterrupts;
  524. ULONG UsbInterrupts;
  525. Controller = Parameter;
  526. UsbInterrupts = RtlAtomicExchange32(&(Controller->PendingUsbInterrupts), 0);
  527. EndpointInterrupts =
  528. RtlAtomicExchange32(&(Controller->PendingEndpointInterrupts), 0);
  529. if ((UsbInterrupts == 0) && (EndpointInterrupts == 0)) {
  530. return InterruptStatusNotClaimed;
  531. }
  532. if (UsbInterrupts != 0) {
  533. MusbpProcessUsbInterrupts(Controller, UsbInterrupts);
  534. }
  535. if (EndpointInterrupts != 0) {
  536. MusbpProcessEndpointInterrupts(Controller, EndpointInterrupts);
  537. }
  538. return InterruptStatusClaimed;
  539. }
  540. //
  541. // --------------------------------------------------------- Internal Functions
  542. //
  543. VOID
  544. MusbpCppiDmaCompletionCallback (
  545. PVOID Context,
  546. ULONG DmaEndpoint,
  547. BOOL Transmit
  548. )
  549. /*++
  550. Routine Description:
  551. This routine is called when CPPI receives an interrupt telling it that a
  552. queue completion occurred.
  553. Arguments:
  554. Context - Supplies an opaque pointer's worth of context for the callback
  555. routine.
  556. DmaEndpoint - Supplies the zero-based DMA endpoint number. Add 1 to get
  557. to a USB endpoint number.
  558. Transmit - Supplies a boolean indicating if this is a transmit completion
  559. (TRUE) or a receive completion (FALSE).
  560. Return Value:
  561. None.
  562. --*/
  563. {
  564. PMUSB_CONTROLLER Controller;
  565. ULONG Endpoint;
  566. ULONG Mask;
  567. Controller = Context;
  568. Endpoint = CPPI_DMA_ENDPOINT_TO_USB(DmaEndpoint);
  569. Mask = 1 << Endpoint;
  570. if (Transmit == FALSE) {
  571. Mask <<= 16;
  572. }
  573. MusbpProcessEndpointInterrupts(Controller, Mask);
  574. return;
  575. }
  576. KSTATUS
  577. MusbpCreateEndpoint (
  578. PVOID HostControllerContext,
  579. PUSB_HOST_ENDPOINT_CREATION_REQUEST Endpoint,
  580. PVOID *EndpointContext
  581. )
  582. /*++
  583. Routine Description:
  584. This routine is called by the USB core when a new endpoint is being opened.
  585. It allows the host controller to create and store any context needed to
  586. support a new endpoint (such as a queue head).
  587. Arguments:
  588. HostControllerContext - Supplies the context pointer passed to the USB core
  589. when the controller was created. This is used to identify the USB host
  590. controller to the host controller driver.
  591. Endpoint - Supplies a pointer containing information about the endpoint
  592. being created. The host controller cannot count on this buffer sticking
  593. around after the function returns. If it needs this information it
  594. should make a copy of it.
  595. EndpointContext - Supplies a pointer where the host controller can store a
  596. context pointer identifying the endpoint created.
  597. Return Value:
  598. STATUS_SUCCESS if the endpoint can be successfully accommodated.
  599. Failing status code if the endpoint cannot be opened.
  600. --*/
  601. {
  602. USHORT Control;
  603. PMUSB_CONTROLLER Controller;
  604. USHORT PollRate;
  605. PMUSB_SOFT_ENDPOINT SoftEndpoint;
  606. KSTATUS Status;
  607. UCHAR Type;
  608. Controller = HostControllerContext;
  609. PollRate = Endpoint->PollRate;
  610. //
  611. // For high speed endpoints, the interval is 2^(Interval - 1). This is
  612. // also true for full speed isochronous and full speed bulk (NAK count).
  613. // For other full/low speed endpoints, it's just a frame count.
  614. //
  615. if ((Endpoint->Speed == UsbDeviceSpeedHigh) ||
  616. ((Endpoint->Speed == UsbDeviceSpeedFull) &&
  617. ((Endpoint->Type == UsbTransferTypeIsochronous) ||
  618. (Endpoint->Type == UsbTransferTypeBulk)))) {
  619. if (PollRate != 0) {
  620. PollRate = RtlCountTrailingZeros32(PollRate) + 1;
  621. if (PollRate > 16) {
  622. PollRate = 16;
  623. }
  624. }
  625. }
  626. SoftEndpoint = MmAllocateNonPagedPool(sizeof(MUSB_SOFT_ENDPOINT),
  627. MUSB_ALLOCATION_TAG);
  628. if (SoftEndpoint == NULL) {
  629. Status = STATUS_INSUFFICIENT_RESOURCES;
  630. goto CreateEndpointEnd;
  631. }
  632. RtlZeroMemory(SoftEndpoint, sizeof(MUSB_SOFT_ENDPOINT));
  633. SoftEndpoint->MaxPayload = Endpoint->MaxPacketSize;
  634. SoftEndpoint->HubAddress = Endpoint->HubAddress;
  635. SoftEndpoint->HubPort = Endpoint->HubPortNumber;
  636. SoftEndpoint->EndpointNumber = Endpoint->EndpointNumber;
  637. Type = Endpoint->EndpointNumber & MUSB_TXTYPE_TARGET_ENDPOINT_MASK;
  638. switch (Endpoint->Speed) {
  639. case UsbDeviceSpeedLow:
  640. Type |= MUSB_TXTYPE_SPEED_LOW;
  641. break;
  642. case UsbDeviceSpeedFull:
  643. Type |= MUSB_TXTYPE_SPEED_FULL;
  644. break;
  645. case UsbDeviceSpeedHigh:
  646. Type |= MUSB_TXTYPE_SPEED_HIGH;
  647. break;
  648. default:
  649. ASSERT(FALSE);
  650. Status = STATUS_INVALID_PARAMETER;
  651. goto CreateEndpointEnd;
  652. }
  653. SoftEndpoint->Interval = PollRate;
  654. switch (Endpoint->Type) {
  655. case UsbTransferTypeControl:
  656. Type |= MUSB_TXTYPE_PROTOCOL_CONTROL;
  657. SoftEndpoint->HardwareIndex = 0;
  658. SoftEndpoint->Interval = 0;
  659. break;
  660. case UsbTransferTypeInterrupt:
  661. Type |= MUSB_TXTYPE_PROTOCOL_INTERRUPT;
  662. break;
  663. case UsbTransferTypeBulk:
  664. Type |= MUSB_TXTYPE_PROTOCOL_BULK;
  665. break;
  666. case UsbTransferTypeIsochronous:
  667. Type |= MUSB_TXTYPE_PROTOCOL_ISOCHRONOUS;
  668. break;
  669. default:
  670. ASSERT(FALSE);
  671. Status = STATUS_INVALID_PARAMETER;
  672. goto CreateEndpointEnd;
  673. }
  674. SoftEndpoint->Type = Type;
  675. SoftEndpoint->Direction = Endpoint->Direction;
  676. //
  677. // All control endpoints use hardware endpoint 0, and cannot use DMA. For
  678. // any other type, assign it a hard endpoint/channel.
  679. //
  680. if (Endpoint->Type == UsbTransferTypeControl) {
  681. //
  682. // Set the control endpoint direction to "out" so that the TX
  683. // control/status register is always used, which is required for
  684. // hardware endpoint 0.
  685. //
  686. SoftEndpoint->Direction = UsbTransferDirectionOut;
  687. } else {
  688. if ((MusbDisableDma == FALSE) && (Controller->CppiDma != NULL)) {
  689. Control = 0;
  690. if (Endpoint->Direction == UsbTransferDirectionOut) {
  691. Control |= MUSB_TX_CONTROL_DMA_ENABLE |
  692. MUSB_TX_CONTROL_DMA_MODE;
  693. } else {
  694. ASSERT(Endpoint->Direction == UsbTransferDirectionIn);
  695. Control |= MUSB_RX_CONTROL_DMA_ENABLE;
  696. }
  697. SoftEndpoint->Control = Control;
  698. }
  699. //
  700. // Find an initial hardware endpoint for this software endpoint.
  701. //
  702. MusbpAcquireLock(Controller);
  703. MusbpAssignEndpoint(Controller, SoftEndpoint);
  704. MusbpReleaseLock(Controller);
  705. }
  706. *EndpointContext = SoftEndpoint;
  707. Status = STATUS_SUCCESS;
  708. CreateEndpointEnd:
  709. if (!KSUCCESS(Status)) {
  710. if (SoftEndpoint != NULL) {
  711. MmFreePagedPool(SoftEndpoint);
  712. }
  713. }
  714. return Status;
  715. }
  716. VOID
  717. MusbpResetEndpoint (
  718. PVOID HostControllerContext,
  719. PVOID EndpointContext,
  720. ULONG MaxPacketSize
  721. )
  722. /*++
  723. Routine Description:
  724. This routine is called by the USB core when an endpoint needs to be reset.
  725. Arguments:
  726. HostControllerContext - Supplies the context pointer passed to the USB core
  727. when the controller was created. This is used to identify the USB host
  728. controller to the host controller driver.
  729. EndpointContext - Supplies a pointer to the context returned by the host
  730. controller when the endpoint was created.
  731. MaxPacketSize - Supplies the maximum transfer size of the endpoint.
  732. Return Value:
  733. None.
  734. --*/
  735. {
  736. PMUSB_CONTROLLER Controller;
  737. PMUSB_HARD_ENDPOINT HardEndpoint;
  738. ULONG Register;
  739. RUNLEVEL RunLevel;
  740. PMUSB_SOFT_ENDPOINT SoftEndpoint;
  741. USHORT Value;
  742. Controller = HostControllerContext;
  743. SoftEndpoint = EndpointContext;
  744. //
  745. // Only control endpoints are expected to change max packet sizes.
  746. //
  747. ASSERT((SoftEndpoint->HardwareIndex == 0) ||
  748. (MaxPacketSize == SoftEndpoint->MaxPayload));
  749. SoftEndpoint->MaxPayload = MaxPacketSize;
  750. //
  751. // This needs to acquire the lock in normal mode. In crash dump mode, skip
  752. // that.
  753. //
  754. RunLevel = KeGetRunLevel();
  755. if (RunLevel != RunLevelHigh) {
  756. MusbpAcquireLock(Controller);
  757. }
  758. //
  759. // Clear the data toggle bit.
  760. //
  761. if (SoftEndpoint->HardwareIndex == 0) {
  762. SoftEndpoint->Control &= ~MUSB_EP0_CONTROL_DATA_TOGGLE;
  763. } else if (SoftEndpoint->Direction == UsbTransferDirectionIn) {
  764. SoftEndpoint->Control &= ~MUSB_RX_CONTROL_DATA_TOGGLE;
  765. } else {
  766. ASSERT(SoftEndpoint->Direction == UsbTransferDirectionOut);
  767. SoftEndpoint->Control &= ~MUSB_TX_CONTROL_DATA_TOGGLE;
  768. }
  769. //
  770. // If this software endpoint is currently programmed in the hardware
  771. // channel, clear the data toggle in the hardware too.
  772. //
  773. HardEndpoint = &(Controller->Endpoints[SoftEndpoint->HardwareIndex]);
  774. if (HardEndpoint->CurrentEndpoint == SoftEndpoint) {
  775. if (SoftEndpoint->HardwareIndex == 0) {
  776. ASSERT(MaxPacketSize <= 64);
  777. Register = MUSB_ENDPOINT_CONTROL(MusbTxControlStatus, 0);
  778. Value = SoftEndpoint->Control | MUSB_EP0_CONTROL_DATA_TOGGLE_WRITE;
  779. MUSB_WRITE16(Controller, Register, Value);
  780. Value = SoftEndpoint->MaxPayload;
  781. Register = MUSB_ENDPOINT_CONTROL(MusbTxMaxPacketSize, 0);
  782. MUSB_WRITE16(Controller, Register, Value);
  783. } else if (SoftEndpoint->Direction == UsbTransferDirectionIn) {
  784. Register = MUSB_ENDPOINT_CONTROL(MusbRxControlStatus,
  785. SoftEndpoint->HardwareIndex);
  786. Value = SoftEndpoint->Control | MUSB_RX_CONTROL_CLEAR_TOGGLE;
  787. MUSB_WRITE16(Controller, Register, Value);
  788. } else {
  789. Register = MUSB_ENDPOINT_CONTROL(MusbTxControlStatus,
  790. SoftEndpoint->HardwareIndex);
  791. Value = SoftEndpoint->Control | MUSB_TX_CONTROL_CLEAR_TOGGLE;
  792. MUSB_WRITE16(Controller, Register, Value);
  793. }
  794. }
  795. if (RunLevel != RunLevelHigh) {
  796. MusbpReleaseLock(Controller);
  797. }
  798. return;
  799. }
  800. KSTATUS
  801. MusbpFlushEndpoint (
  802. PVOID HostControllerContext,
  803. PVOID EndpointContext,
  804. PULONG TransferCount
  805. )
  806. /*++
  807. Routine Description:
  808. This routine flushes all the active transfers from an endpoint. It does so
  809. by polling for completion status and does not return until all transfers
  810. are completed. This must be called at high run level.
  811. Arguments:
  812. HostControllerContext - Supplies the context pointer passed to the USB core
  813. when the controller was created. This is used to identify the USB host
  814. controller to the host controller driver.
  815. EndpointContext - Supplies a pointer to the context returned by the host
  816. controller when the endpoint was created.
  817. TransferCount - Supplies a pointer to a boolean that receives the number
  818. of transfers that were flushed.
  819. Return Value:
  820. Status code.
  821. --*/
  822. {
  823. PMUSB_CONTROLLER Controller;
  824. ULONG Count;
  825. USHORT EndpointInterrupts;
  826. PMUSB_HARD_ENDPOINT HardEndpoint;
  827. UCHAR HardwareIndex;
  828. PMUSB_SOFT_ENDPOINT SoftEndpoint;
  829. BOOL StartNextTransfer;
  830. KSTATUS Status;
  831. ULONGLONG Timeout;
  832. PMUSB_TRANSFER_SET TransferSet;
  833. Controller = HostControllerContext;
  834. SoftEndpoint = EndpointContext;
  835. Count = 0;
  836. HardwareIndex = SoftEndpoint->HardwareIndex;
  837. HardEndpoint = &(Controller->Endpoints[HardwareIndex]);
  838. ASSERT(KeGetRunLevel() == RunLevelHigh);
  839. Timeout = HlQueryTimeCounter() + (10 * HlQueryTimeCounterFrequency());
  840. while (!LIST_EMPTY(&(HardEndpoint->TransferList))) {
  841. //
  842. // Read the endpoint interrupt status, and wait for this endpoint to
  843. // arrive.
  844. //
  845. EndpointInterrupts = MUSB_READ16(Controller, MusbInterruptRx) |
  846. MUSB_READ16(Controller, MusbInterruptTx);
  847. if ((EndpointInterrupts & (1 << HardwareIndex)) == 0) {
  848. if (HlQueryTimeCounter() >= Timeout) {
  849. Status = STATUS_TIMEOUT;
  850. goto FlushEndpointEnd;
  851. }
  852. }
  853. //
  854. // Clear the endpoint interrupt.
  855. //
  856. MUSB_WRITE8(Controller, MusbInterruptRx, 1 << HardwareIndex);
  857. MUSB_WRITE8(Controller, MusbInterruptTx, 1 << HardwareIndex);
  858. //
  859. // Process a completed transfer.
  860. //
  861. TransferSet = MusbpProcessCompletedTransfer(Controller,
  862. HardwareIndex,
  863. &StartNextTransfer);
  864. if (TransferSet != NULL) {
  865. Count += 1;
  866. }
  867. //
  868. // Pump the next transfer through.
  869. //
  870. if (StartNextTransfer != FALSE) {
  871. MusbpExecuteNextTransfer(Controller, HardEndpoint);
  872. }
  873. }
  874. Status = STATUS_SUCCESS;
  875. FlushEndpointEnd:
  876. *TransferCount = Count;
  877. return Status;
  878. }
  879. VOID
  880. MusbpDestroyEndpoint (
  881. PVOID HostControllerContext,
  882. PVOID EndpointContext
  883. )
  884. /*++
  885. Routine Description:
  886. This routine tears down and destroys an endpoint created with the endpoint
  887. creation routine.
  888. Arguments:
  889. HostControllerContext - Supplies the context pointer passed to the USB core
  890. when the controller was created. This is used to identify the USB host
  891. controller to the host controller driver.
  892. EndpointContext - Supplies a pointer to the context returned by the host
  893. controller when the endpoint was created.
  894. Return Value:
  895. None.
  896. --*/
  897. {
  898. PMUSB_CONTROLLER Controller;
  899. PMUSB_HARD_ENDPOINT HardEndpoint;
  900. PMUSB_SOFT_ENDPOINT SoftEndpoint;
  901. SoftEndpoint = EndpointContext;
  902. Controller = HostControllerContext;
  903. HardEndpoint = &(Controller->Endpoints[SoftEndpoint->HardwareIndex]);
  904. if (HardEndpoint->CurrentEndpoint == SoftEndpoint) {
  905. MusbpAcquireLock(Controller);
  906. if (HardEndpoint->CurrentEndpoint == SoftEndpoint) {
  907. HardEndpoint->CurrentEndpoint = NULL;
  908. }
  909. MusbpReleaseLock(Controller);
  910. }
  911. MmFreeNonPagedPool(SoftEndpoint);
  912. return;
  913. }
  914. KSTATUS
  915. MusbpCreateTransfer (
  916. PVOID HostControllerContext,
  917. PVOID EndpointContext,
  918. ULONG MaxBufferSize,
  919. ULONG Flags,
  920. PVOID *TransferContext
  921. )
  922. /*++
  923. Routine Description:
  924. This routine allocates structures needed for the USB host controller to
  925. support a transfer.
  926. Arguments:
  927. HostControllerContext - Supplies the context pointer passed to the USB core
  928. when the controller was created. This is used to identify the USB host
  929. controller to the host controller driver.
  930. EndpointContext - Supplies a pointer to the host controller's context of
  931. the endpoint that this transfer will eventually be submitted to.
  932. MaxBufferSize - Supplies the maximum buffer length, in bytes, of the
  933. transfer when it is submitted. It is assumed that the host controller
  934. will set up as many transfer descriptors as are needed to support a
  935. transfer of this size.
  936. Flags - Supplies a bitfield of flags regarding the transaction. See
  937. USB_TRANSFER_FLAG_* definitions.
  938. TransferContext - Supplies a pointer where the host controller can store a
  939. context pointer containing any needed structures for the transfer.
  940. Return Value:
  941. None.
  942. --*/
  943. {
  944. UINTN AllocationSize;
  945. PMUSB_CONTROLLER Controller;
  946. BOOL ForceShortTransfer;
  947. ULONG Index;
  948. PMUSB_SOFT_ENDPOINT SoftEndpoint;
  949. KSTATUS Status;
  950. PMUSB_TRANSFER Transfer;
  951. ULONG TransferCount;
  952. PMUSB_TRANSFER_SET TransferSet;
  953. Controller = HostControllerContext;
  954. SoftEndpoint = EndpointContext;
  955. TransferCount = 0;
  956. ForceShortTransfer = FALSE;
  957. if ((Flags & USB_TRANSFER_FLAG_FORCE_SHORT_TRANSFER) != 0) {
  958. ForceShortTransfer = TRUE;
  959. }
  960. //
  961. // Control transfers need at least 2 transfers: the setup packet (which
  962. // burns the first 8 bytes), zero or more data transfers, and a status
  963. // transfer.
  964. //
  965. if (SoftEndpoint->HardwareIndex == 0) {
  966. ASSERT(MaxBufferSize >= sizeof(USB_SETUP_PACKET));
  967. MaxBufferSize -= sizeof(USB_SETUP_PACKET);
  968. TransferCount += 2;
  969. }
  970. if (MaxBufferSize != 0) {
  971. TransferCount += (MaxBufferSize + (SoftEndpoint->MaxPayload - 1)) /
  972. SoftEndpoint->MaxPayload;
  973. //
  974. // If it's possible for the transfer to send a multiple of the max
  975. // payload size and a short transfer needs to be forced, add an another
  976. // transfer.
  977. //
  978. if ((ForceShortTransfer != FALSE) &&
  979. (MaxBufferSize >= SoftEndpoint->MaxPayload)) {
  980. TransferCount += 1;
  981. }
  982. //
  983. // Account for a USB transfer that will only send zero length packets and
  984. // for control transfers that need to force a zero length packet in the
  985. // data phase.
  986. //
  987. } else if ((ForceShortTransfer != FALSE) ||
  988. (SoftEndpoint->HardwareIndex != 0)) {
  989. TransferCount += 1;
  990. }
  991. AllocationSize = sizeof(MUSB_TRANSFER_SET) +
  992. (TransferCount * sizeof(MUSB_TRANSFER));
  993. TransferSet = MmAllocateNonPagedPool(AllocationSize, MUSB_ALLOCATION_TAG);
  994. if (TransferSet == NULL) {
  995. Status = STATUS_INSUFFICIENT_RESOURCES;
  996. goto CreateTransferEnd;
  997. }
  998. RtlZeroMemory(TransferSet, AllocationSize);
  999. TransferSet->MaxCount = TransferCount;
  1000. TransferSet->Transfers = (PMUSB_TRANSFER)(TransferSet + 1);
  1001. if ((SoftEndpoint->HardwareIndex != 0) &&
  1002. (MusbDisableDma == FALSE) &&
  1003. (Controller->CppiDma != NULL)) {
  1004. Transfer = TransferSet->Transfers;
  1005. for (Index = 0; Index < TransferCount; Index += 1) {
  1006. Status = CppiCreateDescriptor(Controller->CppiDma,
  1007. Controller->Instance,
  1008. &(Transfer->DmaData));
  1009. if (!KSUCCESS(Status)) {
  1010. goto CreateTransferEnd;
  1011. }
  1012. Transfer += 1;
  1013. }
  1014. }
  1015. Status = STATUS_SUCCESS;
  1016. CreateTransferEnd:
  1017. if (!KSUCCESS(Status)) {
  1018. if (TransferSet != NULL) {
  1019. Transfer = TransferSet->Transfers;
  1020. for (Index = 0; Index < TransferCount; Index += 1) {
  1021. if (Transfer->DmaData.Descriptor != NULL) {
  1022. CppiDestroyDescriptor(Controller->CppiDma,
  1023. &(Transfer->DmaData));
  1024. }
  1025. Transfer += 1;
  1026. }
  1027. MmFreeNonPagedPool(TransferSet);
  1028. TransferSet = NULL;
  1029. }
  1030. }
  1031. *TransferContext = TransferSet;
  1032. return Status;
  1033. }
  1034. VOID
  1035. MusbpDestroyTransfer (
  1036. PVOID HostControllerContext,
  1037. PVOID EndpointContext,
  1038. PVOID TransferContext
  1039. )
  1040. /*++
  1041. Routine Description:
  1042. This routine destroys host controller structures associated with a USB
  1043. transfer.
  1044. Arguments:
  1045. HostControllerContext - Supplies the context pointer passed to the USB core
  1046. when the controller was created. This is used to identify the USB host
  1047. controller to the host controller driver.
  1048. EndpointContext - Supplies a pointer to the host controller context for the
  1049. endpoint this transfer belonged to.
  1050. TransferContext - Supplies the pointer provided to the USB core by the host
  1051. controller when the transfer was created.
  1052. Return Value:
  1053. None.
  1054. --*/
  1055. {
  1056. PMUSB_CONTROLLER Controller;
  1057. ULONG Index;
  1058. PMUSB_TRANSFER Transfer;
  1059. ULONG TransferCount;
  1060. PMUSB_TRANSFER_SET TransferSet;
  1061. Controller = HostControllerContext;
  1062. TransferSet = TransferContext;
  1063. TransferCount = TransferSet->MaxCount;
  1064. Transfer = TransferSet->Transfers;
  1065. for (Index = 0; Index < TransferCount; Index += 1) {
  1066. if (Transfer->DmaData.Descriptor != NULL) {
  1067. CppiDestroyDescriptor(Controller->CppiDma, &(Transfer->DmaData));
  1068. }
  1069. Transfer += 1;
  1070. }
  1071. MmFreeNonPagedPool(TransferSet);
  1072. return;
  1073. }
  1074. KSTATUS
  1075. MusbpSubmitTransfer (
  1076. PVOID HostControllerContext,
  1077. PVOID EndpointContext,
  1078. PUSB_TRANSFER_INTERNAL Transfer,
  1079. PVOID TransferContext
  1080. )
  1081. /*++
  1082. Routine Description:
  1083. This routine submits a transfer to the USB host controller for execution.
  1084. Arguments:
  1085. HostControllerContext - Supplies the context pointer passed to the USB core
  1086. when the controller was created. This is used to identify the USB host
  1087. controller to the host controller driver.
  1088. EndpointContext - Supplies the context pointer provided to the USB core by
  1089. the host controller when the endpoint was created.
  1090. Transfer - Supplies a pointer to the USB transfer to execute.
  1091. TransferContext - Supplies the pointer provided to the USB core by the host
  1092. controller when the transfer was created.
  1093. Return Value:
  1094. STATUS_SUCCESS if the transfer was successfully added to the hardware queue.
  1095. Failure codes if the transfer could not be added.
  1096. --*/
  1097. {
  1098. PMUSB_CONTROLLER Controller;
  1099. PMUSB_HARD_ENDPOINT HardEndpoint;
  1100. PMUSB_SOFT_ENDPOINT SoftEndpoint;
  1101. KSTATUS Status;
  1102. PMUSB_TRANSFER_SET TransferSet;
  1103. Controller = HostControllerContext;
  1104. SoftEndpoint = EndpointContext;
  1105. TransferSet = TransferContext;
  1106. MusbpAcquireLock(Controller);
  1107. if (Controller->Connected == FALSE) {
  1108. Status = STATUS_DEVICE_NOT_CONNECTED;
  1109. goto SubmitTransferEnd;
  1110. }
  1111. //
  1112. // Assign a hardware endpoint and fill out all the descriptors.
  1113. //
  1114. MusbpAssignEndpoint(Controller, SoftEndpoint);
  1115. Status = MusbpInitializeTransfer(Controller,
  1116. SoftEndpoint,
  1117. Transfer,
  1118. TransferSet);
  1119. if (!KSUCCESS(Status)) {
  1120. goto SubmitTransferEnd;
  1121. }
  1122. HardEndpoint = &(Controller->Endpoints[SoftEndpoint->HardwareIndex]);
  1123. if (Transfer->DeviceAddress != SoftEndpoint->Device) {
  1124. ASSERT((SoftEndpoint->Device == 0) && (Transfer->DeviceAddress != 0));
  1125. SoftEndpoint->Device = Transfer->DeviceAddress;
  1126. //
  1127. // The device ID changed so the endpoint will require reconfiguration.
  1128. //
  1129. HardEndpoint->CurrentEndpoint = NULL;
  1130. }
  1131. //
  1132. // If there are no transfers pending, kick this one off.
  1133. //
  1134. INSERT_BEFORE(&(TransferSet->ListEntry), &(HardEndpoint->TransferList));
  1135. SoftEndpoint->InFlight += 1;
  1136. if (HardEndpoint->TransferList.Next == &(TransferSet->ListEntry)) {
  1137. ASSERT(SoftEndpoint->InFlight == 1);
  1138. MusbpExecuteNextTransfer(Controller, HardEndpoint);
  1139. }
  1140. Status = STATUS_SUCCESS;
  1141. SubmitTransferEnd:
  1142. MusbpReleaseLock(Controller);
  1143. return Status;
  1144. }
  1145. KSTATUS
  1146. MusbpSubmitPolledTransfer (
  1147. PVOID HostControllerContext,
  1148. PVOID EndpointContext,
  1149. PUSB_TRANSFER_INTERNAL Transfer,
  1150. PVOID TransferContext
  1151. )
  1152. /*++
  1153. Routine Description:
  1154. This routine submits a transfer to the USB host controller for execution
  1155. and busy waits for it to complete. This routine is meant for crash dump
  1156. support to allow USB transfers when the system is fragile. As a result, it
  1157. forgoes acquiring the normal sequence of locks.
  1158. Arguments:
  1159. HostControllerContext - Supplies the context pointer passed to the USB core
  1160. when the controller was created. This is used to identify the USB host
  1161. controller to the host controller driver.
  1162. EndpointContext - Supplies the context pointer provided to the USB core by
  1163. the host controller when the endpoint was created.
  1164. Transfer - Supplies a pointer to the USB transfer to execute.
  1165. TransferContext - Supplies the pointer provided to the USB core by the host
  1166. controller when the transfer was created.
  1167. Return Value:
  1168. STATUS_SUCCESS if the transfer was successfully added to the hardware queue.
  1169. Failure codes if the transfer could not be added.
  1170. --*/
  1171. {
  1172. PMUSB_CONTROLLER Controller;
  1173. PMUSB_HARD_ENDPOINT HardEndpoint;
  1174. PMUSB_SOFT_ENDPOINT SoftEndpoint;
  1175. KSTATUS Status;
  1176. ULONG TransferCount;
  1177. PMUSB_TRANSFER_SET TransferSet;
  1178. Controller = HostControllerContext;
  1179. SoftEndpoint = EndpointContext;
  1180. HardEndpoint = &(Controller->Endpoints[SoftEndpoint->HardwareIndex]);
  1181. TransferSet = TransferContext;
  1182. //
  1183. // Clear the DMA flag on the endpoint.
  1184. //
  1185. if (SoftEndpoint->HardwareIndex != 0) {
  1186. if (SoftEndpoint->Direction == UsbTransferDirectionOut) {
  1187. SoftEndpoint->Control &= ~MUSB_TX_CONTROL_DMA_ENABLE;
  1188. } else {
  1189. SoftEndpoint->Control &= ~MUSB_RX_CONTROL_DMA_ENABLE;
  1190. }
  1191. }
  1192. MusbpAssignEndpoint(Controller, SoftEndpoint);
  1193. Status = MusbpInitializeTransfer(Controller,
  1194. SoftEndpoint,
  1195. Transfer,
  1196. TransferSet);
  1197. if (!KSUCCESS(Status)) {
  1198. goto SubmitPolledTransferEnd;
  1199. }
  1200. //
  1201. // Stick this transfer on the head of the list, and then work through it.
  1202. //
  1203. INSERT_AFTER(&(TransferSet->ListEntry), &(HardEndpoint->TransferList));
  1204. SoftEndpoint->InFlight += 1;
  1205. HardEndpoint->CurrentEndpoint = NULL;
  1206. MusbpExecuteNextTransfer(Controller, HardEndpoint);
  1207. Status = MusbpFlushEndpoint(Controller, SoftEndpoint, &TransferCount);
  1208. if (!KSUCCESS(Status)) {
  1209. goto SubmitPolledTransferEnd;
  1210. }
  1211. if (TransferCount != 1) {
  1212. Status = STATUS_DEVICE_IO_ERROR;
  1213. goto SubmitPolledTransferEnd;
  1214. }
  1215. SubmitPolledTransferEnd:
  1216. return Status;
  1217. }
  1218. KSTATUS
  1219. MusbpCancelTransfer (
  1220. PVOID HostControllerContext,
  1221. PVOID EndpointContext,
  1222. PUSB_TRANSFER_INTERNAL Transfer,
  1223. PVOID TransferContext
  1224. )
  1225. /*++
  1226. Routine Description:
  1227. This routine submits attempts to cancel a transfer that was previously
  1228. submitted for execution.
  1229. Arguments:
  1230. HostControllerContext - Supplies the context pointer passed to the USB core
  1231. when the controller was created. This is used to identify the USB host
  1232. controller to the host controller driver.
  1233. EndpointContext - Supplies the context pointer provided to the USB core by
  1234. the host controller when the endpoint was created.
  1235. Transfer - Supplies a pointer to the USB transfer to execute.
  1236. TransferContext - Supplies the pointer provided to the USB core by the host
  1237. controller when the transfer was created.
  1238. Return Value:
  1239. STATUS_SUCCESS if the transfer was successfully removed from the hardware
  1240. queue.
  1241. STATUS_TOO_LATE if the transfer had already completed.
  1242. Other failure codes if the transfer could not be cancelled but has not yet
  1243. completed.
  1244. --*/
  1245. {
  1246. PMUSB_CONTROLLER Controller;
  1247. PMUSB_HARD_ENDPOINT HardEndpoint;
  1248. UCHAR HardwareIndex;
  1249. PMUSB_TRANSFER MusbTransfer;
  1250. PMUSB_SOFT_ENDPOINT SoftEndpoint;
  1251. KSTATUS Status;
  1252. PMUSB_TRANSFER_SET TransferSet;
  1253. Controller = HostControllerContext;
  1254. SoftEndpoint = EndpointContext;
  1255. TransferSet = TransferContext;
  1256. MusbpAcquireLock(Controller);
  1257. HardwareIndex = SoftEndpoint->HardwareIndex;
  1258. HardEndpoint = &(Controller->Endpoints[HardwareIndex]);
  1259. if (TransferSet->ListEntry.Next == NULL) {
  1260. Status = STATUS_TOO_LATE;
  1261. goto CancelTransferEnd;
  1262. }
  1263. //
  1264. // If the transfer hasn't even started yet, then this is super easy.
  1265. //
  1266. ASSERT(TransferSet->ListEntry.Next != NULL);
  1267. if (HardEndpoint->TransferList.Next != &(TransferSet->ListEntry)) {
  1268. ASSERT(TransferSet->CurrentIndex == 0);
  1269. } else {
  1270. ASSERT(TransferSet->CurrentIndex < TransferSet->Count);
  1271. MusbTransfer = &(TransferSet->Transfers[TransferSet->CurrentIndex]);
  1272. MusbpAbortTransfer(Controller, HardwareIndex, MusbTransfer);
  1273. MusbpUpdateDataToggle(Controller, TransferSet);
  1274. }
  1275. LIST_REMOVE(&(TransferSet->ListEntry));
  1276. TransferSet->ListEntry.Next = NULL;
  1277. ASSERT(SoftEndpoint->InFlight != 0);
  1278. SoftEndpoint->InFlight -= 1;
  1279. //
  1280. // If the hardware endpoint has another transfer to do, kick that off now.
  1281. //
  1282. if (!LIST_EMPTY(&(HardEndpoint->TransferList))) {
  1283. MusbpExecuteNextTransfer(Controller, HardEndpoint);
  1284. }
  1285. Status = STATUS_SUCCESS;
  1286. CancelTransferEnd:
  1287. if (KSUCCESS(Status)) {
  1288. Transfer->Public.Status = STATUS_OPERATION_CANCELLED;
  1289. Transfer->Public.Error = UsbErrorTransferCancelled;
  1290. UsbHostProcessCompletedTransfer(TransferSet->UsbTransfer);
  1291. }
  1292. MusbpReleaseLock(Controller);
  1293. return Status;
  1294. }
  1295. KSTATUS
  1296. MusbpGetRootHubStatus (
  1297. PVOID HostControllerContext,
  1298. PUSB_HUB_STATUS HubStatus
  1299. )
  1300. /*++
  1301. Routine Description:
  1302. This routine queries the host controller for the status of the root hub.
  1303. Arguments:
  1304. HostControllerContext - Supplies the context pointer passed to the USB core
  1305. when the controller was created. This is used to identify the USB host
  1306. controller to the host controller driver.
  1307. HubStatus - Supplies a pointer where the host controller should fill out
  1308. the root hub status.
  1309. Return Value:
  1310. STATUS_SUCCESS if the hub status was successfully queried.
  1311. Failure codes if the status could not be queried.
  1312. --*/
  1313. {
  1314. PMUSB_CONTROLLER Controller;
  1315. PUSB_PORT_STATUS PortStatus;
  1316. USHORT SoftwareStatus;
  1317. USHORT Value;
  1318. Controller = HostControllerContext;
  1319. PortStatus = &(HubStatus->PortStatus[0]);
  1320. SoftwareStatus = 0;
  1321. Value = MUSB_READ8(Controller, MusbPower);
  1322. if ((Value & MUSB_POWER_HIGH_SPEED) != 0) {
  1323. SoftwareStatus = USB_PORT_STATUS_ENABLED | USB_PORT_STATUS_CONNECTED;
  1324. HubStatus->PortDeviceSpeed[0] = UsbDeviceSpeedHigh;
  1325. } else {
  1326. Value = MUSB_READ8(Controller, MusbDeviceControl);
  1327. if ((Value & MUSB_DEVICE_CONTROL_FULL_SPEED) != 0) {
  1328. SoftwareStatus = USB_PORT_STATUS_ENABLED |
  1329. USB_PORT_STATUS_CONNECTED;
  1330. HubStatus->PortDeviceSpeed[0] = UsbDeviceSpeedFull;
  1331. } else if ((Value & MUSB_DEVICE_CONTROL_LOW_SPEED) != 0) {
  1332. SoftwareStatus = USB_PORT_STATUS_ENABLED |
  1333. USB_PORT_STATUS_CONNECTED;
  1334. HubStatus->PortDeviceSpeed[0] = UsbDeviceSpeedLow;
  1335. }
  1336. }
  1337. PortStatus->Change |= SoftwareStatus ^ PortStatus->Status;
  1338. PortStatus->Status = SoftwareStatus;
  1339. return STATUS_SUCCESS;
  1340. }
  1341. KSTATUS
  1342. MusbpSetRootHubStatus (
  1343. PVOID HostControllerContext,
  1344. PUSB_HUB_STATUS HubStatus
  1345. )
  1346. /*++
  1347. Routine Description:
  1348. This routine sets the state of the root hub in the USB host controller. It
  1349. looks at the status change bits for each port in order to determine what
  1350. needs to be set.
  1351. Arguments:
  1352. HostControllerContext - Supplies the context pointer passed to the USB core
  1353. when the controller was created. This is used to identify the USB host
  1354. controller to the host controller driver.
  1355. HubStatus - Supplies a pointer to the status that should be set in the root
  1356. hub.
  1357. Return Value:
  1358. STATUS_SUCCESS if the hub state was successfully programmed into the device.
  1359. Failure codes if the status could not be set.
  1360. --*/
  1361. {
  1362. PMUSB_CONTROLLER Controller;
  1363. PUSB_PORT_STATUS PortStatus;
  1364. UCHAR Power;
  1365. Controller = HostControllerContext;
  1366. PortStatus = &(HubStatus->PortStatus[0]);
  1367. if ((PortStatus->Change & USB_PORT_STATUS_CHANGE_ENABLED) != 0) {
  1368. PortStatus->Change &= ~USB_PORT_STATUS_CHANGE_ENABLED;
  1369. }
  1370. if ((PortStatus->Change & USB_PORT_STATUS_CHANGE_RESET) != 0) {
  1371. if ((PortStatus->Status & USB_HUB_PORT_STATUS_RESET) != 0) {
  1372. Power = MUSB_READ8(Controller, MusbPower);
  1373. Power |= MUSB_POWER_RESET;
  1374. MUSB_WRITE8(Controller, MusbPower, Power);
  1375. HlBusySpin(20 * 1000);
  1376. Power &= ~MUSB_POWER_RESET;
  1377. MUSB_WRITE8(Controller, MusbPower, Power);
  1378. }
  1379. PortStatus->Change &= ~USB_PORT_STATUS_CHANGE_RESET;
  1380. }
  1381. return STATUS_SUCCESS;
  1382. }
  1383. VOID
  1384. MusbpProcessUsbInterrupts (
  1385. PMUSB_CONTROLLER Controller,
  1386. UCHAR UsbInterrupts
  1387. )
  1388. /*++
  1389. Routine Description:
  1390. This routine handles incoming general USB interrupts.
  1391. Arguments:
  1392. Controller - Supplies a pointer to the controller.
  1393. UsbInterrupts - Supplies the USB interrupts that occurred.
  1394. Return Value:
  1395. None.
  1396. --*/
  1397. {
  1398. UCHAR DeviceControl;
  1399. ASSERT(KeGetRunLevel() == RunLevelDispatch);
  1400. MusbpAcquireLock(Controller);
  1401. if ((UsbInterrupts & MUSB_USB_INTERRUPT_DISCONNECT) != 0) {
  1402. Controller->Connected = FALSE;
  1403. MusbpFailAllTransfers(Controller);
  1404. UsbHostNotifyPortChange(Controller->UsbCoreHandle);
  1405. }
  1406. if ((UsbInterrupts & MUSB_USB_INTERRUPT_CONNECT) != 0) {
  1407. Controller->Connected = TRUE;
  1408. UsbHostNotifyPortChange(Controller->UsbCoreHandle);
  1409. }
  1410. //
  1411. // If there was a VBUS error, just try to power the session back up.
  1412. //
  1413. if ((UsbInterrupts & MUSB_USB_INTERRUPT_VBUS_ERROR) != 0) {
  1414. DeviceControl = MUSB_READ8(Controller, MusbDeviceControl);
  1415. DeviceControl |= MUSB_DEVICE_CONTROL_SESSION;
  1416. MUSB_WRITE8(Controller, MusbDeviceControl, DeviceControl);
  1417. }
  1418. MusbpReleaseLock(Controller);
  1419. return;
  1420. }
  1421. VOID
  1422. MusbpProcessEndpointInterrupts (
  1423. PMUSB_CONTROLLER Controller,
  1424. ULONG EndpointInterrupts
  1425. )
  1426. /*++
  1427. Routine Description:
  1428. This routine handles incoming USB endpoint interrupts.
  1429. Arguments:
  1430. Controller - Supplies a pointer to the controller.
  1431. EndpointInterrupts - Supplies the endpoint interrupts that occurred.
  1432. Return Value:
  1433. None.
  1434. --*/
  1435. {
  1436. PMUSB_HARD_ENDPOINT HardEndpoint;
  1437. UCHAR HardwareIndex;
  1438. USHORT Interrupts;
  1439. BOOL StartNextTransfer;
  1440. PMUSB_TRANSFER_SET TransferSet;
  1441. //
  1442. // Combine the TX and RX interrupts into one.
  1443. //
  1444. Interrupts = (EndpointInterrupts >> 16) | EndpointInterrupts;
  1445. MusbpAcquireLock(Controller);
  1446. while (Interrupts != 0) {
  1447. HardwareIndex = RtlCountTrailingZeros32(Interrupts);
  1448. Interrupts &= ~(1 << HardwareIndex);
  1449. HardEndpoint = &(Controller->Endpoints[HardwareIndex]);
  1450. //
  1451. // Process a completed transfer. If this caused the entire set to
  1452. // complete, then send the transfer back to USB core.
  1453. //
  1454. if (!LIST_EMPTY(&(HardEndpoint->TransferList))) {
  1455. TransferSet = MusbpProcessCompletedTransfer(Controller,
  1456. HardwareIndex,
  1457. &StartNextTransfer);
  1458. if (TransferSet != NULL) {
  1459. UsbHostProcessCompletedTransfer(TransferSet->UsbTransfer);
  1460. }
  1461. //
  1462. // Kick off the next thing to do on this endpoint.
  1463. //
  1464. if (StartNextTransfer != FALSE) {
  1465. MusbpExecuteNextTransfer(Controller, HardEndpoint);
  1466. }
  1467. }
  1468. }
  1469. MusbpReleaseLock(Controller);
  1470. return;
  1471. }
  1472. KSTATUS
  1473. MusbpInitializeTransfer (
  1474. PMUSB_CONTROLLER Controller,
  1475. PMUSB_SOFT_ENDPOINT SoftEndpoint,
  1476. PUSB_TRANSFER_INTERNAL Transfer,
  1477. PMUSB_TRANSFER_SET TransferSet
  1478. )
  1479. /*++
  1480. Routine Description:
  1481. This routine initializes the necessary transfer structures in preparation
  1482. for executing a new USB transfer. The hardware endpoint must be assigned
  1483. prior to this routine.
  1484. Arguments:
  1485. Controller - Supplies a pointer to the controller.
  1486. SoftEndpoint - Supplies a pointer to the endpoint.
  1487. Transfer - Supplies a pointer to the USB transfer to execute.
  1488. TransferSet - Supplies a pointer to the MUSB transfer set.
  1489. Return Value:
  1490. Status code.
  1491. --*/
  1492. {
  1493. ULONG BufferOffset;
  1494. ULONG DmaEndpoint;
  1495. BOOL ForceShortTransfer;
  1496. PMUSB_TRANSFER MusbTransfer;
  1497. BOOL ShortTransfer;
  1498. ULONG TransferIndex;
  1499. ULONG TransferSize;
  1500. BOOL Transmit;
  1501. ASSERT(((Transfer->Type == UsbTransferTypeControl) &&
  1502. (SoftEndpoint->HardwareIndex == 0)) ||
  1503. ((Transfer->Type != UsbTransferTypeControl) &&
  1504. (SoftEndpoint->HardwareIndex != 0)));
  1505. ASSERT(Transfer->EndpointNumber == SoftEndpoint->EndpointNumber);
  1506. Transmit = TRUE;
  1507. Transfer->Public.Status = STATUS_SUCCESS;
  1508. Transfer->Public.Error = UsbErrorNone;
  1509. TransferSet->SoftEndpoint = SoftEndpoint;
  1510. TransferSet->CurrentIndex = 0;
  1511. DmaEndpoint = CPPI_USB_ENDPOINT_TO_DMA(SoftEndpoint->HardwareIndex);
  1512. ForceShortTransfer = FALSE;
  1513. if ((Transfer->Public.Flags &
  1514. USB_TRANSFER_FLAG_FORCE_SHORT_TRANSFER) != 0) {
  1515. ForceShortTransfer = TRUE;
  1516. }
  1517. //
  1518. // Go around and fill out the transfers. Make sure the data transfer end
  1519. // with a short transfer if required and that zero-length transfers are
  1520. // allowed.
  1521. //
  1522. ShortTransfer = FALSE;
  1523. TransferIndex = 0;
  1524. BufferOffset = 0;
  1525. MusbTransfer = &(TransferSet->Transfers[0]);
  1526. while ((BufferOffset < Transfer->Public.Length) ||
  1527. ((ShortTransfer == FALSE) &&
  1528. ((Transfer->Public.Length == 0) ||
  1529. (ForceShortTransfer != FALSE)))) {
  1530. //
  1531. // If this is a control transfer on the first packet, it's a setup
  1532. // packet.
  1533. //
  1534. if ((BufferOffset == 0) && (SoftEndpoint->HardwareIndex == 0)) {
  1535. ASSERT(Transfer->Public.Length >= sizeof(USB_SETUP_PACKET));
  1536. MusbTransfer->Flags = MUSB_TRANSFER_OUT | MUSB_TRANSFER_SETUP;
  1537. MusbTransfer->Size = sizeof(USB_SETUP_PACKET);
  1538. } else {
  1539. TransferSize = Transfer->Public.Length - BufferOffset;
  1540. if (TransferSize < SoftEndpoint->MaxPayload) {
  1541. ShortTransfer = TRUE;
  1542. } else {
  1543. TransferSize = SoftEndpoint->MaxPayload;
  1544. }
  1545. MusbTransfer->Size = TransferSize;
  1546. MusbTransfer->Flags = 0;
  1547. if (Transfer->Public.Direction == UsbTransferDirectionOut) {
  1548. MusbTransfer->Flags |= MUSB_TRANSFER_OUT;
  1549. Transmit = TRUE;
  1550. if ((SoftEndpoint->Control & MUSB_TX_CONTROL_DMA_ENABLE) != 0) {
  1551. MusbTransfer->Flags |= MUSB_TRANSFER_DMA;
  1552. }
  1553. } else {
  1554. Transmit = FALSE;
  1555. if ((SoftEndpoint->Control & MUSB_RX_CONTROL_DMA_ENABLE) != 0) {
  1556. MusbTransfer->Flags |= MUSB_TRANSFER_DMA;
  1557. }
  1558. }
  1559. }
  1560. if (MusbTransfer->Size != 0) {
  1561. MusbTransfer->BufferVirtual = Transfer->Public.Buffer +
  1562. BufferOffset;
  1563. MusbTransfer->BufferPhysical =
  1564. Transfer->Public.BufferPhysicalAddress +
  1565. BufferOffset;
  1566. } else {
  1567. MusbTransfer->BufferVirtual = NULL;
  1568. MusbTransfer->BufferPhysical = 0;
  1569. }
  1570. //
  1571. // Initialize the DMA descriptor if there is one.
  1572. //
  1573. if (MusbTransfer->DmaData.Descriptor != NULL) {
  1574. ASSERT(SoftEndpoint->HardwareIndex != 0);
  1575. CppiInitializeDescriptor(Controller->CppiDma,
  1576. &(MusbTransfer->DmaData),
  1577. DmaEndpoint,
  1578. Transmit,
  1579. MusbTransfer->BufferPhysical,
  1580. MusbTransfer->Size);
  1581. }
  1582. BufferOffset += MusbTransfer->Size;
  1583. MusbTransfer += 1;
  1584. TransferIndex += 1;
  1585. }
  1586. //
  1587. // Add the status phase if needed. The status phase always has the opposite
  1588. // direction of the data phase.
  1589. //
  1590. if (SoftEndpoint->HardwareIndex == 0) {
  1591. MusbTransfer->Flags = MUSB_TRANSFER_STATUS;
  1592. if (Transfer->Public.Direction == UsbTransferDirectionIn) {
  1593. MusbTransfer->Flags |= MUSB_TRANSFER_OUT;
  1594. }
  1595. MusbTransfer->Size = 0;
  1596. MusbTransfer->BufferVirtual = NULL;
  1597. MusbTransfer->BufferPhysical = 0;
  1598. TransferIndex += 1;
  1599. }
  1600. ASSERT(TransferIndex <= TransferSet->MaxCount);
  1601. TransferSet->Count = TransferIndex;
  1602. TransferSet->UsbTransfer = Transfer;
  1603. return STATUS_SUCCESS;
  1604. }
  1605. VOID
  1606. MusbpExecuteNextTransfer (
  1607. PMUSB_CONTROLLER Controller,
  1608. PMUSB_HARD_ENDPOINT HardEndpoint
  1609. )
  1610. /*++
  1611. Routine Description:
  1612. This routine begins the next transfer on the given endpoint. This routine
  1613. assumes the controller lock is already held.
  1614. Arguments:
  1615. Controller - Supplies a pointer to the controller.
  1616. HardEndpoint - Supplies a pointer to the endpoint to execute a transfer on.
  1617. Return Value:
  1618. None.
  1619. --*/
  1620. {
  1621. USHORT Control;
  1622. UCHAR HardwareIndex;
  1623. ULONG Register;
  1624. PMUSB_SOFT_ENDPOINT SoftEndpoint;
  1625. PMUSB_TRANSFER Transfer;
  1626. PMUSB_TRANSFER_SET TransferSet;
  1627. if (LIST_EMPTY(&(HardEndpoint->TransferList))) {
  1628. return;
  1629. }
  1630. TransferSet = LIST_VALUE(HardEndpoint->TransferList.Next,
  1631. MUSB_TRANSFER_SET,
  1632. ListEntry);
  1633. SoftEndpoint = TransferSet->SoftEndpoint;
  1634. HardwareIndex = SoftEndpoint->HardwareIndex;
  1635. MusbpConfigureHardwareEndpoint(Controller, SoftEndpoint);
  1636. Transfer = &(TransferSet->Transfers[TransferSet->CurrentIndex]);
  1637. //
  1638. // In DMA mode, enqueue the packet into the DMA controller. This actually
  1639. // kicks off the DMA.
  1640. //
  1641. if ((Transfer->Flags & MUSB_TRANSFER_DMA) != 0) {
  1642. ASSERT(Transfer->DmaData.Descriptor != NULL);
  1643. CppiSubmitDescriptor(Controller->CppiDma, &(Transfer->DmaData));
  1644. } else {
  1645. //
  1646. // If this is an out transfer, fill the FIFO with the data.
  1647. //
  1648. if ((Transfer->Flags & MUSB_TRANSFER_OUT) != 0) {
  1649. MusbpWriteFifo(Controller,
  1650. HardwareIndex,
  1651. Transfer->BufferVirtual,
  1652. Transfer->Size);
  1653. }
  1654. }
  1655. //
  1656. // Enable interrupts.
  1657. //
  1658. if ((Transfer->Flags & MUSB_TRANSFER_OUT) != 0) {
  1659. Controller->TxInterruptEnable |= 1 << HardwareIndex;
  1660. MUSB_WRITE16(Controller,
  1661. MusbInterruptEnableTx,
  1662. Controller->TxInterruptEnable);
  1663. } else {
  1664. Controller->RxInterruptEnable |= 1 << HardwareIndex;
  1665. MUSB_WRITE16(Controller,
  1666. MusbInterruptEnableRx,
  1667. Controller->RxInterruptEnable);
  1668. }
  1669. //
  1670. // For outbound DMA transfers, there's no need to write the TX ready bit,
  1671. // so just return.
  1672. //
  1673. if ((Transfer->Flags & (MUSB_TRANSFER_OUT | MUSB_TRANSFER_DMA)) ==
  1674. (MUSB_TRANSFER_OUT | MUSB_TRANSFER_DMA)) {
  1675. return;
  1676. }
  1677. //
  1678. // Kick off the transfer by writing to the control register.
  1679. //
  1680. Control = SoftEndpoint->Control;
  1681. if (HardwareIndex == 0) {
  1682. if ((Transfer->Flags & MUSB_TRANSFER_OUT) != 0) {
  1683. Control |= MUSB_EP0_CONTROL_TX_PACKET_READY;
  1684. } else {
  1685. Control |= MUSB_EP0_CONTROL_REQUEST_PACKET;
  1686. }
  1687. if ((Transfer->Flags & MUSB_TRANSFER_SETUP) != 0) {
  1688. Control |= MUSB_EP0_CONTROL_SETUP_PACKET;
  1689. } else if ((Transfer->Flags & MUSB_TRANSFER_STATUS) != 0) {
  1690. Control |= MUSB_EP0_CONTROL_STATUS_PACKET;
  1691. }
  1692. Register = MUSB_ENDPOINT_CONTROL(MusbTxControlStatus, 0);
  1693. } else if ((Transfer->Flags & MUSB_TRANSFER_OUT) != 0) {
  1694. Control |= MUSB_TX_CONTROL_PACKET_READY;
  1695. Register = MUSB_ENDPOINT_CONTROL(MusbTxControlStatus, HardwareIndex);
  1696. } else {
  1697. Control |= MUSB_RX_CONTROL_REQUEST_PACKET;
  1698. Register = MUSB_ENDPOINT_CONTROL(MusbRxControlStatus, HardwareIndex);
  1699. }
  1700. //
  1701. // Only write the low byte of control.
  1702. //
  1703. MUSB_WRITE8(Controller, Register, Control);
  1704. return;
  1705. }
  1706. PMUSB_TRANSFER_SET
  1707. MusbpProcessCompletedTransfer (
  1708. PMUSB_CONTROLLER Controller,
  1709. UCHAR HardwareIndex,
  1710. PBOOL TransferCompleted
  1711. )
  1712. /*++
  1713. Routine Description:
  1714. This routine processes a completed USB transfer on a hardware endpoint.
  1715. This routine assumes the controller lock is already held.
  1716. Arguments:
  1717. Controller - Supplies a pointer to the controller.
  1718. HardwareIndex - Supplies the hardware endpoint index of the transfer that
  1719. completed.
  1720. TransferCompleted - Supplies a pointer where a boolean will be returned
  1721. indicating if this transfer actually completed (TRUE) and the next
  1722. transfer should be executed, or if this transfer is still going (FALSE).
  1723. Return Value:
  1724. Returns a pointer to the transfer set that just completed and was removed.
  1725. NULL if the current transfer is still in progress.
  1726. --*/
  1727. {
  1728. BOOL CompleteSet;
  1729. USHORT Control;
  1730. ULONG ControlRegister;
  1731. PMUSB_HARD_ENDPOINT HardEndpoint;
  1732. ULONG Register;
  1733. ULONG RxCount;
  1734. PMUSB_SOFT_ENDPOINT SoftEndpoint;
  1735. PMUSB_TRANSFER Transfer;
  1736. PMUSB_TRANSFER_SET TransferSet;
  1737. PUSB_TRANSFER UsbTransfer;
  1738. *TransferCompleted = FALSE;
  1739. CompleteSet = FALSE;
  1740. HardEndpoint = &(Controller->Endpoints[HardwareIndex]);
  1741. ASSERT(!LIST_EMPTY(&(HardEndpoint->TransferList)));
  1742. TransferSet = LIST_VALUE(HardEndpoint->TransferList.Next,
  1743. MUSB_TRANSFER_SET,
  1744. ListEntry);
  1745. ASSERT(TransferSet->CurrentIndex < TransferSet->Count);
  1746. SoftEndpoint = TransferSet->SoftEndpoint;
  1747. Transfer = &(TransferSet->Transfers[TransferSet->CurrentIndex]);
  1748. UsbTransfer = &(TransferSet->UsbTransfer->Public);
  1749. //
  1750. // Handle a completed control transfer if this is endpoint zero.
  1751. //
  1752. if (HardwareIndex == 0) {
  1753. ControlRegister = MUSB_ENDPOINT_CONTROL(MusbTxControlStatus,
  1754. HardwareIndex);
  1755. Control = MUSB_READ16(Controller, ControlRegister);
  1756. //
  1757. // If the transfer's not actually finished, the interrupt was spurious
  1758. // or stale.
  1759. //
  1760. if ((Transfer->Flags & MUSB_TRANSFER_OUT) != 0) {
  1761. if ((Control & MUSB_EP0_CONTROL_TX_PACKET_READY) != 0) {
  1762. return NULL;
  1763. }
  1764. } else {
  1765. if ((Control &
  1766. (MUSB_EP0_CONTROL_RX_PACKET_READY |
  1767. MUSB_EP0_CONTROL_ERROR_MASK)) == 0) {
  1768. return NULL;
  1769. }
  1770. }
  1771. //
  1772. // For IN transfers, read the data from the FIFO.
  1773. //
  1774. if (((Transfer->Flags & MUSB_TRANSFER_OUT) == 0) &&
  1775. ((Control & MUSB_EP0_CONTROL_RX_PACKET_READY) != 0)) {
  1776. Register = MUSB_ENDPOINT_CONTROL(MusbCount, HardwareIndex);
  1777. RxCount = MUSB_READ16(Controller, Register);
  1778. ASSERT(RxCount <= Transfer->Size);
  1779. if (RxCount >= Transfer->Size) {
  1780. RxCount = Transfer->Size;
  1781. }
  1782. UsbTransfer->LengthTransferred += RxCount;
  1783. MusbpReadFifo(Controller,
  1784. HardwareIndex,
  1785. Transfer->BufferVirtual,
  1786. RxCount);
  1787. //
  1788. // Handle a shorted transfer.
  1789. //
  1790. if (RxCount < Transfer->Size) {
  1791. if ((UsbTransfer->Flags &
  1792. USB_TRANSFER_FLAG_NO_SHORT_TRANSFERS) != 0) {
  1793. if (KSUCCESS(UsbTransfer->Status)) {
  1794. UsbTransfer->Status = STATUS_DATA_LENGTH_MISMATCH;
  1795. UsbTransfer->Error = UsbErrorShortPacket;
  1796. }
  1797. }
  1798. //
  1799. // Move to the status phase (or one before to account for the
  1800. // increment at the end of the function).
  1801. //
  1802. ASSERT(TransferSet->CurrentIndex < TransferSet->Count - 1);
  1803. TransferSet->CurrentIndex = TransferSet->Count - 2;
  1804. }
  1805. }
  1806. //
  1807. // Fail the transfer if there was an error.
  1808. //
  1809. if ((Control & MUSB_EP0_CONTROL_ERROR_MASK) != 0) {
  1810. CompleteSet = TRUE;
  1811. UsbTransfer->Status = STATUS_DEVICE_IO_ERROR;
  1812. //
  1813. // Write those error bits to clear them, and perform any FIFO
  1814. // cleanup needed.
  1815. //
  1816. MUSB_WRITE16(Controller, ControlRegister, Control);
  1817. MusbpAbortTransfer(Controller, HardwareIndex, Transfer);
  1818. if ((Control & MUSB_EP0_CONTROL_ERROR) != 0) {
  1819. UsbTransfer->Error = UsbErrorTransferCrcOrTimeoutError;
  1820. } else if ((Control & MUSB_EP0_CONTROL_RX_STALL) != 0) {
  1821. UsbTransfer->Error = UsbErrorTransferStalled;
  1822. } else if ((Control & MUSB_EP0_CONTROL_NAK_TIMEOUT) != 0) {
  1823. UsbTransfer->Error = UsbErrorTransferNakReceived;
  1824. } else {
  1825. ASSERT(FALSE);
  1826. }
  1827. } else {
  1828. if ((Transfer->Flags & MUSB_TRANSFER_OUT) != 0) {
  1829. UsbTransfer->LengthTransferred += Transfer->Size;
  1830. }
  1831. }
  1832. //
  1833. // The data toggle bit in the soft endpoint does not need updating
  1834. // because it will never migrate to another hardware endpoint, and
  1835. // a control transfer is never broken up by other requests.
  1836. //
  1837. //
  1838. // Handle a completed OUT transfer.
  1839. //
  1840. } else if ((Transfer->Flags & MUSB_TRANSFER_OUT) != 0) {
  1841. ControlRegister = MUSB_ENDPOINT_CONTROL(MusbTxControlStatus,
  1842. HardwareIndex);
  1843. Control = MUSB_READ16(Controller, ControlRegister);
  1844. //
  1845. // In DMA mode, the packet ready and FIFO full bits might still be set
  1846. // (even though the DMA transfer supposedly completed). The original
  1847. // code spun here waiting for those bits to clear, but that turned out
  1848. // to be a very significant portion of time. Instead it seems to be
  1849. // okay to clear the control register, and then spin on seeing the
  1850. // descriptor show up in the CPPI completion queue.
  1851. //
  1852. //
  1853. // In non-DMA mode, there's a FIFO empty interrupt, so if the FIFO is
  1854. // not currently empty just wait for that.
  1855. //
  1856. if ((Transfer->Flags & MUSB_TRANSFER_DMA) == 0) {
  1857. if ((Control & MUSB_TX_CONTROL_PACKET_READY) != 0) {
  1858. return NULL;
  1859. }
  1860. }
  1861. if ((Control & MUSB_TX_CONTROL_ERROR_MASK) != 0) {
  1862. CompleteSet = TRUE;
  1863. UsbTransfer->Status = STATUS_DEVICE_IO_ERROR;
  1864. //
  1865. // Write those error bits to clear them, and perform any FIFO
  1866. // cleanup needed.
  1867. //
  1868. MUSB_WRITE16(Controller, ControlRegister, Control);
  1869. MusbpAbortTransfer(Controller, HardwareIndex, Transfer);
  1870. if ((Control & MUSB_TX_CONTROL_ERROR) != 0) {
  1871. UsbTransfer->Error = UsbErrorTransferCrcOrTimeoutError;
  1872. } else if ((Control & MUSB_TX_CONTROL_RX_STALL) != 0) {
  1873. UsbTransfer->Error = UsbErrorTransferStalled;
  1874. } else if ((Control & MUSB_TX_CONTROL_NAK_TIMEOUT) != 0) {
  1875. UsbTransfer->Error = UsbErrorTransferNakReceived;
  1876. } else {
  1877. ASSERT(FALSE);
  1878. }
  1879. } else {
  1880. UsbTransfer->LengthTransferred += Transfer->Size;
  1881. if ((Transfer->Flags & MUSB_TRANSFER_DMA) != 0) {
  1882. CppiReapCompletedDescriptor(Controller->CppiDma,
  1883. &(Transfer->DmaData),
  1884. NULL);
  1885. }
  1886. }
  1887. //
  1888. // Update the data toggle bit.
  1889. //
  1890. SoftEndpoint->Control = (SoftEndpoint->Control &
  1891. ~MUSB_TX_CONTROL_DATA_TOGGLE) |
  1892. (Control & MUSB_TX_CONTROL_DATA_TOGGLE);
  1893. //
  1894. // Handle a completed IN transfer.
  1895. //
  1896. } else {
  1897. ControlRegister = MUSB_ENDPOINT_CONTROL(MusbRxControlStatus,
  1898. HardwareIndex);
  1899. Control = MUSB_READ16(Controller, ControlRegister);
  1900. //
  1901. // Incoming NAK timeouts aren't actually errors (except on isochronous
  1902. // channels.
  1903. //
  1904. if ((Control & MUSB_RX_CONTROL_DATA_ERROR_NAK_TIMEOUT) != 0) {
  1905. if ((TransferSet->UsbTransfer->Type !=
  1906. UsbTransferTypeIsochronous) &&
  1907. (SoftEndpoint->Interval == 0)) {
  1908. Control &= ~MUSB_RX_CONTROL_DATA_ERROR_NAK_TIMEOUT;
  1909. MUSB_WRITE16(Controller, ControlRegister, Control);
  1910. return NULL;
  1911. }
  1912. }
  1913. //
  1914. // Handle errors first.
  1915. //
  1916. if ((Control & MUSB_RX_CONTROL_ERROR_MASK) != 0) {
  1917. CompleteSet = TRUE;
  1918. UsbTransfer->Status = STATUS_DEVICE_IO_ERROR;
  1919. //
  1920. // Write those error bits to clear them, and perform any FIFO
  1921. // cleanup needed.
  1922. //
  1923. MUSB_WRITE16(Controller, ControlRegister, Control);
  1924. MusbpAbortTransfer(Controller, HardwareIndex, Transfer);
  1925. if ((Control & MUSB_RX_CONTROL_ERROR) != 0) {
  1926. UsbTransfer->Error = UsbErrorTransferCrcOrTimeoutError;
  1927. } else if ((Control & MUSB_RX_CONTROL_RX_STALL) != 0) {
  1928. UsbTransfer->Error = UsbErrorTransferStalled;
  1929. } else if ((Control &
  1930. MUSB_RX_CONTROL_DATA_ERROR_NAK_TIMEOUT) != 0) {
  1931. if (TransferSet->UsbTransfer->Type ==
  1932. UsbTransferTypeIsochronous) {
  1933. UsbTransfer->Error = UsbErrorTransferCrcOrTimeoutError;
  1934. } else {
  1935. UsbTransfer->Error = UsbErrorTransferNakReceived;
  1936. }
  1937. } else {
  1938. ASSERT(FALSE);
  1939. }
  1940. //
  1941. // There are no errors. If the request packet flag is clear and either
  1942. // this is DMA or the packet ready flag is set, go get the data.
  1943. //
  1944. } else if (((Control & MUSB_RX_CONTROL_REQUEST_PACKET) == 0) &&
  1945. (((Transfer->Flags & MUSB_TRANSFER_DMA) != 0) ||
  1946. ((Control & MUSB_RX_CONTROL_PACKET_READY) != 0))) {
  1947. Register = MUSB_ENDPOINT_CONTROL(MusbCount, HardwareIndex);
  1948. if ((Transfer->Flags & MUSB_TRANSFER_DMA) != 0) {
  1949. CppiReapCompletedDescriptor(Controller->CppiDma,
  1950. &(Transfer->DmaData),
  1951. &RxCount);
  1952. ASSERT(RxCount <= Transfer->Size);
  1953. } else {
  1954. RxCount = MUSB_READ16(Controller, Register);
  1955. //
  1956. // If the RX count is more than the transfer size, then it means
  1957. // the RX max packet size was programmed incorrectly.
  1958. //
  1959. ASSERT(RxCount <= Transfer->Size);
  1960. if (RxCount >= Transfer->Size) {
  1961. RxCount = Transfer->Size;
  1962. }
  1963. MusbpReadFifo(Controller,
  1964. HardwareIndex,
  1965. Transfer->BufferVirtual,
  1966. RxCount);
  1967. }
  1968. UsbTransfer->LengthTransferred += RxCount;
  1969. //
  1970. // Account for a shorted transfer.
  1971. //
  1972. if (RxCount < Transfer->Size) {
  1973. CompleteSet = TRUE;
  1974. if ((UsbTransfer->Flags &
  1975. USB_TRANSFER_FLAG_NO_SHORT_TRANSFERS) != 0) {
  1976. UsbTransfer->Status = STATUS_DATA_LENGTH_MISMATCH;
  1977. UsbTransfer->Error = UsbErrorShortPacket;
  1978. }
  1979. }
  1980. }
  1981. //
  1982. // Update the data toggle bit.
  1983. //
  1984. SoftEndpoint->Control = (SoftEndpoint->Control &
  1985. ~MUSB_RX_CONTROL_DATA_TOGGLE) |
  1986. (Control & MUSB_RX_CONTROL_DATA_TOGGLE);
  1987. }
  1988. MUSB_WRITE16(Controller, ControlRegister, 0);
  1989. *TransferCompleted = TRUE;
  1990. TransferSet->CurrentIndex += 1;
  1991. if (TransferSet->CurrentIndex == TransferSet->Count) {
  1992. CompleteSet = TRUE;
  1993. }
  1994. if (CompleteSet != FALSE) {
  1995. LIST_REMOVE(&(TransferSet->ListEntry));
  1996. TransferSet->ListEntry.Next = NULL;
  1997. ASSERT(SoftEndpoint->InFlight != 0);
  1998. SoftEndpoint->InFlight -= 1;
  1999. } else {
  2000. TransferSet = NULL;
  2001. }
  2002. return TransferSet;
  2003. }
  2004. VOID
  2005. MusbpFailAllTransfers (
  2006. PMUSB_CONTROLLER Controller
  2007. )
  2008. /*++
  2009. Routine Description:
  2010. This routine completes all pending USB transfers, failing everything with
  2011. a device not connected error. This routine assumes the controller lock is
  2012. already held.
  2013. Arguments:
  2014. Controller - Supplies a pointer to the controller.
  2015. Return Value:
  2016. None.
  2017. --*/
  2018. {
  2019. PMUSB_HARD_ENDPOINT HardEndpoint;
  2020. ULONG HardwareIndex;
  2021. PMUSB_SOFT_ENDPOINT SoftEndpoint;
  2022. PMUSB_TRANSFER Transfer;
  2023. PMUSB_TRANSFER_SET TransferSet;
  2024. PUSB_TRANSFER_INTERNAL UsbTransfer;
  2025. for (HardwareIndex = 0;
  2026. HardwareIndex < Controller->EndpointCount;
  2027. HardwareIndex += 1) {
  2028. HardEndpoint = &(Controller->Endpoints[HardwareIndex]);
  2029. if (LIST_EMPTY(&(HardEndpoint->TransferList))) {
  2030. continue;
  2031. }
  2032. //
  2033. // Kill the first transfer, which is the tricky one since it's in the
  2034. // hardware.
  2035. //
  2036. TransferSet = LIST_VALUE(HardEndpoint->TransferList.Next,
  2037. MUSB_TRANSFER_SET,
  2038. ListEntry);
  2039. SoftEndpoint = TransferSet->SoftEndpoint;
  2040. Transfer = &(TransferSet->Transfers[TransferSet->CurrentIndex]);
  2041. MusbpAbortTransfer(Controller, HardwareIndex, Transfer);
  2042. MusbpUpdateDataToggle(Controller, TransferSet);
  2043. UsbTransfer = TransferSet->UsbTransfer;
  2044. UsbTransfer->Public.Status = STATUS_DEVICE_IO_ERROR;
  2045. UsbTransfer->Public.Error = UsbErrorTransferDeviceNotConnected;
  2046. LIST_REMOVE(&(TransferSet->ListEntry));
  2047. TransferSet->ListEntry.Next = NULL;
  2048. ASSERT(SoftEndpoint->InFlight != 0);
  2049. SoftEndpoint->InFlight -= 1;
  2050. UsbHostProcessCompletedTransfer(UsbTransfer);
  2051. //
  2052. // Now process all the other transfers, which were never even started.
  2053. //
  2054. while (!LIST_EMPTY(&(HardEndpoint->TransferList))) {
  2055. TransferSet = LIST_VALUE(HardEndpoint->TransferList.Next,
  2056. MUSB_TRANSFER_SET,
  2057. ListEntry);
  2058. UsbTransfer = TransferSet->UsbTransfer;
  2059. UsbTransfer->Public.Status = STATUS_DEVICE_IO_ERROR;
  2060. UsbTransfer->Public.Error = UsbErrorTransferDeviceNotConnected;
  2061. LIST_REMOVE(&(TransferSet->ListEntry));
  2062. TransferSet->ListEntry.Next = NULL;
  2063. ASSERT(SoftEndpoint->InFlight != 0);
  2064. SoftEndpoint->InFlight -= 1;
  2065. UsbHostProcessCompletedTransfer(UsbTransfer);
  2066. }
  2067. }
  2068. return;
  2069. }
  2070. VOID
  2071. MusbpConfigureFifo (
  2072. PMUSB_CONTROLLER Controller,
  2073. PMUSB_FIFO_CONFIGURATION Configuration,
  2074. PULONG Offset
  2075. )
  2076. /*++
  2077. Routine Description:
  2078. This routine configures a hardware endpoint FIFO.
  2079. Arguments:
  2080. Controller - Supplies a pointer to the controller.
  2081. Configuration - Supplies the configuration to set.
  2082. Offset - Supplies the current FIFO region offset. On output, this will be
  2083. advanced.
  2084. Return Value:
  2085. None.
  2086. --*/
  2087. {
  2088. ULONG CurrentOffset;
  2089. UCHAR Endpoint;
  2090. UCHAR SizeValue;
  2091. ASSERT(Configuration->Endpoint != 0);
  2092. CurrentOffset = *Offset;
  2093. Endpoint = Configuration->Endpoint;
  2094. *Offset += Configuration->MaxPacketSize;
  2095. //
  2096. // The size register is logarithmic, with the max packet size being
  2097. // 2^(sz+3) for single buffer mode, and 2^(sz+4) for double buffer
  2098. // mode.
  2099. //
  2100. SizeValue = RtlCountTrailingZeros32(Configuration->MaxPacketSize) - 3;
  2101. if ((Configuration->Direction == MusbEndpointTx) ||
  2102. (Configuration->Direction == MusbEndpointTxRx)) {
  2103. ASSERT(Controller->Endpoints[Endpoint].TxFifoSize == 0);
  2104. Controller->Endpoints[Endpoint].TxFifoSize =
  2105. Configuration->MaxPacketSize;
  2106. MusbpWriteIndexed8(Controller, Endpoint, MusbTxFifoSize, SizeValue);
  2107. //
  2108. // The FIFO address register is in units of 8 bytes.
  2109. //
  2110. MusbpWriteIndexed16(Controller,
  2111. Endpoint,
  2112. MusbTxFifoAddress,
  2113. CurrentOffset >> 3);
  2114. }
  2115. if ((Configuration->Direction == MusbEndpointRx) ||
  2116. (Configuration->Direction == MusbEndpointTxRx)) {
  2117. ASSERT(Controller->Endpoints[Endpoint].RxFifoSize == 0);
  2118. Controller->Endpoints[Endpoint].RxFifoSize =
  2119. Configuration->MaxPacketSize;
  2120. MusbpWriteIndexed8(Controller, Endpoint, MusbRxFifoSize, SizeValue);
  2121. MusbpWriteIndexed16(Controller,
  2122. Endpoint,
  2123. MusbRxFifoAddress,
  2124. CurrentOffset >> 3);
  2125. }
  2126. return;
  2127. }
  2128. VOID
  2129. MusbpAbortTransfer (
  2130. PMUSB_CONTROLLER Controller,
  2131. UCHAR HardwareIndex,
  2132. PMUSB_TRANSFER Transfer
  2133. )
  2134. /*++
  2135. Routine Description:
  2136. This routine aborts a transmit operation by flushing FIFOs and DMA.
  2137. Arguments:
  2138. Controller - Supplies a pointer to the controller.
  2139. HardwareIndex - Supplies the hardware endpoint index to abort.
  2140. Transfer - Supplies the transfer that's stuck in there.
  2141. Return Value:
  2142. None.
  2143. --*/
  2144. {
  2145. USHORT Control;
  2146. ULONG ControlRegister;
  2147. KSTATUS Status;
  2148. if ((Transfer->Flags & MUSB_TRANSFER_OUT) != 0) {
  2149. //
  2150. // Flush twice as required for double buffering.
  2151. //
  2152. MusbpFlushFifo(Controller, HardwareIndex, TRUE);
  2153. MusbpFlushFifo(Controller, HardwareIndex, TRUE);
  2154. if ((Transfer->Flags & MUSB_TRANSFER_DMA) != 0) {
  2155. ControlRegister = MUSB_ENDPOINT_CONTROL(MusbTxControlStatus,
  2156. HardwareIndex);
  2157. Control = MUSB_READ16(Controller, ControlRegister);
  2158. Control &= ~MUSB_TX_CONTROL_DMA_ENABLE;
  2159. MUSB_WRITE16(Controller, ControlRegister, Control);
  2160. ASSERT(Transfer->DmaData.Descriptor != NULL);
  2161. Status = CppiTearDownDescriptor(Controller->CppiDma,
  2162. &(Transfer->DmaData));
  2163. ASSERT(KSUCCESS(Status));
  2164. }
  2165. } else {
  2166. if (HardwareIndex == 0) {
  2167. ControlRegister = MUSB_ENDPOINT_CONTROL(MusbTxControlStatus, 0);
  2168. } else {
  2169. ControlRegister = MUSB_ENDPOINT_CONTROL(MusbRxControlStatus,
  2170. HardwareIndex);
  2171. }
  2172. //
  2173. // Clear the auto request flag from the high byte of the control
  2174. // register.
  2175. //
  2176. Control = MUSB_READ8(Controller, ControlRegister + 1);
  2177. Control &= ~(MUSB_RX_CONTROL_AUTO_REQUEST >> BITS_PER_BYTE);
  2178. MUSB_WRITE8(Controller, ControlRegister + 1, Control);
  2179. if ((Transfer->Flags & MUSB_TRANSFER_DMA) != 0) {
  2180. //
  2181. // Clear the request packet and DMA enable flags. If a packet
  2182. // squeaked in, flush the FIFO. Then tear down the DMA descriptor.
  2183. //
  2184. Control = MUSB_READ16(Controller, ControlRegister);
  2185. Control &= ~(MUSB_RX_CONTROL_REQUEST_PACKET |
  2186. MUSB_RX_CONTROL_DMA_ENABLE);
  2187. MUSB_WRITE16(Controller, ControlRegister, Control);
  2188. HlBusySpin(250);
  2189. Control = MUSB_READ16(Controller, ControlRegister);
  2190. if ((Control & MUSB_RX_CONTROL_PACKET_READY) != 0) {
  2191. Control |= MUSB_RX_CONTROL_FLUSH_FIFO;
  2192. }
  2193. Control |= MUSB_RX_CONTROL_ERROR_MASK;
  2194. MUSB_WRITE16(Controller, ControlRegister, Control);
  2195. Status = CppiTearDownDescriptor(Controller->CppiDma,
  2196. &(Transfer->DmaData));
  2197. ASSERT(KSUCCESS(Status));
  2198. //
  2199. // Abort a non-DMA transfer.
  2200. //
  2201. } else {
  2202. Control = MUSB_READ8(Controller, ControlRegister);
  2203. Control &= ~MUSB_RX_CONTROL_REQUEST_PACKET;
  2204. MUSB_WRITE8(Controller, ControlRegister, Control);
  2205. HlBusySpin(250);
  2206. MusbpFlushFifo(Controller, HardwareIndex, FALSE);
  2207. MusbpFlushFifo(Controller, HardwareIndex, FALSE);
  2208. MUSB_WRITE16(Controller, ControlRegister, 0);
  2209. }
  2210. }
  2211. return;
  2212. }
  2213. VOID
  2214. MusbpConfigureHardwareEndpoint (
  2215. PMUSB_CONTROLLER Controller,
  2216. PMUSB_SOFT_ENDPOINT SoftEndpoint
  2217. )
  2218. /*++
  2219. Routine Description:
  2220. This routine sets up the hardware endpoint associated with the given
  2221. software endpoint in preparation for transfer submission. This routine
  2222. assumes the controller lock is already held.
  2223. Arguments:
  2224. Controller - Supplies a pointer to the controller.
  2225. SoftEndpoint - Supplies a pointer to the software endpoint structure.
  2226. Return Value:
  2227. None.
  2228. --*/
  2229. {
  2230. USHORT Control;
  2231. PMUSB_HARD_ENDPOINT HardEndpoint;
  2232. UCHAR HardIndex;
  2233. ULONG Register;
  2234. HardIndex = SoftEndpoint->HardwareIndex;
  2235. HardEndpoint = &(Controller->Endpoints[HardIndex]);
  2236. //
  2237. // If the hardware endpoint is already set up from last time, then there's
  2238. // no need to reprogram it.
  2239. //
  2240. if (HardEndpoint->CurrentEndpoint == SoftEndpoint) {
  2241. //
  2242. // Just write the control register.
  2243. //
  2244. if (SoftEndpoint->Direction == UsbTransferDirectionOut) {
  2245. Register = MUSB_ENDPOINT_CONTROL(MusbTxControlStatus, HardIndex);
  2246. } else {
  2247. Register = MUSB_ENDPOINT_CONTROL(MusbRxControlStatus, HardIndex);
  2248. }
  2249. MUSB_WRITE16(Controller, Register, SoftEndpoint->Control);
  2250. return;
  2251. }
  2252. if (SoftEndpoint->Direction == UsbTransferDirectionOut) {
  2253. Controller->TxInterruptEnable &= ~(1 << HardIndex);
  2254. MUSB_WRITE16(Controller,
  2255. MusbInterruptEnableTx,
  2256. Controller->TxInterruptEnable);
  2257. //
  2258. // Write the control registers.
  2259. //
  2260. Register = MUSB_ENDPOINT_CONTROL(MusbTxMaxPacketSize, HardIndex);
  2261. MUSB_WRITE16(Controller, Register, SoftEndpoint->MaxPayload);
  2262. Register = MUSB_ENDPOINT_CONTROL(MusbTxControlStatus, HardIndex);
  2263. if (SoftEndpoint->HardwareIndex == 0) {
  2264. Control = SoftEndpoint->Control |
  2265. MUSB_EP0_CONTROL_DATA_TOGGLE_WRITE;
  2266. } else {
  2267. Control = SoftEndpoint->Control | MUSB_TX_CONTROL_DATA_TOGGLE_WRITE;
  2268. }
  2269. MUSB_WRITE16(Controller, Register, Control);
  2270. Register = MUSB_ENDPOINT_CONTROL(MusbTxType, HardIndex);
  2271. MUSB_WRITE8(Controller, Register, SoftEndpoint->Type);
  2272. Register = MUSB_ENDPOINT_CONTROL(MusbTxInterval, HardIndex);
  2273. MUSB_WRITE8(Controller, Register, SoftEndpoint->Interval);
  2274. //
  2275. // Write the setup registers.
  2276. //
  2277. Register = MUSB_ENDPOINT_SETUP(MusbTxFunctionAddress, HardIndex);
  2278. MUSB_WRITE8(Controller, Register, SoftEndpoint->Device);
  2279. Register = MUSB_ENDPOINT_SETUP(MusbTxHubAddress, HardIndex);
  2280. MUSB_WRITE8(Controller, Register, SoftEndpoint->HubAddress);
  2281. Register = MUSB_ENDPOINT_SETUP(MusbTxHubPort, HardIndex);
  2282. MUSB_WRITE8(Controller, Register, SoftEndpoint->HubPort);
  2283. //
  2284. // For the control endpoint, initialize both TX and RX setup registers.
  2285. //
  2286. if (SoftEndpoint->HardwareIndex == 0) {
  2287. Register = MUSB_ENDPOINT_SETUP(MusbRxFunctionAddress, HardIndex);
  2288. MUSB_WRITE8(Controller, Register, SoftEndpoint->Device);
  2289. Register = MUSB_ENDPOINT_SETUP(MusbRxHubAddress, HardIndex);
  2290. MUSB_WRITE8(Controller, Register, SoftEndpoint->HubAddress);
  2291. Register = MUSB_ENDPOINT_SETUP(MusbRxHubPort, HardIndex);
  2292. }
  2293. } else {
  2294. ASSERT(SoftEndpoint->Direction == UsbTransferDirectionIn);
  2295. Controller->RxInterruptEnable &= ~(1 << HardIndex);
  2296. MUSB_WRITE16(Controller,
  2297. MusbInterruptEnableRx,
  2298. Controller->RxInterruptEnable);
  2299. //
  2300. // Write the control registers.
  2301. //
  2302. Register = MUSB_ENDPOINT_CONTROL(MusbRxMaxPacketSize, HardIndex);
  2303. MUSB_WRITE16(Controller, Register, SoftEndpoint->MaxPayload);
  2304. Register = MUSB_ENDPOINT_CONTROL(MusbRxControlStatus, HardIndex);
  2305. Control = SoftEndpoint->Control | MUSB_RX_CONTROL_DATA_TOGGLE_WRITE;
  2306. MUSB_WRITE16(Controller, Register, Control);
  2307. Register = MUSB_ENDPOINT_CONTROL(MusbRxType, HardIndex);
  2308. MUSB_WRITE8(Controller, Register, SoftEndpoint->Type);
  2309. Register = MUSB_ENDPOINT_CONTROL(MusbRxInterval, HardIndex);
  2310. MUSB_WRITE8(Controller, Register, SoftEndpoint->Interval);
  2311. //
  2312. // Write the setup registers.
  2313. //
  2314. Register = MUSB_ENDPOINT_SETUP(MusbRxFunctionAddress, HardIndex);
  2315. MUSB_WRITE8(Controller, Register, SoftEndpoint->Device);
  2316. Register = MUSB_ENDPOINT_SETUP(MusbRxHubAddress, HardIndex);
  2317. MUSB_WRITE8(Controller, Register, SoftEndpoint->HubAddress);
  2318. Register = MUSB_ENDPOINT_SETUP(MusbRxHubPort, HardIndex);
  2319. MUSB_WRITE8(Controller, Register, SoftEndpoint->HubPort);
  2320. }
  2321. HardEndpoint->CurrentEndpoint = SoftEndpoint;
  2322. return;
  2323. }
  2324. VOID
  2325. MusbpUpdateDataToggle (
  2326. PMUSB_CONTROLLER Controller,
  2327. PMUSB_TRANSFER_SET TransferSet
  2328. )
  2329. /*++
  2330. Routine Description:
  2331. This routine updates the data toggle bit in the control member of the soft
  2332. endpoint corresponding to the given transfer set.
  2333. Arguments:
  2334. Controller - Supplies a pointer to the controller.
  2335. TransferSet - Supplies a pointer to the transfer set. The current index
  2336. transfer will be used to determine whether the transfer is IN or OUT.
  2337. Return Value:
  2338. None.
  2339. --*/
  2340. {
  2341. USHORT Control;
  2342. UCHAR HardwareIndex;
  2343. ULONG Register;
  2344. PMUSB_SOFT_ENDPOINT SoftEndpoint;
  2345. PMUSB_TRANSFER Transfer;
  2346. SoftEndpoint = TransferSet->SoftEndpoint;
  2347. HardwareIndex = SoftEndpoint->HardwareIndex;
  2348. Transfer = &(TransferSet->Transfers[TransferSet->CurrentIndex]);
  2349. //
  2350. // Update the data toggle.
  2351. //
  2352. if ((Transfer->Flags & MUSB_TRANSFER_OUT) != 0) {
  2353. if (HardwareIndex != 0) {
  2354. Register = MUSB_ENDPOINT_CONTROL(MusbTxControlStatus,
  2355. HardwareIndex);
  2356. Control = MUSB_READ16(Controller, Register);
  2357. SoftEndpoint->Control = (SoftEndpoint->Control &
  2358. ~MUSB_TX_CONTROL_DATA_TOGGLE) |
  2359. (Control & MUSB_TX_CONTROL_DATA_TOGGLE);
  2360. }
  2361. } else {
  2362. Register = MUSB_ENDPOINT_CONTROL(MusbRxControlStatus,
  2363. HardwareIndex);
  2364. Control = MUSB_READ16(Controller, Register);
  2365. SoftEndpoint->Control = (SoftEndpoint->Control &
  2366. ~MUSB_RX_CONTROL_DATA_TOGGLE) |
  2367. (Control & MUSB_RX_CONTROL_DATA_TOGGLE);
  2368. }
  2369. return;
  2370. }
  2371. VOID
  2372. MusbpWriteFifo (
  2373. PMUSB_CONTROLLER Controller,
  2374. UCHAR EndpointIndex,
  2375. PVOID Buffer,
  2376. ULONG Size
  2377. )
  2378. /*++
  2379. Routine Description:
  2380. This routine writes the given buffer contents to the FIFO.
  2381. Arguments:
  2382. Controller - Supplies a pointer to the controller.
  2383. EndpointIndex - Supplies the hardware endpoint number to write to.
  2384. Buffer - Supplies a pointer to the data to write.
  2385. Size - Supplies the number of bytes to write.
  2386. Return Value:
  2387. None.
  2388. --*/
  2389. {
  2390. PUCHAR Bytes;
  2391. ULONG Index;
  2392. ULONG Register;
  2393. Bytes = Buffer;
  2394. Register = MUSB_FIFO_REGISTER(EndpointIndex);
  2395. for (Index = 0; Index < Size; Index += 1) {
  2396. MUSB_WRITE8(Controller, Register, Bytes[Index]);
  2397. }
  2398. return;
  2399. }
  2400. VOID
  2401. MusbpReadFifo (
  2402. PMUSB_CONTROLLER Controller,
  2403. UCHAR EndpointIndex,
  2404. PVOID Buffer,
  2405. ULONG BufferSize
  2406. )
  2407. /*++
  2408. Routine Description:
  2409. This routine reads from the FIFO into the given buffer.
  2410. Arguments:
  2411. Controller - Supplies a pointer to the controller.
  2412. EndpointIndex - Supplies the hardware endpoint number to read from.
  2413. Buffer - Supplies a pointer where the read data will be returned..
  2414. BufferSize - Supplies the number of bytes to read into the buffer.
  2415. Return Value:
  2416. None.
  2417. --*/
  2418. {
  2419. PUCHAR Bytes;
  2420. ULONG Index;
  2421. ULONG Register;
  2422. Bytes = Buffer;
  2423. Register = MUSB_FIFO_REGISTER(EndpointIndex);
  2424. for (Index = 0; Index < BufferSize; Index += 1) {
  2425. Bytes[Index] = MUSB_READ8(Controller, Register);
  2426. }
  2427. MmSyncCacheRegion(Buffer, BufferSize);
  2428. return;
  2429. }
  2430. VOID
  2431. MusbpFlushFifo (
  2432. PMUSB_CONTROLLER Controller,
  2433. UCHAR HardwareIndex,
  2434. BOOL HostOut
  2435. )
  2436. /*++
  2437. Routine Description:
  2438. This routine forcefully flushes the FIFO.
  2439. Arguments:
  2440. Controller - Supplies a pointer to the controller.
  2441. HardwareIndex - Supplies the hardware endpoint number to write to.
  2442. HostOut - Supplies a boolean indicating whether to flush the transmit FIFO
  2443. (TRUE) or the receive FIFO (FALSE).
  2444. Return Value:
  2445. None.
  2446. --*/
  2447. {
  2448. UCHAR Control;
  2449. ULONG Register;
  2450. if (HardwareIndex == 0) {
  2451. //
  2452. // If there's something in the FIFO, hit the red button.
  2453. //
  2454. Register = MUSB_ENDPOINT_CONTROL(MusbTxControlStatus, 0);
  2455. Control = MUSB_READ8(Controller, Register);
  2456. if ((Control &
  2457. (MUSB_EP0_CONTROL_TX_PACKET_READY |
  2458. MUSB_EP0_CONTROL_RX_PACKET_READY)) != 0) {
  2459. //
  2460. // Just write the high byte of the control word.
  2461. //
  2462. Control = MUSB_EP0_CONTROL_FLUSH_FIFO >> 8;
  2463. MUSB_WRITE8(Controller, Register + 1, Control);
  2464. }
  2465. } else if (HostOut != FALSE) {
  2466. //
  2467. // If the FIFO is not empty, flush it.
  2468. //
  2469. Register = MUSB_ENDPOINT_CONTROL(MusbTxControlStatus, HardwareIndex);
  2470. Control = MUSB_READ8(Controller, Register);
  2471. if ((Control & MUSB_TX_CONTROL_PACKET_READY) != 0) {
  2472. Control |= MUSB_TX_CONTROL_FLUSH_FIFO | MUSB_TX_CONTROL_ERROR_MASK;
  2473. MUSB_WRITE8(Controller, Register, Control);
  2474. }
  2475. } else {
  2476. Register = MUSB_ENDPOINT_CONTROL(MusbRxControlStatus, HardwareIndex);
  2477. Control = MUSB_READ8(Controller, Register);
  2478. if ((Control & MUSB_RX_CONTROL_PACKET_READY) != 0) {
  2479. Control |= MUSB_RX_CONTROL_FLUSH_FIFO | MUSB_RX_CONTROL_ERROR_MASK;
  2480. MUSB_WRITE8(Controller, Register, Control);
  2481. }
  2482. }
  2483. Controller->Endpoints[HardwareIndex].CurrentEndpoint = NULL;
  2484. return;
  2485. }
  2486. VOID
  2487. MusbpAssignEndpoint (
  2488. PMUSB_CONTROLLER Controller,
  2489. PMUSB_SOFT_ENDPOINT SoftEndpoint
  2490. )
  2491. /*++
  2492. Routine Description:
  2493. This routine assigns a software endpoint to a hardware endpoint. Ideally it
  2494. tries to find one with no transfers on it already, and will try not to
  2495. move endpoints if possible. This routine assumes the controller lock is
  2496. already held.
  2497. Arguments:
  2498. Controller - Supplies a pointer to the controller.
  2499. SoftEndpoint - Supplies a pointer to the endpoint to assign. On output, the
  2500. hardware index of this endpoint will be set.
  2501. Return Value:
  2502. None.
  2503. --*/
  2504. {
  2505. UCHAR Alternate;
  2506. USHORT FifoSize;
  2507. PMUSB_HARD_ENDPOINT HardEndpoint;
  2508. ULONG Index;
  2509. UCHAR SearchIndex;
  2510. //
  2511. // Control endpoints always go to hardware endpoint 0, by hardware mandate.
  2512. //
  2513. if ((SoftEndpoint->Type & MUSB_TXTYPE_PROTOCOL_MASK) ==
  2514. MUSB_TXTYPE_PROTOCOL_CONTROL) {
  2515. SoftEndpoint->HardwareIndex = 0;
  2516. return;
  2517. }
  2518. //
  2519. // If there are already transfers in flight on this endpoint, then it
  2520. // cannot move as that would mess up the ordering of transfers on the bus.
  2521. //
  2522. if (SoftEndpoint->InFlight != 0) {
  2523. ASSERT(SoftEndpoint->HardwareIndex != 0);
  2524. return;
  2525. }
  2526. //
  2527. // This endpoint is not a control endpoint. If its hardware index is not
  2528. // yet assigned, pick a round-robin new one. Otherwise, start from the
  2529. // previous one.
  2530. //
  2531. Alternate = 0;
  2532. SearchIndex = SoftEndpoint->HardwareIndex;
  2533. if (SearchIndex == 0) {
  2534. SearchIndex = Controller->NextEndpointAssignment;
  2535. Controller->NextEndpointAssignment += 1;
  2536. if (Controller->NextEndpointAssignment == Controller->EndpointCount) {
  2537. Controller->NextEndpointAssignment = 1;
  2538. }
  2539. }
  2540. for (Index = 1; Index < Controller->EndpointCount; Index += 1) {
  2541. ASSERT(SearchIndex != 0);
  2542. HardEndpoint = &(Controller->Endpoints[SearchIndex]);
  2543. if (SoftEndpoint->Direction == UsbTransferDirectionOut) {
  2544. FifoSize = HardEndpoint->TxFifoSize;
  2545. } else {
  2546. FifoSize = HardEndpoint->RxFifoSize;
  2547. }
  2548. //
  2549. // If the endpoint has the FIFO space, then this endpoint may work.
  2550. //
  2551. if (SoftEndpoint->MaxPayload <= FifoSize) {
  2552. //
  2553. // If this endpoint has no transfers on it, then definitely use it.
  2554. //
  2555. if (LIST_EMPTY(&(HardEndpoint->TransferList))) {
  2556. SoftEndpoint->HardwareIndex = SearchIndex;
  2557. return;
  2558. }
  2559. //
  2560. // Otherwise, save the endpoint as a backup.
  2561. //
  2562. if (Alternate == 0) {
  2563. Alternate = SearchIndex;
  2564. //
  2565. // This endpoint is moving off what it was before, so clear out
  2566. // the saved configuration, since when the endpoint is
  2567. // destroyed it may never know to clear this old pointer.
  2568. //
  2569. if (HardEndpoint->CurrentEndpoint == SoftEndpoint) {
  2570. HardEndpoint->CurrentEndpoint = NULL;
  2571. }
  2572. }
  2573. }
  2574. SearchIndex += 1;
  2575. if (SearchIndex == Controller->EndpointCount) {
  2576. SearchIndex = 1;
  2577. }
  2578. }
  2579. //
  2580. // Use the alternate, even though there are transfers queued on it.
  2581. //
  2582. ASSERT(Alternate != 0);
  2583. SoftEndpoint->HardwareIndex = Alternate;
  2584. return;
  2585. }
  2586. UCHAR
  2587. MusbpReadIndexed8 (
  2588. PMUSB_CONTROLLER Controller,
  2589. UCHAR Index,
  2590. MUSB_INDEXED_REGISTER Register
  2591. )
  2592. /*++
  2593. Routine Description:
  2594. This routine performs an indexed register read. It is assumed the
  2595. controller lock is already held.
  2596. Arguments:
  2597. Controller - Supplies a pointer to the controller.
  2598. Index - Supplies the hardware endpoint index to read from.
  2599. Register - Supplies the register to read.
  2600. Return Value:
  2601. Returns the register value.
  2602. --*/
  2603. {
  2604. if (Controller->CurrentIndex != Index) {
  2605. MUSB_WRITE8(Controller, MusbIndex, Index);
  2606. Controller->CurrentIndex = Index;
  2607. }
  2608. return MUSB_READ8(Controller, Register);
  2609. }
  2610. UCHAR
  2611. MusbpReadIndexed16 (
  2612. PMUSB_CONTROLLER Controller,
  2613. UCHAR Index,
  2614. MUSB_INDEXED_REGISTER Register
  2615. )
  2616. /*++
  2617. Routine Description:
  2618. This routine performs an indexed register read. It is assumed the
  2619. controller lock is already held.
  2620. Arguments:
  2621. Controller - Supplies a pointer to the controller.
  2622. Index - Supplies the hardware endpoint index to read from.
  2623. Register - Supplies the register to read.
  2624. Return Value:
  2625. Returns the register value.
  2626. --*/
  2627. {
  2628. if (Controller->CurrentIndex != Index) {
  2629. MUSB_WRITE8(Controller, MusbIndex, Index);
  2630. Controller->CurrentIndex = Index;
  2631. }
  2632. return MUSB_READ16(Controller, Register);
  2633. }
  2634. VOID
  2635. MusbpWriteIndexed8 (
  2636. PMUSB_CONTROLLER Controller,
  2637. UCHAR Index,
  2638. MUSB_INDEXED_REGISTER Register,
  2639. UCHAR Value
  2640. )
  2641. /*++
  2642. Routine Description:
  2643. This routine performs an indexed register write. It is assumed the
  2644. controller lock is already held.
  2645. Arguments:
  2646. Controller - Supplies a pointer to the controller.
  2647. Index - Supplies the hardware endpoint index to write to.
  2648. Register - Supplies the register to write.
  2649. Value - Supplies the value to write.
  2650. Return Value:
  2651. None.
  2652. --*/
  2653. {
  2654. if (Controller->CurrentIndex != Index) {
  2655. MUSB_WRITE8(Controller, MusbIndex, Index);
  2656. Controller->CurrentIndex = Index;
  2657. }
  2658. MUSB_WRITE8(Controller, Register, Value);
  2659. return;
  2660. }
  2661. VOID
  2662. MusbpWriteIndexed16 (
  2663. PMUSB_CONTROLLER Controller,
  2664. UCHAR Index,
  2665. MUSB_INDEXED_REGISTER Register,
  2666. USHORT Value
  2667. )
  2668. /*++
  2669. Routine Description:
  2670. This routine performs an indexed register write. It is assumed the
  2671. controller lock is already held.
  2672. Arguments:
  2673. Controller - Supplies a pointer to the controller.
  2674. Index - Supplies the hardware endpoint index to write to.
  2675. Register - Supplies the register to write.
  2676. Value - Supplies the value to write.
  2677. Return Value:
  2678. None.
  2679. --*/
  2680. {
  2681. if (Controller->CurrentIndex != Index) {
  2682. MUSB_WRITE8(Controller, MusbIndex, Index);
  2683. Controller->CurrentIndex = Index;
  2684. }
  2685. MUSB_WRITE16(Controller, Register, Value);
  2686. return;
  2687. }
  2688. VOID
  2689. MusbpAcquireLock (
  2690. PMUSB_CONTROLLER Controller
  2691. )
  2692. /*++
  2693. Routine Description:
  2694. This routine acquires the controller lock.
  2695. Arguments:
  2696. Controller - Supplies a pointer to the controller.
  2697. Return Value:
  2698. None.
  2699. --*/
  2700. {
  2701. RUNLEVEL OldRunLevel;
  2702. OldRunLevel = KeRaiseRunLevel(RunLevelDispatch);
  2703. KeAcquireSpinLock(&(Controller->Lock));
  2704. Controller->OldRunLevel = OldRunLevel;
  2705. return;
  2706. }
  2707. VOID
  2708. MusbpReleaseLock (
  2709. PMUSB_CONTROLLER Controller
  2710. )
  2711. /*++
  2712. Routine Description:
  2713. This routine releases the controller lock.
  2714. Arguments:
  2715. Controller - Supplies a pointer to the controller.
  2716. OldRunLevel - Stores the original runlevel to return to.
  2717. Return Value:
  2718. None.
  2719. --*/
  2720. {
  2721. RUNLEVEL OldRunLevel;
  2722. OldRunLevel = Controller->OldRunLevel;
  2723. KeReleaseSpinLock(&(Controller->Lock));
  2724. KeLowerRunLevel(OldRunLevel);
  2725. return;
  2726. }