Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2920 lines
76 KiB

  1. /*****************************************************************************
  2. *
  3. * Copyright (c) 1996-1999 Microsoft Corporation
  4. *
  5. * @doc
  6. * @module ioctl.c | IrSIR NDIS Miniport Driver
  7. * @comm
  8. *
  9. *-----------------------------------------------------------------------------
  10. *
  11. * Author: Scott Holden (sholden)
  12. *
  13. * Date: 9/30/1996 (created)
  14. *
  15. * Contents:
  16. * Wrappers to the io control functions of the serial port.
  17. *
  18. *****************************************************************************/
  19. #include "irsir.h"
  20. NTSTATUS
  21. SerialFlush(IN PDEVICE_OBJECT pSerialDevObj);
  22. VOID
  23. SendIoctlToSerial(
  24. PDEVICE_OBJECT DeviceObject,
  25. PIO_STATUS_BLOCK StatusBlock,
  26. ULONG IoCtl,
  27. PVOID InputBuffer,
  28. ULONG InputBufferLength,
  29. PVOID OutputBuffer,
  30. ULONG OutputBufferLength
  31. );
  32. #pragma alloc_text(PAGE, SendIoctlToSerial)
  33. #pragma alloc_text(PAGE, SerialGetStats)
  34. #pragma alloc_text(PAGE, SerialClearStats)
  35. #pragma alloc_text(PAGE, SerialGetProperties)
  36. #pragma alloc_text(PAGE, SerialGetModemStatus)
  37. #pragma alloc_text(PAGE, SerialGetCommStatus)
  38. #pragma alloc_text(PAGE, SerialResetDevice)
  39. #pragma alloc_text(PAGE, SerialPurge)
  40. #pragma alloc_text(PAGE, SerialLSRMSTInsert)
  41. #pragma alloc_text(PAGE, SerialGetBaudRate)
  42. #pragma alloc_text(PAGE, SerialSetBaudRate)
  43. #pragma alloc_text(PAGE, SerialSetQueueSize)
  44. #pragma alloc_text(PAGE, SerialGetHandflow)
  45. #pragma alloc_text(PAGE, SerialSetHandflow)
  46. #pragma alloc_text(PAGE, SerialGetLineControl)
  47. #pragma alloc_text(PAGE, SerialSetLineControl)
  48. #pragma alloc_text(PAGE, SerialSetBreakOn)
  49. #pragma alloc_text(PAGE, SerialSetBreakOff)
  50. #pragma alloc_text(PAGE, SerialSetTimeouts)
  51. #pragma alloc_text(PAGE, SerialSetDTR)
  52. #pragma alloc_text(PAGE, SerialClrDTR)
  53. #pragma alloc_text(PAGE, SerialSetRTS)
  54. #pragma alloc_text(PAGE, SerialClrRTS)
  55. #pragma alloc_text(PAGE, SerialSetWaitMask)
  56. #pragma alloc_text(PAGE, SerialFlush)
  57. #pragma alloc_text(PAGE, SerialSynchronousWrite)
  58. #pragma alloc_text(PAGE, SerialSynchronousRead)
  59. //
  60. // NOTE:
  61. // all IOCTL_SERIAL_xxx control codes are built using the CTL_CODE macro
  62. // i.e. #define IOCTL_SERIAL_GET_BAUD_RATE \
  63. // CTL_CODE( FILE_DEVICE_SERIAL_PORT, \
  64. // 20, \
  65. // METHOD_BUFFERED, \
  66. // FILE_ANY_ACCESS)
  67. //
  68. // the CTL_CODE macro is defined as:
  69. // #define CTL_CODE( DeviceType, Function, Method, Access ) \
  70. // ( ((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method) )
  71. //
  72. // all of the serial io control codes use Method = METHOD_BUFFERED
  73. //
  74. // when using the IoBuildDeviceIoControlRequest(..), the function checks
  75. // IOCTL_SERIAL_xxx & 3
  76. //
  77. // since METHOD_BUFFERED = 0
  78. // IoBuildDeviceIoControlRequest will always follow case 0 and allocate a buffer
  79. // which is large enough to contain both the input and output buffers and then
  80. // set the appropriate fields in the irp.
  81. //
  82. // the input buffer is always copied into the buffer, so we don't have to do
  83. // it in the following wrapper functions
  84. //
  85. VOID
  86. SendIoctlToSerial(
  87. PDEVICE_OBJECT DeviceObject,
  88. PIO_STATUS_BLOCK StatusBlock,
  89. ULONG IoCtl,
  90. PVOID InputBuffer,
  91. ULONG InputBufferLength,
  92. PVOID OutputBuffer,
  93. ULONG OutputBufferLength
  94. )
  95. {
  96. KEVENT Event;
  97. PIRP Irp;
  98. NTSTATUS Status;
  99. PAGED_CODE();
  100. if (DeviceObject == NULL) {
  101. DEBUGMSG(DBG_OUT, (" SendIoctlToSerial() No device object.\n"));
  102. StatusBlock->Status=STATUS_INVALID_PARAMETER;
  103. return;
  104. }
  105. //
  106. // event to wait for completion of serial driver
  107. //
  108. KeInitializeEvent(
  109. &Event,
  110. NotificationEvent,
  111. FALSE
  112. );
  113. //
  114. // build irp to get performance stats and wait for event signalled
  115. //
  116. // irp is released by io manager
  117. //
  118. Irp = IoBuildDeviceIoControlRequest(
  119. IoCtl, // io control code
  120. DeviceObject, // device object
  121. InputBuffer, // input buffer
  122. InputBufferLength, // input buffer length
  123. OutputBuffer, // output buffer
  124. OutputBufferLength, // output buffer length
  125. FALSE, // calls IRP_MJ_DEVICE_CONTROL rather than IRP_MJ_INTERNAL_DEVICE_CONTROL
  126. &Event, // event to wait for completion
  127. StatusBlock // io status block to be set
  128. );
  129. if (Irp == NULL) {
  130. DEBUGMSG(DBG_OUT, (" SendIoctlToSerial(): IoBuildDeviceIoControlRequest failed.\n"));
  131. StatusBlock->Status = STATUS_INSUFFICIENT_RESOURCES;
  132. return;
  133. }
  134. Status = IoCallDriver(DeviceObject, Irp);
  135. //
  136. // if IoCallDriver returns STATUS_PENDING, we need to wait for the event
  137. //
  138. if (Status == STATUS_PENDING) {
  139. KeWaitForSingleObject(
  140. &Event, // object to wait for
  141. Executive, // reason to wait
  142. KernelMode, // processor mode
  143. FALSE, // alertable
  144. NULL // timeout
  145. );
  146. //
  147. // we can get the status of the IoCallDriver from the io status
  148. // block
  149. //
  150. }
  151. return;
  152. }
  153. /*****************************************************************************
  154. *
  155. * Function: SerialGetStats
  156. *
  157. * Synopsis: Synchronous I/O control request to serial device object.
  158. *
  159. * Arguments:
  160. *
  161. * Returns: STATUS_SUCCESS
  162. * STATUS_INSUFFICIENT_RESOURCES
  163. * STATUS_UNSUCCESSFUL or other failure if IoCallDriver fails
  164. *
  165. * Algorithm:
  166. *
  167. * History: dd-mm-yyyy Author Comment
  168. * 9/30/1996 sholden author
  169. *
  170. * Notes:
  171. *
  172. * This routine must be called from IRQL PASSIVE_LEVEL.
  173. *
  174. *****************************************************************************/
  175. NTSTATUS
  176. SerialGetStats(
  177. IN PDEVICE_OBJECT pSerialDevObj,
  178. OUT PSERIALPERF_STATS pPerfStats
  179. )
  180. {
  181. SERIALPERF_STATS PerfStats;
  182. IO_STATUS_BLOCK ioStatusBlock;
  183. DEBUGMSG(DBG_FUNC, ("+SerialGetStats\n"));
  184. SendIoctlToSerial(
  185. pSerialDevObj,
  186. &ioStatusBlock,
  187. IOCTL_SERIAL_GET_STATS,
  188. NULL,
  189. 0,
  190. &PerfStats, // output buffer
  191. sizeof(SERIALPERF_STATS) // output buffer length
  192. );
  193. ASSERT(sizeof(*pPerfStats) >= sizeof(SERIALPERF_STATS));
  194. if (NT_SUCCESS(ioStatusBlock.Status)) {
  195. RtlCopyMemory(pPerfStats, &PerfStats, sizeof(SERIALPERF_STATS));
  196. }
  197. DEBUGMSG(DBG_FUNC, ("-SerialGetStats\n"));
  198. return ioStatusBlock.Status;
  199. }
  200. /*****************************************************************************
  201. *
  202. * Function: SerialClearStats
  203. *
  204. * Synopsis: Synchronous I/O control request to serial device object.
  205. *
  206. * Arguments:
  207. *
  208. * Returns: STATUS_SUCCESS
  209. * STATUS_INSUFFICIENT_RESOURCES
  210. * STATUS_UNSUCCESSFUL or other failure if IoCallDriver fails
  211. *
  212. * Algorithm:
  213. *
  214. * History: dd-mm-yyyy Author Comment
  215. * 9/30/1996 sholden author
  216. *
  217. * Notes:
  218. *
  219. * This routine must be called from IRQL PASSIVE_LEVEL.
  220. *
  221. *****************************************************************************/
  222. NTSTATUS
  223. SerialClearStats(
  224. IN PDEVICE_OBJECT pSerialDevObj
  225. )
  226. {
  227. IO_STATUS_BLOCK ioStatusBlock;
  228. DEBUGMSG(DBG_FUNC, ("+SerialClearStats\n"));
  229. SendIoctlToSerial(
  230. pSerialDevObj,
  231. &ioStatusBlock,
  232. IOCTL_SERIAL_CLEAR_STATS,
  233. NULL,
  234. 0,
  235. NULL, // output buffer
  236. 0 // output buffer length
  237. );
  238. DEBUGMSG(DBG_FUNC, ("-SerialClearStats\n"));
  239. return ioStatusBlock.Status;
  240. }
  241. /*****************************************************************************
  242. *
  243. * Function: SerialGetProperties
  244. *
  245. * Synopsis: Synchronous I/O control request to serial device object.
  246. *
  247. * Arguments:
  248. *
  249. * Returns: STATUS_SUCCESS
  250. * STATUS_INSUFFICIENT_RESOURCES
  251. * STATUS_UNSUCCESSFUL or other failure if IoCallDriver fails
  252. *
  253. * Algorithm:
  254. *
  255. * History: dd-mm-yyyy Author Comment
  256. * 9/30/1996 sholden author
  257. *
  258. * Notes:
  259. *
  260. * This routine must be called from IRQL PASSIVE_LEVEL.
  261. *
  262. *****************************************************************************/
  263. NTSTATUS
  264. SerialGetProperties(
  265. IN PDEVICE_OBJECT pSerialDevObj,
  266. OUT PSERIAL_COMMPROP pCommProp
  267. )
  268. {
  269. SERIAL_COMMPROP CommProp;
  270. IO_STATUS_BLOCK ioStatusBlock;
  271. DEBUGMSG(DBG_FUNC, ("+SerialGetProperties\n"));
  272. SendIoctlToSerial(
  273. pSerialDevObj,
  274. &ioStatusBlock,
  275. IOCTL_SERIAL_GET_PROPERTIES,
  276. NULL,
  277. 0,
  278. &CommProp, // output buffer
  279. sizeof(SERIAL_COMMPROP) // output buffer length
  280. );
  281. ASSERT(sizeof(*pCommProp) >= sizeof(SERIAL_COMMPROP));
  282. if (NT_SUCCESS(ioStatusBlock.Status)) {
  283. RtlCopyMemory(pCommProp, &CommProp, sizeof(SERIAL_COMMPROP));
  284. }
  285. DEBUGMSG(DBG_FUNC, ("-SerialGetProperties\n"));
  286. return ioStatusBlock.Status;
  287. }
  288. /*****************************************************************************
  289. *
  290. * Function: SerialGetModemStatus
  291. *
  292. * Synopsis: Synchronous I/O control request to serial device object.
  293. *
  294. * Arguments:
  295. *
  296. * Returns: STATUS_SUCCESS
  297. * STATUS_INSUFFICIENT_RESOURCES
  298. * STATUS_UNSUCCESSFUL or other failure if IoCallDriver fails
  299. *
  300. * Algorithm:
  301. *
  302. * History: dd-mm-yyyy Author Comment
  303. * 9/30/1996 sholden author
  304. *
  305. * Notes:
  306. *
  307. * This routine must be called from IRQL PASSIVE_LEVEL.
  308. *
  309. *****************************************************************************/
  310. NTSTATUS
  311. SerialGetModemStatus(
  312. IN PDEVICE_OBJECT pSerialDevObj,
  313. OUT ULONG *pModemStatus
  314. )
  315. {
  316. ULONG ModemStatus;
  317. IO_STATUS_BLOCK ioStatusBlock;
  318. DEBUGMSG(DBG_FUNC, ("+SerialGetModemStatus\n"));
  319. SendIoctlToSerial(
  320. pSerialDevObj,
  321. &ioStatusBlock,
  322. IOCTL_SERIAL_GET_MODEMSTATUS,
  323. NULL,
  324. 0,
  325. &ModemStatus, // output buffer
  326. sizeof(ULONG) // output buffer length
  327. );
  328. ASSERT(sizeof(*pModemStatus) >= sizeof(ULONG));
  329. if (NT_SUCCESS(ioStatusBlock.Status)) {
  330. RtlCopyMemory(pModemStatus, &ModemStatus, sizeof(ULONG));
  331. }
  332. DEBUGMSG(DBG_FUNC, ("-SerialGetModemStatus\n"));
  333. return ioStatusBlock.Status;
  334. }
  335. /*****************************************************************************
  336. *
  337. * Function: SerialGetCommStatus
  338. *
  339. * Synopsis: Synchronous I/O control request to serial device object.
  340. *
  341. * Arguments:
  342. *
  343. * Returns: STATUS_SUCCESS
  344. * STATUS_INSUFFICIENT_RESOURCES
  345. * STATUS_UNSUCCESSFUL or other failure if IoCallDriver fails
  346. *
  347. * Algorithm:
  348. *
  349. * History: dd-mm-yyyy Author Comment
  350. * 9/30/1996 sholden author
  351. *
  352. * Notes:
  353. *
  354. * This routine must be called from IRQL PASSIVE_LEVEL.
  355. *
  356. *****************************************************************************/
  357. NTSTATUS
  358. SerialGetCommStatus(
  359. IN PDEVICE_OBJECT pSerialDevObj,
  360. OUT PSERIAL_STATUS pCommStatus
  361. )
  362. {
  363. SERIAL_STATUS CommStatus;
  364. IO_STATUS_BLOCK ioStatusBlock;
  365. DEBUGMSG(DBG_FUNC, ("+SerialGetCommStatus\n"));
  366. SendIoctlToSerial(
  367. pSerialDevObj,
  368. &ioStatusBlock,
  369. IOCTL_SERIAL_GET_COMMSTATUS,
  370. NULL,
  371. 0,
  372. &CommStatus, // output buffer
  373. sizeof(SERIAL_STATUS) // output buffer length
  374. );
  375. ASSERT(sizeof(*pCommStatus) >= sizeof(SERIAL_STATUS));
  376. if (NT_SUCCESS(ioStatusBlock.Status)) {
  377. RtlCopyMemory(pCommStatus, &CommStatus, sizeof(SERIAL_STATUS));
  378. }
  379. DEBUGMSG(DBG_FUNC, ("-SerialGetCommStatus\n"));
  380. return ioStatusBlock.Status;
  381. }
  382. /*****************************************************************************
  383. *
  384. * Function: SerialResetDevice
  385. *
  386. * Synopsis: Synchronous I/O control request to serial device object.
  387. *
  388. * Arguments:
  389. *
  390. * Returns: STATUS_SUCCESS
  391. * STATUS_INSUFFICIENT_RESOURCES
  392. * STATUS_UNSUCCESSFUL or other failure if IoCallDriver fails
  393. *
  394. * Algorithm:
  395. *
  396. * History: dd-mm-yyyy Author Comment
  397. * 9/30/1996 sholden author
  398. *
  399. * Notes:
  400. *
  401. * This routine must be called from IRQL PASSIVE_LEVEL.
  402. *
  403. *****************************************************************************/
  404. NTSTATUS
  405. SerialResetDevice(
  406. IN PDEVICE_OBJECT pSerialDevObj
  407. )
  408. {
  409. IO_STATUS_BLOCK ioStatusBlock;
  410. DEBUGMSG(DBG_FUNC, ("+SerialResetDevice\n"));
  411. SendIoctlToSerial(
  412. pSerialDevObj,
  413. &ioStatusBlock,
  414. IOCTL_SERIAL_RESET_DEVICE,
  415. NULL,
  416. 0,
  417. NULL,
  418. 0
  419. );
  420. DEBUGMSG(DBG_FUNC, ("-SerialResetDevice\n"));
  421. return ioStatusBlock.Status;
  422. }
  423. /*****************************************************************************
  424. *
  425. * Function: SerialPurge
  426. *
  427. * Synopsis: Synchronous I/O control request to serial device object.
  428. *
  429. * Arguments:
  430. *
  431. * Returns: STATUS_SUCCESS
  432. * STATUS_INSUFFICIENT_RESOURCES
  433. * STATUS_UNSUCCESSFUL or other failure if IoCallDriver fails
  434. *
  435. * Algorithm:
  436. *
  437. * History: dd-mm-yyyy Author Comment
  438. * 9/30/1996 sholden author
  439. *
  440. * Notes:
  441. *
  442. * This routine must be called from IRQL PASSIVE_LEVEL.
  443. *
  444. *****************************************************************************/
  445. NTSTATUS
  446. SerialPurge(
  447. IN PDEVICE_OBJECT pSerialDevObj
  448. )
  449. {
  450. ULONG BitMask;
  451. IO_STATUS_BLOCK ioStatusBlock;
  452. DEBUGMSG(DBG_FUNC, ("+SerialPurge\n"));
  453. SendIoctlToSerial(
  454. pSerialDevObj,
  455. &ioStatusBlock,
  456. IOCTL_SERIAL_PURGE,
  457. &BitMask, // input buffer
  458. sizeof(ULONG), // input buffer length
  459. NULL,
  460. 0
  461. );
  462. DEBUGMSG(DBG_FUNC, ("-SerialPurge\n"));
  463. return ioStatusBlock.Status;
  464. }
  465. #if 0
  466. /*****************************************************************************
  467. *
  468. * Function: SerialLSRMSTInsert
  469. *
  470. * Synopsis: Synchronous I/O control request to serial device object.
  471. *
  472. * Arguments:
  473. *
  474. * Returns: STATUS_SUCCESS
  475. * STATUS_INSUFFICIENT_RESOURCES
  476. * STATUS_UNSUCCESSFUL or other failure if IoCallDriver fails
  477. *
  478. * Algorithm:
  479. *
  480. * History: dd-mm-yyyy Author Comment
  481. * 9/30/1996 sholden author
  482. *
  483. * Notes:
  484. *
  485. * This routine must be called from IRQL PASSIVE_LEVEL.
  486. *
  487. *****************************************************************************/
  488. NTSTATUS
  489. SerialLSRMSTInsert(
  490. IN PDEVICE_OBJECT pSerialDevObj,
  491. IN UCHAR *pInsertionMode
  492. )
  493. {
  494. UCHAR InsertionMode;
  495. IO_STATUS_BLOCK ioStatusBlock;
  496. DEBUGMSG(DBG_FUNC, ("+SerialLSRMSTInsert\n"));
  497. SendIoctlToSerial(
  498. pSerialDevObj,
  499. &ioStatusBlock,
  500. IOCTL_SERIAL_LSRMST_INSERT,
  501. pInsertionMode, // input buffer
  502. sizeof(UCHAR), // input buffer length
  503. NULL,
  504. 0
  505. );
  506. DEBUGMSG(DBG_FUNC, ("-SerialLSRMSTInsert\n"));
  507. return IoStatusBlock.Status;
  508. }
  509. #endif
  510. /*****************************************************************************
  511. *
  512. * Function: SerialGetBaudRate
  513. *
  514. * Synopsis: Synchronous I/O control request to serial device object.
  515. *
  516. * Arguments:
  517. *
  518. * Returns: STATUS_SUCCESS
  519. * STATUS_INSUFFICIENT_RESOURCES
  520. * STATUS_UNSUCCESSFUL or other failure if IoCallDriver fails
  521. *
  522. * Algorithm:
  523. *
  524. * History: dd-mm-yyyy Author Comment
  525. * 9/30/1996 sholden author
  526. *
  527. * Notes:
  528. *
  529. * This routine must be called from IRQL PASSIVE_LEVEL.
  530. *
  531. *****************************************************************************/
  532. NTSTATUS
  533. SerialGetBaudRate(
  534. IN PDEVICE_OBJECT pSerialDevObj,
  535. OUT ULONG *pBaudRate
  536. )
  537. {
  538. ULONG BaudRate;
  539. IO_STATUS_BLOCK ioStatusBlock;
  540. DEBUGMSG(DBG_FUNC, ("+SerialGetBaudRate\n"));
  541. SendIoctlToSerial(
  542. pSerialDevObj,
  543. &ioStatusBlock,
  544. IOCTL_SERIAL_GET_BAUD_RATE, // io control code
  545. NULL,
  546. 0,
  547. &BaudRate, // output buffer
  548. sizeof(ULONG) // output buffer length
  549. );
  550. ASSERT(sizeof(*pBaudRate) >= sizeof(ULONG));
  551. if (NT_SUCCESS(ioStatusBlock.Status)) {
  552. RtlCopyMemory(pBaudRate, &BaudRate, sizeof(ULONG));
  553. }
  554. DEBUGMSG(DBG_FUNC, ("-SerialGetBaudRate\n"));
  555. return ioStatusBlock.Status;
  556. }
  557. /*****************************************************************************
  558. *
  559. * Function: SerialSetBaudRate
  560. *
  561. * Synopsis: Synchronous I/O control request to serial device object.
  562. *
  563. * Arguments:
  564. *
  565. * Returns: STATUS_SUCCESS
  566. * STATUS_INSUFFICIENT_RESOURCES
  567. * STATUS_UNSUCCESSFUL or other failure if IoCallDriver fails
  568. *
  569. * Algorithm:
  570. *
  571. * History: dd-mm-yyyy Author Comment
  572. * 9/30/1996 sholden author
  573. *
  574. * Notes:
  575. *
  576. * This routine must be called from IRQL PASSIVE_LEVEL.
  577. *
  578. *****************************************************************************/
  579. NTSTATUS
  580. SerialSetBaudRate(
  581. IN PDEVICE_OBJECT pSerialDevObj,
  582. IN ULONG *pBaudRate
  583. )
  584. {
  585. IO_STATUS_BLOCK ioStatusBlock;
  586. DEBUGMSG(DBG_FUNC, ("+SerialSetBaudRate\n"));
  587. SendIoctlToSerial(
  588. pSerialDevObj,
  589. &ioStatusBlock,
  590. IOCTL_SERIAL_SET_BAUD_RATE, // io control code
  591. pBaudRate, // input buffer
  592. sizeof(ULONG), // input buffer length
  593. NULL,
  594. 0
  595. );
  596. DEBUGMSG(DBG_FUNC, ("-SerialSetBaudRate\n"));
  597. return ioStatusBlock.Status;
  598. }
  599. /*****************************************************************************
  600. *
  601. * Function: SerialSetQueueSize
  602. *
  603. * Synopsis: Synchronous I/O control request to serial device object.
  604. *
  605. * Arguments:
  606. *
  607. * Returns: STATUS_SUCCESS
  608. * STATUS_INSUFFICIENT_RESOURCES
  609. * STATUS_UNSUCCESSFUL or other failure if IoCallDriver fails
  610. *
  611. * Algorithm:
  612. *
  613. * History: dd-mm-yyyy Author Comment
  614. * 9/30/1996 sholden author
  615. *
  616. * Notes:
  617. *
  618. * This routine must be called from IRQL PASSIVE_LEVEL.
  619. *
  620. *****************************************************************************/
  621. NTSTATUS
  622. SerialSetQueueSize(
  623. IN PDEVICE_OBJECT pSerialDevObj,
  624. IN PSERIAL_QUEUE_SIZE pQueueSize
  625. )
  626. {
  627. IO_STATUS_BLOCK ioStatusBlock;
  628. DEBUGMSG(DBG_FUNC, ("+SerialSetQueueSize\n"));
  629. SendIoctlToSerial(
  630. pSerialDevObj,
  631. &ioStatusBlock,
  632. IOCTL_SERIAL_SET_QUEUE_SIZE, // io control code
  633. pQueueSize, // input buffer
  634. sizeof(SERIAL_QUEUE_SIZE), // input buffer length
  635. NULL,
  636. 0
  637. );
  638. DEBUGMSG(DBG_FUNC, ("-SerialSetQueueSize\n"));
  639. return ioStatusBlock.Status;
  640. }
  641. #if 0
  642. /*****************************************************************************
  643. *
  644. * Function: SerialGetHandflow
  645. *
  646. * Synopsis: Synchronous I/O control request to serial device object.
  647. *
  648. * Arguments:
  649. *
  650. * Returns: STATUS_SUCCESS
  651. * STATUS_INSUFFICIENT_RESOURCES
  652. * STATUS_UNSUCCESSFUL or other failure if IoCallDriver fails
  653. *
  654. * Algorithm:
  655. *
  656. * History: dd-mm-yyyy Author Comment
  657. * 9/30/1996 sholden author
  658. *
  659. * Notes:
  660. *
  661. * This routine must be called from IRQL PASSIVE_LEVEL.
  662. *
  663. *****************************************************************************/
  664. NTSTATUS
  665. SerialGetHandflow(
  666. IN PDEVICE_OBJECT pSerialDevObj,
  667. OUT PSERIAL_HANDFLOW pHandflow
  668. )
  669. {
  670. SERIAL_HANDFLOW Handflow;
  671. IO_STATUS_BLOCK ioStatusBlock;
  672. DEBUGMSG(DBG_FUNC, ("+SerialGetHandflow\n"));
  673. SendIoctlToSerial(
  674. pSerialDevObj,
  675. &ioStatusBlock,
  676. IOCTL_SERIAL_GET_HANDFLOW, // io control code
  677. NULL,
  678. 0,
  679. &Handflow, // output buffer
  680. sizeof(SERIAL_HANDFLOW), // output buffer length
  681. );
  682. ASSERT(sizeof(*pHandflow) >= sizeof(SERIAL_HANDFLOW));
  683. RtlCopyMemory(pHandflow, &Handflow, sizeof(SERIAL_HANDFLOW));
  684. DEBUGMSG(DBG_FUNC, ("-SerialGetHandflow\n"));
  685. return ioStatusBlock.Status;
  686. }
  687. /*****************************************************************************
  688. *
  689. * Function: SerialSetHandflow
  690. *
  691. * Synopsis: Synchronous I/O control request to serial device object.
  692. *
  693. * Arguments:
  694. *
  695. * Returns: STATUS_SUCCESS
  696. * STATUS_INSUFFICIENT_RESOURCES
  697. * STATUS_UNSUCCESSFUL or other failure if IoCallDriver fails
  698. *
  699. * Algorithm:
  700. *
  701. * History: dd-mm-yyyy Author Comment
  702. * 9/30/1996 sholden author
  703. *
  704. * Notes:
  705. *
  706. * This routine must be called from IRQL PASSIVE_LEVEL.
  707. *
  708. *****************************************************************************/
  709. NTSTATUS
  710. SerialSetHandflow(
  711. IN PDEVICE_OBJECT pSerialDevObj,
  712. IN PSERIAL_HANDFLOW pHandflow
  713. )
  714. {
  715. IO_STATUS_BLOCK ioStatusBlock;
  716. DEBUGMSG(DBG_FUNC, ("+SerialSetHandflow\n"));
  717. SendIoctlToSerial(
  718. pSerialDevObj,
  719. &ioStatusBlock,
  720. IOCTL_SERIAL_SET_HANDFLOW, // io control code
  721. pHandflow, // input buffer
  722. sizeof(SERIAL_HANDFLOW), // input buffer length
  723. NULL,
  724. 0
  725. );
  726. DEBUGMSG(DBG_FUNC, ("-SerialSetHandflow\n"));
  727. return ioStatusBlock.Status;
  728. }
  729. #endif
  730. /*****************************************************************************
  731. *
  732. * Function: SerialGetLineControl
  733. *
  734. * Synopsis: Synchronous I/O control request to serial device object.
  735. *
  736. * Arguments:
  737. *
  738. * Returns: STATUS_SUCCESS
  739. * STATUS_INSUFFICIENT_RESOURCES
  740. * STATUS_UNSUCCESSFUL or other failure if IoCallDriver fails
  741. *
  742. * Algorithm:
  743. *
  744. * History: dd-mm-yyyy Author Comment
  745. * 9/30/1996 sholden author
  746. *
  747. * Notes:
  748. *
  749. * This routine must be called from IRQL PASSIVE_LEVEL.
  750. *
  751. *****************************************************************************/
  752. NTSTATUS
  753. SerialGetLineControl(
  754. IN PDEVICE_OBJECT pSerialDevObj,
  755. OUT PSERIAL_LINE_CONTROL pLineControl
  756. )
  757. {
  758. SERIAL_LINE_CONTROL LineControl;
  759. IO_STATUS_BLOCK ioStatusBlock;
  760. DEBUGMSG(DBG_FUNC, ("+SerialGetLineControl\n"));
  761. SendIoctlToSerial(
  762. pSerialDevObj,
  763. &ioStatusBlock,
  764. IOCTL_SERIAL_GET_LINE_CONTROL,
  765. NULL,
  766. 0,
  767. &LineControl, // output buffer
  768. sizeof(SERIAL_LINE_CONTROL) // output buffer length
  769. );
  770. ASSERT(sizeof(*pLineControl) >= sizeof(SERIAL_LINE_CONTROL));
  771. if (NT_SUCCESS(ioStatusBlock.Status)) {
  772. RtlCopyMemory(pLineControl, &LineControl, sizeof(SERIAL_LINE_CONTROL));
  773. }
  774. DEBUGMSG(DBG_FUNC, ("-SerialGetLineControl\n"));
  775. return ioStatusBlock.Status;
  776. }
  777. /*****************************************************************************
  778. *
  779. * Function: SerialSetLineControl
  780. *
  781. * Synopsis: Synchronous I/O control request to serial device object.
  782. *
  783. * Arguments:
  784. *
  785. * Returns: STATUS_SUCCESS
  786. * STATUS_INSUFFICIENT_RESOURCES
  787. * STATUS_UNSUCCESSFUL or other failure if IoCallDriver fails
  788. *
  789. * Algorithm:
  790. *
  791. * History: dd-mm-yyyy Author Comment
  792. * 9/30/1996 sholden author
  793. *
  794. * Notes:
  795. *
  796. * This routine must be called from IRQL PASSIVE_LEVEL.
  797. *
  798. *****************************************************************************/
  799. NTSTATUS
  800. SerialSetLineControl(
  801. IN PDEVICE_OBJECT pSerialDevObj,
  802. IN PSERIAL_LINE_CONTROL pLineControl
  803. )
  804. {
  805. IO_STATUS_BLOCK ioStatusBlock;
  806. DEBUGMSG(DBG_FUNC, ("+SerialSetLineControl\n"));
  807. SendIoctlToSerial(
  808. pSerialDevObj,
  809. &ioStatusBlock,
  810. IOCTL_SERIAL_SET_LINE_CONTROL, // io control code
  811. pLineControl, // input buffer
  812. sizeof(SERIAL_LINE_CONTROL), // input buffer length
  813. NULL,
  814. 0
  815. );
  816. DEBUGMSG(DBG_FUNC, ("-SerialResetDevice\n"));
  817. return ioStatusBlock.Status;
  818. }
  819. /*****************************************************************************
  820. *
  821. * Function: SerialSetBreakOn
  822. *
  823. * Synopsis: Synchronous I/O control request to serial device object.
  824. *
  825. * Arguments:
  826. *
  827. * Returns: STATUS_SUCCESS
  828. * STATUS_INSUFFICIENT_RESOURCES
  829. * STATUS_UNSUCCESSFUL or other failure if IoCallDriver fails
  830. *
  831. * Algorithm:
  832. *
  833. * History: dd-mm-yyyy Author Comment
  834. * 9/30/1996 sholden author
  835. *
  836. * Notes:
  837. *
  838. * This routine must be called from IRQL PASSIVE_LEVEL.
  839. *
  840. *****************************************************************************/
  841. NTSTATUS
  842. SerialSetBreakOn(
  843. IN PDEVICE_OBJECT pSerialDevObj
  844. )
  845. {
  846. IO_STATUS_BLOCK ioStatusBlock;
  847. DEBUGMSG(DBG_FUNC, ("+SerialSetBreakOn\n"));
  848. SendIoctlToSerial(
  849. pSerialDevObj,
  850. &ioStatusBlock,
  851. IOCTL_SERIAL_SET_BREAK_ON, // io control code
  852. NULL,
  853. 0,
  854. NULL,
  855. 0
  856. );
  857. DEBUGMSG(DBG_FUNC, ("-SerialSetBreakOn\n"));
  858. return ioStatusBlock.Status;
  859. }
  860. /*****************************************************************************
  861. *
  862. * Function: SerialSetBreakOff
  863. *
  864. * Synopsis: Synchronous I/O control request to serial device object.
  865. *
  866. * Arguments:
  867. *
  868. * Returns: STATUS_SUCCESS
  869. * STATUS_INSUFFICIENT_RESOURCES
  870. * STATUS_UNSUCCESSFUL or other failure if IoCallDriver fails
  871. *
  872. * Algorithm:
  873. *
  874. * History: dd-mm-yyyy Author Comment
  875. * 9/30/1996 sholden author
  876. *
  877. * Notes:
  878. *
  879. * This routine must be called from IRQL PASSIVE_LEVEL.
  880. *
  881. *****************************************************************************/
  882. NTSTATUS
  883. SerialSetBreakOff(
  884. IN PDEVICE_OBJECT pSerialDevObj
  885. )
  886. {
  887. IO_STATUS_BLOCK ioStatusBlock;
  888. DEBUGMSG(DBG_FUNC, ("+SerialSetBreakOff\n"));
  889. SendIoctlToSerial(
  890. pSerialDevObj,
  891. &ioStatusBlock,
  892. IOCTL_SERIAL_SET_BREAK_OFF, // io control code
  893. NULL,
  894. 0,
  895. NULL,
  896. 0
  897. );
  898. DEBUGMSG(DBG_FUNC, ("-SerialSetBreakOff\n"));
  899. return ioStatusBlock.Status;
  900. }
  901. #if 0
  902. /*****************************************************************************
  903. *
  904. * Function: SerialGetTimeouts
  905. *
  906. * Synopsis: Synchronous I/O control request to serial device object.
  907. *
  908. * Arguments:
  909. *
  910. * Returns: STATUS_SUCCESS
  911. * STATUS_INSUFFICIENT_RESOURCES
  912. * STATUS_UNSUCCESSFUL or other failure if IoCallDriver fails
  913. *
  914. * Algorithm:
  915. *
  916. * History: dd-mm-yyyy Author Comment
  917. * 9/30/1996 sholden author
  918. *
  919. * Notes:
  920. *
  921. * This routine must be called from IRQL PASSIVE_LEVEL.
  922. *
  923. *****************************************************************************/
  924. NTSTATUS
  925. SerialGetTimeouts(
  926. IN PDEVICE_OBJECT pSerialDevObj,
  927. OUT PSERIAL_TIMEOUTS pTimeouts
  928. )
  929. {
  930. PIRP pIrp;
  931. SERIAL_TIMEOUTS Timeouts;
  932. KEVENT eventComplete;
  933. IO_STATUS_BLOCK ioStatusBlock;
  934. NTSTATUS status;
  935. if (!pSerialDevObj)
  936. {
  937. DEBUGMSG(DBG_ERROR, ("IRSIR: SerialDevObj==NULL\n"));
  938. return STATUS_INVALID_PARAMETER;
  939. }
  940. DEBUGMSG(DBG_FUNC, ("+SerialGetTimeouts\n"));
  941. //
  942. // event to wait for completion of serial driver
  943. //
  944. KeInitializeEvent(
  945. &eventComplete,
  946. NotificationEvent,
  947. FALSE
  948. );
  949. //
  950. // build irp to get baud rate and wait for event signalled
  951. //
  952. // irp is released by io manager
  953. //
  954. pIrp = IoBuildDeviceIoControlRequest(
  955. IOCTL_SERIAL_GET_TIMEOUTS, // io control code
  956. pSerialDevObj, // device object
  957. NULL, // input buffer
  958. 0, // input buffer length
  959. &Timeouts, // output buffer
  960. sizeof(SERIAL_TIMEOUTS), // output buffer length
  961. FALSE, // calls IRP_MJ_DEVICE_CONTROL
  962. // rather than IRP_MJ_INTERNAL_DEVICE_CONTROL
  963. &eventComplete, // event to wait for completion
  964. &ioStatusBlock // io status block to be set
  965. );
  966. if (pIrp == NULL)
  967. {
  968. DEBUGMSG(DBG_OUT, (" IoBuildDeviceIoControlRequest() failed.\n"));
  969. status = STATUS_INSUFFICIENT_RESOURCES;
  970. goto done;
  971. }
  972. status = IoCallDriver(pSerialDevObj, pIrp);
  973. //
  974. // if IoCallDriver returns STATUS_PENDING, we need to wait for the event
  975. //
  976. if (status == STATUS_PENDING)
  977. {
  978. KeWaitForSingleObject(
  979. &eventComplete, // object to wait for
  980. Executive, // reason to wait
  981. KernelMode, // processor mode
  982. FALSE, // alertable
  983. NULL // timeout
  984. );
  985. //
  986. // we can get the status of the IoCallDriver from the io status
  987. // block
  988. //
  989. status = ioStatusBlock.Status;
  990. }
  991. //
  992. // if IoCallDriver returns something other that STATUS_PENDING, then it
  993. // is the same as what the serial driver set in ioStatusBlock.Status
  994. //
  995. if (status != STATUS_SUCCESS)
  996. {
  997. DEBUGMSG(DBG_OUT, (" IoCallDriver() failed. Returned = 0x%.8x\n", status));
  998. goto done;
  999. }
  1000. ASSERT(sizeof(*pTimeouts) >= sizeof(SERIAL_TIMEOUTS));
  1001. RtlCopyMemory(pTimeouts, &Timeouts, sizeof(SERIAL_TIMEOUTS));
  1002. done:
  1003. DEBUGMSG(DBG_FUNC, ("-SerialGetTimeouts\n"));
  1004. return status;
  1005. }
  1006. #endif
  1007. /*****************************************************************************
  1008. *
  1009. * Function: SerialSetTimeouts
  1010. *
  1011. * Synopsis: Synchronous I/O control request to serial device object.
  1012. *
  1013. * Arguments:
  1014. *
  1015. * Returns: STATUS_SUCCESS
  1016. * STATUS_INSUFFICIENT_RESOURCES
  1017. * STATUS_UNSUCCESSFUL or other failure if IoCallDriver fails
  1018. *
  1019. * Algorithm:
  1020. *
  1021. * History: dd-mm-yyyy Author Comment
  1022. * 9/30/1996 sholden author
  1023. *
  1024. * Notes:
  1025. *
  1026. * This routine must be called from IRQL PASSIVE_LEVEL.
  1027. *
  1028. *****************************************************************************/
  1029. NTSTATUS
  1030. SerialSetTimeouts(
  1031. IN PDEVICE_OBJECT pSerialDevObj,
  1032. IN SERIAL_TIMEOUTS *pTimeouts
  1033. )
  1034. {
  1035. IO_STATUS_BLOCK ioStatusBlock;
  1036. DEBUGMSG(DBG_FUNC, ("+SerialSetTimeouts\n"));
  1037. SendIoctlToSerial(
  1038. pSerialDevObj,
  1039. &ioStatusBlock,
  1040. IOCTL_SERIAL_SET_TIMEOUTS, // io control code
  1041. pTimeouts, // input buffer
  1042. sizeof(SERIAL_TIMEOUTS), // input buffer length
  1043. NULL,
  1044. 0
  1045. );
  1046. DEBUGMSG(DBG_FUNC, ("-SerialSetTimeouts\n"));
  1047. return ioStatusBlock.Status;
  1048. }
  1049. #if 0
  1050. /*****************************************************************************
  1051. *
  1052. * Function: SerialImmediateChar
  1053. *
  1054. * Synopsis: Synchronous I/O control request to serial device object.
  1055. *
  1056. * Arguments:
  1057. *
  1058. * Returns: STATUS_SUCCESS
  1059. * STATUS_INSUFFICIENT_RESOURCES
  1060. * STATUS_UNSUCCESSFUL or other failure if IoCallDriver fails
  1061. *
  1062. * Algorithm:
  1063. *
  1064. * History: dd-mm-yyyy Author Comment
  1065. * 9/30/1996 sholden author
  1066. *
  1067. * Notes:
  1068. *
  1069. * This routine must be called from IRQL PASSIVE_LEVEL.
  1070. *
  1071. *****************************************************************************/
  1072. NTSTATUS
  1073. SerialImmediateChar(
  1074. IN PDEVICE_OBJECT pSerialDevObj,
  1075. IN UCHAR *pImmediateChar
  1076. )
  1077. {
  1078. PIRP pIrp;
  1079. KEVENT eventComplete;
  1080. IO_STATUS_BLOCK ioStatusBlock;
  1081. if (!pSerialDevObj)
  1082. {
  1083. DEBUGMSG(DBG_ERROR, ("IRSIR: SerialDevObj==NULL\n"));
  1084. return STATUS_INVALID_PARAMETER;
  1085. }
  1086. DEBUGMSG(DBG_FUNC, ("+SerialImmediateChar\n"));
  1087. //
  1088. // event to wait for completion of serial driver
  1089. //
  1090. KeInitializeEvent(
  1091. &eventComplete,
  1092. NotificationEvent,
  1093. FALSE
  1094. );
  1095. //
  1096. // build irp to set baud rate and wait for event signalled
  1097. //
  1098. // irp is released by io manager
  1099. //
  1100. pIrp = IoBuildDeviceIoControlRequest(
  1101. IOCTL_SERIAL_IMMEDIATE_CHAR, // io control code
  1102. pSerialDevObj, // device object
  1103. pImmediateChar, // input buffer
  1104. sizeof(UCHAR), // input buffer length
  1105. NULL, // output buffer
  1106. 0, // output buffer length
  1107. FALSE, // calls IRP_MJ_DEVICE_CONTROL
  1108. // rather than IRP_MJ_INTERNAL_DEVICE_CONTROL
  1109. &eventComplete, // event to wait for completion
  1110. &ioStatusBlock // io status block to be set
  1111. );
  1112. if (pIrp == NULL)
  1113. {
  1114. DEBUGMSG(DBG_OUT, (" IoBuildDeviceIoControlRequest() failed.\n"));
  1115. status = STATUS_INSUFFICIENT_RESOURCES;
  1116. goto done;
  1117. }
  1118. status = IoCallDriver(pSerialDevObj, pIrp);
  1119. //
  1120. // if IoCallDriver returns STATUS_PENDING, we need to wait for the event
  1121. //
  1122. if (status == STATUS_PENDING)
  1123. {
  1124. KeWaitForSingleObject(
  1125. &eventComplete, // object to wait for
  1126. Executive, // reason to wait
  1127. KernelMode, // processor mode
  1128. FALSE, // alertable
  1129. NULL // timeout
  1130. );
  1131. //
  1132. // we can get the status of the IoCallDriver from the io status
  1133. // block
  1134. //
  1135. status = ioStatusBlock.Status;
  1136. }
  1137. //
  1138. // if IoCallDriver returns something other that STATUS_PENDING, then it
  1139. // is the same as what the serial driver set in ioStatusBlock.Status
  1140. //
  1141. if (status != STATUS_SUCCESS)
  1142. {
  1143. DEBUGMSG(DBG_OUT, (" IoCallDriver() failed. Returned = 0x%.8x\n", status));
  1144. goto done;
  1145. }
  1146. done:
  1147. DEBUGMSG(DBG_FUNC, ("-SerialImmediateChar\n"));
  1148. return status;
  1149. }
  1150. /*****************************************************************************
  1151. *
  1152. * Function: SerialXoffCounter
  1153. *
  1154. * Synopsis: Synchronous I/O control request to serial device object.
  1155. *
  1156. * Arguments:
  1157. *
  1158. * Returns: STATUS_SUCCESS
  1159. * STATUS_INSUFFICIENT_RESOURCES
  1160. * STATUS_UNSUCCESSFUL or other failure if IoCallDriver fails
  1161. *
  1162. * Algorithm:
  1163. *
  1164. * History: dd-mm-yyyy Author Comment
  1165. * 9/30/1996 sholden author
  1166. *
  1167. * Notes:
  1168. *
  1169. * This routine must be called from IRQL PASSIVE_LEVEL.
  1170. *
  1171. *****************************************************************************/
  1172. NTSTATUS
  1173. SerialXoffCounter(
  1174. IN PDEVICE_OBJECT pSerialDevObj,
  1175. IN PSERIAL_XOFF_COUNTER pXoffCounter
  1176. )
  1177. {
  1178. PIRP pIrp;
  1179. KEVENT eventComplete;
  1180. IO_STATUS_BLOCK ioStatusBlock;
  1181. NTSTATUS status;
  1182. if (!pSerialDevObj)
  1183. {
  1184. DEBUGMSG(DBG_ERROR, ("IRSIR: SerialDevObj==NULL\n"));
  1185. return STATUS_INVALID_PARAMETER;
  1186. }
  1187. DEBUGMSG(DBG_FUNC, ("+SerialXoffCounter\n"));
  1188. //
  1189. // event to wait for completion of serial driver
  1190. //
  1191. KeInitializeEvent(
  1192. &eventComplete,
  1193. NotificationEvent,
  1194. FALSE
  1195. );
  1196. //
  1197. // build irp to set baud rate and wait for event signalled
  1198. //
  1199. // irp is released by io manager
  1200. //
  1201. pIrp = IoBuildDeviceIoControlRequest(
  1202. IOCTL_SERIAL_XOFF_COUNTER, // io control code
  1203. pSerialDevObj, // device object
  1204. pXoffCounter, // input buffer
  1205. sizeof(SERIAL_XOFF_COUNTER), // input buffer length
  1206. NULL, // output buffer
  1207. 0, // output buffer length
  1208. FALSE, // calls IRP_MJ_DEVICE_CONTROL
  1209. // rather than IRP_MJ_INTERNAL_DEVICE_CONTROL
  1210. &eventComplete, // event to wait for completion
  1211. &ioStatusBlock // io status block to be set
  1212. );
  1213. if (pIrp == NULL)
  1214. {
  1215. DEBUGMSG(DBG_OUT, (" IoBuildDeviceIoControlRequest() failed.\n"));
  1216. status = STATUS_INSUFFICIENT_RESOURCES;
  1217. goto done;
  1218. }
  1219. status = IoCallDriver(pSerialDevObj, pIrp);
  1220. //
  1221. // if IoCallDriver returns STATUS_PENDING, we need to wait for the event
  1222. //
  1223. if (status == STATUS_PENDING)
  1224. {
  1225. KeWaitForSingleObject(
  1226. &eventComplete, // object to wait for
  1227. Executive, // reason to wait
  1228. KernelMode, // processor mode
  1229. FALSE, // alertable
  1230. NULL // timeout
  1231. );
  1232. //
  1233. // we can get the status of the IoCallDriver from the io status
  1234. // block
  1235. //
  1236. status = ioStatusBlock.Status;
  1237. }
  1238. //
  1239. // if IoCallDriver returns something other that STATUS_PENDING, then it
  1240. // is the same as what the serial driver set in ioStatusBlock.Status
  1241. //
  1242. if (status != STATUS_SUCCESS)
  1243. {
  1244. DEBUGMSG(DBG_OUT, (" IoCallDriver() failed. Returned = 0x%.8x\n", status));
  1245. goto done;
  1246. }
  1247. done:
  1248. DEBUGMSG(DBG_FUNC, ("-SerialXoffCounter\n"));
  1249. return status;
  1250. }
  1251. #endif
  1252. /*****************************************************************************
  1253. *
  1254. * Function: SerialSetDTR
  1255. *
  1256. * Synopsis: Synchronous I/O control request to serial device object.
  1257. *
  1258. * Arguments:
  1259. *
  1260. * Returns: STATUS_SUCCESS
  1261. * STATUS_INSUFFICIENT_RESOURCES
  1262. * STATUS_UNSUCCESSFUL or other failure if IoCallDriver fails
  1263. *
  1264. * Algorithm:
  1265. *
  1266. * History: dd-mm-yyyy Author Comment
  1267. * 9/30/1996 sholden author
  1268. *
  1269. * Notes:
  1270. *
  1271. * This routine must be called from IRQL PASSIVE_LEVEL.
  1272. *
  1273. *****************************************************************************/
  1274. NTSTATUS
  1275. SerialSetDTR(
  1276. IN PDEVICE_OBJECT pSerialDevObj
  1277. )
  1278. {
  1279. IO_STATUS_BLOCK ioStatusBlock;
  1280. DEBUGMSG(DBG_FUNC, ("+SerialSetDTR\n"));
  1281. SendIoctlToSerial(
  1282. pSerialDevObj,
  1283. &ioStatusBlock,
  1284. IOCTL_SERIAL_SET_DTR, // io control code
  1285. NULL,
  1286. 0,
  1287. NULL,
  1288. 0
  1289. );
  1290. DEBUGMSG(DBG_FUNC, ("-SerialSetDTR\n"));
  1291. return ioStatusBlock.Status;
  1292. }
  1293. /*****************************************************************************
  1294. *
  1295. * Function: SerialClrDTR
  1296. *
  1297. * Synopsis: Synchronous I/O control request to serial device object.
  1298. *
  1299. * Arguments:
  1300. *
  1301. * Returns: STATUS_SUCCESS
  1302. * STATUS_INSUFFICIENT_RESOURCES
  1303. * STATUS_UNSUCCESSFUL or other failure if IoCallDriver fails
  1304. *
  1305. * Algorithm:
  1306. *
  1307. * History: dd-mm-yyyy Author Comment
  1308. * 9/30/1996 sholden author
  1309. *
  1310. * Notes:
  1311. *
  1312. * This routine must be called from IRQL PASSIVE_LEVEL.
  1313. *
  1314. *****************************************************************************/
  1315. NTSTATUS
  1316. SerialClrDTR(
  1317. IN PDEVICE_OBJECT pSerialDevObj
  1318. )
  1319. {
  1320. IO_STATUS_BLOCK ioStatusBlock;
  1321. DEBUGMSG(DBG_FUNC, ("+SerialClrDTR\n"));
  1322. SendIoctlToSerial(
  1323. pSerialDevObj,
  1324. &ioStatusBlock,
  1325. IOCTL_SERIAL_CLR_DTR, // io control code
  1326. NULL,
  1327. 0,
  1328. NULL,
  1329. 0
  1330. );
  1331. DEBUGMSG(DBG_FUNC, ("-SerialClrDTR\n"));
  1332. return ioStatusBlock.Status;
  1333. }
  1334. /*****************************************************************************
  1335. *
  1336. * Function: SerialSetRTS
  1337. *
  1338. * Synopsis: Synchronous I/O control request to serial device object.
  1339. *
  1340. * Arguments:
  1341. *
  1342. * Returns: STATUS_SUCCESS
  1343. * STATUS_INSUFFICIENT_RESOURCES
  1344. * STATUS_UNSUCCESSFUL or other failure if IoCallDriver fails
  1345. *
  1346. * Algorithm:
  1347. *
  1348. * History: dd-mm-yyyy Author Comment
  1349. * 9/30/1996 sholden author
  1350. *
  1351. * Notes:
  1352. *
  1353. * This routine must be called from IRQL PASSIVE_LEVEL.
  1354. *
  1355. *****************************************************************************/
  1356. NTSTATUS
  1357. SerialSetRTS(
  1358. IN PDEVICE_OBJECT pSerialDevObj
  1359. )
  1360. {
  1361. IO_STATUS_BLOCK ioStatusBlock;
  1362. DEBUGMSG(DBG_FUNC, ("+SerialSetRTS\n"));
  1363. SendIoctlToSerial(
  1364. pSerialDevObj,
  1365. &ioStatusBlock,
  1366. IOCTL_SERIAL_SET_RTS, // io control code
  1367. NULL,
  1368. 0,
  1369. NULL,
  1370. 0
  1371. );
  1372. DEBUGMSG(DBG_FUNC, ("-SerialSetRTS\n"));
  1373. return ioStatusBlock.Status;
  1374. }
  1375. /*****************************************************************************
  1376. *
  1377. * Function: SerialClrRTS
  1378. *
  1379. * Synopsis: Synchronous I/O control request to serial device object.
  1380. *
  1381. * Arguments:
  1382. *
  1383. * Returns: STATUS_SUCCESS
  1384. * STATUS_INSUFFICIENT_RESOURCES
  1385. * STATUS_UNSUCCESSFUL or other failure if IoCallDriver fails
  1386. *
  1387. * Algorithm:
  1388. *
  1389. * History: dd-mm-yyyy Author Comment
  1390. * 9/30/1996 sholden author
  1391. *
  1392. * Notes:
  1393. *
  1394. * This routine must be called from IRQL PASSIVE_LEVEL.
  1395. *
  1396. *****************************************************************************/
  1397. NTSTATUS
  1398. SerialClrRTS(
  1399. IN PDEVICE_OBJECT pSerialDevObj
  1400. )
  1401. {
  1402. IO_STATUS_BLOCK ioStatusBlock;
  1403. DEBUGMSG(DBG_FUNC, ("+SerialClrRTS\n"));
  1404. SendIoctlToSerial(
  1405. pSerialDevObj,
  1406. &ioStatusBlock,
  1407. IOCTL_SERIAL_CLR_RTS, // io control code
  1408. NULL,
  1409. 0,
  1410. NULL,
  1411. 0
  1412. );
  1413. DEBUGMSG(DBG_FUNC, ("-SerialClrRTS\n"));
  1414. return ioStatusBlock.Status;
  1415. }
  1416. #if 0
  1417. /*****************************************************************************
  1418. *
  1419. * Function: SerialGetDtrRts
  1420. *
  1421. * Synopsis: Synchronous I/O control request to serial device object.
  1422. *
  1423. * Arguments:
  1424. *
  1425. * Returns: STATUS_SUCCESS
  1426. * STATUS_INSUFFICIENT_RESOURCES
  1427. * STATUS_UNSUCCESSFUL or other failure if IoCallDriver fails
  1428. *
  1429. * Algorithm:
  1430. *
  1431. * History: dd-mm-yyyy Author Comment
  1432. * 9/30/1996 sholden author
  1433. *
  1434. * Notes:
  1435. *
  1436. * This routine must be called from IRQL PASSIVE_LEVEL.
  1437. *
  1438. *****************************************************************************/
  1439. NTSTATUS
  1440. SerialGetDtrRts(
  1441. IN PDEVICE_OBJECT pSerialDevObj,
  1442. OUT ULONG *pDtrRts
  1443. )
  1444. {
  1445. PIRP pIrp;
  1446. ULONG DtrRts;
  1447. KEVENT eventComplete;
  1448. IO_STATUS_BLOCK ioStatusBlock;
  1449. NTSTATUS status;
  1450. if (!pSerialDevObj)
  1451. {
  1452. DEBUGMSG(DBG_ERROR, ("IRSIR: SerialDevObj==NULL\n"));
  1453. return STATUS_INVALID_PARAMETER;
  1454. }
  1455. DEBUGMSG(DBG_FUNC, ("+SerialGetDtrRts\n"));
  1456. //
  1457. // event to wait for completion of serial driver
  1458. //
  1459. KeInitializeEvent(
  1460. &eventComplete,
  1461. NotificationEvent,
  1462. FALSE
  1463. );
  1464. //
  1465. // build irp to get baud rate and wait for event signalled
  1466. //
  1467. // irp is released by io manager
  1468. //
  1469. pIrp = IoBuildDeviceIoControlRequest(
  1470. IOCTL_SERIAL_GET_DTRRTS, // io control code
  1471. pSerialDevObj, // device object
  1472. NULL, // input buffer
  1473. 0, // input buffer length
  1474. &DtrRts, // output buffer
  1475. sizeof(ULONG), // output buffer length
  1476. FALSE, // calls IRP_MJ_DEVICE_CONTROL
  1477. // rather than IRP_MJ_INTERNAL_DEVICE_CONTROL
  1478. &eventComplete, // event to wait for completion
  1479. &ioStatusBlock // io status block to be set
  1480. );
  1481. if (pIrp == NULL)
  1482. {
  1483. DEBUGMSG(DBG_OUT, (" IoBuildDeviceIoControlRequest() failed.\n"));
  1484. status = STATUS_INSUFFICIENT_RESOURCES;
  1485. goto done;
  1486. }
  1487. status = IoCallDriver(pSerialDevObj, pIrp);
  1488. //
  1489. // if IoCallDriver returns STATUS_PENDING, we need to wait for the event
  1490. //
  1491. if (status == STATUS_PENDING)
  1492. {
  1493. KeWaitForSingleObject(
  1494. &eventComplete, // object to wait for
  1495. Executive, // reason to wait
  1496. KernelMode, // processor mode
  1497. FALSE, // alertable
  1498. NULL // timeout
  1499. );
  1500. //
  1501. // we can get the status of the IoCallDriver from the io status
  1502. // block
  1503. //
  1504. status = ioStatusBlock.Status;
  1505. }
  1506. //
  1507. // if IoCallDriver returns something other that STATUS_PENDING, then it
  1508. // is the same as what the serial driver set in ioStatusBlock.Status
  1509. //
  1510. if (status != STATUS_SUCCESS)
  1511. {
  1512. DEBUGMSG(DBG_OUT, (" IoCallDriver() failed. Returned = 0x%.8x\n", status));
  1513. goto done;
  1514. }
  1515. ASSERT(sizeof(*pDtrRts) >= sizeof(ULONG));
  1516. RtlCopyMemory(pDtrRts, &DtrRts, sizeof(ULONG));
  1517. done:
  1518. DEBUGMSG(DBG_FUNC, ("-SerialGetDtrRts\n"));
  1519. return status;
  1520. }
  1521. #endif
  1522. #if 0
  1523. /*****************************************************************************
  1524. *
  1525. * Function: SerialSetXon
  1526. *
  1527. * Synopsis: Synchronous I/O control request to serial device object.
  1528. *
  1529. * Arguments:
  1530. *
  1531. * Returns: STATUS_SUCCESS
  1532. * STATUS_INSUFFICIENT_RESOURCES
  1533. * STATUS_UNSUCCESSFUL or other failure if IoCallDriver fails
  1534. *
  1535. * Algorithm:
  1536. *
  1537. * History: dd-mm-yyyy Author Comment
  1538. * 9/30/1996 sholden author
  1539. *
  1540. * Notes:
  1541. *
  1542. * This routine must be called from IRQL PASSIVE_LEVEL.
  1543. *
  1544. *****************************************************************************/
  1545. NTSTATUS
  1546. SerialSetXon(
  1547. IN PDEVICE_OBJECT pSerialDevObj
  1548. )
  1549. {
  1550. PIRP pIrp;
  1551. KEVENT eventComplete;
  1552. IO_STATUS_BLOCK ioStatusBlock;
  1553. NTSTATUS status;
  1554. if (!pSerialDevObj)
  1555. {
  1556. DEBUGMSG(DBG_ERROR, ("IRSIR: SerialDevObj==NULL\n"));
  1557. return STATUS_INVALID_PARAMETER;
  1558. }
  1559. DEBUGMSG(DBG_FUNC, ("+SerialSetXon\n"));
  1560. //
  1561. // event to wait for completion of serial driver
  1562. //
  1563. KeInitializeEvent(
  1564. &eventComplete,
  1565. NotificationEvent,
  1566. FALSE
  1567. );
  1568. //
  1569. // build irp to set Xon and wait for event signalled
  1570. //
  1571. // irp is released by io manager
  1572. //
  1573. pIrp = IoBuildDeviceIoControlRequest(
  1574. IOCTL_SERIAL_SET_XON, // io control code
  1575. pSerialDevObj, // device object
  1576. NULL, // input buffer
  1577. 0, // input buffer length
  1578. NULL, // output buffer
  1579. 0, // output buffer length
  1580. FALSE, // calls IRP_MJ_DEVICE_CONTROL
  1581. // rather than IRP_MJ_INTERNAL_DEVICE_CONTROL
  1582. &eventComplete, // event to wait for completion
  1583. &ioStatusBlock // io status block to be set
  1584. );
  1585. if (pIrp == NULL)
  1586. {
  1587. DEBUGMSG(DBG_OUT, (" IoBuildDeviceIoControlRequest() failed.\n"));
  1588. status = STATUS_INSUFFICIENT_RESOURCES;
  1589. goto done;
  1590. }
  1591. status = IoCallDriver(pSerialDevObj, pIrp);
  1592. //
  1593. // if IoCallDriver returns STATUS_PENDING, we need to wait for the event
  1594. //
  1595. if (status == STATUS_PENDING)
  1596. {
  1597. KeWaitForSingleObject(
  1598. &eventComplete, // object to wait for
  1599. Executive, // reason to wait
  1600. KernelMode, // processor mode
  1601. FALSE, // alertable
  1602. NULL // timeout
  1603. );
  1604. //
  1605. // we can get the status of the IoCallDriver from the io status
  1606. // block
  1607. //
  1608. status = ioStatusBlock.Status;
  1609. }
  1610. //
  1611. // if IoCallDriver returns something other that STATUS_PENDING, then it
  1612. // is the same as what the serial driver set in ioStatusBlock.Status
  1613. //
  1614. if (status != STATUS_SUCCESS)
  1615. {
  1616. DEBUGMSG(DBG_OUT, (" IoCallDriver() failed. Returned = 0x%.8x\n", status));
  1617. goto done;
  1618. }
  1619. done:
  1620. DEBUGMSG(DBG_FUNC, ("-SerialSetXon\n"));
  1621. return status;
  1622. }
  1623. /*****************************************************************************
  1624. *
  1625. * Function: SerialSetXoff
  1626. *
  1627. * Synopsis: Synchronous I/O control request to serial device object.
  1628. *
  1629. * Arguments:
  1630. *
  1631. * Returns: STATUS_SUCCESS
  1632. * STATUS_INSUFFICIENT_RESOURCES
  1633. * STATUS_UNSUCCESSFUL or other failure if IoCallDriver fails
  1634. *
  1635. * Algorithm:
  1636. *
  1637. * History: dd-mm-yyyy Author Comment
  1638. * 9/30/1996 sholden author
  1639. *
  1640. * Notes:
  1641. *
  1642. * This routine must be called from IRQL PASSIVE_LEVEL.
  1643. *
  1644. *****************************************************************************/
  1645. NTSTATUS
  1646. SerialSetXoff(
  1647. IN PDEVICE_OBJECT pSerialDevObj
  1648. )
  1649. {
  1650. PIRP pIrp;
  1651. KEVENT eventComplete;
  1652. IO_STATUS_BLOCK ioStatusBlock;
  1653. NTSTATUS status;
  1654. if (!pSerialDevObj)
  1655. {
  1656. DEBUGMSG(DBG_ERROR, ("IRSIR: SerialDevObj==NULL\n"));
  1657. return STATUS_INVALID_PARAMETER;
  1658. }
  1659. DEBUGMSG(DBG_FUNC, ("+SerialSetXoff\n"));
  1660. //
  1661. // event to wait for completion of serial driver
  1662. //
  1663. KeInitializeEvent(
  1664. &eventComplete,
  1665. NotificationEvent,
  1666. FALSE
  1667. );
  1668. //
  1669. // build irp to set Xoff and wait for event signalled
  1670. //
  1671. // irp is released by io manager
  1672. //
  1673. pIrp = IoBuildDeviceIoControlRequest(
  1674. IOCTL_SERIAL_SET_XON, // io control code
  1675. pSerialDevObj, // device object
  1676. NULL, // input buffer
  1677. 0, // input buffer length
  1678. NULL, // output buffer
  1679. 0, // output buffer length
  1680. FALSE, // calls IRP_MJ_DEVICE_CONTROL
  1681. // rather than IRP_MJ_INTERNAL_DEVICE_CONTROL
  1682. &eventComplete, // event to wait for completion
  1683. &ioStatusBlock // io status block to be set
  1684. );
  1685. if (pIrp == NULL)
  1686. {
  1687. DEBUGMSG(DBG_OUT, (" IoBuildDeviceIoControlRequest() failed.\n"));
  1688. status = STATUS_INSUFFICIENT_RESOURCES;
  1689. goto done;
  1690. }
  1691. status = IoCallDriver(pSerialDevObj, pIrp);
  1692. //
  1693. // if IoCallDriver returns STATUS_PENDING, we need to wait for the event
  1694. //
  1695. if (status == STATUS_PENDING)
  1696. {
  1697. KeWaitForSingleObject(
  1698. &eventComplete, // object to wait for
  1699. Executive, // reason to wait
  1700. KernelMode, // processor mode
  1701. FALSE, // alertable
  1702. NULL // timeout
  1703. );
  1704. //
  1705. // we can get the status of the IoCallDriver from the io status
  1706. // block
  1707. //
  1708. status = ioStatusBlock.Status;
  1709. }
  1710. //
  1711. // if IoCallDriver returns something other that STATUS_PENDING, then it
  1712. // is the same as what the serial driver set in ioStatusBlock.Status
  1713. //
  1714. if (status != STATUS_SUCCESS)
  1715. {
  1716. DEBUGMSG(DBG_OUT, (" IoCallDriver() failed. Returned = 0x%.8x\n", status));
  1717. goto done;
  1718. }
  1719. done:
  1720. DEBUGMSG(DBG_FUNC, ("-SerialSetXoff\n"));
  1721. return status;
  1722. }
  1723. #endif
  1724. #if 0
  1725. /*****************************************************************************
  1726. *
  1727. * Function: SerialGetWaitMask
  1728. *
  1729. * Synopsis: Synchronous I/O control request to serial device object.
  1730. *
  1731. * Arguments:
  1732. *
  1733. * Returns: STATUS_SUCCESS
  1734. * STATUS_INSUFFICIENT_RESOURCES
  1735. * STATUS_UNSUCCESSFUL or other failure if IoCallDriver fails
  1736. *
  1737. * Algorithm:
  1738. *
  1739. * History: dd-mm-yyyy Author Comment
  1740. * 9/30/1996 sholden author
  1741. *
  1742. * Notes:
  1743. *
  1744. * This routine must be called from IRQL PASSIVE_LEVEL.
  1745. *
  1746. *****************************************************************************/
  1747. NTSTATUS
  1748. SerialGetWaitMask(
  1749. IN PDEVICE_OBJECT pSerialDevObj,
  1750. OUT ULONG *pWaitMask
  1751. )
  1752. {
  1753. PIRP pIrp;
  1754. ULONG WaitMask;
  1755. KEVENT eventComplete;
  1756. IO_STATUS_BLOCK ioStatusBlock;
  1757. NTSTATUS status;
  1758. if (!pSerialDevObj)
  1759. {
  1760. DEBUGMSG(DBG_ERROR, ("IRSIR: SerialDevObj==NULL\n"));
  1761. return STATUS_INVALID_PARAMETER;
  1762. }
  1763. DEBUGMSG(DBG_FUNC, ("+SerialGetWaitMask\n"));
  1764. //
  1765. // event to wait for completion of serial driver
  1766. //
  1767. KeInitializeEvent(
  1768. &eventComplete,
  1769. NotificationEvent,
  1770. FALSE
  1771. );
  1772. //
  1773. // build irp to get baud rate and wait for event signalled
  1774. //
  1775. // irp is released by io manager
  1776. //
  1777. pIrp = IoBuildDeviceIoControlRequest(
  1778. IOCTL_SERIAL_GET_WAIT_MASK, // io control code
  1779. pSerialDevObj, // device object
  1780. NULL, // input buffer
  1781. 0, // input buffer length
  1782. &WaitMask, // output buffer
  1783. sizeof(ULONG), // output buffer length
  1784. FALSE, // calls IRP_MJ_DEVICE_CONTROL
  1785. // rather than IRP_MJ_INTERNAL_DEVICE_CONTROL
  1786. &eventComplete, // event to wait for completion
  1787. &ioStatusBlock // io status block to be set
  1788. );
  1789. if (pIrp == NULL)
  1790. {
  1791. DEBUGMSG(DBG_OUT, (" IoBuildDeviceIoControlRequest() failed.\n"));
  1792. status = STATUS_INSUFFICIENT_RESOURCES;
  1793. goto done;
  1794. }
  1795. status = IoCallDriver(pSerialDevObj, pIrp);
  1796. //
  1797. // if IoCallDriver returns STATUS_PENDING, we need to wait for the event
  1798. //
  1799. if (status == STATUS_PENDING)
  1800. {
  1801. KeWaitForSingleObject(
  1802. &eventComplete, // object to wait for
  1803. Executive, // reason to wait
  1804. KernelMode, // processor mode
  1805. FALSE, // alertable
  1806. NULL // timeout
  1807. );
  1808. //
  1809. // we can get the status of the IoCallDriver from the io status
  1810. // block
  1811. //
  1812. status = ioStatusBlock.Status;
  1813. }
  1814. //
  1815. // if IoCallDriver returns something other that STATUS_PENDING, then it
  1816. // is the same as what the serial driver set in ioStatusBlock.Status
  1817. //
  1818. if (status != STATUS_SUCCESS)
  1819. {
  1820. DEBUGMSG(DBG_OUT, (" IoCallDriver() failed. Returned = 0x%.8x\n", status));
  1821. goto done;
  1822. }
  1823. ASSERT(sizeof(*pWaitMask) >= sizeof(ULONG));
  1824. RtlCopyMemory(pWaitMask, &WaitMask, sizeof(ULONG));
  1825. done:
  1826. DEBUGMSG(DBG_FUNC, ("-SerialGetWaitMask\n"));
  1827. return status;
  1828. }
  1829. #endif
  1830. /*****************************************************************************
  1831. *
  1832. * Function: SerialSetWaitMask
  1833. *
  1834. * Synopsis: Synchronous I/O control request to serial device object.
  1835. *
  1836. * Arguments:
  1837. *
  1838. * Returns: STATUS_SUCCESS
  1839. * STATUS_INSUFFICIENT_RESOURCES
  1840. * STATUS_UNSUCCESSFUL or other failure if IoCallDriver fails
  1841. *
  1842. * Algorithm:
  1843. *
  1844. * History: dd-mm-yyyy Author Comment
  1845. * 9/30/1996 sholden author
  1846. *
  1847. * Notes:
  1848. *
  1849. * This routine must be called from IRQL PASSIVE_LEVEL.
  1850. *
  1851. *****************************************************************************/
  1852. NTSTATUS
  1853. SerialSetWaitMask(
  1854. IN PDEVICE_OBJECT pSerialDevObj,
  1855. IN ULONG *pWaitMask
  1856. )
  1857. {
  1858. IO_STATUS_BLOCK ioStatusBlock;
  1859. DEBUGMSG(DBG_FUNC, ("+SerialSetWaitMask\n"));
  1860. SendIoctlToSerial(
  1861. pSerialDevObj,
  1862. &ioStatusBlock,
  1863. IOCTL_SERIAL_SET_WAIT_MASK, // io control code
  1864. pWaitMask, // input buffer
  1865. sizeof(ULONG), // input buffer length
  1866. NULL,
  1867. 0
  1868. );
  1869. DEBUGMSG(DBG_FUNC, ("-SerialSetWaitMask\n"));
  1870. return ioStatusBlock.Status;
  1871. }
  1872. #if 0
  1873. /*****************************************************************************
  1874. *
  1875. * Function: SerialWaitOnMask
  1876. *
  1877. * Synopsis: Synchronous I/O control request to serial device object.
  1878. *
  1879. * Arguments:
  1880. *
  1881. * Returns: STATUS_SUCCESS
  1882. * STATUS_INSUFFICIENT_RESOURCES
  1883. * STATUS_UNSUCCESSFUL or other failure if IoCallDriver fails
  1884. *
  1885. * Algorithm:
  1886. *
  1887. * History: dd-mm-yyyy Author Comment
  1888. * 9/30/1996 sholden author
  1889. *
  1890. * Notes:
  1891. *
  1892. * This routine must be called from IRQL PASSIVE_LEVEL.
  1893. *
  1894. *****************************************************************************/
  1895. NTSTATUS
  1896. SerialWaitOnMask(
  1897. IN PDEVICE_OBJECT pSerialDevObj,
  1898. OUT ULONG *pWaitOnMask
  1899. )
  1900. {
  1901. PIRP pIrp;
  1902. ULONG WaitOnMask;
  1903. KEVENT eventComplete;
  1904. IO_STATUS_BLOCK ioStatusBlock;
  1905. NTSTATUS status;
  1906. if (!pSerialDevObj)
  1907. {
  1908. DEBUGMSG(DBG_ERROR, ("IRSIR: SerialDevObj==NULL\n"));
  1909. return STATUS_INVALID_PARAMETER;
  1910. }
  1911. DEBUGMSG(DBG_FUNC, ("+SerialWaitOnMask\n"));
  1912. //
  1913. // event to wait for completion of serial driver
  1914. //
  1915. KeInitializeEvent(
  1916. &eventComplete,
  1917. NotificationEvent,
  1918. FALSE
  1919. );
  1920. //
  1921. // build irp to get baud rate and wait for event signalled
  1922. //
  1923. // irp is released by io manager
  1924. //
  1925. pIrp = IoBuildDeviceIoControlRequest(
  1926. IOCTL_SERIAL_WAIT_ON_MASK, // io control code
  1927. pSerialDevObj, // device object
  1928. NULL, // input buffer
  1929. 0, // input buffer length
  1930. &WaitOnMask, // output buffer
  1931. sizeof(ULONG), // output buffer length
  1932. FALSE, // calls IRP_MJ_DEVICE_CONTROL
  1933. // rather than IRP_MJ_INTERNAL_DEVICE_CONTROL
  1934. &eventComplete, // event to wait for completion
  1935. &ioStatusBlock // io status block to be set
  1936. );
  1937. if (pIrp == NULL)
  1938. {
  1939. DEBUGMSG(DBG_OUT, (" IoBuildDeviceIoControlRequest() failed.\n"));
  1940. status = STATUS_INSUFFICIENT_RESOURCES;
  1941. goto done;
  1942. }
  1943. status = IoCallDriver(pSerialDevObj, pIrp);
  1944. //
  1945. // if IoCallDriver returns STATUS_PENDING, we need to wait for the event
  1946. //
  1947. if (status == STATUS_PENDING)
  1948. {
  1949. KeWaitForSingleObject(
  1950. &eventComplete, // object to wait for
  1951. Executive, // reason to wait
  1952. KernelMode, // processor mode
  1953. FALSE, // alertable
  1954. NULL // timeout
  1955. );
  1956. //
  1957. // we can get the status of the IoCallDriver from the io status
  1958. // block
  1959. //
  1960. status = ioStatusBlock.Status;
  1961. }
  1962. //
  1963. // if IoCallDriver returns something other that STATUS_PENDING, then it
  1964. // is the same as what the serial driver set in ioStatusBlock.Status
  1965. //
  1966. if (status != STATUS_SUCCESS)
  1967. {
  1968. DEBUGMSG(DBG_OUT, (" IoCallDriver() failed. Returned = 0x%.8x\n", status));
  1969. goto done;
  1970. }
  1971. *pWaitOnMask = WaitOnMask;
  1972. done:
  1973. DEBUGMSG(DBG_FUNC, ("-SerialWaitOnMask\n"));
  1974. return status;
  1975. }
  1976. #endif
  1977. /*****************************************************************************
  1978. *
  1979. * Function: SerialCallbackOnMask
  1980. *
  1981. * Synopsis: Asynchronous I/O control request to serial device object.
  1982. *
  1983. * Arguments:
  1984. *
  1985. * Returns: STATUS_SUCCESS
  1986. * STATUS_INSUFFICIENT_RESOURCES
  1987. * STATUS_UNSUCCESSFUL or other failure if IoCallDriver fails
  1988. *
  1989. * Algorithm:
  1990. *
  1991. * History: dd-mm-yyyy Author Comment
  1992. * 10-03-1998 stana author
  1993. *
  1994. * Notes:
  1995. *
  1996. * This routine must be called from IRQL PASSIVE_LEVEL.
  1997. *
  1998. *****************************************************************************/
  1999. NTSTATUS
  2000. SerialCallbackOnMask(
  2001. IN PDEVICE_OBJECT pSerialDevObj,
  2002. IN PIO_COMPLETION_ROUTINE pRoutine,
  2003. IN PIO_STATUS_BLOCK pIosb,
  2004. IN PVOID Context,
  2005. OUT PULONG pResult
  2006. )
  2007. {
  2008. PIRP pIrp;
  2009. NTSTATUS status;
  2010. if (!pSerialDevObj)
  2011. {
  2012. DEBUGMSG(DBG_ERROR, ("IRSIR: SerialDevObj==NULL\n"));
  2013. return STATUS_INVALID_PARAMETER;
  2014. }
  2015. DEBUGMSG(DBG_FUNC, ("+SerialCallbackOnMask\n"));
  2016. NdisZeroMemory(pIosb, sizeof(IO_STATUS_BLOCK));
  2017. //
  2018. // build irp to get baud rate and wait for event signalled
  2019. //
  2020. // irp is released by io manager
  2021. //
  2022. pIrp = IoBuildDeviceIoControlRequest(
  2023. IOCTL_SERIAL_WAIT_ON_MASK, // io control code
  2024. pSerialDevObj, // device object
  2025. NULL, // input buffer
  2026. 0, // input buffer length
  2027. pResult, // output buffer
  2028. sizeof(ULONG), // output buffer length
  2029. FALSE, // calls IRP_MJ_DEVICE_CONTROL
  2030. // rather than IRP_MJ_INTERNAL_DEVICE_CONTROL
  2031. NULL, // event to wait for completion
  2032. pIosb // io status block to be set
  2033. );
  2034. if (pIrp == NULL)
  2035. {
  2036. DEBUGMSG(DBG_OUT, (" IoBuildDeviceIoControlRequest() failed.\n"));
  2037. status = STATUS_INSUFFICIENT_RESOURCES;
  2038. goto done;
  2039. }
  2040. IoSetCompletionRoutine(pIrp, pRoutine, Context, TRUE, TRUE, TRUE);
  2041. LOG_ENTRY('WI', Context, pIrp, 0);
  2042. status = IoCallDriver(pSerialDevObj, pIrp);
  2043. done:
  2044. DEBUGMSG(DBG_FUNC, ("-SerialCallbackOnMask\n"));
  2045. return status;
  2046. }
  2047. #if 0
  2048. /*****************************************************************************
  2049. *
  2050. * Function: SerialGetChars
  2051. *
  2052. * Synopsis: Synchronous I/O control request to serial device object.
  2053. *
  2054. * Arguments:
  2055. *
  2056. * Returns: STATUS_SUCCESS
  2057. * STATUS_INSUFFICIENT_RESOURCES
  2058. * STATUS_UNSUCCESSFUL or other failure if IoCallDriver fails
  2059. *
  2060. * Algorithm:
  2061. *
  2062. * History: dd-mm-yyyy Author Comment
  2063. * 9/30/1996 sholden author
  2064. *
  2065. * Notes:
  2066. *
  2067. * This routine must be called from IRQL PASSIVE_LEVEL.
  2068. *
  2069. *****************************************************************************/
  2070. NTSTATUS
  2071. SerialGetChars(
  2072. IN PDEVICE_OBJECT pSerialDevObj,
  2073. OUT PSERIAL_CHARS pChars
  2074. )
  2075. {
  2076. PIRP pIrp;
  2077. SERIAL_CHARS Chars;
  2078. KEVENT eventComplete;
  2079. IO_STATUS_BLOCK ioStatusBlock;
  2080. NTSTATUS status;
  2081. if (!pSerialDevObj)
  2082. {
  2083. DEBUGMSG(DBG_ERROR, ("IRSIR: SerialDevObj==NULL\n"));
  2084. return STATUS_INVALID_PARAMETER;
  2085. }
  2086. DEBUGMSG(DBG_FUNC, ("+SerialGetChars\n"));
  2087. //
  2088. // event to wait for completion of serial driver
  2089. //
  2090. KeInitializeEvent(
  2091. &eventComplete,
  2092. NotificationEvent,
  2093. FALSE
  2094. );
  2095. //
  2096. // build irp to get baud rate and wait for event signalled
  2097. //
  2098. // irp is released by io manager
  2099. //
  2100. pIrp = IoBuildDeviceIoControlRequest(
  2101. IOCTL_SERIAL_GET_CHARS, // io control code
  2102. pSerialDevObj, // device object
  2103. NULL, // input buffer
  2104. 0, // input buffer length
  2105. &Chars, // output buffer
  2106. sizeof(SERIAL_CHARS), // output buffer length
  2107. FALSE, // calls IRP_MJ_DEVICE_CONTROL
  2108. // rather than IRP_MJ_INTERNAL_DEVICE_CONTROL
  2109. &eventComplete, // event to wait for completion
  2110. &ioStatusBlock // io status block to be set
  2111. );
  2112. if (pIrp == NULL)
  2113. {
  2114. DEBUGMSG(DBG_OUT, (" IoBuildDeviceIoControlRequest() failed.\n"));
  2115. status = STATUS_INSUFFICIENT_RESOURCES;
  2116. goto done;
  2117. }
  2118. status = IoCallDriver(pSerialDevObj, pIrp);
  2119. //
  2120. // if IoCallDriver returns STATUS_PENDING, we need to wait for the event
  2121. //
  2122. if (status == STATUS_PENDING)
  2123. {
  2124. KeWaitForSingleObject(
  2125. &eventComplete, // object to wait for
  2126. Executive, // reason to wait
  2127. KernelMode, // processor mode
  2128. FALSE, // alertable
  2129. NULL // timeout
  2130. );
  2131. //
  2132. // we can get the status of the IoCallDriver from the io status
  2133. // block
  2134. //
  2135. status = ioStatusBlock.Status;
  2136. }
  2137. //
  2138. // if IoCallDriver returns something other that STATUS_PENDING, then it
  2139. // is the same as what the serial driver set in ioStatusBlock.Status
  2140. //
  2141. if (status != STATUS_SUCCESS)
  2142. {
  2143. DEBUGMSG(DBG_OUT, (" IoCallDriver() failed. Returned = 0x%.8x\n", status));
  2144. goto done;
  2145. }
  2146. ASSERT(sizeof(*pChars) >= sizeof(SERIAL_CHARS));
  2147. RtlCopyMemory(pChars, &Chars, sizeof(SERIAL_CHARS));
  2148. done:
  2149. DEBUGMSG(DBG_FUNC, ("-SerialGetChars\n"));
  2150. return status;
  2151. }
  2152. /*****************************************************************************
  2153. *
  2154. * Function: SerialSetChars
  2155. *
  2156. * Synopsis: Synchronous I/O control request to serial device object.
  2157. *
  2158. * Arguments:
  2159. *
  2160. * Returns: STATUS_SUCCESS
  2161. * STATUS_INSUFFICIENT_RESOURCES
  2162. * STATUS_UNSUCCESSFUL or other failure if IoCallDriver fails
  2163. *
  2164. * Algorithm:
  2165. *
  2166. * History: dd-mm-yyyy Author Comment
  2167. * 9/30/1996 sholden author
  2168. *
  2169. * Notes:
  2170. *
  2171. * This routine must be called from IRQL PASSIVE_LEVEL.
  2172. *
  2173. *****************************************************************************/
  2174. NTSTATUS
  2175. SerialSetChars(
  2176. IN PDEVICE_OBJECT pSerialDevObj,
  2177. IN PSERIAL_CHARS pChars
  2178. )
  2179. {
  2180. PIRP pIrp;
  2181. KEVENT eventComplete;
  2182. IO_STATUS_BLOCK ioStatusBlock;
  2183. NTSTATUS status;
  2184. if (!pSerialDevObj)
  2185. {
  2186. DEBUGMSG(DBG_ERROR, ("IRSIR: SerialDevObj==NULL\n"));
  2187. return STATUS_INVALID_PARAMETER;
  2188. }
  2189. DEBUGMSG(DBG_FUNC, ("+SerialSetChars\n"));
  2190. //
  2191. // event to wait for completion of serial driver
  2192. //
  2193. KeInitializeEvent(
  2194. &eventComplete,
  2195. NotificationEvent,
  2196. FALSE
  2197. );
  2198. //
  2199. // build irp to set baud rate and wait for event signalled
  2200. //
  2201. // irp is released by io manager
  2202. //
  2203. pIrp = IoBuildDeviceIoControlRequest(
  2204. IOCTL_SERIAL_SET_CHARS, // io control code
  2205. pSerialDevObj, // device object
  2206. pChars, // input buffer
  2207. sizeof(SERIAL_CHARS), // input buffer length
  2208. NULL, // output buffer
  2209. 0, // output buffer length
  2210. FALSE, // calls IRP_MJ_DEVICE_CONTROL
  2211. // rather than IRP_MJ_INTERNAL_DEVICE_CONTROL
  2212. &eventComplete, // event to wait for completion
  2213. &ioStatusBlock // io status block to be set
  2214. );
  2215. if (pIrp == NULL)
  2216. {
  2217. DEBUGMSG(DBG_OUT, (" IoBuildDeviceIoControlRequest() failed.\n"));
  2218. status = STATUS_INSUFFICIENT_RESOURCES;
  2219. goto done;
  2220. }
  2221. status = IoCallDriver(pSerialDevObj, pIrp);
  2222. //
  2223. // if IoCallDriver returns STATUS_PENDING, we need to wait for the event
  2224. //
  2225. if (status == STATUS_PENDING)
  2226. {
  2227. KeWaitForSingleObject(
  2228. &eventComplete, // object to wait for
  2229. Executive, // reason to wait
  2230. KernelMode, // processor mode
  2231. FALSE, // alertable
  2232. NULL // timeout
  2233. );
  2234. //
  2235. // we can get the status of the IoCallDriver from the io status
  2236. // block
  2237. //
  2238. status = ioStatusBlock.Status;
  2239. }
  2240. //
  2241. // if IoCallDriver returns something other that STATUS_PENDING, then it
  2242. // is the same as what the serial driver set in ioStatusBlock.Status
  2243. //
  2244. if (status != STATUS_SUCCESS)
  2245. {
  2246. DEBUGMSG(DBG_OUT, (" IoCallDriver() failed. Returned = 0x%.8x\n", status));
  2247. goto done;
  2248. }
  2249. done:
  2250. DEBUGMSG(DBG_FUNC, ("-SerialSetChars\n"));
  2251. return status;
  2252. }
  2253. #endif
  2254. NTSTATUS IrpCompleteSetEvent(IN PDEVICE_OBJECT pDevObj,
  2255. IN PIRP pIrp,
  2256. IN PVOID pContext)
  2257. {
  2258. PKEVENT pEvent = pContext;
  2259. DEBUGMSG(DBG_FUNC, ("+IrpCompleteSetEvent\n"));
  2260. KeSetEvent(pEvent, 0, FALSE);
  2261. *pIrp->UserIosb = pIrp->IoStatus;
  2262. IoFreeIrp(pIrp);
  2263. DEBUGMSG(DBG_FUNC, ("-IrpCompleteSetEvent\n"));
  2264. return STATUS_MORE_PROCESSING_REQUIRED;
  2265. }
  2266. NTSTATUS
  2267. SerialFlush(IN PDEVICE_OBJECT pSerialDevObj)
  2268. {
  2269. PIRP Irp;
  2270. PIO_STACK_LOCATION IrpSp;
  2271. NTSTATUS Status;
  2272. KEVENT Event;
  2273. IO_STATUS_BLOCK IOStatus;
  2274. ULONG WaitMask = SERIAL_EV_TXEMPTY;
  2275. if (!pSerialDevObj)
  2276. {
  2277. DEBUGMSG(DBG_ERROR, ("IRSIR: SerialDevObj==NULL\n"));
  2278. return STATUS_INVALID_PARAMETER;
  2279. }
  2280. DEBUGMSG(DBG_FUNC, ("+SerialFlush\n"));
  2281. ASSERT(KeGetCurrentIrql() < DISPATCH_LEVEL);
  2282. KeInitializeEvent( &Event, NotificationEvent, FALSE );
  2283. RtlZeroMemory(&IOStatus, sizeof(IOStatus));
  2284. Irp = SerialBuildReadWriteIrp(pSerialDevObj,
  2285. IRP_MJ_FLUSH_BUFFERS,
  2286. NULL,
  2287. 0,
  2288. &IOStatus);
  2289. if (Irp == NULL)
  2290. {
  2291. Status = STATUS_INSUFFICIENT_RESOURCES;
  2292. goto sfDone;
  2293. }
  2294. IoSetCompletionRoutine(Irp,
  2295. IrpCompleteSetEvent,
  2296. &Event,
  2297. TRUE,
  2298. TRUE,
  2299. TRUE);
  2300. Status = IoCallDriver(pSerialDevObj, Irp);
  2301. if (Status == STATUS_PENDING)
  2302. {
  2303. KeWaitForSingleObject( &Event, Executive, KernelMode, FALSE, NULL );
  2304. }
  2305. Status = IOStatus.Status;
  2306. sfDone:
  2307. #if DBG
  2308. if (Status != STATUS_SUCCESS)
  2309. {
  2310. DEBUGMSG(DBG_ERR, (" SerialFlush() Failed. 0x%08X\n\n", Status));
  2311. }
  2312. #endif
  2313. DEBUGMSG(DBG_FUNC, ("-SerialFlush\n"));
  2314. return Status;
  2315. }
  2316. NTSTATUS
  2317. SerialSynchronousWrite(
  2318. IN PDEVICE_OBJECT pSerialDevObj,
  2319. IN PVOID pBuffer,
  2320. IN ULONG dwLength,
  2321. OUT PULONG pdwBytesWritten)
  2322. {
  2323. PIRP Irp;
  2324. PIO_STACK_LOCATION IrpSp;
  2325. NTSTATUS Status;
  2326. KEVENT Event;
  2327. IO_STATUS_BLOCK IOStatus;
  2328. ULONG WaitMask = SERIAL_EV_TXEMPTY;
  2329. if (!pSerialDevObj)
  2330. {
  2331. DEBUGMSG(DBG_ERROR, ("IRSIR: SerialDevObj==NULL\n"));
  2332. return STATUS_INVALID_PARAMETER;
  2333. }
  2334. DEBUGMSG(DBG_FUNC, ("+SerialSynchronousWrite\n"));
  2335. ASSERT(KeGetCurrentIrql() < DISPATCH_LEVEL);
  2336. //(void)SerialSetWaitMask(pSerialDevObj, &WaitMask);
  2337. KeInitializeEvent( &Event, NotificationEvent, FALSE );
  2338. RtlZeroMemory(&IOStatus, sizeof(IOStatus));
  2339. Irp = SerialBuildReadWriteIrp(pSerialDevObj,
  2340. IRP_MJ_WRITE,
  2341. pBuffer,
  2342. dwLength,
  2343. &IOStatus);
  2344. if (Irp == NULL)
  2345. {
  2346. Status = STATUS_INSUFFICIENT_RESOURCES;
  2347. goto sswDone;
  2348. }
  2349. IoSetCompletionRoutine(Irp,
  2350. IrpCompleteSetEvent,
  2351. &Event,
  2352. TRUE,
  2353. TRUE,
  2354. TRUE);
  2355. Status = IoCallDriver(pSerialDevObj, Irp);
  2356. if (Status == STATUS_PENDING)
  2357. {
  2358. KeWaitForSingleObject( &Event, Executive, KernelMode, FALSE, NULL );
  2359. }
  2360. Status = IOStatus.Status;
  2361. // This truncates if 64 bits. Don't think we'll be reading or writing more than
  2362. // 4.5 GB to a serial port soon.
  2363. *pdwBytesWritten = (ULONG)IOStatus.Information;
  2364. (void)SerialFlush(pSerialDevObj);
  2365. //(void)SerialWaitOnMask(pSerialDevObj, &WaitMask);
  2366. sswDone:
  2367. #if DBG
  2368. if (Status != STATUS_SUCCESS)
  2369. {
  2370. DEBUGMSG(DBG_ERR, (" SerialSynchronousWrite() Failed. 0x%08X\n\n", Status));
  2371. }
  2372. #endif
  2373. DEBUGMSG(DBG_FUNC, ("-SerialSynchronousWrite\n"));
  2374. return Status;
  2375. }
  2376. NTSTATUS
  2377. SerialSynchronousRead(
  2378. IN PDEVICE_OBJECT pSerialDevObj,
  2379. OUT PVOID pBuffer,
  2380. IN ULONG dwLength,
  2381. OUT PULONG pdwBytesRead)
  2382. {
  2383. PIRP Irp;
  2384. PIO_STACK_LOCATION IrpSp;
  2385. NTSTATUS Status;
  2386. KEVENT Event;
  2387. IO_STATUS_BLOCK IOStatus;
  2388. *pdwBytesRead = 0;
  2389. if (!pSerialDevObj)
  2390. {
  2391. DEBUGMSG(DBG_ERROR, ("IRSIR: SerialDevObj==NULL\n"));
  2392. return STATUS_INVALID_PARAMETER;
  2393. }
  2394. DEBUGMSG(DBG_FUNC, ("+SerialSynchronousRead\n"));
  2395. ASSERT(KeGetCurrentIrql() < DISPATCH_LEVEL);
  2396. KeInitializeEvent( &Event, NotificationEvent, FALSE );
  2397. RtlZeroMemory(&IOStatus, sizeof(IOStatus));
  2398. Irp = SerialBuildReadWriteIrp(pSerialDevObj,
  2399. IRP_MJ_READ,
  2400. pBuffer,
  2401. dwLength,
  2402. &IOStatus);
  2403. if (Irp == NULL)
  2404. {
  2405. Status = STATUS_INSUFFICIENT_RESOURCES;
  2406. goto ssrDone;
  2407. }
  2408. IoSetCompletionRoutine(Irp,
  2409. IrpCompleteSetEvent,
  2410. &Event,
  2411. TRUE,
  2412. TRUE,
  2413. TRUE);
  2414. Status = IoCallDriver(pSerialDevObj, Irp);
  2415. if (Status == STATUS_PENDING)
  2416. {
  2417. KeWaitForSingleObject( &Event, Executive, KernelMode, FALSE, NULL );
  2418. }
  2419. Status = IOStatus.Status;
  2420. // This truncates if 64 bits. Don't think we'll be reading or writing more than
  2421. // 4.5 GB to a serial port soon.
  2422. *pdwBytesRead = (ULONG)IOStatus.Information;
  2423. ssrDone:
  2424. #if DBG
  2425. if (Status != STATUS_SUCCESS)
  2426. {
  2427. DEBUGMSG(DBG_WARN, (" SerialSynchronousRead() Failed. 0x%08X\n\n", Status));
  2428. }
  2429. #endif
  2430. DEBUGMSG(DBG_FUNC, ("-SerialSynchronousRead\n"));
  2431. return Status;
  2432. }