-
Notifications
You must be signed in to change notification settings - Fork 68
iSCSI commands and enum values to support DVD-ROM devices #10
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
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,39 @@ | ||
| using System; | ||
| using Utilities; | ||
|
|
||
| namespace SCSI | ||
| { | ||
| internal class GetConfigurationCommand : SCSICommandDescriptorBlock | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Shouldn't this inherit from SCSICommandDescriptorBlock10? and than you can use some of the fields... |
||
| { | ||
| public const int PacketLength = 12; | ||
| // Request Type | ||
| public byte RT; | ||
| public ushort StartingFeatureNumber; | ||
| public short AllocationLength; | ||
|
|
||
| public GetConfigurationCommand() | ||
| { | ||
| OpCode = SCSIOpCodeName.GetConfiguration; | ||
| } | ||
|
|
||
| public GetConfigurationCommand(byte[] buffer, int offset) | ||
| { | ||
| OpCode = (SCSIOpCodeName)buffer[offset + 0]; | ||
| RT = (byte)(buffer[offset +1] & 0x03); | ||
| StartingFeatureNumber = BigEndianConverter.ToUInt16(buffer, offset + 2); | ||
| AllocationLength = BigEndianConverter.ToInt16(buffer, offset +7); | ||
| TransferLength = (uint)AllocationLength; | ||
| } | ||
|
|
||
| public override byte[] GetBytes() | ||
| { | ||
| byte[] buffer = new byte[PacketLength]; | ||
| buffer[0] = (byte)OpCode; | ||
| buffer[1] = RT; | ||
| BigEndianWriter.WriteUInt16(buffer, 2, StartingFeatureNumber); | ||
| BigEndianWriter.WriteInt16(buffer, 7, AllocationLength); | ||
|
|
||
| return buffer; | ||
| } | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,46 @@ | ||
| using System; | ||
| using Utilities; | ||
|
|
||
| namespace SCSI | ||
| { | ||
| internal class ReadTocCommand : SCSICommandDescriptorBlock | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Shouldn't this inherit from SCSICommandDescriptorBlock10? and than you can use some of the fields... |
||
| { | ||
| public const int PacketLength = 12; | ||
| public bool MSF; | ||
| public byte Format; | ||
| public byte TrackSessionNumber; | ||
| public short AllocationLength; | ||
|
|
||
| public ReadTocCommand() | ||
| { | ||
| OpCode = SCSIOpCodeName.ReadToc; | ||
| } | ||
|
|
||
| public ReadTocCommand(byte[] buffer, int offset) | ||
| { | ||
| OpCode = (SCSIOpCodeName)buffer[offset + 0]; | ||
| MSF = (buffer[offset + 1] & 0x02) == 1; | ||
| Format = (byte)(buffer[offset + 2] & 0xF); | ||
| TrackSessionNumber = buffer[offset + 6]; | ||
| AllocationLength = BigEndianConverter.ToInt16(buffer, offset + 7); | ||
| TransferLength = (uint)AllocationLength; | ||
| Control = buffer[offset + 9]; | ||
| } | ||
|
|
||
| public override byte[] GetBytes() | ||
| { | ||
| byte[] buffer = new byte[PacketLength]; | ||
| buffer[0] = (byte)OpCode; | ||
| if (MSF) | ||
| { | ||
| buffer[1] |= 0x02; | ||
| } | ||
| buffer[2] |= (byte)(Format & 0xF); | ||
| buffer[6] = TrackSessionNumber; | ||
| BigEndianWriter.WriteInt16(buffer, 7, AllocationLength); | ||
| buffer[9] = Control; | ||
|
|
||
| return buffer; | ||
| } | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,65 @@ | ||
| /* Copyright (C) 2012-2016 Tal Aloni <tal.aloni.il@gmail.com>. All rights reserved. | ||
| * | ||
| * You can redistribute this program and/or modify it under the terms of | ||
| * the GNU Lesser Public License as published by the Free Software Foundation, | ||
| * either version 3 of the License, or (at your option) any later version. | ||
| */ | ||
| using Utilities; | ||
|
|
||
| namespace SCSI | ||
| { | ||
| public class ModeSense10CommandDescriptorBlock : SCSICommandDescriptorBlock | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should this inherit from SCSICommandDescriptorBlock10? |
||
| { | ||
| public const int PacketLength = 10; | ||
|
|
||
| public bool DBD; // Disable block descriptors | ||
| public byte PC; // Page Control | ||
| public ModePageCodeName PageCode; | ||
| public byte SubpageCode; | ||
| public bool LLBA; | ||
|
|
||
| public ModeSense10CommandDescriptorBlock() : base() | ||
| { | ||
| OpCode = SCSIOpCodeName.ModeSense10; | ||
| } | ||
|
|
||
| public ModeSense10CommandDescriptorBlock(byte[] buffer, int offset) : base() | ||
| { | ||
| OpCode = (SCSIOpCodeName)buffer[offset + 0]; | ||
| DBD = (buffer[offset + 1] & 0x08) != 0; | ||
| PC = (byte)(buffer[offset + 2] >> 6); | ||
| PageCode = (ModePageCodeName)(buffer[offset + 2] & 0x3F); | ||
| SubpageCode = buffer[offset + 3]; | ||
| AllocationLength = BigEndianConverter.ToInt16(buffer,offset + 7); | ||
| Control = buffer[offset + 9]; | ||
| } | ||
|
|
||
| public override byte[] GetBytes() | ||
| { | ||
| var buffer = new byte[PacketLength]; | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. "byte[] buffer" is better IMO |
||
| buffer[0] = (byte)OpCode; | ||
| if (DBD) | ||
| { | ||
| buffer[1] |= 0x08; | ||
| } | ||
| buffer[2] |= (byte)(PC << 6); | ||
| buffer[2] |= (byte)((byte)PageCode & 0x3F); | ||
| buffer[3] = SubpageCode; | ||
| BigEndianWriter.WriteInt16(buffer, 7, AllocationLength); | ||
| buffer[9] = Control; | ||
| return buffer; | ||
| } | ||
|
|
||
| public short AllocationLength | ||
| { | ||
| get | ||
| { | ||
| return (short)TransferLength; | ||
| } | ||
| set | ||
| { | ||
| TransferLength = (uint)value; | ||
| } | ||
| } | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,104 @@ | ||
| using System; | ||
| using System.Collections.Generic; | ||
| using System.Text; | ||
| using Utilities; | ||
|
|
||
| namespace SCSI | ||
| { | ||
| internal class FormattedToc | ||
| { | ||
| const int Length = 64; | ||
| byte[] data = new byte[Length]; | ||
| bool _msf = false; | ||
|
|
||
| /// <summary> | ||
| /// The TOC data length indicates the length in bytes of the following TOC data. The TOC data length value | ||
| /// does not include the TOC data length field itself.This value is not modified when the allocation length is | ||
| /// insufficient to return all of the TOC data available. | ||
| /// </summary> | ||
| private ushort TocDataLength | ||
| { | ||
| get { return BigEndianConverter.ToUInt16(data, 0); } | ||
| set { BigEndianWriter.WriteUInt16(data, 0, value); } | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// The First Track Number field indicates the first track number in the first complete session Table of Contents. | ||
| /// </summary> | ||
| public byte FirstTrackNumber | ||
| { | ||
| get { return data[2]; } | ||
| set { data[2] = value; } | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// The Last Track Number field indicates the last track number in the last complete session Table of Contents | ||
| /// before the lead-out. | ||
| /// </summary> | ||
| public byte LastTrackNumber | ||
| { | ||
| get { return data[3]; } | ||
| set { data[3] = value; } | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// An MSF bit of zero indicates that the Logical Block Address field | ||
| /// contains a logical block address.An MSF bit of one indicates the Logical Block Address field contains an | ||
| /// MSF address. | ||
| /// </summary> | ||
| /// <param name="msf"></param> | ||
| public FormattedToc(bool msf) | ||
| { | ||
| _msf = msf; | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Sets TOC Track Descriptor in the Formatted TOC data array. | ||
| /// </summary> | ||
| /// <param name="position">Descriptor position in the data array</param> | ||
| /// <param name="adr">The ADR field gives the type of information encoded in the Q sub-channel of the block where this TOC | ||
| /// entry was found.</param> | ||
| /// <param name="control">The Control Field indicates the attributes, of the track.</param> | ||
| /// <param name="trackNumber">The Track Number field indicates the track number for which the data in the TOC track descriptor is valid. | ||
| /// A track number of AAh indicates that the track descriptor is for the start of the lead-out area.</param> | ||
| /// <param name="address">The Logical Block Address contains the address of the first block with user information for that track | ||
| /// number as read from the Table of Contents.</param> | ||
| public void SetTocTrackDescriptor(byte position, byte adr, byte control, byte trackNumber, uint address) | ||
| { | ||
| int offset = 4 + position * 8; // 4 descriptor start offset, 8 - size of descriptor (TOC/PMA/ATIP Response Data Format 0000) | ||
| // Reserved | ||
| data[offset + 0] = 0; | ||
| // ADR(7-4) CONTROL(3-0) | ||
| data[offset + 1] = (byte)(adr << 4 | (control & 0xF)); | ||
| data[offset + 2] = trackNumber; | ||
| // Reserved | ||
| data[offset + 3] = 0; | ||
|
|
||
| /* Track Start Address */ | ||
| if (_msf) | ||
| { | ||
| BigEndianWriter.WriteUInt32(data, offset + 4, MmcHelper.Lba2Msf(address)); | ||
| } | ||
| else | ||
| { | ||
| BigEndianWriter.WriteUInt32(data, offset + 4, address); | ||
| } | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Adjusts data length for requested track count. | ||
| /// </summary> | ||
| /// <param name="trackCount"></param> | ||
| /// <exception cref="NotImplementedException"></exception> | ||
| public void UpdateDataLength(int trackCount) | ||
| { | ||
| // 4 bytes of data + trackCount descriptors - TOC data length field itself | ||
| TocDataLength = (byte)(4 + trackCount * 8 - 2); | ||
| } | ||
|
|
||
| public byte[] GetBytes() | ||
| { | ||
| return data; | ||
| } | ||
| } | ||
| } |
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is device specific, right? which specification covers that 0x2A code?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is CD/DVD device specific (MMC), Windows requests it, for example, when peripheral device type is 0x5.
You can find it's description in scsi spec paragraph 5.2.3.4 (http://www.13thmonkey.org/documentation/SCSI/x3_304_1997.pdf)