1 // Copyright (C) 2014 Michael McMaster <michael@codesrc.com>
3 // This file is part of SCSI2SD.
5 // SCSI2SD is free software: you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation, either version 3 of the License, or
8 // (at your option) any later version.
10 // SCSI2SD is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
15 // You should have received a copy of the GNU General Public License
16 // along with SCSI2SD. If not, see <http://www.gnu.org/licenses/>.
18 #include "ConfigUtil.hh"
25 using namespace SCSI2SD
;
30 // Endian conversion routines.
31 // The Cortex-M3 inside the Cypress PSoC 5LP is a
32 // little-endian device.
45 uint16_t toLE16(uint16_t in
)
53 return (in
>> 8) | (in
<< 8);
56 uint16_t fromLE16(uint16_t in
)
61 uint32_t toLE32(uint32_t in
)
70 ((in
>> 8) & 0xff00) |
71 ((in
<< 8) & 0xff0000) |
75 uint32_t fromLE32(uint32_t in
)
83 ConfigUtil::Default(size_t targetIdx
)
86 memset(&config
, 0, sizeof(config
));
88 config
.scsiId
= targetIdx
;
91 config
.scsiId
= config
.scsiId
| CONFIG_TARGET_ENABLED
;
93 config
.deviceType
= CONFIG_FIXED
;
95 // Default to maximum fail-safe options.
96 config
.flags
= 0;// CONFIG_ENABLE_PARITY | CONFIG_ENABLE_UNIT_ATTENTION;
97 config
.deviceTypeModifier
= 0;
98 config
.sdSectorStart
= 0;
100 // Default to 2GB. Many systems have trouble with > 2GB disks, and
101 // a few start to complain at 1GB.
102 config
.scsiSectors
= 4194303; // 2GB - 1 sector
103 config
.bytesPerSector
= 512;
104 config
.sectorsPerTrack
= 63;
105 config
.headsPerCylinder
= 255;
106 memcpy(config
.vendor
, " codesrc", 8);
107 memcpy(config
.prodId
, " SCSI2SD", 16);
108 memcpy(config
.revision
, " 4.0", 4);
109 memcpy(config
.serial
, "1234567812345678", 16);
111 // Reserved fields, already set to 0
114 // not supported yet.
122 ConfigUtil::fromBytes(const uint8_t* data
)
125 memcpy(&result
, data
, sizeof(TargetConfig
));
126 result
.sdSectorStart
= toLE32(result
.sdSectorStart
);
127 result
.scsiSectors
= toLE32(result
.scsiSectors
);
128 result
.bytesPerSector
= toLE16(result
.bytesPerSector
);
129 result
.sectorsPerTrack
= toLE16(result
.sectorsPerTrack
);
130 result
.headsPerCylinder
= toLE16(result
.headsPerCylinder
);
136 ConfigUtil::toBytes(const TargetConfig
& _config
)
138 TargetConfig
config(_config
);
139 config
.sdSectorStart
= fromLE32(config
.sdSectorStart
);
140 config
.scsiSectors
= fromLE32(config
.scsiSectors
);
141 config
.bytesPerSector
= fromLE16(config
.bytesPerSector
);
142 config
.sectorsPerTrack
= fromLE16(config
.sectorsPerTrack
);
143 config
.headsPerCylinder
= fromLE16(config
.headsPerCylinder
);
145 const uint8_t* begin
= reinterpret_cast<const uint8_t*>(&config
);
146 return std::vector
<uint8_t>(begin
, begin
+ sizeof(config
));
150 ConfigUtil::toXML(const TargetConfig
& config
)
152 wxXmlNode
* target
= new wxXmlNode(wxXML_ELEMENT_NODE
, "SCSITarget");
155 std::stringstream s
; s
<< scsiId
& CONFIG_TARGET_ID_BITS
;
156 target
.AddAttribute("id", s
.str());
159 std::stringstream s
; s
<< config
.deviceType
;
161 new wxXmlNode(target
, wxXML_ELEMENT_NODE
, "deviceType"),
162 wxXML_TEXT_NODE
, "", s
.str());
166 std::stringstream s
; s
<< "0x" << std::hex
<< config
.deviceTypeModifier
;
168 new wxXmlNode(target
, wxXML_ELEMENT_NODE
, "deviceTypeModifier"),
169 wxXML_TEXT_NODE
, "", s
.str());
172 wxXmlNode
* flags(new wxXmlNode(target
, wxXML_ELEMENT_NODE
, "flags"));
175 new wxXmlNode(flags
, wxXML_ELEMENT_NODE
, "enabled"),
178 config
.scsiId
& CONFIG_TARGET_ENABLED
? "true" : "false");
181 (config
.flags
& CONFIG_ENABLE_UNIT_ATTENTION
? "true" : "false") <<
182 "</unitAttention>\n" <<
184 (config
.flags
& CONFIG_ENABLE_PARITY
? "true" : "false") <<
187 "<sdSectorStart>" << config
.sdSectorStart
<< "</sdSectorStart>\n" <<
188 "<scsiSectors>" << config
.scsiSectors
<< "</scsiSectors>\n" <<
189 "<bytesPerSector>" << config
.bytesPerSector
<< "</bytesPerSector>\n" <<
190 "<sectorsPerTrack>" << config
.sectorsPerTrack
<< "</sectorsPerTrack>\n" <<
191 "<headsPerCylinder>" << config
.headsPerCylinder
<< "</headsPerCylinder>\n" <<
193 "<vendor>" << std::string(config
.vendor
, 8) << "</vendor>" <<
194 "<prodId>" << std::string(config
.prodId
, 16) << "</prodId>" <<
195 "<revision>" << std::string(config
.revision
, 4) << "</revision>" <<
196 "<serial>" << std::string(config
.serial
, 16) << "</serial>" <<
202 ConfigUtil::deserialise(const std::string
& in
)