xref: /reactos/drivers/usb/usbhub/usbhub.c (revision 80733143)
1 /*
2  * PROJECT:         ReactOS Universal Serial Bus Hub Driver
3  * LICENSE:         GPL - See COPYING in the top level directory
4  * FILE:            drivers/usb/usbhub/usbhub.c
5  * PURPOSE:         UsbHub Driver
6  * PROGRAMMERS:
7  *                  Hervé Poussineau (hpoussin@reactos.org)
8  *                  Michael Martin (michael.martin@reactos.org)
9  *                  Johannes Anderwald (johannes.anderwald@reactos.org)
10  */
11 
12 #include "usbhub.h"
13 
14 #define NDEBUG
15 #include <debug.h>
16 
17 NTSTATUS NTAPI
18 USBHUB_Create(
19     IN PDEVICE_OBJECT DeviceObject,
20     IN PIRP Irp)
21 {
22     DPRINT("USBHUB: IRP_MJ_CREATE\n");
23 
24     Irp->IoStatus.Status = STATUS_SUCCESS;
25     Irp->IoStatus.Information = 0;
26     IoCompleteRequest(Irp, IO_NO_INCREMENT);
27     return STATUS_SUCCESS;
28 }
29 
30 NTSTATUS NTAPI
31 USBHUB_Close(
32     IN PDEVICE_OBJECT DeviceObject,
33     IN PIRP Irp)
34 {
35     DPRINT("USBHUB: IRP_MJ_CLOSE\n");
36 
37     Irp->IoStatus.Status = STATUS_SUCCESS;
38     Irp->IoStatus.Information = 0;
39     IoCompleteRequest(Irp, IO_NO_INCREMENT);
40     return STATUS_SUCCESS;
41 }
42 
43 NTSTATUS NTAPI
44 USBHUB_Cleanup(
45     IN PDEVICE_OBJECT DeviceObject,
46     IN PIRP Irp)
47 {
48     DPRINT("USBHUB: IRP_MJ_CLEANUP\n");
49 
50     Irp->IoStatus.Status = STATUS_SUCCESS;
51     Irp->IoStatus.Information = 0;
52     IoCompleteRequest(Irp, IO_NO_INCREMENT);
53     return STATUS_SUCCESS;
54 }
55 
56 
57 NTSTATUS NTAPI
58 USBHUB_AddDevice(
59     IN PDRIVER_OBJECT DriverObject,
60     IN PDEVICE_OBJECT PhysicalDeviceObject)
61 {
62     PDEVICE_OBJECT DeviceObject;
63     PHUB_DEVICE_EXTENSION HubDeviceExtension;
64     NTSTATUS Status;
65     DPRINT("USBHUB: AddDevice (%p)\n", PhysicalDeviceObject);
66     //
67     // Create the Device Object
68     //
69     Status = IoCreateDevice(DriverObject,
70                             sizeof(HUB_DEVICE_EXTENSION),
71                             NULL,
72                             FILE_DEVICE_BUS_EXTENDER,
73                             FILE_AUTOGENERATED_DEVICE_NAME,
74                             FALSE,
75                             &DeviceObject);
76 
77     if (!NT_SUCCESS(Status))
78     {
79         DPRINT1("USBHUB: IoCreateDevice() failed with status 0x%08lx\n", Status);
80         return Status;
81     }
82 
83     //
84     // Zero Hub Extension
85     //
86     HubDeviceExtension = (PHUB_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
87     RtlZeroMemory(HubDeviceExtension, sizeof(HUB_DEVICE_EXTENSION));
88 
89     INITIALIZE_PNP_STATE(HubDeviceExtension->Common);
90 
91     //
92     // Set this to Fdo
93     //
94     HubDeviceExtension->Common.IsFDO = TRUE;
95     DeviceObject->Flags |= DO_POWER_PAGABLE;
96 
97     // initialize mutex
98     KeInitializeGuardedMutex(&HubDeviceExtension->HubMutexLock);
99 
100     // initialize remove lock
101     IoInitializeRemoveLock(&HubDeviceExtension->Common.RemoveLock, 'buH', 0, 0);
102 
103     //
104     // initialize reset complete event
105     //
106     KeInitializeEvent(&HubDeviceExtension->ResetComplete, NotificationEvent, FALSE);
107 
108     //
109     // Attached to lower device
110     //
111     //Status = IoAttachDeviceToDeviceStackSafe(Fdo, Pdo, &DeviceExtension->LowerDevice);
112     HubDeviceExtension->LowerDeviceObject = IoAttachDeviceToDeviceStack(DeviceObject, PhysicalDeviceObject);
113     if (!NT_SUCCESS(Status))
114     {
115         DPRINT1("USBHUB: IoAttachDeviceToDeviceStackSafe() failed with status 0x%08lx\n", Status);
116         IoDeleteDevice(DeviceObject);
117         return Status;
118     }
119 
120     DeviceObject->Flags |= DO_BUFFERED_IO;
121     DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
122 
123     return STATUS_SUCCESS;
124 }
125 
126 static NTSTATUS NTAPI
127 USBHUB_IrpStub(
128     IN PDEVICE_OBJECT DeviceObject,
129     IN PIRP Irp)
130 {
131     NTSTATUS Status;
132 
133     if (((PHUB_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->Common.IsFDO)
134     {
135         DPRINT1("Usbhub: FDO stub for major function 0x%lx\n",
136             IoGetCurrentIrpStackLocation(Irp)->MajorFunction);
137         return ForwardIrpAndForget(DeviceObject, Irp);
138     }
139     else
140     {
141         //
142         // Cant forward as we are the PDO!
143         //
144         DPRINT1("USBHUB: ERROR- PDO stub for major function 0x%lx\n",
145             IoGetCurrentIrpStackLocation(Irp)->MajorFunction);
146 #ifndef NDEBUG
147         DbgBreakPoint();
148 #endif
149     }
150 
151     Status = Irp->IoStatus.Status;
152     IoCompleteRequest(Irp, IO_NO_INCREMENT);
153     return Status;
154 }
155 
156 
157 NTSTATUS NTAPI
158 USBHUB_DispatchDeviceControl(
159     PDEVICE_OBJECT DeviceObject,
160     PIRP Irp)
161 {
162     DPRINT("Usbhub: DispatchDeviceControl\n");
163     if (((PHUB_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->Common.IsFDO)
164         return USBHUB_FdoHandleDeviceControl(DeviceObject, Irp);
165     else
166         return USBHUB_IrpStub(DeviceObject, Irp);
167 }
168 
169 NTSTATUS NTAPI
170 USBHUB_DispatchSystemControl(
171     PDEVICE_OBJECT DeviceObject,
172     PIRP Irp)
173 {
174     DPRINT("Usbhub: DispatchSystemControl\n");
175     if (((PHUB_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->Common.IsFDO)
176         return USBHUB_IrpStub(DeviceObject, Irp);
177     else
178         return USBHUB_IrpStub(DeviceObject, Irp);
179 }
180 
181 NTSTATUS NTAPI
182 USBHUB_DispatchInternalDeviceControl(
183     PDEVICE_OBJECT DeviceObject,
184     PIRP Irp)
185 {
186     DPRINT("Usbhub: DispatchInternalDeviceControl\n");
187     if (((PHUB_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->Common.IsFDO)
188         return USBHUB_IrpStub(DeviceObject, Irp);
189     else
190         return USBHUB_PdoHandleInternalDeviceControl(DeviceObject, Irp);
191 }
192 
193 NTSTATUS NTAPI
194 USBHUB_DispatchPnp(
195     PDEVICE_OBJECT DeviceObject,
196     PIRP Irp)
197 {
198     DPRINT("USBHUB: DispatchPnp\n");
199     if (((PHUB_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->Common.IsFDO)
200         return USBHUB_FdoHandlePnp(DeviceObject, Irp);
201     else
202         return USBHUB_PdoHandlePnp(DeviceObject, Irp);
203 }
204 
205 NTSTATUS NTAPI
206 USBHUB_DispatchPower(
207     PDEVICE_OBJECT DeviceObject,
208     PIRP Irp)
209 {
210     PIO_STACK_LOCATION IoStack;
211     PHUB_DEVICE_EXTENSION DeviceExtension;
212     NTSTATUS Status;
213     IoStack = IoGetCurrentIrpStackLocation(Irp);
214     DeviceExtension = DeviceObject->DeviceExtension;
215 
216     Status = IoAcquireRemoveLock(&DeviceExtension->Common.RemoveLock, Irp);
217     if (!NT_SUCCESS(Status))
218     {
219         Irp->IoStatus.Status = Status;
220         IoCompleteRequest(Irp, IO_NO_INCREMENT);
221         return Status;
222     }
223 
224     DPRINT1("Power Function %x\n", IoStack->MinorFunction);
225 
226     if (DeviceExtension->Common.IsFDO)
227     {
228         PoStartNextPowerIrp(Irp);
229         IoSkipCurrentIrpStackLocation(Irp);
230         Status = PoCallDriver(DeviceExtension->LowerDeviceObject, Irp);
231         IoReleaseRemoveLock(&DeviceExtension->Common.RemoveLock, Irp);
232         return Status;
233     }
234 
235     switch (IoStack->MinorFunction)
236     {
237         case IRP_MN_SET_POWER:
238         {
239             DPRINT("IRP_MN_SET_POWER\n");
240             break;
241         }
242         case IRP_MN_QUERY_POWER:
243         {
244             DPRINT("IRP_MN_QUERY_POWER\n");
245             break;
246         }
247         case IRP_MN_WAIT_WAKE:
248         {
249             DPRINT("IRP_MN_WAIT_WAKE\n");
250             break;
251         }
252         default:
253         {
254             DPRINT1("PDO IRP_MJ_POWER / unknown minor function 0x%lx\n", IoStack->MinorFunction);
255             IoCompleteRequest(Irp, IO_NO_INCREMENT);
256             return Irp->IoStatus.Status;
257         }
258     }
259 
260     PoStartNextPowerIrp(Irp);
261     Irp->IoStatus.Status = STATUS_SUCCESS;
262     IoCompleteRequest(Irp, IO_NO_INCREMENT);
263     IoReleaseRemoveLock(&DeviceExtension->Common.RemoveLock, Irp);
264     return STATUS_SUCCESS;
265 }
266 
267 VOID
268 NTAPI
269 USBHUB_Unload(
270     IN PDRIVER_OBJECT DriverObject)
271 {
272     UNIMPLEMENTED;
273 }
274 
275 
276 NTSTATUS NTAPI
277 DriverEntry(
278     IN PDRIVER_OBJECT DriverObject,
279     IN PUNICODE_STRING RegistryPath)
280 {
281     DriverObject->DriverExtension->AddDevice = USBHUB_AddDevice;
282     DriverObject->DriverUnload = USBHUB_Unload;
283 
284     DPRINT("USBHUB: DriverEntry\n");
285 
286     DriverObject->MajorFunction[IRP_MJ_CREATE] = USBHUB_Create;
287     DriverObject->MajorFunction[IRP_MJ_CLOSE] = USBHUB_Close;
288     DriverObject->MajorFunction[IRP_MJ_CLEANUP] = USBHUB_Cleanup;
289     DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = USBHUB_DispatchDeviceControl;
290     DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = USBHUB_DispatchSystemControl;
291     DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = USBHUB_DispatchInternalDeviceControl;
292     DriverObject->MajorFunction[IRP_MJ_PNP] = USBHUB_DispatchPnp;
293     DriverObject->MajorFunction[IRP_MJ_POWER] =USBHUB_DispatchPower;
294 
295     return STATUS_SUCCESS;
296 }
297 
298