Made use of Immed bit with 1Bh START STOP UNIT and 35h SYNCHRONIZE CACHE

This commit is contained in:
Thomas Schmitt 2007-09-18 20:03:20 +00:00
parent bbdc3fe840
commit 1ec9176f9c
6 changed files with 82 additions and 12 deletions

View File

@ -1 +1 @@
#define Cdrskin_timestamP "2007.09.18.130344" #define Cdrskin_timestamP "2007.09.18.200343"

View File

@ -430,6 +430,9 @@ Range "scdbackup" : 0x00020000 to 0x0002ffff
0x0002014a (SORRY,HIGH) = Cannot read desired amount of data 0x0002014a (SORRY,HIGH) = Cannot read desired amount of data
0x0002014b (SORRY,HIGH) = Drive is already registered resp. scanned 0x0002014b (SORRY,HIGH) = Drive is already registered resp. scanned
0x0002014c (FATAL,HIGH) = Emulated drive caught in SCSI function 0x0002014c (FATAL,HIGH) = Emulated drive caught in SCSI function
0x0002014d (SORRY,HIGH) = Asynchromous SCSI error
0x0002014f (SORRY,HIGH) = Timeout with asynchromous SCSI command
0x00020150 (DEBUG,LOW) = Reporting asynchronous waiting time
libdax_audioxtr: libdax_audioxtr:

View File

@ -444,9 +444,12 @@ void mmc_close(struct burn_drive *d, int session, int track)
d->issue_command(d, &c); d->issue_command(d, &c);
/* ts A70918 : Immed : wait for drive to complete command */ /* ts A70918 : Immed : wait for drive to complete command */
usleep(1000000); /* (in format() there was a race condition) */ if (c.error) {
while (!d->test_unit_ready(d)) d->cancel = 1;
usleep(100000); return;
}
if (spc_wait_unit_attention(d, 3600, "CLOSE TRACK SESSION", 0) <= 0)
d->cancel = 1;
} }
void mmc_get_event(struct burn_drive *d) void mmc_get_event(struct burn_drive *d)
@ -2273,6 +2276,9 @@ void mmc_sync_cache(struct burn_drive *d)
c.oplen = sizeof(MMC_SYNC_CACHE); c.oplen = sizeof(MMC_SYNC_CACHE);
*/ */
c.retry = 1; c.retry = 1;
c.opcode[1] |= 2; /* ts A70918 : Immed */
c.page = NULL; c.page = NULL;
c.dir = NO_TRANSFER; c.dir = NO_TRANSFER;
@ -2294,6 +2300,14 @@ void mmc_sync_cache(struct burn_drive *d)
} }
d->issue_command(d, &c); d->issue_command(d, &c);
/* ts A70918 */
if (c.error) {
d->cancel = 1;
return;
}
if (spc_wait_unit_attention(d, 3600, "SYNCHRONIZE CACHE", 0) <= 0)
d->cancel = 1;
} }

View File

@ -36,9 +36,16 @@ void sbc_load(struct burn_drive *d)
c.page = NULL; c.page = NULL;
*/ */
c.retry = 1; c.retry = 1;
c.opcode[1] |= 1; /* ts A70918 : Immed */
c.dir = NO_TRANSFER; c.dir = NO_TRANSFER;
d->issue_command(d, &c); d->issue_command(d, &c);
spc_wait_unit_attention(d, 60); if (c.error)
return;
/* 5 minutes for loading. If this does not suffice then other commands
shall fail righteously. */
spc_wait_unit_attention(d, 300, "START UNIT (+ LOAD)", 0);
} }
void sbc_eject(struct burn_drive *d) void sbc_eject(struct burn_drive *d)
@ -54,9 +61,16 @@ void sbc_eject(struct burn_drive *d)
c.oplen = sizeof(SBC_UNLOAD); c.oplen = sizeof(SBC_UNLOAD);
c.page = NULL; c.page = NULL;
*/ */
c.opcode[1] |= 1; /* ts A70918 : Immed */
c.page = NULL; c.page = NULL;
c.dir = NO_TRANSFER; c.dir = NO_TRANSFER;
d->issue_command(d, &c); d->issue_command(d, &c);
if (c.error)
return;
/* Wait long. A late eject could surprise or hurt user. */
spc_wait_unit_attention(d, 1800, "STOP UNIT (+ EJECT)", 0);
} }
/* ts A61118 : is it necessary to tell the drive to get ready for use ? */ /* ts A61118 : is it necessary to tell the drive to get ready for use ? */
@ -74,9 +88,14 @@ int sbc_start_unit(struct burn_drive *d)
c.page = NULL; c.page = NULL;
*/ */
c.retry = 1; c.retry = 1;
c.opcode[1] |= 1; /* ts A70918 : Immed */
c.dir = NO_TRANSFER; c.dir = NO_TRANSFER;
d->issue_command(d, &c); d->issue_command(d, &c);
return (c.error==0); if (c.error)
return 0;
return spc_wait_unit_attention(d, 1800, "START UNIT", 0);
} }

View File

@ -98,19 +98,52 @@ int spc_test_unit_ready(struct burn_drive *d)
/* ts A70315 */ /* ts A70315 */
/** @param flag bit0=do not wait 0.1 seconds before first test unit ready */
/** Wait until the drive state becomes clear or until max_usec elapsed */ /** Wait until the drive state becomes clear or until max_usec elapsed */
int spc_wait_unit_attention(struct burn_drive *d, int max_sec) int spc_wait_unit_attention(struct burn_drive *d, int max_sec, char *cmd_text,
int flag)
{ {
int i, ret, key, asc, ascq; int i, ret, key, asc, ascq;
char msg[160];
for(i=0; i < max_sec; i++) { if (!(flag & 1))
usleep(100000);
for(i = !(flag & 1); i < max_sec * 10; i++) {
ret = spc_test_unit_ready_r(d, &key, &asc, &ascq); ret = spc_test_unit_ready_r(d, &key, &asc, &ascq);
if(ret > 0 || key!=0x2 || asc!=0x4) /* ready or error */ if(ret > 0) /* ready */
break; break;
usleep(1000000); if(key!=0x2 || asc!=0x4) {
if (key == 0x2 && asc == 0x3A) {
ret = 1; /* medium not present = ok */
break;
}
if (key == 0x6 && asc == 0x28 && ascq == 0x00)
continue; /* media change notice = try again */
sprintf(msg,
"Asynchromous SCSI error on %s: key=%X asc=%2.2Xh ascq=%2.2Xh",
cmd_text, (unsigned) key, (unsigned) asc,
(unsigned) ascq);
libdax_msgs_submit(libdax_messenger, d->global_index,
0x0002014d,
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
msg, 0, 0);
d->cancel = 1;
break;
}
usleep(100000);
} }
if (i < max_sec) sprintf(msg, "Async %s %s after %d.%d seconds",
cmd_text, (ret > 0 ? "succeeded" : "failed"), i / 10, i % 10);
libdax_msgs_submit(libdax_messenger, d->global_index, 0x00020150,
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_LOW, msg, 0, 0);
if (i < max_sec * 10)
return (ret > 0); return (ret > 0);
sprintf(msg, "Timeout (%d s) with asynchronous SCSI command %s\n",
max_sec, cmd_text);
libdax_msgs_submit(libdax_messenger, d->global_index, 0x0002014f,
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH, msg, 0, 0);
return 0; return 0;
} }

View File

@ -28,7 +28,8 @@ int spc_test_unit_ready(struct burn_drive *d);
/* ts A70315 */ /* ts A70315 */
/** Wait until the drive state becomes clear in or until max_sec elapsed */ /** Wait until the drive state becomes clear in or until max_sec elapsed */
int spc_wait_unit_attention(struct burn_drive *d, int max_sec); int spc_wait_unit_attention(struct burn_drive *d, int max_sec, char *cmd_text,
int flag);
/* ts A61021 : the spc specific part of sg.c:enumerate_common() /* ts A61021 : the spc specific part of sg.c:enumerate_common()
*/ */