Control channel framework
Building the framework for communicating with the GreenSCSI command line over the SCSI bus.
This commit is contained in:
parent
5aeb32e928
commit
968f3336af
|
@ -1506,6 +1506,12 @@ void createcmd(int argc, char **argv) {
|
|||
goto success;
|
||||
}
|
||||
#endif /* SUPPORT_TAPE */
|
||||
#if SUPPORT_CONTROL
|
||||
if(!strcasecmp(argv[1], "control")) {
|
||||
ConfigureControl(h, NULL);
|
||||
goto success;
|
||||
}
|
||||
#endif /* SUPPORT_CONTROL */
|
||||
|
||||
//failure:
|
||||
errorlevel = -1;
|
||||
|
@ -1711,6 +1717,9 @@ void saveconfig(int argc, char **argv) {
|
|||
if(h->m_enabled) {
|
||||
// The create command automatically changes directory to the created object
|
||||
switch(h->m_type) {
|
||||
case DEV_PROCESSOR:
|
||||
config_file.print("create control\r\n");
|
||||
break;
|
||||
case DEV_DISK:
|
||||
config_file.print("create disk\r\n");
|
||||
break;
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#define MAX_BLOCKSIZE (1 << 15) // Maximum BLOCK size (2048 to 8192 tested, 16384 had issues)
|
||||
|
||||
#define SCSI_INQUIRY_RESPONSE_SIZE 96
|
||||
extern uint8_t SCSI_INQUIRY_RESPONSE[][SCSI_INQUIRY_RESPONSE_SIZE];
|
||||
|
||||
// Supported Device Types
|
||||
#define SUPPORT_DISK true
|
||||
|
@ -29,6 +30,7 @@
|
|||
#define SUPPORT_TAPE false
|
||||
#define SUPPORT_MO false
|
||||
#define SUPPORT_INITIATOR true
|
||||
#define SUPPORT_CONTROL true
|
||||
|
||||
// Compatibility Settings
|
||||
#define SUPPORT_SASI false // Enable SASI compatiblity for Sharp X68000
|
||||
|
|
|
@ -0,0 +1,111 @@
|
|||
#include "config.h"
|
||||
#include "scsi_defs.h"
|
||||
|
||||
#if SUPPORT_CONTROL
|
||||
/*
|
||||
* RECEIVE Command processing.
|
||||
*/
|
||||
void onControlReceiveCommand(uint32_t adds, uint32_t len)
|
||||
{
|
||||
LOG("-R ");
|
||||
LOGHEX4N(len);
|
||||
|
||||
if(!m_sel) {
|
||||
m_sts |= STATUS_CHECK;
|
||||
m_phase = PHASE_STATUSIN;
|
||||
return;
|
||||
}
|
||||
|
||||
switch(m_cmd[1] & 0x3) {
|
||||
case 0:
|
||||
if(len == 0) return;
|
||||
break;
|
||||
case 1: // Fixed
|
||||
break;
|
||||
case 2: // SILI
|
||||
break;
|
||||
case 3: // Illegal Request
|
||||
m_sts = 0x02;
|
||||
m_sel->m_sense.m_key = ILLEGAL_REQUEST;
|
||||
m_sel->m_sense.m_code = INVALID_FIELD_IN_CDB; /* "Invalid field in CDB" */
|
||||
m_sel->m_sense.m_key_specific[0] = ERROR_IN_OPCODE; /* "Error in Byte 1" */
|
||||
m_sel->m_sense.m_key_specific[1] = 0x00;
|
||||
m_sel->m_sense.m_key_specific[2] = 0x01;
|
||||
m_phase = PHASE_STATUSIN;
|
||||
return;
|
||||
}
|
||||
|
||||
LED_ON();
|
||||
writeDataPhase(len, m_responsebuffer);
|
||||
LED_OFF();
|
||||
|
||||
m_phase = PHASE_STATUSIN;
|
||||
}
|
||||
|
||||
/*
|
||||
* SEND Command processing.
|
||||
*/
|
||||
void onControlSendCommand(uint32_t adds, uint32_t len)
|
||||
{
|
||||
LOG("-W ");
|
||||
LOGHEX4N(len);
|
||||
|
||||
if(!m_sel) {
|
||||
m_sts |= STATUS_CHECK;
|
||||
m_phase = PHASE_STATUSIN;
|
||||
return;
|
||||
}
|
||||
if(len > MAX_BLOCKSIZE) {
|
||||
m_sel->m_sense.m_key = ILLEGAL_REQUEST;
|
||||
m_sel->m_sense.m_code = INVALID_FIELD_IN_CDB; /* "Invalid field in CDB" */
|
||||
m_sel->m_sense.m_key_specific[0] = ERROR_IN_OPCODE; /* "Error in Byte 4" */
|
||||
m_sel->m_sense.m_key_specific[1] = 0x00;
|
||||
m_sel->m_sense.m_key_specific[2] = 0x04;
|
||||
m_sts |= STATUS_CHECK;
|
||||
m_phase = PHASE_STATUSIN;
|
||||
return;
|
||||
}
|
||||
|
||||
LED_ON();
|
||||
readDataPhase(len, m_responsebuffer);
|
||||
LED_OFF();
|
||||
|
||||
m_phase = PHASE_STATUSIN;
|
||||
}
|
||||
|
||||
void ControlReceive6CommandHandler() {
|
||||
LOG("[Receive6]");
|
||||
onControlReceiveCommand((((uint32_t)m_cmd[1] & 0x1F) << 16) | ((uint32_t)m_cmd[2] << 8) | m_cmd[3], (m_cmd[4] == 0) ? 0x100 : m_cmd[4]);
|
||||
}
|
||||
|
||||
void ControlSend6CommandHandler() {
|
||||
LOG("[Send6]");
|
||||
onControlSendCommand((((uint32_t)m_cmd[1] & 0x1F) << 16) | ((uint32_t)m_cmd[2] << 8) | m_cmd[3], (m_cmd[4] == 0) ? 0x100 : m_cmd[4]);
|
||||
}
|
||||
|
||||
void ConfigureControlHandlers(VirtualDevice_t *vdev) {
|
||||
for(int c = 0; c < 256; c++)
|
||||
vdev->m_handler[c] = &UnknownCommandHandler;
|
||||
|
||||
vdev->m_handler[CMD_TEST_UNIT_READY] = &TestUnitCommandHandler;
|
||||
vdev->m_handler[CMD_REQUEST_SENSE] = &RequestSenseCommandHandler;
|
||||
vdev->m_handler[CMD_READ6] = &ControlReceive6CommandHandler;
|
||||
vdev->m_handler[CMD_WRITE6] = &ControlSend6CommandHandler;
|
||||
vdev->m_handler[CMD_INQUIRY] = &InquiryCommandHandler;
|
||||
vdev->m_handler[CMD_SEND_DIAGNOSTIC] = &SendDiagnosticCommandHandler;
|
||||
}
|
||||
|
||||
// If config file exists, read the first three lines and copy the contents.
|
||||
// File must be well formed or you will get junk in the SCSI Vendor fields.
|
||||
void ConfigureControl(VirtualDevice_t *vdev, const char *image_name) {
|
||||
for(int i = 0; SCSI_INQUIRY_RESPONSE[i][0] != 0xff; i++) {
|
||||
if(SCSI_INQUIRY_RESPONSE[i][0] == DEV_PROCESSOR) {
|
||||
memcpy(vdev->m_inquiryresponse, SCSI_INQUIRY_RESPONSE[i], SCSI_INQUIRY_RESPONSE_SIZE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
vdev->m_type = DEV_PROCESSOR;
|
||||
ConfigureControlHandlers(vdev);
|
||||
}
|
||||
#endif
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
// SCSI Drive Vendor information
|
||||
|
||||
static uint8_t SCSI_INQUIRY_RESPONSE[][SCSI_INQUIRY_RESPONSE_SIZE] = {
|
||||
uint8_t SCSI_INQUIRY_RESPONSE[][SCSI_INQUIRY_RESPONSE_SIZE] = {
|
||||
#if SUPPORT_SASI
|
||||
{
|
||||
0x00, //Device type
|
||||
|
@ -163,6 +163,24 @@ static uint8_t SCSI_INQUIRY_RESPONSE[][SCSI_INQUIRY_RESPONSE_SIZE] = {
|
|||
},
|
||||
#endif /* SUPPORT_TAPE */
|
||||
|
||||
|
||||
#if SUPPORT_CONTROL
|
||||
{
|
||||
DEV_PROCESSOR, //device type
|
||||
0x80, //RMB = 0
|
||||
0x03, //ISO, ECMA, ANSI version
|
||||
0x02, //Response data format
|
||||
37 - 4, //Additional data length
|
||||
0, //Reserve
|
||||
0x00, // Support function
|
||||
0x00, // Support function
|
||||
'G', 'R', 'N', 'S', 'C', 'S', 'I', ' ', // vendor 8
|
||||
'G', 'R', 'E', 'E', 'N', 'S', 'C', 'S', 'I', 'C', 'T','R', 'L', ' ', ' ', ' ', // product 16
|
||||
'G', 'S', 'C', '0', // version 4
|
||||
0
|
||||
},
|
||||
#endif /* SUPPORT_CONTROL */
|
||||
|
||||
// Invalid entry to mark end of data
|
||||
{
|
||||
0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00,
|
||||
|
|
|
@ -93,7 +93,14 @@
|
|||
*/
|
||||
#define DEV_DISK 0x00
|
||||
#define DEV_TAPE 0x01
|
||||
#define DEV_PRINTER 0x02
|
||||
#define DEV_PROCESSOR 0x03
|
||||
#define DEV_WORM 0x04
|
||||
#define DEV_OPTICAL 0x05
|
||||
#define DEV_SCANNER 0x06
|
||||
#define DEV_OMS 0x07
|
||||
#define DEV_CHANGER 0x08
|
||||
#define DEV_COMM 0x09
|
||||
|
||||
/*
|
||||
* SCSI MESSAGE CODES
|
||||
|
|
Loading…
Reference in New Issue