Skip to content

Commit

Permalink
scsi: allow for switching of any removable media
Browse files Browse the repository at this point in the history
  • Loading branch information
erichelgeson committed Oct 21, 2024
1 parent e054e13 commit e5d63c9
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 25 deletions.
2 changes: 1 addition & 1 deletion lib/SCSI2SD/src/firmware/scsi.c
Original file line number Diff line number Diff line change
Expand Up @@ -1340,7 +1340,7 @@ void scsiInit()
// won't respond properly to
// LOGICAL_UNIT_NOT_READY_INITIALIZING_COMMAND_REQUIRED sense
// code
scsiDev.targets[i].started = 1;
scsiDev.targets[i].started = true;
}
firstInit = 0;
}
Expand Down
2 changes: 1 addition & 1 deletion lib/SCSI2SD/src/firmware/scsi.h
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ typedef struct
uint8_t syncOffset;
uint8_t syncPeriod;

uint8_t started; // Controlled by START STOP UNIT
bool started; // Controlled by START STOP UNIT
} TargetState;

typedef struct
Expand Down
6 changes: 3 additions & 3 deletions src/BlueSCSI_cdrom.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1149,7 +1149,7 @@ bool cdromValidateCueSheet(image_config_t &img)
/* Ejection and image switching logic */
/**************************************/

// Close CDROM tray and note media change event
// Close CD-ROM tray and note media change event
void cdromCloseTray(image_config_t &img)
{
if (img.ejected)
Expand All @@ -1167,7 +1167,7 @@ void cdromCloseTray(image_config_t &img)
}
}

// Eject CDROM tray if closed, close if open
// Eject CD-ROM tray if closed, close if open
// Switch image on ejection.
void cdromPerformEject(image_config_t &img)
{
Expand All @@ -1189,7 +1189,7 @@ void cdromPerformEject(image_config_t &img)
}
}

// Reinsert any ejected CDROMs on reboot
// Reinsert any ejected CD-ROMs on reboot
void cdromReinsertFirstImage(image_config_t &img)
{
if (img.image_index > 0)
Expand Down
71 changes: 53 additions & 18 deletions src/BlueSCSI_disk.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
// Copyright (C) 2013 Michael McMaster <michael@codesrc.com>
// Copyright (C) 2014 Doug Brown <doug@downtowndougbrown.com>
// Copyright (C) 2022 Rabbit Hole Computing
// Copyright (C) 2024 Eric Helgeson <erichelgeson@gmail.com>

#include "BlueSCSI_disk.h"
#include "BlueSCSI_log.h"
Expand Down Expand Up @@ -775,19 +776,19 @@ static int findNextImageAfter(image_config_t &img,
}
}

int scsiDiskGetNextImageName(image_config_t &img, char *buf, size_t buflen)
int scsiDiskGetNextImageName(image_config_t &img, char *buf, size_t buf_len)
{
int target_idx = img.scsiId & S2S_CFG_TARGET_ID_BITS;

// sanity check: is provided buffer is long enough to store a filename?
assert(buflen >= MAX_FILE_PATH);
assert(buf_len >= MAX_FILE_PATH);

if (img.image_directory)
{
// image directory was found during startup
char dirname[MAX_FILE_PATH];
int dirlen = getImgDir(target_idx, dirname);
if (!dirlen)
int dir_len = getImgDir(target_idx, dirname);
if (!dir_len)
{
// If image_directory set but ImgDir is not look for a well known ImgDir
if(img.deviceType == S2S_CFG_OPTICAL)
Expand All @@ -807,7 +808,7 @@ int scsiDiskGetNextImageName(image_config_t &img, char *buf, size_t buflen)
dirname[2] = '0' + target_idx;
if(!SD.exists(dirname))
{
debuglog("ERROR: Looking for ", dirname, " to load images, but was not found.");
log("ERROR: Looking for ", dirname, " to load images, but was not found.");
return 0;
}
}
Expand All @@ -821,18 +822,18 @@ int scsiDiskGetNextImageName(image_config_t &img, char *buf, size_t buflen)
log("Image directory was empty for ID", target_idx);
return 0;
}
else if (buflen < nextlen + dirlen + 2)
else if (buf_len < nextlen + dir_len + 2)
{
log("Directory '", dirname, "' and file '", nextname, "' exceed allowed length");
return 0;
}
else
{
// construct a return value
strncpy(buf, dirname, buflen);
strncpy(buf, dirname, buf_len);
if (buf[strlen(buf) - 1] != '/') strcat(buf, "/");
strcat(buf, nextname);
return dirlen + nextlen;
return dir_len + nextlen;
}
}
else
Expand All @@ -853,7 +854,7 @@ int scsiDiskGetNextImageName(image_config_t &img, char *buf, size_t buflen)
// there may be more than one image but we've ran out of new ones
// wrap back to the first image
img.image_index = -1;
return scsiDiskGetNextImageName(img, buf, buflen);
return scsiDiskGetNextImageName(img, buf, buf_len);
}
else
{
Expand Down Expand Up @@ -1365,9 +1366,9 @@ static void doReadCapacity()
/* TestUnitReady command */
/*************************/

static int doTestUnitReady()
static bool doTestUnitReady()
{
int ready = 1;
bool ready = true;
image_config_t &img = *(image_config_t*)scsiDev.target->cfg;
if (unlikely(!scsiDev.target->started || !img.file.isOpen()))
{
Expand All @@ -1379,7 +1380,7 @@ static int doTestUnitReady()
}
else if (img.ejected)
{
ready = 0;
ready = false;
scsiDev.status = CHECK_CONDITION;
scsiDev.target->sense.code = NOT_READY;
scsiDev.target->sense.asc = MEDIUM_NOT_PRESENT;
Expand All @@ -1389,20 +1390,23 @@ static int doTestUnitReady()
{
// We are now reporting to host that the drive is open.
// Simulate a "close" for next time the host polls.
cdromCloseTray(img);
if(img.deviceType == S2S_CFG_OPTICAL)
cdromCloseTray(img);
else if(img.deviceType != S2S_CFG_FIXED)
removableInsert(img);
}
}
else if (unlikely(!(blockDev.state & DISK_PRESENT)))
{
ready = 0;
ready = false;
scsiDev.status = CHECK_CONDITION;
scsiDev.target->sense.code = NOT_READY;
scsiDev.target->sense.asc = MEDIUM_NOT_PRESENT;
scsiDev.phase = STATUS;
}
else if (unlikely(!(blockDev.state & DISK_INITIALISED)))
{
ready = 0;
ready = false;
scsiDev.status = CHECK_CONDITION;
scsiDev.target->sense.code = NOT_READY;
scsiDev.target->sense.asc = LOGICAL_UNIT_NOT_READY_CAUSE_NOT_REPORTABLE;
Expand Down Expand Up @@ -1956,6 +1960,31 @@ static void diskDataIn()
}
}

void removableInsert(image_config_t &img) {
if(img.ejected) {
uint8_t target = img.scsiId & S2S_CFG_TARGET_ID_BITS;
debuglog("------ Removable inserted on ID ", (int)target);
img.ejected = false;

if (scsiDev.boardCfg.flags & S2S_CFG_ENABLE_UNIT_ATTENTION)
{
debuglog("------ Posting UNIT ATTENTION after medium change");
scsiDev.targets[target].unitAttention = NOT_READY_TO_READY_TRANSITION_MEDIUM_MAY_HAVE_CHANGED;
}
}
}

void removableEject(image_config_t &img)
{
uint8_t target = img.scsiId & S2S_CFG_TARGET_ID_BITS;
if(!img.ejected) {
debuglog(" ----- Ejecting target ID ", (int)target);
img.ejected = true;
switchNextImage(img);
} else {
removableInsert(img);
}
}

/********************/
/* Command dispatch */
Expand All @@ -1978,11 +2007,17 @@ int scsiDiskCommand()

if (start)
{
scsiDev.target->started = 1;
if(img.deviceType == S2S_CFG_FIXED)
scsiDev.target->started = true;
else
removableInsert(img);
}
else
else // Stop
{
scsiDev.target->started = 0;
if(img.deviceType == S2S_CFG_FIXED)
scsiDev.target->started = false;
else
removableEject(img);
}
}
else if (unlikely(command == 0x00))
Expand Down
11 changes: 9 additions & 2 deletions src/BlueSCSI_disk.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
* SCSI2SD V6 - Copyright (C) 2013 Michael McMaster <michael@codesrc.com>
* Copyright (C) 2014 Doug Brown <doug@downtowndougbrown.com
* ZuluSCSI™ - Copyright (c) 2022 Rabbit Hole Computing™
* Copyright (C) 2024 Eric Helgeson <erichelgeson@gmail.com>
*
* It is derived from disk.h in SCSI2SD V6.
*
Expand Down Expand Up @@ -129,7 +130,7 @@ bool scsiDiskCheckAnyImagesConfigured();
// images. As a side effect this advances image tracking to the next image.
// Returns the length of the new image filename, or 0 if the target is not
// configured for multiple images.
int scsiDiskGetNextImageName(image_config_t &img, char *buf, size_t buflen);
int scsiDiskGetNextImageName(image_config_t &img, char *buf, size_t buf_len);

// Get pointer to extended image configuration based on target idx
image_config_t &scsiDiskGetImageConfig(int target_idx);
Expand All @@ -145,4 +146,10 @@ void scsiDiskStartWrite(uint32_t lba, uint32_t blocks);
bool scsiDiskCheckAnyNetworkDevicesConfigured();

// Switch to next Drive image if multiple have been configured
bool switchNextImage(image_config_t &img, const char* next_filename = nullptr);
bool switchNextImage(image_config_t &img, const char* next_filename = nullptr);

// For removable, non-CD based images
void removableInsert(image_config_t &img);

// For removable, non-CD based images
void removableEject(image_config_t &img);

0 comments on commit e5d63c9

Please sign in to comment.