Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    3)  * Copyright © 2016 Intel Corporation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    5)  * Authors:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    6)  *    Scott  Bauer      <scott.bauer@intel.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    7)  *    Rafael Antognolli <rafael.antognolli@intel.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    8)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    9) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   10) #define pr_fmt(fmt) KBUILD_MODNAME ":OPAL: " fmt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   11) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   12) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   13) #include <linux/device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   14) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   15) #include <linux/list.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   16) #include <linux/genhd.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   17) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   18) #include <linux/uaccess.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   19) #include <uapi/linux/sed-opal.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   20) #include <linux/sed-opal.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   21) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   22) #include <linux/kdev_t.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   23) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   24) #include "opal_proto.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   25) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   26) #define IO_BUFFER_LENGTH 2048
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   27) #define MAX_TOKS 64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   28) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   29) /* Number of bytes needed by cmd_finalize. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   30) #define CMD_FINALIZE_BYTES_NEEDED 7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   31) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   32) struct opal_step {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   33) 	int (*fn)(struct opal_dev *dev, void *data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   34) 	void *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   35) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   36) typedef int (cont_fn)(struct opal_dev *dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   37) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   38) enum opal_atom_width {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   39) 	OPAL_WIDTH_TINY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   40) 	OPAL_WIDTH_SHORT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   41) 	OPAL_WIDTH_MEDIUM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   42) 	OPAL_WIDTH_LONG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   43) 	OPAL_WIDTH_TOKEN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   44) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   45) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   46) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   47)  * On the parsed response, we don't store again the toks that are already
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   48)  * stored in the response buffer. Instead, for each token, we just store a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   49)  * pointer to the position in the buffer where the token starts, and the size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   50)  * of the token in bytes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   51)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   52) struct opal_resp_tok {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   53) 	const u8 *pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   54) 	size_t len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   55) 	enum opal_response_token type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   56) 	enum opal_atom_width width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   57) 	union {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   58) 		u64 u;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   59) 		s64 s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   60) 	} stored;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   61) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   62) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   63) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   64)  * From the response header it's not possible to know how many tokens there are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   65)  * on the payload. So we hardcode that the maximum will be MAX_TOKS, and later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   66)  * if we start dealing with messages that have more than that, we can increase
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   67)  * this number. This is done to avoid having to make two passes through the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   68)  * response, the first one counting how many tokens we have and the second one
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   69)  * actually storing the positions.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   70)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   71) struct parsed_resp {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   72) 	int num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   73) 	struct opal_resp_tok toks[MAX_TOKS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   74) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   75) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   76) struct opal_dev {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   77) 	bool supported;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   78) 	bool mbr_enabled;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   79) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   80) 	void *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   81) 	sec_send_recv *send_recv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   82) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   83) 	struct mutex dev_lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   84) 	u16 comid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   85) 	u32 hsn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   86) 	u32 tsn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   87) 	u64 align;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   88) 	u64 lowest_lba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   89) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   90) 	size_t pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   91) 	u8 cmd[IO_BUFFER_LENGTH];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   92) 	u8 resp[IO_BUFFER_LENGTH];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   93) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   94) 	struct parsed_resp parsed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   95) 	size_t prev_d_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   96) 	void *prev_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   97) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   98) 	struct list_head unlk_lst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   99) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  100) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  101) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  102) static const u8 opaluid[][OPAL_UID_LENGTH] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  103) 	/* users */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  104) 	[OPAL_SMUID_UID] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  105) 		{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  106) 	[OPAL_THISSP_UID] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  107) 		{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  108) 	[OPAL_ADMINSP_UID] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  109) 		{ 0x00, 0x00, 0x02, 0x05, 0x00, 0x00, 0x00, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  110) 	[OPAL_LOCKINGSP_UID] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  111) 		{ 0x00, 0x00, 0x02, 0x05, 0x00, 0x00, 0x00, 0x02 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  112) 	[OPAL_ENTERPRISE_LOCKINGSP_UID] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  113) 		{ 0x00, 0x00, 0x02, 0x05, 0x00, 0x01, 0x00, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  114) 	[OPAL_ANYBODY_UID] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  115) 		{ 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  116) 	[OPAL_SID_UID] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  117) 		{ 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x06 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  118) 	[OPAL_ADMIN1_UID] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  119) 		{ 0x00, 0x00, 0x00, 0x09, 0x00, 0x01, 0x00, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  120) 	[OPAL_USER1_UID] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  121) 		{ 0x00, 0x00, 0x00, 0x09, 0x00, 0x03, 0x00, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  122) 	[OPAL_USER2_UID] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  123) 		{ 0x00, 0x00, 0x00, 0x09, 0x00, 0x03, 0x00, 0x02 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  124) 	[OPAL_PSID_UID] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  125) 		{ 0x00, 0x00, 0x00, 0x09, 0x00, 0x01, 0xff, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  126) 	[OPAL_ENTERPRISE_BANDMASTER0_UID] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  127) 		{ 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x80, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  128) 	[OPAL_ENTERPRISE_ERASEMASTER_UID] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  129) 		{ 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x84, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  130) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  131) 	/* tables */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  132) 	[OPAL_TABLE_TABLE] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  133) 		{ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  134) 	[OPAL_LOCKINGRANGE_GLOBAL] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  135) 		{ 0x00, 0x00, 0x08, 0x02, 0x00, 0x00, 0x00, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  136) 	[OPAL_LOCKINGRANGE_ACE_RDLOCKED] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  137) 		{ 0x00, 0x00, 0x00, 0x08, 0x00, 0x03, 0xE0, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  138) 	[OPAL_LOCKINGRANGE_ACE_WRLOCKED] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  139) 		{ 0x00, 0x00, 0x00, 0x08, 0x00, 0x03, 0xE8, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  140) 	[OPAL_MBRCONTROL] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  141) 		{ 0x00, 0x00, 0x08, 0x03, 0x00, 0x00, 0x00, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  142) 	[OPAL_MBR] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  143) 		{ 0x00, 0x00, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  144) 	[OPAL_AUTHORITY_TABLE] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  145) 		{ 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  146) 	[OPAL_C_PIN_TABLE] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  147) 		{ 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  148) 	[OPAL_LOCKING_INFO_TABLE] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  149) 		{ 0x00, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  150) 	[OPAL_ENTERPRISE_LOCKING_INFO_TABLE] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  151) 		{ 0x00, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  152) 	[OPAL_DATASTORE] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  153) 		{ 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x00, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  154) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  155) 	/* C_PIN_TABLE object ID's */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  156) 	[OPAL_C_PIN_MSID] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  157) 		{ 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x84, 0x02},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  158) 	[OPAL_C_PIN_SID] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  159) 		{ 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  160) 	[OPAL_C_PIN_ADMIN1] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  161) 		{ 0x00, 0x00, 0x00, 0x0B, 0x00, 0x01, 0x00, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  162) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  163) 	/* half UID's (only first 4 bytes used) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  164) 	[OPAL_HALF_UID_AUTHORITY_OBJ_REF] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  165) 		{ 0x00, 0x00, 0x0C, 0x05, 0xff, 0xff, 0xff, 0xff },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  166) 	[OPAL_HALF_UID_BOOLEAN_ACE] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  167) 		{ 0x00, 0x00, 0x04, 0x0E, 0xff, 0xff, 0xff, 0xff },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  168) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  169) 	/* special value for omitted optional parameter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  170) 	[OPAL_UID_HEXFF] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  171) 		{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  172) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  173) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  174) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  175)  * TCG Storage SSC Methods.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  176)  * Derived from: TCG_Storage_Architecture_Core_Spec_v2.01_r1.00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  177)  * Section: 6.3 Assigned UIDs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  178)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  179) static const u8 opalmethod[][OPAL_METHOD_LENGTH] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  180) 	[OPAL_PROPERTIES] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  181) 		{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  182) 	[OPAL_STARTSESSION] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  183) 		{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x02 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  184) 	[OPAL_REVERT] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  185) 		{ 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x02, 0x02 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  186) 	[OPAL_ACTIVATE] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  187) 		{ 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x02, 0x03 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  188) 	[OPAL_EGET] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  189) 		{ 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  190) 	[OPAL_ESET] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  191) 		{ 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x07 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  192) 	[OPAL_NEXT] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  193) 		{ 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x08 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  194) 	[OPAL_EAUTHENTICATE] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  195) 		{ 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0c },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  196) 	[OPAL_GETACL] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  197) 		{ 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0d },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  198) 	[OPAL_GENKEY] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  199) 		{ 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x10 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  200) 	[OPAL_REVERTSP] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  201) 		{ 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x11 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  202) 	[OPAL_GET] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  203) 		{ 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x16 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  204) 	[OPAL_SET] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  205) 		{ 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x17 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  206) 	[OPAL_AUTHENTICATE] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  207) 		{ 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x1c },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  208) 	[OPAL_RANDOM] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  209) 		{ 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  210) 	[OPAL_ERASE] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  211) 		{ 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x08, 0x03 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  212) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  213) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  214) static int end_opal_session_error(struct opal_dev *dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  215) static int opal_discovery0_step(struct opal_dev *dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  216) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  217) struct opal_suspend_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  218) 	struct opal_lock_unlock unlk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  219) 	u8 lr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  220) 	struct list_head node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  221) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  222) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  223) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  224)  * Derived from:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  225)  * TCG_Storage_Architecture_Core_Spec_v2.01_r1.00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  226)  * Section: 5.1.5 Method Status Codes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  227)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  228) static const char * const opal_errors[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  229) 	"Success",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  230) 	"Not Authorized",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  231) 	"Unknown Error",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  232) 	"SP Busy",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  233) 	"SP Failed",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  234) 	"SP Disabled",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  235) 	"SP Frozen",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  236) 	"No Sessions Available",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  237) 	"Uniqueness Conflict",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  238) 	"Insufficient Space",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  239) 	"Insufficient Rows",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  240) 	"Invalid Function",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  241) 	"Invalid Parameter",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  242) 	"Invalid Reference",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  243) 	"Unknown Error",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  244) 	"TPER Malfunction",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  245) 	"Transaction Failure",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  246) 	"Response Overflow",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  247) 	"Authority Locked Out",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  248) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  249) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  250) static const char *opal_error_to_human(int error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  251) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  252) 	if (error == 0x3f)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  253) 		return "Failed";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  254) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  255) 	if (error >= ARRAY_SIZE(opal_errors) || error < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  256) 		return "Unknown Error";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  257) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  258) 	return opal_errors[error];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  259) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  260) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  261) static void print_buffer(const u8 *ptr, u32 length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  262) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  263) #ifdef DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  264) 	print_hex_dump_bytes("OPAL: ", DUMP_PREFIX_OFFSET, ptr, length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  265) 	pr_debug("\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  266) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  267) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  268) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  269) static bool check_tper(const void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  270) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  271) 	const struct d0_tper_features *tper = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  272) 	u8 flags = tper->supported_features;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  273) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  274) 	if (!(flags & TPER_SYNC_SUPPORTED)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  275) 		pr_debug("TPer sync not supported. flags = %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  276) 			 tper->supported_features);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  277) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  278) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  279) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  280) 	return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  281) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  282) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  283) static bool check_mbrenabled(const void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  284) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  285) 	const struct d0_locking_features *lfeat = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  286) 	u8 sup_feat = lfeat->supported_features;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  287) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  288) 	return !!(sup_feat & MBR_ENABLED_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  289) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  290) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  291) static bool check_sum(const void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  292) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  293) 	const struct d0_single_user_mode *sum = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  294) 	u32 nlo = be32_to_cpu(sum->num_locking_objects);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  295) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  296) 	if (nlo == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  297) 		pr_debug("Need at least one locking object.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  298) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  299) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  300) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  301) 	pr_debug("Number of locking objects: %d\n", nlo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  302) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  303) 	return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  304) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  305) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  306) static u16 get_comid_v100(const void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  307) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  308) 	const struct d0_opal_v100 *v100 = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  309) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  310) 	return be16_to_cpu(v100->baseComID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  311) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  312) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  313) static u16 get_comid_v200(const void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  314) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  315) 	const struct d0_opal_v200 *v200 = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  316) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  317) 	return be16_to_cpu(v200->baseComID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  318) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  319) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  320) static int opal_send_cmd(struct opal_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  321) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  322) 	return dev->send_recv(dev->data, dev->comid, TCG_SECP_01,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  323) 			      dev->cmd, IO_BUFFER_LENGTH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  324) 			      true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  325) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  326) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  327) static int opal_recv_cmd(struct opal_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  328) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  329) 	return dev->send_recv(dev->data, dev->comid, TCG_SECP_01,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  330) 			      dev->resp, IO_BUFFER_LENGTH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  331) 			      false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  332) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  333) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  334) static int opal_recv_check(struct opal_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  335) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  336) 	size_t buflen = IO_BUFFER_LENGTH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  337) 	void *buffer = dev->resp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  338) 	struct opal_header *hdr = buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  339) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  340) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  341) 	do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  342) 		pr_debug("Sent OPAL command: outstanding=%d, minTransfer=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  343) 			 hdr->cp.outstandingData,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  344) 			 hdr->cp.minTransfer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  345) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  346) 		if (hdr->cp.outstandingData == 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  347) 		    hdr->cp.minTransfer != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  348) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  349) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  350) 		memset(buffer, 0, buflen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  351) 		ret = opal_recv_cmd(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  352) 	} while (!ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  353) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  354) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  355) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  356) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  357) static int opal_send_recv(struct opal_dev *dev, cont_fn *cont)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  358) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  359) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  360) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  361) 	ret = opal_send_cmd(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  362) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  363) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  364) 	ret = opal_recv_cmd(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  365) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  366) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  367) 	ret = opal_recv_check(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  368) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  369) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  370) 	return cont(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  371) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  372) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  373) static void check_geometry(struct opal_dev *dev, const void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  374) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  375) 	const struct d0_geometry_features *geo = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  376) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  377) 	dev->align = be64_to_cpu(geo->alignment_granularity);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  378) 	dev->lowest_lba = be64_to_cpu(geo->lowest_aligned_lba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  379) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  380) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  381) static int execute_step(struct opal_dev *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  382) 			const struct opal_step *step, size_t stepIndex)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  383) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  384) 	int error = step->fn(dev, step->data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  385) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  386) 	if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  387) 		pr_debug("Step %zu (%pS) failed with error %d: %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  388) 			 stepIndex, step->fn, error,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  389) 			 opal_error_to_human(error));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  390) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  391) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  392) 	return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  393) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  394) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  395) static int execute_steps(struct opal_dev *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  396) 			 const struct opal_step *steps, size_t n_steps)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  397) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  398) 	size_t state = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  399) 	int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  400) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  401) 	/* first do a discovery0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  402) 	error = opal_discovery0_step(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  403) 	if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  404) 		return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  405) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  406) 	for (state = 0; state < n_steps; state++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  407) 		error = execute_step(dev, &steps[state], state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  408) 		if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  409) 			goto out_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  410) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  411) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  412) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  413) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  414) out_error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  415) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  416) 	 * For each OPAL command the first step in steps starts some sort of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  417) 	 * session. If an error occurred in the initial discovery0 or if an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  418) 	 * error occurred in the first step (and thus stopping the loop with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  419) 	 * state == 0) then there was an error before or during the attempt to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  420) 	 * start a session. Therefore we shouldn't attempt to terminate a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  421) 	 * session, as one has not yet been created.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  422) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  423) 	if (state > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  424) 		end_opal_session_error(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  425) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  426) 	return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  427) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  428) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  429) static int opal_discovery0_end(struct opal_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  430) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  431) 	bool found_com_id = false, supported = true, single_user = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  432) 	const struct d0_header *hdr = (struct d0_header *)dev->resp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  433) 	const u8 *epos = dev->resp, *cpos = dev->resp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  434) 	u16 comid = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  435) 	u32 hlen = be32_to_cpu(hdr->length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  436) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  437) 	print_buffer(dev->resp, hlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  438) 	dev->mbr_enabled = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  439) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  440) 	if (hlen > IO_BUFFER_LENGTH - sizeof(*hdr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  441) 		pr_debug("Discovery length overflows buffer (%zu+%u)/%u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  442) 			 sizeof(*hdr), hlen, IO_BUFFER_LENGTH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  443) 		return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  444) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  445) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  446) 	epos += hlen; /* end of buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  447) 	cpos += sizeof(*hdr); /* current position on buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  448) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  449) 	while (cpos < epos && supported) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  450) 		const struct d0_features *body =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  451) 			(const struct d0_features *)cpos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  452) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  453) 		switch (be16_to_cpu(body->code)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  454) 		case FC_TPER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  455) 			supported = check_tper(body->features);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  456) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  457) 		case FC_SINGLEUSER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  458) 			single_user = check_sum(body->features);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  459) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  460) 		case FC_GEOMETRY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  461) 			check_geometry(dev, body);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  462) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  463) 		case FC_LOCKING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  464) 			dev->mbr_enabled = check_mbrenabled(body->features);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  465) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  466) 		case FC_ENTERPRISE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  467) 		case FC_DATASTORE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  468) 			/* some ignored properties */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  469) 			pr_debug("Found OPAL feature description: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  470) 				 be16_to_cpu(body->code));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  471) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  472) 		case FC_OPALV100:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  473) 			comid = get_comid_v100(body->features);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  474) 			found_com_id = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  475) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  476) 		case FC_OPALV200:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  477) 			comid = get_comid_v200(body->features);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  478) 			found_com_id = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  479) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  480) 		case 0xbfff ... 0xffff:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  481) 			/* vendor specific, just ignore */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  482) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  483) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  484) 			pr_debug("OPAL Unknown feature: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  485) 				 be16_to_cpu(body->code));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  486) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  487) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  488) 		cpos += body->length + 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  489) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  490) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  491) 	if (!supported) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  492) 		pr_debug("This device is not Opal enabled. Not Supported!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  493) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  494) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  495) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  496) 	if (!single_user)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  497) 		pr_debug("Device doesn't support single user mode\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  498) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  499) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  500) 	if (!found_com_id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  501) 		pr_debug("Could not find OPAL comid for device. Returning early\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  502) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  503) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  504) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  505) 	dev->comid = comid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  506) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  507) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  508) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  509) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  510) static int opal_discovery0(struct opal_dev *dev, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  511) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  512) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  513) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  514) 	memset(dev->resp, 0, IO_BUFFER_LENGTH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  515) 	dev->comid = OPAL_DISCOVERY_COMID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  516) 	ret = opal_recv_cmd(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  517) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  518) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  519) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  520) 	return opal_discovery0_end(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  521) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  522) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  523) static int opal_discovery0_step(struct opal_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  524) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  525) 	const struct opal_step discovery0_step = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  526) 		opal_discovery0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  527) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  528) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  529) 	return execute_step(dev, &discovery0_step, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  530) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  531) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  532) static size_t remaining_size(struct opal_dev *cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  533) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  534) 	return IO_BUFFER_LENGTH - cmd->pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  535) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  536) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  537) static bool can_add(int *err, struct opal_dev *cmd, size_t len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  538) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  539) 	if (*err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  540) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  541) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  542) 	if (remaining_size(cmd) < len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  543) 		pr_debug("Error adding %zu bytes: end of buffer.\n", len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  544) 		*err = -ERANGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  545) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  546) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  547) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  548) 	return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  549) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  550) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  551) static void add_token_u8(int *err, struct opal_dev *cmd, u8 tok)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  552) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  553) 	if (!can_add(err, cmd, 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  554) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  555) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  556) 	cmd->cmd[cmd->pos++] = tok;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  557) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  558) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  559) static void add_short_atom_header(struct opal_dev *cmd, bool bytestring,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  560) 				  bool has_sign, int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  561) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  562) 	u8 atom;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  563) 	int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  564) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  565) 	atom = SHORT_ATOM_ID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  566) 	atom |= bytestring ? SHORT_ATOM_BYTESTRING : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  567) 	atom |= has_sign ? SHORT_ATOM_SIGNED : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  568) 	atom |= len & SHORT_ATOM_LEN_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  569) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  570) 	add_token_u8(&err, cmd, atom);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  571) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  572) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  573) static void add_medium_atom_header(struct opal_dev *cmd, bool bytestring,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  574) 				   bool has_sign, int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  575) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  576) 	u8 header0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  577) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  578) 	header0 = MEDIUM_ATOM_ID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  579) 	header0 |= bytestring ? MEDIUM_ATOM_BYTESTRING : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  580) 	header0 |= has_sign ? MEDIUM_ATOM_SIGNED : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  581) 	header0 |= (len >> 8) & MEDIUM_ATOM_LEN_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  582) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  583) 	cmd->cmd[cmd->pos++] = header0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  584) 	cmd->cmd[cmd->pos++] = len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  585) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  586) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  587) static void add_token_u64(int *err, struct opal_dev *cmd, u64 number)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  588) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  589) 	size_t len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  590) 	int msb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  591) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  592) 	if (!(number & ~TINY_ATOM_DATA_MASK)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  593) 		add_token_u8(err, cmd, number);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  594) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  595) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  596) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  597) 	msb = fls64(number);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  598) 	len = DIV_ROUND_UP(msb, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  599) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  600) 	if (!can_add(err, cmd, len + 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  601) 		pr_debug("Error adding u64: end of buffer.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  602) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  603) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  604) 	add_short_atom_header(cmd, false, false, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  605) 	while (len--)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  606) 		add_token_u8(err, cmd, number >> (len * 8));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  607) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  608) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  609) static u8 *add_bytestring_header(int *err, struct opal_dev *cmd, size_t len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  610) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  611) 	size_t header_len = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  612) 	bool is_short_atom = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  613) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  614) 	if (len & ~SHORT_ATOM_LEN_MASK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  615) 		header_len = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  616) 		is_short_atom = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  617) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  618) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  619) 	if (!can_add(err, cmd, header_len + len)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  620) 		pr_debug("Error adding bytestring: end of buffer.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  621) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  622) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  623) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  624) 	if (is_short_atom)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  625) 		add_short_atom_header(cmd, true, false, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  626) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  627) 		add_medium_atom_header(cmd, true, false, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  628) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  629) 	return &cmd->cmd[cmd->pos];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  630) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  631) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  632) static void add_token_bytestring(int *err, struct opal_dev *cmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  633) 				 const u8 *bytestring, size_t len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  634) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  635) 	u8 *start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  636) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  637) 	start = add_bytestring_header(err, cmd, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  638) 	if (!start)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  639) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  640) 	memcpy(start, bytestring, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  641) 	cmd->pos += len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  642) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  643) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  644) static int build_locking_range(u8 *buffer, size_t length, u8 lr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  645) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  646) 	if (length > OPAL_UID_LENGTH) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  647) 		pr_debug("Can't build locking range. Length OOB\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  648) 		return -ERANGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  649) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  650) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  651) 	memcpy(buffer, opaluid[OPAL_LOCKINGRANGE_GLOBAL], OPAL_UID_LENGTH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  652) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  653) 	if (lr == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  654) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  655) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  656) 	buffer[5] = LOCKING_RANGE_NON_GLOBAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  657) 	buffer[7] = lr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  658) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  659) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  660) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  661) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  662) static int build_locking_user(u8 *buffer, size_t length, u8 lr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  663) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  664) 	if (length > OPAL_UID_LENGTH) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  665) 		pr_debug("Can't build locking range user. Length OOB\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  666) 		return -ERANGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  667) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  668) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  669) 	memcpy(buffer, opaluid[OPAL_USER1_UID], OPAL_UID_LENGTH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  670) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  671) 	buffer[7] = lr + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  672) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  673) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  674) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  675) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  676) static void set_comid(struct opal_dev *cmd, u16 comid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  677) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  678) 	struct opal_header *hdr = (struct opal_header *)cmd->cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  679) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  680) 	hdr->cp.extendedComID[0] = comid >> 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  681) 	hdr->cp.extendedComID[1] = comid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  682) 	hdr->cp.extendedComID[2] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  683) 	hdr->cp.extendedComID[3] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  684) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  685) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  686) static int cmd_finalize(struct opal_dev *cmd, u32 hsn, u32 tsn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  687) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  688) 	struct opal_header *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  689) 	int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  690) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  691) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  692) 	 * Close the parameter list opened from cmd_start.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  693) 	 * The number of bytes added must be equal to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  694) 	 * CMD_FINALIZE_BYTES_NEEDED.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  695) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  696) 	add_token_u8(&err, cmd, OPAL_ENDLIST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  697) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  698) 	add_token_u8(&err, cmd, OPAL_ENDOFDATA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  699) 	add_token_u8(&err, cmd, OPAL_STARTLIST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  700) 	add_token_u8(&err, cmd, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  701) 	add_token_u8(&err, cmd, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  702) 	add_token_u8(&err, cmd, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  703) 	add_token_u8(&err, cmd, OPAL_ENDLIST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  704) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  705) 	if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  706) 		pr_debug("Error finalizing command.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  707) 		return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  708) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  709) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  710) 	hdr = (struct opal_header *) cmd->cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  711) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  712) 	hdr->pkt.tsn = cpu_to_be32(tsn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  713) 	hdr->pkt.hsn = cpu_to_be32(hsn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  714) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  715) 	hdr->subpkt.length = cpu_to_be32(cmd->pos - sizeof(*hdr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  716) 	while (cmd->pos % 4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  717) 		if (cmd->pos >= IO_BUFFER_LENGTH) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  718) 			pr_debug("Error: Buffer overrun\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  719) 			return -ERANGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  720) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  721) 		cmd->cmd[cmd->pos++] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  722) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  723) 	hdr->pkt.length = cpu_to_be32(cmd->pos - sizeof(hdr->cp) -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  724) 				      sizeof(hdr->pkt));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  725) 	hdr->cp.length = cpu_to_be32(cmd->pos - sizeof(hdr->cp));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  726) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  727) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  728) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  729) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  730) static const struct opal_resp_tok *response_get_token(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  731) 				const struct parsed_resp *resp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  732) 				int n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  733) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  734) 	const struct opal_resp_tok *tok;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  735) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  736) 	if (!resp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  737) 		pr_debug("Response is NULL\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  738) 		return ERR_PTR(-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  739) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  740) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  741) 	if (n >= resp->num) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  742) 		pr_debug("Token number doesn't exist: %d, resp: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  743) 			 n, resp->num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  744) 		return ERR_PTR(-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  745) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  746) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  747) 	tok = &resp->toks[n];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  748) 	if (tok->len == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  749) 		pr_debug("Token length must be non-zero\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  750) 		return ERR_PTR(-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  751) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  752) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  753) 	return tok;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  754) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  755) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  756) static ssize_t response_parse_tiny(struct opal_resp_tok *tok,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  757) 				   const u8 *pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  758) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  759) 	tok->pos = pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  760) 	tok->len = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  761) 	tok->width = OPAL_WIDTH_TINY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  762) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  763) 	if (pos[0] & TINY_ATOM_SIGNED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  764) 		tok->type = OPAL_DTA_TOKENID_SINT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  765) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  766) 		tok->type = OPAL_DTA_TOKENID_UINT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  767) 		tok->stored.u = pos[0] & 0x3f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  768) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  769) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  770) 	return tok->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  771) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  772) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  773) static ssize_t response_parse_short(struct opal_resp_tok *tok,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  774) 				    const u8 *pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  775) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  776) 	tok->pos = pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  777) 	tok->len = (pos[0] & SHORT_ATOM_LEN_MASK) + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  778) 	tok->width = OPAL_WIDTH_SHORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  779) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  780) 	if (pos[0] & SHORT_ATOM_BYTESTRING) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  781) 		tok->type = OPAL_DTA_TOKENID_BYTESTRING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  782) 	} else if (pos[0] & SHORT_ATOM_SIGNED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  783) 		tok->type = OPAL_DTA_TOKENID_SINT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  784) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  785) 		u64 u_integer = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  786) 		ssize_t i, b = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  787) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  788) 		tok->type = OPAL_DTA_TOKENID_UINT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  789) 		if (tok->len > 9) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  790) 			pr_debug("uint64 with more than 8 bytes\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  791) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  792) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  793) 		for (i = tok->len - 1; i > 0; i--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  794) 			u_integer |= ((u64)pos[i] << (8 * b));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  795) 			b++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  796) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  797) 		tok->stored.u = u_integer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  798) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  799) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  800) 	return tok->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  801) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  802) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  803) static ssize_t response_parse_medium(struct opal_resp_tok *tok,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  804) 				     const u8 *pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  805) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  806) 	tok->pos = pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  807) 	tok->len = (((pos[0] & MEDIUM_ATOM_LEN_MASK) << 8) | pos[1]) + 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  808) 	tok->width = OPAL_WIDTH_MEDIUM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  809) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  810) 	if (pos[0] & MEDIUM_ATOM_BYTESTRING)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  811) 		tok->type = OPAL_DTA_TOKENID_BYTESTRING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  812) 	else if (pos[0] & MEDIUM_ATOM_SIGNED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  813) 		tok->type = OPAL_DTA_TOKENID_SINT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  814) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  815) 		tok->type = OPAL_DTA_TOKENID_UINT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  816) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  817) 	return tok->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  818) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  819) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  820) static ssize_t response_parse_long(struct opal_resp_tok *tok,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  821) 				   const u8 *pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  822) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  823) 	tok->pos = pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  824) 	tok->len = ((pos[1] << 16) | (pos[2] << 8) | pos[3]) + 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  825) 	tok->width = OPAL_WIDTH_LONG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  826) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  827) 	if (pos[0] & LONG_ATOM_BYTESTRING)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  828) 		tok->type = OPAL_DTA_TOKENID_BYTESTRING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  829) 	else if (pos[0] & LONG_ATOM_SIGNED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  830) 		tok->type = OPAL_DTA_TOKENID_SINT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  831) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  832) 		tok->type = OPAL_DTA_TOKENID_UINT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  833) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  834) 	return tok->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  835) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  836) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  837) static ssize_t response_parse_token(struct opal_resp_tok *tok,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  838) 				    const u8 *pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  839) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  840) 	tok->pos = pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  841) 	tok->len = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  842) 	tok->type = OPAL_DTA_TOKENID_TOKEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  843) 	tok->width = OPAL_WIDTH_TOKEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  844) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  845) 	return tok->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  846) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  847) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  848) static int response_parse(const u8 *buf, size_t length,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  849) 			  struct parsed_resp *resp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  850) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  851) 	const struct opal_header *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  852) 	struct opal_resp_tok *iter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  853) 	int num_entries = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  854) 	int total;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  855) 	ssize_t token_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  856) 	const u8 *pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  857) 	u32 clen, plen, slen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  858) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  859) 	if (!buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  860) 		return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  861) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  862) 	if (!resp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  863) 		return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  864) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  865) 	hdr = (struct opal_header *)buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  866) 	pos = buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  867) 	pos += sizeof(*hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  868) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  869) 	clen = be32_to_cpu(hdr->cp.length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  870) 	plen = be32_to_cpu(hdr->pkt.length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  871) 	slen = be32_to_cpu(hdr->subpkt.length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  872) 	pr_debug("Response size: cp: %u, pkt: %u, subpkt: %u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  873) 		 clen, plen, slen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  874) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  875) 	if (clen == 0 || plen == 0 || slen == 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  876) 	    slen > IO_BUFFER_LENGTH - sizeof(*hdr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  877) 		pr_debug("Bad header length. cp: %u, pkt: %u, subpkt: %u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  878) 			 clen, plen, slen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  879) 		print_buffer(pos, sizeof(*hdr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  880) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  881) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  882) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  883) 	if (pos > buf + length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  884) 		return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  885) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  886) 	iter = resp->toks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  887) 	total = slen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  888) 	print_buffer(pos, total);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  889) 	while (total > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  890) 		if (pos[0] <= TINY_ATOM_BYTE) /* tiny atom */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  891) 			token_length = response_parse_tiny(iter, pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  892) 		else if (pos[0] <= SHORT_ATOM_BYTE) /* short atom */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  893) 			token_length = response_parse_short(iter, pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  894) 		else if (pos[0] <= MEDIUM_ATOM_BYTE) /* medium atom */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  895) 			token_length = response_parse_medium(iter, pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  896) 		else if (pos[0] <= LONG_ATOM_BYTE) /* long atom */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  897) 			token_length = response_parse_long(iter, pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  898) 		else /* TOKEN */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  899) 			token_length = response_parse_token(iter, pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  900) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  901) 		if (token_length < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  902) 			return token_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  903) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  904) 		pos += token_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  905) 		total -= token_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  906) 		iter++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  907) 		num_entries++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  908) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  909) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  910) 	resp->num = num_entries;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  911) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  912) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  913) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  914) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  915) static size_t response_get_string(const struct parsed_resp *resp, int n,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  916) 				  const char **store)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  917) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  918) 	u8 skip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  919) 	const struct opal_resp_tok *tok;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  920) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  921) 	*store = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  922) 	tok = response_get_token(resp, n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  923) 	if (IS_ERR(tok))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  924) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  925) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  926) 	if (tok->type != OPAL_DTA_TOKENID_BYTESTRING) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  927) 		pr_debug("Token is not a byte string!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  928) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  929) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  930) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  931) 	switch (tok->width) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  932) 	case OPAL_WIDTH_TINY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  933) 	case OPAL_WIDTH_SHORT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  934) 		skip = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  935) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  936) 	case OPAL_WIDTH_MEDIUM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  937) 		skip = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  938) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  939) 	case OPAL_WIDTH_LONG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  940) 		skip = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  941) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  942) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  943) 		pr_debug("Token has invalid width!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  944) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  945) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  946) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  947) 	*store = tok->pos + skip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  948) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  949) 	return tok->len - skip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  950) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  951) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  952) static u64 response_get_u64(const struct parsed_resp *resp, int n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  953) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  954) 	const struct opal_resp_tok *tok;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  955) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  956) 	tok = response_get_token(resp, n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  957) 	if (IS_ERR(tok))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  958) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  959) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  960) 	if (tok->type != OPAL_DTA_TOKENID_UINT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  961) 		pr_debug("Token is not unsigned int: %d\n", tok->type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  962) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  963) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  964) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  965) 	if (tok->width != OPAL_WIDTH_TINY && tok->width != OPAL_WIDTH_SHORT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  966) 		pr_debug("Atom is not short or tiny: %d\n", tok->width);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  967) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  968) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  969) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  970) 	return tok->stored.u;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  971) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  972) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  973) static bool response_token_matches(const struct opal_resp_tok *token, u8 match)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  974) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  975) 	if (IS_ERR(token) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  976) 	    token->type != OPAL_DTA_TOKENID_TOKEN ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  977) 	    token->pos[0] != match)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  978) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  979) 	return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  980) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  981) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  982) static u8 response_status(const struct parsed_resp *resp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  983) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  984) 	const struct opal_resp_tok *tok;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  985) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  986) 	tok = response_get_token(resp, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  987) 	if (response_token_matches(tok, OPAL_ENDOFSESSION))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  988) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  989) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  990) 	if (resp->num < 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  991) 		return DTAERROR_NO_METHOD_STATUS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  992) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  993) 	tok = response_get_token(resp, resp->num - 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  994) 	if (!response_token_matches(tok, OPAL_STARTLIST))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  995) 		return DTAERROR_NO_METHOD_STATUS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  996) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  997) 	tok = response_get_token(resp, resp->num - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  998) 	if (!response_token_matches(tok, OPAL_ENDLIST))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  999) 		return DTAERROR_NO_METHOD_STATUS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) 	return response_get_u64(resp, resp->num - 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) /* Parses and checks for errors */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) static int parse_and_check_status(struct opal_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) 	int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) 	print_buffer(dev->cmd, dev->pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) 	error = response_parse(dev->resp, IO_BUFFER_LENGTH, &dev->parsed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) 	if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) 		pr_debug("Couldn't parse response.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) 		return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) 	return response_status(&dev->parsed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) static void clear_opal_cmd(struct opal_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) 	dev->pos = sizeof(struct opal_header);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) 	memset(dev->cmd, 0, IO_BUFFER_LENGTH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) static int cmd_start(struct opal_dev *dev, const u8 *uid, const u8 *method)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) 	int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) 	clear_opal_cmd(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) 	set_comid(dev, dev->comid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) 	add_token_u8(&err, dev, OPAL_CALL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) 	add_token_bytestring(&err, dev, uid, OPAL_UID_LENGTH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) 	add_token_bytestring(&err, dev, method, OPAL_METHOD_LENGTH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) 	 * Every method call is followed by its parameters enclosed within
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) 	 * OPAL_STARTLIST and OPAL_ENDLIST tokens. We automatically open the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) 	 * parameter list here and close it later in cmd_finalize.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) 	add_token_u8(&err, dev, OPAL_STARTLIST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) static int start_opal_session_cont(struct opal_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) 	u32 hsn, tsn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) 	int error = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) 	error = parse_and_check_status(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) 	if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) 		return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) 	hsn = response_get_u64(&dev->parsed, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) 	tsn = response_get_u64(&dev->parsed, 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) 	if (hsn != GENERIC_HOST_SESSION_NUM || tsn < FIRST_TPER_SESSION_NUM) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) 		pr_debug("Couldn't authenticate session\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) 		return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) 	dev->hsn = hsn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) 	dev->tsn = tsn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) static void add_suspend_info(struct opal_dev *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) 			     struct opal_suspend_data *sus)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) 	struct opal_suspend_data *iter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) 	list_for_each_entry(iter, &dev->unlk_lst, node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) 		if (iter->lr == sus->lr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) 			list_del(&iter->node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) 			kfree(iter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) 	list_add_tail(&sus->node, &dev->unlk_lst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) static int end_session_cont(struct opal_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) 	dev->hsn = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) 	dev->tsn = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) 	return parse_and_check_status(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) static int finalize_and_send(struct opal_dev *dev, cont_fn cont)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) 	ret = cmd_finalize(dev, dev->hsn, dev->tsn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) 		pr_debug("Error finalizing command buffer: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) 	print_buffer(dev->cmd, dev->pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) 	return opal_send_recv(dev, cont);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109)  * request @column from table @table on device @dev. On success, the column
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110)  * data will be available in dev->resp->tok[4]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) static int generic_get_column(struct opal_dev *dev, const u8 *table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) 			      u64 column)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) 	err = cmd_start(dev, table, opalmethod[OPAL_GET]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) 	add_token_u8(&err, dev, OPAL_STARTLIST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) 	add_token_u8(&err, dev, OPAL_STARTNAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) 	add_token_u8(&err, dev, OPAL_STARTCOLUMN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) 	add_token_u64(&err, dev, column);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) 	add_token_u8(&err, dev, OPAL_ENDNAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) 	add_token_u8(&err, dev, OPAL_STARTNAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) 	add_token_u8(&err, dev, OPAL_ENDCOLUMN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) 	add_token_u64(&err, dev, column);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) 	add_token_u8(&err, dev, OPAL_ENDNAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) 	add_token_u8(&err, dev, OPAL_ENDLIST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) 	return finalize_and_send(dev, parse_and_check_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140)  * see TCG SAS 5.3.2.3 for a description of the available columns
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142)  * the result is provided in dev->resp->tok[4]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) static int generic_get_table_info(struct opal_dev *dev, const u8 *table_uid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) 				  u64 column)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) 	u8 uid[OPAL_UID_LENGTH];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) 	const unsigned int half = OPAL_UID_LENGTH_HALF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) 	/* sed-opal UIDs can be split in two halves:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) 	 *  first:  actual table index
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) 	 *  second: relative index in the table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) 	 * so we have to get the first half of the OPAL_TABLE_TABLE and use the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) 	 * first part of the target table as relative index into that table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) 	memcpy(uid, opaluid[OPAL_TABLE_TABLE], half);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) 	memcpy(uid + half, table_uid, half);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) 	return generic_get_column(dev, uid, column);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) static int gen_key(struct opal_dev *dev, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) 	u8 uid[OPAL_UID_LENGTH];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) 	memcpy(uid, dev->prev_data, min(sizeof(uid), dev->prev_d_len));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) 	kfree(dev->prev_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) 	dev->prev_data = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) 	err = cmd_start(dev, uid, opalmethod[OPAL_GENKEY]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) 	if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) 		pr_debug("Error building gen key command\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) 	return finalize_and_send(dev, parse_and_check_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) static int get_active_key_cont(struct opal_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) 	const char *activekey;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) 	size_t keylen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) 	int error = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) 	error = parse_and_check_status(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) 	if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) 		return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) 	keylen = response_get_string(&dev->parsed, 4, &activekey);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) 	if (!activekey) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) 		pr_debug("%s: Couldn't extract the Activekey from the response\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) 			 __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) 		return OPAL_INVAL_PARAM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) 	dev->prev_data = kmemdup(activekey, keylen, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) 	if (!dev->prev_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) 	dev->prev_d_len = keylen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) static int get_active_key(struct opal_dev *dev, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) 	u8 uid[OPAL_UID_LENGTH];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) 	u8 *lr = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) 	err = build_locking_range(uid, sizeof(uid), *lr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) 	err = generic_get_column(dev, uid, OPAL_ACTIVEKEY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) 	return get_active_key_cont(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) static int generic_table_write_data(struct opal_dev *dev, const u64 data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) 				    u64 offset, u64 size, const u8 *uid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) 	const u8 __user *src = (u8 __user *)(uintptr_t)data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) 	u8 *dst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) 	u64 len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) 	size_t off = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) 	/* do we fit in the available space? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) 	err = generic_get_table_info(dev, uid, OPAL_TABLE_ROWS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) 	if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) 		pr_debug("Couldn't get the table size\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) 	len = response_get_u64(&dev->parsed, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) 	if (size > len || offset > len - size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) 		pr_debug("Does not fit in the table (%llu vs. %llu)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) 			  offset + size, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) 		return -ENOSPC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) 	/* do the actual transmission(s) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) 	while (off < size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) 		err = cmd_start(dev, uid, opalmethod[OPAL_SET]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) 		add_token_u8(&err, dev, OPAL_STARTNAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) 		add_token_u8(&err, dev, OPAL_WHERE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) 		add_token_u64(&err, dev, offset + off);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) 		add_token_u8(&err, dev, OPAL_ENDNAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) 		add_token_u8(&err, dev, OPAL_STARTNAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) 		add_token_u8(&err, dev, OPAL_VALUES);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) 		 * The bytestring header is either 1 or 2 bytes, so assume 2.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) 		 * There also needs to be enough space to accommodate the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) 		 * trailing OPAL_ENDNAME (1 byte) and tokens added by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) 		 * cmd_finalize.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) 		len = min(remaining_size(dev) - (2+1+CMD_FINALIZE_BYTES_NEEDED),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) 			  (size_t)(size - off));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) 		pr_debug("Write bytes %zu+%llu/%llu\n", off, len, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) 		dst = add_bytestring_header(&err, dev, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) 		if (!dst)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) 		if (copy_from_user(dst, src + off, len)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) 			err = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) 		dev->pos += len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) 		add_token_u8(&err, dev, OPAL_ENDNAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) 		if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) 		err = finalize_and_send(dev, parse_and_check_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) 		if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) 		off += len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) static int generic_lr_enable_disable(struct opal_dev *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) 				     u8 *uid, bool rle, bool wle,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) 				     bool rl, bool wl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) 	err = cmd_start(dev, uid, opalmethod[OPAL_SET]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) 	add_token_u8(&err, dev, OPAL_STARTNAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) 	add_token_u8(&err, dev, OPAL_VALUES);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) 	add_token_u8(&err, dev, OPAL_STARTLIST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) 	add_token_u8(&err, dev, OPAL_STARTNAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) 	add_token_u8(&err, dev, OPAL_READLOCKENABLED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) 	add_token_u8(&err, dev, rle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) 	add_token_u8(&err, dev, OPAL_ENDNAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) 	add_token_u8(&err, dev, OPAL_STARTNAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) 	add_token_u8(&err, dev, OPAL_WRITELOCKENABLED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) 	add_token_u8(&err, dev, wle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) 	add_token_u8(&err, dev, OPAL_ENDNAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) 	add_token_u8(&err, dev, OPAL_STARTNAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) 	add_token_u8(&err, dev, OPAL_READLOCKED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) 	add_token_u8(&err, dev, rl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) 	add_token_u8(&err, dev, OPAL_ENDNAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) 	add_token_u8(&err, dev, OPAL_STARTNAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) 	add_token_u8(&err, dev, OPAL_WRITELOCKED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) 	add_token_u8(&err, dev, wl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) 	add_token_u8(&err, dev, OPAL_ENDNAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) 	add_token_u8(&err, dev, OPAL_ENDLIST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) 	add_token_u8(&err, dev, OPAL_ENDNAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) static inline int enable_global_lr(struct opal_dev *dev, u8 *uid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) 				   struct opal_user_lr_setup *setup)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) 	err = generic_lr_enable_disable(dev, uid, !!setup->RLE, !!setup->WLE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) 					0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) 		pr_debug("Failed to create enable global lr command\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) static int setup_locking_range(struct opal_dev *dev, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) 	u8 uid[OPAL_UID_LENGTH];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) 	struct opal_user_lr_setup *setup = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) 	u8 lr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) 	lr = setup->session.opal_key.lr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) 	err = build_locking_range(uid, sizeof(uid), lr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) 	if (lr == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) 		err = enable_global_lr(dev, uid, setup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) 	else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) 		err = cmd_start(dev, uid, opalmethod[OPAL_SET]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) 		add_token_u8(&err, dev, OPAL_STARTNAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) 		add_token_u8(&err, dev, OPAL_VALUES);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) 		add_token_u8(&err, dev, OPAL_STARTLIST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) 		add_token_u8(&err, dev, OPAL_STARTNAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) 		add_token_u8(&err, dev, OPAL_RANGESTART);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) 		add_token_u64(&err, dev, setup->range_start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) 		add_token_u8(&err, dev, OPAL_ENDNAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) 		add_token_u8(&err, dev, OPAL_STARTNAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) 		add_token_u8(&err, dev, OPAL_RANGELENGTH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) 		add_token_u64(&err, dev, setup->range_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) 		add_token_u8(&err, dev, OPAL_ENDNAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) 		add_token_u8(&err, dev, OPAL_STARTNAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) 		add_token_u8(&err, dev, OPAL_READLOCKENABLED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) 		add_token_u64(&err, dev, !!setup->RLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) 		add_token_u8(&err, dev, OPAL_ENDNAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) 		add_token_u8(&err, dev, OPAL_STARTNAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) 		add_token_u8(&err, dev, OPAL_WRITELOCKENABLED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) 		add_token_u64(&err, dev, !!setup->WLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) 		add_token_u8(&err, dev, OPAL_ENDNAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) 		add_token_u8(&err, dev, OPAL_ENDLIST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) 		add_token_u8(&err, dev, OPAL_ENDNAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) 	if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) 		pr_debug("Error building Setup Locking range command.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) 	return finalize_and_send(dev, parse_and_check_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) static int start_generic_opal_session(struct opal_dev *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) 				      enum opal_uid auth,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) 				      enum opal_uid sp_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) 				      const char *key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) 				      u8 key_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) 	u32 hsn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) 	if (key == NULL && auth != OPAL_ANYBODY_UID)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) 		return OPAL_INVAL_PARAM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) 	hsn = GENERIC_HOST_SESSION_NUM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) 	err = cmd_start(dev, opaluid[OPAL_SMUID_UID],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) 			opalmethod[OPAL_STARTSESSION]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) 	add_token_u64(&err, dev, hsn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) 	add_token_bytestring(&err, dev, opaluid[sp_type], OPAL_UID_LENGTH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) 	add_token_u8(&err, dev, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) 	switch (auth) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) 	case OPAL_ANYBODY_UID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) 	case OPAL_ADMIN1_UID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) 	case OPAL_SID_UID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) 	case OPAL_PSID_UID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) 		add_token_u8(&err, dev, OPAL_STARTNAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) 		add_token_u8(&err, dev, 0); /* HostChallenge */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) 		add_token_bytestring(&err, dev, key, key_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) 		add_token_u8(&err, dev, OPAL_ENDNAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) 		add_token_u8(&err, dev, OPAL_STARTNAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) 		add_token_u8(&err, dev, 3); /* HostSignAuth */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) 		add_token_bytestring(&err, dev, opaluid[auth],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) 				     OPAL_UID_LENGTH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) 		add_token_u8(&err, dev, OPAL_ENDNAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) 		pr_debug("Cannot start Admin SP session with auth %d\n", auth);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) 		return OPAL_INVAL_PARAM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) 	if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) 		pr_debug("Error building start adminsp session command.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) 	return finalize_and_send(dev, start_opal_session_cont);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) static int start_anybodyASP_opal_session(struct opal_dev *dev, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) 	return start_generic_opal_session(dev, OPAL_ANYBODY_UID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) 					  OPAL_ADMINSP_UID, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) static int start_SIDASP_opal_session(struct opal_dev *dev, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) 	const u8 *key = dev->prev_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) 	if (!key) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) 		const struct opal_key *okey = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) 		ret = start_generic_opal_session(dev, OPAL_SID_UID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) 						 OPAL_ADMINSP_UID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) 						 okey->key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) 						 okey->key_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) 		ret = start_generic_opal_session(dev, OPAL_SID_UID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) 						 OPAL_ADMINSP_UID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) 						 key, dev->prev_d_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) 		kfree(key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) 		dev->prev_data = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) static int start_admin1LSP_opal_session(struct opal_dev *dev, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) 	struct opal_key *key = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) 	return start_generic_opal_session(dev, OPAL_ADMIN1_UID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) 					  OPAL_LOCKINGSP_UID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) 					  key->key, key->key_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) static int start_PSID_opal_session(struct opal_dev *dev, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) 	const struct opal_key *okey = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) 	return start_generic_opal_session(dev, OPAL_PSID_UID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) 					  OPAL_ADMINSP_UID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) 					  okey->key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) 					  okey->key_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) static int start_auth_opal_session(struct opal_dev *dev, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) 	struct opal_session_info *session = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) 	u8 lk_ul_user[OPAL_UID_LENGTH];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) 	size_t keylen = session->opal_key.key_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) 	int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) 	u8 *key = session->opal_key.key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) 	u32 hsn = GENERIC_HOST_SESSION_NUM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) 	if (session->sum)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) 		err = build_locking_user(lk_ul_user, sizeof(lk_ul_user),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) 					 session->opal_key.lr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) 	else if (session->who != OPAL_ADMIN1 && !session->sum)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) 		err = build_locking_user(lk_ul_user, sizeof(lk_ul_user),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) 					 session->who - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) 		memcpy(lk_ul_user, opaluid[OPAL_ADMIN1_UID], OPAL_UID_LENGTH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) 	err = cmd_start(dev, opaluid[OPAL_SMUID_UID],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) 			opalmethod[OPAL_STARTSESSION]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) 	add_token_u64(&err, dev, hsn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) 	add_token_bytestring(&err, dev, opaluid[OPAL_LOCKINGSP_UID],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) 			     OPAL_UID_LENGTH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) 	add_token_u8(&err, dev, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) 	add_token_u8(&err, dev, OPAL_STARTNAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) 	add_token_u8(&err, dev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) 	add_token_bytestring(&err, dev, key, keylen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) 	add_token_u8(&err, dev, OPAL_ENDNAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) 	add_token_u8(&err, dev, OPAL_STARTNAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) 	add_token_u8(&err, dev, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) 	add_token_bytestring(&err, dev, lk_ul_user, OPAL_UID_LENGTH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) 	add_token_u8(&err, dev, OPAL_ENDNAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) 	if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) 		pr_debug("Error building STARTSESSION command.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) 	return finalize_and_send(dev, start_opal_session_cont);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) static int revert_tper(struct opal_dev *dev, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) 	err = cmd_start(dev, opaluid[OPAL_ADMINSP_UID],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) 			opalmethod[OPAL_REVERT]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) 	if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) 		pr_debug("Error building REVERT TPER command.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) 	return finalize_and_send(dev, parse_and_check_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) static int internal_activate_user(struct opal_dev *dev, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) 	struct opal_session_info *session = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) 	u8 uid[OPAL_UID_LENGTH];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) 	memcpy(uid, opaluid[OPAL_USER1_UID], OPAL_UID_LENGTH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) 	uid[7] = session->who;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) 	err = cmd_start(dev, uid, opalmethod[OPAL_SET]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) 	add_token_u8(&err, dev, OPAL_STARTNAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) 	add_token_u8(&err, dev, OPAL_VALUES);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) 	add_token_u8(&err, dev, OPAL_STARTLIST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) 	add_token_u8(&err, dev, OPAL_STARTNAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) 	add_token_u8(&err, dev, 5); /* Enabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) 	add_token_u8(&err, dev, OPAL_TRUE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) 	add_token_u8(&err, dev, OPAL_ENDNAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) 	add_token_u8(&err, dev, OPAL_ENDLIST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) 	add_token_u8(&err, dev, OPAL_ENDNAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) 	if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) 		pr_debug("Error building Activate UserN command.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) 	return finalize_and_send(dev, parse_and_check_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) static int erase_locking_range(struct opal_dev *dev, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) 	struct opal_session_info *session = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) 	u8 uid[OPAL_UID_LENGTH];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) 	if (build_locking_range(uid, sizeof(uid), session->opal_key.lr) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) 		return -ERANGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) 	err = cmd_start(dev, uid, opalmethod[OPAL_ERASE]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) 	if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) 		pr_debug("Error building Erase Locking Range Command.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) 	return finalize_and_send(dev, parse_and_check_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) static int set_mbr_done(struct opal_dev *dev, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) 	u8 *mbr_done_tf = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) 	err = cmd_start(dev, opaluid[OPAL_MBRCONTROL],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) 			opalmethod[OPAL_SET]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) 	add_token_u8(&err, dev, OPAL_STARTNAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) 	add_token_u8(&err, dev, OPAL_VALUES);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) 	add_token_u8(&err, dev, OPAL_STARTLIST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) 	add_token_u8(&err, dev, OPAL_STARTNAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) 	add_token_u8(&err, dev, OPAL_MBRDONE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) 	add_token_u8(&err, dev, *mbr_done_tf); /* Done T or F */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) 	add_token_u8(&err, dev, OPAL_ENDNAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) 	add_token_u8(&err, dev, OPAL_ENDLIST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) 	add_token_u8(&err, dev, OPAL_ENDNAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) 	if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) 		pr_debug("Error Building set MBR Done command\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) 	return finalize_and_send(dev, parse_and_check_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) static int set_mbr_enable_disable(struct opal_dev *dev, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) 	u8 *mbr_en_dis = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) 	err = cmd_start(dev, opaluid[OPAL_MBRCONTROL],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) 			opalmethod[OPAL_SET]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) 	add_token_u8(&err, dev, OPAL_STARTNAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) 	add_token_u8(&err, dev, OPAL_VALUES);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) 	add_token_u8(&err, dev, OPAL_STARTLIST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) 	add_token_u8(&err, dev, OPAL_STARTNAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) 	add_token_u8(&err, dev, OPAL_MBRENABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) 	add_token_u8(&err, dev, *mbr_en_dis);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) 	add_token_u8(&err, dev, OPAL_ENDNAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) 	add_token_u8(&err, dev, OPAL_ENDLIST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) 	add_token_u8(&err, dev, OPAL_ENDNAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) 	if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) 		pr_debug("Error Building set MBR done command\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) 	return finalize_and_send(dev, parse_and_check_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) static int write_shadow_mbr(struct opal_dev *dev, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) 	struct opal_shadow_mbr *shadow = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) 	return generic_table_write_data(dev, shadow->data, shadow->offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) 					shadow->size, opaluid[OPAL_MBR]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) static int generic_pw_cmd(u8 *key, size_t key_len, u8 *cpin_uid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) 			  struct opal_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) 	err = cmd_start(dev, cpin_uid, opalmethod[OPAL_SET]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) 	add_token_u8(&err, dev, OPAL_STARTNAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) 	add_token_u8(&err, dev, OPAL_VALUES);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) 	add_token_u8(&err, dev, OPAL_STARTLIST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) 	add_token_u8(&err, dev, OPAL_STARTNAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) 	add_token_u8(&err, dev, OPAL_PIN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) 	add_token_bytestring(&err, dev, key, key_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) 	add_token_u8(&err, dev, OPAL_ENDNAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) 	add_token_u8(&err, dev, OPAL_ENDLIST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) 	add_token_u8(&err, dev, OPAL_ENDNAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) static int set_new_pw(struct opal_dev *dev, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) 	u8 cpin_uid[OPAL_UID_LENGTH];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) 	struct opal_session_info *usr = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) 	memcpy(cpin_uid, opaluid[OPAL_C_PIN_ADMIN1], OPAL_UID_LENGTH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) 	if (usr->who != OPAL_ADMIN1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) 		cpin_uid[5] = 0x03;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) 		if (usr->sum)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) 			cpin_uid[7] = usr->opal_key.lr + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) 			cpin_uid[7] = usr->who;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) 	if (generic_pw_cmd(usr->opal_key.key, usr->opal_key.key_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) 			   cpin_uid, dev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) 		pr_debug("Error building set password command.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) 		return -ERANGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) 	return finalize_and_send(dev, parse_and_check_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) static int set_sid_cpin_pin(struct opal_dev *dev, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) 	u8 cpin_uid[OPAL_UID_LENGTH];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) 	struct opal_key *key = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) 	memcpy(cpin_uid, opaluid[OPAL_C_PIN_SID], OPAL_UID_LENGTH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) 	if (generic_pw_cmd(key->key, key->key_len, cpin_uid, dev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) 		pr_debug("Error building Set SID cpin\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) 		return -ERANGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) 	return finalize_and_send(dev, parse_and_check_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) static int add_user_to_lr(struct opal_dev *dev, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) 	u8 lr_buffer[OPAL_UID_LENGTH];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) 	u8 user_uid[OPAL_UID_LENGTH];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) 	struct opal_lock_unlock *lkul = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) 	memcpy(lr_buffer, opaluid[OPAL_LOCKINGRANGE_ACE_RDLOCKED],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) 	       OPAL_UID_LENGTH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) 	if (lkul->l_state == OPAL_RW)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) 		memcpy(lr_buffer, opaluid[OPAL_LOCKINGRANGE_ACE_WRLOCKED],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) 		       OPAL_UID_LENGTH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) 	lr_buffer[7] = lkul->session.opal_key.lr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) 	memcpy(user_uid, opaluid[OPAL_USER1_UID], OPAL_UID_LENGTH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) 	user_uid[7] = lkul->session.who;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) 	err = cmd_start(dev, lr_buffer, opalmethod[OPAL_SET]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) 	add_token_u8(&err, dev, OPAL_STARTNAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) 	add_token_u8(&err, dev, OPAL_VALUES);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) 	add_token_u8(&err, dev, OPAL_STARTLIST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) 	add_token_u8(&err, dev, OPAL_STARTNAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) 	add_token_u8(&err, dev, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) 	add_token_u8(&err, dev, OPAL_STARTLIST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) 	add_token_u8(&err, dev, OPAL_STARTNAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) 	add_token_bytestring(&err, dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) 			     opaluid[OPAL_HALF_UID_AUTHORITY_OBJ_REF],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) 			     OPAL_UID_LENGTH/2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) 	add_token_bytestring(&err, dev, user_uid, OPAL_UID_LENGTH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) 	add_token_u8(&err, dev, OPAL_ENDNAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) 	add_token_u8(&err, dev, OPAL_STARTNAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) 	add_token_bytestring(&err, dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) 			     opaluid[OPAL_HALF_UID_AUTHORITY_OBJ_REF],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) 			     OPAL_UID_LENGTH/2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) 	add_token_bytestring(&err, dev, user_uid, OPAL_UID_LENGTH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) 	add_token_u8(&err, dev, OPAL_ENDNAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) 	add_token_u8(&err, dev, OPAL_STARTNAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769) 	add_token_bytestring(&err, dev, opaluid[OPAL_HALF_UID_BOOLEAN_ACE],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) 			     OPAL_UID_LENGTH/2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) 	add_token_u8(&err, dev, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) 	add_token_u8(&err, dev, OPAL_ENDNAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) 	add_token_u8(&err, dev, OPAL_ENDLIST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) 	add_token_u8(&err, dev, OPAL_ENDNAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) 	add_token_u8(&err, dev, OPAL_ENDLIST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) 	add_token_u8(&err, dev, OPAL_ENDNAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) 	if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) 		pr_debug("Error building add user to locking range command.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) 	return finalize_and_send(dev, parse_and_check_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) static int lock_unlock_locking_range(struct opal_dev *dev, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) 	u8 lr_buffer[OPAL_UID_LENGTH];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791) 	struct opal_lock_unlock *lkul = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) 	u8 read_locked = 1, write_locked = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) 	int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) 	if (build_locking_range(lr_buffer, sizeof(lr_buffer),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796) 				lkul->session.opal_key.lr) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) 		return -ERANGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799) 	switch (lkul->l_state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800) 	case OPAL_RO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801) 		read_locked = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) 		write_locked = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804) 	case OPAL_RW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805) 		read_locked = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) 		write_locked = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808) 	case OPAL_LK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) 		/* vars are initialized to locked */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812) 		pr_debug("Tried to set an invalid locking state... returning to uland\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) 		return OPAL_INVAL_PARAM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) 	err = cmd_start(dev, lr_buffer, opalmethod[OPAL_SET]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818) 	add_token_u8(&err, dev, OPAL_STARTNAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819) 	add_token_u8(&err, dev, OPAL_VALUES);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820) 	add_token_u8(&err, dev, OPAL_STARTLIST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822) 	add_token_u8(&err, dev, OPAL_STARTNAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823) 	add_token_u8(&err, dev, OPAL_READLOCKED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) 	add_token_u8(&err, dev, read_locked);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) 	add_token_u8(&err, dev, OPAL_ENDNAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827) 	add_token_u8(&err, dev, OPAL_STARTNAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828) 	add_token_u8(&err, dev, OPAL_WRITELOCKED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829) 	add_token_u8(&err, dev, write_locked);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830) 	add_token_u8(&err, dev, OPAL_ENDNAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832) 	add_token_u8(&err, dev, OPAL_ENDLIST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833) 	add_token_u8(&err, dev, OPAL_ENDNAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835) 	if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836) 		pr_debug("Error building SET command.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840) 	return finalize_and_send(dev, parse_and_check_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) static int lock_unlock_locking_range_sum(struct opal_dev *dev, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846) 	u8 lr_buffer[OPAL_UID_LENGTH];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847) 	u8 read_locked = 1, write_locked = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848) 	struct opal_lock_unlock *lkul = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851) 	clear_opal_cmd(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) 	set_comid(dev, dev->comid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854) 	if (build_locking_range(lr_buffer, sizeof(lr_buffer),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) 				lkul->session.opal_key.lr) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856) 		return -ERANGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) 	switch (lkul->l_state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859) 	case OPAL_RO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860) 		read_locked = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861) 		write_locked = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863) 	case OPAL_RW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864) 		read_locked = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865) 		write_locked = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867) 	case OPAL_LK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868) 		/* vars are initialized to locked */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871) 		pr_debug("Tried to set an invalid locking state.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872) 		return OPAL_INVAL_PARAM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874) 	ret = generic_lr_enable_disable(dev, lr_buffer, 1, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875) 					read_locked, write_locked);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878) 		pr_debug("Error building SET command.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882) 	return finalize_and_send(dev, parse_and_check_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885) static int activate_lsp(struct opal_dev *dev, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887) 	struct opal_lr_act *opal_act = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888) 	u8 user_lr[OPAL_UID_LENGTH];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889) 	int err, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891) 	err = cmd_start(dev, opaluid[OPAL_LOCKINGSP_UID],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892) 			opalmethod[OPAL_ACTIVATE]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894) 	if (opal_act->sum) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895) 		err = build_locking_range(user_lr, sizeof(user_lr),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896) 					  opal_act->lr[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897) 		if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898) 			return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900) 		add_token_u8(&err, dev, OPAL_STARTNAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901) 		add_token_u64(&err, dev, OPAL_SUM_SET_LIST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903) 		add_token_u8(&err, dev, OPAL_STARTLIST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904) 		add_token_bytestring(&err, dev, user_lr, OPAL_UID_LENGTH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905) 		for (i = 1; i < opal_act->num_lrs; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906) 			user_lr[7] = opal_act->lr[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907) 			add_token_bytestring(&err, dev, user_lr, OPAL_UID_LENGTH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909) 		add_token_u8(&err, dev, OPAL_ENDLIST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910) 		add_token_u8(&err, dev, OPAL_ENDNAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913) 	if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914) 		pr_debug("Error building Activate LockingSP command.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918) 	return finalize_and_send(dev, parse_and_check_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921) /* Determine if we're in the Manufactured Inactive or Active state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922) static int get_lsp_lifecycle(struct opal_dev *dev, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924) 	u8 lc_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927) 	err = generic_get_column(dev, opaluid[OPAL_LOCKINGSP_UID],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928) 				 OPAL_LIFECYCLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932) 	lc_status = response_get_u64(&dev->parsed, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933) 	/* 0x08 is Manufactured Inactive */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934) 	/* 0x09 is Manufactured */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935) 	if (lc_status != OPAL_MANUFACTURED_INACTIVE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936) 		pr_debug("Couldn't determine the status of the Lifecycle state\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943) static int get_msid_cpin_pin(struct opal_dev *dev, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945) 	const char *msid_pin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946) 	size_t strlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1949) 	err = generic_get_column(dev, opaluid[OPAL_C_PIN_MSID], OPAL_PIN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1950) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1951) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1952) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1953) 	strlen = response_get_string(&dev->parsed, 4, &msid_pin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1954) 	if (!msid_pin) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1955) 		pr_debug("Couldn't extract MSID_CPIN from response\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1956) 		return OPAL_INVAL_PARAM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1957) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1958) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1959) 	dev->prev_data = kmemdup(msid_pin, strlen, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1960) 	if (!dev->prev_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1961) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1962) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1963) 	dev->prev_d_len = strlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1964) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1965) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1966) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1967) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1968) static int write_table_data(struct opal_dev *dev, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1969) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1970) 	struct opal_read_write_table *write_tbl = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1971) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1972) 	return generic_table_write_data(dev, write_tbl->data, write_tbl->offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1973) 					write_tbl->size, write_tbl->table_uid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1974) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1975) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1976) static int read_table_data_cont(struct opal_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1977) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1978) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1979) 	const char *data_read;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1980) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1981) 	err = parse_and_check_status(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1982) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1983) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1984) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1985) 	dev->prev_d_len = response_get_string(&dev->parsed, 1, &data_read);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1986) 	dev->prev_data = (void *)data_read;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1987) 	if (!dev->prev_data) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1988) 		pr_debug("%s: Couldn't read data from the table.\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1989) 		return OPAL_INVAL_PARAM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1990) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1991) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1992) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1993) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1994) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1995) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1996)  * IO_BUFFER_LENGTH = 2048
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1997)  * sizeof(header) = 56
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1998)  * No. of Token Bytes in the Response = 11
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1999)  * MAX size of data that can be carried in response buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2000)  * at a time is : 2048 - (56 + 11) = 1981 = 0x7BD.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2001)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2002) #define OPAL_MAX_READ_TABLE (0x7BD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2003) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2004) static int read_table_data(struct opal_dev *dev, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2005) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2006) 	struct opal_read_write_table *read_tbl = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2007) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2008) 	size_t off = 0, max_read_size = OPAL_MAX_READ_TABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2009) 	u64 table_len, len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2010) 	u64 offset = read_tbl->offset, read_size = read_tbl->size - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2011) 	u8 __user *dst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2012) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2013) 	err = generic_get_table_info(dev, read_tbl->table_uid, OPAL_TABLE_ROWS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2014) 	if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2015) 		pr_debug("Couldn't get the table size\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2016) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2017) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2018) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2019) 	table_len = response_get_u64(&dev->parsed, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2020) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2021) 	/* Check if the user is trying to read from the table limits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2022) 	if (read_size > table_len || offset > table_len - read_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2023) 		pr_debug("Read size exceeds the Table size limits (%llu vs. %llu)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2024) 			  offset + read_size, table_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2025) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2026) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2027) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2028) 	while (off < read_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2029) 		err = cmd_start(dev, read_tbl->table_uid, opalmethod[OPAL_GET]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2030) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2031) 		add_token_u8(&err, dev, OPAL_STARTLIST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2032) 		add_token_u8(&err, dev, OPAL_STARTNAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2033) 		add_token_u8(&err, dev, OPAL_STARTROW);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2034) 		add_token_u64(&err, dev, offset + off); /* start row value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2035) 		add_token_u8(&err, dev, OPAL_ENDNAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2036) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2037) 		add_token_u8(&err, dev, OPAL_STARTNAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2038) 		add_token_u8(&err, dev, OPAL_ENDROW);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2039) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2040) 		len = min(max_read_size, (size_t)(read_size - off));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2041) 		add_token_u64(&err, dev, offset + off + len); /* end row value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2042) 							       */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2043) 		add_token_u8(&err, dev, OPAL_ENDNAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2044) 		add_token_u8(&err, dev, OPAL_ENDLIST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2045) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2046) 		if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2047) 			pr_debug("Error building read table data command.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2048) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2049) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2050) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2051) 		err = finalize_and_send(dev, read_table_data_cont);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2052) 		if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2053) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2054) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2055) 		/* len+1: This includes the NULL terminator at the end*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2056) 		if (dev->prev_d_len > len + 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2057) 			err = -EOVERFLOW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2058) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2059) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2060) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2061) 		dst = (u8 __user *)(uintptr_t)read_tbl->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2062) 		if (copy_to_user(dst + off, dev->prev_data, dev->prev_d_len)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2063) 			pr_debug("Error copying data to userspace\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2064) 			err = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2065) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2066) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2067) 		dev->prev_data = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2068) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2069) 		off += len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2070) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2071) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2072) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2073) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2074) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2075) static int end_opal_session(struct opal_dev *dev, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2076) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2077) 	int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2078) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2079) 	clear_opal_cmd(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2080) 	set_comid(dev, dev->comid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2081) 	add_token_u8(&err, dev, OPAL_ENDOFSESSION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2082) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2083) 	if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2084) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2085) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2086) 	return finalize_and_send(dev, end_session_cont);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2087) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2088) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2089) static int end_opal_session_error(struct opal_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2090) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2091) 	const struct opal_step error_end_session = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2092) 		end_opal_session,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2093) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2094) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2095) 	return execute_step(dev, &error_end_session, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2096) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2097) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2098) static inline void setup_opal_dev(struct opal_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2099) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2100) 	dev->tsn = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2101) 	dev->hsn = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2102) 	dev->prev_data = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2103) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2104) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2105) static int check_opal_support(struct opal_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2106) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2107) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2108) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2109) 	mutex_lock(&dev->dev_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2110) 	setup_opal_dev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2111) 	ret = opal_discovery0_step(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2112) 	dev->supported = !ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2113) 	mutex_unlock(&dev->dev_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2114) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2115) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2116) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2117) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2118) static void clean_opal_dev(struct opal_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2119) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2120) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2121) 	struct opal_suspend_data *suspend, *next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2122) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2123) 	mutex_lock(&dev->dev_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2124) 	list_for_each_entry_safe(suspend, next, &dev->unlk_lst, node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2125) 		list_del(&suspend->node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2126) 		kfree(suspend);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2127) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2128) 	mutex_unlock(&dev->dev_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2129) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2130) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2131) void free_opal_dev(struct opal_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2132) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2133) 	if (!dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2134) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2135) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2136) 	clean_opal_dev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2137) 	kfree(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2138) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2139) EXPORT_SYMBOL(free_opal_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2140) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2141) struct opal_dev *init_opal_dev(void *data, sec_send_recv *send_recv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2142) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2143) 	struct opal_dev *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2144) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2145) 	dev = kmalloc(sizeof(*dev), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2146) 	if (!dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2147) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2148) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2149) 	INIT_LIST_HEAD(&dev->unlk_lst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2150) 	mutex_init(&dev->dev_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2151) 	dev->data = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2152) 	dev->send_recv = send_recv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2153) 	if (check_opal_support(dev) != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2154) 		pr_debug("Opal is not supported on this device\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2155) 		kfree(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2156) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2157) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2158) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2159) 	return dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2160) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2161) EXPORT_SYMBOL(init_opal_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2162) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2163) static int opal_secure_erase_locking_range(struct opal_dev *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2164) 					   struct opal_session_info *opal_session)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2165) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2166) 	const struct opal_step erase_steps[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2167) 		{ start_auth_opal_session, opal_session },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2168) 		{ get_active_key, &opal_session->opal_key.lr },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2169) 		{ gen_key, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2170) 		{ end_opal_session, }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2171) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2172) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2173) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2174) 	mutex_lock(&dev->dev_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2175) 	setup_opal_dev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2176) 	ret = execute_steps(dev, erase_steps, ARRAY_SIZE(erase_steps));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2177) 	mutex_unlock(&dev->dev_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2178) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2179) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2180) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2181) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2182) static int opal_erase_locking_range(struct opal_dev *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2183) 				    struct opal_session_info *opal_session)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2184) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2185) 	const struct opal_step erase_steps[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2186) 		{ start_auth_opal_session, opal_session },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2187) 		{ erase_locking_range, opal_session },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2188) 		{ end_opal_session, }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2189) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2190) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2191) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2192) 	mutex_lock(&dev->dev_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2193) 	setup_opal_dev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2194) 	ret = execute_steps(dev, erase_steps, ARRAY_SIZE(erase_steps));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2195) 	mutex_unlock(&dev->dev_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2196) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2197) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2198) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2199) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2200) static int opal_enable_disable_shadow_mbr(struct opal_dev *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2201) 					  struct opal_mbr_data *opal_mbr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2202) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2203) 	u8 enable_disable = opal_mbr->enable_disable == OPAL_MBR_ENABLE ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2204) 		OPAL_TRUE : OPAL_FALSE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2205) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2206) 	const struct opal_step mbr_steps[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2207) 		{ start_admin1LSP_opal_session, &opal_mbr->key },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2208) 		{ set_mbr_done, &enable_disable },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2209) 		{ end_opal_session, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2210) 		{ start_admin1LSP_opal_session, &opal_mbr->key },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2211) 		{ set_mbr_enable_disable, &enable_disable },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2212) 		{ end_opal_session, }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2213) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2214) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2215) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2216) 	if (opal_mbr->enable_disable != OPAL_MBR_ENABLE &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2217) 	    opal_mbr->enable_disable != OPAL_MBR_DISABLE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2218) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2219) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2220) 	mutex_lock(&dev->dev_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2221) 	setup_opal_dev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2222) 	ret = execute_steps(dev, mbr_steps, ARRAY_SIZE(mbr_steps));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2223) 	mutex_unlock(&dev->dev_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2224) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2225) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2226) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2227) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2228) static int opal_set_mbr_done(struct opal_dev *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2229) 			     struct opal_mbr_done *mbr_done)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2230) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2231) 	u8 mbr_done_tf = mbr_done->done_flag == OPAL_MBR_DONE ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2232) 		OPAL_TRUE : OPAL_FALSE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2233) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2234) 	const struct opal_step mbr_steps[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2235) 		{ start_admin1LSP_opal_session, &mbr_done->key },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2236) 		{ set_mbr_done, &mbr_done_tf },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2237) 		{ end_opal_session, }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2238) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2239) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2240) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2241) 	if (mbr_done->done_flag != OPAL_MBR_DONE &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2242) 	    mbr_done->done_flag != OPAL_MBR_NOT_DONE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2243) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2244) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2245) 	mutex_lock(&dev->dev_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2246) 	setup_opal_dev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2247) 	ret = execute_steps(dev, mbr_steps, ARRAY_SIZE(mbr_steps));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2248) 	mutex_unlock(&dev->dev_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2249) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2250) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2251) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2252) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2253) static int opal_write_shadow_mbr(struct opal_dev *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2254) 				 struct opal_shadow_mbr *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2255) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2256) 	const struct opal_step mbr_steps[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2257) 		{ start_admin1LSP_opal_session, &info->key },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2258) 		{ write_shadow_mbr, info },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2259) 		{ end_opal_session, }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2260) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2261) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2262) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2263) 	if (info->size == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2264) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2265) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2266) 	mutex_lock(&dev->dev_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2267) 	setup_opal_dev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2268) 	ret = execute_steps(dev, mbr_steps, ARRAY_SIZE(mbr_steps));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2269) 	mutex_unlock(&dev->dev_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2270) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2271) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2272) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2273) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2274) static int opal_save(struct opal_dev *dev, struct opal_lock_unlock *lk_unlk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2275) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2276) 	struct opal_suspend_data *suspend;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2277) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2278) 	suspend = kzalloc(sizeof(*suspend), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2279) 	if (!suspend)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2280) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2281) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2282) 	suspend->unlk = *lk_unlk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2283) 	suspend->lr = lk_unlk->session.opal_key.lr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2284) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2285) 	mutex_lock(&dev->dev_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2286) 	setup_opal_dev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2287) 	add_suspend_info(dev, suspend);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2288) 	mutex_unlock(&dev->dev_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2289) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2290) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2291) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2292) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2293) static int opal_add_user_to_lr(struct opal_dev *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2294) 			       struct opal_lock_unlock *lk_unlk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2295) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2296) 	const struct opal_step steps[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2297) 		{ start_admin1LSP_opal_session, &lk_unlk->session.opal_key },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2298) 		{ add_user_to_lr, lk_unlk },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2299) 		{ end_opal_session, }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2300) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2301) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2302) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2303) 	if (lk_unlk->l_state != OPAL_RO &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2304) 	    lk_unlk->l_state != OPAL_RW) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2305) 		pr_debug("Locking state was not RO or RW\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2306) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2307) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2308) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2309) 	if (lk_unlk->session.who < OPAL_USER1 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2310) 	    lk_unlk->session.who > OPAL_USER9) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2311) 		pr_debug("Authority was not within the range of users: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2312) 			 lk_unlk->session.who);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2313) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2314) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2315) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2316) 	if (lk_unlk->session.sum) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2317) 		pr_debug("%s not supported in sum. Use setup locking range\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2318) 			 __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2319) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2320) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2321) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2322) 	mutex_lock(&dev->dev_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2323) 	setup_opal_dev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2324) 	ret = execute_steps(dev, steps, ARRAY_SIZE(steps));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2325) 	mutex_unlock(&dev->dev_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2326) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2327) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2328) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2329) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2330) static int opal_reverttper(struct opal_dev *dev, struct opal_key *opal, bool psid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2331) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2332) 	/* controller will terminate session */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2333) 	const struct opal_step revert_steps[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2334) 		{ start_SIDASP_opal_session, opal },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2335) 		{ revert_tper, }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2336) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2337) 	const struct opal_step psid_revert_steps[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2338) 		{ start_PSID_opal_session, opal },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2339) 		{ revert_tper, }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2340) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2341) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2342) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2343) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2344) 	mutex_lock(&dev->dev_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2345) 	setup_opal_dev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2346) 	if (psid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2347) 		ret = execute_steps(dev, psid_revert_steps,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2348) 				    ARRAY_SIZE(psid_revert_steps));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2349) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2350) 		ret = execute_steps(dev, revert_steps,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2351) 				    ARRAY_SIZE(revert_steps));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2352) 	mutex_unlock(&dev->dev_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2353) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2354) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2355) 	 * If we successfully reverted lets clean
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2356) 	 * any saved locking ranges.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2357) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2358) 	if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2359) 		clean_opal_dev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2360) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2361) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2362) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2363) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2364) static int __opal_lock_unlock(struct opal_dev *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2365) 			      struct opal_lock_unlock *lk_unlk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2366) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2367) 	const struct opal_step unlock_steps[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2368) 		{ start_auth_opal_session, &lk_unlk->session },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2369) 		{ lock_unlock_locking_range, lk_unlk },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2370) 		{ end_opal_session, }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2371) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2372) 	const struct opal_step unlock_sum_steps[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2373) 		{ start_auth_opal_session, &lk_unlk->session },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2374) 		{ lock_unlock_locking_range_sum, lk_unlk },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2375) 		{ end_opal_session, }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2376) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2377) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2378) 	if (lk_unlk->session.sum)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2379) 		return execute_steps(dev, unlock_sum_steps,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2380) 				     ARRAY_SIZE(unlock_sum_steps));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2381) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2382) 		return execute_steps(dev, unlock_steps,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2383) 				     ARRAY_SIZE(unlock_steps));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2384) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2385) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2386) static int __opal_set_mbr_done(struct opal_dev *dev, struct opal_key *key)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2387) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2388) 	u8 mbr_done_tf = OPAL_TRUE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2389) 	const struct opal_step mbrdone_step[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2390) 		{ start_admin1LSP_opal_session, key },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2391) 		{ set_mbr_done, &mbr_done_tf },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2392) 		{ end_opal_session, }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2393) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2394) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2395) 	return execute_steps(dev, mbrdone_step, ARRAY_SIZE(mbrdone_step));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2396) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2397) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2398) static int opal_lock_unlock(struct opal_dev *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2399) 			    struct opal_lock_unlock *lk_unlk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2400) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2401) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2402) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2403) 	if (lk_unlk->session.who > OPAL_USER9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2404) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2405) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2406) 	mutex_lock(&dev->dev_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2407) 	ret = __opal_lock_unlock(dev, lk_unlk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2408) 	mutex_unlock(&dev->dev_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2409) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2410) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2411) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2412) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2413) static int opal_take_ownership(struct opal_dev *dev, struct opal_key *opal)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2414) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2415) 	const struct opal_step owner_steps[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2416) 		{ start_anybodyASP_opal_session, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2417) 		{ get_msid_cpin_pin, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2418) 		{ end_opal_session, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2419) 		{ start_SIDASP_opal_session, opal },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2420) 		{ set_sid_cpin_pin, opal },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2421) 		{ end_opal_session, }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2422) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2423) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2424) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2425) 	if (!dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2426) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2427) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2428) 	mutex_lock(&dev->dev_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2429) 	setup_opal_dev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2430) 	ret = execute_steps(dev, owner_steps, ARRAY_SIZE(owner_steps));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2431) 	mutex_unlock(&dev->dev_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2432) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2433) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2434) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2435) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2436) static int opal_activate_lsp(struct opal_dev *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2437) 			     struct opal_lr_act *opal_lr_act)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2438) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2439) 	const struct opal_step active_steps[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2440) 		{ start_SIDASP_opal_session, &opal_lr_act->key },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2441) 		{ get_lsp_lifecycle, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2442) 		{ activate_lsp, opal_lr_act },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2443) 		{ end_opal_session, }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2444) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2445) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2446) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2447) 	if (!opal_lr_act->num_lrs || opal_lr_act->num_lrs > OPAL_MAX_LRS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2448) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2449) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2450) 	mutex_lock(&dev->dev_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2451) 	setup_opal_dev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2452) 	ret = execute_steps(dev, active_steps, ARRAY_SIZE(active_steps));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2453) 	mutex_unlock(&dev->dev_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2454) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2455) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2456) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2457) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2458) static int opal_setup_locking_range(struct opal_dev *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2459) 				    struct opal_user_lr_setup *opal_lrs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2460) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2461) 	const struct opal_step lr_steps[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2462) 		{ start_auth_opal_session, &opal_lrs->session },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2463) 		{ setup_locking_range, opal_lrs },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2464) 		{ end_opal_session, }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2465) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2466) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2467) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2468) 	mutex_lock(&dev->dev_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2469) 	setup_opal_dev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2470) 	ret = execute_steps(dev, lr_steps, ARRAY_SIZE(lr_steps));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2471) 	mutex_unlock(&dev->dev_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2472) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2473) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2474) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2475) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2476) static int opal_set_new_pw(struct opal_dev *dev, struct opal_new_pw *opal_pw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2477) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2478) 	const struct opal_step pw_steps[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2479) 		{ start_auth_opal_session, &opal_pw->session },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2480) 		{ set_new_pw, &opal_pw->new_user_pw },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2481) 		{ end_opal_session, }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2482) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2483) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2484) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2485) 	if (opal_pw->session.who > OPAL_USER9  ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2486) 	    opal_pw->new_user_pw.who > OPAL_USER9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2487) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2488) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2489) 	mutex_lock(&dev->dev_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2490) 	setup_opal_dev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2491) 	ret = execute_steps(dev, pw_steps, ARRAY_SIZE(pw_steps));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2492) 	mutex_unlock(&dev->dev_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2493) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2494) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2495) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2496) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2497) static int opal_activate_user(struct opal_dev *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2498) 			      struct opal_session_info *opal_session)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2499) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2500) 	const struct opal_step act_steps[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2501) 		{ start_admin1LSP_opal_session, &opal_session->opal_key },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2502) 		{ internal_activate_user, opal_session },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2503) 		{ end_opal_session, }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2504) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2505) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2506) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2507) 	/* We can't activate Admin1 it's active as manufactured */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2508) 	if (opal_session->who < OPAL_USER1 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2509) 	    opal_session->who > OPAL_USER9) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2510) 		pr_debug("Who was not a valid user: %d\n", opal_session->who);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2511) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2512) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2513) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2514) 	mutex_lock(&dev->dev_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2515) 	setup_opal_dev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2516) 	ret = execute_steps(dev, act_steps, ARRAY_SIZE(act_steps));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2517) 	mutex_unlock(&dev->dev_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2518) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2519) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2520) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2521) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2522) bool opal_unlock_from_suspend(struct opal_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2523) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2524) 	struct opal_suspend_data *suspend;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2525) 	bool was_failure = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2526) 	int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2527) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2528) 	if (!dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2529) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2530) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2531) 	if (!dev->supported)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2532) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2533) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2534) 	mutex_lock(&dev->dev_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2535) 	setup_opal_dev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2536) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2537) 	list_for_each_entry(suspend, &dev->unlk_lst, node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2538) 		dev->tsn = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2539) 		dev->hsn = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2540) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2541) 		ret = __opal_lock_unlock(dev, &suspend->unlk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2542) 		if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2543) 			pr_debug("Failed to unlock LR %hhu with sum %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2544) 				 suspend->unlk.session.opal_key.lr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2545) 				 suspend->unlk.session.sum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2546) 			was_failure = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2547) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2548) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2549) 		if (dev->mbr_enabled) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2550) 			ret = __opal_set_mbr_done(dev, &suspend->unlk.session.opal_key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2551) 			if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2552) 				pr_debug("Failed to set MBR Done in S3 resume\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2553) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2554) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2555) 	mutex_unlock(&dev->dev_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2556) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2557) 	return was_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2558) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2559) EXPORT_SYMBOL(opal_unlock_from_suspend);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2560) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2561) static int opal_read_table(struct opal_dev *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2562) 			   struct opal_read_write_table *rw_tbl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2563) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2564) 	const struct opal_step read_table_steps[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2565) 		{ start_admin1LSP_opal_session, &rw_tbl->key },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2566) 		{ read_table_data, rw_tbl },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2567) 		{ end_opal_session, }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2568) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2569) 	int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2570) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2571) 	if (!rw_tbl->size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2572) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2573) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2574) 	return execute_steps(dev, read_table_steps,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2575) 			     ARRAY_SIZE(read_table_steps));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2576) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2577) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2578) static int opal_write_table(struct opal_dev *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2579) 			    struct opal_read_write_table *rw_tbl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2580) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2581) 	const struct opal_step write_table_steps[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2582) 		{ start_admin1LSP_opal_session, &rw_tbl->key },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2583) 		{ write_table_data, rw_tbl },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2584) 		{ end_opal_session, }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2585) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2586) 	int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2587) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2588) 	if (!rw_tbl->size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2589) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2590) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2591) 	return execute_steps(dev, write_table_steps,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2592) 			     ARRAY_SIZE(write_table_steps));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2593) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2594) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2595) static int opal_generic_read_write_table(struct opal_dev *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2596) 					 struct opal_read_write_table *rw_tbl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2597) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2598) 	int ret, bit_set;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2599) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2600) 	mutex_lock(&dev->dev_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2601) 	setup_opal_dev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2602) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2603) 	bit_set = fls64(rw_tbl->flags) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2604) 	switch (bit_set) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2605) 	case OPAL_READ_TABLE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2606) 		ret = opal_read_table(dev, rw_tbl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2607) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2608) 	case OPAL_WRITE_TABLE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2609) 		ret = opal_write_table(dev, rw_tbl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2610) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2611) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2612) 		pr_debug("Invalid bit set in the flag (%016llx).\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2613) 			 rw_tbl->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2614) 		ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2615) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2616) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2617) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2618) 	mutex_unlock(&dev->dev_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2619) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2620) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2621) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2622) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2623) int sed_ioctl(struct opal_dev *dev, unsigned int cmd, void __user *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2624) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2625) 	void *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2626) 	int ret = -ENOTTY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2627) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2628) 	if (!capable(CAP_SYS_ADMIN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2629) 		return -EACCES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2630) 	if (!dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2631) 		return -ENOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2632) 	if (!dev->supported)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2633) 		return -ENOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2634) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2635) 	p = memdup_user(arg, _IOC_SIZE(cmd));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2636) 	if (IS_ERR(p))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2637) 		return PTR_ERR(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2638) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2639) 	switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2640) 	case IOC_OPAL_SAVE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2641) 		ret = opal_save(dev, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2642) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2643) 	case IOC_OPAL_LOCK_UNLOCK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2644) 		ret = opal_lock_unlock(dev, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2645) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2646) 	case IOC_OPAL_TAKE_OWNERSHIP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2647) 		ret = opal_take_ownership(dev, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2648) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2649) 	case IOC_OPAL_ACTIVATE_LSP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2650) 		ret = opal_activate_lsp(dev, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2651) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2652) 	case IOC_OPAL_SET_PW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2653) 		ret = opal_set_new_pw(dev, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2654) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2655) 	case IOC_OPAL_ACTIVATE_USR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2656) 		ret = opal_activate_user(dev, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2657) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2658) 	case IOC_OPAL_REVERT_TPR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2659) 		ret = opal_reverttper(dev, p, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2660) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2661) 	case IOC_OPAL_LR_SETUP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2662) 		ret = opal_setup_locking_range(dev, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2663) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2664) 	case IOC_OPAL_ADD_USR_TO_LR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2665) 		ret = opal_add_user_to_lr(dev, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2666) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2667) 	case IOC_OPAL_ENABLE_DISABLE_MBR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2668) 		ret = opal_enable_disable_shadow_mbr(dev, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2669) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2670) 	case IOC_OPAL_MBR_DONE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2671) 		ret = opal_set_mbr_done(dev, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2672) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2673) 	case IOC_OPAL_WRITE_SHADOW_MBR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2674) 		ret = opal_write_shadow_mbr(dev, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2675) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2676) 	case IOC_OPAL_ERASE_LR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2677) 		ret = opal_erase_locking_range(dev, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2678) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2679) 	case IOC_OPAL_SECURE_ERASE_LR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2680) 		ret = opal_secure_erase_locking_range(dev, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2681) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2682) 	case IOC_OPAL_PSID_REVERT_TPR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2683) 		ret = opal_reverttper(dev, p, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2684) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2685) 	case IOC_OPAL_GENERIC_TABLE_RW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2686) 		ret = opal_generic_read_write_table(dev, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2687) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2688) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2689) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2690) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2691) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2692) 	kfree(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2693) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2694) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2695) EXPORT_SYMBOL_GPL(sed_ioctl);