xref: /reactos/drivers/usb/usbstor/usbstor.c (revision 4f0b8d3d)
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 
296