From Adrien Destugues <pulkomandy@xxxxxxxxx>:
Adrien Destugues has uploaded this change for review. (
https://review.haiku-os.org/c/haiku/+/3641 ;)
Change subject: mmc_disk: implement B_TRIM_DEVICE
......................................................................
mmc_disk: implement B_TRIM_DEVICE
---
M headers/private/drivers/mmc.h
M headers/private/kernel/util/fs_trim_support.h
M src/add-ons/kernel/busses/mmc/sdhci_pci.cpp
M src/add-ons/kernel/drivers/disk/mmc/mmc_disk.cpp
4 files changed, 100 insertions(+), 3 deletions(-)
git pull ssh://git.haiku-os.org:22/haiku refs/changes/41/3641/1
diff --git a/headers/private/drivers/mmc.h b/headers/private/drivers/mmc.h
index 8d3780e..e8434c4 100644
--- a/headers/private/drivers/mmc.h
+++ b/headers/private/drivers/mmc.h
@@ -49,6 +49,11 @@
SD_WRITE_SINGLE_BLOCK = 24,
SD_WRITE_MULTIPLE_BLOCKS = 25,
+ // Erase commands, class 5
+ SD_ERASE_WR_BLK_START = 32,
+ SD_ERASE_WR_BLK_END = 33,
+ SD_ERASE = 38,
+
// Application specific commands, class 8
SD_APP_CMD = 55,
diff --git a/headers/private/kernel/util/fs_trim_support.h
b/headers/private/kernel/util/fs_trim_support.h
index 22e6f9a..317929f 100644
--- a/headers/private/kernel/util/fs_trim_support.h
+++ b/headers/private/kernel/util/fs_trim_support.h
@@ -6,7 +6,9 @@
#define _FS_TRIM_SUPPORT_H
+#include <AutoDeleter.h>
#include <KernelExport.h>
+#include <SupportDefs.h>
#include <kernel.h>
#include <syscall_restart.h>
diff --git a/src/add-ons/kernel/busses/mmc/sdhci_pci.cpp
b/src/add-ons/kernel/busses/mmc/sdhci_pci.cpp
index d8b4495..0027e88 100644
--- a/src/add-ons/kernel/busses/mmc/sdhci_pci.cpp
+++ b/src/add-ons/kernel/busses/mmc/sdhci_pci.cpp
@@ -212,6 +212,7 @@
replyType = Command::kR6Type;
break;
case SD_SELECT_DESELECT_CARD:
+ case SD_ERASE:
replyType = Command::kR1bType;
break;
case SD_SEND_IF_COND:
@@ -224,6 +225,8 @@
replyType = Command::kR1Type | Command::kDataPresent;
break;
case SD_APP_CMD:
+ case SD_ERASE_WR_BLK_START:
+ case SD_ERASE_WR_BLK_END:
case SD_SET_BUS_WIDTH: // SD Application command
replyType = Command::kR1Type;
break;
diff --git a/src/add-ons/kernel/drivers/disk/mmc/mmc_disk.cpp
b/src/add-ons/kernel/drivers/disk/mmc/mmc_disk.cpp
index 2fec95e..6a0263c 100644
--- a/src/add-ons/kernel/drivers/disk/mmc/mmc_disk.cpp
+++ b/src/add-ons/kernel/drivers/disk/mmc/mmc_disk.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright 2018-2020 Haiku, Inc. All rights reserved.
+ * Copyright 2018-2021 Haiku, Inc. All rights reserved.
* Copyright 2020, Viveris Technologies.
* Distributed under the terms of the MIT License.
*
@@ -23,8 +23,10 @@
#include <drivers/KernelExport.h>
#include <drivers/Drivers.h>
#include <kernel/OS.h>
+#include <util/fs_trim_support.h>
-// #include <fs/devfs.h>
+#include <AutoDeleter.h>
+
#define TRACE_MMC_DISK
#ifdef TRACE_MMC_DISK
@@ -39,6 +41,9 @@
#define MMC_DISK_DEVICE_MODULE_NAME "drivers/disk/mmc/mmc_disk/device_v1"
#define MMC_DEVICE_ID_GENERATOR "mmc/device_id"
+
+static const uint32 kBlockSize = 512; // FIXME get it from the CSD
+
static device_manager_info* sDeviceManager;
@@ -237,7 +242,6 @@
else
info->flags = kIoCommandOffsetAsSectors;
- static const uint32 kBlockSize = 512; // FIXME get it from the CSD
status_t error;
static const uint32 kDMAResourceBufferCount = 16;
@@ -476,6 +480,73 @@
static status_t
+mmc_block_trim(mmc_disk_driver_info* info, fs_trim_data* trimData)
+{
+ enum {
+ kEraseModeErase = 0, // force to actually erase the data
+ kEraseModeDiscard = 1,
+ // just mark the data as unused for internal wear
leveling
+ // algorithms
+ kEraseModeFullErase = 2, // erase the whole card
+ };
+ TRACE("trim_device()\n");
+
+ uint64 trimmedSize = 0;
+ status_t result = B_OK;
+ for (uint32 i = 0; i < trimData->range_count; i++) {
+ off_t offset = trimData->ranges[i].offset;
+ off_t length = trimData->ranges[i].size;
+
+ // Round up offset and length to multiple of the sector size
+ // The offset is rounded up, so some space may be left
+ // (not trimmed) at the start of the range.
+ offset = (offset + kBlockSize - 1) & ~(kBlockSize - 1);
+ // Adjust the length for the possibly skipped range
+ length -= trimData->ranges[i].offset - offset;
+ // The length is rounded down, so some space at the end may also
+ // be left (not trimmed).
+ length &= ~(kBlockSize - 1);
+
+ if (length == 0) {
+ trimmedSize += trimData->ranges[i].size;
+ continue;
+ }
+
+ TRACE("trim %" B_PRIdOFF " bytes from %" B_PRIdOFF "\n",
+ length, offset);
+
+ ASSERT(offset % kBlockSize == 0);
+ ASSERT(length % kBlockSize == 0);
+
+ if (info->flags & kIoCommandOffsetAsSectors) {
+ offset /= kBlockSize;
+ length /= kBlockSize;
+ }
+
+ uint32_t response;
+ result = info->mmc->execute_command(info->parent,
info->parentCookie,
+ info->rca, SD_ERASE_WR_BLK_START, offset, &response);
+ if (result != B_OK)
+ break;
+ result = info->mmc->execute_command(info->parent,
info->parentCookie,
+ info->rca, SD_ERASE_WR_BLK_END, offset + length,
&response);
+ if (result != B_OK)
+ break;
+ result = info->mmc->execute_command(info->parent,
info->parentCookie,
+ info->rca, SD_ERASE, kEraseModeDiscard, &response);
+ if (result != B_OK)
+ break;
+
+ trimmedSize += trimData->ranges[i].size;
+ }
+
+ trimData->trimmed_size = trimmedSize;
+
+ return result;
+}
+
+
+static status_t
mmc_block_ioctl(void* cookie, uint32 op, void* buffer, size_t length)
{
mmc_disk_handle* handle = (mmc_disk_handle*)cookie;
@@ -550,6 +621,22 @@
return user_memcpy(buffer, &iconData,
sizeof(device_icon));
}
+ case B_TRIM_DEVICE:
+ {
+ fs_trim_data* trimData;
+ MemoryDeleter deleter;
+ status_t status = get_trim_data_from_user(buffer,
length, deleter,
+ trimData);
+ if (status != B_OK)
+ return status;
+
+ status = mmc_block_trim(info, trimData);
+ if (status != B_OK)
+ return status;
+
+ return copy_trim_data_to_user(buffer, trimData);
+ }
+
/*case B_FLUSH_DRIVE_CACHE:
return synchronize_cache(info);*/
}
--
To view, visit https://review.haiku-os.org/c/haiku/+/3641
To unsubscribe, or for help writing mail filters, visit
https://review.haiku-os.org/settings
Gerrit-Project: haiku
Gerrit-Branch: master
Gerrit-Change-Id: Ib08a1e196441f35550fe221b912332b4803a04b4
Gerrit-Change-Number: 3641
Gerrit-PatchSet: 1
Gerrit-Owner: Adrien Destugues <pulkomandy@xxxxxxxxx>
Gerrit-MessageType: newchange