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.

1488 lines
42 KiB

  1. /*--------------------------------------------------------------------------
  2. *
  3. * Copyright (C) Cyclades Corporation, 1997-2000.
  4. * All rights reserved.
  5. *
  6. * Cyclades-Z Port Driver
  7. *
  8. * This file: cyzport.h
  9. *
  10. * Description: Type definitions and data for the Cyclades-Z Port
  11. * Driver
  12. *
  13. * Notes: This code supports Windows 2000 and x86 processor.
  14. *
  15. * Complies with Cyclades SW Coding Standard rev 1.3.
  16. *
  17. *--------------------------------------------------------------------------
  18. */
  19. /*-------------------------------------------------------------------------
  20. *
  21. * Change History
  22. *
  23. *--------------------------------------------------------------------------
  24. *
  25. *
  26. *--------------------------------------------------------------------------
  27. */
  28. #define POOL_TAGGING 1
  29. #ifdef POOL_TAGGING
  30. #undef ExAllocatePool
  31. #undef ExAllocatePoolWithQuota
  32. #define ExAllocatePool(a,b) ExAllocatePoolWithTag(a,b,'PzyC')
  33. #define ExAllocatePoolWithQuota(a,b) ExAllocatePoolWithQuotaTag(a,b,'PzyC')
  34. #endif
  35. //
  36. // The following definition is used to include/exclude changes made for power
  37. // support in the driver. If non-zero the support is included. If zero the
  38. // support is excluded.
  39. //
  40. #define POWER_SUPPORT 1
  41. #define CYZDIAG1 (DPFLTR_INFO_LEVEL + 1)
  42. #define CYZDIAG2 (DPFLTR_INFO_LEVEL + 2)
  43. #define CYZDIAG3 (DPFLTR_INFO_LEVEL + 3)
  44. #define CYZDIAG4 (DPFLTR_INFO_LEVEL + 4)
  45. #define CYZDIAG5 (DPFLTR_INFO_LEVEL + 5)
  46. #define CYZIRPPATH (DPFLTR_INFO_LEVEL + 6)
  47. #define CYZINITCODE (DPFLTR_INFO_LEVEL + 7)
  48. #define CYZTRACECALLS (DPFLTR_INFO_LEVEL + 8)
  49. #define CYZPNPPOWER (DPFLTR_INFO_LEVEL + 9)
  50. #define CYZFLOW (DPFLTR_INFO_LEVEL + 10)
  51. #define CYZERRORS (DPFLTR_INFO_LEVEL + 11)
  52. #define CYZDBGALL ((ULONG)0xFFFFFFFF)
  53. #define CYZ_DBG_DEFAULT CYZDBGALL
  54. //
  55. // Some default driver values. We will check the registry for
  56. // them first.
  57. //
  58. #define CYZ_UNINITIALIZED_DEFAULT 1234567
  59. #define CYZ_PERMIT_SHARE_DEFAULT 0
  60. //
  61. // This define gives the default Object directory
  62. // that we should use to insert the symbolic links
  63. // between the NT device name and namespace used by
  64. // that object directory.
  65. #define DEFAULT_DIRECTORY L"DosDevices"
  66. //
  67. // For the above directory, the serial port will
  68. // use the following name as the suffix of the serial
  69. // ports for that directory. It will also append
  70. // a number onto the end of the name. That number
  71. // will start at 1.
  72. #define DEFAULT_SERIAL_NAME L"COM"
  73. //
  74. //
  75. // This define gives the default NT name for
  76. // for serial ports detected by the firmware.
  77. // This name will be appended to Device prefix
  78. // with a number following it. The number is
  79. // incremented each time encounter a serial
  80. // port detected by the firmware. Note that
  81. // on a system with multiple busses, this means
  82. // that the first port on a bus is not necessarily
  83. // \Device\Serial0.
  84. //
  85. #define DEFAULT_NT_SUFFIX L"Cyzport"
  86. //#define CYZ_VENDOR_ID 0x120e
  87. //#define CYZ_LO_DEV_ID 0x100
  88. //#define CYZ_HI_DEV_ID 0x101
  89. // Defines for OutputRS232
  90. #define CYZ_LC_RTS 0x01
  91. #define CYZ_LC_DTR 0x02
  92. typedef struct _CONFIG_DATA {
  93. PHYSICAL_ADDRESS PhysicalRuntime;
  94. PHYSICAL_ADDRESS TranslatedRuntime;
  95. PHYSICAL_ADDRESS PhysicalBoardMemory;
  96. PHYSICAL_ADDRESS TranslatedBoardMemory;
  97. ULONG RuntimeLength;
  98. ULONG BoardMemoryLength;
  99. ULONG PortIndex;
  100. ULONG PPPaware;
  101. ULONG WriteComplete;
  102. ULONG BusNumber;
  103. ULONG RuntimeAddressSpace;
  104. ULONG BoardMemoryAddressSpace;
  105. ULONG RxFIFO;
  106. ULONG TxFIFO;
  107. INTERFACE_TYPE InterfaceType;
  108. #ifndef POLL
  109. KINTERRUPT_MODE InterruptMode;
  110. ULONG OriginalVector;
  111. ULONG OriginalIrql;
  112. ULONG TrVector;
  113. ULONG TrIrql;
  114. KAFFINITY Affinity;
  115. #endif
  116. } CONFIG_DATA,*PCONFIG_DATA;
  117. //
  118. // This structure contains configuration data, much of which
  119. // is read from the registry.
  120. //
  121. typedef struct _CYZ_REGISTRY_DATA {
  122. PDRIVER_OBJECT DriverObject;
  123. ULONG ControllersFound;
  124. ULONG DebugLevel;
  125. ULONG ShouldBreakOnEntry;
  126. // ULONG RxFIFODefault;
  127. // ULONG TxFIFODefault;
  128. ULONG PermitShareDefault;
  129. ULONG PermitSystemWideShare;
  130. UNICODE_STRING Directory;
  131. UNICODE_STRING NtNameSuffix;
  132. UNICODE_STRING DirectorySymbolicName;
  133. LIST_ENTRY ConfigList;
  134. } CYZ_REGISTRY_DATA,*PCYZ_REGISTRY_DATA;
  135. // Default xon/xoff characters.
  136. #define CYZ_DEF_XON 0x11
  137. #define CYZ_DEF_XOFF 0x13
  138. // Reasons why reception may be held up.
  139. #define CYZ_RX_DTR ((ULONG)0x01)
  140. #define CYZ_RX_XOFF ((ULONG)0x02)
  141. #define CYZ_RX_RTS ((ULONG)0x04)
  142. #define CYZ_RX_DSR ((ULONG)0x08)
  143. // Reasons why transmission may be held up.
  144. #define CYZ_TX_CTS ((ULONG)0x01)
  145. #define CYZ_TX_DSR ((ULONG)0x02)
  146. #define CYZ_TX_DCD ((ULONG)0x04)
  147. #define CYZ_TX_XOFF ((ULONG)0x08)
  148. #define CYZ_TX_BREAK ((ULONG)0x10)
  149. //Line status in RDSR Register
  150. #define CYZ_LSR_OE 0x01 //Overrun Error
  151. #define CYZ_LSR_FE 0x02 //Framing Error
  152. #define CYZ_LSR_PE 0x04 //Parity Error
  153. #define CYZ_LSR_BI 0x08 //Break Interrupt
  154. #define CYZ_LSR_ERROR 0x0f //Overrun+Framing+Parity+Break
  155. // These values are used by the routines that can be used
  156. // to complete a read (other than interval timeout) to indicate
  157. //
  158. #define CYZ_COMPLETE_READ_CANCEL ((LONG)-1)
  159. #define CYZ_COMPLETE_READ_TOTAL ((LONG)-2)
  160. #define CYZ_COMPLETE_READ_COMPLETE ((LONG)-3)
  161. typedef struct _CYZ_DEVICE_STATE {
  162. //
  163. // TRUE if we need to set the state to open
  164. // on a powerup
  165. //
  166. BOOLEAN Reopen;
  167. ULONG op_mode;
  168. ULONG intr_enable;
  169. ULONG sw_flow;
  170. ULONG comm_baud;
  171. ULONG comm_parity;
  172. ULONG comm_data_l;
  173. ULONG hw_flow;
  174. ULONG rs_control;
  175. #if 0
  176. //
  177. // Hardware registers
  178. //
  179. UCHAR IER;
  180. // FCR is known by other values
  181. UCHAR LCR;
  182. UCHAR MCR;
  183. // LSR is never written
  184. // MSR is never written
  185. // SCR is either scratch or interrupt status
  186. #endif
  187. } CYZ_DEVICE_STATE, *PCYZ_DEVICE_STATE;
  188. #if DBG
  189. #define CyzLockPagableSectionByHandle(_secHandle) \
  190. { \
  191. MmLockPagableSectionByHandle((_secHandle)); \
  192. InterlockedIncrement(&CyzGlobals.PAGESER_Count); \
  193. }
  194. #define CyzUnlockPagableImageSection(_secHandle) \
  195. { \
  196. InterlockedDecrement(&CyzGlobals.PAGESER_Count); \
  197. MmUnlockPagableImageSection(_secHandle); \
  198. }
  199. #define CYZ_LOCKED_PAGED_CODE() \
  200. if ((KeGetCurrentIrql() > APC_LEVEL) \
  201. && (CyzGlobals.PAGESER_Count == 0)) { \
  202. KdPrint(("CYZPORT: Pageable code called at IRQL %d without lock \n", \
  203. KeGetCurrentIrql())); \
  204. ASSERT(FALSE); \
  205. }
  206. #else
  207. #define CyzLockPagableSectionByHandle(_secHandle) \
  208. { \
  209. MmLockPagableSectionByHandle((_secHandle)); \
  210. }
  211. #define CyzUnlockPagableImageSection(_secHandle) \
  212. { \
  213. MmUnlockPagableImageSection(_secHandle); \
  214. }
  215. #define CYZ_LOCKED_PAGED_CODE()
  216. #endif // DBG
  217. #define CyzRemoveQueueDpc(_dpc, _pExt) \
  218. { \
  219. if (KeRemoveQueueDpc((_dpc))) { \
  220. InterlockedDecrement(&(_pExt)->DpcCount); \
  221. } \
  222. }
  223. typedef struct _CYZ_DEVICE_EXTENSION {
  224. // PKSERVICE_ROUTINE ptIsr;
  225. // PVOID ptContext;
  226. // struct _CYZ_DEVICE_EXTENSION *ptExtension[CYZ_MAX_PORTS];
  227. // ULONG nchannel;
  228. BOOLEAN LieRIDSR;
  229. //
  230. // This holds the isr that should be called from our own
  231. // dispatching isr for "cards" that are trying to share the
  232. // same interrupt.
  233. //
  234. // PKSERVICE_ROUTINE TopLevelOurIsr;
  235. //
  236. // This holds the context that should be used when we
  237. // call the above service routine.
  238. //
  239. // PVOID TopLevelOurIsrContext;
  240. //
  241. // This links together all of the different "cards" that are
  242. // trying to share the same interrupt of a non-mca machine.
  243. //
  244. // LIST_ENTRY TopLevelSharers;
  245. //
  246. // This circular doubly linked list links together all
  247. // devices that are using the same interrupt object.
  248. // NOTE: This does not mean that they are using the
  249. // same interrupt "dispatching" routine.
  250. //
  251. // LIST_ENTRY CommonInterruptObject;
  252. //
  253. // This links together all devobjs that this driver owns.
  254. // It is needed to search when starting a new device.
  255. //
  256. LIST_ENTRY AllDevObjs;
  257. // For reporting resource usage, we keep around the physical
  258. // address we got from the registry.
  259. //
  260. PHYSICAL_ADDRESS OriginalRuntimeMemory;
  261. // For reporting resource usage, we keep around the physical
  262. // address we got from the registry.
  263. //
  264. PHYSICAL_ADDRESS OriginalBoardMemory;
  265. //
  266. // This value is set by the read code to hold the time value
  267. // used for read interval timing. We keep it in the extension
  268. // so that the interval timer dpc routine determine if the
  269. // interval time has passed for the IO.
  270. //
  271. LARGE_INTEGER IntervalTime;
  272. //
  273. // These two values hold the "constant" time that we should use
  274. // to delay for the read interval time.
  275. //
  276. LARGE_INTEGER ShortIntervalAmount;
  277. LARGE_INTEGER LongIntervalAmount;
  278. //
  279. // This holds the value that we use to determine if we should use
  280. // the long interval delay or the short interval delay.
  281. //
  282. LARGE_INTEGER CutOverAmount;
  283. //
  284. // This holds the system time when we last time we had
  285. // checked that we had actually read characters. Used
  286. // for interval timing.
  287. //
  288. LARGE_INTEGER LastReadTime;
  289. //
  290. // We keep a pointer around to our device name for dumps
  291. // and for creating "external" symbolic links to this
  292. // device.
  293. //
  294. UNICODE_STRING DeviceName;
  295. //
  296. // This points to the object directory that we will place
  297. // a symbolic link to our device name.
  298. //
  299. UNICODE_STRING ObjectDirectory;
  300. //
  301. // This points to the device name for this device
  302. // sans device prefix.
  303. //
  304. UNICODE_STRING NtNameForPort;
  305. //
  306. // This points to the symbolic link name that will be
  307. // linked to the actual nt device name.
  308. //
  309. UNICODE_STRING SymbolicLinkName;
  310. //
  311. // This points to the pure "COMx" name
  312. //
  313. UNICODE_STRING DosName;
  314. //
  315. // This points the the delta time that we should use to
  316. // delay for interval timing.
  317. //
  318. PLARGE_INTEGER IntervalTimeToUse;
  319. //
  320. // Points to the device object that contains
  321. // this device extension.
  322. //
  323. PDEVICE_OBJECT DeviceObject;
  324. //
  325. // After initialization of the driver is complete, this
  326. // will either be NULL or point to the routine that the
  327. // kernel will call when an interrupt occurs.
  328. //
  329. // If the pointer is null then this is part of a list
  330. // of ports that are sharing an interrupt and this isn't
  331. // the first port that we configured for this interrupt.
  332. //
  333. // If the pointer is non-null then this routine has some
  334. // kind of structure that will "eventually" get us into
  335. // the real serial isr with a pointer to this device extension.
  336. //
  337. // NOTE: On an MCA bus (except for multiport cards) this
  338. // is always a pointer to the "real" serial isr.
  339. #ifndef POLL
  340. PKSERVICE_ROUTINE OurIsr;
  341. #endif
  342. //
  343. // This will generally point right to this device extension.
  344. //
  345. // However, when the port that this device extension is
  346. // "managing" was the first port initialized on a chain
  347. // of ports that were trying to share an interrupt, this
  348. // will point to a structure that will enable dispatching
  349. // to any port on the chain of sharers of this interrupt.
  350. //
  351. PVOID OurIsrContext;
  352. struct RUNTIME_9060 *Runtime; // Virtual Address Pointer to the PLX Runtime memory
  353. // PUCHAR BoardMemory; // Virtual Address Pointer to the Dual Port memory
  354. struct BOARD_CTRL *BoardCtrl;
  355. struct CH_CTRL *ChCtrl;
  356. struct BUF_CTRL *BufCtrl;
  357. struct INT_QUEUE *PtZfIntQueue;
  358. PUCHAR TxBufaddr;
  359. PUCHAR RxBufaddr;
  360. ULONG TxBufsize;
  361. ULONG RxBufsize;
  362. //POLL // The base address for interrupt status register.
  363. //POLL // This is only defined in the root extension.
  364. //POLL //
  365. //POLL PUCHAR InterruptStatus;
  366. #ifndef POLL
  367. //
  368. // Points to the interrupt object for used by this device.
  369. //
  370. PKINTERRUPT Interrupt;
  371. #endif
  372. //
  373. // This list head is used to contain the time ordered list
  374. // of read requests. Access to this list is protected by
  375. // the global cancel spinlock.
  376. //
  377. LIST_ENTRY ReadQueue;
  378. //
  379. // This list head is used to contain the time ordered list
  380. // of write requests. Access to this list is protected by
  381. // the global cancel spinlock.
  382. //
  383. LIST_ENTRY WriteQueue;
  384. //
  385. // This list head is used to contain the time ordered list
  386. // of set and wait mask requests. Access to this list is protected by
  387. // the global cancel spinlock.
  388. //
  389. LIST_ENTRY MaskQueue;
  390. //
  391. // Holds the serialized list of purge requests.
  392. //
  393. LIST_ENTRY PurgeQueue;
  394. //
  395. // This points to the irp that is currently being processed
  396. // for the read queue. This field is initialized by the open to
  397. // NULL.
  398. //
  399. // This value is only set at dispatch level. It may be
  400. // read at interrupt level.
  401. //
  402. PIRP CurrentReadIrp;
  403. //
  404. // This points to the irp that is currently being processed
  405. // for the write queue.
  406. //
  407. // This value is only set at dispatch level. It may be
  408. // read at interrupt level.
  409. //
  410. PIRP CurrentWriteIrp;
  411. //
  412. // Points to the irp that is currently being processed to
  413. // affect the wait mask operations.
  414. //
  415. PIRP CurrentMaskIrp;
  416. //
  417. // Points to the irp that is currently being processed to
  418. // purge the read/write queues and buffers.
  419. //
  420. PIRP CurrentPurgeIrp;
  421. //
  422. // Points to the current irp that is waiting on a comm event.
  423. //
  424. PIRP CurrentWaitIrp;
  425. //
  426. // Points to the irp that is being used to send an immediate
  427. // character.
  428. //
  429. PIRP CurrentImmediateIrp;
  430. //
  431. // Points to the irp that is being used to count the number
  432. // of characters received after an xoff (as currently defined
  433. // by the IOCTL_CYZ_XOFF_COUNTER ioctl) is sent.
  434. //
  435. PIRP CurrentXoffIrp;
  436. //
  437. // Holds the number of bytes remaining in the current write
  438. // irp.
  439. //
  440. // This location is only accessed while at interrupt level.
  441. //
  442. ULONG WriteLength;
  443. //
  444. // Holds a pointer to the current character to be sent in
  445. // the current write.
  446. //
  447. // This location is only accessed while at interrupt level.
  448. //
  449. PUCHAR WriteCurrentChar;
  450. //
  451. // This is a buffer for the read processing.
  452. //
  453. // The buffer works as a ring. When the character is read from
  454. // the device it will be place at the end of the ring.
  455. //
  456. // Characters are only placed in this buffer at interrupt level
  457. // although character may be read at any level. The pointers
  458. // that manage this buffer may not be updated except at interrupt
  459. // level.
  460. //
  461. PUCHAR InterruptReadBuffer;
  462. //
  463. // This is a pointer to the first character of the buffer into
  464. // which the interrupt service routine is copying characters.
  465. //
  466. PUCHAR ReadBufferBase;
  467. //
  468. // This is a count of the number of characters in the interrupt
  469. // buffer. This value is set and read at interrupt level. Note
  470. // that this value is only *incremented* at interrupt level so
  471. // it is safe to read it at any level. When characters are
  472. // copied out of the read buffer, this count is decremented by
  473. // a routine that synchronizes with the ISR.
  474. //
  475. ULONG CharsInInterruptBuffer;
  476. //
  477. // Points to the first available position for a newly received
  478. // character. This variable is only accessed at interrupt level and
  479. // buffer initialization code.
  480. //
  481. PUCHAR CurrentCharSlot;
  482. //
  483. // This variable is used to contain the last available position
  484. // in the read buffer. It is updated at open and at interrupt
  485. // level when switching between the users buffer and the interrupt
  486. // buffer.
  487. //
  488. PUCHAR LastCharSlot;
  489. //
  490. // This marks the first character that is available to satisfy
  491. // a read request. Note that while this always points to valid
  492. // memory, it may not point to a character that can be sent to
  493. // the user. This can occur when the buffer is empty.
  494. //
  495. PUCHAR FirstReadableChar;
  496. //
  497. // Pointer to the lock variable returned for this extension when
  498. // locking down the driver
  499. //
  500. PVOID LockPtr;
  501. BOOLEAN LockPtrFlag;
  502. //
  503. // This variable holds the size of whatever buffer we are currently
  504. // using.
  505. //
  506. ULONG BufferSize;
  507. //
  508. // This variable holds .8 of BufferSize. We don't want to recalculate
  509. // this real often - It's needed when so that an application can be
  510. // "notified" that the buffer is getting full.
  511. //
  512. ULONG BufferSizePt8;
  513. //
  514. // This value holds the number of characters desired for a
  515. // particular read. It is initially set by read length in the
  516. // IRP. It is decremented each time more characters are placed
  517. // into the "users" buffer buy the code that reads characters
  518. // out of the typeahead buffer into the users buffer. If the
  519. // typeahead buffer is exhausted by the read, and the reads buffer
  520. // is given to the isr to fill, this value is becomes meaningless.
  521. //
  522. ULONG NumberNeededForRead;
  523. //
  524. // This mask will hold the bitmask sent down via the set mask
  525. // ioctl. It is used by the interrupt service routine to determine
  526. // if the occurence of "events" (in the serial drivers understanding
  527. // of the concept of an event) should be noted.
  528. //
  529. ULONG IsrWaitMask;
  530. //
  531. // This mask will always be a subset of the IsrWaitMask. While
  532. // at device level, if an event occurs that is "marked" as interesting
  533. // in the IsrWaitMask, the driver will turn on that bit in this
  534. // history mask. The driver will then look to see if there is a
  535. // request waiting for an event to occur. If there is one, it
  536. // will copy the value of the history mask into the wait irp, zero
  537. // the history mask, and complete the wait irp. If there is no
  538. // waiting request, the driver will be satisfied with just recording
  539. // that the event occured. If a wait request should be queued,
  540. // the driver will look to see if the history mask is non-zero. If
  541. // it is non-zero, the driver will copy the history mask into the
  542. // irp, zero the history mask, and then complete the irp.
  543. //
  544. ULONG HistoryMask;
  545. //
  546. // This is a pointer to the where the history mask should be
  547. // placed when completing a wait. It is only accessed at
  548. // device level.
  549. //
  550. // We have a pointer here to assist us to synchronize completing a wait.
  551. // If this is non-zero, then we have wait outstanding, and the isr still
  552. // knows about it. We make this pointer null so that the isr won't
  553. // attempt to complete the wait.
  554. //
  555. // We still keep a pointer around to the wait irp, since the actual
  556. // pointer to the wait irp will be used for the "common" irp completion
  557. // path.
  558. //
  559. ULONG *IrpMaskLocation;
  560. //
  561. // This mask holds all of the reason that transmission
  562. // is not proceeding. Normal transmission can not occur
  563. // if this is non-zero.
  564. //
  565. // This is only written from interrupt level.
  566. // This could be (but is not) read at any level.
  567. //
  568. ULONG TXHolding;
  569. //
  570. // This mask holds all of the reason that reception
  571. // is not proceeding. Normal reception can not occur
  572. // if this is non-zero.
  573. //
  574. // This is only written from interrupt level.
  575. // This could be (but is not) read at any level.
  576. //
  577. ULONG RXHolding;
  578. //
  579. // This holds the reasons that the driver thinks it is in
  580. // an error state.
  581. //
  582. // This is only written from interrupt level.
  583. // This could be (but is not) read at any level.
  584. //
  585. ULONG ErrorWord;
  586. //
  587. // This keeps a total of the number of characters that
  588. // are in all of the "write" irps that the driver knows
  589. // about. It is only accessed with the cancel spinlock
  590. // held.
  591. //
  592. ULONG TotalCharsQueued;
  593. //
  594. // This holds a count of the number of characters read
  595. // the last time the interval timer dpc fired. It
  596. // is a long (rather than a ulong) since the other read
  597. // completion routines use negative values to indicate
  598. // to the interval timer that it should complete the read
  599. // if the interval timer DPC was lurking in some DPC queue when
  600. // some other way to complete occurs.
  601. //
  602. LONG CountOnLastRead;
  603. //
  604. // This is a count of the number of characters read by the
  605. // isr routine. It is *ONLY* written at isr level. We can
  606. // read it at dispatch level.
  607. //
  608. ULONG ReadByIsr;
  609. //
  610. // This holds the current baud rate for the device.
  611. //
  612. ULONG CurrentBaud;
  613. //
  614. // This is the number of characters read since the XoffCounter
  615. // was started. This variable is only accessed at device level.
  616. // If it is greater than zero, it implies that there is an
  617. // XoffCounter ioctl in the queue.
  618. //
  619. LONG CountSinceXoff;
  620. //
  621. // This ulong is incremented each time something trys to start
  622. // the execution path that tries to lower the RTS line when
  623. // doing transmit toggling. If it "bumps" into another path
  624. // (indicated by a false return value from queueing a dpc
  625. // and a TRUE return value tring to start a timer) it will
  626. // decrement the count. These increments and decrements
  627. // are all done at device level. Note that in the case
  628. // of a bump while trying to start the timer, we have to
  629. // go up to device level to do the decrement.
  630. //
  631. ULONG CountOfTryingToLowerRTS;
  632. //
  633. // This ULONG is used to keep track of the "named" (in ntddser.h)
  634. // baud rates that this particular device supports.
  635. //
  636. ULONG SupportedBauds;
  637. //
  638. // This value holds the span (in units of bytes) of the register
  639. // set controlling this port. This is constant over the life
  640. // of the port.
  641. //
  642. ULONG RuntimeLength;
  643. //
  644. // This value holds the span (in units of bytes) of the interrupt
  645. // status register associated with this port. This is constant
  646. // over the life of the port.
  647. //
  648. ULONG BoardMemoryLength;
  649. //
  650. // The number of characters to push out if a fifo is present.
  651. //
  652. ULONG TxFifoAmount;
  653. //
  654. // Set to indicate that it is ok to share interrupts within the device.
  655. //
  656. ULONG PermitShare;
  657. //
  658. // Holds the timeout controls for the device. This value
  659. // is set by the Ioctl processing.
  660. //
  661. // It should only be accessed under protection of the control
  662. // lock since more than one request can be in the control dispatch
  663. // routine at one time.
  664. //
  665. SERIAL_TIMEOUTS Timeouts;
  666. //
  667. // This holds the various characters that are used
  668. // for replacement on errors and also for flow control.
  669. //
  670. // They are only set at interrupt level.
  671. //
  672. SERIAL_CHARS SpecialChars;
  673. //
  674. // This structure holds the handshake and control flow
  675. // settings for the serial driver.
  676. //
  677. // It is only set at interrupt level. It can be
  678. // be read at any level with the control lock held.
  679. //
  680. SERIAL_HANDFLOW HandFlow;
  681. //
  682. // Holds performance statistics that applications can query.
  683. // Reset on each open. Only set at device level.
  684. //
  685. SERIALPERF_STATS PerfStats;
  686. //
  687. // This holds what we beleive to be the current value of
  688. // the line control register.
  689. //
  690. // It should only be accessed under protection of the control
  691. // lock since more than one request can be in the control dispatch
  692. // routine at one time.
  693. //
  694. ULONG CommParity;
  695. ULONG CommDataLen;
  696. //
  697. // We keep track of whether the somebody has the device currently
  698. // opened with a simple boolean. We need to know this so that
  699. // spurious interrupts from the device (especially during initialization)
  700. // will be ignored. This value is only accessed in the ISR and
  701. // is only set via synchronization routines. We may be able
  702. // to get rid of this boolean when the code is more fleshed out.
  703. //
  704. BOOLEAN DeviceIsOpened;
  705. //
  706. // This is only accessed at interrupt level. It keeps track
  707. // of whether the holding register is empty.
  708. //
  709. BOOLEAN HoldingEmpty;
  710. //
  711. // This variable is only accessed at interrupt level. It
  712. // indicates that we want to transmit a character immediately.
  713. // That is - in front of any characters that could be transmitting
  714. // from a normal write.
  715. //
  716. BOOLEAN TransmitImmediate;
  717. //
  718. // This variable is only accessed at interrupt level. Whenever
  719. // a wait is initiated this variable is set to false.
  720. // Whenever any kind of character is written it is set to true.
  721. // Whenever the write queue is found to be empty the code that
  722. // is processing that completing irp will synchonize with the interrupt.
  723. // If this synchronization code finds that the variable is true and that
  724. // there is a wait on the transmit queue being empty then it is
  725. // certain that the queue was emptied and that it has happened since
  726. // the wait was initiated.
  727. //
  728. BOOLEAN EmptiedTransmit;
  729. //
  730. // This simply indicates that the port associated with this
  731. // extension is part of a multiport card.
  732. //
  733. // BOOLEAN PortOnAMultiportCard;
  734. #ifndef POLL
  735. //
  736. // We keep the following values around so that we can connect
  737. // to the interrupt and report resources after the configuration
  738. // record is gone.
  739. //
  740. ULONG Vector;
  741. KIRQL Irql;
  742. ULONG OriginalVector;
  743. ULONG OriginalIrql;
  744. KINTERRUPT_MODE InterruptMode;
  745. KAFFINITY ProcessorAffinity;
  746. #endif
  747. ULONG RuntimeAddressSpace;
  748. ULONG BoardMemoryAddressSpace;
  749. ULONG BusNumber;
  750. INTERFACE_TYPE InterfaceType;
  751. //
  752. // Port index for multiport devices
  753. //
  754. ULONG PortIndex;
  755. //
  756. // We hold the character that should be transmitted immediately.
  757. //
  758. // Note that we can't use this to determine whether there is
  759. // a character to send because the character to send could be
  760. // zero.
  761. //
  762. UCHAR ImmediateChar;
  763. //
  764. // This holds the mask that will be used to mask off unwanted
  765. // data bits of the received data (valid data bits can be 5,6,7,8)
  766. // The mask will normally be 0xff. This is set while the control
  767. // lock is held since it wouldn't have adverse effects on the
  768. // isr if it is changed in the middle of reading characters.
  769. // (What it would do to the app is another question - but then
  770. // the app asked the driver to do it.)
  771. //
  772. UCHAR ValidDataMask;
  773. //
  774. // The application can turn on a mode,via the
  775. // IOCTL_CYZ_LSRMST_INSERT ioctl, that will cause the
  776. // serial driver to insert the line status or the modem
  777. // status into the RX stream. The parameter with the ioctl
  778. // is a pointer to a UCHAR. If the value of the UCHAR is
  779. // zero, then no insertion will ever take place. If the
  780. // value of the UCHAR is non-zero (and not equal to the
  781. // xon/xoff characters), then the serial driver will insert.
  782. //
  783. UCHAR EscapeChar;
  784. // REMOVED FANNY
  785. // //
  786. // // This boolean will be true if a 16550 is present *and* enabled.
  787. // //
  788. // BOOLEAN FifoPresent;
  789. //
  790. // //
  791. // // This denotes that this particular port is an on the motherboard
  792. // // port for the Jensen hardware. On these ports the OUT2 bit
  793. // // which is used to enable/disable interrupts is always hight.
  794. // //
  795. // BOOLEAN Jensen;
  796. //
  797. // This is the water mark that the rxfifo should be
  798. // set to when the fifo is turned on. This is not the actual
  799. // value, but the encoded value that goes into the register.
  800. //
  801. ULONG RxFifoTrigger;
  802. #ifndef POLL
  803. //
  804. // Says whether this device can share interrupts with devices
  805. // other than serial devices.
  806. //
  807. BOOLEAN InterruptShareable;
  808. #endif
  809. //
  810. // Records whether we actually created the symbolic link name
  811. // at driver load time. If we didn't create it, we won't try
  812. // to distry it when we unload.
  813. //
  814. BOOLEAN CreatedSymbolicLink;
  815. //
  816. // Records whether we actually created an entry in SERIALCOMM
  817. // at driver load time. If we didn't create it, we won't try
  818. // to destroy it when the device is removed.
  819. //
  820. BOOLEAN CreatedSerialCommEntry;
  821. //
  822. // We place all of the kernel and Io subsystem "opaque" structures
  823. // at the end of the extension. We don't care about their contents.
  824. //
  825. //
  826. // This lock will be used to protect various fields in
  827. // the extension that are set (& read) in the extension
  828. // by the io controls.
  829. //
  830. KSPIN_LOCK ControlLock;
  831. //
  832. // This lock will be used to protect the accept / reject state
  833. // transitions and flags of the driver It must be acquired
  834. // before a cancel lock
  835. //
  836. KSPIN_LOCK FlagsLock;
  837. #ifdef POLL
  838. //
  839. // This lock will be used to protect various fields in
  840. // the extension and in the hardware that are set (& read)
  841. // by the Timer Dpc. In the NT driver, we used ControlLock
  842. // for this.
  843. //
  844. KSPIN_LOCK PollLock; // Added to fix Modem Share test 53 freeze (dead lock)
  845. #endif
  846. //
  847. // This points to a DPC used to complete read requests.
  848. //
  849. KDPC CompleteWriteDpc;
  850. //
  851. // This points to a DPC used to complete read requests.
  852. //
  853. KDPC CompleteReadDpc;
  854. //
  855. // This dpc is fired off if the timer for the total timeout
  856. // for the read expires. It will execute a dpc routine that
  857. // will cause the current read to complete.
  858. //
  859. //
  860. KDPC TotalReadTimeoutDpc;
  861. //
  862. // This dpc is fired off if the timer for the interval timeout
  863. // expires. If no more characters have been read then the
  864. // dpc routine will cause the read to complete. However, if
  865. // more characters have been read then the dpc routine will
  866. // resubmit the timer.
  867. //
  868. KDPC IntervalReadTimeoutDpc;
  869. //
  870. // This dpc is fired off if the timer for the total timeout
  871. // for the write expires. It will execute a dpc routine that
  872. // will cause the current write to complete.
  873. //
  874. //
  875. KDPC TotalWriteTimeoutDpc;
  876. //
  877. // This dpc is fired off if a comm error occurs. It will
  878. // execute a dpc routine that will cancel all pending reads
  879. // and writes.
  880. //
  881. KDPC CommErrorDpc;
  882. //
  883. // This dpc is fired off if an event occurs and there was
  884. // a irp waiting on that event. A dpc routine will execute
  885. // that completes the irp.
  886. //
  887. KDPC CommWaitDpc;
  888. //
  889. // This dpc is fired off when the transmit immediate char
  890. // character is given to the hardware. It will simply complete
  891. // the irp.
  892. //
  893. KDPC CompleteImmediateDpc;
  894. //
  895. // This dpc is fired off if the transmit immediate char
  896. // character times out. The dpc routine will "grab" the
  897. // irp from the isr and time it out.
  898. //
  899. KDPC TotalImmediateTimeoutDpc;
  900. //
  901. // This dpc is fired off if the timer used to "timeout" counting
  902. // the number of characters received after the Xoff ioctl is started
  903. // expired.
  904. //
  905. KDPC XoffCountTimeoutDpc;
  906. //
  907. // This dpc is fired off if the xoff counter actually runs down
  908. // to zero.
  909. //
  910. KDPC XoffCountCompleteDpc;
  911. //
  912. // This dpc is fired off only from device level to start off
  913. // a timer that will queue a dpc to check if the RTS line
  914. // should be lowered when we are doing transmit toggling.
  915. //
  916. KDPC StartTimerLowerRTSDpc;
  917. //
  918. // This dpc is fired off when a timer expires (after one
  919. // character time), so that code can be invoked that will
  920. // check to see if we should lower the RTS line when
  921. // doing transmit toggling.
  922. //
  923. KDPC PerhapsLowerRTSDpc;
  924. //
  925. // This DPC is fired to set an event stating that all other
  926. // DPC's have been finish for this device extension so that
  927. // paged code may be unlocked.
  928. //
  929. KDPC IsrUnlockPagesDpc;
  930. //
  931. // This is the kernal timer structure used to handle
  932. // total read request timing.
  933. //
  934. KTIMER ReadRequestTotalTimer;
  935. //
  936. // This is the kernal timer structure used to handle
  937. // interval read request timing.
  938. //
  939. KTIMER ReadRequestIntervalTimer;
  940. //
  941. // This is the kernal timer structure used to handle
  942. // total time request timing.
  943. //
  944. KTIMER WriteRequestTotalTimer;
  945. //
  946. // This is the kernal timer structure used to handle
  947. // total time request timing.
  948. //
  949. KTIMER ImmediateTotalTimer;
  950. //
  951. // This timer is used to timeout the xoff counter
  952. // io.
  953. //
  954. KTIMER XoffCountTimer;
  955. //
  956. // This timer is used to invoke a dpc one character time
  957. // after the timer is set. That dpc will be used to check
  958. // whether we should lower the RTS line if we are doing
  959. // transmit toggling.
  960. //
  961. KTIMER LowerRTSTimer;
  962. //
  963. // This is a pointer to the next lower device in the IRP stack.
  964. //
  965. PDEVICE_OBJECT LowerDeviceObject;
  966. //
  967. // This is where keep track of the power state the device is in.
  968. //
  969. DEVICE_POWER_STATE PowerState;
  970. //
  971. // Pointer to the driver object
  972. //
  973. PDRIVER_OBJECT DriverObject;
  974. //
  975. // Event used to do some synchronization with the devices underneath me
  976. // (namely ACPI)
  977. //
  978. KEVENT SerialSyncEvent;
  979. //
  980. // String where we keep the symbolic link that is returned to us when we
  981. // register our device under the COMM class with the Plug and Play manager.
  982. //
  983. UNICODE_STRING DeviceClassSymbolicName;
  984. //
  985. // Count of pending IRP's
  986. //
  987. ULONG PendingIRPCnt;
  988. //
  989. // Accepting requests?
  990. //
  991. ULONG DevicePNPAccept;
  992. //
  993. // No IRP's pending event
  994. //
  995. KEVENT PendingIRPEvent;
  996. //
  997. // PNP State
  998. //
  999. ULONG PNPState;
  1000. //
  1001. // Misc Flags
  1002. //
  1003. ULONG Flags;
  1004. //
  1005. // Open count
  1006. //
  1007. LONG OpenCount;
  1008. //
  1009. // Start sync event
  1010. //
  1011. KEVENT CyzStartEvent;
  1012. //
  1013. // Current state during powerdown
  1014. //
  1015. CYZ_DEVICE_STATE DeviceState;
  1016. //
  1017. // Device stack capabilites
  1018. //
  1019. DEVICE_POWER_STATE DeviceStateMap[PowerSystemMaximum];
  1020. //
  1021. // Event to signal transition to D0 completion
  1022. //
  1023. KEVENT PowerD0Event;
  1024. //
  1025. // List of stalled IRP's
  1026. //
  1027. LIST_ENTRY StalledIrpQueue;
  1028. //
  1029. // Mutex on open status
  1030. //
  1031. FAST_MUTEX OpenMutex;
  1032. //
  1033. // Mutex on close
  1034. //
  1035. FAST_MUTEX CloseMutex;
  1036. //
  1037. // TRUE if we own power policy
  1038. //
  1039. BOOLEAN OwnsPowerPolicy;
  1040. //
  1041. // SystemWake from devcaps
  1042. //
  1043. SYSTEM_POWER_STATE SystemWake;
  1044. //
  1045. // DeviceWake from devcaps
  1046. //
  1047. DEVICE_POWER_STATE DeviceWake;
  1048. //
  1049. // Our PDO
  1050. //
  1051. PDEVICE_OBJECT Pdo;
  1052. //
  1053. // Should we enable wakeup
  1054. //
  1055. BOOLEAN SendWaitWake;
  1056. //
  1057. // Pending wait wake IRP
  1058. //
  1059. PIRP PendingWakeIrp;
  1060. //
  1061. // WMI Information
  1062. //
  1063. WMILIB_CONTEXT WmiLibInfo;
  1064. //
  1065. // Name to use as WMI identifier
  1066. //
  1067. UNICODE_STRING WmiIdentifier;
  1068. //
  1069. // WMI Comm Data
  1070. //
  1071. SERIAL_WMI_COMM_DATA WmiCommData;
  1072. //
  1073. // WMI HW Data
  1074. //
  1075. SERIAL_WMI_HW_DATA WmiHwData;
  1076. //
  1077. // WMI Performance Data
  1078. //
  1079. SERIAL_WMI_PERF_DATA WmiPerfData;
  1080. //
  1081. // Pending DPC count
  1082. //
  1083. ULONG DpcCount;
  1084. //
  1085. // Pending DPC event
  1086. //
  1087. KEVENT PendingDpcEvent;
  1088. //
  1089. // Should we expose external interfaces?
  1090. //
  1091. ULONG SkipNaming;
  1092. //
  1093. // Com port number.
  1094. //
  1095. //ULONG Com;
  1096. //
  1097. // Flag to indicate if Command Failure error was already logged.
  1098. // Only one log per driver load. Otherwise, the system may crash if
  1099. // too many logs start happening.
  1100. //
  1101. BOOLEAN CmdFailureLog;
  1102. //
  1103. // DCD Status when the firmware detected the DCD signal change
  1104. //
  1105. ULONG DCDstatus;
  1106. //
  1107. // Flag to indicate that the fw has processed the C_CM_IOCTLW command.
  1108. //
  1109. BOOLEAN IoctlwProcessed;
  1110. //
  1111. // Flag read from the Registry. It indicates when Write status is returned.
  1112. //
  1113. BOOLEAN ReturnStatusAfterFwEmpty;
  1114. //
  1115. // Flag read from the Registry. It indicates that the reception should
  1116. // give the packets as soon as the second 7E is received.
  1117. //
  1118. BOOLEAN PPPaware;
  1119. //
  1120. // Flag to indicate that the driver can return the status of CyzWrite.
  1121. //
  1122. BOOLEAN ReturnWriteStatus;
  1123. // These two booleans are used to indicate to the isr transmit
  1124. // code that it should send the xon or xoff character. They are
  1125. // only accessed at open and at interrupt level.
  1126. //
  1127. BOOLEAN SendXonChar;
  1128. BOOLEAN SendXoffChar;
  1129. //
  1130. // PCI slot where the board is inserted.
  1131. //
  1132. ULONG PciSlot;
  1133. } CYZ_DEVICE_EXTENSION,*PCYZ_DEVICE_EXTENSION;
  1134. #define CYZ_PNPACCEPT_OK 0x0L
  1135. #define CYZ_PNPACCEPT_REMOVING 0x1L
  1136. #define CYZ_PNPACCEPT_STOPPING 0x2L
  1137. #define CYZ_PNPACCEPT_STOPPED 0x4L
  1138. #define CYZ_PNPACCEPT_SURPRISE_REMOVING 0x8L
  1139. #define CYZ_PNP_ADDED 0x0L
  1140. #define CYZ_PNP_STARTED 0x1L
  1141. #define CYZ_PNP_QSTOP 0x2L
  1142. #define CYZ_PNP_STOPPING 0x3L
  1143. #define CYZ_PNP_QREMOVE 0x4L
  1144. #define CYZ_PNP_REMOVING 0x5L
  1145. #define CYZ_PNP_RESTARTING 0x6L
  1146. #define CYZ_FLAGS_CLEAR 0x0L
  1147. #define CYZ_FLAGS_STARTED 0x1L
  1148. #define CYZ_FLAGS_STOPPED 0x2L
  1149. #define CYZ_FLAGS_BROKENHW 0x4L
  1150. //
  1151. // When dealing with a multi-port device (that is possibly
  1152. // daisy chained with other multi-port device), the interrupt
  1153. // service routine will actually be a routine that determines
  1154. // which port on which board is actually causing the interrupt.
  1155. //
  1156. // The following structure is used so that only one device
  1157. // extension will actually need to connect to the interrupt.
  1158. // The following structure which is passed to the interrupt
  1159. // service routine contains the addresses of all of the
  1160. // interrupt status registers (there will be multiple
  1161. // status registers when multi-port cards are chained). It
  1162. // will contain the addresses of all the extensions whose
  1163. // devices are being serviced by this interrupt.
  1164. //
  1165. #ifdef POLL
  1166. typedef struct _CYZ_DISPATCH {
  1167. ULONG NChannels;
  1168. PCYZ_DEVICE_EXTENSION Extensions[CYZ_MAX_PORTS];
  1169. KTIMER PollingTimer;
  1170. LARGE_INTEGER PollingTime;
  1171. ULONG PollingPeriod;
  1172. KDPC PollingDpc;
  1173. BOOLEAN PollingStarted;
  1174. BOOLEAN PollingDrained;
  1175. ULONG PollingCount;
  1176. KSPIN_LOCK PollingLock;
  1177. KSPIN_LOCK PciDoorbellLock;
  1178. KEVENT PendingDpcEvent;
  1179. } CYZ_DISPATCH,*PCYZ_DISPATCH;
  1180. #else
  1181. typedef struct _CYZ_DISPATCH {
  1182. ULONG NChannels;
  1183. PCYZ_DEVICE_EXTENSION Extensions[CYZ_MAX_PORTS];
  1184. BOOLEAN PoweredOn[CYZ_MAX_PORTS];
  1185. } CYZ_DISPATCH,*PCYZ_DISPATCH;
  1186. #endif
  1187. //
  1188. // This is exported from the kernel. It is used to point
  1189. // to the address that the kernel debugger is using.
  1190. //
  1191. extern PUCHAR *KdComPortInUse;
  1192. typedef enum _CYZ_MEM_COMPARES {
  1193. AddressesAreEqual,
  1194. AddressesOverlap,
  1195. AddressesAreDisjoint
  1196. } CYZ_MEM_COMPARES,*PCYZ_MEM_COMPARES;
  1197. typedef struct _CYZ_GLOBALS {
  1198. LIST_ENTRY AllDevObjs;
  1199. PVOID PAGESER_Handle;
  1200. UNICODE_STRING RegistryPath;
  1201. KSPIN_LOCK GlobalsSpinLock;
  1202. #if DBG
  1203. ULONG PAGESER_Count;
  1204. #endif // DBG
  1205. } CYZ_GLOBALS, *PCYZ_GLOBALS;
  1206. extern CYZ_GLOBALS CyzGlobals;
  1207. typedef struct _SERIAL_PTR_CTX {
  1208. ULONG isPointer;
  1209. PHYSICAL_ADDRESS Port;
  1210. ULONG Vector;
  1211. } SERIAL_PTR_CTX, *PSERIAL_PTR_CTX;
  1212. #define DEVICE_OBJECT_NAME_LENGTH 128
  1213. #define SYMBOLIC_NAME_LENGTH 128
  1214. #define SERIAL_DEVICE_MAP L"SERIALCOMM"
  1215. //
  1216. // Return values for mouse detection callback
  1217. //
  1218. #define SERIAL_FOUNDPOINTER_PORT 1
  1219. #define SERIAL_FOUNDPOINTER_VECTOR 2
  1220. #define CyzCompleteRequest(PDevExt, PIrp, PriBoost) \
  1221. { \
  1222. CyzDbgPrintEx(CYZIRPPATH, "Complete Irp: %X\n", (PIrp)); \
  1223. IoCompleteRequest((PIrp), (PriBoost)); \
  1224. CyzIRPEpilogue((PDevExt)); \
  1225. }
  1226. #define SERIAL_WMI_GUID_LIST_SIZE 5
  1227. extern WMIGUIDREGINFO SerialWmiGuidList[SERIAL_WMI_GUID_LIST_SIZE];
  1228. // For Cyclades-Z
  1229. #define CYZ_BASIC_RXTRIGGER 0x08 // Used in IOCTL_SERIAL_INTERNAL_BASIC_SETTINGS
  1230. #define Z_COMPATIBLE_FIRMWARE 0x323 // C_CM_TXFEMPTY support added.