New API function burn_random_access_write()

This commit is contained in:
Thomas Schmitt 2007-08-11 20:16:57 +00:00
parent 6950ac8c42
commit cf0dd395f0
4 changed files with 121 additions and 9 deletions

View File

@ -1 +1 @@
#define Cdrskin_timestamP "2007.08.11.075330"
#define Cdrskin_timestamP "2007.08.11.202027"

View File

@ -1427,11 +1427,14 @@ void burn_write_opts_set_multi(struct burn_write_opts *opts, int multi);
/* ts A61222 */
/** Sets a start address for writing to media and write modes which allow to
choose this address at all (DVD+RW, DVD-RAM, formatted DVD-RW only for
choose this address at all (for now: DVD+RW, DVD-RAM, formatted DVD-RW).
now). The address is given in bytes. If it is not -1 then a write run
will fail if choice of start address is not supported or if the block
alignment of the address is not suitable for media and write mode.
(Alignment to 32 kB blocks is advised with DVD media.)
Alignment to 32 kB blocks is supposed to be safe with DVD media.
Call burn_disc_get_multi_caps() can obtain the necessary media info. See
resulting struct burn_multi_caps elements .start_adr , .start_alignment ,
.start_range_low , .start_range_high .
@param opts The write opts to change
@param value The address in bytes (-1 = start at default address)
*/
@ -1788,7 +1791,7 @@ int burn_msgs_obtain(char *minimum_severity,
/* ts A61002 */
/* The prototype of a handler function suitable for burn_set_abort_handling().
/** The prototype of a handler function suitable for burn_set_abort_handling().
Such a function has to return -2 if it does not want the process to
exit with value 1.
*/
@ -1810,6 +1813,34 @@ typedef int (*burn_abort_handler_t)(void *handle, int signum, int flag);
void burn_set_signal_handling(void *handle, burn_abort_handler_t handler,
int mode);
/* ts A70811 */
/** Circumvent usual libburn session processing and rather write data without
preparations or finalizing. This will work only with overwriteable media
which are also suitable for burn_write_opts_set_start_byte(). The same
address alignment restrictions as with this function apply. I.e. for DVD
it is best to align to 32 KiB blocks (= 16 LBA units). The amount of data
to be written is subject to the same media dependent alignment rules.
Again, 32 KiB is most safe.
Call burn_disc_get_multi_caps() can obtain the necessary media info. See
resulting struct burn_multi_caps elements .start_adr , .start_alignment ,
.start_range_low , .start_range_high .
Other than burn_disc_write() this is a synchronous call which returns
only after the write transaction has ended (sucessfully or not). So it is
wise not to transfer giant amounts of data in a single call.
@param d The drive to which to write
@param byte_address The start address of the write in byte
(1 LBA unit = 2048 bytes) (do respect media alignment)
@param data The bytes to be written
@param data_count The number of those bytes (do respect media alignment)
data_count == 0 is permitted (e.g. to flush the
drive buffer without further data transfer).
@param flag Bitfield for control purposes:
bit0 = flush the drive buffer after eventual writing
@return 1=sucessful , <=0 : number of tranfered bytes * -1
*/
int burn_random_access_write(struct burn_drive *d, off_t byte_address,
char *data, off_t data_count, int flag);
#ifndef DOXYGEN
BURN_END_DECLS

View File

@ -371,6 +371,8 @@ Range "scdbackup" : 0x00020000 to 0x0002ffff
0x0002013d (DEBUG,LOW) = Waiting for free buffer space takes long time
0x0002013e (SORRY,HIGH) = Timeout with waiting for free buffer. Now disabled
0x0002013f (DEBUG,LOW) = Reporting total time spent with waiting for buffer
0x00020140 (FATAL,HIGH) = Drive is busy on attempt to write random access
0x00020141 (SORRY,HIGH) = Write data count not properly aligned
libdax_audioxtr:

View File

@ -1523,7 +1523,7 @@ int burn_dvd_write_sync(struct burn_write_opts *o,
sprintf(msg,
"Write start address not properly aligned to 2048");
libdax_msgs_submit(libdax_messenger, d->global_index,
0x00020125,
0x00020126,
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
msg, 0, 0);
goto early_failure;
@ -1553,7 +1553,7 @@ int burn_dvd_write_sync(struct burn_write_opts *o,
sprintf(msg,
"Write start address not properly aligned to 32K");
libdax_msgs_submit(libdax_messenger, d->global_index,
0x00020125,
0x00020126,
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
msg, 0, 0);
goto early_failure;
@ -1636,7 +1636,7 @@ int burn_dvd_write_sync(struct burn_write_opts *o,
if (o->start_byte >= 0) {
sprintf(msg, "Write start address not supported");
libdax_msgs_submit(libdax_messenger, d->global_index,
0x00020124,
0x00020125,
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
msg, 0, 0);
goto early_failure;
@ -1969,3 +1969,82 @@ fail_wo_sync:;
d->cancel = 1;
d->busy = BURN_DRIVE_IDLE;
}
int burn_random_access_write(struct burn_drive *d, off_t byte_address,
char *data, off_t data_count, int flag)
{
int alignment = 0, start, upto, chunksize, err;
char msg[81], *rpt;
struct buffer buf;
if (d->current_profile == 0x12) /* DVD-RAM */
alignment = 2 * 1024;
if (d->current_profile == 0x13) /* DVD-RW restricted overwrite */
alignment = 32 * 1024;
if (d->current_profile == 0x1a) /* DVD+RW */
alignment = 2 * 1024;
if (alignment == 0) {
sprintf(msg, "Write start address not supported");
libdax_msgs_submit(libdax_messenger, d->global_index,
0x00020125,
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
"Write start address not supported", 0, 0);
return 0;
}
if ((byte_address % alignment) != 0) {
sprintf(msg,
"Write start address not properly aligned (%d bytes)",
alignment);
libdax_msgs_submit(libdax_messenger, d->global_index,
0x00020126,
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
msg, 0, 0);
return 0;
}
if ((data_count % alignment) != 0) {
sprintf(msg,
"Write data count not properly aligned (%ld bytes)",
(long) alignment);
libdax_msgs_submit(libdax_messenger, d->global_index,
0x00020141,
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
msg, 0, 0);
return 0;
}
if (d->busy != BURN_DRIVE_IDLE) {
libdax_msgs_submit(libdax_messenger,
d->global_index, 0x00020140,
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
"Drive is busy on attempt to write random access",0,0);
return 0;
}
d->busy = BURN_DRIVE_WRITING;
d->buffer = &buf;
start = byte_address / 2048;
upto = start + data_count / 2048;
rpt = data;
for (; start < upto; start += 16) {
chunksize = upto - start;
if (chunksize > 16)
chunksize = 16;
d->buffer->bytes = chunksize * 2048;
memcpy(d->buffer->data, rpt, d->buffer->bytes);
rpt += d->buffer->bytes;
d->buffer->sectors = chunksize;
d->nwa = start;
err = d->write(d, d->nwa, d->buffer);
if (err == BE_CANCELLED) {
d->busy = BURN_DRIVE_IDLE;
return (-(start * 2048 - byte_address));
}
}
if (flag & 1)
d->sync_cache(d);
d->busy = BURN_DRIVE_IDLE;
return(1);
}