From 93474f1a9c36e0244c418a2cecc848a815efd934 Mon Sep 17 00:00:00 2001 From: Natalia Portillo Date: Wed, 13 Apr 2016 16:28:50 +0100 Subject: [PATCH] Added skeleton for FreeBSD device handling. --- .../DiscImageChef.Devices.csproj | 5 + DiscImageChef.Devices/FreeBSD/Command.cs | 49 ++++ DiscImageChef.Devices/FreeBSD/Enums.cs | 261 ++++++++++++++++++ DiscImageChef.Devices/FreeBSD/Extern.cs | 73 +++++ DiscImageChef.Devices/FreeBSD/Structs.cs | 226 +++++++++++++++ DiscImageChef.sln | 5 +- DiscImageChef/DiscImageChef.csproj | 4 +- 7 files changed, 619 insertions(+), 4 deletions(-) create mode 100644 DiscImageChef.Devices/FreeBSD/Command.cs create mode 100644 DiscImageChef.Devices/FreeBSD/Enums.cs create mode 100644 DiscImageChef.Devices/FreeBSD/Extern.cs create mode 100644 DiscImageChef.Devices/FreeBSD/Structs.cs diff --git a/DiscImageChef.Devices/DiscImageChef.Devices.csproj b/DiscImageChef.Devices/DiscImageChef.Devices.csproj index cd00ea88..76e2ad14 100644 --- a/DiscImageChef.Devices/DiscImageChef.Devices.csproj +++ b/DiscImageChef.Devices/DiscImageChef.Devices.csproj @@ -72,6 +72,10 @@ + + + + @@ -80,6 +84,7 @@ + diff --git a/DiscImageChef.Devices/FreeBSD/Command.cs b/DiscImageChef.Devices/FreeBSD/Command.cs new file mode 100644 index 00000000..6b1b6850 --- /dev/null +++ b/DiscImageChef.Devices/FreeBSD/Command.cs @@ -0,0 +1,49 @@ +// /*************************************************************************** +// The Disc Image Chef +// ---------------------------------------------------------------------------- +// +// Filename : Command.cs +// Version : 1.0 +// Author(s) : Natalia Portillo +// +// Component : Component +// +// Revision : $Revision$ +// Last change by : $Author$ +// Date : $Date$ +// +// --[ Description ] ---------------------------------------------------------- +// +// Contains a high level representation of the FreeBSD syscalls used to directly +// interface devices +// +// --[ License ] -------------------------------------------------------------- +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// ---------------------------------------------------------------------------- +// Copyright (C) 2011-2015 Claunia.com +// ****************************************************************************/ +// //$Id$ +using System; +namespace DiscImageChef.Devices.FreeBSD +{ + public class Command + { + public Command() + { + } + } +} + diff --git a/DiscImageChef.Devices/FreeBSD/Enums.cs b/DiscImageChef.Devices/FreeBSD/Enums.cs new file mode 100644 index 00000000..f7bc4849 --- /dev/null +++ b/DiscImageChef.Devices/FreeBSD/Enums.cs @@ -0,0 +1,261 @@ +// /// ************************************************************************** +// The Disc Image Chef +// ---------------------------------------------------------------------------- +// +// Filename : Enums.cs +// Version : 1.0 +// Author(s) : Natalia Portillo +// +// Component : Linux direct device access +// +// Revision : $Revision$ +// Last change by : $Author$ +// Date : $Date$ +// +// --[ Description ] ---------------------------------------------------------- +// +// Contains enumerations necessary for directly interfacing devices under FreeBSD +// +// --[ License ] -------------------------------------------------------------- +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// ---------------------------------------------------------------------------- +// Copyright (C) 2011-2015 Claunia.com +// *************************************************************************** +// //$Id$ +using System; +namespace DiscImageChef.Devices.FreeBSD +{ + [Flags] + enum FileFlags : int + { + /// + /// O_RDONLY + /// + ReadOnly = 0x00000000, + /// + /// O_WRONLY + /// + WriteOnly = 0x00000001, + /// + /// O_RDWR + /// + ReadWrite = 0x00000002, + /// + /// O_NONBLOCK + /// + NonBlocking = 0x00000004, + /// + /// O_APPEND + /// + Append = 0x00000008, + /// + /// O_SHLOCK + /// + SharedLock = 0x00000010, + /// + /// O_EXLOCK + /// + ExclusiveLock = 0x00000020, + /// + /// O_ASYNC + /// + Async = 0x00000040, + /// + /// O_FSYNC + /// + SyncWrites = 0x00000080, + /// + /// O_NOFOLLOW + /// + NoFollowSymlink = 0x00000100, + /// + /// O_CREAT + /// + OpenOrCreate = 0x00000200, + /// + /// O_TRUNC + /// + Truncate = 0x00000400, + /// + /// O_EXCL + /// + CreateNew = 0x00000800, + /// + /// O_NOCTTY + /// + NoControlTTY = 0x00008000, + /// + /// O_DIRECT + /// + Direct = 0x00010000, + /// + /// O_DIRECTORY + /// + Directory = 0x00020000, + /// + /// O_EXEC + /// + Execute = 0x00040000, + /// + /// O_TTY_INIT + /// + InitializeTTY = 0x00080000, + /// + /// O_CLOEXEC + /// + CloseOnExec = 0x00100000 + } + + [Flags] + enum CamAtaIoFlags : byte + { + /// + /// 48-bit command + /// + ExtendedCommand = 0x01, + /// + /// FPDMA command + /// + FPDMA = 0x02, + /// + /// Control, not a command + /// + Control = 0x04, + /// + /// Needs result + /// + NeedResult = 0x08, + /// + /// DMA command + /// + DMA = 0x10 + } + + /// XPT Opcodes for xpt_action + [Flags] + enum xpt_opcode + { + // Function code flags are bits greater than 0xff + + /// Non-immediate function code + XPT_FC_QUEUED = 0x100, + XPT_FC_USER_CCB = 0x200, + /// Only for the transport layer device + XPT_FC_XPT_ONLY = 0x400, + /// Passes through the device queues + XPT_FC_DEV_QUEUED = 0x800 | XPT_FC_QUEUED, + + // Common function commands: 0x00->0x0F + + /// Execute Nothing + XPT_NOOP = 0x00, + /// Execute the requested I/O operation + XPT_SCSI_IO = 0x01 | XPT_FC_DEV_QUEUED, + /// Get type information for specified device + XPT_GDEV_TYPE = 0x02, + /// Get a list of peripheral devices + XPT_GDEVLIST = 0x03, + /// Path routing inquiry + XPT_PATH_INQ = 0x04, + /// Release a frozen device queue + XPT_REL_SIMQ = 0x05, + /// Set Asynchronous Callback Parameters + XPT_SASYNC_CB = 0x06, + /// Set device type information + XPT_SDEV_TYPE = 0x07, + /// (Re)Scan the SCSI Bus + XPT_SCAN_BUS = 0x08 | XPT_FC_QUEUED | XPT_FC_USER_CCB + | XPT_FC_XPT_ONLY, + /// Get EDT entries matching the given pattern + XPT_DEV_MATCH = 0x09 | XPT_FC_XPT_ONLY, + /// Turn on debugging for a bus, target or lun + XPT_DEBUG = 0x0a, + /// Path statistics (error counts, etc.) + XPT_PATH_STATS = 0x0b, + /// Device statistics (error counts, etc.) + XPT_GDEV_STATS = 0x0c, + /// Get/Set Device advanced information + XPT_DEV_ADVINFO = 0x0e, + /// Asynchronous event + XPT_ASYNC = 0x0f | XPT_FC_QUEUED | XPT_FC_USER_CCB + | XPT_FC_XPT_ONLY, + + /// SCSI Control Functions: 0x10->0x1F + + /// Abort the specified CCB + XPT_ABORT = 0x10, + /// Reset the specified SCSI bus + XPT_RESET_BUS = 0x11 | XPT_FC_XPT_ONLY, + /// Bus Device Reset the specified SCSI device + XPT_RESET_DEV = 0x12 | XPT_FC_DEV_QUEUED, + /// Terminate the I/O process + XPT_TERM_IO = 0x13, + /// Scan Logical Unit + XPT_SCAN_LUN = 0x14 | XPT_FC_QUEUED | XPT_FC_USER_CCB + | XPT_FC_XPT_ONLY, + /// Get default/user transfer settings for the target + XPT_GET_TRAN_SETTINGS = 0x15, + /// Set transfer rate/width negotiation settings + XPT_SET_TRAN_SETTINGS = 0x16, + /// Calculate the geometry parameters for a device give the sector size and volume size. + XPT_CALC_GEOMETRY = 0x17, + /// Execute the requested ATA I/O operation + XPT_ATA_IO = 0x18 | XPT_FC_DEV_QUEUED, + + /// Compat only + XPT_GET_SIM_KNOB_OLD = 0x18, + + /// Set SIM specific knob values. + XPT_SET_SIM_KNOB = 0x19, + /// Get SIM specific knob values. + XPT_GET_SIM_KNOB = 0x1a, + /// Serial Management Protocol + XPT_SMP_IO = 0x1b | XPT_FC_DEV_QUEUED, + /// Scan Target + XPT_SCAN_TGT = 0x1E | XPT_FC_QUEUED | XPT_FC_USER_CCB + | XPT_FC_XPT_ONLY, + + // HBA engine commands 0x20->0x2F + + /// HBA engine feature inquiry + XPT_ENG_INQ = 0x20 | XPT_FC_XPT_ONLY, + /// HBA execute engine request + XPT_ENG_EXEC = 0x21 | XPT_FC_DEV_QUEUED, + + // Target mode commands: 0x30->0x3F + + /// Enable LUN as a target + XPT_EN_LUN = 0x30, + /// Execute target I/O request + XPT_TARGET_IO = 0x31 | XPT_FC_DEV_QUEUED, + /// Accept Host Target Mode CDB + XPT_ACCEPT_TARGET_IO = 0x32 | XPT_FC_QUEUED | XPT_FC_USER_CCB, + /// Continue Host Target I/O Connection + XPT_CONT_TARGET_IO = 0x33 | XPT_FC_DEV_QUEUED, + /// Notify Host Target driver of event (obsolete) + XPT_IMMED_NOTIFY = 0x34 | XPT_FC_QUEUED | XPT_FC_USER_CCB, + /// Acknowledgement of event (obsolete) + XPT_NOTIFY_ACK = 0x35, + /// Notify Host Target driver of event + XPT_IMMEDIATE_NOTIFY = 0x36 | XPT_FC_QUEUED | XPT_FC_USER_CCB, + /// Acknowledgement of event + XPT_NOTIFY_ACKNOWLEDGE = 0x37 | XPT_FC_QUEUED | XPT_FC_USER_CCB, + + /// Vendor Unique codes: 0x80->0x8F + XPT_VUNIQUE = 0x80 + } +} + diff --git a/DiscImageChef.Devices/FreeBSD/Extern.cs b/DiscImageChef.Devices/FreeBSD/Extern.cs new file mode 100644 index 00000000..d0a0b9a3 --- /dev/null +++ b/DiscImageChef.Devices/FreeBSD/Extern.cs @@ -0,0 +1,73 @@ +// /*************************************************************************** +// The Disc Image Chef +// ---------------------------------------------------------------------------- +// +// Filename : Extern.cs +// Version : 1.0 +// Author(s) : Natalia Portillo +// +// Component : Component +// +// Revision : $Revision$ +// Last change by : $Author$ +// Date : $Date$ +// +// --[ Description ] ---------------------------------------------------------- +// +// Contains the P/Invoke definitions of FreeBSD syscalls used to directly interface devices +// +// --[ License ] -------------------------------------------------------------- +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// ---------------------------------------------------------------------------- +// Copyright (C) 2011-2015 Claunia.com +// ****************************************************************************/ +// //$Id$ +using System; +using System.Runtime.InteropServices; + +namespace DiscImageChef.Devices.FreeBSD +{ + static class Extern + { + [DllImport("libc", CharSet = CharSet.Ansi, SetLastError = true)] + internal static extern int open( + string pathname, + [MarshalAs(UnmanagedType.U4)] + FileFlags flags); + + [DllImport("libc")] + internal static extern int close(int fd); + + [DllImport("libcam", CharSet = CharSet.Ansi, SetLastError = true)] + internal static extern IntPtr cam_open_device( + string path, + [MarshalAs(UnmanagedType.U4)] + FileFlags flags); + + [DllImport("libcam", CharSet = CharSet.Ansi, SetLastError = true)] + internal static extern void cam_close_device(IntPtr dev); + + [DllImport("libcam", CharSet = CharSet.Ansi, SetLastError = true)] + internal static extern IntPtr cam_getccb(IntPtr dev); + + [DllImport("libcam", CharSet = CharSet.Ansi, SetLastError = true)] + internal static extern void cam_freeccb(IntPtr ccb); + + [DllImport("libcam", CharSet = CharSet.Ansi, SetLastError = true)] + internal static extern int cam_send_ccb(IntPtr dev, IntPtr ccb); + } +} + diff --git a/DiscImageChef.Devices/FreeBSD/Structs.cs b/DiscImageChef.Devices/FreeBSD/Structs.cs new file mode 100644 index 00000000..153a53df --- /dev/null +++ b/DiscImageChef.Devices/FreeBSD/Structs.cs @@ -0,0 +1,226 @@ +// /*************************************************************************** +// The Disc Image Chef +// ---------------------------------------------------------------------------- +// +// Filename : Structs.cs +// Version : 1.0 +// Author(s) : Natalia Portillo +// +// Component : Component +// +// Revision : $Revision$ +// Last change by : $Author$ +// Date : $Date$ +// +// --[ Description ] ---------------------------------------------------------- +// +// Contains structures necessary for directly interfacing devices under FreeBSD +// +// --[ License ] -------------------------------------------------------------- +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// ---------------------------------------------------------------------------- +// Copyright (C) 2011-2015 Claunia.com +// ****************************************************************************/ +// //$Id$ +using System; +using System.Runtime.InteropServices; + +namespace DiscImageChef.Devices.FreeBSD +{ + struct ata_cmd + { + public CamAtaIoFlags flags; + public byte command; + public byte features; + public byte lba_low; + public byte lba_mid; + public byte lba_high; + public byte device; + public byte lba_low_exp; + public byte lba_mid_exp; + public byte lba_high_exp; + public byte features_exp; + public byte sector_count; + public byte sector_count_exp; + public byte control; + } + + struct ata_res + { + public CamAtaIoFlags flags; + public byte status; + public byte error; + public byte lba_low; + public byte lba_mid; + public byte lba_high; + public byte device; + public byte lba_low_exp; + public byte lba_mid_exp; + public byte lba_high_exp; + public byte sector_count; + public byte sector_count_exp; + } + + struct cam_pinfo + { + public UInt32 priority; + public UInt32 generation; + public int index; + } + + struct camq_entry + { + /// + /// LIST_ENTRY(ccb_hdr)=le->*le_next + /// + public IntPtr le_next; + /// + /// LIST_ENTRY(ccb_hdr)=le->**le_prev + /// + public IntPtr le_prev; + /// + /// SLIST_ENTRY(ccb_hdr)=sle->*sle_next + /// + public IntPtr sle_next; + /// + /// TAILQ_ENTRY(ccb_hdr)=tqe->*tqe_next + /// + public IntPtr tqe_next; + /// + /// TAILQ_ENTRY(ccb_hdr)=tqe->**tqe_prev + /// + public IntPtr tqe_prev; + /// + /// STAILQ_ENTRY(ccb_hdr)=stqe->*stqe_next + /// + public IntPtr stqe_next; + } + + struct timeval + { + public Int64 tv_sec; + /// long + public IntPtr tv_usec; + } + + struct ccb_qos_area + { + public timeval etime; + public UIntPtr sim_data; + public UIntPtr periph_data; + } + + struct ccb_hdr + { + public cam_pinfo pinfo; + public camq_entry xpt_links; + public camq_entry sim_links; + public camq_entry periph_links; + public UInt32 retry_count; + public IntPtr cbfcnp; + public xpt_opcode func_code; + public UInt32 status; + public IntPtr path; + public uint path_id; + public uint target_id; + public UInt64 target_lun; + public UInt32 flags; + public UInt32 xflags; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)] + public IntPtr[] periph_priv; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)] + public IntPtr[] sim_priv; + public ccb_qos_area qos; + public UInt32 timeout; + public timeval softtimeout; + } + + struct scsi_sense_data + { + public byte error_code; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 251)] + public byte[] sense_buf; + } + + /// + /// SCSI I/O Request CCB used for the XPT_SCSI_IO and XPT_CONT_TARGET_IO function codes. + /// + struct cdb_scsiio + { + public ccb_hdr ccb_h; + /// Ptr for next CCB for action + public IntPtr next_ccb; + /// Ptr to mapping info + public IntPtr req_map; + /// Ptr to the data buf/SG list + public IntPtr data_ptr; + /// Data transfer length + public UInt32 dxfer_len; + /// Autosense storage + public scsi_sense_data sense_data; + /// Number of bytes to autosense + public byte sense_len; + /// Number of bytes for the CDB + public byte cdb_len; + /// Number of SG list entries + public UInt16 sglist_cnt; + /// Returned SCSI status + public byte scsi_status; + /// Autosense resid length: 2's comp + public sbyte sense_resid; + /// Transfer residual length: 2's comp + public Int32 resid; + /// Union for CDB bytes/pointer + public IntPtr cdb_io; + /// Pointer to the message buffer + public IntPtr msg_ptr; + /// Number of bytes for the Message + public UInt16 msg_len; + /// What to do for tag queueing. The tag action should be either the define below (to send a non-tagged transaction) or one of the defined scsi tag messages from scsi_message.h. + public byte tag_action; + /// tag id from initator (target mode) + public UInt32 tag_id; + /// initiator id of who selected + public UInt32 init_id; + } + + /// + /// ATA I/O Request CCB used for the XPT_ATA_IO function code. + /// + struct ccb_ataio + { + public ccb_hdr ccb_h; + /// Ptr for next CCB for action + public IntPtr next_ccb; + /// ATA command register set + public ata_cmd cmd; + /// ATA result register set + public ata_res res; + /// Ptr to the data buf/SG list + public IntPtr data_ptr; + /// Data transfer length + public UInt32 dxfer_len; + /// Transfer residual length: 2's comp + public Int32 resid; + /// What to do for tag queueing. The tag action should be either the define below (to send a non-tagged transaction) or one of the defined scsi tag messages from scsi_message.h. + public byte tag_action; + /// tag id from initator (target mode) + public UInt32 tag_id; + /// initiator id of who selected + public UInt32 init_id; + } +} + diff --git a/DiscImageChef.sln b/DiscImageChef.sln index dc9e902a..b29caa32 100644 --- a/DiscImageChef.sln +++ b/DiscImageChef.sln @@ -102,9 +102,9 @@ Global $1.Text = @/***************************************************************************\nThe Disc Image Chef\n----------------------------------------------------------------------------\n \nFilename : ${FileName}\nVersion : 1.0\nAuthor(s) : ${AuthorName}\n \nComponent : Component\n\nRevision : $Revision$\nLast change by : $Author$\nDate : $Date$\n \n--[ Description ] ----------------------------------------------------------\n \nDescription\n \n--[ License ] --------------------------------------------------------------\n \n This program is free software: you can redistribute it and/or modify\n it under the terms of the GNU General Public License as\n published by the Free Software Foundation, either version 3 of the\n License, or (at your option) any later version.\n\n This program is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU General Public License for more details.\n\n You should have received a copy of the GNU General Public License\n along with this program. If not, see .\n\n----------------------------------------------------------------------------\nCopyright (C) 2011-2015 Claunia.com\n****************************************************************************/\n//$Id$ $1.IncludeInNewFiles = True $0.TextStylePolicy = $2 - $2.inheritsSet = null + $2.inheritsSet = VisualStudio $2.inheritsScope = text/plain - $2.scope = application/config+xml + $2.scope = text/x-csharp $2.FileWidth = 120 $0.CSharpFormattingPolicy = $3 $3.SpacingAfterMethodDeclarationName = False @@ -130,6 +130,7 @@ Global $3.NewLineForClausesInQuery = True $3.IndentBlock = False $3.IndentSwitchCaseSection = False + $3.SpaceAfterControlFlowStatementKeyword = False $0.DotNetNamingPolicy = $4 $4.DirectoryNamespaceAssociation = Hierarchical $4.ResourceNamePolicy = MSBuild diff --git a/DiscImageChef/DiscImageChef.csproj b/DiscImageChef/DiscImageChef.csproj index 666a74a3..d5adfcba 100644 --- a/DiscImageChef/DiscImageChef.csproj +++ b/DiscImageChef/DiscImageChef.csproj @@ -83,8 +83,8 @@ - - + +