nvme/opal: use asynchronous security send/receive transport APIs
opal_send_recv() is a wrapper implementation to use the asynchronous security send/receive APIs, it can be used in a session context, but from the view of one session, the opal_send_recv() is still executed synchronously, but if the drive can support more than one session, opal_send_recv() can be called from different sessions or threads. Change-Id: I3a4b2ec14cb7706c39565a6b4fb8a3a4862f3d4c Signed-off-by: Changpeng Liu <changpeng.liu@intel.com> Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/1670 Tested-by: SPDK CI Jenkins <sys_sgci@intel.com> Community-CI: Broadcom CI Reviewed-by: Jim Harris <james.r.harris@intel.com> Reviewed-by: Ben Walker <benjamin.walker@intel.com>
This commit is contained in:
parent
71327bfef8
commit
e51a2aaf3f
@ -37,40 +37,71 @@
|
|||||||
|
|
||||||
#include "nvme_opal_internal.h"
|
#include "nvme_opal_internal.h"
|
||||||
|
|
||||||
static int
|
static void
|
||||||
opal_security_send(struct spdk_opal_dev *dev, struct opal_session *sess)
|
opal_nvme_security_recv_done(void *arg, const struct spdk_nvme_cpl *cpl)
|
||||||
{
|
{
|
||||||
return spdk_nvme_ctrlr_security_send(dev->ctrlr, SPDK_SCSI_SECP_TCG, dev->comid,
|
struct opal_session *sess = arg;
|
||||||
0, sess->cmd, IO_BUFFER_LENGTH);
|
struct spdk_opal_dev *dev = sess->dev;
|
||||||
|
void *response = sess->resp;
|
||||||
|
struct spdk_opal_compacket *header = response;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (spdk_nvme_cpl_is_error(cpl)) {
|
||||||
|
sess->sess_cb(sess, -EIO, sess->cb_arg);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!header->outstanding_data && !header->min_transfer) {
|
||||||
|
sess->sess_cb(sess, 0, sess->cb_arg);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(response, 0, IO_BUFFER_LENGTH);
|
||||||
|
ret = spdk_nvme_ctrlr_cmd_security_receive(dev->ctrlr, SPDK_SCSI_SECP_TCG,
|
||||||
|
dev->comid, 0, sess->resp, IO_BUFFER_LENGTH,
|
||||||
|
opal_nvme_security_recv_done, sess);
|
||||||
|
if (ret) {
|
||||||
|
sess->sess_cb(sess, ret, sess->cb_arg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
opal_nvme_security_send_done(void *arg, const struct spdk_nvme_cpl *cpl)
|
||||||
|
{
|
||||||
|
struct opal_session *sess = arg;
|
||||||
|
struct spdk_opal_dev *dev = sess->dev;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (spdk_nvme_cpl_is_error(cpl)) {
|
||||||
|
sess->sess_cb(sess, -EIO, sess->cb_arg);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = spdk_nvme_ctrlr_cmd_security_receive(dev->ctrlr, SPDK_SCSI_SECP_TCG,
|
||||||
|
dev->comid, 0, sess->resp, IO_BUFFER_LENGTH,
|
||||||
|
opal_nvme_security_recv_done, sess);
|
||||||
|
if (ret) {
|
||||||
|
sess->sess_cb(sess, ret, sess->cb_arg);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
opal_security_recv(struct spdk_opal_dev *dev, struct opal_session *sess)
|
opal_nvme_security_send(struct spdk_opal_dev *dev, struct opal_session *sess,
|
||||||
|
opal_sess_cb sess_cb, void *cb_arg)
|
||||||
{
|
{
|
||||||
void *response = sess->resp;
|
sess->sess_cb = sess_cb;
|
||||||
struct spdk_opal_compacket *header = response;
|
sess->cb_arg = cb_arg;
|
||||||
int ret = 0;
|
|
||||||
|
|
||||||
do {
|
return spdk_nvme_ctrlr_cmd_security_send(dev->ctrlr, SPDK_SCSI_SECP_TCG, dev->comid,
|
||||||
memset(response, 0, IO_BUFFER_LENGTH);
|
0, sess->cmd, IO_BUFFER_LENGTH,
|
||||||
ret = spdk_nvme_ctrlr_security_receive(dev->ctrlr, SPDK_SCSI_SECP_TCG, dev->comid,
|
opal_nvme_security_send_done, sess);
|
||||||
0, sess->resp, IO_BUFFER_LENGTH);
|
}
|
||||||
if (ret) {
|
|
||||||
SPDK_ERRLOG("Security Receive Error on dev = %p\n", dev);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
SPDK_DEBUGLOG(SPDK_LOG_OPAL, "outstanding_data=%d, minTransfer=%d\n",
|
|
||||||
header->outstanding_data,
|
|
||||||
header->min_transfer);
|
|
||||||
|
|
||||||
if (header->outstanding_data == 0 &&
|
static void
|
||||||
header->min_transfer == 0) {
|
opal_send_recv_done(struct opal_session *sess, int status, void *ctx)
|
||||||
/* return if all the response data are ready by tper and received by host */
|
{
|
||||||
return 0;
|
sess->status = status;
|
||||||
}
|
sess->done = true;
|
||||||
} while (true);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@ -78,12 +109,31 @@ opal_send_recv(struct spdk_opal_dev *dev, struct opal_session *sess)
|
|||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = opal_security_send(dev, sess);
|
sess->done = false;
|
||||||
|
ret = opal_nvme_security_send(dev, sess, opal_send_recv_done, NULL);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
return opal_security_recv(dev, sess);
|
while (!sess->done) {
|
||||||
|
spdk_nvme_ctrlr_process_admin_completions(dev->ctrlr);
|
||||||
|
}
|
||||||
|
|
||||||
|
return sess->status;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct opal_session *
|
||||||
|
opal_alloc_session(struct spdk_opal_dev *dev)
|
||||||
|
{
|
||||||
|
struct opal_session *sess;
|
||||||
|
|
||||||
|
sess = calloc(1, sizeof(*sess));
|
||||||
|
if (!sess) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
sess->dev = dev;
|
||||||
|
|
||||||
|
return sess;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -1721,7 +1771,7 @@ spdk_opal_cmd_take_ownership(struct spdk_opal_dev *dev, char *new_passwd)
|
|||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
sess = calloc(1, sizeof(*sess));
|
sess = opal_alloc_session(dev);
|
||||||
if (!sess) {
|
if (!sess) {
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
@ -1748,6 +1798,7 @@ spdk_opal_cmd_take_ownership(struct spdk_opal_dev *dev, char *new_passwd)
|
|||||||
|
|
||||||
/* reuse the session structure */
|
/* reuse the session structure */
|
||||||
memset(sess, 0, sizeof(*sess));
|
memset(sess, 0, sizeof(*sess));
|
||||||
|
sess->dev = dev;
|
||||||
ret = opal_start_generic_session(dev, sess, UID_SID, UID_ADMINSP,
|
ret = opal_start_generic_session(dev, sess, UID_SID, UID_ADMINSP,
|
||||||
opal_key.key, opal_key.key_len);
|
opal_key.key, opal_key.key_len);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
@ -2008,7 +2059,7 @@ spdk_opal_cmd_revert_tper(struct spdk_opal_dev *dev, const char *passwd)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
sess = calloc(1, sizeof(*sess));
|
sess = opal_alloc_session(dev);
|
||||||
if (!sess) {
|
if (!sess) {
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
@ -2062,7 +2113,7 @@ spdk_opal_cmd_activate_locking_sp(struct spdk_opal_dev *dev, const char *passwd)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
sess = calloc(1, sizeof(*sess));
|
sess = opal_alloc_session(dev);
|
||||||
if (!sess) {
|
if (!sess) {
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
@ -2117,7 +2168,7 @@ spdk_opal_cmd_lock_unlock(struct spdk_opal_dev *dev, enum spdk_opal_user user,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
sess = calloc(1, sizeof(*sess));
|
sess = opal_alloc_session(dev);
|
||||||
if (!sess) {
|
if (!sess) {
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
@ -2164,7 +2215,7 @@ spdk_opal_cmd_setup_locking_range(struct spdk_opal_dev *dev, enum spdk_opal_user
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
sess = calloc(1, sizeof(*sess));
|
sess = opal_alloc_session(dev);
|
||||||
if (!sess) {
|
if (!sess) {
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
@ -2214,7 +2265,7 @@ spdk_opal_cmd_get_max_ranges(struct spdk_opal_dev *dev, const char *passwd)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
sess = calloc(1, sizeof(*sess));
|
sess = opal_alloc_session(dev);
|
||||||
if (!sess) {
|
if (!sess) {
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
@ -2262,7 +2313,7 @@ spdk_opal_cmd_get_locking_range_info(struct spdk_opal_dev *dev, const char *pass
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
sess = calloc(1, sizeof(*sess));
|
sess = opal_alloc_session(dev);
|
||||||
if (!sess) {
|
if (!sess) {
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
@ -2308,7 +2359,7 @@ spdk_opal_cmd_enable_user(struct spdk_opal_dev *dev, enum spdk_opal_user user_id
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
sess = calloc(1, sizeof(*sess));
|
sess = opal_alloc_session(dev);
|
||||||
if (!sess) {
|
if (!sess) {
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
@ -2356,7 +2407,7 @@ spdk_opal_cmd_add_user_to_locking_range(struct spdk_opal_dev *dev, enum spdk_opa
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
sess = calloc(1, sizeof(*sess));
|
sess = opal_alloc_session(dev);
|
||||||
if (!sess) {
|
if (!sess) {
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
@ -2409,7 +2460,7 @@ spdk_opal_cmd_set_new_passwd(struct spdk_opal_dev *dev, enum spdk_opal_user user
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
sess = calloc(1, sizeof(*sess));
|
sess = opal_alloc_session(dev);
|
||||||
if (!sess) {
|
if (!sess) {
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
@ -2456,7 +2507,7 @@ spdk_opal_cmd_erase_locking_range(struct spdk_opal_dev *dev, enum spdk_opal_user
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
sess = calloc(1, sizeof(*sess));
|
sess = opal_alloc_session(dev);
|
||||||
if (!sess) {
|
if (!sess) {
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
@ -2508,7 +2559,7 @@ spdk_opal_cmd_secure_erase_locking_range(struct spdk_opal_dev *dev, enum spdk_op
|
|||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
sess = calloc(1, sizeof(*sess));
|
sess = opal_alloc_session(dev);
|
||||||
if (!sess) {
|
if (!sess) {
|
||||||
free(active_key);
|
free(active_key);
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
@ -238,6 +238,11 @@ struct spdk_opal_header {
|
|||||||
struct spdk_opal_data_subpacket sub_packet;
|
struct spdk_opal_data_subpacket sub_packet;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct opal_session;
|
||||||
|
struct spdk_opal_dev;
|
||||||
|
|
||||||
|
typedef void (*opal_sess_cb)(struct opal_session *sess, int status, void *ctx);
|
||||||
|
|
||||||
struct opal_session {
|
struct opal_session {
|
||||||
uint32_t hsn;
|
uint32_t hsn;
|
||||||
uint32_t tsn;
|
uint32_t tsn;
|
||||||
@ -245,6 +250,12 @@ struct opal_session {
|
|||||||
uint8_t cmd[IO_BUFFER_LENGTH];
|
uint8_t cmd[IO_BUFFER_LENGTH];
|
||||||
uint8_t resp[IO_BUFFER_LENGTH];
|
uint8_t resp[IO_BUFFER_LENGTH];
|
||||||
struct spdk_opal_resp_parsed parsed_resp;
|
struct spdk_opal_resp_parsed parsed_resp;
|
||||||
|
|
||||||
|
opal_sess_cb sess_cb;
|
||||||
|
void *cb_arg;
|
||||||
|
bool done;
|
||||||
|
int status;
|
||||||
|
struct spdk_opal_dev *dev;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct spdk_opal_dev {
|
struct spdk_opal_dev {
|
||||||
|
Loading…
Reference in New Issue
Block a user