]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/commitdiff
mmc: core: Export device/vendor ids from Common CIS for SDIO cards
authorPali Rohár <pali@kernel.org>
Wed, 27 May 2020 11:08:58 +0000 (13:08 +0200)
committerUlf Hansson <ulf.hansson@linaro.org>
Fri, 29 May 2020 10:38:00 +0000 (12:38 +0200)
Device/vendor ids from Common CIS (Card Information Structure) may be
different as device/vendor ids from CIS on particular SDIO function.

Kernel currently exports only device/vendor ids from SDIO functions and not
"main" device/vendor ids from Common CIS.

This patch exports "main" device/vendor ids for SDIO and SD combo cards at
top level mmc device in sysfs hierarchy.

Userspace can use e.g. udev rules to correctly match whole SDIO card based
on Common CIS device/vendor id and not only one particular SDIO function.
Having this information in userspace also helps developers to debug whole
SDIO card as e.g. kernel mmc quirks use device/vendor ids from Common CIS
and not from particular SDIO function. Also it allows to write userspace
applications which list all connected SDIO cards based on CIS ids.

Signed-off-by: Pali Rohár <pali@kernel.org>
Reviewed-by: Marek Behún <marek.behun@nic.cz>
Link: https://lore.kernel.org/r/20200527110858.17504-2-pali@kernel.org
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
drivers/mmc/core/bus.c
drivers/mmc/core/sd.c
drivers/mmc/core/sdio.c

index b1cb447da7649c66e6f978aa0f777b54ed9ecbc0..70207f11a6548e2c6c1e0ba5d38eb7b2b3aae891 100644 (file)
@@ -93,6 +93,13 @@ mmc_bus_uevent(struct device *dev, struct kobj_uevent_env *env)
                        return retval;
        }
 
+       if (card->type == MMC_TYPE_SDIO || card->type == MMC_TYPE_SD_COMBO) {
+               retval = add_uevent_var(env, "SDIO_ID=%04X:%04X",
+                                       card->cis.vendor, card->cis.device);
+               if (retval)
+                       return retval;
+       }
+
        /*
         * SDIO (non-combo) cards are not handled by mmc_block driver and do not
         * have accessible CID register which used by mmc_card_name() function.
index 43de3190d71898d8187b5489ab5c04ce49c4231a..5a2210c25aa7a65082c1471ab0094db46b8daa0a 100644 (file)
@@ -707,7 +707,12 @@ static ssize_t mmc_dsr_show(struct device *dev,
 
 static DEVICE_ATTR(dsr, S_IRUGO, mmc_dsr_show, NULL);
 
+MMC_DEV_ATTR(vendor, "0x%04x\n", card->cis.vendor);
+MMC_DEV_ATTR(device, "0x%04x\n", card->cis.device);
+
 static struct attribute *sd_std_attrs[] = {
+       &dev_attr_vendor.attr,
+       &dev_attr_device.attr,
        &dev_attr_cid.attr,
        &dev_attr_csd.attr,
        &dev_attr_scr.attr,
@@ -726,7 +731,26 @@ static struct attribute *sd_std_attrs[] = {
        &dev_attr_dsr.attr,
        NULL,
 };
-ATTRIBUTE_GROUPS(sd_std);
+
+static umode_t sd_std_is_visible(struct kobject *kobj, struct attribute *attr,
+                                int index)
+{
+       struct device *dev = container_of(kobj, struct device, kobj);
+       struct mmc_card *card = mmc_dev_to_card(dev);
+
+       /* CIS vendor and device ids are available only for Combo cards */
+       if ((attr == &dev_attr_vendor.attr || attr == &dev_attr_device.attr) &&
+           card->type != MMC_TYPE_SD_COMBO)
+               return 0;
+
+       return attr->mode;
+}
+
+static const struct attribute_group sd_std_group = {
+       .attrs = sd_std_attrs,
+       .is_visible = sd_std_is_visible,
+};
+__ATTRIBUTE_GROUPS(sd_std);
 
 struct device_type sd_type = {
        .groups = sd_std_groups,
index 435de47a6ee0f9b50ed835b938daea502eb891be..b65b26f76d719e9f31134f2d5802ed9917f80044 100644 (file)
 #include "sdio_ops.h"
 #include "sdio_cis.h"
 
+MMC_DEV_ATTR(vendor, "0x%04x\n", card->cis.vendor);
+MMC_DEV_ATTR(device, "0x%04x\n", card->cis.device);
+MMC_DEV_ATTR(ocr, "0x%08x\n", card->ocr);
+MMC_DEV_ATTR(rca, "0x%04x\n", card->rca);
+
+static struct attribute *sdio_std_attrs[] = {
+       &dev_attr_vendor.attr,
+       &dev_attr_device.attr,
+       &dev_attr_ocr.attr,
+       &dev_attr_rca.attr,
+       NULL,
+};
+ATTRIBUTE_GROUPS(sdio_std);
+
+static struct device_type sdio_type = {
+       .groups = sdio_std_groups,
+};
+
 static int sdio_read_fbr(struct sdio_func *func)
 {
        int ret;
@@ -618,7 +636,7 @@ try_again:
        /*
         * Allocate card structure.
         */
-       card = mmc_alloc_card(host, NULL);
+       card = mmc_alloc_card(host, &sdio_type);
        if (IS_ERR(card))
                return PTR_ERR(card);