Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 28 Apr 2005 15:27:47 -0600
From:      Scott Long <scottl@samsco.org>
To:        Cole <cole@opteqint.net>
Cc:        freebsd-hackers@freebsd.org
Subject:   Re: PCI Programming
Message-ID:  <42715553.6050704@samsco.org>
In-Reply-To: <000901c54c19$3dba2570$4206000a@deadmind>
References:  <000901c54c19$3dba2570$4206000a@deadmind>

next in thread | previous in thread | raw e-mail | index | archive | help
Cole wrote:
> Hey
> 
> Im currently trying to port some linux pci driver to FreeBSD code. But im running into a  problem. Its using a function that I cant
> seem to find the equivalent of for FreeBSD.
> 
> Heres the function up to the point where im getting stuck.
> 
> int FindDevice( void )
> {
> 
>     static struct pci_dev *pciptr;
>     int pci_info_index = 0;
>     U16 wDev;
>     unsigned int tmp_addr;
> 
>         /*-----------------------------------------*/
> #ifdef CONFIG_PCI  // find the specified device and its configuration
>   if( pcibios_present() ){
> 
>     pci_for_each_dev( pciptr ){
>         if ((pciptr->vendor == VENDOR_ID) && \
>             (pciptr->device == DEVICE_ID) && \
>             (pciptr->subsystem_vendor == SUBSYSTEM_VID) && \
>             (pciptr->subsystem_device == SUBSYSTEM_DID) && \
>             (PCI_FUNC(pciptr->devfn) == 0) )
>         {
>                     DevExtension[pci_info_index].wBus= pciptr->bus->number;
>                     DevExtension[pci_info_index].wDevFunc= pciptr->devfn;
>                     DevExtension[pci_info_index].wCard = pci_info_index;
>                     tmp_addr = pci_resource_start( pciptr, 4 );
>                     DevExtension[pci_info_index].func0_bar = (tmp_addr & ~0x03);
> 
> now the function im getting stuck at, is the "tmp_addr = pci_resource_start(pciptr, 4). I was wondering if anyone knows of an
> equivalent under FreeBSD. Or if there is a way to obtain that value with some other method in FreeBSD. I am pretty much fine up
> until that point.
> 
> If anyone has any sample code or anything that I could read to proceed any further, it would be greatly appreciated.
> 
> Regards
> /Cole
> 

I think that you're going to have to ignore trying to do a literal 
transation of this linux code.  It looks like the code in question
is trying to snarf the memory mapped I/O base address at register 0x14 
(0x10 is where the BARs start, so this is 0x10 + 4) in the config space. 
  Linux likes to pretend that these addresses are coherent (which they 
are on i386 and amd64, but not neccesarily for other platforms), so it 
treats them like regular memory.  Why is wants to save the physical
address of the BAR is a mystery, so you might want to track down the 
other places where this structure member is used.  It's likely only
used for informational purposes, in which can you can likely ignore
dealing with it.

The correct way to access the BAR memory in FreeBSD is:

int rid;
bus_handle_t handle;
bus_tag_t tag;

rid = 0x14;
res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE);
tag = rman_get_btag(res);
handle = rman_get_handle(res);

/* Write a DWORD */
bus_space_write_4(tag, handle, offset, val);

/*read a DWORD */
tmp = bus_space_read_4(tag, handle, offset);

This assumes the linux example of wanting BAR1 at offset 0x14.

Scott



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?42715553.6050704>