Skip to contentSkip to conversation

fixed order for mmc devices/mmc block devices

RFC In review [email protected] 3 participants 8 messages Apr 1, 2014 – Mar 13, 2015

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

cover fixed order for mmc devices/mmc block devices

From: Stefan Agner <[email protected]>

Nowadays SoCs usually have multiple SD/MMC host adapters. Often the first is connected to an internal eMMC, however sometimes it is the second controller that is connected to the eMMC.

If the second controller is connected to the eMMC, the number assigned to the eMMC block device varies depending on whether the external SD-Card is present or not.
The boot device could be specified using partition UUIDs, but those can change when recreating the partition table. Especially for embedded devices it would be preferable to have a reliable assigned block device number.

The first patch aims to give a way to specify the logical SD/MMC host order. This is achieved by extending the device tree using aliases:

aliases {
        mmc0 = "/sdhci@78000600";
        mmc1 = "/sdhci@78000200";
};

The second patch then uses the SD/MMC host index as preferred id for the block device.

In theory, one SD/MMC host could control multiple cards. For this case, this patch is somewhat ugly. It would only assign the first host/card combination with a predictable block number. However, for the case at hand this would be sufficient.

Stefan Agner (2):
mmc: read mmc alias from device tree
mmc: use SD/MMC host ID for block device name ID

 drivers/mmc/card/block.c |  3 ++-
 drivers/mmc/core/host.c  | 24 +++++++++++++++++++-----
 2 files changed, 21 insertions(+), 6 deletions(-)
Signature · 1 line
1.9.1
#1 lore raw

RFC 1/2 mmc: read mmc alias from device tree

From: Stefan Agner <[email protected]>

To get the SD/MMC host device ID, read the alias from the device tree.

This is useful in case a SoC has multipe SD/MMC host controllers while the second controller should logically be the first device (e.g. if the second controller is connected to an internal eMMC). Combined with block device numbering using MMC/SD host device ID, this results in predictable name assignment of the internal eMMC block device.

---
 drivers/mmc/core/host.c | 24 +++++++++++++++++++-----
 1 file changed, 19 insertions(+), 5 deletions(-)
drivers/mmc/core/host.c +19 -5
index 49bc403..29f44cf 100644
@@ -448,8 +448,8 @@ EXPORT_SYMBOL(mmc_of_parse);
  */
 struct mmc_host *mmc_alloc_host(int extra, struct device *dev)
 {
-	int err;
 	struct mmc_host *host;
+	int of_id = -1, id = -1;
 
 	host = kzalloc(sizeof(struct mmc_host) + extra, GFP_KERNEL);
 	if (!host)
@@ -459,12 +459,26 @@ struct mmc_host *mmc_alloc_host(int extra, struct device *dev)
 	host->rescan_disable = 1;
 	idr_preload(GFP_KERNEL);
 	spin_lock(&mmc_host_lock);
-	err = idr_alloc(&mmc_host_idr, host, 0, 0, GFP_NOWAIT);
-	if (err >= 0)
-		host->index = err;
+
+	if (dev->of_node)
+		of_id = of_alias_get_id(dev->of_node, "mmc");
+
+	if (of_id >= 0) {
+		id = idr_alloc(&mmc_host_idr, host, of_id, of_id + 1,
+				GFP_NOWAIT);
+		if (id < 0)
+			dev_warn(dev, "/aliases ID %d not available\n", of_id);
+	}
+
+	if (id < 0)
+		id = idr_alloc(&mmc_host_idr, host, 0, 0, GFP_NOWAIT);
+
+	if (id >= 0)
+		host->index = id;
+
 	spin_unlock(&mmc_host_lock);
 	idr_preload_end();
-	if (err < 0)
+	if (id < 0)
 		goto free;
 
 	dev_set_name(&host->class_dev, "mmc%d", host->index);
Signature · 1 line
1.9.1
Reviewed-by Tested-by on v1 1/2
#2 lore raw

Re: [RFC 1/2] mmc: read mmc alias from device tree

Stefan,

Quoted 5 lines · On Tue, Apr 1, 2014 at 1:35 PM, <[email protected]> wrote:

From: Stefan Agner <[email protected]>

To get the SD/MMC host device ID, read the alias from the device tree.

Quoted 8 lines

This is useful in case a SoC has multipe SD/MMC host controllers while the second controller should logically be the first device (e.g. if the second controller is connected to an internal eMMC). Combined with block device numbering using MMC/SD host device ID, this results in predictable name assignment of the internal eMMC block device.

Yes, please. It is very handy to have mmc devices be enumerated in a predictable way.

#3 lore raw

Re: [RFC 1/2] mmc: read mmc alias from device tree

In reply to [email protected]

Hi,

Quoted 32 lines · On Tue, Apr 1, 2014 at 1:35 PM, <[email protected]> wrote:

From: Stefan Agner <[email protected]>

To get the SD/MMC host device ID, read the alias from the device tree.

This is useful in case a SoC has multipe SD/MMC host controllers while the second controller should logically be the first device (e.g. if the second controller is connected to an internal eMMC). Combined with block device numbering using MMC/SD host device ID, this results in predictable name assignment of the internal eMMC block device.

---
 drivers/mmc/core/host.c | 24 +++++++++++++++++++-----
 1 file changed, 19 insertions(+), 5 deletions(-)
drivers/mmc/core/host.c +1 -1
index 49bc403..29f44cf 100644
@@ -448,8 +448,8 @@ EXPORT_SYMBOL(mmc_of_parse);
  */
 struct mmc_host *mmc_alloc_host(int extra, struct device *dev)
 {
-       int err;
        struct mmc_host *host;
+       int of_id = -1, id = -1;
 
        host = kzalloc(sizeof(struct mmc_host) + extra, GFP_KERNEL);
        if (!host)

drivers/mmc/core/host.c struct mmc_host *mmc_alloc_host(int extra, struct device *dev) · line 464

Quoted 9 lines
drivers/mmc/core/host.c +3 -3
@@ -459,12 +459,26 @@ struct mmc_host *mmc_alloc_host(int extra, struct device *dev)
        host->rescan_disable = 1;
        idr_preload(GFP_KERNEL);
        spin_lock(&mmc_host_lock);
-       err = idr_alloc(&mmc_host_idr, host, 0, 0, GFP_NOWAIT);
-       if (err >= 0)
-               host->index = err;
+
+       if (dev->of_node)
+               of_id = of_alias_get_id(dev->of_node, "mmc");

Not that there's much chance of such an old patch landing, but just in case anyone finds this Dmitry points out that this causes a "scheduling while atomic". A fix is to move the "of_alias_get_id" up above the spin_lock():

https://chromium-review.googlesource.com/#/c/259916/

-Doug

#4 lore raw

RFC 2/2 mmc: use SD/MMC host ID for block device name ID

In reply to [email protected]

From: Stefan Agner <[email protected]>

By using the SD/MMC host device ID as a starting point for block device numbering, one can reliably predict the first block device name (at least for the first controller). This is especially useful for SoCs with multiple SD/MMC host controller, where the controller with index 0 is connected to a eMMC device.

Usually the first controller gets the first block device name ID, however this is not guaranteed. Also if the first controller is aliased as second controller and visa-versa (using device tree aliases), the block device name ID assignation is not ordered by the SD/MMC host device ID (since mmc_rescan is called in order of the memory mapped pheripherial addresses).

---
 drivers/mmc/card/block.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/mmc/card/block.c +2 -1
index 7b5424f..03626ed 100644
@@ -2045,7 +2045,8 @@ static struct mmc_blk_data *mmc_blk_alloc_req(struct mmc_card *card,
 	 * index anymore so we keep track of a name index.
 	 */
 	if (!subname) {
-		md->name_idx = find_first_zero_bit(name_use, max_devices);
+		md->name_idx = find_next_zero_bit(name_use, max_devices,
+				card->host->index);
 		__set_bit(md->name_idx, name_use);
 	} else
 		md->name_idx = ((struct mmc_blk_data *)
Signature · 1 line
1.9.1
#5 lore raw

Re: [RFC 2/2] mmc: use SD/MMC host ID for block device name ID

Quoted 5 lines · On 04/01/2014 02:35 PM, [email protected] wrote:

From: Stefan Agner <[email protected]>

By using the SD/MMC host device ID as a starting point for block device numbering, one can reliably predict the first block device name (at least for the first controller).

That's not true. There's no guarantee that a device name/ID gets released as soon as the SD card is removed; something might still have it mounted for example.

The correct solution here is to use filesystem or partition UUIDs to identify the device/partition, not to attempt to assign static device IDs.

#6 lore raw

Re: [RFC 2/2] mmc: use SD/MMC host ID for block device name ID

Quoted 3 lines · Stephen Warren

That's not true. There's no guarantee that a device name/ID gets released as soon as the SD card is removed; something might still have it mounted for example.

Yes. Also when booted there are other solutions to get static block device name (e.g. /dev/disk/by-path), but the problem at hand aims for a solution for the root file system.

Also, eMMC don't get removed, and those internal eMMC devices are the reason of this thread... (see cover letter)

Quoted 2 lines

The correct solution here is to use filesystem or partition UUIDs to identify the device/partition, not to attempt to assign static device IDs.

Yes, I'm aware of that solution. However, when recreating the partition table, those UUIDs do change, which in turn needs a change of the kernel arguments. Of course, one can use scripts to work around this, but its easier to just boot from the block device at a given location (say eMMC, first partition). Then, using UUID is also not as fast as using a device name directly, since all block devices get scanned. This is not optimal when trying to optimize boot speed, but might be negligible. I actually never measured that.

There are the /dev/disk/by-path/ which aim at a similar goal, but those names are generated by udev. I'm open to suggestions solve this issue in a more fashionable way...

Reviewed-by Tested-by on v1 2/2
#7 lore raw

Re: [RFC 2/2] mmc: use SD/MMC host ID for block device name ID

In reply to [email protected]

Stefan,

Quoted 15 lines · On Tue, Apr 1, 2014 at 1:35 PM, <[email protected]> wrote:

From: Stefan Agner <[email protected]>

By using the SD/MMC host device ID as a starting point for block device numbering, one can reliably predict the first block device name (at least for the first controller). This is especially useful for SoCs with multiple SD/MMC host controller, where the controller with index 0 is connected to a eMMC device.

Usually the first controller gets the first block device name ID, however this is not guaranteed. Also if the first controller is aliased as second controller and visa-versa (using device tree aliases), the block device name ID assignation is not ordered by the SD/MMC host device ID (since mmc_rescan is called in order of the memory mapped pheripherial addresses).

Quoted 4 lines
---
 drivers/mmc/card/block.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

As Stephen points out, "mmcblk" IDs for SD cards are not actually guaranteed. Also UUID is a better API for things to use.

That being said, your patch helps me a lot when doing development. As you said, I'm guaranteed that if eMMC is no-removable and enumerated at boot that it will be a predictable ID and I can use it in my scripts. Also this helps keep me from having to do lots of extra thinking to figure out whether I happened to have an SD card plugged in at boot or I didn't.

I'd love to see this land.