Hi to all, because it's my first post here.
This is about how to use binary Seagate terminal - ESLIP
I couldnt' find any info about using ESLIP, so I made my own research, using error and trial... I hope some of you will find it interesting.
---------------------------------------------------------------
ESLIP is binary terminal of Seagate - in contrary to well-known text-terminal.
ESLIP means "Extended SLIP". SLIP is a very simple net communication protocol,
https://www.rfc-editor.org/rfc/rfc1055.txt. Many features of SLIP were adopted by Seagate, and many others were added.
1. SLIP defines 0xC0 as end-of-packet. Seagate uses "double-ended-SLIP": 0xC0 starts and ends the packet. When 0xC0 is a part of data transferred, it must be replaced with something - otherwise the receiver would think, that this is the end of the transfer. SLIP defines replacing 0xC0 in data with 0xDB,0xDC, and "0xDB" with 0xDB,0xDD. 0xDB is called "escape character" - it "escapes" real 0xC0 and 0xDB in transferred data - these two bytes cant' be used directly during data transfer to avoid confusion. "DB,DC" is called "escaped END" and "DB,DD" is called "escaped ESC". This was fully adopted by ESLIP, so if we read MBR via ESLIP, we can see at the start of sector "FA 33 DB DC" - instead of "FA 33 C0" as in original MBR.
2. Seagate added checksums to ESLIP packets.
ESLIP packet looks as follows:
C0 - [content] - C0 [checksum of content]
This is 8-bit checksum and occupies 2 bytes. So after constructing a packet, we must sum all the bytes between C0s and attach obtained 2 bytes just after second "C0".
All is little-endian in ESLIP - ports, functions, arguments, checksum etc.
3. ESLIP defines ACK and NAK -> ACK=acknowledged=packet accepted, NAK=not acknowledged=packet rejected. "ACK" is "1", "NAK" is "2", so in ESLIP language this take a form of C001C00100 [C0-"1"-C0-checksum of "1"], and C002C00200 [c0-"2"-C0-checksum of "2"].
If we got C002C00200 from disk, this usually means, that checksum of our packet is bad.
If we got C001C001000 from disk, this only means, that a FORMAT of our packet is correct - i.e. the packet has 2 "C0"s and correct checksum after. This doesnt' mean that we called correct function with appropriate parameters - we can brick the drive forever just a second after we got "ACK" from it....
4. ESLIP packet in details looks as follows:
C0-[FromPort(2b)-ToPort(2b)-Length of {}(4b)-{Function(2b)-Revision(2b)-...}]-C0-[checksum of content from C0 to C0]
"Port" value is used to address requests to different groups of firmware functions. SDBP=SeagateDiagnosticBridgeProtocol uses firmware functions, which are accessible via terminal (text and/or binary). These functions are grouped as DETS=Diagnostic External Test Service, DITS=Diagnostic Internal Test Service, SelfTest, etc. To address a request to certain function category, we use ports, i.e. for DETS functions - port 7, DITS functions - port 1, SelfTest functions - port 2 etc.
"External" in DETS means, that most/all of them (I didnt' check) are accessible via text-terminal. On contrary, DITS are "internal", so functions like SetFactoryProcess or InduceSelfTestError are not accessible via text-terminal, but are accessible via binary-terminal = ESLIP.
The second part of ESLIP packet i.e. bytes after "Length", starting from "Function" and "Revision":
1) is called DFB=DiagnosticFunctionBlock, when packet is sent to drive
2) is called DSB=DiagnosticStatusBlock, when packet is received from drive. DITS functions dont' use DSB - they have output described as "[function}_ret_value".
So we send DFB and we receive DSB for DETS/ret_value for DITS.
Formats of DFB,DSB,[function]_ret are usually function-specific.
---------------------------------------------------------------
Example: GetActiveStatus
GetActiveStatus is DETS function nr 6. It's called when we request "DisplayActiveStatus" in text-terminal by pressing [dot]. Uses no arguments.
Lets' seek to CHS 567/1 (binary output will be easier understandable), request DisplayActiveStatus output in text-terminal and then switch to ESLIP mode and call GetActiveStatus in this mode:
F3 T>/2s567,1,22 -> Target User LBA 000000D451CC LLL CHS 000567.1.0000 PLP CHS 000567.1.0000
F3 2>. -> Current R/W User LBA 000000D451CC LLL CHS 000567.1.0000 PLP CHS 000567.1.0000 R/W Status 1 R/W Error 00000080 Ready
[Ctrl-T]
ESLIP mode
Now we send:
TX: C0 0700 0700 04000000 0600 0100 C0 1900
That's:
C0-[FromPort=7,ToPort=7,Length=4,{Function=6=GetActiveStatus,Revision=1}]-C0-[checksum 7+7+4+6+1=19]
Checksum [] is calculated from C0 to C0. Length {} is calculated from "Length" dword to C0.
We received:
RX: C001C00100
RX: C0 0700 0700 2C00 0000 0C00 0200 00000000 00010000 01000000 80000000 00 000000 CC51D400 67050000 01 00 0000 67050000 01 F4 0000 C0 8904
This is:
C001C00100 = ACK=packet accepted
C0 0700 0700 2C00 0000 = FromPort=7,ToPort=7,Length=2C
0C00 0200 00000000 00010000 01000000 80000000 00 000000 CC51D400 67050000 01 00 0000 67050000 01 F4 0000 = ActiveStatus:DataTypeId-Revision-ErrorCode(dword)-Ready(dword)-RWSenseStatus(dword)-RWErrorCode(dword)-SystemAccess(byte)-rsvd(3b)-LBA(dword)-LLL CHS: Cyl(dword)-Head(byte)-rsvd(byte)-Sect(word); PLP CHS:Cyl(dword)-Head(byte)-rsvd(byte)-Sect(word)
C0 = end of packet
8904 = checksum
-------------------------------------------------------------------------------------------------
Example: SpinDown using DITS function 157
We will use DITS function 157. Of course, we could use DETS function 1B or send 2>Z in text-terminal, but this example is not to spin-down, but to show how to use DITS functions
DITS function 157 is called "SpinupSpindown", and SpinUpFlag decides, which operation is to be performed; 0=spin-down, 1=spin-up
The packet should look as follows:
C0 0100 0100 06000000 5701 0100 0000 C0 6100
[FromPort=1=DITS, ToPort=1=DITS, Length=6, Function=157, Revision=1, SpinUpFlag=0, checksum=61]
DITS functions are kind of super-commands, and (like in disks of other manufacturers) we can get access to them only after proper autorization. In Seagate, this is made by calling "unlock" to port 1:
C0 0100 0100 08000000 FFFF 0100 9A324F03 C0 2703
[FromPort=1=DITS, ToPort=1=DITS, Length=8, Function=FFFF, Revision=1, KEY=034F329A, checksum=327]
KEY is little-endian as all in ESLIP
I attached a listing showing all this
We start the disk, and we are by default in ESLIP mode, so commands can be send without any "Ctrl-T".
[boot]
TX:C0 0100 0100 06000000 5701 0100 0000 C06100 [SpinDown]
RX:C001C00100 [ACK]
RX:C0 0100 0100 10000000 72052C00000000080302000380020000 C04701 [SCSI error]
TX:C0 0100 0100 06000000 5701 0100 0000 C06100 [SpinDown]
RX:C002C00200 [NAK]
TX:C0 0100 0100 06000000 5701 0100 0000 C06100 [SpinDown]
RX:C002C00200 [NAK]
TX:C0C0C0C0 [ESLIP reset]
TX:C0 0100 0100 06000000 5701 0100 0000 C06100 [SpinDown]
RX:C002C00200 [NAK]
TX:C0 0100 0100 08000000 FFFF 0100 9A324F03 C02703 [Unlock DITS]
RX:C002C00200 [NAK]
TX:C0 0100 0100 08000000 FFFF 0100 9A324F03 C02703 [Unlock DITS]
RX:C002C00200 [NAK]
TX:1A [Ctrl-Z]
RX:0D 0A 41 53 43 49 49 20 44 69 61 67 20 6D 6F 64 65 0D 0A [ASCII Diag mode]
RX:0D 0A 46 33 20 54 3E [F3 T>]
TX:14 [Ctrl-T]
RX:0D 0A 45 53 4C 49 50 20 6D 6F 64 65 0D 0A [ESLIP mode]
TX:C0 0100 0100 08000000 FFFF 0100 9A324F03 C02703 [Unlock DITS]
RX:C001C00100 [ACK]
RX:C0 0100 0100 10000000 72000000000000080302000080020000 C01301 [SCSI OK]
TX:C0 0100 0100 06000000 5701 0100 0000 C06100 [SpinDown]
RX:C001C00100 [ACK]
RX:C0 0100 0100 10000000 72000000000000080302000080020000 C01301 [SCSI OK]
We start with SpinDown, we get ACK=correct packet, but we get 16b "SCSI-error" packet from disk. This is packet starting with "72". Why it means an error will be explained a minute later. We try to send SpinDown command two more times, but now we get NAK=packet rejected - as if the checksum was bad, but it's OK!!. ESLIP reset with C0C0C0C0 - doesnt' help. We send unlock command - also doesnt' help. So we restart the terminal - switch with Ctrl-Z to text-terminal for a moment and return with Ctrl-T to ESLIP.
Now we send commands in proper order:
1. unlock DITS -> we get ACK and proper 16b packet from disk. We unlocked DITS.
2. SpinDown -> we get ACK and proper 16b packet from disk. After ACK the disk spins down. A few seconds later we see "SCSI OK" packet. We spinned-down the disk with DITS command.
..
And now explanation of "SCSI-packet". This is 16b packet called DiagStatusBlock, most DITS functions uses DiagStatusBlock as its output. It's taken directly from SCSI standards. Most important values are first four:
72 - in SCSI it means "block describes current error and description is included". Seagate uses only "72" value, so it's easy to recognize this 16b packet in output - it starts from "72" and is 16b in length.
Three next bytes are:"SenseKey", "SenseCode", "SenseCodeQualifier", they give detailed description of an error, and there is no secret in it:
https://en.wikipedia.org/wiki/Key_Code_QualifierIn Seagate docs we can read, that their codes are not "exactly" as SCSIs, but... they are enough to understand meaning of the output.
If we got 72,0,0,0 -> command was successful
If we got 72, anything other -> there was an error specified in SCSI standards.
For example, we got "72 05 2C 00" after first SpinDown attempt.
This means: 5=Illegal Request,2C00=command sequence error. We didnt' unlock DITS before calling it.
-------------------------------------------------------------------------------------------------
Example: ReadPhysicalSector using DITS function 135: reads 3 sectors from CHS 0/0/0
TX:C0 0100 0100 08000000 FFFF 0100 9A324F03 C02703 [Unlock DITS]
RX:C001C00100 [ACK]
RX:C0 0100 0100 10000000 72000000000000080302000080020000 C01301 [SCSI OK]
TX:C0 0100 0100 18000000 3501 0100 00000000 03000000 0000 00 000000000000000000 C05400
If someone is interested - details in next post, because it is a long story