- fixed warnings, produced by Haiku version of gcc;
- space-based indentations replaced with tab-based; - a bit of cleanup; git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@18782 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -1,7 +1,14 @@
|
|||||||
/*
|
/**
|
||||||
* Copyright (c) 2003-2005 by Siarzhuk Zharski <[email protected]>
|
*
|
||||||
* Distributed under the terms of the BSD License.
|
* TODO: description
|
||||||
*
|
*
|
||||||
|
* This file is a part of USB SCSI CAM for Haiku OS.
|
||||||
|
* May be used under terms of the MIT License
|
||||||
|
*
|
||||||
|
* Author(s):
|
||||||
|
* Siarzhuk Zharski <[email protected]>
|
||||||
|
*
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
#include "usb_scsi.h"
|
#include "usb_scsi.h"
|
||||||
|
|
||||||
@@ -12,77 +19,77 @@
|
|||||||
#include "fake_device.h"
|
#include "fake_device.h"
|
||||||
|
|
||||||
/* duplication! Hope this fake file will be not required in Haiku version*/
|
/* duplication! Hope this fake file will be not required in Haiku version*/
|
||||||
#define INQ_VENDOR_LEN 0x08
|
#define INQ_VENDOR_LEN 0x08
|
||||||
#define INQ_PRODUCT_LEN 0x10
|
#define INQ_PRODUCT_LEN 0x10
|
||||||
#define INQ_REVISION_LEN 0x04
|
#define INQ_REVISION_LEN 0x04
|
||||||
|
|
||||||
|
|
||||||
void fake_inquiry_request(usb_device_info *udi, CCB_SCSIIO *ccbio)
|
void fake_inquiry_request(usb_device_info *udi, CCB_SCSIIO *ccbio)
|
||||||
{
|
{
|
||||||
uint8 *data = ccbio->cam_data_ptr;
|
uint8 *data = ccbio->cam_data_ptr;
|
||||||
if(ccbio->cam_ch.cam_flags & CAM_SCATTER_VALID){
|
if(ccbio->cam_ch.cam_flags & CAM_SCATTER_VALID){
|
||||||
TRACE_ALWAYS("fake_inquiry: problems!!! scatter gatter ....=-(\n");
|
TRACE_ALWAYS("fake_inquiry: problems!!! scatter gatter ....=-(\n");
|
||||||
} else {
|
} else {
|
||||||
memset(data, 0, ccbio->cam_dxfer_len);
|
memset(data, 0, ccbio->cam_dxfer_len);
|
||||||
/* data[0] = 0x1F;*/ /* we can play here with type of device */
|
/* data[0] = 0x1F;*/ /* we can play here with type of device */
|
||||||
data[1] = 0x80;
|
data[1] = 0x80;
|
||||||
data[2] = 0x02;
|
data[2] = 0x02;
|
||||||
data[3] = 0x02;
|
data[3] = 0x02;
|
||||||
data[4] = (0 != udi) ? 5 : 31; /* udi != 0 - mean FIX_NO_INQUIRY */
|
data[4] = (0 != udi) ? 5 : 31; /* udi != 0 - mean FIX_NO_INQUIRY */
|
||||||
if(ccbio->cam_dxfer_len >= 0x24){
|
if(ccbio->cam_dxfer_len >= 0x24){
|
||||||
strncpy(&data[8], "USB SCSI", INQ_VENDOR_LEN);
|
strncpy(&data[8], "USB SCSI", INQ_VENDOR_LEN);
|
||||||
strncpy(&data[16], "Reserved", INQ_PRODUCT_LEN);
|
strncpy(&data[16], "Reserved", INQ_PRODUCT_LEN);
|
||||||
strncpy(&data[32], "N/A", INQ_REVISION_LEN);
|
strncpy(&data[32], "N/A", INQ_REVISION_LEN);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void fake_test_unit_ready_request(CCB_SCSIIO *ccbio)
|
void fake_test_unit_ready_request(CCB_SCSIIO *ccbio)
|
||||||
{
|
{
|
||||||
if(ccbio->cam_sense_ptr != NULL){
|
if(ccbio->cam_sense_ptr != NULL){
|
||||||
scsi_sense_data *sense_data = (scsi_sense_data *)ccbio->cam_sense_ptr;
|
scsi_sense_data *sense_data = (scsi_sense_data *)ccbio->cam_sense_ptr;
|
||||||
memset(sense_data, 0, ccbio->cam_sense_len);
|
memset(sense_data, 0, ccbio->cam_sense_len);
|
||||||
sense_data->error_code = SSD_CURRENT_ERROR;
|
sense_data->error_code = SSD_CURRENT_ERROR;
|
||||||
sense_data->flags = SSD_KEY_NOT_READY;
|
sense_data->flags = SSD_KEY_NOT_READY;
|
||||||
ccbio->cam_ch.cam_status = CAM_REQ_CMP_ERR | CAM_AUTOSNS_VALID;
|
ccbio->cam_ch.cam_status = CAM_REQ_CMP_ERR | CAM_AUTOSNS_VALID;
|
||||||
ccbio->cam_scsi_status = SCSI_STATUS_CHECK_CONDITION;
|
ccbio->cam_scsi_status = SCSI_STATUS_CHECK_CONDITION;
|
||||||
} else {
|
} else {
|
||||||
ccbio->cam_ch.cam_status = CAM_REQ_CMP_ERR;
|
ccbio->cam_ch.cam_status = CAM_REQ_CMP_ERR;
|
||||||
ccbio->cam_scsi_status = SCSI_STATUS_OK;
|
ccbio->cam_scsi_status = SCSI_STATUS_OK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
\fn:fake_scsi_io
|
\fn:fake_scsi_io
|
||||||
\param ccbio: ????
|
\param ccbio: ????
|
||||||
\return: ???
|
\return: ???
|
||||||
|
|
||||||
xpt_scsi_io - handle XPT_SCSI_IO sim action
|
xpt_scsi_io - handle XPT_SCSI_IO sim action
|
||||||
*/
|
*/
|
||||||
status_t fake_scsi_io(CCB_SCSIIO *ccbio)
|
status_t fake_scsi_io(CCB_SCSIIO *ccbio)
|
||||||
{
|
{
|
||||||
status_t status = B_BAD_VALUE;
|
status_t status = B_BAD_VALUE;
|
||||||
uint8 *cmd;
|
uint8 *cmd;
|
||||||
scsi_cmd_generic *command;
|
scsi_cmd_generic *command;
|
||||||
if(ccbio->cam_ch.cam_flags & CAM_CDB_POINTER){
|
if(ccbio->cam_ch.cam_flags & CAM_CDB_POINTER){
|
||||||
cmd = ccbio->cam_cdb_io.cam_cdb_ptr;
|
cmd = ccbio->cam_cdb_io.cam_cdb_ptr;
|
||||||
}else{
|
}else{
|
||||||
cmd = ccbio->cam_cdb_io.cam_cdb_bytes;
|
cmd = ccbio->cam_cdb_io.cam_cdb_bytes;
|
||||||
}
|
}
|
||||||
command = (scsi_cmd_generic *)cmd;
|
command = (scsi_cmd_generic *)cmd;
|
||||||
switch(command->opcode){
|
switch(command->opcode){
|
||||||
case TEST_UNIT_READY:{
|
case TEST_UNIT_READY:{
|
||||||
fake_test_unit_ready_request(ccbio);
|
fake_test_unit_ready_request(ccbio);
|
||||||
status = B_OK;
|
status = B_OK;
|
||||||
}break;
|
}break;
|
||||||
case INQUIRY:{
|
case INQUIRY:{
|
||||||
fake_inquiry_request(NULL, ccbio);
|
fake_inquiry_request(NULL, ccbio);
|
||||||
ccbio->cam_ch.cam_status = CAM_REQ_CMP;
|
ccbio->cam_ch.cam_status = CAM_REQ_CMP;
|
||||||
status = B_OK;
|
status = B_OK;
|
||||||
}break;
|
}break;
|
||||||
default:
|
default:
|
||||||
ccbio->cam_ch.cam_status = CAM_REQ_INVALID;
|
ccbio->cam_ch.cam_status = CAM_REQ_INVALID;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,13 +1,20 @@
|
|||||||
/*
|
/**
|
||||||
* Copyright (c) 2003-2005 by Siarzhuk Zharski <[email protected]>
|
*
|
||||||
* Distributed under the terms of the BSD License.
|
* TODO: description
|
||||||
*
|
*
|
||||||
|
* This file is a part of USB SCSI CAM for Haiku OS.
|
||||||
|
* May be used under terms of the MIT License
|
||||||
|
*
|
||||||
|
* Author(s):
|
||||||
|
* Siarzhuk Zharski <[email protected]>
|
||||||
|
*
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
#ifndef _FAKE_DEVICE_H_
|
#ifndef _FAKE_DEVICE_H_
|
||||||
#define _FAKE_DEVICE_H_
|
#define _FAKE_DEVICE_H_
|
||||||
|
|
||||||
void fake_inquiry_request(usb_device_info *udi, CCB_SCSIIO *ccbio);
|
void fake_inquiry_request(usb_device_info *udi, CCB_SCSIIO *ccbio);
|
||||||
void fake_test_unit_ready_request(CCB_SCSIIO *ccbio);
|
void fake_test_unit_ready_request(CCB_SCSIIO *ccbio);
|
||||||
status_t fake_scsi_io(CCB_SCSIIO *ccbio);
|
status_t fake_scsi_io(CCB_SCSIIO *ccbio);
|
||||||
|
|
||||||
#endif /* _FAKE_DEVICE_H_ */
|
#endif /* _FAKE_DEVICE_H_ */
|
||||||
|
|||||||
@@ -1,39 +1,45 @@
|
|||||||
/*
|
/**
|
||||||
* Copyright (c) 2003-2005 by Siarzhuk Zharski <[email protected]>
|
*
|
||||||
* Distributed under the terms of the BSD License.
|
* TODO: description
|
||||||
*
|
*
|
||||||
|
* This file is a part of USB SCSI CAM for Haiku OS.
|
||||||
|
* May be used under terms of the MIT License
|
||||||
|
*
|
||||||
|
* Author(s):
|
||||||
|
* Siarzhuk Zharski <[email protected]>
|
||||||
|
*
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** driver settings support implementation */
|
/** driver settings support implementation */
|
||||||
|
|
||||||
#include "usb_scsi.h"
|
#include "usb_scsi.h"
|
||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
//#include "proto_common.h"
|
//#include "proto_common.h"
|
||||||
|
|
||||||
#include <stdlib.h> /* strtoul */
|
#include <stdlib.h> /* strtoul */
|
||||||
#include <strings.h> /* strncpy */
|
#include <strings.h> /* strncpy */
|
||||||
#include <driver_settings.h>
|
#include <driver_settings.h>
|
||||||
#include "tracing.h"
|
#include "tracing.h"
|
||||||
|
|
||||||
#define DEF_DEVS 2 /**< default amount of reserved devices */
|
#define DEF_DEVS 2 /**< default amount of reserved devices */
|
||||||
#define S_DEF_DEVS "2" /**< default amount of reserved devices */
|
#define S_DEF_DEVS "2" /**< default amount of reserved devices */
|
||||||
#define DEF_LUNS 4 /**< default amount of reserved LUNs */
|
#define DEF_LUNS 4 /**< default amount of reserved LUNs */
|
||||||
#define S_DEF_LUNS "4" /**< default amount of reserved LUNs */
|
#define S_DEF_LUNS "4" /**< default amount of reserved LUNs */
|
||||||
/** count of device entries, to be reserved for fake devices */
|
/** count of device entries, to be reserved for fake devices */
|
||||||
int reserved_devices = DEF_DEVS;
|
int reserved_devices = DEF_DEVS;
|
||||||
/** count of Logical Unit Numbers, to be reserved for fake devices */
|
/** count of Logical Unit Numbers, to be reserved for fake devices */
|
||||||
int reserved_luns = DEF_LUNS;
|
int reserved_luns = DEF_LUNS;
|
||||||
|
|
||||||
bool b_reservation_on = true;
|
bool b_reservation_on = true;
|
||||||
bool b_ignore_sysinit2 = false;
|
bool b_ignore_sysinit2 = false;
|
||||||
/**
|
/**
|
||||||
support of some kind rudimentary "quick" search. Indexes in
|
support of some kind rudimentary "quick" search. Indexes in
|
||||||
settings_keys array.
|
settings_keys array.
|
||||||
*/
|
*/
|
||||||
enum SKKeys{
|
enum SKKeys{
|
||||||
skkVendor = 0,
|
skkVendor = 0,
|
||||||
skkDevice,
|
skkDevice,
|
||||||
// skkName,
|
// skkName,
|
||||||
// skkTransport,
|
// skkTransport,
|
||||||
skkProtocol,
|
skkProtocol,
|
||||||
skkCommandSet,
|
skkCommandSet,
|
||||||
@@ -45,296 +51,291 @@ enum SKKeys{
|
|||||||
skkNoPreventMedia,
|
skkNoPreventMedia,
|
||||||
skkUseModeSense10,
|
skkUseModeSense10,
|
||||||
skkForceReadOnly,
|
skkForceReadOnly,
|
||||||
skkProtoBulk,
|
skkProtoBulk,
|
||||||
skkProtoCB,
|
skkProtoCB,
|
||||||
skkProtoCBI,
|
skkProtoCBI,
|
||||||
// skkProtoFreecom,
|
// skkProtoFreecom,
|
||||||
skkCmdSetSCSI,
|
skkCmdSetSCSI,
|
||||||
skkCmdSetUFI,
|
skkCmdSetUFI,
|
||||||
skkCmdSetATAPI,
|
skkCmdSetATAPI,
|
||||||
skkCmdSetRBC,
|
skkCmdSetRBC,
|
||||||
skkCmdSetQIC157,
|
skkCmdSetQIC157,
|
||||||
|
|
||||||
skkKeysCount,
|
skkKeysCount,
|
||||||
// skkTransportBase = skkSubClassSCSI,
|
// skkTransportBase = skkSubClassSCSI,
|
||||||
skkProtoBegin = skkProtoBulk,
|
skkProtoBegin = skkProtoBulk,
|
||||||
skkProtoEnd = skkProtoCBI,
|
skkProtoEnd = skkProtoCBI,
|
||||||
skkCmdSetBegin = skkCmdSetSCSI,
|
skkCmdSetBegin = skkCmdSetSCSI,
|
||||||
skkCmdSetEnd = skkCmdSetQIC157,
|
skkCmdSetEnd = skkCmdSetQIC157,
|
||||||
};
|
};
|
||||||
/**
|
/**
|
||||||
helper struct, used in our "quick" search algorithm
|
helper struct, used in our "quick" search algorithm
|
||||||
*/
|
*/
|
||||||
struct _settings_key{
|
struct _settings_key{
|
||||||
union _hash{
|
union _hash{
|
||||||
char name[32];
|
char name[32];
|
||||||
uint16 key;
|
uint16 key;
|
||||||
}hash;
|
}hash;
|
||||||
uint32 property;
|
uint32 property;
|
||||||
}settings_keys[] = { /**< array of keys, used in our settings files */
|
}settings_keys[] = { /**< array of keys, used in our settings files */
|
||||||
{{"vendor" }, 0}, /* MUST BE SYNCHRONISED WITH skk*** indexes!!! */
|
{{"vendor" }, 0}, /* MUST BE SYNCHRONISED WITH skk*** indexes!!! */
|
||||||
{{"device" }, 0},
|
{{"device" }, 0},
|
||||||
// {{"name" }, 0},
|
// {{"name" }, 0},
|
||||||
// {{"transport"}, 0},
|
// {{"transport"}, 0},
|
||||||
{{"protocol"}, 0},
|
{{"protocol"}, 0},
|
||||||
{{"commandset"}, 0},
|
{{"commandset"}, 0},
|
||||||
{{"fake_inquiry" }, 0},
|
{{"fake_inquiry" }, 0},
|
||||||
{{"use_rw6_byte_cmd" }, 0},
|
{{"use_rw6_byte_cmd" }, 0},
|
||||||
{{"trans_test_unit" }, 0},
|
{{"trans_test_unit" }, 0},
|
||||||
{{"no_test_unit" }, 0},
|
{{"no_test_unit" }, 0},
|
||||||
{{"no_get_max_lun"}, 0},
|
{{"no_get_max_lun"}, 0},
|
||||||
{{"no_prevent_media"}, 0},
|
{{"no_prevent_media"}, 0},
|
||||||
{{"use_mode_sense_10"}, 0},
|
{{"use_mode_sense_10"}, 0},
|
||||||
{{"force_read_only"}, 0},
|
{{"force_read_only"}, 0},
|
||||||
{{"BULK" }, PROTO_BULK_ONLY},
|
{{"BULK" }, PROTO_BULK_ONLY},
|
||||||
{{"CB" }, PROTO_CB},
|
{{"CB" }, PROTO_CB},
|
||||||
{{"CBI" }, PROTO_CBI},
|
{{"CBI" }, PROTO_CBI},
|
||||||
// {{"Freecom"}, PROTO_FREECOM},
|
// {{"Freecom"}, PROTO_FREECOM},
|
||||||
{{"SCSI" }, CMDSET_SCSI},
|
{{"SCSI" }, CMDSET_SCSI},
|
||||||
{{"UFI" }, CMDSET_UFI},
|
{{"UFI" }, CMDSET_UFI},
|
||||||
{{"ATAPI" }, CMDSET_ATAPI},
|
{{"ATAPI" }, CMDSET_ATAPI},
|
||||||
{{"RBC" }, CMDSET_RBC},
|
{{"RBC" }, CMDSET_RBC},
|
||||||
{{"QIC157" }, CMDSET_QIC157},
|
{{"QIC157" }, CMDSET_QIC157},
|
||||||
};
|
};
|
||||||
/**
|
/**
|
||||||
\define:SK_EQUAL
|
\define:SK_EQUAL
|
||||||
checks is the __name parameter correspond to value, pointed by __id index
|
checks is the __name parameter correspond to value, pointed by __id index
|
||||||
in settings_keys array. The magic of our "quick" search algorithm =-))
|
in settings_keys array. The magic of our "quick" search algorithm =-))
|
||||||
*/
|
*/
|
||||||
#define CAST_SK(__name) (*(uint16 *)(__name))
|
#define CAST_SK(__name) (*(uint16 *)(__name))
|
||||||
#define SK_EQUAL(__name, __id) ((CAST_SK(__name) == (settings_keys[__id].hash.key)) && \
|
#define SK_EQUAL(__name, __id) ((CAST_SK(__name) == (settings_keys[__id].hash.key)) && \
|
||||||
(0 == strcmp(__name, settings_keys[__id].hash.name)))
|
(0 == strcmp(__name, settings_keys[__id].hash.name)))
|
||||||
/**
|
/**
|
||||||
\fn:load_module_settings
|
\fn:load_module_settings
|
||||||
loads driver settings from extarnal settings file through BeOS driver
|
loads driver settings from extarnal settings file through BeOS driver
|
||||||
settings API. Called on initialization of the module
|
settings API. Called on initialization of the module
|
||||||
*/
|
*/
|
||||||
void load_module_settings()
|
void load_module_settings(void)
|
||||||
{
|
{
|
||||||
void *sh = load_driver_settings(MODULE_NAME);
|
void *sh = load_driver_settings(MODULE_NAME);
|
||||||
if(sh){
|
if(sh){
|
||||||
load_log_settings(sh);
|
load_log_settings(sh);
|
||||||
/* devices "reservation". Workaround for plug-n-play device attaching*/
|
/* devices "reservation". Workaround for plug-n-play device attaching*/
|
||||||
reserved_devices = strtoul(get_driver_parameter(sh, "reserve_devices",
|
reserved_devices = strtoul(get_driver_parameter(sh, "reserve_devices",
|
||||||
S_DEF_DEVS, S_DEF_DEVS), NULL, 0);
|
S_DEF_DEVS, S_DEF_DEVS), NULL, 0);
|
||||||
reserved_luns = strtoul(get_driver_parameter(sh, "reserve_luns",
|
reserved_luns = strtoul(get_driver_parameter(sh, "reserve_luns",
|
||||||
S_DEF_LUNS, S_DEF_LUNS), NULL, 0);
|
S_DEF_LUNS, S_DEF_LUNS), NULL, 0);
|
||||||
b_ignore_sysinit2 = get_driver_boolean_parameter(sh, "ignore_sysinit2",
|
b_ignore_sysinit2 = get_driver_boolean_parameter(sh, "ignore_sysinit2",
|
||||||
b_ignore_sysinit2, false);
|
b_ignore_sysinit2, false);
|
||||||
if(reserved_devices > MAX_DEVICES_COUNT)
|
if(reserved_devices > MAX_DEVICES_COUNT)
|
||||||
reserved_devices = MAX_DEVICES_COUNT;
|
reserved_devices = MAX_DEVICES_COUNT;
|
||||||
if(reserved_luns > MAX_LUNS_COUNT)
|
if(reserved_luns > MAX_LUNS_COUNT)
|
||||||
reserved_luns = MAX_LUNS_COUNT;
|
reserved_luns = MAX_LUNS_COUNT;
|
||||||
b_reservation_on = (reserved_devices != 0);
|
b_reservation_on = (reserved_devices != 0);
|
||||||
|
|
||||||
unload_driver_settings(sh);
|
unload_driver_settings(sh);
|
||||||
} else {
|
} else {
|
||||||
TRACE("settings:load:file '%s' was not found. Using default setting...\n",
|
TRACE("settings:load:file '%s' was not found. Using default setting...\n",
|
||||||
MODULE_NAME);
|
MODULE_NAME);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
\fn:strncpy_value
|
\fn:strncpy_value
|
||||||
\param to: buffer for copied string
|
\param to: buffer for copied string
|
||||||
\param dp: driver_parameter, from wich copied string come
|
\param dp: driver_parameter, from wich copied string come
|
||||||
\param size: maximal size of copied string
|
\param size: maximal size of copied string
|
||||||
copies a string, containing value[0] of this parameter, from driver_parameter,
|
copies a string, containing value[0] of this parameter, from driver_parameter,
|
||||||
pointed by dp, to buffer pointed by to. Semantic of this function is similar
|
pointed by dp, to buffer pointed by to. Semantic of this function is similar
|
||||||
to standard strncpy() one.
|
to standard strncpy() one.
|
||||||
*/
|
*/
|
||||||
/*static void
|
/*static void
|
||||||
strncpy_value(char *to, driver_parameter *dp, size_t size)
|
strncpy_value(char *to, driver_parameter *dp, size_t size)
|
||||||
{
|
{
|
||||||
to[0] = 0;
|
to[0] = 0;
|
||||||
if(dp->value_count > 0){
|
if(dp->value_count > 0){
|
||||||
strncpy(to, dp->values[0], size);
|
strncpy(to, dp->values[0], size);
|
||||||
}
|
}
|
||||||
}*/
|
}*/
|
||||||
/**
|
/**
|
||||||
\fn:parse_transport
|
\fn:parse_transport
|
||||||
\param dp: driver_parameter, containing device transport information
|
\param dp: driver_parameter, containing device transport information
|
||||||
\return: a bitmasked value from PROP_-defined flags for USB subclass and \
|
\return: a bitmasked value from PROP_-defined flags for USB subclass and \
|
||||||
protocol
|
protocol
|
||||||
parse the transport driver_parameter for known USB subclasses, protocols and
|
parse the transport driver_parameter for known USB subclasses, protocols and
|
||||||
compose a bitmasked value from those settings
|
compose a bitmasked value from those settings
|
||||||
*/
|
*/
|
||||||
static uint32
|
static uint32
|
||||||
parse_transport(driver_parameter *dp,
|
parse_transport(driver_parameter *dp, int skkBase, int skkEnd,
|
||||||
int skkBase, int skkEnd,
|
uint32 vendor_prop, char *vendor_prop_name)
|
||||||
uint32 vendor_prop, char *vendor_prop_name)
|
|
||||||
{
|
{
|
||||||
uint32 ret = 0;
|
uint32 ret = 0;
|
||||||
if(dp->value_count > 0){
|
if(dp->value_count > 0){
|
||||||
char *value = dp->values[0];
|
char *value = dp->values[0];
|
||||||
int skkIdx = skkBase;
|
int skkIdx = skkBase;
|
||||||
for(; skkIdx <= skkEnd; skkIdx++){
|
for(; skkIdx <= skkEnd; skkIdx++){
|
||||||
if(SK_EQUAL(value, skkIdx)){
|
if(SK_EQUAL(value, skkIdx)){
|
||||||
ret |= settings_keys[skkIdx].property;
|
ret |= settings_keys[skkIdx].property;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} /* for(...) enumerate protocol and commandset keys */
|
} /* for(...) enumerate protocol and commandset keys */
|
||||||
if(skkIdx > skkEnd){ /* not found - assume vendor prop */
|
if(skkIdx > skkEnd){ /* not found - assume vendor prop */
|
||||||
ret |= vendor_prop;
|
ret |= vendor_prop;
|
||||||
strncpy(vendor_prop_name, value, VENDOR_PROP_NAME_LEN);
|
strncpy(vendor_prop_name, value, VENDOR_PROP_NAME_LEN);
|
||||||
}
|
}
|
||||||
if(dp->value_count > 1){
|
if(dp->value_count > 1){
|
||||||
TRACE("settings:parse_transport:accept '%s', ignore extra...\n", value);
|
TRACE("settings:parse_transport:accept '%s', ignore extra...\n", value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
\fn:lookup_device_info
|
\fn:lookup_device_info
|
||||||
\param product_id: product id of device to be checked for private settings
|
\param product_id: product id of device to be checked for private settings
|
||||||
\param dp: driver_parameter, containing device information
|
\param dp: driver_parameter, containing device information
|
||||||
\param udd: on return contains name,protocol etc. information about device
|
\param udd: on return contains name,protocol etc. information about device
|
||||||
\return: "true" if private settings for device found - "false" otherwise
|
\return: "true" if private settings for device found - "false" otherwise
|
||||||
looks through device parameter, pointed by dp, obtains the name and other
|
looks through device parameter, pointed by dp, obtains the name and other
|
||||||
parameters of private device settings if available
|
parameters of private device settings if available
|
||||||
*/
|
*/
|
||||||
static bool
|
static bool
|
||||||
lookup_device_info(uint16 product_id,
|
lookup_device_info(uint16 product_id, driver_parameter *dp,
|
||||||
driver_parameter *dp,
|
usb_device_settings *uds)
|
||||||
usb_device_settings *uds)
|
|
||||||
{
|
{
|
||||||
bool b_found = false;
|
bool b_found = false;
|
||||||
if(dp){
|
if(dp){
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for(; i < dp->value_count; i++){
|
for(; i < dp->value_count; i++){
|
||||||
uint16 id = strtoul(dp->values[0], NULL, 0) & 0xffff;
|
uint16 id = strtoul(dp->values[0], NULL, 0) & 0xffff;
|
||||||
if(product_id == id){
|
if(product_id == id){
|
||||||
int prm = 0;
|
int prm = 0;
|
||||||
uds->product_id = product_id;
|
uds->product_id = product_id;
|
||||||
for(; prm < dp->parameter_count; prm++){
|
for(; prm < dp->parameter_count; prm++){
|
||||||
/* if(SK_EQUAL(dp->parameters[prm].name, skkName)){
|
/* if(SK_EQUAL(dp->parameters[prm].name, skkName)){
|
||||||
strncpy_value(udd->product_name, &dp->parameters[prm], INQ_PRODUCT_LEN);
|
strncpy_value(udd->product_name, &dp->parameters[prm], INQ_PRODUCT_LEN);
|
||||||
} else*/
|
} else*/
|
||||||
/* if(SK_EQUAL(dp->parameters[prm].name, skkTransport)){
|
/* if(SK_EQUAL(dp->parameters[prm].name, skkTransport)){
|
||||||
udd->properties |= parse_transport(&dp->parameters[prm]);
|
udd->properties |= parse_transport(&dp->parameters[prm]);
|
||||||
} else*/
|
} else*/
|
||||||
if(SK_EQUAL(dp->parameters[prm].name, skkProtocol)){
|
if(SK_EQUAL(dp->parameters[prm].name, skkProtocol)){
|
||||||
uds->properties |= parse_transport(&dp->parameters[prm],
|
uds->properties |= parse_transport(&dp->parameters[prm],
|
||||||
skkProtoBegin, skkProtoEnd,
|
skkProtoBegin, skkProtoEnd,
|
||||||
PROTO_VENDOR,
|
PROTO_VENDOR, uds->vendor_protocol);
|
||||||
uds->vendor_protocol);
|
} else
|
||||||
} else
|
if(SK_EQUAL(dp->parameters[prm].name, skkCommandSet)){
|
||||||
if(SK_EQUAL(dp->parameters[prm].name, skkCommandSet)){
|
uds->properties |= parse_transport(&dp->parameters[prm],
|
||||||
uds->properties |= parse_transport(&dp->parameters[prm],
|
skkCmdSetBegin, skkCmdSetEnd,
|
||||||
skkCmdSetBegin, skkCmdSetEnd,
|
CMDSET_VENDOR, uds->vendor_commandset);
|
||||||
CMDSET_VENDOR,
|
} else
|
||||||
uds->vendor_commandset);
|
if(SK_EQUAL(dp->parameters[prm].name, skkFakeInq)){
|
||||||
} else
|
uds->properties |= FIX_NO_INQUIRY;
|
||||||
if(SK_EQUAL(dp->parameters[prm].name, skkFakeInq)){
|
} else
|
||||||
uds->properties |= FIX_NO_INQUIRY;
|
if(SK_EQUAL(dp->parameters[prm].name, skk6ByteCmd)){
|
||||||
} else
|
uds->properties |= FIX_FORCE_RW_TO_6;
|
||||||
if(SK_EQUAL(dp->parameters[prm].name, skk6ByteCmd)){
|
} else
|
||||||
uds->properties |= FIX_FORCE_RW_TO_6;
|
if(SK_EQUAL(dp->parameters[prm].name, skkTransTU)){
|
||||||
} else
|
uds->properties |= FIX_TRANS_TEST_UNIT;
|
||||||
if(SK_EQUAL(dp->parameters[prm].name, skkTransTU)){
|
} else
|
||||||
uds->properties |= FIX_TRANS_TEST_UNIT;
|
if(SK_EQUAL(dp->parameters[prm].name, skkNoTU)){
|
||||||
} else
|
uds->properties |= FIX_NO_TEST_UNIT;
|
||||||
if(SK_EQUAL(dp->parameters[prm].name, skkNoTU)){
|
} else
|
||||||
uds->properties |= FIX_NO_TEST_UNIT;
|
if(SK_EQUAL(dp->parameters[prm].name, skkNoPreventMedia)){
|
||||||
} else
|
uds->properties |= FIX_NO_PREVENT_MEDIA;
|
||||||
if(SK_EQUAL(dp->parameters[prm].name, skkNoPreventMedia)){
|
} else
|
||||||
uds->properties |= FIX_NO_PREVENT_MEDIA;
|
if(SK_EQUAL(dp->parameters[prm].name, skkUseModeSense10)){
|
||||||
} else
|
uds->properties |= FIX_FORCE_MS_TO_10;
|
||||||
if(SK_EQUAL(dp->parameters[prm].name, skkUseModeSense10)){
|
} else
|
||||||
uds->properties |= FIX_FORCE_MS_TO_10;
|
if(SK_EQUAL(dp->parameters[prm].name, skkForceReadOnly)){
|
||||||
} else
|
uds->properties |= FIX_FORCE_READ_ONLY;
|
||||||
if(SK_EQUAL(dp->parameters[prm].name, skkForceReadOnly)){
|
} else
|
||||||
uds->properties |= FIX_FORCE_READ_ONLY;
|
if(SK_EQUAL(dp->parameters[prm].name, skkNoGetMaxLUN)){
|
||||||
} else
|
uds->properties |= FIX_NO_GETMAXLUN;
|
||||||
if(SK_EQUAL(dp->parameters[prm].name, skkNoGetMaxLUN)){
|
} else {
|
||||||
uds->properties |= FIX_NO_GETMAXLUN;
|
TRACE("settings:device:ignore unknown parameter:%s\n",
|
||||||
} else {
|
dp->parameters[prm].name);
|
||||||
TRACE("settings:device:ignore unknown parameter:%s\n",
|
}
|
||||||
dp->parameters[prm].name);
|
} /* for(...) enumerate device parameters */
|
||||||
}
|
b_found = true;
|
||||||
} /* for(...) enumerate device parameters */
|
break;
|
||||||
b_found = true;
|
} /* if(product_id == id){ */
|
||||||
break;
|
} /*enumerate parameter values (product ids) */
|
||||||
} /* if(product_id == id){ */
|
} /* if(dp) */
|
||||||
} /*enumerate parameter values (product ids) */
|
return b_found;
|
||||||
} /* if(dp) */
|
|
||||||
return b_found;
|
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
\fn:lookup_vendor_info
|
\fn:lookup_vendor_info
|
||||||
\param vendor_id: vendor id of device to be checked for private settings
|
\param vendor_id: vendor id of device to be checked for private settings
|
||||||
\param product_id: product id of device to be checked for private settings
|
\param product_id: product id of device to be checked for private settings
|
||||||
\param dp: driver_parameter, containing vendor information
|
\param dp: driver_parameter, containing vendor information
|
||||||
\param udd: on return contains name, protocol etc. information about device
|
\param udd: on return contains name, protocol etc. information about device
|
||||||
\return: "true" if private settings for device found - "false" otherwise
|
\return: "true" if private settings for device found - "false" otherwise
|
||||||
looks through vendor parameter, pointed by dp, obtains the name of vendor and
|
looks through vendor parameter, pointed by dp, obtains the name of vendor and
|
||||||
device information if available
|
device information if available
|
||||||
*/
|
*/
|
||||||
static bool
|
static bool
|
||||||
lookup_vendor_info(uint16 vendor_id,
|
lookup_vendor_info(uint16 vendor_id, uint16 product_id,
|
||||||
uint16 product_id,
|
driver_parameter *dp, usb_device_settings *uds)
|
||||||
driver_parameter *dp,
|
|
||||||
usb_device_settings *uds)
|
|
||||||
{
|
{
|
||||||
bool b_found = false;
|
bool b_found = false;
|
||||||
if(dp && dp->value_count > 0 && dp->values[0]){
|
if(dp && dp->value_count > 0 && dp->values[0]){
|
||||||
uint16 id = strtoul(dp->values[0], NULL, 0) & 0xffff;
|
uint16 id = strtoul(dp->values[0], NULL, 0) & 0xffff;
|
||||||
if(vendor_id == id){
|
if(vendor_id == id){
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for( i = 0; i < dp->parameter_count; i++){
|
for( i = 0; i < dp->parameter_count; i++){
|
||||||
if(!b_found && SK_EQUAL(dp->parameters[i].name, skkDevice)){
|
if(!b_found && SK_EQUAL(dp->parameters[i].name, skkDevice)){
|
||||||
b_found = lookup_device_info(product_id, &dp->parameters[i], uds);
|
b_found = lookup_device_info(product_id, &dp->parameters[i], uds);
|
||||||
} /*else
|
} /*else
|
||||||
if(SK_EQUAL(dp->parameters[i].name, skkName)){
|
if(SK_EQUAL(dp->parameters[i].name, skkName)){
|
||||||
strncpy_value(udd->vendor_name, &dp->parameters[i], INQ_VENDOR_LEN);
|
strncpy_value(udd->vendor_name, &dp->parameters[i], INQ_VENDOR_LEN);
|
||||||
} */else {
|
} */else {
|
||||||
TRACE("settings:vendor:ignore unknown parameter:%s\n",
|
TRACE("settings:vendor:ignore unknown parameter:%s\n",
|
||||||
dp->parameters[i].name);
|
dp->parameters[i].name);
|
||||||
}
|
}
|
||||||
} /*for(...) enumerate "vendor" parameters*/
|
} /*for(...) enumerate "vendor" parameters*/
|
||||||
} /*if(vendor_id == id){*/
|
} /*if(vendor_id == id){*/
|
||||||
} /* if(dp && ... etc */
|
} /* if(dp && ... etc */
|
||||||
return b_found;
|
return b_found;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
\fn:lookup_device_settings
|
\fn:lookup_device_settings
|
||||||
\param vendor_id: vendor id of device to be checked for private settings
|
\param vendor_id: vendor id of device to be checked for private settings
|
||||||
\param product_id: product id of device to be checked for private settings
|
\param product_id: product id of device to be checked for private settings
|
||||||
\param udd: on return contains name,protocol etc. information about device
|
\param udd: on return contains name,protocol etc. information about device
|
||||||
\return: "true" if private settings for device found - "false" otherwise
|
\return: "true" if private settings for device found - "false" otherwise
|
||||||
looks through driver settings file for private device description and load it
|
looks through driver settings file for private device description and load it
|
||||||
if available into struct pointed by udd
|
if available into struct pointed by udd
|
||||||
*/
|
*/
|
||||||
bool lookup_device_settings(const usb_device_descriptor *udd,
|
bool lookup_device_settings(const usb_device_descriptor *udd,
|
||||||
usb_device_settings *uds)
|
usb_device_settings *uds)
|
||||||
{
|
{
|
||||||
bool b_found = false;
|
bool b_found = false;
|
||||||
if(uds){
|
if(uds){
|
||||||
void *sh = load_driver_settings(MODULE_NAME);
|
void *sh = load_driver_settings(MODULE_NAME);
|
||||||
if(sh){
|
if(sh){
|
||||||
const driver_settings *ds = get_driver_settings(sh);
|
const driver_settings *ds = get_driver_settings(sh);
|
||||||
if(ds){
|
if(ds){
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for(i = 0; i < ds->parameter_count; i++){
|
for(i = 0; i < ds->parameter_count; i++){
|
||||||
if(SK_EQUAL(ds->parameters[i].name, skkVendor)){
|
if(SK_EQUAL(ds->parameters[i].name, skkVendor)){
|
||||||
b_found = lookup_vendor_info(udd->vendor_id,
|
b_found = lookup_vendor_info(udd->vendor_id,
|
||||||
udd->product_id,
|
udd->product_id,
|
||||||
&ds->parameters[i], uds);
|
&ds->parameters[i], uds);
|
||||||
if(b_found){
|
if(b_found){
|
||||||
uds->vendor_id = udd->vendor_id;
|
uds->vendor_id = udd->vendor_id;
|
||||||
break; //we've got it - stop enumeration.
|
break; //we've got it - stop enumeration.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} /*for(...) - enumerate "root" parameters*/
|
} /*for(...) - enumerate "root" parameters*/
|
||||||
} /* if(ds) */
|
} /* if(ds) */
|
||||||
unload_driver_settings(sh);
|
unload_driver_settings(sh);
|
||||||
} /* if(sh) */
|
} /* if(sh) */
|
||||||
if(b_found){
|
if(b_found){
|
||||||
//TRACE("settings:loaded settings:'%s(%04x)/%s(%04x)/%08x'\n",
|
//TRACE("settings:loaded settings:'%s(%04x)/%s(%04x)/%08x'\n",
|
||||||
TRACE("settings:loaded settings:'%04x/%04x/%08x'\n",
|
TRACE("settings:loaded settings:'%04x/%04x/%08x'\n",
|
||||||
/*descr->vendor_name,*/ uds->vendor_id,
|
/*descr->vendor_name,*/ uds->vendor_id,
|
||||||
/*descr->product_name,*/
|
/*descr->product_name,*/
|
||||||
uds->product_id, uds->properties);
|
uds->product_id, uds->properties);
|
||||||
}
|
}
|
||||||
} /* if(descr)*/
|
} /* if(descr)*/
|
||||||
return b_found;
|
return b_found;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,31 +1,38 @@
|
|||||||
/*
|
/**
|
||||||
* Copyright (c) 2003-2005 by Siarzhuk Zharski <[email protected]>
|
*
|
||||||
* Distributed under the terms of the BSD License.
|
* TODO: description
|
||||||
*
|
*
|
||||||
|
* This file is a part of USB SCSI CAM for Haiku OS.
|
||||||
|
* May be used under terms of the MIT License
|
||||||
|
*
|
||||||
|
* Author(s):
|
||||||
|
* Siarzhuk Zharski <[email protected]>
|
||||||
|
*
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** driver settings support definitions */
|
/** driver settings support definitions */
|
||||||
|
|
||||||
#ifndef _USB_SCSI_SETTINGS_H_
|
#ifndef _USB_SCSI_SETTINGS_H_
|
||||||
#define _USB_SCSI_SETTINGS_H_
|
#define _USB_SCSI_SETTINGS_H_
|
||||||
|
|
||||||
void load_module_settings();
|
void load_module_settings(void);
|
||||||
|
|
||||||
typedef struct{
|
typedef struct{
|
||||||
uint16 vendor_id;
|
uint16 vendor_id;
|
||||||
uint16 product_id;
|
uint16 product_id;
|
||||||
uint32 properties;
|
uint32 properties;
|
||||||
#define VENDOR_PROP_NAME_LEN 0x08
|
#define VENDOR_PROP_NAME_LEN 0x08
|
||||||
char vendor_protocol[VENDOR_PROP_NAME_LEN + 1];
|
char vendor_protocol[VENDOR_PROP_NAME_LEN + 1];
|
||||||
char vendor_commandset[VENDOR_PROP_NAME_LEN + 1];
|
char vendor_commandset[VENDOR_PROP_NAME_LEN + 1];
|
||||||
}usb_device_settings;
|
}usb_device_settings;
|
||||||
|
|
||||||
bool lookup_device_settings(const usb_device_descriptor *udd,
|
bool lookup_device_settings(const usb_device_descriptor *udd,
|
||||||
usb_device_settings *uds);
|
usb_device_settings *uds);
|
||||||
|
|
||||||
extern int reserved_devices;
|
extern int reserved_devices;
|
||||||
extern int reserved_luns;
|
extern int reserved_luns;
|
||||||
extern bool b_reservation_on;
|
extern bool b_reservation_on;
|
||||||
extern bool b_ignore_sysinit2;
|
extern bool b_ignore_sysinit2;
|
||||||
|
|
||||||
#endif /*_USB_SCSI_SETTINGS_H_*/
|
#endif /*_USB_SCSI_SETTINGS_H_*/
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,15 @@
|
|||||||
/*
|
/**
|
||||||
* Copyright (c) 2003-2005 by Siarzhuk Zharski <[email protected]>
|
*
|
||||||
* Distributed under the terms of the BSD License.
|
* TODO: description
|
||||||
*
|
*
|
||||||
|
* This file is a part of USB SCSI CAM for Haiku OS.
|
||||||
|
* May be used under terms of the MIT License
|
||||||
|
*
|
||||||
|
* Author(s):
|
||||||
|
* Siarzhuk Zharski <[email protected]>
|
||||||
|
*
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** handling SCSI data-buffer (both usual "plain" and scatter/gather ones) */
|
/** handling SCSI data-buffer (both usual "plain" and scatter/gather ones) */
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@@ -15,159 +21,160 @@
|
|||||||
#include "sg_buffer.h"
|
#include "sg_buffer.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
\fn:init_sg_buffer
|
\fn:init_sg_buffer
|
||||||
TODO!!!
|
TODO!!!
|
||||||
*/
|
*/
|
||||||
status_t
|
status_t
|
||||||
init_sg_buffer(sg_buffer *sgb, CCB_SCSIIO *ccbio)
|
init_sg_buffer(sg_buffer *sgb, CCB_SCSIIO *ccbio)
|
||||||
{
|
{
|
||||||
status_t status = B_NO_INIT;
|
status_t status = B_NO_INIT;
|
||||||
if(0 != sgb){
|
if(0 != sgb){
|
||||||
memset(sgb, 0, sizeof(sg_buffer));
|
memset(sgb, 0, sizeof(sg_buffer));
|
||||||
/* setup scatter/gather if exists in CCBIO*/
|
/* setup scatter/gather if exists in CCBIO*/
|
||||||
if(ccbio->cam_ch.cam_flags & CAM_SCATTER_VALID) {
|
if(ccbio->cam_ch.cam_flags & CAM_SCATTER_VALID) {
|
||||||
sgb->piov = (iovec *) ccbio->cam_data_ptr;
|
sgb->piov = (iovec *) ccbio->cam_data_ptr;
|
||||||
sgb->count = ccbio->cam_sglist_cnt;
|
sgb->count = ccbio->cam_sglist_cnt;
|
||||||
} else {
|
} else {
|
||||||
sgb->iov.iov_base = (iovec *) ccbio->cam_data_ptr;
|
sgb->iov.iov_base = (iovec *) ccbio->cam_data_ptr;
|
||||||
sgb->iov.iov_len = ccbio->cam_dxfer_len;
|
sgb->iov.iov_len = ccbio->cam_dxfer_len;
|
||||||
sgb->piov = &sgb->iov;
|
sgb->piov = &sgb->iov;
|
||||||
sgb->count = 1;
|
sgb->count = 1;
|
||||||
}
|
}
|
||||||
status = B_OK;
|
status = B_OK;
|
||||||
} else {
|
} else {
|
||||||
TRACE_ALWAYS("init_sg_buffer fatal: not initialized!\n");
|
TRACE_ALWAYS("init_sg_buffer fatal: not initialized!\n");
|
||||||
}
|
}
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
\fn:alloc_sg_buffer
|
\fn:alloc_sg_buffer
|
||||||
TODO!!!
|
TODO!!!
|
||||||
*/
|
*/
|
||||||
status_t
|
status_t
|
||||||
realloc_sg_buffer(sg_buffer *sgb, size_t size)
|
realloc_sg_buffer(sg_buffer *sgb, size_t size)
|
||||||
{
|
{
|
||||||
status_t status = B_NO_INIT;
|
status_t status = B_NO_INIT;
|
||||||
if(0 != sgb){
|
if(0 != sgb){
|
||||||
/* NOTE: no check for previously allocations! May be dangerous!*/
|
/* NOTE: no check for previously allocations! May be dangerous!*/
|
||||||
void *ptr = malloc(size);
|
void *ptr = malloc(size);
|
||||||
status = (0 != ptr) ? B_OK : B_NO_MEMORY;
|
status = (0 != ptr) ? B_OK : B_NO_MEMORY;
|
||||||
if(B_OK == status) {
|
if(B_OK == status) {
|
||||||
memset(ptr, 0, size);
|
memset(ptr, 0, size);
|
||||||
sgb->iov.iov_base = (iovec *)ptr;
|
sgb->iov.iov_base = (iovec *)ptr;
|
||||||
sgb->iov.iov_len = size;
|
sgb->iov.iov_len = size;
|
||||||
sgb->piov = &sgb->iov;
|
sgb->piov = &sgb->iov;
|
||||||
sgb->count = 1;
|
sgb->count = 1;
|
||||||
sgb->b_own = true;
|
sgb->b_own = true;
|
||||||
status = B_OK;
|
status = B_OK;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
TRACE_ALWAYS("realloc_sg_buffer fatal: not initialized!\n");
|
TRACE_ALWAYS("realloc_sg_buffer fatal: not initialized!\n");
|
||||||
}
|
}
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
sg_access_byte(sg_buffer *sgb, off_t offset, uchar *byte, bool b_set)
|
sg_access_byte(sg_buffer *sgb, off_t offset, uchar *byte, bool b_set)
|
||||||
{
|
{
|
||||||
status_t status = B_ERROR;
|
status_t status = B_ERROR;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for(; i < sgb->count; i++){
|
for(; i < sgb->count; i++){
|
||||||
if(offset >= sgb->piov[i].iov_len){
|
if(offset >= sgb->piov[i].iov_len){
|
||||||
offset -= sgb->piov[i].iov_len;
|
offset -= sgb->piov[i].iov_len;
|
||||||
} else {
|
} else {
|
||||||
uchar *ptr = (uchar *)sgb->piov[i].iov_base;
|
uchar *ptr = (uchar *)sgb->piov[i].iov_base;
|
||||||
if(b_set){
|
if(b_set){
|
||||||
ptr[offset] = *byte;
|
ptr[offset] = *byte;
|
||||||
}else{
|
}else{
|
||||||
*byte = ptr[offset];
|
*byte = ptr[offset];
|
||||||
}
|
}
|
||||||
status = B_OK;
|
status = B_OK;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
sg_memcpy(sg_buffer *d_sgb, off_t d_offset,
|
sg_memcpy(sg_buffer *d_sgb, off_t d_offset,
|
||||||
sg_buffer *s_sgb, off_t s_offset, size_t size)
|
sg_buffer *s_sgb, off_t s_offset, size_t size)
|
||||||
{
|
{
|
||||||
status_t status = B_NO_INIT;
|
status_t status = B_NO_INIT;
|
||||||
while(0 != d_sgb && 0 != s_sgb){
|
while(0 != d_sgb && 0 != s_sgb){
|
||||||
uchar *d_ptr = 0;
|
uchar *d_ptr = 0;
|
||||||
uchar *s_ptr = 0;
|
uchar *s_ptr = 0;
|
||||||
status = B_ERROR;
|
status = B_ERROR;
|
||||||
if(1 == d_sgb->count){
|
if(1 == d_sgb->count){
|
||||||
d_ptr = d_sgb->piov->iov_base + d_offset;
|
d_ptr = d_sgb->piov->iov_base + d_offset;
|
||||||
if((d_offset + size) > d_sgb->piov->iov_len){
|
if((d_offset + size) > d_sgb->piov->iov_len){
|
||||||
TRACE_ALWAYS("sg_memcpy fatal: dest buffer overflow: has:%d req:%d\n",
|
TRACE_ALWAYS("sg_memcpy fatal: dest buffer overflow: has:%d req:%d\n",
|
||||||
d_sgb->piov->iov_len, d_offset + size);
|
d_sgb->piov->iov_len, d_offset + size);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(1 == s_sgb->count){
|
if(1 == s_sgb->count){
|
||||||
s_ptr = s_sgb->piov->iov_base + s_offset;
|
s_ptr = s_sgb->piov->iov_base + s_offset;
|
||||||
if((s_offset + size) > s_sgb->piov->iov_len){
|
if((s_offset + size) > s_sgb->piov->iov_len){
|
||||||
TRACE_ALWAYS("sg_memcpy fatal: src buffer overflow: has:%d req:%d\n",
|
TRACE_ALWAYS("sg_memcpy fatal: src buffer overflow: has:%d req:%d\n",
|
||||||
s_sgb->piov->iov_len, s_offset + size);
|
s_sgb->piov->iov_len, s_offset + size);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(0 != d_ptr && 0 != s_ptr){
|
if(0 != d_ptr && 0 != s_ptr){
|
||||||
memcpy(d_ptr, s_ptr, size);
|
memcpy(d_ptr, s_ptr, size);
|
||||||
} else {
|
} else {
|
||||||
uchar byte = 0;
|
uchar byte = 0;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for(; i < size; i++){
|
for(; i < size; i++){
|
||||||
status = sg_access_byte(s_sgb, s_offset + i, &byte, false);
|
status = sg_access_byte(s_sgb, s_offset + i, &byte, false);
|
||||||
if(B_OK == status)
|
if(B_OK == status)
|
||||||
status = sg_access_byte(d_sgb, d_offset + i, &byte, true);
|
status = sg_access_byte(d_sgb, d_offset + i, &byte, true);
|
||||||
if(B_OK != status){
|
if(B_OK != status){
|
||||||
TRACE_ALWAYS("sg_memcpy fatal: dest:%d src:%d size:%d/%d\n",
|
TRACE_ALWAYS("sg_memcpy fatal: dest:%d src:%d size:%d/%d\n",
|
||||||
d_offset, s_offset, i, size);
|
d_offset, s_offset, i, size);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
status = B_OK;
|
status = B_OK;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if(B_NO_INIT == status)
|
if(B_NO_INIT == status)
|
||||||
TRACE_ALWAYS("sg_memcpy fatal: not initialized");
|
TRACE_ALWAYS("sg_memcpy fatal: not initialized");
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
\fn:free_sg_buffer
|
\fn:free_sg_buffer
|
||||||
TODO!!!
|
TODO!!!
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
free_sg_buffer(sg_buffer *sgb)
|
free_sg_buffer(sg_buffer *sgb)
|
||||||
{
|
{
|
||||||
if(0 != sgb && sgb->b_own){
|
if(0 != sgb && sgb->b_own){
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for(; i < sgb->count; i++){
|
for(; i < sgb->count; i++){
|
||||||
free(sgb->piov[i].iov_base);
|
free(sgb->piov[i].iov_base);
|
||||||
}
|
}
|
||||||
memset(sgb, 0, sizeof(sg_buffer));
|
memset(sgb, 0, sizeof(sg_buffer));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
sg_buffer_len(sg_buffer *sgb, size_t *size)
|
sg_buffer_len(sg_buffer *sgb, size_t *size)
|
||||||
{
|
{
|
||||||
status_t status = B_NO_INIT;
|
status_t status = B_NO_INIT;
|
||||||
if(0!=sgb && 0!=size){
|
if(0!=sgb && 0!=size){
|
||||||
int i = 0;
|
int i = 0;
|
||||||
*size = 0;
|
*size = 0;
|
||||||
for(; i < sgb->count; i++){
|
for(; i < sgb->count; i++){
|
||||||
*size += sgb->piov[i].iov_len;
|
*size += sgb->piov[i].iov_len;
|
||||||
}
|
}
|
||||||
status = B_OK;
|
status = B_OK;
|
||||||
} else {
|
} else {
|
||||||
TRACE_ALWAYS("sg_buffer_len fatal: not initialized (sgb:%x/size:%x)", sgb, size);
|
TRACE_ALWAYS("sg_buffer_len fatal: not initialized (sgb:%x/size:%x)", sgb, size);
|
||||||
}
|
}
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,26 +1,32 @@
|
|||||||
/*
|
/**
|
||||||
* Copyright (c) 2003-2005 by Siarzhuk Zharski <[email protected]>
|
*
|
||||||
* Distributed under the terms of the BSD License.
|
* TODO: description
|
||||||
*
|
*
|
||||||
|
* This file is a part of USB SCSI CAM for Haiku OS.
|
||||||
|
* May be used under terms of the MIT License
|
||||||
|
*
|
||||||
|
* Author(s):
|
||||||
|
* Siarzhuk Zharski <[email protected]>
|
||||||
|
*
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** handling SCSI data-buffer (both usual "plain" and scatter/gather ones) */
|
/** handling SCSI data-buffer (both usual "plain" and scatter/gather ones) */
|
||||||
|
|
||||||
#ifndef _SG_BUFFER_H_
|
#ifndef _SG_BUFFER_H_
|
||||||
#define _SG_BUFFER_H_
|
#define _SG_BUFFER_H_
|
||||||
|
|
||||||
#ifndef _IOVEC_H
|
#ifndef _IOVEC_H
|
||||||
#include <iovec.h>
|
#include <iovec.h>
|
||||||
#endif/*_IOVEC_H*/
|
#endif/*_IOVEC_H*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
\struct:_sg_buffer
|
\struct:_sg_buffer
|
||||||
*/
|
*/
|
||||||
typedef struct _sg_buffer{
|
typedef struct _sg_buffer{
|
||||||
iovec iov; /**< to avoid extra memory allocations */
|
iovec iov; /**< to avoid extra memory allocations */
|
||||||
iovec *piov; /**< ptr to scatter/gather list, default is equal to &iov */
|
iovec *piov; /**< ptr to scatter/gather list, default is equal to &iov */
|
||||||
int count; /**< count of scatter/gather vector entries */
|
int count; /**< count of scatter/gather vector entries */
|
||||||
bool b_own; /**< was allocated - must be freed */
|
bool b_own; /**< was allocated - must be freed */
|
||||||
} sg_buffer;
|
} sg_buffer;
|
||||||
|
|
||||||
#define member_offset(__type, __member) ((size_t)&(((__type *)0)->__member))
|
#define member_offset(__type, __member) ((size_t)&(((__type *)0)->__member))
|
||||||
@@ -31,7 +37,8 @@ status_t realloc_sg_buffer(sg_buffer *sgb, size_t size);
|
|||||||
status_t sg_buffer_len(sg_buffer *sgb, size_t *size);
|
status_t sg_buffer_len(sg_buffer *sgb, size_t *size);
|
||||||
status_t sg_access_byte(sg_buffer *sgb, off_t offset, uchar *byte, bool b_set);
|
status_t sg_access_byte(sg_buffer *sgb, off_t offset, uchar *byte, bool b_set);
|
||||||
status_t sg_memcpy(sg_buffer *dest_sgb, off_t dest_offset,
|
status_t sg_memcpy(sg_buffer *dest_sgb, off_t dest_offset,
|
||||||
sg_buffer *src_sgb, off_t src_offset, size_t size);
|
sg_buffer *src_sgb, off_t src_offset, size_t size);
|
||||||
void free_sg_buffer(sg_buffer *sgb);
|
void free_sg_buffer(sg_buffer *sgb);
|
||||||
|
|
||||||
#endif /*_SG_BUFFER_H_*/
|
#endif /*_SG_BUFFER_H_*/
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user