⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 card.c

📁 自编的RTL8029驱动程序,用DS3.1开发
💻 C
📖 第 1 页 / 共 5 页
字号:
        NdisRawWritePortUshort(
                       Adapter->IoAddr + NIC_RACK_NIC,
                       (USHORT)(TmpSave | ((*SourceBuffer) << 8))
                       );

        //
        // 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);

            }

        }

        SourceBuffer++;
        TargetBuffer++;
        Length--;

    }

    //
    // 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(                              // robin
//                     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) {

        return(FALSE);

    }

    //
    // Set Count and destination address
    //

//  NdisRawWritePortUchar(                              // robin
//                     Adapter->IoAddr + NIC_COMMAND,  // robin
//                     CR_PAGE0                         // robin
//                    );                                // robin

    NdisRawWritePortUchar(
                       Adapter->IoAddr + NIC_RMT_ADDR_LSB,
                       LSB(PtrToUlong(TargetBuffer))
                      );

    NdisRawWritePortUchar(
                       Adapter->IoAddr + NIC_RMT_ADDR_MSB,
                       MSB(PtrToUlong(TargetBuffer))
                      );

    NdisRawWritePortUchar(
                       Adapter->IoAddr + NIC_RMT_COUNT_LSB,
                       LSB(Length)
                      );

    NdisRawWritePortUchar(
                       Adapter->IoAddr + NIC_RMT_COUNT_MSB,
                       MSB(Length)
                      );

    //
    // Set direction (Write)
    //

    NdisRawWritePortUchar(
                   Adapter->IoAddr + NIC_COMMAND,
                   CR_START | CR_PAGE0 | CR_DMA_WRITE
                  );

    if (Adapter->EightBitSlot) {

        //
        // Repeatedly write to out port
        //

        NdisRawWritePortBufferUchar(
                       Adapter->IoAddr + NIC_RACK_NIC,
                       SourceBuffer,
                       Length);

    } else {

        //
        // Write words to out ports
        //

        NdisRawWritePortBufferUshort(
                       Adapter->IoAddr + NIC_RACK_NIC,
                       (PUSHORT)SourceBuffer,
                       (Length >> 1));

        //
        // Write trailing byte (if necessary)
        //
        if (Length & 0x1)
        {
            SourceBuffer += (Length - 1);

// RTL8029 PCMCIA CHANGE!!!  start

            //NdisRawWritePortUchar(
            //    Adapter->IoAddr + NIC_RACK_NIC,
            //    *SourceBuffer
            //);

            TmpShort = (USHORT)(*SourceBuffer);
            NdisRawWritePortUshort(
                Adapter->IoAddr + NIC_RACK_NIC,
                TmpShort
            );
// RTL8029 PCMCIA CHANGE!!!  end


        }

    }

    //
    // 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);

        }

#if DBG
        if (!(Tmp & ISR_DMA_DONE)) {

            DbgPrint("CopyDownDMA didn't finish!");

        }
#endif // DBG

    }

    IF_LOG(RTL8029Log('>');)

    return TRUE;
}


BOOLEAN
CardCopyUp(
    IN PRTL8029_ADAPTER Adapter,
    IN PUCHAR TargetBuffer,
    IN PUCHAR SourceBuffer,
    IN UINT BufferLength
    )

/*++

Routine Description:

    Copies data from the card to memory.

Arguments:

    Adapter - pointer to the adapter block

    Target - the target address

    Source - the source address (on the card)

    BufferLength - the number of bytes to copy

Return Value:

    TRUE if the transfer completed with no problems.

--*/

{

    //
    // Used to check when the dma is done
    //
    UCHAR IsrValue;

    //
    // Count of the number of transfers to do
    //
    USHORT Count;

    //
    // Place holder for port values
    //
    UCHAR Temp;

    if (BufferLength == 0) {

        return TRUE;

    }

    //
    // Read the Command Register, to make sure it is ready for a write
    //
    NdisRawReadPortUchar(Adapter->IoAddr+NIC_COMMAND, &Temp);

    if (Adapter->EightBitSlot) {

        //
        // If byte mode
        //

        //
        // Set Count and destination address
        //

//      NdisRawWritePortUchar(                               // robin
//                         Adapter->IoAddr + NIC_COMMAND,   // robin
//                         CR_PAGE0                          // robin
//                        );                                 // robin

        NdisRawWritePortUchar(
                           Adapter->IoAddr + NIC_RMT_ADDR_LSB,
                           LSB(PtrToUlong(SourceBuffer))
                          );

        NdisRawWritePortUchar(
                           Adapter->IoAddr + NIC_RMT_ADDR_MSB,
                           MSB(PtrToUlong(SourceBuffer))
                          );

        NdisRawWritePortUchar(
                           Adapter->IoAddr + NIC_RMT_COUNT_LSB,
                           LSB(BufferLength)
                          );

        NdisRawWritePortUchar(
                           Adapter->IoAddr + NIC_RMT_COUNT_MSB,
                           MSB(BufferLength)
                          );

        //
        // Set direction (Read)
        //

        NdisRawWritePortUchar(
                       Adapter->IoAddr + NIC_COMMAND,
                       CR_START | CR_PAGE0 | CR_DMA_READ
                      );
        //
        // Repeatedly read from port
        //

        NdisRawReadPortBufferUchar(
                       Adapter->IoAddr + NIC_RACK_NIC,
                       TargetBuffer,
                       BufferLength
                      );

    } else {

        //
        // Else word mode
        //

        USHORT Tmp;

//      NdisRawWritePortUchar(                                   // robin
//                             Adapter->IoAddr + NIC_COMMAND,   // robin
//                             CR_PAGE0                          // robin
//                            );                                 // robin

        //
        // Avoid transfers to odd addresses
        //

        if ((ULONG_PTR)SourceBuffer & 0x1) {

            //
            // For odd addresses we need to read previous word and store the
            // second byte
            //

            //
            // Set Count and Source address
            //

            NdisRawWritePortUchar(
                               Adapter->IoAddr + NIC_RMT_ADDR_LSB,
                               LSB(PtrToUlong(SourceBuffer - 1))
                              );

            NdisRawWritePortUchar(
                               Adapter->IoAddr + NIC_RMT_ADDR_MSB,
                               MSB(PtrToUlong(SourceBuffer - 1))
                              );

            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
                          );

            NdisRawReadPortUshort(
                           Adapter->IoAddr + NIC_RACK_NIC,
                           &Tmp
                           );

            *TargetBuffer = MSB(Tmp);

            //
            // Wait for DMA to complete
            //

            Count = 0xFFFF;

            while (Count) {

                NdisRawReadPortUchar(
                              Adapter->IoAddr + NIC_INTR_STATUS,
                              &IsrValue
                             );

                if (IsrValue & ISR_DMA_DONE) {

                    break;

                } else {

                    Count--;

                    NdisStallExecution(4);

                }

#if DBG
                if (!(IsrValue & ISR_DMA_DONE)) {

                    DbgPrint("CopyUpDMA didn't finish!");

                }
#endif // DBG

            }

            SourceBuffer++;
            TargetBuffer++;
            BufferLength--;
        }

        //
        // Set Count and destination address
        //

        NdisRawWritePortUchar(
                           Adapter->IoAddr + NIC_RMT_ADDR_LSB,
                           LSB(PtrToUlong(SourceBuffer))
                          );

        NdisRawWritePortUchar(
                           Adapter->IoAddr + NIC_RMT_ADDR_MSB,
                           MSB(PtrToUlong(SourceBuffer))
                          );

// RTL8029 PCMCIA CHANGE!!!  start

//        NdisRawWritePortUchar(
//            Adapter->IoAddr + NIC_RMT_COUNT_LSB,
//            LSB(BufferLength)
//        );
//
//        NdisRawWritePortUchar(
//            Adapter->IoAddr + NIC_RMT_COUNT_MSB,
//            MSB(BufferLength)
//        );

        if (BufferLength & 1)
        {
            NdisRawWritePortUchar(
                Adapter->IoAddr + NIC_RMT_COUNT_LSB,
                LSB(BufferLength + 1)
            );

            NdisRawWritePortUchar(
                Adapter->IoAddr + NIC_RMT_COUNT_MSB,
                MSB(BufferLength + 1)
            );
        }
        else
        {
            NdisRawWritePortUchar(
                Adapter->IoAddr + NIC_RMT_COUNT_LSB,
                LSB(BufferLength)
            );

            NdisRawWritePortUchar(
                Adapter->IoAddr + NIC_RMT_COUNT_MSB,
                MSB(BufferLength)
            );
        }

// RTL8029 PCMCIA CHANGE!!!  end


        //
        // Set direction (Read)
        //

        NdisRawWritePortUchar(
                       Adapter->IoAddr + NIC_COMMAND,
                       CR_START | CR_PAGE0 | CR_DMA_READ
                      );

        //
        // Read words from port
        //

        NdisRawReadPortBufferUshort(
                       Adapter->IoAddr + NIC_RACK_NIC,
                       (PUSHORT)TargetBuffer,
                       (BufferLength >> 1));

        //
        // Read trailing byte (if necessary)
        //

        if (BufferLength & 1) {

            TargetBuffer += (BufferLength - 1);

// RTL8029 PCMCIA CHANGE!!!  start

            //NdisRawReadPortUchar(
            //    Adapter->IoAddr + NIC_RACK_NIC,
            //    TargetBuffer
            //);

            NdisRawReadPortUshort(
                Adapter->IoAddr + NIC_RACK_NIC,
                &Tmp
            );

            *TargetBuffer = LSB(Tmp);

// RTL8029 PCMCIA CHANGE!!!  end
        }

    }

    //
    // Wait for DMA to complete
    //

    Count = 0xFFFF;

    while (Count) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -