2 ReactOS specific functions for OHCI module
3 by Aleksey Bragin (aleksey@reactos.com)
4 Some parts of code are inspired (or even just copied) from ReactOS Videoport driver
8 #include <ddk/ntddkbd.h>
9 #include <ddk/ntdd8042.h>
12 #include "../usb_wrapper.h"
13 #include "../core/hcd.h"
14 #include "ohci_main.h"
16 // declare basic init funcs
17 void init_wrapper(struct pci_dev
*probe_dev
);
18 int ohci_hcd_pci_init (void);
19 void ohci_hcd_pci_cleanup (void);
20 int STDCALL
usb_init(void);
21 void STDCALL
usb_exit(void);
22 extern struct pci_driver ohci_pci_driver
;
23 extern const struct pci_device_id pci_ids
[];
26 // This should be removed, but for testing purposes it's here
28 //struct pci_device_id *dev_id;
29 static bool xbox_workaround
=false;
31 // data for embedded drivers
32 CONNECT_DATA KbdClassInformation
;
33 CONNECT_DATA MouseClassInformation
;
34 PDEVICE_OBJECT KeyboardFdo
= NULL
;
35 PDEVICE_OBJECT MouseFdo
= NULL
;
38 #define USB_OHCI_TAG TAG('u','s','b','o')
40 NTSTATUS
AddDevice_Keyboard(PDRIVER_OBJECT DriverObject
, PDEVICE_OBJECT pdo
)
42 UNICODE_STRING DeviceName
= RTL_CONSTANT_STRING(L
"\\Device\\KeyboardClass0");
46 Status
= IoCreateDevice(DriverObject
,
50 FILE_DEVICE_SECURE_OPEN
,
54 if (!NT_SUCCESS(Status
))
56 DPRINT1("IoCreateDevice for usb keyboard driver failed\n");
60 fdo
->Flags
&= ~DO_DEVICE_INITIALIZING
;
61 DPRINT1("Created keyboard fdo: %p\n", fdo
);
63 return STATUS_SUCCESS
;
66 NTSTATUS
AddDevice_Mouse(PDRIVER_OBJECT DriverObject
, PDEVICE_OBJECT pdo
)
68 UNICODE_STRING DeviceName
= RTL_CONSTANT_STRING(L
"\\Device\\PointerClass0");
72 Status
= IoCreateDevice(DriverObject
,
76 FILE_DEVICE_SECURE_OPEN
,
80 if (!NT_SUCCESS(Status
))
82 DPRINT1("IoCreateDevice for usb mouse driver failed\n");
86 fdo
->Flags
&= ~DO_DEVICE_INITIALIZING
;
88 DPRINT1("Created mouse fdo: %p\n", fdo
);
90 return STATUS_SUCCESS
;
94 NTSTATUS STDCALL
AddDevice(PDRIVER_OBJECT DriverObject
, PDEVICE_OBJECT pdo
)
98 WCHAR DeviceBuffer
[20];
99 UNICODE_STRING DeviceName
;
100 POHCI_DRIVER_EXTENSION DriverExtension
;
101 POHCI_DEVICE_EXTENSION DeviceExtension
;
102 ULONG Size
, DeviceNumber
;
104 DPRINT1("ohci: AddDevice called\n");
107 return STATUS_INSUFFICIENT_RESOURCES
; // Fail for any other host controller than the first
109 xbox_workaround
= true;
111 // Allocate driver extension now
112 DriverExtension
= IoGetDriverObjectExtension(DriverObject
, DriverObject
);
113 if (DriverExtension
== NULL
)
115 Status
= IoAllocateDriverObjectExtension(
118 sizeof(OHCI_DRIVER_EXTENSION
),
119 (PVOID
*)&DriverExtension
);
121 if (!NT_SUCCESS(Status
))
123 DPRINT1("Allocating DriverObjectExtension failed.\n");
128 // Create a unicode device name
129 DeviceNumber
= 0; //TODO: Allocate new device number every time
130 swprintf(DeviceBuffer
, L
"\\Device\\USBFDO-%lu", DeviceNumber
);
131 RtlInitUnicodeString(&DeviceName
, DeviceBuffer
);
133 Status
= IoCreateDevice(DriverObject
,
134 sizeof(OHCI_DEVICE_EXTENSION
)/* + DriverExtension->InitializationData.HwDeviceExtensionSize*/,
136 FILE_DEVICE_CONTROLLER
,
141 if (!NT_SUCCESS(Status
))
143 DPRINT("IoCreateDevice call failed with status 0x%08x\n", Status
);
147 // zerofill device extension
148 DeviceExtension
= (POHCI_DEVICE_EXTENSION
)fdo
->DeviceExtension
;
149 RtlZeroMemory(DeviceExtension
, sizeof(OHCI_DEVICE_EXTENSION
));
150 DeviceExtension
->NextDeviceObject
= IoAttachDeviceToDeviceStack(fdo
, pdo
);
152 fdo
->Flags
&= ~DO_DEVICE_INITIALIZING
;
154 // Initialize device extension
155 DeviceExtension
->DeviceNumber
= DeviceNumber
;
156 DeviceExtension
->PhysicalDeviceObject
= pdo
;
157 DeviceExtension
->FunctionalDeviceObject
= fdo
;
158 DeviceExtension
->DriverExtension
= DriverExtension
;
160 /* Get bus number from the upper level bus driver. */
161 Size
= sizeof(ULONG
);
162 Status
= IoGetDeviceProperty(
164 DevicePropertyBusNumber
,
166 &DeviceExtension
->SystemIoBusNumber
,
169 if (!NT_SUCCESS(Status
))
171 DPRINT("Couldn't get an information from bus driver. Panic!!!\n");
175 DPRINT("Done AddDevice\n");
177 // create embedded keyboard driver
178 Status
= AddDevice_Keyboard(DriverObject
, pdo
);
179 Status
= AddDevice_Mouse(DriverObject
, pdo
);
185 VOID STDCALL
DriverUnload(PDRIVER_OBJECT DriverObject
)
187 DPRINT1("DriverUnload()\n");
192 // Remove device (ohci_pci_driver.remove)
193 ohci_pci_driver
.remove(dev
);
195 ExFreePool(dev
->slot_name
);
198 // Perform some cleanup
199 ohci_hcd_pci_cleanup();
202 void RegisterISR(PDEVICE_OBJECT DeviceObject
)
206 POHCI_DEVICE_EXTENSION DeviceExtension
= (POHCI_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
208 /* Connect interrupt and enable them */
209 Status
= IoConnectInterrupt(
210 &DeviceExtension
->InterruptObject
, SerialInterruptService
,
212 Vector
, Dirql
, Dirql
,
213 InterruptMode
, ShareInterrupt
,
215 if (!NT_SUCCESS(Status
))
217 DPRINT("hci: IoConnectInterrupt() failed with status 0x%08x\n", Status
);
224 InitLinuxWrapper(PDEVICE_OBJECT DeviceObject
)
227 POHCI_DEVICE_EXTENSION DeviceExtension
= (POHCI_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
229 // Allocate and fill generic linux structs
230 dev
= ExAllocatePoolWithTag(PagedPool
, sizeof(struct pci_dev
), USB_OHCI_TAG
);
231 dev
->irq
= DeviceExtension
->InterruptVector
;
232 dev
->dev_ext
= (PVOID
)DeviceExtension
;
233 dev
->dev
.dev_ext
= (PVOID
)DeviceExtension
;
234 dev
->slot_name
= ExAllocatePoolWithTag(NonPagedPool
, 128, USB_OHCI_TAG
); // 128 max len for slot name
239 strcpy(dev
->dev
.name
, "OpenHCI PCI-USB Controller");
240 strcpy(dev
->slot_name
, "OHCD PCI Slot");
242 // Init the OHCI HCD. Probe will be called automatically, but will fail because id=NULL
243 Status
= ohci_hcd_pci_init();
244 //FIXME: Check status returned value
249 // Probe device with real id now
250 ohci_pci_driver
.probe(dev
, pci_ids
);
252 // Register interrupt here
253 RegisterISR(DeviceObject
);
255 DPRINT1("InitLinuxWrapper() done\n");
257 return STATUS_SUCCESS
;
261 OHCD_PnPStartDevice(IN PDEVICE_OBJECT DeviceObject
,
264 PIO_STACK_LOCATION Stack
= IoGetCurrentIrpStackLocation(Irp
);
265 PDRIVER_OBJECT DriverObject
;
266 POHCI_DRIVER_EXTENSION DriverExtension
;
267 POHCI_DEVICE_EXTENSION DeviceExtension
;
268 PCM_RESOURCE_LIST AllocatedResources
;
270 NTSTATUS Status
; // debug
271 LONGLONG delay
; // debug
273 if (DeviceObject
== KeyboardFdo
|| DeviceObject
== MouseFdo
)
274 return STATUS_SUCCESS
;
277 * Get the initialization data we saved in VideoPortInitialize.
279 DriverObject
= DeviceObject
->DriverObject
;
280 DriverExtension
= IoGetDriverObjectExtension(DriverObject
, DriverObject
);
281 DeviceExtension
= (POHCI_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
284 * Store some resources in the DeviceExtension.
286 AllocatedResources
= Stack
->Parameters
.StartDevice
.AllocatedResources
;
287 if (AllocatedResources
!= NULL
)
289 CM_FULL_RESOURCE_DESCRIPTOR
*FullList
;
290 CM_PARTIAL_RESOURCE_DESCRIPTOR
*Descriptor
;
292 ULONG ResourceListSize
;
294 /* Save the resource list */
295 ResourceCount
= AllocatedResources
->List
[0].PartialResourceList
.Count
;
297 FIELD_OFFSET(CM_RESOURCE_LIST
, List
[0].PartialResourceList
.
298 PartialDescriptors
[ResourceCount
]);
299 DeviceExtension
->AllocatedResources
= ExAllocatePool(PagedPool
, ResourceListSize
);
300 if (DeviceExtension
->AllocatedResources
== NULL
)
302 return STATUS_INSUFFICIENT_RESOURCES
;
305 RtlCopyMemory(DeviceExtension
->AllocatedResources
,
309 /* Get the interrupt level/vector - needed by HwFindAdapter sometimes */
310 for (FullList
= AllocatedResources
->List
;
311 FullList
< AllocatedResources
->List
+ AllocatedResources
->Count
;
314 /* FIXME: Is this ASSERT ok for resources from the PNP manager? */
315 /*ASSERT(FullList->InterfaceType == PCIBus &&
316 FullList->BusNumber == DeviceExtension->SystemIoBusNumber &&
317 1 == FullList->PartialResourceList.Version &&
318 1 == FullList->PartialResourceList.Revision);*/
319 for (Descriptor
= FullList
->PartialResourceList
.PartialDescriptors
;
320 Descriptor
< FullList
->PartialResourceList
.PartialDescriptors
+ FullList
->PartialResourceList
.Count
;
323 if (Descriptor
->Type
== CmResourceTypeInterrupt
)
325 DeviceExtension
->InterruptLevel
= Descriptor
->u
.Interrupt
.Level
;
326 DeviceExtension
->InterruptVector
= Descriptor
->u
.Interrupt
.Vector
;
328 else if (Descriptor
->Type
== CmResourceTypeMemory
)
330 DeviceExtension
->BaseAddress
= Descriptor
->u
.Memory
.Start
;
331 DeviceExtension
->BaseAddrLength
= Descriptor
->u
.Memory
.Length
;
336 DPRINT1("Interrupt level: 0x%x Interrupt Vector: 0x%x\n",
337 DeviceExtension
->InterruptLevel
,
338 DeviceExtension
->InterruptVector
);
341 * Init wrapper with this object
343 //return InitLinuxWrapper(DeviceObject);
346 Status
= InitLinuxWrapper(DeviceObject
);
348 //delay = -10000000*30; // wait 30 secs
349 //KeDelayExecutionThread(KernelMode, FALSE, (LARGE_INTEGER *)&delay); //wait_us(1);
355 NTSTATUS STDCALL
DispatchPnp(PDEVICE_OBJECT DeviceObject
, PIRP Irp
)
357 PIO_STACK_LOCATION IrpSp
;
360 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
362 DPRINT("PNP for %p, minorfunc=0x%x\n", DeviceObject
, IrpSp
->MinorFunction
);
365 switch (IrpSp
->MinorFunction
)
367 case IRP_MN_START_DEVICE
:
368 //Status = IntVideoPortForwardIrpAndWait(DeviceObject, Irp);
369 //if (NT_SUCCESS(Status) && NT_SUCCESS(Irp->IoStatus.Status))
371 Status
= OHCD_PnPStartDevice(DeviceObject
, Irp
);
372 Irp
->IoStatus
.Status
= Status
;
373 Irp
->IoStatus
.Information
= 0;
374 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
378 case IRP_MN_REMOVE_DEVICE
:
379 case IRP_MN_QUERY_REMOVE_DEVICE
:
380 case IRP_MN_CANCEL_REMOVE_DEVICE
:
381 case IRP_MN_SURPRISE_REMOVAL
:
383 case IRP_MN_STOP_DEVICE
:
384 //Status = IntVideoPortForwardIrpAndWait(DeviceObject, Irp);
385 //if (NT_SUCCESS(Status) && NT_SUCCESS(Irp->IoStatus.Status))
386 Status
= STATUS_SUCCESS
;
387 Irp
->IoStatus
.Status
= Status
;
388 Irp
->IoStatus
.Information
= 0;
389 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
391 IoDeleteDevice(DeviceObject
); // just delete device for now
394 case IRP_MN_QUERY_STOP_DEVICE
:
395 case IRP_MN_CANCEL_STOP_DEVICE
:
396 Status
= STATUS_SUCCESS
;
397 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
398 Irp
->IoStatus
.Information
= 0;
399 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
403 return STATUS_NOT_IMPLEMENTED
;
410 NTSTATUS STDCALL
DispatchPower(PDEVICE_OBJECT fido
, PIRP Irp
)
412 DbgPrint("IRP_MJ_POWER dispatch\n");
413 return STATUS_SUCCESS
;
416 NTSTATUS STDCALL
UsbCoreDispatch(PDEVICE_OBJECT DeviceObject
, PIRP Irp
)
418 ULONG MajorFunction
= IoGetCurrentIrpStackLocation(Irp
)->MajorFunction
;
420 DPRINT("usbohci: Dispatching major function 0x%lx\n", MajorFunction
);
422 IoCompleteRequest (Irp
, IO_NO_INCREMENT
);
423 return STATUS_SUCCESS
;
427 NTSTATUS STDCALL
UsbCoreInternalDeviceControl(PDEVICE_OBJECT DeviceObject
, PIRP Irp
)
429 NTSTATUS Status
= STATUS_INVALID_DEVICE_REQUEST
;
431 DPRINT("INT_IOCTL for %p, code=0x%x\n", DeviceObject
, IoGetCurrentIrpStackLocation(Irp
)->Parameters
.DeviceIoControl
.IoControlCode
);
433 if (DeviceObject
== KeyboardFdo
)
435 // it's keyboard's IOCTL
436 PIO_STACK_LOCATION Stk
;
438 Irp
->IoStatus
.Information
= 0;
439 Stk
= IoGetCurrentIrpStackLocation(Irp
);
441 switch (Stk
->Parameters
.DeviceIoControl
.IoControlCode
) {
442 case IOCTL_INTERNAL_KEYBOARD_CONNECT
:
443 DPRINT("IOCTL_INTERNAL_KEYBOARD_CONNECT\n");
444 if (Stk
->Parameters
.DeviceIoControl
.InputBufferLength
< sizeof(CONNECT_DATA
)) {
445 DPRINT1("Keyboard IOCTL_INTERNAL_KEYBOARD_CONNECT "
446 "invalid buffer size\n");
447 Irp
->IoStatus
.Status
= STATUS_INVALID_PARAMETER
;
451 memcpy(&KbdClassInformation
,
452 Stk
->Parameters
.DeviceIoControl
.Type3InputBuffer
,
453 sizeof(CONNECT_DATA
));
455 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
458 case IOCTL_INTERNAL_I8042_KEYBOARD_WRITE_BUFFER
:
459 DPRINT("IOCTL_INTERNAL_I8042_KEYBOARD_WRITE_BUFFER\n");
460 if (Stk
->Parameters
.DeviceIoControl
.InputBufferLength
< 1) {
461 Irp
->IoStatus
.Status
= STATUS_INVALID_PARAMETER
;
464 /* if (!DevExt->KeyboardInterruptObject) {
465 Irp->IoStatus.Status = STATUS_DEVICE_NOT_READY;
469 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
471 case IOCTL_KEYBOARD_QUERY_ATTRIBUTES
:
472 DPRINT("IOCTL_KEYBOARD_QUERY_ATTRIBUTES\n");
473 if (Stk
->Parameters
.DeviceIoControl
.OutputBufferLength
<
474 sizeof(KEYBOARD_ATTRIBUTES
)) {
475 DPRINT("Keyboard IOCTL_KEYBOARD_QUERY_ATTRIBUTES "
476 "invalid buffer size\n");
477 Irp
->IoStatus
.Status
= STATUS_BUFFER_TOO_SMALL
;
480 /*memcpy(Irp->AssociatedIrp.SystemBuffer,
481 &DevExt->KeyboardAttributes,
482 sizeof(KEYBOARD_ATTRIBUTES));*/
484 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
486 case IOCTL_KEYBOARD_QUERY_INDICATORS
:
487 DPRINT("IOCTL_KEYBOARD_QUERY_INDICATORS\n");
488 if (Stk
->Parameters
.DeviceIoControl
.OutputBufferLength
<
489 sizeof(KEYBOARD_INDICATOR_PARAMETERS
)) {
490 DPRINT("Keyboard IOCTL_KEYBOARD_QUERY_INDICATORS "
491 "invalid buffer size\n");
492 Irp
->IoStatus
.Status
= STATUS_BUFFER_TOO_SMALL
;
495 /*memcpy(Irp->AssociatedIrp.SystemBuffer,
496 &DevExt->KeyboardIndicators,
497 sizeof(KEYBOARD_INDICATOR_PARAMETERS));*/
499 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
501 case IOCTL_KEYBOARD_QUERY_TYPEMATIC
:
502 DPRINT("IOCTL_KEYBOARD_QUERY_TYPEMATIC\n");
503 if (Stk
->Parameters
.DeviceIoControl
.OutputBufferLength
<
504 sizeof(KEYBOARD_TYPEMATIC_PARAMETERS
)) {
505 DPRINT("Keyboard IOCTL_KEYBOARD_QUERY_TYPEMATIC "
506 "invalid buffer size\n");
507 Irp
->IoStatus
.Status
= STATUS_BUFFER_TOO_SMALL
;
510 /*memcpy(Irp->AssociatedIrp.SystemBuffer,
511 &DevExt->KeyboardTypematic,
512 sizeof(KEYBOARD_TYPEMATIC_PARAMETERS));*/
514 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
516 case IOCTL_KEYBOARD_SET_INDICATORS
:
517 DPRINT("IOCTL_KEYBOARD_SET_INDICATORS\n");
518 if (Stk
->Parameters
.DeviceIoControl
.InputBufferLength
<
519 sizeof(KEYBOARD_INDICATOR_PARAMETERS
)) {
520 DPRINT("Keyboard IOCTL_KEYBOARD_SET_INDICTATORS "
521 "invalid buffer size\n");
522 Irp
->IoStatus
.Status
= STATUS_BUFFER_TOO_SMALL
;
526 /*memcpy(&DevExt->KeyboardIndicators,
527 Irp->AssociatedIrp.SystemBuffer,
528 sizeof(KEYBOARD_INDICATOR_PARAMETERS));*/
530 //DPRINT("%x\n", DevExt->KeyboardIndicators.LedFlags);
532 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
534 case IOCTL_KEYBOARD_SET_TYPEMATIC
:
535 DPRINT("IOCTL_KEYBOARD_SET_TYPEMATIC\n");
536 if (Stk
->Parameters
.DeviceIoControl
.InputBufferLength
<
537 sizeof(KEYBOARD_TYPEMATIC_PARAMETERS
)) {
538 DPRINT("Keyboard IOCTL_KEYBOARD_SET_TYPEMATIC "
539 "invalid buffer size\n");
540 Irp
->IoStatus
.Status
= STATUS_BUFFER_TOO_SMALL
;
544 /*memcpy(&DevExt->KeyboardTypematic,
545 Irp->AssociatedIrp.SystemBuffer,
546 sizeof(KEYBOARD_TYPEMATIC_PARAMETERS));*/
548 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
550 case IOCTL_KEYBOARD_QUERY_INDICATOR_TRANSLATION
:
551 /* We should check the UnitID, but it's kind of pointless as
552 * all keyboards are supposed to have the same one
555 if (Stk
->Parameters
.DeviceIoControl
.OutputBufferLength
<
556 sizeof(LOCAL_KEYBOARD_INDICATOR_TRANSLATION
)) {
557 DPRINT("IOCTL_KEYBOARD_QUERY_INDICATOR_TRANSLATION: "
558 "invalid buffer size (expected)\n");
559 /* It's to query the buffer size */
560 Irp
->IoStatus
.Status
= STATUS_BUFFER_TOO_SMALL
;
563 Irp
->IoStatus
.Information
=
564 sizeof(LOCAL_KEYBOARD_INDICATOR_TRANSLATION
);
566 /*memcpy(Irp->AssociatedIrp.SystemBuffer,
567 &IndicatorTranslation,
568 sizeof(LOCAL_KEYBOARD_INDICATOR_TRANSLATION));*/
570 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
572 case IOCTL_INTERNAL_I8042_HOOK_KEYBOARD
:
573 /* Nothing to do here */
574 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
577 Irp
->IoStatus
.Status
= STATUS_INVALID_DEVICE_REQUEST
;
582 Status
= Irp
->IoStatus
.Status
;
584 else if (DeviceObject
== MouseFdo
)
586 // it's mouse's IOCTL
587 PIO_STACK_LOCATION Stk
;
589 Irp
->IoStatus
.Information
= 0;
590 Stk
= IoGetCurrentIrpStackLocation(Irp
);
592 switch (Stk
->Parameters
.DeviceIoControl
.IoControlCode
) {
593 case IOCTL_INTERNAL_MOUSE_CONNECT
:
594 DPRINT("IOCTL_INTERNAL_MOUSE_CONNECT\n");
595 if (Stk
->Parameters
.DeviceIoControl
.InputBufferLength
< sizeof(CONNECT_DATA
)) {
596 DPRINT1("Mouse IOCTL_INTERNAL_MOUSE_CONNECT "
597 "invalid buffer size\n");
598 Irp
->IoStatus
.Status
= STATUS_INVALID_PARAMETER
;
599 goto intcontfailure2
;
602 memcpy(&MouseClassInformation
,
603 Stk
->Parameters
.DeviceIoControl
.Type3InputBuffer
,
604 sizeof(CONNECT_DATA
));
606 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
610 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;//STATUS_INVALID_DEVICE_REQUEST;
614 Status
= Irp
->IoStatus
.Status
;
618 DPRINT("We got IOCTL for UsbCore\n");
619 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
620 return STATUS_SUCCESS
;
624 if (Status
== STATUS_INVALID_DEVICE_REQUEST
) {
625 DPRINT1("Invalid internal device request!\n");
628 if (Status
!= STATUS_PENDING
)
629 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
636 * Standard DriverEntry method.
639 DriverEntry(IN PDRIVER_OBJECT DriverObject
, IN PUNICODE_STRING RegPath
)
642 USBPORT_INTERFACE UsbPortInterface
;
644 DriverObject
->DriverUnload
= DriverUnload
;
645 DriverObject
->DriverExtension
->AddDevice
= AddDevice
;
647 for (i
= 0; i
< IRP_MJ_MAXIMUM_FUNCTION
; i
++)
648 DriverObject
->MajorFunction
[i
] = UsbCoreDispatch
;
650 DriverObject
->MajorFunction
[IRP_MJ_PNP
] = DispatchPnp
;
651 DriverObject
->MajorFunction
[IRP_MJ_POWER
] = DispatchPower
;
652 DriverObject
->MajorFunction
[IRP_MJ_INTERNAL_DEVICE_CONTROL
] = UsbCoreInternalDeviceControl
;
654 // Register in usbcore.sys
655 UsbPortInterface
.KbdConnectData
= &KbdClassInformation
;
656 UsbPortInterface
.MouseConnectData
= &MouseClassInformation
;
658 KbdClassInformation
.ClassService
= NULL
;
659 KbdClassInformation
.ClassDeviceObject
= NULL
;
660 MouseClassInformation
.ClassService
= NULL
;
661 MouseClassInformation
.ClassDeviceObject
= NULL
;
663 RegisterPortDriver(DriverObject
, &UsbPortInterface
);
665 return STATUS_SUCCESS
;