📄 nsc.c
字号:
*/
NDIS_STATUS MiniportReset(PBOOLEAN AddressingReset, NDIS_HANDLE MiniportAdapterContext)
{
IrDevice *thisDev = CONTEXT_TO_DEV(MiniportAdapterContext);
NDIS_STATUS result = NDIS_STATUS_PENDING;
LIST_ENTRY TempList;
BOOLEAN SetSpeedNow=FALSE;
PNDIS_PACKET Packet;
DBGERR(("MiniportReset(0x%x)", MiniportAdapterContext));
InitializeListHead(&TempList);
NdisAcquireSpinLock(&thisDev->QueueLock);
thisDev->hardwareStatus = NdisHardwareStatusReset;
//
// un-queue all the send packets and put them on a temp list
//
while (!IsListEmpty(&thisDev->SendQueue)) {
PLIST_ENTRY ListEntry;
ListEntry=RemoveHeadList(&thisDev->SendQueue);
InsertTailList(&TempList,ListEntry);
}
//
// if there is a current send packet, then request a speed change after it completes
//
if (thisDev->CurrentPacket != NULL) {
//
// the current packet is now the last, chage speed after it is done
//
thisDev->lastPacketAtOldSpeed=thisDev->CurrentPacket;
} else {
//
// no current packet, change speed now
//
SetSpeedNow=TRUE;
}
//
// back to 9600
//
thisDev->linkSpeedInfo = &supportedBaudRateTable[BAUDRATE_9600];
if (SetSpeedNow) {
//
// there are no packets being transmitted now, switch speeds now.
// otherwise the dpc will do it when the current send completes
//
SetSpeed(thisDev);
thisDev->TransmitIsIdle=FALSE;
}
NdisReleaseSpinLock(&thisDev->QueueLock);
if (SetSpeedNow) {
//
// the transmit was idle, but we change this to get the receive going again
//
ProcessSendQueue(thisDev);
}
//
// return all of these back to the protocol
//
while (!IsListEmpty(&TempList)) {
PLIST_ENTRY ListEntry;
ListEntry=RemoveHeadList(&TempList);
Packet= CONTAINING_RECORD(
ListEntry,
NDIS_PACKET,
MiniportReserved
);
NdisMSendComplete(thisDev->ndisAdapterHandle, Packet, NDIS_STATUS_RESET_IN_PROGRESS );
}
thisDev->hardwareStatus = NdisHardwareStatusReady;
NdisMResetComplete(thisDev->ndisAdapterHandle,
NDIS_STATUS_SUCCESS,
TRUE); // Addressing reset
*AddressingReset = TRUE;
DBGOUT(("MiniportReset done."));
return NDIS_STATUS_PENDING;
}
/*
*************************************************************************
* ReturnPacketHandler
*************************************************************************
*
* When NdisMIndicateReceivePacket returns asynchronously,
* the protocol returns ownership of the packet to the miniport via this function.
*
*/
VOID ReturnPacketHandler(NDIS_HANDLE MiniportAdapterContext, PNDIS_PACKET Packet)
{
IrDevice *thisDev = CONTEXT_TO_DEV(MiniportAdapterContext);
rcvBuffer *rcvBuf;
LONG PacketsLeft;
DBGOUT(("ReturnPacketHandler(0x%x)", MiniportAdapterContext));
RegStats.ReturnPacketHandlerCalled++;
//
// MiniportReserved contains the pointer to our rcvBuffer
//
rcvBuf = *(rcvBuffer**) Packet->MiniportReserved;
VerifyNdisPacket(Packet, 1);
if (rcvBuf->state == STATE_PENDING){
PNDIS_BUFFER ndisBuf;
DBGPKT(("Reclaimed rcv packet 0x%x.", Packet));
LOG_RemoveEntryList(thisDev, rcvBuf);
NDISSynchronizedRemoveEntryList(&rcvBuf->listEntry, &thisDev->interruptObj);
LOG_PacketUnchain(thisDev, rcvBuf->packet);
NdisUnchainBufferAtFront(Packet, &ndisBuf);
if (ndisBuf){
NdisFreeBuffer(ndisBuf);
}
if (!rcvBuf->isDmaBuf)
{
NDISSynchronizedInsertTailList(&thisDev->rcvBufBuf,
RCV_BUF_TO_LIST_ENTRY(rcvBuf->dataBuf),
&thisDev->interruptObj);
// ASSERT the pointer is actually outside our FIR DMA buffer
ASSERT(rcvBuf->dataBuf < thisDev->dmaReadBuf ||
rcvBuf->dataBuf >= thisDev->dmaReadBuf+RCV_DMA_SIZE);
}
rcvBuf->dataBuf = NULL;
rcvBuf->state = STATE_FREE;
VerifyNdisPacket(rcvBuf->packet, 0);
NDISSynchronizedInsertHeadList(&thisDev->rcvBufFree,
&rcvBuf->listEntry,
&thisDev->interruptObj);
}
else {
LOG("Error: Packet in ReturnPacketHandler was not PENDING");
DBGERR(("Packet in ReturnPacketHandler was not PENDING."));
}
NdisAcquireSpinLock(&thisDev->QueueLock);
PacketsLeft=NdisInterlockedDecrement(&thisDev->PacketsSentToProtocol);
if (thisDev->Halting && (PacketsLeft == 0)) {
NdisSetEvent(&thisDev->ReceiveStopped);
}
NdisReleaseSpinLock(&thisDev->QueueLock);
VerifyNdisPacket(rcvBuf->packet, 1);
}
VOID
GivePacketToSirISR(
IrDevice *thisDev
)
{
thisDev->portInfo.writeComBufferPos = 0;
thisDev->portInfo.SirWritePending = TRUE;
thisDev->nowReceiving = FALSE;
SetCOMPort(thisDev->portInfo.ioBase, INT_ENABLE_REG_OFFSET, XMIT_MODE_INTS_ENABLE);
}
VOID
SendCurrentPacket(
IrDevice *thisDev
)
{
BOOLEAN Result;
PNDIS_PACKET FailedPacket=NULL;
NdisAcquireSpinLock(&thisDev->QueueLock);
thisDev->TransmitIsIdle=FALSE;
if (thisDev->CurrentPacket == thisDev->lastPacketAtOldSpeed){
thisDev->setSpeedAfterCurrentSendPacket = TRUE;
}
if (thisDev->currentSpeed > MAX_SIR_SPEED) {
//
// send via FIR
//
if (thisDev->FirReceiveDmaActive) {
thisDev->FirReceiveDmaActive=FALSE;
//
// receive dma is running, stop it
//
CompleteDmaTransferFromDevice(
&thisDev->DmaUtil
);
}
thisDev->HangChk=0;
thisDev->FirTransmitPending = TRUE;
//
// Use DMA swap bit to switch to DMA to Transmit.
//
SyncWriteBankReg(&thisDev->interruptObj,thisDev->portInfo.ioBase, 2, 2, 0x0B);
//
// Switch on the DMA interrupt to decide when
// transmission is complete.
//
thisDev->FirIntMask = 0x14;
SyncSetInterruptMask(thisDev, TRUE);
//
// Kick off the first transmit.
//
NdisToFirPacket(
thisDev->CurrentPacket,
(UCHAR *) thisDev->TransmitDmaBuffer,
MAX_IRDA_DATA_SIZE,
&thisDev->TransmitDmaLength
);
LOG_FIR("Sending packet %d",thisDev->TransmitDmaLength);
DEBUGFIR(DBG_PKT, ("NSC: Sending packet\n"));
DBGPRINTBUF(thisDev->TransmitDmaBuffer,thisDev->TransmitDmaLength);
{
UCHAR LsrValue;
//
// make sure the transmitter is empty before starting to send this frame
//
LsrValue=SyncReadBankReg(&thisDev->interruptObj,thisDev->portInfo.ioBase, 0, LSR_OFFSET);
if ((LsrValue & (LSR_TXRDY | LSR_TXEMP)) != (LSR_TXRDY | LSR_TXEMP)) {
ULONG LoopCount=0;
while (((LsrValue & (LSR_TXRDY | LSR_TXEMP)) != (LSR_TXRDY | LSR_TXEMP)) && (LoopCount < 16)) {
LsrValue=SyncReadBankReg(&thisDev->interruptObj,thisDev->portInfo.ioBase, 0, LSR_OFFSET);
LoopCount++;
}
LOG_ERROR("SendCurrentPacket: Looped %d times waiting for tx empty",LoopCount);
}
}
/* Setup Transmit DMA. */
StartDmaTransferToDevice(
&thisDev->DmaUtil,
thisDev->xmitDmaBuffer,
0,
thisDev->TransmitDmaLength
);
#if 0
{
ULONG CurrentDMACount;
CurrentDMACount = NdisMReadDmaCounter(thisDev->DmaHandle);
LOG("SendCurrentPacket: dma count after start %d",CurrentDMACount);
}
#endif
SyncSetInterruptMask(thisDev, TRUE);
} else {
//
// SIR mode transfer
//
/*
* See if this was the last packet before we need to change
* speed.
*/
/*
* Send one packet to the COMM port.
*/
DBGPKT(("Sending packet 0x%x (0x%x).", thisDev->packetsSent++, thisDev->CurrentPacket));
/*
* Convert the NDIS packet to an IRDA packet.
*/
Result = NdisToIrPacket(
thisDev->CurrentPacket,
(UCHAR *)thisDev->portInfo.writeComBuffer,
MAX_IRDA_DATA_SIZE,
&thisDev->portInfo.writeComBufferLen
);
if (Result){
LOG_SIR("Sending packet %d",thisDev->portInfo.writeComBufferLen);
NdisMSynchronizeWithInterrupt(
&thisDev->interruptObj,
GivePacketToSirISR,
thisDev
);
} else {
ASSERT(0);
FailedPacket=thisDev->CurrentPacket;
thisDev->CurrentPacket=NULL;
}
}
NdisReleaseSpinLock(&thisDev->QueueLock);
if (FailedPacket != NULL) {
NdisMSendComplete(thisDev->ndisAdapterHandle, FailedPacket, NDIS_STATUS_FAILURE );
ProcessSendQueue(thisDev);
}
return;
}
VOID
DelayedWrite(
IN PVOID SystemSpecific1,
IN PVOID FunctionContext,
IN PVOID SystemSpecific2,
IN PVOID SystemSpecific3
)
{
IrDevice *thisDev = FunctionContext;
#if DBG
ASSERT(thisDev->WaitingForTurnAroundTimer);
thisDev->WaitingForTurnAroundTimer=FALSE;
#endif
LOG("Turn around timer expired");
SendCurrentPacket(thisDev);
}
VOID
ProcessSendQueue(
IrDevice *thisDev
)
{
PNDIS_PACKET Packet=NULL;
PLIST_ENTRY ListEntry;
NdisAcquireSpinLock(&thisDev->QueueLock);
if (thisDev->CurrentPacket == NULL) {
//
// not currently processing a send
//
if (!IsListEmpty(&thisDev->SendQueue)) {
//
// we have some queue packets to process
//
ListEntry=RemoveHeadList(&thisDev->SendQueue);
Packet= CONTAINING_RECORD(
ListEntry,
NDIS_PACKET,
MiniportReserved
);
thisDev->CurrentPacket=Packet;
NdisReleaseSpinLock(&thisDev->QueueLock);
{
PNDIS_IRDA_PACKET_INFO packetInfo;
/*
* Enforce the minimum turnaround time that must transpire
* after the last receive.
*/
packetInfo = GetPacketInfo(Packet);
//
// see if this packet is requesting a turnaround time or not
//
if (packetInfo->MinTurnAr
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -