drivers/bus: Move Arm CCN PMU driver
[linux/fpc-iii.git] / block / sed-opal.c
blobe4929eec547fc4141a6b078e79d5fe2688a20198
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;
557 u8 n;
559 if (!(number & ~TINY_ATOM_DATA_MASK)) {
560 add_token_u8(err, cmd, number);
561 return;
564 msb = fls(number);
565 len = DIV_ROUND_UP(msb, 4);
567 if (cmd->pos >= IO_BUFFER_LENGTH - len - 1) {
568 pr_debug("Error adding u64: end of buffer.\n");
569 *err = -ERANGE;
570 return;
572 add_short_atom_header(cmd, false, false, len);
573 while (len--) {
574 n = number >> (len * 8);
575 add_token_u8(err, cmd, n);
579 static void add_token_bytestring(int *err, struct opal_dev *cmd,
580 const u8 *bytestring, size_t len)
582 size_t header_len = 1;
583 bool is_short_atom = true;
585 if (*err)
586 return;
588 if (len & ~SHORT_ATOM_LEN_MASK) {
589 header_len = 2;
590 is_short_atom = false;
593 if (len >= IO_BUFFER_LENGTH - cmd->pos - header_len) {
594 pr_debug("Error adding bytestring: end of buffer.\n");
595 *err = -ERANGE;
596 return;
599 if (is_short_atom)
600 add_short_atom_header(cmd, true, false, len);
601 else
602 add_medium_atom_header(cmd, true, false, len);
604 memcpy(&cmd->cmd[cmd->pos], bytestring, len);
605 cmd->pos += len;
609 static int build_locking_range(u8 *buffer, size_t length, u8 lr)
611 if (length > OPAL_UID_LENGTH) {
612 pr_debug("Can't build locking range. Length OOB\n");
613 return -ERANGE;
616 memcpy(buffer, opaluid[OPAL_LOCKINGRANGE_GLOBAL], OPAL_UID_LENGTH);
618 if (lr == 0)
619 return 0;
620 buffer[5] = LOCKING_RANGE_NON_GLOBAL;
621 buffer[7] = lr;
623 return 0;
626 static int build_locking_user(u8 *buffer, size_t length, u8 lr)
628 if (length > OPAL_UID_LENGTH) {
629 pr_debug("Can't build locking range user, Length OOB\n");
630 return -ERANGE;
633 memcpy(buffer, opaluid[OPAL_USER1_UID], OPAL_UID_LENGTH);
635 buffer[7] = lr + 1;
637 return 0;
640 static void set_comid(struct opal_dev *cmd, u16 comid)
642 struct opal_header *hdr = (struct opal_header *)cmd->cmd;
644 hdr->cp.extendedComID[0] = comid >> 8;
645 hdr->cp.extendedComID[1] = comid;
646 hdr->cp.extendedComID[2] = 0;
647 hdr->cp.extendedComID[3] = 0;
650 static int cmd_finalize(struct opal_dev *cmd, u32 hsn, u32 tsn)
652 struct opal_header *hdr;
653 int err = 0;
655 add_token_u8(&err, cmd, OPAL_ENDOFDATA);
656 add_token_u8(&err, cmd, OPAL_STARTLIST);
657 add_token_u8(&err, cmd, 0);
658 add_token_u8(&err, cmd, 0);
659 add_token_u8(&err, cmd, 0);
660 add_token_u8(&err, cmd, OPAL_ENDLIST);
662 if (err) {
663 pr_debug("Error finalizing command.\n");
664 return -EFAULT;
667 hdr = (struct opal_header *) cmd->cmd;
669 hdr->pkt.tsn = cpu_to_be32(tsn);
670 hdr->pkt.hsn = cpu_to_be32(hsn);
672 hdr->subpkt.length = cpu_to_be32(cmd->pos - sizeof(*hdr));
673 while (cmd->pos % 4) {
674 if (cmd->pos >= IO_BUFFER_LENGTH) {
675 pr_debug("Error: Buffer overrun\n");
676 return -ERANGE;
678 cmd->cmd[cmd->pos++] = 0;
680 hdr->pkt.length = cpu_to_be32(cmd->pos - sizeof(hdr->cp) -
681 sizeof(hdr->pkt));
682 hdr->cp.length = cpu_to_be32(cmd->pos - sizeof(hdr->cp));
684 return 0;
687 static const struct opal_resp_tok *response_get_token(
688 const struct parsed_resp *resp,
689 int n)
691 const struct opal_resp_tok *tok;
693 if (n >= resp->num) {
694 pr_debug("Token number doesn't exist: %d, resp: %d\n",
695 n, resp->num);
696 return ERR_PTR(-EINVAL);
699 tok = &resp->toks[n];
700 if (tok->len == 0) {
701 pr_debug("Token length must be non-zero\n");
702 return ERR_PTR(-EINVAL);
705 return tok;
708 static ssize_t response_parse_tiny(struct opal_resp_tok *tok,
709 const u8 *pos)
711 tok->pos = pos;
712 tok->len = 1;
713 tok->width = OPAL_WIDTH_TINY;
715 if (pos[0] & TINY_ATOM_SIGNED) {
716 tok->type = OPAL_DTA_TOKENID_SINT;
717 } else {
718 tok->type = OPAL_DTA_TOKENID_UINT;
719 tok->stored.u = pos[0] & 0x3f;
722 return tok->len;
725 static ssize_t response_parse_short(struct opal_resp_tok *tok,
726 const u8 *pos)
728 tok->pos = pos;
729 tok->len = (pos[0] & SHORT_ATOM_LEN_MASK) + 1;
730 tok->width = OPAL_WIDTH_SHORT;
732 if (pos[0] & SHORT_ATOM_BYTESTRING) {
733 tok->type = OPAL_DTA_TOKENID_BYTESTRING;
734 } else if (pos[0] & SHORT_ATOM_SIGNED) {
735 tok->type = OPAL_DTA_TOKENID_SINT;
736 } else {
737 u64 u_integer = 0;
738 ssize_t i, b = 0;
740 tok->type = OPAL_DTA_TOKENID_UINT;
741 if (tok->len > 9) {
742 pr_debug("uint64 with more than 8 bytes\n");
743 return -EINVAL;
745 for (i = tok->len - 1; i > 0; i--) {
746 u_integer |= ((u64)pos[i] << (8 * b));
747 b++;
749 tok->stored.u = u_integer;
752 return tok->len;
755 static ssize_t response_parse_medium(struct opal_resp_tok *tok,
756 const u8 *pos)
758 tok->pos = pos;
759 tok->len = (((pos[0] & MEDIUM_ATOM_LEN_MASK) << 8) | pos[1]) + 2;
760 tok->width = OPAL_WIDTH_MEDIUM;
762 if (pos[0] & MEDIUM_ATOM_BYTESTRING)
763 tok->type = OPAL_DTA_TOKENID_BYTESTRING;
764 else if (pos[0] & MEDIUM_ATOM_SIGNED)
765 tok->type = OPAL_DTA_TOKENID_SINT;
766 else
767 tok->type = OPAL_DTA_TOKENID_UINT;
769 return tok->len;
772 static ssize_t response_parse_long(struct opal_resp_tok *tok,
773 const u8 *pos)
775 tok->pos = pos;
776 tok->len = ((pos[1] << 16) | (pos[2] << 8) | pos[3]) + 4;
777 tok->width = OPAL_WIDTH_LONG;
779 if (pos[0] & LONG_ATOM_BYTESTRING)
780 tok->type = OPAL_DTA_TOKENID_BYTESTRING;
781 else if (pos[0] & LONG_ATOM_SIGNED)
782 tok->type = OPAL_DTA_TOKENID_SINT;
783 else
784 tok->type = OPAL_DTA_TOKENID_UINT;
786 return tok->len;
789 static ssize_t response_parse_token(struct opal_resp_tok *tok,
790 const u8 *pos)
792 tok->pos = pos;
793 tok->len = 1;
794 tok->type = OPAL_DTA_TOKENID_TOKEN;
795 tok->width = OPAL_WIDTH_TOKEN;
797 return tok->len;
800 static int response_parse(const u8 *buf, size_t length,
801 struct parsed_resp *resp)
803 const struct opal_header *hdr;
804 struct opal_resp_tok *iter;
805 int num_entries = 0;
806 int total;
807 ssize_t token_length;
808 const u8 *pos;
809 u32 clen, plen, slen;
811 if (!buf)
812 return -EFAULT;
814 if (!resp)
815 return -EFAULT;
817 hdr = (struct opal_header *)buf;
818 pos = buf;
819 pos += sizeof(*hdr);
821 clen = be32_to_cpu(hdr->cp.length);
822 plen = be32_to_cpu(hdr->pkt.length);
823 slen = be32_to_cpu(hdr->subpkt.length);
824 pr_debug("Response size: cp: %u, pkt: %u, subpkt: %u\n",
825 clen, plen, slen);
827 if (clen == 0 || plen == 0 || slen == 0 ||
828 slen > IO_BUFFER_LENGTH - sizeof(*hdr)) {
829 pr_debug("Bad header length. cp: %u, pkt: %u, subpkt: %u\n",
830 clen, plen, slen);
831 print_buffer(pos, sizeof(*hdr));
832 return -EINVAL;
835 if (pos > buf + length)
836 return -EFAULT;
838 iter = resp->toks;
839 total = slen;
840 print_buffer(pos, total);
841 while (total > 0) {
842 if (pos[0] <= TINY_ATOM_BYTE) /* tiny atom */
843 token_length = response_parse_tiny(iter, pos);
844 else if (pos[0] <= SHORT_ATOM_BYTE) /* short atom */
845 token_length = response_parse_short(iter, pos);
846 else if (pos[0] <= MEDIUM_ATOM_BYTE) /* medium atom */
847 token_length = response_parse_medium(iter, pos);
848 else if (pos[0] <= LONG_ATOM_BYTE) /* long atom */
849 token_length = response_parse_long(iter, pos);
850 else /* TOKEN */
851 token_length = response_parse_token(iter, pos);
853 if (token_length < 0)
854 return token_length;
856 pos += token_length;
857 total -= token_length;
858 iter++;
859 num_entries++;
862 if (num_entries == 0) {
863 pr_debug("Couldn't parse response.\n");
864 return -EINVAL;
866 resp->num = num_entries;
868 return 0;
871 static size_t response_get_string(const struct parsed_resp *resp, int n,
872 const char **store)
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 if (resp->toks[n].type != OPAL_DTA_TOKENID_BYTESTRING) {
887 pr_debug("Token is not a byte string!\n");
888 return 0;
891 *store = resp->toks[n].pos + 1;
892 return resp->toks[n].len - 1;
895 static u64 response_get_u64(const struct parsed_resp *resp, int n)
897 if (!resp) {
898 pr_debug("Response is NULL\n");
899 return 0;
902 if (n > resp->num) {
903 pr_debug("Response has %d tokens. Can't access %d\n",
904 resp->num, n);
905 return 0;
908 if (resp->toks[n].type != OPAL_DTA_TOKENID_UINT) {
909 pr_debug("Token is not unsigned it: %d\n",
910 resp->toks[n].type);
911 return 0;
914 if (!(resp->toks[n].width == OPAL_WIDTH_TINY ||
915 resp->toks[n].width == OPAL_WIDTH_SHORT)) {
916 pr_debug("Atom is not short or tiny: %d\n",
917 resp->toks[n].width);
918 return 0;
921 return resp->toks[n].stored.u;
924 static bool response_token_matches(const struct opal_resp_tok *token, u8 match)
926 if (IS_ERR(token) ||
927 token->type != OPAL_DTA_TOKENID_TOKEN ||
928 token->pos[0] != match)
929 return false;
930 return true;
933 static u8 response_status(const struct parsed_resp *resp)
935 const struct opal_resp_tok *tok;
937 tok = response_get_token(resp, 0);
938 if (response_token_matches(tok, OPAL_ENDOFSESSION))
939 return 0;
941 if (resp->num < 5)
942 return DTAERROR_NO_METHOD_STATUS;
944 tok = response_get_token(resp, resp->num - 5);
945 if (!response_token_matches(tok, OPAL_STARTLIST))
946 return DTAERROR_NO_METHOD_STATUS;
948 tok = response_get_token(resp, resp->num - 1);
949 if (!response_token_matches(tok, OPAL_ENDLIST))
950 return DTAERROR_NO_METHOD_STATUS;
952 return response_get_u64(resp, resp->num - 4);
955 /* Parses and checks for errors */
956 static int parse_and_check_status(struct opal_dev *dev)
958 int error;
960 print_buffer(dev->cmd, dev->pos);
962 error = response_parse(dev->resp, IO_BUFFER_LENGTH, &dev->parsed);
963 if (error) {
964 pr_debug("Couldn't parse response.\n");
965 return error;
968 return response_status(&dev->parsed);
971 static void clear_opal_cmd(struct opal_dev *dev)
973 dev->pos = sizeof(struct opal_header);
974 memset(dev->cmd, 0, IO_BUFFER_LENGTH);
977 static int start_opal_session_cont(struct opal_dev *dev)
979 u32 hsn, tsn;
980 int error = 0;
982 error = parse_and_check_status(dev);
983 if (error)
984 return error;
986 hsn = response_get_u64(&dev->parsed, 4);
987 tsn = response_get_u64(&dev->parsed, 5);
989 if (hsn == 0 && tsn == 0) {
990 pr_debug("Couldn't authenticate session\n");
991 return -EPERM;
994 dev->hsn = hsn;
995 dev->tsn = tsn;
996 return 0;
999 static void add_suspend_info(struct opal_dev *dev,
1000 struct opal_suspend_data *sus)
1002 struct opal_suspend_data *iter;
1004 list_for_each_entry(iter, &dev->unlk_lst, node) {
1005 if (iter->lr == sus->lr) {
1006 list_del(&iter->node);
1007 kfree(iter);
1008 break;
1011 list_add_tail(&sus->node, &dev->unlk_lst);
1014 static int end_session_cont(struct opal_dev *dev)
1016 dev->hsn = 0;
1017 dev->tsn = 0;
1018 return parse_and_check_status(dev);
1021 static int finalize_and_send(struct opal_dev *dev, cont_fn cont)
1023 int ret;
1025 ret = cmd_finalize(dev, dev->hsn, dev->tsn);
1026 if (ret) {
1027 pr_debug("Error finalizing command buffer: %d\n", ret);
1028 return ret;
1031 print_buffer(dev->cmd, dev->pos);
1033 return opal_send_recv(dev, cont);
1036 static int gen_key(struct opal_dev *dev, void *data)
1038 u8 uid[OPAL_UID_LENGTH];
1039 int err = 0;
1041 clear_opal_cmd(dev);
1042 set_comid(dev, dev->comid);
1044 memcpy(uid, dev->prev_data, min(sizeof(uid), dev->prev_d_len));
1045 kfree(dev->prev_data);
1046 dev->prev_data = NULL;
1048 add_token_u8(&err, dev, OPAL_CALL);
1049 add_token_bytestring(&err, dev, uid, OPAL_UID_LENGTH);
1050 add_token_bytestring(&err, dev, opalmethod[OPAL_GENKEY],
1051 OPAL_UID_LENGTH);
1052 add_token_u8(&err, dev, OPAL_STARTLIST);
1053 add_token_u8(&err, dev, OPAL_ENDLIST);
1055 if (err) {
1056 pr_debug("Error building gen key command\n");
1057 return err;
1060 return finalize_and_send(dev, parse_and_check_status);
1063 static int get_active_key_cont(struct opal_dev *dev)
1065 const char *activekey;
1066 size_t keylen;
1067 int error = 0;
1069 error = parse_and_check_status(dev);
1070 if (error)
1071 return error;
1072 keylen = response_get_string(&dev->parsed, 4, &activekey);
1073 if (!activekey) {
1074 pr_debug("%s: Couldn't extract the Activekey from the response\n",
1075 __func__);
1076 return OPAL_INVAL_PARAM;
1078 dev->prev_data = kmemdup(activekey, keylen, GFP_KERNEL);
1080 if (!dev->prev_data)
1081 return -ENOMEM;
1083 dev->prev_d_len = keylen;
1085 return 0;
1088 static int get_active_key(struct opal_dev *dev, void *data)
1090 u8 uid[OPAL_UID_LENGTH];
1091 int err = 0;
1092 u8 *lr = data;
1094 clear_opal_cmd(dev);
1095 set_comid(dev, dev->comid);
1097 err = build_locking_range(uid, sizeof(uid), *lr);
1098 if (err)
1099 return err;
1101 err = 0;
1102 add_token_u8(&err, dev, OPAL_CALL);
1103 add_token_bytestring(&err, dev, uid, OPAL_UID_LENGTH);
1104 add_token_bytestring(&err, dev, opalmethod[OPAL_GET], OPAL_UID_LENGTH);
1105 add_token_u8(&err, dev, OPAL_STARTLIST);
1106 add_token_u8(&err, dev, OPAL_STARTLIST);
1107 add_token_u8(&err, dev, OPAL_STARTNAME);
1108 add_token_u8(&err, dev, 3); /* startCloumn */
1109 add_token_u8(&err, dev, 10); /* ActiveKey */
1110 add_token_u8(&err, dev, OPAL_ENDNAME);
1111 add_token_u8(&err, dev, OPAL_STARTNAME);
1112 add_token_u8(&err, dev, 4); /* endColumn */
1113 add_token_u8(&err, dev, 10); /* ActiveKey */
1114 add_token_u8(&err, dev, OPAL_ENDNAME);
1115 add_token_u8(&err, dev, OPAL_ENDLIST);
1116 add_token_u8(&err, dev, OPAL_ENDLIST);
1117 if (err) {
1118 pr_debug("Error building get active key command\n");
1119 return err;
1122 return finalize_and_send(dev, get_active_key_cont);
1125 static int generic_lr_enable_disable(struct opal_dev *dev,
1126 u8 *uid, bool rle, bool wle,
1127 bool rl, bool wl)
1129 int err = 0;
1131 add_token_u8(&err, dev, OPAL_CALL);
1132 add_token_bytestring(&err, dev, uid, OPAL_UID_LENGTH);
1133 add_token_bytestring(&err, dev, opalmethod[OPAL_SET], OPAL_UID_LENGTH);
1135 add_token_u8(&err, dev, OPAL_STARTLIST);
1136 add_token_u8(&err, dev, OPAL_STARTNAME);
1137 add_token_u8(&err, dev, OPAL_VALUES);
1138 add_token_u8(&err, dev, OPAL_STARTLIST);
1140 add_token_u8(&err, dev, OPAL_STARTNAME);
1141 add_token_u8(&err, dev, 5); /* ReadLockEnabled */
1142 add_token_u8(&err, dev, rle);
1143 add_token_u8(&err, dev, OPAL_ENDNAME);
1145 add_token_u8(&err, dev, OPAL_STARTNAME);
1146 add_token_u8(&err, dev, 6); /* WriteLockEnabled */
1147 add_token_u8(&err, dev, wle);
1148 add_token_u8(&err, dev, OPAL_ENDNAME);
1150 add_token_u8(&err, dev, OPAL_STARTNAME);
1151 add_token_u8(&err, dev, OPAL_READLOCKED);
1152 add_token_u8(&err, dev, rl);
1153 add_token_u8(&err, dev, OPAL_ENDNAME);
1155 add_token_u8(&err, dev, OPAL_STARTNAME);
1156 add_token_u8(&err, dev, OPAL_WRITELOCKED);
1157 add_token_u8(&err, dev, wl);
1158 add_token_u8(&err, dev, OPAL_ENDNAME);
1160 add_token_u8(&err, dev, OPAL_ENDLIST);
1161 add_token_u8(&err, dev, OPAL_ENDNAME);
1162 add_token_u8(&err, dev, OPAL_ENDLIST);
1163 return err;
1166 static inline int enable_global_lr(struct opal_dev *dev, u8 *uid,
1167 struct opal_user_lr_setup *setup)
1169 int err;
1171 err = generic_lr_enable_disable(dev, uid, !!setup->RLE, !!setup->WLE,
1172 0, 0);
1173 if (err)
1174 pr_debug("Failed to create enable global lr command\n");
1175 return err;
1178 static int setup_locking_range(struct opal_dev *dev, void *data)
1180 u8 uid[OPAL_UID_LENGTH];
1181 struct opal_user_lr_setup *setup = data;
1182 u8 lr;
1183 int err = 0;
1185 clear_opal_cmd(dev);
1186 set_comid(dev, dev->comid);
1188 lr = setup->session.opal_key.lr;
1189 err = build_locking_range(uid, sizeof(uid), lr);
1190 if (err)
1191 return err;
1193 if (lr == 0)
1194 err = enable_global_lr(dev, uid, setup);
1195 else {
1196 add_token_u8(&err, dev, OPAL_CALL);
1197 add_token_bytestring(&err, dev, uid, OPAL_UID_LENGTH);
1198 add_token_bytestring(&err, dev, opalmethod[OPAL_SET],
1199 OPAL_UID_LENGTH);
1201 add_token_u8(&err, dev, OPAL_STARTLIST);
1202 add_token_u8(&err, dev, OPAL_STARTNAME);
1203 add_token_u8(&err, dev, OPAL_VALUES);
1204 add_token_u8(&err, dev, OPAL_STARTLIST);
1206 add_token_u8(&err, dev, OPAL_STARTNAME);
1207 add_token_u8(&err, dev, 3); /* Ranges Start */
1208 add_token_u64(&err, dev, setup->range_start);
1209 add_token_u8(&err, dev, OPAL_ENDNAME);
1211 add_token_u8(&err, dev, OPAL_STARTNAME);
1212 add_token_u8(&err, dev, 4); /* Ranges length */
1213 add_token_u64(&err, dev, setup->range_length);
1214 add_token_u8(&err, dev, OPAL_ENDNAME);
1216 add_token_u8(&err, dev, OPAL_STARTNAME);
1217 add_token_u8(&err, dev, 5); /*ReadLockEnabled */
1218 add_token_u64(&err, dev, !!setup->RLE);
1219 add_token_u8(&err, dev, OPAL_ENDNAME);
1221 add_token_u8(&err, dev, OPAL_STARTNAME);
1222 add_token_u8(&err, dev, 6); /*WriteLockEnabled*/
1223 add_token_u64(&err, dev, !!setup->WLE);
1224 add_token_u8(&err, dev, OPAL_ENDNAME);
1226 add_token_u8(&err, dev, OPAL_ENDLIST);
1227 add_token_u8(&err, dev, OPAL_ENDNAME);
1228 add_token_u8(&err, dev, OPAL_ENDLIST);
1231 if (err) {
1232 pr_debug("Error building Setup Locking range command.\n");
1233 return err;
1237 return finalize_and_send(dev, parse_and_check_status);
1240 static int start_generic_opal_session(struct opal_dev *dev,
1241 enum opal_uid auth,
1242 enum opal_uid sp_type,
1243 const char *key,
1244 u8 key_len)
1246 u32 hsn;
1247 int err = 0;
1249 if (key == NULL && auth != OPAL_ANYBODY_UID)
1250 return OPAL_INVAL_PARAM;
1252 clear_opal_cmd(dev);
1254 set_comid(dev, dev->comid);
1255 hsn = GENERIC_HOST_SESSION_NUM;
1257 add_token_u8(&err, dev, OPAL_CALL);
1258 add_token_bytestring(&err, dev, opaluid[OPAL_SMUID_UID],
1259 OPAL_UID_LENGTH);
1260 add_token_bytestring(&err, dev, opalmethod[OPAL_STARTSESSION],
1261 OPAL_UID_LENGTH);
1262 add_token_u8(&err, dev, OPAL_STARTLIST);
1263 add_token_u64(&err, dev, hsn);
1264 add_token_bytestring(&err, dev, opaluid[sp_type], OPAL_UID_LENGTH);
1265 add_token_u8(&err, dev, 1);
1267 switch (auth) {
1268 case OPAL_ANYBODY_UID:
1269 add_token_u8(&err, dev, OPAL_ENDLIST);
1270 break;
1271 case OPAL_ADMIN1_UID:
1272 case OPAL_SID_UID:
1273 add_token_u8(&err, dev, OPAL_STARTNAME);
1274 add_token_u8(&err, dev, 0); /* HostChallenge */
1275 add_token_bytestring(&err, dev, key, key_len);
1276 add_token_u8(&err, dev, OPAL_ENDNAME);
1277 add_token_u8(&err, dev, OPAL_STARTNAME);
1278 add_token_u8(&err, dev, 3); /* HostSignAuth */
1279 add_token_bytestring(&err, dev, opaluid[auth],
1280 OPAL_UID_LENGTH);
1281 add_token_u8(&err, dev, OPAL_ENDNAME);
1282 add_token_u8(&err, dev, OPAL_ENDLIST);
1283 break;
1284 default:
1285 pr_debug("Cannot start Admin SP session with auth %d\n", auth);
1286 return OPAL_INVAL_PARAM;
1289 if (err) {
1290 pr_debug("Error building start adminsp session command.\n");
1291 return err;
1294 return finalize_and_send(dev, start_opal_session_cont);
1297 static int start_anybodyASP_opal_session(struct opal_dev *dev, void *data)
1299 return start_generic_opal_session(dev, OPAL_ANYBODY_UID,
1300 OPAL_ADMINSP_UID, NULL, 0);
1303 static int start_SIDASP_opal_session(struct opal_dev *dev, void *data)
1305 int ret;
1306 const u8 *key = dev->prev_data;
1308 if (!key) {
1309 const struct opal_key *okey = data;
1310 ret = start_generic_opal_session(dev, OPAL_SID_UID,
1311 OPAL_ADMINSP_UID,
1312 okey->key,
1313 okey->key_len);
1314 } else {
1315 ret = start_generic_opal_session(dev, OPAL_SID_UID,
1316 OPAL_ADMINSP_UID,
1317 key, dev->prev_d_len);
1318 kfree(key);
1319 dev->prev_data = NULL;
1321 return ret;
1324 static int start_admin1LSP_opal_session(struct opal_dev *dev, void *data)
1326 struct opal_key *key = data;
1327 return start_generic_opal_session(dev, OPAL_ADMIN1_UID,
1328 OPAL_LOCKINGSP_UID,
1329 key->key, key->key_len);
1332 static int start_auth_opal_session(struct opal_dev *dev, void *data)
1334 struct opal_session_info *session = data;
1335 u8 lk_ul_user[OPAL_UID_LENGTH];
1336 size_t keylen = session->opal_key.key_len;
1337 int err = 0;
1339 u8 *key = session->opal_key.key;
1340 u32 hsn = GENERIC_HOST_SESSION_NUM;
1342 clear_opal_cmd(dev);
1343 set_comid(dev, dev->comid);
1345 if (session->sum) {
1346 err = build_locking_user(lk_ul_user, sizeof(lk_ul_user),
1347 session->opal_key.lr);
1348 if (err)
1349 return err;
1351 } else if (session->who != OPAL_ADMIN1 && !session->sum) {
1352 err = build_locking_user(lk_ul_user, sizeof(lk_ul_user),
1353 session->who - 1);
1354 if (err)
1355 return err;
1356 } else
1357 memcpy(lk_ul_user, opaluid[OPAL_ADMIN1_UID], OPAL_UID_LENGTH);
1359 add_token_u8(&err, dev, OPAL_CALL);
1360 add_token_bytestring(&err, dev, opaluid[OPAL_SMUID_UID],
1361 OPAL_UID_LENGTH);
1362 add_token_bytestring(&err, dev, opalmethod[OPAL_STARTSESSION],
1363 OPAL_UID_LENGTH);
1365 add_token_u8(&err, dev, OPAL_STARTLIST);
1366 add_token_u64(&err, dev, hsn);
1367 add_token_bytestring(&err, dev, opaluid[OPAL_LOCKINGSP_UID],
1368 OPAL_UID_LENGTH);
1369 add_token_u8(&err, dev, 1);
1370 add_token_u8(&err, dev, OPAL_STARTNAME);
1371 add_token_u8(&err, dev, 0);
1372 add_token_bytestring(&err, dev, key, keylen);
1373 add_token_u8(&err, dev, OPAL_ENDNAME);
1374 add_token_u8(&err, dev, OPAL_STARTNAME);
1375 add_token_u8(&err, dev, 3);
1376 add_token_bytestring(&err, dev, lk_ul_user, OPAL_UID_LENGTH);
1377 add_token_u8(&err, dev, OPAL_ENDNAME);
1378 add_token_u8(&err, dev, OPAL_ENDLIST);
1380 if (err) {
1381 pr_debug("Error building STARTSESSION command.\n");
1382 return err;
1385 return finalize_and_send(dev, start_opal_session_cont);
1388 static int revert_tper(struct opal_dev *dev, void *data)
1390 int err = 0;
1392 clear_opal_cmd(dev);
1393 set_comid(dev, dev->comid);
1395 add_token_u8(&err, dev, OPAL_CALL);
1396 add_token_bytestring(&err, dev, opaluid[OPAL_ADMINSP_UID],
1397 OPAL_UID_LENGTH);
1398 add_token_bytestring(&err, dev, opalmethod[OPAL_REVERT],
1399 OPAL_UID_LENGTH);
1400 add_token_u8(&err, dev, OPAL_STARTLIST);
1401 add_token_u8(&err, dev, OPAL_ENDLIST);
1402 if (err) {
1403 pr_debug("Error building REVERT TPER command.\n");
1404 return err;
1407 return finalize_and_send(dev, parse_and_check_status);
1410 static int internal_activate_user(struct opal_dev *dev, void *data)
1412 struct opal_session_info *session = data;
1413 u8 uid[OPAL_UID_LENGTH];
1414 int err = 0;
1416 clear_opal_cmd(dev);
1417 set_comid(dev, dev->comid);
1419 memcpy(uid, opaluid[OPAL_USER1_UID], OPAL_UID_LENGTH);
1420 uid[7] = session->who;
1422 add_token_u8(&err, dev, OPAL_CALL);
1423 add_token_bytestring(&err, dev, uid, OPAL_UID_LENGTH);
1424 add_token_bytestring(&err, dev, opalmethod[OPAL_SET], OPAL_UID_LENGTH);
1425 add_token_u8(&err, dev, OPAL_STARTLIST);
1426 add_token_u8(&err, dev, OPAL_STARTNAME);
1427 add_token_u8(&err, dev, OPAL_VALUES);
1428 add_token_u8(&err, dev, OPAL_STARTLIST);
1429 add_token_u8(&err, dev, OPAL_STARTNAME);
1430 add_token_u8(&err, dev, 5); /* Enabled */
1431 add_token_u8(&err, dev, OPAL_TRUE);
1432 add_token_u8(&err, dev, OPAL_ENDNAME);
1433 add_token_u8(&err, dev, OPAL_ENDLIST);
1434 add_token_u8(&err, dev, OPAL_ENDNAME);
1435 add_token_u8(&err, dev, OPAL_ENDLIST);
1437 if (err) {
1438 pr_debug("Error building Activate UserN command.\n");
1439 return err;
1442 return finalize_and_send(dev, parse_and_check_status);
1445 static int erase_locking_range(struct opal_dev *dev, void *data)
1447 struct opal_session_info *session = data;
1448 u8 uid[OPAL_UID_LENGTH];
1449 int err = 0;
1451 clear_opal_cmd(dev);
1452 set_comid(dev, dev->comid);
1454 if (build_locking_range(uid, sizeof(uid), session->opal_key.lr) < 0)
1455 return -ERANGE;
1457 add_token_u8(&err, dev, OPAL_CALL);
1458 add_token_bytestring(&err, dev, uid, OPAL_UID_LENGTH);
1459 add_token_bytestring(&err, dev, opalmethod[OPAL_ERASE],
1460 OPAL_UID_LENGTH);
1461 add_token_u8(&err, dev, OPAL_STARTLIST);
1462 add_token_u8(&err, dev, OPAL_ENDLIST);
1464 if (err) {
1465 pr_debug("Error building Erase Locking Range Command.\n");
1466 return err;
1468 return finalize_and_send(dev, parse_and_check_status);
1471 static int set_mbr_done(struct opal_dev *dev, void *data)
1473 u8 *mbr_done_tf = data;
1474 int err = 0;
1476 clear_opal_cmd(dev);
1477 set_comid(dev, dev->comid);
1479 add_token_u8(&err, dev, OPAL_CALL);
1480 add_token_bytestring(&err, dev, opaluid[OPAL_MBRCONTROL],
1481 OPAL_UID_LENGTH);
1482 add_token_bytestring(&err, dev, opalmethod[OPAL_SET], OPAL_UID_LENGTH);
1483 add_token_u8(&err, dev, OPAL_STARTLIST);
1484 add_token_u8(&err, dev, OPAL_STARTNAME);
1485 add_token_u8(&err, dev, OPAL_VALUES);
1486 add_token_u8(&err, dev, OPAL_STARTLIST);
1487 add_token_u8(&err, dev, OPAL_STARTNAME);
1488 add_token_u8(&err, dev, 2); /* Done */
1489 add_token_u8(&err, dev, *mbr_done_tf); /* Done T or F */
1490 add_token_u8(&err, dev, OPAL_ENDNAME);
1491 add_token_u8(&err, dev, OPAL_ENDLIST);
1492 add_token_u8(&err, dev, OPAL_ENDNAME);
1493 add_token_u8(&err, dev, OPAL_ENDLIST);
1495 if (err) {
1496 pr_debug("Error Building set MBR Done command\n");
1497 return err;
1500 return finalize_and_send(dev, parse_and_check_status);
1503 static int set_mbr_enable_disable(struct opal_dev *dev, void *data)
1505 u8 *mbr_en_dis = data;
1506 int err = 0;
1508 clear_opal_cmd(dev);
1509 set_comid(dev, dev->comid);
1511 add_token_u8(&err, dev, OPAL_CALL);
1512 add_token_bytestring(&err, dev, opaluid[OPAL_MBRCONTROL],
1513 OPAL_UID_LENGTH);
1514 add_token_bytestring(&err, dev, opalmethod[OPAL_SET], OPAL_UID_LENGTH);
1515 add_token_u8(&err, dev, OPAL_STARTLIST);
1516 add_token_u8(&err, dev, OPAL_STARTNAME);
1517 add_token_u8(&err, dev, OPAL_VALUES);
1518 add_token_u8(&err, dev, OPAL_STARTLIST);
1519 add_token_u8(&err, dev, OPAL_STARTNAME);
1520 add_token_u8(&err, dev, 1);
1521 add_token_u8(&err, dev, *mbr_en_dis);
1522 add_token_u8(&err, dev, OPAL_ENDNAME);
1523 add_token_u8(&err, dev, OPAL_ENDLIST);
1524 add_token_u8(&err, dev, OPAL_ENDNAME);
1525 add_token_u8(&err, dev, OPAL_ENDLIST);
1527 if (err) {
1528 pr_debug("Error Building set MBR done command\n");
1529 return err;
1532 return finalize_and_send(dev, parse_and_check_status);
1535 static int generic_pw_cmd(u8 *key, size_t key_len, u8 *cpin_uid,
1536 struct opal_dev *dev)
1538 int err = 0;
1540 clear_opal_cmd(dev);
1541 set_comid(dev, dev->comid);
1543 add_token_u8(&err, dev, OPAL_CALL);
1544 add_token_bytestring(&err, dev, cpin_uid, OPAL_UID_LENGTH);
1545 add_token_bytestring(&err, dev, opalmethod[OPAL_SET],
1546 OPAL_UID_LENGTH);
1547 add_token_u8(&err, dev, OPAL_STARTLIST);
1548 add_token_u8(&err, dev, OPAL_STARTNAME);
1549 add_token_u8(&err, dev, OPAL_VALUES);
1550 add_token_u8(&err, dev, OPAL_STARTLIST);
1551 add_token_u8(&err, dev, OPAL_STARTNAME);
1552 add_token_u8(&err, dev, 3); /* PIN */
1553 add_token_bytestring(&err, dev, key, key_len);
1554 add_token_u8(&err, dev, OPAL_ENDNAME);
1555 add_token_u8(&err, dev, OPAL_ENDLIST);
1556 add_token_u8(&err, dev, OPAL_ENDNAME);
1557 add_token_u8(&err, dev, OPAL_ENDLIST);
1559 return err;
1562 static int set_new_pw(struct opal_dev *dev, void *data)
1564 u8 cpin_uid[OPAL_UID_LENGTH];
1565 struct opal_session_info *usr = data;
1567 memcpy(cpin_uid, opaluid[OPAL_C_PIN_ADMIN1], OPAL_UID_LENGTH);
1569 if (usr->who != OPAL_ADMIN1) {
1570 cpin_uid[5] = 0x03;
1571 if (usr->sum)
1572 cpin_uid[7] = usr->opal_key.lr + 1;
1573 else
1574 cpin_uid[7] = usr->who;
1577 if (generic_pw_cmd(usr->opal_key.key, usr->opal_key.key_len,
1578 cpin_uid, dev)) {
1579 pr_debug("Error building set password command.\n");
1580 return -ERANGE;
1583 return finalize_and_send(dev, parse_and_check_status);
1586 static int set_sid_cpin_pin(struct opal_dev *dev, void *data)
1588 u8 cpin_uid[OPAL_UID_LENGTH];
1589 struct opal_key *key = data;
1591 memcpy(cpin_uid, opaluid[OPAL_C_PIN_SID], OPAL_UID_LENGTH);
1593 if (generic_pw_cmd(key->key, key->key_len, cpin_uid, dev)) {
1594 pr_debug("Error building Set SID cpin\n");
1595 return -ERANGE;
1597 return finalize_and_send(dev, parse_and_check_status);
1600 static int add_user_to_lr(struct opal_dev *dev, void *data)
1602 u8 lr_buffer[OPAL_UID_LENGTH];
1603 u8 user_uid[OPAL_UID_LENGTH];
1604 struct opal_lock_unlock *lkul = data;
1605 int err = 0;
1607 clear_opal_cmd(dev);
1608 set_comid(dev, dev->comid);
1610 memcpy(lr_buffer, opaluid[OPAL_LOCKINGRANGE_ACE_RDLOCKED],
1611 OPAL_UID_LENGTH);
1613 if (lkul->l_state == OPAL_RW)
1614 memcpy(lr_buffer, opaluid[OPAL_LOCKINGRANGE_ACE_WRLOCKED],
1615 OPAL_UID_LENGTH);
1617 lr_buffer[7] = lkul->session.opal_key.lr;
1619 memcpy(user_uid, opaluid[OPAL_USER1_UID], OPAL_UID_LENGTH);
1621 user_uid[7] = lkul->session.who;
1623 add_token_u8(&err, dev, OPAL_CALL);
1624 add_token_bytestring(&err, dev, lr_buffer, OPAL_UID_LENGTH);
1625 add_token_bytestring(&err, dev, opalmethod[OPAL_SET],
1626 OPAL_UID_LENGTH);
1628 add_token_u8(&err, dev, OPAL_STARTLIST);
1629 add_token_u8(&err, dev, OPAL_STARTNAME);
1630 add_token_u8(&err, dev, OPAL_VALUES);
1632 add_token_u8(&err, dev, OPAL_STARTLIST);
1633 add_token_u8(&err, dev, OPAL_STARTNAME);
1634 add_token_u8(&err, dev, 3);
1636 add_token_u8(&err, dev, OPAL_STARTLIST);
1639 add_token_u8(&err, dev, OPAL_STARTNAME);
1640 add_token_bytestring(&err, dev,
1641 opaluid[OPAL_HALF_UID_AUTHORITY_OBJ_REF],
1642 OPAL_UID_LENGTH/2);
1643 add_token_bytestring(&err, dev, user_uid, OPAL_UID_LENGTH);
1644 add_token_u8(&err, dev, OPAL_ENDNAME);
1647 add_token_u8(&err, dev, OPAL_STARTNAME);
1648 add_token_bytestring(&err, dev,
1649 opaluid[OPAL_HALF_UID_AUTHORITY_OBJ_REF],
1650 OPAL_UID_LENGTH/2);
1651 add_token_bytestring(&err, dev, user_uid, OPAL_UID_LENGTH);
1652 add_token_u8(&err, dev, OPAL_ENDNAME);
1655 add_token_u8(&err, dev, OPAL_STARTNAME);
1656 add_token_bytestring(&err, dev, opaluid[OPAL_HALF_UID_BOOLEAN_ACE],
1657 OPAL_UID_LENGTH/2);
1658 add_token_u8(&err, dev, 1);
1659 add_token_u8(&err, dev, OPAL_ENDNAME);
1662 add_token_u8(&err, dev, OPAL_ENDLIST);
1663 add_token_u8(&err, dev, OPAL_ENDNAME);
1664 add_token_u8(&err, dev, OPAL_ENDLIST);
1665 add_token_u8(&err, dev, OPAL_ENDNAME);
1666 add_token_u8(&err, dev, OPAL_ENDLIST);
1668 if (err) {
1669 pr_debug("Error building add user to locking range command.\n");
1670 return err;
1673 return finalize_and_send(dev, parse_and_check_status);
1676 static int lock_unlock_locking_range(struct opal_dev *dev, void *data)
1678 u8 lr_buffer[OPAL_UID_LENGTH];
1679 struct opal_lock_unlock *lkul = data;
1680 u8 read_locked = 1, write_locked = 1;
1681 int err = 0;
1683 clear_opal_cmd(dev);
1684 set_comid(dev, dev->comid);
1686 if (build_locking_range(lr_buffer, sizeof(lr_buffer),
1687 lkul->session.opal_key.lr) < 0)
1688 return -ERANGE;
1690 switch (lkul->l_state) {
1691 case OPAL_RO:
1692 read_locked = 0;
1693 write_locked = 1;
1694 break;
1695 case OPAL_RW:
1696 read_locked = 0;
1697 write_locked = 0;
1698 break;
1699 case OPAL_LK:
1700 /* vars are initalized to locked */
1701 break;
1702 default:
1703 pr_debug("Tried to set an invalid locking state... returning to uland\n");
1704 return OPAL_INVAL_PARAM;
1707 add_token_u8(&err, dev, OPAL_CALL);
1708 add_token_bytestring(&err, dev, lr_buffer, OPAL_UID_LENGTH);
1709 add_token_bytestring(&err, dev, opalmethod[OPAL_SET], OPAL_UID_LENGTH);
1710 add_token_u8(&err, dev, OPAL_STARTLIST);
1711 add_token_u8(&err, dev, OPAL_STARTNAME);
1712 add_token_u8(&err, dev, OPAL_VALUES);
1713 add_token_u8(&err, dev, OPAL_STARTLIST);
1715 add_token_u8(&err, dev, OPAL_STARTNAME);
1716 add_token_u8(&err, dev, OPAL_READLOCKED);
1717 add_token_u8(&err, dev, read_locked);
1718 add_token_u8(&err, dev, OPAL_ENDNAME);
1720 add_token_u8(&err, dev, OPAL_STARTNAME);
1721 add_token_u8(&err, dev, OPAL_WRITELOCKED);
1722 add_token_u8(&err, dev, write_locked);
1723 add_token_u8(&err, dev, OPAL_ENDNAME);
1725 add_token_u8(&err, dev, OPAL_ENDLIST);
1726 add_token_u8(&err, dev, OPAL_ENDNAME);
1727 add_token_u8(&err, dev, OPAL_ENDLIST);
1729 if (err) {
1730 pr_debug("Error building SET command.\n");
1731 return err;
1733 return finalize_and_send(dev, parse_and_check_status);
1737 static int lock_unlock_locking_range_sum(struct opal_dev *dev, void *data)
1739 u8 lr_buffer[OPAL_UID_LENGTH];
1740 u8 read_locked = 1, write_locked = 1;
1741 struct opal_lock_unlock *lkul = data;
1742 int ret;
1744 clear_opal_cmd(dev);
1745 set_comid(dev, dev->comid);
1747 if (build_locking_range(lr_buffer, sizeof(lr_buffer),
1748 lkul->session.opal_key.lr) < 0)
1749 return -ERANGE;
1751 switch (lkul->l_state) {
1752 case OPAL_RO:
1753 read_locked = 0;
1754 write_locked = 1;
1755 break;
1756 case OPAL_RW:
1757 read_locked = 0;
1758 write_locked = 0;
1759 break;
1760 case OPAL_LK:
1761 /* vars are initalized to locked */
1762 break;
1763 default:
1764 pr_debug("Tried to set an invalid locking state.\n");
1765 return OPAL_INVAL_PARAM;
1767 ret = generic_lr_enable_disable(dev, lr_buffer, 1, 1,
1768 read_locked, write_locked);
1770 if (ret < 0) {
1771 pr_debug("Error building SET command.\n");
1772 return ret;
1774 return finalize_and_send(dev, parse_and_check_status);
1777 static int activate_lsp(struct opal_dev *dev, void *data)
1779 struct opal_lr_act *opal_act = data;
1780 u8 user_lr[OPAL_UID_LENGTH];
1781 u8 uint_3 = 0x83;
1782 int err = 0, i;
1784 clear_opal_cmd(dev);
1785 set_comid(dev, dev->comid);
1787 add_token_u8(&err, dev, OPAL_CALL);
1788 add_token_bytestring(&err, dev, opaluid[OPAL_LOCKINGSP_UID],
1789 OPAL_UID_LENGTH);
1790 add_token_bytestring(&err, dev, opalmethod[OPAL_ACTIVATE],
1791 OPAL_UID_LENGTH);
1794 if (opal_act->sum) {
1795 err = build_locking_range(user_lr, sizeof(user_lr),
1796 opal_act->lr[0]);
1797 if (err)
1798 return err;
1800 add_token_u8(&err, dev, OPAL_STARTLIST);
1801 add_token_u8(&err, dev, OPAL_STARTNAME);
1802 add_token_u8(&err, dev, uint_3);
1803 add_token_u8(&err, dev, 6);
1804 add_token_u8(&err, dev, 0);
1805 add_token_u8(&err, dev, 0);
1807 add_token_u8(&err, dev, OPAL_STARTLIST);
1808 add_token_bytestring(&err, dev, user_lr, OPAL_UID_LENGTH);
1809 for (i = 1; i < opal_act->num_lrs; i++) {
1810 user_lr[7] = opal_act->lr[i];
1811 add_token_bytestring(&err, dev, user_lr, OPAL_UID_LENGTH);
1813 add_token_u8(&err, dev, OPAL_ENDLIST);
1814 add_token_u8(&err, dev, OPAL_ENDNAME);
1815 add_token_u8(&err, dev, OPAL_ENDLIST);
1817 } else {
1818 add_token_u8(&err, dev, OPAL_STARTLIST);
1819 add_token_u8(&err, dev, OPAL_ENDLIST);
1822 if (err) {
1823 pr_debug("Error building Activate LockingSP command.\n");
1824 return err;
1827 return finalize_and_send(dev, parse_and_check_status);
1830 static int get_lsp_lifecycle_cont(struct opal_dev *dev)
1832 u8 lc_status;
1833 int error = 0;
1835 error = parse_and_check_status(dev);
1836 if (error)
1837 return error;
1839 lc_status = response_get_u64(&dev->parsed, 4);
1840 /* 0x08 is Manufacured Inactive */
1841 /* 0x09 is Manufactured */
1842 if (lc_status != OPAL_MANUFACTURED_INACTIVE) {
1843 pr_debug("Couldn't determine the status of the Lifecycle state\n");
1844 return -ENODEV;
1847 return 0;
1850 /* Determine if we're in the Manufactured Inactive or Active state */
1851 static int get_lsp_lifecycle(struct opal_dev *dev, void *data)
1853 int err = 0;
1855 clear_opal_cmd(dev);
1856 set_comid(dev, dev->comid);
1858 add_token_u8(&err, dev, OPAL_CALL);
1859 add_token_bytestring(&err, dev, opaluid[OPAL_LOCKINGSP_UID],
1860 OPAL_UID_LENGTH);
1861 add_token_bytestring(&err, dev, opalmethod[OPAL_GET], OPAL_UID_LENGTH);
1863 add_token_u8(&err, dev, OPAL_STARTLIST);
1864 add_token_u8(&err, dev, OPAL_STARTLIST);
1866 add_token_u8(&err, dev, OPAL_STARTNAME);
1867 add_token_u8(&err, dev, 3); /* Start Column */
1868 add_token_u8(&err, dev, 6); /* Lifecycle Column */
1869 add_token_u8(&err, dev, OPAL_ENDNAME);
1871 add_token_u8(&err, dev, OPAL_STARTNAME);
1872 add_token_u8(&err, dev, 4); /* End Column */
1873 add_token_u8(&err, dev, 6); /* Lifecycle Column */
1874 add_token_u8(&err, dev, OPAL_ENDNAME);
1876 add_token_u8(&err, dev, OPAL_ENDLIST);
1877 add_token_u8(&err, dev, OPAL_ENDLIST);
1879 if (err) {
1880 pr_debug("Error Building GET Lifecycle Status command\n");
1881 return err;
1884 return finalize_and_send(dev, get_lsp_lifecycle_cont);
1887 static int get_msid_cpin_pin_cont(struct opal_dev *dev)
1889 const char *msid_pin;
1890 size_t strlen;
1891 int error = 0;
1893 error = parse_and_check_status(dev);
1894 if (error)
1895 return error;
1897 strlen = response_get_string(&dev->parsed, 4, &msid_pin);
1898 if (!msid_pin) {
1899 pr_debug("%s: Couldn't extract PIN from response\n", __func__);
1900 return OPAL_INVAL_PARAM;
1903 dev->prev_data = kmemdup(msid_pin, strlen, GFP_KERNEL);
1904 if (!dev->prev_data)
1905 return -ENOMEM;
1907 dev->prev_d_len = strlen;
1909 return 0;
1912 static int get_msid_cpin_pin(struct opal_dev *dev, void *data)
1914 int err = 0;
1916 clear_opal_cmd(dev);
1917 set_comid(dev, dev->comid);
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);
1924 add_token_u8(&err, dev, OPAL_STARTLIST);
1925 add_token_u8(&err, dev, OPAL_STARTLIST);
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);
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);
1937 add_token_u8(&err, dev, OPAL_ENDLIST);
1938 add_token_u8(&err, dev, OPAL_ENDLIST);
1940 if (err) {
1941 pr_debug("Error building Get MSID CPIN PIN command.\n");
1942 return err;
1945 return finalize_and_send(dev, get_msid_cpin_pin_cont);
1948 static int end_opal_session(struct opal_dev *dev, void *data)
1950 int err = 0;
1952 clear_opal_cmd(dev);
1953 set_comid(dev, dev->comid);
1954 add_token_u8(&err, dev, OPAL_ENDOFSESSION);
1956 if (err < 0)
1957 return err;
1958 return finalize_and_send(dev, end_session_cont);
1961 static int end_opal_session_error(struct opal_dev *dev)
1963 const struct opal_step error_end_session[] = {
1964 { end_opal_session, },
1965 { NULL, }
1967 dev->steps = error_end_session;
1968 return next(dev);
1971 static inline void setup_opal_dev(struct opal_dev *dev,
1972 const struct opal_step *steps)
1974 dev->steps = steps;
1975 dev->tsn = 0;
1976 dev->hsn = 0;
1977 dev->prev_data = NULL;
1980 static int check_opal_support(struct opal_dev *dev)
1982 const struct opal_step steps[] = {
1983 { opal_discovery0, },
1984 { NULL, }
1986 int ret;
1988 mutex_lock(&dev->dev_lock);
1989 setup_opal_dev(dev, steps);
1990 ret = next(dev);
1991 dev->supported = !ret;
1992 mutex_unlock(&dev->dev_lock);
1993 return ret;
1996 static void clean_opal_dev(struct opal_dev *dev)
1999 struct opal_suspend_data *suspend, *next;
2001 mutex_lock(&dev->dev_lock);
2002 list_for_each_entry_safe(suspend, next, &dev->unlk_lst, node) {
2003 list_del(&suspend->node);
2004 kfree(suspend);
2006 mutex_unlock(&dev->dev_lock);
2009 void free_opal_dev(struct opal_dev *dev)
2011 if (!dev)
2012 return;
2013 clean_opal_dev(dev);
2014 kfree(dev);
2016 EXPORT_SYMBOL(free_opal_dev);
2018 struct opal_dev *init_opal_dev(void *data, sec_send_recv *send_recv)
2020 struct opal_dev *dev;
2022 dev = kmalloc(sizeof(*dev), GFP_KERNEL);
2023 if (!dev)
2024 return NULL;
2026 INIT_LIST_HEAD(&dev->unlk_lst);
2027 mutex_init(&dev->dev_lock);
2028 dev->data = data;
2029 dev->send_recv = send_recv;
2030 if (check_opal_support(dev) != 0) {
2031 pr_debug("Opal is not supported on this device\n");
2032 kfree(dev);
2033 return NULL;
2035 return dev;
2037 EXPORT_SYMBOL(init_opal_dev);
2039 static int opal_secure_erase_locking_range(struct opal_dev *dev,
2040 struct opal_session_info *opal_session)
2042 const struct opal_step erase_steps[] = {
2043 { opal_discovery0, },
2044 { start_auth_opal_session, opal_session },
2045 { get_active_key, &opal_session->opal_key.lr },
2046 { gen_key, },
2047 { end_opal_session, },
2048 { NULL, }
2050 int ret;
2052 mutex_lock(&dev->dev_lock);
2053 setup_opal_dev(dev, erase_steps);
2054 ret = next(dev);
2055 mutex_unlock(&dev->dev_lock);
2056 return ret;
2059 static int opal_erase_locking_range(struct opal_dev *dev,
2060 struct opal_session_info *opal_session)
2062 const struct opal_step erase_steps[] = {
2063 { opal_discovery0, },
2064 { start_auth_opal_session, opal_session },
2065 { erase_locking_range, opal_session },
2066 { end_opal_session, },
2067 { NULL, }
2069 int ret;
2071 mutex_lock(&dev->dev_lock);
2072 setup_opal_dev(dev, erase_steps);
2073 ret = next(dev);
2074 mutex_unlock(&dev->dev_lock);
2075 return ret;
2078 static int opal_enable_disable_shadow_mbr(struct opal_dev *dev,
2079 struct opal_mbr_data *opal_mbr)
2081 const struct opal_step mbr_steps[] = {
2082 { opal_discovery0, },
2083 { start_admin1LSP_opal_session, &opal_mbr->key },
2084 { set_mbr_done, &opal_mbr->enable_disable },
2085 { end_opal_session, },
2086 { start_admin1LSP_opal_session, &opal_mbr->key },
2087 { set_mbr_enable_disable, &opal_mbr->enable_disable },
2088 { end_opal_session, },
2089 { NULL, }
2091 int ret;
2093 if (opal_mbr->enable_disable != OPAL_MBR_ENABLE &&
2094 opal_mbr->enable_disable != OPAL_MBR_DISABLE)
2095 return -EINVAL;
2097 mutex_lock(&dev->dev_lock);
2098 setup_opal_dev(dev, mbr_steps);
2099 ret = next(dev);
2100 mutex_unlock(&dev->dev_lock);
2101 return ret;
2104 static int opal_save(struct opal_dev *dev, struct opal_lock_unlock *lk_unlk)
2106 struct opal_suspend_data *suspend;
2108 suspend = kzalloc(sizeof(*suspend), GFP_KERNEL);
2109 if (!suspend)
2110 return -ENOMEM;
2112 suspend->unlk = *lk_unlk;
2113 suspend->lr = lk_unlk->session.opal_key.lr;
2115 mutex_lock(&dev->dev_lock);
2116 setup_opal_dev(dev, NULL);
2117 add_suspend_info(dev, suspend);
2118 mutex_unlock(&dev->dev_lock);
2119 return 0;
2122 static int opal_add_user_to_lr(struct opal_dev *dev,
2123 struct opal_lock_unlock *lk_unlk)
2125 const struct opal_step steps[] = {
2126 { opal_discovery0, },
2127 { start_admin1LSP_opal_session, &lk_unlk->session.opal_key },
2128 { add_user_to_lr, lk_unlk },
2129 { end_opal_session, },
2130 { NULL, }
2132 int ret;
2134 if (lk_unlk->l_state != OPAL_RO &&
2135 lk_unlk->l_state != OPAL_RW) {
2136 pr_debug("Locking state was not RO or RW\n");
2137 return -EINVAL;
2139 if (lk_unlk->session.who < OPAL_USER1 ||
2140 lk_unlk->session.who > OPAL_USER9) {
2141 pr_debug("Authority was not within the range of users: %d\n",
2142 lk_unlk->session.who);
2143 return -EINVAL;
2145 if (lk_unlk->session.sum) {
2146 pr_debug("%s not supported in sum. Use setup locking range\n",
2147 __func__);
2148 return -EINVAL;
2151 mutex_lock(&dev->dev_lock);
2152 setup_opal_dev(dev, steps);
2153 ret = next(dev);
2154 mutex_unlock(&dev->dev_lock);
2155 return ret;
2158 static int opal_reverttper(struct opal_dev *dev, struct opal_key *opal)
2160 const struct opal_step revert_steps[] = {
2161 { opal_discovery0, },
2162 { start_SIDASP_opal_session, opal },
2163 { revert_tper, }, /* controller will terminate session */
2164 { NULL, }
2166 int ret;
2168 mutex_lock(&dev->dev_lock);
2169 setup_opal_dev(dev, revert_steps);
2170 ret = next(dev);
2171 mutex_unlock(&dev->dev_lock);
2174 * If we successfully reverted lets clean
2175 * any saved locking ranges.
2177 if (!ret)
2178 clean_opal_dev(dev);
2180 return ret;
2183 static int __opal_lock_unlock(struct opal_dev *dev,
2184 struct opal_lock_unlock *lk_unlk)
2186 const struct opal_step unlock_steps[] = {
2187 { opal_discovery0, },
2188 { start_auth_opal_session, &lk_unlk->session },
2189 { lock_unlock_locking_range, lk_unlk },
2190 { end_opal_session, },
2191 { NULL, }
2193 const struct opal_step unlock_sum_steps[] = {
2194 { opal_discovery0, },
2195 { start_auth_opal_session, &lk_unlk->session },
2196 { lock_unlock_locking_range_sum, lk_unlk },
2197 { end_opal_session, },
2198 { NULL, }
2201 dev->steps = lk_unlk->session.sum ? unlock_sum_steps : unlock_steps;
2202 return next(dev);
2205 static int __opal_set_mbr_done(struct opal_dev *dev, struct opal_key *key)
2207 u8 mbr_done_tf = 1;
2208 const struct opal_step mbrdone_step [] = {
2209 { opal_discovery0, },
2210 { start_admin1LSP_opal_session, key },
2211 { set_mbr_done, &mbr_done_tf },
2212 { end_opal_session, },
2213 { NULL, }
2216 dev->steps = mbrdone_step;
2217 return next(dev);
2220 static int opal_lock_unlock(struct opal_dev *dev,
2221 struct opal_lock_unlock *lk_unlk)
2223 int ret;
2225 if (lk_unlk->session.who < OPAL_ADMIN1 ||
2226 lk_unlk->session.who > OPAL_USER9)
2227 return -EINVAL;
2229 mutex_lock(&dev->dev_lock);
2230 ret = __opal_lock_unlock(dev, lk_unlk);
2231 mutex_unlock(&dev->dev_lock);
2232 return ret;
2235 static int opal_take_ownership(struct opal_dev *dev, struct opal_key *opal)
2237 const struct opal_step owner_steps[] = {
2238 { opal_discovery0, },
2239 { start_anybodyASP_opal_session, },
2240 { get_msid_cpin_pin, },
2241 { end_opal_session, },
2242 { start_SIDASP_opal_session, opal },
2243 { set_sid_cpin_pin, opal },
2244 { end_opal_session, },
2245 { NULL, }
2247 int ret;
2249 if (!dev)
2250 return -ENODEV;
2252 mutex_lock(&dev->dev_lock);
2253 setup_opal_dev(dev, owner_steps);
2254 ret = next(dev);
2255 mutex_unlock(&dev->dev_lock);
2256 return ret;
2259 static int opal_activate_lsp(struct opal_dev *dev, struct opal_lr_act *opal_lr_act)
2261 const struct opal_step active_steps[] = {
2262 { opal_discovery0, },
2263 { start_SIDASP_opal_session, &opal_lr_act->key },
2264 { get_lsp_lifecycle, },
2265 { activate_lsp, opal_lr_act },
2266 { end_opal_session, },
2267 { NULL, }
2269 int ret;
2271 if (!opal_lr_act->num_lrs || opal_lr_act->num_lrs > OPAL_MAX_LRS)
2272 return -EINVAL;
2274 mutex_lock(&dev->dev_lock);
2275 setup_opal_dev(dev, active_steps);
2276 ret = next(dev);
2277 mutex_unlock(&dev->dev_lock);
2278 return ret;
2281 static int opal_setup_locking_range(struct opal_dev *dev,
2282 struct opal_user_lr_setup *opal_lrs)
2284 const struct opal_step lr_steps[] = {
2285 { opal_discovery0, },
2286 { start_auth_opal_session, &opal_lrs->session },
2287 { setup_locking_range, opal_lrs },
2288 { end_opal_session, },
2289 { NULL, }
2291 int ret;
2293 mutex_lock(&dev->dev_lock);
2294 setup_opal_dev(dev, lr_steps);
2295 ret = next(dev);
2296 mutex_unlock(&dev->dev_lock);
2297 return ret;
2300 static int opal_set_new_pw(struct opal_dev *dev, struct opal_new_pw *opal_pw)
2302 const struct opal_step pw_steps[] = {
2303 { opal_discovery0, },
2304 { start_auth_opal_session, &opal_pw->session },
2305 { set_new_pw, &opal_pw->new_user_pw },
2306 { end_opal_session, },
2307 { NULL }
2309 int ret;
2311 if (opal_pw->session.who < OPAL_ADMIN1 ||
2312 opal_pw->session.who > OPAL_USER9 ||
2313 opal_pw->new_user_pw.who < OPAL_ADMIN1 ||
2314 opal_pw->new_user_pw.who > OPAL_USER9)
2315 return -EINVAL;
2317 mutex_lock(&dev->dev_lock);
2318 setup_opal_dev(dev, pw_steps);
2319 ret = next(dev);
2320 mutex_unlock(&dev->dev_lock);
2321 return ret;
2324 static int opal_activate_user(struct opal_dev *dev,
2325 struct opal_session_info *opal_session)
2327 const struct opal_step act_steps[] = {
2328 { opal_discovery0, },
2329 { start_admin1LSP_opal_session, &opal_session->opal_key },
2330 { internal_activate_user, opal_session },
2331 { end_opal_session, },
2332 { NULL, }
2334 int ret;
2336 /* We can't activate Admin1 it's active as manufactured */
2337 if (opal_session->who < OPAL_USER1 ||
2338 opal_session->who > OPAL_USER9) {
2339 pr_debug("Who was not a valid user: %d\n", opal_session->who);
2340 return -EINVAL;
2343 mutex_lock(&dev->dev_lock);
2344 setup_opal_dev(dev, act_steps);
2345 ret = next(dev);
2346 mutex_unlock(&dev->dev_lock);
2347 return ret;
2350 bool opal_unlock_from_suspend(struct opal_dev *dev)
2352 struct opal_suspend_data *suspend;
2353 bool was_failure = false;
2354 int ret = 0;
2356 if (!dev)
2357 return false;
2358 if (!dev->supported)
2359 return false;
2361 mutex_lock(&dev->dev_lock);
2362 setup_opal_dev(dev, NULL);
2364 list_for_each_entry(suspend, &dev->unlk_lst, node) {
2365 dev->tsn = 0;
2366 dev->hsn = 0;
2368 ret = __opal_lock_unlock(dev, &suspend->unlk);
2369 if (ret) {
2370 pr_debug("Failed to unlock LR %hhu with sum %d\n",
2371 suspend->unlk.session.opal_key.lr,
2372 suspend->unlk.session.sum);
2373 was_failure = true;
2375 if (dev->mbr_enabled) {
2376 ret = __opal_set_mbr_done(dev, &suspend->unlk.session.opal_key);
2377 if (ret)
2378 pr_debug("Failed to set MBR Done in S3 resume\n");
2381 mutex_unlock(&dev->dev_lock);
2382 return was_failure;
2384 EXPORT_SYMBOL(opal_unlock_from_suspend);
2386 int sed_ioctl(struct opal_dev *dev, unsigned int cmd, void __user *arg)
2388 void *p;
2389 int ret = -ENOTTY;
2391 if (!capable(CAP_SYS_ADMIN))
2392 return -EACCES;
2393 if (!dev)
2394 return -ENOTSUPP;
2395 if (!dev->supported)
2396 return -ENOTSUPP;
2398 p = memdup_user(arg, _IOC_SIZE(cmd));
2399 if (IS_ERR(p))
2400 return PTR_ERR(p);
2402 switch (cmd) {
2403 case IOC_OPAL_SAVE:
2404 ret = opal_save(dev, p);
2405 break;
2406 case IOC_OPAL_LOCK_UNLOCK:
2407 ret = opal_lock_unlock(dev, p);
2408 break;
2409 case IOC_OPAL_TAKE_OWNERSHIP:
2410 ret = opal_take_ownership(dev, p);
2411 break;
2412 case IOC_OPAL_ACTIVATE_LSP:
2413 ret = opal_activate_lsp(dev, p);
2414 break;
2415 case IOC_OPAL_SET_PW:
2416 ret = opal_set_new_pw(dev, p);
2417 break;
2418 case IOC_OPAL_ACTIVATE_USR:
2419 ret = opal_activate_user(dev, p);
2420 break;
2421 case IOC_OPAL_REVERT_TPR:
2422 ret = opal_reverttper(dev, p);
2423 break;
2424 case IOC_OPAL_LR_SETUP:
2425 ret = opal_setup_locking_range(dev, p);
2426 break;
2427 case IOC_OPAL_ADD_USR_TO_LR:
2428 ret = opal_add_user_to_lr(dev, p);
2429 break;
2430 case IOC_OPAL_ENABLE_DISABLE_MBR:
2431 ret = opal_enable_disable_shadow_mbr(dev, p);
2432 break;
2433 case IOC_OPAL_ERASE_LR:
2434 ret = opal_erase_locking_range(dev, p);
2435 break;
2436 case IOC_OPAL_SECURE_ERASE_LR:
2437 ret = opal_secure_erase_locking_range(dev, p);
2438 break;
2439 default:
2440 break;
2443 kfree(p);
2444 return ret;
2446 EXPORT_SYMBOL_GPL(sed_ioctl);