Пример #1
0
        /// <summary>Sends a MMC/SD command</summary>
        /// <returns>The result of the command.</returns>
        /// <param name="fd">File handle</param>
        /// <param name="command">MMC/SD opcode</param>
        /// <param name="buffer">Buffer for MMC/SD command response</param>
        /// <param name="timeout">Timeout in seconds</param>
        /// <param name="duration">Time it took to execute the command in milliseconds</param>
        /// <param name="sense"><c>True</c> if MMC/SD returned non-OK status</param>
        /// <param name="write"><c>True</c> if data is sent from host to card</param>
        /// <param name="isApplication"><c>True</c> if command should be preceded with CMD55</param>
        /// <param name="flags">Flags indicating kind and place of response</param>
        /// <param name="blocks">How many blocks to transfer</param>
        /// <param name="argument">Command argument</param>
        /// <param name="response">Response registers</param>
        /// <param name="blockSize">Size of block in bytes</param>
        internal static int SendMmcCommand(int fd, MmcCommands command, bool write, bool isApplication, MmcFlags flags,
                                           uint argument, uint blockSize, uint blocks, ref byte[] buffer,
                                           out uint[] response, out double duration, out bool sense, uint timeout = 0)
        {
            response = null;
            duration = 0;
            sense    = false;

            if (buffer == null)
            {
                return(-1);
            }

            var ioCmd = new MmcIocCmd();

            IntPtr bufPtr = Marshal.AllocHGlobal(buffer.Length);

            ioCmd.write_flag = write;
            ioCmd.is_ascmd   = isApplication;
            ioCmd.opcode     = (uint)command;
            ioCmd.arg        = argument;
            ioCmd.flags      = flags;
            ioCmd.blksz      = blockSize;
            ioCmd.blocks     = blocks;

            if (timeout > 0)
            {
                ioCmd.data_timeout_ns = timeout * 1000000000;
                ioCmd.cmd_timeout_ms  = timeout * 1000;
            }

            ioCmd.data_ptr = (ulong)bufPtr;

            Marshal.Copy(buffer, 0, bufPtr, buffer.Length);

            DateTime start = DateTime.UtcNow;
            int      error = Extern.ioctlMmc(fd, LinuxIoctl.MmcIocCmd, ref ioCmd);
            DateTime end   = DateTime.UtcNow;

            sense |= error < 0;

            if (error < 0)
            {
                error = Marshal.GetLastWin32Error();
            }

            Marshal.Copy(bufPtr, buffer, 0, buffer.Length);

            response = ioCmd.response;
            duration = (end - start).TotalMilliseconds;

            Marshal.FreeHGlobal(bufPtr);

            return(error);
        }
Пример #2
0
 internal static extern int ioctlMmc(int fd, LinuxIoctl request, ref MmcIocCmd value);
Пример #3
0
        internal static int SendMultipleMmcCommands(int fd, Device.MmcSingleCommand[] commands, out double duration,
                                                    out bool sense, uint timeout = 0)
        {
            duration = 0;
            sense    = false;
            int off = 0;

            // Create array for buffers
            IntPtr[] bufferPointers = new IntPtr[commands.Length];

            // Allocate memory for the array for commands
            byte[] ioMultiCmd = new byte[sizeof(ulong) + (Marshal.SizeOf <MmcIocCmd>() * commands.Length)];

            // First value of array is uint64 with count of commands
            Array.Copy(BitConverter.GetBytes((ulong)commands.Length), 0, ioMultiCmd, 0, sizeof(ulong));

            off = sizeof(ulong);

            for (int i = 0; i < commands.Length; i++)
            {
                // Create command
                var ioCmd = new MmcIocCmd();

                // Allocate buffer
                bufferPointers[i] = Marshal.AllocHGlobal(commands[i].buffer.Length);

                // Define command
                ioCmd.write_flag = commands[i].write;
                ioCmd.is_ascmd   = commands[i].isApplication;
                ioCmd.opcode     = (uint)commands[i].command;
                ioCmd.arg        = commands[i].argument;
                ioCmd.flags      = commands[i].flags;
                ioCmd.blksz      = commands[i].blockSize;
                ioCmd.blocks     = commands[i].blocks;

                if (timeout > 0)
                {
                    ioCmd.data_timeout_ns = timeout * 1000000000;
                    ioCmd.cmd_timeout_ms  = timeout * 1000;
                }

                ioCmd.data_ptr = (ulong)bufferPointers[i];

                // Copy buffer to unmanaged space
                Marshal.Copy(commands[i].buffer, 0, bufferPointers[i], commands[i].buffer.Length);

                // Copy command to array
                byte[] ioCmdBytes = Helpers.Marshal.StructureToByteArrayLittleEndian(ioCmd);
                Array.Copy(ioCmdBytes, 0, ioMultiCmd, off, Marshal.SizeOf <MmcIocCmd>());

                // Advance pointer
                off += Marshal.SizeOf <MmcIocCmd>();
            }

            // Allocate unmanaged memory for array of commands
            IntPtr ioMultiCmdPtr = Marshal.AllocHGlobal(ioMultiCmd.Length);

            // Copy array of commands to unmanaged memory
            Marshal.Copy(ioMultiCmd, 0, ioMultiCmdPtr, ioMultiCmd.Length);

            // Send command
            DateTime start = DateTime.UtcNow;
            int      error = Extern.ioctlMmcMulti(fd, LinuxIoctl.MmcIocMultiCmd, ioMultiCmdPtr);
            DateTime end   = DateTime.UtcNow;

            sense |= error < 0;

            if (error < 0)
            {
                error = Marshal.GetLastWin32Error();
            }

            duration = (end - start).TotalMilliseconds;

            off = sizeof(ulong);

            // Copy array from unmanaged memory
            Marshal.Copy(ioMultiCmdPtr, ioMultiCmd, 0, ioMultiCmd.Length);

            // TODO: Use real pointers this is too slow
            for (int i = 0; i < commands.Length; i++)
            {
                byte[] tmp = new byte[Marshal.SizeOf <MmcIocCmd>()];

                // Copy command to managed space
                Array.Copy(ioMultiCmd, off, tmp, 0, tmp.Length);
                MmcIocCmd command = Helpers.Marshal.ByteArrayToStructureLittleEndian <MmcIocCmd>(tmp);

                // Copy response
                commands[i].response = command.response;

                // Copy buffer to managed space
                Marshal.Copy(bufferPointers[i], commands[i].buffer, 0, commands[i].buffer.Length);

                // Free buffer
                Marshal.FreeHGlobal(bufferPointers[i]);

                // Advance pointer
                off += Marshal.SizeOf <MmcIocCmd>();
            }

            // Free unmanaged memory
            Marshal.FreeHGlobal(ioMultiCmdPtr);

            return(error);
        }