VAXen with SCSI: Allow some cross controller read only drive access

This commit is contained in:
Mark Pizzolato 2020-12-29 11:14:34 -08:00
parent 613625e878
commit 8c42a3436c
5 changed files with 84 additions and 17 deletions

View file

@ -142,6 +142,7 @@ typedef struct {
t_stat rz_svc (UNIT *uptr); t_stat rz_svc (UNIT *uptr);
t_stat rz_isvc (UNIT *uptr); t_stat rz_isvc (UNIT *uptr);
t_stat rz_reset (DEVICE *dptr); t_stat rz_reset (DEVICE *dptr);
t_stat rz_attach (UNIT *uptr, CONST char *cptr);
t_stat rz_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr); t_stat rz_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr);
t_stat rz_set_type (UNIT *uptr, int32 val, CONST char *cptr, void *desc); t_stat rz_set_type (UNIT *uptr, int32 val, CONST char *cptr, void *desc);
t_stat rz_show_type (FILE *st, UNIT *uptr, int32 val, CONST void *desc); t_stat rz_show_type (FILE *st, UNIT *uptr, int32 val, CONST void *desc);
@ -250,11 +251,32 @@ MTAB rz_mod[] = {
{ 0 } { 0 }
}; };
static const char *drv_types[] = {
"RZ23",
"RZ23L",
"RZ24",
"RZ24L",
"RZ25",
"RZ25L",
"RZ26",
"RZ26L",
"RZ55",
"CDROM",
"RRD40",
"RRD42",
"RRW11",
"CDW900",
"XR1001",
"TZK50",
"TZ30",
"RZUSER"
};
DEVICE rz_dev = { DEVICE rz_dev = {
"RZ", rz_unit, rz_reg, rz_mod, "RZ", rz_unit, rz_reg, rz_mod,
RZ_NUMDR + 1, DEV_RDX, 31, 1, DEV_RDX, 8, RZ_NUMDR + 1, DEV_RDX, 31, 1, DEV_RDX, 8,
NULL, NULL, &rz_reset, NULL, NULL, &rz_reset,
NULL, &scsi_attach, &scsi_detach, NULL, &rz_attach, &scsi_detach,
NULL, DEV_DEBUG | DEV_DISK | DEV_SECTORS | RZ_FLAGS, NULL, DEV_DEBUG | DEV_DISK | DEV_SECTORS | RZ_FLAGS,
0, rz_debug, NULL, NULL, &rz_help, NULL, NULL, 0, rz_debug, NULL, NULL, &rz_help, NULL, NULL,
&rz_description &rz_description
@ -302,7 +324,7 @@ DEVICE rzb_dev = {
"RZB", rzb_unit, rzb_reg, rz_mod, "RZB", rzb_unit, rzb_reg, rz_mod,
RZ_NUMDR + 1, DEV_RDX, 31, 1, DEV_RDX, 8, RZ_NUMDR + 1, DEV_RDX, 31, 1, DEV_RDX, 8,
NULL, NULL, &rz_reset, NULL, NULL, &rz_reset,
NULL, &scsi_attach, &scsi_detach, NULL, &rz_attach, &scsi_detach,
&rzb_dib, DEV_DEBUG | DEV_DISK | DEV_SECTORS | RZB_FLAGS, &rzb_dib, DEV_DEBUG | DEV_DISK | DEV_SECTORS | RZB_FLAGS,
0, rz_debug, NULL, NULL, 0, rz_debug, NULL, NULL,
&rz_help, NULL /* help and attach_help routines */ &rz_help, NULL /* help and attach_help routines */
@ -860,6 +882,11 @@ scsi_help (st, dptr, uptr, flag, cptr);
return SCPE_OK; return SCPE_OK;
} }
t_stat rz_attach (UNIT *uptr, CONST char *cptr)
{
return scsi_attach_ex (uptr, cptr, drv_types);
}
const char *rz_description (DEVICE *dptr) const char *rz_description (DEVICE *dptr)
{ {
return "NCR 5380 SCSI controller"; return "NCR 5380 SCSI controller";

View file

@ -111,6 +111,7 @@ DEBTAB rz_debug[] = {
t_stat rz_svc (UNIT *uptr); t_stat rz_svc (UNIT *uptr);
t_stat rz_reset (DEVICE *dptr); t_stat rz_reset (DEVICE *dptr);
t_stat rz_attach (UNIT *uptr, CONST char *cptr);
void rz_sw_reset (void); void rz_sw_reset (void);
t_stat rz_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr); t_stat rz_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr);
void rz_cmd (uint32 cmd); void rz_cmd (uint32 cmd);
@ -203,11 +204,32 @@ MTAB rz_mod[] = {
{ 0 } { 0 }
}; };
static const char *drv_types[] = {
"RZ23",
"RZ23L",
"RZ24",
"RZ24L",
"RZ25",
"RZ25L",
"RZ26",
"RZ26L",
"RZ55",
"CDROM",
"RRD40",
"RRD42",
"RRW11",
"CDW900",
"XR1001",
"TZK50",
"TZ30",
"RZUSER"
};
DEVICE rz_dev = { DEVICE rz_dev = {
"RZ", rz_unit, rz_reg, rz_mod, "RZ", rz_unit, rz_reg, rz_mod,
9, DEV_RDX, 8, 1, DEV_RDX, 8, 9, DEV_RDX, 8, 1, DEV_RDX, 8,
NULL, NULL, &rz_reset, NULL, NULL, &rz_reset,
NULL, &scsi_attach, &scsi_detach, NULL, &rz_attach, &scsi_detach,
NULL, DEV_DISABLE | DEV_DEBUG | DEV_DISK | DEV_SECTORS, NULL, DEV_DISABLE | DEV_DEBUG | DEV_DISK | DEV_SECTORS,
0, rz_debug, NULL, NULL, &rz_help, NULL, NULL, 0, rz_debug, NULL, NULL, &rz_help, NULL, NULL,
&rz_description &rz_description
@ -866,6 +888,11 @@ scsi_help (st, dptr, uptr, flag, cptr);
return SCPE_OK; return SCPE_OK;
} }
t_stat rz_attach (UNIT *uptr, CONST char *cptr)
{
return scsi_attach_ex (uptr, cptr, drv_types);
}
const char *rz_description (DEVICE *dptr) const char *rz_description (DEVICE *dptr)
{ {
return "NCR 53C94 SCSI controller"; return "NCR 53C94 SCSI controller";

View file

@ -2043,6 +2043,8 @@ for (i = 0; checks[i] != NULL; i++) {
return ret_val; return ret_val;
} }
static t_stat store_disk_footer (UNIT *uptr, const char *dtype);
static t_stat get_disk_footer (UNIT *uptr) static t_stat get_disk_footer (UNIT *uptr)
{ {
struct disk_context *ctx = (struct disk_context *)uptr->disk_ctx; struct disk_context *ctx = (struct disk_context *)uptr->disk_ctx;
@ -2109,6 +2111,13 @@ if (f) {
f = NULL; f = NULL;
} }
else { else {
/* We've got a valid footer, but it may need to be corrected */
if ((NtoHl (f->TransferElementSize) == 1) &&
(0 == memcmp (f->DriveType, "RZ", 2))) {
f->TransferElementSize = NtoHl (2);
f->Checksum = NtoHl (eth_crc32 (0, f, sizeof (*f) - sizeof (f->Checksum)));
store_disk_footer (uptr, (char *)f->DriveType);
}
free (ctx->footer); free (ctx->footer);
ctx->footer = f; ctx->footer = f;
container_size -= sizeof (*f); container_size -= sizeof (*f);
@ -2161,8 +2170,10 @@ free (ctx->footer);
ctx->footer = f; ctx->footer = f;
switch (f->AccessFormat) { switch (f->AccessFormat) {
case DKUF_F_STD: /* SIMH format */ case DKUF_F_STD: /* SIMH format */
if (sim_fseeko ((FILE *)uptr->fileref, total_sectors * ctx->sector_size, SEEK_SET) == 0) if (sim_fseeko ((FILE *)uptr->fileref, total_sectors * ctx->sector_size, SEEK_SET) == 0) {
sim_fwrite (f, sizeof (*f), 1, (FILE *)uptr->fileref); sim_fwrite (f, sizeof (*f), 1, (FILE *)uptr->fileref);
fflush ((FILE *)uptr->fileref);
}
break; break;
case DKUF_F_VHD: /* VHD format */ case DKUF_F_VHD: /* VHD format */
break; break;
@ -2189,7 +2200,6 @@ DEVICE *dptr;
char tbuf[4*CBUFSIZE]; char tbuf[4*CBUFSIZE];
FILE *(*open_function)(const char *filename, const char *mode) = sim_fopen; FILE *(*open_function)(const char *filename, const char *mode) = sim_fopen;
FILE *(*create_function)(const char *filename, t_offset desiredsize) = NULL; FILE *(*create_function)(const char *filename, t_offset desiredsize) = NULL;
t_offset (*size_function)(FILE *file);
t_stat (*storage_function)(FILE *file, uint32 *sector_size, uint32 *removable, uint32 *is_cdrom) = NULL; t_stat (*storage_function)(FILE *file, uint32 *sector_size, uint32 *removable, uint32 *is_cdrom) = NULL;
t_bool created = FALSE, copied = FALSE; t_bool created = FALSE, copied = FALSE;
t_bool auto_format = FALSE; t_bool auto_format = FALSE;
@ -2416,7 +2426,6 @@ switch (DK_GET_FMT (uptr)) { /* case on format */
sim_vhd_disk_close (uptr->fileref); /* close vhd file*/ sim_vhd_disk_close (uptr->fileref); /* close vhd file*/
uptr->fileref = NULL; uptr->fileref = NULL;
open_function = sim_vhd_disk_open; open_function = sim_vhd_disk_open;
size_function = sim_vhd_disk_size;
break; break;
} }
while (tmp_size < sector_size) while (tmp_size < sector_size)
@ -2426,7 +2435,6 @@ switch (DK_GET_FMT (uptr)) { /* case on format */
sim_disk_set_fmt (uptr, 0, "RAW", NULL); /* set file format to RAW */ sim_disk_set_fmt (uptr, 0, "RAW", NULL); /* set file format to RAW */
sim_os_disk_close_raw (uptr->fileref); /* close raw file*/ sim_os_disk_close_raw (uptr->fileref); /* close raw file*/
open_function = sim_os_disk_open_raw; open_function = sim_os_disk_open_raw;
size_function = sim_os_disk_size_raw;
storage_function = sim_os_disk_info_raw; storage_function = sim_os_disk_info_raw;
uptr->fileref = NULL; uptr->fileref = NULL;
break; break;
@ -2434,7 +2442,6 @@ switch (DK_GET_FMT (uptr)) { /* case on format */
} }
sim_disk_set_fmt (uptr, 0, "SIMH", NULL); /* set file format to SIMH */ sim_disk_set_fmt (uptr, 0, "SIMH", NULL); /* set file format to SIMH */
open_function = sim_fopen; open_function = sim_fopen;
size_function = sim_fsize_ex;
break; break;
case DKUF_F_STD: /* SIMH format */ case DKUF_F_STD: /* SIMH format */
if (NULL != (uptr->fileref = sim_vhd_disk_open (cptr, "rb"))) { /* Try VHD first */ if (NULL != (uptr->fileref = sim_vhd_disk_open (cptr, "rb"))) { /* Try VHD first */
@ -2442,17 +2449,14 @@ switch (DK_GET_FMT (uptr)) { /* case on format */
sim_vhd_disk_close (uptr->fileref); /* close vhd file*/ sim_vhd_disk_close (uptr->fileref); /* close vhd file*/
uptr->fileref = NULL; uptr->fileref = NULL;
open_function = sim_vhd_disk_open; open_function = sim_vhd_disk_open;
size_function = sim_vhd_disk_size;
auto_format = TRUE; auto_format = TRUE;
break; break;
} }
open_function = sim_fopen; open_function = sim_fopen;
size_function = sim_fsize_ex;
break; break;
case DKUF_F_VHD: /* VHD format */ case DKUF_F_VHD: /* VHD format */
open_function = sim_vhd_disk_open; open_function = sim_vhd_disk_open;
create_function = sim_vhd_disk_create; create_function = sim_vhd_disk_create;
size_function = sim_vhd_disk_size;
storage_function = sim_os_disk_info_raw; storage_function = sim_os_disk_info_raw;
break; break;
case DKUF_F_RAW: /* Raw Physical Disk Access */ case DKUF_F_RAW: /* Raw Physical Disk Access */
@ -2461,12 +2465,10 @@ switch (DK_GET_FMT (uptr)) { /* case on format */
sim_vhd_disk_close (uptr->fileref); /* close vhd file*/ sim_vhd_disk_close (uptr->fileref); /* close vhd file*/
uptr->fileref = NULL; uptr->fileref = NULL;
open_function = sim_vhd_disk_open; open_function = sim_vhd_disk_open;
size_function = sim_vhd_disk_size;
auto_format = TRUE; auto_format = TRUE;
break; break;
} }
open_function = sim_os_disk_open_raw; open_function = sim_os_disk_open_raw;
size_function = sim_os_disk_size_raw;
storage_function = sim_os_disk_info_raw; storage_function = sim_os_disk_info_raw;
break; break;
default: default:
@ -2552,8 +2554,13 @@ if ((DK_GET_FMT (uptr) == DKUF_F_VHD) || (ctx->footer)) {
cmd[sizeof (cmd) - 1] = '\0'; cmd[sizeof (cmd) - 1] = '\0';
snprintf (cmd, sizeof (cmd) - 1, "%s %s", sim_uname (uptr), container_dtype); snprintf (cmd, sizeof (cmd) - 1, "%s %s", sim_uname (uptr), container_dtype);
r = set_cmd (0, cmd); r = set_cmd (0, cmd);
if (r != SCPE_OK) if (r != SCPE_OK) {
r = sim_messagef (r, "Can't set %s to drive type %s\n", sim_uname (uptr), container_dtype); r = sim_messagef (r, "%s: Can't set to drive type %s\n", sim_uname (uptr), container_dtype);
if ((uptr->flags & UNIT_RO) != 0) /* Not Opening read only? */
r = sim_messagef (SCPE_OK, "%s: Read Only access to inconsistent drive type allowed\n", sim_uname (uptr));
else
sim_messagef (SCPE_OK, "'%s' can only be attached Read Only to %s\n", cptr, sim_uname (uptr));
}
} }
} }
} }

View file

@ -1689,7 +1689,7 @@ return SCPE_OK;
/* Attach device */ /* Attach device */
t_stat scsi_attach (UNIT *uptr, CONST char *cptr) t_stat scsi_attach_ex (UNIT *uptr, CONST char *cptr, const char **drivetypes)
{ {
SCSI_DEV *dev = (SCSI_DEV *)uptr->up7; SCSI_DEV *dev = (SCSI_DEV *)uptr->up7;
@ -1700,7 +1700,7 @@ switch (dev->devtype) {
case SCSI_DISK: case SCSI_DISK:
case SCSI_WORM: case SCSI_WORM:
case SCSI_CDROM: case SCSI_CDROM:
return sim_disk_attach (uptr, cptr, dev->block_size, sizeof (uint8), (uptr->flags & SCSI_NOAUTO), SCSI_DBG_DSK, dev->name, 0, 0); return sim_disk_attach_ex (uptr, cptr, dev->block_size, sizeof (uint16), (uptr->flags & SCSI_NOAUTO), SCSI_DBG_DSK, dev->name, 0, 0, drivetypes);
case SCSI_TAPE: case SCSI_TAPE:
return sim_tape_attach (uptr, cptr); return sim_tape_attach (uptr, cptr);
default: default:
@ -1708,6 +1708,11 @@ switch (dev->devtype) {
} }
} }
t_stat scsi_attach (UNIT *uptr, CONST char *cptr)
{
return scsi_attach_ex (uptr, cptr, NULL);
}
/* Dettach device */ /* Dettach device */
t_stat scsi_detach (UNIT *uptr) t_stat scsi_detach (UNIT *uptr)

View file

@ -129,6 +129,7 @@ t_stat scsi_set_wlk (UNIT *uptr, int32 val, CONST char *cptr, void *desc);
t_stat scsi_show_fmt (FILE *st, UNIT *uptr, int32 val, CONST void *desc); t_stat scsi_show_fmt (FILE *st, UNIT *uptr, int32 val, CONST void *desc);
t_stat scsi_show_wlk (FILE *st, UNIT *uptr, int32 val, CONST void *desc); t_stat scsi_show_wlk (FILE *st, UNIT *uptr, int32 val, CONST void *desc);
t_stat scsi_attach (UNIT *uptr, CONST char *cptr); t_stat scsi_attach (UNIT *uptr, CONST char *cptr);
t_stat scsi_attach_ex (UNIT *uptr, CONST char *cptr, const char **drivetypes);
t_stat scsi_detach (UNIT *uptr); t_stat scsi_detach (UNIT *uptr);
t_stat scsi_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr); t_stat scsi_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr);