1*8a978a17SVictor Perevertkin /*++
2*8a978a17SVictor Perevertkin 
3*8a978a17SVictor Perevertkin Copyright (c) Microsoft Corporation
4*8a978a17SVictor Perevertkin 
5*8a978a17SVictor Perevertkin Module Name:
6*8a978a17SVictor Perevertkin 
7*8a978a17SVictor Perevertkin     FxUsbDeviceAPI.cpp
8*8a978a17SVictor Perevertkin 
9*8a978a17SVictor Perevertkin Abstract:
10*8a978a17SVictor Perevertkin 
11*8a978a17SVictor Perevertkin 
12*8a978a17SVictor Perevertkin Author:
13*8a978a17SVictor Perevertkin 
14*8a978a17SVictor Perevertkin Environment:
15*8a978a17SVictor Perevertkin 
16*8a978a17SVictor Perevertkin     kernel mode only
17*8a978a17SVictor Perevertkin 
18*8a978a17SVictor Perevertkin Revision History:
19*8a978a17SVictor Perevertkin 
20*8a978a17SVictor Perevertkin --*/
21*8a978a17SVictor Perevertkin 
22*8a978a17SVictor Perevertkin #include "fxusbpch.hpp"
23*8a978a17SVictor Perevertkin 
24*8a978a17SVictor Perevertkin extern "C" {
25*8a978a17SVictor Perevertkin #include "FxUsbDeviceApiKm.tmh"
26*8a978a17SVictor Perevertkin }
27*8a978a17SVictor Perevertkin 
28*8a978a17SVictor Perevertkin //
29*8a978a17SVictor Perevertkin // Extern "C" all APIs
30*8a978a17SVictor Perevertkin //
31*8a978a17SVictor Perevertkin extern "C" {
32*8a978a17SVictor Perevertkin 
33*8a978a17SVictor Perevertkin _Must_inspect_result_
__drv_maxIRQL(DISPATCH_LEVEL)34*8a978a17SVictor Perevertkin __drv_maxIRQL(DISPATCH_LEVEL)
35*8a978a17SVictor Perevertkin NTSTATUS
36*8a978a17SVictor Perevertkin WDFAPI
37*8a978a17SVictor Perevertkin WDFEXPORT(WdfUsbTargetDeviceRetrieveCurrentFrameNumber)(
38*8a978a17SVictor Perevertkin     __in
39*8a978a17SVictor Perevertkin     PWDF_DRIVER_GLOBALS DriverGlobals,
40*8a978a17SVictor Perevertkin     __in
41*8a978a17SVictor Perevertkin     WDFUSBDEVICE UsbDevice,
42*8a978a17SVictor Perevertkin     __out
43*8a978a17SVictor Perevertkin     PULONG CurrentFrameNumber
44*8a978a17SVictor Perevertkin     )
45*8a978a17SVictor Perevertkin {
46*8a978a17SVictor Perevertkin     DDI_ENTRY();
47*8a978a17SVictor Perevertkin 
48*8a978a17SVictor Perevertkin     PFX_DRIVER_GLOBALS pFxDriverGlobals;
49*8a978a17SVictor Perevertkin     FxUsbDevice* pUsbDevice;
50*8a978a17SVictor Perevertkin 
51*8a978a17SVictor Perevertkin     FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals),
52*8a978a17SVictor Perevertkin                                    UsbDevice,
53*8a978a17SVictor Perevertkin                                    FX_TYPE_IO_TARGET_USB_DEVICE,
54*8a978a17SVictor Perevertkin                                    (PVOID*) &pUsbDevice,
55*8a978a17SVictor Perevertkin                                    &pFxDriverGlobals);
56*8a978a17SVictor Perevertkin 
57*8a978a17SVictor Perevertkin     FxPointerNotNull(pFxDriverGlobals, CurrentFrameNumber);
58*8a978a17SVictor Perevertkin 
59*8a978a17SVictor Perevertkin     return pUsbDevice->GetCurrentFrameNumber(CurrentFrameNumber);
60*8a978a17SVictor Perevertkin }
61*8a978a17SVictor Perevertkin 
62*8a978a17SVictor Perevertkin _Must_inspect_result_
__drv_maxIRQL(PASSIVE_LEVEL)63*8a978a17SVictor Perevertkin __drv_maxIRQL(PASSIVE_LEVEL)
64*8a978a17SVictor Perevertkin NTSTATUS
65*8a978a17SVictor Perevertkin WDFAPI
66*8a978a17SVictor Perevertkin WDFEXPORT(WdfUsbTargetDeviceSendUrbSynchronously)(
67*8a978a17SVictor Perevertkin     __in
68*8a978a17SVictor Perevertkin     PWDF_DRIVER_GLOBALS DriverGlobals,
69*8a978a17SVictor Perevertkin     __in
70*8a978a17SVictor Perevertkin     WDFUSBDEVICE UsbDevice,
71*8a978a17SVictor Perevertkin     __in_opt
72*8a978a17SVictor Perevertkin     WDFREQUEST Request,
73*8a978a17SVictor Perevertkin     __in_opt
74*8a978a17SVictor Perevertkin     PWDF_REQUEST_SEND_OPTIONS RequestOptions,
75*8a978a17SVictor Perevertkin     __in_xcount("union bug in SAL")
76*8a978a17SVictor Perevertkin     PURB Urb
77*8a978a17SVictor Perevertkin     )
78*8a978a17SVictor Perevertkin {
79*8a978a17SVictor Perevertkin     PFX_DRIVER_GLOBALS pFxDriverGlobals;
80*8a978a17SVictor Perevertkin     FxRequestBuffer buf;
81*8a978a17SVictor Perevertkin     NTSTATUS status;
82*8a978a17SVictor Perevertkin     FxUsbDevice* pUsbDevice;
83*8a978a17SVictor Perevertkin 
84*8a978a17SVictor Perevertkin     FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals),
85*8a978a17SVictor Perevertkin                                    UsbDevice,
86*8a978a17SVictor Perevertkin                                    FX_TYPE_IO_TARGET_USB_DEVICE,
87*8a978a17SVictor Perevertkin                                    (PVOID*) &pUsbDevice,
88*8a978a17SVictor Perevertkin                                    &pFxDriverGlobals);
89*8a978a17SVictor Perevertkin 
90*8a978a17SVictor Perevertkin     FxUsbUrbContext context;
91*8a978a17SVictor Perevertkin     FxSyncRequest request(pFxDriverGlobals, &context, Request);
92*8a978a17SVictor Perevertkin 
93*8a978a17SVictor Perevertkin     //
94*8a978a17SVictor Perevertkin     // FxSyncRequest always succeesds for KM but can fail for UM.
95*8a978a17SVictor Perevertkin     //
96*8a978a17SVictor Perevertkin     status = request.Initialize();
97*8a978a17SVictor Perevertkin     if (!NT_SUCCESS(status)) {
98*8a978a17SVictor Perevertkin         DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGIOTARGET,
99*8a978a17SVictor Perevertkin                             "Failed to initialize FxSyncRequest");
100*8a978a17SVictor Perevertkin         return status;
101*8a978a17SVictor Perevertkin     }
102*8a978a17SVictor Perevertkin 
103*8a978a17SVictor Perevertkin     DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGIOTARGET,
104*8a978a17SVictor Perevertkin                         "WDFUSBDEVICE %p, Urb %p", UsbDevice, Urb);
105*8a978a17SVictor Perevertkin 
106*8a978a17SVictor Perevertkin     FxPointerNotNull(pFxDriverGlobals, Urb);
107*8a978a17SVictor Perevertkin 
108*8a978a17SVictor Perevertkin     status = FxVerifierCheckIrqlLevel(pFxDriverGlobals, PASSIVE_LEVEL);
109*8a978a17SVictor Perevertkin     if (!NT_SUCCESS(status)) {
110*8a978a17SVictor Perevertkin         return status;
111*8a978a17SVictor Perevertkin     }
112*8a978a17SVictor Perevertkin 
113*8a978a17SVictor Perevertkin     status = FxValidateRequestOptions(pFxDriverGlobals, RequestOptions);
114*8a978a17SVictor Perevertkin     if (!NT_SUCCESS(status)) {
115*8a978a17SVictor Perevertkin         return status;
116*8a978a17SVictor Perevertkin     }
117*8a978a17SVictor Perevertkin 
118*8a978a17SVictor Perevertkin     buf.SetBuffer(Urb, 0);
119*8a978a17SVictor Perevertkin 
120*8a978a17SVictor Perevertkin     status = FxFormatUrbRequest(pFxDriverGlobals,
121*8a978a17SVictor Perevertkin                                 pUsbDevice,
122*8a978a17SVictor Perevertkin                                 request.m_TrueRequest,
123*8a978a17SVictor Perevertkin                                 &buf,
124*8a978a17SVictor Perevertkin                                 pUsbDevice->GetUrbType(),
125*8a978a17SVictor Perevertkin                                 pUsbDevice->GetUSBDHandle());
126*8a978a17SVictor Perevertkin 
127*8a978a17SVictor Perevertkin     if (NT_SUCCESS(status)) {
128*8a978a17SVictor Perevertkin         DoTraceLevelMessage(
129*8a978a17SVictor Perevertkin             pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGIOTARGET,
130*8a978a17SVictor Perevertkin             "WDFUSBDEVICE %p, WDFREQUEST %p being submitted",
131*8a978a17SVictor Perevertkin             UsbDevice, request.m_TrueRequest->GetTraceObjectHandle());
132*8a978a17SVictor Perevertkin 
133*8a978a17SVictor Perevertkin         status = pUsbDevice->SubmitSync(request.m_TrueRequest, RequestOptions);
134*8a978a17SVictor Perevertkin     }
135*8a978a17SVictor Perevertkin 
136*8a978a17SVictor Perevertkin     DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGIOTARGET,
137*8a978a17SVictor Perevertkin                         "Device %p, Urb %p, %!STATUS!",
138*8a978a17SVictor Perevertkin                         UsbDevice, Urb, status);
139*8a978a17SVictor Perevertkin 
140*8a978a17SVictor Perevertkin     return status;
141*8a978a17SVictor Perevertkin }
142*8a978a17SVictor Perevertkin 
143*8a978a17SVictor Perevertkin _Must_inspect_result_
__drv_maxIRQL(DISPATCH_LEVEL)144*8a978a17SVictor Perevertkin __drv_maxIRQL(DISPATCH_LEVEL)
145*8a978a17SVictor Perevertkin NTSTATUS
146*8a978a17SVictor Perevertkin WDFAPI
147*8a978a17SVictor Perevertkin WDFEXPORT(WdfUsbTargetDeviceFormatRequestForUrb)(
148*8a978a17SVictor Perevertkin     __in
149*8a978a17SVictor Perevertkin     PWDF_DRIVER_GLOBALS DriverGlobals,
150*8a978a17SVictor Perevertkin     __in
151*8a978a17SVictor Perevertkin     WDFUSBDEVICE UsbDevice,
152*8a978a17SVictor Perevertkin     __in
153*8a978a17SVictor Perevertkin     WDFREQUEST Request,
154*8a978a17SVictor Perevertkin     __in
155*8a978a17SVictor Perevertkin     WDFMEMORY UrbMemory,
156*8a978a17SVictor Perevertkin     __in_opt
157*8a978a17SVictor Perevertkin     PWDFMEMORY_OFFSET UrbOffsets
158*8a978a17SVictor Perevertkin     )
159*8a978a17SVictor Perevertkin {
160*8a978a17SVictor Perevertkin     DDI_ENTRY();
161*8a978a17SVictor Perevertkin 
162*8a978a17SVictor Perevertkin     PFX_DRIVER_GLOBALS pFxDriverGlobals;
163*8a978a17SVictor Perevertkin     IFxMemory* pMemory;
164*8a978a17SVictor Perevertkin     FxUsbDevice* pUsbDevice;
165*8a978a17SVictor Perevertkin     FxRequestBuffer buf;
166*8a978a17SVictor Perevertkin     FxRequest* pRequest;
167*8a978a17SVictor Perevertkin     NTSTATUS status;
168*8a978a17SVictor Perevertkin     size_t bufferSize;
169*8a978a17SVictor Perevertkin 
170*8a978a17SVictor Perevertkin     FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals),
171*8a978a17SVictor Perevertkin                                    UsbDevice,
172*8a978a17SVictor Perevertkin                                    FX_TYPE_IO_TARGET_USB_DEVICE,
173*8a978a17SVictor Perevertkin                                    (PVOID*) &pUsbDevice,
174*8a978a17SVictor Perevertkin                                    &pFxDriverGlobals);
175*8a978a17SVictor Perevertkin 
176*8a978a17SVictor Perevertkin     DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGIOTARGET,
177*8a978a17SVictor Perevertkin                         "WDFUSBDEVICE %p, Request %p, Memory %p",
178*8a978a17SVictor Perevertkin                         UsbDevice, Request, UrbMemory);
179*8a978a17SVictor Perevertkin 
180*8a978a17SVictor Perevertkin     FxPointerNotNull(pFxDriverGlobals, UrbMemory);
181*8a978a17SVictor Perevertkin 
182*8a978a17SVictor Perevertkin     FxObjectHandleGetPtr(pFxDriverGlobals,
183*8a978a17SVictor Perevertkin                          UrbMemory,
184*8a978a17SVictor Perevertkin                          IFX_TYPE_MEMORY,
185*8a978a17SVictor Perevertkin                          (PVOID*) &pMemory);
186*8a978a17SVictor Perevertkin 
187*8a978a17SVictor Perevertkin     FxObjectHandleGetPtr(pFxDriverGlobals,
188*8a978a17SVictor Perevertkin                          Request,
189*8a978a17SVictor Perevertkin                          FX_TYPE_REQUEST,
190*8a978a17SVictor Perevertkin                          (PVOID*) &pRequest);
191*8a978a17SVictor Perevertkin 
192*8a978a17SVictor Perevertkin     status = pMemory->ValidateMemoryOffsets(UrbOffsets);
193*8a978a17SVictor Perevertkin     if (!NT_SUCCESS(status)) {
194*8a978a17SVictor Perevertkin         return status;
195*8a978a17SVictor Perevertkin     }
196*8a978a17SVictor Perevertkin 
197*8a978a17SVictor Perevertkin     bufferSize = pMemory->GetBufferSize();
198*8a978a17SVictor Perevertkin     if (UrbOffsets != NULL && UrbOffsets->BufferOffset > 0) {
199*8a978a17SVictor Perevertkin         bufferSize -= UrbOffsets->BufferOffset;
200*8a978a17SVictor Perevertkin     }
201*8a978a17SVictor Perevertkin 
202*8a978a17SVictor Perevertkin     if (bufferSize < sizeof(_URB_HEADER)) {
203*8a978a17SVictor Perevertkin         status = STATUS_INVALID_PARAMETER;
204*8a978a17SVictor Perevertkin         DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGIOTARGET,
205*8a978a17SVictor Perevertkin                             "UrbMemory %p buffer size, %I64d, smaller then"
206*8a978a17SVictor Perevertkin                             "_URB_HEADER, %!STATUS!",
207*8a978a17SVictor Perevertkin                              UrbMemory, pMemory->GetBufferSize(), status);
208*8a978a17SVictor Perevertkin         return status;
209*8a978a17SVictor Perevertkin     }
210*8a978a17SVictor Perevertkin 
211*8a978a17SVictor Perevertkin     buf.SetMemory(pMemory, UrbOffsets);
212*8a978a17SVictor Perevertkin 
213*8a978a17SVictor Perevertkin     status = FxFormatUrbRequest(pFxDriverGlobals,
214*8a978a17SVictor Perevertkin                                 pUsbDevice,
215*8a978a17SVictor Perevertkin                                 pRequest,
216*8a978a17SVictor Perevertkin                                 &buf,
217*8a978a17SVictor Perevertkin                                 pUsbDevice->GetUrbType(),
218*8a978a17SVictor Perevertkin                                 pUsbDevice->GetUSBDHandle());
219*8a978a17SVictor Perevertkin 
220*8a978a17SVictor Perevertkin     if (NT_SUCCESS(status)) {
221*8a978a17SVictor Perevertkin         FxUsbUrbContext* pContext;
222*8a978a17SVictor Perevertkin         pContext = (FxUsbUrbContext*) pRequest->GetContext();
223*8a978a17SVictor Perevertkin 
224*8a978a17SVictor Perevertkin         pContext->SetUsbType(WdfUsbRequestTypeDeviceUrb);
225*8a978a17SVictor Perevertkin         pContext->m_UsbParameters.Parameters.DeviceUrb.Buffer = UrbMemory;
226*8a978a17SVictor Perevertkin     }
227*8a978a17SVictor Perevertkin 
228*8a978a17SVictor Perevertkin     DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGIOTARGET,
229*8a978a17SVictor Perevertkin                         "WDFUSBDEVICE %p, Request %p, Memory %p, %!STATUS!",
230*8a978a17SVictor Perevertkin                         UsbDevice, Request, UrbMemory, status);
231*8a978a17SVictor Perevertkin 
232*8a978a17SVictor Perevertkin     return status;
233*8a978a17SVictor Perevertkin }
234*8a978a17SVictor Perevertkin 
235*8a978a17SVictor Perevertkin _Must_inspect_result_
__drv_maxIRQL(PASSIVE_LEVEL)236*8a978a17SVictor Perevertkin __drv_maxIRQL(PASSIVE_LEVEL)
237*8a978a17SVictor Perevertkin NTSTATUS
238*8a978a17SVictor Perevertkin WDFAPI
239*8a978a17SVictor Perevertkin WDFEXPORT(WdfUsbTargetDeviceIsConnectedSynchronous)(
240*8a978a17SVictor Perevertkin     __in
241*8a978a17SVictor Perevertkin     PWDF_DRIVER_GLOBALS DriverGlobals,
242*8a978a17SVictor Perevertkin     __in
243*8a978a17SVictor Perevertkin     WDFUSBDEVICE UsbDevice
244*8a978a17SVictor Perevertkin     )
245*8a978a17SVictor Perevertkin {
246*8a978a17SVictor Perevertkin     DDI_ENTRY();
247*8a978a17SVictor Perevertkin 
248*8a978a17SVictor Perevertkin     PFX_DRIVER_GLOBALS pFxDriverGlobals;
249*8a978a17SVictor Perevertkin     FxUsbDevice* pUsbDevice;
250*8a978a17SVictor Perevertkin     NTSTATUS status;
251*8a978a17SVictor Perevertkin 
252*8a978a17SVictor Perevertkin     FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals),
253*8a978a17SVictor Perevertkin                                    UsbDevice,
254*8a978a17SVictor Perevertkin                                    FX_TYPE_IO_TARGET_USB_DEVICE,
255*8a978a17SVictor Perevertkin                                    (PVOID*) &pUsbDevice,
256*8a978a17SVictor Perevertkin                                    &pFxDriverGlobals);
257*8a978a17SVictor Perevertkin 
258*8a978a17SVictor Perevertkin     status = FxVerifierCheckIrqlLevel(pFxDriverGlobals, PASSIVE_LEVEL);
259*8a978a17SVictor Perevertkin     if (!NT_SUCCESS(status)) {
260*8a978a17SVictor Perevertkin         return status;
261*8a978a17SVictor Perevertkin     }
262*8a978a17SVictor Perevertkin 
263*8a978a17SVictor Perevertkin     status = pUsbDevice->IsConnected();
264*8a978a17SVictor Perevertkin 
265*8a978a17SVictor Perevertkin     return status;
266*8a978a17SVictor Perevertkin }
267*8a978a17SVictor Perevertkin 
268*8a978a17SVictor Perevertkin _Must_inspect_result_
__drv_maxIRQL(PASSIVE_LEVEL)269*8a978a17SVictor Perevertkin __drv_maxIRQL(PASSIVE_LEVEL)
270*8a978a17SVictor Perevertkin NTSTATUS
271*8a978a17SVictor Perevertkin WDFEXPORT(WdfUsbTargetDeviceCyclePortSynchronously)(
272*8a978a17SVictor Perevertkin     __in
273*8a978a17SVictor Perevertkin     PWDF_DRIVER_GLOBALS DriverGlobals,
274*8a978a17SVictor Perevertkin     __in
275*8a978a17SVictor Perevertkin     WDFUSBDEVICE UsbDevice
276*8a978a17SVictor Perevertkin     )
277*8a978a17SVictor Perevertkin /*++
278*8a978a17SVictor Perevertkin 
279*8a978a17SVictor Perevertkin Routine Description:
280*8a978a17SVictor Perevertkin     Synchronously cycles a device on a USB port.  This will cause the device
281*8a978a17SVictor Perevertkin     to be surprise removed and reenumerated.  Very similar to the reenumerate
282*8a978a17SVictor Perevertkin     interface we use in the pnp state machine.  Usually a driver will do this
283*8a978a17SVictor Perevertkin     after it has downloaded firmware and wants to be reenumerated as a new
284*8a978a17SVictor Perevertkin     device.
285*8a978a17SVictor Perevertkin 
286*8a978a17SVictor Perevertkin 
287*8a978a17SVictor Perevertkin 
288*8a978a17SVictor Perevertkin 
289*8a978a17SVictor Perevertkin Arguments:
290*8a978a17SVictor Perevertkin     UsbDevice - the IOTARGET representing the device
291*8a978a17SVictor Perevertkin 
292*8a978a17SVictor Perevertkin Return Value:
293*8a978a17SVictor Perevertkin     NTSTATUS
294*8a978a17SVictor Perevertkin 
295*8a978a17SVictor Perevertkin   --*/
296*8a978a17SVictor Perevertkin {
297*8a978a17SVictor Perevertkin     DDI_ENTRY();
298*8a978a17SVictor Perevertkin 
299*8a978a17SVictor Perevertkin     PFX_DRIVER_GLOBALS pFxDriverGlobals;
300*8a978a17SVictor Perevertkin     FxUsbDevice* pUsbDevice;
301*8a978a17SVictor Perevertkin     NTSTATUS status;
302*8a978a17SVictor Perevertkin 
303*8a978a17SVictor Perevertkin     FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals),
304*8a978a17SVictor Perevertkin                                    UsbDevice,
305*8a978a17SVictor Perevertkin                                    FX_TYPE_IO_TARGET_USB_DEVICE,
306*8a978a17SVictor Perevertkin                                    (PVOID*) &pUsbDevice,
307*8a978a17SVictor Perevertkin                                    &pFxDriverGlobals);
308*8a978a17SVictor Perevertkin 
309*8a978a17SVictor Perevertkin     status = FxVerifierCheckIrqlLevel(pFxDriverGlobals, PASSIVE_LEVEL);
310*8a978a17SVictor Perevertkin     if (!NT_SUCCESS(status)) {
311*8a978a17SVictor Perevertkin         return status;
312*8a978a17SVictor Perevertkin     }
313*8a978a17SVictor Perevertkin 
314*8a978a17SVictor Perevertkin     status = pUsbDevice->CyclePort();
315*8a978a17SVictor Perevertkin 
316*8a978a17SVictor Perevertkin     return status;
317*8a978a17SVictor Perevertkin }
318*8a978a17SVictor Perevertkin 
319*8a978a17SVictor Perevertkin _Must_inspect_result_
__drv_maxIRQL(DISPATCH_LEVEL)320*8a978a17SVictor Perevertkin __drv_maxIRQL(DISPATCH_LEVEL)
321*8a978a17SVictor Perevertkin NTSTATUS
322*8a978a17SVictor Perevertkin WDFEXPORT(WdfUsbTargetDeviceFormatRequestForCyclePort)(
323*8a978a17SVictor Perevertkin     __in
324*8a978a17SVictor Perevertkin     PWDF_DRIVER_GLOBALS DriverGlobals,
325*8a978a17SVictor Perevertkin     __in
326*8a978a17SVictor Perevertkin     WDFUSBDEVICE UsbDevice,
327*8a978a17SVictor Perevertkin     __in
328*8a978a17SVictor Perevertkin     WDFREQUEST Request
329*8a978a17SVictor Perevertkin     )
330*8a978a17SVictor Perevertkin /*++
331*8a978a17SVictor Perevertkin 
332*8a978a17SVictor Perevertkin Routine Description:
333*8a978a17SVictor Perevertkin     Formats a WDFREQUEST so that it will cycle the port and reenumerate the
334*8a978a17SVictor Perevertkin     device when sent.
335*8a978a17SVictor Perevertkin 
336*8a978a17SVictor Perevertkin Arguments:
337*8a978a17SVictor Perevertkin     UsbDevice - the IOTARGET representing the device that will be reenumerated
338*8a978a17SVictor Perevertkin 
339*8a978a17SVictor Perevertkin     Request - the request which will be formatted
340*8a978a17SVictor Perevertkin 
341*8a978a17SVictor Perevertkin Return Value:
342*8a978a17SVictor Perevertkin     NTSTATUS
343*8a978a17SVictor Perevertkin 
344*8a978a17SVictor Perevertkin   --*/
345*8a978a17SVictor Perevertkin {
346*8a978a17SVictor Perevertkin     DDI_ENTRY();
347*8a978a17SVictor Perevertkin 
348*8a978a17SVictor Perevertkin     PFX_DRIVER_GLOBALS pFxDriverGlobals;
349*8a978a17SVictor Perevertkin     FxUsbDevice* pUsbDevice;
350*8a978a17SVictor Perevertkin     FxRequest* pRequest;
351*8a978a17SVictor Perevertkin     NTSTATUS status;
352*8a978a17SVictor Perevertkin 
353*8a978a17SVictor Perevertkin     FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals),
354*8a978a17SVictor Perevertkin                                    UsbDevice,
355*8a978a17SVictor Perevertkin                                    FX_TYPE_IO_TARGET_USB_DEVICE,
356*8a978a17SVictor Perevertkin                                    (PVOID*) &pUsbDevice,
357*8a978a17SVictor Perevertkin                                    &pFxDriverGlobals);
358*8a978a17SVictor Perevertkin 
359*8a978a17SVictor Perevertkin     FxObjectHandleGetPtr(pFxDriverGlobals,
360*8a978a17SVictor Perevertkin                          Request,
361*8a978a17SVictor Perevertkin                          FX_TYPE_REQUEST,
362*8a978a17SVictor Perevertkin                          (PVOID*) &pRequest);
363*8a978a17SVictor Perevertkin 
364*8a978a17SVictor Perevertkin     status = pUsbDevice->FormatCycleRequest(pRequest);
365*8a978a17SVictor Perevertkin 
366*8a978a17SVictor Perevertkin     return status;
367*8a978a17SVictor Perevertkin }
368*8a978a17SVictor Perevertkin 
369*8a978a17SVictor Perevertkin __checkReturn
__drv_maxIRQL(DISPATCH_LEVEL)370*8a978a17SVictor Perevertkin __drv_maxIRQL(DISPATCH_LEVEL)
371*8a978a17SVictor Perevertkin NTSTATUS
372*8a978a17SVictor Perevertkin WDFAPI
373*8a978a17SVictor Perevertkin WDFEXPORT(WdfUsbTargetDeviceCreateUrb)(
374*8a978a17SVictor Perevertkin     __in
375*8a978a17SVictor Perevertkin     PWDF_DRIVER_GLOBALS DriverGlobals,
376*8a978a17SVictor Perevertkin     __in
377*8a978a17SVictor Perevertkin     WDFUSBDEVICE UsbDevice,
378*8a978a17SVictor Perevertkin     __in_opt
379*8a978a17SVictor Perevertkin     PWDF_OBJECT_ATTRIBUTES Attributes,
380*8a978a17SVictor Perevertkin     __out
381*8a978a17SVictor Perevertkin     WDFMEMORY* UrbMemory,
382*8a978a17SVictor Perevertkin     __deref_opt_out_bcount(sizeof(URB))
383*8a978a17SVictor Perevertkin     PURB* Urb
384*8a978a17SVictor Perevertkin     )
385*8a978a17SVictor Perevertkin /*++
386*8a978a17SVictor Perevertkin 
387*8a978a17SVictor Perevertkin Routine Description:
388*8a978a17SVictor Perevertkin     Creates a WDFUSBDEVICE handle for the client.
389*8a978a17SVictor Perevertkin 
390*8a978a17SVictor Perevertkin Arguments:
391*8a978a17SVictor Perevertkin     Attributes - Attributes associated with this object
392*8a978a17SVictor Perevertkin 
393*8a978a17SVictor Perevertkin     UrbMemory - The returned handle to the caller for the allocated Urb
394*8a978a17SVictor Perevertkin 
395*8a978a17SVictor Perevertkin     Urb - (opt) Pointer to the associated urb buffer.
396*8a978a17SVictor Perevertkin 
397*8a978a17SVictor Perevertkin Return Value:
398*8a978a17SVictor Perevertkin     STATUS_INVALID_PARAMETER - any required parameters are not present/invalid
399*8a978a17SVictor Perevertkin 
400*8a978a17SVictor Perevertkin     STATUS_INVALID_DEVICE_STATE - If the client did not specify a client contract verion while
401*8a978a17SVictor Perevertkin         creating the WDFUSBDEVICE
402*8a978a17SVictor Perevertkin 
403*8a978a17SVictor Perevertkin     STATUS_INSUFFICIENT_RESOURCES - could not allocated the object that backs
404*8a978a17SVictor Perevertkin         the handle
405*8a978a17SVictor Perevertkin 
406*8a978a17SVictor Perevertkin     STATUS_SUCCESS - success
407*8a978a17SVictor Perevertkin 
408*8a978a17SVictor Perevertkin     ...
409*8a978a17SVictor Perevertkin 
410*8a978a17SVictor Perevertkin   --*/
411*8a978a17SVictor Perevertkin {
412*8a978a17SVictor Perevertkin     DDI_ENTRY();
413*8a978a17SVictor Perevertkin 
414*8a978a17SVictor Perevertkin     PFX_DRIVER_GLOBALS pFxDriverGlobals;
415*8a978a17SVictor Perevertkin     FxUsbDevice* pUsbDevice;
416*8a978a17SVictor Perevertkin     NTSTATUS status;
417*8a978a17SVictor Perevertkin 
418*8a978a17SVictor Perevertkin     FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals),
419*8a978a17SVictor Perevertkin                                    UsbDevice,
420*8a978a17SVictor Perevertkin                                    FX_TYPE_IO_TARGET_USB_DEVICE,
421*8a978a17SVictor Perevertkin                                    (PVOID*) &pUsbDevice,
422*8a978a17SVictor Perevertkin                                    &pFxDriverGlobals);
423*8a978a17SVictor Perevertkin 
424*8a978a17SVictor Perevertkin     //
425*8a978a17SVictor Perevertkin     // Basic parameter validation
426*8a978a17SVictor Perevertkin     //
427*8a978a17SVictor Perevertkin     FxPointerNotNull(pFxDriverGlobals, UrbMemory);
428*8a978a17SVictor Perevertkin 
429*8a978a17SVictor Perevertkin     if (pUsbDevice->GetUSBDHandle() == NULL) {
430*8a978a17SVictor Perevertkin         status = STATUS_INVALID_DEVICE_STATE;
431*8a978a17SVictor Perevertkin 
432*8a978a17SVictor Perevertkin         DoTraceLevelMessage(
433*8a978a17SVictor Perevertkin             pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGIOTARGET,
434*8a978a17SVictor Perevertkin             "USBDEVICE Must have been created with Client Contract Verion Info, %!STATUS!",
435*8a978a17SVictor Perevertkin             status);
436*8a978a17SVictor Perevertkin 
437*8a978a17SVictor Perevertkin         return status;
438*8a978a17SVictor Perevertkin     }
439*8a978a17SVictor Perevertkin 
440*8a978a17SVictor Perevertkin     status = pUsbDevice->CreateUrb(Attributes, UrbMemory, Urb);
441*8a978a17SVictor Perevertkin 
442*8a978a17SVictor Perevertkin     return status;
443*8a978a17SVictor Perevertkin }
444*8a978a17SVictor Perevertkin 
445*8a978a17SVictor Perevertkin } // extern "C"
446