]>
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 | |
baaa35ad ZJS |
52 | if (info->type != MTD_NANDFLASH) |
53 | return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), | |
54 | "Not marked MTD_NANDFLASH."); | |
674c3412 | 55 | |
fc863dea KS |
56 | sector_size = info->writesize; |
57 | block_size = info->erasesize; | |
58 | size_in_megs = info->size / (1024 * 1024); | |
674c3412 | 59 | |
baaa35ad ZJS |
60 | if (!IN_SET(sector_size, SM_SECTOR_SIZE, SM_SMALL_PAGE)) |
61 | return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), | |
62 | "Unexpected sector size: %i", sector_size); | |
674c3412 | 63 | |
912541b0 KS |
64 | switch(size_in_megs) { |
65 | case 1: | |
66 | case 2: | |
67 | spare_count = 6; | |
68 | break; | |
69 | case 4: | |
70 | spare_count = 12; | |
71 | break; | |
72 | default: | |
73 | spare_count = 24; | |
74 | break; | |
75 | } | |
674c3412 | 76 | |
41b9d436 LP |
77 | for (offset = 0; offset < block_size * spare_count; offset += sector_size) { |
78 | (void) lseek(mtd_fd, SEEK_SET, offset); | |
79 | ||
9ed794a3 | 80 | if (read(mtd_fd, cis_buffer, SM_SECTOR_SIZE) == SM_SECTOR_SIZE) { |
912541b0 KS |
81 | cis_found = 1; |
82 | break; | |
83 | } | |
84 | } | |
674c3412 | 85 | |
baaa35ad ZJS |
86 | if (!cis_found) |
87 | return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), | |
88 | "CIS not found"); | |
674c3412 | 89 | |
912541b0 | 90 | if (memcmp(cis_buffer, cis_signature, sizeof(cis_signature)) != 0 && |
baaa35ad ZJS |
91 | memcmp(cis_buffer + SM_SMALL_PAGE, cis_signature, sizeof(cis_signature)) != 0) |
92 | return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), | |
93 | "CIS signature didn't match"); | |
674c3412 | 94 | |
912541b0 | 95 | printf("MTD_FTL=smartmedia\n"); |
41b9d436 | 96 | return 0; |
674c3412 | 97 | } |