Source code of Windows XP (NT5)
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.

333 lines
8.3 KiB

  1. /*++
  2. Copyright (C) Microsoft Corporation, 1993 - 1999
  3. Module Name:
  4. epp.c
  5. Abstract:
  6. This module contains the code to perform all Hardware EPP related tasks.
  7. Author:
  8. Don Redford - July 30, 1998
  9. Environment:
  10. Kernel mode
  11. Revision History :
  12. --*/
  13. #include "pch.h"
  14. BOOLEAN
  15. ParIsEppHwSupported(
  16. IN PDEVICE_EXTENSION Extension
  17. )
  18. /*++
  19. Routine Description:
  20. This routine determines whether or not HW EPP mode is suported
  21. for either direction by negotiating when asked.
  22. Arguments:
  23. Extension - The device extension.
  24. Return Value:
  25. BOOLEAN.
  26. --*/
  27. {
  28. NTSTATUS Status;
  29. // dvdr
  30. ParDump2(PARINFO, ("ParIsEppHwWriteSupported: Entering\n"));
  31. // Check to see if the hardware is capable
  32. if (!(Extension->HardwareCapabilities & PPT_EPP_PRESENT)) {
  33. // dvdr
  34. ParDump2(PARINFO, ("ParIsEppHwWriteSupported: Hardware Not Supported Leaving\n"));
  35. return FALSE;
  36. }
  37. if (Extension->BadProtocolModes & EPP_HW) {
  38. // dvdr
  39. ParDump2(PARINFO, ("ParIsEppHwWriteSupported: Bad Protocol Not Supported Leaving\n"));
  40. return FALSE;
  41. }
  42. if (Extension->ProtocolModesSupported & EPP_HW) {
  43. // dvdr
  44. ParDump2(PARINFO, ("ParIsEppHwWriteSupported: Already Checked Supported Leaving\n"));
  45. return TRUE;
  46. }
  47. // Must use HWEPP Enter and Terminate for this test.
  48. // Internel state machines will fail otherwise. --dvrh
  49. Status = ParEnterEppHwMode (Extension, FALSE);
  50. ParTerminateEppHwMode (Extension);
  51. if (NT_SUCCESS(Status)) {
  52. ParDump2(PARINFO, ("ParIsEppHwWriteSupported: Negotiated Supported Leaving\n"));
  53. Extension->ProtocolModesSupported |= EPP_HW;
  54. return TRUE;
  55. }
  56. ParDump2(PARINFO, ("ParIsEppHwWriteSupported: Not Negotiated Not Supported Leaving\n"));
  57. return FALSE;
  58. }
  59. NTSTATUS
  60. ParEnterEppHwMode(
  61. IN PDEVICE_EXTENSION Extension,
  62. IN BOOLEAN DeviceIdRequest
  63. )
  64. /*++
  65. Routine Description:
  66. This routine performs 1284 negotiation with the peripheral to the
  67. EPP mode protocol.
  68. Arguments:
  69. Controller - Supplies the port address.
  70. DeviceIdRequest - Supplies whether or not this is a request for a device
  71. id.
  72. Return Value:
  73. STATUS_SUCCESS - Successful negotiation.
  74. otherwise - Unsuccessful negotiation.
  75. --*/
  76. {
  77. NTSTATUS Status = STATUS_SUCCESS;
  78. // dvdr
  79. ParDump2(PARINFO, ("ParEnterEppHwMode: Entering\n"));
  80. if ( Extension->ModeSafety == SAFE_MODE ) {
  81. if (DeviceIdRequest) {
  82. // dvdr
  83. ParDump2(PARINFO, ("ParEnterEppHwMode: Calling IeeeEnter1284Mode with DEVICE_ID_REQUEST\n"));
  84. Status = IeeeEnter1284Mode (Extension, EPP_EXTENSIBILITY | DEVICE_ID_REQ);
  85. } else {
  86. // dvdr
  87. ParDump2(PARINFO, ("ParEnterEppHwMode: Calling IeeeEnter1284Mode\n"));
  88. Status = IeeeEnter1284Mode (Extension, EPP_EXTENSIBILITY);
  89. }
  90. } else {
  91. ParDump2(PARINFO, ("ParEnterEppHwMode: In UNSAFE_MODE.\n"));
  92. Extension->Connected = TRUE;
  93. }
  94. if (NT_SUCCESS(Status)) {
  95. Status = Extension->TrySetChipMode ( Extension->PortContext, ECR_EPP_PIO_MODE );
  96. if (NT_SUCCESS(Status)) {
  97. // dvdr
  98. ParDump2(PARINFO, ("ParEnterEppHwMode: IeeeEnter1284Mode returned success\n"));
  99. Extension->CurrentPhase = PHASE_FORWARD_IDLE;
  100. Extension->IsIeeeTerminateOk = TRUE;
  101. } else {
  102. ParDump2(PARINFO, ("ParEnterEppHwMode: TrySetChipMode returned unsuccessful\n"));
  103. ParTerminateEppHwMode ( Extension );
  104. Extension->CurrentPhase = PHASE_UNKNOWN;
  105. Extension->IsIeeeTerminateOk = FALSE;
  106. }
  107. } else {
  108. // dvdr
  109. ParDump2(PARINFO, ("ParEnterEppHwMode: IeeeEnter1284Mode returned unsuccessful\n"));
  110. Extension->CurrentPhase = PHASE_UNKNOWN;
  111. Extension->IsIeeeTerminateOk = FALSE;
  112. }
  113. ParDump2(PARINFO, ("ParEnterEppHwMode: Leaving with Status : %x \n", Status));
  114. return Status;
  115. }
  116. VOID
  117. ParTerminateEppHwMode(
  118. IN PDEVICE_EXTENSION Extension
  119. )
  120. /*++
  121. Routine Description:
  122. This routine terminates the interface back to compatibility mode.
  123. Arguments:
  124. Extension - The Device Extension which has the parallel port's controller address.
  125. Return Value:
  126. None.
  127. --*/
  128. {
  129. // dvdr
  130. ParDump2(PARINFO, ("ParTerminateEppMode: Entering\n"));
  131. Extension->ClearChipMode( Extension->PortContext, ECR_EPP_PIO_MODE );
  132. if ( Extension->ModeSafety == SAFE_MODE ) {
  133. IeeeTerminate1284Mode ( Extension );
  134. } else {
  135. ParDump2(PARINFO, ("ParTerminateEppMode: In UNSAFE_MODE.\n"));
  136. Extension->Connected = FALSE;
  137. }
  138. ParDump2(PARINFO, ("ParTerminateEppMode: Leaving\n"));
  139. return;
  140. }
  141. NTSTATUS
  142. ParEppHwWrite(
  143. IN PDEVICE_EXTENSION Extension,
  144. IN PVOID Buffer,
  145. IN ULONG BufferSize,
  146. OUT PULONG BytesTransferred
  147. )
  148. /*++
  149. Routine Description:
  150. Writes data to the peripheral using the EPP using Hardware flow control.
  151. Arguments:
  152. Extension - Supplies the device extension.
  153. Buffer - Supplies the buffer to write from.
  154. BufferSize - Supplies the number of bytes in the buffer.
  155. BytesTransferred - Returns the number of bytes transferred.
  156. Return Value:
  157. None.
  158. --*/
  159. {
  160. PUCHAR wPortEPP;
  161. PUCHAR pBuffer;
  162. ULONG ulongSize = 0; // represents how many ULONG's we are transfering if enabled
  163. // dvdr
  164. ParDump2(PARINFO, ("ParEppHwWrite: Entering\n"));
  165. wPortEPP = Extension->Controller + EPP_OFFSET;
  166. pBuffer = Buffer;
  167. Extension->CurrentPhase = PHASE_FORWARD_XFER;
  168. // Check to see if hardware supports 32 bit reads and writes
  169. if ( Extension->HardwareCapabilities & PPT_EPP_32_PRESENT ) {
  170. if ( !(BufferSize % 4) )
  171. ulongSize = BufferSize >> 2;
  172. }
  173. // ulongSize != 0 so EPP 32 bit is enabled and Buffersize / 4
  174. if ( ulongSize ) {
  175. WRITE_PORT_BUFFER_ULONG( (PULONG)wPortEPP,
  176. (PULONG)pBuffer,
  177. ulongSize );
  178. } else {
  179. WRITE_PORT_BUFFER_UCHAR( wPortEPP,
  180. (PUCHAR)pBuffer,
  181. BufferSize );
  182. }
  183. Extension->CurrentPhase = PHASE_FORWARD_IDLE;
  184. *BytesTransferred = BufferSize;
  185. // dvdr
  186. ParDump2(PARINFO, ("ParEppHwWrite: Leaving with %i Bytes Transferred\n", BufferSize));
  187. return STATUS_SUCCESS;
  188. }
  189. NTSTATUS
  190. ParEppHwRead(
  191. IN PDEVICE_EXTENSION Extension,
  192. IN PVOID Buffer,
  193. IN ULONG BufferSize,
  194. OUT PULONG BytesTransferred
  195. )
  196. /*++
  197. Routine Description:
  198. This routine performs a 1284 EPP mode read under software control
  199. into the given buffer for no more than 'BufferSize' bytes.
  200. Arguments:
  201. Extension - Supplies the device extension.
  202. Buffer - Supplies the buffer to read into.
  203. BufferSize - Supplies the number of bytes in the buffer.
  204. BytesTransferred - Returns the number of bytes transferred.
  205. --*/
  206. {
  207. PUCHAR wPortEPP;
  208. PUCHAR pBuffer;
  209. ULONG ulongSize = 0; // represents how many ULONG's we are transfering if enabled
  210. // dvdr
  211. ParDump2(PARINFO, ("ParEppHwRead: Entering\n"));
  212. wPortEPP = Extension->Controller + EPP_OFFSET;
  213. pBuffer = Buffer;
  214. Extension->CurrentPhase = PHASE_REVERSE_XFER;
  215. // Check to see if hardware supports 32 bit reads and writes
  216. if ( Extension->HardwareCapabilities & PPT_EPP_32_PRESENT ) {
  217. if ( !(BufferSize % 4) )
  218. ulongSize = BufferSize >> 2;
  219. }
  220. // ulongSize != 0 so EPP 32 bit is enabled and Buffersize / 4
  221. if ( ulongSize ) {
  222. READ_PORT_BUFFER_ULONG( (PULONG)wPortEPP,
  223. (PULONG)pBuffer,
  224. ulongSize );
  225. } else {
  226. READ_PORT_BUFFER_UCHAR( wPortEPP,
  227. (PUCHAR)pBuffer,
  228. BufferSize );
  229. }
  230. Extension->CurrentPhase = PHASE_FORWARD_IDLE;
  231. *BytesTransferred = BufferSize;
  232. // dvdr
  233. ParDump2(PARINFO, ("ParEppHwRead: Leaving with %i Bytes Transferred\n", BufferSize));
  234. return STATUS_SUCCESS;
  235. }