📄 request.c
字号:
pRequest, 0, &dwRequestThreadId);
if (hRequestThread == NULL)
{
status = NDIS_STATUS_RESOURCES;
goto done;
}
CloseHandle(hRequestThread);
status = NDIS_STATUS_PENDING;
}
break;
case OID_IRDA_MEDIA_BUSY:
DEBUGMSG(ZONE_SETINFO, (TEXT("Set: OID_IRDA_MEDIA_BUSY\r\n")));
NdisAcquireSpinLock(&pIrDevice->slDevice);
pIrDevice->fMediaBusy = FALSE;
#ifdef DEBUG
pIrDevice->cMediaBusyRxBytes = 0;
pIrDevice->cMediaBusyRxErrs = 0;
#endif // DEBUG
pIrDevice->dwCommMask |= EV_ERR;
SetCommMask(pIrDevice->hSerial, pIrDevice->dwCommMask);
DEBUGMSG(ZONE_COMMMASK,
(TEXT("SMB: cm=%#x\r\n"), pIrDevice->dwCommMask));
NdisReleaseSpinLock(&pIrDevice->slDevice);
break;
case OID_IRDA_REACQUIRE_HW_RESOURCES:
DEBUGMSG(ZONE_SETINFO | ZONE_WARN, (TEXT("Set: OID_IRDA_REACQUIRE_HW_RESOURCES\r\n")));
if (pIrDevice->hSerial == INVALID_HANDLE_VALUE)
{
status = StartDevice(pIrDevice);
}
else
{
// We already have resources.
status = NDIS_STATUS_FAILURE;
DEBUGMSG(ZONE_ERROR,
(TEXT("IrSIR: REACQUIRE_RESOURCES - Already have resources!\r\n")));
}
break;
// Unsupported IrDA OIDs.
case OID_IRDA_RELEASE_HW_RESOURCES:
case OID_IRDA_RATE_SNIFF:
case OID_IRDA_UNICAST_LIST:
case OID_IRDA_MAX_UNICAST_LIST_SIZE:
*lpcbRead = 0;
*lpcbNeeded = 0;
status = NDIS_STATUS_NOT_SUPPORTED;
goto done;
// Many query only OIDs -> invalid set OIDs.
default:
*lpcbRead = 0;
*lpcbNeeded = 0;
status = NDIS_STATUS_INVALID_OID;
goto done;
}
done:
DEBUGMSG(ZONE_SETINFO,
(TEXT("-IrsirSetInformation [status = 0x%.8X, %dL]")
TEXT(" *lpcbWritten = %d, *lpcbNeeded = %d.\r\n"),
status, status, *lpcbRead, *lpcbNeeded)
);
return (status);
}
/*++
Function: IrsirpNdisRequest
Description: Processes NDIS requests asynchronously.
Arguments:
pvRequest - Pointer the asynchronous request block (PIRSIR_REQUEST).
Returns:
DWORD - Async thread exit code.
NDIS_STATUS indicate to protocol via NdisMSetInformationComplete.
NDIS_STATUS_SUCCESS
- Asynchronous request complete successfully.
NDIS_STATUS_FAILURE
- The request failed.
Comments:
Currently only IrsirSetInformation:OID_IRDA_LINK_SPEED is supported.
This function must free the asynchronous request block when finished
processing the request.
--*/
DWORD
IrsirpNdisRequest(
LPVOID pvRequest
)
{
NDIS_STATUS status = NDIS_STATUS_SUCCESS;
PIRSIR_REQUEST pRequest;
BOOL fSwitchSuccessful;
NDIS_HANDLE hSwitchToMiniport;
PIR_DEVICE pIrDevice;
pRequest = (PIRSIR_REQUEST)pvRequest;
ASSERT(pRequest != NULL);
pIrDevice = pRequest->pIrDevice;
ASSERT(pIrDevice != NULL);
//
// NdisRequestTypes: SetInformation, QueryInformation.
//
if (pRequest->NdisRequest.RequestType == NdisRequestSetInformation)
{
// Only support OID_IRDA_LINK_SPEED currently.
ASSERT(pRequest->NdisRequest.DATA.SET_INFORMATION.Oid == OID_IRDA_LINK_SPEED);
if (pRequest->NdisRequest.DATA.SET_INFORMATION.Oid == OID_IRDA_LINK_SPEED)
{
DWORD dwRequestedBPS;
dwRequestedBPS = *(UINT *)pRequest->NdisRequest.DATA.SET_INFORMATION.InformationBuffer;
status = IrsirpSetSpeed(pIrDevice, dwRequestedBPS);
}
}
else if (pRequest->NdisRequest.RequestType == NdisRequestQueryInformation)
{
// Only support OID_IRDA_RELEASE_HW_RESOURCES currently.
ASSERT(pRequest->NdisRequest.DATA.QUERY_INFORMATION.Oid == OID_IRDA_RELEASE_HW_RESOURCES);
while (1)
{
NdisAcquireSpinLock(&pIrDevice->slDevice);
if (pIrDevice->pSendActive == NULL)
{
NdisReleaseSpinLock(&pIrDevice->slDevice);
break;
}
NdisReleaseSpinLock(&pIrDevice->slDevice);
Sleep(100);
}
status = StopDevice(pIrDevice);
}
#ifdef DEBUG
else
{
// Don't allow other NDIS request types.
ASSERT(FALSE);
}
#endif
//
// Indicate status of request operation back to protocol.
//
fSwitchSuccessful = NdisIMSwitchToMiniport(
pIrDevice->hNdisAdapter,
&hSwitchToMiniport
);
if (hSwitchToMiniport == FALSE)
{
// WinCE's NdisIMSwitchToMiniport should not fail.
ASSERT(FALSE);
}
if (pRequest->NdisRequest.RequestType == NdisRequestSetInformation)
{
NdisMSetInformationComplete(
pIrDevice->hNdisAdapter,
status
);
}
else
{
ASSERT(pRequest->NdisRequest.RequestType == NdisRequestQueryInformation);
NdisMQueryInformationComplete(
pIrDevice->hNdisAdapter,
status
);
}
NdisIMRevertBack(
pIrDevice->hNdisAdapter,
hSwitchToMiniport
);
IrsirFree(pRequest);
return (status);
}
/*++
Function: IrsirpSetSpeed
Description: Sets the speed of the UART and dongle.
Arguments:
pIrDevice - Pointer to the IR device to set the speed.
dwRequestedBPS - The new speed to set the device to.
Returns:
NDIS_STATUS
NDIS_STATUS_SUCCESS
- New speed was set successfully.
NDIS_STATUS_INVALID_DATA
- The requested speed is not supported by the IR dongle.
NDIS_STATUS_FAILURE
- An error occurred while attempting to set the dongle speed.
Comments:
Some dongles require that bytes be sent and received from the dongle. This
would need to be treated specially to ensure that the miniport is not
sending or receiving at the time. Could create an event which is set by
default and is reset when want to stop RX/TX and set again after set
speed is complete.
--*/
NDIS_STATUS
IrsirpSetSpeed(
PIR_DEVICE pIrDevice,
DWORD dwRequestedBPS
)
{
NDIS_STATUS status = NDIS_STATUS_SUCCESS;
DWORD iBaud;
BOOL fSending;
DEBUGMSG(ZONE_SETINFO,
(TEXT("+IrsirpSetSpeed(0x%.8X, %d)\r\n"),
pIrDevice, dwRequestedBPS)
);
NdisAcquireSpinLock(&pIrDevice->slDevice);
ASSERT(pIrDevice->pCurrBaud != NULL);
// Are we currently at requested speed?
if (dwRequestedBPS == pIrDevice->pCurrBaud->dwBPS)
{
// Success.
goto done;
}
// Find baud rate in table to get NDIS_IRDA_SPEED_Xxx mask.
for (iBaud = 0; iBaud < NUM_BAUDRATES; iBaud++)
{
if (v_rgSupportedBaudRates[iBaud].dwBPS == dwRequestedBPS)
{
break;
}
}
// Do we support the baud rate?
if ((iBaud == NUM_BAUDRATES) ||
(v_rgSupportedBaudRates[iBaud].dwSpeedMask & pIrDevice->dwSupportedSpeedsMask) == 0)
{
DEBUGMSG(ZONE_ERROR,
(TEXT("Irsir: protocol requested unsupported baud rate %d\r\n"),
dwRequestedBPS));
// We don't support the requested baud.
status = NDIS_STATUS_INVALID_DATA;
goto done;
}
NdisReleaseSpinLock(&pIrDevice->slDevice);
//
// Need to make sure that we are not sending when we switch the
// speed.
//
// NOTE : The way NDIS queues it favors requests overs sends. And
// the protocol does not wait for a send to complete before
// sending the set speed request. Therefore, IrsirSend
// may not even have been called when we are here and we
// set the speed before the UA goes out. Sleep for 50ms
// to help this out.
Sleep(50);
fSending = TRUE;
while (fSending == TRUE)
{
NdisAcquireSpinLock(&pIrDevice->slDevice);
if (pIrDevice->pSendActive == NULL)
{
fSending = FALSE;
// Sleep one last time since write file may return before
// the UART has actually finished writing all the bytes
// (some bytes may be in the FIFO when WriteFile returns).
// Derivation approx:
// MIN(FIFO size, UA size) * 1 byte time @ 9600bps
Sleep(20);
// Break with the spinlock held.
break;
}
NdisReleaseSpinLock(&pIrDevice->slDevice);
// Sleep in 20ms increments.
Sleep(20);
}
// Set the new speed.
status = pIrDevice->IDongle.SetSpeed(
pIrDevice->hSerial,
&pIrDevice->Dcb,
dwRequestedBPS
);
if (status != NDIS_STATUS_SUCCESS)
{
DEBUGMSG(ZONE_ERROR,
(TEXT("Failure to set dongle speed = [0x%.8X]\r\n"),
status)
);
goto done;
}
pIrDevice->pCurrBaud = &v_rgSupportedBaudRates[iBaud];
done:
NdisReleaseSpinLock(&pIrDevice->slDevice);
DEBUGMSG(ZONE_SETINFO, (TEXT("-IrsirpSetSpeed [0x%.8X]\r\n"), status));
return (status);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -