[NTFS] - Add some fixes and improvements to attribute.c from CR-123:
[reactos.git] / drivers / base / kdcom / kdserial.c
1 /*
2 * COPYRIGHT: GPL, see COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * FILE: drivers/base/kddll/kdserial.c
5 * PURPOSE: Serial communication functions for the kernel debugger.
6 * PROGRAMMER: Timo Kreuzer (timo.kreuzer@reactos.org)
7 */
8
9 #include "kddll.h"
10
11 /* FUNCTIONS ******************************************************************/
12
13 /******************************************************************************
14 * \name KdpSendBuffer
15 * \brief Sends a buffer of data to the serial KD port.
16 * \param Buffer Pointer to the data.
17 * \param Size Size of data in bytes.
18 */
19 VOID
20 NTAPI
21 KdpSendBuffer(
22 IN PVOID Buffer,
23 IN ULONG Size)
24 {
25 PUCHAR ByteBuffer = Buffer;
26
27 while (Size-- > 0)
28 {
29 KdpSendByte(*ByteBuffer++);
30 }
31 }
32
33 /******************************************************************************
34 * \name KdpReceiveBuffer
35 * \brief Receives data from the KD port and fills a buffer.
36 * \param Buffer Pointer to a buffer that receives the data.
37 * \param Size Size of data to receive in bytes.
38 * \return KDP_PACKET_RECEIVED if successful.
39 * KDP_PACKET_TIMEOUT if the receive timed out.
40 */
41 KDP_STATUS
42 NTAPI
43 KdpReceiveBuffer(
44 OUT PVOID Buffer,
45 IN ULONG Size)
46 {
47 PUCHAR ByteBuffer = Buffer;
48 UCHAR Byte;
49 KDP_STATUS Status;
50
51 while (Size-- > 0)
52 {
53 /* Try to get a byte from the port */
54 Status = KdpReceiveByte(&Byte);
55 if (Status != KDP_PACKET_RECEIVED)
56 return Status;
57
58 *ByteBuffer++ = Byte;
59 }
60
61 return KDP_PACKET_RECEIVED;
62 }
63
64
65 /******************************************************************************
66 * \name KdpReceivePacketLeader
67 * \brief Receives a packet leader from the KD port.
68 * \param PacketLeader Pointer to an ULONG that receives the packet leader.
69 * \return KDP_PACKET_RECEIVED if successful.
70 * KDP_PACKET_TIMEOUT if the receive timed out.
71 * KDP_PACKET_RESEND if a breakin byte was detected.
72 */
73 KDP_STATUS
74 NTAPI
75 KdpReceivePacketLeader(
76 OUT PULONG PacketLeader)
77 {
78 UCHAR Index = 0, Byte, Buffer[4];
79 KDP_STATUS KdStatus;
80
81 /* Set first character to 0 */
82 Buffer[0] = 0;
83
84 do
85 {
86 /* Receive a single byte */
87 KdStatus = KdpReceiveByte(&Byte);
88
89 /* Check for timeout */
90 if (KdStatus == KDP_PACKET_TIMEOUT)
91 {
92 /* Check if we already got a breakin byte */
93 if (Buffer[0] == BREAKIN_PACKET_BYTE)
94 {
95 return KDP_PACKET_RESEND;
96 }
97
98 /* Report timeout */
99 return KDP_PACKET_TIMEOUT;
100 }
101
102 /* Check if we received a byte */
103 if (KdStatus == KDP_PACKET_RECEIVED)
104 {
105 /* Check if this is a valid packet leader byte */
106 if (Byte == PACKET_LEADER_BYTE ||
107 Byte == CONTROL_PACKET_LEADER_BYTE)
108 {
109 /* Check if we match the first byte */
110 if (Byte != Buffer[0])
111 {
112 /* No, this is the new byte 0! */
113 Index = 0;
114 }
115
116 /* Store the byte in the buffer */
117 Buffer[Index] = Byte;
118
119 /* Continue with next byte */
120 Index++;
121 continue;
122 }
123
124 /* Check for breakin byte */
125 if (Byte == BREAKIN_PACKET_BYTE)
126 {
127 KDDBGPRINT("BREAKIN_PACKET_BYTE\n");
128 Index = 0;
129 Buffer[0] = Byte;
130 continue;
131 }
132 }
133
134 /* Restart */
135 Index = 0;
136 Buffer[0] = 0;
137 }
138 while (Index < 4);
139
140 /* Enable the debugger */
141 KD_DEBUGGER_NOT_PRESENT = FALSE;
142 SharedUserData->KdDebuggerEnabled |= 0x00000002;
143
144 /* Return the received packet leader */
145 *PacketLeader = *(PULONG)Buffer;
146
147 return KDP_PACKET_RECEIVED;
148 }
149
150 /* EOF */