99392f7e0921f829bdcef54163fa6111304aae1a
[reactos.git] / drivers / usb / usbstor / usbstor.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 */
9
10 #include "usbstor.h"
11
12 #define NDEBUG
13 #include <debug.h>
14
15
16 NTSTATUS
17 NTAPI
18 USBSTOR_AddDevice(
19 IN PDRIVER_OBJECT DriverObject,
20 IN PDEVICE_OBJECT PhysicalDeviceObject)
21 {
22 NTSTATUS Status;
23 PDEVICE_OBJECT DeviceObject;
24 PFDO_DEVICE_EXTENSION DeviceExtension;
25
26 Status = IoCreateDevice(DriverObject, sizeof(FDO_DEVICE_EXTENSION), 0, FILE_DEVICE_BUS_EXTENDER, FILE_AUTOGENERATED_DEVICE_NAME | FILE_DEVICE_SECURE_OPEN, FALSE, &DeviceObject);
27 if (!NT_SUCCESS(Status))
28 {
29 DPRINT1("USBSTOR_AddDevice: Failed to create FDO Status %x\n", Status);
30 return Status;
31 }
32
33 DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
34 ASSERT(DeviceExtension);
35 RtlZeroMemory(DeviceExtension, sizeof(FDO_DEVICE_EXTENSION));
36
37 // initialize device extension
38 DeviceExtension->Common.IsFDO = TRUE;
39 DeviceExtension->FunctionalDeviceObject = DeviceObject;
40 DeviceExtension->PhysicalDeviceObject = PhysicalDeviceObject;
41 DeviceExtension->LowerDeviceObject = IoAttachDeviceToDeviceStack(DeviceObject, PhysicalDeviceObject);
42
43 KeInitializeSpinLock(&DeviceExtension->CommonLock);
44
45 IoInitializeTimer(DeviceObject, USBSTOR_TimerRoutine, (PVOID)DeviceExtension);
46
47 // did attaching fail
48 if (!DeviceExtension->LowerDeviceObject)
49 {
50 IoDeleteDevice(DeviceObject);
51
52 return STATUS_DEVICE_REMOVED;
53 }
54
55 DeviceObject->Flags |= DO_BUFFERED_IO | DO_POWER_PAGABLE;
56
57 // device is initialized
58 DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
59
60 return STATUS_SUCCESS;
61 }
62
63 VOID
64 NTAPI
65 USBSTOR_Unload(
66 PDRIVER_OBJECT DriverObject)
67 {
68 // no-op
69 }
70
71 NTSTATUS
72 NTAPI
73 USBSTOR_DispatchClose(
74 PDEVICE_OBJECT DeviceObject,
75 PIRP Irp)
76 {
77 // function always succeeds ;)
78 DPRINT("USBSTOR_DispatchClose\n");
79 Irp->IoStatus.Information = 0;
80 Irp->IoStatus.Status = STATUS_SUCCESS;
81 IoCompleteRequest(Irp, IO_NO_INCREMENT);
82 return STATUS_SUCCESS;
83 }
84
85 NTSTATUS
86 NTAPI
87 USBSTOR_DispatchDeviceControl(
88 PDEVICE_OBJECT DeviceObject,
89 PIRP Irp)
90 {
91 NTSTATUS Status;
92
93 Status = USBSTOR_HandleDeviceControl(DeviceObject, Irp);
94 Irp->IoStatus.Status = Status;
95 IoCompleteRequest(Irp, IO_NO_INCREMENT);
96 return Status;
97 }
98
99 NTSTATUS
100 NTAPI
101 USBSTOR_DispatchScsi(
102 PDEVICE_OBJECT DeviceObject,
103 PIRP Irp)
104 {
105 return USBSTOR_HandleInternalDeviceControl(DeviceObject, Irp);
106 }
107
108 NTSTATUS
109 NTAPI
110 USBSTOR_DispatchReadWrite(
111 PDEVICE_OBJECT DeviceObject,
112 PIRP Irp)
113 {
114 // read write ioctl is not supported
115 Irp->IoStatus.Information = 0;
116 Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
117 IoCompleteRequest(Irp, IO_NO_INCREMENT);
118 return STATUS_INVALID_PARAMETER;
119 }
120
121 NTSTATUS
122 NTAPI
123 USBSTOR_DispatchPnp(
124 PDEVICE_OBJECT DeviceObject,
125 PIRP Irp)
126 {
127 PUSBSTOR_COMMON_DEVICE_EXTENSION DeviceExtension;
128
129 DeviceExtension = (PUSBSTOR_COMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
130
131 if (DeviceExtension->IsFDO)
132 {
133 return USBSTOR_FdoHandlePnp(DeviceObject, Irp);
134 }
135 else
136 {
137 return USBSTOR_PdoHandlePnp(DeviceObject, Irp);
138 }
139 }
140
141 NTSTATUS
142 NTAPI
143 USBSTOR_DispatchPower(
144 PDEVICE_OBJECT DeviceObject,
145 PIRP Irp)
146 {
147 PFDO_DEVICE_EXTENSION DeviceExtension;
148
149 // get common device extension
150 DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
151
152 if (DeviceExtension->Common.IsFDO)
153 {
154 PoStartNextPowerIrp(Irp);
155 IoSkipCurrentIrpStackLocation(Irp);
156 return PoCallDriver(DeviceExtension->LowerDeviceObject, Irp);
157 }
158 else
159 {
160 PoStartNextPowerIrp(Irp);
161 Irp->IoStatus.Status = STATUS_SUCCESS;
162 IoCompleteRequest(Irp, IO_NO_INCREMENT);
163 return STATUS_SUCCESS;
164 }
165 }
166
167 NTSTATUS
168 NTAPI
169 DriverEntry(
170 IN PDRIVER_OBJECT DriverObject,
171 IN PUNICODE_STRING RegPath)
172 {
173
174 DPRINT("********* USB Storage *********\n");
175
176 DriverObject->DriverUnload = USBSTOR_Unload;
177 DriverObject->DriverExtension->AddDevice = USBSTOR_AddDevice;
178 DriverObject->DriverStartIo = USBSTOR_StartIo;
179 DriverObject->MajorFunction[IRP_MJ_CREATE] = USBSTOR_DispatchClose;
180 DriverObject->MajorFunction[IRP_MJ_CLOSE] = USBSTOR_DispatchClose;
181 DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = USBSTOR_DispatchDeviceControl; // scsi pass through requests
182 DriverObject->MajorFunction[IRP_MJ_READ] = USBSTOR_DispatchReadWrite;
183 DriverObject->MajorFunction[IRP_MJ_WRITE] = USBSTOR_DispatchReadWrite;
184 DriverObject->MajorFunction[IRP_MJ_SCSI] = USBSTOR_DispatchScsi;
185 DriverObject->MajorFunction[IRP_MJ_PNP] = USBSTOR_DispatchPnp;
186 DriverObject->MajorFunction[IRP_MJ_POWER] = USBSTOR_DispatchPower;
187
188 return STATUS_SUCCESS;
189 }