Prepared experiments for writing to DVD (most easy: DVD+RW)
This commit is contained in:
parent
c1f49bab3b
commit
94848398c0
@ -1 +1 @@
|
||||
#define Cdrskin_timestamP "2006.12.18.123242"
|
||||
#define Cdrskin_timestamP "2006.12.20.111932"
|
||||
|
@ -334,8 +334,12 @@ Range "scdbackup" : 0x00020000 to 0x0002ffff
|
||||
0x0002011a (NOTE,HIGH) = Padding up track to minimum size
|
||||
0x0002011b (FATAL,HIGH) = Attempt to read track info from ungrabbed drive
|
||||
0x0002011c (FATAL,HIGH) = Attempt to read track info from busy drive
|
||||
0x0002011d (FATAL,HIGH) = SCSI error condition on write
|
||||
0x0002011e (SORRY, HIGH) = Unsuitable media detected
|
||||
0x0002011d (FATAL,HIGH) = SCSI error on write
|
||||
0x0002011e (SORRY,HIGH) = Unsuitable media detected
|
||||
0x0002011f (SORRY,HIGH) = Burning of DVD+RW is restricted to a single track
|
||||
0x00020120 (NOTE,HIGH) = FORMAT UNIT ignored
|
||||
0x00020121 (FATAL,HIGH) = Write preparation setup failed
|
||||
0x00020122 (FATAL,HIGH) = SCSI error on format_unit
|
||||
|
||||
libdax_audioxtr:
|
||||
0x00020200 (SORRY,HIGH) = Cannot open audio source file
|
||||
|
132
libburn/mmc.c
132
libburn/mmc.c
@ -34,6 +34,23 @@
|
||||
extern struct libdax_msgs *libdax_messenger;
|
||||
|
||||
|
||||
/* ts A61219 : ! HIGHLY EXPERIMENTAL !
|
||||
Based on knowlege from dvd+rw-tools-7.0 and mmc5r03c.pdf
|
||||
*/
|
||||
/*
|
||||
#define Libburn_support_dvd_plus_rW 1
|
||||
*/
|
||||
/* Progress report (with Libburn_support_dvd_plus_rW defined):
|
||||
ts A61219 : It seems to work with a used (i.e. thoroughly formatted) DVD+RW.
|
||||
Error messages of class DEBUG appear because of inability to
|
||||
read TOC or track info. Nevertheless, the written images verify.
|
||||
ts A61220 : Burned to a virgin DVD+RW by help of new mmc_format_unit()
|
||||
(did not test wether it would work without). Burned to a
|
||||
not completely formatted DVD+RW. (Had worked before without
|
||||
mmc_format_unit(). I did not exceed the formatted range
|
||||
as reported by dvd+rw-mediainfo.
|
||||
*/
|
||||
|
||||
|
||||
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 };
|
||||
@ -62,6 +79,9 @@ static unsigned char MMC_SEND_CUE_SHEET[] =
|
||||
/* ts A61023 : get size and free space of drive buffer */
|
||||
static unsigned char MMC_READ_BUFFER_CAPACITY[] = { 0x5C, 0, 0, 0, 0, 0, 0, 16, 0, 0 };
|
||||
|
||||
/* ts A61219 : format DVD+RW (and various others) */
|
||||
static unsigned char MMC_FORMAT_UNIT[] = { 0x04, 0x11, 0, 0, 0, 0 };
|
||||
|
||||
|
||||
static int mmc_function_spy_do_tell = 0;
|
||||
|
||||
@ -310,9 +330,10 @@ int mmc_write(struct burn_drive *d, int start, struct buffer *buf)
|
||||
|
||||
/* >>> make this scsi_notify_error() when liberated */
|
||||
if (c.sense[2]!=0) {
|
||||
char msg[80];
|
||||
char msg[160];
|
||||
sprintf(msg,
|
||||
"SCSI error condition on write : key=%X asc=%2.2Xh ascq=%2.2Xh",
|
||||
"SCSI error on write(%d,%d): key=%X asc=%2.2Xh ascq=%2.2Xh",
|
||||
start, len,
|
||||
c.sense[2],c.sense[12],c.sense[13]);
|
||||
libdax_msgs_submit(libdax_messenger, d->global_index,
|
||||
0x0002011d,
|
||||
@ -355,7 +376,7 @@ void mmc_read_toc(struct burn_drive *d)
|
||||
/* ts A61106 : also snaps on CD with unclosed track/session */
|
||||
/* Very unsure wether this old measure is ok.
|
||||
Obviously higher levels do not care about this.
|
||||
DVD+RW burns go on after passing through here.
|
||||
outdated info: DVD+RW burns go on after passing through here.
|
||||
|
||||
d->busy = BURN_DRIVE_IDLE;
|
||||
*/
|
||||
@ -479,7 +500,7 @@ void mmc_read_disc_info(struct burn_drive *d)
|
||||
|
||||
mmc_get_configuration(d);
|
||||
if ((d->current_profile != 0 || d->status != BURN_DISC_UNREADY)
|
||||
&& ! d->current_is_cd_profile) {
|
||||
&& ! d->current_is_supported_profile) {
|
||||
if (!d->silent_on_scsi_error) {
|
||||
sprintf(msg,
|
||||
"Unsuitable media detected. Profile %4.4Xh %s",
|
||||
@ -536,12 +557,24 @@ void mmc_read_disc_info(struct burn_drive *d)
|
||||
break;
|
||||
}
|
||||
|
||||
/* ts A61217 : Note for future
|
||||
>>> growisofs performs OPC if (data[0]<<8)|data[1]<=32
|
||||
>>> which indicates no OPC entries are attached to the
|
||||
>>> reply from the drive.
|
||||
/* >>> ts A61217 : Note for future
|
||||
growisofs performs OPC if (data[0]<<8)|data[1]<=32
|
||||
which indicates no OPC entries are attached to the
|
||||
reply from the drive.
|
||||
*/
|
||||
|
||||
/* ts A61219 : mmc5r03c.pdf 6.22.3.1.13 BG Format Status
|
||||
0=blank (not yet started)
|
||||
1=started but neither running nor complete
|
||||
2=in progress
|
||||
3=completed
|
||||
*/
|
||||
d->bg_format_status = data[7] & 3;
|
||||
|
||||
/* <<< ts A61219 : preliminarily declare all DVD+RW blank,
|
||||
(which is not the same as bg_format_status==0 "blank") */
|
||||
if (d->current_profile == 0x1a)
|
||||
d->status = BURN_DISC_BLANK;
|
||||
}
|
||||
|
||||
void mmc_read_atip(struct burn_drive *d)
|
||||
@ -893,6 +926,7 @@ void mmc_get_configuration(struct burn_drive *d)
|
||||
d->current_profile = 0;
|
||||
d->current_profile_text[0] = 0;
|
||||
d->current_is_cd_profile = 0;
|
||||
d->current_is_supported_profile = 0;
|
||||
|
||||
mmc_function_spy("mmc_get_configuration");
|
||||
memcpy(c.opcode, MMC_GET_CONFIGURATION, sizeof(MMC_GET_CONFIGURATION));
|
||||
@ -917,7 +951,13 @@ void mmc_get_configuration(struct burn_drive *d)
|
||||
d->current_profile = cp;
|
||||
strcpy(d->current_profile_text, mmc_obtain_profile_name(cp));
|
||||
if (cp == 0x08 || cp == 0x09 || cp == 0x0a)
|
||||
d->current_is_cd_profile = 1;
|
||||
d->current_is_supported_profile = d->current_is_cd_profile = 1;
|
||||
|
||||
#ifdef Libburn_support_dvd_plus_rW
|
||||
if (cp == 0x1a)
|
||||
d->current_is_supported_profile = 1;
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
void mmc_sync_cache(struct burn_drive *d)
|
||||
@ -975,6 +1015,77 @@ int mmc_read_buffer_capacity(struct burn_drive *d)
|
||||
}
|
||||
|
||||
|
||||
/* ts A61219 : learned much from dvd+rw-tools-7.0: plus_rw_format() */
|
||||
int mmc_format_unit(struct burn_drive *d)
|
||||
{
|
||||
struct buffer buf;
|
||||
struct command c;
|
||||
int ret;
|
||||
char msg[160],descr[80];
|
||||
|
||||
mmc_function_spy("mmc_format_unit");
|
||||
c.retry = 1;
|
||||
c.oplen = sizeof(MMC_FORMAT_UNIT);
|
||||
memcpy(c.opcode, MMC_FORMAT_UNIT, sizeof(MMC_FORMAT_UNIT));
|
||||
c.page = &buf;
|
||||
c.page->bytes = 12;
|
||||
c.page->sectors = 0;
|
||||
c.dir = TO_DRIVE;
|
||||
memset(c.page->data, 0, c.page->bytes);
|
||||
|
||||
descr[0] = 0;
|
||||
if (d->current_profile == 0x1a) { /* DVD+RW */
|
||||
c.page->data[1] = 0x02; /* Immed */
|
||||
c.page->data[3] = 8; /* Format descriptor length */
|
||||
/* mmc5r03c.pdf , 6.5.4.2.14 */
|
||||
c.page->data[8] = 0x26 << 2; /* Format type */
|
||||
memset(c.page->data + 4, 0xff, 4); /* maximum blocksize */
|
||||
if (d->bg_format_status == 1) /* is partly formatted */
|
||||
c.page->data[11] = 1; /* Restart bit */
|
||||
else if(d->bg_format_status == 2) { /* format in progress */
|
||||
strcpy(msg,"FORMAT UNIT ignored. Already in progress");
|
||||
libdax_msgs_submit(libdax_messenger, d->global_index,
|
||||
0x00020120,
|
||||
LIBDAX_MSGS_SEV_NOTE, LIBDAX_MSGS_PRIO_HIGH,
|
||||
msg, 0,0);
|
||||
}
|
||||
sprintf(descr, "DVD+RW, BGFS %d",
|
||||
d->bg_format_status);
|
||||
} else {
|
||||
|
||||
/* >>> other formattable types to come */
|
||||
|
||||
sprintf(msg, "Unsuitable media detected. Profile %4.4Xh %s",
|
||||
d->current_profile, d->current_profile_text);
|
||||
libdax_msgs_submit(libdax_messenger, d->global_index,
|
||||
0x0002011e,
|
||||
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
||||
msg, 0,0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
d->issue_command(d, &c);
|
||||
if (c.error) {
|
||||
if (c.sense[2]!=0) {
|
||||
sprintf(msg,
|
||||
"SCSI error on format_unit(%s): key=%X asc=%2.2Xh ascq=%2.2Xh",
|
||||
descr,
|
||||
c.sense[2],c.sense[12],c.sense[13]);
|
||||
libdax_msgs_submit(libdax_messenger, d->global_index,
|
||||
0x00020122,
|
||||
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
|
||||
msg, 0, 0);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (ret = 0; ret <= 0 ;)
|
||||
ret = spc_test_unit_ready(d);
|
||||
mmc_sync_cache(d);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* ts A61021 : the mmc specific part of sg.c:enumerate_common()
|
||||
*/
|
||||
int mmc_setup_drive(struct burn_drive *d)
|
||||
@ -993,6 +1104,7 @@ int mmc_setup_drive(struct burn_drive *d)
|
||||
d->close_session = mmc_close_session;
|
||||
d->close_track_session = mmc_close;
|
||||
d->read_buffer_capacity = mmc_read_buffer_capacity;
|
||||
d->format_unit = mmc_format_unit;
|
||||
|
||||
/* ts A61020 */
|
||||
d->start_lba = -2000000000;
|
||||
@ -1003,6 +1115,8 @@ int mmc_setup_drive(struct burn_drive *d)
|
||||
d->current_profile = -1;
|
||||
d->current_profile_text[0] = 0;
|
||||
d->current_is_cd_profile = 0;
|
||||
d->current_is_supported_profile = 0;
|
||||
d->bg_format_status = -1;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
@ -32,6 +32,7 @@ struct burn_write_opts *burn_write_opts_new(struct burn_drive *drive)
|
||||
opts->simulate = 0;
|
||||
opts->underrun_proof = drive->mdata->underrun_proof;
|
||||
opts->perform_opc = 1;
|
||||
opts->obs = -1;
|
||||
opts->has_mediacatalog = 0;
|
||||
opts->format = BURN_CDROM;
|
||||
opts->multi = 0;
|
||||
|
@ -32,6 +32,11 @@ struct burn_write_opts
|
||||
/** Perform calibration of the drive's laser before beginning the
|
||||
write. */
|
||||
unsigned int perform_opc:1;
|
||||
|
||||
/* ts A61219 : Output block size to trigger buffer flush if hit.
|
||||
-1 with CD, 32 kB with DVD */
|
||||
int obs;
|
||||
|
||||
/** A disc can have a media catalog number */
|
||||
int has_mediacatalog;
|
||||
unsigned char mediacatalog[13];
|
||||
|
@ -217,7 +217,8 @@ static unsigned char *get_sector(struct burn_write_opts *opts,
|
||||
return NULL;
|
||||
seclen += burn_subcode_length(outmode);
|
||||
|
||||
if (out->bytes + (seclen) >= BUFFER_SIZE) {
|
||||
/* ts A61219 : opts->obs is eventually a 32k trigger for DVD */
|
||||
if (out->bytes + (seclen) > BUFFER_SIZE || out->bytes == opts->obs) {
|
||||
int err;
|
||||
err = d->write(d, d->nwa, out);
|
||||
if (err == BE_CANCELLED)
|
||||
@ -642,7 +643,10 @@ int sector_data(struct burn_write_opts *o, struct burn_track *t, int psub)
|
||||
return 2;
|
||||
}
|
||||
|
||||
if (!t->source->read_sub)
|
||||
/* ts A61219 : allow track without .entry */
|
||||
if (t->entry == NULL)
|
||||
;
|
||||
else if (!t->source->read_sub)
|
||||
subcode_user(o, subs, t->entry->point,
|
||||
t->entry->control, 1, &t->isrc, psub);
|
||||
else if (!t->source->read_sub(t->source, subs, 96))
|
||||
|
@ -36,7 +36,12 @@ struct params
|
||||
|
||||
struct buffer
|
||||
{
|
||||
unsigned char data[BUFFER_SIZE];
|
||||
/* ts A61219:
|
||||
Added 4096 bytes reserve against possible buffer overflows.
|
||||
(Changed in sector.c buffer flush test from >= to > BUFFER_SIZE .
|
||||
This can at most cause a 1 sector overlap. Sometimes an offset
|
||||
of 16 byte is applied to the output data (in some RAW mode). ) */
|
||||
unsigned char data[BUFFER_SIZE + 4096];
|
||||
int sectors;
|
||||
int bytes;
|
||||
};
|
||||
@ -124,6 +129,11 @@ struct burn_drive
|
||||
int current_profile;
|
||||
char current_profile_text[80];
|
||||
int current_is_cd_profile;
|
||||
int current_is_supported_profile;
|
||||
|
||||
/* ts A61218 from 46h GET CONFIGURATION */
|
||||
int bg_format_status; /* 0=needs format start, 1=needs format restart*/
|
||||
|
||||
|
||||
volatile int released;
|
||||
|
||||
@ -206,6 +216,9 @@ struct burn_drive
|
||||
/* ts A61023 : get size and free space of drive buffer */
|
||||
int (*read_buffer_capacity) (struct burn_drive *d);
|
||||
|
||||
/* ts A61220 : format media (e.g. DVD+RW) */
|
||||
int (*format_unit) (struct burn_drive *d);
|
||||
|
||||
};
|
||||
|
||||
/* end of generic 'drive' data structures */
|
||||
|
333
libburn/write.c
333
libburn/write.c
@ -580,6 +580,30 @@ ex:;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* ts A61218 : outsourced from burn_write_track() */
|
||||
int burn_disc_init_track_status(struct burn_write_opts *o,
|
||||
struct burn_session *s, int tnum)
|
||||
{
|
||||
struct burn_drive *d = o->drive;
|
||||
int sectors;
|
||||
|
||||
/* ts A61102 */
|
||||
d->busy = BURN_DRIVE_WRITING;
|
||||
|
||||
/* Update progress */
|
||||
d->progress.start_sector = d->nwa;
|
||||
d->progress.sectors = sectors;
|
||||
d->progress.sector = 0;
|
||||
|
||||
/* ts A60831: added tnum-line, extended print message on proposal
|
||||
by bonfire-app@wanadoo.fr in http://libburn.pykix.org/ticket/58 */
|
||||
d->progress.track = tnum;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int burn_write_track(struct burn_write_opts *o, struct burn_session *s,
|
||||
int tnum)
|
||||
{
|
||||
@ -637,20 +661,10 @@ int burn_write_track(struct burn_write_opts *o, struct burn_session *s,
|
||||
|
||||
/* user data */
|
||||
|
||||
/* ts A61102 */
|
||||
d->busy = BURN_DRIVE_WRITING;
|
||||
|
||||
sectors = burn_track_get_sectors(t);
|
||||
open_ended = burn_track_is_open_ended(t);
|
||||
|
||||
/* Update progress */
|
||||
d->progress.start_sector = d->nwa;
|
||||
d->progress.sectors = sectors;
|
||||
d->progress.sector = 0;
|
||||
|
||||
/* ts A60831: added tnum-line, extended print message on proposal
|
||||
by bonfire-app@wanadoo.fr in http://libburn.pykix.org/ticket/58 */
|
||||
d->progress.track = tnum;
|
||||
burn_disc_init_track_status(o, s, tnum);
|
||||
|
||||
burn_print(12, "track %d is %d sectors long\n", tnum, sectors);
|
||||
|
||||
@ -761,47 +775,12 @@ bad_track_mode_found:;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void burn_disc_write_sync(struct burn_write_opts *o, struct burn_disc *disc)
|
||||
|
||||
/* ts A61218 : outsourced from burn_disc_write_sync() */
|
||||
int burn_disc_init_write_status(struct burn_write_opts *o,
|
||||
struct burn_disc *disc)
|
||||
{
|
||||
struct cue_sheet *sheet;
|
||||
struct burn_drive *d = o->drive;
|
||||
struct buffer buf;
|
||||
struct burn_track *lt;
|
||||
int first = 1, i, ret, lba, nwa = 0;
|
||||
char msg[80];
|
||||
|
||||
/* ts A60924 : libburn/message.c gets obsoleted
|
||||
burn_message_clear_queue();
|
||||
*/
|
||||
|
||||
burn_print(1, "sync write of %d sessions\n", disc->sessions);
|
||||
d->buffer = &buf;
|
||||
memset(d->buffer, 0, sizeof(struct buffer));
|
||||
|
||||
d->rlba = -150;
|
||||
|
||||
d->toc_temp = 9;
|
||||
|
||||
/* Apparently some drives require this command to be sent, and a few drives
|
||||
return crap. so we send the command, then ignore the result.
|
||||
*/
|
||||
/* ts A61107 : moved up send_write_parameters because LG GSA-4082B
|
||||
seems to dislike get_nwa() in advance */
|
||||
d->alba = d->start_lba; /* ts A61114: this looks senseless */
|
||||
d->nwa = d->alba;
|
||||
if (o->write_type == BURN_WRITE_TAO) {
|
||||
nwa = 0; /* get_nwa() will be called in burn_track() */
|
||||
} else {
|
||||
|
||||
d->send_write_parameters(d, o);
|
||||
|
||||
ret = d->get_nwa(d, -1, &lba, &nwa);
|
||||
sprintf(msg, "Inquired nwa: %d (ret=%d)", nwa, ret);
|
||||
libdax_msgs_submit(libdax_messenger, d->global_index,
|
||||
0x00000002,
|
||||
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_ZERO,
|
||||
msg,0,0);
|
||||
}
|
||||
|
||||
/* init progress before showing the state */
|
||||
d->progress.session = 0;
|
||||
@ -825,6 +804,259 @@ return crap. so we send the command, then ignore the result.
|
||||
|
||||
d->busy = BURN_DRIVE_WRITING;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* ts A61218 */
|
||||
int burn_dvd_write_track(struct burn_write_opts *o,
|
||||
struct burn_session *s, int tnum)
|
||||
{
|
||||
struct burn_track *t = s->track[tnum];
|
||||
struct burn_drive *d = o->drive;
|
||||
struct buffer *out = d->buffer;
|
||||
int sectors;
|
||||
int i, open_ended = 0, ret= 0;
|
||||
|
||||
sectors = burn_track_get_sectors(t);
|
||||
open_ended = burn_track_is_open_ended(t);
|
||||
|
||||
/* >>> any type specific track preparations */;
|
||||
|
||||
burn_disc_init_track_status(o, s, tnum);
|
||||
for (i = 0; open_ended || i < sectors; i++) {
|
||||
|
||||
/* From time to time inquire drive buffer */
|
||||
if ((i%256)==0)
|
||||
d->read_buffer_capacity(d);
|
||||
|
||||
/* transact a (CD sized) sector */
|
||||
if (!sector_data(o, t, 0))
|
||||
{ ret = 0; goto ex; }
|
||||
|
||||
if (open_ended) {
|
||||
d->progress.sectors = sectors = i;
|
||||
if (burn_track_is_data_done(t))
|
||||
break;
|
||||
}
|
||||
|
||||
/* update current progress */
|
||||
d->progress.sector++;
|
||||
}
|
||||
|
||||
/* Pad up buffer to next full 32 kB */
|
||||
if (out->bytes > 0 && out->bytes < o->obs) {
|
||||
memset(out->data + out->bytes, 0, o->obs - out->bytes);
|
||||
out->sectors += (o->obs - out->bytes) / 2048;
|
||||
out->bytes = o->obs;
|
||||
}
|
||||
ret = burn_write_flush(o, t);
|
||||
if (ret <= 0)
|
||||
goto ex;
|
||||
|
||||
/* >>> any normal track finalizing */;
|
||||
|
||||
ret = 1;
|
||||
ex:;
|
||||
if (ret<=0) {
|
||||
/* >>> any unnormal track finalizing */;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* ts A61219 */
|
||||
int burn_disc_close_session_dvd_plus_rw(struct burn_write_opts *o,
|
||||
struct burn_session *s)
|
||||
{
|
||||
struct burn_drive *d = o->drive;
|
||||
|
||||
/* This seems to be a quick end : "if (!dvd_compat)" */
|
||||
/* >>> Stop de-icing (ongoing background format) quickly
|
||||
by mmc_close() i(but with opcode[2]=0).
|
||||
Wait for unit to get ready.
|
||||
return 1;
|
||||
*/
|
||||
/* Else: end eventual background format in a "DVD-RO" compatible way */
|
||||
d->close_track_session(d, 1, 0); /* same as CLOSE SESSION for CD */
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* ts A61218 */
|
||||
int burn_dvd_write_session(struct burn_write_opts *o,
|
||||
struct burn_session *s)
|
||||
{
|
||||
int i,ret;
|
||||
struct burn_drive *d = o->drive;
|
||||
|
||||
for (i = 0; i < s->tracks; i++) {
|
||||
ret = burn_dvd_write_track(o, s, i);
|
||||
if (ret <= 0)
|
||||
break;
|
||||
}
|
||||
if (strcmp(d->current_profile_text,"DVD+RW")==0) {
|
||||
ret = burn_disc_close_session_dvd_plus_rw(o, s);
|
||||
if (ret <= 0)
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* ts A61218 : learned much from dvd+rw-tools-7.0/growisofs_mmc.cpp */
|
||||
int burn_disc_setup_dvd_plus_rw(struct burn_write_opts *o,
|
||||
struct burn_disc *disc)
|
||||
{
|
||||
struct burn_drive *d = o->drive;
|
||||
int ret;
|
||||
|
||||
fprintf(stderr, "LIBBURN_DEBUG: d->bg_format_status= %d\n",
|
||||
d->bg_format_status);
|
||||
|
||||
if (d->bg_format_status==0 || d->bg_format_status==1) {
|
||||
/* start or re-start dvd_plus_rw formatting */
|
||||
ret = d->format_unit(d);
|
||||
|
||||
fprintf(stderr, "LIBBURN_DEBUG: format_unit() = %d\n", ret);
|
||||
|
||||
if (ret <= 0)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* >>> Set speed */;
|
||||
|
||||
/* >>> perform OPC if needed */;
|
||||
|
||||
d->nwa = 0;
|
||||
/* >>> d->get_nwa() (default to 0) */;
|
||||
|
||||
/* >>> ? what else ? */;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* ts A61218 */
|
||||
int burn_dvd_write_sync(struct burn_write_opts *o,
|
||||
struct burn_disc *disc)
|
||||
{
|
||||
int i, ret;
|
||||
struct burn_drive *d = o->drive;
|
||||
char msg[160];
|
||||
|
||||
if (strcmp(d->current_profile_text,"DVD+RW")==0) {
|
||||
|
||||
if (disc->sessions!=1 || disc->session[0]->tracks>1) {
|
||||
sprintf(msg,
|
||||
"Burning of DVD+RW is restricted to a single track");
|
||||
libdax_msgs_submit(libdax_messenger, d->global_index,
|
||||
0x0002011f,
|
||||
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
||||
msg, 0,0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = burn_disc_setup_dvd_plus_rw(o, disc);
|
||||
if (ret <= 0) {
|
||||
sprintf(msg,
|
||||
"Write preparation setup failed for DVD+RW");
|
||||
libdax_msgs_submit(libdax_messenger, d->global_index,
|
||||
0x00020121,
|
||||
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
|
||||
msg, 0,0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
} else {
|
||||
sprintf(msg, "Unsuitable media detected. Profile %4.4Xh %s",
|
||||
d->current_profile, d->current_profile_text);
|
||||
libdax_msgs_submit(libdax_messenger, d->global_index,
|
||||
0x0002011e,
|
||||
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
||||
msg, 0,0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
o->obs = 32*1024; /* buffer flush trigger for sector.c:get_sector() */
|
||||
|
||||
burn_disc_init_write_status(o, disc);
|
||||
for (i = 0; i < disc->sessions; i++) {
|
||||
/* update progress */
|
||||
d->progress.session = i;
|
||||
d->progress.tracks = disc->session[i]->tracks;
|
||||
|
||||
ret = burn_dvd_write_session(o, disc->session[i]);
|
||||
if (ret <= 0)
|
||||
goto ex;
|
||||
}
|
||||
|
||||
/* >>> eventual normal finalization measures */
|
||||
|
||||
ret = 1;
|
||||
ex:;
|
||||
|
||||
/* >>> eventual emergency finalization measures */
|
||||
|
||||
/* update media state records */
|
||||
burn_drive_mark_unready(d);
|
||||
burn_drive_inquire_media(d);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
void burn_disc_write_sync(struct burn_write_opts *o, struct burn_disc *disc)
|
||||
{
|
||||
struct cue_sheet *sheet;
|
||||
struct burn_drive *d = o->drive;
|
||||
struct buffer buf;
|
||||
struct burn_track *lt;
|
||||
int first = 1, i, ret, lba, nwa = 0;
|
||||
char msg[80];
|
||||
|
||||
/* ts A60924 : libburn/message.c gets obsoleted
|
||||
burn_message_clear_queue();
|
||||
*/
|
||||
|
||||
d->buffer = &buf;
|
||||
memset(d->buffer, 0, sizeof(struct buffer));
|
||||
d->rlba = -150;
|
||||
d->toc_temp = 9;
|
||||
|
||||
/* ts A61218 */
|
||||
if (! d->current_is_cd_profile) {
|
||||
ret = burn_dvd_write_sync(o, disc);
|
||||
if (ret <= 0)
|
||||
goto fail_wo_sync;
|
||||
return;
|
||||
}
|
||||
|
||||
burn_print(1, "sync write of %d CD sessions\n", disc->sessions);
|
||||
|
||||
/* Apparently some drives require this command to be sent, and a few drives
|
||||
return crap. so we send the command, then ignore the result.
|
||||
*/
|
||||
/* ts A61107 : moved up send_write_parameters because LG GSA-4082B
|
||||
seems to dislike get_nwa() in advance */
|
||||
d->alba = d->start_lba; /* ts A61114: this looks senseless */
|
||||
d->nwa = d->alba;
|
||||
if (o->write_type == BURN_WRITE_TAO) {
|
||||
nwa = 0; /* get_nwa() will be called in burn_track() */
|
||||
} else {
|
||||
|
||||
d->send_write_parameters(d, o);
|
||||
|
||||
ret = d->get_nwa(d, -1, &lba, &nwa);
|
||||
sprintf(msg, "Inquired nwa: %d (ret=%d)", nwa, ret);
|
||||
libdax_msgs_submit(libdax_messenger, d->global_index,
|
||||
0x00000002,
|
||||
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_ZERO,
|
||||
msg,0,0);
|
||||
}
|
||||
|
||||
burn_disc_init_write_status(o, disc);
|
||||
|
||||
for (i = 0; i < disc->sessions; i++) {
|
||||
/* update progress */
|
||||
d->progress.session = i;
|
||||
@ -932,6 +1164,7 @@ return crap. so we send the command, then ignore the result.
|
||||
|
||||
fail:
|
||||
d->sync_cache(d);
|
||||
fail_wo_sync:;
|
||||
burn_print(1, "done - failed\n");
|
||||
libdax_msgs_submit(libdax_messenger, d->global_index, 0x0002010b,
|
||||
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
|
||||
|
Loading…
Reference in New Issue
Block a user