Provisorily obtain multi-session -C parameters (violates MMC specs but works)

This commit is contained in:
Thomas Schmitt 2007-01-31 17:34:49 +00:00
parent f194aa8d5d
commit dde52c1971
7 changed files with 120 additions and 11 deletions

View File

@ -149,8 +149,9 @@ Note: The support for sequentially recordable media is still emerging.
DVD-R have not been tested yet. If no Incremental Streaming feature (21h) DVD-R have not been tested yet. If no Incremental Streaming feature (21h)
is offered, then the media is regarded as unsuitable without further is offered, then the media is regarded as unsuitable without further
explanation. (One can torture DVD-RW to make them offer only DAO (2Fh)). explanation. (One can torture DVD-RW to make them offer only DAO (2Fh)).
Only single-track sessions have been tested yet. Multi-session works but Multi-session works, but -toc is not implemented yet. -msinfo works although
-toc and -msinfo are not implemented yet. otherwise predicted by MMC-3 to MMC-5. Be mistrusting when appending a third
session for the first time with your drive.
.br .br
--------------- ---------------
.br .br
@ -165,6 +166,8 @@ It resembles much TAO writing with CD, as it allows track sources of
unpredicted length and to keep media appendable by option unpredicted length and to keep media appendable by option
.B -multi . .B -multi .
Only restriction towards CD-RW is the lack of support for -audio tracks. Only restriction towards CD-RW is the lack of support for -audio tracks.
Multiple tracks per session are permissible. A reasonable use case for
this has still to be found, though.
.br .br
(The other write mode, DAO, is not implemented yet. It will allow no -multi and (The other write mode, DAO, is not implemented yet. It will allow no -multi and
only a single track.) only a single track.)

View File

@ -127,6 +127,9 @@ or
#ifdef Cdrskin_libburn_0_3_1 #ifdef Cdrskin_libburn_0_3_1
#define Cdrskin_libburn_versioN "0.3.1" #define Cdrskin_libburn_versioN "0.3.1"
#define Cdrskin_libburn_from_pykix_svN 1 #define Cdrskin_libburn_from_pykix_svN 1
#define Cdrskin_libburn_has_get_msc1 1
#endif /* Cdrskin_libburn_0_3_1 */ #endif /* Cdrskin_libburn_0_3_1 */
#ifndef Cdrskin_libburn_versioN #ifndef Cdrskin_libburn_versioN
@ -3484,12 +3487,19 @@ int Cdrskin_msinfo(struct CdrskiN *skin, int flag)
s= burn_disc_get_status(drive); s= burn_disc_get_status(drive);
if(s!=BURN_DISC_APPENDABLE) { if(s!=BURN_DISC_APPENDABLE) {
Cdrskin_report_disc_status(skin,s,0); Cdrskin_report_disc_status(skin,s,0);
fprintf(stderr, fprintf(stderr,"cdrskin: FATAL : -msinfo can only operate on appendable (i.e. -multi) discs\n");
"cdrskin: FATAL : -msinfo can only operate on appendable (i.e. -multi) CD\n");
{ret= 0; goto ex;} {ret= 0; goto ex;}
} }
disc= burn_drive_get_disc(drive); disc= burn_drive_get_disc(drive);
if(disc==NULL) { if(disc==NULL) {
#ifdef Cdrskin_libburn_has_get_msc1
/* No TOC available. Try to inquire directly. */
ret= burn_disc_get_msc1(drive,&lba);
if(ret>0)
goto obtain_nwa;
#endif /* Cdrskin_libburn_has_get_msc1 */
fprintf(stderr,"cdrskin: FATAL : Cannot obtain info about CD content\n"); fprintf(stderr,"cdrskin: FATAL : Cannot obtain info about CD content\n");
{ret= 0; goto ex;} {ret= 0; goto ex;}
} }
@ -3506,6 +3516,7 @@ int Cdrskin_msinfo(struct CdrskiN *skin, int flag)
{ret= 0; goto ex;} {ret= 0; goto ex;}
} }
obtain_nwa:;
ret= Cdrskin_obtain_nwa(skin,&nwa,flag); ret= Cdrskin_obtain_nwa(skin,&nwa,flag);
if(ret<=0) { if(ret<=0) {
fprintf(stderr, fprintf(stderr,
@ -4394,8 +4405,9 @@ int Cdrskin_activate_write_mode(struct CdrskiN *skin, enum burn_disc_status s,
strcpy(skin->preskin->write_mode_name,"TAO"); strcpy(skin->preskin->write_mode_name,"TAO");
was_still_default= 2; /* prevents trying of SAO if drive dislikes TAO*/ was_still_default= 2; /* prevents trying of SAO if drive dislikes TAO*/
} else if(profile_number==0x1a || profile_number==0x13 || } else if(profile_number==0x1a || profile_number==0x13 ||
profile_number==0x12) { profile_number==0x12 ||
/* DVD+RW , DVD-RW Restricted Overwrite , DVD-RAM */ profile_number==0x11 || profile_number==0x14) {
/* DVD+RW, DVD-RW Restr. Overwrite, DVD-RAM, DVD-R, DVD-RW Sequential */
strcpy(skin->preskin->write_mode_name,"TAO"); strcpy(skin->preskin->write_mode_name,"TAO");
} else { } else {
strcpy(skin->preskin->write_mode_name,"SAO"); strcpy(skin->preskin->write_mode_name,"SAO");
@ -4639,9 +4651,6 @@ burn_failed:;
burn_write_opts_set_perform_opc(o, 0); burn_write_opts_set_perform_opc(o, 0);
#ifdef Cdrskin_libburn_has_multI #ifdef Cdrskin_libburn_has_multI
if(skin->multi)
fprintf(stderr,
"cdrskin: NOTE : Option -multi set. Media will be appendable.\n");
burn_write_opts_set_multi(o,skin->multi); burn_write_opts_set_multi(o,skin->multi);
#endif #endif

View File

@ -1 +1 @@
#define Cdrskin_timestamP "2007.01.31.130100" #define Cdrskin_timestamP "2007.01.31.173611"

View File

@ -1409,6 +1409,32 @@ int burn_disc_track_lba_nwa(struct burn_drive *d, struct burn_write_opts *o,
} }
/* ts A70131 : new API function */
int burn_disc_get_msc1(struct burn_drive *d, int *start)
{
int ret, trackno;
if (burn_drive_is_released(d)) {
libdax_msgs_submit(libdax_messenger,
d->global_index, 0x0002011b,
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
"Attempt to read track info from ungrabbed drive",
0, 0);
return -1;
}
if (d->busy != BURN_DRIVE_IDLE) {
libdax_msgs_submit(libdax_messenger,
d->global_index, 0x0002011c,
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
"Attempt to read track info from busy drive",
0, 0);
return -1;
}
ret = d->read_multi_session_c1(d, &trackno, start);
return ret;
}
/* ts A61202 : New API function */ /* ts A61202 : New API function */
int burn_disc_get_profile(struct burn_drive *d, int *pno, char name[80]) int burn_disc_get_profile(struct burn_drive *d, int *pno, char name[80])
{ {

View File

@ -788,6 +788,16 @@ int burn_drive_get_start_end_lba(struct burn_drive *drive,
int burn_disc_track_lba_nwa(struct burn_drive *d, struct burn_write_opts *o, int burn_disc_track_lba_nwa(struct burn_drive *d, struct burn_write_opts *o,
int trackno, int *lba, int *nwa); int trackno, int *lba, int *nwa);
/* ts A70131 */
/** Read start lba of the first track in the last complete session.
This is the first parameter of mkisofs option -C. The second parameter
is nwa as obtained by burn_disc_track_lba_nwa() with trackno 0.
@param d The drive to query.
@param start_lba returns the start address of that track
@return <= 0 : failure, 1 = ok
*/
int burn_disc_get_msc1(struct burn_drive *d, int *start_lba);
/* ts A61202 */ /* ts A61202 */
/** Tells the MMC Profile identifier of the loaded media. The drive must be /** Tells the MMC Profile identifier of the loaded media. The drive must be
grabbed in order to get a non-zero result. grabbed in order to get a non-zero result.

View File

@ -84,6 +84,8 @@ Todo:
*/ */
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[] = { 0x43, 2, 2, 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_ATIP[] = { 0x43, 2, 4, 0, 0, 0, 0, 16, 0, 0 };
static unsigned char MMC_GET_DISC_INFO[] = static unsigned char MMC_GET_DISC_INFO[] =
@ -421,6 +423,18 @@ void mmc_read_toc(struct burn_drive *d)
mmc_function_spy("mmc_read_toc"); mmc_function_spy("mmc_read_toc");
memcpy(c.opcode, MMC_GET_TOC, sizeof(MMC_GET_TOC)); memcpy(c.opcode, MMC_GET_TOC, sizeof(MMC_GET_TOC));
if(!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 */
/* One could try
51h READ DISC INFORMATION and 52h READ TRACK INFORMATION
where 51h gives the number of tracks and 52h tells the
session number with each track. */
/* >>> One must do someting */;
}
c.retry = 1; c.retry = 1;
c.oplen = sizeof(MMC_GET_TOC); c.oplen = sizeof(MMC_GET_TOC);
c.page = &buf; c.page = &buf;
@ -442,7 +456,7 @@ void mmc_read_toc(struct burn_drive *d)
libdax_msgs_submit(libdax_messenger, d->global_index, libdax_msgs_submit(libdax_messenger, d->global_index,
0x0002010d, 0x0002010d,
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH, LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH,
"Could not inquire TOC (non-blank DVD media ?)", 0,0); "Could not inquire TOC", 0,0);
d->status = BURN_DISC_UNSUITABLE; d->status = BURN_DISC_UNSUITABLE;
d->toc_entries = 0; d->toc_entries = 0;
/* Prefering memory leaks over fandangos */ /* Prefering memory leaks over fandangos */
@ -541,6 +555,47 @@ void mmc_read_toc(struct burn_drive *d)
toc_find_modes(d); toc_find_modes(d);
} }
/* ts A70131 : If no TOC is at hand, this tries to get the start of the
last complete session (mksifs -c first parameter) */
int mmc_read_multi_session_c1(struct burn_drive *d, int *trackno, int *start)
{
struct buffer buf;
struct command c;
unsigned char *tdata;
mmc_function_spy("mmc_read_multi_session_c");
/* mmc5r03.pdf 6.26.3.3.3 states that with non-CD this would
be a useless fake always starting at track 1, lba 0.
My drives return useful data, though.
MMC-3 states that DVD had not tracks. So maybe this fake is
a legacy ?
>>> Possibly one will have to fake this reply from
51h READ DISC INFORMATION and 52h READ TRACK INFORMATION
(I still have to find out what growisofs is using)
*/
memcpy(c.opcode, MMC_GET_MSINFO, sizeof(MMC_GET_MSINFO));
c.retry = 1;
c.oplen = sizeof(MMC_GET_MSINFO);
c.page = &buf;
c.page->bytes = 0;
c.page->sectors = 0;
c.dir = FROM_DRIVE;
d->issue_command(d, &c);
if (c.error)
return 0;
tdata = c.page->data + 4;
*trackno = tdata[2];
*start = (tdata[4] << 24) | (tdata[5] << 16)
| (tdata[6] << 8) | tdata[7];
return 1;
}
void mmc_read_disc_info(struct burn_drive *d) void mmc_read_disc_info(struct burn_drive *d)
{ {
struct buffer buf; struct buffer buf;
@ -1806,6 +1861,7 @@ int mmc_setup_drive(struct burn_drive *d)
d->send_cue_sheet = mmc_send_cue_sheet; d->send_cue_sheet = mmc_send_cue_sheet;
d->sync_cache = mmc_sync_cache; d->sync_cache = mmc_sync_cache;
d->get_nwa = mmc_get_nwa; d->get_nwa = mmc_get_nwa;
d->read_multi_session_c1 = mmc_read_multi_session_c1;
d->close_disc = mmc_close_disc; d->close_disc = mmc_close_disc;
d->close_session = mmc_close_session; d->close_session = mmc_close_session;
d->close_track_session = mmc_close; d->close_track_session = mmc_close;

View File

@ -250,6 +250,11 @@ struct burn_drive
int (*get_erase_progress) (struct burn_drive *); int (*get_erase_progress) (struct burn_drive *);
int (*get_nwa) (struct burn_drive *, int trackno, int *lba, int *nwa); int (*get_nwa) (struct burn_drive *, int trackno, int *lba, int *nwa);
/* ts A70131 : obtain (possibly fake) TOC number and start lba of
first track in last complete session */
int (*read_multi_session_c1)(struct burn_drive *d,
int *trackno, int *start);
/* ts A61009 : removed d in favor of o->drive */ /* ts A61009 : removed d in favor of o->drive */
/* void (*close_disc) (struct burn_drive * d, /* void (*close_disc) (struct burn_drive * d,
struct burn_write_opts * o); struct burn_write_opts * o);