sed-opal.h 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. /*
  2. * Copyright © 2016 Intel Corporation
  3. *
  4. * Authors:
  5. * Rafael Antognolli <rafael.antognolli@intel.com>
  6. * Scott Bauer <scott.bauer@intel.com>
  7. *
  8. * This program is free software; you can redistribute it and/or modify it
  9. * under the terms and conditions of the GNU General Public License,
  10. * version 2, as published by the Free Software Foundation.
  11. *
  12. * This program is distributed in the hope it will be useful, but WITHOUT
  13. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  14. * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  15. * more details.
  16. */
  17. #ifndef LINUX_OPAL_H
  18. #define LINUX_OPAL_H
  19. #include <uapi/linux/sed-opal.h>
  20. #include <linux/kernel.h>
  21. /*
  22. * These constant values come from:
  23. * SPC-4 section
  24. * 6.30 SECURITY PROTOCOL IN command / table 265.
  25. */
  26. enum {
  27. TCG_SECP_00 = 0,
  28. TCG_SECP_01,
  29. };
  30. struct opal_dev;
  31. #define IO_BUFFER_LENGTH 2048
  32. #define MAX_TOKS 64
  33. typedef int (*opal_step)(struct opal_dev *dev);
  34. typedef int (sec_send_recv)(struct opal_dev *ctx, u16 spsp, u8 secp,
  35. void *buffer, size_t len, bool send);
  36. enum opal_atom_width {
  37. OPAL_WIDTH_TINY,
  38. OPAL_WIDTH_SHORT,
  39. OPAL_WIDTH_MEDIUM,
  40. OPAL_WIDTH_LONG,
  41. OPAL_WIDTH_TOKEN
  42. };
  43. /*
  44. * Token defs derived from:
  45. * TCG_Storage_Architecture_Core_Spec_v2.01_r1.00
  46. * 3.2.2 Data Stream Encoding
  47. */
  48. enum opal_response_token {
  49. OPAL_DTA_TOKENID_BYTESTRING = 0xe0,
  50. OPAL_DTA_TOKENID_SINT = 0xe1,
  51. OPAL_DTA_TOKENID_UINT = 0xe2,
  52. OPAL_DTA_TOKENID_TOKEN = 0xe3, /* actual token is returned */
  53. OPAL_DTA_TOKENID_INVALID = 0X0
  54. };
  55. /*
  56. * On the parsed response, we don't store again the toks that are already
  57. * stored in the response buffer. Instead, for each token, we just store a
  58. * pointer to the position in the buffer where the token starts, and the size
  59. * of the token in bytes.
  60. */
  61. struct opal_resp_tok {
  62. const u8 *pos;
  63. size_t len;
  64. enum opal_response_token type;
  65. enum opal_atom_width width;
  66. union {
  67. u64 u;
  68. s64 s;
  69. } stored;
  70. };
  71. /*
  72. * From the response header it's not possible to know how many tokens there are
  73. * on the payload. So we hardcode that the maximum will be MAX_TOKS, and later
  74. * if we start dealing with messages that have more than that, we can increase
  75. * this number. This is done to avoid having to make two passes through the
  76. * response, the first one counting how many tokens we have and the second one
  77. * actually storing the positions.
  78. */
  79. struct parsed_resp {
  80. int num;
  81. struct opal_resp_tok toks[MAX_TOKS];
  82. };
  83. /**
  84. * struct opal_dev - The structure representing a OPAL enabled SED.
  85. * @supported: Whether or not OPAL is supported on this controller.
  86. * @send_recv: The combined sec_send/sec_recv function pointer.
  87. * @opal_step: A series of opal methods that are necessary to complete a command.
  88. * @func_data: An array of parameters for the opal methods above.
  89. * @state: Describes the current opal_step we're working on.
  90. * @dev_lock: Locks the entire opal_dev structure.
  91. * @parsed: Parsed response from controller.
  92. * @prev_data: Data returned from a method to the controller.
  93. * @unlk_lst: A list of Locking ranges to unlock on this device during a resume.
  94. */
  95. struct opal_dev {
  96. bool initialized;
  97. bool supported;
  98. sec_send_recv *send_recv;
  99. const opal_step *funcs;
  100. void **func_data;
  101. int state;
  102. struct mutex dev_lock;
  103. u16 comid;
  104. u32 hsn;
  105. u32 tsn;
  106. u64 align;
  107. u64 lowest_lba;
  108. size_t pos;
  109. u8 cmd[IO_BUFFER_LENGTH];
  110. u8 resp[IO_BUFFER_LENGTH];
  111. struct parsed_resp parsed;
  112. size_t prev_d_len;
  113. void *prev_data;
  114. struct list_head unlk_lst;
  115. };
  116. #ifdef CONFIG_BLK_SED_OPAL
  117. bool opal_unlock_from_suspend(struct opal_dev *dev);
  118. void init_opal_dev(struct opal_dev *opal_dev, sec_send_recv *send_recv);
  119. int sed_ioctl(struct opal_dev *dev, unsigned int cmd, void __user *ioctl_ptr);
  120. static inline bool is_sed_ioctl(unsigned int cmd)
  121. {
  122. switch (cmd) {
  123. case IOC_OPAL_SAVE:
  124. case IOC_OPAL_LOCK_UNLOCK:
  125. case IOC_OPAL_TAKE_OWNERSHIP:
  126. case IOC_OPAL_ACTIVATE_LSP:
  127. case IOC_OPAL_SET_PW:
  128. case IOC_OPAL_ACTIVATE_USR:
  129. case IOC_OPAL_REVERT_TPR:
  130. case IOC_OPAL_LR_SETUP:
  131. case IOC_OPAL_ADD_USR_TO_LR:
  132. case IOC_OPAL_ENABLE_DISABLE_MBR:
  133. case IOC_OPAL_ERASE_LR:
  134. case IOC_OPAL_SECURE_ERASE_LR:
  135. return true;
  136. }
  137. return false;
  138. }
  139. #else
  140. static inline bool is_sed_ioctl(unsigned int cmd)
  141. {
  142. return false;
  143. }
  144. static inline int sed_ioctl(struct opal_dev *dev, unsigned int cmd,
  145. void __user *ioctl_ptr)
  146. {
  147. return 0;
  148. }
  149. static inline bool opal_unlock_from_suspend(struct opal_dev *dev)
  150. {
  151. return false;
  152. }
  153. static inline void init_opal_dev(struct opal_dev *opal_dev,
  154. sec_send_recv *send_recv)
  155. {
  156. opal_dev->supported = false;
  157. opal_dev->initialized = true;
  158. }
  159. #endif /* CONFIG_BLK_SED_OPAL */
  160. #endif /* LINUX_OPAL_H */