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        u8 n;
 558
 559        if (!(number & ~TINY_ATOM_DATA_MASK)) {
 560                add_token_u8(err, cmd, number);
 561                return;
 562        }
 563
 564        msb = fls(number);
 565        len = DIV_ROUND_UP(msb, 4);
 566
 567        if (cmd->pos >= IO_BUFFER_LENGTH - len - 1) {
 568                pr_debug("Error adding u64: end of buffer.\n");
 569                *err = -ERANGE;
 570                return;
 571        }
 572        add_short_atom_header(cmd, false, false, len);
 573        while (len--) {
 574                n = number >> (len * 8);
 575                add_token_u8(err, cmd, n);
 576        }
 577}
 578
 579static void add_token_bytestring(int *err, struct opal_dev *cmd,
 580                                 const u8 *bytestring, size_t len)
 581{
 582        size_t header_len = 1;
 583        bool is_short_atom = true;
 584
 585        if (*err)
 586                return;
 587
 588        if (len & ~SHORT_ATOM_LEN_MASK) {
 589                header_len = 2;
 590                is_short_atom = false;
 591        }
 592
 593        if (len >= IO_BUFFER_LENGTH - cmd->pos - header_len) {
 594                pr_debug("Error adding bytestring: end of buffer.\n");
 595                *err = -ERANGE;
 596                return;
 597        }
 598
 599        if (is_short_atom)
 600                add_short_atom_header(cmd, true, false, len);
 601        else
 602                add_medium_atom_header(cmd, true, false, len);
 603
 604        memcpy(&cmd->cmd[cmd->pos], bytestring, len);
 605        cmd->pos += len;
 606
 607}
 608
 609static int build_locking_range(u8 *buffer, size_t length, u8 lr)
 610{
 611        if (length > OPAL_UID_LENGTH) {
 612                pr_debug("Can't build locking range. Length OOB\n");
 613                return -ERANGE;
 614        }
 615
 616        memcpy(buffer, opaluid[OPAL_LOCKINGRANGE_GLOBAL], OPAL_UID_LENGTH);
 617
 618        if (lr == 0)
 619                return 0;
 620        buffer[5] = LOCKING_RANGE_NON_GLOBAL;
 621        buffer[7] = lr;
 622
 623        return 0;
 624}
 625
 626static int build_locking_user(u8 *buffer, size_t length, u8 lr)
 627{
 628        if (length > OPAL_UID_LENGTH) {
 629                pr_debug("Can't build locking range user, Length OOB\n");
 630                return -ERANGE;
 631        }
 632
 633        memcpy(buffer, opaluid[OPAL_USER1_UID], OPAL_UID_LENGTH);
 634
 635        buffer[7] = lr + 1;
 636
 637        return 0;
 638}
 639
 640static void set_comid(struct opal_dev *cmd, u16 comid)
 641{
 642        struct opal_header *hdr = (struct opal_header *)cmd->cmd;
 643
 644        hdr->cp.extendedComID[0] = comid >> 8;
 645        hdr->cp.extendedComID[1] = comid;
 646        hdr->cp.extendedComID[2] = 0;
 647        hdr->cp.extendedComID[3] = 0;
 648}
 649
 650static int cmd_finalize(struct opal_dev *cmd, u32 hsn, u32 tsn)
 651{
 652        struct opal_header *hdr;
 653        int err = 0;
 654
 655        add_token_u8(&err, cmd, OPAL_ENDOFDATA);
 656        add_token_u8(&err, cmd, OPAL_STARTLIST);
 657        add_token_u8(&err, cmd, 0);
 658        add_token_u8(&err, cmd, 0);
 659        add_token_u8(&err, cmd, 0);
 660        add_token_u8(&err, cmd, OPAL_ENDLIST);
 661
 662        if (err) {
 663                pr_debug("Error finalizing command.\n");
 664                return -EFAULT;
 665        }
 666
 667        hdr = (struct opal_header *) cmd->cmd;
 668
 669        hdr->pkt.tsn = cpu_to_be32(tsn);
 670        hdr->pkt.hsn = cpu_to_be32(hsn);
 671
 672        hdr->subpkt.length = cpu_to_be32(cmd->pos - sizeof(*hdr));
 673        while (cmd->pos % 4) {
 674                if (cmd->pos >= IO_BUFFER_LENGTH) {
 675                        pr_debug("Error: Buffer overrun\n");
 676                        return -ERANGE;
 677                }
 678                cmd->cmd[cmd->pos++] = 0;
 679        }
 680        hdr->pkt.length = cpu_to_be32(cmd->pos - sizeof(hdr->cp) -
 681                                      sizeof(hdr->pkt));
 682        hdr->cp.length = cpu_to_be32(cmd->pos - sizeof(hdr->cp));
 683
 684        return 0;
 685}
 686
 687static const struct opal_resp_tok *response_get_token(
 688                                const struct parsed_resp *resp,
 689                                int n)
 690{
 691        const struct opal_resp_tok *tok;
 692
 693        if (n >= resp->num) {
 694                pr_debug("Token number doesn't exist: %d, resp: %d\n",
 695                         n, resp->num);
 696                return ERR_PTR(-EINVAL);
 697        }
 698
 699        tok = &resp->toks[n];
 700        if (tok->len == 0) {
 701                pr_debug("Token length must be non-zero\n");
 702                return ERR_PTR(-EINVAL);
 703        }
 704
 705        return tok;
 706}
 707
 708static ssize_t response_parse_tiny(struct opal_resp_tok *tok,
 709                                   const u8 *pos)
 710{
 711        tok->pos = pos;
 712        tok->len = 1;
 713        tok->width = OPAL_WIDTH_TINY;
 714
 715        if (pos[0] & TINY_ATOM_SIGNED) {
 716                tok->type = OPAL_DTA_TOKENID_SINT;
 717        } else {
 718                tok->type = OPAL_DTA_TOKENID_UINT;
 719                tok->stored.u = pos[0] & 0x3f;
 720        }
 721
 722        return tok->len;
 723}
 724
 725static ssize_t response_parse_short(struct opal_resp_tok *tok,
 726                                    const u8 *pos)
 727{
 728        tok->pos = pos;
 729        tok->len = (pos[0] & SHORT_ATOM_LEN_MASK) + 1;
 730        tok->width = OPAL_WIDTH_SHORT;
 731
 732        if (pos[0] & SHORT_ATOM_BYTESTRING) {
 733                tok->type = OPAL_DTA_TOKENID_BYTESTRING;
 734        } else if (pos[0] & SHORT_ATOM_SIGNED) {
 735                tok->type = OPAL_DTA_TOKENID_SINT;
 736        } else {
 737                u64 u_integer = 0;
 738                ssize_t i, b = 0;
 739
 740                tok->type = OPAL_DTA_TOKENID_UINT;
 741                if (tok->len > 9) {
 742                        pr_debug("uint64 with more than 8 bytes\n");
 743                        return -EINVAL;
 744                }
 745                for (i = tok->len - 1; i > 0; i--) {
 746                        u_integer |= ((u64)pos[i] << (8 * b));
 747                        b++;
 748                }
 749                tok->stored.u = u_integer;
 750        }
 751
 752        return tok->len;
 753}
 754
 755static ssize_t response_parse_medium(struct opal_resp_tok *tok,
 756                                     const u8 *pos)
 757{
 758        tok->pos = pos;
 759        tok->len = (((pos[0] & MEDIUM_ATOM_LEN_MASK) << 8) | pos[1]) + 2;
 760        tok->width = OPAL_WIDTH_MEDIUM;
 761
 762        if (pos[0] & MEDIUM_ATOM_BYTESTRING)
 763                tok->type = OPAL_DTA_TOKENID_BYTESTRING;
 764        else if (pos[0] & MEDIUM_ATOM_SIGNED)
 765                tok->type = OPAL_DTA_TOKENID_SINT;
 766        else
 767                tok->type = OPAL_DTA_TOKENID_UINT;
 768
 769        return tok->len;
 770}
 771
 772static ssize_t response_parse_long(struct opal_resp_tok *tok,
 773                                   const u8 *pos)
 774{
 775        tok->pos = pos;
 776        tok->len = ((pos[1] << 16) | (pos[2] << 8) | pos[3]) + 4;
 777        tok->width = OPAL_WIDTH_LONG;
 778
 779        if (pos[0] & LONG_ATOM_BYTESTRING)
 780                tok->type = OPAL_DTA_TOKENID_BYTESTRING;
 781        else if (pos[0] & LONG_ATOM_SIGNED)
 782                tok->type = OPAL_DTA_TOKENID_SINT;
 783        else
 784                tok->type = OPAL_DTA_TOKENID_UINT;
 785
 786        return tok->len;
 787}
 788
 789static ssize_t response_parse_token(struct opal_resp_tok *tok,
 790                                    const u8 *pos)
 791{
 792        tok->pos = pos;
 793        tok->len = 1;
 794        tok->type = OPAL_DTA_TOKENID_TOKEN;
 795        tok->width = OPAL_WIDTH_TOKEN;
 796
 797        return tok->len;
 798}
 799
 800static int response_parse(const u8 *buf, size_t length,
 801                          struct parsed_resp *resp)
 802{
 803        const struct opal_header *hdr;
 804        struct opal_resp_tok *iter;
 805        int num_entries = 0;
 806        int total;
 807        ssize_t token_length;
 808        const u8 *pos;
 809        u32 clen, plen, slen;
 810
 811        if (!buf)
 812                return -EFAULT;
 813
 814        if (!resp)
 815                return -EFAULT;
 816
 817        hdr = (struct opal_header *)buf;
 818        pos = buf;
 819        pos += sizeof(*hdr);
 820
 821        clen = be32_to_cpu(hdr->cp.length);
 822        plen = be32_to_cpu(hdr->pkt.length);
 823        slen = be32_to_cpu(hdr->subpkt.length);
 824        pr_debug("Response size: cp: %u, pkt: %u, subpkt: %u\n",
 825                 clen, plen, slen);
 826
 827        if (clen == 0 || plen == 0 || slen == 0 ||
 828            slen > IO_BUFFER_LENGTH - sizeof(*hdr)) {
 829                pr_debug("Bad header length. cp: %u, pkt: %u, subpkt: %u\n",
 830                         clen, plen, slen);
 831                print_buffer(pos, sizeof(*hdr));
 832                return -EINVAL;
 833        }
 834
 835        if (pos > buf + length)
 836                return -EFAULT;
 837
 838        iter = resp->toks;
 839        total = slen;
 840        print_buffer(pos, total);
 841        while (total > 0) {
 842                if (pos[0] <= TINY_ATOM_BYTE) /* tiny atom */
 843                        token_length = response_parse_tiny(iter, pos);
 844                else if (pos[0] <= SHORT_ATOM_BYTE) /* short atom */
 845                        token_length = response_parse_short(iter, pos);
 846                else if (pos[0] <= MEDIUM_ATOM_BYTE) /* medium atom */
 847                        token_length = response_parse_medium(iter, pos);
 848                else if (pos[0] <= LONG_ATOM_BYTE) /* long atom */
 849                        token_length = response_parse_long(iter, pos);
 850                else /* TOKEN */
 851                        token_length = response_parse_token(iter, pos);
 852
 853                if (token_length < 0)
 854                        return token_length;
 855
 856                pos += token_length;
 857                total -= token_length;
 858                iter++;
 859                num_entries++;
 860        }
 861
 862        if (num_entries == 0) {
 863                pr_debug("Couldn't parse response.\n");
 864                return -EINVAL;
 865        }
 866        resp->num = num_entries;
 867
 868        return 0;
 869}
 870
 871static size_t response_get_string(const struct parsed_resp *resp, int n,
 872                                  const char **store)
 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        if (resp->toks[n].type != OPAL_DTA_TOKENID_BYTESTRING) {
 887                pr_debug("Token is not a byte string!\n");
 888                return 0;
 889        }
 890
 891        *store = resp->toks[n].pos + 1;
 892        return resp->toks[n].len - 1;
 893}
 894
 895static u64 response_get_u64(const struct parsed_resp *resp, int n)
 896{
 897        if (!resp) {
 898                pr_debug("Response is NULL\n");
 899                return 0;
 900        }
 901
 902        if (n > resp->num) {
 903                pr_debug("Response has %d tokens. Can't access %d\n",
 904                         resp->num, n);
 905                return 0;
 906        }
 907
 908        if (resp->toks[n].type != OPAL_DTA_TOKENID_UINT) {
 909                pr_debug("Token is not unsigned it: %d\n",
 910                         resp->toks[n].type);
 911                return 0;
 912        }
 913
 914        if (!(resp->toks[n].width == OPAL_WIDTH_TINY ||
 915              resp->toks[n].width == OPAL_WIDTH_SHORT)) {
 916                pr_debug("Atom is not short or tiny: %d\n",
 917                         resp->toks[n].width);
 918                return 0;
 919        }
 920
 921        return resp->toks[n].stored.u;
 922}
 923
 924static bool response_token_matches(const struct opal_resp_tok *token, u8 match)
 925{
 926        if (IS_ERR(token) ||
 927            token->type != OPAL_DTA_TOKENID_TOKEN ||
 928            token->pos[0] != match)
 929                return false;
 930        return true;
 931}
 932
 933static u8 response_status(const struct parsed_resp *resp)
 934{
 935        const struct opal_resp_tok *tok;
 936
 937        tok = response_get_token(resp, 0);
 938        if (response_token_matches(tok, OPAL_ENDOFSESSION))
 939                return 0;
 940
 941        if (resp->num < 5)
 942                return DTAERROR_NO_METHOD_STATUS;
 943
 944        tok = response_get_token(resp, resp->num - 5);
 945        if (!response_token_matches(tok, OPAL_STARTLIST))
 946                return DTAERROR_NO_METHOD_STATUS;
 947
 948        tok = response_get_token(resp, resp->num - 1);
 949        if (!response_token_matches(tok, OPAL_ENDLIST))
 950                return DTAERROR_NO_METHOD_STATUS;
 951
 952        return response_get_u64(resp, resp->num - 4);
 953}
 954
 955/* Parses and checks for errors */
 956static int parse_and_check_status(struct opal_dev *dev)
 957{
 958        int error;
 959
 960        print_buffer(dev->cmd, dev->pos);
 961
 962        error = response_parse(dev->resp, IO_BUFFER_LENGTH, &dev->parsed);
 963        if (error) {
 964                pr_debug("Couldn't parse response.\n");
 965                return error;
 966        }
 967
 968        return response_status(&dev->parsed);
 969}
 970
 971static void clear_opal_cmd(struct opal_dev *dev)
 972{
 973        dev->pos = sizeof(struct opal_header);
 974        memset(dev->cmd, 0, IO_BUFFER_LENGTH);
 975}
 976
 977static int start_opal_session_cont(struct opal_dev *dev)
 978{
 979        u32 hsn, tsn;
 980        int error = 0;
 981
 982        error = parse_and_check_status(dev);
 983        if (error)
 984                return error;
 985
 986        hsn = response_get_u64(&dev->parsed, 4);
 987        tsn = response_get_u64(&dev->parsed, 5);
 988
 989        if (hsn == 0 && tsn == 0) {
 990                pr_debug("Couldn't authenticate session\n");
 991                return -EPERM;
 992        }
 993
 994        dev->hsn = hsn;
 995        dev->tsn = tsn;
 996        return 0;
 997}
 998
 999static void add_suspend_info(struct opal_dev *dev,
1000                             struct opal_suspend_data *sus)
1001{
1002        struct opal_suspend_data *iter;
1003
1004        list_for_each_entry(iter, &dev->unlk_lst, node) {
1005                if (iter->lr == sus->lr) {
1006                        list_del(&iter->node);
1007                        kfree(iter);
1008                        break;
1009                }
1010        }
1011        list_add_tail(&sus->node, &dev->unlk_lst);
1012}
1013
1014static int end_session_cont(struct opal_dev *dev)
1015{
1016        dev->hsn = 0;
1017        dev->tsn = 0;
1018        return parse_and_check_status(dev);
1019}
1020
1021static int finalize_and_send(struct opal_dev *dev, cont_fn cont)
1022{
1023        int ret;
1024
1025        ret = cmd_finalize(dev, dev->hsn, dev->tsn);
1026        if (ret) {
1027                pr_debug("Error finalizing command buffer: %d\n", ret);
1028                return ret;
1029        }
1030
1031        print_buffer(dev->cmd, dev->pos);
1032
1033        return opal_send_recv(dev, cont);
1034}
1035
1036static int gen_key(struct opal_dev *dev, void *data)
1037{
1038        u8 uid[OPAL_UID_LENGTH];
1039        int err = 0;
1040
1041        clear_opal_cmd(dev);
1042        set_comid(dev, dev->comid);
1043
1044        memcpy(uid, dev->prev_data, min(sizeof(uid), dev->prev_d_len));
1045        kfree(dev->prev_data);
1046        dev->prev_data = NULL;
1047
1048        add_token_u8(&err, dev, OPAL_CALL);
1049        add_token_bytestring(&err, dev, uid, OPAL_UID_LENGTH);
1050        add_token_bytestring(&err, dev, opalmethod[OPAL_GENKEY],
1051                             OPAL_UID_LENGTH);
1052        add_token_u8(&err, dev, OPAL_STARTLIST);
1053        add_token_u8(&err, dev, OPAL_ENDLIST);
1054
1055        if (err) {
1056                pr_debug("Error building gen key command\n");
1057                return err;
1058
1059        }
1060        return finalize_and_send(dev, parse_and_check_status);
1061}
1062
1063static int get_active_key_cont(struct opal_dev *dev)
1064{
1065        const char *activekey;
1066        size_t keylen;
1067        int error = 0;
1068
1069        error = parse_and_check_status(dev);
1070        if (error)
1071                return error;
1072        keylen = response_get_string(&dev->parsed, 4, &activekey);
1073        if (!activekey) {
1074                pr_debug("%s: Couldn't extract the Activekey from the response\n",
1075                         __func__);
1076                return OPAL_INVAL_PARAM;
1077        }
1078        dev->prev_data = kmemdup(activekey, keylen, GFP_KERNEL);
1079
1080        if (!dev->prev_data)
1081                return -ENOMEM;
1082
1083        dev->prev_d_len = keylen;
1084
1085        return 0;
1086}
1087
1088static int get_active_key(struct opal_dev *dev, void *data)
1089{
1090        u8 uid[OPAL_UID_LENGTH];
1091        int err = 0;
1092        u8 *lr = data;
1093
1094        clear_opal_cmd(dev);
1095        set_comid(dev, dev->comid);
1096
1097        err = build_locking_range(uid, sizeof(uid), *lr);
1098        if (err)
1099                return err;
1100
1101        err = 0;
1102        add_token_u8(&err, dev, OPAL_CALL);
1103        add_token_bytestring(&err, dev, uid, OPAL_UID_LENGTH);
1104        add_token_bytestring(&err, dev, opalmethod[OPAL_GET], OPAL_UID_LENGTH);
1105        add_token_u8(&err, dev, OPAL_STARTLIST);
1106        add_token_u8(&err, dev, OPAL_STARTLIST);
1107        add_token_u8(&err, dev, OPAL_STARTNAME);
1108        add_token_u8(&err, dev, 3); /* startCloumn */
1109        add_token_u8(&err, dev, 10); /* ActiveKey */
1110        add_token_u8(&err, dev, OPAL_ENDNAME);
1111        add_token_u8(&err, dev, OPAL_STARTNAME);
1112        add_token_u8(&err, dev, 4); /* endColumn */
1113        add_token_u8(&err, dev, 10); /* ActiveKey */
1114        add_token_u8(&err, dev, OPAL_ENDNAME);
1115        add_token_u8(&err, dev, OPAL_ENDLIST);
1116        add_token_u8(&err, dev, OPAL_ENDLIST);
1117        if (err) {
1118                pr_debug("Error building get active key command\n");
1119                return err;
1120        }
1121
1122        return finalize_and_send(dev, get_active_key_cont);
1123}
1124
1125static int generic_lr_enable_disable(struct opal_dev *dev,
1126                                     u8 *uid, bool rle, bool wle,
1127                                     bool rl, bool wl)
1128{
1129        int err = 0;
1130
1131        add_token_u8(&err, dev, OPAL_CALL);
1132        add_token_bytestring(&err, dev, uid, OPAL_UID_LENGTH);
1133        add_token_bytestring(&err, dev, opalmethod[OPAL_SET], OPAL_UID_LENGTH);
1134
1135        add_token_u8(&err, dev, OPAL_STARTLIST);
1136        add_token_u8(&err, dev, OPAL_STARTNAME);
1137        add_token_u8(&err, dev, OPAL_VALUES);
1138        add_token_u8(&err, dev, OPAL_STARTLIST);
1139
1140        add_token_u8(&err, dev, OPAL_STARTNAME);
1141        add_token_u8(&err, dev, 5); /* ReadLockEnabled */
1142        add_token_u8(&err, dev, rle);
1143        add_token_u8(&err, dev, OPAL_ENDNAME);
1144
1145        add_token_u8(&err, dev, OPAL_STARTNAME);
1146        add_token_u8(&err, dev, 6); /* WriteLockEnabled */
1147        add_token_u8(&err, dev, wle);
1148        add_token_u8(&err, dev, OPAL_ENDNAME);
1149
1150        add_token_u8(&err, dev, OPAL_STARTNAME);
1151        add_token_u8(&err, dev, OPAL_READLOCKED);
1152        add_token_u8(&err, dev, rl);
1153        add_token_u8(&err, dev, OPAL_ENDNAME);
1154
1155        add_token_u8(&err, dev, OPAL_STARTNAME);
1156        add_token_u8(&err, dev, OPAL_WRITELOCKED);
1157        add_token_u8(&err, dev, wl);
1158        add_token_u8(&err, dev, OPAL_ENDNAME);
1159
1160        add_token_u8(&err, dev, OPAL_ENDLIST);
1161        add_token_u8(&err, dev, OPAL_ENDNAME);
1162        add_token_u8(&err, dev, OPAL_ENDLIST);
1163        return err;
1164}
1165
1166static inline int enable_global_lr(struct opal_dev *dev, u8 *uid,
1167                                   struct opal_user_lr_setup *setup)
1168{
1169        int err;
1170
1171        err = generic_lr_enable_disable(dev, uid, !!setup->RLE, !!setup->WLE,
1172                                        0, 0);
1173        if (err)
1174                pr_debug("Failed to create enable global lr command\n");
1175        return err;
1176}
1177
1178static int setup_locking_range(struct opal_dev *dev, void *data)
1179{
1180        u8 uid[OPAL_UID_LENGTH];
1181        struct opal_user_lr_setup *setup = data;
1182        u8 lr;
1183        int err = 0;
1184
1185        clear_opal_cmd(dev);
1186        set_comid(dev, dev->comid);
1187
1188        lr = setup->session.opal_key.lr;
1189        err = build_locking_range(uid, sizeof(uid), lr);
1190        if (err)
1191                return err;
1192
1193        if (lr == 0)
1194                err = enable_global_lr(dev, uid, setup);
1195        else {
1196                add_token_u8(&err, dev, OPAL_CALL);
1197                add_token_bytestring(&err, dev, uid, OPAL_UID_LENGTH);
1198                add_token_bytestring(&err, dev, opalmethod[OPAL_SET],
1199                                     OPAL_UID_LENGTH);
1200
1201                add_token_u8(&err, dev, OPAL_STARTLIST);
1202                add_token_u8(&err, dev, OPAL_STARTNAME);
1203                add_token_u8(&err, dev, OPAL_VALUES);
1204                add_token_u8(&err, dev, OPAL_STARTLIST);
1205
1206                add_token_u8(&err, dev, OPAL_STARTNAME);
1207                add_token_u8(&err, dev, 3); /* Ranges Start */
1208                add_token_u64(&err, dev, setup->range_start);
1209                add_token_u8(&err, dev, OPAL_ENDNAME);
1210
1211                add_token_u8(&err, dev, OPAL_STARTNAME);
1212                add_token_u8(&err, dev, 4); /* Ranges length */
1213                add_token_u64(&err, dev, setup->range_length);
1214                add_token_u8(&err, dev, OPAL_ENDNAME);
1215
1216                add_token_u8(&err, dev, OPAL_STARTNAME);
1217                add_token_u8(&err, dev, 5); /*ReadLockEnabled */
1218                add_token_u64(&err, dev, !!setup->RLE);
1219                add_token_u8(&err, dev, OPAL_ENDNAME);
1220
1221                add_token_u8(&err, dev, OPAL_STARTNAME);
1222                add_token_u8(&err, dev, 6); /*WriteLockEnabled*/
1223                add_token_u64(&err, dev, !!setup->WLE);
1224                add_token_u8(&err, dev, OPAL_ENDNAME);
1225
1226                add_token_u8(&err, dev, OPAL_ENDLIST);
1227                add_token_u8(&err, dev, OPAL_ENDNAME);
1228                add_token_u8(&err, dev, OPAL_ENDLIST);
1229
1230        }
1231        if (err) {
1232                pr_debug("Error building Setup Locking range command.\n");
1233                return err;
1234
1235        }
1236
1237        return finalize_and_send(dev, parse_and_check_status);
1238}
1239
1240static int start_generic_opal_session(struct opal_dev *dev,
1241                                      enum opal_uid auth,
1242                                      enum opal_uid sp_type,
1243                                      const char *key,
1244                                      u8 key_len)
1245{
1246        u32 hsn;
1247        int err = 0;
1248
1249        if (key == NULL && auth != OPAL_ANYBODY_UID)
1250                return OPAL_INVAL_PARAM;
1251
1252        clear_opal_cmd(dev);
1253
1254        set_comid(dev, dev->comid);
1255        hsn = GENERIC_HOST_SESSION_NUM;
1256
1257        add_token_u8(&err, dev, OPAL_CALL);
1258        add_token_bytestring(&err, dev, opaluid[OPAL_SMUID_UID],
1259                             OPAL_UID_LENGTH);
1260        add_token_bytestring(&err, dev, opalmethod[OPAL_STARTSESSION],
1261                             OPAL_UID_LENGTH);
1262        add_token_u8(&err, dev, OPAL_STARTLIST);
1263        add_token_u64(&err, dev, hsn);
1264        add_token_bytestring(&err, dev, opaluid[sp_type], OPAL_UID_LENGTH);
1265        add_token_u8(&err, dev, 1);
1266
1267        switch (auth) {
1268        case OPAL_ANYBODY_UID:
1269                add_token_u8(&err, dev, OPAL_ENDLIST);
1270                break;
1271        case OPAL_ADMIN1_UID:
1272        case OPAL_SID_UID:
1273                add_token_u8(&err, dev, OPAL_STARTNAME);
1274                add_token_u8(&err, dev, 0); /* HostChallenge */
1275                add_token_bytestring(&err, dev, key, key_len);
1276                add_token_u8(&err, dev, OPAL_ENDNAME);
1277                add_token_u8(&err, dev, OPAL_STARTNAME);
1278                add_token_u8(&err, dev, 3); /* HostSignAuth */
1279                add_token_bytestring(&err, dev, opaluid[auth],
1280                                     OPAL_UID_LENGTH);
1281                add_token_u8(&err, dev, OPAL_ENDNAME);
1282                add_token_u8(&err, dev, OPAL_ENDLIST);
1283                break;
1284        default:
1285                pr_debug("Cannot start Admin SP session with auth %d\n", auth);
1286                return OPAL_INVAL_PARAM;
1287        }
1288
1289        if (err) {
1290                pr_debug("Error building start adminsp session command.\n");
1291                return err;
1292        }
1293
1294        return finalize_and_send(dev, start_opal_session_cont);
1295}
1296
1297static int start_anybodyASP_opal_session(struct opal_dev *dev, void *data)
1298{
1299        return start_generic_opal_session(dev, OPAL_ANYBODY_UID,
1300                                          OPAL_ADMINSP_UID, NULL, 0);
1301}
1302
1303static int start_SIDASP_opal_session(struct opal_dev *dev, void *data)
1304{
1305        int ret;
1306        const u8 *key = dev->prev_data;
1307
1308        if (!key) {
1309                const struct opal_key *okey = data;
1310                ret = start_generic_opal_session(dev, OPAL_SID_UID,
1311                                                 OPAL_ADMINSP_UID,
1312                                                 okey->key,
1313                                                 okey->key_len);
1314        } else {
1315                ret = start_generic_opal_session(dev, OPAL_SID_UID,
1316                                                 OPAL_ADMINSP_UID,
1317                                                 key, dev->prev_d_len);
1318                kfree(key);
1319                dev->prev_data = NULL;
1320        }
1321        return ret;
1322}
1323
1324static int start_admin1LSP_opal_session(struct opal_dev *dev, void *data)
1325{
1326        struct opal_key *key = data;
1327        return start_generic_opal_session(dev, OPAL_ADMIN1_UID,
1328                                          OPAL_LOCKINGSP_UID,
1329                                          key->key, key->key_len);
1330}
1331
1332static int start_auth_opal_session(struct opal_dev *dev, void *data)
1333{
1334        struct opal_session_info *session = data;
1335        u8 lk_ul_user[OPAL_UID_LENGTH];
1336        size_t keylen = session->opal_key.key_len;
1337        int err = 0;
1338
1339        u8 *key = session->opal_key.key;
1340        u32 hsn = GENERIC_HOST_SESSION_NUM;
1341
1342        clear_opal_cmd(dev);
1343        set_comid(dev, dev->comid);
1344
1345        if (session->sum) {
1346                err = build_locking_user(lk_ul_user, sizeof(lk_ul_user),
1347                                         session->opal_key.lr);
1348                if (err)
1349                        return err;
1350
1351        } else if (session->who != OPAL_ADMIN1 && !session->sum) {
1352                err = build_locking_user(lk_ul_user, sizeof(lk_ul_user),
1353                                         session->who - 1);
1354                if (err)
1355                        return err;
1356        } else
1357                memcpy(lk_ul_user, opaluid[OPAL_ADMIN1_UID], OPAL_UID_LENGTH);
1358
1359        add_token_u8(&err, dev, OPAL_CALL);
1360        add_token_bytestring(&err, dev, opaluid[OPAL_SMUID_UID],
1361                             OPAL_UID_LENGTH);
1362        add_token_bytestring(&err, dev, opalmethod[OPAL_STARTSESSION],
1363                             OPAL_UID_LENGTH);
1364
1365        add_token_u8(&err, dev, OPAL_STARTLIST);
1366        add_token_u64(&err, dev, hsn);
1367        add_token_bytestring(&err, dev, opaluid[OPAL_LOCKINGSP_UID],
1368                             OPAL_UID_LENGTH);
1369        add_token_u8(&err, dev, 1);
1370        add_token_u8(&err, dev, OPAL_STARTNAME);
1371        add_token_u8(&err, dev, 0);
1372        add_token_bytestring(&err, dev, key, keylen);
1373        add_token_u8(&err, dev, OPAL_ENDNAME);
1374        add_token_u8(&err, dev, OPAL_STARTNAME);
1375        add_token_u8(&err, dev, 3);
1376        add_token_bytestring(&err, dev, lk_ul_user, OPAL_UID_LENGTH);
1377        add_token_u8(&err, dev, OPAL_ENDNAME);
1378        add_token_u8(&err, dev, OPAL_ENDLIST);
1379
1380        if (err) {
1381                pr_debug("Error building STARTSESSION command.\n");
1382                return err;
1383        }
1384
1385        return finalize_and_send(dev, start_opal_session_cont);
1386}
1387
1388static int revert_tper(struct opal_dev *dev, void *data)
1389{
1390        int err = 0;
1391
1392        clear_opal_cmd(dev);
1393        set_comid(dev, dev->comid);
1394
1395        add_token_u8(&err, dev, OPAL_CALL);
1396        add_token_bytestring(&err, dev, opaluid[OPAL_ADMINSP_UID],
1397                             OPAL_UID_LENGTH);
1398        add_token_bytestring(&err, dev, opalmethod[OPAL_REVERT],
1399                             OPAL_UID_LENGTH);
1400        add_token_u8(&err, dev, OPAL_STARTLIST);
1401        add_token_u8(&err, dev, OPAL_ENDLIST);
1402        if (err) {
1403                pr_debug("Error building REVERT TPER command.\n");
1404                return err;
1405        }
1406
1407        return finalize_and_send(dev, parse_and_check_status);
1408}
1409
1410static int internal_activate_user(struct opal_dev *dev, void *data)
1411{
1412        struct opal_session_info *session = data;
1413        u8 uid[OPAL_UID_LENGTH];
1414        int err = 0;
1415
1416        clear_opal_cmd(dev);
1417        set_comid(dev, dev->comid);
1418
1419        memcpy(uid, opaluid[OPAL_USER1_UID], OPAL_UID_LENGTH);
1420        uid[7] = session->who;
1421
1422        add_token_u8(&err, dev, OPAL_CALL);
1423        add_token_bytestring(&err, dev, uid, OPAL_UID_LENGTH);
1424        add_token_bytestring(&err, dev, opalmethod[OPAL_SET], OPAL_UID_LENGTH);
1425        add_token_u8(&err, dev, OPAL_STARTLIST);
1426        add_token_u8(&err, dev, OPAL_STARTNAME);
1427        add_token_u8(&err, dev, OPAL_VALUES);
1428        add_token_u8(&err, dev, OPAL_STARTLIST);
1429        add_token_u8(&err, dev, OPAL_STARTNAME);
1430        add_token_u8(&err, dev, 5); /* Enabled */
1431        add_token_u8(&err, dev, OPAL_TRUE);
1432        add_token_u8(&err, dev, OPAL_ENDNAME);
1433        add_token_u8(&err, dev, OPAL_ENDLIST);
1434        add_token_u8(&err, dev, OPAL_ENDNAME);
1435        add_token_u8(&err, dev, OPAL_ENDLIST);
1436
1437        if (err) {
1438                pr_debug("Error building Activate UserN command.\n");
1439                return err;
1440        }
1441
1442        return finalize_and_send(dev, parse_and_check_status);
1443}
1444
1445static int erase_locking_range(struct opal_dev *dev, void *data)
1446{
1447        struct opal_session_info *session = data;
1448        u8 uid[OPAL_UID_LENGTH];
1449        int err = 0;
1450
1451        clear_opal_cmd(dev);
1452        set_comid(dev, dev->comid);
1453
1454        if (build_locking_range(uid, sizeof(uid), session->opal_key.lr) < 0)
1455                return -ERANGE;
1456
1457        add_token_u8(&err, dev, OPAL_CALL);
1458        add_token_bytestring(&err, dev, uid, OPAL_UID_LENGTH);
1459        add_token_bytestring(&err, dev, opalmethod[OPAL_ERASE],
1460                             OPAL_UID_LENGTH);
1461        add_token_u8(&err, dev, OPAL_STARTLIST);
1462        add_token_u8(&err, dev, OPAL_ENDLIST);
1463
1464        if (err) {
1465                pr_debug("Error building Erase Locking Range Command.\n");
1466                return err;
1467        }
1468        return finalize_and_send(dev, parse_and_check_status);
1469}
1470
1471static int set_mbr_done(struct opal_dev *dev, void *data)
1472{
1473        u8 *mbr_done_tf = data;
1474        int err = 0;
1475
1476        clear_opal_cmd(dev);
1477        set_comid(dev, dev->comid);
1478
1479        add_token_u8(&err, dev, OPAL_CALL);
1480        add_token_bytestring(&err, dev, opaluid[OPAL_MBRCONTROL],
1481                             OPAL_UID_LENGTH);
1482        add_token_bytestring(&err, dev, opalmethod[OPAL_SET], OPAL_UID_LENGTH);
1483        add_token_u8(&err, dev, OPAL_STARTLIST);
1484        add_token_u8(&err, dev, OPAL_STARTNAME);
1485        add_token_u8(&err, dev, OPAL_VALUES);
1486        add_token_u8(&err, dev, OPAL_STARTLIST);
1487        add_token_u8(&err, dev, OPAL_STARTNAME);
1488        add_token_u8(&err, dev, 2); /* Done */
1489        add_token_u8(&err, dev, *mbr_done_tf); /* Done T or F */
1490        add_token_u8(&err, dev, OPAL_ENDNAME);
1491        add_token_u8(&err, dev, OPAL_ENDLIST);
1492        add_token_u8(&err, dev, OPAL_ENDNAME);
1493        add_token_u8(&err, dev, OPAL_ENDLIST);
1494
1495        if (err) {
1496                pr_debug("Error Building set MBR Done command\n");
1497                return err;
1498        }
1499
1500        return finalize_and_send(dev, parse_and_check_status);
1501}
1502
1503static int set_mbr_enable_disable(struct opal_dev *dev, void *data)
1504{
1505        u8 *mbr_en_dis = data;
1506        int err = 0;
1507
1508        clear_opal_cmd(dev);
1509        set_comid(dev, dev->comid);
1510
1511        add_token_u8(&err, dev, OPAL_CALL);
1512        add_token_bytestring(&err, dev, opaluid[OPAL_MBRCONTROL],
1513                             OPAL_UID_LENGTH);
1514        add_token_bytestring(&err, dev, opalmethod[OPAL_SET], OPAL_UID_LENGTH);
1515        add_token_u8(&err, dev, OPAL_STARTLIST);
1516        add_token_u8(&err, dev, OPAL_STARTNAME);
1517        add_token_u8(&err, dev, OPAL_VALUES);
1518        add_token_u8(&err, dev, OPAL_STARTLIST);
1519        add_token_u8(&err, dev, OPAL_STARTNAME);
1520        add_token_u8(&err, dev, 1);
1521        add_token_u8(&err, dev, *mbr_en_dis);
1522        add_token_u8(&err, dev, OPAL_ENDNAME);
1523        add_token_u8(&err, dev, OPAL_ENDLIST);
1524        add_token_u8(&err, dev, OPAL_ENDNAME);
1525        add_token_u8(&err, dev, OPAL_ENDLIST);
1526
1527        if (err) {
1528                pr_debug("Error Building set MBR done command\n");
1529                return err;
1530        }
1531
1532        return finalize_and_send(dev, parse_and_check_status);
1533}
1534
1535static int generic_pw_cmd(u8 *key, size_t key_len, u8 *cpin_uid,
1536                          struct opal_dev *dev)
1537{
1538        int err = 0;
1539
1540        clear_opal_cmd(dev);
1541        set_comid(dev, dev->comid);
1542
1543        add_token_u8(&err, dev, OPAL_CALL);
1544        add_token_bytestring(&err, dev, cpin_uid, OPAL_UID_LENGTH);
1545        add_token_bytestring(&err, dev, opalmethod[OPAL_SET],
1546                             OPAL_UID_LENGTH);
1547        add_token_u8(&err, dev, OPAL_STARTLIST);
1548        add_token_u8(&err, dev, OPAL_STARTNAME);
1549        add_token_u8(&err, dev, OPAL_VALUES);
1550        add_token_u8(&err, dev, OPAL_STARTLIST);
1551        add_token_u8(&err, dev, OPAL_STARTNAME);
1552        add_token_u8(&err, dev, 3); /* PIN */
1553        add_token_bytestring(&err, dev, key, key_len);
1554        add_token_u8(&err, dev, OPAL_ENDNAME);
1555        add_token_u8(&err, dev, OPAL_ENDLIST);
1556        add_token_u8(&err, dev, OPAL_ENDNAME);
1557        add_token_u8(&err, dev, OPAL_ENDLIST);
1558
1559        return err;
1560}
1561
1562static int set_new_pw(struct opal_dev *dev, void *data)
1563{
1564        u8 cpin_uid[OPAL_UID_LENGTH];
1565        struct opal_session_info *usr = data;
1566
1567        memcpy(cpin_uid, opaluid[OPAL_C_PIN_ADMIN1], OPAL_UID_LENGTH);
1568
1569        if (usr->who != OPAL_ADMIN1) {
1570                cpin_uid[5] = 0x03;
1571                if (usr->sum)
1572                        cpin_uid[7] = usr->opal_key.lr + 1;
1573                else
1574                        cpin_uid[7] = usr->who;
1575        }
1576
1577        if (generic_pw_cmd(usr->opal_key.key, usr->opal_key.key_len,
1578                           cpin_uid, dev)) {
1579                pr_debug("Error building set password command.\n");
1580                return -ERANGE;
1581        }
1582
1583        return finalize_and_send(dev, parse_and_check_status);
1584}
1585
1586static int set_sid_cpin_pin(struct opal_dev *dev, void *data)
1587{
1588        u8 cpin_uid[OPAL_UID_LENGTH];
1589        struct opal_key *key = data;
1590
1591        memcpy(cpin_uid, opaluid[OPAL_C_PIN_SID], OPAL_UID_LENGTH);
1592
1593        if (generic_pw_cmd(key->key, key->key_len, cpin_uid, dev)) {
1594                pr_debug("Error building Set SID cpin\n");
1595                return -ERANGE;
1596        }
1597        return finalize_and_send(dev, parse_and_check_status);
1598}
1599
1600static int add_user_to_lr(struct opal_dev *dev, void *data)
1601{
1602        u8 lr_buffer[OPAL_UID_LENGTH];
1603        u8 user_uid[OPAL_UID_LENGTH];
1604        struct opal_lock_unlock *lkul = data;
1605        int err = 0;
1606
1607        clear_opal_cmd(dev);
1608        set_comid(dev, dev->comid);
1609
1610        memcpy(lr_buffer, opaluid[OPAL_LOCKINGRANGE_ACE_RDLOCKED],
1611               OPAL_UID_LENGTH);
1612
1613        if (lkul->l_state == OPAL_RW)
1614                memcpy(lr_buffer, opaluid[OPAL_LOCKINGRANGE_ACE_WRLOCKED],
1615                       OPAL_UID_LENGTH);
1616
1617        lr_buffer[7] = lkul->session.opal_key.lr;
1618
1619        memcpy(user_uid, opaluid[OPAL_USER1_UID], OPAL_UID_LENGTH);
1620
1621        user_uid[7] = lkul->session.who;
1622
1623        add_token_u8(&err, dev, OPAL_CALL);
1624        add_token_bytestring(&err, dev, lr_buffer, OPAL_UID_LENGTH);
1625        add_token_bytestring(&err, dev, opalmethod[OPAL_SET],
1626                             OPAL_UID_LENGTH);
1627
1628        add_token_u8(&err, dev, OPAL_STARTLIST);
1629        add_token_u8(&err, dev, OPAL_STARTNAME);
1630        add_token_u8(&err, dev, OPAL_VALUES);
1631
1632        add_token_u8(&err, dev, OPAL_STARTLIST);
1633        add_token_u8(&err, dev, OPAL_STARTNAME);
1634        add_token_u8(&err, dev, 3);
1635
1636        add_token_u8(&err, dev, OPAL_STARTLIST);
1637
1638
1639        add_token_u8(&err, dev, OPAL_STARTNAME);
1640        add_token_bytestring(&err, dev,
1641                             opaluid[OPAL_HALF_UID_AUTHORITY_OBJ_REF],
1642                             OPAL_UID_LENGTH/2);
1643        add_token_bytestring(&err, dev, user_uid, OPAL_UID_LENGTH);
1644        add_token_u8(&err, dev, OPAL_ENDNAME);
1645
1646
1647        add_token_u8(&err, dev, OPAL_STARTNAME);
1648        add_token_bytestring(&err, dev,
1649                             opaluid[OPAL_HALF_UID_AUTHORITY_OBJ_REF],
1650                             OPAL_UID_LENGTH/2);
1651        add_token_bytestring(&err, dev, user_uid, OPAL_UID_LENGTH);
1652        add_token_u8(&err, dev, OPAL_ENDNAME);
1653
1654
1655        add_token_u8(&err, dev, OPAL_STARTNAME);
1656        add_token_bytestring(&err, dev, opaluid[OPAL_HALF_UID_BOOLEAN_ACE],
1657                             OPAL_UID_LENGTH/2);
1658        add_token_u8(&err, dev, 1);
1659        add_token_u8(&err, dev, OPAL_ENDNAME);
1660
1661
1662        add_token_u8(&err, dev, OPAL_ENDLIST);
1663        add_token_u8(&err, dev, OPAL_ENDNAME);
1664        add_token_u8(&err, dev, OPAL_ENDLIST);
1665        add_token_u8(&err, dev, OPAL_ENDNAME);
1666        add_token_u8(&err, dev, OPAL_ENDLIST);
1667
1668        if (err) {
1669                pr_debug("Error building add user to locking range command.\n");
1670                return err;
1671        }
1672
1673        return finalize_and_send(dev, parse_and_check_status);
1674}
1675
1676static int lock_unlock_locking_range(struct opal_dev *dev, void *data)
1677{
1678        u8 lr_buffer[OPAL_UID_LENGTH];
1679        struct opal_lock_unlock *lkul = data;
1680        u8 read_locked = 1, write_locked = 1;
1681        int err = 0;
1682
1683        clear_opal_cmd(dev);
1684        set_comid(dev, dev->comid);
1685
1686        if (build_locking_range(lr_buffer, sizeof(lr_buffer),
1687                                lkul->session.opal_key.lr) < 0)
1688                return -ERANGE;
1689
1690        switch (lkul->l_state) {
1691        case OPAL_RO:
1692                read_locked = 0;
1693                write_locked = 1;
1694                break;
1695        case OPAL_RW:
1696                read_locked = 0;
1697                write_locked = 0;
1698                break;
1699        case OPAL_LK:
1700                /* vars are initalized to locked */
1701                break;
1702        default:
1703                pr_debug("Tried to set an invalid locking state... returning to uland\n");
1704                return OPAL_INVAL_PARAM;
1705        }
1706
1707        add_token_u8(&err, dev, OPAL_CALL);
1708        add_token_bytestring(&err, dev, lr_buffer, OPAL_UID_LENGTH);
1709        add_token_bytestring(&err, dev, opalmethod[OPAL_SET], OPAL_UID_LENGTH);
1710        add_token_u8(&err, dev, OPAL_STARTLIST);
1711        add_token_u8(&err, dev, OPAL_STARTNAME);
1712        add_token_u8(&err, dev, OPAL_VALUES);
1713        add_token_u8(&err, dev, OPAL_STARTLIST);
1714
1715        add_token_u8(&err, dev, OPAL_STARTNAME);
1716        add_token_u8(&err, dev, OPAL_READLOCKED);
1717        add_token_u8(&err, dev, read_locked);
1718        add_token_u8(&err, dev, OPAL_ENDNAME);
1719
1720        add_token_u8(&err, dev, OPAL_STARTNAME);
1721        add_token_u8(&err, dev, OPAL_WRITELOCKED);
1722        add_token_u8(&err, dev, write_locked);
1723        add_token_u8(&err, dev, OPAL_ENDNAME);
1724
1725        add_token_u8(&err, dev, OPAL_ENDLIST);
1726        add_token_u8(&err, dev, OPAL_ENDNAME);
1727        add_token_u8(&err, dev, OPAL_ENDLIST);
1728
1729        if (err) {
1730                pr_debug("Error building SET command.\n");
1731                return err;
1732        }
1733        return finalize_and_send(dev, parse_and_check_status);
1734}
1735
1736
1737static int lock_unlock_locking_range_sum(struct opal_dev *dev, void *data)
1738{
1739        u8 lr_buffer[OPAL_UID_LENGTH];
1740        u8 read_locked = 1, write_locked = 1;
1741        struct opal_lock_unlock *lkul = data;
1742        int ret;
1743
1744        clear_opal_cmd(dev);
1745        set_comid(dev, dev->comid);
1746
1747        if (build_locking_range(lr_buffer, sizeof(lr_buffer),
1748                                lkul->session.opal_key.lr) < 0)
1749                return -ERANGE;
1750
1751        switch (lkul->l_state) {
1752        case OPAL_RO:
1753                read_locked = 0;
1754                write_locked = 1;
1755                break;
1756        case OPAL_RW:
1757                read_locked = 0;
1758                write_locked = 0;
1759                break;
1760        case OPAL_LK:
1761                /* vars are initalized to locked */
1762                break;
1763        default:
1764                pr_debug("Tried to set an invalid locking state.\n");
1765                return OPAL_INVAL_PARAM;
1766        }
1767        ret = generic_lr_enable_disable(dev, lr_buffer, 1, 1,
1768                                        read_locked, write_locked);
1769
1770        if (ret < 0) {
1771                pr_debug("Error building SET command.\n");
1772                return ret;
1773        }
1774        return finalize_and_send(dev, parse_and_check_status);
1775}
1776
1777static int activate_lsp(struct opal_dev *dev, void *data)
1778{
1779        struct opal_lr_act *opal_act = data;
1780        u8 user_lr[OPAL_UID_LENGTH];
1781        u8 uint_3 = 0x83;
1782        int err = 0, i;
1783
1784        clear_opal_cmd(dev);
1785        set_comid(dev, dev->comid);
1786
1787        add_token_u8(&err, dev, OPAL_CALL);
1788        add_token_bytestring(&err, dev, opaluid[OPAL_LOCKINGSP_UID],
1789                             OPAL_UID_LENGTH);
1790        add_token_bytestring(&err, dev, opalmethod[OPAL_ACTIVATE],
1791                             OPAL_UID_LENGTH);
1792
1793
1794        if (opal_act->sum) {
1795                err = build_locking_range(user_lr, sizeof(user_lr),
1796                                          opal_act->lr[0]);
1797                if (err)
1798                        return err;
1799
1800                add_token_u8(&err, dev, OPAL_STARTLIST);
1801                add_token_u8(&err, dev, OPAL_STARTNAME);
1802                add_token_u8(&err, dev, uint_3);
1803                add_token_u8(&err, dev, 6);
1804                add_token_u8(&err, dev, 0);
1805                add_token_u8(&err, dev, 0);
1806
1807                add_token_u8(&err, dev, OPAL_STARTLIST);
1808                add_token_bytestring(&err, dev, user_lr, OPAL_UID_LENGTH);
1809                for (i = 1; i < opal_act->num_lrs; i++) {
1810                        user_lr[7] = opal_act->lr[i];
1811                        add_token_bytestring(&err, dev, user_lr, OPAL_UID_LENGTH);
1812                }
1813                add_token_u8(&err, dev, OPAL_ENDLIST);
1814                add_token_u8(&err, dev, OPAL_ENDNAME);
1815                add_token_u8(&err, dev, OPAL_ENDLIST);
1816
1817        } else {
1818                add_token_u8(&err, dev, OPAL_STARTLIST);
1819                add_token_u8(&err, dev, OPAL_ENDLIST);
1820        }
1821
1822        if (err) {
1823                pr_debug("Error building Activate LockingSP command.\n");
1824                return err;
1825        }
1826
1827        return finalize_and_send(dev, parse_and_check_status);
1828}
1829
1830static int get_lsp_lifecycle_cont(struct opal_dev *dev)
1831{
1832        u8 lc_status;
1833        int error = 0;
1834
1835        error = parse_and_check_status(dev);
1836        if (error)
1837                return error;
1838
1839        lc_status = response_get_u64(&dev->parsed, 4);
1840        /* 0x08 is Manufacured Inactive */
1841        /* 0x09 is Manufactured */
1842        if (lc_status != OPAL_MANUFACTURED_INACTIVE) {
1843                pr_debug("Couldn't determine the status of the Lifecycle state\n");
1844                return -ENODEV;
1845        }
1846
1847        return 0;
1848}
1849
1850/* Determine if we're in the Manufactured Inactive or Active state */
1851static int get_lsp_lifecycle(struct opal_dev *dev, void *data)
1852{
1853        int err = 0;
1854
1855        clear_opal_cmd(dev);
1856        set_comid(dev, dev->comid);
1857
1858        add_token_u8(&err, dev, OPAL_CALL);
1859        add_token_bytestring(&err, dev, opaluid[OPAL_LOCKINGSP_UID],
1860                             OPAL_UID_LENGTH);
1861        add_token_bytestring(&err, dev, opalmethod[OPAL_GET], OPAL_UID_LENGTH);
1862
1863        add_token_u8(&err, dev, OPAL_STARTLIST);
1864        add_token_u8(&err, dev, OPAL_STARTLIST);
1865
1866        add_token_u8(&err, dev, OPAL_STARTNAME);
1867        add_token_u8(&err, dev, 3); /* Start Column */
1868        add_token_u8(&err, dev, 6); /* Lifecycle Column */
1869        add_token_u8(&err, dev, OPAL_ENDNAME);
1870
1871        add_token_u8(&err, dev, OPAL_STARTNAME);
1872        add_token_u8(&err, dev, 4); /* End Column */
1873        add_token_u8(&err, dev, 6); /* Lifecycle Column */
1874        add_token_u8(&err, dev, OPAL_ENDNAME);
1875
1876        add_token_u8(&err, dev, OPAL_ENDLIST);
1877        add_token_u8(&err, dev, OPAL_ENDLIST);
1878
1879        if (err) {
1880                pr_debug("Error Building GET Lifecycle Status command\n");
1881                return err;
1882        }
1883
1884        return finalize_and_send(dev, get_lsp_lifecycle_cont);
1885}
1886
1887static int get_msid_cpin_pin_cont(struct opal_dev *dev)
1888{
1889        const char *msid_pin;
1890        size_t strlen;
1891        int error = 0;
1892
1893        error = parse_and_check_status(dev);
1894        if (error)
1895                return error;
1896
1897        strlen = response_get_string(&dev->parsed, 4, &msid_pin);
1898        if (!msid_pin) {
1899                pr_debug("%s: Couldn't extract PIN from response\n", __func__);
1900                return OPAL_INVAL_PARAM;
1901        }
1902
1903        dev->prev_data = kmemdup(msid_pin, strlen, GFP_KERNEL);
1904        if (!dev->prev_data)
1905                return -ENOMEM;
1906
1907        dev->prev_d_len = strlen;
1908
1909        return 0;
1910}
1911
1912static int get_msid_cpin_pin(struct opal_dev *dev, void *data)
1913{
1914        int err = 0;
1915
1916        clear_opal_cmd(dev);
1917        set_comid(dev, dev->comid);
1918
1919        add_token_u8(&err, dev, OPAL_CALL);
1920        add_token_bytestring(&err, dev, opaluid[OPAL_C_PIN_MSID],
1921                             OPAL_UID_LENGTH);
1922        add_token_bytestring(&err, dev, opalmethod[OPAL_GET], OPAL_UID_LENGTH);
1923
1924        add_token_u8(&err, dev, OPAL_STARTLIST);
1925        add_token_u8(&err, dev, OPAL_STARTLIST);
1926
1927        add_token_u8(&err, dev, OPAL_STARTNAME);
1928        add_token_u8(&err, dev, 3); /* Start Column */
1929        add_token_u8(&err, dev, 3); /* PIN */
1930        add_token_u8(&err, dev, OPAL_ENDNAME);
1931
1932        add_token_u8(&err, dev, OPAL_STARTNAME);
1933        add_token_u8(&err, dev, 4); /* End Column */
1934        add_token_u8(&err, dev, 3); /* Lifecycle Column */
1935        add_token_u8(&err, dev, OPAL_ENDNAME);
1936
1937        add_token_u8(&err, dev, OPAL_ENDLIST);
1938        add_token_u8(&err, dev, OPAL_ENDLIST);
1939
1940        if (err) {
1941                pr_debug("Error building Get MSID CPIN PIN command.\n");
1942                return err;
1943        }
1944
1945        return finalize_and_send(dev, get_msid_cpin_pin_cont);
1946}
1947
1948static int end_opal_session(struct opal_dev *dev, void *data)
1949{
1950        int err = 0;
1951
1952        clear_opal_cmd(dev);
1953        set_comid(dev, dev->comid);
1954        add_token_u8(&err, dev, OPAL_ENDOFSESSION);
1955
1956        if (err < 0)
1957                return err;
1958        return finalize_and_send(dev, end_session_cont);
1959}
1960
1961static int end_opal_session_error(struct opal_dev *dev)
1962{
1963        const struct opal_step error_end_session[] = {
1964                { end_opal_session, },
1965                { NULL, }
1966        };
1967        dev->steps = error_end_session;
1968        return next(dev);
1969}
1970
1971static inline void setup_opal_dev(struct opal_dev *dev,
1972                                  const struct opal_step *steps)
1973{
1974        dev->steps = steps;
1975        dev->tsn = 0;
1976        dev->hsn = 0;
1977        dev->prev_data = NULL;
1978}
1979
1980static int check_opal_support(struct opal_dev *dev)
1981{
1982        const struct opal_step steps[] = {
1983                { opal_discovery0, },
1984                { NULL, }
1985        };
1986        int ret;
1987
1988        mutex_lock(&dev->dev_lock);
1989        setup_opal_dev(dev, steps);
1990        ret = next(dev);
1991        dev->supported = !ret;
1992        mutex_unlock(&dev->dev_lock);
1993        return ret;
1994}
1995
1996static void clean_opal_dev(struct opal_dev *dev)
1997{
1998
1999        struct opal_suspend_data *suspend, *next;
2000
2001        mutex_lock(&dev->dev_lock);
2002        list_for_each_entry_safe(suspend, next, &dev->unlk_lst, node) {
2003                list_del(&suspend->node);
2004                kfree(suspend);
2005        }
2006        mutex_unlock(&dev->dev_lock);
2007}
2008
2009void free_opal_dev(struct opal_dev *dev)
2010{
2011        if (!dev)
2012                return;
2013        clean_opal_dev(dev);
2014        kfree(dev);
2015}
2016EXPORT_SYMBOL(free_opal_dev);
2017
2018struct opal_dev *init_opal_dev(void *data, sec_send_recv *send_recv)
2019{
2020        struct opal_dev *dev;
2021
2022        dev = kmalloc(sizeof(*dev), GFP_KERNEL);
2023        if (!dev)
2024                return NULL;
2025
2026        INIT_LIST_HEAD(&dev->unlk_lst);
2027        mutex_init(&dev->dev_lock);
2028        dev->data = data;
2029        dev->send_recv = send_recv;
2030        if (check_opal_support(dev) != 0) {
2031                pr_debug("Opal is not supported on this device\n");
2032                kfree(dev);
2033                return NULL;
2034        }
2035        return dev;
2036}
2037EXPORT_SYMBOL(init_opal_dev);
2038
2039static int opal_secure_erase_locking_range(struct opal_dev *dev,
2040                                           struct opal_session_info *opal_session)
2041{
2042        const struct opal_step erase_steps[] = {
2043                { opal_discovery0, },
2044                { start_auth_opal_session, opal_session },
2045                { get_active_key, &opal_session->opal_key.lr },
2046                { gen_key, },
2047                { end_opal_session, },
2048                { NULL, }
2049        };
2050        int ret;
2051
2052        mutex_lock(&dev->dev_lock);
2053        setup_opal_dev(dev, erase_steps);
2054        ret = next(dev);
2055        mutex_unlock(&dev->dev_lock);
2056        return ret;
2057}
2058
2059static int opal_erase_locking_range(struct opal_dev *dev,
2060                                    struct opal_session_info *opal_session)
2061{
2062        const struct opal_step erase_steps[] = {
2063                { opal_discovery0, },
2064                { start_auth_opal_session, opal_session },
2065                { erase_locking_range, opal_session },
2066                { end_opal_session, },
2067                { NULL, }
2068        };
2069        int ret;
2070
2071        mutex_lock(&dev->dev_lock);
2072        setup_opal_dev(dev, erase_steps);
2073        ret = next(dev);
2074        mutex_unlock(&dev->dev_lock);
2075        return ret;
2076}
2077
2078static int opal_enable_disable_shadow_mbr(struct opal_dev *dev,
2079                                          struct opal_mbr_data *opal_mbr)
2080{
2081        const struct opal_step mbr_steps[] = {
2082                { opal_discovery0, },
2083                { start_admin1LSP_opal_session, &opal_mbr->key },
2084                { set_mbr_done, &opal_mbr->enable_disable },
2085                { end_opal_session, },
2086                { start_admin1LSP_opal_session, &opal_mbr->key },
2087                { set_mbr_enable_disable, &opal_mbr->enable_disable },
2088                { end_opal_session, },
2089                { NULL, }
2090        };
2091        int ret;
2092
2093        if (opal_mbr->enable_disable != OPAL_MBR_ENABLE &&
2094            opal_mbr->enable_disable != OPAL_MBR_DISABLE)
2095                return -EINVAL;
2096
2097        mutex_lock(&dev->dev_lock);
2098        setup_opal_dev(dev, mbr_steps);
2099        ret = next(dev);
2100        mutex_unlock(&dev->dev_lock);
2101        return ret;
2102}
2103
2104static int opal_save(struct opal_dev *dev, struct opal_lock_unlock *lk_unlk)
2105{
2106        struct opal_suspend_data *suspend;
2107
2108        suspend = kzalloc(sizeof(*suspend), GFP_KERNEL);
2109        if (!suspend)
2110                return -ENOMEM;
2111
2112        suspend->unlk = *lk_unlk;
2113        suspend->lr = lk_unlk->session.opal_key.lr;
2114
2115        mutex_lock(&dev->dev_lock);
2116        setup_opal_dev(dev, NULL);
2117        add_suspend_info(dev, suspend);
2118        mutex_unlock(&dev->dev_lock);
2119        return 0;
2120}
2121
2122static int opal_add_user_to_lr(struct opal_dev *dev,
2123                               struct opal_lock_unlock *lk_unlk)
2124{
2125        const struct opal_step steps[] = {
2126                { opal_discovery0, },
2127                { start_admin1LSP_opal_session, &lk_unlk->session.opal_key },
2128                { add_user_to_lr, lk_unlk },
2129                { end_opal_session, },
2130                { NULL, }
2131        };
2132        int ret;
2133
2134        if (lk_unlk->l_state != OPAL_RO &&
2135            lk_unlk->l_state != OPAL_RW) {
2136                pr_debug("Locking state was not RO or RW\n");
2137                return -EINVAL;
2138        }
2139        if (lk_unlk->session.who < OPAL_USER1 ||
2140            lk_unlk->session.who > OPAL_USER9) {
2141                pr_debug("Authority was not within the range of users: %d\n",
2142                         lk_unlk->session.who);
2143                return -EINVAL;
2144        }
2145        if (lk_unlk->session.sum) {
2146                pr_debug("%s not supported in sum. Use setup locking range\n",
2147                         __func__);
2148                return -EINVAL;
2149        }
2150
2151        mutex_lock(&dev->dev_lock);
2152        setup_opal_dev(dev, steps);
2153        ret = next(dev);
2154        mutex_unlock(&dev->dev_lock);
2155        return ret;
2156}
2157
2158static int opal_reverttper(struct opal_dev *dev, struct opal_key *opal)
2159{
2160        const struct opal_step revert_steps[] = {
2161                { opal_discovery0, },
2162                { start_SIDASP_opal_session, opal },
2163                { revert_tper, }, /* controller will terminate session */
2164                { NULL, }
2165        };
2166        int ret;
2167
2168        mutex_lock(&dev->dev_lock);
2169        setup_opal_dev(dev, revert_steps);
2170        ret = next(dev);
2171        mutex_unlock(&dev->dev_lock);
2172
2173        /*
2174         * If we successfully reverted lets clean
2175         * any saved locking ranges.
2176         */
2177        if (!ret)
2178                clean_opal_dev(dev);
2179
2180        return ret;
2181}
2182
2183static int __opal_lock_unlock(struct opal_dev *dev,
2184                              struct opal_lock_unlock *lk_unlk)
2185{
2186        const struct opal_step unlock_steps[] = {
2187                { opal_discovery0, },
2188                { start_auth_opal_session, &lk_unlk->session },
2189                { lock_unlock_locking_range, lk_unlk },
2190                { end_opal_session, },
2191                { NULL, }
2192        };
2193        const struct opal_step unlock_sum_steps[] = {
2194                { opal_discovery0, },
2195                { start_auth_opal_session, &lk_unlk->session },
2196                { lock_unlock_locking_range_sum, lk_unlk },
2197                { end_opal_session, },
2198                { NULL, }
2199        };
2200
2201        dev->steps = lk_unlk->session.sum ? unlock_sum_steps : unlock_steps;
2202        return next(dev);
2203}
2204
2205static int __opal_set_mbr_done(struct opal_dev *dev, struct opal_key *key)
2206{
2207        u8 mbr_done_tf = 1;
2208        const struct opal_step mbrdone_step [] = {
2209                { opal_discovery0, },
2210                { start_admin1LSP_opal_session, key },
2211                { set_mbr_done, &mbr_done_tf },
2212                { end_opal_session, },
2213                { NULL, }
2214        };
2215
2216        dev->steps = mbrdone_step;
2217        return next(dev);
2218}
2219
2220static int opal_lock_unlock(struct opal_dev *dev,
2221                            struct opal_lock_unlock *lk_unlk)
2222{
2223        int ret;
2224
2225        if (lk_unlk->session.who < OPAL_ADMIN1 ||
2226            lk_unlk->session.who > OPAL_USER9)
2227                return -EINVAL;
2228
2229        mutex_lock(&dev->dev_lock);
2230        ret = __opal_lock_unlock(dev, lk_unlk);
2231        mutex_unlock(&dev->dev_lock);
2232        return ret;
2233}
2234
2235static int opal_take_ownership(struct opal_dev *dev, struct opal_key *opal)
2236{
2237        const struct opal_step owner_steps[] = {
2238                { opal_discovery0, },
2239                { start_anybodyASP_opal_session, },
2240                { get_msid_cpin_pin, },
2241                { end_opal_session, },
2242                { start_SIDASP_opal_session, opal },
2243                { set_sid_cpin_pin, opal },
2244                { end_opal_session, },
2245                { NULL, }
2246        };
2247        int ret;
2248
2249        if (!dev)
2250                return -ENODEV;
2251
2252        mutex_lock(&dev->dev_lock);
2253        setup_opal_dev(dev, owner_steps);
2254        ret = next(dev);
2255        mutex_unlock(&dev->dev_lock);
2256        return ret;
2257}
2258
2259static int opal_activate_lsp(struct opal_dev *dev, struct opal_lr_act *opal_lr_act)
2260{
2261        const struct opal_step active_steps[] = {
2262                { opal_discovery0, },
2263                { start_SIDASP_opal_session, &opal_lr_act->key },
2264                { get_lsp_lifecycle, },
2265                { activate_lsp, opal_lr_act },
2266                { end_opal_session, },
2267                { NULL, }
2268        };
2269        int ret;
2270
2271        if (!opal_lr_act->num_lrs || opal_lr_act->num_lrs > OPAL_MAX_LRS)
2272                return -EINVAL;
2273
2274        mutex_lock(&dev->dev_lock);
2275        setup_opal_dev(dev, active_steps);
2276        ret = next(dev);
2277        mutex_unlock(&dev->dev_lock);
2278        return ret;
2279}
2280
2281static int opal_setup_locking_range(struct opal_dev *dev,
2282                                    struct opal_user_lr_setup *opal_lrs)
2283{
2284        const struct opal_step lr_steps[] = {
2285                { opal_discovery0, },
2286                { start_auth_opal_session, &opal_lrs->session },
2287                { setup_locking_range, opal_lrs },
2288                { end_opal_session, },
2289                { NULL, }
2290        };
2291        int ret;
2292
2293        mutex_lock(&dev->dev_lock);
2294        setup_opal_dev(dev, lr_steps);
2295        ret = next(dev);
2296        mutex_unlock(&dev->dev_lock);
2297        return ret;
2298}
2299
2300static int opal_set_new_pw(struct opal_dev *dev, struct opal_new_pw *opal_pw)
2301{
2302        const struct opal_step pw_steps[] = {
2303                { opal_discovery0, },
2304                { start_auth_opal_session, &opal_pw->session },
2305                { set_new_pw, &opal_pw->new_user_pw },
2306                { end_opal_session, },
2307                { NULL }
2308        };
2309        int ret;
2310
2311        if (opal_pw->session.who < OPAL_ADMIN1 ||
2312            opal_pw->session.who > OPAL_USER9  ||
2313            opal_pw->new_user_pw.who < OPAL_ADMIN1 ||
2314            opal_pw->new_user_pw.who > OPAL_USER9)
2315                return -EINVAL;
2316
2317        mutex_lock(&dev->dev_lock);
2318        setup_opal_dev(dev, pw_steps);
2319        ret = next(dev);
2320        mutex_unlock(&dev->dev_lock);
2321        return ret;
2322}
2323
2324static int opal_activate_user(struct opal_dev *dev,
2325                              struct opal_session_info *opal_session)
2326{
2327        const struct opal_step act_steps[] = {
2328                { opal_discovery0, },
2329                { start_admin1LSP_opal_session, &opal_session->opal_key },
2330                { internal_activate_user, opal_session },
2331                { end_opal_session, },
2332                { NULL, }
2333        };
2334        int ret;
2335
2336        /* We can't activate Admin1 it's active as manufactured */
2337        if (opal_session->who < OPAL_USER1 ||
2338            opal_session->who > OPAL_USER9) {
2339                pr_debug("Who was not a valid user: %d\n", opal_session->who);
2340                return -EINVAL;
2341        }
2342
2343        mutex_lock(&dev->dev_lock);
2344        setup_opal_dev(dev, act_steps);
2345        ret = next(dev);
2346        mutex_unlock(&dev->dev_lock);
2347        return ret;
2348}
2349
2350bool opal_unlock_from_suspend(struct opal_dev *dev)
2351{
2352        struct opal_suspend_data *suspend;
2353        bool was_failure = false;
2354        int ret = 0;
2355
2356        if (!dev)
2357                return false;
2358        if (!dev->supported)
2359                return false;
2360
2361        mutex_lock(&dev->dev_lock);
2362        setup_opal_dev(dev, NULL);
2363
2364        list_for_each_entry(suspend, &dev->unlk_lst, node) {
2365                dev->tsn = 0;
2366                dev->hsn = 0;
2367
2368                ret = __opal_lock_unlock(dev, &suspend->unlk);
2369                if (ret) {
2370                        pr_debug("Failed to unlock LR %hhu with sum %d\n",
2371                                 suspend->unlk.session.opal_key.lr,
2372                                 suspend->unlk.session.sum);
2373                        was_failure = true;
2374                }
2375                if (dev->mbr_enabled) {
2376                        ret = __opal_set_mbr_done(dev, &suspend->unlk.session.opal_key);
2377                        if (ret)
2378                                pr_debug("Failed to set MBR Done in S3 resume\n");
2379                }
2380        }
2381        mutex_unlock(&dev->dev_lock);
2382        return was_failure;
2383}
2384EXPORT_SYMBOL(opal_unlock_from_suspend);
2385
2386int sed_ioctl(struct opal_dev *dev, unsigned int cmd, void __user *arg)
2387{
2388        void *p;
2389        int ret = -ENOTTY;
2390
2391        if (!capable(CAP_SYS_ADMIN))
2392                return -EACCES;
2393        if (!dev)
2394                return -ENOTSUPP;
2395        if (!dev->supported)
2396                return -ENOTSUPP;
2397
2398        p = memdup_user(arg, _IOC_SIZE(cmd));
2399        if (IS_ERR(p))
2400                return PTR_ERR(p);
2401
2402        switch (cmd) {
2403        case IOC_OPAL_SAVE:
2404                ret = opal_save(dev, p);
2405                break;
2406        case IOC_OPAL_LOCK_UNLOCK:
2407                ret = opal_lock_unlock(dev, p);
2408                break;
2409        case IOC_OPAL_TAKE_OWNERSHIP:
2410                ret = opal_take_ownership(dev, p);
2411                break;
2412        case IOC_OPAL_ACTIVATE_LSP:
2413                ret = opal_activate_lsp(dev, p);
2414                break;
2415        case IOC_OPAL_SET_PW:
2416                ret = opal_set_new_pw(dev, p);
2417                break;
2418        case IOC_OPAL_ACTIVATE_USR:
2419                ret = opal_activate_user(dev, p);
2420                break;
2421        case IOC_OPAL_REVERT_TPR:
2422                ret = opal_reverttper(dev, p);
2423                break;
2424        case IOC_OPAL_LR_SETUP:
2425                ret = opal_setup_locking_range(dev, p);
2426                break;
2427        case IOC_OPAL_ADD_USR_TO_LR:
2428                ret = opal_add_user_to_lr(dev, p);
2429                break;
2430        case IOC_OPAL_ENABLE_DISABLE_MBR:
2431                ret = opal_enable_disable_shadow_mbr(dev, p);
2432                break;
2433        case IOC_OPAL_ERASE_LR:
2434                ret = opal_erase_locking_range(dev, p);
2435                break;
2436        case IOC_OPAL_SECURE_ERASE_LR:
2437                ret = opal_secure_erase_locking_range(dev, p);
2438                break;
2439        default:
2440                break;
2441        }
2442
2443        kfree(p);
2444        return ret;
2445}
2446EXPORT_SYMBOL_GPL(sed_ioctl);
2447