return status;
}
-static int handle_scsi (TrapContext *ctx, uae_u8 *iobuf, uaecptr request, struct hardfiledata *hfd, struct scsi_data *sd)
+static int handle_scsi (TrapContext *ctx, uae_u8 *iobuf, uaecptr request, struct hardfiledata *hfd, struct scsi_data *sd, bool safeonly)
{
int ret = 0;
}
scsi_log (_T("\n"));
- scsi_emulate_analyze(sd);
- scsi_start_transfer(sd);
- if (sd->direction > 0) {
- trap_get_bytes(ctx, sd->buffer, scsi_data, sd->data_len);
- scsi_emulate_cmd(sd);
+ if (safeonly && !scsi_cmd_is_safe(sd->cmd[0])) {
+ sd->status = 2;
+ sd->sense_len = 18;
+ sd->sense[0] = 0x70;
+ sd->sense[2] = 5; /* ILLEGAL REQUEST */
+ sd->sense[12] = 0x30; /* INCOMPATIBLE MEDIUM INSERTED */
} else {
- scsi_emulate_cmd(sd);
- if (sd->direction < 0)
- trap_put_bytes(ctx, sd->buffer, scsi_data, sd->data_len);
+ scsi_emulate_analyze(sd);
+ scsi_start_transfer(sd);
+ if (sd->direction > 0) {
+ trap_get_bytes(ctx, sd->buffer, scsi_data, sd->data_len);
+ scsi_emulate_cmd(sd);
+ } else {
+ scsi_emulate_cmd(sd);
+ if (sd->direction < 0)
+ trap_put_bytes(ctx, sd->buffer, scsi_data, sd->data_len);
+ }
}
put_word_host(scsicmd + 18, sd->status != 0 ? 0 : sd->cmd_len); /* fake scsi_CmdActual */
#if HDF_SUPPORT_DS
case HD_SCSICMD: /* SCSI */
if (vdisk(hfpd)) {
- error = handle_scsi(ctx, iobuf, request, hfd, hfpd->sd);
+ error = handle_scsi(ctx, iobuf, request, hfd, hfpd->sd, false);
} else if (HDF_SUPPORT_DS_PARTITION || enable_ds_partition_hdf || (!hfd->ci.sectors && !hfd->ci.surfaces && !hfd->ci.reserved)) {
- error = handle_scsi(ctx, iobuf, request, hfd, hfpd->sd);
+ error = handle_scsi(ctx, iobuf, request, hfd, hfpd->sd, false);
} else { /* we don't want users trashing their "partition" hardfiles with hdtoolbox */
- error = IOERR_NOCMD;
- write_log (_T("UAEHF: HD_SCSICMD tried on regular HDF, unit %d\n"), unit);
+ error = handle_scsi(ctx, iobuf, request, hfd, hfpd->sd, true);
}
break;
#endif
static const uae_s16 outcmd[] = { 0x04, 0x0a, 0x0c, 0x11, 0x2a, 0xaa, 0x15, 0x55, 0x0f, -1 };
static const uae_s16 incmd[] = { 0x01, 0x03, 0x08, 0x0e, 0x12, 0x1a, 0x5a, 0x25, 0x28, 0x34, 0x37, 0x42, 0x43, 0xa8, 0x51, 0x52, 0xb9, 0xbd, 0xd8, 0xd9, 0xbe, -1 };
static const uae_s16 nonecmd[] = { 0x00, 0x05, 0x06, 0x07, 0x09, 0x0b, 0x10, 0x16, 0x17, 0x19, 0x1b, 0x1d, 0x1e, 0x2b, 0x35, 0x45, 0x47, 0x48, 0x49, 0x4b, 0x4e, 0xa5, 0xa9, 0xba, 0xbc, 0xe0, 0xe3, 0xe4, -1 };
-static const uae_s16 dirscsi[] = { 0x00, 0x01, 0x03, 0x0e, 0x0f, 0x12, 0x1a, 0x1b, 0x25, 0x35, 0x5a, -1 };
+static const uae_s16 safescsi[] = { 0x00, 0x01, 0x03, 0x0e, 0x0f, 0x12, 0x1a, 0x1b, 0x25, 0x35, 0x5a, -1 };
static const uae_s16 scsicmdsizes[] = { 6, 10, 10, 12, 16, 12, 10, 6 };
static void scsi_illegal_command(struct scsi_data *sd)
return true;
}
+bool scsi_cmd_is_safe(uae_u8 cmd)
+{
+ for (int i = 0; safescsi[i] >= 0; i++) {
+ if (safescsi[i] == cmd) {
+ return true;
+ }
+ }
+ return false;
+}
+
+
void scsi_emulate_cmd(struct scsi_data *sd)
{
sd->status = 0;
if (ua)
sd->unit_attention = ua;
if (handle_ca(sd)) {
- bool allowed = false;
- for (int i = 0; dirscsi[i] >= 0; i++) {
- if (dirscsi[i] == sd->cmd[0]) {
- allowed = true;
- break;
- }
- }
- if (allowed) {
+ if (scsi_cmd_is_safe(sd->cmd[0])) {
if (sd->cmd[0] == 0x03) { /* REQUEST SENSE */
scsi_hd_emulate(sd->hfd, sd->hdhfd, sd->cmd, 0, 0, 0, 0, 0, sd->sense, &sd->sense_len);
copysense(sd);