📄 whyt1_diag.c
字号:
return DeviceOpen(&slot);
}
/* Find a WHYT1 device */
static BOOL DeviceFind(DWORD dwVendorId, DWORD dwDeviceId, WD_PCI_SLOT *pSlot)
{
DWORD dwStatus;
DWORD i, dwNumDevices;
WDC_PCI_SCAN_RESULT scanResult;
if (dwVendorId == 0)
{
if (DIAG_INPUT_SUCCESS != DIAG_InputDWORD((PVOID)&dwVendorId,
"Enter vendor ID", TRUE, 0, 0))
{
return FALSE;
}
if (DIAG_INPUT_SUCCESS != DIAG_InputDWORD((PVOID)&dwDeviceId,
"Enter device ID", TRUE, 0, 0))
{
return FALSE;
}
}
BZERO(scanResult);
dwStatus = WDC_PciScanDevices(dwVendorId, dwDeviceId, &scanResult);
if (WD_STATUS_SUCCESS != dwStatus)
{
WHYT1_ERR("DeviceFind: Failed scanning the PCI bus.\n"
"Error: 0x%lx - %s\n", dwStatus, Stat2Str(dwStatus));
return FALSE;
}
dwNumDevices = scanResult.dwNumDevices;
if (!dwNumDevices)
{
WHYT1_ERR("No matching device was found for search criteria "
"(Vendor ID 0x%lX, Device ID 0x%lX)\n",
dwVendorId, dwDeviceId);
return FALSE;
}
printf("\n");
printf("Found %ld matching device%s [ Vendor ID 0x%lX%s, Device ID 0x%lX%s ]:\n",
dwNumDevices, dwNumDevices > 1 ? "s" : "",
dwVendorId, dwVendorId ? "" : " (ALL)",
dwDeviceId, dwDeviceId ? "" : " (ALL)");
for (i = 0; i < dwNumDevices; i++)
{
printf("\n");
printf("%2ld. Vendor ID: 0x%lX, Device ID: 0x%lX\n",
i + 1,
scanResult.deviceId[i].dwVendorId,
scanResult.deviceId[i].dwDeviceId);
WDC_DIAG_PciDeviceInfoPrint(&scanResult.deviceSlot[i], FALSE);
}
printf("\n");
if (dwNumDevices > 1)
{
sprintf(gsInput, "Select a device (1 - %ld): ", dwNumDevices);
i = 0;
if (DIAG_INPUT_SUCCESS != DIAG_InputDWORD((PVOID)&i,
gsInput, FALSE, 1, dwNumDevices))
{
return FALSE;
}
}
*pSlot = scanResult.deviceSlot[i - 1];
return TRUE;
}
/* Open a handle to a WHYT1 device */
static WDC_DEVICE_HANDLE DeviceOpen(const WD_PCI_SLOT *pSlot)
{
WDC_DEVICE_HANDLE hDev;
DWORD dwStatus;
WD_PCI_CARD_INFO deviceInfo;
/* Retrieve the device's resources information */
BZERO(deviceInfo);
deviceInfo.pciSlot = *pSlot;
dwStatus = WDC_PciGetDeviceInfo(&deviceInfo);
if (WD_STATUS_SUCCESS != dwStatus)
{
WHYT1_ERR("DeviceOpen: Failed retrieving the device's resources information.\n"
"Error 0x%lx - %s\n", dwStatus, Stat2Str(dwStatus));
return NULL;
}
/* NOTE: You can modify the device's resources information here, if
necessary (mainly the deviceInfo.Card.Items array or the items number -
deviceInfo.Card.dwItems) in order to register only some of the resources
or register only a portion of a specific address space, for example. */
/* Open a handle to the device */
hDev = WHYT1_DeviceOpen(&deviceInfo);
if (!hDev)
{
WHYT1_ERR("DeviceOpen: Failed opening a handle to the device: %s",
WHYT1_GetLastErr());
return NULL;
}
return hDev;
}
/* Close handle to a WHYT1 device */
static void DeviceClose(WDC_DEVICE_HANDLE hDev)
{
if (!hDev)
return;
if (!WHYT1_DeviceClose(hDev))
{
WHYT1_ERR("DeviceClose: Failed closing WHYT1 device: %s",
WHYT1_GetLastErr());
}
}
/* -----------------------------------------------
Read/write memory and I/O addresses
----------------------------------------------- */
/* Read/write address menu options */
enum {
MENU_RW_ADDR_SET_ADDR_SPACE = 1,
MENU_RW_ADDR_SET_MODE,
MENU_RW_ADDR_SET_TRANS_TYPE,
MENU_RW_ADDR_READ,
MENU_RW_ADDR_WRITE,
MENU_RW_ADDR_EXIT = DIAG_EXIT_MENU,
};
#define ACTIVE_ADDR_SPACE_NEEDS_INIT 0xFF
/* Read/write memory or I/O space address menu */
static void MenuReadWriteAddr(WDC_DEVICE_HANDLE hDev)
{
DWORD option;
static DWORD dwAddrSpace = ACTIVE_ADDR_SPACE_NEEDS_INIT;
static WDC_ADDR_MODE mode = WDC_MODE_32;
static BOOL fBlock = FALSE;
/* Initialize active address space */
if (ACTIVE_ADDR_SPACE_NEEDS_INIT == dwAddrSpace)
{
DWORD dwNumAddrSpaces = WHYT1_GetNumAddrSpaces(hDev);
/* Find the first active address space */
for (dwAddrSpace = 0; dwAddrSpace < dwNumAddrSpaces; dwAddrSpace++)
{
if (WDC_AddrSpaceIsActive(hDev, dwAddrSpace))
break;
}
/* Sanity check */
if (dwAddrSpace == dwNumAddrSpaces)
{
WHYT1_ERR("MenuReadWriteAddr: Error - no active address spaces found\n");
dwAddrSpace = ACTIVE_ADDR_SPACE_NEEDS_INIT;
return;
}
}
do
{
printf("\n");
printf("Read/write the device's memory and IO ranges\n");
printf("---------------------------------------------\n");
printf("%d. Change active address space for read/write "
"(currently: BAR %ld)\n", MENU_RW_ADDR_SET_ADDR_SPACE, dwAddrSpace);
printf("%d. Change active read/write mode (currently: %s)\n",
MENU_RW_ADDR_SET_MODE,
(WDC_MODE_8 == mode) ? "8 bit" : (WDC_MODE_16 == mode) ? "16 bit" :
(WDC_MODE_32 == mode) ? "32 bit" : "64 bit");
printf("%d. Toggle active transfer type (currently: %s)\n",
MENU_RW_ADDR_SET_TRANS_TYPE,
(fBlock ? "block transfers" : "non-block transfers"));
printf("%d. Read from active address space\n", MENU_RW_ADDR_READ);
printf("%d. Write to active address space\n", MENU_RW_ADDR_WRITE);
printf("%d. Exit menu\n", MENU_RW_ADDR_EXIT);
printf("\n");
if (DIAG_INPUT_FAIL == DIAG_GetMenuOption(&option,
MENU_RW_ADDR_WRITE))
{
continue;
}
switch (option)
{
case MENU_RW_ADDR_EXIT: /* Exit menu */
break;
case MENU_RW_ADDR_SET_ADDR_SPACE: /* Set active address space for read/write address requests */
{
SetAddrSpace(hDev, &dwAddrSpace);
break;
}
case MENU_RW_ADDR_SET_MODE: /* Set active mode for read/write address requests */
WDC_DIAG_SetMode(&mode);
break;
case MENU_RW_ADDR_SET_TRANS_TYPE: /* Toggle active transfer type */
fBlock = !fBlock;
break;
case MENU_RW_ADDR_READ: /* Read from a memory or I/O address */
case MENU_RW_ADDR_WRITE: /* Write to a memory or I/O address */
{
WDC_DIRECTION direction =
(MENU_RW_ADDR_READ == option) ? WDC_READ : WDC_WRITE;
if (fBlock)
WDC_DIAG_ReadWriteBlock(hDev, direction, dwAddrSpace);
else
WDC_DIAG_ReadWriteAddr(hDev, direction, dwAddrSpace, mode);
break;
}
}
} while (MENU_RW_ADDR_EXIT != option);
}
static void SetAddrSpace(WDC_DEVICE_HANDLE hDev, PDWORD pdwAddrSpace)
{
DWORD dwAddrSpace;
DWORD dwNumAddrSpaces = WHYT1_GetNumAddrSpaces(hDev);
WHYT1_ADDR_SPACE_INFO addrSpaceInfo;
printf("\n");
printf("Select an active address space:\n");
printf("-------------------------------\n");
for (dwAddrSpace = 0; dwAddrSpace < dwNumAddrSpaces; dwAddrSpace++)
{
BZERO(addrSpaceInfo);
addrSpaceInfo.dwAddrSpace = dwAddrSpace;
if (!WHYT1_GetAddrSpaceInfo(hDev, &addrSpaceInfo))
{
WHYT1_ERR("SetAddrSpace: Error - Failed to get address space information: %s",
WHYT1_GetLastErr());
return;
}
printf("%ld. %-*s %-*s %s\n",
dwAddrSpace + 1,
MAX_NAME_DISPLAY, addrSpaceInfo.sName,
MAX_TYPE - 1, addrSpaceInfo.sType,
addrSpaceInfo.sDesc);
}
printf("\n");
if (DIAG_INPUT_SUCCESS != DIAG_InputDWORD((PVOID)&dwAddrSpace,
"Enter option", FALSE, 1, dwNumAddrSpaces))
{
return;
}
dwAddrSpace--;
if (!WDC_AddrSpaceIsActive(hDev, dwAddrSpace))
{
printf("You have selected an inactive address space\n");
return;
}
*pdwAddrSpace = dwAddrSpace;
}
/* -----------------------------------------------
Read/write the configuration space
----------------------------------------------- */
/* Read/write the configuration space menu options */
enum {
MENU_RW_CFG_SPACE_READ_OFFSET = 1,
MENU_RW_CFG_SPACE_WRITE_OFFSET,
MENU_RW_CFG_SPACE_READ_ALL_REGS,
MENU_RW_CFG_SPACE_READ_REG,
MENU_RW_CFG_SPACE_WRITE_REG,
MENU_RW_CFG_SPACE_EXIT = DIAG_EXIT_MENU,
};
/* Display read/write configuration space menu */
static void MenuReadWriteCfgSpace(WDC_DEVICE_HANDLE hDev)
{
DWORD option;
do {
/* Display pre-defined registers' information */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -