A few questions about SD/MMC drivers

Warner Losh imp at bsdimp.com
Sun Oct 5 23:06:39 UTC 2014


On Oct 5, 2014, at 4:05 PM, Martin Galvan <omgalvan.86 at gmail.com> wrote:

> Hello everyone! I'm currently working on an SD/MMC host controller
> driver for the Allwinner A10 SoC. Looking at some other drivers such
> as at91_mci.c and lpc_mmc.c it seems most if not all of them have
> roughly the same basic structure, so I thought I'd ask you guys a
> couple of questions about them:
> 
> 1) I noticed most MMC drvers allocate their memory and interrupt
> resources using bus_alloc_resource_any by doing something like:
> 
> /* Allocate a memory window */
> rid = 0;
> bus_alloc_resource_any(device, type, &rid, flags);
> 
> /* Some code */
> 
> /*Allocate an interrupt */
> rid = 0;
> bus_alloc_resource_any(device, type, &rid, flags);
> 
> and on error handling code, they do:
> 
> bus_release_resource(device, type, 0, resource);
> 
> Looking at the man pages for both functions, it seems we shouldn't be
> ignoring the returned value of rid after bus_alloc_resource_any. From
> bus_release_resource(9):
> 
> "rid is the resource ID of the resource.  The rid value must be the
> same as the one returned by bus_alloc_resource(9)."
> 
> Is there any reason why we're just passing it a hardcoded 0 instead of
> storing the returned rid?

Because we’re naughty and know that it will always be 0. Yes, this directly
contradicts the man page.

> Furthermore, why are we passing
> bus_alloc_resource_any a value of 0 in the first place? Looking at
> bus_alloc_resource(9):
> 
> "rid points to a bus specific handle that identifies the resource
> being allocated. For ISA this is an index into an array of resources
> that have been setup for this device by either the PnP mechanism, or
> via the hints mechanism. For PCCARD, this is an index into the array
> of resources described by the PC Card's CIS entry. For PCI, the offset
> into pci config space which has the BAR to use to access the resource.
> The bus methods are free to change the RIDs that they are given as a
> parameter.  You must not depend on the value you gave it earlier.”

We know 0 is the right value because 0 is the right value for the bus
that it lives on. :) 

> I'm not implying the existing code is wrong, I'm just curious about
> why are we using those particular values.

Changing it to save the rid would be more pedantically correct, but in
this case, it would result in no changes.

> 2) The code I'm working on is based off the Linux driver for the same
> host, which as of today stands as the only "documentation", so to
> speak, on that particular host. According to the Linux driver, we need
> to do a phase shift adjustment while setting the clock in the set_ios
> function. That involves several steps, one of which is calling
> clk_set_rate, which seems to be a function many other Linux drivers
> use. As I'm not familiar with Linux kernel internals, so far I haven't
> been able to find the equivalent for that function on BSD, so how
> should I go about this?

Most likely you’ll need to write the clock infrastructure for allwinner to
make this work. I don’t believe that it is actually there today. Note: I’ve
not looked at the allwinner core code in a long time, so maybe this
has already been rectified.

clk_set_rate in Linux adjusts the produced clock frequency for a clock
that’s programmable in the SoC.

> 3) Finally, I noticed in the Linux driver they sometimes wrap a
> register read operation around a do-while loop waiting on both the
> result of that read and a timer, like this:
> 
> do {
>    read_value = read_a_register(some_register);
> } while ((read_value != desired_value) && (time_before(jiffies, expire));
> 
> where "expire" is an unsigned long whose value is computed as the sum
> of a global called "jiffies" and the result of a call to
> msecs_to_jiffies(). This is done so after the loop they can check
> whether the register holds the desired value or a timeout occurred. Do
> we have something similar on BSD? If not, what would be a safer way to
> implement a timeout mechanism than simply decreasing a counter?

Usually FreeBSD just uses a big number for the timeout, calculated based
on the bus access speed, some kludge factor and a healthy amount of
rounding up to the next power of 10 when it doesn’t work.

Warner
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 842 bytes
Desc: Message signed with OpenPGP using GPGMail
URL: <http://lists.freebsd.org/pipermail/freebsd-embedded/attachments/20141005/9fc08507/attachment.sig>


More information about the freebsd-embedded mailing list