Exemplo n.º 1
0
/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
* Function:     emu_Read_Page_Main_Spare
* Inputs:       Write Buffer
*                       Address
*                       Buffer size
* Outputs:      PASS=0 (notice 0=ok here)
* Description:          Read from flash main+spare area
*
*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
u16 emu_Read_Page_Main_Spare(u8 *read_data, u32 Block,
				u16 Page, u16 PageCount)
{
	int i;

	nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
		       __FILE__, __LINE__, __func__);

	if (Block >= DeviceInfo.wTotalBlocks) {
		printk(KERN_ERR "Read Page Main+Spare "
		       "Error: Block Address too big\n");
		return FAIL;
	}

	if (Page + PageCount > DeviceInfo.wPagesPerBlock) {
		printk(KERN_ERR "Read Page Main+Spare "
		       "Error: Page number too big\n");
		return FAIL;
	}

	nand_dbg_print(NAND_DBG_DEBUG, "Read Page Main + Spare - "
		       "No. of pages %u block %u start page %u\n",
		       (unsigned int)PageCount,
		       (unsigned int)Block, (unsigned int)Page);

	for (i = 0; i < PageCount; i++) {
		if (NULL == flash_memory[Block * GLOB_LLD_PAGES + Page]) {
			memset(read_data, 0xFF, DeviceInfo.wPageSize);
		} else {
			memcpy(read_data, (u8 *) (flash_memory[Block *
								 GLOB_LLD_PAGES
								 + Page]),
			       DeviceInfo.wPageSize);
		}

		read_data += DeviceInfo.wPageSize;
		Page++;
	}

	return PASS;
}
Exemplo n.º 2
0
/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
* Function:     mtd_Flash_Release
* Inputs:       none
* Outputs:      PASS=0 (notice 0=ok here)
* Description:          Releases the flash.
*
*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
int mtd_Flash_Release(void)
{
	nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
		       __FILE__, __LINE__, __func__);
	if (!spectra_mtd)
		return PASS;

	put_mtd_device(spectra_mtd);
	spectra_mtd = NULL;

	return PASS;
}
Exemplo n.º 3
0
/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
* Function:     mtd_Read_Page_Main
* Inputs:       Read buffer address pointer
*               Block number
*               Page  number
*               Number of pages to process
* Outputs:      PASS=0 (notice 0=ok here)
* Description:  Read the data from the flash main area to the buffer
*
*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
u16 mtd_Read_Page_Main(u8 *read_data, u32 Block,
			  u16 Page, u16 PageCount)
{
	size_t retlen;
	int ret = 0;

	nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
		       __FILE__, __LINE__, __func__);

	if (Block >= DeviceInfo.wTotalBlocks)
		return FAIL;

	if (Page + PageCount > DeviceInfo.wPagesPerBlock)
		return FAIL;

	nand_dbg_print(NAND_DBG_DEBUG, "mtd_Read_Page_Main: "
		       "lba %u Page %u PageCount %u\n",
		       (unsigned int)Block,
		       (unsigned int)Page, (unsigned int)PageCount);


	while (PageCount) {
		ret = spectra_mtd->read(spectra_mtd,
					(Block * spectra_mtd->erasesize) + (Page * spectra_mtd->writesize),
					DeviceInfo.wPageDataSize, &retlen, read_data);
		if (ret) {
			printk(KERN_ERR "%s failed %d\n", __func__, ret);
			return FAIL;
		}
		read_data += DeviceInfo.wPageDataSize;
		Page++;
		PageCount--;
	}

	nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
		       __FILE__, __LINE__, __func__);

	return PASS;
}
Exemplo n.º 4
0
/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
* Function:     mtd_Erase_Block
* Inputs:       Address
* Outputs:      PASS=0 (notice 0=ok here)
* Description:          Erase a block
*
*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
u16 mtd_Erase_Block(u32 block_add)
{
	struct erase_info erase;
	DECLARE_COMPLETION_ONSTACK(comp);
	int ret;

	nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
		       __FILE__, __LINE__, __func__);

	if (block_add >= DeviceInfo.wTotalBlocks) {
		printk(KERN_ERR "mtd_Erase_Block error! "
		       "Too big block address: %d\n", block_add);
		return FAIL;
	}

	nand_dbg_print(NAND_DBG_DEBUG, "Erasing block %d\n",
		(int)block_add);

	erase.mtd = spectra_mtd;
	erase.callback = erase_callback;
	erase.addr = block_add * spectra_mtd->erasesize;
	erase.len = spectra_mtd->erasesize;
	erase.priv = (unsigned long)&comp;

	ret = spectra_mtd->erase(spectra_mtd, &erase);
	if (!ret) {
		wait_for_completion(&comp);
		if (erase.state != MTD_ERASE_DONE)
			ret = -EIO;
	}
	if (ret) {
		printk(KERN_WARNING "mtd_Erase_Block error! "
		       "erase of region [0x%llx, 0x%llx] failed\n",
		       erase.addr, erase.len);
		return FAIL;
	}

	return PASS;
}
Exemplo n.º 5
0
/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
* Function:     emu_Write_Page_Main_Spare
* Inputs:       Write buffer
*                       address
*                       buffer length
* Outputs:      PASS=0 (notice 0=ok here)
* Description:          Write the buffer to main+spare area of flash
*
*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
u16 emu_Write_Page_Main_Spare(u8 *write_data, u32 Block,
                              u16 Page, u16 page_count)
{
    u16 i;

    nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
                   __FILE__, __LINE__, __func__);

    if (Block >= DeviceInfo.wTotalBlocks) {
        printk(KERN_ERR "Write Page Main + Spare "
               "Error: Block Address too big\n");
        return FAIL;
    }

    if (Page + page_count > DeviceInfo.wPagesPerBlock) {
        printk(KERN_ERR "Write Page Main + Spare "
               "Error: Page number too big\n");
        return FAIL;
    }

    nand_dbg_print(NAND_DBG_DEBUG, "Write Page Main+Spare - "
                   "No. of pages %u block %u start page %u\n",
                   (unsigned int)page_count,
                   (unsigned int)Block, (unsigned int)Page);

    for (i = 0; i < page_count; i++) {
        if (NULL == flash_memory[Block * GLOB_LLD_PAGES + Page]) {
            printk(KERN_ERR "Run out of memory!\n");
            return FAIL;
        }
        memcpy((u8 *) (flash_memory[Block * GLOB_LLD_PAGES + Page]),
               write_data, DeviceInfo.wPageSize);
        write_data += DeviceInfo.wPageSize;
        Page++;
    }

    return PASS;
}
Exemplo n.º 6
0
/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
* Function:     mtd_Flash_Init
* Inputs:       none
* Outputs:      PASS=0 (notice 0=ok here)
* Description:  Creates & initializes the flash RAM array.
*
*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
u16 mtd_Flash_Init(void)
{
	if (mtddev == -1) {
		printk(KERN_ERR "No MTD device specified. Give mtddev parameter\n");
		return FAIL;
	}

	spectra_mtd = get_mtd_device(NULL, mtddev);
	if (!spectra_mtd) {
		printk(KERN_ERR "Failed to obtain MTD device #%d\n", mtddev);
		return FAIL;
	}

	nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
		       __FILE__, __LINE__, __func__);

	return PASS;
}
Exemplo n.º 7
0
u16 mtd_Read_Device_ID(void)
{
	uint64_t tmp;
	nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
		       __FILE__, __LINE__, __func__);

	if (!spectra_mtd)
		return FAIL;

	DeviceInfo.wDeviceMaker = 0;
	DeviceInfo.wDeviceType = 8;
	DeviceInfo.wSpectraStartBlock = SPECTRA_START_BLOCK;
	tmp = spectra_mtd->size;
	do_div(tmp, spectra_mtd->erasesize);
	DeviceInfo.wTotalBlocks = tmp;
	DeviceInfo.wSpectraEndBlock = DeviceInfo.wTotalBlocks - 1;
	DeviceInfo.wPagesPerBlock = spectra_mtd->erasesize / spectra_mtd->writesize;
	DeviceInfo.wPageSize = spectra_mtd->writesize + spectra_mtd->oobsize;
	DeviceInfo.wPageDataSize = spectra_mtd->writesize;
	DeviceInfo.wPageSpareSize = spectra_mtd->oobsize;
	DeviceInfo.wBlockSize = DeviceInfo.wPageSize * DeviceInfo.wPagesPerBlock;
	DeviceInfo.wBlockDataSize = DeviceInfo.wPageDataSize * DeviceInfo.wPagesPerBlock;
	DeviceInfo.wDataBlockNum = (u32) (DeviceInfo.wSpectraEndBlock -
						DeviceInfo.wSpectraStartBlock
						+ 1);
	DeviceInfo.MLCDevice = 0;//spectra_mtd->celltype & NAND_CI_CELLTYPE_MSK;
	DeviceInfo.nBitsInPageNumber =
		(u8)GLOB_Calc_Used_Bits(DeviceInfo.wPagesPerBlock);
	DeviceInfo.nBitsInPageDataSize =
		(u8)GLOB_Calc_Used_Bits(DeviceInfo.wPageDataSize);
	DeviceInfo.nBitsInBlockDataSize =
		(u8)GLOB_Calc_Used_Bits(DeviceInfo.wBlockDataSize);

#if CMD_DMA
	totalUsedBanks = 4;
	valid_banks[0] = 1;
	valid_banks[1] = 1;
	valid_banks[2] = 1;
	valid_banks[3] = 1;
#endif

	return PASS;
}
Exemplo n.º 8
0
u16 emu_Read_Device_ID(void)
{
    nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
                   __FILE__, __LINE__, __func__);

    DeviceInfo.wDeviceMaker = 0;
    DeviceInfo.wDeviceType = 8;
    DeviceInfo.wSpectraStartBlock = 36;
    DeviceInfo.wSpectraEndBlock = GLOB_LLD_BLOCKS - 1;
    DeviceInfo.wTotalBlocks = GLOB_LLD_BLOCKS;
    DeviceInfo.wPagesPerBlock = GLOB_LLD_PAGES;
    DeviceInfo.wPageSize = GLOB_LLD_PAGE_SIZE;
    DeviceInfo.wPageDataSize = GLOB_LLD_PAGE_DATA_SIZE;
    DeviceInfo.wPageSpareSize = GLOB_LLD_PAGE_SIZE -
                                GLOB_LLD_PAGE_DATA_SIZE;
    DeviceInfo.wBlockSize = DeviceInfo.wPageSize * GLOB_LLD_PAGES;
    DeviceInfo.wBlockDataSize = DeviceInfo.wPageDataSize * GLOB_LLD_PAGES;
    DeviceInfo.wDataBlockNum = (u32) (DeviceInfo.wSpectraEndBlock -
                                      DeviceInfo.wSpectraStartBlock
                                      + 1);
    DeviceInfo.MLCDevice = 1; /* Emulate MLC device */
    DeviceInfo.nBitsInPageNumber =
        (u8)GLOB_Calc_Used_Bits(DeviceInfo.wPagesPerBlock);
    DeviceInfo.nBitsInPageDataSize =
        (u8)GLOB_Calc_Used_Bits(DeviceInfo.wPageDataSize);
    DeviceInfo.nBitsInBlockDataSize =
        (u8)GLOB_Calc_Used_Bits(DeviceInfo.wBlockDataSize);

#if CMD_DMA
    totalUsedBanks = 4;
    valid_banks[0] = 1;
    valid_banks[1] = 1;
    valid_banks[2] = 1;
    valid_banks[3] = 1;
#endif

    return PASS;
}
Exemplo n.º 9
0
/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
* Function:     emu_Enable_Disable_Interrupts
* Inputs:       enable or disable
* Outputs:      none
* Description:  NOP
*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
void emu_Enable_Disable_Interrupts(u16 INT_ENABLE)
{
    nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
                   __FILE__, __LINE__, __func__);
}
Exemplo n.º 10
0
/* Read nand emu file and then fill it's content to flash_memory */
int emu_load_file_to_mem(void)
{
    mm_segment_t fs;
    struct file *nef_filp = NULL;
    struct inode *inode = NULL;
    loff_t nef_size = 0;
    loff_t tmp_file_offset, file_offset;
    ssize_t nread;
    int i, rc = -EINVAL;

    nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
                   __FILE__, __LINE__, __func__);

    fs = get_fs();
    set_fs(get_ds());

    nef_filp = filp_open("/root/nand_emu_file", O_RDWR | O_LARGEFILE, 0);
    if (IS_ERR(nef_filp)) {
        printk(KERN_ERR "filp_open error: "
               "Unable to open nand emu file!\n");
        return PTR_ERR(nef_filp);
    }

    if (nef_filp->f_path.dentry) {
        inode = nef_filp->f_path.dentry->d_inode;
    } else {
        printk(KERN_ERR "Can not get valid inode!\n");
        goto out;
    }

    nef_size = i_size_read(inode->i_mapping->host);
    if (nef_size <= 0) {
        printk(KERN_ERR "Invalid nand emu file size: "
               "0x%llx\n", nef_size);
        goto out;
    } else {
        nand_dbg_print(NAND_DBG_DEBUG, "nand emu file size: %lld\n",
                       nef_size);
    }

    file_offset = 0;
    for (i = 0; i < GLOB_LLD_BLOCKS * GLOB_LLD_PAGES; i++) {
        tmp_file_offset = file_offset;
        nread = vfs_read(nef_filp,
                         (char __user *)flash_memory[i],
                         GLOB_LLD_PAGE_SIZE, &tmp_file_offset);
        if (nread < GLOB_LLD_PAGE_SIZE) {
            printk(KERN_ERR "%s, Line %d - "
                   "nand emu file partial read: "
                   "%d bytes\n", __FILE__, __LINE__, (int)nread);
            goto out;
        }
        file_offset += GLOB_LLD_PAGE_SIZE;
    }
    rc = 0;

out:
    filp_close(nef_filp, current->files);
    set_fs(fs);
    return rc;
}