1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18#define pr_fmt(fmt) KBUILD_MODNAME ":OPAL: " fmt
19
20#include <linux/delay.h>
21#include <linux/device.h>
22#include <linux/kernel.h>
23#include <linux/list.h>
24#include <linux/genhd.h>
25#include <linux/slab.h>
26#include <linux/uaccess.h>
27#include <uapi/linux/sed-opal.h>
28#include <linux/sed-opal.h>
29#include <linux/string.h>
30#include <linux/kdev_t.h>
31
32#include "opal_proto.h"
33
34#define IO_BUFFER_LENGTH 2048
35#define MAX_TOKS 64
36
37struct opal_step {
38 int (*fn)(struct opal_dev *dev, void *data);
39 void *data;
40};
41typedef int (cont_fn)(struct opal_dev *dev);
42
43enum opal_atom_width {
44 OPAL_WIDTH_TINY,
45 OPAL_WIDTH_SHORT,
46 OPAL_WIDTH_MEDIUM,
47 OPAL_WIDTH_LONG,
48 OPAL_WIDTH_TOKEN
49};
50
51
52
53
54
55
56
57struct opal_resp_tok {
58 const u8 *pos;
59 size_t len;
60 enum opal_response_token type;
61 enum opal_atom_width width;
62 union {
63 u64 u;
64 s64 s;
65 } stored;
66};
67
68
69
70
71
72
73
74
75
76struct parsed_resp {
77 int num;
78 struct opal_resp_tok toks[MAX_TOKS];
79};
80
81struct opal_dev {
82 bool supported;
83 bool mbr_enabled;
84
85 void *data;
86 sec_send_recv *send_recv;
87
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;
95
96 size_t pos;
97 u8 cmd[IO_BUFFER_LENGTH];
98 u8 resp[IO_BUFFER_LENGTH];
99
100 struct parsed_resp parsed;
101 size_t prev_d_len;
102 void *prev_data;
103
104 struct list_head unlk_lst;
105};
106
107
108static const u8 opaluid[][OPAL_UID_LENGTH] = {
109
110 [OPAL_SMUID_UID] =
111 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff },
112 [OPAL_THISSP_UID] =
113 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 },
114 [OPAL_ADMINSP_UID] =
115 { 0x00, 0x00, 0x02, 0x05, 0x00, 0x00, 0x00, 0x01 },
116 [OPAL_LOCKINGSP_UID] =
117 { 0x00, 0x00, 0x02, 0x05, 0x00, 0x00, 0x00, 0x02 },
118 [OPAL_ENTERPRISE_LOCKINGSP_UID] =
119 { 0x00, 0x00, 0x02, 0x05, 0x00, 0x01, 0x00, 0x01 },
120 [OPAL_ANYBODY_UID] =
121 { 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x01 },
122 [OPAL_SID_UID] =
123 { 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x06 },
124 [OPAL_ADMIN1_UID] =
125 { 0x00, 0x00, 0x00, 0x09, 0x00, 0x01, 0x00, 0x01 },
126 [OPAL_USER1_UID] =
127 { 0x00, 0x00, 0x00, 0x09, 0x00, 0x03, 0x00, 0x01 },
128 [OPAL_USER2_UID] =
129 { 0x00, 0x00, 0x00, 0x09, 0x00, 0x03, 0x00, 0x02 },
130 [OPAL_PSID_UID] =
131 { 0x00, 0x00, 0x00, 0x09, 0x00, 0x01, 0xff, 0x01 },
132 [OPAL_ENTERPRISE_BANDMASTER0_UID] =
133 { 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x80, 0x01 },
134 [OPAL_ENTERPRISE_ERASEMASTER_UID] =
135 { 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x84, 0x01 },
136
137
138
139 [OPAL_LOCKINGRANGE_GLOBAL] =
140 { 0x00, 0x00, 0x08, 0x02, 0x00, 0x00, 0x00, 0x01 },
141 [OPAL_LOCKINGRANGE_ACE_RDLOCKED] =
142 { 0x00, 0x00, 0x00, 0x08, 0x00, 0x03, 0xE0, 0x01 },
143 [OPAL_LOCKINGRANGE_ACE_WRLOCKED] =
144 { 0x00, 0x00, 0x00, 0x08, 0x00, 0x03, 0xE8, 0x01 },
145 [OPAL_MBRCONTROL] =
146 { 0x00, 0x00, 0x08, 0x03, 0x00, 0x00, 0x00, 0x01 },
147 [OPAL_MBR] =
148 { 0x00, 0x00, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00 },
149 [OPAL_AUTHORITY_TABLE] =
150 { 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00},
151 [OPAL_C_PIN_TABLE] =
152 { 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x00},
153 [OPAL_LOCKING_INFO_TABLE] =
154 { 0x00, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x01 },
155 [OPAL_ENTERPRISE_LOCKING_INFO_TABLE] =
156 { 0x00, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x00 },
157
158
159
160 [OPAL_C_PIN_MSID] =
161 { 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x84, 0x02},
162 [OPAL_C_PIN_SID] =
163 { 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x01},
164 [OPAL_C_PIN_ADMIN1] =
165 { 0x00, 0x00, 0x00, 0x0B, 0x00, 0x01, 0x00, 0x01},
166
167
168
169 [OPAL_HALF_UID_AUTHORITY_OBJ_REF] =
170 { 0x00, 0x00, 0x0C, 0x05, 0xff, 0xff, 0xff, 0xff },
171 [OPAL_HALF_UID_BOOLEAN_ACE] =
172 { 0x00, 0x00, 0x04, 0x0E, 0xff, 0xff, 0xff, 0xff },
173
174
175 [OPAL_UID_HEXFF] =
176 { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
177};
178
179
180
181
182
183
184static const u8 opalmethod[][OPAL_UID_LENGTH] = {
185 [OPAL_PROPERTIES] =
186 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x01 },
187 [OPAL_STARTSESSION] =
188 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x02 },
189 [OPAL_REVERT] =
190 { 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x02, 0x02 },
191 [OPAL_ACTIVATE] =
192 { 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x02, 0x03 },
193 [OPAL_EGET] =
194 { 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06 },
195 [OPAL_ESET] =
196 { 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x07 },
197 [OPAL_NEXT] =
198 { 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x08 },
199 [OPAL_EAUTHENTICATE] =
200 { 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0c },
201 [OPAL_GETACL] =
202 { 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0d },
203 [OPAL_GENKEY] =
204 { 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x10 },
205 [OPAL_REVERTSP] =
206 { 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x11 },
207 [OPAL_GET] =
208 { 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x16 },
209 [OPAL_SET] =
210 { 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x17 },
211 [OPAL_AUTHENTICATE] =
212 { 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x1c },
213 [OPAL_RANDOM] =
214 { 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x01 },
215 [OPAL_ERASE] =
216 { 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x08, 0x03 },
217};
218
219static int end_opal_session_error(struct opal_dev *dev);
220
221struct opal_suspend_data {
222 struct opal_lock_unlock unlk;
223 u8 lr;
224 struct list_head node;
225};
226
227
228
229
230
231
232static const char * const opal_errors[] = {
233 "Success",
234 "Not Authorized",
235 "Unknown Error",
236 "SP Busy",
237 "SP Failed",
238 "SP Disabled",
239 "SP Frozen",
240 "No Sessions Available",
241 "Uniqueness Conflict",
242 "Insufficient Space",
243 "Insufficient Rows",
244 "Invalid Function",
245 "Invalid Parameter",
246 "Invalid Reference",
247 "Unknown Error",
248 "TPER Malfunction",
249 "Transaction Failure",
250 "Response Overflow",
251 "Authority Locked Out",
252};
253
254static const char *opal_error_to_human(int error)
255{
256 if (error == 0x3f)
257 return "Failed";
258
259 if (error >= ARRAY_SIZE(opal_errors) || error < 0)
260 return "Unknown Error";
261
262 return opal_errors[error];
263}
264
265static void print_buffer(const u8 *ptr, u32 length)
266{
267#ifdef DEBUG
268 print_hex_dump_bytes("OPAL: ", DUMP_PREFIX_OFFSET, ptr, length);
269 pr_debug("\n");
270#endif
271}
272
273static bool check_tper(const void *data)
274{
275 const struct d0_tper_features *tper = data;
276 u8 flags = tper->supported_features;
277
278 if (!(flags & TPER_SYNC_SUPPORTED)) {
279 pr_debug("TPer sync not supported. flags = %d\n",
280 tper->supported_features);
281 return false;
282 }
283
284 return true;
285}
286
287static bool check_mbrenabled(const void *data)
288{
289 const struct d0_locking_features *lfeat = data;
290 u8 sup_feat = lfeat->supported_features;
291
292 return !!(sup_feat & MBR_ENABLED_MASK);
293}
294
295static bool check_sum(const void *data)
296{
297 const struct d0_single_user_mode *sum = data;
298 u32 nlo = be32_to_cpu(sum->num_locking_objects);
299
300 if (nlo == 0) {
301 pr_debug("Need at least one locking object.\n");
302 return false;
303 }
304
305 pr_debug("Number of locking objects: %d\n", nlo);
306
307 return true;
308}
309
310static u16 get_comid_v100(const void *data)
311{
312 const struct d0_opal_v100 *v100 = data;
313
314 return be16_to_cpu(v100->baseComID);
315}
316
317static u16 get_comid_v200(const void *data)
318{
319 const struct d0_opal_v200 *v200 = data;
320
321 return be16_to_cpu(v200->baseComID);
322}
323
324static int opal_send_cmd(struct opal_dev *dev)
325{
326 return dev->send_recv(dev->data, dev->comid, TCG_SECP_01,
327 dev->cmd, IO_BUFFER_LENGTH,
328 true);
329}
330
331static int opal_recv_cmd(struct opal_dev *dev)
332{
333 return dev->send_recv(dev->data, dev->comid, TCG_SECP_01,
334 dev->resp, IO_BUFFER_LENGTH,
335 false);
336}
337
338static int opal_recv_check(struct opal_dev *dev)
339{
340 size_t buflen = IO_BUFFER_LENGTH;
341 void *buffer = dev->resp;
342 struct opal_header *hdr = buffer;
343 int ret;
344
345 do {
346 pr_debug("Sent OPAL command: outstanding=%d, minTransfer=%d\n",
347 hdr->cp.outstandingData,
348 hdr->cp.minTransfer);
349
350 if (hdr->cp.outstandingData == 0 ||
351 hdr->cp.minTransfer != 0)
352 return 0;
353
354 memset(buffer, 0, buflen);
355 ret = opal_recv_cmd(dev);
356 } while (!ret);
357
358 return ret;
359}
360
361static int opal_send_recv(struct opal_dev *dev, cont_fn *cont)
362{
363 int ret;
364
365 ret = opal_send_cmd(dev);
366 if (ret)
367 return ret;
368 ret = opal_recv_cmd(dev);
369 if (ret)
370 return ret;
371 ret = opal_recv_check(dev);
372 if (ret)
373 return ret;
374 return cont(dev);
375}
376
377static void check_geometry(struct opal_dev *dev, const void *data)
378{
379 const struct d0_geometry_features *geo = data;
380
381 dev->align = geo->alignment_granularity;
382 dev->lowest_lba = geo->lowest_aligned_lba;
383}
384
385static int next(struct opal_dev *dev)
386{
387 const struct opal_step *step;
388 int state = 0, error = 0;
389
390 do {
391 step = &dev->steps[state];
392 if (!step->fn)
393 break;
394
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));
400
401
402
403
404
405
406
407
408 if (state > 1) {
409 end_opal_session_error(dev);
410 return error;
411 }
412
413 }
414 state++;
415 } while (!error);
416
417 return error;
418}
419
420static int opal_discovery0_end(struct opal_dev *dev)
421{
422 bool found_com_id = false, supported = true, single_user = false;
423 const struct d0_header *hdr = (struct d0_header *)dev->resp;
424 const u8 *epos = dev->resp, *cpos = dev->resp;
425 u16 comid = 0;
426 u32 hlen = be32_to_cpu(hdr->length);
427
428 print_buffer(dev->resp, hlen);
429 dev->mbr_enabled = false;
430
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;
435 }
436
437 epos += hlen;
438 cpos += sizeof(*hdr);
439
440 while (cpos < epos && supported) {
441 const struct d0_features *body =
442 (const struct d0_features *)cpos;
443
444 switch (be16_to_cpu(body->code)) {
445 case FC_TPER:
446 supported = check_tper(body->features);
447 break;
448 case FC_SINGLEUSER:
449 single_user = check_sum(body->features);
450 break;
451 case FC_GEOMETRY:
452 check_geometry(dev, body);
453 break;
454 case FC_LOCKING:
455 dev->mbr_enabled = check_mbrenabled(body->features);
456 break;
457 case FC_ENTERPRISE:
458 case FC_DATASTORE:
459
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
473 break;
474 default:
475 pr_debug("OPAL Unknown feature: %d\n",
476 be16_to_cpu(body->code));
477
478 }
479 cpos += body->length + 4;
480 }
481
482 if (!supported) {
483 pr_debug("This device is not Opal enabled. Not Supported!\n");
484 return -EOPNOTSUPP;
485 }
486
487 if (!single_user)
488 pr_debug("Device doesn't support single user mode\n");
489
490
491 if (!found_com_id) {
492 pr_debug("Could not find OPAL comid for device. Returning early\n");
493 return -EOPNOTSUPP;;
494 }
495
496 dev->comid = comid;
497
498 return 0;
499}
500
501static int opal_discovery0(struct opal_dev *dev, void *data)
502{
503 int ret;
504
505 memset(dev->resp, 0, IO_BUFFER_LENGTH);
506 dev->comid = OPAL_DISCOVERY_COMID;
507 ret = opal_recv_cmd(dev);
508 if (ret)
509 return ret;
510 return opal_discovery0_end(dev);
511}
512
513static void add_token_u8(int *err, struct opal_dev *cmd, u8 tok)
514{
515 if (*err)
516 return;
517 if (cmd->pos >= IO_BUFFER_LENGTH - 1) {
518 pr_debug("Error adding u8: end of buffer.\n");
519 *err = -ERANGE;
520 return;
521 }
522 cmd->cmd[cmd->pos++] = tok;
523}
524
525static void add_short_atom_header(struct opal_dev *cmd, bool bytestring,
526 bool has_sign, int len)
527{
528 u8 atom;
529 int err = 0;
530
531 atom = SHORT_ATOM_ID;
532 atom |= bytestring ? SHORT_ATOM_BYTESTRING : 0;
533 atom |= has_sign ? SHORT_ATOM_SIGNED : 0;
534 atom |= len & SHORT_ATOM_LEN_MASK;
535
536 add_token_u8(&err, cmd, atom);
537}
538
539static void add_medium_atom_header(struct opal_dev *cmd, bool bytestring,
540 bool has_sign, int len)
541{
542 u8 header0;
543
544 header0 = MEDIUM_ATOM_ID;
545 header0 |= bytestring ? MEDIUM_ATOM_BYTESTRING : 0;
546 header0 |= has_sign ? MEDIUM_ATOM_SIGNED : 0;
547 header0 |= (len >> 8) & MEDIUM_ATOM_LEN_MASK;
548 cmd->cmd[cmd->pos++] = header0;
549 cmd->cmd[cmd->pos++] = len;
550}
551
552static void add_token_u64(int *err, struct opal_dev *cmd, u64 number)
553{
554
555 size_t len;
556 int msb;
557 u8 n;
558
559 if (!(number & ~TINY_ATOM_DATA_MASK)) {
560 add_token_u8(err, cmd, number);
561 return;
562 }
563
564 msb = fls(number);
565 len = DIV_ROUND_UP(msb, 4);
566
567 if (cmd->pos >= IO_BUFFER_LENGTH - len - 1) {
568 pr_debug("Error adding u64: end of buffer.\n");
569 *err = -ERANGE;
570 return;
571 }
572 add_short_atom_header(cmd, false, false, len);
573 while (len--) {
574 n = number >> (len * 8);
575 add_token_u8(err, cmd, n);
576 }
577}
578
579static void add_token_bytestring(int *err, struct opal_dev *cmd,
580 const u8 *bytestring, size_t len)
581{
582 size_t header_len = 1;
583 bool is_short_atom = true;
584
585 if (*err)
586 return;
587
588 if (len & ~SHORT_ATOM_LEN_MASK) {
589 header_len = 2;
590 is_short_atom = false;
591 }
592
593 if (len >= IO_BUFFER_LENGTH - cmd->pos - header_len) {
594 pr_debug("Error adding bytestring: end of buffer.\n");
595 *err = -ERANGE;
596 return;
597 }
598
599 if (is_short_atom)
600 add_short_atom_header(cmd, true, false, len);
601 else
602 add_medium_atom_header(cmd, true, false, len);
603
604 memcpy(&cmd->cmd[cmd->pos], bytestring, len);
605 cmd->pos += len;
606
607}
608
609static int build_locking_range(u8 *buffer, size_t length, u8 lr)
610{
611 if (length > OPAL_UID_LENGTH) {
612 pr_debug("Can't build locking range. Length OOB\n");
613 return -ERANGE;
614 }
615
616 memcpy(buffer, opaluid[OPAL_LOCKINGRANGE_GLOBAL], OPAL_UID_LENGTH);
617
618 if (lr == 0)
619 return 0;
620 buffer[5] = LOCKING_RANGE_NON_GLOBAL;
621 buffer[7] = lr;
622
623 return 0;
624}
625
626static int build_locking_user(u8 *buffer, size_t length, u8 lr)
627{
628 if (length > OPAL_UID_LENGTH) {
629 pr_debug("Can't build locking range user, Length OOB\n");
630 return -ERANGE;
631 }
632
633 memcpy(buffer, opaluid[OPAL_USER1_UID], OPAL_UID_LENGTH);
634
635 buffer[7] = lr + 1;
636
637 return 0;
638}
639
640static void set_comid(struct opal_dev *cmd, u16 comid)
641{
642 struct opal_header *hdr = (struct opal_header *)cmd->cmd;
643
644 hdr->cp.extendedComID[0] = comid >> 8;
645 hdr->cp.extendedComID[1] = comid;
646 hdr->cp.extendedComID[2] = 0;
647 hdr->cp.extendedComID[3] = 0;
648}
649
650static int cmd_finalize(struct opal_dev *cmd, u32 hsn, u32 tsn)
651{
652 struct opal_header *hdr;
653 int err = 0;
654
655 add_token_u8(&err, cmd, OPAL_ENDOFDATA);
656 add_token_u8(&err, cmd, OPAL_STARTLIST);
657 add_token_u8(&err, cmd, 0);
658 add_token_u8(&err, cmd, 0);
659 add_token_u8(&err, cmd, 0);
660 add_token_u8(&err, cmd, OPAL_ENDLIST);
661
662 if (err) {
663 pr_debug("Error finalizing command.\n");
664 return -EFAULT;
665 }
666
667 hdr = (struct opal_header *) cmd->cmd;
668
669 hdr->pkt.tsn = cpu_to_be32(tsn);
670 hdr->pkt.hsn = cpu_to_be32(hsn);
671
672 hdr->subpkt.length = cpu_to_be32(cmd->pos - sizeof(*hdr));
673 while (cmd->pos % 4) {
674 if (cmd->pos >= IO_BUFFER_LENGTH) {
675 pr_debug("Error: Buffer overrun\n");
676 return -ERANGE;
677 }
678 cmd->cmd[cmd->pos++] = 0;
679 }
680 hdr->pkt.length = cpu_to_be32(cmd->pos - sizeof(hdr->cp) -
681 sizeof(hdr->pkt));
682 hdr->cp.length = cpu_to_be32(cmd->pos - sizeof(hdr->cp));
683
684 return 0;
685}
686
687static const struct opal_resp_tok *response_get_token(
688 const struct parsed_resp *resp,
689 int n)
690{
691 const struct opal_resp_tok *tok;
692
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);
697 }
698
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);
703 }
704
705 return tok;
706}
707
708static ssize_t response_parse_tiny(struct opal_resp_tok *tok,
709 const u8 *pos)
710{
711 tok->pos = pos;
712 tok->len = 1;
713 tok->width = OPAL_WIDTH_TINY;
714
715 if (pos[0] & TINY_ATOM_SIGNED) {
716 tok->type = OPAL_DTA_TOKENID_SINT;
717 } else {
718 tok->type = OPAL_DTA_TOKENID_UINT;
719 tok->stored.u = pos[0] & 0x3f;
720 }
721
722 return tok->len;
723}
724
725static ssize_t response_parse_short(struct opal_resp_tok *tok,
726 const u8 *pos)
727{
728 tok->pos = pos;
729 tok->len = (pos[0] & SHORT_ATOM_LEN_MASK) + 1;
730 tok->width = OPAL_WIDTH_SHORT;
731
732 if (pos[0] & SHORT_ATOM_BYTESTRING) {
733 tok->type = OPAL_DTA_TOKENID_BYTESTRING;
734 } else if (pos[0] & SHORT_ATOM_SIGNED) {
735 tok->type = OPAL_DTA_TOKENID_SINT;
736 } else {
737 u64 u_integer = 0;
738 ssize_t i, b = 0;
739
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;
744 }
745 for (i = tok->len - 1; i > 0; i--) {
746 u_integer |= ((u64)pos[i] << (8 * b));
747 b++;
748 }
749 tok->stored.u = u_integer;
750 }
751
752 return tok->len;
753}
754
755static ssize_t response_parse_medium(struct opal_resp_tok *tok,
756 const u8 *pos)
757{
758 tok->pos = pos;
759 tok->len = (((pos[0] & MEDIUM_ATOM_LEN_MASK) << 8) | pos[1]) + 2;
760 tok->width = OPAL_WIDTH_MEDIUM;
761
762 if (pos[0] & MEDIUM_ATOM_BYTESTRING)
763 tok->type = OPAL_DTA_TOKENID_BYTESTRING;
764 else if (pos[0] & MEDIUM_ATOM_SIGNED)
765 tok->type = OPAL_DTA_TOKENID_SINT;
766 else
767 tok->type = OPAL_DTA_TOKENID_UINT;
768
769 return tok->len;
770}
771
772static ssize_t response_parse_long(struct opal_resp_tok *tok,
773 const u8 *pos)
774{
775 tok->pos = pos;
776 tok->len = ((pos[1] << 16) | (pos[2] << 8) | pos[3]) + 4;
777 tok->width = OPAL_WIDTH_LONG;
778
779 if (pos[0] & LONG_ATOM_BYTESTRING)
780 tok->type = OPAL_DTA_TOKENID_BYTESTRING;
781 else if (pos[0] & LONG_ATOM_SIGNED)
782 tok->type = OPAL_DTA_TOKENID_SINT;
783 else
784 tok->type = OPAL_DTA_TOKENID_UINT;
785
786 return tok->len;
787}
788
789static ssize_t response_parse_token(struct opal_resp_tok *tok,
790 const u8 *pos)
791{
792 tok->pos = pos;
793 tok->len = 1;
794 tok->type = OPAL_DTA_TOKENID_TOKEN;
795 tok->width = OPAL_WIDTH_TOKEN;
796
797 return tok->len;
798}
799
800static int response_parse(const u8 *buf, size_t length,
801 struct parsed_resp *resp)
802{
803 const struct opal_header *hdr;
804 struct opal_resp_tok *iter;
805 int num_entries = 0;
806 int total;
807 ssize_t token_length;
808 const u8 *pos;
809 u32 clen, plen, slen;
810
811 if (!buf)
812 return -EFAULT;
813
814 if (!resp)
815 return -EFAULT;
816
817 hdr = (struct opal_header *)buf;
818 pos = buf;
819 pos += sizeof(*hdr);
820
821 clen = be32_to_cpu(hdr->cp.length);
822 plen = be32_to_cpu(hdr->pkt.length);
823 slen = be32_to_cpu(hdr->subpkt.length);
824 pr_debug("Response size: cp: %u, pkt: %u, subpkt: %u\n",
825 clen, plen, slen);
826
827 if (clen == 0 || plen == 0 || slen == 0 ||
828 slen > IO_BUFFER_LENGTH - sizeof(*hdr)) {
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;
833 }
834
835 if (pos > buf + length)
836 return -EFAULT;
837
838 iter = resp->toks;
839 total = slen;
840 print_buffer(pos, total);
841 while (total > 0) {
842 if (pos[0] <= TINY_ATOM_BYTE)
843 token_length = response_parse_tiny(iter, pos);
844 else if (pos[0] <= SHORT_ATOM_BYTE)
845 token_length = response_parse_short(iter, pos);
846 else if (pos[0] <= MEDIUM_ATOM_BYTE)
847 token_length = response_parse_medium(iter, pos);
848 else if (pos[0] <= LONG_ATOM_BYTE)
849 token_length = response_parse_long(iter, pos);
850 else
851 token_length = response_parse_token(iter, pos);
852
853 if (token_length < 0)
854 return token_length;
855
856 pos += token_length;
857 total -= token_length;
858 iter++;
859 num_entries++;
860 }
861
862 if (num_entries == 0) {
863 pr_debug("Couldn't parse response.\n");
864 return -EINVAL;
865 }
866 resp->num = num_entries;
867
868 return 0;
869}
870
871static size_t response_get_string(const struct parsed_resp *resp, int n,
872 const char **store)
873{
874 *store = NULL;
875 if (!resp) {
876 pr_debug("Response is NULL\n");
877 return 0;
878 }
879
880 if (n > resp->num) {
881 pr_debug("Response has %d tokens. Can't access %d\n",
882 resp->num, n);
883 return 0;
884 }
885
886 if (resp->toks[n].type != OPAL_DTA_TOKENID_BYTESTRING) {
887 pr_debug("Token is not a byte string!\n");
888 return 0;
889 }
890
891 *store = resp->toks[n].pos + 1;
892 return resp->toks[n].len - 1;
893}
894
895static u64 response_get_u64(const struct parsed_resp *resp, int n)
896{
897 if (!resp) {
898 pr_debug("Response is NULL\n");
899 return 0;
900 }
901
902 if (n > resp->num) {
903 pr_debug("Response has %d tokens. Can't access %d\n",
904 resp->num, n);
905 return 0;
906 }
907
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;
912 }
913
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;
919 }
920
921 return resp->toks[n].stored.u;
922}
923
924static bool response_token_matches(const struct opal_resp_tok *token, u8 match)
925{
926 if (IS_ERR(token) ||
927 token->type != OPAL_DTA_TOKENID_TOKEN ||
928 token->pos[0] != match)
929 return false;
930 return true;
931}
932
933static u8 response_status(const struct parsed_resp *resp)
934{
935 const struct opal_resp_tok *tok;
936
937 tok = response_get_token(resp, 0);
938 if (response_token_matches(tok, OPAL_ENDOFSESSION))
939 return 0;
940
941 if (resp->num < 5)
942 return DTAERROR_NO_METHOD_STATUS;
943
944 tok = response_get_token(resp, resp->num - 5);
945 if (!response_token_matches(tok, OPAL_STARTLIST))
946 return DTAERROR_NO_METHOD_STATUS;
947
948 tok = response_get_token(resp, resp->num - 1);
949 if (!response_token_matches(tok, OPAL_ENDLIST))
950 return DTAERROR_NO_METHOD_STATUS;
951
952 return response_get_u64(resp, resp->num - 4);
953}
954
955
956static int parse_and_check_status(struct opal_dev *dev)
957{
958 int error;
959
960 print_buffer(dev->cmd, dev->pos);
961
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;
966 }
967
968 return response_status(&dev->parsed);
969}
970
971static void clear_opal_cmd(struct opal_dev *dev)
972{
973 dev->pos = sizeof(struct opal_header);
974 memset(dev->cmd, 0, IO_BUFFER_LENGTH);
975}
976
977static int start_opal_session_cont(struct opal_dev *dev)
978{
979 u32 hsn, tsn;
980 int error = 0;
981
982 error = parse_and_check_status(dev);
983 if (error)
984 return error;
985
986 hsn = response_get_u64(&dev->parsed, 4);
987 tsn = response_get_u64(&dev->parsed, 5);
988
989 if (hsn == 0 && tsn == 0) {
990 pr_debug("Couldn't authenticate session\n");
991 return -EPERM;
992 }
993
994 dev->hsn = hsn;
995 dev->tsn = tsn;
996 return 0;
997}
998
999static void add_suspend_info(struct opal_dev *dev,
1000 struct opal_suspend_data *sus)
1001{
1002 struct opal_suspend_data *iter;
1003
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;
1009 }
1010 }
1011 list_add_tail(&sus->node, &dev->unlk_lst);
1012}
1013
1014static int end_session_cont(struct opal_dev *dev)
1015{
1016 dev->hsn = 0;
1017 dev->tsn = 0;
1018 return parse_and_check_status(dev);
1019}
1020
1021static int finalize_and_send(struct opal_dev *dev, cont_fn cont)
1022{
1023 int ret;
1024
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;
1029 }
1030
1031 print_buffer(dev->cmd, dev->pos);
1032
1033 return opal_send_recv(dev, cont);
1034}
1035
1036static int gen_key(struct opal_dev *dev, void *data)
1037{
1038 u8 uid[OPAL_UID_LENGTH];
1039 int err = 0;
1040
1041 clear_opal_cmd(dev);
1042 set_comid(dev, dev->comid);
1043
1044 memcpy(uid, dev->prev_data, min(sizeof(uid), dev->prev_d_len));
1045 kfree(dev->prev_data);
1046 dev->prev_data = NULL;
1047
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);
1054
1055 if (err) {
1056 pr_debug("Error building gen key command\n");
1057 return err;
1058
1059 }
1060 return finalize_and_send(dev, parse_and_check_status);
1061}
1062
1063static int get_active_key_cont(struct opal_dev *dev)
1064{
1065 const char *activekey;
1066 size_t keylen;
1067 int error = 0;
1068
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;
1077 }
1078 dev->prev_data = kmemdup(activekey, keylen, GFP_KERNEL);
1079
1080 if (!dev->prev_data)
1081 return -ENOMEM;
1082
1083 dev->prev_d_len = keylen;
1084
1085 return 0;
1086}
1087
1088static int get_active_key(struct opal_dev *dev, void *data)
1089{
1090 u8 uid[OPAL_UID_LENGTH];
1091 int err = 0;
1092 u8 *lr = data;
1093
1094 clear_opal_cmd(dev);
1095 set_comid(dev, dev->comid);
1096
1097 err = build_locking_range(uid, sizeof(uid), *lr);
1098 if (err)
1099 return err;
1100
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);
1109 add_token_u8(&err, dev, 10);
1110 add_token_u8(&err, dev, OPAL_ENDNAME);
1111 add_token_u8(&err, dev, OPAL_STARTNAME);
1112 add_token_u8(&err, dev, 4);
1113 add_token_u8(&err, dev, 10);
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;
1120 }
1121
1122 return finalize_and_send(dev, get_active_key_cont);
1123}
1124
1125static int generic_lr_enable_disable(struct opal_dev *dev,
1126 u8 *uid, bool rle, bool wle,
1127 bool rl, bool wl)
1128{
1129 int err = 0;
1130
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);
1134
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);
1139
1140 add_token_u8(&err, dev, OPAL_STARTNAME);
1141 add_token_u8(&err, dev, 5);
1142 add_token_u8(&err, dev, rle);
1143 add_token_u8(&err, dev, OPAL_ENDNAME);
1144
1145 add_token_u8(&err, dev, OPAL_STARTNAME);
1146 add_token_u8(&err, dev, 6);
1147 add_token_u8(&err, dev, wle);
1148 add_token_u8(&err, dev, OPAL_ENDNAME);
1149
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);
1154
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);
1159
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;
1164}
1165
1166static inline int enable_global_lr(struct opal_dev *dev, u8 *uid,
1167 struct opal_user_lr_setup *setup)
1168{
1169 int err;
1170
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;
1176}
1177
1178static int setup_locking_range(struct opal_dev *dev, void *data)
1179{
1180 u8 uid[OPAL_UID_LENGTH];
1181 struct opal_user_lr_setup *setup = data;
1182 u8 lr;
1183 int err = 0;
1184
1185 clear_opal_cmd(dev);
1186 set_comid(dev, dev->comid);
1187
1188 lr = setup->session.opal_key.lr;
1189 err = build_locking_range(uid, sizeof(uid), lr);
1190 if (err)
1191 return err;
1192
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);
1200
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);
1205
1206 add_token_u8(&err, dev, OPAL_STARTNAME);
1207 add_token_u8(&err, dev, 3);
1208 add_token_u64(&err, dev, setup->range_start);
1209 add_token_u8(&err, dev, OPAL_ENDNAME);
1210
1211 add_token_u8(&err, dev, OPAL_STARTNAME);
1212 add_token_u8(&err, dev, 4);
1213 add_token_u64(&err, dev, setup->range_length);
1214 add_token_u8(&err, dev, OPAL_ENDNAME);
1215
1216 add_token_u8(&err, dev, OPAL_STARTNAME);
1217 add_token_u8(&err, dev, 5);
1218 add_token_u64(&err, dev, !!setup->RLE);
1219 add_token_u8(&err, dev, OPAL_ENDNAME);
1220
1221 add_token_u8(&err, dev, OPAL_STARTNAME);
1222 add_token_u8(&err, dev, 6);
1223 add_token_u64(&err, dev, !!setup->WLE);
1224 add_token_u8(&err, dev, OPAL_ENDNAME);
1225
1226 add_token_u8(&err, dev, OPAL_ENDLIST);
1227 add_token_u8(&err, dev, OPAL_ENDNAME);
1228 add_token_u8(&err, dev, OPAL_ENDLIST);
1229
1230 }
1231 if (err) {
1232 pr_debug("Error building Setup Locking range command.\n");
1233 return err;
1234
1235 }
1236
1237 return finalize_and_send(dev, parse_and_check_status);
1238}
1239
1240static 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)
1245{
1246 u32 hsn;
1247 int err = 0;
1248
1249 if (key == NULL && auth != OPAL_ANYBODY_UID)
1250 return OPAL_INVAL_PARAM;
1251
1252 clear_opal_cmd(dev);
1253
1254 set_comid(dev, dev->comid);
1255 hsn = GENERIC_HOST_SESSION_NUM;
1256
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);
1266
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);
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);
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;
1287 }
1288
1289 if (err) {
1290 pr_debug("Error building start adminsp session command.\n");
1291 return err;
1292 }
1293
1294 return finalize_and_send(dev, start_opal_session_cont);
1295}
1296
1297static int start_anybodyASP_opal_session(struct opal_dev *dev, void *data)
1298{
1299 return start_generic_opal_session(dev, OPAL_ANYBODY_UID,
1300 OPAL_ADMINSP_UID, NULL, 0);
1301}
1302
1303static int start_SIDASP_opal_session(struct opal_dev *dev, void *data)
1304{
1305 int ret;
1306 const u8 *key = dev->prev_data;
1307
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;
1320 }
1321 return ret;
1322}
1323
1324static int start_admin1LSP_opal_session(struct opal_dev *dev, void *data)
1325{
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);
1330}
1331
1332static int start_auth_opal_session(struct opal_dev *dev, void *data)
1333{
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;
1338
1339 u8 *key = session->opal_key.key;
1340 u32 hsn = GENERIC_HOST_SESSION_NUM;
1341
1342 clear_opal_cmd(dev);
1343 set_comid(dev, dev->comid);
1344
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;
1350
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);
1358
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);
1364
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);
1379
1380 if (err) {
1381 pr_debug("Error building STARTSESSION command.\n");
1382 return err;
1383 }
1384
1385 return finalize_and_send(dev, start_opal_session_cont);
1386}
1387
1388static int revert_tper(struct opal_dev *dev, void *data)
1389{
1390 int err = 0;
1391
1392 clear_opal_cmd(dev);
1393 set_comid(dev, dev->comid);
1394
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;
1405 }
1406
1407 return finalize_and_send(dev, parse_and_check_status);
1408}
1409
1410static int internal_activate_user(struct opal_dev *dev, void *data)
1411{
1412 struct opal_session_info *session = data;
1413 u8 uid[OPAL_UID_LENGTH];
1414 int err = 0;
1415
1416 clear_opal_cmd(dev);
1417 set_comid(dev, dev->comid);
1418
1419 memcpy(uid, opaluid[OPAL_USER1_UID], OPAL_UID_LENGTH);
1420 uid[7] = session->who;
1421
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);
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);
1436
1437 if (err) {
1438 pr_debug("Error building Activate UserN command.\n");
1439 return err;
1440 }
1441
1442 return finalize_and_send(dev, parse_and_check_status);
1443}
1444
1445static int erase_locking_range(struct opal_dev *dev, void *data)
1446{
1447 struct opal_session_info *session = data;
1448 u8 uid[OPAL_UID_LENGTH];
1449 int err = 0;
1450
1451 clear_opal_cmd(dev);
1452 set_comid(dev, dev->comid);
1453
1454 if (build_locking_range(uid, sizeof(uid), session->opal_key.lr) < 0)
1455 return -ERANGE;
1456
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);
1463
1464 if (err) {
1465 pr_debug("Error building Erase Locking Range Command.\n");
1466 return err;
1467 }
1468 return finalize_and_send(dev, parse_and_check_status);
1469}
1470
1471static int set_mbr_done(struct opal_dev *dev, void *data)
1472{
1473 u8 *mbr_done_tf = data;
1474 int err = 0;
1475
1476 clear_opal_cmd(dev);
1477 set_comid(dev, dev->comid);
1478
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);
1489 add_token_u8(&err, dev, *mbr_done_tf);
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);
1494
1495 if (err) {
1496 pr_debug("Error Building set MBR Done command\n");
1497 return err;
1498 }
1499
1500 return finalize_and_send(dev, parse_and_check_status);
1501}
1502
1503static int set_mbr_enable_disable(struct opal_dev *dev, void *data)
1504{
1505 u8 *mbr_en_dis = data;
1506 int err = 0;
1507
1508 clear_opal_cmd(dev);
1509 set_comid(dev, dev->comid);
1510
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);
1526
1527 if (err) {
1528 pr_debug("Error Building set MBR done command\n");
1529 return err;
1530 }
1531
1532 return finalize_and_send(dev, parse_and_check_status);
1533}
1534
1535static int generic_pw_cmd(u8 *key, size_t key_len, u8 *cpin_uid,
1536 struct opal_dev *dev)
1537{
1538 int err = 0;
1539
1540 clear_opal_cmd(dev);
1541 set_comid(dev, dev->comid);
1542
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);
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);
1558
1559 return err;
1560}
1561
1562static int set_new_pw(struct opal_dev *dev, void *data)
1563{
1564 u8 cpin_uid[OPAL_UID_LENGTH];
1565 struct opal_session_info *usr = data;
1566
1567 memcpy(cpin_uid, opaluid[OPAL_C_PIN_ADMIN1], OPAL_UID_LENGTH);
1568
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;
1575 }
1576
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;
1581 }
1582
1583 return finalize_and_send(dev, parse_and_check_status);
1584}
1585
1586static int set_sid_cpin_pin(struct opal_dev *dev, void *data)
1587{
1588 u8 cpin_uid[OPAL_UID_LENGTH];
1589 struct opal_key *key = data;
1590
1591 memcpy(cpin_uid, opaluid[OPAL_C_PIN_SID], OPAL_UID_LENGTH);
1592
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;
1596 }
1597 return finalize_and_send(dev, parse_and_check_status);
1598}
1599
1600static int add_user_to_lr(struct opal_dev *dev, void *data)
1601{
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;
1606
1607 clear_opal_cmd(dev);
1608 set_comid(dev, dev->comid);
1609
1610 memcpy(lr_buffer, opaluid[OPAL_LOCKINGRANGE_ACE_RDLOCKED],
1611 OPAL_UID_LENGTH);
1612
1613 if (lkul->l_state == OPAL_RW)
1614 memcpy(lr_buffer, opaluid[OPAL_LOCKINGRANGE_ACE_WRLOCKED],
1615 OPAL_UID_LENGTH);
1616
1617 lr_buffer[7] = lkul->session.opal_key.lr;
1618
1619 memcpy(user_uid, opaluid[OPAL_USER1_UID], OPAL_UID_LENGTH);
1620
1621 user_uid[7] = lkul->session.who;
1622
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);
1627
1628 add_token_u8(&err, dev, OPAL_STARTLIST);
1629 add_token_u8(&err, dev, OPAL_STARTNAME);
1630 add_token_u8(&err, dev, OPAL_VALUES);
1631
1632 add_token_u8(&err, dev, OPAL_STARTLIST);
1633 add_token_u8(&err, dev, OPAL_STARTNAME);
1634 add_token_u8(&err, dev, 3);
1635
1636 add_token_u8(&err, dev, OPAL_STARTLIST);
1637
1638
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);
1645
1646
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);
1653
1654
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);
1660
1661
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);
1667
1668 if (err) {
1669 pr_debug("Error building add user to locking range command.\n");
1670 return err;
1671 }
1672
1673 return finalize_and_send(dev, parse_and_check_status);
1674}
1675
1676static int lock_unlock_locking_range(struct opal_dev *dev, void *data)
1677{
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;
1682
1683 clear_opal_cmd(dev);
1684 set_comid(dev, dev->comid);
1685
1686 if (build_locking_range(lr_buffer, sizeof(lr_buffer),
1687 lkul->session.opal_key.lr) < 0)
1688 return -ERANGE;
1689
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
1701 break;
1702 default:
1703 pr_debug("Tried to set an invalid locking state... returning to uland\n");
1704 return OPAL_INVAL_PARAM;
1705 }
1706
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);
1714
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);
1719
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);
1724
1725 add_token_u8(&err, dev, OPAL_ENDLIST);
1726 add_token_u8(&err, dev, OPAL_ENDNAME);
1727 add_token_u8(&err, dev, OPAL_ENDLIST);
1728
1729 if (err) {
1730 pr_debug("Error building SET command.\n");
1731 return err;
1732 }
1733 return finalize_and_send(dev, parse_and_check_status);
1734}
1735
1736
1737static int lock_unlock_locking_range_sum(struct opal_dev *dev, void *data)
1738{
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;
1743
1744 clear_opal_cmd(dev);
1745 set_comid(dev, dev->comid);
1746
1747 if (build_locking_range(lr_buffer, sizeof(lr_buffer),
1748 lkul->session.opal_key.lr) < 0)
1749 return -ERANGE;
1750
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
1762 break;
1763 default:
1764 pr_debug("Tried to set an invalid locking state.\n");
1765 return OPAL_INVAL_PARAM;
1766 }
1767 ret = generic_lr_enable_disable(dev, lr_buffer, 1, 1,
1768 read_locked, write_locked);
1769
1770 if (ret < 0) {
1771 pr_debug("Error building SET command.\n");
1772 return ret;
1773 }
1774 return finalize_and_send(dev, parse_and_check_status);
1775}
1776
1777static int activate_lsp(struct opal_dev *dev, void *data)
1778{
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;
1783
1784 clear_opal_cmd(dev);
1785 set_comid(dev, dev->comid);
1786
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);
1792
1793
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;
1799
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);
1806
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);
1812 }
1813 add_token_u8(&err, dev, OPAL_ENDLIST);
1814 add_token_u8(&err, dev, OPAL_ENDNAME);
1815 add_token_u8(&err, dev, OPAL_ENDLIST);
1816
1817 } else {
1818 add_token_u8(&err, dev, OPAL_STARTLIST);
1819 add_token_u8(&err, dev, OPAL_ENDLIST);
1820 }
1821
1822 if (err) {
1823 pr_debug("Error building Activate LockingSP command.\n");
1824 return err;
1825 }
1826
1827 return finalize_and_send(dev, parse_and_check_status);
1828}
1829
1830static int get_lsp_lifecycle_cont(struct opal_dev *dev)
1831{
1832 u8 lc_status;
1833 int error = 0;
1834
1835 error = parse_and_check_status(dev);
1836 if (error)
1837 return error;
1838
1839 lc_status = response_get_u64(&dev->parsed, 4);
1840
1841
1842 if (lc_status != OPAL_MANUFACTURED_INACTIVE) {
1843 pr_debug("Couldn't determine the status of the Lifecycle state\n");
1844 return -ENODEV;
1845 }
1846
1847 return 0;
1848}
1849
1850
1851static int get_lsp_lifecycle(struct opal_dev *dev, void *data)
1852{
1853 int err = 0;
1854
1855 clear_opal_cmd(dev);
1856 set_comid(dev, dev->comid);
1857
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);
1862
1863 add_token_u8(&err, dev, OPAL_STARTLIST);
1864 add_token_u8(&err, dev, OPAL_STARTLIST);
1865
1866 add_token_u8(&err, dev, OPAL_STARTNAME);
1867 add_token_u8(&err, dev, 3);
1868 add_token_u8(&err, dev, 6);
1869 add_token_u8(&err, dev, OPAL_ENDNAME);
1870
1871 add_token_u8(&err, dev, OPAL_STARTNAME);
1872 add_token_u8(&err, dev, 4);
1873 add_token_u8(&err, dev, 6);
1874 add_token_u8(&err, dev, OPAL_ENDNAME);
1875
1876 add_token_u8(&err, dev, OPAL_ENDLIST);
1877 add_token_u8(&err, dev, OPAL_ENDLIST);
1878
1879 if (err) {
1880 pr_debug("Error Building GET Lifecycle Status command\n");
1881 return err;
1882 }
1883
1884 return finalize_and_send(dev, get_lsp_lifecycle_cont);
1885}
1886
1887static int get_msid_cpin_pin_cont(struct opal_dev *dev)
1888{
1889 const char *msid_pin;
1890 size_t strlen;
1891 int error = 0;
1892
1893 error = parse_and_check_status(dev);
1894 if (error)
1895 return error;
1896
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;
1901 }
1902
1903 dev->prev_data = kmemdup(msid_pin, strlen, GFP_KERNEL);
1904 if (!dev->prev_data)
1905 return -ENOMEM;
1906
1907 dev->prev_d_len = strlen;
1908
1909 return 0;
1910}
1911
1912static int get_msid_cpin_pin(struct opal_dev *dev, void *data)
1913{
1914 int err = 0;
1915
1916 clear_opal_cmd(dev);
1917 set_comid(dev, dev->comid);
1918
1919 add_token_u8(&err, dev, OPAL_CALL);
1920 add_token_bytestring(&err, dev, opaluid[OPAL_C_PIN_MSID],
1921 OPAL_UID_LENGTH);
1922 add_token_bytestring(&err, dev, opalmethod[OPAL_GET], OPAL_UID_LENGTH);
1923
1924 add_token_u8(&err, dev, OPAL_STARTLIST);
1925 add_token_u8(&err, dev, OPAL_STARTLIST);
1926
1927 add_token_u8(&err, dev, OPAL_STARTNAME);
1928 add_token_u8(&err, dev, 3);
1929 add_token_u8(&err, dev, 3);
1930 add_token_u8(&err, dev, OPAL_ENDNAME);
1931
1932 add_token_u8(&err, dev, OPAL_STARTNAME);
1933 add_token_u8(&err, dev, 4);
1934 add_token_u8(&err, dev, 3);
1935 add_token_u8(&err, dev, OPAL_ENDNAME);
1936
1937 add_token_u8(&err, dev, OPAL_ENDLIST);
1938 add_token_u8(&err, dev, OPAL_ENDLIST);
1939
1940 if (err) {
1941 pr_debug("Error building Get MSID CPIN PIN command.\n");
1942 return err;
1943 }
1944
1945 return finalize_and_send(dev, get_msid_cpin_pin_cont);
1946}
1947
1948static int end_opal_session(struct opal_dev *dev, void *data)
1949{
1950 int err = 0;
1951
1952 clear_opal_cmd(dev);
1953 set_comid(dev, dev->comid);
1954 add_token_u8(&err, dev, OPAL_ENDOFSESSION);
1955
1956 if (err < 0)
1957 return err;
1958 return finalize_and_send(dev, end_session_cont);
1959}
1960
1961static int end_opal_session_error(struct opal_dev *dev)
1962{
1963 const struct opal_step error_end_session[] = {
1964 { end_opal_session, },
1965 { NULL, }
1966 };
1967 dev->steps = error_end_session;
1968 return next(dev);
1969}
1970
1971static inline void setup_opal_dev(struct opal_dev *dev,
1972 const struct opal_step *steps)
1973{
1974 dev->steps = steps;
1975 dev->tsn = 0;
1976 dev->hsn = 0;
1977 dev->prev_data = NULL;
1978}
1979
1980static int check_opal_support(struct opal_dev *dev)
1981{
1982 const struct opal_step steps[] = {
1983 { opal_discovery0, },
1984 { NULL, }
1985 };
1986 int ret;
1987
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;
1994}
1995
1996static void clean_opal_dev(struct opal_dev *dev)
1997{
1998
1999 struct opal_suspend_data *suspend, *next;
2000
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);
2005 }
2006 mutex_unlock(&dev->dev_lock);
2007}
2008
2009void free_opal_dev(struct opal_dev *dev)
2010{
2011 if (!dev)
2012 return;
2013 clean_opal_dev(dev);
2014 kfree(dev);
2015}
2016EXPORT_SYMBOL(free_opal_dev);
2017
2018struct opal_dev *init_opal_dev(void *data, sec_send_recv *send_recv)
2019{
2020 struct opal_dev *dev;
2021
2022 dev = kmalloc(sizeof(*dev), GFP_KERNEL);
2023 if (!dev)
2024 return NULL;
2025
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;
2034 }
2035 return dev;
2036}
2037EXPORT_SYMBOL(init_opal_dev);
2038
2039static int opal_secure_erase_locking_range(struct opal_dev *dev,
2040 struct opal_session_info *opal_session)
2041{
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, }
2049 };
2050 int ret;
2051
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;
2057}
2058
2059static int opal_erase_locking_range(struct opal_dev *dev,
2060 struct opal_session_info *opal_session)
2061{
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, }
2068 };
2069 int ret;
2070
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;
2076}
2077
2078static int opal_enable_disable_shadow_mbr(struct opal_dev *dev,
2079 struct opal_mbr_data *opal_mbr)
2080{
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, }
2090 };
2091 int ret;
2092
2093 if (opal_mbr->enable_disable != OPAL_MBR_ENABLE &&
2094 opal_mbr->enable_disable != OPAL_MBR_DISABLE)
2095 return -EINVAL;
2096
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;
2102}
2103
2104static int opal_save(struct opal_dev *dev, struct opal_lock_unlock *lk_unlk)
2105{
2106 struct opal_suspend_data *suspend;
2107
2108 suspend = kzalloc(sizeof(*suspend), GFP_KERNEL);
2109 if (!suspend)
2110 return -ENOMEM;
2111
2112 suspend->unlk = *lk_unlk;
2113 suspend->lr = lk_unlk->session.opal_key.lr;
2114
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;
2120}
2121
2122static int opal_add_user_to_lr(struct opal_dev *dev,
2123 struct opal_lock_unlock *lk_unlk)
2124{
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, }
2131 };
2132 int ret;
2133
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;
2138 }
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;
2144 }
2145 if (lk_unlk->session.sum) {
2146 pr_debug("%s not supported in sum. Use setup locking range\n",
2147 __func__);
2148 return -EINVAL;
2149 }
2150
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;
2156}
2157
2158static int opal_reverttper(struct opal_dev *dev, struct opal_key *opal)
2159{
2160 const struct opal_step revert_steps[] = {
2161 { opal_discovery0, },
2162 { start_SIDASP_opal_session, opal },
2163 { revert_tper, },
2164 { NULL, }
2165 };
2166 int ret;
2167
2168 mutex_lock(&dev->dev_lock);
2169 setup_opal_dev(dev, revert_steps);
2170 ret = next(dev);
2171 mutex_unlock(&dev->dev_lock);
2172
2173
2174
2175
2176
2177 if (!ret)
2178 clean_opal_dev(dev);
2179
2180 return ret;
2181}
2182
2183static int __opal_lock_unlock(struct opal_dev *dev,
2184 struct opal_lock_unlock *lk_unlk)
2185{
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, }
2192 };
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, }
2199 };
2200
2201 dev->steps = lk_unlk->session.sum ? unlock_sum_steps : unlock_steps;
2202 return next(dev);
2203}
2204
2205static int __opal_set_mbr_done(struct opal_dev *dev, struct opal_key *key)
2206{
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, }
2214 };
2215
2216 dev->steps = mbrdone_step;
2217 return next(dev);
2218}
2219
2220static int opal_lock_unlock(struct opal_dev *dev,
2221 struct opal_lock_unlock *lk_unlk)
2222{
2223 int ret;
2224
2225 if (lk_unlk->session.who < OPAL_ADMIN1 ||
2226 lk_unlk->session.who > OPAL_USER9)
2227 return -EINVAL;
2228
2229 mutex_lock(&dev->dev_lock);
2230 ret = __opal_lock_unlock(dev, lk_unlk);
2231 mutex_unlock(&dev->dev_lock);
2232 return ret;
2233}
2234
2235static int opal_take_ownership(struct opal_dev *dev, struct opal_key *opal)
2236{
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, }
2246 };
2247 int ret;
2248
2249 if (!dev)
2250 return -ENODEV;
2251
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;
2257}
2258
2259static int opal_activate_lsp(struct opal_dev *dev, struct opal_lr_act *opal_lr_act)
2260{
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, }
2268 };
2269 int ret;
2270
2271 if (!opal_lr_act->num_lrs || opal_lr_act->num_lrs > OPAL_MAX_LRS)
2272 return -EINVAL;
2273
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;
2279}
2280
2281static int opal_setup_locking_range(struct opal_dev *dev,
2282 struct opal_user_lr_setup *opal_lrs)
2283{
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, }
2290 };
2291 int ret;
2292
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;
2298}
2299
2300static int opal_set_new_pw(struct opal_dev *dev, struct opal_new_pw *opal_pw)
2301{
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 }
2308 };
2309 int ret;
2310
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;
2316
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;
2322}
2323
2324static int opal_activate_user(struct opal_dev *dev,
2325 struct opal_session_info *opal_session)
2326{
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, }
2333 };
2334 int ret;
2335
2336
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;
2341 }
2342
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;
2348}
2349
2350bool opal_unlock_from_suspend(struct opal_dev *dev)
2351{
2352 struct opal_suspend_data *suspend;
2353 bool was_failure = false;
2354 int ret = 0;
2355
2356 if (!dev)
2357 return false;
2358 if (!dev->supported)
2359 return false;
2360
2361 mutex_lock(&dev->dev_lock);
2362 setup_opal_dev(dev, NULL);
2363
2364 list_for_each_entry(suspend, &dev->unlk_lst, node) {
2365 dev->tsn = 0;
2366 dev->hsn = 0;
2367
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;
2374 }
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");
2379 }
2380 }
2381 mutex_unlock(&dev->dev_lock);
2382 return was_failure;
2383}
2384EXPORT_SYMBOL(opal_unlock_from_suspend);
2385
2386int sed_ioctl(struct opal_dev *dev, unsigned int cmd, void __user *arg)
2387{
2388 void *p;
2389 int ret = -ENOTTY;
2390
2391 if (!capable(CAP_SYS_ADMIN))
2392 return -EACCES;
2393 if (!dev)
2394 return -ENOTSUPP;
2395 if (!dev->supported)
2396 return -ENOTSUPP;
2397
2398 p = memdup_user(arg, _IOC_SIZE(cmd));
2399 if (IS_ERR(p))
2400 return PTR_ERR(p);
2401
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;
2441 }
2442
2443 kfree(p);
2444 return ret;
2445}
2446EXPORT_SYMBOL_GPL(sed_ioctl);
2447