aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/nvdimm/namespace_devs.c
diff options
context:
space:
mode:
authorVishal Verma <vishal.l.verma@intel.com>2017-06-28 16:25:00 -0400
committerDan Williams <dan.j.williams@intel.com>2017-06-29 16:50:38 -0400
commit14e494542636b7a685c5bf27e695e3bb9ec3fe7d (patch)
treeab04daf7eacbc7237c127c3052628c5cac729755 /drivers/nvdimm/namespace_devs.c
parent5e93746f065c49445cf8115007fc887789438ec0 (diff)
libnvdimm, btt: BTT updates for UEFI 2.7 format
The UEFI 2.7 specification defines an updated BTT metadata format, bumping the revision to 2.0. Add support for the new format, while retaining compatibility for the old 1.1 format. Cc: Toshi Kani <toshi.kani@hpe.com> Cc: Linda Knippers <linda.knippers@hpe.com> Cc: Dan Williams <dan.j.williams@intel.com> Signed-off-by: Vishal Verma <vishal.l.verma@intel.com> Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Diffstat (limited to 'drivers/nvdimm/namespace_devs.c')
-rw-r--r--drivers/nvdimm/namespace_devs.c61
1 files changed, 59 insertions, 2 deletions
diff --git a/drivers/nvdimm/namespace_devs.c b/drivers/nvdimm/namespace_devs.c
index f05d9b0672bf..c96e31330213 100644
--- a/drivers/nvdimm/namespace_devs.c
+++ b/drivers/nvdimm/namespace_devs.c
@@ -1411,6 +1411,58 @@ static ssize_t dpa_extents_show(struct device *dev,
1411} 1411}
1412static DEVICE_ATTR_RO(dpa_extents); 1412static DEVICE_ATTR_RO(dpa_extents);
1413 1413
1414static int btt_claim_class(struct device *dev)
1415{
1416 struct nd_region *nd_region = to_nd_region(dev->parent);
1417 int i, loop_bitmask = 0;
1418
1419 for (i = 0; i < nd_region->ndr_mappings; i++) {
1420 struct nd_mapping *nd_mapping = &nd_region->mapping[i];
1421 struct nvdimm_drvdata *ndd = to_ndd(nd_mapping);
1422 struct nd_namespace_index *nsindex;
1423
1424 nsindex = to_namespace_index(ndd, ndd->ns_current);
1425 if (nsindex == NULL)
1426 loop_bitmask |= 1;
1427 else {
1428 /* check whether existing labels are v1.1 or v1.2 */
1429 if (__le16_to_cpu(nsindex->major) == 1
1430 && __le16_to_cpu(nsindex->minor) == 1)
1431 loop_bitmask |= 2;
1432 else
1433 loop_bitmask |= 4;
1434 }
1435 }
1436 /*
1437 * If nsindex is null loop_bitmask's bit 0 will be set, and if an index
1438 * block is found, a v1.1 label for any mapping will set bit 1, and a
1439 * v1.2 label will set bit 2.
1440 *
1441 * At the end of the loop, at most one of the three bits must be set.
1442 * If multiple bits were set, it means the different mappings disagree
1443 * about their labels, and this must be cleaned up first.
1444 *
1445 * If all the label index blocks are found to agree, nsindex of NULL
1446 * implies labels haven't been initialized yet, and when they will,
1447 * they will be of the 1.2 format, so we can assume BTT2.0
1448 *
1449 * If 1.1 labels are found, we enforce BTT1.1, and if 1.2 labels are
1450 * found, we enforce BTT2.0
1451 *
1452 * If the loop was never entered, default to BTT1.1 (legacy namespaces)
1453 */
1454 switch (loop_bitmask) {
1455 case 0:
1456 case 2:
1457 return NVDIMM_CCLASS_BTT;
1458 case 1:
1459 case 4:
1460 return NVDIMM_CCLASS_BTT2;
1461 default:
1462 return -ENXIO;
1463 }
1464}
1465
1414static ssize_t holder_show(struct device *dev, 1466static ssize_t holder_show(struct device *dev,
1415 struct device_attribute *attr, char *buf) 1467 struct device_attribute *attr, char *buf)
1416{ 1468{
@@ -1433,7 +1485,7 @@ static ssize_t __holder_class_store(struct device *dev, const char *buf)
1433 return -EBUSY; 1485 return -EBUSY;
1434 1486
1435 if (strcmp(buf, "btt") == 0 || strcmp(buf, "btt\n") == 0) 1487 if (strcmp(buf, "btt") == 0 || strcmp(buf, "btt\n") == 0)
1436 ndns->claim_class = NVDIMM_CCLASS_BTT; 1488 ndns->claim_class = btt_claim_class(dev);
1437 else if (strcmp(buf, "pfn") == 0 || strcmp(buf, "pfn\n") == 0) 1489 else if (strcmp(buf, "pfn") == 0 || strcmp(buf, "pfn\n") == 0)
1438 ndns->claim_class = NVDIMM_CCLASS_PFN; 1490 ndns->claim_class = NVDIMM_CCLASS_PFN;
1439 else if (strcmp(buf, "dax") == 0 || strcmp(buf, "dax\n") == 0) 1491 else if (strcmp(buf, "dax") == 0 || strcmp(buf, "dax\n") == 0)
@@ -1443,6 +1495,10 @@ static ssize_t __holder_class_store(struct device *dev, const char *buf)
1443 else 1495 else
1444 return -EINVAL; 1496 return -EINVAL;
1445 1497
1498 /* btt_claim_class() could've returned an error */
1499 if (ndns->claim_class < 0)
1500 return ndns->claim_class;
1501
1446 return 0; 1502 return 0;
1447} 1503}
1448 1504
@@ -1474,7 +1530,8 @@ static ssize_t holder_class_show(struct device *dev,
1474 device_lock(dev); 1530 device_lock(dev);
1475 if (ndns->claim_class == NVDIMM_CCLASS_NONE) 1531 if (ndns->claim_class == NVDIMM_CCLASS_NONE)
1476 rc = sprintf(buf, "\n"); 1532 rc = sprintf(buf, "\n");
1477 else if (ndns->claim_class == NVDIMM_CCLASS_BTT) 1533 else if ((ndns->claim_class == NVDIMM_CCLASS_BTT) ||
1534 (ndns->claim_class == NVDIMM_CCLASS_BTT2))
1478 rc = sprintf(buf, "btt\n"); 1535 rc = sprintf(buf, "btt\n");
1479 else if (ndns->claim_class == NVDIMM_CCLASS_PFN) 1536 else if (ndns->claim_class == NVDIMM_CCLASS_PFN)
1480 rc = sprintf(buf, "pfn\n"); 1537 rc = sprintf(buf, "pfn\n");