+// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (C) 2016 Google, Inc
* Written by Simon Glass <sjg@chromium.org>
- *
- * SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <blk.h>
#include <dm.h>
+#include <log.h>
+#include <malloc.h>
+#include <part.h>
#include <dm/device-internal.h>
#include <dm/lists.h>
+#include <dm/uclass-internal.h>
+#include <linux/err.h>
static const char *if_typename_str[IF_TYPE_COUNT] = {
[IF_TYPE_IDE] = "ide",
[IF_TYPE_SD] = "sd",
[IF_TYPE_SATA] = "sata",
[IF_TYPE_HOST] = "host",
- [IF_TYPE_SYSTEMACE] = "ace",
+ [IF_TYPE_NVME] = "nvme",
+ [IF_TYPE_EFI] = "efi",
+ [IF_TYPE_VIRTIO] = "virtio",
};
static enum uclass_id if_type_uclass_id[IF_TYPE_COUNT] = {
- [IF_TYPE_IDE] = UCLASS_INVALID,
+ [IF_TYPE_IDE] = UCLASS_IDE,
[IF_TYPE_SCSI] = UCLASS_SCSI,
[IF_TYPE_ATAPI] = UCLASS_INVALID,
[IF_TYPE_USB] = UCLASS_MASS_STORAGE,
[IF_TYPE_SD] = UCLASS_INVALID,
[IF_TYPE_SATA] = UCLASS_AHCI,
[IF_TYPE_HOST] = UCLASS_ROOT,
- [IF_TYPE_SYSTEMACE] = UCLASS_INVALID,
+ [IF_TYPE_NVME] = UCLASS_NVME,
+ [IF_TYPE_EFI] = UCLASS_EFI,
+ [IF_TYPE_VIRTIO] = UCLASS_VIRTIO,
};
static enum if_type if_typename_to_iftype(const char *if_typename)
return if_type_uclass_id[if_type];
}
+const char *blk_get_if_type_name(enum if_type if_type)
+{
+ return if_typename_str[if_type];
+}
+
struct blk_desc *blk_get_devnum_by_type(enum if_type if_type, int devnum)
{
struct blk_desc *desc;
return NULL;
}
+/**
+ * blk_get_by_device() - Get the block device descriptor for the given device
+ * @dev: Instance of a storage device
+ *
+ * Return: With block device descriptor on success , NULL if there is no such
+ * block device.
+ */
+struct blk_desc *blk_get_by_device(struct udevice *dev)
+{
+ struct udevice *child_dev;
+
+ device_foreach_child(child_dev, dev) {
+ if (device_get_uclass_id(child_dev) != UCLASS_BLK)
+ continue;
+
+ return dev_get_uclass_platdata(child_dev);
+ }
+
+ debug("%s: No block device found\n", __func__);
+
+ return NULL;
+}
+
/**
* get_desc() - Get the block device descriptor for the given device number
*
if (IS_ERR_VALUE(n))
return n;
- /* flush cache after read */
- flush_cache((ulong)buffer, blkcnt * desc->blksz);
-
return n;
}
struct blk_desc *desc;
int ret;
- ret = uclass_first_device(UCLASS_BLK, devp);
+ ret = uclass_find_first_device(UCLASS_BLK, devp);
if (ret)
return ret;
if (!*devp)
desc = dev_get_uclass_platdata(*devp);
if (desc->if_type == if_type)
return 0;
- ret = uclass_next_device(devp);
+ ret = uclass_find_next_device(devp);
if (ret)
return ret;
} while (*devp);
desc = dev_get_uclass_platdata(*devp);
if_type = desc->if_type;
do {
- ret = uclass_next_device(devp);
+ ret = uclass_find_next_device(devp);
if (ret)
return ret;
if (!*devp)
return ops->erase(dev, start, blkcnt);
}
-int blk_prepare_device(struct udevice *dev)
-{
- struct blk_desc *desc = dev_get_uclass_platdata(dev);
-
- part_init(desc);
-
- return 0;
-}
-
int blk_get_from_parent(struct udevice *parent, struct udevice **devp)
{
struct udevice *dev;
return max_devnum;
}
-static int blk_next_free_devnum(enum if_type if_type)
+int blk_next_free_devnum(enum if_type if_type)
{
int ret;
int blk_create_device(struct udevice *parent, const char *drv_name,
const char *name, int if_type, int devnum, int blksz,
- lbaint_t size, struct udevice **devp)
+ lbaint_t lba, struct udevice **devp)
{
struct blk_desc *desc;
struct udevice *dev;
desc = dev_get_uclass_platdata(dev);
desc->if_type = if_type;
desc->blksz = blksz;
- desc->lba = size / blksz;
+ desc->log2blksz = LOG2(desc->blksz);
+ desc->lba = lba;
desc->part_type = PART_TYPE_UNKNOWN;
desc->bdev = dev;
desc->devnum = devnum;
int blk_create_devicef(struct udevice *parent, const char *drv_name,
const char *name, int if_type, int devnum, int blksz,
- lbaint_t size, struct udevice **devp)
+ lbaint_t lba, struct udevice **devp)
{
char dev_name[30], *str;
int ret;
return -ENOMEM;
ret = blk_create_device(parent, drv_name, str, if_type, devnum,
- blksz, size, devp);
+ blksz, lba, devp);
if (ret) {
free(str);
return ret;
}
device_set_name_alloced(*devp);
- return ret;
+ return 0;
}
int blk_unbind_all(int if_type)
return 0;
}
+static int blk_post_probe(struct udevice *dev)
+{
+#if defined(CONFIG_PARTITIONS) && defined(CONFIG_HAVE_BLOCK_DEVICE)
+ struct blk_desc *desc = dev_get_uclass_platdata(dev);
+
+ part_init(desc);
+#endif
+
+ return 0;
+}
+
UCLASS_DRIVER(blk) = {
.id = UCLASS_BLK,
.name = "blk",
+ .post_probe = blk_post_probe,
.per_device_platdata_auto_alloc_size = sizeof(struct blk_desc),
};