Blame view
common/fb_nand.c
4.56 KB
bf8940d35 fastboot: Impleme... |
1 2 3 4 5 6 7 8 9 |
/* * Copyright 2014 Broadcom Corporation. * Copyright 2015 Free Electrons. * * SPDX-License-Identifier: GPL-2.0+ */ #include <config.h> #include <common.h> |
bf8940d35 fastboot: Impleme... |
10 |
#include <fastboot.h> |
3d4ef38de sparse: Rename th... |
11 |
#include <image-sparse.h> |
bf8940d35 fastboot: Impleme... |
12 13 14 15 16 17 18 19 20 21 22 23 |
#include <sparse_format.h> #include <linux/mtd/mtd.h> #include <jffs2/jffs2.h> #include <nand.h> static char *response_str; struct fb_nand_sparse { nand_info_t *nand; struct part_info *part; }; |
6fb77c48e fastboot: nand: A... |
24 25 26 27 28 29 30 31 32 |
__weak int board_fastboot_erase_partition_setup(char *name) { return 0; } __weak int board_fastboot_write_partition_setup(char *name) { return 0; } |
bf8940d35 fastboot: Impleme... |
33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 |
static int fb_nand_lookup(const char *partname, char *response, nand_info_t **nand, struct part_info **part) { struct mtd_device *dev; int ret; u8 pnum; ret = mtdparts_init(); if (ret) { error("Cannot initialize MTD partitions "); fastboot_fail(response_str, "cannot init mtdparts"); return ret; } ret = find_dev_and_part(partname, &dev, &pnum, part); if (ret) { error("cannot find partition: '%s'", partname); fastboot_fail(response_str, "cannot find partition"); return ret; } if (dev->id->type != MTD_DEV_TYPE_NAND) { error("partition '%s' is not stored on a NAND device", partname); fastboot_fail(response_str, "not a NAND device"); return -EINVAL; } *nand = &nand_info[dev->id->num]; return 0; } static int _fb_nand_erase(nand_info_t *nand, struct part_info *part) { nand_erase_options_t opts; int ret; memset(&opts, 0, sizeof(opts)); opts.offset = part->offset; opts.length = part->size; opts.quiet = 1; printf("Erasing blocks 0x%llx to 0x%llx ", part->offset, part->offset + part->size); ret = nand_erase_opts(nand, &opts); if (ret) return ret; printf("........ erased 0x%llx bytes from '%s' ", part->size, part->name); return 0; } static int _fb_nand_write(nand_info_t *nand, struct part_info *part, void *buffer, unsigned int offset, unsigned int length, size_t *written) { int flags = WITH_WR_VERIFY; #ifdef CONFIG_FASTBOOT_FLASH_NAND_TRIMFFS flags |= WITH_DROP_FFS; #endif return nand_write_skip_bad(nand, offset, &length, written, part->size - (offset - part->offset), buffer, flags); } static int fb_nand_sparse_write(struct sparse_storage *storage, void *priv, unsigned int offset, unsigned int size, char *data) { struct fb_nand_sparse *sparse = priv; size_t written; int ret; ret = _fb_nand_write(sparse->nand, sparse->part, data, offset * storage->block_sz, size * storage->block_sz, &written); if (ret < 0) { printf("Failed to write sparse chunk "); return ret; } return written / storage->block_sz; } void fb_nand_flash_write(const char *partname, unsigned int session_id, void *download_buffer, unsigned int download_bytes, char *response) { struct part_info *part; nand_info_t *nand = NULL; int ret; /* initialize the response buffer */ response_str = response; ret = fb_nand_lookup(partname, response, &nand, &part); if (ret) { error("invalid NAND device"); fastboot_fail(response_str, "invalid NAND device"); return; } |
6fb77c48e fastboot: nand: A... |
147 148 149 |
ret = board_fastboot_write_partition_setup(part->name); if (ret) return; |
bf8940d35 fastboot: Impleme... |
150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 |
if (is_sparse_image(download_buffer)) { struct fb_nand_sparse sparse_priv; sparse_storage_t sparse; sparse_priv.nand = nand; sparse_priv.part = part; sparse.block_sz = nand->writesize; sparse.start = part->offset / sparse.block_sz; sparse.size = part->size / sparse.block_sz; sparse.name = part->name; sparse.write = fb_nand_sparse_write; ret = store_sparse_image(&sparse, &sparse_priv, session_id, download_buffer); } else { printf("Flashing raw image at offset 0x%llx ", part->offset); ret = _fb_nand_write(nand, part, download_buffer, part->offset, download_bytes, NULL); printf("........ wrote %u bytes to '%s' ", download_bytes, part->name); } if (ret) { fastboot_fail(response_str, "error writing the image"); return; } fastboot_okay(response_str, ""); } void fb_nand_erase(const char *partname, char *response) { struct part_info *part; nand_info_t *nand = NULL; int ret; /* initialize the response buffer */ response_str = response; ret = fb_nand_lookup(partname, response, &nand, &part); if (ret) { error("invalid NAND device"); fastboot_fail(response_str, "invalid NAND device"); return; } |
6fb77c48e fastboot: nand: A... |
201 202 203 |
ret = board_fastboot_erase_partition_setup(part->name); if (ret) return; |
bf8940d35 fastboot: Impleme... |
204 205 206 207 208 209 210 211 212 |
ret = _fb_nand_erase(nand, part); if (ret) { error("failed erasing from device %s", nand->name); fastboot_fail(response_str, "failed erasing from device"); return; } fastboot_okay(response_str, ""); } |