2 * PROJECT: ReactOS USB OHCI Miniport Driver
3 * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4 * PURPOSE: USBOHCI main driver functions
5 * COPYRIGHT: Copyright 2017-2018 Vadim Galyant <vgal@rambler.ru>
13 #define NDEBUG_OHCI_TRACE
16 USBPORT_REGISTRATION_PACKET RegPacket
;
18 static const UCHAR Index
[8] =
20 ENDPOINT_INTERRUPT_1ms
- 1,
21 ENDPOINT_INTERRUPT_2ms
- 1,
22 ENDPOINT_INTERRUPT_4ms
- 1,
23 ENDPOINT_INTERRUPT_8ms
- 1,
24 ENDPOINT_INTERRUPT_16ms
- 1,
25 ENDPOINT_INTERRUPT_32ms
- 1,
26 ENDPOINT_INTERRUPT_32ms
- 1,
27 ENDPOINT_INTERRUPT_32ms
- 1
30 static const UCHAR Balance
[OHCI_NUMBER_OF_INTERRUPTS
] =
32 0, 16, 8, 24, 4, 20, 12, 28, 2, 18, 10, 26, 6, 22, 14, 30,
33 1, 17, 9, 25, 5, 21, 13, 29, 3, 19, 11, 27, 7, 23, 15, 31
38 OHCI_DumpHcdED(POHCI_HCD_ED ED
)
40 DPRINT("ED - %p\n", ED
);
41 DPRINT("EndpointControl - %X\n", ED
->HwED
.EndpointControl
.AsULONG
);
42 DPRINT("TailPointer - %08X\n", ED
->HwED
.TailPointer
);
43 DPRINT("HeadPointer - %08X\n", ED
->HwED
.HeadPointer
);
44 DPRINT("NextED - %08X\n", ED
->HwED
.NextED
);
49 OHCI_DumpHcdTD(POHCI_HCD_TD TD
)
51 DPRINT("TD - %p\n", TD
);
52 DPRINT("gTD.Control - %08X\n", TD
->HwTD
.gTD
.Control
.AsULONG
);
53 if (TD
->HwTD
.gTD
.CurrentBuffer
)
54 DPRINT("gTD.CurrentBuffer - %08X\n", TD
->HwTD
.gTD
.CurrentBuffer
);
55 if (TD
->HwTD
.gTD
.NextTD
)
56 DPRINT("gTD.NextTD - %08X\n", TD
->HwTD
.gTD
.NextTD
);
57 if (TD
->HwTD
.gTD
.BufferEnd
)
58 DPRINT("gTD.BufferEnd - %08X\n", TD
->HwTD
.gTD
.BufferEnd
);
60 if (TD
->HwTD
.SetupPacket
.bmRequestType
.B
)
61 DPRINT("bmRequestType - %02X\n", TD
->HwTD
.SetupPacket
.bmRequestType
.B
);
62 if (TD
->HwTD
.SetupPacket
.bRequest
)
63 DPRINT("bRequest - %02X\n", TD
->HwTD
.SetupPacket
.bRequest
);
64 if (TD
->HwTD
.SetupPacket
.wValue
.W
)
65 DPRINT("wValue - %04X\n", TD
->HwTD
.SetupPacket
.wValue
.W
);
66 if (TD
->HwTD
.SetupPacket
.wIndex
.W
)
67 DPRINT("wIndex - %04X\n", TD
->HwTD
.SetupPacket
.wIndex
.W
);
68 if (TD
->HwTD
.SetupPacket
.wLength
)
69 DPRINT("wLength - %04X\n", TD
->HwTD
.SetupPacket
.wLength
);
71 DPRINT("PhysicalAddress - %p\n", TD
->PhysicalAddress
);
72 DPRINT("Flags - %X\n", TD
->Flags
);
73 DPRINT("OhciTransfer - %08X\n", TD
->OhciTransfer
);
74 DPRINT("NextTDVa - %08X\n", TD
->NextTDVa
);
76 DPRINT("TransferLen - %X\n", TD
->TransferLen
);
81 OHCI_EnableList(IN POHCI_EXTENSION OhciExtension
,
82 IN POHCI_ENDPOINT OhciEndpoint
)
84 POHCI_OPERATIONAL_REGISTERS OperationalRegs
;
85 PULONG CommandStatusReg
;
87 OHCI_REG_COMMAND_STATUS CommandStatus
;
89 DPRINT_OHCI("OHCI_EnableList: ... \n");
91 OperationalRegs
= OhciExtension
->OperationalRegs
;
92 CommandStatusReg
= (PULONG
)&OperationalRegs
->HcCommandStatus
;
94 CommandStatus
.AsULONG
= 0;
96 if (READ_REGISTER_ULONG((PULONG
)&OperationalRegs
->HcControlHeadED
))
97 CommandStatus
.ControlListFilled
= 1;
99 if (READ_REGISTER_ULONG((PULONG
)&OperationalRegs
->HcBulkHeadED
))
100 CommandStatus
.BulkListFilled
= 1;
102 TransferType
= OhciEndpoint
->EndpointProperties
.TransferType
;
104 if (TransferType
== USBPORT_TRANSFER_TYPE_BULK
)
105 CommandStatus
.BulkListFilled
= 1;
106 else if (TransferType
== USBPORT_TRANSFER_TYPE_CONTROL
)
107 CommandStatus
.ControlListFilled
= 1;
109 WRITE_REGISTER_ULONG(CommandStatusReg
, CommandStatus
.AsULONG
);
114 OHCI_InsertEndpointInSchedule(IN POHCI_ENDPOINT OhciEndpoint
)
116 POHCI_STATIC_ED HeadED
;
119 PLIST_ENTRY HeadLink
;
121 DPRINT_OHCI("OHCI_InsertEndpointInSchedule: OhciEndpoint - %p\n",
124 ED
= OhciEndpoint
->HcdED
;
126 HeadED
= OhciEndpoint
->HeadED
;
127 HeadLink
= &HeadED
->Link
;
129 if (IsListEmpty(HeadLink
))
131 InsertHeadList(HeadLink
, &ED
->HcdEDLink
);
133 if (HeadED
->Type
== OHCI_STATIC_ED_TYPE_CONTROL
||
134 HeadED
->Type
== OHCI_STATIC_ED_TYPE_BULK
)
136 ED
->HwED
.NextED
= READ_REGISTER_ULONG(HeadED
->pNextED
);
137 WRITE_REGISTER_ULONG(HeadED
->pNextED
, ED
->PhysicalAddress
);
139 else if (HeadED
->Type
== OHCI_STATIC_ED_TYPE_INTERRUPT
)
141 ED
->HwED
.NextED
= *HeadED
->pNextED
;
142 *HeadED
->pNextED
= ED
->PhysicalAddress
;
146 DPRINT1("OHCI_InsertEndpointInSchedule: Unknown HeadED->Type - %x\n",
153 PrevED
= CONTAINING_RECORD(HeadLink
->Blink
,
157 InsertTailList(HeadLink
, &ED
->HcdEDLink
);
160 PrevED
->HwED
.NextED
= ED
->PhysicalAddress
;
166 OHCI_InitializeED(IN POHCI_ENDPOINT OhciEndpoint
,
168 IN POHCI_HCD_TD FirstTD
,
171 OHCI_ENDPOINT_CONTROL EndpointControl
;
172 PUSBPORT_ENDPOINT_PROPERTIES EndpointProperties
;
174 DPRINT_OHCI("OHCI_InitializeED: OhciEndpoint - %p, ED - %p, FirstTD - %p, EdPA - %p\n",
180 RtlZeroMemory(ED
, sizeof(OHCI_HCD_ED
));
182 ED
->PhysicalAddress
= EdPA
;
184 EndpointProperties
= &OhciEndpoint
->EndpointProperties
;
186 EndpointControl
= ED
->HwED
.EndpointControl
;
188 EndpointControl
.FunctionAddress
= EndpointProperties
->DeviceAddress
;
189 EndpointControl
.EndpointNumber
= EndpointProperties
->EndpointAddress
;
190 EndpointControl
.MaximumPacketSize
= EndpointProperties
->TotalMaxPacketSize
;
192 if (EndpointProperties
->TransferType
== USBPORT_TRANSFER_TYPE_CONTROL
)
194 EndpointControl
.Direction
= OHCI_ED_DATA_FLOW_DIRECTION_FROM_TD
;
196 else if (EndpointProperties
->Direction
)
198 EndpointControl
.Direction
= OHCI_ED_DATA_FLOW_DIRECTION_OUT
;
202 EndpointControl
.Direction
= OHCI_ED_DATA_FLOW_DIRECTION_IN
;
205 if (EndpointProperties
->DeviceSpeed
== UsbLowSpeed
)
206 EndpointControl
.Speed
= OHCI_ENDPOINT_LOW_SPEED
;
208 if (EndpointProperties
->TransferType
== USBPORT_TRANSFER_TYPE_ISOCHRONOUS
)
209 EndpointControl
.Format
= OHCI_ENDPOINT_ISOCHRONOUS_FORMAT
;
211 EndpointControl
.sKip
= 1;
213 ED
->HwED
.EndpointControl
= EndpointControl
;
215 ED
->HwED
.TailPointer
= FirstTD
->PhysicalAddress
;
216 ED
->HwED
.HeadPointer
= FirstTD
->PhysicalAddress
;
218 FirstTD
->Flags
|= OHCI_HCD_TD_FLAG_ALLOCATED
;
220 OhciEndpoint
->HcdTailP
= FirstTD
;
221 OhciEndpoint
->HcdHeadP
= FirstTD
;
228 OHCI_InitializeTDs(IN POHCI_ENDPOINT OhciEndpoint
,
229 IN PUSBPORT_ENDPOINT_PROPERTIES EndpointProperties
)
236 ASSERT(EndpointProperties
->BufferLength
> sizeof(OHCI_HCD_ED
));
238 TdCount
= (EndpointProperties
->BufferLength
- sizeof(OHCI_HCD_ED
)) /
241 OhciEndpoint
->MaxTransferDescriptors
= TdCount
;
243 DPRINT_OHCI("OHCI_InitializeTDs: TdCount - %x\n", TdCount
);
247 TdVA
= OhciEndpoint
->FirstTD
;
249 TdPA
= EndpointProperties
->BufferPA
+ sizeof(OHCI_HCD_ED
);
251 for (ix
= 0; ix
< TdCount
; ix
++)
253 DPRINT_OHCI("OHCI_InitializeTDs: TdVA - %p, TdPA - %08X\n", TdVA
, TdPA
);
255 RtlZeroMemory(TdVA
, sizeof(OHCI_HCD_TD
));
257 TdVA
->PhysicalAddress
= TdPA
;
259 TdVA
->OhciTransfer
= 0;
262 TdPA
+= sizeof(OHCI_HCD_TD
);
268 OHCI_OpenControlEndpoint(IN POHCI_EXTENSION OhciExtension
,
269 IN PUSBPORT_ENDPOINT_PROPERTIES EndpointProperties
,
270 IN POHCI_ENDPOINT OhciEndpoint
)
274 DPRINT_OHCI("OHCI_OpenControlEndpoint: ... \n");
276 ED
= (POHCI_HCD_ED
)EndpointProperties
->BufferVA
;
278 OhciEndpoint
->FirstTD
= (POHCI_HCD_TD
)((ULONG_PTR
)ED
+ sizeof(OHCI_HCD_ED
));
279 OhciEndpoint
->HeadED
= &OhciExtension
->ControlStaticED
;
281 OHCI_InitializeTDs(OhciEndpoint
, EndpointProperties
);
283 OhciEndpoint
->HcdED
= OHCI_InitializeED(OhciEndpoint
,
285 OhciEndpoint
->FirstTD
,
286 EndpointProperties
->BufferPA
);
288 OhciEndpoint
->HcdED
->Flags
= OHCI_HCD_ED_FLAG_CONTROL
|
289 OHCI_HCD_ED_FLAG_RESET_ON_HALT
;
291 OHCI_InsertEndpointInSchedule(OhciEndpoint
);
293 return MP_STATUS_SUCCESS
;
298 OHCI_OpenBulkEndpoint(IN POHCI_EXTENSION OhciExtension
,
299 IN PUSBPORT_ENDPOINT_PROPERTIES EndpointProperties
,
300 IN POHCI_ENDPOINT OhciEndpoint
)
304 DPRINT_OHCI("OHCI_OpenBulkEndpoint: ... \n");
306 ED
= (POHCI_HCD_ED
)EndpointProperties
->BufferVA
;
308 OhciEndpoint
->FirstTD
= (POHCI_HCD_TD
)((ULONG_PTR
)ED
+ sizeof(OHCI_HCD_ED
));
309 OhciEndpoint
->HeadED
= &OhciExtension
->BulkStaticED
;
311 OHCI_InitializeTDs(OhciEndpoint
, EndpointProperties
);
313 OhciEndpoint
->HcdED
= OHCI_InitializeED(OhciEndpoint
,
315 OhciEndpoint
->FirstTD
,
316 EndpointProperties
->BufferPA
);
318 OHCI_InsertEndpointInSchedule(OhciEndpoint
);
320 return MP_STATUS_SUCCESS
;
325 OHCI_OpenInterruptEndpoint(IN POHCI_EXTENSION OhciExtension
,
326 IN PUSBPORT_ENDPOINT_PROPERTIES EndpointProperties
,
327 IN POHCI_ENDPOINT OhciEndpoint
)
332 ULONG ScheduleOffset
;
334 DPRINT_OHCI("OHCI_OpenInterruptEndpoint: ... \n");
336 ED
= (POHCI_HCD_ED
)EndpointProperties
->BufferVA
;
338 OhciEndpoint
->FirstTD
= (POHCI_HCD_TD
)((ULONG_PTR
)ED
+ sizeof(OHCI_HCD_ED
));
340 Period
= EndpointProperties
->Period
;
344 while (!(Period
& 1))
350 ASSERT(PeriodIdx
< ARRAYSIZE(Index
));
352 ScheduleOffset
= EndpointProperties
->ScheduleOffset
;
353 DPRINT_OHCI("OHCI_OpenInterruptEndpoint: InitTD. Index[PeriodIdx] - %x, ScheduleOffset - %x\n",
357 OhciEndpoint
->HeadED
= &OhciExtension
->IntStaticED
[Index
[PeriodIdx
] +
360 //OhciEndpoint->HeadED->UsbBandwidth += EndpointProperties->UsbBandwidth;
362 OHCI_InitializeTDs(OhciEndpoint
, EndpointProperties
);
364 OhciEndpoint
->HcdED
= OHCI_InitializeED(OhciEndpoint
,
366 OhciEndpoint
->FirstTD
,
367 EndpointProperties
->BufferPA
);
369 OHCI_InsertEndpointInSchedule(OhciEndpoint
);
371 return MP_STATUS_SUCCESS
;
376 OHCI_OpenIsoEndpoint(IN POHCI_EXTENSION OhciExtension
,
377 IN PUSBPORT_ENDPOINT_PROPERTIES EndpointProperties
,
378 IN POHCI_ENDPOINT OhciEndpoint
)
380 DPRINT1("OHCI_OpenIsoEndpoint: UNIMPLEMENTED. FIXME\n");
381 return MP_STATUS_NOT_SUPPORTED
;
386 OHCI_OpenEndpoint(IN PVOID ohciExtension
,
387 IN PUSBPORT_ENDPOINT_PROPERTIES EndpointProperties
,
388 IN PVOID ohciEndpoint
)
390 POHCI_EXTENSION OhciExtension
= ohciExtension
;
391 POHCI_ENDPOINT OhciEndpoint
= ohciEndpoint
;
395 DPRINT_OHCI("OHCI_OpenEndpoint: ... \n");
397 RtlCopyMemory(&OhciEndpoint
->EndpointProperties
,
399 sizeof(OhciEndpoint
->EndpointProperties
));
401 InitializeListHead(&OhciEndpoint
->TDList
);
403 TransferType
= EndpointProperties
->TransferType
;
405 switch (TransferType
)
407 case USBPORT_TRANSFER_TYPE_ISOCHRONOUS
:
408 MPStatus
= OHCI_OpenIsoEndpoint(OhciExtension
,
413 case USBPORT_TRANSFER_TYPE_CONTROL
:
414 MPStatus
= OHCI_OpenControlEndpoint(OhciExtension
,
419 case USBPORT_TRANSFER_TYPE_BULK
:
420 MPStatus
= OHCI_OpenBulkEndpoint(OhciExtension
,
425 case USBPORT_TRANSFER_TYPE_INTERRUPT
:
426 MPStatus
= OHCI_OpenInterruptEndpoint(OhciExtension
,
432 MPStatus
= MP_STATUS_NOT_SUPPORTED
;
441 OHCI_ReopenEndpoint(IN PVOID ohciExtension
,
442 IN PUSBPORT_ENDPOINT_PROPERTIES EndpointProperties
,
443 IN PVOID ohciEndpoint
)
445 POHCI_ENDPOINT OhciEndpoint
= ohciEndpoint
;
448 DPRINT_OHCI("OHCI_ReopenEndpoint: ... \n");
450 ED
= OhciEndpoint
->HcdED
;
452 RtlCopyMemory(&OhciEndpoint
->EndpointProperties
,
454 sizeof(OhciEndpoint
->EndpointProperties
));
456 ED
->HwED
.EndpointControl
.FunctionAddress
=
457 OhciEndpoint
->EndpointProperties
.DeviceAddress
;
459 ED
->HwED
.EndpointControl
.MaximumPacketSize
=
460 OhciEndpoint
->EndpointProperties
.TotalMaxPacketSize
;
462 return MP_STATUS_SUCCESS
;
467 OHCI_QueryEndpointRequirements(IN PVOID ohciExtension
,
468 IN PUSBPORT_ENDPOINT_PROPERTIES EndpointProperties
,
469 IN PUSBPORT_ENDPOINT_REQUIREMENTS EndpointRequirements
)
473 DPRINT_OHCI("OHCI_QueryEndpointRequirements: ... \n");
475 TransferType
= EndpointProperties
->TransferType
;
477 switch (TransferType
)
479 case USBPORT_TRANSFER_TYPE_ISOCHRONOUS
:
480 DPRINT_OHCI("OHCI_QueryEndpointRequirements: IsoTransfer\n");
481 EndpointRequirements
->MaxTransferSize
= OHCI_MAX_ISO_TRANSFER_SIZE
;
482 EndpointRequirements
->HeaderBufferSize
=
483 sizeof(OHCI_HCD_ED
) + OHCI_MAX_ISO_TD_COUNT
* sizeof(OHCI_HCD_TD
);
486 case USBPORT_TRANSFER_TYPE_CONTROL
:
487 DPRINT_OHCI("OHCI_QueryEndpointRequirements: ControlTransfer\n");
488 EndpointRequirements
->MaxTransferSize
= OHCI_MAX_CONTROL_TRANSFER_SIZE
;
489 EndpointRequirements
->HeaderBufferSize
=
490 sizeof(OHCI_HCD_ED
) + OHCI_MAX_CONTROL_TD_COUNT
* sizeof(OHCI_HCD_TD
);
493 case USBPORT_TRANSFER_TYPE_BULK
:
494 DPRINT_OHCI("OHCI_QueryEndpointRequirements: BulkTransfer\n");
495 EndpointRequirements
->MaxTransferSize
= OHCI_MAX_BULK_TRANSFER_SIZE
;
496 EndpointRequirements
->HeaderBufferSize
=
497 sizeof(OHCI_HCD_ED
) + OHCI_MAX_BULK_TD_COUNT
* sizeof(OHCI_HCD_TD
);
500 case USBPORT_TRANSFER_TYPE_INTERRUPT
:
501 DPRINT_OHCI("OHCI_QueryEndpointRequirements: InterruptTransfer\n");
502 EndpointRequirements
->MaxTransferSize
= OHCI_MAX_INTERRUPT_TRANSFER_SIZE
;
503 EndpointRequirements
->HeaderBufferSize
=
504 sizeof(OHCI_HCD_ED
) + OHCI_MAX_INTERRUPT_TD_COUNT
* sizeof(OHCI_HCD_TD
);
508 DPRINT1("OHCI_QueryEndpointRequirements: Unknown TransferType - %x\n",
517 OHCI_CloseEndpoint(IN PVOID ohciExtension
,
518 IN PVOID ohciEndpoint
,
519 IN BOOLEAN IsDoDisablePeriodic
)
522 DPRINT1("OHCI_CloseEndpoint: Not supported\n");
529 OHCI_TakeControlHC(IN POHCI_EXTENSION OhciExtension
,
530 IN PUSBPORT_RESOURCES Resources
)
532 POHCI_OPERATIONAL_REGISTERS OperationalRegs
;
534 PULONG InterruptEnableReg
;
535 PULONG InterruptDisableReg
;
536 PULONG CommandStatusReg
;
537 PULONG InterruptStatusReg
;
538 OHCI_REG_CONTROL Control
;
539 OHCI_REG_INTERRUPT_ENABLE_DISABLE IntEnable
;
540 OHCI_REG_INTERRUPT_ENABLE_DISABLE IntDisable
;
541 OHCI_REG_COMMAND_STATUS CommandStatus
;
542 OHCI_REG_INTERRUPT_STATUS IntStatus
;
543 LARGE_INTEGER EndTime
;
544 LARGE_INTEGER SystemTime
;
546 DPRINT("OHCI_TakeControlHC: ...\n");
548 OperationalRegs
= OhciExtension
->OperationalRegs
;
550 ControlReg
= (PULONG
)&OperationalRegs
->HcControl
;
551 InterruptEnableReg
= (PULONG
)&OperationalRegs
->HcInterruptEnable
;
552 InterruptDisableReg
= (PULONG
)&OperationalRegs
->HcInterruptDisable
;
553 CommandStatusReg
= (PULONG
)&OperationalRegs
->HcCommandStatus
;
554 InterruptStatusReg
= (PULONG
)&OperationalRegs
->HcInterruptStatus
;
556 /* 5.1.1.3 Take Control of Host Controller */
557 Control
.AsULONG
= READ_REGISTER_ULONG(ControlReg
);
559 if (Control
.InterruptRouting
== 0)
560 return MP_STATUS_SUCCESS
;
562 DPRINT1("OHCI_TakeControlHC: detected Legacy BIOS\n");
564 IntEnable
.AsULONG
= READ_REGISTER_ULONG(InterruptEnableReg
);
566 DPRINT("OHCI_TakeControlHC: Control - %lX, IntEnable - %lX\n",
570 if (Control
.HostControllerFunctionalState
== OHCI_HC_STATE_RESET
&&
571 IntEnable
.AsULONG
== 0)
574 WRITE_REGISTER_ULONG(ControlReg
, Control
.AsULONG
);
575 return MP_STATUS_SUCCESS
;
578 /* Enable interrupt generations */
579 IntEnable
.AsULONG
= 0;
580 IntEnable
.MasterInterruptEnable
= 1;
582 WRITE_REGISTER_ULONG(InterruptEnableReg
, IntEnable
.AsULONG
);
584 /* Request a change of control of the HC */
585 CommandStatus
.AsULONG
= 0;
586 CommandStatus
.OwnershipChangeRequest
= 1;
588 WRITE_REGISTER_ULONG(CommandStatusReg
, CommandStatus
.AsULONG
);
590 /* Disable interrupt generation due to Root Hub Status Change */
591 IntDisable
.AsULONG
= 0;
592 IntDisable
.RootHubStatusChange
= 1;
594 WRITE_REGISTER_ULONG(InterruptDisableReg
, IntDisable
.AsULONG
);
596 /* Monitoring the InterruptRouting bit
597 to determine when the ownership change has taken effect. */
599 KeQuerySystemTime(&EndTime
);
600 EndTime
.QuadPart
+= 500 * 10000; // 0.5 sec;
604 Control
.AsULONG
= READ_REGISTER_ULONG(ControlReg
);
606 if (Control
.InterruptRouting
== 0)
608 /* Clear all bits in register */
609 IntStatus
.AsULONG
= 0xFFFFFFFF;
610 WRITE_REGISTER_ULONG(InterruptStatusReg
, IntStatus
.AsULONG
);
612 /* Disable interrupt generations */
613 IntDisable
.AsULONG
= 0;
614 IntDisable
.MasterInterruptEnable
= 1;
616 WRITE_REGISTER_ULONG(InterruptDisableReg
, IntDisable
.AsULONG
);
618 return MP_STATUS_SUCCESS
;
621 KeQuerySystemTime(&SystemTime
);
623 while (SystemTime
.QuadPart
< EndTime
.QuadPart
);
625 return MP_STATUS_HW_ERROR
;
630 OHCI_StartController(IN PVOID ohciExtension
,
631 IN PUSBPORT_RESOURCES Resources
)
633 POHCI_EXTENSION OhciExtension
= ohciExtension
;
634 POHCI_OPERATIONAL_REGISTERS OperationalRegs
;
635 PULONG CommandStatusReg
;
636 PULONG FmIntervalReg
;
638 PULONG InterruptEnableReg
;
640 OHCI_REG_COMMAND_STATUS CommandStatus
;
641 OHCI_REG_INTERRUPT_ENABLE_DISABLE Interrupts
;
642 OHCI_REG_RH_STATUS RhStatus
;
643 OHCI_REG_FRAME_INTERVAL FrameInterval
;
644 ULONG MaxFrameIntervalAdjusting
;
645 OHCI_REG_CONTROL Control
;
647 POHCI_ENDPOINT_DESCRIPTOR IntED
;
650 LARGE_INTEGER SystemTime
;
651 LARGE_INTEGER EndTime
;
654 MPSTATUS MPStatus
= MP_STATUS_SUCCESS
;
656 DPRINT_OHCI("OHCI_StartController: ohciExtension - %p, Resources - %p\n",
660 /* HC on-chip operational registers */
661 OperationalRegs
= (POHCI_OPERATIONAL_REGISTERS
)Resources
->ResourceBase
;
662 OhciExtension
->OperationalRegs
= OperationalRegs
;
664 CommandStatusReg
= (PULONG
)&OperationalRegs
->HcCommandStatus
;
665 FmIntervalReg
= (PULONG
)&OperationalRegs
->HcFmInterval
;
666 ControlReg
= (PULONG
)&OperationalRegs
->HcControl
;
667 InterruptEnableReg
= (PULONG
)&OperationalRegs
->HcInterruptEnable
;
668 RhStatusReg
= (PULONG
)&OperationalRegs
->HcRhStatus
;
670 /* 5.1.1 Initialization */
672 MPStatus
= OHCI_TakeControlHC(OhciExtension
, Resources
);
674 if (MPStatus
!= MP_STATUS_SUCCESS
)
676 DPRINT1("OHCI_StartController: OHCI_TakeControlHC return MPStatus - %x\n",
682 OhciExtension
->HcResourcesVA
= (POHCI_HC_RESOURCES
)Resources
->StartVA
;
683 OhciExtension
->HcResourcesPA
= Resources
->StartPA
;
685 DPRINT_OHCI("OHCI_StartController: HcResourcesVA - %p, HcResourcesPA - %lx\n",
686 OhciExtension
->HcResourcesVA
,
687 OhciExtension
->HcResourcesPA
);
689 /* 5.2.7.2 Interrupt */
691 /* Build structure of interrupt static EDs */
692 for (ix
= 0; ix
< INTERRUPT_ENDPOINTs
; ix
++)
694 IntED
= &OhciExtension
->HcResourcesVA
->InterrruptHeadED
[ix
];
695 IntEdPA
= OhciExtension
->HcResourcesPA
+ FIELD_OFFSET(OHCI_HC_RESOURCES
, InterrruptHeadED
[ix
]);
697 if (ix
== (ENDPOINT_INTERRUPT_1ms
- 1))
704 HeadIndex
= ((ix
- 1) / 2);
706 ASSERT(HeadIndex
>= (ENDPOINT_INTERRUPT_1ms
- 1) &&
707 HeadIndex
< (INTERRUPT_ENDPOINTs
- ENDPOINT_INTERRUPT_32ms
));
709 IntED
->NextED
= OhciExtension
->IntStaticED
[HeadIndex
].PhysicalAddress
;
712 IntED
->EndpointControl
.sKip
= 1;
714 IntED
->TailPointer
= 0;
715 IntED
->HeadPointer
= 0;
717 OhciExtension
->IntStaticED
[ix
].HwED
= IntED
;
718 OhciExtension
->IntStaticED
[ix
].PhysicalAddress
= IntEdPA
;
719 OhciExtension
->IntStaticED
[ix
].HeadIndex
= HeadIndex
;
720 OhciExtension
->IntStaticED
[ix
].pNextED
= &IntED
->NextED
;
721 OhciExtension
->IntStaticED
[ix
].Type
= OHCI_STATIC_ED_TYPE_INTERRUPT
;
723 InitializeListHead(&OhciExtension
->IntStaticED
[ix
].Link
);
726 OhciHCCA
= &OhciExtension
->HcResourcesVA
->HcHCCA
;
727 DPRINT_OHCI("OHCI_InitializeSchedule: OhciHCCA - %p\n", OhciHCCA
);
729 /* Set head pointers which start from HCCA */
730 for (ix
= 0, jx
= (INTERRUPT_ENDPOINTs
- ENDPOINT_INTERRUPT_32ms
);
731 ix
< OHCI_NUMBER_OF_INTERRUPTS
;
734 OhciHCCA
->InterrruptTable
[Balance
[ix
]] =
735 OhciExtension
->IntStaticED
[jx
].PhysicalAddress
;
737 OhciExtension
->IntStaticED
[jx
].pNextED
=
738 (PULONG
)&OhciHCCA
->InterrruptTable
[Balance
[ix
]];
740 OhciExtension
->IntStaticED
[jx
].HccaIndex
= Balance
[ix
];
743 DPRINT_OHCI("OHCI_InitializeSchedule: ix - %x\n", ix
);
745 /* Init static Control and Bulk EDs head pointers which start from HCCA */
746 InitializeListHead(&OhciExtension
->ControlStaticED
.Link
);
748 OhciExtension
->ControlStaticED
.HeadIndex
= ED_EOF
;
749 OhciExtension
->ControlStaticED
.Type
= OHCI_STATIC_ED_TYPE_CONTROL
;
750 OhciExtension
->ControlStaticED
.pNextED
= &OperationalRegs
->HcControlHeadED
;
752 InitializeListHead(&OhciExtension
->BulkStaticED
.Link
);
754 OhciExtension
->BulkStaticED
.HeadIndex
= ED_EOF
;
755 OhciExtension
->BulkStaticED
.Type
= OHCI_STATIC_ED_TYPE_BULK
;
756 OhciExtension
->BulkStaticED
.pNextED
= &OperationalRegs
->HcBulkHeadED
;
758 /* 6.3.1 Frame Timing */
759 FrameInterval
.AsULONG
= READ_REGISTER_ULONG(FmIntervalReg
);
761 MaxFrameIntervalAdjusting
= OHCI_DEFAULT_FRAME_INTERVAL
/ 10; // 10%
763 if ((FrameInterval
.FrameInterval
) < (OHCI_DEFAULT_FRAME_INTERVAL
- MaxFrameIntervalAdjusting
) ||
764 (FrameInterval
.FrameInterval
) > (OHCI_DEFAULT_FRAME_INTERVAL
+ MaxFrameIntervalAdjusting
))
766 FrameInterval
.FrameInterval
= OHCI_DEFAULT_FRAME_INTERVAL
;
769 /* 5.4 FrameInterval Counter */
770 FrameInterval
.FrameIntervalToggle
= 1;
772 /* OHCI_MAXIMUM_OVERHEAD is the maximum overhead per frame */
773 FrameInterval
.FSLargestDataPacket
=
774 ((FrameInterval
.FrameInterval
- OHCI_MAXIMUM_OVERHEAD
) * 6) / 7;
776 OhciExtension
->FrameInterval
= FrameInterval
;
778 DPRINT_OHCI("OHCI_StartController: FrameInterval - %lX\n",
779 FrameInterval
.AsULONG
);
781 /* Reset HostController */
782 CommandStatus
.AsULONG
= 0;
783 CommandStatus
.HostControllerReset
= 1;
785 WRITE_REGISTER_ULONG(CommandStatusReg
, CommandStatus
.AsULONG
);
787 KeStallExecutionProcessor(25);
789 Control
.AsULONG
= READ_REGISTER_ULONG(ControlReg
);
790 Control
.HostControllerFunctionalState
= OHCI_HC_STATE_RESET
;
792 WRITE_REGISTER_ULONG(ControlReg
, Control
.AsULONG
);
794 KeQuerySystemTime(&EndTime
);
795 EndTime
.QuadPart
+= 500 * 10000; // 0.5 sec
799 WRITE_REGISTER_ULONG(FmIntervalReg
, OhciExtension
->FrameInterval
.AsULONG
);
800 FrameInterval
.AsULONG
= READ_REGISTER_ULONG(FmIntervalReg
);
802 KeQuerySystemTime(&SystemTime
);
804 if (SystemTime
.QuadPart
>= EndTime
.QuadPart
)
806 MPStatus
= MP_STATUS_HW_ERROR
;
810 if (FrameInterval
.AsULONG
== OhciExtension
->FrameInterval
.AsULONG
)
812 MPStatus
= MP_STATUS_SUCCESS
;
817 if (MPStatus
!= MP_STATUS_SUCCESS
)
819 DPRINT_OHCI("OHCI_StartController: frame interval not set\n");
823 /* Setup HcPeriodicStart register */
824 WRITE_REGISTER_ULONG(&OperationalRegs
->HcPeriodicStart
,
825 (OhciExtension
->FrameInterval
.FrameInterval
* 9) / 10); //90%
827 /* Setup HcHCCA register */
828 WRITE_REGISTER_ULONG(&OperationalRegs
->HcHCCA
,
829 OhciExtension
->HcResourcesPA
+ FIELD_OFFSET(OHCI_HC_RESOURCES
, HcHCCA
));
831 /* Setup HcInterruptEnable register */
832 Interrupts
.AsULONG
= 0;
834 Interrupts
.SchedulingOverrun
= 1;
835 Interrupts
.WritebackDoneHead
= 1;
836 Interrupts
.UnrecoverableError
= 1;
837 Interrupts
.FrameNumberOverflow
= 1;
838 Interrupts
.OwnershipChange
= 1;
840 WRITE_REGISTER_ULONG(InterruptEnableReg
, Interrupts
.AsULONG
);
842 /* Setup HcControl register */
843 Control
.AsULONG
= READ_REGISTER_ULONG(ControlReg
);
845 Control
.ControlBulkServiceRatio
= 0; // FIXME (1 : 1)
846 Control
.PeriodicListEnable
= 1;
847 Control
.IsochronousEnable
= 1;
848 Control
.ControlListEnable
= 1;
849 Control
.BulkListEnable
= 1;
850 Control
.HostControllerFunctionalState
= OHCI_HC_STATE_OPERATIONAL
;
852 WRITE_REGISTER_ULONG(ControlReg
, Control
.AsULONG
);
854 /* Setup HcRhStatus register */
855 RhStatus
.AsULONG
= 0;
856 RhStatus
.SetGlobalPower
= 1;
858 WRITE_REGISTER_ULONG(RhStatusReg
, RhStatus
.AsULONG
);
860 return MP_STATUS_SUCCESS
;
865 OHCI_StopController(IN PVOID ohciExtension
,
866 IN BOOLEAN IsDoDisableInterrupts
)
868 POHCI_EXTENSION OhciExtension
= ohciExtension
;
869 POHCI_OPERATIONAL_REGISTERS OperationalRegs
;
871 PULONG InterruptDisableReg
;
872 PULONG InterruptStatusReg
;
873 OHCI_REG_CONTROL Control
;
874 OHCI_REG_INTERRUPT_ENABLE_DISABLE IntDisable
;
875 OHCI_REG_INTERRUPT_STATUS IntStatus
;
877 DPRINT("OHCI_StopController: ... \n");
879 OperationalRegs
= OhciExtension
->OperationalRegs
;
881 ControlReg
= (PULONG
)&OperationalRegs
->HcControl
;
882 InterruptDisableReg
= (PULONG
)&OperationalRegs
->HcInterruptDisable
;
883 InterruptStatusReg
= (PULONG
)&OperationalRegs
->HcInterruptStatus
;
885 /* Setup HcControl register */
886 Control
.AsULONG
= READ_REGISTER_ULONG(ControlReg
);
888 Control
.PeriodicListEnable
= 0;
889 Control
.IsochronousEnable
= 0;
890 Control
.ControlListEnable
= 0;
891 Control
.BulkListEnable
= 0;
892 Control
.HostControllerFunctionalState
= OHCI_HC_STATE_SUSPEND
;
893 Control
.RemoteWakeupEnable
= 0;
895 WRITE_REGISTER_ULONG(ControlReg
, Control
.AsULONG
);
897 /* Disable interrupt generations */
898 IntDisable
.AsULONG
= 0xFFFFFFFF;
899 WRITE_REGISTER_ULONG(InterruptDisableReg
, IntDisable
.AsULONG
);
901 /* Clear all bits in HcInterruptStatus register */
902 IntStatus
.AsULONG
= 0xFFFFFFFF;
903 WRITE_REGISTER_ULONG(InterruptStatusReg
, IntStatus
.AsULONG
);
908 OHCI_SuspendController(IN PVOID ohciExtension
)
910 POHCI_EXTENSION OhciExtension
= ohciExtension
;
911 POHCI_OPERATIONAL_REGISTERS OperationalRegs
;
913 PULONG InterruptEnableReg
;
914 OHCI_REG_CONTROL Control
;
915 OHCI_REG_INTERRUPT_ENABLE_DISABLE InterruptReg
;
917 DPRINT("OHCI_SuspendController: ... \n");
919 OperationalRegs
= OhciExtension
->OperationalRegs
;
920 ControlReg
= (PULONG
)&OperationalRegs
->HcControl
;
921 InterruptEnableReg
= (PULONG
)&OperationalRegs
->HcInterruptEnable
;
923 /* Disable all interrupt generations */
924 WRITE_REGISTER_ULONG(&OperationalRegs
->HcInterruptDisable
.AsULONG
,
927 /* Clear all bits in HcInterruptStatus register */
928 WRITE_REGISTER_ULONG(&OperationalRegs
->HcInterruptStatus
.AsULONG
,
931 /* Setup HcControl register */
932 Control
.AsULONG
= READ_REGISTER_ULONG(ControlReg
);
933 Control
.HostControllerFunctionalState
= OHCI_HC_STATE_SUSPEND
;
934 Control
.RemoteWakeupEnable
= 1;
936 WRITE_REGISTER_ULONG(ControlReg
, Control
.AsULONG
);
938 /* Setup HcInterruptEnable register */
939 InterruptReg
.AsULONG
= 0;
940 InterruptReg
.ResumeDetected
= 1;
941 InterruptReg
.UnrecoverableError
= 1;
942 InterruptReg
.RootHubStatusChange
= 1;
943 InterruptReg
.MasterInterruptEnable
= 1;
945 WRITE_REGISTER_ULONG(InterruptEnableReg
, InterruptReg
.AsULONG
);
950 OHCI_ResumeController(IN PVOID ohciExtension
)
952 POHCI_EXTENSION OhciExtension
= ohciExtension
;
953 POHCI_OPERATIONAL_REGISTERS OperationalRegs
;
955 PULONG InterruptEnableReg
;
957 OHCI_REG_CONTROL control
;
958 OHCI_REG_INTERRUPT_ENABLE_DISABLE InterruptReg
;
960 DPRINT("OHCI_ResumeController \n");
962 OperationalRegs
= OhciExtension
->OperationalRegs
;
963 ControlReg
= (PULONG
)&OperationalRegs
->HcControl
;
964 InterruptEnableReg
= (PULONG
)&OperationalRegs
->HcInterruptEnable
;
966 control
.AsULONG
= READ_REGISTER_ULONG(ControlReg
);
968 if (control
.HostControllerFunctionalState
!= OHCI_HC_STATE_SUSPEND
)
969 return MP_STATUS_HW_ERROR
;
971 HcHCCA
= &OhciExtension
->HcResourcesVA
->HcHCCA
;
974 /* Setup HcControl register */
975 control
.HostControllerFunctionalState
= OHCI_HC_STATE_OPERATIONAL
;
976 WRITE_REGISTER_ULONG(ControlReg
, control
.AsULONG
);
978 /* Setup HcInterruptEnable register */
979 InterruptReg
.AsULONG
= 0;
980 InterruptReg
.SchedulingOverrun
= 1;
981 InterruptReg
.WritebackDoneHead
= 1;
982 InterruptReg
.UnrecoverableError
= 1;
983 InterruptReg
.FrameNumberOverflow
= 1;
984 InterruptReg
.OwnershipChange
= 1;
986 WRITE_REGISTER_ULONG(InterruptEnableReg
, InterruptReg
.AsULONG
);
987 WRITE_REGISTER_ULONG(ControlReg
, control
.AsULONG
);
989 return MP_STATUS_SUCCESS
;
994 OHCI_HardwarePresent(IN POHCI_EXTENSION OhciExtension
,
995 IN BOOLEAN IsInvalidateController
)
997 POHCI_OPERATIONAL_REGISTERS OperationalRegs
;
998 PULONG CommandStatusReg
;
1000 OperationalRegs
= OhciExtension
->OperationalRegs
;
1001 CommandStatusReg
= (PULONG
)&OperationalRegs
->HcCommandStatus
;
1003 if (READ_REGISTER_ULONG(CommandStatusReg
) != 0xFFFFFFFF)
1006 DPRINT1("OHCI_HardwarePresent: IsInvalidateController - %x\n",
1007 IsInvalidateController
);
1009 if (IsInvalidateController
)
1011 RegPacket
.UsbPortInvalidateController(OhciExtension
,
1012 USBPORT_INVALIDATE_CONTROLLER_SURPRISE_REMOVE
);
1020 OHCI_InterruptService(IN PVOID ohciExtension
)
1022 POHCI_EXTENSION OhciExtension
= ohciExtension
;
1023 POHCI_OPERATIONAL_REGISTERS OperationalRegs
;
1024 OHCI_REG_INTERRUPT_STATUS IntStatus
;
1025 OHCI_REG_INTERRUPT_ENABLE_DISABLE IntEnable
;
1026 OHCI_REG_INTERRUPT_ENABLE_DISABLE IntDisable
;
1027 BOOLEAN HardwarePresent
= FALSE
;
1029 DPRINT_OHCI("OHCI_Interrupt: Ext %p\n", OhciExtension
);
1031 OperationalRegs
= OhciExtension
->OperationalRegs
;
1033 HardwarePresent
= OHCI_HardwarePresent(OhciExtension
, FALSE
);
1035 if (!HardwarePresent
)
1038 IntEnable
.AsULONG
= READ_REGISTER_ULONG((PULONG
)&OperationalRegs
->HcInterruptEnable
);
1039 IntStatus
.AsULONG
= READ_REGISTER_ULONG((PULONG
)&OperationalRegs
->HcInterruptStatus
) & IntEnable
.AsULONG
;
1041 if ((IntStatus
.AsULONG
== 0) || (IntEnable
.MasterInterruptEnable
== 0))
1044 if (IntStatus
.UnrecoverableError
)
1045 DPRINT1("OHCI_InterruptService: IntStatus.UnrecoverableError\n");
1047 if (IntStatus
.FrameNumberOverflow
)
1053 HcHCCA
= &OhciExtension
->HcResourcesVA
->HcHCCA
;
1055 DPRINT("FrameNumberOverflow %lX\n", HcHCCA
->FrameNumber
);
1057 hp
= OhciExtension
->FrameHighPart
;
1058 fm
= HcHCCA
->FrameNumber
;
1060 /* Increment value of FrameHighPart */
1061 OhciExtension
->FrameHighPart
+= 1 * (1 << 16) - ((hp
^ fm
) & 0x8000);
1064 /* Disable interrupt generation */
1065 IntDisable
.AsULONG
= 0;
1066 IntDisable
.MasterInterruptEnable
= 1;
1067 WRITE_REGISTER_ULONG((PULONG
)&OperationalRegs
->HcInterruptDisable
,
1068 IntDisable
.AsULONG
);
1075 OHCI_InterruptDpc(IN PVOID ohciExtension
,
1076 IN BOOLEAN IsDoEnableInterrupts
)
1078 POHCI_EXTENSION OhciExtension
= ohciExtension
;
1079 POHCI_OPERATIONAL_REGISTERS OperationalRegs
;
1080 PULONG InterruptDisableReg
;
1081 PULONG InterruptEnableReg
;
1082 PULONG InterruptStatusReg
;
1083 OHCI_REG_INTERRUPT_STATUS IntStatus
;
1084 OHCI_REG_INTERRUPT_ENABLE_DISABLE InterruptBits
;
1087 OperationalRegs
= OhciExtension
->OperationalRegs
;
1089 InterruptEnableReg
= (PULONG
)&OperationalRegs
->HcInterruptEnable
;
1090 InterruptDisableReg
= (PULONG
)&OperationalRegs
->HcInterruptDisable
;
1091 InterruptStatusReg
= (PULONG
)&OperationalRegs
->HcInterruptStatus
;
1093 DPRINT_OHCI("OHCI_InterruptDpc: OhciExtension - %p, IsDoEnableInterrupts - %x\n",
1095 IsDoEnableInterrupts
);
1097 IntStatus
.AsULONG
= READ_REGISTER_ULONG(InterruptStatusReg
);
1099 if (IntStatus
.RootHubStatusChange
)
1101 DPRINT_OHCI("OHCI_InterruptDpc: RootHubStatusChange\n");
1102 RegPacket
.UsbPortInvalidateRootHub(OhciExtension
);
1105 if (IntStatus
.WritebackDoneHead
)
1107 DPRINT_OHCI("OHCI_InterruptDpc: WritebackDoneHead\n");
1109 HcHCCA
= &OhciExtension
->HcResourcesVA
->HcHCCA
;
1110 HcHCCA
->DoneHead
= 0;
1112 RegPacket
.UsbPortInvalidateEndpoint(OhciExtension
, NULL
);
1115 if (IntStatus
.StartofFrame
)
1117 /* Disable interrupt generation due to Start of Frame */
1118 InterruptBits
.AsULONG
= 0;
1119 InterruptBits
.StartofFrame
= 1;
1121 WRITE_REGISTER_ULONG(InterruptDisableReg
, InterruptBits
.AsULONG
);
1124 if (IntStatus
.ResumeDetected
)
1125 DPRINT1("OHCI_IntDpc: ResumeDetected\n");
1127 if (IntStatus
.UnrecoverableError
)
1129 DPRINT1("OHCI_IntDpc: UnrecoverableError\n");
1132 WRITE_REGISTER_ULONG(InterruptStatusReg
, IntStatus
.AsULONG
);
1134 if (IsDoEnableInterrupts
)
1136 /* Enable interrupt generation */
1137 InterruptBits
.AsULONG
= 0;
1138 InterruptBits
.MasterInterruptEnable
= 1;
1140 WRITE_REGISTER_ULONG(InterruptEnableReg
, InterruptBits
.AsULONG
);
1145 * @brief Forms the next General Transfer Descriptor for the current transfer
1147 * @param[in] OhciExtension The ohci extension
1148 * @param[in] TransferedLen The consolidated length of all previous descriptors' buffers
1149 * @param[in] OhciTransfer The ohci transfer
1150 * @param[out] TD The transfer descriptor we are forming
1151 * @param[in] SGList The scatter/gather list
1153 * @return The length of all previous buffers summed with the length of the current buffer
1157 OHCI_MapTransferToTD(IN POHCI_EXTENSION OhciExtension
,
1158 IN ULONG TransferedLen
,
1159 IN POHCI_TRANSFER OhciTransfer
,
1160 OUT POHCI_HCD_TD TD
,
1161 IN PUSBPORT_SCATTER_GATHER_LIST SGList
)
1163 PUSBPORT_SCATTER_GATHER_ELEMENT SgElement
;
1164 ULONG SgIdx
, CurrentTransferLen
, BufferEnd
, CurrentBuffer
;
1165 ULONG TransferDataLeft
= OhciTransfer
->TransferParameters
->TransferBufferLength
- TransferedLen
;
1167 DPRINT_OHCI("OHCI_MapTransferToTD: TransferedLen - %x\n", TransferedLen
);
1169 for (SgIdx
= 0; SgIdx
< SGList
->SgElementCount
; SgIdx
++)
1171 SgElement
= &SGList
->SgElement
[SgIdx
];
1173 if (TransferedLen
>= SgElement
->SgOffset
&&
1174 TransferedLen
< SgElement
->SgOffset
+ SgElement
->SgTransferLength
)
1180 DPRINT_OHCI("OHCI_MapTransferToTD: SgIdx - %x, SgCount - %x\n",
1182 SGList
->SgElementCount
);
1184 ASSERT(SgIdx
< SGList
->SgElementCount
);
1185 ASSERT(TransferedLen
== SgElement
->SgOffset
);
1187 /* The buffer for a TD can be 0 to 8192 bytes long,
1188 * and can span within mo more than two 4k pages (see OpenHCI spec 3.3.2)
1189 * CurrentBuffer - the (physical) address of the first byte in the buffer
1190 * BufferEnd - the address of the last byte in the buffer. It can be on a different physical 4k page
1191 * when a controller will reach the end of a page from CurrentBuffer, it will take the first 20 bits
1192 * of the BufferEnd as a next address (OpenHCI spec, 4.3.1.3.1)
1195 CurrentBuffer
= SgElement
->SgPhysicalAddress
.LowPart
;
1197 if (TransferDataLeft
<= SgElement
->SgTransferLength
)
1199 CurrentTransferLen
= TransferDataLeft
;
1200 BufferEnd
= SgElement
->SgPhysicalAddress
.LowPart
+ CurrentTransferLen
- 1;
1204 PUSBPORT_SCATTER_GATHER_ELEMENT SgNextElement
;
1205 ASSERT(SGList
->SgElementCount
- SgIdx
> 1);
1207 SgNextElement
= &SGList
->SgElement
[SgIdx
+ 1];
1209 TransferDataLeft
-= SgElement
->SgTransferLength
;
1210 CurrentTransferLen
= SgElement
->SgTransferLength
;
1212 if (TransferDataLeft
<= SgNextElement
->SgTransferLength
)
1214 CurrentTransferLen
+= TransferDataLeft
;
1215 BufferEnd
= SgNextElement
->SgPhysicalAddress
.LowPart
+ TransferDataLeft
- 1;
1219 CurrentTransferLen
+= SgNextElement
->SgTransferLength
;
1220 BufferEnd
= SgNextElement
->SgPhysicalAddress
.LowPart
+ SgNextElement
->SgTransferLength
- 1;
1224 TD
->HwTD
.gTD
.CurrentBuffer
= CurrentBuffer
;
1225 TD
->HwTD
.gTD
.BufferEnd
= BufferEnd
;
1226 TD
->TransferLen
= CurrentTransferLen
;
1228 return TransferedLen
+ CurrentTransferLen
;
1233 OHCI_AllocateTD(IN POHCI_EXTENSION OhciExtension
,
1234 IN POHCI_ENDPOINT OhciEndpoint
)
1238 DPRINT_OHCI("OHCI_AllocateTD: ... \n");
1240 TD
= OhciEndpoint
->FirstTD
;
1242 while (TD
->Flags
& OHCI_HCD_TD_FLAG_ALLOCATED
)
1247 TD
->Flags
|= OHCI_HCD_TD_FLAG_ALLOCATED
;
1249 RtlSecureZeroMemory(&TD
->HwTD
, sizeof(TD
->HwTD
));
1256 OHCI_RemainTDs(IN POHCI_EXTENSION OhciExtension
,
1257 IN POHCI_ENDPOINT OhciEndpoint
)
1264 DPRINT_OHCI("OHCI_RemainTDs: ... \n");
1266 MaxTDs
= OhciEndpoint
->MaxTransferDescriptors
;
1267 TD
= OhciEndpoint
->FirstTD
;
1271 for (ix
= 0; ix
< MaxTDs
; ix
++)
1273 if (!(TD
->Flags
& OHCI_HCD_TD_FLAG_ALLOCATED
))
1284 OHCI_ControlTransfer(IN POHCI_EXTENSION OhciExtension
,
1285 IN POHCI_ENDPOINT OhciEndpoint
,
1286 IN PUSBPORT_TRANSFER_PARAMETERS TransferParameters
,
1287 IN POHCI_TRANSFER OhciTransfer
,
1288 IN PUSBPORT_SCATTER_GATHER_LIST SGList
)
1290 POHCI_HCD_TD SetupTD
;
1292 POHCI_HCD_TD PrevTD
;
1294 ULONG TransferedLen
;
1297 DPRINT_OHCI("OHCI_ControlTransfer: Ext %p, Endpoint %p\n",
1301 MaxTDs
= OHCI_RemainTDs(OhciExtension
, OhciEndpoint
);
1303 if ((SGList
->SgElementCount
+ OHCI_NON_DATA_CONTROL_TDS
) > MaxTDs
)
1304 return MP_STATUS_FAILURE
;
1306 /* Form a setup packet first */
1307 SetupTD
= OhciEndpoint
->HcdTailP
;
1308 RtlSecureZeroMemory(&SetupTD
->HwTD
, sizeof(SetupTD
->HwTD
));
1310 SetupTD
->Flags
|= OHCI_HCD_TD_FLAG_PROCESSED
;
1311 SetupTD
->OhciTransfer
= OhciTransfer
;
1313 OhciTransfer
->PendingTDs
++;
1315 RtlCopyMemory(&SetupTD
->HwTD
.SetupPacket
,
1316 &TransferParameters
->SetupPacket
,
1317 sizeof(SetupTD
->HwTD
.SetupPacket
));
1319 SetupTD
->HwTD
.gTD
.CurrentBuffer
= SetupTD
->PhysicalAddress
+ FIELD_OFFSET(OHCI_HCD_TD
, HwTD
.SetupPacket
);
1320 SetupTD
->HwTD
.gTD
.BufferEnd
= SetupTD
->PhysicalAddress
+ FIELD_OFFSET(OHCI_HCD_TD
, HwTD
.SetupPacket
) +
1321 sizeof(USB_DEFAULT_PIPE_SETUP_PACKET
) - 1;
1322 SetupTD
->HwTD
.gTD
.Control
.DelayInterrupt
= OHCI_TD_INTERRUPT_NONE
;
1323 SetupTD
->HwTD
.gTD
.Control
.ConditionCode
= OHCI_TD_CONDITION_NOT_ACCESSED
;
1324 SetupTD
->HwTD
.gTD
.Control
.DataToggle
= OHCI_TD_DATA_TOGGLE_DATA0
;
1328 /* Data packets follow a setup packet (if any) */
1329 TD
= OHCI_AllocateTD(OhciExtension
, OhciEndpoint
);
1330 TD
->Flags
|= OHCI_HCD_TD_FLAG_PROCESSED
;
1331 TD
->OhciTransfer
= OhciTransfer
;
1333 PrevTD
->HwTD
.gTD
.NextTD
= TD
->PhysicalAddress
;
1334 PrevTD
->NextTDVa
= TD
;
1336 /* The first data packet should use DATA1, subsequent ones use DATA0 (OpenHCI spec, 4.3.1.3.4) */
1337 DataToggle
= OHCI_TD_DATA_TOGGLE_DATA1
;
1340 while (TransferedLen
< TransferParameters
->TransferBufferLength
)
1342 OhciTransfer
->PendingTDs
++;
1344 if (TransferParameters
->TransferFlags
& USBD_TRANSFER_DIRECTION_IN
)
1345 TD
->HwTD
.gTD
.Control
.DirectionPID
= OHCI_TD_DIRECTION_PID_IN
;
1347 TD
->HwTD
.gTD
.Control
.DirectionPID
= OHCI_TD_DIRECTION_PID_OUT
;
1349 TD
->HwTD
.gTD
.Control
.DelayInterrupt
= OHCI_TD_INTERRUPT_NONE
;
1350 TD
->HwTD
.gTD
.Control
.ConditionCode
= OHCI_TD_CONDITION_NOT_ACCESSED
;
1351 TD
->HwTD
.gTD
.Control
.DataToggle
= DataToggle
;
1353 TransferedLen
= OHCI_MapTransferToTD(OhciExtension
,
1361 TD
= OHCI_AllocateTD(OhciExtension
, OhciEndpoint
);
1362 TD
->HwTD
.gTD
.Control
.DelayInterrupt
= OHCI_TD_INTERRUPT_NONE
;
1363 TD
->Flags
|= OHCI_HCD_TD_FLAG_PROCESSED
;
1364 TD
->OhciTransfer
= OhciTransfer
;
1366 PrevTD
->HwTD
.gTD
.NextTD
= TD
->PhysicalAddress
;
1367 PrevTD
->NextTDVa
= TD
;
1369 DataToggle
= OHCI_TD_DATA_TOGGLE_DATA0
;
1372 if (TransferParameters
->TransferFlags
& USBD_SHORT_TRANSFER_OK
)
1374 PrevTD
->HwTD
.gTD
.Control
.BufferRounding
= TRUE
;
1375 OhciTransfer
->Flags
|= OHCI_TRANSFER_FLAGS_SHORT_TRANSFER_OK
;
1378 /* After data packets, goes a status packet */
1380 TD
->Flags
|= OHCI_HCD_TD_FLAG_CONTROL_STATUS
;
1381 TD
->TransferLen
= 0;
1383 if ((TransferParameters
->TransferFlags
& USBD_TRANSFER_DIRECTION_IN
) != 0)
1385 TD
->HwTD
.gTD
.Control
.BufferRounding
= FALSE
;
1386 TD
->HwTD
.gTD
.Control
.DirectionPID
= OHCI_TD_DIRECTION_PID_OUT
;
1390 TD
->HwTD
.gTD
.Control
.BufferRounding
= TRUE
;
1391 TD
->HwTD
.gTD
.Control
.DirectionPID
= OHCI_TD_DIRECTION_PID_IN
;
1394 /* OpenHCI spec, 4.3.1.3.4 */
1395 TD
->HwTD
.gTD
.Control
.DataToggle
= OHCI_TD_DATA_TOGGLE_DATA1
;
1396 TD
->HwTD
.gTD
.Control
.ConditionCode
= OHCI_TD_CONDITION_NOT_ACCESSED
;
1397 TD
->HwTD
.gTD
.Control
.DelayInterrupt
= OHCI_TD_INTERRUPT_IMMEDIATE
;
1399 OhciTransfer
->PendingTDs
++;
1400 OhciTransfer
->ControlStatusTD
= TD
;
1404 /* And the last descriptor, which is not used in the current transfer (OpenHCI spec, 4.6) */
1405 TD
= OHCI_AllocateTD(OhciExtension
, OhciEndpoint
);
1407 PrevTD
->HwTD
.gTD
.NextTD
= TD
->PhysicalAddress
;
1408 PrevTD
->NextTDVa
= TD
;
1410 TD
->NextTDVa
= NULL
;
1411 /* TD->HwTD.gTD.NextTD = 0; */
1413 OhciTransfer
->NextTD
= TD
;
1414 OhciEndpoint
->HcdTailP
= TD
;
1416 OhciEndpoint
->HcdED
->HwED
.TailPointer
= TD
->PhysicalAddress
;
1418 OHCI_EnableList(OhciExtension
, OhciEndpoint
);
1420 return MP_STATUS_SUCCESS
;
1425 OHCI_BulkOrInterruptTransfer(IN POHCI_EXTENSION OhciExtension
,
1426 IN POHCI_ENDPOINT OhciEndpoint
,
1427 IN PUSBPORT_TRANSFER_PARAMETERS TransferParameters
,
1428 IN POHCI_TRANSFER OhciTransfer
,
1429 IN PUSBPORT_SCATTER_GATHER_LIST SGList
)
1432 POHCI_HCD_TD PrevTD
;
1433 ULONG TransferedLen
;
1436 DPRINT_OHCI("OHCI_BulkOrInterruptTransfer: ... \n");
1438 MaxTDs
= OHCI_RemainTDs(OhciExtension
, OhciEndpoint
);
1440 if (SGList
->SgElementCount
> MaxTDs
)
1441 return MP_STATUS_FAILURE
;
1443 TD
= OhciEndpoint
->HcdTailP
;
1449 TD
->HwTD
.gTD
.Control
.DelayInterrupt
= OHCI_TD_INTERRUPT_NONE
;
1450 TD
->HwTD
.gTD
.Control
.ConditionCode
= OHCI_TD_CONDITION_NOT_ACCESSED
;
1452 if (TransferParameters
->TransferFlags
& USBD_TRANSFER_DIRECTION_IN
)
1454 TD
->HwTD
.gTD
.Control
.BufferRounding
= FALSE
;
1455 TD
->HwTD
.gTD
.Control
.DirectionPID
= OHCI_TD_DIRECTION_PID_IN
;
1459 TD
->HwTD
.gTD
.Control
.BufferRounding
= TRUE
;
1460 TD
->HwTD
.gTD
.Control
.DirectionPID
= OHCI_TD_DIRECTION_PID_OUT
;
1463 TD
->Flags
|= OHCI_HCD_TD_FLAG_PROCESSED
;
1464 TD
->OhciTransfer
= OhciTransfer
;
1466 if (TransferParameters
->TransferBufferLength
)
1468 TransferedLen
= OHCI_MapTransferToTD(OhciExtension
,
1476 ASSERT(SGList
->SgElementCount
== 0);
1477 TD
->TransferLen
= 0;
1482 TD
= OHCI_AllocateTD(OhciExtension
, OhciEndpoint
);
1483 OhciTransfer
->PendingTDs
++;
1485 PrevTD
->HwTD
.gTD
.NextTD
= TD
->PhysicalAddress
;
1486 PrevTD
->NextTDVa
= TD
;
1488 while (TransferedLen
< TransferParameters
->TransferBufferLength
);
1490 if (TransferParameters
->TransferFlags
& USBD_SHORT_TRANSFER_OK
)
1492 PrevTD
->HwTD
.gTD
.Control
.BufferRounding
= TRUE
;
1493 OhciTransfer
->Flags
|= OHCI_TRANSFER_FLAGS_SHORT_TRANSFER_OK
;
1496 PrevTD
->HwTD
.gTD
.Control
.DelayInterrupt
= OHCI_TD_INTERRUPT_IMMEDIATE
;
1498 /* The last TD in a chain is not used in a transfer. The controller does not access it
1499 * so it will be used for chaining a next transfer to it (OpenHCI spec, 4.6)
1501 /* TD->HwTD.gTD.NextTD = 0; */
1502 TD
->NextTDVa
= NULL
;
1504 OhciTransfer
->NextTD
= TD
;
1505 OhciEndpoint
->HcdTailP
= TD
;
1507 OhciEndpoint
->HcdED
->HwED
.TailPointer
= TD
->PhysicalAddress
;
1509 OHCI_EnableList(OhciExtension
, OhciEndpoint
);
1511 return MP_STATUS_SUCCESS
;
1515 * @brief Creates the transfer descriptor chain for the given transfer's buffer
1516 * and attaches it to a given endpoint (for control, bulk or interrupt transfers)
1518 * @param[in] OhciExtension The ohci extension
1519 * @param[in] OhciEndpoint The ohci endpoint
1520 * @param[in] TransferParameters The transfer parameters
1521 * @param[in] OhciTransfer The ohci transfer
1522 * @param[in] SGList The scatter/gather list
1524 * @return MP_STATUS_SUCCESS or MP_STATUS_FAILURE if there are not enough TDs left
1525 * or wrong transfer type given
1529 OHCI_SubmitTransfer(IN PVOID ohciExtension
,
1530 IN PVOID ohciEndpoint
,
1531 IN PUSBPORT_TRANSFER_PARAMETERS TransferParameters
,
1532 IN PVOID ohciTransfer
,
1533 IN PUSBPORT_SCATTER_GATHER_LIST SGList
)
1535 POHCI_EXTENSION OhciExtension
= ohciExtension
;
1536 POHCI_ENDPOINT OhciEndpoint
= ohciEndpoint
;
1537 POHCI_TRANSFER OhciTransfer
= ohciTransfer
;
1540 DPRINT_OHCI("OHCI_SubmitTransfer: ... \n");
1542 RtlZeroMemory(OhciTransfer
, sizeof(OHCI_TRANSFER
));
1544 OhciTransfer
->TransferParameters
= TransferParameters
;
1545 OhciTransfer
->OhciEndpoint
= OhciEndpoint
;
1547 TransferType
= OhciEndpoint
->EndpointProperties
.TransferType
;
1549 if (TransferType
== USBPORT_TRANSFER_TYPE_CONTROL
)
1551 return OHCI_ControlTransfer(OhciExtension
,
1558 if (TransferType
== USBPORT_TRANSFER_TYPE_BULK
||
1559 TransferType
== USBPORT_TRANSFER_TYPE_INTERRUPT
)
1561 return OHCI_BulkOrInterruptTransfer(OhciExtension
,
1568 return MP_STATUS_FAILURE
;
1573 OHCI_SubmitIsoTransfer(IN PVOID ohciExtension
,
1574 IN PVOID ohciEndpoint
,
1575 IN PUSBPORT_TRANSFER_PARAMETERS TransferParameters
,
1576 IN PVOID ohciTransfer
,
1577 IN PVOID isoParameters
)
1579 DPRINT1("OHCI_SubmitIsoTransfer: UNIMPLEMENTED. FIXME\n");
1580 return MP_STATUS_SUCCESS
;
1585 OHCI_ProcessDoneTD(IN POHCI_EXTENSION OhciExtension
,
1587 IN BOOLEAN IsPortComplete
)
1589 POHCI_TRANSFER OhciTransfer
;
1590 POHCI_ENDPOINT OhciEndpoint
;
1595 DPRINT_OHCI("OHCI_ProcessDoneTD: ... \n");
1597 OhciTransfer
= TD
->OhciTransfer
;
1598 OhciEndpoint
= OhciTransfer
->OhciEndpoint
;
1600 OhciTransfer
->PendingTDs
--;
1602 Buffer
= TD
->HwTD
.gTD
.CurrentBuffer
;
1603 BufferEnd
= TD
->HwTD
.gTD
.BufferEnd
;
1605 if (TD
->Flags
& OHCI_HCD_TD_FLAG_NOT_ACCESSED
)
1607 TD
->HwTD
.gTD
.Control
.ConditionCode
= OHCI_TD_CONDITION_NO_ERROR
;
1611 if (TD
->HwTD
.gTD
.CurrentBuffer
)
1613 if (TD
->TransferLen
)
1615 Length
= (BufferEnd
& (PAGE_SIZE
- 1)) -
1616 (Buffer
& (PAGE_SIZE
- 1));
1620 if (Buffer
>> PAGE_SHIFT
!= BufferEnd
>> PAGE_SHIFT
)
1621 Length
+= PAGE_SIZE
;
1623 TD
->TransferLen
-= Length
;
1627 if (TD
->HwTD
.gTD
.Control
.DirectionPID
!= OHCI_TD_DIRECTION_PID_SETUP
)
1628 OhciTransfer
->TransferLen
+= TD
->TransferLen
;
1630 if (TD
->HwTD
.gTD
.Control
.ConditionCode
)
1632 OhciTransfer
->USBDStatus
= USBD_STATUS_HALTED
|
1633 TD
->HwTD
.gTD
.Control
.ConditionCode
;
1638 TD
->HwTD
.gTD
.NextTD
= 0;
1639 TD
->OhciTransfer
= 0;
1641 TD
->DoneLink
.Flink
= NULL
;
1642 TD
->DoneLink
.Blink
= NULL
;
1644 if (IsPortComplete
&& (OhciTransfer
->PendingTDs
== 0))
1646 RegPacket
.UsbPortCompleteTransfer(OhciExtension
,
1648 OhciTransfer
->TransferParameters
,
1649 OhciTransfer
->USBDStatus
,
1650 OhciTransfer
->TransferLen
);
1656 OHCI_ProcessDoneIsoTD(IN POHCI_EXTENSION OhciExtension
,
1658 IN BOOLEAN IsPortComplete
)
1660 DPRINT1("OHCI_ProcessDoneIsoTD: UNIMPLEMENTED. FIXME\n");
1664 * @brief Aborts the transfer descriptor chain in a given endpoint
1666 * @param[in] ohciExtension The ohci extension
1667 * @param[in] ohciEndpoint The ohci endpoint
1668 * @param[in] ohciTransfer The ohci transfer
1669 * @param[out] CompletedLength
1673 OHCI_AbortTransfer(IN PVOID ohciExtension
,
1674 IN PVOID ohciEndpoint
,
1675 IN PVOID ohciTransfer
,
1676 IN OUT PULONG CompletedLength
)
1678 POHCI_EXTENSION OhciExtension
= ohciExtension
;
1679 POHCI_ENDPOINT OhciEndpoint
= ohciEndpoint
;
1680 POHCI_TRANSFER OhciTransfer
= ohciTransfer
;
1681 POHCI_HCD_ED ED
= OhciEndpoint
->HcdED
;
1683 POHCI_HCD_TD TD
, NextTD
, LastTD
;
1685 BOOLEAN IsIsoEndpoint
;
1686 BOOLEAN IsProcessed
= FALSE
;
1688 DPRINT("OHCI_AbortTransfer: ohciEndpoint - %p, ohciTransfer - %p\n",
1692 IsIsoEndpoint
= (OhciEndpoint
->EndpointProperties
.TransferType
== USBPORT_TRANSFER_TYPE_ISOCHRONOUS
);
1693 NextTD
= RegPacket
.UsbPortGetMappedVirtualAddress(ED
->HwED
.HeadPointer
& OHCI_ED_HEAD_POINTER_MASK
,
1697 if (NextTD
->OhciTransfer
== OhciTransfer
)
1699 LastTD
= OhciTransfer
->NextTD
;
1701 /* Keeping the carry bit from previous pointer value */
1702 ED
->HwED
.HeadPointer
= LastTD
->PhysicalAddress
|
1703 (ED
->HwED
.HeadPointer
& OHCI_ED_HEAD_POINTER_CARRY
);
1705 OhciEndpoint
->HcdHeadP
= LastTD
;
1707 for (ix
= 0; ix
< OhciEndpoint
->MaxTransferDescriptors
; ix
++)
1709 TD
= &OhciEndpoint
->FirstTD
[ix
];
1711 if (TD
->OhciTransfer
!= OhciTransfer
)
1715 OHCI_ProcessDoneIsoTD(OhciExtension
, TD
, FALSE
);
1717 OHCI_ProcessDoneTD(OhciExtension
, TD
, FALSE
);
1720 *CompletedLength
= OhciTransfer
->TransferLen
;
1724 if (NextTD
== OhciEndpoint
->HcdHeadP
)
1727 for (TD
= OhciEndpoint
->HcdHeadP
; TD
!= NextTD
; TD
= TD
->NextTDVa
)
1729 if (TD
->OhciTransfer
!= OhciTransfer
)
1732 if (OhciEndpoint
->HcdHeadP
== TD
)
1733 OhciEndpoint
->HcdHeadP
= TD
->NextTDVa
;
1736 OHCI_ProcessDoneIsoTD(OhciExtension
, TD
, FALSE
);
1738 OHCI_ProcessDoneTD(OhciExtension
, TD
, FALSE
);
1745 for (TD
= OhciEndpoint
->HcdHeadP
; TD
->OhciTransfer
!= OhciTransfer
; TD
= TD
->NextTDVa
)
1747 if (TD
== OhciEndpoint
->HcdTailP
)
1755 for (; TD
->OhciTransfer
== OhciTransfer
; TD
= TD
->NextTDVa
)
1757 if (TD
== OhciEndpoint
->HcdTailP
)
1761 OHCI_ProcessDoneIsoTD(OhciExtension
, TD
, FALSE
);
1763 OHCI_ProcessDoneTD(OhciExtension
, TD
, FALSE
);
1766 LastTD
->OhciTransfer
->NextTD
= TD
;
1768 LastTD
->NextTDVa
= TD
;
1769 LastTD
->HwTD
.gTD
.NextTD
= TD
->PhysicalAddress
;
1772 *CompletedLength
= OhciTransfer
->TransferLen
;
1774 if (OhciTransfer
->TransferLen
)
1776 DPRINT("OHCI_AbortTransfer: *CompletedLength - %x\n", *CompletedLength
);
1782 OHCI_GetEndpointState(IN PVOID ohciExtension
,
1783 IN PVOID ohciEndpoint
)
1785 POHCI_ENDPOINT OhciEndpoint
= ohciEndpoint
;
1788 DPRINT_OHCI("OHCI_GetEndpointState: ... \n");
1790 ED
= OhciEndpoint
->HcdED
;
1792 if (ED
->Flags
& OHCI_HCD_TD_FLAG_NOT_ACCESSED
)
1793 return USBPORT_ENDPOINT_REMOVE
;
1795 if (ED
->HwED
.EndpointControl
.sKip
)
1796 return USBPORT_ENDPOINT_PAUSED
;
1798 return USBPORT_ENDPOINT_ACTIVE
;
1803 OHCI_RemoveEndpointFromSchedule(IN POHCI_ENDPOINT OhciEndpoint
)
1806 POHCI_HCD_ED PreviousED
;
1807 POHCI_STATIC_ED HeadED
;
1809 DPRINT_OHCI("OHCI_RemoveEndpointFromSchedule \n");
1811 ED
= OhciEndpoint
->HcdED
;
1812 HeadED
= OhciEndpoint
->HeadED
;
1814 if (&HeadED
->Link
== ED
->HcdEDLink
.Blink
)
1816 if (HeadED
->Type
== OHCI_STATIC_ED_TYPE_CONTROL
||
1817 HeadED
->Type
== OHCI_STATIC_ED_TYPE_BULK
)
1819 WRITE_REGISTER_ULONG(HeadED
->pNextED
, ED
->HwED
.NextED
);
1821 else if (HeadED
->Type
== OHCI_STATIC_ED_TYPE_INTERRUPT
)
1823 *HeadED
->pNextED
= ED
->HwED
.NextED
;
1827 DPRINT1("OHCI_RemoveEndpointFromSchedule: Unknown HeadED->Type - %x\n",
1834 PreviousED
= CONTAINING_RECORD(ED
->HcdEDLink
.Blink
,
1838 PreviousED
->HwED
.NextED
= ED
->HwED
.NextED
;
1841 RemoveEntryList(&ED
->HcdEDLink
);
1843 OhciEndpoint
->HeadED
= NULL
;
1848 OHCI_SetEndpointState(IN PVOID ohciExtension
,
1849 IN PVOID ohciEndpoint
,
1850 IN ULONG EndpointState
)
1852 POHCI_EXTENSION OhciExtension
= ohciExtension
;
1853 POHCI_ENDPOINT OhciEndpoint
= ohciEndpoint
;
1856 DPRINT_OHCI("OHCI_SetEndpointState: EndpointState - %x\n",
1859 ED
= OhciEndpoint
->HcdED
;
1861 switch (EndpointState
)
1863 case USBPORT_ENDPOINT_PAUSED
:
1864 ED
->HwED
.EndpointControl
.sKip
= 1;
1867 case USBPORT_ENDPOINT_ACTIVE
:
1868 ED
->HwED
.EndpointControl
.sKip
= 0;
1869 OHCI_EnableList(OhciExtension
, OhciEndpoint
);
1872 case USBPORT_ENDPOINT_REMOVE
:
1873 ED
->HwED
.EndpointControl
.sKip
= 1;
1874 ED
->Flags
|= OHCI_HCD_ED_FLAG_NOT_ACCESSED
;
1875 OHCI_RemoveEndpointFromSchedule(OhciEndpoint
);
1886 OHCI_PollAsyncEndpoint(IN POHCI_EXTENSION OhciExtension
,
1887 IN POHCI_ENDPOINT OhciEndpoint
)
1889 PUSBPORT_TRANSFER_PARAMETERS TransferParameters
;
1892 POHCI_HCD_TD NextTD
;
1894 PLIST_ENTRY DoneList
;
1895 POHCI_TRANSFER OhciTransfer
;
1896 POHCI_HCD_TD ControlStatusTD
;
1897 ULONG_PTR PhysicalAddress
;
1898 ULONG TransferNumber
;
1899 POHCI_TRANSFER transfer
;
1900 UCHAR ConditionCode
;
1901 BOOLEAN IsResetOnHalt
= FALSE
;
1903 //DPRINT_OHCI("OHCI_PollAsyncEndpoint: Endpoint - %p\n", OhciEndpoint);
1905 ED
= OhciEndpoint
->HcdED
;
1906 NextTdPA
= ED
->HwED
.HeadPointer
& OHCI_ED_HEAD_POINTER_MASK
;
1914 NextTD
= RegPacket
.UsbPortGetMappedVirtualAddress(NextTdPA
,
1917 DPRINT_OHCI("NextTD - %p\n", NextTD
);
1919 if ((ED
->HwED
.HeadPointer
& OHCI_ED_HEAD_POINTER_HALT
) == 0)
1920 goto ProcessListTDs
;
1924 IsResetOnHalt
= (ED
->Flags
& OHCI_HCD_ED_FLAG_RESET_ON_HALT
) != 0;
1925 DPRINT1("PollAsyncEndpoint: IsResetOnHalt %x\n", IsResetOnHalt
);
1927 for (TD
= OhciEndpoint
->HcdHeadP
; ; TD
= TD
->NextTDVa
)
1937 DPRINT("TD == NextTD - %p\n", TD
);
1938 goto HandleDoneList
;
1941 OhciTransfer
= TD
->OhciTransfer
;
1942 ConditionCode
= TD
->HwTD
.gTD
.Control
.ConditionCode
;
1944 DPRINT("TD - %p, ConditionCode - %X\n", TD
, ConditionCode
);
1947 switch (ConditionCode
)
1949 case OHCI_TD_CONDITION_NO_ERROR
:
1950 TD
->Flags
|= OHCI_HCD_TD_FLAG_DONE
;
1951 InsertTailList(&OhciEndpoint
->TDList
, &TD
->DoneLink
);
1954 case OHCI_TD_CONDITION_NOT_ACCESSED
:
1955 TD
->Flags
|= (OHCI_HCD_TD_FLAG_DONE
| OHCI_HCD_TD_FLAG_NOT_ACCESSED
);
1956 InsertTailList(&OhciEndpoint
->TDList
, &TD
->DoneLink
);
1959 case OHCI_TD_CONDITION_DATA_UNDERRUN
:
1960 DPRINT1("DATA_UNDERRUN. Transfer->Flags - %X\n", OhciTransfer
->Flags
);
1962 if (OhciTransfer
->Flags
& OHCI_TRANSFER_FLAGS_SHORT_TRANSFER_OK
)
1964 IsResetOnHalt
= TRUE
;
1965 TD
->HwTD
.gTD
.Control
.ConditionCode
= OHCI_TD_CONDITION_NO_ERROR
;
1967 ControlStatusTD
= OhciTransfer
->ControlStatusTD
;
1969 if ((TD
->Flags
& OHCI_HCD_TD_FLAG_CONTROL_STATUS
) == 0 &&
1972 PhysicalAddress
= ControlStatusTD
->PhysicalAddress
;
1973 PhysicalAddress
|= (ED
->HwED
.HeadPointer
&
1974 OHCI_ED_HEAD_POINTER_FLAGS_MASK
);
1976 ED
->HwED
.HeadPointer
= PhysicalAddress
;
1978 NextTD
= OhciTransfer
->ControlStatusTD
;
1979 DPRINT("PhysicalAddress - %p, NextTD - %p\n", PhysicalAddress
, NextTD
);
1983 TransferParameters
= OhciTransfer
->TransferParameters
;
1985 if (TransferParameters
->IsTransferSplited
)
1987 TransferNumber
= TransferParameters
->TransferCounter
;
1988 transfer
= OhciTransfer
;
1992 transfer
= transfer
->NextTD
->OhciTransfer
;
1993 NextTD
= transfer
->NextTD
;
1995 while (transfer
&& TransferNumber
==
1996 transfer
->TransferParameters
->TransferCounter
);
1998 PhysicalAddress
= NextTD
->PhysicalAddress
;
1999 PhysicalAddress
|= (ED
->HwED
.HeadPointer
&
2000 OHCI_ED_HEAD_POINTER_FLAGS_MASK
);
2002 ED
->HwED
.HeadPointer
= PhysicalAddress
;
2003 DPRINT("PhysicalAddress - %p, NextTD - %p\n", PhysicalAddress
, NextTD
);
2007 PhysicalAddress
= OhciTransfer
->NextTD
->PhysicalAddress
;
2008 PhysicalAddress
|= (ED
->HwED
.HeadPointer
&
2009 OHCI_ED_HEAD_POINTER_FLAGS_MASK
);
2011 ED
->HwED
.HeadPointer
= PhysicalAddress
;
2013 NextTD
= OhciTransfer
->NextTD
;
2014 DPRINT("PhysicalAddress - %p, NextTD - %p\n", PhysicalAddress
, NextTD
);
2018 TD
->Flags
|= OHCI_HCD_TD_FLAG_DONE
;
2019 InsertTailList(&OhciEndpoint
->TDList
, &TD
->DoneLink
);
2026 TD
->Flags
|= OHCI_HCD_TD_FLAG_DONE
;
2027 InsertTailList(&OhciEndpoint
->TDList
, &TD
->DoneLink
);
2029 ED
->HwED
.HeadPointer
= OhciTransfer
->NextTD
->PhysicalAddress
|
2030 (ED
->HwED
.HeadPointer
&
2031 OHCI_ED_HEAD_POINTER_FLAGS_MASK
);
2033 NextTD
= OhciTransfer
->NextTD
;
2040 TD
= OhciEndpoint
->HcdHeadP
;
2042 while (TD
!= NextTD
)
2045 TD
->Flags
|= OHCI_HCD_TD_FLAG_DONE
;
2046 InsertTailList(&OhciEndpoint
->TDList
, &TD
->DoneLink
);
2053 OhciEndpoint
->HcdHeadP
= NextTD
;
2055 DoneList
= &OhciEndpoint
->TDList
;
2057 while (!IsListEmpty(DoneList
))
2059 TD
= CONTAINING_RECORD(DoneList
->Flink
,
2063 RemoveHeadList(DoneList
);
2065 if (TD
->Flags
& OHCI_HCD_TD_FLAG_DONE
&&
2066 TD
->Flags
& OHCI_HCD_TD_FLAG_PROCESSED
)
2068 OHCI_ProcessDoneTD(OhciExtension
, TD
, TRUE
);
2074 ED
->HwED
.HeadPointer
&= ~OHCI_ED_HEAD_POINTER_HALT
;
2075 DPRINT("ED->HwED.HeadPointer - %p\n", ED
->HwED
.HeadPointer
);
2081 OHCI_PollIsoEndpoint(IN POHCI_EXTENSION OhciExtension
,
2082 IN POHCI_ENDPOINT OhciEndpoint
)
2084 DPRINT1("OHCI_PollAsyncEndpoint: UNIMPLEMENTED. FIXME \n");
2090 OHCI_PollEndpoint(IN PVOID ohciExtension
,
2091 IN PVOID ohciEndpoint
)
2093 POHCI_EXTENSION OhciExtension
= ohciExtension
;
2094 POHCI_ENDPOINT OhciEndpoint
= ohciEndpoint
;
2097 DPRINT_OHCI("OHCI_PollEndpoint: OhciExtension - %p, Endpoint - %p\n",
2101 TransferType
= OhciEndpoint
->EndpointProperties
.TransferType
;
2103 if (TransferType
== USBPORT_TRANSFER_TYPE_ISOCHRONOUS
)
2105 OHCI_PollIsoEndpoint(OhciExtension
, OhciEndpoint
);
2109 if (TransferType
== USBPORT_TRANSFER_TYPE_CONTROL
||
2110 TransferType
== USBPORT_TRANSFER_TYPE_BULK
||
2111 TransferType
== USBPORT_TRANSFER_TYPE_INTERRUPT
)
2113 OHCI_PollAsyncEndpoint(OhciExtension
, OhciEndpoint
);
2119 OHCI_CheckController(IN PVOID ohciExtension
)
2121 POHCI_EXTENSION OhciExtension
= ohciExtension
;
2122 POHCI_OPERATIONAL_REGISTERS OperationalRegs
;
2123 PULONG HcControlReg
;
2124 OHCI_REG_CONTROL HcControl
;
2129 //DPRINT_OHCI("OHCI_CheckController: ...\n");
2131 OperationalRegs
= OhciExtension
->OperationalRegs
;
2133 if (!OHCI_HardwarePresent(OhciExtension
, TRUE
))
2136 HcControlReg
= (PULONG
)&OperationalRegs
->HcControl
;
2137 HcControl
.AsULONG
= READ_REGISTER_ULONG(HcControlReg
);
2139 if (HcControl
.HostControllerFunctionalState
!= OHCI_HC_STATE_OPERATIONAL
)
2142 FmNumber
= READ_REGISTER_ULONG(&OperationalRegs
->HcFmNumber
);
2143 FmDiff
= (USHORT
)(FmNumber
- OhciExtension
->HcdFmNumber
);
2145 if (FmNumber
== 0 || FmDiff
< 5)
2148 HcHCCA
= &OhciExtension
->HcResourcesVA
->HcHCCA
;
2149 OhciExtension
->HcdFmNumber
= FmNumber
;
2151 if (HcHCCA
->Pad1
== 0)
2153 HcHCCA
->Pad1
= 0xBAD1;
2157 DPRINT1("OHCI_CheckController: HcHCCA->Pad1 - %x\n", HcHCCA
->Pad1
);
2159 if (HcHCCA
->Pad1
== 0xBAD1)
2161 HcHCCA
->Pad1
= 0xBAD2;
2163 else if (HcHCCA
->Pad1
== 0xBAD2)
2165 HcHCCA
->Pad1
= 0xBAD3;
2167 RegPacket
.UsbPortInvalidateController(OhciExtension
,
2168 USBPORT_INVALIDATE_CONTROLLER_RESET
);
2174 OHCI_Get32BitFrameNumber(IN PVOID ohciExtension
)
2176 POHCI_EXTENSION OhciExtension
= ohciExtension
;
2181 HcHCCA
= &OhciExtension
->HcResourcesVA
->HcHCCA
;
2183 /* 5.4 FrameInterval Counter: Get32BitFrameNumber() */
2185 hp
= OhciExtension
->FrameHighPart
;
2186 fm
= HcHCCA
->FrameNumber
;
2188 DPRINT_OHCI("OHCI_Get32BitFrameNumber: hp - %lX, fm - %lX\n", hp
, fm
);
2190 return ((fm
& 0x7FFF) | hp
) + ((fm
^ hp
) & 0x8000);
2195 OHCI_InterruptNextSOF(IN PVOID ohciExtension
)
2197 POHCI_EXTENSION OhciExtension
= ohciExtension
;
2198 POHCI_OPERATIONAL_REGISTERS OperationalRegs
;
2199 PULONG InterruptEnableReg
;
2200 OHCI_REG_INTERRUPT_ENABLE_DISABLE IntEnable
;
2202 DPRINT_OHCI("OHCI_InterruptNextSOF: OhciExtension - %p\n",
2205 OperationalRegs
= OhciExtension
->OperationalRegs
;
2206 InterruptEnableReg
= (PULONG
)&OperationalRegs
->HcInterruptEnable
;
2208 /* Enable interrupt generation due to Start of Frame */
2209 IntEnable
.AsULONG
= 0;
2210 IntEnable
.StartofFrame
= 1;
2212 WRITE_REGISTER_ULONG(InterruptEnableReg
, IntEnable
.AsULONG
);
2217 OHCI_EnableInterrupts(IN PVOID ohciExtension
)
2219 POHCI_EXTENSION OhciExtension
= ohciExtension
;
2220 POHCI_OPERATIONAL_REGISTERS OperationalRegs
;
2221 PULONG InterruptEnableReg
;
2222 OHCI_REG_INTERRUPT_ENABLE_DISABLE IntEnable
;
2224 DPRINT_OHCI("OHCI_EnableInterrupts: OhciExtension - %p\n",
2227 OperationalRegs
= OhciExtension
->OperationalRegs
;
2228 InterruptEnableReg
= (PULONG
)&OperationalRegs
->HcInterruptEnable
;
2230 /* Enable interrupt generation */
2231 IntEnable
.AsULONG
= 0;
2232 IntEnable
.MasterInterruptEnable
= 1;
2234 WRITE_REGISTER_ULONG(InterruptEnableReg
, IntEnable
.AsULONG
);
2239 OHCI_DisableInterrupts(IN PVOID ohciExtension
)
2241 POHCI_EXTENSION OhciExtension
= ohciExtension
;
2242 POHCI_OPERATIONAL_REGISTERS OperationalRegs
;
2243 PULONG InterruptDisableReg
;
2244 OHCI_REG_INTERRUPT_ENABLE_DISABLE IntDisable
;
2246 DPRINT_OHCI("OHCI_DisableInterrupts\n");
2248 OperationalRegs
= OhciExtension
->OperationalRegs
;
2249 InterruptDisableReg
= (PULONG
)&OperationalRegs
->HcInterruptDisable
;
2251 /* Disable interrupt generation */
2252 IntDisable
.AsULONG
= 0;
2253 IntDisable
.MasterInterruptEnable
= 1;
2255 WRITE_REGISTER_ULONG(InterruptDisableReg
, IntDisable
.AsULONG
);
2260 OHCI_PollController(IN PVOID ohciExtension
)
2262 DPRINT1("OHCI_PollController: UNIMPLEMENTED. FIXME\n");
2267 OHCI_SetEndpointDataToggle(IN PVOID ohciExtension
,
2268 IN PVOID ohciEndpoint
,
2269 IN ULONG DataToggle
)
2271 POHCI_ENDPOINT OhciEndpoint
= ohciEndpoint
;
2274 DPRINT_OHCI("OHCI_SetEndpointDataToggle: Endpoint - %p, DataToggle - %x\n",
2278 ED
= OhciEndpoint
->HcdED
;
2281 ED
->HwED
.HeadPointer
|= OHCI_ED_HEAD_POINTER_CARRY
;
2283 ED
->HwED
.HeadPointer
&= ~OHCI_ED_HEAD_POINTER_CARRY
;
2288 OHCI_GetEndpointStatus(IN PVOID ohciExtension
,
2289 IN PVOID ohciEndpoint
)
2291 POHCI_ENDPOINT OhciEndpoint
= ohciEndpoint
;
2293 ULONG EndpointStatus
= USBPORT_ENDPOINT_RUN
;
2295 DPRINT_OHCI("OHCI_GetEndpointStatus: ... \n");
2297 ED
= OhciEndpoint
->HcdED
;
2299 if ((ED
->HwED
.HeadPointer
& OHCI_ED_HEAD_POINTER_HALT
) &&
2300 !(ED
->Flags
& OHCI_HCD_ED_FLAG_RESET_ON_HALT
))
2302 EndpointStatus
= USBPORT_ENDPOINT_HALT
;
2305 return EndpointStatus
;
2310 OHCI_SetEndpointStatus(IN PVOID ohciExtension
,
2311 IN PVOID ohciEndpoint
,
2312 IN ULONG EndpointStatus
)
2314 POHCI_EXTENSION OhciExtension
= ohciExtension
;
2315 POHCI_ENDPOINT OhciEndpoint
= ohciEndpoint
;
2318 DPRINT_OHCI("OHCI_SetEndpointStatus: Endpoint - %p, EndpointStatus - %lX\n",
2322 if (EndpointStatus
== USBPORT_ENDPOINT_RUN
)
2324 ED
= OhciEndpoint
->HcdED
;
2325 ED
->HwED
.HeadPointer
&= ~OHCI_ED_HEAD_POINTER_HALT
;
2327 OHCI_EnableList(OhciExtension
, OhciEndpoint
);
2329 else if (EndpointStatus
== USBPORT_ENDPOINT_HALT
)
2337 OHCI_ResetController(IN PVOID ohciExtension
)
2339 POHCI_EXTENSION OhciExtension
= ohciExtension
;
2340 POHCI_OPERATIONAL_REGISTERS OperationalRegs
;
2343 PULONG CommandStatusReg
;
2344 PULONG InterruptEnableReg
;
2345 PULONG FmIntervalReg
;
2347 PULONG PortStatusReg
;
2348 OHCI_REG_CONTROL ControlBak
;
2349 OHCI_REG_CONTROL Control
;
2350 OHCI_REG_COMMAND_STATUS CommandStatus
;
2351 OHCI_REG_INTERRUPT_ENABLE_DISABLE IntEnable
;
2353 ULONG_PTR ControlHeadED
;
2354 ULONG_PTR BulkHeadED
;
2355 OHCI_REG_FRAME_INTERVAL FrameInterval
;
2356 ULONG_PTR PeriodicStart
;
2357 ULONG_PTR LSThreshold
;
2358 OHCI_REG_RH_STATUS RhStatus
;
2359 OHCI_REG_RH_DESCRIPTORA RhDescriptorA
;
2360 OHCI_REG_RH_PORT_STATUS PortStatus
;
2364 DPRINT("OHCI_ResetController: ... \n");
2366 OperationalRegs
= OhciExtension
->OperationalRegs
;
2368 ControlReg
= (PULONG
)&OperationalRegs
->HcControl
;
2369 CommandStatusReg
= (PULONG
)&OperationalRegs
->HcCommandStatus
;
2370 InterruptEnableReg
= (PULONG
)&OperationalRegs
->HcInterruptEnable
;
2371 FmIntervalReg
= (PULONG
)&OperationalRegs
->HcFmInterval
;
2372 RhStatusReg
= (PULONG
)&OperationalRegs
->HcRhStatus
;
2374 /* Backup FrameNumber from HcHCCA */
2375 FrameNumber
= OhciExtension
->HcResourcesVA
->HcHCCA
.FrameNumber
;
2377 /* Backup registers */
2378 ControlBak
.AsULONG
= READ_REGISTER_ULONG(ControlReg
);
2379 HCCA
= READ_REGISTER_ULONG(&OperationalRegs
->HcHCCA
);
2380 ControlHeadED
= READ_REGISTER_ULONG(&OperationalRegs
->HcControlHeadED
);
2381 BulkHeadED
= READ_REGISTER_ULONG(&OperationalRegs
->HcBulkHeadED
);
2382 FrameInterval
.AsULONG
= READ_REGISTER_ULONG(FmIntervalReg
);
2383 PeriodicStart
= READ_REGISTER_ULONG(&OperationalRegs
->HcPeriodicStart
);
2384 LSThreshold
= READ_REGISTER_ULONG(&OperationalRegs
->HcLSThreshold
);
2386 /* Reset HostController */
2387 CommandStatus
.AsULONG
= 0;
2388 CommandStatus
.HostControllerReset
= 1;
2389 WRITE_REGISTER_ULONG(CommandStatusReg
, CommandStatus
.AsULONG
);
2391 KeStallExecutionProcessor(10);
2393 /* Restore registers */
2394 WRITE_REGISTER_ULONG(&OperationalRegs
->HcHCCA
, HCCA
);
2395 WRITE_REGISTER_ULONG(&OperationalRegs
->HcControlHeadED
, ControlHeadED
);
2396 WRITE_REGISTER_ULONG(&OperationalRegs
->HcBulkHeadED
, BulkHeadED
);
2398 /* Set OPERATIONAL state for HC */
2399 Control
.AsULONG
= 0;
2400 Control
.HostControllerFunctionalState
= OHCI_HC_STATE_OPERATIONAL
;
2401 WRITE_REGISTER_ULONG(ControlReg
, Control
.AsULONG
);
2403 /* Set Toggle bit for FmInterval register */
2404 FrameInterval
.FrameIntervalToggle
= 1;
2405 WRITE_REGISTER_ULONG(FmIntervalReg
, FrameInterval
.AsULONG
);
2407 /* Restore registers */
2408 WRITE_REGISTER_ULONG(&OperationalRegs
->HcFmNumber
, FrameNumber
);
2409 WRITE_REGISTER_ULONG(&OperationalRegs
->HcPeriodicStart
, PeriodicStart
);
2410 WRITE_REGISTER_ULONG(&OperationalRegs
->HcLSThreshold
, LSThreshold
);
2412 /* Setup RhStatus register */
2413 RhStatus
.AsULONG
= 0;
2414 RhStatus
.SetRemoteWakeupEnable
= 1;
2415 RhStatus
.SetGlobalPower
= 1;
2416 WRITE_REGISTER_ULONG(RhStatusReg
, RhStatus
.AsULONG
);
2418 /* Setup RH PortStatus registers */
2419 RhDescriptorA
= OHCI_ReadRhDescriptorA(OhciExtension
);
2420 NumPorts
= RhDescriptorA
.NumberDownstreamPorts
;
2422 PortStatus
.AsULONG
= 0;
2423 PortStatus
.SetPortPower
= 1;
2425 for (ix
= 0; ix
< NumPorts
; ix
++)
2427 PortStatusReg
= (PULONG
)&OperationalRegs
->HcRhPortStatus
[ix
];
2428 WRITE_REGISTER_ULONG(PortStatusReg
, PortStatus
.AsULONG
);
2431 /* Restore HcControl register */
2432 ControlBak
.HostControllerFunctionalState
= OHCI_HC_STATE_OPERATIONAL
;
2433 WRITE_REGISTER_ULONG(ControlReg
, ControlBak
.AsULONG
);
2435 /* Setup HcInterruptEnable register */
2436 IntEnable
.AsULONG
= 0xFFFFFFFF;
2437 IntEnable
.Reserved1
= 0;
2438 WRITE_REGISTER_ULONG(InterruptEnableReg
, IntEnable
.AsULONG
);
2443 OHCI_StartSendOnePacket(IN PVOID ohciExtension
,
2444 IN PVOID PacketParameters
,
2446 IN PULONG pDataLength
,
2449 IN ULONG BufferLength
,
2450 IN USBD_STATUS
* pUSBDStatus
)
2452 DPRINT1("OHCI_StartSendOnePacket: UNIMPLEMENTED. FIXME\n");
2453 return MP_STATUS_SUCCESS
;
2458 OHCI_EndSendOnePacket(IN PVOID ohciExtension
,
2459 IN PVOID PacketParameters
,
2461 IN PULONG pDataLength
,
2464 IN ULONG BufferLength
,
2465 IN USBD_STATUS
* pUSBDStatus
)
2467 DPRINT1("OHCI_EndSendOnePacket: UNIMPLEMENTED. FIXME\n");
2468 return MP_STATUS_SUCCESS
;
2473 OHCI_PassThru(IN PVOID ohciExtension
,
2474 IN PVOID passThruParameters
,
2475 IN ULONG ParameterLength
,
2476 IN PVOID pParameters
)
2478 DPRINT1("OHCI_PassThru: UNIMPLEMENTED. FIXME\n");
2479 return MP_STATUS_SUCCESS
;
2484 OHCI_Unload(IN PDRIVER_OBJECT DriverObject
)
2487 DPRINT1("OHCI_Unload: Not supported\n");
2494 OHCI_FlushInterrupts(IN PVOID uhciExtension
)
2497 DPRINT1("OHCI_FlushInterrupts: Not supported\n");
2504 DriverEntry(IN PDRIVER_OBJECT DriverObject
,
2505 IN PUNICODE_STRING RegistryPath
)
2509 DPRINT_OHCI("DriverEntry: DriverObject - %p, RegistryPath - %wZ\n",
2513 RtlZeroMemory(&RegPacket
, sizeof(USBPORT_REGISTRATION_PACKET
));
2515 RegPacket
.MiniPortVersion
= USB_MINIPORT_VERSION_OHCI
;
2517 RegPacket
.MiniPortFlags
= USB_MINIPORT_FLAGS_INTERRUPT
|
2518 USB_MINIPORT_FLAGS_MEMORY_IO
;
2520 RegPacket
.MiniPortBusBandwidth
= TOTAL_USB11_BUS_BANDWIDTH
;
2522 RegPacket
.MiniPortExtensionSize
= sizeof(OHCI_EXTENSION
);
2523 RegPacket
.MiniPortEndpointSize
= sizeof(OHCI_ENDPOINT
);
2524 RegPacket
.MiniPortTransferSize
= sizeof(OHCI_TRANSFER
);
2525 RegPacket
.MiniPortResourcesSize
= sizeof(OHCI_HC_RESOURCES
);
2527 RegPacket
.OpenEndpoint
= OHCI_OpenEndpoint
;
2528 RegPacket
.ReopenEndpoint
= OHCI_ReopenEndpoint
;
2529 RegPacket
.QueryEndpointRequirements
= OHCI_QueryEndpointRequirements
;
2530 RegPacket
.CloseEndpoint
= OHCI_CloseEndpoint
;
2531 RegPacket
.StartController
= OHCI_StartController
;
2532 RegPacket
.StopController
= OHCI_StopController
;
2533 RegPacket
.SuspendController
= OHCI_SuspendController
;
2534 RegPacket
.ResumeController
= OHCI_ResumeController
;
2535 RegPacket
.InterruptService
= OHCI_InterruptService
;
2536 RegPacket
.InterruptDpc
= OHCI_InterruptDpc
;
2537 RegPacket
.SubmitTransfer
= OHCI_SubmitTransfer
;
2538 RegPacket
.SubmitIsoTransfer
= OHCI_SubmitIsoTransfer
;
2539 RegPacket
.AbortTransfer
= OHCI_AbortTransfer
;
2540 RegPacket
.GetEndpointState
= OHCI_GetEndpointState
;
2541 RegPacket
.SetEndpointState
= OHCI_SetEndpointState
;
2542 RegPacket
.PollEndpoint
= OHCI_PollEndpoint
;
2543 RegPacket
.CheckController
= OHCI_CheckController
;
2544 RegPacket
.Get32BitFrameNumber
= OHCI_Get32BitFrameNumber
;
2545 RegPacket
.InterruptNextSOF
= OHCI_InterruptNextSOF
;
2546 RegPacket
.EnableInterrupts
= OHCI_EnableInterrupts
;
2547 RegPacket
.DisableInterrupts
= OHCI_DisableInterrupts
;
2548 RegPacket
.PollController
= OHCI_PollController
;
2549 RegPacket
.SetEndpointDataToggle
= OHCI_SetEndpointDataToggle
;
2550 RegPacket
.GetEndpointStatus
= OHCI_GetEndpointStatus
;
2551 RegPacket
.SetEndpointStatus
= OHCI_SetEndpointStatus
;
2552 RegPacket
.ResetController
= OHCI_ResetController
;
2553 RegPacket
.RH_GetRootHubData
= OHCI_RH_GetRootHubData
;
2554 RegPacket
.RH_GetStatus
= OHCI_RH_GetStatus
;
2555 RegPacket
.RH_GetPortStatus
= OHCI_RH_GetPortStatus
;
2556 RegPacket
.RH_GetHubStatus
= OHCI_RH_GetHubStatus
;
2557 RegPacket
.RH_SetFeaturePortReset
= OHCI_RH_SetFeaturePortReset
;
2558 RegPacket
.RH_SetFeaturePortPower
= OHCI_RH_SetFeaturePortPower
;
2559 RegPacket
.RH_SetFeaturePortEnable
= OHCI_RH_SetFeaturePortEnable
;
2560 RegPacket
.RH_SetFeaturePortSuspend
= OHCI_RH_SetFeaturePortSuspend
;
2561 RegPacket
.RH_ClearFeaturePortEnable
= OHCI_RH_ClearFeaturePortEnable
;
2562 RegPacket
.RH_ClearFeaturePortPower
= OHCI_RH_ClearFeaturePortPower
;
2563 RegPacket
.RH_ClearFeaturePortSuspend
= OHCI_RH_ClearFeaturePortSuspend
;
2564 RegPacket
.RH_ClearFeaturePortEnableChange
= OHCI_RH_ClearFeaturePortEnableChange
;
2565 RegPacket
.RH_ClearFeaturePortConnectChange
= OHCI_RH_ClearFeaturePortConnectChange
;
2566 RegPacket
.RH_ClearFeaturePortResetChange
= OHCI_RH_ClearFeaturePortResetChange
;
2567 RegPacket
.RH_ClearFeaturePortSuspendChange
= OHCI_RH_ClearFeaturePortSuspendChange
;
2568 RegPacket
.RH_ClearFeaturePortOvercurrentChange
= OHCI_RH_ClearFeaturePortOvercurrentChange
;
2569 RegPacket
.RH_DisableIrq
= OHCI_RH_DisableIrq
;
2570 RegPacket
.RH_EnableIrq
= OHCI_RH_EnableIrq
;
2571 RegPacket
.StartSendOnePacket
= OHCI_StartSendOnePacket
;
2572 RegPacket
.EndSendOnePacket
= OHCI_EndSendOnePacket
;
2573 RegPacket
.PassThru
= OHCI_PassThru
;
2574 RegPacket
.FlushInterrupts
= OHCI_FlushInterrupts
;
2576 DriverObject
->DriverUnload
= OHCI_Unload
;
2578 Status
= USBPORT_RegisterUSBPortDriver(DriverObject
,
2579 USB10_MINIPORT_INTERFACE_VERSION
,
2582 DPRINT_OHCI("DriverEntry: USBPORT_RegisterUSBPortDriver return Status - %x\n",