New API function burn_read_data()

This commit is contained in:
Thomas Schmitt 2007-08-12 15:25:56 +00:00
parent 12b6a07e9f
commit d21697b289
8 changed files with 161 additions and 4 deletions

View File

@ -1 +1 @@
#define Cdrskin_timestamP "2007.08.12.095623" #define Cdrskin_timestamP "2007.08.12.152937"

View File

@ -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

View File

@ -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:

View File

@ -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 */

View File

@ -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

View File

@ -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;
}

View File

@ -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 */

View File

@ -1970,7 +1970,7 @@ 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)
{ {
@ -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);
} }