enum.c 63 KB

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