This gets the trim command as WRITE SAME operation to SCSI
* Neither hardware nor driver to test it; AHCI/IDE support is next on the table.
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2004-2008, Haiku, Inc. All RightsReserved.
|
* Copyright 2004-2013, Haiku, Inc. All RightsReserved.
|
||||||
* Copyright 2002/03, Thomas Kurschel. All rights reserved.
|
* Copyright 2002/03, Thomas Kurschel. All rights reserved.
|
||||||
*
|
*
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
@@ -7,6 +7,7 @@
|
|||||||
#ifndef _SCSI_PERIPH_H
|
#ifndef _SCSI_PERIPH_H
|
||||||
#define _SCSI_PERIPH_H
|
#define _SCSI_PERIPH_H
|
||||||
|
|
||||||
|
|
||||||
/*! Use this module to minimize work required to write a SCSI
|
/*! Use this module to minimize work required to write a SCSI
|
||||||
peripheral driver.
|
peripheral driver.
|
||||||
|
|
||||||
@@ -114,6 +115,12 @@ typedef struct scsi_periph_interface {
|
|||||||
// request - ccb for this device; is used to talk to device
|
// request - ccb for this device; is used to talk to device
|
||||||
status_t (*check_capacity)(scsi_periph_device device, scsi_ccb *request);
|
status_t (*check_capacity)(scsi_periph_device device, scsi_ccb *request);
|
||||||
|
|
||||||
|
// synchronizes (flush) the device cache
|
||||||
|
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);
|
||||||
|
|
||||||
// *** removable media ***
|
// *** removable media ***
|
||||||
// to be called when a medium change is detected to block subsequent commands
|
// to be called when a medium change is detected to block subsequent commands
|
||||||
void (*media_changed)(scsi_periph_device device);
|
void (*media_changed)(scsi_periph_device device);
|
||||||
@@ -128,8 +135,6 @@ typedef struct scsi_periph_interface {
|
|||||||
// returns: B_OK, B_DEV_MEDIA_CHANGE_REQUESTED, B_NO_MEMORY or
|
// returns: B_OK, B_DEV_MEDIA_CHANGE_REQUESTED, B_NO_MEMORY or
|
||||||
// pending error reported by handle_get_error
|
// pending error reported by handle_get_error
|
||||||
status_t (*get_media_status)(scsi_periph_handle handle);
|
status_t (*get_media_status)(scsi_periph_handle handle);
|
||||||
// synchronizes (flush) the device cache
|
|
||||||
err_res(*synchronize_cache)(scsi_periph_device device, scsi_ccb *request);
|
|
||||||
|
|
||||||
// compose device name consisting of prefix and path/target/LUN
|
// compose device name consisting of prefix and path/target/LUN
|
||||||
// (result must be freed by caller)
|
// (result must be freed by caller)
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2008-2012, Axel Dörfler, [email protected].
|
* Copyright 2008-2013, Axel Dörfler, [email protected].
|
||||||
* Copyright 2002/03, Thomas Kurschel. All rights reserved.
|
* Copyright 2002/03, Thomas Kurschel. All rights reserved.
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
/*! Peripheral driver to handle any kind of SCSI disks,
|
/*! Peripheral driver to handle any kind of SCSI disks,
|
||||||
i.e. hard disk and floopy disks (ZIP etc.)
|
i.e. hard disk and floopy disks (ZIP etc.)
|
||||||
|
|
||||||
@@ -93,7 +94,6 @@ get_geometry(das_handle* handle, device_geometry* geometry)
|
|||||||
if (status != B_OK)
|
if (status != B_OK)
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
|
|
||||||
devfs_compute_geometry_size(geometry, info->capacity, info->block_size);
|
devfs_compute_geometry_size(geometry, info->capacity, info->block_size);
|
||||||
|
|
||||||
geometry->device_type = B_DISK;
|
geometry->device_type = B_DISK;
|
||||||
@@ -153,6 +153,24 @@ synchronize_cache(das_driver_info *device)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static status_t
|
||||||
|
trim_device(das_driver_info* device, off_t offset, off_t size)
|
||||||
|
{
|
||||||
|
TRACE("trim_device()\n");
|
||||||
|
|
||||||
|
scsi_ccb* request = device->scsi->alloc_ccb(device->scsi_device);
|
||||||
|
if (request == NULL)
|
||||||
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
|
status_t status = sSCSIPeripheral->trim_device(device->scsi_periph_device,
|
||||||
|
request, offset / device->block_size, size / device->block_size);
|
||||||
|
|
||||||
|
device->scsi->free_ccb(request);
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
log2(uint32 x)
|
log2(uint32 x)
|
||||||
{
|
{
|
||||||
@@ -385,6 +403,21 @@ das_ioctl(void* cookie, uint32 op, void* buffer, size_t length)
|
|||||||
case B_FLUSH_DRIVE_CACHE:
|
case B_FLUSH_DRIVE_CACHE:
|
||||||
return synchronize_cache(info);
|
return synchronize_cache(info);
|
||||||
|
|
||||||
|
case B_TRIM_DEVICE:
|
||||||
|
{
|
||||||
|
fs_trim_data trimData;
|
||||||
|
if (user_memcpy(&trimData, buffer, sizeof(fs_trim_data)) != B_OK)
|
||||||
|
return B_BAD_ADDRESS;
|
||||||
|
|
||||||
|
status_t status = trim_device(info, trimData.offset, trimData.size);
|
||||||
|
if (status != B_OK)
|
||||||
|
return status;
|
||||||
|
|
||||||
|
trimData.trimmed_size = trimData.size;
|
||||||
|
|
||||||
|
return user_memcpy(buffer, &trimData, sizeof(fs_trim_data));
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return sSCSIPeripheral->ioctl(handle->scsi_periph_handle, op,
|
return sSCSIPeripheral->ioctl(handle->scsi_periph_handle, op,
|
||||||
buffer, length);
|
buffer, length);
|
||||||
@@ -649,7 +682,7 @@ struct driver_module_info sSCSIDiskDriver = {
|
|||||||
das_init_driver,
|
das_init_driver,
|
||||||
das_uninit_driver,
|
das_uninit_driver,
|
||||||
das_register_child_devices,
|
das_register_child_devices,
|
||||||
das_rescan_child_devices,
|
das_rescan_child_devices,
|
||||||
NULL, // removed
|
NULL, // removed
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2004-2011, Haiku, Inc. All RightsReserved.
|
* Copyright 2004-2013, Haiku, Inc. All RightsReserved.
|
||||||
* Copyright 2002-2003, Thomas Kurschel. All rights reserved.
|
* Copyright 2002-2003, Thomas Kurschel. All rights reserved.
|
||||||
*
|
*
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
//! Handling of block device (currently, only a capacity check is provided)
|
//! Handling of block device
|
||||||
|
|
||||||
|
|
||||||
#include "scsi_periph_int.h"
|
#include "scsi_periph_int.h"
|
||||||
@@ -59,10 +59,10 @@ periph_check_capacity(scsi_periph_device_info *device, scsi_ccb *request)
|
|||||||
|
|
||||||
if (capacity == UINT_MAX) {
|
if (capacity == UINT_MAX) {
|
||||||
mutex_unlock(&device->mutex);
|
mutex_unlock(&device->mutex);
|
||||||
|
|
||||||
scsi_cmd_read_capacity_long *cmd
|
scsi_cmd_read_capacity_long *cmd
|
||||||
= (scsi_cmd_read_capacity_long *)request->cdb;
|
= (scsi_cmd_read_capacity_long *)request->cdb;
|
||||||
|
|
||||||
scsi_res_read_capacity_long capacityLongResult;
|
scsi_res_read_capacity_long capacityLongResult;
|
||||||
request->data = (uint8*)&capacityLongResult;
|
request->data = (uint8*)&capacityLongResult;
|
||||||
request->data_length = sizeof(capacityLongResult);
|
request->data_length = sizeof(capacityLongResult);
|
||||||
@@ -114,3 +114,42 @@ periph_check_capacity(scsi_periph_device_info *device, scsi_ccb *request)
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
periph_trim_device(scsi_periph_device_info *device, scsi_ccb *request,
|
||||||
|
uint64 offset, uint64 numBlocks)
|
||||||
|
{
|
||||||
|
err_res res;
|
||||||
|
int retries = 0;
|
||||||
|
|
||||||
|
do {
|
||||||
|
request->flags = SCSI_DIR_OUT;
|
||||||
|
request->sort = offset;
|
||||||
|
request->timeout = device->std_timeout;
|
||||||
|
|
||||||
|
scsi_cmd_wsame_16* cmd = (scsi_cmd_wsame_16*)request->cdb;
|
||||||
|
|
||||||
|
memset(cmd, 0, sizeof(*cmd));
|
||||||
|
cmd->opcode = SCSI_OP_WRITE_SAME_16;
|
||||||
|
cmd->unmap = 1;
|
||||||
|
cmd->lba = B_HOST_TO_BENDIAN_INT64(offset);
|
||||||
|
cmd->length = B_HOST_TO_BENDIAN_INT32(numBlocks);
|
||||||
|
|
||||||
|
request->cdb_length = sizeof(*cmd);
|
||||||
|
|
||||||
|
device->scsi->async_io(request);
|
||||||
|
|
||||||
|
acquire_sem(request->completion_sem);
|
||||||
|
|
||||||
|
// ask generic peripheral layer what to do now
|
||||||
|
res = periph_check_error(device, request);
|
||||||
|
} while ((res.action == err_act_retry && retries++ < 3)
|
||||||
|
|| (res.action == err_act_many_retries && retries++ < 30));
|
||||||
|
|
||||||
|
// peripheral layer only creates "read" error
|
||||||
|
if (res.error_code == B_DEV_READ_ERROR)
|
||||||
|
return B_DEV_WRITE_ERROR;
|
||||||
|
|
||||||
|
return res.error_code;
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2004-2008, Haiku, Inc. All RightsReserved.
|
* Copyright 2004-2013, Haiku, Inc. All RightsReserved.
|
||||||
* Copyright 2002-2003, Thomas Kurschel. All rights reserved.
|
* Copyright 2002-2003, Thomas Kurschel. All rights reserved.
|
||||||
*
|
*
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
@@ -135,12 +135,13 @@ static scsi_periph_interface sSCSIPeripheralModule = {
|
|||||||
periph_io,
|
periph_io,
|
||||||
periph_ioctl,
|
periph_ioctl,
|
||||||
periph_check_capacity,
|
periph_check_capacity,
|
||||||
|
periph_synchronize_cache,
|
||||||
|
periph_trim_device,
|
||||||
|
|
||||||
periph_media_changed_public,
|
periph_media_changed_public,
|
||||||
periph_check_error,
|
periph_check_error,
|
||||||
periph_send_start_stop,
|
periph_send_start_stop,
|
||||||
periph_get_media_status,
|
periph_get_media_status,
|
||||||
periph_synchronize_cache,
|
|
||||||
|
|
||||||
periph_compose_device_name
|
periph_compose_device_name
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2004-2008, Haiku, Inc. All Rights Reserved.
|
* Copyright 2004-2013, Haiku, Inc. All Rights Reserved.
|
||||||
* Copyright 2002, Thomas Kurschel. All rights reserved.
|
* Copyright 2002, Thomas Kurschel. All rights reserved.
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
@@ -77,6 +77,8 @@ status_t periph_handle_free(scsi_periph_handle_info *handle);
|
|||||||
// block.c
|
// block.c
|
||||||
|
|
||||||
status_t periph_check_capacity(scsi_periph_device_info *device, scsi_ccb *ccb);
|
status_t periph_check_capacity(scsi_periph_device_info *device, scsi_ccb *ccb);
|
||||||
|
status_t periph_trim_device(scsi_periph_device_info *device, scsi_ccb *request,
|
||||||
|
uint64 offset, uint64 numBlocks);
|
||||||
|
|
||||||
|
|
||||||
// device.c
|
// device.c
|
||||||
|
|||||||
Reference in New Issue
Block a user