1*0d6140beSAndroid Build Coastguard Worker /*
2*0d6140beSAndroid Build Coastguard Worker * This file is part of the flashrom project.
3*0d6140beSAndroid Build Coastguard Worker *
4*0d6140beSAndroid Build Coastguard Worker * Copyright (C) 2012, 2016 secunet Security Networks AG
5*0d6140beSAndroid Build Coastguard Worker * (Written by Nico Huber <[email protected]> for secunet)
6*0d6140beSAndroid Build Coastguard Worker *
7*0d6140beSAndroid Build Coastguard Worker * This program is free software; you can redistribute it and/or modify
8*0d6140beSAndroid Build Coastguard Worker * it under the terms of the GNU General Public License as published by
9*0d6140beSAndroid Build Coastguard Worker * the Free Software Foundation; either version 2 of the License, or
10*0d6140beSAndroid Build Coastguard Worker * (at your option) any later version.
11*0d6140beSAndroid Build Coastguard Worker *
12*0d6140beSAndroid Build Coastguard Worker * This program is distributed in the hope that it will be useful,
13*0d6140beSAndroid Build Coastguard Worker * but WITHOUT ANY WARRANTY; without even the implied warranty of
14*0d6140beSAndroid Build Coastguard Worker * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15*0d6140beSAndroid Build Coastguard Worker * GNU General Public License for more details.
16*0d6140beSAndroid Build Coastguard Worker */
17*0d6140beSAndroid Build Coastguard Worker
18*0d6140beSAndroid Build Coastguard Worker #include <errno.h>
19*0d6140beSAndroid Build Coastguard Worker #include <stdlib.h>
20*0d6140beSAndroid Build Coastguard Worker #include <string.h>
21*0d6140beSAndroid Build Coastguard Worker #include <stdarg.h>
22*0d6140beSAndroid Build Coastguard Worker
23*0d6140beSAndroid Build Coastguard Worker #include "flash.h"
24*0d6140beSAndroid Build Coastguard Worker #include "fmap.h"
25*0d6140beSAndroid Build Coastguard Worker #include "programmer.h"
26*0d6140beSAndroid Build Coastguard Worker #include "layout.h"
27*0d6140beSAndroid Build Coastguard Worker #include "ich_descriptors.h"
28*0d6140beSAndroid Build Coastguard Worker #include "libflashrom.h"
29*0d6140beSAndroid Build Coastguard Worker #include "writeprotect.h"
30*0d6140beSAndroid Build Coastguard Worker
31*0d6140beSAndroid Build Coastguard Worker
32*0d6140beSAndroid Build Coastguard Worker /** Pointer to log callback function. */
33*0d6140beSAndroid Build Coastguard Worker static flashrom_log_callback *global_log_callback = NULL;
34*0d6140beSAndroid Build Coastguard Worker
flashrom_init(const int perform_selfcheck)35*0d6140beSAndroid Build Coastguard Worker int flashrom_init(const int perform_selfcheck)
36*0d6140beSAndroid Build Coastguard Worker {
37*0d6140beSAndroid Build Coastguard Worker if (perform_selfcheck && selfcheck())
38*0d6140beSAndroid Build Coastguard Worker return 1;
39*0d6140beSAndroid Build Coastguard Worker return 0;
40*0d6140beSAndroid Build Coastguard Worker }
41*0d6140beSAndroid Build Coastguard Worker
flashrom_shutdown(void)42*0d6140beSAndroid Build Coastguard Worker int flashrom_shutdown(void)
43*0d6140beSAndroid Build Coastguard Worker {
44*0d6140beSAndroid Build Coastguard Worker return 0; /* TODO: nothing to do? */
45*0d6140beSAndroid Build Coastguard Worker }
46*0d6140beSAndroid Build Coastguard Worker
47*0d6140beSAndroid Build Coastguard Worker /* TODO: flashrom_set_loglevel()? do we need it?
48*0d6140beSAndroid Build Coastguard Worker For now, let the user decide in their callback. */
flashrom_set_log_callback(flashrom_log_callback * const log_callback)49*0d6140beSAndroid Build Coastguard Worker void flashrom_set_log_callback(flashrom_log_callback *const log_callback)
50*0d6140beSAndroid Build Coastguard Worker {
51*0d6140beSAndroid Build Coastguard Worker global_log_callback = log_callback;
52*0d6140beSAndroid Build Coastguard Worker }
53*0d6140beSAndroid Build Coastguard Worker /** @private */
print(const enum flashrom_log_level level,const char * const fmt,...)54*0d6140beSAndroid Build Coastguard Worker int print(const enum flashrom_log_level level, const char *const fmt, ...)
55*0d6140beSAndroid Build Coastguard Worker {
56*0d6140beSAndroid Build Coastguard Worker if (global_log_callback) {
57*0d6140beSAndroid Build Coastguard Worker int ret;
58*0d6140beSAndroid Build Coastguard Worker va_list args;
59*0d6140beSAndroid Build Coastguard Worker va_start(args, fmt);
60*0d6140beSAndroid Build Coastguard Worker ret = global_log_callback(level, fmt, args);
61*0d6140beSAndroid Build Coastguard Worker va_end(args);
62*0d6140beSAndroid Build Coastguard Worker return ret;
63*0d6140beSAndroid Build Coastguard Worker }
64*0d6140beSAndroid Build Coastguard Worker return 0;
65*0d6140beSAndroid Build Coastguard Worker }
66*0d6140beSAndroid Build Coastguard Worker
flashrom_set_progress_callback(struct flashrom_flashctx * flashctx,flashrom_progress_callback * progress_callback,struct flashrom_progress * progress_state)67*0d6140beSAndroid Build Coastguard Worker void flashrom_set_progress_callback(struct flashrom_flashctx *flashctx, flashrom_progress_callback *progress_callback, struct flashrom_progress *progress_state)
68*0d6140beSAndroid Build Coastguard Worker {
69*0d6140beSAndroid Build Coastguard Worker flashctx->progress_callback = progress_callback;
70*0d6140beSAndroid Build Coastguard Worker flashctx->progress_state = progress_state;
71*0d6140beSAndroid Build Coastguard Worker }
72*0d6140beSAndroid Build Coastguard Worker /** @private */
update_progress(struct flashrom_flashctx * flashctx,enum flashrom_progress_stage stage,size_t current,size_t total)73*0d6140beSAndroid Build Coastguard Worker void update_progress(struct flashrom_flashctx *flashctx, enum flashrom_progress_stage stage, size_t current, size_t total)
74*0d6140beSAndroid Build Coastguard Worker {
75*0d6140beSAndroid Build Coastguard Worker if (flashctx->progress_callback == NULL)
76*0d6140beSAndroid Build Coastguard Worker return;
77*0d6140beSAndroid Build Coastguard Worker if (current > total)
78*0d6140beSAndroid Build Coastguard Worker current = total;
79*0d6140beSAndroid Build Coastguard Worker
80*0d6140beSAndroid Build Coastguard Worker flashctx->progress_state->stage = stage;
81*0d6140beSAndroid Build Coastguard Worker flashctx->progress_state->current = current;
82*0d6140beSAndroid Build Coastguard Worker flashctx->progress_state->total = total;
83*0d6140beSAndroid Build Coastguard Worker flashctx->progress_callback(flashctx);
84*0d6140beSAndroid Build Coastguard Worker }
85*0d6140beSAndroid Build Coastguard Worker
flashrom_version_info(void)86*0d6140beSAndroid Build Coastguard Worker const char *flashrom_version_info(void)
87*0d6140beSAndroid Build Coastguard Worker {
88*0d6140beSAndroid Build Coastguard Worker return flashrom_version;
89*0d6140beSAndroid Build Coastguard Worker }
90*0d6140beSAndroid Build Coastguard Worker
flashrom_supported_flash_chips(void)91*0d6140beSAndroid Build Coastguard Worker struct flashrom_flashchip_info *flashrom_supported_flash_chips(void)
92*0d6140beSAndroid Build Coastguard Worker {
93*0d6140beSAndroid Build Coastguard Worker struct flashrom_flashchip_info *supported_flashchips =
94*0d6140beSAndroid Build Coastguard Worker malloc(flashchips_size * sizeof(*supported_flashchips));
95*0d6140beSAndroid Build Coastguard Worker
96*0d6140beSAndroid Build Coastguard Worker if (!supported_flashchips) {
97*0d6140beSAndroid Build Coastguard Worker msg_gerr("Memory allocation error!\n");
98*0d6140beSAndroid Build Coastguard Worker return NULL;
99*0d6140beSAndroid Build Coastguard Worker }
100*0d6140beSAndroid Build Coastguard Worker
101*0d6140beSAndroid Build Coastguard Worker for (unsigned int i = 0; i < flashchips_size; ++i) {
102*0d6140beSAndroid Build Coastguard Worker supported_flashchips[i].vendor = flashchips[i].vendor;
103*0d6140beSAndroid Build Coastguard Worker supported_flashchips[i].name = flashchips[i].name;
104*0d6140beSAndroid Build Coastguard Worker supported_flashchips[i].manufacture_id = flashchips[i].manufacture_id;
105*0d6140beSAndroid Build Coastguard Worker supported_flashchips[i].model_id = flashchips[i].model_id;
106*0d6140beSAndroid Build Coastguard Worker supported_flashchips[i].tested.erase =
107*0d6140beSAndroid Build Coastguard Worker (enum flashrom_test_state)flashchips[i].tested.erase;
108*0d6140beSAndroid Build Coastguard Worker supported_flashchips[i].tested.probe =
109*0d6140beSAndroid Build Coastguard Worker (enum flashrom_test_state)flashchips[i].tested.probe;
110*0d6140beSAndroid Build Coastguard Worker supported_flashchips[i].tested.read =
111*0d6140beSAndroid Build Coastguard Worker (enum flashrom_test_state)flashchips[i].tested.read;
112*0d6140beSAndroid Build Coastguard Worker supported_flashchips[i].tested.write =
113*0d6140beSAndroid Build Coastguard Worker (enum flashrom_test_state)flashchips[i].tested.write;
114*0d6140beSAndroid Build Coastguard Worker supported_flashchips[i].total_size = flashchips[i].total_size;
115*0d6140beSAndroid Build Coastguard Worker }
116*0d6140beSAndroid Build Coastguard Worker
117*0d6140beSAndroid Build Coastguard Worker return supported_flashchips;
118*0d6140beSAndroid Build Coastguard Worker }
119*0d6140beSAndroid Build Coastguard Worker
flashrom_supported_boards(void)120*0d6140beSAndroid Build Coastguard Worker struct flashrom_board_info *flashrom_supported_boards(void)
121*0d6140beSAndroid Build Coastguard Worker {
122*0d6140beSAndroid Build Coastguard Worker #if CONFIG_INTERNAL == 1
123*0d6140beSAndroid Build Coastguard Worker int boards_known_size = 0;
124*0d6140beSAndroid Build Coastguard Worker const struct board_info *binfo = boards_known;
125*0d6140beSAndroid Build Coastguard Worker
126*0d6140beSAndroid Build Coastguard Worker while ((binfo++)->vendor)
127*0d6140beSAndroid Build Coastguard Worker ++boards_known_size;
128*0d6140beSAndroid Build Coastguard Worker binfo = boards_known;
129*0d6140beSAndroid Build Coastguard Worker /* add place for {0} */
130*0d6140beSAndroid Build Coastguard Worker ++boards_known_size;
131*0d6140beSAndroid Build Coastguard Worker
132*0d6140beSAndroid Build Coastguard Worker struct flashrom_board_info *supported_boards =
133*0d6140beSAndroid Build Coastguard Worker malloc(boards_known_size * sizeof(*supported_boards));
134*0d6140beSAndroid Build Coastguard Worker
135*0d6140beSAndroid Build Coastguard Worker if (!supported_boards) {
136*0d6140beSAndroid Build Coastguard Worker msg_gerr("Memory allocation error!\n");
137*0d6140beSAndroid Build Coastguard Worker return NULL;
138*0d6140beSAndroid Build Coastguard Worker }
139*0d6140beSAndroid Build Coastguard Worker
140*0d6140beSAndroid Build Coastguard Worker for (int i = 0; i < boards_known_size; ++i) {
141*0d6140beSAndroid Build Coastguard Worker supported_boards[i].vendor = binfo[i].vendor;
142*0d6140beSAndroid Build Coastguard Worker supported_boards[i].name = binfo[i].name;
143*0d6140beSAndroid Build Coastguard Worker supported_boards[i].working =
144*0d6140beSAndroid Build Coastguard Worker (enum flashrom_test_state) binfo[i].working;
145*0d6140beSAndroid Build Coastguard Worker }
146*0d6140beSAndroid Build Coastguard Worker
147*0d6140beSAndroid Build Coastguard Worker return supported_boards;
148*0d6140beSAndroid Build Coastguard Worker #else
149*0d6140beSAndroid Build Coastguard Worker return NULL;
150*0d6140beSAndroid Build Coastguard Worker #endif
151*0d6140beSAndroid Build Coastguard Worker }
152*0d6140beSAndroid Build Coastguard Worker
flashrom_supported_chipsets(void)153*0d6140beSAndroid Build Coastguard Worker struct flashrom_chipset_info *flashrom_supported_chipsets(void)
154*0d6140beSAndroid Build Coastguard Worker {
155*0d6140beSAndroid Build Coastguard Worker #if CONFIG_INTERNAL == 1
156*0d6140beSAndroid Build Coastguard Worker int chipset_enables_size = 0;
157*0d6140beSAndroid Build Coastguard Worker const struct penable *chipset = chipset_enables;
158*0d6140beSAndroid Build Coastguard Worker
159*0d6140beSAndroid Build Coastguard Worker while ((chipset++)->vendor_name)
160*0d6140beSAndroid Build Coastguard Worker ++chipset_enables_size;
161*0d6140beSAndroid Build Coastguard Worker chipset = chipset_enables;
162*0d6140beSAndroid Build Coastguard Worker /* add place for {0}*/
163*0d6140beSAndroid Build Coastguard Worker ++chipset_enables_size;
164*0d6140beSAndroid Build Coastguard Worker
165*0d6140beSAndroid Build Coastguard Worker struct flashrom_chipset_info *supported_chipsets =
166*0d6140beSAndroid Build Coastguard Worker malloc(chipset_enables_size * sizeof(*supported_chipsets));
167*0d6140beSAndroid Build Coastguard Worker
168*0d6140beSAndroid Build Coastguard Worker if (!supported_chipsets) {
169*0d6140beSAndroid Build Coastguard Worker msg_gerr("Memory allocation error!\n");
170*0d6140beSAndroid Build Coastguard Worker return NULL;
171*0d6140beSAndroid Build Coastguard Worker }
172*0d6140beSAndroid Build Coastguard Worker
173*0d6140beSAndroid Build Coastguard Worker for (int i = 0; i < chipset_enables_size; ++i) {
174*0d6140beSAndroid Build Coastguard Worker supported_chipsets[i].vendor = chipset[i].vendor_name;
175*0d6140beSAndroid Build Coastguard Worker supported_chipsets[i].chipset = chipset[i].device_name;
176*0d6140beSAndroid Build Coastguard Worker supported_chipsets[i].vendor_id = chipset[i].vendor_id;
177*0d6140beSAndroid Build Coastguard Worker supported_chipsets[i].chipset_id = chipset[i].device_id;
178*0d6140beSAndroid Build Coastguard Worker supported_chipsets[i].status =
179*0d6140beSAndroid Build Coastguard Worker (enum flashrom_test_state) chipset[i].status;
180*0d6140beSAndroid Build Coastguard Worker }
181*0d6140beSAndroid Build Coastguard Worker
182*0d6140beSAndroid Build Coastguard Worker return supported_chipsets;
183*0d6140beSAndroid Build Coastguard Worker #else
184*0d6140beSAndroid Build Coastguard Worker return NULL;
185*0d6140beSAndroid Build Coastguard Worker #endif
186*0d6140beSAndroid Build Coastguard Worker }
187*0d6140beSAndroid Build Coastguard Worker
flashrom_data_free(void * const p)188*0d6140beSAndroid Build Coastguard Worker int flashrom_data_free(void *const p)
189*0d6140beSAndroid Build Coastguard Worker {
190*0d6140beSAndroid Build Coastguard Worker free(p);
191*0d6140beSAndroid Build Coastguard Worker return 0;
192*0d6140beSAndroid Build Coastguard Worker }
193*0d6140beSAndroid Build Coastguard Worker
flashrom_programmer_init(struct flashrom_programmer ** const flashprog,const char * const prog_name,const char * const prog_param)194*0d6140beSAndroid Build Coastguard Worker int flashrom_programmer_init(struct flashrom_programmer **const flashprog,
195*0d6140beSAndroid Build Coastguard Worker const char *const prog_name, const char *const prog_param)
196*0d6140beSAndroid Build Coastguard Worker {
197*0d6140beSAndroid Build Coastguard Worker unsigned prog;
198*0d6140beSAndroid Build Coastguard Worker
199*0d6140beSAndroid Build Coastguard Worker for (prog = 0; prog < programmer_table_size; prog++) {
200*0d6140beSAndroid Build Coastguard Worker if (strcmp(prog_name, programmer_table[prog]->name) == 0)
201*0d6140beSAndroid Build Coastguard Worker break;
202*0d6140beSAndroid Build Coastguard Worker }
203*0d6140beSAndroid Build Coastguard Worker if (prog >= programmer_table_size) {
204*0d6140beSAndroid Build Coastguard Worker msg_ginfo("Error: Unknown programmer \"%s\". Valid choices are:\n", prog_name);
205*0d6140beSAndroid Build Coastguard Worker list_programmers_linebreak(0, 80, 0);
206*0d6140beSAndroid Build Coastguard Worker return 1;
207*0d6140beSAndroid Build Coastguard Worker }
208*0d6140beSAndroid Build Coastguard Worker return programmer_init(programmer_table[prog], prog_param);
209*0d6140beSAndroid Build Coastguard Worker }
210*0d6140beSAndroid Build Coastguard Worker
flashrom_programmer_shutdown(struct flashrom_programmer * const flashprog)211*0d6140beSAndroid Build Coastguard Worker int flashrom_programmer_shutdown(struct flashrom_programmer *const flashprog)
212*0d6140beSAndroid Build Coastguard Worker {
213*0d6140beSAndroid Build Coastguard Worker return programmer_shutdown();
214*0d6140beSAndroid Build Coastguard Worker }
215*0d6140beSAndroid Build Coastguard Worker
216*0d6140beSAndroid Build Coastguard Worker /* TODO: flashrom_programmer_capabilities()? */
217*0d6140beSAndroid Build Coastguard Worker
flashrom_flash_probe(struct flashrom_flashctx ** const flashctx,const struct flashrom_programmer * const flashprog,const char * const chip_name)218*0d6140beSAndroid Build Coastguard Worker int flashrom_flash_probe(struct flashrom_flashctx **const flashctx,
219*0d6140beSAndroid Build Coastguard Worker const struct flashrom_programmer *const flashprog,
220*0d6140beSAndroid Build Coastguard Worker const char *const chip_name)
221*0d6140beSAndroid Build Coastguard Worker {
222*0d6140beSAndroid Build Coastguard Worker int i, ret = 2;
223*0d6140beSAndroid Build Coastguard Worker struct flashrom_flashctx second_flashctx = { 0, };
224*0d6140beSAndroid Build Coastguard Worker
225*0d6140beSAndroid Build Coastguard Worker *flashctx = malloc(sizeof(**flashctx));
226*0d6140beSAndroid Build Coastguard Worker if (!*flashctx)
227*0d6140beSAndroid Build Coastguard Worker return 1;
228*0d6140beSAndroid Build Coastguard Worker memset(*flashctx, 0, sizeof(**flashctx));
229*0d6140beSAndroid Build Coastguard Worker
230*0d6140beSAndroid Build Coastguard Worker for (i = 0; i < registered_master_count; ++i) {
231*0d6140beSAndroid Build Coastguard Worker int flash_idx = -1;
232*0d6140beSAndroid Build Coastguard Worker if (!ret || (flash_idx = probe_flash(®istered_masters[i], 0, *flashctx, 0, chip_name)) != -1) {
233*0d6140beSAndroid Build Coastguard Worker ret = 0;
234*0d6140beSAndroid Build Coastguard Worker /* We found one chip, now check that there is no second match. */
235*0d6140beSAndroid Build Coastguard Worker if (probe_flash(®istered_masters[i], flash_idx + 1, &second_flashctx, 0, chip_name) != -1) {
236*0d6140beSAndroid Build Coastguard Worker flashrom_layout_release(second_flashctx.default_layout);
237*0d6140beSAndroid Build Coastguard Worker free(second_flashctx.chip);
238*0d6140beSAndroid Build Coastguard Worker ret = 3;
239*0d6140beSAndroid Build Coastguard Worker break;
240*0d6140beSAndroid Build Coastguard Worker }
241*0d6140beSAndroid Build Coastguard Worker }
242*0d6140beSAndroid Build Coastguard Worker }
243*0d6140beSAndroid Build Coastguard Worker if (ret) {
244*0d6140beSAndroid Build Coastguard Worker flashrom_flash_release(*flashctx);
245*0d6140beSAndroid Build Coastguard Worker *flashctx = NULL;
246*0d6140beSAndroid Build Coastguard Worker }
247*0d6140beSAndroid Build Coastguard Worker return ret;
248*0d6140beSAndroid Build Coastguard Worker }
249*0d6140beSAndroid Build Coastguard Worker
flashrom_flash_getsize(const struct flashrom_flashctx * const flashctx)250*0d6140beSAndroid Build Coastguard Worker size_t flashrom_flash_getsize(const struct flashrom_flashctx *const flashctx)
251*0d6140beSAndroid Build Coastguard Worker {
252*0d6140beSAndroid Build Coastguard Worker return flashctx->chip->total_size * 1024;
253*0d6140beSAndroid Build Coastguard Worker }
254*0d6140beSAndroid Build Coastguard Worker
flashrom_flash_getinfo(const struct flashrom_flashctx * const flashctx,struct flashrom_flashchip_info * info)255*0d6140beSAndroid Build Coastguard Worker void flashrom_flash_getinfo(const struct flashrom_flashctx *const flashctx, struct flashrom_flashchip_info *info)
256*0d6140beSAndroid Build Coastguard Worker {
257*0d6140beSAndroid Build Coastguard Worker if (!info) return;
258*0d6140beSAndroid Build Coastguard Worker
259*0d6140beSAndroid Build Coastguard Worker info->vendor = flashctx->chip->vendor;
260*0d6140beSAndroid Build Coastguard Worker info->name = flashctx->chip->name;
261*0d6140beSAndroid Build Coastguard Worker info->manufacture_id = flashctx->chip->manufacture_id;
262*0d6140beSAndroid Build Coastguard Worker info->model_id = flashctx->chip->model_id;
263*0d6140beSAndroid Build Coastguard Worker
264*0d6140beSAndroid Build Coastguard Worker info->total_size = flashctx->chip->total_size;
265*0d6140beSAndroid Build Coastguard Worker
266*0d6140beSAndroid Build Coastguard Worker info->tested.erase = (enum flashrom_test_state) flashctx->chip->tested.erase;
267*0d6140beSAndroid Build Coastguard Worker info->tested.probe = (enum flashrom_test_state) flashctx->chip->tested.probe;
268*0d6140beSAndroid Build Coastguard Worker info->tested.read = (enum flashrom_test_state) flashctx->chip->tested.read;
269*0d6140beSAndroid Build Coastguard Worker info->tested.write = (enum flashrom_test_state) flashctx->chip->tested.write;
270*0d6140beSAndroid Build Coastguard Worker }
271*0d6140beSAndroid Build Coastguard Worker
flashrom_flash_release(struct flashrom_flashctx * const flashctx)272*0d6140beSAndroid Build Coastguard Worker void flashrom_flash_release(struct flashrom_flashctx *const flashctx)
273*0d6140beSAndroid Build Coastguard Worker {
274*0d6140beSAndroid Build Coastguard Worker if (!flashctx)
275*0d6140beSAndroid Build Coastguard Worker return;
276*0d6140beSAndroid Build Coastguard Worker
277*0d6140beSAndroid Build Coastguard Worker flashrom_layout_release(flashctx->default_layout);
278*0d6140beSAndroid Build Coastguard Worker free(flashctx->chip);
279*0d6140beSAndroid Build Coastguard Worker free(flashctx);
280*0d6140beSAndroid Build Coastguard Worker }
281*0d6140beSAndroid Build Coastguard Worker
flashrom_flag_set(struct flashrom_flashctx * const flashctx,const enum flashrom_flag flag,const bool value)282*0d6140beSAndroid Build Coastguard Worker void flashrom_flag_set(struct flashrom_flashctx *const flashctx,
283*0d6140beSAndroid Build Coastguard Worker const enum flashrom_flag flag, const bool value)
284*0d6140beSAndroid Build Coastguard Worker {
285*0d6140beSAndroid Build Coastguard Worker switch (flag) {
286*0d6140beSAndroid Build Coastguard Worker case FLASHROM_FLAG_FORCE: flashctx->flags.force = value; break;
287*0d6140beSAndroid Build Coastguard Worker case FLASHROM_FLAG_FORCE_BOARDMISMATCH: flashctx->flags.force_boardmismatch = value; break;
288*0d6140beSAndroid Build Coastguard Worker case FLASHROM_FLAG_VERIFY_AFTER_WRITE: flashctx->flags.verify_after_write = value; break;
289*0d6140beSAndroid Build Coastguard Worker case FLASHROM_FLAG_VERIFY_WHOLE_CHIP: flashctx->flags.verify_whole_chip = value; break;
290*0d6140beSAndroid Build Coastguard Worker case FLASHROM_FLAG_SKIP_UNREADABLE_REGIONS: flashctx->flags.skip_unreadable_regions = value; break;
291*0d6140beSAndroid Build Coastguard Worker case FLASHROM_FLAG_SKIP_UNWRITABLE_REGIONS: flashctx->flags.skip_unwritable_regions = value; break;
292*0d6140beSAndroid Build Coastguard Worker }
293*0d6140beSAndroid Build Coastguard Worker }
294*0d6140beSAndroid Build Coastguard Worker
flashrom_flag_get(const struct flashrom_flashctx * const flashctx,const enum flashrom_flag flag)295*0d6140beSAndroid Build Coastguard Worker bool flashrom_flag_get(const struct flashrom_flashctx *const flashctx, const enum flashrom_flag flag)
296*0d6140beSAndroid Build Coastguard Worker {
297*0d6140beSAndroid Build Coastguard Worker switch (flag) {
298*0d6140beSAndroid Build Coastguard Worker case FLASHROM_FLAG_FORCE: return flashctx->flags.force;
299*0d6140beSAndroid Build Coastguard Worker case FLASHROM_FLAG_FORCE_BOARDMISMATCH: return flashctx->flags.force_boardmismatch;
300*0d6140beSAndroid Build Coastguard Worker case FLASHROM_FLAG_VERIFY_AFTER_WRITE: return flashctx->flags.verify_after_write;
301*0d6140beSAndroid Build Coastguard Worker case FLASHROM_FLAG_VERIFY_WHOLE_CHIP: return flashctx->flags.verify_whole_chip;
302*0d6140beSAndroid Build Coastguard Worker case FLASHROM_FLAG_SKIP_UNREADABLE_REGIONS: return flashctx->flags.skip_unreadable_regions;
303*0d6140beSAndroid Build Coastguard Worker case FLASHROM_FLAG_SKIP_UNWRITABLE_REGIONS: return flashctx->flags.skip_unwritable_regions;
304*0d6140beSAndroid Build Coastguard Worker default: return false;
305*0d6140beSAndroid Build Coastguard Worker }
306*0d6140beSAndroid Build Coastguard Worker }
307*0d6140beSAndroid Build Coastguard Worker
flashrom_layout_read_from_ifd(struct flashrom_layout ** const layout,struct flashctx * const flashctx,const void * const dump,const size_t len)308*0d6140beSAndroid Build Coastguard Worker int flashrom_layout_read_from_ifd(struct flashrom_layout **const layout, struct flashctx *const flashctx,
309*0d6140beSAndroid Build Coastguard Worker const void *const dump, const size_t len)
310*0d6140beSAndroid Build Coastguard Worker {
311*0d6140beSAndroid Build Coastguard Worker #ifndef __FLASHROM_LITTLE_ENDIAN__
312*0d6140beSAndroid Build Coastguard Worker return 6;
313*0d6140beSAndroid Build Coastguard Worker #else
314*0d6140beSAndroid Build Coastguard Worker struct flashrom_layout *dump_layout = NULL, *chip_layout = NULL;
315*0d6140beSAndroid Build Coastguard Worker int ret = 1;
316*0d6140beSAndroid Build Coastguard Worker
317*0d6140beSAndroid Build Coastguard Worker void *const desc = malloc(0x1000);
318*0d6140beSAndroid Build Coastguard Worker if (prepare_flash_access(flashctx, true, false, false, false))
319*0d6140beSAndroid Build Coastguard Worker goto _free_ret;
320*0d6140beSAndroid Build Coastguard Worker
321*0d6140beSAndroid Build Coastguard Worker msg_cinfo("Reading ich descriptor... ");
322*0d6140beSAndroid Build Coastguard Worker if (read_flash(flashctx, desc, 0, 0x1000)) {
323*0d6140beSAndroid Build Coastguard Worker msg_cerr("Read operation failed!\n");
324*0d6140beSAndroid Build Coastguard Worker msg_cinfo("FAILED.\n");
325*0d6140beSAndroid Build Coastguard Worker ret = 2;
326*0d6140beSAndroid Build Coastguard Worker goto _finalize_ret;
327*0d6140beSAndroid Build Coastguard Worker }
328*0d6140beSAndroid Build Coastguard Worker msg_cinfo("done.\n");
329*0d6140beSAndroid Build Coastguard Worker
330*0d6140beSAndroid Build Coastguard Worker if (layout_from_ich_descriptors(&chip_layout, desc, 0x1000)) {
331*0d6140beSAndroid Build Coastguard Worker msg_cerr("Couldn't parse the descriptor!\n");
332*0d6140beSAndroid Build Coastguard Worker ret = 3;
333*0d6140beSAndroid Build Coastguard Worker goto _finalize_ret;
334*0d6140beSAndroid Build Coastguard Worker }
335*0d6140beSAndroid Build Coastguard Worker
336*0d6140beSAndroid Build Coastguard Worker if (dump) {
337*0d6140beSAndroid Build Coastguard Worker if (layout_from_ich_descriptors(&dump_layout, dump, len)) {
338*0d6140beSAndroid Build Coastguard Worker msg_cerr("Couldn't parse the descriptor!\n");
339*0d6140beSAndroid Build Coastguard Worker ret = 4;
340*0d6140beSAndroid Build Coastguard Worker goto _finalize_ret;
341*0d6140beSAndroid Build Coastguard Worker }
342*0d6140beSAndroid Build Coastguard Worker
343*0d6140beSAndroid Build Coastguard Worker const struct romentry *chip_entry = layout_next(chip_layout, NULL);
344*0d6140beSAndroid Build Coastguard Worker const struct romentry *dump_entry = layout_next(dump_layout, NULL);
345*0d6140beSAndroid Build Coastguard Worker while (chip_entry && dump_entry && !memcmp(chip_entry, dump_entry, sizeof(*chip_entry))) {
346*0d6140beSAndroid Build Coastguard Worker chip_entry = layout_next(chip_layout, chip_entry);
347*0d6140beSAndroid Build Coastguard Worker dump_entry = layout_next(dump_layout, dump_entry);
348*0d6140beSAndroid Build Coastguard Worker }
349*0d6140beSAndroid Build Coastguard Worker flashrom_layout_release(dump_layout);
350*0d6140beSAndroid Build Coastguard Worker if (chip_entry || dump_entry) {
351*0d6140beSAndroid Build Coastguard Worker msg_cerr("Descriptors don't match!\n");
352*0d6140beSAndroid Build Coastguard Worker ret = 5;
353*0d6140beSAndroid Build Coastguard Worker goto _finalize_ret;
354*0d6140beSAndroid Build Coastguard Worker }
355*0d6140beSAndroid Build Coastguard Worker }
356*0d6140beSAndroid Build Coastguard Worker
357*0d6140beSAndroid Build Coastguard Worker *layout = (struct flashrom_layout *)chip_layout;
358*0d6140beSAndroid Build Coastguard Worker ret = 0;
359*0d6140beSAndroid Build Coastguard Worker
360*0d6140beSAndroid Build Coastguard Worker _finalize_ret:
361*0d6140beSAndroid Build Coastguard Worker finalize_flash_access(flashctx);
362*0d6140beSAndroid Build Coastguard Worker _free_ret:
363*0d6140beSAndroid Build Coastguard Worker if (ret)
364*0d6140beSAndroid Build Coastguard Worker flashrom_layout_release(chip_layout);
365*0d6140beSAndroid Build Coastguard Worker free(desc);
366*0d6140beSAndroid Build Coastguard Worker return ret;
367*0d6140beSAndroid Build Coastguard Worker #endif
368*0d6140beSAndroid Build Coastguard Worker }
369*0d6140beSAndroid Build Coastguard Worker
370*0d6140beSAndroid Build Coastguard Worker #ifdef __FLASHROM_LITTLE_ENDIAN__
flashrom_layout_parse_fmap(struct flashrom_layout ** layout,struct flashctx * const flashctx,const struct fmap * const fmap)371*0d6140beSAndroid Build Coastguard Worker static int flashrom_layout_parse_fmap(struct flashrom_layout **layout,
372*0d6140beSAndroid Build Coastguard Worker struct flashctx *const flashctx, const struct fmap *const fmap)
373*0d6140beSAndroid Build Coastguard Worker {
374*0d6140beSAndroid Build Coastguard Worker int i;
375*0d6140beSAndroid Build Coastguard Worker char name[FMAP_STRLEN + 1];
376*0d6140beSAndroid Build Coastguard Worker const struct fmap_area *area;
377*0d6140beSAndroid Build Coastguard Worker struct flashrom_layout *l;
378*0d6140beSAndroid Build Coastguard Worker
379*0d6140beSAndroid Build Coastguard Worker if (!fmap || flashrom_layout_new(&l))
380*0d6140beSAndroid Build Coastguard Worker return 1;
381*0d6140beSAndroid Build Coastguard Worker
382*0d6140beSAndroid Build Coastguard Worker for (i = 0, area = fmap->areas; i < fmap->nareas; i++, area++) {
383*0d6140beSAndroid Build Coastguard Worker if (area->size == 0) {
384*0d6140beSAndroid Build Coastguard Worker /* Layout regions use inclusive upper and lower bounds,
385*0d6140beSAndroid Build Coastguard Worker * so it's impossible to represent a region with zero
386*0d6140beSAndroid Build Coastguard Worker * size although it's allowed in fmap. */
387*0d6140beSAndroid Build Coastguard Worker msg_gwarn("Ignoring zero-size fmap region \"%s\";"
388*0d6140beSAndroid Build Coastguard Worker " empty regions are unsupported.\n",
389*0d6140beSAndroid Build Coastguard Worker area->name);
390*0d6140beSAndroid Build Coastguard Worker continue;
391*0d6140beSAndroid Build Coastguard Worker }
392*0d6140beSAndroid Build Coastguard Worker
393*0d6140beSAndroid Build Coastguard Worker snprintf(name, sizeof(name), "%s", area->name);
394*0d6140beSAndroid Build Coastguard Worker if (flashrom_layout_add_region(l, area->offset, area->offset + area->size - 1, name)) {
395*0d6140beSAndroid Build Coastguard Worker flashrom_layout_release(l);
396*0d6140beSAndroid Build Coastguard Worker return 1;
397*0d6140beSAndroid Build Coastguard Worker }
398*0d6140beSAndroid Build Coastguard Worker }
399*0d6140beSAndroid Build Coastguard Worker
400*0d6140beSAndroid Build Coastguard Worker *layout = l;
401*0d6140beSAndroid Build Coastguard Worker return 0;
402*0d6140beSAndroid Build Coastguard Worker }
403*0d6140beSAndroid Build Coastguard Worker #endif /* __FLASHROM_LITTLE_ENDIAN__ */
404*0d6140beSAndroid Build Coastguard Worker
flashrom_layout_read_fmap_from_rom(struct flashrom_layout ** const layout,struct flashctx * const flashctx,size_t offset,size_t len)405*0d6140beSAndroid Build Coastguard Worker int flashrom_layout_read_fmap_from_rom(struct flashrom_layout **const layout,
406*0d6140beSAndroid Build Coastguard Worker struct flashctx *const flashctx, size_t offset, size_t len)
407*0d6140beSAndroid Build Coastguard Worker {
408*0d6140beSAndroid Build Coastguard Worker #ifndef __FLASHROM_LITTLE_ENDIAN__
409*0d6140beSAndroid Build Coastguard Worker return 3;
410*0d6140beSAndroid Build Coastguard Worker #else
411*0d6140beSAndroid Build Coastguard Worker struct fmap *fmap = NULL;
412*0d6140beSAndroid Build Coastguard Worker int ret = 0;
413*0d6140beSAndroid Build Coastguard Worker
414*0d6140beSAndroid Build Coastguard Worker msg_gdbg("Attempting to read fmap from ROM content.\n");
415*0d6140beSAndroid Build Coastguard Worker if (fmap_read_from_rom(&fmap, flashctx, offset, len)) {
416*0d6140beSAndroid Build Coastguard Worker msg_gerr("Failed to read fmap from ROM.\n");
417*0d6140beSAndroid Build Coastguard Worker return 1;
418*0d6140beSAndroid Build Coastguard Worker }
419*0d6140beSAndroid Build Coastguard Worker
420*0d6140beSAndroid Build Coastguard Worker msg_gdbg("Adding fmap layout to global layout.\n");
421*0d6140beSAndroid Build Coastguard Worker if (flashrom_layout_parse_fmap(layout, flashctx, fmap)) {
422*0d6140beSAndroid Build Coastguard Worker msg_gerr("Failed to add fmap regions to layout.\n");
423*0d6140beSAndroid Build Coastguard Worker ret = 1;
424*0d6140beSAndroid Build Coastguard Worker }
425*0d6140beSAndroid Build Coastguard Worker
426*0d6140beSAndroid Build Coastguard Worker free(fmap);
427*0d6140beSAndroid Build Coastguard Worker return ret;
428*0d6140beSAndroid Build Coastguard Worker #endif
429*0d6140beSAndroid Build Coastguard Worker }
430*0d6140beSAndroid Build Coastguard Worker
flashrom_layout_read_fmap_from_buffer(struct flashrom_layout ** const layout,struct flashctx * const flashctx,const uint8_t * const buf,size_t size)431*0d6140beSAndroid Build Coastguard Worker int flashrom_layout_read_fmap_from_buffer(struct flashrom_layout **const layout,
432*0d6140beSAndroid Build Coastguard Worker struct flashctx *const flashctx, const uint8_t *const buf, size_t size)
433*0d6140beSAndroid Build Coastguard Worker {
434*0d6140beSAndroid Build Coastguard Worker #ifndef __FLASHROM_LITTLE_ENDIAN__
435*0d6140beSAndroid Build Coastguard Worker return 3;
436*0d6140beSAndroid Build Coastguard Worker #else
437*0d6140beSAndroid Build Coastguard Worker struct fmap *fmap = NULL;
438*0d6140beSAndroid Build Coastguard Worker int ret = 1;
439*0d6140beSAndroid Build Coastguard Worker
440*0d6140beSAndroid Build Coastguard Worker if (!buf || !size)
441*0d6140beSAndroid Build Coastguard Worker goto _ret;
442*0d6140beSAndroid Build Coastguard Worker
443*0d6140beSAndroid Build Coastguard Worker msg_gdbg("Attempting to read fmap from buffer.\n");
444*0d6140beSAndroid Build Coastguard Worker if (fmap_read_from_buffer(&fmap, buf, size)) {
445*0d6140beSAndroid Build Coastguard Worker msg_gerr("Failed to read fmap from buffer.\n");
446*0d6140beSAndroid Build Coastguard Worker goto _ret;
447*0d6140beSAndroid Build Coastguard Worker }
448*0d6140beSAndroid Build Coastguard Worker
449*0d6140beSAndroid Build Coastguard Worker msg_gdbg("Adding fmap layout to global layout.\n");
450*0d6140beSAndroid Build Coastguard Worker if (flashrom_layout_parse_fmap(layout, flashctx, fmap)) {
451*0d6140beSAndroid Build Coastguard Worker msg_gerr("Failed to add fmap regions to layout.\n");
452*0d6140beSAndroid Build Coastguard Worker goto _free_ret;
453*0d6140beSAndroid Build Coastguard Worker }
454*0d6140beSAndroid Build Coastguard Worker
455*0d6140beSAndroid Build Coastguard Worker ret = 0;
456*0d6140beSAndroid Build Coastguard Worker _free_ret:
457*0d6140beSAndroid Build Coastguard Worker free(fmap);
458*0d6140beSAndroid Build Coastguard Worker _ret:
459*0d6140beSAndroid Build Coastguard Worker return ret;
460*0d6140beSAndroid Build Coastguard Worker #endif
461*0d6140beSAndroid Build Coastguard Worker }
462*0d6140beSAndroid Build Coastguard Worker
flashrom_layout_set(struct flashrom_flashctx * const flashctx,const struct flashrom_layout * const layout)463*0d6140beSAndroid Build Coastguard Worker void flashrom_layout_set(struct flashrom_flashctx *const flashctx, const struct flashrom_layout *const layout)
464*0d6140beSAndroid Build Coastguard Worker {
465*0d6140beSAndroid Build Coastguard Worker flashctx->layout = layout;
466*0d6140beSAndroid Build Coastguard Worker }
467*0d6140beSAndroid Build Coastguard Worker
flashrom_wp_cfg_new(struct flashrom_wp_cfg ** cfg)468*0d6140beSAndroid Build Coastguard Worker enum flashrom_wp_result flashrom_wp_cfg_new(struct flashrom_wp_cfg **cfg)
469*0d6140beSAndroid Build Coastguard Worker {
470*0d6140beSAndroid Build Coastguard Worker *cfg = calloc(1, sizeof(**cfg));
471*0d6140beSAndroid Build Coastguard Worker return *cfg ? 0 : FLASHROM_WP_ERR_OTHER;
472*0d6140beSAndroid Build Coastguard Worker }
473*0d6140beSAndroid Build Coastguard Worker
flashrom_wp_cfg_release(struct flashrom_wp_cfg * cfg)474*0d6140beSAndroid Build Coastguard Worker void flashrom_wp_cfg_release(struct flashrom_wp_cfg *cfg)
475*0d6140beSAndroid Build Coastguard Worker {
476*0d6140beSAndroid Build Coastguard Worker free(cfg);
477*0d6140beSAndroid Build Coastguard Worker }
478*0d6140beSAndroid Build Coastguard Worker
flashrom_wp_set_mode(struct flashrom_wp_cfg * cfg,enum flashrom_wp_mode mode)479*0d6140beSAndroid Build Coastguard Worker void flashrom_wp_set_mode(struct flashrom_wp_cfg *cfg, enum flashrom_wp_mode mode)
480*0d6140beSAndroid Build Coastguard Worker {
481*0d6140beSAndroid Build Coastguard Worker cfg->mode = mode;
482*0d6140beSAndroid Build Coastguard Worker }
483*0d6140beSAndroid Build Coastguard Worker
flashrom_wp_get_mode(const struct flashrom_wp_cfg * cfg)484*0d6140beSAndroid Build Coastguard Worker enum flashrom_wp_mode flashrom_wp_get_mode(const struct flashrom_wp_cfg *cfg)
485*0d6140beSAndroid Build Coastguard Worker {
486*0d6140beSAndroid Build Coastguard Worker return cfg->mode;
487*0d6140beSAndroid Build Coastguard Worker }
488*0d6140beSAndroid Build Coastguard Worker
flashrom_wp_set_range(struct flashrom_wp_cfg * cfg,size_t start,size_t len)489*0d6140beSAndroid Build Coastguard Worker void flashrom_wp_set_range(struct flashrom_wp_cfg *cfg, size_t start, size_t len)
490*0d6140beSAndroid Build Coastguard Worker {
491*0d6140beSAndroid Build Coastguard Worker cfg->range.start = start;
492*0d6140beSAndroid Build Coastguard Worker cfg->range.len = len;
493*0d6140beSAndroid Build Coastguard Worker }
494*0d6140beSAndroid Build Coastguard Worker
flashrom_wp_get_range(size_t * start,size_t * len,const struct flashrom_wp_cfg * cfg)495*0d6140beSAndroid Build Coastguard Worker void flashrom_wp_get_range(size_t *start, size_t *len, const struct flashrom_wp_cfg *cfg)
496*0d6140beSAndroid Build Coastguard Worker {
497*0d6140beSAndroid Build Coastguard Worker *start = cfg->range.start;
498*0d6140beSAndroid Build Coastguard Worker *len = cfg->range.len;
499*0d6140beSAndroid Build Coastguard Worker }
500*0d6140beSAndroid Build Coastguard Worker
flashrom_wp_write_cfg(struct flashctx * flash,const struct flashrom_wp_cfg * cfg)501*0d6140beSAndroid Build Coastguard Worker enum flashrom_wp_result flashrom_wp_write_cfg(struct flashctx *flash, const struct flashrom_wp_cfg *cfg)
502*0d6140beSAndroid Build Coastguard Worker {
503*0d6140beSAndroid Build Coastguard Worker if (flash->mst->buses_supported & BUS_PROG && flash->mst->opaque.wp_write_cfg)
504*0d6140beSAndroid Build Coastguard Worker return flash->mst->opaque.wp_write_cfg(flash, cfg);
505*0d6140beSAndroid Build Coastguard Worker
506*0d6140beSAndroid Build Coastguard Worker if (wp_operations_available(flash))
507*0d6140beSAndroid Build Coastguard Worker return wp_write_cfg(flash, cfg);
508*0d6140beSAndroid Build Coastguard Worker
509*0d6140beSAndroid Build Coastguard Worker return FLASHROM_WP_ERR_OTHER;
510*0d6140beSAndroid Build Coastguard Worker }
511*0d6140beSAndroid Build Coastguard Worker
flashrom_wp_read_cfg(struct flashrom_wp_cfg * cfg,struct flashctx * flash)512*0d6140beSAndroid Build Coastguard Worker enum flashrom_wp_result flashrom_wp_read_cfg(struct flashrom_wp_cfg *cfg, struct flashctx *flash)
513*0d6140beSAndroid Build Coastguard Worker {
514*0d6140beSAndroid Build Coastguard Worker if (flash->mst->buses_supported & BUS_PROG && flash->mst->opaque.wp_read_cfg)
515*0d6140beSAndroid Build Coastguard Worker return flash->mst->opaque.wp_read_cfg(cfg, flash);
516*0d6140beSAndroid Build Coastguard Worker
517*0d6140beSAndroid Build Coastguard Worker if (wp_operations_available(flash))
518*0d6140beSAndroid Build Coastguard Worker return wp_read_cfg(cfg, flash);
519*0d6140beSAndroid Build Coastguard Worker
520*0d6140beSAndroid Build Coastguard Worker return FLASHROM_WP_ERR_OTHER;
521*0d6140beSAndroid Build Coastguard Worker }
522*0d6140beSAndroid Build Coastguard Worker
flashrom_wp_get_available_ranges(struct flashrom_wp_ranges ** list,struct flashrom_flashctx * flash)523*0d6140beSAndroid Build Coastguard Worker enum flashrom_wp_result flashrom_wp_get_available_ranges(struct flashrom_wp_ranges **list, struct flashrom_flashctx *flash)
524*0d6140beSAndroid Build Coastguard Worker {
525*0d6140beSAndroid Build Coastguard Worker if (flash->mst->buses_supported & BUS_PROG && flash->mst->opaque.wp_get_ranges)
526*0d6140beSAndroid Build Coastguard Worker return flash->mst->opaque.wp_get_ranges(list, flash);
527*0d6140beSAndroid Build Coastguard Worker
528*0d6140beSAndroid Build Coastguard Worker if (wp_operations_available(flash))
529*0d6140beSAndroid Build Coastguard Worker return wp_get_available_ranges(list, flash);
530*0d6140beSAndroid Build Coastguard Worker
531*0d6140beSAndroid Build Coastguard Worker return FLASHROM_WP_ERR_OTHER;
532*0d6140beSAndroid Build Coastguard Worker }
533*0d6140beSAndroid Build Coastguard Worker
flashrom_wp_ranges_get_count(const struct flashrom_wp_ranges * list)534*0d6140beSAndroid Build Coastguard Worker size_t flashrom_wp_ranges_get_count(const struct flashrom_wp_ranges *list)
535*0d6140beSAndroid Build Coastguard Worker {
536*0d6140beSAndroid Build Coastguard Worker return list->count;
537*0d6140beSAndroid Build Coastguard Worker }
538*0d6140beSAndroid Build Coastguard Worker
flashrom_wp_ranges_get_range(size_t * start,size_t * len,const struct flashrom_wp_ranges * list,unsigned int index)539*0d6140beSAndroid Build Coastguard Worker enum flashrom_wp_result flashrom_wp_ranges_get_range(size_t *start, size_t *len, const struct flashrom_wp_ranges *list, unsigned int index)
540*0d6140beSAndroid Build Coastguard Worker {
541*0d6140beSAndroid Build Coastguard Worker if (index >= list->count)
542*0d6140beSAndroid Build Coastguard Worker return FLASHROM_WP_ERR_OTHER;
543*0d6140beSAndroid Build Coastguard Worker
544*0d6140beSAndroid Build Coastguard Worker *start = list->ranges[index].start;
545*0d6140beSAndroid Build Coastguard Worker *len = list->ranges[index].len;
546*0d6140beSAndroid Build Coastguard Worker
547*0d6140beSAndroid Build Coastguard Worker return 0;
548*0d6140beSAndroid Build Coastguard Worker }
549*0d6140beSAndroid Build Coastguard Worker
flashrom_wp_ranges_release(struct flashrom_wp_ranges * list)550*0d6140beSAndroid Build Coastguard Worker void flashrom_wp_ranges_release(struct flashrom_wp_ranges *list)
551*0d6140beSAndroid Build Coastguard Worker {
552*0d6140beSAndroid Build Coastguard Worker if (!list)
553*0d6140beSAndroid Build Coastguard Worker return;
554*0d6140beSAndroid Build Coastguard Worker
555*0d6140beSAndroid Build Coastguard Worker free(list->ranges);
556*0d6140beSAndroid Build Coastguard Worker free(list);
557*0d6140beSAndroid Build Coastguard Worker }
558