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