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