ReactOS 0.4.15-dev-7842-g558ab78
devctrl.c File Reference
#include "serial.h"
#include <debug.h>
Include dependency graph for devctrl.c:

Go to the source code of this file.

Macros

#define IO_METHOD_FROM_CTL_CODE(ctlCode)   (ctlCode&0x00000003)
 

Functions

static VOID SerialGetUserBuffers (IN PIRP Irp, IN ULONG IoControlCode, OUT PVOID *BufferIn, OUT PVOID *BufferOut)
 
NTSTATUS NTAPI SerialSetBaudRate (IN PSERIAL_DEVICE_EXTENSION DeviceExtension, IN ULONG NewBaudRate)
 
NTSTATUS NTAPI SerialSetLineControl (IN PSERIAL_DEVICE_EXTENSION DeviceExtension, IN PSERIAL_LINE_CONTROL NewSettings)
 
static BOOLEAN NTAPI SerialClearPerfStats (IN PVOID SynchronizeContext)
 
static BOOLEAN NTAPI SerialGetPerfStats (IN PVOID SynchronizeContext)
 
static NTSTATUS SerialGetCommProp (OUT PSERIAL_COMMPROP pCommProp, IN PSERIAL_DEVICE_EXTENSION DeviceExtension)
 
static NTSTATUS SerialGetCommStatus (OUT PSERIAL_STATUS pSerialStatus, IN PSERIAL_DEVICE_EXTENSION DeviceExtension)
 
NTSTATUS NTAPI SerialDeviceControl (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
 

Macro Definition Documentation

◆ IO_METHOD_FROM_CTL_CODE

#define IO_METHOD_FROM_CTL_CODE (   ctlCode)    (ctlCode&0x00000003)

Definition at line 14 of file devctrl.c.

Function Documentation

◆ SerialClearPerfStats()

static BOOLEAN NTAPI SerialClearPerfStats ( IN PVOID  SynchronizeContext)
static

Definition at line 164 of file devctrl.c.

165{
167 ASSERT(DeviceExtension);
168 RtlZeroMemory(&DeviceExtension->SerialPerfStats, sizeof(SERIALPERF_STATS));
169 DeviceExtension->BreakInterruptErrorCount = 0;
170 return TRUE;
171}
#define TRUE
Definition: types.h:120
#define ASSERT(a)
Definition: mode.c:44
ULONG BreakInterruptErrorCount
Definition: serial.h:70
SERIALPERF_STATS SerialPerfStats
Definition: serial.h:71
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
_In_ PKSYNCHRONIZE_ROUTINE _In_opt_ __drv_aliasesMem PVOID SynchronizeContext
Definition: kefuncs.h:525

Referenced by SerialDeviceControl().

◆ SerialDeviceControl()

NTSTATUS NTAPI SerialDeviceControl ( IN PDEVICE_OBJECT  DeviceObject,
IN PIRP  Irp 
)

Definition at line 281 of file devctrl.c.

284{
287 PSERIAL_DEVICE_EXTENSION DeviceExtension;
288 ULONG LengthIn, LengthOut;
290 PVOID BufferIn, BufferOut;
291 PUCHAR ComPortBase;
293
294 TRACE_(SERIAL, "IRP_MJ_DEVICE_CONTROL dispatch\n");
295
297 LengthIn = Stack->Parameters.DeviceIoControl.InputBufferLength;
298 LengthOut = Stack->Parameters.DeviceIoControl.OutputBufferLength;
299 DeviceExtension = (PSERIAL_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
300 ComPortBase = ULongToPtr(DeviceExtension->BaseAddress);
301 IoControlCode = Stack->Parameters.DeviceIoControl.IoControlCode;
302 SerialGetUserBuffers(Irp, IoControlCode, &BufferIn, &BufferOut);
303
304 /* FIXME: need to probe buffers */
305 /* FIXME: see http://www.osronline.com/ddkx/serial/serref_61bm.htm */
306 switch (IoControlCode)
307 {
309 {
310 TRACE_(SERIAL, "IOCTL_SERIAL_CLEAR_STATS\n");
312 DeviceExtension->Interrupt,
314 DeviceExtension);
316 break;
317 }
319 {
320 TRACE_(SERIAL, "IOCTL_SERIAL_CLR_DTR\n");
321 /* FIXME: If the handshake flow control of the device is configured to
322 * automatically use DTR, return STATUS_INVALID_PARAMETER */
323 Status = IoAcquireRemoveLock(&DeviceExtension->RemoveLock, ULongToPtr(DeviceExtension->ComPort));
324 if (NT_SUCCESS(Status))
325 {
326 DeviceExtension->MCR &= ~SR_MCR_DTR;
327 WRITE_PORT_UCHAR(SER_MCR(ComPortBase), DeviceExtension->MCR);
328 IoReleaseRemoveLock(&DeviceExtension->RemoveLock, ULongToPtr(DeviceExtension->ComPort));
329 }
330 break;
331 }
333 {
334 TRACE_(SERIAL, "IOCTL_SERIAL_CLR_RTS\n");
335 /* FIXME: If the handshake flow control of the device is configured to
336 * automatically use RTS, return STATUS_INVALID_PARAMETER */
337 Status = IoAcquireRemoveLock(&DeviceExtension->RemoveLock, ULongToPtr(DeviceExtension->ComPort));
338 if (NT_SUCCESS(Status))
339 {
340 DeviceExtension->MCR &= ~SR_MCR_RTS;
341 WRITE_PORT_UCHAR(SER_MCR(ComPortBase), DeviceExtension->MCR);
342 IoReleaseRemoveLock(&DeviceExtension->RemoveLock, ULongToPtr(DeviceExtension->ComPort));
343 }
344 break;
345 }
347 {
348 /* Obsolete on Microsoft Windows 2000+ */
349 PULONG pConfigSize;
350 TRACE_(SERIAL, "IOCTL_SERIAL_CONFIG_SIZE\n");
351 if (LengthOut != sizeof(ULONG) || BufferOut == NULL)
353 else
354 {
355 pConfigSize = (PULONG)BufferOut;
356 *pConfigSize = 0;
357 Information = sizeof(ULONG);
359 }
360 break;
361 }
363 {
364 TRACE_(SERIAL, "IOCTL_SERIAL_GET_BAUD_RATE\n");
365 if (LengthOut < sizeof(SERIAL_BAUD_RATE))
367 else if (BufferOut == NULL)
369 else
370 {
371 ((PSERIAL_BAUD_RATE)BufferOut)->BaudRate = DeviceExtension->BaudRate;
374 }
375 break;
376 }
378 {
379 /* FIXME */
380 PSERIAL_CHARS pSerialChars;
381 ERR_(SERIAL, "IOCTL_SERIAL_GET_CHARS not implemented.\n");
382 if (LengthOut < sizeof(SERIAL_CHARS))
384 else if (BufferOut == NULL)
386 else
387 {
388 pSerialChars = (PSERIAL_CHARS)BufferOut;
389 pSerialChars->EofChar = 0;
390 pSerialChars->ErrorChar = 0;
391 pSerialChars->BreakChar = 0;
392 pSerialChars->EventChar = 0;
393 pSerialChars->XonChar = 0;
394 pSerialChars->XoffChar = 0;
395 Information = sizeof(SERIAL_CHARS);
397 }
398 break;
399 }
401 {
402 TRACE_(SERIAL, "IOCTL_SERIAL_GET_COMMSTATUS\n");
403 if (LengthOut < sizeof(SERIAL_STATUS))
405 else if (BufferOut == NULL)
407 else
408 {
409 Status = SerialGetCommStatus((PSERIAL_STATUS)BufferOut, DeviceExtension);
410 Information = sizeof(SERIAL_STATUS);
411 }
412 break;
413 }
415 {
416 PULONG pDtrRts;
417 TRACE_(SERIAL, "IOCTL_SERIAL_GET_DTRRTS\n");
418 if (LengthOut != sizeof(ULONG) || BufferOut == NULL)
420 else
421 {
422 pDtrRts = (PULONG)BufferOut;
423 *pDtrRts = 0;
424 if (DeviceExtension->MCR & SR_MCR_DTR)
425 *pDtrRts |= SERIAL_DTR_STATE;
426 if (DeviceExtension->MCR & SR_MCR_RTS)
427 *pDtrRts |= SERIAL_RTS_STATE;
428 Information = sizeof(ULONG);
430 }
431 break;
432 }
434 {
435 /* FIXME */
436 PSERIAL_HANDFLOW pSerialHandflow;
437 ERR_(SERIAL, "IOCTL_SERIAL_GET_HANDFLOW not implemented.\n");
438 if (LengthOut < sizeof(SERIAL_HANDFLOW))
440 else if (BufferOut == NULL)
442 else
443 {
444 pSerialHandflow = (PSERIAL_HANDFLOW)BufferOut;
445 pSerialHandflow->ControlHandShake = 0;
446 pSerialHandflow->FlowReplace = 0;
447 pSerialHandflow->XonLimit = 0;
448 pSerialHandflow->XoffLimit = 0;
451 }
452 break;
453 }
455 {
456 TRACE_(SERIAL, "IOCTL_SERIAL_GET_LINE_CONTROL\n");
457 if (LengthOut < sizeof(SERIAL_LINE_CONTROL))
459 else if (BufferOut == NULL)
461 else
462 {
463 *((PSERIAL_LINE_CONTROL)BufferOut) = DeviceExtension->SerialLineControl;
466 }
467 break;
468 }
470 {
471 PULONG pMCR;
472 TRACE_(SERIAL, "IOCTL_SERIAL_GET_MODEM_CONTROL\n");
473 if (LengthOut != sizeof(ULONG) || BufferOut == NULL)
475 else
476 {
477 pMCR = (PULONG)BufferOut;
478 *pMCR = DeviceExtension->MCR;
479 Information = sizeof(ULONG);
481 }
482 break;
483 }
485 {
486 PULONG pMSR;
487 TRACE_(SERIAL, "IOCTL_SERIAL_GET_MODEMSTATUS\n");
488 if (LengthOut != sizeof(ULONG) || BufferOut == NULL)
490 else
491 {
492 pMSR = (PULONG)BufferOut;
493 *pMSR = DeviceExtension->MSR;
494 Information = sizeof(ULONG);
496 }
497 break;
498 }
500 {
501 TRACE_(SERIAL, "IOCTL_SERIAL_GET_PROPERTIES\n");
502 if (LengthOut < sizeof(SERIAL_COMMPROP))
504 else if (BufferOut == NULL)
506 else
507 {
508 Status = SerialGetCommProp((PSERIAL_COMMPROP)BufferOut, DeviceExtension);
510 }
511 break;
512 }
514 {
515 TRACE_(SERIAL, "IOCTL_SERIAL_GET_STATS\n");
516 if (LengthOut < sizeof(SERIALPERF_STATS))
518 else if (BufferOut == NULL)
520 else
521 {
522 KeSynchronizeExecution(DeviceExtension->Interrupt,
526 }
527 break;
528 }
530 {
531 TRACE_(SERIAL, "IOCTL_SERIAL_GET_TIMEOUTS\n");
532 if (LengthOut != sizeof(SERIAL_TIMEOUTS) || BufferOut == NULL)
534 else
535 {
536 *(PSERIAL_TIMEOUTS)BufferOut = DeviceExtension->SerialTimeOuts;
539 }
540 break;
541 }
543 {
544 PULONG pWaitMask;
545 TRACE_(SERIAL, "IOCTL_SERIAL_GET_WAIT_MASK\n");
546 if (LengthOut != sizeof(ULONG) || BufferOut == NULL)
548 else
549 {
550 pWaitMask = (PULONG)BufferOut;
551 *pWaitMask = DeviceExtension->WaitMask;
552 Information = sizeof(ULONG);
554 }
555 break;
556 }
558 {
559 /* FIXME */
560 ERR_(SERIAL, "IOCTL_SERIAL_IMMEDIATE_CHAR not implemented.\n");
562 break;
563 }
565 {
566 /* FIXME */
567 ERR_(SERIAL, "IOCTL_SERIAL_LSRMST_INSERT not implemented.\n");
569 break;
570 }
572 {
573 KIRQL Irql;
574 TRACE_(SERIAL, "IOCTL_SERIAL_PURGE\n");
575 /* FIXME: SERIAL_PURGE_RXABORT and SERIAL_PURGE_TXABORT
576 * should stop current request */
577 if (LengthIn != sizeof(ULONG) || BufferIn == NULL)
579 else
580 {
581 ULONG PurgeMask = *(PULONG)BufferIn;
582
584 /* FIXME: use SERIAL_PURGE_RXABORT and SERIAL_PURGE_TXABORT flags */
585 if (PurgeMask & SERIAL_PURGE_RXCLEAR)
586 {
587 KeAcquireSpinLock(&DeviceExtension->InputBufferLock, &Irql);
588 DeviceExtension->InputBuffer.ReadPosition = DeviceExtension->InputBuffer.WritePosition = 0;
589 if (DeviceExtension->UartType >= Uart16550A)
590 {
591 /* Clear also Uart FIFO */
592 Status = IoAcquireRemoveLock(&DeviceExtension->RemoveLock, ULongToPtr(DeviceExtension->ComPort));
593 if (NT_SUCCESS(Status))
594 {
596 IoReleaseRemoveLock(&DeviceExtension->RemoveLock, ULongToPtr(DeviceExtension->ComPort));
597 }
598 }
599 KeReleaseSpinLock(&DeviceExtension->InputBufferLock, Irql);
600 }
601
602 if (PurgeMask & SERIAL_PURGE_TXCLEAR)
603 {
604 KeAcquireSpinLock(&DeviceExtension->OutputBufferLock, &Irql);
605 DeviceExtension->OutputBuffer.ReadPosition = DeviceExtension->OutputBuffer.WritePosition = 0;
606 if (DeviceExtension->UartType >= Uart16550A)
607 {
608 /* Clear also Uart FIFO */
609 Status = IoAcquireRemoveLock(&DeviceExtension->RemoveLock, ULongToPtr(DeviceExtension->ComPort));
610 if (NT_SUCCESS(Status))
611 {
613 IoReleaseRemoveLock(&DeviceExtension->RemoveLock, ULongToPtr(DeviceExtension->ComPort));
614 }
615 }
616 KeReleaseSpinLock(&DeviceExtension->OutputBufferLock, Irql);
617 }
618 }
619 break;
620 }
622 {
623 /* FIXME */
624 ERR_(SERIAL, "IOCTL_SERIAL_RESET_DEVICE not implemented.\n");
626 break;
627 }
629 {
630 PULONG pNewBaudRate;
631 TRACE_(SERIAL, "IOCTL_SERIAL_SET_BAUD_RATE\n");
632 if (LengthIn != sizeof(ULONG) || BufferIn == NULL)
634 else
635 {
636 pNewBaudRate = (PULONG)BufferIn;
637 Status = SerialSetBaudRate(DeviceExtension, *pNewBaudRate);
638 }
639 break;
640 }
642 {
643 /* FIXME */
644 ERR_(SERIAL, "IOCTL_SERIAL_SET_BREAK_OFF not implemented.\n");
646 break;
647 }
649 {
650 /* FIXME */
651 ERR_(SERIAL, "IOCTL_SERIAL_SET_BREAK_ON not implemented.\n");
653 break;
654 }
656 {
657 /* FIXME */
658 ERR_(SERIAL, "IOCTL_SERIAL_SET_CHARS not implemented.\n");
660 break;
661 }
663 {
664 /* FIXME: If the handshake flow control of the device is configured to
665 * automatically use DTR, return STATUS_INVALID_PARAMETER */
666 TRACE_(SERIAL, "IOCTL_SERIAL_SET_DTR\n");
667 if (!(DeviceExtension->MCR & SR_MCR_DTR))
668 {
669 Status = IoAcquireRemoveLock(&DeviceExtension->RemoveLock, ULongToPtr(DeviceExtension->ComPort));
670 if (NT_SUCCESS(Status))
671 {
672 DeviceExtension->MCR |= SR_MCR_DTR;
673 WRITE_PORT_UCHAR(SER_MCR(ComPortBase), DeviceExtension->MCR);
674 IoReleaseRemoveLock(&DeviceExtension->RemoveLock, ULongToPtr(DeviceExtension->ComPort));
675 }
676 }
677 else
679 break;
680 }
682 {
683 TRACE_(SERIAL, "IOCTL_SERIAL_SET_FIFO_CONTROL\n");
684 if (LengthIn != sizeof(ULONG) || BufferIn == NULL)
686 else
687 {
688 Status = IoAcquireRemoveLock(&DeviceExtension->RemoveLock, ULongToPtr(DeviceExtension->ComPort));
689 if (NT_SUCCESS(Status))
690 {
691 WRITE_PORT_UCHAR(SER_FCR(ComPortBase), (UCHAR)((*(PULONG)BufferIn) & 0xff));
692 IoReleaseRemoveLock(&DeviceExtension->RemoveLock, ULongToPtr(DeviceExtension->ComPort));
693 }
694 }
695 break;
696 }
698 {
699 /* FIXME */
700 ERR_(SERIAL, "IOCTL_SERIAL_SET_HANDFLOW not implemented.\n");
702 break;
703 }
705 {
706 TRACE_(SERIAL, "IOCTL_SERIAL_SET_LINE_CONTROL\n");
707 if (LengthIn < sizeof(SERIAL_LINE_CONTROL))
709 else if (BufferIn == NULL)
711 else
712 Status = SerialSetLineControl(DeviceExtension, (PSERIAL_LINE_CONTROL)BufferIn);
713 break;
714 }
716 {
717 PULONG pMCR;
718 TRACE_(SERIAL, "IOCTL_SERIAL_SET_MODEM_CONTROL\n");
719 if (LengthIn != sizeof(ULONG) || BufferIn == NULL)
721 else
722 {
723 Status = IoAcquireRemoveLock(&DeviceExtension->RemoveLock, ULongToPtr(DeviceExtension->ComPort));
724 if (NT_SUCCESS(Status))
725 {
726 pMCR = (PULONG)BufferIn;
727 DeviceExtension->MCR = (UCHAR)(*pMCR & 0xff);
728 WRITE_PORT_UCHAR(SER_MCR(ComPortBase), DeviceExtension->MCR);
729 IoReleaseRemoveLock(&DeviceExtension->RemoveLock, ULongToPtr(DeviceExtension->ComPort));
730 }
731 }
732 break;
733 }
735 {
736 if (LengthIn < sizeof(SERIAL_QUEUE_SIZE ))
738 else if (BufferIn == NULL)
740 else
741 {
742 KIRQL Irql;
743 PSERIAL_QUEUE_SIZE NewQueueSize = (PSERIAL_QUEUE_SIZE)BufferIn;
745 if (NewQueueSize->InSize > DeviceExtension->InputBuffer.Length)
746 {
747 KeAcquireSpinLock(&DeviceExtension->InputBufferLock, &Irql);
748 Status = IncreaseCircularBufferSize(&DeviceExtension->InputBuffer, NewQueueSize->InSize);
749 KeReleaseSpinLock(&DeviceExtension->InputBufferLock, Irql);
750 }
751 if (NT_SUCCESS(Status) && NewQueueSize->OutSize > DeviceExtension->OutputBuffer.Length)
752 {
753 KeAcquireSpinLock(&DeviceExtension->OutputBufferLock, &Irql);
754 Status = IncreaseCircularBufferSize(&DeviceExtension->OutputBuffer, NewQueueSize->OutSize);
755 KeReleaseSpinLock(&DeviceExtension->OutputBufferLock, Irql);
756 }
757 }
758 break;
759 }
761 {
762 /* FIXME: If the handshake flow control of the device is configured to
763 * automatically use DTR, return STATUS_INVALID_PARAMETER */
764 TRACE_(SERIAL, "IOCTL_SERIAL_SET_RTS\n");
765 if (!(DeviceExtension->MCR & SR_MCR_RTS))
766 {
767 Status = IoAcquireRemoveLock(&DeviceExtension->RemoveLock, ULongToPtr(DeviceExtension->ComPort));
768 if (NT_SUCCESS(Status))
769 {
770 DeviceExtension->MCR |= SR_MCR_RTS;
771 WRITE_PORT_UCHAR(SER_MCR(ComPortBase), DeviceExtension->MCR);
772 IoReleaseRemoveLock(&DeviceExtension->RemoveLock, ULongToPtr(DeviceExtension->ComPort));
773 }
774 }
775 else
777 break;
778 }
780 {
781 TRACE_(SERIAL, "IOCTL_SERIAL_SET_TIMEOUTS\n");
782 if (LengthIn != sizeof(SERIAL_TIMEOUTS) || BufferIn == NULL)
784 else
785 {
786 DeviceExtension->SerialTimeOuts = *(PSERIAL_TIMEOUTS)BufferIn;
788 }
789 break;
790 }
792 {
793 PULONG pWaitMask = (PULONG)BufferIn;
794 TRACE_(SERIAL, "IOCTL_SERIAL_SET_WAIT_MASK\n");
795
796 if (LengthIn != sizeof(ULONG) || BufferIn == NULL)
798 else if (DeviceExtension->WaitOnMaskIrp) /* FIXME: Race condition ; field may be currently in modification */
799 {
800 WARN_(SERIAL, "An IRP is already currently processed\n");
802 }
803 else
804 {
805 DeviceExtension->WaitMask = *pWaitMask;
807 }
808 break;
809 }
811 {
812 /* FIXME */
813 ERR_(SERIAL, "IOCTL_SERIAL_SET_XOFF not implemented.\n");
815 break;
816 }
818 {
819 /* FIXME */
820 ERR_(SERIAL, "IOCTL_SERIAL_SET_XON not implemented.\n");
822 break;
823 }
825 {
826 PIRP WaitingIrp;
827 TRACE_(SERIAL, "IOCTL_SERIAL_WAIT_ON_MASK\n");
828
829 if (LengthOut != sizeof(ULONG) || BufferOut == NULL)
831 else
832 {
834
836 (PVOID*)&DeviceExtension->WaitOnMaskIrp,
837 Irp,
838 NULL);
839
840 /* Check if an Irp is already pending */
841 if (WaitingIrp != NULL)
842 {
843 /* Unable to have a 2nd pending IRP for this IOCTL */
844 WARN_(SERIAL, "Unable to pend a second IRP for IOCTL_SERIAL_WAIT_ON_MASK\n");
845 Irp->IoStatus.Information = 0;
846 Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
848 }
849 return STATUS_PENDING;
850 }
851 break;
852 }
854 {
855 /* FIXME */
856 ERR_(SERIAL, "IOCTL_SERIAL_XOFF_COUNTER not implemented.\n");
858 break;
859 }
860 default:
861 {
862 /* Pass Irp to lower driver */
863 TRACE_(SERIAL, "Unknown IOCTL code 0x%x\n", Stack->Parameters.DeviceIoControl.IoControlCode);
865 return IoCallDriver(DeviceExtension->LowerDevice, Irp);
866 }
867 }
868
869 Irp->IoStatus.Status = Status;
870 if (Status == STATUS_PENDING)
871 {
873 }
874 else
875 {
876 Irp->IoStatus.Information = Information;
878 }
879 return Status;
880}
LONG NTSTATUS
Definition: precomp.h:26
#define ULongToPtr(ul)
Definition: basetsd.h:92
NTSTATUS IncreaseCircularBufferSize(IN PCIRCULAR_BUFFER pBuffer, IN ULONG NewBufferSize)
_In_ PIRP Irp
Definition: csq.h:116
_Out_ PKIRQL Irql
Definition: csq.h:179
#define NULL
Definition: types.h:112
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define TRACE_(x)
Definition: compat.h:76
@ Uart16550A
Definition: serial.h:35
#define SR_MCR_DTR
Definition: serial.h:150
#define SR_FCR_CLEAR_RCVR
Definition: serial.h:129
#define SR_FCR_CLEAR_XMIT
Definition: serial.h:130
struct _SERIAL_DEVICE_EXTENSION * PSERIAL_DEVICE_EXTENSION
#define SER_FCR(x)
Definition: serial.h:127
#define SR_MCR_RTS
Definition: serial.h:151
#define SER_MCR(x)
Definition: serial.h:149
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
Status
Definition: gdiplustypes.h:25
#define InterlockedCompareExchangePointer
Definition: interlocked.h:129
IoMarkIrpPending(Irp)
#define SERIAL_PURGE_TXCLEAR
Definition: serial.c:95
#define SERIAL_PURGE_RXCLEAR
Definition: serial.c:96
#define IOCTL_SERIAL_SET_CHARS
Definition: ntddser.h:88
#define SERIAL_RTS_STATE
Definition: ntddser.h:428
#define IOCTL_SERIAL_SET_LINE_CONTROL
Definition: ntddser.h:96
struct _SERIAL_CHARS * PSERIAL_CHARS
#define IOCTL_SERIAL_XOFF_COUNTER
Definition: ntddser.h:114
#define IOCTL_SERIAL_SET_TIMEOUTS
Definition: ntddser.h:104
struct _SERIAL_QUEUE_SIZE * PSERIAL_QUEUE_SIZE
struct _SERIAL_COMMPROP SERIAL_COMMPROP
#define IOCTL_SERIAL_WAIT_ON_MASK
Definition: ntddser.h:112
#define IOCTL_SERIAL_SET_MODEM_CONTROL
Definition: ntddser.h:98
#define IOCTL_SERIAL_IMMEDIATE_CHAR
Definition: ntddser.h:74
#define IOCTL_SERIAL_GET_DTRRTS
Definition: ntddser.h:56
#define IOCTL_SERIAL_SET_XOFF
Definition: ntddser.h:108
#define IOCTL_SERIAL_GET_CHARS
Definition: ntddser.h:52
struct _SERIAL_HANDFLOW * PSERIAL_HANDFLOW
struct _SERIALPERF_STATS SERIALPERF_STATS
struct _SERIAL_BAUD_RATE SERIAL_BAUD_RATE
struct _SERIAL_CHARS SERIAL_CHARS
#define IOCTL_SERIAL_SET_WAIT_MASK
Definition: ntddser.h:106
#define IOCTL_SERIAL_SET_QUEUE_SIZE
Definition: ntddser.h:100
#define SERIAL_DTR_STATE
Definition: ntddser.h:427
#define IOCTL_SERIAL_RESET_DEVICE
Definition: ntddser.h:80
struct _SERIAL_BAUD_RATE * PSERIAL_BAUD_RATE
struct _SERIAL_HANDFLOW SERIAL_HANDFLOW
#define IOCTL_SERIAL_GET_BAUD_RATE
Definition: ntddser.h:50
#define IOCTL_SERIAL_GET_COMMSTATUS
Definition: ntddser.h:54
#define IOCTL_SERIAL_SET_FIFO_CONTROL
Definition: ntddser.h:92
#define IOCTL_SERIAL_GET_WAIT_MASK
Definition: ntddser.h:72
#define IOCTL_SERIAL_SET_BREAK_OFF
Definition: ntddser.h:86
#define IOCTL_SERIAL_CONFIG_SIZE
Definition: ntddser.h:48
#define IOCTL_SERIAL_GET_MODEM_CONTROL
Definition: ntddser.h:62
#define IOCTL_SERIAL_GET_TIMEOUTS
Definition: ntddser.h:70
#define IOCTL_SERIAL_SET_XON
Definition: ntddser.h:110
#define IOCTL_SERIAL_GET_STATS
Definition: ntddser.h:68
#define IOCTL_SERIAL_CLR_DTR
Definition: ntddser.h:44
struct _SERIAL_LINE_CONTROL * PSERIAL_LINE_CONTROL
#define IOCTL_SERIAL_SET_BAUD_RATE
Definition: ntddser.h:82
#define IOCTL_SERIAL_GET_PROPERTIES
Definition: ntddser.h:66
#define IOCTL_SERIAL_LSRMST_INSERT
Definition: ntddser.h:76
#define IOCTL_SERIAL_CLR_RTS
Definition: ntddser.h:46
#define IOCTL_SERIAL_GET_MODEMSTATUS
Definition: ntddser.h:64
#define IOCTL_SERIAL_CLEAR_STATS
Definition: ntddser.h:42
#define IOCTL_SERIAL_GET_LINE_CONTROL
Definition: ntddser.h:60
struct _SERIAL_STATUS SERIAL_STATUS
#define IOCTL_SERIAL_SET_DTR
Definition: ntddser.h:90
struct _SERIAL_TIMEOUTS * PSERIAL_TIMEOUTS
struct _SERIAL_LINE_CONTROL SERIAL_LINE_CONTROL
#define IOCTL_SERIAL_SET_BREAK_ON
Definition: ntddser.h:84
#define IOCTL_SERIAL_GET_HANDFLOW
Definition: ntddser.h:58
#define IOCTL_SERIAL_SET_RTS
Definition: ntddser.h:102
#define IOCTL_SERIAL_SET_HANDFLOW
Definition: ntddser.h:94
#define IOCTL_SERIAL_PURGE
Definition: ntddser.h:78
#define IoSkipCurrentIrpStackLocation(Irp)
Definition: ntifs_ex.h:421
#define IoCompleteRequest
Definition: irp.c:1240
#define IoCallDriver
Definition: irp.c:1225
BOOLEAN NTAPI KeSynchronizeExecution(IN OUT PKINTERRUPT Interrupt, IN PKSYNCHRONIZE_ROUTINE SynchronizeRoutine, IN PVOID SynchronizeContext OPTIONAL)
Definition: interrupt.c:237
#define STATUS_PENDING
Definition: ntstatus.h:82
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:239
#define WRITE_PORT_UCHAR(p, d)
Definition: pc98vid.h:21
#define ERR_(ch,...)
Definition: debug.h:156
#define WARN_(ch,...)
Definition: debug.h:157
static NTSTATUS SerialGetCommProp(OUT PSERIAL_COMMPROP pCommProp, IN PSERIAL_DEVICE_EXTENSION DeviceExtension)
Definition: devctrl.c:195
static BOOLEAN NTAPI SerialGetPerfStats(IN PVOID SynchronizeContext)
Definition: devctrl.c:176
static VOID SerialGetUserBuffers(IN PIRP Irp, IN ULONG IoControlCode, OUT PVOID *BufferIn, OUT PVOID *BufferOut)
Definition: devctrl.c:17
static NTSTATUS SerialGetCommStatus(OUT PSERIAL_STATUS pSerialStatus, IN PSERIAL_DEVICE_EXTENSION DeviceExtension)
Definition: devctrl.c:241
NTSTATUS NTAPI SerialSetBaudRate(IN PSERIAL_DEVICE_EXTENSION DeviceExtension, IN ULONG NewBaudRate)
Definition: devctrl.c:50
static BOOLEAN NTAPI SerialClearPerfStats(IN PVOID SynchronizeContext)
Definition: devctrl.c:164
NTSTATUS NTAPI SerialSetLineControl(IN PSERIAL_DEVICE_EXTENSION DeviceExtension, IN PSERIAL_LINE_CONTROL NewSettings)
Definition: devctrl.c:88
#define STATUS_SUCCESS
Definition: shellext.h:65
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
ULONG Length
Definition: serial.h:43
ULONG WritePosition
Definition: serial.h:45
ULONG ReadPosition
Definition: serial.h:44
UCHAR XoffChar
Definition: ntddser.h:167
UCHAR EventChar
Definition: ntddser.h:165
UCHAR ErrorChar
Definition: ntddser.h:163
UCHAR EofChar
Definition: ntddser.h:162
UCHAR XonChar
Definition: ntddser.h:166
UCHAR BreakChar
Definition: ntddser.h:164
SERIAL_LINE_CONTROL SerialLineControl
Definition: serial.h:65
PKINTERRUPT Interrupt
Definition: serial.h:60
PDEVICE_OBJECT LowerDevice
Definition: serial.h:51
KSPIN_LOCK OutputBufferLock
Definition: serial.h:78
UART_TYPE UartType
Definition: serial.h:66
KSPIN_LOCK InputBufferLock
Definition: serial.h:76
IO_REMOVE_LOCK RemoveLock
Definition: serial.h:53
CIRCULAR_BUFFER InputBuffer
Definition: serial.h:75
CIRCULAR_BUFFER OutputBuffer
Definition: serial.h:77
SERIAL_TIMEOUTS SerialTimeOuts
Definition: serial.h:72
ULONG ControlHandShake
Definition: ntddser.h:180
ULONG FlowReplace
Definition: ntddser.h:181
uint32_t * PULONG
Definition: typedefs.h:59
uint32_t ULONG_PTR
Definition: typedefs.h:65
unsigned char * PUCHAR
Definition: typedefs.h:53
uint32_t ULONG
Definition: typedefs.h:59
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
_In_ WDFREQUEST _In_ size_t _In_ size_t _In_ ULONG IoControlCode
Definition: wdfio.h:325
_In_ WDFREQUEST _In_ PIO_STACK_LOCATION Stack
Definition: wdfrequest.h:639
_In_ WDFREQUEST _In_ NTSTATUS _In_ ULONG_PTR Information
Definition: wdfrequest.h:1049
#define IoAcquireRemoveLock(RemoveLock, Tag)
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2793
#define IoReleaseRemoveLock(_RemoveLock, _Tag)
Definition: iofuncs.h:2764
#define IO_NO_INCREMENT
Definition: iotypes.h:598
unsigned char UCHAR
Definition: xmlstorage.h:181

◆ SerialGetCommProp()

static NTSTATUS SerialGetCommProp ( OUT PSERIAL_COMMPROP  pCommProp,
IN PSERIAL_DEVICE_EXTENSION  DeviceExtension 
)
static

Definition at line 195 of file devctrl.c.

198{
199 ASSERT(pCommProp);
200
201 RtlZeroMemory(pCommProp, sizeof(SERIAL_COMMPROP));
202
203 if (!(pCommProp->ProvSpec1 & COMMPROP_INITIALIZED))
204 pCommProp->PacketLength = sizeof(SERIAL_COMMPROP);
205 pCommProp->PacketVersion = 2;
206 pCommProp->ServiceMask = SERIAL_SP_SERIALCOMM;
207 pCommProp->MaxTxQueue = pCommProp->CurrentTxQueue = DeviceExtension->OutputBuffer.Length - 1;
208 pCommProp->MaxRxQueue = pCommProp->CurrentRxQueue = DeviceExtension->InputBuffer.Length - 1;
209 pCommProp->ProvSubType = PST_RS232;
213 pCommProp->SettableParams = SERIAL_SP_BAUD | SERIAL_SP_DATABITS | SERIAL_SP_HANDSHAKING
215
216 /* SettableBaud is related to Uart type */
217 pCommProp->SettableBaud = SERIAL_BAUD_075 | SERIAL_BAUD_110 | SERIAL_BAUD_134_5
221 pCommProp->MaxBaud = SERIAL_BAUD_USER;
222 if (DeviceExtension->UartType >= Uart16450)
223 {
224 pCommProp->SettableBaud |= SERIAL_BAUD_14400 | SERIAL_BAUD_19200 | SERIAL_BAUD_38400;
225 }
226 if (DeviceExtension->UartType >= Uart16550)
227 {
229 }
230
232 pCommProp->SettableStopParity = SERIAL_STOPBITS_10 | SERIAL_STOPBITS_15 | SERIAL_STOPBITS_20
234
235 pCommProp->ProvSpec2 = 0; /* Size of provider-specific data */
236
237 return STATUS_SUCCESS;
238}
@ Uart16550
Definition: serial.h:34
@ Uart16450
Definition: serial.h:33
#define COMMPROP_INITIALIZED
Definition: serial.h:18
#define PST_RS232
Definition: serial.h:17
#define SERIAL_BAUD_134_5
Definition: ntddser.h:142
#define SERIAL_PCF_TOTALTIMEOUTS
Definition: ntddser.h:270
#define SERIAL_BAUD_110
Definition: ntddser.h:141
#define SERIAL_BAUD_14400
Definition: ntddser.h:152
#define SERIAL_SP_DATABITS
Definition: ntddser.h:257
#define SERIAL_SP_STOPBITS
Definition: ntddser.h:258
#define SERIAL_BAUD_38400
Definition: ntddser.h:154
#define SERIAL_BAUD_USER
Definition: ntddser.h:159
#define SERIAL_PARITY_MARK
Definition: ntddser.h:290
#define SERIAL_BAUD_075
Definition: ntddser.h:140
#define SERIAL_BAUD_150
Definition: ntddser.h:143
#define SERIAL_PCF_SPECIALCHARS
Definition: ntddser.h:272
#define SERIAL_PCF_DTRDSR
Definition: ntddser.h:264
#define SERIAL_SP_HANDSHAKING
Definition: ntddser.h:259
#define SERIAL_DATABITS_5
Definition: ntddser.h:276
#define SERIAL_PCF_XONXOFF
Definition: ntddser.h:268
#define SERIAL_STOPBITS_15
Definition: ntddser.h:285
#define SERIAL_BAUD_2400
Definition: ntddser.h:148
#define SERIAL_BAUD_1200
Definition: ntddser.h:146
#define SERIAL_BAUD_4800
Definition: ntddser.h:149
#define SERIAL_BAUD_7200
Definition: ntddser.h:150
#define SERIAL_BAUD_600
Definition: ntddser.h:145
#define SERIAL_PCF_PARITY_CHECK
Definition: ntddser.h:267
#define SERIAL_BAUD_56K
Definition: ntddser.h:155
#define SERIAL_SP_PARITY
Definition: ntddser.h:255
#define SERIAL_PARITY_ODD
Definition: ntddser.h:288
#define SERIAL_BAUD_19200
Definition: ntddser.h:153
#define SERIAL_PCF_SETXCHAR
Definition: ntddser.h:269
#define SERIAL_BAUD_128K
Definition: ntddser.h:156
#define SERIAL_PARITY_EVEN
Definition: ntddser.h:289
#define SERIAL_PCF_INTTIMEOUTS
Definition: ntddser.h:271
#define SERIAL_BAUD_9600
Definition: ntddser.h:151
#define SERIAL_SP_BAUD
Definition: ntddser.h:256
#define SERIAL_PARITY_NONE
Definition: ntddser.h:287
#define SERIAL_PARITY_SPACE
Definition: ntddser.h:291
#define SERIAL_BAUD_1800
Definition: ntddser.h:147
#define SERIAL_BAUD_115200
Definition: ntddser.h:157
#define SERIAL_STOPBITS_10
Definition: ntddser.h:284
#define SERIAL_DATABITS_6
Definition: ntddser.h:277
#define SERIAL_DATABITS_8
Definition: ntddser.h:279
#define SERIAL_PCF_RTSCTS
Definition: ntddser.h:265
#define SERIAL_SP_PARITY_CHECK
Definition: ntddser.h:260
#define SERIAL_BAUD_57600
Definition: ntddser.h:158
#define SERIAL_DATABITS_7
Definition: ntddser.h:278
#define SERIAL_BAUD_300
Definition: ntddser.h:144
#define SERIAL_STOPBITS_20
Definition: ntddser.h:286
#define SERIAL_SP_SERIALCOMM
Definition: ntddser.h:417

Referenced by SerialDeviceControl().

◆ SerialGetCommStatus()

static NTSTATUS SerialGetCommStatus ( OUT PSERIAL_STATUS  pSerialStatus,
IN PSERIAL_DEVICE_EXTENSION  DeviceExtension 
)
static

Definition at line 241 of file devctrl.c.

244{
245 KIRQL Irql;
246
247 ASSERT(pSerialStatus);
248 RtlZeroMemory(pSerialStatus, sizeof(SERIAL_STATUS));
249
250 pSerialStatus->Errors = 0;
251 if (DeviceExtension->BreakInterruptErrorCount)
252 pSerialStatus->Errors |= SERIAL_ERROR_BREAK;
253 if (DeviceExtension->SerialPerfStats.FrameErrorCount)
254 pSerialStatus->Errors |= SERIAL_ERROR_FRAMING;
255 if (DeviceExtension->SerialPerfStats.SerialOverrunErrorCount)
256 pSerialStatus->Errors |= SERIAL_ERROR_OVERRUN;
257 if (DeviceExtension->SerialPerfStats.BufferOverrunErrorCount)
258 pSerialStatus->Errors |= SERIAL_ERROR_QUEUEOVERRUN;
259 if (DeviceExtension->SerialPerfStats.ParityErrorCount)
260 pSerialStatus->Errors |= SERIAL_ERROR_PARITY;
261
262 pSerialStatus->HoldReasons = 0; /* FIXME */
263
264 KeAcquireSpinLock(&DeviceExtension->InputBufferLock, &Irql);
265 pSerialStatus->AmountInInQueue = (DeviceExtension->InputBuffer.WritePosition + DeviceExtension->InputBuffer.Length
266 - DeviceExtension->InputBuffer.ReadPosition) % DeviceExtension->InputBuffer.Length;
267 KeReleaseSpinLock(&DeviceExtension->InputBufferLock, Irql);
268
269 KeAcquireSpinLock(&DeviceExtension->OutputBufferLock, &Irql);
270 pSerialStatus->AmountInOutQueue = (DeviceExtension->OutputBuffer.WritePosition + DeviceExtension->OutputBuffer.Length
271 - DeviceExtension->OutputBuffer.ReadPosition) % DeviceExtension->OutputBuffer.Length;
272 KeReleaseSpinLock(&DeviceExtension->OutputBufferLock, Irql);
273
274 pSerialStatus->EofReceived = FALSE; /* always FALSE */
275 pSerialStatus->WaitForImmediate = FALSE; /* always FALSE */
276
277 return STATUS_SUCCESS;
278}
#define FALSE
Definition: types.h:117
#define SERIAL_ERROR_QUEUEOVERRUN
Definition: ntddser.h:401
#define SERIAL_ERROR_BREAK
Definition: ntddser.h:398
#define SERIAL_ERROR_FRAMING
Definition: ntddser.h:399
#define SERIAL_ERROR_PARITY
Definition: ntddser.h:402
#define SERIAL_ERROR_OVERRUN
Definition: ntddser.h:400

Referenced by SerialDeviceControl().

◆ SerialGetPerfStats()

static BOOLEAN NTAPI SerialGetPerfStats ( IN PVOID  SynchronizeContext)
static

Definition at line 176 of file devctrl.c.

177{
179 PSERIAL_DEVICE_EXTENSION pDeviceExtension;
180
181 ASSERT(pIrp);
183
184 /*
185 * we assume buffer is big enough to hold SerialPerfStats structure
186 * caller must verify this
187 */
188 RtlCopyMemory(pIrp->AssociatedIrp.SystemBuffer,
189 &pDeviceExtension->SerialPerfStats,
190 sizeof(SERIALPERF_STATS));
191 return TRUE;
192}
FxIrp * pIrp
PVOID DeviceExtension
Definition: env_spec_w32.h:418
PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:3223
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263

Referenced by SerialDeviceControl().

◆ SerialGetUserBuffers()

static VOID SerialGetUserBuffers ( IN PIRP  Irp,
IN ULONG  IoControlCode,
OUT PVOID BufferIn,
OUT PVOID BufferOut 
)
static

Definition at line 17 of file devctrl.c.

22{
23 ASSERT(Irp);
24 ASSERT(BufferIn);
25 ASSERT(BufferOut);
26
28 {
29 case METHOD_BUFFERED:
30 *BufferIn = *BufferOut = Irp->AssociatedIrp.SystemBuffer;
31 break;
34 *BufferIn = Irp->AssociatedIrp.SystemBuffer;
35 *BufferOut = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority);
36 break;
37 case METHOD_NEITHER:
38 *BufferIn = IoGetCurrentIrpStackLocation(Irp)->Parameters.DeviceIoControl.Type3InputBuffer;
39 *BufferOut = Irp->UserBuffer;
40 break;
41 default:
42 /* Should never happen */
43 *BufferIn = NULL;
44 *BufferOut = NULL;
45 break;
46 }
47}
@ NormalPagePriority
Definition: imports.h:56
#define METHOD_NEITHER
Definition: nt_native.h:597
#define METHOD_OUT_DIRECT
Definition: nt_native.h:596
#define METHOD_BUFFERED
Definition: nt_native.h:594
#define METHOD_IN_DIRECT
Definition: nt_native.h:595
#define IO_METHOD_FROM_CTL_CODE(ctlCode)
Definition: devctrl.c:14
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:3128
#define MmGetSystemAddressForMdlSafe(_Mdl, _Priority)

Referenced by SerialDeviceControl().

◆ SerialSetBaudRate()

NTSTATUS NTAPI SerialSetBaudRate ( IN PSERIAL_DEVICE_EXTENSION  DeviceExtension,
IN ULONG  NewBaudRate 
)

Definition at line 50 of file devctrl.c.

53{
54 ULONG BaudRate;
56 PUCHAR ComPortBase = ULongToPtr(DeviceExtension->BaseAddress);
58
59 if (NewBaudRate == 0)
61
62 divisor = (USHORT)(BAUD_CLOCK / (CLOCKS_PER_BIT * NewBaudRate));
63 BaudRate = BAUD_CLOCK / (CLOCKS_PER_BIT * divisor);
64
65 Status = IoAcquireRemoveLock(&DeviceExtension->RemoveLock, ULongToPtr(DeviceExtension->ComPort));
66 if (NT_SUCCESS(Status))
67 {
68 UCHAR Lcr;
69 TRACE_(SERIAL, "SerialSetBaudRate(COM%lu, %lu Bauds)\n", DeviceExtension->ComPort, BaudRate);
70 /* Set Bit 7 of LCR to expose baud registers */
71 Lcr = READ_PORT_UCHAR(SER_LCR(ComPortBase));
72 WRITE_PORT_UCHAR(SER_LCR(ComPortBase), Lcr | SR_LCR_DLAB);
73 /* Write the baud rate */
74 WRITE_PORT_UCHAR(SER_DLL(ComPortBase), divisor & 0xff);
75 WRITE_PORT_UCHAR(SER_DLM(ComPortBase), divisor >> 8);
76 /* Switch back to normal registers */
77 WRITE_PORT_UCHAR(SER_LCR(ComPortBase), Lcr);
78
79 IoReleaseRemoveLock(&DeviceExtension->RemoveLock, ULongToPtr(DeviceExtension->ComPort));
80 }
81
82 if (NT_SUCCESS(Status))
83 DeviceExtension->BaudRate = BaudRate;
84 return Status;
85}
#define BAUD_CLOCK
Definition: serial.h:105
#define SR_LCR_DLAB
Definition: serial.h:148
#define CLOCKS_PER_BIT
Definition: serial.h:106
#define SER_DLL(x)
Definition: serial.h:111
#define SER_DLM(x)
Definition: serial.h:119
#define SER_LCR(x)
Definition: serial.h:135
GLuint divisor
Definition: glext.h:6313
#define READ_PORT_UCHAR(p)
Definition: pc98vid.h:22
unsigned short USHORT
Definition: pedump.c:61

Referenced by SerialDeviceControl(), and SerialPnpStartDevice().

◆ SerialSetLineControl()

NTSTATUS NTAPI SerialSetLineControl ( IN PSERIAL_DEVICE_EXTENSION  DeviceExtension,
IN PSERIAL_LINE_CONTROL  NewSettings 
)

Definition at line 88 of file devctrl.c.

91{
92 PUCHAR ComPortBase;
93 UCHAR Lcr = 0;
95
96 ASSERT(DeviceExtension);
97 ASSERT(NewSettings);
98
99 TRACE_(SERIAL, "SerialSetLineControl(COM%lu, Settings { %lu %lu %lu })\n",
100 DeviceExtension->ComPort, NewSettings->StopBits, NewSettings->Parity, NewSettings->WordLength);
101
102 /* Verify parameters */
103 switch (NewSettings->WordLength)
104 {
105 case 5: Lcr |= SR_LCR_CS5; break;
106 case 6: Lcr |= SR_LCR_CS6; break;
107 case 7: Lcr |= SR_LCR_CS7; break;
108 case 8: Lcr |= SR_LCR_CS8; break;
109 default: return STATUS_INVALID_PARAMETER;
110 }
111
112 if (NewSettings->WordLength < 5 || NewSettings->WordLength > 8)
114
115 switch (NewSettings->Parity)
116 {
117 case NO_PARITY: Lcr |= SR_LCR_PNO; break;
118 case ODD_PARITY: Lcr |= SR_LCR_POD; break;
119 case EVEN_PARITY: Lcr |= SR_LCR_PEV; break;
120 case MARK_PARITY: Lcr |= SR_LCR_PMK; break;
121 case SPACE_PARITY: Lcr |= SR_LCR_PSP; break;
122 default: return STATUS_INVALID_PARAMETER;
123 }
124
125 switch (NewSettings->StopBits)
126 {
127 case STOP_BIT_1:
128 Lcr |= SR_LCR_ST1;
129 break;
130 case STOP_BITS_1_5:
131 if (NewSettings->WordLength != 5)
133 Lcr |= SR_LCR_ST2;
134 break;
135 case STOP_BITS_2:
136 if (NewSettings->WordLength < 6 || NewSettings->WordLength > 8)
138 Lcr |= SR_LCR_ST2;
139 break;
140 default:
142 }
143
144 /* Update current parameters */
145 ComPortBase = ULongToPtr(DeviceExtension->BaseAddress);
146 Status = IoAcquireRemoveLock(&DeviceExtension->RemoveLock, ULongToPtr(DeviceExtension->ComPort));
147 if (!NT_SUCCESS(Status))
148 return Status;
149 WRITE_PORT_UCHAR(SER_LCR(ComPortBase), Lcr);
150
151 /* Read junk out of RBR */
152 READ_PORT_UCHAR(SER_RBR(ComPortBase));
153 IoReleaseRemoveLock(&DeviceExtension->RemoveLock, ULongToPtr(DeviceExtension->ComPort));
154
155 if (NT_SUCCESS(Status))
156 DeviceExtension->SerialLineControl = *NewSettings;
157
158 return Status;
159}
#define SR_LCR_ST2
Definition: serial.h:141
#define SR_LCR_PMK
Definition: serial.h:145
#define SR_LCR_PSP
Definition: serial.h:146
#define SR_LCR_CS8
Definition: serial.h:139
#define SR_LCR_ST1
Definition: serial.h:140
#define SR_LCR_CS6
Definition: serial.h:137
#define SR_LCR_CS7
Definition: serial.h:138
#define SER_RBR(x)
Definition: serial.h:109
#define SR_LCR_PNO
Definition: serial.h:142
#define SR_LCR_CS5
Definition: serial.h:136
#define SR_LCR_POD
Definition: serial.h:143
#define SR_LCR_PEV
Definition: serial.h:144
#define STOP_BITS_2
Definition: serial.c:87
#define EVEN_PARITY
Definition: serial.c:91
#define NO_PARITY
Definition: serial.c:89
#define ODD_PARITY
Definition: serial.c:90
#define MARK_PARITY
Definition: ntddser.h:223
#define STOP_BIT_1
Definition: ntddser.h:215
#define SPACE_PARITY
Definition: ntddser.h:224
#define STOP_BITS_1_5
Definition: ntddser.h:216

Referenced by SerialDeviceControl(), and SerialPnpStartDevice().