block: Don't invalidate pagecache for invalid falloc modes
[linux-2.6-block.git] / block / sed-opal.c
CommitLineData
8c16567d 1// SPDX-License-Identifier: GPL-2.0
455a7b23
SB
2/*
3 * Copyright © 2016 Intel Corporation
4 *
5 * Authors:
6 * Scott Bauer <scott.bauer@intel.com>
7 * Rafael Antognolli <rafael.antognolli@intel.com>
455a7b23
SB
8 */
9
10#define pr_fmt(fmt) KBUILD_MODNAME ":OPAL: " fmt
11
12#include <linux/delay.h>
13#include <linux/device.h>
14#include <linux/kernel.h>
15#include <linux/list.h>
322cbb50 16#include <linux/blkdev.h>
455a7b23
SB
17#include <linux/slab.h>
18#include <linux/uaccess.h>
19#include <uapi/linux/sed-opal.h>
20#include <linux/sed-opal.h>
21#include <linux/string.h>
22#include <linux/kdev_t.h>
3bfeb612
GJ
23#include <linux/key.h>
24#include <linux/key-type.h>
25#include <keys/user-type.h>
455a7b23
SB
26
27#include "opal_proto.h"
28
4f1244c8
CH
29#define IO_BUFFER_LENGTH 2048
30#define MAX_TOKS 64
31
a9b25b4c
JR
32/* Number of bytes needed by cmd_finalize. */
33#define CMD_FINALIZE_BYTES_NEEDED 7
34
3bfeb612
GJ
35static struct key *sed_opal_keyring;
36
eed64951
JD
37struct opal_step {
38 int (*fn)(struct opal_dev *dev, void *data);
39 void *data;
40};
41typedef int (cont_fn)(struct opal_dev *dev);
4f1244c8
CH
42
43enum opal_atom_width {
44 OPAL_WIDTH_TINY,
45 OPAL_WIDTH_SHORT,
46 OPAL_WIDTH_MEDIUM,
47 OPAL_WIDTH_LONG,
48 OPAL_WIDTH_TOKEN
49};
50
51/*
52 * On the parsed response, we don't store again the toks that are already
53 * stored in the response buffer. Instead, for each token, we just store a
54 * pointer to the position in the buffer where the token starts, and the size
55 * of the token in bytes.
56 */
57struct opal_resp_tok {
58 const u8 *pos;
59 size_t len;
60 enum opal_response_token type;
61 enum opal_atom_width width;
62 union {
63 u64 u;
64 s64 s;
65 } stored;
66};
67
68/*
69 * From the response header it's not possible to know how many tokens there are
70 * on the payload. So we hardcode that the maximum will be MAX_TOKS, and later
71 * if we start dealing with messages that have more than that, we can increase
72 * this number. This is done to avoid having to make two passes through the
73 * response, the first one counting how many tokens we have and the second one
74 * actually storing the positions.
75 */
76struct parsed_resp {
77 int num;
78 struct opal_resp_tok toks[MAX_TOKS];
79};
80
81struct opal_dev {
c6ea7060 82 u32 flags;
4f1244c8
CH
83
84 void *data;
85 sec_send_recv *send_recv;
86
4f1244c8
CH
87 struct mutex dev_lock;
88 u16 comid;
89 u32 hsn;
90 u32 tsn;
9e05a259 91 u64 align; /* alignment granularity */
4f1244c8 92 u64 lowest_lba;
9e05a259
OK
93 u32 logical_block_size;
94 u8 align_required; /* ALIGN: 0 or 1 */
4f1244c8
CH
95
96 size_t pos;
f829230d
SS
97 u8 *cmd;
98 u8 *resp;
4f1244c8
CH
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
455a7b23
SB
108static 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 },
136
137 /* tables */
dc301025 138 [OPAL_TABLE_TABLE] =
ff91064e 139 { 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01 },
455a7b23
SB
140 [OPAL_LOCKINGRANGE_GLOBAL] =
141 { 0x00, 0x00, 0x08, 0x02, 0x00, 0x00, 0x00, 0x01 },
8be19a02
OK
142 [OPAL_LOCKINGRANGE_ACE_START_TO_KEY] =
143 { 0x00, 0x00, 0x00, 0x08, 0x00, 0x03, 0xD0, 0x01 },
455a7b23
SB
144 [OPAL_LOCKINGRANGE_ACE_RDLOCKED] =
145 { 0x00, 0x00, 0x00, 0x08, 0x00, 0x03, 0xE0, 0x01 },
146 [OPAL_LOCKINGRANGE_ACE_WRLOCKED] =
147 { 0x00, 0x00, 0x00, 0x08, 0x00, 0x03, 0xE8, 0x01 },
148 [OPAL_MBRCONTROL] =
149 { 0x00, 0x00, 0x08, 0x03, 0x00, 0x00, 0x00, 0x01 },
150 [OPAL_MBR] =
151 { 0x00, 0x00, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00 },
152 [OPAL_AUTHORITY_TABLE] =
153 { 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00},
154 [OPAL_C_PIN_TABLE] =
155 { 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x00},
156 [OPAL_LOCKING_INFO_TABLE] =
157 { 0x00, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x01 },
158 [OPAL_ENTERPRISE_LOCKING_INFO_TABLE] =
159 { 0x00, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x00 },
62c441c6
RR
160 [OPAL_DATASTORE] =
161 { 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x00, 0x00 },
455a7b23
SB
162
163 /* C_PIN_TABLE object ID's */
1e815b33 164 [OPAL_C_PIN_MSID] =
455a7b23
SB
165 { 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x84, 0x02},
166 [OPAL_C_PIN_SID] =
167 { 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x01},
168 [OPAL_C_PIN_ADMIN1] =
169 { 0x00, 0x00, 0x00, 0x0B, 0x00, 0x01, 0x00, 0x01},
170
171 /* half UID's (only first 4 bytes used) */
455a7b23
SB
172 [OPAL_HALF_UID_AUTHORITY_OBJ_REF] =
173 { 0x00, 0x00, 0x0C, 0x05, 0xff, 0xff, 0xff, 0xff },
174 [OPAL_HALF_UID_BOOLEAN_ACE] =
175 { 0x00, 0x00, 0x04, 0x0E, 0xff, 0xff, 0xff, 0xff },
176
177 /* special value for omitted optional parameter */
178 [OPAL_UID_HEXFF] =
179 { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
180};
181
182/*
183 * TCG Storage SSC Methods.
184 * Derived from: TCG_Storage_Architecture_Core_Spec_v2.01_r1.00
185 * Section: 6.3 Assigned UIDs
186 */
1b6b75b0 187static const u8 opalmethod[][OPAL_METHOD_LENGTH] = {
455a7b23
SB
188 [OPAL_PROPERTIES] =
189 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x01 },
190 [OPAL_STARTSESSION] =
191 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x02 },
192 [OPAL_REVERT] =
193 { 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x02, 0x02 },
194 [OPAL_ACTIVATE] =
195 { 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x02, 0x03 },
196 [OPAL_EGET] =
197 { 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06 },
198 [OPAL_ESET] =
199 { 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x07 },
200 [OPAL_NEXT] =
201 { 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x08 },
202 [OPAL_EAUTHENTICATE] =
203 { 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0c },
204 [OPAL_GETACL] =
205 { 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0d },
206 [OPAL_GENKEY] =
207 { 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x10 },
208 [OPAL_REVERTSP] =
209 { 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x11 },
210 [OPAL_GET] =
211 { 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x16 },
212 [OPAL_SET] =
213 { 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x17 },
214 [OPAL_AUTHENTICATE] =
215 { 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x1c },
216 [OPAL_RANDOM] =
217 { 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x01 },
218 [OPAL_ERASE] =
219 { 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x08, 0x03 },
220};
221
455a7b23 222static int end_opal_session_error(struct opal_dev *dev);
0af2648e 223static int opal_discovery0_step(struct opal_dev *dev);
455a7b23
SB
224
225struct opal_suspend_data {
226 struct opal_lock_unlock unlk;
227 u8 lr;
228 struct list_head node;
229};
230
231/*
232 * Derived from:
233 * TCG_Storage_Architecture_Core_Spec_v2.01_r1.00
234 * Section: 5.1.5 Method Status Codes
235 */
236static const char * const opal_errors[] = {
237 "Success",
238 "Not Authorized",
239 "Unknown Error",
240 "SP Busy",
241 "SP Failed",
242 "SP Disabled",
243 "SP Frozen",
244 "No Sessions Available",
245 "Uniqueness Conflict",
246 "Insufficient Space",
247 "Insufficient Rows",
248 "Invalid Function",
249 "Invalid Parameter",
250 "Invalid Reference",
251 "Unknown Error",
252 "TPER Malfunction",
253 "Transaction Failure",
254 "Response Overflow",
255 "Authority Locked Out",
256};
257
258static const char *opal_error_to_human(int error)
259{
260 if (error == 0x3f)
261 return "Failed";
262
263 if (error >= ARRAY_SIZE(opal_errors) || error < 0)
264 return "Unknown Error";
265
266 return opal_errors[error];
267}
268
269static void print_buffer(const u8 *ptr, u32 length)
270{
271#ifdef DEBUG
272 print_hex_dump_bytes("OPAL: ", DUMP_PREFIX_OFFSET, ptr, length);
273 pr_debug("\n");
274#endif
275}
276
3bfeb612
GJ
277/*
278 * Allocate/update a SED Opal key and add it to the SED Opal keyring.
279 */
280static int update_sed_opal_key(const char *desc, u_char *key_data, int keylen)
281{
282 key_ref_t kr;
283
284 if (!sed_opal_keyring)
285 return -ENOKEY;
286
287 kr = key_create_or_update(make_key_ref(sed_opal_keyring, true), "user",
288 desc, (const void *)key_data, keylen,
289 KEY_USR_VIEW | KEY_USR_SEARCH | KEY_USR_WRITE,
290 KEY_ALLOC_NOT_IN_QUOTA | KEY_ALLOC_BUILT_IN |
291 KEY_ALLOC_BYPASS_RESTRICTION);
292 if (IS_ERR(kr)) {
293 pr_err("Error adding SED key (%ld)\n", PTR_ERR(kr));
294 return PTR_ERR(kr);
295 }
296
297 return 0;
298}
299
300/*
301 * Read a SED Opal key from the SED Opal keyring.
302 */
303static int read_sed_opal_key(const char *key_name, u_char *buffer, int buflen)
304{
305 int ret;
306 key_ref_t kref;
307 struct key *key;
308
309 if (!sed_opal_keyring)
310 return -ENOKEY;
311
312 kref = keyring_search(make_key_ref(sed_opal_keyring, true),
313 &key_type_user, key_name, true);
314
315 if (IS_ERR(kref))
316 ret = PTR_ERR(kref);
317
318 key = key_ref_to_ptr(kref);
319 down_read(&key->sem);
320 ret = key_validate(key);
321 if (ret == 0) {
322 if (buflen > key->datalen)
323 buflen = key->datalen;
324
325 ret = key->type->read(key, (char *)buffer, buflen);
326 }
327 up_read(&key->sem);
328
329 key_ref_put(kref);
330
331 return ret;
332}
333
334static int opal_get_key(struct opal_dev *dev, struct opal_key *key)
335{
336 int ret = 0;
337
338 switch (key->key_type) {
339 case OPAL_INCLUDED:
340 /* the key is ready to use */
341 break;
342 case OPAL_KEYRING:
343 /* the key is in the keyring */
344 ret = read_sed_opal_key(OPAL_AUTH_KEY, key->key, OPAL_KEY_MAX);
345 if (ret > 0) {
346 if (ret > U8_MAX) {
347 ret = -ENOSPC;
348 goto error;
349 }
350 key->key_len = ret;
351 key->key_type = OPAL_INCLUDED;
352 }
353 break;
354 default:
355 ret = -EINVAL;
356 break;
357 }
358 if (ret < 0)
359 goto error;
360
361 /* must have a PEK by now or it's an error */
362 if (key->key_type != OPAL_INCLUDED || key->key_len == 0) {
363 ret = -EINVAL;
364 goto error;
365 }
366 return 0;
367error:
368 pr_debug("Error getting password: %d\n", ret);
369 return ret;
370}
371
455a7b23
SB
372static bool check_tper(const void *data)
373{
374 const struct d0_tper_features *tper = data;
375 u8 flags = tper->supported_features;
376
377 if (!(flags & TPER_SYNC_SUPPORTED)) {
591c59d1
SB
378 pr_debug("TPer sync not supported. flags = %d\n",
379 tper->supported_features);
455a7b23
SB
380 return false;
381 }
382
383 return true;
384}
385
c6ea7060 386static bool check_lcksuppt(const void *data)
387{
388 const struct d0_locking_features *lfeat = data;
389 u8 sup_feat = lfeat->supported_features;
390
391 return !!(sup_feat & LOCKING_SUPPORTED_MASK);
392}
393
394static bool check_lckenabled(const void *data)
395{
396 const struct d0_locking_features *lfeat = data;
397 u8 sup_feat = lfeat->supported_features;
398
399 return !!(sup_feat & LOCKING_ENABLED_MASK);
400}
401
402static bool check_locked(const void *data)
403{
404 const struct d0_locking_features *lfeat = data;
405 u8 sup_feat = lfeat->supported_features;
406
407 return !!(sup_feat & LOCKED_MASK);
408}
409
dbec491b
SB
410static bool check_mbrenabled(const void *data)
411{
412 const struct d0_locking_features *lfeat = data;
413 u8 sup_feat = lfeat->supported_features;
414
415 return !!(sup_feat & MBR_ENABLED_MASK);
416}
417
c6ea7060 418static bool check_mbrdone(const void *data)
419{
420 const struct d0_locking_features *lfeat = data;
421 u8 sup_feat = lfeat->supported_features;
422
423 return !!(sup_feat & MBR_DONE_MASK);
424}
425
455a7b23
SB
426static bool check_sum(const void *data)
427{
428 const struct d0_single_user_mode *sum = data;
429 u32 nlo = be32_to_cpu(sum->num_locking_objects);
430
431 if (nlo == 0) {
591c59d1 432 pr_debug("Need at least one locking object.\n");
455a7b23
SB
433 return false;
434 }
435
436 pr_debug("Number of locking objects: %d\n", nlo);
437
438 return true;
439}
440
441static u16 get_comid_v100(const void *data)
442{
443 const struct d0_opal_v100 *v100 = data;
444
445 return be16_to_cpu(v100->baseComID);
446}
447
448static u16 get_comid_v200(const void *data)
449{
450 const struct d0_opal_v200 *v200 = data;
451
452 return be16_to_cpu(v200->baseComID);
453}
454
455static int opal_send_cmd(struct opal_dev *dev)
456{
4f1244c8 457 return dev->send_recv(dev->data, dev->comid, TCG_SECP_01,
455a7b23
SB
458 dev->cmd, IO_BUFFER_LENGTH,
459 true);
460}
461
462static int opal_recv_cmd(struct opal_dev *dev)
463{
4f1244c8 464 return dev->send_recv(dev->data, dev->comid, TCG_SECP_01,
455a7b23
SB
465 dev->resp, IO_BUFFER_LENGTH,
466 false);
467}
468
469static int opal_recv_check(struct opal_dev *dev)
470{
471 size_t buflen = IO_BUFFER_LENGTH;
472 void *buffer = dev->resp;
473 struct opal_header *hdr = buffer;
474 int ret;
475
476 do {
477 pr_debug("Sent OPAL command: outstanding=%d, minTransfer=%d\n",
478 hdr->cp.outstandingData,
479 hdr->cp.minTransfer);
480
481 if (hdr->cp.outstandingData == 0 ||
482 hdr->cp.minTransfer != 0)
483 return 0;
484
485 memset(buffer, 0, buflen);
486 ret = opal_recv_cmd(dev);
487 } while (!ret);
488
489 return ret;
490}
491
492static int opal_send_recv(struct opal_dev *dev, cont_fn *cont)
493{
494 int ret;
495
496 ret = opal_send_cmd(dev);
497 if (ret)
498 return ret;
499 ret = opal_recv_cmd(dev);
500 if (ret)
501 return ret;
502 ret = opal_recv_check(dev);
503 if (ret)
504 return ret;
505 return cont(dev);
506}
507
508static void check_geometry(struct opal_dev *dev, const void *data)
509{
510 const struct d0_geometry_features *geo = data;
511
a9eb49c9
RD
512 dev->align = be64_to_cpu(geo->alignment_granularity);
513 dev->lowest_lba = be64_to_cpu(geo->lowest_aligned_lba);
9e05a259
OK
514 dev->logical_block_size = be32_to_cpu(geo->logical_block_size);
515 dev->align_required = geo->reserved01 & 1;
455a7b23
SB
516}
517
0af2648e
DK
518static int execute_step(struct opal_dev *dev,
519 const struct opal_step *step, size_t stepIndex)
520{
521 int error = step->fn(dev, step->data);
522
523 if (error) {
524 pr_debug("Step %zu (%pS) failed with error %d: %s\n",
525 stepIndex, step->fn, error,
526 opal_error_to_human(error));
527 }
528
529 return error;
530}
531
a80f36cc
DK
532static int execute_steps(struct opal_dev *dev,
533 const struct opal_step *steps, size_t n_steps)
455a7b23 534{
0af2648e
DK
535 size_t state = 0;
536 int error;
455a7b23 537
0af2648e
DK
538 /* first do a discovery0 */
539 error = opal_discovery0_step(dev);
540 if (error)
541 return error;
455a7b23 542
0af2648e
DK
543 for (state = 0; state < n_steps; state++) {
544 error = execute_step(dev, &steps[state], state);
3db87236
DK
545 if (error)
546 goto out_error;
547 }
2d19020b 548
3db87236
DK
549 return 0;
550
551out_error:
552 /*
0af2648e
DK
553 * For each OPAL command the first step in steps starts some sort of
554 * session. If an error occurred in the initial discovery0 or if an
555 * error occurred in the first step (and thus stopping the loop with
556 * state == 0) then there was an error before or during the attempt to
557 * start a session. Therefore we shouldn't attempt to terminate a
558 * session, as one has not yet been created.
3db87236 559 */
0af2648e 560 if (state > 0)
3db87236 561 end_opal_session_error(dev);
455a7b23
SB
562
563 return error;
564}
565
9fb10726 566static int opal_discovery0_end(struct opal_dev *dev, void *data)
455a7b23 567{
9fb10726
GJ
568 struct opal_discovery *discv_out = data; /* may be NULL */
569 u8 __user *buf_out;
570 u64 len_out;
455a7b23
SB
571 bool found_com_id = false, supported = true, single_user = false;
572 const struct d0_header *hdr = (struct d0_header *)dev->resp;
573 const u8 *epos = dev->resp, *cpos = dev->resp;
574 u16 comid = 0;
77039b96 575 u32 hlen = be32_to_cpu(hdr->length);
455a7b23 576
77039b96 577 print_buffer(dev->resp, hlen);
c6ea7060 578 dev->flags &= OPAL_FL_SUPPORTED;
455a7b23 579
77039b96 580 if (hlen > IO_BUFFER_LENGTH - sizeof(*hdr)) {
591c59d1
SB
581 pr_debug("Discovery length overflows buffer (%zu+%u)/%u\n",
582 sizeof(*hdr), hlen, IO_BUFFER_LENGTH);
77039b96
JD
583 return -EFAULT;
584 }
585
9fb10726
GJ
586 if (discv_out) {
587 buf_out = (u8 __user *)(uintptr_t)discv_out->data;
588 len_out = min_t(u64, discv_out->size, hlen);
589 if (buf_out && copy_to_user(buf_out, dev->resp, len_out))
590 return -EFAULT;
591
592 discv_out->size = hlen; /* actual size of data */
593 }
594
77039b96 595 epos += hlen; /* end of buffer */
455a7b23
SB
596 cpos += sizeof(*hdr); /* current position on buffer */
597
598 while (cpos < epos && supported) {
599 const struct d0_features *body =
600 (const struct d0_features *)cpos;
601
602 switch (be16_to_cpu(body->code)) {
603 case FC_TPER:
604 supported = check_tper(body->features);
605 break;
606 case FC_SINGLEUSER:
607 single_user = check_sum(body->features);
9ec041ea
LB
608 if (single_user)
609 dev->flags |= OPAL_FL_SUM_SUPPORTED;
455a7b23
SB
610 break;
611 case FC_GEOMETRY:
612 check_geometry(dev, body);
613 break;
614 case FC_LOCKING:
c6ea7060 615 if (check_lcksuppt(body->features))
616 dev->flags |= OPAL_FL_LOCKING_SUPPORTED;
617 if (check_lckenabled(body->features))
618 dev->flags |= OPAL_FL_LOCKING_ENABLED;
619 if (check_locked(body->features))
620 dev->flags |= OPAL_FL_LOCKED;
621 if (check_mbrenabled(body->features))
622 dev->flags |= OPAL_FL_MBR_ENABLED;
623 if (check_mbrdone(body->features))
624 dev->flags |= OPAL_FL_MBR_DONE;
dbec491b 625 break;
455a7b23
SB
626 case FC_ENTERPRISE:
627 case FC_DATASTORE:
628 /* some ignored properties */
629 pr_debug("Found OPAL feature description: %d\n",
630 be16_to_cpu(body->code));
631 break;
632 case FC_OPALV100:
633 comid = get_comid_v100(body->features);
634 found_com_id = true;
635 break;
636 case FC_OPALV200:
637 comid = get_comid_v200(body->features);
638 found_com_id = true;
639 break;
640 case 0xbfff ... 0xffff:
641 /* vendor specific, just ignore */
642 break;
643 default:
644 pr_debug("OPAL Unknown feature: %d\n",
645 be16_to_cpu(body->code));
646
647 }
648 cpos += body->length + 4;
649 }
650
651 if (!supported) {
f5b37b7c 652 pr_debug("This device is not Opal enabled. Not Supported!\n");
455a7b23
SB
653 return -EOPNOTSUPP;
654 }
655
656 if (!single_user)
f5b37b7c 657 pr_debug("Device doesn't support single user mode\n");
455a7b23
SB
658
659
660 if (!found_com_id) {
f5b37b7c 661 pr_debug("Could not find OPAL comid for device. Returning early\n");
ed7158ba 662 return -EOPNOTSUPP;
455a7b23
SB
663 }
664
665 dev->comid = comid;
666
667 return 0;
668}
669
eed64951 670static int opal_discovery0(struct opal_dev *dev, void *data)
455a7b23
SB
671{
672 int ret;
673
674 memset(dev->resp, 0, IO_BUFFER_LENGTH);
675 dev->comid = OPAL_DISCOVERY_COMID;
676 ret = opal_recv_cmd(dev);
677 if (ret)
678 return ret;
5cc23ed7 679
9fb10726 680 return opal_discovery0_end(dev, data);
455a7b23
SB
681}
682
0af2648e
DK
683static int opal_discovery0_step(struct opal_dev *dev)
684{
685 const struct opal_step discovery0_step = {
9fb10726 686 opal_discovery0, NULL
0af2648e 687 };
5cc23ed7 688
0af2648e
DK
689 return execute_step(dev, &discovery0_step, 0);
690}
691
a9b25b4c
JR
692static size_t remaining_size(struct opal_dev *cmd)
693{
694 return IO_BUFFER_LENGTH - cmd->pos;
695}
696
e2821a50 697static bool can_add(int *err, struct opal_dev *cmd, size_t len)
455a7b23
SB
698{
699 if (*err)
e2821a50
JR
700 return false;
701
a9b25b4c 702 if (remaining_size(cmd) < len) {
e2821a50 703 pr_debug("Error adding %zu bytes: end of buffer.\n", len);
455a7b23 704 *err = -ERANGE;
e2821a50 705 return false;
455a7b23 706 }
e2821a50
JR
707
708 return true;
709}
710
711static void add_token_u8(int *err, struct opal_dev *cmd, u8 tok)
712{
713 if (!can_add(err, cmd, 1))
714 return;
5cc23ed7 715
455a7b23
SB
716 cmd->cmd[cmd->pos++] = tok;
717}
718
719static void add_short_atom_header(struct opal_dev *cmd, bool bytestring,
720 bool has_sign, int len)
721{
722 u8 atom;
723 int err = 0;
724
725 atom = SHORT_ATOM_ID;
726 atom |= bytestring ? SHORT_ATOM_BYTESTRING : 0;
727 atom |= has_sign ? SHORT_ATOM_SIGNED : 0;
728 atom |= len & SHORT_ATOM_LEN_MASK;
729
730 add_token_u8(&err, cmd, atom);
731}
732
733static void add_medium_atom_header(struct opal_dev *cmd, bool bytestring,
734 bool has_sign, int len)
735{
736 u8 header0;
737
738 header0 = MEDIUM_ATOM_ID;
739 header0 |= bytestring ? MEDIUM_ATOM_BYTESTRING : 0;
740 header0 |= has_sign ? MEDIUM_ATOM_SIGNED : 0;
741 header0 |= (len >> 8) & MEDIUM_ATOM_LEN_MASK;
5cc23ed7 742
455a7b23
SB
743 cmd->cmd[cmd->pos++] = header0;
744 cmd->cmd[cmd->pos++] = len;
745}
746
747static void add_token_u64(int *err, struct opal_dev *cmd, u64 number)
748{
455a7b23
SB
749 size_t len;
750 int msb;
455a7b23
SB
751
752 if (!(number & ~TINY_ATOM_DATA_MASK)) {
753 add_token_u8(err, cmd, number);
754 return;
755 }
756
5f990d31
JR
757 msb = fls64(number);
758 len = DIV_ROUND_UP(msb, 8);
455a7b23 759
e2821a50 760 if (!can_add(err, cmd, len + 1)) {
591c59d1 761 pr_debug("Error adding u64: end of buffer.\n");
455a7b23
SB
762 return;
763 }
764 add_short_atom_header(cmd, false, false, len);
5f990d31
JR
765 while (len--)
766 add_token_u8(err, cmd, number >> (len * 8));
455a7b23
SB
767}
768
28559959 769static u8 *add_bytestring_header(int *err, struct opal_dev *cmd, size_t len)
455a7b23
SB
770{
771 size_t header_len = 1;
772 bool is_short_atom = true;
773
455a7b23
SB
774 if (len & ~SHORT_ATOM_LEN_MASK) {
775 header_len = 2;
776 is_short_atom = false;
777 }
778
e2821a50 779 if (!can_add(err, cmd, header_len + len)) {
591c59d1 780 pr_debug("Error adding bytestring: end of buffer.\n");
28559959 781 return NULL;
455a7b23
SB
782 }
783
784 if (is_short_atom)
785 add_short_atom_header(cmd, true, false, len);
786 else
787 add_medium_atom_header(cmd, true, false, len);
788
28559959
JR
789 return &cmd->cmd[cmd->pos];
790}
455a7b23 791
28559959
JR
792static void add_token_bytestring(int *err, struct opal_dev *cmd,
793 const u8 *bytestring, size_t len)
794{
795 u8 *start;
796
797 start = add_bytestring_header(err, cmd, len);
798 if (!start)
799 return;
800 memcpy(start, bytestring, len);
801 cmd->pos += len;
455a7b23
SB
802}
803
804static int build_locking_range(u8 *buffer, size_t length, u8 lr)
805{
806 if (length > OPAL_UID_LENGTH) {
591c59d1 807 pr_debug("Can't build locking range. Length OOB\n");
455a7b23
SB
808 return -ERANGE;
809 }
810
811 memcpy(buffer, opaluid[OPAL_LOCKINGRANGE_GLOBAL], OPAL_UID_LENGTH);
812
813 if (lr == 0)
814 return 0;
5cc23ed7 815
455a7b23
SB
816 buffer[5] = LOCKING_RANGE_NON_GLOBAL;
817 buffer[7] = lr;
818
819 return 0;
820}
821
822static int build_locking_user(u8 *buffer, size_t length, u8 lr)
823{
824 if (length > OPAL_UID_LENGTH) {
1e815b33 825 pr_debug("Can't build locking range user. Length OOB\n");
455a7b23
SB
826 return -ERANGE;
827 }
828
829 memcpy(buffer, opaluid[OPAL_USER1_UID], OPAL_UID_LENGTH);
830
831 buffer[7] = lr + 1;
832
833 return 0;
834}
835
836static void set_comid(struct opal_dev *cmd, u16 comid)
837{
838 struct opal_header *hdr = (struct opal_header *)cmd->cmd;
839
840 hdr->cp.extendedComID[0] = comid >> 8;
841 hdr->cp.extendedComID[1] = comid;
842 hdr->cp.extendedComID[2] = 0;
843 hdr->cp.extendedComID[3] = 0;
844}
845
846static int cmd_finalize(struct opal_dev *cmd, u32 hsn, u32 tsn)
847{
848 struct opal_header *hdr;
849 int err = 0;
850
a9b25b4c
JR
851 /*
852 * Close the parameter list opened from cmd_start.
853 * The number of bytes added must be equal to
854 * CMD_FINALIZE_BYTES_NEEDED.
855 */
78d584ca
DK
856 add_token_u8(&err, cmd, OPAL_ENDLIST);
857
455a7b23
SB
858 add_token_u8(&err, cmd, OPAL_ENDOFDATA);
859 add_token_u8(&err, cmd, OPAL_STARTLIST);
860 add_token_u8(&err, cmd, 0);
861 add_token_u8(&err, cmd, 0);
862 add_token_u8(&err, cmd, 0);
863 add_token_u8(&err, cmd, OPAL_ENDLIST);
864
865 if (err) {
591c59d1 866 pr_debug("Error finalizing command.\n");
455a7b23
SB
867 return -EFAULT;
868 }
869
870 hdr = (struct opal_header *) cmd->cmd;
871
872 hdr->pkt.tsn = cpu_to_be32(tsn);
873 hdr->pkt.hsn = cpu_to_be32(hsn);
874
875 hdr->subpkt.length = cpu_to_be32(cmd->pos - sizeof(*hdr));
876 while (cmd->pos % 4) {
877 if (cmd->pos >= IO_BUFFER_LENGTH) {
591c59d1 878 pr_debug("Error: Buffer overrun\n");
455a7b23
SB
879 return -ERANGE;
880 }
881 cmd->cmd[cmd->pos++] = 0;
882 }
883 hdr->pkt.length = cpu_to_be32(cmd->pos - sizeof(hdr->cp) -
884 sizeof(hdr->pkt));
885 hdr->cp.length = cpu_to_be32(cmd->pos - sizeof(hdr->cp));
886
887 return 0;
888}
889
cccb9241
JD
890static const struct opal_resp_tok *response_get_token(
891 const struct parsed_resp *resp,
892 int n)
455a7b23
SB
893{
894 const struct opal_resp_tok *tok;
895
7d9b62ae
DK
896 if (!resp) {
897 pr_debug("Response is NULL\n");
898 return ERR_PTR(-EINVAL);
899 }
900
455a7b23 901 if (n >= resp->num) {
591c59d1
SB
902 pr_debug("Token number doesn't exist: %d, resp: %d\n",
903 n, resp->num);
cccb9241 904 return ERR_PTR(-EINVAL);
455a7b23
SB
905 }
906
907 tok = &resp->toks[n];
908 if (tok->len == 0) {
591c59d1 909 pr_debug("Token length must be non-zero\n");
cccb9241 910 return ERR_PTR(-EINVAL);
455a7b23
SB
911 }
912
cccb9241 913 return tok;
455a7b23
SB
914}
915
aedb6e24
JD
916static ssize_t response_parse_tiny(struct opal_resp_tok *tok,
917 const u8 *pos)
455a7b23
SB
918{
919 tok->pos = pos;
920 tok->len = 1;
921 tok->width = OPAL_WIDTH_TINY;
922
923 if (pos[0] & TINY_ATOM_SIGNED) {
924 tok->type = OPAL_DTA_TOKENID_SINT;
925 } else {
926 tok->type = OPAL_DTA_TOKENID_UINT;
927 tok->stored.u = pos[0] & 0x3f;
928 }
929
930 return tok->len;
931}
932
aedb6e24
JD
933static ssize_t response_parse_short(struct opal_resp_tok *tok,
934 const u8 *pos)
455a7b23
SB
935{
936 tok->pos = pos;
937 tok->len = (pos[0] & SHORT_ATOM_LEN_MASK) + 1;
938 tok->width = OPAL_WIDTH_SHORT;
939
940 if (pos[0] & SHORT_ATOM_BYTESTRING) {
941 tok->type = OPAL_DTA_TOKENID_BYTESTRING;
942 } else if (pos[0] & SHORT_ATOM_SIGNED) {
943 tok->type = OPAL_DTA_TOKENID_SINT;
944 } else {
945 u64 u_integer = 0;
aedb6e24 946 ssize_t i, b = 0;
455a7b23
SB
947
948 tok->type = OPAL_DTA_TOKENID_UINT;
949 if (tok->len > 9) {
591c59d1 950 pr_debug("uint64 with more than 8 bytes\n");
455a7b23
SB
951 return -EINVAL;
952 }
953 for (i = tok->len - 1; i > 0; i--) {
954 u_integer |= ((u64)pos[i] << (8 * b));
955 b++;
956 }
957 tok->stored.u = u_integer;
958 }
959
960 return tok->len;
961}
962
aedb6e24
JD
963static ssize_t response_parse_medium(struct opal_resp_tok *tok,
964 const u8 *pos)
455a7b23
SB
965{
966 tok->pos = pos;
967 tok->len = (((pos[0] & MEDIUM_ATOM_LEN_MASK) << 8) | pos[1]) + 2;
968 tok->width = OPAL_WIDTH_MEDIUM;
969
970 if (pos[0] & MEDIUM_ATOM_BYTESTRING)
971 tok->type = OPAL_DTA_TOKENID_BYTESTRING;
972 else if (pos[0] & MEDIUM_ATOM_SIGNED)
973 tok->type = OPAL_DTA_TOKENID_SINT;
974 else
975 tok->type = OPAL_DTA_TOKENID_UINT;
976
977 return tok->len;
978}
979
aedb6e24
JD
980static ssize_t response_parse_long(struct opal_resp_tok *tok,
981 const u8 *pos)
455a7b23
SB
982{
983 tok->pos = pos;
984 tok->len = ((pos[1] << 16) | (pos[2] << 8) | pos[3]) + 4;
985 tok->width = OPAL_WIDTH_LONG;
986
987 if (pos[0] & LONG_ATOM_BYTESTRING)
988 tok->type = OPAL_DTA_TOKENID_BYTESTRING;
989 else if (pos[0] & LONG_ATOM_SIGNED)
990 tok->type = OPAL_DTA_TOKENID_SINT;
991 else
992 tok->type = OPAL_DTA_TOKENID_UINT;
993
994 return tok->len;
995}
996
aedb6e24
JD
997static ssize_t response_parse_token(struct opal_resp_tok *tok,
998 const u8 *pos)
455a7b23
SB
999{
1000 tok->pos = pos;
1001 tok->len = 1;
1002 tok->type = OPAL_DTA_TOKENID_TOKEN;
1003 tok->width = OPAL_WIDTH_TOKEN;
1004
1005 return tok->len;
1006}
1007
1008static int response_parse(const u8 *buf, size_t length,
1009 struct parsed_resp *resp)
1010{
1011 const struct opal_header *hdr;
1012 struct opal_resp_tok *iter;
1013 int num_entries = 0;
1014 int total;
aedb6e24 1015 ssize_t token_length;
455a7b23 1016 const u8 *pos;
77039b96 1017 u32 clen, plen, slen;
455a7b23
SB
1018
1019 if (!buf)
1020 return -EFAULT;
1021
1022 if (!resp)
1023 return -EFAULT;
1024
1025 hdr = (struct opal_header *)buf;
1026 pos = buf;
1027 pos += sizeof(*hdr);
1028
77039b96
JD
1029 clen = be32_to_cpu(hdr->cp.length);
1030 plen = be32_to_cpu(hdr->pkt.length);
1031 slen = be32_to_cpu(hdr->subpkt.length);
1032 pr_debug("Response size: cp: %u, pkt: %u, subpkt: %u\n",
1033 clen, plen, slen);
1034
1035 if (clen == 0 || plen == 0 || slen == 0 ||
1036 slen > IO_BUFFER_LENGTH - sizeof(*hdr)) {
591c59d1
SB
1037 pr_debug("Bad header length. cp: %u, pkt: %u, subpkt: %u\n",
1038 clen, plen, slen);
455a7b23
SB
1039 print_buffer(pos, sizeof(*hdr));
1040 return -EINVAL;
1041 }
1042
1043 if (pos > buf + length)
1044 return -EFAULT;
1045
1046 iter = resp->toks;
77039b96 1047 total = slen;
455a7b23
SB
1048 print_buffer(pos, total);
1049 while (total > 0) {
1050 if (pos[0] <= TINY_ATOM_BYTE) /* tiny atom */
1051 token_length = response_parse_tiny(iter, pos);
1052 else if (pos[0] <= SHORT_ATOM_BYTE) /* short atom */
1053 token_length = response_parse_short(iter, pos);
1054 else if (pos[0] <= MEDIUM_ATOM_BYTE) /* medium atom */
1055 token_length = response_parse_medium(iter, pos);
1056 else if (pos[0] <= LONG_ATOM_BYTE) /* long atom */
1057 token_length = response_parse_long(iter, pos);
1058 else /* TOKEN */
1059 token_length = response_parse_token(iter, pos);
1060
aedb6e24
JD
1061 if (token_length < 0)
1062 return token_length;
455a7b23
SB
1063
1064 pos += token_length;
1065 total -= token_length;
1066 iter++;
1067 num_entries++;
1068 }
1069
455a7b23
SB
1070 resp->num = num_entries;
1071
1072 return 0;
1073}
1074
1075static size_t response_get_string(const struct parsed_resp *resp, int n,
1076 const char **store)
1077{
d15e1175 1078 u8 skip;
b68f09ec 1079 const struct opal_resp_tok *tok;
d15e1175 1080
455a7b23 1081 *store = NULL;
b68f09ec
DK
1082 tok = response_get_token(resp, n);
1083 if (IS_ERR(tok))
455a7b23 1084 return 0;
455a7b23 1085
b68f09ec 1086 if (tok->type != OPAL_DTA_TOKENID_BYTESTRING) {
591c59d1 1087 pr_debug("Token is not a byte string!\n");
455a7b23
SB
1088 return 0;
1089 }
1090
b68f09ec 1091 switch (tok->width) {
d15e1175
JR
1092 case OPAL_WIDTH_TINY:
1093 case OPAL_WIDTH_SHORT:
1094 skip = 1;
1095 break;
1096 case OPAL_WIDTH_MEDIUM:
1097 skip = 2;
1098 break;
1099 case OPAL_WIDTH_LONG:
1100 skip = 4;
1101 break;
1102 default:
1103 pr_debug("Token has invalid width!\n");
1104 return 0;
1105 }
1106
b68f09ec 1107 *store = tok->pos + skip;
5cc23ed7 1108
b68f09ec 1109 return tok->len - skip;
455a7b23
SB
1110}
1111
1112static u64 response_get_u64(const struct parsed_resp *resp, int n)
1113{
b68f09ec 1114 const struct opal_resp_tok *tok;
455a7b23 1115
b68f09ec
DK
1116 tok = response_get_token(resp, n);
1117 if (IS_ERR(tok))
455a7b23 1118 return 0;
455a7b23 1119
b68f09ec
DK
1120 if (tok->type != OPAL_DTA_TOKENID_UINT) {
1121 pr_debug("Token is not unsigned int: %d\n", tok->type);
455a7b23
SB
1122 return 0;
1123 }
1124
b68f09ec
DK
1125 if (tok->width != OPAL_WIDTH_TINY && tok->width != OPAL_WIDTH_SHORT) {
1126 pr_debug("Atom is not short or tiny: %d\n", tok->width);
455a7b23
SB
1127 return 0;
1128 }
1129
b68f09ec 1130 return tok->stored.u;
455a7b23
SB
1131}
1132
cccb9241
JD
1133static bool response_token_matches(const struct opal_resp_tok *token, u8 match)
1134{
1135 if (IS_ERR(token) ||
1136 token->type != OPAL_DTA_TOKENID_TOKEN ||
1137 token->pos[0] != match)
1138 return false;
1139 return true;
1140}
1141
455a7b23
SB
1142static u8 response_status(const struct parsed_resp *resp)
1143{
cccb9241
JD
1144 const struct opal_resp_tok *tok;
1145
1146 tok = response_get_token(resp, 0);
1147 if (response_token_matches(tok, OPAL_ENDOFSESSION))
455a7b23 1148 return 0;
455a7b23
SB
1149
1150 if (resp->num < 5)
1151 return DTAERROR_NO_METHOD_STATUS;
1152
cccb9241
JD
1153 tok = response_get_token(resp, resp->num - 5);
1154 if (!response_token_matches(tok, OPAL_STARTLIST))
1155 return DTAERROR_NO_METHOD_STATUS;
1156
1157 tok = response_get_token(resp, resp->num - 1);
1158 if (!response_token_matches(tok, OPAL_ENDLIST))
455a7b23
SB
1159 return DTAERROR_NO_METHOD_STATUS;
1160
1161 return response_get_u64(resp, resp->num - 4);
1162}
1163
1164/* Parses and checks for errors */
1165static int parse_and_check_status(struct opal_dev *dev)
1166{
1167 int error;
1168
1169 print_buffer(dev->cmd, dev->pos);
1170
1171 error = response_parse(dev->resp, IO_BUFFER_LENGTH, &dev->parsed);
1172 if (error) {
591c59d1 1173 pr_debug("Couldn't parse response.\n");
455a7b23
SB
1174 return error;
1175 }
1176
1177 return response_status(&dev->parsed);
1178}
1179
1180static void clear_opal_cmd(struct opal_dev *dev)
1181{
1182 dev->pos = sizeof(struct opal_header);
1183 memset(dev->cmd, 0, IO_BUFFER_LENGTH);
1184}
1185
e8b29224
DK
1186static int cmd_start(struct opal_dev *dev, const u8 *uid, const u8 *method)
1187{
1188 int err = 0;
1189
1190 clear_opal_cmd(dev);
1191 set_comid(dev, dev->comid);
1192
1193 add_token_u8(&err, dev, OPAL_CALL);
1194 add_token_bytestring(&err, dev, uid, OPAL_UID_LENGTH);
1195 add_token_bytestring(&err, dev, method, OPAL_METHOD_LENGTH);
1196
1197 /*
1198 * Every method call is followed by its parameters enclosed within
1199 * OPAL_STARTLIST and OPAL_ENDLIST tokens. We automatically open the
1200 * parameter list here and close it later in cmd_finalize.
1201 */
1202 add_token_u8(&err, dev, OPAL_STARTLIST);
1203
1204 return err;
1205}
1206
455a7b23
SB
1207static int start_opal_session_cont(struct opal_dev *dev)
1208{
1209 u32 hsn, tsn;
1210 int error = 0;
1211
1212 error = parse_and_check_status(dev);
1213 if (error)
1214 return error;
1215
1216 hsn = response_get_u64(&dev->parsed, 4);
1217 tsn = response_get_u64(&dev->parsed, 5);
1218
88d6041d 1219 if (hsn != GENERIC_HOST_SESSION_NUM || tsn < FIRST_TPER_SESSION_NUM) {
591c59d1 1220 pr_debug("Couldn't authenticate session\n");
455a7b23
SB
1221 return -EPERM;
1222 }
1223
1224 dev->hsn = hsn;
1225 dev->tsn = tsn;
5cc23ed7 1226
455a7b23
SB
1227 return 0;
1228}
1229
1230static void add_suspend_info(struct opal_dev *dev,
1231 struct opal_suspend_data *sus)
1232{
1233 struct opal_suspend_data *iter;
1234
1235 list_for_each_entry(iter, &dev->unlk_lst, node) {
1236 if (iter->lr == sus->lr) {
1237 list_del(&iter->node);
1238 kfree(iter);
1239 break;
1240 }
1241 }
1242 list_add_tail(&sus->node, &dev->unlk_lst);
1243}
1244
1245static int end_session_cont(struct opal_dev *dev)
1246{
1247 dev->hsn = 0;
1248 dev->tsn = 0;
5cc23ed7 1249
455a7b23
SB
1250 return parse_and_check_status(dev);
1251}
1252
1253static int finalize_and_send(struct opal_dev *dev, cont_fn cont)
1254{
1255 int ret;
1256
1257 ret = cmd_finalize(dev, dev->hsn, dev->tsn);
1258 if (ret) {
591c59d1 1259 pr_debug("Error finalizing command buffer: %d\n", ret);
455a7b23
SB
1260 return ret;
1261 }
1262
1263 print_buffer(dev->cmd, dev->pos);
1264
1265 return opal_send_recv(dev, cont);
1266}
1267
baf82b67
OK
1268static int generic_get_columns(struct opal_dev *dev, const u8 *table,
1269 u64 start_column, u64 end_column)
3fff234b
DK
1270{
1271 int err;
1272
1273 err = cmd_start(dev, table, opalmethod[OPAL_GET]);
1274
1275 add_token_u8(&err, dev, OPAL_STARTLIST);
1276
1277 add_token_u8(&err, dev, OPAL_STARTNAME);
1278 add_token_u8(&err, dev, OPAL_STARTCOLUMN);
baf82b67 1279 add_token_u64(&err, dev, start_column);
3fff234b
DK
1280 add_token_u8(&err, dev, OPAL_ENDNAME);
1281
1282 add_token_u8(&err, dev, OPAL_STARTNAME);
1283 add_token_u8(&err, dev, OPAL_ENDCOLUMN);
baf82b67 1284 add_token_u64(&err, dev, end_column);
3fff234b
DK
1285 add_token_u8(&err, dev, OPAL_ENDNAME);
1286
1287 add_token_u8(&err, dev, OPAL_ENDLIST);
1288
1289 if (err)
1290 return err;
1291
1292 return finalize_and_send(dev, parse_and_check_status);
1293}
1294
baf82b67
OK
1295/*
1296 * request @column from table @table on device @dev. On success, the column
1297 * data will be available in dev->resp->tok[4]
1298 */
1299static int generic_get_column(struct opal_dev *dev, const u8 *table,
1300 u64 column)
1301{
1302 return generic_get_columns(dev, table, column, column);
1303}
1304
ff91064e
JR
1305/*
1306 * see TCG SAS 5.3.2.3 for a description of the available columns
1307 *
1308 * the result is provided in dev->resp->tok[4]
1309 */
3495ea1b 1310static int generic_get_table_info(struct opal_dev *dev, const u8 *table_uid,
ff91064e
JR
1311 u64 column)
1312{
1313 u8 uid[OPAL_UID_LENGTH];
3495ea1b 1314 const unsigned int half = OPAL_UID_LENGTH_HALF;
ff91064e
JR
1315
1316 /* sed-opal UIDs can be split in two halves:
1317 * first: actual table index
1318 * second: relative index in the table
1319 * so we have to get the first half of the OPAL_TABLE_TABLE and use the
1320 * first part of the target table as relative index into that table
1321 */
1322 memcpy(uid, opaluid[OPAL_TABLE_TABLE], half);
3495ea1b 1323 memcpy(uid + half, table_uid, half);
ff91064e
JR
1324
1325 return generic_get_column(dev, uid, column);
1326}
1327
eed64951 1328static int gen_key(struct opal_dev *dev, void *data)
455a7b23 1329{
455a7b23 1330 u8 uid[OPAL_UID_LENGTH];
e8b29224 1331 int err;
455a7b23
SB
1332
1333 memcpy(uid, dev->prev_data, min(sizeof(uid), dev->prev_d_len));
455a7b23
SB
1334 kfree(dev->prev_data);
1335 dev->prev_data = NULL;
1336
e8b29224 1337 err = cmd_start(dev, uid, opalmethod[OPAL_GENKEY]);
455a7b23
SB
1338
1339 if (err) {
591c59d1 1340 pr_debug("Error building gen key command\n");
455a7b23
SB
1341 return err;
1342
1343 }
5cc23ed7 1344
455a7b23
SB
1345 return finalize_and_send(dev, parse_and_check_status);
1346}
1347
1348static int get_active_key_cont(struct opal_dev *dev)
1349{
1350 const char *activekey;
1351 size_t keylen;
1352 int error = 0;
1353
1354 error = parse_and_check_status(dev);
1355 if (error)
1356 return error;
5cc23ed7 1357
455a7b23
SB
1358 keylen = response_get_string(&dev->parsed, 4, &activekey);
1359 if (!activekey) {
591c59d1
SB
1360 pr_debug("%s: Couldn't extract the Activekey from the response\n",
1361 __func__);
455a7b23
SB
1362 return OPAL_INVAL_PARAM;
1363 }
5cc23ed7 1364
455a7b23
SB
1365 dev->prev_data = kmemdup(activekey, keylen, GFP_KERNEL);
1366
1367 if (!dev->prev_data)
1368 return -ENOMEM;
1369
1370 dev->prev_d_len = keylen;
1371
1372 return 0;
1373}
1374
eed64951 1375static int get_active_key(struct opal_dev *dev, void *data)
455a7b23
SB
1376{
1377 u8 uid[OPAL_UID_LENGTH];
e8b29224 1378 int err;
eed64951 1379 u8 *lr = data;
455a7b23 1380
455a7b23
SB
1381 err = build_locking_range(uid, sizeof(uid), *lr);
1382 if (err)
1383 return err;
1384
3fff234b
DK
1385 err = generic_get_column(dev, uid, OPAL_ACTIVEKEY);
1386 if (err)
455a7b23 1387 return err;
455a7b23 1388
3fff234b 1389 return get_active_key_cont(dev);
455a7b23
SB
1390}
1391
3495ea1b
RR
1392static int generic_table_write_data(struct opal_dev *dev, const u64 data,
1393 u64 offset, u64 size, const u8 *uid)
1394{
1395 const u8 __user *src = (u8 __user *)(uintptr_t)data;
1396 u8 *dst;
1397 u64 len;
1398 size_t off = 0;
1399 int err;
1400
1401 /* do we fit in the available space? */
1402 err = generic_get_table_info(dev, uid, OPAL_TABLE_ROWS);
1403 if (err) {
1404 pr_debug("Couldn't get the table size\n");
1405 return err;
1406 }
1407
1408 len = response_get_u64(&dev->parsed, 4);
1409 if (size > len || offset > len - size) {
1410 pr_debug("Does not fit in the table (%llu vs. %llu)\n",
1411 offset + size, len);
1412 return -ENOSPC;
1413 }
1414
1415 /* do the actual transmission(s) */
1416 while (off < size) {
1417 err = cmd_start(dev, uid, opalmethod[OPAL_SET]);
1418 add_token_u8(&err, dev, OPAL_STARTNAME);
1419 add_token_u8(&err, dev, OPAL_WHERE);
1420 add_token_u64(&err, dev, offset + off);
1421 add_token_u8(&err, dev, OPAL_ENDNAME);
1422
1423 add_token_u8(&err, dev, OPAL_STARTNAME);
1424 add_token_u8(&err, dev, OPAL_VALUES);
1425
1426 /*
1427 * The bytestring header is either 1 or 2 bytes, so assume 2.
1428 * There also needs to be enough space to accommodate the
1429 * trailing OPAL_ENDNAME (1 byte) and tokens added by
1430 * cmd_finalize.
1431 */
1432 len = min(remaining_size(dev) - (2+1+CMD_FINALIZE_BYTES_NEEDED),
1433 (size_t)(size - off));
1434 pr_debug("Write bytes %zu+%llu/%llu\n", off, len, size);
1435
1436 dst = add_bytestring_header(&err, dev, len);
1437 if (!dst)
1438 break;
1439
1440 if (copy_from_user(dst, src + off, len)) {
1441 err = -EFAULT;
1442 break;
1443 }
1444
1445 dev->pos += len;
1446
1447 add_token_u8(&err, dev, OPAL_ENDNAME);
1448 if (err)
1449 break;
1450
1451 err = finalize_and_send(dev, parse_and_check_status);
1452 if (err)
1453 break;
1454
1455 off += len;
1456 }
1457
1458 return err;
1459}
1460
455a7b23
SB
1461static int generic_lr_enable_disable(struct opal_dev *dev,
1462 u8 *uid, bool rle, bool wle,
1463 bool rl, bool wl)
1464{
e8b29224 1465 int err;
455a7b23 1466
e8b29224 1467 err = cmd_start(dev, uid, opalmethod[OPAL_SET]);
455a7b23 1468
455a7b23
SB
1469 add_token_u8(&err, dev, OPAL_STARTNAME);
1470 add_token_u8(&err, dev, OPAL_VALUES);
1471 add_token_u8(&err, dev, OPAL_STARTLIST);
1472
1473 add_token_u8(&err, dev, OPAL_STARTNAME);
372be408 1474 add_token_u8(&err, dev, OPAL_READLOCKENABLED);
455a7b23
SB
1475 add_token_u8(&err, dev, rle);
1476 add_token_u8(&err, dev, OPAL_ENDNAME);
1477
1478 add_token_u8(&err, dev, OPAL_STARTNAME);
372be408 1479 add_token_u8(&err, dev, OPAL_WRITELOCKENABLED);
455a7b23
SB
1480 add_token_u8(&err, dev, wle);
1481 add_token_u8(&err, dev, OPAL_ENDNAME);
1482
1483 add_token_u8(&err, dev, OPAL_STARTNAME);
1484 add_token_u8(&err, dev, OPAL_READLOCKED);
1485 add_token_u8(&err, dev, rl);
1486 add_token_u8(&err, dev, OPAL_ENDNAME);
1487
1488 add_token_u8(&err, dev, OPAL_STARTNAME);
1489 add_token_u8(&err, dev, OPAL_WRITELOCKED);
1490 add_token_u8(&err, dev, wl);
1491 add_token_u8(&err, dev, OPAL_ENDNAME);
1492
1493 add_token_u8(&err, dev, OPAL_ENDLIST);
1494 add_token_u8(&err, dev, OPAL_ENDNAME);
5cc23ed7 1495
455a7b23
SB
1496 return err;
1497}
1498
1499static inline int enable_global_lr(struct opal_dev *dev, u8 *uid,
1500 struct opal_user_lr_setup *setup)
1501{
1502 int err;
1503
1504 err = generic_lr_enable_disable(dev, uid, !!setup->RLE, !!setup->WLE,
1505 0, 0);
1506 if (err)
591c59d1 1507 pr_debug("Failed to create enable global lr command\n");
5cc23ed7 1508
455a7b23
SB
1509 return err;
1510}
1511
eed64951 1512static int setup_locking_range(struct opal_dev *dev, void *data)
455a7b23
SB
1513{
1514 u8 uid[OPAL_UID_LENGTH];
eed64951 1515 struct opal_user_lr_setup *setup = data;
455a7b23 1516 u8 lr;
e8b29224 1517 int err;
455a7b23 1518
455a7b23
SB
1519 lr = setup->session.opal_key.lr;
1520 err = build_locking_range(uid, sizeof(uid), lr);
1521 if (err)
1522 return err;
1523
1524 if (lr == 0)
1525 err = enable_global_lr(dev, uid, setup);
1526 else {
e8b29224 1527 err = cmd_start(dev, uid, opalmethod[OPAL_SET]);
455a7b23 1528
455a7b23
SB
1529 add_token_u8(&err, dev, OPAL_STARTNAME);
1530 add_token_u8(&err, dev, OPAL_VALUES);
1531 add_token_u8(&err, dev, OPAL_STARTLIST);
1532
1533 add_token_u8(&err, dev, OPAL_STARTNAME);
372be408 1534 add_token_u8(&err, dev, OPAL_RANGESTART);
455a7b23
SB
1535 add_token_u64(&err, dev, setup->range_start);
1536 add_token_u8(&err, dev, OPAL_ENDNAME);
1537
1538 add_token_u8(&err, dev, OPAL_STARTNAME);
372be408 1539 add_token_u8(&err, dev, OPAL_RANGELENGTH);
455a7b23
SB
1540 add_token_u64(&err, dev, setup->range_length);
1541 add_token_u8(&err, dev, OPAL_ENDNAME);
1542
1543 add_token_u8(&err, dev, OPAL_STARTNAME);
372be408 1544 add_token_u8(&err, dev, OPAL_READLOCKENABLED);
455a7b23
SB
1545 add_token_u64(&err, dev, !!setup->RLE);
1546 add_token_u8(&err, dev, OPAL_ENDNAME);
1547
1548 add_token_u8(&err, dev, OPAL_STARTNAME);
372be408 1549 add_token_u8(&err, dev, OPAL_WRITELOCKENABLED);
455a7b23
SB
1550 add_token_u64(&err, dev, !!setup->WLE);
1551 add_token_u8(&err, dev, OPAL_ENDNAME);
1552
1553 add_token_u8(&err, dev, OPAL_ENDLIST);
1554 add_token_u8(&err, dev, OPAL_ENDNAME);
455a7b23
SB
1555 }
1556 if (err) {
591c59d1 1557 pr_debug("Error building Setup Locking range command.\n");
455a7b23 1558 return err;
455a7b23
SB
1559 }
1560
1561 return finalize_and_send(dev, parse_and_check_status);
1562}
1563
4c4dd04e
OK
1564static int response_get_column(const struct parsed_resp *resp,
1565 int *iter,
1566 u8 column,
1567 u64 *value)
1568{
1569 const struct opal_resp_tok *tok;
1570 int n = *iter;
1571 u64 val;
1572
1573 tok = response_get_token(resp, n);
1574 if (IS_ERR(tok))
1575 return PTR_ERR(tok);
1576
1577 if (!response_token_matches(tok, OPAL_STARTNAME)) {
1578 pr_debug("Unexpected response token type %d.\n", n);
1579 return OPAL_INVAL_PARAM;
1580 }
1581 n++;
1582
1583 if (response_get_u64(resp, n) != column) {
1584 pr_debug("Token %d does not match expected column %u.\n",
1585 n, column);
1586 return OPAL_INVAL_PARAM;
1587 }
1588 n++;
1589
1590 val = response_get_u64(resp, n);
1591 n++;
1592
1593 tok = response_get_token(resp, n);
1594 if (IS_ERR(tok))
1595 return PTR_ERR(tok);
1596
1597 if (!response_token_matches(tok, OPAL_ENDNAME)) {
1598 pr_debug("Unexpected response token type %d.\n", n);
1599 return OPAL_INVAL_PARAM;
1600 }
1601 n++;
1602
1603 *value = val;
1604 *iter = n;
1605
1606 return 0;
1607}
1608
1609static int locking_range_status(struct opal_dev *dev, void *data)
1610{
1611 u8 lr_buffer[OPAL_UID_LENGTH];
1612 u64 resp;
1613 bool rlocked, wlocked;
1614 int err, tok_n = 2;
1615 struct opal_lr_status *lrst = data;
1616
1617 err = build_locking_range(lr_buffer, sizeof(lr_buffer),
1618 lrst->session.opal_key.lr);
1619 if (err)
1620 return err;
1621
1622 err = generic_get_columns(dev, lr_buffer, OPAL_RANGESTART,
1623 OPAL_WRITELOCKED);
1624 if (err) {
1625 pr_debug("Couldn't get lr %u table columns %d to %d.\n",
1626 lrst->session.opal_key.lr, OPAL_RANGESTART,
1627 OPAL_WRITELOCKED);
1628 return err;
1629 }
1630
1631 /* range start */
1632 err = response_get_column(&dev->parsed, &tok_n, OPAL_RANGESTART,
1633 &lrst->range_start);
1634 if (err)
1635 return err;
1636
1637 /* range length */
1638 err = response_get_column(&dev->parsed, &tok_n, OPAL_RANGELENGTH,
1639 &lrst->range_length);
1640 if (err)
1641 return err;
1642
1643 /* RLE */
1644 err = response_get_column(&dev->parsed, &tok_n, OPAL_READLOCKENABLED,
1645 &resp);
1646 if (err)
1647 return err;
1648
1649 lrst->RLE = !!resp;
1650
1651 /* WLE */
1652 err = response_get_column(&dev->parsed, &tok_n, OPAL_WRITELOCKENABLED,
1653 &resp);
1654 if (err)
1655 return err;
1656
1657 lrst->WLE = !!resp;
1658
1659 /* read locked */
1660 err = response_get_column(&dev->parsed, &tok_n, OPAL_READLOCKED, &resp);
1661 if (err)
1662 return err;
1663
1664 rlocked = !!resp;
1665
1666 /* write locked */
1667 err = response_get_column(&dev->parsed, &tok_n, OPAL_WRITELOCKED, &resp);
1668 if (err)
1669 return err;
1670
1671 wlocked = !!resp;
1672
1673 /* opal_lock_state can not map 'read locked' only state. */
1674 lrst->l_state = OPAL_RW;
1675 if (rlocked && wlocked)
1676 lrst->l_state = OPAL_LK;
1677 else if (wlocked)
1678 lrst->l_state = OPAL_RO;
1679 else if (rlocked) {
1680 pr_debug("Can not report read locked only state.\n");
1681 return -EINVAL;
1682 }
1683
1684 return 0;
1685}
1686
455a7b23
SB
1687static int start_generic_opal_session(struct opal_dev *dev,
1688 enum opal_uid auth,
1689 enum opal_uid sp_type,
1690 const char *key,
1691 u8 key_len)
1692{
1693 u32 hsn;
e8b29224 1694 int err;
455a7b23 1695
591c59d1 1696 if (key == NULL && auth != OPAL_ANYBODY_UID)
455a7b23 1697 return OPAL_INVAL_PARAM;
455a7b23 1698
455a7b23 1699 hsn = GENERIC_HOST_SESSION_NUM;
e8b29224
DK
1700 err = cmd_start(dev, opaluid[OPAL_SMUID_UID],
1701 opalmethod[OPAL_STARTSESSION]);
455a7b23 1702
455a7b23
SB
1703 add_token_u64(&err, dev, hsn);
1704 add_token_bytestring(&err, dev, opaluid[sp_type], OPAL_UID_LENGTH);
1705 add_token_u8(&err, dev, 1);
1706
1707 switch (auth) {
1708 case OPAL_ANYBODY_UID:
455a7b23
SB
1709 break;
1710 case OPAL_ADMIN1_UID:
1711 case OPAL_SID_UID:
5e4c7cf6 1712 case OPAL_PSID_UID:
455a7b23
SB
1713 add_token_u8(&err, dev, OPAL_STARTNAME);
1714 add_token_u8(&err, dev, 0); /* HostChallenge */
1715 add_token_bytestring(&err, dev, key, key_len);
1716 add_token_u8(&err, dev, OPAL_ENDNAME);
1717 add_token_u8(&err, dev, OPAL_STARTNAME);
1718 add_token_u8(&err, dev, 3); /* HostSignAuth */
1719 add_token_bytestring(&err, dev, opaluid[auth],
1720 OPAL_UID_LENGTH);
1721 add_token_u8(&err, dev, OPAL_ENDNAME);
455a7b23
SB
1722 break;
1723 default:
591c59d1 1724 pr_debug("Cannot start Admin SP session with auth %d\n", auth);
455a7b23
SB
1725 return OPAL_INVAL_PARAM;
1726 }
1727
1728 if (err) {
591c59d1 1729 pr_debug("Error building start adminsp session command.\n");
455a7b23
SB
1730 return err;
1731 }
1732
1733 return finalize_and_send(dev, start_opal_session_cont);
1734}
1735
eed64951 1736static int start_anybodyASP_opal_session(struct opal_dev *dev, void *data)
455a7b23
SB
1737{
1738 return start_generic_opal_session(dev, OPAL_ANYBODY_UID,
1739 OPAL_ADMINSP_UID, NULL, 0);
1740}
1741
eed64951 1742static int start_SIDASP_opal_session(struct opal_dev *dev, void *data)
455a7b23
SB
1743{
1744 int ret;
1745 const u8 *key = dev->prev_data;
455a7b23
SB
1746
1747 if (!key) {
eed64951 1748 const struct opal_key *okey = data;
1e815b33 1749
455a7b23
SB
1750 ret = start_generic_opal_session(dev, OPAL_SID_UID,
1751 OPAL_ADMINSP_UID,
1752 okey->key,
1753 okey->key_len);
1754 } else {
1755 ret = start_generic_opal_session(dev, OPAL_SID_UID,
1756 OPAL_ADMINSP_UID,
1757 key, dev->prev_d_len);
1758 kfree(key);
1759 dev->prev_data = NULL;
1760 }
5cc23ed7 1761
455a7b23
SB
1762 return ret;
1763}
1764
eed64951 1765static int start_admin1LSP_opal_session(struct opal_dev *dev, void *data)
455a7b23 1766{
eed64951 1767 struct opal_key *key = data;
1e815b33 1768
455a7b23
SB
1769 return start_generic_opal_session(dev, OPAL_ADMIN1_UID,
1770 OPAL_LOCKINGSP_UID,
1771 key->key, key->key_len);
1772}
1773
5e4c7cf6
RR
1774static int start_PSID_opal_session(struct opal_dev *dev, void *data)
1775{
1776 const struct opal_key *okey = data;
1777
1778 return start_generic_opal_session(dev, OPAL_PSID_UID,
1779 OPAL_ADMINSP_UID,
1780 okey->key,
1781 okey->key_len);
1782}
1783
eed64951 1784static int start_auth_opal_session(struct opal_dev *dev, void *data)
455a7b23 1785{
eed64951 1786 struct opal_session_info *session = data;
455a7b23 1787 u8 lk_ul_user[OPAL_UID_LENGTH];
eed64951 1788 size_t keylen = session->opal_key.key_len;
455a7b23
SB
1789 int err = 0;
1790
455a7b23
SB
1791 u8 *key = session->opal_key.key;
1792 u32 hsn = GENERIC_HOST_SESSION_NUM;
1793
e8b29224 1794 if (session->sum)
455a7b23
SB
1795 err = build_locking_user(lk_ul_user, sizeof(lk_ul_user),
1796 session->opal_key.lr);
e8b29224 1797 else if (session->who != OPAL_ADMIN1 && !session->sum)
455a7b23
SB
1798 err = build_locking_user(lk_ul_user, sizeof(lk_ul_user),
1799 session->who - 1);
e8b29224 1800 else
455a7b23
SB
1801 memcpy(lk_ul_user, opaluid[OPAL_ADMIN1_UID], OPAL_UID_LENGTH);
1802
e8b29224
DK
1803 if (err)
1804 return err;
1805
1806 err = cmd_start(dev, opaluid[OPAL_SMUID_UID],
1807 opalmethod[OPAL_STARTSESSION]);
455a7b23 1808
455a7b23
SB
1809 add_token_u64(&err, dev, hsn);
1810 add_token_bytestring(&err, dev, opaluid[OPAL_LOCKINGSP_UID],
1811 OPAL_UID_LENGTH);
1812 add_token_u8(&err, dev, 1);
1813 add_token_u8(&err, dev, OPAL_STARTNAME);
1814 add_token_u8(&err, dev, 0);
1815 add_token_bytestring(&err, dev, key, keylen);
1816 add_token_u8(&err, dev, OPAL_ENDNAME);
1817 add_token_u8(&err, dev, OPAL_STARTNAME);
1818 add_token_u8(&err, dev, 3);
1819 add_token_bytestring(&err, dev, lk_ul_user, OPAL_UID_LENGTH);
1820 add_token_u8(&err, dev, OPAL_ENDNAME);
455a7b23
SB
1821
1822 if (err) {
591c59d1 1823 pr_debug("Error building STARTSESSION command.\n");
455a7b23
SB
1824 return err;
1825 }
1826
1827 return finalize_and_send(dev, start_opal_session_cont);
1828}
1829
eed64951 1830static int revert_tper(struct opal_dev *dev, void *data)
455a7b23 1831{
e8b29224 1832 int err;
455a7b23 1833
e8b29224
DK
1834 err = cmd_start(dev, opaluid[OPAL_ADMINSP_UID],
1835 opalmethod[OPAL_REVERT]);
455a7b23 1836 if (err) {
591c59d1 1837 pr_debug("Error building REVERT TPER command.\n");
455a7b23
SB
1838 return err;
1839 }
1840
1841 return finalize_and_send(dev, parse_and_check_status);
1842}
1843
eed64951 1844static int internal_activate_user(struct opal_dev *dev, void *data)
455a7b23 1845{
eed64951 1846 struct opal_session_info *session = data;
455a7b23 1847 u8 uid[OPAL_UID_LENGTH];
e8b29224 1848 int err;
455a7b23
SB
1849
1850 memcpy(uid, opaluid[OPAL_USER1_UID], OPAL_UID_LENGTH);
1851 uid[7] = session->who;
1852
e8b29224 1853 err = cmd_start(dev, uid, opalmethod[OPAL_SET]);
455a7b23
SB
1854 add_token_u8(&err, dev, OPAL_STARTNAME);
1855 add_token_u8(&err, dev, OPAL_VALUES);
1856 add_token_u8(&err, dev, OPAL_STARTLIST);
1857 add_token_u8(&err, dev, OPAL_STARTNAME);
1858 add_token_u8(&err, dev, 5); /* Enabled */
1859 add_token_u8(&err, dev, OPAL_TRUE);
1860 add_token_u8(&err, dev, OPAL_ENDNAME);
1861 add_token_u8(&err, dev, OPAL_ENDLIST);
1862 add_token_u8(&err, dev, OPAL_ENDNAME);
455a7b23
SB
1863
1864 if (err) {
591c59d1 1865 pr_debug("Error building Activate UserN command.\n");
455a7b23
SB
1866 return err;
1867 }
1868
1869 return finalize_and_send(dev, parse_and_check_status);
1870}
1871
5c82efc1
GJ
1872static int revert_lsp(struct opal_dev *dev, void *data)
1873{
1874 struct opal_revert_lsp *rev = data;
1875 int err;
1876
1877 err = cmd_start(dev, opaluid[OPAL_THISSP_UID],
1878 opalmethod[OPAL_REVERTSP]);
1879 add_token_u8(&err, dev, OPAL_STARTNAME);
1880 add_token_u64(&err, dev, OPAL_KEEP_GLOBAL_RANGE_KEY);
1881 add_token_u8(&err, dev, (rev->options & OPAL_PRESERVE) ?
1882 OPAL_TRUE : OPAL_FALSE);
1883 add_token_u8(&err, dev, OPAL_ENDNAME);
1884 if (err) {
1885 pr_debug("Error building REVERT SP command.\n");
1886 return err;
1887 }
1888
1889 return finalize_and_send(dev, parse_and_check_status);
1890}
1891
eed64951 1892static int erase_locking_range(struct opal_dev *dev, void *data)
455a7b23 1893{
eed64951 1894 struct opal_session_info *session = data;
455a7b23 1895 u8 uid[OPAL_UID_LENGTH];
e8b29224 1896 int err;
455a7b23
SB
1897
1898 if (build_locking_range(uid, sizeof(uid), session->opal_key.lr) < 0)
1899 return -ERANGE;
1900
e8b29224 1901 err = cmd_start(dev, uid, opalmethod[OPAL_ERASE]);
455a7b23
SB
1902
1903 if (err) {
591c59d1 1904 pr_debug("Error building Erase Locking Range Command.\n");
455a7b23
SB
1905 return err;
1906 }
5cc23ed7 1907
455a7b23
SB
1908 return finalize_and_send(dev, parse_and_check_status);
1909}
1910
eed64951 1911static int set_mbr_done(struct opal_dev *dev, void *data)
455a7b23 1912{
eed64951 1913 u8 *mbr_done_tf = data;
e8b29224 1914 int err;
455a7b23 1915
e8b29224
DK
1916 err = cmd_start(dev, opaluid[OPAL_MBRCONTROL],
1917 opalmethod[OPAL_SET]);
455a7b23 1918
455a7b23
SB
1919 add_token_u8(&err, dev, OPAL_STARTNAME);
1920 add_token_u8(&err, dev, OPAL_VALUES);
1921 add_token_u8(&err, dev, OPAL_STARTLIST);
1922 add_token_u8(&err, dev, OPAL_STARTNAME);
372be408 1923 add_token_u8(&err, dev, OPAL_MBRDONE);
eed64951 1924 add_token_u8(&err, dev, *mbr_done_tf); /* Done T or F */
455a7b23
SB
1925 add_token_u8(&err, dev, OPAL_ENDNAME);
1926 add_token_u8(&err, dev, OPAL_ENDLIST);
1927 add_token_u8(&err, dev, OPAL_ENDNAME);
455a7b23
SB
1928
1929 if (err) {
591c59d1 1930 pr_debug("Error Building set MBR Done command\n");
455a7b23
SB
1931 return err;
1932 }
1933
1934 return finalize_and_send(dev, parse_and_check_status);
1935}
1936
eed64951 1937static int set_mbr_enable_disable(struct opal_dev *dev, void *data)
455a7b23 1938{
eed64951 1939 u8 *mbr_en_dis = data;
e8b29224 1940 int err;
455a7b23 1941
e8b29224
DK
1942 err = cmd_start(dev, opaluid[OPAL_MBRCONTROL],
1943 opalmethod[OPAL_SET]);
455a7b23 1944
455a7b23
SB
1945 add_token_u8(&err, dev, OPAL_STARTNAME);
1946 add_token_u8(&err, dev, OPAL_VALUES);
1947 add_token_u8(&err, dev, OPAL_STARTLIST);
1948 add_token_u8(&err, dev, OPAL_STARTNAME);
372be408 1949 add_token_u8(&err, dev, OPAL_MBRENABLE);
eed64951 1950 add_token_u8(&err, dev, *mbr_en_dis);
455a7b23
SB
1951 add_token_u8(&err, dev, OPAL_ENDNAME);
1952 add_token_u8(&err, dev, OPAL_ENDLIST);
1953 add_token_u8(&err, dev, OPAL_ENDNAME);
455a7b23
SB
1954
1955 if (err) {
591c59d1 1956 pr_debug("Error Building set MBR done command\n");
455a7b23
SB
1957 return err;
1958 }
1959
1960 return finalize_and_send(dev, parse_and_check_status);
1961}
1962
a9b25b4c
JR
1963static int write_shadow_mbr(struct opal_dev *dev, void *data)
1964{
1965 struct opal_shadow_mbr *shadow = data;
a9b25b4c 1966
3495ea1b
RR
1967 return generic_table_write_data(dev, shadow->data, shadow->offset,
1968 shadow->size, opaluid[OPAL_MBR]);
a9b25b4c
JR
1969}
1970
455a7b23
SB
1971static int generic_pw_cmd(u8 *key, size_t key_len, u8 *cpin_uid,
1972 struct opal_dev *dev)
1973{
e8b29224 1974 int err;
455a7b23 1975
e8b29224 1976 err = cmd_start(dev, cpin_uid, opalmethod[OPAL_SET]);
455a7b23 1977
455a7b23
SB
1978 add_token_u8(&err, dev, OPAL_STARTNAME);
1979 add_token_u8(&err, dev, OPAL_VALUES);
1980 add_token_u8(&err, dev, OPAL_STARTLIST);
1981 add_token_u8(&err, dev, OPAL_STARTNAME);
372be408 1982 add_token_u8(&err, dev, OPAL_PIN);
455a7b23
SB
1983 add_token_bytestring(&err, dev, key, key_len);
1984 add_token_u8(&err, dev, OPAL_ENDNAME);
1985 add_token_u8(&err, dev, OPAL_ENDLIST);
1986 add_token_u8(&err, dev, OPAL_ENDNAME);
455a7b23
SB
1987
1988 return err;
1989}
1990
eed64951 1991static int set_new_pw(struct opal_dev *dev, void *data)
455a7b23
SB
1992{
1993 u8 cpin_uid[OPAL_UID_LENGTH];
eed64951 1994 struct opal_session_info *usr = data;
455a7b23
SB
1995
1996 memcpy(cpin_uid, opaluid[OPAL_C_PIN_ADMIN1], OPAL_UID_LENGTH);
1997
1998 if (usr->who != OPAL_ADMIN1) {
1999 cpin_uid[5] = 0x03;
2000 if (usr->sum)
2001 cpin_uid[7] = usr->opal_key.lr + 1;
2002 else
2003 cpin_uid[7] = usr->who;
2004 }
2005
2006 if (generic_pw_cmd(usr->opal_key.key, usr->opal_key.key_len,
2007 cpin_uid, dev)) {
591c59d1 2008 pr_debug("Error building set password command.\n");
455a7b23
SB
2009 return -ERANGE;
2010 }
2011
2012 return finalize_and_send(dev, parse_and_check_status);
2013}
2014
eed64951 2015static int set_sid_cpin_pin(struct opal_dev *dev, void *data)
455a7b23
SB
2016{
2017 u8 cpin_uid[OPAL_UID_LENGTH];
eed64951 2018 struct opal_key *key = data;
455a7b23
SB
2019
2020 memcpy(cpin_uid, opaluid[OPAL_C_PIN_SID], OPAL_UID_LENGTH);
2021
2022 if (generic_pw_cmd(key->key, key->key_len, cpin_uid, dev)) {
591c59d1 2023 pr_debug("Error building Set SID cpin\n");
455a7b23
SB
2024 return -ERANGE;
2025 }
2026 return finalize_and_send(dev, parse_and_check_status);
2027}
2028
175b6544
OK
2029static void add_authority_object_ref(int *err,
2030 struct opal_dev *dev,
2031 const u8 *uid,
2032 size_t uid_len)
2033{
2034 add_token_u8(err, dev, OPAL_STARTNAME);
2035 add_token_bytestring(err, dev,
2036 opaluid[OPAL_HALF_UID_AUTHORITY_OBJ_REF],
2037 OPAL_UID_LENGTH/2);
2038 add_token_bytestring(err, dev, uid, uid_len);
2039 add_token_u8(err, dev, OPAL_ENDNAME);
2040}
2041
2042static void add_boolean_object_ref(int *err,
2043 struct opal_dev *dev,
2044 u8 boolean_op)
2045{
2046 add_token_u8(err, dev, OPAL_STARTNAME);
2047 add_token_bytestring(err, dev, opaluid[OPAL_HALF_UID_BOOLEAN_ACE],
2048 OPAL_UID_LENGTH/2);
2049 add_token_u8(err, dev, boolean_op);
2050 add_token_u8(err, dev, OPAL_ENDNAME);
2051}
2052
2053static int set_lr_boolean_ace(struct opal_dev *dev,
2054 unsigned int opal_uid,
2055 u8 lr,
2056 const u8 *users,
2057 size_t users_len)
455a7b23
SB
2058{
2059 u8 lr_buffer[OPAL_UID_LENGTH];
2060 u8 user_uid[OPAL_UID_LENGTH];
175b6544 2061 u8 u;
e8b29224 2062 int err;
455a7b23 2063
175b6544
OK
2064 memcpy(lr_buffer, opaluid[opal_uid], OPAL_UID_LENGTH);
2065 lr_buffer[7] = lr;
455a7b23 2066
e8b29224 2067 err = cmd_start(dev, lr_buffer, opalmethod[OPAL_SET]);
455a7b23 2068
455a7b23
SB
2069 add_token_u8(&err, dev, OPAL_STARTNAME);
2070 add_token_u8(&err, dev, OPAL_VALUES);
2071
2072 add_token_u8(&err, dev, OPAL_STARTLIST);
2073 add_token_u8(&err, dev, OPAL_STARTNAME);
2074 add_token_u8(&err, dev, 3);
2075
2076 add_token_u8(&err, dev, OPAL_STARTLIST);
2077
175b6544
OK
2078 for (u = 0; u < users_len; u++) {
2079 if (users[u] == OPAL_ADMIN1)
2080 memcpy(user_uid, opaluid[OPAL_ADMIN1_UID],
2081 OPAL_UID_LENGTH);
2082 else {
2083 memcpy(user_uid, opaluid[OPAL_USER1_UID],
2084 OPAL_UID_LENGTH);
2085 user_uid[7] = users[u];
2086 }
2087
2088 add_authority_object_ref(&err, dev, user_uid, sizeof(user_uid));
455a7b23 2089
175b6544
OK
2090 /*
2091 * Add boolean operator in postfix only with
2092 * two or more authorities being added in ACE
2093 * expresion.
2094 * */
2095 if (u > 0)
2096 add_boolean_object_ref(&err, dev, OPAL_BOOLEAN_OR);
2097 }
455a7b23 2098
455a7b23
SB
2099 add_token_u8(&err, dev, OPAL_ENDLIST);
2100 add_token_u8(&err, dev, OPAL_ENDNAME);
2101 add_token_u8(&err, dev, OPAL_ENDLIST);
2102 add_token_u8(&err, dev, OPAL_ENDNAME);
455a7b23 2103
175b6544
OK
2104 return err;
2105}
2106
2107static int add_user_to_lr(struct opal_dev *dev, void *data)
2108{
2109 int err;
2110 struct opal_lock_unlock *lkul = data;
2111 const u8 users[] = {
2112 lkul->session.who
2113 };
2114
2115 err = set_lr_boolean_ace(dev,
2116 lkul->l_state == OPAL_RW ?
2117 OPAL_LOCKINGRANGE_ACE_WRLOCKED :
2118 OPAL_LOCKINGRANGE_ACE_RDLOCKED,
2119 lkul->session.opal_key.lr, users,
2120 ARRAY_SIZE(users));
455a7b23 2121 if (err) {
591c59d1 2122 pr_debug("Error building add user to locking range command.\n");
455a7b23
SB
2123 return err;
2124 }
2125
2126 return finalize_and_send(dev, parse_and_check_status);
2127}
2128
8be19a02
OK
2129static int add_user_to_lr_ace(struct opal_dev *dev, void *data)
2130{
2131 int err;
2132 struct opal_lock_unlock *lkul = data;
2133 const u8 users[] = {
2134 OPAL_ADMIN1,
2135 lkul->session.who
2136 };
2137
2138 err = set_lr_boolean_ace(dev, OPAL_LOCKINGRANGE_ACE_START_TO_KEY,
2139 lkul->session.opal_key.lr, users,
2140 ARRAY_SIZE(users));
2141
2142 if (err) {
2143 pr_debug("Error building add user to locking ranges ACEs.\n");
2144 return err;
2145 }
2146
2147 return finalize_and_send(dev, parse_and_check_status);
2148}
2149
eed64951 2150static int lock_unlock_locking_range(struct opal_dev *dev, void *data)
455a7b23
SB
2151{
2152 u8 lr_buffer[OPAL_UID_LENGTH];
eed64951 2153 struct opal_lock_unlock *lkul = data;
455a7b23
SB
2154 u8 read_locked = 1, write_locked = 1;
2155 int err = 0;
2156
455a7b23
SB
2157 if (build_locking_range(lr_buffer, sizeof(lr_buffer),
2158 lkul->session.opal_key.lr) < 0)
2159 return -ERANGE;
2160
2161 switch (lkul->l_state) {
2162 case OPAL_RO:
2163 read_locked = 0;
2164 write_locked = 1;
2165 break;
2166 case OPAL_RW:
2167 read_locked = 0;
2168 write_locked = 0;
2169 break;
2170 case OPAL_LK:
1e815b33 2171 /* vars are initialized to locked */
455a7b23
SB
2172 break;
2173 default:
591c59d1 2174 pr_debug("Tried to set an invalid locking state... returning to uland\n");
455a7b23
SB
2175 return OPAL_INVAL_PARAM;
2176 }
2177
e8b29224
DK
2178 err = cmd_start(dev, lr_buffer, opalmethod[OPAL_SET]);
2179
455a7b23
SB
2180 add_token_u8(&err, dev, OPAL_STARTNAME);
2181 add_token_u8(&err, dev, OPAL_VALUES);
2182 add_token_u8(&err, dev, OPAL_STARTLIST);
2183
2184 add_token_u8(&err, dev, OPAL_STARTNAME);
2185 add_token_u8(&err, dev, OPAL_READLOCKED);
2186 add_token_u8(&err, dev, read_locked);
2187 add_token_u8(&err, dev, OPAL_ENDNAME);
2188
2189 add_token_u8(&err, dev, OPAL_STARTNAME);
2190 add_token_u8(&err, dev, OPAL_WRITELOCKED);
2191 add_token_u8(&err, dev, write_locked);
2192 add_token_u8(&err, dev, OPAL_ENDNAME);
2193
2194 add_token_u8(&err, dev, OPAL_ENDLIST);
2195 add_token_u8(&err, dev, OPAL_ENDNAME);
455a7b23
SB
2196
2197 if (err) {
591c59d1 2198 pr_debug("Error building SET command.\n");
455a7b23
SB
2199 return err;
2200 }
5cc23ed7 2201
455a7b23
SB
2202 return finalize_and_send(dev, parse_and_check_status);
2203}
2204
2205
eed64951 2206static int lock_unlock_locking_range_sum(struct opal_dev *dev, void *data)
455a7b23
SB
2207{
2208 u8 lr_buffer[OPAL_UID_LENGTH];
2209 u8 read_locked = 1, write_locked = 1;
eed64951 2210 struct opal_lock_unlock *lkul = data;
455a7b23
SB
2211 int ret;
2212
2213 clear_opal_cmd(dev);
2214 set_comid(dev, dev->comid);
2215
455a7b23
SB
2216 if (build_locking_range(lr_buffer, sizeof(lr_buffer),
2217 lkul->session.opal_key.lr) < 0)
2218 return -ERANGE;
2219
2220 switch (lkul->l_state) {
2221 case OPAL_RO:
2222 read_locked = 0;
2223 write_locked = 1;
2224 break;
2225 case OPAL_RW:
2226 read_locked = 0;
2227 write_locked = 0;
2228 break;
2229 case OPAL_LK:
1e815b33 2230 /* vars are initialized to locked */
455a7b23
SB
2231 break;
2232 default:
591c59d1 2233 pr_debug("Tried to set an invalid locking state.\n");
455a7b23
SB
2234 return OPAL_INVAL_PARAM;
2235 }
2236 ret = generic_lr_enable_disable(dev, lr_buffer, 1, 1,
2237 read_locked, write_locked);
2238
2239 if (ret < 0) {
591c59d1 2240 pr_debug("Error building SET command.\n");
455a7b23
SB
2241 return ret;
2242 }
5cc23ed7 2243
455a7b23
SB
2244 return finalize_and_send(dev, parse_and_check_status);
2245}
2246
eed64951 2247static int activate_lsp(struct opal_dev *dev, void *data)
455a7b23 2248{
eed64951 2249 struct opal_lr_act *opal_act = data;
455a7b23 2250 u8 user_lr[OPAL_UID_LENGTH];
e8b29224 2251 int err, i;
455a7b23 2252
e8b29224
DK
2253 err = cmd_start(dev, opaluid[OPAL_LOCKINGSP_UID],
2254 opalmethod[OPAL_ACTIVATE]);
455a7b23
SB
2255
2256 if (opal_act->sum) {
2257 err = build_locking_range(user_lr, sizeof(user_lr),
2258 opal_act->lr[0]);
2259 if (err)
2260 return err;
2261
455a7b23 2262 add_token_u8(&err, dev, OPAL_STARTNAME);
c6da429e 2263 add_token_u64(&err, dev, OPAL_SUM_SET_LIST);
455a7b23
SB
2264
2265 add_token_u8(&err, dev, OPAL_STARTLIST);
2266 add_token_bytestring(&err, dev, user_lr, OPAL_UID_LENGTH);
2267 for (i = 1; i < opal_act->num_lrs; i++) {
2268 user_lr[7] = opal_act->lr[i];
2269 add_token_bytestring(&err, dev, user_lr, OPAL_UID_LENGTH);
2270 }
2271 add_token_u8(&err, dev, OPAL_ENDLIST);
2272 add_token_u8(&err, dev, OPAL_ENDNAME);
455a7b23
SB
2273 }
2274
2275 if (err) {
591c59d1 2276 pr_debug("Error building Activate LockingSP command.\n");
455a7b23
SB
2277 return err;
2278 }
2279
2280 return finalize_and_send(dev, parse_and_check_status);
2281}
2282
3fff234b
DK
2283/* Determine if we're in the Manufactured Inactive or Active state */
2284static int get_lsp_lifecycle(struct opal_dev *dev, void *data)
455a7b23
SB
2285{
2286 u8 lc_status;
3fff234b 2287 int err;
455a7b23 2288
3fff234b
DK
2289 err = generic_get_column(dev, opaluid[OPAL_LOCKINGSP_UID],
2290 OPAL_LIFECYCLE);
2291 if (err)
2292 return err;
455a7b23
SB
2293
2294 lc_status = response_get_u64(&dev->parsed, 4);
1e815b33 2295 /* 0x08 is Manufactured Inactive */
455a7b23
SB
2296 /* 0x09 is Manufactured */
2297 if (lc_status != OPAL_MANUFACTURED_INACTIVE) {
591c59d1 2298 pr_debug("Couldn't determine the status of the Lifecycle state\n");
455a7b23
SB
2299 return -ENODEV;
2300 }
2301
2302 return 0;
2303}
2304
3fff234b 2305static int get_msid_cpin_pin(struct opal_dev *dev, void *data)
455a7b23
SB
2306{
2307 const char *msid_pin;
2308 size_t strlen;
3fff234b 2309 int err;
455a7b23 2310
3fff234b
DK
2311 err = generic_get_column(dev, opaluid[OPAL_C_PIN_MSID], OPAL_PIN);
2312 if (err)
2313 return err;
455a7b23
SB
2314
2315 strlen = response_get_string(&dev->parsed, 4, &msid_pin);
2316 if (!msid_pin) {
3fff234b 2317 pr_debug("Couldn't extract MSID_CPIN from response\n");
455a7b23
SB
2318 return OPAL_INVAL_PARAM;
2319 }
2320
2321 dev->prev_data = kmemdup(msid_pin, strlen, GFP_KERNEL);
2322 if (!dev->prev_data)
2323 return -ENOMEM;
2324
2325 dev->prev_d_len = strlen;
2326
2327 return 0;
2328}
2329
51f421c8
RR
2330static int write_table_data(struct opal_dev *dev, void *data)
2331{
2332 struct opal_read_write_table *write_tbl = data;
2333
2334 return generic_table_write_data(dev, write_tbl->data, write_tbl->offset,
2335 write_tbl->size, write_tbl->table_uid);
2336}
2337
2338static int read_table_data_cont(struct opal_dev *dev)
2339{
2340 int err;
2341 const char *data_read;
2342
2343 err = parse_and_check_status(dev);
2344 if (err)
2345 return err;
2346
2347 dev->prev_d_len = response_get_string(&dev->parsed, 1, &data_read);
2348 dev->prev_data = (void *)data_read;
2349 if (!dev->prev_data) {
2350 pr_debug("%s: Couldn't read data from the table.\n", __func__);
2351 return OPAL_INVAL_PARAM;
2352 }
2353
2354 return 0;
2355}
2356
2357/*
2358 * IO_BUFFER_LENGTH = 2048
2359 * sizeof(header) = 56
2360 * No. of Token Bytes in the Response = 11
2361 * MAX size of data that can be carried in response buffer
2362 * at a time is : 2048 - (56 + 11) = 1981 = 0x7BD.
2363 */
2364#define OPAL_MAX_READ_TABLE (0x7BD)
2365
2366static int read_table_data(struct opal_dev *dev, void *data)
2367{
2368 struct opal_read_write_table *read_tbl = data;
2369 int err;
2370 size_t off = 0, max_read_size = OPAL_MAX_READ_TABLE;
2371 u64 table_len, len;
2372 u64 offset = read_tbl->offset, read_size = read_tbl->size - 1;
2373 u8 __user *dst;
2374
2375 err = generic_get_table_info(dev, read_tbl->table_uid, OPAL_TABLE_ROWS);
2376 if (err) {
2377 pr_debug("Couldn't get the table size\n");
2378 return err;
2379 }
2380
2381 table_len = response_get_u64(&dev->parsed, 4);
2382
2383 /* Check if the user is trying to read from the table limits */
2384 if (read_size > table_len || offset > table_len - read_size) {
2385 pr_debug("Read size exceeds the Table size limits (%llu vs. %llu)\n",
2386 offset + read_size, table_len);
2387 return -EINVAL;
2388 }
2389
2390 while (off < read_size) {
2391 err = cmd_start(dev, read_tbl->table_uid, opalmethod[OPAL_GET]);
2392
2393 add_token_u8(&err, dev, OPAL_STARTLIST);
2394 add_token_u8(&err, dev, OPAL_STARTNAME);
2395 add_token_u8(&err, dev, OPAL_STARTROW);
2396 add_token_u64(&err, dev, offset + off); /* start row value */
2397 add_token_u8(&err, dev, OPAL_ENDNAME);
2398
2399 add_token_u8(&err, dev, OPAL_STARTNAME);
2400 add_token_u8(&err, dev, OPAL_ENDROW);
2401
2402 len = min(max_read_size, (size_t)(read_size - off));
2403 add_token_u64(&err, dev, offset + off + len); /* end row value
2404 */
2405 add_token_u8(&err, dev, OPAL_ENDNAME);
2406 add_token_u8(&err, dev, OPAL_ENDLIST);
2407
2408 if (err) {
2409 pr_debug("Error building read table data command.\n");
2410 break;
2411 }
2412
2413 err = finalize_and_send(dev, read_table_data_cont);
2414 if (err)
2415 break;
2416
2417 /* len+1: This includes the NULL terminator at the end*/
2418 if (dev->prev_d_len > len + 1) {
2419 err = -EOVERFLOW;
2420 break;
2421 }
2422
2423 dst = (u8 __user *)(uintptr_t)read_tbl->data;
2424 if (copy_to_user(dst + off, dev->prev_data, dev->prev_d_len)) {
2425 pr_debug("Error copying data to userspace\n");
2426 err = -EFAULT;
2427 break;
2428 }
2429 dev->prev_data = NULL;
2430
2431 off += len;
2432 }
2433
2434 return err;
2435}
2436
eed64951 2437static int end_opal_session(struct opal_dev *dev, void *data)
455a7b23
SB
2438{
2439 int err = 0;
2440
2441 clear_opal_cmd(dev);
455a7b23
SB
2442 set_comid(dev, dev->comid);
2443 add_token_u8(&err, dev, OPAL_ENDOFSESSION);
455a7b23 2444
eed64951
JD
2445 if (err < 0)
2446 return err;
5cc23ed7 2447
455a7b23
SB
2448 return finalize_and_send(dev, end_session_cont);
2449}
2450
2451static int end_opal_session_error(struct opal_dev *dev)
2452{
0af2648e
DK
2453 const struct opal_step error_end_session = {
2454 end_opal_session,
455a7b23 2455 };
5cc23ed7 2456
0af2648e 2457 return execute_step(dev, &error_end_session, 0);
455a7b23
SB
2458}
2459
3db87236 2460static inline void setup_opal_dev(struct opal_dev *dev)
455a7b23 2461{
455a7b23
SB
2462 dev->tsn = 0;
2463 dev->hsn = 0;
455a7b23
SB
2464 dev->prev_data = NULL;
2465}
2466
2467static int check_opal_support(struct opal_dev *dev)
2468{
455a7b23
SB
2469 int ret;
2470
2471 mutex_lock(&dev->dev_lock);
3db87236 2472 setup_opal_dev(dev);
0af2648e 2473 ret = opal_discovery0_step(dev);
c6ea7060 2474 if (!ret)
2475 dev->flags |= OPAL_FL_SUPPORTED;
455a7b23 2476 mutex_unlock(&dev->dev_lock);
5cc23ed7 2477
455a7b23
SB
2478 return ret;
2479}
2480
7d6d1578
SB
2481static void clean_opal_dev(struct opal_dev *dev)
2482{
2483
2484 struct opal_suspend_data *suspend, *next;
2485
2486 mutex_lock(&dev->dev_lock);
2487 list_for_each_entry_safe(suspend, next, &dev->unlk_lst, node) {
2488 list_del(&suspend->node);
2489 kfree(suspend);
2490 }
2491 mutex_unlock(&dev->dev_lock);
2492}
2493
2494void free_opal_dev(struct opal_dev *dev)
2495{
2496 if (!dev)
2497 return;
5cc23ed7 2498
7d6d1578 2499 clean_opal_dev(dev);
f829230d
SS
2500 kfree(dev->resp);
2501 kfree(dev->cmd);
7d6d1578
SB
2502 kfree(dev);
2503}
2504EXPORT_SYMBOL(free_opal_dev);
2505
4f1244c8 2506struct opal_dev *init_opal_dev(void *data, sec_send_recv *send_recv)
455a7b23 2507{
4f1244c8
CH
2508 struct opal_dev *dev;
2509
2510 dev = kmalloc(sizeof(*dev), GFP_KERNEL);
2511 if (!dev)
2512 return NULL;
2513
f829230d
SS
2514 /*
2515 * Presumably DMA-able buffers must be cache-aligned. Kmalloc makes
2516 * sure the allocated buffer is DMA-safe in that regard.
2517 */
2518 dev->cmd = kmalloc(IO_BUFFER_LENGTH, GFP_KERNEL);
2519 if (!dev->cmd)
2520 goto err_free_dev;
2521
2522 dev->resp = kmalloc(IO_BUFFER_LENGTH, GFP_KERNEL);
2523 if (!dev->resp)
2524 goto err_free_cmd;
2525
4f1244c8
CH
2526 INIT_LIST_HEAD(&dev->unlk_lst);
2527 mutex_init(&dev->dev_lock);
c6ea7060 2528 dev->flags = 0;
4f1244c8
CH
2529 dev->data = data;
2530 dev->send_recv = send_recv;
2531 if (check_opal_support(dev) != 0) {
f5b37b7c 2532 pr_debug("Opal is not supported on this device\n");
f829230d 2533 goto err_free_resp;
4f1244c8 2534 }
5cc23ed7 2535
4f1244c8 2536 return dev;
f829230d
SS
2537
2538err_free_resp:
2539 kfree(dev->resp);
2540
2541err_free_cmd:
2542 kfree(dev->cmd);
2543
2544err_free_dev:
2545 kfree(dev);
2546
2547 return NULL;
455a7b23
SB
2548}
2549EXPORT_SYMBOL(init_opal_dev);
2550
2551static int opal_secure_erase_locking_range(struct opal_dev *dev,
2552 struct opal_session_info *opal_session)
2553{
eed64951 2554 const struct opal_step erase_steps[] = {
eed64951
JD
2555 { start_auth_opal_session, opal_session },
2556 { get_active_key, &opal_session->opal_key.lr },
2557 { gen_key, },
3db87236 2558 { end_opal_session, }
455a7b23
SB
2559 };
2560 int ret;
2561
3bfeb612
GJ
2562 ret = opal_get_key(dev, &opal_session->opal_key);
2563 if (ret)
2564 return ret;
455a7b23 2565 mutex_lock(&dev->dev_lock);
3db87236 2566 setup_opal_dev(dev);
a80f36cc 2567 ret = execute_steps(dev, erase_steps, ARRAY_SIZE(erase_steps));
455a7b23 2568 mutex_unlock(&dev->dev_lock);
5cc23ed7 2569
455a7b23
SB
2570 return ret;
2571}
2572
9fb10726
GJ
2573static int opal_get_discv(struct opal_dev *dev, struct opal_discovery *discv)
2574{
2575 const struct opal_step discovery0_step = {
2576 opal_discovery0, discv
2577 };
2578 int ret = 0;
2579
2580 mutex_lock(&dev->dev_lock);
2581 setup_opal_dev(dev);
2582 ret = execute_step(dev, &discovery0_step, 0);
2583 mutex_unlock(&dev->dev_lock);
2584 if (ret)
2585 return ret;
2586 return discv->size; /* modified to actual length of data */
2587}
2588
5c82efc1
GJ
2589static int opal_revertlsp(struct opal_dev *dev, struct opal_revert_lsp *rev)
2590{
2591 /* controller will terminate session */
2592 const struct opal_step steps[] = {
2593 { start_admin1LSP_opal_session, &rev->key },
2594 { revert_lsp, rev }
2595 };
2596 int ret;
2597
3bfeb612
GJ
2598 ret = opal_get_key(dev, &rev->key);
2599 if (ret)
2600 return ret;
5c82efc1
GJ
2601 mutex_lock(&dev->dev_lock);
2602 setup_opal_dev(dev);
2603 ret = execute_steps(dev, steps, ARRAY_SIZE(steps));
2604 mutex_unlock(&dev->dev_lock);
2605
2606 return ret;
2607}
2608
455a7b23
SB
2609static int opal_erase_locking_range(struct opal_dev *dev,
2610 struct opal_session_info *opal_session)
2611{
eed64951 2612 const struct opal_step erase_steps[] = {
eed64951
JD
2613 { start_auth_opal_session, opal_session },
2614 { erase_locking_range, opal_session },
3db87236 2615 { end_opal_session, }
455a7b23
SB
2616 };
2617 int ret;
2618
3bfeb612
GJ
2619 ret = opal_get_key(dev, &opal_session->opal_key);
2620 if (ret)
2621 return ret;
455a7b23 2622 mutex_lock(&dev->dev_lock);
3db87236 2623 setup_opal_dev(dev);
a80f36cc 2624 ret = execute_steps(dev, erase_steps, ARRAY_SIZE(erase_steps));
455a7b23 2625 mutex_unlock(&dev->dev_lock);
5cc23ed7 2626
455a7b23
SB
2627 return ret;
2628}
2629
2630static int opal_enable_disable_shadow_mbr(struct opal_dev *dev,
2631 struct opal_mbr_data *opal_mbr)
2632{
78bf4735
DK
2633 u8 enable_disable = opal_mbr->enable_disable == OPAL_MBR_ENABLE ?
2634 OPAL_TRUE : OPAL_FALSE;
2635
eed64951 2636 const struct opal_step mbr_steps[] = {
eed64951 2637 { start_admin1LSP_opal_session, &opal_mbr->key },
78bf4735 2638 { set_mbr_done, &enable_disable },
eed64951
JD
2639 { end_opal_session, },
2640 { start_admin1LSP_opal_session, &opal_mbr->key },
78bf4735 2641 { set_mbr_enable_disable, &enable_disable },
3db87236 2642 { end_opal_session, }
455a7b23
SB
2643 };
2644 int ret;
2645
2646 if (opal_mbr->enable_disable != OPAL_MBR_ENABLE &&
2647 opal_mbr->enable_disable != OPAL_MBR_DISABLE)
2648 return -EINVAL;
2649
3bfeb612
GJ
2650 ret = opal_get_key(dev, &opal_mbr->key);
2651 if (ret)
2652 return ret;
455a7b23 2653 mutex_lock(&dev->dev_lock);
3db87236 2654 setup_opal_dev(dev);
a80f36cc 2655 ret = execute_steps(dev, mbr_steps, ARRAY_SIZE(mbr_steps));
455a7b23 2656 mutex_unlock(&dev->dev_lock);
5cc23ed7 2657
455a7b23
SB
2658 return ret;
2659}
2660
c9888443
JR
2661static int opal_set_mbr_done(struct opal_dev *dev,
2662 struct opal_mbr_done *mbr_done)
2663{
2664 u8 mbr_done_tf = mbr_done->done_flag == OPAL_MBR_DONE ?
2665 OPAL_TRUE : OPAL_FALSE;
2666
2667 const struct opal_step mbr_steps[] = {
2668 { start_admin1LSP_opal_session, &mbr_done->key },
2669 { set_mbr_done, &mbr_done_tf },
2670 { end_opal_session, }
2671 };
2672 int ret;
2673
2674 if (mbr_done->done_flag != OPAL_MBR_DONE &&
2675 mbr_done->done_flag != OPAL_MBR_NOT_DONE)
2676 return -EINVAL;
2677
3bfeb612
GJ
2678 ret = opal_get_key(dev, &mbr_done->key);
2679 if (ret)
2680 return ret;
c9888443
JR
2681 mutex_lock(&dev->dev_lock);
2682 setup_opal_dev(dev);
2683 ret = execute_steps(dev, mbr_steps, ARRAY_SIZE(mbr_steps));
2684 mutex_unlock(&dev->dev_lock);
5cc23ed7 2685
c9888443
JR
2686 return ret;
2687}
2688
a9b25b4c
JR
2689static int opal_write_shadow_mbr(struct opal_dev *dev,
2690 struct opal_shadow_mbr *info)
2691{
2692 const struct opal_step mbr_steps[] = {
2693 { start_admin1LSP_opal_session, &info->key },
2694 { write_shadow_mbr, info },
2695 { end_opal_session, }
2696 };
2697 int ret;
2698
2699 if (info->size == 0)
2700 return 0;
2701
3bfeb612
GJ
2702 ret = opal_get_key(dev, &info->key);
2703 if (ret)
2704 return ret;
a9b25b4c
JR
2705 mutex_lock(&dev->dev_lock);
2706 setup_opal_dev(dev);
2707 ret = execute_steps(dev, mbr_steps, ARRAY_SIZE(mbr_steps));
2708 mutex_unlock(&dev->dev_lock);
5cc23ed7 2709
a9b25b4c
JR
2710 return ret;
2711}
2712
455a7b23
SB
2713static int opal_save(struct opal_dev *dev, struct opal_lock_unlock *lk_unlk)
2714{
2715 struct opal_suspend_data *suspend;
2716
2717 suspend = kzalloc(sizeof(*suspend), GFP_KERNEL);
2718 if (!suspend)
2719 return -ENOMEM;
2720
2721 suspend->unlk = *lk_unlk;
2722 suspend->lr = lk_unlk->session.opal_key.lr;
2723
2724 mutex_lock(&dev->dev_lock);
3db87236 2725 setup_opal_dev(dev);
455a7b23
SB
2726 add_suspend_info(dev, suspend);
2727 mutex_unlock(&dev->dev_lock);
5cc23ed7 2728
455a7b23
SB
2729 return 0;
2730}
2731
2732static int opal_add_user_to_lr(struct opal_dev *dev,
2733 struct opal_lock_unlock *lk_unlk)
2734{
eed64951 2735 const struct opal_step steps[] = {
eed64951
JD
2736 { start_admin1LSP_opal_session, &lk_unlk->session.opal_key },
2737 { add_user_to_lr, lk_unlk },
8be19a02 2738 { add_user_to_lr_ace, lk_unlk },
3db87236 2739 { end_opal_session, }
455a7b23
SB
2740 };
2741 int ret;
2742
2743 if (lk_unlk->l_state != OPAL_RO &&
2744 lk_unlk->l_state != OPAL_RW) {
591c59d1 2745 pr_debug("Locking state was not RO or RW\n");
455a7b23
SB
2746 return -EINVAL;
2747 }
5cc23ed7 2748
b0bfdfc2 2749 if (lk_unlk->session.who < OPAL_USER1 ||
455a7b23 2750 lk_unlk->session.who > OPAL_USER9) {
591c59d1
SB
2751 pr_debug("Authority was not within the range of users: %d\n",
2752 lk_unlk->session.who);
455a7b23
SB
2753 return -EINVAL;
2754 }
5cc23ed7 2755
455a7b23 2756 if (lk_unlk->session.sum) {
591c59d1
SB
2757 pr_debug("%s not supported in sum. Use setup locking range\n",
2758 __func__);
455a7b23
SB
2759 return -EINVAL;
2760 }
2761
3bfeb612
GJ
2762 ret = opal_get_key(dev, &lk_unlk->session.opal_key);
2763 if (ret)
2764 return ret;
455a7b23 2765 mutex_lock(&dev->dev_lock);
3db87236 2766 setup_opal_dev(dev);
a80f36cc 2767 ret = execute_steps(dev, steps, ARRAY_SIZE(steps));
455a7b23 2768 mutex_unlock(&dev->dev_lock);
5cc23ed7 2769
455a7b23
SB
2770 return ret;
2771}
2772
5e4c7cf6 2773static int opal_reverttper(struct opal_dev *dev, struct opal_key *opal, bool psid)
455a7b23 2774{
5e4c7cf6 2775 /* controller will terminate session */
eed64951 2776 const struct opal_step revert_steps[] = {
eed64951 2777 { start_SIDASP_opal_session, opal },
5e4c7cf6 2778 { revert_tper, }
455a7b23 2779 };
5e4c7cf6
RR
2780 const struct opal_step psid_revert_steps[] = {
2781 { start_PSID_opal_session, opal },
2782 { revert_tper, }
2783 };
2784
455a7b23
SB
2785 int ret;
2786
3bfeb612
GJ
2787 ret = opal_get_key(dev, opal);
2788
2789 if (ret)
2790 return ret;
455a7b23 2791 mutex_lock(&dev->dev_lock);
3db87236 2792 setup_opal_dev(dev);
5e4c7cf6
RR
2793 if (psid)
2794 ret = execute_steps(dev, psid_revert_steps,
2795 ARRAY_SIZE(psid_revert_steps));
2796 else
2797 ret = execute_steps(dev, revert_steps,
2798 ARRAY_SIZE(revert_steps));
455a7b23 2799 mutex_unlock(&dev->dev_lock);
7d6d1578
SB
2800
2801 /*
2802 * If we successfully reverted lets clean
2803 * any saved locking ranges.
2804 */
2805 if (!ret)
2806 clean_opal_dev(dev);
2807
455a7b23
SB
2808 return ret;
2809}
2810
eed64951
JD
2811static int __opal_lock_unlock(struct opal_dev *dev,
2812 struct opal_lock_unlock *lk_unlk)
455a7b23 2813{
eed64951 2814 const struct opal_step unlock_steps[] = {
eed64951
JD
2815 { start_auth_opal_session, &lk_unlk->session },
2816 { lock_unlock_locking_range, lk_unlk },
3db87236 2817 { end_opal_session, }
455a7b23 2818 };
eed64951 2819 const struct opal_step unlock_sum_steps[] = {
eed64951
JD
2820 { start_auth_opal_session, &lk_unlk->session },
2821 { lock_unlock_locking_range_sum, lk_unlk },
3db87236 2822 { end_opal_session, }
455a7b23
SB
2823 };
2824
3db87236 2825 if (lk_unlk->session.sum)
a80f36cc
DK
2826 return execute_steps(dev, unlock_sum_steps,
2827 ARRAY_SIZE(unlock_sum_steps));
3db87236 2828 else
a80f36cc
DK
2829 return execute_steps(dev, unlock_steps,
2830 ARRAY_SIZE(unlock_steps));
455a7b23
SB
2831}
2832
dbec491b
SB
2833static int __opal_set_mbr_done(struct opal_dev *dev, struct opal_key *key)
2834{
78bf4735 2835 u8 mbr_done_tf = OPAL_TRUE;
1e815b33 2836 const struct opal_step mbrdone_step[] = {
dbec491b
SB
2837 { start_admin1LSP_opal_session, key },
2838 { set_mbr_done, &mbr_done_tf },
3db87236 2839 { end_opal_session, }
dbec491b
SB
2840 };
2841
a80f36cc 2842 return execute_steps(dev, mbrdone_step, ARRAY_SIZE(mbrdone_step));
dbec491b
SB
2843}
2844
c1f480b2
LB
2845static void opal_lock_check_for_saved_key(struct opal_dev *dev,
2846 struct opal_lock_unlock *lk_unlk)
2847{
2848 struct opal_suspend_data *iter;
2849
2850 if (lk_unlk->l_state != OPAL_LK ||
2851 lk_unlk->session.opal_key.key_len > 0)
2852 return;
2853
2854 /*
2855 * Usually when closing a crypto device (eg: dm-crypt with LUKS) the
2856 * volume key is not required, as it requires root privileges anyway,
2857 * and root can deny access to a disk in many ways regardless.
2858 * Requiring the volume key to lock the device is a peculiarity of the
2859 * OPAL specification. Given we might already have saved the key if
2860 * the user requested it via the 'IOC_OPAL_SAVE' ioctl, we can use
2861 * that key to lock the device if no key was provided here, the
2862 * locking range matches and the appropriate flag was passed with
2863 * 'IOC_OPAL_SAVE'.
2864 * This allows integrating OPAL with tools and libraries that are used
2865 * to the common behaviour and do not ask for the volume key when
2866 * closing a device.
2867 */
2868 setup_opal_dev(dev);
2869 list_for_each_entry(iter, &dev->unlk_lst, node) {
2870 if ((iter->unlk.flags & OPAL_SAVE_FOR_LOCK) &&
2871 iter->lr == lk_unlk->session.opal_key.lr &&
2872 iter->unlk.session.opal_key.key_len > 0) {
2873 lk_unlk->session.opal_key.key_len =
2874 iter->unlk.session.opal_key.key_len;
2875 memcpy(lk_unlk->session.opal_key.key,
2876 iter->unlk.session.opal_key.key,
2877 iter->unlk.session.opal_key.key_len);
2878 break;
2879 }
2880 }
2881}
2882
eed64951
JD
2883static int opal_lock_unlock(struct opal_dev *dev,
2884 struct opal_lock_unlock *lk_unlk)
455a7b23 2885{
455a7b23
SB
2886 int ret;
2887
15ddffcb 2888 if (lk_unlk->session.who > OPAL_USER9)
455a7b23
SB
2889 return -EINVAL;
2890
3bfeb612
GJ
2891 ret = opal_get_key(dev, &lk_unlk->session.opal_key);
2892 if (ret)
2893 return ret;
455a7b23 2894 mutex_lock(&dev->dev_lock);
c1f480b2 2895 opal_lock_check_for_saved_key(dev, lk_unlk);
eed64951 2896 ret = __opal_lock_unlock(dev, lk_unlk);
455a7b23 2897 mutex_unlock(&dev->dev_lock);
5cc23ed7 2898
455a7b23
SB
2899 return ret;
2900}
2901
2902static int opal_take_ownership(struct opal_dev *dev, struct opal_key *opal)
2903{
eed64951 2904 const struct opal_step owner_steps[] = {
eed64951
JD
2905 { start_anybodyASP_opal_session, },
2906 { get_msid_cpin_pin, },
2907 { end_opal_session, },
2908 { start_SIDASP_opal_session, opal },
2909 { set_sid_cpin_pin, opal },
3db87236 2910 { end_opal_session, }
455a7b23 2911 };
455a7b23
SB
2912 int ret;
2913
2914 if (!dev)
2915 return -ENODEV;
2916
3bfeb612
GJ
2917 ret = opal_get_key(dev, opal);
2918 if (ret)
2919 return ret;
455a7b23 2920 mutex_lock(&dev->dev_lock);
3db87236 2921 setup_opal_dev(dev);
a80f36cc 2922 ret = execute_steps(dev, owner_steps, ARRAY_SIZE(owner_steps));
455a7b23 2923 mutex_unlock(&dev->dev_lock);
5cc23ed7 2924
455a7b23
SB
2925 return ret;
2926}
2927
1e815b33
DK
2928static int opal_activate_lsp(struct opal_dev *dev,
2929 struct opal_lr_act *opal_lr_act)
455a7b23 2930{
eed64951 2931 const struct opal_step active_steps[] = {
eed64951
JD
2932 { start_SIDASP_opal_session, &opal_lr_act->key },
2933 { get_lsp_lifecycle, },
2934 { activate_lsp, opal_lr_act },
3db87236 2935 { end_opal_session, }
455a7b23
SB
2936 };
2937 int ret;
2938
2939 if (!opal_lr_act->num_lrs || opal_lr_act->num_lrs > OPAL_MAX_LRS)
2940 return -EINVAL;
2941
3bfeb612
GJ
2942 ret = opal_get_key(dev, &opal_lr_act->key);
2943 if (ret)
2944 return ret;
455a7b23 2945 mutex_lock(&dev->dev_lock);
3db87236 2946 setup_opal_dev(dev);
a80f36cc 2947 ret = execute_steps(dev, active_steps, ARRAY_SIZE(active_steps));
455a7b23 2948 mutex_unlock(&dev->dev_lock);
5cc23ed7 2949
455a7b23
SB
2950 return ret;
2951}
2952
2953static int opal_setup_locking_range(struct opal_dev *dev,
2954 struct opal_user_lr_setup *opal_lrs)
2955{
eed64951 2956 const struct opal_step lr_steps[] = {
eed64951
JD
2957 { start_auth_opal_session, &opal_lrs->session },
2958 { setup_locking_range, opal_lrs },
3db87236 2959 { end_opal_session, }
455a7b23
SB
2960 };
2961 int ret;
2962
3bfeb612
GJ
2963 ret = opal_get_key(dev, &opal_lrs->session.opal_key);
2964 if (ret)
2965 return ret;
455a7b23 2966 mutex_lock(&dev->dev_lock);
3db87236 2967 setup_opal_dev(dev);
a80f36cc 2968 ret = execute_steps(dev, lr_steps, ARRAY_SIZE(lr_steps));
455a7b23 2969 mutex_unlock(&dev->dev_lock);
5cc23ed7 2970
455a7b23
SB
2971 return ret;
2972}
2973
4c4dd04e
OK
2974static int opal_locking_range_status(struct opal_dev *dev,
2975 struct opal_lr_status *opal_lrst,
2976 void __user *data)
2977{
2978 const struct opal_step lr_steps[] = {
2979 { start_auth_opal_session, &opal_lrst->session },
2980 { locking_range_status, opal_lrst },
2981 { end_opal_session, }
2982 };
2983 int ret;
2984
2985 mutex_lock(&dev->dev_lock);
2986 setup_opal_dev(dev);
2987 ret = execute_steps(dev, lr_steps, ARRAY_SIZE(lr_steps));
2988 mutex_unlock(&dev->dev_lock);
2989
2990 /* skip session info when copying back to uspace */
2991 if (!ret && copy_to_user(data + offsetof(struct opal_lr_status, range_start),
2992 (void *)opal_lrst + offsetof(struct opal_lr_status, range_start),
2993 sizeof(*opal_lrst) - offsetof(struct opal_lr_status, range_start))) {
2994 pr_debug("Error copying status to userspace\n");
2995 return -EFAULT;
2996 }
2997
2998 return ret;
2999}
3000
455a7b23
SB
3001static int opal_set_new_pw(struct opal_dev *dev, struct opal_new_pw *opal_pw)
3002{
eed64951 3003 const struct opal_step pw_steps[] = {
eed64951
JD
3004 { start_auth_opal_session, &opal_pw->session },
3005 { set_new_pw, &opal_pw->new_user_pw },
3db87236 3006 { end_opal_session, }
455a7b23 3007 };
455a7b23
SB
3008 int ret;
3009
15ddffcb 3010 if (opal_pw->session.who > OPAL_USER9 ||
455a7b23
SB
3011 opal_pw->new_user_pw.who > OPAL_USER9)
3012 return -EINVAL;
3013
3014 mutex_lock(&dev->dev_lock);
3db87236 3015 setup_opal_dev(dev);
a80f36cc 3016 ret = execute_steps(dev, pw_steps, ARRAY_SIZE(pw_steps));
455a7b23 3017 mutex_unlock(&dev->dev_lock);
5cc23ed7 3018
3bfeb612
GJ
3019 if (ret)
3020 return ret;
3021
3022 /* update keyring with new password */
3023 ret = update_sed_opal_key(OPAL_AUTH_KEY,
3024 opal_pw->new_user_pw.opal_key.key,
3025 opal_pw->new_user_pw.opal_key.key_len);
3026
455a7b23
SB
3027 return ret;
3028}
3029
3030static int opal_activate_user(struct opal_dev *dev,
3031 struct opal_session_info *opal_session)
3032{
eed64951 3033 const struct opal_step act_steps[] = {
eed64951
JD
3034 { start_admin1LSP_opal_session, &opal_session->opal_key },
3035 { internal_activate_user, opal_session },
3db87236 3036 { end_opal_session, }
455a7b23 3037 };
455a7b23
SB
3038 int ret;
3039
3040 /* We can't activate Admin1 it's active as manufactured */
b0bfdfc2 3041 if (opal_session->who < OPAL_USER1 ||
455a7b23 3042 opal_session->who > OPAL_USER9) {
591c59d1 3043 pr_debug("Who was not a valid user: %d\n", opal_session->who);
455a7b23
SB
3044 return -EINVAL;
3045 }
3046
3bfeb612
GJ
3047 ret = opal_get_key(dev, &opal_session->opal_key);
3048 if (ret)
3049 return ret;
455a7b23 3050 mutex_lock(&dev->dev_lock);
3db87236 3051 setup_opal_dev(dev);
a80f36cc 3052 ret = execute_steps(dev, act_steps, ARRAY_SIZE(act_steps));
455a7b23 3053 mutex_unlock(&dev->dev_lock);
5cc23ed7 3054
455a7b23
SB
3055 return ret;
3056}
3057
3058bool opal_unlock_from_suspend(struct opal_dev *dev)
3059{
3060 struct opal_suspend_data *suspend;
455a7b23
SB
3061 bool was_failure = false;
3062 int ret = 0;
3063
3064 if (!dev)
3065 return false;
5cc23ed7 3066
c6ea7060 3067 if (!(dev->flags & OPAL_FL_SUPPORTED))
455a7b23
SB
3068 return false;
3069
3070 mutex_lock(&dev->dev_lock);
3db87236 3071 setup_opal_dev(dev);
455a7b23
SB
3072
3073 list_for_each_entry(suspend, &dev->unlk_lst, node) {
455a7b23
SB
3074 dev->tsn = 0;
3075 dev->hsn = 0;
3076
eed64951 3077 ret = __opal_lock_unlock(dev, &suspend->unlk);
455a7b23 3078 if (ret) {
591c59d1
SB
3079 pr_debug("Failed to unlock LR %hhu with sum %d\n",
3080 suspend->unlk.session.opal_key.lr,
3081 suspend->unlk.session.sum);
455a7b23
SB
3082 was_failure = true;
3083 }
5cc23ed7 3084
c6ea7060 3085 if (dev->flags & OPAL_FL_MBR_ENABLED) {
dbec491b
SB
3086 ret = __opal_set_mbr_done(dev, &suspend->unlk.session.opal_key);
3087 if (ret)
3088 pr_debug("Failed to set MBR Done in S3 resume\n");
3089 }
455a7b23
SB
3090 }
3091 mutex_unlock(&dev->dev_lock);
5cc23ed7 3092
455a7b23
SB
3093 return was_failure;
3094}
3095EXPORT_SYMBOL(opal_unlock_from_suspend);
3096
51f421c8
RR
3097static int opal_read_table(struct opal_dev *dev,
3098 struct opal_read_write_table *rw_tbl)
3099{
3100 const struct opal_step read_table_steps[] = {
3101 { start_admin1LSP_opal_session, &rw_tbl->key },
3102 { read_table_data, rw_tbl },
3103 { end_opal_session, }
3104 };
3105 int ret = 0;
3106
3107 if (!rw_tbl->size)
3108 return ret;
3109
3110 return execute_steps(dev, read_table_steps,
3111 ARRAY_SIZE(read_table_steps));
3112}
3113
3114static int opal_write_table(struct opal_dev *dev,
3115 struct opal_read_write_table *rw_tbl)
3116{
3117 const struct opal_step write_table_steps[] = {
3118 { start_admin1LSP_opal_session, &rw_tbl->key },
3119 { write_table_data, rw_tbl },
3120 { end_opal_session, }
3121 };
3122 int ret = 0;
3123
3124 if (!rw_tbl->size)
3125 return ret;
3126
3127 return execute_steps(dev, write_table_steps,
3128 ARRAY_SIZE(write_table_steps));
3129}
3130
3131static int opal_generic_read_write_table(struct opal_dev *dev,
3132 struct opal_read_write_table *rw_tbl)
3133{
3134 int ret, bit_set;
3135
3bfeb612
GJ
3136 ret = opal_get_key(dev, &rw_tbl->key);
3137 if (ret)
3138 return ret;
51f421c8
RR
3139 mutex_lock(&dev->dev_lock);
3140 setup_opal_dev(dev);
3141
3142 bit_set = fls64(rw_tbl->flags) - 1;
3143 switch (bit_set) {
3144 case OPAL_READ_TABLE:
3145 ret = opal_read_table(dev, rw_tbl);
3146 break;
3147 case OPAL_WRITE_TABLE:
3148 ret = opal_write_table(dev, rw_tbl);
3149 break;
3150 default:
3151 pr_debug("Invalid bit set in the flag (%016llx).\n",
3152 rw_tbl->flags);
3153 ret = -EINVAL;
3154 break;
3155 }
3156
3157 mutex_unlock(&dev->dev_lock);
3158
3159 return ret;
3160}
3161
c6ea7060 3162static int opal_get_status(struct opal_dev *dev, void __user *data)
3163{
3164 struct opal_status sts = {0};
3165
3166 /*
3167 * check_opal_support() error is not fatal,
3168 * !dev->supported is a valid condition
3169 */
3170 if (!check_opal_support(dev))
3171 sts.flags = dev->flags;
3172 if (copy_to_user(data, &sts, sizeof(sts))) {
3173 pr_debug("Error copying status to userspace\n");
3174 return -EFAULT;
3175 }
3176 return 0;
3177}
3178
9e05a259
OK
3179static int opal_get_geometry(struct opal_dev *dev, void __user *data)
3180{
3181 struct opal_geometry geo = {0};
3182
3183 if (check_opal_support(dev))
3184 return -EINVAL;
3185
3186 geo.align = dev->align_required;
3187 geo.logical_block_size = dev->logical_block_size;
3188 geo.alignment_granularity = dev->align;
3189 geo.lowest_aligned_lba = dev->lowest_lba;
3190
3191 if (copy_to_user(data, &geo, sizeof(geo))) {
3192 pr_debug("Error copying geometry data to userspace\n");
3193 return -EFAULT;
3194 }
3195
3196 return 0;
3197}
3198
e225c20e 3199int sed_ioctl(struct opal_dev *dev, unsigned int cmd, void __user *arg)
455a7b23 3200{
e225c20e
SB
3201 void *p;
3202 int ret = -ENOTTY;
455a7b23
SB
3203
3204 if (!capable(CAP_SYS_ADMIN))
3205 return -EACCES;
4f1244c8 3206 if (!dev)
3bfeb612 3207 return -EOPNOTSUPP;
c6ea7060 3208 if (!(dev->flags & OPAL_FL_SUPPORTED))
3bfeb612 3209 return -EOPNOTSUPP;
455a7b23 3210
c6ea7060 3211 if (cmd & IOC_IN) {
3212 p = memdup_user(arg, _IOC_SIZE(cmd));
3213 if (IS_ERR(p))
3214 return PTR_ERR(p);
3215 }
455a7b23 3216
e225c20e
SB
3217 switch (cmd) {
3218 case IOC_OPAL_SAVE:
3219 ret = opal_save(dev, p);
3220 break;
3221 case IOC_OPAL_LOCK_UNLOCK:
3222 ret = opal_lock_unlock(dev, p);
3223 break;
3224 case IOC_OPAL_TAKE_OWNERSHIP:
3225 ret = opal_take_ownership(dev, p);
3226 break;
3227 case IOC_OPAL_ACTIVATE_LSP:
3228 ret = opal_activate_lsp(dev, p);
3229 break;
3230 case IOC_OPAL_SET_PW:
3231 ret = opal_set_new_pw(dev, p);
3232 break;
3233 case IOC_OPAL_ACTIVATE_USR:
3234 ret = opal_activate_user(dev, p);
3235 break;
3236 case IOC_OPAL_REVERT_TPR:
5e4c7cf6 3237 ret = opal_reverttper(dev, p, false);
e225c20e
SB
3238 break;
3239 case IOC_OPAL_LR_SETUP:
3240 ret = opal_setup_locking_range(dev, p);
3241 break;
3242 case IOC_OPAL_ADD_USR_TO_LR:
3243 ret = opal_add_user_to_lr(dev, p);
3244 break;
3245 case IOC_OPAL_ENABLE_DISABLE_MBR:
3246 ret = opal_enable_disable_shadow_mbr(dev, p);
3247 break;
c9888443
JR
3248 case IOC_OPAL_MBR_DONE:
3249 ret = opal_set_mbr_done(dev, p);
3250 break;
a9b25b4c
JR
3251 case IOC_OPAL_WRITE_SHADOW_MBR:
3252 ret = opal_write_shadow_mbr(dev, p);
3253 break;
e225c20e
SB
3254 case IOC_OPAL_ERASE_LR:
3255 ret = opal_erase_locking_range(dev, p);
3256 break;
3257 case IOC_OPAL_SECURE_ERASE_LR:
3258 ret = opal_secure_erase_locking_range(dev, p);
3259 break;
5e4c7cf6
RR
3260 case IOC_OPAL_PSID_REVERT_TPR:
3261 ret = opal_reverttper(dev, p, true);
3262 break;
51f421c8
RR
3263 case IOC_OPAL_GENERIC_TABLE_RW:
3264 ret = opal_generic_read_write_table(dev, p);
3265 break;
c6ea7060 3266 case IOC_OPAL_GET_STATUS:
3267 ret = opal_get_status(dev, arg);
3268 break;
4c4dd04e
OK
3269 case IOC_OPAL_GET_LR_STATUS:
3270 ret = opal_locking_range_status(dev, p, arg);
3271 break;
9e05a259
OK
3272 case IOC_OPAL_GET_GEOMETRY:
3273 ret = opal_get_geometry(dev, arg);
3274 break;
5c82efc1
GJ
3275 case IOC_OPAL_REVERT_LSP:
3276 ret = opal_revertlsp(dev, p);
3277 break;
9fb10726
GJ
3278 case IOC_OPAL_DISCOVERY:
3279 ret = opal_get_discv(dev, p);
3280 break;
3281
455a7b23 3282 default:
591c59d1 3283 break;
455a7b23 3284 }
e225c20e 3285
c6ea7060 3286 if (cmd & IOC_IN)
3287 kfree(p);
e225c20e 3288 return ret;
455a7b23
SB
3289}
3290EXPORT_SYMBOL_GPL(sed_ioctl);
3bfeb612
GJ
3291
3292static int __init sed_opal_init(void)
3293{
3294 struct key *kr;
3295
3296 kr = keyring_alloc(".sed_opal",
3297 GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, current_cred(),
3298 (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_VIEW |
3299 KEY_USR_READ | KEY_USR_SEARCH | KEY_USR_WRITE,
3300 KEY_ALLOC_NOT_IN_QUOTA,
3301 NULL, NULL);
3302 if (IS_ERR(kr))
3303 return PTR_ERR(kr);
3304
3305 sed_opal_keyring = kr;
3306
3307 return 0;
3308}
3309late_initcall(sed_opal_init);