Enabled reading of TOC from ROM drives (direly needed for xorriso)
This commit is contained in:
parent
8860c92a4c
commit
762ac54aa7
@ -1 +1 @@
|
||||
#define Cdrskin_timestamP "2007.11.26.154817"
|
||||
#define Cdrskin_timestamP "2007.11.29.185342"
|
||||
|
@ -201,7 +201,9 @@ int burn_drive_inquire_media(struct burn_drive *d)
|
||||
|
||||
/* ts A61020 : d->status was set to BURN_DISC_BLANK as pure guess */
|
||||
|
||||
if (d->mdata->cdr_write || d->mdata->cdrw_write ||
|
||||
/* ts A71128 : run read_disc_info() for any recognizeable profile */
|
||||
if (d->current_profile > 0 ||
|
||||
d->mdata->cdr_write || d->mdata->cdrw_write ||
|
||||
d->mdata->dvdr_write || d->mdata->dvdram_write) {
|
||||
|
||||
#define Libburn_knows_correct_state_after_loaD 1
|
||||
|
@ -441,7 +441,7 @@ Range "scdbackup" : 0x00020000 to 0x0002ffff
|
||||
0x00020156 (SORRY,HIGH) = Desired fifo buffer too small
|
||||
0x00020157 (FATAL,HIGH) = burn_source is not a fifo object
|
||||
0x00020158 (DEBUG,LOW) = Reporting thread disposal precautions
|
||||
|
||||
0x00020159 (DEBUG,HIGH) = TOC Format 0 returns inconsistent data
|
||||
|
||||
libdax_audioxtr:
|
||||
0x00020200 (SORRY,HIGH) = Cannot open audio source file
|
||||
|
@ -116,6 +116,7 @@ extern struct libdax_msgs *libdax_messenger;
|
||||
static unsigned char MMC_GET_MSINFO[] =
|
||||
{ 0x43, 0, 1, 0, 0, 0, 0, 16, 0, 0 };
|
||||
static unsigned char MMC_GET_TOC[] = { 0x43, 2, 2, 0, 0, 0, 0, 16, 0, 0 };
|
||||
static unsigned char MMC_GET_TOC_FMT0[] = { 0x43, 0, 0, 0, 0, 0, 0, 16, 0, 0 };
|
||||
static unsigned char MMC_GET_ATIP[] = { 0x43, 2, 4, 0, 0, 0, 0, 16, 0, 0 };
|
||||
static unsigned char MMC_GET_DISC_INFO[] =
|
||||
{ 0x51, 0, 0, 0, 0, 0, 0, 16, 0, 0 };
|
||||
@ -797,6 +798,153 @@ int mmc_fake_toc_entry(struct burn_toc_entry *entry, int session_number,
|
||||
}
|
||||
|
||||
|
||||
/* ts A71128 : for DVD-ROM drives which offer no reliable track information */
|
||||
static int mmc_read_toc_fmt0_al(struct burn_drive *d, int *alloc_len)
|
||||
{
|
||||
struct burn_track *track;
|
||||
struct burn_session *session;
|
||||
struct burn_toc_entry *entry;
|
||||
struct buffer buf;
|
||||
struct command c;
|
||||
int dlen, i, old_alloc_len, session_number, prev_session = -1;
|
||||
int lba, size;
|
||||
unsigned char *tdata, size_data[4], start_data[4];
|
||||
|
||||
if (*alloc_len < 4)
|
||||
return 0;
|
||||
|
||||
scsi_init_command(&c, MMC_GET_TOC_FMT0, sizeof(MMC_GET_TOC_FMT0));
|
||||
c.dxfer_len = *alloc_len;
|
||||
c.opcode[7] = (c.dxfer_len >> 8) & 0xff;
|
||||
c.opcode[8] = c.dxfer_len & 0xff;
|
||||
c.retry = 1;
|
||||
c.page = &buf;
|
||||
c.page->bytes = 0;
|
||||
c.page->sectors = 0;
|
||||
c.dir = FROM_DRIVE;
|
||||
d->issue_command(d, &c);
|
||||
|
||||
if (c.error) {
|
||||
err_ex:;
|
||||
libdax_msgs_submit(libdax_messenger, d->global_index,
|
||||
0x0002010d,
|
||||
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH,
|
||||
"Could not inquire TOC", 0,0);
|
||||
d->status = BURN_DISC_UNSUITABLE;
|
||||
d->toc_entries = 0;
|
||||
/* Prefering memory leaks over fandangos */
|
||||
d->toc_entry = calloc(1, sizeof(struct burn_toc_entry));
|
||||
return 0;
|
||||
}
|
||||
dlen = c.page->data[0] * 256 + c.page->data[1];
|
||||
old_alloc_len = *alloc_len;
|
||||
*alloc_len = dlen + 2;
|
||||
if (old_alloc_len < 12)
|
||||
return 1;
|
||||
if (dlen + 2 > old_alloc_len)
|
||||
dlen = old_alloc_len - 2;
|
||||
d->complete_sessions = 1 + c.page->data[3] - c.page->data[2];
|
||||
d->last_track_no = d->complete_sessions;
|
||||
if (dlen - 2 < (d->last_track_no + 1) * 8) {
|
||||
libdax_msgs_submit(libdax_messenger, d->global_index,
|
||||
0x00020159,
|
||||
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH,
|
||||
"TOC Format 0 returns inconsistent data", 0,0);
|
||||
goto err_ex;
|
||||
}
|
||||
|
||||
d->toc_entries = d->last_track_no + d->complete_sessions;
|
||||
if (d->toc_entries < 1)
|
||||
return 0;
|
||||
d->toc_entry = calloc(d->toc_entries, sizeof(struct burn_toc_entry));
|
||||
if(d->toc_entry == NULL)
|
||||
return 0;
|
||||
|
||||
d->disc = burn_disc_create();
|
||||
if (d->disc == NULL)
|
||||
return 0;
|
||||
for (i = 0; i < d->complete_sessions; i++) {
|
||||
session = burn_session_create();
|
||||
if (session == NULL)
|
||||
return 0;
|
||||
burn_disc_add_session(d->disc, session, BURN_POS_END);
|
||||
burn_session_free(session);
|
||||
}
|
||||
|
||||
|
||||
for (i = 0; i < d->last_track_no; i++) {
|
||||
tdata = c.page->data + 4 + i * 8;
|
||||
session_number = i + 1;
|
||||
if (session_number != prev_session && prev_session > 0) {
|
||||
/* leadout entry previous session */
|
||||
entry = &(d->toc_entry[(i - 1) + prev_session]);
|
||||
lba = mmc_four_char_to_int(start_data) +
|
||||
mmc_four_char_to_int(size_data);
|
||||
mmc_int_to_four_char(start_data, lba);
|
||||
mmc_int_to_four_char(size_data, 0);
|
||||
mmc_fake_toc_entry(entry, prev_session, 0xA2,
|
||||
size_data, start_data);
|
||||
entry->min= entry->sec= entry->frame= 0;
|
||||
d->disc->session[prev_session - 1]->leadout_entry =
|
||||
entry;
|
||||
}
|
||||
|
||||
/* ??? >>> d->media_capacity_remaining , d->media_lba_limit
|
||||
as of mmc_fake_toc()
|
||||
*/
|
||||
|
||||
entry = &(d->toc_entry[i + session_number - 1]);
|
||||
track = burn_track_create();
|
||||
if (track == NULL)
|
||||
return -1;
|
||||
burn_session_add_track(
|
||||
d->disc->session[session_number - 1],
|
||||
track, BURN_POS_END);
|
||||
track->entry = entry;
|
||||
burn_track_free(track);
|
||||
|
||||
memcpy(start_data, tdata + 4, 4);
|
||||
/* size_data are estimated from next track start */
|
||||
memcpy(size_data, tdata + 8 + 4, 4);
|
||||
size = mmc_four_char_to_int(size_data) -
|
||||
mmc_four_char_to_int(start_data);
|
||||
mmc_int_to_four_char(size_data, size);
|
||||
mmc_fake_toc_entry(entry, session_number, i + 1,
|
||||
size_data, start_data);
|
||||
if (prev_session != session_number)
|
||||
d->disc->session[session_number - 1]->firsttrack = i+1;
|
||||
d->disc->session[session_number - 1]->lasttrack = i+1;
|
||||
prev_session = session_number;
|
||||
}
|
||||
if (prev_session > 0 && prev_session <= d->disc->sessions) {
|
||||
/* leadout entry of last session of closed disc */
|
||||
tdata = c.page->data + 4 + d->last_track_no * 8;
|
||||
entry = &(d->toc_entry[(d->last_track_no - 1) + prev_session]);
|
||||
memcpy(start_data, tdata + 4, 4);
|
||||
mmc_int_to_four_char(size_data, 0);
|
||||
mmc_fake_toc_entry(entry, prev_session, 0xA2,
|
||||
size_data, start_data);
|
||||
entry->min= entry->sec= entry->frame= 0;
|
||||
d->disc->session[prev_session - 1]->leadout_entry = entry;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* ts A71128 : for DVD-ROM drives which offer no reliable track information */
|
||||
static int mmc_read_toc_fmt0(struct burn_drive *d)
|
||||
{
|
||||
int alloc_len = 4, ret;
|
||||
|
||||
if (mmc_function_spy(d, "mmc_read_toc_fmt0") <= 0)
|
||||
return -1;
|
||||
ret = mmc_read_toc_fmt0_al(d, &alloc_len);
|
||||
if (alloc_len >= 12)
|
||||
ret = mmc_read_toc_fmt0_al(d, &alloc_len);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* ts A70131 : compose a disc TOC structure from d->complete_sessions
|
||||
and 52h READ TRACK INFORMATION */
|
||||
int mmc_fake_toc(struct burn_drive *d)
|
||||
@ -825,6 +973,12 @@ int mmc_fake_toc(struct burn_drive *d)
|
||||
msg, 0,0);
|
||||
return 0;
|
||||
}
|
||||
/* ts A71128 : My DVD-ROM drive issues no reliable track info.
|
||||
One has to try 43h READ TOC/PMA/ATIP Form 0. */
|
||||
if (d->current_profile == 0x10 && d->last_track_no <= 1) {
|
||||
ret = mmc_read_toc_fmt0(d);
|
||||
return ret;
|
||||
}
|
||||
d->disc = burn_disc_create();
|
||||
if (d->disc == NULL)
|
||||
return -1;
|
||||
@ -835,12 +989,15 @@ int mmc_fake_toc(struct burn_drive *d)
|
||||
memset(d->toc_entry, 0,d->toc_entries * sizeof(struct burn_toc_entry));
|
||||
for (i = 0; i < d->complete_sessions; i++) {
|
||||
session = burn_session_create();
|
||||
if (session == NULL)
|
||||
return -1;
|
||||
burn_disc_add_session(d->disc, session, BURN_POS_END);
|
||||
burn_session_free(session);
|
||||
}
|
||||
memset(size_data, 0, 4);
|
||||
memset(start_data, 0, 4);
|
||||
|
||||
|
||||
/* Entry Layout :
|
||||
session 1 track 1 entry 0
|
||||
...
|
||||
@ -943,13 +1100,15 @@ static int mmc_read_toc_al(struct burn_drive *d, int *alloc_len)
|
||||
if (!(d->current_profile == -1 || d->current_is_cd_profile)) {
|
||||
/* ts A70131 : MMC_GET_TOC uses Response Format 2
|
||||
For DVD this fails with 5,24,00 */
|
||||
/* One could try Response Format 0: mmc5r03.pdf 6.26.3.2
|
||||
which does not yield the same result wit the same disc
|
||||
/* mmc_read_toc_fmt0() uses
|
||||
Response Format 0: mmc5r03.pdf 6.26.3.2
|
||||
which does not yield the same result with the same disc
|
||||
on different drives.
|
||||
*/
|
||||
/* ts A70201 :
|
||||
This uses the session count from 51h READ DISC INFORMATION
|
||||
and the track records from 52h READ TRACK INFORMATION
|
||||
and the track records from 52h READ TRACK INFORMATION.
|
||||
mmc_read_toc_fmt0() is used as fallback for dull DVD-ROM.
|
||||
*/
|
||||
mmc_fake_toc(d);
|
||||
|
||||
@ -1251,7 +1410,7 @@ static int mmc_read_disc_info_al(struct burn_drive *d, int *alloc_len)
|
||||
*alloc_len = len + 2;
|
||||
if (old_alloc_len < 34)
|
||||
return 1;
|
||||
if (*alloc_len < 24) /* data[23] is the last byte used her */
|
||||
if (*alloc_len < 24) /* data[23] is the last byte used here */
|
||||
return 0;
|
||||
if (len + 2 > old_alloc_len)
|
||||
len = old_alloc_len - 2;
|
||||
|
@ -566,12 +566,16 @@ void spc_sense_write_params(struct burn_drive *d)
|
||||
c.dir = FROM_DRIVE;
|
||||
d->issue_command(d, &c);
|
||||
|
||||
size = c.page->data[0] * 256 + c.page->data[1];
|
||||
/* ts A71128 : do not interpret reply if error */
|
||||
m = d->mdata;
|
||||
if(!c.error) {
|
||||
size = c.page->data[0] * 256 + c.page->data[1];
|
||||
page = c.page->data + 8;
|
||||
burn_print(1, "write page length 0x%x\n", page[1]);
|
||||
m->write_page_length = page[1];
|
||||
m->write_page_valid = 1;
|
||||
} else
|
||||
m->write_page_valid = 0;
|
||||
mmc_read_disc_info(d);
|
||||
|
||||
/* ts A70212 : try to setup d->media_capacity_remaining */
|
||||
|
Loading…
Reference in New Issue
Block a user