mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-30 19:51:31 -04:00
lightnvm: expose device geometry through sysfs
For a host to access an Open-Channel SSD, it has to know its geometry, so that it writes and reads at the appropriate device bounds. Currently, the geometry information is kept within the kernel, and not exported to user-space for consumption. This patch exposes the configuration through sysfs and enables user-space libraries, such as liblightnvm, to use the sysfs implementation to get the geometry of an Open-Channel SSD. The sysfs entries are stored within the device hierarchy, and can be found using the "lightnvm" device type. An example configuration looks like this: /sys/class/nvme/ └── nvme0n1 ├── capabilities: 3 ├── device_mode: 1 ├── erase_max: 1000000 ├── erase_typ: 1000000 ├── flash_media_type: 0 ├── media_capabilities: 0x00000001 ├── media_type: 0 ├── multiplane: 0x00010101 ├── num_blocks: 1022 ├── num_channels: 1 ├── num_luns: 4 ├── num_pages: 64 ├── num_planes: 1 ├── page_size: 4096 ├── prog_max: 100000 ├── prog_typ: 100000 ├── read_max: 10000 ├── read_typ: 10000 ├── sector_oob_size: 0 ├── sector_size: 4096 ├── media_manager: gennvm ├── ppa_format: 0x380830082808001010102008 ├── vendor_opcode: 0 ├── max_phys_secs: 64 └── version: 1 Signed-off-by: Simon A. F. Lund <[email protected]> Signed-off-by: Matias Bjørling <[email protected]> Signed-off-by: Jens Axboe <[email protected]>
This commit is contained in:
parent
b0b4e09c1a
commit
40267efddc
8 changed files with 278 additions and 17 deletions
|
|
@ -1435,7 +1435,7 @@ static DEVICE_ATTR(rescan_controller, S_IWUSR, NULL, nvme_sysfs_rescan);
|
|||
static ssize_t wwid_show(struct device *dev, struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct nvme_ns *ns = dev_to_disk(dev)->private_data;
|
||||
struct nvme_ns *ns = nvme_get_ns_from_dev(dev);
|
||||
struct nvme_ctrl *ctrl = ns->ctrl;
|
||||
int serial_len = sizeof(ctrl->serial);
|
||||
int model_len = sizeof(ctrl->model);
|
||||
|
|
@ -1459,7 +1459,7 @@ static DEVICE_ATTR(wwid, S_IRUGO, wwid_show, NULL);
|
|||
static ssize_t uuid_show(struct device *dev, struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct nvme_ns *ns = dev_to_disk(dev)->private_data;
|
||||
struct nvme_ns *ns = nvme_get_ns_from_dev(dev);
|
||||
return sprintf(buf, "%pU\n", ns->uuid);
|
||||
}
|
||||
static DEVICE_ATTR(uuid, S_IRUGO, uuid_show, NULL);
|
||||
|
|
@ -1467,7 +1467,7 @@ static DEVICE_ATTR(uuid, S_IRUGO, uuid_show, NULL);
|
|||
static ssize_t eui_show(struct device *dev, struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct nvme_ns *ns = dev_to_disk(dev)->private_data;
|
||||
struct nvme_ns *ns = nvme_get_ns_from_dev(dev);
|
||||
return sprintf(buf, "%8phd\n", ns->eui);
|
||||
}
|
||||
static DEVICE_ATTR(eui, S_IRUGO, eui_show, NULL);
|
||||
|
|
@ -1475,7 +1475,7 @@ static DEVICE_ATTR(eui, S_IRUGO, eui_show, NULL);
|
|||
static ssize_t nsid_show(struct device *dev, struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct nvme_ns *ns = dev_to_disk(dev)->private_data;
|
||||
struct nvme_ns *ns = nvme_get_ns_from_dev(dev);
|
||||
return sprintf(buf, "%d\n", ns->ns_id);
|
||||
}
|
||||
static DEVICE_ATTR(nsid, S_IRUGO, nsid_show, NULL);
|
||||
|
|
@ -1492,7 +1492,7 @@ static umode_t nvme_ns_attrs_are_visible(struct kobject *kobj,
|
|||
struct attribute *a, int n)
|
||||
{
|
||||
struct device *dev = container_of(kobj, struct device, kobj);
|
||||
struct nvme_ns *ns = dev_to_disk(dev)->private_data;
|
||||
struct nvme_ns *ns = nvme_get_ns_from_dev(dev);
|
||||
|
||||
if (a == &dev_attr_uuid.attr) {
|
||||
if (!memchr_inv(ns->uuid, 0, sizeof(ns->uuid)))
|
||||
|
|
@ -1684,7 +1684,8 @@ static void nvme_alloc_ns(struct nvme_ctrl *ctrl, unsigned nsid)
|
|||
goto out_free_queue;
|
||||
|
||||
if (nvme_nvm_ns_supported(ns, id)) {
|
||||
if (nvme_nvm_register(ns, disk_name, node)) {
|
||||
if (nvme_nvm_register(ns, disk_name, node,
|
||||
&nvme_ns_attr_group)) {
|
||||
dev_warn(ctrl->dev, "%s: LightNVM init failure\n",
|
||||
__func__);
|
||||
goto out_free_id;
|
||||
|
|
|
|||
|
|
@ -592,7 +592,8 @@ static struct nvm_dev_ops nvme_nvm_dev_ops = {
|
|||
.max_phys_sect = 64,
|
||||
};
|
||||
|
||||
int nvme_nvm_register(struct nvme_ns *ns, char *disk_name, int node)
|
||||
int nvme_nvm_register(struct nvme_ns *ns, char *disk_name, int node,
|
||||
const struct attribute_group *attrs)
|
||||
{
|
||||
struct request_queue *q = ns->queue;
|
||||
struct nvm_dev *dev;
|
||||
|
|
@ -605,19 +606,23 @@ int nvme_nvm_register(struct nvme_ns *ns, char *disk_name, int node)
|
|||
dev->q = q;
|
||||
memcpy(dev->name, disk_name, DISK_NAME_LEN);
|
||||
dev->ops = &nvme_nvm_dev_ops;
|
||||
dev->parent_dev = ns->ctrl->device;
|
||||
dev->private_data = ns;
|
||||
ns->ndev = dev;
|
||||
|
||||
ret = nvm_register(dev);
|
||||
|
||||
ns->lba_shift = ilog2(dev->sec_size) - 9;
|
||||
|
||||
if (sysfs_create_group(&dev->dev.kobj, attrs))
|
||||
pr_warn("%s: failed to create sysfs group for identification\n",
|
||||
disk_name);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void nvme_nvm_unregister(struct nvme_ns *ns)
|
||||
{
|
||||
nvm_unregister(ns->ndev);
|
||||
kfree(ns->ndev);
|
||||
}
|
||||
|
||||
/* move to shared place when used in multiple places. */
|
||||
|
|
|
|||
|
|
@ -308,11 +308,21 @@ int nvme_sg_get_version_num(int __user *ip);
|
|||
|
||||
#ifdef CONFIG_NVM
|
||||
int nvme_nvm_ns_supported(struct nvme_ns *ns, struct nvme_id_ns *id);
|
||||
int nvme_nvm_register(struct nvme_ns *ns, char *disk_name, int node);
|
||||
int nvme_nvm_register(struct nvme_ns *ns, char *disk_name, int node,
|
||||
const struct attribute_group *attrs);
|
||||
void nvme_nvm_unregister(struct nvme_ns *ns);
|
||||
|
||||
static inline struct nvme_ns *nvme_get_ns_from_dev(struct device *dev)
|
||||
{
|
||||
if (dev->type->devnode)
|
||||
return dev_to_disk(dev)->private_data;
|
||||
|
||||
return (container_of(dev, struct nvm_dev, dev))->private_data;
|
||||
}
|
||||
#else
|
||||
static inline int nvme_nvm_register(struct nvme_ns *ns, char *disk_name,
|
||||
int node)
|
||||
int node,
|
||||
const struct attribute_group *attrs)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -323,6 +333,10 @@ static inline int nvme_nvm_ns_supported(struct nvme_ns *ns, struct nvme_id_ns *i
|
|||
{
|
||||
return 0;
|
||||
}
|
||||
static inline struct nvme_ns *nvme_get_ns_from_dev(struct device *dev)
|
||||
{
|
||||
return dev_to_disk(dev)->private_data;
|
||||
}
|
||||
#endif /* CONFIG_NVM */
|
||||
|
||||
int __init nvme_core_init(void);
|
||||
|
|
|
|||
Loading…
Reference in a new issue