diff --git a/src/ZuluSCSI_disk.cpp b/src/ZuluSCSI_disk.cpp index 1b3c60fb..514cd717 100644 --- a/src/ZuluSCSI_disk.cpp +++ b/src/ZuluSCSI_disk.cpp @@ -1,24 +1,24 @@ -/** +/** * SCSI2SD V6 - Copyright (C) 2013 Michael McMaster * Portions Copyright (C) 2014 Doug Brown * Portions Copyright (C) 2023 Eric Helgeson * ZuluSCSI™ - Copyright (c) 2022-2023 Rabbit Hole Computing™ - * + * * This file is licensed under the GPL version 3 or any later version.  * It is derived from disk.c in SCSI2SD V6 - * + * * https://www.gnu.org/licenses/gpl-3.0.html * ---- * This program 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.  - * + * * This program 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 this program.  If not, see . **/ @@ -92,7 +92,7 @@ void scsiStartRead(uint8_t* data, uint32_t count, int *parityError) } void scsiFinishRead(uint8_t* data, uint32_t count, int *parityError) { - + } bool scsiIsReadFinished(const uint8_t *data) { @@ -234,7 +234,7 @@ static void formatDriveInfoField(char *field, int fieldsize, bool align_right) } } -// remove path and extension from filename +// remove path and extension from filename void extractFileName(const char* path, char* output) { const char *lastSlash, *lastDot; @@ -260,7 +260,7 @@ void setNameFromImage(image_config_t &img, const char *filename) { extractFileName(filename, image_name); memset(img.vendor, 0, 8); - strncpy(img.vendor, image_name, 8); + strncpy(img.vendor, image_name, 8); memset(img.prodId, 0, 8); strncpy(img.prodId, image_name+8, 8); } @@ -295,7 +295,7 @@ static void setDefaultDriveInfo(int target_idx) switch (img.deviceType) { case S2S_CFG_FIXED: driveinfo = apl_driveinfo_fixed; break; - case S2S_CFG_REMOVABLE: driveinfo = apl_driveinfo_removable; break; + case S2S_CFG_REMOVABLE: driveinfo = apl_driveinfo_removable; break; case S2S_CFG_OPTICAL: driveinfo = apl_driveinfo_optical; break; case S2S_CFG_FLOPPY_14MB: driveinfo = apl_driveinfo_floppy; break; case S2S_CFG_MO: driveinfo = apl_driveinfo_magopt; break; @@ -310,12 +310,12 @@ static void setDefaultDriveInfo(int target_idx) switch (img.deviceType) { case S2S_CFG_FIXED: driveinfo = driveinfo_fixed; break; - case S2S_CFG_REMOVABLE: driveinfo = driveinfo_removable; break; + case S2S_CFG_REMOVABLE: driveinfo = driveinfo_removable; break; case S2S_CFG_OPTICAL: driveinfo = driveinfo_optical; break; case S2S_CFG_FLOPPY_14MB: driveinfo = driveinfo_floppy; break; case S2S_CFG_MO: driveinfo = driveinfo_magopt; break; - case S2S_CFG_SEQUENTIAL: driveinfo = driveinfo_tape; break; case S2S_CFG_NETWORK: driveinfo = driveinfo_network; break; + case S2S_CFG_SEQUENTIAL: driveinfo = driveinfo_tape; break; default: driveinfo = driveinfo_fixed; break; } } @@ -386,7 +386,7 @@ bool scsiDiskOpenHDDImage(int target_idx, const char *filename, int scsi_id, int img.scsiSectors = img.file.size() / blocksize; img.scsiId = scsi_id | S2S_CFG_TARGET_ENABLED; img.sdSectorStart = 0; - + if (type != S2S_CFG_NETWORK && img.scsiSectors == 0) { logmsg("---- Error: image file ", filename, " is empty"); @@ -450,9 +450,9 @@ bool scsiDiskOpenHDDImage(int target_idx, const char *filename, int scsi_id, int #endif quirksCheck(&img); - if (img.name_from_image) - { - setNameFromImage(img, filename); + if (img.name_from_image) + { + setNameFromImage(img, filename); logmsg("---- Vendor / product id set from image file name"); } @@ -609,9 +609,9 @@ static void scsiDiskLoadConfig(int target_idx, const char *section) img.deviceTypeModifier = ini_getl(section, "TypeModifier", img.deviceTypeModifier, CONFIGFILE); img.sectorsPerTrack = ini_getl(section, "SectorsPerTrack", img.sectorsPerTrack, CONFIGFILE); img.headsPerCylinder = ini_getl(section, "HeadsPerCylinder", img.headsPerCylinder, CONFIGFILE); - img.quirks = ini_getl(section, "Quirks", img.quirks, CONFIGFILE); + img.quirks = ini_getl(section, "Quirks", img.quirks, CONFIGFILE); img.rightAlignStrings = ini_getbool(section, "RightAlignStrings", 0, CONFIGFILE); - img.name_from_image = ini_getbool(section, "NameFromImage", 0, CONFIGFILE); + img.name_from_image = ini_getbool(section, "NameFromImage", 0, CONFIGFILE); img.prefetchbytes = ini_getl(section, "PrefetchBytes", img.prefetchbytes, CONFIGFILE); img.reinsert_on_inquiry = ini_getbool(section, "ReinsertCDOnInquiry", img.reinsert_on_inquiry, CONFIGFILE); img.reinsert_after_eject = ini_getbool(section, "ReinsertAfterEject", img.reinsert_after_eject, CONFIGFILE); @@ -634,7 +634,7 @@ static void scsiDiskLoadConfig(int target_idx, const char *section) memset(tmp, 0, sizeof(tmp)); ini_gets(section, "Version", "", tmp, sizeof(tmp), CONFIGFILE); if (tmp[0]) memcpy(img.revision, tmp, sizeof(img.revision)); - + memset(tmp, 0, sizeof(tmp)); ini_gets(section, "Serial", "", tmp, sizeof(tmp), CONFIGFILE); if (tmp[0]) memcpy(img.serial, tmp, sizeof(img.serial)); @@ -1028,7 +1028,7 @@ void s2s_configInit(S2S_BoardCfg* config) config->scsiSpeed = S2S_CFG_SPEED_ASYNC_50; else if (maxSyncSpeed < 10 && config->scsiSpeed > S2S_CFG_SPEED_SYNC_5) config->scsiSpeed = S2S_CFG_SPEED_SYNC_5; - + logmsg("-- SelectionDelay = ", (int)config->selectionDelay); if (ini_getbool("SCSI", "EnableUnitAttention", defaults.enableUnitAttention, CONFIGFILE)) @@ -1477,7 +1477,7 @@ void diskDataOut_callback(uint32_t bytes_complete) // How many bytes remaining in the transfer? uint32_t remain = g_disk_transfer.bytes_scsi - g_disk_transfer.bytes_scsi_started; uint32_t len = remain; - + // Split read so that it doesn't wrap around buffer edge uint32_t bufsize = sizeof(scsiDev.data); uint32_t start = (g_disk_transfer.bytes_scsi_started % bufsize); @@ -1581,7 +1581,7 @@ void diskDataOut() } if (len < min_write_size) - { + { len = 0; } } @@ -1655,7 +1655,7 @@ void scsiDiskStartRead(uint32_t lba, uint32_t blocks) image_config_t &img = *(image_config_t*)scsiDev.target->cfg; uint32_t bytesPerSector = scsiDev.target->liveCfg.bytesPerSector; uint32_t capacity = img.file.size() / bytesPerSector; - + dbgmsg("------ Read ", (int)blocks, "x", (int)bytesPerSector, " starting at ", (int)lba); if (unlikely(((uint64_t) lba) + blocks > capacity)) @@ -1749,7 +1749,7 @@ void diskDataIn_callback(uint32_t bytes_complete) scsiStartWrite(g_disk_transfer.buffer + g_disk_transfer.bytes_scsi, len); g_disk_transfer.bytes_scsi += len; } - + // Provide a chance for polling request processing scsiIsWriteFinished(NULL); } @@ -1761,7 +1761,7 @@ static void start_dataInTransfer(uint8_t *buffer, uint32_t count) g_disk_transfer.buffer = buffer; g_disk_transfer.bytes_scsi = 0; g_disk_transfer.bytes_sd = count; - + // Verify that previous write using this buffer has finished uint32_t start = millis(); while (!scsiIsWriteFinished(buffer + count - 1) && !scsiDev.resetFlag) @@ -1803,7 +1803,7 @@ static void diskDataIn() uint32_t bytesPerSector = scsiDev.target->liveCfg.bytesPerSector; uint32_t maxblocks = sizeof(scsiDev.data) / bytesPerSector; uint32_t maxblocks_half = maxblocks / 2; - + // Start transfer in first half of buffer // Waits for the previous first half transfer to finish first. uint32_t remain = (transfer.blocks - transfer.currentBlock); @@ -1839,7 +1839,7 @@ static void diskDataIn() g_scsi_prefetch.sector = transfer.lba + transfer.blocks; g_scsi_prefetch.bytes = 0; g_scsi_prefetch.scsiId = scsiDev.target->cfg->scsiId; - + if (g_scsi_prefetch.sector + prefetch_sectors > img_sector_count) { // Don't try to read past image end. diff --git a/src/ZuluSCSI_initiator.cpp b/src/ZuluSCSI_initiator.cpp index f3d77c21..0ca296de 100644 --- a/src/ZuluSCSI_initiator.cpp +++ b/src/ZuluSCSI_initiator.cpp @@ -1,26 +1,26 @@ -/** +/** * ZuluSCSI™ - Copyright (c) 2022 Rabbit Hole Computing™ - * + * * ZuluSCSI™ firmware is licensed under the GPL version 3 or any later version.  - * + * * https://www.gnu.org/licenses/gpl-3.0.html * ---- * This program 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.  - * + * * This program 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 this program.  If not, see . **/ -/* +/* * Main program for initiator mode. */ @@ -172,6 +172,8 @@ void scsiInitiatorMainLoop() delay_with_poll(1000); uint8_t inquiry_data[36]; + char vendor[9], product[17], revision[5]; + int type; LED_ON(); bool startstopok = @@ -185,6 +187,15 @@ void scsiInitiatorMainLoop() bool inquiryok = startstopok && scsiInquiry(g_initiator_state.target_id, inquiry_data); + + memcpy(vendor, &inquiry_data[8], 8); + vendor[8]=0; + memcpy(product, &inquiry_data[16], 16); + product[16]=0; + memcpy(revision, &inquiry_data[32], 4); + revision[4]=0; + type=inquiry_data[0]&0x1f; + LED_OFF(); uint64_t total_bytes = 0; @@ -194,6 +205,12 @@ void scsiInitiatorMainLoop() " capacity ", (int)g_initiator_state.sectorcount, " sectors x ", (int)g_initiator_state.sectorsize, " bytes"); + logmsg("[SCSI", g_initiator_state.target_id,"]"); + logmsg(" Vendor = \"", vendor,"\""); + logmsg(" Product = \"", product,"\""); + logmsg(" Version = \"", revision,"\""); + logmsg(" Type = ", type); + g_initiator_state.sectorcount_all = g_initiator_state.sectorcount; total_bytes = (uint64_t)g_initiator_state.sectorcount * g_initiator_state.sectorsize; @@ -509,14 +526,14 @@ bool scsiInitiatorReadCapacity(int target_id, uint32_t *sectorcount, uint32_t *s command, sizeof(command), response, sizeof(response), NULL, 0); - + if (status == 0) { *sectorcount = ((uint32_t)response[0] << 24) | ((uint32_t)response[1] << 16) | ((uint32_t)response[2] << 8) | ((uint32_t)response[3] << 0); - + *sectorcount += 1; // SCSI reports last sector address *sectorsize = ((uint32_t)response[4] << 24) @@ -538,7 +555,7 @@ bool scsiInitiatorReadCapacity(int target_id, uint32_t *sectorcount, uint32_t *s *sectorcount = *sectorsize = 0; return false; } -} +} // Execute REQUEST SENSE command to get more information about error status bool scsiRequestSense(int target_id, uint8_t *sense_key) @@ -647,7 +664,7 @@ static struct { uint32_t bytes_sd_scheduled; // Number of bytes scheduled for transfer on SD card side uint32_t bytes_scsi; // Number of bytes that have been scheduled for transfer on SCSI side uint32_t bytes_scsi_done; // Number of bytes that have been transferred on SCSI side - + uint32_t bytes_per_sector; bool all_ok; } g_initiator_transfer; @@ -686,7 +703,7 @@ static void initiatorReadSDCallback(uint32_t bytes_complete) uint32_t sd_ready_cnt = g_initiator_transfer.bytes_sd + bytes_complete; if (g_initiator_transfer.bytes_scsi_done + len > sd_ready_cnt + bufsize) len = sd_ready_cnt + bufsize - g_initiator_transfer.bytes_scsi_done; - + if (sd_ready_cnt == g_initiator_transfer.bytes_sd_scheduled && g_initiator_transfer.bytes_sd_scheduled + bytesPerSector <= g_initiator_transfer.bytes_scsi_done) {