|
|
@ -481,10 +481,11 @@ int burn_fifo_source_shoveller(struct burn_source *source, int flag) |
|
|
|
|
|
|
|
int burn_fifo_cancel(struct burn_source *source) |
|
|
|
{ |
|
|
|
int ret; |
|
|
|
struct burn_source_fifo *fs = source->data; |
|
|
|
|
|
|
|
burn_source_cancel(fs->inp); |
|
|
|
return(1); |
|
|
|
ret = burn_source_cancel(fs->inp); |
|
|
|
return ret; |
|
|
|
} |
|
|
|
|
|
|
|
/* |
|
|
@ -747,3 +748,162 @@ int burn_fifo_fill(struct burn_source *source, int bufsize, int flag) |
|
|
|
1 | ((flag & 1) << 1)); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/* ----------------------------- Offset source ----------------------------- */ |
|
|
|
/* ts B00922 */ |
|
|
|
|
|
|
|
static void offst_free(struct burn_source *source); |
|
|
|
|
|
|
|
static struct burn_source_offst *offst_auth(struct burn_source *source) |
|
|
|
{ |
|
|
|
if (source->free_data != offst_free) { |
|
|
|
libdax_msgs_submit(libdax_messenger, -1, 0x0002017a, |
|
|
|
LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH, |
|
|
|
"Expected offset source object as parameter", |
|
|
|
0, 0); |
|
|
|
return NULL; |
|
|
|
} |
|
|
|
return (struct burn_source_offst *) source->data; |
|
|
|
} |
|
|
|
|
|
|
|
static off_t offst_get_size(struct burn_source *source) |
|
|
|
{ |
|
|
|
struct burn_source_offst *fs; |
|
|
|
|
|
|
|
if ((fs = offst_auth(source)) == NULL) |
|
|
|
return (off_t) 0; |
|
|
|
return fs->size; |
|
|
|
} |
|
|
|
|
|
|
|
static int offst_set_size(struct burn_source *source, off_t size) |
|
|
|
{ |
|
|
|
struct burn_source_offst *fs; |
|
|
|
|
|
|
|
if ((fs = offst_auth(source)) == NULL) |
|
|
|
return 0; |
|
|
|
fs->size = size; |
|
|
|
return 1; |
|
|
|
} |
|
|
|
|
|
|
|
static void offst_free(struct burn_source *source) |
|
|
|
{ |
|
|
|
struct burn_source_offst *fs; |
|
|
|
|
|
|
|
if ((fs = offst_auth(source)) == NULL) |
|
|
|
return; |
|
|
|
if (fs->prev != NULL) |
|
|
|
offst_auth(fs->prev)->next = fs->next; |
|
|
|
if (fs->next != NULL) |
|
|
|
offst_auth(fs->next)->prev = fs->prev; |
|
|
|
if (fs->inp != NULL) |
|
|
|
burn_source_free(fs->inp); /* i.e. decrement refcount */ |
|
|
|
free(source->data); |
|
|
|
} |
|
|
|
|
|
|
|
static int offst_read(struct burn_source *source, unsigned char *buffer, |
|
|
|
int size) |
|
|
|
{ |
|
|
|
int ret, to_read, todo; |
|
|
|
struct burn_source_offst *fs; |
|
|
|
|
|
|
|
if ((fs = offst_auth(source)) == NULL) |
|
|
|
return -1; |
|
|
|
|
|
|
|
/* Eventually skip bytes up to start position */; |
|
|
|
if (!fs->running) { |
|
|
|
if (fs->prev != NULL) |
|
|
|
fs->pos = offst_auth(fs->prev)->pos; |
|
|
|
fs->running= 1; |
|
|
|
} |
|
|
|
if(fs->pos < fs->start) { |
|
|
|
todo = fs->start - fs->pos; |
|
|
|
while (todo > 0) { |
|
|
|
to_read = todo; |
|
|
|
if (to_read > size) |
|
|
|
to_read = size; |
|
|
|
ret = burn_source_read(fs->inp, buffer, to_read); |
|
|
|
if (ret <= 0) |
|
|
|
return ret; |
|
|
|
todo -= ret; |
|
|
|
fs->pos += ret; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/* Produce EOF if source size is exhausted. |
|
|
|
burn_source delivers no incomplete sector buffers. |
|
|
|
*/ |
|
|
|
if (fs->pos + size > fs->start + fs->size) |
|
|
|
return 0; |
|
|
|
|
|
|
|
/* Read payload */ |
|
|
|
ret = burn_source_read(fs->inp, buffer, size); |
|
|
|
if (ret > 0) |
|
|
|
fs->pos += ret; |
|
|
|
return ret; |
|
|
|
} |
|
|
|
|
|
|
|
static int offst_cancel(struct burn_source *source) |
|
|
|
{ |
|
|
|
int ret; |
|
|
|
struct burn_source_offst *fs; |
|
|
|
|
|
|
|
if ((fs = offst_auth(source)) == NULL) |
|
|
|
return -1; |
|
|
|
ret = burn_source_cancel(fs->inp); |
|
|
|
return ret; |
|
|
|
} |
|
|
|
|
|
|
|
struct burn_source *burn_offst_source_new( |
|
|
|
struct burn_source *inp, struct burn_source *prev, |
|
|
|
off_t start, off_t size, int flag) |
|
|
|
{ |
|
|
|
struct burn_source *src; |
|
|
|
struct burn_source_offst *fs, *prev_fs = NULL; |
|
|
|
|
|
|
|
if (prev != NULL) |
|
|
|
if ((prev_fs = offst_auth(prev)) == NULL) |
|
|
|
return NULL; /* Not type burn_source_offst */ |
|
|
|
|
|
|
|
fs = calloc(1, sizeof(struct burn_source_offst)); |
|
|
|
if (fs == NULL) |
|
|
|
return NULL; |
|
|
|
src = burn_source_new(); |
|
|
|
if (src == NULL) { |
|
|
|
free((char *) fs); |
|
|
|
return NULL; |
|
|
|
} |
|
|
|
src->read = NULL; |
|
|
|
src->read_sub = NULL; |
|
|
|
src->get_size = offst_get_size; |
|
|
|
src->set_size = offst_set_size; |
|
|
|
src->free_data = offst_free; |
|
|
|
src->data = fs; |
|
|
|
src->version= 1; |
|
|
|
src->read_xt = offst_read; |
|
|
|
src->cancel= offst_cancel; |
|
|
|
fs->inp = inp; |
|
|
|
fs->prev = prev; |
|
|
|
fs->next = NULL; |
|
|
|
if (prev != NULL) { |
|
|
|
if (prev_fs->next != NULL) { |
|
|
|
offst_auth(prev_fs->next)->prev = src; |
|
|
|
fs->next = prev_fs->next; |
|
|
|
} |
|
|
|
prev_fs->next = src; |
|
|
|
if (prev_fs->start + prev_fs->size > start) { |
|
|
|
libdax_msgs_submit(libdax_messenger, -1, 0x00020179, |
|
|
|
LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH, |
|
|
|
"Offset source start address is before end of previous source", |
|
|
|
0, 0); |
|
|
|
return NULL; |
|
|
|
} |
|
|
|
} |
|
|
|
fs->start = start; |
|
|
|
fs->size = size; |
|
|
|
fs->running = 0; |
|
|
|
fs->pos = 0; |
|
|
|
inp->refcount++; /* make sure inp lives longer than src */ |
|
|
|
|
|
|
|
return src; |
|
|
|
} |
|
|
|
|