I found some old sources from me where I detect the IRQ and the type (8250, 16450, 16550, 16550A) of a COM port. I converted the sources to the ReactOS style.
The detection if there is a COM port at all is made by inverting all bits of the LCR twice:
Code: Select all
BYTE Lcr, TestLcr;
BYTE OldScr, Scr5A, ScrA5;
BOOLEAN FifoEnabled;
BYTE NewFifoStatus;
Lcr = READ_PORT_UCHAR(SER_LCR(BaseAddress));
WRITE_PORT_UCHAR(BaseAddress, (BYTE) (Lcr ^ 0xFF));
TestLcr = (BYTE) (READ_PORT_UCHAR(SER_LCR(BaseAddress)) ^ 0xFF);
WRITE_PORT_UCHAR(BaseAddress, Lcr);
/* Accessing the LCR must work for a usable serial port */
if (TestLcr!=Lcr)
return SER_TYPE_NONE;
/* Ensure that all following accesses are done as required */
READ_PORT_UCHAR(SER_RBR(BaseAddress));
READ_PORT_UCHAR(SER_IER(BaseAddress));
READ_PORT_UCHAR(SER_IIR(BaseAddress));
READ_PORT_UCHAR(SER_LCR(BaseAddress));
READ_PORT_UCHAR(SER_MCR(BaseAddress));
READ_PORT_UCHAR(SER_LSR(BaseAddress));
READ_PORT_UCHAR(SER_MSR(BaseAddress));
READ_PORT_UCHAR(SER_SCR(BaseAddress));
/* Test scratch pad */
OldScr = READ_PORT_UCHAR(SER_SCR(BaseAddress));
WRITE_PORT_UCHAR(SER_SCR(BaseAddress), 0x5A);
Scr5A = READ_PORT_UCHAR(SER_SCR(BaseAddress));
WRITE_PORT_UCHAR(SER_SCR(BaseAddress), 0xA5);
ScrA5 = READ_PORT_UCHAR(SER_SCR(BaseAddress));
WRITE_PORT_UCHAR(SER_SCR(BaseAddress), OldScr);
/* When non-functional, we have a 8250 */
if (Scr5A!=0x5A || ScrA5!=0xA5)
return SER_TYPE_8250;
FifoEnabled = (READ_PORT_UCHAR(SER_IIR(BaseAddress)) & 0x80)!=0;
WRITE_PORT_UCHAR(SER_FCR(BaseAddress), SR_FCR_ENABLE_FIFO);
NewFifoStatus = READ_PORT_UCHAR(SER_IIR(BaseAddress)) & 0xC0;
if (!FifoEnabled)
WRITE_PORT_UCHAR(SER_FCR(BaseAddress), 0);
switch (NewFifoStatus) {
case 0x00:
return SER_TYPE_16450;
case 0x80:
return SER_TYPE_16550;
}
return SER_TYPE_16550A;
Regards,
Mark