block: sed-opal: fix typos and formatting
[linux-block.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 */
184static const u8 opalmethod[][OPAL_UID_LENGTH] = {
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
513static void add_token_u8(int *err, struct opal_dev *cmd, u8 tok)
514{
515 if (*err)
516 return;
517 if (cmd->pos >= IO_BUFFER_LENGTH - 1) {
591c59d1 518 pr_debug("Error adding u8: end of buffer.\n");
455a7b23
SB
519 *err = -ERANGE;
520 return;
521 }
522 cmd->cmd[cmd->pos++] = tok;
523}
524
525static void add_short_atom_header(struct opal_dev *cmd, bool bytestring,
526 bool has_sign, int len)
527{
528 u8 atom;
529 int err = 0;
530
531 atom = SHORT_ATOM_ID;
532 atom |= bytestring ? SHORT_ATOM_BYTESTRING : 0;
533 atom |= has_sign ? SHORT_ATOM_SIGNED : 0;
534 atom |= len & SHORT_ATOM_LEN_MASK;
535
536 add_token_u8(&err, cmd, atom);
537}
538
539static void add_medium_atom_header(struct opal_dev *cmd, bool bytestring,
540 bool has_sign, int len)
541{
542 u8 header0;
543
544 header0 = MEDIUM_ATOM_ID;
545 header0 |= bytestring ? MEDIUM_ATOM_BYTESTRING : 0;
546 header0 |= has_sign ? MEDIUM_ATOM_SIGNED : 0;
547 header0 |= (len >> 8) & MEDIUM_ATOM_LEN_MASK;
548 cmd->cmd[cmd->pos++] = header0;
549 cmd->cmd[cmd->pos++] = len;
550}
551
552static void add_token_u64(int *err, struct opal_dev *cmd, u64 number)
553{
455a7b23
SB
554 size_t len;
555 int msb;
455a7b23
SB
556
557 if (!(number & ~TINY_ATOM_DATA_MASK)) {
558 add_token_u8(err, cmd, number);
559 return;
560 }
561
5f990d31
JR
562 msb = fls64(number);
563 len = DIV_ROUND_UP(msb, 8);
455a7b23
SB
564
565 if (cmd->pos >= IO_BUFFER_LENGTH - len - 1) {
591c59d1 566 pr_debug("Error adding u64: end of buffer.\n");
455a7b23
SB
567 *err = -ERANGE;
568 return;
569 }
570 add_short_atom_header(cmd, false, false, len);
5f990d31
JR
571 while (len--)
572 add_token_u8(err, cmd, number >> (len * 8));
455a7b23
SB
573}
574
575static void add_token_bytestring(int *err, struct opal_dev *cmd,
576 const u8 *bytestring, size_t len)
577{
578 size_t header_len = 1;
579 bool is_short_atom = true;
580
581 if (*err)
582 return;
583
584 if (len & ~SHORT_ATOM_LEN_MASK) {
585 header_len = 2;
586 is_short_atom = false;
587 }
588
589 if (len >= IO_BUFFER_LENGTH - cmd->pos - header_len) {
591c59d1 590 pr_debug("Error adding bytestring: end of buffer.\n");
455a7b23
SB
591 *err = -ERANGE;
592 return;
593 }
594
595 if (is_short_atom)
596 add_short_atom_header(cmd, true, false, len);
597 else
598 add_medium_atom_header(cmd, true, false, len);
599
600 memcpy(&cmd->cmd[cmd->pos], bytestring, len);
601 cmd->pos += len;
602
603}
604
605static int build_locking_range(u8 *buffer, size_t length, u8 lr)
606{
607 if (length > OPAL_UID_LENGTH) {
591c59d1 608 pr_debug("Can't build locking range. Length OOB\n");
455a7b23
SB
609 return -ERANGE;
610 }
611
612 memcpy(buffer, opaluid[OPAL_LOCKINGRANGE_GLOBAL], OPAL_UID_LENGTH);
613
614 if (lr == 0)
615 return 0;
616 buffer[5] = LOCKING_RANGE_NON_GLOBAL;
617 buffer[7] = lr;
618
619 return 0;
620}
621
622static int build_locking_user(u8 *buffer, size_t length, u8 lr)
623{
624 if (length > OPAL_UID_LENGTH) {
1e815b33 625 pr_debug("Can't build locking range user. Length OOB\n");
455a7b23
SB
626 return -ERANGE;
627 }
628
629 memcpy(buffer, opaluid[OPAL_USER1_UID], OPAL_UID_LENGTH);
630
631 buffer[7] = lr + 1;
632
633 return 0;
634}
635
636static void set_comid(struct opal_dev *cmd, u16 comid)
637{
638 struct opal_header *hdr = (struct opal_header *)cmd->cmd;
639
640 hdr->cp.extendedComID[0] = comid >> 8;
641 hdr->cp.extendedComID[1] = comid;
642 hdr->cp.extendedComID[2] = 0;
643 hdr->cp.extendedComID[3] = 0;
644}
645
646static int cmd_finalize(struct opal_dev *cmd, u32 hsn, u32 tsn)
647{
648 struct opal_header *hdr;
649 int err = 0;
650
651 add_token_u8(&err, cmd, OPAL_ENDOFDATA);
652 add_token_u8(&err, cmd, OPAL_STARTLIST);
653 add_token_u8(&err, cmd, 0);
654 add_token_u8(&err, cmd, 0);
655 add_token_u8(&err, cmd, 0);
656 add_token_u8(&err, cmd, OPAL_ENDLIST);
657
658 if (err) {
591c59d1 659 pr_debug("Error finalizing command.\n");
455a7b23
SB
660 return -EFAULT;
661 }
662
663 hdr = (struct opal_header *) cmd->cmd;
664
665 hdr->pkt.tsn = cpu_to_be32(tsn);
666 hdr->pkt.hsn = cpu_to_be32(hsn);
667
668 hdr->subpkt.length = cpu_to_be32(cmd->pos - sizeof(*hdr));
669 while (cmd->pos % 4) {
670 if (cmd->pos >= IO_BUFFER_LENGTH) {
591c59d1 671 pr_debug("Error: Buffer overrun\n");
455a7b23
SB
672 return -ERANGE;
673 }
674 cmd->cmd[cmd->pos++] = 0;
675 }
676 hdr->pkt.length = cpu_to_be32(cmd->pos - sizeof(hdr->cp) -
677 sizeof(hdr->pkt));
678 hdr->cp.length = cpu_to_be32(cmd->pos - sizeof(hdr->cp));
679
680 return 0;
681}
682
cccb9241
JD
683static const struct opal_resp_tok *response_get_token(
684 const struct parsed_resp *resp,
685 int n)
455a7b23
SB
686{
687 const struct opal_resp_tok *tok;
688
689 if (n >= resp->num) {
591c59d1
SB
690 pr_debug("Token number doesn't exist: %d, resp: %d\n",
691 n, resp->num);
cccb9241 692 return ERR_PTR(-EINVAL);
455a7b23
SB
693 }
694
695 tok = &resp->toks[n];
696 if (tok->len == 0) {
591c59d1 697 pr_debug("Token length must be non-zero\n");
cccb9241 698 return ERR_PTR(-EINVAL);
455a7b23
SB
699 }
700
cccb9241 701 return tok;
455a7b23
SB
702}
703
aedb6e24
JD
704static ssize_t response_parse_tiny(struct opal_resp_tok *tok,
705 const u8 *pos)
455a7b23
SB
706{
707 tok->pos = pos;
708 tok->len = 1;
709 tok->width = OPAL_WIDTH_TINY;
710
711 if (pos[0] & TINY_ATOM_SIGNED) {
712 tok->type = OPAL_DTA_TOKENID_SINT;
713 } else {
714 tok->type = OPAL_DTA_TOKENID_UINT;
715 tok->stored.u = pos[0] & 0x3f;
716 }
717
718 return tok->len;
719}
720
aedb6e24
JD
721static ssize_t response_parse_short(struct opal_resp_tok *tok,
722 const u8 *pos)
455a7b23
SB
723{
724 tok->pos = pos;
725 tok->len = (pos[0] & SHORT_ATOM_LEN_MASK) + 1;
726 tok->width = OPAL_WIDTH_SHORT;
727
728 if (pos[0] & SHORT_ATOM_BYTESTRING) {
729 tok->type = OPAL_DTA_TOKENID_BYTESTRING;
730 } else if (pos[0] & SHORT_ATOM_SIGNED) {
731 tok->type = OPAL_DTA_TOKENID_SINT;
732 } else {
733 u64 u_integer = 0;
aedb6e24 734 ssize_t i, b = 0;
455a7b23
SB
735
736 tok->type = OPAL_DTA_TOKENID_UINT;
737 if (tok->len > 9) {
591c59d1 738 pr_debug("uint64 with more than 8 bytes\n");
455a7b23
SB
739 return -EINVAL;
740 }
741 for (i = tok->len - 1; i > 0; i--) {
742 u_integer |= ((u64)pos[i] << (8 * b));
743 b++;
744 }
745 tok->stored.u = u_integer;
746 }
747
748 return tok->len;
749}
750
aedb6e24
JD
751static ssize_t response_parse_medium(struct opal_resp_tok *tok,
752 const u8 *pos)
455a7b23
SB
753{
754 tok->pos = pos;
755 tok->len = (((pos[0] & MEDIUM_ATOM_LEN_MASK) << 8) | pos[1]) + 2;
756 tok->width = OPAL_WIDTH_MEDIUM;
757
758 if (pos[0] & MEDIUM_ATOM_BYTESTRING)
759 tok->type = OPAL_DTA_TOKENID_BYTESTRING;
760 else if (pos[0] & MEDIUM_ATOM_SIGNED)
761 tok->type = OPAL_DTA_TOKENID_SINT;
762 else
763 tok->type = OPAL_DTA_TOKENID_UINT;
764
765 return tok->len;
766}
767
aedb6e24
JD
768static ssize_t response_parse_long(struct opal_resp_tok *tok,
769 const u8 *pos)
455a7b23
SB
770{
771 tok->pos = pos;
772 tok->len = ((pos[1] << 16) | (pos[2] << 8) | pos[3]) + 4;
773 tok->width = OPAL_WIDTH_LONG;
774
775 if (pos[0] & LONG_ATOM_BYTESTRING)
776 tok->type = OPAL_DTA_TOKENID_BYTESTRING;
777 else if (pos[0] & LONG_ATOM_SIGNED)
778 tok->type = OPAL_DTA_TOKENID_SINT;
779 else
780 tok->type = OPAL_DTA_TOKENID_UINT;
781
782 return tok->len;
783}
784
aedb6e24
JD
785static ssize_t response_parse_token(struct opal_resp_tok *tok,
786 const u8 *pos)
455a7b23
SB
787{
788 tok->pos = pos;
789 tok->len = 1;
790 tok->type = OPAL_DTA_TOKENID_TOKEN;
791 tok->width = OPAL_WIDTH_TOKEN;
792
793 return tok->len;
794}
795
796static int response_parse(const u8 *buf, size_t length,
797 struct parsed_resp *resp)
798{
799 const struct opal_header *hdr;
800 struct opal_resp_tok *iter;
801 int num_entries = 0;
802 int total;
aedb6e24 803 ssize_t token_length;
455a7b23 804 const u8 *pos;
77039b96 805 u32 clen, plen, slen;
455a7b23
SB
806
807 if (!buf)
808 return -EFAULT;
809
810 if (!resp)
811 return -EFAULT;
812
813 hdr = (struct opal_header *)buf;
814 pos = buf;
815 pos += sizeof(*hdr);
816
77039b96
JD
817 clen = be32_to_cpu(hdr->cp.length);
818 plen = be32_to_cpu(hdr->pkt.length);
819 slen = be32_to_cpu(hdr->subpkt.length);
820 pr_debug("Response size: cp: %u, pkt: %u, subpkt: %u\n",
821 clen, plen, slen);
822
823 if (clen == 0 || plen == 0 || slen == 0 ||
824 slen > IO_BUFFER_LENGTH - sizeof(*hdr)) {
591c59d1
SB
825 pr_debug("Bad header length. cp: %u, pkt: %u, subpkt: %u\n",
826 clen, plen, slen);
455a7b23
SB
827 print_buffer(pos, sizeof(*hdr));
828 return -EINVAL;
829 }
830
831 if (pos > buf + length)
832 return -EFAULT;
833
834 iter = resp->toks;
77039b96 835 total = slen;
455a7b23
SB
836 print_buffer(pos, total);
837 while (total > 0) {
838 if (pos[0] <= TINY_ATOM_BYTE) /* tiny atom */
839 token_length = response_parse_tiny(iter, pos);
840 else if (pos[0] <= SHORT_ATOM_BYTE) /* short atom */
841 token_length = response_parse_short(iter, pos);
842 else if (pos[0] <= MEDIUM_ATOM_BYTE) /* medium atom */
843 token_length = response_parse_medium(iter, pos);
844 else if (pos[0] <= LONG_ATOM_BYTE) /* long atom */
845 token_length = response_parse_long(iter, pos);
846 else /* TOKEN */
847 token_length = response_parse_token(iter, pos);
848
aedb6e24
JD
849 if (token_length < 0)
850 return token_length;
455a7b23
SB
851
852 pos += token_length;
853 total -= token_length;
854 iter++;
855 num_entries++;
856 }
857
858 if (num_entries == 0) {
591c59d1 859 pr_debug("Couldn't parse response.\n");
455a7b23
SB
860 return -EINVAL;
861 }
862 resp->num = num_entries;
863
864 return 0;
865}
866
867static size_t response_get_string(const struct parsed_resp *resp, int n,
868 const char **store)
869{
d15e1175
JR
870 u8 skip;
871 const struct opal_resp_tok *token;
872
455a7b23
SB
873 *store = NULL;
874 if (!resp) {
591c59d1 875 pr_debug("Response is NULL\n");
455a7b23
SB
876 return 0;
877 }
878
ce042c18 879 if (n >= resp->num) {
591c59d1
SB
880 pr_debug("Response has %d tokens. Can't access %d\n",
881 resp->num, n);
455a7b23
SB
882 return 0;
883 }
884
d15e1175
JR
885 token = &resp->toks[n];
886 if (token->type != OPAL_DTA_TOKENID_BYTESTRING) {
591c59d1 887 pr_debug("Token is not a byte string!\n");
455a7b23
SB
888 return 0;
889 }
890
d15e1175
JR
891 switch (token->width) {
892 case OPAL_WIDTH_TINY:
893 case OPAL_WIDTH_SHORT:
894 skip = 1;
895 break;
896 case OPAL_WIDTH_MEDIUM:
897 skip = 2;
898 break;
899 case OPAL_WIDTH_LONG:
900 skip = 4;
901 break;
902 default:
903 pr_debug("Token has invalid width!\n");
904 return 0;
905 }
906
907 *store = token->pos + skip;
908 return token->len - skip;
455a7b23
SB
909}
910
911static u64 response_get_u64(const struct parsed_resp *resp, int n)
912{
913 if (!resp) {
591c59d1 914 pr_debug("Response is NULL\n");
455a7b23
SB
915 return 0;
916 }
917
ce042c18 918 if (n >= resp->num) {
591c59d1
SB
919 pr_debug("Response has %d tokens. Can't access %d\n",
920 resp->num, n);
455a7b23
SB
921 return 0;
922 }
923
924 if (resp->toks[n].type != OPAL_DTA_TOKENID_UINT) {
591c59d1
SB
925 pr_debug("Token is not unsigned it: %d\n",
926 resp->toks[n].type);
455a7b23
SB
927 return 0;
928 }
929
930 if (!(resp->toks[n].width == OPAL_WIDTH_TINY ||
931 resp->toks[n].width == OPAL_WIDTH_SHORT)) {
591c59d1
SB
932 pr_debug("Atom is not short or tiny: %d\n",
933 resp->toks[n].width);
455a7b23
SB
934 return 0;
935 }
936
937 return resp->toks[n].stored.u;
938}
939
cccb9241
JD
940static bool response_token_matches(const struct opal_resp_tok *token, u8 match)
941{
942 if (IS_ERR(token) ||
943 token->type != OPAL_DTA_TOKENID_TOKEN ||
944 token->pos[0] != match)
945 return false;
946 return true;
947}
948
455a7b23
SB
949static u8 response_status(const struct parsed_resp *resp)
950{
cccb9241
JD
951 const struct opal_resp_tok *tok;
952
953 tok = response_get_token(resp, 0);
954 if (response_token_matches(tok, OPAL_ENDOFSESSION))
455a7b23 955 return 0;
455a7b23
SB
956
957 if (resp->num < 5)
958 return DTAERROR_NO_METHOD_STATUS;
959
cccb9241
JD
960 tok = response_get_token(resp, resp->num - 5);
961 if (!response_token_matches(tok, OPAL_STARTLIST))
962 return DTAERROR_NO_METHOD_STATUS;
963
964 tok = response_get_token(resp, resp->num - 1);
965 if (!response_token_matches(tok, OPAL_ENDLIST))
455a7b23
SB
966 return DTAERROR_NO_METHOD_STATUS;
967
968 return response_get_u64(resp, resp->num - 4);
969}
970
971/* Parses and checks for errors */
972static int parse_and_check_status(struct opal_dev *dev)
973{
974 int error;
975
976 print_buffer(dev->cmd, dev->pos);
977
978 error = response_parse(dev->resp, IO_BUFFER_LENGTH, &dev->parsed);
979 if (error) {
591c59d1 980 pr_debug("Couldn't parse response.\n");
455a7b23
SB
981 return error;
982 }
983
984 return response_status(&dev->parsed);
985}
986
987static void clear_opal_cmd(struct opal_dev *dev)
988{
989 dev->pos = sizeof(struct opal_header);
990 memset(dev->cmd, 0, IO_BUFFER_LENGTH);
991}
992
993static int start_opal_session_cont(struct opal_dev *dev)
994{
995 u32 hsn, tsn;
996 int error = 0;
997
998 error = parse_and_check_status(dev);
999 if (error)
1000 return error;
1001
1002 hsn = response_get_u64(&dev->parsed, 4);
1003 tsn = response_get_u64(&dev->parsed, 5);
1004
1005 if (hsn == 0 && tsn == 0) {
591c59d1 1006 pr_debug("Couldn't authenticate session\n");
455a7b23
SB
1007 return -EPERM;
1008 }
1009
1010 dev->hsn = hsn;
1011 dev->tsn = tsn;
1012 return 0;
1013}
1014
1015static void add_suspend_info(struct opal_dev *dev,
1016 struct opal_suspend_data *sus)
1017{
1018 struct opal_suspend_data *iter;
1019
1020 list_for_each_entry(iter, &dev->unlk_lst, node) {
1021 if (iter->lr == sus->lr) {
1022 list_del(&iter->node);
1023 kfree(iter);
1024 break;
1025 }
1026 }
1027 list_add_tail(&sus->node, &dev->unlk_lst);
1028}
1029
1030static int end_session_cont(struct opal_dev *dev)
1031{
1032 dev->hsn = 0;
1033 dev->tsn = 0;
1034 return parse_and_check_status(dev);
1035}
1036
1037static int finalize_and_send(struct opal_dev *dev, cont_fn cont)
1038{
1039 int ret;
1040
1041 ret = cmd_finalize(dev, dev->hsn, dev->tsn);
1042 if (ret) {
591c59d1 1043 pr_debug("Error finalizing command buffer: %d\n", ret);
455a7b23
SB
1044 return ret;
1045 }
1046
1047 print_buffer(dev->cmd, dev->pos);
1048
1049 return opal_send_recv(dev, cont);
1050}
1051
eed64951 1052static int gen_key(struct opal_dev *dev, void *data)
455a7b23 1053{
455a7b23
SB
1054 u8 uid[OPAL_UID_LENGTH];
1055 int err = 0;
1056
1057 clear_opal_cmd(dev);
1058 set_comid(dev, dev->comid);
1059
1060 memcpy(uid, dev->prev_data, min(sizeof(uid), dev->prev_d_len));
455a7b23
SB
1061 kfree(dev->prev_data);
1062 dev->prev_data = NULL;
1063
1064 add_token_u8(&err, dev, OPAL_CALL);
1065 add_token_bytestring(&err, dev, uid, OPAL_UID_LENGTH);
1066 add_token_bytestring(&err, dev, opalmethod[OPAL_GENKEY],
1067 OPAL_UID_LENGTH);
1068 add_token_u8(&err, dev, OPAL_STARTLIST);
1069 add_token_u8(&err, dev, OPAL_ENDLIST);
1070
1071 if (err) {
591c59d1 1072 pr_debug("Error building gen key command\n");
455a7b23
SB
1073 return err;
1074
1075 }
1076 return finalize_and_send(dev, parse_and_check_status);
1077}
1078
1079static int get_active_key_cont(struct opal_dev *dev)
1080{
1081 const char *activekey;
1082 size_t keylen;
1083 int error = 0;
1084
1085 error = parse_and_check_status(dev);
1086 if (error)
1087 return error;
1088 keylen = response_get_string(&dev->parsed, 4, &activekey);
1089 if (!activekey) {
591c59d1
SB
1090 pr_debug("%s: Couldn't extract the Activekey from the response\n",
1091 __func__);
455a7b23
SB
1092 return OPAL_INVAL_PARAM;
1093 }
1094 dev->prev_data = kmemdup(activekey, keylen, GFP_KERNEL);
1095
1096 if (!dev->prev_data)
1097 return -ENOMEM;
1098
1099 dev->prev_d_len = keylen;
1100
1101 return 0;
1102}
1103
eed64951 1104static int get_active_key(struct opal_dev *dev, void *data)
455a7b23
SB
1105{
1106 u8 uid[OPAL_UID_LENGTH];
1107 int err = 0;
eed64951 1108 u8 *lr = data;
455a7b23
SB
1109
1110 clear_opal_cmd(dev);
1111 set_comid(dev, dev->comid);
455a7b23
SB
1112
1113 err = build_locking_range(uid, sizeof(uid), *lr);
1114 if (err)
1115 return err;
1116
1117 err = 0;
1118 add_token_u8(&err, dev, OPAL_CALL);
1119 add_token_bytestring(&err, dev, uid, OPAL_UID_LENGTH);
1120 add_token_bytestring(&err, dev, opalmethod[OPAL_GET], OPAL_UID_LENGTH);
1121 add_token_u8(&err, dev, OPAL_STARTLIST);
1122 add_token_u8(&err, dev, OPAL_STARTLIST);
1123 add_token_u8(&err, dev, OPAL_STARTNAME);
1124 add_token_u8(&err, dev, 3); /* startCloumn */
1125 add_token_u8(&err, dev, 10); /* ActiveKey */
1126 add_token_u8(&err, dev, OPAL_ENDNAME);
1127 add_token_u8(&err, dev, OPAL_STARTNAME);
1128 add_token_u8(&err, dev, 4); /* endColumn */
1129 add_token_u8(&err, dev, 10); /* ActiveKey */
1130 add_token_u8(&err, dev, OPAL_ENDNAME);
1131 add_token_u8(&err, dev, OPAL_ENDLIST);
1132 add_token_u8(&err, dev, OPAL_ENDLIST);
1133 if (err) {
591c59d1 1134 pr_debug("Error building get active key command\n");
455a7b23
SB
1135 return err;
1136 }
1137
1138 return finalize_and_send(dev, get_active_key_cont);
1139}
1140
1141static int generic_lr_enable_disable(struct opal_dev *dev,
1142 u8 *uid, bool rle, bool wle,
1143 bool rl, bool wl)
1144{
1145 int err = 0;
1146
1147 add_token_u8(&err, dev, OPAL_CALL);
1148 add_token_bytestring(&err, dev, uid, OPAL_UID_LENGTH);
1149 add_token_bytestring(&err, dev, opalmethod[OPAL_SET], OPAL_UID_LENGTH);
1150
1151 add_token_u8(&err, dev, OPAL_STARTLIST);
1152 add_token_u8(&err, dev, OPAL_STARTNAME);
1153 add_token_u8(&err, dev, OPAL_VALUES);
1154 add_token_u8(&err, dev, OPAL_STARTLIST);
1155
1156 add_token_u8(&err, dev, OPAL_STARTNAME);
1157 add_token_u8(&err, dev, 5); /* ReadLockEnabled */
1158 add_token_u8(&err, dev, rle);
1159 add_token_u8(&err, dev, OPAL_ENDNAME);
1160
1161 add_token_u8(&err, dev, OPAL_STARTNAME);
1162 add_token_u8(&err, dev, 6); /* WriteLockEnabled */
1163 add_token_u8(&err, dev, wle);
1164 add_token_u8(&err, dev, OPAL_ENDNAME);
1165
1166 add_token_u8(&err, dev, OPAL_STARTNAME);
1167 add_token_u8(&err, dev, OPAL_READLOCKED);
1168 add_token_u8(&err, dev, rl);
1169 add_token_u8(&err, dev, OPAL_ENDNAME);
1170
1171 add_token_u8(&err, dev, OPAL_STARTNAME);
1172 add_token_u8(&err, dev, OPAL_WRITELOCKED);
1173 add_token_u8(&err, dev, wl);
1174 add_token_u8(&err, dev, OPAL_ENDNAME);
1175
1176 add_token_u8(&err, dev, OPAL_ENDLIST);
1177 add_token_u8(&err, dev, OPAL_ENDNAME);
1178 add_token_u8(&err, dev, OPAL_ENDLIST);
1179 return err;
1180}
1181
1182static inline int enable_global_lr(struct opal_dev *dev, u8 *uid,
1183 struct opal_user_lr_setup *setup)
1184{
1185 int err;
1186
1187 err = generic_lr_enable_disable(dev, uid, !!setup->RLE, !!setup->WLE,
1188 0, 0);
1189 if (err)
591c59d1 1190 pr_debug("Failed to create enable global lr command\n");
455a7b23
SB
1191 return err;
1192}
1193
eed64951 1194static int setup_locking_range(struct opal_dev *dev, void *data)
455a7b23
SB
1195{
1196 u8 uid[OPAL_UID_LENGTH];
eed64951 1197 struct opal_user_lr_setup *setup = data;
455a7b23
SB
1198 u8 lr;
1199 int err = 0;
1200
1201 clear_opal_cmd(dev);
1202 set_comid(dev, dev->comid);
1203
455a7b23
SB
1204 lr = setup->session.opal_key.lr;
1205 err = build_locking_range(uid, sizeof(uid), lr);
1206 if (err)
1207 return err;
1208
1209 if (lr == 0)
1210 err = enable_global_lr(dev, uid, setup);
1211 else {
1212 add_token_u8(&err, dev, OPAL_CALL);
1213 add_token_bytestring(&err, dev, uid, OPAL_UID_LENGTH);
1214 add_token_bytestring(&err, dev, opalmethod[OPAL_SET],
1215 OPAL_UID_LENGTH);
1216
1217 add_token_u8(&err, dev, OPAL_STARTLIST);
1218 add_token_u8(&err, dev, OPAL_STARTNAME);
1219 add_token_u8(&err, dev, OPAL_VALUES);
1220 add_token_u8(&err, dev, OPAL_STARTLIST);
1221
1222 add_token_u8(&err, dev, OPAL_STARTNAME);
1223 add_token_u8(&err, dev, 3); /* Ranges Start */
1224 add_token_u64(&err, dev, setup->range_start);
1225 add_token_u8(&err, dev, OPAL_ENDNAME);
1226
1227 add_token_u8(&err, dev, OPAL_STARTNAME);
1228 add_token_u8(&err, dev, 4); /* Ranges length */
1229 add_token_u64(&err, dev, setup->range_length);
1230 add_token_u8(&err, dev, OPAL_ENDNAME);
1231
1232 add_token_u8(&err, dev, OPAL_STARTNAME);
1233 add_token_u8(&err, dev, 5); /*ReadLockEnabled */
1234 add_token_u64(&err, dev, !!setup->RLE);
1235 add_token_u8(&err, dev, OPAL_ENDNAME);
1236
1237 add_token_u8(&err, dev, OPAL_STARTNAME);
1238 add_token_u8(&err, dev, 6); /*WriteLockEnabled*/
1239 add_token_u64(&err, dev, !!setup->WLE);
1240 add_token_u8(&err, dev, OPAL_ENDNAME);
1241
1242 add_token_u8(&err, dev, OPAL_ENDLIST);
1243 add_token_u8(&err, dev, OPAL_ENDNAME);
1244 add_token_u8(&err, dev, OPAL_ENDLIST);
1245
1246 }
1247 if (err) {
591c59d1 1248 pr_debug("Error building Setup Locking range command.\n");
455a7b23
SB
1249 return err;
1250
1251 }
1252
1253 return finalize_and_send(dev, parse_and_check_status);
1254}
1255
1256static int start_generic_opal_session(struct opal_dev *dev,
1257 enum opal_uid auth,
1258 enum opal_uid sp_type,
1259 const char *key,
1260 u8 key_len)
1261{
1262 u32 hsn;
1263 int err = 0;
1264
591c59d1 1265 if (key == NULL && auth != OPAL_ANYBODY_UID)
455a7b23 1266 return OPAL_INVAL_PARAM;
455a7b23
SB
1267
1268 clear_opal_cmd(dev);
1269
1270 set_comid(dev, dev->comid);
1271 hsn = GENERIC_HOST_SESSION_NUM;
1272
1273 add_token_u8(&err, dev, OPAL_CALL);
1274 add_token_bytestring(&err, dev, opaluid[OPAL_SMUID_UID],
1275 OPAL_UID_LENGTH);
1276 add_token_bytestring(&err, dev, opalmethod[OPAL_STARTSESSION],
1277 OPAL_UID_LENGTH);
1278 add_token_u8(&err, dev, OPAL_STARTLIST);
1279 add_token_u64(&err, dev, hsn);
1280 add_token_bytestring(&err, dev, opaluid[sp_type], OPAL_UID_LENGTH);
1281 add_token_u8(&err, dev, 1);
1282
1283 switch (auth) {
1284 case OPAL_ANYBODY_UID:
1285 add_token_u8(&err, dev, OPAL_ENDLIST);
1286 break;
1287 case OPAL_ADMIN1_UID:
1288 case OPAL_SID_UID:
1289 add_token_u8(&err, dev, OPAL_STARTNAME);
1290 add_token_u8(&err, dev, 0); /* HostChallenge */
1291 add_token_bytestring(&err, dev, key, key_len);
1292 add_token_u8(&err, dev, OPAL_ENDNAME);
1293 add_token_u8(&err, dev, OPAL_STARTNAME);
1294 add_token_u8(&err, dev, 3); /* HostSignAuth */
1295 add_token_bytestring(&err, dev, opaluid[auth],
1296 OPAL_UID_LENGTH);
1297 add_token_u8(&err, dev, OPAL_ENDNAME);
1298 add_token_u8(&err, dev, OPAL_ENDLIST);
1299 break;
1300 default:
591c59d1 1301 pr_debug("Cannot start Admin SP session with auth %d\n", auth);
455a7b23
SB
1302 return OPAL_INVAL_PARAM;
1303 }
1304
1305 if (err) {
591c59d1 1306 pr_debug("Error building start adminsp session command.\n");
455a7b23
SB
1307 return err;
1308 }
1309
1310 return finalize_and_send(dev, start_opal_session_cont);
1311}
1312
eed64951 1313static int start_anybodyASP_opal_session(struct opal_dev *dev, void *data)
455a7b23
SB
1314{
1315 return start_generic_opal_session(dev, OPAL_ANYBODY_UID,
1316 OPAL_ADMINSP_UID, NULL, 0);
1317}
1318
eed64951 1319static int start_SIDASP_opal_session(struct opal_dev *dev, void *data)
455a7b23
SB
1320{
1321 int ret;
1322 const u8 *key = dev->prev_data;
455a7b23
SB
1323
1324 if (!key) {
eed64951 1325 const struct opal_key *okey = data;
1e815b33 1326
455a7b23
SB
1327 ret = start_generic_opal_session(dev, OPAL_SID_UID,
1328 OPAL_ADMINSP_UID,
1329 okey->key,
1330 okey->key_len);
1331 } else {
1332 ret = start_generic_opal_session(dev, OPAL_SID_UID,
1333 OPAL_ADMINSP_UID,
1334 key, dev->prev_d_len);
1335 kfree(key);
1336 dev->prev_data = NULL;
1337 }
1338 return ret;
1339}
1340
eed64951 1341static int start_admin1LSP_opal_session(struct opal_dev *dev, void *data)
455a7b23 1342{
eed64951 1343 struct opal_key *key = data;
1e815b33 1344
455a7b23
SB
1345 return start_generic_opal_session(dev, OPAL_ADMIN1_UID,
1346 OPAL_LOCKINGSP_UID,
1347 key->key, key->key_len);
1348}
1349
eed64951 1350static int start_auth_opal_session(struct opal_dev *dev, void *data)
455a7b23 1351{
eed64951 1352 struct opal_session_info *session = data;
455a7b23 1353 u8 lk_ul_user[OPAL_UID_LENGTH];
eed64951 1354 size_t keylen = session->opal_key.key_len;
455a7b23
SB
1355 int err = 0;
1356
455a7b23
SB
1357 u8 *key = session->opal_key.key;
1358 u32 hsn = GENERIC_HOST_SESSION_NUM;
1359
1360 clear_opal_cmd(dev);
1361 set_comid(dev, dev->comid);
1362
1363 if (session->sum) {
1364 err = build_locking_user(lk_ul_user, sizeof(lk_ul_user),
1365 session->opal_key.lr);
1366 if (err)
1367 return err;
1368
1369 } else if (session->who != OPAL_ADMIN1 && !session->sum) {
1370 err = build_locking_user(lk_ul_user, sizeof(lk_ul_user),
1371 session->who - 1);
1372 if (err)
1373 return err;
1374 } else
1375 memcpy(lk_ul_user, opaluid[OPAL_ADMIN1_UID], OPAL_UID_LENGTH);
1376
1377 add_token_u8(&err, dev, OPAL_CALL);
1378 add_token_bytestring(&err, dev, opaluid[OPAL_SMUID_UID],
1379 OPAL_UID_LENGTH);
1380 add_token_bytestring(&err, dev, opalmethod[OPAL_STARTSESSION],
1381 OPAL_UID_LENGTH);
1382
1383 add_token_u8(&err, dev, OPAL_STARTLIST);
1384 add_token_u64(&err, dev, hsn);
1385 add_token_bytestring(&err, dev, opaluid[OPAL_LOCKINGSP_UID],
1386 OPAL_UID_LENGTH);
1387 add_token_u8(&err, dev, 1);
1388 add_token_u8(&err, dev, OPAL_STARTNAME);
1389 add_token_u8(&err, dev, 0);
1390 add_token_bytestring(&err, dev, key, keylen);
1391 add_token_u8(&err, dev, OPAL_ENDNAME);
1392 add_token_u8(&err, dev, OPAL_STARTNAME);
1393 add_token_u8(&err, dev, 3);
1394 add_token_bytestring(&err, dev, lk_ul_user, OPAL_UID_LENGTH);
1395 add_token_u8(&err, dev, OPAL_ENDNAME);
1396 add_token_u8(&err, dev, OPAL_ENDLIST);
1397
1398 if (err) {
591c59d1 1399 pr_debug("Error building STARTSESSION command.\n");
455a7b23
SB
1400 return err;
1401 }
1402
1403 return finalize_and_send(dev, start_opal_session_cont);
1404}
1405
eed64951 1406static int revert_tper(struct opal_dev *dev, void *data)
455a7b23
SB
1407{
1408 int err = 0;
1409
1410 clear_opal_cmd(dev);
1411 set_comid(dev, dev->comid);
1412
1413 add_token_u8(&err, dev, OPAL_CALL);
1414 add_token_bytestring(&err, dev, opaluid[OPAL_ADMINSP_UID],
1415 OPAL_UID_LENGTH);
1416 add_token_bytestring(&err, dev, opalmethod[OPAL_REVERT],
1417 OPAL_UID_LENGTH);
1418 add_token_u8(&err, dev, OPAL_STARTLIST);
1419 add_token_u8(&err, dev, OPAL_ENDLIST);
1420 if (err) {
591c59d1 1421 pr_debug("Error building REVERT TPER command.\n");
455a7b23
SB
1422 return err;
1423 }
1424
1425 return finalize_and_send(dev, parse_and_check_status);
1426}
1427
eed64951 1428static int internal_activate_user(struct opal_dev *dev, void *data)
455a7b23 1429{
eed64951 1430 struct opal_session_info *session = data;
455a7b23
SB
1431 u8 uid[OPAL_UID_LENGTH];
1432 int err = 0;
1433
1434 clear_opal_cmd(dev);
1435 set_comid(dev, dev->comid);
1436
1437 memcpy(uid, opaluid[OPAL_USER1_UID], OPAL_UID_LENGTH);
1438 uid[7] = session->who;
1439
1440 add_token_u8(&err, dev, OPAL_CALL);
1441 add_token_bytestring(&err, dev, uid, OPAL_UID_LENGTH);
1442 add_token_bytestring(&err, dev, opalmethod[OPAL_SET], OPAL_UID_LENGTH);
1443 add_token_u8(&err, dev, OPAL_STARTLIST);
1444 add_token_u8(&err, dev, OPAL_STARTNAME);
1445 add_token_u8(&err, dev, OPAL_VALUES);
1446 add_token_u8(&err, dev, OPAL_STARTLIST);
1447 add_token_u8(&err, dev, OPAL_STARTNAME);
1448 add_token_u8(&err, dev, 5); /* Enabled */
1449 add_token_u8(&err, dev, OPAL_TRUE);
1450 add_token_u8(&err, dev, OPAL_ENDNAME);
1451 add_token_u8(&err, dev, OPAL_ENDLIST);
1452 add_token_u8(&err, dev, OPAL_ENDNAME);
1453 add_token_u8(&err, dev, OPAL_ENDLIST);
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);
1480 add_token_u8(&err, dev, OPAL_ENDLIST);
1481
1482 if (err) {
591c59d1 1483 pr_debug("Error building Erase Locking Range Command.\n");
455a7b23
SB
1484 return err;
1485 }
1486 return finalize_and_send(dev, parse_and_check_status);
1487}
1488
eed64951 1489static int set_mbr_done(struct opal_dev *dev, void *data)
455a7b23 1490{
eed64951 1491 u8 *mbr_done_tf = data;
455a7b23
SB
1492 int err = 0;
1493
1494 clear_opal_cmd(dev);
1495 set_comid(dev, dev->comid);
1496
1497 add_token_u8(&err, dev, OPAL_CALL);
1498 add_token_bytestring(&err, dev, opaluid[OPAL_MBRCONTROL],
1499 OPAL_UID_LENGTH);
1500 add_token_bytestring(&err, dev, opalmethod[OPAL_SET], OPAL_UID_LENGTH);
1501 add_token_u8(&err, dev, OPAL_STARTLIST);
1502 add_token_u8(&err, dev, OPAL_STARTNAME);
1503 add_token_u8(&err, dev, OPAL_VALUES);
1504 add_token_u8(&err, dev, OPAL_STARTLIST);
1505 add_token_u8(&err, dev, OPAL_STARTNAME);
1506 add_token_u8(&err, dev, 2); /* Done */
eed64951 1507 add_token_u8(&err, dev, *mbr_done_tf); /* Done T or F */
455a7b23
SB
1508 add_token_u8(&err, dev, OPAL_ENDNAME);
1509 add_token_u8(&err, dev, OPAL_ENDLIST);
1510 add_token_u8(&err, dev, OPAL_ENDNAME);
1511 add_token_u8(&err, dev, OPAL_ENDLIST);
1512
1513 if (err) {
591c59d1 1514 pr_debug("Error Building set MBR Done command\n");
455a7b23
SB
1515 return err;
1516 }
1517
1518 return finalize_and_send(dev, parse_and_check_status);
1519}
1520
eed64951 1521static int set_mbr_enable_disable(struct opal_dev *dev, void *data)
455a7b23 1522{
eed64951 1523 u8 *mbr_en_dis = data;
455a7b23
SB
1524 int err = 0;
1525
1526 clear_opal_cmd(dev);
1527 set_comid(dev, dev->comid);
1528
1529 add_token_u8(&err, dev, OPAL_CALL);
1530 add_token_bytestring(&err, dev, opaluid[OPAL_MBRCONTROL],
1531 OPAL_UID_LENGTH);
1532 add_token_bytestring(&err, dev, opalmethod[OPAL_SET], OPAL_UID_LENGTH);
1533 add_token_u8(&err, dev, OPAL_STARTLIST);
1534 add_token_u8(&err, dev, OPAL_STARTNAME);
1535 add_token_u8(&err, dev, OPAL_VALUES);
1536 add_token_u8(&err, dev, OPAL_STARTLIST);
1537 add_token_u8(&err, dev, OPAL_STARTNAME);
1538 add_token_u8(&err, dev, 1);
eed64951 1539 add_token_u8(&err, dev, *mbr_en_dis);
455a7b23
SB
1540 add_token_u8(&err, dev, OPAL_ENDNAME);
1541 add_token_u8(&err, dev, OPAL_ENDLIST);
1542 add_token_u8(&err, dev, OPAL_ENDNAME);
1543 add_token_u8(&err, dev, OPAL_ENDLIST);
1544
1545 if (err) {
591c59d1 1546 pr_debug("Error Building set MBR done command\n");
455a7b23
SB
1547 return err;
1548 }
1549
1550 return finalize_and_send(dev, parse_and_check_status);
1551}
1552
1553static int generic_pw_cmd(u8 *key, size_t key_len, u8 *cpin_uid,
1554 struct opal_dev *dev)
1555{
1556 int err = 0;
1557
1558 clear_opal_cmd(dev);
1559 set_comid(dev, dev->comid);
1560
1561 add_token_u8(&err, dev, OPAL_CALL);
1562 add_token_bytestring(&err, dev, cpin_uid, OPAL_UID_LENGTH);
1563 add_token_bytestring(&err, dev, opalmethod[OPAL_SET],
1564 OPAL_UID_LENGTH);
1565 add_token_u8(&err, dev, OPAL_STARTLIST);
1566 add_token_u8(&err, dev, OPAL_STARTNAME);
1567 add_token_u8(&err, dev, OPAL_VALUES);
1568 add_token_u8(&err, dev, OPAL_STARTLIST);
1569 add_token_u8(&err, dev, OPAL_STARTNAME);
1570 add_token_u8(&err, dev, 3); /* PIN */
1571 add_token_bytestring(&err, dev, key, key_len);
1572 add_token_u8(&err, dev, OPAL_ENDNAME);
1573 add_token_u8(&err, dev, OPAL_ENDLIST);
1574 add_token_u8(&err, dev, OPAL_ENDNAME);
1575 add_token_u8(&err, dev, OPAL_ENDLIST);
1576
1577 return err;
1578}
1579
eed64951 1580static int set_new_pw(struct opal_dev *dev, void *data)
455a7b23
SB
1581{
1582 u8 cpin_uid[OPAL_UID_LENGTH];
eed64951 1583 struct opal_session_info *usr = data;
455a7b23
SB
1584
1585 memcpy(cpin_uid, opaluid[OPAL_C_PIN_ADMIN1], OPAL_UID_LENGTH);
1586
1587 if (usr->who != OPAL_ADMIN1) {
1588 cpin_uid[5] = 0x03;
1589 if (usr->sum)
1590 cpin_uid[7] = usr->opal_key.lr + 1;
1591 else
1592 cpin_uid[7] = usr->who;
1593 }
1594
1595 if (generic_pw_cmd(usr->opal_key.key, usr->opal_key.key_len,
1596 cpin_uid, dev)) {
591c59d1 1597 pr_debug("Error building set password command.\n");
455a7b23
SB
1598 return -ERANGE;
1599 }
1600
1601 return finalize_and_send(dev, parse_and_check_status);
1602}
1603
eed64951 1604static int set_sid_cpin_pin(struct opal_dev *dev, void *data)
455a7b23
SB
1605{
1606 u8 cpin_uid[OPAL_UID_LENGTH];
eed64951 1607 struct opal_key *key = data;
455a7b23
SB
1608
1609 memcpy(cpin_uid, opaluid[OPAL_C_PIN_SID], OPAL_UID_LENGTH);
1610
1611 if (generic_pw_cmd(key->key, key->key_len, cpin_uid, dev)) {
591c59d1 1612 pr_debug("Error building Set SID cpin\n");
455a7b23
SB
1613 return -ERANGE;
1614 }
1615 return finalize_and_send(dev, parse_and_check_status);
1616}
1617
eed64951 1618static int add_user_to_lr(struct opal_dev *dev, void *data)
455a7b23
SB
1619{
1620 u8 lr_buffer[OPAL_UID_LENGTH];
1621 u8 user_uid[OPAL_UID_LENGTH];
eed64951 1622 struct opal_lock_unlock *lkul = data;
455a7b23
SB
1623 int err = 0;
1624
1625 clear_opal_cmd(dev);
1626 set_comid(dev, dev->comid);
1627
455a7b23
SB
1628 memcpy(lr_buffer, opaluid[OPAL_LOCKINGRANGE_ACE_RDLOCKED],
1629 OPAL_UID_LENGTH);
1630
1631 if (lkul->l_state == OPAL_RW)
1632 memcpy(lr_buffer, opaluid[OPAL_LOCKINGRANGE_ACE_WRLOCKED],
1633 OPAL_UID_LENGTH);
1634
1635 lr_buffer[7] = lkul->session.opal_key.lr;
1636
1637 memcpy(user_uid, opaluid[OPAL_USER1_UID], OPAL_UID_LENGTH);
1638
1639 user_uid[7] = lkul->session.who;
1640
1641 add_token_u8(&err, dev, OPAL_CALL);
1642 add_token_bytestring(&err, dev, lr_buffer, OPAL_UID_LENGTH);
1643 add_token_bytestring(&err, dev, opalmethod[OPAL_SET],
1644 OPAL_UID_LENGTH);
1645
1646 add_token_u8(&err, dev, OPAL_STARTLIST);
1647 add_token_u8(&err, dev, OPAL_STARTNAME);
1648 add_token_u8(&err, dev, OPAL_VALUES);
1649
1650 add_token_u8(&err, dev, OPAL_STARTLIST);
1651 add_token_u8(&err, dev, OPAL_STARTNAME);
1652 add_token_u8(&err, dev, 3);
1653
1654 add_token_u8(&err, dev, OPAL_STARTLIST);
1655
1656
1657 add_token_u8(&err, dev, OPAL_STARTNAME);
1658 add_token_bytestring(&err, dev,
1659 opaluid[OPAL_HALF_UID_AUTHORITY_OBJ_REF],
1660 OPAL_UID_LENGTH/2);
1661 add_token_bytestring(&err, dev, user_uid, OPAL_UID_LENGTH);
1662 add_token_u8(&err, dev, OPAL_ENDNAME);
1663
1664
1665 add_token_u8(&err, dev, OPAL_STARTNAME);
1666 add_token_bytestring(&err, dev,
1667 opaluid[OPAL_HALF_UID_AUTHORITY_OBJ_REF],
1668 OPAL_UID_LENGTH/2);
1669 add_token_bytestring(&err, dev, user_uid, OPAL_UID_LENGTH);
1670 add_token_u8(&err, dev, OPAL_ENDNAME);
1671
1672
1673 add_token_u8(&err, dev, OPAL_STARTNAME);
1674 add_token_bytestring(&err, dev, opaluid[OPAL_HALF_UID_BOOLEAN_ACE],
1675 OPAL_UID_LENGTH/2);
1676 add_token_u8(&err, dev, 1);
1677 add_token_u8(&err, dev, OPAL_ENDNAME);
1678
1679
1680 add_token_u8(&err, dev, OPAL_ENDLIST);
1681 add_token_u8(&err, dev, OPAL_ENDNAME);
1682 add_token_u8(&err, dev, OPAL_ENDLIST);
1683 add_token_u8(&err, dev, OPAL_ENDNAME);
1684 add_token_u8(&err, dev, OPAL_ENDLIST);
1685
1686 if (err) {
591c59d1 1687 pr_debug("Error building add user to locking range command.\n");
455a7b23
SB
1688 return err;
1689 }
1690
1691 return finalize_and_send(dev, parse_and_check_status);
1692}
1693
eed64951 1694static int lock_unlock_locking_range(struct opal_dev *dev, void *data)
455a7b23
SB
1695{
1696 u8 lr_buffer[OPAL_UID_LENGTH];
eed64951 1697 struct opal_lock_unlock *lkul = data;
455a7b23
SB
1698 u8 read_locked = 1, write_locked = 1;
1699 int err = 0;
1700
1701 clear_opal_cmd(dev);
1702 set_comid(dev, dev->comid);
1703
455a7b23
SB
1704 if (build_locking_range(lr_buffer, sizeof(lr_buffer),
1705 lkul->session.opal_key.lr) < 0)
1706 return -ERANGE;
1707
1708 switch (lkul->l_state) {
1709 case OPAL_RO:
1710 read_locked = 0;
1711 write_locked = 1;
1712 break;
1713 case OPAL_RW:
1714 read_locked = 0;
1715 write_locked = 0;
1716 break;
1717 case OPAL_LK:
1e815b33 1718 /* vars are initialized to locked */
455a7b23
SB
1719 break;
1720 default:
591c59d1 1721 pr_debug("Tried to set an invalid locking state... returning to uland\n");
455a7b23
SB
1722 return OPAL_INVAL_PARAM;
1723 }
1724
1725 add_token_u8(&err, dev, OPAL_CALL);
1726 add_token_bytestring(&err, dev, lr_buffer, OPAL_UID_LENGTH);
1727 add_token_bytestring(&err, dev, opalmethod[OPAL_SET], OPAL_UID_LENGTH);
1728 add_token_u8(&err, dev, OPAL_STARTLIST);
1729 add_token_u8(&err, dev, OPAL_STARTNAME);
1730 add_token_u8(&err, dev, OPAL_VALUES);
1731 add_token_u8(&err, dev, OPAL_STARTLIST);
1732
1733 add_token_u8(&err, dev, OPAL_STARTNAME);
1734 add_token_u8(&err, dev, OPAL_READLOCKED);
1735 add_token_u8(&err, dev, read_locked);
1736 add_token_u8(&err, dev, OPAL_ENDNAME);
1737
1738 add_token_u8(&err, dev, OPAL_STARTNAME);
1739 add_token_u8(&err, dev, OPAL_WRITELOCKED);
1740 add_token_u8(&err, dev, write_locked);
1741 add_token_u8(&err, dev, OPAL_ENDNAME);
1742
1743 add_token_u8(&err, dev, OPAL_ENDLIST);
1744 add_token_u8(&err, dev, OPAL_ENDNAME);
1745 add_token_u8(&err, dev, OPAL_ENDLIST);
1746
1747 if (err) {
591c59d1 1748 pr_debug("Error building SET command.\n");
455a7b23
SB
1749 return err;
1750 }
1751 return finalize_and_send(dev, parse_and_check_status);
1752}
1753
1754
eed64951 1755static int lock_unlock_locking_range_sum(struct opal_dev *dev, void *data)
455a7b23
SB
1756{
1757 u8 lr_buffer[OPAL_UID_LENGTH];
1758 u8 read_locked = 1, write_locked = 1;
eed64951 1759 struct opal_lock_unlock *lkul = data;
455a7b23
SB
1760 int ret;
1761
1762 clear_opal_cmd(dev);
1763 set_comid(dev, dev->comid);
1764
455a7b23
SB
1765 if (build_locking_range(lr_buffer, sizeof(lr_buffer),
1766 lkul->session.opal_key.lr) < 0)
1767 return -ERANGE;
1768
1769 switch (lkul->l_state) {
1770 case OPAL_RO:
1771 read_locked = 0;
1772 write_locked = 1;
1773 break;
1774 case OPAL_RW:
1775 read_locked = 0;
1776 write_locked = 0;
1777 break;
1778 case OPAL_LK:
1e815b33 1779 /* vars are initialized to locked */
455a7b23
SB
1780 break;
1781 default:
591c59d1 1782 pr_debug("Tried to set an invalid locking state.\n");
455a7b23
SB
1783 return OPAL_INVAL_PARAM;
1784 }
1785 ret = generic_lr_enable_disable(dev, lr_buffer, 1, 1,
1786 read_locked, write_locked);
1787
1788 if (ret < 0) {
591c59d1 1789 pr_debug("Error building SET command.\n");
455a7b23
SB
1790 return ret;
1791 }
1792 return finalize_and_send(dev, parse_and_check_status);
1793}
1794
eed64951 1795static int activate_lsp(struct opal_dev *dev, void *data)
455a7b23 1796{
eed64951 1797 struct opal_lr_act *opal_act = data;
455a7b23
SB
1798 u8 user_lr[OPAL_UID_LENGTH];
1799 u8 uint_3 = 0x83;
1800 int err = 0, i;
1801
1802 clear_opal_cmd(dev);
1803 set_comid(dev, dev->comid);
1804
455a7b23
SB
1805 add_token_u8(&err, dev, OPAL_CALL);
1806 add_token_bytestring(&err, dev, opaluid[OPAL_LOCKINGSP_UID],
1807 OPAL_UID_LENGTH);
1808 add_token_bytestring(&err, dev, opalmethod[OPAL_ACTIVATE],
1809 OPAL_UID_LENGTH);
1810
1811
1812 if (opal_act->sum) {
1813 err = build_locking_range(user_lr, sizeof(user_lr),
1814 opal_act->lr[0]);
1815 if (err)
1816 return err;
1817
1818 add_token_u8(&err, dev, OPAL_STARTLIST);
1819 add_token_u8(&err, dev, OPAL_STARTNAME);
1820 add_token_u8(&err, dev, uint_3);
1821 add_token_u8(&err, dev, 6);
1822 add_token_u8(&err, dev, 0);
1823 add_token_u8(&err, dev, 0);
1824
1825 add_token_u8(&err, dev, OPAL_STARTLIST);
1826 add_token_bytestring(&err, dev, user_lr, OPAL_UID_LENGTH);
1827 for (i = 1; i < opal_act->num_lrs; i++) {
1828 user_lr[7] = opal_act->lr[i];
1829 add_token_bytestring(&err, dev, user_lr, OPAL_UID_LENGTH);
1830 }
1831 add_token_u8(&err, dev, OPAL_ENDLIST);
1832 add_token_u8(&err, dev, OPAL_ENDNAME);
1833 add_token_u8(&err, dev, OPAL_ENDLIST);
1834
1835 } else {
1836 add_token_u8(&err, dev, OPAL_STARTLIST);
1837 add_token_u8(&err, dev, OPAL_ENDLIST);
1838 }
1839
1840 if (err) {
591c59d1 1841 pr_debug("Error building Activate LockingSP command.\n");
455a7b23
SB
1842 return err;
1843 }
1844
1845 return finalize_and_send(dev, parse_and_check_status);
1846}
1847
1848static int get_lsp_lifecycle_cont(struct opal_dev *dev)
1849{
1850 u8 lc_status;
1851 int error = 0;
1852
1853 error = parse_and_check_status(dev);
1854 if (error)
1855 return error;
1856
1857 lc_status = response_get_u64(&dev->parsed, 4);
1e815b33 1858 /* 0x08 is Manufactured Inactive */
455a7b23
SB
1859 /* 0x09 is Manufactured */
1860 if (lc_status != OPAL_MANUFACTURED_INACTIVE) {
591c59d1 1861 pr_debug("Couldn't determine the status of the Lifecycle state\n");
455a7b23
SB
1862 return -ENODEV;
1863 }
1864
1865 return 0;
1866}
1867
1868/* Determine if we're in the Manufactured Inactive or Active state */
eed64951 1869static int get_lsp_lifecycle(struct opal_dev *dev, void *data)
455a7b23
SB
1870{
1871 int err = 0;
1872
1873 clear_opal_cmd(dev);
1874 set_comid(dev, dev->comid);
1875
1876 add_token_u8(&err, dev, OPAL_CALL);
1877 add_token_bytestring(&err, dev, opaluid[OPAL_LOCKINGSP_UID],
1878 OPAL_UID_LENGTH);
1879 add_token_bytestring(&err, dev, opalmethod[OPAL_GET], OPAL_UID_LENGTH);
1880
1881 add_token_u8(&err, dev, OPAL_STARTLIST);
1882 add_token_u8(&err, dev, OPAL_STARTLIST);
1883
1884 add_token_u8(&err, dev, OPAL_STARTNAME);
1885 add_token_u8(&err, dev, 3); /* Start Column */
1886 add_token_u8(&err, dev, 6); /* Lifecycle Column */
1887 add_token_u8(&err, dev, OPAL_ENDNAME);
1888
1889 add_token_u8(&err, dev, OPAL_STARTNAME);
1890 add_token_u8(&err, dev, 4); /* End Column */
1891 add_token_u8(&err, dev, 6); /* Lifecycle Column */
1892 add_token_u8(&err, dev, OPAL_ENDNAME);
1893
1894 add_token_u8(&err, dev, OPAL_ENDLIST);
1895 add_token_u8(&err, dev, OPAL_ENDLIST);
1896
1897 if (err) {
591c59d1 1898 pr_debug("Error Building GET Lifecycle Status command\n");
455a7b23
SB
1899 return err;
1900 }
1901
1902 return finalize_and_send(dev, get_lsp_lifecycle_cont);
1903}
1904
1905static int get_msid_cpin_pin_cont(struct opal_dev *dev)
1906{
1907 const char *msid_pin;
1908 size_t strlen;
1909 int error = 0;
1910
1911 error = parse_and_check_status(dev);
1912 if (error)
1913 return error;
1914
1915 strlen = response_get_string(&dev->parsed, 4, &msid_pin);
1916 if (!msid_pin) {
591c59d1 1917 pr_debug("%s: Couldn't extract PIN from response\n", __func__);
455a7b23
SB
1918 return OPAL_INVAL_PARAM;
1919 }
1920
1921 dev->prev_data = kmemdup(msid_pin, strlen, GFP_KERNEL);
1922 if (!dev->prev_data)
1923 return -ENOMEM;
1924
1925 dev->prev_d_len = strlen;
1926
1927 return 0;
1928}
1929
eed64951 1930static int get_msid_cpin_pin(struct opal_dev *dev, void *data)
455a7b23
SB
1931{
1932 int err = 0;
1933
1934 clear_opal_cmd(dev);
1935 set_comid(dev, dev->comid);
1936
455a7b23
SB
1937 add_token_u8(&err, dev, OPAL_CALL);
1938 add_token_bytestring(&err, dev, opaluid[OPAL_C_PIN_MSID],
1939 OPAL_UID_LENGTH);
1940 add_token_bytestring(&err, dev, opalmethod[OPAL_GET], OPAL_UID_LENGTH);
1941
1942 add_token_u8(&err, dev, OPAL_STARTLIST);
1943 add_token_u8(&err, dev, OPAL_STARTLIST);
1944
1945 add_token_u8(&err, dev, OPAL_STARTNAME);
1946 add_token_u8(&err, dev, 3); /* Start Column */
1947 add_token_u8(&err, dev, 3); /* PIN */
1948 add_token_u8(&err, dev, OPAL_ENDNAME);
1949
1950 add_token_u8(&err, dev, OPAL_STARTNAME);
1951 add_token_u8(&err, dev, 4); /* End Column */
1952 add_token_u8(&err, dev, 3); /* Lifecycle Column */
1953 add_token_u8(&err, dev, OPAL_ENDNAME);
1954
1955 add_token_u8(&err, dev, OPAL_ENDLIST);
1956 add_token_u8(&err, dev, OPAL_ENDLIST);
1957
1958 if (err) {
591c59d1 1959 pr_debug("Error building Get MSID CPIN PIN command.\n");
455a7b23
SB
1960 return err;
1961 }
1962
1963 return finalize_and_send(dev, get_msid_cpin_pin_cont);
1964}
1965
eed64951 1966static int end_opal_session(struct opal_dev *dev, void *data)
455a7b23
SB
1967{
1968 int err = 0;
1969
1970 clear_opal_cmd(dev);
455a7b23
SB
1971 set_comid(dev, dev->comid);
1972 add_token_u8(&err, dev, OPAL_ENDOFSESSION);
455a7b23 1973
eed64951
JD
1974 if (err < 0)
1975 return err;
455a7b23
SB
1976 return finalize_and_send(dev, end_session_cont);
1977}
1978
1979static int end_opal_session_error(struct opal_dev *dev)
1980{
eed64951
JD
1981 const struct opal_step error_end_session[] = {
1982 { end_opal_session, },
1983 { NULL, }
455a7b23 1984 };
eed64951 1985 dev->steps = error_end_session;
455a7b23
SB
1986 return next(dev);
1987}
1988
1989static inline void setup_opal_dev(struct opal_dev *dev,
eed64951 1990 const struct opal_step *steps)
455a7b23 1991{
eed64951 1992 dev->steps = steps;
455a7b23
SB
1993 dev->tsn = 0;
1994 dev->hsn = 0;
455a7b23
SB
1995 dev->prev_data = NULL;
1996}
1997
1998static int check_opal_support(struct opal_dev *dev)
1999{
eed64951
JD
2000 const struct opal_step steps[] = {
2001 { opal_discovery0, },
2002 { NULL, }
455a7b23
SB
2003 };
2004 int ret;
2005
2006 mutex_lock(&dev->dev_lock);
eed64951 2007 setup_opal_dev(dev, steps);
455a7b23
SB
2008 ret = next(dev);
2009 dev->supported = !ret;
2010 mutex_unlock(&dev->dev_lock);
2011 return ret;
2012}
2013
7d6d1578
SB
2014static void clean_opal_dev(struct opal_dev *dev)
2015{
2016
2017 struct opal_suspend_data *suspend, *next;
2018
2019 mutex_lock(&dev->dev_lock);
2020 list_for_each_entry_safe(suspend, next, &dev->unlk_lst, node) {
2021 list_del(&suspend->node);
2022 kfree(suspend);
2023 }
2024 mutex_unlock(&dev->dev_lock);
2025}
2026
2027void free_opal_dev(struct opal_dev *dev)
2028{
2029 if (!dev)
2030 return;
2031 clean_opal_dev(dev);
2032 kfree(dev);
2033}
2034EXPORT_SYMBOL(free_opal_dev);
2035
4f1244c8 2036struct opal_dev *init_opal_dev(void *data, sec_send_recv *send_recv)
455a7b23 2037{
4f1244c8
CH
2038 struct opal_dev *dev;
2039
2040 dev = kmalloc(sizeof(*dev), GFP_KERNEL);
2041 if (!dev)
2042 return NULL;
2043
2044 INIT_LIST_HEAD(&dev->unlk_lst);
2045 mutex_init(&dev->dev_lock);
2046 dev->data = data;
2047 dev->send_recv = send_recv;
2048 if (check_opal_support(dev) != 0) {
f5b37b7c 2049 pr_debug("Opal is not supported on this device\n");
4f1244c8
CH
2050 kfree(dev);
2051 return NULL;
2052 }
2053 return dev;
455a7b23
SB
2054}
2055EXPORT_SYMBOL(init_opal_dev);
2056
2057static int opal_secure_erase_locking_range(struct opal_dev *dev,
2058 struct opal_session_info *opal_session)
2059{
eed64951
JD
2060 const struct opal_step erase_steps[] = {
2061 { opal_discovery0, },
2062 { start_auth_opal_session, opal_session },
2063 { get_active_key, &opal_session->opal_key.lr },
2064 { gen_key, },
2065 { end_opal_session, },
2066 { NULL, }
455a7b23
SB
2067 };
2068 int ret;
2069
2070 mutex_lock(&dev->dev_lock);
eed64951 2071 setup_opal_dev(dev, erase_steps);
455a7b23
SB
2072 ret = next(dev);
2073 mutex_unlock(&dev->dev_lock);
2074 return ret;
2075}
2076
2077static int opal_erase_locking_range(struct opal_dev *dev,
2078 struct opal_session_info *opal_session)
2079{
eed64951
JD
2080 const struct opal_step erase_steps[] = {
2081 { opal_discovery0, },
2082 { start_auth_opal_session, opal_session },
2083 { erase_locking_range, opal_session },
2084 { end_opal_session, },
2085 { NULL, }
455a7b23
SB
2086 };
2087 int ret;
2088
2089 mutex_lock(&dev->dev_lock);
eed64951 2090 setup_opal_dev(dev, erase_steps);
455a7b23
SB
2091 ret = next(dev);
2092 mutex_unlock(&dev->dev_lock);
2093 return ret;
2094}
2095
2096static int opal_enable_disable_shadow_mbr(struct opal_dev *dev,
2097 struct opal_mbr_data *opal_mbr)
2098{
78bf4735
DK
2099 u8 enable_disable = opal_mbr->enable_disable == OPAL_MBR_ENABLE ?
2100 OPAL_TRUE : OPAL_FALSE;
2101
eed64951
JD
2102 const struct opal_step mbr_steps[] = {
2103 { opal_discovery0, },
2104 { start_admin1LSP_opal_session, &opal_mbr->key },
78bf4735 2105 { set_mbr_done, &enable_disable },
eed64951
JD
2106 { end_opal_session, },
2107 { start_admin1LSP_opal_session, &opal_mbr->key },
78bf4735 2108 { set_mbr_enable_disable, &enable_disable },
eed64951
JD
2109 { end_opal_session, },
2110 { NULL, }
455a7b23
SB
2111 };
2112 int ret;
2113
2114 if (opal_mbr->enable_disable != OPAL_MBR_ENABLE &&
2115 opal_mbr->enable_disable != OPAL_MBR_DISABLE)
2116 return -EINVAL;
2117
2118 mutex_lock(&dev->dev_lock);
eed64951 2119 setup_opal_dev(dev, mbr_steps);
455a7b23
SB
2120 ret = next(dev);
2121 mutex_unlock(&dev->dev_lock);
2122 return ret;
2123}
2124
2125static int opal_save(struct opal_dev *dev, struct opal_lock_unlock *lk_unlk)
2126{
2127 struct opal_suspend_data *suspend;
2128
2129 suspend = kzalloc(sizeof(*suspend), GFP_KERNEL);
2130 if (!suspend)
2131 return -ENOMEM;
2132
2133 suspend->unlk = *lk_unlk;
2134 suspend->lr = lk_unlk->session.opal_key.lr;
2135
2136 mutex_lock(&dev->dev_lock);
2137 setup_opal_dev(dev, NULL);
2138 add_suspend_info(dev, suspend);
2139 mutex_unlock(&dev->dev_lock);
2140 return 0;
2141}
2142
2143static int opal_add_user_to_lr(struct opal_dev *dev,
2144 struct opal_lock_unlock *lk_unlk)
2145{
eed64951
JD
2146 const struct opal_step steps[] = {
2147 { opal_discovery0, },
2148 { start_admin1LSP_opal_session, &lk_unlk->session.opal_key },
2149 { add_user_to_lr, lk_unlk },
2150 { end_opal_session, },
2151 { NULL, }
455a7b23
SB
2152 };
2153 int ret;
2154
2155 if (lk_unlk->l_state != OPAL_RO &&
2156 lk_unlk->l_state != OPAL_RW) {
591c59d1 2157 pr_debug("Locking state was not RO or RW\n");
455a7b23
SB
2158 return -EINVAL;
2159 }
b0bfdfc2 2160 if (lk_unlk->session.who < OPAL_USER1 ||
455a7b23 2161 lk_unlk->session.who > OPAL_USER9) {
591c59d1
SB
2162 pr_debug("Authority was not within the range of users: %d\n",
2163 lk_unlk->session.who);
455a7b23
SB
2164 return -EINVAL;
2165 }
2166 if (lk_unlk->session.sum) {
591c59d1
SB
2167 pr_debug("%s not supported in sum. Use setup locking range\n",
2168 __func__);
455a7b23
SB
2169 return -EINVAL;
2170 }
2171
2172 mutex_lock(&dev->dev_lock);
eed64951 2173 setup_opal_dev(dev, steps);
455a7b23
SB
2174 ret = next(dev);
2175 mutex_unlock(&dev->dev_lock);
2176 return ret;
2177}
2178
2179static int opal_reverttper(struct opal_dev *dev, struct opal_key *opal)
2180{
eed64951
JD
2181 const struct opal_step revert_steps[] = {
2182 { opal_discovery0, },
2183 { start_SIDASP_opal_session, opal },
2184 { revert_tper, }, /* controller will terminate session */
2185 { NULL, }
455a7b23
SB
2186 };
2187 int ret;
2188
2189 mutex_lock(&dev->dev_lock);
eed64951 2190 setup_opal_dev(dev, revert_steps);
455a7b23
SB
2191 ret = next(dev);
2192 mutex_unlock(&dev->dev_lock);
7d6d1578
SB
2193
2194 /*
2195 * If we successfully reverted lets clean
2196 * any saved locking ranges.
2197 */
2198 if (!ret)
2199 clean_opal_dev(dev);
2200
455a7b23
SB
2201 return ret;
2202}
2203
eed64951
JD
2204static int __opal_lock_unlock(struct opal_dev *dev,
2205 struct opal_lock_unlock *lk_unlk)
455a7b23 2206{
eed64951
JD
2207 const struct opal_step unlock_steps[] = {
2208 { opal_discovery0, },
2209 { start_auth_opal_session, &lk_unlk->session },
2210 { lock_unlock_locking_range, lk_unlk },
2211 { end_opal_session, },
2212 { NULL, }
455a7b23 2213 };
eed64951
JD
2214 const struct opal_step unlock_sum_steps[] = {
2215 { opal_discovery0, },
2216 { start_auth_opal_session, &lk_unlk->session },
2217 { lock_unlock_locking_range_sum, lk_unlk },
2218 { end_opal_session, },
2219 { NULL, }
455a7b23
SB
2220 };
2221
eed64951 2222 dev->steps = lk_unlk->session.sum ? unlock_sum_steps : unlock_steps;
455a7b23
SB
2223 return next(dev);
2224}
2225
dbec491b
SB
2226static int __opal_set_mbr_done(struct opal_dev *dev, struct opal_key *key)
2227{
78bf4735 2228 u8 mbr_done_tf = OPAL_TRUE;
1e815b33 2229 const struct opal_step mbrdone_step[] = {
dbec491b
SB
2230 { opal_discovery0, },
2231 { start_admin1LSP_opal_session, key },
2232 { set_mbr_done, &mbr_done_tf },
2233 { end_opal_session, },
2234 { NULL, }
2235 };
2236
2237 dev->steps = mbrdone_step;
2238 return next(dev);
2239}
2240
eed64951
JD
2241static int opal_lock_unlock(struct opal_dev *dev,
2242 struct opal_lock_unlock *lk_unlk)
455a7b23 2243{
455a7b23
SB
2244 int ret;
2245
2246 if (lk_unlk->session.who < OPAL_ADMIN1 ||
2247 lk_unlk->session.who > OPAL_USER9)
2248 return -EINVAL;
2249
2250 mutex_lock(&dev->dev_lock);
eed64951 2251 ret = __opal_lock_unlock(dev, lk_unlk);
455a7b23
SB
2252 mutex_unlock(&dev->dev_lock);
2253 return ret;
2254}
2255
2256static int opal_take_ownership(struct opal_dev *dev, struct opal_key *opal)
2257{
eed64951
JD
2258 const struct opal_step owner_steps[] = {
2259 { opal_discovery0, },
2260 { start_anybodyASP_opal_session, },
2261 { get_msid_cpin_pin, },
2262 { end_opal_session, },
2263 { start_SIDASP_opal_session, opal },
2264 { set_sid_cpin_pin, opal },
2265 { end_opal_session, },
2266 { NULL, }
455a7b23 2267 };
455a7b23
SB
2268 int ret;
2269
2270 if (!dev)
2271 return -ENODEV;
2272
2273 mutex_lock(&dev->dev_lock);
eed64951 2274 setup_opal_dev(dev, owner_steps);
455a7b23
SB
2275 ret = next(dev);
2276 mutex_unlock(&dev->dev_lock);
2277 return ret;
2278}
2279
1e815b33
DK
2280static int opal_activate_lsp(struct opal_dev *dev,
2281 struct opal_lr_act *opal_lr_act)
455a7b23 2282{
eed64951
JD
2283 const struct opal_step active_steps[] = {
2284 { opal_discovery0, },
2285 { start_SIDASP_opal_session, &opal_lr_act->key },
2286 { get_lsp_lifecycle, },
2287 { activate_lsp, opal_lr_act },
2288 { end_opal_session, },
2289 { NULL, }
455a7b23
SB
2290 };
2291 int ret;
2292
2293 if (!opal_lr_act->num_lrs || opal_lr_act->num_lrs > OPAL_MAX_LRS)
2294 return -EINVAL;
2295
2296 mutex_lock(&dev->dev_lock);
eed64951 2297 setup_opal_dev(dev, active_steps);
455a7b23
SB
2298 ret = next(dev);
2299 mutex_unlock(&dev->dev_lock);
2300 return ret;
2301}
2302
2303static int opal_setup_locking_range(struct opal_dev *dev,
2304 struct opal_user_lr_setup *opal_lrs)
2305{
eed64951
JD
2306 const struct opal_step lr_steps[] = {
2307 { opal_discovery0, },
2308 { start_auth_opal_session, &opal_lrs->session },
2309 { setup_locking_range, opal_lrs },
2310 { end_opal_session, },
2311 { NULL, }
455a7b23
SB
2312 };
2313 int ret;
2314
2315 mutex_lock(&dev->dev_lock);
eed64951 2316 setup_opal_dev(dev, lr_steps);
455a7b23
SB
2317 ret = next(dev);
2318 mutex_unlock(&dev->dev_lock);
2319 return ret;
2320}
2321
2322static int opal_set_new_pw(struct opal_dev *dev, struct opal_new_pw *opal_pw)
2323{
eed64951
JD
2324 const struct opal_step pw_steps[] = {
2325 { opal_discovery0, },
2326 { start_auth_opal_session, &opal_pw->session },
2327 { set_new_pw, &opal_pw->new_user_pw },
2328 { end_opal_session, },
2329 { NULL }
455a7b23 2330 };
455a7b23
SB
2331 int ret;
2332
2333 if (opal_pw->session.who < OPAL_ADMIN1 ||
2334 opal_pw->session.who > OPAL_USER9 ||
2335 opal_pw->new_user_pw.who < OPAL_ADMIN1 ||
2336 opal_pw->new_user_pw.who > OPAL_USER9)
2337 return -EINVAL;
2338
2339 mutex_lock(&dev->dev_lock);
eed64951 2340 setup_opal_dev(dev, pw_steps);
455a7b23
SB
2341 ret = next(dev);
2342 mutex_unlock(&dev->dev_lock);
2343 return ret;
2344}
2345
2346static int opal_activate_user(struct opal_dev *dev,
2347 struct opal_session_info *opal_session)
2348{
eed64951
JD
2349 const struct opal_step act_steps[] = {
2350 { opal_discovery0, },
2351 { start_admin1LSP_opal_session, &opal_session->opal_key },
2352 { internal_activate_user, opal_session },
2353 { end_opal_session, },
2354 { NULL, }
455a7b23 2355 };
455a7b23
SB
2356 int ret;
2357
2358 /* We can't activate Admin1 it's active as manufactured */
b0bfdfc2 2359 if (opal_session->who < OPAL_USER1 ||
455a7b23 2360 opal_session->who > OPAL_USER9) {
591c59d1 2361 pr_debug("Who was not a valid user: %d\n", opal_session->who);
455a7b23
SB
2362 return -EINVAL;
2363 }
2364
2365 mutex_lock(&dev->dev_lock);
eed64951 2366 setup_opal_dev(dev, act_steps);
455a7b23
SB
2367 ret = next(dev);
2368 mutex_unlock(&dev->dev_lock);
2369 return ret;
2370}
2371
2372bool opal_unlock_from_suspend(struct opal_dev *dev)
2373{
2374 struct opal_suspend_data *suspend;
455a7b23
SB
2375 bool was_failure = false;
2376 int ret = 0;
2377
2378 if (!dev)
2379 return false;
2380 if (!dev->supported)
2381 return false;
2382
2383 mutex_lock(&dev->dev_lock);
2384 setup_opal_dev(dev, NULL);
455a7b23
SB
2385
2386 list_for_each_entry(suspend, &dev->unlk_lst, node) {
455a7b23
SB
2387 dev->tsn = 0;
2388 dev->hsn = 0;
2389
eed64951 2390 ret = __opal_lock_unlock(dev, &suspend->unlk);
455a7b23 2391 if (ret) {
591c59d1
SB
2392 pr_debug("Failed to unlock LR %hhu with sum %d\n",
2393 suspend->unlk.session.opal_key.lr,
2394 suspend->unlk.session.sum);
455a7b23
SB
2395 was_failure = true;
2396 }
dbec491b
SB
2397 if (dev->mbr_enabled) {
2398 ret = __opal_set_mbr_done(dev, &suspend->unlk.session.opal_key);
2399 if (ret)
2400 pr_debug("Failed to set MBR Done in S3 resume\n");
2401 }
455a7b23
SB
2402 }
2403 mutex_unlock(&dev->dev_lock);
2404 return was_failure;
2405}
2406EXPORT_SYMBOL(opal_unlock_from_suspend);
2407
e225c20e 2408int sed_ioctl(struct opal_dev *dev, unsigned int cmd, void __user *arg)
455a7b23 2409{
e225c20e
SB
2410 void *p;
2411 int ret = -ENOTTY;
455a7b23
SB
2412
2413 if (!capable(CAP_SYS_ADMIN))
2414 return -EACCES;
4f1244c8
CH
2415 if (!dev)
2416 return -ENOTSUPP;
591c59d1 2417 if (!dev->supported)
455a7b23 2418 return -ENOTSUPP;
455a7b23 2419
eed64951 2420 p = memdup_user(arg, _IOC_SIZE(cmd));
e225c20e
SB
2421 if (IS_ERR(p))
2422 return PTR_ERR(p);
455a7b23 2423
e225c20e
SB
2424 switch (cmd) {
2425 case IOC_OPAL_SAVE:
2426 ret = opal_save(dev, p);
2427 break;
2428 case IOC_OPAL_LOCK_UNLOCK:
2429 ret = opal_lock_unlock(dev, p);
2430 break;
2431 case IOC_OPAL_TAKE_OWNERSHIP:
2432 ret = opal_take_ownership(dev, p);
2433 break;
2434 case IOC_OPAL_ACTIVATE_LSP:
2435 ret = opal_activate_lsp(dev, p);
2436 break;
2437 case IOC_OPAL_SET_PW:
2438 ret = opal_set_new_pw(dev, p);
2439 break;
2440 case IOC_OPAL_ACTIVATE_USR:
2441 ret = opal_activate_user(dev, p);
2442 break;
2443 case IOC_OPAL_REVERT_TPR:
2444 ret = opal_reverttper(dev, p);
2445 break;
2446 case IOC_OPAL_LR_SETUP:
2447 ret = opal_setup_locking_range(dev, p);
2448 break;
2449 case IOC_OPAL_ADD_USR_TO_LR:
2450 ret = opal_add_user_to_lr(dev, p);
2451 break;
2452 case IOC_OPAL_ENABLE_DISABLE_MBR:
2453 ret = opal_enable_disable_shadow_mbr(dev, p);
2454 break;
2455 case IOC_OPAL_ERASE_LR:
2456 ret = opal_erase_locking_range(dev, p);
2457 break;
2458 case IOC_OPAL_SECURE_ERASE_LR:
2459 ret = opal_secure_erase_locking_range(dev, p);
2460 break;
455a7b23 2461 default:
591c59d1 2462 break;
455a7b23 2463 }
e225c20e
SB
2464
2465 kfree(p);
2466 return ret;
455a7b23
SB
2467}
2468EXPORT_SYMBOL_GPL(sed_ioctl);