diff mbox

[13/20] lightnvm: add support for 2.0 address format

Message ID 1519205218-26994-14-git-send-email-javier@cnexlabs.com (mailing list archive)
State New, archived
Headers show

Commit Message

=?UTF-8?q?Javier=20Gonz=C3=A1lez?= Feb. 21, 2018, 9:26 a.m. UTC
Add support for 2.0 address format. Also, align address bits for 1.2 and
2.0 to be able to operate on channel and luns without requiring a format
conversion. Use a generic address format for this purpose.

Signed-off-by: Javier González <javier@cnexlabs.com>
---
 drivers/lightnvm/core.c  |  20 ++++-----
 include/linux/lightnvm.h | 105 ++++++++++++++++++++++++++++++++++-------------
 2 files changed, 86 insertions(+), 39 deletions(-)

Comments

Matias Bjorling Feb. 22, 2018, 9:24 a.m. UTC | #1
On 02/21/2018 10:26 AM, Javier González wrote:
> Add support for 2.0 address format. Also, align address bits for 1.2 and
> 2.0 to be able to operate on channel and luns without requiring a format
> conversion. Use a generic address format for this purpose.
> 
> Signed-off-by: Javier González <javier@cnexlabs.com>
> ---
>   drivers/lightnvm/core.c  |  20 ++++-----
>   include/linux/lightnvm.h | 105 ++++++++++++++++++++++++++++++++++-------------
>   2 files changed, 86 insertions(+), 39 deletions(-)
> 
> diff --git a/drivers/lightnvm/core.c b/drivers/lightnvm/core.c
> index f70a907223e2..baec963b2c96 100644
> --- a/drivers/lightnvm/core.c
> +++ b/drivers/lightnvm/core.c
> @@ -196,8 +196,8 @@ static struct nvm_tgt_dev *nvm_create_tgt_dev(struct nvm_dev *dev,
>   
>   		for (j = 0; j < luns_in_chnl; j++) {
>   			luns[lunid].ppa = 0;
> -			luns[lunid].g.ch = i;
> -			luns[lunid++].g.lun = j;
> +			luns[lunid].a.ch = i;
> +			luns[lunid++].a.lun = j;
>   
>   			lun_offs[j] = blun;
>   			lun_roffs[j + blun] = blun;
> @@ -563,22 +563,22 @@ static void nvm_unregister_map(struct nvm_dev *dev)
>   static void nvm_map_to_dev(struct nvm_tgt_dev *tgt_dev, struct ppa_addr *p)
>   {
>   	struct nvm_dev_map *dev_map = tgt_dev->map;
> -	struct nvm_ch_map *ch_map = &dev_map->chnls[p->g.ch];
> -	int lun_off = ch_map->lun_offs[p->g.lun];
> +	struct nvm_ch_map *ch_map = &dev_map->chnls[p->a.ch];
> +	int lun_off = ch_map->lun_offs[p->a.lun];
>   
> -	p->g.ch += ch_map->ch_off;
> -	p->g.lun += lun_off;
> +	p->a.ch += ch_map->ch_off;
> +	p->a.lun += lun_off;
>   }
>   
>   static void nvm_map_to_tgt(struct nvm_tgt_dev *tgt_dev, struct ppa_addr *p)
>   {
>   	struct nvm_dev *dev = tgt_dev->parent;
>   	struct nvm_dev_map *dev_rmap = dev->rmap;
> -	struct nvm_ch_map *ch_rmap = &dev_rmap->chnls[p->g.ch];
> -	int lun_roff = ch_rmap->lun_offs[p->g.lun];
> +	struct nvm_ch_map *ch_rmap = &dev_rmap->chnls[p->a.ch];
> +	int lun_roff = ch_rmap->lun_offs[p->a.lun];
>   
> -	p->g.ch -= ch_rmap->ch_off;
> -	p->g.lun -= lun_roff;
> +	p->a.ch -= ch_rmap->ch_off;
> +	p->a.lun -= lun_roff;
>   }
>   
>   static void nvm_ppa_tgt_to_dev(struct nvm_tgt_dev *tgt_dev,
> diff --git a/include/linux/lightnvm.h b/include/linux/lightnvm.h
> index e1c4292ea33d..cd310bf06051 100644
> --- a/include/linux/lightnvm.h
> +++ b/include/linux/lightnvm.h
> @@ -16,12 +16,22 @@ enum {
>   	NVM_IOTYPE_GC = 1,
>   };
>   
> -#define NVM_BLK_BITS (16)
> -#define NVM_PG_BITS  (16)
> -#define NVM_SEC_BITS (8)
> -#define NVM_PL_BITS  (8)
> -#define NVM_LUN_BITS (8)
> -#define NVM_CH_BITS  (7)
> +/* common format */
> +#define NVM_GEN_CH_BITS  (8)
> +#define NVM_GEN_LUN_BITS (8)
> +#define NVM_GEN_RESERVED (48)
> +
> +/* 1.2 format */
> +#define NVM_12_BLK_BITS (16)
> +#define NVM_12_PG_BITS  (16)
> +#define NVM_12_PL_BITS  (4)
> +#define NVM_12_SEC_BITS (4)
> +#define NVM_12_RESERVED (8)
> +
> +/* 2.0 format */
> +#define NVM_20_CHK_BITS (16)
> +#define NVM_20_SEC_BITS (24)
> +#define NVM_20_RESERVED (8)
>   
>   enum {
>   	NVM_OCSSD_SPEC_12 = 12,
> @@ -31,16 +41,33 @@ enum {
>   struct ppa_addr {
>   	/* Generic structure for all addresses */
>   	union {
> +		/* generic device format */
>   		struct {
> -			u64 blk		: NVM_BLK_BITS;
> -			u64 pg		: NVM_PG_BITS;
> -			u64 sec		: NVM_SEC_BITS;
> -			u64 pl		: NVM_PL_BITS;
> -			u64 lun		: NVM_LUN_BITS;
> -			u64 ch		: NVM_CH_BITS;
> -			u64 reserved	: 1;
> +			u64 ch		: NVM_GEN_CH_BITS;
> +			u64 lun		: NVM_GEN_LUN_BITS;
> +			u64 reserved	: NVM_GEN_RESERVED;
> +		} a;
> +
> +		/* 1.2 device format */
> +		struct {
> +			u64 ch		: NVM_GEN_CH_BITS;
> +			u64 lun		: NVM_GEN_LUN_BITS;
> +			u64 blk		: NVM_12_BLK_BITS;
> +			u64 pg		: NVM_12_PG_BITS;
> +			u64 pl		: NVM_12_PL_BITS;
> +			u64 sec		: NVM_12_SEC_BITS;
> +			u64 reserved	: NVM_12_RESERVED;
>   		} g;
>   
> +		/* 2.0 device format */
> +		struct {
> +			u64 ch		: NVM_GEN_CH_BITS;
> +			u64 lun		: NVM_GEN_LUN_BITS;
> +			u64 chk		: NVM_20_CHK_BITS;
> +			u64 sec		: NVM_20_SEC_BITS;
> +			u64 reserved	: NVM_20_RESERVED;
> +		} m;
> +
>   		struct {
>   			u64 line	: 63;
>   			u64 is_cached	: 1;
> @@ -392,16 +419,26 @@ static inline struct ppa_addr generic_to_dev_addr(struct nvm_tgt_dev *tgt_dev,
>   						  struct ppa_addr r)
>   {
>   	struct nvm_geo *geo = &tgt_dev->geo;
> -	struct nvm_addr_format_12 *ppaf =
> -				(struct nvm_addr_format_12 *)&geo->c.addrf;
>   	struct ppa_addr l;
>   
> -	l.ppa = ((u64)r.g.ch) << ppaf->ch_offset;
> -	l.ppa |= ((u64)r.g.lun) << ppaf->lun_offset;
> -	l.ppa |= ((u64)r.g.blk) << ppaf->blk_offset;
> -	l.ppa |= ((u64)r.g.pg) << ppaf->pg_offset;
> -	l.ppa |= ((u64)r.g.pl) << ppaf->pln_offset;
> -	l.ppa |= ((u64)r.g.sec) << ppaf->sec_offset;
> +	if (geo->c.version == NVM_OCSSD_SPEC_12) {
> +		struct nvm_addr_format_12 *ppaf =
> +				(struct nvm_addr_format_12 *)&geo->c.addrf;
> +
> +		l.ppa = ((u64)r.g.ch) << ppaf->ch_offset;
> +		l.ppa |= ((u64)r.g.lun) << ppaf->lun_offset;
> +		l.ppa |= ((u64)r.g.blk) << ppaf->blk_offset;
> +		l.ppa |= ((u64)r.g.pg) << ppaf->pg_offset;
> +		l.ppa |= ((u64)r.g.pl) << ppaf->pln_offset;
> +		l.ppa |= ((u64)r.g.sec) << ppaf->sec_offset;
> +	} else {
> +		struct nvm_addr_format *lbaf = &geo->c.addrf;
> +
> +		l.ppa = ((u64)r.m.ch) << lbaf->ch_offset;
> +		l.ppa |= ((u64)r.m.lun) << lbaf->lun_offset;
> +		l.ppa |= ((u64)r.m.chk) << lbaf->chk_offset;
> +		l.ppa |= ((u64)r.m.sec) << lbaf->sec_offset;
> +	}
>   
>   	return l;
>   }
> @@ -410,18 +447,28 @@ static inline struct ppa_addr dev_to_generic_addr(struct nvm_tgt_dev *tgt_dev,
>   						  struct ppa_addr r)
>   {
>   	struct nvm_geo *geo = &tgt_dev->geo;
> -	struct nvm_addr_format_12 *ppaf =
> -				(struct nvm_addr_format_12 *)&geo->c.addrf;
>   	struct ppa_addr l;
>   
>   	l.ppa = 0;
>   
> -	l.g.ch = (r.ppa & ppaf->ch_mask) >> ppaf->ch_offset;
> -	l.g.lun = (r.ppa & ppaf->lun_mask) >> ppaf->lun_offset;
> -	l.g.blk = (r.ppa & ppaf->blk_mask) >> ppaf->blk_offset;
> -	l.g.pg = (r.ppa & ppaf->pg_mask) >> ppaf->pg_offset;
> -	l.g.pl = (r.ppa & ppaf->pln_mask) >> ppaf->pln_offset;
> -	l.g.sec = (r.ppa & ppaf->sec_mask) >> ppaf->sec_offset;
> +	if (geo->c.version == NVM_OCSSD_SPEC_12) {
> +		struct nvm_addr_format_12 *ppaf =
> +				(struct nvm_addr_format_12 *)&geo->c.addrf;
> +
> +		l.g.ch = (r.ppa & ppaf->ch_mask) >> ppaf->ch_offset;
> +		l.g.lun = (r.ppa & ppaf->lun_mask) >> ppaf->lun_offset;
> +		l.g.blk = (r.ppa & ppaf->blk_mask) >> ppaf->blk_offset;
> +		l.g.pg = (r.ppa & ppaf->pg_mask) >> ppaf->pg_offset;
> +		l.g.pl = (r.ppa & ppaf->pln_mask) >> ppaf->pln_offset;
> +		l.g.sec = (r.ppa & ppaf->sec_mask) >> ppaf->sec_offset;
> +	} else {
> +		struct nvm_addr_format *lbaf = &geo->c.addrf;
> +
> +		l.m.ch = (r.ppa & lbaf->ch_mask) >> lbaf->ch_offset;
> +		l.m.lun = (r.ppa & lbaf->lun_mask) >> lbaf->lun_offset;
> +		l.m.chk = (r.ppa & lbaf->chk_mask) >> lbaf->chk_offset;
> +		l.m.sec = (r.ppa & lbaf->sec_mask) >> lbaf->sec_offset;
> +	}
>   
>   	return l;
>   }
> 

Looks good to me.
diff mbox

Patch

diff --git a/drivers/lightnvm/core.c b/drivers/lightnvm/core.c
index f70a907223e2..baec963b2c96 100644
--- a/drivers/lightnvm/core.c
+++ b/drivers/lightnvm/core.c
@@ -196,8 +196,8 @@  static struct nvm_tgt_dev *nvm_create_tgt_dev(struct nvm_dev *dev,
 
 		for (j = 0; j < luns_in_chnl; j++) {
 			luns[lunid].ppa = 0;
-			luns[lunid].g.ch = i;
-			luns[lunid++].g.lun = j;
+			luns[lunid].a.ch = i;
+			luns[lunid++].a.lun = j;
 
 			lun_offs[j] = blun;
 			lun_roffs[j + blun] = blun;
@@ -563,22 +563,22 @@  static void nvm_unregister_map(struct nvm_dev *dev)
 static void nvm_map_to_dev(struct nvm_tgt_dev *tgt_dev, struct ppa_addr *p)
 {
 	struct nvm_dev_map *dev_map = tgt_dev->map;
-	struct nvm_ch_map *ch_map = &dev_map->chnls[p->g.ch];
-	int lun_off = ch_map->lun_offs[p->g.lun];
+	struct nvm_ch_map *ch_map = &dev_map->chnls[p->a.ch];
+	int lun_off = ch_map->lun_offs[p->a.lun];
 
-	p->g.ch += ch_map->ch_off;
-	p->g.lun += lun_off;
+	p->a.ch += ch_map->ch_off;
+	p->a.lun += lun_off;
 }
 
 static void nvm_map_to_tgt(struct nvm_tgt_dev *tgt_dev, struct ppa_addr *p)
 {
 	struct nvm_dev *dev = tgt_dev->parent;
 	struct nvm_dev_map *dev_rmap = dev->rmap;
-	struct nvm_ch_map *ch_rmap = &dev_rmap->chnls[p->g.ch];
-	int lun_roff = ch_rmap->lun_offs[p->g.lun];
+	struct nvm_ch_map *ch_rmap = &dev_rmap->chnls[p->a.ch];
+	int lun_roff = ch_rmap->lun_offs[p->a.lun];
 
-	p->g.ch -= ch_rmap->ch_off;
-	p->g.lun -= lun_roff;
+	p->a.ch -= ch_rmap->ch_off;
+	p->a.lun -= lun_roff;
 }
 
 static void nvm_ppa_tgt_to_dev(struct nvm_tgt_dev *tgt_dev,
diff --git a/include/linux/lightnvm.h b/include/linux/lightnvm.h
index e1c4292ea33d..cd310bf06051 100644
--- a/include/linux/lightnvm.h
+++ b/include/linux/lightnvm.h
@@ -16,12 +16,22 @@  enum {
 	NVM_IOTYPE_GC = 1,
 };
 
-#define NVM_BLK_BITS (16)
-#define NVM_PG_BITS  (16)
-#define NVM_SEC_BITS (8)
-#define NVM_PL_BITS  (8)
-#define NVM_LUN_BITS (8)
-#define NVM_CH_BITS  (7)
+/* common format */
+#define NVM_GEN_CH_BITS  (8)
+#define NVM_GEN_LUN_BITS (8)
+#define NVM_GEN_RESERVED (48)
+
+/* 1.2 format */
+#define NVM_12_BLK_BITS (16)
+#define NVM_12_PG_BITS  (16)
+#define NVM_12_PL_BITS  (4)
+#define NVM_12_SEC_BITS (4)
+#define NVM_12_RESERVED (8)
+
+/* 2.0 format */
+#define NVM_20_CHK_BITS (16)
+#define NVM_20_SEC_BITS (24)
+#define NVM_20_RESERVED (8)
 
 enum {
 	NVM_OCSSD_SPEC_12 = 12,
@@ -31,16 +41,33 @@  enum {
 struct ppa_addr {
 	/* Generic structure for all addresses */
 	union {
+		/* generic device format */
 		struct {
-			u64 blk		: NVM_BLK_BITS;
-			u64 pg		: NVM_PG_BITS;
-			u64 sec		: NVM_SEC_BITS;
-			u64 pl		: NVM_PL_BITS;
-			u64 lun		: NVM_LUN_BITS;
-			u64 ch		: NVM_CH_BITS;
-			u64 reserved	: 1;
+			u64 ch		: NVM_GEN_CH_BITS;
+			u64 lun		: NVM_GEN_LUN_BITS;
+			u64 reserved	: NVM_GEN_RESERVED;
+		} a;
+
+		/* 1.2 device format */
+		struct {
+			u64 ch		: NVM_GEN_CH_BITS;
+			u64 lun		: NVM_GEN_LUN_BITS;
+			u64 blk		: NVM_12_BLK_BITS;
+			u64 pg		: NVM_12_PG_BITS;
+			u64 pl		: NVM_12_PL_BITS;
+			u64 sec		: NVM_12_SEC_BITS;
+			u64 reserved	: NVM_12_RESERVED;
 		} g;
 
+		/* 2.0 device format */
+		struct {
+			u64 ch		: NVM_GEN_CH_BITS;
+			u64 lun		: NVM_GEN_LUN_BITS;
+			u64 chk		: NVM_20_CHK_BITS;
+			u64 sec		: NVM_20_SEC_BITS;
+			u64 reserved	: NVM_20_RESERVED;
+		} m;
+
 		struct {
 			u64 line	: 63;
 			u64 is_cached	: 1;
@@ -392,16 +419,26 @@  static inline struct ppa_addr generic_to_dev_addr(struct nvm_tgt_dev *tgt_dev,
 						  struct ppa_addr r)
 {
 	struct nvm_geo *geo = &tgt_dev->geo;
-	struct nvm_addr_format_12 *ppaf =
-				(struct nvm_addr_format_12 *)&geo->c.addrf;
 	struct ppa_addr l;
 
-	l.ppa = ((u64)r.g.ch) << ppaf->ch_offset;
-	l.ppa |= ((u64)r.g.lun) << ppaf->lun_offset;
-	l.ppa |= ((u64)r.g.blk) << ppaf->blk_offset;
-	l.ppa |= ((u64)r.g.pg) << ppaf->pg_offset;
-	l.ppa |= ((u64)r.g.pl) << ppaf->pln_offset;
-	l.ppa |= ((u64)r.g.sec) << ppaf->sec_offset;
+	if (geo->c.version == NVM_OCSSD_SPEC_12) {
+		struct nvm_addr_format_12 *ppaf =
+				(struct nvm_addr_format_12 *)&geo->c.addrf;
+
+		l.ppa = ((u64)r.g.ch) << ppaf->ch_offset;
+		l.ppa |= ((u64)r.g.lun) << ppaf->lun_offset;
+		l.ppa |= ((u64)r.g.blk) << ppaf->blk_offset;
+		l.ppa |= ((u64)r.g.pg) << ppaf->pg_offset;
+		l.ppa |= ((u64)r.g.pl) << ppaf->pln_offset;
+		l.ppa |= ((u64)r.g.sec) << ppaf->sec_offset;
+	} else {
+		struct nvm_addr_format *lbaf = &geo->c.addrf;
+
+		l.ppa = ((u64)r.m.ch) << lbaf->ch_offset;
+		l.ppa |= ((u64)r.m.lun) << lbaf->lun_offset;
+		l.ppa |= ((u64)r.m.chk) << lbaf->chk_offset;
+		l.ppa |= ((u64)r.m.sec) << lbaf->sec_offset;
+	}
 
 	return l;
 }
@@ -410,18 +447,28 @@  static inline struct ppa_addr dev_to_generic_addr(struct nvm_tgt_dev *tgt_dev,
 						  struct ppa_addr r)
 {
 	struct nvm_geo *geo = &tgt_dev->geo;
-	struct nvm_addr_format_12 *ppaf =
-				(struct nvm_addr_format_12 *)&geo->c.addrf;
 	struct ppa_addr l;
 
 	l.ppa = 0;
 
-	l.g.ch = (r.ppa & ppaf->ch_mask) >> ppaf->ch_offset;
-	l.g.lun = (r.ppa & ppaf->lun_mask) >> ppaf->lun_offset;
-	l.g.blk = (r.ppa & ppaf->blk_mask) >> ppaf->blk_offset;
-	l.g.pg = (r.ppa & ppaf->pg_mask) >> ppaf->pg_offset;
-	l.g.pl = (r.ppa & ppaf->pln_mask) >> ppaf->pln_offset;
-	l.g.sec = (r.ppa & ppaf->sec_mask) >> ppaf->sec_offset;
+	if (geo->c.version == NVM_OCSSD_SPEC_12) {
+		struct nvm_addr_format_12 *ppaf =
+				(struct nvm_addr_format_12 *)&geo->c.addrf;
+
+		l.g.ch = (r.ppa & ppaf->ch_mask) >> ppaf->ch_offset;
+		l.g.lun = (r.ppa & ppaf->lun_mask) >> ppaf->lun_offset;
+		l.g.blk = (r.ppa & ppaf->blk_mask) >> ppaf->blk_offset;
+		l.g.pg = (r.ppa & ppaf->pg_mask) >> ppaf->pg_offset;
+		l.g.pl = (r.ppa & ppaf->pln_mask) >> ppaf->pln_offset;
+		l.g.sec = (r.ppa & ppaf->sec_mask) >> ppaf->sec_offset;
+	} else {
+		struct nvm_addr_format *lbaf = &geo->c.addrf;
+
+		l.m.ch = (r.ppa & lbaf->ch_mask) >> lbaf->ch_offset;
+		l.m.lun = (r.ppa & lbaf->lun_mask) >> lbaf->lun_offset;
+		l.m.chk = (r.ppa & lbaf->chk_mask) >> lbaf->chk_offset;
+		l.m.sec = (r.ppa & lbaf->sec_mask) >> lbaf->sec_offset;
+	}
 
 	return l;
 }