> It's less ugly than it used to be, esp. with the bus_read_X() stuff.  There's 
> no separate bus_alloc_resource/bus_setup_intr for interrupts though for 
> example, just bus_setup_intr() equivalent.  This is pretty simple though:
> 
>       /* OS X */
>       IOMemoryMap *myBarMap;
>       void *myBar;
>       u_int32_t reg;
> 
>       /* BAR 0 */
>       myBarMap = 
> provider->mapDeviceMemoryWithRegister(kIOPCIConfigBaseAddress0);
>       myBar = myBarMap->getVirtualAddress();
> 
>       reg = OSReadLittleInt32(myBar, FOO_REG);
>       reg |= BAR_FLAG;
>       OSWriteLittleIntew(myBar, FOO_REG, reg);
> 
>       myBar->release();
> 
> In FreeBSD-7 this is something like:
> 
>       struct resource *res;
>       int rid;
>       u_int32_t reg;

uint32_t is the standards compliant spelling :-)

>       rid = PCIR_BAR(0);
>       res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE);

The above should be shortenable to:
        res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, PCIR_BAR(0), 
RF_ACTIVE);

because we don't need to have rid be a pointer.

>       /* XXX: Not sure about endian.. stream_read maybe? */

no.  bus_read is correct, because the pci bus is little endian by
definition.  bus_stream_read will read/write from native endian to bus
endian.

>       reg = bus_read_4(res, FOO_REG);
>       reg |= BAR_FLAG;
>       bus_write_4(res, FOO_REG, reg);
> 
>       bus_release_resource(dev, SYS_RES_MEMORY, rid, res);

We should be able to shorten that to:
        bus_release_resource(dev, res);
these days.

> Which is very similar though there is some clutter (bus_release_resource() 
> should take fewer args, like just dev and res, and it would be nice to say 
> something like map_bar(dev, PCIR_BAR(0)) and get back a resource *).

Agreed.  If you have mutliple resources, you can stack them up as well.

> Usually drivers come up with macros to hide the bus handles and tags which is 
> an indication that they were quite unsightly (thankfully that's been fixed in 
> 7). :)

I usually do:

#define RD4(sc, r)      bus_read_4(sc->res, (r))
#define WR4(sc, r, v)   bus_write_4(sc->res, (r), (v))

which makes usage even shorter.  It also helps me hid cross-version
differences...

> Anyways, if you took FreeBSD-7 and cut down some of the gunk similar to OS X 
> you'd have something like:
> 
>       struct resource *res;
>       u_int32_t reg;
> 
>       res = pci_alloc_bar(dev, PCIR_BAR(0));
> 
>       /* XXX: endian question again */
>       reg = bus_read_4(res, FOO_REG);
>       reg |= BAR_FLAG;
>       bus_write_4(res, FOO_REG, reg);
> 
>       bus_release_resource(dev, res);
> 
> Which is at least somewhat better I think.

In the case where you don't care what kind of mapping you get, that
would work great.

It wouldn't be too hard to implement a pci_alloc_bar that does the
default allocation and mapping.  Changing some of the other APIs would
be more difficult...

> > Also, in FreeBSD, the resources are already allocated by the bus
> > code.  It just changes ownership to the child when the request comes
> > in...
> 
> Yes, this has been a recent improvement.

Yes.  We also do it in a lazy way so that if the resource is allocated
or not is transparent to the driver and the system.  If it could be
decoded, we reserve it.

Warner
_______________________________________________
freebsd-hackers@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-hackers
To unsubscribe, send any mail to "[EMAIL PROTECTED]"

Reply via email to