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