ConfigUtil.cc 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. // Copyright (C) 2014 Michael McMaster <michael@codesrc.com>
  2. //
  3. // This file is part of SCSI2SD.
  4. //
  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.
  9. //
  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.
  14. //
  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/>.
  17. #include "ConfigUtil.hh"
  18. #include <limits>
  19. #include <string.h>
  20. using namespace SCSI2SD;
  21. ADD QUIRKS MODES
  22. namespace
  23. {
  24. // Endian conversion routines.
  25. // The Cortex-M3 inside the Cypress PSoC 5LP is a
  26. // little-endian device.
  27. bool isHostLE()
  28. {
  29. union
  30. {
  31. int i;
  32. char c[sizeof(int)];
  33. } x;
  34. x.i = 1;
  35. return (x.c[0] == 1);
  36. }
  37. uint16_t toLE16(uint16_t in)
  38. {
  39. if (isHostLE())
  40. {
  41. return in;
  42. }
  43. else
  44. {
  45. return (in >> 8) | (in << 8);
  46. }
  47. }
  48. uint16_t fromLE16(uint16_t in)
  49. {
  50. return toLE16(in);
  51. }
  52. uint32_t toLE32(uint32_t in)
  53. {
  54. if (isHostLE())
  55. {
  56. return in;
  57. }
  58. else
  59. {
  60. return (in >> 24) |
  61. ((in >> 8) & 0xff00) |
  62. ((in << 8) & 0xff0000) |
  63. (in << 24);
  64. }
  65. }
  66. uint32_t fromLE32(uint32_t in)
  67. {
  68. return toLE32(in);
  69. }
  70. }
  71. TargetConfig
  72. ConfigUtil::Default(size_t targetIdx)
  73. {
  74. TargetConfig config;
  75. memset(&config, 0, sizeof(config));
  76. config.scsiId = targetIdx;
  77. if (targetIdx == 0)
  78. {
  79. config.scsiId = config.scsiId | CONFIG_TARGET_ENABLED;
  80. }
  81. config.deviceType = CONFIG_FIXED;
  82. // Default to maximum fail-safe options.
  83. config.flags = 0;// CONFIG_ENABLE_PARITY | CONFIG_ENABLE_UNIT_ATTENTION;
  84. config.deviceTypeModifier = 0;
  85. config.sdSectorStart = 0;
  86. // Default to 2GB. Many systems have trouble with > 2GB disks, and
  87. // a few start to complain at 1GB.
  88. config.scsiSectors = 4194303; // 2GB - 1 sector
  89. config.bytesPerSector = 512;
  90. config.sectorsPerTrack = 63;
  91. config.headsPerCylinder = 255;
  92. memcpy(config.vendor, " codesrc", 8);
  93. memcpy(config.prodId, " SCSI2SD", 16);
  94. memcpy(config.revision, " 4.0", 4);
  95. memcpy(config.serial, "1234567812345678", 16);
  96. // Reserved fields, already set to 0
  97. // config.reserved
  98. // not supported yet.
  99. // config.vpd
  100. return config;
  101. }
  102. TargetConfig
  103. ConfigUtil::fromBytes(const uint8_t* data)
  104. {
  105. TargetConfig result;
  106. memcpy(&result, data, sizeof(TargetConfig));
  107. result.sdSectorStart = toLE32(result.sdSectorStart);
  108. result.scsiSectors = toLE32(result.scsiSectors);
  109. result.bytesPerSector = toLE16(result.bytesPerSector);
  110. result.sectorsPerTrack = toLE16(result.sectorsPerTrack);
  111. result.headsPerCylinder = toLE16(result.headsPerCylinder);
  112. return result;
  113. }
  114. std::vector<uint8_t>
  115. ConfigUtil::toBytes(const TargetConfig& _config)
  116. {
  117. TargetConfig config(_config);
  118. config.sdSectorStart = fromLE32(config.sdSectorStart);
  119. config.scsiSectors = fromLE32(config.scsiSectors);
  120. config.bytesPerSector = fromLE16(config.bytesPerSector);
  121. config.sectorsPerTrack = fromLE16(config.sectorsPerTrack);
  122. config.headsPerCylinder = fromLE16(config.headsPerCylinder);
  123. const uint8_t* begin = reinterpret_cast<const uint8_t*>(&config);
  124. return std::vector<uint8_t>(begin, begin + sizeof(config));
  125. }
  126. wxXmlNode*
  127. ConfigUtil::toXML(const TargetConfig& config)
  128. {
  129. wxXmlNode* target = new wxXmlNode(wxXML_ELEMENT_NODE, "SCSITarget");
  130. {
  131. std::stringstream s; s << scsiId & CONFIG_TARGET_ID_BITS;
  132. target.AddAttribute("id", s.str());
  133. }
  134. {
  135. std::stringstream s; s << config.deviceType;
  136. new wxXmlNode(
  137. new wxXmlNode(target, wxXML_ELEMENT_NODE, "deviceType"),
  138. wxXML_TEXT_NODE, "", s.str());
  139. }
  140. {
  141. std::stringstream s; s << "0x" << std::hex << config.deviceTypeModifier;
  142. new wxXmlNode(
  143. new wxXmlNode(target, wxXML_ELEMENT_NODE, "deviceTypeModifier"),
  144. wxXML_TEXT_NODE, "", s.str());
  145. }
  146. wxXmlNode* flags(new wxXmlNode(target, wxXML_ELEMENT_NODE, "flags"));
  147. new wxXmlNode(
  148. new wxXmlNode(flags, wxXML_ELEMENT_NODE, "enabled"),
  149. wxXML_TEXT_NODE,
  150. "",
  151. config.scsiId & CONFIG_TARGET_ENABLED ? "true" : "false");
  152. "<unitAttention>" <<
  153. (config.flags & CONFIG_ENABLE_UNIT_ATTENTION ? "true" : "false") <<
  154. "</unitAttention>\n" <<
  155. "<parity>" <<
  156. (config.flags & CONFIG_ENABLE_PARITY ? "true" : "false") <<
  157. "</parity>\n" <<
  158. "<sdSectorStart>" << config.sdSectorStart << "</sdSectorStart>\n" <<
  159. "<scsiSectors>" << config.scsiSectors << "</scsiSectors>\n" <<
  160. "<bytesPerSector>" << config.bytesPerSector << "</bytesPerSector>\n" <<
  161. "<sectorsPerTrack>" << config.sectorsPerTrack<< "</sectorsPerTrack>\n" <<
  162. "<headsPerCylinder>" << config.headsPerCylinder << "</headsPerCylinder>\n" <<
  163. "<vendor>" << std::string(config.vendor, 8) << "</vendor>" <<
  164. "<prodId>" << std::string(config.prodId, 16) << "</prodId>" <<
  165. "<revision>" << std::string(config.revision, 4) << "</revision>" <<
  166. "<serial>" << std::string(config.serial, 16) << "</serial>" <<
  167. "</SCSITarget>";
  168. }
  169. void
  170. ConfigUtil::deserialise(const std::string& in)
  171. {
  172. }