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