Made use of Immed bit with 1Bh START STOP UNIT and 35h SYNCHRONIZE CACHE
This commit is contained in:
parent
bbdc3fe840
commit
1ec9176f9c
@ -1 +1 @@
|
||||
#define Cdrskin_timestamP "2007.09.18.130344"
|
||||
#define Cdrskin_timestamP "2007.09.18.200343"
|
||||
|
@ -430,6 +430,9 @@ Range "scdbackup" : 0x00020000 to 0x0002ffff
|
||||
0x0002014a (SORRY,HIGH) = Cannot read desired amount of data
|
||||
0x0002014b (SORRY,HIGH) = Drive is already registered resp. scanned
|
||||
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:
|
||||
|
@ -444,9 +444,12 @@ void mmc_close(struct burn_drive *d, int session, int track)
|
||||
d->issue_command(d, &c);
|
||||
|
||||
/* ts A70918 : Immed : wait for drive to complete command */
|
||||
usleep(1000000); /* (in format() there was a race condition) */
|
||||
while (!d->test_unit_ready(d))
|
||||
usleep(100000);
|
||||
if (c.error) {
|
||||
d->cancel = 1;
|
||||
return;
|
||||
}
|
||||
if (spc_wait_unit_attention(d, 3600, "CLOSE TRACK SESSION", 0) <= 0)
|
||||
d->cancel = 1;
|
||||
}
|
||||
|
||||
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.retry = 1;
|
||||
|
||||
c.opcode[1] |= 2; /* ts A70918 : Immed */
|
||||
|
||||
c.page = NULL;
|
||||
c.dir = NO_TRANSFER;
|
||||
|
||||
@ -2294,6 +2300,14 @@ void mmc_sync_cache(struct burn_drive *d)
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -36,9 +36,16 @@ void sbc_load(struct burn_drive *d)
|
||||
c.page = NULL;
|
||||
*/
|
||||
c.retry = 1;
|
||||
|
||||
c.opcode[1] |= 1; /* ts A70918 : Immed */
|
||||
|
||||
c.dir = NO_TRANSFER;
|
||||
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)
|
||||
@ -54,9 +61,16 @@ void sbc_eject(struct burn_drive *d)
|
||||
c.oplen = sizeof(SBC_UNLOAD);
|
||||
c.page = NULL;
|
||||
*/
|
||||
|
||||
c.opcode[1] |= 1; /* ts A70918 : Immed */
|
||||
|
||||
c.page = NULL;
|
||||
c.dir = NO_TRANSFER;
|
||||
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 ? */
|
||||
@ -74,9 +88,14 @@ int sbc_start_unit(struct burn_drive *d)
|
||||
c.page = NULL;
|
||||
*/
|
||||
c.retry = 1;
|
||||
|
||||
c.opcode[1] |= 1; /* ts A70918 : Immed */
|
||||
|
||||
c.dir = NO_TRANSFER;
|
||||
d->issue_command(d, &c);
|
||||
return (c.error==0);
|
||||
if (c.error)
|
||||
return 0;
|
||||
return spc_wait_unit_attention(d, 1800, "START UNIT", 0);
|
||||
}
|
||||
|
||||
|
||||
|
@ -98,19 +98,52 @@ int spc_test_unit_ready(struct burn_drive *d)
|
||||
|
||||
|
||||
/* 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 */
|
||||
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;
|
||||
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);
|
||||
if(ret > 0 || key!=0x2 || asc!=0x4) /* ready or error */
|
||||
if(ret > 0) /* ready */
|
||||
break;
|
||||
if(key!=0x2 || asc!=0x4) {
|
||||
if (key == 0x2 && asc == 0x3A) {
|
||||
ret = 1; /* medium not present = ok */
|
||||
break;
|
||||
usleep(1000000);
|
||||
}
|
||||
if (i < max_sec)
|
||||
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);
|
||||
}
|
||||
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);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -28,7 +28,8 @@ int spc_test_unit_ready(struct burn_drive *d);
|
||||
|
||||
/* ts A70315 */
|
||||
/** 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()
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user