1 | /* SPDX-License-Identifier: GPL-2.0-only */ |
2 | /* |
3 | * Copyright © 2009 - Maxim Levitsky |
4 | * Common routines & support for SmartMedia/xD format |
5 | */ |
6 | #include <linux/bitops.h> |
7 | #include <linux/mtd/mtd.h> |
8 | |
9 | /* Full oob structure as written on the flash */ |
10 | struct sm_oob { |
11 | uint32_t reserved; |
12 | uint8_t data_status; |
13 | uint8_t block_status; |
14 | uint8_t lba_copy1[2]; |
15 | uint8_t ecc2[3]; |
16 | uint8_t lba_copy2[2]; |
17 | uint8_t ecc1[3]; |
18 | } __packed; |
19 | |
20 | |
21 | /* one sector is always 512 bytes, but it can consist of two nand pages */ |
22 | #define SM_SECTOR_SIZE 512 |
23 | |
24 | /* oob area is also 16 bytes, but might be from two pages */ |
25 | #define SM_OOB_SIZE 16 |
26 | |
27 | /* This is maximum zone size, and all devices that have more that one zone |
28 | have this size */ |
29 | #define SM_MAX_ZONE_SIZE 1024 |
30 | |
31 | /* support for small page nand */ |
32 | #define SM_SMALL_PAGE 256 |
33 | #define SM_SMALL_OOB_SIZE 8 |
34 | |
35 | |
36 | int sm_register_device(struct mtd_info *mtd, int smartmedia); |
37 | |
38 | |
39 | static inline int sm_sector_valid(struct sm_oob *oob) |
40 | { |
41 | return hweight16(oob->data_status) >= 5; |
42 | } |
43 | |
44 | static inline int sm_block_valid(struct sm_oob *oob) |
45 | { |
46 | return hweight16(oob->block_status) >= 7; |
47 | } |
48 | |
49 | static inline int sm_block_erased(struct sm_oob *oob) |
50 | { |
51 | static const uint32_t erased_pattern[4] = { |
52 | 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF }; |
53 | |
54 | /* First test for erased block */ |
55 | if (!memcmp(p: oob, q: erased_pattern, size: sizeof(*oob))) |
56 | return 1; |
57 | return 0; |
58 | } |
59 | |