|
|
|
@ -300,6 +300,14 @@ int mmc_four_char_to_int(unsigned char *data)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* ts C40226 */
|
|
|
|
|
unsigned int mmc_four_char_to_uint(unsigned char *data)
|
|
|
|
|
{
|
|
|
|
|
return (((unsigned int) data[0]) << 24) | (data[1] << 16) |
|
|
|
|
|
(data[2] << 8) | data[3];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* ts A70201 */
|
|
|
|
|
int mmc_int_to_four_char(unsigned char *data, int num)
|
|
|
|
|
{
|
|
|
|
@ -311,6 +319,17 @@ int mmc_int_to_four_char(unsigned char *data, int num)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* ts C40226 */
|
|
|
|
|
int mmc_uint_to_four_char(unsigned char *data, unsigned int num)
|
|
|
|
|
{
|
|
|
|
|
data[0] = (num >> 24) & 0xff;
|
|
|
|
|
data[1] = (num >> 16) & 0xff;
|
|
|
|
|
data[2] = (num >> 8) & 0xff;
|
|
|
|
|
data[3] = num & 0xff;
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static int mmc_start_for_bit0 = 0;
|
|
|
|
|
|
|
|
|
|
/* @param flag bit0= the calling function should need no START UNIT.
|
|
|
|
@ -1087,10 +1106,11 @@ int mmc_fake_toc_entry(struct burn_toc_entry *entry, int session_number,
|
|
|
|
|
unsigned char *size_data, unsigned char *start_data,
|
|
|
|
|
unsigned char *last_adr_data)
|
|
|
|
|
{
|
|
|
|
|
int min, sec, frames, num;
|
|
|
|
|
int min, sec, frames;
|
|
|
|
|
unsigned int num;
|
|
|
|
|
|
|
|
|
|
/* mark DVD extensions and Track Info extension as valid */
|
|
|
|
|
entry->extensions_valid |= (1 | 2);
|
|
|
|
|
/* mark extensions as valid: DVD, Track Info, Long block address */
|
|
|
|
|
entry->extensions_valid |= (1 | 2 | 8);
|
|
|
|
|
|
|
|
|
|
/* defaults are as of mmc5r03.pdf 6.26.3.2.4 Fabricated TOC */
|
|
|
|
|
entry->session = session_number & 0xff;
|
|
|
|
@ -1100,9 +1120,16 @@ int mmc_fake_toc_entry(struct burn_toc_entry *entry, int session_number,
|
|
|
|
|
entry->tno = 0;
|
|
|
|
|
entry->point = track_number & 0xff;
|
|
|
|
|
entry->point_msb = (track_number >> 8) & 0xff;
|
|
|
|
|
num = mmc_four_char_to_int(size_data);
|
|
|
|
|
entry->track_blocks = num;
|
|
|
|
|
burn_lba_to_msf(num, &min, &sec, &frames);
|
|
|
|
|
num = mmc_four_char_to_uint(size_data);
|
|
|
|
|
if (num < 0x80000000) {
|
|
|
|
|
entry->track_blocks = num;
|
|
|
|
|
burn_lba_to_msf(num, &min, &sec, &frames);
|
|
|
|
|
} else {
|
|
|
|
|
entry->track_blocks = -1;
|
|
|
|
|
min = 477218; /* ~=LBA 0x7fffffff */
|
|
|
|
|
sec = frames = 0;
|
|
|
|
|
}
|
|
|
|
|
entry->long_track_blocks = num;
|
|
|
|
|
if (min > 255) {
|
|
|
|
|
min = 255;
|
|
|
|
|
sec = 255;
|
|
|
|
@ -1112,9 +1139,16 @@ int mmc_fake_toc_entry(struct burn_toc_entry *entry, int session_number,
|
|
|
|
|
entry->sec = sec;
|
|
|
|
|
entry->frame = frames;
|
|
|
|
|
entry->zero = 0;
|
|
|
|
|
num = mmc_four_char_to_int(start_data);
|
|
|
|
|
entry->start_lba = num;
|
|
|
|
|
burn_lba_to_msf(num, &min, &sec, &frames);
|
|
|
|
|
num = mmc_four_char_to_uint(start_data);
|
|
|
|
|
if (num < 0x80000000) {
|
|
|
|
|
entry->start_lba = num;
|
|
|
|
|
burn_lba_to_msf(num, &min, &sec, &frames);
|
|
|
|
|
} else {
|
|
|
|
|
entry->start_lba = -1;
|
|
|
|
|
min = 477218;
|
|
|
|
|
sec = frames = 0;
|
|
|
|
|
}
|
|
|
|
|
entry->long_start_lba = num;
|
|
|
|
|
if (min > 255) {
|
|
|
|
|
min = 255;
|
|
|
|
|
sec = 255;
|
|
|
|
@ -1123,7 +1157,13 @@ int mmc_fake_toc_entry(struct burn_toc_entry *entry, int session_number,
|
|
|
|
|
entry->pmin = min;
|
|
|
|
|
entry->psec = sec;
|
|
|
|
|
entry->pframe = frames;
|
|
|
|
|
entry->last_recorded_address = mmc_four_char_to_int(last_adr_data);
|
|
|
|
|
num = mmc_four_char_to_uint(last_adr_data);
|
|
|
|
|
if (num < 0x80000000) {
|
|
|
|
|
entry->last_recorded_address = num;
|
|
|
|
|
} else {
|
|
|
|
|
entry->last_recorded_address = -1;
|
|
|
|
|
}
|
|
|
|
|
entry->long_last_rec_adr = num;
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -1137,7 +1177,7 @@ static int mmc_read_toc_fmt0_al(struct burn_drive *d, int *alloc_len)
|
|
|
|
|
struct buffer *buf = NULL;
|
|
|
|
|
struct command *c = NULL;
|
|
|
|
|
int dlen, i, old_alloc_len, session_number, prev_session = -1, ret;
|
|
|
|
|
int lba, size;
|
|
|
|
|
unsigned int lba, size;
|
|
|
|
|
unsigned char *tdata, size_data[4], start_data[4], end_data[4];
|
|
|
|
|
|
|
|
|
|
if (*alloc_len < 4)
|
|
|
|
@ -1216,11 +1256,11 @@ err_ex:;
|
|
|
|
|
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_int_to_four_char(end_data, lba - 1);
|
|
|
|
|
lba = mmc_four_char_to_uint(start_data) +
|
|
|
|
|
mmc_four_char_to_uint(size_data);
|
|
|
|
|
mmc_uint_to_four_char(start_data, lba);
|
|
|
|
|
mmc_uint_to_four_char(size_data, 0);
|
|
|
|
|
mmc_uint_to_four_char(end_data, lba - 1);
|
|
|
|
|
mmc_fake_toc_entry(entry, prev_session, 0xA2,
|
|
|
|
|
size_data, start_data, end_data);
|
|
|
|
|
entry->min= entry->sec= entry->frame= 0;
|
|
|
|
@ -1245,11 +1285,11 @@ err_ex:;
|
|
|
|
|
memcpy(start_data, tdata + 4, 4);
|
|
|
|
|
/* size_data are estimated from next track start */
|
|
|
|
|
memcpy(size_data, tdata + 8 + 4, 4);
|
|
|
|
|
mmc_int_to_four_char(end_data,
|
|
|
|
|
mmc_four_char_to_int(size_data) - 1);
|
|
|
|
|
size = mmc_four_char_to_int(size_data) -
|
|
|
|
|
mmc_four_char_to_int(start_data);
|
|
|
|
|
mmc_int_to_four_char(size_data, size);
|
|
|
|
|
mmc_uint_to_four_char(end_data,
|
|
|
|
|
mmc_four_char_to_uint(size_data) - 1);
|
|
|
|
|
size = mmc_four_char_to_uint(size_data) -
|
|
|
|
|
mmc_four_char_to_uint(start_data);
|
|
|
|
|
mmc_uint_to_four_char(size_data, size);
|
|
|
|
|
mmc_fake_toc_entry(entry, session_number, i + 1,
|
|
|
|
|
size_data, start_data, end_data);
|
|
|
|
|
if (prev_session != session_number)
|
|
|
|
@ -1262,9 +1302,9 @@ err_ex:;
|
|
|
|
|
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_int_to_four_char(end_data,
|
|
|
|
|
mmc_four_char_to_int(start_data) - 1);
|
|
|
|
|
mmc_uint_to_four_char(size_data, 0);
|
|
|
|
|
mmc_uint_to_four_char(end_data,
|
|
|
|
|
mmc_four_char_to_uint(start_data) - 1);
|
|
|
|
|
mmc_fake_toc_entry(entry, prev_session, 0xA2,
|
|
|
|
|
size_data, start_data, end_data);
|
|
|
|
|
entry->min= entry->sec= entry->frame= 0;
|
|
|
|
@ -1301,7 +1341,8 @@ int mmc_fake_toc(struct burn_drive *d)
|
|
|
|
|
struct burn_session *session;
|
|
|
|
|
struct burn_toc_entry *entry;
|
|
|
|
|
struct buffer *buf = NULL;
|
|
|
|
|
int i, session_number, prev_session = -1, ret, lba, alloc_len = 34;
|
|
|
|
|
int i, session_number, prev_session = -1, ret, alloc_len = 34;
|
|
|
|
|
unsigned int lba;
|
|
|
|
|
unsigned char *tdata, size_data[4], start_data[4], end_data[4];
|
|
|
|
|
char *msg = NULL;
|
|
|
|
|
|
|
|
|
@ -1406,11 +1447,11 @@ int mmc_fake_toc(struct burn_drive *d)
|
|
|
|
|
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_int_to_four_char(end_data, lba - 1);
|
|
|
|
|
lba = mmc_four_char_to_uint(start_data) +
|
|
|
|
|
mmc_four_char_to_uint(size_data);
|
|
|
|
|
mmc_uint_to_four_char(start_data, lba);
|
|
|
|
|
mmc_uint_to_four_char(size_data, 0);
|
|
|
|
|
mmc_uint_to_four_char(end_data, lba - 1);
|
|
|
|
|
mmc_fake_toc_entry(entry, prev_session, 0xA2,
|
|
|
|
|
size_data, start_data, end_data);
|
|
|
|
|
entry->min= entry->sec= entry->frame= 0;
|
|
|
|
@ -1431,7 +1472,7 @@ int mmc_fake_toc(struct burn_drive *d)
|
|
|
|
|
if (i == d->last_track_no - 1) {
|
|
|
|
|
/* ts A70212 : Last track field Free Blocks */
|
|
|
|
|
burn_drive_set_media_capacity_remaining(d,
|
|
|
|
|
((off_t) mmc_four_char_to_int(tdata + 16)) *
|
|
|
|
|
((off_t) mmc_four_char_to_uint(tdata + 16)) *
|
|
|
|
|
((off_t) 2048));
|
|
|
|
|
d->media_lba_limit = 0;
|
|
|
|
|
}
|
|
|
|
@ -1477,11 +1518,11 @@ int mmc_fake_toc(struct burn_drive *d)
|
|
|
|
|
if (prev_session > 0 && prev_session <= d->disc->sessions) {
|
|
|
|
|
/* leadout entry of last session of closed disc */
|
|
|
|
|
entry = &(d->toc_entry[(d->last_track_no - 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_int_to_four_char(end_data, lba - 1);
|
|
|
|
|
lba = mmc_four_char_to_uint(start_data) +
|
|
|
|
|
mmc_four_char_to_uint(size_data);
|
|
|
|
|
mmc_uint_to_four_char(start_data, lba);
|
|
|
|
|
mmc_uint_to_four_char(size_data, 0);
|
|
|
|
|
mmc_uint_to_four_char(end_data, lba - 1);
|
|
|
|
|
mmc_fake_toc_entry(entry, prev_session, 0xA2,
|
|
|
|
|
size_data, start_data, end_data);
|
|
|
|
|
entry->min= entry->sec= entry->frame= 0;
|
|
|
|
@ -1774,12 +1815,12 @@ void mmc_read_toc(struct burn_drive *d)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* ts A70131 : This tries to get the start of the last complete session */
|
|
|
|
|
/* ts C40226 : long address reply version of mmc_read_multi_session_c1 */
|
|
|
|
|
/* man mkisofs , option -C :
|
|
|
|
|
The first number is the sector number of the first sector in
|
|
|
|
|
the last session of the disk that should be appended to.
|
|
|
|
|
*/
|
|
|
|
|
int mmc_read_multi_session_c1(struct burn_drive *d, int *trackno, int *start)
|
|
|
|
|
int mmc_read_msc1_long(struct burn_drive *d, int *trackno, off_t *start)
|
|
|
|
|
{
|
|
|
|
|
struct buffer *buf = NULL;
|
|
|
|
|
struct command *c = NULL;
|
|
|
|
@ -1812,7 +1853,11 @@ int mmc_read_multi_session_c1(struct burn_drive *d, int *trackno, int *start)
|
|
|
|
|
continue;
|
|
|
|
|
burn_track_get_entry(tracks[0], &toc_entry);
|
|
|
|
|
if (toc_entry.extensions_valid & 1) { /* DVD extension valid */
|
|
|
|
|
*start = toc_entry.start_lba;
|
|
|
|
|
if (toc_entry.extensions_valid & 8) { /* Long adr */
|
|
|
|
|
*start = toc_entry.long_start_lba;
|
|
|
|
|
} else {
|
|
|
|
|
*start = toc_entry.start_lba;
|
|
|
|
|
}
|
|
|
|
|
*trackno = (toc_entry.point_msb << 8)| toc_entry.point;
|
|
|
|
|
} else {
|
|
|
|
|
*start = burn_msf_to_lba(toc_entry.pmin,
|
|
|
|
@ -1847,7 +1892,7 @@ inquire_drive:;
|
|
|
|
|
|
|
|
|
|
tdata = c->page->data + 4;
|
|
|
|
|
*trackno = tdata[2];
|
|
|
|
|
*start = mmc_four_char_to_int(tdata + 4);
|
|
|
|
|
*start = mmc_four_char_to_uint(tdata + 4);
|
|
|
|
|
ret = 1;
|
|
|
|
|
ex:;
|
|
|
|
|
BURN_FREE_MEM(buf);
|
|
|
|
@ -1856,6 +1901,24 @@ ex:;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* ts A70131 : This tries to get the start of the last complete session */
|
|
|
|
|
int mmc_read_multi_session_c1(struct burn_drive *d, int *trackno, int *start)
|
|
|
|
|
{
|
|
|
|
|
int ret;
|
|
|
|
|
off_t num;
|
|
|
|
|
|
|
|
|
|
ret = mmc_read_msc1_long(d, trackno, &num);
|
|
|
|
|
if (ret <= 0)
|
|
|
|
|
return ret;
|
|
|
|
|
if(num >= 0x80000000) {
|
|
|
|
|
*start = 0x7fffffff;
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
*start = num;
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* ts A61201 */
|
|
|
|
|
char *mmc_obtain_profile_name(int profile_number)
|
|
|
|
|
{
|
|
|
|
|