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