[SHELL32] Remove 2 redundant initializations
[reactos.git] / drivers / usb / usbstor / fdo.c
1 /*
2 * PROJECT: ReactOS Universal Serial Bus Bulk Storage Driver
3 * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
4 * PURPOSE: USB block storage device driver.
5 * COPYRIGHT: 2005-2006 James Tabor
6 * 2011-2012 Michael Martin (michael.martin@reactos.org)
7 * 2011-2013 Johannes Anderwald (johannes.anderwald@reactos.org)
8 * 2019 Victor Perevertkin (victor.perevertkin@reactos.org)
9 */
10
11 #include "usbstor.h"
12
13 #define NDEBUG
14 #include <debug.h>
15
16
17 #if DBG
18 static
19 VOID
20 USBSTOR_DumpDeviceDescriptor(PUSB_DEVICE_DESCRIPTOR DeviceDescriptor)
21 {
22 DPRINT("Dumping Device Descriptor %p\n", DeviceDescriptor);
23 DPRINT("bLength %x\n", DeviceDescriptor->bLength);
24 DPRINT("bDescriptorType %x\n", DeviceDescriptor->bDescriptorType);
25 DPRINT("bcdUSB %x\n", DeviceDescriptor->bcdUSB);
26 DPRINT("bDeviceClass %x\n", DeviceDescriptor->bDeviceClass);
27 DPRINT("bDeviceSubClass %x\n", DeviceDescriptor->bDeviceSubClass);
28 DPRINT("bDeviceProtocol %x\n", DeviceDescriptor->bDeviceProtocol);
29 DPRINT("bMaxPacketSize0 %x\n", DeviceDescriptor->bMaxPacketSize0);
30 DPRINT("idVendor %x\n", DeviceDescriptor->idVendor);
31 DPRINT("idProduct %x\n", DeviceDescriptor->idProduct);
32 DPRINT("bcdDevice %x\n", DeviceDescriptor->bcdDevice);
33 DPRINT("iManufacturer %x\n", DeviceDescriptor->iManufacturer);
34 DPRINT("iProduct %x\n", DeviceDescriptor->iProduct);
35 DPRINT("iSerialNumber %x\n", DeviceDescriptor->iSerialNumber);
36 DPRINT("bNumConfigurations %x\n", DeviceDescriptor->bNumConfigurations);
37 }
38 #endif
39
40 NTSTATUS
41 USBSTOR_FdoHandleDeviceRelations(
42 IN PFDO_DEVICE_EXTENSION DeviceExtension,
43 IN OUT PIRP Irp)
44 {
45 INT32 DeviceCount = 0;
46 LONG Index;
47 PDEVICE_RELATIONS DeviceRelations;
48 PIO_STACK_LOCATION IoStack;
49
50 IoStack = IoGetCurrentIrpStackLocation(Irp);
51
52 // FDO always only handles bus relations
53 if (IoStack->Parameters.QueryDeviceRelations.Type == BusRelations)
54 {
55 // go through array and count device objects
56 for (Index = 0; Index < max(DeviceExtension->MaxLUN, 1); Index++)
57 {
58 if (DeviceExtension->ChildPDO[Index])
59 {
60 DeviceCount++;
61 }
62 }
63
64 DeviceRelations = ExAllocatePoolWithTag(PagedPool, sizeof(DEVICE_RELATIONS) + (DeviceCount - 1) * sizeof(PDEVICE_OBJECT), USB_STOR_TAG);
65 if (!DeviceRelations)
66 {
67 Irp->IoStatus.Information = 0;
68 Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
69 IoCompleteRequest(Irp, IO_NO_INCREMENT);
70 return STATUS_INSUFFICIENT_RESOURCES;
71 }
72
73 DeviceRelations->Count = 0;
74
75 // add device objects
76 for (Index = 0; Index < max(DeviceExtension->MaxLUN, 1); Index++)
77 {
78 if (DeviceExtension->ChildPDO[Index])
79 {
80 // store child pdo
81 DeviceRelations->Objects[DeviceRelations->Count] = DeviceExtension->ChildPDO[Index];
82
83 // add reference
84 ObReferenceObject(DeviceExtension->ChildPDO[Index]);
85
86 DeviceRelations->Count++;
87 }
88 }
89
90 Irp->IoStatus.Information = (ULONG_PTR)DeviceRelations;
91 Irp->IoStatus.Status = STATUS_SUCCESS;
92 }
93
94 IoCopyCurrentIrpStackLocationToNext(Irp);
95
96 return IoCallDriver(DeviceExtension->LowerDeviceObject, Irp);
97 }
98
99 NTSTATUS
100 USBSTOR_FdoHandleRemoveDevice(
101 IN PDEVICE_OBJECT DeviceObject,
102 IN PFDO_DEVICE_EXTENSION DeviceExtension,
103 IN OUT PIRP Irp)
104 {
105 NTSTATUS Status;
106 ULONG Index;
107
108 DPRINT("Handling FDO removal %p\n", DeviceObject);
109
110 // FIXME: wait for devices finished processing
111 for (Index = 0; Index < USB_MAXCHILDREN; Index++)
112 {
113 if (DeviceExtension->ChildPDO[Index] != NULL)
114 {
115 DPRINT("Deleting PDO %p RefCount %x AttachedDevice %p \n", DeviceExtension->ChildPDO[Index], DeviceExtension->ChildPDO[Index]->ReferenceCount, DeviceExtension->ChildPDO[Index]->AttachedDevice);
116 IoDeleteDevice(DeviceExtension->ChildPDO[Index]);
117 }
118 }
119
120 // Freeing everything in DeviceExtension
121 ASSERT(
122 DeviceExtension->DeviceDescriptor &&
123 DeviceExtension->ConfigurationDescriptor &&
124 DeviceExtension->InterfaceInformation &&
125 DeviceExtension->ResetDeviceWorkItem
126 );
127
128 ExFreePoolWithTag(DeviceExtension->DeviceDescriptor, USB_STOR_TAG);
129 ExFreePoolWithTag(DeviceExtension->ConfigurationDescriptor, USB_STOR_TAG);
130 ExFreePoolWithTag(DeviceExtension->InterfaceInformation, USB_STOR_TAG);
131 IoFreeWorkItem(DeviceExtension->ResetDeviceWorkItem);
132
133 if (DeviceExtension->SerialNumber)
134 {
135 ExFreePoolWithTag(DeviceExtension->SerialNumber, USB_STOR_TAG);
136 }
137
138 // Send the IRP down the stack
139 IoSkipCurrentIrpStackLocation(Irp);
140 Irp->IoStatus.Status = STATUS_SUCCESS;
141 Status = IoCallDriver(DeviceExtension->LowerDeviceObject, Irp);
142
143 // Detach from the device stack
144 IoDetachDevice(DeviceExtension->LowerDeviceObject);
145
146 IoDeleteDevice(DeviceObject);
147
148 return Status;
149 }
150
151 NTSTATUS
152 USBSTOR_FdoHandleStartDevice(
153 IN PDEVICE_OBJECT DeviceObject,
154 IN PFDO_DEVICE_EXTENSION DeviceExtension,
155 IN OUT PIRP Irp)
156 {
157 PUSB_INTERFACE_DESCRIPTOR InterfaceDesc;
158 NTSTATUS Status;
159 UCHAR Index = 0;
160 PIO_WORKITEM WorkItem;
161
162 // forward irp to lower device
163 Status = USBSTOR_SyncForwardIrp(DeviceExtension->LowerDeviceObject, Irp);
164 if (!NT_SUCCESS(Status))
165 {
166 DPRINT1("USBSTOR_FdoHandleStartDevice Lower device failed to start %x\n", Status);
167 return Status;
168 }
169
170 if (!DeviceExtension->ResetDeviceWorkItem)
171 {
172 WorkItem = IoAllocateWorkItem(DeviceObject);
173 DeviceExtension->ResetDeviceWorkItem = WorkItem;
174
175 if (!WorkItem)
176 {
177 return STATUS_INSUFFICIENT_RESOURCES;
178 }
179 }
180
181 // initialize irp queue
182 USBSTOR_QueueInitialize(DeviceExtension);
183
184 // first get device & configuration & string descriptor
185 Status = USBSTOR_GetDescriptors(DeviceObject);
186 if (!NT_SUCCESS(Status))
187 {
188 DPRINT1("USBSTOR_FdoHandleStartDevice failed to get device descriptor with %x\n", Status);
189 return Status;
190 }
191
192 #if DBG
193 USBSTOR_DumpDeviceDescriptor(DeviceExtension->DeviceDescriptor);
194 #endif
195
196 // Check that this device uses bulk transfers and is SCSI
197
198 InterfaceDesc = (PUSB_INTERFACE_DESCRIPTOR)((ULONG_PTR)DeviceExtension->ConfigurationDescriptor + sizeof(USB_CONFIGURATION_DESCRIPTOR));
199 ASSERT(InterfaceDesc->bDescriptorType == USB_INTERFACE_DESCRIPTOR_TYPE);
200 ASSERT(InterfaceDesc->bLength == sizeof(USB_INTERFACE_DESCRIPTOR));
201
202 DPRINT("bInterfaceSubClass %x\n", InterfaceDesc->bInterfaceSubClass);
203 if (InterfaceDesc->bInterfaceProtocol != USB_PROTOCOL_BULK)
204 {
205 DPRINT1("USB Device is not a bulk only device and is not currently supported\n");
206 return STATUS_NOT_SUPPORTED;
207 }
208
209 if (InterfaceDesc->bInterfaceSubClass == USB_SUBCLASS_UFI)
210 {
211 DPRINT1("USB Floppy devices are not supported\n");
212 return STATUS_NOT_SUPPORTED;
213 }
214
215 // now select an interface
216 Status = USBSTOR_SelectConfigurationAndInterface(DeviceObject, DeviceExtension);
217 if (!NT_SUCCESS(Status))
218 {
219 // failed to get device descriptor
220 DPRINT1("USBSTOR_FdoHandleStartDevice failed to select configuration / interface with %x\n", Status);
221 return Status;
222 }
223
224 // check if we got a bulk in + bulk out endpoint
225 Status = USBSTOR_GetPipeHandles(DeviceExtension);
226 if (!NT_SUCCESS(Status))
227 {
228 DPRINT1("USBSTOR_FdoHandleStartDevice no pipe handles %x\n", Status);
229 return Status;
230 }
231
232 Status = USBSTOR_GetMaxLUN(DeviceExtension->LowerDeviceObject, DeviceExtension);
233 if (!NT_SUCCESS(Status))
234 {
235 DPRINT1("USBSTOR_FdoHandleStartDevice failed to get max lun %x\n", Status);
236 return Status;
237 }
238
239 // now create for each LUN a device object, 1 minimum
240 do
241 {
242 Status = USBSTOR_CreatePDO(DeviceObject, Index);
243
244 if (!NT_SUCCESS(Status))
245 {
246 DPRINT1("USBSTOR_FdoHandleStartDevice USBSTOR_CreatePDO failed for Index %lu with Status %x\n", Index, Status);
247 return Status;
248 }
249
250 Index++;
251 DeviceExtension->InstanceCount++;
252
253 } while(Index < DeviceExtension->MaxLUN);
254
255 #if 0
256 //
257 // finally get usb device interface
258 //
259 Status = USBSTOR_GetBusInterface(DeviceExtension->LowerDeviceObject, &DeviceExtension->BusInterface);
260 if (!NT_SUCCESS(Status))
261 {
262 //
263 // failed to device interface
264 //
265 DPRINT1("USBSTOR_FdoHandleStartDevice failed to get device interface %x\n", Status);
266 return Status;
267 }
268 #endif
269
270 //IoStartTimer(DeviceObject);
271
272 DPRINT("USBSTOR_FdoHandleStartDevice FDO is initialized\n");
273 return STATUS_SUCCESS;
274 }
275
276 NTSTATUS
277 USBSTOR_FdoHandlePnp(
278 IN PDEVICE_OBJECT DeviceObject,
279 IN OUT PIRP Irp)
280 {
281 PIO_STACK_LOCATION IoStack;
282 PFDO_DEVICE_EXTENSION DeviceExtension;
283 NTSTATUS Status;
284
285 IoStack = IoGetCurrentIrpStackLocation(Irp);
286 DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
287 ASSERT(DeviceExtension->Common.IsFDO);
288
289 switch(IoStack->MinorFunction)
290 {
291 case IRP_MN_SURPRISE_REMOVAL:
292 {
293 DPRINT("IRP_MN_SURPRISE_REMOVAL %p\n", DeviceObject);
294 Irp->IoStatus.Status = STATUS_SUCCESS;
295
296 // forward irp to next device object
297 IoSkipCurrentIrpStackLocation(Irp);
298 return IoCallDriver(DeviceExtension->LowerDeviceObject, Irp);
299 }
300 case IRP_MN_QUERY_DEVICE_RELATIONS:
301 {
302 DPRINT("IRP_MN_QUERY_DEVICE_RELATIONS %p Type: %u\n", DeviceObject, IoStack->Parameters.QueryDeviceRelations.Type);
303 return USBSTOR_FdoHandleDeviceRelations(DeviceExtension, Irp);
304 }
305 case IRP_MN_STOP_DEVICE:
306 {
307 DPRINT1("USBSTOR_FdoHandlePnp: IRP_MN_STOP_DEVICE unimplemented\n");
308 IoStopTimer(DeviceObject);
309 Irp->IoStatus.Status = STATUS_SUCCESS;
310
311 // forward irp to next device object
312 IoSkipCurrentIrpStackLocation(Irp);
313 return IoCallDriver(DeviceExtension->LowerDeviceObject, Irp);
314 }
315 case IRP_MN_REMOVE_DEVICE:
316 {
317 DPRINT("IRP_MN_REMOVE_DEVICE\n");
318
319 return USBSTOR_FdoHandleRemoveDevice(DeviceObject, DeviceExtension, Irp);
320 }
321 case IRP_MN_QUERY_CAPABILITIES:
322 {
323 // FIXME: set custom capabilities
324 IoSkipCurrentIrpStackLocation(Irp);
325 return IoCallDriver(DeviceExtension->LowerDeviceObject, Irp);
326 }
327 case IRP_MN_QUERY_STOP_DEVICE:
328 case IRP_MN_QUERY_REMOVE_DEVICE:
329 {
330 #if 0
331 //
332 // we can if nothing is pending
333 //
334 if (DeviceExtension->IrpPendingCount != 0 ||
335 DeviceExtension->ActiveSrb != NULL)
336 #else
337 if (TRUE)
338 #endif
339 {
340 /* We have pending requests */
341 DPRINT1("Failing removal/stop request due to pending requests present\n");
342 Status = STATUS_UNSUCCESSFUL;
343 }
344 else
345 {
346 /* We're all clear */
347 Irp->IoStatus.Status = STATUS_SUCCESS;
348
349 IoSkipCurrentIrpStackLocation(Irp);
350 return IoCallDriver(DeviceExtension->LowerDeviceObject, Irp);
351 }
352 break;
353 }
354 case IRP_MN_START_DEVICE:
355 {
356 Status = USBSTOR_FdoHandleStartDevice(DeviceObject, DeviceExtension, Irp);
357 break;
358 }
359 default:
360 {
361 // forward irp to next device object
362 IoSkipCurrentIrpStackLocation(Irp);
363 return IoCallDriver(DeviceExtension->LowerDeviceObject, Irp);
364 }
365 }
366
367 if (Status != STATUS_PENDING)
368 {
369 Irp->IoStatus.Status = Status;
370 IoCompleteRequest(Irp, IO_NO_INCREMENT);
371 }
372
373 return Status;
374 }