Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce Stack Reset #455

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 44 additions & 0 deletions Common/DtaDev.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/* C:B**************************************************************************
This software is Copyright 2014-2017 Bright Plaza Inc. <[email protected]>
This software is Copyright 2023 Nutanix, Inc. <[email protected]>

This file is part of sedutil.

Expand Down Expand Up @@ -300,3 +301,46 @@ void DtaDev::puke()
if (disk_info.Unknown)
cout << "**** " << (uint16_t)disk_info.Unknown << " **** Unknown function codes IGNORED " << std::endl;
}

uint8_t DtaDev::stack_reset(uint32_t ext_com_id) {
uint8_t reset_buffer[MIN_BUFFER_LENGTH + IO_BUFFER_ALIGNMENT];
uint8_t response_buf[MIN_BUFFER_LENGTH + IO_BUFFER_ALIGNMENT];
uint8_t lastRC;
LOG(D1) << "Entering DtaDev::stack_reset()";

memset(reset_buffer, 0, MIN_BUFFER_LENGTH);
reset_buffer[0] = (ext_com_id >> 24) & 0xFF;
reset_buffer[1] = (ext_com_id >> 16) & 0xFF;
reset_buffer[2] = (ext_com_id >> 8) & 0xFF;
reset_buffer[3] = (ext_com_id) & 0xFF;
reset_buffer[7] = 0x02;
if ((lastRC = sendCmd(IF_SEND, 0x02, comID(), reset_buffer, MIN_BUFFER_LENGTH)) != 0) {
LOG(E) << "Reset send with ComID " << HEXON(4) << comID() << " failed!" << HEXOFF << std::endl;
return lastRC;
}
for (uint8_t trials=1; trials<=2;trials++) {
memset(response_buf, 0, MIN_BUFFER_LENGTH);
if ((lastRC = sendCmd(IF_RECV, 0x02, comID(), response_buf, MIN_BUFFER_LENGTH)) != 0) {
LOG(D) << "Receive Reset Status Request to device failed " << (uint16_t)lastRC;
return -1;
}
SSCCommResp *resp = (SSCCommResp *)(response_buf);
resp->decode();
if (resp->type == SSCCommResp::STACK_RESET_PEND_RESP) {
LOG(D) << " DtaDev::stack_reset() Reset is pending. Retry #" << trials;
osmsSleep(25);
} else if (resp->type == SSCCommResp::STACK_RESET_RESP) {
if (resp->structure.reset.status != SSCCommResp::Response::Reset::SUCCESS) {
LOG(E) << "Stack reset failed";
return SWAP32(resp->structure.reset.status);
}
LOG(D) << "DtaDev::stack_reset() Stack Reset is successful";
return 0;
} else {
LOG(E) << "DtaDev::stack_reset() Unrecognized response received";
return -2;
}
}
LOG(E) << "DtaDev::stack_reset() Reset poll timed out";
return -3;
}
7 changes: 7 additions & 0 deletions Common/DtaDev.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/* C:B**************************************************************************
This software is Copyright 2014-2017 Bright Plaza Inc. <[email protected]>
This software is Copyright 2023 Nutanix, Inc. <[email protected]>

This file is part of sedutil.

Expand Down Expand Up @@ -283,6 +284,12 @@ class DtaDev {
virtual uint8_t exec(DtaCommand * cmd, DtaResponse & resp, uint8_t protocol = 0x01) = 0;
/** return the communications ID to be used for sessions to this device */
virtual uint16_t comID() = 0;

/* Reset the stack, without powering cycle the drive. All ongoing or
* in middle sessions are closed. Non committed transactions are lost.
*/
virtual uint8_t stack_reset(uint32_t ext_com_id);

bool no_hash_passwords; /** disables hashing of passwords */
sedutiloutput output_format; /** standard, readable, JSON */
protected:
Expand Down
19 changes: 16 additions & 3 deletions Common/DtaDevEnterprise.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/* C:B**************************************************************************
This software is Copyright 2014-2017 Bright Plaza Inc. <[email protected]>
This software is Copyright 2017 Spectra Logic Corporation
This software is Copyright 2023 Nutanix, Inc. <[email protected]>

This file is part of sedutil.

Expand Down Expand Up @@ -1492,9 +1493,21 @@ uint8_t DtaDevEnterprise::properties()
props->addToken(OPAL_TOKEN::ENDNAME);
props->addToken(OPAL_TOKEN::ENDLIST);
props->complete();
if ((lastRC = session->sendCommand(props, propertiesResponse)) != 0) {
delete props;
return lastRC;
for (uint8_t trial=1; trial<=2; trial++) {
if ((lastRC = session->sendCommand(props, propertiesResponse)) != 0) {
LOG(E) << "Property Exchange Command Failed rc = " << (int)lastRC;
if (trial == 1) {
LOG(D) << "Try to apply stack reset";
if (this->stack_reset(this->comID() << 16) == 0x0000) {
LOG(D) << "Stack Reset Successful";
continue;
}
LOG(E) << "Stack Reset Failed";
delete props;
return lastRC;
}
}
break;
}
disk_info.Properties = 1;
delete props;
Expand Down
19 changes: 16 additions & 3 deletions Common/DtaDevOpal.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/* C:B**************************************************************************
This software is Copyright 2014-2017 Bright Plaza Inc. <[email protected]>
This software is Copyright 2023 Nutanix, Inc. <[email protected]>

This file is part of sedutil.

Expand Down Expand Up @@ -1638,9 +1639,21 @@ uint8_t DtaDevOpal::properties()
props->addToken(OPAL_TOKEN::ENDNAME);
props->addToken(OPAL_TOKEN::ENDLIST);
props->complete();
if ((lastRC = session->sendCommand(props, propertiesResponse)) != 0) {
delete props;
return lastRC;
for (uint8_t trial=1; trial<=2; trial++) {
if ((lastRC = session->sendCommand(props, propertiesResponse)) != 0) {
LOG(E) << "Property Exchange Command Failed rc = " << (int)lastRC;
if (trial == 1) {
LOG(D) << "Try to apply stack reset";
if (this->stack_reset(this->comID() << 16) == 0x0000) {
LOG(D) << "Stack Reset Successful";
continue;
}
LOG(E) << "Stack Reset Failed";
delete props;
return lastRC;
}
}
break;
}
disk_info.Properties = 1;
delete props;
Expand Down
6 changes: 6 additions & 0 deletions Common/DtaLexicon.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/* C:B**************************************************************************
This software is Copyright 2014-2017 Bright Plaza Inc. <[email protected]>
This software is Copyright 2023 Nutanix, Inc. <[email protected]>

This file is part of sedutil.

Expand Down Expand Up @@ -264,3 +265,8 @@ typedef enum _OPALSTATUSCODE {
AUTHORITY_LOCKED_OUT = 0x12,
FAIL = 0x3f,
} OPALSTATUSCODE;

typedef enum _SA_CORE_COMM_LAYER_CMD {
VERIFY_COMID_VALID,
STACK_RESET
} SA_CORE_COMM_LAYER_CMD;
22 changes: 17 additions & 5 deletions Common/DtaSession.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/* C:B**************************************************************************
This software is Copyright 2014-2017 Bright Plaza Inc. <[email protected]>
This software is Copyright 2023 Nutanix, Inc. <[email protected]>

This file is part of sedutil.

Expand Down Expand Up @@ -140,11 +141,22 @@ DtaSession::start(OPAL_UID SP, char * HostChallenge, vector<uint8_t> SignAuthori

cmd->addToken(OPAL_TOKEN::ENDLIST); // ] (Close Bracket)
cmd->complete();
if ((lastRC = sendCommand(cmd, response)) != 0) {
LOG(E) << "Session start failed rc = " << (int)lastRC;
delete cmd;
return lastRC;
}
for (uint8_t trial=1; trial<=2; trial++) {
if ((lastRC = sendCommand(cmd, response)) != 0) {
LOG(E) << "Session start failed rc = " << (int)lastRC;
if (trial == 1) {
LOG(D) << "Try to apply stack reset";
if (d->stack_reset(d->comID() << 16) == 0x0000) {
LOG(D) << "Stack Reset Successful";
continue;
}
LOG(E) << "Stack Reset Failed";
}
delete cmd;
return lastRC;
}
break;
}
// call user method SL HSN TSN EL EOD SL 00 00 00 EL
// 0 1 2 3 4 5 6 7 8
HSN = SWAP32(response.getUint32(4));
Expand Down
94 changes: 93 additions & 1 deletion Common/DtaStructures.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/* C:B**************************************************************************
This software is Copyright 2014-2017 Bright Plaza Inc. <[email protected]>
This software is Copyright 2023 Nutanix, Inc. <[email protected]>

This file is part of sedutil.

Expand Down Expand Up @@ -264,6 +265,97 @@ typedef struct _OPALHeader {
OPALPacket pkt;
OPALDataSubPacket subpkt;
} OPALHeader;

/** Comm Layer Commands */

/** Comm Layer Response Header
* se Header */
typedef struct _SSCCommRespHdr {
uint32_t extendedComID;
uint32_t requestCode;
uint16_t reserved0;
uint16_t length;
} SSCCommRespHdr;

typedef struct _SSCDateVal {
uint8_t year[2];
uint8_t month;
uint8_t day;
uint8_t hour;
uint8_t minute;
uint8_t second;
uint8_t fraction[2];
uint8_t reserved;

uint16_t get_year() {
return (year[1] | (year[0] << 8));
}
uint16_t get_fraction() {
return (fraction[1] | (fraction[0] << 8));
}
} SSCDateVal;

typedef struct _SSCCommResp {
union Response {
struct {
SSCCommRespHdr hdr;
} no_resp;
struct VerifyComIDValid {
SSCCommRespHdr hdr;
enum uint32_t {
INVALID = 0x00000000,
INACTIVE = 0x01000000,
ISSUED = 0x02000000,
ASSOCIATED = 0x03000000
} state;
SSCDateVal allocation_time;
SSCDateVal expiry_time;
SSCDateVal since_last_reset_time;
} verify_comid_valid;
struct Reset {
SSCCommRespHdr hdr;
enum uint32_t {
SUCCESS = 0x00000000,
FAILURE = 0x01000000
} status;
} reset;
struct {
SSCCommRespHdr hdr;
} reset_pending;
struct {
uint8_t data[512];
} raw;
} structure;
enum {NO_RESP, VERIFY_COMID_RESP, STACK_RESET_RESP, STACK_RESET_PEND_RESP, UNKNOWN } type;
uint16_t length;

void decode() {
length = ((structure.no_resp.hdr.length & 0xFF) << 8) | ((structure.no_resp.hdr.length >> 8) & 0xFF);
switch (structure.no_resp.hdr.requestCode) {
case 0x01000000 : {
if (structure.no_resp.hdr.length == 0)
type = NO_RESP;
else if (length == 0x22)
type = VERIFY_COMID_RESP;
else type = UNKNOWN;
};
break;
case 0x02000000 : {
if (structure.reset_pending.hdr.length == 0)
type = STACK_RESET_PEND_RESP;
else if (length == 0x4)
type = STACK_RESET_RESP;
else type = UNKNOWN;
};
break;
default: {
type = UNKNOWN;
}
break;
}
}
} SSCCommResp;

/** ATA commands needed for TCG storage communication */
typedef enum _ATACOMMAND {
IF_RECV = 0x5c,
Expand Down Expand Up @@ -466,4 +558,4 @@ class CScsiCmdSecurityProtocolOut
uint8_t m_Control; // 11
}; // 12

#pragma pack(pop)
#pragma pack(pop)