📄 flash_nand_samsung.c
字号:
64, /* Page Count */ 2048, /* Page Size */ 2112, /* Total Page Size */ 0xEC, /* Maker ID */ 0x34, /* Device ID */ FLASHI_NAND_16BIT, /* Device width */ FLASH_ONENAND_BLOCK_UNLOCK | /* dev_specfic_flag1 */ FLASH_ONENAND_PINGPONG_MREAD | FLASH_ONENAND_EVERIFY_BLOCK, 0x0, /* dev_specfic_flag2 */ }, /* END Samsung KFG1G16Q2A flash */ /*==========================================================*/ /*==========================================================*/ { /* Samsung 512Mbit flash */ "samsung_OneNAND_512Mbit", /* Device Name */ 512, /* Block Count */ 64, /* Page Count */ 2048, /* Page Size */ 2112, /* Total Page Size */ 0xEC, /* Maker ID */ 0x24, /* Device ID */ FLASHI_NAND_16BIT, /* Device width */ FLASH_ONENAND_RANGE_UNLOCK | /* dev_specfic_flag1 */ FLASH_ONENAND_PINGPONG_MREAD | FLASH_ONENAND_EVERIFY_PAGES, 0x0, /* dev_specfic_flag2 */ }, /* END Samsung KFG1G16Q2A flash */ /*==========================================================*/};/***********************************************************************FUNCTION samsung_probeDESCRIPTION This function looks through the devices it knows about to find a match on both maker ID and device ID, and if it finds a match, returns a pointer to the device structure.RETURN VALUE FS_DEVICE_OK if match found FSI_NO_DEVICE if match not found **********************************************************************/intsamsung_probe (fsi_device_t priv, int maker_id, int device_id){ int dev_no; int total_no_devices = sizeof (samsung_devices_array) / sizeof (struct flash_device_config_data); for (dev_no = 0; dev_no < total_no_devices; dev_no++) { if ((samsung_devices_array[dev_no].maker_id == maker_id) && (samsung_devices_array[dev_no].device_id == device_id)) { /* We have found a match of IDs */ /* Fill in device structures, public, then private */ priv->pub_dev.bad_block_check = samsung_nand_bad_block_check; priv->dev_info = samsung_devices_array[dev_no]; /* * Fill in individual value fields. * For right now, allow access to entire flash. */ priv->partition_blk_start = 0; priv->partition_blk_limit = samsung_devices_array[dev_no].block_count; return FS_DEVICE_OK; } } return FSI_NO_DEVICE;}/***********************************************************************FUNCTION samsung_nand_bad_block_checkDESCRIPTION This function should be called to determine the initial bad blocks marked by the device maker. If the 517th column of the 1st or 2nd page of a block has non FFh data then that block is considered invalid.RETURN VALUE FS_DEVICE_OK if the block is ok, else FS_DEVICE_BAD_BLOCK**********************************************************************/static intsamsung_nand_bad_block_check (fs_device_t self, block_id block){ fsi_device_t priv = (fsi_device_t)self; page_id page; page_id page_offset; uint32 status; uint32 spare_unit = 0; int result = FS_DEVICE_OK; int spare_offset; int len; spare_offset = priv->ctlr.get_bad_block_offset(self); len = (priv->dev_info.device_width == FLASHI_NAND_16BIT) ? 2 : 1; /* Set the first page number */ page = (block << priv->block_size_shift); /* Check the first page of the block */ for (page_offset = 0; page_offset < 2; page_offset++) { status = flash_nand_read_spare_bytes(self, (page + page_offset), spare_offset, len, &spare_unit); if (status != FS_DEVICE_OK) { /* Error encountered while reading the spare bytes. Return bad block so as not to have this block erased by mistake and allow the issue to be debugged */ return FS_DEVICE_BAD_BLOCK; } result = flash_nand_check_bad_block_marker (self, spare_unit); if(result == FS_DEVICE_BAD_BLOCK) { TPRINTF(3,("Spare unit value 0x%x for block 0x%x\n", spare_unit, block)); break; } } return result;} /* End of samsung_nand_bad_block_check *//***********************************************************************FUNCTION samsung_onenand_probeDESCRIPTION This function looks through the devices it knows about to find a match on both maker ID and device ID, and if it finds a match, returns a pointer to the device structure.RETURN VALUE FS_DEVICE_OK if match found FSI_NO_DEVICE if match not found **********************************************************************/intsamsung_onenand_probe (fsi_device_t priv, int maker_id, int device_id){ int dev_no; int total_no_devices = sizeof (samsung_onenand_devices_array) / sizeof (struct flash_device_config_data); for (dev_no = 0; dev_no < total_no_devices; dev_no++) { if ((samsung_onenand_devices_array[dev_no].maker_id == maker_id) && (samsung_onenand_devices_array[dev_no].device_id == device_id)) { /* We have found a match of IDs */ /* Fill in device structures, public, then private */ priv->pub_dev.bad_block_check = samsung_onenand_bad_block_check; priv->dev_info = samsung_onenand_devices_array[dev_no]; /* * Fill in individual value fields. * For right now, allow access to entire flash. */ priv->partition_blk_start = 0; priv->partition_blk_limit = samsung_onenand_devices_array[dev_no].block_count; return FS_DEVICE_OK; } } return FSI_NO_DEVICE;}/***********************************************************************FUNCTION samsung_onenand_bad_block_checkDESCRIPTION This function should be called to determine the initial bad blocks marked by the device maker. If the 517th column of the 1st or 2nd page of a block has non FFh data then that block is considered invalid.RETURN VALUE FS_DEVICE_OK if the block is ok, else FS_DEVICE_BAD_BLOCK**********************************************************************/static intsamsung_onenand_bad_block_check (fs_device_t self, block_id block){ fsi_device_t priv = (fsi_device_t)self; page_id page; page_id page_offset; uint32 status; uint32 spare_unit = 0; uint32 pages_in_block = priv->dev_info.page_count; int result = FS_DEVICE_OK; /* Set the first page number */ page = (block * pages_in_block); /* Check the first page of the block */ for (page_offset = 0; page_offset < 2; page_offset++) { status = flash_nand_read_spare_bytes(self, (page + page_offset), 0, 2, &spare_unit); if (status != FS_DEVICE_OK) { /* Error encountered while reading the spare bytes. Return bad block so as not to have this block erased by mistake and allow the issue to be debugged */ return FS_DEVICE_BAD_BLOCK; } result = flash_nand_check_bad_block_marker (self, spare_unit); if(result == FS_DEVICE_BAD_BLOCK) { TPRINTF(3,("Spare unit value 0x%x for block 0x%x\n", spare_unit, block)); break; } } return result; } /* End of samsung_onenand_bad_block_check */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -