- return sparse_header;
-}
-
-static int sparse_parse_fill_chunk(sparse_header_t *sparse,
- chunk_header_t *chunk)
-{
- unsigned int chunk_data_sz = sparse_get_chunk_data_size(sparse, chunk);
-
- if (chunk_data_sz != sizeof(uint32_t))
- return -EINVAL;
-
- return 0;
-}
-
-static int sparse_parse_raw_chunk(sparse_header_t *sparse,
- chunk_header_t *chunk)
-{
- unsigned int chunk_data_sz = sparse_get_chunk_data_size(sparse, chunk);
-
- /* Check if the data size is a multiple of the main block size */
- if (chunk_data_sz % sparse->blk_sz)
- return -EINVAL;
-
- /* Check that the chunk size is consistent */
- if ((chunk_data_sz / sparse->blk_sz) != chunk->chunk_sz)
- return -EINVAL;
-
- return 0;
-}
-
-static chunk_header_t *sparse_parse_chunk(sparse_header_t *sparse,
- void **image)
-{
- chunk_header_t *chunk = (chunk_header_t *) *image;
- int ret;
-
- debug("=== Chunk Header ===\n");
- debug("chunk_type: 0x%x\n", chunk->chunk_type);
- debug("chunk_data_sz: 0x%x\n", chunk->chunk_sz);
- debug("total_size: 0x%x\n", chunk->total_sz);
-
- switch (chunk->chunk_type) {
- case CHUNK_TYPE_RAW:
- ret = sparse_parse_raw_chunk(sparse, chunk);
- if (ret)
- return NULL;
- break;
-
- case CHUNK_TYPE_FILL:
- ret = sparse_parse_fill_chunk(sparse, chunk);
- if (ret)
- return NULL;
- break;
-
- case CHUNK_TYPE_DONT_CARE:
- case CHUNK_TYPE_CRC32:
- debug("Ignoring chunk\n");
- break;
-
- default:
- printf("%s: Unknown chunk type: %x\n", __func__,
- chunk->chunk_type);
- return NULL;
- }
-
- *image += sparse->chunk_hdr_sz;
-
- return chunk;
-}
-
-static int sparse_get_fill_buffer(sparse_header_t *sparse,
- chunk_header_t *chunk,
- sparse_buffer_t *buffer,
- unsigned int blk_sz,
- void *data)
-{
- int i;
-
- buffer->type = CHUNK_TYPE_FILL;
-
- /*
- * We create a buffer of one block, and ask it to be
- * repeated as many times as needed.
- */
- buffer->length = blk_sz;
- buffer->repeat = (chunk->chunk_sz * sparse->blk_sz) / blk_sz;
-
- buffer->data = memalign(ARCH_DMA_MINALIGN,
- ROUNDUP(blk_sz,
- ARCH_DMA_MINALIGN));
- if (!buffer->data)
- return -ENOMEM;
-
- for (i = 0; i < (buffer->length / sizeof(uint32_t)); i++)
- ((uint32_t *)buffer->data)[i] = *(uint32_t *)(data);
-
- return 0;
-}
-
-static int sparse_get_raw_buffer(sparse_header_t *sparse,
- chunk_header_t *chunk,
- sparse_buffer_t *buffer,
- unsigned int blk_sz,
- void *data)
-{
- unsigned int chunk_data_sz = sparse_get_chunk_data_size(sparse, chunk);
-
- buffer->type = CHUNK_TYPE_RAW;
- buffer->length = chunk_data_sz;
- buffer->data = data;
- buffer->repeat = 1;
-
- return 0;
-}
-
-static sparse_buffer_t *sparse_get_data_buffer(sparse_header_t *sparse,
- chunk_header_t *chunk,
- unsigned int blk_sz,
- void **image)
-{
- unsigned int chunk_data_sz = sparse_get_chunk_data_size(sparse, chunk);
- sparse_buffer_t *buffer;
- void *data = *image;
- int ret;
-
- *image += chunk_data_sz;
-
- if (!sparse_chunk_has_buffer(chunk))
- return NULL;
-
- buffer = calloc(sizeof(sparse_buffer_t), 1);
- if (!buffer)
- return NULL;
-
- switch (chunk->chunk_type) {
- case CHUNK_TYPE_RAW:
- ret = sparse_get_raw_buffer(sparse, chunk, buffer, blk_sz,
- data);
- if (ret)
- return NULL;
- break;
-
- case CHUNK_TYPE_FILL:
- ret = sparse_get_fill_buffer(sparse, chunk, buffer, blk_sz,
- data);
- if (ret)
- return NULL;
- break;
-
- default:
- return NULL;
- }
-
- debug("=== Buffer ===\n");
- debug("length: 0x%x\n", buffer->length);
- debug("repeat: 0x%x\n", buffer->repeat);
- debug("type: 0x%x\n", buffer->type);
- debug("data: 0x%p\n", buffer->data);
-
- return buffer;
-}
-
-static void sparse_put_data_buffer(sparse_buffer_t *buffer)
-{
- if (buffer->type == CHUNK_TYPE_FILL)
- free(buffer->data);
-
- free(buffer);
-}
-
-int store_sparse_image(sparse_storage_t *storage, void *storage_priv,
- unsigned int session_id, void *data)
-{
- unsigned int chunk, offset;
- sparse_header_t *sparse_header;
- chunk_header_t *chunk_header;
- sparse_buffer_t *buffer;
- uint32_t start;
- uint32_t total_blocks = 0;
- int i;
-
- debug("=== Storage ===\n");
- debug("name: %s\n", storage->name);
- debug("block_size: 0x%x\n", storage->block_sz);
- debug("start: 0x%x\n", storage->start);
- debug("size: 0x%x\n", storage->size);
- debug("write: 0x%p\n", storage->write);
- debug("priv: 0x%p\n", storage_priv);
-
- sparse_header = sparse_parse_header(&data);
- if (!sparse_header) {
- printf("sparse header issue\n");
- return -EINVAL;
- }
-