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