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);
218 int retlen, i, q, result;
226 fatal(
"[ diskimage_scsicommand(): machine == NULL ]\n");
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);
700 ofs = ((xferp->
cmd[1] & 0x1f) << 16) +
701 (xferp->
cmd[2] << 8) + xferp->
cmd[3];
702 retlen = xferp->
cmd[4];
715 ofs = ((uint64_t)xferp->
cmd[2] << 24) +
716 (xferp->
cmd[3] << 16) + (xferp->
cmd[4] << 8) +
718 retlen = (xferp->
cmd[7] << 8) + xferp->
cmd[8];
725 debug(
", data_out == NULL, wanting %i bytes, \n\n",
731 debug(
", data_out != NULL, OK :-)");
733 debug(
"WRITE ofs=%i size=%i offset=%i\n", (
int)ofs,
741 diskimage__return_default_status_and_message(xferp);
745 debug(
"SYNCHRONIZE_CACHE");
756 diskimage__return_default_status_and_message(xferp);
760 debug(
"START_STOP_UNIT");
765 for (i=0; i<(ssize_t)xferp->
cmd_len; i++)
770 diskimage__return_default_status_and_message(xferp);
774 debug(
"REQUEST_SENSE");
776 retlen = xferp->
cmd[4];
779 if (xferp->
cmd[1] != 0x00)
780 fatal(
"WARNING: REQUEST_SENSE with cmd[1]=0x%02x not"
781 " yet implemented\n", (
int)xferp->
cmd[1]);
784 fatal(
"WARNING: SCSI request sense len=%i, <18!\n",
793 xferp->
data_in[0] = 0x80 + 0x70;
802 printf(
" XXX(!) \n");
805 xferp->
data_in[7] = retlen - 7;
808 diskimage__return_default_status_and_message(xferp);
812 debug(
"READ_BLOCK_LIMITS");
817 if (xferp->
cmd[1] != 0x00)
818 fatal(
"WARNING: READ_BLOCK_LIMITS with cmd[1]="
819 "0x%02x not yet implemented\n", (
int)xferp->
cmd[1]);
831 int max_limit = 32768;
834 xferp->
data_in[1] = (max_limit >> 16) & 255;
835 xferp->
data_in[2] = (max_limit >> 8) & 255;
836 xferp->
data_in[3] = max_limit & 255;
837 xferp->
data_in[4] = (min_limit >> 8) & 255;
838 xferp->
data_in[5] = min_limit & 255;
841 diskimage__return_default_status_and_message(xferp);
848 if ((xferp->
cmd[1] & 0xe0) != 0x00)
849 fatal(
"WARNING: REWIND with cmd[1]=0x%02x not yet "
850 "implemented\n", (
int)xferp->
cmd[1]);
859 fprintf(stderr,
"[ diskimage: could not (re)open "
860 "'%s' ]\n", d->
fname);
868 diskimage__return_default_status_and_message(xferp);
875 if ((xferp->
cmd[1] & 0xe0) != 0x00)
876 fatal(
"WARNING: SPACE with cmd[1]=0x%02x not yet "
877 "implemented\n", (
int)xferp->
cmd[1]);
884 debug(
"[ SPACE: buf[] = %02x %02x %02x %02x %02x %02x ]\n",
892 switch (xferp->
cmd[1] & 7) {
895 int diff = (xferp->
cmd[2] << 16) +
896 (xferp->
cmd[3] << 8) + xferp->
cmd[4];
899 if (diff & (1 << 23))
900 diff = - (16777216 - diff);
912 diskimage__switch_tape(d);
916 fatal(
"[ diskimage.c: unimplemented SPACE type %i ]\n",
920 diskimage__return_default_status_and_message(xferp);
936 debug(
"CDROM_READ_SUBCHANNEL/READ_CD_CAPACITY, cmd[1]=0x%02x",
949 xferp->
data_in[0] = (size >> 24) & 255;
950 xferp->
data_in[1] = (size >> 16) & 255;
951 xferp->
data_in[2] = (size >> 8) & 255;
952 xferp->
data_in[3] = size & 255;
959 diskimage__return_default_status_and_message(xferp);
963 debug(
"(CDROM_READ_TOC: ");
964 debug(
"lun=%i msf=%i ",
965 xferp->
cmd[1] >> 5, (xferp->
cmd[1] >> 1) & 1);
966 debug(
"starting_track=%i ", xferp->
cmd[6]);
967 retlen = xferp->
cmd[7] * 256 + xferp->
cmd[8];
968 debug(
"allocation_len=%i)\n", retlen);
987 diskimage__return_default_status_and_message(xferp);
992 debug(
"CDROM_READ_DISCINFO, cmd[1]=0x%02x", xferp->
cmd[1]);
1012 for (
size_t j=16; j<=23; j++)
1015 diskimage__return_default_status_and_message(xferp);
1020 debug(
"CDROM_READ_TRACKINFO");
1047 for(
size_t j=8; j<=23; j++)
1051 xferp->
data_in[24] = (size >> 24) & 0xff;
1052 xferp->
data_in[25] = (size >> 16) & 0xff;
1053 xferp->
data_in[26] = (size >> 8) & 0xff;
1054 xferp->
data_in[27] = size & 0xff;
1057 for (
size_t k=28; k<=35; k++)
1060 diskimage__return_default_status_and_message(xferp);
1064 debug(
"[ SCSI MODE_SELECT: ");
1075 debug(
"data_out == NULL, wanting %i bytes ]\n",
1080 debug(
"data_out!=NULL (OK), ");
1094 debug(
"[ setting logical_block_size to %i ]\n",
1098 fatal(
"[ unknown MODE_SELECT: cmd =");
1099 for (j=0; j<(ssize_t)xferp->
cmd_len; j++)
1101 fatal(
", data_out =");
1108 diskimage__return_default_status_and_message(xferp);
1112 debug(
"[ SCSI 0x%02x Prevent/allow medium removal: "
1113 "TODO ]\n", xferp->
cmd[0]);
1115 diskimage__return_default_status_and_message(xferp);
1119 fatal(
"[ SCSI 0x%02x (len %i), TODO: ", xferp->
cmd[0],
1121 for (i=0; i<(ssize_t)xferp->
cmd_len; i++)
1134 fatal(
"WEIRD LEN?\n");
1137 retlen = xferp->
cmd[8] * 256 + xferp->
cmd[9];
1144 diskimage__return_default_status_and_message(xferp);
1149 debug(
"[ UNIMPLEMENTED SCSI command 0x%02x, disk id=%i",