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

📄 wdc_diag_lib.c

📁 This a generic PCI express device driver that enable user to access the device without caring much o
💻 C
📖 第 1 页 / 共 3 页
字号:
            WDC_WriteAddr32(hDev, dwAddrSpace, dwOffset, u32Data);
        if (WD_STATUS_SUCCESS == dwStatus)
        {
            printf("%s 0x%X %s offset 0x%lX in BAR %ld\n",
                (WDC_READ == direction) ? "Read" : "Wrote", u32Data,
                (WDC_READ == direction) ? "from" : "to", dwOffset, dwAddrSpace);
        }
        break;
    case WDC_MODE_64:
        dwStatus = (WDC_READ == direction) ?
            WDC_ReadAddr64(hDev, dwAddrSpace, dwOffset, &u64Data) :
            WDC_WriteAddr64(hDev, dwAddrSpace, dwOffset, u64Data);
        if (WD_STATUS_SUCCESS == dwStatus)
        {
            printf("%s 0x%"PRI64"X %s offset 0x%lX in BAR %ld\n",
                (WDC_READ == direction) ? "Read" : "Wrote", u64Data,
                (WDC_READ == direction) ? "from" : "to", dwOffset, dwAddrSpace);
        }
        break;
    default:
        WDC_DIAG_ERR("WDC_DIAG_ReadWriteAddr: Error - Invalid mode (%d)\n", mode);
        return;
    }

    if (WD_STATUS_SUCCESS != dwStatus)
    {
        printf("Failed to %s offset 0x%lX in BAR %ld. Error 0x%lx - %s\n",
            (WDC_READ == direction) ? "read from" : "write to", dwOffset,
            dwAddrSpace, dwStatus, Stat2Str(dwStatus));
    }
}

/* Read/write a memory or I/O address OR an offset in the PCI configuration space /
   PCMCIA attribute space (dwAddrSpace == WDC_AD_CFG_SPACE) */
void WDC_DIAG_ReadWriteBlock(WDC_DEVICE_HANDLE hDev, WDC_DIRECTION direction,
    DWORD dwAddrSpace)
{
    DWORD dwStatus;
    DWORD dwOffset, dwBytes;
    const CHAR *sDir = (WDC_READ == direction) ? "read" : "write";
    PVOID pBuf = NULL;
 
    if (!hDev)
    {
        WDC_DIAG_ERR("WDC_DIAG_ReadWriteBlock: Error - NULL WDC device handle\n");
        return;
    }

    if (!DIAG_InputDWORD(&dwOffset, "offset", TRUE, 0, 0))
        return;

    if (!DIAG_InputDWORD(&dwBytes, "bytes", TRUE, 0, 0))
        return;

    if (!dwBytes)
        return;

    pBuf = malloc(dwBytes);
    if (!pBuf)
    {
        WDC_DIAG_ERR("WDC_DIAG_ReadWriteBlock: Failed allocating %s data buffer\n", sDir);
        goto Exit;
    }
    memset(pBuf, 0, dwBytes);

    if (WDC_WRITE == direction)
    {
        printf("data to write (hex format): 0x"); 
        if (!DIAG_GetHexBuffer(pBuf, dwBytes))
            goto Exit;
    }

    if (WDC_AD_CFG_SPACE == dwAddrSpace) /* Read/write a configuration/attribute space address */
    {
        WD_BUS_TYPE busType = WDC_GetBusType(hDev);

        if (WD_BUS_PCI == busType) /* Read/write PCI configuration space offset */
        {
            if (direction == WDC_READ)
                dwStatus = WDC_PciReadCfg(hDev, dwOffset, pBuf, dwBytes);
            else
                dwStatus = WDC_PciWriteCfg(hDev, dwOffset, pBuf, dwBytes);
        }
        else if (WD_BUS_PCMCIA == busType) /* Read/write PCMCIA attribute space offset */
        {
            if (direction == WDC_READ)
                dwStatus = WDC_PcmciaReadAttribSpace(hDev, dwOffset, pBuf, dwBytes);
            else
                dwStatus = WDC_PcmciaWriteAttribSpace(hDev, dwOffset, pBuf, dwBytes);
        }
        else
        {
            printf("Error - Cannot read/write configuration space address space "
                "for bus type 0x%lx\n", busType);
            goto Exit;
        }
    }
    else /* Read/write a memory or I/O address */
    {
        WDC_ADDR_MODE mode;
        WDC_ADDR_RW_OPTIONS options;
        BOOL fAutoInc;

        if (!WDC_DIAG_SetMode(&mode))
            goto Exit;
            
        printf("Do you wish to increment the address after each %s block "
            "(0x%lX bytes) (0 - No, Otherwise - Yes)? ",
            sDir, WDC_ADDR_MODE_TO_SIZE(mode));
        fgets(gsInput, sizeof(gsInput), stdin);
        if (sscanf(gsInput, "%ld", &fAutoInc) < 1)
        {
            printf("Invalid input\n");
            goto Exit;
        }

        options = (fAutoInc ? WDC_ADDR_RW_DEFAULT : WDC_ADDR_RW_NO_AUTOINC);

        dwStatus = direction == WDC_READ ?
            WDC_ReadAddrBlock(hDev, dwAddrSpace, dwOffset, dwBytes, pBuf, mode, options) :
            WDC_WriteAddrBlock(hDev, dwAddrSpace, dwOffset, dwBytes, pBuf, mode, options);
    }
    
    if (WD_STATUS_SUCCESS == dwStatus)
    {
        if (WDC_READ == direction)
            DIAG_PrintHexBuffer(pBuf, dwBytes, FALSE);
        else
            printf("Wrote 0x%lX bytes to offset 0x%lX\n", dwBytes, dwOffset);
    }
    else
    {
        printf("Failed to %s 0x%lX bytes %s offset 0x%lX. Error 0x%lx - %s\n",
            sDir, dwBytes, (WDC_READ == direction) ? "from" : "to", dwOffset,
            dwStatus, Stat2Str(dwStatus));
    }

Exit:
    if (pBuf)
        free(pBuf);

    printf("\n");
    printf("Press ENTER to continue\n");
    fgets(gsInput, sizeof(gsInput), stdin);
}

/* Read all pre-defined run-time or PCI configuration registers and display results */
void WDC_DIAG_ReadRegsAll(WDC_DEVICE_HANDLE hDev, const WDC_REG *pRegs,
    DWORD dwNumRegs, BOOL fPciCfg)
{
    DWORD i, dwStatus;
    const WDC_REG *pReg;
    BYTE bData = 0;
    WORD wData = 0;
    UINT32 u32Data = 0;
    UINT64 u64Data = 0;
 
    if (!hDev)
    {
        WDC_DIAG_ERR("WDC_DIAG_ReadRegsAll: Error - NULL WDC device handle\n");
        return;
    }

    if (!dwNumRegs || !pRegs)
    {
        WDC_DIAG_ERR("WDC_DIAG_ReadRegsAll: %s\n",
            !dwNumRegs ? "No registers (dwNumRegs == 0)" :
            "Error - NULL registers pointer");
        
        return;
    }

    printf("\n");
    printf("%s registers data:\n", fPciCfg ? "PCI configuration" : "run-time");
    printf("---------------------------------\n\n");
    printf("%3s %-*s %-*s  %s\n",
        "", MAX_NAME_DISPLAY, "Name", 8 * 2 + 2, "Data", "Description");
    printf("%3s %-*s %-*s  %s\n",
        "", MAX_NAME_DISPLAY, "----", 8 * 2 + 2, "----", "-----------");

    for (i = 1, pReg = pRegs; i <= dwNumRegs; i++, pReg++)
    {
        printf("%2ld. %-*.*s ", i, MAX_NAME_DISPLAY, MAX_NAME_DISPLAY, pReg->sName);

        if (WDC_WRITE == pReg->direction)
        {
            printf("Write-only register\n");
            continue;
        }

        switch (pReg->dwSize)
        {
        case WDC_SIZE_8:
            dwStatus = fPciCfg ? WDC_PciReadCfg8(hDev, pReg->dwOffset, &bData) :
                WDC_ReadAddr8(hDev, pReg->dwAddrSpace, pReg->dwOffset, &bData);
            if (WD_STATUS_SUCCESS == dwStatus)
                printf("0x%-*X  ", (int)WDC_SIZE_64 * 2, (UINT32)bData);
            break;
        case WDC_SIZE_16:
            dwStatus = fPciCfg ?  WDC_PciReadCfg16(hDev, pReg->dwOffset, &wData) :
                WDC_ReadAddr16(hDev, pReg->dwAddrSpace, pReg->dwOffset, &wData);
            if (WD_STATUS_SUCCESS == dwStatus)
                printf("0x%-*hX  ", (int)WDC_SIZE_64 * 2, wData);
            break;
        case WDC_SIZE_32:
            dwStatus = fPciCfg ?  WDC_PciReadCfg32(hDev, pReg->dwOffset, &u32Data) :
                WDC_ReadAddr32(hDev, pReg->dwAddrSpace, pReg->dwOffset, &u32Data);
            if (WD_STATUS_SUCCESS == dwStatus)
                printf("0x%-*X  ", (int)WDC_SIZE_64 * 2, u32Data);
            break;
        case WDC_SIZE_64:
            dwStatus = fPciCfg ?  WDC_PciReadCfg64(hDev, pReg->dwOffset, &u64Data) :
                WDC_ReadAddr64(hDev, pReg->dwAddrSpace, pReg->dwOffset, &u64Data);
            if (WD_STATUS_SUCCESS == dwStatus)
                printf("0x%-*"PRI64"X  ", (int)WDC_SIZE_64 * 2, u64Data);
            break;
        default:
            printf("Invalid register size (%ld)\n", pReg->dwSize);
            return;
        }

        if (WD_STATUS_SUCCESS != dwStatus)
            printf("Error: 0x%-*lx  ", (int)WDC_SIZE_64 * 2 - 7, dwStatus);
        
        printf("%.*s\n", 43, pReg->sDesc);
    }

    printf("\n");
    printf("Press ENTER to continue\n");
    fgets(gsInput, sizeof(gsInput), stdin);
}

/* Display a list of pre-defined run-time or PCI configuration registers
   and let user select to read/write from/to a specific register */
void WDC_DIAG_ReadWriteReg(WDC_DEVICE_HANDLE hDev, const WDC_REG *pRegs,
    DWORD dwNumRegs, WDC_DIRECTION direction, BOOL fPciCfg)
{
    DWORD dwStatus;
    DWORD dwReg;
    const WDC_REG *pReg; 
    BYTE bData = 0;
    WORD wData = 0;
    UINT32 u32Data = 0;
    UINT64 u64Data = 0;
    
    if (!hDev)
    {
        WDC_DIAG_ERR("WDC_DIAG_ReadWriteReg: Error - NULL WDC device handle\n");
        return;
    }

    if (!dwNumRegs || !pRegs)
    {
        WDC_DIAG_ERR("WDC_DIAG_ReadWriteReg: %s\n",
            !dwNumRegs ? "No registers to read/write (dwNumRegs == 0)" :
            "Error - NULL registers pointer");
        
        return;
    }

    /* Display pre-defined registers' information */
    printf("\n");
    printf("PCI %s registers:\n", fPciCfg ? "configuration" : "run-time");
    printf("----------------------------\n");   
    WDC_DIAG_RegsInfoPrint(pRegs, dwNumRegs, WDC_DIAG_REG_PRINT_ALL);

    /* Read/write register */
    printf("\n");
    printf("Select a register from the list above to %s or 0 to cancel: ",
        (WDC_READ == direction) ? "read from" : "write to");
    fgets(gsInput, sizeof(gsInput), stdin);
    if (sscanf(gsInput, "%ld", &dwReg) < 1)
    {
        printf("Invalid selection\n");
        goto Exit;
    }
    
    if (!dwReg)
        return;

    if (dwReg > dwNumRegs)
    {
        printf("Selection (%ld) is out of range (1 - %ld)\n",
            dwReg, dwNumRegs);
        goto Exit;
    }

    pReg = &pRegs[dwReg - 1];


    if ( ((WDC_READ == direction) && (WDC_WRITE == pReg->direction)) ||
        ((WDC_WRITE == direction) && (WDC_READ == pReg->direction)))
    {
        printf("Error - you have selected to %s a %s-only register\n",
            (WDC_READ == direction) ? "read from" : "write to",
            (WDC_WRITE == pReg->direction) ? "write" : "read");
        goto Exit;
    }

    if ((WDC_WRITE == direction) &&
        !WDC_DIAG_InputWriteData((WDC_SIZE_8 == pReg->dwSize) ? (PVOID)&bData :
        (WDC_SIZE_16 == pReg->dwSize) ? (PVOID)&wData :
        (WDC_SIZE_32 == pReg->dwSize) ? (PVOID)&u32Data : (PVOID)&u64Data,
        pReg->dwSize))
    {
        goto Exit;
    }

    switch (pReg->dwSize)
    {
    case WDC_SIZE_8:
        if (WDC_READ == direction)
            dwStatus = fPciCfg ? WDC_PciReadCfg8(hDev, pReg->dwOffset, &bData) :
                WDC_ReadAddr8(hDev, pReg->dwAddrSpace, pReg->dwOffset, &bData);
        else
            dwStatus = fPciCfg ? WDC_PciWriteCfg8(hDev, pReg->dwOffset, bData) :
                WDC_WriteAddr8(hDev, pReg->dwAddrSpace, pReg->dwOffset, bData);
        if (WD_STATUS_SUCCESS == dwStatus)
        {
            printf("%s 0x%X %s register %s\n", (WDC_READ == direction) ? "Read" : "Wrote",
                (UINT32)bData, (WDC_READ == direction) ? "from" : "to", 
                pReg->sName);
        }
        break;
    case WDC_SIZE_16:
        if (WDC_READ == direction)
            dwStatus = fPciCfg ? WDC_PciReadCfg16(hDev, pReg->dwOffset, &wData) :
                WDC_ReadAddr16(hDev, pReg->dwAddrSpace, pReg->dwOffset, &wData);
        else
            dwStatus = fPciCfg ? WDC_PciWriteCfg16(hDev, pReg->dwOffset, wData) :
                WDC_WriteAddr16(hDev, pReg->dwAddrSpace, pReg->dwOffset, wData);
        if (WD_STATUS_SUCCESS == dwStatus)
        {
            printf("%s 0x%hX %s register %s\n", (WDC_READ == direction) ? "Read" : "Wrote",
                wData, (WDC_READ == direction) ? "from" : "to", pReg->sName);
        }
        break;

⌨️ 快捷键说明

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