1
/* Copyright 2013-2015 IBM Corp.
3
* Licensed under the Apache License, Version 2.0 (the "License");
4
* you may not use this file except in compliance with the License.
5
* You may obtain a copy of the License at
7
* http://www.apache.org/licenses/LICENSE-2.0
9
* Unless required by applicable law or agreed to in writing, software
10
* distributed under the License is distributed on an "AS IS" BASIS,
11
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
13
* See the License for the specific language governing permissions and
14
* limitations under the License.
17
#include <libflash/libffs.h>
18
#include <common/arch_flash.h>
23
#include <sys/types.h>
29
#include <sys/ioctl.h>
30
#include <mtd/mtd-user.h>
35
int pnor_init(struct pnor *pnor)
42
rc = arch_flash_init(&(pnor->bl), pnor->path, false);
44
pr_log(LOG_ERR, "PNOR: Flash init failed");
48
rc = blocklevel_get_info(pnor->bl, NULL, &(pnor->size), &(pnor->erasesize));
50
pr_log(LOG_ERR, "PNOR: blocklevel_get_info() failed. Can't use PNOR");
54
rc = ffs_init(0, pnor->size, pnor->bl, &pnor->ffsh, 0);
56
pr_log(LOG_ERR, "PNOR: Failed to open pnor partition table");
62
arch_flash_close(pnor->bl, pnor->path);
67
void pnor_close(struct pnor *pnor)
73
ffs_close(pnor->ffsh);
76
arch_flash_close(pnor->bl, pnor->path);
82
void dump_parts(struct ffs_handle *ffs) {
84
uint32_t start, size, act_size;
87
pr_debug("PNOR: %10s %8s %8s %8s",
88
"name", "start", "size", "act_size");
90
rc = ffs_part_info(ffs, i, &name, &start,
91
&size, &act_size, NULL);
94
pr_debug("PNOR: %10s %08x %08x %08x",
95
name, start, size, act_size);
100
static int mtd_write(struct pnor *pnor, void *data, uint64_t offset,
105
if (len > pnor->size || offset > pnor->size ||
106
len + offset > pnor->size)
109
rc = blocklevel_smart_write(pnor->bl, offset, data, len);
116
static int mtd_read(struct pnor *pnor, void *data, uint64_t offset,
121
if (len > pnor->size || offset > pnor->size ||
122
len + offset > pnor->size)
125
rc = blocklevel_read(pnor->bl, offset, data, len);
132
/* Similar to read(2), this performs partial operations where the number of
133
* bytes read/written may be less than size.
135
* Returns number of bytes written, or a negative value on failure. */
136
int pnor_operation(struct pnor *pnor, const char *name, uint64_t offset,
137
void *data, size_t requested_size, enum pnor_op op)
140
uint32_t pstart, psize, idx;
144
pr_log(LOG_ERR, "PNOR: ffs not initialised");
148
rc = ffs_lookup_part(pnor->ffsh, name, &idx);
150
pr_log(LOG_WARNING, "PNOR: no partiton named '%s'", name);
154
ffs_part_info(pnor->ffsh, idx, NULL, &pstart, &psize, NULL, NULL);
156
pr_log(LOG_ERR, "PNOR: unable to fetch partition info for %s",
161
if (offset > psize) {
162
pr_log(LOG_WARNING, "PNOR: partition %s(size 0x%x) "
163
"offset (0x%lx) out of bounds",
164
name, psize, offset);
168
/* Large requests are trimmed */
169
if (requested_size > psize)
172
size = requested_size;
174
if (size + offset > psize)
175
size = psize - offset;
178
pr_log(LOG_WARNING, "PNOR: partition %s(size 0x%x) "
179
"read size (0x%zx) and offset (0x%lx) "
181
name, psize, requested_size, offset);
187
rc = mtd_read(pnor, data, pstart + offset, size);
190
rc = mtd_write(pnor, data, pstart + offset, size);
194
pr_log(LOG_ERR, "PNOR: Invalid operation");
199
pr_log(LOG_ERR, "PNOR: MTD operation failed");
201
pr_log(LOG_WARNING, "PNOR: mtd operation "
202
"returned %d, expected %d",