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