diff --git a/a4091d.c b/a4091d.c index 6ca48f6..68ea9dd 100644 --- a/a4091d.c +++ b/a4091d.c @@ -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" }, diff --git a/cmdhandler.c b/cmdhandler.c index 6bef2d2..725e821 100644 --- a/cmdhandler.c +++ b/cmdhandler.c @@ -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; diff --git a/nsd.h b/nsd.h index 515f4be..408a387 100644 --- a/nsd.h +++ b/nsd.h @@ -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 {