Start of big changes in layout of USB code. Fireball and I are agreeing on these...
[reactos.git] / reactos / drivers / usb / cromwell / host / ohci_main.c
1 /*
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
5 */
6
7 #include <ddk/ntddk.h>
8 #include <ddk/ntddkbd.h>
9 #include <ddk/ntdd8042.h>
10
11 #include <debug.h>
12 #include "../usb_wrapper.h"
13 #include "../core/hcd.h"
14 #include "ohci_main.h"
15
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[];
24
25
26 // This should be removed, but for testing purposes it's here
27 struct pci_dev *dev;
28 //struct pci_device_id *dev_id;
29 static bool xbox_workaround=false;
30
31 // data for embedded drivers
32 CONNECT_DATA KbdClassInformation;
33 CONNECT_DATA MouseClassInformation;
34 PDEVICE_OBJECT KeyboardFdo = NULL;
35 PDEVICE_OBJECT MouseFdo = NULL;
36
37
38 #define USB_OHCI_TAG TAG('u','s','b','o')
39
40 NTSTATUS AddDevice_Keyboard(PDRIVER_OBJECT DriverObject, PDEVICE_OBJECT pdo)
41 {
42 UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Device\\KeyboardClass0");
43 PDEVICE_OBJECT fdo;
44 NTSTATUS Status;
45
46 Status = IoCreateDevice(DriverObject,
47 8, // debug
48 &DeviceName,
49 FILE_DEVICE_KEYBOARD,
50 FILE_DEVICE_SECURE_OPEN,
51 TRUE,
52 &fdo);
53
54 if (!NT_SUCCESS(Status))
55 {
56 DPRINT1("IoCreateDevice for usb keyboard driver failed\n");
57 return Status;
58 }
59 KeyboardFdo = fdo;
60 fdo->Flags &= ~DO_DEVICE_INITIALIZING;
61 DPRINT1("Created keyboard fdo: %p\n", fdo);
62
63 return STATUS_SUCCESS;
64 }
65
66 NTSTATUS AddDevice_Mouse(PDRIVER_OBJECT DriverObject, PDEVICE_OBJECT pdo)
67 {
68 UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Device\\PointerClass0");
69 PDEVICE_OBJECT fdo;
70 NTSTATUS Status;
71
72 Status = IoCreateDevice(DriverObject,
73 8, // debug
74 &DeviceName,
75 FILE_DEVICE_MOUSE,
76 FILE_DEVICE_SECURE_OPEN,
77 TRUE,
78 &fdo);
79
80 if (!NT_SUCCESS(Status))
81 {
82 DPRINT1("IoCreateDevice for usb mouse driver failed\n");
83 return Status;
84 }
85 MouseFdo = fdo;
86 fdo->Flags &= ~DO_DEVICE_INITIALIZING;
87
88 DPRINT1("Created mouse fdo: %p\n", fdo);
89
90 return STATUS_SUCCESS;
91 }
92
93
94 NTSTATUS STDCALL AddDevice(PDRIVER_OBJECT DriverObject, PDEVICE_OBJECT pdo)
95 {
96 PDEVICE_OBJECT fdo;
97 NTSTATUS Status;
98 WCHAR DeviceBuffer[20];
99 UNICODE_STRING DeviceName;
100 POHCI_DRIVER_EXTENSION DriverExtension;
101 POHCI_DEVICE_EXTENSION DeviceExtension;
102 ULONG Size, DeviceNumber;
103
104 DPRINT1("ohci: AddDevice called\n");
105
106 if (xbox_workaround)
107 return STATUS_INSUFFICIENT_RESOURCES; // Fail for any other host controller than the first
108
109 xbox_workaround = true;
110
111 // Allocate driver extension now
112 DriverExtension = IoGetDriverObjectExtension(DriverObject, DriverObject);
113 if (DriverExtension == NULL)
114 {
115 Status = IoAllocateDriverObjectExtension(
116 DriverObject,
117 DriverObject,
118 sizeof(OHCI_DRIVER_EXTENSION),
119 (PVOID *)&DriverExtension);
120
121 if (!NT_SUCCESS(Status))
122 {
123 DPRINT1("Allocating DriverObjectExtension failed.\n");
124 return Status;
125 }
126 }
127
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);
132
133 Status = IoCreateDevice(DriverObject,
134 sizeof(OHCI_DEVICE_EXTENSION)/* + DriverExtension->InitializationData.HwDeviceExtensionSize*/,
135 &DeviceName,
136 FILE_DEVICE_CONTROLLER,
137 0,
138 FALSE,
139 &fdo);
140
141 if (!NT_SUCCESS(Status))
142 {
143 DPRINT("IoCreateDevice call failed with status 0x%08x\n", Status);
144 return Status;
145 }
146
147 // zerofill device extension
148 DeviceExtension = (POHCI_DEVICE_EXTENSION)fdo->DeviceExtension;
149 RtlZeroMemory(DeviceExtension, sizeof(OHCI_DEVICE_EXTENSION));
150 DeviceExtension->NextDeviceObject = IoAttachDeviceToDeviceStack(fdo, pdo);
151
152 fdo->Flags &= ~DO_DEVICE_INITIALIZING;
153
154 // Initialize device extension
155 DeviceExtension->DeviceNumber = DeviceNumber;
156 DeviceExtension->PhysicalDeviceObject = pdo;
157 DeviceExtension->FunctionalDeviceObject = fdo;
158 DeviceExtension->DriverExtension = DriverExtension;
159
160 /* Get bus number from the upper level bus driver. */
161 Size = sizeof(ULONG);
162 Status = IoGetDeviceProperty(
163 pdo,
164 DevicePropertyBusNumber,
165 Size,
166 &DeviceExtension->SystemIoBusNumber,
167 &Size);
168
169 if (!NT_SUCCESS(Status))
170 {
171 DPRINT("Couldn't get an information from bus driver. Panic!!!\n");
172 return Status;
173 }
174
175 DPRINT("Done AddDevice\n");
176
177 // create embedded keyboard driver
178 Status = AddDevice_Keyboard(DriverObject, pdo);
179 Status = AddDevice_Mouse(DriverObject, pdo);
180
181 return Status;
182 }
183
184
185 VOID STDCALL DriverUnload(PDRIVER_OBJECT DriverObject)
186 {
187 DPRINT1("DriverUnload()\n");
188
189 // Exit usb device
190 usb_exit();
191
192 // Remove device (ohci_pci_driver.remove)
193 ohci_pci_driver.remove(dev);
194
195 ExFreePool(dev->slot_name);
196 ExFreePool(dev);
197
198 // Perform some cleanup
199 ohci_hcd_pci_cleanup();
200 }
201
202 void RegisterISR(PDEVICE_OBJECT DeviceObject)
203 {
204 #if 0
205 NTSTATUS Status;
206 POHCI_DEVICE_EXTENSION DeviceExtension = (POHCI_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
207
208 /* Connect interrupt and enable them */
209 Status = IoConnectInterrupt(
210 &DeviceExtension->InterruptObject, SerialInterruptService,
211 DeviceObject, NULL,
212 Vector, Dirql, Dirql,
213 InterruptMode, ShareInterrupt,
214 Affinity, FALSE);
215 if (!NT_SUCCESS(Status))
216 {
217 DPRINT("hci: IoConnectInterrupt() failed with status 0x%08x\n", Status);
218 return 1;
219 }
220 #endif
221 }
222
223 NTSTATUS
224 InitLinuxWrapper(PDEVICE_OBJECT DeviceObject)
225 {
226 NTSTATUS Status;
227 POHCI_DEVICE_EXTENSION DeviceExtension = (POHCI_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
228
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
235
236 // Init wrapper
237 init_wrapper(dev);
238
239 strcpy(dev->dev.name, "OpenHCI PCI-USB Controller");
240 strcpy(dev->slot_name, "OHCD PCI Slot");
241
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
245
246 // Init core usb
247 usb_init();
248
249 // Probe device with real id now
250 ohci_pci_driver.probe(dev, pci_ids);
251
252 // Register interrupt here
253 RegisterISR(DeviceObject);
254
255 DPRINT1("InitLinuxWrapper() done\n");
256
257 return STATUS_SUCCESS;
258 }
259
260 NTSTATUS STDCALL
261 OHCD_PnPStartDevice(IN PDEVICE_OBJECT DeviceObject,
262 IN PIRP Irp)
263 {
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;
269
270 NTSTATUS Status; // debug
271 LONGLONG delay; // debug
272
273 if (DeviceObject == KeyboardFdo || DeviceObject == MouseFdo)
274 return STATUS_SUCCESS;
275
276 /*
277 * Get the initialization data we saved in VideoPortInitialize.
278 */
279 DriverObject = DeviceObject->DriverObject;
280 DriverExtension = IoGetDriverObjectExtension(DriverObject, DriverObject);
281 DeviceExtension = (POHCI_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
282
283 /*
284 * Store some resources in the DeviceExtension.
285 */
286 AllocatedResources = Stack->Parameters.StartDevice.AllocatedResources;
287 if (AllocatedResources != NULL)
288 {
289 CM_FULL_RESOURCE_DESCRIPTOR *FullList;
290 CM_PARTIAL_RESOURCE_DESCRIPTOR *Descriptor;
291 ULONG ResourceCount;
292 ULONG ResourceListSize;
293
294 /* Save the resource list */
295 ResourceCount = AllocatedResources->List[0].PartialResourceList.Count;
296 ResourceListSize =
297 FIELD_OFFSET(CM_RESOURCE_LIST, List[0].PartialResourceList.
298 PartialDescriptors[ResourceCount]);
299 DeviceExtension->AllocatedResources = ExAllocatePool(PagedPool, ResourceListSize);
300 if (DeviceExtension->AllocatedResources == NULL)
301 {
302 return STATUS_INSUFFICIENT_RESOURCES;
303 }
304
305 RtlCopyMemory(DeviceExtension->AllocatedResources,
306 AllocatedResources,
307 ResourceListSize);
308
309 /* Get the interrupt level/vector - needed by HwFindAdapter sometimes */
310 for (FullList = AllocatedResources->List;
311 FullList < AllocatedResources->List + AllocatedResources->Count;
312 FullList++)
313 {
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;
321 Descriptor++)
322 {
323 if (Descriptor->Type == CmResourceTypeInterrupt)
324 {
325 DeviceExtension->InterruptLevel = Descriptor->u.Interrupt.Level;
326 DeviceExtension->InterruptVector = Descriptor->u.Interrupt.Vector;
327 }
328 else if (Descriptor->Type == CmResourceTypeMemory)
329 {
330 DeviceExtension->BaseAddress = Descriptor->u.Memory.Start;
331 DeviceExtension->BaseAddrLength = Descriptor->u.Memory.Length;
332 }
333 }
334 }
335 }
336 DPRINT1("Interrupt level: 0x%x Interrupt Vector: 0x%x\n",
337 DeviceExtension->InterruptLevel,
338 DeviceExtension->InterruptVector);
339
340 /*
341 * Init wrapper with this object
342 */
343 //return InitLinuxWrapper(DeviceObject);
344
345 // debug wait
346 Status = InitLinuxWrapper(DeviceObject);
347
348 //delay = -10000000*30; // wait 30 secs
349 //KeDelayExecutionThread(KernelMode, FALSE, (LARGE_INTEGER *)&delay); //wait_us(1);
350
351 return Status;
352 }
353
354 // Dispatch PNP
355 NTSTATUS STDCALL DispatchPnp(PDEVICE_OBJECT DeviceObject, PIRP Irp)
356 {
357 PIO_STACK_LOCATION IrpSp;
358 NTSTATUS Status;
359
360 IrpSp = IoGetCurrentIrpStackLocation(Irp);
361
362 DPRINT("PNP for %p, minorfunc=0x%x\n", DeviceObject, IrpSp->MinorFunction);
363
364
365 switch (IrpSp->MinorFunction)
366 {
367 case IRP_MN_START_DEVICE:
368 //Status = IntVideoPortForwardIrpAndWait(DeviceObject, Irp);
369 //if (NT_SUCCESS(Status) && NT_SUCCESS(Irp->IoStatus.Status))
370
371 Status = OHCD_PnPStartDevice(DeviceObject, Irp);
372 Irp->IoStatus.Status = Status;
373 Irp->IoStatus.Information = 0;
374 IoCompleteRequest(Irp, IO_NO_INCREMENT);
375 break;
376
377
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:
382
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);
390
391 IoDeleteDevice(DeviceObject); // just delete device for now
392 break;
393
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);
400 break;
401
402 default:
403 return STATUS_NOT_IMPLEMENTED;
404 break;
405 }
406
407 return Status;
408 }
409
410 NTSTATUS STDCALL DispatchPower(PDEVICE_OBJECT fido, PIRP Irp)
411 {
412 DbgPrint("IRP_MJ_POWER dispatch\n");
413 return STATUS_SUCCESS;
414 }
415
416 NTSTATUS STDCALL UsbCoreDispatch(PDEVICE_OBJECT DeviceObject, PIRP Irp)
417 {
418 ULONG MajorFunction = IoGetCurrentIrpStackLocation(Irp)->MajorFunction;
419
420 DPRINT("usbohci: Dispatching major function 0x%lx\n", MajorFunction);
421
422 IoCompleteRequest (Irp, IO_NO_INCREMENT);
423 return STATUS_SUCCESS;
424 }
425
426
427 NTSTATUS STDCALL UsbCoreInternalDeviceControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
428 {
429 NTSTATUS Status = STATUS_INVALID_DEVICE_REQUEST;
430
431 DPRINT("INT_IOCTL for %p, code=0x%x\n", DeviceObject, IoGetCurrentIrpStackLocation(Irp)->Parameters.DeviceIoControl.IoControlCode);
432
433 if (DeviceObject == KeyboardFdo)
434 {
435 // it's keyboard's IOCTL
436 PIO_STACK_LOCATION Stk;
437
438 Irp->IoStatus.Information = 0;
439 Stk = IoGetCurrentIrpStackLocation(Irp);
440
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;
448 goto intcontfailure;
449 }
450
451 memcpy(&KbdClassInformation,
452 Stk->Parameters.DeviceIoControl.Type3InputBuffer,
453 sizeof(CONNECT_DATA));
454
455 Irp->IoStatus.Status = STATUS_SUCCESS;
456 break;
457
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;
462 goto intcontfailure;
463 }
464 /* if (!DevExt->KeyboardInterruptObject) {
465 Irp->IoStatus.Status = STATUS_DEVICE_NOT_READY;
466 goto intcontfailure;
467 }*/
468
469 Irp->IoStatus.Status = STATUS_SUCCESS;
470 break;
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;
478 goto intcontfailure;
479 }
480 /*memcpy(Irp->AssociatedIrp.SystemBuffer,
481 &DevExt->KeyboardAttributes,
482 sizeof(KEYBOARD_ATTRIBUTES));*/
483
484 Irp->IoStatus.Status = STATUS_SUCCESS;
485 break;
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;
493 goto intcontfailure;
494 }
495 /*memcpy(Irp->AssociatedIrp.SystemBuffer,
496 &DevExt->KeyboardIndicators,
497 sizeof(KEYBOARD_INDICATOR_PARAMETERS));*/
498
499 Irp->IoStatus.Status = STATUS_SUCCESS;
500 break;
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;
508 goto intcontfailure;
509 }
510 /*memcpy(Irp->AssociatedIrp.SystemBuffer,
511 &DevExt->KeyboardTypematic,
512 sizeof(KEYBOARD_TYPEMATIC_PARAMETERS));*/
513
514 Irp->IoStatus.Status = STATUS_SUCCESS;
515 break;
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;
523 goto intcontfailure;
524 }
525
526 /*memcpy(&DevExt->KeyboardIndicators,
527 Irp->AssociatedIrp.SystemBuffer,
528 sizeof(KEYBOARD_INDICATOR_PARAMETERS));*/
529
530 //DPRINT("%x\n", DevExt->KeyboardIndicators.LedFlags);
531
532 Irp->IoStatus.Status = STATUS_SUCCESS;
533 break;
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;
541 goto intcontfailure;
542 }
543
544 /*memcpy(&DevExt->KeyboardTypematic,
545 Irp->AssociatedIrp.SystemBuffer,
546 sizeof(KEYBOARD_TYPEMATIC_PARAMETERS));*/
547
548 Irp->IoStatus.Status = STATUS_SUCCESS;
549 break;
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
553 */
554 #if 0
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;
561 goto intcontfailure;
562 }
563 Irp->IoStatus.Information =
564 sizeof(LOCAL_KEYBOARD_INDICATOR_TRANSLATION);
565 #endif
566 /*memcpy(Irp->AssociatedIrp.SystemBuffer,
567 &IndicatorTranslation,
568 sizeof(LOCAL_KEYBOARD_INDICATOR_TRANSLATION));*/
569
570 Irp->IoStatus.Status = STATUS_SUCCESS;
571 break;
572 case IOCTL_INTERNAL_I8042_HOOK_KEYBOARD:
573 /* Nothing to do here */
574 Irp->IoStatus.Status = STATUS_SUCCESS;
575 break;
576 default:
577 Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
578 break;
579 }
580
581 intcontfailure:
582 Status = Irp->IoStatus.Status;
583 }
584 else if (DeviceObject == MouseFdo)
585 {
586 // it's mouse's IOCTL
587 PIO_STACK_LOCATION Stk;
588
589 Irp->IoStatus.Information = 0;
590 Stk = IoGetCurrentIrpStackLocation(Irp);
591
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;
600 }
601
602 memcpy(&MouseClassInformation,
603 Stk->Parameters.DeviceIoControl.Type3InputBuffer,
604 sizeof(CONNECT_DATA));
605
606 Irp->IoStatus.Status = STATUS_SUCCESS;
607 break;
608
609 default:
610 Irp->IoStatus.Status = STATUS_SUCCESS;//STATUS_INVALID_DEVICE_REQUEST;
611 break;
612 }
613 intcontfailure2:
614 Status = Irp->IoStatus.Status;
615 }
616 else
617 {
618 DPRINT("We got IOCTL for UsbCore\n");
619 IoCompleteRequest(Irp, IO_NO_INCREMENT);
620 return STATUS_SUCCESS;
621 }
622
623
624 if (Status == STATUS_INVALID_DEVICE_REQUEST) {
625 DPRINT1("Invalid internal device request!\n");
626 }
627
628 if (Status != STATUS_PENDING)
629 IoCompleteRequest(Irp, IO_NO_INCREMENT);
630
631 return Status;
632 }
633
634
635 /*
636 * Standard DriverEntry method.
637 */
638 NTSTATUS STDCALL
639 DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegPath)
640 {
641 int i;
642 USBPORT_INTERFACE UsbPortInterface;
643
644 DriverObject->DriverUnload = DriverUnload;
645 DriverObject->DriverExtension->AddDevice = AddDevice;
646
647 for (i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++)
648 DriverObject->MajorFunction[i] = UsbCoreDispatch;
649
650 DriverObject->MajorFunction[IRP_MJ_PNP] = DispatchPnp;
651 DriverObject->MajorFunction[IRP_MJ_POWER] = DispatchPower;
652 DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = UsbCoreInternalDeviceControl;
653
654 // Register in usbcore.sys
655 UsbPortInterface.KbdConnectData = &KbdClassInformation;
656 UsbPortInterface.MouseConnectData = &MouseClassInformation;
657
658 KbdClassInformation.ClassService = NULL;
659 KbdClassInformation.ClassDeviceObject = NULL;
660 MouseClassInformation.ClassService = NULL;
661 MouseClassInformation.ClassDeviceObject = NULL;
662
663 RegisterPortDriver(DriverObject, &UsbPortInterface);
664
665 return STATUS_SUCCESS;
666 }