1*94e09426SAmine Khaldi /*
2*94e09426SAmine Khaldi * PROJECT: ReactOS Universal Serial Bus Bulk Storage Driver
3*94e09426SAmine Khaldi * LICENSE: GPL - See COPYING in the top level directory
4*94e09426SAmine Khaldi * FILE: drivers/usb/usbstor/fdo.c
5*94e09426SAmine Khaldi * PURPOSE: USB block storage device driver.
6*94e09426SAmine Khaldi * PROGRAMMERS:
7*94e09426SAmine Khaldi * James Tabor
8*94e09426SAmine Khaldi * Michael Martin (michael.martin@reactos.org)
9*94e09426SAmine Khaldi * Johannes Anderwald (johannes.anderwald@reactos.org)
10*94e09426SAmine Khaldi */
11*94e09426SAmine Khaldi
12*94e09426SAmine Khaldi #include "usbstor.h"
13*94e09426SAmine Khaldi
14*94e09426SAmine Khaldi #define NDEBUG
15*94e09426SAmine Khaldi #include <debug.h>
16*94e09426SAmine Khaldi
17*94e09426SAmine Khaldi VOID
USBSTOR_DumpDeviceDescriptor(PUSB_DEVICE_DESCRIPTOR DeviceDescriptor)18*94e09426SAmine Khaldi USBSTOR_DumpDeviceDescriptor(PUSB_DEVICE_DESCRIPTOR DeviceDescriptor)
19*94e09426SAmine Khaldi {
20*94e09426SAmine Khaldi DPRINT1("Dumping Device Descriptor %p\n", DeviceDescriptor);
21*94e09426SAmine Khaldi DPRINT1("bLength %x\n", DeviceDescriptor->bLength);
22*94e09426SAmine Khaldi DPRINT1("bDescriptorType %x\n", DeviceDescriptor->bDescriptorType);
23*94e09426SAmine Khaldi DPRINT1("bcdUSB %x\n", DeviceDescriptor->bcdUSB);
24*94e09426SAmine Khaldi DPRINT1("bDeviceClass %x\n", DeviceDescriptor->bDeviceClass);
25*94e09426SAmine Khaldi DPRINT1("bDeviceSubClass %x\n", DeviceDescriptor->bDeviceSubClass);
26*94e09426SAmine Khaldi DPRINT1("bDeviceProtocol %x\n", DeviceDescriptor->bDeviceProtocol);
27*94e09426SAmine Khaldi DPRINT1("bMaxPacketSize0 %x\n", DeviceDescriptor->bMaxPacketSize0);
28*94e09426SAmine Khaldi DPRINT1("idVendor %x\n", DeviceDescriptor->idVendor);
29*94e09426SAmine Khaldi DPRINT1("idProduct %x\n", DeviceDescriptor->idProduct);
30*94e09426SAmine Khaldi DPRINT1("bcdDevice %x\n", DeviceDescriptor->bcdDevice);
31*94e09426SAmine Khaldi DPRINT1("iManufacturer %x\n", DeviceDescriptor->iManufacturer);
32*94e09426SAmine Khaldi DPRINT1("iProduct %x\n", DeviceDescriptor->iProduct);
33*94e09426SAmine Khaldi DPRINT1("iSerialNumber %x\n", DeviceDescriptor->iSerialNumber);
34*94e09426SAmine Khaldi DPRINT1("bNumConfigurations %x\n", DeviceDescriptor->bNumConfigurations);
35*94e09426SAmine Khaldi }
36*94e09426SAmine Khaldi
37*94e09426SAmine Khaldi NTSTATUS
USBSTOR_FdoHandleDeviceRelations(IN PFDO_DEVICE_EXTENSION DeviceExtension,IN OUT PIRP Irp)38*94e09426SAmine Khaldi USBSTOR_FdoHandleDeviceRelations(
39*94e09426SAmine Khaldi IN PFDO_DEVICE_EXTENSION DeviceExtension,
40*94e09426SAmine Khaldi IN OUT PIRP Irp)
41*94e09426SAmine Khaldi {
42*94e09426SAmine Khaldi ULONG DeviceCount = 0;
43*94e09426SAmine Khaldi LONG Index;
44*94e09426SAmine Khaldi PDEVICE_RELATIONS DeviceRelations;
45*94e09426SAmine Khaldi PIO_STACK_LOCATION IoStack;
46*94e09426SAmine Khaldi
47*94e09426SAmine Khaldi //
48*94e09426SAmine Khaldi // get current irp stack location
49*94e09426SAmine Khaldi //
50*94e09426SAmine Khaldi IoStack = IoGetCurrentIrpStackLocation(Irp);
51*94e09426SAmine Khaldi
52*94e09426SAmine Khaldi //
53*94e09426SAmine Khaldi // check if relation type is BusRelations
54*94e09426SAmine Khaldi //
55*94e09426SAmine Khaldi if (IoStack->Parameters.QueryDeviceRelations.Type != BusRelations)
56*94e09426SAmine Khaldi {
57*94e09426SAmine Khaldi //
58*94e09426SAmine Khaldi // FDO always only handles bus relations
59*94e09426SAmine Khaldi //
60*94e09426SAmine Khaldi return USBSTOR_SyncForwardIrp(DeviceExtension->LowerDeviceObject, Irp);
61*94e09426SAmine Khaldi }
62*94e09426SAmine Khaldi
63*94e09426SAmine Khaldi //
64*94e09426SAmine Khaldi // go through array and count device objects
65*94e09426SAmine Khaldi //
66*94e09426SAmine Khaldi for (Index = 0; Index < max(DeviceExtension->MaxLUN, 1); Index++)
67*94e09426SAmine Khaldi {
68*94e09426SAmine Khaldi if (DeviceExtension->ChildPDO[Index])
69*94e09426SAmine Khaldi {
70*94e09426SAmine Khaldi //
71*94e09426SAmine Khaldi // child pdo
72*94e09426SAmine Khaldi //
73*94e09426SAmine Khaldi DeviceCount++;
74*94e09426SAmine Khaldi }
75*94e09426SAmine Khaldi }
76*94e09426SAmine Khaldi
77*94e09426SAmine Khaldi //
78*94e09426SAmine Khaldi // allocate device relations
79*94e09426SAmine Khaldi //
80*94e09426SAmine Khaldi DeviceRelations = (PDEVICE_RELATIONS)AllocateItem(PagedPool, sizeof(DEVICE_RELATIONS) + (DeviceCount > 1 ? (DeviceCount-1) * sizeof(PDEVICE_OBJECT) : 0));
81*94e09426SAmine Khaldi if (!DeviceRelations)
82*94e09426SAmine Khaldi {
83*94e09426SAmine Khaldi //
84*94e09426SAmine Khaldi // no memory
85*94e09426SAmine Khaldi //
86*94e09426SAmine Khaldi return STATUS_INSUFFICIENT_RESOURCES;
87*94e09426SAmine Khaldi }
88*94e09426SAmine Khaldi
89*94e09426SAmine Khaldi //
90*94e09426SAmine Khaldi // add device objects
91*94e09426SAmine Khaldi //
92*94e09426SAmine Khaldi for(Index = 0; Index < max(DeviceExtension->MaxLUN, 1); Index++)
93*94e09426SAmine Khaldi {
94*94e09426SAmine Khaldi if (DeviceExtension->ChildPDO[Index])
95*94e09426SAmine Khaldi {
96*94e09426SAmine Khaldi //
97*94e09426SAmine Khaldi // store child pdo
98*94e09426SAmine Khaldi //
99*94e09426SAmine Khaldi DeviceRelations->Objects[DeviceRelations->Count] = DeviceExtension->ChildPDO[Index];
100*94e09426SAmine Khaldi
101*94e09426SAmine Khaldi //
102*94e09426SAmine Khaldi // add reference
103*94e09426SAmine Khaldi //
104*94e09426SAmine Khaldi ObReferenceObject(DeviceExtension->ChildPDO[Index]);
105*94e09426SAmine Khaldi
106*94e09426SAmine Khaldi //
107*94e09426SAmine Khaldi // increment count
108*94e09426SAmine Khaldi //
109*94e09426SAmine Khaldi DeviceRelations->Count++;
110*94e09426SAmine Khaldi }
111*94e09426SAmine Khaldi }
112*94e09426SAmine Khaldi
113*94e09426SAmine Khaldi //
114*94e09426SAmine Khaldi // store result
115*94e09426SAmine Khaldi //
116*94e09426SAmine Khaldi Irp->IoStatus.Information = (ULONG_PTR)DeviceRelations;
117*94e09426SAmine Khaldi
118*94e09426SAmine Khaldi //
119*94e09426SAmine Khaldi // request completed successfully
120*94e09426SAmine Khaldi //
121*94e09426SAmine Khaldi return STATUS_SUCCESS;
122*94e09426SAmine Khaldi }
123*94e09426SAmine Khaldi
124*94e09426SAmine Khaldi NTSTATUS
USBSTOR_FdoHandleRemoveDevice(IN PDEVICE_OBJECT DeviceObject,IN PFDO_DEVICE_EXTENSION DeviceExtension,IN OUT PIRP Irp)125*94e09426SAmine Khaldi USBSTOR_FdoHandleRemoveDevice(
126*94e09426SAmine Khaldi IN PDEVICE_OBJECT DeviceObject,
127*94e09426SAmine Khaldi IN PFDO_DEVICE_EXTENSION DeviceExtension,
128*94e09426SAmine Khaldi IN OUT PIRP Irp)
129*94e09426SAmine Khaldi {
130*94e09426SAmine Khaldi NTSTATUS Status;
131*94e09426SAmine Khaldi ULONG Index;
132*94e09426SAmine Khaldi
133*94e09426SAmine Khaldi DPRINT("Handling FDO removal %p\n", DeviceObject);
134*94e09426SAmine Khaldi
135*94e09426SAmine Khaldi /* FIXME: wait for devices finished processing */
136*94e09426SAmine Khaldi for(Index = 0; Index < 16; Index++)
137*94e09426SAmine Khaldi {
138*94e09426SAmine Khaldi if (DeviceExtension->ChildPDO[Index] != NULL)
139*94e09426SAmine Khaldi {
140*94e09426SAmine Khaldi DPRINT("Deleting PDO %p RefCount %x AttachedDevice %p \n", DeviceExtension->ChildPDO[Index], DeviceExtension->ChildPDO[Index]->ReferenceCount, DeviceExtension->ChildPDO[Index]->AttachedDevice);
141*94e09426SAmine Khaldi IoDeleteDevice(DeviceExtension->ChildPDO[Index]);
142*94e09426SAmine Khaldi }
143*94e09426SAmine Khaldi }
144*94e09426SAmine Khaldi
145*94e09426SAmine Khaldi /* Send the IRP down the stack */
146*94e09426SAmine Khaldi IoSkipCurrentIrpStackLocation(Irp);
147*94e09426SAmine Khaldi Status = IoCallDriver(DeviceExtension->LowerDeviceObject, Irp);
148*94e09426SAmine Khaldi
149*94e09426SAmine Khaldi /* Detach from the device stack */
150*94e09426SAmine Khaldi IoDetachDevice(DeviceExtension->LowerDeviceObject);
151*94e09426SAmine Khaldi
152*94e09426SAmine Khaldi /* Delete the device object */
153*94e09426SAmine Khaldi IoDeleteDevice(DeviceObject);
154*94e09426SAmine Khaldi
155*94e09426SAmine Khaldi return Status;
156*94e09426SAmine Khaldi }
157*94e09426SAmine Khaldi
158*94e09426SAmine Khaldi NTSTATUS
USBSTOR_FdoHandleStartDevice(IN PDEVICE_OBJECT DeviceObject,IN PFDO_DEVICE_EXTENSION DeviceExtension,IN OUT PIRP Irp)159*94e09426SAmine Khaldi USBSTOR_FdoHandleStartDevice(
160*94e09426SAmine Khaldi IN PDEVICE_OBJECT DeviceObject,
161*94e09426SAmine Khaldi IN PFDO_DEVICE_EXTENSION DeviceExtension,
162*94e09426SAmine Khaldi IN OUT PIRP Irp)
163*94e09426SAmine Khaldi {
164*94e09426SAmine Khaldi PUSB_INTERFACE_DESCRIPTOR InterfaceDesc;
165*94e09426SAmine Khaldi NTSTATUS Status;
166*94e09426SAmine Khaldi UCHAR Index = 0;
167*94e09426SAmine Khaldi
168*94e09426SAmine Khaldi //
169*94e09426SAmine Khaldi // forward irp to lower device
170*94e09426SAmine Khaldi //
171*94e09426SAmine Khaldi Status = USBSTOR_SyncForwardIrp(DeviceExtension->LowerDeviceObject, Irp);
172*94e09426SAmine Khaldi if (!NT_SUCCESS(Status))
173*94e09426SAmine Khaldi {
174*94e09426SAmine Khaldi //
175*94e09426SAmine Khaldi // failed to start
176*94e09426SAmine Khaldi //
177*94e09426SAmine Khaldi DPRINT1("USBSTOR_FdoHandleStartDevice Lower device failed to start %x\n", Status);
178*94e09426SAmine Khaldi return Status;
179*94e09426SAmine Khaldi }
180*94e09426SAmine Khaldi
181*94e09426SAmine Khaldi //
182*94e09426SAmine Khaldi // initialize irp queue
183*94e09426SAmine Khaldi //
184*94e09426SAmine Khaldi USBSTOR_QueueInitialize(DeviceExtension);
185*94e09426SAmine Khaldi
186*94e09426SAmine Khaldi //
187*94e09426SAmine Khaldi // first get device & configuration & string descriptor
188*94e09426SAmine Khaldi //
189*94e09426SAmine Khaldi Status = USBSTOR_GetDescriptors(DeviceObject);
190*94e09426SAmine Khaldi if (!NT_SUCCESS(Status))
191*94e09426SAmine Khaldi {
192*94e09426SAmine Khaldi //
193*94e09426SAmine Khaldi // failed to get device descriptor
194*94e09426SAmine Khaldi //
195*94e09426SAmine Khaldi DPRINT1("USBSTOR_FdoHandleStartDevice failed to get device descriptor with %x\n", Status);
196*94e09426SAmine Khaldi return Status;
197*94e09426SAmine Khaldi }
198*94e09426SAmine Khaldi
199*94e09426SAmine Khaldi //
200*94e09426SAmine Khaldi // dump device descriptor
201*94e09426SAmine Khaldi //
202*94e09426SAmine Khaldi USBSTOR_DumpDeviceDescriptor(DeviceExtension->DeviceDescriptor);
203*94e09426SAmine Khaldi
204*94e09426SAmine Khaldi //
205*94e09426SAmine Khaldi // Check that this device uses bulk transfers and is SCSI
206*94e09426SAmine Khaldi //
207*94e09426SAmine Khaldi InterfaceDesc = (PUSB_INTERFACE_DESCRIPTOR)((ULONG_PTR)DeviceExtension->ConfigurationDescriptor + sizeof(USB_CONFIGURATION_DESCRIPTOR));
208*94e09426SAmine Khaldi
209*94e09426SAmine Khaldi //
210*94e09426SAmine Khaldi // sanity check
211*94e09426SAmine Khaldi //
212*94e09426SAmine Khaldi ASSERT(InterfaceDesc->bDescriptorType == USB_INTERFACE_DESCRIPTOR_TYPE);
213*94e09426SAmine Khaldi ASSERT(InterfaceDesc->bLength == sizeof(USB_INTERFACE_DESCRIPTOR));
214*94e09426SAmine Khaldi
215*94e09426SAmine Khaldi DPRINT("bInterfaceSubClass %x\n", InterfaceDesc->bInterfaceSubClass);
216*94e09426SAmine Khaldi if (InterfaceDesc->bInterfaceProtocol != 0x50)
217*94e09426SAmine Khaldi {
218*94e09426SAmine Khaldi DPRINT1("USB Device is not a bulk only device and is not currently supported\n");
219*94e09426SAmine Khaldi return STATUS_NOT_SUPPORTED;
220*94e09426SAmine Khaldi }
221*94e09426SAmine Khaldi
222*94e09426SAmine Khaldi if (InterfaceDesc->bInterfaceSubClass != 0x06)
223*94e09426SAmine Khaldi {
224*94e09426SAmine Khaldi //
225*94e09426SAmine Khaldi // FIXME: need to pad CDBs to 12 byte
226*94e09426SAmine Khaldi // mode select commands must be translated from 1AH / 15h to 5AH / 55h
227*94e09426SAmine Khaldi //
228*94e09426SAmine Khaldi DPRINT1("[USBSTOR] Error: need to pad CDBs\n");
229*94e09426SAmine Khaldi return STATUS_NOT_IMPLEMENTED;
230*94e09426SAmine Khaldi }
231*94e09426SAmine Khaldi
232*94e09426SAmine Khaldi //
233*94e09426SAmine Khaldi // now select an interface
234*94e09426SAmine Khaldi //
235*94e09426SAmine Khaldi Status = USBSTOR_SelectConfigurationAndInterface(DeviceObject, DeviceExtension);
236*94e09426SAmine Khaldi if (!NT_SUCCESS(Status))
237*94e09426SAmine Khaldi {
238*94e09426SAmine Khaldi //
239*94e09426SAmine Khaldi // failed to get device descriptor
240*94e09426SAmine Khaldi //
241*94e09426SAmine Khaldi DPRINT1("USBSTOR_FdoHandleStartDevice failed to select configuration / interface with %x\n", Status);
242*94e09426SAmine Khaldi return Status;
243*94e09426SAmine Khaldi }
244*94e09426SAmine Khaldi
245*94e09426SAmine Khaldi //
246*94e09426SAmine Khaldi // check if we got a bulk in + bulk out endpoint
247*94e09426SAmine Khaldi //
248*94e09426SAmine Khaldi Status = USBSTOR_GetPipeHandles(DeviceExtension);
249*94e09426SAmine Khaldi if (!NT_SUCCESS(Status))
250*94e09426SAmine Khaldi {
251*94e09426SAmine Khaldi //
252*94e09426SAmine Khaldi // failed to get pipe handles descriptor
253*94e09426SAmine Khaldi //
254*94e09426SAmine Khaldi DPRINT1("USBSTOR_FdoHandleStartDevice no pipe handles %x\n", Status);
255*94e09426SAmine Khaldi return Status;
256*94e09426SAmine Khaldi }
257*94e09426SAmine Khaldi
258*94e09426SAmine Khaldi //
259*94e09426SAmine Khaldi // get num of lun which are supported
260*94e09426SAmine Khaldi //
261*94e09426SAmine Khaldi Status = USBSTOR_GetMaxLUN(DeviceExtension->LowerDeviceObject, DeviceExtension);
262*94e09426SAmine Khaldi if (!NT_SUCCESS(Status))
263*94e09426SAmine Khaldi {
264*94e09426SAmine Khaldi //
265*94e09426SAmine Khaldi // failed to get max LUN
266*94e09426SAmine Khaldi //
267*94e09426SAmine Khaldi DPRINT1("USBSTOR_FdoHandleStartDevice failed to get max lun %x\n", Status);
268*94e09426SAmine Khaldi return Status;
269*94e09426SAmine Khaldi }
270*94e09426SAmine Khaldi
271*94e09426SAmine Khaldi //
272*94e09426SAmine Khaldi // now create for each LUN a device object, 1 minimum
273*94e09426SAmine Khaldi //
274*94e09426SAmine Khaldi do
275*94e09426SAmine Khaldi {
276*94e09426SAmine Khaldi //
277*94e09426SAmine Khaldi // create pdo
278*94e09426SAmine Khaldi //
279*94e09426SAmine Khaldi Status = USBSTOR_CreatePDO(DeviceObject, Index);
280*94e09426SAmine Khaldi
281*94e09426SAmine Khaldi //
282*94e09426SAmine Khaldi // check for failure
283*94e09426SAmine Khaldi //
284*94e09426SAmine Khaldi if (!NT_SUCCESS(Status))
285*94e09426SAmine Khaldi {
286*94e09426SAmine Khaldi //
287*94e09426SAmine Khaldi // failed to create child pdo
288*94e09426SAmine Khaldi //
289*94e09426SAmine Khaldi DPRINT1("USBSTOR_FdoHandleStartDevice USBSTOR_CreatePDO failed for Index %lu with Status %x\n", Index, Status);
290*94e09426SAmine Khaldi return Status;
291*94e09426SAmine Khaldi }
292*94e09426SAmine Khaldi
293*94e09426SAmine Khaldi //
294*94e09426SAmine Khaldi // increment pdo index
295*94e09426SAmine Khaldi //
296*94e09426SAmine Khaldi Index++;
297*94e09426SAmine Khaldi DeviceExtension->InstanceCount++;
298*94e09426SAmine Khaldi
299*94e09426SAmine Khaldi }while(Index < DeviceExtension->MaxLUN);
300*94e09426SAmine Khaldi
301*94e09426SAmine Khaldi #if 0
302*94e09426SAmine Khaldi //
303*94e09426SAmine Khaldi // finally get usb device interface
304*94e09426SAmine Khaldi //
305*94e09426SAmine Khaldi Status = USBSTOR_GetBusInterface(DeviceExtension->LowerDeviceObject, &DeviceExtension->BusInterface);
306*94e09426SAmine Khaldi if (!NT_SUCCESS(Status))
307*94e09426SAmine Khaldi {
308*94e09426SAmine Khaldi //
309*94e09426SAmine Khaldi // failed to device interface
310*94e09426SAmine Khaldi //
311*94e09426SAmine Khaldi DPRINT1("USBSTOR_FdoHandleStartDevice failed to get device interface %x\n", Status);
312*94e09426SAmine Khaldi return Status;
313*94e09426SAmine Khaldi }
314*94e09426SAmine Khaldi #endif
315*94e09426SAmine Khaldi
316*94e09426SAmine Khaldi
317*94e09426SAmine Khaldi //
318*94e09426SAmine Khaldi // start the timer
319*94e09426SAmine Khaldi //
320*94e09426SAmine Khaldi //IoStartTimer(DeviceObject);
321*94e09426SAmine Khaldi
322*94e09426SAmine Khaldi
323*94e09426SAmine Khaldi //
324*94e09426SAmine Khaldi // fdo is now initialized
325*94e09426SAmine Khaldi //
326*94e09426SAmine Khaldi DPRINT("USBSTOR_FdoHandleStartDevice FDO is initialized\n");
327*94e09426SAmine Khaldi return STATUS_SUCCESS;
328*94e09426SAmine Khaldi }
329*94e09426SAmine Khaldi
330*94e09426SAmine Khaldi NTSTATUS
USBSTOR_FdoHandlePnp(IN PDEVICE_OBJECT DeviceObject,IN OUT PIRP Irp)331*94e09426SAmine Khaldi USBSTOR_FdoHandlePnp(
332*94e09426SAmine Khaldi IN PDEVICE_OBJECT DeviceObject,
333*94e09426SAmine Khaldi IN OUT PIRP Irp)
334*94e09426SAmine Khaldi {
335*94e09426SAmine Khaldi PIO_STACK_LOCATION IoStack;
336*94e09426SAmine Khaldi PFDO_DEVICE_EXTENSION DeviceExtension;
337*94e09426SAmine Khaldi NTSTATUS Status;
338*94e09426SAmine Khaldi
339*94e09426SAmine Khaldi //
340*94e09426SAmine Khaldi // get current stack location
341*94e09426SAmine Khaldi //
342*94e09426SAmine Khaldi IoStack = IoGetCurrentIrpStackLocation(Irp);
343*94e09426SAmine Khaldi
344*94e09426SAmine Khaldi //
345*94e09426SAmine Khaldi // get device extension
346*94e09426SAmine Khaldi //
347*94e09426SAmine Khaldi DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
348*94e09426SAmine Khaldi
349*94e09426SAmine Khaldi //
350*94e09426SAmine Khaldi // sanity check
351*94e09426SAmine Khaldi //
352*94e09426SAmine Khaldi ASSERT(DeviceExtension->Common.IsFDO);
353*94e09426SAmine Khaldi
354*94e09426SAmine Khaldi switch(IoStack->MinorFunction)
355*94e09426SAmine Khaldi {
356*94e09426SAmine Khaldi case IRP_MN_SURPRISE_REMOVAL:
357*94e09426SAmine Khaldi {
358*94e09426SAmine Khaldi DPRINT("IRP_MN_SURPRISE_REMOVAL %p\n", DeviceObject);
359*94e09426SAmine Khaldi Irp->IoStatus.Status = STATUS_SUCCESS;
360*94e09426SAmine Khaldi
361*94e09426SAmine Khaldi //
362*94e09426SAmine Khaldi // forward irp to next device object
363*94e09426SAmine Khaldi //
364*94e09426SAmine Khaldi IoSkipCurrentIrpStackLocation(Irp);
365*94e09426SAmine Khaldi return IoCallDriver(DeviceExtension->LowerDeviceObject, Irp);
366*94e09426SAmine Khaldi }
367*94e09426SAmine Khaldi case IRP_MN_QUERY_DEVICE_RELATIONS:
368*94e09426SAmine Khaldi {
369*94e09426SAmine Khaldi DPRINT("IRP_MN_QUERY_DEVICE_RELATIONS %p\n", DeviceObject);
370*94e09426SAmine Khaldi Status = USBSTOR_FdoHandleDeviceRelations(DeviceExtension, Irp);
371*94e09426SAmine Khaldi break;
372*94e09426SAmine Khaldi }
373*94e09426SAmine Khaldi case IRP_MN_STOP_DEVICE:
374*94e09426SAmine Khaldi {
375*94e09426SAmine Khaldi DPRINT1("USBSTOR_FdoHandlePnp: IRP_MN_STOP_DEVICE unimplemented\n");
376*94e09426SAmine Khaldi IoStopTimer(DeviceObject);
377*94e09426SAmine Khaldi Irp->IoStatus.Status = STATUS_SUCCESS;
378*94e09426SAmine Khaldi
379*94e09426SAmine Khaldi //
380*94e09426SAmine Khaldi // forward irp to next device object
381*94e09426SAmine Khaldi //
382*94e09426SAmine Khaldi IoSkipCurrentIrpStackLocation(Irp);
383*94e09426SAmine Khaldi return IoCallDriver(DeviceExtension->LowerDeviceObject, Irp);
384*94e09426SAmine Khaldi }
385*94e09426SAmine Khaldi case IRP_MN_REMOVE_DEVICE:
386*94e09426SAmine Khaldi {
387*94e09426SAmine Khaldi DPRINT("IRP_MN_REMOVE_DEVICE\n");
388*94e09426SAmine Khaldi
389*94e09426SAmine Khaldi return USBSTOR_FdoHandleRemoveDevice(DeviceObject, DeviceExtension, Irp);
390*94e09426SAmine Khaldi }
391*94e09426SAmine Khaldi case IRP_MN_QUERY_CAPABILITIES:
392*94e09426SAmine Khaldi {
393*94e09426SAmine Khaldi //
394*94e09426SAmine Khaldi // FIXME: set custom capabilities
395*94e09426SAmine Khaldi //
396*94e09426SAmine Khaldi IoSkipCurrentIrpStackLocation(Irp);
397*94e09426SAmine Khaldi return IoCallDriver(DeviceExtension->LowerDeviceObject, Irp);
398*94e09426SAmine Khaldi }
399*94e09426SAmine Khaldi case IRP_MN_QUERY_STOP_DEVICE:
400*94e09426SAmine Khaldi case IRP_MN_QUERY_REMOVE_DEVICE:
401*94e09426SAmine Khaldi {
402*94e09426SAmine Khaldi #if 0
403*94e09426SAmine Khaldi //
404*94e09426SAmine Khaldi // we can if nothing is pending
405*94e09426SAmine Khaldi //
406*94e09426SAmine Khaldi if (DeviceExtension->IrpPendingCount != 0 ||
407*94e09426SAmine Khaldi DeviceExtension->ActiveSrb != NULL)
408*94e09426SAmine Khaldi #else
409*94e09426SAmine Khaldi if (TRUE)
410*94e09426SAmine Khaldi #endif
411*94e09426SAmine Khaldi {
412*94e09426SAmine Khaldi /* We have pending requests */
413*94e09426SAmine Khaldi DPRINT1("Failing removal/stop request due to pending requests present\n");
414*94e09426SAmine Khaldi Status = STATUS_UNSUCCESSFUL;
415*94e09426SAmine Khaldi }
416*94e09426SAmine Khaldi else
417*94e09426SAmine Khaldi {
418*94e09426SAmine Khaldi /* We're all clear */
419*94e09426SAmine Khaldi Irp->IoStatus.Status = STATUS_SUCCESS;
420*94e09426SAmine Khaldi
421*94e09426SAmine Khaldi IoSkipCurrentIrpStackLocation(Irp);
422*94e09426SAmine Khaldi return IoCallDriver(DeviceExtension->LowerDeviceObject, Irp);
423*94e09426SAmine Khaldi }
424*94e09426SAmine Khaldi break;
425*94e09426SAmine Khaldi }
426*94e09426SAmine Khaldi case IRP_MN_START_DEVICE:
427*94e09426SAmine Khaldi {
428*94e09426SAmine Khaldi Status = USBSTOR_FdoHandleStartDevice(DeviceObject, DeviceExtension, Irp);
429*94e09426SAmine Khaldi break;
430*94e09426SAmine Khaldi }
431*94e09426SAmine Khaldi default:
432*94e09426SAmine Khaldi {
433*94e09426SAmine Khaldi //
434*94e09426SAmine Khaldi // forward irp to next device object
435*94e09426SAmine Khaldi //
436*94e09426SAmine Khaldi IoSkipCurrentIrpStackLocation(Irp);
437*94e09426SAmine Khaldi return IoCallDriver(DeviceExtension->LowerDeviceObject, Irp);
438*94e09426SAmine Khaldi }
439*94e09426SAmine Khaldi }
440*94e09426SAmine Khaldi
441*94e09426SAmine Khaldi //
442*94e09426SAmine Khaldi // complete request
443*94e09426SAmine Khaldi //
444*94e09426SAmine Khaldi if (Status != STATUS_PENDING)
445*94e09426SAmine Khaldi {
446*94e09426SAmine Khaldi //
447*94e09426SAmine Khaldi // store result
448*94e09426SAmine Khaldi //
449*94e09426SAmine Khaldi Irp->IoStatus.Status = Status;
450*94e09426SAmine Khaldi
451*94e09426SAmine Khaldi //
452*94e09426SAmine Khaldi // complete request
453*94e09426SAmine Khaldi //
454*94e09426SAmine Khaldi IoCompleteRequest(Irp, IO_NO_INCREMENT);
455*94e09426SAmine Khaldi }
456*94e09426SAmine Khaldi
457*94e09426SAmine Khaldi //
458*94e09426SAmine Khaldi // done processing
459*94e09426SAmine Khaldi //
460*94e09426SAmine Khaldi return Status;
461*94e09426SAmine Khaldi }
462