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.

1734 lines
48 KiB

  1. /*++
  2. Copyright (C) Microsoft Corporation, 1993 - 1999
  3. Module Name :
  4. parclass.h
  5. Abstract:
  6. Type definitions and data for the ParClass (parallel.sys) driver.
  7. Author:
  8. Revision History:
  9. --*/
  10. #include "ntddk.h" // Windows NT DDK header
  11. #include "parallel.h" // Public (driver) interface to ParPort
  12. #include "queue.h" // dvrh's Queue
  13. #include "test.h"
  14. // #include "log.h" - structure moved to ntddpar.h
  15. #include <wmilib.h>
  16. #define ASSERT_EVENT(E) { \
  17. ASSERT((E)->Header.Type == NotificationEvent || \
  18. (E)->Header.Type == SynchronizationEvent); \
  19. }
  20. #define REQUEST_DEVICE_ID TRUE
  21. #define HAVE_PORT_KEEP_PORT TRUE
  22. // enable scans for Legacy Zip?
  23. extern ULONG ParEnableLegacyZip;
  24. #define PAR_LGZIP_PSEUDO_1284_ID_STRING "MFG:IMG;CMD:;MDL:VP0;CLS:SCSIADAPTER;DES:IOMEGA PARALLEL PORT"
  25. extern PCHAR ParLegacyZipPseudoId;
  26. #define USE_PAR3QUERYDEVICEID 1
  27. // Disable IRQL Raising in Parclass
  28. // 0 - Run at passive
  29. // 1 - Run everything at dispatch
  30. // NOTE: SPP.c will still raise IRQL to dispatch regardless of this setting.
  31. // This has not changed since NT 3.51. Any takers?
  32. #define DVRH_RAISE_IRQL 0
  33. extern LARGE_INTEGER AcquirePortTimeout; // timeout for IOCTL_INTERNAL_PARALLEL_PORT_ALLOCATE
  34. extern ULONG g_NumPorts; // used to generate N in \Device\ParallelN ClassName
  35. extern UNICODE_STRING RegistryPath; // copy of the registry path passed to DriverEntry()
  36. extern ULONG DumpDevExtTable;
  37. // Driver Globals
  38. extern ULONG SppNoRaiseIrql; // 0 == original raise IRQL behavior in SPP
  39. // !0 == new behavior - disable raise IRQL
  40. // and insert some KeDelayExecutionThread
  41. // calls while waiting for peripheral response
  42. extern ULONG DefaultModes; // Upper USHORT is Reverse Default Mode, Lower is Forward Default Mode
  43. // if == 0, or invalid, then use default of Nibble/Centronics
  44. // used to slow down Spp writes to reduce CPU util caused by printing
  45. extern ULONG gSppLoopDelay; // how long to sleep each time we decide to do so (100ns units)
  46. extern ULONG gSppLoopBytesPerDelay; // how many bytes to write between sleeps
  47. //
  48. // Temporary Development Globals - used as switches in debug code
  49. //
  50. extern ULONG tdev1;
  51. extern ULONG tdev2;
  52. //
  53. // remove this after PnP stops calling us back multiple
  54. // times for the same interface arrival
  55. //
  56. #define USE_TEMP_FIX_FOR_MULTIPLE_INTERFACE_ARRIVAL 1
  57. #define PAR_USE_BUFFER_READ_WRITE 1 // Used to select between WRITE_PORT_BUFFER_UCHAR/READ_PORT_BUFFER_UCHAR vs WRITE_PORT_UCHAR/READ_PORT_UCHAR in hwecp.c
  58. #define DVRH_USE_CORRECT_PTRS 1
  59. #define PAR_NO_FAST_CALLS 1
  60. #if PAR_NO_FAST_CALLS
  61. VOID
  62. ParCompleteRequest(
  63. IN PIRP Irp,
  64. IN CCHAR PriorityBoost
  65. );
  66. NTSTATUS
  67. ParCallDriver(
  68. IN PDEVICE_OBJECT DeviceObject,
  69. IN OUT PIRP Irp
  70. );
  71. #else
  72. #define ParCompleteRequest(a,b) IoCompleteRequest(a,b)
  73. #define ParCallDriver(a,b) IoCallDriver(a,b)
  74. #endif
  75. #ifdef POOL_TAGGING
  76. #ifdef ExAllocatePool
  77. #undef ExAllocatePool
  78. #endif
  79. #define ExAllocatePool(a,b) ExAllocatePoolWithTag(a,b,'CraP')
  80. #endif
  81. #define PARCLASS_POOL_TAG (ULONG) 'CraP'
  82. // used as a check that this is a ParClass Device Extension
  83. // - used for debugging and by a ParClass debugger extension
  84. // - the value is arbitrary but must be consistent between the driver and the debugger extension
  85. #define PARCLASS_EXTENSION_SIGNATURE 0xA55AC33C
  86. // the following two variables are not currently used
  87. extern ULONG OpenCloseReferenceCount;// Keep track of Creates vs Closes
  88. extern PFAST_MUTEX OpenCloseMutex; // protect access to OpenCloseReferenceCount
  89. #if 0
  90. #define ParClaimDriver() \
  91. ExAcquireFastMutex(OpenCloseMutex); \
  92. if(++OpenCloseReferenceCount == 1) { \
  93. MmResetDriverPaging(DriverEntry); \
  94. } \
  95. ExReleaseFastMutex(OpenCloseMutex);
  96. #define ParReleaseDriver() \
  97. ExAcquireFastMutex(OpenCloseMutex); \
  98. if(--OpenCloseReferenceCount == 0) { \
  99. MmPageEntireDriver(DriverEntry); \
  100. } \
  101. ExReleaseFastMutex(OpenCloseMutex);
  102. #else
  103. #define ParClaimDriver()
  104. #define ParReleaseDriver()
  105. #endif
  106. extern const PHYSICAL_ADDRESS PhysicalZero;
  107. //
  108. // For the above directory, the serial port will
  109. // use the following name as the suffix of the serial
  110. // ports for that directory. It will also append
  111. // a number onto the end of the name. That number
  112. // will start at 1.
  113. //
  114. #define DEFAULT_PARALLEL_NAME L"LPT"
  115. //
  116. // This is the parallel class name.
  117. //
  118. #define DEFAULT_NT_SUFFIX L"Parallel"
  119. #define PARALLEL_DATA_OFFSET 0
  120. #define PARALLEL_STATUS_OFFSET 1
  121. #define PARALLEL_CONTROL_OFFSET 2
  122. #define PARALLEL_REGISTER_SPAN 3
  123. //
  124. // Ieee 1284 constants (Protocol Families)
  125. //
  126. #define FAMILY_NONE 0x0
  127. #define FAMILY_REVERSE_NIBBLE 0x1
  128. #define FAMILY_REVERSE_BYTE 0x2
  129. #define FAMILY_ECP 0x3
  130. #define FAMILY_EPP 0x4
  131. #define FAMILY_BECP 0x5
  132. #define FAMILY_MAX FAMILY_BECP
  133. //
  134. // For pnp id strings
  135. //
  136. #define MAX_ID_SIZE 256
  137. // used to construct IEEE 1284.3 "Dot" name suffixes
  138. // table lookup for integer to WCHAR conversion
  139. #define PAR_UNICODE_PERIOD L'.'
  140. #define PAR_UNICODE_COLON L':'
  141. //
  142. // DeviceStateFlags
  143. //
  144. #define PAR_DEVICE_STARTED ((ULONG)0x00000001)
  145. #define PAR_DEVICE_DELETED ((ULONG)0x00000002) // IoDeleteDevice has been called
  146. #define PAR_DEVICE_REMOVE_PENDING ((ULONG)0x00000004) // received QUERY_REMOVE, waiting for REMOVE or CANCEL
  147. #define PAR_DEVICE_REMOVED ((ULONG)0x00000008) // received REMOVE
  148. #define PAR_DEVICE_PAUSED ((ULONG)0x00000010) // stop-pending, stopped, or remove-pending states
  149. #define PAR_DEVICE_STOP_PENDING ((ULONG)0x00000020) // received QUERY_STOP
  150. #define PAR_DEVICE_DELETE_PENDING ((ULONG)0x00000040) // we have started the process of deleting device object
  151. #define PAR_DEVICE_HARDWARE_GONE ((ULONG)0x00000080) // our hardware is gone
  152. #define PAR_DEVICE_SURPRISE_REMOVAL ((ULONG)0x00000100) // we received a SURPRISE_REMOVAL
  153. #define PAR_DEVICE_PORT_REMOVE_PENDING ((ULONG)0x00000200) // our ParPort is in a Remove Pending State
  154. //#define PAR_REV_MODE_SKIP_MASK (CHANNEL_NIBBLE | BYTE_BIDIR | EPP_ANY)
  155. #define PAR_REV_MODE_SKIP_MASK (CHANNEL_NIBBLE | BYTE_BIDIR | EPP_ANY | ECP_ANY)
  156. #define PAR_FWD_MODE_SKIP_MASK (EPP_ANY | BOUNDED_ECP | ECP_HW_NOIRQ | ECP_HW_IRQ)
  157. //#define PAR_FWD_MODE_SKIP_MASK (EPP_ANY)
  158. #define PAR_MAX_CHANNEL 127
  159. #define PAR_COMPATIBILITY_RESET 300
  160. typedef struct _DOT3DL_PCTL {
  161. PVOID fnRead;
  162. PVOID fnWrite;
  163. PVOID fnReset;
  164. P12843_DL_MODES DataLinkMode;
  165. USHORT CurrentPID;
  166. USHORT FwdSkipMask;
  167. USHORT RevSkipMask;
  168. UCHAR DataChannel;
  169. UCHAR ResetChannel;
  170. UCHAR ResetByteCount;
  171. UCHAR ResetByte;
  172. PKEVENT Event;
  173. BOOLEAN bEventActive;
  174. } DOT3DL_PCTL, *PDOT3DL_PCTL;
  175. #if PAR_TEST_HARNESS
  176. typedef struct _PAR_HARNS_PCTL {
  177. PVOID fnRead;
  178. PVOID fnRevSetInterfaceAddress;
  179. PVOID fnEnterReverse;
  180. PVOID fnExitReverse;
  181. PVOID fnReadShadow;
  182. PVOID fnHaveReadData;
  183. PVOID fnWrite;
  184. PVOID fnFwdSetInterfaceAddress;
  185. PVOID fnEnterForward;
  186. PVOID fnExitForward;
  187. UNICODE_STRING deviceName;
  188. PDEVICE_OBJECT device;
  189. PFILE_OBJECT file;
  190. } PAR_HARNS_PCTL, *PPAR_HARNS_PCTL;
  191. #endif
  192. //
  193. // ParClass DeviceObject structure
  194. //
  195. // - Lists the ParClass created PODO and all PDOs associated with a specific ParPort device
  196. //
  197. typedef struct _PAR_DEVOBJ_STRUCT {
  198. PUCHAR Controller; // host controller address for devices in this structure
  199. PDEVICE_OBJECT LegacyPodo; // legacy or "raw" port device
  200. PDEVICE_OBJECT EndOfChainPdo; // End-Of-Chain PnP device
  201. PDEVICE_OBJECT Dot3Id0Pdo; // 1284.3 daisy chain device, 1284.3 deviceID == 0
  202. PDEVICE_OBJECT Dot3Id1Pdo;
  203. PDEVICE_OBJECT Dot3Id2Pdo;
  204. PDEVICE_OBJECT Dot3Id3Pdo; // 1284.3 daisy chain device, 1284.3 deviceID == 3
  205. PDEVICE_OBJECT LegacyZipPdo; // Legacy Zip Drive
  206. PFILE_OBJECT pFileObject; // Need an open handle to ParPort device to prevent it
  207. // from being removed out from under us
  208. struct _PAR_DEVOBJ_STRUCT *Next;
  209. } PAR_DEVOBJ_STRUCT, *PPAR_DEVOBJ_STRUCT;
  210. //
  211. // Used in device extension for DeviceType field
  212. //
  213. #define PAR_DEVTYPE_FDO 0x00000001
  214. #define PAR_DEVTYPE_PODO 0x00000002
  215. #define PAR_DEVTYPE_PDO 0x00000004
  216. //
  217. // ParClass Device Extension:
  218. // - This is a common structure for ParClass (parallel.sys) FDO, PDOs, and PODOs.
  219. // - Fields that are not used by a particular type of device object are 0, NULL, or FALSE.
  220. // - FDO == field used by Function Device Object
  221. // - PDO == field used by Physical Device Objects
  222. // - PODO == field used by Plain Old Device Objects - similar to a PDOs but no
  223. // device ID and is not reported to or known by PnP
  224. // - P[O]DO == field used by PDOs and PODOs
  225. // - no mark == field used by all three types of ParClass device objects
  226. //
  227. typedef struct _DEVICE_EXTENSION {
  228. ULONG ExtensionSignature; // Used to increase our confidence that this is a ParClass extension
  229. ULONG DeviceType; // PAR_DEVTYPE_FDO=0x1, PODO=0x2, or PDO=0x4
  230. ULONG DeviceStateFlags; // Device State - See Device State Flags above
  231. UCHAR Ieee1284_3DeviceId; // PDO - 0..3 is 1284.3 Daisy Chain device, 4 is End-Of-Chain Device, 5 is Legacy Zip
  232. BOOLEAN IsPdo; // TRUE == this is either a PODO or a PDO - use DeviceIdString[0] to distinguish
  233. BOOLEAN EndOfChain; // PODO - TRUE==NOT a 1284.3 daisy chain device - deprecated, use Ieee1284_3DeviceId==4 instead
  234. BOOLEAN PodoRegForWMI; // has this PODO registered for WMI callbacks?
  235. // 0x10 on x86
  236. PDEVICE_OBJECT ParClassFdo; // P[O]DO - points to the ParClass FDO
  237. PDEVICE_OBJECT ParClassPdo; // FDO - points to first P[O]DO in list of ParClass created PODOs and PDOs
  238. PDEVICE_OBJECT Next; // P[O]DO - points to the next DO in the list of ParClass ejected P[O]DOs
  239. PDEVICE_OBJECT DeviceObject;// back pointer to our device object
  240. // 0x20 on x86
  241. PDEVICE_OBJECT PortDeviceObject; // P[O]DO - points to the associated ParPort device object
  242. PFILE_OBJECT PortDeviceFileObject;// P[O]DO - referenced pointer to a FILE created against PortDeviceObject
  243. UNICODE_STRING PortSymbolicLinkName;// P[O]DO - Symbolic link name of the associated ParPort device - used to open a FILE
  244. // 0x30 on x86
  245. PDEVICE_OBJECT PhysicalDeviceObject;// FDO - The PDO passed to ParPnPAddDevice
  246. PDEVICE_OBJECT ParentDeviceObject; // FDO - parent DO returned by IoAttachDeviceToDeviceStack
  247. PIRP CurrentOpIrp; // IRP that our thread is currently processing
  248. PVOID NotificationHandle; // PlugPlay Notification Handle
  249. // 0x40 on x86
  250. UNICODE_STRING ClassName; // P[O]DO - ClassName passed to IoCreateDevice() as DeviceName
  251. UNICODE_STRING SymbolicLinkName; // P[O]DO - SymbolicLinkName linked to ClassName using IoCreateUnprotectedSymbolicLink()
  252. // 0x50 on x86
  253. ULONG TimerStart; // initial value used for countdown when starting an operation
  254. BOOLEAN CreatedSymbolicLink; // P[O]DO - did we create a Symbolic Link for this device?
  255. BOOLEAN UsePIWriteLoop; // P[O]DO - do we want to use processor independant write loop?
  256. BOOLEAN Initialized; // FALSE == we think that the device needs to be initialized
  257. //
  258. // Set to true before the deferred initialization routine is run
  259. // and false once it has completed. Used to synchronize the deferred
  260. // initialization worker thread and the parallel port thread
  261. //
  262. BOOLEAN Initializing;
  263. LONG OpenCloseRefCount; // count of Creates vs Closes - number of open FILEs against us,
  264. // used for QUERY_REMOVE decision: SUCCEED if count == 0, otherwise FAIL
  265. BOOLEAN ParPortDeviceGone; // Is our ParPort device object gone, possibly surprise removed?
  266. BOOLEAN RegForPptRemovalRelations; // Are we registered for ParPort removal relations?
  267. UCHAR Ieee1284Flags; // is device Stl older 1284.3 spec device?
  268. UCHAR spare1; // return to dword alignment
  269. // 0x60 on x86
  270. USHORT IdxForwardProtocol; // see afpForward[] in ieee1284.c
  271. USHORT IdxReverseProtocol; // see arpReverse[] in ieee1284.c
  272. ULONG CurrentEvent; // IEEE 1284 event - see IEEE 1284-1994 spec
  273. P1284_PHASE CurrentPhase; // see parallel.h for enum def - PHASE_UNKNOWN, ..., PHASE_INTERRUPT_HOST
  274. P1284_HW_MODE PortHWMode; // see parallel.h for enum def - HW_MODE_COMPATIBILITY, ..., HW_MODE_CONFIGURATION
  275. // 0x70 on x86
  276. FAST_MUTEX OpenCloseMutex; // protect manipulation of OpenCloseRefCount
  277. // 0x90 on x86
  278. FAST_MUTEX DevObjListMutex; // protect manipulation of list of ParClass ejected DOs
  279. // 0xb0 on x86
  280. LIST_ENTRY WorkQueue; // Queue of irps waiting to be processed.
  281. PVOID ThreadObjectPointer; // pointer to a worker thread for this Device
  282. KSEMAPHORE RequestSemaphore;// dispatch routines use this to tell device worker thread that there is work to do
  283. //
  284. // PARALLEL_PORT_INFORMATION returned by IOCTL_INTERNAL_GET_PARALLEL_PORT_INFO
  285. //
  286. PHYSICAL_ADDRESS OriginalController;
  287. PUCHAR Controller;
  288. PUCHAR EcrController;
  289. ULONG SpanOfController;
  290. PPARALLEL_TRY_ALLOCATE_ROUTINE TryAllocatePort; // nonblocking callback to allocate ParPort device
  291. PPARALLEL_FREE_ROUTINE FreePort; // callback to free ParPort device
  292. PPARALLEL_QUERY_WAITERS_ROUTINE QueryNumWaiters; // callback to query number of waiters in port allocation queue
  293. PVOID PortContext; // context for callbacks to ParPort
  294. //
  295. // subset of PARALLEL_PNP_INFORMATION returned by IOCTL_INTERNAL_GET_PARALLEL_PNP_INFO
  296. //
  297. ULONG HardwareCapabilities;
  298. PPARALLEL_SET_CHIP_MODE TrySetChipMode;
  299. PPARALLEL_CLEAR_CHIP_MODE ClearChipMode;
  300. PPARALLEL_TRY_SELECT_ROUTINE TrySelectDevice;
  301. PPARALLEL_DESELECT_ROUTINE DeselectDevice;
  302. ULONG FifoDepth;
  303. ULONG FifoWidth;
  304. BOOLEAN bAllocated; // have we allocated associated ParPort device?
  305. // Note: during some PnP processing we may have the port
  306. // for a short duration without setting this value to TRUE
  307. ULONG BusyDelay; // number of microseconds to wait after strobing a byte before checking the BUSY line.
  308. BOOLEAN BusyDelayDetermined;// Indicates if the BusyDelay parameter has been computed yet.
  309. PWORK_QUEUE_ITEM DeferredWorkItem; // Holds the work item used to defer printer initialization
  310. BOOLEAN TimeToTerminateThread; // TRUE == Thread should kill itself via PsTerminateSystemThread()
  311. // If the registry entry by the same name is set, run the parallel
  312. // thread at the priority we used for NT 3.5 - this solves some
  313. // cases where a dos app spinning for input in the foreground is
  314. // starving the parallel thread
  315. BOOLEAN UseNT35Priority;
  316. ULONG InitializationTimeout;// timeout in seconds to wait for device to respond to an initialization request
  317. // - default == 15 seconds
  318. // - value overridden by registry entry of same name
  319. // - we will spin for max amount if no device attached
  320. LARGE_INTEGER AbsoluteOneSecond;// constants that are cheaper to put here rather
  321. LARGE_INTEGER OneSecond; // than in bss
  322. //
  323. // IEEE 1284 Mode support
  324. //
  325. BOOLEAN Connected; // are we currently negotiated into a 1284 mode?
  326. BOOLEAN AllocatedByLockPort; // are we currently allocated via IOCTL_INTERNAL_LOCK_PORT?
  327. USHORT spare4[2];
  328. #if (1 == DVRH_USE_CORRECT_PTRS)
  329. PVOID fnRead; // Current pointer to a valid read funtion
  330. PVOID fnWrite; // Current pointer to a valid write Funtion
  331. #endif
  332. LARGE_INTEGER IdleTimeout; // how long do we hold the port on the caller's behalf following an operation?
  333. USHORT ProtocolData[FAMILY_MAX];
  334. UCHAR ForwardInterfaceAddress;
  335. UCHAR ReverseInterfaceAddress;
  336. BOOLEAN SetForwardAddress;
  337. BOOLEAN SetReverseAddress;
  338. FAST_MUTEX LockPortMutex;
  339. DEVICE_POWER_STATE DeviceState;// Current Device Power State
  340. SYSTEM_POWER_STATE SystemState;// Current System Power State
  341. ULONG spare2;
  342. BOOLEAN bShadowBuffer;
  343. Queue ShadowBuffer;
  344. ULONG spare3;
  345. BOOLEAN bSynchWrites; // TRUE if ECP HW writes should be synchronous
  346. BOOLEAN bFirstByteTimeout; // TRUE if bus just reversed, means give the
  347. // device some time to respond with some data
  348. BOOLEAN bIsHostRecoverSupported; // Set via IOCTL_PAR_ECP_HOST_RECOVERY.
  349. // HostRecovery will not be utilized unless this bit is set
  350. KEVENT PauseEvent; // PnP dispatch routine uses this to pause worker thread during
  351. // during QUERY_STOP, STOP, and QUERY_REMOVE states
  352. USHORT ProtocolModesSupported;
  353. USHORT BadProtocolModes;
  354. PARALLEL_SAFETY ModeSafety;
  355. BOOLEAN IsIeeeTerminateOk;
  356. BOOLEAN IsCritical;
  357. DOT3DL_PCTL P12843DL;
  358. // WMI
  359. PARALLEL_WMI_LOG_INFO log;
  360. WMILIB_CONTEXT WmiLibContext;
  361. LONG WmiRegistrationCount; // number of times this device has registered with WMI
  362. // PnP Query ID results
  363. UCHAR DeviceIdString[MAX_ID_SIZE]; // IEEE 1284 DeviceID string massaged/checksum'd to match INF form
  364. UCHAR DeviceDescription[MAX_ID_SIZE]; // "Manufacturer<SPACE>Model" from IEEE 1284 DeviceID string
  365. #if PAR_TEST_HARNESS
  366. PAR_HARNS_PCTL ParTestHarness;
  367. #endif
  368. ULONG dummy; // dummy word to force RemoveLock to QuadWord alignment
  369. IO_REMOVE_LOCK RemoveLock; // FDO - insure that other IRPs drain before FDO processes REMOVE_DEVICE
  370. PVOID HwProfileChangeNotificationHandle;
  371. ULONG ExtensionSignatureEnd; // keep this the last member in extension
  372. } DEVICE_EXTENSION, *PDEVICE_EXTENSION;
  373. //
  374. // Protocol structure definitions
  375. //
  376. typedef
  377. BOOLEAN
  378. (*PPROTOCOL_IS_MODE_SUPPORTED_ROUTINE) (
  379. IN PDEVICE_EXTENSION Extension
  380. );
  381. typedef
  382. NTSTATUS
  383. (*PPROTOCOL_CONNECT_ROUTINE) (
  384. IN PDEVICE_EXTENSION Extension,
  385. IN BOOLEAN DeviceIdRequest
  386. );
  387. typedef
  388. VOID
  389. (*PPROTOCOL_DISCONNECT_ROUTINE) (
  390. IN PDEVICE_EXTENSION Extension
  391. );
  392. typedef
  393. NTSTATUS
  394. (*PPROTOCOL_ENTER_FORWARD_ROUTINE) (
  395. IN PDEVICE_EXTENSION Extension
  396. );
  397. typedef
  398. NTSTATUS
  399. (*PPROTOCOL_EXIT_FORWARD_ROUTINE) (
  400. IN PDEVICE_EXTENSION Extension
  401. );
  402. typedef
  403. NTSTATUS
  404. (*PPROTOCOL_ENTER_REVERSE_ROUTINE) (
  405. IN PDEVICE_EXTENSION Extension
  406. );
  407. typedef
  408. NTSTATUS
  409. (*PPROTOCOL_EXIT_REVERSE_ROUTINE) (
  410. IN PDEVICE_EXTENSION Extension
  411. );
  412. typedef
  413. NTSTATUS
  414. (*PPROTOCOL_READ_ROUTINE) (
  415. IN PDEVICE_EXTENSION Extension,
  416. IN PVOID Buffer,
  417. IN ULONG BufferSize,
  418. OUT PULONG BytesTransferred
  419. );
  420. typedef
  421. VOID
  422. (*PPROTOCOL_READSHADOW_ROUTINE) (
  423. IN Queue *pShadowBuffer,
  424. IN PUCHAR lpsBufPtr,
  425. IN ULONG dCount,
  426. OUT ULONG *fifoCount
  427. );
  428. typedef
  429. BOOLEAN
  430. (*PPROTOCOL_HAVEREADDATA_ROUTINE) (
  431. IN PDEVICE_EXTENSION Extension
  432. );
  433. typedef
  434. NTSTATUS
  435. (*PPROTOCOL_WRITE_ROUTINE) (
  436. IN PDEVICE_EXTENSION Extension,
  437. IN PVOID Buffer,
  438. IN ULONG BufferSize,
  439. OUT PULONG BytesTransferred
  440. );
  441. typedef
  442. NTSTATUS
  443. (*PPROTOCOL_SET_INTERFACE_ADDRESS_ROUTINE) (
  444. IN PDEVICE_EXTENSION Extension,
  445. IN UCHAR Address
  446. );
  447. typedef struct _FORWARD_PTCL {
  448. PPROTOCOL_IS_MODE_SUPPORTED_ROUTINE fnIsModeSupported;
  449. PPROTOCOL_CONNECT_ROUTINE fnConnect;
  450. PPROTOCOL_DISCONNECT_ROUTINE fnDisconnect;
  451. PPROTOCOL_SET_INTERFACE_ADDRESS_ROUTINE fnSetInterfaceAddress;
  452. PPROTOCOL_ENTER_FORWARD_ROUTINE fnEnterForward;
  453. PPROTOCOL_EXIT_FORWARD_ROUTINE fnExitForward;
  454. PPROTOCOL_WRITE_ROUTINE fnWrite;
  455. USHORT Protocol;
  456. USHORT ProtocolFamily;
  457. } FORWARD_PTCL, *PFORWARD_PTCL;
  458. typedef struct _REVERSE_PTCL {
  459. PPROTOCOL_IS_MODE_SUPPORTED_ROUTINE fnIsModeSupported;
  460. PPROTOCOL_CONNECT_ROUTINE fnConnect;
  461. PPROTOCOL_DISCONNECT_ROUTINE fnDisconnect;
  462. PPROTOCOL_SET_INTERFACE_ADDRESS_ROUTINE fnSetInterfaceAddress;
  463. PPROTOCOL_ENTER_REVERSE_ROUTINE fnEnterReverse;
  464. PPROTOCOL_EXIT_REVERSE_ROUTINE fnExitReverse;
  465. PPROTOCOL_READSHADOW_ROUTINE fnReadShadow;
  466. PPROTOCOL_HAVEREADDATA_ROUTINE fnHaveReadData;
  467. PPROTOCOL_READ_ROUTINE fnRead;
  468. USHORT Protocol;
  469. USHORT ProtocolFamily;
  470. } REVERSE_PTCL, *PREVERSE_PTCL;
  471. extern FORWARD_PTCL afpForward[];
  472. extern REVERSE_PTCL arpReverse[];
  473. //
  474. // WARNING...Make sure that enumeration matches the protocol array...
  475. //
  476. typedef enum _FORWARD_MODE {
  477. FORWARD_FASTEST = 0,
  478. BOUNDED_ECP_FORWARD = FORWARD_FASTEST,
  479. ECP_HW_FORWARD_NOIRQ,
  480. EPP_HW_FORWARD,
  481. EPP_SW_FORWARD,
  482. ECP_SW_FORWARD,
  483. IEEE_COMPAT_MODE,
  484. CENTRONICS_MODE,
  485. FORWARD_NONE
  486. } FORWARD_MODE;
  487. typedef enum _REVERSE_MODE {
  488. REVERSE_FASTEST = 0,
  489. BOUNDED_ECP_REVERSE = REVERSE_FASTEST,
  490. ECP_HW_REVERSE_NOIRQ,
  491. EPP_HW_REVERSE,
  492. EPP_SW_REVERSE,
  493. ECP_SW_REVERSE,
  494. BYTE_MODE,
  495. NIBBLE_MODE,
  496. CHANNELIZED_NIBBLE_MODE,
  497. REVERSE_NONE
  498. } REVERSE_MODE;
  499. //
  500. // Ieee Extensibility constants
  501. //
  502. #define NIBBLE_EXTENSIBILITY 0x00
  503. #define BYTE_EXTENSIBILITY 0x01
  504. #define CHANNELIZED_EXTENSIBILITY 0x08
  505. #define ECP_EXTENSIBILITY 0x10
  506. #define BECP_EXTENSIBILITY 0x18
  507. #define EPP_EXTENSIBILITY 0x40
  508. #define DEVICE_ID_REQ 0x04
  509. //
  510. // Bit Definitions in the status register.
  511. //
  512. #define PAR_STATUS_NOT_ERROR 0x08 //not error on device
  513. #define PAR_STATUS_SLCT 0x10 //device is selected (on-line)
  514. #define PAR_STATUS_PE 0x20 //paper empty
  515. #define PAR_STATUS_NOT_ACK 0x40 //not acknowledge (data transfer was not ok)
  516. #define PAR_STATUS_NOT_BUSY 0x80 //operation in progress
  517. //
  518. // Bit Definitions in the control register.
  519. //
  520. #define PAR_CONTROL_STROBE 0x01 //to read or write data
  521. #define PAR_CONTROL_AUTOFD 0x02 //to autofeed continuous form paper
  522. #define PAR_CONTROL_NOT_INIT 0x04 //begin an initialization routine
  523. #define PAR_CONTROL_SLIN 0x08 //to select the device
  524. #define PAR_CONTROL_IRQ_ENB 0x10 //to enable interrupts
  525. #define PAR_CONTROL_DIR 0x20 //direction = read
  526. #define PAR_CONTROL_WR_CONTROL 0xc0 //the 2 highest bits of the control
  527. // register must be 1
  528. //
  529. // More bit definitions.
  530. //
  531. #define DATA_OFFSET 0
  532. #define DSR_OFFSET 1
  533. #define DCR_OFFSET 2
  534. #define OFFSET_DATA DATA_OFFSET // Put in for compatibility with legacy code
  535. #define OFFSET_DSR DSR_OFFSET // Put in for compatibility with legacy code
  536. #define OFFSET_DCR DCR_OFFSET // Put in for compatibility with legacy code
  537. //
  538. // Bit definitions for the DSR.
  539. //
  540. #define DSR_NOT_BUSY 0x80
  541. #define DSR_NOT_ACK 0x40
  542. #define DSR_PERROR 0x20
  543. #define DSR_SELECT 0x10
  544. #define DSR_NOT_FAULT 0x08
  545. //
  546. // More bit definitions for the DSR.
  547. //
  548. #define DSR_NOT_PTR_BUSY 0x80
  549. #define DSR_NOT_PERIPH_ACK 0x80
  550. #define DSR_WAIT 0x80
  551. #define DSR_PTR_CLK 0x40
  552. #define DSR_PERIPH_CLK 0x40
  553. #define DSR_INTR 0x40
  554. #define DSR_ACK_DATA_REQ 0x20
  555. #define DSR_NOT_ACK_REVERSE 0x20
  556. #define DSR_XFLAG 0x10
  557. #define DSR_NOT_DATA_AVAIL 0x08
  558. #define DSR_NOT_PERIPH_REQUEST 0x08
  559. //
  560. // Bit definitions for the DCR.
  561. //
  562. #define DCR_RESERVED 0xC0
  563. #define DCR_DIRECTION 0x20
  564. #define DCR_ACKINT_ENABLED 0x10
  565. #define DCR_SELECT_IN 0x08
  566. #define DCR_NOT_INIT 0x04
  567. #define DCR_AUTOFEED 0x02
  568. #define DCR_STROBE 0x01
  569. //
  570. // More bit definitions for the DCR.
  571. //
  572. #define DCR_NOT_1284_ACTIVE 0x08
  573. #define DCR_ASTRB 0x08
  574. #define DCR_NOT_REVERSE_REQUEST 0x04
  575. #define DCR_NOT_HOST_BUSY 0x02
  576. #define DCR_NOT_HOST_ACK 0x02
  577. #define DCR_DSTRB 0x02
  578. #define DCR_NOT_HOST_CLK 0x01
  579. #define DCR_WRITE 0x01
  580. #define DCR_NEUTRAL (DCR_RESERVED | DCR_SELECT_IN | DCR_NOT_INIT)
  581. //
  582. // Give a timeout of 300 seconds. Some postscript printers will
  583. // buffer up a lot of commands then proceed to render what they
  584. // have. The printer will then refuse to accept any characters
  585. // until it's done with the rendering. This render process can
  586. // take a while. We'll give it 300 seconds.
  587. //
  588. // Note that an application can change this value.
  589. //
  590. #define PAR_WRITE_TIMEOUT_VALUE 300
  591. #ifdef JAPAN // IBM-J printers
  592. //
  593. // Support for IBM-J printers.
  594. //
  595. // When the printer operates in Japanese (PS55) mode, it redefines
  596. // the meaning of parallel lines so that extended error status can
  597. // be reported. It is roughly compatible with PC/AT, but we have to
  598. // take care of a few cases where the status looks like PC/AT error
  599. // condition.
  600. //
  601. // Status Busy /AutoFdXT Paper Empty Select /Fault
  602. // ------ ---- --------- ----------- ------ ------
  603. // Not RMR 1 1 1 1 1
  604. // Head Alarm 1 1 1 1 0
  605. // ASF Jam 1 1 1 0 0
  606. // Paper Empty 1 0 1 0 0
  607. // No Error 0 0 0 1 1
  608. // Can Req 1 0 0 0 1
  609. // Deselect 1 0 0 0 0
  610. //
  611. // The printer keeps "Not RMR" during the parallel port
  612. // initialization, then it takes "Paper Empty", "No Error"
  613. // or "Deselect". Other status can be thought as an
  614. // H/W error condition.
  615. //
  616. // Namely, "Not RMR" conflicts with PAR_NO_CABLE and "Deselect"
  617. // should also be regarded as another PAR_OFF_LINE. When the
  618. // status is PAR_PAPER_EMPTY, the initialization is finished
  619. // (we should not send init purlse again.)
  620. //
  621. // See ParInitializeDevice() for more information.
  622. //
  623. // [takashim]
  624. #define PAR_OFF_LINE_COMMON( Status ) ( \
  625. (IsNotNEC_98) ? \
  626. (Status & PAR_STATUS_NOT_ERROR) && \
  627. ((Status & PAR_STATUS_NOT_BUSY) ^ PAR_STATUS_NOT_BUSY) && \
  628. !(Status & PAR_STATUS_SLCT) : \
  629. \
  630. ((Status & PAR_STATUS_NOT_ERROR) ^ PAR_STATUS_NOT_ERROR) && \
  631. ((Status & PAR_STATUS_NOT_BUSY) ^ PAR_STATUS_NOT_BUSY) && \
  632. ((Status & PAR_STATUS_PE) ^ PAR_STATUS_PE) && \
  633. !(Status & PAR_STATUS_SLCT) \
  634. )
  635. #define PAR_OFF_LINE_IBM55( Status ) ( \
  636. ((Status & PAR_STATUS_NOT_BUSY) ^ PAR_STATUS_NOT_BUSY) && \
  637. ((Status & PAR_STATUS_PE) ^ PAR_STATUS_PE) && \
  638. ((Status & PAR_STATUS_SLCT) ^ PAR_STATUS_SLCT) && \
  639. ((Status & PAR_STATUS_NOT_ERROR) ^ PAR_STATUS_NOT_ERROR))
  640. #define PAR_PAPER_EMPTY2( Status ) ( \
  641. ((Status & PAR_STATUS_NOT_BUSY) ^ PAR_STATUS_NOT_BUSY) && \
  642. (Status & PAR_STATUS_PE) && \
  643. ((Status & PAR_STATUS_SLCT) ^ PAR_STATUS_SLCT) && \
  644. ((Status & PAR_STATUS_NOT_ERROR) ^ PAR_STATUS_NOT_ERROR))
  645. //
  646. // Redefine this for Japan.
  647. //
  648. #define PAR_OFF_LINE( Status ) ( \
  649. PAR_OFF_LINE_COMMON( Status ) || \
  650. PAR_OFF_LINE_IBM55( Status ))
  651. #else // JAPAN
  652. //
  653. // Busy, not select, not error
  654. //
  655. // !JAPAN
  656. #define PAR_OFF_LINE( Status ) ( \
  657. (IsNotNEC_98) ? \
  658. (Status & PAR_STATUS_NOT_ERROR) && \
  659. ((Status & PAR_STATUS_NOT_BUSY) ^ PAR_STATUS_NOT_BUSY) && \
  660. !(Status & PAR_STATUS_SLCT) : \
  661. \
  662. ((Status & PAR_STATUS_NOT_ERROR) ^ PAR_STATUS_NOT_ERROR) && \
  663. ((Status & PAR_STATUS_NOT_BUSY) ^ PAR_STATUS_NOT_BUSY) && \
  664. ((Status & PAR_STATUS_PE) ^ PAR_STATUS_PE) && \
  665. !(Status & PAR_STATUS_SLCT) \
  666. )
  667. #endif // JAPAN
  668. //
  669. // Busy, PE
  670. //
  671. #define PAR_PAPER_EMPTY( Status ) ( \
  672. (Status & PAR_STATUS_PE) )
  673. //
  674. // error, ack, not busy
  675. //
  676. #define PAR_POWERED_OFF( Status ) ( \
  677. (IsNotNEC_98) ? \
  678. ((Status & PAR_STATUS_NOT_ERROR) ^ PAR_STATUS_NOT_ERROR) && \
  679. ((Status & PAR_STATUS_NOT_ACK) ^ PAR_STATUS_NOT_ACK) && \
  680. (Status & PAR_STATUS_NOT_BUSY) : \
  681. \
  682. ((Status & PAR_STATUS_NOT_ERROR) ^ PAR_STATUS_NOT_ERROR) && \
  683. (Status & PAR_STATUS_NOT_ACK) && \
  684. (Status & PAR_STATUS_NOT_BUSY) \
  685. )
  686. //
  687. // not error, not busy, not select
  688. //
  689. #define PAR_NOT_CONNECTED( Status ) ( \
  690. (Status & PAR_STATUS_NOT_ERROR) && \
  691. (Status & PAR_STATUS_NOT_BUSY) &&\
  692. !(Status & PAR_STATUS_SLCT) )
  693. //
  694. // not error, not busy
  695. //
  696. #define PAR_OK(Status) ( \
  697. (Status & PAR_STATUS_NOT_ERROR) && \
  698. ((Status & PAR_STATUS_PE) ^ PAR_STATUS_PE) && \
  699. (Status & PAR_STATUS_NOT_BUSY) )
  700. //
  701. // busy, select, not error
  702. //
  703. #define PAR_POWERED_ON(Status) ( \
  704. ((Status & PAR_STATUS_NOT_BUSY) ^ PAR_STATUS_NOT_BUSY) && \
  705. (Status & PAR_STATUS_SLCT) && \
  706. (Status & PAR_STATUS_NOT_ERROR))
  707. //
  708. // busy, not error
  709. //
  710. #define PAR_BUSY(Status) (\
  711. (( Status & PAR_STATUS_NOT_BUSY) ^ PAR_STATUS_NOT_BUSY) && \
  712. ( Status & PAR_STATUS_NOT_ERROR ) )
  713. //
  714. // selected
  715. //
  716. #define PAR_SELECTED(Status) ( \
  717. ( Status & PAR_STATUS_SLCT ) )
  718. //
  719. // No cable attached.
  720. //
  721. #define PAR_NO_CABLE(Status) ( \
  722. (IsNotNEC_98) ? \
  723. ((Status & PAR_STATUS_NOT_BUSY) ^ PAR_STATUS_NOT_BUSY) && \
  724. (Status & PAR_STATUS_NOT_ACK) && \
  725. (Status & PAR_STATUS_PE) && \
  726. (Status & PAR_STATUS_SLCT) && \
  727. (Status & PAR_STATUS_NOT_ERROR) : \
  728. \
  729. (Status & PAR_STATUS_NOT_BUSY) && \
  730. (Status & PAR_STATUS_NOT_ACK) && \
  731. (Status & PAR_STATUS_PE) && \
  732. (Status & PAR_STATUS_SLCT) && \
  733. (Status & PAR_STATUS_NOT_ERROR) \
  734. )
  735. //
  736. // not error, not busy, selected.
  737. //
  738. #define PAR_ONLINE(Status) ( \
  739. (Status & PAR_STATUS_NOT_ERROR) && \
  740. (Status & PAR_STATUS_NOT_BUSY) && \
  741. ((Status & PAR_STATUS_PE) ^ PAR_STATUS_PE) && \
  742. (Status & PAR_STATUS_SLCT) )
  743. //BOOLEAN
  744. //ParCompareGuid(
  745. // IN LPGUID guid1,
  746. // IN LPGUID guid2
  747. // )
  748. //
  749. #define ParCompareGuid(g1, g2) ( \
  750. ( (g1) == (g2) ) ? \
  751. TRUE : \
  752. RtlCompareMemory( (g1), (g2), sizeof(GUID) ) == sizeof(GUID) \
  753. )
  754. //VOID StoreData(
  755. // IN PUCHAR RegisterBase,
  756. // IN UCHAR DataByte
  757. // )
  758. // Data must be on line before Strobe = 1;
  759. // Strobe = 1, DIR = 0
  760. // Strobe = 0
  761. //
  762. // We change the port direction to output (and make sure stobe is low).
  763. //
  764. // Note that the data must be available at the port for at least
  765. // .5 microseconds before and after you strobe, and that the strobe
  766. // must be active for at least 500 nano seconds. We are going
  767. // to end up stalling for twice as much time as we need to, but, there
  768. // isn't much we can do about that.
  769. //
  770. // We put the data into the port and wait for 1 micro.
  771. // We strobe the line for at least 1 micro
  772. // We lower the strobe and again delay for 1 micro
  773. // We then revert to the original port direction.
  774. //
  775. // Thanks to Olivetti for advice.
  776. //
  777. #define StoreData(RegisterBase,DataByte) \
  778. { \
  779. PUCHAR _Address = RegisterBase; \
  780. UCHAR _Control; \
  781. _Control = GetControl(_Address); \
  782. ASSERT(!(_Control & PAR_CONTROL_STROBE)); \
  783. StoreControl( \
  784. _Address, \
  785. (UCHAR)(_Control & ~(PAR_CONTROL_STROBE | PAR_CONTROL_DIR)) \
  786. ); \
  787. WRITE_PORT_UCHAR( \
  788. _Address+PARALLEL_DATA_OFFSET, \
  789. (UCHAR)DataByte \
  790. ); \
  791. KeStallExecutionProcessor((ULONG)1); \
  792. StoreControl( \
  793. _Address, \
  794. (UCHAR)((_Control | PAR_CONTROL_STROBE) & ~PAR_CONTROL_DIR) \
  795. ); \
  796. KeStallExecutionProcessor((ULONG)1); \
  797. StoreControl( \
  798. _Address, \
  799. (UCHAR)(_Control & ~(PAR_CONTROL_STROBE | PAR_CONTROL_DIR)) \
  800. ); \
  801. KeStallExecutionProcessor((ULONG)1); \
  802. StoreControl( \
  803. _Address, \
  804. (UCHAR)_Control \
  805. ); \
  806. }
  807. //UCHAR
  808. //GetControl(
  809. // IN PUCHAR RegisterBase
  810. // )
  811. #define GetControl(RegisterBase) \
  812. (READ_PORT_UCHAR((RegisterBase)+PARALLEL_CONTROL_OFFSET))
  813. //VOID
  814. //StoreControl(
  815. // IN PUCHAR RegisterBase,
  816. // IN UCHAR ControlByte
  817. // )
  818. #define StoreControl(RegisterBase,ControlByte) \
  819. { \
  820. WRITE_PORT_UCHAR( \
  821. (RegisterBase)+PARALLEL_CONTROL_OFFSET, \
  822. (UCHAR)ControlByte \
  823. ); \
  824. }
  825. //UCHAR
  826. //GetStatus(
  827. // IN PUCHAR RegisterBase
  828. // )
  829. #define GetStatus(RegisterBase) \
  830. (READ_PORT_UCHAR((RegisterBase)+PARALLEL_STATUS_OFFSET))
  831. //
  832. // Function prototypes
  833. //
  834. //
  835. // ieee1284.c
  836. //
  837. VOID
  838. IeeeTerminate1284Mode(
  839. IN PDEVICE_EXTENSION Extension
  840. );
  841. NTSTATUS
  842. IeeeEnter1284Mode(
  843. IN PDEVICE_EXTENSION Extension,
  844. IN UCHAR Extensibility
  845. );
  846. VOID
  847. IeeeDetermineSupportedProtocols(
  848. IN PDEVICE_EXTENSION Extension
  849. );
  850. NTSTATUS
  851. IeeeNegotiateBestMode(
  852. IN PDEVICE_EXTENSION Extension,
  853. IN USHORT usReadMask,
  854. IN USHORT usWriteMask
  855. );
  856. NTSTATUS
  857. IeeeNegotiateMode(
  858. IN PDEVICE_EXTENSION Extension,
  859. IN USHORT usReadMask,
  860. IN USHORT usWriteMask
  861. );
  862. //
  863. // port.c
  864. //
  865. NTSTATUS
  866. ParGetPortInfoFromPortDevice(
  867. IN OUT PDEVICE_EXTENSION Extension
  868. );
  869. VOID
  870. ParReleasePortInfoToPortDevice(
  871. IN PDEVICE_EXTENSION Extension
  872. );
  873. VOID
  874. ParFreePort(
  875. IN PDEVICE_EXTENSION Extension
  876. );
  877. NTSTATUS
  878. ParAllocPortCompletionRoutine(
  879. IN PDEVICE_OBJECT DeviceObject,
  880. IN PIRP Irp,
  881. IN PVOID Context
  882. );
  883. BOOLEAN
  884. ParAllocPort(
  885. IN PDEVICE_EXTENSION Extension
  886. );
  887. PDEVICE_OBJECT
  888. ParGetPortObjectFromLinkName(
  889. IN PUNICODE_STRING SymbolicLinkName,
  890. IN PDEVICE_EXTENSION Extension
  891. );
  892. //
  893. // parpnp.c
  894. //
  895. #ifndef STATIC_LOAD
  896. NTSTATUS
  897. ParPnpAddDevice(
  898. IN PDRIVER_OBJECT pDriverObject,
  899. IN PDEVICE_OBJECT pPhysicalDeviceObject
  900. );
  901. NTSTATUS
  902. ParParallelPnp (
  903. IN PDEVICE_OBJECT pDeviceObject,
  904. IN PIRP pIrp
  905. );
  906. NTSTATUS
  907. ParSynchCompletionRoutine(
  908. IN PDEVICE_OBJECT DeviceObject,
  909. IN PIRP Irp,
  910. IN PKEVENT Event
  911. );
  912. BOOLEAN
  913. ParMakeNames(
  914. IN ULONG ParallelPortNumber,
  915. OUT PUNICODE_STRING ClassName,
  916. OUT PUNICODE_STRING LinkName
  917. );
  918. VOID
  919. ParCheckParameters(
  920. IN OUT PDEVICE_EXTENSION Extension
  921. );
  922. #endif
  923. //
  924. // oldinit.c
  925. //
  926. #ifdef STATIC_LOAD
  927. NTSTATUS
  928. DriverEntry(
  929. IN PDRIVER_OBJECT DriverObject,
  930. IN PUNICODE_STRING RegistryPath
  931. );
  932. BOOLEAN
  933. ParMakeNames(
  934. IN ULONG ParallelPortNumber,
  935. OUT PUNICODE_STRING PortName,
  936. OUT PUNICODE_STRING ClassName,
  937. OUT PUNICODE_STRING LinkName
  938. );
  939. VOID
  940. ParInitializeClassDevice(
  941. IN PDRIVER_OBJECT DriverObject,
  942. IN PUNICODE_STRING RegistryPath,
  943. IN ULONG ParallelPortNumber
  944. );
  945. VOID
  946. ParCheckParameters(
  947. IN PUNICODE_STRING RegistryPath,
  948. IN OUT PDEVICE_EXTENSION Extension
  949. );
  950. #endif
  951. //
  952. // parloop.c
  953. //
  954. ULONG
  955. SppWriteLoop(
  956. IN PUCHAR Controller,
  957. IN PUCHAR WriteBuffer,
  958. IN ULONG NumBytesToWrite
  959. );
  960. //
  961. // parclass.c
  962. //
  963. VOID
  964. ParLogError(
  965. IN PDRIVER_OBJECT DriverObject,
  966. IN PDEVICE_OBJECT DeviceObject OPTIONAL,
  967. IN PHYSICAL_ADDRESS P1,
  968. IN PHYSICAL_ADDRESS P2,
  969. IN ULONG SequenceNumber,
  970. IN UCHAR MajorFunctionCode,
  971. IN UCHAR RetryCount,
  972. IN ULONG UniqueErrorValue,
  973. IN NTSTATUS FinalStatus,
  974. IN NTSTATUS SpecificIOStatus
  975. );
  976. NTSTATUS
  977. ParCreateOpen(
  978. IN PDEVICE_OBJECT DeviceObject,
  979. IN PIRP Irp
  980. );
  981. NTSTATUS
  982. ParClose(
  983. IN PDEVICE_OBJECT DeviceObject,
  984. IN PIRP Irp
  985. );
  986. NTSTATUS
  987. ParCleanup(
  988. IN PDEVICE_OBJECT DeviceObject,
  989. IN PIRP Irp
  990. );
  991. NTSTATUS
  992. ParReadWrite(
  993. IN PDEVICE_OBJECT DeviceObject,
  994. IN PIRP Irp
  995. );
  996. NTSTATUS
  997. ParDeviceControl(
  998. IN PDEVICE_OBJECT DeviceObject,
  999. IN PIRP Irp
  1000. );
  1001. NTSTATUS
  1002. ParInternalDeviceControl(
  1003. IN PDEVICE_OBJECT DeviceObject,
  1004. IN PIRP Irp
  1005. );
  1006. NTSTATUS
  1007. ParQueryInformationFile(
  1008. IN PDEVICE_OBJECT DeviceObject,
  1009. IN PIRP Irp
  1010. );
  1011. NTSTATUS
  1012. ParSetInformationFile(
  1013. IN PDEVICE_OBJECT DeviceObject,
  1014. IN PIRP Irp
  1015. );
  1016. NTSTATUS
  1017. ParExportedNegotiateIeeeMode(
  1018. IN PDEVICE_EXTENSION Extension,
  1019. IN USHORT ModeMaskFwd,
  1020. IN USHORT ModeMaskRev,
  1021. IN PARALLEL_SAFETY ModeSafety,
  1022. IN BOOLEAN IsForward
  1023. );
  1024. NTSTATUS
  1025. ParExportedTerminateIeeeMode(
  1026. IN PDEVICE_EXTENSION Extension
  1027. );
  1028. //////////////////////////////////////////////////////////////////
  1029. // Modes of operation
  1030. //////////////////////////////////////////////////////////////////
  1031. //
  1032. // spp.c
  1033. //
  1034. NTSTATUS
  1035. ParEnterSppMode(
  1036. IN PDEVICE_EXTENSION Extension,
  1037. IN BOOLEAN DeviceIdRequest
  1038. );
  1039. ULONG
  1040. SppWriteLoopPI(
  1041. IN PUCHAR Controller,
  1042. IN PUCHAR WriteBuffer,
  1043. IN ULONG NumBytesToWrite,
  1044. IN ULONG BusyDelay
  1045. );
  1046. ULONG
  1047. SppCheckBusyDelay(
  1048. IN PDEVICE_EXTENSION Extension,
  1049. IN PUCHAR WriteBuffer,
  1050. IN ULONG NumBytesToWrite
  1051. );
  1052. NTSTATUS
  1053. SppWrite(
  1054. IN PDEVICE_EXTENSION Extension,
  1055. IN PVOID Buffer,
  1056. IN ULONG BytesToWrite,
  1057. OUT PULONG BytesTransferred
  1058. );
  1059. VOID
  1060. ParTerminateSppMode(
  1061. IN PDEVICE_EXTENSION Extension
  1062. );
  1063. NTSTATUS
  1064. SppQueryDeviceId(
  1065. IN PDEVICE_EXTENSION Extension,
  1066. OUT PUCHAR DeviceIdBuffer,
  1067. IN ULONG BufferSize,
  1068. OUT PULONG DeviceIdSize,
  1069. IN BOOLEAN bReturnRawString
  1070. );
  1071. //
  1072. // sppieee.c
  1073. //
  1074. NTSTATUS
  1075. SppIeeeWrite(
  1076. IN PDEVICE_EXTENSION Extension,
  1077. IN PVOID Buffer,
  1078. IN ULONG BytesToWrite,
  1079. OUT PULONG BytesTransferred
  1080. );
  1081. //
  1082. // nibble.c
  1083. //
  1084. BOOLEAN
  1085. ParIsChannelizedNibbleSupported(
  1086. IN PDEVICE_EXTENSION Extension
  1087. );
  1088. BOOLEAN
  1089. ParIsNibbleSupported(
  1090. IN PDEVICE_EXTENSION Extension
  1091. );
  1092. NTSTATUS
  1093. ParEnterNibbleMode(
  1094. IN PDEVICE_EXTENSION Extension,
  1095. IN BOOLEAN DeviceIdRequest
  1096. );
  1097. NTSTATUS
  1098. ParEnterChannelizedNibbleMode(
  1099. IN PDEVICE_EXTENSION Extension,
  1100. IN BOOLEAN DeviceIdRequest
  1101. );
  1102. VOID
  1103. ParTerminateNibbleMode(
  1104. IN PDEVICE_EXTENSION Extension
  1105. );
  1106. NTSTATUS
  1107. ParNibbleModeRead(
  1108. IN PDEVICE_EXTENSION Extension,
  1109. IN PVOID Buffer,
  1110. IN ULONG BufferSize,
  1111. OUT PULONG BytesTransferred
  1112. );
  1113. //
  1114. // Byte.c
  1115. //
  1116. BOOLEAN
  1117. ParIsByteSupported(
  1118. IN PDEVICE_EXTENSION Extension
  1119. );
  1120. NTSTATUS
  1121. ParEnterByteMode(
  1122. IN PDEVICE_EXTENSION Extension,
  1123. IN BOOLEAN DeviceIdRequest
  1124. );
  1125. VOID
  1126. ParTerminateByteMode(
  1127. IN PDEVICE_EXTENSION Extension
  1128. );
  1129. NTSTATUS
  1130. ParByteModeRead(
  1131. IN PDEVICE_EXTENSION Extension,
  1132. IN PVOID Buffer,
  1133. IN ULONG BufferSize,
  1134. OUT PULONG BytesTransferred
  1135. );
  1136. //
  1137. // epp.c
  1138. //
  1139. NTSTATUS
  1140. ParEppSetAddress(
  1141. IN PDEVICE_EXTENSION Extension,
  1142. IN UCHAR Address
  1143. );
  1144. //
  1145. // hwepp.c
  1146. //
  1147. BOOLEAN
  1148. ParIsEppHwSupported(
  1149. IN PDEVICE_EXTENSION Extension
  1150. );
  1151. NTSTATUS
  1152. ParEnterEppHwMode(
  1153. IN PDEVICE_EXTENSION Extension,
  1154. IN BOOLEAN DeviceIdRequest
  1155. );
  1156. VOID
  1157. ParTerminateEppHwMode(
  1158. IN PDEVICE_EXTENSION Extension
  1159. );
  1160. NTSTATUS
  1161. ParEppHwWrite(
  1162. IN PDEVICE_EXTENSION Extension,
  1163. IN PVOID Buffer,
  1164. IN ULONG BufferSize,
  1165. OUT PULONG BytesTransferred
  1166. );
  1167. NTSTATUS
  1168. ParEppHwRead(
  1169. IN PDEVICE_EXTENSION Extension,
  1170. IN PVOID Buffer,
  1171. IN ULONG BufferSize,
  1172. OUT PULONG BytesTransferred
  1173. );
  1174. //
  1175. // swepp.c
  1176. //
  1177. BOOLEAN
  1178. ParIsEppSwWriteSupported(
  1179. IN PDEVICE_EXTENSION Extension
  1180. );
  1181. BOOLEAN
  1182. ParIsEppSwReadSupported(
  1183. IN PDEVICE_EXTENSION Extension
  1184. );
  1185. NTSTATUS
  1186. ParEnterEppSwMode(
  1187. IN PDEVICE_EXTENSION Extension,
  1188. IN BOOLEAN DeviceIdRequest
  1189. );
  1190. VOID
  1191. ParTerminateEppSwMode(
  1192. IN PDEVICE_EXTENSION Extension
  1193. );
  1194. NTSTATUS
  1195. ParEppSwWrite(
  1196. IN PDEVICE_EXTENSION Extension,
  1197. IN PVOID Buffer,
  1198. IN ULONG BufferSize,
  1199. OUT PULONG BytesTransferred
  1200. );
  1201. NTSTATUS
  1202. ParEppSwRead(
  1203. IN PDEVICE_EXTENSION Extension,
  1204. IN PVOID Buffer,
  1205. IN ULONG BufferSize,
  1206. OUT PULONG BytesTransferred
  1207. );
  1208. //
  1209. // ecp.c and swecp.c
  1210. //
  1211. NTSTATUS
  1212. ParEcpEnterForwardPhase (
  1213. IN PDEVICE_EXTENSION Extension
  1214. );
  1215. BOOLEAN
  1216. ParEcpHaveReadData (
  1217. IN PDEVICE_EXTENSION Extension
  1218. );
  1219. BOOLEAN
  1220. ParIsEcpSwWriteSupported(
  1221. IN PDEVICE_EXTENSION Extension
  1222. );
  1223. BOOLEAN
  1224. ParIsEcpSwReadSupported(
  1225. IN PDEVICE_EXTENSION Extension
  1226. );
  1227. NTSTATUS
  1228. ParEnterEcpSwMode(
  1229. IN PDEVICE_EXTENSION Extension,
  1230. IN BOOLEAN DeviceIdRequest
  1231. );
  1232. VOID
  1233. ParCleanupSwEcpPort(
  1234. IN PDEVICE_EXTENSION Extension
  1235. );
  1236. VOID
  1237. ParTerminateEcpMode(
  1238. IN PDEVICE_EXTENSION Extension
  1239. );
  1240. NTSTATUS
  1241. ParEcpSetAddress(
  1242. IN PDEVICE_EXTENSION Extension,
  1243. IN UCHAR Address
  1244. );
  1245. NTSTATUS
  1246. ParEcpSwWrite(
  1247. IN PDEVICE_EXTENSION Extension,
  1248. IN PVOID Buffer,
  1249. IN ULONG BufferSize,
  1250. OUT PULONG BytesTransferred
  1251. );
  1252. NTSTATUS
  1253. ParEcpSwRead(
  1254. IN PDEVICE_EXTENSION Extension,
  1255. IN PVOID Buffer,
  1256. IN ULONG BufferSize,
  1257. OUT PULONG BytesTransferred
  1258. );
  1259. NTSTATUS
  1260. ParEcpForwardToReverse(
  1261. IN PDEVICE_EXTENSION Extension
  1262. );
  1263. NTSTATUS
  1264. ParEcpReverseToForward(
  1265. IN PDEVICE_EXTENSION Extension
  1266. );
  1267. //
  1268. // hwecp.c
  1269. //
  1270. BOOLEAN
  1271. ParEcpHwHaveReadData (
  1272. IN PDEVICE_EXTENSION Extension
  1273. );
  1274. NTSTATUS
  1275. ParEcpHwExitForwardPhase (
  1276. IN PDEVICE_EXTENSION Extension
  1277. );
  1278. NTSTATUS
  1279. ParEcpHwEnterReversePhase (
  1280. IN PDEVICE_EXTENSION Extension
  1281. );
  1282. NTSTATUS
  1283. ParEcpHwExitReversePhase (
  1284. IN PDEVICE_EXTENSION Extension
  1285. );
  1286. VOID
  1287. ParEcpHwDrainShadowBuffer(IN Queue *pShadowBuffer,
  1288. IN PUCHAR lpsBufPtr,
  1289. IN ULONG dCount,
  1290. OUT ULONG *fifoCount);
  1291. NTSTATUS
  1292. ParEcpHwRead(
  1293. IN PDEVICE_EXTENSION Extension,
  1294. IN PVOID Buffer,
  1295. IN ULONG BufferSize,
  1296. OUT PULONG BytesTransferred
  1297. );
  1298. NTSTATUS
  1299. ParEcpHwWrite(
  1300. IN PDEVICE_EXTENSION Extension,
  1301. IN PVOID Buffer,
  1302. IN ULONG BufferSize,
  1303. OUT PULONG BytesTransferred
  1304. );
  1305. NTSTATUS
  1306. ParEcpHwSetAddress(
  1307. IN PDEVICE_EXTENSION Extension,
  1308. IN UCHAR Address
  1309. );
  1310. NTSTATUS
  1311. ParEnterEcpHwMode(
  1312. IN PDEVICE_EXTENSION Extension,
  1313. IN BOOLEAN DeviceIdRequest
  1314. );
  1315. BOOLEAN
  1316. ParIsEcpHwSupported(
  1317. IN PDEVICE_EXTENSION Extension
  1318. );
  1319. NTSTATUS
  1320. ParEcpHwSetupPhase(
  1321. IN PDEVICE_EXTENSION Extension
  1322. );
  1323. VOID
  1324. ParTerminateHwEcpMode(
  1325. IN PDEVICE_EXTENSION Extension
  1326. );
  1327. //
  1328. // becp.c
  1329. //
  1330. NTSTATUS
  1331. ParBecpExitReversePhase(
  1332. IN PDEVICE_EXTENSION Extension
  1333. );
  1334. NTSTATUS
  1335. ParBecpRead(
  1336. IN PDEVICE_EXTENSION Extension,
  1337. IN PVOID Buffer,
  1338. IN ULONG BufferSize,
  1339. OUT PULONG BytesTransferred
  1340. );
  1341. NTSTATUS
  1342. ParEnterBecpMode(
  1343. IN PDEVICE_EXTENSION Extension,
  1344. IN BOOLEAN DeviceIdRequest
  1345. );
  1346. BOOLEAN
  1347. ParIsBecpSupported(
  1348. IN PDEVICE_EXTENSION Extension
  1349. );
  1350. VOID
  1351. ParTerminateBecpMode(
  1352. IN PDEVICE_EXTENSION Extension
  1353. );
  1354. //
  1355. // p12843dl.c
  1356. //
  1357. NTSTATUS
  1358. ParDot3Connect(
  1359. IN PDEVICE_EXTENSION Extension
  1360. );
  1361. VOID
  1362. ParDot3CreateObject(
  1363. IN PDEVICE_EXTENSION Extension,
  1364. IN PUCHAR DOT3DL,
  1365. IN PUCHAR DOT3C
  1366. );
  1367. VOID
  1368. ParDot4CreateObject(
  1369. IN PDEVICE_EXTENSION Extension,
  1370. IN PUCHAR DOT4DL
  1371. );
  1372. VOID
  1373. ParDot3ParseModes(
  1374. IN PDEVICE_EXTENSION Extension,
  1375. IN PUCHAR DOT3M
  1376. );
  1377. VOID
  1378. ParMLCCreateObject(
  1379. IN PDEVICE_EXTENSION Extension,
  1380. IN PUCHAR CMDField
  1381. );
  1382. VOID
  1383. ParDot3DestroyObject(
  1384. IN PDEVICE_EXTENSION Extension
  1385. );
  1386. NTSTATUS
  1387. ParDot3Disconnect(
  1388. IN PDEVICE_EXTENSION Extension
  1389. );
  1390. NTSTATUS
  1391. ParDot3Read(
  1392. IN PDEVICE_EXTENSION Extension,
  1393. IN PVOID Buffer,
  1394. IN ULONG BufferSize,
  1395. OUT PULONG BytesTransferred
  1396. );
  1397. NTSTATUS
  1398. ParDot3Write(
  1399. IN PDEVICE_EXTENSION Extension,
  1400. IN PVOID Buffer,
  1401. IN ULONG BufferSize,
  1402. OUT PULONG BytesTransferred
  1403. );
  1404. typedef
  1405. NTSTATUS
  1406. (*PDOT3_RESET_ROUTINE) (
  1407. IN PDEVICE_EXTENSION Extension
  1408. );
  1409. NTSTATUS
  1410. ParMLCCompatReset(
  1411. IN PDEVICE_EXTENSION Extension
  1412. );
  1413. NTSTATUS
  1414. ParMLCECPReset(
  1415. IN PDEVICE_EXTENSION Extension
  1416. );
  1417. #if DBG
  1418. VOID
  1419. ParInitDebugLevel (
  1420. IN PUNICODE_STRING RegistryPath
  1421. );
  1422. #endif