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.

2971 lines
96 KiB

  1. /*++
  2. Copyright (c) 1990, 1991, 1992, 1993 - 1997 Microsoft Corporation
  3. Module Name :
  4. serial.h
  5. Abstract:
  6. Type definitions and data for the serial port driver
  7. Author:
  8. Anthony V. Ercolano April 8, 1991
  9. --*/
  10. #ifdef POOL_TAGGING
  11. #undef ExAllocatePool
  12. #undef ExAllocatePoolWithQuota
  13. #define ExAllocatePool(a,b) ExAllocatePoolWithTag(a,b,'XMOC')
  14. #define ExAllocatePoolWithQuota(a,b) ExAllocatePoolWithQuotaTag(a,b,'XMOC')
  15. #endif
  16. //
  17. // The following definition is used to include/exclude changes made for power
  18. // support in the driver. If non-zero the support is included. If zero the
  19. // support is excluded.
  20. //
  21. #define POWER_SUPPORT 1
  22. //
  23. // The following is used to tell the serial driver to perform legacy detection
  24. // and initialization until PnP functionality can be fully implemented.
  25. //
  26. // #define FAKE_IT 1
  27. #define RM_PNP_CODE
  28. #if DBG
  29. #define SERDIAG1 ((ULONG)0x00000001)
  30. #define SERDIAG2 ((ULONG)0x00000002)
  31. #define SERDIAG3 ((ULONG)0x00000004)
  32. #define SERDIAG4 ((ULONG)0x00000008)
  33. #define SERDIAG5 ((ULONG)0x00000010)
  34. #define SERIRPPATH ((ULONG)0x00000020)
  35. #define SERINITCODE ((ULONG)0x00000040)
  36. #define SERTRACECALLS ((ULONG)0x00000040)
  37. #define SERPNPPOWER ((ULONG)0x00000100)
  38. #define SERFLOW ((ULONG)0x20000000)
  39. #define SERERRORS ((ULONG)0x40000000)
  40. #define SERBUGCHECK ((ULONG)0x80000000)
  41. #define SERDBGALL ((ULONG)0xFFFFFFFF)
  42. #define SER_DBG_DEFAULT SERDBGALL
  43. extern ULONG SerialDebugLevel;
  44. #if defined(NEC_98)
  45. //
  46. // DbgPrint header changed from SERIAL to SER101
  47. //
  48. #define SerialDump(LEVEL,STRING) \
  49. do { \
  50. ULONG _level = (LEVEL); \
  51. if (SerialDebugLevel & _level) { \
  52. DbgPrint ("SER101: "); \
  53. DbgPrint STRING; \
  54. } \
  55. if (_level == SERBUGCHECK) { \
  56. ASSERT(FALSE); \
  57. } \
  58. } while (0)
  59. #else
  60. #define SerialDump(LEVEL,STRING) \
  61. do { \
  62. ULONG _level = (LEVEL); \
  63. if (SerialDebugLevel & _level) { \
  64. DbgPrint STRING; \
  65. } \
  66. if (_level == SERBUGCHECK) { \
  67. ASSERT(FALSE); \
  68. } \
  69. } while (0)
  70. #endif //defined(NEC_98)
  71. #else
  72. #define SerialDump(LEVEL,STRING) do {NOTHING;} while (0)
  73. #endif
  74. //
  75. // Some default driver values. We will check the registry for
  76. // them first.
  77. //
  78. #define SERIAL_UNINITIALIZED_DEFAULT 1234567
  79. #define SERIAL_FORCE_FIFO_DEFAULT 1
  80. #define SERIAL_RX_FIFO_DEFAULT 8
  81. #define SERIAL_TX_FIFO_DEFAULT 14
  82. #define SERIAL_PERMIT_SHARE_DEFAULT 0
  83. #define SERIAL_LOG_FIFO_DEFAULT 0
  84. //
  85. // This define gives the default Object directory
  86. // that we should use to insert the symbolic links
  87. // between the NT device name and namespace used by
  88. // that object directory.
  89. #define DEFAULT_DIRECTORY L"DosDevices"
  90. //
  91. // For the above directory, the serial port will
  92. // use the following name as the suffix of the serial
  93. // ports for that directory. It will also append
  94. // a number onto the end of the name. That number
  95. // will start at 1.
  96. #define DEFAULT_SERIAL_NAME L"COM"
  97. //
  98. //
  99. // This define gives the default NT name for
  100. // for serial ports detected by the firmware.
  101. // This name will be appended to Device prefix
  102. // with a number following it. The number is
  103. // incremented each time encounter a serial
  104. // port detected by the firmware. Note that
  105. // on a system with multiple busses, this means
  106. // that the first port on a bus is not necessarily
  107. // \Device\Serial0.
  108. //
  109. #if defined(NEC_98)
  110. #define DEFAULT_NT_SUFFIX L"Ser101"
  111. #else
  112. #define DEFAULT_NT_SUFFIX L"Serial"
  113. #endif //defined(NEC_98)
  114. #if defined(NEC_98)
  115. //
  116. // Out of offsets from the base register address of the
  117. // various registers for the 71051.
  118. //
  119. #define SYSTEM_PORT_C 0x35
  120. #define TIMER_MODE_REGISTER 0x77
  121. #define TIMER_COUNT_REGISTER 0x75
  122. #define COMMAND_SET 0x32
  123. #define MODE_SET 0x32
  124. #define IO_DELAY_REGISTER 0x5f
  125. #define CONFIG_INDEX_REGISTER 0x411
  126. #define CONFIG_DATA_REGISTER 0x413
  127. #define TRANSFER_CLOCK_ENABLE_ADDRESS (UCHAR)0x83
  128. #else
  129. #endif //defined(NEC_98)
  130. //
  131. // This value - which could be redefined at compile
  132. // time, define the stride between registers
  133. //
  134. #if !defined(SERIAL_REGISTER_STRIDE)
  135. #define SERIAL_REGISTER_STRIDE 1
  136. #endif
  137. //
  138. // Offsets from the base register address of the
  139. // various registers for the 8250 family of UARTS.
  140. //
  141. #define RECEIVE_BUFFER_REGISTER ((ULONG)((0x00)*SERIAL_REGISTER_STRIDE))
  142. #define TRANSMIT_HOLDING_REGISTER ((ULONG)((0x00)*SERIAL_REGISTER_STRIDE))
  143. #if defined(NEC_98)
  144. #define INTERRUPT_ENABLE_REGISTER ((ULONG)((0x08)*SERIAL_REGISTER_STRIDE))
  145. #define INTERRUPT_IDENT_REGISTER ((ULONG)((0x06)*SERIAL_REGISTER_STRIDE))
  146. #define FIFO_CONTROL_REGISTER ((ULONG)((0x08)*SERIAL_REGISTER_STRIDE))
  147. #define LINE_CONTROL_REGISTER ((ULONG)((0x03)*SERIAL_REGISTER_STRIDE))
  148. #define MODEM_CONTROL_REGISTER ((ULONG)((0x04)*SERIAL_REGISTER_STRIDE))
  149. #define LINE_STATUS_REGISTER ((ULONG)((0x02)*SERIAL_REGISTER_STRIDE))
  150. #define MODEM_STATUS_REGISTER ((ULONG)((0x04)*SERIAL_REGISTER_STRIDE))
  151. #define DIVISOR_LATCH_LSB ((ULONG)((0x00)*SERIAL_REGISTER_STRIDE))
  152. #define DIVISOR_LATCH_MSB ((ULONG)((0x01)*SERIAL_REGISTER_STRIDE))
  153. #define VFAST_BAUDCLK_REGISTER ((ULONG)((0x0a)*SERIAL_REGISTER_STRIDE))
  154. #define SERIAL_REGISTER_SPAN ((ULONG)(10*SERIAL_REGISTER_STRIDE))
  155. #else
  156. #define INTERRUPT_ENABLE_REGISTER ((ULONG)((0x01)*SERIAL_REGISTER_STRIDE))
  157. #define INTERRUPT_IDENT_REGISTER ((ULONG)((0x02)*SERIAL_REGISTER_STRIDE))
  158. #define FIFO_CONTROL_REGISTER ((ULONG)((0x02)*SERIAL_REGISTER_STRIDE))
  159. #define LINE_CONTROL_REGISTER ((ULONG)((0x03)*SERIAL_REGISTER_STRIDE))
  160. #define MODEM_CONTROL_REGISTER ((ULONG)((0x04)*SERIAL_REGISTER_STRIDE))
  161. #define LINE_STATUS_REGISTER ((ULONG)((0x05)*SERIAL_REGISTER_STRIDE))
  162. #define MODEM_STATUS_REGISTER ((ULONG)((0x06)*SERIAL_REGISTER_STRIDE))
  163. #define DIVISOR_LATCH_LSB ((ULONG)((0x00)*SERIAL_REGISTER_STRIDE))
  164. #define DIVISOR_LATCH_MSB ((ULONG)((0x01)*SERIAL_REGISTER_STRIDE))
  165. #define SERIAL_REGISTER_SPAN ((ULONG)(7*SERIAL_REGISTER_STRIDE))
  166. #endif //defined(NEC_98)
  167. //
  168. // If we have an interrupt status register this is its assumed
  169. // length.
  170. //
  171. #define SERIAL_STATUS_LENGTH ((ULONG)(1*SERIAL_REGISTER_STRIDE))
  172. #if defined(NEC_98)
  173. //
  174. // Offset from the base register address of the
  175. // INDEX registers for the PC-9801-101(on the 8251 family controler)
  176. //
  177. #define INDEX_REGISTER_OFFSET ((ULONG)((0x04)*SERIAL_REGISTER_STRIDE))
  178. #define INDEX_DATA_REGISTER_OFFSET ((ULONG)((0x05)*SERIAL_REGISTER_STRIDE))
  179. //
  180. // 1stCCU Transfer Clock Enable Port
  181. //
  182. #define TXC_PERMIT ((UCHAR)0x00)
  183. #define TXC_PROHIBIT ((UCHAR)0x01)
  184. //
  185. // V.Fast mode buad rate clock for 101
  186. //
  187. #define VFAST_BAUD_0075 ((SHORT)0x03)
  188. #define VFAST_BAUD_0150 ((SHORT)0x04)
  189. #define VFAST_BAUD_0300 ((SHORT)0x05)
  190. #define VFAST_BAUD_0600 ((SHORT)0x06)
  191. #define VFAST_BAUD_1200 ((SHORT)0x07)
  192. #define VFAST_BAUD_2400 ((SHORT)0x08)
  193. #define VFAST_BAUD_4800 ((SHORT)0x09)
  194. #define VFAST_BAUD_9600 ((SHORT)0x0a)
  195. #define VFAST_BAUD_14400 ((SHORT)0x0b)
  196. #define VFAST_BAUD_19200 ((SHORT)0x0c)
  197. #define VFAST_BAUD_38400 ((SHORT)0x0d)
  198. #define VFAST_BAUD_57600 ((SHORT)0x0e)
  199. #define VFAST_BAUD_115200 ((SHORT)0x0f)
  200. //
  201. // Communication mode default(ASYNC)
  202. //
  203. #define COMMUNICATION_MODE 0x00
  204. //
  205. // default control word to Timer Mode register
  206. //
  207. #define TIMER_DEFAULT_CONTROL ((UCHAR)0xb6)
  208. //
  209. // default out data to command set register
  210. //
  211. #define COMMAND_DEFAULT_SET ((UCHAR)0x15)
  212. #define COMMAND_ERROR_RESET ((UCHAR)0x40)
  213. //
  214. // default baud rate mode(x16) to Mode Set register
  215. //
  216. #define BAUDRATE_DEFAULT_MODE ((UCHAR)0x02)
  217. //
  218. // default out data to Io Delay register
  219. //
  220. #define IO_DELAY_DATA ((UCHAR)0x00)
  221. //
  222. // Fifo mode enable
  223. //
  224. #define DISABLE_FIFO_MODE ((UCHAR)0x00)
  225. #define SUPPORT_FIFO_MODE ((UCHAR)0x40)
  226. #define SUPPORT_FIFO_MASK ((UCHAR)0x60)
  227. //
  228. // Interrupt enable bit
  229. //
  230. #define MODEM_STATUS_INTERRUPT ((UCHAR)0x10)
  231. #define LINE_STATUS_INTERRUPT ((UCHAR)0x08)
  232. #define TRANSMIT_FIFO_INTERRUPT ((UCHAR)0x04)
  233. #define RECEIVE_FIFO_INTERRUPT ((UCHAR)0x01)
  234. //
  235. // These defines are used to set the line control register.
  236. //
  237. #define SER71051_PARITY_MASK ((UCHAR)0x18)
  238. #define SER71051_1_STOP ((UCHAR)0x40)
  239. #define SER71051_1_5_STOP ((UCHAR)0x80)
  240. #define SER71051_2_STOP ((UCHAR)0xc0)
  241. // This defines the bit used to control whether the device is sending
  242. // a break. When this bit is set the device is sending a space (logic 0).
  243. //
  244. #define SER71051_SEND_BREAK 0x08
  245. #else
  246. #endif //defined(NEC_98)
  247. //
  248. // Bitmask definitions for accessing the 8250 device registers.
  249. //
  250. //
  251. // These bits define the number of data bits trasmitted in
  252. // the Serial Data Unit (SDU - Start,data, parity, and stop bits)
  253. //
  254. #define SERIAL_DATA_LENGTH_5 0x00
  255. #define SERIAL_DATA_LENGTH_6 0x01
  256. #define SERIAL_DATA_LENGTH_7 0x02
  257. #define SERIAL_DATA_LENGTH_8 0x03
  258. //
  259. // These masks define the interrupts that can be enabled or disabled.
  260. //
  261. //
  262. // This interrupt is used to notify that there is new incomming
  263. // data available. The SERIAL_RDA interrupt is enabled by this bit.
  264. //
  265. #define SERIAL_IER_RDA 0x01
  266. //
  267. // This interrupt is used to notify that there is space available
  268. // in the transmitter for another character. The SERIAL_THR
  269. // interrupt is enabled by this bit.
  270. //
  271. #define SERIAL_IER_THR 0x02
  272. //
  273. // This interrupt is used to notify that some sort of error occured
  274. // with the incomming data. The SERIAL_RLS interrupt is enabled by
  275. // this bit.
  276. #define SERIAL_IER_RLS 0x04
  277. //
  278. // This interrupt is used to notify that some sort of change has
  279. // taken place in the modem control line. The SERIAL_MS interrupt is
  280. // enabled by this bit.
  281. //
  282. #define SERIAL_IER_MS 0x08
  283. //
  284. // These masks define the values of the interrupt identification
  285. // register. The low bit must be clear in the interrupt identification
  286. // register for any of these interrupts to be valid. The interrupts
  287. // are defined in priority order, with the highest value being most
  288. // important. See above for a description of what each interrupt
  289. // implies.
  290. //
  291. #define SERIAL_IIR_RLS 0x06
  292. #define SERIAL_IIR_RDA 0x04
  293. #define SERIAL_IIR_CTI 0x0c
  294. #define SERIAL_IIR_THR 0x02
  295. #define SERIAL_IIR_MS 0x00
  296. //
  297. // This bit mask get the value of the high two bits of the
  298. // interrupt id register. If this is a 16550 class chip
  299. // these bits will be a one if the fifo's are enbled, otherwise
  300. // they will always be zero.
  301. //
  302. #define SERIAL_IIR_FIFOS_ENABLED 0xc0
  303. //
  304. // If the low bit is logic one in the interrupt identification register
  305. // this implies that *NO* interrupts are pending on the device.
  306. //
  307. #define SERIAL_IIR_NO_INTERRUPT_PENDING 0x01
  308. //
  309. // These masks define access to the fifo control register.
  310. //
  311. //
  312. // Enabling this bit in the fifo control register will turn
  313. // on the fifos. If the fifos are enabled then the high two
  314. // bits of the interrupt id register will be set to one. Note
  315. // that this only occurs on a 16550 class chip. If the high
  316. // two bits in the interrupt id register are not one then
  317. // we know we have a lower model chip.
  318. //
  319. //
  320. #define SERIAL_FCR_ENABLE ((UCHAR)0x01)
  321. #define SERIAL_FCR_RCVR_RESET ((UCHAR)0x02)
  322. #define SERIAL_FCR_TXMT_RESET ((UCHAR)0x04)
  323. //
  324. // This set of values define the high water marks (when the
  325. // interrupts trip) for the receive fifo.
  326. //
  327. #define SERIAL_1_BYTE_HIGH_WATER ((UCHAR)0x00)
  328. #define SERIAL_4_BYTE_HIGH_WATER ((UCHAR)0x40)
  329. #define SERIAL_8_BYTE_HIGH_WATER ((UCHAR)0x80)
  330. #define SERIAL_14_BYTE_HIGH_WATER ((UCHAR)0xc0)
  331. //
  332. // These masks define access to the line control register.
  333. //
  334. //
  335. // This defines the bit used to control the definition of the "first"
  336. // two registers for the 8250. These registers are the input/output
  337. // register and the interrupt enable register. When the DLAB bit is
  338. // enabled these registers become the least significant and most
  339. // significant bytes of the divisor value.
  340. //
  341. #define SERIAL_LCR_DLAB 0x80
  342. //
  343. // This defines the bit used to control whether the device is sending
  344. // a break. When this bit is set the device is sending a space (logic 0).
  345. //
  346. // Most protocols will assume that this is a hangup.
  347. //
  348. #define SERIAL_LCR_BREAK 0x40
  349. //
  350. // These defines are used to set the line control register.
  351. //
  352. #define SERIAL_5_DATA ((UCHAR)0x00)
  353. #define SERIAL_6_DATA ((UCHAR)0x01)
  354. #define SERIAL_7_DATA ((UCHAR)0x02)
  355. #define SERIAL_8_DATA ((UCHAR)0x03)
  356. #define SERIAL_DATA_MASK ((UCHAR)0x03)
  357. #define SERIAL_1_STOP ((UCHAR)0x00)
  358. #define SERIAL_1_5_STOP ((UCHAR)0x04) // Only valid for 5 data bits
  359. #define SERIAL_2_STOP ((UCHAR)0x04) // Not valid for 5 data bits
  360. #define SERIAL_STOP_MASK ((UCHAR)0x04)
  361. #define SERIAL_NONE_PARITY ((UCHAR)0x00)
  362. #define SERIAL_ODD_PARITY ((UCHAR)0x08)
  363. #define SERIAL_EVEN_PARITY ((UCHAR)0x18)
  364. #define SERIAL_MARK_PARITY ((UCHAR)0x28)
  365. #define SERIAL_SPACE_PARITY ((UCHAR)0x38)
  366. #define SERIAL_PARITY_MASK ((UCHAR)0x38)
  367. //
  368. // These masks define access the modem control register.
  369. //
  370. //
  371. // This bit controls the data terminal ready (DTR) line. When
  372. // this bit is set the line goes to logic 0 (which is then inverted
  373. // by normal hardware). This is normally used to indicate that
  374. // the device is available to be used. Some odd hardware
  375. // protocols (like the kernel debugger) use this for handshaking
  376. // purposes.
  377. //
  378. #define SERIAL_MCR_DTR 0x01
  379. //
  380. // This bit controls the ready to send (RTS) line. When this bit
  381. // is set the line goes to logic 0 (which is then inverted by the normal
  382. // hardware). This is used for hardware handshaking. It indicates that
  383. // the hardware is ready to send data and it is waiting for the
  384. // receiving end to set clear to send (CTS).
  385. //
  386. #define SERIAL_MCR_RTS 0x02
  387. //
  388. // This bit is used for general purpose output.
  389. //
  390. #define SERIAL_MCR_OUT1 0x04
  391. //
  392. // This bit is used for general purpose output.
  393. //
  394. #define SERIAL_MCR_OUT2 0x08
  395. //
  396. // This bit controls the loopback testing mode of the device. Basically
  397. // the outputs are connected to the inputs (and vice versa).
  398. //
  399. #define SERIAL_MCR_LOOP 0x10
  400. //
  401. // These masks define access to the line status register. The line
  402. // status register contains information about the status of data
  403. // transfer. The first five bits deal with receive data and the
  404. // last two bits deal with transmission. An interrupt is generated
  405. // whenever bits 1 through 4 in this register are set.
  406. //
  407. //
  408. // This bit is the data ready indicator. It is set to indicate that
  409. // a complete character has been received. This bit is cleared whenever
  410. // the receive buffer register has been read.
  411. //
  412. #define SERIAL_LSR_DR 0x01
  413. //
  414. // This is the overrun indicator. It is set to indicate that the receive
  415. // buffer register was not read befor a new character was transferred
  416. // into the buffer. This bit is cleared when this register is read.
  417. //
  418. #define SERIAL_LSR_OE 0x02
  419. //
  420. // This is the parity error indicator. It is set whenever the hardware
  421. // detects that the incoming serial data unit does not have the correct
  422. // parity as defined by the parity select in the line control register.
  423. // This bit is cleared by reading this register.
  424. //
  425. #define SERIAL_LSR_PE 0x04
  426. //
  427. // This is the framing error indicator. It is set whenever the hardware
  428. // detects that the incoming serial data unit does not have a valid
  429. // stop bit. This bit is cleared by reading this register.
  430. //
  431. #define SERIAL_LSR_FE 0x08
  432. //
  433. // This is the break interrupt indicator. It is set whenever the data
  434. // line is held to logic 0 for more than the amount of time it takes
  435. // to send one serial data unit. This bit is cleared whenever the
  436. // this register is read.
  437. //
  438. #define SERIAL_LSR_BI 0x10
  439. //
  440. // This is the transmit holding register empty indicator. It is set
  441. // to indicate that the hardware is ready to accept another character
  442. // for transmission. This bit is cleared whenever a character is
  443. // written to the transmit holding register.
  444. //
  445. #define SERIAL_LSR_THRE 0x20
  446. //
  447. // This bit is the transmitter empty indicator. It is set whenever the
  448. // transmit holding buffer is empty and the transmit shift register
  449. // (a non-software accessable register that is used to actually put
  450. // the data out on the wire) is empty. Basically this means that all
  451. // data has been sent. It is cleared whenever the transmit holding or
  452. // the shift registers contain data.
  453. //
  454. #define SERIAL_LSR_TEMT 0x40
  455. //
  456. // This bit indicates that there is at least one error in the fifo.
  457. // The bit will not be turned off until there are no more errors
  458. // in the fifo.
  459. //
  460. #define SERIAL_LSR_FIFOERR 0x80
  461. //
  462. // These masks are used to access the modem status register.
  463. // Whenever one of the first four bits in the modem status
  464. // register changes state a modem status interrupt is generated.
  465. //
  466. //
  467. // This bit is the delta clear to send. It is used to indicate
  468. // that the clear to send bit (in this register) has *changed*
  469. // since this register was last read by the CPU.
  470. //
  471. #define SERIAL_MSR_DCTS 0x01
  472. //
  473. // This bit is the delta data set ready. It is used to indicate
  474. // that the data set ready bit (in this register) has *changed*
  475. // since this register was last read by the CPU.
  476. //
  477. #define SERIAL_MSR_DDSR 0x02
  478. //
  479. // This is the trailing edge ring indicator. It is used to indicate
  480. // that the ring indicator input has changed from a low to high state.
  481. //
  482. #define SERIAL_MSR_TERI 0x04
  483. //
  484. // This bit is the delta data carrier detect. It is used to indicate
  485. // that the data carrier bit (in this register) has *changed*
  486. // since this register was last read by the CPU.
  487. //
  488. #define SERIAL_MSR_DDCD 0x08
  489. //
  490. // This bit contains the (complemented) state of the clear to send
  491. // (CTS) line.
  492. //
  493. #define SERIAL_MSR_CTS 0x10
  494. //
  495. // This bit contains the (complemented) state of the data set ready
  496. // (DSR) line.
  497. //
  498. #define SERIAL_MSR_DSR 0x20
  499. //
  500. // This bit contains the (complemented) state of the ring indicator
  501. // (RI) line.
  502. //
  503. #define SERIAL_MSR_RI 0x40
  504. //
  505. // This bit contains the (complemented) state of the data carrier detect
  506. // (DCD) line.
  507. //
  508. #define SERIAL_MSR_DCD 0x80
  509. //
  510. // This should be more than enough space to hold then
  511. // numeric suffix of the device name.
  512. //
  513. #define DEVICE_NAME_DELTA 20
  514. //
  515. // Up to 16 Ports Per card. However for sixteen
  516. // port cards the interrupt status register must me
  517. // the indexing kind rather then the bitmask kind.
  518. //
  519. //
  520. #define SERIAL_MAX_PORTS_INDEXED (16)
  521. #define SERIAL_MAX_PORTS_NONINDEXED (8)
  522. typedef struct _CONFIG_DATA {
  523. PHYSICAL_ADDRESS Controller;
  524. PHYSICAL_ADDRESS TrController;
  525. PHYSICAL_ADDRESS InterruptStatus;
  526. PHYSICAL_ADDRESS TrInterruptStatus;
  527. ULONG SpanOfController;
  528. ULONG SpanOfInterruptStatus;
  529. ULONG PortIndex;
  530. ULONG ClockRate;
  531. ULONG BusNumber;
  532. ULONG AddressSpace;
  533. ULONG DisablePort;
  534. ULONG ForceFifoEnable;
  535. ULONG RxFIFO;
  536. ULONG TxFIFO;
  537. ULONG PermitShare;
  538. ULONG PermitSystemWideShare;
  539. ULONG LogFifo;
  540. ULONG MaskInverted;
  541. KINTERRUPT_MODE InterruptMode;
  542. INTERFACE_TYPE InterfaceType;
  543. ULONG OriginalVector;
  544. ULONG OriginalIrql;
  545. ULONG TrVector;
  546. ULONG TrIrql;
  547. ULONG Affinity;
  548. ULONG Indexed;
  549. BOOLEAN Jensen;
  550. } CONFIG_DATA,*PCONFIG_DATA;
  551. //
  552. // Serial ISR switch structure
  553. //
  554. typedef struct _SERIAL_CISR_SW {
  555. BOOLEAN (*IsrFunc)(PKINTERRUPT, PVOID);
  556. PVOID Context;
  557. LIST_ENTRY SharerList;
  558. } SERIAL_CISR_SW, *PSERIAL_CISR_SW;
  559. //
  560. // This structure contains configuration data, much of which
  561. // is read from the registry.
  562. //
  563. typedef struct _SERIAL_FIRMWARE_DATA {
  564. PDRIVER_OBJECT DriverObject;
  565. ULONG ControllersFound;
  566. ULONG ForceFifoEnableDefault;
  567. ULONG DebugLevel;
  568. ULONG ShouldBreakOnEntry;
  569. ULONG RxFIFODefault;
  570. ULONG TxFIFODefault;
  571. ULONG PermitShareDefault;
  572. ULONG PermitSystemWideShare;
  573. ULONG LogFifoDefault;
  574. UNICODE_STRING Directory;
  575. UNICODE_STRING NtNameSuffix;
  576. UNICODE_STRING DirectorySymbolicName;
  577. LIST_ENTRY ConfigList;
  578. BOOLEAN JensenDetected;
  579. } SERIAL_FIRMWARE_DATA,*PSERIAL_FIRMWARE_DATA;
  580. //
  581. // Default xon/xoff characters.
  582. //
  583. #define SERIAL_DEF_XON 0x11
  584. #define SERIAL_DEF_XOFF 0x13
  585. //
  586. // Reasons that recption may be held up.
  587. //
  588. #define SERIAL_RX_DTR ((ULONG)0x01)
  589. #define SERIAL_RX_XOFF ((ULONG)0x02)
  590. #define SERIAL_RX_RTS ((ULONG)0x04)
  591. #define SERIAL_RX_DSR ((ULONG)0x08)
  592. //
  593. // Reasons that transmission may be held up.
  594. //
  595. #define SERIAL_TX_CTS ((ULONG)0x01)
  596. #define SERIAL_TX_DSR ((ULONG)0x02)
  597. #define SERIAL_TX_DCD ((ULONG)0x04)
  598. #define SERIAL_TX_XOFF ((ULONG)0x08)
  599. #define SERIAL_TX_BREAK ((ULONG)0x10)
  600. //
  601. // These values are used by the routines that can be used
  602. // to complete a read (other than interval timeout) to indicate
  603. // to the interval timeout that it should complete.
  604. //
  605. #define SERIAL_COMPLETE_READ_CANCEL ((LONG)-1)
  606. #define SERIAL_COMPLETE_READ_TOTAL ((LONG)-2)
  607. #define SERIAL_COMPLETE_READ_COMPLETE ((LONG)-3)
  608. //
  609. // These are default values that shouldn't appear in the registry
  610. //
  611. #define SERIAL_BAD_VALUE ((ULONG)-1)
  612. typedef struct _SERIAL_DEVICE_STATE {
  613. //
  614. // TRUE if we need to set the state to open
  615. // on a powerup
  616. //
  617. BOOLEAN Reopen;
  618. //
  619. // Hardware registers
  620. //
  621. UCHAR IER;
  622. // FCR is known by other values
  623. UCHAR LCR;
  624. UCHAR MCR;
  625. // LSR is never written
  626. // MSR is never written
  627. // SCR is either scratch or interrupt status
  628. } SERIAL_DEVICE_STATE, *PSERIAL_DEVICE_STATE;
  629. #if DBG
  630. #define SerialLockPagableSectionByHandle(_secHandle) \
  631. { \
  632. MmLockPagableSectionByHandle((_secHandle)); \
  633. InterlockedIncrement(&SerialGlobals.PAGESER_Count); \
  634. }
  635. #define SerialUnlockPagableImageSection(_secHandle) \
  636. { \
  637. InterlockedDecrement(&SerialGlobals.PAGESER_Count); \
  638. MmUnlockPagableImageSection(_secHandle); \
  639. }
  640. #define SERIAL_LOCKED_PAGED_CODE() \
  641. if ((KeGetCurrentIrql() > APC_LEVEL) \
  642. && (SerialGlobals.PAGESER_Count == 0)) { \
  643. KdPrint(("SERIAL: Pageable code called at IRQL %d without lock \n", \
  644. KeGetCurrentIrql())); \
  645. ASSERT(FALSE); \
  646. }
  647. #else
  648. #define SerialLockPagableSectionByHandle(_secHandle) \
  649. { \
  650. MmLockPagableSectionByHandle((_secHandle)); \
  651. }
  652. #define SerialUnlockPagableImageSection(_secHandle) \
  653. { \
  654. MmUnlockPagableImageSection(_secHandle); \
  655. }
  656. #define SERIAL_LOCKED_PAGED_CODE()
  657. #endif // DBG
  658. #define SerialRemoveQueueDpc(_dpc, _pExt) \
  659. { \
  660. if (KeRemoveQueueDpc((_dpc))) { \
  661. InterlockedDecrement(&(_pExt)->DpcCount); \
  662. } \
  663. }
  664. typedef struct _SERIAL_DEVICE_EXTENSION {
  665. //
  666. // This holds the isr that should be called from our own
  667. // dispatching isr for "cards" that are trying to share the
  668. // same interrupt.
  669. //
  670. PKSERVICE_ROUTINE TopLevelOurIsr;
  671. //
  672. // This holds the context that should be used when we
  673. // call the above service routine.
  674. //
  675. PVOID TopLevelOurIsrContext;
  676. //
  677. // This links together all of the different "cards" that are
  678. // trying to share the same interrupt of a non-mca machine.
  679. //
  680. LIST_ENTRY TopLevelSharers;
  681. //
  682. // This circular doubly linked list links together all
  683. // devices that are using the same interrupt object.
  684. // NOTE: This does not mean that they are using the
  685. // same interrupt "dispatching" routine.
  686. //
  687. LIST_ENTRY CommonInterruptObject;
  688. //
  689. // This is to link together ports on the same multiport card
  690. //
  691. LIST_ENTRY MultiportSiblings;
  692. //
  693. // This links together all devobjs that this driver owns.
  694. // It is needed to search when starting a new device.
  695. //
  696. LIST_ENTRY AllDevObjs;
  697. //
  698. // For reporting resource usage, we keep around the physical
  699. // address we got from the registry.
  700. //
  701. PHYSICAL_ADDRESS OriginalController;
  702. //
  703. // For reporting resource usage, we keep around the physical
  704. // address we got from the registry.
  705. //
  706. PHYSICAL_ADDRESS OriginalInterruptStatus;
  707. //
  708. // This value is set by the read code to hold the time value
  709. // used for read interval timing. We keep it in the extension
  710. // so that the interval timer dpc routine determine if the
  711. // interval time has passed for the IO.
  712. //
  713. LARGE_INTEGER IntervalTime;
  714. //
  715. // These two values hold the "constant" time that we should use
  716. // to delay for the read interval time.
  717. //
  718. LARGE_INTEGER ShortIntervalAmount;
  719. LARGE_INTEGER LongIntervalAmount;
  720. //
  721. // This holds the value that we use to determine if we should use
  722. // the long interval delay or the short interval delay.
  723. //
  724. LARGE_INTEGER CutOverAmount;
  725. //
  726. // This holds the system time when we last time we had
  727. // checked that we had actually read characters. Used
  728. // for interval timing.
  729. //
  730. LARGE_INTEGER LastReadTime;
  731. //
  732. // We keep a pointer around to our device name for dumps
  733. // and for creating "external" symbolic links to this
  734. // device.
  735. //
  736. UNICODE_STRING DeviceName;
  737. //
  738. // This points to the object directory that we will place
  739. // a symbolic link to our device name.
  740. //
  741. UNICODE_STRING ObjectDirectory;
  742. //
  743. // This points to the device name for this device
  744. // sans device prefix.
  745. //
  746. UNICODE_STRING NtNameForPort;
  747. //
  748. // This points to the symbolic link name that will be
  749. // linked to the actual nt device name.
  750. //
  751. UNICODE_STRING SymbolicLinkName;
  752. //
  753. // This points to the pure "COMx" name
  754. //
  755. UNICODE_STRING DosName;
  756. //
  757. // This points the the delta time that we should use to
  758. // delay for interval timing.
  759. //
  760. PLARGE_INTEGER IntervalTimeToUse;
  761. //
  762. // Points to the device object that contains
  763. // this device extension.
  764. //
  765. PDEVICE_OBJECT DeviceObject;
  766. //
  767. // After initialization of the driver is complete, this
  768. // will either be NULL or point to the routine that the
  769. // kernel will call when an interrupt occurs.
  770. //
  771. // If the pointer is null then this is part of a list
  772. // of ports that are sharing an interrupt and this isn't
  773. // the first port that we configured for this interrupt.
  774. //
  775. // If the pointer is non-null then this routine has some
  776. // kind of structure that will "eventually" get us into
  777. // the real serial isr with a pointer to this device extension.
  778. //
  779. // NOTE: On an MCA bus (except for multiport cards) this
  780. // is always a pointer to the "real" serial isr.
  781. PKSERVICE_ROUTINE OurIsr;
  782. //
  783. // This will generally point right to this device extension.
  784. //
  785. // However, when the port that this device extension is
  786. // "managing" was the first port initialized on a chain
  787. // of ports that were trying to share an interrupt, this
  788. // will point to a structure that will enable dispatching
  789. // to any port on the chain of sharers of this interrupt.
  790. //
  791. PVOID OurIsrContext;
  792. //
  793. // The base address for the set of device registers
  794. // of the serial port.
  795. //
  796. PUCHAR Controller;
  797. //
  798. // The base address for interrupt status register.
  799. // This is only defined in the root extension.
  800. //
  801. PUCHAR InterruptStatus;
  802. //
  803. // Points to the interrupt object for used by this device.
  804. //
  805. PKINTERRUPT Interrupt;
  806. //
  807. // This list head is used to contain the time ordered list
  808. // of read requests. Access to this list is protected by
  809. // the global cancel spinlock.
  810. //
  811. LIST_ENTRY ReadQueue;
  812. //
  813. // This list head is used to contain the time ordered list
  814. // of write requests. Access to this list is protected by
  815. // the global cancel spinlock.
  816. //
  817. LIST_ENTRY WriteQueue;
  818. //
  819. // This list head is used to contain the time ordered list
  820. // of set and wait mask requests. Access to this list is protected by
  821. // the global cancel spinlock.
  822. //
  823. LIST_ENTRY MaskQueue;
  824. //
  825. // Holds the serialized list of purge requests.
  826. //
  827. LIST_ENTRY PurgeQueue;
  828. //
  829. // This points to the irp that is currently being processed
  830. // for the read queue. This field is initialized by the open to
  831. // NULL.
  832. //
  833. // This value is only set at dispatch level. It may be
  834. // read at interrupt level.
  835. //
  836. PIRP CurrentReadIrp;
  837. //
  838. // This points to the irp that is currently being processed
  839. // for the write queue.
  840. //
  841. // This value is only set at dispatch level. It may be
  842. // read at interrupt level.
  843. //
  844. PIRP CurrentWriteIrp;
  845. //
  846. // Points to the irp that is currently being processed to
  847. // affect the wait mask operations.
  848. //
  849. PIRP CurrentMaskIrp;
  850. //
  851. // Points to the irp that is currently being processed to
  852. // purge the read/write queues and buffers.
  853. //
  854. PIRP CurrentPurgeIrp;
  855. //
  856. // Points to the current irp that is waiting on a comm event.
  857. //
  858. PIRP CurrentWaitIrp;
  859. //
  860. // Points to the irp that is being used to send an immediate
  861. // character.
  862. //
  863. PIRP CurrentImmediateIrp;
  864. //
  865. // Points to the irp that is being used to count the number
  866. // of characters received after an xoff (as currently defined
  867. // by the IOCTL_SERIAL_XOFF_COUNTER ioctl) is sent.
  868. //
  869. PIRP CurrentXoffIrp;
  870. //
  871. // Holds the number of bytes remaining in the current write
  872. // irp.
  873. //
  874. // This location is only accessed while at interrupt level.
  875. //
  876. ULONG WriteLength;
  877. //
  878. // Holds a pointer to the current character to be sent in
  879. // the current write.
  880. //
  881. // This location is only accessed while at interrupt level.
  882. //
  883. PUCHAR WriteCurrentChar;
  884. //
  885. // This is a buffer for the read processing.
  886. //
  887. // The buffer works as a ring. When the character is read from
  888. // the device it will be place at the end of the ring.
  889. //
  890. // Characters are only placed in this buffer at interrupt level
  891. // although character may be read at any level. The pointers
  892. // that manage this buffer may not be updated except at interrupt
  893. // level.
  894. //
  895. PUCHAR InterruptReadBuffer;
  896. //
  897. // This is a pointer to the first character of the buffer into
  898. // which the interrupt service routine is copying characters.
  899. //
  900. PUCHAR ReadBufferBase;
  901. //
  902. // This is a count of the number of characters in the interrupt
  903. // buffer. This value is set and read at interrupt level. Note
  904. // that this value is only *incremented* at interrupt level so
  905. // it is safe to read it at any level. When characters are
  906. // copied out of the read buffer, this count is decremented by
  907. // a routine that synchronizes with the ISR.
  908. //
  909. ULONG CharsInInterruptBuffer;
  910. //
  911. // Points to the first available position for a newly received
  912. // character. This variable is only accessed at interrupt level and
  913. // buffer initialization code.
  914. //
  915. PUCHAR CurrentCharSlot;
  916. //
  917. // This variable is used to contain the last available position
  918. // in the read buffer. It is updated at open and at interrupt
  919. // level when switching between the users buffer and the interrupt
  920. // buffer.
  921. //
  922. PUCHAR LastCharSlot;
  923. //
  924. // This marks the first character that is available to satisfy
  925. // a read request. Note that while this always points to valid
  926. // memory, it may not point to a character that can be sent to
  927. // the user. This can occur when the buffer is empty.
  928. //
  929. PUCHAR FirstReadableChar;
  930. //
  931. // Pointer to the lock variable returned for this extension when
  932. // locking down the driver
  933. //
  934. PVOID LockPtr;
  935. //
  936. // This variable holds the size of whatever buffer we are currently
  937. // using.
  938. //
  939. ULONG BufferSize;
  940. //
  941. // This variable holds .8 of BufferSize. We don't want to recalculate
  942. // this real often - It's needed when so that an application can be
  943. // "notified" that the buffer is getting full.
  944. //
  945. ULONG BufferSizePt8;
  946. //
  947. // This value holds the number of characters desired for a
  948. // particular read. It is initially set by read length in the
  949. // IRP. It is decremented each time more characters are placed
  950. // into the "users" buffer buy the code that reads characters
  951. // out of the typeahead buffer into the users buffer. If the
  952. // typeahead buffer is exhausted by the read, and the reads buffer
  953. // is given to the isr to fill, this value is becomes meaningless.
  954. //
  955. ULONG NumberNeededForRead;
  956. //
  957. // This mask will hold the bitmask sent down via the set mask
  958. // ioctl. It is used by the interrupt service routine to determine
  959. // if the occurence of "events" (in the serial drivers understanding
  960. // of the concept of an event) should be noted.
  961. //
  962. ULONG IsrWaitMask;
  963. //
  964. // This mask will always be a subset of the IsrWaitMask. While
  965. // at device level, if an event occurs that is "marked" as interesting
  966. // in the IsrWaitMask, the driver will turn on that bit in this
  967. // history mask. The driver will then look to see if there is a
  968. // request waiting for an event to occur. If there is one, it
  969. // will copy the value of the history mask into the wait irp, zero
  970. // the history mask, and complete the wait irp. If there is no
  971. // waiting request, the driver will be satisfied with just recording
  972. // that the event occured. If a wait request should be queued,
  973. // the driver will look to see if the history mask is non-zero. If
  974. // it is non-zero, the driver will copy the history mask into the
  975. // irp, zero the history mask, and then complete the irp.
  976. //
  977. ULONG HistoryMask;
  978. //
  979. // This is a pointer to the where the history mask should be
  980. // placed when completing a wait. It is only accessed at
  981. // device level.
  982. //
  983. // We have a pointer here to assist us to synchronize completing a wait.
  984. // If this is non-zero, then we have wait outstanding, and the isr still
  985. // knows about it. We make this pointer null so that the isr won't
  986. // attempt to complete the wait.
  987. //
  988. // We still keep a pointer around to the wait irp, since the actual
  989. // pointer to the wait irp will be used for the "common" irp completion
  990. // path.
  991. //
  992. ULONG *IrpMaskLocation;
  993. //
  994. // This mask holds all of the reason that transmission
  995. // is not proceeding. Normal transmission can not occur
  996. // if this is non-zero.
  997. //
  998. // This is only written from interrupt level.
  999. // This could be (but is not) read at any level.
  1000. //
  1001. ULONG TXHolding;
  1002. //
  1003. // This mask holds all of the reason that reception
  1004. // is not proceeding. Normal reception can not occur
  1005. // if this is non-zero.
  1006. //
  1007. // This is only written from interrupt level.
  1008. // This could be (but is not) read at any level.
  1009. //
  1010. ULONG RXHolding;
  1011. //
  1012. // This holds the reasons that the driver thinks it is in
  1013. // an error state.
  1014. //
  1015. // This is only written from interrupt level.
  1016. // This could be (but is not) read at any level.
  1017. //
  1018. ULONG ErrorWord;
  1019. //
  1020. // This keeps a total of the number of characters that
  1021. // are in all of the "write" irps that the driver knows
  1022. // about. It is only accessed with the cancel spinlock
  1023. // held.
  1024. //
  1025. ULONG TotalCharsQueued;
  1026. //
  1027. // This holds a count of the number of characters read
  1028. // the last time the interval timer dpc fired. It
  1029. // is a long (rather than a ulong) since the other read
  1030. // completion routines use negative values to indicate
  1031. // to the interval timer that it should complete the read
  1032. // if the interval timer DPC was lurking in some DPC queue when
  1033. // some other way to complete occurs.
  1034. //
  1035. LONG CountOnLastRead;
  1036. //
  1037. // This is a count of the number of characters read by the
  1038. // isr routine. It is *ONLY* written at isr level. We can
  1039. // read it at dispatch level.
  1040. //
  1041. ULONG ReadByIsr;
  1042. //
  1043. // This holds the current baud rate for the device.
  1044. //
  1045. ULONG CurrentBaud;
  1046. //
  1047. // This is the number of characters read since the XoffCounter
  1048. // was started. This variable is only accessed at device level.
  1049. // If it is greater than zero, it implies that there is an
  1050. // XoffCounter ioctl in the queue.
  1051. //
  1052. LONG CountSinceXoff;
  1053. //
  1054. // This ulong is incremented each time something trys to start
  1055. // the execution path that tries to lower the RTS line when
  1056. // doing transmit toggling. If it "bumps" into another path
  1057. // (indicated by a false return value from queueing a dpc
  1058. // and a TRUE return value tring to start a timer) it will
  1059. // decrement the count. These increments and decrements
  1060. // are all done at device level. Note that in the case
  1061. // of a bump while trying to start the timer, we have to
  1062. // go up to device level to do the decrement.
  1063. //
  1064. ULONG CountOfTryingToLowerRTS;
  1065. //
  1066. // This ULONG is used to keep track of the "named" (in ntddser.h)
  1067. // baud rates that this particular device supports.
  1068. //
  1069. ULONG SupportedBauds;
  1070. //
  1071. // This value holds the span (in units of bytes) of the register
  1072. // set controlling this port. This is constant over the life
  1073. // of the port.
  1074. //
  1075. ULONG SpanOfController;
  1076. //
  1077. // This value holds the span (in units of bytes) of the interrupt
  1078. // status register associated with this port. This is constant
  1079. // over the life of the port.
  1080. //
  1081. ULONG SpanOfInterruptStatus;
  1082. //
  1083. // Hold the clock rate input to the serial part.
  1084. //
  1085. ULONG ClockRate;
  1086. //
  1087. // The number of characters to push out if a fifo is present.
  1088. //
  1089. ULONG TxFifoAmount;
  1090. //
  1091. // Set to indicate that it is ok to share interrupts within the device.
  1092. //
  1093. ULONG PermitShare;
  1094. //
  1095. // Holds the timeout controls for the device. This value
  1096. // is set by the Ioctl processing.
  1097. //
  1098. // It should only be accessed under protection of the control
  1099. // lock since more than one request can be in the control dispatch
  1100. // routine at one time.
  1101. //
  1102. SERIAL_TIMEOUTS Timeouts;
  1103. //
  1104. // This holds the various characters that are used
  1105. // for replacement on errors and also for flow control.
  1106. //
  1107. // They are only set at interrupt level.
  1108. //
  1109. SERIAL_CHARS SpecialChars;
  1110. //
  1111. // This structure holds the handshake and control flow
  1112. // settings for the serial driver.
  1113. //
  1114. // It is only set at interrupt level. It can be
  1115. // be read at any level with the control lock held.
  1116. //
  1117. SERIAL_HANDFLOW HandFlow;
  1118. //
  1119. // Holds performance statistics that applications can query.
  1120. // Reset on each open. Only set at device level.
  1121. //
  1122. SERIALPERF_STATS PerfStats;
  1123. //
  1124. // This holds what we beleive to be the current value of
  1125. // the line control register.
  1126. //
  1127. // It should only be accessed under protection of the control
  1128. // lock since more than one request can be in the control dispatch
  1129. // routine at one time.
  1130. //
  1131. UCHAR LineControl;
  1132. //
  1133. // We keep track of whether the somebody has the device currently
  1134. // opened with a simple boolean. We need to know this so that
  1135. // spurious interrupts from the device (especially during initialization)
  1136. // will be ignored. This value is only accessed in the ISR and
  1137. // is only set via synchronization routines. We may be able
  1138. // to get rid of this boolean when the code is more fleshed out.
  1139. //
  1140. BOOLEAN DeviceIsOpened;
  1141. //
  1142. // Set at intialization to indicate that on the current
  1143. // architecture we need to unmap the base register address
  1144. // when we unload the driver.
  1145. //
  1146. BOOLEAN UnMapRegisters;
  1147. //
  1148. // Set at intialization to indicate that on the current
  1149. // architecture we need to unmap the interrupt status address
  1150. // when we unload the driver.
  1151. //
  1152. BOOLEAN UnMapStatus;
  1153. //
  1154. // This is only accessed at interrupt level. It keeps track
  1155. // of whether the holding register is empty.
  1156. //
  1157. BOOLEAN HoldingEmpty;
  1158. //
  1159. // This variable is only accessed at interrupt level. It
  1160. // indicates that we want to transmit a character immediately.
  1161. // That is - in front of any characters that could be transmitting
  1162. // from a normal write.
  1163. //
  1164. BOOLEAN TransmitImmediate;
  1165. //
  1166. // This variable is only accessed at interrupt level. Whenever
  1167. // a wait is initiated this variable is set to false.
  1168. // Whenever any kind of character is written it is set to true.
  1169. // Whenever the write queue is found to be empty the code that
  1170. // is processing that completing irp will synchonize with the interrupt.
  1171. // If this synchronization code finds that the variable is true and that
  1172. // there is a wait on the transmit queue being empty then it is
  1173. // certain that the queue was emptied and that it has happened since
  1174. // the wait was initiated.
  1175. //
  1176. BOOLEAN EmptiedTransmit;
  1177. //
  1178. // This simply indicates that the port associated with this
  1179. // extension is part of a multiport card.
  1180. //
  1181. BOOLEAN PortOnAMultiportCard;
  1182. //
  1183. // We keep the following values around so that we can connect
  1184. // to the interrupt and report resources after the configuration
  1185. // record is gone.
  1186. //
  1187. //
  1188. // Translated vector
  1189. //
  1190. ULONG Vector;
  1191. //
  1192. // Translated Irql
  1193. //
  1194. KIRQL Irql;
  1195. //
  1196. // Untranslated vector
  1197. //
  1198. ULONG OriginalVector;
  1199. //
  1200. // Untranslated irql
  1201. //
  1202. ULONG OriginalIrql;
  1203. //
  1204. // Address space
  1205. //
  1206. ULONG AddressSpace;
  1207. //
  1208. // Bus number
  1209. //
  1210. ULONG BusNumber;
  1211. //
  1212. // Interface type
  1213. //
  1214. INTERFACE_TYPE InterfaceType;
  1215. //
  1216. // Port index no for multiport devices
  1217. //
  1218. ULONG PortIndex;
  1219. //
  1220. // Indexed flag for multiport devices
  1221. //
  1222. BOOLEAN Indexed;
  1223. //
  1224. // Mask inverted mask for multiport devices
  1225. //
  1226. ULONG MaskInverted;
  1227. //
  1228. // Needed to add new devices to multiport boards
  1229. //
  1230. ULONG NewPortIndex;
  1231. ULONG NewMaskInverted;
  1232. PVOID NewExtension;
  1233. //
  1234. // We hold the character that should be transmitted immediately.
  1235. //
  1236. // Note that we can't use this to determine whether there is
  1237. // a character to send because the character to send could be
  1238. // zero.
  1239. //
  1240. UCHAR ImmediateChar;
  1241. //
  1242. // This holds the mask that will be used to mask off unwanted
  1243. // data bits of the received data (valid data bits can be 5,6,7,8)
  1244. // The mask will normally be 0xff. This is set while the control
  1245. // lock is held since it wouldn't have adverse effects on the
  1246. // isr if it is changed in the middle of reading characters.
  1247. // (What it would do to the app is another question - but then
  1248. // the app asked the driver to do it.)
  1249. //
  1250. UCHAR ValidDataMask;
  1251. //
  1252. // The application can turn on a mode,via the
  1253. // IOCTL_SERIAL_LSRMST_INSERT ioctl, that will cause the
  1254. // serial driver to insert the line status or the modem
  1255. // status into the RX stream. The parameter with the ioctl
  1256. // is a pointer to a UCHAR. If the value of the UCHAR is
  1257. // zero, then no insertion will ever take place. If the
  1258. // value of the UCHAR is non-zero (and not equal to the
  1259. // xon/xoff characters), then the serial driver will insert.
  1260. //
  1261. UCHAR EscapeChar;
  1262. //
  1263. // These two booleans are used to indicate to the isr transmit
  1264. // code that it should send the xon or xoff character. They are
  1265. // only accessed at open and at interrupt level.
  1266. //
  1267. BOOLEAN SendXonChar;
  1268. BOOLEAN SendXoffChar;
  1269. //
  1270. // This boolean will be true if a 16550 is present *and* enabled.
  1271. //
  1272. BOOLEAN FifoPresent;
  1273. //
  1274. // This denotes that this particular port is an on the motherboard
  1275. // port for the Jensen hardware. On these ports the OUT2 bit
  1276. // which is used to enable/disable interrupts is always hight.
  1277. //
  1278. BOOLEAN Jensen;
  1279. //
  1280. // This is the water mark that the rxfifo should be
  1281. // set to when the fifo is turned on. This is not the actual
  1282. // value, but the encoded value that goes into the register.
  1283. //
  1284. UCHAR RxFifoTrigger;
  1285. //
  1286. // Says whether this device can share interrupts with devices
  1287. // other than serial devices.
  1288. //
  1289. BOOLEAN InterruptShareable;
  1290. //
  1291. // Records whether we actually created the symbolic link name
  1292. // at driver load time. If we didn't create it, we won't try
  1293. // to destroy it when we unload.
  1294. //
  1295. BOOLEAN CreatedSymbolicLink;
  1296. //
  1297. // Records whether we actually created an entry in SERIALCOMM
  1298. // at driver load time. If we didn't create it, we won't try
  1299. // to destroy it when the device is removed.
  1300. //
  1301. BOOLEAN CreatedSerialCommEntry;
  1302. //
  1303. // We place all of the kernel and Io subsystem "opaque" structures
  1304. // at the end of the extension. We don't care about their contents.
  1305. //
  1306. //
  1307. // This lock will be used to protect various fields in
  1308. // the extension that are set (& read) in the extension
  1309. // by the io controls.
  1310. //
  1311. KSPIN_LOCK ControlLock;
  1312. //
  1313. // This lock will be used to protect the accept / reject state
  1314. // transitions and flags of the driver It must be acquired
  1315. // before a cancel lock
  1316. //
  1317. KSPIN_LOCK FlagsLock;
  1318. //
  1319. // This points to a DPC used to complete read requests.
  1320. //
  1321. KDPC CompleteWriteDpc;
  1322. //
  1323. // This points to a DPC used to complete read requests.
  1324. //
  1325. KDPC CompleteReadDpc;
  1326. //
  1327. // This dpc is fired off if the timer for the total timeout
  1328. // for the read expires. It will execute a dpc routine that
  1329. // will cause the current read to complete.
  1330. //
  1331. //
  1332. KDPC TotalReadTimeoutDpc;
  1333. //
  1334. // This dpc is fired off if the timer for the interval timeout
  1335. // expires. If no more characters have been read then the
  1336. // dpc routine will cause the read to complete. However, if
  1337. // more characters have been read then the dpc routine will
  1338. // resubmit the timer.
  1339. //
  1340. KDPC IntervalReadTimeoutDpc;
  1341. //
  1342. // This dpc is fired off if the timer for the total timeout
  1343. // for the write expires. It will execute a dpc routine that
  1344. // will cause the current write to complete.
  1345. //
  1346. //
  1347. KDPC TotalWriteTimeoutDpc;
  1348. //
  1349. // This dpc is fired off if a comm error occurs. It will
  1350. // execute a dpc routine that will cancel all pending reads
  1351. // and writes.
  1352. //
  1353. KDPC CommErrorDpc;
  1354. //
  1355. // This dpc is fired off if an event occurs and there was
  1356. // a irp waiting on that event. A dpc routine will execute
  1357. // that completes the irp.
  1358. //
  1359. KDPC CommWaitDpc;
  1360. //
  1361. // This dpc is fired off when the transmit immediate char
  1362. // character is given to the hardware. It will simply complete
  1363. // the irp.
  1364. //
  1365. KDPC CompleteImmediateDpc;
  1366. //
  1367. // This dpc is fired off if the transmit immediate char
  1368. // character times out. The dpc routine will "grab" the
  1369. // irp from the isr and time it out.
  1370. //
  1371. KDPC TotalImmediateTimeoutDpc;
  1372. //
  1373. // This dpc is fired off if the timer used to "timeout" counting
  1374. // the number of characters received after the Xoff ioctl is started
  1375. // expired.
  1376. //
  1377. KDPC XoffCountTimeoutDpc;
  1378. //
  1379. // This dpc is fired off if the xoff counter actually runs down
  1380. // to zero.
  1381. //
  1382. KDPC XoffCountCompleteDpc;
  1383. //
  1384. // This dpc is fired off only from device level to start off
  1385. // a timer that will queue a dpc to check if the RTS line
  1386. // should be lowered when we are doing transmit toggling.
  1387. //
  1388. KDPC StartTimerLowerRTSDpc;
  1389. //
  1390. // This dpc is fired off when a timer expires (after one
  1391. // character time), so that code can be invoked that will
  1392. // check to see if we should lower the RTS line when
  1393. // doing transmit toggling.
  1394. //
  1395. KDPC PerhapsLowerRTSDpc;
  1396. //
  1397. // This DPC is fired to set an event stating that all other
  1398. // DPC's have been finish for this device extension so that
  1399. // paged code may be unlocked.
  1400. //
  1401. KDPC IsrUnlockPagesDpc;
  1402. //
  1403. // This is the kernal timer structure used to handle
  1404. // total read request timing.
  1405. //
  1406. KTIMER ReadRequestTotalTimer;
  1407. //
  1408. // This is the kernal timer structure used to handle
  1409. // interval read request timing.
  1410. //
  1411. KTIMER ReadRequestIntervalTimer;
  1412. //
  1413. // This is the kernal timer structure used to handle
  1414. // total time request timing.
  1415. //
  1416. KTIMER WriteRequestTotalTimer;
  1417. //
  1418. // This is the kernal timer structure used to handle
  1419. // total time request timing.
  1420. //
  1421. KTIMER ImmediateTotalTimer;
  1422. //
  1423. // This timer is used to timeout the xoff counter
  1424. // io.
  1425. //
  1426. KTIMER XoffCountTimer;
  1427. //
  1428. // This timer is used to invoke a dpc one character time
  1429. // after the timer is set. That dpc will be used to check
  1430. // whether we should lower the RTS line if we are doing
  1431. // transmit toggling.
  1432. //
  1433. KTIMER LowerRTSTimer;
  1434. //
  1435. // This is a pointer to the next lower device in the IRP stack.
  1436. //
  1437. PDEVICE_OBJECT LowerDeviceObject;
  1438. //
  1439. // This is where keep track of the power state the device is in.
  1440. //
  1441. DEVICE_POWER_STATE PowerState;
  1442. //
  1443. // Pointer to the driver object
  1444. //
  1445. PDRIVER_OBJECT DriverObject;
  1446. //
  1447. // Event used to do some synchronization with the devices underneath me
  1448. // (namely ACPI)
  1449. //
  1450. KEVENT SerialSyncEvent;
  1451. //
  1452. // String where we keep the symbolic link that is returned to us when we
  1453. // register our device under the COMM class with the Plug and Play manager.
  1454. //
  1455. UNICODE_STRING DeviceClassSymbolicName;
  1456. //
  1457. // Serial ISR switch structure
  1458. //
  1459. PSERIAL_CISR_SW CIsrSw;
  1460. //
  1461. // Count of pending IRP's
  1462. //
  1463. ULONG PendingIRPCnt;
  1464. //
  1465. // Accepting requests?
  1466. //
  1467. ULONG DevicePNPAccept;
  1468. //
  1469. // No IRP's pending event
  1470. //
  1471. KEVENT PendingIRPEvent;
  1472. //
  1473. // PNP State
  1474. //
  1475. ULONG PNPState;
  1476. //
  1477. // Misc Flags
  1478. //
  1479. ULONG Flags;
  1480. //
  1481. // Open count
  1482. //
  1483. LONG OpenCount;
  1484. //
  1485. // Start sync event
  1486. //
  1487. KEVENT SerialStartEvent;
  1488. //
  1489. // Current state during powerdown
  1490. //
  1491. SERIAL_DEVICE_STATE DeviceState;
  1492. //
  1493. // Device stack capabilites
  1494. //
  1495. DEVICE_POWER_STATE DeviceStateMap[PowerSystemMaximum];
  1496. //
  1497. // Event to signal transition to D0 completion
  1498. //
  1499. KEVENT PowerD0Event;
  1500. //
  1501. // List of stalled IRP's
  1502. //
  1503. LIST_ENTRY StalledIrpQueue;
  1504. //
  1505. // Mutex on open status
  1506. //
  1507. FAST_MUTEX OpenMutex;
  1508. //
  1509. // Mutex on close
  1510. //
  1511. FAST_MUTEX CloseMutex;
  1512. //
  1513. // TRUE if we own power policy
  1514. //
  1515. BOOLEAN OwnsPowerPolicy;
  1516. //
  1517. // SystemWake from devcaps
  1518. //
  1519. SYSTEM_POWER_STATE SystemWake;
  1520. //
  1521. // DeviceWake from devcaps
  1522. //
  1523. DEVICE_POWER_STATE DeviceWake;
  1524. //
  1525. // Our PDO
  1526. //
  1527. PDEVICE_OBJECT Pdo;
  1528. //
  1529. // Should we enable wakeup
  1530. //
  1531. BOOLEAN SendWaitWake;
  1532. //
  1533. // Pending wait wake IRP
  1534. //
  1535. PIRP PendingWakeIrp;
  1536. //
  1537. // WMI Information
  1538. //
  1539. WMILIB_CONTEXT WmiLibInfo;
  1540. //
  1541. // Name to use as WMI identifier
  1542. //
  1543. UNICODE_STRING WmiIdentifier;
  1544. //
  1545. // WMI Comm Data
  1546. //
  1547. SERIAL_WMI_COMM_DATA WmiCommData;
  1548. //
  1549. // WMI HW Data
  1550. //
  1551. SERIAL_WMI_HW_DATA WmiHwData;
  1552. //
  1553. // WMI Performance Data
  1554. //
  1555. SERIAL_WMI_PERF_DATA WmiPerfData;
  1556. //
  1557. // Pending DPC count
  1558. //
  1559. ULONG DpcCount;
  1560. //
  1561. // Pending DPC event
  1562. //
  1563. KEVENT PendingDpcEvent;
  1564. //
  1565. // Should we expose external interfaces?
  1566. //
  1567. ULONG SkipNaming;
  1568. #if defined(NEC_98)
  1569. //
  1570. // write data to divisor latch register (for 16550)
  1571. //
  1572. SHORT DivisorLatch16550;
  1573. //
  1574. // write data to modem control register (for 16550)
  1575. //
  1576. UCHAR ModemControl16550;
  1577. //
  1578. // write data to line control register (for 16550)
  1579. //
  1580. UCHAR LineControl16550;
  1581. //
  1582. // out data to mode set register (for 71051)
  1583. //
  1584. UCHAR ModeSet71051;
  1585. //
  1586. // out data to command set register (for 71051)
  1587. //
  1588. UCHAR CommandSet71051;
  1589. //
  1590. // out data to Interrupt enable register for 101
  1591. // bit0 = Recive Data Available
  1592. // bit1 = Transmit Holding Register Empty
  1593. //
  1594. UCHAR InterruptEnable16550;
  1595. //
  1596. // Common base address for 101
  1597. // CH2 = 0x0yB0
  1598. // CH3 = 0x0yB2
  1599. //
  1600. PUCHAR CommonBaseAddress;
  1601. //
  1602. // CCU Mode set register address for 101
  1603. // CH2 = 0x0yB3
  1604. // CH3 = 0x0yBB
  1605. PUCHAR ModeSetRegisterAddress;
  1606. //
  1607. // CCU Command set register address for 101
  1608. // CH2 = 0x0yB3
  1609. // CH3 = 0x0yBB
  1610. PUCHAR CommandSetRegisterAddress;
  1611. #else
  1612. #endif //defined(NEC_98)
  1613. } SERIAL_DEVICE_EXTENSION,*PSERIAL_DEVICE_EXTENSION;
  1614. #define SERIAL_PNPACCEPT_OK 0x0L
  1615. #define SERIAL_PNPACCEPT_REMOVING 0x1L
  1616. #define SERIAL_PNPACCEPT_STOPPING 0x2L
  1617. #define SERIAL_PNPACCEPT_STOPPED 0x4L
  1618. #define SERIAL_PNPACCEPT_SURPRISE_REMOVING 0x8L
  1619. #define SERIAL_PNP_ADDED 0x0L
  1620. #define SERIAL_PNP_STARTED 0x1L
  1621. #define SERIAL_PNP_QSTOP 0x2L
  1622. #define SERIAL_PNP_STOPPING 0x3L
  1623. #define SERIAL_PNP_QREMOVE 0x4L
  1624. #define SERIAL_PNP_REMOVING 0x5L
  1625. #define SERIAL_PNP_RESTARTING 0x6L
  1626. #define SERIAL_FLAGS_CLEAR 0x0L
  1627. #define SERIAL_FLAGS_STARTED 0x1L
  1628. #define SERIAL_FLAGS_STOPPED 0x2L
  1629. #define SERIAL_FLAGS_BROKENHW 0x4L
  1630. //
  1631. // When dealing with a multi-port device (that is possibly
  1632. // daisy chained with other multi-port device), the interrupt
  1633. // service routine will actually be a routine that determines
  1634. // which port on which board is actually causing the interrupt.
  1635. //
  1636. // The following structure is used so that only one device
  1637. // extension will actually need to connect to the interrupt.
  1638. // The following structure which is passed to the interrupt
  1639. // service routine contains the addresses of all of the
  1640. // interrupt status registers (there will be multiple
  1641. // status registers when multi-port cards are chained). It
  1642. // will contain the addresses of all the extensions whose
  1643. // devices are being serviced by this interrupt.
  1644. //
  1645. typedef struct _SERIAL_MULTIPORT_DISPATCH {
  1646. PUCHAR InterruptStatus;
  1647. PSERIAL_DEVICE_EXTENSION Extensions[SERIAL_MAX_PORTS_INDEXED];
  1648. ULONG MaskInverted;
  1649. UCHAR UsablePortMask;
  1650. } SERIAL_MULTIPORT_DISPATCH,*PSERIAL_MULTIPORT_DISPATCH;
  1651. #if defined(NEC_98)
  1652. //
  1653. // The value of INDEX for the access of various registers.
  1654. // For the PC-9801-101
  1655. //
  1656. #define INDEX_FOR_DATA_REGISTER ((ULONG)((0x00)*SERIAL_REGISTER_STRIDE))
  1657. #define INDEX_FOR_INTERRUPT_ENABLE_REGISTER ((ULONG)((0x04)*SERIAL_REGISTER_STRIDE))
  1658. #define INDEX_FOR_INTERRUPT_IDENT_REGISTER ((ULONG)((0x03)*SERIAL_REGISTER_STRIDE))
  1659. #define INDEX_FOR_FIFO_CONTROL_REGISTER ((ULONG)((0x04)*SERIAL_REGISTER_STRIDE))
  1660. #define INDEX_FOR_LINE_CONTROL_REGISTER ((ULONG)((0x06)*SERIAL_REGISTER_STRIDE))
  1661. #define INDEX_FOR_LINE_STATUS_REGISTER ((ULONG)((0x01)*SERIAL_REGISTER_STRIDE))
  1662. #define INDEX_FOR_MODEM_STATUS_REGISTER ((ULONG)((0x02)*SERIAL_REGISTER_STRIDE))
  1663. #define INDEX_FOR_VFAST_BAUDCLK_REGISTER ((ULONG)((0x05)*SERIAL_REGISTER_STRIDE))
  1664. //
  1665. // The inline process is access for the various registers on the PC-9801-101
  1666. //
  1667. #define WRITE_IO_DELAY(Counter) \
  1668. do \
  1669. { \
  1670. ULONG i; \
  1671. \
  1672. for (i = 0; (i <= Counter) && (Counter >= 1); i++) { \
  1673. WRITE_PORT_UCHAR((PUCHAR)IO_DELAY_REGISTER, IO_DELAY_DATA); \
  1674. } \
  1675. } while (0)
  1676. _inline
  1677. UCHAR
  1678. ReadDataRegister(
  1679. IN PUCHAR BaseAddress
  1680. )
  1681. {
  1682. WRITE_PORT_UCHAR((BaseAddress)+INDEX_REGISTER_OFFSET,INDEX_FOR_DATA_REGISTER);
  1683. WRITE_IO_DELAY(1);
  1684. return (READ_PORT_UCHAR((BaseAddress)+INDEX_DATA_REGISTER_OFFSET));
  1685. }
  1686. _inline
  1687. VOID
  1688. WriteDataRegister(
  1689. IN PUCHAR BaseAddress,
  1690. IN UCHAR Value
  1691. )
  1692. {
  1693. WRITE_PORT_UCHAR((BaseAddress)+INDEX_REGISTER_OFFSET,INDEX_FOR_DATA_REGISTER);
  1694. WRITE_PORT_UCHAR((BaseAddress)+INDEX_DATA_REGISTER_OFFSET, Value);
  1695. }
  1696. _inline
  1697. UCHAR
  1698. ReadInterruptEnableRegister(
  1699. IN PUCHAR BaseAddress
  1700. )
  1701. {
  1702. WRITE_PORT_UCHAR((BaseAddress)+INDEX_REGISTER_OFFSET,INDEX_FOR_INTERRUPT_ENABLE_REGISTER);
  1703. WRITE_IO_DELAY(1);
  1704. return (READ_PORT_UCHAR((BaseAddress)+INDEX_DATA_REGISTER_OFFSET));
  1705. }
  1706. _inline
  1707. VOID
  1708. WriteInterruptEnableRegister(
  1709. IN PUCHAR BaseAddress,
  1710. IN UCHAR Value
  1711. )
  1712. {
  1713. WRITE_PORT_UCHAR((BaseAddress)+INDEX_REGISTER_OFFSET,INDEX_FOR_INTERRUPT_ENABLE_REGISTER);
  1714. WRITE_PORT_UCHAR((BaseAddress)+INDEX_DATA_REGISTER_OFFSET, Value);
  1715. }
  1716. _inline
  1717. UCHAR
  1718. ReadInterruptIdentRegister(
  1719. IN PUCHAR BaseAddress
  1720. )
  1721. {
  1722. WRITE_PORT_UCHAR((BaseAddress)+INDEX_REGISTER_OFFSET,INDEX_FOR_INTERRUPT_IDENT_REGISTER);
  1723. WRITE_IO_DELAY(1);
  1724. return (READ_PORT_UCHAR((BaseAddress)+INDEX_DATA_REGISTER_OFFSET));
  1725. }
  1726. _inline
  1727. VOID
  1728. WriteInterruptIdentRegister(
  1729. IN PUCHAR BaseAddress,
  1730. IN UCHAR Value
  1731. )
  1732. {
  1733. WRITE_PORT_UCHAR((BaseAddress)+INDEX_REGISTER_OFFSET,INDEX_FOR_INTERRUPT_IDENT_REGISTER);
  1734. WRITE_PORT_UCHAR((BaseAddress)+INDEX_DATA_REGISTER_OFFSET, Value);
  1735. }
  1736. _inline
  1737. UCHAR
  1738. ReadFifoControlRegister(
  1739. IN PUCHAR BaseAddress
  1740. )
  1741. {
  1742. WRITE_PORT_UCHAR((BaseAddress)+INDEX_REGISTER_OFFSET,INDEX_FOR_FIFO_CONTROL_REGISTER);
  1743. WRITE_IO_DELAY(1);
  1744. return (READ_PORT_UCHAR((BaseAddress)+INDEX_DATA_REGISTER_OFFSET));
  1745. }
  1746. _inline
  1747. VOID
  1748. WriteFifoControlRegister(
  1749. IN PUCHAR BaseAddress,
  1750. IN UCHAR Value
  1751. )
  1752. {
  1753. WRITE_PORT_UCHAR((BaseAddress)+INDEX_REGISTER_OFFSET,INDEX_FOR_FIFO_CONTROL_REGISTER);
  1754. WRITE_PORT_UCHAR((BaseAddress)+INDEX_DATA_REGISTER_OFFSET, Value);
  1755. }
  1756. _inline
  1757. UCHAR
  1758. ReadLineControlRegister(
  1759. IN PUCHAR BaseAddress
  1760. )
  1761. {
  1762. WRITE_PORT_UCHAR((BaseAddress)+INDEX_REGISTER_OFFSET,INDEX_FOR_LINE_CONTROL_REGISTER);
  1763. WRITE_IO_DELAY(1);
  1764. return (READ_PORT_UCHAR((BaseAddress)+INDEX_DATA_REGISTER_OFFSET));
  1765. }
  1766. _inline
  1767. VOID
  1768. WriteLineControlRegister(
  1769. IN PUCHAR BaseAddress,
  1770. IN UCHAR Value
  1771. )
  1772. {
  1773. WRITE_PORT_UCHAR((BaseAddress)+INDEX_REGISTER_OFFSET,INDEX_FOR_LINE_CONTROL_REGISTER);
  1774. WRITE_PORT_UCHAR((BaseAddress)+INDEX_DATA_REGISTER_OFFSET, Value);
  1775. }
  1776. _inline
  1777. UCHAR
  1778. ReadLineStatusRegister(
  1779. IN PUCHAR BaseAddress
  1780. )
  1781. {
  1782. WRITE_PORT_UCHAR((BaseAddress)+INDEX_REGISTER_OFFSET,INDEX_FOR_LINE_STATUS_REGISTER);
  1783. WRITE_IO_DELAY(1);
  1784. return (READ_PORT_UCHAR((BaseAddress)+INDEX_DATA_REGISTER_OFFSET));
  1785. }
  1786. _inline
  1787. UCHAR
  1788. ReadModemStatusRegister(
  1789. IN PUCHAR BaseAddress
  1790. )
  1791. {
  1792. WRITE_PORT_UCHAR((BaseAddress)+INDEX_REGISTER_OFFSET,INDEX_FOR_MODEM_STATUS_REGISTER);
  1793. WRITE_IO_DELAY(1);
  1794. return (READ_PORT_UCHAR((BaseAddress)+INDEX_DATA_REGISTER_OFFSET));
  1795. }
  1796. _inline
  1797. UCHAR
  1798. ReadVFASTBaudclkRegister(
  1799. IN PUCHAR BaseAddress
  1800. )
  1801. {
  1802. WRITE_PORT_UCHAR((BaseAddress)+INDEX_REGISTER_OFFSET,INDEX_FOR_VFAST_BAUDCLK_REGISTER);
  1803. WRITE_IO_DELAY(1);
  1804. return (READ_PORT_UCHAR((BaseAddress)+INDEX_DATA_REGISTER_OFFSET));
  1805. }
  1806. _inline
  1807. VOID
  1808. WriteVFASTBaudclkRegister(
  1809. IN PUCHAR BaseAddress,
  1810. IN UCHAR Value
  1811. )
  1812. {
  1813. WRITE_PORT_UCHAR((BaseAddress)+INDEX_REGISTER_OFFSET,INDEX_FOR_VFAST_BAUDCLK_REGISTER);
  1814. WRITE_PORT_UCHAR((BaseAddress)+INDEX_DATA_REGISTER_OFFSET, Value);
  1815. }
  1816. _inline
  1817. UCHAR
  1818. SerialGetInterruptEnable(
  1819. IN PUCHAR BaseAddress,
  1820. IN PSERIAL_DEVICE_EXTENSION Extension
  1821. )
  1822. {
  1823. UCHAR InterruptEnable = 0;
  1824. UCHAR FifoControl;
  1825. FifoControl = ReadInterruptEnableRegister(BaseAddress);
  1826. //
  1827. // D3: Modem Status D4:INTERRUPT_ENABLE_REG
  1828. // D2: Receiver Line Status D3:INTERRUPT_ENABLE_REG
  1829. // D1: Transmit Holding Register Empty D1:
  1830. // D0: Received Data Available D0:
  1831. //
  1832. InterruptEnable |= (FifoControl & (MODEM_STATUS_INTERRUPT | LINE_STATUS_INTERRUPT)) >> 1;
  1833. InterruptEnable |= (Extension->InterruptEnable16550);
  1834. return(InterruptEnable);
  1835. }
  1836. _inline
  1837. UCHAR
  1838. SerialGetLineStatus(
  1839. IN PUCHAR BaseAddress
  1840. )
  1841. {
  1842. UCHAR LineStatus = 0;
  1843. UCHAR FifoStatus;
  1844. FifoStatus = ReadLineStatusRegister(BaseAddress);
  1845. //
  1846. // D7: Error in Receive FIFO D7:LINE_STATUS_REG
  1847. // D6: Transmitter shift Register empty D0:LINE_STATUS_REG
  1848. // D5: Transmitter holding Register empty D1:LINE_STATUS_REG
  1849. // D4: Break interrupt D6:LINE_STATUS_REG
  1850. // D3: Framing error D5:LINE_STATUS_REG
  1851. // D2: Parity error D3:LINE_STATUS_REG
  1852. // D1: Overrun error D4:LINE_STATUS_REG
  1853. // D0: Receive Data Ready D2:LINE_STATUS_REG
  1854. //
  1855. LineStatus |= (FifoStatus & 0x80); // Error in Receive FIFO
  1856. LineStatus |= (FifoStatus & 0x01) << 6; // Transmitter shift Register empty
  1857. LineStatus |= (FifoStatus & 0x02) << 4; // Transmitter holding Register empty
  1858. LineStatus |= (FifoStatus & 0x40) >> 2; // Break interrupt
  1859. LineStatus |= (FifoStatus & 0x20) >> 2; // Framing error
  1860. LineStatus |= (FifoStatus & 0x08) >> 1; // Parity error
  1861. LineStatus |= (FifoStatus & 0x10) >> 3; // Overrun error
  1862. LineStatus |= (FifoStatus & 0x04) >> 2; // Receive Data Ready
  1863. return(LineStatus);
  1864. }
  1865. /* #define WRITE_PORT_UCHAR(BaseAddress, Value) */ \
  1866. /* do */ \
  1867. /* { */ \
  1868. /* WRITE_PORT_UCHAR(BaseAddress, Value); */ \
  1869. /* WRITE_PORT_UCHAR( */ \
  1870. /* (PUCHAR)IO_DELAY_REGISTER, */ \
  1871. /* IO_DELAY_DATA */ \
  1872. /* ); */ \
  1873. /* } while (0) */
  1874. #define READ_DIVISOR_LATCH(BaseAddress,PDesiredDivisor) \
  1875. do \
  1876. { \
  1877. *PDesiredDivisor = Extension->DivisorLatch16550; \
  1878. } while (0)
  1879. #define READ_INTERRUPT_ENABLE(BaseAddress) \
  1880. (SerialGetInterruptEnable(BaseAddress,Extension))
  1881. #define WRITE_INTERRUPT_ENABLE(BaseAddress,Values) \
  1882. do \
  1883. { \
  1884. UCHAR FifoControl = 0; \
  1885. UCHAR FifoInterruptControl = 0; \
  1886. UCHAR OutValues = 0; \
  1887. FifoControl = ReadInterruptEnableRegister(BaseAddress); \
  1888. if (Values & SERIAL_IER_MS) { \
  1889. FifoControl |= MODEM_STATUS_INTERRUPT; \
  1890. } else { \
  1891. FifoControl &= ~MODEM_STATUS_INTERRUPT; \
  1892. } \
  1893. if (Values & SERIAL_IER_RLS) { \
  1894. FifoControl |= LINE_STATUS_INTERRUPT; \
  1895. } else { \
  1896. FifoControl &= ~LINE_STATUS_INTERRUPT; \
  1897. } \
  1898. WriteInterruptEnableRegister(BaseAddress, FifoControl); \
  1899. FifoInterruptControl = (Values & (SERIAL_IER_THR | SERIAL_IER_RDA)); \
  1900. OutValues = (Values & (SERIAL_IER_THR | SERIAL_IER_RDA)); \
  1901. if (OutValues & SERIAL_IER_THR) { \
  1902. OutValues |= 0x04; \
  1903. } else { \
  1904. OutValues &= ~0x04; \
  1905. } \
  1906. WRITE_PORT_UCHAR(BaseAddress, OutValues); \
  1907. Extension->InterruptEnable16550 = FifoInterruptControl; \
  1908. } while (0)
  1909. #define DISABLE_ALL_INTERRUPTS(BaseAddress) \
  1910. do \
  1911. { \
  1912. WRITE_INTERRUPT_ENABLE(BaseAddress,0); \
  1913. } while (0)
  1914. #define ENABLE_ALL_INTERRUPTS(BaseAddress) \
  1915. do \
  1916. { \
  1917. \
  1918. WRITE_INTERRUPT_ENABLE( \
  1919. (BaseAddress), \
  1920. (UCHAR)(SERIAL_IER_RDA | SERIAL_IER_THR | \
  1921. SERIAL_IER_RLS | SERIAL_IER_MS) \
  1922. ); \
  1923. \
  1924. } while (0)
  1925. #define READ_INTERRUPT_ID_REG(BaseAddress) \
  1926. (((ReadInterruptIdentRegister(BaseAddress)) & 0x0f) | SERIAL_IIR_FIFOS_ENABLED)
  1927. #define READ_MODEM_CONTROL(BaseAddress) \
  1928. (Extension->ModemControl16550)
  1929. #define READ_MODEM_STATUS(BaseAddress) \
  1930. (ReadModemStatusRegister(BaseAddress))
  1931. #define READ_RECEIVE_BUFFER(BaseAddress) \
  1932. (ReadDataRegister(BaseAddress))
  1933. #define READ_LINE_STATUS(BaseAddress) \
  1934. (SerialGetLineStatus(BaseAddress))
  1935. #define READ_LINE_CONTROL(BaseAddress) \
  1936. (Extension->LineControl16550)
  1937. #define WRITE_TRANSMIT_HOLDING(BaseAddress,TransmitChar) \
  1938. do \
  1939. { \
  1940. WriteDataRegister( \
  1941. BaseAddress, \
  1942. (TransmitChar) \
  1943. ); \
  1944. } while (0)
  1945. #define WRITE_TRANSMIT_FIFO_HOLDING(BaseAddress,TransmitChars,TxN) \
  1946. do \
  1947. { \
  1948. PUCHAR TransmitBuffer = TransmitChars; \
  1949. ULONG i; \
  1950. for (i = 0; i < TxN; i++, TransmitBuffer++) { \
  1951. WriteDataRegister( \
  1952. BaseAddress, \
  1953. (UCHAR)(*TransmitBuffer) \
  1954. ); \
  1955. } \
  1956. } while (0)
  1957. #define ENTER_LEGACY_MODE(BaseAddress, InterruptEnable, FifoControl) \
  1958. do \
  1959. { \
  1960. *InterruptEnable = READ_INTERRUPT_ENABLE(BaseAddress); \
  1961. DISABLE_ALL_INTERRUPTS(BaseAddress); \
  1962. *FifoControl = ReadFifoControlRegister(BaseAddress); \
  1963. WriteFifoControlRegister(BaseAddress, DISABLE_FIFO_MODE); \
  1964. WRITE_IO_DELAY(3); \
  1965. } while (0)
  1966. #define EXIT_LEGACY_MODE(BaseAddress, InterruptEnable, FifoControl) \
  1967. do \
  1968. { \
  1969. WriteFifoControlRegister( \
  1970. (BaseAddress), \
  1971. (UCHAR)(*FifoControl) \
  1972. ); \
  1973. WRITE_INTERRUPT_ENABLE( \
  1974. (BaseAddress), \
  1975. (UCHAR)(*InterruptEnable), \
  1976. ); \
  1977. } while (0)
  1978. #define RESET_71051(ModeSet) \
  1979. do \
  1980. { \
  1981. WRITE_PORT_UCHAR((PUCHAR)Extension->CommandSetRegisterAddress, (UCHAR)0); \
  1982. WRITE_IO_DELAY(1); \
  1983. WRITE_PORT_UCHAR((PUCHAR)Extension->CommandSetRegisterAddress, (UCHAR)0); \
  1984. WRITE_IO_DELAY(1); \
  1985. WRITE_PORT_UCHAR((PUCHAR)Extension->CommandSetRegisterAddress, (UCHAR)0); \
  1986. WRITE_IO_DELAY(1); \
  1987. WRITE_PORT_UCHAR((PUCHAR)Extension->CommandSetRegisterAddress, COMMAND_ERROR_RESET); \
  1988. WRITE_IO_DELAY(2); \
  1989. WRITE_PORT_UCHAR( \
  1990. (PUCHAR)Extension->ModeSetRegisterAddress, \
  1991. (ModeSet) \
  1992. ); \
  1993. WRITE_IO_DELAY(1); \
  1994. WRITE_PORT_UCHAR( \
  1995. (PUCHAR)Extension->CommandSetRegisterAddress, \
  1996. (UCHAR)Extension->CommandSet71051 \
  1997. ); \
  1998. WRITE_IO_DELAY(1); \
  1999. } while (0)
  2000. #define WRITE_DIVISOR_LATCH(BaseAddress,DesiredDivisor) \
  2001. do \
  2002. { \
  2003. SHORT Divisor = DesiredDivisor; \
  2004. ULONG denominator; \
  2005. LONG DesiredBaud; \
  2006. Extension->DivisorLatch16550 = Divisor; \
  2007. denominator = 1843200 / Divisor; \
  2008. DesiredBaud = denominator / (ULONG)16; \
  2009. /* RS syncronize clock TXC prohibit */ \
  2010. /* 98 mode -> V.Fast mode, and Baud rate set */ \
  2011. switch (DesiredBaud) { \
  2012. case 0075: Divisor = VFAST_BAUD_0075; \
  2013. break; \
  2014. case 0150: Divisor = VFAST_BAUD_0150; \
  2015. break; \
  2016. case 0300: Divisor = VFAST_BAUD_0300; \
  2017. break; \
  2018. case 0600: Divisor = VFAST_BAUD_0600; \
  2019. break; \
  2020. case 1200: Divisor = VFAST_BAUD_1200; \
  2021. break; \
  2022. case 2400: Divisor = VFAST_BAUD_2400; \
  2023. break; \
  2024. case 4800: Divisor = VFAST_BAUD_4800; \
  2025. break; \
  2026. case 9600: Divisor = VFAST_BAUD_9600; \
  2027. break; \
  2028. case 14400: Divisor = VFAST_BAUD_14400; \
  2029. break; \
  2030. case 19200: Divisor = VFAST_BAUD_19200; \
  2031. break; \
  2032. case 38400: Divisor = VFAST_BAUD_38400; \
  2033. break; \
  2034. case 57600: Divisor = VFAST_BAUD_57600; \
  2035. break; \
  2036. case 115200: Divisor = VFAST_BAUD_115200; \
  2037. } \
  2038. WriteVFASTBaudclkRegister(BaseAddress, \
  2039. (UCHAR)(Divisor | COMMUNICATION_MODE) \
  2040. ); \
  2041. } while (0)
  2042. #define WRITE_LINE_CONTROL(BaseAddress,NewLineControl) \
  2043. do \
  2044. { \
  2045. UCHAR InterruptControl = 0; \
  2046. UCHAR FifoControl = 0; \
  2047. UCHAR OutLineControl = BAUDRATE_DEFAULT_MODE; \
  2048. ENTER_LEGACY_MODE(BaseAddress, &InterruptControl, &FifoControl); \
  2049. /* character length */ \
  2050. OutLineControl |= (NewLineControl & SERIAL_DATA_MASK) << 2; \
  2051. /* parity enable and parity mode */ \
  2052. OutLineControl |= (NewLineControl & SER71051_PARITY_MASK) << 1; \
  2053. /* stop bit */ \
  2054. if (NewLineControl & SERIAL_STOP_MASK) { \
  2055. if (NewLineControl & SERIAL_DATA_MASK) { \
  2056. OutLineControl |= SER71051_1_5_STOP; \
  2057. } else { \
  2058. OutLineControl |= SER71051_2_STOP; \
  2059. } \
  2060. } else { \
  2061. OutLineControl |= SER71051_1_STOP; \
  2062. } \
  2063. Extension->ModeSet71051 = OutLineControl; \
  2064. RESET_71051(OutLineControl); \
  2065. /* break character */ \
  2066. if (NewLineControl & SERIAL_LCR_BREAK) { \
  2067. if (!(Extension->LineControl16550 & SERIAL_LCR_BREAK)) { \
  2068. Extension->CommandSet71051 |= SER71051_SEND_BREAK; \
  2069. WRITE_PORT_UCHAR( \
  2070. (PUCHAR)Extension->CommandSetRegisterAddress, \
  2071. (UCHAR)Extension->CommandSet71051 \
  2072. ); \
  2073. } \
  2074. } else { \
  2075. if (Extension->LineControl16550 & SERIAL_LCR_BREAK) { \
  2076. Extension->CommandSet71051 &= ~SER71051_SEND_BREAK; \
  2077. WRITE_PORT_UCHAR( \
  2078. (PUCHAR)Extension->CommandSetRegisterAddress, \
  2079. (UCHAR)Extension->CommandSet71051 \
  2080. ); \
  2081. } \
  2082. } \
  2083. Extension->LineControl16550 = NewLineControl; \
  2084. EXIT_LEGACY_MODE(BaseAddress, &InterruptControl, &FifoControl); \
  2085. } while (0)
  2086. #define WRITE_FIFO_CONTROL(BaseAddress,ControlValue) \
  2087. do \
  2088. { \
  2089. UCHAR InterruptControl = 0; \
  2090. UCHAR FifoControl = 0; \
  2091. UCHAR OutValue = ControlValue; \
  2092. ENTER_LEGACY_MODE(BaseAddress, &InterruptControl, &FifoControl); \
  2093. OutValue &= ~(MODEM_STATUS_INTERRUPT | LINE_STATUS_INTERRUPT); \
  2094. WriteFifoControlRegister( \
  2095. (BaseAddress), \
  2096. (OutValue) \
  2097. ); \
  2098. FifoControl = ReadFifoControlRegister(BaseAddress); \
  2099. /* always Fifo mode on PC98 */ \
  2100. FifoControl |= SERIAL_FCR_ENABLE; \
  2101. EXIT_LEGACY_MODE(BaseAddress, &InterruptControl, &FifoControl); \
  2102. } while (0)
  2103. #define WRITE_MODEM_CONTROL(BaseAddress,ModemControl) \
  2104. do \
  2105. { \
  2106. UCHAR InterruptControl = 0; \
  2107. UCHAR FifoControl = 0; \
  2108. /* command default:ER, RXE, TxE -> ON */ \
  2109. UCHAR CommandSet = COMMAND_DEFAULT_SET; \
  2110. Extension->ModemControl16550 = ModemControl; \
  2111. ENTER_LEGACY_MODE(BaseAddress, &InterruptControl, &FifoControl); \
  2112. CommandSet |= (ModemControl & SERIAL_MCR_DTR) << 1; \
  2113. CommandSet |= (ModemControl & SERIAL_MCR_RTS) << 4; \
  2114. Extension->CommandSet71051 = CommandSet; \
  2115. WRITE_PORT_UCHAR( \
  2116. (PUCHAR)Extension->CommandSetRegisterAddress, \
  2117. (CommandSet) \
  2118. ); \
  2119. EXIT_LEGACY_MODE(BaseAddress, &InterruptControl, &FifoControl); \
  2120. } while (0)
  2121. #else
  2122. //
  2123. // Sets the divisor latch register. The divisor latch register
  2124. // is used to control the baud rate of the 8250.
  2125. //
  2126. // As with all of these routines it is assumed that it is called
  2127. // at a safe point to access the hardware registers. In addition
  2128. // it also assumes that the data is correct.
  2129. //
  2130. // Arguments:
  2131. //
  2132. // BaseAddress - A pointer to the address from which the hardware
  2133. // device registers are located.
  2134. //
  2135. // DesiredDivisor - The value to which the divisor latch register should
  2136. // be set.
  2137. //
  2138. #define WRITE_DIVISOR_LATCH(BaseAddress,DesiredDivisor) \
  2139. do \
  2140. { \
  2141. PUCHAR Address = BaseAddress; \
  2142. SHORT Divisor = DesiredDivisor; \
  2143. UCHAR LineControl; \
  2144. LineControl = READ_PORT_UCHAR(Address+LINE_CONTROL_REGISTER); \
  2145. WRITE_PORT_UCHAR( \
  2146. Address+LINE_CONTROL_REGISTER, \
  2147. (UCHAR)(LineControl | SERIAL_LCR_DLAB) \
  2148. ); \
  2149. WRITE_PORT_UCHAR( \
  2150. Address+DIVISOR_LATCH_LSB, \
  2151. (UCHAR)(Divisor & 0xff) \
  2152. ); \
  2153. WRITE_PORT_UCHAR( \
  2154. Address+DIVISOR_LATCH_MSB, \
  2155. (UCHAR)((Divisor & 0xff00) >> 8) \
  2156. ); \
  2157. WRITE_PORT_UCHAR( \
  2158. Address+LINE_CONTROL_REGISTER, \
  2159. LineControl \
  2160. ); \
  2161. } while (0)
  2162. //
  2163. // Reads the divisor latch register. The divisor latch register
  2164. // is used to control the baud rate of the 8250.
  2165. //
  2166. // As with all of these routines it is assumed that it is called
  2167. // at a safe point to access the hardware registers. In addition
  2168. // it also assumes that the data is correct.
  2169. //
  2170. // Arguments:
  2171. //
  2172. // BaseAddress - A pointer to the address from which the hardware
  2173. // device registers are located.
  2174. //
  2175. // DesiredDivisor - A pointer to the 2 byte word which will contain
  2176. // the value of the divisor.
  2177. //
  2178. #define READ_DIVISOR_LATCH(BaseAddress,PDesiredDivisor) \
  2179. do \
  2180. { \
  2181. PUCHAR Address = BaseAddress; \
  2182. PSHORT PDivisor = PDesiredDivisor; \
  2183. UCHAR LineControl; \
  2184. UCHAR Lsb; \
  2185. UCHAR Msb; \
  2186. LineControl = READ_PORT_UCHAR(Address+LINE_CONTROL_REGISTER); \
  2187. WRITE_PORT_UCHAR( \
  2188. Address+LINE_CONTROL_REGISTER, \
  2189. (UCHAR)(LineControl | SERIAL_LCR_DLAB) \
  2190. ); \
  2191. Lsb = READ_PORT_UCHAR(Address+DIVISOR_LATCH_LSB); \
  2192. Msb = READ_PORT_UCHAR(Address+DIVISOR_LATCH_MSB); \
  2193. *PDivisor = Lsb; \
  2194. *PDivisor = *PDivisor | (((USHORT)Msb) << 8); \
  2195. WRITE_PORT_UCHAR( \
  2196. Address+LINE_CONTROL_REGISTER, \
  2197. LineControl \
  2198. ); \
  2199. } while (0)
  2200. //
  2201. // This macro reads the interrupt enable register.
  2202. //
  2203. // Arguments:
  2204. //
  2205. // BaseAddress - A pointer to the address from which the hardware
  2206. // device registers are located.
  2207. //
  2208. #define READ_INTERRUPT_ENABLE(BaseAddress) \
  2209. (READ_PORT_UCHAR((BaseAddress)+INTERRUPT_ENABLE_REGISTER))
  2210. //
  2211. // This macro writes the interrupt enable register.
  2212. //
  2213. // Arguments:
  2214. //
  2215. // BaseAddress - A pointer to the address from which the hardware
  2216. // device registers are located.
  2217. //
  2218. // Values - The values to write to the interrupt enable register.
  2219. //
  2220. #define WRITE_INTERRUPT_ENABLE(BaseAddress,Values) \
  2221. do \
  2222. { \
  2223. WRITE_PORT_UCHAR( \
  2224. BaseAddress+INTERRUPT_ENABLE_REGISTER, \
  2225. Values \
  2226. ); \
  2227. } while (0)
  2228. //
  2229. // This macro disables all interrupts on the hardware.
  2230. //
  2231. // Arguments:
  2232. //
  2233. // BaseAddress - A pointer to the address from which the hardware
  2234. // device registers are located.
  2235. //
  2236. //
  2237. #define DISABLE_ALL_INTERRUPTS(BaseAddress) \
  2238. do \
  2239. { \
  2240. WRITE_INTERRUPT_ENABLE(BaseAddress,0); \
  2241. } while (0)
  2242. //
  2243. // This macro enables all interrupts on the hardware.
  2244. //
  2245. // Arguments:
  2246. //
  2247. // BaseAddress - A pointer to the address from which the hardware
  2248. // device registers are located.
  2249. //
  2250. //
  2251. #define ENABLE_ALL_INTERRUPTS(BaseAddress) \
  2252. do \
  2253. { \
  2254. \
  2255. WRITE_INTERRUPT_ENABLE( \
  2256. (BaseAddress), \
  2257. (UCHAR)(SERIAL_IER_RDA | SERIAL_IER_THR | \
  2258. SERIAL_IER_RLS | SERIAL_IER_MS) \
  2259. ); \
  2260. \
  2261. } while (0)
  2262. //
  2263. // This macro reads the interrupt identification register
  2264. //
  2265. // Arguments:
  2266. //
  2267. // BaseAddress - A pointer to the address from which the hardware
  2268. // device registers are located.
  2269. //
  2270. // Note that this routine potententially quites a transmitter
  2271. // empty interrupt. This is because one way that the transmitter
  2272. // empty interrupt is cleared is to simply read the interrupt id
  2273. // register.
  2274. //
  2275. //
  2276. #define READ_INTERRUPT_ID_REG(BaseAddress) \
  2277. (READ_PORT_UCHAR((BaseAddress)+INTERRUPT_IDENT_REGISTER))
  2278. //
  2279. // This macro reads the modem control register
  2280. //
  2281. // Arguments:
  2282. //
  2283. // BaseAddress - A pointer to the address from which the hardware
  2284. // device registers are located.
  2285. //
  2286. //
  2287. #define READ_MODEM_CONTROL(BaseAddress) \
  2288. (READ_PORT_UCHAR((BaseAddress)+MODEM_CONTROL_REGISTER))
  2289. //
  2290. // This macro reads the modem status register
  2291. //
  2292. // Arguments:
  2293. //
  2294. // BaseAddress - A pointer to the address from which the hardware
  2295. // device registers are located.
  2296. //
  2297. //
  2298. #define READ_MODEM_STATUS(BaseAddress) \
  2299. (READ_PORT_UCHAR((BaseAddress)+MODEM_STATUS_REGISTER))
  2300. //
  2301. // This macro reads a value out of the receive buffer
  2302. //
  2303. // Arguments:
  2304. //
  2305. // BaseAddress - A pointer to the address from which the hardware
  2306. // device registers are located.
  2307. //
  2308. //
  2309. #define READ_RECEIVE_BUFFER(BaseAddress) \
  2310. (READ_PORT_UCHAR((BaseAddress)+RECEIVE_BUFFER_REGISTER))
  2311. //
  2312. // This macro reads the line status register
  2313. //
  2314. // Arguments:
  2315. //
  2316. // BaseAddress - A pointer to the address from which the hardware
  2317. // device registers are located.
  2318. //
  2319. //
  2320. #define READ_LINE_STATUS(BaseAddress) \
  2321. (READ_PORT_UCHAR((BaseAddress)+LINE_STATUS_REGISTER))
  2322. //
  2323. // This macro writes the line control register
  2324. //
  2325. // Arguments:
  2326. //
  2327. // BaseAddress - A pointer to the address from which the hardware
  2328. // device registers are located.
  2329. //
  2330. //
  2331. #define WRITE_LINE_CONTROL(BaseAddress,NewLineControl) \
  2332. do \
  2333. { \
  2334. WRITE_PORT_UCHAR( \
  2335. (BaseAddress)+LINE_CONTROL_REGISTER, \
  2336. (NewLineControl) \
  2337. ); \
  2338. } while (0)
  2339. //
  2340. // This macro reads the line control register
  2341. //
  2342. // Arguments:
  2343. //
  2344. // BaseAddress - A pointer to the address from which the hardware
  2345. // device registers are located.
  2346. //
  2347. //
  2348. #define READ_LINE_CONTROL(BaseAddress) \
  2349. (READ_PORT_UCHAR((BaseAddress)+LINE_CONTROL_REGISTER))
  2350. //
  2351. // This macro writes to the transmit register
  2352. //
  2353. // Arguments:
  2354. //
  2355. // BaseAddress - A pointer to the address from which the hardware
  2356. // device registers are located.
  2357. //
  2358. // TransmitChar - The character to send down the wire.
  2359. //
  2360. //
  2361. #define WRITE_TRANSMIT_HOLDING(BaseAddress,TransmitChar) \
  2362. do \
  2363. { \
  2364. WRITE_PORT_UCHAR( \
  2365. (BaseAddress)+TRANSMIT_HOLDING_REGISTER, \
  2366. (TransmitChar) \
  2367. ); \
  2368. } while (0)
  2369. //
  2370. // This macro writes to the transmit FIFO register
  2371. //
  2372. // Arguments:
  2373. //
  2374. // BaseAddress - A pointer to the address from which the hardware
  2375. // device registers are located.
  2376. //
  2377. // TransmitChars - Pointer to the characters to send down the wire.
  2378. //
  2379. // TxN - number of charactes to send.
  2380. //
  2381. //
  2382. #define WRITE_TRANSMIT_FIFO_HOLDING(BaseAddress,TransmitChars,TxN) \
  2383. do \
  2384. { \
  2385. WRITE_PORT_BUFFER_UCHAR( \
  2386. (BaseAddress)+TRANSMIT_HOLDING_REGISTER, \
  2387. (TransmitChars), \
  2388. (TxN) \
  2389. ); \
  2390. } while (0)
  2391. //
  2392. // This macro writes to the control register
  2393. //
  2394. // Arguments:
  2395. //
  2396. // BaseAddress - A pointer to the address from which the hardware
  2397. // device registers are located.
  2398. //
  2399. // ControlValue - The value to set the fifo control register too.
  2400. //
  2401. //
  2402. #define WRITE_FIFO_CONTROL(BaseAddress,ControlValue) \
  2403. do \
  2404. { \
  2405. WRITE_PORT_UCHAR( \
  2406. (BaseAddress)+FIFO_CONTROL_REGISTER, \
  2407. (ControlValue) \
  2408. ); \
  2409. } while (0)
  2410. //
  2411. // This macro writes to the modem control register
  2412. //
  2413. // Arguments:
  2414. //
  2415. // BaseAddress - A pointer to the address from which the hardware
  2416. // device registers are located.
  2417. //
  2418. // ModemControl - The control bits to send to the modem control.
  2419. //
  2420. //
  2421. #define WRITE_MODEM_CONTROL(BaseAddress,ModemControl) \
  2422. do \
  2423. { \
  2424. WRITE_PORT_UCHAR( \
  2425. (BaseAddress)+MODEM_CONTROL_REGISTER, \
  2426. (ModemControl) \
  2427. ); \
  2428. } while (0)
  2429. #endif //defined(NEC_98)
  2430. //
  2431. // We use this to query into the registry as to whether we
  2432. // should break at driver entry.
  2433. //
  2434. extern SERIAL_FIRMWARE_DATA driverDefaults;
  2435. //
  2436. // This is exported from the kernel. It is used to point
  2437. // to the address that the kernel debugger is using.
  2438. //
  2439. extern PUCHAR *KdComPortInUse;
  2440. typedef enum _SERIAL_MEM_COMPARES {
  2441. AddressesAreEqual,
  2442. AddressesOverlap,
  2443. AddressesAreDisjoint
  2444. } SERIAL_MEM_COMPARES,*PSERIAL_MEM_COMPARES;
  2445. typedef struct _SERIAL_LIST_DATA {
  2446. PLIST_ENTRY destList;
  2447. PLIST_ENTRY newElement;
  2448. } SERIAL_LIST_DATA, *PSERIAL_LIST_DATA;
  2449. typedef struct _SERIAL_GLOBALS {
  2450. LIST_ENTRY AllDevObjs;
  2451. PVOID PAGESER_Handle;
  2452. UNICODE_STRING RegistryPath;
  2453. #if DBG
  2454. ULONG PAGESER_Count;
  2455. #endif // DBG
  2456. } SERIAL_GLOBALS, *PSERIAL_GLOBALS;
  2457. extern SERIAL_GLOBALS SerialGlobals;
  2458. typedef struct _SERIAL_USER_DATA {
  2459. PHYSICAL_ADDRESS UserPort;
  2460. PHYSICAL_ADDRESS UserInterruptStatus;
  2461. ULONG UserVector;
  2462. UNICODE_STRING UserSymbolicLink;
  2463. ULONG UserPortIndex;
  2464. ULONG UserBusNumber;
  2465. ULONG UserInterfaceType;
  2466. ULONG UserClockRate;
  2467. ULONG UserIndexed;
  2468. ULONG UserInterruptMode;
  2469. ULONG UserAddressSpace;
  2470. ULONG UserLevel;
  2471. ULONG DefaultPermitSystemWideShare;
  2472. ULONG DisablePort;
  2473. ULONG RxFIFO;
  2474. ULONG RxFIFODefault;
  2475. ULONG TxFIFO;
  2476. ULONG TxFIFODefault;
  2477. ULONG ForceFIFOEnable;
  2478. ULONG ForceFIFOEnableDefault;
  2479. ULONG PermitShareDefault;
  2480. ULONG LogFIFODefault;
  2481. ULONG MaskInverted;
  2482. } SERIAL_USER_DATA, *PSERIAL_USER_DATA;
  2483. typedef struct _SERIAL_PTR_CTX {
  2484. ULONG isPointer;
  2485. PHYSICAL_ADDRESS Port;
  2486. ULONG Vector;
  2487. } SERIAL_PTR_CTX, *PSERIAL_PTR_CTX;
  2488. #define DEVICE_OBJECT_NAME_LENGTH 128
  2489. #define SYMBOLIC_NAME_LENGTH 128
  2490. #define SERIAL_PNP_ID_STR L"*PNP0501"
  2491. #define SERIAL_PNP_MULTI_ID_STR L"*PNP0502"
  2492. #define SERIAL_DEVICE_MAP L"SERIALCOMM"
  2493. //
  2494. // Return values for mouse detection callback
  2495. //
  2496. #define SERIAL_FOUNDPOINTER_PORT 1
  2497. #define SERIAL_FOUNDPOINTER_VECTOR 2
  2498. #define SerialCompleteRequest(PDevExt, PIrp, PriBoost) \
  2499. { \
  2500. IoCompleteRequest((PIrp), (PriBoost)); \
  2501. SerialIRPEpilogue((PDevExt)); \
  2502. }
  2503. #define SERIAL_WMI_GUID_LIST_SIZE 5
  2504. extern WMIGUIDREGINFO SerialWmiGuidList[SERIAL_WMI_GUID_LIST_SIZE];