^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);