where is "resource_list" defined ?

Liu Wang liuw at supermicro.com
Wed Nov 16 00:01:05 UTC 2011


John-Mark Gurney,

Appreciate the help buddy.

Will do accordingly.

Sincerely,
Liu Wang

-----Original Message-----
From: John-Mark Gurney [mailto:jmg at funkthat.com] 
Sent: Tuesday, November 15, 2011 3:55 PM
To: Liu Wang
Cc: freebsd-drivers at freebsd.org
Subject: Re: where is "resource_list" defined ?

Liu Wang wrote this message on Tue, Nov 15, 2011 at 14:41 -0800:
> Appreciate any help here.
> 
> The project is to port our PCIe controller card to FreeBSD from Linux.
> When porting Linux function "pci_request_regions()" to FreeBSD we met the compiling error "error: dereferencing pointer to incomplete type" at the c sentences of "rl = &dinfo->resources;" in the following code segment.

This is because you don't access the PCI(e) information like that...

You should just use bus_alloc_resource_any(9), and not try to grok the
pci resource information directly...  There is also a function
bus_alloc_resources (we don't appear to have a man page for it) which
is used to allocate multiple resources, and properly release them if
any of them fail...  Take a look at sys/dev/sis/if_sis.c for an example
of bus_alloc_resources...

Feel free to look at another driver for some examples on how to do this...
Or look in the FreeBSD Architecture Handbook:
http://www.freebsd.org/doc/en/books/arch-handbook/pci.html
Though that doesn't contain information on how to allocate resources...
In the directory /usr/share/examples/drivers, there is a README and a
script on creating a device driver, but it is targeted at ISA, but
the calls are similar...

Also, I did a presentation a number of years back on writing FreeBSD
device drivers, and posted the slides and links to source at:
http://people.freebsd.org/~jmg/drivers/

Most of the information is still valid, but one major change is that
to support systems w/ multiple PCI domains, we have added a
bus_get_dma_tag function...  This gets the parent bus's dma tag to
apply additional restrictions (like boundary) to the transfers and to
be able to properly handle IOMMU's on systems that have them (sparc64)...

> "make depend" has been launched in kernel level and doesn't help.
> 
> Local type casting has been tried and doesn't help either.
> 
> Looks we go astray the PCIe porting methodology in FreeBSD.

I have some comments down below...

Good luck, if you have more questions, feel free to ask...

> /*----------------------------
> *
> * AOC_main.c
> *
> * x8 PCIe controller driver
>  ---------------------------*/
> #include <sys/param.h>
> #include <sys/module.h>
> #include <sys/kernel.h>
> #include <sys/systm.h>
> #include <sys/errno.h>
> #include <sys/conf.h>
> #include <sys/uio.h>
> #include <sys/malloc.h>
> #include <sys/bus.h>
> #include <sys/types.h>
> #include <machine/bus.h>
> #include <sys/rman.h>
> #include <machine/resource.h>
> 
> #include <dev/pci/pcivar.h>
> #include <dev/pci/pcireg.h>
> #include <sys/queue.h>
> #include <sys/bus.h>
> #include <sys/pciio.h>
> #include <dev/pci/pci_private.h>
> #include <asm/atomic.h>
> #include <bus_if.h>
> #include <AOC.h>
> #define VENDOR_ID  0x1b4b
> #define MAX_REQUEST_NUMBER_PERFORMANCE        4096
> 
> 
> struct AOC_softc
> {
>   device_t AOC_dev;
>   struct cdev *AOC_cdev;
> };
> 
> static int AOC_pci_request_regions( struct device *dev, const char *res_name )
> {
>   int i,j;
>   int rid;
>   int bar;
>   struct resource_list_entry *rle;
>   struct pci_devinfo *dinfo;
>   struct resource_list *rl=NULL;
> 
>   for ( i = 0; i <= PCIR_MAX_BAR_0; i++ )
>   {
>     bar = PCIR_BAR( i );
>     dinfo = dev->ivars;

Don't do this.. use the ivars accessor methods...

The following code isn't nedded:
>     rl = &dinfo->resources;
>     rle = resource_list_find( rl, SYS_RES_MEMORY, i );
>     if( rle == NULL )
>     {
>       dinfo = device_get_ivars(dev);
>       rl = &dinfo->resources;
>       rle = resource_list_find( rl, SYS_RES_IOPORT, i );
>     };
>     if( rle == NULL )
>     return (-ENODEV);
>     rid = PCIR_BAR( i );

If you are using _any, just set the type to what you want, SYS_RES_MEMORY
or SYS_RES_IRQ, and the value pointed to rid to the BAR offset or IRQ number,
something like:
rid = 0x10;
>     if (bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE) == NULL)

>     if (bus_alloc_resource_any(dev, rle->type, &rid, RF_ACTIVE) == NULL)
>     {

This code is also unnecessary:
>       for (j = 0; j <= PCIR_MAX_BAR_0; j++)
>       {
>         {
>           bar = PCIR_BAR( bar );
>           {
>             dinfo = device_get_ivars( dev );
>             rle = resource_list_find( rl, SYS_RES_MEMORY, j );
>           };
>           if ( rle == NULL )
>           {
>               dinfo = device_get_ivars( dev );
>               rl = &dinfo->resources;
>               rle = resource_list_find( rl, SYS_RES_IOPORT, i );
>           };
>         };
>                 if (rle == NULL)
>                 bus_release_resource(dev, rle->type, rle->rid, rle->res);
>       };
>       return (-EINVAL);
>     };
>   }
>   return (0);
> };
> 
> static int AOC_probe( device_t dev )
> {
>   device_printf( dev, "AOC Probe\nVendor ID : 0x%x\nDevice ID : 0x%x\n", pci_get_vendor( dev ), pci_get_device( dev ) );
>   if ( pci_get_vendor( dev ) == VENDOR_ID )
>   {
>     printf( "AOC probe successful !\n" );
>     device_set_desc( dev, "AOC");
> 
>     pci_enable_io( dev, SYS_RES_IOPORT );
>     pci_enable_io( dev, SYS_RES_MEMORY );
> 
>     AOC_pci_request_regions(dev, "AOC");
>     ...
>     ...
> };

-- 
  John-Mark Gurney				Voice: +1 415 225 5579

P
     "All that I will do, has been done, All that I have, has not."




More information about the freebsd-drivers mailing list