V4.7 release fixes

This commit is contained in:
Michael McMaster 2017-03-12 14:15:05 +10:00
parent ecdf21796a
commit c75fbc8e6e
18 changed files with 437 additions and 289 deletions

View File

@ -1,5 +1,15 @@
2016xxxx 4.x
20170312 4.7
- Fix bug in SCSI Inquiry command for SCSI2 hosts
- Added OMTI host quirks mode
- Fix for booting from early Mac Plus ROMS
- Performance fix when SCSI2 mode is enabled. Some users may need
to disable SCSI2 mode if it was incorrectly enabled previously.
- Added support for configurable mode pages
- Fix for exporting selectionDelay/startupDelay parameters to XML
via scsi2sd-util
- scsi2sd-util is now built with libudev1 on Linux, as all distros have
moved to this version. Users on older Linux distributions will need to
compile from source.
20160111 4.6
- Fixed bug when using sector size that isn't a multiple of 4

View File

@ -33,7 +33,7 @@
#include <string.h>
static const uint16_t FIRMWARE_VERSION = 0x0460;
static const uint16_t FIRMWARE_VERSION = 0x0470;
// 1 flash row
static const uint8_t DEFAULT_CONFIG[256] =
@ -418,13 +418,24 @@ void configSave(int scsiId, uint16_t bytesPerSector)
const TargetConfig* getConfigByIndex(int i)
{
size_t row = SCSI_CONFIG_0_ROW + (i * SCSI_CONFIG_ROWS);
return (const TargetConfig*)
(
CY_FLASH_BASE +
(CY_FLASH_SIZEOF_ARRAY * (size_t) SCSI_CONFIG_ARRAY) +
(CY_FLASH_SIZEOF_ROW * row)
);
if (i <= 3)
{
size_t row = SCSI_CONFIG_0_ROW + (i * SCSI_CONFIG_ROWS);
return (const TargetConfig*)
(
CY_FLASH_BASE +
(CY_FLASH_SIZEOF_ARRAY * (size_t) SCSI_CONFIG_ARRAY) +
(CY_FLASH_SIZEOF_ROW * row)
);
} else {
size_t row = SCSI_CONFIG_4_ROW + ((i-4) * SCSI_CONFIG_ROWS);
return (const TargetConfig*)
(
CY_FLASH_BASE +
(CY_FLASH_SIZEOF_ARRAY * (size_t) SCSI_CONFIG_ARRAY) +
(CY_FLASH_SIZEOF_ROW * row)
);
}
}
const TargetConfig* getConfigById(int scsiId)

View File

@ -1,258 +1,267 @@
// Copyright (C) 2013 Michael McMaster <michael@codesrc.com>
//
// This file is part of SCSI2SD.
//
// SCSI2SD is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// SCSI2SD is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with SCSI2SD. If not, see <http://www.gnu.org/licenses/>.
#pragma GCC push_options
#pragma GCC optimize("-flto")
#include "device.h"
#include "scsi.h"
#include "config.h"
#include "inquiry.h"
#include <string.h>
static uint8 StandardResponse[] =
{
0x00, // "Direct-access device". AKA standard hard disk
0x00, // device type modifier
0x02, // Complies with ANSI SCSI-2.
0x01, // Response format is compatible with the old CCS format.
0x1f, // standard length.
0, 0, // Reserved
0x08 // Enable linked commands
};
// Vendor set by config 'c','o','d','e','s','r','c',' ',
// prodId set by config'S','C','S','I','2','S','D',' ',' ',' ',' ',' ',' ',' ',' ',' ',
// Revision set by config'2','.','0','a'
/* For reference, here's a dump from an Apple branded 500Mb drive from 1994.
$ sudo sg_inq -H /dev/sdd --len 255
standard INQUIRY:
00 00 00 02 01 31 00 00 18 51 55 41 4e 54 55 4d 20 ....1...QUANTUM
10 4c 50 53 32 37 30 20 20 20 20 20 20 20 20 20 20 LPS270
20 30 39 30 30 00 00 00 d9 b0 27 34 01 04 b3 01 1b 0900.....'4.....
30 07 00 a0 00 00 ff ......
Vendor identification: QUANTUM
Product identification: LPS270
Product revision level: 0900
*/
static const uint8 SupportedVitalPages[] =
{
0x00, // "Direct-access device". AKA standard hard disk
0x00, // Page Code
0x00, // Reserved
0x04, // Page length
0x00, // Support "Supported vital product data pages"
0x80, // Support "Unit serial number page"
0x81, // Support "Implemented operating definition page"
0x82 // Support "ASCII Implemented operating definition page"
};
static const uint8 UnitSerialNumber[] =
{
0x00, // "Direct-access device". AKA standard hard disk
0x80, // Page Code
0x00, // Reserved
0x10, // Page length
'c','o','d','e','s','r','c','-','1','2','3','4','5','6','7','8'
};
static const uint8 ImpOperatingDefinition[] =
{
0x00, // "Direct-access device". AKA standard hard disk
0x81, // Page Code
0x00, // Reserved
0x03, // Page length
0x03, // Current: SCSI-2 operating definition
0x03, // Default: SCSI-2 operating definition
0x03 // Supported (list): SCSI-2 operating definition.
};
static const uint8 AscImpOperatingDefinition[] =
{
0x00, // "Direct-access device". AKA standard hard disk
0x82, // Page Code
0x00, // Reserved
0x07, // Page length
0x06, // Ascii length
'S','C','S','I','-','2'
};
static void useCustomVPD(const TargetConfig* cfg, int pageCode)
{
int cfgIdx = 0;
int found = 0;
while ((cfgIdx < sizeof(cfg->vpd) - 4) &&
(cfg->vpd[cfgIdx + 3] != 0)
)
{
int pageSize = cfg->vpd[cfgIdx + 3] + 4;
int dataPageCode = cfg->vpd[cfgIdx + 1];
if (dataPageCode == pageCode)
{
memcpy(scsiDev.data, &(cfg->vpd[cfgIdx]), pageSize);
scsiDev.dataLen = pageSize;
scsiDev.phase = DATA_IN;
found = 1;
break;
}
cfgIdx += pageSize;
}
if (!found)
{
// error.
scsiDev.status = CHECK_CONDITION;
scsiDev.target->sense.code = ILLEGAL_REQUEST;
scsiDev.target->sense.asc = INVALID_FIELD_IN_CDB;
scsiDev.phase = STATUS;
}
}
void scsiInquiry()
{
uint8 evpd = scsiDev.cdb[1] & 1; // enable vital product data.
uint8 pageCode = scsiDev.cdb[2];
uint32 allocationLength = scsiDev.cdb[4];
// SASI standard, X3T9.3_185_RevE states that 0 == 256 bytes
if (allocationLength == 0) allocationLength = 256;
if (!evpd)
{
if (pageCode)
{
// error.
scsiDev.status = CHECK_CONDITION;
scsiDev.target->sense.code = ILLEGAL_REQUEST;
scsiDev.target->sense.asc = INVALID_FIELD_IN_CDB;
scsiDev.phase = STATUS;
}
else
{
const TargetConfig* config = scsiDev.target->cfg;
memcpy(scsiDev.data, StandardResponse, sizeof(StandardResponse));
scsiDev.data[1] = scsiDev.target->cfg->deviceTypeModifier;
memcpy(&scsiDev.data[8], config->vendor, sizeof(config->vendor));
memcpy(&scsiDev.data[16], config->prodId, sizeof(config->prodId));
memcpy(&scsiDev.data[32], config->revision, sizeof(config->revision));
scsiDev.dataLen = sizeof(StandardResponse) +
sizeof(config->vendor) +
sizeof(config->prodId) +
sizeof(config->revision);
scsiDev.phase = DATA_IN;
}
}
else if (scsiDev.target->cfg->vpd[3] != 0)
{
useCustomVPD(scsiDev.target->cfg, pageCode);
}
else if (pageCode == 0x00)
{
memcpy(scsiDev.data, SupportedVitalPages, sizeof(SupportedVitalPages));
scsiDev.dataLen = sizeof(SupportedVitalPages);
scsiDev.phase = DATA_IN;
}
else if (pageCode == 0x80)
{
memcpy(scsiDev.data, UnitSerialNumber, sizeof(UnitSerialNumber));
scsiDev.dataLen = sizeof(UnitSerialNumber);
scsiDev.phase = DATA_IN;
}
else if (pageCode == 0x81)
{
memcpy(
scsiDev.data,
ImpOperatingDefinition,
sizeof(ImpOperatingDefinition));
scsiDev.dataLen = sizeof(ImpOperatingDefinition);
scsiDev.phase = DATA_IN;
}
else if (pageCode == 0x82)
{
memcpy(
scsiDev.data,
AscImpOperatingDefinition,
sizeof(AscImpOperatingDefinition));
scsiDev.dataLen = sizeof(AscImpOperatingDefinition);
scsiDev.phase = DATA_IN;
}
else
{
// error.
scsiDev.status = CHECK_CONDITION;
scsiDev.target->sense.code = ILLEGAL_REQUEST;
scsiDev.target->sense.asc = INVALID_FIELD_IN_CDB;
scsiDev.phase = STATUS;
}
if (scsiDev.phase == DATA_IN)
{
// "real" hard drives send back exactly allocationLenth bytes, padded
// with zeroes. This only seems to happen for Inquiry responses, and not
// other commands that also supply an allocation length such as Mode Sense or
// Request Sense.
// (See below for exception to this rule when 0 allocation length)
if (scsiDev.dataLen < allocationLength)
{
memset(
&scsiDev.data[scsiDev.dataLen],
0,
allocationLength - scsiDev.dataLen);
}
// Spec 8.2.5 requires us to simply truncate the response if it's
// too big.
scsiDev.dataLen = allocationLength;
// Set the device type as needed.
switch (scsiDev.target->cfg->deviceType)
{
case CONFIG_OPTICAL:
scsiDev.data[0] = 0x05; // device type
scsiDev.data[1] |= 0x80; // Removable bit.
break;
case CONFIG_SEQUENTIAL:
scsiDev.data[0] = 0x01; // device type
scsiDev.data[1] |= 0x80; // Removable bit.
break;
case CONFIG_MO:
scsiDev.data[0] = 0x07; // device type
scsiDev.data[1] |= 0x80; // Removable bit.
break;
case CONFIG_FLOPPY_14MB:
case CONFIG_REMOVEABLE:
scsiDev.data[1] |= 0x80; // Removable bit.
break;
default:
// Accept defaults for a fixed disk.
break;
}
}
// Set the first byte to indicate LUN presence.
if (scsiDev.lun) // We only support lun 0
{
scsiDev.data[0] = 0x7F;
}
}
#pragma GCC pop_options
// Copyright (C) 2013 Michael McMaster <michael@codesrc.com>
//
// This file is part of SCSI2SD.
//
// SCSI2SD is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// SCSI2SD is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with SCSI2SD. If not, see <http://www.gnu.org/licenses/>.
#pragma GCC push_options
#pragma GCC optimize("-flto")
#include "device.h"
#include "scsi.h"
#include "config.h"
#include "inquiry.h"
#include <string.h>
static uint8 StandardResponse[] =
{
0x00, // "Direct-access device". AKA standard hard disk
0x00, // device type modifier
0x02, // Complies with ANSI SCSI-2.
0x01, // Response format is compatible with the old CCS format.
0x1f, // standard length.
0, 0, // Reserved
0x08 // Enable linked commands
};
// Vendor set by config 'c','o','d','e','s','r','c',' ',
// prodId set by config'S','C','S','I','2','S','D',' ',' ',' ',' ',' ',' ',' ',' ',' ',
// Revision set by config'2','.','0','a'
/* For reference, here's a dump from an Apple branded 500Mb drive from 1994.
$ sudo sg_inq -H /dev/sdd --len 255
standard INQUIRY:
00 00 00 02 01 31 00 00 18 51 55 41 4e 54 55 4d 20 ....1...QUANTUM
10 4c 50 53 32 37 30 20 20 20 20 20 20 20 20 20 20 LPS270
20 30 39 30 30 00 00 00 d9 b0 27 34 01 04 b3 01 1b 0900.....'4.....
30 07 00 a0 00 00 ff ......
Vendor identification: QUANTUM
Product identification: LPS270
Product revision level: 0900
*/
static const uint8 SupportedVitalPages[] =
{
0x00, // "Direct-access device". AKA standard hard disk
0x00, // Page Code
0x00, // Reserved
0x04, // Page length
0x00, // Support "Supported vital product data pages"
0x80, // Support "Unit serial number page"
0x81, // Support "Implemented operating definition page"
0x82 // Support "ASCII Implemented operating definition page"
};
static const uint8 UnitSerialNumber[] =
{
0x00, // "Direct-access device". AKA standard hard disk
0x80, // Page Code
0x00, // Reserved
0x10, // Page length
'c','o','d','e','s','r','c','-','1','2','3','4','5','6','7','8'
};
static const uint8 ImpOperatingDefinition[] =
{
0x00, // "Direct-access device". AKA standard hard disk
0x81, // Page Code
0x00, // Reserved
0x03, // Page length
0x03, // Current: SCSI-2 operating definition
0x03, // Default: SCSI-2 operating definition
0x03 // Supported (list): SCSI-2 operating definition.
};
static const uint8 AscImpOperatingDefinition[] =
{
0x00, // "Direct-access device". AKA standard hard disk
0x82, // Page Code
0x00, // Reserved
0x07, // Page length
0x06, // Ascii length
'S','C','S','I','-','2'
};
static void useCustomVPD(const TargetConfig* cfg, int pageCode)
{
int cfgIdx = 0;
int found = 0;
while ((cfgIdx < sizeof(cfg->vpd) - 4) &&
(cfg->vpd[cfgIdx + 3] != 0)
)
{
int pageSize = cfg->vpd[cfgIdx + 3] + 4;
int dataPageCode = cfg->vpd[cfgIdx + 1];
if (dataPageCode == pageCode)
{
memcpy(scsiDev.data, &(cfg->vpd[cfgIdx]), pageSize);
scsiDev.dataLen = pageSize;
scsiDev.phase = DATA_IN;
found = 1;
break;
}
cfgIdx += pageSize;
}
if (!found)
{
// error.
scsiDev.status = CHECK_CONDITION;
scsiDev.target->sense.code = ILLEGAL_REQUEST;
scsiDev.target->sense.asc = INVALID_FIELD_IN_CDB;
scsiDev.phase = STATUS;
}
}
void scsiInquiry()
{
uint8 evpd = scsiDev.cdb[1] & 1; // enable vital product data.
uint8 pageCode = scsiDev.cdb[2];
uint32 allocationLength = scsiDev.cdb[4];
// SASI standard, X3T9.3_185_RevE states that 0 == 256 bytes
// BUT SCSI 2 standard says 0 == 0.
if (scsiDev.compatMode <= COMPAT_SCSI1) // excludes COMPAT_SCSI2_DISABLED
{
if (allocationLength == 0) allocationLength = 256;
}
if (!evpd)
{
if (pageCode)
{
// error.
scsiDev.status = CHECK_CONDITION;
scsiDev.target->sense.code = ILLEGAL_REQUEST;
scsiDev.target->sense.asc = INVALID_FIELD_IN_CDB;
scsiDev.phase = STATUS;
}
else
{
const TargetConfig* config = scsiDev.target->cfg;
memcpy(scsiDev.data, StandardResponse, sizeof(StandardResponse));
scsiDev.data[1] = scsiDev.target->cfg->deviceTypeModifier;
if (scsiDev.compatMode >= COMPAT_SCSI2)
{
scsiDev.data[3] = 2; // SCSI 2 response format.
}
memcpy(&scsiDev.data[8], config->vendor, sizeof(config->vendor));
memcpy(&scsiDev.data[16], config->prodId, sizeof(config->prodId));
memcpy(&scsiDev.data[32], config->revision, sizeof(config->revision));
scsiDev.dataLen = sizeof(StandardResponse) +
sizeof(config->vendor) +
sizeof(config->prodId) +
sizeof(config->revision);
scsiDev.phase = DATA_IN;
}
}
else if (scsiDev.target->cfg->vpd[3] != 0)
{
useCustomVPD(scsiDev.target->cfg, pageCode);
}
else if (pageCode == 0x00)
{
memcpy(scsiDev.data, SupportedVitalPages, sizeof(SupportedVitalPages));
scsiDev.dataLen = sizeof(SupportedVitalPages);
scsiDev.phase = DATA_IN;
}
else if (pageCode == 0x80)
{
memcpy(scsiDev.data, UnitSerialNumber, sizeof(UnitSerialNumber));
scsiDev.dataLen = sizeof(UnitSerialNumber);
scsiDev.phase = DATA_IN;
}
else if (pageCode == 0x81)
{
memcpy(
scsiDev.data,
ImpOperatingDefinition,
sizeof(ImpOperatingDefinition));
scsiDev.dataLen = sizeof(ImpOperatingDefinition);
scsiDev.phase = DATA_IN;
}
else if (pageCode == 0x82)
{
memcpy(
scsiDev.data,
AscImpOperatingDefinition,
sizeof(AscImpOperatingDefinition));
scsiDev.dataLen = sizeof(AscImpOperatingDefinition);
scsiDev.phase = DATA_IN;
}
else
{
// error.
scsiDev.status = CHECK_CONDITION;
scsiDev.target->sense.code = ILLEGAL_REQUEST;
scsiDev.target->sense.asc = INVALID_FIELD_IN_CDB;
scsiDev.phase = STATUS;
}
if (scsiDev.phase == DATA_IN)
{
// "real" hard drives send back exactly allocationLenth bytes, padded
// with zeroes. This only seems to happen for Inquiry responses, and not
// other commands that also supply an allocation length such as Mode Sense or
// Request Sense.
// (See below for exception to this rule when 0 allocation length)
if (scsiDev.dataLen < allocationLength)
{
memset(
&scsiDev.data[scsiDev.dataLen],
0,
allocationLength - scsiDev.dataLen);
}
// Spec 8.2.5 requires us to simply truncate the response if it's
// too big.
scsiDev.dataLen = allocationLength;
// Set the device type as needed.
switch (scsiDev.target->cfg->deviceType)
{
case CONFIG_OPTICAL:
scsiDev.data[0] = 0x05; // device type
scsiDev.data[1] |= 0x80; // Removable bit.
break;
case CONFIG_SEQUENTIAL:
scsiDev.data[0] = 0x01; // device type
scsiDev.data[1] |= 0x80; // Removable bit.
break;
case CONFIG_MO:
scsiDev.data[0] = 0x07; // device type
scsiDev.data[1] |= 0x80; // Removable bit.
break;
case CONFIG_FLOPPY_14MB:
case CONFIG_REMOVEABLE:
scsiDev.data[1] |= 0x80; // Removable bit.
break;
default:
// Accept defaults for a fixed disk.
break;
}
}
// Set the first byte to indicate LUN presence.
if (scsiDev.lun) // We only support lun 0
{
scsiDev.data[0] = 0x7F;
}
}
#pragma GCC pop_options

View File

@ -33,6 +33,7 @@
#include "debug.h"
#include "tape.h"
#include "mo.h"
#include "vendor.h"
#include <string.h>
@ -138,6 +139,16 @@ void process_Status()
uint8 message;
uint8 control = scsiDev.cdb[scsiDev.cdbLen - 1];
if (scsiDev.target->cfg->quirks == CONFIG_QUIRKS_OMTI)
{
// OMTI non-standard LINK control
if (control & 0x01)
{
scsiDev.phase = COMMAND; return;
}
}
if ((scsiDev.status == GOOD) && (control & 0x01))
{
// Linked command.
@ -155,6 +166,10 @@ void process_Status()
{
message = MSG_COMMAND_COMPLETE;
}
// TODO OMTI ENABLE VIA CONFIG
// scsiDev.status |= (scsiDev.target->targetId & 0x03) << 5 ;
scsiWriteByte(scsiDev.status);
scsiDev.lastStatus = scsiDev.status;
@ -403,7 +418,7 @@ static void process_Command()
{
scsiReadBuffer();
}
else if (!scsiModeCommand())
else if (!scsiModeCommand() && !scsiVendorCommand())
{
scsiDev.target->sense.code = ILLEGAL_REQUEST;
scsiDev.target->sense.asc = INVALID_COMMAND_OPERATION_CODE;
@ -566,7 +581,7 @@ static void process_SelectionPhase()
// Only read these pins AFTER SEL and BSY - we don't want to catch them
// during a transition period.
uint8 mask = scsiReadDBxPins();
uint8 mask = (selLatchCfg && scsiDev.selFlag) ? scsiDev.selDBX : scsiReadDBxPins();
int maskBitCount = countBits(mask);
int goodParity = (Lookup_OddParity[mask] == SCSI_ReadPin(SCSI_In_DBP));
int atnFlag = SCSI_ReadFilt(SCSI_Filt_ATN);
@ -617,9 +632,9 @@ static void process_SelectionPhase()
}
else if (!(scsiDev.boardCfg.flags & CONFIG_ENABLE_SCSI2))
{
scsiDev.compatMode = COMPAT_SCSI1;
scsiDev.compatMode = COMPAT_SCSI2_DISABLED;
}
else if (scsiDev.compatMode == COMPAT_UNKNOWN)
else
{
scsiDev.compatMode = COMPAT_SCSI2;
}

View File

@ -61,6 +61,11 @@ typedef enum
{
COMPAT_UNKNOWN,
COMPAT_SCSI1,
// Messages are being used, yet SCSI 2 mode is disabled.
// This impacts interpretation of INQUIRY commands.
COMPAT_SCSI2_DISABLED,
COMPAT_SCSI2
} SCSI_COMPAT_MODE;
@ -106,12 +111,14 @@ typedef struct
// Set to true (1) if the RST flag was set.
volatile int resetFlag;
// Set to true (1) if the SEL flag was set.
volatile int selFlag;
// Set to true (1) if a parity error was observed.
int parityError;
int parityError;
volatile int selDBX;
int phase;

View File

@ -80,6 +80,9 @@ CY_ISR(scsiSelectionISR)
// selFlag is required for Philips P2000C which releases it after 600ns
// without waiting for BSY.
scsiDev.selFlag = 1;
// Required for some early Mac Plus roms
scsiDev.selDBX = scsiReadDBxPins();
}
uint8_t

View File

@ -144,6 +144,13 @@
<build_action v="C_FILE" />
<PropertyDeltas />
</CyGuid_8b8ab257-35d3-4473-b57b-36315200b38b>
<CyGuid_8b8ab257-35d3-4473-b57b-36315200b38b type_name="CyDesigner.Common.ProjMgmt.Model.CyPrjMgmtFile" version="3" xml_contents_version="1">
<CyGuid_31768f72-0253-412b-af77-e7dba74d1330 type_name="CyDesigner.Common.ProjMgmt.Model.CyPrjMgmtItem" version="2" name="vendor.c" persistent="..\..\src\vendor.c">
<Hidden v="False" />
</CyGuid_31768f72-0253-412b-af77-e7dba74d1330>
<build_action v="C_FILE" />
<PropertyDeltas />
</CyGuid_8b8ab257-35d3-4473-b57b-36315200b38b>
</dependencies>
</CyGuid_0820c2e7-528d-4137-9a08-97257b946089>
</CyGuid_2f73275c-45bf-46ba-b3b1-00a2fe0c8dd8>
@ -308,6 +315,13 @@
<build_action v="NONE" />
<PropertyDeltas />
</CyGuid_8b8ab257-35d3-4473-b57b-36315200b38b>
<CyGuid_8b8ab257-35d3-4473-b57b-36315200b38b type_name="CyDesigner.Common.ProjMgmt.Model.CyPrjMgmtFile" version="3" xml_contents_version="1">
<CyGuid_31768f72-0253-412b-af77-e7dba74d1330 type_name="CyDesigner.Common.ProjMgmt.Model.CyPrjMgmtItem" version="2" name="vendor.h" persistent="..\..\src\vendor.h">
<Hidden v="False" />
</CyGuid_31768f72-0253-412b-af77-e7dba74d1330>
<build_action v="NONE" />
<PropertyDeltas />
</CyGuid_8b8ab257-35d3-4473-b57b-36315200b38b>
</dependencies>
</CyGuid_0820c2e7-528d-4137-9a08-97257b946089>
</CyGuid_2f73275c-45bf-46ba-b3b1-00a2fe0c8dd8>

View File

@ -144,6 +144,13 @@
<build_action v="C_FILE" />
<PropertyDeltas />
</CyGuid_8b8ab257-35d3-4473-b57b-36315200b38b>
<CyGuid_8b8ab257-35d3-4473-b57b-36315200b38b type_name="CyDesigner.Common.ProjMgmt.Model.CyPrjMgmtFile" version="3" xml_contents_version="1">
<CyGuid_31768f72-0253-412b-af77-e7dba74d1330 type_name="CyDesigner.Common.ProjMgmt.Model.CyPrjMgmtItem" version="2" name="vendor.c" persistent="..\..\src\vendor.c">
<Hidden v="False" />
</CyGuid_31768f72-0253-412b-af77-e7dba74d1330>
<build_action v="C_FILE" />
<PropertyDeltas />
</CyGuid_8b8ab257-35d3-4473-b57b-36315200b38b>
</dependencies>
</CyGuid_0820c2e7-528d-4137-9a08-97257b946089>
</CyGuid_2f73275c-45bf-46ba-b3b1-00a2fe0c8dd8>
@ -308,6 +315,13 @@
<build_action v="NONE" />
<PropertyDeltas />
</CyGuid_8b8ab257-35d3-4473-b57b-36315200b38b>
<CyGuid_8b8ab257-35d3-4473-b57b-36315200b38b type_name="CyDesigner.Common.ProjMgmt.Model.CyPrjMgmtFile" version="3" xml_contents_version="1">
<CyGuid_31768f72-0253-412b-af77-e7dba74d1330 type_name="CyDesigner.Common.ProjMgmt.Model.CyPrjMgmtItem" version="2" name="vendor.h" persistent="..\..\src\vendor.h">
<Hidden v="False" />
</CyGuid_31768f72-0253-412b-af77-e7dba74d1330>
<build_action v="NONE" />
<PropertyDeltas />
</CyGuid_8b8ab257-35d3-4473-b57b-36315200b38b>
</dependencies>
</CyGuid_0820c2e7-528d-4137-9a08-97257b946089>
</CyGuid_2f73275c-45bf-46ba-b3b1-00a2fe0c8dd8>

View File

@ -46,8 +46,18 @@ extern "C" {
|Row 188 | Config target 0
---------------------------------
|Row 187 | Board Config
| ... | Empty
|Row 172 | Empty
---------------------------------
|Row 186 |
|Row 171 |
| ... |
|Row 156 | Config target 6
| ... |
|Row 140 | Config target 5
| ... |
|Row 124 | Config target 4
---------------------------------
|Row 123 |
| ... |
|Row 0 |
--------| |
@ -65,6 +75,7 @@ extern "C" {
#include "stdint.h"
//#define MAX_SCSI_TARGETS 7
#define MAX_SCSI_TARGETS 4
#define SCSI_CONFIG_ARRAY 1
#define SCSI_CONFIG_ROWS 16
@ -77,6 +88,9 @@ extern "C" {
#define SCSI_CONFIG_1_ROW 204
#define SCSI_CONFIG_2_ROW 220
#define SCSI_CONFIG_3_ROW 236
#define SCSI_CONFIG_4_ROW 124
#define SCSI_CONFIG_5_ROW 140
#define SCSI_CONFIG_6_ROW 156
typedef enum
{
@ -110,7 +124,8 @@ typedef enum
typedef enum
{
CONFIG_QUIRKS_NONE,
CONFIG_QUIRKS_APPLE
CONFIG_QUIRKS_APPLE,
CONFIG_QUIRKS_OMTI
} CONFIG_QUIRKS;
typedef struct __attribute__((packed))

41
software/scsi2sd-util/ConfigUtil.cc Normal file → Executable file
View File

@ -248,9 +248,19 @@ ConfigUtil::toXML(const TargetConfig& config)
" <!-- ********************************************************\n" <<
" Space separated list. Available options:\n" <<
" apple\t\tReturns Apple-specific mode pages\n" <<
" omti\t\tOMTI host non-standard link control\n" <<
" ********************************************************* -->\n" <<
" <quirks>" <<
(config.quirks & CONFIG_QUIRKS_APPLE ? "apple" : "") <<
" <quirks>";
if (config.quirks == CONFIG_QUIRKS_APPLE)
{
s << "apple";
}
else if (config.quirks == CONFIG_QUIRKS_OMTI)
{
s << "omti";
}
s <<
"</quirks>\n" <<
"\n\n" <<
@ -393,6 +403,19 @@ ConfigUtil::toXML(const BoardConfig& config)
" <mapLunsToIds>" <<
(config.flags & CONFIG_MAP_LUNS_TO_IDS ? "true" : "false") <<
"</mapLunsToIds>\n" <<
" <!-- ********************************************************\n" <<
" Delay (in milliseconds) before responding to a SCSI selection.\n" <<
" 255 (auto) sets it to 0 for SCSI2 hosts and 1ms otherwise.\n" <<
" Some samplers need this set to 1 manually.\n" <<
" ********************************************************* -->\n" <<
" <selectionDelay>" << static_cast<int>(config.selectionDelay) << "</selectionDelay>\n" <<
" <!-- ********************************************************\n" <<
" Startup delay (in seconds) before responding to the SCSI bus \n" <<
" after power on. Default = 0.\n" <<
" ********************************************************* -->\n" <<
" <startupDelay>" << static_cast<int>(config.startupDelay) << "</startupDelay>\n" <<
"</BoardConfig>\n";
return s.str();
@ -471,6 +494,10 @@ parseTarget(wxXmlNode* node)
{
result.quirks |= CONFIG_QUIRKS_APPLE;
}
else if (quirk == "omti")
{
result.quirks |= CONFIG_QUIRKS_OMTI;
}
}
}
else if (child->GetName() == "deviceType")
@ -559,7 +586,15 @@ parseBoardConfig(wxXmlNode* node)
wxXmlNode *child = node->GetChildren();
while (child)
{
if (child->GetName() == "unitAttention")
if (child->GetName() == "selectionDelay")
{
result.selectionDelay = parseInt(child, 255);
}
else if (child->GetName() == "startupDelay")
{
result.startupDelay = parseInt(child, 255);
}
else if (child->GetName() == "unitAttention")
{
std::string s(child->GetNodeContent().mb_str());
if (s == "true")

View File

@ -42,7 +42,8 @@ LDFLAGS += -L$(BUILD)/libzipper/.libs -lzipper $(LDFLAGS_ZLIB) $(LDFLAGS_HIDAPI)
# wxWidgets 3.0.2 uses broken Webkit headers under OSX Yosemeti
# liblzma not available on OSX 10.7
WX_CONFIG=--disable-webkit --disable-webviewwebkit \
# --disable-mediactrl for missing Quicktime.h on Mac OSX Sierra
WX_CONFIG=--disable-webkit --disable-webviewwebkit --disable-mediactrl \
--without-libtiff --without-libjbig --without-liblzma --without-opengl \
--enable-monolithic --enable-stl --disable-shared
@ -80,6 +81,13 @@ ifeq ($(TARGET),Darwin)
CXX=clang++ -stdlib=libc++ -mmacosx-version-min=10.7
WX_CONFIG += --with-macosx-version-min=10.7
BUILD := $(PWD)/build/mac
all: $(BUILD)/scsi2sd-util.dmg
$(BUILD)/scsi2sd-util.dmg: $(BUILD)/scsi2sd-util $(BUILD)/scsi2sd-monitor
mkdir -p $(dir $@)/dmg
cp $(BUILD)/scsi2sd-util $(BUILD)/scsi2sd-monitor $(dir $@)/dmg
chmod a+rx $(dir $@)/dmg/*
hdiutil create -srcfolder $(dir $@)/dmg $@
endif
export CC CXX

2
software/scsi2sd-util/TargetPanel.cc Normal file → Executable file
View File

@ -312,7 +312,7 @@ TargetPanel::evaluate()
{
case CONFIG_OPTICAL:
mySectorSizeCtrl->ChangeValue("2048");
mySectorSizeCtrl->Enable(false);
mySectorSizeCtrl->Enable(true); // Enable override
break;
case CONFIG_FLOPPY_14MB:
mySectorSizeCtrl->ChangeValue("512");

View File

@ -570,7 +570,7 @@ private:
std::vector<zipper::CompressedFilePtr> files(decomp.getEntries());
for (auto it(files.begin()); it != files.end(); it++)
{
if (myBootloader->isCorrectFirmware((*it)->getPath()))
if (myBootloader && myBootloader->isCorrectFirmware((*it)->getPath()))
{
std::stringstream msg;
msg << "Found firmware entry " << (*it)->getPath() <<
@ -1007,11 +1007,13 @@ private:
}
}
flashRow = SCSI_CONFIG_0_ROW;
for (size_t i = 0;
i < myTargets.size();
++i, flashRow += SCSI_CONFIG_ROWS)
++i)
{
flashRow = (i <= 3)
? SCSI_CONFIG_0_ROW + (i*SCSI_CONFIG_ROWS)
: SCSI_CONFIG_4_ROW + ((i-4)*SCSI_CONFIG_ROWS);
std::vector<uint8_t> raw(sizeof(TargetConfig));
for (size_t j = 0; j < SCSI_CONFIG_ROWS; ++j)
@ -1135,8 +1137,12 @@ private:
flashRow = SCSI_CONFIG_0_ROW;
for (size_t i = 0;
i < myTargets.size();
++i, flashRow += SCSI_CONFIG_ROWS)
++i)
{
flashRow = (i <= 3)
? SCSI_CONFIG_0_ROW + (i*SCSI_CONFIG_ROWS)
: SCSI_CONFIG_4_ROW + ((i-4)*SCSI_CONFIG_ROWS);
TargetConfig config(myTargets[i]->getConfig());
std::vector<uint8_t> raw(ConfigUtil::toBytes(config));

View File

@ -30,7 +30,7 @@
#include "wx/osx/private.h"
#if wxOSX_USE_COCOA_OR_CARBON
#include <QuickTime/QuickTime.h>
// #include <QuickTime/QuickTime.h>
#endif
// ----------------------------------------------------------------------------

View File

@ -36,7 +36,7 @@ IMPLEMENT_DYNAMIC_CLASS(wxMask, wxObject)
#endif
#ifndef __WXOSX_IPHONE__
#include <QuickTime/QuickTime.h>
//#include <QuickTime/QuickTime.h>
#endif
CGColorSpaceRef wxMacGetGenericRGBColorSpace();

View File

@ -11,6 +11,7 @@
#include <ctype.h>
#include <assert.h>
#include <cmath>
#include <string>
#include <vector>
#include <map>
@ -5841,9 +5842,9 @@ void Editor::GoToLine(int lineNo) {
}
static bool Close(Point pt1, Point pt2) {
if (abs(pt1.x - pt2.x) > 3)
if (std::abs(pt1.x - pt2.x) > 3)
return false;
if (abs(pt1.y - pt2.y) > 3)
if (std::abs(pt1.y - pt2.y) > 3)
return false;
return true;
}