📄 ser_card.c
字号:
DEBUGMSG(ZONE_INIT|ZONE_ERROR,
(TEXT("SC_INIT: RegQueryValueEx(%s) Val = %d\r\n"),
DEVLOAD_SOCKET_VALNAME, hCardSock));
// When we finish with registry, be sure to close it
RegCloseKey(ActiveKey);
// OK, we got the handle from the registry, return it
*pCardSock = hCardSock;
return (TRUE);
}
#define RESET_DELAY_VALNAME TEXT("ResetDelay")
#define NOSCRATCHPAD_VALNAME TEXT("NoScratchPad")
// For some cards we store special overrides in the registry.
// This routine reads them all in, or sets the default if the
// value is not in the registry.
VOID
GetRegistryData(ULONG Identifier, PSER_CARD_INFO pHWHead)
{
HKEY ActiveKey;
DWORD status, ValType, ValLen;
DWORD ResetDelay = 0;
DWORD NoScratchPad = 0;
TCHAR IdStr[300]; // Should be a defined constant??
status = RegOpenKeyEx(HKEY_LOCAL_MACHINE,(LPCWSTR)Identifier,
0,0,&ActiveKey);
if ( status ) {
DEBUGMSG(ZONE_INIT|ZONE_ERROR,
(TEXT("SC_INIT - RegOpenKeyEx(%s) returned %d!!!\r\n"),
(LPCWSTR)Identifier,status));
goto GRD_Exit;
}
// Open the Key of the currently active device
ValLen = sizeof(IdStr);
status = RegQueryValueEx(ActiveKey,DEVLOAD_DEVKEY_VALNAME,
NULL,&ValType,(PUCHAR)IdStr,&ValLen);
if ( status != ERROR_SUCCESS ) {
DEBUGMSG(ZONE_INIT|ZONE_ERROR,
(TEXT("SC_INIT: RegQueryValueEx(%s) returned %d\r\n"),
DEVLOAD_DEVKEY_VALNAME, status));
RegCloseKey(ActiveKey);
goto GRD_Exit;
}
RegCloseKey(ActiveKey);
IdStr[300-1]=0;// Make sure it proper terminated.
// Now, see if we have info for this device in registry
status = RegOpenKeyEx(HKEY_LOCAL_MACHINE,IdStr,0,0,&ActiveKey);
if ( status ) {
DEBUGMSG(ZONE_INIT|ZONE_ERROR,
(TEXT("SC_INIT - RegOpenKeyEx(%s) returned %d!!!\r\n"),
IdStr,status));
} else {
// Read parameter from registry that specifies an interval to sleep
// upon a card reset. This is for some PCMCIA cards (AT&T, USR)
// which will not function correctly otherwise. If registry entry
// is not present, return 0 (no delay).
ValLen = sizeof(ResetDelay);
status = RegQueryValueEx( ActiveKey,RESET_DELAY_VALNAME,
NULL,&ValType,(PUCHAR)&ResetDelay,&ValLen);
if ( status != ERROR_SUCCESS ) {
DEBUGMSG(ZONE_INIT|ZONE_ERROR,
(TEXT("SC_INIT: RegQueryValueExs(%s) returned %d\r\n"),
RESET_DELAY_VALNAME,status));
ResetDelay = 300;
}
// Get scratch pad register option. This is required
// because some modems don't actually have a scratch
// pad register even though they appear to be a 16550
// in every other respect.
ValLen = sizeof(NoScratchPad);
status = RegQueryValueEx( ActiveKey,NOSCRATCHPAD_VALNAME,
NULL,&ValType,(PUCHAR)&NoScratchPad,&ValLen);
if ( status != ERROR_SUCCESS ) {
DEBUGMSG(ZONE_INIT|ZONE_ERROR,
(TEXT("SC_INIT: RegQueryValueExs(%s) returned %d\r\n"),
NOSCRATCHPAD_VALNAME,status));
}
RegCloseKey(ActiveKey);
}
GRD_Exit:
if ( NoScratchPad )
pHWHead->NoScratchPad = TRUE;
pHWHead->ResetDelay = ResetDelay;
DEBUGMSG(ZONE_INIT,(TEXT("SC_INIT: ResetDelay == %d ms, NoScratchPad = 0x%X\n\r"),
ResetDelay, NoScratchPad));
return;
}
BOOL
InitPCMCIACard( PSER_CARD_INFO pHWHead,
PVOID pMddHead )
{
CARD_CONFIG_INFO ConfigInfo;
PCARD_CONFIG_INFO pConfigInfo = &ConfigInfo;
UCHAR ConfigNum;
UINT32 IOAddress;
UINT32 IOLen;
UINT32 Vcc;
CARD_REGISTER_PARMS Parms;
CARD_WINDOW_PARMS WinParms; // For CardRequestWindow
STATUS status;
DEBUGMSG (ZONE_INIT, (TEXT("SerCard: Attempting to register\r\n")));
Parms.fEventMask = 0xffff;
Parms.uClientData = (UINT32)pHWHead;
//
// Register as an IO client.
//
Parms.fAttributes = CLIENT_ATTR_IO_DRIVER | CLIENT_ATTR_NOTIFY_SHARED |
CLIENT_ATTR_NOTIFY_EXCLUSIVE;
pHWHead->hCardClient = CallCardServices(CardRegisterClient) (CallBackFn, &Parms);
DEBUGMSG (ZONE_INIT, ( TEXT("head @ 1 = 0x%X\r\n"), pHWHead));
if ( pHWHead->hCardClient == 0 ) {
DEBUGMSG (ZONE_INIT, (
TEXT("SerCard: RegisterClient - failed (%d)\r\n"),
GetLastError()));
return (FALSE);
}
// Request the I/O window before we reset, so the pcmcia driver doesn't
// power down the socket after CE_REGISTER_COMPLETE when it sees no clients
// using the card.
WinParms.fAttributes = WIN_ATTR_IO_SPACE;
WinParms.uWindowSize = 16;
WinParms.fAccessSpeed = WIN_SPEED_USE_WAIT;
WinParms.hSocket = pHWHead->hCardSock;
pHWHead->hCardWindow = CallCardServices(CardRequestWindow) (pHWHead->hCardClient, &WinParms);
if ( pHWHead->hCardWindow == NULL ) {
DEBUGMSG (ZONE_INIT | ZONE_ERROR,
(TEXT("SerCard : CardRequestWindow failed %d\n"),
GetLastError()));
CallCardServices(CardDeregisterClient) (pHWHead->hCardClient);
return (FALSE);
}
CallCardServices(CardResetFunction) (pHWHead->hCardClient, pHWHead->hCardSock);
#ifdef FORCE_MODEM
ConfigNum = 32;
IOAddress = 0x3f8;
IOLen = 7;
pHWHead->pCardIOWin = CallCardServices(CardMapWindow) ( pHWHead->hCardWindow, IOAddress, IOLen, &(pHWHead->IO_Granularity) );
DEBUGMSG (ZONE_INIT,
(TEXT("SerCard : Using Configuration %d (IOAddr 0x%X, len %d)\n"),
ConfigNum, IOAddress, IOLen ));
// And then use CardRequestConfig to power up
ConfigInfo.hSocket = pHWHead->hCardSock;
ConfigInfo.fAttributes = CFG_ATTR_VALID_CLIENT | CFG_ATTR_IRQ_STEERING;
ConfigInfo.uVcc = 50;
ConfigInfo.uVpp1 = 0;
ConfigInfo.uVpp2 = 0;
ConfigInfo.fInterfaceType = CFG_IFACE_MEMORY_IO;
ConfigInfo.fRegisters = CFG_REGISTER_EXREG | CFG_REGISTER_STATUS | CFG_REGISTER_CONFIG;
ConfigInfo.uStatusReg = FCR_FCSR_REQUIRED_BITS | FCR_FCSR_AUDIO;
ConfigInfo.uPinReg = 0;
ConfigInfo.uCopyReg = 0;
ConfigInfo.uConfigReg = 0x20;
ConfigInfo.uExtendedStatus = 0;
ConfigInfo.fExtRegisters = CFG_EXREGISTER_IOBASE0 | CFG_EXREGISTER_IOBASE1;
ConfigInfo.IOBase[0] = (IOAddress & 0xff);
ConfigInfo.IOBase[1] = ((IOAddress >> 8) & 0xff);
#else
if ( FindComConfig(pHWHead->hCardSock, &ConfigNum, &IOAddress, &IOLen, &Vcc,
pHWHead->hCardWindow, &pHWHead->pCardIOWin, &pHWHead->IO_Granularity) == FALSE ) {
DEBUGMSG (ZONE_INIT | ZONE_ERROR,
(TEXT("SerCard : No valid PC card configuration found\n")));
CallCardServices(CardDeregisterClient) (pHWHead->hCardClient);
return (FALSE);
}
DEBUGMSG (ZONE_INIT,
(TEXT("SerCard : Using Configuration %d (IOAddr 0x%X, len %d)\n"),
ConfigNum, IOAddress, IOLen ));
// And then use CardRequestConfig to power up
ConfigInfo.hSocket = pHWHead->hCardSock;
ConfigInfo.fAttributes = CFG_ATTR_VALID_CLIENT | CFG_ATTR_IRQ_STEERING;
ConfigInfo.uVcc = Vcc;
ConfigInfo.uVpp1 = 0;
ConfigInfo.uVpp2 = 0;
ConfigInfo.fInterfaceType = CFG_IFACE_MEMORY_IO;
ConfigInfo.fRegisters = CFG_REGISTER_EXREG | CFG_REGISTER_STATUS | CFG_REGISTER_CONFIG;
ConfigInfo.uStatusReg = FCR_FCSR_REQUIRED_BITS | FCR_FCSR_AUDIO;
ConfigInfo.uPinReg = 0;
ConfigInfo.uCopyReg = 0;
ConfigInfo.uConfigReg = ConfigNum;
ConfigInfo.uExtendedStatus = 0;
ConfigInfo.fExtRegisters = CFG_EXREGISTER_IOBASE0 | CFG_EXREGISTER_IOBASE1;
ConfigInfo.IOBase[0] = (IOAddress & 0xff);
ConfigInfo.IOBase[1] = ((IOAddress >> 8) & 0xff);
#endif
DEBUGMSG (ZONE_INIT, ( TEXT("head @ 2 = 0x%X\r\n"), pHWHead));
DEBUGMSG (ZONE_INIT,
(TEXT("SerCard : Mapping Window 0x%X at 0x%X, len %d, Granularity %d\n"),
pHWHead->hCardWindow, IOAddress, IOLen, pHWHead->IO_Granularity ));
// Now we know all the attributes, lets map the IO space
if ( pHWHead->pCardIOWin == NULL ) {
DEBUGMSG (ZONE_INIT | ZONE_ERROR,
(TEXT("SerCard : CardMapWindow failed %d\n"),
GetLastError()));
CallCardServices(CardDeregisterClient) (pHWHead->hCardClient);
return (FALSE);
} else {
DEBUGMSG (ZONE_INIT,
(TEXT("SerCard : CardMapWindow pCardIOWin = 0x%X\n"),
pHWHead->pCardIOWin));
}
status = CallCardServices(CardRequestConfiguration) (pHWHead->hCardClient, pConfigInfo);
if ( status ) {
DEBUGMSG (ZONE_INIT | ZONE_ERROR,
(TEXT("SerCard : CardRequestConfiguration returned %d\n"),
status) );
CallCardServices(CardDeregisterClient) (pHWHead->hCardClient);
return (FALSE);
} else
DEBUGMSG (ZONE_INIT,
(TEXT("SerCard : CardRequestConfiguration completed \n")));
return (TRUE);
}
//
// PVOID | SC_SetIRBaudRate | Sets Buad rate for IR interface
//
void
SC_SetIRMode(
PSER_CARD_INFO pHWHead,
BOOL UseIR // BOOL Should we use IR interface
)
{
// We don't support any IR cards.
}
//
// PVOID | SC_SetIRBaudRate | Sets Buad rate for IR interface
//
BOOL
SC_SetIRBaudRate(
PSER_CARD_INFO pHWHead,
UINT16 baud // UINT16 what is the baud rate
)
{
// We don't support any IR cards.
return (TRUE);
}
//
// @doc OEM
// @func PVOID | SC_Init | Initializes device identified by argument.
// This routine allocates any memory required by the driver, and
// initializes a few of the fields. For PCMCIA cards, that is all
// we can do this early. Nearly everything else is done at open
// time in order to ensure that we do not power the PCMCIA card
// up nay sooner than required.
//
// @rdesc The return value is a PVOID to be passed back into the other
// SC_??? entrypoints as a device handle.
//
PVOID
SC_Init(
ULONG Identifier, // @parm Device identifier.
PVOID pMddHead, // @parm First argument to mdd callbacks.
PHWOBJ pHWObj // @parm Pointer to our own HW OBJ for this device
)
{
PSER_CARD_INFO pHWHead;
CARD_SOCKET_HANDLE hCardSock;
DEBUGMSG (ZONE_FUNCTION, (TEXT("+SC_INIT\r\n") ));
DEBUGMSG (ZONE_INIT, (TEXT("Initializing modem\r\n") ));
// First make sure this card is valid
if ( !GetCardHandle( Identifier, &hCardSock ) )
return (UINT32)NULL;
// Allocate for our main data structure and one of it's fields.
pHWHead = (PSER_CARD_INFO)LocalAlloc( LMEM_ZEROINIT|LMEM_FIXED ,
sizeof(SER_CARD_INFO) );
if ( !pHWHead )
return (UINT32)NULL;
// OK, Now make sure PCMCIA.DLL is available
if ( ! InitCardServices() ) {
LocalFree(pHWHead);
return (UINT32)NULL;
}
pHWHead->pMddHead = pMddHead;
pHWHead->pHWObj = pHWObj;
pHWHead->hCardSock = hCardSock; // GetCardHandle read this from registry
pHWHead->cOpenCount = 0;
pHWHead->fPowerCycle = FALSE;
// Set up our Comm Properties data
pHWHead->CommProp.wPacketLength = 0xffff;
pHWHead->CommProp.wPacketVersion = 0xffff;
pHWHead->CommProp.dwServiceMask = SP_SERIALCOMM;
pHWHead->CommProp.dwReserved1 = 0;
pHWHead->CommProp.dwMaxTxQueue = 16;
pHWHead->CommProp.dwMaxRxQueue = 16;
pHWHead->CommProp.dwMaxBaud = BAUD_115200;
pHWHead->CommProp.dwProvSubType = PST_RS232;
pHWHead->CommProp.dwProvCapabilities =
PCF_DTRDSR | PCF_RLSD | PCF_RTSCTS |
PCF_SETXCHAR |
PCF_INTTIMEOUTS |
PCF_PARITY_CHECK |
PCF_SPECIALCHARS |
PCF_TOTALTIMEOUTS |
PCF_XONXOFF;
pHWHead->CommProp.dwSettableBaud =
BAUD_075 | BAUD_110 | BAUD_150 | BAUD_300 | BAUD_600 |
BAUD_1200 | BAUD_1800 | BAUD_2400 | BAUD_4800 |
BAUD_7200 | BAUD_9600 | BAUD_14400 |
BAUD_19200 | BAUD_38400 | BAUD_56K | BAUD_128K |
BAUD_115200 | BAUD_57600 | BAUD_USER;
pHWHead->CommProp.dwSettableParams =
SP_BAUD | SP_DATABITS | SP_HANDSHAKING | SP_PARITY |
SP_PARITY_CHECK | SP_RLSD | SP_STOPBITS;
pHWHead->CommProp.wSettableData =
DATABITS_5 | DATABITS_6 | DATABITS_7 | DATABITS_8;
pHWHead->CommProp.wSettableStopParity =
STOPBITS_10 | STOPBITS_20 |
PARITY_NONE | PARITY_ODD | PARITY_EVEN | PARITY_SPACE |
PARITY_MARK;
// Read reset delay and other parameters from registry
GetRegistryData( Identifier, pHWHead );
DEBUGMSG (ZONE_FUNCTION, (TEXT("-SC_INIT\r\n") ));
return (pHWHead);
}
//
// @doc OEM
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -