📄 card.c
字号:
// RTL8029 PCMCIA CHANGE END
//
// Do Write errata as described on pages 1-143 and
// 1-144 of the 1992 LAN databook
//
//
// Set Count and destination address
//
ReadBuffer = XmitBufAddress + ((ULONG_PTR)XmitBufAddress & 1);
OldAddr = NewAddr = (USHORT)(ReadBuffer);
// NdisRawWritePortUchar(Adapter->IoAddr + NIC_COMMAND, // robin
// CR_PAGE0 // robin
// ); // robin
NdisRawWritePortUchar(Adapter->IoAddr + NIC_RMT_ADDR_LSB,
LSB(PtrToUlong(ReadBuffer))
);
NdisRawWritePortUchar(Adapter->IoAddr + NIC_RMT_ADDR_MSB,
MSB(PtrToUlong(ReadBuffer))
);
NdisRawWritePortUchar(Adapter->IoAddr + NIC_RMT_COUNT_LSB, 0x2 );
NdisRawWritePortUchar(Adapter->IoAddr + NIC_RMT_COUNT_MSB, 0x0 );
//
// Set direction (Read)
//
NdisRawWritePortUchar(
Adapter->IoAddr + NIC_COMMAND,
CR_START | CR_PAGE0 | CR_DMA_READ
);
//
// Read from port
//
NdisRawReadPortUshort( Adapter->IoAddr + NIC_RACK_NIC, &TmpShort );
//
// Wait for addr to change
//
TmpShort = 0xFFFF;
while (TmpShort != 0) {
NdisRawReadPortUchar( Adapter->IoAddr + NIC_CRDA_LSB, &Tmp );
NewAddr = Tmp;
NdisRawReadPortUchar( Adapter->IoAddr + NIC_CRDA_MSB, &Tmp );
NewAddr |= (Tmp << 8);
if (NewAddr != OldAddr) {
break;
}
NdisStallExecution(1);
TmpShort--;
}
if (NewAddr == OldAddr) {
NdisWriteErrorLogEntry(
Adapter->MiniportAdapterHandle,
NDIS_ERROR_CODE_HARDWARE_FAILURE,
2,
cardCopyDownPacket,
(ULONG_PTR)XmitBufAddress
);
return(FALSE);
}
//
// Set Count and destination address
//
NdisRawWritePortUchar( Adapter->IoAddr + NIC_RMT_ADDR_LSB,
LSB(PtrToUlong(XmitBufAddress - 1)) );
NdisRawWritePortUchar( Adapter->IoAddr + NIC_RMT_ADDR_MSB,
MSB(PtrToUlong(XmitBufAddress - 1)) );
NdisRawWritePortUchar( Adapter->IoAddr + NIC_RMT_COUNT_LSB, 0x2 );
NdisRawWritePortUchar( Adapter->IoAddr + NIC_RMT_COUNT_MSB, 0x0 );
//
// Set direction (Write)
//
NdisRawWritePortUchar( Adapter->IoAddr + NIC_COMMAND,
CR_START | CR_PAGE0 | CR_DMA_WRITE );
//
// It seems that the card stores words in LOW:HIGH order
//
NdisRawWritePortUshort( Adapter->IoAddr + NIC_RACK_NIC,
(USHORT)(Tmp1 | ((*CurBufAddress) << 8)) );
//
// Wait for DMA to complete
//
Count = 0xFFFF;
while (Count) {
NdisRawReadPortUchar( Adapter->IoAddr + NIC_INTR_STATUS, &Tmp1 );
if (Tmp1 & ISR_DMA_DONE) {
break;
} else {
Count--;
NdisStallExecution(4);
}
}
CurBufAddress++;
XmitBufAddress++;
PacketLength--;
CurBufLen--;
}
//
// Do Write errata as described on pages 1-143 and 1-144 of
// the 1992 LAN databook
//
//
// Set Count and destination address
//
ReadBuffer = XmitBufAddress + ((ULONG_PTR)XmitBufAddress & 1);
OldAddr = NewAddr = (USHORT)(ReadBuffer);
// NdisRawWritePortUchar(Adapter->IoAddr + NIC_COMMAND, // robin
// CR_PAGE0 // robin
// ); // robin
NdisRawWritePortUchar(Adapter->IoAddr + NIC_RMT_ADDR_LSB,
LSB(PtrToUlong(ReadBuffer))
);
NdisRawWritePortUchar(Adapter->IoAddr + NIC_RMT_ADDR_MSB,
MSB(PtrToUlong(ReadBuffer))
);
NdisRawWritePortUchar(Adapter->IoAddr + NIC_RMT_COUNT_LSB,
0x2
);
NdisRawWritePortUchar(Adapter->IoAddr + NIC_RMT_COUNT_MSB,
0x0
);
//
// Set direction (Read)
//
NdisRawWritePortUchar(
Adapter->IoAddr + NIC_COMMAND,
CR_START | CR_PAGE0 | CR_DMA_READ
);
if (Adapter->EightBitSlot) {
//
// Read from port
//
NdisRawReadPortUchar( Adapter->IoAddr + NIC_RACK_NIC, &Tmp );
NdisRawReadPortUchar( Adapter->IoAddr + NIC_RACK_NIC, &Tmp );
} else {
//
// Read from port
//
NdisRawReadPortUshort( Adapter->IoAddr + NIC_RACK_NIC, &TmpShort );
}
//
// Wait for addr to change
//
TmpShort = 0xFFFF;
while (TmpShort != 0) {
NdisRawReadPortUchar( Adapter->IoAddr + NIC_CRDA_LSB, &Tmp );
NewAddr = Tmp;
NdisRawReadPortUchar( Adapter->IoAddr + NIC_CRDA_MSB, &Tmp );
NewAddr |= (Tmp << 8);
if (NewAddr != OldAddr) {
break;
}
NdisStallExecution(1);
TmpShort--;
}
if (NewAddr == OldAddr) {
NdisWriteErrorLogEntry(
Adapter->MiniportAdapterHandle,
NDIS_ERROR_CODE_HARDWARE_FAILURE,
2,
cardCopyDownPacket,
(ULONG_PTR)XmitBufAddress
);
return(FALSE);
}
//
// Set Count and destination address
//
// NdisRawWritePortUchar( Adapter->IoAddr + NIC_COMMAND, CR_PAGE0 ); // robin
NdisRawWritePortUchar( Adapter->IoAddr + NIC_RMT_ADDR_LSB,
LSB(PtrToUlong(XmitBufAddress)) );
NdisRawWritePortUchar( Adapter->IoAddr + NIC_RMT_ADDR_MSB,
MSB(PtrToUlong(XmitBufAddress)) );
NdisRawWritePortUchar( Adapter->IoAddr + NIC_RMT_COUNT_LSB,
LSB(PacketLength) );
NdisRawWritePortUchar( Adapter->IoAddr + NIC_RMT_COUNT_MSB,
MSB(PacketLength) );
//
// Set direction (Write)
//
NdisRawWritePortUchar( Adapter->IoAddr + NIC_COMMAND,
CR_START | CR_PAGE0 | CR_DMA_WRITE );
} // setup
//
// Copy the data now
//
do {
UINT Count;
UCHAR Tmp;
//
// Write the previous byte with this one
//
if (OddBufLen) {
//
// It seems that the card stores words in LOW:HIGH order
//
NdisRawWritePortUshort( Adapter->IoAddr + NIC_RACK_NIC,
(USHORT)(*OddBufAddress | ((*CurBufAddress) << 8)) );
OddBufLen = FALSE;
CurBufAddress++;
CurBufLen--;
}
if (Adapter->EightBitSlot) { // byte mode
NdisRawWritePortBufferUchar(
Adapter->IoAddr + NIC_RACK_NIC,
CurBufAddress,
CurBufLen
);
} else { // word mode
NdisRawWritePortBufferUshort(
Adapter->IoAddr + NIC_RACK_NIC,
(PUSHORT)CurBufAddress,
(CurBufLen >> 1));
//
// Save trailing byte (if an odd lengthed transfer)
//
if (CurBufLen & 0x1) {
OddBufAddress = CurBufAddress + (CurBufLen - 1);
OddBufLen = TRUE;
}
}
//
// Wait for DMA to complete
//
Count = 0xFFFF;
while (Count) {
NdisRawReadPortUchar(
Adapter->IoAddr + NIC_INTR_STATUS,
&Tmp );
if (Tmp & ISR_DMA_DONE) {
break;
} else {
Count--;
NdisStallExecution(4);
}
}
//
// Move to the next buffer
//
NdisGetNextBuffer(CurBuffer, &CurBuffer);
if (CurBuffer){
NdisQueryBuffer(CurBuffer, (PVOID *)&CurBufAddress, &CurBufLen);
}
//
// Get address and length of the next buffer
//
while (CurBuffer && (CurBufLen == 0)) {
NdisGetNextBuffer(CurBuffer, &CurBuffer);
if (CurBuffer){
NdisQueryBuffer(CurBuffer, (PVOID *)&CurBufAddress, &CurBufLen);
}
}
} while (CurBuffer);
//
// Write trailing byte (if necessary)
//
if (OddBufLen)
{
UINT Count;
UCHAR Tmp;
USHORT TmpShort;
NdisRawWritePortUchar(Adapter->IoAddr + NIC_RACK_NIC, *OddBufAddress);
//
// Wait for DMA to complete robin-2
//
Count = 0xFFFF;
while (Count) {
NdisRawReadPortUchar(
Adapter->IoAddr + NIC_INTR_STATUS,
&Tmp );
if (Tmp & ISR_DMA_DONE) {
break;
} else {
Count--;
NdisStallExecution(4);
}
}
}
//
// Return length written
//
*Length = PacketLength;
return TRUE;
}
BOOLEAN
CardCopyDown(
IN PRTL8029_ADAPTER Adapter,
IN PUCHAR TargetBuffer,
IN PUCHAR SourceBuffer,
IN UINT Length
)
/*++
Routine Description:
Copies Length bytes from the SourceBuffer to the card buffer space
at card address TargetBuffer.
Arguments:
Adapter - pointer to the adapter block
SourceBuffer - Buffer in virtual address space
TargetBuffer - Buffer in card address space
Length - number of bytes to transfer to card
Return Value:
TRUE if the transfer completed with no problems.
--*/
{
//
// Temporary place holders for odd alignment transfers
//
UCHAR Tmp, TmpSave;
USHORT TmpShort;
//
// Values for waiting for noticing when a DMA completes.
//
USHORT OldAddr, NewAddr;
//
// Count of transfers to do
//
USHORT Count;
//
// Address the copy if coming from
//
PUCHAR ReadBuffer;
//
// Skip 0 length copies
//
if (Length == 0) {
return(TRUE);
}
if (!Adapter->EightBitSlot && ((ULONG_PTR)TargetBuffer & 0x1)) {
//
// For odd addresses we need to read first to get the previous
// byte and then merge it with our first byte.
//
//
// Set Count and Source address
//
NdisRawWritePortUchar(
Adapter->IoAddr + NIC_RMT_ADDR_LSB,
LSB(PtrToUlong(TargetBuffer - 1))
);
NdisRawWritePortUchar(
Adapter->IoAddr + NIC_RMT_ADDR_MSB,
MSB(PtrToUlong(TargetBuffer - 1))
);
// RTL8029 PCMCIA CHANGE!!! start
//NdisRawWritePortUchar(Adapter->IoAddr + NIC_RMT_COUNT_LSB, 0x1);
NdisRawWritePortUchar(Adapter->IoAddr + NIC_RMT_COUNT_LSB, 0x2);
NdisRawWritePortUchar(Adapter->IoAddr + NIC_RMT_COUNT_MSB, 0x0);
// RTL8029 PCMCIA CHANGE!!! end
//
// Set direction (Read)
//
NdisRawWritePortUchar(
Adapter->IoAddr + NIC_COMMAND,
CR_START | CR_PAGE0 | CR_DMA_READ
);
// RTL8029 PCMCIA CHANGE!!! start
//NdisRawReadPortUchar(Adapter->IoAddr + NIC_RACK_NIC, &TmpSave);
NdisRawReadPortUshort(Adapter->IoAddr + NIC_RACK_NIC, &TmpShort);
TmpSave = LSB(TmpShort);
// RTL8029 PCMCIA CHANGE!!! end
//
// Do Write errata as described on pages 1-143 and 1-144 of the 1992
// LAN databook
//
//
// Set Count and destination address
//
ReadBuffer = TargetBuffer + ((ULONG_PTR)TargetBuffer & 1);
OldAddr = NewAddr = (USHORT)(ReadBuffer);
// NdisRawWritePortUchar(Adapter->IoAddr + NIC_COMMAND, CR_PAGE0); // robin
NdisRawWritePortUchar(
Adapter->IoAddr + NIC_RMT_ADDR_LSB,
LSB(PtrToUlong(ReadBuffer))
);
NdisRawWritePortUchar(
Adapter->IoAddr + NIC_RMT_ADDR_MSB,
MSB(PtrToUlong(ReadBuffer))
);
NdisRawWritePortUchar(Adapter->IoAddr + NIC_RMT_COUNT_LSB, 0x2);
NdisRawWritePortUchar(Adapter->IoAddr + NIC_RMT_COUNT_MSB, 0x0);
//
// Set direction (Read)
//
NdisRawWritePortUchar(
Adapter->IoAddr + NIC_COMMAND,
CR_START | CR_PAGE0 | CR_DMA_READ
);
//
// Read from port
//
NdisRawReadPortUshort(Adapter->IoAddr + NIC_RACK_NIC, &TmpShort);
//
// Wait for addr to change
//
TmpShort = 0xFFFF;
while (TmpShort != 0) {
NdisRawReadPortUchar(
Adapter->IoAddr + NIC_CRDA_LSB,
&Tmp
);
NewAddr = Tmp;
NdisRawReadPortUchar(
Adapter->IoAddr + NIC_CRDA_MSB,
&Tmp
);
NewAddr |= (Tmp << 8);
if (NewAddr != OldAddr) {
break;
}
NdisStallExecution(1);
TmpShort--;
}
if (NewAddr == OldAddr) {
return(FALSE);
}
//
// Set Count and destination address
//
NdisRawWritePortUchar(
Adapter->IoAddr + NIC_RMT_ADDR_LSB,
LSB(PtrToUlong(TargetBuffer - 1))
);
NdisRawWritePortUchar(
Adapter->IoAddr + NIC_RMT_ADDR_MSB,
MSB(PtrToUlong(TargetBuffer - 1))
);
NdisRawWritePortUchar(Adapter->IoAddr + NIC_RMT_COUNT_LSB, 0x2);
NdisRawWritePortUchar(Adapter->IoAddr + NIC_RMT_COUNT_MSB, 0x0);
//
// Set direction (Write)
//
NdisRawWritePortUchar(
Adapter->IoAddr + NIC_COMMAND,
CR_START | CR_PAGE0 | CR_DMA_WRITE
);
//
// It seems that the card stores words in LOW:HIGH order
//
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -