Trying to find out whether READ CAPACITY on CD media includes 2 TAO end blocks

This commit is contained in:
Thomas Schmitt 2016-03-08 07:33:45 +00:00
parent a87ff5291b
commit 24ef645552
6 changed files with 86 additions and 7 deletions

View File

@ -1 +1 @@
#define Cdrskin_timestamP "2016.02.18.114857"
#define Cdrskin_timestamP "2016.03.08.073402"

View File

@ -419,6 +419,7 @@ int burn_drive_grab_stdio(struct burn_drive *d, int flag)
/* despite its name : last valid address, not size */
d->media_read_capacity =
read_size / 2048 - !(read_size % 2048);
d->mr_capacity_trusted = 1;
if ((stat_ret == -1 || is_rdwr) && d->devname[0]) {
ret = burn_os_stdio_capacity(d->devname, 0, &size);
if (ret > 0)
@ -1782,10 +1783,12 @@ int burn_drive_grab_dummy(struct burn_drive_info *drive_infos[], char *fname)
strcpy(d->current_profile_text,"stdio file");
d->current_is_cd_profile = 0;
d->current_is_supported_profile = 1;
if (read_size >= 0)
if (read_size >= 0) {
/* despite its name : last valid address, not size */
d->media_read_capacity =
read_size / 2048 - !(read_size % 2048);
d->mr_capacity_trusted = 1;
}
burn_drive_set_media_capacity_remaining(d, size);
} else
d->current_profile = 0; /* Drives return this if empty */
@ -3322,7 +3325,8 @@ int burn_drive_set_media_capacity_remaining(struct burn_drive *d, off_t value)
/* ts A81215 : API */
int burn_get_read_capacity(struct burn_drive *d, int *capacity, int flag)
{
*capacity = d->media_read_capacity + 1;
*capacity = d->media_read_capacity +
(d->media_read_capacity != 0x7fffffff);
return (d->media_read_capacity != 0x7fffffff);
}

View File

@ -1,7 +1,7 @@
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
Copyright (c) 2006 - 2015 Thomas Schmitt <scdbackup@gmx.net>
Copyright (c) 2006 - 2016 Thomas Schmitt <scdbackup@gmx.net>
Provided under GPL version 2 or later.
This is the official API definition of libburn.
@ -3935,7 +3935,7 @@ int burn_random_access_write(struct burn_drive *d, off_t byte_address,
/* ts A81215 */
/** Inquire the maximum amount of readable data.
It is supposed that all LBAs in the range from 0 to media_read_acpacity-1
It is supposed that all LBAs in the range from 0 to capacity - 1
can be read via burn_read_data() although some of them may never have been
recorded. If tracks are recognizable then it is better to only read
LBAs which are part of some track.

View File

@ -1485,6 +1485,20 @@ ex:;
}
static int mmc_register_leadout(struct burn_drive *d, int *highest_leadout,
int toc_idx)
{
int lba;
lba = burn_msf_to_lba(d->toc_entry[toc_idx].pmin,
d->toc_entry[toc_idx].psec,
d->toc_entry[toc_idx].pframe);
if (lba > *highest_leadout)
*highest_leadout = lba;
return 1;
}
static int mmc_read_toc_al(struct burn_drive *d, int *alloc_len)
{
/* read full toc, all sessions, in m/s/f form, 4k buffer */
@ -1494,7 +1508,7 @@ static int mmc_read_toc_al(struct burn_drive *d, int *alloc_len)
struct buffer *buf = NULL;
struct command *c = NULL;
int dlen;
int i, old_alloc_len, t_idx, ret;
int i, old_alloc_len, t_idx, ret, highest_leadout = -1;
unsigned char *tdata;
char *msg = NULL;
@ -1652,9 +1666,12 @@ static int mmc_read_toc_al(struct burn_drive *d, int *alloc_len)
d->disc->session[tdata[0] - 1]->firsttrack = tdata[8];
if (tdata[3] == 0xA1)
d->disc->session[tdata[0] - 1]->lasttrack = tdata[8];
if (tdata[3] == 0xA2)
if (tdata[3] == 0xA2) {
d->disc->session[tdata[0] - 1]->leadout_entry =
&d->toc_entry[i];
/* ts B60305 */
mmc_register_leadout(d, &highest_leadout, i);
}
}
/* ts A70131 : was (d->status != BURN_DISC_BLANK) */
@ -1701,6 +1718,23 @@ static int mmc_read_toc_al(struct burn_drive *d, int *alloc_len)
/* A80808 */
burn_disc_cd_toc_extensions(d, 0);
/* ts B60304
Most drives report READ CAPACITY of TAO CD too high by 2 blocks.
TOC format 2 always reports 2 blocks more than are readable.
So here it is possible to check and mark as trusted.
*/
if (highest_leadout > 0 && d->media_read_capacity != 0x7fffffff &&
!d->mr_capacity_trusted) {
if (highest_leadout - 3 == d->media_read_capacity) {
d->mr_capacity_trusted = 1;
libdax_msgs_submit(libdax_messenger, d->global_index,
0x00000002, LIBDAX_MSGS_SEV_DEBUG,
LIBDAX_MSGS_PRIO_ZERO,
"Trusting READ CAPACITY by 2 extra blocks in TOC. Assuming TAO.",
0, 0);
}
}
ret = 1;
ex:;
BURN_FREE_MEM(msg);
@ -1909,6 +1943,7 @@ static int mmc_read_disc_info_al(struct burn_drive *d, int *alloc_len)
/* ts A81210 */
d->media_read_capacity = 0x7fffffff;
d->mr_capacity_trusted = -1;
/* ts A61202 */
d->toc_entries = 0;
@ -4836,6 +4871,7 @@ int mmc_read_capacity(struct burn_drive *d)
BURN_ALLOC_MEM(buf, struct buffer, 1);
BURN_ALLOC_MEM(c, struct command, 1);
d->media_read_capacity = 0x7fffffff;
d->mr_capacity_trusted = -1;
mmc_start_if_needed(d, 1);
if (mmc_function_spy(d, "mmc_read_capacity") <= 0)
{ret = 0; goto ex;}
@ -4853,6 +4889,10 @@ int mmc_read_capacity(struct burn_drive *d)
d->media_read_capacity = 0x7fffffff;
{ret = 0; goto ex;}
}
if (d->current_profile >= 0x08 && d->current_profile <= 0x0A)
d->mr_capacity_trusted = 0;
else
d->mr_capacity_trusted = 1;
ret = 1;
ex:;
BURN_FREE_MEM(c);
@ -5367,6 +5407,7 @@ int mmc_setup_drive(struct burn_drive *d)
d->media_capacity_remaining = 0;
d->media_lba_limit = 0;
d->media_read_capacity = 0x7fffffff;
d->mr_capacity_trusted = 0;
d->pessimistic_buffer_free = 0;
d->pbf_altered = 0;
d->wait_for_buffer_free = Libburn_wait_for_buffer_freE;

View File

@ -749,10 +749,23 @@ int burn_session_get_hidefirst(struct burn_session *session)
}
static void burn_track_info_high_read(unsigned char *data,
int *higest_readable)
{
int ret;
ret = mmc_four_char_to_int(data + 8) +
mmc_four_char_to_int(data + 24);
if (ret - 1> *higest_readable)
*higest_readable = ret - 1;
}
/* ts A80808 : Enhance CD toc to DVD toc */
int burn_disc_cd_toc_extensions(struct burn_drive *drive, int flag)
{
int sidx= 0, tidx= 0, ret, track_offset, alloc_len = 34;
int higest_readable = -1;
struct burn_toc_entry *entry, *prev_entry= NULL;
struct burn_disc *d;
/* ts A81126 : ticket 146 : There was a SIGSEGV in here */
@ -835,6 +848,9 @@ int burn_disc_cd_toc_extensions(struct burn_drive *drive, int flag)
((!drive->current_is_cd_profile) ||
ret < prev_entry->track_blocks - 2))
prev_entry->track_blocks = ret;
if (!drive->mr_capacity_trusted)
burn_track_info_high_read(
buf->data, &higest_readable);
}
prev_entry->extensions_valid |= 1;
}
@ -847,6 +863,19 @@ int burn_disc_cd_toc_extensions(struct burn_drive *drive, int flag)
prev_entry = entry;
}
}
if (!drive->mr_capacity_trusted) {
if (higest_readable == drive->media_read_capacity - 2) {
drive->media_read_capacity = higest_readable;
drive->mr_capacity_trusted = 1;
libdax_msgs_submit(libdax_messenger,
drive->global_index, 0x00000002,
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_ZERO,
"Corrected READ CAPACITY by READ TRACK INFORMATION. Assuming TAO.",
0, 0);
}
}
{ret = 1; goto ex;}
failure:
libdax_msgs_submit(libdax_messenger, -1, 0x0002015f,

View File

@ -369,6 +369,11 @@ struct burn_drive
0x7ffffff0 = 32 bit overflow, or unknown stdio size
*/
int media_read_capacity;
/* ts B60305 : Whether READ CAPACITY of CD is credible:
-1= no READ CAPACITY yet , 0= untrusted READ CAPACITY
1= READ CAPACITY confirmed or corrected by other commands
*/
int mr_capacity_trusted;
/* ts B10314 : Next Writeable Adress for drive_role == 5 */
int role_5_nwa;