44daca0666ac916e9a83214bec7a3a19eb56c6db
[reactos.git] / reactos / drivers / usb / usbstor / usbstor.c
1 /*
2 * PROJECT: ReactOS Universal Serial Bus Bulk Storage Driver
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: drivers/usb/usbstor/usbstor.c
5 * PURPOSE: USB block storage device driver.
6 * PROGRAMMERS:
7 * James Tabor
8 Johannes Anderwald
9 */
10
11 /* INCLUDES ******************************************************************/
12
13 #define NDEBUG
14 #define INITGUID
15 #include "usbstor.h"
16
17 /* PUBLIC AND PRIVATE FUNCTIONS **********************************************/
18
19 NTSTATUS
20 NTAPI
21 USBSTOR_AddDevice(
22 IN PDRIVER_OBJECT DriverObject,
23 IN PDEVICE_OBJECT PhysicalDeviceObject)
24 {
25 NTSTATUS Status;
26 PDEVICE_OBJECT DeviceObject;
27 PFDO_DEVICE_EXTENSION DeviceExtension;
28
29 //
30 // lets create the device
31 //
32 Status = IoCreateDevice(DriverObject, sizeof(FDO_DEVICE_EXTENSION), 0, FILE_DEVICE_BUS_EXTENDER, FILE_AUTOGENERATED_DEVICE_NAME | FILE_DEVICE_SECURE_OPEN, FALSE, &DeviceObject);
33
34 //
35 // check for success
36 //
37 if (!NT_SUCCESS(Status))
38 {
39 DPRINT1("USBSTOR_AddDevice: Failed to create FDO Status %x\n", Status);
40 return Status;
41 }
42
43 //
44 // get device extension
45 //
46 DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
47 ASSERT(DeviceExtension);
48
49 //
50 // zero device extension
51 //
52 RtlZeroMemory(DeviceExtension, sizeof(FDO_DEVICE_EXTENSION));
53
54 //
55 // initialize device extension
56 //
57 DeviceExtension->Common.IsFDO = TRUE;
58 DeviceExtension->FunctionalDeviceObject = DeviceObject;
59 DeviceExtension->PhysicalDeviceObject = PhysicalDeviceObject;
60 DeviceExtension->LowerDeviceObject = IoAttachDeviceToDeviceStack(DeviceObject, PhysicalDeviceObject);
61
62 //
63 // init timer
64 //
65 IoInitializeTimer(DeviceObject, USBSTOR_TimerRoutine, (PVOID)DeviceExtension);
66
67 //
68 // did attaching fail
69 //
70 if (!DeviceExtension->LowerDeviceObject)
71 {
72 //
73 // device removed
74 //
75 IoDeleteDevice(DeviceObject);
76
77 return STATUS_DEVICE_REMOVED;
78 }
79
80 //
81 // set device flags
82 //
83 DeviceObject->Flags |= DO_BUFFERED_IO | DO_POWER_PAGABLE;
84
85 //
86 // device is initialized
87 //
88 DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
89
90
91 //
92 // done
93 //
94 return STATUS_SUCCESS;
95 }
96
97 VOID
98 NTAPI
99 USBSTOR_Unload(
100 PDRIVER_OBJECT DriverObject)
101 {
102 //
103 // no-op
104 //
105 }
106
107 NTSTATUS
108 NTAPI
109 USBSTOR_DispatchClose(
110 PDEVICE_OBJECT DeviceObject,
111 PIRP Irp)
112 {
113 //
114 // function always succeeds ;)
115 //
116 DPRINT("USBSTOR_DispatchClose\n");
117 Irp->IoStatus.Information = 0;
118 Irp->IoStatus.Status = STATUS_SUCCESS;
119 IoCompleteRequest(Irp, IO_NO_INCREMENT);
120 return STATUS_SUCCESS;
121 }
122
123
124 NTSTATUS
125 NTAPI
126 USBSTOR_DispatchDeviceControl(
127 PDEVICE_OBJECT DeviceObject,
128 PIRP Irp)
129 {
130 NTSTATUS Status;
131
132 //
133 // handle requests
134 //
135 Status = USBSTOR_HandleDeviceControl(DeviceObject, Irp);
136
137 //
138 // complete request
139 //
140 Irp->IoStatus.Status = Status;
141 IoCompleteRequest(Irp, IO_NO_INCREMENT);
142
143 //
144 // done
145 //
146 return Status;
147 }
148
149
150 NTSTATUS
151 NTAPI
152 USBSTOR_DispatchScsi(
153 PDEVICE_OBJECT DeviceObject,
154 PIRP Irp)
155 {
156 //
157 // handle requests
158 //
159 return USBSTOR_HandleInternalDeviceControl(DeviceObject, Irp);
160 }
161
162 NTSTATUS
163 NTAPI
164 USBSTOR_DispatchReadWrite(
165 PDEVICE_OBJECT DeviceObject,
166 PIRP Irp)
167 {
168 //
169 // read write ioctl is not supported
170 //
171 Irp->IoStatus.Information = 0;
172 Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
173 IoCompleteRequest(Irp, IO_NO_INCREMENT);
174 return STATUS_INVALID_PARAMETER;
175 }
176
177 NTSTATUS
178 NTAPI
179 USBSTOR_DispatchPnp(
180 PDEVICE_OBJECT DeviceObject,
181 PIRP Irp)
182 {
183 PUSBSTOR_COMMON_DEVICE_EXTENSION DeviceExtension;
184
185 //
186 // get common device extension
187 //
188 DeviceExtension = (PUSBSTOR_COMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
189
190 //
191 // is it for the FDO
192 //
193 if (DeviceExtension->IsFDO)
194 {
195 //
196 // dispatch pnp request to fdo pnp handler
197 //
198 return USBSTOR_FdoHandlePnp(DeviceObject, Irp);
199 }
200 else
201 {
202 //
203 // dispatch request to pdo pnp handler
204 //
205 return USBSTOR_PdoHandlePnp(DeviceObject, Irp);
206 }
207 }
208
209 NTSTATUS
210 NTAPI
211 USBSTOR_DispatchPower(
212 PDEVICE_OBJECT DeviceObject,
213 PIRP Irp)
214 {
215 PFDO_DEVICE_EXTENSION DeviceExtension;
216
217 // get common device extension
218 DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
219
220 if (DeviceExtension->Common.IsFDO)
221 {
222 PoStartNextPowerIrp(Irp);
223 IoSkipCurrentIrpStackLocation(Irp);
224 return PoCallDriver(DeviceExtension->LowerDeviceObject, Irp);
225 }
226 else
227 {
228 PoStartNextPowerIrp(Irp);
229 Irp->IoStatus.Status = STATUS_SUCCESS;
230 IoCompleteRequest(Irp, IO_NO_INCREMENT);
231 return STATUS_SUCCESS;
232 }
233 }
234
235
236
237 NTSTATUS
238 NTAPI
239 DriverEntry(
240 IN PDRIVER_OBJECT DriverObject,
241 IN PUNICODE_STRING RegPath)
242 {
243
244 DPRINT("********* USB Storage *********\n");
245
246 //
247 // driver unload routine
248 //
249 DriverObject->DriverUnload = USBSTOR_Unload;
250
251 //
252 // add device function
253 //
254 DriverObject->DriverExtension->AddDevice = USBSTOR_AddDevice;
255
256 //
257 // driver start i/o routine
258 //
259 DriverObject->DriverStartIo = USBSTOR_StartIo;
260
261 //
262 // create / close
263 //
264 DriverObject->MajorFunction[IRP_MJ_CREATE] = USBSTOR_DispatchClose;
265 DriverObject->MajorFunction[IRP_MJ_CLOSE] = USBSTOR_DispatchClose;
266
267 //
268 // scsi pass through requests
269 //
270 DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = USBSTOR_DispatchDeviceControl;
271
272 //
273 // irp dispatch read / write
274 //
275 DriverObject->MajorFunction[IRP_MJ_READ] = USBSTOR_DispatchReadWrite;
276 DriverObject->MajorFunction[IRP_MJ_WRITE] = USBSTOR_DispatchReadWrite;
277
278 //
279 // scsi queue ioctl
280 //
281 DriverObject->MajorFunction[IRP_MJ_SCSI] = USBSTOR_DispatchScsi;
282
283 //
284 // pnp processing
285 //
286 DriverObject->MajorFunction[IRP_MJ_PNP] = USBSTOR_DispatchPnp;
287
288 //
289 // power processing
290 //
291 DriverObject->MajorFunction[IRP_MJ_POWER] = USBSTOR_DispatchPower;
292
293 return STATUS_SUCCESS;
294 }
295