Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 28 Apr 2005 21:19:33 -0600 (MDT)
From:      "M. Warner Losh" <imp@bsdimp.com>
To:        cole@opteqint.net
Cc:        freebsd-hackers@freebsd.org
Subject:   Re: PCI Programming
Message-ID:  <20050428.211933.27777590.imp@bsdimp.com>
In-Reply-To: <000901c54c19$3dba2570$4206000a@deadmind>
References:  <000901c54c19$3dba2570$4206000a@deadmind>

next in thread | previous in thread | raw e-mail | index | archive | help
In message: <000901c54c19$3dba2570$4206000a@deadmind>
            "Cole" <cole@opteqint.net> writes:

: 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.


FreeBSD's driver enumeration differs in several fundamental ways from
Linux.  In FreeBSD, the PCI bus code will enumerate (which means find)
all the devices on the PCI bus.  For each each of these devices, each
pci driver is presented with the device for its consideration.  The
drivers compete for the device by bidding on it.  Then, in the attach
routine, the resources are allocated.

bus_alloc_resource(9) is how you get resources on FreeBSD.  All the
appropriate masking, etc is done in the pci bus code so you don't have
to know much of anything about bars and the like.  Just pass the
offset of the BAR that describes the resoruce that you want to
allocate (for I/O and Memory, IRQ's aren't described by BARs, but
instead have a dedicated register).

here's a sample driver (it happens to be a slightly edited 'ed' pci
attachment) that should help some.

ed_pci_probe checks to see if this device's ID matches.  ed_pci_attach
(in this example) allocates resources, and calls the MI part of the
driver to do the attachment.  On error, it releases the resoruces,
using a standard routine.  The ed_attach routine also sets up the
ifnet and prints some mostly useless information about the card.

Warner

static struct _pcsid
{
	uint32_t	type;
	const char	*desc;
} pci_ids[] =
{
	{ 0x802910ec,	"NE2000 PCI Ethernet (RealTek 8029)"	},
	{ 0x00000000,	NULL					}
};

static int	ed_pci_probe(device_t);
static int	ed_pci_attach(device_t);

static int
ed_pci_probe(device_t dev)
{
	uint32_t	type = pci_get_devid(dev);
	struct _pcsid	*ep =pci_ids;

	while (ep->type && ep->type != type)
		++ep;
	if (ep->desc == NULL)
		return (ENXIO);
	device_set_desc(dev, ep->desc);
	return (BUS_PROBE_DEFAULT);
}

static int
ed_pci_attach(device_t dev)
{
        struct	ed_softc *sc = device_get_softc(dev);
	struct resource *res;
        int	error;

	res = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid,
	    0ul, ~0ul, size, RF_ACTIVE);
	if (res == NULL)
		return (ENOMEM);
	sc->port_rid = rid;
	sc->port_res = res;
	sc->port_used = size;
	sc->port_bst = rman_get_bustag(res);
	sc->port_bsh = rman_get_bushandle(res);

	res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, RF_ACTIVE
	    | RF_SHAREABLE);
	if (res == NULL) {
		ed_release_resources(dev);
		return (ENOMEM);
	}

        error = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_NET,
	    edintr, sc, &sc->irq_handle);
        if (error) {
                ed_release_resources(dev);
                return (error);
        }
	error = ed_attach(dev);
        if (error)
                ed_release_resources(dev);
	return (error);
}

static device_method_t ed_pci_methods[] = {
	/* Device interface */
	DEVMETHOD(device_probe,		ed_pci_probe),
	DEVMETHOD(device_attach,	ed_pci_attach),
	DEVMETHOD(device_attach,	ed_detach),

	{ 0, 0 }
};

static driver_t ed_pci_driver = {
	"ed",
	ed_pci_methods,
	sizeof(struct ed_softc),
};

DRIVER_MODULE(ed, pci, ed_pci_driver, ed_devclass, 0, 0);
MODULE_DEPEND(ed, pci, 1, 1, 1);
MODULE_DEPEND(ed, ether, 1, 1, 1);



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