Lines Matching +full:nand +full:- +full:oob +full:- +full:sector +full:- +full:size

1 // SPDX-License-Identifier: GPL-2.0-only
54 unsigned long size; member
60 /* Must be ordered by size */
73 static int get_chs(unsigned long size, unsigned short *cyl, unsigned char *head, in get_chs() argument
80 while (chs_table[k].size > 0 && size > chs_table[k].size) in get_chs()
83 if (chs_table[k].size > 0) { in get_chs()
96 /* These bytes are the signature for the CIS/IDI sector */
101 /* Read and check for a valid CIS sector */
109 cis_sector = -1; in get_valid_cis_sector()
116 * Look for CIS/IDI sector on the first GOOD block (give up after 4 bad in get_valid_cis_sector()
120 for (k = 0, offset = 0; k < 4; k++, offset += mtd->erasesize) { in get_valid_cis_sector()
125 /* CIS pattern match on the sector buffer */ in get_valid_cis_sector()
128 "SSFDC_RO:can't read CIS/IDI sector\n"); in get_valid_cis_sector()
134 pr_debug("SSFDC_RO: CIS/IDI sector not found" in get_valid_cis_sector()
135 " on %s (mtd%d)\n", mtd->name, in get_valid_cis_sector()
136 mtd->index); in get_valid_cis_sector()
147 /* Read physical sector (wrapper to MTD_READ) */
157 return -1; in read_physical_sector()
176 return -1; in read_raw_oob()
181 /* Parity calculator on a word of n bit size */
182 static int get_parity(int number, int size) in get_parity() argument
188 for (k = 0; k < size; k++) { in get_parity()
195 /* Read and validate the logical block address field stored in the OOB */
199 int offset[2] = {6, 11}; /* offset of the 2 address fields within OOB */ in get_logical_address()
230 block_address = -2; in get_logical_address()
244 struct mtd_info *mtd = ssfdc->mbd.mtd; in build_logical_block_map()
247 ssfdc->map_len, in build_logical_block_map()
248 (unsigned long)ssfdc->map_len * ssfdc->erase_size / 1024); in build_logical_block_map()
251 for (phys_block = ssfdc->cis_block + 1; phys_block < ssfdc->map_len; in build_logical_block_map()
253 offset = (unsigned long)phys_block * ssfdc->erase_size; in build_logical_block_map()
261 return -1; in build_logical_block_map()
272 ssfdc->logic_block_map[block_address] = in build_logical_block_map()
288 /* Check for small page NAND flash */ in ssfdcr_add_mtd()
289 if (!mtd_type_is_nand(mtd) || mtd->oobsize != OOB_SIZE || in ssfdcr_add_mtd()
290 mtd->size > UINT_MAX) in ssfdcr_add_mtd()
293 /* Check for SSDFC format by reading CIS/IDI sector */ in ssfdcr_add_mtd()
295 if (cis_sector == -1) in ssfdcr_add_mtd()
302 ssfdc->mbd.mtd = mtd; in ssfdcr_add_mtd()
303 ssfdc->mbd.devnum = -1; in ssfdcr_add_mtd()
304 ssfdc->mbd.tr = tr; in ssfdcr_add_mtd()
305 ssfdc->mbd.readonly = 1; in ssfdcr_add_mtd()
307 ssfdc->cis_block = cis_sector / (mtd->erasesize >> SECTOR_SHIFT); in ssfdcr_add_mtd()
308 ssfdc->erase_size = mtd->erasesize; in ssfdcr_add_mtd()
309 ssfdc->map_len = (u32)mtd->size / mtd->erasesize; in ssfdcr_add_mtd()
312 ssfdc->cis_block, ssfdc->erase_size, ssfdc->map_len, in ssfdcr_add_mtd()
313 DIV_ROUND_UP(ssfdc->map_len, MAX_PHYS_BLK_PER_ZONE)); in ssfdcr_add_mtd()
316 ssfdc->heads = 16; in ssfdcr_add_mtd()
317 ssfdc->sectors = 32; in ssfdcr_add_mtd()
318 get_chs(mtd->size, NULL, &ssfdc->heads, &ssfdc->sectors); in ssfdcr_add_mtd()
319 ssfdc->cylinders = (unsigned short)(((u32)mtd->size >> SECTOR_SHIFT) / in ssfdcr_add_mtd()
320 ((long)ssfdc->sectors * (long)ssfdc->heads)); in ssfdcr_add_mtd()
323 ssfdc->cylinders, ssfdc->heads , ssfdc->sectors, in ssfdcr_add_mtd()
324 (long)ssfdc->cylinders * (long)ssfdc->heads * in ssfdcr_add_mtd()
325 (long)ssfdc->sectors); in ssfdcr_add_mtd()
327 ssfdc->mbd.size = (long)ssfdc->heads * (long)ssfdc->cylinders * in ssfdcr_add_mtd()
328 (long)ssfdc->sectors; in ssfdcr_add_mtd()
331 ssfdc->logic_block_map = in ssfdcr_add_mtd()
332 kmalloc_array(ssfdc->map_len, in ssfdcr_add_mtd()
333 sizeof(ssfdc->logic_block_map[0]), GFP_KERNEL); in ssfdcr_add_mtd()
334 if (!ssfdc->logic_block_map) in ssfdcr_add_mtd()
336 memset(ssfdc->logic_block_map, 0xff, sizeof(ssfdc->logic_block_map[0]) * in ssfdcr_add_mtd()
337 ssfdc->map_len); in ssfdcr_add_mtd()
344 if (add_mtd_blktrans_dev(&ssfdc->mbd)) in ssfdcr_add_mtd()
348 ssfdc->mbd.devnum + 'a', mtd->index, mtd->name); in ssfdcr_add_mtd()
352 kfree(ssfdc->logic_block_map); in ssfdcr_add_mtd()
361 pr_debug("SSFDC_RO: remove_dev (i=%d)\n", dev->devnum); in ssfdcr_remove_dev()
364 kfree(ssfdc->logic_block_map); in ssfdcr_remove_dev()
373 sectors_per_block = ssfdc->erase_size >> SECTOR_SHIFT; in ssfdcr_readsect()
381 BUG_ON(block_address >= ssfdc->map_len); in ssfdcr_readsect()
383 block_address = ssfdc->logic_block_map[block_address]; in ssfdcr_readsect()
397 if (read_physical_sector(ssfdc->mbd.mtd, buf, sect_no) < 0) in ssfdcr_readsect()
398 return -EIO; in ssfdcr_readsect()
411 ssfdc->cylinders, ssfdc->heads, ssfdc->sectors); in ssfdcr_getgeo()
413 geo->heads = ssfdc->heads; in ssfdcr_getgeo()
414 geo->sectors = ssfdc->sectors; in ssfdcr_getgeo()
415 geo->cylinders = ssfdc->cylinders; in ssfdcr_getgeo()
440 printk(KERN_INFO "SSFDC read-only Flash Translation layer\n"); in init_ssfdcr()
455 MODULE_DESCRIPTION("Flash Translation Layer for read-only SSFDC SmartMedia card");