.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0 |
---|
1 | 2 | /* |
---|
2 | 3 | * Copyright © 2016 Intel Corporation |
---|
3 | 4 | * |
---|
4 | 5 | * Authors: |
---|
5 | 6 | * Scott Bauer <scott.bauer@intel.com> |
---|
6 | 7 | * 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 | 8 | */ |
---|
17 | 9 | |
---|
18 | 10 | #define pr_fmt(fmt) KBUILD_MODNAME ":OPAL: " fmt |
---|
.. | .. |
---|
33 | 25 | |
---|
34 | 26 | #define IO_BUFFER_LENGTH 2048 |
---|
35 | 27 | #define MAX_TOKS 64 |
---|
| 28 | + |
---|
| 29 | +/* Number of bytes needed by cmd_finalize. */ |
---|
| 30 | +#define CMD_FINALIZE_BYTES_NEEDED 7 |
---|
36 | 31 | |
---|
37 | 32 | struct opal_step { |
---|
38 | 33 | int (*fn)(struct opal_dev *dev, void *data); |
---|
.. | .. |
---|
85 | 80 | void *data; |
---|
86 | 81 | sec_send_recv *send_recv; |
---|
87 | 82 | |
---|
88 | | - const struct opal_step *steps; |
---|
89 | 83 | struct mutex dev_lock; |
---|
90 | 84 | u16 comid; |
---|
91 | 85 | u32 hsn; |
---|
.. | .. |
---|
94 | 88 | u64 lowest_lba; |
---|
95 | 89 | |
---|
96 | 90 | size_t pos; |
---|
97 | | - u8 cmd[IO_BUFFER_LENGTH]; |
---|
98 | | - u8 resp[IO_BUFFER_LENGTH]; |
---|
| 91 | + u8 *cmd; |
---|
| 92 | + u8 *resp; |
---|
99 | 93 | |
---|
100 | 94 | struct parsed_resp parsed; |
---|
101 | 95 | size_t prev_d_len; |
---|
.. | .. |
---|
135 | 129 | { 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x84, 0x01 }, |
---|
136 | 130 | |
---|
137 | 131 | /* tables */ |
---|
138 | | - |
---|
| 132 | + [OPAL_TABLE_TABLE] = |
---|
| 133 | + { 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01 }, |
---|
139 | 134 | [OPAL_LOCKINGRANGE_GLOBAL] = |
---|
140 | 135 | { 0x00, 0x00, 0x08, 0x02, 0x00, 0x00, 0x00, 0x01 }, |
---|
141 | 136 | [OPAL_LOCKINGRANGE_ACE_RDLOCKED] = |
---|
.. | .. |
---|
154 | 149 | { 0x00, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x01 }, |
---|
155 | 150 | [OPAL_ENTERPRISE_LOCKING_INFO_TABLE] = |
---|
156 | 151 | { 0x00, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x00 }, |
---|
| 152 | + [OPAL_DATASTORE] = |
---|
| 153 | + { 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x00, 0x00 }, |
---|
157 | 154 | |
---|
158 | 155 | /* C_PIN_TABLE object ID's */ |
---|
159 | | - |
---|
160 | | - [OPAL_C_PIN_MSID] = |
---|
| 156 | + [OPAL_C_PIN_MSID] = |
---|
161 | 157 | { 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x84, 0x02}, |
---|
162 | 158 | [OPAL_C_PIN_SID] = |
---|
163 | 159 | { 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x01}, |
---|
.. | .. |
---|
165 | 161 | { 0x00, 0x00, 0x00, 0x0B, 0x00, 0x01, 0x00, 0x01}, |
---|
166 | 162 | |
---|
167 | 163 | /* half UID's (only first 4 bytes used) */ |
---|
168 | | - |
---|
169 | 164 | [OPAL_HALF_UID_AUTHORITY_OBJ_REF] = |
---|
170 | 165 | { 0x00, 0x00, 0x0C, 0x05, 0xff, 0xff, 0xff, 0xff }, |
---|
171 | 166 | [OPAL_HALF_UID_BOOLEAN_ACE] = |
---|
.. | .. |
---|
181 | 176 | * Derived from: TCG_Storage_Architecture_Core_Spec_v2.01_r1.00 |
---|
182 | 177 | * Section: 6.3 Assigned UIDs |
---|
183 | 178 | */ |
---|
184 | | -static const u8 opalmethod[][OPAL_UID_LENGTH] = { |
---|
| 179 | +static const u8 opalmethod[][OPAL_METHOD_LENGTH] = { |
---|
185 | 180 | [OPAL_PROPERTIES] = |
---|
186 | 181 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x01 }, |
---|
187 | 182 | [OPAL_STARTSESSION] = |
---|
.. | .. |
---|
217 | 212 | }; |
---|
218 | 213 | |
---|
219 | 214 | static int end_opal_session_error(struct opal_dev *dev); |
---|
| 215 | +static int opal_discovery0_step(struct opal_dev *dev); |
---|
220 | 216 | |
---|
221 | 217 | struct opal_suspend_data { |
---|
222 | 218 | struct opal_lock_unlock unlk; |
---|
.. | .. |
---|
378 | 374 | { |
---|
379 | 375 | const struct d0_geometry_features *geo = data; |
---|
380 | 376 | |
---|
381 | | - dev->align = geo->alignment_granularity; |
---|
382 | | - dev->lowest_lba = geo->lowest_aligned_lba; |
---|
| 377 | + dev->align = be64_to_cpu(geo->alignment_granularity); |
---|
| 378 | + dev->lowest_lba = be64_to_cpu(geo->lowest_aligned_lba); |
---|
383 | 379 | } |
---|
384 | 380 | |
---|
385 | | -static int next(struct opal_dev *dev) |
---|
| 381 | +static int execute_step(struct opal_dev *dev, |
---|
| 382 | + const struct opal_step *step, size_t stepIndex) |
---|
386 | 383 | { |
---|
387 | | - const struct opal_step *step; |
---|
388 | | - int state = 0, error = 0; |
---|
| 384 | + int error = step->fn(dev, step->data); |
---|
389 | 385 | |
---|
390 | | - do { |
---|
391 | | - step = &dev->steps[state]; |
---|
392 | | - if (!step->fn) |
---|
393 | | - break; |
---|
| 386 | + if (error) { |
---|
| 387 | + pr_debug("Step %zu (%pS) failed with error %d: %s\n", |
---|
| 388 | + stepIndex, step->fn, error, |
---|
| 389 | + opal_error_to_human(error)); |
---|
| 390 | + } |
---|
394 | 391 | |
---|
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)); |
---|
| 392 | + return error; |
---|
| 393 | +} |
---|
400 | 394 | |
---|
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 | | - } |
---|
| 395 | +static int execute_steps(struct opal_dev *dev, |
---|
| 396 | + const struct opal_step *steps, size_t n_steps) |
---|
| 397 | +{ |
---|
| 398 | + size_t state = 0; |
---|
| 399 | + int error; |
---|
412 | 400 | |
---|
413 | | - } |
---|
414 | | - state++; |
---|
415 | | - } while (!error); |
---|
| 401 | + /* first do a discovery0 */ |
---|
| 402 | + error = opal_discovery0_step(dev); |
---|
| 403 | + if (error) |
---|
| 404 | + return error; |
---|
| 405 | + |
---|
| 406 | + for (state = 0; state < n_steps; state++) { |
---|
| 407 | + error = execute_step(dev, &steps[state], state); |
---|
| 408 | + if (error) |
---|
| 409 | + goto out_error; |
---|
| 410 | + } |
---|
| 411 | + |
---|
| 412 | + return 0; |
---|
| 413 | + |
---|
| 414 | +out_error: |
---|
| 415 | + /* |
---|
| 416 | + * For each OPAL command the first step in steps starts some sort of |
---|
| 417 | + * session. If an error occurred in the initial discovery0 or if an |
---|
| 418 | + * error occurred in the first step (and thus stopping the loop with |
---|
| 419 | + * state == 0) then there was an error before or during the attempt to |
---|
| 420 | + * start a session. Therefore we shouldn't attempt to terminate a |
---|
| 421 | + * session, as one has not yet been created. |
---|
| 422 | + */ |
---|
| 423 | + if (state > 0) |
---|
| 424 | + end_opal_session_error(dev); |
---|
416 | 425 | |
---|
417 | 426 | return error; |
---|
418 | 427 | } |
---|
.. | .. |
---|
507 | 516 | ret = opal_recv_cmd(dev); |
---|
508 | 517 | if (ret) |
---|
509 | 518 | return ret; |
---|
| 519 | + |
---|
510 | 520 | return opal_discovery0_end(dev); |
---|
| 521 | +} |
---|
| 522 | + |
---|
| 523 | +static int opal_discovery0_step(struct opal_dev *dev) |
---|
| 524 | +{ |
---|
| 525 | + const struct opal_step discovery0_step = { |
---|
| 526 | + opal_discovery0, |
---|
| 527 | + }; |
---|
| 528 | + |
---|
| 529 | + return execute_step(dev, &discovery0_step, 0); |
---|
| 530 | +} |
---|
| 531 | + |
---|
| 532 | +static size_t remaining_size(struct opal_dev *cmd) |
---|
| 533 | +{ |
---|
| 534 | + return IO_BUFFER_LENGTH - cmd->pos; |
---|
| 535 | +} |
---|
| 536 | + |
---|
| 537 | +static bool can_add(int *err, struct opal_dev *cmd, size_t len) |
---|
| 538 | +{ |
---|
| 539 | + if (*err) |
---|
| 540 | + return false; |
---|
| 541 | + |
---|
| 542 | + if (remaining_size(cmd) < len) { |
---|
| 543 | + pr_debug("Error adding %zu bytes: end of buffer.\n", len); |
---|
| 544 | + *err = -ERANGE; |
---|
| 545 | + return false; |
---|
| 546 | + } |
---|
| 547 | + |
---|
| 548 | + return true; |
---|
511 | 549 | } |
---|
512 | 550 | |
---|
513 | 551 | static void add_token_u8(int *err, struct opal_dev *cmd, u8 tok) |
---|
514 | 552 | { |
---|
515 | | - if (*err) |
---|
| 553 | + if (!can_add(err, cmd, 1)) |
---|
516 | 554 | 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 | | - } |
---|
| 555 | + |
---|
522 | 556 | cmd->cmd[cmd->pos++] = tok; |
---|
523 | 557 | } |
---|
524 | 558 | |
---|
.. | .. |
---|
545 | 579 | header0 |= bytestring ? MEDIUM_ATOM_BYTESTRING : 0; |
---|
546 | 580 | header0 |= has_sign ? MEDIUM_ATOM_SIGNED : 0; |
---|
547 | 581 | header0 |= (len >> 8) & MEDIUM_ATOM_LEN_MASK; |
---|
| 582 | + |
---|
548 | 583 | cmd->cmd[cmd->pos++] = header0; |
---|
549 | 584 | cmd->cmd[cmd->pos++] = len; |
---|
550 | 585 | } |
---|
551 | 586 | |
---|
552 | 587 | static void add_token_u64(int *err, struct opal_dev *cmd, u64 number) |
---|
553 | 588 | { |
---|
554 | | - |
---|
555 | 589 | size_t len; |
---|
556 | 590 | int msb; |
---|
557 | 591 | |
---|
.. | .. |
---|
563 | 597 | msb = fls64(number); |
---|
564 | 598 | len = DIV_ROUND_UP(msb, 8); |
---|
565 | 599 | |
---|
566 | | - if (cmd->pos >= IO_BUFFER_LENGTH - len - 1) { |
---|
| 600 | + if (!can_add(err, cmd, len + 1)) { |
---|
567 | 601 | pr_debug("Error adding u64: end of buffer.\n"); |
---|
568 | | - *err = -ERANGE; |
---|
569 | 602 | return; |
---|
570 | 603 | } |
---|
571 | 604 | add_short_atom_header(cmd, false, false, len); |
---|
.. | .. |
---|
573 | 606 | add_token_u8(err, cmd, number >> (len * 8)); |
---|
574 | 607 | } |
---|
575 | 608 | |
---|
576 | | -static void add_token_bytestring(int *err, struct opal_dev *cmd, |
---|
577 | | - const u8 *bytestring, size_t len) |
---|
| 609 | +static u8 *add_bytestring_header(int *err, struct opal_dev *cmd, size_t len) |
---|
578 | 610 | { |
---|
579 | 611 | size_t header_len = 1; |
---|
580 | 612 | bool is_short_atom = true; |
---|
581 | | - |
---|
582 | | - if (*err) |
---|
583 | | - return; |
---|
584 | 613 | |
---|
585 | 614 | if (len & ~SHORT_ATOM_LEN_MASK) { |
---|
586 | 615 | header_len = 2; |
---|
587 | 616 | is_short_atom = false; |
---|
588 | 617 | } |
---|
589 | 618 | |
---|
590 | | - if (len >= IO_BUFFER_LENGTH - cmd->pos - header_len) { |
---|
| 619 | + if (!can_add(err, cmd, header_len + len)) { |
---|
591 | 620 | pr_debug("Error adding bytestring: end of buffer.\n"); |
---|
592 | | - *err = -ERANGE; |
---|
593 | | - return; |
---|
| 621 | + return NULL; |
---|
594 | 622 | } |
---|
595 | 623 | |
---|
596 | 624 | if (is_short_atom) |
---|
.. | .. |
---|
598 | 626 | else |
---|
599 | 627 | add_medium_atom_header(cmd, true, false, len); |
---|
600 | 628 | |
---|
601 | | - memcpy(&cmd->cmd[cmd->pos], bytestring, len); |
---|
602 | | - cmd->pos += len; |
---|
| 629 | + return &cmd->cmd[cmd->pos]; |
---|
| 630 | +} |
---|
603 | 631 | |
---|
| 632 | +static void add_token_bytestring(int *err, struct opal_dev *cmd, |
---|
| 633 | + const u8 *bytestring, size_t len) |
---|
| 634 | +{ |
---|
| 635 | + u8 *start; |
---|
| 636 | + |
---|
| 637 | + start = add_bytestring_header(err, cmd, len); |
---|
| 638 | + if (!start) |
---|
| 639 | + return; |
---|
| 640 | + memcpy(start, bytestring, len); |
---|
| 641 | + cmd->pos += len; |
---|
604 | 642 | } |
---|
605 | 643 | |
---|
606 | 644 | static int build_locking_range(u8 *buffer, size_t length, u8 lr) |
---|
.. | .. |
---|
614 | 652 | |
---|
615 | 653 | if (lr == 0) |
---|
616 | 654 | return 0; |
---|
| 655 | + |
---|
617 | 656 | buffer[5] = LOCKING_RANGE_NON_GLOBAL; |
---|
618 | 657 | buffer[7] = lr; |
---|
619 | 658 | |
---|
.. | .. |
---|
623 | 662 | static int build_locking_user(u8 *buffer, size_t length, u8 lr) |
---|
624 | 663 | { |
---|
625 | 664 | if (length > OPAL_UID_LENGTH) { |
---|
626 | | - pr_debug("Can't build locking range user, Length OOB\n"); |
---|
| 665 | + pr_debug("Can't build locking range user. Length OOB\n"); |
---|
627 | 666 | return -ERANGE; |
---|
628 | 667 | } |
---|
629 | 668 | |
---|
.. | .. |
---|
648 | 687 | { |
---|
649 | 688 | struct opal_header *hdr; |
---|
650 | 689 | int err = 0; |
---|
| 690 | + |
---|
| 691 | + /* |
---|
| 692 | + * Close the parameter list opened from cmd_start. |
---|
| 693 | + * The number of bytes added must be equal to |
---|
| 694 | + * CMD_FINALIZE_BYTES_NEEDED. |
---|
| 695 | + */ |
---|
| 696 | + add_token_u8(&err, cmd, OPAL_ENDLIST); |
---|
651 | 697 | |
---|
652 | 698 | add_token_u8(&err, cmd, OPAL_ENDOFDATA); |
---|
653 | 699 | add_token_u8(&err, cmd, OPAL_STARTLIST); |
---|
.. | .. |
---|
686 | 732 | int n) |
---|
687 | 733 | { |
---|
688 | 734 | const struct opal_resp_tok *tok; |
---|
| 735 | + |
---|
| 736 | + if (!resp) { |
---|
| 737 | + pr_debug("Response is NULL\n"); |
---|
| 738 | + return ERR_PTR(-EINVAL); |
---|
| 739 | + } |
---|
689 | 740 | |
---|
690 | 741 | if (n >= resp->num) { |
---|
691 | 742 | pr_debug("Token number doesn't exist: %d, resp: %d\n", |
---|
.. | .. |
---|
856 | 907 | num_entries++; |
---|
857 | 908 | } |
---|
858 | 909 | |
---|
859 | | - if (num_entries == 0) { |
---|
860 | | - pr_debug("Couldn't parse response.\n"); |
---|
861 | | - return -EINVAL; |
---|
862 | | - } |
---|
863 | 910 | resp->num = num_entries; |
---|
864 | 911 | |
---|
865 | 912 | return 0; |
---|
.. | .. |
---|
869 | 916 | const char **store) |
---|
870 | 917 | { |
---|
871 | 918 | u8 skip; |
---|
872 | | - const struct opal_resp_tok *token; |
---|
| 919 | + const struct opal_resp_tok *tok; |
---|
873 | 920 | |
---|
874 | 921 | *store = NULL; |
---|
875 | | - if (!resp) { |
---|
876 | | - pr_debug("Response is NULL\n"); |
---|
| 922 | + tok = response_get_token(resp, n); |
---|
| 923 | + if (IS_ERR(tok)) |
---|
877 | 924 | return 0; |
---|
878 | | - } |
---|
879 | 925 | |
---|
880 | | - if (n >= resp->num) { |
---|
881 | | - pr_debug("Response has %d tokens. Can't access %d\n", |
---|
882 | | - resp->num, n); |
---|
883 | | - return 0; |
---|
884 | | - } |
---|
885 | | - |
---|
886 | | - token = &resp->toks[n]; |
---|
887 | | - if (token->type != OPAL_DTA_TOKENID_BYTESTRING) { |
---|
| 926 | + if (tok->type != OPAL_DTA_TOKENID_BYTESTRING) { |
---|
888 | 927 | pr_debug("Token is not a byte string!\n"); |
---|
889 | 928 | return 0; |
---|
890 | 929 | } |
---|
891 | 930 | |
---|
892 | | - switch (token->width) { |
---|
| 931 | + switch (tok->width) { |
---|
893 | 932 | case OPAL_WIDTH_TINY: |
---|
894 | 933 | case OPAL_WIDTH_SHORT: |
---|
895 | 934 | skip = 1; |
---|
.. | .. |
---|
905 | 944 | return 0; |
---|
906 | 945 | } |
---|
907 | 946 | |
---|
908 | | - *store = token->pos + skip; |
---|
909 | | - return token->len - skip; |
---|
| 947 | + *store = tok->pos + skip; |
---|
| 948 | + |
---|
| 949 | + return tok->len - skip; |
---|
910 | 950 | } |
---|
911 | 951 | |
---|
912 | 952 | static u64 response_get_u64(const struct parsed_resp *resp, int n) |
---|
913 | 953 | { |
---|
914 | | - if (!resp) { |
---|
915 | | - pr_debug("Response is NULL\n"); |
---|
| 954 | + const struct opal_resp_tok *tok; |
---|
| 955 | + |
---|
| 956 | + tok = response_get_token(resp, n); |
---|
| 957 | + if (IS_ERR(tok)) |
---|
| 958 | + return 0; |
---|
| 959 | + |
---|
| 960 | + if (tok->type != OPAL_DTA_TOKENID_UINT) { |
---|
| 961 | + pr_debug("Token is not unsigned int: %d\n", tok->type); |
---|
916 | 962 | return 0; |
---|
917 | 963 | } |
---|
918 | 964 | |
---|
919 | | - if (n >= resp->num) { |
---|
920 | | - pr_debug("Response has %d tokens. Can't access %d\n", |
---|
921 | | - resp->num, n); |
---|
| 965 | + if (tok->width != OPAL_WIDTH_TINY && tok->width != OPAL_WIDTH_SHORT) { |
---|
| 966 | + pr_debug("Atom is not short or tiny: %d\n", tok->width); |
---|
922 | 967 | return 0; |
---|
923 | 968 | } |
---|
924 | 969 | |
---|
925 | | - if (resp->toks[n].type != OPAL_DTA_TOKENID_UINT) { |
---|
926 | | - pr_debug("Token is not unsigned it: %d\n", |
---|
927 | | - resp->toks[n].type); |
---|
928 | | - return 0; |
---|
929 | | - } |
---|
930 | | - |
---|
931 | | - if (!(resp->toks[n].width == OPAL_WIDTH_TINY || |
---|
932 | | - resp->toks[n].width == OPAL_WIDTH_SHORT)) { |
---|
933 | | - pr_debug("Atom is not short or tiny: %d\n", |
---|
934 | | - resp->toks[n].width); |
---|
935 | | - return 0; |
---|
936 | | - } |
---|
937 | | - |
---|
938 | | - return resp->toks[n].stored.u; |
---|
| 970 | + return tok->stored.u; |
---|
939 | 971 | } |
---|
940 | 972 | |
---|
941 | 973 | static bool response_token_matches(const struct opal_resp_tok *token, u8 match) |
---|
.. | .. |
---|
991 | 1023 | memset(dev->cmd, 0, IO_BUFFER_LENGTH); |
---|
992 | 1024 | } |
---|
993 | 1025 | |
---|
| 1026 | +static int cmd_start(struct opal_dev *dev, const u8 *uid, const u8 *method) |
---|
| 1027 | +{ |
---|
| 1028 | + int err = 0; |
---|
| 1029 | + |
---|
| 1030 | + clear_opal_cmd(dev); |
---|
| 1031 | + set_comid(dev, dev->comid); |
---|
| 1032 | + |
---|
| 1033 | + add_token_u8(&err, dev, OPAL_CALL); |
---|
| 1034 | + add_token_bytestring(&err, dev, uid, OPAL_UID_LENGTH); |
---|
| 1035 | + add_token_bytestring(&err, dev, method, OPAL_METHOD_LENGTH); |
---|
| 1036 | + |
---|
| 1037 | + /* |
---|
| 1038 | + * Every method call is followed by its parameters enclosed within |
---|
| 1039 | + * OPAL_STARTLIST and OPAL_ENDLIST tokens. We automatically open the |
---|
| 1040 | + * parameter list here and close it later in cmd_finalize. |
---|
| 1041 | + */ |
---|
| 1042 | + add_token_u8(&err, dev, OPAL_STARTLIST); |
---|
| 1043 | + |
---|
| 1044 | + return err; |
---|
| 1045 | +} |
---|
| 1046 | + |
---|
994 | 1047 | static int start_opal_session_cont(struct opal_dev *dev) |
---|
995 | 1048 | { |
---|
996 | 1049 | u32 hsn, tsn; |
---|
.. | .. |
---|
1003 | 1056 | hsn = response_get_u64(&dev->parsed, 4); |
---|
1004 | 1057 | tsn = response_get_u64(&dev->parsed, 5); |
---|
1005 | 1058 | |
---|
1006 | | - if (hsn == 0 && tsn == 0) { |
---|
| 1059 | + if (hsn != GENERIC_HOST_SESSION_NUM || tsn < FIRST_TPER_SESSION_NUM) { |
---|
1007 | 1060 | pr_debug("Couldn't authenticate session\n"); |
---|
1008 | 1061 | return -EPERM; |
---|
1009 | 1062 | } |
---|
1010 | 1063 | |
---|
1011 | 1064 | dev->hsn = hsn; |
---|
1012 | 1065 | dev->tsn = tsn; |
---|
| 1066 | + |
---|
1013 | 1067 | return 0; |
---|
1014 | 1068 | } |
---|
1015 | 1069 | |
---|
.. | .. |
---|
1032 | 1086 | { |
---|
1033 | 1087 | dev->hsn = 0; |
---|
1034 | 1088 | dev->tsn = 0; |
---|
| 1089 | + |
---|
1035 | 1090 | return parse_and_check_status(dev); |
---|
1036 | 1091 | } |
---|
1037 | 1092 | |
---|
.. | .. |
---|
1050 | 1105 | return opal_send_recv(dev, cont); |
---|
1051 | 1106 | } |
---|
1052 | 1107 | |
---|
| 1108 | +/* |
---|
| 1109 | + * request @column from table @table on device @dev. On success, the column |
---|
| 1110 | + * data will be available in dev->resp->tok[4] |
---|
| 1111 | + */ |
---|
| 1112 | +static int generic_get_column(struct opal_dev *dev, const u8 *table, |
---|
| 1113 | + u64 column) |
---|
| 1114 | +{ |
---|
| 1115 | + int err; |
---|
| 1116 | + |
---|
| 1117 | + err = cmd_start(dev, table, opalmethod[OPAL_GET]); |
---|
| 1118 | + |
---|
| 1119 | + add_token_u8(&err, dev, OPAL_STARTLIST); |
---|
| 1120 | + |
---|
| 1121 | + add_token_u8(&err, dev, OPAL_STARTNAME); |
---|
| 1122 | + add_token_u8(&err, dev, OPAL_STARTCOLUMN); |
---|
| 1123 | + add_token_u64(&err, dev, column); |
---|
| 1124 | + add_token_u8(&err, dev, OPAL_ENDNAME); |
---|
| 1125 | + |
---|
| 1126 | + add_token_u8(&err, dev, OPAL_STARTNAME); |
---|
| 1127 | + add_token_u8(&err, dev, OPAL_ENDCOLUMN); |
---|
| 1128 | + add_token_u64(&err, dev, column); |
---|
| 1129 | + add_token_u8(&err, dev, OPAL_ENDNAME); |
---|
| 1130 | + |
---|
| 1131 | + add_token_u8(&err, dev, OPAL_ENDLIST); |
---|
| 1132 | + |
---|
| 1133 | + if (err) |
---|
| 1134 | + return err; |
---|
| 1135 | + |
---|
| 1136 | + return finalize_and_send(dev, parse_and_check_status); |
---|
| 1137 | +} |
---|
| 1138 | + |
---|
| 1139 | +/* |
---|
| 1140 | + * see TCG SAS 5.3.2.3 for a description of the available columns |
---|
| 1141 | + * |
---|
| 1142 | + * the result is provided in dev->resp->tok[4] |
---|
| 1143 | + */ |
---|
| 1144 | +static int generic_get_table_info(struct opal_dev *dev, const u8 *table_uid, |
---|
| 1145 | + u64 column) |
---|
| 1146 | +{ |
---|
| 1147 | + u8 uid[OPAL_UID_LENGTH]; |
---|
| 1148 | + const unsigned int half = OPAL_UID_LENGTH_HALF; |
---|
| 1149 | + |
---|
| 1150 | + /* sed-opal UIDs can be split in two halves: |
---|
| 1151 | + * first: actual table index |
---|
| 1152 | + * second: relative index in the table |
---|
| 1153 | + * so we have to get the first half of the OPAL_TABLE_TABLE and use the |
---|
| 1154 | + * first part of the target table as relative index into that table |
---|
| 1155 | + */ |
---|
| 1156 | + memcpy(uid, opaluid[OPAL_TABLE_TABLE], half); |
---|
| 1157 | + memcpy(uid + half, table_uid, half); |
---|
| 1158 | + |
---|
| 1159 | + return generic_get_column(dev, uid, column); |
---|
| 1160 | +} |
---|
| 1161 | + |
---|
1053 | 1162 | static int gen_key(struct opal_dev *dev, void *data) |
---|
1054 | 1163 | { |
---|
1055 | 1164 | u8 uid[OPAL_UID_LENGTH]; |
---|
1056 | | - int err = 0; |
---|
1057 | | - |
---|
1058 | | - clear_opal_cmd(dev); |
---|
1059 | | - set_comid(dev, dev->comid); |
---|
| 1165 | + int err; |
---|
1060 | 1166 | |
---|
1061 | 1167 | memcpy(uid, dev->prev_data, min(sizeof(uid), dev->prev_d_len)); |
---|
1062 | 1168 | kfree(dev->prev_data); |
---|
1063 | 1169 | dev->prev_data = NULL; |
---|
1064 | 1170 | |
---|
1065 | | - add_token_u8(&err, dev, OPAL_CALL); |
---|
1066 | | - add_token_bytestring(&err, dev, uid, OPAL_UID_LENGTH); |
---|
1067 | | - add_token_bytestring(&err, dev, opalmethod[OPAL_GENKEY], |
---|
1068 | | - OPAL_UID_LENGTH); |
---|
1069 | | - add_token_u8(&err, dev, OPAL_STARTLIST); |
---|
1070 | | - add_token_u8(&err, dev, OPAL_ENDLIST); |
---|
| 1171 | + err = cmd_start(dev, uid, opalmethod[OPAL_GENKEY]); |
---|
1071 | 1172 | |
---|
1072 | 1173 | if (err) { |
---|
1073 | 1174 | pr_debug("Error building gen key command\n"); |
---|
1074 | 1175 | return err; |
---|
1075 | 1176 | |
---|
1076 | 1177 | } |
---|
| 1178 | + |
---|
1077 | 1179 | return finalize_and_send(dev, parse_and_check_status); |
---|
1078 | 1180 | } |
---|
1079 | 1181 | |
---|
.. | .. |
---|
1086 | 1188 | error = parse_and_check_status(dev); |
---|
1087 | 1189 | if (error) |
---|
1088 | 1190 | return error; |
---|
| 1191 | + |
---|
1089 | 1192 | keylen = response_get_string(&dev->parsed, 4, &activekey); |
---|
1090 | 1193 | if (!activekey) { |
---|
1091 | 1194 | pr_debug("%s: Couldn't extract the Activekey from the response\n", |
---|
1092 | 1195 | __func__); |
---|
1093 | 1196 | return OPAL_INVAL_PARAM; |
---|
1094 | 1197 | } |
---|
| 1198 | + |
---|
1095 | 1199 | dev->prev_data = kmemdup(activekey, keylen, GFP_KERNEL); |
---|
1096 | 1200 | |
---|
1097 | 1201 | if (!dev->prev_data) |
---|
.. | .. |
---|
1105 | 1209 | static int get_active_key(struct opal_dev *dev, void *data) |
---|
1106 | 1210 | { |
---|
1107 | 1211 | u8 uid[OPAL_UID_LENGTH]; |
---|
1108 | | - int err = 0; |
---|
| 1212 | + int err; |
---|
1109 | 1213 | u8 *lr = data; |
---|
1110 | | - |
---|
1111 | | - clear_opal_cmd(dev); |
---|
1112 | | - set_comid(dev, dev->comid); |
---|
1113 | 1214 | |
---|
1114 | 1215 | err = build_locking_range(uid, sizeof(uid), *lr); |
---|
1115 | 1216 | if (err) |
---|
1116 | 1217 | return err; |
---|
1117 | 1218 | |
---|
1118 | | - err = 0; |
---|
1119 | | - add_token_u8(&err, dev, OPAL_CALL); |
---|
1120 | | - add_token_bytestring(&err, dev, uid, OPAL_UID_LENGTH); |
---|
1121 | | - add_token_bytestring(&err, dev, opalmethod[OPAL_GET], OPAL_UID_LENGTH); |
---|
1122 | | - add_token_u8(&err, dev, OPAL_STARTLIST); |
---|
1123 | | - add_token_u8(&err, dev, OPAL_STARTLIST); |
---|
1124 | | - add_token_u8(&err, dev, OPAL_STARTNAME); |
---|
1125 | | - add_token_u8(&err, dev, 3); /* startCloumn */ |
---|
1126 | | - add_token_u8(&err, dev, 10); /* ActiveKey */ |
---|
1127 | | - add_token_u8(&err, dev, OPAL_ENDNAME); |
---|
1128 | | - add_token_u8(&err, dev, OPAL_STARTNAME); |
---|
1129 | | - add_token_u8(&err, dev, 4); /* endColumn */ |
---|
1130 | | - add_token_u8(&err, dev, 10); /* ActiveKey */ |
---|
1131 | | - add_token_u8(&err, dev, OPAL_ENDNAME); |
---|
1132 | | - add_token_u8(&err, dev, OPAL_ENDLIST); |
---|
1133 | | - add_token_u8(&err, dev, OPAL_ENDLIST); |
---|
| 1219 | + err = generic_get_column(dev, uid, OPAL_ACTIVEKEY); |
---|
| 1220 | + if (err) |
---|
| 1221 | + return err; |
---|
| 1222 | + |
---|
| 1223 | + return get_active_key_cont(dev); |
---|
| 1224 | +} |
---|
| 1225 | + |
---|
| 1226 | +static int generic_table_write_data(struct opal_dev *dev, const u64 data, |
---|
| 1227 | + u64 offset, u64 size, const u8 *uid) |
---|
| 1228 | +{ |
---|
| 1229 | + const u8 __user *src = (u8 __user *)(uintptr_t)data; |
---|
| 1230 | + u8 *dst; |
---|
| 1231 | + u64 len; |
---|
| 1232 | + size_t off = 0; |
---|
| 1233 | + int err; |
---|
| 1234 | + |
---|
| 1235 | + /* do we fit in the available space? */ |
---|
| 1236 | + err = generic_get_table_info(dev, uid, OPAL_TABLE_ROWS); |
---|
1134 | 1237 | if (err) { |
---|
1135 | | - pr_debug("Error building get active key command\n"); |
---|
| 1238 | + pr_debug("Couldn't get the table size\n"); |
---|
1136 | 1239 | return err; |
---|
1137 | 1240 | } |
---|
1138 | 1241 | |
---|
1139 | | - return finalize_and_send(dev, get_active_key_cont); |
---|
| 1242 | + len = response_get_u64(&dev->parsed, 4); |
---|
| 1243 | + if (size > len || offset > len - size) { |
---|
| 1244 | + pr_debug("Does not fit in the table (%llu vs. %llu)\n", |
---|
| 1245 | + offset + size, len); |
---|
| 1246 | + return -ENOSPC; |
---|
| 1247 | + } |
---|
| 1248 | + |
---|
| 1249 | + /* do the actual transmission(s) */ |
---|
| 1250 | + while (off < size) { |
---|
| 1251 | + err = cmd_start(dev, uid, opalmethod[OPAL_SET]); |
---|
| 1252 | + add_token_u8(&err, dev, OPAL_STARTNAME); |
---|
| 1253 | + add_token_u8(&err, dev, OPAL_WHERE); |
---|
| 1254 | + add_token_u64(&err, dev, offset + off); |
---|
| 1255 | + add_token_u8(&err, dev, OPAL_ENDNAME); |
---|
| 1256 | + |
---|
| 1257 | + add_token_u8(&err, dev, OPAL_STARTNAME); |
---|
| 1258 | + add_token_u8(&err, dev, OPAL_VALUES); |
---|
| 1259 | + |
---|
| 1260 | + /* |
---|
| 1261 | + * The bytestring header is either 1 or 2 bytes, so assume 2. |
---|
| 1262 | + * There also needs to be enough space to accommodate the |
---|
| 1263 | + * trailing OPAL_ENDNAME (1 byte) and tokens added by |
---|
| 1264 | + * cmd_finalize. |
---|
| 1265 | + */ |
---|
| 1266 | + len = min(remaining_size(dev) - (2+1+CMD_FINALIZE_BYTES_NEEDED), |
---|
| 1267 | + (size_t)(size - off)); |
---|
| 1268 | + pr_debug("Write bytes %zu+%llu/%llu\n", off, len, size); |
---|
| 1269 | + |
---|
| 1270 | + dst = add_bytestring_header(&err, dev, len); |
---|
| 1271 | + if (!dst) |
---|
| 1272 | + break; |
---|
| 1273 | + |
---|
| 1274 | + if (copy_from_user(dst, src + off, len)) { |
---|
| 1275 | + err = -EFAULT; |
---|
| 1276 | + break; |
---|
| 1277 | + } |
---|
| 1278 | + |
---|
| 1279 | + dev->pos += len; |
---|
| 1280 | + |
---|
| 1281 | + add_token_u8(&err, dev, OPAL_ENDNAME); |
---|
| 1282 | + if (err) |
---|
| 1283 | + break; |
---|
| 1284 | + |
---|
| 1285 | + err = finalize_and_send(dev, parse_and_check_status); |
---|
| 1286 | + if (err) |
---|
| 1287 | + break; |
---|
| 1288 | + |
---|
| 1289 | + off += len; |
---|
| 1290 | + } |
---|
| 1291 | + |
---|
| 1292 | + return err; |
---|
1140 | 1293 | } |
---|
1141 | 1294 | |
---|
1142 | 1295 | static int generic_lr_enable_disable(struct opal_dev *dev, |
---|
1143 | 1296 | u8 *uid, bool rle, bool wle, |
---|
1144 | 1297 | bool rl, bool wl) |
---|
1145 | 1298 | { |
---|
1146 | | - int err = 0; |
---|
| 1299 | + int err; |
---|
1147 | 1300 | |
---|
1148 | | - add_token_u8(&err, dev, OPAL_CALL); |
---|
1149 | | - add_token_bytestring(&err, dev, uid, OPAL_UID_LENGTH); |
---|
1150 | | - add_token_bytestring(&err, dev, opalmethod[OPAL_SET], OPAL_UID_LENGTH); |
---|
| 1301 | + err = cmd_start(dev, uid, opalmethod[OPAL_SET]); |
---|
1151 | 1302 | |
---|
1152 | | - add_token_u8(&err, dev, OPAL_STARTLIST); |
---|
1153 | 1303 | add_token_u8(&err, dev, OPAL_STARTNAME); |
---|
1154 | 1304 | add_token_u8(&err, dev, OPAL_VALUES); |
---|
1155 | 1305 | add_token_u8(&err, dev, OPAL_STARTLIST); |
---|
1156 | 1306 | |
---|
1157 | 1307 | add_token_u8(&err, dev, OPAL_STARTNAME); |
---|
1158 | | - add_token_u8(&err, dev, 5); /* ReadLockEnabled */ |
---|
| 1308 | + add_token_u8(&err, dev, OPAL_READLOCKENABLED); |
---|
1159 | 1309 | add_token_u8(&err, dev, rle); |
---|
1160 | 1310 | add_token_u8(&err, dev, OPAL_ENDNAME); |
---|
1161 | 1311 | |
---|
1162 | 1312 | add_token_u8(&err, dev, OPAL_STARTNAME); |
---|
1163 | | - add_token_u8(&err, dev, 6); /* WriteLockEnabled */ |
---|
| 1313 | + add_token_u8(&err, dev, OPAL_WRITELOCKENABLED); |
---|
1164 | 1314 | add_token_u8(&err, dev, wle); |
---|
1165 | 1315 | add_token_u8(&err, dev, OPAL_ENDNAME); |
---|
1166 | 1316 | |
---|
.. | .. |
---|
1176 | 1326 | |
---|
1177 | 1327 | add_token_u8(&err, dev, OPAL_ENDLIST); |
---|
1178 | 1328 | add_token_u8(&err, dev, OPAL_ENDNAME); |
---|
1179 | | - add_token_u8(&err, dev, OPAL_ENDLIST); |
---|
| 1329 | + |
---|
1180 | 1330 | return err; |
---|
1181 | 1331 | } |
---|
1182 | 1332 | |
---|
.. | .. |
---|
1189 | 1339 | 0, 0); |
---|
1190 | 1340 | if (err) |
---|
1191 | 1341 | pr_debug("Failed to create enable global lr command\n"); |
---|
| 1342 | + |
---|
1192 | 1343 | return err; |
---|
1193 | 1344 | } |
---|
1194 | 1345 | |
---|
.. | .. |
---|
1197 | 1348 | u8 uid[OPAL_UID_LENGTH]; |
---|
1198 | 1349 | struct opal_user_lr_setup *setup = data; |
---|
1199 | 1350 | u8 lr; |
---|
1200 | | - int err = 0; |
---|
1201 | | - |
---|
1202 | | - clear_opal_cmd(dev); |
---|
1203 | | - set_comid(dev, dev->comid); |
---|
| 1351 | + int err; |
---|
1204 | 1352 | |
---|
1205 | 1353 | lr = setup->session.opal_key.lr; |
---|
1206 | 1354 | err = build_locking_range(uid, sizeof(uid), lr); |
---|
.. | .. |
---|
1210 | 1358 | if (lr == 0) |
---|
1211 | 1359 | err = enable_global_lr(dev, uid, setup); |
---|
1212 | 1360 | else { |
---|
1213 | | - add_token_u8(&err, dev, OPAL_CALL); |
---|
1214 | | - add_token_bytestring(&err, dev, uid, OPAL_UID_LENGTH); |
---|
1215 | | - add_token_bytestring(&err, dev, opalmethod[OPAL_SET], |
---|
1216 | | - OPAL_UID_LENGTH); |
---|
| 1361 | + err = cmd_start(dev, uid, opalmethod[OPAL_SET]); |
---|
1217 | 1362 | |
---|
1218 | | - add_token_u8(&err, dev, OPAL_STARTLIST); |
---|
1219 | 1363 | add_token_u8(&err, dev, OPAL_STARTNAME); |
---|
1220 | 1364 | add_token_u8(&err, dev, OPAL_VALUES); |
---|
1221 | 1365 | add_token_u8(&err, dev, OPAL_STARTLIST); |
---|
1222 | 1366 | |
---|
1223 | 1367 | add_token_u8(&err, dev, OPAL_STARTNAME); |
---|
1224 | | - add_token_u8(&err, dev, 3); /* Ranges Start */ |
---|
| 1368 | + add_token_u8(&err, dev, OPAL_RANGESTART); |
---|
1225 | 1369 | add_token_u64(&err, dev, setup->range_start); |
---|
1226 | 1370 | add_token_u8(&err, dev, OPAL_ENDNAME); |
---|
1227 | 1371 | |
---|
1228 | 1372 | add_token_u8(&err, dev, OPAL_STARTNAME); |
---|
1229 | | - add_token_u8(&err, dev, 4); /* Ranges length */ |
---|
| 1373 | + add_token_u8(&err, dev, OPAL_RANGELENGTH); |
---|
1230 | 1374 | add_token_u64(&err, dev, setup->range_length); |
---|
1231 | 1375 | add_token_u8(&err, dev, OPAL_ENDNAME); |
---|
1232 | 1376 | |
---|
1233 | 1377 | add_token_u8(&err, dev, OPAL_STARTNAME); |
---|
1234 | | - add_token_u8(&err, dev, 5); /*ReadLockEnabled */ |
---|
| 1378 | + add_token_u8(&err, dev, OPAL_READLOCKENABLED); |
---|
1235 | 1379 | add_token_u64(&err, dev, !!setup->RLE); |
---|
1236 | 1380 | add_token_u8(&err, dev, OPAL_ENDNAME); |
---|
1237 | 1381 | |
---|
1238 | 1382 | add_token_u8(&err, dev, OPAL_STARTNAME); |
---|
1239 | | - add_token_u8(&err, dev, 6); /*WriteLockEnabled*/ |
---|
| 1383 | + add_token_u8(&err, dev, OPAL_WRITELOCKENABLED); |
---|
1240 | 1384 | add_token_u64(&err, dev, !!setup->WLE); |
---|
1241 | 1385 | add_token_u8(&err, dev, OPAL_ENDNAME); |
---|
1242 | 1386 | |
---|
1243 | 1387 | add_token_u8(&err, dev, OPAL_ENDLIST); |
---|
1244 | 1388 | add_token_u8(&err, dev, OPAL_ENDNAME); |
---|
1245 | | - add_token_u8(&err, dev, OPAL_ENDLIST); |
---|
1246 | | - |
---|
1247 | 1389 | } |
---|
1248 | 1390 | if (err) { |
---|
1249 | 1391 | pr_debug("Error building Setup Locking range command.\n"); |
---|
1250 | 1392 | return err; |
---|
1251 | | - |
---|
1252 | 1393 | } |
---|
1253 | 1394 | |
---|
1254 | 1395 | return finalize_and_send(dev, parse_and_check_status); |
---|
.. | .. |
---|
1261 | 1402 | u8 key_len) |
---|
1262 | 1403 | { |
---|
1263 | 1404 | u32 hsn; |
---|
1264 | | - int err = 0; |
---|
| 1405 | + int err; |
---|
1265 | 1406 | |
---|
1266 | 1407 | if (key == NULL && auth != OPAL_ANYBODY_UID) |
---|
1267 | 1408 | return OPAL_INVAL_PARAM; |
---|
1268 | 1409 | |
---|
1269 | | - clear_opal_cmd(dev); |
---|
1270 | | - |
---|
1271 | | - set_comid(dev, dev->comid); |
---|
1272 | 1410 | hsn = GENERIC_HOST_SESSION_NUM; |
---|
| 1411 | + err = cmd_start(dev, opaluid[OPAL_SMUID_UID], |
---|
| 1412 | + opalmethod[OPAL_STARTSESSION]); |
---|
1273 | 1413 | |
---|
1274 | | - add_token_u8(&err, dev, OPAL_CALL); |
---|
1275 | | - add_token_bytestring(&err, dev, opaluid[OPAL_SMUID_UID], |
---|
1276 | | - OPAL_UID_LENGTH); |
---|
1277 | | - add_token_bytestring(&err, dev, opalmethod[OPAL_STARTSESSION], |
---|
1278 | | - OPAL_UID_LENGTH); |
---|
1279 | | - add_token_u8(&err, dev, OPAL_STARTLIST); |
---|
1280 | 1414 | add_token_u64(&err, dev, hsn); |
---|
1281 | 1415 | add_token_bytestring(&err, dev, opaluid[sp_type], OPAL_UID_LENGTH); |
---|
1282 | 1416 | add_token_u8(&err, dev, 1); |
---|
1283 | 1417 | |
---|
1284 | 1418 | switch (auth) { |
---|
1285 | 1419 | case OPAL_ANYBODY_UID: |
---|
1286 | | - add_token_u8(&err, dev, OPAL_ENDLIST); |
---|
1287 | 1420 | break; |
---|
1288 | 1421 | case OPAL_ADMIN1_UID: |
---|
1289 | 1422 | case OPAL_SID_UID: |
---|
| 1423 | + case OPAL_PSID_UID: |
---|
1290 | 1424 | add_token_u8(&err, dev, OPAL_STARTNAME); |
---|
1291 | 1425 | add_token_u8(&err, dev, 0); /* HostChallenge */ |
---|
1292 | 1426 | add_token_bytestring(&err, dev, key, key_len); |
---|
.. | .. |
---|
1296 | 1430 | add_token_bytestring(&err, dev, opaluid[auth], |
---|
1297 | 1431 | OPAL_UID_LENGTH); |
---|
1298 | 1432 | add_token_u8(&err, dev, OPAL_ENDNAME); |
---|
1299 | | - add_token_u8(&err, dev, OPAL_ENDLIST); |
---|
1300 | 1433 | break; |
---|
1301 | 1434 | default: |
---|
1302 | 1435 | pr_debug("Cannot start Admin SP session with auth %d\n", auth); |
---|
.. | .. |
---|
1324 | 1457 | |
---|
1325 | 1458 | if (!key) { |
---|
1326 | 1459 | const struct opal_key *okey = data; |
---|
| 1460 | + |
---|
1327 | 1461 | ret = start_generic_opal_session(dev, OPAL_SID_UID, |
---|
1328 | 1462 | OPAL_ADMINSP_UID, |
---|
1329 | 1463 | okey->key, |
---|
.. | .. |
---|
1335 | 1469 | kfree(key); |
---|
1336 | 1470 | dev->prev_data = NULL; |
---|
1337 | 1471 | } |
---|
| 1472 | + |
---|
1338 | 1473 | return ret; |
---|
1339 | 1474 | } |
---|
1340 | 1475 | |
---|
1341 | 1476 | static int start_admin1LSP_opal_session(struct opal_dev *dev, void *data) |
---|
1342 | 1477 | { |
---|
1343 | 1478 | struct opal_key *key = data; |
---|
| 1479 | + |
---|
1344 | 1480 | return start_generic_opal_session(dev, OPAL_ADMIN1_UID, |
---|
1345 | 1481 | OPAL_LOCKINGSP_UID, |
---|
1346 | 1482 | key->key, key->key_len); |
---|
| 1483 | +} |
---|
| 1484 | + |
---|
| 1485 | +static int start_PSID_opal_session(struct opal_dev *dev, void *data) |
---|
| 1486 | +{ |
---|
| 1487 | + const struct opal_key *okey = data; |
---|
| 1488 | + |
---|
| 1489 | + return start_generic_opal_session(dev, OPAL_PSID_UID, |
---|
| 1490 | + OPAL_ADMINSP_UID, |
---|
| 1491 | + okey->key, |
---|
| 1492 | + okey->key_len); |
---|
1347 | 1493 | } |
---|
1348 | 1494 | |
---|
1349 | 1495 | static int start_auth_opal_session(struct opal_dev *dev, void *data) |
---|
.. | .. |
---|
1356 | 1502 | u8 *key = session->opal_key.key; |
---|
1357 | 1503 | u32 hsn = GENERIC_HOST_SESSION_NUM; |
---|
1358 | 1504 | |
---|
1359 | | - clear_opal_cmd(dev); |
---|
1360 | | - set_comid(dev, dev->comid); |
---|
1361 | | - |
---|
1362 | | - if (session->sum) { |
---|
| 1505 | + if (session->sum) |
---|
1363 | 1506 | err = build_locking_user(lk_ul_user, sizeof(lk_ul_user), |
---|
1364 | 1507 | session->opal_key.lr); |
---|
1365 | | - if (err) |
---|
1366 | | - return err; |
---|
1367 | | - |
---|
1368 | | - } else if (session->who != OPAL_ADMIN1 && !session->sum) { |
---|
| 1508 | + else if (session->who != OPAL_ADMIN1 && !session->sum) |
---|
1369 | 1509 | err = build_locking_user(lk_ul_user, sizeof(lk_ul_user), |
---|
1370 | 1510 | session->who - 1); |
---|
1371 | | - if (err) |
---|
1372 | | - return err; |
---|
1373 | | - } else |
---|
| 1511 | + else |
---|
1374 | 1512 | memcpy(lk_ul_user, opaluid[OPAL_ADMIN1_UID], OPAL_UID_LENGTH); |
---|
1375 | 1513 | |
---|
1376 | | - add_token_u8(&err, dev, OPAL_CALL); |
---|
1377 | | - add_token_bytestring(&err, dev, opaluid[OPAL_SMUID_UID], |
---|
1378 | | - OPAL_UID_LENGTH); |
---|
1379 | | - add_token_bytestring(&err, dev, opalmethod[OPAL_STARTSESSION], |
---|
1380 | | - OPAL_UID_LENGTH); |
---|
| 1514 | + if (err) |
---|
| 1515 | + return err; |
---|
1381 | 1516 | |
---|
1382 | | - add_token_u8(&err, dev, OPAL_STARTLIST); |
---|
| 1517 | + err = cmd_start(dev, opaluid[OPAL_SMUID_UID], |
---|
| 1518 | + opalmethod[OPAL_STARTSESSION]); |
---|
| 1519 | + |
---|
1383 | 1520 | add_token_u64(&err, dev, hsn); |
---|
1384 | 1521 | add_token_bytestring(&err, dev, opaluid[OPAL_LOCKINGSP_UID], |
---|
1385 | 1522 | OPAL_UID_LENGTH); |
---|
.. | .. |
---|
1392 | 1529 | add_token_u8(&err, dev, 3); |
---|
1393 | 1530 | add_token_bytestring(&err, dev, lk_ul_user, OPAL_UID_LENGTH); |
---|
1394 | 1531 | add_token_u8(&err, dev, OPAL_ENDNAME); |
---|
1395 | | - add_token_u8(&err, dev, OPAL_ENDLIST); |
---|
1396 | 1532 | |
---|
1397 | 1533 | if (err) { |
---|
1398 | 1534 | pr_debug("Error building STARTSESSION command.\n"); |
---|
.. | .. |
---|
1404 | 1540 | |
---|
1405 | 1541 | static int revert_tper(struct opal_dev *dev, void *data) |
---|
1406 | 1542 | { |
---|
1407 | | - int err = 0; |
---|
| 1543 | + int err; |
---|
1408 | 1544 | |
---|
1409 | | - clear_opal_cmd(dev); |
---|
1410 | | - set_comid(dev, dev->comid); |
---|
1411 | | - |
---|
1412 | | - add_token_u8(&err, dev, OPAL_CALL); |
---|
1413 | | - add_token_bytestring(&err, dev, opaluid[OPAL_ADMINSP_UID], |
---|
1414 | | - OPAL_UID_LENGTH); |
---|
1415 | | - add_token_bytestring(&err, dev, opalmethod[OPAL_REVERT], |
---|
1416 | | - OPAL_UID_LENGTH); |
---|
1417 | | - add_token_u8(&err, dev, OPAL_STARTLIST); |
---|
1418 | | - add_token_u8(&err, dev, OPAL_ENDLIST); |
---|
| 1545 | + err = cmd_start(dev, opaluid[OPAL_ADMINSP_UID], |
---|
| 1546 | + opalmethod[OPAL_REVERT]); |
---|
1419 | 1547 | if (err) { |
---|
1420 | 1548 | pr_debug("Error building REVERT TPER command.\n"); |
---|
1421 | 1549 | return err; |
---|
.. | .. |
---|
1428 | 1556 | { |
---|
1429 | 1557 | struct opal_session_info *session = data; |
---|
1430 | 1558 | u8 uid[OPAL_UID_LENGTH]; |
---|
1431 | | - int err = 0; |
---|
1432 | | - |
---|
1433 | | - clear_opal_cmd(dev); |
---|
1434 | | - set_comid(dev, dev->comid); |
---|
| 1559 | + int err; |
---|
1435 | 1560 | |
---|
1436 | 1561 | memcpy(uid, opaluid[OPAL_USER1_UID], OPAL_UID_LENGTH); |
---|
1437 | 1562 | uid[7] = session->who; |
---|
1438 | 1563 | |
---|
1439 | | - add_token_u8(&err, dev, OPAL_CALL); |
---|
1440 | | - add_token_bytestring(&err, dev, uid, OPAL_UID_LENGTH); |
---|
1441 | | - add_token_bytestring(&err, dev, opalmethod[OPAL_SET], OPAL_UID_LENGTH); |
---|
1442 | | - add_token_u8(&err, dev, OPAL_STARTLIST); |
---|
| 1564 | + err = cmd_start(dev, uid, opalmethod[OPAL_SET]); |
---|
1443 | 1565 | add_token_u8(&err, dev, OPAL_STARTNAME); |
---|
1444 | 1566 | add_token_u8(&err, dev, OPAL_VALUES); |
---|
1445 | 1567 | add_token_u8(&err, dev, OPAL_STARTLIST); |
---|
.. | .. |
---|
1449 | 1571 | add_token_u8(&err, dev, OPAL_ENDNAME); |
---|
1450 | 1572 | add_token_u8(&err, dev, OPAL_ENDLIST); |
---|
1451 | 1573 | add_token_u8(&err, dev, OPAL_ENDNAME); |
---|
1452 | | - add_token_u8(&err, dev, OPAL_ENDLIST); |
---|
1453 | 1574 | |
---|
1454 | 1575 | if (err) { |
---|
1455 | 1576 | pr_debug("Error building Activate UserN command.\n"); |
---|
.. | .. |
---|
1463 | 1584 | { |
---|
1464 | 1585 | struct opal_session_info *session = data; |
---|
1465 | 1586 | u8 uid[OPAL_UID_LENGTH]; |
---|
1466 | | - int err = 0; |
---|
1467 | | - |
---|
1468 | | - clear_opal_cmd(dev); |
---|
1469 | | - set_comid(dev, dev->comid); |
---|
| 1587 | + int err; |
---|
1470 | 1588 | |
---|
1471 | 1589 | if (build_locking_range(uid, sizeof(uid), session->opal_key.lr) < 0) |
---|
1472 | 1590 | return -ERANGE; |
---|
1473 | 1591 | |
---|
1474 | | - add_token_u8(&err, dev, OPAL_CALL); |
---|
1475 | | - add_token_bytestring(&err, dev, uid, OPAL_UID_LENGTH); |
---|
1476 | | - add_token_bytestring(&err, dev, opalmethod[OPAL_ERASE], |
---|
1477 | | - OPAL_UID_LENGTH); |
---|
1478 | | - add_token_u8(&err, dev, OPAL_STARTLIST); |
---|
1479 | | - add_token_u8(&err, dev, OPAL_ENDLIST); |
---|
| 1592 | + err = cmd_start(dev, uid, opalmethod[OPAL_ERASE]); |
---|
1480 | 1593 | |
---|
1481 | 1594 | if (err) { |
---|
1482 | 1595 | pr_debug("Error building Erase Locking Range Command.\n"); |
---|
1483 | 1596 | return err; |
---|
1484 | 1597 | } |
---|
| 1598 | + |
---|
1485 | 1599 | return finalize_and_send(dev, parse_and_check_status); |
---|
1486 | 1600 | } |
---|
1487 | 1601 | |
---|
1488 | 1602 | static int set_mbr_done(struct opal_dev *dev, void *data) |
---|
1489 | 1603 | { |
---|
1490 | 1604 | u8 *mbr_done_tf = data; |
---|
1491 | | - int err = 0; |
---|
| 1605 | + int err; |
---|
1492 | 1606 | |
---|
1493 | | - clear_opal_cmd(dev); |
---|
1494 | | - set_comid(dev, dev->comid); |
---|
| 1607 | + err = cmd_start(dev, opaluid[OPAL_MBRCONTROL], |
---|
| 1608 | + opalmethod[OPAL_SET]); |
---|
1495 | 1609 | |
---|
1496 | | - add_token_u8(&err, dev, OPAL_CALL); |
---|
1497 | | - add_token_bytestring(&err, dev, opaluid[OPAL_MBRCONTROL], |
---|
1498 | | - OPAL_UID_LENGTH); |
---|
1499 | | - add_token_bytestring(&err, dev, opalmethod[OPAL_SET], OPAL_UID_LENGTH); |
---|
1500 | | - add_token_u8(&err, dev, OPAL_STARTLIST); |
---|
1501 | 1610 | add_token_u8(&err, dev, OPAL_STARTNAME); |
---|
1502 | 1611 | add_token_u8(&err, dev, OPAL_VALUES); |
---|
1503 | 1612 | add_token_u8(&err, dev, OPAL_STARTLIST); |
---|
1504 | 1613 | add_token_u8(&err, dev, OPAL_STARTNAME); |
---|
1505 | | - add_token_u8(&err, dev, 2); /* Done */ |
---|
| 1614 | + add_token_u8(&err, dev, OPAL_MBRDONE); |
---|
1506 | 1615 | add_token_u8(&err, dev, *mbr_done_tf); /* Done T or F */ |
---|
1507 | 1616 | add_token_u8(&err, dev, OPAL_ENDNAME); |
---|
1508 | 1617 | add_token_u8(&err, dev, OPAL_ENDLIST); |
---|
1509 | 1618 | add_token_u8(&err, dev, OPAL_ENDNAME); |
---|
1510 | | - add_token_u8(&err, dev, OPAL_ENDLIST); |
---|
1511 | 1619 | |
---|
1512 | 1620 | if (err) { |
---|
1513 | 1621 | pr_debug("Error Building set MBR Done command\n"); |
---|
.. | .. |
---|
1520 | 1628 | static int set_mbr_enable_disable(struct opal_dev *dev, void *data) |
---|
1521 | 1629 | { |
---|
1522 | 1630 | u8 *mbr_en_dis = data; |
---|
1523 | | - int err = 0; |
---|
| 1631 | + int err; |
---|
1524 | 1632 | |
---|
1525 | | - clear_opal_cmd(dev); |
---|
1526 | | - set_comid(dev, dev->comid); |
---|
| 1633 | + err = cmd_start(dev, opaluid[OPAL_MBRCONTROL], |
---|
| 1634 | + opalmethod[OPAL_SET]); |
---|
1527 | 1635 | |
---|
1528 | | - add_token_u8(&err, dev, OPAL_CALL); |
---|
1529 | | - add_token_bytestring(&err, dev, opaluid[OPAL_MBRCONTROL], |
---|
1530 | | - OPAL_UID_LENGTH); |
---|
1531 | | - add_token_bytestring(&err, dev, opalmethod[OPAL_SET], OPAL_UID_LENGTH); |
---|
1532 | | - add_token_u8(&err, dev, OPAL_STARTLIST); |
---|
1533 | 1636 | add_token_u8(&err, dev, OPAL_STARTNAME); |
---|
1534 | 1637 | add_token_u8(&err, dev, OPAL_VALUES); |
---|
1535 | 1638 | add_token_u8(&err, dev, OPAL_STARTLIST); |
---|
1536 | 1639 | add_token_u8(&err, dev, OPAL_STARTNAME); |
---|
1537 | | - add_token_u8(&err, dev, 1); |
---|
| 1640 | + add_token_u8(&err, dev, OPAL_MBRENABLE); |
---|
1538 | 1641 | add_token_u8(&err, dev, *mbr_en_dis); |
---|
1539 | 1642 | add_token_u8(&err, dev, OPAL_ENDNAME); |
---|
1540 | 1643 | add_token_u8(&err, dev, OPAL_ENDLIST); |
---|
1541 | 1644 | add_token_u8(&err, dev, OPAL_ENDNAME); |
---|
1542 | | - add_token_u8(&err, dev, OPAL_ENDLIST); |
---|
1543 | 1645 | |
---|
1544 | 1646 | if (err) { |
---|
1545 | 1647 | pr_debug("Error Building set MBR done command\n"); |
---|
.. | .. |
---|
1549 | 1651 | return finalize_and_send(dev, parse_and_check_status); |
---|
1550 | 1652 | } |
---|
1551 | 1653 | |
---|
| 1654 | +static int write_shadow_mbr(struct opal_dev *dev, void *data) |
---|
| 1655 | +{ |
---|
| 1656 | + struct opal_shadow_mbr *shadow = data; |
---|
| 1657 | + |
---|
| 1658 | + return generic_table_write_data(dev, shadow->data, shadow->offset, |
---|
| 1659 | + shadow->size, opaluid[OPAL_MBR]); |
---|
| 1660 | +} |
---|
| 1661 | + |
---|
1552 | 1662 | static int generic_pw_cmd(u8 *key, size_t key_len, u8 *cpin_uid, |
---|
1553 | 1663 | struct opal_dev *dev) |
---|
1554 | 1664 | { |
---|
1555 | | - int err = 0; |
---|
| 1665 | + int err; |
---|
1556 | 1666 | |
---|
1557 | | - clear_opal_cmd(dev); |
---|
1558 | | - set_comid(dev, dev->comid); |
---|
| 1667 | + err = cmd_start(dev, cpin_uid, opalmethod[OPAL_SET]); |
---|
1559 | 1668 | |
---|
1560 | | - add_token_u8(&err, dev, OPAL_CALL); |
---|
1561 | | - add_token_bytestring(&err, dev, cpin_uid, OPAL_UID_LENGTH); |
---|
1562 | | - add_token_bytestring(&err, dev, opalmethod[OPAL_SET], |
---|
1563 | | - OPAL_UID_LENGTH); |
---|
1564 | | - add_token_u8(&err, dev, OPAL_STARTLIST); |
---|
1565 | 1669 | add_token_u8(&err, dev, OPAL_STARTNAME); |
---|
1566 | 1670 | add_token_u8(&err, dev, OPAL_VALUES); |
---|
1567 | 1671 | add_token_u8(&err, dev, OPAL_STARTLIST); |
---|
1568 | 1672 | add_token_u8(&err, dev, OPAL_STARTNAME); |
---|
1569 | | - add_token_u8(&err, dev, 3); /* PIN */ |
---|
| 1673 | + add_token_u8(&err, dev, OPAL_PIN); |
---|
1570 | 1674 | add_token_bytestring(&err, dev, key, key_len); |
---|
1571 | 1675 | add_token_u8(&err, dev, OPAL_ENDNAME); |
---|
1572 | 1676 | add_token_u8(&err, dev, OPAL_ENDLIST); |
---|
1573 | 1677 | add_token_u8(&err, dev, OPAL_ENDNAME); |
---|
1574 | | - add_token_u8(&err, dev, OPAL_ENDLIST); |
---|
1575 | 1678 | |
---|
1576 | 1679 | return err; |
---|
1577 | 1680 | } |
---|
.. | .. |
---|
1619 | 1722 | u8 lr_buffer[OPAL_UID_LENGTH]; |
---|
1620 | 1723 | u8 user_uid[OPAL_UID_LENGTH]; |
---|
1621 | 1724 | struct opal_lock_unlock *lkul = data; |
---|
1622 | | - int err = 0; |
---|
1623 | | - |
---|
1624 | | - clear_opal_cmd(dev); |
---|
1625 | | - set_comid(dev, dev->comid); |
---|
| 1725 | + int err; |
---|
1626 | 1726 | |
---|
1627 | 1727 | memcpy(lr_buffer, opaluid[OPAL_LOCKINGRANGE_ACE_RDLOCKED], |
---|
1628 | 1728 | OPAL_UID_LENGTH); |
---|
.. | .. |
---|
1637 | 1737 | |
---|
1638 | 1738 | user_uid[7] = lkul->session.who; |
---|
1639 | 1739 | |
---|
1640 | | - add_token_u8(&err, dev, OPAL_CALL); |
---|
1641 | | - add_token_bytestring(&err, dev, lr_buffer, OPAL_UID_LENGTH); |
---|
1642 | | - add_token_bytestring(&err, dev, opalmethod[OPAL_SET], |
---|
1643 | | - OPAL_UID_LENGTH); |
---|
| 1740 | + err = cmd_start(dev, lr_buffer, opalmethod[OPAL_SET]); |
---|
1644 | 1741 | |
---|
1645 | | - add_token_u8(&err, dev, OPAL_STARTLIST); |
---|
1646 | 1742 | add_token_u8(&err, dev, OPAL_STARTNAME); |
---|
1647 | 1743 | add_token_u8(&err, dev, OPAL_VALUES); |
---|
1648 | 1744 | |
---|
.. | .. |
---|
1680 | 1776 | add_token_u8(&err, dev, OPAL_ENDNAME); |
---|
1681 | 1777 | add_token_u8(&err, dev, OPAL_ENDLIST); |
---|
1682 | 1778 | add_token_u8(&err, dev, OPAL_ENDNAME); |
---|
1683 | | - add_token_u8(&err, dev, OPAL_ENDLIST); |
---|
1684 | 1779 | |
---|
1685 | 1780 | if (err) { |
---|
1686 | 1781 | pr_debug("Error building add user to locking range command.\n"); |
---|
.. | .. |
---|
1697 | 1792 | u8 read_locked = 1, write_locked = 1; |
---|
1698 | 1793 | int err = 0; |
---|
1699 | 1794 | |
---|
1700 | | - clear_opal_cmd(dev); |
---|
1701 | | - set_comid(dev, dev->comid); |
---|
1702 | | - |
---|
1703 | 1795 | if (build_locking_range(lr_buffer, sizeof(lr_buffer), |
---|
1704 | 1796 | lkul->session.opal_key.lr) < 0) |
---|
1705 | 1797 | return -ERANGE; |
---|
.. | .. |
---|
1714 | 1806 | write_locked = 0; |
---|
1715 | 1807 | break; |
---|
1716 | 1808 | case OPAL_LK: |
---|
1717 | | - /* vars are initalized to locked */ |
---|
| 1809 | + /* vars are initialized to locked */ |
---|
1718 | 1810 | break; |
---|
1719 | 1811 | default: |
---|
1720 | 1812 | pr_debug("Tried to set an invalid locking state... returning to uland\n"); |
---|
1721 | 1813 | return OPAL_INVAL_PARAM; |
---|
1722 | 1814 | } |
---|
1723 | 1815 | |
---|
1724 | | - add_token_u8(&err, dev, OPAL_CALL); |
---|
1725 | | - add_token_bytestring(&err, dev, lr_buffer, OPAL_UID_LENGTH); |
---|
1726 | | - add_token_bytestring(&err, dev, opalmethod[OPAL_SET], OPAL_UID_LENGTH); |
---|
1727 | | - add_token_u8(&err, dev, OPAL_STARTLIST); |
---|
| 1816 | + err = cmd_start(dev, lr_buffer, opalmethod[OPAL_SET]); |
---|
| 1817 | + |
---|
1728 | 1818 | add_token_u8(&err, dev, OPAL_STARTNAME); |
---|
1729 | 1819 | add_token_u8(&err, dev, OPAL_VALUES); |
---|
1730 | 1820 | add_token_u8(&err, dev, OPAL_STARTLIST); |
---|
.. | .. |
---|
1741 | 1831 | |
---|
1742 | 1832 | add_token_u8(&err, dev, OPAL_ENDLIST); |
---|
1743 | 1833 | add_token_u8(&err, dev, OPAL_ENDNAME); |
---|
1744 | | - add_token_u8(&err, dev, OPAL_ENDLIST); |
---|
1745 | 1834 | |
---|
1746 | 1835 | if (err) { |
---|
1747 | 1836 | pr_debug("Error building SET command.\n"); |
---|
1748 | 1837 | return err; |
---|
1749 | 1838 | } |
---|
| 1839 | + |
---|
1750 | 1840 | return finalize_and_send(dev, parse_and_check_status); |
---|
1751 | 1841 | } |
---|
1752 | 1842 | |
---|
.. | .. |
---|
1775 | 1865 | write_locked = 0; |
---|
1776 | 1866 | break; |
---|
1777 | 1867 | case OPAL_LK: |
---|
1778 | | - /* vars are initalized to locked */ |
---|
| 1868 | + /* vars are initialized to locked */ |
---|
1779 | 1869 | break; |
---|
1780 | 1870 | default: |
---|
1781 | 1871 | pr_debug("Tried to set an invalid locking state.\n"); |
---|
.. | .. |
---|
1788 | 1878 | pr_debug("Error building SET command.\n"); |
---|
1789 | 1879 | return ret; |
---|
1790 | 1880 | } |
---|
| 1881 | + |
---|
1791 | 1882 | return finalize_and_send(dev, parse_and_check_status); |
---|
1792 | 1883 | } |
---|
1793 | 1884 | |
---|
.. | .. |
---|
1795 | 1886 | { |
---|
1796 | 1887 | struct opal_lr_act *opal_act = data; |
---|
1797 | 1888 | u8 user_lr[OPAL_UID_LENGTH]; |
---|
1798 | | - u8 uint_3 = 0x83; |
---|
1799 | | - int err = 0, i; |
---|
| 1889 | + int err, i; |
---|
1800 | 1890 | |
---|
1801 | | - clear_opal_cmd(dev); |
---|
1802 | | - set_comid(dev, dev->comid); |
---|
1803 | | - |
---|
1804 | | - add_token_u8(&err, dev, OPAL_CALL); |
---|
1805 | | - add_token_bytestring(&err, dev, opaluid[OPAL_LOCKINGSP_UID], |
---|
1806 | | - OPAL_UID_LENGTH); |
---|
1807 | | - add_token_bytestring(&err, dev, opalmethod[OPAL_ACTIVATE], |
---|
1808 | | - OPAL_UID_LENGTH); |
---|
1809 | | - |
---|
| 1891 | + err = cmd_start(dev, opaluid[OPAL_LOCKINGSP_UID], |
---|
| 1892 | + opalmethod[OPAL_ACTIVATE]); |
---|
1810 | 1893 | |
---|
1811 | 1894 | if (opal_act->sum) { |
---|
1812 | 1895 | err = build_locking_range(user_lr, sizeof(user_lr), |
---|
.. | .. |
---|
1814 | 1897 | if (err) |
---|
1815 | 1898 | return err; |
---|
1816 | 1899 | |
---|
1817 | | - add_token_u8(&err, dev, OPAL_STARTLIST); |
---|
1818 | 1900 | add_token_u8(&err, dev, OPAL_STARTNAME); |
---|
1819 | | - add_token_u8(&err, dev, uint_3); |
---|
1820 | | - add_token_u8(&err, dev, 6); |
---|
1821 | | - add_token_u8(&err, dev, 0); |
---|
1822 | | - add_token_u8(&err, dev, 0); |
---|
| 1901 | + add_token_u64(&err, dev, OPAL_SUM_SET_LIST); |
---|
1823 | 1902 | |
---|
1824 | 1903 | add_token_u8(&err, dev, OPAL_STARTLIST); |
---|
1825 | 1904 | add_token_bytestring(&err, dev, user_lr, OPAL_UID_LENGTH); |
---|
.. | .. |
---|
1829 | 1908 | } |
---|
1830 | 1909 | add_token_u8(&err, dev, OPAL_ENDLIST); |
---|
1831 | 1910 | add_token_u8(&err, dev, OPAL_ENDNAME); |
---|
1832 | | - add_token_u8(&err, dev, OPAL_ENDLIST); |
---|
1833 | | - |
---|
1834 | | - } else { |
---|
1835 | | - add_token_u8(&err, dev, OPAL_STARTLIST); |
---|
1836 | | - add_token_u8(&err, dev, OPAL_ENDLIST); |
---|
1837 | 1911 | } |
---|
1838 | 1912 | |
---|
1839 | 1913 | if (err) { |
---|
.. | .. |
---|
1844 | 1918 | return finalize_and_send(dev, parse_and_check_status); |
---|
1845 | 1919 | } |
---|
1846 | 1920 | |
---|
1847 | | -static int get_lsp_lifecycle_cont(struct opal_dev *dev) |
---|
| 1921 | +/* Determine if we're in the Manufactured Inactive or Active state */ |
---|
| 1922 | +static int get_lsp_lifecycle(struct opal_dev *dev, void *data) |
---|
1848 | 1923 | { |
---|
1849 | 1924 | u8 lc_status; |
---|
1850 | | - int error = 0; |
---|
| 1925 | + int err; |
---|
1851 | 1926 | |
---|
1852 | | - error = parse_and_check_status(dev); |
---|
1853 | | - if (error) |
---|
1854 | | - return error; |
---|
| 1927 | + err = generic_get_column(dev, opaluid[OPAL_LOCKINGSP_UID], |
---|
| 1928 | + OPAL_LIFECYCLE); |
---|
| 1929 | + if (err) |
---|
| 1930 | + return err; |
---|
1855 | 1931 | |
---|
1856 | 1932 | lc_status = response_get_u64(&dev->parsed, 4); |
---|
1857 | | - /* 0x08 is Manufacured Inactive */ |
---|
| 1933 | + /* 0x08 is Manufactured Inactive */ |
---|
1858 | 1934 | /* 0x09 is Manufactured */ |
---|
1859 | 1935 | if (lc_status != OPAL_MANUFACTURED_INACTIVE) { |
---|
1860 | 1936 | pr_debug("Couldn't determine the status of the Lifecycle state\n"); |
---|
.. | .. |
---|
1864 | 1940 | return 0; |
---|
1865 | 1941 | } |
---|
1866 | 1942 | |
---|
1867 | | -/* Determine if we're in the Manufactured Inactive or Active state */ |
---|
1868 | | -static int get_lsp_lifecycle(struct opal_dev *dev, void *data) |
---|
1869 | | -{ |
---|
1870 | | - int err = 0; |
---|
1871 | | - |
---|
1872 | | - clear_opal_cmd(dev); |
---|
1873 | | - set_comid(dev, dev->comid); |
---|
1874 | | - |
---|
1875 | | - add_token_u8(&err, dev, OPAL_CALL); |
---|
1876 | | - add_token_bytestring(&err, dev, opaluid[OPAL_LOCKINGSP_UID], |
---|
1877 | | - OPAL_UID_LENGTH); |
---|
1878 | | - add_token_bytestring(&err, dev, opalmethod[OPAL_GET], OPAL_UID_LENGTH); |
---|
1879 | | - |
---|
1880 | | - add_token_u8(&err, dev, OPAL_STARTLIST); |
---|
1881 | | - add_token_u8(&err, dev, OPAL_STARTLIST); |
---|
1882 | | - |
---|
1883 | | - add_token_u8(&err, dev, OPAL_STARTNAME); |
---|
1884 | | - add_token_u8(&err, dev, 3); /* Start Column */ |
---|
1885 | | - add_token_u8(&err, dev, 6); /* Lifecycle Column */ |
---|
1886 | | - add_token_u8(&err, dev, OPAL_ENDNAME); |
---|
1887 | | - |
---|
1888 | | - add_token_u8(&err, dev, OPAL_STARTNAME); |
---|
1889 | | - add_token_u8(&err, dev, 4); /* End Column */ |
---|
1890 | | - add_token_u8(&err, dev, 6); /* Lifecycle Column */ |
---|
1891 | | - add_token_u8(&err, dev, OPAL_ENDNAME); |
---|
1892 | | - |
---|
1893 | | - add_token_u8(&err, dev, OPAL_ENDLIST); |
---|
1894 | | - add_token_u8(&err, dev, OPAL_ENDLIST); |
---|
1895 | | - |
---|
1896 | | - if (err) { |
---|
1897 | | - pr_debug("Error Building GET Lifecycle Status command\n"); |
---|
1898 | | - return err; |
---|
1899 | | - } |
---|
1900 | | - |
---|
1901 | | - return finalize_and_send(dev, get_lsp_lifecycle_cont); |
---|
1902 | | -} |
---|
1903 | | - |
---|
1904 | | -static int get_msid_cpin_pin_cont(struct opal_dev *dev) |
---|
| 1943 | +static int get_msid_cpin_pin(struct opal_dev *dev, void *data) |
---|
1905 | 1944 | { |
---|
1906 | 1945 | const char *msid_pin; |
---|
1907 | 1946 | size_t strlen; |
---|
1908 | | - int error = 0; |
---|
| 1947 | + int err; |
---|
1909 | 1948 | |
---|
1910 | | - error = parse_and_check_status(dev); |
---|
1911 | | - if (error) |
---|
1912 | | - return error; |
---|
| 1949 | + err = generic_get_column(dev, opaluid[OPAL_C_PIN_MSID], OPAL_PIN); |
---|
| 1950 | + if (err) |
---|
| 1951 | + return err; |
---|
1913 | 1952 | |
---|
1914 | 1953 | strlen = response_get_string(&dev->parsed, 4, &msid_pin); |
---|
1915 | 1954 | if (!msid_pin) { |
---|
1916 | | - pr_debug("%s: Couldn't extract PIN from response\n", __func__); |
---|
| 1955 | + pr_debug("Couldn't extract MSID_CPIN from response\n"); |
---|
1917 | 1956 | return OPAL_INVAL_PARAM; |
---|
1918 | 1957 | } |
---|
1919 | 1958 | |
---|
.. | .. |
---|
1926 | 1965 | return 0; |
---|
1927 | 1966 | } |
---|
1928 | 1967 | |
---|
1929 | | -static int get_msid_cpin_pin(struct opal_dev *dev, void *data) |
---|
| 1968 | +static int write_table_data(struct opal_dev *dev, void *data) |
---|
1930 | 1969 | { |
---|
1931 | | - int err = 0; |
---|
| 1970 | + struct opal_read_write_table *write_tbl = data; |
---|
1932 | 1971 | |
---|
1933 | | - clear_opal_cmd(dev); |
---|
1934 | | - set_comid(dev, dev->comid); |
---|
| 1972 | + return generic_table_write_data(dev, write_tbl->data, write_tbl->offset, |
---|
| 1973 | + write_tbl->size, write_tbl->table_uid); |
---|
| 1974 | +} |
---|
1935 | 1975 | |
---|
1936 | | - add_token_u8(&err, dev, OPAL_CALL); |
---|
1937 | | - add_token_bytestring(&err, dev, opaluid[OPAL_C_PIN_MSID], |
---|
1938 | | - OPAL_UID_LENGTH); |
---|
1939 | | - add_token_bytestring(&err, dev, opalmethod[OPAL_GET], OPAL_UID_LENGTH); |
---|
| 1976 | +static int read_table_data_cont(struct opal_dev *dev) |
---|
| 1977 | +{ |
---|
| 1978 | + int err; |
---|
| 1979 | + const char *data_read; |
---|
1940 | 1980 | |
---|
1941 | | - add_token_u8(&err, dev, OPAL_STARTLIST); |
---|
1942 | | - add_token_u8(&err, dev, OPAL_STARTLIST); |
---|
| 1981 | + err = parse_and_check_status(dev); |
---|
| 1982 | + if (err) |
---|
| 1983 | + return err; |
---|
1943 | 1984 | |
---|
1944 | | - add_token_u8(&err, dev, OPAL_STARTNAME); |
---|
1945 | | - add_token_u8(&err, dev, 3); /* Start Column */ |
---|
1946 | | - add_token_u8(&err, dev, 3); /* PIN */ |
---|
1947 | | - add_token_u8(&err, dev, OPAL_ENDNAME); |
---|
| 1985 | + dev->prev_d_len = response_get_string(&dev->parsed, 1, &data_read); |
---|
| 1986 | + dev->prev_data = (void *)data_read; |
---|
| 1987 | + if (!dev->prev_data) { |
---|
| 1988 | + pr_debug("%s: Couldn't read data from the table.\n", __func__); |
---|
| 1989 | + return OPAL_INVAL_PARAM; |
---|
| 1990 | + } |
---|
1948 | 1991 | |
---|
1949 | | - add_token_u8(&err, dev, OPAL_STARTNAME); |
---|
1950 | | - add_token_u8(&err, dev, 4); /* End Column */ |
---|
1951 | | - add_token_u8(&err, dev, 3); /* Lifecycle Column */ |
---|
1952 | | - add_token_u8(&err, dev, OPAL_ENDNAME); |
---|
| 1992 | + return 0; |
---|
| 1993 | +} |
---|
1953 | 1994 | |
---|
1954 | | - add_token_u8(&err, dev, OPAL_ENDLIST); |
---|
1955 | | - add_token_u8(&err, dev, OPAL_ENDLIST); |
---|
| 1995 | +/* |
---|
| 1996 | + * IO_BUFFER_LENGTH = 2048 |
---|
| 1997 | + * sizeof(header) = 56 |
---|
| 1998 | + * No. of Token Bytes in the Response = 11 |
---|
| 1999 | + * MAX size of data that can be carried in response buffer |
---|
| 2000 | + * at a time is : 2048 - (56 + 11) = 1981 = 0x7BD. |
---|
| 2001 | + */ |
---|
| 2002 | +#define OPAL_MAX_READ_TABLE (0x7BD) |
---|
1956 | 2003 | |
---|
| 2004 | +static int read_table_data(struct opal_dev *dev, void *data) |
---|
| 2005 | +{ |
---|
| 2006 | + struct opal_read_write_table *read_tbl = data; |
---|
| 2007 | + int err; |
---|
| 2008 | + size_t off = 0, max_read_size = OPAL_MAX_READ_TABLE; |
---|
| 2009 | + u64 table_len, len; |
---|
| 2010 | + u64 offset = read_tbl->offset, read_size = read_tbl->size - 1; |
---|
| 2011 | + u8 __user *dst; |
---|
| 2012 | + |
---|
| 2013 | + err = generic_get_table_info(dev, read_tbl->table_uid, OPAL_TABLE_ROWS); |
---|
1957 | 2014 | if (err) { |
---|
1958 | | - pr_debug("Error building Get MSID CPIN PIN command.\n"); |
---|
| 2015 | + pr_debug("Couldn't get the table size\n"); |
---|
1959 | 2016 | return err; |
---|
1960 | 2017 | } |
---|
1961 | 2018 | |
---|
1962 | | - return finalize_and_send(dev, get_msid_cpin_pin_cont); |
---|
| 2019 | + table_len = response_get_u64(&dev->parsed, 4); |
---|
| 2020 | + |
---|
| 2021 | + /* Check if the user is trying to read from the table limits */ |
---|
| 2022 | + if (read_size > table_len || offset > table_len - read_size) { |
---|
| 2023 | + pr_debug("Read size exceeds the Table size limits (%llu vs. %llu)\n", |
---|
| 2024 | + offset + read_size, table_len); |
---|
| 2025 | + return -EINVAL; |
---|
| 2026 | + } |
---|
| 2027 | + |
---|
| 2028 | + while (off < read_size) { |
---|
| 2029 | + err = cmd_start(dev, read_tbl->table_uid, opalmethod[OPAL_GET]); |
---|
| 2030 | + |
---|
| 2031 | + add_token_u8(&err, dev, OPAL_STARTLIST); |
---|
| 2032 | + add_token_u8(&err, dev, OPAL_STARTNAME); |
---|
| 2033 | + add_token_u8(&err, dev, OPAL_STARTROW); |
---|
| 2034 | + add_token_u64(&err, dev, offset + off); /* start row value */ |
---|
| 2035 | + add_token_u8(&err, dev, OPAL_ENDNAME); |
---|
| 2036 | + |
---|
| 2037 | + add_token_u8(&err, dev, OPAL_STARTNAME); |
---|
| 2038 | + add_token_u8(&err, dev, OPAL_ENDROW); |
---|
| 2039 | + |
---|
| 2040 | + len = min(max_read_size, (size_t)(read_size - off)); |
---|
| 2041 | + add_token_u64(&err, dev, offset + off + len); /* end row value |
---|
| 2042 | + */ |
---|
| 2043 | + add_token_u8(&err, dev, OPAL_ENDNAME); |
---|
| 2044 | + add_token_u8(&err, dev, OPAL_ENDLIST); |
---|
| 2045 | + |
---|
| 2046 | + if (err) { |
---|
| 2047 | + pr_debug("Error building read table data command.\n"); |
---|
| 2048 | + break; |
---|
| 2049 | + } |
---|
| 2050 | + |
---|
| 2051 | + err = finalize_and_send(dev, read_table_data_cont); |
---|
| 2052 | + if (err) |
---|
| 2053 | + break; |
---|
| 2054 | + |
---|
| 2055 | + /* len+1: This includes the NULL terminator at the end*/ |
---|
| 2056 | + if (dev->prev_d_len > len + 1) { |
---|
| 2057 | + err = -EOVERFLOW; |
---|
| 2058 | + break; |
---|
| 2059 | + } |
---|
| 2060 | + |
---|
| 2061 | + dst = (u8 __user *)(uintptr_t)read_tbl->data; |
---|
| 2062 | + if (copy_to_user(dst + off, dev->prev_data, dev->prev_d_len)) { |
---|
| 2063 | + pr_debug("Error copying data to userspace\n"); |
---|
| 2064 | + err = -EFAULT; |
---|
| 2065 | + break; |
---|
| 2066 | + } |
---|
| 2067 | + dev->prev_data = NULL; |
---|
| 2068 | + |
---|
| 2069 | + off += len; |
---|
| 2070 | + } |
---|
| 2071 | + |
---|
| 2072 | + return err; |
---|
1963 | 2073 | } |
---|
1964 | 2074 | |
---|
1965 | 2075 | static int end_opal_session(struct opal_dev *dev, void *data) |
---|
.. | .. |
---|
1972 | 2082 | |
---|
1973 | 2083 | if (err < 0) |
---|
1974 | 2084 | return err; |
---|
| 2085 | + |
---|
1975 | 2086 | return finalize_and_send(dev, end_session_cont); |
---|
1976 | 2087 | } |
---|
1977 | 2088 | |
---|
1978 | 2089 | static int end_opal_session_error(struct opal_dev *dev) |
---|
1979 | 2090 | { |
---|
1980 | | - const struct opal_step error_end_session[] = { |
---|
1981 | | - { end_opal_session, }, |
---|
1982 | | - { NULL, } |
---|
| 2091 | + const struct opal_step error_end_session = { |
---|
| 2092 | + end_opal_session, |
---|
1983 | 2093 | }; |
---|
1984 | | - dev->steps = error_end_session; |
---|
1985 | | - return next(dev); |
---|
| 2094 | + |
---|
| 2095 | + return execute_step(dev, &error_end_session, 0); |
---|
1986 | 2096 | } |
---|
1987 | 2097 | |
---|
1988 | | -static inline void setup_opal_dev(struct opal_dev *dev, |
---|
1989 | | - const struct opal_step *steps) |
---|
| 2098 | +static inline void setup_opal_dev(struct opal_dev *dev) |
---|
1990 | 2099 | { |
---|
1991 | | - dev->steps = steps; |
---|
1992 | 2100 | dev->tsn = 0; |
---|
1993 | 2101 | dev->hsn = 0; |
---|
1994 | 2102 | dev->prev_data = NULL; |
---|
.. | .. |
---|
1996 | 2104 | |
---|
1997 | 2105 | static int check_opal_support(struct opal_dev *dev) |
---|
1998 | 2106 | { |
---|
1999 | | - const struct opal_step steps[] = { |
---|
2000 | | - { opal_discovery0, }, |
---|
2001 | | - { NULL, } |
---|
2002 | | - }; |
---|
2003 | 2107 | int ret; |
---|
2004 | 2108 | |
---|
2005 | 2109 | mutex_lock(&dev->dev_lock); |
---|
2006 | | - setup_opal_dev(dev, steps); |
---|
2007 | | - ret = next(dev); |
---|
| 2110 | + setup_opal_dev(dev); |
---|
| 2111 | + ret = opal_discovery0_step(dev); |
---|
2008 | 2112 | dev->supported = !ret; |
---|
2009 | 2113 | mutex_unlock(&dev->dev_lock); |
---|
| 2114 | + |
---|
2010 | 2115 | return ret; |
---|
2011 | 2116 | } |
---|
2012 | 2117 | |
---|
.. | .. |
---|
2027 | 2132 | { |
---|
2028 | 2133 | if (!dev) |
---|
2029 | 2134 | return; |
---|
| 2135 | + |
---|
2030 | 2136 | clean_opal_dev(dev); |
---|
| 2137 | + kfree(dev->resp); |
---|
| 2138 | + kfree(dev->cmd); |
---|
2031 | 2139 | kfree(dev); |
---|
2032 | 2140 | } |
---|
2033 | 2141 | EXPORT_SYMBOL(free_opal_dev); |
---|
.. | .. |
---|
2040 | 2148 | if (!dev) |
---|
2041 | 2149 | return NULL; |
---|
2042 | 2150 | |
---|
| 2151 | + /* |
---|
| 2152 | + * Presumably DMA-able buffers must be cache-aligned. Kmalloc makes |
---|
| 2153 | + * sure the allocated buffer is DMA-safe in that regard. |
---|
| 2154 | + */ |
---|
| 2155 | + dev->cmd = kmalloc(IO_BUFFER_LENGTH, GFP_KERNEL); |
---|
| 2156 | + if (!dev->cmd) |
---|
| 2157 | + goto err_free_dev; |
---|
| 2158 | + |
---|
| 2159 | + dev->resp = kmalloc(IO_BUFFER_LENGTH, GFP_KERNEL); |
---|
| 2160 | + if (!dev->resp) |
---|
| 2161 | + goto err_free_cmd; |
---|
| 2162 | + |
---|
2043 | 2163 | INIT_LIST_HEAD(&dev->unlk_lst); |
---|
2044 | 2164 | mutex_init(&dev->dev_lock); |
---|
2045 | 2165 | dev->data = data; |
---|
2046 | 2166 | dev->send_recv = send_recv; |
---|
2047 | 2167 | if (check_opal_support(dev) != 0) { |
---|
2048 | 2168 | pr_debug("Opal is not supported on this device\n"); |
---|
2049 | | - kfree(dev); |
---|
2050 | | - return NULL; |
---|
| 2169 | + goto err_free_resp; |
---|
2051 | 2170 | } |
---|
| 2171 | + |
---|
2052 | 2172 | return dev; |
---|
| 2173 | + |
---|
| 2174 | +err_free_resp: |
---|
| 2175 | + kfree(dev->resp); |
---|
| 2176 | + |
---|
| 2177 | +err_free_cmd: |
---|
| 2178 | + kfree(dev->cmd); |
---|
| 2179 | + |
---|
| 2180 | +err_free_dev: |
---|
| 2181 | + kfree(dev); |
---|
| 2182 | + |
---|
| 2183 | + return NULL; |
---|
2053 | 2184 | } |
---|
2054 | 2185 | EXPORT_SYMBOL(init_opal_dev); |
---|
2055 | 2186 | |
---|
.. | .. |
---|
2057 | 2188 | struct opal_session_info *opal_session) |
---|
2058 | 2189 | { |
---|
2059 | 2190 | const struct opal_step erase_steps[] = { |
---|
2060 | | - { opal_discovery0, }, |
---|
2061 | 2191 | { start_auth_opal_session, opal_session }, |
---|
2062 | 2192 | { get_active_key, &opal_session->opal_key.lr }, |
---|
2063 | 2193 | { gen_key, }, |
---|
2064 | | - { end_opal_session, }, |
---|
2065 | | - { NULL, } |
---|
| 2194 | + { end_opal_session, } |
---|
2066 | 2195 | }; |
---|
2067 | 2196 | int ret; |
---|
2068 | 2197 | |
---|
2069 | 2198 | mutex_lock(&dev->dev_lock); |
---|
2070 | | - setup_opal_dev(dev, erase_steps); |
---|
2071 | | - ret = next(dev); |
---|
| 2199 | + setup_opal_dev(dev); |
---|
| 2200 | + ret = execute_steps(dev, erase_steps, ARRAY_SIZE(erase_steps)); |
---|
2072 | 2201 | mutex_unlock(&dev->dev_lock); |
---|
| 2202 | + |
---|
2073 | 2203 | return ret; |
---|
2074 | 2204 | } |
---|
2075 | 2205 | |
---|
.. | .. |
---|
2077 | 2207 | struct opal_session_info *opal_session) |
---|
2078 | 2208 | { |
---|
2079 | 2209 | const struct opal_step erase_steps[] = { |
---|
2080 | | - { opal_discovery0, }, |
---|
2081 | 2210 | { start_auth_opal_session, opal_session }, |
---|
2082 | 2211 | { erase_locking_range, opal_session }, |
---|
2083 | | - { end_opal_session, }, |
---|
2084 | | - { NULL, } |
---|
| 2212 | + { end_opal_session, } |
---|
2085 | 2213 | }; |
---|
2086 | 2214 | int ret; |
---|
2087 | 2215 | |
---|
2088 | 2216 | mutex_lock(&dev->dev_lock); |
---|
2089 | | - setup_opal_dev(dev, erase_steps); |
---|
2090 | | - ret = next(dev); |
---|
| 2217 | + setup_opal_dev(dev); |
---|
| 2218 | + ret = execute_steps(dev, erase_steps, ARRAY_SIZE(erase_steps)); |
---|
2091 | 2219 | mutex_unlock(&dev->dev_lock); |
---|
| 2220 | + |
---|
2092 | 2221 | return ret; |
---|
2093 | 2222 | } |
---|
2094 | 2223 | |
---|
.. | .. |
---|
2099 | 2228 | OPAL_TRUE : OPAL_FALSE; |
---|
2100 | 2229 | |
---|
2101 | 2230 | const struct opal_step mbr_steps[] = { |
---|
2102 | | - { opal_discovery0, }, |
---|
2103 | 2231 | { start_admin1LSP_opal_session, &opal_mbr->key }, |
---|
2104 | 2232 | { set_mbr_done, &enable_disable }, |
---|
2105 | 2233 | { end_opal_session, }, |
---|
2106 | 2234 | { start_admin1LSP_opal_session, &opal_mbr->key }, |
---|
2107 | 2235 | { set_mbr_enable_disable, &enable_disable }, |
---|
2108 | | - { end_opal_session, }, |
---|
2109 | | - { NULL, } |
---|
| 2236 | + { end_opal_session, } |
---|
2110 | 2237 | }; |
---|
2111 | 2238 | int ret; |
---|
2112 | 2239 | |
---|
.. | .. |
---|
2115 | 2242 | return -EINVAL; |
---|
2116 | 2243 | |
---|
2117 | 2244 | mutex_lock(&dev->dev_lock); |
---|
2118 | | - setup_opal_dev(dev, mbr_steps); |
---|
2119 | | - ret = next(dev); |
---|
| 2245 | + setup_opal_dev(dev); |
---|
| 2246 | + ret = execute_steps(dev, mbr_steps, ARRAY_SIZE(mbr_steps)); |
---|
2120 | 2247 | mutex_unlock(&dev->dev_lock); |
---|
| 2248 | + |
---|
| 2249 | + return ret; |
---|
| 2250 | +} |
---|
| 2251 | + |
---|
| 2252 | +static int opal_set_mbr_done(struct opal_dev *dev, |
---|
| 2253 | + struct opal_mbr_done *mbr_done) |
---|
| 2254 | +{ |
---|
| 2255 | + u8 mbr_done_tf = mbr_done->done_flag == OPAL_MBR_DONE ? |
---|
| 2256 | + OPAL_TRUE : OPAL_FALSE; |
---|
| 2257 | + |
---|
| 2258 | + const struct opal_step mbr_steps[] = { |
---|
| 2259 | + { start_admin1LSP_opal_session, &mbr_done->key }, |
---|
| 2260 | + { set_mbr_done, &mbr_done_tf }, |
---|
| 2261 | + { end_opal_session, } |
---|
| 2262 | + }; |
---|
| 2263 | + int ret; |
---|
| 2264 | + |
---|
| 2265 | + if (mbr_done->done_flag != OPAL_MBR_DONE && |
---|
| 2266 | + mbr_done->done_flag != OPAL_MBR_NOT_DONE) |
---|
| 2267 | + return -EINVAL; |
---|
| 2268 | + |
---|
| 2269 | + mutex_lock(&dev->dev_lock); |
---|
| 2270 | + setup_opal_dev(dev); |
---|
| 2271 | + ret = execute_steps(dev, mbr_steps, ARRAY_SIZE(mbr_steps)); |
---|
| 2272 | + mutex_unlock(&dev->dev_lock); |
---|
| 2273 | + |
---|
| 2274 | + return ret; |
---|
| 2275 | +} |
---|
| 2276 | + |
---|
| 2277 | +static int opal_write_shadow_mbr(struct opal_dev *dev, |
---|
| 2278 | + struct opal_shadow_mbr *info) |
---|
| 2279 | +{ |
---|
| 2280 | + const struct opal_step mbr_steps[] = { |
---|
| 2281 | + { start_admin1LSP_opal_session, &info->key }, |
---|
| 2282 | + { write_shadow_mbr, info }, |
---|
| 2283 | + { end_opal_session, } |
---|
| 2284 | + }; |
---|
| 2285 | + int ret; |
---|
| 2286 | + |
---|
| 2287 | + if (info->size == 0) |
---|
| 2288 | + return 0; |
---|
| 2289 | + |
---|
| 2290 | + mutex_lock(&dev->dev_lock); |
---|
| 2291 | + setup_opal_dev(dev); |
---|
| 2292 | + ret = execute_steps(dev, mbr_steps, ARRAY_SIZE(mbr_steps)); |
---|
| 2293 | + mutex_unlock(&dev->dev_lock); |
---|
| 2294 | + |
---|
2121 | 2295 | return ret; |
---|
2122 | 2296 | } |
---|
2123 | 2297 | |
---|
.. | .. |
---|
2133 | 2307 | suspend->lr = lk_unlk->session.opal_key.lr; |
---|
2134 | 2308 | |
---|
2135 | 2309 | mutex_lock(&dev->dev_lock); |
---|
2136 | | - setup_opal_dev(dev, NULL); |
---|
| 2310 | + setup_opal_dev(dev); |
---|
2137 | 2311 | add_suspend_info(dev, suspend); |
---|
2138 | 2312 | mutex_unlock(&dev->dev_lock); |
---|
| 2313 | + |
---|
2139 | 2314 | return 0; |
---|
2140 | 2315 | } |
---|
2141 | 2316 | |
---|
.. | .. |
---|
2143 | 2318 | struct opal_lock_unlock *lk_unlk) |
---|
2144 | 2319 | { |
---|
2145 | 2320 | const struct opal_step steps[] = { |
---|
2146 | | - { opal_discovery0, }, |
---|
2147 | 2321 | { start_admin1LSP_opal_session, &lk_unlk->session.opal_key }, |
---|
2148 | 2322 | { add_user_to_lr, lk_unlk }, |
---|
2149 | | - { end_opal_session, }, |
---|
2150 | | - { NULL, } |
---|
| 2323 | + { end_opal_session, } |
---|
2151 | 2324 | }; |
---|
2152 | 2325 | int ret; |
---|
2153 | 2326 | |
---|
.. | .. |
---|
2156 | 2329 | pr_debug("Locking state was not RO or RW\n"); |
---|
2157 | 2330 | return -EINVAL; |
---|
2158 | 2331 | } |
---|
| 2332 | + |
---|
2159 | 2333 | if (lk_unlk->session.who < OPAL_USER1 || |
---|
2160 | 2334 | lk_unlk->session.who > OPAL_USER9) { |
---|
2161 | 2335 | pr_debug("Authority was not within the range of users: %d\n", |
---|
2162 | 2336 | lk_unlk->session.who); |
---|
2163 | 2337 | return -EINVAL; |
---|
2164 | 2338 | } |
---|
| 2339 | + |
---|
2165 | 2340 | if (lk_unlk->session.sum) { |
---|
2166 | 2341 | pr_debug("%s not supported in sum. Use setup locking range\n", |
---|
2167 | 2342 | __func__); |
---|
.. | .. |
---|
2169 | 2344 | } |
---|
2170 | 2345 | |
---|
2171 | 2346 | mutex_lock(&dev->dev_lock); |
---|
2172 | | - setup_opal_dev(dev, steps); |
---|
2173 | | - ret = next(dev); |
---|
| 2347 | + setup_opal_dev(dev); |
---|
| 2348 | + ret = execute_steps(dev, steps, ARRAY_SIZE(steps)); |
---|
2174 | 2349 | mutex_unlock(&dev->dev_lock); |
---|
| 2350 | + |
---|
2175 | 2351 | return ret; |
---|
2176 | 2352 | } |
---|
2177 | 2353 | |
---|
2178 | | -static int opal_reverttper(struct opal_dev *dev, struct opal_key *opal) |
---|
| 2354 | +static int opal_reverttper(struct opal_dev *dev, struct opal_key *opal, bool psid) |
---|
2179 | 2355 | { |
---|
| 2356 | + /* controller will terminate session */ |
---|
2180 | 2357 | const struct opal_step revert_steps[] = { |
---|
2181 | | - { opal_discovery0, }, |
---|
2182 | 2358 | { start_SIDASP_opal_session, opal }, |
---|
2183 | | - { revert_tper, }, /* controller will terminate session */ |
---|
2184 | | - { NULL, } |
---|
| 2359 | + { revert_tper, } |
---|
2185 | 2360 | }; |
---|
| 2361 | + const struct opal_step psid_revert_steps[] = { |
---|
| 2362 | + { start_PSID_opal_session, opal }, |
---|
| 2363 | + { revert_tper, } |
---|
| 2364 | + }; |
---|
| 2365 | + |
---|
2186 | 2366 | int ret; |
---|
2187 | 2367 | |
---|
2188 | 2368 | mutex_lock(&dev->dev_lock); |
---|
2189 | | - setup_opal_dev(dev, revert_steps); |
---|
2190 | | - ret = next(dev); |
---|
| 2369 | + setup_opal_dev(dev); |
---|
| 2370 | + if (psid) |
---|
| 2371 | + ret = execute_steps(dev, psid_revert_steps, |
---|
| 2372 | + ARRAY_SIZE(psid_revert_steps)); |
---|
| 2373 | + else |
---|
| 2374 | + ret = execute_steps(dev, revert_steps, |
---|
| 2375 | + ARRAY_SIZE(revert_steps)); |
---|
2191 | 2376 | mutex_unlock(&dev->dev_lock); |
---|
2192 | 2377 | |
---|
2193 | 2378 | /* |
---|
.. | .. |
---|
2204 | 2389 | struct opal_lock_unlock *lk_unlk) |
---|
2205 | 2390 | { |
---|
2206 | 2391 | const struct opal_step unlock_steps[] = { |
---|
2207 | | - { opal_discovery0, }, |
---|
2208 | 2392 | { start_auth_opal_session, &lk_unlk->session }, |
---|
2209 | 2393 | { lock_unlock_locking_range, lk_unlk }, |
---|
2210 | | - { end_opal_session, }, |
---|
2211 | | - { NULL, } |
---|
| 2394 | + { end_opal_session, } |
---|
2212 | 2395 | }; |
---|
2213 | 2396 | const struct opal_step unlock_sum_steps[] = { |
---|
2214 | | - { opal_discovery0, }, |
---|
2215 | 2397 | { start_auth_opal_session, &lk_unlk->session }, |
---|
2216 | 2398 | { lock_unlock_locking_range_sum, lk_unlk }, |
---|
2217 | | - { end_opal_session, }, |
---|
2218 | | - { NULL, } |
---|
| 2399 | + { end_opal_session, } |
---|
2219 | 2400 | }; |
---|
2220 | 2401 | |
---|
2221 | | - dev->steps = lk_unlk->session.sum ? unlock_sum_steps : unlock_steps; |
---|
2222 | | - return next(dev); |
---|
| 2402 | + if (lk_unlk->session.sum) |
---|
| 2403 | + return execute_steps(dev, unlock_sum_steps, |
---|
| 2404 | + ARRAY_SIZE(unlock_sum_steps)); |
---|
| 2405 | + else |
---|
| 2406 | + return execute_steps(dev, unlock_steps, |
---|
| 2407 | + ARRAY_SIZE(unlock_steps)); |
---|
2223 | 2408 | } |
---|
2224 | 2409 | |
---|
2225 | 2410 | static int __opal_set_mbr_done(struct opal_dev *dev, struct opal_key *key) |
---|
2226 | 2411 | { |
---|
2227 | 2412 | u8 mbr_done_tf = OPAL_TRUE; |
---|
2228 | | - const struct opal_step mbrdone_step [] = { |
---|
2229 | | - { opal_discovery0, }, |
---|
| 2413 | + const struct opal_step mbrdone_step[] = { |
---|
2230 | 2414 | { start_admin1LSP_opal_session, key }, |
---|
2231 | 2415 | { set_mbr_done, &mbr_done_tf }, |
---|
2232 | | - { end_opal_session, }, |
---|
2233 | | - { NULL, } |
---|
| 2416 | + { end_opal_session, } |
---|
2234 | 2417 | }; |
---|
2235 | 2418 | |
---|
2236 | | - dev->steps = mbrdone_step; |
---|
2237 | | - return next(dev); |
---|
| 2419 | + return execute_steps(dev, mbrdone_step, ARRAY_SIZE(mbrdone_step)); |
---|
2238 | 2420 | } |
---|
2239 | 2421 | |
---|
2240 | 2422 | static int opal_lock_unlock(struct opal_dev *dev, |
---|
.. | .. |
---|
2242 | 2424 | { |
---|
2243 | 2425 | int ret; |
---|
2244 | 2426 | |
---|
2245 | | - if (lk_unlk->session.who < OPAL_ADMIN1 || |
---|
2246 | | - lk_unlk->session.who > OPAL_USER9) |
---|
| 2427 | + if (lk_unlk->session.who > OPAL_USER9) |
---|
2247 | 2428 | return -EINVAL; |
---|
2248 | 2429 | |
---|
2249 | 2430 | mutex_lock(&dev->dev_lock); |
---|
2250 | 2431 | ret = __opal_lock_unlock(dev, lk_unlk); |
---|
2251 | 2432 | mutex_unlock(&dev->dev_lock); |
---|
| 2433 | + |
---|
2252 | 2434 | return ret; |
---|
2253 | 2435 | } |
---|
2254 | 2436 | |
---|
2255 | 2437 | static int opal_take_ownership(struct opal_dev *dev, struct opal_key *opal) |
---|
2256 | 2438 | { |
---|
2257 | 2439 | const struct opal_step owner_steps[] = { |
---|
2258 | | - { opal_discovery0, }, |
---|
2259 | 2440 | { start_anybodyASP_opal_session, }, |
---|
2260 | 2441 | { get_msid_cpin_pin, }, |
---|
2261 | 2442 | { end_opal_session, }, |
---|
2262 | 2443 | { start_SIDASP_opal_session, opal }, |
---|
2263 | 2444 | { set_sid_cpin_pin, opal }, |
---|
2264 | | - { end_opal_session, }, |
---|
2265 | | - { NULL, } |
---|
| 2445 | + { end_opal_session, } |
---|
2266 | 2446 | }; |
---|
2267 | 2447 | int ret; |
---|
2268 | 2448 | |
---|
.. | .. |
---|
2270 | 2450 | return -ENODEV; |
---|
2271 | 2451 | |
---|
2272 | 2452 | mutex_lock(&dev->dev_lock); |
---|
2273 | | - setup_opal_dev(dev, owner_steps); |
---|
2274 | | - ret = next(dev); |
---|
| 2453 | + setup_opal_dev(dev); |
---|
| 2454 | + ret = execute_steps(dev, owner_steps, ARRAY_SIZE(owner_steps)); |
---|
2275 | 2455 | mutex_unlock(&dev->dev_lock); |
---|
| 2456 | + |
---|
2276 | 2457 | return ret; |
---|
2277 | 2458 | } |
---|
2278 | 2459 | |
---|
2279 | | -static int opal_activate_lsp(struct opal_dev *dev, struct opal_lr_act *opal_lr_act) |
---|
| 2460 | +static int opal_activate_lsp(struct opal_dev *dev, |
---|
| 2461 | + struct opal_lr_act *opal_lr_act) |
---|
2280 | 2462 | { |
---|
2281 | 2463 | const struct opal_step active_steps[] = { |
---|
2282 | | - { opal_discovery0, }, |
---|
2283 | 2464 | { start_SIDASP_opal_session, &opal_lr_act->key }, |
---|
2284 | 2465 | { get_lsp_lifecycle, }, |
---|
2285 | 2466 | { activate_lsp, opal_lr_act }, |
---|
2286 | | - { end_opal_session, }, |
---|
2287 | | - { NULL, } |
---|
| 2467 | + { end_opal_session, } |
---|
2288 | 2468 | }; |
---|
2289 | 2469 | int ret; |
---|
2290 | 2470 | |
---|
.. | .. |
---|
2292 | 2472 | return -EINVAL; |
---|
2293 | 2473 | |
---|
2294 | 2474 | mutex_lock(&dev->dev_lock); |
---|
2295 | | - setup_opal_dev(dev, active_steps); |
---|
2296 | | - ret = next(dev); |
---|
| 2475 | + setup_opal_dev(dev); |
---|
| 2476 | + ret = execute_steps(dev, active_steps, ARRAY_SIZE(active_steps)); |
---|
2297 | 2477 | mutex_unlock(&dev->dev_lock); |
---|
| 2478 | + |
---|
2298 | 2479 | return ret; |
---|
2299 | 2480 | } |
---|
2300 | 2481 | |
---|
.. | .. |
---|
2302 | 2483 | struct opal_user_lr_setup *opal_lrs) |
---|
2303 | 2484 | { |
---|
2304 | 2485 | const struct opal_step lr_steps[] = { |
---|
2305 | | - { opal_discovery0, }, |
---|
2306 | 2486 | { start_auth_opal_session, &opal_lrs->session }, |
---|
2307 | 2487 | { setup_locking_range, opal_lrs }, |
---|
2308 | | - { end_opal_session, }, |
---|
2309 | | - { NULL, } |
---|
| 2488 | + { end_opal_session, } |
---|
2310 | 2489 | }; |
---|
2311 | 2490 | int ret; |
---|
2312 | 2491 | |
---|
2313 | 2492 | mutex_lock(&dev->dev_lock); |
---|
2314 | | - setup_opal_dev(dev, lr_steps); |
---|
2315 | | - ret = next(dev); |
---|
| 2493 | + setup_opal_dev(dev); |
---|
| 2494 | + ret = execute_steps(dev, lr_steps, ARRAY_SIZE(lr_steps)); |
---|
2316 | 2495 | mutex_unlock(&dev->dev_lock); |
---|
| 2496 | + |
---|
2317 | 2497 | return ret; |
---|
2318 | 2498 | } |
---|
2319 | 2499 | |
---|
2320 | 2500 | static int opal_set_new_pw(struct opal_dev *dev, struct opal_new_pw *opal_pw) |
---|
2321 | 2501 | { |
---|
2322 | 2502 | const struct opal_step pw_steps[] = { |
---|
2323 | | - { opal_discovery0, }, |
---|
2324 | 2503 | { start_auth_opal_session, &opal_pw->session }, |
---|
2325 | 2504 | { set_new_pw, &opal_pw->new_user_pw }, |
---|
2326 | | - { end_opal_session, }, |
---|
2327 | | - { NULL } |
---|
| 2505 | + { end_opal_session, } |
---|
2328 | 2506 | }; |
---|
2329 | 2507 | int ret; |
---|
2330 | 2508 | |
---|
2331 | | - if (opal_pw->session.who < OPAL_ADMIN1 || |
---|
2332 | | - opal_pw->session.who > OPAL_USER9 || |
---|
2333 | | - opal_pw->new_user_pw.who < OPAL_ADMIN1 || |
---|
| 2509 | + if (opal_pw->session.who > OPAL_USER9 || |
---|
2334 | 2510 | opal_pw->new_user_pw.who > OPAL_USER9) |
---|
2335 | 2511 | return -EINVAL; |
---|
2336 | 2512 | |
---|
2337 | 2513 | mutex_lock(&dev->dev_lock); |
---|
2338 | | - setup_opal_dev(dev, pw_steps); |
---|
2339 | | - ret = next(dev); |
---|
| 2514 | + setup_opal_dev(dev); |
---|
| 2515 | + ret = execute_steps(dev, pw_steps, ARRAY_SIZE(pw_steps)); |
---|
2340 | 2516 | mutex_unlock(&dev->dev_lock); |
---|
| 2517 | + |
---|
2341 | 2518 | return ret; |
---|
2342 | 2519 | } |
---|
2343 | 2520 | |
---|
.. | .. |
---|
2345 | 2522 | struct opal_session_info *opal_session) |
---|
2346 | 2523 | { |
---|
2347 | 2524 | const struct opal_step act_steps[] = { |
---|
2348 | | - { opal_discovery0, }, |
---|
2349 | 2525 | { start_admin1LSP_opal_session, &opal_session->opal_key }, |
---|
2350 | 2526 | { internal_activate_user, opal_session }, |
---|
2351 | | - { end_opal_session, }, |
---|
2352 | | - { NULL, } |
---|
| 2527 | + { end_opal_session, } |
---|
2353 | 2528 | }; |
---|
2354 | 2529 | int ret; |
---|
2355 | 2530 | |
---|
.. | .. |
---|
2361 | 2536 | } |
---|
2362 | 2537 | |
---|
2363 | 2538 | mutex_lock(&dev->dev_lock); |
---|
2364 | | - setup_opal_dev(dev, act_steps); |
---|
2365 | | - ret = next(dev); |
---|
| 2539 | + setup_opal_dev(dev); |
---|
| 2540 | + ret = execute_steps(dev, act_steps, ARRAY_SIZE(act_steps)); |
---|
2366 | 2541 | mutex_unlock(&dev->dev_lock); |
---|
| 2542 | + |
---|
2367 | 2543 | return ret; |
---|
2368 | 2544 | } |
---|
2369 | 2545 | |
---|
.. | .. |
---|
2375 | 2551 | |
---|
2376 | 2552 | if (!dev) |
---|
2377 | 2553 | return false; |
---|
| 2554 | + |
---|
2378 | 2555 | if (!dev->supported) |
---|
2379 | 2556 | return false; |
---|
2380 | 2557 | |
---|
2381 | 2558 | mutex_lock(&dev->dev_lock); |
---|
2382 | | - setup_opal_dev(dev, NULL); |
---|
| 2559 | + setup_opal_dev(dev); |
---|
2383 | 2560 | |
---|
2384 | 2561 | list_for_each_entry(suspend, &dev->unlk_lst, node) { |
---|
2385 | 2562 | dev->tsn = 0; |
---|
.. | .. |
---|
2392 | 2569 | suspend->unlk.session.sum); |
---|
2393 | 2570 | was_failure = true; |
---|
2394 | 2571 | } |
---|
| 2572 | + |
---|
2395 | 2573 | if (dev->mbr_enabled) { |
---|
2396 | 2574 | ret = __opal_set_mbr_done(dev, &suspend->unlk.session.opal_key); |
---|
2397 | 2575 | if (ret) |
---|
.. | .. |
---|
2399 | 2577 | } |
---|
2400 | 2578 | } |
---|
2401 | 2579 | mutex_unlock(&dev->dev_lock); |
---|
| 2580 | + |
---|
2402 | 2581 | return was_failure; |
---|
2403 | 2582 | } |
---|
2404 | 2583 | EXPORT_SYMBOL(opal_unlock_from_suspend); |
---|
| 2584 | + |
---|
| 2585 | +static int opal_read_table(struct opal_dev *dev, |
---|
| 2586 | + struct opal_read_write_table *rw_tbl) |
---|
| 2587 | +{ |
---|
| 2588 | + const struct opal_step read_table_steps[] = { |
---|
| 2589 | + { start_admin1LSP_opal_session, &rw_tbl->key }, |
---|
| 2590 | + { read_table_data, rw_tbl }, |
---|
| 2591 | + { end_opal_session, } |
---|
| 2592 | + }; |
---|
| 2593 | + int ret = 0; |
---|
| 2594 | + |
---|
| 2595 | + if (!rw_tbl->size) |
---|
| 2596 | + return ret; |
---|
| 2597 | + |
---|
| 2598 | + return execute_steps(dev, read_table_steps, |
---|
| 2599 | + ARRAY_SIZE(read_table_steps)); |
---|
| 2600 | +} |
---|
| 2601 | + |
---|
| 2602 | +static int opal_write_table(struct opal_dev *dev, |
---|
| 2603 | + struct opal_read_write_table *rw_tbl) |
---|
| 2604 | +{ |
---|
| 2605 | + const struct opal_step write_table_steps[] = { |
---|
| 2606 | + { start_admin1LSP_opal_session, &rw_tbl->key }, |
---|
| 2607 | + { write_table_data, rw_tbl }, |
---|
| 2608 | + { end_opal_session, } |
---|
| 2609 | + }; |
---|
| 2610 | + int ret = 0; |
---|
| 2611 | + |
---|
| 2612 | + if (!rw_tbl->size) |
---|
| 2613 | + return ret; |
---|
| 2614 | + |
---|
| 2615 | + return execute_steps(dev, write_table_steps, |
---|
| 2616 | + ARRAY_SIZE(write_table_steps)); |
---|
| 2617 | +} |
---|
| 2618 | + |
---|
| 2619 | +static int opal_generic_read_write_table(struct opal_dev *dev, |
---|
| 2620 | + struct opal_read_write_table *rw_tbl) |
---|
| 2621 | +{ |
---|
| 2622 | + int ret, bit_set; |
---|
| 2623 | + |
---|
| 2624 | + mutex_lock(&dev->dev_lock); |
---|
| 2625 | + setup_opal_dev(dev); |
---|
| 2626 | + |
---|
| 2627 | + bit_set = fls64(rw_tbl->flags) - 1; |
---|
| 2628 | + switch (bit_set) { |
---|
| 2629 | + case OPAL_READ_TABLE: |
---|
| 2630 | + ret = opal_read_table(dev, rw_tbl); |
---|
| 2631 | + break; |
---|
| 2632 | + case OPAL_WRITE_TABLE: |
---|
| 2633 | + ret = opal_write_table(dev, rw_tbl); |
---|
| 2634 | + break; |
---|
| 2635 | + default: |
---|
| 2636 | + pr_debug("Invalid bit set in the flag (%016llx).\n", |
---|
| 2637 | + rw_tbl->flags); |
---|
| 2638 | + ret = -EINVAL; |
---|
| 2639 | + break; |
---|
| 2640 | + } |
---|
| 2641 | + |
---|
| 2642 | + mutex_unlock(&dev->dev_lock); |
---|
| 2643 | + |
---|
| 2644 | + return ret; |
---|
| 2645 | +} |
---|
2405 | 2646 | |
---|
2406 | 2647 | int sed_ioctl(struct opal_dev *dev, unsigned int cmd, void __user *arg) |
---|
2407 | 2648 | { |
---|
.. | .. |
---|
2439 | 2680 | ret = opal_activate_user(dev, p); |
---|
2440 | 2681 | break; |
---|
2441 | 2682 | case IOC_OPAL_REVERT_TPR: |
---|
2442 | | - ret = opal_reverttper(dev, p); |
---|
| 2683 | + ret = opal_reverttper(dev, p, false); |
---|
2443 | 2684 | break; |
---|
2444 | 2685 | case IOC_OPAL_LR_SETUP: |
---|
2445 | 2686 | ret = opal_setup_locking_range(dev, p); |
---|
.. | .. |
---|
2450 | 2691 | case IOC_OPAL_ENABLE_DISABLE_MBR: |
---|
2451 | 2692 | ret = opal_enable_disable_shadow_mbr(dev, p); |
---|
2452 | 2693 | break; |
---|
| 2694 | + case IOC_OPAL_MBR_DONE: |
---|
| 2695 | + ret = opal_set_mbr_done(dev, p); |
---|
| 2696 | + break; |
---|
| 2697 | + case IOC_OPAL_WRITE_SHADOW_MBR: |
---|
| 2698 | + ret = opal_write_shadow_mbr(dev, p); |
---|
| 2699 | + break; |
---|
2453 | 2700 | case IOC_OPAL_ERASE_LR: |
---|
2454 | 2701 | ret = opal_erase_locking_range(dev, p); |
---|
2455 | 2702 | break; |
---|
2456 | 2703 | case IOC_OPAL_SECURE_ERASE_LR: |
---|
2457 | 2704 | ret = opal_secure_erase_locking_range(dev, p); |
---|
2458 | 2705 | break; |
---|
| 2706 | + case IOC_OPAL_PSID_REVERT_TPR: |
---|
| 2707 | + ret = opal_reverttper(dev, p, true); |
---|
| 2708 | + break; |
---|
| 2709 | + case IOC_OPAL_GENERIC_TABLE_RW: |
---|
| 2710 | + ret = opal_generic_read_write_table(dev, p); |
---|
| 2711 | + break; |
---|
2459 | 2712 | default: |
---|
2460 | 2713 | break; |
---|
2461 | 2714 | } |
---|