#include	<stdio.h>
#include	<stdlib.h>
#include	<string.h>
#include	<errno.h>
#include	<inttypes.h>
#include	<hw/pci.h>


/************************************************************************/
/*                                                                      */
/************************************************************************/

int		main (int argc, char **argv)

{
struct		pci_dev_info	info;
struct		pci_dev_info	info1;
int			i, phdl, index = 0;
void		*hdl;
uint32_t	vendor, device;

	if (argc < 2) {
		fprintf (stderr, "Usage: pci_att vendor device [index]\n");
		exit (1);
		}
	printf ("Info size %d\n", sizeof (struct pci_dev_info));
	memset ((char *) &info, 0, sizeof (info));
	memset ((char *) &info1, 0, sizeof (info1));
	vendor = strtoul (argv [1], NULL, 0);
	device = strtoul (argv [2], NULL, 0);
	info.VendorId = (uint16_t) vendor;
	info.DeviceId = (uint16_t) device;
	if (argc > 3)
		index = atoi (argv [3]);
	printf ("\nAttach Vendor 0x%x - Device 0x%x - Index %d\n", info.VendorId, info.DeviceId, index);
	if ((phdl = pci_attach (0)) == -1) {
		printf ("Unable to attach - errno %s\n", strerror (errno));
		exit (1);
		}
	if ((hdl = pci_attach_device (NULL, PCI_INIT_ALL | PCI_INIT_ROM | PCI_PERSIST |
		PCI_MASTER_ENABLE | PCI_USE_MSI | PCI_USE_MSIX, index, &info)) == NULL) {
		printf ("Attach error - errno %s\n", strerror (errno));
		exit (1);
		}
	for (i = 0; i < 6; i++) {
		if (info.PciBaseAddress [i] || info.CpuBaseAddress [i] || info.BaseAddressSize [i]) {
			printf ("Base %d - PCI Address 0x%llx - CPU Address 0x%llx - Size 0x%x\n", i,
				info.PciBaseAddress [i], info.CpuBaseAddress [i], info.BaseAddressSize [i]);
			}
		}
	if (info.Irq) {
		printf ("Irq 0x%x\n", info.Irq);
		if (info.NumIrq) {
			i = 0;
			while (info.MsiDefs [i].count) {
				printf ("MSI/X count %d - interrupt 0x%x\n", info.MsiDefs [i].count, info.MsiDefs [i].vector);
				i++;
				}
			}
		}
	if (info.Revision) {
		printf ("Revision 0x%x\n", info.Revision);
		}
	if (info.PciRom) {	
		printf ("ROM Address 0x%llx\n", info.PciRom);
		}
	if (info.CpuIoTranslation) {
		printf ("CPU IO Xlation 0x%llx\n", info.CpuIoTranslation);
		}
	if (info.CpuMemTranslation) {
		printf ("CPU MEM Xlation 0x%llx\n", info.CpuMemTranslation);
		}
	if (info.CpuIsaTranslation) {
		printf ("CPU ISA Xlation 0x%llx\n", info.CpuIsaTranslation);
		}
	if (info.CpuBmstrTranslation) {
		printf ("CPU BMSTR Xlation 0x%llx\n", info.CpuBmstrTranslation);
		}
	printf ("Subsystem Vendor 0x%x - Device 0x%x\n", info.SubsystemVendorId, info.SubsystemId);
	if (info.HeaderType & 1) {
		printf ("Bus I/O Start 0x%llx - Size 0x%llx\n", info.BusIoStart, info.BusIoSize);
		printf ("Bus Mem Start 0x%llx - Size 0x%llx\n", info.BusMemStart, info.BusMemSize);
		printf ("Bus Pref Start 0x%llx - Size 0x%llx\n", info.BusPrefStart, info.BusPrefSize);
		printf ("Primary %d - Secondary %d - Subordinate %d\n", info.PrimaryBus, info.SecondaryBus, info.SubordinateBus);
		}

//	getchar ();
	pci_detach_device (hdl);
	if (pci_detach (phdl))
		fprintf (stderr, "pci_detach1 %s\n", strerror (errno));
	return (0);
}
