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