*
* TODO: description
*
* This file is a part of USB SCSI CAM for Haiku.
* May be used under terms of the MIT License
*
* Author(s):
* Siarzhuk Zharski <imker@gmx.li>
*
*
*/
#include "usb_scsi.h"
#include <strings.h>
#include "device_info.h"
#include "tracing.h"
#include "fake_device.h"
#define INQ_VENDOR_LEN 0x08
#define INQ_PRODUCT_LEN 0x10
#define INQ_REVISION_LEN 0x04
void fake_inquiry_request(usb_device_info *udi, CCB_SCSIIO *ccbio)
{
uint8 *data = ccbio->cam_data_ptr;
if(ccbio->cam_ch.cam_flags & CAM_SCATTER_VALID){
TRACE_ALWAYS("fake_inquiry: problems!!! scatter gatter ....=-(\n");
} else {
memset(data, 0, ccbio->cam_dxfer_len);
data[1] = 0x80;
data[2] = 0x02;
data[3] = 0x02;
data[4] = (0 != udi) ? 5 : 31;
if(ccbio->cam_dxfer_len >= 0x24){
strncpy(&data[8], "USB SCSI", INQ_VENDOR_LEN);
strncpy(&data[16], "Reserved", INQ_PRODUCT_LEN);
strncpy(&data[32], "N/A", INQ_REVISION_LEN);
}
}
}
void fake_test_unit_ready_request(CCB_SCSIIO *ccbio)
{
if(ccbio->cam_sense_ptr != NULL){
scsi_sense_data *sense_data = (scsi_sense_data *)ccbio->cam_sense_ptr;
memset(sense_data, 0, ccbio->cam_sense_len);
sense_data->error_code = SSD_CURRENT_ERROR;
sense_data->flags = SSD_KEY_NOT_READY;
ccbio->cam_ch.cam_status = CAM_REQ_CMP_ERR | CAM_AUTOSNS_VALID;
ccbio->cam_scsi_status = SCSI_STATUS_CHECK_CONDITION;
} else {
ccbio->cam_ch.cam_status = CAM_REQ_CMP_ERR;
ccbio->cam_scsi_status = SCSI_STATUS_OK;
}
}
\fn:fake_scsi_io
\param ccbio: ????
\return: ???
xpt_scsi_io - handle XPT_SCSI_IO sim action
*/
status_t fake_scsi_io(CCB_SCSIIO *ccbio)
{
status_t status = B_BAD_VALUE;
uint8 *cmd;
scsi_cmd_generic *command;
if(ccbio->cam_ch.cam_flags & CAM_CDB_POINTER){
cmd = ccbio->cam_cdb_io.cam_cdb_ptr;
}else{
cmd = ccbio->cam_cdb_io.cam_cdb_bytes;
}
command = (scsi_cmd_generic *)cmd;
switch(command->opcode){
case TEST_UNIT_READY:{
fake_test_unit_ready_request(ccbio);
status = B_OK;
}break;
case INQUIRY:{
fake_inquiry_request(NULL, ccbio);
ccbio->cam_ch.cam_status = CAM_REQ_CMP;
status = B_OK;
}break;
default:
ccbio->cam_ch.cam_status = CAM_REQ_INVALID;
break;
}
return status;
}