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