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