// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright © 2016 Intel Corporation
 *
 * Authors:
 *    Scott  Bauer      <scott.bauer@intel.com>
 *    Rafael Antognolli <rafael.antognolli@intel.com>
 */

#define pr_fmt(fmt) KBUILD_MODNAME ":OPAL: " fmt

#include <linux/delay.h>
#include <linux/device.h>
#include <linux/kernel.h>
#include <linux/list.h>
#include <linux/blkdev.h>
#include <linux/slab.h>
#include <linux/uaccess.h>
#include <uapi/linux/sed-opal.h>
#include <linux/sed-opal.h>
#include <linux/string.h>
#include <linux/kdev_t.h>
#include <linux/key.h>
#include <linux/key-type.h>
#include <keys/user-type.h>

#include "opal_proto.h"

#define IO_BUFFER_LENGTH 2048
#define MAX_TOKS 64

/* Number of bytes needed by cmd_finalize. */
#define CMD_FINALIZE_BYTES_NEEDED 7

static struct key *sed_opal_keyring;

struct opal_step {
	int (*fn)(struct opal_dev *dev, void *data);
	void *data;
};
typedef int (cont_fn)(struct opal_dev *dev);

enum opal_atom_width {
	OPAL_WIDTH_TINY,
	OPAL_WIDTH_SHORT,
	OPAL_WIDTH_MEDIUM,
	OPAL_WIDTH_LONG,
	OPAL_WIDTH_TOKEN
};

/*
 * On the parsed response, we don't store again the toks that are already
 * stored in the response buffer. Instead, for each token, we just store a
 * pointer to the position in the buffer where the token starts, and the size
 * of the token in bytes.
 */
struct opal_resp_tok {
	const u8 *pos;
	size_t len;
	enum opal_response_token type;
	enum opal_atom_width width;
	union {
		u64 u;
		s64 s;
	} stored;
};

/*
 * From the response header it's not possible to know how many tokens there are
 * on the payload. So we hardcode that the maximum will be MAX_TOKS, and later
 * if we start dealing with messages that have more than that, we can increase
 * this number. This is done to avoid having to make two passes through the
 * response, the first one counting how many tokens we have and the second one
 * actually storing the positions.
 */
struct parsed_resp {
	int num;
	struct opal_resp_tok toks[MAX_TOKS];
};

struct opal_dev {
	u32 flags;

	void *data;
	sec_send_recv *send_recv;

	struct mutex dev_lock;
	u16 comid;
	u32 hsn;
	u32 tsn;
	u64 align; /* alignment granularity */
	u64 lowest_lba;
	u32 logical_block_size;
	u8  align_required; /* ALIGN: 0 or 1 */

	size_t pos;
	u8 *cmd;
	u8 *resp;

	struct parsed_resp parsed;
	size_t prev_d_len;
	void *prev_data;

	struct list_head unlk_lst;
};


static const u8 opaluid[][OPAL_UID_LENGTH] = {
	/* users */
	[OPAL_SMUID_UID] =
		{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff },
	[OPAL_THISSP_UID] =
		{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 },
	[OPAL_ADMINSP_UID] =
		{ 0x00, 0x00, 0x02, 0x05, 0x00, 0x00, 0x00, 0x01 },
	[OPAL_LOCKINGSP_UID] =
		{ 0x00, 0x00, 0x02, 0x05, 0x00, 0x00, 0x00, 0x02 },
	[OPAL_ENTERPRISE_LOCKINGSP_UID] =
		{ 0x00, 0x00, 0x02, 0x05, 0x00, 0x01, 0x00, 0x01 },
	[OPAL_ANYBODY_UID] =
		{ 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x01 },
	[OPAL_SID_UID] =
		{ 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x06 },
	[OPAL_ADMIN1_UID] =
		{ 0x00, 0x00, 0x00, 0x09, 0x00, 0x01, 0x00, 0x01 },
	[OPAL_USER1_UID] =
		{ 0x00, 0x00, 0x00, 0x09, 0x00, 0x03, 0x00, 0x01 },
	[OPAL_USER2_UID] =
		{ 0x00, 0x00, 0x00, 0x09, 0x00, 0x03, 0x00, 0x02 },
	[OPAL_PSID_UID] =
		{ 0x00, 0x00, 0x00, 0x09, 0x00, 0x01, 0xff, 0x01 },
	[OPAL_ENTERPRISE_BANDMASTER0_UID] =
		{ 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x80, 0x01 },
	[OPAL_ENTERPRISE_ERASEMASTER_UID] =
		{ 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x84, 0x01 },

	/* tables */
	[OPAL_TABLE_TABLE] =
		{ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01 },
	[OPAL_LOCKINGRANGE_GLOBAL] =
		{ 0x00, 0x00, 0x08, 0x02, 0x00, 0x00, 0x00, 0x01 },
	[OPAL_LOCKINGRANGE_ACE_START_TO_KEY] =
		{ 0x00, 0x00, 0x00, 0x08, 0x00, 0x03, 0xD0, 0x01 },
	[OPAL_LOCKINGRANGE_ACE_RDLOCKED] =
		{ 0x00, 0x00, 0x00, 0x08, 0x00, 0x03, 0xE0, 0x01 },
	[OPAL_LOCKINGRANGE_ACE_WRLOCKED] =
		{ 0x00, 0x00, 0x00, 0x08, 0x00, 0x03, 0xE8, 0x01 },
	[OPAL_MBRCONTROL] =
		{ 0x00, 0x00, 0x08, 0x03, 0x00, 0x00, 0x00, 0x01 },
	[OPAL_MBR] =
		{ 0x00, 0x00, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00 },
	[OPAL_AUTHORITY_TABLE] =
		{ 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00},
	[OPAL_C_PIN_TABLE] =
		{ 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x00},
	[OPAL_LOCKING_INFO_TABLE] =
		{ 0x00, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x01 },
	[OPAL_ENTERPRISE_LOCKING_INFO_TABLE] =
		{ 0x00, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x00 },
	[OPAL_DATASTORE] =
		{ 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x00, 0x00 },

	/* C_PIN_TABLE object ID's */
	[OPAL_C_PIN_MSID] =
		{ 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x84, 0x02},
	[OPAL_C_PIN_SID] =
		{ 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x01},
	[OPAL_C_PIN_ADMIN1] =
		{ 0x00, 0x00, 0x00, 0x0B, 0x00, 0x01, 0x00, 0x01},

	/* half UID's (only first 4 bytes used) */
	[OPAL_HALF_UID_AUTHORITY_OBJ_REF] =
		{ 0x00, 0x00, 0x0C, 0x05, 0xff, 0xff, 0xff, 0xff },
	[OPAL_HALF_UID_BOOLEAN_ACE] =
		{ 0x00, 0x00, 0x04, 0x0E, 0xff, 0xff, 0xff, 0xff },

	/* special value for omitted optional parameter */
	[OPAL_UID_HEXFF] =
		{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
};

/*
 * TCG Storage SSC Methods.
 * Derived from: TCG_Storage_Architecture_Core_Spec_v2.01_r1.00
 * Section: 6.3 Assigned UIDs
 */
static const u8 opalmethod[][OPAL_METHOD_LENGTH] = {
	[OPAL_PROPERTIES] =
		{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x01 },
	[OPAL_STARTSESSION] =
		{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x02 },
	[OPAL_REVERT] =
		{ 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x02, 0x02 },
	[OPAL_ACTIVATE] =
		{ 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x02, 0x03 },
	[OPAL_EGET] =
		{ 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06 },
	[OPAL_ESET] =
		{ 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x07 },
	[OPAL_NEXT] =
		{ 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x08 },
	[OPAL_EAUTHENTICATE] =
		{ 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0c },
	[OPAL_GETACL] =
		{ 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0d },
	[OPAL_GENKEY] =
		{ 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x10 },
	[OPAL_REVERTSP] =
		{ 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x11 },
	[OPAL_GET] =
		{ 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x16 },
	[OPAL_SET] =
		{ 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x17 },
	[OPAL_AUTHENTICATE] =
		{ 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x1c },
	[OPAL_RANDOM] =
		{ 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x01 },
	[OPAL_ERASE] =
		{ 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x08, 0x03 },
};

static int end_opal_session_error(struct opal_dev *dev);
static int opal_discovery0_step(struct opal_dev *dev);

struct opal_suspend_data {
	struct opal_lock_unlock unlk;
	u8 lr;
	struct list_head node;
};

/*
 * Derived from:
 * TCG_Storage_Architecture_Core_Spec_v2.01_r1.00
 * Section: 5.1.5 Method Status Codes
 */
static const char * const opal_errors[] = {
	"Success",
	"Not Authorized",
	"Unknown Error",
	"SP Busy",
	"SP Failed",
	"SP Disabled",
	"SP Frozen",
	"No Sessions Available",
	"Uniqueness Conflict",
	"Insufficient Space",
	"Insufficient Rows",
	"Invalid Function",
	"Invalid Parameter",
	"Invalid Reference",
	"Unknown Error",
	"TPER Malfunction",
	"Transaction Failure",
	"Response Overflow",
	"Authority Locked Out",
};

static const char *opal_error_to_human(int error)
{
	if (error == 0x3f)
		return "Failed";

	if (error >= ARRAY_SIZE(opal_errors) || error < 0)
		return "Unknown Error";

	return opal_errors[error];
}

static void print_buffer(const u8 *ptr, u32 length)
{
#ifdef DEBUG
	print_hex_dump_bytes("OPAL: ", DUMP_PREFIX_OFFSET, ptr, length);
	pr_debug("\n");
#endif
}

/*
 * Allocate/update a SED Opal key and add it to the SED Opal keyring.
 */
static int update_sed_opal_key(const char *desc, u_char *key_data, int keylen)
{
	key_ref_t kr;

	if (!sed_opal_keyring)
		return -ENOKEY;

	kr = key_create_or_update(make_key_ref(sed_opal_keyring, true), "user",
				  desc, (const void *)key_data, keylen,
				  KEY_USR_VIEW | KEY_USR_SEARCH | KEY_USR_WRITE,
				  KEY_ALLOC_NOT_IN_QUOTA | KEY_ALLOC_BUILT_IN |
					KEY_ALLOC_BYPASS_RESTRICTION);
	if (IS_ERR(kr)) {
		pr_err("Error adding SED key (%ld)\n", PTR_ERR(kr));
		return PTR_ERR(kr);
	}

	return 0;
}

/*
 * Read a SED Opal key from the SED Opal keyring.
 */
static int read_sed_opal_key(const char *key_name, u_char *buffer, int buflen)
{
	int ret;
	key_ref_t kref;
	struct key *key;

	if (!sed_opal_keyring)
		return -ENOKEY;

	kref = keyring_search(make_key_ref(sed_opal_keyring, true),
			      &key_type_user, key_name, true);

	if (IS_ERR(kref))
		ret = PTR_ERR(kref);

	key = key_ref_to_ptr(kref);
	down_read(&key->sem);
	ret = key_validate(key);
	if (ret == 0) {
		if (buflen > key->datalen)
			buflen = key->datalen;

		ret = key->type->read(key, (char *)buffer, buflen);
	}
	up_read(&key->sem);

	key_ref_put(kref);

	return ret;
}

static int opal_get_key(struct opal_dev *dev, struct opal_key *key)
{
	int ret = 0;

	switch (key->key_type) {
	case OPAL_INCLUDED:
		/* the key is ready to use */
		break;
	case OPAL_KEYRING:
		/* the key is in the keyring */
		ret = read_sed_opal_key(OPAL_AUTH_KEY, key->key, OPAL_KEY_MAX);
		if (ret > 0) {
			if (ret > U8_MAX) {
				ret = -ENOSPC;
				goto error;
			}
			key->key_len = ret;
			key->key_type = OPAL_INCLUDED;
		}
		break;
	default:
		ret = -EINVAL;
		break;
	}
	if (ret < 0)
		goto error;

	/* must have a PEK by now or it's an error */
	if (key->key_type != OPAL_INCLUDED || key->key_len == 0) {
		ret = -EINVAL;
		goto error;
	}
	return 0;
error:
	pr_debug("Error getting password: %d\n", ret);
	return ret;
}

static bool check_tper(const void *data)
{
	const struct d0_tper_features *tper = data;
	u8 flags = tper->supported_features;

	if (!(flags & TPER_SYNC_SUPPORTED)) {
		pr_debug("TPer sync not supported. flags = %d\n",
			 tper->supported_features);
		return false;
	}

	return true;
}

static bool check_lcksuppt(const void *data)
{
	const struct d0_locking_features *lfeat = data;
	u8 sup_feat = lfeat->supported_features;

	return !!(sup_feat & LOCKING_SUPPORTED_MASK);
}

static bool check_lckenabled(const void *data)
{
	const struct d0_locking_features *lfeat = data;
	u8 sup_feat = lfeat->supported_features;

	return !!(sup_feat & LOCKING_ENABLED_MASK);
}

static bool check_locked(const void *data)
{
	const struct d0_locking_features *lfeat = data;
	u8 sup_feat = lfeat->supported_features;

	return !!(sup_feat & LOCKED_MASK);
}

static bool check_mbrenabled(const void *data)
{
	const struct d0_locking_features *lfeat = data;
	u8 sup_feat = lfeat->supported_features;

	return !!(sup_feat & MBR_ENABLED_MASK);
}

static bool check_mbrdone(const void *data)
{
	const struct d0_locking_features *lfeat = data;
	u8 sup_feat = lfeat->supported_features;

	return !!(sup_feat & MBR_DONE_MASK);
}

static bool check_sum(const void *data)
{
	const struct d0_single_user_mode *sum = data;
	u32 nlo = be32_to_cpu(sum->num_locking_objects);

	if (nlo == 0) {
		pr_debug("Need at least one locking object.\n");
		return false;
	}

	pr_debug("Number of locking objects: %d\n", nlo);

	return true;
}

static u16 get_comid_v100(const void *data)
{
	const struct d0_opal_v100 *v100 = data;

	return be16_to_cpu(v100->baseComID);
}

static u16 get_comid_v200(const void *data)
{
	const struct d0_opal_v200 *v200 = data;

	return be16_to_cpu(v200->baseComID);
}

static int opal_send_cmd(struct opal_dev *dev)
{
	return dev->send_recv(dev->data, dev->comid, TCG_SECP_01,
			      dev->cmd, IO_BUFFER_LENGTH,
			      true);
}

static int opal_recv_cmd(struct opal_dev *dev)
{
	return dev->send_recv(dev->data, dev->comid, TCG_SECP_01,
			      dev->resp, IO_BUFFER_LENGTH,
			      false);
}

static int opal_recv_check(struct opal_dev *dev)
{
	size_t buflen = IO_BUFFER_LENGTH;
	void *buffer = dev->resp;
	struct opal_header *hdr = buffer;
	int ret;

	do {
		pr_debug("Sent OPAL command: outstanding=%d, minTransfer=%d\n",
			 hdr->cp.outstandingData,
			 hdr->cp.minTransfer);

		if (hdr->cp.outstandingData == 0 ||
		    hdr->cp.minTransfer != 0)
			return 0;

		memset(buffer, 0, buflen);
		ret = opal_recv_cmd(dev);
	} while (!ret);

	return ret;
}

static int opal_send_recv(struct opal_dev *dev, cont_fn *cont)
{
	int ret;

	ret = opal_send_cmd(dev);
	if (ret)
		return ret;
	ret = opal_recv_cmd(dev);
	if (ret)
		return ret;
	ret = opal_recv_check(dev);
	if (ret)
		return ret;
	return cont(dev);
}

static void check_geometry(struct opal_dev *dev, const void *data)
{
	const struct d0_geometry_features *geo = data;

	dev->align = be64_to_cpu(geo->alignment_granularity);
	dev->lowest_lba = be64_to_cpu(geo->lowest_aligned_lba);
	dev->logical_block_size = be32_to_cpu(geo->logical_block_size);
	dev->align_required = geo->reserved01 & 1;
}

static int execute_step(struct opal_dev *dev,
			const struct opal_step *step, size_t stepIndex)
{
	int error = step->fn(dev, step->data);

	if (error) {
		pr_debug("Step %zu (%pS) failed with error %d: %s\n",
			 stepIndex, step->fn, error,
			 opal_error_to_human(error));
	}

	return error;
}

static int execute_steps(struct opal_dev *dev,
			 const struct opal_step *steps, size_t n_steps)
{
	size_t state = 0;
	int error;

	/* first do a discovery0 */
	error = opal_discovery0_step(dev);
	if (error)
		return error;

	for (state = 0; state < n_steps; state++) {
		error = execute_step(dev, &steps[state], state);
		if (error)
			goto out_error;
	}

	return 0;

out_error:
	/*
	 * For each OPAL command the first step in steps starts some sort of
	 * session. If an error occurred in the initial discovery0 or if an
	 * error occurred in the first step (and thus stopping the loop with
	 * state == 0) then there was an error before or during the attempt to
	 * start a session. Therefore we shouldn't attempt to terminate a
	 * session, as one has not yet been created.
	 */
	if (state > 0)
		end_opal_session_error(dev);

	return error;
}

static int opal_discovery0_end(struct opal_dev *dev, void *data)
{
	struct opal_discovery *discv_out = data; /* may be NULL */
	u8 __user *buf_out;
	u64 len_out;
	bool found_com_id = false, supported = true, single_user = false;
	const struct d0_header *hdr = (struct d0_header *)dev->resp;
	const u8 *epos = dev->resp, *cpos = dev->resp;
	u16 comid = 0;
	u32 hlen = be32_to_cpu(hdr->length);

	print_buffer(dev->resp, hlen);
	dev->flags &= OPAL_FL_SUPPORTED;

	if (hlen > IO_BUFFER_LENGTH - sizeof(*hdr)) {
		pr_debug("Discovery length overflows buffer (%zu+%u)/%u\n",
			 sizeof(*hdr), hlen, IO_BUFFER_LENGTH);
		return -EFAULT;
	}

	if (discv_out) {
		buf_out = (u8 __user *)(uintptr_t)discv_out->data;
		len_out = min_t(u64, discv_out->size, hlen);
		if (buf_out && copy_to_user(buf_out, dev->resp, len_out))
			return -EFAULT;

		discv_out->size = hlen; /* actual size of data */
	}

	epos += hlen; /* end of buffer */
	cpos += sizeof(*hdr); /* current position on buffer */

	while (cpos < epos && supported) {
		const struct d0_features *body =
			(const struct d0_features *)cpos;

		switch (be16_to_cpu(body->code)) {
		case FC_TPER:
			supported = check_tper(body->features);
			break;
		case FC_SINGLEUSER:
			single_user = check_sum(body->features);
			if (single_user)
				dev->flags |= OPAL_FL_SUM_SUPPORTED;
			break;
		case FC_GEOMETRY:
			check_geometry(dev, body);
			break;
		case FC_LOCKING:
			if (check_lcksuppt(body->features))
				dev->flags |= OPAL_FL_LOCKING_SUPPORTED;
			if (check_lckenabled(body->features))
				dev->flags |= OPAL_FL_LOCKING_ENABLED;
			if (check_locked(body->features))
				dev->flags |= OPAL_FL_LOCKED;
			if (check_mbrenabled(body->features))
				dev->flags |= OPAL_FL_MBR_ENABLED;
			if (check_mbrdone(body->features))
				dev->flags |= OPAL_FL_MBR_DONE;
			break;
		case FC_ENTERPRISE:
		case FC_DATASTORE:
			/* some ignored properties */
			pr_debug("Found OPAL feature description: %d\n",
				 be16_to_cpu(body->code));
			break;
		case FC_OPALV100:
			comid = get_comid_v100(body->features);
			found_com_id = true;
			break;
		case FC_OPALV200:
			comid = get_comid_v200(body->features);
			found_com_id = true;
			break;
		case 0xbfff ... 0xffff:
			/* vendor specific, just ignore */
			break;
		default:
			pr_debug("OPAL Unknown feature: %d\n",
				 be16_to_cpu(body->code));

		}
		cpos += body->length + 4;
	}

	if (!supported) {
		pr_debug("This device is not Opal enabled. Not Supported!\n");
		return -EOPNOTSUPP;
	}

	if (!single_user)
		pr_debug("Device doesn't support single user mode\n");


	if (!found_com_id) {
		pr_debug("Could not find OPAL comid for device. Returning early\n");
		return -EOPNOTSUPP;
	}

	dev->comid = comid;

	return 0;
}

static int opal_discovery0(struct opal_dev *dev, void *data)
{
	int ret;

	memset(dev->resp, 0, IO_BUFFER_LENGTH);
	dev->comid = OPAL_DISCOVERY_COMID;
	ret = opal_recv_cmd(dev);
	if (ret)
		return ret;

	return opal_discovery0_end(dev, data);
}

static int opal_discovery0_step(struct opal_dev *dev)
{
	const struct opal_step discovery0_step = {
		opal_discovery0, NULL
	};

	return execute_step(dev, &discovery0_step, 0);
}

static size_t remaining_size(struct opal_dev *cmd)
{
	return IO_BUFFER_LENGTH - cmd->pos;
}

static bool can_add(int *err, struct opal_dev *cmd, size_t len)
{
	if (*err)
		return false;

	if (remaining_size(cmd) < len) {
		pr_debug("Error adding %zu bytes: end of buffer.\n", len);
		*err = -ERANGE;
		return false;
	}

	return true;
}

static void add_token_u8(int *err, struct opal_dev *cmd, u8 tok)
{
	if (!can_add(err, cmd, 1))
		return;

	cmd->cmd[cmd->pos++] = tok;
}

static void add_short_atom_header(struct opal_dev *cmd, bool bytestring,
				  bool has_sign, int len)
{
	u8 atom;
	int err = 0;

	atom = SHORT_ATOM_ID;
	atom |= bytestring ? SHORT_ATOM_BYTESTRING : 0;
	atom |= has_sign ? SHORT_ATOM_SIGNED : 0;
	atom |= len & SHORT_ATOM_LEN_MASK;

	add_token_u8(&err, cmd, atom);
}

static void add_medium_atom_header(struct opal_dev *cmd, bool bytestring,
				   bool has_sign, int len)
{
	u8 header0;

	header0 = MEDIUM_ATOM_ID;
	header0 |= bytestring ? MEDIUM_ATOM_BYTESTRING : 0;
	header0 |= has_sign ? MEDIUM_ATOM_SIGNED : 0;
	header0 |= (len >> 8) & MEDIUM_ATOM_LEN_MASK;

	cmd->cmd[cmd->pos++] = header0;
	cmd->cmd[cmd->pos++] = len;
}

static void add_token_u64(int *err, struct opal_dev *cmd, u64 number)
{
	size_t len;
	int msb;

	if (!(number & ~TINY_ATOM_DATA_MASK)) {
		add_token_u8(err, cmd, number);
		return;
	}

	msb = fls64(number);
	len = DIV_ROUND_UP(msb, 8);

	if (!can_add(err, cmd, len + 1)) {
		pr_debug("Error adding u64: end of buffer.\n");
		return;
	}
	add_short_atom_header(cmd, false, false, len);
	while (len--)
		add_token_u8(err, cmd, number >> (len * 8));
}

static u8 *add_bytestring_header(int *err, struct opal_dev *cmd, size_t len)
{
	size_t header_len = 1;
	bool is_short_atom = true;

	if (len & ~SHORT_ATOM_LEN_MASK) {
		header_len = 2;
		is_short_atom = false;
	}

	if (!can_add(err, cmd, header_len + len)) {
		pr_debug("Error adding bytestring: end of buffer.\n");
		return NULL;
	}

	if (is_short_atom)
		add_short_atom_header(cmd, true, false, len);
	else
		add_medium_atom_header(cmd, true, false, len);

	return &cmd->cmd[cmd->pos];
}

static void add_token_bytestring(int *err, struct opal_dev *cmd,
				 const u8 *bytestring, size_t len)
{
	u8 *start;

	start = add_bytestring_header(err, cmd, len);
	if (!start)
		return;
	memcpy(start, bytestring, len);
	cmd->pos += len;
}

static int build_locking_range(u8 *buffer, size_t length, u8 lr)
{
	if (length > OPAL_UID_LENGTH) {
		pr_debug("Can't build locking range. Length OOB\n");
		return -ERANGE;
	}

	memcpy(buffer, opaluid[OPAL_LOCKINGRANGE_GLOBAL], OPAL_UID_LENGTH);

	if (lr == 0)
		return 0;

	buffer[5] = LOCKING_RANGE_NON_GLOBAL;
	buffer[7] = lr;

	return 0;
}

static int build_locking_user(u8 *buffer, size_t length, u8 lr)
{
	if (length > OPAL_UID_LENGTH) {
		pr_debug("Can't build locking range user. Length OOB\n");
		return -ERANGE;
	}

	memcpy(buffer, opaluid[OPAL_USER1_UID], OPAL_UID_LENGTH);

	buffer[7] = lr + 1;

	return 0;
}

static void set_comid(struct opal_dev *cmd, u16 comid)
{
	struct opal_header *hdr = (struct opal_header *)cmd->cmd;

	hdr->cp.extendedComID[0] = comid >> 8;
	hdr->cp.extendedComID[1] = comid;
	hdr->cp.extendedComID[2] = 0;
	hdr->cp.extendedComID[3] = 0;
}

static int cmd_finalize(struct opal_dev *cmd, u32 hsn, u32 tsn)
{
	struct opal_header *hdr;
	int err = 0;

	/*
	 * Close the parameter list opened from cmd_start.
	 * The number of bytes added must be equal to
	 * CMD_FINALIZE_BYTES_NEEDED.
	 */
	add_token_u8(&err, cmd, OPAL_ENDLIST);

	add_token_u8(&err, cmd, OPAL_ENDOFDATA);
	add_token_u8(&err, cmd, OPAL_STARTLIST);
	add_token_u8(&err, cmd, 0);
	add_token_u8(&err, cmd, 0);
	add_token_u8(&err, cmd, 0);
	add_token_u8(&err, cmd, OPAL_ENDLIST);

	if (err) {
		pr_debug("Error finalizing command.\n");
		return -EFAULT;
	}

	hdr = (struct opal_header *) cmd->cmd;

	hdr->pkt.tsn = cpu_to_be32(tsn);
	hdr->pkt.hsn = cpu_to_be32(hsn);

	hdr->subpkt.length = cpu_to_be32(cmd->pos - sizeof(*hdr));
	while (cmd->pos % 4) {
		if (cmd->pos >= IO_BUFFER_LENGTH) {
			pr_debug("Error: Buffer overrun\n");
			return -ERANGE;
		}
		cmd->cmd[cmd->pos++] = 0;
	}
	hdr->pkt.length = cpu_to_be32(cmd->pos - sizeof(hdr->cp) -
				      sizeof(hdr->pkt));
	hdr->cp.length = cpu_to_be32(cmd->pos - sizeof(hdr->cp));

	return 0;
}

static const struct opal_resp_tok *response_get_token(
				const struct parsed_resp *resp,
				int n)
{
	const struct opal_resp_tok *tok;

	if (!resp) {
		pr_debug("Response is NULL\n");
		return ERR_PTR(-EINVAL);
	}

	if (n >= resp->num) {
		pr_debug("Token number doesn't exist: %d, resp: %d\n",
			 n, resp->num);
		return ERR_PTR(-EINVAL);
	}

	tok = &resp->toks[n];
	if (tok->len == 0) {
		pr_debug("Token length must be non-zero\n");
		return ERR_PTR(-EINVAL);
	}

	return tok;
}

static ssize_t response_parse_tiny(struct opal_resp_tok *tok,
				   const u8 *pos)
{
	tok->pos = pos;
	tok->len = 1;
	tok->width = OPAL_WIDTH_TINY;

	if (pos[0] & TINY_ATOM_SIGNED) {
		tok->type = OPAL_DTA_TOKENID_SINT;
	} else {
		tok->type = OPAL_DTA_TOKENID_UINT;
		tok->stored.u = pos[0] & 0x3f;
	}

	return tok->len;
}

static ssize_t response_parse_short(struct opal_resp_tok *tok,
				    const u8 *pos)
{
	tok->pos = pos;
	tok->len = (pos[0] & SHORT_ATOM_LEN_MASK) + 1;
	tok->width = OPAL_WIDTH_SHORT;

	if (pos[0] & SHORT_ATOM_BYTESTRING) {
		tok->type = OPAL_DTA_TOKENID_BYTESTRING;
	} else if (pos[0] & SHORT_ATOM_SIGNED) {
		tok->type = OPAL_DTA_TOKENID_SINT;
	} else {
		u64 u_integer = 0;
		ssize_t i, b = 0;

		tok->type = OPAL_DTA_TOKENID_UINT;
		if (tok->len > 9) {
			pr_debug("uint64 with more than 8 bytes\n");
			return -EINVAL;
		}
		for (i = tok->len - 1; i > 0; i--) {
			u_integer |= ((u64)pos[i] << (8 * b));
			b++;
		}
		tok->stored.u = u_integer;
	}

	return tok->len;
}

static ssize_t response_parse_medium(struct opal_resp_tok *tok,
				     const u8 *pos)
{
	tok->pos = pos;
	tok->len = (((pos[0] & MEDIUM_ATOM_LEN_MASK) << 8) | pos[1]) + 2;
	tok->width = OPAL_WIDTH_MEDIUM;

	if (pos[0] & MEDIUM_ATOM_BYTESTRING)
		tok->type = OPAL_DTA_TOKENID_BYTESTRING;
	else if (pos[0] & MEDIUM_ATOM_SIGNED)
		tok->type = OPAL_DTA_TOKENID_SINT;
	else
		tok->type = OPAL_DTA_TOKENID_UINT;

	return tok->len;
}

static ssize_t response_parse_long(struct opal_resp_tok *tok,
				   const u8 *pos)
{
	tok->pos = pos;
	tok->len = ((pos[1] << 16) | (pos[2] << 8) | pos[3]) + 4;
	tok->width = OPAL_WIDTH_LONG;

	if (pos[0] & LONG_ATOM_BYTESTRING)
		tok->type = OPAL_DTA_TOKENID_BYTESTRING;
	else if (pos[0] & LONG_ATOM_SIGNED)
		tok->type = OPAL_DTA_TOKENID_SINT;
	else
		tok->type = OPAL_DTA_TOKENID_UINT;

	return tok->len;
}

static ssize_t response_parse_token(struct opal_resp_tok *tok,
				    const u8 *pos)
{
	tok->pos = pos;
	tok->len = 1;
	tok->type = OPAL_DTA_TOKENID_TOKEN;
	tok->width = OPAL_WIDTH_TOKEN;

	return tok->len;
}

static int response_parse(const u8 *buf, size_t length,
			  struct parsed_resp *resp)
{
	const struct opal_header *hdr;
	struct opal_resp_tok *iter;
	int num_entries = 0;
	int total;
	ssize_t token_length;
	const u8 *pos;
	u32 clen, plen, slen;

	if (!buf)
		return -EFAULT;

	if (!resp)
		return -EFAULT;

	hdr = (struct opal_header *)buf;
	pos = buf;
	pos += sizeof(*hdr);

	clen = be32_to_cpu(hdr->cp.length);
	plen = be32_to_cpu(hdr->pkt.length);
	slen = be32_to_cpu(hdr->subpkt.length);
	pr_debug("Response size: cp: %u, pkt: %u, subpkt: %u\n",
		 clen, plen, slen);

	if (clen == 0 || plen == 0 || slen == 0 ||
	    slen > IO_BUFFER_LENGTH - sizeof(*hdr)) {
		pr_debug("Bad header length. cp: %u, pkt: %u, subpkt: %u\n",
			 clen, plen, slen);
		print_buffer(pos, sizeof(*hdr));
		return -EINVAL;
	}

	if (pos > buf + length)
		return -EFAULT;

	iter = resp->toks;
	total = slen;
	print_buffer(pos, total);
	while (total > 0) {
		if (pos[0] <= TINY_ATOM_BYTE) /* tiny atom */
			token_length = response_parse_tiny(iter, pos);
		else if (pos[0] <= SHORT_ATOM_BYTE) /* short atom */
			token_length = response_parse_short(iter, pos);
		else if (pos[0] <= MEDIUM_ATOM_BYTE) /* medium atom */
			token_length = response_parse_medium(iter, pos);
		else if (pos[0] <= LONG_ATOM_BYTE) /* long atom */
			token_length = response_parse_long(iter, pos);
		else /* TOKEN */
			token_length = response_parse_token(iter, pos);

		if (token_length < 0)
			return token_length;

		pos += token_length;
		total -= token_length;
		iter++;
		num_entries++;
	}

	resp->num = num_entries;

	return 0;
}

static size_t response_get_string(const struct parsed_resp *resp, int n,
				  const char **store)
{
	u8 skip;
	const struct opal_resp_tok *tok;

	*store = NULL;
	tok = response_get_token(resp, n);
	if (IS_ERR(tok))
		return 0;

	if (tok->type != OPAL_DTA_TOKENID_BYTESTRING) {
		pr_debug("Token is not a byte string!\n");
		return 0;
	}

	switch (tok->width) {
	case OPAL_WIDTH_TINY:
	case OPAL_WIDTH_SHORT:
		skip = 1;
		break;
	case OPAL_WIDTH_MEDIUM:
		skip = 2;
		break;
	case OPAL_WIDTH_LONG:
		skip = 4;
		break;
	default:
		pr_debug("Token has invalid width!\n");
		return 0;
	}

	*store = tok->pos + skip;

	return tok->len - skip;
}

static u64 response_get_u64(const struct parsed_resp *resp, int n)
{
	const struct opal_resp_tok *tok;

	tok = response_get_token(resp, n);
	if (IS_ERR(tok))
		return 0;

	if (tok->type != OPAL_DTA_TOKENID_UINT) {
		pr_debug("Token is not unsigned int: %d\n", tok->type);
		return 0;
	}

	if (tok->width != OPAL_WIDTH_TINY && tok->width != OPAL_WIDTH_SHORT) {
		pr_debug("Atom is not short or tiny: %d\n", tok->width);
		return 0;
	}

	return tok->stored.u;
}

static bool response_token_matches(const struct opal_resp_tok *token, u8 match)
{
	if (IS_ERR(token) ||
	    token->type != OPAL_DTA_TOKENID_TOKEN ||
	    token->pos[0] != match)
		return false;
	return true;
}

static u8 response_status(const struct parsed_resp *resp)
{
	const struct opal_resp_tok *tok;

	tok = response_get_token(resp, 0);
	if (response_token_matches(tok, OPAL_ENDOFSESSION))
		return 0;

	if (resp->num < 5)
		return DTAERROR_NO_METHOD_STATUS;

	tok = response_get_token(resp, resp->num - 5);
	if (!response_token_matches(tok, OPAL_STARTLIST))
		return DTAERROR_NO_METHOD_STATUS;

	tok = response_get_token(resp, resp->num - 1);
	if (!response_token_matches(tok, OPAL_ENDLIST))
		return DTAERROR_NO_METHOD_STATUS;

	return response_get_u64(resp, resp->num - 4);
}

/* Parses and checks for errors */
static int parse_and_check_status(struct opal_dev *dev)
{
	int error;

	print_buffer(dev->cmd, dev->pos);

	error = response_parse(dev->resp, IO_BUFFER_LENGTH, &dev->parsed);
	if (error) {
		pr_debug("Couldn't parse response.\n");
		return error;
	}

	return response_status(&dev->parsed);
}

static void clear_opal_cmd(struct opal_dev *dev)
{
	dev->pos = sizeof(struct opal_header);
	memset(dev->cmd, 0, IO_BUFFER_LENGTH);
}

static int cmd_start(struct opal_dev *dev, const u8 *uid, const u8 *method)
{
	int err = 0;

	clear_opal_cmd(dev);
	set_comid(dev, dev->comid);

	add_token_u8(&err, dev, OPAL_CALL);
	add_token_bytestring(&err, dev, uid, OPAL_UID_LENGTH);
	add_token_bytestring(&err, dev, method, OPAL_METHOD_LENGTH);

	/*
	 * Every method call is followed by its parameters enclosed within
	 * OPAL_STARTLIST and OPAL_ENDLIST tokens. We automatically open the
	 * parameter list here and close it later in cmd_finalize.
	 */
	add_token_u8(&err, dev, OPAL_STARTLIST);

	return err;
}

static int start_opal_session_cont(struct opal_dev *dev)
{
	u32 hsn, tsn;
	int error = 0;

	error = parse_and_check_status(dev);
	if (error)
		return error;

	hsn = response_get_u64(&dev->parsed, 4);
	tsn = response_get_u64(&dev->parsed, 5);

	if (hsn != GENERIC_HOST_SESSION_NUM || tsn < FIRST_TPER_SESSION_NUM) {
		pr_debug("Couldn't authenticate session\n");
		return -EPERM;
	}

	dev->hsn = hsn;
	dev->tsn = tsn;

	return 0;
}

static void add_suspend_info(struct opal_dev *dev,
			     struct opal_suspend_data *sus)
{
	struct opal_suspend_data *iter;

	list_for_each_entry(iter, &dev->unlk_lst, node) {
		if (iter->lr == sus->lr) {
			list_del(&iter->node);
			kfree(iter);
			break;
		}
	}
	list_add_tail(&sus->node, &dev->unlk_lst);
}

static int end_session_cont(struct opal_dev *dev)
{
	dev->hsn = 0;
	dev->tsn = 0;

	return parse_and_check_status(dev);
}

static int finalize_and_send(struct opal_dev *dev, cont_fn cont)
{
	int ret;

	ret = cmd_finalize(dev, dev->hsn, dev->tsn);
	if (ret) {
		pr_debug("Error finalizing command buffer: %d\n", ret);
		return ret;
	}

	print_buffer(dev->cmd, dev->pos);

	return opal_send_recv(dev, cont);
}

static int generic_get_columns(struct opal_dev *dev, const u8 *table,
			       u64 start_column, u64 end_column)
{
	int err;

	err = cmd_start(dev, table, opalmethod[OPAL_GET]);

	add_token_u8(&err, dev, OPAL_STARTLIST);

	add_token_u8(&err, dev, OPAL_STARTNAME);
	add_token_u8(&err, dev, OPAL_STARTCOLUMN);
	add_token_u64(&err, dev, start_column);
	add_token_u8(&err, dev, OPAL_ENDNAME);

	add_token_u8(&err, dev, OPAL_STARTNAME);
	add_token_u8(&err, dev, OPAL_ENDCOLUMN);
	add_token_u64(&err, dev, end_column);
	add_token_u8(&err, dev, OPAL_ENDNAME);

	add_token_u8(&err, dev, OPAL_ENDLIST);

	if (err)
		return err;

	return finalize_and_send(dev, parse_and_check_status);
}

/*
 * request @column from table @table on device @dev. On success, the column
 * data will be available in dev->resp->tok[4]
 */
static int generic_get_column(struct opal_dev *dev, const u8 *table,
			      u64 column)
{
	return generic_get_columns(dev, table, column, column);
}

/*
 * see TCG SAS 5.3.2.3 for a description of the available columns
 *
 * the result is provided in dev->resp->tok[4]
 */
static int generic_get_table_info(struct opal_dev *dev, const u8 *table_uid,
				  u64 column)
{
	u8 uid[OPAL_UID_LENGTH];
	const unsigned int half = OPAL_UID_LENGTH_HALF;

	/* sed-opal UIDs can be split in two halves:
	 *  first:  actual table index
	 *  second: relative index in the table
	 * so we have to get the first half of the OPAL_TABLE_TABLE and use the
	 * first part of the target table as relative index into that table
	 */
	memcpy(uid, opaluid[OPAL_TABLE_TABLE], half);
	memcpy(uid + half, table_uid, half);

	return generic_get_column(dev, uid, column);
}

static int gen_key(struct opal_dev *dev, void *data)
{
	u8 uid[OPAL_UID_LENGTH];
	int err;

	memcpy(uid, dev->prev_data, min(sizeof(uid), dev->prev_d_len));
	kfree(dev->prev_data);
	dev->prev_data = NULL;

	err = cmd_start(dev, uid, opalmethod[OPAL_GENKEY]);

	if (err) {
		pr_debug("Error building gen key command\n");
		return err;

	}

	return finalize_and_send(dev, parse_and_check_status);
}

static int get_active_key_cont(struct opal_dev *dev)
{
	const char *activekey;
	size_t keylen;
	int error = 0;

	error = parse_and_check_status(dev);
	if (error)
		return error;

	keylen = response_get_string(&dev->parsed, 4, &activekey);
	if (!activekey) {
		pr_debug("%s: Couldn't extract the Activekey from the response\n",
			 __func__);
		return OPAL_INVAL_PARAM;
	}

	dev->prev_data = kmemdup(activekey, keylen, GFP_KERNEL);

	if (!dev->prev_data)
		return -ENOMEM;

	dev->prev_d_len = keylen;

	return 0;
}

static int get_active_key(struct opal_dev *dev, void *data)
{
	u8 uid[OPAL_UID_LENGTH];
	int err;
	u8 *lr = data;

	err = build_locking_range(uid, sizeof(uid), *lr);
	if (err)
		return err;

	err = generic_get_column(dev, uid, OPAL_ACTIVEKEY);
	if (err)
		return err;

	return get_active_key_cont(dev);
}

static int generic_table_write_data(struct opal_dev *dev, const u64 data,
				    u64 offset, u64 size, const u8 *uid)
{
	const u8 __user *src = (u8 __user *)(uintptr_t)data;
	u8 *dst;
	u64 len;
	size_t off = 0;
	int err;

	/* do we fit in the available space? */
	err = generic_get_table_info(dev, uid, OPAL_TABLE_ROWS);
	if (err) {
		pr_debug("Couldn't get the table size\n");
		return err;
	}

	len = response_get_u64(&dev->parsed, 4);
	if (size > len || offset > len - size) {
		pr_debug("Does not fit in the table (%llu vs. %llu)\n",
			  offset + size, len);
		return -ENOSPC;
	}

	/* do the actual transmission(s) */
	while (off < size) {
		err = cmd_start(dev, uid, opalmethod[OPAL_SET]);
		add_token_u8(&err, dev, OPAL_STARTNAME);
		add_token_u8(&err, dev, OPAL_WHERE);
		add_token_u64(&err, dev, offset + off);
		add_token_u8(&err, dev, OPAL_ENDNAME);

		add_token_u8(&err, dev, OPAL_STARTNAME);
		add_token_u8(&err, dev, OPAL_VALUES);

		/*
		 * The bytestring header is either 1 or 2 bytes, so assume 2.
		 * There also needs to be enough space to accommodate the
		 * trailing OPAL_ENDNAME (1 byte) and tokens added by
		 * cmd_finalize.
		 */
		len = min(remaining_size(dev) - (2+1+CMD_FINALIZE_BYTES_NEEDED),
			  (size_t)(size - off));
		pr_debug("Write bytes %zu+%llu/%llu\n", off, len, size);

		dst = add_bytestring_header(&err, dev, len);
		if (!dst)
			break;

		if (copy_from_user(dst, src + off, len)) {
			err = -EFAULT;
			break;
		}

		dev->pos += len;

		add_token_u8(&err, dev, OPAL_ENDNAME);
		if (err)
			break;

		err = finalize_and_send(dev, parse_and_check_status);
		if (err)
			break;

		off += len;
	}

	return err;
}

static int generic_lr_enable_disable(struct opal_dev *dev,
				     u8 *uid, bool rle, bool wle,
				     bool rl, bool wl)
{
	int err;

	err = cmd_start(dev, uid, opalmethod[OPAL_SET]);

	add_token_u8(&err, dev, OPAL_STARTNAME);
	add_token_u8(&err, dev, OPAL_VALUES);
	add_token_u8(&err, dev, OPAL_STARTLIST);

	add_token_u8(&err, dev, OPAL_STARTNAME);
	add_token_u8(&err, dev, OPAL_READLOCKENABLED);
	add_token_u8(&err, dev, rle);
	add_token_u8(&err, dev, OPAL_ENDNAME);

	add_token_u8(&err, dev, OPAL_STARTNAME);
	add_token_u8(&err, dev, OPAL_WRITELOCKENABLED);
	add_token_u8(&err, dev, wle);
	add_token_u8(&err, dev, OPAL_ENDNAME);

	add_token_u8(&err, dev, OPAL_STARTNAME);
	add_token_u8(&err, dev, OPAL_READLOCKED);
	add_token_u8(&err, dev, rl);
	add_token_u8(&err, dev, OPAL_ENDNAME);

	add_token_u8(&err, dev, OPAL_STARTNAME);
	add_token_u8(&err, dev, OPAL_WRITELOCKED);
	add_token_u8(&err, dev, wl);
	add_token_u8(&err, dev, OPAL_ENDNAME);

	add_token_u8(&err, dev, OPAL_ENDLIST);
	add_token_u8(&err, dev, OPAL_ENDNAME);

	return err;
}

static inline int enable_global_lr(struct opal_dev *dev, u8 *uid,
				   struct opal_user_lr_setup *setup)
{
	int err;

	err = generic_lr_enable_disable(dev, uid, !!setup->RLE, !!setup->WLE,
					0, 0);
	if (err)
		pr_debug("Failed to create enable global lr command\n");

	return err;
}

static int setup_locking_range(struct opal_dev *dev, void *data)
{
	u8 uid[OPAL_UID_LENGTH];
	struct opal_user_lr_setup *setup = data;
	u8 lr;
	int err;

	lr = setup->session.opal_key.lr;
	err = build_locking_range(uid, sizeof(uid), lr);
	if (err)
		return err;

	if (lr == 0)
		err = enable_global_lr(dev, uid, setup);
	else {
		err = cmd_start(dev, uid, opalmethod[OPAL_SET]);

		add_token_u8(&err, dev, OPAL_STARTNAME);
		add_token_u8(&err, dev, OPAL_VALUES);
		add_token_u8(&err, dev, OPAL_STARTLIST);

		add_token_u8(&err, dev, OPAL_STARTNAME);
		add_token_u8(&err, dev, OPAL_RANGESTART);
		add_token_u64(&err, dev, setup->range_start);
		add_token_u8(&err, dev, OPAL_ENDNAME);

		add_token_u8(&err, dev, OPAL_STARTNAME);
		add_token_u8(&err, dev, OPAL_RANGELENGTH);
		add_token_u64(&err, dev, setup->range_length);
		add_token_u8(&err, dev, OPAL_ENDNAME);

		add_token_u8(&err, dev, OPAL_STARTNAME);
		add_token_u8(&err, dev, OPAL_READLOCKENABLED);
		add_token_u64(&err, dev, !!setup->RLE);
		add_token_u8(&err, dev, OPAL_ENDNAME);

		add_token_u8(&err, dev, OPAL_STARTNAME);
		add_token_u8(&err, dev, OPAL_WRITELOCKENABLED);
		add_token_u64(&err, dev, !!setup->WLE);
		add_token_u8(&err, dev, OPAL_ENDNAME);

		add_token_u8(&err, dev, OPAL_ENDLIST);
		add_token_u8(&err, dev, OPAL_ENDNAME);
	}
	if (err) {
		pr_debug("Error building Setup Locking range command.\n");
		return err;
	}

	return finalize_and_send(dev, parse_and_check_status);
}

static int response_get_column(const struct parsed_resp *resp,
			       int *iter,
			       u8 column,
			       u64 *value)
{
	const struct opal_resp_tok *tok;
	int n = *iter;
	u64 val;

	tok = response_get_token(resp, n);
	if (IS_ERR(tok))
		return PTR_ERR(tok);

	if (!response_token_matches(tok, OPAL_STARTNAME)) {
		pr_debug("Unexpected response token type %d.\n", n);
		return OPAL_INVAL_PARAM;
	}
	n++;

	if (response_get_u64(resp, n) != column) {
		pr_debug("Token %d does not match expected column %u.\n",
			 n, column);
		return OPAL_INVAL_PARAM;
	}
	n++;

	val = response_get_u64(resp, n);
	n++;

	tok = response_get_token(resp, n);
	if (IS_ERR(tok))
		return PTR_ERR(tok);

	if (!response_token_matches(tok, OPAL_ENDNAME)) {
		pr_debug("Unexpected response token type %d.\n", n);
		return OPAL_INVAL_PARAM;
	}
	n++;

	*value = val;
	*iter = n;

	return 0;
}

static int locking_range_status(struct opal_dev *dev, void *data)
{
	u8 lr_buffer[OPAL_UID_LENGTH];
	u64 resp;
	bool rlocked, wlocked;
	int err, tok_n = 2;
	struct opal_lr_status *lrst = data;

	err = build_locking_range(lr_buffer, sizeof(lr_buffer),
				  lrst->session.opal_key.lr);
	if (err)
		return err;

	err = generic_get_columns(dev, lr_buffer, OPAL_RANGESTART,
				  OPAL_WRITELOCKED);
	if (err) {
		pr_debug("Couldn't get lr %u table columns %d to %d.\n",
			 lrst->session.opal_key.lr, OPAL_RANGESTART,
			 OPAL_WRITELOCKED);
		return err;
	}

	/* range start */
	err = response_get_column(&dev->parsed, &tok_n, OPAL_RANGESTART,
				  &lrst->range_start);
	if (err)
		return err;

	/* range length */
	err = response_get_column(&dev->parsed, &tok_n, OPAL_RANGELENGTH,
				  &lrst->range_length);
	if (err)
		return err;

	/* RLE */
	err = response_get_column(&dev->parsed, &tok_n, OPAL_READLOCKENABLED,
				  &resp);
	if (err)
		return err;

	lrst->RLE = !!resp;

	/* WLE */
	err = response_get_column(&dev->parsed, &tok_n, OPAL_WRITELOCKENABLED,
				  &resp);
	if (err)
		return err;

	lrst->WLE = !!resp;

	/* read locked */
	err = response_get_column(&dev->parsed, &tok_n, OPAL_READLOCKED, &resp);
	if (err)
		return err;

	rlocked = !!resp;

	/* write locked */
	err = response_get_column(&dev->parsed, &tok_n, OPAL_WRITELOCKED, &resp);
	if (err)
		return err;

	wlocked = !!resp;

	/* opal_lock_state can not map 'read locked' only state. */
	lrst->l_state = OPAL_RW;
	if (rlocked && wlocked)
		lrst->l_state = OPAL_LK;
	else if (wlocked)
		lrst->l_state = OPAL_RO;
	else if (rlocked) {
		pr_debug("Can not report read locked only state.\n");
		return -EINVAL;
	}

	return 0;
}

static int start_generic_opal_session(struct opal_dev *dev,
				      enum opal_uid auth,
				      enum opal_uid sp_type,
				      const char *key,
				      u8 key_len)
{
	u32 hsn;
	int err;

	if (key == NULL && auth != OPAL_ANYBODY_UID)
		return OPAL_INVAL_PARAM;

	hsn = GENERIC_HOST_SESSION_NUM;
	err = cmd_start(dev, opaluid[OPAL_SMUID_UID],
			opalmethod[OPAL_STARTSESSION]);

	add_token_u64(&err, dev, hsn);
	add_token_bytestring(&err, dev, opaluid[sp_type], OPAL_UID_LENGTH);
	add_token_u8(&err, dev, 1);

	switch (auth) {
	case OPAL_ANYBODY_UID:
		break;
	case OPAL_ADMIN1_UID:
	case OPAL_SID_UID:
	case OPAL_PSID_UID:
		add_token_u8(&err, dev, OPAL_STARTNAME);
		add_token_u8(&err, dev, 0); /* HostChallenge */
		add_token_bytestring(&err, dev, key, key_len);
		add_token_u8(&err, dev, OPAL_ENDNAME);
		add_token_u8(&err, dev, OPAL_STARTNAME);
		add_token_u8(&err, dev, 3); /* HostSignAuth */
		add_token_bytestring(&err, dev, opaluid[auth],
				     OPAL_UID_LENGTH);
		add_token_u8(&err, dev, OPAL_ENDNAME);
		break;
	default:
		pr_debug("Cannot start Admin SP session with auth %d\n", auth);
		return OPAL_INVAL_PARAM;
	}

	if (err) {
		pr_debug("Error building start adminsp session command.\n");
		return err;
	}

	return finalize_and_send(dev, start_opal_session_cont);
}

static int start_anybodyASP_opal_session(struct opal_dev *dev, void *data)
{
	return start_generic_opal_session(dev, OPAL_ANYBODY_UID,
					  OPAL_ADMINSP_UID, NULL, 0);
}

static int start_SIDASP_opal_session(struct opal_dev *dev, void *data)
{
	int ret;
	const u8 *key = dev->prev_data;

	if (!key) {
		const struct opal_key *okey = data;

		ret = start_generic_opal_session(dev, OPAL_SID_UID,
						 OPAL_ADMINSP_UID,
						 okey->key,
						 okey->key_len);
	} else {
		ret = start_generic_opal_session(dev, OPAL_SID_UID,
						 OPAL_ADMINSP_UID,
						 key, dev->prev_d_len);
		kfree(key);
		dev->prev_data = NULL;
	}

	return ret;
}

static int start_admin1LSP_opal_session(struct opal_dev *dev, void *data)
{
	struct opal_key *key = data;

	return start_generic_opal_session(dev, OPAL_ADMIN1_UID,
					  OPAL_LOCKINGSP_UID,
					  key->key, key->key_len);
}

static int start_PSID_opal_session(struct opal_dev *dev, void *data)
{
	const struct opal_key *okey = data;

	return start_generic_opal_session(dev, OPAL_PSID_UID,
					  OPAL_ADMINSP_UID,
					  okey->key,
					  okey->key_len);
}

static int start_auth_opal_session(struct opal_dev *dev, void *data)
{
	struct opal_session_info *session = data;
	u8 lk_ul_user[OPAL_UID_LENGTH];
	size_t keylen = session->opal_key.key_len;
	int err = 0;

	u8 *key = session->opal_key.key;
	u32 hsn = GENERIC_HOST_SESSION_NUM;

	if (session->sum)
		err = build_locking_user(lk_ul_user, sizeof(lk_ul_user),
					 session->opal_key.lr);
	else if (session->who != OPAL_ADMIN1 && !session->sum)
		err = build_locking_user(lk_ul_user, sizeof(lk_ul_user),
					 session->who - 1);
	else
		memcpy(lk_ul_user, opaluid[OPAL_ADMIN1_UID], OPAL_UID_LENGTH);

	if (err)
		return err;

	err = cmd_start(dev, opaluid[OPAL_SMUID_UID],
			opalmethod[OPAL_STARTSESSION]);

	add_token_u64(&err, dev, hsn);
	add_token_bytestring(&err, dev, opaluid[OPAL_LOCKINGSP_UID],
			     OPAL_UID_LENGTH);
	add_token_u8(&err, dev, 1);
	add_token_u8(&err, dev, OPAL_STARTNAME);
	add_token_u8(&err, dev, 0);
	add_token_bytestring(&err, dev, key, keylen);
	add_token_u8(&err, dev, OPAL_ENDNAME);
	add_token_u8(&err, dev, OPAL_STARTNAME);
	add_token_u8(&err, dev, 3);
	add_token_bytestring(&err, dev, lk_ul_user, OPAL_UID_LENGTH);
	add_token_u8(&err, dev, OPAL_ENDNAME);

	if (err) {
		pr_debug("Error building STARTSESSION command.\n");
		return err;
	}

	return finalize_and_send(dev, start_opal_session_cont);
}

static int revert_tper(struct opal_dev *dev, void *data)
{
	int err;

	err = cmd_start(dev, opaluid[OPAL_ADMINSP_UID],
			opalmethod[OPAL_REVERT]);
	if (err) {
		pr_debug("Error building REVERT TPER command.\n");
		return err;
	}

	return finalize_and_send(dev, parse_and_check_status);
}

static int internal_activate_user(struct opal_dev *dev, void *data)
{
	struct opal_session_info *session = data;
	u8 uid[OPAL_UID_LENGTH];
	int err;

	memcpy(uid, opaluid[OPAL_USER1_UID], OPAL_UID_LENGTH);
	uid[7] = session->who;

	err = cmd_start(dev, uid, opalmethod[OPAL_SET]);
	add_token_u8(&err, dev, OPAL_STARTNAME);
	add_token_u8(&err, dev, OPAL_VALUES);
	add_token_u8(&err, dev, OPAL_STARTLIST);
	add_token_u8(&err, dev, OPAL_STARTNAME);
	add_token_u8(&err, dev, 5); /* Enabled */
	add_token_u8(&err, dev, OPAL_TRUE);
	add_token_u8(&err, dev, OPAL_ENDNAME);
	add_token_u8(&err, dev, OPAL_ENDLIST);
	add_token_u8(&err, dev, OPAL_ENDNAME);

	if (err) {
		pr_debug("Error building Activate UserN command.\n");
		return err;
	}

	return finalize_and_send(dev, parse_and_check_status);
}

static int revert_lsp(struct opal_dev *dev, void *data)
{
	struct opal_revert_lsp *rev = data;
	int err;

	err = cmd_start(dev, opaluid[OPAL_THISSP_UID],
			opalmethod[OPAL_REVERTSP]);
	add_token_u8(&err, dev, OPAL_STARTNAME);
	add_token_u64(&err, dev, OPAL_KEEP_GLOBAL_RANGE_KEY);
	add_token_u8(&err, dev, (rev->options & OPAL_PRESERVE) ?
			OPAL_TRUE : OPAL_FALSE);
	add_token_u8(&err, dev, OPAL_ENDNAME);
	if (err) {
		pr_debug("Error building REVERT SP command.\n");
		return err;
	}

	return finalize_and_send(dev, parse_and_check_status);
}

static int erase_locking_range(struct opal_dev *dev, void *data)
{
	struct opal_session_info *session = data;
	u8 uid[OPAL_UID_LENGTH];
	int err;

	if (build_locking_range(uid, sizeof(uid), session->opal_key.lr) < 0)
		return -ERANGE;

	err = cmd_start(dev, uid, opalmethod[OPAL_ERASE]);

	if (err) {
		pr_debug("Error building Erase Locking Range Command.\n");
		return err;
	}

	return finalize_and_send(dev, parse_and_check_status);
}

static int set_mbr_done(struct opal_dev *dev, void *data)
{
	u8 *mbr_done_tf = data;
	int err;

	err = cmd_start(dev, opaluid[OPAL_MBRCONTROL],
			opalmethod[OPAL_SET]);

	add_token_u8(&err, dev, OPAL_STARTNAME);
	add_token_u8(&err, dev, OPAL_VALUES);
	add_token_u8(&err, dev, OPAL_STARTLIST);
	add_token_u8(&err, dev, OPAL_STARTNAME);
	add_token_u8(&err, dev, OPAL_MBRDONE);
	add_token_u8(&err, dev, *mbr_done_tf); /* Done T or F */
	add_token_u8(&err, dev, OPAL_ENDNAME);
	add_token_u8(&err, dev, OPAL_ENDLIST);
	add_token_u8(&err, dev, OPAL_ENDNAME);

	if (err) {
		pr_debug("Error Building set MBR Done command\n");
		return err;
	}

	return finalize_and_send(dev, parse_and_check_status);
}

static int set_mbr_enable_disable(struct opal_dev *dev, void *data)
{
	u8 *mbr_en_dis = data;
	int err;

	err = cmd_start(dev, opaluid[OPAL_MBRCONTROL],
			opalmethod[OPAL_SET]);

	add_token_u8(&err, dev, OPAL_STARTNAME);
	add_token_u8(&err, dev, OPAL_VALUES);
	add_token_u8(&err, dev, OPAL_STARTLIST);
	add_token_u8(&err, dev, OPAL_STARTNAME);
	add_token_u8(&err, dev, OPAL_MBRENABLE);
	add_token_u8(&err, dev, *mbr_en_dis);
	add_token_u8(&err, dev, OPAL_ENDNAME);
	add_token_u8(&err, dev, OPAL_ENDLIST);
	add_token_u8(&err, dev, OPAL_ENDNAME);

	if (err) {
		pr_debug("Error Building set MBR done command\n");
		return err;
	}

	return finalize_and_send(dev, parse_and_check_status);
}

static int write_shadow_mbr(struct opal_dev *dev, void *data)
{
	struct opal_shadow_mbr *shadow = data;

	return generic_table_write_data(dev, shadow->data, shadow->offset,
					shadow->size, opaluid[OPAL_MBR]);
}

static int generic_pw_cmd(u8 *key, size_t key_len, u8 *cpin_uid,
			  struct opal_dev *dev)
{
	int err;

	err = cmd_start(dev, cpin_uid, opalmethod[OPAL_SET]);

	add_token_u8(&err, dev, OPAL_STARTNAME);
	add_token_u8(&err, dev, OPAL_VALUES);
	add_token_u8(&err, dev, OPAL_STARTLIST);
	add_token_u8(&err, dev, OPAL_STARTNAME);
	add_token_u8(&err, dev, OPAL_PIN);
	add_token_bytestring(&err, dev, key, key_len);
	add_token_u8(&err, dev, OPAL_ENDNAME);
	add_token_u8(&err, dev, OPAL_ENDLIST);
	add_token_u8(&err, dev, OPAL_ENDNAME);

	return err;
}

static int set_new_pw(struct opal_dev *dev, void *data)
{
	u8 cpin_uid[OPAL_UID_LENGTH];
	struct opal_session_info *usr = data;

	memcpy(cpin_uid, opaluid[OPAL_C_PIN_ADMIN1], OPAL_UID_LENGTH);

	if (usr->who != OPAL_ADMIN1) {
		cpin_uid[5] = 0x03;
		if (usr->sum)
			cpin_uid[7] = usr->opal_key.lr + 1;
		else
			cpin_uid[7] = usr->who;
	}

	if (generic_pw_cmd(usr->opal_key.key, usr->opal_key.key_len,
			   cpin_uid, dev)) {
		pr_debug("Error building set password command.\n");
		return -ERANGE;
	}

	return finalize_and_send(dev, parse_and_check_status);
}

static int set_sid_cpin_pin(struct opal_dev *dev, void *data)
{
	u8 cpin_uid[OPAL_UID_LENGTH];
	struct opal_key *key = data;

	memcpy(cpin_uid, opaluid[OPAL_C_PIN_SID], OPAL_UID_LENGTH);

	if (generic_pw_cmd(key->key, key->key_len, cpin_uid, dev)) {
		pr_debug("Error building Set SID cpin\n");
		return -ERANGE;
	}
	return finalize_and_send(dev, parse_and_check_status);
}

static void add_authority_object_ref(int *err,
				     struct opal_dev *dev,
				     const u8 *uid,
				     size_t uid_len)
{
	add_token_u8(err, dev, OPAL_STARTNAME);
	add_token_bytestring(err, dev,
			     opaluid[OPAL_HALF_UID_AUTHORITY_OBJ_REF],
			     OPAL_UID_LENGTH/2);
	add_token_bytestring(err, dev, uid, uid_len);
	add_token_u8(err, dev, OPAL_ENDNAME);
}

static void add_boolean_object_ref(int *err,
				   struct opal_dev *dev,
				   u8 boolean_op)
{
	add_token_u8(err, dev, OPAL_STARTNAME);
	add_token_bytestring(err, dev, opaluid[OPAL_HALF_UID_BOOLEAN_ACE],
			     OPAL_UID_LENGTH/2);
	add_token_u8(err, dev, boolean_op);
	add_token_u8(err, dev, OPAL_ENDNAME);
}

static int set_lr_boolean_ace(struct opal_dev *dev,
			      unsigned int opal_uid,
			      u8 lr,
			      const u8 *users,
			      size_t users_len)
{
	u8 lr_buffer[OPAL_UID_LENGTH];
	u8 user_uid[OPAL_UID_LENGTH];
	u8 u;
	int err;

	memcpy(lr_buffer, opaluid[opal_uid], OPAL_UID_LENGTH);
	lr_buffer[7] = lr;

	err = cmd_start(dev, lr_buffer, opalmethod[OPAL_SET]);

	add_token_u8(&err, dev, OPAL_STARTNAME);
	add_token_u8(&err, dev, OPAL_VALUES);

	add_token_u8(&err, dev, OPAL_STARTLIST);
	add_token_u8(&err, dev, OPAL_STARTNAME);
	add_token_u8(&err, dev, 3);

	add_token_u8(&err, dev, OPAL_STARTLIST);

	for (u = 0; u < users_len; u++) {
		if (users[u] == OPAL_ADMIN1)
			memcpy(user_uid, opaluid[OPAL_ADMIN1_UID],
			       OPAL_UID_LENGTH);
		else {
			memcpy(user_uid, opaluid[OPAL_USER1_UID],
			       OPAL_UID_LENGTH);
			user_uid[7] = users[u];
		}

		add_authority_object_ref(&err, dev, user_uid, sizeof(user_uid));

		/*
		 * Add boolean operator in postfix only with
		 * two or more authorities being added in ACE
		 * expresion.
		 * */
		if (u > 0)
			add_boolean_object_ref(&err, dev, OPAL_BOOLEAN_OR);
	}

	add_token_u8(&err, dev, OPAL_ENDLIST);
	add_token_u8(&err, dev, OPAL_ENDNAME);
	add_token_u8(&err, dev, OPAL_ENDLIST);
	add_token_u8(&err, dev, OPAL_ENDNAME);

	return err;
}

static int add_user_to_lr(struct opal_dev *dev, void *data)
{
	int err;
	struct opal_lock_unlock *lkul = data;
	const u8 users[] = {
		lkul->session.who
	};

	err = set_lr_boolean_ace(dev,
				 lkul->l_state == OPAL_RW ?
					OPAL_LOCKINGRANGE_ACE_WRLOCKED :
					OPAL_LOCKINGRANGE_ACE_RDLOCKED,
				 lkul->session.opal_key.lr, users,
				 ARRAY_SIZE(users));
	if (err) {
		pr_debug("Error building add user to locking range command.\n");
		return err;
	}

	return finalize_and_send(dev, parse_and_check_status);
}

static int add_user_to_lr_ace(struct opal_dev *dev, void *data)
{
	int err;
	struct opal_lock_unlock *lkul = data;
	const u8 users[] = {
		OPAL_ADMIN1,
		lkul->session.who
	};

	err = set_lr_boolean_ace(dev, OPAL_LOCKINGRANGE_ACE_START_TO_KEY,
				 lkul->session.opal_key.lr, users,
				 ARRAY_SIZE(users));

	if (err) {
		pr_debug("Error building add user to locking ranges ACEs.\n");
		return err;
	}

	return finalize_and_send(dev, parse_and_check_status);
}

static int lock_unlock_locking_range(struct opal_dev *dev, void *data)
{
	u8 lr_buffer[OPAL_UID_LENGTH];
	struct opal_lock_unlock *lkul = data;
	u8 read_locked = 1, write_locked = 1;
	int err = 0;

	if (build_locking_range(lr_buffer, sizeof(lr_buffer),
				lkul->session.opal_key.lr) < 0)
		return -ERANGE;

	switch (lkul->l_state) {
	case OPAL_RO:
		read_locked = 0;
		write_locked = 1;
		break;
	case OPAL_RW:
		read_locked = 0;
		write_locked = 0;
		break;
	case OPAL_LK:
		/* vars are initialized to locked */
		break;
	default:
		pr_debug("Tried to set an invalid locking state... returning to uland\n");
		return OPAL_INVAL_PARAM;
	}

	err = cmd_start(dev, lr_buffer, opalmethod[OPAL_SET]);

	add_token_u8(&err, dev, OPAL_STARTNAME);
	add_token_u8(&err, dev, OPAL_VALUES);
	add_token_u8(&err, dev, OPAL_STARTLIST);

	add_token_u8(&err, dev, OPAL_STARTNAME);
	add_token_u8(&err, dev, OPAL_READLOCKED);
	add_token_u8(&err, dev, read_locked);
	add_token_u8(&err, dev, OPAL_ENDNAME);

	add_token_u8(&err, dev, OPAL_STARTNAME);
	add_token_u8(&err, dev, OPAL_WRITELOCKED);
	add_token_u8(&err, dev, write_locked);
	add_token_u8(&err, dev, OPAL_ENDNAME);

	add_token_u8(&err, dev, OPAL_ENDLIST);
	add_token_u8(&err, dev, OPAL_ENDNAME);

	if (err) {
		pr_debug("Error building SET command.\n");
		return err;
	}

	return finalize_and_send(dev, parse_and_check_status);
}


static int lock_unlock_locking_range_sum(struct opal_dev *dev, void *data)
{
	u8 lr_buffer[OPAL_UID_LENGTH];
	u8 read_locked = 1, write_locked = 1;
	struct opal_lock_unlock *lkul = data;
	int ret;

	clear_opal_cmd(dev);
	set_comid(dev, dev->comid);

	if (build_locking_range(lr_buffer, sizeof(lr_buffer),
				lkul->session.opal_key.lr) < 0)
		return -ERANGE;

	switch (lkul->l_state) {
	case OPAL_RO:
		read_locked = 0;
		write_locked = 1;
		break;
	case OPAL_RW:
		read_locked = 0;
		write_locked = 0;
		break;
	case OPAL_LK:
		/* vars are initialized to locked */
		break;
	default:
		pr_debug("Tried to set an invalid locking state.\n");
		return OPAL_INVAL_PARAM;
	}
	ret = generic_lr_enable_disable(dev, lr_buffer, 1, 1,
					read_locked, write_locked);

	if (ret < 0) {
		pr_debug("Error building SET command.\n");
		return ret;
	}

	return finalize_and_send(dev, parse_and_check_status);
}

static int activate_lsp(struct opal_dev *dev, void *data)
{
	struct opal_lr_act *opal_act = data;
	u8 user_lr[OPAL_UID_LENGTH];
	int err, i;

	err = cmd_start(dev, opaluid[OPAL_LOCKINGSP_UID],
			opalmethod[OPAL_ACTIVATE]);

	if (opal_act->sum) {
		err = build_locking_range(user_lr, sizeof(user_lr),
					  opal_act->lr[0]);
		if (err)
			return err;

		add_token_u8(&err, dev, OPAL_STARTNAME);
		add_token_u64(&err, dev, OPAL_SUM_SET_LIST);

		add_token_u8(&err, dev, OPAL_STARTLIST);
		add_token_bytestring(&err, dev, user_lr, OPAL_UID_LENGTH);
		for (i = 1; i < opal_act->num_lrs; i++) {
			user_lr[7] = opal_act->lr[i];
			add_token_bytestring(&err, dev, user_lr, OPAL_UID_LENGTH);
		}
		add_token_u8(&err, dev, OPAL_ENDLIST);
		add_token_u8(&err, dev, OPAL_ENDNAME);
	}

	if (err) {
		pr_debug("Error building Activate LockingSP command.\n");
		return err;
	}

	return finalize_and_send(dev, parse_and_check_status);
}

/* Determine if we're in the Manufactured Inactive or Active state */
static int get_lsp_lifecycle(struct opal_dev *dev, void *data)
{
	u8 lc_status;
	int err;

	err = generic_get_column(dev, opaluid[OPAL_LOCKINGSP_UID],
				 OPAL_LIFECYCLE);
	if (err)
		return err;

	lc_status = response_get_u64(&dev->parsed, 4);
	/* 0x08 is Manufactured Inactive */
	/* 0x09 is Manufactured */
	if (lc_status != OPAL_MANUFACTURED_INACTIVE) {
		pr_debug("Couldn't determine the status of the Lifecycle state\n");
		return -ENODEV;
	}

	return 0;
}

static int get_msid_cpin_pin(struct opal_dev *dev, void *data)
{
	const char *msid_pin;
	size_t strlen;
	int err;

	err = generic_get_column(dev, opaluid[OPAL_C_PIN_MSID], OPAL_PIN);
	if (err)
		return err;

	strlen = response_get_string(&dev->parsed, 4, &msid_pin);
	if (!msid_pin) {
		pr_debug("Couldn't extract MSID_CPIN from response\n");
		return OPAL_INVAL_PARAM;
	}

	dev->prev_data = kmemdup(msid_pin, strlen, GFP_KERNEL);
	if (!dev->prev_data)
		return -ENOMEM;

	dev->prev_d_len = strlen;

	return 0;
}

static int write_table_data(struct opal_dev *dev, void *data)
{
	struct opal_read_write_table *write_tbl = data;

	return generic_table_write_data(dev, write_tbl->data, write_tbl->offset,
					write_tbl->size, write_tbl->table_uid);
}

static int read_table_data_cont(struct opal_dev *dev)
{
	int err;
	const char *data_read;

	err = parse_and_check_status(dev);
	if (err)
		return err;

	dev->prev_d_len = response_get_string(&dev->parsed, 1, &data_read);
	dev->prev_data = (void *)data_read;
	if (!dev->prev_data) {
		pr_debug("%s: Couldn't read data from the table.\n", __func__);
		return OPAL_INVAL_PARAM;
	}

	return 0;
}

/*
 * IO_BUFFER_LENGTH = 2048
 * sizeof(header) = 56
 * No. of Token Bytes in the Response = 11
 * MAX size of data that can be carried in response buffer
 * at a time is : 2048 - (56 + 11) = 1981 = 0x7BD.
 */
#define OPAL_MAX_READ_TABLE (0x7BD)

static int read_table_data(struct opal_dev *dev, void *data)
{
	struct opal_read_write_table *read_tbl = data;
	int err;
	size_t off = 0, max_read_size = OPAL_MAX_READ_TABLE;
	u64 table_len, len;
	u64 offset = read_tbl->offset, read_size = read_tbl->size - 1;
	u8 __user *dst;

	err = generic_get_table_info(dev, read_tbl->table_uid, OPAL_TABLE_ROWS);
	if (err) {
		pr_debug("Couldn't get the table size\n");
		return err;
	}

	table_len = response_get_u64(&dev->parsed, 4);

	/* Check if the user is trying to read from the table limits */
	if (read_size > table_len || offset > table_len - read_size) {
		pr_debug("Read size exceeds the Table size limits (%llu vs. %llu)\n",
			  offset + read_size, table_len);
		return -EINVAL;
	}

	while (off < read_size) {
		err = cmd_start(dev, read_tbl->table_uid, opalmethod[OPAL_GET]);

		add_token_u8(&err, dev, OPAL_STARTLIST);
		add_token_u8(&err, dev, OPAL_STARTNAME);
		add_token_u8(&err, dev, OPAL_STARTROW);
		add_token_u64(&err, dev, offset + off); /* start row value */
		add_token_u8(&err, dev, OPAL_ENDNAME);

		add_token_u8(&err, dev, OPAL_STARTNAME);
		add_token_u8(&err, dev, OPAL_ENDROW);

		len = min(max_read_size, (size_t)(read_size - off));
		add_token_u64(&err, dev, offset + off + len); /* end row value
							       */
		add_token_u8(&err, dev, OPAL_ENDNAME);
		add_token_u8(&err, dev, OPAL_ENDLIST);

		if (err) {
			pr_debug("Error building read table data command.\n");
			break;
		}

		err = finalize_and_send(dev, read_table_data_cont);
		if (err)
			break;

		/* len+1: This includes the NULL terminator at the end*/
		if (dev->prev_d_len > len + 1) {
			err = -EOVERFLOW;
			break;
		}

		dst = (u8 __user *)(uintptr_t)read_tbl->data;
		if (copy_to_user(dst + off, dev->prev_data, dev->prev_d_len)) {
			pr_debug("Error copying data to userspace\n");
			err = -EFAULT;
			break;
		}
		dev->prev_data = NULL;

		off += len;
	}

	return err;
}

static int end_opal_session(struct opal_dev *dev, void *data)
{
	int err = 0;

	clear_opal_cmd(dev);
	set_comid(dev, dev->comid);
	add_token_u8(&err, dev, OPAL_ENDOFSESSION);

	if (err < 0)
		return err;

	return finalize_and_send(dev, end_session_cont);
}

static int end_opal_session_error(struct opal_dev *dev)
{
	const struct opal_step error_end_session = {
		end_opal_session,
	};

	return execute_step(dev, &error_end_session, 0);
}

static inline void setup_opal_dev(struct opal_dev *dev)
{
	dev->tsn = 0;
	dev->hsn = 0;
	dev->prev_data = NULL;
}

static int check_opal_support(struct opal_dev *dev)
{
	int ret;

	mutex_lock(&dev->dev_lock);
	setup_opal_dev(dev);
	ret = opal_discovery0_step(dev);
	if (!ret)
		dev->flags |= OPAL_FL_SUPPORTED;
	mutex_unlock(&dev->dev_lock);

	return ret;
}

static void clean_opal_dev(struct opal_dev *dev)
{

	struct opal_suspend_data *suspend, *next;

	mutex_lock(&dev->dev_lock);
	list_for_each_entry_safe(suspend, next, &dev->unlk_lst, node) {
		list_del(&suspend->node);
		kfree(suspend);
	}
	mutex_unlock(&dev->dev_lock);
}

void free_opal_dev(struct opal_dev *dev)
{
	if (!dev)
		return;

	clean_opal_dev(dev);
	kfree(dev->resp);
	kfree(dev->cmd);
	kfree(dev);
}
EXPORT_SYMBOL(free_opal_dev);

struct opal_dev *init_opal_dev(void *data, sec_send_recv *send_recv)
{
	struct opal_dev *dev;

	dev = kmalloc(sizeof(*dev), GFP_KERNEL);
	if (!dev)
		return NULL;

	/*
	 * Presumably DMA-able buffers must be cache-aligned. Kmalloc makes
	 * sure the allocated buffer is DMA-safe in that regard.
	 */
	dev->cmd = kmalloc(IO_BUFFER_LENGTH, GFP_KERNEL);
	if (!dev->cmd)
		goto err_free_dev;

	dev->resp = kmalloc(IO_BUFFER_LENGTH, GFP_KERNEL);
	if (!dev->resp)
		goto err_free_cmd;

	INIT_LIST_HEAD(&dev->unlk_lst);
	mutex_init(&dev->dev_lock);
	dev->flags = 0;
	dev->data = data;
	dev->send_recv = send_recv;
	if (check_opal_support(dev) != 0) {
		pr_debug("Opal is not supported on this device\n");
		goto err_free_resp;
	}

	return dev;

err_free_resp:
	kfree(dev->resp);

err_free_cmd:
	kfree(dev->cmd);

err_free_dev:
	kfree(dev);

	return NULL;
}
EXPORT_SYMBOL(init_opal_dev);

static int opal_secure_erase_locking_range(struct opal_dev *dev,
					   struct opal_session_info *opal_session)
{
	const struct opal_step erase_steps[] = {
		{ start_auth_opal_session, opal_session },
		{ get_active_key, &opal_session->opal_key.lr },
		{ gen_key, },
		{ end_opal_session, }
	};
	int ret;

	ret = opal_get_key(dev, &opal_session->opal_key);
	if (ret)
		return ret;
	mutex_lock(&dev->dev_lock);
	setup_opal_dev(dev);
	ret = execute_steps(dev, erase_steps, ARRAY_SIZE(erase_steps));
	mutex_unlock(&dev->dev_lock);

	return ret;
}

static int opal_get_discv(struct opal_dev *dev, struct opal_discovery *discv)
{
	const struct opal_step discovery0_step = {
		opal_discovery0, discv
	};
	int ret = 0;

	mutex_lock(&dev->dev_lock);
	setup_opal_dev(dev);
	ret = execute_step(dev, &discovery0_step, 0);
	mutex_unlock(&dev->dev_lock);
	if (ret)
		return ret;
	return discv->size; /* modified to actual length of data */
}

static int opal_revertlsp(struct opal_dev *dev, struct opal_revert_lsp *rev)
{
	/* controller will terminate session */
	const struct opal_step steps[] = {
		{ start_admin1LSP_opal_session, &rev->key },
		{ revert_lsp, rev }
	};
	int ret;

	ret = opal_get_key(dev, &rev->key);
	if (ret)
		return ret;
	mutex_lock(&dev->dev_lock);
	setup_opal_dev(dev);
	ret = execute_steps(dev, steps, ARRAY_SIZE(steps));
	mutex_unlock(&dev->dev_lock);

	return ret;
}

static int opal_erase_locking_range(struct opal_dev *dev,
				    struct opal_session_info *opal_session)
{
	const struct opal_step erase_steps[] = {
		{ start_auth_opal_session, opal_session },
		{ erase_locking_range, opal_session },
		{ end_opal_session, }
	};
	int ret;

	ret = opal_get_key(dev, &opal_session->opal_key);
	if (ret)
		return ret;
	mutex_lock(&dev->dev_lock);
	setup_opal_dev(dev);
	ret = execute_steps(dev, erase_steps, ARRAY_SIZE(erase_steps));
	mutex_unlock(&dev->dev_lock);

	return ret;
}

static int opal_enable_disable_shadow_mbr(struct opal_dev *dev,
					  struct opal_mbr_data *opal_mbr)
{
	u8 enable_disable = opal_mbr->enable_disable == OPAL_MBR_ENABLE ?
		OPAL_TRUE : OPAL_FALSE;

	const struct opal_step mbr_steps[] = {
		{ start_admin1LSP_opal_session, &opal_mbr->key },
		{ set_mbr_done, &enable_disable },
		{ end_opal_session, },
		{ start_admin1LSP_opal_session, &opal_mbr->key },
		{ set_mbr_enable_disable, &enable_disable },
		{ end_opal_session, }
	};
	int ret;

	if (opal_mbr->enable_disable != OPAL_MBR_ENABLE &&
	    opal_mbr->enable_disable != OPAL_MBR_DISABLE)
		return -EINVAL;

	ret = opal_get_key(dev, &opal_mbr->key);
	if (ret)
		return ret;
	mutex_lock(&dev->dev_lock);
	setup_opal_dev(dev);
	ret = execute_steps(dev, mbr_steps, ARRAY_SIZE(mbr_steps));
	mutex_unlock(&dev->dev_lock);

	return ret;
}

static int opal_set_mbr_done(struct opal_dev *dev,
			     struct opal_mbr_done *mbr_done)
{
	u8 mbr_done_tf = mbr_done->done_flag == OPAL_MBR_DONE ?
		OPAL_TRUE : OPAL_FALSE;

	const struct opal_step mbr_steps[] = {
		{ start_admin1LSP_opal_session, &mbr_done->key },
		{ set_mbr_done, &mbr_done_tf },
		{ end_opal_session, }
	};
	int ret;

	if (mbr_done->done_flag != OPAL_MBR_DONE &&
	    mbr_done->done_flag != OPAL_MBR_NOT_DONE)
		return -EINVAL;

	ret = opal_get_key(dev, &mbr_done->key);
	if (ret)
		return ret;
	mutex_lock(&dev->dev_lock);
	setup_opal_dev(dev);
	ret = execute_steps(dev, mbr_steps, ARRAY_SIZE(mbr_steps));
	mutex_unlock(&dev->dev_lock);

	return ret;
}

static int opal_write_shadow_mbr(struct opal_dev *dev,
				 struct opal_shadow_mbr *info)
{
	const struct opal_step mbr_steps[] = {
		{ start_admin1LSP_opal_session, &info->key },
		{ write_shadow_mbr, info },
		{ end_opal_session, }
	};
	int ret;

	if (info->size == 0)
		return 0;

	ret = opal_get_key(dev, &info->key);
	if (ret)
		return ret;
	mutex_lock(&dev->dev_lock);
	setup_opal_dev(dev);
	ret = execute_steps(dev, mbr_steps, ARRAY_SIZE(mbr_steps));
	mutex_unlock(&dev->dev_lock);

	return ret;
}

static int opal_save(struct opal_dev *dev, struct opal_lock_unlock *lk_unlk)
{
	struct opal_suspend_data *suspend;

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

	suspend->unlk = *lk_unlk;
	suspend->lr = lk_unlk->session.opal_key.lr;

	mutex_lock(&dev->dev_lock);
	setup_opal_dev(dev);
	add_suspend_info(dev, suspend);
	mutex_unlock(&dev->dev_lock);

	return 0;
}

static int opal_add_user_to_lr(struct opal_dev *dev,
			       struct opal_lock_unlock *lk_unlk)
{
	const struct opal_step steps[] = {
		{ start_admin1LSP_opal_session, &lk_unlk->session.opal_key },
		{ add_user_to_lr, lk_unlk },
		{ add_user_to_lr_ace, lk_unlk },
		{ end_opal_session, }
	};
	int ret;

	if (lk_unlk->l_state != OPAL_RO &&
	    lk_unlk->l_state != OPAL_RW) {
		pr_debug("Locking state was not RO or RW\n");
		return -EINVAL;
	}

	if (lk_unlk->session.who < OPAL_USER1 ||
	    lk_unlk->session.who > OPAL_USER9) {
		pr_debug("Authority was not within the range of users: %d\n",
			 lk_unlk->session.who);
		return -EINVAL;
	}

	if (lk_unlk->session.sum) {
		pr_debug("%s not supported in sum. Use setup locking range\n",
			 __func__);
		return -EINVAL;
	}

	ret = opal_get_key(dev, &lk_unlk->session.opal_key);
	if (ret)
		return ret;
	mutex_lock(&dev->dev_lock);
	setup_opal_dev(dev);
	ret = execute_steps(dev, steps, ARRAY_SIZE(steps));
	mutex_unlock(&dev->dev_lock);

	return ret;
}

static int opal_reverttper(struct opal_dev *dev, struct opal_key *opal, bool psid)
{
	/* controller will terminate session */
	const struct opal_step revert_steps[] = {
		{ start_SIDASP_opal_session, opal },
		{ revert_tper, }
	};
	const struct opal_step psid_revert_steps[] = {
		{ start_PSID_opal_session, opal },
		{ revert_tper, }
	};

	int ret;

	ret = opal_get_key(dev, opal);

	if (ret)
		return ret;
	mutex_lock(&dev->dev_lock);
	setup_opal_dev(dev);
	if (psid)
		ret = execute_steps(dev, psid_revert_steps,
				    ARRAY_SIZE(psid_revert_steps));
	else
		ret = execute_steps(dev, revert_steps,
				    ARRAY_SIZE(revert_steps));
	mutex_unlock(&dev->dev_lock);

	/*
	 * If we successfully reverted lets clean
	 * any saved locking ranges.
	 */
	if (!ret)
		clean_opal_dev(dev);

	return ret;
}

static int __opal_lock_unlock(struct opal_dev *dev,
			      struct opal_lock_unlock *lk_unlk)
{
	const struct opal_step unlock_steps[] = {
		{ start_auth_opal_session, &lk_unlk->session },
		{ lock_unlock_locking_range, lk_unlk },
		{ end_opal_session, }
	};
	const struct opal_step unlock_sum_steps[] = {
		{ start_auth_opal_session, &lk_unlk->session },
		{ lock_unlock_locking_range_sum, lk_unlk },
		{ end_opal_session, }
	};

	if (lk_unlk->session.sum)
		return execute_steps(dev, unlock_sum_steps,
				     ARRAY_SIZE(unlock_sum_steps));
	else
		return execute_steps(dev, unlock_steps,
				     ARRAY_SIZE(unlock_steps));
}

static int __opal_set_mbr_done(struct opal_dev *dev, struct opal_key *key)
{
	u8 mbr_done_tf = OPAL_TRUE;
	const struct opal_step mbrdone_step[] = {
		{ start_admin1LSP_opal_session, key },
		{ set_mbr_done, &mbr_done_tf },
		{ end_opal_session, }
	};

	return execute_steps(dev, mbrdone_step, ARRAY_SIZE(mbrdone_step));
}

static void opal_lock_check_for_saved_key(struct opal_dev *dev,
			    struct opal_lock_unlock *lk_unlk)
{
	struct opal_suspend_data *iter;

	if (lk_unlk->l_state != OPAL_LK ||
			lk_unlk->session.opal_key.key_len > 0)
		return;

	/*
	 * Usually when closing a crypto device (eg: dm-crypt with LUKS) the
	 * volume key is not required, as it requires root privileges anyway,
	 * and root can deny access to a disk in many ways regardless.
	 * Requiring the volume key to lock the device is a peculiarity of the
	 * OPAL specification. Given we might already have saved the key if
	 * the user requested it via the 'IOC_OPAL_SAVE' ioctl, we can use
	 * that key to lock the device if no key was provided here, the
	 * locking range matches and the appropriate flag was passed with
	 * 'IOC_OPAL_SAVE'.
	 * This allows integrating OPAL with tools and libraries that are used
	 * to the common behaviour and do not ask for the volume key when
	 * closing a device.
	 */
	setup_opal_dev(dev);
	list_for_each_entry(iter, &dev->unlk_lst, node) {
		if ((iter->unlk.flags & OPAL_SAVE_FOR_LOCK) &&
				iter->lr == lk_unlk->session.opal_key.lr &&
				iter->unlk.session.opal_key.key_len > 0) {
			lk_unlk->session.opal_key.key_len =
				iter->unlk.session.opal_key.key_len;
			memcpy(lk_unlk->session.opal_key.key,
				iter->unlk.session.opal_key.key,
				iter->unlk.session.opal_key.key_len);
			break;
		}
	}
}

static int opal_lock_unlock(struct opal_dev *dev,
			    struct opal_lock_unlock *lk_unlk)
{
	int ret;

	if (lk_unlk->session.who > OPAL_USER9)
		return -EINVAL;

	mutex_lock(&dev->dev_lock);
	opal_lock_check_for_saved_key(dev, lk_unlk);
	ret = opal_get_key(dev, &lk_unlk->session.opal_key);
	if (!ret)
		ret = __opal_lock_unlock(dev, lk_unlk);
	mutex_unlock(&dev->dev_lock);

	return ret;
}

static int opal_take_ownership(struct opal_dev *dev, struct opal_key *opal)
{
	const struct opal_step owner_steps[] = {
		{ start_anybodyASP_opal_session, },
		{ get_msid_cpin_pin, },
		{ end_opal_session, },
		{ start_SIDASP_opal_session, opal },
		{ set_sid_cpin_pin, opal },
		{ end_opal_session, }
	};
	int ret;

	if (!dev)
		return -ENODEV;

	ret = opal_get_key(dev, opal);
	if (ret)
		return ret;
	mutex_lock(&dev->dev_lock);
	setup_opal_dev(dev);
	ret = execute_steps(dev, owner_steps, ARRAY_SIZE(owner_steps));
	mutex_unlock(&dev->dev_lock);

	return ret;
}

static int opal_activate_lsp(struct opal_dev *dev,
			     struct opal_lr_act *opal_lr_act)
{
	const struct opal_step active_steps[] = {
		{ start_SIDASP_opal_session, &opal_lr_act->key },
		{ get_lsp_lifecycle, },
		{ activate_lsp, opal_lr_act },
		{ end_opal_session, }
	};
	int ret;

	if (!opal_lr_act->num_lrs || opal_lr_act->num_lrs > OPAL_MAX_LRS)
		return -EINVAL;

	ret = opal_get_key(dev, &opal_lr_act->key);
	if (ret)
		return ret;
	mutex_lock(&dev->dev_lock);
	setup_opal_dev(dev);
	ret = execute_steps(dev, active_steps, ARRAY_SIZE(active_steps));
	mutex_unlock(&dev->dev_lock);

	return ret;
}

static int opal_setup_locking_range(struct opal_dev *dev,
				    struct opal_user_lr_setup *opal_lrs)
{
	const struct opal_step lr_steps[] = {
		{ start_auth_opal_session, &opal_lrs->session },
		{ setup_locking_range, opal_lrs },
		{ end_opal_session, }
	};
	int ret;

	ret = opal_get_key(dev, &opal_lrs->session.opal_key);
	if (ret)
		return ret;
	mutex_lock(&dev->dev_lock);
	setup_opal_dev(dev);
	ret = execute_steps(dev, lr_steps, ARRAY_SIZE(lr_steps));
	mutex_unlock(&dev->dev_lock);

	return ret;
}

static int opal_locking_range_status(struct opal_dev *dev,
			  struct opal_lr_status *opal_lrst,
			  void __user *data)
{
	const struct opal_step lr_steps[] = {
		{ start_auth_opal_session, &opal_lrst->session },
		{ locking_range_status, opal_lrst },
		{ end_opal_session, }
	};
	int ret;

	mutex_lock(&dev->dev_lock);
	setup_opal_dev(dev);
	ret = execute_steps(dev, lr_steps, ARRAY_SIZE(lr_steps));
	mutex_unlock(&dev->dev_lock);

	/* skip session info when copying back to uspace */
	if (!ret && copy_to_user(data + offsetof(struct opal_lr_status, range_start),
				(void *)opal_lrst + offsetof(struct opal_lr_status, range_start),
				sizeof(*opal_lrst) - offsetof(struct opal_lr_status, range_start))) {
		pr_debug("Error copying status to userspace\n");
		return -EFAULT;
	}

	return ret;
}

static int opal_set_new_pw(struct opal_dev *dev, struct opal_new_pw *opal_pw)
{
	const struct opal_step pw_steps[] = {
		{ start_auth_opal_session, &opal_pw->session },
		{ set_new_pw, &opal_pw->new_user_pw },
		{ end_opal_session, }
	};
	int ret;

	if (opal_pw->session.who > OPAL_USER9  ||
	    opal_pw->new_user_pw.who > OPAL_USER9)
		return -EINVAL;

	mutex_lock(&dev->dev_lock);
	setup_opal_dev(dev);
	ret = execute_steps(dev, pw_steps, ARRAY_SIZE(pw_steps));
	mutex_unlock(&dev->dev_lock);

	if (ret)
		return ret;

	/* update keyring with new password */
	ret = update_sed_opal_key(OPAL_AUTH_KEY,
				  opal_pw->new_user_pw.opal_key.key,
				  opal_pw->new_user_pw.opal_key.key_len);

	return ret;
}

static int opal_activate_user(struct opal_dev *dev,
			      struct opal_session_info *opal_session)
{
	const struct opal_step act_steps[] = {
		{ start_admin1LSP_opal_session, &opal_session->opal_key },
		{ internal_activate_user, opal_session },
		{ end_opal_session, }
	};
	int ret;

	/* We can't activate Admin1 it's active as manufactured */
	if (opal_session->who < OPAL_USER1 ||
	    opal_session->who > OPAL_USER9) {
		pr_debug("Who was not a valid user: %d\n", opal_session->who);
		return -EINVAL;
	}

	ret = opal_get_key(dev, &opal_session->opal_key);
	if (ret)
		return ret;
	mutex_lock(&dev->dev_lock);
	setup_opal_dev(dev);
	ret = execute_steps(dev, act_steps, ARRAY_SIZE(act_steps));
	mutex_unlock(&dev->dev_lock);

	return ret;
}

bool opal_unlock_from_suspend(struct opal_dev *dev)
{
	struct opal_suspend_data *suspend;
	bool was_failure = false;
	int ret = 0;

	if (!dev)
		return false;

	if (!(dev->flags & OPAL_FL_SUPPORTED))
		return false;

	mutex_lock(&dev->dev_lock);
	setup_opal_dev(dev);

	list_for_each_entry(suspend, &dev->unlk_lst, node) {
		dev->tsn = 0;
		dev->hsn = 0;

		ret = __opal_lock_unlock(dev, &suspend->unlk);
		if (ret) {
			pr_debug("Failed to unlock LR %hhu with sum %d\n",
				 suspend->unlk.session.opal_key.lr,
				 suspend->unlk.session.sum);
			was_failure = true;
		}

		if (dev->flags & OPAL_FL_MBR_ENABLED) {
			ret = __opal_set_mbr_done(dev, &suspend->unlk.session.opal_key);
			if (ret)
				pr_debug("Failed to set MBR Done in S3 resume\n");
		}
	}
	mutex_unlock(&dev->dev_lock);

	return was_failure;
}
EXPORT_SYMBOL(opal_unlock_from_suspend);

static int opal_read_table(struct opal_dev *dev,
			   struct opal_read_write_table *rw_tbl)
{
	const struct opal_step read_table_steps[] = {
		{ start_admin1LSP_opal_session, &rw_tbl->key },
		{ read_table_data, rw_tbl },
		{ end_opal_session, }
	};
	int ret = 0;

	if (!rw_tbl->size)
		return ret;

	return execute_steps(dev, read_table_steps,
			     ARRAY_SIZE(read_table_steps));
}

static int opal_write_table(struct opal_dev *dev,
			    struct opal_read_write_table *rw_tbl)
{
	const struct opal_step write_table_steps[] = {
		{ start_admin1LSP_opal_session, &rw_tbl->key },
		{ write_table_data, rw_tbl },
		{ end_opal_session, }
	};
	int ret = 0;

	if (!rw_tbl->size)
		return ret;

	return execute_steps(dev, write_table_steps,
			     ARRAY_SIZE(write_table_steps));
}

static int opal_generic_read_write_table(struct opal_dev *dev,
					 struct opal_read_write_table *rw_tbl)
{
	int ret, bit_set;

	ret = opal_get_key(dev, &rw_tbl->key);
	if (ret)
		return ret;
	mutex_lock(&dev->dev_lock);
	setup_opal_dev(dev);

	bit_set = fls64(rw_tbl->flags) - 1;
	switch (bit_set) {
	case OPAL_READ_TABLE:
		ret = opal_read_table(dev, rw_tbl);
		break;
	case OPAL_WRITE_TABLE:
		ret = opal_write_table(dev, rw_tbl);
		break;
	default:
		pr_debug("Invalid bit set in the flag (%016llx).\n",
			 rw_tbl->flags);
		ret = -EINVAL;
		break;
	}

	mutex_unlock(&dev->dev_lock);

	return ret;
}

static int opal_get_status(struct opal_dev *dev, void __user *data)
{
	struct opal_status sts = {0};

	/*
	 * check_opal_support() error is not fatal,
	 * !dev->supported is a valid condition
	 */
	if (!check_opal_support(dev))
		sts.flags = dev->flags;
	if (copy_to_user(data, &sts, sizeof(sts))) {
		pr_debug("Error copying status to userspace\n");
		return -EFAULT;
	}
	return 0;
}

static int opal_get_geometry(struct opal_dev *dev, void __user *data)
{
	struct opal_geometry geo = {0};

	if (check_opal_support(dev))
		return -EINVAL;

	geo.align = dev->align_required;
	geo.logical_block_size = dev->logical_block_size;
	geo.alignment_granularity =  dev->align;
	geo.lowest_aligned_lba = dev->lowest_lba;

	if (copy_to_user(data, &geo, sizeof(geo))) {
		pr_debug("Error copying geometry data to userspace\n");
		return -EFAULT;
	}

	return 0;
}

int sed_ioctl(struct opal_dev *dev, unsigned int cmd, void __user *arg)
{
	void *p;
	int ret = -ENOTTY;

	if (!capable(CAP_SYS_ADMIN))
		return -EACCES;
	if (!dev)
		return -EOPNOTSUPP;
	if (!(dev->flags & OPAL_FL_SUPPORTED))
		return -EOPNOTSUPP;

	if (cmd & IOC_IN) {
		p = memdup_user(arg, _IOC_SIZE(cmd));
		if (IS_ERR(p))
			return PTR_ERR(p);
	}

	switch (cmd) {
	case IOC_OPAL_SAVE:
		ret = opal_save(dev, p);
		break;
	case IOC_OPAL_LOCK_UNLOCK:
		ret = opal_lock_unlock(dev, p);
		break;
	case IOC_OPAL_TAKE_OWNERSHIP:
		ret = opal_take_ownership(dev, p);
		break;
	case IOC_OPAL_ACTIVATE_LSP:
		ret = opal_activate_lsp(dev, p);
		break;
	case IOC_OPAL_SET_PW:
		ret = opal_set_new_pw(dev, p);
		break;
	case IOC_OPAL_ACTIVATE_USR:
		ret = opal_activate_user(dev, p);
		break;
	case IOC_OPAL_REVERT_TPR:
		ret = opal_reverttper(dev, p, false);
		break;
	case IOC_OPAL_LR_SETUP:
		ret = opal_setup_locking_range(dev, p);
		break;
	case IOC_OPAL_ADD_USR_TO_LR:
		ret = opal_add_user_to_lr(dev, p);
		break;
	case IOC_OPAL_ENABLE_DISABLE_MBR:
		ret = opal_enable_disable_shadow_mbr(dev, p);
		break;
	case IOC_OPAL_MBR_DONE:
		ret = opal_set_mbr_done(dev, p);
		break;
	case IOC_OPAL_WRITE_SHADOW_MBR:
		ret = opal_write_shadow_mbr(dev, p);
		break;
	case IOC_OPAL_ERASE_LR:
		ret = opal_erase_locking_range(dev, p);
		break;
	case IOC_OPAL_SECURE_ERASE_LR:
		ret = opal_secure_erase_locking_range(dev, p);
		break;
	case IOC_OPAL_PSID_REVERT_TPR:
		ret = opal_reverttper(dev, p, true);
		break;
	case IOC_OPAL_GENERIC_TABLE_RW:
		ret = opal_generic_read_write_table(dev, p);
		break;
	case IOC_OPAL_GET_STATUS:
		ret = opal_get_status(dev, arg);
		break;
	case IOC_OPAL_GET_LR_STATUS:
		ret = opal_locking_range_status(dev, p, arg);
		break;
	case IOC_OPAL_GET_GEOMETRY:
		ret = opal_get_geometry(dev, arg);
		break;
	case IOC_OPAL_REVERT_LSP:
		ret = opal_revertlsp(dev, p);
		break;
	case IOC_OPAL_DISCOVERY:
		ret = opal_get_discv(dev, p);
		break;

	default:
		break;
	}

	if (cmd & IOC_IN)
		kfree(p);
	return ret;
}
EXPORT_SYMBOL_GPL(sed_ioctl);

static int __init sed_opal_init(void)
{
	struct key *kr;

	kr = keyring_alloc(".sed_opal",
			   GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, current_cred(),
			   (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_VIEW |
			   KEY_USR_READ | KEY_USR_SEARCH | KEY_USR_WRITE,
			   KEY_ALLOC_NOT_IN_QUOTA,
			   NULL, NULL);
	if (IS_ERR(kr))
		return PTR_ERR(kr);

	sed_opal_keyring = kr;

	return 0;
}
late_initcall(sed_opal_init);
