Windows NT 4.0 source code leak
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.
 
 
 
 
 
 

328 lines
6.9 KiB

/*
* adaptec.c
*
*
*
*/
#ifndef IRMINILIB
#include "dongle.h"
/*
* The programming interface to a UART (COM serial port)
* consists of eight consecutive registers.
* These are the port offsets from the UART's base I/O address.
*/
typedef enum comPortRegOffsets {
XFER_REG_OFFSET = 0,
INT_ENABLE_REG_OFFSET = 1,
INT_ID_AND_FIFO_CNTRL_REG_OFFSET = 2,
LINE_CONTROL_REG_OFFSET = 3,
MODEM_CONTROL_REG_OFFSET = 4,
LINE_STAT_REG_OFFSET = 5,
MODEM_STAT_REG_OFFSET = 6,
SCRATCH_REG_OFFSET = 7
} comPortRegOffset;
/*
* Bits in the UART line-status register.
*/
#define LINESTAT_DATAREADY (UCHAR)(1 << 0)
#define LINESTAT_OVERRUNERROR (UCHAR)(1 << 1)
#define LINESTAT_PARITYERROR (UCHAR)(1 << 2)
#define LINESTAT_FRAMINGERROR (UCHAR)(1 << 3)
#define LINESTAT_BREAK (UCHAR)(1 << 4)
#define LINESTAT_XMIT_HOLDING_REG_EMPTY (UCHAR)(1 << 5)
#define LINESTAT_XMIT_SHIFT_AND_HOLDING_REG_EMPTY (UCHAR)(1 << 6)
#define ADAPTEC_IRDA_SPEEDS ( \
NDIS_IRDA_SPEED_2400 | \
NDIS_IRDA_SPEED_9600 | \
NDIS_IRDA_SPEED_19200 | \
NDIS_IRDA_SPEED_38400 | \
NDIS_IRDA_SPEED_57600 | \
NDIS_IRDA_SPEED_115200 \
)
/*
*************************************************************************
* AdaptecCommandMode
*************************************************************************
*
*
*/
BOOLEAN AdaptecCommandMode(UINT comBase, BOOLEAN commandModeOn)
{
UCHAR modemCntrlVal, sig;
BOOLEAN result = FALSE;
UINT i;
IRMINI_RawReadPort(comBase+MODEM_CONTROL_REG_OFFSET, &modemCntrlVal);
if (commandModeOn){
/*
* Set command mode
*/
modemCntrlVal |= 2;
modemCntrlVal &= ~1;
IRMINI_RawWritePort(comBase+MODEM_CONTROL_REG_OFFSET, modemCntrlVal);
IRMINI_StallExecution(20000);
for (i = 0; i < 10; i++){
/*
* Select the signature register
*/
IRMINI_RawWritePort(comBase+XFER_REG_OFFSET, 0xff);
IRMINI_StallExecution(20000);
IRMINI_RawReadPort(comBase+XFER_REG_OFFSET, &sig);
if (sig == 0xc3){
result = TRUE;
break;
}
else {
/*
* Read a few characters to gyrate the part
*/
UINT j;
for (j = 0; j < 3; j++){
UCHAR dummy;
IRMINI_RawReadPort(comBase+XFER_REG_OFFSET, &dummy);
}
}
}
}
else {
/*
* Set normal mode
*/
modemCntrlVal |= 3;
IRMINI_RawWritePort(comBase+MODEM_CONTROL_REG_OFFSET, modemCntrlVal);
result = TRUE;
}
IRMINI_StallExecution(20000);
return result;
}
/*
*************************************************************************
* AdaptecWriteChar
*************************************************************************
*
*
*/
BOOLEAN AdaptecWriteChar(UINT comBase, UCHAR val)
{
UINT i;
UCHAR lineStatReg;
BOOLEAN result = TRUE;
UINT confirmAttempts = 0;
/*
* Wait for ready-to-send.
*/
i = 0;
do {
IRMINI_RawReadPort(comBase+LINE_STAT_REG_OFFSET, &lineStatReg);
IRMINI_StallExecution(20000);
} while (!(lineStatReg & LINESTAT_XMIT_HOLDING_REG_EMPTY) && (++i < 4));
if (!(lineStatReg & LINESTAT_XMIT_HOLDING_REG_EMPTY)){
return FALSE;
}
/*
* Send the byte.
*/
IRMINI_RawWritePort(comBase+XFER_REG_OFFSET, val);
IRMINI_StallExecution(20000);
/*
* Confirm the write by reading back the character
*/
do {
IRMINI_StallExecution(20000);
i = 0;
do {
IRMINI_RawReadPort(comBase+LINE_STAT_REG_OFFSET, &lineStatReg);
} while (!(lineStatReg & LINESTAT_DATAREADY) && (++i < 4));
if (lineStatReg & LINESTAT_DATAREADY){
UCHAR readBackChar;
IRMINI_RawReadPort(comBase+XFER_REG_OFFSET, &readBackChar);
if (readBackChar != val){
result = FALSE;
}
}
else {
result = FALSE;
}
} while (!result && (++confirmAttempts < 5));
return result;
}
/*
*************************************************************************
* AdaptecWriteCmd
*************************************************************************
*
* Initialize UART registers
*
*/
BOOLEAN AdaptecWriteCmd(UINT comBase, UCHAR val)
{
UINT loops;
BOOLEAN result = FALSE;
/*
* Set command mode and attempt the operation 5 times.
*/
if (!AdaptecCommandMode(comBase, TRUE)){
return FALSE;
}
for (loops = 0; loops < 5; loops++){
if (AdaptecWriteChar(comBase, val)){
result = TRUE;
break;
}
else {
IRMINI_StallExecution(20000);
}
}
AdaptecCommandMode(comBase, FALSE);
return result;
}
/*
*************************************************************************
* ADAPTEC_Init
*************************************************************************
*
* NOTE: The UART speed must be set to 9600 when this function is called.
*
*/
BOOLEAN ADAPTEC_Init(UINT comBase, dongleCapabilities *caps, UINT *context)
{
/*
* Set normal (not command) mode
*/
if (!AdaptecCommandMode(comBase, FALSE)){
return FALSE;
}
/*
* Wait 2 seconds (!) for power-up. BUGBUG - reduce ???
*/
IRMINI_StallExecution(2000000);
/*
* Set speed to 9600 baud in both baud and reload registers
*/
if (!AdaptecWriteCmd(comBase, 0x30)){
return FALSE;
}
if (!AdaptecWriteCmd(comBase, 0x31)){
return FALSE;
}
/*
* Initialize the xmit and rcv control registers.
*/
if (!AdaptecWriteCmd(comBase, 0x02)){
return FALSE;
}
if (!AdaptecWriteCmd(comBase, 0x03)){
return FALSE;
}
/*
* Clear the status register and confirm the result.
*/
if (!AdaptecWriteCmd(comBase, 0x04)){
return FALSE;
}
caps->supportedSpeedsMask = ADAPTEC_IRDA_SPEEDS;
caps->turnAroundTime_usec = 5000;
caps->extraBOFsRequired = 0;
*context = 0;
return TRUE;
}
/*
*************************************************************************
* ADAPTEC_Deinit
*************************************************************************
*
*
*/
VOID ADAPTEC_Deinit(UINT comBase, UINT context)
{
UCHAR modemCntrlVal;
IRMINI_RawReadPort(comBase+MODEM_CONTROL_REG_OFFSET, &modemCntrlVal);
modemCntrlVal &= ~3;
IRMINI_RawWritePort(comBase+MODEM_CONTROL_REG_OFFSET, modemCntrlVal);
}
/*
*************************************************************************
* ADAPTEC_SetSpeed
*************************************************************************
*
* Initialize UART registers
*
* NOTE: The UART speed must be set to 9600 when this function is called.
*
*/
BOOLEAN ADAPTEC_SetSpeed(UINT comBase, UINT bitsPerSec, UINT context)
{
UCHAR code;
switch (bitsPerSec){
case 2400: code = 0x10; break;
case 9600: code = 0x30; break;
case 19200: code = 0x40; break;
case 38400: code = 0x50; break;
case 57600: code = 0x60; break;
case 115200: code = 0x70; break;
default: code = 0x30; break;
}
if (!AdaptecWriteCmd(comBase, code)){
return FALSE;
}
if (!AdaptecWriteCmd(comBase, (UCHAR)(code | 1))){
return FALSE;
}
return TRUE;
}
#endif