Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
dCache
cta
Commits
19d06ead
Commit
19d06ead
authored
Jul 31, 2013
by
Eric Cano
Browse files
Slight code cleanup.
Added senseData structure, which is polymorphic, and added unit test.
parent
d2b7d4bf
Changes
3
Hide whitespace changes
Inline
Side-by-side
Drive/Drive.hh
View file @
19d06ead
...
...
@@ -146,7 +146,8 @@ namespace Tape {
std
::
vector
<
std
::
string
>
ret
;
/* We don't know how many elements we'll get. Prepare a 100 parameters array */
SCSI
::
Structures
::
tapeAlertLogPage_t
<
100
>
tal
;
unsigned
char
senseBuff
[
255
];
/* Prepare a sense buffer of 255 bytes */
SCSI
::
Structures
::
senseData_t
<
255
>
senseBuff
;
SCSI
::
Structures
::
logSenseCDB_t
cdb
;
cdb
.
pageCode
=
SCSI
::
logSensePages
::
tapeAlert
;
SCSI
::
Structures
::
LinuxSGIO_t
sgh
;
...
...
SCSI/Structures.hh
View file @
19d06ead
...
...
@@ -122,6 +122,7 @@ namespace SCSI {
*/
class
inquiryCDB_t
{
public:
inquiryCDB_t
()
{
zeroStruct
(
this
);
opCode
=
SCSI
::
Commands
::
INQUIRY
;
}
unsigned
char
opCode
;
unsigned
char
EVPD
:
1
;
...
...
@@ -132,13 +133,14 @@ namespace SCSI {
char
allocationLength
[
2
];
unsigned
char
control
;
inquiryCDB_t
()
{
zeroStruct
(
this
);
opCode
=
SCSI
::
Commands
::
INQUIRY
;
}
};
/**
* Inquiry data as described in SPC-4.
*/
typedef
struct
{
class
inquiryData_t
{
public:
inquiryData_t
()
{
zeroStruct
(
this
);
}
unsigned
char
perifDevType
:
5
;
unsigned
char
perifQualifyer
:
3
;
...
...
@@ -191,13 +193,17 @@ namespace SCSI {
unsigned
char
reserved2
[
22
];
unsigned
char
vendorSpecific2
[
1
];
}
inquiryData_t
;
};
/*
* LOG SELECT CDB as described in SPC-4.
*/
class
logSelectCDB_t
{
public:
logSelectCDB_t
()
{
zeroStruct
(
this
);
opCode
=
SCSI
::
Commands
::
LOG_SELECT
;
}
// byte 0
unsigned
char
opCode
;
// OPERATION CODE (4Ch)
...
...
@@ -220,12 +226,7 @@ namespace SCSI {
unsigned
char
parameterListLength
[
2
];
// PARAMETER LIST LENGTH
// byte 9
unsigned
char
control
;
// CONTROL
logSelectCDB_t
()
{
zeroStruct
(
this
);
opCode
=
SCSI
::
Commands
::
LOG_SELECT
;
}
unsigned
char
control
;
// CONTROL
};
/**
...
...
@@ -233,6 +234,7 @@ namespace SCSI {
*/
class
logSenseCDB_t
{
public:
logSenseCDB_t
()
{
zeroStruct
(
this
);
opCode
=
SCSI
::
Commands
::
LOG_SENSE
;
}
unsigned
char
opCode
;
unsigned
char
SP
:
1
;
...
...
@@ -251,10 +253,8 @@ namespace SCSI {
unsigned
char
allocationLength
[
2
];
unsigned
char
control
;
logSenseCDB_t
()
{
zeroStruct
(
this
);
opCode
=
SCSI
::
Commands
::
LOG_SENSE
;
}
};
/**
* Log sense Log Page Parameter Format as described in SPC-4,
*/
...
...
@@ -313,7 +313,11 @@ namespace SCSI {
};
/**
* Part of a tape alert log page.
* This structure does not need to be initialized, as the containing structure
* (tapeAlertLogPage_t) will do it while initializing itself.
*/
class
tapeAlertLogParameter_t
{
public:
unsigned
char
parameterCode
[
2
];
...
...
@@ -337,6 +341,7 @@ namespace SCSI {
template
<
int
n
>
class
tapeAlertLogPage_t
{
public:
tapeAlertLogPage_t
()
{
zeroStruct
(
this
);
}
unsigned
char
pageCode
:
6
;
unsigned
char
:
2
;
...
...
@@ -355,7 +360,118 @@ namespace SCSI {
int
numFromLength
=
SCSI
::
Structures
::
toU16
(
pageLength
)
/
sizeof
(
tapeAlertLogParameter_t
);
return
numFromLength
;
}
tapeAlertLogPage_t
()
{
zeroStruct
(
this
);
}
};
/**
* Sense buffer as defined in SPC-4,
* section 4.5.2 Descriptor format sense data and
* section 4.5.3 Fixed format sense data
* The sense buffer size is stored in the form of
* a single byte. Therefore, the constructor forbids
* creation of a senseData_t structure bigger than
* 255 bytes.
* As the structure will be different depending on the response code,
* everything after the first byte is represented by a union, which
* can be any of the 2 forms (fixedFormat/descriptorFormat).
* getXXXXX helper member function allow the getting of on of the other
* version of the common fields.
*/
template
<
int
n
>
class
senseData_t
{
public:
senseData_t
()
{
if
(
sizeof
(
*
this
)
>
255
)
throw
Tape
::
Exception
(
"In SCSI::Structures::senseData_t::senseData_t(): size too big (> 255>"
);
zeroStruct
(
this
);
}
// byte 0
unsigned
char
responseCode
:
7
;
unsigned
char
:
1
;
// Following bytes can take 2 versions:
union
{
struct
{
// byte 1
unsigned
char
senseKey
:
4
;
unsigned
char
:
4
;
// Additional sense code (byte 2))
unsigned
char
ASC
;
// Additional sense code qualifier (byte 3)
unsigned
char
ASCQ
;
// byte 4
unsigned
char
:
7
;
unsigned
char
SDAT_OVFL
:
1
;
// byte 5-6
unsigned
char
reserved
[
2
];
// byte 7
unsigned
char
additionalSenseLength
;
// byte 8 onwards
unsigned
char
additionalSenseBuffer
[
n
-
8
];
}
descriptorFormat
;
struct
{
// byte 1
unsigned
char
obsolete
;
// byte 2
unsigned
char
senseKey
:
4
;
unsigned
char
SDAT_OVFL
:
1
;
unsigned
char
ILI
:
1
;
unsigned
char
EOM
:
1
;
unsigned
char
filemark
:
1
;
// bytes 3-6
unsigned
char
information
[
4
];
// byte 7
unsigned
char
additionalSenseLength
;
// bytes 8 - 11
unsigned
char
commandSpecificInformation
[
4
];
// Additional sense code (byte 12))
unsigned
char
ASC
;
// Additional sense code qualifier (byte 13)
unsigned
char
ASCQ
;
// bytes 14
unsigned
char
fieldReplaceableUnitCode
;
// bytes 15-17
unsigned
char
senseSpecificInformation
[
3
];
// bytes 18 onwards
unsigned
char
aditionalSenseBuffer
[
n
-
18
];
}
fixedFormat
;
// Helper functions for common fields
// First make the difference between the fixed/descriptor
// and current/deffered
};
bool
isFixedFormat
()
{
return
responseCode
==
0x70
||
responseCode
==
0x71
;
}
bool
isDescriptorFormat
()
{
return
responseCode
==
0x72
||
responseCode
==
0x73
;
}
bool
isCurrent
()
{
return
responseCode
==
0x70
||
responseCode
==
0x72
;
}
bool
isDeffered
()
{
return
responseCode
==
0x71
||
responseCode
==
0x73
;
}
uint8_t
getASC
()
{
if
(
isFixedFormat
())
{
return
fixedFormat
.
ASC
;
}
else
if
(
isDescriptorFormat
())
{
return
descriptorFormat
.
ASC
;
}
else
{
throw
Tape
::
Exception
(
"In senseData_t::getASC: no ACS with this response code or response code not supported"
);
}
}
uint8_t
getASCQ
()
{
if
(
isFixedFormat
())
{
return
fixedFormat
.
ASCQ
;
}
else
if
(
isDescriptorFormat
())
{
return
descriptorFormat
.
ASCQ
;
}
else
{
throw
Tape
::
Exception
(
"In senseData_t::getASCQ: no ACSQ with this response code or response code not supported"
);
}
};
};
template
<
size_t
n
>
...
...
SCSI/StructuresTest.cc
View file @
19d06ead
...
...
@@ -249,7 +249,59 @@ namespace UnitTests {
ASSERT_EQ
(
1
,
tal
.
parameters
[
11
].
flag
);
}
TEST
(
SCSI_Structures
,
toto
)
{}
TEST
(
SCSI_Structures
,
senseBuffer_t
)
{
SCSI
::
Structures
::
senseData_t
<
255
>
sense
;
unsigned
char
*
buff
=
(
unsigned
char
*
)
&
sense
;
/* Check the total size of the structure, plus the one of each of the members
of the union */
ASSERT_EQ
(
255
,
sizeof
(
sense
));
ASSERT_EQ
(
255
-
1
,
sizeof
(
sense
.
descriptorFormat
));
ASSERT_EQ
(
255
-
1
,
sizeof
(
sense
.
fixedFormat
));
buff
[
0
]
=
0x70
;
buff
[
12
]
=
0x12
;
buff
[
13
]
=
0x34
;
ASSERT_EQ
(
true
,
sense
.
isCurrent
());
ASSERT_EQ
(
false
,
sense
.
isDeffered
());
ASSERT_EQ
(
true
,
sense
.
isFixedFormat
());
ASSERT_EQ
(
false
,
sense
.
isDescriptorFormat
());
ASSERT_EQ
(
0x12
,
sense
.
getASC
());
ASSERT_EQ
(
0x34
,
sense
.
getASCQ
());
buff
[
0
]
=
0x71
;
buff
[
12
]
=
0x12
;
buff
[
13
]
=
0x34
;
ASSERT_EQ
(
false
,
sense
.
isCurrent
());
ASSERT_EQ
(
true
,
sense
.
isDeffered
());
ASSERT_EQ
(
true
,
sense
.
isFixedFormat
());
ASSERT_EQ
(
false
,
sense
.
isDescriptorFormat
());
ASSERT_EQ
(
0x12
,
sense
.
getASC
());
ASSERT_EQ
(
0x34
,
sense
.
getASCQ
());
buff
[
0
]
=
0x72
;
buff
[
2
]
=
0x56
;
buff
[
3
]
=
0x78
;
ASSERT_EQ
(
true
,
sense
.
isCurrent
());
ASSERT_EQ
(
false
,
sense
.
isDeffered
());
ASSERT_EQ
(
false
,
sense
.
isFixedFormat
());
ASSERT_EQ
(
true
,
sense
.
isDescriptorFormat
());
ASSERT_EQ
(
0x56
,
sense
.
getASC
());
ASSERT_EQ
(
0x78
,
sense
.
getASCQ
());
buff
[
0
]
=
0x73
;
buff
[
2
]
=
0x56
;
buff
[
3
]
=
0x78
;
ASSERT_EQ
(
false
,
sense
.
isCurrent
());
ASSERT_EQ
(
true
,
sense
.
isDeffered
());
ASSERT_EQ
(
false
,
sense
.
isFixedFormat
());
ASSERT_EQ
(
true
,
sense
.
isDescriptorFormat
());
ASSERT_EQ
(
0x56
,
sense
.
getASC
());
ASSERT_EQ
(
0x78
,
sense
.
getASCQ
());
buff
[
0
]
=
0x74
;
ASSERT_THROW
(
sense
.
getASC
(),
Tape
::
Exception
);
}
TEST
(
SCSI_Structures
,
toU16
)
{
unsigned
char
num
[
2
]
=
{
0x1
,
0x2
};
...
...
@@ -260,4 +312,9 @@ namespace UnitTests {
unsigned
char
num
[
4
]
=
{
0x1
,
0x2
,
0x3
,
0x4
};
ASSERT_EQ
(
0x1020304
,
SCSI
::
Structures
::
toU32
(
num
));
}
TEST
(
SCSI_Structures
,
toU64
)
{
unsigned
char
num
[
8
]
=
{
0xDE
,
0xAD
,
0xBE
,
0xEF
,
0xCA
,
0xFE
,
0xFA
,
0xDE
};
ASSERT_EQ
(
0xDEADBEEFCAFEFADEULL
,
SCSI
::
Structures
::
toU64
(
num
));
}
};
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment