blob: 16f2363ab1bfd73bb59c06ef61ed92a9f78c7f36 [file] [log] [blame]
Deepak Kodihalli6c2fa902017-05-01 06:36:02 -05001/*
2 * Mailbox Daemon Flash Helpers
3 *
4 * Copyright 2017 IBM
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 *
18 */
19
20#define _GNU_SOURCE
21#include <stdint.h>
22#include <stdlib.h>
23#include <syslog.h>
24#include <sys/types.h>
25#include <unistd.h>
26#include <errno.h>
27#include <mtd/mtd-abi.h>
28
29#include "mbox.h"
30#include "common.h"
31#include "mboxd_flash.h"
32
33#define CHUNKSIZE (64 * 1024)
34
35/*
36 * copy_flash() - Copy data from the flash device into a provided buffer
37 * @context: The mbox context pointer
38 * @offset: The flash offset to copy from (bytes)
39 * @mem: The buffer to copy into (must be of atleast 'size' bytes)
40 * @size: The number of bytes to copy
41 *
42 * Return: 0 on success otherwise negative error code
43 */
44int copy_flash(struct mbox_context *context, uint32_t offset, void *mem,
45 uint32_t size)
46{
47 int32_t size_read;
48
49 MSG_DBG("Copy flash to %p for size 0x%.8x from offset 0x%.8x\n",
50 mem, size, offset);
51 if (lseek(context->fds[MTD_FD].fd, offset, SEEK_SET) != offset) {
52 MSG_ERR("Couldn't seek flash at pos: %u %s\n", offset,
53 strerror(errno));
54 return -MBOX_R_SYSTEM_ERROR;
55 }
56
57 do {
58 size_read = read(context->fds[MTD_FD].fd, mem,
59 min_u32(CHUNKSIZE, size));
60 if (size_read < 0) {
61 MSG_ERR("Couldn't copy mtd into ram: %s\n",
62 strerror(errno));
63 return -MBOX_R_SYSTEM_ERROR;
64 }
65
66 size -= size_read;
67 mem += size_read;
68 } while (size && size_read);
69
70 return size ? -MBOX_R_SYSTEM_ERROR : 0;
71}
Ratan Guptadc50ce52017-05-31 15:47:55 +053072
73/*
74 * write_flash() - Write the flash from a provided buffer
75 * @context: The mbox context pointer
76 * @offset: The flash offset to write to (bytes)
77 * @buf: The buffer to write from (must be of atleast size)
78 * @size: The number of bytes to write
79 *
80 * Return: 0 on success otherwise negative error code
81 */
82int write_flash(struct mbox_context *context, uint32_t offset, void *buf,
83 uint32_t count)
84{
85 uint32_t buf_offset = 0;
86 int rc;
87
88 MSG_DBG("Write flash @ 0x%.8x for 0x%.8x from %p\n", offset, count, buf);
89
90 if (lseek(context->fds[MTD_FD].fd, offset, SEEK_SET) != offset) {
91 MSG_ERR("Couldn't seek flash at pos: %u %s\n", offset,
92 strerror(errno));
93 return -MBOX_R_SYSTEM_ERROR;
94 }
95
96 while (count) {
97 rc = write(context->fds[MTD_FD].fd, buf + buf_offset, count);
98 if (rc < 0) {
99 MSG_ERR("Couldn't write to flash, write lost: %s\n",
100 strerror(errno));
101 return -MBOX_R_WRITE_ERROR;
102 }
103 /* Mark *NOT* erased where we just wrote */
104 set_flash_bytemap(context, offset + buf_offset, rc,
105 FLASH_DIRTY);
106 count -= rc;
107 buf_offset += rc;
108 }
109
110 return 0;
111}