usbcore.c 94 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776
  1. /*++
  2. Copyright (c) 2013 Minoca Corp. All Rights Reserved
  3. Module Name:
  4. usbcore.c
  5. Abstract:
  6. This module implements the USB core library.
  7. Author:
  8. Evan Green 15-Jan-2013
  9. Environment:
  10. Kernel
  11. --*/
  12. //
  13. // ------------------------------------------------------------------- Includes
  14. //
  15. #include <minoca/kernel/driver.h>
  16. #include <minoca/fw/acpitabs.h>
  17. #include "usbcore.h"
  18. //
  19. // ---------------------------------------------------------------- Definitions
  20. //
  21. //
  22. // Define the initial allocation size for a configuration descriptor.
  23. //
  24. #define USB_INITIAL_CONFIGURATION_LENGTH 0xFF
  25. //
  26. // ------------------------------------------------------ Data Type Definitions
  27. //
  28. //
  29. // ----------------------------------------------- Internal Function Prototypes
  30. //
  31. KSTATUS
  32. UsbpCancelTransfer (
  33. PUSB_TRANSFER_PRIVATE Transfer
  34. );
  35. VOID
  36. UsbpDestroyTransfer (
  37. PUSB_TRANSFER Transfer
  38. );
  39. KSTATUS
  40. UsbpGetConfiguration (
  41. PUSB_DEVICE Device,
  42. UCHAR ConfigurationNumber,
  43. BOOL NumberIsIndex,
  44. PUSB_CONFIGURATION *Configuration
  45. );
  46. KSTATUS
  47. UsbpSubmitTransfer (
  48. PUSB_TRANSFER Transfer,
  49. ULONG PrivateFlags,
  50. BOOL PolledMode
  51. );
  52. KSTATUS
  53. UsbpCreateEndpointsForInterface (
  54. PUSB_DEVICE Device,
  55. PUSB_INTERFACE Interface
  56. );
  57. PUSB_ENDPOINT
  58. UsbpGetDeviceEndpoint (
  59. PUSB_DEVICE Device,
  60. UCHAR EndpointNumber
  61. );
  62. VOID
  63. UsbpCompletedTransferWorker (
  64. PVOID Parameter
  65. );
  66. RUNLEVEL
  67. UsbpAcquireCompletedTransfersLock (
  68. PUSB_TRANSFER_COMPLETION_QUEUE CompletionQueue
  69. );
  70. VOID
  71. UsbpReleaseCompletedTransfersLock (
  72. PUSB_TRANSFER_COMPLETION_QUEUE CompletionQueue,
  73. RUNLEVEL OldRunLevel
  74. );
  75. //
  76. // -------------------------------------------------------------------- Globals
  77. //
  78. PDRIVER UsbCoreDriver;
  79. //
  80. // Store a pointer to the USB core work queue.
  81. //
  82. PWORK_QUEUE UsbCoreWorkQueue = NULL;
  83. //
  84. // Store a pointer to the special USB paging transfer completion queue.
  85. //
  86. PUSB_TRANSFER_COMPLETION_QUEUE UsbCorePagingCompletionQueue = NULL;
  87. //
  88. // Store a list of all active host controllers and a lock that protects this
  89. // list.
  90. //
  91. LIST_ENTRY UsbHostControllerList;
  92. PQUEUED_LOCK UsbHostControllerListLock = NULL;
  93. //
  94. // Store a list of all active USB devices in the system.
  95. //
  96. LIST_ENTRY UsbDeviceList;
  97. PQUEUED_LOCK UsbDeviceListLock = NULL;
  98. //
  99. // Store a bitfield of enabled USB debug flags. See USB_DEBUG_* definitions.
  100. //
  101. ULONG UsbDebugFlags = 0x0;
  102. //
  103. // Set this to enable debugging only a single device address. If this is zero,
  104. // it's enabled on all addresses.
  105. //
  106. UCHAR UsbDebugDeviceAddress = 0x0;
  107. //
  108. // Store a pointer to the USB debugger handoff data.
  109. //
  110. PDEBUG_HANDOFF_DATA UsbDebugHandoffData = NULL;
  111. //
  112. // Define transfer direction and endpoint type strings.
  113. //
  114. PSTR UsbTransferDirectionStrings[UsbTransferDirectionCount] = {
  115. "INVALID",
  116. "from",
  117. "to",
  118. "from/to"
  119. };
  120. PSTR UsbTransferTypeStrings[UsbTransferTypeCount] = {
  121. "INVALID",
  122. "control",
  123. "interrupt",
  124. "bulk",
  125. "isochronous",
  126. };
  127. PSTR UsbErrorStrings[UsbErrorCount] = {
  128. "No error",
  129. "Not started",
  130. "Cancelled",
  131. "Allocated incorrectly",
  132. "Double submitted",
  133. "Incorrectly filled out",
  134. "Failed to submit",
  135. "Stalled",
  136. "Data buffer",
  137. "Babble",
  138. "Nak",
  139. "CrcOrTimeout",
  140. "Bitstuff",
  141. "Missed microframe",
  142. "Misaligned buffer",
  143. "Device not connected",
  144. "Short packet",
  145. };
  146. //
  147. // ------------------------------------------------------------------ Functions
  148. //
  149. KSTATUS
  150. DriverEntry (
  151. PDRIVER Driver
  152. )
  153. /*++
  154. Routine Description:
  155. This routine implements the initial entry point of the USB core library,
  156. called when the library is first loaded.
  157. Arguments:
  158. Driver - Supplies a pointer to the driver object.
  159. Return Value:
  160. Status code.
  161. --*/
  162. {
  163. ULONG PathIndex;
  164. KSTATUS Status;
  165. Status = STATUS_INSUFFICIENT_RESOURCES;
  166. UsbCoreDriver = Driver;
  167. //
  168. // Initialize USB structures.
  169. //
  170. INITIALIZE_LIST_HEAD(&UsbHostControllerList);
  171. INITIALIZE_LIST_HEAD(&UsbDeviceList);
  172. ASSERT((UsbHostControllerListLock == NULL) &&
  173. (UsbDeviceListLock == NULL) &&
  174. (UsbCorePagingCompletionQueue == NULL) &&
  175. (UsbCoreWorkQueue == NULL));
  176. UsbHostControllerListLock = KeCreateQueuedLock();
  177. if (UsbHostControllerListLock == NULL) {
  178. goto DriverEntryEnd;
  179. }
  180. UsbDeviceListLock = KeCreateQueuedLock();
  181. if (UsbDeviceListLock == NULL) {
  182. goto DriverEntryEnd;
  183. }
  184. UsbCoreWorkQueue = KeCreateWorkQueue(WORK_QUEUE_FLAG_SUPPORT_DISPATCH_LEVEL,
  185. "UsbCoreWorker");
  186. if (UsbCoreWorkQueue== NULL) {
  187. goto DriverEntryEnd;
  188. }
  189. Status = KdGetDeviceInformation(&UsbDebugHandoffData);
  190. if ((!KSUCCESS(Status)) || (UsbDebugHandoffData == NULL) ||
  191. (UsbDebugHandoffData->PortType != DEBUG_PORT_TYPE_USB)) {
  192. UsbDebugHandoffData = NULL;
  193. }
  194. if ((UsbDebugFlags & USB_DEBUG_DEBUGGER_HANDOFF) != 0) {
  195. RtlDebugPrint("USB: Debug handoff data: %x\n", UsbDebugHandoffData);
  196. if (UsbDebugHandoffData != NULL) {
  197. RtlDebugPrint("USB: Debug device %04X:%04X is at path ",
  198. UsbDebugHandoffData->U.Usb.VendorId,
  199. UsbDebugHandoffData->U.Usb.ProductId);
  200. for (PathIndex = 0;
  201. PathIndex < UsbDebugHandoffData->U.Usb.DevicePathSize;
  202. PathIndex += 1) {
  203. if (PathIndex != 0) {
  204. RtlDebugPrint(", ");
  205. }
  206. RtlDebugPrint(
  207. "%d",
  208. UsbDebugHandoffData->U.Usb.DevicePath[PathIndex]);
  209. }
  210. RtlDebugPrint("\n");
  211. }
  212. }
  213. Status = STATUS_SUCCESS;
  214. DriverEntryEnd:
  215. return Status;
  216. }
  217. USB_API
  218. HANDLE
  219. UsbDeviceOpen (
  220. PUSB_DEVICE Device
  221. )
  222. /*++
  223. Routine Description:
  224. This routine attempts to open a USB device for I/O.
  225. Arguments:
  226. Device - Supplies a pointer to the device to open.
  227. Return Value:
  228. Returns a handle to the device upon success.
  229. INVALID_HANDLE if the device could not be opened.
  230. --*/
  231. {
  232. if (Device->Connected != FALSE) {
  233. UsbpDeviceAddReference(Device);
  234. return (HANDLE)Device;
  235. }
  236. return INVALID_HANDLE;
  237. }
  238. USB_API
  239. VOID
  240. UsbDeviceClose (
  241. HANDLE UsbDeviceHandle
  242. )
  243. /*++
  244. Routine Description:
  245. This routine closes an open USB handle.
  246. Arguments:
  247. UsbDeviceHandle - Supplies the handle returned when the device was opened.
  248. Return Value:
  249. None.
  250. --*/
  251. {
  252. PUSB_DEVICE Device;
  253. if (UsbDeviceHandle == INVALID_HANDLE) {
  254. return;
  255. }
  256. Device = (PUSB_DEVICE)UsbDeviceHandle;
  257. UsbpDeviceReleaseReference(Device);
  258. return;
  259. }
  260. USB_API
  261. PUSB_TRANSFER
  262. UsbAllocateTransfer (
  263. HANDLE UsbDeviceHandle,
  264. UCHAR EndpointNumber,
  265. ULONG MaxTransferSize,
  266. ULONG Flags
  267. )
  268. /*++
  269. Routine Description:
  270. This routine allocates a new USB transfer structure. This routine must be
  271. used to allocate transfers.
  272. Arguments:
  273. UsbDeviceHandle - Supplies the handle returned when the device was opened.
  274. EndpointNumber - Supplies the endpoint number that the transfer will go to.
  275. MaxTransferSize - Supplies the maximum length, in bytes, of the transfer.
  276. Attempts to submit a transfer with lengths longer than this initialized
  277. length will fail. Longer transfer sizes do require more resources as
  278. they are split into subpackets, so try to be reasonable.
  279. Flags - Supplies a bitfield of flags regarding the transaction. See
  280. USB_TRANSFER_FLAG_* definitions.
  281. Return Value:
  282. Returns a pointer to the new USB transfer on success.
  283. NULL when there are insufficient resources to complete the request.
  284. --*/
  285. {
  286. PUSB_TRANSFER Transfer;
  287. Transfer = UsbpAllocateTransfer((PUSB_DEVICE)UsbDeviceHandle,
  288. EndpointNumber,
  289. MaxTransferSize,
  290. Flags);
  291. return Transfer;
  292. }
  293. USB_API
  294. VOID
  295. UsbDestroyTransfer (
  296. PUSB_TRANSFER Transfer
  297. )
  298. /*++
  299. Routine Description:
  300. This routine destroys an allocated transfer. This transfer must not be
  301. actively transferring.
  302. Arguments:
  303. Transfer - Supplies a pointer to the transfer to destroy.
  304. Return Value:
  305. None.
  306. --*/
  307. {
  308. UsbTransferReleaseReference(Transfer);
  309. return;
  310. }
  311. USB_API
  312. KSTATUS
  313. UsbSubmitTransfer (
  314. PUSB_TRANSFER Transfer
  315. )
  316. /*++
  317. Routine Description:
  318. This routine submits a USB transfer. The routine returns immediately,
  319. indicating only whether the transfer was submitted successfully. When the
  320. transfer actually completes, the callback routine will be called.
  321. Arguments:
  322. Transfer - Supplies a pointer to the transfer to submit.
  323. Return Value:
  324. STATUS_SUCCESS if the transfer was submitted to the USB host controller's
  325. queue.
  326. STATUS_INVALID_PARAMETER if one or more of the transfer fields is not
  327. properly filled out.
  328. Failing status codes if the request could not be submitted.
  329. --*/
  330. {
  331. return UsbpSubmitTransfer(Transfer, 0, FALSE);
  332. }
  333. USB_API
  334. KSTATUS
  335. UsbSubmitSynchronousTransfer (
  336. PUSB_TRANSFER Transfer
  337. )
  338. /*++
  339. Routine Description:
  340. This routine submits a USB transfer, and does not return until the transfer
  341. is completed successfully or with an error. This routine must be called at
  342. low level.
  343. Arguments:
  344. Transfer - Supplies a pointer to the transfer to submit.
  345. Return Value:
  346. STATUS_SUCCESS if the transfer was submitted to the USB host controller's
  347. queue.
  348. STATUS_INVALID_PARAMETER if one or more of the transfer fields is not
  349. properly filled out.
  350. Failing status codes if the request could not be submitted.
  351. --*/
  352. {
  353. PUSB_TRANSFER_PRIVATE CompleteTransfer;
  354. KSTATUS Status;
  355. ASSERT(KeGetRunLevel() == RunLevelLow);
  356. CompleteTransfer = (PUSB_TRANSFER_PRIVATE)Transfer;
  357. KeSignalEvent(CompleteTransfer->Event, SignalOptionUnsignal);
  358. Status = UsbpSubmitTransfer(Transfer,
  359. USB_TRANSFER_PRIVATE_SYNCHRONOUS,
  360. FALSE);
  361. if (!KSUCCESS(Status)) {
  362. return Status;
  363. }
  364. //
  365. // Wait for the transfer to complete.
  366. //
  367. KeWaitForEvent(CompleteTransfer->Event, FALSE, WAIT_TIME_INDEFINITE);
  368. //
  369. // Assert that the transfer is now inactive. The caller should coordinate
  370. // not re-submitting this transfer before this call returns the status.
  371. //
  372. ASSERT(CompleteTransfer->State == TransferInactive);
  373. return Transfer->Status;
  374. }
  375. USB_API
  376. KSTATUS
  377. UsbSubmitPolledTransfer (
  378. PUSB_TRANSFER Transfer
  379. )
  380. /*++
  381. Routine Description:
  382. This routine submits a USB transfer, and does not return until the transfer
  383. is completed successfully or with an error. This routine is meant to be
  384. called in critical code paths at high level.
  385. Arguments:
  386. Transfer - Supplies a pointer to the transfer to submit.
  387. Return Value:
  388. Status code.
  389. --*/
  390. {
  391. PUSB_TRANSFER_PRIVATE CompleteTransfer;
  392. ULONG OriginalState;
  393. KSTATUS Status;
  394. ASSERT(KeGetRunLevel() == RunLevelHigh);
  395. ASSERT(Transfer->CallbackRoutine == NULL);
  396. Transfer->Flags |= USB_TRANSFER_FLAG_NO_INTERRUPT_ON_COMPLETION;
  397. Status = UsbpSubmitTransfer(Transfer,
  398. USB_TRANSFER_PRIVATE_SYNCHRONOUS,
  399. TRUE);
  400. if (!KSUCCESS(Status)) {
  401. return Status;
  402. }
  403. //
  404. // If the transfer was successful, then it should be in the active state.
  405. // Flip it back to inactive.
  406. //
  407. CompleteTransfer = (PUSB_TRANSFER_PRIVATE)Transfer;
  408. OriginalState = RtlAtomicCompareExchange32(&(CompleteTransfer->State),
  409. TransferInactive,
  410. TransferActive);
  411. ASSERT(OriginalState == TransferActive);
  412. return Status;
  413. }
  414. USB_API
  415. KSTATUS
  416. UsbCancelTransfer (
  417. PUSB_TRANSFER Transfer,
  418. BOOL Wait
  419. )
  420. /*++
  421. Routine Description:
  422. This routine cancels a USB transfer, waiting for the transfer to enter the
  423. inactive state before returning. Must be called at low level.
  424. Arguments:
  425. Transfer - Supplies a pointer to the transfer to cancel.
  426. Wait - Supplies a boolean indicating that the caller wants to wait for the
  427. transfer the reach the inactive state. Specify TRUE if unsure.
  428. Return Value:
  429. Returns STATUS_SUCCESS if the transfer was successfully cancelled.
  430. Returns STATUS_TOO_LATE if the transfer was not cancelled, but moved to the
  431. inactive state.
  432. --*/
  433. {
  434. PUSB_TRANSFER_PRIVATE CompleteTransfer;
  435. KSTATUS Status;
  436. ASSERT(KeGetRunLevel() == RunLevelLow);
  437. //
  438. // Attempt to cancel the transfer.
  439. //
  440. CompleteTransfer = (PUSB_TRANSFER_PRIVATE)Transfer;
  441. Status = UsbpCancelTransfer(CompleteTransfer);
  442. //
  443. // If desired, wait until the transfer has entered the inactive state.
  444. //
  445. if (Wait != FALSE) {
  446. while (CompleteTransfer->State != TransferInactive) {
  447. KeYield();
  448. }
  449. //
  450. // If the transfer was successfully pulled off the hardware queue, then
  451. // it really shouldn't be active. If it was too late to cancel, then it
  452. // may be active again. Tough luck.
  453. //
  454. ASSERT(!KSUCCESS(Status) ||
  455. (CompleteTransfer->State == TransferInactive));
  456. }
  457. return Status;
  458. }
  459. USB_API
  460. KSTATUS
  461. UsbInitializePagingDeviceTransfers (
  462. VOID
  463. )
  464. /*++
  465. Routine Description:
  466. This routine initializes the USB core to handle special paging device
  467. transfers that are serviced on their own work queue.
  468. Arguments:
  469. None.
  470. Return Value:
  471. Status code.
  472. --*/
  473. {
  474. ULONG AllocationSize;
  475. PUSB_TRANSFER_COMPLETION_QUEUE CompletionQueue;
  476. PVOID OriginalQueue;
  477. KSTATUS Status;
  478. //
  479. // If the paging device transfer completion queue is already initialized,
  480. // then all is ready to go.
  481. //
  482. if (UsbCorePagingCompletionQueue != NULL) {
  483. return STATUS_SUCCESS;
  484. }
  485. //
  486. // Otherwise initialize a transfer completion queue.
  487. //
  488. AllocationSize = sizeof(USB_TRANSFER_COMPLETION_QUEUE);
  489. CompletionQueue = MmAllocateNonPagedPool(AllocationSize,
  490. USB_CORE_ALLOCATION_TAG);
  491. if (CompletionQueue == NULL) {
  492. Status = STATUS_INSUFFICIENT_RESOURCES;
  493. goto InitializePagingDeviceTransfersEnd;
  494. }
  495. Status = UsbpInitializeTransferCompletionQueue(CompletionQueue, TRUE);
  496. if (!KSUCCESS(Status)) {
  497. goto InitializePagingDeviceTransfersEnd;
  498. }
  499. //
  500. // Now try make this new transfer completion queue the global queue.
  501. //
  502. OriginalQueue = (PVOID)RtlAtomicCompareExchange(
  503. (volatile UINTN *)&UsbCorePagingCompletionQueue,
  504. (UINTN)CompletionQueue,
  505. (UINTN)NULL);
  506. //
  507. // If the original queue value was still NULL, then this completion queue
  508. // won the race, do not destroy it below.
  509. //
  510. if (OriginalQueue == NULL) {
  511. CompletionQueue = NULL;
  512. }
  513. Status = STATUS_SUCCESS;
  514. InitializePagingDeviceTransfersEnd:
  515. if (CompletionQueue != NULL) {
  516. UsbpDestroyTransferCompletionQueue(CompletionQueue);
  517. MmFreeNonPagedPool(CompletionQueue);
  518. }
  519. return Status;
  520. }
  521. USB_API
  522. ULONG
  523. UsbTransferAddReference (
  524. PUSB_TRANSFER Transfer
  525. )
  526. /*++
  527. Routine Description:
  528. This routine adds a reference to a USB transfer.
  529. Arguments:
  530. Transfer - Supplies a pointer to the transfer that is to be referenced.
  531. Return Value:
  532. Returns the old reference count.
  533. --*/
  534. {
  535. PUSB_TRANSFER_PRIVATE CompleteTransfer;
  536. ULONG OldReferenceCount;
  537. CompleteTransfer = (PUSB_TRANSFER_PRIVATE)Transfer;
  538. OldReferenceCount = RtlAtomicAdd32(&(CompleteTransfer->ReferenceCount), 1);
  539. ASSERT((OldReferenceCount != 0) && (OldReferenceCount < 0x10000000));
  540. return OldReferenceCount;
  541. }
  542. USB_API
  543. ULONG
  544. UsbTransferReleaseReference (
  545. PUSB_TRANSFER Transfer
  546. )
  547. /*++
  548. Routine Description:
  549. This routine releases a reference on a USB transfer.
  550. Arguments:
  551. Transfer - Supplies a pointer to the transfer that is to be reference.
  552. Return Value:
  553. Returns the old reference count.
  554. --*/
  555. {
  556. PUSB_TRANSFER_PRIVATE CompleteTransfer;
  557. ULONG OldReferenceCount;
  558. CompleteTransfer = (PUSB_TRANSFER_PRIVATE)Transfer;
  559. OldReferenceCount = RtlAtomicAdd32(&(CompleteTransfer->ReferenceCount),
  560. (ULONG)-1);
  561. ASSERT((OldReferenceCount != 0) && (OldReferenceCount < 0x10000000));
  562. if (OldReferenceCount == 1) {
  563. UsbpDestroyTransfer(Transfer);
  564. }
  565. return OldReferenceCount;
  566. }
  567. USB_API
  568. KSTATUS
  569. UsbGetStatus (
  570. HANDLE UsbDeviceHandle,
  571. UCHAR RequestRecipient,
  572. USHORT Index,
  573. PUSHORT Data
  574. )
  575. /*++
  576. Routine Description:
  577. This routine gets the status from the given device, interface, or endpoint,
  578. as determined based on the request type and index. This routine must be
  579. called at low level.
  580. Arguments:
  581. UsbDeviceHandle - Supplies the handle returned when the device was opened.
  582. RequestRecipient - Supplies the recipient of this get status request.
  583. Index - Supplies the index of this get status request. This can be
  584. zero for devices, an interface number, or an endpoint number.
  585. Data - Supplies a pointer that receives the status from the request.
  586. Return Value:
  587. Status code.
  588. --*/
  589. {
  590. PUSB_DEVICE Device;
  591. ULONG LengthTransferred;
  592. USB_SETUP_PACKET SetupPacket;
  593. KSTATUS Status;
  594. ASSERT(KeGetRunLevel() == RunLevelLow);
  595. //
  596. // Validate the arguments.
  597. //
  598. if ((UsbDeviceHandle == INVALID_HANDLE) ||
  599. ((RequestRecipient != USB_SETUP_REQUEST_DEVICE_RECIPIENT) &&
  600. (RequestRecipient != USB_SETUP_REQUEST_INTERFACE_RECIPIENT) &&
  601. (RequestRecipient != USB_SETUP_REQUEST_ENDPOINT_RECIPIENT))) {
  602. Status = STATUS_INVALID_PARAMETER;
  603. goto GetStatusEnd;
  604. }
  605. //
  606. // Initialize the setup packet to send the device.
  607. //
  608. RtlZeroMemory(&SetupPacket, sizeof(USB_SETUP_PACKET));
  609. SetupPacket.RequestType = RequestRecipient | USB_SETUP_REQUEST_TO_HOST;
  610. SetupPacket.Request = USB_REQUEST_GET_STATUS;
  611. SetupPacket.Value = 0;
  612. SetupPacket.Index = Index;
  613. SetupPacket.Length = sizeof(USHORT);
  614. //
  615. // Send the transfer.
  616. //
  617. Device = (PUSB_DEVICE)UsbDeviceHandle;
  618. Status = UsbSendControlTransfer(Device,
  619. UsbTransferDirectionIn,
  620. &SetupPacket,
  621. Data,
  622. sizeof(USHORT),
  623. &LengthTransferred);
  624. //
  625. // Return failure if the transfer succeeded, but not enough bytes were
  626. // returned.
  627. //
  628. if (KSUCCESS(Status) && (LengthTransferred < sizeof(USHORT))) {
  629. Status = STATUS_DEVICE_IO_ERROR;
  630. goto GetStatusEnd;
  631. }
  632. GetStatusEnd:
  633. return Status;
  634. }
  635. USB_API
  636. KSTATUS
  637. UsbSetFeature (
  638. HANDLE UsbDeviceHandle,
  639. UCHAR RequestRecipient,
  640. USHORT Feature,
  641. USHORT Index
  642. )
  643. /*++
  644. Routine Description:
  645. This routine sets the given feature for a device, interface or endpoint,
  646. as specified by the request type and index. This routine must be called at
  647. low level.
  648. Arguments:
  649. UsbDeviceHandle - Supplies the handle returned when the device was opened.
  650. RequestRecipient - Supplies the recipient of this clear feature request.
  651. Feature - Supplies the value of this clear feature request.
  652. Index - Supplies the index of this clear feature request. This can be
  653. zero for devices, an interface number, or an endpoint number.
  654. Return Value:
  655. Status code.
  656. --*/
  657. {
  658. PUSB_DEVICE Device;
  659. USB_SETUP_PACKET SetupPacket;
  660. KSTATUS Status;
  661. ASSERT(KeGetRunLevel() == RunLevelLow);
  662. //
  663. // Validate the arguments.
  664. //
  665. if ((UsbDeviceHandle == INVALID_HANDLE) ||
  666. ((RequestRecipient != USB_SETUP_REQUEST_DEVICE_RECIPIENT) &&
  667. (RequestRecipient != USB_SETUP_REQUEST_INTERFACE_RECIPIENT) &&
  668. (RequestRecipient != USB_SETUP_REQUEST_ENDPOINT_RECIPIENT)) ||
  669. ((RequestRecipient == USB_SETUP_REQUEST_ENDPOINT_RECIPIENT) &&
  670. (Feature != USB_FEATURE_ENDPOINT_HALT)) ||
  671. ((RequestRecipient == USB_SETUP_REQUEST_DEVICE_RECIPIENT) &&
  672. (Feature != USB_FEATURE_DEVICE_REMOTE_WAKEUP))) {
  673. Status = STATUS_INVALID_PARAMETER;
  674. goto SetFeatureEnd;
  675. }
  676. //
  677. // There are no interface features defined in the USB specification.
  678. //
  679. ASSERT(RequestRecipient != USB_SETUP_REQUEST_INTERFACE_RECIPIENT);
  680. //
  681. // The test mode feature is not allowed to be cleared.
  682. //
  683. ASSERT(Feature != USB_FEATURE_DEVICE_TEST_MODE);
  684. //
  685. // Initialize the setup packet to send the device.
  686. //
  687. RtlZeroMemory(&SetupPacket, sizeof(USB_SETUP_PACKET));
  688. SetupPacket.RequestType = RequestRecipient | USB_SETUP_REQUEST_TO_DEVICE;
  689. SetupPacket.Request = USB_REQUEST_SET_FEATURE;
  690. SetupPacket.Value = Feature;
  691. SetupPacket.Index = Index;
  692. SetupPacket.Length = 0;
  693. //
  694. // Send the transfer.
  695. //
  696. Device = (PUSB_DEVICE)UsbDeviceHandle;
  697. Status = UsbSendControlTransfer(Device,
  698. UsbTransferDirectionOut,
  699. &SetupPacket,
  700. NULL,
  701. 0,
  702. NULL);
  703. if (!KSUCCESS(Status)) {
  704. goto SetFeatureEnd;
  705. }
  706. SetFeatureEnd:
  707. return Status;
  708. }
  709. USB_API
  710. KSTATUS
  711. UsbClearFeature (
  712. HANDLE UsbDeviceHandle,
  713. UCHAR RequestRecipient,
  714. USHORT Feature,
  715. USHORT Index
  716. )
  717. /*++
  718. Routine Description:
  719. This routine clears the given feature from a device, interface or endpoint,
  720. as specified by the request type and index. This routine must be called at
  721. low level.
  722. Arguments:
  723. UsbDeviceHandle - Supplies the handle returned when the device was opened.
  724. RequestRecipient - Supplies the recipient of this clear feature request.
  725. Feature - Supplies the value of this clear feature request.
  726. Index - Supplies the index of this clear feature request. This can be
  727. zero for devices, an interface number, or an endpoint number.
  728. Return Value:
  729. Status code.
  730. --*/
  731. {
  732. PUSB_DEVICE Device;
  733. PUSB_ENDPOINT Endpoint;
  734. USB_SETUP_PACKET SetupPacket;
  735. KSTATUS Status;
  736. ASSERT(KeGetRunLevel() == RunLevelLow);
  737. //
  738. // Validate the arguments.
  739. //
  740. if ((UsbDeviceHandle == INVALID_HANDLE) ||
  741. ((RequestRecipient != USB_SETUP_REQUEST_DEVICE_RECIPIENT) &&
  742. (RequestRecipient != USB_SETUP_REQUEST_INTERFACE_RECIPIENT) &&
  743. (RequestRecipient != USB_SETUP_REQUEST_ENDPOINT_RECIPIENT)) ||
  744. ((RequestRecipient == USB_SETUP_REQUEST_ENDPOINT_RECIPIENT) &&
  745. (Feature != USB_FEATURE_ENDPOINT_HALT)) ||
  746. ((RequestRecipient == USB_SETUP_REQUEST_DEVICE_RECIPIENT) &&
  747. (Feature != USB_FEATURE_DEVICE_REMOTE_WAKEUP))) {
  748. Status = STATUS_INVALID_PARAMETER;
  749. goto ClearFeatureEnd;
  750. }
  751. //
  752. // There are no interface features defined in the USB specification.
  753. //
  754. ASSERT(RequestRecipient != USB_SETUP_REQUEST_INTERFACE_RECIPIENT);
  755. //
  756. // The test mode feature is not allowed to be cleared.
  757. //
  758. ASSERT(Feature != USB_FEATURE_DEVICE_TEST_MODE);
  759. //
  760. // Initialize the setup packet to send the device.
  761. //
  762. RtlZeroMemory(&SetupPacket, sizeof(USB_SETUP_PACKET));
  763. SetupPacket.RequestType = RequestRecipient | USB_SETUP_REQUEST_TO_DEVICE;
  764. SetupPacket.Request = USB_REQUEST_CLEAR_FEATURE;
  765. SetupPacket.Value = Feature;
  766. SetupPacket.Index = Index;
  767. SetupPacket.Length = 0;
  768. //
  769. // Send the transfer.
  770. //
  771. Device = (PUSB_DEVICE)UsbDeviceHandle;
  772. Status = UsbSendControlTransfer(Device,
  773. UsbTransferDirectionOut,
  774. &SetupPacket,
  775. NULL,
  776. 0,
  777. NULL);
  778. if (!KSUCCESS(Status)) {
  779. goto ClearFeatureEnd;
  780. }
  781. //
  782. // If this was a successful attempt to clear an endpoint's HALT feature,
  783. // then the endpoint's data toggle needs to be unset, ensuring that the
  784. // next transfer on the endpoint will use DATA0.
  785. //
  786. if ((RequestRecipient == USB_SETUP_REQUEST_ENDPOINT_RECIPIENT) &&
  787. (Feature == USB_FEATURE_ENDPOINT_HALT)) {
  788. Endpoint = UsbpGetDeviceEndpoint(Device, Index);
  789. if (Endpoint == NULL) {
  790. ASSERT(Endpoint != NULL);
  791. Status = STATUS_NOT_FOUND;
  792. goto ClearFeatureEnd;
  793. }
  794. UsbpResetEndpoint(Device, Endpoint);
  795. }
  796. ClearFeatureEnd:
  797. return Status;
  798. }
  799. USB_API
  800. ULONG
  801. UsbGetConfigurationCount (
  802. HANDLE UsbDeviceHandle
  803. )
  804. /*++
  805. Routine Description:
  806. This routine gets the number of possible configurations in a given device.
  807. Arguments:
  808. UsbDeviceHandle - Supplies the handle returned when the device was opened.
  809. Return Value:
  810. Returns the number of configurations in the device.
  811. --*/
  812. {
  813. PUSB_DEVICE Device;
  814. if (UsbDeviceHandle == INVALID_HANDLE) {
  815. return 0;
  816. }
  817. Device = (PUSB_DEVICE)UsbDeviceHandle;
  818. return Device->ConfigurationCount;
  819. }
  820. USB_API
  821. KSTATUS
  822. UsbGetConfiguration (
  823. HANDLE UsbDeviceHandle,
  824. UCHAR ConfigurationNumber,
  825. BOOL NumberIsIndex,
  826. PUSB_CONFIGURATION_DESCRIPTION *Configuration
  827. )
  828. /*++
  829. Routine Description:
  830. This routine gets a configuration out of the given device. This routine will
  831. send a blocking request to the device. This routine must be called at low
  832. level.
  833. Arguments:
  834. UsbDeviceHandle - Supplies the handle returned when the device was opened.
  835. ConfigurationNumber - Supplies the index or configuration value of the
  836. configuration to get.
  837. NumberIsIndex - Supplies a boolean indicating whether the configuration
  838. number is an index (TRUE) or a specific configuration value (FALSE).
  839. Configuration - Supplies a pointer where a pointer to the desired
  840. configuration will be returned.
  841. Return Value:
  842. Status code.
  843. --*/
  844. {
  845. PUSB_DEVICE Device;
  846. PUSB_CONFIGURATION InternalConfiguration;
  847. KSTATUS Status;
  848. Device = (PUSB_DEVICE)UsbDeviceHandle;
  849. Status = UsbpGetConfiguration(Device,
  850. ConfigurationNumber,
  851. NumberIsIndex,
  852. &InternalConfiguration);
  853. *Configuration = &(InternalConfiguration->Description);
  854. return Status;
  855. }
  856. USB_API
  857. PUSB_CONFIGURATION_DESCRIPTION
  858. UsbGetActiveConfiguration (
  859. HANDLE UsbDeviceHandle
  860. )
  861. /*++
  862. Routine Description:
  863. This routine gets the currently active configuration set in the device.
  864. Arguments:
  865. UsbDeviceHandle - Supplies the handle returned when the device was opened.
  866. Return Value:
  867. Returns a pointer to the current configuration.
  868. NULL if the device is not currently configured.
  869. --*/
  870. {
  871. PUSB_DEVICE Device;
  872. if (UsbDeviceHandle == INVALID_HANDLE) {
  873. return NULL;
  874. }
  875. Device = (PUSB_DEVICE)UsbDeviceHandle;
  876. if (Device->ActiveConfiguration == NULL) {
  877. return NULL;
  878. }
  879. return &(Device->ActiveConfiguration->Description);
  880. }
  881. USB_API
  882. KSTATUS
  883. UsbSetConfiguration (
  884. HANDLE UsbDeviceHandle,
  885. UCHAR ConfigurationNumber,
  886. BOOL NumberIsIndex
  887. )
  888. /*++
  889. Routine Description:
  890. This routine sets the configuration to the given configuration value. This
  891. routine must be called at low level.
  892. Arguments:
  893. UsbDeviceHandle - Supplies the handle returned when the device was opened.
  894. ConfigurationNumber - Supplies the configuration index or value to set.
  895. NumberIsIndex - Supplies a boolean indicating whether the configuration
  896. number is an index (TRUE) or a specific configuration value (FALSE).
  897. Return Value:
  898. Status code.
  899. --*/
  900. {
  901. PUSB_CONFIGURATION Configuration;
  902. PLIST_ENTRY CurrentEndpointEntry;
  903. PLIST_ENTRY CurrentInterfaceEntry;
  904. PUSB_DEVICE Device;
  905. PUSB_ENDPOINT Endpoint;
  906. PUSB_INTERFACE Interface;
  907. PLIST_ENTRY InterfaceListHead;
  908. ULONG LengthTransferred;
  909. USB_SETUP_PACKET SetupPacket;
  910. KSTATUS Status;
  911. Device = (PUSB_DEVICE)UsbDeviceHandle;
  912. ASSERT(KeGetRunLevel() == RunLevelLow);
  913. //
  914. // First, get the configuration being described.
  915. //
  916. Status = UsbpGetConfiguration(Device,
  917. ConfigurationNumber,
  918. NumberIsIndex,
  919. &Configuration);
  920. if (!KSUCCESS(Status)) {
  921. goto SetConfigurationEnd;
  922. }
  923. //
  924. // Initialize the setup packet to send the device.
  925. //
  926. RtlZeroMemory(&SetupPacket, sizeof(USB_SETUP_PACKET));
  927. SetupPacket.RequestType = USB_SETUP_REQUEST_TO_DEVICE |
  928. USB_SETUP_REQUEST_STANDARD |
  929. USB_SETUP_REQUEST_DEVICE_RECIPIENT;
  930. SetupPacket.Request = USB_DEVICE_REQUEST_SET_CONFIGURATION;
  931. SetupPacket.Value =
  932. Configuration->Description.Descriptor.ConfigurationValue;
  933. SetupPacket.Index = 0;
  934. SetupPacket.Length = 0;
  935. //
  936. // Lock the device and send the set request. The device is locked to avoid
  937. // getting the active configuration variable out of sync with what the
  938. // device actually has set.
  939. //
  940. KeAcquireQueuedLock(Device->ConfigurationLock);
  941. Status = UsbSendControlTransfer(Device,
  942. UsbTransferDirectionOut,
  943. &SetupPacket,
  944. NULL,
  945. 0,
  946. &LengthTransferred);
  947. if (KSUCCESS(Status)) {
  948. Device->ActiveConfiguration = Configuration;
  949. }
  950. KeReleaseQueuedLock(Device->ConfigurationLock);
  951. //
  952. // Setting the configuration resets the DATA toggle for every endpoint on
  953. // the device. See Section 9.1.1.5 of the USB 2.0 Specification.
  954. //
  955. if (KSUCCESS(Status)) {
  956. UsbpResetEndpoint(Device, Device->EndpointZero);
  957. InterfaceListHead = &(Configuration->Description.InterfaceListHead);
  958. CurrentInterfaceEntry = InterfaceListHead->Next;
  959. while (CurrentInterfaceEntry != InterfaceListHead) {
  960. Interface = LIST_VALUE(CurrentInterfaceEntry,
  961. USB_INTERFACE,
  962. Description.ListEntry);
  963. CurrentEndpointEntry = Interface->EndpointList.Next;
  964. CurrentInterfaceEntry = CurrentInterfaceEntry->Next;
  965. while (CurrentEndpointEntry != &(Interface->EndpointList)) {
  966. Endpoint = LIST_VALUE(CurrentEndpointEntry,
  967. USB_ENDPOINT,
  968. ListEntry);
  969. UsbpResetEndpoint(Device, Endpoint);
  970. CurrentEndpointEntry = CurrentEndpointEntry->Next;
  971. }
  972. }
  973. }
  974. SetConfigurationEnd:
  975. return Status;
  976. }
  977. USB_API
  978. KSTATUS
  979. UsbClaimInterface (
  980. HANDLE UsbDeviceHandle,
  981. UCHAR InterfaceNumber
  982. )
  983. /*++
  984. Routine Description:
  985. This routine claims an interface, preparing it for I/O use. An interface
  986. can be claimed more than once. This routine must be called at low level.
  987. Arguments:
  988. UsbDeviceHandle - Supplies the handle returned when the device was opened.
  989. InterfaceNumber - Supplies the number of the interface to claim.
  990. Return Value:
  991. Status code.
  992. --*/
  993. {
  994. PUSB_CONFIGURATION Configuration;
  995. PLIST_ENTRY CurrentEntry;
  996. PUSB_DEVICE Device;
  997. PUSB_ENDPOINT Endpoint;
  998. PUSB_INTERFACE Interface;
  999. KSTATUS Status;
  1000. Device = (PUSB_DEVICE)UsbDeviceHandle;
  1001. Interface = NULL;
  1002. ASSERT(KeGetRunLevel() == RunLevelLow);
  1003. //
  1004. // Lock the device.
  1005. //
  1006. KeAcquireQueuedLock(Device->ConfigurationLock);
  1007. //
  1008. // If no interface has been set on the device yet, then an interface
  1009. // cannot be claimed.
  1010. //
  1011. Configuration = Device->ActiveConfiguration;
  1012. if (Configuration == NULL) {
  1013. Status = STATUS_INVALID_CONFIGURATION;
  1014. goto ClaimInterfaceEnd;
  1015. }
  1016. //
  1017. // Loop through looking for the requested interface.
  1018. //
  1019. CurrentEntry = Configuration->Description.InterfaceListHead.Next;
  1020. while (CurrentEntry != &(Configuration->Description.InterfaceListHead)) {
  1021. Interface = LIST_VALUE(CurrentEntry,
  1022. USB_INTERFACE,
  1023. Description.ListEntry);
  1024. if (Interface->Description.Descriptor.InterfaceNumber ==
  1025. InterfaceNumber) {
  1026. break;
  1027. }
  1028. CurrentEntry = CurrentEntry->Next;
  1029. }
  1030. if (CurrentEntry == &(Configuration->Description.InterfaceListHead)) {
  1031. Status = STATUS_NOT_FOUND;
  1032. goto ClaimInterfaceEnd;
  1033. }
  1034. //
  1035. // If the interface isn't supposed to have any endpoints, then finish.
  1036. //
  1037. if (LIST_EMPTY(&(Interface->Description.EndpointListHead)) != FALSE) {
  1038. Status = STATUS_SUCCESS;
  1039. goto ClaimInterfaceEnd;
  1040. }
  1041. //
  1042. // If there are no endpoints yet, they'll have to be created now.
  1043. //
  1044. if (LIST_EMPTY(&(Interface->EndpointList)) != FALSE) {
  1045. Status = UsbpCreateEndpointsForInterface(Device, Interface);
  1046. if (!KSUCCESS(Status)) {
  1047. goto ClaimInterfaceEnd;
  1048. }
  1049. //
  1050. // The endpoints are there, up the reference counts on them.
  1051. //
  1052. } else {
  1053. CurrentEntry = Interface->EndpointList.Next;
  1054. while (CurrentEntry != &(Interface->EndpointList)) {
  1055. Endpoint = LIST_VALUE(CurrentEntry, USB_ENDPOINT, ListEntry);
  1056. CurrentEntry = CurrentEntry->Next;
  1057. UsbpEndpointAddReference(Endpoint);
  1058. }
  1059. }
  1060. Status = STATUS_SUCCESS;
  1061. ClaimInterfaceEnd:
  1062. KeReleaseQueuedLock(Device->ConfigurationLock);
  1063. return Status;
  1064. }
  1065. USB_API
  1066. VOID
  1067. UsbReleaseInterface (
  1068. HANDLE UsbDeviceHandle,
  1069. UCHAR InterfaceNumber
  1070. )
  1071. /*++
  1072. Routine Description:
  1073. This routine releases an interface that was previously claimed for I/O.
  1074. After this call, the caller that had claimed the interface should not use
  1075. it again without reclaiming it.
  1076. Arguments:
  1077. UsbDeviceHandle - Supplies the handle returned when the device was opened.
  1078. InterfaceNumber - Supplies the number of the interface to release.
  1079. Return Value:
  1080. Status code.
  1081. --*/
  1082. {
  1083. PUSB_CONFIGURATION Configuration;
  1084. PLIST_ENTRY CurrentEntry;
  1085. PUSB_DEVICE Device;
  1086. PUSB_ENDPOINT Endpoint;
  1087. PUSB_INTERFACE Interface;
  1088. Device = (PUSB_DEVICE)UsbDeviceHandle;
  1089. Interface = NULL;
  1090. ASSERT(KeGetRunLevel() == RunLevelLow);
  1091. //
  1092. // Lock the device.
  1093. //
  1094. KeAcquireQueuedLock(Device->ConfigurationLock);
  1095. //
  1096. // If no interface has been set on the device yet, then an interface
  1097. // cannot be claimed.
  1098. //
  1099. Configuration = Device->ActiveConfiguration;
  1100. if (Configuration == NULL) {
  1101. goto ClaimInterfaceEnd;
  1102. }
  1103. //
  1104. // Loop through looking for the requested interface.
  1105. //
  1106. CurrentEntry = Configuration->Description.InterfaceListHead.Next;
  1107. while (CurrentEntry != &(Configuration->Description.InterfaceListHead)) {
  1108. Interface = LIST_VALUE(CurrentEntry,
  1109. USB_INTERFACE,
  1110. Description.ListEntry);
  1111. if (Interface->Description.Descriptor.InterfaceNumber ==
  1112. InterfaceNumber) {
  1113. break;
  1114. }
  1115. CurrentEntry = CurrentEntry->Next;
  1116. }
  1117. if (CurrentEntry == &(Configuration->Description.InterfaceListHead)) {
  1118. goto ClaimInterfaceEnd;
  1119. }
  1120. //
  1121. // If the interface isn't supposed to have any endpoints, then finish.
  1122. //
  1123. if (LIST_EMPTY(&(Interface->Description.EndpointListHead)) != FALSE) {
  1124. goto ClaimInterfaceEnd;
  1125. }
  1126. //
  1127. // Decrement the reference count on each endpoint. It's important to move
  1128. // to the next list entry before releasing the reference, as doing so may
  1129. // cause the endpoint to get unlinked and released.
  1130. //
  1131. CurrentEntry = Interface->EndpointList.Next;
  1132. while (CurrentEntry != &(Interface->EndpointList)) {
  1133. Endpoint = LIST_VALUE(CurrentEntry, USB_ENDPOINT, ListEntry);
  1134. CurrentEntry = CurrentEntry->Next;
  1135. UsbpEndpointReleaseReference(Device, Endpoint);
  1136. }
  1137. ClaimInterfaceEnd:
  1138. KeReleaseQueuedLock(Device->ConfigurationLock);
  1139. return;
  1140. }
  1141. USB_API
  1142. KSTATUS
  1143. UsbSendControlTransfer (
  1144. HANDLE UsbDeviceHandle,
  1145. USB_TRANSFER_DIRECTION TransferDirection,
  1146. PUSB_SETUP_PACKET SetupPacket,
  1147. PVOID Buffer,
  1148. ULONG BufferLength,
  1149. PULONG LengthTransferred
  1150. )
  1151. /*++
  1152. Routine Description:
  1153. This routine sends a syncrhonous control transfer to or from the given USB
  1154. device.
  1155. Arguments:
  1156. UsbDeviceHandle - Supplies a pointer to the device to talk to.
  1157. TransferDirection - Supplies whether or not the transfer is to the device
  1158. or to the host.
  1159. SetupPacket - Supplies a pointer to the setup packet.
  1160. Buffer - Supplies a pointer to the buffer to be sent or received. This does
  1161. not include the setup packet, this is the optional data portion only.
  1162. BufferLength - Supplies the length of the buffer, not including the setup
  1163. packet.
  1164. LengthTransferred - Supplies a pointer where the number of bytes that were
  1165. actually transfered (not including the setup packet) will be returned.
  1166. Return Value:
  1167. Status code.
  1168. --*/
  1169. {
  1170. UINTN AllocationSize;
  1171. UINTN BufferAlignment;
  1172. PUSB_DEVICE Device;
  1173. PIO_BUFFER IoBuffer;
  1174. ULONG IoBufferFlags;
  1175. KSTATUS Status;
  1176. PUSB_TRANSFER Transfer;
  1177. PVOID TransferBuffer;
  1178. ULONG TransferLength;
  1179. Device = (PUSB_DEVICE)UsbDeviceHandle;
  1180. Transfer = NULL;
  1181. if (LengthTransferred != NULL) {
  1182. *LengthTransferred = 0;
  1183. }
  1184. ASSERT(TransferDirection != UsbTransferDirectionInvalid);
  1185. //
  1186. // Create the I/O buffer that will be used for the transfer.
  1187. //
  1188. TransferLength = BufferLength + sizeof(USB_SETUP_PACKET);
  1189. BufferAlignment = MmGetIoBufferAlignment();
  1190. AllocationSize = ALIGN_RANGE_UP(TransferLength, BufferAlignment);
  1191. IoBufferFlags = IO_BUFFER_FLAG_PHYSICALLY_CONTIGUOUS;
  1192. IoBuffer = MmAllocateNonPagedIoBuffer(0,
  1193. MAX_ULONG,
  1194. BufferAlignment,
  1195. AllocationSize,
  1196. IoBufferFlags);
  1197. if (IoBuffer == NULL) {
  1198. Status = STATUS_INSUFFICIENT_RESOURCES;
  1199. goto SendControlTransferEnd;
  1200. }
  1201. ASSERT(IoBuffer->FragmentCount == 1);
  1202. TransferBuffer = IoBuffer->Fragment[0].VirtualAddress;
  1203. RtlCopyMemory(TransferBuffer, SetupPacket, sizeof(USB_SETUP_PACKET));
  1204. if ((TransferDirection == UsbTransferDirectionOut) &&
  1205. (BufferLength != 0)) {
  1206. RtlCopyMemory(TransferBuffer + sizeof(USB_SETUP_PACKET),
  1207. Buffer,
  1208. BufferLength);
  1209. }
  1210. //
  1211. // Create a USB transfer.
  1212. //
  1213. Transfer = UsbpAllocateTransfer(Device, 0, AllocationSize, 0);
  1214. if (Transfer == NULL) {
  1215. Status = STATUS_INSUFFICIENT_RESOURCES;
  1216. goto SendControlTransferEnd;
  1217. }
  1218. Transfer->Direction = TransferDirection;
  1219. Transfer->Length = TransferLength;
  1220. Transfer->Buffer = IoBuffer->Fragment[0].VirtualAddress;
  1221. Transfer->BufferPhysicalAddress = IoBuffer->Fragment[0].PhysicalAddress;
  1222. Transfer->BufferActualLength = IoBuffer->Fragment[0].Size;
  1223. //
  1224. // Submit the transfer and wait for it to complete.
  1225. //
  1226. Status = UsbSubmitSynchronousTransfer(Transfer);
  1227. if (!KSUCCESS(Status)) {
  1228. goto SendControlTransferEnd;
  1229. }
  1230. ASSERT(KSUCCESS(Transfer->Status));
  1231. //
  1232. // Copy the results into the caller's buffer.
  1233. //
  1234. ASSERT(Transfer->LengthTransferred >= sizeof(USB_SETUP_PACKET));
  1235. ASSERT(Transfer->LengthTransferred - sizeof(USB_SETUP_PACKET) <=
  1236. BufferLength);
  1237. if ((TransferDirection == UsbTransferDirectionIn) &&
  1238. (Transfer->LengthTransferred > sizeof(USB_SETUP_PACKET))) {
  1239. if (LengthTransferred != NULL) {
  1240. *LengthTransferred = Transfer->LengthTransferred -
  1241. sizeof(USB_SETUP_PACKET);
  1242. }
  1243. RtlCopyMemory(Buffer,
  1244. Transfer->Buffer + sizeof(USB_SETUP_PACKET),
  1245. Transfer->LengthTransferred - sizeof(USB_SETUP_PACKET));
  1246. }
  1247. Status = STATUS_SUCCESS;
  1248. SendControlTransferEnd:
  1249. if (Transfer != NULL) {
  1250. UsbDestroyTransfer(Transfer);
  1251. }
  1252. if (IoBuffer != NULL) {
  1253. MmFreeIoBuffer(IoBuffer);
  1254. }
  1255. return Status;
  1256. }
  1257. PUSB_TRANSFER
  1258. UsbpAllocateTransfer (
  1259. PUSB_DEVICE Device,
  1260. UCHAR EndpointNumber,
  1261. ULONG MaxTransferSize,
  1262. ULONG Flags
  1263. )
  1264. /*++
  1265. Routine Description:
  1266. This routine allocates a new USB transfer structure. This routine must be
  1267. used to allocate transfers.
  1268. Arguments:
  1269. Device - Supplies a pointer to the device the transfer will eventually be
  1270. submitted to. This must not be changed by the caller in the transfer
  1271. structure once set.
  1272. EndpointNumber - Supplies the endpoint number that the transfer will go to.
  1273. MaxTransferSize - Supplies the maximum length, in bytes, of the transfer.
  1274. Attempts to submit a transfer with lengths longer than this initialized
  1275. length will fail. Longer transfer sizes do require more resources as
  1276. they are split into subpackets, so try to be reasonable.
  1277. Flags - Supplies a bitfield of flags regarding the transaction. See
  1278. USB_TRANSFER_FLAG_* definitions.
  1279. Return Value:
  1280. Returns a pointer to the new USB transfer on success.
  1281. NULL when there are insufficient resources to complete the request.
  1282. --*/
  1283. {
  1284. ULONG AllocationSize;
  1285. PUSB_HOST_CREATE_TRANSFER CreateTransfer;
  1286. PUSB_HOST_DESTROY_TRANSFER DestroyTransfer;
  1287. PUSB_ENDPOINT Endpoint;
  1288. PVOID HostControllerContext;
  1289. BOOL ReleaseLock;
  1290. KSTATUS Status;
  1291. PUSB_TRANSFER_PRIVATE Transfer;
  1292. BOOL TransferCreated;
  1293. CreateTransfer = Device->Controller->Device.CreateTransfer;
  1294. DestroyTransfer = Device->Controller->Device.DestroyTransfer;
  1295. Endpoint = NULL;
  1296. HostControllerContext = Device->Controller->Device.HostControllerContext;
  1297. ReleaseLock = FALSE;
  1298. Transfer = NULL;
  1299. TransferCreated = FALSE;
  1300. //
  1301. // Add a reference to the device to account for the transfer. This is to
  1302. // potentially allow a driver to roll through the removal IRP destroying
  1303. // everything except for some pending transfer which depends on the USB
  1304. // core. The USB core device will get cleaned up when said transfer get
  1305. // destroyed, releasing this reference.
  1306. //
  1307. UsbpDeviceAddReference(Device);
  1308. //
  1309. // Find the endpoint associated with this transfer.
  1310. //
  1311. Endpoint = UsbpGetDeviceEndpoint(Device, EndpointNumber);
  1312. if (Endpoint == NULL) {
  1313. Status = STATUS_INVALID_PARAMETER;
  1314. goto AllocateTransferEnd;
  1315. }
  1316. //
  1317. // Allocate the transfer.
  1318. //
  1319. AllocationSize = sizeof(USB_TRANSFER_PRIVATE);
  1320. Transfer = MmAllocateNonPagedPool(AllocationSize, USB_CORE_ALLOCATION_TAG);
  1321. if (Transfer == NULL) {
  1322. Status = STATUS_INSUFFICIENT_RESOURCES;
  1323. goto AllocateTransferEnd;
  1324. }
  1325. RtlZeroMemory(Transfer, AllocationSize);
  1326. Transfer->Magic = USB_TRANSFER_INTERNAL_MAGIC;
  1327. Transfer->ReferenceCount = 1;
  1328. Transfer->Device = Device;
  1329. Transfer->Protected.DeviceAddress = Device->BusAddress;
  1330. Transfer->Protected.EndpointNumber = EndpointNumber;
  1331. Transfer->Protected.Type = Endpoint->Type;
  1332. Transfer->MaxTransferSize = MaxTransferSize;
  1333. Transfer->Endpoint = Endpoint;
  1334. Transfer->Protected.Public.Flags = Flags;
  1335. Transfer->Event = KeCreateEvent(NULL);
  1336. if (Transfer->Event == NULL) {
  1337. Status = STATUS_INSUFFICIENT_RESOURCES;
  1338. goto AllocateTransferEnd;
  1339. }
  1340. ASSERT(Transfer->State == TransferInvalid);
  1341. ASSERT(Transfer->CompletionListEntry.Next == NULL);
  1342. //
  1343. // Don't let a new transfer be created for a disconnected device.
  1344. //
  1345. KeAcquireQueuedLock(Device->Lock);
  1346. ReleaseLock = TRUE;
  1347. if (Device->Connected == FALSE) {
  1348. Status = STATUS_DEVICE_NOT_CONNECTED;
  1349. goto AllocateTransferEnd;
  1350. }
  1351. //
  1352. // Call into the host controller to allocate any of its needed structures.
  1353. //
  1354. Status = CreateTransfer(HostControllerContext,
  1355. Endpoint->HostControllerContext,
  1356. MaxTransferSize,
  1357. Flags,
  1358. &(Transfer->HostControllerContext));
  1359. if (!KSUCCESS(Status)) {
  1360. goto AllocateTransferEnd;
  1361. }
  1362. //
  1363. // Now that the transfer is successfully created, mark it as inactive and
  1364. // add it to the USB device's list of transfers.
  1365. //
  1366. Transfer->State = TransferInactive;
  1367. INSERT_BEFORE(&(Transfer->DeviceListEntry), &(Device->TransferList));
  1368. KeReleaseQueuedLock(Device->Lock);
  1369. ReleaseLock = FALSE;
  1370. TransferCreated = TRUE;
  1371. Status = STATUS_SUCCESS;
  1372. AllocateTransferEnd:
  1373. if (!KSUCCESS(Status)) {
  1374. if (Transfer != NULL) {
  1375. if (TransferCreated != FALSE) {
  1376. DestroyTransfer(HostControllerContext,
  1377. Endpoint->HostControllerContext,
  1378. Transfer->HostControllerContext);
  1379. }
  1380. if (Transfer->Event != NULL) {
  1381. KeDestroyEvent(Transfer->Event);
  1382. }
  1383. MmFreeNonPagedPool(Transfer);
  1384. Transfer = NULL;
  1385. }
  1386. if (ReleaseLock != FALSE) {
  1387. KeReleaseQueuedLock(Device->Lock);
  1388. }
  1389. UsbpDeviceReleaseReference(Device);
  1390. }
  1391. return (PUSB_TRANSFER)Transfer;
  1392. }
  1393. VOID
  1394. UsbpCancelAllTransfers (
  1395. PUSB_DEVICE Device
  1396. )
  1397. /*++
  1398. Routine Description:
  1399. This routine cancels all transfers for the given USB core device. The
  1400. device must be disconnected before calling into this routine.
  1401. Arguments:
  1402. Device - Supplies the core handle to the device whose transfers are
  1403. to be cancelled.
  1404. Return Value:
  1405. None.
  1406. --*/
  1407. {
  1408. PLIST_ENTRY CurrentEntry;
  1409. PUSB_TRANSFER_PRIVATE Transfer;
  1410. ASSERT(Device != NULL);
  1411. ASSERT(Device->Connected == FALSE);
  1412. ASSERT(KeGetRunLevel() == RunLevelLow);
  1413. //
  1414. // Loop through the transfers and add a reference to each. This way the
  1415. // device lock does not need to be held while going through the cancel
  1416. // process, potentially impeding a transfer's ability to fail resubmission.
  1417. //
  1418. KeAcquireQueuedLock(Device->Lock);
  1419. CurrentEntry = Device->TransferList.Next;
  1420. while (CurrentEntry != &(Device->TransferList)) {
  1421. Transfer = (PUSB_TRANSFER_PRIVATE)LIST_VALUE(CurrentEntry,
  1422. USB_TRANSFER_PRIVATE,
  1423. DeviceListEntry);
  1424. UsbTransferAddReference((PUSB_TRANSFER)Transfer);
  1425. CurrentEntry = CurrentEntry->Next;
  1426. }
  1427. //
  1428. // Release the lock. It is safe to proceed outside the lock because a
  1429. // reference has been added to each transfer to prevent deletion and
  1430. // because the device has been disconnected, preventing insertion.
  1431. //
  1432. KeReleaseQueuedLock(Device->Lock);
  1433. //
  1434. // Loop through the transfers again and cancel them all.
  1435. //
  1436. CurrentEntry = Device->TransferList.Next;
  1437. while (CurrentEntry != &(Device->TransferList)) {
  1438. Transfer = (PUSB_TRANSFER_PRIVATE)LIST_VALUE(CurrentEntry,
  1439. USB_TRANSFER_PRIVATE,
  1440. DeviceListEntry);
  1441. UsbpCancelTransfer(Transfer);
  1442. CurrentEntry = CurrentEntry->Next;
  1443. }
  1444. //
  1445. // Now wait on all transfers to enter the inactive state.
  1446. //
  1447. CurrentEntry = Device->TransferList.Next;
  1448. while (CurrentEntry != &(Device->TransferList)) {
  1449. Transfer = (PUSB_TRANSFER_PRIVATE)LIST_VALUE(CurrentEntry,
  1450. USB_TRANSFER_PRIVATE,
  1451. DeviceListEntry);
  1452. while (Transfer->State != TransferInactive) {
  1453. KeYield();
  1454. }
  1455. CurrentEntry = CurrentEntry->Next;
  1456. }
  1457. //
  1458. // Loop one last time, releasing the references. Be aware that this could
  1459. // be the last reference on some transfers, meaning the lock cannot be
  1460. // held because the release could trigger deletion.
  1461. //
  1462. CurrentEntry = Device->TransferList.Next;
  1463. while (CurrentEntry != &(Device->TransferList)) {
  1464. Transfer = (PUSB_TRANSFER_PRIVATE)LIST_VALUE(CurrentEntry,
  1465. USB_TRANSFER_PRIVATE,
  1466. DeviceListEntry);
  1467. CurrentEntry = CurrentEntry->Next;
  1468. UsbTransferReleaseReference((PUSB_TRANSFER)Transfer);
  1469. }
  1470. return;
  1471. }
  1472. KSTATUS
  1473. UsbpReadConfigurationDescriptors (
  1474. PUSB_DEVICE Device,
  1475. PUSB_DEVICE_DESCRIPTOR DeviceDescriptor
  1476. )
  1477. /*++
  1478. Routine Description:
  1479. This routine attempts to read all configuration descriptors from the device.
  1480. Arguments:
  1481. Device - Supplies a pointer to the device to query.
  1482. DeviceDescriptor - Supplies a pointer to the device descriptor.
  1483. Return Value:
  1484. Status code.
  1485. --*/
  1486. {
  1487. PUSB_CONFIGURATION Configuration;
  1488. UCHAR ConfigurationCount;
  1489. UCHAR ConfigurationIndex;
  1490. KSTATUS OverallStatus;
  1491. KSTATUS Status;
  1492. OverallStatus = STATUS_SUCCESS;
  1493. ConfigurationCount = DeviceDescriptor->ConfigurationCount;
  1494. for (ConfigurationIndex = 0;
  1495. ConfigurationIndex < ConfigurationCount;
  1496. ConfigurationIndex += 1) {
  1497. Status = UsbpGetConfiguration(Device,
  1498. ConfigurationIndex,
  1499. TRUE,
  1500. &Configuration);
  1501. if (!KSUCCESS(Status)) {
  1502. OverallStatus = Status;
  1503. }
  1504. }
  1505. return OverallStatus;
  1506. }
  1507. USB_API
  1508. PVOID
  1509. UsbGetDeviceToken (
  1510. PUSB_DEVICE Device
  1511. )
  1512. /*++
  1513. Routine Description:
  1514. This routine returns the system device token associated with the given USB
  1515. device.
  1516. Arguments:
  1517. Device - Supplies a pointer to a USB device.
  1518. Return Value:
  1519. Returns a system device token.
  1520. --*/
  1521. {
  1522. return Device->Device;
  1523. }
  1524. KSTATUS
  1525. UsbpInitializeTransferCompletionQueue (
  1526. PUSB_TRANSFER_COMPLETION_QUEUE CompletionQueue,
  1527. BOOL PrivateWorkQueue
  1528. )
  1529. /*++
  1530. Routine Description:
  1531. This routine initializes the given transfer completion queue.
  1532. Arguments:
  1533. CompletionQueue - Supplies a pointer to a USB transfer completion queue
  1534. that is to be initialized.
  1535. PrivateWorkQueue - Supplies a boolean indicating whether or not the
  1536. completion queue requires a private work queue for queuing its work
  1537. item.
  1538. Return Value:
  1539. Status code.
  1540. --*/
  1541. {
  1542. KSTATUS Status;
  1543. ULONG WorkQueueFlags;
  1544. RtlZeroMemory(CompletionQueue, sizeof(USB_TRANSFER_COMPLETION_QUEUE));
  1545. INITIALIZE_LIST_HEAD(&(CompletionQueue->CompletedTransfersList));
  1546. KeInitializeSpinLock(&(CompletionQueue->CompletedTransfersListLock));
  1547. if (PrivateWorkQueue != FALSE) {
  1548. WorkQueueFlags = WORK_QUEUE_FLAG_SUPPORT_DISPATCH_LEVEL;
  1549. CompletionQueue->WorkQueue = KeCreateWorkQueue(WorkQueueFlags,
  1550. "UsbCorePrivateWorker");
  1551. if (CompletionQueue->WorkQueue == NULL) {
  1552. Status = STATUS_INSUFFICIENT_RESOURCES;
  1553. goto InitializeTransferCompletionQueueEnd;
  1554. }
  1555. } else {
  1556. CompletionQueue->WorkQueue = UsbCoreWorkQueue;
  1557. }
  1558. ASSERT(CompletionQueue->WorkQueue != NULL);
  1559. CompletionQueue->WorkItem = KeCreateWorkItem(CompletionQueue->WorkQueue,
  1560. WorkPriorityNormal,
  1561. UsbpCompletedTransferWorker,
  1562. CompletionQueue,
  1563. USB_CORE_ALLOCATION_TAG);
  1564. if (CompletionQueue->WorkItem == NULL) {
  1565. Status = STATUS_INSUFFICIENT_RESOURCES;
  1566. goto InitializeTransferCompletionQueueEnd;
  1567. }
  1568. Status = STATUS_SUCCESS;
  1569. InitializeTransferCompletionQueueEnd:
  1570. if (!KSUCCESS(Status)) {
  1571. UsbpDestroyTransferCompletionQueue(CompletionQueue);
  1572. }
  1573. return Status;
  1574. }
  1575. VOID
  1576. UsbpDestroyTransferCompletionQueue (
  1577. PUSB_TRANSFER_COMPLETION_QUEUE CompletionQueue
  1578. )
  1579. /*++
  1580. Routine Description:
  1581. This routine destroys the given transfer completion queue. It does not
  1582. release the completion queue's memory.
  1583. Arguments:
  1584. CompletionQueue - Supplies a pointer to a USB transfer completion queue
  1585. that is to be destroyed.
  1586. Return Value:
  1587. Status code.
  1588. --*/
  1589. {
  1590. if (CompletionQueue->WorkItem != NULL) {
  1591. KeDestroyWorkItem(CompletionQueue->WorkItem);
  1592. }
  1593. if ((CompletionQueue->WorkQueue != NULL) &&
  1594. (CompletionQueue->WorkQueue != UsbCoreWorkQueue)) {
  1595. KeDestroyWorkQueue(CompletionQueue->WorkQueue);
  1596. }
  1597. return;
  1598. }
  1599. VOID
  1600. UsbpProcessCompletedTransfer (
  1601. PUSB_TRANSFER_INTERNAL Transfer
  1602. )
  1603. /*++
  1604. Routine Description:
  1605. This routine processes the completed transfer. It will either signal
  1606. synchronous transfers or queue asynchronous transfers on the correct
  1607. transfer completion queue so that its callback routine can be completed at
  1608. low level. This routine is called at dispatch.
  1609. Arguments:
  1610. Transfer - Supplies a pointer to a completed transfer.
  1611. Return Value:
  1612. None.
  1613. --*/
  1614. {
  1615. PUSB_TRANSFER_PRIVATE CompleteTransfer;
  1616. PUSB_TRANSFER_COMPLETION_QUEUE CompletionQueue;
  1617. PUSB_HOST_CONTROLLER Controller;
  1618. ULONG FlushAlignment;
  1619. ULONG FlushLength;
  1620. RUNLEVEL OldRunLevel;
  1621. USB_TRANSFER_STATE OldState;
  1622. ULONG PrivateFlags;
  1623. BOOL QueueWorkItem;
  1624. KSTATUS Status;
  1625. CompleteTransfer = (PUSB_TRANSFER_PRIVATE)Transfer;
  1626. ASSERT(KeGetRunLevel() == RunLevelDispatch);
  1627. ASSERT(CompleteTransfer->CompletionListEntry.Next == NULL);
  1628. //
  1629. // For any transfer that read data (i.e. all but the out transfers),
  1630. // invalidate the data cache again so that the consumer reads the correct
  1631. // data.
  1632. //
  1633. if (Transfer->Public.Direction != UsbTransferDirectionOut) {
  1634. ASSERT((Transfer->Public.Direction == UsbTransferDirectionIn) ||
  1635. (Transfer->Public.Direction == UsbTransferBidirectional));
  1636. FlushAlignment = MmGetIoBufferAlignment();
  1637. ASSERT(POWER_OF_2(FlushAlignment) != FALSE);
  1638. FlushLength = ALIGN_RANGE_UP(Transfer->Public.LengthTransferred,
  1639. FlushAlignment);
  1640. MmFlushBufferForDataIn(Transfer->Public.Buffer, FlushLength);
  1641. }
  1642. //
  1643. // For synchronous transfers, fire the event.
  1644. //
  1645. PrivateFlags = CompleteTransfer->PrivateFlags;
  1646. if ((PrivateFlags & USB_TRANSFER_PRIVATE_SYNCHRONOUS) != 0) {
  1647. //
  1648. // Mark that the transfer is no longer in flight.
  1649. //
  1650. OldState = RtlAtomicCompareExchange32(&(CompleteTransfer->State),
  1651. TransferInactive,
  1652. TransferActive);
  1653. ASSERT(OldState == TransferActive);
  1654. KeSignalEvent(CompleteTransfer->Event, SignalOptionSignalAll);
  1655. //
  1656. // USB core is done with this transfer, so release the reference taken
  1657. // on submit.
  1658. //
  1659. UsbTransferReleaseReference((PUSB_TRANSFER)Transfer);
  1660. //
  1661. // Queue all non-synchronous transfers to handle the callback at low-level.
  1662. //
  1663. } else {
  1664. //
  1665. // If this is a paging device transfer, then use the paging device
  1666. // completion queue.
  1667. //
  1668. if ((Transfer->Public.Flags & USB_TRANSFER_FLAG_PAGING_DEVICE) != 0) {
  1669. ASSERT(UsbCorePagingCompletionQueue != NULL);
  1670. CompletionQueue = UsbCorePagingCompletionQueue;
  1671. //
  1672. // Otherwise use the controller's completion queue.
  1673. //
  1674. } else {
  1675. Controller = CompleteTransfer->Device->Controller;
  1676. CompletionQueue = &(Controller->TransferCompletionQueue);
  1677. }
  1678. //
  1679. // Add the transfer to the completion list and potentially queue the
  1680. // work item to empty the list.
  1681. //
  1682. OldRunLevel = UsbpAcquireCompletedTransfersLock(CompletionQueue);
  1683. //
  1684. // If the list is currently empty, then the work item needs to be
  1685. // queued to process this new insertion.
  1686. //
  1687. if (LIST_EMPTY(&(CompletionQueue->CompletedTransfersList)) != FALSE) {
  1688. QueueWorkItem = TRUE;
  1689. //
  1690. // If it is not empty, then the work item is already queued and the
  1691. // insertion below will be picked up.
  1692. //
  1693. } else {
  1694. QueueWorkItem = FALSE;
  1695. }
  1696. INSERT_BEFORE(&(CompleteTransfer->CompletionListEntry),
  1697. &(CompletionQueue->CompletedTransfersList));
  1698. if (QueueWorkItem != FALSE) {
  1699. Status = KeQueueWorkItem(CompletionQueue->WorkItem);
  1700. ASSERT(KSUCCESS(Status));
  1701. }
  1702. UsbpReleaseCompletedTransfersLock(CompletionQueue, OldRunLevel);
  1703. }
  1704. return;
  1705. }
  1706. USB_API
  1707. BOOL
  1708. UsbIsPolledIoSupported (
  1709. HANDLE UsbDeviceHandle
  1710. )
  1711. /*++
  1712. Routine Description:
  1713. This routine returns a boolean indicating whether or not the given USB
  1714. device's controller supports polled I/O mode. Polled I/O should only be
  1715. used in dire circumstances. That is, during system failure when a crash
  1716. dump file needs to be written over USB Mass Storage at high run level with
  1717. interrupts disabled.
  1718. Arguments:
  1719. UsbDeviceHandle - Supplies the handle returned when the device was opened.
  1720. Return Value:
  1721. Returns a boolean indicating if polled I/O is supported (TRUE) or not
  1722. (FALSE).
  1723. --*/
  1724. {
  1725. PUSB_DEVICE Device;
  1726. Device = (PUSB_DEVICE)UsbDeviceHandle;
  1727. if (Device->Controller->Device.SubmitPolledTransfer != NULL) {
  1728. return TRUE;
  1729. }
  1730. return FALSE;
  1731. }
  1732. USB_API
  1733. KSTATUS
  1734. UsbResetEndpoint (
  1735. HANDLE UsbDeviceHandle,
  1736. UCHAR EndpointNumber
  1737. )
  1738. /*++
  1739. Routine Description:
  1740. This routine resets the given endpoint for the given USB device. This
  1741. includes resetting the data toggle to DATA 0.
  1742. Arguments:
  1743. UsbDeviceHandle - Supplies the handle returned when the device was opened.
  1744. EndpointNumber - Supplies the number of the endpoint to be reset.
  1745. Return Value:
  1746. Status code.
  1747. --*/
  1748. {
  1749. PUSB_DEVICE Device;
  1750. PUSB_ENDPOINT Endpoint;
  1751. KSTATUS Status;
  1752. Device = (PUSB_DEVICE)UsbDeviceHandle;
  1753. Endpoint = UsbpGetDeviceEndpoint(Device, EndpointNumber);
  1754. if (Endpoint == NULL) {
  1755. Status = STATUS_INVALID_PARAMETER;
  1756. goto ResetEndpointEnd;
  1757. }
  1758. UsbpResetEndpoint(Device, Endpoint);
  1759. Status = STATUS_SUCCESS;
  1760. ResetEndpointEnd:
  1761. return Status;
  1762. }
  1763. USB_API
  1764. KSTATUS
  1765. UsbFlushEndpoint (
  1766. HANDLE UsbDeviceHandle,
  1767. UCHAR EndpointNumber,
  1768. PULONG TransferCount
  1769. )
  1770. /*++
  1771. Routine Description:
  1772. This routine flushes the given endpoint for the given USB device. This
  1773. includes busily waiting for all active transfers to complete. This is only
  1774. meant to be used at high run level when preparing to write a crash dump
  1775. file using USB Mass Storage.
  1776. Arguments:
  1777. UsbDeviceHandle - Supplies the handle returned when the device was opened.
  1778. EndpointNumber - Supplies the number of the endpoint to be reset.
  1779. TransferCount - Supplies a pointer that receives the total number of
  1780. transfers that were flushed.
  1781. Return Value:
  1782. Status code.
  1783. --*/
  1784. {
  1785. PUSB_DEVICE Device;
  1786. PUSB_ENDPOINT Endpoint;
  1787. KSTATUS Status;
  1788. ASSERT(KeGetRunLevel() == RunLevelHigh);
  1789. Device = (PUSB_DEVICE)UsbDeviceHandle;
  1790. Endpoint = UsbpGetDeviceEndpoint(Device, EndpointNumber);
  1791. if (Endpoint == NULL) {
  1792. Status = STATUS_INVALID_PARAMETER;
  1793. goto FlushEndpointEnd;
  1794. }
  1795. Status = UsbpFlushEndpoint(Device, Endpoint, TransferCount);
  1796. if (!KSUCCESS(Status)) {
  1797. goto FlushEndpointEnd;
  1798. }
  1799. FlushEndpointEnd:
  1800. return Status;
  1801. }
  1802. //
  1803. // --------------------------------------------------------- Internal Functions
  1804. //
  1805. KSTATUS
  1806. UsbpCancelTransfer (
  1807. PUSB_TRANSFER_PRIVATE Transfer
  1808. )
  1809. /*++
  1810. Routine Description:
  1811. This routine cancels a USB transfer.
  1812. Arguments:
  1813. Transfer - Supplies a pointer to the transfer to cancel.
  1814. Return Value:
  1815. Status code.
  1816. --*/
  1817. {
  1818. PUSB_HOST_CANCEL_TRANSFER CancelTransfer;
  1819. PUSB_HOST_CONTROLLER Controller;
  1820. PUSB_ENDPOINT Endpoint;
  1821. KSTATUS Status;
  1822. Endpoint = Transfer->Endpoint;
  1823. Controller = Transfer->Device->Controller;
  1824. CancelTransfer = Controller->Device.CancelTransfer;
  1825. //
  1826. // Try to cancel the transfer. This only makes an attempt at cancelling
  1827. // the transfer and does not guarantee success or that the transfer is
  1828. // out of USB core's domain. The caller needs to handle the various failure
  1829. // cases. If the transfer is currently inactive, just return that the
  1830. // cancel is too early.
  1831. //
  1832. if (Transfer->State == TransferInactive) {
  1833. Status = STATUS_TOO_EARLY;
  1834. } else {
  1835. Status = CancelTransfer(Controller->Device.HostControllerContext,
  1836. Endpoint->HostControllerContext,
  1837. (PUSB_TRANSFER_INTERNAL)Transfer,
  1838. Transfer->HostControllerContext);
  1839. if (!KSUCCESS(Status)) {
  1840. ASSERT(Status == STATUS_TOO_LATE);
  1841. }
  1842. }
  1843. return Status;
  1844. }
  1845. VOID
  1846. UsbpDestroyTransfer (
  1847. PUSB_TRANSFER Transfer
  1848. )
  1849. /*++
  1850. Routine Description:
  1851. This routine destroys an allocated transfer. This transfer must not be
  1852. actively transferring.
  1853. Arguments:
  1854. Transfer - Supplies a pointer to the transfer to destroy.
  1855. Return Value:
  1856. None.
  1857. --*/
  1858. {
  1859. PUSB_TRANSFER_PRIVATE CompleteTransfer;
  1860. PUSB_HOST_DESTROY_TRANSFER DestroyTransfer;
  1861. PUSB_HOST_CONTROLLER HostController;
  1862. PVOID HostControllerContext;
  1863. CompleteTransfer = (PUSB_TRANSFER_PRIVATE)Transfer;
  1864. ASSERT(CompleteTransfer->CompletionListEntry.Next == NULL);
  1865. ASSERT(CompleteTransfer->Magic == USB_TRANSFER_INTERNAL_MAGIC);
  1866. ASSERT(CompleteTransfer->State == TransferInactive);
  1867. //
  1868. // Remove the transfer from its USB device's list of transfers.
  1869. //
  1870. KeAcquireQueuedLock(CompleteTransfer->Device->Lock);
  1871. LIST_REMOVE(&(CompleteTransfer->DeviceListEntry));
  1872. KeReleaseQueuedLock(CompleteTransfer->Device->Lock);
  1873. //
  1874. // Call the host controller to destroy the transfer.
  1875. //
  1876. HostController = CompleteTransfer->Device->Controller;
  1877. DestroyTransfer = HostController->Device.DestroyTransfer;
  1878. HostControllerContext = HostController->Device.HostControllerContext;
  1879. DestroyTransfer(HostControllerContext,
  1880. CompleteTransfer->Endpoint->HostControllerContext,
  1881. CompleteTransfer->HostControllerContext);
  1882. KeDestroyEvent(CompleteTransfer->Event);
  1883. //
  1884. // Releae the reference the transfer took on the device.
  1885. //
  1886. UsbpDeviceReleaseReference(CompleteTransfer->Device);
  1887. //
  1888. // Destroy the transfer itself.
  1889. //
  1890. MmFreeNonPagedPool(CompleteTransfer);
  1891. return;
  1892. }
  1893. KSTATUS
  1894. UsbpGetConfiguration (
  1895. PUSB_DEVICE Device,
  1896. UCHAR ConfigurationNumber,
  1897. BOOL NumberIsIndex,
  1898. PUSB_CONFIGURATION *Configuration
  1899. )
  1900. /*++
  1901. Routine Description:
  1902. This routine gets a configuration out of the given device. This routine
  1903. will send a blocking request to the device. This routine must be called at
  1904. low level.
  1905. Arguments:
  1906. Device - Supplies a pointer to the device.
  1907. ConfigurationNumber - Supplies the index or configuration value of the
  1908. configuration to get.
  1909. NumberIsIndex - Supplies a boolean indicating whether the configuration
  1910. number is an index (TRUE) or a specific configuration value (FALSE).
  1911. Configuration - Supplies a pointer where a pointer to the created
  1912. configuration will be returned.
  1913. Return Value:
  1914. Status code.
  1915. --*/
  1916. {
  1917. ULONG AllocationSize;
  1918. PUCHAR BufferPointer;
  1919. PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor;
  1920. UCHAR ConfigurationValue;
  1921. PUSB_CONFIGURATION CurrentConfiguration;
  1922. PLIST_ENTRY CurrentEntry;
  1923. PUSB_INTERFACE CurrentInterface;
  1924. PUSB_CONFIGURATION_DESCRIPTION Description;
  1925. UCHAR DescriptorLength;
  1926. UCHAR DescriptorType;
  1927. PUSB_ENDPOINT_DESCRIPTION Endpoint;
  1928. ULONG EndpointCount;
  1929. ULONG InterfaceCount;
  1930. ULONG Length;
  1931. ULONG LengthTransferred;
  1932. PUCHAR NewBufferPointer;
  1933. USB_SETUP_PACKET SetupPacket;
  1934. KSTATUS Status;
  1935. USHORT TotalLength;
  1936. *Configuration = NULL;
  1937. ConfigurationDescriptor = NULL;
  1938. CurrentConfiguration = NULL;
  1939. ASSERT(KeGetRunLevel() == RunLevelLow);
  1940. KeAcquireQueuedLock(Device->ConfigurationLock);
  1941. //
  1942. // First look to see if the configuration already exists.
  1943. //
  1944. CurrentEntry = Device->ConfigurationList.Next;
  1945. while (CurrentEntry != &(Device->ConfigurationList)) {
  1946. CurrentConfiguration = LIST_VALUE(CurrentEntry,
  1947. USB_CONFIGURATION,
  1948. ListEntry);
  1949. //
  1950. // Match on either the index or the value.
  1951. //
  1952. Description = &(CurrentConfiguration->Description);
  1953. if (NumberIsIndex != FALSE) {
  1954. if (ConfigurationNumber == Description->Index) {
  1955. break;
  1956. }
  1957. } else {
  1958. ConfigurationValue = Description->Descriptor.ConfigurationValue;
  1959. if (ConfigurationNumber == ConfigurationValue) {
  1960. break;
  1961. }
  1962. }
  1963. CurrentEntry = CurrentEntry->Next;
  1964. }
  1965. if (CurrentEntry != &(Device->ConfigurationList)) {
  1966. Status = STATUS_SUCCESS;
  1967. goto GetConfigurationEnd;
  1968. }
  1969. CurrentConfiguration = NULL;
  1970. //
  1971. // The USB spec does not support requesting descriptors by value, so this
  1972. // had better be a "by-index" request.
  1973. //
  1974. ASSERT(NumberIsIndex != FALSE);
  1975. //
  1976. // Allocate space for the entire descriptor, which includes all of the
  1977. // interface and endpoint descriptors (hopefully).
  1978. //
  1979. ConfigurationDescriptor = MmAllocatePagedPool(
  1980. USB_INITIAL_CONFIGURATION_LENGTH,
  1981. USB_CORE_ALLOCATION_TAG);
  1982. if (ConfigurationDescriptor == NULL) {
  1983. Status = STATUS_INSUFFICIENT_RESOURCES;
  1984. goto GetConfigurationEnd;
  1985. }
  1986. //
  1987. // Read in the configuration descriptor.
  1988. //
  1989. RtlZeroMemory(&SetupPacket, sizeof(USB_SETUP_PACKET));
  1990. SetupPacket.RequestType = USB_SETUP_REQUEST_TO_HOST |
  1991. USB_SETUP_REQUEST_STANDARD |
  1992. USB_SETUP_REQUEST_DEVICE_RECIPIENT;
  1993. SetupPacket.Request = USB_DEVICE_REQUEST_GET_DESCRIPTOR;
  1994. SetupPacket.Value = (UsbDescriptorTypeConfiguration << 8) |
  1995. ConfigurationNumber;
  1996. SetupPacket.Index = 0;
  1997. SetupPacket.Length = USB_INITIAL_CONFIGURATION_LENGTH;
  1998. Status = UsbSendControlTransfer(Device,
  1999. UsbTransferDirectionIn,
  2000. &SetupPacket,
  2001. ConfigurationDescriptor,
  2002. USB_INITIAL_CONFIGURATION_LENGTH,
  2003. &LengthTransferred);
  2004. if (!KSUCCESS(Status)) {
  2005. goto GetConfigurationEnd;
  2006. }
  2007. if (LengthTransferred < sizeof(USB_CONFIGURATION_DESCRIPTOR)) {
  2008. Status = STATUS_INVALID_CONFIGURATION;
  2009. goto GetConfigurationEnd;
  2010. }
  2011. //
  2012. // If the buffer was too small, allocate a bigger one and read it in again.
  2013. //
  2014. TotalLength = ConfigurationDescriptor->TotalLength;
  2015. if (TotalLength > USB_INITIAL_CONFIGURATION_LENGTH) {
  2016. MmFreePagedPool(ConfigurationDescriptor);
  2017. ConfigurationDescriptor = MmAllocatePagedPool(TotalLength,
  2018. USB_CORE_ALLOCATION_TAG);
  2019. if (ConfigurationDescriptor == NULL) {
  2020. Status = STATUS_INSUFFICIENT_RESOURCES;
  2021. goto GetConfigurationEnd;
  2022. }
  2023. SetupPacket.Length = TotalLength;
  2024. Status = UsbSendControlTransfer(Device,
  2025. UsbTransferDirectionIn,
  2026. &SetupPacket,
  2027. ConfigurationDescriptor,
  2028. TotalLength,
  2029. &LengthTransferred);
  2030. if (!KSUCCESS(Status)) {
  2031. goto GetConfigurationEnd;
  2032. }
  2033. if (LengthTransferred != TotalLength) {
  2034. Status = STATUS_INVALID_CONFIGURATION;
  2035. goto GetConfigurationEnd;
  2036. }
  2037. }
  2038. //
  2039. // Count the number of interfaces and endpoints to determine the allocation
  2040. // size for the description.
  2041. //
  2042. InterfaceCount = 0;
  2043. EndpointCount = 0;
  2044. Length = ConfigurationDescriptor->Length;
  2045. BufferPointer = (PUCHAR)ConfigurationDescriptor +
  2046. ConfigurationDescriptor->Length;
  2047. while (Length + 1 < LengthTransferred) {
  2048. //
  2049. // Get this descriptor and count it.
  2050. //
  2051. DescriptorLength = *BufferPointer;
  2052. DescriptorType = *(BufferPointer + 1);
  2053. if (DescriptorType == UsbDescriptorTypeInterface) {
  2054. InterfaceCount += 1;
  2055. } else if (DescriptorType == UsbDescriptorTypeEndpoint) {
  2056. EndpointCount += 1;
  2057. }
  2058. //
  2059. // Move on to the next descriptor.
  2060. //
  2061. BufferPointer += DescriptorLength;
  2062. Length += DescriptorLength;
  2063. }
  2064. //
  2065. // Now allocate space for the configuration description.
  2066. //
  2067. AllocationSize = sizeof(USB_CONFIGURATION) +
  2068. (InterfaceCount * sizeof(USB_INTERFACE)) +
  2069. (EndpointCount * sizeof(USB_ENDPOINT_DESCRIPTION));
  2070. CurrentConfiguration = MmAllocatePagedPool(AllocationSize,
  2071. USB_CORE_ALLOCATION_TAG);
  2072. if (CurrentConfiguration == NULL) {
  2073. Status = STATUS_INSUFFICIENT_RESOURCES;
  2074. }
  2075. RtlZeroMemory(CurrentConfiguration, AllocationSize);
  2076. CurrentConfiguration->Description.Index = ConfigurationNumber;
  2077. RtlCopyMemory(&(CurrentConfiguration->Description.Descriptor),
  2078. ConfigurationDescriptor,
  2079. sizeof(USB_CONFIGURATION_DESCRIPTOR));
  2080. INITIALIZE_LIST_HEAD(
  2081. &(CurrentConfiguration->Description.InterfaceListHead));
  2082. //
  2083. // Go through the descriptor again and create analogous structures for them.
  2084. //
  2085. CurrentInterface = NULL;
  2086. Length = ConfigurationDescriptor->Length;
  2087. BufferPointer = (PUCHAR)ConfigurationDescriptor +
  2088. ConfigurationDescriptor->Length;
  2089. NewBufferPointer = (PUCHAR)(CurrentConfiguration + 1);
  2090. while (Length + 1 < LengthTransferred) {
  2091. //
  2092. // Get this descriptor and create the analogous structure.
  2093. //
  2094. DescriptorLength = *BufferPointer;
  2095. DescriptorType = *(BufferPointer + 1);
  2096. if (DescriptorType == UsbDescriptorTypeInterface) {
  2097. CurrentInterface = (PUSB_INTERFACE)NewBufferPointer;
  2098. if (DescriptorLength < sizeof(USB_INTERFACE_DESCRIPTOR)) {
  2099. Status = STATUS_INVALID_CONFIGURATION;
  2100. goto GetConfigurationEnd;
  2101. }
  2102. RtlCopyMemory(&(CurrentInterface->Description.Descriptor),
  2103. BufferPointer,
  2104. sizeof(USB_INTERFACE_DESCRIPTOR));
  2105. INITIALIZE_LIST_HEAD(
  2106. &(CurrentInterface->Description.EndpointListHead));
  2107. INITIALIZE_LIST_HEAD(&(CurrentInterface->EndpointList));
  2108. INSERT_BEFORE(
  2109. &(CurrentInterface->Description.ListEntry),
  2110. &(CurrentConfiguration->Description.InterfaceListHead));
  2111. NewBufferPointer = (PUCHAR)(CurrentInterface + 1);
  2112. } else if (DescriptorType == UsbDescriptorTypeEndpoint) {
  2113. //
  2114. // If an endpoint came with no interface, that's illegal.
  2115. //
  2116. if (CurrentInterface == NULL) {
  2117. Status = STATUS_INVALID_CONFIGURATION;
  2118. goto GetConfigurationEnd;
  2119. }
  2120. Endpoint = (PUSB_ENDPOINT_DESCRIPTION)NewBufferPointer;
  2121. if (DescriptorLength < sizeof(USB_ENDPOINT_DESCRIPTOR)) {
  2122. Status = STATUS_INVALID_CONFIGURATION;
  2123. goto GetConfigurationEnd;
  2124. }
  2125. RtlCopyMemory(&(Endpoint->Descriptor),
  2126. BufferPointer,
  2127. sizeof(USB_ENDPOINT_DESCRIPTOR));
  2128. INSERT_BEFORE(&(Endpoint->ListEntry),
  2129. &(CurrentInterface->Description.EndpointListHead));
  2130. NewBufferPointer = (PUCHAR)(Endpoint + 1);
  2131. }
  2132. //
  2133. // Move on to the next descriptor.
  2134. //
  2135. BufferPointer += DescriptorLength;
  2136. Length += DescriptorLength;
  2137. }
  2138. ASSERT((UINTN)NewBufferPointer - (UINTN)CurrentConfiguration ==
  2139. AllocationSize);
  2140. //
  2141. // Insert the new configuration onto the global list to cache it for
  2142. // future calls.
  2143. //
  2144. INSERT_BEFORE(&(CurrentConfiguration->ListEntry),
  2145. &(Device->ConfigurationList));
  2146. GetConfigurationEnd:
  2147. KeReleaseQueuedLock(Device->ConfigurationLock);
  2148. if (!KSUCCESS(Status)) {
  2149. if (CurrentConfiguration != NULL) {
  2150. MmFreePagedPool(CurrentConfiguration);
  2151. CurrentConfiguration = NULL;
  2152. }
  2153. }
  2154. if (ConfigurationDescriptor != NULL) {
  2155. MmFreePagedPool(ConfigurationDescriptor);
  2156. }
  2157. *Configuration = CurrentConfiguration;
  2158. return Status;
  2159. }
  2160. KSTATUS
  2161. UsbpSubmitTransfer (
  2162. PUSB_TRANSFER Transfer,
  2163. ULONG PrivateFlags,
  2164. BOOL PolledMode
  2165. )
  2166. /*++
  2167. Routine Description:
  2168. This routine submits a USB transfer. The routine returns immediately,
  2169. indicating only whether the transfer was submitted successfully. When the
  2170. transfer actually completes, the callback routine will be called.
  2171. Arguments:
  2172. Transfer - Supplies a pointer to the transfer to destroy.
  2173. PrivateFlags - Supplies an optional bitfield of private flags regarding the
  2174. transfer. See USB_TRANSFER_PRIVATE_* definitions.
  2175. PolledMode - Supplies a boolean indicating whether the I/O should be done
  2176. in polled mode or not. This is reserved for I/O paths after a critical
  2177. system error.
  2178. Return Value:
  2179. STATUS_SUCCESS if the transfer was submitted to the USB host controller's
  2180. queue.
  2181. STATUS_INVALID_PARAMETER if one or more of the transfer fields is not
  2182. properly filled out.
  2183. Failing status codes if the request could not be submitted.
  2184. --*/
  2185. {
  2186. PUSB_TRANSFER_PRIVATE CompleteTransfer;
  2187. PUSB_HOST_CONTROLLER Controller;
  2188. PUSB_DEVICE Device;
  2189. PUSB_ENDPOINT Endpoint;
  2190. ULONG FlushAlignment;
  2191. ULONG FlushLength;
  2192. USB_TRANSFER_STATE OriginalState;
  2193. BOOL PacketQueued;
  2194. BOOL ReleaseDeviceLock;
  2195. PUSB_SETUP_PACKET Setup;
  2196. KSTATUS Status;
  2197. PUSB_HOST_SUBMIT_TRANSFER SubmitTransfer;
  2198. ASSERT(Transfer != NULL);
  2199. CompleteTransfer = (PUSB_TRANSFER_PRIVATE)Transfer;
  2200. Endpoint = CompleteTransfer->Endpoint;
  2201. Controller = CompleteTransfer->Device->Controller;
  2202. Device = (PUSB_DEVICE)CompleteTransfer->Device;
  2203. PacketQueued = FALSE;
  2204. ReleaseDeviceLock = FALSE;
  2205. //
  2206. // Reference the transfer.
  2207. //
  2208. UsbTransferAddReference(Transfer);
  2209. //
  2210. // Callers are not allowed to allocate their own transfer structures, nor
  2211. // are they allowed to resubmit packets that have not completed.
  2212. //
  2213. if (CompleteTransfer->Magic != USB_TRANSFER_INTERNAL_MAGIC) {
  2214. ASSERT(FALSE);
  2215. Transfer->Error = UsbErrorTransferAllocatedIncorrectly;
  2216. Status = STATUS_INVALID_PARAMETER;
  2217. goto SubmitTransferEnd;
  2218. }
  2219. //
  2220. // Also fail if a transfer is submitted while it is still in-flight. It
  2221. // should either be inactive or in the middle of the callback.
  2222. //
  2223. if (CompleteTransfer->State == TransferActive) {
  2224. ASSERT(FALSE);
  2225. Transfer->Error = UsbErrorTransferSubmittedWhileStillActive;
  2226. Status = STATUS_RESOURCE_IN_USE;
  2227. goto SubmitTransferEnd;
  2228. }
  2229. ASSERT(CompleteTransfer->CompletionListEntry.Next == NULL);
  2230. //
  2231. // Validate the transfer.
  2232. //
  2233. if ((Transfer->Length == 0) ||
  2234. (Transfer->Length > CompleteTransfer->MaxTransferSize) ||
  2235. (Transfer->Buffer == NULL) ||
  2236. (Transfer->BufferPhysicalAddress == INVALID_PHYSICAL_ADDRESS) ||
  2237. (Transfer->BufferActualLength < Transfer->Length) ||
  2238. ((Transfer->Direction != UsbTransferDirectionIn) &&
  2239. (Transfer->Direction != UsbTransferDirectionOut))) {
  2240. ASSERT(FALSE);
  2241. Transfer->Error = UsbErrorTransferIncorrectlyFilledOut;
  2242. Status = STATUS_INVALID_PARAMETER;
  2243. goto SubmitTransferEnd;
  2244. }
  2245. if ((PrivateFlags & USB_TRANSFER_PRIVATE_SYNCHRONOUS) != 0) {
  2246. CompleteTransfer->PrivateFlags |= USB_TRANSFER_PRIVATE_SYNCHRONOUS;
  2247. } else {
  2248. CompleteTransfer->PrivateFlags &= ~USB_TRANSFER_PRIVATE_SYNCHRONOUS;
  2249. if (Transfer->CallbackRoutine == NULL) {
  2250. Transfer->Error = UsbErrorTransferIncorrectlyFilledOut;
  2251. Status = STATUS_INVALID_PARAMETER;
  2252. goto SubmitTransferEnd;
  2253. }
  2254. }
  2255. Transfer->Status = STATUS_NOT_STARTED;
  2256. Transfer->Error = UsbErrorTransferNotStarted;
  2257. Transfer->LengthTransferred = 0;
  2258. if (PolledMode == FALSE) {
  2259. SubmitTransfer = Controller->Device.SubmitTransfer;
  2260. ASSERT(SubmitTransfer != NULL);
  2261. } else {
  2262. SubmitTransfer = Controller->Device.SubmitPolledTransfer;
  2263. if (SubmitTransfer == NULL) {
  2264. Status = STATUS_NOT_SUPPORTED;
  2265. goto SubmitTransferEnd;
  2266. }
  2267. }
  2268. //
  2269. // Clean the data buffer in preparation for the USB controller doing DMA
  2270. // to/from it. Control transfers always have an outgoing portion.
  2271. //
  2272. FlushAlignment = MmGetIoBufferAlignment();
  2273. ASSERT(POWER_OF_2(FlushAlignment) != FALSE);
  2274. FlushLength = ALIGN_RANGE_UP(Transfer->Length, FlushAlignment);
  2275. if ((ALIGN_RANGE_DOWN((UINTN)Transfer->Buffer, FlushAlignment) !=
  2276. (UINTN)Transfer->Buffer) ||
  2277. (FlushLength > Transfer->BufferActualLength)) {
  2278. ASSERT(FALSE);
  2279. Transfer->Error = UsbErrorTransferBufferNotAligned;
  2280. Status = STATUS_INVALID_PARAMETER;
  2281. Transfer->Status = Status;
  2282. goto SubmitTransferEnd;
  2283. }
  2284. //
  2285. // Print out any debug information. The transfer isn't guaranteed to be
  2286. // submitted after this point, but this touches the transfer buffer, which
  2287. // needs to be flushed and then not touched.
  2288. //
  2289. if ((UsbDebugFlags & USB_DEBUG_TRANSFERS) != 0) {
  2290. if ((UsbDebugDeviceAddress == 0) ||
  2291. (UsbDebugDeviceAddress ==
  2292. CompleteTransfer->Protected.DeviceAddress)) {
  2293. ASSERT(Transfer->Direction < UsbTransferDirectionCount);
  2294. ASSERT(CompleteTransfer->Protected.Type < UsbTransferTypeCount);
  2295. RtlDebugPrint(
  2296. "USB: Transfer (0x%08x) %s dev %x, EP%x, %s, "
  2297. "Buffer %x, Length 0x%x\n",
  2298. Transfer,
  2299. UsbTransferDirectionStrings[Transfer->Direction],
  2300. CompleteTransfer->Protected.DeviceAddress,
  2301. CompleteTransfer->Protected.EndpointNumber,
  2302. UsbTransferTypeStrings[CompleteTransfer->Protected.Type],
  2303. Transfer->Buffer,
  2304. Transfer->Length);
  2305. if (CompleteTransfer->Protected.Type == UsbTransferTypeControl) {
  2306. ASSERT(Transfer->Length >= sizeof(USB_SETUP_PACKET));
  2307. Setup = Transfer->Buffer;
  2308. RtlDebugPrint("USB: RequestType 0x%x, Request 0x%x, "
  2309. "Value 0x%x, Index 0x%x, Length 0x%x\n",
  2310. Setup->RequestType,
  2311. Setup->Request,
  2312. Setup->Value,
  2313. Setup->Index,
  2314. Setup->Length);
  2315. }
  2316. }
  2317. }
  2318. //
  2319. // Flush the transfer buffer. Do not access the buffer beyond this point.
  2320. //
  2321. if (CompleteTransfer->Endpoint->Type == UsbTransferTypeControl) {
  2322. if (Transfer->Direction == UsbTransferDirectionOut) {
  2323. MmFlushBufferForDataOut(Transfer->Buffer, FlushLength);
  2324. } else {
  2325. MmFlushBufferForDataIo(Transfer->Buffer, FlushLength);
  2326. }
  2327. //
  2328. // Bulk, interrupt, and isochronous transfers really only go the direction
  2329. // they claim.
  2330. //
  2331. } else {
  2332. if (Transfer->Direction == UsbTransferDirectionOut) {
  2333. MmFlushBufferForDataOut(Transfer->Buffer, FlushLength);
  2334. } else {
  2335. ASSERT(Transfer->Direction == UsbTransferDirectionIn);
  2336. MmFlushBufferForDataIn(Transfer->Buffer, FlushLength);
  2337. }
  2338. }
  2339. //
  2340. // Acquire the USB device's lock to check the status. Transfers should not
  2341. // be submitted to disconnected devices.
  2342. //
  2343. if (PolledMode == FALSE) {
  2344. KeAcquireQueuedLock(Device->Lock);
  2345. ReleaseDeviceLock = TRUE;
  2346. }
  2347. if (Device->Connected == FALSE) {
  2348. Transfer->Error = UsbErrorTransferDeviceNotConnected;
  2349. Status = STATUS_DEVICE_NOT_CONNECTED;
  2350. goto SubmitTransferEnd;
  2351. }
  2352. //
  2353. // Update the transfer state to 'active' before submission to the host
  2354. // controller. This could be a transition from either the callback state
  2355. // or the inactive state.
  2356. //
  2357. OriginalState = RtlAtomicCompareExchange32(&(CompleteTransfer->State),
  2358. TransferActive,
  2359. TransferInCallback);
  2360. if (OriginalState != TransferInCallback) {
  2361. OriginalState = RtlAtomicCompareExchange32(&(CompleteTransfer->State),
  2362. TransferActive,
  2363. TransferInactive);
  2364. if (OriginalState != TransferInactive) {
  2365. KeCrashSystem(CRASH_USB_ERROR,
  2366. UsbErrorTransferSubmittedWhileStillActive,
  2367. (UINTN)Transfer,
  2368. CompleteTransfer->State,
  2369. 0);
  2370. }
  2371. }
  2372. //
  2373. // Submit the transfer to the host controller.
  2374. //
  2375. Status = SubmitTransfer(Controller->Device.HostControllerContext,
  2376. Endpoint->HostControllerContext,
  2377. &(CompleteTransfer->Protected),
  2378. CompleteTransfer->HostControllerContext);
  2379. if (!KSUCCESS(Status)) {
  2380. Transfer->Error = UsbErrorTransferFailedToSubmit;
  2381. //
  2382. // Flip the transfer state to inactive, always.
  2383. //
  2384. OriginalState = RtlAtomicCompareExchange32(&(CompleteTransfer->State),
  2385. TransferInactive,
  2386. TransferActive);
  2387. ASSERT(OriginalState == TransferActive);
  2388. goto SubmitTransferEnd;
  2389. }
  2390. if (PolledMode == FALSE) {
  2391. KeReleaseQueuedLock(Device->Lock);
  2392. ReleaseDeviceLock = FALSE;
  2393. }
  2394. PacketQueued = TRUE;
  2395. Status = STATUS_SUCCESS;
  2396. SubmitTransferEnd:
  2397. if (!KSUCCESS(Status)) {
  2398. //
  2399. // Release the device lock, if necessary.
  2400. //
  2401. if (ReleaseDeviceLock != FALSE) {
  2402. ASSERT(PolledMode == FALSE);
  2403. KeReleaseQueuedLock(Device->Lock);
  2404. }
  2405. //
  2406. // Report transfer failures.
  2407. //
  2408. if ((UsbDebugFlags & (USB_DEBUG_TRANSFERS | USB_DEBUG_ERRORS)) != 0) {
  2409. if ((UsbDebugDeviceAddress == 0) ||
  2410. (UsbDebugDeviceAddress ==
  2411. CompleteTransfer->Protected.DeviceAddress)) {
  2412. RtlDebugPrint(
  2413. "USB: Submit failed, transfer (0x%08x) %s "
  2414. "dev %d, EP%x, %s, Buffer %x, Len %x. Status 0x%x\n",
  2415. Transfer,
  2416. UsbTransferDirectionStrings[Transfer->Direction],
  2417. CompleteTransfer->Protected.DeviceAddress,
  2418. CompleteTransfer->Protected.EndpointNumber,
  2419. UsbTransferTypeStrings[CompleteTransfer->Protected.Type],
  2420. Transfer->Buffer,
  2421. Transfer->Length,
  2422. Status);
  2423. }
  2424. }
  2425. //
  2426. // Upon failure, cancel the transfer if it was submitted. This will
  2427. // modify the transfer state. Also, it could fail if the transfer went
  2428. // through very quickly. This, however, is not currently a valid error
  2429. // path - just future proofing.
  2430. //
  2431. if (PacketQueued != FALSE) {
  2432. UsbCancelTransfer(Transfer, TRUE);
  2433. //
  2434. // Relese the reference on failure. If the cancel path was taken, then
  2435. // the reference will be released after the callback. Also set the
  2436. // transfer status here; the cancel path does that as well.
  2437. //
  2438. } else {
  2439. Transfer->Status = Status;
  2440. UsbTransferReleaseReference(Transfer);
  2441. }
  2442. }
  2443. return Status;
  2444. }
  2445. KSTATUS
  2446. UsbpCreateEndpointsForInterface (
  2447. PUSB_DEVICE Device,
  2448. PUSB_INTERFACE Interface
  2449. )
  2450. /*++
  2451. Routine Description:
  2452. This routine creates endpoints for the given interface.
  2453. Arguments:
  2454. Device - Supplies a pointer to the device owning the interface and
  2455. endpoints.
  2456. Interface - Supplies a pointer to the interface to create endpoints for.
  2457. Return Value:
  2458. Status code.
  2459. --*/
  2460. {
  2461. UCHAR Attributes;
  2462. PLIST_ENTRY CurrentEntry;
  2463. USB_TRANSFER_DIRECTION Direction;
  2464. PUSB_ENDPOINT Endpoint;
  2465. PUSB_ENDPOINT_DESCRIPTION EndpointDescription;
  2466. UCHAR EndpointNumber;
  2467. ULONG MaxPacketSize;
  2468. ULONG PollRate;
  2469. KSTATUS Status;
  2470. USB_TRANSFER_TYPE Type;
  2471. //
  2472. // Loop through all the endpoint descriptions.
  2473. //
  2474. CurrentEntry = Interface->Description.EndpointListHead.Next;
  2475. while (CurrentEntry != &(Interface->Description.EndpointListHead)) {
  2476. EndpointDescription = LIST_VALUE(CurrentEntry,
  2477. USB_ENDPOINT_DESCRIPTION,
  2478. ListEntry);
  2479. CurrentEntry = CurrentEntry->Next;
  2480. PollRate = 0;
  2481. //
  2482. // Get the endpoint number.
  2483. //
  2484. EndpointNumber = EndpointDescription->Descriptor.EndpointAddress;
  2485. //
  2486. // Get the endpoint type.
  2487. //
  2488. Attributes = EndpointDescription->Descriptor.Attributes;
  2489. switch (Attributes & USB_ENDPOINT_ATTRIBUTES_TYPE_MASK) {
  2490. case USB_ENDPOINT_ATTRIBUTES_TYPE_CONTROL:
  2491. Type = UsbTransferTypeControl;
  2492. break;
  2493. case USB_ENDPOINT_ATTRIBUTES_TYPE_ISOCHRONOUS:
  2494. Type = UsbTransferTypeIsochronous;
  2495. PollRate = EndpointDescription->Descriptor.Interval;
  2496. break;
  2497. case USB_ENDPOINT_ATTRIBUTES_TYPE_BULK:
  2498. Type = UsbTransferTypeBulk;
  2499. if ((EndpointNumber & USB_ENDPOINT_ADDRESS_DIRECTION_IN) == 0) {
  2500. PollRate = EndpointDescription->Descriptor.Interval;
  2501. }
  2502. break;
  2503. case USB_ENDPOINT_ATTRIBUTES_TYPE_INTERRUPT:
  2504. default:
  2505. Type = UsbTransferTypeInterrupt;
  2506. PollRate = EndpointDescription->Descriptor.Interval;
  2507. break;
  2508. }
  2509. //
  2510. // Get the direction.
  2511. //
  2512. if (Type == UsbTransferTypeControl) {
  2513. Direction = UsbTransferBidirectional;
  2514. } else {
  2515. Direction = UsbTransferDirectionOut;
  2516. if ((EndpointNumber & USB_ENDPOINT_ADDRESS_DIRECTION_IN) != 0) {
  2517. Direction = UsbTransferDirectionIn;
  2518. }
  2519. }
  2520. MaxPacketSize = EndpointDescription->Descriptor.MaxPacketSize;
  2521. Status = UsbpCreateEndpoint(Device,
  2522. EndpointNumber,
  2523. Direction,
  2524. Type,
  2525. MaxPacketSize,
  2526. PollRate,
  2527. &Endpoint);
  2528. if (!KSUCCESS(Status)) {
  2529. goto CreateEndpointsForInterfaceEnd;
  2530. }
  2531. INSERT_BEFORE(&(Endpoint->ListEntry), &(Interface->EndpointList));
  2532. }
  2533. Status = STATUS_SUCCESS;
  2534. CreateEndpointsForInterfaceEnd:
  2535. if (!KSUCCESS(Status)) {
  2536. //
  2537. // Loop through and free any endpoints that were created.
  2538. //
  2539. CurrentEntry = Interface->EndpointList.Next;
  2540. while (CurrentEntry != &(Interface->EndpointList)) {
  2541. Endpoint = LIST_VALUE(CurrentEntry, USB_ENDPOINT, ListEntry);
  2542. CurrentEntry = CurrentEntry->Next;
  2543. ASSERT(Endpoint->ReferenceCount == 1);
  2544. UsbpEndpointReleaseReference(Device, Endpoint);
  2545. }
  2546. }
  2547. return Status;
  2548. }
  2549. PUSB_ENDPOINT
  2550. UsbpGetDeviceEndpoint (
  2551. PUSB_DEVICE Device,
  2552. UCHAR EndpointNumber
  2553. )
  2554. /*++
  2555. Routine Description:
  2556. This routine looks up a USB endpoint for the given device.
  2557. Arguments:
  2558. Device - Supplies a pointer to a USB device.
  2559. EndpointNumber - Supplies the number of the desired endpoint.
  2560. Return Value:
  2561. Returns a pointer to a USB endpoint on success, or NULL if the given
  2562. endpoint does not exist for the given device.
  2563. --*/
  2564. {
  2565. PUSB_CONFIGURATION ActiveConfiguration;
  2566. PLIST_ENTRY CurrentEndpointEntry;
  2567. PLIST_ENTRY CurrentInterfaceEntry;
  2568. PUSB_ENDPOINT Endpoint;
  2569. PUSB_INTERFACE Interface;
  2570. PLIST_ENTRY InterfaceListHead;
  2571. //
  2572. // Endpoint zero is easy to retrieve.
  2573. //
  2574. if (EndpointNumber == 0) {
  2575. return Device->EndpointZero;
  2576. }
  2577. //
  2578. // Run through the list of interfaces and associated endpoints to find
  2579. // non-zero endpoints.
  2580. //
  2581. ASSERT(Device->ActiveConfiguration != NULL);
  2582. ActiveConfiguration = Device->ActiveConfiguration;
  2583. InterfaceListHead = &(ActiveConfiguration->Description.InterfaceListHead);
  2584. CurrentInterfaceEntry = InterfaceListHead->Next;
  2585. Endpoint = NULL;
  2586. while (CurrentInterfaceEntry != InterfaceListHead) {
  2587. Interface = LIST_VALUE(CurrentInterfaceEntry,
  2588. USB_INTERFACE,
  2589. Description.ListEntry);
  2590. CurrentEndpointEntry = Interface->EndpointList.Next;
  2591. CurrentInterfaceEntry = CurrentInterfaceEntry->Next;
  2592. while (CurrentEndpointEntry != &(Interface->EndpointList)) {
  2593. Endpoint = LIST_VALUE(CurrentEndpointEntry,
  2594. USB_ENDPOINT,
  2595. ListEntry);
  2596. CurrentEndpointEntry = CurrentEndpointEntry->Next;
  2597. if (Endpoint->Number == EndpointNumber) {
  2598. break;
  2599. }
  2600. }
  2601. if ((Endpoint != NULL) && (Endpoint->Number == EndpointNumber)) {
  2602. break;
  2603. }
  2604. }
  2605. return Endpoint;
  2606. }
  2607. VOID
  2608. UsbpCompletedTransferWorker (
  2609. PVOID Parameter
  2610. )
  2611. /*++
  2612. Routine Description:
  2613. This routine processes completed USB transfers.
  2614. Arguments:
  2615. Parameter - Supplies a pointer to the USB host controller.
  2616. Return Value:
  2617. None.
  2618. --*/
  2619. {
  2620. PUSB_TRANSFER_CALLBACK CallbackRoutine;
  2621. PUSB_TRANSFER_PRIVATE CompleteTransfer;
  2622. PUSB_TRANSFER_COMPLETION_QUEUE CompletionQueue;
  2623. PLIST_ENTRY CurrentEntry;
  2624. RUNLEVEL OldRunLevel;
  2625. USB_TRANSFER_STATE OldState;
  2626. LIST_ENTRY TransferList;
  2627. ASSERT(KeGetRunLevel() == RunLevelLow);
  2628. CompletionQueue = (PUSB_TRANSFER_COMPLETION_QUEUE)Parameter;
  2629. //
  2630. // Acquire the lock and pull all transfers off of the list. Once the list
  2631. // is empty and the lock is released, other completed transfers will know
  2632. // that the work item needs to be queued.
  2633. //
  2634. ASSERT(LIST_EMPTY(&(CompletionQueue->CompletedTransfersList)) == FALSE);
  2635. OldRunLevel = UsbpAcquireCompletedTransfersLock(CompletionQueue);
  2636. MOVE_LIST(&(CompletionQueue->CompletedTransfersList), &TransferList);
  2637. INITIALIZE_LIST_HEAD(&(CompletionQueue->CompletedTransfersList));
  2638. UsbpReleaseCompletedTransfersLock(CompletionQueue, OldRunLevel);
  2639. //
  2640. // Now that the lock is released and execution is at low level, process the
  2641. // work items.
  2642. //
  2643. while (LIST_EMPTY(&TransferList) == FALSE) {
  2644. CurrentEntry = TransferList.Next;
  2645. LIST_REMOVE(CurrentEntry);
  2646. CompleteTransfer = LIST_VALUE(CurrentEntry,
  2647. USB_TRANSFER_PRIVATE,
  2648. CompletionListEntry);
  2649. ASSERT(CompleteTransfer->Magic == USB_TRANSFER_INTERNAL_MAGIC);
  2650. //
  2651. // Mark that the transfer is no longer in flight, but in the callback.
  2652. //
  2653. OldState = RtlAtomicCompareExchange32(&(CompleteTransfer->State),
  2654. TransferInCallback,
  2655. TransferActive);
  2656. ASSERT(OldState == TransferActive);
  2657. //
  2658. // Call the callback routine.
  2659. //
  2660. CompleteTransfer->CompletionListEntry.Next = NULL;
  2661. CallbackRoutine = CompleteTransfer->Protected.Public.CallbackRoutine;
  2662. CallbackRoutine(&(CompleteTransfer->Protected.Public));
  2663. //
  2664. // If the callback did not resubmit the transfer, then move it to the
  2665. // inactive state. See the submit routine for how this change
  2666. // synchronizes with re-submits that are outside the callback (e.g. in
  2667. // a work item).
  2668. //
  2669. RtlAtomicCompareExchange32(&(CompleteTransfer->State),
  2670. TransferInactive,
  2671. TransferInCallback);
  2672. //
  2673. // Once the callback is called, USB core is done with this transfer;
  2674. // release the reference taken during submit.
  2675. //
  2676. UsbTransferReleaseReference((PUSB_TRANSFER)CompleteTransfer);
  2677. }
  2678. return;
  2679. }
  2680. RUNLEVEL
  2681. UsbpAcquireCompletedTransfersLock (
  2682. PUSB_TRANSFER_COMPLETION_QUEUE CompletionQueue
  2683. )
  2684. /*++
  2685. Routine Description:
  2686. This routine acquires the given completion queue's completed transfers lock
  2687. at dispatch level.
  2688. Arguments:
  2689. CompletionQueue - Supplies a pointer to the completion queue to lock.
  2690. Return Value:
  2691. Returns the previous run-level, which must be passed in when the completion
  2692. queue is unlocked.
  2693. --*/
  2694. {
  2695. RUNLEVEL OldRunLevel;
  2696. OldRunLevel = KeRaiseRunLevel(RunLevelDispatch);
  2697. KeAcquireSpinLock(&(CompletionQueue->CompletedTransfersListLock));
  2698. return OldRunLevel;
  2699. }
  2700. VOID
  2701. UsbpReleaseCompletedTransfersLock (
  2702. PUSB_TRANSFER_COMPLETION_QUEUE CompletionQueue,
  2703. RUNLEVEL OldRunLevel
  2704. )
  2705. /*++
  2706. Routine Description:
  2707. This routine releases the given completion queue's completed transfers
  2708. lock, and returns the run-level to its previous value.
  2709. Arguments:
  2710. CompletionQueue - Supplies a pointer to the completion queue to unlock.
  2711. OldRunLevel - Supplies the original run level returned when the lock was
  2712. acquired.
  2713. Return Value:
  2714. None.
  2715. --*/
  2716. {
  2717. KeReleaseSpinLock(&(CompletionQueue->CompletedTransfersListLock));
  2718. KeLowerRunLevel(OldRunLevel);
  2719. return;
  2720. }