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.

305 lines
9.0 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1998 - 2000
  6. //
  7. // File: ppa3x.c
  8. //
  9. //--------------------------------------------------------------------------
  10. #include "pch.h"
  11. VOID
  12. PptLegacyZipClockDiskModeByte(
  13. PUCHAR Controller,
  14. UCHAR ModeByte
  15. )
  16. {
  17. P5WritePortUchar( Controller, ModeByte );
  18. P5WritePortUchar( Controller+DCR_OFFSET, (UCHAR)DCR_NOT_INIT );
  19. P5WritePortUchar( Controller+DCR_OFFSET, (UCHAR)(DCR_NOT_INIT | DCR_AUTOFEED) );
  20. P5WritePortUchar( Controller+DCR_OFFSET, (UCHAR)DCR_NOT_INIT );
  21. P5WritePortUchar( Controller+DCR_OFFSET, (UCHAR)(DCR_NOT_INIT | DCR_SELECT_IN) );
  22. } // end PptLegacyZipClockDiskModeByte()
  23. VOID
  24. PptLegacyZipClockPrtModeByte(
  25. PUCHAR Controller,
  26. UCHAR ModeByte
  27. )
  28. {
  29. P5WritePortUchar( Controller, ModeByte );
  30. P5WritePortUchar( Controller+DCR_OFFSET, (UCHAR)(DCR_SELECT_IN | DCR_NOT_INIT) );
  31. P5WritePortUchar( Controller+DCR_OFFSET, (UCHAR)(DCR_SELECT_IN | DCR_NOT_INIT | DCR_AUTOFEED) );
  32. P5WritePortUchar( Controller+DCR_OFFSET, (UCHAR)(DCR_SELECT_IN | DCR_NOT_INIT) );
  33. P5WritePortUchar( Controller+DCR_OFFSET, (UCHAR)DCR_NOT_INIT );
  34. P5WritePortUchar( Controller+DCR_OFFSET, (UCHAR)(DCR_SELECT_IN | DCR_NOT_INIT) );
  35. } // end PptLegacyZipClockPrtModeByte()
  36. VOID
  37. PptLegacyZipSetDiskMode(
  38. PUCHAR Controller,
  39. UCHAR Mode
  40. )
  41. {
  42. ULONG i;
  43. for ( i = 0; i < LEGACYZIP_MODE_LEN; i++ ) {
  44. PptLegacyZipClockDiskModeByte( Controller, LegacyZipModeQualifier[i] );
  45. }
  46. PptLegacyZipClockDiskModeByte( Controller, Mode );
  47. } // end of PptLegacyZipSetDiskMode()
  48. BOOLEAN
  49. PptLegacyZipCheckDevice(
  50. PUCHAR Controller
  51. )
  52. {
  53. P5WritePortUchar( Controller+DCR_OFFSET, (UCHAR)(DCR_NOT_INIT | DCR_AUTOFEED) );
  54. if ( (P5ReadPortUchar( Controller+DSR_OFFSET ) & DSR_NOT_FAULT) == DSR_NOT_FAULT ) {
  55. P5WritePortUchar( Controller+DCR_OFFSET, (UCHAR)DCR_NOT_INIT );
  56. if ( (P5ReadPortUchar( Controller+DSR_OFFSET ) & DSR_NOT_FAULT) != DSR_NOT_FAULT ) {
  57. // A device was found
  58. return TRUE;
  59. }
  60. }
  61. // No device is there
  62. return FALSE;
  63. } // end PptLegacyZipCheckDevice()
  64. NTSTATUS
  65. PptTrySelectLegacyZip(
  66. IN PVOID Context,
  67. IN PVOID TrySelectCommand
  68. )
  69. {
  70. PFDO_EXTENSION fdx = Context;
  71. PPARALLEL_1284_COMMAND Command = TrySelectCommand;
  72. NTSTATUS Status = STATUS_SUCCESS; // default success
  73. PUCHAR Controller = fdx->PortInfo.Controller;
  74. SYNCHRONIZED_COUNT_CONTEXT SyncContext;
  75. KIRQL CancelIrql;
  76. DD((PCE)fdx,DDT,"par12843::PptTrySelectLegacyZip - Enter\n");
  77. // test to see if we need to grab port
  78. if( !(Command->CommandFlags & PAR_HAVE_PORT_KEEP_PORT) ) {
  79. // Don't have the port
  80. //
  81. // Try to acquire port and select device
  82. //
  83. DD((PCE)fdx,DDT,"par12843::PptTrySelectLegacyZip Try get port.\n");
  84. IoAcquireCancelSpinLock(&CancelIrql);
  85. SyncContext.Count = &fdx->WorkQueueCount;
  86. if (fdx->InterruptRefCount) {
  87. KeSynchronizeExecution(fdx->InterruptObject,
  88. PptSynchronizedIncrement,
  89. &SyncContext);
  90. } else {
  91. PptSynchronizedIncrement(&SyncContext);
  92. }
  93. if (SyncContext.NewCount) {
  94. // Port is busy, queue request
  95. Status = STATUS_PENDING;
  96. } // endif - test for port busy
  97. IoReleaseCancelSpinLock(CancelIrql);
  98. } // endif - test if already have port
  99. //
  100. // If we have port select legacy Zip
  101. //
  102. if ( NT_SUCCESS( Status ) && (Status != STATUS_PENDING) ) {
  103. if ( Command->CommandFlags & PAR_LEGACY_ZIP_DRIVE_EPP_MODE ) {
  104. // Select in EPP mode
  105. PptLegacyZipSetDiskMode( Controller, (UCHAR)0xCF );
  106. } else {
  107. // Select in Nibble or Byte mode
  108. PptLegacyZipSetDiskMode( Controller, (UCHAR)0x8F );
  109. }
  110. if ( PptLegacyZipCheckDevice( Controller ) ) {
  111. DD((PCE)fdx,DDT,"par12843::PptTrySelectLegacyZip - SUCCESS\n");
  112. //
  113. // Legacy Zip is selected - test for EPP if we haven't previously done the test
  114. //
  115. if( !fdx->CheckedForGenericEpp ) {
  116. // haven't done the test yet
  117. if( fdx->PnpInfo.HardwareCapabilities & PPT_ECP_PRESENT ) {
  118. // we have an ECR - required for generic EPP
  119. if( !fdx->NationalChipFound ) {
  120. // we don't have a NationalSemi chipset - no generic EPP on NatSemi chips
  121. PptDetectEppPort( fdx );
  122. }
  123. }
  124. fdx->CheckedForGenericEpp = TRUE; // check is complete
  125. }
  126. } else {
  127. DD((PCE)fdx,DDT,"par12843::PptTrySelectLegacyZip - FAIL\n");
  128. PptDeselectLegacyZip( Context, TrySelectCommand );
  129. Status = STATUS_UNSUCCESSFUL;
  130. }
  131. }
  132. return( Status );
  133. } // end PptTrySelectLegacyZip()
  134. NTSTATUS
  135. PptDeselectLegacyZip(
  136. IN PVOID Context,
  137. IN PVOID DeselectCommand
  138. )
  139. {
  140. ULONG i;
  141. PFDO_EXTENSION fdx = Context;
  142. PUCHAR Controller = fdx->PortInfo.Controller;
  143. PPARALLEL_1284_COMMAND Command = DeselectCommand;
  144. DD((PCE)fdx,DDT,"par12843::PptDeselectLegacyZip - Enter\n");
  145. for ( i = 0; i < LEGACYZIP_MODE_LEN; i++ ) {
  146. PptLegacyZipClockPrtModeByte( Controller, LegacyZipModeQualifier[i] );
  147. }
  148. // set to printer pass thru mode
  149. PptLegacyZipClockPrtModeByte( Controller, (UCHAR)0x0F );
  150. // check if requester wants to keep port or free port
  151. if( !(Command->CommandFlags & PAR_HAVE_PORT_KEEP_PORT) ) {
  152. PptFreePort( fdx );
  153. }
  154. return STATUS_SUCCESS;
  155. } // end PptDeselectLegacyZip()
  156. VOID
  157. P5SelectLegacyZip(
  158. IN PUCHAR Controller
  159. )
  160. // select Legacy Zip drive in NIBBLE/BYTE mode - use this only for PnP
  161. // detection of drive so that drive will answer a subsequent check
  162. // drive command
  163. //
  164. // N.B. caller must own (lock for exclusive access) the port prior to
  165. // calling this function
  166. {
  167. PptLegacyZipSetDiskMode( Controller, (UCHAR)0x8F );
  168. }
  169. VOID
  170. P5DeselectLegacyZip(
  171. IN PUCHAR Controller
  172. )
  173. // deselect drive - set Legacy Zip drive to printer pass thru mode
  174. {
  175. ULONG i;
  176. for ( i = 0; i < LEGACYZIP_MODE_LEN; i++ ) {
  177. PptLegacyZipClockPrtModeByte( Controller, LegacyZipModeQualifier[i] );
  178. }
  179. PptLegacyZipClockPrtModeByte( Controller, (UCHAR)0x0F );
  180. P5WritePortUchar( Controller, 0 ); // set data wires back to zero
  181. }
  182. BOOLEAN
  183. P5LegacyZipDetected(
  184. IN PUCHAR Controller
  185. )
  186. // Detect Legacy Zip drive - return TRUE if Legacy Zip found on port, FALSE otherwise
  187. {
  188. BOOLEAN foundZip;
  189. // Try to select drive so that following CheckDevice will be able
  190. // to determine if there is a legacy zip connected
  191. P5SelectLegacyZip( Controller );
  192. // Try to talk to drive
  193. if( PptLegacyZipCheckDevice( Controller ) ) {
  194. foundZip = TRUE;
  195. } else {
  196. // no drive detected
  197. foundZip = FALSE;
  198. }
  199. // send deselect sequence whether we found the drive or not
  200. P5DeselectLegacyZip( Controller );
  201. return foundZip;
  202. }
  203. // parclass ppa3x.c follows
  204. PCHAR ParBuildLegacyZipDeviceId()
  205. {
  206. ULONG size = sizeof(PAR_LGZIP_PSEUDO_1284_ID_STRING) + sizeof(NULL);
  207. PCHAR id = ExAllocatePool(PagedPool, size);
  208. if( id ) {
  209. RtlZeroMemory( id, size );
  210. RtlCopyMemory( id, ParLegacyZipPseudoId, size - sizeof(NULL) );
  211. return id;
  212. } else {
  213. return NULL;
  214. }
  215. }
  216. PCHAR
  217. Par3QueryLegacyZipDeviceId(
  218. IN PPDO_EXTENSION Extension,
  219. OUT PCHAR CallerDeviceIdBuffer, OPTIONAL
  220. IN ULONG CallerBufferSize,
  221. OUT PULONG DeviceIdSize,
  222. IN BOOLEAN bReturnRawString // TRUE == include the 2 size bytes in the returned string
  223. // FALSE == discard the 2 size bytes
  224. )
  225. {
  226. USHORT deviceIdSize;
  227. PCHAR deviceIdBuffer;
  228. UNREFERENCED_PARAMETER( Extension );
  229. UNREFERENCED_PARAMETER( bReturnRawString );
  230. // initialize returned size in case we have an error
  231. *DeviceIdSize = 0;
  232. deviceIdBuffer = ParBuildLegacyZipDeviceId();
  233. if( !deviceIdBuffer ) {
  234. // error, likely out of resources
  235. return NULL;
  236. }
  237. deviceIdSize = (USHORT)strlen(deviceIdBuffer);
  238. *DeviceIdSize = deviceIdSize;
  239. if( (NULL != CallerDeviceIdBuffer) && (CallerBufferSize >= deviceIdSize) ) {
  240. // caller supplied buffer is large enough, use it
  241. RtlZeroMemory( CallerDeviceIdBuffer, CallerBufferSize );
  242. RtlCopyMemory( CallerDeviceIdBuffer, deviceIdBuffer, deviceIdSize );
  243. ExFreePool( deviceIdBuffer );
  244. return CallerDeviceIdBuffer;
  245. } else {
  246. // caller buffer too small, return pointer to our buffer
  247. return deviceIdBuffer;
  248. }
  249. }