From b0c857b2f358d8fd2622c15e5abcfd27a55cbe4b Mon Sep 17 00:00:00 2001 From: Natalia Portillo Date: Sat, 19 Oct 2019 17:18:58 +0100 Subject: [PATCH] Implement SDHCI commands for Linux. --- CMakeLists.txt | 4 +-- dicmote.h | 14 ++++++++++ linux/linux.h | 14 +++++++++- linux/sdhci.c | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++ sdhci.c | 54 ++++++++++++++++++++++++++++++++++++++ 5 files changed, 154 insertions(+), 3 deletions(-) create mode 100644 linux/sdhci.c create mode 100644 sdhci.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 72549b1..ba6c80d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,10 +3,10 @@ project(dicremote C) set(CMAKE_C_STANDARD 90) -set(MAIN_SOURCES main.c list_devices.c device.c scsi.c hex2bin.c usb.c ieee1394.c pcmcia.c ata.c) +set(MAIN_SOURCES main.c list_devices.c device.c scsi.c hex2bin.c usb.c ieee1394.c pcmcia.c ata.c sdhci.c) if("${CMAKE_SYSTEM}" MATCHES "Linux") - set(PLATFORM_SOURCES linux/list_devices.c linux/linux.h linux/device.c linux/scsi.c linux/usb.c linux/ieee1394.c linux/pcmcia.c linux/ata.c) + set(PLATFORM_SOURCES linux/list_devices.c linux/linux.h linux/device.c linux/scsi.c linux/usb.c linux/ieee1394.c linux/pcmcia.c linux/ata.c linux/sdhci.c) endif() add_executable(dicremote ${MAIN_SOURCES} ${PLATFORM_SOURCES}) diff --git a/dicmote.h b/dicmote.h index ce9be25..8826ef8 100644 --- a/dicmote.h +++ b/dicmote.h @@ -483,5 +483,19 @@ int32_t SendAtaLba48Command(int device_fd, uint32_t* duration, uint32_t* sense, uint32_t* buf_len); +int32_t SendSdhciCommand(int device_fd, + uint8_t command, + uint8_t write, + uint8_t application, + uint32_t flags, + uint32_t argument, + uint32_t block_size, + uint32_t blocks, + char* buffer, + uint32_t buf_len, + uint32_t timeout, + uint32_t* response, + uint32_t* duration, + uint32_t* sense); #endif diff --git a/linux/linux.h b/linux/linux.h index 31a4d57..62413d9 100644 --- a/linux/linux.h +++ b/linux/linux.h @@ -92,5 +92,17 @@ int32_t linux_send_ata_lba48_command(int device_fd, uint32_t* duration, uint32_t* sense, uint32_t* buf_len); - +int32_t linux_send_sdhci_command(int device_fd, + uint8_t command, + uint8_t write, + uint8_t application, + uint32_t flags, + uint32_t argument, + uint32_t block_size, + uint32_t blocks, + char* buffer, + uint32_t timeout, + uint32_t* response, + uint32_t* duration, + uint32_t* sense); #endif // DICREMOTE_LINUX_H diff --git a/linux/sdhci.c b/linux/sdhci.c new file mode 100644 index 0000000..be0fae4 --- /dev/null +++ b/linux/sdhci.c @@ -0,0 +1,71 @@ +/* + * This file is part of the DiscImageChef Remote Server. + * Copyright (c) 2019 Natalia Portillo. + * + * 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, version 3. + * + * 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 . + */ + +#include +#include +#include +#include +#include +#include + +int32_t linux_send_sdhci_command(int device_fd, + uint8_t command, + uint8_t write, + uint8_t application, + uint32_t flags, + uint32_t argument, + uint32_t block_size, + uint32_t blocks, + char* buffer, + uint32_t timeout, + uint32_t* response, + uint32_t* duration, + uint32_t* sense) +{ + struct mmc_ioc_cmd mmc_ioc_cmd; + int32_t error; + *duration = 0; + *sense = 0; + + memset(response, 0, sizeof(uint32_t) * 4); + memset(&mmc_ioc_cmd, 0, sizeof(struct mmc_ioc_cmd)); + + mmc_ioc_cmd.write_flag = write; + mmc_ioc_cmd.is_acmd = application; + mmc_ioc_cmd.opcode = command; + mmc_ioc_cmd.arg = argument; + mmc_ioc_cmd.flags = flags; + mmc_ioc_cmd.blksz = block_size; + mmc_ioc_cmd.blocks = blocks; + if(timeout > 0) + { + mmc_ioc_cmd.data_timeout_ns = timeout * 1000000000; + mmc_ioc_cmd.cmd_timeout_ms = timeout * 1000; + } + mmc_ioc_cmd.data_ptr = (uint64_t)buffer; + + // TODO: Timing + error = ioctl(device_fd, MMC_IOC_CMD, &mmc_ioc_cmd); + + if(error < 0) error = errno; + + *sense = error < 0; + + memcpy((char*)response, (char*)&mmc_ioc_cmd.response, sizeof(uint32_t) * 4); + + return error; +} \ No newline at end of file diff --git a/sdhci.c b/sdhci.c new file mode 100644 index 0000000..e44d30e --- /dev/null +++ b/sdhci.c @@ -0,0 +1,54 @@ +/* + * This file is part of the DiscImageChef Remote Server. + * Copyright (c) 2019 Natalia Portillo. + * + * 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, version 3. + * + * 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 . + */ + +#if defined(__linux__) && !defined(__ANDROID__) +#include "linux/linux.h" +#endif + +int32_t SendSdhciCommand(int device_fd, + uint8_t command, + uint8_t write, + uint8_t application, + uint32_t flags, + uint32_t argument, + uint32_t block_size, + uint32_t blocks, + char* buffer, + uint32_t buf_len, + uint32_t timeout, + uint32_t* response, + uint32_t* duration, + uint32_t* sense) +{ +#if defined(__linux__) && !defined(__ANDROID__) + return linux_send_sdhci_command(device_fd, + command, + write, + application, + flags, + argument, + block_size, + blocks, + buffer, + timeout, + response, + duration, + sense); +#else + return -1; +#endif +} \ No newline at end of file