hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
kernel/block/sed-opal.c
....@@ -1,18 +1,10 @@
1
+// SPDX-License-Identifier: GPL-2.0
12 /*
23 * Copyright © 2016 Intel Corporation
34 *
45 * Authors:
56 * Scott Bauer <scott.bauer@intel.com>
67 * 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.
168 */
179
1810 #define pr_fmt(fmt) KBUILD_MODNAME ":OPAL: " fmt
....@@ -33,6 +25,9 @@
3325
3426 #define IO_BUFFER_LENGTH 2048
3527 #define MAX_TOKS 64
28
+
29
+/* Number of bytes needed by cmd_finalize. */
30
+#define CMD_FINALIZE_BYTES_NEEDED 7
3631
3732 struct opal_step {
3833 int (*fn)(struct opal_dev *dev, void *data);
....@@ -85,7 +80,6 @@
8580 void *data;
8681 sec_send_recv *send_recv;
8782
88
- const struct opal_step *steps;
8983 struct mutex dev_lock;
9084 u16 comid;
9185 u32 hsn;
....@@ -94,8 +88,8 @@
9488 u64 lowest_lba;
9589
9690 size_t pos;
97
- u8 cmd[IO_BUFFER_LENGTH];
98
- u8 resp[IO_BUFFER_LENGTH];
91
+ u8 *cmd;
92
+ u8 *resp;
9993
10094 struct parsed_resp parsed;
10195 size_t prev_d_len;
....@@ -135,7 +129,8 @@
135129 { 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x84, 0x01 },
136130
137131 /* tables */
138
-
132
+ [OPAL_TABLE_TABLE] =
133
+ { 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01 },
139134 [OPAL_LOCKINGRANGE_GLOBAL] =
140135 { 0x00, 0x00, 0x08, 0x02, 0x00, 0x00, 0x00, 0x01 },
141136 [OPAL_LOCKINGRANGE_ACE_RDLOCKED] =
....@@ -154,10 +149,11 @@
154149 { 0x00, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x01 },
155150 [OPAL_ENTERPRISE_LOCKING_INFO_TABLE] =
156151 { 0x00, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x00 },
152
+ [OPAL_DATASTORE] =
153
+ { 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x00, 0x00 },
157154
158155 /* C_PIN_TABLE object ID's */
159
-
160
- [OPAL_C_PIN_MSID] =
156
+ [OPAL_C_PIN_MSID] =
161157 { 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x84, 0x02},
162158 [OPAL_C_PIN_SID] =
163159 { 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x01},
....@@ -165,7 +161,6 @@
165161 { 0x00, 0x00, 0x00, 0x0B, 0x00, 0x01, 0x00, 0x01},
166162
167163 /* half UID's (only first 4 bytes used) */
168
-
169164 [OPAL_HALF_UID_AUTHORITY_OBJ_REF] =
170165 { 0x00, 0x00, 0x0C, 0x05, 0xff, 0xff, 0xff, 0xff },
171166 [OPAL_HALF_UID_BOOLEAN_ACE] =
....@@ -181,7 +176,7 @@
181176 * Derived from: TCG_Storage_Architecture_Core_Spec_v2.01_r1.00
182177 * Section: 6.3 Assigned UIDs
183178 */
184
-static const u8 opalmethod[][OPAL_UID_LENGTH] = {
179
+static const u8 opalmethod[][OPAL_METHOD_LENGTH] = {
185180 [OPAL_PROPERTIES] =
186181 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x01 },
187182 [OPAL_STARTSESSION] =
....@@ -217,6 +212,7 @@
217212 };
218213
219214 static int end_opal_session_error(struct opal_dev *dev);
215
+static int opal_discovery0_step(struct opal_dev *dev);
220216
221217 struct opal_suspend_data {
222218 struct opal_lock_unlock unlk;
....@@ -378,41 +374,54 @@
378374 {
379375 const struct d0_geometry_features *geo = data;
380376
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);
383379 }
384380
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)
386383 {
387
- const struct opal_step *step;
388
- int state = 0, error = 0;
384
+ int error = step->fn(dev, step->data);
389385
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
+ }
394391
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
+}
400394
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;
412400
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);
416425
417426 return error;
418427 }
....@@ -507,18 +516,43 @@
507516 ret = opal_recv_cmd(dev);
508517 if (ret)
509518 return ret;
519
+
510520 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;
511549 }
512550
513551 static void add_token_u8(int *err, struct opal_dev *cmd, u8 tok)
514552 {
515
- if (*err)
553
+ if (!can_add(err, cmd, 1))
516554 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
+
522556 cmd->cmd[cmd->pos++] = tok;
523557 }
524558
....@@ -545,13 +579,13 @@
545579 header0 |= bytestring ? MEDIUM_ATOM_BYTESTRING : 0;
546580 header0 |= has_sign ? MEDIUM_ATOM_SIGNED : 0;
547581 header0 |= (len >> 8) & MEDIUM_ATOM_LEN_MASK;
582
+
548583 cmd->cmd[cmd->pos++] = header0;
549584 cmd->cmd[cmd->pos++] = len;
550585 }
551586
552587 static void add_token_u64(int *err, struct opal_dev *cmd, u64 number)
553588 {
554
-
555589 size_t len;
556590 int msb;
557591
....@@ -563,9 +597,8 @@
563597 msb = fls64(number);
564598 len = DIV_ROUND_UP(msb, 8);
565599
566
- if (cmd->pos >= IO_BUFFER_LENGTH - len - 1) {
600
+ if (!can_add(err, cmd, len + 1)) {
567601 pr_debug("Error adding u64: end of buffer.\n");
568
- *err = -ERANGE;
569602 return;
570603 }
571604 add_short_atom_header(cmd, false, false, len);
....@@ -573,24 +606,19 @@
573606 add_token_u8(err, cmd, number >> (len * 8));
574607 }
575608
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)
578610 {
579611 size_t header_len = 1;
580612 bool is_short_atom = true;
581
-
582
- if (*err)
583
- return;
584613
585614 if (len & ~SHORT_ATOM_LEN_MASK) {
586615 header_len = 2;
587616 is_short_atom = false;
588617 }
589618
590
- if (len >= IO_BUFFER_LENGTH - cmd->pos - header_len) {
619
+ if (!can_add(err, cmd, header_len + len)) {
591620 pr_debug("Error adding bytestring: end of buffer.\n");
592
- *err = -ERANGE;
593
- return;
621
+ return NULL;
594622 }
595623
596624 if (is_short_atom)
....@@ -598,9 +626,19 @@
598626 else
599627 add_medium_atom_header(cmd, true, false, len);
600628
601
- memcpy(&cmd->cmd[cmd->pos], bytestring, len);
602
- cmd->pos += len;
629
+ return &cmd->cmd[cmd->pos];
630
+}
603631
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;
604642 }
605643
606644 static int build_locking_range(u8 *buffer, size_t length, u8 lr)
....@@ -614,6 +652,7 @@
614652
615653 if (lr == 0)
616654 return 0;
655
+
617656 buffer[5] = LOCKING_RANGE_NON_GLOBAL;
618657 buffer[7] = lr;
619658
....@@ -623,7 +662,7 @@
623662 static int build_locking_user(u8 *buffer, size_t length, u8 lr)
624663 {
625664 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");
627666 return -ERANGE;
628667 }
629668
....@@ -648,6 +687,13 @@
648687 {
649688 struct opal_header *hdr;
650689 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);
651697
652698 add_token_u8(&err, cmd, OPAL_ENDOFDATA);
653699 add_token_u8(&err, cmd, OPAL_STARTLIST);
....@@ -686,6 +732,11 @@
686732 int n)
687733 {
688734 const struct opal_resp_tok *tok;
735
+
736
+ if (!resp) {
737
+ pr_debug("Response is NULL\n");
738
+ return ERR_PTR(-EINVAL);
739
+ }
689740
690741 if (n >= resp->num) {
691742 pr_debug("Token number doesn't exist: %d, resp: %d\n",
....@@ -856,10 +907,6 @@
856907 num_entries++;
857908 }
858909
859
- if (num_entries == 0) {
860
- pr_debug("Couldn't parse response.\n");
861
- return -EINVAL;
862
- }
863910 resp->num = num_entries;
864911
865912 return 0;
....@@ -869,27 +916,19 @@
869916 const char **store)
870917 {
871918 u8 skip;
872
- const struct opal_resp_tok *token;
919
+ const struct opal_resp_tok *tok;
873920
874921 *store = NULL;
875
- if (!resp) {
876
- pr_debug("Response is NULL\n");
922
+ tok = response_get_token(resp, n);
923
+ if (IS_ERR(tok))
877924 return 0;
878
- }
879925
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) {
888927 pr_debug("Token is not a byte string!\n");
889928 return 0;
890929 }
891930
892
- switch (token->width) {
931
+ switch (tok->width) {
893932 case OPAL_WIDTH_TINY:
894933 case OPAL_WIDTH_SHORT:
895934 skip = 1;
....@@ -905,37 +944,30 @@
905944 return 0;
906945 }
907946
908
- *store = token->pos + skip;
909
- return token->len - skip;
947
+ *store = tok->pos + skip;
948
+
949
+ return tok->len - skip;
910950 }
911951
912952 static u64 response_get_u64(const struct parsed_resp *resp, int n)
913953 {
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);
916962 return 0;
917963 }
918964
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);
922967 return 0;
923968 }
924969
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;
939971 }
940972
941973 static bool response_token_matches(const struct opal_resp_tok *token, u8 match)
....@@ -991,6 +1023,27 @@
9911023 memset(dev->cmd, 0, IO_BUFFER_LENGTH);
9921024 }
9931025
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
+
9941047 static int start_opal_session_cont(struct opal_dev *dev)
9951048 {
9961049 u32 hsn, tsn;
....@@ -1003,13 +1056,14 @@
10031056 hsn = response_get_u64(&dev->parsed, 4);
10041057 tsn = response_get_u64(&dev->parsed, 5);
10051058
1006
- if (hsn == 0 && tsn == 0) {
1059
+ if (hsn != GENERIC_HOST_SESSION_NUM || tsn < FIRST_TPER_SESSION_NUM) {
10071060 pr_debug("Couldn't authenticate session\n");
10081061 return -EPERM;
10091062 }
10101063
10111064 dev->hsn = hsn;
10121065 dev->tsn = tsn;
1066
+
10131067 return 0;
10141068 }
10151069
....@@ -1032,6 +1086,7 @@
10321086 {
10331087 dev->hsn = 0;
10341088 dev->tsn = 0;
1089
+
10351090 return parse_and_check_status(dev);
10361091 }
10371092
....@@ -1050,30 +1105,77 @@
10501105 return opal_send_recv(dev, cont);
10511106 }
10521107
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
+
10531162 static int gen_key(struct opal_dev *dev, void *data)
10541163 {
10551164 u8 uid[OPAL_UID_LENGTH];
1056
- int err = 0;
1057
-
1058
- clear_opal_cmd(dev);
1059
- set_comid(dev, dev->comid);
1165
+ int err;
10601166
10611167 memcpy(uid, dev->prev_data, min(sizeof(uid), dev->prev_d_len));
10621168 kfree(dev->prev_data);
10631169 dev->prev_data = NULL;
10641170
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]);
10711172
10721173 if (err) {
10731174 pr_debug("Error building gen key command\n");
10741175 return err;
10751176
10761177 }
1178
+
10771179 return finalize_and_send(dev, parse_and_check_status);
10781180 }
10791181
....@@ -1086,12 +1188,14 @@
10861188 error = parse_and_check_status(dev);
10871189 if (error)
10881190 return error;
1191
+
10891192 keylen = response_get_string(&dev->parsed, 4, &activekey);
10901193 if (!activekey) {
10911194 pr_debug("%s: Couldn't extract the Activekey from the response\n",
10921195 __func__);
10931196 return OPAL_INVAL_PARAM;
10941197 }
1198
+
10951199 dev->prev_data = kmemdup(activekey, keylen, GFP_KERNEL);
10961200
10971201 if (!dev->prev_data)
....@@ -1105,62 +1209,108 @@
11051209 static int get_active_key(struct opal_dev *dev, void *data)
11061210 {
11071211 u8 uid[OPAL_UID_LENGTH];
1108
- int err = 0;
1212
+ int err;
11091213 u8 *lr = data;
1110
-
1111
- clear_opal_cmd(dev);
1112
- set_comid(dev, dev->comid);
11131214
11141215 err = build_locking_range(uid, sizeof(uid), *lr);
11151216 if (err)
11161217 return err;
11171218
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);
11341237 if (err) {
1135
- pr_debug("Error building get active key command\n");
1238
+ pr_debug("Couldn't get the table size\n");
11361239 return err;
11371240 }
11381241
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;
11401293 }
11411294
11421295 static int generic_lr_enable_disable(struct opal_dev *dev,
11431296 u8 *uid, bool rle, bool wle,
11441297 bool rl, bool wl)
11451298 {
1146
- int err = 0;
1299
+ int err;
11471300
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]);
11511302
1152
- add_token_u8(&err, dev, OPAL_STARTLIST);
11531303 add_token_u8(&err, dev, OPAL_STARTNAME);
11541304 add_token_u8(&err, dev, OPAL_VALUES);
11551305 add_token_u8(&err, dev, OPAL_STARTLIST);
11561306
11571307 add_token_u8(&err, dev, OPAL_STARTNAME);
1158
- add_token_u8(&err, dev, 5); /* ReadLockEnabled */
1308
+ add_token_u8(&err, dev, OPAL_READLOCKENABLED);
11591309 add_token_u8(&err, dev, rle);
11601310 add_token_u8(&err, dev, OPAL_ENDNAME);
11611311
11621312 add_token_u8(&err, dev, OPAL_STARTNAME);
1163
- add_token_u8(&err, dev, 6); /* WriteLockEnabled */
1313
+ add_token_u8(&err, dev, OPAL_WRITELOCKENABLED);
11641314 add_token_u8(&err, dev, wle);
11651315 add_token_u8(&err, dev, OPAL_ENDNAME);
11661316
....@@ -1176,7 +1326,7 @@
11761326
11771327 add_token_u8(&err, dev, OPAL_ENDLIST);
11781328 add_token_u8(&err, dev, OPAL_ENDNAME);
1179
- add_token_u8(&err, dev, OPAL_ENDLIST);
1329
+
11801330 return err;
11811331 }
11821332
....@@ -1189,6 +1339,7 @@
11891339 0, 0);
11901340 if (err)
11911341 pr_debug("Failed to create enable global lr command\n");
1342
+
11921343 return err;
11931344 }
11941345
....@@ -1197,10 +1348,7 @@
11971348 u8 uid[OPAL_UID_LENGTH];
11981349 struct opal_user_lr_setup *setup = data;
11991350 u8 lr;
1200
- int err = 0;
1201
-
1202
- clear_opal_cmd(dev);
1203
- set_comid(dev, dev->comid);
1351
+ int err;
12041352
12051353 lr = setup->session.opal_key.lr;
12061354 err = build_locking_range(uid, sizeof(uid), lr);
....@@ -1210,45 +1358,38 @@
12101358 if (lr == 0)
12111359 err = enable_global_lr(dev, uid, setup);
12121360 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]);
12171362
1218
- add_token_u8(&err, dev, OPAL_STARTLIST);
12191363 add_token_u8(&err, dev, OPAL_STARTNAME);
12201364 add_token_u8(&err, dev, OPAL_VALUES);
12211365 add_token_u8(&err, dev, OPAL_STARTLIST);
12221366
12231367 add_token_u8(&err, dev, OPAL_STARTNAME);
1224
- add_token_u8(&err, dev, 3); /* Ranges Start */
1368
+ add_token_u8(&err, dev, OPAL_RANGESTART);
12251369 add_token_u64(&err, dev, setup->range_start);
12261370 add_token_u8(&err, dev, OPAL_ENDNAME);
12271371
12281372 add_token_u8(&err, dev, OPAL_STARTNAME);
1229
- add_token_u8(&err, dev, 4); /* Ranges length */
1373
+ add_token_u8(&err, dev, OPAL_RANGELENGTH);
12301374 add_token_u64(&err, dev, setup->range_length);
12311375 add_token_u8(&err, dev, OPAL_ENDNAME);
12321376
12331377 add_token_u8(&err, dev, OPAL_STARTNAME);
1234
- add_token_u8(&err, dev, 5); /*ReadLockEnabled */
1378
+ add_token_u8(&err, dev, OPAL_READLOCKENABLED);
12351379 add_token_u64(&err, dev, !!setup->RLE);
12361380 add_token_u8(&err, dev, OPAL_ENDNAME);
12371381
12381382 add_token_u8(&err, dev, OPAL_STARTNAME);
1239
- add_token_u8(&err, dev, 6); /*WriteLockEnabled*/
1383
+ add_token_u8(&err, dev, OPAL_WRITELOCKENABLED);
12401384 add_token_u64(&err, dev, !!setup->WLE);
12411385 add_token_u8(&err, dev, OPAL_ENDNAME);
12421386
12431387 add_token_u8(&err, dev, OPAL_ENDLIST);
12441388 add_token_u8(&err, dev, OPAL_ENDNAME);
1245
- add_token_u8(&err, dev, OPAL_ENDLIST);
1246
-
12471389 }
12481390 if (err) {
12491391 pr_debug("Error building Setup Locking range command.\n");
12501392 return err;
1251
-
12521393 }
12531394
12541395 return finalize_and_send(dev, parse_and_check_status);
....@@ -1261,32 +1402,25 @@
12611402 u8 key_len)
12621403 {
12631404 u32 hsn;
1264
- int err = 0;
1405
+ int err;
12651406
12661407 if (key == NULL && auth != OPAL_ANYBODY_UID)
12671408 return OPAL_INVAL_PARAM;
12681409
1269
- clear_opal_cmd(dev);
1270
-
1271
- set_comid(dev, dev->comid);
12721410 hsn = GENERIC_HOST_SESSION_NUM;
1411
+ err = cmd_start(dev, opaluid[OPAL_SMUID_UID],
1412
+ opalmethod[OPAL_STARTSESSION]);
12731413
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);
12801414 add_token_u64(&err, dev, hsn);
12811415 add_token_bytestring(&err, dev, opaluid[sp_type], OPAL_UID_LENGTH);
12821416 add_token_u8(&err, dev, 1);
12831417
12841418 switch (auth) {
12851419 case OPAL_ANYBODY_UID:
1286
- add_token_u8(&err, dev, OPAL_ENDLIST);
12871420 break;
12881421 case OPAL_ADMIN1_UID:
12891422 case OPAL_SID_UID:
1423
+ case OPAL_PSID_UID:
12901424 add_token_u8(&err, dev, OPAL_STARTNAME);
12911425 add_token_u8(&err, dev, 0); /* HostChallenge */
12921426 add_token_bytestring(&err, dev, key, key_len);
....@@ -1296,7 +1430,6 @@
12961430 add_token_bytestring(&err, dev, opaluid[auth],
12971431 OPAL_UID_LENGTH);
12981432 add_token_u8(&err, dev, OPAL_ENDNAME);
1299
- add_token_u8(&err, dev, OPAL_ENDLIST);
13001433 break;
13011434 default:
13021435 pr_debug("Cannot start Admin SP session with auth %d\n", auth);
....@@ -1324,6 +1457,7 @@
13241457
13251458 if (!key) {
13261459 const struct opal_key *okey = data;
1460
+
13271461 ret = start_generic_opal_session(dev, OPAL_SID_UID,
13281462 OPAL_ADMINSP_UID,
13291463 okey->key,
....@@ -1335,15 +1469,27 @@
13351469 kfree(key);
13361470 dev->prev_data = NULL;
13371471 }
1472
+
13381473 return ret;
13391474 }
13401475
13411476 static int start_admin1LSP_opal_session(struct opal_dev *dev, void *data)
13421477 {
13431478 struct opal_key *key = data;
1479
+
13441480 return start_generic_opal_session(dev, OPAL_ADMIN1_UID,
13451481 OPAL_LOCKINGSP_UID,
13461482 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);
13471493 }
13481494
13491495 static int start_auth_opal_session(struct opal_dev *dev, void *data)
....@@ -1356,30 +1502,21 @@
13561502 u8 *key = session->opal_key.key;
13571503 u32 hsn = GENERIC_HOST_SESSION_NUM;
13581504
1359
- clear_opal_cmd(dev);
1360
- set_comid(dev, dev->comid);
1361
-
1362
- if (session->sum) {
1505
+ if (session->sum)
13631506 err = build_locking_user(lk_ul_user, sizeof(lk_ul_user),
13641507 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)
13691509 err = build_locking_user(lk_ul_user, sizeof(lk_ul_user),
13701510 session->who - 1);
1371
- if (err)
1372
- return err;
1373
- } else
1511
+ else
13741512 memcpy(lk_ul_user, opaluid[OPAL_ADMIN1_UID], OPAL_UID_LENGTH);
13751513
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;
13811516
1382
- add_token_u8(&err, dev, OPAL_STARTLIST);
1517
+ err = cmd_start(dev, opaluid[OPAL_SMUID_UID],
1518
+ opalmethod[OPAL_STARTSESSION]);
1519
+
13831520 add_token_u64(&err, dev, hsn);
13841521 add_token_bytestring(&err, dev, opaluid[OPAL_LOCKINGSP_UID],
13851522 OPAL_UID_LENGTH);
....@@ -1392,7 +1529,6 @@
13921529 add_token_u8(&err, dev, 3);
13931530 add_token_bytestring(&err, dev, lk_ul_user, OPAL_UID_LENGTH);
13941531 add_token_u8(&err, dev, OPAL_ENDNAME);
1395
- add_token_u8(&err, dev, OPAL_ENDLIST);
13961532
13971533 if (err) {
13981534 pr_debug("Error building STARTSESSION command.\n");
....@@ -1404,18 +1540,10 @@
14041540
14051541 static int revert_tper(struct opal_dev *dev, void *data)
14061542 {
1407
- int err = 0;
1543
+ int err;
14081544
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]);
14191547 if (err) {
14201548 pr_debug("Error building REVERT TPER command.\n");
14211549 return err;
....@@ -1428,18 +1556,12 @@
14281556 {
14291557 struct opal_session_info *session = data;
14301558 u8 uid[OPAL_UID_LENGTH];
1431
- int err = 0;
1432
-
1433
- clear_opal_cmd(dev);
1434
- set_comid(dev, dev->comid);
1559
+ int err;
14351560
14361561 memcpy(uid, opaluid[OPAL_USER1_UID], OPAL_UID_LENGTH);
14371562 uid[7] = session->who;
14381563
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]);
14431565 add_token_u8(&err, dev, OPAL_STARTNAME);
14441566 add_token_u8(&err, dev, OPAL_VALUES);
14451567 add_token_u8(&err, dev, OPAL_STARTLIST);
....@@ -1449,7 +1571,6 @@
14491571 add_token_u8(&err, dev, OPAL_ENDNAME);
14501572 add_token_u8(&err, dev, OPAL_ENDLIST);
14511573 add_token_u8(&err, dev, OPAL_ENDNAME);
1452
- add_token_u8(&err, dev, OPAL_ENDLIST);
14531574
14541575 if (err) {
14551576 pr_debug("Error building Activate UserN command.\n");
....@@ -1463,51 +1584,38 @@
14631584 {
14641585 struct opal_session_info *session = data;
14651586 u8 uid[OPAL_UID_LENGTH];
1466
- int err = 0;
1467
-
1468
- clear_opal_cmd(dev);
1469
- set_comid(dev, dev->comid);
1587
+ int err;
14701588
14711589 if (build_locking_range(uid, sizeof(uid), session->opal_key.lr) < 0)
14721590 return -ERANGE;
14731591
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]);
14801593
14811594 if (err) {
14821595 pr_debug("Error building Erase Locking Range Command.\n");
14831596 return err;
14841597 }
1598
+
14851599 return finalize_and_send(dev, parse_and_check_status);
14861600 }
14871601
14881602 static int set_mbr_done(struct opal_dev *dev, void *data)
14891603 {
14901604 u8 *mbr_done_tf = data;
1491
- int err = 0;
1605
+ int err;
14921606
1493
- clear_opal_cmd(dev);
1494
- set_comid(dev, dev->comid);
1607
+ err = cmd_start(dev, opaluid[OPAL_MBRCONTROL],
1608
+ opalmethod[OPAL_SET]);
14951609
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);
15011610 add_token_u8(&err, dev, OPAL_STARTNAME);
15021611 add_token_u8(&err, dev, OPAL_VALUES);
15031612 add_token_u8(&err, dev, OPAL_STARTLIST);
15041613 add_token_u8(&err, dev, OPAL_STARTNAME);
1505
- add_token_u8(&err, dev, 2); /* Done */
1614
+ add_token_u8(&err, dev, OPAL_MBRDONE);
15061615 add_token_u8(&err, dev, *mbr_done_tf); /* Done T or F */
15071616 add_token_u8(&err, dev, OPAL_ENDNAME);
15081617 add_token_u8(&err, dev, OPAL_ENDLIST);
15091618 add_token_u8(&err, dev, OPAL_ENDNAME);
1510
- add_token_u8(&err, dev, OPAL_ENDLIST);
15111619
15121620 if (err) {
15131621 pr_debug("Error Building set MBR Done command\n");
....@@ -1520,26 +1628,20 @@
15201628 static int set_mbr_enable_disable(struct opal_dev *dev, void *data)
15211629 {
15221630 u8 *mbr_en_dis = data;
1523
- int err = 0;
1631
+ int err;
15241632
1525
- clear_opal_cmd(dev);
1526
- set_comid(dev, dev->comid);
1633
+ err = cmd_start(dev, opaluid[OPAL_MBRCONTROL],
1634
+ opalmethod[OPAL_SET]);
15271635
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);
15331636 add_token_u8(&err, dev, OPAL_STARTNAME);
15341637 add_token_u8(&err, dev, OPAL_VALUES);
15351638 add_token_u8(&err, dev, OPAL_STARTLIST);
15361639 add_token_u8(&err, dev, OPAL_STARTNAME);
1537
- add_token_u8(&err, dev, 1);
1640
+ add_token_u8(&err, dev, OPAL_MBRENABLE);
15381641 add_token_u8(&err, dev, *mbr_en_dis);
15391642 add_token_u8(&err, dev, OPAL_ENDNAME);
15401643 add_token_u8(&err, dev, OPAL_ENDLIST);
15411644 add_token_u8(&err, dev, OPAL_ENDNAME);
1542
- add_token_u8(&err, dev, OPAL_ENDLIST);
15431645
15441646 if (err) {
15451647 pr_debug("Error Building set MBR done command\n");
....@@ -1549,29 +1651,30 @@
15491651 return finalize_and_send(dev, parse_and_check_status);
15501652 }
15511653
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
+
15521662 static int generic_pw_cmd(u8 *key, size_t key_len, u8 *cpin_uid,
15531663 struct opal_dev *dev)
15541664 {
1555
- int err = 0;
1665
+ int err;
15561666
1557
- clear_opal_cmd(dev);
1558
- set_comid(dev, dev->comid);
1667
+ err = cmd_start(dev, cpin_uid, opalmethod[OPAL_SET]);
15591668
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);
15651669 add_token_u8(&err, dev, OPAL_STARTNAME);
15661670 add_token_u8(&err, dev, OPAL_VALUES);
15671671 add_token_u8(&err, dev, OPAL_STARTLIST);
15681672 add_token_u8(&err, dev, OPAL_STARTNAME);
1569
- add_token_u8(&err, dev, 3); /* PIN */
1673
+ add_token_u8(&err, dev, OPAL_PIN);
15701674 add_token_bytestring(&err, dev, key, key_len);
15711675 add_token_u8(&err, dev, OPAL_ENDNAME);
15721676 add_token_u8(&err, dev, OPAL_ENDLIST);
15731677 add_token_u8(&err, dev, OPAL_ENDNAME);
1574
- add_token_u8(&err, dev, OPAL_ENDLIST);
15751678
15761679 return err;
15771680 }
....@@ -1619,10 +1722,7 @@
16191722 u8 lr_buffer[OPAL_UID_LENGTH];
16201723 u8 user_uid[OPAL_UID_LENGTH];
16211724 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;
16261726
16271727 memcpy(lr_buffer, opaluid[OPAL_LOCKINGRANGE_ACE_RDLOCKED],
16281728 OPAL_UID_LENGTH);
....@@ -1637,12 +1737,8 @@
16371737
16381738 user_uid[7] = lkul->session.who;
16391739
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]);
16441741
1645
- add_token_u8(&err, dev, OPAL_STARTLIST);
16461742 add_token_u8(&err, dev, OPAL_STARTNAME);
16471743 add_token_u8(&err, dev, OPAL_VALUES);
16481744
....@@ -1680,7 +1776,6 @@
16801776 add_token_u8(&err, dev, OPAL_ENDNAME);
16811777 add_token_u8(&err, dev, OPAL_ENDLIST);
16821778 add_token_u8(&err, dev, OPAL_ENDNAME);
1683
- add_token_u8(&err, dev, OPAL_ENDLIST);
16841779
16851780 if (err) {
16861781 pr_debug("Error building add user to locking range command.\n");
....@@ -1697,9 +1792,6 @@
16971792 u8 read_locked = 1, write_locked = 1;
16981793 int err = 0;
16991794
1700
- clear_opal_cmd(dev);
1701
- set_comid(dev, dev->comid);
1702
-
17031795 if (build_locking_range(lr_buffer, sizeof(lr_buffer),
17041796 lkul->session.opal_key.lr) < 0)
17051797 return -ERANGE;
....@@ -1714,17 +1806,15 @@
17141806 write_locked = 0;
17151807 break;
17161808 case OPAL_LK:
1717
- /* vars are initalized to locked */
1809
+ /* vars are initialized to locked */
17181810 break;
17191811 default:
17201812 pr_debug("Tried to set an invalid locking state... returning to uland\n");
17211813 return OPAL_INVAL_PARAM;
17221814 }
17231815
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
+
17281818 add_token_u8(&err, dev, OPAL_STARTNAME);
17291819 add_token_u8(&err, dev, OPAL_VALUES);
17301820 add_token_u8(&err, dev, OPAL_STARTLIST);
....@@ -1741,12 +1831,12 @@
17411831
17421832 add_token_u8(&err, dev, OPAL_ENDLIST);
17431833 add_token_u8(&err, dev, OPAL_ENDNAME);
1744
- add_token_u8(&err, dev, OPAL_ENDLIST);
17451834
17461835 if (err) {
17471836 pr_debug("Error building SET command.\n");
17481837 return err;
17491838 }
1839
+
17501840 return finalize_and_send(dev, parse_and_check_status);
17511841 }
17521842
....@@ -1775,7 +1865,7 @@
17751865 write_locked = 0;
17761866 break;
17771867 case OPAL_LK:
1778
- /* vars are initalized to locked */
1868
+ /* vars are initialized to locked */
17791869 break;
17801870 default:
17811871 pr_debug("Tried to set an invalid locking state.\n");
....@@ -1788,6 +1878,7 @@
17881878 pr_debug("Error building SET command.\n");
17891879 return ret;
17901880 }
1881
+
17911882 return finalize_and_send(dev, parse_and_check_status);
17921883 }
17931884
....@@ -1795,18 +1886,10 @@
17951886 {
17961887 struct opal_lr_act *opal_act = data;
17971888 u8 user_lr[OPAL_UID_LENGTH];
1798
- u8 uint_3 = 0x83;
1799
- int err = 0, i;
1889
+ int err, i;
18001890
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]);
18101893
18111894 if (opal_act->sum) {
18121895 err = build_locking_range(user_lr, sizeof(user_lr),
....@@ -1814,12 +1897,8 @@
18141897 if (err)
18151898 return err;
18161899
1817
- add_token_u8(&err, dev, OPAL_STARTLIST);
18181900 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);
18231902
18241903 add_token_u8(&err, dev, OPAL_STARTLIST);
18251904 add_token_bytestring(&err, dev, user_lr, OPAL_UID_LENGTH);
....@@ -1829,11 +1908,6 @@
18291908 }
18301909 add_token_u8(&err, dev, OPAL_ENDLIST);
18311910 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);
18371911 }
18381912
18391913 if (err) {
....@@ -1844,17 +1918,19 @@
18441918 return finalize_and_send(dev, parse_and_check_status);
18451919 }
18461920
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)
18481923 {
18491924 u8 lc_status;
1850
- int error = 0;
1925
+ int err;
18511926
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;
18551931
18561932 lc_status = response_get_u64(&dev->parsed, 4);
1857
- /* 0x08 is Manufacured Inactive */
1933
+ /* 0x08 is Manufactured Inactive */
18581934 /* 0x09 is Manufactured */
18591935 if (lc_status != OPAL_MANUFACTURED_INACTIVE) {
18601936 pr_debug("Couldn't determine the status of the Lifecycle state\n");
....@@ -1864,56 +1940,19 @@
18641940 return 0;
18651941 }
18661942
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)
19051944 {
19061945 const char *msid_pin;
19071946 size_t strlen;
1908
- int error = 0;
1947
+ int err;
19091948
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;
19131952
19141953 strlen = response_get_string(&dev->parsed, 4, &msid_pin);
19151954 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");
19171956 return OPAL_INVAL_PARAM;
19181957 }
19191958
....@@ -1926,40 +1965,111 @@
19261965 return 0;
19271966 }
19281967
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)
19301969 {
1931
- int err = 0;
1970
+ struct opal_read_write_table *write_tbl = data;
19321971
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
+}
19351975
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;
19401980
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;
19431984
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
+ }
19481991
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
+}
19531994
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)
19562003
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);
19572014 if (err) {
1958
- pr_debug("Error building Get MSID CPIN PIN command.\n");
2015
+ pr_debug("Couldn't get the table size\n");
19592016 return err;
19602017 }
19612018
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;
19632073 }
19642074
19652075 static int end_opal_session(struct opal_dev *dev, void *data)
....@@ -1972,23 +2082,21 @@
19722082
19732083 if (err < 0)
19742084 return err;
2085
+
19752086 return finalize_and_send(dev, end_session_cont);
19762087 }
19772088
19782089 static int end_opal_session_error(struct opal_dev *dev)
19792090 {
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,
19832093 };
1984
- dev->steps = error_end_session;
1985
- return next(dev);
2094
+
2095
+ return execute_step(dev, &error_end_session, 0);
19862096 }
19872097
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)
19902099 {
1991
- dev->steps = steps;
19922100 dev->tsn = 0;
19932101 dev->hsn = 0;
19942102 dev->prev_data = NULL;
....@@ -1996,17 +2104,14 @@
19962104
19972105 static int check_opal_support(struct opal_dev *dev)
19982106 {
1999
- const struct opal_step steps[] = {
2000
- { opal_discovery0, },
2001
- { NULL, }
2002
- };
20032107 int ret;
20042108
20052109 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);
20082112 dev->supported = !ret;
20092113 mutex_unlock(&dev->dev_lock);
2114
+
20102115 return ret;
20112116 }
20122117
....@@ -2027,7 +2132,10 @@
20272132 {
20282133 if (!dev)
20292134 return;
2135
+
20302136 clean_opal_dev(dev);
2137
+ kfree(dev->resp);
2138
+ kfree(dev->cmd);
20312139 kfree(dev);
20322140 }
20332141 EXPORT_SYMBOL(free_opal_dev);
....@@ -2040,16 +2148,39 @@
20402148 if (!dev)
20412149 return NULL;
20422150
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
+
20432163 INIT_LIST_HEAD(&dev->unlk_lst);
20442164 mutex_init(&dev->dev_lock);
20452165 dev->data = data;
20462166 dev->send_recv = send_recv;
20472167 if (check_opal_support(dev) != 0) {
20482168 pr_debug("Opal is not supported on this device\n");
2049
- kfree(dev);
2050
- return NULL;
2169
+ goto err_free_resp;
20512170 }
2171
+
20522172 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;
20532184 }
20542185 EXPORT_SYMBOL(init_opal_dev);
20552186
....@@ -2057,19 +2188,18 @@
20572188 struct opal_session_info *opal_session)
20582189 {
20592190 const struct opal_step erase_steps[] = {
2060
- { opal_discovery0, },
20612191 { start_auth_opal_session, opal_session },
20622192 { get_active_key, &opal_session->opal_key.lr },
20632193 { gen_key, },
2064
- { end_opal_session, },
2065
- { NULL, }
2194
+ { end_opal_session, }
20662195 };
20672196 int ret;
20682197
20692198 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));
20722201 mutex_unlock(&dev->dev_lock);
2202
+
20732203 return ret;
20742204 }
20752205
....@@ -2077,18 +2207,17 @@
20772207 struct opal_session_info *opal_session)
20782208 {
20792209 const struct opal_step erase_steps[] = {
2080
- { opal_discovery0, },
20812210 { start_auth_opal_session, opal_session },
20822211 { erase_locking_range, opal_session },
2083
- { end_opal_session, },
2084
- { NULL, }
2212
+ { end_opal_session, }
20852213 };
20862214 int ret;
20872215
20882216 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));
20912219 mutex_unlock(&dev->dev_lock);
2220
+
20922221 return ret;
20932222 }
20942223
....@@ -2099,14 +2228,12 @@
20992228 OPAL_TRUE : OPAL_FALSE;
21002229
21012230 const struct opal_step mbr_steps[] = {
2102
- { opal_discovery0, },
21032231 { start_admin1LSP_opal_session, &opal_mbr->key },
21042232 { set_mbr_done, &enable_disable },
21052233 { end_opal_session, },
21062234 { start_admin1LSP_opal_session, &opal_mbr->key },
21072235 { set_mbr_enable_disable, &enable_disable },
2108
- { end_opal_session, },
2109
- { NULL, }
2236
+ { end_opal_session, }
21102237 };
21112238 int ret;
21122239
....@@ -2115,9 +2242,56 @@
21152242 return -EINVAL;
21162243
21172244 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));
21202247 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
+
21212295 return ret;
21222296 }
21232297
....@@ -2133,9 +2307,10 @@
21332307 suspend->lr = lk_unlk->session.opal_key.lr;
21342308
21352309 mutex_lock(&dev->dev_lock);
2136
- setup_opal_dev(dev, NULL);
2310
+ setup_opal_dev(dev);
21372311 add_suspend_info(dev, suspend);
21382312 mutex_unlock(&dev->dev_lock);
2313
+
21392314 return 0;
21402315 }
21412316
....@@ -2143,11 +2318,9 @@
21432318 struct opal_lock_unlock *lk_unlk)
21442319 {
21452320 const struct opal_step steps[] = {
2146
- { opal_discovery0, },
21472321 { start_admin1LSP_opal_session, &lk_unlk->session.opal_key },
21482322 { add_user_to_lr, lk_unlk },
2149
- { end_opal_session, },
2150
- { NULL, }
2323
+ { end_opal_session, }
21512324 };
21522325 int ret;
21532326
....@@ -2156,12 +2329,14 @@
21562329 pr_debug("Locking state was not RO or RW\n");
21572330 return -EINVAL;
21582331 }
2332
+
21592333 if (lk_unlk->session.who < OPAL_USER1 ||
21602334 lk_unlk->session.who > OPAL_USER9) {
21612335 pr_debug("Authority was not within the range of users: %d\n",
21622336 lk_unlk->session.who);
21632337 return -EINVAL;
21642338 }
2339
+
21652340 if (lk_unlk->session.sum) {
21662341 pr_debug("%s not supported in sum. Use setup locking range\n",
21672342 __func__);
....@@ -2169,25 +2344,35 @@
21692344 }
21702345
21712346 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));
21742349 mutex_unlock(&dev->dev_lock);
2350
+
21752351 return ret;
21762352 }
21772353
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)
21792355 {
2356
+ /* controller will terminate session */
21802357 const struct opal_step revert_steps[] = {
2181
- { opal_discovery0, },
21822358 { start_SIDASP_opal_session, opal },
2183
- { revert_tper, }, /* controller will terminate session */
2184
- { NULL, }
2359
+ { revert_tper, }
21852360 };
2361
+ const struct opal_step psid_revert_steps[] = {
2362
+ { start_PSID_opal_session, opal },
2363
+ { revert_tper, }
2364
+ };
2365
+
21862366 int ret;
21872367
21882368 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));
21912376 mutex_unlock(&dev->dev_lock);
21922377
21932378 /*
....@@ -2204,37 +2389,34 @@
22042389 struct opal_lock_unlock *lk_unlk)
22052390 {
22062391 const struct opal_step unlock_steps[] = {
2207
- { opal_discovery0, },
22082392 { start_auth_opal_session, &lk_unlk->session },
22092393 { lock_unlock_locking_range, lk_unlk },
2210
- { end_opal_session, },
2211
- { NULL, }
2394
+ { end_opal_session, }
22122395 };
22132396 const struct opal_step unlock_sum_steps[] = {
2214
- { opal_discovery0, },
22152397 { start_auth_opal_session, &lk_unlk->session },
22162398 { lock_unlock_locking_range_sum, lk_unlk },
2217
- { end_opal_session, },
2218
- { NULL, }
2399
+ { end_opal_session, }
22192400 };
22202401
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));
22232408 }
22242409
22252410 static int __opal_set_mbr_done(struct opal_dev *dev, struct opal_key *key)
22262411 {
22272412 u8 mbr_done_tf = OPAL_TRUE;
2228
- const struct opal_step mbrdone_step [] = {
2229
- { opal_discovery0, },
2413
+ const struct opal_step mbrdone_step[] = {
22302414 { start_admin1LSP_opal_session, key },
22312415 { set_mbr_done, &mbr_done_tf },
2232
- { end_opal_session, },
2233
- { NULL, }
2416
+ { end_opal_session, }
22342417 };
22352418
2236
- dev->steps = mbrdone_step;
2237
- return next(dev);
2419
+ return execute_steps(dev, mbrdone_step, ARRAY_SIZE(mbrdone_step));
22382420 }
22392421
22402422 static int opal_lock_unlock(struct opal_dev *dev,
....@@ -2242,27 +2424,25 @@
22422424 {
22432425 int ret;
22442426
2245
- if (lk_unlk->session.who < OPAL_ADMIN1 ||
2246
- lk_unlk->session.who > OPAL_USER9)
2427
+ if (lk_unlk->session.who > OPAL_USER9)
22472428 return -EINVAL;
22482429
22492430 mutex_lock(&dev->dev_lock);
22502431 ret = __opal_lock_unlock(dev, lk_unlk);
22512432 mutex_unlock(&dev->dev_lock);
2433
+
22522434 return ret;
22532435 }
22542436
22552437 static int opal_take_ownership(struct opal_dev *dev, struct opal_key *opal)
22562438 {
22572439 const struct opal_step owner_steps[] = {
2258
- { opal_discovery0, },
22592440 { start_anybodyASP_opal_session, },
22602441 { get_msid_cpin_pin, },
22612442 { end_opal_session, },
22622443 { start_SIDASP_opal_session, opal },
22632444 { set_sid_cpin_pin, opal },
2264
- { end_opal_session, },
2265
- { NULL, }
2445
+ { end_opal_session, }
22662446 };
22672447 int ret;
22682448
....@@ -2270,21 +2450,21 @@
22702450 return -ENODEV;
22712451
22722452 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));
22752455 mutex_unlock(&dev->dev_lock);
2456
+
22762457 return ret;
22772458 }
22782459
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)
22802462 {
22812463 const struct opal_step active_steps[] = {
2282
- { opal_discovery0, },
22832464 { start_SIDASP_opal_session, &opal_lr_act->key },
22842465 { get_lsp_lifecycle, },
22852466 { activate_lsp, opal_lr_act },
2286
- { end_opal_session, },
2287
- { NULL, }
2467
+ { end_opal_session, }
22882468 };
22892469 int ret;
22902470
....@@ -2292,9 +2472,10 @@
22922472 return -EINVAL;
22932473
22942474 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));
22972477 mutex_unlock(&dev->dev_lock);
2478
+
22982479 return ret;
22992480 }
23002481
....@@ -2302,42 +2483,38 @@
23022483 struct opal_user_lr_setup *opal_lrs)
23032484 {
23042485 const struct opal_step lr_steps[] = {
2305
- { opal_discovery0, },
23062486 { start_auth_opal_session, &opal_lrs->session },
23072487 { setup_locking_range, opal_lrs },
2308
- { end_opal_session, },
2309
- { NULL, }
2488
+ { end_opal_session, }
23102489 };
23112490 int ret;
23122491
23132492 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));
23162495 mutex_unlock(&dev->dev_lock);
2496
+
23172497 return ret;
23182498 }
23192499
23202500 static int opal_set_new_pw(struct opal_dev *dev, struct opal_new_pw *opal_pw)
23212501 {
23222502 const struct opal_step pw_steps[] = {
2323
- { opal_discovery0, },
23242503 { start_auth_opal_session, &opal_pw->session },
23252504 { set_new_pw, &opal_pw->new_user_pw },
2326
- { end_opal_session, },
2327
- { NULL }
2505
+ { end_opal_session, }
23282506 };
23292507 int ret;
23302508
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 ||
23342510 opal_pw->new_user_pw.who > OPAL_USER9)
23352511 return -EINVAL;
23362512
23372513 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));
23402516 mutex_unlock(&dev->dev_lock);
2517
+
23412518 return ret;
23422519 }
23432520
....@@ -2345,11 +2522,9 @@
23452522 struct opal_session_info *opal_session)
23462523 {
23472524 const struct opal_step act_steps[] = {
2348
- { opal_discovery0, },
23492525 { start_admin1LSP_opal_session, &opal_session->opal_key },
23502526 { internal_activate_user, opal_session },
2351
- { end_opal_session, },
2352
- { NULL, }
2527
+ { end_opal_session, }
23532528 };
23542529 int ret;
23552530
....@@ -2361,9 +2536,10 @@
23612536 }
23622537
23632538 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));
23662541 mutex_unlock(&dev->dev_lock);
2542
+
23672543 return ret;
23682544 }
23692545
....@@ -2375,11 +2551,12 @@
23752551
23762552 if (!dev)
23772553 return false;
2554
+
23782555 if (!dev->supported)
23792556 return false;
23802557
23812558 mutex_lock(&dev->dev_lock);
2382
- setup_opal_dev(dev, NULL);
2559
+ setup_opal_dev(dev);
23832560
23842561 list_for_each_entry(suspend, &dev->unlk_lst, node) {
23852562 dev->tsn = 0;
....@@ -2392,6 +2569,7 @@
23922569 suspend->unlk.session.sum);
23932570 was_failure = true;
23942571 }
2572
+
23952573 if (dev->mbr_enabled) {
23962574 ret = __opal_set_mbr_done(dev, &suspend->unlk.session.opal_key);
23972575 if (ret)
....@@ -2399,9 +2577,72 @@
23992577 }
24002578 }
24012579 mutex_unlock(&dev->dev_lock);
2580
+
24022581 return was_failure;
24032582 }
24042583 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
+}
24052646
24062647 int sed_ioctl(struct opal_dev *dev, unsigned int cmd, void __user *arg)
24072648 {
....@@ -2439,7 +2680,7 @@
24392680 ret = opal_activate_user(dev, p);
24402681 break;
24412682 case IOC_OPAL_REVERT_TPR:
2442
- ret = opal_reverttper(dev, p);
2683
+ ret = opal_reverttper(dev, p, false);
24432684 break;
24442685 case IOC_OPAL_LR_SETUP:
24452686 ret = opal_setup_locking_range(dev, p);
....@@ -2450,12 +2691,24 @@
24502691 case IOC_OPAL_ENABLE_DISABLE_MBR:
24512692 ret = opal_enable_disable_shadow_mbr(dev, p);
24522693 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;
24532700 case IOC_OPAL_ERASE_LR:
24542701 ret = opal_erase_locking_range(dev, p);
24552702 break;
24562703 case IOC_OPAL_SECURE_ERASE_LR:
24572704 ret = opal_secure_erase_locking_range(dev, p);
24582705 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;
24592712 default:
24602713 break;
24612714 }