|
@@ -81,11 +81,19 @@ static struct {
|
|
|
uint32_t sectorcount_all;
|
|
uint32_t sectorcount_all;
|
|
|
uint32_t sectors_done;
|
|
uint32_t sectors_done;
|
|
|
uint32_t max_sector_per_transfer;
|
|
uint32_t max_sector_per_transfer;
|
|
|
|
|
+ uint32_t bad_sector_count;
|
|
|
|
|
+ uint8_t ansi_version;
|
|
|
|
|
+ uint8_t max_retry_count;
|
|
|
|
|
+ uint8_t device_type;
|
|
|
|
|
|
|
|
// Retry information for sector reads.
|
|
// Retry information for sector reads.
|
|
|
// If a large read fails, retry is done sector-by-sector.
|
|
// If a large read fails, retry is done sector-by-sector.
|
|
|
int retrycount;
|
|
int retrycount;
|
|
|
uint32_t failposition;
|
|
uint32_t failposition;
|
|
|
|
|
+ bool eject_when_done;
|
|
|
|
|
+ bool removable;
|
|
|
|
|
+
|
|
|
|
|
+ uint32_t removable_count[8];
|
|
|
|
|
|
|
|
FsFile target_file;
|
|
FsFile target_file;
|
|
|
} g_initiator_state;
|
|
} g_initiator_state;
|
|
@@ -103,6 +111,12 @@ void scsiInitiatorInit()
|
|
|
logmsg("InitiatorID set to illegal value in, ", CONFIGFILE, ", defaulting to 7");
|
|
logmsg("InitiatorID set to illegal value in, ", CONFIGFILE, ", defaulting to 7");
|
|
|
g_initiator_state.initiator_id = 7;
|
|
g_initiator_state.initiator_id = 7;
|
|
|
}
|
|
}
|
|
|
|
|
+ else
|
|
|
|
|
+ {
|
|
|
|
|
+ logmsg("InitiatorID set to ID ", g_initiator_state.initiator_id);
|
|
|
|
|
+ }
|
|
|
|
|
+ g_initiator_state.max_retry_count = ini_getl("SCSI", "InitiatorMaxRetry", 5, CONFIGFILE);
|
|
|
|
|
+
|
|
|
// treat initiator id as already imaged drive so it gets skipped
|
|
// treat initiator id as already imaged drive so it gets skipped
|
|
|
g_initiator_state.drives_imaged = 1 << g_initiator_state.initiator_id;
|
|
g_initiator_state.drives_imaged = 1 << g_initiator_state.initiator_id;
|
|
|
|
|
|
|
@@ -114,7 +128,12 @@ void scsiInitiatorInit()
|
|
|
g_initiator_state.retrycount = 0;
|
|
g_initiator_state.retrycount = 0;
|
|
|
g_initiator_state.failposition = 0;
|
|
g_initiator_state.failposition = 0;
|
|
|
g_initiator_state.max_sector_per_transfer = 512;
|
|
g_initiator_state.max_sector_per_transfer = 512;
|
|
|
-
|
|
|
|
|
|
|
+ g_initiator_state.ansi_version = 0;
|
|
|
|
|
+ g_initiator_state.bad_sector_count = 0;
|
|
|
|
|
+ g_initiator_state.device_type = SCSI_DEVICE_TYPE_DIRECT_ACCESS;
|
|
|
|
|
+ g_initiator_state.removable = false;
|
|
|
|
|
+ g_initiator_state.eject_when_done = false;
|
|
|
|
|
+ memset(g_initiator_state.removable_count, 0, sizeof(g_initiator_state.removable_count));
|
|
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -150,6 +169,30 @@ void delay_with_poll(uint32_t ms)
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+static int scsiTypeToIniType(int scsi_type, bool removable)
|
|
|
|
|
+{
|
|
|
|
|
+ int ini_type = -1;
|
|
|
|
|
+ switch (scsi_type)
|
|
|
|
|
+ {
|
|
|
|
|
+ case SCSI_DEVICE_TYPE_DIRECT_ACCESS:
|
|
|
|
|
+ ini_type = removable ? S2S_CFG_REMOVABLE : S2S_CFG_FIXED;
|
|
|
|
|
+ break;
|
|
|
|
|
+ case 1:
|
|
|
|
|
+ ini_type = -1; // S2S_CFG_SEQUENTIAL
|
|
|
|
|
+ break;
|
|
|
|
|
+ case SCSI_DEVICE_TYPE_CD:
|
|
|
|
|
+ ini_type = S2S_CFG_OPTICAL;
|
|
|
|
|
+ break;
|
|
|
|
|
+ case SCSI_DEVICE_TYPE_MO:
|
|
|
|
|
+ ini_type = S2S_CFG_MO;
|
|
|
|
|
+ break;
|
|
|
|
|
+ default:
|
|
|
|
|
+ ini_type = -1;
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ return ini_type;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
// High level logic of the initiator mode
|
|
// High level logic of the initiator mode
|
|
|
void scsiInitiatorMainLoop()
|
|
void scsiInitiatorMainLoop()
|
|
|
{
|
|
{
|
|
@@ -166,14 +209,14 @@ void scsiInitiatorMainLoop()
|
|
|
g_initiator_state.sectors_done = 0;
|
|
g_initiator_state.sectors_done = 0;
|
|
|
g_initiator_state.retrycount = 0;
|
|
g_initiator_state.retrycount = 0;
|
|
|
g_initiator_state.max_sector_per_transfer = 512;
|
|
g_initiator_state.max_sector_per_transfer = 512;
|
|
|
|
|
+ g_initiator_state.bad_sector_count = 0;
|
|
|
|
|
+ g_initiator_state.eject_when_done = false;
|
|
|
|
|
|
|
|
if (!(g_initiator_state.drives_imaged & (1 << g_initiator_state.target_id)))
|
|
if (!(g_initiator_state.drives_imaged & (1 << g_initiator_state.target_id)))
|
|
|
{
|
|
{
|
|
|
delay_with_poll(1000);
|
|
delay_with_poll(1000);
|
|
|
|
|
|
|
|
- uint8_t inquiry_data[36];
|
|
|
|
|
- char vendor[9], product[17], revision[5];
|
|
|
|
|
- int type;
|
|
|
|
|
|
|
+ uint8_t inquiry_data[36] = {0};
|
|
|
|
|
|
|
|
LED_ON();
|
|
LED_ON();
|
|
|
bool startstopok =
|
|
bool startstopok =
|
|
@@ -188,14 +231,6 @@ void scsiInitiatorMainLoop()
|
|
|
bool inquiryok = startstopok &&
|
|
bool inquiryok = startstopok &&
|
|
|
scsiInquiry(g_initiator_state.target_id, inquiry_data);
|
|
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();
|
|
LED_OFF();
|
|
|
|
|
|
|
|
uint64_t total_bytes = 0;
|
|
uint64_t total_bytes = 0;
|
|
@@ -205,12 +240,6 @@ void scsiInitiatorMainLoop()
|
|
|
" capacity ", (int)g_initiator_state.sectorcount,
|
|
" capacity ", (int)g_initiator_state.sectorcount,
|
|
|
" sectors x ", (int)g_initiator_state.sectorsize, " bytes");
|
|
" 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;
|
|
g_initiator_state.sectorcount_all = g_initiator_state.sectorcount;
|
|
|
|
|
|
|
|
total_bytes = (uint64_t)g_initiator_state.sectorcount * g_initiator_state.sectorsize;
|
|
total_bytes = (uint64_t)g_initiator_state.sectorcount * g_initiator_state.sectorsize;
|
|
@@ -242,22 +271,79 @@ void scsiInitiatorMainLoop()
|
|
|
|
|
|
|
|
char filename_base[12];
|
|
char filename_base[12];
|
|
|
strncpy(filename_base, "HD00_imaged", sizeof(filename_base));
|
|
strncpy(filename_base, "HD00_imaged", sizeof(filename_base));
|
|
|
- const char *filename_extention = ".hda";
|
|
|
|
|
|
|
+ const char *filename_extension = ".hda";
|
|
|
|
|
+
|
|
|
if (inquiryok)
|
|
if (inquiryok)
|
|
|
{
|
|
{
|
|
|
- if ((inquiry_data[0] & 0x1F) == 5)
|
|
|
|
|
|
|
+ char vendor[9], product[17], revision[5];
|
|
|
|
|
+ g_initiator_state.device_type=inquiry_data[0] & 0x1f;
|
|
|
|
|
+ g_initiator_state.ansi_version = inquiry_data[2] & 0x7;
|
|
|
|
|
+ g_initiator_state.removable = !!(inquiry_data[1] & 0x80);
|
|
|
|
|
+ g_initiator_state.eject_when_done = g_initiator_state.removable;
|
|
|
|
|
+ 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;
|
|
|
|
|
+
|
|
|
|
|
+ if(g_initiator_state.ansi_version != 0x02)
|
|
|
|
|
+ {
|
|
|
|
|
+ // this is a SCSI-1 drive, use READ6 and 256 bytes to be safe.
|
|
|
|
|
+ g_initiator_state.max_sector_per_transfer = 256;
|
|
|
|
|
+ }
|
|
|
|
|
+ int ini_type = scsiTypeToIniType(g_initiator_state.device_type, g_initiator_state.removable);
|
|
|
|
|
+ logmsg("SCSI Version ", (int) g_initiator_state.ansi_version);
|
|
|
|
|
+ logmsg("[SCSI", g_initiator_state.target_id,"]");
|
|
|
|
|
+ logmsg(" Vendor = \"", vendor,"\"");
|
|
|
|
|
+ logmsg(" Product = \"", product,"\"");
|
|
|
|
|
+ logmsg(" Version = \"", revision,"\"");
|
|
|
|
|
+ if (ini_type == -1)
|
|
|
|
|
+ logmsg("Type = Not Supported, trying direct access");
|
|
|
|
|
+ else
|
|
|
|
|
+ logmsg(" Type = ", ini_type);
|
|
|
|
|
+
|
|
|
|
|
+ if (g_initiator_state.device_type == SCSI_DEVICE_TYPE_CD)
|
|
|
{
|
|
{
|
|
|
strncpy(filename_base, "CD00_imaged", sizeof(filename_base));
|
|
strncpy(filename_base, "CD00_imaged", sizeof(filename_base));
|
|
|
- filename_extention = ".iso";
|
|
|
|
|
|
|
+ filename_extension = ".iso";
|
|
|
|
|
+ }
|
|
|
|
|
+ else if (g_initiator_state.device_type == SCSI_DEVICE_TYPE_MO)
|
|
|
|
|
+ {
|
|
|
|
|
+ strncpy(filename_base, "MO00_imaged", sizeof(filename_base));
|
|
|
|
|
+ filename_extension = ".img";
|
|
|
|
|
+ }
|
|
|
|
|
+ else if (g_initiator_state.device_type != SCSI_DEVICE_TYPE_DIRECT_ACCESS)
|
|
|
|
|
+ {
|
|
|
|
|
+ logmsg("Unhandled scsi device type: ", g_initiator_state.device_type, ". Handling it as Direct Access Device.");
|
|
|
|
|
+ g_initiator_state.device_type = SCSI_DEVICE_TYPE_DIRECT_ACCESS;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (g_initiator_state.device_type == SCSI_DEVICE_TYPE_DIRECT_ACCESS && g_initiator_state.removable)
|
|
|
|
|
+ {
|
|
|
|
|
+ strncpy(filename_base, "RM00_imaged", sizeof(filename_base));
|
|
|
|
|
+ filename_extension = ".img";
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ if (g_initiator_state.eject_when_done && g_initiator_state.removable_count[g_initiator_state.target_id] == 0)
|
|
|
|
|
+ {
|
|
|
|
|
+ g_initiator_state.removable_count[g_initiator_state.target_id] = 1;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
if (g_initiator_state.sectorcount > 0)
|
|
if (g_initiator_state.sectorcount > 0)
|
|
|
{
|
|
{
|
|
|
char filename[32] = {0};
|
|
char filename[32] = {0};
|
|
|
filename_base[2] += g_initiator_state.target_id;
|
|
filename_base[2] += g_initiator_state.target_id;
|
|
|
- strncpy(filename, filename_base, sizeof(filename) - 1);
|
|
|
|
|
- strncat(filename, filename_extention, sizeof(filename) - 1);
|
|
|
|
|
|
|
+ if (g_initiator_state.eject_when_done)
|
|
|
|
|
+ {
|
|
|
|
|
+ auto removable_count = g_initiator_state.removable_count[g_initiator_state.target_id];
|
|
|
|
|
+ snprintf(filename, sizeof(filename), "%s(%lu)%s",filename_base, removable_count, filename_extension);
|
|
|
|
|
+ }
|
|
|
|
|
+ else
|
|
|
|
|
+ {
|
|
|
|
|
+ snprintf(filename, sizeof(filename), "%s%s", filename_base, filename_extension);
|
|
|
|
|
+ }
|
|
|
static int handling = -1;
|
|
static int handling = -1;
|
|
|
if (handling == -1)
|
|
if (handling == -1)
|
|
|
{
|
|
{
|
|
@@ -291,12 +377,16 @@ void scsiInitiatorMainLoop()
|
|
|
return;
|
|
return;
|
|
|
}
|
|
}
|
|
|
char filename_copy[6] = {0};
|
|
char filename_copy[6] = {0};
|
|
|
- snprintf(filename_copy, sizeof(filename_copy), "_%03lu", i);
|
|
|
|
|
-
|
|
|
|
|
- strncpy(filename, filename_base, sizeof(filename) - 1);
|
|
|
|
|
- strncat(filename, filename_copy, sizeof(filename) - 1);
|
|
|
|
|
- strncat(filename, filename_extention, sizeof(filename) - 1);
|
|
|
|
|
-
|
|
|
|
|
|
|
+ if (g_initiator_state.eject_when_done)
|
|
|
|
|
+ {
|
|
|
|
|
+ auto removable_count = g_initiator_state.removable_count[g_initiator_state.target_id];
|
|
|
|
|
+ snprintf(filename, sizeof(filename), "%s(%lu)-%03lu%s", filename_base, removable_count, i, filename_extension);
|
|
|
|
|
+ }
|
|
|
|
|
+ else
|
|
|
|
|
+ {
|
|
|
|
|
+ snprintf(filename, sizeof(filename), "%s-%03lu%s", filename_base, i, filename_extension);
|
|
|
|
|
+ }
|
|
|
|
|
+ snprintf(filename_copy, sizeof(filename_copy), "-%03lu", i);
|
|
|
if (SD.exists(filename))
|
|
if (SD.exists(filename))
|
|
|
continue;
|
|
continue;
|
|
|
break;
|
|
break;
|
|
@@ -333,7 +423,7 @@ void scsiInitiatorMainLoop()
|
|
|
return;
|
|
return;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- g_initiator_state.target_file = SD.open(filename, O_RDWR | O_CREAT | O_TRUNC);
|
|
|
|
|
|
|
+ g_initiator_state.target_file = SD.open(filename, O_WRONLY | O_CREAT | O_TRUNC);
|
|
|
if (!g_initiator_state.target_file.isOpen())
|
|
if (!g_initiator_state.target_file.isOpen())
|
|
|
{
|
|
{
|
|
|
logmsg("Failed to open file for writing: ", filename);
|
|
logmsg("Failed to open file for writing: ", filename);
|
|
@@ -368,7 +458,17 @@ void scsiInitiatorMainLoop()
|
|
|
logmsg("Please reformat the SD card with exFAT format to image this drive fully");
|
|
logmsg("Please reformat the SD card with exFAT format to image this drive fully");
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- g_initiator_state.drives_imaged |= (1 << g_initiator_state.target_id);
|
|
|
|
|
|
|
+ if(g_initiator_state.bad_sector_count != 0)
|
|
|
|
|
+ {
|
|
|
|
|
+ logmsg_f("NOTE: There were %d bad sectors that could not be read off this drive.", g_initiator_state.bad_sector_count);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (!g_initiator_state.eject_when_done)
|
|
|
|
|
+ {
|
|
|
|
|
+ logmsg("Marking SCSI ID, ", g_initiator_state.target_id, ", as imaged, wont ask it again.");
|
|
|
|
|
+ g_initiator_state.drives_imaged |= (1 << g_initiator_state.target_id);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
g_initiator_state.imaging = false;
|
|
g_initiator_state.imaging = false;
|
|
|
g_initiator_state.target_file.close();
|
|
g_initiator_state.target_file.close();
|
|
|
return;
|
|
return;
|
|
@@ -394,11 +494,12 @@ void scsiInitiatorMainLoop()
|
|
|
{
|
|
{
|
|
|
logmsg("Failed to transfer ", numtoread, " sectors starting at ", (int)g_initiator_state.sectors_done);
|
|
logmsg("Failed to transfer ", numtoread, " sectors starting at ", (int)g_initiator_state.sectors_done);
|
|
|
|
|
|
|
|
- if (g_initiator_state.retrycount < 5)
|
|
|
|
|
|
|
+ if (g_initiator_state.retrycount < g_initiator_state.max_retry_count)
|
|
|
{
|
|
{
|
|
|
- logmsg("Retrying.. ", g_initiator_state.retrycount, "/5");
|
|
|
|
|
|
|
+ logmsg("Retrying.. ", g_initiator_state.retrycount + 1, "/", (int) g_initiator_state.max_retry_count);
|
|
|
delay_with_poll(200);
|
|
delay_with_poll(200);
|
|
|
- scsiHostPhyReset();
|
|
|
|
|
|
|
+ // This reset causes some drives to hang and seems to have no effect if left off.
|
|
|
|
|
+ // scsiHostPhyReset();
|
|
|
delay_with_poll(200);
|
|
delay_with_poll(200);
|
|
|
|
|
|
|
|
g_initiator_state.retrycount++;
|
|
g_initiator_state.retrycount++;
|
|
@@ -415,6 +516,7 @@ void scsiInitiatorMainLoop()
|
|
|
logmsg("Retry limit exceeded, skipping one sector");
|
|
logmsg("Retry limit exceeded, skipping one sector");
|
|
|
g_initiator_state.retrycount = 0;
|
|
g_initiator_state.retrycount = 0;
|
|
|
g_initiator_state.sectors_done++;
|
|
g_initiator_state.sectors_done++;
|
|
|
|
|
+ g_initiator_state.bad_sector_count++;
|
|
|
g_initiator_state.target_file.seek((uint64_t)g_initiator_state.sectors_done * g_initiator_state.sectorsize);
|
|
g_initiator_state.target_file.seek((uint64_t)g_initiator_state.sectors_done * g_initiator_state.sectorsize);
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
@@ -427,7 +529,8 @@ void scsiInitiatorMainLoop()
|
|
|
int speed_kbps = numtoread * g_initiator_state.sectorsize / (millis() - time_start);
|
|
int speed_kbps = numtoread * g_initiator_state.sectorsize / (millis() - time_start);
|
|
|
logmsg("SCSI read succeeded, sectors done: ",
|
|
logmsg("SCSI read succeeded, sectors done: ",
|
|
|
(int)g_initiator_state.sectors_done, " / ", (int)g_initiator_state.sectorcount,
|
|
(int)g_initiator_state.sectors_done, " / ", (int)g_initiator_state.sectorcount,
|
|
|
- " speed ", speed_kbps, " kB/s");
|
|
|
|
|
|
|
+ " speed ", speed_kbps, " kB/s - ",
|
|
|
|
|
+ (int)(100 * g_initiator_state.sectors_done / g_initiator_state.sectorcount), "%");
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
@@ -568,9 +671,9 @@ bool scsiRequestSense(int target_id, uint8_t *sense_key)
|
|
|
response, sizeof(response),
|
|
response, sizeof(response),
|
|
|
NULL, 0);
|
|
NULL, 0);
|
|
|
|
|
|
|
|
- logmsg("RequestSense response: ", bytearray(response, 18));
|
|
|
|
|
|
|
+ dbgmsg("RequestSense response: ", bytearray(response, 18));
|
|
|
|
|
|
|
|
- *sense_key = response[2];
|
|
|
|
|
|
|
+ *sense_key = response[2] % 0xF;
|
|
|
return status == 0;
|
|
return status == 0;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -585,6 +688,15 @@ bool scsiStartStopUnit(int target_id, bool start)
|
|
|
command[4] |= 1; // Start
|
|
command[4] |= 1; // Start
|
|
|
command[1] = 0; // Immediate
|
|
command[1] = 0; // Immediate
|
|
|
}
|
|
}
|
|
|
|
|
+ else // stop
|
|
|
|
|
+ {
|
|
|
|
|
+ if(g_initiator_state.eject_when_done)
|
|
|
|
|
+ {
|
|
|
|
|
+ logmsg("Ejecting media on SCSI ID: ", target_id);
|
|
|
|
|
+ g_initiator_state.removable_count[g_initiator_state.target_id]++;
|
|
|
|
|
+ command[4] = 0b00000010; // eject(6), stop(7).
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
int status = scsiInitiatorRunCommand(target_id,
|
|
int status = scsiInitiatorRunCommand(target_id,
|
|
|
command, sizeof(command),
|
|
command, sizeof(command),
|
|
@@ -595,7 +707,7 @@ bool scsiStartStopUnit(int target_id, bool start)
|
|
|
{
|
|
{
|
|
|
uint8_t sense_key;
|
|
uint8_t sense_key;
|
|
|
scsiRequestSense(target_id, &sense_key);
|
|
scsiRequestSense(target_id, &sense_key);
|
|
|
- logmsg("START STOP UNIT on target ", target_id, " failed, sense key ", sense_key);
|
|
|
|
|
|
|
+ dbgmsg("START STOP UNIT on target ", target_id, " failed, sense key ", sense_key);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
return status == 0;
|
|
return status == 0;
|
|
@@ -640,18 +752,18 @@ bool scsiTestUnitReady(int target_id)
|
|
|
if (sense_key == 6)
|
|
if (sense_key == 6)
|
|
|
{
|
|
{
|
|
|
uint8_t inquiry[36];
|
|
uint8_t inquiry[36];
|
|
|
- logmsg("Target ", target_id, " reports UNIT_ATTENTION, running INQUIRY");
|
|
|
|
|
|
|
+ dbgmsg("Target ", target_id, " reports UNIT_ATTENTION, running INQUIRY");
|
|
|
scsiInquiry(target_id, inquiry);
|
|
scsiInquiry(target_id, inquiry);
|
|
|
}
|
|
}
|
|
|
else if (sense_key == 2)
|
|
else if (sense_key == 2)
|
|
|
{
|
|
{
|
|
|
- logmsg("Target ", target_id, " reports NOT_READY, running STARTSTOPUNIT");
|
|
|
|
|
|
|
+ dbgmsg("Target ", target_id, " reports NOT_READY, running STARTSTOPUNIT");
|
|
|
scsiStartStopUnit(target_id, true);
|
|
scsiStartStopUnit(target_id, true);
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
else
|
|
else
|
|
|
{
|
|
{
|
|
|
- logmsg("Target ", target_id, " TEST UNIT READY response: ", status);
|
|
|
|
|
|
|
+ dbgmsg("Target ", target_id, " TEST UNIT READY response: ", status);
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -769,7 +881,7 @@ bool scsiInitiatorReadDataToFile(int target_id, uint32_t start_sector, uint32_t
|
|
|
|
|
|
|
|
// Read6 command supports 21 bit LBA - max of 0x1FFFFF
|
|
// Read6 command supports 21 bit LBA - max of 0x1FFFFF
|
|
|
// ref: https://www.seagate.com/files/staticfiles/support/docs/manual/Interface%20manuals/100293068j.pdf pg 134
|
|
// ref: https://www.seagate.com/files/staticfiles/support/docs/manual/Interface%20manuals/100293068j.pdf pg 134
|
|
|
- if (start_sector < 0x1FFFFF && sectorcount <= 256)
|
|
|
|
|
|
|
+ if (g_initiator_state.ansi_version != 0x02 || (start_sector < 0x1FFFFF && sectorcount <= 256))
|
|
|
{
|
|
{
|
|
|
// Use READ6 command for compatibility with old SCSI1 drives
|
|
// Use READ6 command for compatibility with old SCSI1 drives
|
|
|
uint8_t command[6] = {0x08,
|
|
uint8_t command[6] = {0x08,
|