]>
Commit | Line | Data |
---|---|---|
e7145211 | 1 | /* SPDX-License-Identifier: GPL-2.0+ */ |
674c3412 | 2 | /* |
810adae9 | 3 | * Copyright © 2010 - Maxim Levitsky |
674c3412 ML |
4 | * |
5 | * mtd_probe is free software; you can redistribute it and/or modify | |
6 | * it under the terms of the GNU General Public License as published by | |
7 | * the Free Software Foundation; either version 2 of the License, or | |
8 | * (at your option) any later version. | |
9 | * | |
10 | * mtd_probe 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 | * You should have received a copy of the GNU General Public License | |
16 | * along with mtd_probe; if not, write to the Free Software | |
ad29a9f1 | 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, |
674c3412 ML |
18 | * Boston, MA 02110-1301 USA |
19 | */ | |
20 | ||
41b9d436 | 21 | #include <errno.h> |
cf0fbc49 TA |
22 | #include <fcntl.h> |
23 | #include <mtd/mtd-user.h> | |
24 | #include <stdint.h> | |
674c3412 ML |
25 | #include <stdio.h> |
26 | #include <stdlib.h> | |
5f307a98 | 27 | #include <string.h> |
674c3412 | 28 | #include <sys/stat.h> |
cf0fbc49 | 29 | #include <sys/types.h> |
674c3412 | 30 | #include <unistd.h> |
cf0fbc49 | 31 | |
451cdf78 | 32 | #include "alloc-util.h" |
674c3412 ML |
33 | #include "mtd_probe.h" |
34 | ||
35 | static const uint8_t cis_signature[] = { | |
912541b0 | 36 | 0x01, 0x03, 0xD9, 0x01, 0xFF, 0x18, 0x02, 0xDF, 0x01, 0x20 |
674c3412 ML |
37 | }; |
38 | ||
41b9d436 | 39 | int probe_smart_media(int mtd_fd, mtd_info_t* info) { |
fc863dea KS |
40 | int sector_size; |
41 | int block_size; | |
42 | int size_in_megs; | |
43 | int spare_count; | |
451cdf78 | 44 | _cleanup_free_ uint8_t *cis_buffer = NULL; |
fc863dea KS |
45 | int offset; |
46 | int cis_found = 0; | |
5f307a98 | 47 | |
451cdf78 | 48 | cis_buffer = malloc(SM_SECTOR_SIZE); |
912541b0 | 49 | if (!cis_buffer) |
41b9d436 | 50 | return log_oom(); |
674c3412 | 51 | |
41b9d436 LP |
52 | if (info->type != MTD_NANDFLASH) { |
53 | log_debug("Not marked MTD_NANDFLASH."); | |
54 | return -EINVAL; | |
55 | } | |
674c3412 | 56 | |
fc863dea KS |
57 | sector_size = info->writesize; |
58 | block_size = info->erasesize; | |
59 | size_in_megs = info->size / (1024 * 1024); | |
674c3412 | 60 | |
41b9d436 LP |
61 | if (!IN_SET(sector_size, SM_SECTOR_SIZE, SM_SMALL_PAGE)) { |
62 | log_debug("Unexpected sector size: %i", sector_size); | |
63 | return -EINVAL; | |
64 | } | |
674c3412 | 65 | |
912541b0 KS |
66 | switch(size_in_megs) { |
67 | case 1: | |
68 | case 2: | |
69 | spare_count = 6; | |
70 | break; | |
71 | case 4: | |
72 | spare_count = 12; | |
73 | break; | |
74 | default: | |
75 | spare_count = 24; | |
76 | break; | |
77 | } | |
674c3412 | 78 | |
41b9d436 LP |
79 | for (offset = 0; offset < block_size * spare_count; offset += sector_size) { |
80 | (void) lseek(mtd_fd, SEEK_SET, offset); | |
81 | ||
9ed794a3 | 82 | if (read(mtd_fd, cis_buffer, SM_SECTOR_SIZE) == SM_SECTOR_SIZE) { |
912541b0 KS |
83 | cis_found = 1; |
84 | break; | |
85 | } | |
86 | } | |
674c3412 | 87 | |
41b9d436 LP |
88 | if (!cis_found) { |
89 | log_debug("CIS not found"); | |
90 | return -EINVAL; | |
91 | } | |
674c3412 | 92 | |
912541b0 | 93 | if (memcmp(cis_buffer, cis_signature, sizeof(cis_signature)) != 0 && |
41b9d436 LP |
94 | memcmp(cis_buffer + SM_SMALL_PAGE, cis_signature, sizeof(cis_signature)) != 0) { |
95 | log_debug("CIS signature didn't match"); | |
96 | return -EINVAL; | |
97 | } | |
674c3412 | 98 | |
912541b0 | 99 | printf("MTD_FTL=smartmedia\n"); |
41b9d436 | 100 | return 0; |
674c3412 | 101 | } |