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.

1455 lines
40 KiB

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