Add proper changenum checking for ETD_* and NSCMD_ETD_* commands

This commit is contained in:
Chris Hooper 2022-09-29 08:01:18 -07:00
parent 5b06321f26
commit 9785a8eb1f
3 changed files with 60 additions and 14 deletions

View File

@ -167,7 +167,7 @@ iocmd_name(uint cmd)
"TD_SEEK64", // 26
"TD_FORMAT64", // 27
"HD_SCSICMD", // 28
"29", // 29
"MD_SETPARAMS", // 29
"30", // 30
"31", // 31
"CD_INFO", // 32
@ -225,24 +225,29 @@ struct ioerr {
{ -5, "IOERR_BADADDRESS" },
{ -6, "IOERR_UNITBUSY" },
{ -7, "IOERR_SELFTEST" },
{ 2, "EACCES" },
{ 5, "EIO" },
{ 12, "ENOMEM" },
{ 16, "EBUSY" },
{ 19, "ENODEV" },
{ 20, "TDERR_NotSpecified" },
{ 21, "TDERR_NoSecHdr" },
{ 22, "TDERR_BadSecPreamble" },
{ 22, "TDERR_BadSecPreamble" }, // also EINVAL
{ 23, "TDERR_BadSecID" },
{ 24, "TDERR_BadHdrSum" },
{ 25, "TDERR_BadSecSum" },
{ 26, "TDERR_TooFewSecs" },
{ 27, "TDERR_BadSecHdr" },
{ 28, "TDERR_WriteProt" },
{ 28, "TDERR_WriteProt" }, // also ENOSPC
{ 29, "TDERR_DiskChanged" },
{ 30, "TDERR_SeekError" },
{ 30, "TDERR_SeekError" }, // also EROFS
{ 31, "TDERR_NoMem" },
{ 32, "TDERR_BadUnitNum" },
{ 33, "TDERR_BadDriveType" },
{ 34, "TDERR_DriveInUse" },
{ 35, "TDERR_PostReset" },
{ 36, "CDERR_BadDataType" }, // data on disk is wrong type
{ 37, "CDERR_InvalidState" }, // invalid cmd under current conditions
{ 35, "TDERR_PostReset" }, // also EAGAIN
{ 36, "CDERR_BadDataType" }, // data on disk is wrong type
{ 37, "CDERR_InvalidState" }, // invalid cmd under current conditions
{ 40, "HFERR_SelfUnit" },
{ 41, "HFERR_DMA" },
{ 42, "HFERR_Phase" },

View File

@ -254,10 +254,40 @@ cmd_do_iorequest(struct IORequest * ior)
uint64_t blkno;
uint blkshift;
struct IOExtTD *iotd = (struct IOExtTD *) ior;
UWORD cmd = ior->io_Command;
ior->io_Error = 0;
switch (ior->io_Command) {
switch (cmd) {
case ETD_WRITE:
case ETD_READ:
case ETD_MOTOR:
case ETD_SEEK:
case ETD_FORMAT:
cmd &= ~TDF_EXTCOM;
goto validate_etd;
case NSCMD_ETD_READ64:
case NSCMD_ETD_WRITE64:
case NSCMD_ETD_SEEK64:
case NSCMD_ETD_FORMAT64:
cmd &= ~NSCMD_TDF_EXTCOM;
validate_etd:
{
struct scsipi_periph *periph = (struct scsipi_periph *)ior->io_Unit;
if (periph->periph_changenum > iotd->iotd_Count) {
/*
* Current change count is higher than maximum allowed
* change count. Reject the command.
*/
iotd->iotd_Req.io_Error = TDERR_DiskChanged;
ReplyMsg(&iotd->iotd_Req.io_Message);
return (0);
}
PRINTF_CMD("E");
break;
}
}
switch (cmd) {
case CMD_READ:
PRINTF_CMD("CMD_READ %d %"PRIx32" %"PRIx32"\n",
((struct scsipi_periph *) ior->io_Unit)->periph_lun * 10 +
@ -282,9 +312,7 @@ io_done:
}
break;
case ETD_WRITE:
case CMD_WRITE:
case ETD_FORMAT:
case TD_FORMAT:
PRINTF_CMD("CMD_WRITE %d %"PRIx32" %"PRIx32"\n",
((struct scsipi_periph *) ior->io_Unit)->periph_lun * 10 +
@ -366,7 +394,6 @@ CMD_WRITE_continue:
blkno = ((uint64_t) iotd->iotd_Req.io_Actual << (32 - blkshift)) |
(iotd->iotd_Req.io_Offset >> blkshift);
goto CMD_SEEK_continue;
case ETD_SEEK:
case TD_SEEK:
PRINTF_CMD("TD_SEEK %d off=%"PRIu32"\n",
((struct scsipi_periph *) ior->io_Unit)->periph_lun * 10 +
@ -395,6 +422,16 @@ CMD_SEEK_continue:
// TD_GETGEOMETRY without media should return TDERR_DiskChanged 29
break;
#ifdef OLD_NSD_IDENTIFY
/*
* It is no longer recommended that TD_GETDRIVETYPE return
* DRIVE_NEWSTYLE for NSD-style devices.
*/
case TD_GETDRIVETYPE:
iotd->iotd_Req.io_Actual = DRIVE_NEWSTYLE;
break;
#endif
case NSCMD_DEVICEQUERY: {
struct NSDeviceQueryResult *nsd =
(struct NSDeviceQueryResult *) iotd->iotd_Req.io_Data;
@ -540,6 +577,11 @@ CMD_SEEK_continue:
ReplyMsg(&ior->io_Message);
break;
case TD_MOTOR: // Turn the drive motor on or off
/* Just reply with success, like the C= scsi.device does */
ReplyMsg(&ior->io_Message);
break;
case CMD_INVALID: // Invalid command (0)
case CMD_RESET: // Not supported by SCSI
case CMD_UPDATE: // Not supported by SCSI
@ -547,13 +589,10 @@ CMD_SEEK_continue:
case CMD_FLUSH: // Not supported by SCSI
case TD_RAWREAD: // Not supported by SCSI (raw bits from disk)
case TD_RAWWRITE: // Not supported by SCSI (raw bits to disk)
case TD_GETDRIVETYPE: // Not supported by SCSI (floppy-only DRIVExxxx)
case TD_GETNUMTRACKS: // Not supported by SCSI (floppy-only)
default:
/* Unknown command */
printf("Unknown cmd %x\n", ior->io_Command);
/* FALLTHROUGH */
case TD_MOTOR: // Not supported by SCSI (floppy-only)
ior->io_Error = ERROR_UNKNOWN_COMMAND;
ReplyMsg(&ior->io_Message);
break;

2
nsd.h
View File

@ -15,7 +15,9 @@
#define NSDEVTYPE_TRACKDISK 5 // Trackdisk-like block storage device
#define DRIVE_NEWSTYLE 0x4E535459L /* NSTY */
#define NSCMD_TDF_EXTCOM (1<<13) // Mask for extended NSD commands
struct NSDeviceQueryResult
{