trim: Target SCSI UNMAP command instead of WRITE SAME.
* The UNMAP command is theoretically much faster, as it can get many block ranges instead of just a single range. * Furthermore, the ATA TRIM command resembles it much better. * Therefore, fs_trim_data now gets an array of ranges, and we use SCSI UNMAP to trim. * Updated BFS code to collect array ranges to fully support the new fs_trim_data possibilities.
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2004-2010, Haiku, Inc. All RightsReserved.
|
||||
* Copyright 2004-2013, Haiku, Inc. All RightsReserved.
|
||||
* Copyright 2002/03, Thomas Kurschel. All rights reserved.
|
||||
*
|
||||
* Distributed under the terms of the MIT License.
|
||||
@@ -185,6 +185,8 @@
|
||||
#define SCSI_OP_WRITE_BUFFER 0x3b
|
||||
#define SCSI_OP_READ_BUFFER 0x3c
|
||||
#define SCSI_OP_CHANGE_DEFINITION 0x40
|
||||
#define SCSI_OP_WRITE_SAME_10 0x41
|
||||
#define SCSI_OP_UNMAP 0x42
|
||||
#define SCSI_OP_READ_SUB_CHANNEL 0x42
|
||||
#define SCSI_OP_READ_TOC 0x43
|
||||
#define SCSI_OP_PLAY_MSF 0x47
|
||||
@@ -457,7 +459,38 @@ typedef struct scsi_cmd_wsame_16 {
|
||||
);
|
||||
uint8 control;
|
||||
} _PACKED scsi_cmd_wsame_16;
|
||||
|
||||
|
||||
|
||||
// UNMAP
|
||||
|
||||
typedef struct scsi_cmd_unmap {
|
||||
uint8 opcode;
|
||||
LBITFIELD8_2(
|
||||
anchor : 1,
|
||||
_reserved1_7 : 7
|
||||
);
|
||||
uint32 _reserved1;
|
||||
LBITFIELD8_2(
|
||||
group_number : 5,
|
||||
_reserved5_7 : 3
|
||||
);
|
||||
uint16 length;
|
||||
uint8 control;
|
||||
} _PACKED scsi_cmd_unmap;
|
||||
|
||||
struct scsi_unmap_block_descriptor {
|
||||
uint64 lba;
|
||||
uint32 block_count;
|
||||
uint32 _reserved1;
|
||||
} _PACKED;
|
||||
|
||||
struct scsi_unmap_parameter_list {
|
||||
uint16 data_length;
|
||||
uint16 block_data_length;
|
||||
uint32 _reserved1;
|
||||
struct scsi_unmap_block_descriptor blocks[1];
|
||||
} _PACKED;
|
||||
|
||||
|
||||
// REQUEST SENSE
|
||||
|
||||
|
||||
@@ -72,6 +72,10 @@ typedef struct scsi_periph_callbacks {
|
||||
void (*media_changed)(periph_device_cookie cookie, scsi_ccb *request);
|
||||
} scsi_periph_callbacks;
|
||||
|
||||
typedef struct scsi_block_range {
|
||||
uint64 offset;
|
||||
uint64 size;
|
||||
} scsi_block_range;
|
||||
|
||||
// functions provided by this module
|
||||
typedef struct scsi_periph_interface {
|
||||
@@ -119,7 +123,7 @@ typedef struct scsi_periph_interface {
|
||||
err_res (*synchronize_cache)(scsi_periph_device device, scsi_ccb *request);
|
||||
|
||||
status_t (*trim_device)(scsi_periph_device_info *device, scsi_ccb *request,
|
||||
uint64 offset, uint64 numBlocks);
|
||||
scsi_block_range* ranges, uint32 rangeCount);
|
||||
|
||||
// *** removable media ***
|
||||
// to be called when a medium change is detected to block subsequent commands
|
||||
|
||||
Reference in New Issue
Block a user