2 * ReactOS USB hub driver
3 * Copyright (C) 2004 Aleksey Bragin
5 * (C) 2005 Hervé Poussineau
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23 /* INCLUDES *******************************************************************/
27 /* PUBLIC AND PRIVATE FUNCTIONS ***********************************************/
31 IN PDEVICE_OBJECT Pdo
,
32 OUT PVOID
* RootHubPointer
)
36 IO_STATUS_BLOCK IoStatus
;
39 KeInitializeEvent (&Event
, NotificationEvent
, FALSE
);
41 Irp
= IoBuildDeviceIoControlRequest(IOCTL_INTERNAL_USB_GET_PARENT_HUB_INFO
,
44 RootHubPointer
, sizeof(*RootHubPointer
),
50 DPRINT("Usbhub: IoBuildDeviceIoControlRequest() failed\n");
51 return STATUS_INSUFFICIENT_RESOURCES
;
54 /* Initialize the status block before sending the IRP */
55 IoGetNextIrpStackLocation(Irp
)->MajorFunction
= IRP_MJ_INTERNAL_DEVICE_CONTROL
;
56 IoStatus
.Status
= STATUS_NOT_SUPPORTED
;
57 IoStatus
.Information
= 0;
59 Status
= IoCallDriver(Pdo
, Irp
);
61 if (Status
== STATUS_PENDING
)
63 DPRINT("Usbhub: Operation pending\n");
64 KeWaitForSingleObject(&Event
, Suspended
, KernelMode
, FALSE
, NULL
);
65 Status
= IoStatus
.Status
;
73 IN PDRIVER_OBJECT DriverObject
,
74 IN PDEVICE_OBJECT Pdo
)
77 PHUB_DEVICE_EXTENSION DeviceExtension
;
80 Status
= IoCreateDevice(DriverObject
,
81 sizeof(HUB_DEVICE_EXTENSION
),
82 NULL
, /* DeviceName */
83 FILE_DEVICE_BUS_EXTENDER
,
87 if (!NT_SUCCESS(Status
))
89 DPRINT1("Usbhub: IoCreateDevice() failed with status 0x%08lx\n", Status
);
93 // zerofill device extension
94 DeviceExtension
= (PHUB_DEVICE_EXTENSION
)Fdo
->DeviceExtension
;
95 RtlZeroMemory(DeviceExtension
, sizeof(HUB_DEVICE_EXTENSION
));
97 /* Get a pointer to the linux structure created by the USB controller,
98 * by sending IOCTL_INTERNAL_USB_GET_PARENT_HUB_INFO to lower device.
100 Status
= GetRootHubPointer(Pdo
, (PVOID
*)&DeviceExtension
->dev
);
101 if (!NT_SUCCESS(Status
))
103 DPRINT("Usbhub: GetRootHubPointer() failed with status 0x%08lx\n", Status
);
107 DeviceExtension
->dev
->dev
.dev_ext
= Pdo
;
109 DeviceExtension
->IsFDO
= TRUE
;
110 Fdo
->Flags
|= DO_POWER_PAGABLE
;
111 Status
= IoAttachDeviceToDeviceStackSafe(Fdo
, Pdo
, &DeviceExtension
->LowerDevice
);
112 if (!NT_SUCCESS(Status
))
114 DPRINT("Usbhub: IoAttachDeviceToDeviceStackSafe() failed with status 0x%08lx\n", Status
);
118 Fdo
->Flags
|= DO_BUFFERED_IO
;
119 Fdo
->Flags
&= ~DO_DEVICE_INITIALIZING
;
121 return STATUS_SUCCESS
;
124 static NTSTATUS NTAPI
126 IN PDEVICE_OBJECT DeviceObject
,
131 if (((PHUB_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
)->IsFDO
)
133 DPRINT1("Usbhub: FDO stub for major function 0x%lx\n",
134 IoGetCurrentIrpStackLocation(Irp
)->MajorFunction
);
138 return ForwardIrpAndForget(DeviceObject
, Irp
);
142 /* We can't forward request to the lower driver, because
143 * we are a Pdo, so we don't have lower driver...
145 DPRINT1("Usbhub: PDO stub for major function 0x%lx\n",
146 IoGetCurrentIrpStackLocation(Irp
)->MajorFunction
);
152 Status
= Irp
->IoStatus
.Status
;
153 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
157 static NTSTATUS NTAPI
158 DispatchDeviceControl(PDEVICE_OBJECT DeviceObject
, PIRP Irp
)
160 if (((PHUB_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
)->IsFDO
)
161 return UsbhubDeviceControlFdo(DeviceObject
, Irp
);
163 return IrpStub(DeviceObject
, Irp
);
166 static NTSTATUS NTAPI
167 DispatchInternalDeviceControl(PDEVICE_OBJECT DeviceObject
, PIRP Irp
)
169 if (((PHUB_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
)->IsFDO
)
170 return IrpStub(DeviceObject
, Irp
);
172 return UsbhubInternalDeviceControlPdo(DeviceObject
, Irp
);
175 static NTSTATUS NTAPI
176 DispatchPnp(PDEVICE_OBJECT DeviceObject
, PIRP Irp
)
178 if (((PHUB_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
)->IsFDO
)
179 return UsbhubPnpFdo(DeviceObject
, Irp
);
181 return UsbhubPnpPdo(DeviceObject
, Irp
);
185 * Standard DriverEntry method.
189 IN PDRIVER_OBJECT DriverObject
,
190 IN PUNICODE_STRING RegistryPath
)
194 DriverObject
->DriverExtension
->AddDevice
= UsbhubAddDevice
;
196 for (i
= 0; i
<= IRP_MJ_MAXIMUM_FUNCTION
; i
++)
197 DriverObject
->MajorFunction
[i
] = IrpStub
;
199 DriverObject
->MajorFunction
[IRP_MJ_CREATE
] = UsbhubCreate
;
200 DriverObject
->MajorFunction
[IRP_MJ_CLOSE
] = UsbhubClose
;
201 DriverObject
->MajorFunction
[IRP_MJ_CLEANUP
] = UsbhubCleanup
;
202 DriverObject
->MajorFunction
[IRP_MJ_DEVICE_CONTROL
] = DispatchDeviceControl
;
203 DriverObject
->MajorFunction
[IRP_MJ_INTERNAL_DEVICE_CONTROL
] = DispatchInternalDeviceControl
;
204 DriverObject
->MajorFunction
[IRP_MJ_PNP
] = DispatchPnp
;
206 return STATUS_SUCCESS
;