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.

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