📄 irfir.cpp
字号:
*BytesNeeded = 0;
NdisAcquireSpinLock(&thisDev->Lock);
switch (Oid)
{
case OID_IRDA_LINK_SPEED:
info = *(UINT *)InformationBuffer;
DEBUGMSG(ZONE_SETINFO, (TEXT("IrFir: IrFirSetInformation(OID_IRDA_LINK_SPEED, %d)\r\n"), info));
result = NDIS_STATUS_INVALID_DATA;
for (int i = 0; i < NUM_BAUDRATES; i++)
{
if (supportedBaudRateTable[i].bitsPerSec == info)
{
thisDev->newSpeed = supportedBaudRateTable[i].bitsPerSec;
result = NDIS_STATUS_SUCCESS;
break;
}
}
if (result == NDIS_STATUS_SUCCESS)
{
if (!SetSpeed(thisDev))
result = NDIS_STATUS_FAILURE;
}
else
{
result = NDIS_STATUS_FAILURE;
*BytesRead = 0;
*BytesNeeded = 0;
}
break;
case OID_IRDA_MEDIA_BUSY:
info = *(UINT *)InformationBuffer;
DEBUGMSG(ZONE_SETINFO, (TEXT("IrFir: IrFirSetInformation(OID_IRDA_MEDIA_BUSY, %xh)\r\n"), info));
// The protocol can use this OID to reset the busy field
// in order to check it later for intervening activity.
thisDev->mediaBusy = (BOOLEAN)info;
result = NDIS_STATUS_SUCCESS;
break;
case OID_IRDA_REACQUIRE_HW_RESOURCES:
DEBUGMSG(ZONE_SETINFO, (TEXT("IrFir: IRDA: Set(OID_IRDA_REACQUIRE_HW_RESOURCES)\r\n")));
*BytesNeeded = 0;
if (thisDev->resourcesReleased == FALSE)
{
DEBUGMSG(ZONE_WARN, (TEXT("IrFir: IRDA: resources already acquired!!\r\n")));
result = NDIS_STATUS_FAILURE;
}
else
{
if (thisDev->IR_VTbl->m_pAcquireAdapterResources(thisDev))
{
// Reset state.
thisDev->portInfo.rcvState = STATE_INIT;
thisDev->writePending = FALSE;
thisDev->resourcesReleased = FALSE;
// Setup receive
thisDev->IR_VTbl->m_pSetupRecv(thisDev);
}
else
{
DEBUGMSG(ZONE_ERROR, (TEXT("IrFir: IRDA: initialization failure.\r\n")));
result = NDIS_STATUS_FAILURE;
}
}
break;
case OID_GEN_CURRENT_PACKET_FILTER:
DEBUGMSG(ZONE_SETINFO, (TEXT("IrFir: IrFirSetInformation(OID_GEN_CURRENT_PACKET_FILTER)\r\n")));
result = NDIS_STATUS_SUCCESS;
break;
// Power management related OID's
case OID_PNP_SET_POWER:
DEBUGMSG(ZONE_SETINFO, (TEXT("IrFir: IrFirSetInformation(OID_PNP_SET_POWER)\r\n")));
if (InformationBufferLength != sizeof(NDIS_DEVICE_POWER_STATE ))
{
return(NDIS_STATUS_INVALID_LENGTH);
}
NewPowerState = *(PNDIS_DEVICE_POWER_STATE)InformationBuffer;
if(NewPowerState != NdisDeviceStateD0)
NewPowerState = NdisDeviceStateD3;
// Set the power state - Cannot fail this request
if(NewPowerState == NdisDeviceStateD0)
{
// Power ON
thisDev->IR_VTbl->m_pAcquireAdapterResources(thisDev);
}
else
{
// Power OFF
thisDev->IR_VTbl->m_pReleaseAdapterResources(thisDev);
}
*BytesRead = sizeof(NDIS_DEVICE_POWER_STATE);
result = NDIS_STATUS_SUCCESS;
break;
// we dont need to support these
case OID_PNP_ADD_WAKE_UP_PATTERN:
case OID_PNP_REMOVE_WAKE_UP_PATTERN:
case OID_PNP_ENABLE_WAKE_UP:
// We don't support these
case OID_IRDA_RATE_SNIFF:
case OID_IRDA_UNICAST_LIST:
// These are query-only parameters.
case OID_IRDA_SUPPORTED_SPEEDS:
case OID_IRDA_MAX_UNICAST_LIST_SIZE:
case OID_IRDA_TURNAROUND_TIME:
default:
DEBUGMSG(ZONE_SETINFO, (TEXT("IrFir: IrFirSetInformation(OID=%d=0x%x) - unsupported OID\r\n"), Oid, Oid));
*BytesRead = 0;
*BytesNeeded = 0;
result = NDIS_STATUS_NOT_SUPPORTED;
break;
}
NdisReleaseSpinLock(&thisDev->Lock);
}
else
{
*BytesRead = 0;
*BytesNeeded = sizeof(UINT);
result = NDIS_STATUS_INVALID_LENGTH;
}
if(result == NDIS_STATUS_SUCCESS)
DEBUGMSG(ZONE_SETINFO, (TEXT("IrFir: IrFirSetInformation succeeded\r\n")));
else
DEBUGMSG(ZONE_WARN, (TEXT("IrFir: IrFir: IrFirSetInformation failed\r\n")));
return result;
}
//-----------------------------------------------------------------------------
//
// Function: IrFirReturnPacket
//
// When NdisMIndicateReceivePacket returns asynchronously, the protocol returns ownership
// of the packet to the miniport via this function.
//
// Parameters:
// MiniportAdapterContext
// [in] .
// Packet
// [in] .
//
// Returns:
// None.
//
//-----------------------------------------------------------------------------
VOID IrFirReturnPacket( NDIS_HANDLE MiniportAdapterContext, PNDIS_PACKET Packet )
{
pFirDevice_t thisDev = (pFirDevice_t)MiniportAdapterContext;
rcvBuffer *rcvBuf;
DEBUGMSG(ZONE_FUNCTION, (TEXT("IrFir: IrFirReturnPacket(0x%x, packet = 0x%x)\r\n"), (UINT)MiniportAdapterContext, Packet));
NdisAcquireSpinLock(&thisDev->Lock);
// MiniportReserved contains the pointer to our rcvBuffer
rcvBuf = *(rcvBuffer**) Packet->MiniportReserved;
if (rcvBuf->state == STATE_PENDING)
{
PNDIS_BUFFER ndisBuf;
DEBUGMSG(ZONE_FUNCTION, (TEXT("IrFir: Reclaimed rcv packet 0x%x.\r\n"), (UINT)Packet));
NdisUnchainBufferAtFront(Packet, &ndisBuf);
if (ndisBuf)
NdisFreeBuffer(ndisBuf);
// At SIR speeds, we manage a group of buffers that
// we keep on the rcvBufBuf queue.
InsertTailList(&thisDev->rcvBufBuf, RCV_BUF_TO_LIST_ENTRY(rcvBuf->dataBuf));
rcvBuf->dataBuf = NULL;
rcvBuf->state = STATE_FREE;
RemoveEntryList(&rcvBuf->listEntry);
InsertHeadList(&thisDev->rcvBufFree, &rcvBuf->listEntry);
}
else
DEBUGMSG(ZONE_FUNCTION, (TEXT("IrFir: Packet in IrFirReturnPacket was not PENDING\r\n")));
NdisReleaseSpinLock(&thisDev->Lock);
}
//-----------------------------------------------------------------------------
//
// Function: DeliverFullBuffers
//
// This function delivers received packets to the protocol.
//
// Parameters:
// thisDev
// [in] pointer to Fir Device structure.
//
// Returns:
// This function returns TRUE if delivered at least one frame
//
//-----------------------------------------------------------------------------
BOOLEAN DeliverFullBuffers( pFirDevice_t thisDev )
{
BOOLEAN result = FALSE;
PLIST_ENTRY ListEntry;
DEBUGMSG(ZONE_FUNCTION, (TEXT("IrFir: +DeliverFullBuffers(0x%x)\r\n"), (UINT) thisDev));
// Deliver all full rcv buffers
for (ListEntry = MyRemoveHeadList(&thisDev->rcvBufFull); ListEntry;
ListEntry = MyRemoveHeadList(&thisDev->rcvBufFull))
{
rcvBuffer *rcvBuf = CONTAINING_RECORD(ListEntry, rcvBuffer, listEntry);
NDIS_STATUS stat;
PNDIS_BUFFER packetBuf;
SLOW_IR_FCS_TYPE fcs;
if (thisDev->linkSpeedInfo->bitsPerSec <= MAX_SIR_SPEED)
{
// The packet we have already has had BOFs,
// EOF, and * escape-sequences removed. It
// contains an FCS code at the end, which we
// need to verify and then remove before
// delivering the frame. We compute the FCS
// on the packet with the packet FCS attached;
// this should produce the constant value
// GOOD_FCS.
fcs = ComputeFCS(rcvBuf->dataBuf, rcvBuf->dataLen);
if (fcs != GOOD_FCS)
{
// FCS Error. Drop this frame.
DEBUGMSG(ZONE_FUNCTION, (TEXT("IrFir: Bad FCS in DeliverFullBuffers bad != good 0x%x!=0x%x.\r\n"), (UINT)fcs, (UINT) GOOD_FCS));
rcvBuf->state = STATE_FREE;
DEBUGMSG(ZONE_FUNCTION, (TEXT("IrFir: Dropped pkts; BAD FCS (%xh!=%xh):\r\n"), fcs, GOOD_FCS));
InsertTailList(&thisDev->rcvBufBuf, RCV_BUF_TO_LIST_ENTRY(rcvBuf->dataBuf));
rcvBuf->dataBuf = NULL;
InsertHeadList(&thisDev->rcvBufFree, &rcvBuf->listEntry);
//break;
continue;
}
// Remove the FCS from the end of the packet
rcvBuf->dataLen -= SLOW_IR_FCS_SIZE;
}
// The packet array is set up with its NDIS_PACKET.
// Now we need to allocate a single NDIS_BUFFER for
// the NDIS_PACKET and set the NDIS_BUFFER to the
// part of dataBuf that we want to deliver.
NdisAllocateBuffer(&stat, &packetBuf, thisDev->bufferPoolHandle,
(PVOID)rcvBuf->dataBuf, rcvBuf->dataLen);
if (stat != NDIS_STATUS_SUCCESS)
{
DEBUGMSG(ZONE_ERROR, (TEXT("IrFir: NdisAllocateBuffer failed\r\n")));
break;
}
NdisChainBufferAtFront(rcvBuf->packet, packetBuf);
// Fix up some other packet fields.
NDIS_SET_PACKET_HEADER_SIZE(rcvBuf->packet, IR_ADDR_SIZE+IR_CONTROL_SIZE);
DEBUGMSG(ZONE_FUNCTION, (TEXT("IrFir: Indicating rcv packet 0x%x.\r\n"), (UINT)rcvBuf->packet));
// Indicate to the protocol that another packet is
// ready. Set the rcv buffer's state to PENDING first
// to avoid a race condition with NDIS's call to the
// return packet handler.
rcvBuf->state = STATE_PENDING;
*(rcvBuffer **)rcvBuf->packet->MiniportReserved = rcvBuf;
InsertBufferSorted(&thisDev->rcvBufPend, rcvBuf);
NdisReleaseSpinLock(&thisDev->Lock);
NdisMIndicateReceivePacket(thisDev->ndisAdapterHandle, &rcvBuf->packet, 1);
NdisAcquireSpinLock(&thisDev->Lock);
result = TRUE;
stat = NDIS_GET_PACKET_STATUS(rcvBuf->packet);
if (stat == NDIS_STATUS_PENDING)
{
// The packet is being delivered asynchronously.
// Leave the rcv buffer's state as PENDING;
// we'll get a callback when the transfer is
// complete. Do NOT step firstRcvBufIndex.
// We don't really need to break out here,
// but we will anyways just to make things
// simple. This is ok since we get this
// deferred interrupt callback for each packet
// anyway. It'll give the protocol a chance
// to catch up.
DEBUGMSG(ZONE_FUNCTION, (TEXT("IrFir: DeliverFullBuffers, Rcv Pending. Rcvd packets\r\n")));
}
else
{
// If there was an error, we are dropping this
// packet; otherwise, this packet was delivered
// synchronously. We can free the packet
// buffer and make this rcv frame available.
RemoveEntryList(&rcvBuf->listEntry);
NdisUnchainBufferAtFront(rcvBuf->packet, &packetBuf);
if (packetBuf)
NdisFreeBuffer(packetBuf);
rcvBuf->state = STATE_FREE;
// At SIR speeds, we manage a group of buffers that
// we keep on the rcvBufBuf queue.
InsertTailList(&thisDev->rcvBufBuf, RCV_BUF_TO_LIST_ENTRY(rcvBuf->dataBuf));
rcvBuf->dataBuf = NULL;
InsertHeadList(&thisDev->rcvBufFree, &rcvBuf->listEntry);
if (stat == NDIS_STATUS_SUCCESS)
{
DEBUGMSG(ZONE_FUNCTION, (TEXT("IrFir: DeliverFullBuffers, Rcvd packets\r\n")));
}
else
{
DEBUGMSG(ZONE_FUNCTION, (TEXT("IrFir: DeliverFullBuffers, Dropped rcv packets.\r\n")));
}
}
}
DEBUGMSG(ZONE_FUNCTION, (TEXT("IrFir: -DeliverFullBuffers\r\n")));
return result;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -