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 "SCSI2SD_Bootloader.hh"
27 using namespace SCSI2SD;
29 hid_device* SCSI2SDHID_handle = NULL;
33 SCSI2SDHID_OpenConnection(void)
39 SCSI2SDHID_CloseConnection(void)
45 SCSI2SDHID_ReadData(unsigned char* data, int count)
48 buf[0] = 0; // Report ID
50 int result = hid_read(SCSI2SDHID_handle, buf, count);
54 std::cerr << "USB HID Read Failure: " <<
55 hid_error(SCSI2SDHID_handle) << std::endl;
58 memcpy(data, buf, count);
60 return (result >= 0) ? 0 : -1;
64 SCSI2SDHID_WriteData(unsigned char* data, int count)
67 buf[0] = 0; // report ID
69 for (i = 0; i < count; ++i)
74 for (int retry = 0; retry < 3 && result < 0; ++retry)
76 result = hid_write(SCSI2SDHID_handle, buf, count + 1);
81 std::cerr << "USB HID Write Failure: " <<
82 hid_error(SCSI2SDHID_handle) << std::endl;
85 return (result >= 0) ? 0 : -1;
88 static CyBtldr_CommunicationsData g_cyComms =
90 &SCSI2SDHID_OpenConnection,
91 &SCSI2SDHID_CloseConnection,
93 &SCSI2SDHID_WriteData,
94 Bootloader::HID_PACKET_SIZE
97 Bootloader::OperationScope::OperationScope()
100 if (CyBtldr_StartBootloadOperation(&g_cyComms, 0x2e133069, 0, &blVer)
103 throw std::runtime_error("Could not start bootloader operation");
107 Bootloader::OperationScope::~OperationScope()
109 CyBtldr_EndBootloadOperation();
112 Bootloader::Bootloader(hid_device_info* hidInfo) :
114 myBootloaderHandle(NULL)
116 myBootloaderHandle = hid_open_path(hidInfo->path);
117 if (!myBootloaderHandle)
119 std::stringstream msg;
120 msg << "Error opening HID device " << hidInfo->path << std::endl;
122 hid_free_enumeration(myHidInfo);
125 throw std::runtime_error(msg.str());
129 SCSI2SDHID_handle = myBootloaderHandle;
133 Bootloader::~Bootloader()
135 if (myBootloaderHandle)
137 hid_close(myBootloaderHandle);
139 SCSI2SDHID_handle = NULL;
141 hid_free_enumeration(myHidInfo);
147 hid_device_info* dev = hid_enumerate(VENDOR_ID, PRODUCT_ID);
150 return new Bootloader(dev);
159 Bootloader::getHWInfo() const
161 HWInfo info = {"unknown", "unknown", "unknown"};
163 switch (myHidInfo->release_number)
166 info.desc = "3.5\" SCSI2SD (green)";
167 info.version = "V3.0";
168 info.firmwareName = "SCSI2SD-V3.cyacd";
171 info.desc = "3.5\" SCSI2SD (yellow) or 2.5\" SCSI2SD for Apple Powerbook";
172 info.version = "V4.1/V4.2";
173 info.firmwareName = "SCSI2SD-V4.cyacd";
180 Bootloader::isCorrectFirmware(const std::string& path) const
182 HWInfo info = getHWInfo();
183 return path.rfind(info.firmwareName) != std::string::npos;
187 Bootloader::getDevicePath() const
189 return myHidInfo->path;
193 Bootloader::getManufacturer() const
195 return myHidInfo->manufacturer_string;
199 Bootloader::getProductString() const
201 return myHidInfo->product_string;
205 Bootloader::load(const std::string& path, void (*progress)(uint8_t, uint16_t))
207 int result = CyBtldr_Program(
214 throw std::runtime_error("Firmware update failed");
219 Bootloader::ping() const
223 Bootloader::OperationScope operationGuard;
225 int result = CyBtldr_VerifyRow(0, 0, 0);
229 case CYRET_ERR_CHECKSUM: // We supplied a dummy value of 0.
232 default: return false;
236 catch (std::exception& e)