Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

258 lines
6.3 KiB

  1. /*++
  2. Copyright (c) 1999 Microsoft Corporation
  3. Module Name:
  4. int.c
  5. Abstract:
  6. interrupt service routine
  7. Environment:
  8. kernel mode only
  9. Notes:
  10. THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
  11. KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
  12. IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
  13. PURPOSE.
  14. Copyright (c) 1999 Microsoft Corporation. All Rights Reserved.
  15. Revision History:
  16. 7-19-99 : created, jdunn
  17. --*/
  18. #include "common.h"
  19. BOOLEAN
  20. OHCI_InterruptService (
  21. PDEVICE_DATA DeviceData
  22. )
  23. /*++
  24. Routine Description:
  25. Arguments:
  26. Return Value:
  27. --*/
  28. {
  29. BOOLEAN usbInt;
  30. PHC_OPERATIONAL_REGISTER hc;
  31. ULONG irqStatus, enabledIrqs, tmp;
  32. hc = DeviceData->HC;
  33. // assume it is not ours
  34. usbInt = FALSE;
  35. // see if we have lost the controller due to
  36. // a surprise remove
  37. if (OHCI_HardwarePresent(DeviceData, FALSE) == FALSE) {
  38. return FALSE;
  39. }
  40. // get a mask of possible interrupts
  41. enabledIrqs = READ_REGISTER_ULONG (&hc->HcInterruptEnable);
  42. irqStatus = READ_REGISTER_ULONG(&hc->HcInterruptStatus);
  43. // mask off non-enabled irqs
  44. irqStatus &= enabledIrqs;
  45. // irqStatus now possibly contains bits set for any currently
  46. // enabled interrupts
  47. if ((irqStatus != 0) &&
  48. (enabledIrqs & HcInt_MasterInterruptEnable)) {
  49. // check for frame number overflow
  50. if (irqStatus & HcInt_FrameNumberOverflow) {
  51. DeviceData->FrameHighPart
  52. += 0x10000 - (0x8000 & (DeviceData->HcHCCA->HccaFrameNumber
  53. ^ DeviceData->FrameHighPart));
  54. }
  55. #if DBG
  56. if (irqStatus & HcInt_UnrecoverableError) {
  57. // something has gone terribly wrong
  58. OHCI_KdPrint((DeviceData, 0, "'HcInt_UnrecoverableError! DD(%x)\n",
  59. DeviceData));
  60. //DbgBreakPoint();
  61. }
  62. #endif
  63. // indications are that this came from the USB controller
  64. usbInt = TRUE;
  65. // disable interrupts until the DPC for ISR runs
  66. WRITE_REGISTER_ULONG(&hc->HcInterruptDisable,
  67. HcInt_MasterInterruptEnable);
  68. }
  69. return usbInt;
  70. }
  71. VOID
  72. OHCI_InterruptDpc (
  73. PDEVICE_DATA DeviceData,
  74. BOOLEAN EnableInterrupts
  75. )
  76. /*++
  77. Routine Description:
  78. process an interrupt
  79. Arguments:
  80. Return Value:
  81. --*/
  82. {
  83. ULONG irqStatus;
  84. PHC_OPERATIONAL_REGISTER hc;
  85. ULONG doneQueue, cf;
  86. hc = DeviceData->HC;
  87. irqStatus = READ_REGISTER_ULONG(&hc->HcInterruptStatus);
  88. cf = OHCI_Get32BitFrameNumber(DeviceData);
  89. // what was the reason for the interrupt?
  90. if (irqStatus & HcInt_RootHubStatusChange) {
  91. LOGENTRY(DeviceData, G, '_rhS', DeviceData, 0, 0);
  92. USBPORT_INVALIDATE_ROOTHUB(DeviceData);
  93. }
  94. if (irqStatus & HcInt_WritebackDoneHead) {
  95. // controller indicates some done TDs
  96. doneQueue = DeviceData->HcHCCA->HccaDoneHead;
  97. LOGENTRY(DeviceData, G, '_dnQ', DeviceData, doneQueue,
  98. cf);
  99. // we will have a problem if we ever actually use the doneQ.
  100. // Currently we do not use it so the hydra bug where the doneQ
  101. // is wriiten back as zero won't hurt us.
  102. //if (doneQueue == 0) {
  103. //}
  104. // write the done head back to zero
  105. DeviceData->HcHCCA->HccaDoneHead = 0;
  106. LOGENTRY(DeviceData, G, '_dQZ', DeviceData, doneQueue, 0);
  107. // if (DoneQueue) {
  108. // OpenHCI_ProcessDoneQueue(deviceData, (DoneQueue & 0xFFFFfffe));
  109. // //
  110. // // BUGBUG (?) No interrupts can come in while processing
  111. // // the done queue. Is this bad? This might take a while.
  112. // //
  113. // }
  114. // check all endpoints
  115. USBPORT_INVALIDATE_ENDPOINT(DeviceData, NULL);
  116. }
  117. if (irqStatus & HcInt_StartOfFrame) {
  118. // got the SOF we requested, disable it
  119. WRITE_REGISTER_ULONG(&hc->HcInterruptDisable,
  120. HcInt_StartOfFrame);
  121. }
  122. if (irqStatus & HcInt_ResumeDetected) {
  123. // got the resume, disable it
  124. WRITE_REGISTER_ULONG(&hc->HcInterruptDisable,
  125. HcInt_ResumeDetected);
  126. }
  127. if (irqStatus & HcInt_UnrecoverableError) {
  128. // host controller is dead, try to recover...
  129. USBPORT_INVALIDATE_CONTROLLER(DeviceData, UsbMpControllerNeedsHwReset);
  130. }
  131. // acknowlege the interrupts we processed --
  132. // we should have proceesed them all
  133. WRITE_REGISTER_ULONG(&hc->HcInterruptStatus, irqStatus);
  134. // see if we need to re-enable ints
  135. if (EnableInterrupts) {
  136. // throw the master irq enable to allow more interupts
  137. WRITE_REGISTER_ULONG(&hc->HcInterruptEnable,
  138. HcInt_MasterInterruptEnable);
  139. }
  140. }
  141. VOID
  142. OHCI_RH_DisableIrq(
  143. PDEVICE_DATA DeviceData
  144. )
  145. {
  146. PHC_OPERATIONAL_REGISTER hc;
  147. hc = DeviceData->HC;
  148. WRITE_REGISTER_ULONG(&hc->HcInterruptDisable,
  149. HcInt_RootHubStatusChange);
  150. }
  151. VOID
  152. OHCI_RH_EnableIrq(
  153. PDEVICE_DATA DeviceData
  154. )
  155. {
  156. PHC_OPERATIONAL_REGISTER hc;
  157. hc = DeviceData->HC;
  158. WRITE_REGISTER_ULONG(&hc->HcInterruptEnable,
  159. HcInt_RootHubStatusChange);
  160. }
  161. ULONG
  162. OHCI_Get32BitFrameNumber(
  163. PDEVICE_DATA DeviceData
  164. )
  165. {
  166. ULONG hp, fn, n;
  167. /*
  168. * This code accounts for the fact that HccaFrameNumber is updated by the
  169. * HC before the HCD gets an interrupt that will adjust FrameHighPart. No
  170. * synchronization is nescisary due to great cleaverness.
  171. */
  172. hp = DeviceData->FrameHighPart;
  173. fn = DeviceData->HcHCCA->HccaFrameNumber;
  174. n = ((fn & 0x7FFF) | hp) + ((fn ^ hp) & 0x8000);
  175. return n;
  176. }
  177. VOID
  178. OHCI_InterruptNextSOF(
  179. PDEVICE_DATA DeviceData
  180. )
  181. {
  182. PHC_OPERATIONAL_REGISTER hc;
  183. hc = DeviceData->HC;
  184. WRITE_REGISTER_ULONG(&hc->HcInterruptEnable,
  185. HcInt_StartOfFrame);
  186. }