📄 wdc_general.c
字号:
static DWORD PciSlotToId(const WD_PCI_SLOT *pSlot, WD_PCI_ID *pId)
{
DWORD dwStatus, i;
WD_PCI_SCAN_CARDS scanDevices;
BZERO(scanDevices); /* scanCards.searchId.dwVendorId/dwDeviceId = 0 - all cards */
dwStatus = WD_PciScanCards(ghWD, &scanDevices);
if (WD_STATUS_SUCCESS != dwStatus)
{
WdcSetLastErrStr("Failed scanning PCI bus.\n",
"Error 0x%lx - %s\n", dwStatus, Stat2Str(dwStatus));
return dwStatus;
}
for (i = 0; i < scanDevices.dwCards; i++)
{
if ((scanDevices.cardSlot[i].dwBus == pSlot->dwBus) &&
(scanDevices.cardSlot[i].dwSlot == pSlot->dwSlot) &&
(scanDevices.cardSlot[i].dwFunction == pSlot->dwFunction))
{
pId->dwVendorId = scanDevices.cardId[i].dwVendorId;
pId->dwDeviceId = scanDevices.cardId[i].dwDeviceId;
return WD_STATUS_SUCCESS;
}
}
WdcSetLastErrStr("Failed to locate the device "
"(bus: 0x%lx, slot: 0x%lx, function: 0x%lx)\n",
pSlot->dwBus, pSlot->dwSlot, pSlot->dwFunction);
return WD_DEVICE_NOT_FOUND;
}
static DWORD PcmciaSlotToId(const WD_PCMCIA_SLOT *pSlot, WD_PCMCIA_ID *pId)
{
DWORD dwStatus, i;
WD_PCMCIA_SCAN_CARDS scanDevices;
BZERO(scanDevices); /* scanCards.searchId.wManufacturerId/wCardId = 0 - all cards */
dwStatus = WD_PcmciaScanCards(ghWD, &scanDevices);
if (WD_STATUS_SUCCESS != dwStatus)
{
WdcSetLastErrStr("Failed scanning PCMCIA bus.\n",
"Error 0x%lx - %s\n", dwStatus, Stat2Str(dwStatus));
return dwStatus;
}
for (i = 0; i < scanDevices.dwCards; i++)
{
if ((scanDevices.cardSlot[i].uBus == pSlot->uBus) &&
(scanDevices.cardSlot[i].uSocket == pSlot->uSocket) &&
(scanDevices.cardSlot[i].uFunction == pSlot->uFunction))
{
pId->wManufacturerId = scanDevices.cardId[i].wManufacturerId;
pId->wCardId = scanDevices.cardId[i].wCardId;
return WD_STATUS_SUCCESS;
}
}
WdcSetLastErrStr("Failed to locate the device "
"(socket: 0x%x, function: 0x%x)\n", pSlot->uSocket, pSlot->uFunction);
return WD_DEVICE_NOT_FOUND;
}
static PWDC_DEVICE DeviceCreate(const PVOID pDeviceInfo, const PVOID pDevCtx,
WD_BUS_TYPE bus)
{
PWDC_DEVICE pDev;
pDev = (PWDC_DEVICE)malloc(sizeof(WDC_DEVICE));
if (!pDev)
{
WdcSetLastErrStr("Failed to allocate memory for the device\n");
return NULL;
}
BZERO(*pDev);
switch (bus)
{
case WD_BUS_PCI:
{
WD_PCI_CARD_INFO *pInfo = (WD_PCI_CARD_INFO*)pDeviceInfo;
pDev->slot.pciSlot = pInfo->pciSlot;
pDev->cardReg.Card = pInfo->Card;
if (WD_STATUS_SUCCESS != PciSlotToId(&pDev->slot.pciSlot, &pDev->id.pciId))
goto Error;
break;
}
case WD_BUS_PCMCIA:
{
WD_PCMCIA_CARD_INFO *pInfo = (WD_PCMCIA_CARD_INFO*)pDeviceInfo;
pDev->slot.pcmciaSlot = pInfo->pcmciaSlot;
pDev->cardReg.Card = pInfo->Card;
if (WD_STATUS_SUCCESS != PcmciaSlotToId(&pDev->slot.pcmciaSlot, &pDev->id.pcmciaId))
goto Error;
break;
}
case WD_BUS_ISA:
{
pDev->cardReg.Card = *(WD_CARD*)pDeviceInfo;
break;
}
default:
WdcSetLastErrStr("Error - Invalid bus type (0x%lx)\n", bus);
goto Error;
break;
}
pDev->pCtx = pDevCtx;
return pDev;
Error:
DeviceDestroy(pDev);
return NULL;
}
static DWORD DeviceOpen(WDC_DEVICE_HANDLE *phDev, const PVOID pDeviceInfo,
const PVOID pDevCtx, const CHAR *pcKPDriverName, PVOID pKPOpenData,
WD_BUS_TYPE bus)
{
DWORD dwStatus;
PWDC_DEVICE pDev;
if (!WdcIsValidPtr(phDev, "NULL device handle pointer") ||
!WdcIsValidPtr(pDeviceInfo, "NULL pointer to device's resources information struct"))
{
return WD_INVALID_PARAMETER;
}
*phDev = NULL;
pDev = DeviceCreate(pDeviceInfo, pDevCtx, bus);
if (!pDev)
return WD_INSUFFICIENT_RESOURCES;
dwStatus = WD_CardRegister(ghWD, &pDev->cardReg);
if (WD_STATUS_SUCCESS != dwStatus)
{
WdcSetLastErrStr("Failed registering the device. Error 0x%lx - %s\n",
dwStatus, Stat2Str(dwStatus));
goto Error;
}
dwStatus = SetDeviceInfo(pDev);
if (WD_STATUS_SUCCESS != dwStatus)
goto Error;
/* Set device handle before KP open to enable passing &hDev as pOpenData */
*phDev = (WDC_DEVICE_HANDLE)pDev;
if (pcKPDriverName && strcmp(pcKPDriverName, ""))
{
dwStatus = KernelPlugInOpen(*phDev, pcKPDriverName, pKPOpenData);
if(dwStatus != WD_STATUS_SUCCESS)
goto Error;
}
return WD_STATUS_SUCCESS;
Error:
DeviceClose((WDC_DEVICE_HANDLE)pDev);
*phDev = NULL;
return dwStatus;
}
static void DeviceDestroy(PWDC_DEVICE pDev)
{
if (!pDev)
return;
if (pDev->pAddrDesc)
free(pDev->pAddrDesc);
free(pDev);
}
static DWORD DeviceClose(WDC_DEVICE_HANDLE hDev)
{
DWORD dwStatus = WD_STATUS_SUCCESS;
PWDC_DEVICE pDev = (PWDC_DEVICE)hDev;
if (!WdcIsValidDevHandle(hDev))
return WD_INVALID_PARAMETER;
if (pDev->hIntThread)
{
dwStatus = WDC_IntDisable(hDev);
if (WD_STATUS_SUCCESS != dwStatus)
{
WdcSetLastErrStr("Failed disabling interrupt. Error 0x%lx - %s\n",
dwStatus, Stat2Str(dwStatus));
}
}
if (pDev->hEvent)
{
dwStatus = WDC_EventUnregister(hDev);
if (WD_STATUS_SUCCESS != dwStatus)
{
WdcSetLastErrStr("Failed unregistering events. Error 0x%lx - %s\n",
dwStatus, Stat2Str(dwStatus));
}
}
if (WDC_IS_KP(pDev))
{
dwStatus = WD_KernelPlugInClose(ghWD, &pDev->kerPlug);
if (WD_STATUS_SUCCESS != dwStatus)
{
WdcSetLastErrStr("Failed closing Kernel PlugIn handle 0x%lx.\n"
"Error 0x%lx - %s\n", WDC_GET_KP_HANDLE(pDev), dwStatus,
Stat2Str(dwStatus));
}
}
if (pDev->kerPlug.pcDriverName)
free(pDev->kerPlug.pcDriverName);
if (WDC_GET_CARD_HANDLE(pDev))
{
dwStatus = WD_CardUnregister(ghWD, &pDev->cardReg);
if (WD_STATUS_SUCCESS != dwStatus)
{
WdcSetLastErrStr("Failed unregistering the device (handle 0x%lx).\n"
"Error 0x%lx - %s\n",
WDC_GET_CARD_HANDLE(pDev), dwStatus, Stat2Str(dwStatus));
}
}
DeviceDestroy(pDev);
return dwStatus;
}
static DWORD KernelPlugInOpen(WDC_DEVICE_HANDLE hDev,
const CHAR *pcKPDriverName, PVOID pKPOpenData)
{
DWORD dwStatus;
PWDC_DEVICE pDev = (PWDC_DEVICE)hDev;
pDev->kerPlug.pcDriverName = strdup(pcKPDriverName);
pDev->kerPlug.pOpenData = pKPOpenData;
dwStatus = WD_KernelPlugInOpen(ghWD, &pDev->kerPlug);
if (WD_STATUS_SUCCESS != dwStatus)
{
WdcSetLastErrStr("Failed opening a handle to the Kernel PlugIn.\n"
"Error 0x%lx - %s\n", dwStatus, Stat2Str(dwStatus));
}
return dwStatus;
}
#define MAX_ADDR_SPACE_NUM WD_CARD_ITEMS
static DWORD SetDeviceInfo(PWDC_DEVICE pDev)
{
DWORD i;
DWORD dwNumAddrs = 0;
DWORD dwNumItems = pDev->cardReg.Card.dwItems;
WD_ITEMS *pItem = pDev->cardReg.Card.Item;
WDC_ADDR_DESC addrDescs[MAX_ADDR_SPACE_NUM];
WDC_ADDR_DESC *pAddrDesc;
BZERO(addrDescs);
for (i=0; i<dwNumItems; i++, pItem++)
{
switch (pItem->item)
{
case ITEM_INTERRUPT:
pDev->Int.hInterrupt = pItem->I.Int.hInterrupt;
pDev->Int.dwOptions = pItem->I.Int.dwOptions;
break;
case ITEM_MEMORY:
case ITEM_IO:
if (pItem->item == ITEM_MEMORY)
{
pAddrDesc = &addrDescs[pItem->I.Mem.dwBar];
pAddrDesc->fIsMemory = TRUE;
pAddrDesc->dwAddrSpace = pItem->I.Mem.dwBar;
pAddrDesc->kptAddr = pItem->I.Mem.dwTransAddr;
pAddrDesc->dwUserDirectMemAddr = pItem->I.Mem.dwUserDirectAddr;
pAddrDesc->dwBytes = pItem->I.Mem.dwBytes;
}
else
{
pAddrDesc = &addrDescs[pItem->I.IO.dwBar];
pAddrDesc->fIsMemory = FALSE;
pAddrDesc->dwAddrSpace = pItem->I.IO.dwBar;
pAddrDesc->kptAddr = pItem->I.IO.dwAddr;
pAddrDesc->dwBytes = pItem->I.IO.dwBytes;
}
pAddrDesc->dwItemIndex = i;
dwNumAddrs = MAX(pAddrDesc->dwAddrSpace + 1, dwNumAddrs);
break;
default:
break;
}
}
if (dwNumAddrs)
{
pDev->pAddrDesc = (WDC_ADDR_DESC*)malloc(dwNumAddrs * sizeof(WDC_ADDR_DESC));
if (!pDev->pAddrDesc)
{
WdcSetLastErrStr("Failed allocating memory for address spaces "
"description (insufficient resources)\n");
return WD_INSUFFICIENT_RESOURCES;
}
memcpy(pDev->pAddrDesc, addrDescs, dwNumAddrs * sizeof(addrDescs[0]));
pDev->dwNumAddrSpaces = dwNumAddrs;
}
return WD_STATUS_SUCCESS;
}
#endif
/* -----------------------------------------------
Set card cleanup commands
----------------------------------------------- */
DWORD WDC_CardCleanupSetup(WDC_DEVICE_HANDLE hDev, WD_TRANSFER *Cmd,
DWORD dwCmds, BOOL bForceCleanup)
{
PWDC_DEVICE pDev = (PWDC_DEVICE)hDev;
WD_CARD_CLEANUP cardCleanup;
if (!Cmd || !dwCmds)
return WD_INVALID_PARAMETER;
cardCleanup.hCard = WDC_GET_CARD_HANDLE(pDev);
cardCleanup.Cmd = Cmd;
cardCleanup.dwCmds = dwCmds;
cardCleanup.dwOptions = bForceCleanup ? WD_FORCE_CLEANUP : 0;
return WD_CardCleanupSetup(ghWD, &cardCleanup);
}
/* -----------------------------------------------
Send Kernel PlugIn messages
----------------------------------------------- */
DWORD DLLCALLCONV WDC_CallKerPlug(WDC_DEVICE_HANDLE hDev, DWORD dwMsg,
PVOID pData, PDWORD pdwResult)
{
DWORD dwStatus;
PWDC_DEVICE pDev = (PWDC_DEVICE)hDev;
WD_KERNEL_PLUGIN_CALL kpCall;
BZERO(kpCall);
kpCall.hKernelPlugIn = WDC_GET_KP_HANDLE(pDev);
kpCall.dwMessage = dwMsg;
kpCall.pData = pData;
dwStatus = WD_KernelPlugInCall(ghWD, &kpCall);
if (WD_STATUS_SUCCESS != dwStatus)
{
WDC_Err("WDC_CallKerPlug: Failed sending 0x%lx message to the Kernel PlugIn (%s).\n"
"Error 0x%lx - %s\n",
dwMsg, pDev->kerPlug.pcDriverName, dwStatus, Stat2Str(dwStatus));
}
else if (pdwResult)
*pdwResult = kpCall.dwResult;
return dwStatus;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -