6 #define NDEBUG_OHCI_TRACE
9 USBPORT_REGISTRATION_PACKET RegPacket
;
11 static const UCHAR Index
[8] =
13 ENDPOINT_INTERRUPT_1ms
- 1,
14 ENDPOINT_INTERRUPT_2ms
- 1,
15 ENDPOINT_INTERRUPT_4ms
- 1,
16 ENDPOINT_INTERRUPT_8ms
- 1,
17 ENDPOINT_INTERRUPT_16ms
- 1,
18 ENDPOINT_INTERRUPT_32ms
- 1,
19 ENDPOINT_INTERRUPT_32ms
- 1,
20 ENDPOINT_INTERRUPT_32ms
- 1
23 static const UCHAR Balance
[OHCI_NUMBER_OF_INTERRUPTS
] =
25 0, 16, 8, 24, 4, 20, 12, 28, 2, 18, 10, 26, 6, 22, 14, 30,
26 1, 17, 9, 25, 5, 21, 13, 29, 3, 19, 11, 27, 7, 23, 15, 31
31 OHCI_DumpHcdED(POHCI_HCD_ED ED
)
33 DPRINT("ED - %p\n", ED
);
34 DPRINT("EndpointControl - %X\n", ED
->HwED
.EndpointControl
.AsULONG
);
35 DPRINT("TailPointer - %08X\n", ED
->HwED
.TailPointer
);
36 DPRINT("HeadPointer - %08X\n", ED
->HwED
.HeadPointer
);
37 DPRINT("NextED - %08X\n", ED
->HwED
.NextED
);
42 OHCI_DumpHcdTD(POHCI_HCD_TD TD
)
44 DPRINT("TD - %p\n", TD
);
45 DPRINT("gTD.Control - %08X\n", TD
->HwTD
.gTD
.Control
.AsULONG
);
46 if (TD
->HwTD
.gTD
.CurrentBuffer
)
47 DPRINT("gTD.CurrentBuffer - %08X\n", TD
->HwTD
.gTD
.CurrentBuffer
);
48 if (TD
->HwTD
.gTD
.NextTD
)
49 DPRINT("gTD.NextTD - %08X\n", TD
->HwTD
.gTD
.NextTD
);
50 if (TD
->HwTD
.gTD
.BufferEnd
)
51 DPRINT("gTD.BufferEnd - %08X\n", TD
->HwTD
.gTD
.BufferEnd
);
53 if (TD
->HwTD
.SetupPacket
.bmRequestType
.B
)
54 DPRINT("bmRequestType - %02X\n", TD
->HwTD
.SetupPacket
.bmRequestType
.B
);
55 if (TD
->HwTD
.SetupPacket
.bRequest
)
56 DPRINT("bRequest - %02X\n", TD
->HwTD
.SetupPacket
.bRequest
);
57 if (TD
->HwTD
.SetupPacket
.wValue
.W
)
58 DPRINT("wValue - %04X\n", TD
->HwTD
.SetupPacket
.wValue
.W
);
59 if (TD
->HwTD
.SetupPacket
.wIndex
.W
)
60 DPRINT("wIndex - %04X\n", TD
->HwTD
.SetupPacket
.wIndex
.W
);
61 if (TD
->HwTD
.SetupPacket
.wLength
)
62 DPRINT("wLength - %04X\n", TD
->HwTD
.SetupPacket
.wLength
);
64 DPRINT("PhysicalAddress - %p\n", TD
->PhysicalAddress
);
65 DPRINT("Flags - %X\n", TD
->Flags
);
66 DPRINT("OhciTransfer - %08X\n", TD
->OhciTransfer
);
67 DPRINT("NextHcdTD - %08X\n", TD
->NextHcdTD
);
69 DPRINT("TransferLen - %X\n", TD
->TransferLen
);
74 OHCI_EnableList(IN POHCI_EXTENSION OhciExtension
,
75 IN POHCI_ENDPOINT OhciEndpoint
)
77 POHCI_OPERATIONAL_REGISTERS OperationalRegs
;
78 PULONG CommandStatusReg
;
80 OHCI_REG_COMMAND_STATUS CommandStatus
;
82 DPRINT_OHCI("OHCI_EnableList: ... \n");
84 OperationalRegs
= OhciExtension
->OperationalRegs
;
85 CommandStatusReg
= (PULONG
)&OperationalRegs
->HcCommandStatus
;
87 CommandStatus
.AsULONG
= 0;
89 if (READ_REGISTER_ULONG((PULONG
)&OperationalRegs
->HcControlHeadED
))
90 CommandStatus
.ControlListFilled
= 1;
92 if (READ_REGISTER_ULONG((PULONG
)&OperationalRegs
->HcBulkHeadED
))
93 CommandStatus
.BulkListFilled
= 1;
95 TransferType
= OhciEndpoint
->EndpointProperties
.TransferType
;
97 if (TransferType
== USBPORT_TRANSFER_TYPE_BULK
)
98 CommandStatus
.BulkListFilled
= 1;
99 else if (TransferType
== USBPORT_TRANSFER_TYPE_CONTROL
)
100 CommandStatus
.ControlListFilled
= 1;
102 WRITE_REGISTER_ULONG(CommandStatusReg
, CommandStatus
.AsULONG
);
107 OHCI_InsertEndpointInSchedule(IN POHCI_ENDPOINT OhciEndpoint
)
109 POHCI_STATIC_ED HeadED
;
112 PLIST_ENTRY HeadLink
;
114 DPRINT_OHCI("OHCI_InsertEndpointInSchedule: OhciEndpoint - %p\n",
117 ED
= OhciEndpoint
->HcdED
;
119 HeadED
= OhciEndpoint
->HeadED
;
120 HeadLink
= &HeadED
->Link
;
122 if (IsListEmpty(HeadLink
))
124 InsertHeadList(HeadLink
, &ED
->HcdEDLink
);
126 if (HeadED
->Type
== OHCI_STATIC_ED_TYPE_CONTROL
||
127 HeadED
->Type
== OHCI_STATIC_ED_TYPE_BULK
)
129 ED
->HwED
.NextED
= READ_REGISTER_ULONG(HeadED
->pNextED
);
130 WRITE_REGISTER_ULONG(HeadED
->pNextED
, ED
->PhysicalAddress
);
132 else if (HeadED
->Type
== OHCI_STATIC_ED_TYPE_INTERRUPT
)
134 ED
->HwED
.NextED
= *HeadED
->pNextED
;
135 *HeadED
->pNextED
= ED
->PhysicalAddress
;
139 DPRINT1("OHCI_InsertEndpointInSchedule: Unknown HeadED->Type - %x\n",
146 PrevED
= CONTAINING_RECORD(HeadLink
->Blink
,
150 InsertTailList(HeadLink
, &ED
->HcdEDLink
);
153 PrevED
->HwED
.NextED
= ED
->PhysicalAddress
;
159 OHCI_InitializeED(IN POHCI_ENDPOINT OhciEndpoint
,
161 IN POHCI_HCD_TD FirstTD
,
164 OHCI_ENDPOINT_CONTROL EndpointControl
;
165 PUSBPORT_ENDPOINT_PROPERTIES EndpointProperties
;
167 DPRINT_OHCI("OHCI_InitializeED: OhciEndpoint - %p, ED - %p, FirstTD - %p, EdPA - %p\n",
173 RtlZeroMemory(ED
, sizeof(OHCI_HCD_ED
));
175 ED
->PhysicalAddress
= EdPA
;
177 EndpointProperties
= &OhciEndpoint
->EndpointProperties
;
179 EndpointControl
= ED
->HwED
.EndpointControl
;
181 EndpointControl
.FunctionAddress
= EndpointProperties
->DeviceAddress
;
182 EndpointControl
.EndpointNumber
= EndpointProperties
->EndpointAddress
;
183 EndpointControl
.MaximumPacketSize
= EndpointProperties
->TotalMaxPacketSize
;
185 if (EndpointProperties
->TransferType
== USBPORT_TRANSFER_TYPE_CONTROL
)
187 EndpointControl
.Direction
= OHCI_ED_DATA_FLOW_DIRECTION_FROM_TD
;
189 else if (EndpointProperties
->Direction
)
191 EndpointControl
.Direction
= OHCI_ED_DATA_FLOW_DIRECTION_OUT
;
195 EndpointControl
.Direction
= OHCI_ED_DATA_FLOW_DIRECTION_IN
;
198 if (EndpointProperties
->DeviceSpeed
== UsbLowSpeed
)
199 EndpointControl
.Speed
= OHCI_ENDPOINT_LOW_SPEED
;
201 if (EndpointProperties
->TransferType
== USBPORT_TRANSFER_TYPE_ISOCHRONOUS
)
202 EndpointControl
.Format
= OHCI_ENDPOINT_ISOCHRONOUS_FORMAT
;
204 EndpointControl
.sKip
= 1;
206 ED
->HwED
.EndpointControl
= EndpointControl
;
208 ED
->HwED
.TailPointer
= FirstTD
->PhysicalAddress
;
209 ED
->HwED
.HeadPointer
= FirstTD
->PhysicalAddress
;
211 FirstTD
->Flags
|= OHCI_HCD_TD_FLAG_ALLOCATED
;
213 OhciEndpoint
->HcdTailP
= FirstTD
;
214 OhciEndpoint
->HcdHeadP
= FirstTD
;
221 OHCI_InitializeTDs(IN POHCI_ENDPOINT OhciEndpoint
,
222 IN PUSBPORT_ENDPOINT_PROPERTIES EndpointProperties
)
229 ASSERT(EndpointProperties
->BufferLength
> sizeof(OHCI_HCD_ED
));
231 TdCount
= (EndpointProperties
->BufferLength
- sizeof(OHCI_HCD_ED
)) /
234 OhciEndpoint
->MaxTransferDescriptors
= TdCount
;
236 DPRINT_OHCI("OHCI_InitializeTDs: TdCount - %x\n", TdCount
);
240 TdVA
= OhciEndpoint
->FirstTD
;
242 TdPA
= (ULONG
)EndpointProperties
->BufferPA
+ sizeof(OHCI_HCD_ED
);
244 for (ix
= 0; ix
< TdCount
; ix
++)
246 DPRINT_OHCI("OHCI_InitializeTDs: TdVA - %p, TdPA - %08X\n", TdVA
, TdPA
);
248 RtlZeroMemory(TdVA
, sizeof(OHCI_HCD_TD
));
250 TdVA
->PhysicalAddress
= TdPA
;
252 TdVA
->OhciTransfer
= 0;
255 TdPA
+= sizeof(OHCI_HCD_TD
);
261 OHCI_OpenControlEndpoint(IN POHCI_EXTENSION OhciExtension
,
262 IN PUSBPORT_ENDPOINT_PROPERTIES EndpointProperties
,
263 IN POHCI_ENDPOINT OhciEndpoint
)
267 DPRINT_OHCI("OHCI_OpenControlEndpoint: ... \n");
269 ED
= (POHCI_HCD_ED
)EndpointProperties
->BufferVA
;
271 OhciEndpoint
->FirstTD
= (POHCI_HCD_TD
)((ULONG_PTR
)ED
+ sizeof(OHCI_HCD_ED
));
272 OhciEndpoint
->HeadED
= &OhciExtension
->ControlStaticED
;
274 OHCI_InitializeTDs(OhciEndpoint
, EndpointProperties
);
276 OhciEndpoint
->HcdED
= OHCI_InitializeED(OhciEndpoint
,
278 OhciEndpoint
->FirstTD
,
279 EndpointProperties
->BufferPA
);
281 OhciEndpoint
->HcdED
->Flags
= OHCI_HCD_ED_FLAG_CONTROL
|
282 OHCI_HCD_ED_FLAG_RESET_ON_HALT
;
284 OHCI_InsertEndpointInSchedule(OhciEndpoint
);
286 return MP_STATUS_SUCCESS
;
291 OHCI_OpenBulkEndpoint(IN POHCI_EXTENSION OhciExtension
,
292 IN PUSBPORT_ENDPOINT_PROPERTIES EndpointProperties
,
293 IN POHCI_ENDPOINT OhciEndpoint
)
297 DPRINT_OHCI("OHCI_OpenBulkEndpoint: ... \n");
299 ED
= (POHCI_HCD_ED
)EndpointProperties
->BufferVA
;
301 OhciEndpoint
->FirstTD
= (POHCI_HCD_TD
)((ULONG_PTR
)ED
+ sizeof(OHCI_HCD_ED
));
302 OhciEndpoint
->HeadED
= &OhciExtension
->BulkStaticED
;
304 OHCI_InitializeTDs(OhciEndpoint
, EndpointProperties
);
306 OhciEndpoint
->HcdED
= OHCI_InitializeED(OhciEndpoint
,
308 OhciEndpoint
->FirstTD
,
309 EndpointProperties
->BufferPA
);
311 OHCI_InsertEndpointInSchedule(OhciEndpoint
);
313 return MP_STATUS_SUCCESS
;
318 OHCI_OpenInterruptEndpoint(IN POHCI_EXTENSION OhciExtension
,
319 IN PUSBPORT_ENDPOINT_PROPERTIES EndpointProperties
,
320 IN POHCI_ENDPOINT OhciEndpoint
)
325 ULONG ScheduleOffset
;
327 DPRINT_OHCI("OHCI_OpenInterruptEndpoint: ... \n");
329 ED
= (POHCI_HCD_ED
)EndpointProperties
->BufferVA
;
331 OhciEndpoint
->FirstTD
= (POHCI_HCD_TD
)((ULONG_PTR
)ED
+ sizeof(OHCI_HCD_ED
));
333 Period
= EndpointProperties
->Period
;
337 while (!(Period
& 1))
343 ASSERT(PeriodIdx
< ARRAYSIZE(Index
));
345 ScheduleOffset
= EndpointProperties
->ScheduleOffset
;
346 DPRINT_OHCI("OHCI_OpenInterruptEndpoint: InitTD. Index[PeriodIdx] - %x, ScheduleOffset - %x\n",
350 OhciEndpoint
->HeadED
= &OhciExtension
->IntStaticED
[Index
[PeriodIdx
] +
353 //OhciEndpoint->HeadED->UsbBandwidth += EndpointProperties->UsbBandwidth;
355 OHCI_InitializeTDs(OhciEndpoint
, EndpointProperties
);
357 OhciEndpoint
->HcdED
= OHCI_InitializeED(OhciEndpoint
,
359 OhciEndpoint
->FirstTD
,
360 EndpointProperties
->BufferPA
);
362 OHCI_InsertEndpointInSchedule(OhciEndpoint
);
364 return MP_STATUS_SUCCESS
;
369 OHCI_OpenIsoEndpoint(IN POHCI_EXTENSION OhciExtension
,
370 IN PUSBPORT_ENDPOINT_PROPERTIES EndpointProperties
,
371 IN POHCI_ENDPOINT OhciEndpoint
)
373 DPRINT1("OHCI_OpenIsoEndpoint: UNIMPLEMENTED. FIXME\n");
374 return MP_STATUS_NOT_SUPPORTED
;
379 OHCI_OpenEndpoint(IN PVOID ohciExtension
,
380 IN PUSBPORT_ENDPOINT_PROPERTIES EndpointProperties
,
381 IN PVOID ohciEndpoint
)
383 POHCI_EXTENSION OhciExtension
= ohciExtension
;
384 POHCI_ENDPOINT OhciEndpoint
= ohciEndpoint
;
388 DPRINT_OHCI("OHCI_OpenEndpoint: ... \n");
390 RtlCopyMemory(&OhciEndpoint
->EndpointProperties
,
392 sizeof(OhciEndpoint
->EndpointProperties
));
394 InitializeListHead(&OhciEndpoint
->TDList
);
396 TransferType
= EndpointProperties
->TransferType
;
398 switch (TransferType
)
400 case USBPORT_TRANSFER_TYPE_ISOCHRONOUS
:
401 MPStatus
= OHCI_OpenIsoEndpoint(OhciExtension
,
406 case USBPORT_TRANSFER_TYPE_CONTROL
:
407 MPStatus
= OHCI_OpenControlEndpoint(OhciExtension
,
412 case USBPORT_TRANSFER_TYPE_BULK
:
413 MPStatus
= OHCI_OpenBulkEndpoint(OhciExtension
,
418 case USBPORT_TRANSFER_TYPE_INTERRUPT
:
419 MPStatus
= OHCI_OpenInterruptEndpoint(OhciExtension
,
425 MPStatus
= MP_STATUS_NOT_SUPPORTED
;
434 OHCI_ReopenEndpoint(IN PVOID ohciExtension
,
435 IN PUSBPORT_ENDPOINT_PROPERTIES EndpointProperties
,
436 IN PVOID ohciEndpoint
)
438 POHCI_ENDPOINT OhciEndpoint
= ohciEndpoint
;
441 DPRINT_OHCI("OHCI_ReopenEndpoint: ... \n");
443 ED
= OhciEndpoint
->HcdED
;
445 RtlCopyMemory(&OhciEndpoint
->EndpointProperties
,
447 sizeof(OhciEndpoint
->EndpointProperties
));
449 ED
->HwED
.EndpointControl
.FunctionAddress
=
450 OhciEndpoint
->EndpointProperties
.DeviceAddress
;
452 ED
->HwED
.EndpointControl
.MaximumPacketSize
=
453 OhciEndpoint
->EndpointProperties
.TotalMaxPacketSize
;
455 return MP_STATUS_SUCCESS
;
460 OHCI_QueryEndpointRequirements(IN PVOID ohciExtension
,
461 IN PUSBPORT_ENDPOINT_PROPERTIES EndpointProperties
,
462 IN PUSBPORT_ENDPOINT_REQUIREMENTS EndpointRequirements
)
466 DPRINT_OHCI("OHCI_QueryEndpointRequirements: ... \n");
468 TransferType
= EndpointProperties
->TransferType
;
470 switch (TransferType
)
472 case USBPORT_TRANSFER_TYPE_ISOCHRONOUS
:
473 DPRINT_OHCI("OHCI_QueryEndpointRequirements: IsoTransfer\n");
474 EndpointRequirements
->MaxTransferSize
= OHCI_MAX_ISO_TRANSFER_SIZE
;
475 EndpointRequirements
->HeaderBufferSize
=
476 sizeof(OHCI_HCD_ED
) + OHCI_MAX_ISO_TD_COUNT
* sizeof(OHCI_HCD_TD
);
479 case USBPORT_TRANSFER_TYPE_CONTROL
:
480 DPRINT_OHCI("OHCI_QueryEndpointRequirements: ControlTransfer\n");
481 EndpointRequirements
->MaxTransferSize
= OHCI_MAX_CONTROL_TRANSFER_SIZE
;
482 EndpointRequirements
->HeaderBufferSize
=
483 sizeof(OHCI_HCD_ED
) + OHCI_MAX_CONTROL_TD_COUNT
* sizeof(OHCI_HCD_TD
);
486 case USBPORT_TRANSFER_TYPE_BULK
:
487 DPRINT_OHCI("OHCI_QueryEndpointRequirements: BulkTransfer\n");
488 EndpointRequirements
->MaxTransferSize
= OHCI_MAX_BULK_TRANSFER_SIZE
;
489 EndpointRequirements
->HeaderBufferSize
=
490 sizeof(OHCI_HCD_ED
) + OHCI_MAX_BULK_TD_COUNT
* sizeof(OHCI_HCD_TD
);
493 case USBPORT_TRANSFER_TYPE_INTERRUPT
:
494 DPRINT_OHCI("OHCI_QueryEndpointRequirements: InterruptTransfer\n");
495 EndpointRequirements
->MaxTransferSize
= OHCI_MAX_INTERRUPT_TRANSFER_SIZE
;
496 EndpointRequirements
->HeaderBufferSize
=
497 sizeof(OHCI_HCD_ED
) + OHCI_MAX_INTERRUPT_TD_COUNT
* sizeof(OHCI_HCD_TD
);
501 DPRINT1("OHCI_QueryEndpointRequirements: Unknown TransferType - %x\n",
510 OHCI_CloseEndpoint(IN PVOID ohciExtension
,
511 IN PVOID ohciEndpoint
,
512 IN BOOLEAN IsDoDisablePeriodic
)
515 DPRINT1("OHCI_CloseEndpoint: Not supported\n");
522 OHCI_TakeControlHC(IN POHCI_EXTENSION OhciExtension
,
523 IN PUSBPORT_RESOURCES Resources
)
525 POHCI_OPERATIONAL_REGISTERS OperationalRegs
;
527 PULONG InterruptEnableReg
;
528 PULONG InterruptDisableReg
;
529 PULONG CommandStatusReg
;
530 PULONG InterruptStatusReg
;
531 OHCI_REG_CONTROL Control
;
532 OHCI_REG_INTERRUPT_ENABLE_DISABLE IntEnable
;
533 OHCI_REG_INTERRUPT_ENABLE_DISABLE IntDisable
;
534 OHCI_REG_COMMAND_STATUS CommandStatus
;
535 OHCI_REG_INTERRUPT_STATUS IntStatus
;
536 LARGE_INTEGER EndTime
;
537 LARGE_INTEGER SystemTime
;
539 DPRINT("OHCI_TakeControlHC: ...\n");
541 OperationalRegs
= OhciExtension
->OperationalRegs
;
543 ControlReg
= (PULONG
)&OperationalRegs
->HcControl
;
544 InterruptEnableReg
= (PULONG
)&OperationalRegs
->HcInterruptEnable
;
545 InterruptDisableReg
= (PULONG
)&OperationalRegs
->HcInterruptDisable
;
546 CommandStatusReg
= (PULONG
)&OperationalRegs
->HcCommandStatus
;
547 InterruptStatusReg
= (PULONG
)&OperationalRegs
->HcInterruptStatus
;
549 /* 5.1.1.3 Take Control of Host Controller */
550 Control
.AsULONG
= READ_REGISTER_ULONG(ControlReg
);
552 if (Control
.InterruptRouting
== 0)
553 return MP_STATUS_SUCCESS
;
555 DPRINT1("OHCI_TakeControlHC: detected Legacy BIOS\n");
557 IntEnable
.AsULONG
= READ_REGISTER_ULONG(InterruptEnableReg
);
559 DPRINT("OHCI_TakeControlHC: Control - %lX, IntEnable - %lX\n",
563 if (Control
.HostControllerFunctionalState
== OHCI_HC_STATE_RESET
&&
564 IntEnable
.AsULONG
== 0)
567 WRITE_REGISTER_ULONG(ControlReg
, Control
.AsULONG
);
568 return MP_STATUS_SUCCESS
;
571 /* Enable interrupt generations */
572 IntEnable
.AsULONG
= 0;
573 IntEnable
.MasterInterruptEnable
= 1;
575 WRITE_REGISTER_ULONG(InterruptEnableReg
, IntEnable
.AsULONG
);
577 /* Request a change of control of the HC */
578 CommandStatus
.AsULONG
= 0;
579 CommandStatus
.OwnershipChangeRequest
= 1;
581 WRITE_REGISTER_ULONG(CommandStatusReg
, CommandStatus
.AsULONG
);
583 /* Disable interrupt generation due to Root Hub Status Change */
584 IntDisable
.AsULONG
= 0;
585 IntDisable
.RootHubStatusChange
= 1;
587 WRITE_REGISTER_ULONG(InterruptDisableReg
, IntDisable
.AsULONG
);
589 /* Monitoring the InterruptRouting bit
590 to determine when the ownership change has taken effect. */
592 KeQuerySystemTime(&EndTime
);
593 EndTime
.QuadPart
+= 500 * 10000; // 0.5 sec;
597 Control
.AsULONG
= READ_REGISTER_ULONG(ControlReg
);
599 if (Control
.InterruptRouting
== 0)
601 /* Clear all bits in register */
602 IntStatus
.AsULONG
= 0xFFFFFFFF;
603 WRITE_REGISTER_ULONG(InterruptStatusReg
, IntStatus
.AsULONG
);
605 /* Disable interrupt generations */
606 IntDisable
.AsULONG
= 0;
607 IntDisable
.MasterInterruptEnable
= 1;
609 WRITE_REGISTER_ULONG(InterruptDisableReg
, IntDisable
.AsULONG
);
611 return MP_STATUS_SUCCESS
;
614 KeQuerySystemTime(&SystemTime
);
616 while (SystemTime
.QuadPart
< EndTime
.QuadPart
);
618 return MP_STATUS_HW_ERROR
;
623 OHCI_StartController(IN PVOID ohciExtension
,
624 IN PUSBPORT_RESOURCES Resources
)
626 POHCI_EXTENSION OhciExtension
= ohciExtension
;
627 POHCI_OPERATIONAL_REGISTERS OperationalRegs
;
628 PULONG CommandStatusReg
;
629 PULONG FmIntervalReg
;
631 PULONG InterruptEnableReg
;
633 OHCI_REG_COMMAND_STATUS CommandStatus
;
634 OHCI_REG_INTERRUPT_ENABLE_DISABLE Interrupts
;
635 OHCI_REG_RH_STATUS RhStatus
;
636 OHCI_REG_FRAME_INTERVAL FrameInterval
;
637 ULONG MaxFrameIntervalAdjusting
;
638 OHCI_REG_CONTROL Control
;
640 POHCI_ENDPOINT_DESCRIPTOR IntED
;
643 LARGE_INTEGER SystemTime
;
644 LARGE_INTEGER EndTime
;
647 MPSTATUS MPStatus
= MP_STATUS_SUCCESS
;
649 DPRINT_OHCI("OHCI_StartController: ohciExtension - %p, Resources - %p\n",
653 /* HC on-chip operational registers */
654 OperationalRegs
= (POHCI_OPERATIONAL_REGISTERS
)Resources
->ResourceBase
;
655 OhciExtension
->OperationalRegs
= OperationalRegs
;
657 CommandStatusReg
= (PULONG
)&OperationalRegs
->HcCommandStatus
;
658 FmIntervalReg
= (PULONG
)&OperationalRegs
->HcFmInterval
;
659 ControlReg
= (PULONG
)&OperationalRegs
->HcControl
;
660 InterruptEnableReg
= (PULONG
)&OperationalRegs
->HcInterruptEnable
;
661 RhStatusReg
= (PULONG
)&OperationalRegs
->HcRhStatus
;
663 /* 5.1.1 Initialization */
665 MPStatus
= OHCI_TakeControlHC(OhciExtension
, Resources
);
667 if (MPStatus
!= MP_STATUS_SUCCESS
)
669 DPRINT1("OHCI_StartController: OHCI_TakeControlHC return MPStatus - %x\n",
675 OhciExtension
->HcResourcesVA
= Resources
->StartVA
;
676 OhciExtension
->HcResourcesPA
= Resources
->StartPA
;
678 DPRINT_OHCI("OHCI_StartController: HcResourcesVA - %p, HcResourcesPA - %p\n",
679 OhciExtension
->HcResourcesVA
,
680 OhciExtension
->HcResourcesPA
);
682 /* 5.2.7.2 Interrupt */
684 /* Build structure of interrupt static EDs */
685 for (ix
= 0; ix
< INTERRUPT_ENDPOINTs
; ix
++)
687 IntED
= &OhciExtension
->HcResourcesVA
->InterrruptHeadED
[ix
];
688 IntEdPA
= (ULONG_PTR
)&OhciExtension
->HcResourcesPA
->InterrruptHeadED
[ix
];
690 if (ix
== (ENDPOINT_INTERRUPT_1ms
- 1))
697 HeadIndex
= ((ix
- 1) / 2);
699 ASSERT(HeadIndex
>= (ENDPOINT_INTERRUPT_1ms
- 1) &&
700 HeadIndex
< (INTERRUPT_ENDPOINTs
- ENDPOINT_INTERRUPT_32ms
));
702 IntED
->NextED
= OhciExtension
->IntStaticED
[HeadIndex
].PhysicalAddress
;
705 IntED
->EndpointControl
.sKip
= 1;
707 IntED
->TailPointer
= 0;
708 IntED
->HeadPointer
= 0;
710 OhciExtension
->IntStaticED
[ix
].HwED
= IntED
;
711 OhciExtension
->IntStaticED
[ix
].PhysicalAddress
= IntEdPA
;
712 OhciExtension
->IntStaticED
[ix
].HeadIndex
= HeadIndex
;
713 OhciExtension
->IntStaticED
[ix
].pNextED
= &IntED
->NextED
;
714 OhciExtension
->IntStaticED
[ix
].Type
= OHCI_STATIC_ED_TYPE_INTERRUPT
;
716 InitializeListHead(&OhciExtension
->IntStaticED
[ix
].Link
);
719 OhciHCCA
= &OhciExtension
->HcResourcesVA
->HcHCCA
;
720 DPRINT_OHCI("OHCI_InitializeSchedule: OhciHCCA - %p\n", OhciHCCA
);
722 /* Set head pointers which start from HCCA */
723 for (ix
= 0, jx
= (INTERRUPT_ENDPOINTs
- ENDPOINT_INTERRUPT_32ms
);
724 ix
< OHCI_NUMBER_OF_INTERRUPTS
;
727 OhciHCCA
->InterrruptTable
[Balance
[ix
]] =
728 OhciExtension
->IntStaticED
[jx
].PhysicalAddress
;
730 OhciExtension
->IntStaticED
[jx
].pNextED
=
731 (PULONG
)&OhciHCCA
->InterrruptTable
[Balance
[ix
]];
733 OhciExtension
->IntStaticED
[jx
].HccaIndex
= Balance
[ix
];
736 DPRINT_OHCI("OHCI_InitializeSchedule: ix - %x\n", ix
);
738 /* Init static Control and Bulk EDs head pointers which start from HCCA */
739 InitializeListHead(&OhciExtension
->ControlStaticED
.Link
);
741 OhciExtension
->ControlStaticED
.HeadIndex
= ED_EOF
;
742 OhciExtension
->ControlStaticED
.Type
= OHCI_STATIC_ED_TYPE_CONTROL
;
743 OhciExtension
->ControlStaticED
.pNextED
= &OperationalRegs
->HcControlHeadED
;
745 InitializeListHead(&OhciExtension
->BulkStaticED
.Link
);
747 OhciExtension
->BulkStaticED
.HeadIndex
= ED_EOF
;
748 OhciExtension
->BulkStaticED
.Type
= OHCI_STATIC_ED_TYPE_BULK
;
749 OhciExtension
->BulkStaticED
.pNextED
= &OperationalRegs
->HcBulkHeadED
;
751 /* 6.3.1 Frame Timing */
752 FrameInterval
.AsULONG
= READ_REGISTER_ULONG(FmIntervalReg
);
754 MaxFrameIntervalAdjusting
= OHCI_DEFAULT_FRAME_INTERVAL
/ 10; // 10%
756 if ((FrameInterval
.FrameInterval
) < (OHCI_DEFAULT_FRAME_INTERVAL
- MaxFrameIntervalAdjusting
) ||
757 (FrameInterval
.FrameInterval
) > (OHCI_DEFAULT_FRAME_INTERVAL
+ MaxFrameIntervalAdjusting
))
759 FrameInterval
.FrameInterval
= OHCI_DEFAULT_FRAME_INTERVAL
;
762 /* 5.4 FrameInterval Counter */
763 FrameInterval
.FrameIntervalToggle
= 1;
765 /* OHCI_MAXIMUM_OVERHEAD is the maximum overhead per frame */
766 FrameInterval
.FSLargestDataPacket
=
767 ((FrameInterval
.FrameInterval
- OHCI_MAXIMUM_OVERHEAD
) * 6) / 7;
769 OhciExtension
->FrameInterval
= FrameInterval
;
771 DPRINT_OHCI("OHCI_StartController: FrameInterval - %lX\n",
772 FrameInterval
.AsULONG
);
774 /* Reset HostController */
775 CommandStatus
.AsULONG
= 0;
776 CommandStatus
.HostControllerReset
= 1;
778 WRITE_REGISTER_ULONG(CommandStatusReg
, CommandStatus
.AsULONG
);
780 KeStallExecutionProcessor(25);
782 Control
.AsULONG
= READ_REGISTER_ULONG(ControlReg
);
783 Control
.HostControllerFunctionalState
= OHCI_HC_STATE_RESET
;
785 WRITE_REGISTER_ULONG(ControlReg
, Control
.AsULONG
);
787 KeQuerySystemTime(&EndTime
);
788 EndTime
.QuadPart
+= 500 * 10000; // 0.5 sec
792 WRITE_REGISTER_ULONG(FmIntervalReg
, OhciExtension
->FrameInterval
.AsULONG
);
793 FrameInterval
.AsULONG
= READ_REGISTER_ULONG(FmIntervalReg
);
795 KeQuerySystemTime(&SystemTime
);
797 if (SystemTime
.QuadPart
>= EndTime
.QuadPart
)
799 MPStatus
= MP_STATUS_HW_ERROR
;
803 if (FrameInterval
.AsULONG
== OhciExtension
->FrameInterval
.AsULONG
)
805 MPStatus
= MP_STATUS_SUCCESS
;
810 if (MPStatus
!= MP_STATUS_SUCCESS
)
812 DPRINT_OHCI("OHCI_StartController: frame interval not set\n");
816 /* Setup HcPeriodicStart register */
817 WRITE_REGISTER_ULONG(&OperationalRegs
->HcPeriodicStart
,
818 (OhciExtension
->FrameInterval
.FrameInterval
* 9) / 10); //90%
820 /* Setup HcHCCA register */
821 WRITE_REGISTER_ULONG(&OperationalRegs
->HcHCCA
,
822 (ULONG
)&OhciExtension
->HcResourcesPA
->HcHCCA
);
824 /* Setup HcInterruptEnable register */
825 Interrupts
.AsULONG
= 0;
827 Interrupts
.SchedulingOverrun
= 1;
828 Interrupts
.WritebackDoneHead
= 1;
829 Interrupts
.UnrecoverableError
= 1;
830 Interrupts
.FrameNumberOverflow
= 1;
831 Interrupts
.OwnershipChange
= 1;
833 WRITE_REGISTER_ULONG(InterruptEnableReg
, Interrupts
.AsULONG
);
835 /* Setup HcControl register */
836 Control
.AsULONG
= READ_REGISTER_ULONG(ControlReg
);
838 Control
.ControlBulkServiceRatio
= 0; // FIXME (1 : 1)
839 Control
.PeriodicListEnable
= 1;
840 Control
.IsochronousEnable
= 1;
841 Control
.ControlListEnable
= 1;
842 Control
.BulkListEnable
= 1;
843 Control
.HostControllerFunctionalState
= OHCI_HC_STATE_OPERATIONAL
;
845 WRITE_REGISTER_ULONG(ControlReg
, Control
.AsULONG
);
847 /* Setup HcRhStatus register */
848 RhStatus
.AsULONG
= 0;
849 RhStatus
.SetGlobalPower
= 1;
851 WRITE_REGISTER_ULONG(RhStatusReg
, RhStatus
.AsULONG
);
853 return MP_STATUS_SUCCESS
;
858 OHCI_StopController(IN PVOID ohciExtension
,
859 IN BOOLEAN IsDoDisableInterrupts
)
861 POHCI_EXTENSION OhciExtension
= ohciExtension
;
862 POHCI_OPERATIONAL_REGISTERS OperationalRegs
;
864 PULONG InterruptDisableReg
;
865 PULONG InterruptStatusReg
;
866 OHCI_REG_CONTROL Control
;
867 OHCI_REG_INTERRUPT_ENABLE_DISABLE IntDisable
;
868 OHCI_REG_INTERRUPT_STATUS IntStatus
;
870 DPRINT("OHCI_StopController: ... \n");
872 OperationalRegs
= OhciExtension
->OperationalRegs
;
874 ControlReg
= (PULONG
)&OperationalRegs
->HcControl
;
875 InterruptDisableReg
= (PULONG
)&OperationalRegs
->HcInterruptDisable
;
876 InterruptStatusReg
= (PULONG
)&OperationalRegs
->HcInterruptStatus
;
878 /* Setup HcControl register */
879 Control
.AsULONG
= READ_REGISTER_ULONG(ControlReg
);
881 Control
.PeriodicListEnable
= 0;
882 Control
.IsochronousEnable
= 0;
883 Control
.ControlListEnable
= 0;
884 Control
.BulkListEnable
= 0;
885 Control
.HostControllerFunctionalState
= OHCI_HC_STATE_SUSPEND
;
886 Control
.RemoteWakeupEnable
= 0;
888 WRITE_REGISTER_ULONG(ControlReg
, Control
.AsULONG
);
890 /* Disable interrupt generations */
891 IntDisable
.AsULONG
= 0xFFFFFFFF;
892 WRITE_REGISTER_ULONG(InterruptDisableReg
, IntDisable
.AsULONG
);
894 /* Clear all bits in HcInterruptStatus register */
895 IntStatus
.AsULONG
= 0xFFFFFFFF;
896 WRITE_REGISTER_ULONG(InterruptStatusReg
, IntStatus
.AsULONG
);
901 OHCI_SuspendController(IN PVOID ohciExtension
)
903 POHCI_EXTENSION OhciExtension
= ohciExtension
;
904 POHCI_OPERATIONAL_REGISTERS OperationalRegs
;
906 PULONG InterruptEnableReg
;
907 OHCI_REG_CONTROL Control
;
908 OHCI_REG_INTERRUPT_ENABLE_DISABLE InterruptReg
;
910 DPRINT("OHCI_SuspendController: ... \n");
912 OperationalRegs
= OhciExtension
->OperationalRegs
;
913 ControlReg
= (PULONG
)&OperationalRegs
->HcControl
;
914 InterruptEnableReg
= (PULONG
)&OperationalRegs
->HcInterruptEnable
;
916 /* Disable all interrupt generations */
917 WRITE_REGISTER_ULONG(&OperationalRegs
->HcInterruptDisable
.AsULONG
,
920 /* Clear all bits in HcInterruptStatus register */
921 WRITE_REGISTER_ULONG(&OperationalRegs
->HcInterruptStatus
.AsULONG
,
924 /* Setup HcControl register */
925 Control
.AsULONG
= READ_REGISTER_ULONG(ControlReg
);
926 Control
.HostControllerFunctionalState
= OHCI_HC_STATE_SUSPEND
;
927 Control
.RemoteWakeupEnable
= 1;
929 WRITE_REGISTER_ULONG(ControlReg
, Control
.AsULONG
);
931 /* Setup HcInterruptEnable register */
932 InterruptReg
.AsULONG
= 0;
933 InterruptReg
.ResumeDetected
= 1;
934 InterruptReg
.UnrecoverableError
= 1;
935 InterruptReg
.RootHubStatusChange
= 1;
936 InterruptReg
.MasterInterruptEnable
= 1;
938 WRITE_REGISTER_ULONG(InterruptEnableReg
, InterruptReg
.AsULONG
);
943 OHCI_ResumeController(IN PVOID ohciExtension
)
945 POHCI_EXTENSION OhciExtension
= ohciExtension
;
946 POHCI_OPERATIONAL_REGISTERS OperationalRegs
;
948 PULONG InterruptEnableReg
;
950 OHCI_REG_CONTROL control
;
951 OHCI_REG_INTERRUPT_ENABLE_DISABLE InterruptReg
;
953 DPRINT("OHCI_ResumeController \n");
955 OperationalRegs
= OhciExtension
->OperationalRegs
;
956 ControlReg
= (PULONG
)&OperationalRegs
->HcControl
;
957 InterruptEnableReg
= (PULONG
)&OperationalRegs
->HcInterruptEnable
;
959 control
.AsULONG
= READ_REGISTER_ULONG(ControlReg
);
961 if (control
.HostControllerFunctionalState
!= OHCI_HC_STATE_SUSPEND
)
962 return MP_STATUS_HW_ERROR
;
964 HcHCCA
= &OhciExtension
->HcResourcesVA
->HcHCCA
;
967 /* Setup HcControl register */
968 control
.HostControllerFunctionalState
= OHCI_HC_STATE_OPERATIONAL
;
969 WRITE_REGISTER_ULONG(ControlReg
, control
.AsULONG
);
971 /* Setup HcInterruptEnable register */
972 InterruptReg
.AsULONG
= 0;
973 InterruptReg
.SchedulingOverrun
= 1;
974 InterruptReg
.WritebackDoneHead
= 1;
975 InterruptReg
.UnrecoverableError
= 1;
976 InterruptReg
.FrameNumberOverflow
= 1;
977 InterruptReg
.OwnershipChange
= 1;
979 WRITE_REGISTER_ULONG(InterruptEnableReg
, InterruptReg
.AsULONG
);
980 WRITE_REGISTER_ULONG(ControlReg
, control
.AsULONG
);
982 return MP_STATUS_SUCCESS
;
987 OHCI_HardwarePresent(IN POHCI_EXTENSION OhciExtension
,
988 IN BOOLEAN IsInvalidateController
)
990 POHCI_OPERATIONAL_REGISTERS OperationalRegs
;
991 PULONG CommandStatusReg
;
993 OperationalRegs
= OhciExtension
->OperationalRegs
;
994 CommandStatusReg
= (PULONG
)&OperationalRegs
->HcCommandStatus
;
996 if (READ_REGISTER_ULONG(CommandStatusReg
) != 0xFFFFFFFF)
999 DPRINT1("OHCI_HardwarePresent: IsInvalidateController - %x\n",
1000 IsInvalidateController
);
1002 if (IsInvalidateController
)
1004 RegPacket
.UsbPortInvalidateController(OhciExtension
,
1005 USBPORT_INVALIDATE_CONTROLLER_SURPRISE_REMOVE
);
1013 OHCI_InterruptService(IN PVOID ohciExtension
)
1015 POHCI_EXTENSION OhciExtension
= ohciExtension
;
1016 POHCI_OPERATIONAL_REGISTERS OperationalRegs
;
1017 OHCI_REG_INTERRUPT_STATUS IntStatus
;
1018 OHCI_REG_INTERRUPT_ENABLE_DISABLE IntEnable
;
1019 OHCI_REG_INTERRUPT_ENABLE_DISABLE IntDisable
;
1020 BOOLEAN HardwarePresent
= FALSE
;
1022 DPRINT_OHCI("OHCI_Interrupt: Ext %p\n", OhciExtension
);
1024 OperationalRegs
= OhciExtension
->OperationalRegs
;
1026 HardwarePresent
= OHCI_HardwarePresent(OhciExtension
, FALSE
);
1028 if (!HardwarePresent
)
1031 IntEnable
.AsULONG
= READ_REGISTER_ULONG((PULONG
)&OperationalRegs
->HcInterruptEnable
);
1032 IntStatus
.AsULONG
= READ_REGISTER_ULONG((PULONG
)&OperationalRegs
->HcInterruptStatus
) & IntEnable
.AsULONG
;
1034 if ((IntStatus
.AsULONG
== 0) || (IntEnable
.MasterInterruptEnable
== 0))
1037 if (IntStatus
.UnrecoverableError
)
1038 DPRINT1("OHCI_InterruptService: IntStatus.UnrecoverableError\n");
1040 if (IntStatus
.FrameNumberOverflow
)
1046 HcHCCA
= &OhciExtension
->HcResourcesVA
->HcHCCA
;
1048 DPRINT("FrameNumberOverflow %lX\n", HcHCCA
->FrameNumber
);
1050 hp
= OhciExtension
->FrameHighPart
;
1051 fm
= HcHCCA
->FrameNumber
;
1053 /* Increment value of FrameHighPart */
1054 OhciExtension
->FrameHighPart
+= 1 * (1 << 16) - ((hp
^ fm
) & 0x8000);
1057 /* Disable interrupt generation */
1058 IntDisable
.AsULONG
= 0;
1059 IntDisable
.MasterInterruptEnable
= 1;
1060 WRITE_REGISTER_ULONG((PULONG
)&OperationalRegs
->HcInterruptDisable
,
1061 IntDisable
.AsULONG
);
1068 OHCI_InterruptDpc(IN PVOID ohciExtension
,
1069 IN BOOLEAN IsDoEnableInterrupts
)
1071 POHCI_EXTENSION OhciExtension
= ohciExtension
;
1072 POHCI_OPERATIONAL_REGISTERS OperationalRegs
;
1073 PULONG InterruptDisableReg
;
1074 PULONG InterruptEnableReg
;
1075 PULONG InterruptStatusReg
;
1076 OHCI_REG_INTERRUPT_STATUS IntStatus
;
1077 OHCI_REG_INTERRUPT_ENABLE_DISABLE InterruptBits
;
1080 OperationalRegs
= OhciExtension
->OperationalRegs
;
1082 InterruptEnableReg
= (PULONG
)&OperationalRegs
->HcInterruptEnable
;
1083 InterruptDisableReg
= (PULONG
)&OperationalRegs
->HcInterruptDisable
;
1084 InterruptStatusReg
= (PULONG
)&OperationalRegs
->HcInterruptStatus
;
1086 DPRINT_OHCI("OHCI_InterruptDpc: OhciExtension - %p, IsDoEnableInterrupts - %x\n",
1088 IsDoEnableInterrupts
);
1090 IntStatus
.AsULONG
= READ_REGISTER_ULONG(InterruptStatusReg
);
1092 if (IntStatus
.RootHubStatusChange
)
1094 DPRINT_OHCI("OHCI_InterruptDpc: RootHubStatusChange\n");
1095 RegPacket
.UsbPortInvalidateRootHub(OhciExtension
);
1098 if (IntStatus
.WritebackDoneHead
)
1100 DPRINT_OHCI("OHCI_InterruptDpc: WritebackDoneHead\n");
1102 HcHCCA
= &OhciExtension
->HcResourcesVA
->HcHCCA
;
1103 HcHCCA
->DoneHead
= 0;
1105 RegPacket
.UsbPortInvalidateEndpoint(OhciExtension
, NULL
);
1108 if (IntStatus
.StartofFrame
)
1110 /* Disable interrupt generation due to Start of Frame */
1111 InterruptBits
.AsULONG
= 0;
1112 InterruptBits
.StartofFrame
= 1;
1114 WRITE_REGISTER_ULONG(InterruptDisableReg
, InterruptBits
.AsULONG
);
1117 if (IntStatus
.ResumeDetected
)
1118 DPRINT1("OHCI_IntDpc: ResumeDetected\n");
1120 if (IntStatus
.UnrecoverableError
)
1122 DPRINT1("OHCI_IntDpc: UnrecoverableError\n");
1125 WRITE_REGISTER_ULONG(InterruptStatusReg
, IntStatus
.AsULONG
);
1127 if (IsDoEnableInterrupts
)
1129 /* Enable interrupt generation */
1130 InterruptBits
.AsULONG
= 0;
1131 InterruptBits
.MasterInterruptEnable
= 1;
1133 WRITE_REGISTER_ULONG(InterruptEnableReg
, InterruptBits
.AsULONG
);
1139 OHCI_MapTransferToTD(IN POHCI_EXTENSION OhciExtension
,
1140 IN ULONG MaxPacketSize
,
1141 IN OUT ULONG TransferedLen
,
1142 IN POHCI_TRANSFER OhciTransfer
,
1144 IN PUSBPORT_SCATTER_GATHER_LIST SGList
)
1146 PUSBPORT_SCATTER_GATHER_ELEMENT SgElement
;
1152 ULONG TransferLength
;
1155 DPRINT_OHCI("OHCI_MapTransferToTD: TransferedLen - %x\n", TransferedLen
);
1157 for (SgIdx
= 0; SgIdx
< SGList
->SgElementCount
; SgIdx
++)
1159 SgElement
= &SGList
->SgElement
[SgIdx
];
1161 if (TransferedLen
>= SgElement
->SgOffset
&&
1162 TransferedLen
< SgElement
->SgOffset
+ SgElement
->SgTransferLength
)
1168 DPRINT_OHCI("OHCI_MapTransferToTD: SgIdx - %x, SgCount - %x\n",
1170 SGList
->SgElementCount
);
1172 ASSERT(SgIdx
< SGList
->SgElementCount
);
1174 Offset
= TransferedLen
- SGList
->SgElement
[SgIdx
].SgOffset
;
1175 Buffer
= SGList
->SgElement
[SgIdx
].SgPhysicalAddress
.LowPart
+ Offset
;
1177 SgRemain
= SGList
->SgElementCount
- SgIdx
;
1181 LengthThisTd
= OhciTransfer
->TransferParameters
->TransferBufferLength
-
1185 BufferEnd
= SGList
->SgElement
[SgIdx
].SgPhysicalAddress
.LowPart
+
1188 else if (SgRemain
== 2)
1190 LengthThisTd
= OhciTransfer
->TransferParameters
->TransferBufferLength
-
1193 BufferEnd
= SGList
->SgElement
[SgIdx
+ 1].SgPhysicalAddress
.LowPart
+
1194 SGList
->SgElement
[SgIdx
+ 1].SgTransferLength
;
1198 TransferLength
= SGList
->SgElement
[SgIdx
].SgTransferLength
+
1199 SGList
->SgElement
[SgIdx
+1].SgTransferLength
-
1202 BufferEnd
= SGList
->SgElement
[SgIdx
+ 1].SgPhysicalAddress
.LowPart
+
1203 SGList
->SgElement
[SgIdx
+ 1].SgTransferLength
;
1205 LengthThisTd
= MaxPacketSize
* (TransferLength
/ MaxPacketSize
);
1207 if (TransferLength
> LengthThisTd
)
1208 BufferEnd
-= (TransferLength
- LengthThisTd
);
1211 TD
->HwTD
.gTD
.CurrentBuffer
= Buffer
;
1212 TD
->HwTD
.gTD
.BufferEnd
= BufferEnd
- 1;
1213 TD
->TransferLen
= LengthThisTd
;
1215 return TransferedLen
+ LengthThisTd
;
1220 OHCI_AllocateTD(IN POHCI_EXTENSION OhciExtension
,
1221 IN POHCI_ENDPOINT OhciEndpoint
)
1225 DPRINT_OHCI("OHCI_AllocateTD: ... \n");
1227 TD
= OhciEndpoint
->FirstTD
;
1229 while (TD
->Flags
& OHCI_HCD_TD_FLAG_ALLOCATED
)
1234 TD
->Flags
|= OHCI_HCD_TD_FLAG_ALLOCATED
;
1241 OHCI_RemainTDs(IN POHCI_EXTENSION OhciExtension
,
1242 IN POHCI_ENDPOINT OhciEndpoint
)
1249 DPRINT_OHCI("OHCI_RemainTDs: ... \n");
1251 MaxTDs
= OhciEndpoint
->MaxTransferDescriptors
;
1252 TD
= (POHCI_HCD_TD
)OhciEndpoint
->FirstTD
;
1256 for (ix
= 0; ix
< MaxTDs
; ix
++)
1258 if (!(TD
->Flags
& OHCI_HCD_TD_FLAG_ALLOCATED
))
1269 OHCI_ControlTransfer(IN POHCI_EXTENSION OhciExtension
,
1270 IN POHCI_ENDPOINT OhciEndpoint
,
1271 IN PUSBPORT_TRANSFER_PARAMETERS TransferParameters
,
1272 IN POHCI_TRANSFER OhciTransfer
,
1273 IN PUSBPORT_SCATTER_GATHER_LIST SGList
)
1275 POHCI_HCD_TD FirstTD
;
1276 POHCI_HCD_TD FirstTdPA
;
1279 POHCI_HCD_TD PrevTD
;
1280 POHCI_HCD_TD NextTD
;
1282 ULONG TransferedLen
;
1283 ULONG MaxPacketSize
;
1287 DPRINT_OHCI("OHCI_ControlTransfer: Ext %p, Endpoint %p\n",
1291 MaxTDs
= OHCI_RemainTDs(OhciExtension
, OhciEndpoint
);
1293 if ((SGList
->SgElementCount
+ OHCI_NON_DATA_CONTROL_TDS
) > MaxTDs
)
1294 return MP_STATUS_FAILURE
;
1296 FirstTD
= OhciEndpoint
->HcdTailP
;
1297 FirstTD
->HwTD
.gTD
.Control
.DelayInterrupt
= OHCI_TD_INTERRUPT_NONE
;
1299 FirstTD
->HwTD
.gTD
.NextTD
= 0;
1300 FirstTD
->HwTD
.gTD
.CurrentBuffer
= 0;
1301 FirstTD
->HwTD
.gTD
.BufferEnd
= 0;
1303 FirstTD
->Flags
|= OHCI_HCD_TD_FLAG_PROCESSED
;
1304 FirstTD
->NextHcdTD
= 0;
1305 FirstTD
->OhciTransfer
= (ULONG
)OhciTransfer
;
1307 FirstTD
->HwTD
.Padded
[0] = 0;
1308 FirstTD
->HwTD
.Padded
[1] = 0;
1310 OhciTransfer
->PendingTDs
++;
1312 RtlCopyMemory(&FirstTD
->HwTD
.SetupPacket
,
1313 &TransferParameters
->SetupPacket
,
1314 sizeof(FirstTD
->HwTD
.SetupPacket
));
1316 FirstTdPA
= (POHCI_HCD_TD
)FirstTD
->PhysicalAddress
;
1318 FirstTD
->HwTD
.gTD
.CurrentBuffer
= (ULONG
)&FirstTdPA
->HwTD
.SetupPacket
;
1320 BufferEnd
= (ULONG_PTR
)&FirstTdPA
->HwTD
.SetupPacket
+
1321 sizeof(USB_DEFAULT_PIPE_SETUP_PACKET
) - 1;
1323 FirstTD
->HwTD
.gTD
.BufferEnd
= BufferEnd
;
1325 FirstTD
->HwTD
.gTD
.Control
.AsULONG
= 0;
1326 FirstTD
->HwTD
.gTD
.Control
.DelayInterrupt
= OHCI_TD_INTERRUPT_NONE
;
1327 FirstTD
->HwTD
.gTD
.Control
.ConditionCode
= OHCI_TD_CONDITION_NOT_ACCESSED
;
1328 FirstTD
->HwTD
.gTD
.Control
.DataToggle
= OHCI_TD_DATA_TOGGLE_DATA0
;
1330 TD2
= OHCI_AllocateTD(OhciExtension
, OhciEndpoint
);
1332 TD2
->HwTD
.gTD
.Control
.DelayInterrupt
= OHCI_TD_INTERRUPT_NONE
;
1333 TD2
->HwTD
.gTD
.CurrentBuffer
= 0;
1334 TD2
->HwTD
.gTD
.BufferEnd
= 0;
1335 TD2
->HwTD
.gTD
.NextTD
= 0;
1337 TD2
->Flags
|= OHCI_HCD_TD_FLAG_PROCESSED
;
1339 TD2
->OhciTransfer
= (ULONG
)OhciTransfer
;
1341 RtlZeroMemory(&TD2
->HwTD
.SetupPacket
,
1342 sizeof(TD2
->HwTD
.SetupPacket
));
1344 TD2
->HwTD
.Padded
[0] = 0;
1345 TD2
->HwTD
.Padded
[1] = 0;
1350 PrevTD
->HwTD
.gTD
.NextTD
= TD2
->PhysicalAddress
;
1351 PrevTD
->NextHcdTD
= (ULONG
)TD2
;
1353 MaxPacketSize
= OhciEndpoint
->EndpointProperties
.TotalMaxPacketSize
;
1356 DataToggle
= OHCI_TD_DATA_TOGGLE_DATA1
;
1358 while (TransferedLen
< TransferParameters
->TransferBufferLength
)
1360 OhciTransfer
->PendingTDs
++;
1362 if (TransferParameters
->TransferFlags
& USBD_TRANSFER_DIRECTION_IN
)
1363 TD
->HwTD
.gTD
.Control
.DirectionPID
= OHCI_TD_DIRECTION_PID_IN
;
1365 TD
->HwTD
.gTD
.Control
.DirectionPID
= OHCI_TD_DIRECTION_PID_OUT
;
1367 TD
->HwTD
.gTD
.Control
.DelayInterrupt
= OHCI_TD_INTERRUPT_NONE
;
1368 TD
->HwTD
.gTD
.Control
.DataToggle
= DataToggle
;
1369 TD
->HwTD
.gTD
.Control
.ConditionCode
= OHCI_TD_CONDITION_NOT_ACCESSED
;
1371 DataToggle
= OHCI_TD_DATA_TOGGLE_FROM_ED
;
1373 TransferedLen
= OHCI_MapTransferToTD(OhciExtension
,
1382 TD
= OHCI_AllocateTD(OhciExtension
, OhciEndpoint
);
1384 TD
->Flags
|= OHCI_HCD_TD_FLAG_PROCESSED
;
1386 TD
->HwTD
.gTD
.NextTD
= 0;
1387 TD
->HwTD
.gTD
.Control
.DelayInterrupt
= OHCI_TD_INTERRUPT_NONE
;
1390 TD
->OhciTransfer
= (ULONG
)OhciTransfer
;
1392 TD
->HwTD
.gTD
.CurrentBuffer
= 0;
1393 TD
->HwTD
.gTD
.BufferEnd
= 0;
1395 RtlZeroMemory(&TD
->HwTD
.SetupPacket
,
1396 sizeof(TD
->HwTD
.SetupPacket
));
1398 TD
->HwTD
.Padded
[0] = 0;
1399 TD
->HwTD
.Padded
[1] = 0;
1401 PrevTD
->HwTD
.gTD
.NextTD
= TD
->PhysicalAddress
;
1402 PrevTD
->NextHcdTD
= (ULONG
)TD
;
1405 if (TransferParameters
->TransferFlags
& USBD_SHORT_TRANSFER_OK
)
1407 PrevTD
->HwTD
.gTD
.Control
.BufferRounding
= TRUE
;
1408 OhciTransfer
->Flags
|= OHCI_TRANSFER_FLAGS_SHORT_TRANSFER_OK
;
1411 TD
->HwTD
.gTD
.CurrentBuffer
= 0;
1412 TD
->HwTD
.gTD
.BufferEnd
= 0;
1414 TD
->Flags
|= OHCI_HCD_TD_FLAG_CONTROL_STATUS
;
1415 TD
->TransferLen
= 0;
1417 TD
->HwTD
.gTD
.Control
.AsULONG
= 0;
1419 if ((TransferParameters
->TransferFlags
& USBD_TRANSFER_DIRECTION_IN
) != 0)
1421 TD
->HwTD
.gTD
.Control
.DirectionPID
= OHCI_TD_DIRECTION_PID_OUT
;
1425 TD
->HwTD
.gTD
.Control
.BufferRounding
= TRUE
;
1426 TD
->HwTD
.gTD
.Control
.DirectionPID
= OHCI_TD_DIRECTION_PID_IN
;
1429 TD
->HwTD
.gTD
.Control
.DataToggle
= OHCI_TD_DATA_TOGGLE_DATA1
;
1430 TD
->HwTD
.gTD
.Control
.ConditionCode
= OHCI_TD_CONDITION_NOT_ACCESSED
;
1432 OhciTransfer
->PendingTDs
++;
1433 OhciTransfer
->ControlStatusTD
= TD
;
1435 NextTD
= OHCI_AllocateTD(OhciExtension
, OhciEndpoint
);
1437 TD
->HwTD
.gTD
.NextTD
= NextTD
->PhysicalAddress
;
1438 TD
->NextHcdTD
= (ULONG
)NextTD
;
1440 NextTD
->NextHcdTD
= 0;
1441 NextTD
->HwTD
.gTD
.NextTD
= 0;
1443 OhciTransfer
->NextTD
= NextTD
;
1444 OhciEndpoint
->HcdTailP
= NextTD
;
1446 OhciEndpoint
->HcdED
->HwED
.TailPointer
= NextTD
->PhysicalAddress
;
1448 OHCI_EnableList(OhciExtension
, OhciEndpoint
);
1450 return MP_STATUS_SUCCESS
;
1455 OHCI_BulkOrInterruptTransfer(IN POHCI_EXTENSION OhciExtension
,
1456 IN POHCI_ENDPOINT OhciEndpoint
,
1457 IN PUSBPORT_TRANSFER_PARAMETERS TransferParameters
,
1458 IN POHCI_TRANSFER OhciTransfer
,
1459 IN PUSBPORT_SCATTER_GATHER_LIST SGList
)
1462 POHCI_HCD_TD PrevTD
;
1463 ULONG TransferedLen
;
1465 ULONG MaxPacketSize
;
1467 DPRINT_OHCI("OHCI_BulkOrInterruptTransfer: ... \n");
1469 MaxTDs
= OHCI_RemainTDs(OhciExtension
, OhciEndpoint
);
1471 if (SGList
->SgElementCount
> MaxTDs
)
1472 return MP_STATUS_FAILURE
;
1474 TD
= OhciEndpoint
->HcdTailP
;
1480 TD
->HwTD
.gTD
.Control
.AsULONG
= 0;
1481 TD
->HwTD
.gTD
.Control
.DelayInterrupt
= OHCI_TD_INTERRUPT_NONE
;
1482 TD
->HwTD
.gTD
.Control
.ConditionCode
= OHCI_TD_CONDITION_NOT_ACCESSED
;
1484 if (TransferParameters
->TransferFlags
& USBD_TRANSFER_DIRECTION_IN
)
1486 TD
->HwTD
.gTD
.Control
.BufferRounding
= 0;
1487 TD
->HwTD
.gTD
.Control
.DirectionPID
= OHCI_TD_DIRECTION_PID_IN
;
1491 TD
->HwTD
.gTD
.Control
.BufferRounding
= TRUE
;
1492 TD
->HwTD
.gTD
.Control
.DirectionPID
= OHCI_TD_DIRECTION_PID_OUT
;
1495 TD
->HwTD
.gTD
.CurrentBuffer
= 0;
1496 TD
->HwTD
.gTD
.NextTD
= 0;
1497 TD
->HwTD
.gTD
.BufferEnd
= 0;
1499 RtlZeroMemory(&TD
->HwTD
.SetupPacket
,
1500 sizeof(TD
->HwTD
.SetupPacket
));
1502 TD
->HwTD
.Padded
[0] = 0;
1503 TD
->HwTD
.Padded
[1] = 0;
1505 TD
->Flags
|= OHCI_HCD_TD_FLAG_PROCESSED
;
1506 TD
->OhciTransfer
= (ULONG
)OhciTransfer
;
1509 if (TransferParameters
->TransferBufferLength
)
1511 MaxPacketSize
= OhciEndpoint
->EndpointProperties
.TotalMaxPacketSize
;
1513 TransferedLen
= OHCI_MapTransferToTD(OhciExtension
,
1522 ASSERT(SGList
->SgElementCount
== 0);
1524 TD
->HwTD
.gTD
.CurrentBuffer
= 0;
1525 TD
->HwTD
.gTD
.BufferEnd
= 0;
1527 TD
->TransferLen
= 0;
1532 TD
= OHCI_AllocateTD(OhciExtension
, OhciEndpoint
);
1533 OhciTransfer
->PendingTDs
++;
1535 PrevTD
->HwTD
.gTD
.NextTD
= TD
->PhysicalAddress
;
1536 PrevTD
->NextHcdTD
= (ULONG
)TD
;
1538 while (TransferedLen
< TransferParameters
->TransferBufferLength
);
1540 if (TransferParameters
->TransferFlags
& USBD_SHORT_TRANSFER_OK
)
1542 PrevTD
->HwTD
.gTD
.Control
.BufferRounding
= TRUE
;
1543 OhciTransfer
->Flags
|= OHCI_TRANSFER_FLAGS_SHORT_TRANSFER_OK
;
1546 PrevTD
->HwTD
.gTD
.Control
.DelayInterrupt
= OHCI_TD_INTERRUPT_IMMEDIATE
;
1547 PrevTD
->HwTD
.gTD
.NextTD
= TD
->PhysicalAddress
;
1548 PrevTD
->NextHcdTD
= (ULONG
)TD
;
1550 TD
->HwTD
.gTD
.NextTD
= 0;
1553 OhciTransfer
->NextTD
= TD
;
1554 OhciEndpoint
->HcdTailP
= TD
;
1556 OhciEndpoint
->HcdED
->HwED
.TailPointer
= TD
->PhysicalAddress
;
1558 OHCI_EnableList(OhciExtension
, OhciEndpoint
);
1560 return MP_STATUS_SUCCESS
;
1565 OHCI_SubmitTransfer(IN PVOID ohciExtension
,
1566 IN PVOID ohciEndpoint
,
1567 IN PUSBPORT_TRANSFER_PARAMETERS TransferParameters
,
1568 IN PVOID ohciTransfer
,
1569 IN PUSBPORT_SCATTER_GATHER_LIST SGList
)
1571 POHCI_EXTENSION OhciExtension
= ohciExtension
;
1572 POHCI_ENDPOINT OhciEndpoint
= ohciEndpoint
;
1573 POHCI_TRANSFER OhciTransfer
= ohciTransfer
;
1576 DPRINT_OHCI("OHCI_SubmitTransfer: ... \n");
1578 RtlZeroMemory(OhciTransfer
, sizeof(OHCI_TRANSFER
));
1580 OhciTransfer
->TransferParameters
= TransferParameters
;
1581 OhciTransfer
->OhciEndpoint
= OhciEndpoint
;
1583 TransferType
= OhciEndpoint
->EndpointProperties
.TransferType
;
1585 if (TransferType
== USBPORT_TRANSFER_TYPE_CONTROL
)
1587 return OHCI_ControlTransfer(OhciExtension
,
1594 if (TransferType
== USBPORT_TRANSFER_TYPE_BULK
||
1595 TransferType
== USBPORT_TRANSFER_TYPE_INTERRUPT
)
1597 return OHCI_BulkOrInterruptTransfer(OhciExtension
,
1604 return MP_STATUS_FAILURE
;
1609 OHCI_SubmitIsoTransfer(IN PVOID ohciExtension
,
1610 IN PVOID ohciEndpoint
,
1611 IN PUSBPORT_TRANSFER_PARAMETERS TransferParameters
,
1612 IN PVOID ohciTransfer
,
1613 IN PVOID isoParameters
)
1615 DPRINT1("OHCI_SubmitIsoTransfer: UNIMPLEMENTED. FIXME\n");
1616 return MP_STATUS_SUCCESS
;
1621 OHCI_ProcessDoneTD(IN POHCI_EXTENSION OhciExtension
,
1623 IN BOOLEAN IsPortComplete
)
1625 POHCI_TRANSFER OhciTransfer
;
1626 POHCI_ENDPOINT OhciEndpoint
;
1631 DPRINT_OHCI("OHCI_ProcessDoneTD: ... \n");
1633 OhciTransfer
= (POHCI_TRANSFER
)TD
->OhciTransfer
;
1634 OhciEndpoint
= OhciTransfer
->OhciEndpoint
;
1636 OhciTransfer
->PendingTDs
--;
1638 Buffer
= TD
->HwTD
.gTD
.CurrentBuffer
;
1639 BufferEnd
= TD
->HwTD
.gTD
.BufferEnd
;
1641 if (TD
->Flags
& OHCI_HCD_TD_FLAG_NOT_ACCESSED
)
1643 TD
->HwTD
.gTD
.Control
.ConditionCode
= OHCI_TD_CONDITION_NO_ERROR
;
1647 if (TD
->HwTD
.gTD
.CurrentBuffer
)
1649 if (TD
->TransferLen
)
1651 Length
= (BufferEnd
& (PAGE_SIZE
- 1)) -
1652 (Buffer
& (PAGE_SIZE
- 1));
1656 if (Buffer
>> PAGE_SHIFT
!= BufferEnd
>> PAGE_SHIFT
)
1657 Length
+= PAGE_SIZE
;
1659 TD
->TransferLen
-= Length
;
1663 if (TD
->HwTD
.gTD
.Control
.DirectionPID
!= OHCI_TD_DIRECTION_PID_SETUP
)
1664 OhciTransfer
->TransferLen
+= TD
->TransferLen
;
1666 if (TD
->HwTD
.gTD
.Control
.ConditionCode
)
1668 OhciTransfer
->USBDStatus
= USBD_STATUS_HALTED
|
1669 TD
->HwTD
.gTD
.Control
.ConditionCode
;
1674 TD
->HwTD
.gTD
.NextTD
= 0;
1675 TD
->OhciTransfer
= 0;
1677 TD
->DoneLink
.Flink
= NULL
;
1678 TD
->DoneLink
.Blink
= NULL
;
1680 if (IsPortComplete
&& (OhciTransfer
->PendingTDs
== 0))
1682 RegPacket
.UsbPortCompleteTransfer(OhciExtension
,
1684 OhciTransfer
->TransferParameters
,
1685 OhciTransfer
->USBDStatus
,
1686 OhciTransfer
->TransferLen
);
1692 OHCI_ProcessDoneIsoTD(IN POHCI_EXTENSION OhciExtension
,
1694 IN BOOLEAN IsPortComplete
)
1696 DPRINT1("OHCI_ProcessDoneIsoTD: UNIMPLEMENTED. FIXME\n");
1701 OHCI_AbortTransfer(IN PVOID ohciExtension
,
1702 IN PVOID ohciEndpoint
,
1703 IN PVOID ohciTransfer
,
1704 IN OUT PULONG CompletedLength
)
1706 POHCI_EXTENSION OhciExtension
= ohciExtension
;
1707 POHCI_ENDPOINT OhciEndpoint
= ohciEndpoint
;
1708 POHCI_TRANSFER OhciTransfer
= ohciTransfer
;
1709 POHCI_TRANSFER TmpTransfer
;
1712 POHCI_HCD_TD NextTD
;
1714 POHCI_HCD_TD PrevTD
;
1715 POHCI_HCD_TD LastTD
;
1716 POHCI_HCD_TD td
= NULL
;
1718 BOOLEAN IsIsoEndpoint
= FALSE
;
1719 BOOLEAN IsProcessed
= FALSE
;
1721 DPRINT("OHCI_AbortTransfer: ohciEndpoint - %p, ohciTransfer - %p\n",
1725 if (OhciEndpoint
->EndpointProperties
.TransferType
==
1726 USBPORT_TRANSFER_TYPE_ISOCHRONOUS
)
1728 IsIsoEndpoint
= TRUE
;
1731 ED
= OhciEndpoint
->HcdED
;
1732 NextTdPA
= ED
->HwED
.HeadPointer
& OHCI_ED_HEAD_POINTER_MASK
;
1734 NextTD
= RegPacket
.UsbPortGetMappedVirtualAddress((PVOID
)NextTdPA
,
1738 if (NextTD
->OhciTransfer
== (ULONG
)OhciTransfer
)
1740 LastTD
= OhciTransfer
->NextTD
;
1742 ED
->HwED
.HeadPointer
= LastTD
->PhysicalAddress
|
1743 (ED
->HwED
.HeadPointer
& OHCI_ED_HEAD_POINTER_CARRY
);
1745 OhciEndpoint
->HcdHeadP
= LastTD
;
1747 for (ix
= 0; ix
< OhciEndpoint
->MaxTransferDescriptors
; ix
++)
1749 TD
= &OhciEndpoint
->FirstTD
[ix
];
1751 if (TD
->OhciTransfer
== (ULONG
)OhciTransfer
)
1754 OHCI_ProcessDoneIsoTD(OhciExtension
, TD
, FALSE
);
1756 OHCI_ProcessDoneTD(OhciExtension
, TD
, FALSE
);
1760 *CompletedLength
= OhciTransfer
->TransferLen
;
1764 TD
= OhciEndpoint
->HcdHeadP
;
1771 if (TD
->OhciTransfer
== (ULONG
)ohciTransfer
)
1774 TD
= (POHCI_HCD_TD
)TD
->NextHcdTD
;
1776 if (PrevTD
== OhciEndpoint
->HcdHeadP
)
1777 OhciEndpoint
->HcdHeadP
= TD
;
1780 OHCI_ProcessDoneIsoTD(OhciExtension
, PrevTD
, FALSE
);
1782 OHCI_ProcessDoneTD(OhciExtension
, PrevTD
, FALSE
);
1788 TD
= (POHCI_HCD_TD
)TD
->NextHcdTD
;
1791 while (TD
!= NextTD
);
1795 TD
= OhciEndpoint
->HcdHeadP
;
1800 while (TD
!= OhciEndpoint
->HcdTailP
)
1802 if (TD
->OhciTransfer
== (ULONG
)OhciTransfer
)
1810 TD
= (POHCI_HCD_TD
)TD
->NextHcdTD
;
1817 if (TD
== OhciEndpoint
->HcdTailP
)
1821 TD
= (POHCI_HCD_TD
)TD
->NextHcdTD
;
1824 OHCI_ProcessDoneIsoTD(OhciExtension
, PrevTD
, FALSE
);
1826 OHCI_ProcessDoneTD(OhciExtension
, PrevTD
, FALSE
);
1828 while (TD
->OhciTransfer
== (ULONG
)OhciTransfer
);
1830 TmpTransfer
= (POHCI_TRANSFER
)LastTD
->OhciTransfer
;
1831 TmpTransfer
->NextTD
= TD
;
1833 LastTD
->NextHcdTD
= (ULONG
)TD
;
1834 LastTD
->HwTD
.gTD
.NextTD
= TD
->PhysicalAddress
;
1839 *CompletedLength
= OhciTransfer
->TransferLen
;
1841 if (OhciTransfer
->TransferLen
)
1843 DPRINT("OHCI_AbortTransfer: *CompletedLength - %x\n", *CompletedLength
);
1849 OHCI_GetEndpointState(IN PVOID ohciExtension
,
1850 IN PVOID ohciEndpoint
)
1852 POHCI_ENDPOINT OhciEndpoint
= ohciEndpoint
;
1855 DPRINT_OHCI("OHCI_GetEndpointState: ... \n");
1857 ED
= OhciEndpoint
->HcdED
;
1859 if (ED
->Flags
& OHCI_HCD_TD_FLAG_NOT_ACCESSED
)
1860 return USBPORT_ENDPOINT_REMOVE
;
1862 if (ED
->HwED
.EndpointControl
.sKip
)
1863 return USBPORT_ENDPOINT_PAUSED
;
1865 return USBPORT_ENDPOINT_ACTIVE
;
1870 OHCI_RemoveEndpointFromSchedule(IN POHCI_ENDPOINT OhciEndpoint
)
1873 POHCI_HCD_ED PreviousED
;
1874 POHCI_STATIC_ED HeadED
;
1876 DPRINT_OHCI("OHCI_RemoveEndpointFromSchedule \n");
1878 ED
= OhciEndpoint
->HcdED
;
1879 HeadED
= OhciEndpoint
->HeadED
;
1881 if (&HeadED
->Link
== ED
->HcdEDLink
.Blink
)
1883 if (HeadED
->Type
== OHCI_STATIC_ED_TYPE_CONTROL
||
1884 HeadED
->Type
== OHCI_STATIC_ED_TYPE_BULK
)
1886 WRITE_REGISTER_ULONG(HeadED
->pNextED
, ED
->HwED
.NextED
);
1888 else if (HeadED
->Type
== OHCI_STATIC_ED_TYPE_INTERRUPT
)
1890 *HeadED
->pNextED
= ED
->HwED
.NextED
;
1894 DPRINT1("OHCI_RemoveEndpointFromSchedule: Unknown HeadED->Type - %x\n",
1901 PreviousED
= CONTAINING_RECORD(ED
->HcdEDLink
.Blink
,
1905 PreviousED
->HwED
.NextED
= ED
->HwED
.NextED
;
1908 RemoveEntryList(&ED
->HcdEDLink
);
1910 OhciEndpoint
->HeadED
= NULL
;
1915 OHCI_SetEndpointState(IN PVOID ohciExtension
,
1916 IN PVOID ohciEndpoint
,
1917 IN ULONG EndpointState
)
1919 POHCI_EXTENSION OhciExtension
= ohciExtension
;
1920 POHCI_ENDPOINT OhciEndpoint
= ohciEndpoint
;
1923 DPRINT_OHCI("OHCI_SetEndpointState: EndpointState - %x\n",
1926 ED
= OhciEndpoint
->HcdED
;
1928 switch (EndpointState
)
1930 case USBPORT_ENDPOINT_PAUSED
:
1931 ED
->HwED
.EndpointControl
.sKip
= 1;
1934 case USBPORT_ENDPOINT_ACTIVE
:
1935 ED
->HwED
.EndpointControl
.sKip
= 0;
1936 OHCI_EnableList(OhciExtension
, OhciEndpoint
);
1939 case USBPORT_ENDPOINT_REMOVE
:
1940 ED
->HwED
.EndpointControl
.sKip
= 1;
1941 ED
->Flags
|= OHCI_HCD_ED_FLAG_NOT_ACCESSED
;
1942 OHCI_RemoveEndpointFromSchedule(OhciEndpoint
);
1953 OHCI_PollAsyncEndpoint(IN POHCI_EXTENSION OhciExtension
,
1954 IN POHCI_ENDPOINT OhciEndpoint
)
1956 PUSBPORT_TRANSFER_PARAMETERS TransferParameters
;
1959 POHCI_HCD_TD NextTD
;
1961 PLIST_ENTRY DoneList
;
1962 POHCI_TRANSFER OhciTransfer
;
1963 POHCI_HCD_TD ControlStatusTD
;
1964 ULONG_PTR PhysicalAddress
;
1965 ULONG TransferNumber
;
1966 POHCI_TRANSFER transfer
;
1967 UCHAR ConditionCode
;
1968 BOOLEAN IsResetOnHalt
= FALSE
;
1970 //DPRINT_OHCI("OHCI_PollAsyncEndpoint: Endpoint - %p\n", OhciEndpoint);
1972 ED
= OhciEndpoint
->HcdED
;
1973 NextTdPA
= ED
->HwED
.HeadPointer
& OHCI_ED_HEAD_POINTER_MASK
;
1981 NextTD
= RegPacket
.UsbPortGetMappedVirtualAddress((PVOID
)NextTdPA
,
1984 DPRINT_OHCI("NextTD - %p\n", NextTD
);
1986 if ((ED
->HwED
.HeadPointer
& OHCI_ED_HEAD_POINTER_HALT
) == 0)
1987 goto ProcessListTDs
;
1991 IsResetOnHalt
= (ED
->Flags
& OHCI_HCD_ED_FLAG_RESET_ON_HALT
) != 0;
1992 DPRINT1("PollAsyncEndpoint: IsResetOnHalt %x\n", IsResetOnHalt
);
1994 for (TD
= OhciEndpoint
->HcdHeadP
; ; TD
= (POHCI_HCD_TD
)TD
->NextHcdTD
)
2004 DPRINT("TD == NextTD - %p\n", TD
);
2005 goto HandleDoneList
;
2008 OhciTransfer
= (POHCI_TRANSFER
)TD
->OhciTransfer
;
2009 ConditionCode
= TD
->HwTD
.gTD
.Control
.ConditionCode
;
2011 DPRINT("TD - %p, ConditionCode - %X\n", TD
, ConditionCode
);
2014 switch (ConditionCode
)
2016 case OHCI_TD_CONDITION_NO_ERROR
:
2017 TD
->Flags
|= OHCI_HCD_TD_FLAG_DONE
;
2018 InsertTailList(&OhciEndpoint
->TDList
, &TD
->DoneLink
);
2021 case OHCI_TD_CONDITION_NOT_ACCESSED
:
2022 TD
->Flags
|= (OHCI_HCD_TD_FLAG_DONE
| OHCI_HCD_TD_FLAG_NOT_ACCESSED
);
2023 InsertTailList(&OhciEndpoint
->TDList
, &TD
->DoneLink
);
2026 case OHCI_TD_CONDITION_DATA_UNDERRUN
:
2027 DPRINT1("DATA_UNDERRUN. Transfer->Flags - %X\n", OhciTransfer
->Flags
);
2029 if (OhciTransfer
->Flags
& OHCI_TRANSFER_FLAGS_SHORT_TRANSFER_OK
)
2031 IsResetOnHalt
= TRUE
;
2032 TD
->HwTD
.gTD
.Control
.ConditionCode
= OHCI_TD_CONDITION_NO_ERROR
;
2034 ControlStatusTD
= OhciTransfer
->ControlStatusTD
;
2036 if ((TD
->Flags
& OHCI_HCD_TD_FLAG_CONTROL_STATUS
) == 0 &&
2039 PhysicalAddress
= ControlStatusTD
->PhysicalAddress
;
2040 PhysicalAddress
|= (ED
->HwED
.HeadPointer
&
2041 OHCI_ED_HEAD_POINTER_FLAGS_MASK
);
2043 ED
->HwED
.HeadPointer
= PhysicalAddress
;
2045 NextTD
= OhciTransfer
->ControlStatusTD
;
2046 DPRINT("PhysicalAddress - %p, NextTD - %p\n", PhysicalAddress
, NextTD
);
2050 TransferParameters
= OhciTransfer
->TransferParameters
;
2052 if (TransferParameters
->IsTransferSplited
)
2054 TransferNumber
= TransferParameters
->TransferCounter
;
2055 transfer
= OhciTransfer
;
2059 transfer
= (POHCI_TRANSFER
)transfer
->NextTD
->OhciTransfer
;
2060 NextTD
= transfer
->NextTD
;
2062 while (transfer
&& TransferNumber
==
2063 transfer
->TransferParameters
->TransferCounter
);
2065 PhysicalAddress
= NextTD
->PhysicalAddress
;
2066 PhysicalAddress
|= (ED
->HwED
.HeadPointer
&
2067 OHCI_ED_HEAD_POINTER_FLAGS_MASK
);
2069 ED
->HwED
.HeadPointer
= PhysicalAddress
;
2070 DPRINT("PhysicalAddress - %p, NextTD - %p\n", PhysicalAddress
, NextTD
);
2074 PhysicalAddress
= OhciTransfer
->NextTD
->PhysicalAddress
;
2075 PhysicalAddress
|= (ED
->HwED
.HeadPointer
&
2076 OHCI_ED_HEAD_POINTER_FLAGS_MASK
);
2078 ED
->HwED
.HeadPointer
= PhysicalAddress
;
2080 NextTD
= OhciTransfer
->NextTD
;
2081 DPRINT("PhysicalAddress - %p, NextTD - %p\n", PhysicalAddress
, NextTD
);
2085 TD
->Flags
|= OHCI_HCD_TD_FLAG_DONE
;
2086 InsertTailList(&OhciEndpoint
->TDList
, &TD
->DoneLink
);
2093 TD
->Flags
|= OHCI_HCD_TD_FLAG_DONE
;
2094 InsertTailList(&OhciEndpoint
->TDList
, &TD
->DoneLink
);
2096 ED
->HwED
.HeadPointer
= OhciTransfer
->NextTD
->PhysicalAddress
|
2097 (ED
->HwED
.HeadPointer
&
2098 OHCI_ED_HEAD_POINTER_FLAGS_MASK
);
2100 NextTD
= OhciTransfer
->NextTD
;
2107 TD
= OhciEndpoint
->HcdHeadP
;
2109 while (TD
!= NextTD
)
2112 TD
->Flags
|= OHCI_HCD_TD_FLAG_DONE
;
2113 InsertTailList(&OhciEndpoint
->TDList
, &TD
->DoneLink
);
2114 TD
= (POHCI_HCD_TD
)TD
->NextHcdTD
;
2120 OhciEndpoint
->HcdHeadP
= NextTD
;
2122 DoneList
= &OhciEndpoint
->TDList
;
2124 while (!IsListEmpty(DoneList
))
2126 TD
= CONTAINING_RECORD(DoneList
->Flink
,
2130 RemoveHeadList(DoneList
);
2132 if (TD
->Flags
& OHCI_HCD_TD_FLAG_DONE
&&
2133 TD
->Flags
& OHCI_HCD_TD_FLAG_PROCESSED
)
2135 OHCI_ProcessDoneTD(OhciExtension
, TD
, TRUE
);
2141 ED
->HwED
.HeadPointer
&= ~OHCI_ED_HEAD_POINTER_HALT
;
2142 DPRINT("ED->HwED.HeadPointer - %p\n", ED
->HwED
.HeadPointer
);
2148 OHCI_PollIsoEndpoint(IN POHCI_EXTENSION OhciExtension
,
2149 IN POHCI_ENDPOINT OhciEndpoint
)
2151 DPRINT1("OHCI_PollAsyncEndpoint: UNIMPLEMENTED. FIXME \n");
2157 OHCI_PollEndpoint(IN PVOID ohciExtension
,
2158 IN PVOID ohciEndpoint
)
2160 POHCI_EXTENSION OhciExtension
= ohciExtension
;
2161 POHCI_ENDPOINT OhciEndpoint
= ohciEndpoint
;
2164 DPRINT_OHCI("OHCI_PollEndpoint: OhciExtension - %p, Endpoint - %p\n",
2168 TransferType
= OhciEndpoint
->EndpointProperties
.TransferType
;
2170 if (TransferType
== USBPORT_TRANSFER_TYPE_ISOCHRONOUS
)
2172 OHCI_PollIsoEndpoint(OhciExtension
, OhciEndpoint
);
2176 if (TransferType
== USBPORT_TRANSFER_TYPE_CONTROL
||
2177 TransferType
== USBPORT_TRANSFER_TYPE_BULK
||
2178 TransferType
== USBPORT_TRANSFER_TYPE_INTERRUPT
)
2180 OHCI_PollAsyncEndpoint(OhciExtension
, OhciEndpoint
);
2186 OHCI_CheckController(IN PVOID ohciExtension
)
2188 POHCI_EXTENSION OhciExtension
= ohciExtension
;
2189 POHCI_OPERATIONAL_REGISTERS OperationalRegs
;
2190 PULONG HcControlReg
;
2191 OHCI_REG_CONTROL HcControl
;
2196 //DPRINT_OHCI("OHCI_CheckController: ...\n");
2198 OperationalRegs
= OhciExtension
->OperationalRegs
;
2200 if (!OHCI_HardwarePresent(OhciExtension
, TRUE
))
2203 HcControlReg
= (PULONG
)&OperationalRegs
->HcControl
;
2204 HcControl
.AsULONG
= READ_REGISTER_ULONG(HcControlReg
);
2206 if (HcControl
.HostControllerFunctionalState
!= OHCI_HC_STATE_OPERATIONAL
)
2209 FmNumber
= READ_REGISTER_ULONG(&OperationalRegs
->HcFmNumber
);
2210 FmDiff
= (USHORT
)(FmNumber
- OhciExtension
->HcdFmNumber
);
2212 if (FmNumber
== 0 || FmDiff
< 5)
2215 HcHCCA
= &OhciExtension
->HcResourcesVA
->HcHCCA
;
2216 OhciExtension
->HcdFmNumber
= FmNumber
;
2218 if (HcHCCA
->Pad1
== 0)
2220 HcHCCA
->Pad1
= 0xBAD1;
2224 DPRINT1("OHCI_CheckController: HcHCCA->Pad1 - %x\n", HcHCCA
->Pad1
);
2226 if (HcHCCA
->Pad1
== 0xBAD1)
2228 HcHCCA
->Pad1
= 0xBAD2;
2230 else if (HcHCCA
->Pad1
== 0xBAD2)
2232 HcHCCA
->Pad1
= 0xBAD3;
2234 RegPacket
.UsbPortInvalidateController(OhciExtension
,
2235 USBPORT_INVALIDATE_CONTROLLER_RESET
);
2241 OHCI_Get32BitFrameNumber(IN PVOID ohciExtension
)
2243 POHCI_EXTENSION OhciExtension
= ohciExtension
;
2248 HcHCCA
= &OhciExtension
->HcResourcesVA
->HcHCCA
;
2250 /* 5.4 FrameInterval Counter: Get32BitFrameNumber() */
2252 hp
= OhciExtension
->FrameHighPart
;
2253 fm
= HcHCCA
->FrameNumber
;
2255 DPRINT_OHCI("OHCI_Get32BitFrameNumber: hp - %lX, fm - %lX\n", hp
, fm
);
2257 return ((fm
& 0x7FFF) | hp
) + ((fm
^ hp
) & 0x8000);
2262 OHCI_InterruptNextSOF(IN PVOID ohciExtension
)
2264 POHCI_EXTENSION OhciExtension
= ohciExtension
;
2265 POHCI_OPERATIONAL_REGISTERS OperationalRegs
;
2266 PULONG InterruptEnableReg
;
2267 OHCI_REG_INTERRUPT_ENABLE_DISABLE IntEnable
;
2269 DPRINT_OHCI("OHCI_InterruptNextSOF: OhciExtension - %p\n",
2272 OperationalRegs
= OhciExtension
->OperationalRegs
;
2273 InterruptEnableReg
= (PULONG
)&OperationalRegs
->HcInterruptEnable
;
2275 /* Enable interrupt generation due to Start of Frame */
2276 IntEnable
.AsULONG
= 0;
2277 IntEnable
.StartofFrame
= 1;
2279 WRITE_REGISTER_ULONG(InterruptEnableReg
, IntEnable
.AsULONG
);
2284 OHCI_EnableInterrupts(IN PVOID ohciExtension
)
2286 POHCI_EXTENSION OhciExtension
= ohciExtension
;
2287 POHCI_OPERATIONAL_REGISTERS OperationalRegs
;
2288 PULONG InterruptEnableReg
;
2289 OHCI_REG_INTERRUPT_ENABLE_DISABLE IntEnable
;
2291 DPRINT_OHCI("OHCI_EnableInterrupts: OhciExtension - %p\n",
2294 OperationalRegs
= OhciExtension
->OperationalRegs
;
2295 InterruptEnableReg
= (PULONG
)&OperationalRegs
->HcInterruptEnable
;
2297 /* Enable interrupt generation */
2298 IntEnable
.AsULONG
= 0;
2299 IntEnable
.MasterInterruptEnable
= 1;
2301 WRITE_REGISTER_ULONG(InterruptEnableReg
, IntEnable
.AsULONG
);
2306 OHCI_DisableInterrupts(IN PVOID ohciExtension
)
2308 POHCI_EXTENSION OhciExtension
= ohciExtension
;
2309 POHCI_OPERATIONAL_REGISTERS OperationalRegs
;
2310 PULONG InterruptDisableReg
;
2311 OHCI_REG_INTERRUPT_ENABLE_DISABLE IntDisable
;
2313 DPRINT_OHCI("OHCI_DisableInterrupts\n");
2315 OperationalRegs
= OhciExtension
->OperationalRegs
;
2316 InterruptDisableReg
= (PULONG
)&OperationalRegs
->HcInterruptDisable
;
2318 /* Disable interrupt generation */
2319 IntDisable
.AsULONG
= 0;
2320 IntDisable
.MasterInterruptEnable
= 1;
2322 WRITE_REGISTER_ULONG(InterruptDisableReg
, IntDisable
.AsULONG
);
2327 OHCI_PollController(IN PVOID ohciExtension
)
2329 DPRINT1("OHCI_PollController: UNIMPLEMENTED. FIXME\n");
2334 OHCI_SetEndpointDataToggle(IN PVOID ohciExtension
,
2335 IN PVOID ohciEndpoint
,
2336 IN ULONG DataToggle
)
2338 POHCI_ENDPOINT OhciEndpoint
= ohciEndpoint
;
2341 DPRINT_OHCI("OHCI_SetEndpointDataToggle: Endpoint - %p, DataToggle - %x\n",
2345 ED
= OhciEndpoint
->HcdED
;
2348 ED
->HwED
.HeadPointer
|= OHCI_ED_HEAD_POINTER_CARRY
;
2350 ED
->HwED
.HeadPointer
&= ~OHCI_ED_HEAD_POINTER_CARRY
;
2355 OHCI_GetEndpointStatus(IN PVOID ohciExtension
,
2356 IN PVOID ohciEndpoint
)
2358 POHCI_ENDPOINT OhciEndpoint
= ohciEndpoint
;
2360 ULONG EndpointStatus
= USBPORT_ENDPOINT_RUN
;
2362 DPRINT_OHCI("OHCI_GetEndpointStatus: ... \n");
2364 ED
= OhciEndpoint
->HcdED
;
2366 if ((ED
->HwED
.HeadPointer
& OHCI_ED_HEAD_POINTER_HALT
) &&
2367 !(ED
->Flags
& OHCI_HCD_ED_FLAG_RESET_ON_HALT
))
2369 EndpointStatus
= USBPORT_ENDPOINT_HALT
;
2372 return EndpointStatus
;
2377 OHCI_SetEndpointStatus(IN PVOID ohciExtension
,
2378 IN PVOID ohciEndpoint
,
2379 IN ULONG EndpointStatus
)
2381 POHCI_EXTENSION OhciExtension
= ohciExtension
;
2382 POHCI_ENDPOINT OhciEndpoint
= ohciEndpoint
;
2385 DPRINT_OHCI("OHCI_SetEndpointStatus: Endpoint - %p, EndpointStatus - %lX\n",
2389 if (EndpointStatus
== USBPORT_ENDPOINT_RUN
)
2391 ED
= OhciEndpoint
->HcdED
;
2392 ED
->HwED
.HeadPointer
&= ~OHCI_ED_HEAD_POINTER_HALT
;
2394 OHCI_EnableList(OhciExtension
, OhciEndpoint
);
2396 else if (EndpointStatus
== USBPORT_ENDPOINT_HALT
)
2404 OHCI_ResetController(IN PVOID ohciExtension
)
2406 POHCI_EXTENSION OhciExtension
= ohciExtension
;
2407 POHCI_OPERATIONAL_REGISTERS OperationalRegs
;
2410 PULONG CommandStatusReg
;
2411 PULONG InterruptEnableReg
;
2412 PULONG FmIntervalReg
;
2414 PULONG PortStatusReg
;
2415 OHCI_REG_CONTROL ControlBak
;
2416 OHCI_REG_CONTROL Control
;
2417 OHCI_REG_COMMAND_STATUS CommandStatus
;
2418 OHCI_REG_INTERRUPT_ENABLE_DISABLE IntEnable
;
2420 ULONG_PTR ControlHeadED
;
2421 ULONG_PTR BulkHeadED
;
2422 OHCI_REG_FRAME_INTERVAL FrameInterval
;
2423 ULONG_PTR PeriodicStart
;
2424 ULONG_PTR LSThreshold
;
2425 OHCI_REG_RH_STATUS RhStatus
;
2426 OHCI_REG_RH_DESCRIPTORA RhDescriptorA
;
2427 OHCI_REG_RH_PORT_STATUS PortStatus
;
2431 DPRINT("OHCI_ResetController: ... \n");
2433 OperationalRegs
= OhciExtension
->OperationalRegs
;
2435 ControlReg
= (PULONG
)&OperationalRegs
->HcControl
;
2436 CommandStatusReg
= (PULONG
)&OperationalRegs
->HcCommandStatus
;
2437 InterruptEnableReg
= (PULONG
)&OperationalRegs
->HcInterruptEnable
;
2438 FmIntervalReg
= (PULONG
)&OperationalRegs
->HcFmInterval
;
2439 RhStatusReg
= (PULONG
)&OperationalRegs
->HcRhStatus
;
2441 /* Backup FrameNumber from HcHCCA */
2442 FrameNumber
= OhciExtension
->HcResourcesVA
->HcHCCA
.FrameNumber
;
2444 /* Backup registers */
2445 ControlBak
.AsULONG
= READ_REGISTER_ULONG(ControlReg
);
2446 HCCA
= READ_REGISTER_ULONG(&OperationalRegs
->HcHCCA
);
2447 ControlHeadED
= READ_REGISTER_ULONG(&OperationalRegs
->HcControlHeadED
);
2448 BulkHeadED
= READ_REGISTER_ULONG(&OperationalRegs
->HcBulkHeadED
);
2449 FrameInterval
.AsULONG
= READ_REGISTER_ULONG(FmIntervalReg
);
2450 PeriodicStart
= READ_REGISTER_ULONG(&OperationalRegs
->HcPeriodicStart
);
2451 LSThreshold
= READ_REGISTER_ULONG(&OperationalRegs
->HcLSThreshold
);
2453 /* Reset HostController */
2454 CommandStatus
.AsULONG
= 0;
2455 CommandStatus
.HostControllerReset
= 1;
2456 WRITE_REGISTER_ULONG(CommandStatusReg
, CommandStatus
.AsULONG
);
2458 KeStallExecutionProcessor(10);
2460 /* Restore registers */
2461 WRITE_REGISTER_ULONG(&OperationalRegs
->HcHCCA
, HCCA
);
2462 WRITE_REGISTER_ULONG(&OperationalRegs
->HcControlHeadED
, ControlHeadED
);
2463 WRITE_REGISTER_ULONG(&OperationalRegs
->HcBulkHeadED
, BulkHeadED
);
2465 /* Set OPERATIONAL state for HC */
2466 Control
.AsULONG
= 0;
2467 Control
.HostControllerFunctionalState
= OHCI_HC_STATE_OPERATIONAL
;
2468 WRITE_REGISTER_ULONG(ControlReg
, Control
.AsULONG
);
2470 /* Set Toggle bit for FmInterval register */
2471 FrameInterval
.FrameIntervalToggle
= 1;
2472 WRITE_REGISTER_ULONG(FmIntervalReg
, FrameInterval
.AsULONG
);
2474 /* Restore registers */
2475 WRITE_REGISTER_ULONG(&OperationalRegs
->HcFmNumber
, FrameNumber
);
2476 WRITE_REGISTER_ULONG(&OperationalRegs
->HcPeriodicStart
, PeriodicStart
);
2477 WRITE_REGISTER_ULONG(&OperationalRegs
->HcLSThreshold
, LSThreshold
);
2479 /* Setup RhStatus register */
2480 RhStatus
.AsULONG
= 0;
2481 RhStatus
.SetRemoteWakeupEnable
= 1;
2482 RhStatus
.SetGlobalPower
= 1;
2483 WRITE_REGISTER_ULONG(RhStatusReg
, RhStatus
.AsULONG
);
2485 /* Setup RH PortStatus registers */
2486 RhDescriptorA
= OHCI_ReadRhDescriptorA(OhciExtension
);
2487 NumPorts
= RhDescriptorA
.NumberDownstreamPorts
;
2489 PortStatus
.AsULONG
= 0;
2490 PortStatus
.SetPortPower
= 1;
2492 for (ix
= 0; ix
< NumPorts
; ix
++)
2494 PortStatusReg
= (PULONG
)&OperationalRegs
->HcRhPortStatus
[ix
];
2495 WRITE_REGISTER_ULONG(PortStatusReg
, PortStatus
.AsULONG
);
2498 /* Restore HcControl register */
2499 ControlBak
.HostControllerFunctionalState
= OHCI_HC_STATE_OPERATIONAL
;
2500 WRITE_REGISTER_ULONG(ControlReg
, ControlBak
.AsULONG
);
2502 /* Setup HcInterruptEnable register */
2503 IntEnable
.AsULONG
= 0xFFFFFFFF;
2504 IntEnable
.Reserved1
= 0;
2505 WRITE_REGISTER_ULONG(InterruptEnableReg
, IntEnable
.AsULONG
);
2510 OHCI_StartSendOnePacket(IN PVOID ohciExtension
,
2511 IN PVOID PacketParameters
,
2513 IN PULONG pDataLength
,
2516 IN ULONG BufferLength
,
2517 IN USBD_STATUS
* pUSBDStatus
)
2519 DPRINT1("OHCI_StartSendOnePacket: UNIMPLEMENTED. FIXME\n");
2520 return MP_STATUS_SUCCESS
;
2525 OHCI_EndSendOnePacket(IN PVOID ohciExtension
,
2526 IN PVOID PacketParameters
,
2528 IN PULONG pDataLength
,
2531 IN ULONG BufferLength
,
2532 IN USBD_STATUS
* pUSBDStatus
)
2534 DPRINT1("OHCI_EndSendOnePacket: UNIMPLEMENTED. FIXME\n");
2535 return MP_STATUS_SUCCESS
;
2540 OHCI_PassThru(IN PVOID ohciExtension
,
2541 IN PVOID passThruParameters
,
2542 IN ULONG ParameterLength
,
2543 IN PVOID pParameters
)
2545 DPRINT1("OHCI_PassThru: UNIMPLEMENTED. FIXME\n");
2546 return MP_STATUS_SUCCESS
;
2551 OHCI_Unload(IN PDRIVER_OBJECT DriverObject
)
2554 DPRINT1("OHCI_Unload: Not supported\n");
2561 OHCI_FlushInterrupts(IN PVOID uhciExtension
)
2564 DPRINT1("OHCI_FlushInterrupts: Not supported\n");
2571 DriverEntry(IN PDRIVER_OBJECT DriverObject
,
2572 IN PUNICODE_STRING RegistryPath
)
2576 DPRINT_OHCI("DriverEntry: DriverObject - %p, RegistryPath - %wZ\n",
2580 RtlZeroMemory(&RegPacket
, sizeof(USBPORT_REGISTRATION_PACKET
));
2582 RegPacket
.MiniPortVersion
= USB_MINIPORT_VERSION_OHCI
;
2584 RegPacket
.MiniPortFlags
= USB_MINIPORT_FLAGS_INTERRUPT
|
2585 USB_MINIPORT_FLAGS_MEMORY_IO
;
2587 RegPacket
.MiniPortBusBandwidth
= TOTAL_USB11_BUS_BANDWIDTH
;
2589 RegPacket
.MiniPortExtensionSize
= sizeof(OHCI_EXTENSION
);
2590 RegPacket
.MiniPortEndpointSize
= sizeof(OHCI_ENDPOINT
);
2591 RegPacket
.MiniPortTransferSize
= sizeof(OHCI_TRANSFER
);
2592 RegPacket
.MiniPortResourcesSize
= sizeof(OHCI_HC_RESOURCES
);
2594 RegPacket
.OpenEndpoint
= OHCI_OpenEndpoint
;
2595 RegPacket
.ReopenEndpoint
= OHCI_ReopenEndpoint
;
2596 RegPacket
.QueryEndpointRequirements
= OHCI_QueryEndpointRequirements
;
2597 RegPacket
.CloseEndpoint
= OHCI_CloseEndpoint
;
2598 RegPacket
.StartController
= OHCI_StartController
;
2599 RegPacket
.StopController
= OHCI_StopController
;
2600 RegPacket
.SuspendController
= OHCI_SuspendController
;
2601 RegPacket
.ResumeController
= OHCI_ResumeController
;
2602 RegPacket
.InterruptService
= OHCI_InterruptService
;
2603 RegPacket
.InterruptDpc
= OHCI_InterruptDpc
;
2604 RegPacket
.SubmitTransfer
= OHCI_SubmitTransfer
;
2605 RegPacket
.SubmitIsoTransfer
= OHCI_SubmitIsoTransfer
;
2606 RegPacket
.AbortTransfer
= OHCI_AbortTransfer
;
2607 RegPacket
.GetEndpointState
= OHCI_GetEndpointState
;
2608 RegPacket
.SetEndpointState
= OHCI_SetEndpointState
;
2609 RegPacket
.PollEndpoint
= OHCI_PollEndpoint
;
2610 RegPacket
.CheckController
= OHCI_CheckController
;
2611 RegPacket
.Get32BitFrameNumber
= OHCI_Get32BitFrameNumber
;
2612 RegPacket
.InterruptNextSOF
= OHCI_InterruptNextSOF
;
2613 RegPacket
.EnableInterrupts
= OHCI_EnableInterrupts
;
2614 RegPacket
.DisableInterrupts
= OHCI_DisableInterrupts
;
2615 RegPacket
.PollController
= OHCI_PollController
;
2616 RegPacket
.SetEndpointDataToggle
= OHCI_SetEndpointDataToggle
;
2617 RegPacket
.GetEndpointStatus
= OHCI_GetEndpointStatus
;
2618 RegPacket
.SetEndpointStatus
= OHCI_SetEndpointStatus
;
2619 RegPacket
.ResetController
= OHCI_ResetController
;
2620 RegPacket
.RH_GetRootHubData
= OHCI_RH_GetRootHubData
;
2621 RegPacket
.RH_GetStatus
= OHCI_RH_GetStatus
;
2622 RegPacket
.RH_GetPortStatus
= OHCI_RH_GetPortStatus
;
2623 RegPacket
.RH_GetHubStatus
= OHCI_RH_GetHubStatus
;
2624 RegPacket
.RH_SetFeaturePortReset
= OHCI_RH_SetFeaturePortReset
;
2625 RegPacket
.RH_SetFeaturePortPower
= OHCI_RH_SetFeaturePortPower
;
2626 RegPacket
.RH_SetFeaturePortEnable
= OHCI_RH_SetFeaturePortEnable
;
2627 RegPacket
.RH_SetFeaturePortSuspend
= OHCI_RH_SetFeaturePortSuspend
;
2628 RegPacket
.RH_ClearFeaturePortEnable
= OHCI_RH_ClearFeaturePortEnable
;
2629 RegPacket
.RH_ClearFeaturePortPower
= OHCI_RH_ClearFeaturePortPower
;
2630 RegPacket
.RH_ClearFeaturePortSuspend
= OHCI_RH_ClearFeaturePortSuspend
;
2631 RegPacket
.RH_ClearFeaturePortEnableChange
= OHCI_RH_ClearFeaturePortEnableChange
;
2632 RegPacket
.RH_ClearFeaturePortConnectChange
= OHCI_RH_ClearFeaturePortConnectChange
;
2633 RegPacket
.RH_ClearFeaturePortResetChange
= OHCI_RH_ClearFeaturePortResetChange
;
2634 RegPacket
.RH_ClearFeaturePortSuspendChange
= OHCI_RH_ClearFeaturePortSuspendChange
;
2635 RegPacket
.RH_ClearFeaturePortOvercurrentChange
= OHCI_RH_ClearFeaturePortOvercurrentChange
;
2636 RegPacket
.RH_DisableIrq
= OHCI_RH_DisableIrq
;
2637 RegPacket
.RH_EnableIrq
= OHCI_RH_EnableIrq
;
2638 RegPacket
.StartSendOnePacket
= OHCI_StartSendOnePacket
;
2639 RegPacket
.EndSendOnePacket
= OHCI_EndSendOnePacket
;
2640 RegPacket
.PassThru
= OHCI_PassThru
;
2641 RegPacket
.FlushInterrupts
= OHCI_FlushInterrupts
;
2643 DriverObject
->DriverUnload
= OHCI_Unload
;
2645 Status
= USBPORT_RegisterUSBPortDriver(DriverObject
,
2646 USB10_MINIPORT_INTERFACE_VERSION
,
2649 DPRINT_OHCI("DriverEntry: USBPORT_RegisterUSBPortDriver return Status - %x\n",