@@ -132,6 +132,8 @@ int cxl_memdev_read_label(struct cxl_memdev *memdev, void *buf, size_t length,
int cxl_memdev_write_label(struct cxl_memdev *memdev, void *buf, size_t length,
size_t offset);
struct cxl_cmd *cxl_cmd_new_get_partition(struct cxl_memdev *memdev);
+struct cxl_cmd *cxl_cmd_new_set_partition(struct cxl_memdev *memdev,
+ unsigned long long volatile_size);
----
@@ -148,6 +150,8 @@ this sub-class of interfaces, there are:
a CXL standard opcode. See the potential command ids in
/usr/include/linux/cxl_mem.h.
+ * 'cxl_cmd_<name>_set_<field>' interfaces that set specific fields in a cxl_cmd
+
* 'cxl_cmd_submit' which submits the command via ioctl()
* 'cxl_cmd_<name>_get_<field>' interfaces that get specific fields out of the
@@ -167,6 +171,13 @@ cxl_memdev{read,write,zero}_label() are helpers for marshaling multiple
label access commands over an arbitrary extent of the device's label
area.
+cxl_cmd_partition_set_mode() supports selecting NEXTBOOT or IMMEDIATE
+mode. When CXL_SETPART_IMMEDIATE mode is set, it is the caller’s
+responsibility to avoid immediate changes to partitioning when the
+device is in use. When CXL_SETPART_NEXTBOOT mode is set, the change
+in partitioning shall become the “next” configuration, to become
+active on the next device reset.
+
BUSES
-----
The CXL Memory space is CPU and Device coherent. The address ranges that
@@ -2478,6 +2478,34 @@ cxl_cmd_partition_get_next_persistent_size(struct cxl_cmd *cmd)
return cxl_capacity_to_bytes(c->next_persistent);
}
+CXL_EXPORT int cxl_cmd_partition_set_mode(struct cxl_cmd *cmd,
+ enum cxl_setpartition_mode mode)
+{
+ struct cxl_cmd_set_partition *setpart = cmd->input_payload;
+
+ if (mode == CXL_SETPART_IMMEDIATE)
+ setpart->flags = CXL_CMD_SET_PARTITION_FLAG_IMMEDIATE;
+ else
+ setpart->flags = !CXL_CMD_SET_PARTITION_FLAG_IMMEDIATE;
+
+ return 0;
+}
+
+CXL_EXPORT struct cxl_cmd *cxl_cmd_new_set_partition(struct cxl_memdev *memdev,
+ unsigned long long volatile_size)
+{
+ struct cxl_cmd_set_partition *setpart;
+ struct cxl_cmd *cmd;
+
+ cmd = cxl_cmd_new_generic(memdev,
+ CXL_MEM_COMMAND_ID_SET_PARTITION_INFO);
+
+ setpart = cmd->input_payload;
+ setpart->volatile_size = cpu_to_le64(volatile_size)
+ / CXL_CAPACITY_MULTIPLIER;
+ return cmd;
+}
+
CXL_EXPORT int cxl_cmd_submit(struct cxl_cmd *cmd)
{
struct cxl_memdev *memdev = cmd->memdev;
@@ -163,4 +163,6 @@ global:
cxl_cmd_identify_get_total_size;
cxl_cmd_identify_get_volatile_only_size;
cxl_cmd_identify_get_persistent_only_size;
+ cxl_cmd_new_set_partition;
+ cxl_cmd_partition_set_mode;
} LIBCXL_1;
@@ -195,6 +195,14 @@ struct cxl_cmd_get_partition {
#define CXL_CAPACITY_MULTIPLIER SZ_256M
+struct cxl_cmd_set_partition {
+ le64 volatile_size;
+ u8 flags;
+} __attribute__((packed));
+
+/* CXL 2.0 8.2.9.5.2 Set Partition Info */
+#define CXL_CMD_SET_PARTITION_FLAG_IMMEDIATE BIT(0)
+
/* CXL 2.0 8.2.9.5.3 Byte 0 Health Status */
#define CXL_CMD_HEALTH_INFO_STATUS_MAINTENANCE_NEEDED_MASK BIT(0)
#define CXL_CMD_HEALTH_INFO_STATUS_PERFORMANCE_DEGRADED_MASK BIT(1)
@@ -250,6 +250,16 @@ unsigned long long cxl_cmd_partition_get_active_volatile_size(struct cxl_cmd *cm
unsigned long long cxl_cmd_partition_get_active_persistent_size(struct cxl_cmd *cmd);
unsigned long long cxl_cmd_partition_get_next_volatile_size(struct cxl_cmd *cmd);
unsigned long long cxl_cmd_partition_get_next_persistent_size(struct cxl_cmd *cmd);
+struct cxl_cmd *cxl_cmd_new_set_partition(struct cxl_memdev *memdev,
+ unsigned long long volatile_size);
+
+enum cxl_setpartition_mode {
+ CXL_SETPART_NEXTBOOT,
+ CXL_SETPART_IMMEDIATE,
+};
+
+int cxl_cmd_partition_set_mode(struct cxl_cmd *cmd,
+ enum cxl_setpartition_mode mode);
#ifdef __cplusplus
} /* extern "C" */