PCI Card understanding

Hi All,
I need to develop a driver for Fastcom:ESCC-PCI for serial interface under qnx and I got code from openqnx. Which is working fine for accessing the PCI bus and able to get port address using mmap_device_memory.
Earlier to PCI driver, i have worked on serial driver using devc-ser8250 which ultimately uses the Resource manager for open,read,write,devctl and after loading driver application can use open, write et.
Issues :

  1. Is there any resource manager working behind for PCI driver?
  2. To perform open, read and write on port what API should be used for PCI driver by application ??

Please find my code,
#include <sys/neutrino.h>
#include <hw/pci.h>
#include <hw/pci_devices.h>
#include <stdio.h>
#include <sys/mman.h>
#include <errno.h>

#define PCI_CARD_DEVICE_ID 0x11
#define PCI_CARD_VENDOR_ID 0x18F7

void pci_give_command(uint16_t pci_command, struct pci_dev_info *inf);

void pci_printf(struct pci_dev_info *inf)
{
uint32_t i;

fprintf (stdout, "\n device id = %x", inf->DeviceId); 
fprintf (stdout, "\n Vendo id = %x", inf->VendorId); 
fprintf (stdout, "\n BusNumber = %x", inf->BusNumber); 
fprintf (stdout, "\n device number = %x", ((inf->DevFunc)>>3)&0x1F); 
fprintf (stdout, "\n Function number = %x", (inf->DevFunc)&0x07); 
fprintf (stdout, "\n Revision = %x", inf->Revision); 
fprintf (stdout, "\n device class = %x", inf->Class); 
fprintf (stdout, "\n device irq = %x", inf->Irq); 
fprintf (stdout, "\n pcibase address = %x", (*(inf->CpuBaseAddress))); 
fprintf (stdout, "\n base address size = %x", (*(inf->BaseAddressSize))); 

pci_read_config32 (inf->BusNumber, inf->DevFunc, 0x10, 1, &i); 
fprintf (stdout, "\n Base address 0 = %x", i); 

pci_read_config32 (inf->BusNumber, inf->DevFunc, 0x14, 1, &i); 
fprintf (stdout, "\n Base address 1 = %x", i); 

}

void pci_give_command(uint16_t pci_command, struct pci_dev_info *inf)
{
uint16_t test_read;
pci_write_config16(inf->BusNumber,inf->DevFunc,0x04,1,&pci_command);
pci_read_config16(inf->BusNumber,inf->DevFunc,0x06,1,&test_read);
fprintf(stdout,"\n pci command register ip=%x",pci_command);
fprintf(stdout,"\n pci command register op =%x",test_read);

}

int main(int argc, char *argv)
{
struct pci_dev_info inf;

	int pci_handle; 
	uint32_t addr_handle; 
	uint32_t io_addr; 
	void *addr[2]; 
	void *dev_handle; 
	unsigned index = 0; 
	unsigned bus; 
	unsigned dev; 
	unsigned func; 
	unsigned dev_func; 
	
	volatile uint8_t* x; 
	uint32_t value; 
	
	uint32_t BAR0, BAR1; 
	
			
	//intial some variable 
	memset (&inf, 0, sizeof (struct pci_dev_info)); 
	inf.VendorId = PCI_CARD_VENDOR_ID; 
	inf.DeviceId = PCI_CARD_DEVICE_ID; 
	
	//get the hight provillege 
	ThreadCtl (_NTO_TCTL_IO, 0); 
	
	//open PCI server, so that you can use pci_*() 
	pci_handle = pci_attach(0); 
	if (pci_handle == -1) 
	return 0; 
	
	//detect pci device 
	if (pci_find_device (inf.DeviceId, 
	inf.VendorId,index,&bus,&dev_func) != PCI_SUCCESS) 
	return 0; 
	
	fprintf (stdout," pci_find_device is called");
	
	//get the device information 
	dev_handle = pci_attach_device (NULL, 
	(PCI_SHARE|PCI_SEARCH_VENDEV|PCI_INIT_ALL), 
	0, 
	&inf); 
	if (dev_handle == NULL) 
	return 0; 
	
	fprintf (stdout,"\n pci_attach_device is called \n");
	//print some information which have been found. 
	pci_printf (&inf); 
	
	//get pci address 
	if ( pci_read_config32 (inf.BusNumber, 
	inf.DevFunc, 
	0x10, 
	1, 
	&BAR0)!= PCI_SUCCESS) 
	return 0; 
	
	fprintf (stdout,"\n pci_read_config32 with 10 is called \n ");
	
	//get pci board register address 
	if ( pci_read_config32 (inf.BusNumber, 
	inf.DevFunc, 
	0x14, 
	1, 
	&BAR1)!= PCI_SUCCESS) 
	return 0; 
	
	fprintf (stdout,"\n pci_read_config32 with 14 is called \n ");
	
	//remap pci mite address 
	if (PCI_IS_MEM (BAR0)) 
	addr_handle = PCI_MEM_ADDR (BAR0); 
	else 
	addr_handle = PCI_IO_ADDR (BAR0); 
	
	fprintf (stdout,"\n addr_handle is %d \n ",addr_handle);
	
	addr[0] = mmap_device_memory (NULL, 
	*(inf.BaseAddressSize), 
	(PROT_READ | PROT_WRITE | PROT_NOCACHE),//must NOCACHE 
	0, 
	(uint64_t)addr_handle); 
	
	if (addr[0] == MAP_FAILED) 
	{
		fprintf (stdout,"\n addr_handle is failed BAR 0\n");
		return 0;
	}
	
	//remap pci board address 
	if (PCI_IS_MEM (BAR1)) 
	addr_handle = PCI_MEM_ADDR (BAR1); 
	else 
	addr_handle = PCI_IO_ADDR (BAR1); 
	
	fprintf (stdout,"\n addr_handle is %d \n ",addr_handle);
	
	addr[1] = mmap_device_memory (NULL, 
	*(inf.BaseAddressSize), 
	(PROT_READ | PROT_WRITE | PROT_NOCACHE), 
	0, 
	(uint64_t)addr_handle); 
	
	if (addr[1] == MAP_FAILED) 
	{
		fprintf (stdout,"\n addr_handle is failed BAR 1 \n");
		return 0; 
	}
	
	pci_give_command(0x384, &inf); 
    //release re-map memory 
	if (munmap_device_memory (addr[0], (*(inf.BaseAddressSize))) == -1) 
	fprintf (stdout, "\n Error:munmap ADDR0 failed!"); 
	
	if (munmap_device_memory (addr[1], (*(inf.BaseAddressSize))) == -1) 
	fprintf (stdout, "\n Error:munmap ADDR1 failed!"); 
	
	//release the relation with the device 
	if (pci_detach_device(dev_handle) != PCI_SUCCESS) 
	fprintf(stdout, "\n Error:detach device failed status!\n"); 
	
	//release pci server 
	if (pci_detach (pci_handle) != PCI_SUCCESS) 
	fprintf (stdout, "\n Error:detach pci sever failed status!!%s\n", strerror (errno)); 
	
	fprintf (stdout, "\n======================================================\n"); 
	return 0; 

}

You cannot open/read/write on a PCI resource. The PCI stuff is just for resources allocation it has nothing to do with accessing it (to some degree). Does that answer your question? I’m not sure I understand exactly what you are trying to achieve.

As per my requirement, there is FastCom board which works on the RS 422 serial protocol and this board is inserted PCI bus and ineed to implement the driver to perform open, write, read etc on this board.
I guess, i need to use reource manager and access the port using mmap_device_memory and perform read/ write to that memory handle. Please verify my understanding is correct ???

First do a quick test by using devc-ser8250 and providing on the command line the port and interrupt number of the comm card ( as reported by pci -v ).

If that works, two options:

1 - Write a program that will extra the resource info and that pass it along to devc-ser8250. Someting like devc-ser8250 getFastComResources.

2 - Get the source to devc-ser8250 and add support for PCI resources. Should be simple.

If it doesn’t work that mean the card isn’t not compatible with 8250 register set. Again take the source to devc-ser8250 and modify it to handle your specific hardware.

Hi Mario,
Thanks for your help. I have got the source code that is pci based and ultimatly invoke the devc-ser8250 driver for read, write ( not sure it will do this operation)
I have tried to work for my fastcom but after changing vendor id = 0x18f7 and did = 0x11. It detected my board and creates a cmd line address to invoke the devc-ser8250 driver ( using driver -g board) option.
Tommorrow, i will try to do some loopback to verify the write /read operation. But meanwhile please have a look on my code and inform thats what you were refering to create the pci resource and add it to devc-ser8250 code ??/

From a quick glance it looks ok to me.

I don’t know about the -g option you are refering to.

To be clear you don’t create PCI resource, they are already there. pci-bios creates them for you. You simply access them.