mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-11-10 07:04:28 +00:00
mtd: nand: Remove docg4 driver and palmtreo680 flashing tool
Commit ad4f54ea86
("arm: Remove palmtreo680 board") removed the only
user of the docg4 driver and the palmtreo680 image flashing tool. This
patch removes them.
Signed-off-by: Scott Wood <oss@buserror.net>
Cc: Mike Dunn <mikedunn@newsguy.com>
Cc: Simon Glass <sjg@chromium.org>
This commit is contained in:
parent
5d74e3a6f1
commit
ea7d1eec66
5 changed files with 0 additions and 1560 deletions
|
@ -13,7 +13,6 @@ endif
|
|||
|
||||
obj-$(CONFIG_SPL_NAND_AM33XX_BCH) += am335x_spl_bch.o
|
||||
obj-$(CONFIG_SPL_NAND_DENALI) += denali_spl.o
|
||||
obj-$(CONFIG_SPL_NAND_DOCG4) += docg4_spl.o
|
||||
obj-$(CONFIG_SPL_NAND_SIMPLE) += nand_spl_simple.o
|
||||
obj-$(CONFIG_SPL_NAND_LOAD) += nand_spl_load.o
|
||||
obj-$(CONFIG_SPL_NAND_ECC) += nand_ecc.o
|
||||
|
@ -67,7 +66,6 @@ obj-$(CONFIG_TEGRA_NAND) += tegra_nand.o
|
|||
obj-$(CONFIG_NAND_OMAP_GPMC) += omap_gpmc.o
|
||||
obj-$(CONFIG_NAND_OMAP_ELM) += omap_elm.o
|
||||
obj-$(CONFIG_NAND_PLAT) += nand_plat.o
|
||||
obj-$(CONFIG_NAND_DOCG4) += docg4.o
|
||||
|
||||
else # minimal SPL drivers
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,219 +0,0 @@
|
|||
/*
|
||||
* SPL driver for Diskonchip G4 nand flash
|
||||
*
|
||||
* Copyright (C) 2013 Mike Dunn <mikedunn@newsguy.com>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*
|
||||
* This driver basically mimics the load functionality of a typical IPL (initial
|
||||
* program loader) resident in the 2k NOR-like region of the docg4 that is
|
||||
* mapped to the reset vector. It allows the u-boot SPL to continue loading if
|
||||
* the IPL loads a fixed number of flash blocks that is insufficient to contain
|
||||
* the entire u-boot image. In this case, a concatenated spl + u-boot image is
|
||||
* written at the flash offset from which the IPL loads an image, and when the
|
||||
* IPL jumps to the SPL, the SPL resumes loading where the IPL left off. See
|
||||
* the palmtreo680 for an example.
|
||||
*
|
||||
* This driver assumes that the data was written to the flash using the device's
|
||||
* "reliable" mode, and also assumes that each 512 byte page is stored
|
||||
* redundantly in the subsequent page. This storage format is likely to be used
|
||||
* by all boards that boot from the docg4. The format compensates for the lack
|
||||
* of ecc in the IPL.
|
||||
*
|
||||
* Reliable mode reduces the capacity of a block by half, and the redundant
|
||||
* pages reduce it by half again. As a result, the normal 256k capacity of a
|
||||
* block is reduced to 64k for the purposes of the IPL/SPL.
|
||||
*/
|
||||
|
||||
#include <asm/io.h>
|
||||
#include <linux/mtd/docg4.h>
|
||||
|
||||
/* forward declarations */
|
||||
static inline void write_nop(void __iomem *docptr);
|
||||
static int poll_status(void __iomem *docptr);
|
||||
static void write_addr(void __iomem *docptr, uint32_t docg4_addr);
|
||||
static void address_sequence(unsigned int g4_page, unsigned int g4_index,
|
||||
void __iomem *docptr);
|
||||
static int docg4_load_block_reliable(uint32_t flash_offset, void *dest_addr);
|
||||
|
||||
int nand_spl_load_image(uint32_t offs, unsigned int size, void *dst)
|
||||
{
|
||||
void *load_addr = dst;
|
||||
uint32_t flash_offset = offs;
|
||||
const unsigned int block_count =
|
||||
(size + DOCG4_BLOCK_CAPACITY_SPL - 1)
|
||||
/ DOCG4_BLOCK_CAPACITY_SPL;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < block_count; i++) {
|
||||
int ret = docg4_load_block_reliable(flash_offset, load_addr);
|
||||
if (ret)
|
||||
return ret;
|
||||
load_addr += DOCG4_BLOCK_CAPACITY_SPL;
|
||||
flash_offset += DOCG4_BLOCK_SIZE;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void write_nop(void __iomem *docptr)
|
||||
{
|
||||
writew(0, docptr + DOC_NOP);
|
||||
}
|
||||
|
||||
static int poll_status(void __iomem *docptr)
|
||||
{
|
||||
/*
|
||||
* Busy-wait for the FLASHREADY bit to be set in the FLASHCONTROL
|
||||
* register. Operations known to take a long time (e.g., block erase)
|
||||
* should sleep for a while before calling this.
|
||||
*/
|
||||
|
||||
uint8_t flash_status;
|
||||
|
||||
/* hardware quirk requires reading twice initially */
|
||||
flash_status = readb(docptr + DOC_FLASHCONTROL);
|
||||
|
||||
do {
|
||||
flash_status = readb(docptr + DOC_FLASHCONTROL);
|
||||
} while (!(flash_status & DOC_CTRL_FLASHREADY));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void write_addr(void __iomem *docptr, uint32_t docg4_addr)
|
||||
{
|
||||
/* write the four address bytes packed in docg4_addr to the device */
|
||||
|
||||
writeb(docg4_addr & 0xff, docptr + DOC_FLASHADDRESS);
|
||||
docg4_addr >>= 8;
|
||||
writeb(docg4_addr & 0xff, docptr + DOC_FLASHADDRESS);
|
||||
docg4_addr >>= 8;
|
||||
writeb(docg4_addr & 0xff, docptr + DOC_FLASHADDRESS);
|
||||
docg4_addr >>= 8;
|
||||
writeb(docg4_addr & 0xff, docptr + DOC_FLASHADDRESS);
|
||||
}
|
||||
|
||||
static void address_sequence(unsigned int g4_page, unsigned int g4_index,
|
||||
void __iomem *docptr)
|
||||
{
|
||||
writew(DOCG4_SEQ_PAGE_READ, docptr + DOC_FLASHSEQUENCE);
|
||||
writew(DOCG4_CMD_PAGE_READ, docptr + DOC_FLASHCOMMAND);
|
||||
write_nop(docptr);
|
||||
write_addr(docptr, ((uint32_t)g4_page << 16) | g4_index);
|
||||
write_nop(docptr);
|
||||
}
|
||||
|
||||
static int docg4_load_block_reliable(uint32_t flash_offset, void *dest_addr)
|
||||
{
|
||||
void __iomem *docptr = (void *)CONFIG_SYS_NAND_BASE;
|
||||
unsigned int g4_page = flash_offset >> 11; /* 2k page */
|
||||
const unsigned int last_g4_page = g4_page + 0x80; /* last in block */
|
||||
int g4_index = 0;
|
||||
uint16_t flash_status;
|
||||
uint16_t *buf;
|
||||
|
||||
/* flash_offset must be aligned to the start of a block */
|
||||
if (flash_offset & 0x3ffff)
|
||||
return -1;
|
||||
|
||||
writew(DOC_SEQ_RESET, docptr + DOC_FLASHSEQUENCE);
|
||||
writew(DOC_CMD_RESET, docptr + DOC_FLASHCOMMAND);
|
||||
write_nop(docptr);
|
||||
write_nop(docptr);
|
||||
poll_status(docptr);
|
||||
write_nop(docptr);
|
||||
writew(0x45, docptr + DOC_FLASHSEQUENCE);
|
||||
writew(0xa3, docptr + DOC_FLASHCOMMAND);
|
||||
write_nop(docptr);
|
||||
writew(0x22, docptr + DOC_FLASHCOMMAND);
|
||||
write_nop(docptr);
|
||||
|
||||
/* read 1st 4 oob bytes of first subpage of block */
|
||||
address_sequence(g4_page, 0x0100, docptr); /* index at oob */
|
||||
write_nop(docptr);
|
||||
flash_status = readw(docptr + DOC_FLASHCONTROL);
|
||||
flash_status = readw(docptr + DOC_FLASHCONTROL);
|
||||
if (flash_status & 0x06) /* sequence or protection errors */
|
||||
return -1;
|
||||
writew(DOCG4_CMD_READ2, docptr + DOC_FLASHCOMMAND);
|
||||
write_nop(docptr);
|
||||
write_nop(docptr);
|
||||
poll_status(docptr);
|
||||
writew(DOC_ECCCONF0_READ_MODE | 4, docptr + DOC_ECCCONF0);
|
||||
write_nop(docptr);
|
||||
write_nop(docptr);
|
||||
write_nop(docptr);
|
||||
write_nop(docptr);
|
||||
write_nop(docptr);
|
||||
|
||||
/*
|
||||
* Here we read the first four oob bytes of the first page of the block.
|
||||
* The IPL on the palmtreo680 requires that this contain a 32 bit magic
|
||||
* number, or the load aborts. We'll ignore it.
|
||||
*/
|
||||
readw(docptr + 0x103c); /* hw quirk; 1st read discarded */
|
||||
readw(docptr + 0x103c); /* lower 16 bits of magic number */
|
||||
readw(docptr + DOCG4_MYSTERY_REG); /* upper 16 bits of magic number */
|
||||
writew(0, docptr + DOC_DATAEND);
|
||||
write_nop(docptr);
|
||||
write_nop(docptr);
|
||||
|
||||
/* load contents of block to memory */
|
||||
buf = (uint16_t *)dest_addr;
|
||||
do {
|
||||
int i;
|
||||
|
||||
address_sequence(g4_page, g4_index, docptr);
|
||||
writew(DOCG4_CMD_READ2,
|
||||
docptr + DOC_FLASHCOMMAND);
|
||||
write_nop(docptr);
|
||||
write_nop(docptr);
|
||||
poll_status(docptr);
|
||||
writew(DOC_ECCCONF0_READ_MODE |
|
||||
DOC_ECCCONF0_ECC_ENABLE |
|
||||
DOCG4_BCH_SIZE,
|
||||
docptr + DOC_ECCCONF0);
|
||||
write_nop(docptr);
|
||||
write_nop(docptr);
|
||||
write_nop(docptr);
|
||||
write_nop(docptr);
|
||||
write_nop(docptr);
|
||||
|
||||
/* read the 512 bytes of page data, 2 bytes at a time */
|
||||
readw(docptr + 0x103c); /* hw quirk */
|
||||
for (i = 0; i < 256; i++)
|
||||
*buf++ = readw(docptr + 0x103c);
|
||||
|
||||
/* read oob, but discard it */
|
||||
for (i = 0; i < 7; i++)
|
||||
readw(docptr + 0x103c);
|
||||
readw(docptr + DOCG4_OOB_6_7);
|
||||
readw(docptr + DOCG4_OOB_6_7);
|
||||
|
||||
writew(0, docptr + DOC_DATAEND);
|
||||
write_nop(docptr);
|
||||
write_nop(docptr);
|
||||
|
||||
if (!(g4_index & 0x100)) {
|
||||
/* not redundant subpage read; check for ecc error */
|
||||
write_nop(docptr);
|
||||
flash_status = readw(docptr + DOC_ECCCONF1);
|
||||
flash_status = readw(docptr + DOC_ECCCONF1);
|
||||
if (flash_status & 0x80) { /* ecc error */
|
||||
g4_index += 0x108; /* read redundant subpage */
|
||||
buf -= 256; /* back up ram ptr */
|
||||
continue;
|
||||
} else /* no ecc error */
|
||||
g4_index += 0x210; /* skip redundant subpage */
|
||||
} else /* redundant page was just read; skip ecc error check */
|
||||
g4_index += 0x108;
|
||||
|
||||
if (g4_index == 0x420) { /* finished with 2k page */
|
||||
g4_index = 0;
|
||||
g4_page += 2; /* odd-numbered 2k pages skipped */
|
||||
}
|
||||
|
||||
} while (g4_page != last_g4_page); /* while still on same block */
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -1,132 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2013 Mike Dunn <mikedunn@newsguy.com>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#ifndef __DOCG4_H__
|
||||
#define __DOCG4_H__
|
||||
|
||||
#include <common.h>
|
||||
#include <linux/mtd/nand.h>
|
||||
|
||||
extern int docg4_nand_init(struct mtd_info *mtd,
|
||||
struct nand_chip *nand, int devnum);
|
||||
|
||||
/* SPL-related definitions */
|
||||
#define DOCG4_IPL_LOAD_BLOCK_COUNT 2 /* number of blocks that IPL loads */
|
||||
#define DOCG4_BLOCK_CAPACITY_SPL 0x10000 /* reliable mode; redundant pages */
|
||||
|
||||
#define DOC_IOSPACE_DATA 0x0800
|
||||
|
||||
/* register offsets */
|
||||
#define DOC_CHIPID 0x1000
|
||||
#define DOC_DEVICESELECT 0x100a
|
||||
#define DOC_ASICMODE 0x100c
|
||||
#define DOC_DATAEND 0x101e
|
||||
#define DOC_NOP 0x103e
|
||||
|
||||
#define DOC_FLASHSEQUENCE 0x1032
|
||||
#define DOC_FLASHCOMMAND 0x1034
|
||||
#define DOC_FLASHADDRESS 0x1036
|
||||
#define DOC_FLASHCONTROL 0x1038
|
||||
#define DOC_ECCCONF0 0x1040
|
||||
#define DOC_ECCCONF1 0x1042
|
||||
#define DOC_HAMMINGPARITY 0x1046
|
||||
#define DOC_BCH_SYNDROM(idx) (0x1048 + idx)
|
||||
|
||||
#define DOC_ASICMODECONFIRM 0x1072
|
||||
#define DOC_CHIPID_INV 0x1074
|
||||
#define DOC_POWERMODE 0x107c
|
||||
|
||||
#define DOCG4_MYSTERY_REG 0x1050
|
||||
|
||||
/* apparently used only to write oob bytes 6 and 7 */
|
||||
#define DOCG4_OOB_6_7 0x1052
|
||||
|
||||
/* DOC_FLASHSEQUENCE register commands */
|
||||
#define DOC_SEQ_RESET 0x00
|
||||
#define DOCG4_SEQ_PAGE_READ 0x03
|
||||
#define DOCG4_SEQ_FLUSH 0x29
|
||||
#define DOCG4_SEQ_PAGEWRITE 0x16
|
||||
#define DOCG4_SEQ_PAGEPROG 0x1e
|
||||
#define DOCG4_SEQ_BLOCKERASE 0x24
|
||||
|
||||
/* DOC_FLASHCOMMAND register commands */
|
||||
#define DOCG4_CMD_PAGE_READ 0x00
|
||||
#define DOC_CMD_ERASECYCLE2 0xd0
|
||||
#define DOCG4_CMD_FLUSH 0x70
|
||||
#define DOCG4_CMD_READ2 0x30
|
||||
#define DOC_CMD_PROG_BLOCK_ADDR 0x60
|
||||
#define DOCG4_CMD_PAGEWRITE 0x80
|
||||
#define DOC_CMD_PROG_CYCLE2 0x10
|
||||
#define DOC_CMD_RESET 0xff
|
||||
|
||||
/* DOC_POWERMODE register bits */
|
||||
#define DOC_POWERDOWN_READY 0x80
|
||||
|
||||
/* DOC_FLASHCONTROL register bits */
|
||||
#define DOC_CTRL_CE 0x10
|
||||
#define DOC_CTRL_UNKNOWN 0x40
|
||||
#define DOC_CTRL_FLASHREADY 0x01
|
||||
|
||||
/* DOC_ECCCONF0 register bits */
|
||||
#define DOC_ECCCONF0_READ_MODE 0x8000
|
||||
#define DOC_ECCCONF0_UNKNOWN 0x2000
|
||||
#define DOC_ECCCONF0_ECC_ENABLE 0x1000
|
||||
#define DOC_ECCCONF0_DATA_BYTES_MASK 0x07ff
|
||||
|
||||
/* DOC_ECCCONF1 register bits */
|
||||
#define DOC_ECCCONF1_BCH_SYNDROM_ERR 0x80
|
||||
#define DOC_ECCCONF1_ECC_ENABLE 0x07
|
||||
#define DOC_ECCCONF1_PAGE_IS_WRITTEN 0x20
|
||||
|
||||
/* DOC_ASICMODE register bits */
|
||||
#define DOC_ASICMODE_RESET 0x00
|
||||
#define DOC_ASICMODE_NORMAL 0x01
|
||||
#define DOC_ASICMODE_POWERDOWN 0x02
|
||||
#define DOC_ASICMODE_MDWREN 0x04
|
||||
#define DOC_ASICMODE_BDETCT_RESET 0x08
|
||||
#define DOC_ASICMODE_RSTIN_RESET 0x10
|
||||
#define DOC_ASICMODE_RAM_WE 0x20
|
||||
|
||||
/* good status values read after read/write/erase operations */
|
||||
#define DOCG4_PROGSTATUS_GOOD 0x51
|
||||
#define DOCG4_PROGSTATUS_GOOD_2 0xe0
|
||||
|
||||
/*
|
||||
* On read operations (page and oob-only), the first byte read from I/O reg is a
|
||||
* status. On error, it reads 0x73; otherwise, it reads either 0x71 (first read
|
||||
* after reset only) or 0x51, so bit 1 is presumed to be an error indicator.
|
||||
*/
|
||||
#define DOCG4_READ_ERROR 0x02 /* bit 1 indicates read error */
|
||||
|
||||
/* anatomy of the device */
|
||||
#define DOCG4_CHIP_SIZE 0x8000000
|
||||
#define DOCG4_PAGE_SIZE 0x200
|
||||
#define DOCG4_PAGES_PER_BLOCK 0x200
|
||||
#define DOCG4_BLOCK_SIZE (DOCG4_PAGES_PER_BLOCK * DOCG4_PAGE_SIZE)
|
||||
#define DOCG4_NUMBLOCKS (DOCG4_CHIP_SIZE / DOCG4_BLOCK_SIZE)
|
||||
#define DOCG4_OOB_SIZE 0x10
|
||||
#define DOCG4_CHIP_SHIFT 27 /* log_2(DOCG4_CHIP_SIZE) */
|
||||
#define DOCG4_PAGE_SHIFT 9 /* log_2(DOCG4_PAGE_SIZE) */
|
||||
#define DOCG4_ERASE_SHIFT 18 /* log_2(DOCG4_BLOCK_SIZE) */
|
||||
|
||||
/* all but the last byte is included in ecc calculation */
|
||||
#define DOCG4_BCH_SIZE (DOCG4_PAGE_SIZE + DOCG4_OOB_SIZE - 1)
|
||||
|
||||
#define DOCG4_USERDATA_LEN 520 /* 512 byte page plus 8 oob avail to user */
|
||||
|
||||
/* expected values from the ID registers */
|
||||
#define DOCG4_IDREG1_VALUE 0x0400
|
||||
#define DOCG4_IDREG2_VALUE 0xfbff
|
||||
|
||||
/* primitive polynomial used to build the Galois field used by hw ecc gen */
|
||||
#define DOCG4_PRIMITIVE_POLY 0x4443
|
||||
|
||||
#define DOCG4_M 14 /* Galois field is of order 2^14 */
|
||||
#define DOCG4_T 4 /* BCH alg corrects up to 4 bit errors */
|
||||
|
||||
#define DOCG4_FACTORY_BBT_PAGE 16 /* page where read-only factory bbt lives */
|
||||
|
||||
#endif /* __DOCG4_H__ */
|
|
@ -1,177 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2013 Mike Dunn <mikedunn@newsguy.com>
|
||||
*
|
||||
* This file is released under the terms of GPL v2 and any later version.
|
||||
* See the file COPYING in the root directory of the source tree for details.
|
||||
*
|
||||
*
|
||||
* This is a userspace Linux utility that, when run on the Treo 680, will
|
||||
* program u-boot to flash. The docg4 driver *must* be loaded with the
|
||||
* reliable_mode and ignore_badblocks parameters enabled:
|
||||
*
|
||||
* modprobe docg4 ignore_badblocks=1 reliable_mode=1
|
||||
*
|
||||
* This utility writes the concatenated spl + u-boot image to the start of the
|
||||
* mtd device in the format expected by the IPL/SPL. The image file and mtd
|
||||
* device node are passed to the utility as arguments. The blocks must have
|
||||
* been erased beforehand.
|
||||
*
|
||||
* When you compile this, note that it links to libmtd from mtd-utils, so ensure
|
||||
* that your include and lib paths include this.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <mtd/mtd-user.h>
|
||||
#include "libmtd.h"
|
||||
|
||||
#define RELIABLE_BLOCKSIZE 0x10000 /* block capacity in reliable mode */
|
||||
#define STANDARD_BLOCKSIZE 0x40000 /* block capacity in normal mode */
|
||||
#define PAGESIZE 512
|
||||
#define PAGES_PER_BLOCK 512
|
||||
#define OOBSIZE 7 /* available to user (16 total) */
|
||||
|
||||
uint8_t ff_oob[OOBSIZE] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
|
||||
|
||||
/* this is the magic number the IPL looks for (ASCII "BIPO") */
|
||||
uint8_t page0_oob[OOBSIZE] = {'B', 'I', 'P', 'O', 0xff, 0xff, 0xff};
|
||||
|
||||
int main(int argc, char * const argv[])
|
||||
{
|
||||
int devfd, datafd, num_blocks, block;
|
||||
off_t file_size;
|
||||
libmtd_t mtd_desc;
|
||||
struct mtd_dev_info devinfo;
|
||||
uint8_t *blockbuf;
|
||||
char response[8];
|
||||
|
||||
if (argc != 3) {
|
||||
printf("usage: %s <image file> <mtd dev node>\n", argv[0]);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
mtd_desc = libmtd_open();
|
||||
if (mtd_desc == NULL) {
|
||||
int errsv = errno;
|
||||
fprintf(stderr, "can't initialize libmtd\n");
|
||||
return -errsv;
|
||||
}
|
||||
|
||||
/* open the spl image file and mtd device */
|
||||
datafd = open(argv[1], O_RDONLY);
|
||||
if (datafd == -1) {
|
||||
int errsv = errno;
|
||||
perror(argv[1]);
|
||||
return -errsv;
|
||||
}
|
||||
devfd = open(argv[2], O_WRONLY);
|
||||
if (devfd == -1) {
|
||||
int errsv = errno;
|
||||
perror(argv[2]);
|
||||
return -errsv;
|
||||
}
|
||||
if (mtd_get_dev_info(mtd_desc, argv[2], &devinfo) < 0) {
|
||||
int errsv = errno;
|
||||
perror(argv[2]);
|
||||
return -errsv;
|
||||
}
|
||||
|
||||
/* determine the number of blocks needed by the image */
|
||||
file_size = lseek(datafd, 0, SEEK_END);
|
||||
if (file_size == (off_t)-1) {
|
||||
int errsv = errno;
|
||||
perror("lseek");
|
||||
return -errsv;
|
||||
}
|
||||
num_blocks = (file_size + RELIABLE_BLOCKSIZE - 1) / RELIABLE_BLOCKSIZE;
|
||||
file_size = lseek(datafd, 0, SEEK_SET);
|
||||
if (file_size == (off_t)-1) {
|
||||
int errsv = errno;
|
||||
perror("lseek");
|
||||
return -errsv;
|
||||
}
|
||||
printf("The mtd partition contains %d blocks\n", devinfo.eb_cnt);
|
||||
printf("U-Boot will occupy %d blocks\n", num_blocks);
|
||||
if (num_blocks > devinfo.eb_cnt) {
|
||||
fprintf(stderr, "Insufficient blocks on partition\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
printf("IMPORTANT: These blocks must be in an erased state!\n");
|
||||
printf("Do you want to proceed?\n");
|
||||
scanf("%s", response);
|
||||
if ((response[0] != 'y') && (response[0] != 'Y')) {
|
||||
printf("Exiting\n");
|
||||
close(devfd);
|
||||
close(datafd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
blockbuf = calloc(RELIABLE_BLOCKSIZE, 1);
|
||||
if (blockbuf == NULL) {
|
||||
int errsv = errno;
|
||||
perror("calloc");
|
||||
return -errsv;
|
||||
}
|
||||
|
||||
for (block = 0; block < num_blocks; block++) {
|
||||
int ofs, page;
|
||||
uint8_t *pagebuf = blockbuf, *buf = blockbuf;
|
||||
uint8_t *oobbuf = page0_oob; /* magic num in oob of 1st page */
|
||||
size_t len = RELIABLE_BLOCKSIZE;
|
||||
int ret;
|
||||
|
||||
/* read data for one block from file */
|
||||
while (len) {
|
||||
ssize_t read_ret = read(datafd, buf, len);
|
||||
if (read_ret == -1) {
|
||||
int errsv = errno;
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
perror("read");
|
||||
return -errsv;
|
||||
} else if (read_ret == 0) {
|
||||
break; /* EOF */
|
||||
}
|
||||
len -= read_ret;
|
||||
buf += read_ret;
|
||||
}
|
||||
|
||||
printf("Block %d: writing\r", block + 1);
|
||||
fflush(stdout);
|
||||
|
||||
for (page = 0, ofs = 0;
|
||||
page < PAGES_PER_BLOCK;
|
||||
page++, ofs += PAGESIZE) {
|
||||
if (page & 0x04) /* Odd-numbered 2k page */
|
||||
continue; /* skipped in reliable mode */
|
||||
|
||||
ret = mtd_write(mtd_desc, &devinfo, devfd, block, ofs,
|
||||
pagebuf, PAGESIZE, oobbuf, OOBSIZE,
|
||||
MTD_OPS_PLACE_OOB);
|
||||
if (ret) {
|
||||
fprintf(stderr,
|
||||
"\nmtd_write returned %d on block %d, ofs %x\n",
|
||||
ret, block + 1, ofs);
|
||||
return -EIO;
|
||||
}
|
||||
oobbuf = ff_oob; /* oob for subsequent pages */
|
||||
|
||||
if (page & 0x01) /* odd-numbered subpage */
|
||||
pagebuf += PAGESIZE;
|
||||
}
|
||||
}
|
||||
|
||||
printf("\nDone\n");
|
||||
|
||||
close(devfd);
|
||||
close(datafd);
|
||||
free(blockbuf);
|
||||
return 0;
|
||||
}
|
Loading…
Reference in a new issue