1
0
mirror of https://github.com/simh/simh.git synced 2026-01-11 23:52:58 +00:00

DISK, SCSI: Add framework of support for different device sharing of containers

- More robust and reasonable behaviors when NOAUTOSIZE is enabled
- Repair/extension of disk metadata when AUTOSIZE is enabled
- MediaID support when device presents it
- Automatic MTAB generation when DEVICE provides a DRVTYPE list
This commit is contained in:
Mark Pizzolato 2022-06-15 15:13:23 -07:00
parent a929b6471d
commit 50b969e519
6 changed files with 1024 additions and 400 deletions

29
scp.c
View File

@ -5945,6 +5945,8 @@ if ((dptr = find_dev (gbuf))) { /* device match? */
ctbr = set_dev_tab; /* global table */
lvl = MTAB_VDV; /* device match */
GET_SWITCHES (cptr); /* get more switches */
if (dptr->numunits == 1) /* Single unit devices have optional */
lvl |= MTAB_VUN; /* unit number */
}
else {
if ((dptr = find_unit (gbuf, &uptr))) { /* unit match? */
@ -8654,6 +8656,8 @@ for (i = 0; i < (device_count + sim_internal_device_count); i++) {/* loop thru d
fprintf (sfile, "%.0f\n", uptr->usecs_remaining);/* [V4.0] remaining wait */
WRITE_I (uptr->pos);
if (uptr->flags & UNIT_ATT) {
if ((uptr->drvtyp != NULL) && (sim_disk_drive_type_set_string (uptr) != NULL))
fprintf (sfile, "\001DriveType=%s\001", sim_disk_drive_type_set_string (uptr));
fputs (sim_relative_path (uptr->filename), sfile);
if ((uptr->flags & UNIT_BUF) && /* writable buffered */
uptr->hwmark && /* files need to be */
@ -9052,8 +9056,21 @@ for (j=0, r = SCPE_OK; j<attcnt; j++) {
if ((r == SCPE_OK) && (!dont_detach_attach)) {
struct stat fstat;
t_addr saved_pos;
char drivetype[CBUFSIZE], filename[CBUFSIZE], cmd[CBUFSIZE * 2];
sim_debug (SIM_DBG_RESTORE, &sim_scp_dev, "ATTACHING=%s to %s\n", sim_uname (attunits[j]), attnames[j]);
if (0 != memcmp (attnames[j], "\001DriveType=", 11)) {
strlcpy (filename, attnames[j], sizeof (filename));
cmd[0] = drivetype[0] = '\0';
}
else {
const char *fname = get_glyph (attnames[j] + 11, drivetype, '\001');
strlcpy (filename, fname, sizeof (filename));
snprintf (cmd, sizeof (cmd), "%s %s", sim_uname (attunits[j]), drivetype);
}
sim_debug (SIM_DBG_RESTORE, &sim_scp_dev, "ATTACHING=%s to %s%s%s\n", sim_uname (attunits[j]), filename, drivetype[0] ? " as " : "", drivetype);
if (cmd[0])
set_cmd (0, cmd);
dptr = find_dev_from_unit (attunits[j]);
if ((!force_restore) &&
(!stat(attnames[j], &fstat)))
@ -9077,7 +9094,7 @@ for (j=0, r = SCPE_OK; j<attcnt; j++) {
warned = TRUE;
sim_printf ("warning - %s was attached to '%s'", sim_uname (attunits[j]), attnames[j]);
if (attunits[j]->filename)
sim_printf (", now attached to '%s'\n", sim_relative_path (attunits[j]->filename));
sim_printf (", now attached to '%s'\n", attunits[j]->filename);
else
sim_printf (", now unattached\n");
}
@ -12595,13 +12612,13 @@ while (bp) {
if (bp == sim_brk_tab[sim_brk_ins])
bpl = sim_brk_tab[sim_brk_ins] = bp->next; /* remove from head of list */
else
bpl->next = bp->next; /* remove from middle of list */
bpl->next = bp->next; /* remove from middle or end of list */
free (bp);
bp = bpl;
}
else {
bpl = bp;
bp = bp->next;
bp = bpl->next;
}
}
if (sim_brk_tab[sim_brk_ins] == NULL) { /* erased entry */
@ -13827,7 +13844,7 @@ static const char *sim_debug_prefix (uint32 dbits, DEVICE* dptr, UNIT* uptr)
const char* debug_type = _get_dbg_verb (dbits, dptr, uptr);
char tim_t[32] = "";
char tim_a[32] = "";
char pc_s[MAX_WIDTH + 1] = "";
char pc_s[MAX_WIDTH + 33] = "";
struct timespec time_now;
if (sim_deb_switches & (SWMASK ('T') | SWMASK ('R') | SWMASK ('A'))) {
@ -13860,7 +13877,7 @@ if (sim_deb_switches & SWMASK ('P')) {
sprintf(pc_s, "-%s:", sim_PC->name);
sprint_val (&pc_s[strlen(pc_s)], val, sim_PC->radix, sim_PC->width, sim_PC->flags & REG_FMT);
}
sprintf(debug_line_prefix, "DBG(%s%s%.0f%s)%s> %s %s: ", tim_t, tim_a, sim_gtime(), pc_s, AIO_MAIN_THREAD ? "" : "+", dptr->name, debug_type);
snprintf(debug_line_prefix, sizeof (debug_line_prefix), "DBG(%s%s%.0f%s)%s> %s %s: ", tim_t, tim_a, sim_gtime(), pc_s, AIO_MAIN_THREAD ? "" : "+", dptr->name, debug_type);
return debug_line_prefix;
}

View File

@ -479,6 +479,7 @@ typedef struct DEBTAB DEBTAB;
typedef struct FILEREF FILEREF;
typedef struct MEMFILE MEMFILE;
typedef struct BITFIELD BITFIELD;
typedef struct DRVTYP DRVTYP;
typedef t_stat (*ACTIVATE_API)(UNIT *unit, int32 interval);
@ -556,10 +557,11 @@ struct DEVICE {
#define DEV_TYPEMASK (((1 << DEV_S_TYPE) - 1) << DEV_V_TYPE)
#define DEV_DISK (1 << DEV_V_TYPE) /* sim_disk Attach */
#define DEV_TAPE (2 << DEV_V_TYPE) /* sim_tape Attach */
#define DEV_MUX (3 << DEV_V_TYPE) /* sim_tmxr Attach */
#define DEV_CARD (4 << DEV_V_TYPE) /* sim_card Attach */
#define DEV_ETHER (5 << DEV_V_TYPE) /* Ethernet Device */
#define DEV_DISPLAY (6 << DEV_V_TYPE) /* Display Device */
#define DEV_SCSI (3 << DEV_V_TYPE) /* sim_scsi Attach */
#define DEV_MUX (4 << DEV_V_TYPE) /* sim_tmxr Attach */
#define DEV_CARD (5 << DEV_V_TYPE) /* sim_card Attach */
#define DEV_ETHER (6 << DEV_V_TYPE) /* Ethernet Device */
#define DEV_DISPLAY (7 << DEV_V_TYPE) /* Display Device */
#define DEV_TYPE(dptr) ((dptr)->flags & DEV_TYPEMASK)
#define DEV_UFMASK_31 (((1u << DEV_V_RSV) - 1) & ~((1u << DEV_V_UF_31) - 1))
@ -600,7 +602,7 @@ struct UNIT {
void *up8; /* device specific */
uint16 us9; /* device specific */
uint16 us10; /* device specific */
uint32 disk_type; /* Disk specific info */
DRVTYP *drvtyp; /* Drive Type */
void *tmxr; /* TMXR linkage */
uint32 recsize; /* Tape specific info */
t_addr tape_eom; /* Tape specific info */

1154
sim_disk.c

File diff suppressed because it is too large Load Diff

View File

@ -42,24 +42,31 @@ typedef uint32 t_lba; /* disk logical block ad
/* Unit flags */
#define DKUF_V_FMT (UNIT_V_UF + 0) /* disk file format */
#define DKUF_W_FMT 2 /* 2b of formats */
#define DKUF_W_FMT 2 /* 2b of container formats */
#define DKUF_M_FMT ((1u << DKUF_W_FMT) - 1)
#define DKUF_F_AUTO 0 /* Auto detect format format */
#define DKUF_F_STD 1 /* SIMH format */
#define DKUF_F_RAW 2 /* Raw Physical Disk Access */
#define DKUF_F_VHD 3 /* VHD format */
#define DKUF_V_NOAUTOSIZE (DKUF_V_FMT + DKUF_W_FMT) /* Don't Autosize disk option */
#define DKUF_V_ENC (DKUF_V_FMT + DKUF_W_FMT) /* data encoding/packing */
#define DKUF_W_ENC 2 /* 2b of data encoding/packing */
#define DKUF_M_ENC ((1u << DKUF_W_ENC) - 1)
#define DKUF_V_NOAUTOSIZE (DKUF_V_ENC + DKUF_W_ENC) /* Don't Autosize disk option */
#define DKUF_V_UF (DKUF_V_NOAUTOSIZE + 1)
#define DKUF_WLK UNIT_WLK
#define DKUF_FMT (DKUF_M_FMT << DKUF_V_FMT)
#define DKUF_ENC (DKUF_M_ENC << DKUF_V_ENC)
#define DKUF_WRP (DKUF_WLK | UNIT_RO)
#define DKUF_NOAUTOSIZE (1 << DKUF_V_NOAUTOSIZE)
#define DK_F_STD (DKUF_F_STD << DKUF_V_FMT)
#define DK_F_RAW (DKUF_F_RAW << DKUF_V_FMT)
#define DK_F_VHD (DKUF_F_VHD << DKUF_V_FMT)
/* Encoding/Packing specfics */
#define DK_GET_FMT(u) (((u)->flags >> DKUF_V_FMT) & DKUF_M_FMT)
#define DK_ENC_BYTE 0x00000001
#define DK_ENC_WORD 0x00000002
#define DK_ENC_LONG 0x00000004
#define DK_ENC_LONGLONG 0x00000008
#define DK_ENC_X_LSB 0x80
#define DK_ENC_X_MSB 0x00
#define DK_ENC_XFR_IN 0
#define DK_ENC_XFR_OUT 16
#define DK_ENC_LL_DBD9 (((DK_ENC_X_LSB | 64) << DK_ENC_XFR_OUT) | ((DK_ENC_X_MSB | 36) << DK_ENC_XFR_IN))
#define DK_ENC_LL_DLD9 (((DK_ENC_X_LSB | 64) << DK_ENC_XFR_OUT) | ((DK_ENC_X_LSB | 36) << DK_ENC_XFR_IN))
/* Return status codes */
@ -101,7 +108,7 @@ t_stat sim_disk_attach_ex2 (UNIT *uptr,
int completion_delay, /* Minimum Delay for asynch I/O completion */
const char **drivetypes, /* list of drive types (from smallest to largest) */
/* to try and fit the container/file system into */
size_t reserved_sectors); /* Unused sectors beyond the file system */
size_t reserved_sectors); /* Unused sectors beyond the file system */
t_stat sim_disk_detach (UNIT *uptr);
t_stat sim_disk_attach_help(FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr);
t_stat sim_disk_rdsect (UNIT *uptr, t_lba lba, uint8 *buf, t_seccnt *sectsread, t_seccnt sects);
@ -125,14 +132,91 @@ t_bool sim_disk_wrp (UNIT *uptr);
t_stat sim_disk_pdp11_bad_block (UNIT *uptr, int32 sec, int32 wds);
const char *sim_disk_decode_mediaid (uint32 MediaId);
uint32 sim_disk_drive_type_to_mediaid (const char *drive_type, const char *device_type);
uint32 sim_disk_get_mediaid (UNIT *uptr);
t_offset sim_disk_size (UNIT *uptr);
t_bool sim_disk_vhd_support (void);
t_bool sim_disk_raw_support (void);
void sim_disk_data_trace (UNIT *uptr, const uint8 *data, size_t lba, size_t len, const char* txt, int detail, uint32 reason);
t_stat sim_disk_info_cmd (int32 flag, CONST char *ptr);
t_stat sim_disk_set_noautosize (int32 flag, CONST char *cptr);
t_stat sim_disk_set_drive_type (UNIT *uptr, int32 val, CONST char *cptr, void *desc);
t_stat sim_disk_set_drive_type_by_name (UNIT *uptr, const char *drive_type);
t_stat sim_disk_show_drive_type (FILE *st, UNIT *uptr, int32 val, CONST void *desc);
const char *sim_disk_drive_type_set_string (UNIT *uptr);
t_stat sim_disk_test (DEVICE *dptr, const char *cptr);
struct DRVTYP {
uint32 sect; /* sectors */
uint32 surf; /* surfaces */
uint32 cyl; /* cylinders */
uint32 size; /* size in LBNs */
const char *name; /* name */
uint32 sectsize; /* sector size in bytes */
uint32 flags; /* flags */
const char *driver_name; /* OS Driver device name */
uint32 MediaId; /* MSCP media id */
uint32 model; /* model */
const char *name_alias; /* Alias device type name */
const char *name_desc; /* Descriptive Text for device type */
uint32 tpg; /* trk/grp */
uint32 gpc; /* grp/cyl */
uint32 xbn; /* XBN size */
uint32 dbn; /* DBN size */
uint32 rcts; /* RCT size */
uint32 rctc; /* RCT copies */
uint32 rbn; /* RBNs */
uint32 cylp; /* first cyl for write precomp */
uint32 cylr; /* first cyl for reduced write current */
uint32 ccs; /* cyl/cyl skew */
uint32 devtype; /* SCSI Device Type */
uint32 pqual; /* SCSI pqual */
uint32 scsiver; /* SCSI scsi version */
const char *manufacturer; /* SCSI manufacturer string */
const char *product; /* SCSI product string */
const char *rev; /* SCSI revision string */
uint32 gaplen; /* SCSI tape gap length */
};
/* Contents/Values in DRVTYP.flags field */
#define DRVFL_V_TYPE 0 /* Interface Type */
#define DRVFL_W_TYPE 5
#define DRVFL_M_TYPE ((1u << DRVFL_W_TYPE) - 1)
#define DRVFL_TYPE_MFM (0 << DRVFL_V_TYPE)
#define DRVFL_TYPE_SDI (1 << DRVFL_V_TYPE)
#define DRVFL_TYPE_RC (2 << DRVFL_V_TYPE)
#define DRVFL_TYPE_DSSI (3 << DRVFL_V_TYPE)
#define DRVFL_TYPE_SCSI (4 << DRVFL_V_TYPE)
#define DRVFL_TYPE_RM (5 << DRVFL_V_TYPE)
#define DRVFL_TYPE_RP (6 << DRVFL_V_TYPE)
#define DRVFL_TYPE_RL (7 << DRVFL_V_TYPE)
#define DRVFL_GET_IFTYPE(drv) (((drv)->flags >> DRVFL_V_TYPE) & DRVFL_M_TYPE)
#define DRVFL_V_RMV (DRVFL_V_TYPE + DRVFL_W_TYPE)
#define DRVFL_RMV (1u << DRVFL_V_RMV) /* Removable */
#define DRVFL_V_RO (DRVFL_V_RMV + 1)
#define DRVFL_RO (1u << DRVFL_V_RO) /* Read Only */
#define DRVFL_V_DEC144 (DRVFL_V_RO + 1)
#define DRVFL_DEC144 (1u << DRVFL_V_DEC144) /* DEC 144 Bad Block track */
#define DRVFL_V_SETSIZE (DRVFL_V_DEC144 + 1)
#define DRVFL_SETSIZE (1u << DRVFL_V_SETSIZE) /* Settable Drive Size/Capacity */
#define DRVFL_V_NOCHNG (DRVFL_V_SETSIZE + 1)
#define DRVFL_NOCHNG (1u << DRVFL_V_NOCHNG) /* Can't change drive type once set */
#define DRVFL_V_NORMV (DRVFL_V_NOCHNG + 1)
#define DRVFL_NORMV (1u << DRVFL_V_NORMV) /* Can't change to a removable drive */
/* DRVTYP Initializer for SCSI disk and/or tape */
#define DRV_SCSI(typ, pq, ver, rmv, bsz, lbn, man, prd, rev, nm, gap, txt) \
46, 9, 1549, lbn, nm, bsz, (rmv == TRUE) ? DRVFL_RMV : 0, \
NULL, 0, 0, NULL, txt, \
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
typ, pq, ver, man, prd, rev, gap
#define DRV_MINC 512 /* min cap LBNs */
#define DRV_MAXC 4194303 /* max cap LBNs */
#define DRV_EMAXC 2147483647 /* ext max cap */
#ifdef __cplusplus
}
#endif

View File

@ -389,7 +389,6 @@ else
void scsi_inquiry (SCSI_BUS *bus, uint8 *data, uint32 len)
{
UNIT *uptr = bus->dev[bus->target];
SCSI_DEV *dev = (SCSI_DEV *)uptr->up7;
scsi_debug_cmd (bus, "Inquiry\n");
@ -400,7 +399,7 @@ if ((bus->lun != 0) || (uptr->flags & UNIT_DIS)) {
// scsi_status (bus, STS_CHK, KEY_ILLREQ, ASC_INVCOM);
}
else {
bus->buf[bus->buf_b++] = (dev->pqual << 5) | dev->devtype; /* device class */
bus->buf[bus->buf_b++] = (uptr->drvtyp->pqual << 5) | uptr->drvtyp->devtype; /* device class */
#if 0
if (data[0] & 0x01) { /* vital product data */
@ -427,22 +426,22 @@ else {
}
}
#endif
if (dev->removeable)
if (uptr->drvtyp->flags & DRVFL_RMV)
bus->buf[bus->buf_b++] = 0x80; /* removeable */
else
bus->buf[bus->buf_b++] = 0; /* fixed */
bus->buf[bus->buf_b++] = dev->scsiver; /* versions */
bus->buf[bus->buf_b++] = dev->scsiver; /* respose data format */
bus->buf[bus->buf_b++] = uptr->drvtyp->scsiver; /* versions */
bus->buf[bus->buf_b++] = uptr->drvtyp->scsiver; /* respose data format */
bus->buf[bus->buf_b++] = 31; /* additional length */
bus->buf[bus->buf_b++] = 0; /* reserved */
bus->buf[bus->buf_b++] = 0; /* reserved */
bus->buf[bus->buf_b++] = 0;
sprintf ((char *)&bus->buf[bus->buf_b], "%-8s", dev->manufacturer);
sprintf ((char *)&bus->buf[bus->buf_b], "%-8s", uptr->drvtyp->manufacturer);
bus->buf_b += 8;
sprintf ((char *)&bus->buf[bus->buf_b], "%-16s", dev->product);
sprintf ((char *)&bus->buf[bus->buf_b], "%-16s", uptr->drvtyp->product);
bus->buf_b += 16;
sprintf ((char *)&bus->buf[bus->buf_b], "%-4s", dev->rev);
sprintf ((char *)&bus->buf[bus->buf_b], "%-4s", uptr->drvtyp->rev);
bus->buf_b += 4;
}
@ -529,7 +528,6 @@ else if (bus->phase == SCSI_DATO) {
void scsi_mode_sense (SCSI_BUS *bus, uint8 *data, uint32 len)
{
UNIT *uptr = bus->dev[bus->target];
SCSI_DEV *dev = (SCSI_DEV *)uptr->up7;
uint32 pc, pctl;
pc = data[2] & 0x3F; /* page code */
@ -540,9 +538,9 @@ bus->buf[bus->buf_b++] = ((uptr->capac - 1) >> 16) & 0xFF; /* # blocks (23:16) *
bus->buf[bus->buf_b++] = ((uptr->capac - 1) >> 8) & 0xFF; /* # blocks (15:8) */
bus->buf[bus->buf_b++] = (uptr->capac - 1) & 0xFF; /* # blocks (7:0) */
bus->buf[bus->buf_b++] = 0x00; /* reserved */
bus->buf[bus->buf_b++] = (dev->block_size >> 16) & 0xFF;
bus->buf[bus->buf_b++] = (dev->block_size >> 8) & 0xFF;
bus->buf[bus->buf_b++] = (dev->block_size >> 0) & 0xFF;
bus->buf[bus->buf_b++] = (uptr->drvtyp->sectsize >> 16) & 0xFF;
bus->buf[bus->buf_b++] = (uptr->drvtyp->sectsize >> 8) & 0xFF;
bus->buf[bus->buf_b++] = (uptr->drvtyp->sectsize >> 0) & 0xFF;
if ((pc == 0x1) || (pc == 0x3F)) {
bus->buf[bus->buf_b++] = 0x1; /* R/W error recovery page */
@ -645,7 +643,6 @@ if ((pc == 0xA) || (pc == 0x3F)) {
void scsi_mode_sense6 (SCSI_BUS *bus, uint8 *data, uint32 len)
{
UNIT *uptr = bus->dev[bus->target];
SCSI_DEV *dev = (SCSI_DEV *)uptr->up7;
uint32 pc, pctl;
scsi_debug_cmd (bus, "Mode Sense(6)\n");
@ -661,7 +658,7 @@ if (pc == 0x8) {
memset (&bus->buf[0], 0, data[4]); /* allocation len */
bus->buf[bus->buf_b++] = 0x0; /* mode data length */
bus->buf[bus->buf_b++] = 0x0; /* medium type */
if (dev->devtype == SCSI_CDROM)
if (uptr->drvtyp->devtype == SCSI_CDROM)
bus->buf[bus->buf_b++] = 0x80; /* dev specific param */
else
bus->buf[bus->buf_b++] = 0x0; /* dev specific param */
@ -732,7 +729,6 @@ scsi_status (bus, STS_OK, KEY_OK, ASC_OK);
void scsi_read_capacity (SCSI_BUS *bus, uint8 *data, uint32 len)
{
UNIT *uptr = bus->dev[bus->target];
SCSI_DEV *dev = (SCSI_DEV *)uptr->up7;
scsi_debug_cmd (bus, "Read Capacity, pmi = %d\n", (data[8] & 0x1));
@ -741,8 +737,8 @@ if ((uptr->flags & UNIT_ATT) == 0) { /* not attached? */
return;
}
PUTL (bus->buf, 0, (uptr->capac - 1)); /* # blocks */
PUTL (bus->buf, 4, dev->block_size); /* block size */
PUTL (bus->buf, 0, (uptr->capac - 1)); /* LBN of last block is 1 less than # blocks */
PUTL (bus->buf, 4, uptr->drvtyp->sectsize); /* block size */
bus->buf_b = 8;
scsi_set_phase (bus, SCSI_DATI); /* data in phase next */
@ -754,7 +750,6 @@ scsi_set_req (bus); /* request to send data
void scsi_read6_disk (SCSI_BUS *bus, uint8 *data, uint32 len)
{
UNIT *uptr = bus->dev[bus->target];
SCSI_DEV *dev = (SCSI_DEV *)uptr->up7;
t_lba lba;
t_seccnt sects, sectsread;
t_stat r;
@ -769,11 +764,11 @@ scsi_debug_cmd (bus, "Read(6) lba %d blks %d\n", lba, sects);
if (uptr->flags & UNIT_ATT)
r = sim_disk_rdsect (uptr, lba, &bus->buf[0], &sectsread, sects);
else {
memset (&bus->buf[0], 0, (sects * dev->block_size));
memset (&bus->buf[0], 0, (sects * uptr->drvtyp->sectsize));
sectsread = sects;
}
bus->buf_b = (sectsread * dev->block_size);
bus->buf_b = (sectsread * uptr->drvtyp->sectsize);
scsi_set_phase (bus, SCSI_DATI); /* data in phase next */
scsi_set_req (bus); /* request to send data */
}
@ -783,7 +778,6 @@ scsi_set_req (bus); /* request to send data
void scsi_read6_tape (SCSI_BUS *bus, uint8 *data, uint32 len)
{
UNIT *uptr = bus->dev[bus->target];
SCSI_DEV *dev = (SCSI_DEV *)uptr->up7;
t_seccnt sects, sectsread;
t_stat r;
@ -804,7 +798,7 @@ scsi_debug_cmd (bus, "Read(6) blks %d fixed %d\n", sects, (data[1] & 0x1));
if (uptr->flags & UNIT_ATT) {
if (data[1] & 0x1) {
r = sim_tape_rdrecf (uptr, &bus->buf[0], &sectsread, (sects * dev->block_size));
r = sim_tape_rdrecf (uptr, &bus->buf[0], &sectsread, (sects * uptr->drvtyp->sectsize));
scsi_debug_cmd (bus, "Read tape blk %d, read %d, r = %d\n", sects, sectsread, r);
}
else {
@ -812,7 +806,7 @@ if (uptr->flags & UNIT_ATT) {
scsi_debug_cmd (bus, "Read tape max %d, read %d, r = %d\n", sects, sectsread, r);
if (r == MTSE_INVRL) { /* overlength condition */
scsi_debug_cmd (bus, "Overlength\n");
if ((data[1] & 0x2) && (dev->block_size == 0)) { /* SILI set */
if ((data[1] & 0x2) && (uptr->drvtyp->sectsize == 0)) { /* SILI set */
scsi_debug_cmd (bus, "SILI set\n");
}
else {
@ -840,8 +834,8 @@ if (uptr->flags & UNIT_ATT) {
scsi_tape_status (bus, r);
}
else {
memset (&bus->buf[0], 0, (sects * dev->block_size));
sectsread = (sects * dev->block_size);
memset (&bus->buf[0], 0, (sects * uptr->drvtyp->sectsize));
sectsread = (sects * uptr->drvtyp->sectsize);
}
if (sectsread > 0) {
@ -860,7 +854,6 @@ scsi_set_req (bus); /* request to send data
void scsi_read10_disk (SCSI_BUS *bus, uint8 *data, uint32 len)
{
UNIT *uptr = bus->dev[bus->target];
SCSI_DEV *dev = (SCSI_DEV *)uptr->up7;
t_lba lba;
t_seccnt sects, sectsread;
t_stat r;
@ -878,11 +871,11 @@ if (sects == 0) { /* no data to read */
if (uptr->flags & UNIT_ATT)
r = sim_disk_rdsect (uptr, lba, &bus->buf[0], &sectsread, sects);
else {
memset (&bus->buf[0], 0, (sects * dev->block_size));
memset (&bus->buf[0], 0, (sects * uptr->drvtyp->sectsize));
sectsread = sects;
}
bus->buf_b = (sectsread * dev->block_size);
bus->buf_b = (sectsread * uptr->drvtyp->sectsize);
scsi_set_phase (bus, SCSI_DATI); /* data in phase next */
scsi_set_req (bus); /* request to send data */
}
@ -919,7 +912,6 @@ scsi_set_req (bus); /* request to send data
void scsi_write6_disk (SCSI_BUS *bus, uint8 *data, uint32 len)
{
UNIT *uptr = bus->dev[bus->target];
SCSI_DEV *dev = (SCSI_DEV *)uptr->up7;
t_lba lba;
t_seccnt sects, sectswritten;
t_stat r;
@ -929,7 +921,7 @@ if (bus->phase == SCSI_CMD) {
memcpy (&bus->cmd[0], &data[0], 6);
sects = bus->cmd[4];
if (sects == 0) sects = 256;
bus->buf_b = (sects * dev->block_size);
bus->buf_b = (sects * uptr->drvtyp->sectsize);
scsi_set_phase (bus, SCSI_DATO); /* data out phase next */
scsi_set_req (bus); /* request data */
}
@ -952,7 +944,6 @@ else if (bus->phase == SCSI_DATO) {
void scsi_write6_tape (SCSI_BUS *bus, uint8 *data, uint32 len)
{
UNIT *uptr = bus->dev[bus->target];
SCSI_DEV *dev = (SCSI_DEV *)uptr->up7;
t_seccnt sects;
t_stat r;
@ -961,7 +952,7 @@ if (bus->phase == SCSI_CMD) {
memcpy (&bus->cmd[0], &data[0], 6); /* save current cmd */
sects = GETW (bus->cmd, 3) | (bus->cmd[2] << 16);
if (data[1] & 0x1) /* FIXED */
sects = sects * dev->block_size;
sects = sects * uptr->drvtyp->sectsize;
bus->buf_b = sects;
scsi_set_phase (bus, SCSI_DATO); /* data out phase next */
scsi_set_req (bus); /* request data */
@ -969,7 +960,7 @@ if (bus->phase == SCSI_CMD) {
else if (bus->phase == SCSI_DATO) {
sects = GETW (bus->cmd, 3) | (bus->cmd[2] << 16);
if (data[1] & 0x1) /* FIXED */
sects = sects * dev->block_size;
sects = sects * uptr->drvtyp->sectsize;
scsi_debug_cmd (bus, "Write(6) - DATO, bytes %d\n", sects);
if (uptr->flags & UNIT_ATT) {
@ -990,7 +981,6 @@ else if (bus->phase == SCSI_DATO) {
void scsi_write10_disk (SCSI_BUS *bus, uint8 *data, uint32 len)
{
UNIT *uptr = bus->dev[bus->target];
SCSI_DEV *dev = (SCSI_DEV *)uptr->up7;
t_lba lba;
t_seccnt sects, sectswritten;
t_stat r;
@ -1002,7 +992,7 @@ if (bus->phase == SCSI_CMD) {
if (sects == 0) /* no data to write */
scsi_status (bus, STS_OK, KEY_OK, ASC_OK);
else {
bus->buf_b = (sects * dev->block_size);
bus->buf_b = (sects * uptr->drvtyp->sectsize);
scsi_set_phase (bus, SCSI_DATO); /* data out phase next */
scsi_set_req (bus); /* request data */
}
@ -1025,7 +1015,6 @@ else if (bus->phase == SCSI_DATO) {
void scsi_erase (SCSI_BUS *bus, uint8 *data, uint32 len)
{
UNIT *uptr = bus->dev[bus->target];
SCSI_DEV *dev = (SCSI_DEV *)uptr->up7;
t_stat r;
scsi_debug_cmd (bus, "Erase\n");
@ -1033,7 +1022,7 @@ scsi_debug_cmd (bus, "Erase\n");
if (data[1] & 0x1) /* LONG bit set? */
r = sim_tape_wreom (uptr); /* erase to EOT */
else
r = sim_tape_wrgap (uptr, dev->gaplen); /* write gap */
r = sim_tape_wrgap (uptr, uptr->drvtyp->gaplen); /* write gap */
scsi_tape_status (bus, r);
scsi_status (bus, bus->status, bus->sense_key, bus->sense_code);
@ -1438,7 +1427,6 @@ switch (data[0]) {
uint32 scsi_command (SCSI_BUS *bus, uint8 *data, uint32 len)
{
UNIT *uptr = bus->dev[bus->target];
SCSI_DEV *dev = (SCSI_DEV *)uptr->up7;
uint32 cmd_len;
cmd_len = scsi_decode_group (data[0]);
@ -1447,7 +1435,7 @@ if (len < cmd_len) /* all command bytes rec
return 0; /* no, need more */
bus->status = STS_OK;
switch (dev->devtype) {
switch (uptr->drvtyp->devtype) {
case SCSI_DISK:
case SCSI_WORM: /* same as disk for now */
@ -1463,7 +1451,7 @@ switch (dev->devtype) {
break;
default:
sim_printf ("SCSI: commands unimplemented for device type %d\n", dev->devtype);
sim_printf ("SCSI: commands unimplemented for device type %d\n", uptr->drvtyp->devtype);
break;
}
@ -1584,26 +1572,14 @@ void scsi_add_unit (SCSI_BUS *bus, uint32 id, UNIT *uptr)
bus->dev[id] = uptr;
}
/* Set the SCSI device parameters for a unit */
void scsi_set_unit (SCSI_BUS *bus, UNIT *uptr, SCSI_DEV *dev)
{
uptr->up7 = (void *)dev;
if (dev->devtype == SCSI_CDROM)
set_writelock (uptr, 1, NULL, NULL);
}
/* Reset a unit */
void scsi_reset_unit (UNIT *uptr)
{
SCSI_DEV *dev = (SCSI_DEV *)uptr->up7;
if (dev == NULL)
if (uptr->drvtyp == NULL)
return;
switch (dev->devtype) {
switch (uptr->drvtyp->devtype) {
case SCSI_DISK:
case SCSI_WORM:
case SCSI_CDROM:
@ -1649,12 +1625,10 @@ return SCPE_OK;
t_stat scsi_set_fmt (UNIT *uptr, int32 val, CONST char *cptr, void *desc)
{
SCSI_DEV *dev = (SCSI_DEV *)uptr->up7;
if (dev == NULL)
if (uptr->drvtyp == NULL)
return SCPE_NOFNC;
switch (dev->devtype) {
switch (uptr->drvtyp->devtype) {
case SCSI_DISK:
case SCSI_WORM:
case SCSI_CDROM:
@ -1670,12 +1644,10 @@ switch (dev->devtype) {
t_stat scsi_show_fmt (FILE *st, UNIT *uptr, int32 val, CONST void *desc)
{
SCSI_DEV *dev = (SCSI_DEV *)uptr->up7;
if (dev == NULL)
if (uptr->drvtyp == NULL)
return SCPE_NOFNC;
switch (dev->devtype) {
switch (uptr->drvtyp->devtype) {
case SCSI_DISK:
case SCSI_WORM:
case SCSI_CDROM:
@ -1691,9 +1663,7 @@ switch (dev->devtype) {
t_stat scsi_set_wlk (UNIT *uptr, int32 val, CONST char *cptr, void *desc)
{
SCSI_DEV *dev = (SCSI_DEV *)uptr->up7;
if ((dev->devtype == SCSI_CDROM) && (val == 0))
if ((uptr->drvtyp->devtype == SCSI_CDROM) && (val == 0))
return sim_messagef (SCPE_ARG, "%s: Can't write enable CDROM device\n", sim_uname (uptr));
return set_writelock (uptr, val, cptr, desc);
}
@ -1709,18 +1679,16 @@ return show_writelock (st, uptr, val, desc);
t_stat scsi_attach_ex (UNIT *uptr, CONST char *cptr, const char **drivetypes)
{
SCSI_DEV *dev = (SCSI_DEV *)uptr->up7;
if (dev == NULL)
if (uptr->drvtyp == NULL)
return SCPE_NOFNC;
switch (dev->devtype) {
switch (uptr->drvtyp->devtype) {
case SCSI_DISK:
case SCSI_WORM:
return sim_disk_attach_ex (uptr, cptr, dev->block_size, sizeof (uint16), (uptr->flags & SCSI_NOAUTO), SCSI_DBG_DSK, dev->name, 0, 0, drivetypes);
return sim_disk_attach_ex (uptr, cptr, uptr->drvtyp->sectsize, sizeof (uint16), (uptr->flags & SCSI_NOAUTO), SCSI_DBG_DSK, uptr->drvtyp->name, 0, 0, drivetypes);
case SCSI_CDROM:
sim_switches |= SWMASK ('R'); /* Force Read Only Attach for CDROM */
return sim_disk_attach_ex (uptr, cptr, dev->block_size, sizeof (uint16), FALSE, SCSI_DBG_DSK, dev->name, 0, 0, drivetypes);
return sim_disk_attach_ex (uptr, cptr, uptr->drvtyp->sectsize, sizeof (uint16), FALSE, SCSI_DBG_DSK, uptr->drvtyp->name, 0, 0, drivetypes);
case SCSI_TAPE:
return sim_tape_attach_ex (uptr, cptr, SCSI_DBG_TAP, 0);
default:
@ -1737,12 +1705,10 @@ return scsi_attach_ex (uptr, cptr, NULL);
t_stat scsi_detach (UNIT *uptr)
{
SCSI_DEV *dev = (SCSI_DEV *)uptr->up7;
if (dev == NULL)
if (uptr->drvtyp == NULL)
return SCPE_NOFNC;
switch (dev->devtype) {
switch (uptr->drvtyp->devtype) {
case SCSI_DISK:
case SCSI_WORM:
case SCSI_CDROM:

View File

@ -72,7 +72,9 @@
#define SCSI_WLK (UNIT_WLK|UNIT_RO) /* hwre write lock */
#define SCSI_NOAUTO DKUF_NOAUTOSIZE
/* This structure has been obsoleted and its role is now provided by
the DRVTYP structure */
#if 0
struct scsi_dev_t {
uint8 devtype; /* device type */
uint8 pqual; /* peripheral qualifier */
@ -86,6 +88,7 @@ struct scsi_dev_t {
const char *name; /* gap length for tapes */
uint32 gaplen;
};
#endif
struct scsi_bus_t {
DEVICE *dptr; /* SCSI device */
@ -108,7 +111,6 @@ struct scsi_bus_t {
};
typedef struct scsi_bus_t SCSI_BUS;
typedef struct scsi_dev_t SCSI_DEV;
t_bool scsi_arbitrate (SCSI_BUS *bus, uint32 initiator);
void scsi_release (SCSI_BUS *bus);
@ -119,7 +121,6 @@ uint32 scsi_write (SCSI_BUS *bus, uint8 *data, uint32 len);
uint32 scsi_read (SCSI_BUS *bus, uint8 *data, uint32 len);
uint32 scsi_state (SCSI_BUS *bus, uint32 id);
void scsi_add_unit (SCSI_BUS *bus, uint32 id, UNIT *uptr);
void scsi_set_unit (SCSI_BUS *bus, UNIT *uptr, SCSI_DEV *dev);
void scsi_reset_unit (UNIT *uptr);
void scsi_reset (SCSI_BUS *bus);
t_stat scsi_init (SCSI_BUS *bus, uint32 maxfr);