enum.c 63 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631
  1. /*++
  2. Copyright (c) 2013 Minoca Corp. All Rights Reserved
  3. Module Name:
  4. enum.c
  5. Abstract:
  6. This module implements device enumeration for the USB core.
  7. Author:
  8. Evan Green 16-Jan-2013
  9. Environment:
  10. Kernel
  11. --*/
  12. //
  13. // ------------------------------------------------------------------- Includes
  14. //
  15. #include <minoca/kernel/driver.h>
  16. #include "usbcore.h"
  17. //
  18. // ---------------------------------------------------------------- Definitions
  19. //
  20. //
  21. // Define the format of device identifiers that USB presents devices with.
  22. //
  23. #define USB_DEVICE_ID_LENGTH 20
  24. #define USB_DEVICE_ID_FORMAT "VID_%04X&PID_%04X"
  25. #define USB_DEVICE_ID_WITH_INTERFACE_FORMAT "VID_%04X&PID_%04X_%02X"
  26. //
  27. // Define the number of times an enumeration request will be made before
  28. // declaring that it really doesn't work.
  29. //
  30. #define USB_ENUMERATION_TRANSFER_TRY_COUNT 5
  31. //
  32. // ------------------------------------------------------ Data Type Definitions
  33. //
  34. //
  35. // ----------------------------------------------- Internal Function Prototypes
  36. //
  37. KSTATUS
  38. UsbpEnumerateRootHub (
  39. PUSB_HOST_CONTROLLER Controller
  40. );
  41. PUSB_DEVICE
  42. UsbpCreateDevice (
  43. USB_DEVICE_SPEED DeviceSpeed,
  44. PUSB_DEVICE ParentDevice,
  45. UCHAR PortNumber,
  46. PUSB_HOST_CONTROLLER ParentController
  47. );
  48. VOID
  49. UsbpDestroyDevice (
  50. PUSB_DEVICE Device
  51. );
  52. KSTATUS
  53. UsbpGetDeviceDescriptor (
  54. PUSB_DEVICE Device,
  55. PUSB_DEVICE_DESCRIPTOR DeviceDescriptor,
  56. BOOL FirstEightBytesOnly
  57. );
  58. KSTATUS
  59. UsbpAssignDeviceAddress (
  60. PUSB_DEVICE Device
  61. );
  62. VOID
  63. UsbpUnassignDeviceAddress (
  64. PUSB_DEVICE Device
  65. );
  66. KSTATUS
  67. UsbpReadDeviceStrings (
  68. PUSB_DEVICE Device,
  69. PUSB_DEVICE_DESCRIPTOR DeviceDescriptor
  70. );
  71. PSTR
  72. UsbpCreateAnsiStringFromStringDescriptor (
  73. PUSB_STRING_DESCRIPTOR StringDescriptor
  74. );
  75. VOID
  76. UsbpGetDeviceClass (
  77. PUSB_DEVICE Device,
  78. PUCHAR Class,
  79. PUCHAR Subclass,
  80. PUCHAR Protocol
  81. );
  82. KSTATUS
  83. UsbpCreateOsDevice (
  84. PUSB_DEVICE Device,
  85. UCHAR Class,
  86. UCHAR Subclass,
  87. UCHAR Protocol,
  88. UCHAR Interface,
  89. BOOL InterfaceDevice,
  90. PDEVICE *CreatedDevice
  91. );
  92. UCHAR
  93. UsbpGetReservedDeviceAddress (
  94. PUSB_DEVICE Device
  95. );
  96. //
  97. // -------------------------------------------------------------------- Globals
  98. //
  99. //
  100. // ------------------------------------------------------------------ Functions
  101. //
  102. USB_API
  103. KSTATUS
  104. UsbHostQueryChildren (
  105. PIRP Irp,
  106. HANDLE UsbDeviceHandle
  107. )
  108. /*++
  109. Routine Description:
  110. This routine responds to the Query Children IRP for a USB Host controller.
  111. Arguments:
  112. Irp - Supplies a pointer to the Query Children IRP.
  113. UsbDeviceHandle - Supplies a pointer to the USB Host controller handle.
  114. Return Value:
  115. Status code.
  116. --*/
  117. {
  118. PUSB_HOST_CONTROLLER Controller;
  119. KSTATUS Status;
  120. Controller = (PUSB_HOST_CONTROLLER)UsbDeviceHandle;
  121. ASSERT(Controller != NULL);
  122. //
  123. // If the root hub's device has never before been created, create it now.
  124. //
  125. if (Controller->RootDevice == NULL) {
  126. Status = UsbpEnumerateRootHub(Controller);
  127. if (!KSUCCESS(Status)) {
  128. goto HostQueryChildrenEnd;
  129. }
  130. }
  131. ASSERT((Controller->RootDevice != NULL) &&
  132. (Controller->RootDevice->Device != NULL));
  133. //
  134. // Merge whatever is in the IRP with the enumeration of this root hub.
  135. //
  136. Status = IoMergeChildArrays(Irp,
  137. &(Controller->RootDevice->Device),
  138. 1,
  139. USB_CORE_ALLOCATION_TAG);
  140. if (!KSUCCESS(Status)) {
  141. goto HostQueryChildrenEnd;
  142. }
  143. HostQueryChildrenEnd:
  144. return Status;
  145. }
  146. USB_API
  147. KSTATUS
  148. UsbDriverAttach (
  149. PDEVICE Device,
  150. PDRIVER Driver,
  151. PHANDLE UsbCoreHandle
  152. )
  153. /*++
  154. Routine Description:
  155. This routine attaches a USB driver to a USB device, and returns a USB
  156. core handle to the device, used for all USB communications. This routine
  157. must be called at low level.
  158. Arguments:
  159. Device - Supplies a pointer to the OS device object representation of the
  160. USB device.
  161. Driver - Supplies a pointer to the driver that will take ownership of the
  162. device.
  163. UsbCoreHandle - Supplies a pointer where the USB Core device handle will
  164. be returned.
  165. Return Value:
  166. Status code.
  167. --*/
  168. {
  169. PUSB_DEVICE CurrentDevice;
  170. PLIST_ENTRY CurrentEntry;
  171. PUSB_DEVICE FoundDevice;
  172. PUSB_INTERFACE Interface;
  173. KSTATUS Status;
  174. ASSERT(KeGetRunLevel() == RunLevelLow);
  175. FoundDevice = NULL;
  176. *UsbCoreHandle = INVALID_HANDLE;
  177. if (Driver == NULL) {
  178. return STATUS_ARGUMENT_EXPECTED;
  179. }
  180. //
  181. // Loop through all USB controllers.
  182. //
  183. Status = STATUS_NOT_FOUND;
  184. KeAcquireQueuedLock(UsbDeviceListLock);
  185. CurrentEntry = UsbDeviceList.Next;
  186. while (CurrentEntry != &UsbDeviceList) {
  187. CurrentDevice = LIST_VALUE(CurrentEntry, USB_DEVICE, GlobalListEntry);
  188. ASSERT(CurrentEntry != NULL);
  189. CurrentEntry = CurrentEntry->Next;
  190. //
  191. // Check to see if the driver is attaching to the current device.
  192. //
  193. if (CurrentDevice->Device == Device) {
  194. FoundDevice = CurrentDevice;
  195. if (FoundDevice->Driver == NULL) {
  196. FoundDevice->Driver = Driver;
  197. Status = STATUS_SUCCESS;
  198. }
  199. break;
  200. }
  201. //
  202. // Check all the interfaces of the current configuration to see if the
  203. // driver is actually just attaching to an interface.
  204. //
  205. Interface = (PUSB_INTERFACE)UsbGetDesignatedInterface(Device,
  206. CurrentDevice);
  207. if (Interface != NULL) {
  208. FoundDevice = CurrentDevice;
  209. ASSERT(Interface->Driver == NULL);
  210. Interface->Driver = Driver;
  211. Status = STATUS_SUCCESS;
  212. break;
  213. }
  214. }
  215. KeReleaseQueuedLock(UsbDeviceListLock);
  216. //
  217. // Only a device's removel IRP marks the device as disconnected. Since the
  218. // removal IRP is the last action a device can take, it is safe to assume
  219. // that the attempt to open the device here will succeed.
  220. //
  221. if (FoundDevice != NULL) {
  222. ASSERT(FoundDevice->Connected != FALSE);
  223. *UsbCoreHandle = UsbDeviceOpen(FoundDevice);
  224. ASSERT(*UsbCoreHandle != INVALID_HANDLE);
  225. }
  226. return Status;
  227. }
  228. USB_API
  229. KSTATUS
  230. UsbEnumerateDeviceForInterface (
  231. HANDLE UsbCoreHandle,
  232. PUSB_INTERFACE_DESCRIPTION InterfaceDescription,
  233. PDEVICE *ChildDevice
  234. )
  235. /*++
  236. Routine Description:
  237. This routine enumerates a child OS device on the requested device and
  238. interface combination. With this interface multiple drivers can
  239. independently operate interfaces of a shared USB device.
  240. Arguments:
  241. UsbCoreHandle - Supplies the core handle to the device containing the
  242. interface to share.
  243. InterfaceDescription - Supplies a pointer to the interface to enumerate a
  244. device for.
  245. ChildDevice - Supplies a pointer to an OS device that will come up to
  246. claim the given interface. This device should be returned in Query
  247. Children calls sent to the parent device so the device can properly
  248. enumerate.
  249. Return Value:
  250. Status code.
  251. --*/
  252. {
  253. UCHAR Class;
  254. PUSB_DEVICE Device;
  255. PUSB_INTERFACE Interface;
  256. UCHAR InterfaceNumber;
  257. UCHAR Protocol;
  258. KSTATUS Status;
  259. UCHAR Subclass;
  260. Device = (PUSB_DEVICE)UsbCoreHandle;
  261. Interface = (PUSB_INTERFACE)InterfaceDescription;
  262. if (Interface->Device != NULL) {
  263. *ChildDevice = Interface->Device;
  264. Status = STATUS_SUCCESS;
  265. goto EnumerateDeviceForInterfaceEnd;
  266. }
  267. Class = InterfaceDescription->Descriptor.Class;
  268. Subclass = InterfaceDescription->Descriptor.Subclass;
  269. Protocol = InterfaceDescription->Descriptor.Protocol;
  270. InterfaceNumber = InterfaceDescription->Descriptor.InterfaceNumber;
  271. ASSERT(Device->DebugDevice == FALSE);
  272. Status = UsbpCreateOsDevice(Device,
  273. Class,
  274. Subclass,
  275. Protocol,
  276. InterfaceNumber,
  277. TRUE,
  278. ChildDevice);
  279. if (!KSUCCESS(Status)) {
  280. goto EnumerateDeviceForInterfaceEnd;
  281. }
  282. Interface->Device = *ChildDevice;
  283. Status = STATUS_SUCCESS;
  284. EnumerateDeviceForInterfaceEnd:
  285. if (!KSUCCESS(Status)) {
  286. *ChildDevice = NULL;
  287. }
  288. return Status;
  289. }
  290. USB_API
  291. PUSB_INTERFACE_DESCRIPTION
  292. UsbGetDesignatedInterface (
  293. PDEVICE Device,
  294. HANDLE UsbCoreHandle
  295. )
  296. /*++
  297. Routine Description:
  298. This routine returns the interface for which the given pseudo-device was
  299. enumerated. This routine is used by general class drivers (like Hub or
  300. Mass Storage) that can interact with an interface without necessarily
  301. taking responsibility for the entire device.
  302. Arguments:
  303. Device - Supplies a pointer to the OS device object representation of the
  304. USB device.
  305. UsbCoreHandle - Supplies the core handle to the device.
  306. Return Value:
  307. Returns a pointer to the interface this pseudo-device is supposed to take
  308. ownership of. If the device only has one interface, then that interface is
  309. returned.
  310. NULL if the OS device was not enumerated for any one particular interface.
  311. --*/
  312. {
  313. PUSB_CONFIGURATION Configuration;
  314. PUSB_INTERFACE FoundInterface;
  315. PUSB_INTERFACE Interface;
  316. PLIST_ENTRY InterfaceEntry;
  317. PLIST_ENTRY InterfaceListHead;
  318. PUSB_DEVICE UsbDevice;
  319. UsbDevice = (PUSB_DEVICE)UsbCoreHandle;
  320. if (UsbCoreHandle == INVALID_HANDLE) {
  321. return NULL;
  322. }
  323. FoundInterface = NULL;
  324. Configuration = UsbDevice->ActiveConfiguration;
  325. if (Configuration == NULL) {
  326. return NULL;
  327. }
  328. //
  329. // If there's only one interface, return that one.
  330. //
  331. InterfaceListHead = &(Configuration->Description.InterfaceListHead);
  332. ASSERT(LIST_EMPTY(InterfaceListHead) == FALSE);
  333. InterfaceEntry = InterfaceListHead->Next;
  334. //
  335. // If this is the main device attached to the USB device, just give it the
  336. // first interface.
  337. //
  338. if (UsbDevice->Device == Device) {
  339. FoundInterface = LIST_VALUE(InterfaceEntry,
  340. USB_INTERFACE,
  341. Description.ListEntry);
  342. return (PUSB_INTERFACE_DESCRIPTION)&(FoundInterface->Description);
  343. }
  344. //
  345. // Loop through all the interfaces looking for the one associated with this
  346. // device.
  347. //
  348. while (InterfaceEntry != InterfaceListHead) {
  349. Interface = LIST_VALUE(InterfaceEntry,
  350. USB_INTERFACE,
  351. Description.ListEntry);
  352. if (Interface->Device == Device) {
  353. FoundInterface = Interface;
  354. break;
  355. }
  356. InterfaceEntry = InterfaceEntry->Next;
  357. }
  358. return (PUSB_INTERFACE_DESCRIPTION)&(FoundInterface->Description);
  359. }
  360. USB_API
  361. KSTATUS
  362. UsbGetDeviceSpeed (
  363. PUSB_DEVICE Device,
  364. PUSB_DEVICE_SPEED Speed
  365. )
  366. /*++
  367. Routine Description:
  368. This routine returns the connected speed of the given USB device.
  369. Arguments:
  370. Device - Supplies a pointer to the device.
  371. Speed - Supplies a pointer where the device speed will be returned.
  372. Return Value:
  373. Status code.
  374. --*/
  375. {
  376. *Speed = Device->Speed;
  377. return STATUS_SUCCESS;
  378. }
  379. USB_API
  380. VOID
  381. UsbDetachDevice (
  382. HANDLE UsbCoreHandle
  383. )
  384. /*++
  385. Routine Description:
  386. This routine detaches a USB device from the USB core by marking it as
  387. disconnected, and cancelling all active transfers belonging to the device.
  388. It does not close the device.
  389. Arguments:
  390. UsbCoreHandle - Supplies the core handle to the device that is to be
  391. removed.
  392. Return Value:
  393. None.
  394. --*/
  395. {
  396. PUSB_DEVICE Device;
  397. ASSERT(KeGetRunLevel() == RunLevelLow);
  398. ASSERT(UsbCoreHandle != INVALID_HANDLE);
  399. Device = (PUSB_DEVICE)UsbCoreHandle;
  400. //
  401. // Acquire the device's lock that protects the status and transfer list in
  402. // order to synchronize with transfer submission and deletion.
  403. //
  404. KeAcquireQueuedLock(Device->Lock);
  405. //
  406. // Mark the device as disconnected. Mark this before cancelling the
  407. // transfer so that no new transfers cannot be submitted.
  408. //
  409. Device->Connected = FALSE;
  410. KeReleaseQueuedLock(Device->Lock);
  411. //
  412. // Cancel all of the device's transfers.
  413. //
  414. UsbpCancelAllTransfers(UsbCoreHandle);
  415. return;
  416. }
  417. USB_API
  418. KSTATUS
  419. UsbReadDeviceString (
  420. PUSB_DEVICE Device,
  421. UCHAR StringNumber,
  422. USHORT Language,
  423. PUSB_STRING_DESCRIPTOR Buffer
  424. )
  425. /*++
  426. Routine Description:
  427. This routine reads a string descriptor from a USB device.
  428. Arguments:
  429. Device - Supplies a pointer to the device to read from.
  430. StringNumber - Supplies the string descriptor index of the string to read.
  431. Language - Supplies the language code.
  432. Buffer - Supplies a pointer where the string descriptor and data will be
  433. returned. This buffer must be the size of the maximum string descriptor,
  434. which is 256 bytes.
  435. Return Value:
  436. Status code.
  437. --*/
  438. {
  439. ULONG LengthTransferred;
  440. USB_SETUP_PACKET SetupPacket;
  441. KSTATUS Status;
  442. ULONG Try;
  443. //
  444. // Initialize the setup packet. Send the request once with just a single
  445. // letter's worth of space to get the real size. Some devices don't like
  446. // it when the length is greater than the actual string they want to send.
  447. //
  448. RtlZeroMemory(&SetupPacket, sizeof(USB_SETUP_PACKET));
  449. SetupPacket.RequestType = USB_SETUP_REQUEST_TO_HOST |
  450. USB_SETUP_REQUEST_STANDARD |
  451. USB_SETUP_REQUEST_DEVICE_RECIPIENT;
  452. SetupPacket.Request = USB_DEVICE_REQUEST_GET_DESCRIPTOR;
  453. SetupPacket.Index = Language;
  454. SetupPacket.Length = sizeof(USB_STRING_DESCRIPTOR) + 2;
  455. SetupPacket.Value = (UsbDescriptorTypeString << 8) | StringNumber;
  456. for (Try = 0; Try < USB_ENUMERATION_TRANSFER_TRY_COUNT; Try += 1) {
  457. Status = UsbSendControlTransfer(Device,
  458. UsbTransferDirectionIn,
  459. &SetupPacket,
  460. Buffer,
  461. SetupPacket.Length,
  462. &LengthTransferred);
  463. if (!KSUCCESS(Status)) {
  464. if ((UsbDebugFlags &
  465. (USB_DEBUG_ENUMERATION | USB_DEBUG_ERRORS)) != 0) {
  466. RtlDebugPrint("USB: Failed to read (small) string %d "
  467. "(language 0x%x) from device 0x%x: status %x,"
  468. "try %d.\n",
  469. StringNumber,
  470. Language,
  471. Device,
  472. Status,
  473. Try + 1);
  474. }
  475. }
  476. if (KSUCCESS(Status)) {
  477. break;
  478. }
  479. }
  480. if (!KSUCCESS(Status)) {
  481. if ((UsbDebugFlags & (USB_DEBUG_ENUMERATION | USB_DEBUG_ERRORS)) != 0) {
  482. RtlDebugPrint("USB: ReadDeviceString Giving up.\n");
  483. }
  484. goto ReadDeviceStringEnd;
  485. }
  486. //
  487. // If the string descriptor header was not fully read, exit.
  488. //
  489. if (LengthTransferred < sizeof(USB_STRING_DESCRIPTOR)) {
  490. Status = STATUS_DATA_LENGTH_MISMATCH;
  491. goto ReadDeviceStringEnd;
  492. }
  493. //
  494. // Now read it for real with the correct size.
  495. //
  496. SetupPacket.Length = Buffer->Length;
  497. for (Try = 0; Try < USB_ENUMERATION_TRANSFER_TRY_COUNT; Try += 1) {
  498. Status = UsbSendControlTransfer(Device,
  499. UsbTransferDirectionIn,
  500. &SetupPacket,
  501. Buffer,
  502. SetupPacket.Length,
  503. &LengthTransferred);
  504. if (!KSUCCESS(Status)) {
  505. if ((UsbDebugFlags &
  506. (USB_DEBUG_ENUMERATION | USB_DEBUG_ERRORS)) != 0) {
  507. RtlDebugPrint("USB: Failed to read string %d (language 0x%x) "
  508. "from device 0x%x: status %x, try %d\n",
  509. StringNumber,
  510. Language,
  511. Device,
  512. Status,
  513. Try);
  514. }
  515. }
  516. if (KSUCCESS(Status)) {
  517. break;
  518. }
  519. }
  520. if (!KSUCCESS(Status)) {
  521. if ((UsbDebugFlags & (USB_DEBUG_ENUMERATION | USB_DEBUG_ERRORS)) != 0) {
  522. RtlDebugPrint("USB: ReadDeviceString Giving up.\n");
  523. }
  524. goto ReadDeviceStringEnd;
  525. }
  526. ReadDeviceStringEnd:
  527. return Status;
  528. }
  529. VOID
  530. UsbpDeviceAddReference (
  531. PUSB_DEVICE Device
  532. )
  533. /*++
  534. Routine Description:
  535. This routine increments the reference count on the given device.
  536. Arguments:
  537. Device - Supplies a pointer to the device whose reference count should be
  538. incremented.
  539. Return Value:
  540. None.
  541. --*/
  542. {
  543. ULONG OldReferenceCount;
  544. OldReferenceCount = RtlAtomicAdd32(&(Device->ReferenceCount), 1);
  545. ASSERT((OldReferenceCount != 0) && (OldReferenceCount < 0x1000));
  546. return;
  547. }
  548. VOID
  549. UsbpDeviceReleaseReference (
  550. PUSB_DEVICE Device
  551. )
  552. /*++
  553. Routine Description:
  554. This routine decrements the reference count on the given device, and
  555. destroys it if it hits zero.
  556. Arguments:
  557. Device - Supplies a pointer to the device whose reference count should be
  558. decremented.
  559. Return Value:
  560. None.
  561. --*/
  562. {
  563. ULONG OldReferenceCount;
  564. OldReferenceCount = RtlAtomicAdd32(&(Device->ReferenceCount), -1);
  565. ASSERT((OldReferenceCount != 0) && (OldReferenceCount < 0x1000));
  566. if (OldReferenceCount == 1) {
  567. UsbpDestroyDevice(Device);
  568. }
  569. return;
  570. }
  571. KSTATUS
  572. UsbpEnumerateDevice (
  573. PUSB_HUB ParentHub,
  574. PUSB_DEVICE ParentHubDevice,
  575. UCHAR PortNumber,
  576. USB_DEVICE_SPEED DeviceSpeed,
  577. PHANDLE DeviceHandle
  578. )
  579. /*++
  580. Routine Description:
  581. This routine creates a new USB device in the system. This routine must be
  582. called at low level, and must be called with the parent hub's child lock
  583. held.
  584. Arguments:
  585. ParentHub - Supplies a pointer to the parent hub object.
  586. ParentHubDevice - Supplies the handle of the parent USB hub device
  587. enumerating the new device.
  588. PortNumber - Supplies the parent hub's one-based port number where this
  589. device exists.
  590. DeviceSpeed - Supplies the speed of the device being enumerated.
  591. DeviceHandle - Supplies a pointer where a handle representing the device
  592. will be returned upon success.
  593. Return Value:
  594. Status code.
  595. --*/
  596. {
  597. UCHAR Class;
  598. UCHAR Configuration;
  599. PUSB_DEVICE Device;
  600. USB_DEVICE_DESCRIPTOR DeviceDescriptor;
  601. UCHAR Protocol;
  602. KSTATUS Status;
  603. UCHAR Subclass;
  604. ULONG Try;
  605. Device = NULL;
  606. ASSERT(KeGetRunLevel() == RunLevelLow);
  607. ASSERT(KeIsQueuedLockHeld(ParentHubDevice->ChildLock) != FALSE);
  608. //
  609. // Acquire the parent device's controller lock to synchronize access to
  610. // address zero.
  611. //
  612. KeAcquireQueuedLock(ParentHubDevice->Controller->Lock);
  613. //
  614. // Create the child device.
  615. //
  616. if ((UsbDebugFlags & USB_DEBUG_ENUMERATION) != 0) {
  617. RtlDebugPrint("USB: Creating device on hub 0x%x port %d.\n",
  618. ParentHubDevice,
  619. PortNumber);
  620. }
  621. Device = UsbpCreateDevice(DeviceSpeed,
  622. ParentHubDevice,
  623. PortNumber,
  624. ParentHubDevice->Controller);
  625. if (Device == NULL) {
  626. Status = STATUS_INSUFFICIENT_RESOURCES;
  627. goto EnumerateDeviceEnd;
  628. }
  629. //
  630. // Attempt to establish communication with the device by asking for the
  631. // first 8 bytes of the device descriptor, which contain the maximum
  632. // packet size.
  633. //
  634. for (Try = 0; Try < USB_ENUMERATION_TRANSFER_TRY_COUNT; Try += 1) {
  635. RtlZeroMemory(&DeviceDescriptor, sizeof(USB_DEVICE_DESCRIPTOR));
  636. Status = UsbpGetDeviceDescriptor(Device, &DeviceDescriptor, TRUE);
  637. if (((UsbDebugFlags & USB_DEBUG_ENUMERATION) != 0) ||
  638. ((!KSUCCESS(Status)) &&
  639. ((UsbDebugFlags & USB_DEBUG_ERRORS) != 0))) {
  640. RtlDebugPrint("USB: GetDeviceDescriptor try %d on device %x, "
  641. "Status %x.\n",
  642. Try + 1,
  643. Device,
  644. Status);
  645. }
  646. if (KSUCCESS(Status)) {
  647. break;
  648. }
  649. HlBusySpin(50 * MICROSECONDS_PER_MILLISECOND);
  650. }
  651. if (!KSUCCESS(Status)) {
  652. goto EnumerateDeviceEnd;
  653. }
  654. //
  655. // Reset the device again.
  656. //
  657. Status = UsbpResetHubPort(ParentHub, PortNumber - 1);
  658. if (!KSUCCESS(Status)) {
  659. if ((UsbDebugFlags & (USB_DEBUG_ENUMERATION | USB_DEBUG_ERRORS)) != 0) {
  660. RtlDebugPrint("USB: Hub %x Port %x failed to reset.\n",
  661. ParentHubDevice,
  662. PortNumber);
  663. }
  664. goto EnumerateDeviceEnd;
  665. }
  666. //
  667. // Reset the endpoint to get the newly found max packet size all the way
  668. // down into the host controller.
  669. //
  670. UsbpResetEndpoint(Device, Device->EndpointZero);
  671. //
  672. // Request the entire device descriptor.
  673. //
  674. for (Try = 0; Try < USB_ENUMERATION_TRANSFER_TRY_COUNT; Try += 1) {
  675. Status = UsbpGetDeviceDescriptor(Device, &DeviceDescriptor, FALSE);
  676. if (((UsbDebugFlags & USB_DEBUG_ENUMERATION) != 0) ||
  677. ((!KSUCCESS(Status)) &&
  678. ((UsbDebugFlags & USB_DEBUG_ERRORS) != 0))) {
  679. RtlDebugPrint("USB: GetDeviceDescriptor2 Try %d on device %x, "
  680. "Status %x.\n",
  681. Try + 1,
  682. Device,
  683. Status);
  684. }
  685. if (KSUCCESS(Status)) {
  686. break;
  687. }
  688. }
  689. if (!KSUCCESS(Status)) {
  690. goto EnumerateDeviceEnd;
  691. }
  692. //
  693. // Assign the device an address.
  694. //
  695. Status = UsbpAssignDeviceAddress(Device);
  696. if (((UsbDebugFlags & USB_DEBUG_ENUMERATION) != 0) ||
  697. ((!KSUCCESS(Status)) &&
  698. ((UsbDebugFlags & USB_DEBUG_ERRORS) != 0))) {
  699. RtlDebugPrint("USB: AssignDeviceAddress on device %x, Status %x.\n",
  700. Device,
  701. Status);
  702. }
  703. if (!KSUCCESS(Status)) {
  704. goto EnumerateDeviceEnd;
  705. }
  706. //
  707. // Remember if the device is a hub.
  708. //
  709. if (DeviceDescriptor.Class == UsbDeviceClassHub) {
  710. Device->Type = UsbDeviceTypeHub;
  711. }
  712. Device->ConfigurationCount = DeviceDescriptor.ConfigurationCount;
  713. //
  714. // Attempt to read the interesting device strings.
  715. //
  716. Status = UsbpReadDeviceStrings(Device, &DeviceDescriptor);
  717. if (((UsbDebugFlags & USB_DEBUG_ENUMERATION) != 0) ||
  718. ((!KSUCCESS(Status)) &&
  719. ((UsbDebugFlags & USB_DEBUG_ERRORS) != 0))) {
  720. RtlDebugPrint("USB: ReadDeviceStrings on device %x, Status %x.\n",
  721. Device,
  722. Status);
  723. }
  724. if (!KSUCCESS(Status)) {
  725. goto EnumerateDeviceEnd;
  726. }
  727. //
  728. // Read the configuration descriptors.
  729. //
  730. for (Try = 0; Try < USB_ENUMERATION_TRANSFER_TRY_COUNT; Try += 1) {
  731. Status = UsbpReadConfigurationDescriptors(Device, &DeviceDescriptor);
  732. if (((UsbDebugFlags & USB_DEBUG_ENUMERATION) != 0) ||
  733. ((!KSUCCESS(Status)) &&
  734. ((UsbDebugFlags & USB_DEBUG_ERRORS) != 0))) {
  735. RtlDebugPrint("USB: ReadConfigurationDescriptors on device %x, "
  736. "Status %x.\n",
  737. Device,
  738. Status);
  739. }
  740. if (KSUCCESS(Status)) {
  741. break;
  742. }
  743. }
  744. if (!KSUCCESS(Status)) {
  745. goto EnumerateDeviceEnd;
  746. }
  747. //
  748. // If this is the debug device, avoid exposing it to the operating system,
  749. // as the debugger is using it.
  750. //
  751. if (Device->DebugDevice != FALSE) {
  752. Configuration = Device->Controller->HandoffData->U.Usb.Configuration;
  753. Status = UsbSetConfiguration(Device, Configuration, FALSE);
  754. if (((UsbDebugFlags & USB_DEBUG_DEBUGGER_HANDOFF) != 0) ||
  755. ((!KSUCCESS(Status)) &&
  756. ((UsbDebugFlags & USB_DEBUG_ERRORS) != 0))) {
  757. RtlDebugPrint("USB: Set configuration %d for debug device %x: "
  758. "%x.\n",
  759. Configuration,
  760. Device,
  761. Status);
  762. }
  763. if (!KSUCCESS(Status)) {
  764. goto EnumerateDeviceEnd;
  765. }
  766. //
  767. // The debug device is back online, reconnect!
  768. //
  769. KdConnect();
  770. } else {
  771. //
  772. // Now that the device is properly enumerated, expose it to the
  773. // operating system.
  774. //
  775. UsbpGetDeviceClass(Device, &Class, &Subclass, &Protocol);
  776. Status = UsbpCreateOsDevice(Device,
  777. Class,
  778. Subclass,
  779. Protocol,
  780. 0,
  781. FALSE,
  782. &(Device->Device));
  783. if (((UsbDebugFlags & USB_DEBUG_ENUMERATION) != 0) ||
  784. ((!KSUCCESS(Status)) &&
  785. ((UsbDebugFlags & USB_DEBUG_ERRORS) != 0))) {
  786. RtlDebugPrint("USB: CreateOsDevice on device %x, Status %x.\n",
  787. Device,
  788. Status);
  789. }
  790. if (!KSUCCESS(Status)) {
  791. goto EnumerateDeviceEnd;
  792. }
  793. }
  794. //
  795. // Add the device to the list of children.
  796. //
  797. INSERT_BEFORE(&(Device->ListEntry), &(ParentHubDevice->ChildList));
  798. Status = STATUS_SUCCESS;
  799. if ((UsbDebugFlags & USB_DEBUG_ENUMERATION) != 0) {
  800. RtlDebugPrint("USB: Enumeration complete for device %x.\n", Device);
  801. }
  802. EnumerateDeviceEnd:
  803. KeReleaseQueuedLock(ParentHubDevice->Controller->Lock);
  804. if (!KSUCCESS(Status)) {
  805. if (Device != NULL) {
  806. //
  807. // Remove the device.
  808. //
  809. ASSERT(Device->ReferenceCount == 1);
  810. UsbpRemoveDevice(Device);
  811. Device = NULL;
  812. }
  813. }
  814. if (Device == NULL) {
  815. *DeviceHandle = INVALID_HANDLE;
  816. } else {
  817. *DeviceHandle = (HANDLE)Device;
  818. }
  819. return Status;
  820. }
  821. VOID
  822. UsbpRemoveDevice (
  823. PUSB_DEVICE Device
  824. )
  825. /*++
  826. Routine Description:
  827. This routine removes a device from its parent hub. The parent USB device's
  828. child lock should be held.
  829. Arguments:
  830. Device - Supplies a pointer to the device that is to be removed.
  831. Return Value:
  832. None.
  833. --*/
  834. {
  835. ASSERT(KeGetRunLevel() == RunLevelLow);
  836. ASSERT(Device->Parent->Type != UsbDeviceTypeNonHub);
  837. ASSERT(KeIsQueuedLockHeld(Device->Parent->ChildLock) != FALSE);
  838. //
  839. // Remove the device from the parent's list.
  840. //
  841. if (Device->ListEntry.Next != NULL) {
  842. LIST_REMOVE(&(Device->ListEntry));
  843. Device->ListEntry.Next = NULL;
  844. }
  845. //
  846. // Remove the device from the global list.
  847. //
  848. if (Device->GlobalListEntry.Next != NULL) {
  849. KeAcquireQueuedLock(UsbDeviceListLock);
  850. LIST_REMOVE(&(Device->GlobalListEntry));
  851. KeReleaseQueuedLock(UsbDeviceListLock);
  852. Device->GlobalListEntry.Next = NULL;
  853. }
  854. //
  855. // Release the reference on the device that the hub took during
  856. // enumeration.
  857. //
  858. UsbpDeviceReleaseReference(Device);
  859. return;
  860. }
  861. KSTATUS
  862. UsbpReserveDeviceAddress (
  863. PUSB_HOST_CONTROLLER Controller,
  864. PUSB_DEVICE Device,
  865. UCHAR Address
  866. )
  867. /*++
  868. Routine Description:
  869. This routine assigns the given device to a specific address.
  870. Arguments:
  871. Controller - Supplies a pointer to the controller the device lives on.
  872. Device - Supplies a pointer to the USB device reserving the address. This
  873. can be NULL.
  874. Address - Supplies the address to reserve.
  875. Return Value:
  876. STATUS_SUCCESS on success.
  877. STATUS_INSUFFICIENT_RESOURCES if an allocation failed.
  878. STATUS_RESOURCE_IN_USE if the address is already assigned.
  879. --*/
  880. {
  881. ULONG AllocationSize;
  882. PUSB_DEVICE *Segment;
  883. ULONG SegmentIndex;
  884. ULONG SegmentOffset;
  885. SegmentIndex = Address / USB_HOST_ADDRESSES_PER_SEGMENT;
  886. if (SegmentIndex >= USB_HOST_ADDRESS_SEGMENT_COUNT) {
  887. return STATUS_INVALID_PARAMETER;
  888. }
  889. Segment = Controller->ChildrenByAddress[SegmentIndex];
  890. //
  891. // If the segment is not yet allocated, allocate it now.
  892. //
  893. if (Segment == NULL) {
  894. AllocationSize = sizeof(PUSB_DEVICE) * USB_HOST_ADDRESSES_PER_SEGMENT;
  895. Segment = MmAllocateNonPagedPool(AllocationSize,
  896. USB_CORE_ALLOCATION_TAG);
  897. if (Segment == NULL) {
  898. return STATUS_INSUFFICIENT_RESOURCES;
  899. }
  900. RtlZeroMemory(Segment, AllocationSize);
  901. Controller->ChildrenByAddress[SegmentIndex] = Segment;
  902. }
  903. //
  904. // Fail if there's already something valid in that slot.
  905. //
  906. SegmentOffset = Address % USB_HOST_ADDRESSES_PER_SEGMENT;
  907. if ((Segment[SegmentOffset] != NULL) &&
  908. (Segment[SegmentOffset] != (PUSB_DEVICE)-1)) {
  909. return STATUS_RESOURCE_IN_USE;
  910. }
  911. //
  912. // Reserve it.
  913. //
  914. if (Device == NULL) {
  915. Segment[SegmentOffset] = (PUSB_DEVICE)-1;
  916. } else {
  917. Segment[SegmentOffset] = Device;
  918. }
  919. return STATUS_SUCCESS;
  920. }
  921. //
  922. // --------------------------------------------------------- Internal Functions
  923. //
  924. KSTATUS
  925. UsbpEnumerateRootHub (
  926. PUSB_HOST_CONTROLLER Controller
  927. )
  928. /*++
  929. Routine Description:
  930. This routine enumerates a root hub off of a host controller.
  931. Arguments:
  932. Controller - Supplies a pointer to the host controller.
  933. Return Value:
  934. Status code.
  935. --*/
  936. {
  937. PUSB_DEVICE RootDevice;
  938. KSTATUS Status;
  939. ASSERT(Controller->RootDevice == NULL);
  940. //
  941. // Create a USB device structure.
  942. //
  943. RootDevice = UsbpCreateDevice(Controller->Device.Speed,
  944. NULL,
  945. 0,
  946. Controller);
  947. if (RootDevice == NULL) {
  948. Status = STATUS_INVALID_PARAMETER;
  949. goto EnumerateRootHubEnd;
  950. }
  951. RootDevice->Type = UsbDeviceTypeRootHub;
  952. Controller->RootDevice = RootDevice;
  953. //
  954. // Create the OS device to go with the USB device.
  955. //
  956. Status = IoCreateDevice(Controller->Device.DriverObject,
  957. NULL,
  958. Controller->Device.DeviceObject,
  959. USB_ROOT_HUB_DEVICE_ID,
  960. NULL,
  961. NULL,
  962. &(RootDevice->Device));
  963. if (!KSUCCESS(Status)) {
  964. goto EnumerateRootHubEnd;
  965. }
  966. Status = STATUS_SUCCESS;
  967. EnumerateRootHubEnd:
  968. if (!KSUCCESS(Status)) {
  969. if (RootDevice != NULL) {
  970. ASSERT(RootDevice->ReferenceCount == 1);
  971. UsbpRemoveDevice(RootDevice);
  972. }
  973. }
  974. return Status;
  975. }
  976. PUSB_DEVICE
  977. UsbpCreateDevice (
  978. USB_DEVICE_SPEED DeviceSpeed,
  979. PUSB_DEVICE ParentDevice,
  980. UCHAR PortNumber,
  981. PUSB_HOST_CONTROLLER ParentController
  982. )
  983. /*++
  984. Routine Description:
  985. This routine allocates and initializes a new USB device structure. This
  986. routine must be called at low level.
  987. Arguments:
  988. DeviceSpeed - Supplies the speed of the device being enumerated.
  989. ParentDevice - Supplies an optional pointer to the hub device enumerating
  990. this device.
  991. PortNumber - Supplies the parent hub's one-based port number where this
  992. device exists.
  993. ParentController - Supplies a pointer to the host controller that this
  994. device descends from.
  995. Return Value:
  996. Status code.
  997. --*/
  998. {
  999. PUSB_DEVICE Device;
  1000. ULONG MaxPacketSize;
  1001. KSTATUS Status;
  1002. Device = NULL;
  1003. ASSERT(KeGetRunLevel() == RunLevelLow);
  1004. ASSERT(DeviceSpeed != UsbDeviceSpeedInvalid);
  1005. ASSERT((ParentDevice == NULL) || (PortNumber != 0));
  1006. //
  1007. // It is illegal to enumerate a child object with a different parent host
  1008. // controller.
  1009. //
  1010. ASSERT((ParentDevice == NULL) ||
  1011. (ParentDevice->Controller == ParentController));
  1012. //
  1013. // Create a device structure.
  1014. //
  1015. Device = MmAllocateNonPagedPool(sizeof(USB_DEVICE),
  1016. USB_CORE_ALLOCATION_TAG);
  1017. if (Device == NULL) {
  1018. Status = STATUS_INSUFFICIENT_RESOURCES;
  1019. goto CreateDeviceEnd;
  1020. }
  1021. RtlZeroMemory(Device, sizeof(USB_DEVICE));
  1022. INITIALIZE_LIST_HEAD(&(Device->ChildList));
  1023. INITIALIZE_LIST_HEAD(&(Device->ConfigurationList));
  1024. INITIALIZE_LIST_HEAD(&(Device->TransferList));
  1025. Device->ReferenceCount = 1;
  1026. Device->Speed = DeviceSpeed;
  1027. Device->Controller = ParentController;
  1028. Device->Parent = ParentDevice;
  1029. Device->PortNumber = PortNumber;
  1030. Device->Depth = 0;
  1031. if (ParentDevice != NULL) {
  1032. Device->Depth = ParentDevice->Depth + 1;
  1033. }
  1034. Device->ChildLock = KeCreateQueuedLock();
  1035. if (Device->ChildLock == NULL) {
  1036. Status = STATUS_INSUFFICIENT_RESOURCES;
  1037. goto CreateDeviceEnd;
  1038. }
  1039. Device->ConfigurationLock = KeCreateQueuedLock();
  1040. if (Device->ConfigurationLock == NULL) {
  1041. Status = STATUS_INSUFFICIENT_RESOURCES;
  1042. goto CreateDeviceEnd;
  1043. }
  1044. Device->Lock = KeCreateQueuedLock();
  1045. if (Device->Lock == NULL) {
  1046. Status = STATUS_INSUFFICIENT_RESOURCES;
  1047. goto CreateDeviceEnd;
  1048. }
  1049. ASSERT(Device->ListEntry.Next == NULL);
  1050. ASSERT(Device->GlobalListEntry.Next == NULL);
  1051. //
  1052. // Create the default control endpoint.
  1053. //
  1054. MaxPacketSize = 8;
  1055. Status = UsbpCreateEndpoint(Device,
  1056. 0,
  1057. UsbTransferBidirectional,
  1058. UsbTransferTypeControl,
  1059. MaxPacketSize,
  1060. 0,
  1061. &(Device->EndpointZero));
  1062. if (!KSUCCESS(Status)) {
  1063. goto CreateDeviceEnd;
  1064. }
  1065. //
  1066. // Mark the device as connected before adding it to the global list. The
  1067. // device needs to be marked connected for transfers to be submitted.
  1068. //
  1069. Device->Connected = TRUE;
  1070. //
  1071. // Insert the device onto the global list.
  1072. //
  1073. KeAcquireQueuedLock(UsbDeviceListLock);
  1074. INSERT_AFTER(&(Device->GlobalListEntry), &UsbDeviceList);
  1075. KeReleaseQueuedLock(UsbDeviceListLock);
  1076. Status = STATUS_SUCCESS;
  1077. CreateDeviceEnd:
  1078. if (!KSUCCESS(Status)) {
  1079. if (Device != NULL) {
  1080. if (Device->EndpointZero != NULL) {
  1081. ASSERT(Device->EndpointZero->ReferenceCount == 1);
  1082. UsbpEndpointReleaseReference(Device, Device->EndpointZero);
  1083. }
  1084. if (Device->ChildLock != NULL) {
  1085. KeDestroyQueuedLock(Device->ChildLock);
  1086. }
  1087. if (Device->ConfigurationLock != NULL) {
  1088. KeDestroyQueuedLock(Device->ConfigurationLock);
  1089. }
  1090. if (Device->Lock != NULL) {
  1091. KeDestroyQueuedLock(Device->Lock);
  1092. }
  1093. MmFreeNonPagedPool(Device);
  1094. Device = NULL;
  1095. }
  1096. }
  1097. return Device;
  1098. }
  1099. VOID
  1100. UsbpDestroyDevice (
  1101. PUSB_DEVICE Device
  1102. )
  1103. /*++
  1104. Routine Description:
  1105. This routine releases the memory associated with a USB device. It is
  1106. assumed that the device is already pulled off of all lists to which it
  1107. belonged. This routine must be called at low level.
  1108. Arguments:
  1109. Device - Supplies a pointer to the device to release.
  1110. Return Value:
  1111. None.
  1112. --*/
  1113. {
  1114. PUSB_CONFIGURATION Configuration;
  1115. ASSERT(KeGetRunLevel() == RunLevelLow);
  1116. //
  1117. // Assert that all references have been released, the device has no more
  1118. // children and that it has no more transfers.
  1119. //
  1120. ASSERT(Device->ReferenceCount == 0);
  1121. ASSERT(LIST_EMPTY(&(Device->ChildList)) != FALSE);
  1122. ASSERT(LIST_EMPTY(&(Device->TransferList)) != FALSE);
  1123. //
  1124. // Unassign the device's bus address.
  1125. //
  1126. if (Device->Type != UsbDeviceTypeRootHub) {
  1127. UsbpUnassignDeviceAddress(Device);
  1128. }
  1129. //
  1130. // Release the reference taken on the endpoint.
  1131. //
  1132. UsbpEndpointReleaseReference(Device, Device->EndpointZero);
  1133. //
  1134. // Release all cached configurations.
  1135. //
  1136. while (LIST_EMPTY(&(Device->ConfigurationList)) == FALSE) {
  1137. Configuration = LIST_VALUE(Device->ConfigurationList.Next,
  1138. USB_CONFIGURATION,
  1139. ListEntry);
  1140. LIST_REMOVE(&(Configuration->ListEntry));
  1141. MmFreePagedPool(Configuration);
  1142. }
  1143. //
  1144. // Destroy all other structures.
  1145. //
  1146. KeDestroyQueuedLock(Device->Lock);
  1147. KeDestroyQueuedLock(Device->ConfigurationLock);
  1148. KeDestroyQueuedLock(Device->ChildLock);
  1149. if (Device->Manufacturer != NULL) {
  1150. MmFreePagedPool(Device->Manufacturer);
  1151. }
  1152. if (Device->ProductName != NULL) {
  1153. MmFreePagedPool(Device->ProductName);
  1154. }
  1155. if (Device->SerialNumber != NULL) {
  1156. MmFreePagedPool(Device->SerialNumber);
  1157. }
  1158. MmFreeNonPagedPool(Device);
  1159. return;
  1160. }
  1161. KSTATUS
  1162. UsbpGetDeviceDescriptor (
  1163. PUSB_DEVICE Device,
  1164. PUSB_DEVICE_DESCRIPTOR DeviceDescriptor,
  1165. BOOL FirstEightBytesOnly
  1166. )
  1167. /*++
  1168. Routine Description:
  1169. This routine attempts to get the device descriptor out of a new USB device.
  1170. Arguments:
  1171. Device - Supplies a pointer to the device to query.
  1172. DeviceDescriptor - Supplies a pointer where the device descriptor will be
  1173. returned.
  1174. FirstEightBytesOnly - Supplies a boolean indicating if only the first 8
  1175. bytes of the device descriptor should be retrieved.
  1176. Return Value:
  1177. Status code.
  1178. --*/
  1179. {
  1180. ULONG LengthTransferred;
  1181. USB_SETUP_PACKET Setup;
  1182. KSTATUS Status;
  1183. //
  1184. // Create the setup packet to get the device descriptor.
  1185. //
  1186. RtlZeroMemory(&Setup, sizeof(USB_SETUP_PACKET));
  1187. Setup.RequestType = USB_SETUP_REQUEST_TO_HOST |
  1188. USB_SETUP_REQUEST_STANDARD |
  1189. USB_SETUP_REQUEST_DEVICE_RECIPIENT;
  1190. Setup.Request = USB_DEVICE_REQUEST_GET_DESCRIPTOR;
  1191. Setup.Value = UsbDescriptorTypeDevice << 8;
  1192. Setup.Index = 0;
  1193. if (FirstEightBytesOnly != FALSE) {
  1194. Setup.Length = 8;
  1195. } else {
  1196. Setup.Length = sizeof(USB_DEVICE_DESCRIPTOR);
  1197. }
  1198. Status = UsbSendControlTransfer(Device,
  1199. UsbTransferDirectionIn,
  1200. &Setup,
  1201. DeviceDescriptor,
  1202. Setup.Length,
  1203. &LengthTransferred);
  1204. if (!KSUCCESS(Status)) {
  1205. goto GetDeviceDescriptorEnd;
  1206. }
  1207. if (LengthTransferred != Setup.Length) {
  1208. Status = STATUS_DATA_LENGTH_MISMATCH;
  1209. goto GetDeviceDescriptorEnd;
  1210. }
  1211. //
  1212. // Save the values just grabbed into the device if they were retrieved.
  1213. // If only the first 8 bytes were grabbed, that's enough to determine the
  1214. // max packet size so that the rest of the device descriptor can be
  1215. // requested next.
  1216. //
  1217. Device->EndpointZero->MaxPacketSize = DeviceDescriptor->MaxPacketSize;
  1218. if (FirstEightBytesOnly == FALSE) {
  1219. Device->VendorId = DeviceDescriptor->VendorId;
  1220. Device->ProductId = DeviceDescriptor->ProductId;
  1221. Device->ClassCode = DeviceDescriptor->Class;
  1222. Device->SubclassCode = DeviceDescriptor->Subclass;
  1223. Device->ProtocolCode = DeviceDescriptor->Protocol;
  1224. }
  1225. Status = STATUS_SUCCESS;
  1226. GetDeviceDescriptorEnd:
  1227. return Status;
  1228. }
  1229. KSTATUS
  1230. UsbpAssignDeviceAddress (
  1231. PUSB_DEVICE Device
  1232. )
  1233. /*++
  1234. Routine Description:
  1235. This routine assigns a new address to the USB device. This routine must be
  1236. called at low level, and assumes the controller lock is held.
  1237. Arguments:
  1238. Device - Supplies a pointer to the device to assign an address to.
  1239. Return Value:
  1240. Status code. On success, the new device address will be returned inside the
  1241. device, and this routine will send a SET_ADDRESS command to the device.
  1242. --*/
  1243. {
  1244. UCHAR AddressIndex;
  1245. BOOL AddressLockHeld;
  1246. PUSB_HOST_CONTROLLER Controller;
  1247. UCHAR FoundAddress;
  1248. ULONG LengthTransferred;
  1249. UCHAR ReservedAddress;
  1250. PUSB_DEVICE *Segment;
  1251. ULONG SegmentIndex;
  1252. USB_SETUP_PACKET SetupPacket;
  1253. KSTATUS Status;
  1254. AddressLockHeld = FALSE;
  1255. FoundAddress = 0;
  1256. ASSERT(KeGetRunLevel() == RunLevelLow);
  1257. ASSERT(Device->BusAddress == 0);
  1258. ASSERT(KeIsQueuedLockHeld(Device->Controller->Lock) != FALSE);
  1259. //
  1260. // Acquire the controller's address lock in order to find an address.
  1261. //
  1262. Controller = Device->Controller;
  1263. KeAcquireQueuedLock(Controller->AddressLock);
  1264. AddressLockHeld = TRUE;
  1265. ReservedAddress = UsbpGetReservedDeviceAddress(Device);
  1266. if (ReservedAddress != 0) {
  1267. //
  1268. // Make the association between the address (which is just reserved)
  1269. // to the actual device pointer.
  1270. //
  1271. Status = UsbpReserveDeviceAddress(Controller, Device, ReservedAddress);
  1272. ASSERT(KSUCCESS(Status));
  1273. FoundAddress = ReservedAddress;
  1274. //
  1275. // This device is not special, go allocate an address.
  1276. //
  1277. } else {
  1278. if (Controller->ControllerFull != FALSE) {
  1279. Status = STATUS_RESOURCE_IN_USE;
  1280. goto AssignDeviceAddressEnd;
  1281. }
  1282. //
  1283. // Loop through every segment of addresses. Segmentation of the 128
  1284. // addresses is done to cut down on wasted memory allocations.
  1285. //
  1286. for (SegmentIndex = 0;
  1287. SegmentIndex < USB_HOST_ADDRESS_SEGMENT_COUNT;
  1288. SegmentIndex += 1) {
  1289. Segment = Controller->ChildrenByAddress[SegmentIndex];
  1290. for (AddressIndex = 0;
  1291. AddressIndex < USB_HOST_ADDRESSES_PER_SEGMENT;
  1292. AddressIndex += 1) {
  1293. //
  1294. // Skip address zero.
  1295. //
  1296. if ((SegmentIndex == 0) && (AddressIndex == 0)) {
  1297. continue;
  1298. }
  1299. //
  1300. // If there is no segment or the index is free, try to reserve
  1301. // it.
  1302. //
  1303. if ((Segment == NULL) || (Segment[AddressIndex] == NULL)) {
  1304. FoundAddress =
  1305. (SegmentIndex * USB_HOST_ADDRESSES_PER_SEGMENT) +
  1306. AddressIndex;
  1307. Status = UsbpReserveDeviceAddress(Controller,
  1308. Device,
  1309. FoundAddress);
  1310. if (KSUCCESS(Status)) {
  1311. break;
  1312. }
  1313. FoundAddress = 0;
  1314. }
  1315. }
  1316. if (FoundAddress != 0) {
  1317. break;
  1318. }
  1319. }
  1320. }
  1321. //
  1322. // If an address could not be allocated, the bus is full of devices!
  1323. //
  1324. if (FoundAddress == 0) {
  1325. Controller->ControllerFull = TRUE;
  1326. Status = STATUS_RESOURCE_IN_USE;
  1327. goto AssignDeviceAddressEnd;
  1328. }
  1329. //
  1330. // Now that an address has been acquired, release the address lock.
  1331. //
  1332. KeReleaseQueuedLock(Controller->AddressLock);
  1333. AddressLockHeld = FALSE;
  1334. //
  1335. // Send a SET_ADDRESS command to the device to get it off of address zero.
  1336. //
  1337. RtlZeroMemory(&SetupPacket, sizeof(USB_SETUP_PACKET));
  1338. SetupPacket.RequestType = USB_SETUP_REQUEST_TO_DEVICE |
  1339. USB_SETUP_REQUEST_STANDARD |
  1340. USB_SETUP_REQUEST_DEVICE_RECIPIENT;
  1341. SetupPacket.Request = USB_DEVICE_REQUEST_SET_ADDRESS;
  1342. SetupPacket.Value = FoundAddress;
  1343. SetupPacket.Index = 0;
  1344. SetupPacket.Length = 0;
  1345. Status = UsbSendControlTransfer(Device,
  1346. UsbTransferDirectionOut,
  1347. &SetupPacket,
  1348. NULL,
  1349. 0,
  1350. &LengthTransferred);
  1351. if (!KSUCCESS(Status)) {
  1352. goto AssignDeviceAddressEnd;
  1353. }
  1354. //
  1355. // Wait 2ms for the set address request to settle (see section 9.2.6.3 of
  1356. // the USB 2.0 specification).
  1357. //
  1358. HlBusySpin(2 * 1000);
  1359. Device->BusAddress = FoundAddress;
  1360. Status = STATUS_SUCCESS;
  1361. AssignDeviceAddressEnd:
  1362. //
  1363. // Release the address lock first before unassigning the address. That
  1364. // routine also acquires the lock.
  1365. //
  1366. if (AddressLockHeld != FALSE) {
  1367. KeReleaseQueuedLock(Controller->AddressLock);
  1368. }
  1369. if (!KSUCCESS(Status)) {
  1370. //
  1371. // Unassign the bus address if it was assigned.
  1372. //
  1373. if (FoundAddress != 0) {
  1374. UsbpUnassignDeviceAddress(Device);
  1375. }
  1376. }
  1377. return Status;
  1378. }
  1379. VOID
  1380. UsbpUnassignDeviceAddress (
  1381. PUSB_DEVICE Device
  1382. )
  1383. /*++
  1384. Routine Description:
  1385. This routine unassigns a USB device's address.
  1386. Arguments:
  1387. Device - Supplies a pointer to the USB device whose address is to be
  1388. unassigned.
  1389. Return Value:
  1390. None.
  1391. --*/
  1392. {
  1393. ULONG AddressIndex;
  1394. PUSB_HOST_CONTROLLER Controller;
  1395. PUSB_DEVICE *Segment;
  1396. BOOL SegmentEmpty;
  1397. ULONG SegmentIndex;
  1398. //
  1399. // There's nothing to do if the device never received an address.
  1400. //
  1401. if (Device->BusAddress == 0) {
  1402. return;
  1403. }
  1404. //
  1405. // Acquire the controller's address lock before releasing the address.
  1406. //
  1407. Controller = Device->Controller;
  1408. KeAcquireQueuedLock(Controller->AddressLock);
  1409. //
  1410. // Release the address and mark that the controller is not full.
  1411. //
  1412. SegmentIndex = Device->BusAddress / USB_HOST_ADDRESSES_PER_SEGMENT;
  1413. Segment = Controller->ChildrenByAddress[SegmentIndex];
  1414. Segment[Device->BusAddress % USB_HOST_ADDRESSES_PER_SEGMENT] = NULL;
  1415. Device->BusAddress = 0;
  1416. Controller->ControllerFull = FALSE;
  1417. //
  1418. // Loop through the segment addresses to determine if it is empty.
  1419. //
  1420. SegmentEmpty = TRUE;
  1421. for (AddressIndex = 0;
  1422. AddressIndex < USB_HOST_ADDRESSES_PER_SEGMENT;
  1423. AddressIndex += 1) {
  1424. //
  1425. // Skip address zero.
  1426. //
  1427. if ((SegmentIndex == 0) && (AddressIndex == 0)) {
  1428. continue;
  1429. }
  1430. //
  1431. // If the space is not free, declare that the segment is not empty.
  1432. //
  1433. if (Segment[AddressIndex] != NULL) {
  1434. SegmentEmpty = FALSE;
  1435. break;
  1436. }
  1437. }
  1438. //
  1439. // If the segment is empty, null it out.
  1440. //
  1441. if (SegmentEmpty != FALSE) {
  1442. Controller->ChildrenByAddress[SegmentIndex] = NULL;
  1443. }
  1444. //
  1445. // Release the address lock.
  1446. //
  1447. KeReleaseQueuedLock(Controller->AddressLock);
  1448. //
  1449. // With the lock released, free the segment if it was empty.
  1450. //
  1451. if (SegmentEmpty != FALSE) {
  1452. MmFreeNonPagedPool(Segment);
  1453. }
  1454. return;
  1455. }
  1456. KSTATUS
  1457. UsbpReadDeviceStrings (
  1458. PUSB_DEVICE Device,
  1459. PUSB_DEVICE_DESCRIPTOR DeviceDescriptor
  1460. )
  1461. /*++
  1462. Routine Description:
  1463. This routine attempts to read the manufacturer, product, and serial number
  1464. strings from the device, if they exist.
  1465. Arguments:
  1466. Device - Supplies a pointer to the device to assign an address to.
  1467. DeviceDescriptor - Supplies a pointer to the device descriptor (which
  1468. contains the string descriptor indices).
  1469. Return Value:
  1470. Status code. On success, the strings will be allocated and filled into the
  1471. device.
  1472. --*/
  1473. {
  1474. ULONG LanguageCount;
  1475. PUSHORT LanguageId;
  1476. ULONG LanguageIndex;
  1477. KSTATUS Status;
  1478. PUSB_STRING_DESCRIPTOR StringDescriptor;
  1479. BOOL UsEnglishSupported;
  1480. StringDescriptor = NULL;
  1481. //
  1482. // If none of the strings being sought exist, just exit.
  1483. //
  1484. if ((DeviceDescriptor->ManufacturerStringIndex == 0) &&
  1485. (DeviceDescriptor->ProductStringIndex == 0) &&
  1486. (DeviceDescriptor->SerialNumberStringIndex == 0)) {
  1487. Status = STATUS_SUCCESS;
  1488. goto ReadDeviceStringsEnd;
  1489. }
  1490. //
  1491. // Create a temporary string descriptor of the maximum possible size.
  1492. //
  1493. StringDescriptor = MmAllocateNonPagedPool(USB_STRING_DESCRIPTOR_MAX_SIZE,
  1494. USB_CORE_ALLOCATION_TAG);
  1495. if (StringDescriptor == NULL) {
  1496. Status = STATUS_INSUFFICIENT_RESOURCES;
  1497. goto ReadDeviceStringsEnd;
  1498. }
  1499. //
  1500. // Attempt to read string 0, which returns the list of supported languages.
  1501. //
  1502. Status = UsbReadDeviceString(Device, 0, 0, StringDescriptor);
  1503. if (!KSUCCESS(Status)) {
  1504. if ((UsbDebugFlags & (USB_DEBUG_ENUMERATION | USB_DEBUG_ERRORS)) != 0) {
  1505. RtlDebugPrint("USB: Device 0x%x failed to read language ID string "
  1506. "0.\n",
  1507. Device);
  1508. }
  1509. goto ReadDeviceStringsEnd;
  1510. }
  1511. LanguageCount = StringDescriptor->Length / 2;
  1512. LanguageId = (PUSHORT)(StringDescriptor + 1);
  1513. UsEnglishSupported = FALSE;
  1514. for (LanguageIndex = 0; LanguageIndex < LanguageCount; LanguageIndex += 1) {
  1515. if (LanguageId[LanguageIndex] == USB_LANGUAGE_ENGLISH_US) {
  1516. UsEnglishSupported = TRUE;
  1517. }
  1518. }
  1519. if (UsEnglishSupported == FALSE) {
  1520. if ((UsbDebugFlags & USB_DEBUG_ENUMERATION) != 0) {
  1521. RtlDebugPrint("USB: Device %x supports %d languages but US "
  1522. "English (0x0409) is not one of them. Skipping "
  1523. "device strings.\n",
  1524. Device);
  1525. Status = STATUS_SUCCESS;
  1526. goto ReadDeviceStringsEnd;
  1527. }
  1528. }
  1529. //
  1530. // Attempt to get the manufacturer string descriptor.
  1531. //
  1532. if (DeviceDescriptor->ManufacturerStringIndex != 0) {
  1533. Status = UsbReadDeviceString(Device,
  1534. DeviceDescriptor->ManufacturerStringIndex,
  1535. USB_LANGUAGE_ENGLISH_US,
  1536. StringDescriptor);
  1537. if (!KSUCCESS(Status)) {
  1538. goto ReadDeviceStringsEnd;
  1539. }
  1540. if (Device->Manufacturer != NULL) {
  1541. MmFreePagedPool(Device->Manufacturer);
  1542. }
  1543. Device->Manufacturer =
  1544. UsbpCreateAnsiStringFromStringDescriptor(StringDescriptor);
  1545. if (Device->Manufacturer == NULL) {
  1546. Status = STATUS_INSUFFICIENT_RESOURCES;
  1547. goto ReadDeviceStringsEnd;
  1548. }
  1549. }
  1550. //
  1551. // Attempt to get the product name string descriptor.
  1552. //
  1553. if (DeviceDescriptor->ProductStringIndex != 0) {
  1554. Status = UsbReadDeviceString(Device,
  1555. DeviceDescriptor->ProductStringIndex,
  1556. USB_LANGUAGE_ENGLISH_US,
  1557. StringDescriptor);
  1558. if (!KSUCCESS(Status)) {
  1559. goto ReadDeviceStringsEnd;
  1560. }
  1561. if (Device->ProductName != NULL) {
  1562. MmFreePagedPool(Device->ProductName);
  1563. }
  1564. Device->ProductName =
  1565. UsbpCreateAnsiStringFromStringDescriptor(StringDescriptor);
  1566. if (Device->ProductName == NULL) {
  1567. Status = STATUS_INSUFFICIENT_RESOURCES;
  1568. goto ReadDeviceStringsEnd;
  1569. }
  1570. }
  1571. //
  1572. // Attempt to get the serial number string descriptor.
  1573. //
  1574. if (DeviceDescriptor->SerialNumberStringIndex != 0) {
  1575. Status = UsbReadDeviceString(Device,
  1576. DeviceDescriptor->SerialNumberStringIndex,
  1577. USB_LANGUAGE_ENGLISH_US,
  1578. StringDescriptor);
  1579. if (!KSUCCESS(Status)) {
  1580. goto ReadDeviceStringsEnd;
  1581. }
  1582. if (Device->SerialNumber != NULL) {
  1583. MmFreePagedPool(Device->SerialNumber);
  1584. }
  1585. Device->SerialNumber =
  1586. UsbpCreateAnsiStringFromStringDescriptor(StringDescriptor);
  1587. if (Device->SerialNumber == NULL) {
  1588. Status = STATUS_INSUFFICIENT_RESOURCES;
  1589. goto ReadDeviceStringsEnd;
  1590. }
  1591. }
  1592. Status = STATUS_SUCCESS;
  1593. ReadDeviceStringsEnd:
  1594. if (KSUCCESS(Status)) {
  1595. if ((UsbDebugFlags & USB_DEBUG_ENUMERATION) != 0) {
  1596. RtlDebugPrint("USB: New Device VID: %04x, PID %04x, Class %d, "
  1597. "Address %d\nUSB: Manufacturer: \"%s\" Product Name: "
  1598. "\"%s\" Serial Number: \"%s\".\n",
  1599. DeviceDescriptor->VendorId,
  1600. DeviceDescriptor->ProductId,
  1601. DeviceDescriptor->Class,
  1602. Device->BusAddress,
  1603. Device->Manufacturer,
  1604. Device->ProductName,
  1605. Device->SerialNumber);
  1606. }
  1607. }
  1608. if (StringDescriptor != NULL) {
  1609. MmFreeNonPagedPool(StringDescriptor);
  1610. }
  1611. return Status;
  1612. }
  1613. PSTR
  1614. UsbpCreateAnsiStringFromStringDescriptor (
  1615. PUSB_STRING_DESCRIPTOR StringDescriptor
  1616. )
  1617. /*++
  1618. Routine Description:
  1619. This routine converts a unicode string descriptor into an ANSI string.
  1620. Arguments:
  1621. StringDescriptor - Supplies a pointer to the string descriptor to convert.
  1622. Return Value:
  1623. Returns a pointer to the string on success. The caller is responsible for
  1624. freeing this new string from paged pool.
  1625. NULL on failure.
  1626. --*/
  1627. {
  1628. ULONG Index;
  1629. ULONG Length;
  1630. PSTR NewString;
  1631. PSTR UnicodeString;
  1632. if ((StringDescriptor->Length < 2) ||
  1633. ((StringDescriptor->Length & 0x1) != 0)) {
  1634. return NULL;
  1635. }
  1636. Length = (StringDescriptor->Length / 2) - 1;
  1637. NewString = MmAllocatePagedPool(Length + 1, USB_CORE_ALLOCATION_TAG);
  1638. if (NewString == NULL) {
  1639. return NULL;
  1640. }
  1641. Index = 0;
  1642. UnicodeString = (PSTR)(StringDescriptor + 1);
  1643. while (Index < Length) {
  1644. NewString[Index] = *UnicodeString;
  1645. Index += 1;
  1646. UnicodeString += 2;
  1647. }
  1648. NewString[Index] = '\0';
  1649. return NewString;
  1650. }
  1651. VOID
  1652. UsbpGetDeviceClass (
  1653. PUSB_DEVICE Device,
  1654. PUCHAR Class,
  1655. PUCHAR Subclass,
  1656. PUCHAR Protocol
  1657. )
  1658. /*++
  1659. Routine Description:
  1660. This routine returns the given device's effective class, subclass, and
  1661. protocol identifiers. It will return information from the device descriptor
  1662. if it is filled in, or the first interface if there is only one
  1663. configuration and one interface.
  1664. Arguments:
  1665. Device - Supplies a pointer to the device to enumerate.
  1666. Class - Supplies a pointer where the class code will be returned.
  1667. Subclass - Supplies a pointer where the sub-class code will be returned.
  1668. Protocol - Supplies a pointer where the protocol code will be returned.
  1669. Return Value:
  1670. Status code.
  1671. --*/
  1672. {
  1673. UCHAR ClassCode;
  1674. PUSB_CONFIGURATION Configuration;
  1675. PUSB_INTERFACE_DESCRIPTION Interface;
  1676. PLIST_ENTRY InterfaceListHead;
  1677. UCHAR ProtocolCode;
  1678. UCHAR SubclassCode;
  1679. //
  1680. // If the class code in the device descriptor is set, use it. If it defers
  1681. // to the interfaces, look to see if there is only one interface. If so,
  1682. // use that one.
  1683. //
  1684. ClassCode = Device->ClassCode;
  1685. SubclassCode = Device->SubclassCode;
  1686. ProtocolCode = Device->ProtocolCode;
  1687. if (ClassCode == UsbDeviceClassUseInterface) {
  1688. ASSERT(LIST_EMPTY(&(Device->ConfigurationList)) == FALSE);
  1689. Configuration = LIST_VALUE(Device->ConfigurationList.Next,
  1690. USB_CONFIGURATION,
  1691. ListEntry);
  1692. InterfaceListHead = &(Configuration->Description.InterfaceListHead);
  1693. ASSERT(LIST_EMPTY(InterfaceListHead) == FALSE);
  1694. //
  1695. // If there's only one interface on the list, use it.
  1696. //
  1697. if (InterfaceListHead->Next == InterfaceListHead->Previous) {
  1698. Interface = LIST_VALUE(InterfaceListHead->Next,
  1699. USB_INTERFACE_DESCRIPTION,
  1700. ListEntry);
  1701. ClassCode = Interface->Descriptor.Class;
  1702. SubclassCode = Interface->Descriptor.Subclass;
  1703. ProtocolCode = Interface->Descriptor.Protocol;
  1704. //
  1705. // Also save these back directly into the device.
  1706. //
  1707. Device->ClassCode = ClassCode;
  1708. Device->SubclassCode = SubclassCode;
  1709. Device->ProtocolCode = ProtocolCode;
  1710. }
  1711. }
  1712. *Class = ClassCode;
  1713. *Subclass = SubclassCode;
  1714. *Protocol = ProtocolCode;
  1715. return;
  1716. }
  1717. KSTATUS
  1718. UsbpCreateOsDevice (
  1719. PUSB_DEVICE Device,
  1720. UCHAR Class,
  1721. UCHAR Subclass,
  1722. UCHAR Protocol,
  1723. UCHAR Interface,
  1724. BOOL InterfaceDevice,
  1725. PDEVICE *CreatedDevice
  1726. )
  1727. /*++
  1728. Routine Description:
  1729. This routine creates an operating system device object for the given USB
  1730. object.
  1731. Arguments:
  1732. Device - Supplies a pointer to the USB device corresponding to the soon-to-
  1733. be-created OS device.
  1734. Class - Supplies the USB device class code of the new device.
  1735. Subclass - Supplies the USB subclass code of the new device.
  1736. Protocol - Supplies the USB protocol code of the new device.
  1737. Interface - Supplies an optional interface number for the device. If the
  1738. interface device boolean flag is false, this parameter is ignored.
  1739. InterfaceDevice - Supplies a boolean indicating if this device is just
  1740. enumerating an interface off a pre-existing device, or if it's
  1741. enumerating the device itself. For interface devies, the interface
  1742. number is tacked onto the device ID.
  1743. CreatedDevice - Supplies a pointer where the pointer to the fresh OS
  1744. device will be returned.
  1745. Return Value:
  1746. Status code.
  1747. --*/
  1748. {
  1749. PSTR DeviceClass;
  1750. CHAR DeviceId[USB_DEVICE_ID_LENGTH + 1];
  1751. PDRIVER Driver;
  1752. PDEVICE Parent;
  1753. KSTATUS Status;
  1754. *CreatedDevice = NULL;
  1755. //
  1756. // Create the device ID string.
  1757. //
  1758. if (InterfaceDevice != FALSE) {
  1759. RtlPrintToString(DeviceId,
  1760. USB_DEVICE_ID_LENGTH + 1,
  1761. CharacterEncodingDefault,
  1762. USB_DEVICE_ID_WITH_INTERFACE_FORMAT,
  1763. Device->VendorId,
  1764. Device->ProductId,
  1765. Interface);
  1766. } else {
  1767. RtlPrintToString(DeviceId,
  1768. USB_DEVICE_ID_LENGTH + 1,
  1769. CharacterEncodingDefault,
  1770. USB_DEVICE_ID_FORMAT,
  1771. Device->VendorId,
  1772. Device->ProductId);
  1773. }
  1774. //
  1775. // Set the class ID if applicable.
  1776. //
  1777. switch (Class) {
  1778. case UsbDeviceClassUseInterface:
  1779. DeviceClass = USB_COMPOUND_DEVICE_CLASS_ID;
  1780. break;
  1781. case UsbDeviceClassHid:
  1782. DeviceClass = USB_HID_CLASS_ID;
  1783. if ((Subclass == USB_HID_BOOT_INTERFACE_SUBCLASS) &&
  1784. (Protocol == USB_HID_BOOT_KEYBOARD_PROTOCOL)) {
  1785. DeviceClass = USB_BOOT_KEYBOARD_CLASS_ID;
  1786. } else if ((Subclass == USB_HID_BOOT_INTERFACE_SUBCLASS) &&
  1787. (Protocol == USB_HID_BOOT_MOUSE_PROTOCOL)) {
  1788. DeviceClass = USB_BOOT_MOUSE_CLASS_ID;
  1789. }
  1790. break;
  1791. case UsbInterfaceClassMassStorage:
  1792. DeviceClass = USB_MASS_STORAGE_CLASS_ID;
  1793. break;
  1794. case UsbDeviceClassHub:
  1795. DeviceClass = USB_HUB_CLASS_ID;
  1796. break;
  1797. default:
  1798. DeviceClass = NULL;
  1799. break;
  1800. }
  1801. //
  1802. // For interface devices, the device itself is the parent.
  1803. //
  1804. if (InterfaceDevice != FALSE) {
  1805. Driver = Device->Driver;
  1806. Parent = Device->Device;
  1807. } else {
  1808. ASSERT(Device->Parent != NULL);
  1809. Driver = Device->Parent->Driver;
  1810. Parent = Device->Parent->Device;
  1811. }
  1812. ASSERT((Driver != NULL) && (Parent != NULL));
  1813. //
  1814. // Create the OS device object, making the device visible to the system.
  1815. //
  1816. Status = IoCreateDevice(Driver,
  1817. NULL,
  1818. Parent,
  1819. DeviceId,
  1820. DeviceClass,
  1821. NULL,
  1822. CreatedDevice);
  1823. if (!KSUCCESS(Status)) {
  1824. goto CreateOsDeviceEnd;
  1825. }
  1826. Status = STATUS_SUCCESS;
  1827. CreateOsDeviceEnd:
  1828. return Status;
  1829. }
  1830. UCHAR
  1831. UsbpGetReservedDeviceAddress (
  1832. PUSB_DEVICE Device
  1833. )
  1834. /*++
  1835. Routine Description:
  1836. This routine returns the device's reserved address if it is a special
  1837. device. The debug device and debug device hub both have reserved addresses
  1838. since they're being used up in debugger land.
  1839. Arguments:
  1840. Device - Supplies a pointer to the device whose address is being assigned.
  1841. Return Value:
  1842. Returns the device's reserved address on success.
  1843. 0 if the device does not have a reserved address.
  1844. --*/
  1845. {
  1846. PUSB_DEVICE CheckDevice;
  1847. ULONG CheckIndex;
  1848. PUSB_HOST_CONTROLLER Controller;
  1849. PDEBUG_USB_HANDOFF_DATA HandoffData;
  1850. ULONG PathIndex;
  1851. Controller = Device->Controller;
  1852. if (Controller->HandoffData == NULL) {
  1853. return 0;
  1854. }
  1855. HandoffData = &(Controller->HandoffData->U.Usb);
  1856. //
  1857. // If this is not the debug device itself or the hub of the debug device,
  1858. // then the device is not special.
  1859. //
  1860. ASSERT(Device->Depth != 0);
  1861. PathIndex = Device->Depth - 1;
  1862. if ((PathIndex != HandoffData->DevicePathSize - 1) &&
  1863. (PathIndex != HandoffData->DevicePathSize - 2)) {
  1864. return 0;
  1865. }
  1866. if ((UsbDebugFlags & USB_DEBUG_DEBUGGER_HANDOFF) != 0) {
  1867. RtlDebugPrint("USB: Checking device %04X:%04X against debugger "
  1868. "device path.\n",
  1869. Device->VendorId,
  1870. Device->ProductId);
  1871. }
  1872. CheckIndex = PathIndex;
  1873. CheckDevice = Device;
  1874. while (TRUE) {
  1875. //
  1876. // If the device's hub address is not equal to the debug device path,
  1877. // exit.
  1878. //
  1879. if (CheckDevice->PortNumber != HandoffData->DevicePath[CheckIndex]) {
  1880. return 0;
  1881. }
  1882. if (CheckIndex == 0) {
  1883. break;
  1884. }
  1885. CheckIndex -= 1;
  1886. CheckDevice = CheckDevice->Parent;
  1887. }
  1888. //
  1889. // The path lines up, this is either the debug device itself or the hub.
  1890. //
  1891. if (PathIndex == HandoffData->DevicePathSize - 1) {
  1892. if ((UsbDebugFlags & USB_DEBUG_DEBUGGER_HANDOFF) != 0) {
  1893. RtlDebugPrint("USB: Found debugger device %x! Assigning "
  1894. "address %x\n",
  1895. Device,
  1896. HandoffData->DeviceAddress);
  1897. }
  1898. if ((Device->VendorId != HandoffData->VendorId) ||
  1899. (Device->ProductId != HandoffData->ProductId)) {
  1900. RtlDebugPrint("USB: Found VID:PID %04X:%04X at debug device path, "
  1901. "expected %04X:%04x.\n",
  1902. Device->VendorId,
  1903. Device->ProductId,
  1904. HandoffData->VendorId,
  1905. HandoffData->ProductId);
  1906. return 0;
  1907. }
  1908. Device->DebugDevice = TRUE;
  1909. return HandoffData->DeviceAddress;
  1910. }
  1911. //
  1912. // If there's a hub address, return that.
  1913. //
  1914. if ((UsbDebugFlags & USB_DEBUG_DEBUGGER_HANDOFF) != 0) {
  1915. RtlDebugPrint("USB: Found debugger hub %x. Assigning "
  1916. "address %x\n",
  1917. Device,
  1918. HandoffData->HubAddress);
  1919. }
  1920. return HandoffData->HubAddress;
  1921. }