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