| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206 | //	Copyright (C) 2014 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/>.#include "ConfigUtil.hh"#include <limits>#include <string.h>using namespace SCSI2SD;namespace{	// Endian conversion routines.	// The Cortex-M3 inside the Cypress PSoC 5LP is a	// little-endian device.	bool isHostLE()	{		union		{			int i;			char c[sizeof(int)];		} x;		x.i = 1;		return (x.c[0] == 1);	}	uint16_t toLE16(uint16_t in)	{		if (isHostLE())		{			return in;		}		else		{			return (in >> 8) | (in << 8);		}	}	uint16_t fromLE16(uint16_t in)	{		return toLE16(in);	}	uint32_t toLE32(uint32_t in)	{		if (isHostLE())		{			return in;		}		else		{			return (in >> 24) |				((in >> 8) & 0xff00) |				((in << 8) & 0xff0000) |				(in << 24);		}	}	uint32_t fromLE32(uint32_t in)	{		return toLE32(in);	}}TargetConfigConfigUtil::Default(size_t targetIdx){	TargetConfig config;	memset(&config, 0, sizeof(config));	config.scsiId = targetIdx;	if (targetIdx == 0)	{		config.scsiId = config.scsiId | CONFIG_TARGET_ENABLED;	}	config.deviceType = CONFIG_FIXED;	// Default to maximum fail-safe options.	config.flags = 0;// CONFIG_ENABLE_PARITY | CONFIG_ENABLE_UNIT_ATTENTION;	config.deviceTypeModifier = 0;	config.sdSectorStart = 0;	// Default to 2GB. Many systems have trouble with > 2GB disks, and	// a few start to complain at 1GB.	config.scsiSectors = 4194303; // 2GB - 1 sector	config.bytesPerSector = 512;	config.sectorsPerTrack = 63;	config.headsPerCylinder = 255;	memcpy(config.vendor, " codesrc", 8);	memcpy(config.prodId, "         SCSI2SD", 16);	memcpy(config.revision, " 4.2", 4);	memcpy(config.serial, "1234567812345678", 16);	// Reserved fields, already set to 0	// config.reserved	// not supported yet.	// config.vpd	return config;}TargetConfigConfigUtil::fromBytes(const uint8_t* data){	TargetConfig result;	memcpy(&result, data, sizeof(TargetConfig));	result.sdSectorStart = toLE32(result.sdSectorStart);	result.scsiSectors = toLE32(result.scsiSectors);	result.bytesPerSector = toLE16(result.bytesPerSector);	result.sectorsPerTrack = toLE16(result.sectorsPerTrack);	result.headsPerCylinder = toLE16(result.headsPerCylinder);	return result;}std::vector<uint8_t>ConfigUtil::toBytes(const TargetConfig& _config){	TargetConfig config(_config);	config.sdSectorStart = fromLE32(config.sdSectorStart);	config.scsiSectors = fromLE32(config.scsiSectors);	config.bytesPerSector = fromLE16(config.bytesPerSector);	config.sectorsPerTrack = fromLE16(config.sectorsPerTrack);	config.headsPerCylinder = fromLE16(config.headsPerCylinder);	const uint8_t* begin = reinterpret_cast<const uint8_t*>(&config);	return std::vector<uint8_t>(begin, begin + sizeof(config));}/*wxXmlNode*ConfigUtil::toXML(const TargetConfig& config){	wxXmlNode* target = new wxXmlNode(wxXML_ELEMENT_NODE, "SCSITarget");	{		std::stringstream s; s << scsiId & CONFIG_TARGET_ID_BITS;		target.AddAttribute("id", s.str());	}	{		std::stringstream s; s << config.deviceType;		new wxXmlNode(			new wxXmlNode(target, wxXML_ELEMENT_NODE, "deviceType"),			wxXML_TEXT_NODE, "", s.str());	}	{		std::stringstream s; s << "0x" << std::hex << config.deviceTypeModifier;		new wxXmlNode(			new wxXmlNode(target, wxXML_ELEMENT_NODE, "deviceTypeModifier"),			wxXML_TEXT_NODE, "", s.str());	}	wxXmlNode* flags(new wxXmlNode(target, wxXML_ELEMENT_NODE, "flags"));	new wxXmlNode(		new wxXmlNode(flags, wxXML_ELEMENT_NODE, "enabled"),		wxXML_TEXT_NODE,		"",		config.scsiId & CONFIG_TARGET_ENABLED ? "true" : "false");				"<unitAttention>" <<					(config.flags & CONFIG_ENABLE_UNIT_ATTENTION ? "true" : "false") <<				"</unitAttention>\n" <<				"<parity>" <<					(config.flags & CONFIG_ENABLE_PARITY ? "true" : "false") <<				"</parity>\n" <<			"<sdSectorStart>" << config.sdSectorStart << "</sdSectorStart>\n" <<			"<scsiSectors>" << config.scsiSectors << "</scsiSectors>\n" <<			"<bytesPerSector>" << config.bytesPerSector << "</bytesPerSector>\n" <<			"<sectorsPerTrack>" << config.sectorsPerTrack<< "</sectorsPerTrack>\n" <<			"<headsPerCylinder>" << config.headsPerCylinder << "</headsPerCylinder>\n" <<			"<vendor>" << std::string(config.vendor, 8) << "</vendor>" <<			"<prodId>" << std::string(config.prodId, 16) << "</prodId>" <<			"<revision>" << std::string(config.revision, 4) << "</revision>" <<			"<serial>" << std::string(config.serial, 16) << "</serial>" <<		"</SCSITarget>";}voidConfigUtil::deserialise(const std::string& in){}*/
 |