void com_putchar(char ch) { if (ch == '\n') { com_putchar('\r'); } while ((READ_PORT_UCHAR (pv(SER_LSR(COM_BASE))) & SR_LSR_TBE) == 0); WRITE_PORT_UCHAR(pv(SER_THR(COM_BASE)), ch); }
VOID NTAPI SerialSendByte( IN PKDPC Dpc, IN PVOID pDeviceExtension, // real type PSERIAL_DEVICE_EXTENSION IN PVOID Unused1, IN PVOID Unused2) { PSERIAL_DEVICE_EXTENSION DeviceExtension; PUCHAR ComPortBase; UCHAR Byte; KIRQL Irql; UCHAR IER; NTSTATUS Status; DeviceExtension = (PSERIAL_DEVICE_EXTENSION)pDeviceExtension; ComPortBase = ULongToPtr(DeviceExtension->BaseAddress); KeAcquireSpinLock(&DeviceExtension->OutputBufferLock, &Irql); while (!IsCircularBufferEmpty(&DeviceExtension->OutputBuffer) && READ_PORT_UCHAR(SER_LSR(ComPortBase)) & SR_LSR_THR_EMPTY) { Status = PopCircularBufferEntry(&DeviceExtension->OutputBuffer, &Byte); if (!NT_SUCCESS(Status)) break; WRITE_PORT_UCHAR(SER_THR(ComPortBase), Byte); INFO_(SERIAL, "Byte sent to COM%lu: 0x%02x\n", DeviceExtension->ComPort, Byte); DeviceExtension->SerialPerfStats.TransmittedCount++; } if (!IsCircularBufferEmpty(&DeviceExtension->OutputBuffer)) { /* allow new interrupts */ IER = READ_PORT_UCHAR(SER_IER(ComPortBase)); WRITE_PORT_UCHAR(SER_IER(ComPortBase), IER | SR_IER_THR_EMPTY); } KeReleaseSpinLock(&DeviceExtension->OutputBufferLock, Irql); }