xref: /reactos/drivers/usb/usbstor_new/fdo.c (revision 94e09426)
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