📄 ethdbg.c
字号:
if (StartKitl (FALSE))
fRet = DoRegisterClient (pId, ServiceName, Flags, WindowSize, pBufferPool);
LeaveCriticalSection (&KITLcs);
KITL_DEBUGMSG(ZONE_INIT,("-KITLRegisterClient(%s): Flags: %u, WindowSize: %u, BufferPool: %X\n",
ServiceName,Flags,WindowSize,pBufferPool));
return fRet;
}
static BOOL DoRegisterClient(
UCHAR *pId, // @parm [OUT] - Receives identifier to pass in to KITLSend/Recv
char *ServiceName, // @parm [IN] - Service name (NULL terminated, up to MAX_SVCNAME_LEN chars)
UCHAR Flags, // @parm [IN] - KITL_CFGFL_ flags, defined in ethdbg.h
UCHAR WindowSize, // @parm [IN] - Protocol window size (default is 8)
UCHAR *pBufferPool) // @parm [IN] - Buffer pool to use for KITL packet buffers - must be WindowSize*2*1500 bytes, unless STOP_AND_WAIT flag is set, in which
// case, need only be 2*1500 bytes. For default OS services, may be NULL.
{
KITL_CLIENT *pClient = NULL;
int i, iStart;
if (!(KITLGlobalState & KITL_ST_ADAPTER_INITIALIZED))
return FALSE;
// Validate params
if (!pId || !ServiceName || (strlen (ServiceName) > MAX_SVC_NAMELEN)) {
KITLOutputDebugString("!DoRegisterClient(%s): Invalid parameter\n",ServiceName?ServiceName: "NULL");
return FALSE;
}
if (!pBufferPool) {
KITLOutputDebugString("!DoRegisterClient(%s): Need to supply memory for buffer pool\n",ServiceName);
return FALSE;
}
if (!WindowSize || (WindowSize > KITL_MAX_WINDOW_SIZE)) {
KITLOutputDebugString("!DoRegisterClient(%s): Invalid window size %u\n",ServiceName, WindowSize);
return FALSE;
}
// Determine where to start looking
if ((i = ChkDfltSvc (ServiceName)) < 0) {
i = HASH(ServiceName[0]);
}
iStart = i;
// look for a slot in the client structure for the newly registered client
do {
if (!KITLClients[i]) {
pClient = NewClient ((UCHAR) i, ServiceName, TRUE);
} else if (strcmp (KITLClients[i]->ServiceName, ServiceName) == 0) {
// same service has registered before
if (!(KITLClients[i]->State & (KITL_CLIENT_REGISTERED|KITL_CLIENT_REGISTERING))) {
pClient = KITLClients[i];
} else if (!(Flags & KITL_CFGFL_MULTIINST)) {
// duplicate registration -- fail the call
break;
}
}
if (pClient) {
pClient->State |= KITL_CLIENT_REGISTERING;
} else if (i < NUM_DFLT_KITL_SERVICES) {
// no dup-registration for default services
break;
} else if (MAX_KITL_CLIENTS == ++ i) {
i = NUM_DFLT_KITL_SERVICES;
}
} while (!pClient && (i != iStart));
if (!pClient) {
if (i == iStart) {
KITLOutputDebugString("!KITLRegisterClient(%s): No available client structs\n",ServiceName);
} else {
KITLOutputDebugString("!KITLRegisterClient(%s): Client already registered (Id: %u)\n",ServiceName,i);
}
return FALSE;
}
// Set up client struct (ServiceId and State field are already valid)
strcpy(pClient->ServiceName,ServiceName);
pClient->State |= KITL_CLIENT_REGISTERING;
pClient->pTxBufferPool = MapPtr(pBufferPool);
pClient->RxWinEnd = WindowSize;
pClient->WindowSize = WindowSize;
pClient->pRxBufferPool = pClient->pTxBufferPool + (WindowSize * KITL_MTU);
pClient->CfgFlags = Flags;
// The service Id also functions as a client handle
*pId = pClient->ServiceId;
// KDBG is special case - it always runs with interrupts off and can't make sys calls,
// so leave it in polling mode.
if ((KITLGlobalState & KITL_ST_MULTITHREADED) && (pClient->ServiceId != KITL_SVC_KDBG))
if (!RegisterClientPart2(*pId))
return FALSE;
#if 0
//
// we no long wait for client to connect to desktop during registration. The config exchange
// will occur on the first KITLSend/KITLRecv call.
//
// Connect to desktop
if (!ExchangeConfig(pClient))
return FALSE;
pClient->State &= ~KITL_CLIENT_REGISTERING;
pClient->State |= KITL_CLIENT_REGISTERED;
#endif
// waiting for config exchange now
pClient->State |= KITL_WAIT_CFG;
// just send a config message to the desktop. Okay if lost since we'll call into
// Exchange config in case the client isn't connected when we call KITLSend/KITLRecv
SendConfig (pClient, FALSE);
return TRUE;
}
/* RegisterClientPart2
*
* Finish initializing client data
*/
static BOOL
RegisterClientPart2(UCHAR Id)
{
KITL_CLIENT *pClient = KITLClients[Id];
CALLSTACK cstk;
DEBUGCHK (pClient);
KITL_DEBUGMSG(ZONE_INIT,("+RegisterClientPart2: Id 0x%X\n",Id));
// if default clients switch to kernel, let kernel own all sync. objects in default clients
if (IS_DFLT_SVC(Id))
SwitchToKernel(&cstk);
// Start retransmission timer thread if required
if (!(KITLGlobalState & KITL_ST_TIMER_INIT)) {
InitializeCriticalSection(&TimerListCS);
if ((hTimerThread = CreateKernelThread((LPTHREAD_START_ROUTINE)TimerThread,0, (WORD)g_dwKITLTimerThreadPriority, 0)) == NULL) {
DeleteCriticalSection(&TimerListCS);
KITLOutputDebugString("Error creating timer thread\n");
return FALSE;
}
KITLGlobalState |= KITL_ST_TIMER_INIT;
}
InitializeCriticalSection(&pClient->ClientCS);
if (!(pClient->evCfg = CreateEvent(NULL,FALSE,FALSE,NULL))) {
DeleteCriticalSection(&pClient->ClientCS);
KITLOutputDebugString("!RegisterClient: Error in CreateEvent()\n");
return FALSE;
}
if (!(pClient->evRecv = CreateEvent(NULL,FALSE,FALSE,NULL))) {
DeleteCriticalSection(&pClient->ClientCS);
CloseHandle(pClient->evCfg);
KITLOutputDebugString("!RegisterClient: Error in CreateEvent()\n");
return FALSE;
}
// Manual reset event, initially signalled
if (!(pClient->evTxFull = CreateEvent(NULL,TRUE,TRUE,NULL))) {
DeleteCriticalSection(&pClient->ClientCS);
CloseHandle(pClient->evCfg);
CloseHandle(pClient->evRecv);
KITLOutputDebugString("!RegisterClient: Error in CreateEvent()\n");
return FALSE;
}
// Set up process permissions, for accessing buffers. Only need to do this
// for non-default services.
if (!IS_DFLT_SVC(Id))
pClient->ProcPerms = SC_GetCurrentPermissions();
else
SwitchBack();
// If we need to turn on HW interrupts, do so now
//if ((KITLGlobalState & KITL_ST_IST_STARTED) && !(KITLGlobalState & KITL_ST_INT_ENABLED))
// EnableInts();
pClient->State |= KITL_USE_SYSCALLS;
KITL_DEBUGMSG(ZONE_INIT,("-RegisterClientPart2\n"));
return TRUE;
}
/*
* @func BOOL | KITLDeregisterClient | Deregister debug Ethernet (KITL) client.
* @rdesc Return TRUE if Id is a valid KITL client Id.
* @comm This function will deregister an KITL client. Note that
* no indication is given to the peer that we have disconnected, so if an
* application needs to send this information, it must be done at a higher layer.
* @xref <f KITLRegisterClient>
*/
BOOL
KITLDeregisterClient(
UCHAR Id) // @parm [IN] - KITL client id.
{
KITL_CLIENT *pClient;
BOOL fRet = FALSE;
UCHAR State;
KITL_DEBUGMSG(ZONE_INIT,("+KITLDeregisterClient, Id:%u\n", Id));
DEBUGCHK (!InSysCall ());
if (!IS_VALID_ID(Id)) {
KITL_DEBUGMSG(ZONE_WARNING, ("KITLDeregisterClient: invalid ID[%u]\n", Id));
return FALSE;
}
EnterCriticalSection (&KITLcs);
if ((pClient = KITLClients[Id]) != NULL) {
EnterCriticalSection(&pClient->ClientCS);
if (pClient->State & (KITL_CLIENT_REGISTERED | KITL_CLIENT_REGISTERING)) {
DEBUGCHK (pClient->ServiceId == Id);
// reset state before setting the events so the waiting
// thread knows that the client deregistered
State = pClient->State;
pClient->State = 0;
ResetClientState (pClient);
if (State & KITL_USE_SYSCALLS) {
SetClientEvent(pClient,pClient->evCfg);
SetClientEvent(pClient,pClient->evRecv);
}
if (pClient->evCfg) CloseHandle(pClient->evCfg);
if (pClient->evRecv) CloseHandle(pClient->evRecv);
if (pClient->evTxFull) CloseHandle(pClient->evTxFull);
// DeleteCriticalSection(&pClient->ClientCS);
// pClient->ServiceName[0] = 0;
fRet = TRUE;
} else {
KITL_DEBUGMSG(ZONE_WARNING, ("KITLDeregisterClient[%u]-already deregistered\n", Id));
}
LeaveCriticalSection(&pClient->ClientCS);
}
LeaveCriticalSection (&KITLcs);
KITL_DEBUGMSG(ZONE_INIT,("-KITLDeregisterClient, Id:%u ret %d\n",Id, fRet));
return fRet;
}
/* KITLInitializeInterrupt
*
* This function is called by the kernel when the system is able to handle interrupts.
* Start our ISR thread, and unmask the HW interrupts.
*/
BOOL
KITLInitializeInterrupt()
{
int i;
if (!(KITLGlobalState & KITL_ST_ADAPTER_INITIALIZED))
return FALSE;
// Check if we are coming up for the first time, or resuming interrupts (e.g. when coming
// back from OEMPowerOff)
if (KITLGlobalState & KITL_ST_MULTITHREADED) {
// Just enable interrupt and return
EnableInts();
return TRUE;
}
KITLOutputDebugString("KITL: Leaving polling mode...\n");
InitializeCriticalSection(&KITLODScs);
InitializeCriticalSection(&KITLKCallcs);
KITLGlobalState |= KITL_ST_MULTITHREADED;
KITL_DEBUGMSG(ZONE_INIT,("KITL Checking client registrations\n"));
// Some clients may have registered already, finish initialization now that
// the system is up. KDBG continues to run in polling mode.
for (i=0; i< MAX_KITL_CLIENTS; i++) {
if (KITLClients[i] && (i != KITL_SVC_KDBG)
&& (KITLClients[i]->State & (KITL_CLIENT_REGISTERED|KITL_CLIENT_REGISTERING))) {
if (!RegisterClientPart2((UCHAR)i))
return FALSE;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -