btrfs: dev-replace: go back to suspended state if target device is missing
[linux/fpc-iii.git] / block / sed-opal.c
blobe0de4dd448b3c7238e8656b572de72206302bf87
1 /*
2 * Copyright © 2016 Intel Corporation
4 * Authors:
5 * Scott Bauer <scott.bauer@intel.com>
6 * Rafael Antognolli <rafael.antognolli@intel.com>
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.
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.
18 #define pr_fmt(fmt) KBUILD_MODNAME ":OPAL: " fmt
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>
32 #include "opal_proto.h"
34 #define IO_BUFFER_LENGTH 2048
35 #define MAX_TOKS 64
37 struct opal_step {
38 int (*fn)(struct opal_dev *dev, void *data);
39 void *data;
41 typedef int (cont_fn)(struct opal_dev *dev);
43 enum opal_atom_width {
44 OPAL_WIDTH_TINY,
45 OPAL_WIDTH_SHORT,
46 OPAL_WIDTH_MEDIUM,
47 OPAL_WIDTH_LONG,
48 OPAL_WIDTH_TOKEN
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.
57 struct 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;
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.
76 struct parsed_resp {
77 int num;
78 struct opal_resp_tok toks[MAX_TOKS];
81 struct opal_dev {
82 bool supported;
83 bool mbr_enabled;
85 void *data;
86 sec_send_recv *send_recv;
88 const struct opal_step *steps;
89 struct mutex dev_lock;
90 u16 comid;
91 u32 hsn;
92 u32 tsn;
93 u64 align;
94 u64 lowest_lba;
96 size_t pos;
97 u8 cmd[IO_BUFFER_LENGTH];
98 u8 resp[IO_BUFFER_LENGTH];
100 struct parsed_resp parsed;
101 size_t prev_d_len;
102 void *prev_data;
104 struct list_head unlk_lst;
108 static const u8 opaluid[][OPAL_UID_LENGTH] = {
109 /* users */
110 [OPAL_SMUID_UID] =
111 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff },
112 [OPAL_THISSP_UID] =
113 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 },
114 [OPAL_ADMINSP_UID] =
115 { 0x00, 0x00, 0x02, 0x05, 0x00, 0x00, 0x00, 0x01 },
116 [OPAL_LOCKINGSP_UID] =
117 { 0x00, 0x00, 0x02, 0x05, 0x00, 0x00, 0x00, 0x02 },
118 [OPAL_ENTERPRISE_LOCKINGSP_UID] =
119 { 0x00, 0x00, 0x02, 0x05, 0x00, 0x01, 0x00, 0x01 },
120 [OPAL_ANYBODY_UID] =
121 { 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x01 },
122 [OPAL_SID_UID] =
123 { 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x06 },
124 [OPAL_ADMIN1_UID] =
125 { 0x00, 0x00, 0x00, 0x09, 0x00, 0x01, 0x00, 0x01 },
126 [OPAL_USER1_UID] =
127 { 0x00, 0x00, 0x00, 0x09, 0x00, 0x03, 0x00, 0x01 },
128 [OPAL_USER2_UID] =
129 { 0x00, 0x00, 0x00, 0x09, 0x00, 0x03, 0x00, 0x02 },
130 [OPAL_PSID_UID] =
131 { 0x00, 0x00, 0x00, 0x09, 0x00, 0x01, 0xff, 0x01 },
132 [OPAL_ENTERPRISE_BANDMASTER0_UID] =
133 { 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x80, 0x01 },
134 [OPAL_ENTERPRISE_ERASEMASTER_UID] =
135 { 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x84, 0x01 },
137 /* tables */
139 [OPAL_LOCKINGRANGE_GLOBAL] =
140 { 0x00, 0x00, 0x08, 0x02, 0x00, 0x00, 0x00, 0x01 },
141 [OPAL_LOCKINGRANGE_ACE_RDLOCKED] =
142 { 0x00, 0x00, 0x00, 0x08, 0x00, 0x03, 0xE0, 0x01 },
143 [OPAL_LOCKINGRANGE_ACE_WRLOCKED] =
144 { 0x00, 0x00, 0x00, 0x08, 0x00, 0x03, 0xE8, 0x01 },
145 [OPAL_MBRCONTROL] =
146 { 0x00, 0x00, 0x08, 0x03, 0x00, 0x00, 0x00, 0x01 },
147 [OPAL_MBR] =
148 { 0x00, 0x00, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00 },
149 [OPAL_AUTHORITY_TABLE] =
150 { 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00},
151 [OPAL_C_PIN_TABLE] =
152 { 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x00},
153 [OPAL_LOCKING_INFO_TABLE] =
154 { 0x00, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x01 },
155 [OPAL_ENTERPRISE_LOCKING_INFO_TABLE] =
156 { 0x00, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x00 },
158 /* C_PIN_TABLE object ID's */
160 [OPAL_C_PIN_MSID] =
161 { 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x84, 0x02},
162 [OPAL_C_PIN_SID] =
163 { 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x01},
164 [OPAL_C_PIN_ADMIN1] =
165 { 0x00, 0x00, 0x00, 0x0B, 0x00, 0x01, 0x00, 0x01},
167 /* half UID's (only first 4 bytes used) */
169 [OPAL_HALF_UID_AUTHORITY_OBJ_REF] =
170 { 0x00, 0x00, 0x0C, 0x05, 0xff, 0xff, 0xff, 0xff },
171 [OPAL_HALF_UID_BOOLEAN_ACE] =
172 { 0x00, 0x00, 0x04, 0x0E, 0xff, 0xff, 0xff, 0xff },
174 /* special value for omitted optional parameter */
175 [OPAL_UID_HEXFF] =
176 { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
180 * TCG Storage SSC Methods.
181 * Derived from: TCG_Storage_Architecture_Core_Spec_v2.01_r1.00
182 * Section: 6.3 Assigned UIDs
184 static const u8 opalmethod[][OPAL_UID_LENGTH] = {
185 [OPAL_PROPERTIES] =
186 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x01 },
187 [OPAL_STARTSESSION] =
188 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x02 },
189 [OPAL_REVERT] =
190 { 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x02, 0x02 },
191 [OPAL_ACTIVATE] =
192 { 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x02, 0x03 },
193 [OPAL_EGET] =
194 { 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06 },
195 [OPAL_ESET] =
196 { 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x07 },
197 [OPAL_NEXT] =
198 { 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x08 },
199 [OPAL_EAUTHENTICATE] =
200 { 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0c },
201 [OPAL_GETACL] =
202 { 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0d },
203 [OPAL_GENKEY] =
204 { 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x10 },
205 [OPAL_REVERTSP] =
206 { 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x11 },
207 [OPAL_GET] =
208 { 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x16 },
209 [OPAL_SET] =
210 { 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x17 },
211 [OPAL_AUTHENTICATE] =
212 { 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x1c },
213 [OPAL_RANDOM] =
214 { 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x01 },
215 [OPAL_ERASE] =
216 { 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x08, 0x03 },
219 static int end_opal_session_error(struct opal_dev *dev);
221 struct opal_suspend_data {
222 struct opal_lock_unlock unlk;
223 u8 lr;
224 struct list_head node;
228 * Derived from:
229 * TCG_Storage_Architecture_Core_Spec_v2.01_r1.00
230 * Section: 5.1.5 Method Status Codes
232 static const char * const opal_errors[] = {
233 "Success",
234 "Not Authorized",
235 "Unknown Error",
236 "SP Busy",
237 "SP Failed",
238 "SP Disabled",
239 "SP Frozen",
240 "No Sessions Available",
241 "Uniqueness Conflict",
242 "Insufficient Space",
243 "Insufficient Rows",
244 "Invalid Function",
245 "Invalid Parameter",
246 "Invalid Reference",
247 "Unknown Error",
248 "TPER Malfunction",
249 "Transaction Failure",
250 "Response Overflow",
251 "Authority Locked Out",
254 static const char *opal_error_to_human(int error)
256 if (error == 0x3f)
257 return "Failed";
259 if (error >= ARRAY_SIZE(opal_errors) || error < 0)
260 return "Unknown Error";
262 return opal_errors[error];
265 static void print_buffer(const u8 *ptr, u32 length)
267 #ifdef DEBUG
268 print_hex_dump_bytes("OPAL: ", DUMP_PREFIX_OFFSET, ptr, length);
269 pr_debug("\n");
270 #endif
273 static bool check_tper(const void *data)
275 const struct d0_tper_features *tper = data;
276 u8 flags = tper->supported_features;
278 if (!(flags & TPER_SYNC_SUPPORTED)) {
279 pr_debug("TPer sync not supported. flags = %d\n",
280 tper->supported_features);
281 return false;
284 return true;
287 static bool check_mbrenabled(const void *data)
289 const struct d0_locking_features *lfeat = data;
290 u8 sup_feat = lfeat->supported_features;
292 return !!(sup_feat & MBR_ENABLED_MASK);
295 static bool check_sum(const void *data)
297 const struct d0_single_user_mode *sum = data;
298 u32 nlo = be32_to_cpu(sum->num_locking_objects);
300 if (nlo == 0) {
301 pr_debug("Need at least one locking object.\n");
302 return false;
305 pr_debug("Number of locking objects: %d\n", nlo);
307 return true;
310 static u16 get_comid_v100(const void *data)
312 const struct d0_opal_v100 *v100 = data;
314 return be16_to_cpu(v100->baseComID);
317 static u16 get_comid_v200(const void *data)
319 const struct d0_opal_v200 *v200 = data;
321 return be16_to_cpu(v200->baseComID);
324 static int opal_send_cmd(struct opal_dev *dev)
326 return dev->send_recv(dev->data, dev->comid, TCG_SECP_01,
327 dev->cmd, IO_BUFFER_LENGTH,
328 true);
331 static int opal_recv_cmd(struct opal_dev *dev)
333 return dev->send_recv(dev->data, dev->comid, TCG_SECP_01,
334 dev->resp, IO_BUFFER_LENGTH,
335 false);
338 static int opal_recv_check(struct opal_dev *dev)
340 size_t buflen = IO_BUFFER_LENGTH;
341 void *buffer = dev->resp;
342 struct opal_header *hdr = buffer;
343 int ret;
345 do {
346 pr_debug("Sent OPAL command: outstanding=%d, minTransfer=%d\n",
347 hdr->cp.outstandingData,
348 hdr->cp.minTransfer);
350 if (hdr->cp.outstandingData == 0 ||
351 hdr->cp.minTransfer != 0)
352 return 0;
354 memset(buffer, 0, buflen);
355 ret = opal_recv_cmd(dev);
356 } while (!ret);
358 return ret;
361 static int opal_send_recv(struct opal_dev *dev, cont_fn *cont)
363 int ret;
365 ret = opal_send_cmd(dev);
366 if (ret)
367 return ret;
368 ret = opal_recv_cmd(dev);
369 if (ret)
370 return ret;
371 ret = opal_recv_check(dev);
372 if (ret)
373 return ret;
374 return cont(dev);
377 static void check_geometry(struct opal_dev *dev, const void *data)
379 const struct d0_geometry_features *geo = data;
381 dev->align = geo->alignment_granularity;
382 dev->lowest_lba = geo->lowest_aligned_lba;
385 static int next(struct opal_dev *dev)
387 const struct opal_step *step;
388 int state = 0, error = 0;
390 do {
391 step = &dev->steps[state];
392 if (!step->fn)
393 break;
395 error = step->fn(dev, step->data);
396 if (error) {
397 pr_debug("Error on step function: %d with error %d: %s\n",
398 state, error,
399 opal_error_to_human(error));
401 /* For each OPAL command we do a discovery0 then we
402 * start some sort of session.
403 * If we haven't passed state 1 then there was an error
404 * on discovery0 or during the attempt to start a
405 * session. Therefore we shouldn't attempt to terminate
406 * a session, as one has not yet been created.
408 if (state > 1) {
409 end_opal_session_error(dev);
410 return error;
414 state++;
415 } while (!error);
417 return error;
420 static int opal_discovery0_end(struct opal_dev *dev)
422 bool found_com_id = false, supported = true, single_user = false;
423 const struct d0_header *hdr = (struct d0_header *)dev->resp;
424 const u8 *epos = dev->resp, *cpos = dev->resp;
425 u16 comid = 0;
426 u32 hlen = be32_to_cpu(hdr->length);
428 print_buffer(dev->resp, hlen);
429 dev->mbr_enabled = false;
431 if (hlen > IO_BUFFER_LENGTH - sizeof(*hdr)) {
432 pr_debug("Discovery length overflows buffer (%zu+%u)/%u\n",
433 sizeof(*hdr), hlen, IO_BUFFER_LENGTH);
434 return -EFAULT;
437 epos += hlen; /* end of buffer */
438 cpos += sizeof(*hdr); /* current position on buffer */
440 while (cpos < epos && supported) {
441 const struct d0_features *body =
442 (const struct d0_features *)cpos;
444 switch (be16_to_cpu(body->code)) {
445 case FC_TPER:
446 supported = check_tper(body->features);
447 break;
448 case FC_SINGLEUSER:
449 single_user = check_sum(body->features);
450 break;
451 case FC_GEOMETRY:
452 check_geometry(dev, body);
453 break;
454 case FC_LOCKING:
455 dev->mbr_enabled = check_mbrenabled(body->features);
456 break;
457 case FC_ENTERPRISE:
458 case FC_DATASTORE:
459 /* some ignored properties */
460 pr_debug("Found OPAL feature description: %d\n",
461 be16_to_cpu(body->code));
462 break;
463 case FC_OPALV100:
464 comid = get_comid_v100(body->features);
465 found_com_id = true;
466 break;
467 case FC_OPALV200:
468 comid = get_comid_v200(body->features);
469 found_com_id = true;
470 break;
471 case 0xbfff ... 0xffff:
472 /* vendor specific, just ignore */
473 break;
474 default:
475 pr_debug("OPAL Unknown feature: %d\n",
476 be16_to_cpu(body->code));
479 cpos += body->length + 4;
482 if (!supported) {
483 pr_debug("This device is not Opal enabled. Not Supported!\n");
484 return -EOPNOTSUPP;
487 if (!single_user)
488 pr_debug("Device doesn't support single user mode\n");
491 if (!found_com_id) {
492 pr_debug("Could not find OPAL comid for device. Returning early\n");
493 return -EOPNOTSUPP;
496 dev->comid = comid;
498 return 0;
501 static int opal_discovery0(struct opal_dev *dev, void *data)
503 int ret;
505 memset(dev->resp, 0, IO_BUFFER_LENGTH);
506 dev->comid = OPAL_DISCOVERY_COMID;
507 ret = opal_recv_cmd(dev);
508 if (ret)
509 return ret;
510 return opal_discovery0_end(dev);
513 static void add_token_u8(int *err, struct opal_dev *cmd, u8 tok)
515 if (*err)
516 return;
517 if (cmd->pos >= IO_BUFFER_LENGTH - 1) {
518 pr_debug("Error adding u8: end of buffer.\n");
519 *err = -ERANGE;
520 return;
522 cmd->cmd[cmd->pos++] = tok;
525 static void add_short_atom_header(struct opal_dev *cmd, bool bytestring,
526 bool has_sign, int len)
528 u8 atom;
529 int err = 0;
531 atom = SHORT_ATOM_ID;
532 atom |= bytestring ? SHORT_ATOM_BYTESTRING : 0;
533 atom |= has_sign ? SHORT_ATOM_SIGNED : 0;
534 atom |= len & SHORT_ATOM_LEN_MASK;
536 add_token_u8(&err, cmd, atom);
539 static void add_medium_atom_header(struct opal_dev *cmd, bool bytestring,
540 bool has_sign, int len)
542 u8 header0;
544 header0 = MEDIUM_ATOM_ID;
545 header0 |= bytestring ? MEDIUM_ATOM_BYTESTRING : 0;
546 header0 |= has_sign ? MEDIUM_ATOM_SIGNED : 0;
547 header0 |= (len >> 8) & MEDIUM_ATOM_LEN_MASK;
548 cmd->cmd[cmd->pos++] = header0;
549 cmd->cmd[cmd->pos++] = len;
552 static void add_token_u64(int *err, struct opal_dev *cmd, u64 number)
555 size_t len;
556 int msb;
558 if (!(number & ~TINY_ATOM_DATA_MASK)) {
559 add_token_u8(err, cmd, number);
560 return;
563 msb = fls64(number);
564 len = DIV_ROUND_UP(msb, 8);
566 if (cmd->pos >= IO_BUFFER_LENGTH - len - 1) {
567 pr_debug("Error adding u64: end of buffer.\n");
568 *err = -ERANGE;
569 return;
571 add_short_atom_header(cmd, false, false, len);
572 while (len--)
573 add_token_u8(err, cmd, number >> (len * 8));
576 static void add_token_bytestring(int *err, struct opal_dev *cmd,
577 const u8 *bytestring, size_t len)
579 size_t header_len = 1;
580 bool is_short_atom = true;
582 if (*err)
583 return;
585 if (len & ~SHORT_ATOM_LEN_MASK) {
586 header_len = 2;
587 is_short_atom = false;
590 if (len >= IO_BUFFER_LENGTH - cmd->pos - header_len) {
591 pr_debug("Error adding bytestring: end of buffer.\n");
592 *err = -ERANGE;
593 return;
596 if (is_short_atom)
597 add_short_atom_header(cmd, true, false, len);
598 else
599 add_medium_atom_header(cmd, true, false, len);
601 memcpy(&cmd->cmd[cmd->pos], bytestring, len);
602 cmd->pos += len;
606 static int build_locking_range(u8 *buffer, size_t length, u8 lr)
608 if (length > OPAL_UID_LENGTH) {
609 pr_debug("Can't build locking range. Length OOB\n");
610 return -ERANGE;
613 memcpy(buffer, opaluid[OPAL_LOCKINGRANGE_GLOBAL], OPAL_UID_LENGTH);
615 if (lr == 0)
616 return 0;
617 buffer[5] = LOCKING_RANGE_NON_GLOBAL;
618 buffer[7] = lr;
620 return 0;
623 static int build_locking_user(u8 *buffer, size_t length, u8 lr)
625 if (length > OPAL_UID_LENGTH) {
626 pr_debug("Can't build locking range user, Length OOB\n");
627 return -ERANGE;
630 memcpy(buffer, opaluid[OPAL_USER1_UID], OPAL_UID_LENGTH);
632 buffer[7] = lr + 1;
634 return 0;
637 static void set_comid(struct opal_dev *cmd, u16 comid)
639 struct opal_header *hdr = (struct opal_header *)cmd->cmd;
641 hdr->cp.extendedComID[0] = comid >> 8;
642 hdr->cp.extendedComID[1] = comid;
643 hdr->cp.extendedComID[2] = 0;
644 hdr->cp.extendedComID[3] = 0;
647 static int cmd_finalize(struct opal_dev *cmd, u32 hsn, u32 tsn)
649 struct opal_header *hdr;
650 int err = 0;
652 add_token_u8(&err, cmd, OPAL_ENDOFDATA);
653 add_token_u8(&err, cmd, OPAL_STARTLIST);
654 add_token_u8(&err, cmd, 0);
655 add_token_u8(&err, cmd, 0);
656 add_token_u8(&err, cmd, 0);
657 add_token_u8(&err, cmd, OPAL_ENDLIST);
659 if (err) {
660 pr_debug("Error finalizing command.\n");
661 return -EFAULT;
664 hdr = (struct opal_header *) cmd->cmd;
666 hdr->pkt.tsn = cpu_to_be32(tsn);
667 hdr->pkt.hsn = cpu_to_be32(hsn);
669 hdr->subpkt.length = cpu_to_be32(cmd->pos - sizeof(*hdr));
670 while (cmd->pos % 4) {
671 if (cmd->pos >= IO_BUFFER_LENGTH) {
672 pr_debug("Error: Buffer overrun\n");
673 return -ERANGE;
675 cmd->cmd[cmd->pos++] = 0;
677 hdr->pkt.length = cpu_to_be32(cmd->pos - sizeof(hdr->cp) -
678 sizeof(hdr->pkt));
679 hdr->cp.length = cpu_to_be32(cmd->pos - sizeof(hdr->cp));
681 return 0;
684 static const struct opal_resp_tok *response_get_token(
685 const struct parsed_resp *resp,
686 int n)
688 const struct opal_resp_tok *tok;
690 if (n >= resp->num) {
691 pr_debug("Token number doesn't exist: %d, resp: %d\n",
692 n, resp->num);
693 return ERR_PTR(-EINVAL);
696 tok = &resp->toks[n];
697 if (tok->len == 0) {
698 pr_debug("Token length must be non-zero\n");
699 return ERR_PTR(-EINVAL);
702 return tok;
705 static ssize_t response_parse_tiny(struct opal_resp_tok *tok,
706 const u8 *pos)
708 tok->pos = pos;
709 tok->len = 1;
710 tok->width = OPAL_WIDTH_TINY;
712 if (pos[0] & TINY_ATOM_SIGNED) {
713 tok->type = OPAL_DTA_TOKENID_SINT;
714 } else {
715 tok->type = OPAL_DTA_TOKENID_UINT;
716 tok->stored.u = pos[0] & 0x3f;
719 return tok->len;
722 static ssize_t response_parse_short(struct opal_resp_tok *tok,
723 const u8 *pos)
725 tok->pos = pos;
726 tok->len = (pos[0] & SHORT_ATOM_LEN_MASK) + 1;
727 tok->width = OPAL_WIDTH_SHORT;
729 if (pos[0] & SHORT_ATOM_BYTESTRING) {
730 tok->type = OPAL_DTA_TOKENID_BYTESTRING;
731 } else if (pos[0] & SHORT_ATOM_SIGNED) {
732 tok->type = OPAL_DTA_TOKENID_SINT;
733 } else {
734 u64 u_integer = 0;
735 ssize_t i, b = 0;
737 tok->type = OPAL_DTA_TOKENID_UINT;
738 if (tok->len > 9) {
739 pr_debug("uint64 with more than 8 bytes\n");
740 return -EINVAL;
742 for (i = tok->len - 1; i > 0; i--) {
743 u_integer |= ((u64)pos[i] << (8 * b));
744 b++;
746 tok->stored.u = u_integer;
749 return tok->len;
752 static ssize_t response_parse_medium(struct opal_resp_tok *tok,
753 const u8 *pos)
755 tok->pos = pos;
756 tok->len = (((pos[0] & MEDIUM_ATOM_LEN_MASK) << 8) | pos[1]) + 2;
757 tok->width = OPAL_WIDTH_MEDIUM;
759 if (pos[0] & MEDIUM_ATOM_BYTESTRING)
760 tok->type = OPAL_DTA_TOKENID_BYTESTRING;
761 else if (pos[0] & MEDIUM_ATOM_SIGNED)
762 tok->type = OPAL_DTA_TOKENID_SINT;
763 else
764 tok->type = OPAL_DTA_TOKENID_UINT;
766 return tok->len;
769 static ssize_t response_parse_long(struct opal_resp_tok *tok,
770 const u8 *pos)
772 tok->pos = pos;
773 tok->len = ((pos[1] << 16) | (pos[2] << 8) | pos[3]) + 4;
774 tok->width = OPAL_WIDTH_LONG;
776 if (pos[0] & LONG_ATOM_BYTESTRING)
777 tok->type = OPAL_DTA_TOKENID_BYTESTRING;
778 else if (pos[0] & LONG_ATOM_SIGNED)
779 tok->type = OPAL_DTA_TOKENID_SINT;
780 else
781 tok->type = OPAL_DTA_TOKENID_UINT;
783 return tok->len;
786 static ssize_t response_parse_token(struct opal_resp_tok *tok,
787 const u8 *pos)
789 tok->pos = pos;
790 tok->len = 1;
791 tok->type = OPAL_DTA_TOKENID_TOKEN;
792 tok->width = OPAL_WIDTH_TOKEN;
794 return tok->len;
797 static int response_parse(const u8 *buf, size_t length,
798 struct parsed_resp *resp)
800 const struct opal_header *hdr;
801 struct opal_resp_tok *iter;
802 int num_entries = 0;
803 int total;
804 ssize_t token_length;
805 const u8 *pos;
806 u32 clen, plen, slen;
808 if (!buf)
809 return -EFAULT;
811 if (!resp)
812 return -EFAULT;
814 hdr = (struct opal_header *)buf;
815 pos = buf;
816 pos += sizeof(*hdr);
818 clen = be32_to_cpu(hdr->cp.length);
819 plen = be32_to_cpu(hdr->pkt.length);
820 slen = be32_to_cpu(hdr->subpkt.length);
821 pr_debug("Response size: cp: %u, pkt: %u, subpkt: %u\n",
822 clen, plen, slen);
824 if (clen == 0 || plen == 0 || slen == 0 ||
825 slen > IO_BUFFER_LENGTH - sizeof(*hdr)) {
826 pr_debug("Bad header length. cp: %u, pkt: %u, subpkt: %u\n",
827 clen, plen, slen);
828 print_buffer(pos, sizeof(*hdr));
829 return -EINVAL;
832 if (pos > buf + length)
833 return -EFAULT;
835 iter = resp->toks;
836 total = slen;
837 print_buffer(pos, total);
838 while (total > 0) {
839 if (pos[0] <= TINY_ATOM_BYTE) /* tiny atom */
840 token_length = response_parse_tiny(iter, pos);
841 else if (pos[0] <= SHORT_ATOM_BYTE) /* short atom */
842 token_length = response_parse_short(iter, pos);
843 else if (pos[0] <= MEDIUM_ATOM_BYTE) /* medium atom */
844 token_length = response_parse_medium(iter, pos);
845 else if (pos[0] <= LONG_ATOM_BYTE) /* long atom */
846 token_length = response_parse_long(iter, pos);
847 else /* TOKEN */
848 token_length = response_parse_token(iter, pos);
850 if (token_length < 0)
851 return token_length;
853 pos += token_length;
854 total -= token_length;
855 iter++;
856 num_entries++;
859 if (num_entries == 0) {
860 pr_debug("Couldn't parse response.\n");
861 return -EINVAL;
863 resp->num = num_entries;
865 return 0;
868 static size_t response_get_string(const struct parsed_resp *resp, int n,
869 const char **store)
871 u8 skip;
872 const struct opal_resp_tok *token;
874 *store = NULL;
875 if (!resp) {
876 pr_debug("Response is NULL\n");
877 return 0;
880 if (n >= resp->num) {
881 pr_debug("Response has %d tokens. Can't access %d\n",
882 resp->num, n);
883 return 0;
886 token = &resp->toks[n];
887 if (token->type != OPAL_DTA_TOKENID_BYTESTRING) {
888 pr_debug("Token is not a byte string!\n");
889 return 0;
892 switch (token->width) {
893 case OPAL_WIDTH_TINY:
894 case OPAL_WIDTH_SHORT:
895 skip = 1;
896 break;
897 case OPAL_WIDTH_MEDIUM:
898 skip = 2;
899 break;
900 case OPAL_WIDTH_LONG:
901 skip = 4;
902 break;
903 default:
904 pr_debug("Token has invalid width!\n");
905 return 0;
908 *store = token->pos + skip;
909 return token->len - skip;
912 static u64 response_get_u64(const struct parsed_resp *resp, int n)
914 if (!resp) {
915 pr_debug("Response is NULL\n");
916 return 0;
919 if (n >= resp->num) {
920 pr_debug("Response has %d tokens. Can't access %d\n",
921 resp->num, n);
922 return 0;
925 if (resp->toks[n].type != OPAL_DTA_TOKENID_UINT) {
926 pr_debug("Token is not unsigned it: %d\n",
927 resp->toks[n].type);
928 return 0;
931 if (!(resp->toks[n].width == OPAL_WIDTH_TINY ||
932 resp->toks[n].width == OPAL_WIDTH_SHORT)) {
933 pr_debug("Atom is not short or tiny: %d\n",
934 resp->toks[n].width);
935 return 0;
938 return resp->toks[n].stored.u;
941 static bool response_token_matches(const struct opal_resp_tok *token, u8 match)
943 if (IS_ERR(token) ||
944 token->type != OPAL_DTA_TOKENID_TOKEN ||
945 token->pos[0] != match)
946 return false;
947 return true;
950 static u8 response_status(const struct parsed_resp *resp)
952 const struct opal_resp_tok *tok;
954 tok = response_get_token(resp, 0);
955 if (response_token_matches(tok, OPAL_ENDOFSESSION))
956 return 0;
958 if (resp->num < 5)
959 return DTAERROR_NO_METHOD_STATUS;
961 tok = response_get_token(resp, resp->num - 5);
962 if (!response_token_matches(tok, OPAL_STARTLIST))
963 return DTAERROR_NO_METHOD_STATUS;
965 tok = response_get_token(resp, resp->num - 1);
966 if (!response_token_matches(tok, OPAL_ENDLIST))
967 return DTAERROR_NO_METHOD_STATUS;
969 return response_get_u64(resp, resp->num - 4);
972 /* Parses and checks for errors */
973 static int parse_and_check_status(struct opal_dev *dev)
975 int error;
977 print_buffer(dev->cmd, dev->pos);
979 error = response_parse(dev->resp, IO_BUFFER_LENGTH, &dev->parsed);
980 if (error) {
981 pr_debug("Couldn't parse response.\n");
982 return error;
985 return response_status(&dev->parsed);
988 static void clear_opal_cmd(struct opal_dev *dev)
990 dev->pos = sizeof(struct opal_header);
991 memset(dev->cmd, 0, IO_BUFFER_LENGTH);
994 static int start_opal_session_cont(struct opal_dev *dev)
996 u32 hsn, tsn;
997 int error = 0;
999 error = parse_and_check_status(dev);
1000 if (error)
1001 return error;
1003 hsn = response_get_u64(&dev->parsed, 4);
1004 tsn = response_get_u64(&dev->parsed, 5);
1006 if (hsn == 0 && tsn == 0) {
1007 pr_debug("Couldn't authenticate session\n");
1008 return -EPERM;
1011 dev->hsn = hsn;
1012 dev->tsn = tsn;
1013 return 0;
1016 static void add_suspend_info(struct opal_dev *dev,
1017 struct opal_suspend_data *sus)
1019 struct opal_suspend_data *iter;
1021 list_for_each_entry(iter, &dev->unlk_lst, node) {
1022 if (iter->lr == sus->lr) {
1023 list_del(&iter->node);
1024 kfree(iter);
1025 break;
1028 list_add_tail(&sus->node, &dev->unlk_lst);
1031 static int end_session_cont(struct opal_dev *dev)
1033 dev->hsn = 0;
1034 dev->tsn = 0;
1035 return parse_and_check_status(dev);
1038 static int finalize_and_send(struct opal_dev *dev, cont_fn cont)
1040 int ret;
1042 ret = cmd_finalize(dev, dev->hsn, dev->tsn);
1043 if (ret) {
1044 pr_debug("Error finalizing command buffer: %d\n", ret);
1045 return ret;
1048 print_buffer(dev->cmd, dev->pos);
1050 return opal_send_recv(dev, cont);
1053 static int gen_key(struct opal_dev *dev, void *data)
1055 u8 uid[OPAL_UID_LENGTH];
1056 int err = 0;
1058 clear_opal_cmd(dev);
1059 set_comid(dev, dev->comid);
1061 memcpy(uid, dev->prev_data, min(sizeof(uid), dev->prev_d_len));
1062 kfree(dev->prev_data);
1063 dev->prev_data = NULL;
1065 add_token_u8(&err, dev, OPAL_CALL);
1066 add_token_bytestring(&err, dev, uid, OPAL_UID_LENGTH);
1067 add_token_bytestring(&err, dev, opalmethod[OPAL_GENKEY],
1068 OPAL_UID_LENGTH);
1069 add_token_u8(&err, dev, OPAL_STARTLIST);
1070 add_token_u8(&err, dev, OPAL_ENDLIST);
1072 if (err) {
1073 pr_debug("Error building gen key command\n");
1074 return err;
1077 return finalize_and_send(dev, parse_and_check_status);
1080 static int get_active_key_cont(struct opal_dev *dev)
1082 const char *activekey;
1083 size_t keylen;
1084 int error = 0;
1086 error = parse_and_check_status(dev);
1087 if (error)
1088 return error;
1089 keylen = response_get_string(&dev->parsed, 4, &activekey);
1090 if (!activekey) {
1091 pr_debug("%s: Couldn't extract the Activekey from the response\n",
1092 __func__);
1093 return OPAL_INVAL_PARAM;
1095 dev->prev_data = kmemdup(activekey, keylen, GFP_KERNEL);
1097 if (!dev->prev_data)
1098 return -ENOMEM;
1100 dev->prev_d_len = keylen;
1102 return 0;
1105 static int get_active_key(struct opal_dev *dev, void *data)
1107 u8 uid[OPAL_UID_LENGTH];
1108 int err = 0;
1109 u8 *lr = data;
1111 clear_opal_cmd(dev);
1112 set_comid(dev, dev->comid);
1114 err = build_locking_range(uid, sizeof(uid), *lr);
1115 if (err)
1116 return err;
1118 err = 0;
1119 add_token_u8(&err, dev, OPAL_CALL);
1120 add_token_bytestring(&err, dev, uid, OPAL_UID_LENGTH);
1121 add_token_bytestring(&err, dev, opalmethod[OPAL_GET], OPAL_UID_LENGTH);
1122 add_token_u8(&err, dev, OPAL_STARTLIST);
1123 add_token_u8(&err, dev, OPAL_STARTLIST);
1124 add_token_u8(&err, dev, OPAL_STARTNAME);
1125 add_token_u8(&err, dev, 3); /* startCloumn */
1126 add_token_u8(&err, dev, 10); /* ActiveKey */
1127 add_token_u8(&err, dev, OPAL_ENDNAME);
1128 add_token_u8(&err, dev, OPAL_STARTNAME);
1129 add_token_u8(&err, dev, 4); /* endColumn */
1130 add_token_u8(&err, dev, 10); /* ActiveKey */
1131 add_token_u8(&err, dev, OPAL_ENDNAME);
1132 add_token_u8(&err, dev, OPAL_ENDLIST);
1133 add_token_u8(&err, dev, OPAL_ENDLIST);
1134 if (err) {
1135 pr_debug("Error building get active key command\n");
1136 return err;
1139 return finalize_and_send(dev, get_active_key_cont);
1142 static int generic_lr_enable_disable(struct opal_dev *dev,
1143 u8 *uid, bool rle, bool wle,
1144 bool rl, bool wl)
1146 int err = 0;
1148 add_token_u8(&err, dev, OPAL_CALL);
1149 add_token_bytestring(&err, dev, uid, OPAL_UID_LENGTH);
1150 add_token_bytestring(&err, dev, opalmethod[OPAL_SET], OPAL_UID_LENGTH);
1152 add_token_u8(&err, dev, OPAL_STARTLIST);
1153 add_token_u8(&err, dev, OPAL_STARTNAME);
1154 add_token_u8(&err, dev, OPAL_VALUES);
1155 add_token_u8(&err, dev, OPAL_STARTLIST);
1157 add_token_u8(&err, dev, OPAL_STARTNAME);
1158 add_token_u8(&err, dev, 5); /* ReadLockEnabled */
1159 add_token_u8(&err, dev, rle);
1160 add_token_u8(&err, dev, OPAL_ENDNAME);
1162 add_token_u8(&err, dev, OPAL_STARTNAME);
1163 add_token_u8(&err, dev, 6); /* WriteLockEnabled */
1164 add_token_u8(&err, dev, wle);
1165 add_token_u8(&err, dev, OPAL_ENDNAME);
1167 add_token_u8(&err, dev, OPAL_STARTNAME);
1168 add_token_u8(&err, dev, OPAL_READLOCKED);
1169 add_token_u8(&err, dev, rl);
1170 add_token_u8(&err, dev, OPAL_ENDNAME);
1172 add_token_u8(&err, dev, OPAL_STARTNAME);
1173 add_token_u8(&err, dev, OPAL_WRITELOCKED);
1174 add_token_u8(&err, dev, wl);
1175 add_token_u8(&err, dev, OPAL_ENDNAME);
1177 add_token_u8(&err, dev, OPAL_ENDLIST);
1178 add_token_u8(&err, dev, OPAL_ENDNAME);
1179 add_token_u8(&err, dev, OPAL_ENDLIST);
1180 return err;
1183 static inline int enable_global_lr(struct opal_dev *dev, u8 *uid,
1184 struct opal_user_lr_setup *setup)
1186 int err;
1188 err = generic_lr_enable_disable(dev, uid, !!setup->RLE, !!setup->WLE,
1189 0, 0);
1190 if (err)
1191 pr_debug("Failed to create enable global lr command\n");
1192 return err;
1195 static int setup_locking_range(struct opal_dev *dev, void *data)
1197 u8 uid[OPAL_UID_LENGTH];
1198 struct opal_user_lr_setup *setup = data;
1199 u8 lr;
1200 int err = 0;
1202 clear_opal_cmd(dev);
1203 set_comid(dev, dev->comid);
1205 lr = setup->session.opal_key.lr;
1206 err = build_locking_range(uid, sizeof(uid), lr);
1207 if (err)
1208 return err;
1210 if (lr == 0)
1211 err = enable_global_lr(dev, uid, setup);
1212 else {
1213 add_token_u8(&err, dev, OPAL_CALL);
1214 add_token_bytestring(&err, dev, uid, OPAL_UID_LENGTH);
1215 add_token_bytestring(&err, dev, opalmethod[OPAL_SET],
1216 OPAL_UID_LENGTH);
1218 add_token_u8(&err, dev, OPAL_STARTLIST);
1219 add_token_u8(&err, dev, OPAL_STARTNAME);
1220 add_token_u8(&err, dev, OPAL_VALUES);
1221 add_token_u8(&err, dev, OPAL_STARTLIST);
1223 add_token_u8(&err, dev, OPAL_STARTNAME);
1224 add_token_u8(&err, dev, 3); /* Ranges Start */
1225 add_token_u64(&err, dev, setup->range_start);
1226 add_token_u8(&err, dev, OPAL_ENDNAME);
1228 add_token_u8(&err, dev, OPAL_STARTNAME);
1229 add_token_u8(&err, dev, 4); /* Ranges length */
1230 add_token_u64(&err, dev, setup->range_length);
1231 add_token_u8(&err, dev, OPAL_ENDNAME);
1233 add_token_u8(&err, dev, OPAL_STARTNAME);
1234 add_token_u8(&err, dev, 5); /*ReadLockEnabled */
1235 add_token_u64(&err, dev, !!setup->RLE);
1236 add_token_u8(&err, dev, OPAL_ENDNAME);
1238 add_token_u8(&err, dev, OPAL_STARTNAME);
1239 add_token_u8(&err, dev, 6); /*WriteLockEnabled*/
1240 add_token_u64(&err, dev, !!setup->WLE);
1241 add_token_u8(&err, dev, OPAL_ENDNAME);
1243 add_token_u8(&err, dev, OPAL_ENDLIST);
1244 add_token_u8(&err, dev, OPAL_ENDNAME);
1245 add_token_u8(&err, dev, OPAL_ENDLIST);
1248 if (err) {
1249 pr_debug("Error building Setup Locking range command.\n");
1250 return err;
1254 return finalize_and_send(dev, parse_and_check_status);
1257 static int start_generic_opal_session(struct opal_dev *dev,
1258 enum opal_uid auth,
1259 enum opal_uid sp_type,
1260 const char *key,
1261 u8 key_len)
1263 u32 hsn;
1264 int err = 0;
1266 if (key == NULL && auth != OPAL_ANYBODY_UID)
1267 return OPAL_INVAL_PARAM;
1269 clear_opal_cmd(dev);
1271 set_comid(dev, dev->comid);
1272 hsn = GENERIC_HOST_SESSION_NUM;
1274 add_token_u8(&err, dev, OPAL_CALL);
1275 add_token_bytestring(&err, dev, opaluid[OPAL_SMUID_UID],
1276 OPAL_UID_LENGTH);
1277 add_token_bytestring(&err, dev, opalmethod[OPAL_STARTSESSION],
1278 OPAL_UID_LENGTH);
1279 add_token_u8(&err, dev, OPAL_STARTLIST);
1280 add_token_u64(&err, dev, hsn);
1281 add_token_bytestring(&err, dev, opaluid[sp_type], OPAL_UID_LENGTH);
1282 add_token_u8(&err, dev, 1);
1284 switch (auth) {
1285 case OPAL_ANYBODY_UID:
1286 add_token_u8(&err, dev, OPAL_ENDLIST);
1287 break;
1288 case OPAL_ADMIN1_UID:
1289 case OPAL_SID_UID:
1290 add_token_u8(&err, dev, OPAL_STARTNAME);
1291 add_token_u8(&err, dev, 0); /* HostChallenge */
1292 add_token_bytestring(&err, dev, key, key_len);
1293 add_token_u8(&err, dev, OPAL_ENDNAME);
1294 add_token_u8(&err, dev, OPAL_STARTNAME);
1295 add_token_u8(&err, dev, 3); /* HostSignAuth */
1296 add_token_bytestring(&err, dev, opaluid[auth],
1297 OPAL_UID_LENGTH);
1298 add_token_u8(&err, dev, OPAL_ENDNAME);
1299 add_token_u8(&err, dev, OPAL_ENDLIST);
1300 break;
1301 default:
1302 pr_debug("Cannot start Admin SP session with auth %d\n", auth);
1303 return OPAL_INVAL_PARAM;
1306 if (err) {
1307 pr_debug("Error building start adminsp session command.\n");
1308 return err;
1311 return finalize_and_send(dev, start_opal_session_cont);
1314 static int start_anybodyASP_opal_session(struct opal_dev *dev, void *data)
1316 return start_generic_opal_session(dev, OPAL_ANYBODY_UID,
1317 OPAL_ADMINSP_UID, NULL, 0);
1320 static int start_SIDASP_opal_session(struct opal_dev *dev, void *data)
1322 int ret;
1323 const u8 *key = dev->prev_data;
1325 if (!key) {
1326 const struct opal_key *okey = data;
1327 ret = start_generic_opal_session(dev, OPAL_SID_UID,
1328 OPAL_ADMINSP_UID,
1329 okey->key,
1330 okey->key_len);
1331 } else {
1332 ret = start_generic_opal_session(dev, OPAL_SID_UID,
1333 OPAL_ADMINSP_UID,
1334 key, dev->prev_d_len);
1335 kfree(key);
1336 dev->prev_data = NULL;
1338 return ret;
1341 static int start_admin1LSP_opal_session(struct opal_dev *dev, void *data)
1343 struct opal_key *key = data;
1344 return start_generic_opal_session(dev, OPAL_ADMIN1_UID,
1345 OPAL_LOCKINGSP_UID,
1346 key->key, key->key_len);
1349 static int start_auth_opal_session(struct opal_dev *dev, void *data)
1351 struct opal_session_info *session = data;
1352 u8 lk_ul_user[OPAL_UID_LENGTH];
1353 size_t keylen = session->opal_key.key_len;
1354 int err = 0;
1356 u8 *key = session->opal_key.key;
1357 u32 hsn = GENERIC_HOST_SESSION_NUM;
1359 clear_opal_cmd(dev);
1360 set_comid(dev, dev->comid);
1362 if (session->sum) {
1363 err = build_locking_user(lk_ul_user, sizeof(lk_ul_user),
1364 session->opal_key.lr);
1365 if (err)
1366 return err;
1368 } else if (session->who != OPAL_ADMIN1 && !session->sum) {
1369 err = build_locking_user(lk_ul_user, sizeof(lk_ul_user),
1370 session->who - 1);
1371 if (err)
1372 return err;
1373 } else
1374 memcpy(lk_ul_user, opaluid[OPAL_ADMIN1_UID], OPAL_UID_LENGTH);
1376 add_token_u8(&err, dev, OPAL_CALL);
1377 add_token_bytestring(&err, dev, opaluid[OPAL_SMUID_UID],
1378 OPAL_UID_LENGTH);
1379 add_token_bytestring(&err, dev, opalmethod[OPAL_STARTSESSION],
1380 OPAL_UID_LENGTH);
1382 add_token_u8(&err, dev, OPAL_STARTLIST);
1383 add_token_u64(&err, dev, hsn);
1384 add_token_bytestring(&err, dev, opaluid[OPAL_LOCKINGSP_UID],
1385 OPAL_UID_LENGTH);
1386 add_token_u8(&err, dev, 1);
1387 add_token_u8(&err, dev, OPAL_STARTNAME);
1388 add_token_u8(&err, dev, 0);
1389 add_token_bytestring(&err, dev, key, keylen);
1390 add_token_u8(&err, dev, OPAL_ENDNAME);
1391 add_token_u8(&err, dev, OPAL_STARTNAME);
1392 add_token_u8(&err, dev, 3);
1393 add_token_bytestring(&err, dev, lk_ul_user, OPAL_UID_LENGTH);
1394 add_token_u8(&err, dev, OPAL_ENDNAME);
1395 add_token_u8(&err, dev, OPAL_ENDLIST);
1397 if (err) {
1398 pr_debug("Error building STARTSESSION command.\n");
1399 return err;
1402 return finalize_and_send(dev, start_opal_session_cont);
1405 static int revert_tper(struct opal_dev *dev, void *data)
1407 int err = 0;
1409 clear_opal_cmd(dev);
1410 set_comid(dev, dev->comid);
1412 add_token_u8(&err, dev, OPAL_CALL);
1413 add_token_bytestring(&err, dev, opaluid[OPAL_ADMINSP_UID],
1414 OPAL_UID_LENGTH);
1415 add_token_bytestring(&err, dev, opalmethod[OPAL_REVERT],
1416 OPAL_UID_LENGTH);
1417 add_token_u8(&err, dev, OPAL_STARTLIST);
1418 add_token_u8(&err, dev, OPAL_ENDLIST);
1419 if (err) {
1420 pr_debug("Error building REVERT TPER command.\n");
1421 return err;
1424 return finalize_and_send(dev, parse_and_check_status);
1427 static int internal_activate_user(struct opal_dev *dev, void *data)
1429 struct opal_session_info *session = data;
1430 u8 uid[OPAL_UID_LENGTH];
1431 int err = 0;
1433 clear_opal_cmd(dev);
1434 set_comid(dev, dev->comid);
1436 memcpy(uid, opaluid[OPAL_USER1_UID], OPAL_UID_LENGTH);
1437 uid[7] = session->who;
1439 add_token_u8(&err, dev, OPAL_CALL);
1440 add_token_bytestring(&err, dev, uid, OPAL_UID_LENGTH);
1441 add_token_bytestring(&err, dev, opalmethod[OPAL_SET], OPAL_UID_LENGTH);
1442 add_token_u8(&err, dev, OPAL_STARTLIST);
1443 add_token_u8(&err, dev, OPAL_STARTNAME);
1444 add_token_u8(&err, dev, OPAL_VALUES);
1445 add_token_u8(&err, dev, OPAL_STARTLIST);
1446 add_token_u8(&err, dev, OPAL_STARTNAME);
1447 add_token_u8(&err, dev, 5); /* Enabled */
1448 add_token_u8(&err, dev, OPAL_TRUE);
1449 add_token_u8(&err, dev, OPAL_ENDNAME);
1450 add_token_u8(&err, dev, OPAL_ENDLIST);
1451 add_token_u8(&err, dev, OPAL_ENDNAME);
1452 add_token_u8(&err, dev, OPAL_ENDLIST);
1454 if (err) {
1455 pr_debug("Error building Activate UserN command.\n");
1456 return err;
1459 return finalize_and_send(dev, parse_and_check_status);
1462 static int erase_locking_range(struct opal_dev *dev, void *data)
1464 struct opal_session_info *session = data;
1465 u8 uid[OPAL_UID_LENGTH];
1466 int err = 0;
1468 clear_opal_cmd(dev);
1469 set_comid(dev, dev->comid);
1471 if (build_locking_range(uid, sizeof(uid), session->opal_key.lr) < 0)
1472 return -ERANGE;
1474 add_token_u8(&err, dev, OPAL_CALL);
1475 add_token_bytestring(&err, dev, uid, OPAL_UID_LENGTH);
1476 add_token_bytestring(&err, dev, opalmethod[OPAL_ERASE],
1477 OPAL_UID_LENGTH);
1478 add_token_u8(&err, dev, OPAL_STARTLIST);
1479 add_token_u8(&err, dev, OPAL_ENDLIST);
1481 if (err) {
1482 pr_debug("Error building Erase Locking Range Command.\n");
1483 return err;
1485 return finalize_and_send(dev, parse_and_check_status);
1488 static int set_mbr_done(struct opal_dev *dev, void *data)
1490 u8 *mbr_done_tf = data;
1491 int err = 0;
1493 clear_opal_cmd(dev);
1494 set_comid(dev, dev->comid);
1496 add_token_u8(&err, dev, OPAL_CALL);
1497 add_token_bytestring(&err, dev, opaluid[OPAL_MBRCONTROL],
1498 OPAL_UID_LENGTH);
1499 add_token_bytestring(&err, dev, opalmethod[OPAL_SET], OPAL_UID_LENGTH);
1500 add_token_u8(&err, dev, OPAL_STARTLIST);
1501 add_token_u8(&err, dev, OPAL_STARTNAME);
1502 add_token_u8(&err, dev, OPAL_VALUES);
1503 add_token_u8(&err, dev, OPAL_STARTLIST);
1504 add_token_u8(&err, dev, OPAL_STARTNAME);
1505 add_token_u8(&err, dev, 2); /* Done */
1506 add_token_u8(&err, dev, *mbr_done_tf); /* Done T or F */
1507 add_token_u8(&err, dev, OPAL_ENDNAME);
1508 add_token_u8(&err, dev, OPAL_ENDLIST);
1509 add_token_u8(&err, dev, OPAL_ENDNAME);
1510 add_token_u8(&err, dev, OPAL_ENDLIST);
1512 if (err) {
1513 pr_debug("Error Building set MBR Done command\n");
1514 return err;
1517 return finalize_and_send(dev, parse_and_check_status);
1520 static int set_mbr_enable_disable(struct opal_dev *dev, void *data)
1522 u8 *mbr_en_dis = data;
1523 int err = 0;
1525 clear_opal_cmd(dev);
1526 set_comid(dev, dev->comid);
1528 add_token_u8(&err, dev, OPAL_CALL);
1529 add_token_bytestring(&err, dev, opaluid[OPAL_MBRCONTROL],
1530 OPAL_UID_LENGTH);
1531 add_token_bytestring(&err, dev, opalmethod[OPAL_SET], OPAL_UID_LENGTH);
1532 add_token_u8(&err, dev, OPAL_STARTLIST);
1533 add_token_u8(&err, dev, OPAL_STARTNAME);
1534 add_token_u8(&err, dev, OPAL_VALUES);
1535 add_token_u8(&err, dev, OPAL_STARTLIST);
1536 add_token_u8(&err, dev, OPAL_STARTNAME);
1537 add_token_u8(&err, dev, 1);
1538 add_token_u8(&err, dev, *mbr_en_dis);
1539 add_token_u8(&err, dev, OPAL_ENDNAME);
1540 add_token_u8(&err, dev, OPAL_ENDLIST);
1541 add_token_u8(&err, dev, OPAL_ENDNAME);
1542 add_token_u8(&err, dev, OPAL_ENDLIST);
1544 if (err) {
1545 pr_debug("Error Building set MBR done command\n");
1546 return err;
1549 return finalize_and_send(dev, parse_and_check_status);
1552 static int generic_pw_cmd(u8 *key, size_t key_len, u8 *cpin_uid,
1553 struct opal_dev *dev)
1555 int err = 0;
1557 clear_opal_cmd(dev);
1558 set_comid(dev, dev->comid);
1560 add_token_u8(&err, dev, OPAL_CALL);
1561 add_token_bytestring(&err, dev, cpin_uid, OPAL_UID_LENGTH);
1562 add_token_bytestring(&err, dev, opalmethod[OPAL_SET],
1563 OPAL_UID_LENGTH);
1564 add_token_u8(&err, dev, OPAL_STARTLIST);
1565 add_token_u8(&err, dev, OPAL_STARTNAME);
1566 add_token_u8(&err, dev, OPAL_VALUES);
1567 add_token_u8(&err, dev, OPAL_STARTLIST);
1568 add_token_u8(&err, dev, OPAL_STARTNAME);
1569 add_token_u8(&err, dev, 3); /* PIN */
1570 add_token_bytestring(&err, dev, key, key_len);
1571 add_token_u8(&err, dev, OPAL_ENDNAME);
1572 add_token_u8(&err, dev, OPAL_ENDLIST);
1573 add_token_u8(&err, dev, OPAL_ENDNAME);
1574 add_token_u8(&err, dev, OPAL_ENDLIST);
1576 return err;
1579 static int set_new_pw(struct opal_dev *dev, void *data)
1581 u8 cpin_uid[OPAL_UID_LENGTH];
1582 struct opal_session_info *usr = data;
1584 memcpy(cpin_uid, opaluid[OPAL_C_PIN_ADMIN1], OPAL_UID_LENGTH);
1586 if (usr->who != OPAL_ADMIN1) {
1587 cpin_uid[5] = 0x03;
1588 if (usr->sum)
1589 cpin_uid[7] = usr->opal_key.lr + 1;
1590 else
1591 cpin_uid[7] = usr->who;
1594 if (generic_pw_cmd(usr->opal_key.key, usr->opal_key.key_len,
1595 cpin_uid, dev)) {
1596 pr_debug("Error building set password command.\n");
1597 return -ERANGE;
1600 return finalize_and_send(dev, parse_and_check_status);
1603 static int set_sid_cpin_pin(struct opal_dev *dev, void *data)
1605 u8 cpin_uid[OPAL_UID_LENGTH];
1606 struct opal_key *key = data;
1608 memcpy(cpin_uid, opaluid[OPAL_C_PIN_SID], OPAL_UID_LENGTH);
1610 if (generic_pw_cmd(key->key, key->key_len, cpin_uid, dev)) {
1611 pr_debug("Error building Set SID cpin\n");
1612 return -ERANGE;
1614 return finalize_and_send(dev, parse_and_check_status);
1617 static int add_user_to_lr(struct opal_dev *dev, void *data)
1619 u8 lr_buffer[OPAL_UID_LENGTH];
1620 u8 user_uid[OPAL_UID_LENGTH];
1621 struct opal_lock_unlock *lkul = data;
1622 int err = 0;
1624 clear_opal_cmd(dev);
1625 set_comid(dev, dev->comid);
1627 memcpy(lr_buffer, opaluid[OPAL_LOCKINGRANGE_ACE_RDLOCKED],
1628 OPAL_UID_LENGTH);
1630 if (lkul->l_state == OPAL_RW)
1631 memcpy(lr_buffer, opaluid[OPAL_LOCKINGRANGE_ACE_WRLOCKED],
1632 OPAL_UID_LENGTH);
1634 lr_buffer[7] = lkul->session.opal_key.lr;
1636 memcpy(user_uid, opaluid[OPAL_USER1_UID], OPAL_UID_LENGTH);
1638 user_uid[7] = lkul->session.who;
1640 add_token_u8(&err, dev, OPAL_CALL);
1641 add_token_bytestring(&err, dev, lr_buffer, OPAL_UID_LENGTH);
1642 add_token_bytestring(&err, dev, opalmethod[OPAL_SET],
1643 OPAL_UID_LENGTH);
1645 add_token_u8(&err, dev, OPAL_STARTLIST);
1646 add_token_u8(&err, dev, OPAL_STARTNAME);
1647 add_token_u8(&err, dev, OPAL_VALUES);
1649 add_token_u8(&err, dev, OPAL_STARTLIST);
1650 add_token_u8(&err, dev, OPAL_STARTNAME);
1651 add_token_u8(&err, dev, 3);
1653 add_token_u8(&err, dev, OPAL_STARTLIST);
1656 add_token_u8(&err, dev, OPAL_STARTNAME);
1657 add_token_bytestring(&err, dev,
1658 opaluid[OPAL_HALF_UID_AUTHORITY_OBJ_REF],
1659 OPAL_UID_LENGTH/2);
1660 add_token_bytestring(&err, dev, user_uid, OPAL_UID_LENGTH);
1661 add_token_u8(&err, dev, OPAL_ENDNAME);
1664 add_token_u8(&err, dev, OPAL_STARTNAME);
1665 add_token_bytestring(&err, dev,
1666 opaluid[OPAL_HALF_UID_AUTHORITY_OBJ_REF],
1667 OPAL_UID_LENGTH/2);
1668 add_token_bytestring(&err, dev, user_uid, OPAL_UID_LENGTH);
1669 add_token_u8(&err, dev, OPAL_ENDNAME);
1672 add_token_u8(&err, dev, OPAL_STARTNAME);
1673 add_token_bytestring(&err, dev, opaluid[OPAL_HALF_UID_BOOLEAN_ACE],
1674 OPAL_UID_LENGTH/2);
1675 add_token_u8(&err, dev, 1);
1676 add_token_u8(&err, dev, OPAL_ENDNAME);
1679 add_token_u8(&err, dev, OPAL_ENDLIST);
1680 add_token_u8(&err, dev, OPAL_ENDNAME);
1681 add_token_u8(&err, dev, OPAL_ENDLIST);
1682 add_token_u8(&err, dev, OPAL_ENDNAME);
1683 add_token_u8(&err, dev, OPAL_ENDLIST);
1685 if (err) {
1686 pr_debug("Error building add user to locking range command.\n");
1687 return err;
1690 return finalize_and_send(dev, parse_and_check_status);
1693 static int lock_unlock_locking_range(struct opal_dev *dev, void *data)
1695 u8 lr_buffer[OPAL_UID_LENGTH];
1696 struct opal_lock_unlock *lkul = data;
1697 u8 read_locked = 1, write_locked = 1;
1698 int err = 0;
1700 clear_opal_cmd(dev);
1701 set_comid(dev, dev->comid);
1703 if (build_locking_range(lr_buffer, sizeof(lr_buffer),
1704 lkul->session.opal_key.lr) < 0)
1705 return -ERANGE;
1707 switch (lkul->l_state) {
1708 case OPAL_RO:
1709 read_locked = 0;
1710 write_locked = 1;
1711 break;
1712 case OPAL_RW:
1713 read_locked = 0;
1714 write_locked = 0;
1715 break;
1716 case OPAL_LK:
1717 /* vars are initalized to locked */
1718 break;
1719 default:
1720 pr_debug("Tried to set an invalid locking state... returning to uland\n");
1721 return OPAL_INVAL_PARAM;
1724 add_token_u8(&err, dev, OPAL_CALL);
1725 add_token_bytestring(&err, dev, lr_buffer, OPAL_UID_LENGTH);
1726 add_token_bytestring(&err, dev, opalmethod[OPAL_SET], OPAL_UID_LENGTH);
1727 add_token_u8(&err, dev, OPAL_STARTLIST);
1728 add_token_u8(&err, dev, OPAL_STARTNAME);
1729 add_token_u8(&err, dev, OPAL_VALUES);
1730 add_token_u8(&err, dev, OPAL_STARTLIST);
1732 add_token_u8(&err, dev, OPAL_STARTNAME);
1733 add_token_u8(&err, dev, OPAL_READLOCKED);
1734 add_token_u8(&err, dev, read_locked);
1735 add_token_u8(&err, dev, OPAL_ENDNAME);
1737 add_token_u8(&err, dev, OPAL_STARTNAME);
1738 add_token_u8(&err, dev, OPAL_WRITELOCKED);
1739 add_token_u8(&err, dev, write_locked);
1740 add_token_u8(&err, dev, OPAL_ENDNAME);
1742 add_token_u8(&err, dev, OPAL_ENDLIST);
1743 add_token_u8(&err, dev, OPAL_ENDNAME);
1744 add_token_u8(&err, dev, OPAL_ENDLIST);
1746 if (err) {
1747 pr_debug("Error building SET command.\n");
1748 return err;
1750 return finalize_and_send(dev, parse_and_check_status);
1754 static int lock_unlock_locking_range_sum(struct opal_dev *dev, void *data)
1756 u8 lr_buffer[OPAL_UID_LENGTH];
1757 u8 read_locked = 1, write_locked = 1;
1758 struct opal_lock_unlock *lkul = data;
1759 int ret;
1761 clear_opal_cmd(dev);
1762 set_comid(dev, dev->comid);
1764 if (build_locking_range(lr_buffer, sizeof(lr_buffer),
1765 lkul->session.opal_key.lr) < 0)
1766 return -ERANGE;
1768 switch (lkul->l_state) {
1769 case OPAL_RO:
1770 read_locked = 0;
1771 write_locked = 1;
1772 break;
1773 case OPAL_RW:
1774 read_locked = 0;
1775 write_locked = 0;
1776 break;
1777 case OPAL_LK:
1778 /* vars are initalized to locked */
1779 break;
1780 default:
1781 pr_debug("Tried to set an invalid locking state.\n");
1782 return OPAL_INVAL_PARAM;
1784 ret = generic_lr_enable_disable(dev, lr_buffer, 1, 1,
1785 read_locked, write_locked);
1787 if (ret < 0) {
1788 pr_debug("Error building SET command.\n");
1789 return ret;
1791 return finalize_and_send(dev, parse_and_check_status);
1794 static int activate_lsp(struct opal_dev *dev, void *data)
1796 struct opal_lr_act *opal_act = data;
1797 u8 user_lr[OPAL_UID_LENGTH];
1798 u8 uint_3 = 0x83;
1799 int err = 0, i;
1801 clear_opal_cmd(dev);
1802 set_comid(dev, dev->comid);
1804 add_token_u8(&err, dev, OPAL_CALL);
1805 add_token_bytestring(&err, dev, opaluid[OPAL_LOCKINGSP_UID],
1806 OPAL_UID_LENGTH);
1807 add_token_bytestring(&err, dev, opalmethod[OPAL_ACTIVATE],
1808 OPAL_UID_LENGTH);
1811 if (opal_act->sum) {
1812 err = build_locking_range(user_lr, sizeof(user_lr),
1813 opal_act->lr[0]);
1814 if (err)
1815 return err;
1817 add_token_u8(&err, dev, OPAL_STARTLIST);
1818 add_token_u8(&err, dev, OPAL_STARTNAME);
1819 add_token_u8(&err, dev, uint_3);
1820 add_token_u8(&err, dev, 6);
1821 add_token_u8(&err, dev, 0);
1822 add_token_u8(&err, dev, 0);
1824 add_token_u8(&err, dev, OPAL_STARTLIST);
1825 add_token_bytestring(&err, dev, user_lr, OPAL_UID_LENGTH);
1826 for (i = 1; i < opal_act->num_lrs; i++) {
1827 user_lr[7] = opal_act->lr[i];
1828 add_token_bytestring(&err, dev, user_lr, OPAL_UID_LENGTH);
1830 add_token_u8(&err, dev, OPAL_ENDLIST);
1831 add_token_u8(&err, dev, OPAL_ENDNAME);
1832 add_token_u8(&err, dev, OPAL_ENDLIST);
1834 } else {
1835 add_token_u8(&err, dev, OPAL_STARTLIST);
1836 add_token_u8(&err, dev, OPAL_ENDLIST);
1839 if (err) {
1840 pr_debug("Error building Activate LockingSP command.\n");
1841 return err;
1844 return finalize_and_send(dev, parse_and_check_status);
1847 static int get_lsp_lifecycle_cont(struct opal_dev *dev)
1849 u8 lc_status;
1850 int error = 0;
1852 error = parse_and_check_status(dev);
1853 if (error)
1854 return error;
1856 lc_status = response_get_u64(&dev->parsed, 4);
1857 /* 0x08 is Manufacured Inactive */
1858 /* 0x09 is Manufactured */
1859 if (lc_status != OPAL_MANUFACTURED_INACTIVE) {
1860 pr_debug("Couldn't determine the status of the Lifecycle state\n");
1861 return -ENODEV;
1864 return 0;
1867 /* Determine if we're in the Manufactured Inactive or Active state */
1868 static int get_lsp_lifecycle(struct opal_dev *dev, void *data)
1870 int err = 0;
1872 clear_opal_cmd(dev);
1873 set_comid(dev, dev->comid);
1875 add_token_u8(&err, dev, OPAL_CALL);
1876 add_token_bytestring(&err, dev, opaluid[OPAL_LOCKINGSP_UID],
1877 OPAL_UID_LENGTH);
1878 add_token_bytestring(&err, dev, opalmethod[OPAL_GET], OPAL_UID_LENGTH);
1880 add_token_u8(&err, dev, OPAL_STARTLIST);
1881 add_token_u8(&err, dev, OPAL_STARTLIST);
1883 add_token_u8(&err, dev, OPAL_STARTNAME);
1884 add_token_u8(&err, dev, 3); /* Start Column */
1885 add_token_u8(&err, dev, 6); /* Lifecycle Column */
1886 add_token_u8(&err, dev, OPAL_ENDNAME);
1888 add_token_u8(&err, dev, OPAL_STARTNAME);
1889 add_token_u8(&err, dev, 4); /* End Column */
1890 add_token_u8(&err, dev, 6); /* Lifecycle Column */
1891 add_token_u8(&err, dev, OPAL_ENDNAME);
1893 add_token_u8(&err, dev, OPAL_ENDLIST);
1894 add_token_u8(&err, dev, OPAL_ENDLIST);
1896 if (err) {
1897 pr_debug("Error Building GET Lifecycle Status command\n");
1898 return err;
1901 return finalize_and_send(dev, get_lsp_lifecycle_cont);
1904 static int get_msid_cpin_pin_cont(struct opal_dev *dev)
1906 const char *msid_pin;
1907 size_t strlen;
1908 int error = 0;
1910 error = parse_and_check_status(dev);
1911 if (error)
1912 return error;
1914 strlen = response_get_string(&dev->parsed, 4, &msid_pin);
1915 if (!msid_pin) {
1916 pr_debug("%s: Couldn't extract PIN from response\n", __func__);
1917 return OPAL_INVAL_PARAM;
1920 dev->prev_data = kmemdup(msid_pin, strlen, GFP_KERNEL);
1921 if (!dev->prev_data)
1922 return -ENOMEM;
1924 dev->prev_d_len = strlen;
1926 return 0;
1929 static int get_msid_cpin_pin(struct opal_dev *dev, void *data)
1931 int err = 0;
1933 clear_opal_cmd(dev);
1934 set_comid(dev, dev->comid);
1936 add_token_u8(&err, dev, OPAL_CALL);
1937 add_token_bytestring(&err, dev, opaluid[OPAL_C_PIN_MSID],
1938 OPAL_UID_LENGTH);
1939 add_token_bytestring(&err, dev, opalmethod[OPAL_GET], OPAL_UID_LENGTH);
1941 add_token_u8(&err, dev, OPAL_STARTLIST);
1942 add_token_u8(&err, dev, OPAL_STARTLIST);
1944 add_token_u8(&err, dev, OPAL_STARTNAME);
1945 add_token_u8(&err, dev, 3); /* Start Column */
1946 add_token_u8(&err, dev, 3); /* PIN */
1947 add_token_u8(&err, dev, OPAL_ENDNAME);
1949 add_token_u8(&err, dev, OPAL_STARTNAME);
1950 add_token_u8(&err, dev, 4); /* End Column */
1951 add_token_u8(&err, dev, 3); /* Lifecycle Column */
1952 add_token_u8(&err, dev, OPAL_ENDNAME);
1954 add_token_u8(&err, dev, OPAL_ENDLIST);
1955 add_token_u8(&err, dev, OPAL_ENDLIST);
1957 if (err) {
1958 pr_debug("Error building Get MSID CPIN PIN command.\n");
1959 return err;
1962 return finalize_and_send(dev, get_msid_cpin_pin_cont);
1965 static int end_opal_session(struct opal_dev *dev, void *data)
1967 int err = 0;
1969 clear_opal_cmd(dev);
1970 set_comid(dev, dev->comid);
1971 add_token_u8(&err, dev, OPAL_ENDOFSESSION);
1973 if (err < 0)
1974 return err;
1975 return finalize_and_send(dev, end_session_cont);
1978 static int end_opal_session_error(struct opal_dev *dev)
1980 const struct opal_step error_end_session[] = {
1981 { end_opal_session, },
1982 { NULL, }
1984 dev->steps = error_end_session;
1985 return next(dev);
1988 static inline void setup_opal_dev(struct opal_dev *dev,
1989 const struct opal_step *steps)
1991 dev->steps = steps;
1992 dev->tsn = 0;
1993 dev->hsn = 0;
1994 dev->prev_data = NULL;
1997 static int check_opal_support(struct opal_dev *dev)
1999 const struct opal_step steps[] = {
2000 { opal_discovery0, },
2001 { NULL, }
2003 int ret;
2005 mutex_lock(&dev->dev_lock);
2006 setup_opal_dev(dev, steps);
2007 ret = next(dev);
2008 dev->supported = !ret;
2009 mutex_unlock(&dev->dev_lock);
2010 return ret;
2013 static void clean_opal_dev(struct opal_dev *dev)
2016 struct opal_suspend_data *suspend, *next;
2018 mutex_lock(&dev->dev_lock);
2019 list_for_each_entry_safe(suspend, next, &dev->unlk_lst, node) {
2020 list_del(&suspend->node);
2021 kfree(suspend);
2023 mutex_unlock(&dev->dev_lock);
2026 void free_opal_dev(struct opal_dev *dev)
2028 if (!dev)
2029 return;
2030 clean_opal_dev(dev);
2031 kfree(dev);
2033 EXPORT_SYMBOL(free_opal_dev);
2035 struct opal_dev *init_opal_dev(void *data, sec_send_recv *send_recv)
2037 struct opal_dev *dev;
2039 dev = kmalloc(sizeof(*dev), GFP_KERNEL);
2040 if (!dev)
2041 return NULL;
2043 INIT_LIST_HEAD(&dev->unlk_lst);
2044 mutex_init(&dev->dev_lock);
2045 dev->data = data;
2046 dev->send_recv = send_recv;
2047 if (check_opal_support(dev) != 0) {
2048 pr_debug("Opal is not supported on this device\n");
2049 kfree(dev);
2050 return NULL;
2052 return dev;
2054 EXPORT_SYMBOL(init_opal_dev);
2056 static int opal_secure_erase_locking_range(struct opal_dev *dev,
2057 struct opal_session_info *opal_session)
2059 const struct opal_step erase_steps[] = {
2060 { opal_discovery0, },
2061 { start_auth_opal_session, opal_session },
2062 { get_active_key, &opal_session->opal_key.lr },
2063 { gen_key, },
2064 { end_opal_session, },
2065 { NULL, }
2067 int ret;
2069 mutex_lock(&dev->dev_lock);
2070 setup_opal_dev(dev, erase_steps);
2071 ret = next(dev);
2072 mutex_unlock(&dev->dev_lock);
2073 return ret;
2076 static int opal_erase_locking_range(struct opal_dev *dev,
2077 struct opal_session_info *opal_session)
2079 const struct opal_step erase_steps[] = {
2080 { opal_discovery0, },
2081 { start_auth_opal_session, opal_session },
2082 { erase_locking_range, opal_session },
2083 { end_opal_session, },
2084 { NULL, }
2086 int ret;
2088 mutex_lock(&dev->dev_lock);
2089 setup_opal_dev(dev, erase_steps);
2090 ret = next(dev);
2091 mutex_unlock(&dev->dev_lock);
2092 return ret;
2095 static int opal_enable_disable_shadow_mbr(struct opal_dev *dev,
2096 struct opal_mbr_data *opal_mbr)
2098 const struct opal_step mbr_steps[] = {
2099 { opal_discovery0, },
2100 { start_admin1LSP_opal_session, &opal_mbr->key },
2101 { set_mbr_done, &opal_mbr->enable_disable },
2102 { end_opal_session, },
2103 { start_admin1LSP_opal_session, &opal_mbr->key },
2104 { set_mbr_enable_disable, &opal_mbr->enable_disable },
2105 { end_opal_session, },
2106 { NULL, }
2108 int ret;
2110 if (opal_mbr->enable_disable != OPAL_MBR_ENABLE &&
2111 opal_mbr->enable_disable != OPAL_MBR_DISABLE)
2112 return -EINVAL;
2114 mutex_lock(&dev->dev_lock);
2115 setup_opal_dev(dev, mbr_steps);
2116 ret = next(dev);
2117 mutex_unlock(&dev->dev_lock);
2118 return ret;
2121 static int opal_save(struct opal_dev *dev, struct opal_lock_unlock *lk_unlk)
2123 struct opal_suspend_data *suspend;
2125 suspend = kzalloc(sizeof(*suspend), GFP_KERNEL);
2126 if (!suspend)
2127 return -ENOMEM;
2129 suspend->unlk = *lk_unlk;
2130 suspend->lr = lk_unlk->session.opal_key.lr;
2132 mutex_lock(&dev->dev_lock);
2133 setup_opal_dev(dev, NULL);
2134 add_suspend_info(dev, suspend);
2135 mutex_unlock(&dev->dev_lock);
2136 return 0;
2139 static int opal_add_user_to_lr(struct opal_dev *dev,
2140 struct opal_lock_unlock *lk_unlk)
2142 const struct opal_step steps[] = {
2143 { opal_discovery0, },
2144 { start_admin1LSP_opal_session, &lk_unlk->session.opal_key },
2145 { add_user_to_lr, lk_unlk },
2146 { end_opal_session, },
2147 { NULL, }
2149 int ret;
2151 if (lk_unlk->l_state != OPAL_RO &&
2152 lk_unlk->l_state != OPAL_RW) {
2153 pr_debug("Locking state was not RO or RW\n");
2154 return -EINVAL;
2156 if (lk_unlk->session.who < OPAL_USER1 ||
2157 lk_unlk->session.who > OPAL_USER9) {
2158 pr_debug("Authority was not within the range of users: %d\n",
2159 lk_unlk->session.who);
2160 return -EINVAL;
2162 if (lk_unlk->session.sum) {
2163 pr_debug("%s not supported in sum. Use setup locking range\n",
2164 __func__);
2165 return -EINVAL;
2168 mutex_lock(&dev->dev_lock);
2169 setup_opal_dev(dev, steps);
2170 ret = next(dev);
2171 mutex_unlock(&dev->dev_lock);
2172 return ret;
2175 static int opal_reverttper(struct opal_dev *dev, struct opal_key *opal)
2177 const struct opal_step revert_steps[] = {
2178 { opal_discovery0, },
2179 { start_SIDASP_opal_session, opal },
2180 { revert_tper, }, /* controller will terminate session */
2181 { NULL, }
2183 int ret;
2185 mutex_lock(&dev->dev_lock);
2186 setup_opal_dev(dev, revert_steps);
2187 ret = next(dev);
2188 mutex_unlock(&dev->dev_lock);
2191 * If we successfully reverted lets clean
2192 * any saved locking ranges.
2194 if (!ret)
2195 clean_opal_dev(dev);
2197 return ret;
2200 static int __opal_lock_unlock(struct opal_dev *dev,
2201 struct opal_lock_unlock *lk_unlk)
2203 const struct opal_step unlock_steps[] = {
2204 { opal_discovery0, },
2205 { start_auth_opal_session, &lk_unlk->session },
2206 { lock_unlock_locking_range, lk_unlk },
2207 { end_opal_session, },
2208 { NULL, }
2210 const struct opal_step unlock_sum_steps[] = {
2211 { opal_discovery0, },
2212 { start_auth_opal_session, &lk_unlk->session },
2213 { lock_unlock_locking_range_sum, lk_unlk },
2214 { end_opal_session, },
2215 { NULL, }
2218 dev->steps = lk_unlk->session.sum ? unlock_sum_steps : unlock_steps;
2219 return next(dev);
2222 static int __opal_set_mbr_done(struct opal_dev *dev, struct opal_key *key)
2224 u8 mbr_done_tf = 1;
2225 const struct opal_step mbrdone_step [] = {
2226 { opal_discovery0, },
2227 { start_admin1LSP_opal_session, key },
2228 { set_mbr_done, &mbr_done_tf },
2229 { end_opal_session, },
2230 { NULL, }
2233 dev->steps = mbrdone_step;
2234 return next(dev);
2237 static int opal_lock_unlock(struct opal_dev *dev,
2238 struct opal_lock_unlock *lk_unlk)
2240 int ret;
2242 if (lk_unlk->session.who < OPAL_ADMIN1 ||
2243 lk_unlk->session.who > OPAL_USER9)
2244 return -EINVAL;
2246 mutex_lock(&dev->dev_lock);
2247 ret = __opal_lock_unlock(dev, lk_unlk);
2248 mutex_unlock(&dev->dev_lock);
2249 return ret;
2252 static int opal_take_ownership(struct opal_dev *dev, struct opal_key *opal)
2254 const struct opal_step owner_steps[] = {
2255 { opal_discovery0, },
2256 { start_anybodyASP_opal_session, },
2257 { get_msid_cpin_pin, },
2258 { end_opal_session, },
2259 { start_SIDASP_opal_session, opal },
2260 { set_sid_cpin_pin, opal },
2261 { end_opal_session, },
2262 { NULL, }
2264 int ret;
2266 if (!dev)
2267 return -ENODEV;
2269 mutex_lock(&dev->dev_lock);
2270 setup_opal_dev(dev, owner_steps);
2271 ret = next(dev);
2272 mutex_unlock(&dev->dev_lock);
2273 return ret;
2276 static int opal_activate_lsp(struct opal_dev *dev, struct opal_lr_act *opal_lr_act)
2278 const struct opal_step active_steps[] = {
2279 { opal_discovery0, },
2280 { start_SIDASP_opal_session, &opal_lr_act->key },
2281 { get_lsp_lifecycle, },
2282 { activate_lsp, opal_lr_act },
2283 { end_opal_session, },
2284 { NULL, }
2286 int ret;
2288 if (!opal_lr_act->num_lrs || opal_lr_act->num_lrs > OPAL_MAX_LRS)
2289 return -EINVAL;
2291 mutex_lock(&dev->dev_lock);
2292 setup_opal_dev(dev, active_steps);
2293 ret = next(dev);
2294 mutex_unlock(&dev->dev_lock);
2295 return ret;
2298 static int opal_setup_locking_range(struct opal_dev *dev,
2299 struct opal_user_lr_setup *opal_lrs)
2301 const struct opal_step lr_steps[] = {
2302 { opal_discovery0, },
2303 { start_auth_opal_session, &opal_lrs->session },
2304 { setup_locking_range, opal_lrs },
2305 { end_opal_session, },
2306 { NULL, }
2308 int ret;
2310 mutex_lock(&dev->dev_lock);
2311 setup_opal_dev(dev, lr_steps);
2312 ret = next(dev);
2313 mutex_unlock(&dev->dev_lock);
2314 return ret;
2317 static int opal_set_new_pw(struct opal_dev *dev, struct opal_new_pw *opal_pw)
2319 const struct opal_step pw_steps[] = {
2320 { opal_discovery0, },
2321 { start_auth_opal_session, &opal_pw->session },
2322 { set_new_pw, &opal_pw->new_user_pw },
2323 { end_opal_session, },
2324 { NULL }
2326 int ret;
2328 if (opal_pw->session.who < OPAL_ADMIN1 ||
2329 opal_pw->session.who > OPAL_USER9 ||
2330 opal_pw->new_user_pw.who < OPAL_ADMIN1 ||
2331 opal_pw->new_user_pw.who > OPAL_USER9)
2332 return -EINVAL;
2334 mutex_lock(&dev->dev_lock);
2335 setup_opal_dev(dev, pw_steps);
2336 ret = next(dev);
2337 mutex_unlock(&dev->dev_lock);
2338 return ret;
2341 static int opal_activate_user(struct opal_dev *dev,
2342 struct opal_session_info *opal_session)
2344 const struct opal_step act_steps[] = {
2345 { opal_discovery0, },
2346 { start_admin1LSP_opal_session, &opal_session->opal_key },
2347 { internal_activate_user, opal_session },
2348 { end_opal_session, },
2349 { NULL, }
2351 int ret;
2353 /* We can't activate Admin1 it's active as manufactured */
2354 if (opal_session->who < OPAL_USER1 ||
2355 opal_session->who > OPAL_USER9) {
2356 pr_debug("Who was not a valid user: %d\n", opal_session->who);
2357 return -EINVAL;
2360 mutex_lock(&dev->dev_lock);
2361 setup_opal_dev(dev, act_steps);
2362 ret = next(dev);
2363 mutex_unlock(&dev->dev_lock);
2364 return ret;
2367 bool opal_unlock_from_suspend(struct opal_dev *dev)
2369 struct opal_suspend_data *suspend;
2370 bool was_failure = false;
2371 int ret = 0;
2373 if (!dev)
2374 return false;
2375 if (!dev->supported)
2376 return false;
2378 mutex_lock(&dev->dev_lock);
2379 setup_opal_dev(dev, NULL);
2381 list_for_each_entry(suspend, &dev->unlk_lst, node) {
2382 dev->tsn = 0;
2383 dev->hsn = 0;
2385 ret = __opal_lock_unlock(dev, &suspend->unlk);
2386 if (ret) {
2387 pr_debug("Failed to unlock LR %hhu with sum %d\n",
2388 suspend->unlk.session.opal_key.lr,
2389 suspend->unlk.session.sum);
2390 was_failure = true;
2392 if (dev->mbr_enabled) {
2393 ret = __opal_set_mbr_done(dev, &suspend->unlk.session.opal_key);
2394 if (ret)
2395 pr_debug("Failed to set MBR Done in S3 resume\n");
2398 mutex_unlock(&dev->dev_lock);
2399 return was_failure;
2401 EXPORT_SYMBOL(opal_unlock_from_suspend);
2403 int sed_ioctl(struct opal_dev *dev, unsigned int cmd, void __user *arg)
2405 void *p;
2406 int ret = -ENOTTY;
2408 if (!capable(CAP_SYS_ADMIN))
2409 return -EACCES;
2410 if (!dev)
2411 return -ENOTSUPP;
2412 if (!dev->supported)
2413 return -ENOTSUPP;
2415 p = memdup_user(arg, _IOC_SIZE(cmd));
2416 if (IS_ERR(p))
2417 return PTR_ERR(p);
2419 switch (cmd) {
2420 case IOC_OPAL_SAVE:
2421 ret = opal_save(dev, p);
2422 break;
2423 case IOC_OPAL_LOCK_UNLOCK:
2424 ret = opal_lock_unlock(dev, p);
2425 break;
2426 case IOC_OPAL_TAKE_OWNERSHIP:
2427 ret = opal_take_ownership(dev, p);
2428 break;
2429 case IOC_OPAL_ACTIVATE_LSP:
2430 ret = opal_activate_lsp(dev, p);
2431 break;
2432 case IOC_OPAL_SET_PW:
2433 ret = opal_set_new_pw(dev, p);
2434 break;
2435 case IOC_OPAL_ACTIVATE_USR:
2436 ret = opal_activate_user(dev, p);
2437 break;
2438 case IOC_OPAL_REVERT_TPR:
2439 ret = opal_reverttper(dev, p);
2440 break;
2441 case IOC_OPAL_LR_SETUP:
2442 ret = opal_setup_locking_range(dev, p);
2443 break;
2444 case IOC_OPAL_ADD_USR_TO_LR:
2445 ret = opal_add_user_to_lr(dev, p);
2446 break;
2447 case IOC_OPAL_ENABLE_DISABLE_MBR:
2448 ret = opal_enable_disable_shadow_mbr(dev, p);
2449 break;
2450 case IOC_OPAL_ERASE_LR:
2451 ret = opal_erase_locking_range(dev, p);
2452 break;
2453 case IOC_OPAL_SECURE_ERASE_LR:
2454 ret = opal_secure_erase_locking_range(dev, p);
2455 break;
2456 default:
2457 break;
2460 kfree(p);
2461 return ret;
2463 EXPORT_SYMBOL_GPL(sed_ioctl);