Skip navigation.
Home
The QNX Community Portal

View topic - PCI Card understanding

PCI Card understanding

For discussion of realtime and/or embedded programming.

PCI Card understanding

Postby garyritu » Thu Jul 23, 2009 3:58 pm

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;
}
garyritu
Active Member
 
Posts: 58
Joined: Fri May 22, 2009 7:09 am

RE: PCI Card understanding

Postby mario » Thu Jul 23, 2009 4:06 pm

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.
mario
QNX Master
 
Posts: 4132
Joined: Sun Sep 01, 2002 1:04 am

RE: PCI Card understanding

Postby garyritu » Fri Jul 24, 2009 3:20 pm

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 ???
garyritu
Active Member
 
Posts: 58
Joined: Fri May 22, 2009 7:09 am

RE: PCI Card understanding

Postby mario » Fri Jul 24, 2009 4:04 pm

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.
mario
QNX Master
 
Posts: 4132
Joined: Sun Sep 01, 2002 1:04 am

Postby garyritu » Mon Jul 27, 2009 3:10 pm

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 ??/
garyritu
Active Member
 
Posts: 58
Joined: Fri May 22, 2009 7:09 am

Postby mario » Mon Jul 27, 2009 4:03 pm

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.
mario
QNX Master
 
Posts: 4132
Joined: Sun Sep 01, 2002 1:04 am


Return to Realtime and Embedded

Who is online

Users browsing this forum: No registered users and 2 guests

cron