Bug fix: Progress report with blanking and formatting could be bogus

This commit is contained in:
Thomas Schmitt 2012-01-05 11:55:22 +00:00
parent bb8aac0db3
commit 56e07dd071
4 changed files with 84 additions and 12 deletions

View File

@ -1 +1 @@
#define Cdrskin_timestamP "2012.01.04.131808" #define Cdrskin_timestamP "2012.01.05.115516"

View File

@ -1,7 +1,7 @@
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */ /* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens /* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
Copyright (c) 2006 - 2011 Thomas Schmitt <scdbackup@gmx.net> Copyright (c) 2006 - 2012 Thomas Schmitt <scdbackup@gmx.net>
Provided under GPL version 2 or later. Provided under GPL version 2 or later.
*/ */
@ -863,12 +863,34 @@ void burn_disc_erase_sync(struct burn_drive *d, int fast)
d->erase(d, fast); d->erase(d, fast);
d->busy = BURN_DRIVE_ERASING; d->busy = BURN_DRIVE_ERASING;
#ifdef Libburn_old_progress_looP
/* read the initial 0 stage */ /* read the initial 0 stage */
while (!d->test_unit_ready(d) && d->get_erase_progress(d) == 0) while (!d->test_unit_ready(d) && d->get_erase_progress(d) == 0)
sleep(1); sleep(1);
while ((d->progress.sector = d->get_erase_progress(d)) > 0 || while ((d->progress.sector = d->get_erase_progress(d)) > 0 ||
!d->test_unit_ready(d)) !d->test_unit_ready(d))
sleep(1); sleep(1);
#else /* Libburn_old_progress_looP */
while (1) {
ret = d->get_erase_progress(d);
if (ret == -2 || ret > 0)
break;
sleep(1);
}
while (1) {
ret = d->get_erase_progress(d);
if(ret == -2)
break;
if (ret >= 0)
d->progress.sector = ret;
sleep(1);
}
#endif /* ! Libburn_old_progress_looP */
d->progress.sector = 0x10000; d->progress.sector = 0x10000;
/* ts A61125 : update media state records */ /* ts A61125 : update media state records */
@ -913,6 +935,8 @@ void burn_disc_format_sync(struct burn_drive *d, off_t size, int flag)
if (ret <= 0) if (ret <= 0)
d->cancel = 1; d->cancel = 1;
#ifdef Libburn_old_progress_looP
while (!d->test_unit_ready(d) && d->get_erase_progress(d) == 0) while (!d->test_unit_ready(d) && d->get_erase_progress(d) == 0)
sleep(1); sleep(1);
while ((pseudo_sector = d->get_erase_progress(d)) > 0 || while ((pseudo_sector = d->get_erase_progress(d)) > 0 ||
@ -920,6 +944,26 @@ void burn_disc_format_sync(struct burn_drive *d, off_t size, int flag)
d->progress.sector = pseudo_sector / stages; d->progress.sector = pseudo_sector / stages;
sleep(1); sleep(1);
} }
#else /* Libburn_old_progress_looP */
while (1) {
ret = d->get_erase_progress(d);
if (ret == -2 || ret > 0)
break;
sleep(1);
}
while (1) {
pseudo_sector = d->get_erase_progress(d);
if(pseudo_sector == -2)
break;
if (pseudo_sector >= 0)
d->progress.sector = pseudo_sector / stages;
sleep(1);
}
#endif /* ! Libburn_old_progress_looP */
d->sync_cache(d); d->sync_cache(d);
if (size <= 0) if (size <= 0)

View File

@ -1,7 +1,7 @@
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */ /* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens /* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
Copyright (c) 2006 - 2011 Thomas Schmitt <scdbackup@gmx.net> Copyright (c) 2006 - 2012 Thomas Schmitt <scdbackup@gmx.net>
Provided under GPL version 2 or later. Provided under GPL version 2 or later.
*/ */
@ -102,7 +102,8 @@ int spc_decode_sense(unsigned char *sense, int senselen,
} }
int spc_test_unit_ready_r(struct burn_drive *d, int *key, int *asc, int *ascq) int spc_test_unit_ready_r(struct burn_drive *d, int *key, int *asc, int *ascq,
int *progress)
{ {
struct command *c; struct command *c;
@ -115,8 +116,13 @@ int spc_test_unit_ready_r(struct burn_drive *d, int *key, int *asc, int *ascq)
c->dir = NO_TRANSFER; c->dir = NO_TRANSFER;
d->issue_command(d, c); d->issue_command(d, c);
*key = *asc = *ascq = 0; *key = *asc = *ascq = 0;
*progress = -1;
if (c->error) { if (c->error) {
spc_decode_sense(c->sense, 0, key, asc, ascq); spc_decode_sense(c->sense, 0, key, asc, ascq);
if (c->sense[0] == 0x70 &&
((c->sense[2] & 0x0f) == 0 || (c->sense[2] & 0x0f) == 2) &&
(c->sense[15] & 0x80))
*progress = (c->sense[16] << 8) + c->sense[17];
return (key == 0); return (key == 0);
} }
return 1; return 1;
@ -125,9 +131,9 @@ int spc_test_unit_ready_r(struct burn_drive *d, int *key, int *asc, int *ascq)
int spc_test_unit_ready(struct burn_drive *d) int spc_test_unit_ready(struct burn_drive *d)
{ {
int key,asc,ascq; int key, asc, ascq, progress;
return spc_test_unit_ready_r(d, &key, &asc, &ascq); return spc_test_unit_ready_r(d, &key, &asc, &ascq, &progress);
} }
@ -141,7 +147,7 @@ int spc_wait_unit_attention(struct burn_drive *d, int max_sec, char *cmd_text,
{ {
int i, ret = 1, key = 0, asc = 0, ascq = 0, clueless_start = 0; int i, ret = 1, key = 0, asc = 0, ascq = 0, clueless_start = 0;
static double tests_per_second = 2.0; static double tests_per_second = 2.0;
int sleep_usecs, loop_limit, clueless_timeout; int sleep_usecs, loop_limit, clueless_timeout, progress;
char *msg = NULL; char *msg = NULL;
unsigned char sense[14]; unsigned char sense[14];
@ -154,7 +160,7 @@ int spc_wait_unit_attention(struct burn_drive *d, int max_sec, char *cmd_text,
usleep(sleep_usecs); usleep(sleep_usecs);
for(i = !(flag & 1); i < loop_limit; i++) { for(i = !(flag & 1); i < loop_limit; i++) {
ret = spc_test_unit_ready_r(d, &key, &asc, &ascq); ret = spc_test_unit_ready_r(d, &key, &asc, &ascq, &progress);
if (ret > 0) /* ready */ if (ret > 0) /* ready */
break; break;
if (key!=0x2 || asc!=0x4) { if (key!=0x2 || asc!=0x4) {
@ -256,17 +262,38 @@ void spc_request_sense(struct burn_drive *d, struct buffer *buf)
d->issue_command(d, c); d->issue_command(d, c);
} }
/* @return -2 = drive is ready , -1 = not ready, but no progress reported
>= 0 progress indication between 0 and 65535
*/
int spc_get_erase_progress(struct burn_drive *d) int spc_get_erase_progress(struct burn_drive *d)
{ {
struct buffer *b = NULL; struct buffer *b = NULL;
int ret; int ret, key, asc, ascq, progress;
if (mmc_function_spy(d, "get_erase_progress") <= 0) if (mmc_function_spy(d, "get_erase_progress") <= 0)
{ret = 0; goto ex;} {ret = 0; goto ex;}
/* ts B20104 :
TEST UNIT READY seems to be more reliable than REQUEST SENSE.
Nevertheless growisofs still uses the latter as fallback.
*/
ret = spc_test_unit_ready_r(d, &key, &asc, &ascq, &progress);
if (ret > 0)
{ret = -2; goto ex;}
if (progress >= 0)
{ret = progress; goto ex;}
/* Fallback to request sense */
BURN_ALLOC_MEM(b, struct buffer, 1); BURN_ALLOC_MEM(b, struct buffer, 1);
spc_request_sense(d, b); spc_request_sense(d, b);
ret = (b->data[16] << 8) | b->data[17];
/* Now checking the the preconditions as of SPC-3 4.5.2.4.4 and 4.5.3
*/
ret = -1;
if (b->data[0] == 0x70 &&
((b->data[2] & 0x0f) == 0 || (b->data[2] & 0x0f) == 2) &&
(b->data[15] & 0x80))
ret = (b->data[16] << 8) | b->data[17];
ex:; ex:;
BURN_FREE_MEM(b); BURN_FREE_MEM(b);
return ret; return ret;

View File

@ -1,7 +1,7 @@
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */ /* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens /* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
Copyright (c) 2006 - 2011 Thomas Schmitt <scdbackup@gmx.net> Copyright (c) 2006 - 2012 Thomas Schmitt <scdbackup@gmx.net>
Provided under GPL version 2 or later. Provided under GPL version 2 or later.
*/ */
@ -29,7 +29,8 @@ int spc_block_type(enum burn_block_types b);
int spc_get_erase_progress(struct burn_drive *d); int spc_get_erase_progress(struct burn_drive *d);
/* ts A70315 : test_unit_ready with result parameters */ /* ts A70315 : test_unit_ready with result parameters */
int spc_test_unit_ready_r(struct burn_drive *d, int *key, int *asc, int *ascq); int spc_test_unit_ready_r(struct burn_drive *d, int *key, int *asc, int *ascq,
int *progress);
int spc_test_unit_ready(struct burn_drive *d); int spc_test_unit_ready(struct burn_drive *d);