Commit c6ac3f35 authored by Matias Bjørling's avatar Matias Bjørling Committed by Jens Axboe
Browse files

lightnvm: flatten nvm_id_group into nvm_id



There are no groups in the 2.0 specification, make sure that the
nvm_id structure is flattened before 2.0 data structures are added.

Signed-off-by: default avatarMatias Bjørling <mb@lightnvm.io>
Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
parent a04e0cf9
Loading
Loading
Loading
Loading
+12 −13
Original line number Diff line number Diff line
@@ -851,33 +851,32 @@ EXPORT_SYMBOL(nvm_get_tgt_bb_tbl);
static int nvm_core_init(struct nvm_dev *dev)
{
	struct nvm_id *id = &dev->identity;
	struct nvm_id_group *grp = &id->grp;
	struct nvm_geo *geo = &dev->geo;
	int ret;

	memcpy(&geo->ppaf, &id->ppaf, sizeof(struct nvm_addr_format));

	if (grp->mtype != 0) {
	if (id->mtype != 0) {
		pr_err("nvm: memory type not supported\n");
		return -EINVAL;
	}

	/* Whole device values */
	geo->nr_chnls = grp->num_ch;
	geo->nr_luns = grp->num_lun;
	geo->nr_chnls = id->num_ch;
	geo->nr_luns = id->num_lun;

	/* Generic device geometry values */
	geo->ws_min = grp->ws_min;
	geo->ws_opt = grp->ws_opt;
	geo->ws_seq = grp->ws_seq;
	geo->ws_per_chk = grp->ws_per_chk;
	geo->nr_chks = grp->num_chk;
	geo->sec_size = grp->csecs;
	geo->oob_size = grp->sos;
	geo->mccap = grp->mccap;
	geo->ws_min = id->ws_min;
	geo->ws_opt = id->ws_opt;
	geo->ws_seq = id->ws_seq;
	geo->ws_per_chk = id->ws_per_chk;
	geo->nr_chks = id->num_chk;
	geo->sec_size = id->csecs;
	geo->oob_size = id->sos;
	geo->mccap = id->mccap;
	geo->max_rq_size = dev->ops->max_phys_sect * geo->sec_size;

	geo->sec_per_chk = grp->clba;
	geo->sec_per_chk = id->clba;
	geo->sec_per_lun = geo->sec_per_chk * geo->nr_chks;
	geo->all_luns = geo->nr_luns * geo->nr_chnls;

+51 −55
Original line number Diff line number Diff line
@@ -203,57 +203,55 @@ static inline void _nvme_nvm_check_size(void)
static int init_grp(struct nvm_id *nvm_id, struct nvme_nvm_id12 *id12)
{
	struct nvme_nvm_id12_grp *src;
	struct nvm_id_group *grp;
	int sec_per_pg, sec_per_pl, pg_per_blk;

	if (id12->cgrps != 1)
		return -EINVAL;

	src = &id12->grp;
	grp = &nvm_id->grp;

	grp->mtype = src->mtype;
	grp->fmtype = src->fmtype;
	nvm_id->mtype = src->mtype;
	nvm_id->fmtype = src->fmtype;

	grp->num_ch = src->num_ch;
	grp->num_lun = src->num_lun;
	nvm_id->num_ch = src->num_ch;
	nvm_id->num_lun = src->num_lun;

	grp->num_chk = le16_to_cpu(src->num_chk);
	grp->csecs = le16_to_cpu(src->csecs);
	grp->sos = le16_to_cpu(src->sos);
	nvm_id->num_chk = le16_to_cpu(src->num_chk);
	nvm_id->csecs = le16_to_cpu(src->csecs);
	nvm_id->sos = le16_to_cpu(src->sos);

	pg_per_blk = le16_to_cpu(src->num_pg);
	sec_per_pg = le16_to_cpu(src->fpg_sz) / grp->csecs;
	sec_per_pg = le16_to_cpu(src->fpg_sz) / nvm_id->csecs;
	sec_per_pl = sec_per_pg * src->num_pln;
	grp->clba = sec_per_pl * pg_per_blk;
	grp->ws_per_chk = pg_per_blk;
	nvm_id->clba = sec_per_pl * pg_per_blk;
	nvm_id->ws_per_chk = pg_per_blk;

	grp->mpos = le32_to_cpu(src->mpos);
	grp->cpar = le16_to_cpu(src->cpar);
	grp->mccap = le32_to_cpu(src->mccap);
	nvm_id->mpos = le32_to_cpu(src->mpos);
	nvm_id->cpar = le16_to_cpu(src->cpar);
	nvm_id->mccap = le32_to_cpu(src->mccap);

	grp->ws_opt = grp->ws_min = sec_per_pg;
	grp->ws_seq = NVM_IO_SNGL_ACCESS;
	nvm_id->ws_opt = nvm_id->ws_min = sec_per_pg;
	nvm_id->ws_seq = NVM_IO_SNGL_ACCESS;

	if (grp->mpos & 0x020202) {
		grp->ws_seq = NVM_IO_DUAL_ACCESS;
		grp->ws_opt <<= 1;
	} else if (grp->mpos & 0x040404) {
		grp->ws_seq = NVM_IO_QUAD_ACCESS;
		grp->ws_opt <<= 2;
	if (nvm_id->mpos & 0x020202) {
		nvm_id->ws_seq = NVM_IO_DUAL_ACCESS;
		nvm_id->ws_opt <<= 1;
	} else if (nvm_id->mpos & 0x040404) {
		nvm_id->ws_seq = NVM_IO_QUAD_ACCESS;
		nvm_id->ws_opt <<= 2;
	}

	grp->trdt = le32_to_cpu(src->trdt);
	grp->trdm = le32_to_cpu(src->trdm);
	grp->tprt = le32_to_cpu(src->tprt);
	grp->tprm = le32_to_cpu(src->tprm);
	grp->tbet = le32_to_cpu(src->tbet);
	grp->tbem = le32_to_cpu(src->tbem);
	nvm_id->trdt = le32_to_cpu(src->trdt);
	nvm_id->trdm = le32_to_cpu(src->trdm);
	nvm_id->tprt = le32_to_cpu(src->tprt);
	nvm_id->tprm = le32_to_cpu(src->tprm);
	nvm_id->tbet = le32_to_cpu(src->tbet);
	nvm_id->tbem = le32_to_cpu(src->tbem);

	/* 1.2 compatibility */
	grp->num_pln = src->num_pln;
	grp->num_pg = le16_to_cpu(src->num_pg);
	grp->fpg_sz = le16_to_cpu(src->fpg_sz);
	nvm_id->num_pln = src->num_pln;
	nvm_id->num_pg = le16_to_cpu(src->num_pg);
	nvm_id->fpg_sz = le16_to_cpu(src->fpg_sz);

	return 0;
}
@@ -740,14 +738,12 @@ static ssize_t nvm_dev_attr_show(struct device *dev,
	struct nvme_ns *ns = nvme_get_ns_from_dev(dev);
	struct nvm_dev *ndev = ns->ndev;
	struct nvm_id *id;
	struct nvm_id_group *grp;
	struct attribute *attr;

	if (!ndev)
		return 0;

	id = &ndev->identity;
	grp = &id->grp;
	attr = &dattr->attr;

	if (strcmp(attr->name, "version") == 0) {
@@ -771,41 +767,41 @@ static ssize_t nvm_dev_attr_show(struct device *dev,
			id->ppaf.pg_offset, id->ppaf.pg_len,
			id->ppaf.sect_offset, id->ppaf.sect_len);
	} else if (strcmp(attr->name, "media_type") == 0) {	/* u8 */
		return scnprintf(page, PAGE_SIZE, "%u\n", grp->mtype);
		return scnprintf(page, PAGE_SIZE, "%u\n", id->mtype);
	} else if (strcmp(attr->name, "flash_media_type") == 0) {
		return scnprintf(page, PAGE_SIZE, "%u\n", grp->fmtype);
		return scnprintf(page, PAGE_SIZE, "%u\n", id->fmtype);
	} else if (strcmp(attr->name, "num_channels") == 0) {
		return scnprintf(page, PAGE_SIZE, "%u\n", grp->num_ch);
		return scnprintf(page, PAGE_SIZE, "%u\n", id->num_ch);
	} else if (strcmp(attr->name, "num_luns") == 0) {
		return scnprintf(page, PAGE_SIZE, "%u\n", grp->num_lun);
		return scnprintf(page, PAGE_SIZE, "%u\n", id->num_lun);
	} else if (strcmp(attr->name, "num_planes") == 0) {
		return scnprintf(page, PAGE_SIZE, "%u\n", grp->num_pln);
		return scnprintf(page, PAGE_SIZE, "%u\n", id->num_pln);
	} else if (strcmp(attr->name, "num_blocks") == 0) {	/* u16 */
		return scnprintf(page, PAGE_SIZE, "%u\n", grp->num_chk);
		return scnprintf(page, PAGE_SIZE, "%u\n", id->num_chk);
	} else if (strcmp(attr->name, "num_pages") == 0) {
		return scnprintf(page, PAGE_SIZE, "%u\n", grp->num_pg);
		return scnprintf(page, PAGE_SIZE, "%u\n", id->num_pg);
	} else if (strcmp(attr->name, "page_size") == 0) {
		return scnprintf(page, PAGE_SIZE, "%u\n", grp->fpg_sz);
		return scnprintf(page, PAGE_SIZE, "%u\n", id->fpg_sz);
	} else if (strcmp(attr->name, "hw_sector_size") == 0) {
		return scnprintf(page, PAGE_SIZE, "%u\n", grp->csecs);
		return scnprintf(page, PAGE_SIZE, "%u\n", id->csecs);
	} else if (strcmp(attr->name, "oob_sector_size") == 0) {/* u32 */
		return scnprintf(page, PAGE_SIZE, "%u\n", grp->sos);
		return scnprintf(page, PAGE_SIZE, "%u\n", id->sos);
	} else if (strcmp(attr->name, "read_typ") == 0) {
		return scnprintf(page, PAGE_SIZE, "%u\n", grp->trdt);
		return scnprintf(page, PAGE_SIZE, "%u\n", id->trdt);
	} else if (strcmp(attr->name, "read_max") == 0) {
		return scnprintf(page, PAGE_SIZE, "%u\n", grp->trdm);
		return scnprintf(page, PAGE_SIZE, "%u\n", id->trdm);
	} else if (strcmp(attr->name, "prog_typ") == 0) {
		return scnprintf(page, PAGE_SIZE, "%u\n", grp->tprt);
		return scnprintf(page, PAGE_SIZE, "%u\n", id->tprt);
	} else if (strcmp(attr->name, "prog_max") == 0) {
		return scnprintf(page, PAGE_SIZE, "%u\n", grp->tprm);
		return scnprintf(page, PAGE_SIZE, "%u\n", id->tprm);
	} else if (strcmp(attr->name, "erase_typ") == 0) {
		return scnprintf(page, PAGE_SIZE, "%u\n", grp->tbet);
		return scnprintf(page, PAGE_SIZE, "%u\n", id->tbet);
	} else if (strcmp(attr->name, "erase_max") == 0) {
		return scnprintf(page, PAGE_SIZE, "%u\n", grp->tbem);
		return scnprintf(page, PAGE_SIZE, "%u\n", id->tbem);
	} else if (strcmp(attr->name, "multiplane_modes") == 0) {
		return scnprintf(page, PAGE_SIZE, "0x%08x\n", grp->mpos);
		return scnprintf(page, PAGE_SIZE, "0x%08x\n", id->mpos);
	} else if (strcmp(attr->name, "media_capabilities") == 0) {
		return scnprintf(page, PAGE_SIZE, "0x%08x\n", grp->mccap);
		return scnprintf(page, PAGE_SIZE, "0x%08x\n", id->mccap);
	} else if (strcmp(attr->name, "max_phys_secs") == 0) {
		return scnprintf(page, PAGE_SIZE, "%u\n",
				ndev->ops->max_phys_sect);
+26 −27
Original line number Diff line number Diff line
@@ -154,9 +154,29 @@ struct nvm_id_lp_tbl {
	struct nvm_id_lp_mlc mlc;
};

struct nvm_id_group {
	u8	mtype;
	u8	fmtype;
struct nvm_addr_format {
	u8	ch_offset;
	u8	ch_len;
	u8	lun_offset;
	u8	lun_len;
	u8	pln_offset;
	u8	pln_len;
	u8	blk_offset;
	u8	blk_len;
	u8	pg_offset;
	u8	pg_len;
	u8	sect_offset;
	u8	sect_len;
};

struct nvm_id {
	u8	ver_id;
	u8	vmnt;
	u32	cap;
	u32	dom;

	struct	nvm_addr_format ppaf;

	u8	num_ch;
	u8	num_lun;
	u16	num_chk;
@@ -180,33 +200,12 @@ struct nvm_id_group {
	u16	cpar;

	/* 1.2 compatibility */
	u8	mtype;
	u8	fmtype;

	u8	num_pln;
	u16	num_pg;
	u16	fpg_sz;
};

struct nvm_addr_format {
	u8	ch_offset;
	u8	ch_len;
	u8	lun_offset;
	u8	lun_len;
	u8	pln_offset;
	u8	pln_len;
	u8	blk_offset;
	u8	blk_len;
	u8	pg_offset;
	u8	pg_len;
	u8	sect_offset;
	u8	sect_len;
};

struct nvm_id {
	u8	ver_id;
	u8	vmnt;
	u32	cap;
	u32	dom;
	struct nvm_addr_format ppaf;
	struct nvm_id_group grp;
} __packed;

struct nvm_target {