New API function burn_read_data()
This commit is contained in:
parent
12b6a07e9f
commit
d21697b289
@ -1 +1 @@
|
|||||||
#define Cdrskin_timestamP "2007.08.12.095623"
|
#define Cdrskin_timestamP "2007.08.12.152937"
|
||||||
|
@ -1061,6 +1061,9 @@ int burn_precheck_write(struct burn_write_opts *o, struct burn_disc *disc,
|
|||||||
Note: write_type BURN_WRITE_SAO is currently not capable of writing a mix
|
Note: write_type BURN_WRITE_SAO is currently not capable of writing a mix
|
||||||
of data and audio tracks. You must use BURN_WRITE_TAO for such sessions.
|
of data and audio tracks. You must use BURN_WRITE_TAO for such sessions.
|
||||||
To be set by burn_write_opts_set_write_type().
|
To be set by burn_write_opts_set_write_type().
|
||||||
|
Note: This function is not suitable for overwriting data in the middle of
|
||||||
|
a valid data area because it is allowed to append trailing data.
|
||||||
|
For exact random access overwriting use burn_random_access_write().
|
||||||
@param o The options for the writing operation.
|
@param o The options for the writing operation.
|
||||||
@param disc The struct burn_disc * that described the disc to be created
|
@param disc The struct burn_disc * that described the disc to be created
|
||||||
*/
|
*/
|
||||||
@ -1813,8 +1816,10 @@ typedef int (*burn_abort_handler_t)(void *handle, int signum, int flag);
|
|||||||
void burn_set_signal_handling(void *handle, burn_abort_handler_t handler,
|
void burn_set_signal_handling(void *handle, burn_abort_handler_t handler,
|
||||||
int mode);
|
int mode);
|
||||||
|
|
||||||
|
|
||||||
/* ts A70811 */
|
/* ts A70811 */
|
||||||
/** The drive must be grabbed successfully before calling this function. It
|
/** Write data in random access mode.
|
||||||
|
The drive must be grabbed successfully before calling this function which
|
||||||
circumvents usual libburn session processing and rather writes data without
|
circumvents usual libburn session processing and rather writes data without
|
||||||
preparations or finalizing. This will work only with overwriteable media
|
preparations or finalizing. This will work only with overwriteable media
|
||||||
which are also suitable for burn_write_opts_set_start_byte(). The same
|
which are also suitable for burn_write_opts_set_start_byte(). The same
|
||||||
@ -1843,6 +1848,29 @@ void burn_set_signal_handling(void *handle, burn_abort_handler_t handler,
|
|||||||
int burn_random_access_write(struct burn_drive *d, off_t byte_address,
|
int burn_random_access_write(struct burn_drive *d, off_t byte_address,
|
||||||
char *data, off_t data_count, int flag);
|
char *data, off_t data_count, int flag);
|
||||||
|
|
||||||
|
|
||||||
|
/* ts A70812 */
|
||||||
|
/** Read data in random access mode.
|
||||||
|
The drive must be grabbed successfully before calling this function.
|
||||||
|
With all currently supported drives and media the byte_address has to
|
||||||
|
be aligned to 2048 bytes. Only data tracks with 2048 bytes per sector
|
||||||
|
can be read this way. I.e. not CD-audio, not CD-video-stream ...
|
||||||
|
This is a synchronous call which returns only after the full read job
|
||||||
|
has ended (sucessfully or not). So it is wise not to read giant amounts
|
||||||
|
of data in a single call.
|
||||||
|
@param d The drive to which to write
|
||||||
|
@param byte_address The start address of the read in byte (aligned to 2048)
|
||||||
|
@param data A memory buffer capable of taking data_size bytes
|
||||||
|
@param data_size The amount of data to be read. This does not have to
|
||||||
|
be aligned to any block size.
|
||||||
|
@param data_count The amount of data actually read (interesting on error)
|
||||||
|
@param flag Bitfield for control purposes: (unused yet, submit 0)
|
||||||
|
@return 1=sucessful , <=0 an error occured
|
||||||
|
*/
|
||||||
|
int burn_read_data(struct burn_drive *d, off_t byte_address,
|
||||||
|
char data[], off_t data_size, off_t *data_count, int flag);
|
||||||
|
|
||||||
|
|
||||||
#ifndef DOXYGEN
|
#ifndef DOXYGEN
|
||||||
|
|
||||||
BURN_END_DECLS
|
BURN_END_DECLS
|
||||||
|
@ -374,6 +374,9 @@ Range "scdbackup" : 0x00020000 to 0x0002ffff
|
|||||||
0x00020140 (FATAL,HIGH) = Drive is busy on attempt to write random access
|
0x00020140 (FATAL,HIGH) = Drive is busy on attempt to write random access
|
||||||
0x00020141 (SORRY,HIGH) = Write data count not properly aligned
|
0x00020141 (SORRY,HIGH) = Write data count not properly aligned
|
||||||
0x00020142 (FATAL,HIGH) = Drive is not grabbed on random access write
|
0x00020142 (FATAL,HIGH) = Drive is not grabbed on random access write
|
||||||
|
0x00020143 (SORRY,HIGH) = Read start address not properly aligned
|
||||||
|
0x00020144 (SORRY,HIGH) = SCSI error on read
|
||||||
|
0x00020145 (FATAL,HIGH) = Drive is busy on attempt to read data
|
||||||
|
|
||||||
|
|
||||||
libdax_audioxtr:
|
libdax_audioxtr:
|
||||||
|
@ -165,6 +165,10 @@ static unsigned char MMC_READ_FORMAT_CAPACITIES[] =
|
|||||||
static unsigned char MMC_RESERVE_TRACK[] =
|
static unsigned char MMC_RESERVE_TRACK[] =
|
||||||
{ 0x53, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
{ 0x53, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
||||||
|
|
||||||
|
/* ts A70812 : Read data sectors (for types with 2048 bytes/sector only) */
|
||||||
|
static unsigned char MMC_READ_10[] =
|
||||||
|
{ 0x28, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
||||||
|
|
||||||
|
|
||||||
static int mmc_function_spy_do_tell = 0;
|
static int mmc_function_spy_do_tell = 0;
|
||||||
|
|
||||||
@ -2793,6 +2797,45 @@ int mmc_compose_mode_page_5(struct burn_drive *d,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* A70812 ts */
|
||||||
|
int mmc_read_10(struct burn_drive *d, int start,int amount, struct buffer *buf)
|
||||||
|
{
|
||||||
|
struct command c;
|
||||||
|
|
||||||
|
mmc_function_spy("mmc_read_10");
|
||||||
|
if (amount > BUFFER_SIZE / 2048)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
scsi_init_command(&c, MMC_READ_10, sizeof(MMC_READ_10));
|
||||||
|
c.dxfer_len = amount * 2048;
|
||||||
|
c.retry = 1;
|
||||||
|
mmc_int_to_four_char(c.opcode + 2, start);
|
||||||
|
c.opcode[7] = (amount >> 8) & 0xFF;
|
||||||
|
c.opcode[8] = amount & 0xFF;
|
||||||
|
c.page = buf;
|
||||||
|
c.page->bytes = 0;
|
||||||
|
c.page->sectors = 0;
|
||||||
|
c.dir = FROM_DRIVE;
|
||||||
|
d->issue_command(d, &c);
|
||||||
|
if (c.error) {
|
||||||
|
char msg[160];
|
||||||
|
printf(msg,
|
||||||
|
"SCSI error on read_10(%d,%d): key=%X asc=%2.2Xh ascq=%2.2Xh",
|
||||||
|
start, amount,
|
||||||
|
c.sense[2],c.sense[12],c.sense[13]);
|
||||||
|
libdax_msgs_submit(libdax_messenger, d->global_index,
|
||||||
|
0x00020144,
|
||||||
|
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
|
msg, 0, 0);
|
||||||
|
return BE_CANCELLED;
|
||||||
|
}
|
||||||
|
|
||||||
|
buf->sectors = amount;
|
||||||
|
buf->bytes = amount * 2048;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ts A61021 : the mmc specific part of sg.c:enumerate_common()
|
/* ts A61021 : the mmc specific part of sg.c:enumerate_common()
|
||||||
*/
|
*/
|
||||||
int mmc_setup_drive(struct burn_drive *d)
|
int mmc_setup_drive(struct burn_drive *d)
|
||||||
@ -2815,6 +2858,7 @@ int mmc_setup_drive(struct burn_drive *d)
|
|||||||
d->read_buffer_capacity = mmc_read_buffer_capacity;
|
d->read_buffer_capacity = mmc_read_buffer_capacity;
|
||||||
d->format_unit = mmc_format_unit;
|
d->format_unit = mmc_format_unit;
|
||||||
d->read_format_capacities = mmc_read_format_capacities;
|
d->read_format_capacities = mmc_read_format_capacities;
|
||||||
|
d->read_10 = mmc_read_10;
|
||||||
|
|
||||||
|
|
||||||
/* ts A70302 */
|
/* ts A70302 */
|
||||||
|
@ -68,6 +68,11 @@ int mmc_compose_mode_page_5(struct burn_drive *d,
|
|||||||
const struct burn_write_opts *o,
|
const struct burn_write_opts *o,
|
||||||
unsigned char *pd);
|
unsigned char *pd);
|
||||||
|
|
||||||
|
/* ts A70812 : return 0 = ok , return BE_CANCELLED = error occured */
|
||||||
|
int mmc_read_10(struct burn_drive *d, int start, int amount,
|
||||||
|
struct buffer *buf);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* mmc5r03c.pdf 4.3.4.4.1 d) "The maximum number of RZones is 2 302." */
|
/* mmc5r03c.pdf 4.3.4.4.1 d) "The maximum number of RZones is 2 302." */
|
||||||
#define BURN_MMC_FAKE_TOC_MAX_SIZE 2302
|
#define BURN_MMC_FAKE_TOC_MAX_SIZE 2302
|
||||||
|
@ -31,6 +31,12 @@
|
|||||||
#include "read.h"
|
#include "read.h"
|
||||||
#include "options.h"
|
#include "options.h"
|
||||||
|
|
||||||
|
/* ts A70812 */
|
||||||
|
#include "error.h"
|
||||||
|
#include "libdax_msgs.h"
|
||||||
|
extern struct libdax_msgs *libdax_messenger;
|
||||||
|
|
||||||
|
|
||||||
void burn_disc_read(struct burn_drive *d, const struct burn_read_opts *o)
|
void burn_disc_read(struct burn_drive *d, const struct burn_read_opts *o)
|
||||||
{
|
{
|
||||||
#if 0
|
#if 0
|
||||||
@ -280,3 +286,68 @@ static void flipq(unsigned char *sub)
|
|||||||
*(sub + 12 + 11) = ~*(sub + 12 + 11);
|
*(sub + 12 + 11) = ~*(sub + 12 + 11);
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/* ts A70812 : API function */
|
||||||
|
int burn_read_data(struct burn_drive *d, off_t byte_address,
|
||||||
|
char data[], off_t data_size, off_t *data_count, int flag)
|
||||||
|
{
|
||||||
|
int alignment = 2048, start, upto, chunksize, err, cpy_size;
|
||||||
|
char msg[81], *wpt;
|
||||||
|
struct buffer buf;
|
||||||
|
|
||||||
|
*data_count = 0;
|
||||||
|
if (d->released) {
|
||||||
|
libdax_msgs_submit(libdax_messenger,
|
||||||
|
d->global_index, 0x00020142,
|
||||||
|
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
|
"Drive is not grabbed on random access write", 0, 0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if ((byte_address % alignment) != 0) {
|
||||||
|
sprintf(msg,
|
||||||
|
"Read start address not properly aligned (%d bytes)",
|
||||||
|
alignment);
|
||||||
|
libdax_msgs_submit(libdax_messenger, d->global_index,
|
||||||
|
0x00020143,
|
||||||
|
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, 0x00020145,
|
||||||
|
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
|
"Drive is busy on attempt to read data", 0, 0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
d->busy = BURN_DRIVE_READING;
|
||||||
|
d->buffer = &buf;
|
||||||
|
|
||||||
|
start = byte_address / 2048;
|
||||||
|
upto = start + data_size / 2048;
|
||||||
|
if (data_size % 2048)
|
||||||
|
upto++;
|
||||||
|
wpt = data;
|
||||||
|
for (; start < upto; start += 16) {
|
||||||
|
chunksize = upto - start;
|
||||||
|
if (chunksize > 16) {
|
||||||
|
chunksize = 16;
|
||||||
|
cpy_size = 16 * 2048;
|
||||||
|
} else
|
||||||
|
cpy_size = data_size - *data_count;
|
||||||
|
err = d->read_10(d, start, chunksize, d->buffer);
|
||||||
|
if (err == BE_CANCELLED) {
|
||||||
|
d->busy = BURN_DRIVE_IDLE;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
memcpy(wpt, d->buffer->data, cpy_size);
|
||||||
|
wpt += cpy_size;
|
||||||
|
*data_count += cpy_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
d->buffer = NULL;
|
||||||
|
d->busy = BURN_DRIVE_IDLE;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
@ -320,6 +320,11 @@ struct burn_drive
|
|||||||
/* mmc5r03c.pdf 6.24 : get list of available formats */
|
/* mmc5r03c.pdf 6.24 : get list of available formats */
|
||||||
int (*read_format_capacities) (struct burn_drive *d, int top_wanted);
|
int (*read_format_capacities) (struct burn_drive *d, int top_wanted);
|
||||||
|
|
||||||
|
/* ts A70812 */
|
||||||
|
/* mmc5r03c.pdf 6.15 : read data sectors (start and amount in LBA) */
|
||||||
|
int (*read_10) (struct burn_drive *d, int start, int amount,
|
||||||
|
struct buffer *buf);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* end of generic 'drive' data structures */
|
/* end of generic 'drive' data structures */
|
||||||
|
@ -1970,9 +1970,9 @@ fail_wo_sync:;
|
|||||||
d->busy = BURN_DRIVE_IDLE;
|
d->busy = BURN_DRIVE_IDLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ts A70811 : API function */
|
||||||
int burn_random_access_write(struct burn_drive *d, off_t byte_address,
|
int burn_random_access_write(struct burn_drive *d, off_t byte_address,
|
||||||
char *data, off_t data_count, int flag)
|
char *data, off_t data_count, int flag)
|
||||||
{
|
{
|
||||||
int alignment = 0, start, upto, chunksize, err;
|
int alignment = 0, start, upto, chunksize, err;
|
||||||
char msg[81], *rpt;
|
char msg[81], *rpt;
|
||||||
@ -2051,6 +2051,7 @@ int burn_random_access_write(struct burn_drive *d, off_t byte_address,
|
|||||||
|
|
||||||
if (flag & 1)
|
if (flag & 1)
|
||||||
d->sync_cache(d);
|
d->sync_cache(d);
|
||||||
|
d->buffer = NULL;
|
||||||
d->busy = BURN_DRIVE_IDLE;
|
d->busy = BURN_DRIVE_IDLE;
|
||||||
return(1);
|
return(1);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user