From e62e6bd5a7b9cddcfcd72bdccf9653bb8b376cc1 Mon Sep 17 00:00:00 2001 From: "Bruno G. Albuquerque" Date: Wed, 17 Jan 2007 01:39:59 +0000 Subject: [PATCH] Implemented support for hardware cache flush. This is based on code I originally did for yellowTAB GmbH when I worked for then and is being used under permission. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@19840 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- .../build/os/drivers/bus/scsi/scsi_periph.h | 4 +- headers/os/drivers/bus/scsi/scsi_cmds.h | 17 +++++++ headers/os/drivers/bus/scsi/scsi_periph.h | 4 +- .../drivers/disk/scsi/scsi_dsk/scsi_dsk.c | 21 +++++++++ .../kernel/generic/scsi_periph/Jamfile | 1 + .../kernel/generic/scsi_periph/scsi_periph.c | 4 +- .../generic/scsi_periph/scsi_periph_int.h | 5 ++ src/add-ons/kernel/generic/scsi_periph/sync.c | 47 +++++++++++++++++++ src/apps/midiplayer/MidiPlayer.rdef | 4 +- src/apps/people/People.rdef | 8 ++-- src/apps/showimage/ShowImage.rdef | 8 ++-- src/apps/soundrecorder/SoundRecorder.rdef | 4 +- 12 files changed, 112 insertions(+), 15 deletions(-) create mode 100644 src/add-ons/kernel/generic/scsi_periph/sync.c diff --git a/headers/build/os/drivers/bus/scsi/scsi_periph.h b/headers/build/os/drivers/bus/scsi/scsi_periph.h index a836a6c895..8c826984bd 100644 --- a/headers/build/os/drivers/bus/scsi/scsi_periph.h +++ b/headers/build/os/drivers/bus/scsi/scsi_periph.h @@ -154,7 +154,9 @@ typedef struct scsi_periph_interface { // fill data with icon (for B_GET_ICON ioctl) status_t (*get_icon)( icon_type type, device_icon *data ); - + + // synchronizes (flush) the device cache + err_res(*synchronize_cache)(scsi_periph_device device, scsi_ccb *request); } scsi_periph_interface; #define SCSI_PERIPH_MODULE_NAME "generic/scsi_periph/v1" diff --git a/headers/os/drivers/bus/scsi/scsi_cmds.h b/headers/os/drivers/bus/scsi/scsi_cmds.h index 7b8ebf2a54..ed1b83ef8c 100644 --- a/headers/os/drivers/bus/scsi/scsi_cmds.h +++ b/headers/os/drivers/bus/scsi/scsi_cmds.h @@ -1023,4 +1023,21 @@ enum { // and Mechanism status page } scsi_read_cd_sub_channel_selection; +// SYNCHRONIZE CACHE (10) + +typedef struct scsi_cmd_sync_cache { + uint8 opcode; + LBITFIELD8_4( + RelAddr : 1, + immed : 1, // 1 - return immediately, 0 - return on completion + res1_1 : 3, + LUN : 3 + ); + scsi_cd_lba lba; + uint8 res2; + uint8 nblocks_high; + uint8 nblocks_low; + uint8 control; +} scsi_cmd_sync_cache; + #endif diff --git a/headers/os/drivers/bus/scsi/scsi_periph.h b/headers/os/drivers/bus/scsi/scsi_periph.h index a836a6c895..529a9abd45 100644 --- a/headers/os/drivers/bus/scsi/scsi_periph.h +++ b/headers/os/drivers/bus/scsi/scsi_periph.h @@ -154,7 +154,9 @@ typedef struct scsi_periph_interface { // fill data with icon (for B_GET_ICON ioctl) status_t (*get_icon)( icon_type type, device_icon *data ); - + + // synchronizes (flush) the device cache + err_res(*synchronize_cache)(scsi_periph_device device, scsi_ccb *request); } scsi_periph_interface; #define SCSI_PERIPH_MODULE_NAME "generic/scsi_periph/v1" diff --git a/src/add-ons/kernel/drivers/disk/scsi/scsi_dsk/scsi_dsk.c b/src/add-ons/kernel/drivers/disk/scsi/scsi_dsk/scsi_dsk.c index 09a7dd824e..6f72dc08f3 100644 --- a/src/add-ons/kernel/drivers/disk/scsi/scsi_dsk/scsi_dsk.c +++ b/src/add-ons/kernel/drivers/disk/scsi/scsi_dsk/scsi_dsk.c @@ -130,6 +130,23 @@ load_eject(das_device_info *device, bool load) } +static status_t +synchronize_cache(das_device_info *device) +{ + scsi_ccb *ccb; + err_res res; + + SHOW_FLOW0( 0, "" ); + + ccb = device->scsi->alloc_ccb(device->scsi_device); + + res = scsi_periph->synchronize_cache(device->scsi_periph_device, ccb); + + device->scsi->free_ccb(ccb); + + return res.error_code; +} + static int log2(uint32 x) { @@ -214,6 +231,10 @@ das_ioctl(das_handle_info *handle, int op, void *buf, size_t len) res = load_eject(device, true); break; + case B_FLUSH_DRIVE_CACHE: + res = synchronize_cache(device); + break; + default: res = scsi_periph->ioctl(handle->scsi_periph_handle, op, buf, len); } diff --git a/src/add-ons/kernel/generic/scsi_periph/Jamfile b/src/add-ons/kernel/generic/scsi_periph/Jamfile index 990b6db292..ababbdb06b 100644 --- a/src/add-ons/kernel/generic/scsi_periph/Jamfile +++ b/src/add-ons/kernel/generic/scsi_periph/Jamfile @@ -16,4 +16,5 @@ KernelAddon scsi_periph : io.c removable.c scsi_periph.c + sync.c ; diff --git a/src/add-ons/kernel/generic/scsi_periph/scsi_periph.c b/src/add-ons/kernel/generic/scsi_periph/scsi_periph.c index b03d10f2d7..f7e63f7721 100644 --- a/src/add-ons/kernel/generic/scsi_periph/scsi_periph.c +++ b/src/add-ons/kernel/generic/scsi_periph/scsi_periph.c @@ -161,7 +161,9 @@ scsi_periph_interface scsi_periph_module = { periph_get_media_status, periph_compose_device_name, - periph_get_icon + periph_get_icon, + + periph_synchronize_cache }; scsi_periph_interface *modules[] = { diff --git a/src/add-ons/kernel/generic/scsi_periph/scsi_periph_int.h b/src/add-ons/kernel/generic/scsi_periph/scsi_periph_int.h index a295679054..916377b18f 100644 --- a/src/add-ons/kernel/generic/scsi_periph/scsi_periph_int.h +++ b/src/add-ons/kernel/generic/scsi_periph/scsi_periph_int.h @@ -109,4 +109,9 @@ status_t periph_simple_exec(scsi_periph_device_info *device, void *cdb, status_t periph_get_icon(icon_type type, device_icon *data); +// sync.c + +err_res periph_synchronize_cache(scsi_periph_device_info *device, + scsi_ccb *request); + #endif /* __SCSI_PERIPH_INT_H__ */ diff --git a/src/add-ons/kernel/generic/scsi_periph/sync.c b/src/add-ons/kernel/generic/scsi_periph/sync.c new file mode 100644 index 0000000000..acce02cc0e --- /dev/null +++ b/src/add-ons/kernel/generic/scsi_periph/sync.c @@ -0,0 +1,47 @@ +/* + * Copyright 2007, Haiku, Inc. All Rights Reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Bruno Albuquerque, bga@bug-br.org.br + * + * Copyright 2004-2006 yellowTAB GMbH. This file is + * based on work I did for ZETA while employed by + * yellowTAB and is used under permission. + * + */ + +#include "scsi_periph_int.h" + +#include + +#include + +err_res +periph_synchronize_cache(scsi_periph_device_info *device, scsi_ccb *request) +{ + scsi_cmd_sync_cache* cmd = (scsi_cmd_sync_cache*)request->cdb; + + request->flags = SCSI_DIR_NONE; + + request->data = NULL; + request->sg_list = NULL; + request->data_len = 0; + request->timeout = device->std_timeout; + request->sort = -1; + + memset(cmd, 0, sizeof(*cmd)); + + cmd->opcode = SCSI_OP_SYNCHRONIZE_CACHE; + cmd->immed = 0; + + // TODO(bga): Maybe we will actually want to set those one day... + cmd->nblocks_high = 0; + cmd->nblocks_low = 0; + + request->cdb_len = sizeof(*cmd); + + device->scsi->sync_io(request); + + return periph_check_error(device, request); +} diff --git a/src/apps/midiplayer/MidiPlayer.rdef b/src/apps/midiplayer/MidiPlayer.rdef index 94a0c6ed4a..c021683f15 100644 --- a/src/apps/midiplayer/MidiPlayer.rdef +++ b/src/apps/midiplayer/MidiPlayer.rdef @@ -11,12 +11,12 @@ resource app_version { long_info = "MidiPlayer ©2004-2007 Haiku, Inc." }; +resource app_flags B_SINGLE_LAUNCH; + resource file_types message { "types" = "audio/x-midi" }; -resource app_flags B_SINGLE_LAUNCH; - resource large_icon array { $"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" $"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" diff --git a/src/apps/people/People.rdef b/src/apps/people/People.rdef index 98403fb667..cc876d204c 100644 --- a/src/apps/people/People.rdef +++ b/src/apps/people/People.rdef @@ -1,10 +1,6 @@ resource(1, "BEOS:APP_SIG") #'MIMS' "application/x-vnd.Be-PEPL"; -resource(1, "BEOS:FILE_TYPES") message { - "types" = "application/x-person" -}; - resource app_version { major = 1, middle = 0, @@ -19,6 +15,10 @@ resource app_version { resource app_flags B_SINGLE_LAUNCH; +resource(1, "BEOS:FILE_TYPES") message { + "types" = "application/x-person" +}; + #ifdef HAIKU_TARGET_PLATFORM_HAIKU resource vector_icon { diff --git a/src/apps/showimage/ShowImage.rdef b/src/apps/showimage/ShowImage.rdef index 846c06c4c6..2bebecf957 100644 --- a/src/apps/showimage/ShowImage.rdef +++ b/src/apps/showimage/ShowImage.rdef @@ -4,10 +4,6 @@ resource app_signature "application/x-vnd.Haiku-ShowImage"; -resource file_types message { - "types" = "image" -}; - resource app_version { major = 0, middle = 0, @@ -22,6 +18,10 @@ resource app_version { resource app_flags B_SINGLE_LAUNCH; +resource file_types message { + "types" = "image" +}; + #ifdef HAIKU_TARGET_PLATFORM_HAIKU resource vector_icon { diff --git a/src/apps/soundrecorder/SoundRecorder.rdef b/src/apps/soundrecorder/SoundRecorder.rdef index 14acd4b3de..7e16623569 100644 --- a/src/apps/soundrecorder/SoundRecorder.rdef +++ b/src/apps/soundrecorder/SoundRecorder.rdef @@ -11,6 +11,8 @@ resource app_version { long_info = "SoundRecorder ©2005-2007 Haiku, Inc." }; +resource app_flags B_SINGLE_LAUNCH; + resource file_types message { "types" = "audio/basic", "types" = "audio/x-wav", @@ -22,8 +24,6 @@ resource file_types message { "types" = "audio/riff" }; -resource app_flags B_SINGLE_LAUNCH; - #ifdef HAIKU_TARGET_PLATFORM_HAIKU resource vector_icon {