summaryrefslogtreecommitdiffstats
path: root/block/sed-opal.c
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@lst.de>2017-02-17 07:59:39 -0500
committerJens Axboe <axboe@fb.com>2017-02-17 14:41:47 -0500
commit4f1244c8298606b8fae64b4d78b820ae6b896e3c (patch)
tree81fbf9080d730ca328572847be75fa4e05e4268e /block/sed-opal.c
parentf5b37b7c23915af93081a8711e0a0f0219063756 (diff)
block/sed-opal: allocate struct opal_dev dynamically
Insted of bloating the containing structure with it all the time this allocates struct opal_dev dynamically. Additionally this allows moving the definition of struct opal_dev into sed-opal.c. For this a new private data field is added to it that is passed to the send/receive callback. After that a lot of internals can be made private as well. Signed-off-by: Christoph Hellwig <hch@lst.de> Tested-by: Scott Bauer <scott.bauer@intel.com> Reviewed-by: Scott Bauer <scott.bauer@intel.com> Signed-off-by: Jens Axboe <axboe@fb.com>
Diffstat (limited to 'block/sed-opal.c')
-rw-r--r--block/sed-opal.c101
1 files changed, 91 insertions, 10 deletions
diff --git a/block/sed-opal.c b/block/sed-opal.c
index bcdd5b6d02e8..d1c52ba4d62d 100644
--- a/block/sed-opal.c
+++ b/block/sed-opal.c
@@ -31,6 +31,77 @@
31 31
32#include "opal_proto.h" 32#include "opal_proto.h"
33 33
34#define IO_BUFFER_LENGTH 2048
35#define MAX_TOKS 64
36
37typedef int (*opal_step)(struct opal_dev *dev);
38
39enum opal_atom_width {
40 OPAL_WIDTH_TINY,
41 OPAL_WIDTH_SHORT,
42 OPAL_WIDTH_MEDIUM,
43 OPAL_WIDTH_LONG,
44 OPAL_WIDTH_TOKEN
45};
46
47/*
48 * On the parsed response, we don't store again the toks that are already
49 * stored in the response buffer. Instead, for each token, we just store a
50 * pointer to the position in the buffer where the token starts, and the size
51 * of the token in bytes.
52 */
53struct opal_resp_tok {
54 const u8 *pos;
55 size_t len;
56 enum opal_response_token type;
57 enum opal_atom_width width;
58 union {
59 u64 u;
60 s64 s;
61 } stored;
62};
63
64/*
65 * From the response header it's not possible to know how many tokens there are
66 * on the payload. So we hardcode that the maximum will be MAX_TOKS, and later
67 * if we start dealing with messages that have more than that, we can increase
68 * this number. This is done to avoid having to make two passes through the
69 * response, the first one counting how many tokens we have and the second one
70 * actually storing the positions.
71 */
72struct parsed_resp {
73 int num;
74 struct opal_resp_tok toks[MAX_TOKS];
75};
76
77struct opal_dev {
78 bool supported;
79
80 void *data;
81 sec_send_recv *send_recv;
82
83 const opal_step *funcs;
84 void **func_data;
85 int state;
86 struct mutex dev_lock;
87 u16 comid;
88 u32 hsn;
89 u32 tsn;
90 u64 align;
91 u64 lowest_lba;
92
93 size_t pos;
94 u8 cmd[IO_BUFFER_LENGTH];
95 u8 resp[IO_BUFFER_LENGTH];
96
97 struct parsed_resp parsed;
98 size_t prev_d_len;
99 void *prev_data;
100
101 struct list_head unlk_lst;
102};
103
104
34static const u8 opaluid[][OPAL_UID_LENGTH] = { 105static const u8 opaluid[][OPAL_UID_LENGTH] = {
35 /* users */ 106 /* users */
36 [OPAL_SMUID_UID] = 107 [OPAL_SMUID_UID] =
@@ -243,14 +314,14 @@ static u16 get_comid_v200(const void *data)
243 314
244static int opal_send_cmd(struct opal_dev *dev) 315static int opal_send_cmd(struct opal_dev *dev)
245{ 316{
246 return dev->send_recv(dev, dev->comid, TCG_SECP_01, 317 return dev->send_recv(dev->data, dev->comid, TCG_SECP_01,
247 dev->cmd, IO_BUFFER_LENGTH, 318 dev->cmd, IO_BUFFER_LENGTH,
248 true); 319 true);
249} 320}
250 321
251static int opal_recv_cmd(struct opal_dev *dev) 322static int opal_recv_cmd(struct opal_dev *dev)
252{ 323{
253 return dev->send_recv(dev, dev->comid, TCG_SECP_01, 324 return dev->send_recv(dev->data, dev->comid, TCG_SECP_01,
254 dev->resp, IO_BUFFER_LENGTH, 325 dev->resp, IO_BUFFER_LENGTH,
255 false); 326 false);
256} 327}
@@ -1943,16 +2014,24 @@ static int check_opal_support(struct opal_dev *dev)
1943 return ret; 2014 return ret;
1944} 2015}
1945 2016
1946void init_opal_dev(struct opal_dev *opal_dev, sec_send_recv *send_recv) 2017struct opal_dev *init_opal_dev(void *data, sec_send_recv *send_recv)
1947{ 2018{
1948 if (opal_dev->initialized) 2019 struct opal_dev *dev;
1949 return; 2020
1950 INIT_LIST_HEAD(&opal_dev->unlk_lst); 2021 dev = kmalloc(sizeof(*dev), GFP_KERNEL);
1951 mutex_init(&opal_dev->dev_lock); 2022 if (!dev)
1952 opal_dev->send_recv = send_recv; 2023 return NULL;
1953 if (check_opal_support(opal_dev) < 0) 2024
2025 INIT_LIST_HEAD(&dev->unlk_lst);
2026 mutex_init(&dev->dev_lock);
2027 dev->data = data;
2028 dev->send_recv = send_recv;
2029 if (check_opal_support(dev) != 0) {
1954 pr_debug("Opal is not supported on this device\n"); 2030 pr_debug("Opal is not supported on this device\n");
1955 opal_dev->initialized = true; 2031 kfree(dev);
2032 return NULL;
2033 }
2034 return dev;
1956} 2035}
1957EXPORT_SYMBOL(init_opal_dev); 2036EXPORT_SYMBOL(init_opal_dev);
1958 2037
@@ -2351,6 +2430,8 @@ int sed_ioctl(struct opal_dev *dev, unsigned int cmd, void __user *arg)
2351 2430
2352 if (!capable(CAP_SYS_ADMIN)) 2431 if (!capable(CAP_SYS_ADMIN))
2353 return -EACCES; 2432 return -EACCES;
2433 if (!dev)
2434 return -ENOTSUPP;
2354 if (!dev->supported) { 2435 if (!dev->supported) {
2355 pr_err("Not supported\n"); 2436 pr_err("Not supported\n");
2356 return -ENOTSUPP; 2437 return -ENOTSUPP;