[haiku-commits] Change in haiku[master]: mmc_disk: implement B_TRIM_DEVICE

  • From: Gerrit <review@xxxxxxxxxxxxxxxxxxx>
  • To: waddlesplash <waddlesplash@xxxxxxxxx>, haiku-commits@xxxxxxxxxxxxx
  • Date: Sun, 17 Jan 2021 16:48:04 +0000

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

Other related posts:

  • » [haiku-commits] Change in haiku[master]: mmc_disk: implement B_TRIM_DEVICE - Gerrit