1/**
2 *
3 * TODO: description
4 *
5 * This file is a part of USB SCSI CAM for Haiku.
6 * May be used under terms of the MIT License
7 *
8 * Author(s):
9 * 	Siarzhuk Zharski <imker@gmx.li>
10 *
11 *
12 */
13#include "usb_scsi.h"
14
15#include <strings.h>
16#include "device_info.h"
17#include "tracing.h"
18
19#include "fake_device.h"
20
21/* duplication! Hope this fake file will be not required in Haiku version*/
22#define INQ_VENDOR_LEN		0x08
23#define INQ_PRODUCT_LEN		0x10
24#define INQ_REVISION_LEN	0x04
25
26void fake_inquiry_request(usb_device_info *udi, CCB_SCSIIO *ccbio)
27{
28	uint8 *data = ccbio->cam_data_ptr;
29	if(ccbio->cam_ch.cam_flags & CAM_SCATTER_VALID){
30		TRACE_ALWAYS("fake_inquiry: problems!!! scatter gatter ....=-(\n");
31	} else {
32		memset(data, 0, ccbio->cam_dxfer_len);
33		/* data[0] = 0x1F;*/ /* we can play here with type of device */
34		data[1] = 0x80;
35		data[2] = 0x02;
36		data[3] = 0x02;
37		data[4] = (0 != udi) ? 5 : 31; /* udi != 0 - mean FIX_NO_INQUIRY */
38		if(ccbio->cam_dxfer_len >= 0x24){
39			strncpy(&data[8],  "USB SCSI", INQ_VENDOR_LEN);
40			strncpy(&data[16], "Reserved", INQ_PRODUCT_LEN);
41			strncpy(&data[32], "N/A",      INQ_REVISION_LEN);
42		}
43	}
44}
45
46void fake_test_unit_ready_request(CCB_SCSIIO *ccbio)
47{
48	if(ccbio->cam_sense_ptr != NULL){
49		scsi_sense_data *sense_data = (scsi_sense_data *)ccbio->cam_sense_ptr;
50		memset(sense_data, 0, ccbio->cam_sense_len);
51		sense_data->error_code 	 = SSD_CURRENT_ERROR;
52		sense_data->flags		 = SSD_KEY_NOT_READY;
53		ccbio->cam_ch.cam_status = CAM_REQ_CMP_ERR | CAM_AUTOSNS_VALID;
54		ccbio->cam_scsi_status	 = SCSI_STATUS_CHECK_CONDITION;
55	} else {
56		ccbio->cam_ch.cam_status = CAM_REQ_CMP_ERR;
57		ccbio->cam_scsi_status	 = SCSI_STATUS_OK;
58	}
59}
60
61/**
62	\fn:fake_scsi_io
63	\param ccbio: ????
64	\return: ???
65
66	xpt_scsi_io - handle XPT_SCSI_IO sim action
67*/
68status_t fake_scsi_io(CCB_SCSIIO *ccbio)
69{
70	status_t status = B_BAD_VALUE;
71	uint8 *cmd;
72	scsi_cmd_generic *command;
73	if(ccbio->cam_ch.cam_flags & CAM_CDB_POINTER){
74		cmd = ccbio->cam_cdb_io.cam_cdb_ptr;
75	}else{
76		cmd = ccbio->cam_cdb_io.cam_cdb_bytes;
77	}
78	command = (scsi_cmd_generic *)cmd;
79	switch(command->opcode){
80		case TEST_UNIT_READY:{
81			fake_test_unit_ready_request(ccbio);
82			status = B_OK;
83		}break;
84		case INQUIRY:{
85			fake_inquiry_request(NULL, ccbio);
86			ccbio->cam_ch.cam_status = CAM_REQ_CMP;
87			status = B_OK;
88		}break;
89		default:
90			ccbio->cam_ch.cam_status = CAM_REQ_INVALID;
91		break;
92	}
93	return status;
94}
95
96