////////////////////////////////////////////////////////////////
// File - PCI_SCAN.C
//
// A utility for getting a list of the PCI cards installed 
// and the resources allocated for each one of them (memory 
// ranges, IO ranges and interrupts).
// 
////////////////////////////////////////////////////////////////

#include <stdio.h>
#include "../../include/windrvr.h"

void WD_CARD_print(WD_CARD *pCard)
{
    DWORD i;

    for (i=0; i<pCard->dwItems; i++)
    {
        WD_ITEMS item = pCard->Item[i];
        printf ("    Item ");
        switch (item.item)
        {
        case ITEM_MEMORY:
            printf ("Memory: range 0x%x-0x%x", 
                item.I.Mem.dwPhysicalAddr, item.I.Mem.dwPhysicalAddr+item.I.Mem.dwBytes-1);
            break;
        case ITEM_IO:
            printf ("IO: range 0x%x-0x%x", 
                item.I.IO.dwAddr, item.I.IO.dwAddr+item.I.IO.dwBytes-1);
            break;
        case ITEM_INTERRUPT:
            printf ("Interrupt: irq %d", item.I.Int.dwInterrupt);
            break;
        case ITEM_BUS:
            printf ("Bus: type %d, bus number %d, slot/func 0x%x", 
                item.I.Bus.dwBusType, item.I.Bus.dwBusNum, item.I.Bus.dwSlotFunc);
            break;
        default:
            printf ("Invalid item type");
            break;
        }
        printf ("\n");
    }
}

int main (int argc, char *argv[]) 
{
    HANDLE hWD;
    int i;
    WD_PCI_SCAN_CARDS pciScan;
    WD_PCI_SLOT pciSlot;
    WD_PCI_ID   pciId;
    WD_VERSION ver;
    WD_PCI_CARD_INFO pciCardInfo;

    hWD = WD_Open();
    // Check whether handle is valid and version OK
    if (hWD==INVALID_HANDLE_VALUE) 
    {
        printf("Failed opening WinDriver kernel module\n");
        return -1;
    }

    BZERO(ver);
    WD_Version(hWD, &ver);
    if (ver.dwVer<WD_VER) 
    {
        printf("Incorrect WinDriver version\n");
        WD_Close(hWD);
        return -1;
    }

    BZERO(pciScan);
    pciScan.searchId.dwVendorId = 0;
    pciScan.searchId.dwDeviceId = 0;

    printf ("Pci bus scan:\n\n");
    WD_PciScanCards (hWD,&pciScan);

    for (i=0; i<(int)pciScan.dwCards; i++)
    {
        CHAR tmp[100];
        pciId = pciScan.cardId[i];
        pciSlot = pciScan.cardSlot[i];
        printf("Bus %d Slot %d Function %d, VendorID %04x DeviceID %04x\n",
            pciSlot.dwBus, pciSlot.dwSlot, pciSlot.dwFunction, pciId.dwVendorId,
            pciId.dwDeviceId);

        // retrieve and print card information
        BZERO(pciCardInfo);
        pciCardInfo.pciSlot = pciSlot;
        WD_PciGetCardInfo (hWD, &pciCardInfo);
        WD_CARD_print(&pciCardInfo.Card);

        printf("Press Enter to continue to next slot\n");
        fgets(tmp, sizeof(tmp), stdin);
    }
    WD_Close (hWD);
    return 0;
}