1 //
2 // Copyright (c) 2010-2018 Antmicro
3 // Copyright (c) 2011-2015 Realtime Embedded
4 //
5 // This file is licensed under the MIT License.
6 // Full license text is available in 'licenses/MIT.txt'.
7 //
8 using System;
9 using Antmicro.Renode.Logging;
10 using Antmicro.Renode.Utilities;
11 
12 namespace Antmicro.Renode.Peripherals.USBDeprecated
13 {
14     public class SCSI
15     {
SCSI()16         public SCSI ()
17         {
18         }
19 
20         public class CommandDescriptorBlock
21         {
22             public byte Size;
23             public byte OperationCode;
24             public byte MiscCDBInformation1;
25             public uint LogicalBlockAddress;
26             public byte MiscCDBInformation2;
27             public byte ServiceAction;
28 
29             public uint TransferLength;
30             public uint ParameterListLength;
31             public uint AllocationLength;
32             public byte Control;
33 
34             public enum GroupCode:byte
35             {
36                 TestUnitReady = 0x00,
37 		RequestSense = 0x03,
38                 Inquiry = 0x12,
39                 ReadCapacity = 0x25,
40                 ModeSense = 0x1A,
41                 PreventAllowMediumRemoval = 0x1E,
42                 Read10 = 0x28,
43                 Write10 = 0x2A
44             }
45 
Fill(byte[] data)46             public void Fill(byte[] data)
47             {
48                 this.Size = (byte)data.Length;
49                 this.OperationCode = data[0];
50                 this.MiscCDBInformation1 = (byte)((data[1] & 0xE0u) >> 5);
51                 if(this.Size == 6)
52                 {
53                     this.LogicalBlockAddress = (uint)((uint)((data[1] & 0x1fu) << 16) | (uint)(data[2] << 8) | data[3]);
54                     this.TransferLength = data[4];
55                     this.AllocationLength = data[4];
56                     this.ParameterListLength = data[4];
57                     this.Control = data[5];
58                 }
59                 else
60                 if(this.Size == 10)
61                 {
62                     this.ServiceAction = (byte)(data[1] & 0xE0u);
63                     this.LogicalBlockAddress = (uint)(data[2] << 24 | data[3] << 16 | data[4] << 8 | data[5]);
64                     this.MiscCDBInformation2 = data[6];
65                     this.TransferLength = (uint)((data[7] << 8) | data[8]);
66                     this.AllocationLength = this.TransferLength;
67                     this.ParameterListLength = this.TransferLength;
68                     this.Control = data[9];
69                 }
70                 else
71                 if(this.Size == 12)
72                 {
73                     this.ServiceAction = (byte)(data[1] & 0xE0u);
74                     this.LogicalBlockAddress = (uint)(data[2] << 24 | data[3] << 16 | data[4] << 8 | data[5]);
75                     this.TransferLength = (uint)(data[6] << 24 | data[7] << 16 | data[8] << 8 | data[9]);
76                     this.AllocationLength = this.TransferLength;
77                     this.ParameterListLength = this.TransferLength;
78                     this.MiscCDBInformation2 = data[10];
79                     this.Control = data[11];
80                 }
81                 else
82                 {
83                     Logger.LogAs(this, LogLevel.Warning, "Unsupported Command Descriptor Block Length");
84                 }
85 
86             }
87        }
88 
89        public class StandardInquiryData
90         {
91             public byte PeripheralQualifier;
92             public byte PeripheralDeviceType;
93             public bool RMB;
94             public byte Version;
95             public bool NormalACASupport;
96             public bool HierachicalSupport;
97             public byte ResponseDataFormat;
98             public byte AdditionalLength;
99             public bool SCCSupport;
100             public bool AccessControlsCoordintor;
101             public byte TargetPortGroupSupport;
102             public bool ThirdPartyCopy;
103             public bool Protect;
104             public bool BasingQueuing;
105             public bool EnclosureServices;
106             public bool VS1;
107             public bool MultiPort;
108             public bool MediumChanger;
109             public bool ADDR16;
110             public bool WBUS16a;
111             public bool Sync;
112             public bool LinkedCommand;
113             public bool CommandQueuing;
114             public bool VS2;
115             public byte[] VendorIdentificationT10 = new byte[8];
116             public byte[] ProductIdentification = new byte[16];
117             public byte[] ProductRevisionLevel = new byte[4];
118 
FillVendor(string vendorStr)119             public void FillVendor(string vendorStr)
120             {
121                 for(int i=0;i<8;i++)
122                 {
123                     this.VendorIdentificationT10[i] = (byte)vendorStr[i];
124                 }
125             }
126 
FillIdentification(string identStr)127             public void FillIdentification(string identStr)
128             {
129                 for(int i=0;i<16;i++)
130                 {
131                     this.ProductIdentification[i] = (byte)identStr[i];
132                 }
133             }
134 
FillRevision(string revisionStr)135             public void FillRevision(string revisionStr)
136             {
137                 for(int i=0;i<4;i++)
138                 {
139                     this.ProductRevisionLevel[i] = (byte)revisionStr[i];
140                 }
141             }
142 
ToArray()143             public byte[] ToArray()
144             {
145                 arr[0] = (byte)(((this.PeripheralQualifier & 0x07)<<5) | (byte)(this.PeripheralDeviceType & 0x1fu));
146                 arr[1] = this.RMB ? (byte) (1u<<7): (byte) 0;
147                 arr[2] = this.Version;
148                 arr[3] = (byte)((this.NormalACASupport ? (byte) (1u<<5) : (byte) 0u) | (this.HierachicalSupport ? (byte) (1u<<4) : (byte) 0u) | (byte)(this.ResponseDataFormat & 0x0fu));
149                 arr[4] = this.AdditionalLength;
150                 arr[5] = (byte)( (byte)(this.SCCSupport ? 1u<<7 : 0u) | (byte)(this.AccessControlsCoordintor ? 1u<<6 : 0u) | (byte)((this.TargetPortGroupSupport & 0x03u) << 4));
151                 arr[5]|= (byte)( (byte)(this.ThirdPartyCopy ? 1u<<3 : 0u) | (byte)(this.Protect ? 1u<<0 : 0u) );
152                 arr[6] = (byte)( (byte)(this.BasingQueuing ? 1u<<7 : 0u) | (byte)(this.EnclosureServices ? 1u<<6 : 0u) | (byte)(this.VS1 ? 1u<<5 : 0u) | (byte)(this.MultiPort ? 1u<<7 : 0u));
153                 arr[6]|= (byte)( (byte)(this.MediumChanger ? 1u<<3 : 0u) | (byte)(this.ADDR16 ? 1u<<0 : 0u));
154                 arr[7] = (byte)( (byte)(this.WBUS16a ? 1u<<5 : 0u) | (byte)(this.Sync ? 1u<<4 : 0u) | (byte)(this.CommandQueuing ? 1u<<1 : 0u) | (byte)(this.VS2 ? 1u<<0 : 0u));
155                 Array.Copy(this.VendorIdentificationT10, 0, arr, 8, this.VendorIdentificationT10.Length);
156                 Array.Copy(this.ProductIdentification, 0, arr, 16, this.ProductIdentification.Length);
157                 Array.Copy(this.ProductRevisionLevel, 0, arr, 32, this.ProductRevisionLevel.Length);
158 
159                 return arr;
160             }
161 
162             private byte[] arr = new byte[36];
163 
164         }
165 
166         public class CapacityDataStructure
167         {
168             public uint ReturnedLBA;
169             public uint BlockLength;
170             private byte[] arr = new byte[8];
ToArray()171             public byte[] ToArray()
172             {
173                 arr[0] = (byte) ((ReturnedLBA & 0xff000000) >> 24);
174                 arr[1] = (byte) ((ReturnedLBA & 0x00ff0000) >> 16);
175                 arr[2] = (byte) ((ReturnedLBA & 0x0000ff00) >> 8);
176                 arr[3] = (byte) ((ReturnedLBA & 0x000000ff) >> 0);
177 
178                 arr[4] = (byte) ((BlockLength & 0xff000000) >> 24);
179                 arr[5] = (byte) ((BlockLength & 0x00ff0000) >> 16);
180                 arr[6] = (byte) ((BlockLength & 0x0000ff00) >> 8);
181                 arr[7] = (byte) ((BlockLength & 0x000000ff) >> 0);
182 
183                 return arr;
184             }
185         }
186 
187         public class ModeSenseCommand
188         {
189             public byte OperationCode;
190             public bool DisableBlockDescriptors;
191             public byte PageControl;
192             public byte PageCode;
193             public byte SubpageCode;
194             public byte AllocationLength;
195             public byte Control;
196 
Fill(byte[] data)197             public void Fill(byte[] data)
198             {
199                 this.OperationCode = data[0];
200                 this.DisableBlockDescriptors = ((data[1] & 1u<<3)!=0) ? true:false;
201                 this.PageCode = (byte)((data[2]&0xC0) >> 6);
202                 this.SubpageCode = data[3];
203                 this.AllocationLength = data[4];
204                 this.Control = data[5];
205             }
206         }
207 
208         public enum PeripheralQualifier:byte
209         {
210             Connected = 0x0,
211             Disconnected = 0x01,
212             NotSuported = 0x3
213         }
214 
215         public enum PeripheralDeviceType:byte
216         {
217             DirectAccessBlockDevice = 0x00,
218             SequentialAccessBlockDevice = 0x01,
219             PrinterDevice = 0x02,
220             ProcessorDevice = 0x03,
221             WriteOnceDevice = 0x04,
222             CDDVDDevice = 0x05,
223             ScannerDevice = 0x06,
224             OpticalDevice = 0x07,
225             MediumChangerDevice = 0x08,
226             CommunicationsDevice = 0x09,
227             StorageArrayControllerDevice = 0x0C,
228             EnclosureServicesDevice = 0x0D,
229             SimplifiedDirectAccessDevice = 0x0E,
230             OpticalCardReaderDevice = 0x0F,
231             BridgeControllerCommands = 0x10,
232             ObjectBasedStorageDevice = 0x11,
233             AutomationDriveInterface = 0x12,
234             WellKnownLogicalUnit = 0x1E,
235             UnknownOrNoDevice = 0x1F
236         }
237 
238         public enum VersionCode
239         {
240             NotStandard = 0x00,
241             ANSISPC = 0x03,
242             ANSISPC2 = 0x04,
243             Standard = 0x05
244         }
245 
246         public enum TargetGroupPortSupportCode:byte
247         {
248             AsimetricLogicalUnitAccesNotSupported = 0x00,
249             ImplicitAsimetricLogicalUnitAccessOnly = 0x01,
250             ExplicitAsimetricLogicalUnitAccessOnly = 0x02,
251             BothAsimetricLogicalUnitAccess = 0x03,
252         }
253 
254     }
255 }
256 
257