From owner-freebsd-drivers@FreeBSD.ORG Sun Oct 5 22:05:18 2014 Return-Path: Delivered-To: freebsd-drivers@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id ED24BD63; Sun, 5 Oct 2014 22:05:17 +0000 (UTC) Received: from mail-ob0-x235.google.com (mail-ob0-x235.google.com [IPv6:2607:f8b0:4003:c01::235]) (using TLSv1 with cipher ECDHE-RSA-RC4-SHA (128/128 bits)) (Client CN "smtp.gmail.com", Issuer "Google Internet Authority G2" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id B220D179; Sun, 5 Oct 2014 22:05:17 +0000 (UTC) Received: by mail-ob0-f181.google.com with SMTP id wm4so3134411obc.12 for ; Sun, 05 Oct 2014 15:05:16 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:date:message-id:subject:from:to:cc:content-type; bh=am4l1rFbm7cFrdqYbaCBDQpdYxFp0hdpgYMzii/VvXw=; b=rFUnL5db9RnlVjsiaOMddC7spE/Yh0dXlEyy1gGnWMV1MWZ/7YeGrn/NkXm8C915hK njEG1sRNK3H8eAoUWTbEMEv7hzGD95WrXvdXbHK4c7bsfek1hAZtXz9N1+oh7XKS7j9i pTbZ3VH4FCpLw6+uvuGewkGRlR4L7NNAHrYd1aho1mVa6nmUI4JTXrP6+kC7ZWFIaDNh 1qqeyjhHd9naqyo7sTwU2YayDDQRCR+oSIQR3ZR+Qr4XMAdVfOx/4GJfq4jz+xzbR1t+ +PQomb8vC6O3GWfYTKjPnauv7LFKPRDBU+W1wTXuSijNMBFLXgA6kySqk0KO6Az92S/p iD4Q== MIME-Version: 1.0 X-Received: by 10.60.61.109 with SMTP id o13mr10835719oer.13.1412546716766; Sun, 05 Oct 2014 15:05:16 -0700 (PDT) Received: by 10.60.118.196 with HTTP; Sun, 5 Oct 2014 15:05:16 -0700 (PDT) Date: Sun, 5 Oct 2014 19:05:16 -0300 Message-ID: Subject: A few questions about SD/MMC drivers From: Martin Galvan To: freebsd-drivers@freebsd.org Content-Type: text/plain; charset=UTF-8 Cc: freebsd-embedded@freebsd.org X-BeenThere: freebsd-drivers@freebsd.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: Writing device drivers for FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 05 Oct 2014 22:05:18 -0000 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? 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." I'm not implying the existing code is wrong, I'm just curious about why are we using those particular values. 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? 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? Thanks a lot!