// SPDX-License-Identifier: GPL-2.0-only
/* Copyright(c) 2020 Intel Corporation. All rights reserved. */
#include <uapi/linux/cxl_mem.h>
#include <linux/security.h>
#include <linux/debugfs.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/cdev.h>
#include <linux/idr.h>
#include <linux/pci.h>
#include <linux/io.h>
#include <linux/io-64-nonatomic-lo-hi.h>
#include "pci.h"
#include "cxl.h"

/**
 * DOC: cxl mem
 *
 * This implements a CXL memory device ("type-3") as it is defined by the
 * Compute Express Link specification.
 *
 * The driver has several responsibilities, mainly:
 *  - Create the memX device and register on the CXL bus.
 *  - Enumerate device's register interface and map them.
 *  - Probe the device attributes to establish sysfs interface.
 *  - Provide an IOCTL interface to userspace to communicate with the device for
 *    things like firmware update.
 *  - Support management of interleave sets.
 *  - Handle and manage error conditions.
 */

/*
 * An entire PCI topology full of devices should be enough for any
 * config
 */
#define CXL_MEM_MAX_DEVS 65536

#define cxl_doorbell_busy(cxlm)                                                \
	(readl((cxlm)->mbox_regs + CXLDEV_MBOX_CTRL_OFFSET) &                  \
	 CXLDEV_MBOX_CTRL_DOORBELL)

/* CXL 2.0 - 8.2.8.4 */
#define CXL_MAILBOX_TIMEOUT_MS (2 * HZ)

enum opcode {
	CXL_MBOX_OP_INVALID		= 0x0000,
	CXL_MBOX_OP_RAW			= CXL_MBOX_OP_INVALID,
	CXL_MBOX_OP_GET_FW_INFO		= 0x0200,
	CXL_MBOX_OP_ACTIVATE_FW		= 0x0202,
	CXL_MBOX_OP_GET_SUPPORTED_LOGS	= 0x0400,
	CXL_MBOX_OP_GET_LOG		= 0x0401,
	CXL_MBOX_OP_IDENTIFY		= 0x4000,
	CXL_MBOX_OP_GET_PARTITION_INFO	= 0x4100,
	CXL_MBOX_OP_SET_PARTITION_INFO	= 0x4101,
	CXL_MBOX_OP_GET_LSA		= 0x4102,
	CXL_MBOX_OP_SET_LSA		= 0x4103,
	CXL_MBOX_OP_GET_HEALTH_INFO	= 0x4200,
	CXL_MBOX_OP_SET_SHUTDOWN_STATE	= 0x4204,
	CXL_MBOX_OP_SCAN_MEDIA		= 0x4304,
	CXL_MBOX_OP_GET_SCAN_MEDIA	= 0x4305,
	CXL_MBOX_OP_MAX			= 0x10000
};

/**
 * struct mbox_cmd - A command to be submitted to hardware.
 * @opcode: (input) The command set and command submitted to hardware.
 * @payload_in: (input) Pointer to the input payload.
 * @payload_out: (output) Pointer to the output payload. Must be allocated by
 *		 the caller.
 * @size_in: (input) Number of bytes to load from @payload_in.
 * @size_out: (input) Max number of bytes loaded into @payload_out.
 *            (output) Number of bytes generated by the device. For fixed size
 *            outputs commands this is always expected to be deterministic. For
 *            variable sized output commands, it tells the exact number of bytes
 *            written.
 * @return_code: (output) Error code returned from hardware.
 *
 * This is the primary mechanism used to send commands to the hardware.
 * All the fields except @payload_* correspond exactly to the fields described in
 * Command Register section of the CXL 2.0 8.2.8.4.5. @payload_in and
 * @payload_out are written to, and read from the Command Payload Registers
 * defined in CXL 2.0 8.2.8.4.8.
 */
struct mbox_cmd {
	u16 opcode;
	void *payload_in;
	void *payload_out;
	size_t size_in;
	size_t size_out;
	u16 return_code;
#define CXL_MBOX_SUCCESS 0
};

/**
 * struct cxl_memdev - CXL bus object representing a Type-3 Memory Device
 * @dev: driver core device object
 * @cdev: char dev core object for ioctl operations
 * @cxlm: pointer to the parent device driver data
 * @id: id number of this memdev instance.
 */
struct cxl_memdev {
	struct device dev;
	struct cdev cdev;
	struct cxl_mem *cxlm;
	int id;
};

static int cxl_mem_major;
static DEFINE_IDA(cxl_memdev_ida);
static DECLARE_RWSEM(cxl_memdev_rwsem);
static struct dentry *cxl_debugfs;
static bool cxl_raw_allow_all;

enum {
	CEL_UUID,
	VENDOR_DEBUG_UUID,
};

/* See CXL 2.0 Table 170. Get Log Input Payload */
static const uuid_t log_uuid[] = {
	[CEL_UUID] = UUID_INIT(0xda9c0b5, 0xbf41, 0x4b78, 0x8f, 0x79, 0x96,
			       0xb1, 0x62, 0x3b, 0x3f, 0x17),
	[VENDOR_DEBUG_UUID] = UUID_INIT(0xe1819d9, 0x11a9, 0x400c, 0x81, 0x1f,
					0xd6, 0x07, 0x19, 0x40, 0x3d, 0x86),
};

/**
 * struct cxl_mem_command - Driver representation of a memory device command
 * @info: Command information as it exists for the UAPI
 * @opcode: The actual bits used for the mailbox protocol
 * @flags: Set of flags effecting driver behavior.
 *
 *  * %CXL_CMD_FLAG_FORCE_ENABLE: In cases of error, commands with this flag
 *    will be enabled by the driver regardless of what hardware may have
 *    advertised.
 *
 * The cxl_mem_command is the driver's internal representation of commands that
 * are supported by the driver. Some of these commands may not be supported by
 * the hardware. The driver will use @info to validate the fields passed in by
 * the user then submit the @opcode to the hardware.
 *
 * See struct cxl_command_info.
 */
struct cxl_mem_command {
	struct cxl_command_info info;
	enum opcode opcode;
	u32 flags;
#define CXL_CMD_FLAG_NONE 0
#define CXL_CMD_FLAG_FORCE_ENABLE BIT(0)
};

#define CXL_CMD(_id, sin, sout, _flags)                                        \
	[CXL_MEM_COMMAND_ID_##_id] = {                                         \
	.info =	{                                                              \
			.id = CXL_MEM_COMMAND_ID_##_id,                        \
			.size_in = sin,                                        \
			.size_out = sout,                                      \
		},                                                             \
	.opcode = CXL_MBOX_OP_##_id,                                           \
	.flags = _flags,                                                       \
	}

/*
 * This table defines the supported mailbox commands for the driver. This table
 * is made up of a UAPI structure. Non-negative values as parameters in the
 * table will be validated against the user's input. For example, if size_in is
 * 0, and the user passed in 1, it is an error.
 */
static struct cxl_mem_command mem_commands[CXL_MEM_COMMAND_ID_MAX] = {
	CXL_CMD(IDENTIFY, 0, 0x43, CXL_CMD_FLAG_FORCE_ENABLE),
#ifdef CONFIG_CXL_MEM_RAW_COMMANDS
	CXL_CMD(RAW, ~0, ~0, 0),
#endif
	CXL_CMD(GET_SUPPORTED_LOGS, 0, ~0, CXL_CMD_FLAG_FORCE_ENABLE),
	CXL_CMD(GET_FW_INFO, 0, 0x50, 0),
	CXL_CMD(GET_PARTITION_INFO, 0, 0x20, 0),
	CXL_CMD(GET_LSA, 0x8, ~0, 0),
	CXL_CMD(GET_HEALTH_INFO, 0, 0x12, 0),
	CXL_CMD(GET_LOG, 0x18, ~0, CXL_CMD_FLAG_FORCE_ENABLE),
};

/*
 * Commands that RAW doesn't permit. The rationale for each:
 *
 * CXL_MBOX_OP_ACTIVATE_FW: Firmware activation requires adjustment /
 * coordination of transaction timeout values at the root bridge level.
 *
 * CXL_MBOX_OP_SET_PARTITION_INFO: The device memory map may change live
 * and needs to be coordinated with HDM updates.
 *
 * CXL_MBOX_OP_SET_LSA: The label storage area may be cached by the
 * driver and any writes from userspace invalidates those contents.
 *
 * CXL_MBOX_OP_SET_SHUTDOWN_STATE: Set shutdown state assumes no writes
 * to the device after it is marked clean, userspace can not make that
 * assertion.
 *
 * CXL_MBOX_OP_[GET_]SCAN_MEDIA: The kernel provides a native error list that
 * is kept up to date with patrol notifications and error management.
 */
static u16 cxl_disabled_raw_commands[] = {
	CXL_MBOX_OP_ACTIVATE_FW,
	CXL_MBOX_OP_SET_PARTITION_INFO,
	CXL_MBOX_OP_SET_LSA,
	CXL_MBOX_OP_SET_SHUTDOWN_STATE,
	CXL_MBOX_OP_SCAN_MEDIA,
	CXL_MBOX_OP_GET_SCAN_MEDIA,
};

/*
 * Command sets that RAW doesn't permit. All opcodes in this set are
 * disabled because they pass plain text security payloads over the
 * user/kernel boundary. This functionality is intended to be wrapped
 * behind the keys ABI which allows for encrypted payloads in the UAPI
 */
static u8 security_command_sets[] = {
	0x44, /* Sanitize */
	0x45, /* Persistent Memory Data-at-rest Security */
	0x46, /* Security Passthrough */
};

#define cxl_for_each_cmd(cmd)                                                  \
	for ((cmd) = &mem_commands[0];                                         \
	     ((cmd) - mem_commands) < ARRAY_SIZE(mem_commands); (cmd)++)

#define cxl_cmd_count ARRAY_SIZE(mem_commands)

static int cxl_mem_wait_for_doorbell(struct cxl_mem *cxlm)
{
	const unsigned long start = jiffies;
	unsigned long end = start;

	while (cxl_doorbell_busy(cxlm)) {
		end = jiffies;

		if (time_after(end, start + CXL_MAILBOX_TIMEOUT_MS)) {
			/* Check again in case preempted before timeout test */
			if (!cxl_doorbell_busy(cxlm))
				break;
			return -ETIMEDOUT;
		}
		cpu_relax();
	}

	dev_dbg(&cxlm->pdev->dev, "Doorbell wait took %dms",
		jiffies_to_msecs(end) - jiffies_to_msecs(start));
	return 0;
}

static bool cxl_is_security_command(u16 opcode)
{
	int i;

	for (i = 0; i < ARRAY_SIZE(security_command_sets); i++)
		if (security_command_sets[i] == (opcode >> 8))
			return true;
	return false;
}

static void cxl_mem_mbox_timeout(struct cxl_mem *cxlm,
				 struct mbox_cmd *mbox_cmd)
{
	struct device *dev = &cxlm->pdev->dev;

	dev_dbg(dev, "Mailbox command (opcode: %#x size: %zub) timed out\n",
		mbox_cmd->opcode, mbox_cmd->size_in);
}

/**
 * __cxl_mem_mbox_send_cmd() - Execute a mailbox command
 * @cxlm: The CXL memory device to communicate with.
 * @mbox_cmd: Command to send to the memory device.
 *
 * Context: Any context. Expects mbox_mutex to be held.
 * Return: -ETIMEDOUT if timeout occurred waiting for completion. 0 on success.
 *         Caller should check the return code in @mbox_cmd to make sure it
 *         succeeded.
 *
 * This is a generic form of the CXL mailbox send command thus only using the
 * registers defined by the mailbox capability ID - CXL 2.0 8.2.8.4. Memory
 * devices, and perhaps other types of CXL devices may have further information
 * available upon error conditions. Driver facilities wishing to send mailbox
 * commands should use the wrapper command.
 *
 * The CXL spec allows for up to two mailboxes. The intention is for the primary
 * mailbox to be OS controlled and the secondary mailbox to be used by system
 * firmware. This allows the OS and firmware to communicate with the device and
 * not need to coordinate with each other. The driver only uses the primary
 * mailbox.
 */
static int __cxl_mem_mbox_send_cmd(struct cxl_mem *cxlm,
				   struct mbox_cmd *mbox_cmd)
{
	void __iomem *payload = cxlm->mbox_regs + CXLDEV_MBOX_PAYLOAD_OFFSET;
	u64 cmd_reg, status_reg;
	size_t out_len;
	int rc;

	lockdep_assert_held(&cxlm->mbox_mutex);

	/*
	 * Here are the steps from 8.2.8.4 of the CXL 2.0 spec.
	 *   1. Caller reads MB Control Register to verify doorbell is clear
	 *   2. Caller writes Command Register
	 *   3. Caller writes Command Payload Registers if input payload is non-empty
	 *   4. Caller writes MB Control Register to set doorbell
	 *   5. Caller either polls for doorbell to be clear or waits for interrupt if configured
	 *   6. Caller reads MB Status Register to fetch Return code
	 *   7. If command successful, Caller reads Command Register to get Payload Length
	 *   8. If output payload is non-empty, host reads Command Payload Registers
	 *
	 * Hardware is free to do whatever it wants before the doorbell is rung,
	 * and isn't allowed to change anything after it clears the doorbell. As
	 * such, steps 2 and 3 can happen in any order, and steps 6, 7, 8 can
	 * also happen in any order (though some orders might not make sense).
	 */

	/* #1 */
	if (cxl_doorbell_busy(cxlm)) {
		dev_err_ratelimited(&cxlm->pdev->dev,
				    "Mailbox re-busy after acquiring\n");
		return -EBUSY;
	}

	cmd_reg = FIELD_PREP(CXLDEV_MBOX_CMD_COMMAND_OPCODE_MASK,
			     mbox_cmd->opcode);
	if (mbox_cmd->size_in) {
		if (WARN_ON(!mbox_cmd->payload_in))
			return -EINVAL;

		cmd_reg |= FIELD_PREP(CXLDEV_MBOX_CMD_PAYLOAD_LENGTH_MASK,
				      mbox_cmd->size_in);
		memcpy_toio(payload, mbox_cmd->payload_in, mbox_cmd->size_in);
	}

	/* #2, #3 */
	writeq(cmd_reg, cxlm->mbox_regs + CXLDEV_MBOX_CMD_OFFSET);

	/* #4 */
	dev_dbg(&cxlm->pdev->dev, "Sending command\n");
	writel(CXLDEV_MBOX_CTRL_DOORBELL,
	       cxlm->mbox_regs + CXLDEV_MBOX_CTRL_OFFSET);

	/* #5 */
	rc = cxl_mem_wait_for_doorbell(cxlm);
	if (rc == -ETIMEDOUT) {
		cxl_mem_mbox_timeout(cxlm, mbox_cmd);
		return rc;
	}

	/* #6 */
	status_reg = readq(cxlm->mbox_regs + CXLDEV_MBOX_STATUS_OFFSET);
	mbox_cmd->return_code =
		FIELD_GET(CXLDEV_MBOX_STATUS_RET_CODE_MASK, status_reg);

	if (mbox_cmd->return_code != 0) {
		dev_dbg(&cxlm->pdev->dev, "Mailbox operation had an error\n");
		return 0;
	}

	/* #7 */
	cmd_reg = readq(cxlm->mbox_regs + CXLDEV_MBOX_CMD_OFFSET);
	out_len = FIELD_GET(CXLDEV_MBOX_CMD_PAYLOAD_LENGTH_MASK, cmd_reg);

	/* #8 */
	if (out_len && mbox_cmd->payload_out) {
		/*
		 * Sanitize the copy. If hardware misbehaves, out_len per the
		 * spec can actually be greater than the max allowed size (21
		 * bits available but spec defined 1M max). The caller also may
		 * have requested less data than the hardware supplied even
		 * within spec.
		 */
		size_t n = min3(mbox_cmd->size_out, cxlm->payload_size, out_len);

		memcpy_fromio(mbox_cmd->payload_out, payload, n);
		mbox_cmd->size_out = n;
	} else {
		mbox_cmd->size_out = 0;
	}

	return 0;
}

/**
 * cxl_mem_mbox_get() - Acquire exclusive access to the mailbox.
 * @cxlm: The memory device to gain access to.
 *
 * Context: Any context. Takes the mbox_mutex.
 * Return: 0 if exclusive access was acquired.
 */
static int cxl_mem_mbox_get(struct cxl_mem *cxlm)
{
	struct device *dev = &cxlm->pdev->dev;
	u64 md_status;
	int rc;

	mutex_lock_io(&cxlm->mbox_mutex);

	/*
	 * XXX: There is some amount of ambiguity in the 2.0 version of the spec
	 * around the mailbox interface ready (8.2.8.5.1.1).  The purpose of the
	 * bit is to allow firmware running on the device to notify the driver
	 * that it's ready to receive commands. It is unclear if the bit needs
	 * to be read for each transaction mailbox, ie. the firmware can switch
	 * it on and off as needed. Second, there is no defined timeout for
	 * mailbox ready, like there is for the doorbell interface.
	 *
	 * Assumptions:
	 * 1. The firmware might toggle the Mailbox Interface Ready bit, check
	 *    it for every command.
	 *
	 * 2. If the doorbell is clear, the firmware should have first set the
	 *    Mailbox Interface Ready bit. Therefore, waiting for the doorbell
	 *    to be ready is sufficient.
	 */
	rc = cxl_mem_wait_for_doorbell(cxlm);
	if (rc) {
		dev_warn(dev, "Mailbox interface not ready\n");
		goto out;
	}

	md_status = readq(cxlm->memdev_regs + CXLMDEV_STATUS_OFFSET);
	if (!(md_status & CXLMDEV_MBOX_IF_READY && CXLMDEV_READY(md_status))) {
		dev_err(dev, "mbox: reported doorbell ready, but not mbox ready\n");
		rc = -EBUSY;
		goto out;
	}

	/*
	 * Hardware shouldn't allow a ready status but also have failure bits
	 * set. Spit out an error, this should be a bug report
	 */
	rc = -EFAULT;
	if (md_status & CXLMDEV_DEV_FATAL) {
		dev_err(dev, "mbox: reported ready, but fatal\n");
		goto out;
	}
	if (md_status & CXLMDEV_FW_HALT) {
		dev_err(dev, "mbox: reported ready, but halted\n");
		goto out;
	}
	if (CXLMDEV_RESET_NEEDED(md_status)) {
		dev_err(dev, "mbox: reported ready, but reset needed\n");
		goto out;
	}

	/* with lock held */
	return 0;

out:
	mutex_unlock(&cxlm->mbox_mutex);
	return rc;
}

/**
 * cxl_mem_mbox_put() - Release exclusive access to the mailbox.
 * @cxlm: The CXL memory device to communicate with.
 *
 * Context: Any context. Expects mbox_mutex to be held.
 */
static void cxl_mem_mbox_put(struct cxl_mem *cxlm)
{
	mutex_unlock(&cxlm->mbox_mutex);
}

/**
 * handle_mailbox_cmd_from_user() - Dispatch a mailbox command for userspace.
 * @cxlm: The CXL memory device to communicate with.
 * @cmd: The validated command.
 * @in_payload: Pointer to userspace's input payload.
 * @out_payload: Pointer to userspace's output payload.
 * @size_out: (Input) Max payload size to copy out.
 *            (Output) Payload size hardware generated.
 * @retval: Hardware generated return code from the operation.
 *
 * Return:
 *  * %0	- Mailbox transaction succeeded. This implies the mailbox
 *		  protocol completed successfully not that the operation itself
 *		  was successful.
 *  * %-ENOMEM  - Couldn't allocate a bounce buffer.
 *  * %-EFAULT	- Something happened with copy_to/from_user.
 *  * %-EINTR	- Mailbox acquisition interrupted.
 *  * %-EXXX	- Transaction level failures.
 *
 * Creates the appropriate mailbox command and dispatches it on behalf of a
 * userspace request. The input and output payloads are copied between
 * userspace.
 *
 * See cxl_send_cmd().
 */
static int handle_mailbox_cmd_from_user(struct cxl_mem *cxlm,
					const struct cxl_mem_command *cmd,
					u64 in_payload, u64 out_payload,
					s32 *size_out, u32 *retval)
{
	struct device *dev = &cxlm->pdev->dev;
	struct mbox_cmd mbox_cmd = {
		.opcode = cmd->opcode,
		.size_in = cmd->info.size_in,
		.size_out = cmd->info.size_out,
	};
	int rc;

	if (cmd->info.size_out) {
		mbox_cmd.payload_out = kvzalloc(cmd->info.size_out, GFP_KERNEL);
		if (!mbox_cmd.payload_out)
			return -ENOMEM;
	}

	if (cmd->info.size_in) {
		mbox_cmd.payload_in = vmemdup_user(u64_to_user_ptr(in_payload),
						   cmd->info.size_in);
		if (IS_ERR(mbox_cmd.payload_in)) {
			kvfree(mbox_cmd.payload_out);
			return PTR_ERR(mbox_cmd.payload_in);
		}
	}

	rc = cxl_mem_mbox_get(cxlm);
	if (rc)
		goto out;

	dev_dbg(dev,
		"Submitting %s command for user\n"
		"\topcode: %x\n"
		"\tsize: %ub\n",
		cxl_command_names[cmd->info.id].name, mbox_cmd.opcode,
		cmd->info.size_in);

	dev_WARN_ONCE(dev, cmd->info.id == CXL_MEM_COMMAND_ID_RAW,
		      "raw command path used\n");

	rc = __cxl_mem_mbox_send_cmd(cxlm, &mbox_cmd);
	cxl_mem_mbox_put(cxlm);
	if (rc)
		goto out;

	/*
	 * @size_out contains the max size that's allowed to be written back out
	 * to userspace. While the payload may have written more output than
	 * this it will have to be ignored.
	 */
	if (mbox_cmd.size_out) {
		dev_WARN_ONCE(dev, mbox_cmd.size_out > *size_out,
			      "Invalid return size\n");
		if (copy_to_user(u64_to_user_ptr(out_payload),
				 mbox_cmd.payload_out, mbox_cmd.size_out)) {
			rc = -EFAULT;
			goto out;
		}
	}

	*size_out = mbox_cmd.size_out;
	*retval = mbox_cmd.return_code;

out:
	kvfree(mbox_cmd.payload_in);
	kvfree(mbox_cmd.payload_out);
	return rc;
}

static bool cxl_mem_raw_command_allowed(u16 opcode)
{
	int i;

	if (!IS_ENABLED(CONFIG_CXL_MEM_RAW_COMMANDS))
		return false;

	if (security_locked_down(LOCKDOWN_NONE))
		return false;

	if (cxl_raw_allow_all)
		return true;

	if (cxl_is_security_command(opcode))
		return false;

	for (i = 0; i < ARRAY_SIZE(cxl_disabled_raw_commands); i++)
		if (cxl_disabled_raw_commands[i] == opcode)
			return false;

	return true;
}

/**
 * cxl_validate_cmd_from_user() - Check fields for CXL_MEM_SEND_COMMAND.
 * @cxlm: &struct cxl_mem device whose mailbox will be used.
 * @send_cmd: &struct cxl_send_command copied in from userspace.
 * @out_cmd: Sanitized and populated &struct cxl_mem_command.
 *
 * Return:
 *  * %0	- @out_cmd is ready to send.
 *  * %-ENOTTY	- Invalid command specified.
 *  * %-EINVAL	- Reserved fields or invalid values were used.
 *  * %-ENOMEM	- Input or output buffer wasn't sized properly.
 *  * %-EPERM	- Attempted to use a protected command.
 *
 * The result of this command is a fully validated command in @out_cmd that is
 * safe to send to the hardware.
 *
 * See handle_mailbox_cmd_from_user()
 */
static int cxl_validate_cmd_from_user(struct cxl_mem *cxlm,
				      const struct cxl_send_command *send_cmd,
				      struct cxl_mem_command *out_cmd)
{
	const struct cxl_command_info *info;
	struct cxl_mem_command *c;

	if (send_cmd->id == 0 || send_cmd->id >= CXL_MEM_COMMAND_ID_MAX)
		return -ENOTTY;

	/*
	 * The user can never specify an input payload larger than what hardware
	 * supports, but output can be arbitrarily large (simply write out as
	 * much data as the hardware provides).
	 */
	if (send_cmd->in.size > cxlm->payload_size)
		return -EINVAL;

	/*
	 * Checks are bypassed for raw commands but a WARN/taint will occur
	 * later in the callchain
	 */
	if (send_cmd->id == CXL_MEM_COMMAND_ID_RAW) {
		const struct cxl_mem_command temp = {
			.info = {
				.id = CXL_MEM_COMMAND_ID_RAW,
				.flags = 0,
				.size_in = send_cmd->in.size,
				.size_out = send_cmd->out.size,
			},
			.opcode = send_cmd->raw.opcode
		};

		if (send_cmd->raw.rsvd)
			return -EINVAL;

		/*
		 * Unlike supported commands, the output size of RAW commands
		 * gets passed along without further checking, so it must be
		 * validated here.
		 */
		if (send_cmd->out.size > cxlm->payload_size)
			return -EINVAL;

		if (!cxl_mem_raw_command_allowed(send_cmd->raw.opcode))
			return -EPERM;

		memcpy(out_cmd, &temp, sizeof(temp));

		return 0;
	}

	if (send_cmd->flags & ~CXL_MEM_COMMAND_FLAG_MASK)
		return -EINVAL;

	if (send_cmd->rsvd)
		return -EINVAL;

	if (send_cmd->in.rsvd || send_cmd->out.rsvd)
		return -EINVAL;

	/* Convert user's command into the internal representation */
	c = &mem_commands[send_cmd->id];
	info = &c->info;

	/* Check that the command is enabled for hardware */
	if (!test_bit(info->id, cxlm->enabled_cmds))
		return -ENOTTY;

	/* Check the input buffer is the expected size */
	if (info->size_in >= 0 && info->size_in != send_cmd->in.size)
		return -ENOMEM;

	/* Check the output buffer is at least large enough */
	if (info->size_out >= 0 && send_cmd->out.size < info->size_out)
		return -ENOMEM;

	memcpy(out_cmd, c, sizeof(*c));
	out_cmd->info.size_in = send_cmd->in.size;
	/*
	 * XXX: out_cmd->info.size_out will be controlled by the driver, and the
	 * specified number of bytes @send_cmd->out.size will be copied back out
	 * to userspace.
	 */

	return 0;
}

static int cxl_query_cmd(struct cxl_memdev *cxlmd,
			 struct cxl_mem_query_commands __user *q)
{
	struct device *dev = &cxlmd->dev;
	struct cxl_mem_command *cmd;
	u32 n_commands;
	int j = 0;

	dev_dbg(dev, "Query IOCTL\n");

	if (get_user(n_commands, &q->n_commands))
		return -EFAULT;

	/* returns the total number if 0 elements are requested. */
	if (n_commands == 0)
		return put_user(cxl_cmd_count, &q->n_commands);

	/*
	 * otherwise, return max(n_commands, total commands) cxl_command_info
	 * structures.
	 */
	cxl_for_each_cmd(cmd) {
		const struct cxl_command_info *info = &cmd->info;

		if (copy_to_user(&q->commands[j++], info, sizeof(*info)))
			return -EFAULT;

		if (j == n_commands)
			break;
	}

	return 0;
}

static int cxl_send_cmd(struct cxl_memdev *cxlmd,
			struct cxl_send_command __user *s)
{
	struct cxl_mem *cxlm = cxlmd->cxlm;
	struct device *dev = &cxlmd->dev;
	struct cxl_send_command send;
	struct cxl_mem_command c;
	int rc;

	dev_dbg(dev, "Send IOCTL\n");

	if (copy_from_user(&send, s, sizeof(send)))
		return -EFAULT;

	rc = cxl_validate_cmd_from_user(cxlmd->cxlm, &send, &c);
	if (rc)
		return rc;

	/* Prepare to handle a full payload for variable sized output */
	if (c.info.size_out < 0)
		c.info.size_out = cxlm->payload_size;

	rc = handle_mailbox_cmd_from_user(cxlm, &c, send.in.payload,
					  send.out.payload, &send.out.size,
					  &send.retval);
	if (rc)
		return rc;

	if (copy_to_user(s, &send, sizeof(send)))
		return -EFAULT;

	return 0;
}

static long __cxl_memdev_ioctl(struct cxl_memdev *cxlmd, unsigned int cmd,
			       unsigned long arg)
{
	switch (cmd) {
	case CXL_MEM_QUERY_COMMANDS:
		return cxl_query_cmd(cxlmd, (void __user *)arg);
	case CXL_MEM_SEND_COMMAND:
		return cxl_send_cmd(cxlmd, (void __user *)arg);
	default:
		return -ENOTTY;
	}
}

static long cxl_memdev_ioctl(struct file *file, unsigned int cmd,
			     unsigned long arg)
{
	struct cxl_memdev *cxlmd = file->private_data;
	int rc = -ENXIO;

	down_read(&cxl_memdev_rwsem);
	if (cxlmd->cxlm)
		rc = __cxl_memdev_ioctl(cxlmd, cmd, arg);
	up_read(&cxl_memdev_rwsem);

	return rc;
}

static int cxl_memdev_open(struct inode *inode, struct file *file)
{
	struct cxl_memdev *cxlmd =
		container_of(inode->i_cdev, typeof(*cxlmd), cdev);

	get_device(&cxlmd->dev);
	file->private_data = cxlmd;

	return 0;
}

static int cxl_memdev_release_file(struct inode *inode, struct file *file)
{
	struct cxl_memdev *cxlmd =
		container_of(inode->i_cdev, typeof(*cxlmd), cdev);

	put_device(&cxlmd->dev);

	return 0;
}

static const struct file_operations cxl_memdev_fops = {
	.owner = THIS_MODULE,
	.unlocked_ioctl = cxl_memdev_ioctl,
	.open = cxl_memdev_open,
	.release = cxl_memdev_release_file,
	.compat_ioctl = compat_ptr_ioctl,
	.llseek = noop_llseek,
};

static inline struct cxl_mem_command *cxl_mem_find_command(u16 opcode)
{
	struct cxl_mem_command *c;

	cxl_for_each_cmd(c)
		if (c->opcode == opcode)
			return c;

	return NULL;
}

/**
 * cxl_mem_mbox_send_cmd() - Send a mailbox command to a memory device.
 * @cxlm: The CXL memory device to communicate with.
 * @opcode: Opcode for the mailbox command.
 * @in: The input payload for the mailbox command.
 * @in_size: The length of the input payload
 * @out: Caller allocated buffer for the output.
 * @out_size: Expected size of output.
 *
 * Context: Any context. Will acquire and release mbox_mutex.
 * Return:
 *  * %>=0	- Number of bytes returned in @out.
 *  * %-E2BIG	- Payload is too large for hardware.
 *  * %-EBUSY	- Couldn't acquire exclusive mailbox access.
 *  * %-EFAULT	- Hardware error occurred.
 *  * %-ENXIO	- Command completed, but device reported an error.
 *  * %-EIO	- Unexpected output size.
 *
 * Mailbox commands may execute successfully yet the device itself reported an
 * error. While this distinction can be useful for commands from userspace, the
 * kernel will only be able to use results when both are successful.
 *
 * See __cxl_mem_mbox_send_cmd()
 */
static int cxl_mem_mbox_send_cmd(struct cxl_mem *cxlm, u16 opcode,
				 void *in, size_t in_size,
				 void *out, size_t out_size)
{
	const struct cxl_mem_command *cmd = cxl_mem_find_command(opcode);
	struct mbox_cmd mbox_cmd = {
		.opcode = opcode,
		.payload_in = in,
		.size_in = in_size,
		.size_out = out_size,
		.payload_out = out,
	};
	int rc;

	if (out_size > cxlm->payload_size)
		return -E2BIG;

	rc = cxl_mem_mbox_get(cxlm);
	if (rc)
		return rc;

	rc = __cxl_mem_mbox_send_cmd(cxlm, &mbox_cmd);
	cxl_mem_mbox_put(cxlm);
	if (rc)
		return rc;

	/* TODO: Map return code to proper kernel style errno */
	if (mbox_cmd.return_code != CXL_MBOX_SUCCESS)
		return -ENXIO;

	/*
	 * Variable sized commands can't be validated and so it's up to the
	 * caller to do that if they wish.
	 */
	if (cmd->info.size_out >= 0 && mbox_cmd.size_out != out_size)
		return -EIO;

	return 0;
}

/**
 * cxl_mem_setup_regs() - Setup necessary MMIO.
 * @cxlm: The CXL memory device to communicate with.
 *
 * Return: 0 if all necessary registers mapped.
 *
 * A memory device is required by spec to implement a certain set of MMIO
 * regions. The purpose of this function is to enumerate and map those
 * registers.
 */
static int cxl_mem_setup_regs(struct cxl_mem *cxlm)
{
	struct device *dev = &cxlm->pdev->dev;
	int cap, cap_count;
	u64 cap_array;

	cap_array = readq(cxlm->regs + CXLDEV_CAP_ARRAY_OFFSET);
	if (FIELD_GET(CXLDEV_CAP_ARRAY_ID_MASK, cap_array) !=
	    CXLDEV_CAP_ARRAY_CAP_ID)
		return -ENODEV;

	cap_count = FIELD_GET(CXLDEV_CAP_ARRAY_COUNT_MASK, cap_array);

	for (cap = 1; cap <= cap_count; cap++) {
		void __iomem *register_block;
		u32 offset;
		u16 cap_id;

		cap_id = FIELD_GET(CXLDEV_CAP_HDR_CAP_ID_MASK,
				   readl(cxlm->regs + cap * 0x10));
		offset = readl(cxlm->regs + cap * 0x10 + 0x4);
		register_block = cxlm->regs + offset;

		switch (cap_id) {
		case CXLDEV_CAP_CAP_ID_DEVICE_STATUS:
			dev_dbg(dev, "found Status capability (0x%x)\n", offset);
			cxlm->status_regs = register_block;
			break;
		case CXLDEV_CAP_CAP_ID_PRIMARY_MAILBOX:
			dev_dbg(dev, "found Mailbox capability (0x%x)\n", offset);
			cxlm->mbox_regs = register_block;
			break;
		case CXLDEV_CAP_CAP_ID_SECONDARY_MAILBOX:
			dev_dbg(dev, "found Secondary Mailbox capability (0x%x)\n", offset);
			break;
		case CXLDEV_CAP_CAP_ID_MEMDEV:
			dev_dbg(dev, "found Memory Device capability (0x%x)\n", offset);
			cxlm->memdev_regs = register_block;
			break;
		default:
			dev_dbg(dev, "Unknown cap ID: %d (0x%x)\n", cap_id, offset);
			break;
		}
	}

	if (!cxlm->status_regs || !cxlm->mbox_regs || !cxlm->memdev_regs) {
		dev_err(dev, "registers not found: %s%s%s\n",
			!cxlm->status_regs ? "status " : "",
			!cxlm->mbox_regs ? "mbox " : "",
			!cxlm->memdev_regs ? "memdev" : "");
		return -ENXIO;
	}

	return 0;
}

static int cxl_mem_setup_mailbox(struct cxl_mem *cxlm)
{
	const int cap = readl(cxlm->mbox_regs + CXLDEV_MBOX_CAPS_OFFSET);

	cxlm->payload_size =
		1 << FIELD_GET(CXLDEV_MBOX_CAP_PAYLOAD_SIZE_MASK, cap);

	/*
	 * CXL 2.0 8.2.8.4.3 Mailbox Capabilities Register
	 *
	 * If the size is too small, mandatory commands will not work and so
	 * there's no point in going forward. If the size is too large, there's
	 * no harm is soft limiting it.
	 */
	cxlm->payload_size = min_t(size_t, cxlm->payload_size, SZ_1M);
	if (cxlm->payload_size < 256) {
		dev_err(&cxlm->pdev->dev, "Mailbox is too small (%zub)",
			cxlm->payload_size);
		return -ENXIO;
	}

	dev_dbg(&cxlm->pdev->dev, "Mailbox payload sized %zu",
		cxlm->payload_size);

	return 0;
}

static struct cxl_mem *cxl_mem_create(struct pci_dev *pdev, u32 reg_lo,
				      u32 reg_hi)
{
	struct device *dev = &pdev->dev;
	struct cxl_mem *cxlm;
	void __iomem *regs;
	u64 offset;
	u8 bar;
	int rc;

	cxlm = devm_kzalloc(&pdev->dev, sizeof(*cxlm), GFP_KERNEL);
	if (!cxlm) {
		dev_err(dev, "No memory available\n");
		return NULL;
	}

	offset = ((u64)reg_hi << 32) | (reg_lo & CXL_REGLOC_ADDR_MASK);
	bar = FIELD_GET(CXL_REGLOC_BIR_MASK, reg_lo);

	/* Basic sanity check that BAR is big enough */
	if (pci_resource_len(pdev, bar) < offset) {
		dev_err(dev, "BAR%d: %pr: too small (offset: %#llx)\n", bar,
			&pdev->resource[bar], (unsigned long long)offset);
		return NULL;
	}

	rc = pcim_iomap_regions(pdev, BIT(bar), pci_name(pdev));
	if (rc) {
		dev_err(dev, "failed to map registers\n");
		return NULL;
	}
	regs = pcim_iomap_table(pdev)[bar];

	mutex_init(&cxlm->mbox_mutex);
	cxlm->pdev = pdev;
	cxlm->regs = regs + offset;
	cxlm->enabled_cmds =
		devm_kmalloc_array(dev, BITS_TO_LONGS(cxl_cmd_count),
				   sizeof(unsigned long),
				   GFP_KERNEL | __GFP_ZERO);
	if (!cxlm->enabled_cmds) {
		dev_err(dev, "No memory available for bitmap\n");
		return NULL;
	}

	dev_dbg(dev, "Mapped CXL Memory Device resource\n");
	return cxlm;
}

static int cxl_mem_dvsec(struct pci_dev *pdev, int dvsec)
{
	int pos;

	pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_DVSEC);
	if (!pos)
		return 0;

	while (pos) {
		u16 vendor, id;

		pci_read_config_word(pdev, pos + PCI_DVSEC_HEADER1, &vendor);
		pci_read_config_word(pdev, pos + PCI_DVSEC_HEADER2, &id);
		if (vendor == PCI_DVSEC_VENDOR_ID_CXL && dvsec == id)
			return pos;

		pos = pci_find_next_ext_capability(pdev, pos,
						   PCI_EXT_CAP_ID_DVSEC);
	}

	return 0;
}

static struct cxl_memdev *to_cxl_memdev(struct device *dev)
{
	return container_of(dev, struct cxl_memdev, dev);
}

static void cxl_memdev_release(struct device *dev)
{
	struct cxl_memdev *cxlmd = to_cxl_memdev(dev);

	ida_free(&cxl_memdev_ida, cxlmd->id);
	kfree(cxlmd);
}

static char *cxl_memdev_devnode(struct device *dev, umode_t *mode, kuid_t *uid,
				kgid_t *gid)
{
	return kasprintf(GFP_KERNEL, "cxl/%s", dev_name(dev));
}

static ssize_t firmware_version_show(struct device *dev,
				     struct device_attribute *attr, char *buf)
{
	struct cxl_memdev *cxlmd = to_cxl_memdev(dev);
	struct cxl_mem *cxlm = cxlmd->cxlm;

	return sysfs_emit(buf, "%.16s\n", cxlm->firmware_version);
}
static DEVICE_ATTR_RO(firmware_version);

static ssize_t payload_max_show(struct device *dev,
				struct device_attribute *attr, char *buf)
{
	struct cxl_memdev *cxlmd = to_cxl_memdev(dev);
	struct cxl_mem *cxlm = cxlmd->cxlm;

	return sysfs_emit(buf, "%zu\n", cxlm->payload_size);
}
static DEVICE_ATTR_RO(payload_max);

static ssize_t ram_size_show(struct device *dev, struct device_attribute *attr,
			     char *buf)
{
	struct cxl_memdev *cxlmd = to_cxl_memdev(dev);
	struct cxl_mem *cxlm = cxlmd->cxlm;
	unsigned long long len = range_len(&cxlm->ram_range);

	return sysfs_emit(buf, "%#llx\n", len);
}

static struct device_attribute dev_attr_ram_size =
	__ATTR(size, 0444, ram_size_show, NULL);

static ssize_t pmem_size_show(struct device *dev, struct device_attribute *attr,
			      char *buf)
{
	struct cxl_memdev *cxlmd = to_cxl_memdev(dev);
	struct cxl_mem *cxlm = cxlmd->cxlm;
	unsigned long long len = range_len(&cxlm->pmem_range);

	return sysfs_emit(buf, "%#llx\n", len);
}

static struct device_attribute dev_attr_pmem_size =
	__ATTR(size, 0444, pmem_size_show, NULL);

static struct attribute *cxl_memdev_attributes[] = {
	&dev_attr_firmware_version.attr,
	&dev_attr_payload_max.attr,
	NULL,
};

static struct attribute *cxl_memdev_pmem_attributes[] = {
	&dev_attr_pmem_size.attr,
	NULL,
};

static struct attribute *cxl_memdev_ram_attributes[] = {
	&dev_attr_ram_size.attr,
	NULL,
};

static struct attribute_group cxl_memdev_attribute_group = {
	.attrs = cxl_memdev_attributes,
};

static struct attribute_group cxl_memdev_ram_attribute_group = {
	.name = "ram",
	.attrs = cxl_memdev_ram_attributes,
};

static struct attribute_group cxl_memdev_pmem_attribute_group = {
	.name = "pmem",
	.attrs = cxl_memdev_pmem_attributes,
};

static const struct attribute_group *cxl_memdev_attribute_groups[] = {
	&cxl_memdev_attribute_group,
	&cxl_memdev_ram_attribute_group,
	&cxl_memdev_pmem_attribute_group,
	NULL,
};

static const struct device_type cxl_memdev_type = {
	.name = "cxl_memdev",
	.release = cxl_memdev_release,
	.devnode = cxl_memdev_devnode,
	.groups = cxl_memdev_attribute_groups,
};

static void cxl_memdev_shutdown(struct cxl_memdev *cxlmd)
{
	down_write(&cxl_memdev_rwsem);
	cxlmd->cxlm = NULL;
	up_write(&cxl_memdev_rwsem);
}

static void cxl_memdev_unregister(void *_cxlmd)
{
	struct cxl_memdev *cxlmd = _cxlmd;
	struct device *dev = &cxlmd->dev;

	cdev_device_del(&cxlmd->cdev, dev);
	cxl_memdev_shutdown(cxlmd);
	put_device(dev);
}

static struct cxl_memdev *cxl_memdev_alloc(struct cxl_mem *cxlm)
{
	struct pci_dev *pdev = cxlm->pdev;
	struct cxl_memdev *cxlmd;
	struct device *dev;
	struct cdev *cdev;
	int rc;

	cxlmd = kzalloc(sizeof(*cxlmd), GFP_KERNEL);
	if (!cxlmd)
		return ERR_PTR(-ENOMEM);

	rc = ida_alloc_range(&cxl_memdev_ida, 0, CXL_MEM_MAX_DEVS, GFP_KERNEL);
	if (rc < 0)
		goto err;
	cxlmd->id = rc;

	dev = &cxlmd->dev;
	device_initialize(dev);
	dev->parent = &pdev->dev;
	dev->bus = &cxl_bus_type;
	dev->devt = MKDEV(cxl_mem_major, cxlmd->id);
	dev->type = &cxl_memdev_type;
	device_set_pm_not_required(dev);

	cdev = &cxlmd->cdev;
	cdev_init(cdev, &cxl_memdev_fops);
	return cxlmd;

err:
	kfree(cxlmd);
	return ERR_PTR(rc);
}

static int cxl_mem_add_memdev(struct cxl_mem *cxlm)
{
	struct cxl_memdev *cxlmd;
	struct device *dev;
	struct cdev *cdev;
	int rc;

	cxlmd = cxl_memdev_alloc(cxlm);
	if (IS_ERR(cxlmd))
		return PTR_ERR(cxlmd);

	dev = &cxlmd->dev;
	rc = dev_set_name(dev, "mem%d", cxlmd->id);
	if (rc)
		goto err;

	/*
	 * Activate ioctl operations, no cxl_memdev_rwsem manipulation
	 * needed as this is ordered with cdev_add() publishing the device.
	 */
	cxlmd->cxlm = cxlm;

	cdev = &cxlmd->cdev;
	rc = cdev_device_add(cdev, dev);
	if (rc)
		goto err;

	return devm_add_action_or_reset(dev->parent, cxl_memdev_unregister,
					cxlmd);

err:
	/*
	 * The cdev was briefly live, shutdown any ioctl operations that
	 * saw that state.
	 */
	cxl_memdev_shutdown(cxlmd);
	put_device(dev);
	return rc;
}

static int cxl_xfer_log(struct cxl_mem *cxlm, uuid_t *uuid, u32 size, u8 *out)
{
	u32 remaining = size;
	u32 offset = 0;

	while (remaining) {
		u32 xfer_size = min_t(u32, remaining, cxlm->payload_size);
		struct cxl_mbox_get_log {
			uuid_t uuid;
			__le32 offset;
			__le32 length;
		} __packed log = {
			.uuid = *uuid,
			.offset = cpu_to_le32(offset),
			.length = cpu_to_le32(xfer_size)
		};
		int rc;

		rc = cxl_mem_mbox_send_cmd(cxlm, CXL_MBOX_OP_GET_LOG, &log,
					   sizeof(log), out, xfer_size);
		if (rc < 0)
			return rc;

		out += xfer_size;
		remaining -= xfer_size;
		offset += xfer_size;
	}

	return 0;
}

/**
 * cxl_walk_cel() - Walk through the Command Effects Log.
 * @cxlm: Device.
 * @size: Length of the Command Effects Log.
 * @cel: CEL
 *
 * Iterate over each entry in the CEL and determine if the driver supports the
 * command. If so, the command is enabled for the device and can be used later.
 */
static void cxl_walk_cel(struct cxl_mem *cxlm, size_t size, u8 *cel)
{
	struct cel_entry {
		__le16 opcode;
		__le16 effect;
	} __packed * cel_entry;
	const int cel_entries = size / sizeof(*cel_entry);
	int i;

	cel_entry = (struct cel_entry *)cel;

	for (i = 0; i < cel_entries; i++) {
		u16 opcode = le16_to_cpu(cel_entry[i].opcode);
		struct cxl_mem_command *cmd = cxl_mem_find_command(opcode);

		if (!cmd) {
			dev_dbg(&cxlm->pdev->dev,
				"Opcode 0x%04x unsupported by driver", opcode);
			continue;
		}

		set_bit(cmd->info.id, cxlm->enabled_cmds);
	}
}

struct cxl_mbox_get_supported_logs {
	__le16 entries;
	u8 rsvd[6];
	struct gsl_entry {
		uuid_t uuid;
		__le32 size;
	} __packed entry[];
} __packed;

static struct cxl_mbox_get_supported_logs *cxl_get_gsl(struct cxl_mem *cxlm)
{
	struct cxl_mbox_get_supported_logs *ret;
	int rc;

	ret = kvmalloc(cxlm->payload_size, GFP_KERNEL);
	if (!ret)
		return ERR_PTR(-ENOMEM);

	rc = cxl_mem_mbox_send_cmd(cxlm, CXL_MBOX_OP_GET_SUPPORTED_LOGS, NULL,
				   0, ret, cxlm->payload_size);
	if (rc < 0) {
		kvfree(ret);
		return ERR_PTR(rc);
	}

	return ret;
}

/**
 * cxl_mem_enumerate_cmds() - Enumerate commands for a device.
 * @cxlm: The device.
 *
 * Returns 0 if enumerate completed successfully.
 *
 * CXL devices have optional support for certain commands. This function will
 * determine the set of supported commands for the hardware and update the
 * enabled_cmds bitmap in the @cxlm.
 */
static int cxl_mem_enumerate_cmds(struct cxl_mem *cxlm)
{
	struct cxl_mbox_get_supported_logs *gsl;
	struct device *dev = &cxlm->pdev->dev;
	struct cxl_mem_command *cmd;
	int i, rc;

	gsl = cxl_get_gsl(cxlm);
	if (IS_ERR(gsl))
		return PTR_ERR(gsl);

	rc = -ENOENT;
	for (i = 0; i < le16_to_cpu(gsl->entries); i++) {
		u32 size = le32_to_cpu(gsl->entry[i].size);
		uuid_t uuid = gsl->entry[i].uuid;
		u8 *log;

		dev_dbg(dev, "Found LOG type %pU of size %d", &uuid, size);

		if (!uuid_equal(&uuid, &log_uuid[CEL_UUID]))
			continue;

		log = kvmalloc(size, GFP_KERNEL);
		if (!log) {
			rc = -ENOMEM;
			goto out;
		}

		rc = cxl_xfer_log(cxlm, &uuid, size, log);
		if (rc) {
			kvfree(log);
			goto out;
		}

		cxl_walk_cel(cxlm, size, log);
		kvfree(log);

		/* In case CEL was bogus, enable some default commands. */
		cxl_for_each_cmd(cmd)
			if (cmd->flags & CXL_CMD_FLAG_FORCE_ENABLE)
				set_bit(cmd->info.id, cxlm->enabled_cmds);

		/* Found the required CEL */
		rc = 0;
	}

out:
	kvfree(gsl);
	return rc;
}

/**
 * cxl_mem_identify() - Send the IDENTIFY command to the device.
 * @cxlm: The device to identify.
 *
 * Return: 0 if identify was executed successfully.
 *
 * This will dispatch the identify command to the device and on success populate
 * structures to be exported to sysfs.
 */
static int cxl_mem_identify(struct cxl_mem *cxlm)
{
	struct cxl_mbox_identify {
		char fw_revision[0x10];
		__le64 total_capacity;
		__le64 volatile_capacity;
		__le64 persistent_capacity;
		__le64 partition_align;
		__le16 info_event_log_size;
		__le16 warning_event_log_size;
		__le16 failure_event_log_size;
		__le16 fatal_event_log_size;
		__le32 lsa_size;
		u8 poison_list_max_mer[3];
		__le16 inject_poison_limit;
		u8 poison_caps;
		u8 qos_telemetry_caps;
	} __packed id;
	int rc;

	rc = cxl_mem_mbox_send_cmd(cxlm, CXL_MBOX_OP_IDENTIFY, NULL, 0, &id,
				   sizeof(id));
	if (rc < 0)
		return rc;

	/*
	 * TODO: enumerate DPA map, as 'ram' and 'pmem' do not alias.
	 * For now, only the capacity is exported in sysfs
	 */
	cxlm->ram_range.start = 0;
	cxlm->ram_range.end = le64_to_cpu(id.volatile_capacity) - 1;

	cxlm->pmem_range.start = 0;
	cxlm->pmem_range.end = le64_to_cpu(id.persistent_capacity) - 1;

	memcpy(cxlm->firmware_version, id.fw_revision, sizeof(id.fw_revision));

	return 0;
}

static int cxl_mem_probe(struct pci_dev *pdev, const struct pci_device_id *id)
{
	struct device *dev = &pdev->dev;
	struct cxl_mem *cxlm = NULL;
	u32 regloc_size, regblocks;
	int rc, regloc, i;

	rc = pcim_enable_device(pdev);
	if (rc)
		return rc;

	regloc = cxl_mem_dvsec(pdev, PCI_DVSEC_ID_CXL_REGLOC_OFFSET);
	if (!regloc) {
		dev_err(dev, "register location dvsec not found\n");
		return -ENXIO;
	}

	/* Get the size of the Register Locator DVSEC */
	pci_read_config_dword(pdev, regloc + PCI_DVSEC_HEADER1, &regloc_size);
	regloc_size = FIELD_GET(PCI_DVSEC_HEADER1_LENGTH_MASK, regloc_size);

	regloc += PCI_DVSEC_ID_CXL_REGLOC_BLOCK1_OFFSET;
	regblocks = (regloc_size - PCI_DVSEC_ID_CXL_REGLOC_BLOCK1_OFFSET) / 8;

	for (i = 0; i < regblocks; i++, regloc += 8) {
		u32 reg_lo, reg_hi;
		u8 reg_type;

		/* "register low and high" contain other bits */
		pci_read_config_dword(pdev, regloc, &reg_lo);
		pci_read_config_dword(pdev, regloc + 4, &reg_hi);

		reg_type = FIELD_GET(CXL_REGLOC_RBI_MASK, reg_lo);

		if (reg_type == CXL_REGLOC_RBI_MEMDEV) {
			cxlm = cxl_mem_create(pdev, reg_lo, reg_hi);
			break;
		}
	}

	if (!cxlm)
		return -ENODEV;

	rc = cxl_mem_setup_regs(cxlm);
	if (rc)
		return rc;

	rc = cxl_mem_setup_mailbox(cxlm);
	if (rc)
		return rc;

	rc = cxl_mem_enumerate_cmds(cxlm);
	if (rc)
		return rc;

	rc = cxl_mem_identify(cxlm);
	if (rc)
		return rc;

	return cxl_mem_add_memdev(cxlm);
}

static const struct pci_device_id cxl_mem_pci_tbl[] = {
	/* PCI class code for CXL.mem Type-3 Devices */
	{ PCI_DEVICE_CLASS((PCI_CLASS_MEMORY_CXL << 8 | CXL_MEMORY_PROGIF), ~0)},
	{ /* terminate list */ },
};
MODULE_DEVICE_TABLE(pci, cxl_mem_pci_tbl);

static struct pci_driver cxl_mem_driver = {
	.name			= KBUILD_MODNAME,
	.id_table		= cxl_mem_pci_tbl,
	.probe			= cxl_mem_probe,
	.driver	= {
		.probe_type	= PROBE_PREFER_ASYNCHRONOUS,
	},
};

static __init int cxl_mem_init(void)
{
	struct dentry *mbox_debugfs;
	dev_t devt;
	int rc;

	rc = alloc_chrdev_region(&devt, 0, CXL_MEM_MAX_DEVS, "cxl");
	if (rc)
		return rc;

	cxl_mem_major = MAJOR(devt);

	rc = pci_register_driver(&cxl_mem_driver);
	if (rc) {
		unregister_chrdev_region(MKDEV(cxl_mem_major, 0),
					 CXL_MEM_MAX_DEVS);
		return rc;
	}

	cxl_debugfs = debugfs_create_dir("cxl", NULL);
	mbox_debugfs = debugfs_create_dir("mbox", cxl_debugfs);
	debugfs_create_bool("raw_allow_all", 0600, mbox_debugfs,
			    &cxl_raw_allow_all);

	return 0;
}

static __exit void cxl_mem_exit(void)
{
	debugfs_remove_recursive(cxl_debugfs);
	pci_unregister_driver(&cxl_mem_driver);
	unregister_chrdev_region(MKDEV(cxl_mem_major, 0), CXL_MEM_MAX_DEVS);
}

MODULE_LICENSE("GPL v2");
module_init(cxl_mem_init);
module_exit(cxl_mem_exit);
MODULE_IMPORT_NS(CXL);
