1 /*
2 * This file is part of the flashrom project.
3 *
4 * Copyright 2021 Google LLC
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 */
15
16 #include <string.h>
17 #include "flash.h"
18
19 /* Cros flashrom needs to be able to automatically identify the board's flash
20 * without additional input. If multiple flashchip entries are considered to be
21 * suitable matches, flashrom will fail to identify the chip and be unable to
22 * perform the requested operations.
23 *
24 * This function allows flashrom to always pick a single flashchip entry, by
25 * filtering out all unwanted duplicate flashchip entries and leaving only the
26 * one we want to use.
27 */
is_chipname_duplicate(const struct flashchip * chip)28 bool is_chipname_duplicate(const struct flashchip *chip)
29 {
30 /* The "GD25B128B/GD25Q128B" and "GD25Q127C/GD25Q128C" chip entries
31 * have the same vendor and model IDs.
32 *
33 * Historically cros flashrom only had the "C" entry; an initial
34 * attempt to import the "B" from upstream entry resulted in flashrom
35 * being unable to identify the flash on Atlas and Nocturne boards,
36 * causing flashrom failures documented in b/168943314.
37 *
38 * After introducing GD25Q128E, we need to split GD25Q127C/GD25Q128C
39 * into GD25Q127C/GD25Q128E and GD25Q128C since 127C and 128C actually
40 * have different features (mainly QPI).
41 * GD25Q128C is phased out now, so we mark GD25Q128C as duplicated.
42 */
43 if(!strcmp(chip->name, "GD25B128B/GD25Q128B") ||
44 !strcmp(chip->name, "GD25Q128C"))
45 return true;
46
47 /* MX25L128... has been split into several entries:
48 * "MX25L12805D" (b/190574697), "MX25L12833F",
49 * "MX25L12835F/MX25L12873F", "MX25L12845E/MX25L12865E" (b/332486637),
50 * and "MX25L12850F" (CB:81350),
51 * We are actually using MX25L12833F, so mark the others as duplicate.
52 */
53 if(!strcmp(chip->name, "MX25L12805D") ||
54 !strcmp(chip->name, "MX25L12835F/MX25L12873F") ||
55 !strcmp(chip->name, "MX25L12845E/MX25L12865E") ||
56 !strcmp(chip->name, "MX25L12850F"))
57 return true;
58
59 /* W25Q256.V has been split into two entries: W25Q256FV and
60 * W25Q256JV_Q.
61 * Marking the latter as duplicate.
62 */
63 if(!strcmp(chip->name, "W25Q256JV_Q")) return true;
64
65 /* W25Q32.W has been split into three entries:
66 * W25Q32BW/W25Q32CW/W25Q32DW, W25Q32FW and W25Q32JW...Q
67 * We are actually using W25Q32DW, so mark the last two as duplicate.
68 */
69 if(!strcmp(chip->name, "W25Q32FW") ||
70 !strcmp(chip->name, "W25Q32JW...Q"))
71 return true;
72
73 /* The "GD25LQ255E" and "GD25LB256F/GD25LR256F" and chip entries
74 * have the same vendor and model IDs.
75 * Marking the latter as duplicate.
76 */
77 if(!strcmp(chip->name, "GD25LB256F/GD25LR256F")) return true;
78
79 return false;
80 }
81