53 static struct scsi_transfer *first_free_scsi_transfer_alloc = NULL;
68 if (first_free_scsi_transfer_alloc != NULL) {
69 p = first_free_scsi_transfer_alloc;
70 first_free_scsi_transfer_alloc = p->
next_free;
74 fprintf(stderr,
"scsi_transfer_alloc(): out " 95 fprintf(stderr,
"scsi_transfer_free(): p == NULL\n");
113 p->
next_free = first_free_scsi_transfer_alloc;
114 first_free_scsi_transfer_alloc = p;
129 unsigned char *p = (*pp);
132 printf(
"WARNING! scsi_transfer_allocbuf(): old pointer " 133 "was not NULL, freeing it now\n");
138 if ((p = (
unsigned char *) malloc(want_len)) == NULL) {
139 fprintf(stderr,
"scsi_transfer_allocbuf(): out of " 140 "memory trying to allocate %li bytes\n", (
long)want_len);
145 memset(p, 0, want_len);
160 static void diskimage__return_default_status_and_message(
175 static void diskimage__switch_tape(
struct diskimage *d)
179 snprintf(tmpfname,
sizeof(tmpfname),
"%s.%i",
181 tmpfname[
sizeof(tmpfname)-1] =
'\0';
186 d->
f = fopen(tmpfname, d->
writable?
"r+" :
"r");
188 fprintf(stderr,
"[ diskimage__switch_tape(): could not " 189 "(re)open '%s' ]\n", tmpfname);
225 if (machine == NULL) {
226 fatal(
"[ diskimage_scsicommand(): machine == NULL ]\n");
232 if (d->
type == type && d->
id ==
id)
237 fprintf(stderr,
"[ diskimage_scsicommand(): %s " 238 " id %i not connected? ]\n", diskimage_types[type],
id);
241 if (xferp->
cmd == NULL) {
242 fatal(
"[ diskimage_scsicommand(): cmd == NULL ]\n");
247 fatal(
"[ diskimage_scsicommand(): cmd_len == %i ]\n",
252 debug(
"[ diskimage_scsicommand(id=%i) cmd=0x%02x: ",
256 fatal(
"[ diskimage_scsicommand(id=%i) cmd=0x%02x len=%i:",
258 for (i=0; i<xferp->
cmd_len; i++)
261 if (xferp->
cmd_len > 7 && xferp->
cmd[5] == 0x11)
267 static FILE *
f = NULL;
269 f = fopen(
"scsi_log.txt",
"w");
272 fprintf(f,
"id=%i cmd =",
id);
273 for (i=0; i<xferp->
cmd_len; i++)
274 fprintf(f,
" %02x", xferp->
cmd[i]);
281 switch (xferp->
cmd[0]) {
284 debug(
"TEST_UNIT_READY");
289 if (xferp->
cmd[1] != 0x00)
290 fatal(
"WARNING: TEST_UNIT_READY with cmd[1]=0x%02x" 291 " not yet implemented\n", (
int)xferp->
cmd[1]);
293 diskimage__return_default_status_and_message(xferp);
300 if (xferp->
cmd[1] != 0x00) {
301 debug(
"WARNING: INQUIRY with cmd[1]=0x%02x not yet " 302 "implemented\n", (
int)xferp->
cmd[1]);
308 retlen = xferp->
cmd[4];
310 fatal(
"WARNING: SCSI inquiry len=%i, <36!\n", retlen);
323 xferp->
data_in[4] = retlen - 4;
330 memcpy(xferp->
data_in+8,
"GXemul ", 8);
332 type, namebuf,
sizeof(namebuf))) {
333 for (
size_t j=0; j<
sizeof(namebuf); j++) {
334 if (namebuf[j] == 0) {
335 for (; j<
sizeof(namebuf); j++)
341 memcpy(xferp->
data_in+16, namebuf, 16);
343 memcpy(xferp->
data_in+16,
"DISK ", 16);
344 memcpy(xferp->
data_in+32,
"0 ", 4);
354 memcpy(xferp->
data_in+8,
"DEC ", 8);
355 memcpy(xferp->
data_in+16,
"RZ58 (C) DEC", 16);
356 memcpy(xferp->
data_in+32,
"2000", 4);
367 memcpy(xferp->
data_in+8,
"SONY ", 8);
372 memcpy(xferp->
data_in+8,
"DEC ", 8);
374 "RRD42 (C) DEC ", 16);
375 memcpy(xferp->
data_in+32,
"4.5d", 4);
378 memcpy(xferp->
data_in+8,
"NEC ", 8);
380 "CD-ROM CDR-210P ", 16);
381 memcpy(xferp->
data_in+32,
"1.0 ", 4);
389 memcpy(xferp->
data_in+16,
"TAPE ", 16);
398 memcpy(xferp->
data_in+8,
"DEC ", 8);
401 memcpy(xferp->
data_in+32,
"2000", 4);
405 diskimage__return_default_status_and_message(xferp);
409 debug(
"READ_CAPACITY");
412 fatal(
" [ weird READ_CAPACITY len=%i, should be 10 ] ",
415 if (xferp->
cmd[8] & 1) {
417 fatal(
"WARNING: READ_CAPACITY with PMI bit" 418 " set not yet implemented\n");
432 xferp->
data_in[0] = (size >> 24) & 255;
433 xferp->
data_in[1] = (size >> 16) & 255;
434 xferp->
data_in[2] = (size >> 8) & 255;
435 xferp->
data_in[3] = size & 255;
442 diskimage__return_default_status_and_message(xferp);
448 q = 4; retlen = xferp->
cmd[4];
452 retlen = xferp->
cmd[7] * 256 + xferp->
cmd[8];
454 default:
fatal(
" (unimplemented mode_sense len=%i)",
467 if ((xferp->
cmd[2] & 0xc0) != 0)
468 fatal(
"WARNING: mode sense, cmd[2] = 0x%02x\n",
477 pagecode = xferp->
cmd[2] & 0x3f;
479 debug(
"[ MODE SENSE id %i, pagecode=%i ]\n",
id, pagecode);
501 diskimage__return_default_status_and_message(xferp);
511 xferp->
data_in[q + 0] = pagecode;
515 xferp->
data_in[q + 0] = pagecode;
528 xferp->
data_in[q + 0] = pagecode;
539 xferp->
data_in[q + 0] = pagecode;
543 xferp->
data_in[q + 2] = ((5000) >> 8) & 255;
544 xferp->
data_in[q + 3] = (5000) & 255;
561 fatal(
"[ MODE_SENSE for page %i is not yet " 562 "implemented! ]\n", pagecode);
580 size = (xferp->
cmd[2] << 16) +
581 (xferp->
cmd[3] << 8) +
587 if (xferp->
cmd[1] & 0x01) {
596 diskimage__switch_tape(d);
603 fatal(
"[ READ tape, id=%i file=%i, cmd[1]=%02x size=%i" 605 xferp->
cmd[1], (
int)size, (
long long)ofs);
609 debug(
" (weird len=%i)",
620 ofs = ((xferp->
cmd[1] & 0x1f) << 16) +
621 (xferp->
cmd[2] << 8) + xferp->
cmd[3];
622 retlen = xferp->
cmd[4];
627 debug(
" (weird len=%i)",
636 ofs = ((uint64_t)xferp->
cmd[2] << 24) +
637 (xferp->
cmd[3] << 16) + (xferp->
cmd[4] << 8)
639 retlen = (xferp->
cmd[7] << 8) + xferp->
cmd[8];
650 debug(
" READ ofs=%lli size=%i\n", (
long long)ofs, (
int)size);
652 diskimage__return_default_status_and_message(xferp);
667 debug(
" feof id=%i\n",
id);
699 ofs = ((xferp->
cmd[1] & 0x1f) << 16) +
700 (xferp->
cmd[2] << 8) + xferp->
cmd[3];
701 retlen = xferp->
cmd[4];
714 ofs = ((uint64_t)xferp->
cmd[2] << 24) +
715 (xferp->
cmd[3] << 16) + (xferp->
cmd[4] << 8) +
717 retlen = (xferp->
cmd[7] << 8) + xferp->
cmd[8];
724 debug(
", data_out == NULL, wanting %i bytes, \n\n",
730 debug(
", data_out != NULL, OK :-)");
732 debug(
"WRITE ofs=%i size=%i offset=%i\n", (
int)ofs,
743 diskimage__return_default_status_and_message(xferp);
747 debug(
"SYNCHRONIZE_CACHE");
755 diskimage__return_default_status_and_message(xferp);
759 debug(
"START_STOP_UNIT");
764 for (i=0; i<(ssize_t)xferp->
cmd_len; i++)
769 diskimage__return_default_status_and_message(xferp);
773 debug(
"REQUEST_SENSE");
775 retlen = xferp->
cmd[4];
778 if (xferp->
cmd[1] != 0x00)
779 fatal(
"WARNING: REQUEST_SENSE with cmd[1]=0x%02x not" 780 " yet implemented\n", (
int)xferp->
cmd[1]);
783 fatal(
"WARNING: SCSI request sense len=%i, <18!\n",
792 xferp->
data_in[0] = 0x80 + 0x70;
801 printf(
" XXX(!) \n");
804 xferp->
data_in[7] = retlen - 7;
807 diskimage__return_default_status_and_message(xferp);
811 debug(
"READ_BLOCK_LIMITS");
816 if (xferp->
cmd[1] != 0x00)
817 fatal(
"WARNING: READ_BLOCK_LIMITS with cmd[1]=" 818 "0x%02x not yet implemented\n", (
int)xferp->
cmd[1]);
830 int max_limit = 32768;
833 xferp->
data_in[1] = (max_limit >> 16) & 255;
834 xferp->
data_in[2] = (max_limit >> 8) & 255;
835 xferp->
data_in[3] = max_limit & 255;
836 xferp->
data_in[4] = (min_limit >> 8) & 255;
837 xferp->
data_in[5] = min_limit & 255;
840 diskimage__return_default_status_and_message(xferp);
847 if ((xferp->
cmd[1] & 0xe0) != 0x00)
848 fatal(
"WARNING: REWIND with cmd[1]=0x%02x not yet " 849 "implemented\n", (
int)xferp->
cmd[1]);
858 fprintf(stderr,
"[ diskimage: could not (re)open " 859 "'%s' ]\n", d->
fname);
867 diskimage__return_default_status_and_message(xferp);
874 if ((xferp->
cmd[1] & 0xe0) != 0x00)
875 fatal(
"WARNING: SPACE with cmd[1]=0x%02x not yet " 876 "implemented\n", (
int)xferp->
cmd[1]);
883 debug(
"[ SPACE: buf[] = %02x %02x %02x %02x %02x %02x ]\n",
891 switch (xferp->
cmd[1] & 7) {
894 int diff = (xferp->
cmd[2] << 16) +
895 (xferp->
cmd[3] << 8) + xferp->
cmd[4];
898 if (diff & (1 << 23))
899 diff = - (16777216 - diff);
911 diskimage__switch_tape(d);
915 fatal(
"[ diskimage.c: unimplemented SPACE type %i ]\n",
919 diskimage__return_default_status_and_message(xferp);
935 debug(
"CDROM_READ_SUBCHANNEL/READ_CD_CAPACITY, cmd[1]=0x%02x",
948 xferp->
data_in[0] = (size >> 24) & 255;
949 xferp->
data_in[1] = (size >> 16) & 255;
950 xferp->
data_in[2] = (size >> 8) & 255;
951 xferp->
data_in[3] = size & 255;
958 diskimage__return_default_status_and_message(xferp);
962 debug(
"(CDROM_READ_TOC: ");
963 debug(
"lun=%i msf=%i ",
964 xferp->
cmd[1] >> 5, (xferp->
cmd[1] >> 1) & 1);
965 debug(
"starting_track=%i ", xferp->
cmd[6]);
966 retlen = xferp->
cmd[7] * 256 + xferp->
cmd[8];
967 debug(
"allocation_len=%i)\n", retlen);
986 diskimage__return_default_status_and_message(xferp);
991 debug(
"CDROM_READ_DISCINFO, cmd[1]=0x%02x", xferp->
cmd[1]);
1011 for (
size_t j=16; j<=23; j++)
1014 diskimage__return_default_status_and_message(xferp);
1019 debug(
"CDROM_READ_TRACKINFO");
1046 for(
size_t j=8; j<=23; j++)
1050 xferp->
data_in[24] = (size >> 24) & 0xff;
1051 xferp->
data_in[25] = (size >> 16) & 0xff;
1052 xferp->
data_in[26] = (size >> 8) & 0xff;
1053 xferp->
data_in[27] = size & 0xff;
1056 for (
size_t k=28; k<=35; k++)
1059 diskimage__return_default_status_and_message(xferp);
1063 debug(
"[ SCSI MODE_SELECT: ");
1074 debug(
"data_out == NULL, wanting %i bytes ]\n",
1079 debug(
"data_out!=NULL (OK), ");
1093 debug(
"[ setting logical_block_size to %i ]\n",
1097 fatal(
"[ unknown MODE_SELECT: cmd =");
1098 for (j=0; j<(ssize_t)xferp->
cmd_len; j++)
1100 fatal(
", data_out =");
1107 diskimage__return_default_status_and_message(xferp);
1111 debug(
"[ SCSI 0x%02x Prevent/allow medium removal: " 1112 "TODO ]\n", xferp->
cmd[0]);
1114 diskimage__return_default_status_and_message(xferp);
1118 fatal(
"[ SCSI 0x%02x (len %i), TODO: ", xferp->
cmd[0],
1120 for (i=0; i<(ssize_t)xferp->
cmd_len; i++)
1133 fatal(
"WEIRD LEN?\n");
1136 retlen = xferp->
cmd[8] * 256 + xferp->
cmd[9];
1143 diskimage__return_default_status_and_message(xferp);
1148 fatal(
"[ UNIMPLEMENTED SCSI command 0x%02x, disk id=%i ]\n",
#define SCSICDROM_READ_DISCINFO
void fatal(const char *fmt,...)
int diskimage_getname(struct machine *machine, int id, int type, char *buf, size_t bufsize)
#define SCSICMD_MODE_SENSE
#define SCSICMD_START_STOP_UNIT
#define SCSICMD_SYNCHRONIZE_CACHE
#define SCSICMD_MODE_SENSE10
#define SCSICMD_TEST_UNIT_READY
void f(int s, int func, int only_name)
#define SCSIBLOCKCMD_READ_CAPACITY
#define SCSICDROM_READ_SUBCHANNEL
struct scsi_transfer * next_free
struct diskimage * first_diskimage
#define SCSICMD_REQUEST_SENSE
struct scsi_transfer * scsi_transfer_alloc(void)
#define SCSICDROM_READ_TRACKINFO
void scsi_transfer_free(struct scsi_transfer *p)
int diskimage__internal_access(struct diskimage *d, int writeflag, off_t offset, unsigned char *buf, size_t len)
#define ENTER_SINGLE_STEPPING
#define SCSICMD_MODE_SELECT
void scsi_transfer_allocbuf(size_t *lenp, unsigned char **pp, size_t want_len, int clearflag)
#define SCSICDROM_READ_TOC
void diskimage_recalc_size(struct diskimage *d)
#define SCSICMD_READ_BLOCK_LIMITS
addr & if(addr >=0x24 &&page !=NULL)
int diskimage_scsicommand(struct cpu *cpu, int id, int type, struct scsi_transfer *xferp)
#define SCSICMD_PREVENT_ALLOW_REMOVE