162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Copyright © 2009 - Maxim Levitsky 462306a36Sopenharmony_ci * Common routines & support for SmartMedia/xD format 562306a36Sopenharmony_ci */ 662306a36Sopenharmony_ci#include <linux/bitops.h> 762306a36Sopenharmony_ci#include <linux/mtd/mtd.h> 862306a36Sopenharmony_ci 962306a36Sopenharmony_ci/* Full oob structure as written on the flash */ 1062306a36Sopenharmony_cistruct sm_oob { 1162306a36Sopenharmony_ci uint32_t reserved; 1262306a36Sopenharmony_ci uint8_t data_status; 1362306a36Sopenharmony_ci uint8_t block_status; 1462306a36Sopenharmony_ci uint8_t lba_copy1[2]; 1562306a36Sopenharmony_ci uint8_t ecc2[3]; 1662306a36Sopenharmony_ci uint8_t lba_copy2[2]; 1762306a36Sopenharmony_ci uint8_t ecc1[3]; 1862306a36Sopenharmony_ci} __packed; 1962306a36Sopenharmony_ci 2062306a36Sopenharmony_ci 2162306a36Sopenharmony_ci/* one sector is always 512 bytes, but it can consist of two nand pages */ 2262306a36Sopenharmony_ci#define SM_SECTOR_SIZE 512 2362306a36Sopenharmony_ci 2462306a36Sopenharmony_ci/* oob area is also 16 bytes, but might be from two pages */ 2562306a36Sopenharmony_ci#define SM_OOB_SIZE 16 2662306a36Sopenharmony_ci 2762306a36Sopenharmony_ci/* This is maximum zone size, and all devices that have more that one zone 2862306a36Sopenharmony_ci have this size */ 2962306a36Sopenharmony_ci#define SM_MAX_ZONE_SIZE 1024 3062306a36Sopenharmony_ci 3162306a36Sopenharmony_ci/* support for small page nand */ 3262306a36Sopenharmony_ci#define SM_SMALL_PAGE 256 3362306a36Sopenharmony_ci#define SM_SMALL_OOB_SIZE 8 3462306a36Sopenharmony_ci 3562306a36Sopenharmony_ci 3662306a36Sopenharmony_ciint sm_register_device(struct mtd_info *mtd, int smartmedia); 3762306a36Sopenharmony_ci 3862306a36Sopenharmony_ci 3962306a36Sopenharmony_cistatic inline int sm_sector_valid(struct sm_oob *oob) 4062306a36Sopenharmony_ci{ 4162306a36Sopenharmony_ci return hweight16(oob->data_status) >= 5; 4262306a36Sopenharmony_ci} 4362306a36Sopenharmony_ci 4462306a36Sopenharmony_cistatic inline int sm_block_valid(struct sm_oob *oob) 4562306a36Sopenharmony_ci{ 4662306a36Sopenharmony_ci return hweight16(oob->block_status) >= 7; 4762306a36Sopenharmony_ci} 4862306a36Sopenharmony_ci 4962306a36Sopenharmony_cistatic inline int sm_block_erased(struct sm_oob *oob) 5062306a36Sopenharmony_ci{ 5162306a36Sopenharmony_ci static const uint32_t erased_pattern[4] = { 5262306a36Sopenharmony_ci 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF }; 5362306a36Sopenharmony_ci 5462306a36Sopenharmony_ci /* First test for erased block */ 5562306a36Sopenharmony_ci if (!memcmp(oob, erased_pattern, sizeof(*oob))) 5662306a36Sopenharmony_ci return 1; 5762306a36Sopenharmony_ci return 0; 5862306a36Sopenharmony_ci} 59