MTD pull for 3.3
-----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.11 (GNU/Linux) iEYEABECAAYFAk8Mq/MACgkQdwG7hYl686PeFACfZCgbdDWD9A/JL+i1RMfExVu6 Pi0An3Hmc3PTCp0yQ21KtcKhpF9CAMEu =NfuL -----END PGP SIGNATURE----- Merge tag 'for-linus-3.3' of git://git.infradead.org/mtd-2.6 MTD pull for 3.3 * tag 'for-linus-3.3' of git://git.infradead.org/mtd-2.6: (113 commits) mtd: Fix dependency for MTD_DOC200x mtd: do not use mtd->block_markbad directly logfs: do not use 'mtd->block_isbad' directly mtd: introduce mtd_can_have_bb helper mtd: do not use mtd->suspend and mtd->resume directly mtd: do not use mtd->lock, unlock and is_locked directly mtd: do not use mtd->sync directly mtd: harmonize mtd_writev usage mtd: do not use mtd->lock_user_prot_reg directly mtd: mtd->write_user_prot_reg directly mtd: do not use mtd->read_*_prot_reg directly mtd: do not use mtd->get_*_prot_info directly mtd: do not use mtd->read_oob directly mtd: mtdoops: do not use mtd->panic_write directly romfs: do not use mtd->get_unmapped_area directly mtd: do not use mtd->get_unmapped_area directly mtd: do use mtd->point directly mtd: introduce mtd_has_oob helper mtd: mtdcore: export symbols cleanup mtd: clean-up the default_mtd_writev function ... Fix up trivial edit/remove conflict in drivers/staging/spectra/lld_mtd.c
This commit is contained in:
commit
7b3480f8b7
34
Documentation/ABI/testing/sysfs-devices-platform-docg3
Normal file
34
Documentation/ABI/testing/sysfs-devices-platform-docg3
Normal file
@ -0,0 +1,34 @@
|
||||
What: /sys/devices/platform/docg3/f[0-3]_dps[01]_is_keylocked
|
||||
Date: November 2011
|
||||
KernelVersion: 3.3
|
||||
Contact: Robert Jarzmik <robert.jarzmik@free.fr>
|
||||
Description:
|
||||
Show whether the floor (0 to 4), protection area (0 or 1) is
|
||||
keylocked. Each docg3 chip (or floor) has 2 protection areas,
|
||||
which can cover any part of it, block aligned, called DPS.
|
||||
The protection has information embedded whether it blocks reads,
|
||||
writes or both.
|
||||
The result is:
|
||||
0 -> the DPS is not keylocked
|
||||
1 -> the DPS is keylocked
|
||||
Users: None identified so far.
|
||||
|
||||
What: /sys/devices/platform/docg3/f[0-3]_dps[01]_protection_key
|
||||
Date: November 2011
|
||||
KernelVersion: 3.3
|
||||
Contact: Robert Jarzmik <robert.jarzmik@free.fr>
|
||||
Description:
|
||||
Enter the protection key for the floor (0 to 4), protection area
|
||||
(0 or 1). Each docg3 chip (or floor) has 2 protection areas,
|
||||
which can cover any part of it, block aligned, called DPS.
|
||||
The protection has information embedded whether it blocks reads,
|
||||
writes or both.
|
||||
The protection key is a string of 8 bytes (value 0-255).
|
||||
Entering the correct value toggle the lock, and can be observed
|
||||
through f[0-3]_dps[01]_is_keylocked.
|
||||
Possible values are:
|
||||
- 8 bytes
|
||||
Typical values are:
|
||||
- "00000000"
|
||||
- "12345678"
|
||||
Users: None identified so far.
|
44
Documentation/devicetree/bindings/mtd/gpio-control-nand.txt
Normal file
44
Documentation/devicetree/bindings/mtd/gpio-control-nand.txt
Normal file
@ -0,0 +1,44 @@
|
||||
GPIO assisted NAND flash
|
||||
|
||||
The GPIO assisted NAND flash uses a memory mapped interface to
|
||||
read/write the NAND commands and data and GPIO pins for the control
|
||||
signals.
|
||||
|
||||
Required properties:
|
||||
- compatible : "gpio-control-nand"
|
||||
- reg : should specify localbus chip select and size used for the chip. The
|
||||
resource describes the data bus connected to the NAND flash and all accesses
|
||||
are made in native endianness.
|
||||
- #address-cells, #size-cells : Must be present if the device has sub-nodes
|
||||
representing partitions.
|
||||
- gpios : specifies the gpio pins to control the NAND device. nwp is an
|
||||
optional gpio and may be set to 0 if not present.
|
||||
|
||||
Optional properties:
|
||||
- bank-width : Width (in bytes) of the device. If not present, the width
|
||||
defaults to 1 byte.
|
||||
- chip-delay : chip dependent delay for transferring data from array to
|
||||
read registers (tR). If not present then a default of 20us is used.
|
||||
- gpio-control-nand,io-sync-reg : A 64-bit physical address for a read
|
||||
location used to guard against bus reordering with regards to accesses to
|
||||
the GPIO's and the NAND flash data bus. If present, then after changing
|
||||
GPIO state and before and after command byte writes, this register will be
|
||||
read to ensure that the GPIO accesses have completed.
|
||||
|
||||
Examples:
|
||||
|
||||
gpio-nand@1,0 {
|
||||
compatible = "gpio-control-nand";
|
||||
reg = <1 0x0000 0x2>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
gpios = <&banka 1 0 /* rdy */
|
||||
&banka 2 0 /* nce */
|
||||
&banka 3 0 /* ale */
|
||||
&banka 4 0 /* cle */
|
||||
0 /* nwp */>;
|
||||
|
||||
partition@0 {
|
||||
...
|
||||
};
|
||||
};
|
@ -127,7 +127,7 @@ static void da850_evm_m25p80_notify_add(struct mtd_info *mtd)
|
||||
size_t retlen;
|
||||
|
||||
if (!strcmp(mtd->name, "MAC-Address")) {
|
||||
mtd->read(mtd, 0, ETH_ALEN, &retlen, mac_addr);
|
||||
mtd_read(mtd, 0, ETH_ALEN, &retlen, mac_addr);
|
||||
if (retlen == ETH_ALEN)
|
||||
pr_info("Read MAC addr from SPI Flash: %pM\n",
|
||||
mac_addr);
|
||||
|
@ -404,8 +404,7 @@ static int __init init_axis_flash(void)
|
||||
*/
|
||||
int blockstat;
|
||||
do {
|
||||
blockstat = main_mtd->block_isbad(main_mtd,
|
||||
ptable_sector);
|
||||
blockstat = mtd_block_isbad(main_mtd, ptable_sector);
|
||||
if (blockstat < 0)
|
||||
ptable_sector = 0; /* read error */
|
||||
else if (blockstat)
|
||||
@ -413,8 +412,8 @@ static int __init init_axis_flash(void)
|
||||
} while (blockstat && ptable_sector);
|
||||
#endif
|
||||
if (ptable_sector) {
|
||||
main_mtd->read(main_mtd, ptable_sector, PAGESIZE,
|
||||
&len, page);
|
||||
mtd_read(main_mtd, ptable_sector, PAGESIZE, &len,
|
||||
page);
|
||||
ptable_head = &((struct partitiontable *) page)->head;
|
||||
}
|
||||
|
||||
|
@ -834,10 +834,13 @@ static struct mtd_partition mtd_partitions[] = {
|
||||
}
|
||||
};
|
||||
|
||||
static const char *bcm63xx_part_types[] = { "bcm63xxpart", NULL };
|
||||
|
||||
static struct physmap_flash_data flash_data = {
|
||||
.width = 2,
|
||||
.nr_parts = ARRAY_SIZE(mtd_partitions),
|
||||
.parts = mtd_partitions,
|
||||
.part_probe_types = bcm63xx_part_types,
|
||||
};
|
||||
|
||||
static struct resource mtd_resources[] = {
|
||||
|
@ -16,7 +16,6 @@
|
||||
#define TAGINFO1_LEN 30 /* Length of vendor information field1 in tag */
|
||||
#define FLASHLAYOUTVER_LEN 4 /* Length of Flash Layout Version String tag */
|
||||
#define TAGINFO2_LEN 16 /* Length of vendor information field2 in tag */
|
||||
#define CRC_LEN 4 /* Length of CRC in bytes */
|
||||
#define ALTTAGINFO_LEN 54 /* Alternate length for vendor information; Pirelli */
|
||||
|
||||
#define NUM_PIRELLI 2
|
||||
@ -77,19 +76,19 @@ struct bcm_tag {
|
||||
/* 192-195: Version flash layout */
|
||||
char flash_layout_ver[FLASHLAYOUTVER_LEN];
|
||||
/* 196-199: kernel+rootfs CRC32 */
|
||||
char fskernel_crc[CRC_LEN];
|
||||
__u32 fskernel_crc;
|
||||
/* 200-215: Unused except on Alice Gate where is is information */
|
||||
char information2[TAGINFO2_LEN];
|
||||
/* 216-219: CRC32 of image less imagetag (kernel for Alice Gate) */
|
||||
char image_crc[CRC_LEN];
|
||||
__u32 image_crc;
|
||||
/* 220-223: CRC32 of rootfs partition */
|
||||
char rootfs_crc[CRC_LEN];
|
||||
__u32 rootfs_crc;
|
||||
/* 224-227: CRC32 of kernel partition */
|
||||
char kernel_crc[CRC_LEN];
|
||||
__u32 kernel_crc;
|
||||
/* 228-235: Unused at present */
|
||||
char reserved1[8];
|
||||
/* 236-239: CRC32 of header excluding last 20 bytes */
|
||||
char header_crc[CRC_LEN];
|
||||
__u32 header_crc;
|
||||
/* 240-255: Unused at present */
|
||||
char reserved2[16];
|
||||
};
|
||||
|
@ -140,6 +140,14 @@ config MTD_AR7_PARTS
|
||||
---help---
|
||||
TI AR7 partitioning support
|
||||
|
||||
config MTD_BCM63XX_PARTS
|
||||
tristate "BCM63XX CFE partitioning support"
|
||||
depends on BCM63XX
|
||||
select CRC32
|
||||
help
|
||||
This provides partions parsing for BCM63xx devices with CFE
|
||||
bootloaders.
|
||||
|
||||
comment "User Modules And Translation Layers"
|
||||
|
||||
config MTD_CHAR
|
||||
|
@ -11,6 +11,7 @@ obj-$(CONFIG_MTD_REDBOOT_PARTS) += redboot.o
|
||||
obj-$(CONFIG_MTD_CMDLINE_PARTS) += cmdlinepart.o
|
||||
obj-$(CONFIG_MTD_AFS_PARTS) += afs.o
|
||||
obj-$(CONFIG_MTD_AR7_PARTS) += ar7part.o
|
||||
obj-$(CONFIG_MTD_BCM63XX_PARTS) += bcm63xxpart.o
|
||||
|
||||
# 'Users' - code which presents functionality to userspace.
|
||||
obj-$(CONFIG_MTD_CHAR) += mtdchar.o
|
||||
|
@ -75,7 +75,7 @@ afs_read_footer(struct mtd_info *mtd, u_int *img_start, u_int *iis_start,
|
||||
size_t sz;
|
||||
int ret;
|
||||
|
||||
ret = mtd->read(mtd, ptr, sizeof(fs), &sz, (u_char *) &fs);
|
||||
ret = mtd_read(mtd, ptr, sizeof(fs), &sz, (u_char *)&fs);
|
||||
if (ret >= 0 && sz != sizeof(fs))
|
||||
ret = -EINVAL;
|
||||
|
||||
@ -132,7 +132,7 @@ afs_read_iis(struct mtd_info *mtd, struct image_info_struct *iis, u_int ptr)
|
||||
int ret, i;
|
||||
|
||||
memset(iis, 0, sizeof(*iis));
|
||||
ret = mtd->read(mtd, ptr, sizeof(*iis), &sz, (u_char *) iis);
|
||||
ret = mtd_read(mtd, ptr, sizeof(*iis), &sz, (u_char *)iis);
|
||||
if (ret < 0)
|
||||
goto failed;
|
||||
|
||||
|
@ -73,8 +73,8 @@ static int create_mtd_partitions(struct mtd_info *master,
|
||||
|
||||
do { /* Try 10 blocks starting from master->erasesize */
|
||||
offset = pre_size;
|
||||
master->read(master, offset,
|
||||
sizeof(header), &len, (uint8_t *)&header);
|
||||
mtd_read(master, offset, sizeof(header), &len,
|
||||
(uint8_t *)&header);
|
||||
if (!strncmp((char *)&header, "TIENV0.8", 8))
|
||||
ar7_parts[1].offset = pre_size;
|
||||
if (header.checksum == LOADER_MAGIC1)
|
||||
@ -95,16 +95,16 @@ static int create_mtd_partitions(struct mtd_info *master,
|
||||
case LOADER_MAGIC1:
|
||||
while (header.length) {
|
||||
offset += sizeof(header) + header.length;
|
||||
master->read(master, offset, sizeof(header),
|
||||
&len, (uint8_t *)&header);
|
||||
mtd_read(master, offset, sizeof(header), &len,
|
||||
(uint8_t *)&header);
|
||||
}
|
||||
root_offset = offset + sizeof(header) + 4;
|
||||
break;
|
||||
case LOADER_MAGIC2:
|
||||
while (header.length) {
|
||||
offset += sizeof(header) + header.length;
|
||||
master->read(master, offset, sizeof(header),
|
||||
&len, (uint8_t *)&header);
|
||||
mtd_read(master, offset, sizeof(header), &len,
|
||||
(uint8_t *)&header);
|
||||
}
|
||||
root_offset = offset + sizeof(header) + 4 + 0xff;
|
||||
root_offset &= ~(uint32_t)0xff;
|
||||
@ -114,8 +114,7 @@ static int create_mtd_partitions(struct mtd_info *master,
|
||||
break;
|
||||
}
|
||||
|
||||
master->read(master, root_offset,
|
||||
sizeof(header), &len, (u8 *)&header);
|
||||
mtd_read(master, root_offset, sizeof(header), &len, (u8 *)&header);
|
||||
if (header.checksum != SQUASHFS_MAGIC) {
|
||||
root_offset += master->erasesize - 1;
|
||||
root_offset &= ~(master->erasesize - 1);
|
||||
|
222
drivers/mtd/bcm63xxpart.c
Normal file
222
drivers/mtd/bcm63xxpart.c
Normal file
@ -0,0 +1,222 @@
|
||||
/*
|
||||
* BCM63XX CFE image tag parser
|
||||
*
|
||||
* Copyright © 2006-2008 Florian Fainelli <florian@openwrt.org>
|
||||
* Mike Albon <malbon@openwrt.org>
|
||||
* Copyright © 2009-2010 Daniel Dickinson <openwrt@cshore.neomailbox.net>
|
||||
* Copyright © 2011 Jonas Gorski <jonas.gorski@gmail.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
||||
|
||||
#include <linux/crc32.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/vmalloc.h>
|
||||
#include <linux/mtd/mtd.h>
|
||||
#include <linux/mtd/partitions.h>
|
||||
|
||||
#include <asm/mach-bcm63xx/bcm963xx_tag.h>
|
||||
#include <asm/mach-bcm63xx/board_bcm963xx.h>
|
||||
|
||||
#define BCM63XX_EXTENDED_SIZE 0xBFC00000 /* Extended flash address */
|
||||
|
||||
#define BCM63XX_MIN_CFE_SIZE 0x10000 /* always at least 64KiB */
|
||||
#define BCM63XX_MIN_NVRAM_SIZE 0x10000 /* always at least 64KiB */
|
||||
|
||||
#define BCM63XX_CFE_MAGIC_OFFSET 0x4e0
|
||||
|
||||
static int bcm63xx_detect_cfe(struct mtd_info *master)
|
||||
{
|
||||
char buf[9];
|
||||
int ret;
|
||||
size_t retlen;
|
||||
|
||||
ret = mtd_read(master, BCM963XX_CFE_VERSION_OFFSET, 5, &retlen,
|
||||
(void *)buf);
|
||||
buf[retlen] = 0;
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (strncmp("cfe-v", buf, 5) == 0)
|
||||
return 0;
|
||||
|
||||
/* very old CFE's do not have the cfe-v string, so check for magic */
|
||||
ret = mtd_read(master, BCM63XX_CFE_MAGIC_OFFSET, 8, &retlen,
|
||||
(void *)buf);
|
||||
buf[retlen] = 0;
|
||||
|
||||
return strncmp("CFE1CFE1", buf, 8);
|
||||
}
|
||||
|
||||
static int bcm63xx_parse_cfe_partitions(struct mtd_info *master,
|
||||
struct mtd_partition **pparts,
|
||||
struct mtd_part_parser_data *data)
|
||||
{
|
||||
/* CFE, NVRAM and global Linux are always present */
|
||||
int nrparts = 3, curpart = 0;
|
||||
struct bcm_tag *buf;
|
||||
struct mtd_partition *parts;
|
||||
int ret;
|
||||
size_t retlen;
|
||||
unsigned int rootfsaddr, kerneladdr, spareaddr;
|
||||
unsigned int rootfslen, kernellen, sparelen, totallen;
|
||||
unsigned int cfelen, nvramlen;
|
||||
int namelen = 0;
|
||||
int i;
|
||||
u32 computed_crc;
|
||||
|
||||
if (bcm63xx_detect_cfe(master))
|
||||
return -EINVAL;
|
||||
|
||||
cfelen = max_t(uint32_t, master->erasesize, BCM63XX_MIN_CFE_SIZE);
|
||||
nvramlen = max_t(uint32_t, master->erasesize, BCM63XX_MIN_NVRAM_SIZE);
|
||||
|
||||
/* Allocate memory for buffer */
|
||||
buf = vmalloc(sizeof(struct bcm_tag));
|
||||
if (!buf)
|
||||
return -ENOMEM;
|
||||
|
||||
/* Get the tag */
|
||||
ret = mtd_read(master, cfelen, sizeof(struct bcm_tag), &retlen,
|
||||
(void *)buf);
|
||||
|
||||
if (retlen != sizeof(struct bcm_tag)) {
|
||||
vfree(buf);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
computed_crc = crc32_le(IMAGETAG_CRC_START, (u8 *)buf,
|
||||
offsetof(struct bcm_tag, header_crc));
|
||||
if (computed_crc == buf->header_crc) {
|
||||
char *boardid = &(buf->board_id[0]);
|
||||
char *tagversion = &(buf->tag_version[0]);
|
||||
|
||||
sscanf(buf->kernel_address, "%u", &kerneladdr);
|
||||
sscanf(buf->kernel_length, "%u", &kernellen);
|
||||
sscanf(buf->total_length, "%u", &totallen);
|
||||
|
||||
pr_info("CFE boot tag found with version %s and board type %s\n",
|
||||
tagversion, boardid);
|
||||
|
||||
kerneladdr = kerneladdr - BCM63XX_EXTENDED_SIZE;
|
||||
rootfsaddr = kerneladdr + kernellen;
|
||||
spareaddr = roundup(totallen, master->erasesize) + cfelen;
|
||||
sparelen = master->size - spareaddr - nvramlen;
|
||||
rootfslen = spareaddr - rootfsaddr;
|
||||
} else {
|
||||
pr_warn("CFE boot tag CRC invalid (expected %08x, actual %08x)\n",
|
||||
buf->header_crc, computed_crc);
|
||||
kernellen = 0;
|
||||
rootfslen = 0;
|
||||
rootfsaddr = 0;
|
||||
spareaddr = cfelen;
|
||||
sparelen = master->size - cfelen - nvramlen;
|
||||
}
|
||||
|
||||
/* Determine number of partitions */
|
||||
namelen = 8;
|
||||
if (rootfslen > 0) {
|
||||
nrparts++;
|
||||
namelen += 6;
|
||||
}
|
||||
if (kernellen > 0) {
|
||||
nrparts++;
|
||||
namelen += 6;
|
||||
}
|
||||
|
||||
/* Ask kernel for more memory */
|
||||
parts = kzalloc(sizeof(*parts) * nrparts + 10 * nrparts, GFP_KERNEL);
|
||||
if (!parts) {
|
||||
vfree(buf);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* Start building partition list */
|
||||
parts[curpart].name = "CFE";
|
||||
parts[curpart].offset = 0;
|
||||
parts[curpart].size = cfelen;
|
||||
curpart++;
|
||||
|
||||
if (kernellen > 0) {
|
||||
parts[curpart].name = "kernel";
|
||||
parts[curpart].offset = kerneladdr;
|
||||
parts[curpart].size = kernellen;
|
||||
curpart++;
|
||||
}
|
||||
|
||||
if (rootfslen > 0) {
|
||||
parts[curpart].name = "rootfs";
|
||||
parts[curpart].offset = rootfsaddr;
|
||||
parts[curpart].size = rootfslen;
|
||||
if (sparelen > 0)
|
||||
parts[curpart].size += sparelen;
|
||||
curpart++;
|
||||
}
|
||||
|
||||
parts[curpart].name = "nvram";
|
||||
parts[curpart].offset = master->size - nvramlen;
|
||||
parts[curpart].size = nvramlen;
|
||||
|
||||
/* Global partition "linux" to make easy firmware upgrade */
|
||||
curpart++;
|
||||
parts[curpart].name = "linux";
|
||||
parts[curpart].offset = cfelen;
|
||||
parts[curpart].size = master->size - cfelen - nvramlen;
|
||||
|
||||
for (i = 0; i < nrparts; i++)
|
||||
pr_info("Partition %d is %s offset %lx and length %lx\n", i,
|
||||
parts[i].name, (long unsigned int)(parts[i].offset),
|
||||
(long unsigned int)(parts[i].size));
|
||||
|
||||
pr_info("Spare partition is offset %x and length %x\n", spareaddr,
|
||||
sparelen);
|
||||
|
||||
*pparts = parts;
|
||||
vfree(buf);
|
||||
|
||||
return nrparts;
|
||||
};
|
||||
|
||||
static struct mtd_part_parser bcm63xx_cfe_parser = {
|
||||
.owner = THIS_MODULE,
|
||||
.parse_fn = bcm63xx_parse_cfe_partitions,
|
||||
.name = "bcm63xxpart",
|
||||
};
|
||||
|
||||
static int __init bcm63xx_cfe_parser_init(void)
|
||||
{
|
||||
return register_mtd_parser(&bcm63xx_cfe_parser);
|
||||
}
|
||||
|
||||
static void __exit bcm63xx_cfe_parser_exit(void)
|
||||
{
|
||||
deregister_mtd_parser(&bcm63xx_cfe_parser);
|
||||
}
|
||||
|
||||
module_init(bcm63xx_cfe_parser_init);
|
||||
module_exit(bcm63xx_cfe_parser_exit);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Daniel Dickinson <openwrt@cshore.neomailbox.net>");
|
||||
MODULE_AUTHOR("Florian Fainelli <florian@openwrt.org>");
|
||||
MODULE_AUTHOR("Mike Albon <malbon@openwrt.org>");
|
||||
MODULE_AUTHOR("Jonas Gorski <jonas.gorski@gmail.com");
|
||||
MODULE_DESCRIPTION("MTD partitioning for BCM63XX CFE bootloaders");
|
@ -139,8 +139,9 @@ struct mtd_info *cfi_cmdset_0020(struct map_info *map, int primary)
|
||||
}
|
||||
|
||||
/* Do some byteswapping if necessary */
|
||||
extp->FeatureSupport = cfi32_to_cpu(extp->FeatureSupport);
|
||||
extp->BlkStatusRegMask = cfi32_to_cpu(extp->BlkStatusRegMask);
|
||||
extp->FeatureSupport = cfi32_to_cpu(map, extp->FeatureSupport);
|
||||
extp->BlkStatusRegMask = cfi32_to_cpu(map,
|
||||
extp->BlkStatusRegMask);
|
||||
|
||||
#ifdef DEBUG_CFI_FEATURES
|
||||
/* Tell the user about it in lots of lovely detail */
|
||||
@ -698,7 +699,8 @@ cfi_staa_writev(struct mtd_info *mtd, const struct kvec *vecs,
|
||||
continue;
|
||||
}
|
||||
memcpy(buffer+buflen, elem_base, ECCBUF_SIZE-buflen);
|
||||
ret = mtd->write(mtd, to, ECCBUF_SIZE, &thislen, buffer);
|
||||
ret = mtd_write(mtd, to, ECCBUF_SIZE, &thislen,
|
||||
buffer);
|
||||
totlen += thislen;
|
||||
if (ret || thislen != ECCBUF_SIZE)
|
||||
goto write_error;
|
||||
@ -707,7 +709,8 @@ cfi_staa_writev(struct mtd_info *mtd, const struct kvec *vecs,
|
||||
to += ECCBUF_SIZE;
|
||||
}
|
||||
if (ECCBUF_DIV(elem_len)) { /* write clean aligned data */
|
||||
ret = mtd->write(mtd, to, ECCBUF_DIV(elem_len), &thislen, elem_base);
|
||||
ret = mtd_write(mtd, to, ECCBUF_DIV(elem_len),
|
||||
&thislen, elem_base);
|
||||
totlen += thislen;
|
||||
if (ret || thislen != ECCBUF_DIV(elem_len))
|
||||
goto write_error;
|
||||
@ -721,7 +724,7 @@ cfi_staa_writev(struct mtd_info *mtd, const struct kvec *vecs,
|
||||
}
|
||||
if (buflen) { /* flush last page, even if not full */
|
||||
/* This is sometimes intended behaviour, really */
|
||||
ret = mtd->write(mtd, to, buflen, &thislen, buffer);
|
||||
ret = mtd_write(mtd, to, buflen, &thislen, buffer);
|
||||
totlen += thislen;
|
||||
if (ret || thislen != ECCBUF_SIZE)
|
||||
goto write_error;
|
||||
|
@ -191,6 +191,7 @@ comment "Disk-On-Chip Device Drivers"
|
||||
|
||||
config MTD_DOC2000
|
||||
tristate "M-Systems Disk-On-Chip 2000 and Millennium (DEPRECATED)"
|
||||
depends on MTD_NAND
|
||||
select MTD_DOCPROBE
|
||||
select MTD_NAND_IDS
|
||||
---help---
|
||||
@ -213,6 +214,7 @@ config MTD_DOC2000
|
||||
|
||||
config MTD_DOC2001
|
||||
tristate "M-Systems Disk-On-Chip Millennium-only alternative driver (DEPRECATED)"
|
||||
depends on MTD_NAND
|
||||
select MTD_DOCPROBE
|
||||
select MTD_NAND_IDS
|
||||
---help---
|
||||
@ -234,6 +236,7 @@ config MTD_DOC2001
|
||||
|
||||
config MTD_DOC2001PLUS
|
||||
tristate "M-Systems Disk-On-Chip Millennium Plus"
|
||||
depends on MTD_NAND
|
||||
select MTD_DOCPROBE
|
||||
select MTD_NAND_IDS
|
||||
---help---
|
||||
@ -251,6 +254,8 @@ config MTD_DOC2001PLUS
|
||||
|
||||
config MTD_DOCG3
|
||||
tristate "M-Systems Disk-On-Chip G3"
|
||||
select BCH
|
||||
select BCH_CONST_PARAMS
|
||||
---help---
|
||||
This provides an MTD device driver for the M-Systems DiskOnChip
|
||||
G3 devices.
|
||||
@ -259,6 +264,13 @@ config MTD_DOCG3
|
||||
M-Systems and now Sandisk. The support is very experimental,
|
||||
and doesn't give access to any write operations.
|
||||
|
||||
if MTD_DOCG3
|
||||
config BCH_CONST_M
|
||||
default 14
|
||||
config BCH_CONST_T
|
||||
default 4
|
||||
endif
|
||||
|
||||
config MTD_DOCPROBE
|
||||
tristate
|
||||
select MTD_DOCECC
|
||||
|
@ -287,7 +287,7 @@ static struct block2mtd_dev *add_device(char *devname, int erase_size)
|
||||
dev->mtd.flags = MTD_CAP_RAM;
|
||||
dev->mtd.erase = block2mtd_erase;
|
||||
dev->mtd.write = block2mtd_write;
|
||||
dev->mtd.writev = default_mtd_writev;
|
||||
dev->mtd.writev = mtd_writev;
|
||||
dev->mtd.sync = block2mtd_sync;
|
||||
dev->mtd.read = block2mtd_read;
|
||||
dev->mtd.priv = dev;
|
||||
|
@ -562,23 +562,14 @@ void DoC2k_init(struct mtd_info *mtd)
|
||||
|
||||
mtd->type = MTD_NANDFLASH;
|
||||
mtd->flags = MTD_CAP_NANDFLASH;
|
||||
mtd->size = 0;
|
||||
mtd->erasesize = 0;
|
||||
mtd->writesize = 512;
|
||||
mtd->oobsize = 16;
|
||||
mtd->owner = THIS_MODULE;
|
||||
mtd->erase = doc_erase;
|
||||
mtd->point = NULL;
|
||||
mtd->unpoint = NULL;
|
||||
mtd->read = doc_read;
|
||||
mtd->write = doc_write;
|
||||
mtd->read_oob = doc_read_oob;
|
||||
mtd->write_oob = doc_write_oob;
|
||||
mtd->sync = NULL;
|
||||
|
||||
this->totlen = 0;
|
||||
this->numchips = 0;
|
||||
|
||||
this->curfloor = -1;
|
||||
this->curchip = -1;
|
||||
mutex_init(&this->lock);
|
||||
|
@ -343,25 +343,17 @@ void DoCMil_init(struct mtd_info *mtd)
|
||||
|
||||
mtd->type = MTD_NANDFLASH;
|
||||
mtd->flags = MTD_CAP_NANDFLASH;
|
||||
mtd->size = 0;
|
||||
|
||||
/* FIXME: erase size is not always 8KiB */
|
||||
mtd->erasesize = 0x2000;
|
||||
|
||||
mtd->writesize = 512;
|
||||
mtd->oobsize = 16;
|
||||
mtd->owner = THIS_MODULE;
|
||||
mtd->erase = doc_erase;
|
||||
mtd->point = NULL;
|
||||
mtd->unpoint = NULL;
|
||||
mtd->read = doc_read;
|
||||
mtd->write = doc_write;
|
||||
mtd->read_oob = doc_read_oob;
|
||||
mtd->write_oob = doc_write_oob;
|
||||
mtd->sync = NULL;
|
||||
|
||||
this->totlen = 0;
|
||||
this->numchips = 0;
|
||||
this->curfloor = -1;
|
||||
this->curchip = -1;
|
||||
|
||||
|
@ -467,23 +467,14 @@ void DoCMilPlus_init(struct mtd_info *mtd)
|
||||
|
||||
mtd->type = MTD_NANDFLASH;
|
||||
mtd->flags = MTD_CAP_NANDFLASH;
|
||||
mtd->size = 0;
|
||||
|
||||
mtd->erasesize = 0;
|
||||
mtd->writesize = 512;
|
||||
mtd->oobsize = 16;
|
||||
mtd->owner = THIS_MODULE;
|
||||
mtd->erase = doc_erase;
|
||||
mtd->point = NULL;
|
||||
mtd->unpoint = NULL;
|
||||
mtd->read = doc_read;
|
||||
mtd->write = doc_write;
|
||||
mtd->read_oob = doc_read_oob;
|
||||
mtd->write_oob = doc_write_oob;
|
||||
mtd->sync = NULL;
|
||||
|
||||
this->totlen = 0;
|
||||
this->numchips = 0;
|
||||
this->curfloor = -1;
|
||||
this->curchip = -1;
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -51,10 +51,19 @@
|
||||
#define DOC_LAYOUT_WEAR_OFFSET (DOC_LAYOUT_PAGE_OOB_SIZE * 2)
|
||||
#define DOC_LAYOUT_BLOCK_SIZE \
|
||||
(DOC_LAYOUT_PAGES_PER_BLOCK * DOC_LAYOUT_PAGE_SIZE)
|
||||
|
||||
/*
|
||||
* ECC related constants
|
||||
*/
|
||||
#define DOC_ECC_BCH_M 14
|
||||
#define DOC_ECC_BCH_T 4
|
||||
#define DOC_ECC_BCH_PRIMPOLY 0x4443
|
||||
#define DOC_ECC_BCH_SIZE 7
|
||||
#define DOC_ECC_BCH_COVERED_BYTES \
|
||||
(DOC_LAYOUT_PAGE_SIZE + DOC_LAYOUT_OOB_PAGEINFO_SZ + \
|
||||
DOC_LAYOUT_OOB_HAMMING_SZ + DOC_LAYOUT_OOB_BCH_SZ)
|
||||
DOC_LAYOUT_OOB_HAMMING_SZ)
|
||||
#define DOC_ECC_BCH_TOTAL_BYTES \
|
||||
(DOC_ECC_BCH_COVERED_BYTES + DOC_LAYOUT_OOB_BCH_SZ)
|
||||
|
||||
/*
|
||||
* Blocks distribution
|
||||
@ -80,6 +89,7 @@
|
||||
|
||||
#define DOC_CHIPID_G3 0x200
|
||||
#define DOC_ERASE_MARK 0xaa
|
||||
#define DOC_MAX_NBFLOORS 4
|
||||
/*
|
||||
* Flash registers
|
||||
*/
|
||||
@ -105,9 +115,11 @@
|
||||
#define DOC_ECCCONF1 0x1042
|
||||
#define DOC_ECCPRESET 0x1044
|
||||
#define DOC_HAMMINGPARITY 0x1046
|
||||
#define DOC_BCH_SYNDROM(idx) (0x1048 + (idx << 1))
|
||||
#define DOC_BCH_HW_ECC(idx) (0x1048 + idx)
|
||||
|
||||
#define DOC_PROTECTION 0x1056
|
||||
#define DOC_DPS0_KEY 0x105c
|
||||
#define DOC_DPS1_KEY 0x105e
|
||||
#define DOC_DPS0_ADDRLOW 0x1060
|
||||
#define DOC_DPS0_ADDRHIGH 0x1062
|
||||
#define DOC_DPS1_ADDRLOW 0x1064
|
||||
@ -117,6 +129,7 @@
|
||||
|
||||
#define DOC_ASICMODECONFIRM 0x1072
|
||||
#define DOC_CHIPID_INV 0x1074
|
||||
#define DOC_POWERMODE 0x107c
|
||||
|
||||
/*
|
||||
* Flash sequences
|
||||
@ -124,11 +137,14 @@
|
||||
*/
|
||||
#define DOC_SEQ_RESET 0x00
|
||||
#define DOC_SEQ_PAGE_SIZE_532 0x03
|
||||
#define DOC_SEQ_SET_MODE 0x09
|
||||
#define DOC_SEQ_SET_FASTMODE 0x05
|
||||
#define DOC_SEQ_SET_RELIABLEMODE 0x09
|
||||
#define DOC_SEQ_READ 0x12
|
||||
#define DOC_SEQ_SET_PLANE1 0x0e
|
||||
#define DOC_SEQ_SET_PLANE2 0x10
|
||||
#define DOC_SEQ_PAGE_SETUP 0x1d
|
||||
#define DOC_SEQ_ERASE 0x27
|
||||
#define DOC_SEQ_PLANES_STATUS 0x31
|
||||
|
||||
/*
|
||||
* Flash commands
|
||||
@ -143,7 +159,10 @@
|
||||
#define DOC_CMD_PROG_BLOCK_ADDR 0x60
|
||||
#define DOC_CMD_PROG_CYCLE1 0x80
|
||||
#define DOC_CMD_PROG_CYCLE2 0x10
|
||||
#define DOC_CMD_PROG_CYCLE3 0x11
|
||||
#define DOC_CMD_ERASECYCLE2 0xd0
|
||||
#define DOC_CMD_READ_STATUS 0x70
|
||||
#define DOC_CMD_PLANES_STATUS 0x71
|
||||
|
||||
#define DOC_CMD_RELIABLE_MODE 0x22
|
||||
#define DOC_CMD_FAST_MODE 0xa2
|
||||
@ -174,6 +193,7 @@
|
||||
/*
|
||||
* Flash register : DOC_ECCCONF0
|
||||
*/
|
||||
#define DOC_ECCCONF0_WRITE_MODE 0x0000
|
||||
#define DOC_ECCCONF0_READ_MODE 0x8000
|
||||
#define DOC_ECCCONF0_AUTO_ECC_ENABLE 0x4000
|
||||
#define DOC_ECCCONF0_HAMMING_ENABLE 0x1000
|
||||
@ -185,7 +205,7 @@
|
||||
*/
|
||||
#define DOC_ECCCONF1_BCH_SYNDROM_ERR 0x80
|
||||
#define DOC_ECCCONF1_UNKOWN1 0x40
|
||||
#define DOC_ECCCONF1_UNKOWN2 0x20
|
||||
#define DOC_ECCCONF1_PAGE_IS_WRITTEN 0x20
|
||||
#define DOC_ECCCONF1_UNKOWN3 0x10
|
||||
#define DOC_ECCCONF1_HAMMING_BITS_MASK 0x0f
|
||||
|
||||
@ -223,13 +243,46 @@
|
||||
#define DOC_READADDR_ONE_BYTE 0x4000
|
||||
#define DOC_READADDR_ADDR_MASK 0x1fff
|
||||
|
||||
/*
|
||||
* Flash register : DOC_POWERMODE
|
||||
*/
|
||||
#define DOC_POWERDOWN_READY 0x80
|
||||
|
||||
/*
|
||||
* Status of erase and write operation
|
||||
*/
|
||||
#define DOC_PLANES_STATUS_FAIL 0x01
|
||||
#define DOC_PLANES_STATUS_PLANE0_KO 0x02
|
||||
#define DOC_PLANES_STATUS_PLANE1_KO 0x04
|
||||
|
||||
/*
|
||||
* DPS key management
|
||||
*
|
||||
* Each floor of docg3 has 2 protection areas: DPS0 and DPS1. These areas span
|
||||
* across block boundaries, and define whether these blocks can be read or
|
||||
* written.
|
||||
* The definition is dynamically stored in page 0 of blocks (2,3) for DPS0, and
|
||||
* page 0 of blocks (4,5) for DPS1.
|
||||
*/
|
||||
#define DOC_LAYOUT_DPS_KEY_LENGTH 8
|
||||
|
||||
/**
|
||||
* struct docg3 - DiskOnChip driver private data
|
||||
* @dev: the device currently under control
|
||||
* @base: mapped IO space
|
||||
* @device_id: number of the cascaded DoCG3 device (0, 1, 2 or 3)
|
||||
* @if_cfg: if true, reads are on 16bits, else reads are on 8bits
|
||||
|
||||
* @reliable: if 0, docg3 in normal mode, if 1 docg3 in fast mode, if 2 in
|
||||
* reliable mode
|
||||
* Fast mode implies more errors than normal mode.
|
||||
* Reliable mode implies that page 2*n and 2*n+1 are clones.
|
||||
* @bbt: bad block table cache
|
||||
* @oob_write_ofs: offset of the MTD where this OOB should belong (ie. in next
|
||||
* page_write)
|
||||
* @oob_autoecc: if 1, use only bytes 0-7, 15, and fill the others with HW ECC
|
||||
* if 0, use all the 16 bytes.
|
||||
* @oob_write_buf: prepared OOB for next page_write
|
||||
* @debugfs_root: debugfs root node
|
||||
*/
|
||||
struct docg3 {
|
||||
@ -237,8 +290,12 @@ struct docg3 {
|
||||
void __iomem *base;
|
||||
unsigned int device_id:4;
|
||||
unsigned int if_cfg:1;
|
||||
unsigned int reliable:2;
|
||||
int max_block;
|
||||
u8 *bbt;
|
||||
loff_t oob_write_ofs;
|
||||
int oob_autoecc;
|
||||
u8 oob_write_buf[DOC_LAYOUT_OOB_SIZE];
|
||||
struct dentry *debugfs_root;
|
||||
};
|
||||
|
||||
|
@ -241,8 +241,7 @@ static void __init DoC_Probe(unsigned long physadr)
|
||||
return;
|
||||
}
|
||||
docfound = 1;
|
||||
mtd = kmalloc(sizeof(struct DiskOnChip) + sizeof(struct mtd_info), GFP_KERNEL);
|
||||
|
||||
mtd = kzalloc(sizeof(struct DiskOnChip) + sizeof(struct mtd_info), GFP_KERNEL);
|
||||
if (!mtd) {
|
||||
printk(KERN_WARNING "Cannot allocate memory for data structures. Dropping.\n");
|
||||
iounmap(docptr);
|
||||
@ -250,10 +249,6 @@ static void __init DoC_Probe(unsigned long physadr)
|
||||
}
|
||||
|
||||
this = (struct DiskOnChip *)(&mtd[1]);
|
||||
|
||||
memset((char *)mtd,0, sizeof(struct mtd_info));
|
||||
memset((char *)this, 0, sizeof(struct DiskOnChip));
|
||||
|
||||
mtd->priv = this;
|
||||
this->virtadr = docptr;
|
||||
this->physadr = physadr;
|
||||
|
@ -992,7 +992,6 @@ static int __devexit m25p_remove(struct spi_device *spi)
|
||||
static struct spi_driver m25p80_driver = {
|
||||
.driver = {
|
||||
.name = "m25p80",
|
||||
.bus = &spi_bus_type,
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
.id_table = m25p_ids,
|
||||
|
@ -936,7 +936,6 @@ static int __devexit dataflash_remove(struct spi_device *spi)
|
||||
static struct spi_driver dataflash_driver = {
|
||||
.driver = {
|
||||
.name = "mtd_dataflash",
|
||||
.bus = &spi_bus_type,
|
||||
.owner = THIS_MODULE,
|
||||
.of_match_table = dataflash_dt_ids,
|
||||
},
|
||||
|
@ -378,7 +378,7 @@ static int __devinit sst25l_probe(struct spi_device *spi)
|
||||
struct flash_info *flash_info;
|
||||
struct sst25l_flash *flash;
|
||||
struct flash_platform_data *data;
|
||||
int ret, i;
|
||||
int ret;
|
||||
|
||||
flash_info = sst25l_match_device(spi);
|
||||
if (!flash_info)
|
||||
@ -444,7 +444,6 @@ static int __devexit sst25l_remove(struct spi_device *spi)
|
||||
static struct spi_driver sst25l_driver = {
|
||||
.driver = {
|
||||
.name = "sst25l",
|
||||
.bus = &spi_bus_type,
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
.probe = sst25l_probe,
|
||||
|
@ -168,8 +168,8 @@ static int scan_header(partition_t *part)
|
||||
(offset + sizeof(header)) < max_offset;
|
||||
offset += part->mbd.mtd->erasesize ? : 0x2000) {
|
||||
|
||||
err = part->mbd.mtd->read(part->mbd.mtd, offset, sizeof(header), &ret,
|
||||
(unsigned char *)&header);
|
||||
err = mtd_read(part->mbd.mtd, offset, sizeof(header), &ret,
|
||||
(unsigned char *)&header);
|
||||
|
||||
if (err)
|
||||
return err;
|
||||
@ -224,8 +224,8 @@ static int build_maps(partition_t *part)
|
||||
for (i = 0; i < le16_to_cpu(part->header.NumEraseUnits); i++) {
|
||||
offset = ((i + le16_to_cpu(part->header.FirstPhysicalEUN))
|
||||
<< part->header.EraseUnitSize);
|
||||
ret = part->mbd.mtd->read(part->mbd.mtd, offset, sizeof(header), &retval,
|
||||
(unsigned char *)&header);
|
||||
ret = mtd_read(part->mbd.mtd, offset, sizeof(header), &retval,
|
||||
(unsigned char *)&header);
|
||||
|
||||
if (ret)
|
||||
goto out_XferInfo;
|
||||
@ -289,9 +289,9 @@ static int build_maps(partition_t *part)
|
||||
part->EUNInfo[i].Deleted = 0;
|
||||
offset = part->EUNInfo[i].Offset + le32_to_cpu(header.BAMOffset);
|
||||
|
||||
ret = part->mbd.mtd->read(part->mbd.mtd, offset,
|
||||
part->BlocksPerUnit * sizeof(uint32_t), &retval,
|
||||
(unsigned char *)part->bam_cache);
|
||||
ret = mtd_read(part->mbd.mtd, offset,
|
||||
part->BlocksPerUnit * sizeof(uint32_t), &retval,
|
||||
(unsigned char *)part->bam_cache);
|
||||
|
||||
if (ret)
|
||||
goto out_bam_cache;
|
||||
@ -355,7 +355,7 @@ static int erase_xfer(partition_t *part,
|
||||
erase->len = 1 << part->header.EraseUnitSize;
|
||||
erase->priv = (u_long)part;
|
||||
|
||||
ret = part->mbd.mtd->erase(part->mbd.mtd, erase);
|
||||
ret = mtd_erase(part->mbd.mtd, erase);
|
||||
|
||||
if (!ret)
|
||||
xfer->EraseCount++;
|
||||
@ -422,8 +422,8 @@ static int prepare_xfer(partition_t *part, int i)
|
||||
header.LogicalEUN = cpu_to_le16(0xffff);
|
||||
header.EraseCount = cpu_to_le32(xfer->EraseCount);
|
||||
|
||||
ret = part->mbd.mtd->write(part->mbd.mtd, xfer->Offset, sizeof(header),
|
||||
&retlen, (u_char *)&header);
|
||||
ret = mtd_write(part->mbd.mtd, xfer->Offset, sizeof(header), &retlen,
|
||||
(u_char *)&header);
|
||||
|
||||
if (ret) {
|
||||
return ret;
|
||||
@ -438,8 +438,8 @@ static int prepare_xfer(partition_t *part, int i)
|
||||
|
||||
for (i = 0; i < nbam; i++, offset += sizeof(uint32_t)) {
|
||||
|
||||
ret = part->mbd.mtd->write(part->mbd.mtd, offset, sizeof(uint32_t),
|
||||
&retlen, (u_char *)&ctl);
|
||||
ret = mtd_write(part->mbd.mtd, offset, sizeof(uint32_t), &retlen,
|
||||
(u_char *)&ctl);
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
@ -485,9 +485,9 @@ static int copy_erase_unit(partition_t *part, uint16_t srcunit,
|
||||
|
||||
offset = eun->Offset + le32_to_cpu(part->header.BAMOffset);
|
||||
|
||||
ret = part->mbd.mtd->read(part->mbd.mtd, offset,
|
||||
part->BlocksPerUnit * sizeof(uint32_t),
|
||||
&retlen, (u_char *) (part->bam_cache));
|
||||
ret = mtd_read(part->mbd.mtd, offset,
|
||||
part->BlocksPerUnit * sizeof(uint32_t), &retlen,
|
||||
(u_char *)(part->bam_cache));
|
||||
|
||||
/* mark the cache bad, in case we get an error later */
|
||||
part->bam_index = 0xffff;
|
||||
@ -503,8 +503,8 @@ static int copy_erase_unit(partition_t *part, uint16_t srcunit,
|
||||
offset = xfer->Offset + 20; /* Bad! */
|
||||
unit = cpu_to_le16(0x7fff);
|
||||
|
||||
ret = part->mbd.mtd->write(part->mbd.mtd, offset, sizeof(uint16_t),
|
||||
&retlen, (u_char *) &unit);
|
||||
ret = mtd_write(part->mbd.mtd, offset, sizeof(uint16_t), &retlen,
|
||||
(u_char *)&unit);
|
||||
|
||||
if (ret) {
|
||||
printk( KERN_WARNING "ftl: Failed to write back to BAM cache in copy_erase_unit()!\n");
|
||||
@ -523,16 +523,16 @@ static int copy_erase_unit(partition_t *part, uint16_t srcunit,
|
||||
break;
|
||||
case BLOCK_DATA:
|
||||
case BLOCK_REPLACEMENT:
|
||||
ret = part->mbd.mtd->read(part->mbd.mtd, src, SECTOR_SIZE,
|
||||
&retlen, (u_char *) buf);
|
||||
ret = mtd_read(part->mbd.mtd, src, SECTOR_SIZE, &retlen,
|
||||
(u_char *)buf);
|
||||
if (ret) {
|
||||
printk(KERN_WARNING "ftl: Error reading old xfer unit in copy_erase_unit\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
ret = part->mbd.mtd->write(part->mbd.mtd, dest, SECTOR_SIZE,
|
||||
&retlen, (u_char *) buf);
|
||||
ret = mtd_write(part->mbd.mtd, dest, SECTOR_SIZE, &retlen,
|
||||
(u_char *)buf);
|
||||
if (ret) {
|
||||
printk(KERN_WARNING "ftl: Error writing new xfer unit in copy_erase_unit\n");
|
||||
return ret;
|
||||
@ -550,9 +550,11 @@ static int copy_erase_unit(partition_t *part, uint16_t srcunit,
|
||||
}
|
||||
|
||||
/* Write the BAM to the transfer unit */
|
||||
ret = part->mbd.mtd->write(part->mbd.mtd, xfer->Offset + le32_to_cpu(part->header.BAMOffset),
|
||||
part->BlocksPerUnit * sizeof(int32_t), &retlen,
|
||||
(u_char *)part->bam_cache);
|
||||
ret = mtd_write(part->mbd.mtd,
|
||||
xfer->Offset + le32_to_cpu(part->header.BAMOffset),
|
||||
part->BlocksPerUnit * sizeof(int32_t),
|
||||
&retlen,
|
||||
(u_char *)part->bam_cache);
|
||||
if (ret) {
|
||||
printk( KERN_WARNING "ftl: Error writing BAM in copy_erase_unit\n");
|
||||
return ret;
|
||||
@ -560,8 +562,8 @@ static int copy_erase_unit(partition_t *part, uint16_t srcunit,
|
||||
|
||||
|
||||
/* All clear? Then update the LogicalEUN again */
|
||||
ret = part->mbd.mtd->write(part->mbd.mtd, xfer->Offset + 20, sizeof(uint16_t),
|
||||
&retlen, (u_char *)&srcunitswap);
|
||||
ret = mtd_write(part->mbd.mtd, xfer->Offset + 20, sizeof(uint16_t),
|
||||
&retlen, (u_char *)&srcunitswap);
|
||||
|
||||
if (ret) {
|
||||
printk(KERN_WARNING "ftl: Error writing new LogicalEUN in copy_erase_unit\n");
|
||||
@ -648,8 +650,7 @@ static int reclaim_block(partition_t *part)
|
||||
if (queued) {
|
||||
pr_debug("ftl_cs: waiting for transfer "
|
||||
"unit to be prepared...\n");
|
||||
if (part->mbd.mtd->sync)
|
||||
part->mbd.mtd->sync(part->mbd.mtd);
|
||||
mtd_sync(part->mbd.mtd);
|
||||
} else {
|
||||
static int ne = 0;
|
||||
if (++ne < 5)
|
||||
@ -747,10 +748,11 @@ static uint32_t find_free(partition_t *part)
|
||||
/* Invalidate cache */
|
||||
part->bam_index = 0xffff;
|
||||
|
||||
ret = part->mbd.mtd->read(part->mbd.mtd,
|
||||
part->EUNInfo[eun].Offset + le32_to_cpu(part->header.BAMOffset),
|
||||
part->BlocksPerUnit * sizeof(uint32_t),
|
||||
&retlen, (u_char *) (part->bam_cache));
|
||||
ret = mtd_read(part->mbd.mtd,
|
||||
part->EUNInfo[eun].Offset + le32_to_cpu(part->header.BAMOffset),
|
||||
part->BlocksPerUnit * sizeof(uint32_t),
|
||||
&retlen,
|
||||
(u_char *)(part->bam_cache));
|
||||
|
||||
if (ret) {
|
||||
printk(KERN_WARNING"ftl: Error reading BAM in find_free\n");
|
||||
@ -810,8 +812,8 @@ static int ftl_read(partition_t *part, caddr_t buffer,
|
||||
else {
|
||||
offset = (part->EUNInfo[log_addr / bsize].Offset
|
||||
+ (log_addr % bsize));
|
||||
ret = part->mbd.mtd->read(part->mbd.mtd, offset, SECTOR_SIZE,
|
||||
&retlen, (u_char *) buffer);
|
||||
ret = mtd_read(part->mbd.mtd, offset, SECTOR_SIZE, &retlen,
|
||||
(u_char *)buffer);
|
||||
|
||||
if (ret) {
|
||||
printk(KERN_WARNING "Error reading MTD device in ftl_read()\n");
|
||||
@ -849,8 +851,8 @@ static int set_bam_entry(partition_t *part, uint32_t log_addr,
|
||||
le32_to_cpu(part->header.BAMOffset));
|
||||
|
||||
#ifdef PSYCHO_DEBUG
|
||||
ret = part->mbd.mtd->read(part->mbd.mtd, offset, sizeof(uint32_t),
|
||||
&retlen, (u_char *)&old_addr);
|
||||
ret = mtd_read(part->mbd.mtd, offset, sizeof(uint32_t), &retlen,
|
||||
(u_char *)&old_addr);
|
||||
if (ret) {
|
||||
printk(KERN_WARNING"ftl: Error reading old_addr in set_bam_entry: %d\n",ret);
|
||||
return ret;
|
||||
@ -886,8 +888,8 @@ static int set_bam_entry(partition_t *part, uint32_t log_addr,
|
||||
#endif
|
||||
part->bam_cache[blk] = le_virt_addr;
|
||||
}
|
||||
ret = part->mbd.mtd->write(part->mbd.mtd, offset, sizeof(uint32_t),
|
||||
&retlen, (u_char *)&le_virt_addr);
|
||||
ret = mtd_write(part->mbd.mtd, offset, sizeof(uint32_t), &retlen,
|
||||
(u_char *)&le_virt_addr);
|
||||
|
||||
if (ret) {
|
||||
printk(KERN_NOTICE "ftl_cs: set_bam_entry() failed!\n");
|
||||
@ -946,8 +948,7 @@ static int ftl_write(partition_t *part, caddr_t buffer,
|
||||
part->EUNInfo[part->bam_index].Deleted++;
|
||||
offset = (part->EUNInfo[part->bam_index].Offset +
|
||||
blk * SECTOR_SIZE);
|
||||
ret = part->mbd.mtd->write(part->mbd.mtd, offset, SECTOR_SIZE, &retlen,
|
||||
buffer);
|
||||
ret = mtd_write(part->mbd.mtd, offset, SECTOR_SIZE, &retlen, buffer);
|
||||
|
||||
if (ret) {
|
||||
printk(KERN_NOTICE "ftl_cs: block write failed!\n");
|
||||
|
@ -158,7 +158,7 @@ int inftl_read_oob(struct mtd_info *mtd, loff_t offs, size_t len,
|
||||
ops.oobbuf = buf;
|
||||
ops.datbuf = NULL;
|
||||
|
||||
res = mtd->read_oob(mtd, offs & ~(mtd->writesize - 1), &ops);
|
||||
res = mtd_read_oob(mtd, offs & ~(mtd->writesize - 1), &ops);
|
||||
*retlen = ops.oobretlen;
|
||||
return res;
|
||||
}
|
||||
@ -178,7 +178,7 @@ int inftl_write_oob(struct mtd_info *mtd, loff_t offs, size_t len,
|
||||
ops.oobbuf = buf;
|
||||
ops.datbuf = NULL;
|
||||
|
||||
res = mtd->write_oob(mtd, offs & ~(mtd->writesize - 1), &ops);
|
||||
res = mtd_write_oob(mtd, offs & ~(mtd->writesize - 1), &ops);
|
||||
*retlen = ops.oobretlen;
|
||||
return res;
|
||||
}
|
||||
@ -199,7 +199,7 @@ static int inftl_write(struct mtd_info *mtd, loff_t offs, size_t len,
|
||||
ops.datbuf = buf;
|
||||
ops.len = len;
|
||||
|
||||
res = mtd->write_oob(mtd, offs & ~(mtd->writesize - 1), &ops);
|
||||
res = mtd_write_oob(mtd, offs & ~(mtd->writesize - 1), &ops);
|
||||
*retlen = ops.retlen;
|
||||
return res;
|
||||
}
|
||||
@ -343,14 +343,17 @@ static u16 INFTL_foldchain(struct INFTLrecord *inftl, unsigned thisVUC, unsigned
|
||||
if (BlockMap[block] == BLOCK_NIL)
|
||||
continue;
|
||||
|
||||
ret = mtd->read(mtd, (inftl->EraseSize * BlockMap[block]) +
|
||||
(block * SECTORSIZE), SECTORSIZE, &retlen,
|
||||
movebuf);
|
||||
ret = mtd_read(mtd,
|
||||
(inftl->EraseSize * BlockMap[block]) + (block * SECTORSIZE),
|
||||
SECTORSIZE,
|
||||
&retlen,
|
||||
movebuf);
|
||||
if (ret < 0 && !mtd_is_bitflip(ret)) {
|
||||
ret = mtd->read(mtd,
|
||||
(inftl->EraseSize * BlockMap[block]) +
|
||||
(block * SECTORSIZE), SECTORSIZE,
|
||||
&retlen, movebuf);
|
||||
ret = mtd_read(mtd,
|
||||
(inftl->EraseSize * BlockMap[block]) + (block * SECTORSIZE),
|
||||
SECTORSIZE,
|
||||
&retlen,
|
||||
movebuf);
|
||||
if (ret != -EIO)
|
||||
pr_debug("INFTL: error went away on retry?\n");
|
||||
}
|
||||
@ -914,7 +917,7 @@ foundit:
|
||||
} else {
|
||||
size_t retlen;
|
||||
loff_t ptr = (thisEUN * inftl->EraseSize) + blockofs;
|
||||
int ret = mtd->read(mtd, ptr, SECTORSIZE, &retlen, buffer);
|
||||
int ret = mtd_read(mtd, ptr, SECTORSIZE, &retlen, buffer);
|
||||
|
||||
/* Handle corrected bit flips gracefully */
|
||||
if (ret < 0 && !mtd_is_bitflip(ret))
|
||||
|
@ -73,8 +73,8 @@ static int find_boot_record(struct INFTLrecord *inftl)
|
||||
* Check for BNAND header first. Then whinge if it's found
|
||||
* but later checks fail.
|
||||
*/
|
||||
ret = mtd->read(mtd, block * inftl->EraseSize,
|
||||
SECTORSIZE, &retlen, buf);
|
||||
ret = mtd_read(mtd, block * inftl->EraseSize, SECTORSIZE,
|
||||
&retlen, buf);
|
||||
/* We ignore ret in case the ECC of the MediaHeader is invalid
|
||||
(which is apparently acceptable) */
|
||||
if (retlen != SECTORSIZE) {
|
||||
@ -118,8 +118,8 @@ static int find_boot_record(struct INFTLrecord *inftl)
|
||||
memcpy(mh, buf, sizeof(struct INFTLMediaHeader));
|
||||
|
||||
/* Read the spare media header at offset 4096 */
|
||||
mtd->read(mtd, block * inftl->EraseSize + 4096,
|
||||
SECTORSIZE, &retlen, buf);
|
||||
mtd_read(mtd, block * inftl->EraseSize + 4096, SECTORSIZE,
|
||||
&retlen, buf);
|
||||
if (retlen != SECTORSIZE) {
|
||||
printk(KERN_WARNING "INFTL: Unable to read spare "
|
||||
"Media Header\n");
|
||||
@ -220,7 +220,7 @@ static int find_boot_record(struct INFTLrecord *inftl)
|
||||
*/
|
||||
instr->addr = ip->Reserved0 * inftl->EraseSize;
|
||||
instr->len = inftl->EraseSize;
|
||||
mtd->erase(mtd, instr);
|
||||
mtd_erase(mtd, instr);
|
||||
}
|
||||
if ((ip->lastUnit - ip->firstUnit + 1) < ip->virtualUnits) {
|
||||
printk(KERN_WARNING "INFTL: Media Header "
|
||||
@ -306,7 +306,8 @@ static int find_boot_record(struct INFTLrecord *inftl)
|
||||
/* If any of the physical eraseblocks are bad, don't
|
||||
use the unit. */
|
||||
for (physblock = 0; physblock < inftl->EraseSize; physblock += inftl->mbd.mtd->erasesize) {
|
||||
if (inftl->mbd.mtd->block_isbad(inftl->mbd.mtd, i * inftl->EraseSize + physblock))
|
||||
if (mtd_block_isbad(inftl->mbd.mtd,
|
||||
i * inftl->EraseSize + physblock))
|
||||
inftl->PUtable[i] = BLOCK_RESERVED;
|
||||
}
|
||||
}
|
||||
@ -342,7 +343,7 @@ static int check_free_sectors(struct INFTLrecord *inftl, unsigned int address,
|
||||
int i;
|
||||
|
||||
for (i = 0; i < len; i += SECTORSIZE) {
|
||||
if (mtd->read(mtd, address, SECTORSIZE, &retlen, buf))
|
||||
if (mtd_read(mtd, address, SECTORSIZE, &retlen, buf))
|
||||
return -1;
|
||||
if (memcmpb(buf, 0xff, SECTORSIZE) != 0)
|
||||
return -1;
|
||||
@ -393,7 +394,7 @@ int INFTL_formatblock(struct INFTLrecord *inftl, int block)
|
||||
mark only the failed block in the bbt. */
|
||||
for (physblock = 0; physblock < inftl->EraseSize;
|
||||
physblock += instr->len, instr->addr += instr->len) {
|
||||
mtd->erase(inftl->mbd.mtd, instr);
|
||||
mtd_erase(inftl->mbd.mtd, instr);
|
||||
|
||||
if (instr->state == MTD_ERASE_FAILED) {
|
||||
printk(KERN_WARNING "INFTL: error while formatting block %d\n",
|
||||
@ -423,7 +424,7 @@ int INFTL_formatblock(struct INFTLrecord *inftl, int block)
|
||||
fail:
|
||||
/* could not format, update the bad block table (caller is responsible
|
||||
for setting the PUtable to BLOCK_RESERVED on failure) */
|
||||
inftl->mbd.mtd->block_markbad(inftl->mbd.mtd, instr->addr);
|
||||
mtd_block_markbad(inftl->mbd.mtd, instr->addr);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -70,19 +70,12 @@ struct mtd_info *lpddr_cmdset(struct map_info *map)
|
||||
mtd->erase = lpddr_erase;
|
||||
mtd->write = lpddr_write_buffers;
|
||||
mtd->writev = lpddr_writev;
|
||||
mtd->read_oob = NULL;
|
||||
mtd->write_oob = NULL;
|
||||
mtd->sync = NULL;
|
||||
mtd->lock = lpddr_lock;
|
||||
mtd->unlock = lpddr_unlock;
|
||||
mtd->suspend = NULL;
|
||||
mtd->resume = NULL;
|
||||
if (map_is_linear(map)) {
|
||||
mtd->point = lpddr_point;
|
||||
mtd->unpoint = lpddr_unpoint;
|
||||
}
|
||||
mtd->block_isbad = NULL;
|
||||
mtd->block_markbad = NULL;
|
||||
mtd->size = 1 << lpddr->qinfo->DevSizeShift;
|
||||
mtd->erasesize = 1 << lpddr->qinfo->UniformBlockSizeShift;
|
||||
mtd->writesize = 1 << lpddr->qinfo->BufSizeShift;
|
||||
|
@ -242,15 +242,6 @@ config MTD_NETtel
|
||||
help
|
||||
Support for flash chips on NETtel/SecureEdge/SnapGear boards.
|
||||
|
||||
config MTD_BCM963XX
|
||||
tristate "Map driver for Broadcom BCM963xx boards"
|
||||
depends on BCM63XX
|
||||
select MTD_MAP_BANK_WIDTH_2
|
||||
select MTD_CFI_I1
|
||||
help
|
||||
Support for parsing CFE image tag and creating MTD partitions on
|
||||
Broadcom BCM63xx boards.
|
||||
|
||||
config MTD_LANTIQ
|
||||
tristate "Lantiq SoC NOR support"
|
||||
depends on LANTIQ
|
||||
|
@ -55,6 +55,5 @@ obj-$(CONFIG_MTD_BFIN_ASYNC) += bfin-async-flash.o
|
||||
obj-$(CONFIG_MTD_RBTX4939) += rbtx4939-flash.o
|
||||
obj-$(CONFIG_MTD_VMU) += vmu-flash.o
|
||||
obj-$(CONFIG_MTD_GPIO_ADDR) += gpio-addr-flash.o
|
||||
obj-$(CONFIG_MTD_BCM963XX) += bcm963xx-flash.o
|
||||
obj-$(CONFIG_MTD_LATCH_ADDR) += latch-addr-flash.o
|
||||
obj-$(CONFIG_MTD_LANTIQ) += lantiq-flash.o
|
||||
|
@ -1,277 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2006-2008 Florian Fainelli <florian@openwrt.org>
|
||||
* Mike Albon <malbon@openwrt.org>
|
||||
* Copyright © 2009-2010 Daniel Dickinson <openwrt@cshore.neomailbox.net>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/mtd/map.h>
|
||||
#include <linux/mtd/mtd.h>
|
||||
#include <linux/mtd/partitions.h>
|
||||
#include <linux/vmalloc.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/io.h>
|
||||
|
||||
#include <asm/mach-bcm63xx/bcm963xx_tag.h>
|
||||
|
||||
#define BCM63XX_BUSWIDTH 2 /* Buswidth */
|
||||
#define BCM63XX_EXTENDED_SIZE 0xBFC00000 /* Extended flash address */
|
||||
|
||||
#define PFX KBUILD_MODNAME ": "
|
||||
|
||||
static struct mtd_partition *parsed_parts;
|
||||
|
||||
static struct mtd_info *bcm963xx_mtd_info;
|
||||
|
||||
static struct map_info bcm963xx_map = {
|
||||
.name = "bcm963xx",
|
||||
.bankwidth = BCM63XX_BUSWIDTH,
|
||||
};
|
||||
|
||||
static int parse_cfe_partitions(struct mtd_info *master,
|
||||
struct mtd_partition **pparts)
|
||||
{
|
||||
/* CFE, NVRAM and global Linux are always present */
|
||||
int nrparts = 3, curpart = 0;
|
||||
struct bcm_tag *buf;
|
||||
struct mtd_partition *parts;
|
||||
int ret;
|
||||
size_t retlen;
|
||||
unsigned int rootfsaddr, kerneladdr, spareaddr;
|
||||
unsigned int rootfslen, kernellen, sparelen, totallen;
|
||||
int namelen = 0;
|
||||
int i;
|
||||
char *boardid;
|
||||
char *tagversion;
|
||||
|
||||
/* Allocate memory for buffer */
|
||||
buf = vmalloc(sizeof(struct bcm_tag));
|
||||
if (!buf)
|
||||
return -ENOMEM;
|
||||
|
||||
/* Get the tag */
|
||||
ret = master->read(master, master->erasesize, sizeof(struct bcm_tag),
|
||||
&retlen, (void *)buf);
|
||||
if (retlen != sizeof(struct bcm_tag)) {
|
||||
vfree(buf);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
sscanf(buf->kernel_address, "%u", &kerneladdr);
|
||||
sscanf(buf->kernel_length, "%u", &kernellen);
|
||||
sscanf(buf->total_length, "%u", &totallen);
|
||||
tagversion = &(buf->tag_version[0]);
|
||||
boardid = &(buf->board_id[0]);
|
||||
|
||||
printk(KERN_INFO PFX "CFE boot tag found with version %s "
|
||||
"and board type %s\n", tagversion, boardid);
|
||||
|
||||
kerneladdr = kerneladdr - BCM63XX_EXTENDED_SIZE;
|
||||
rootfsaddr = kerneladdr + kernellen;
|
||||
spareaddr = roundup(totallen, master->erasesize) + master->erasesize;
|
||||
sparelen = master->size - spareaddr - master->erasesize;
|
||||
rootfslen = spareaddr - rootfsaddr;
|
||||
|
||||
/* Determine number of partitions */
|
||||
namelen = 8;
|
||||
if (rootfslen > 0) {
|
||||
nrparts++;
|
||||
namelen += 6;
|
||||
};
|
||||
if (kernellen > 0) {
|
||||
nrparts++;
|
||||
namelen += 6;
|
||||
};
|
||||
|
||||
/* Ask kernel for more memory */
|
||||
parts = kzalloc(sizeof(*parts) * nrparts + 10 * nrparts, GFP_KERNEL);
|
||||
if (!parts) {
|
||||
vfree(buf);
|
||||
return -ENOMEM;
|
||||
};
|
||||
|
||||
/* Start building partition list */
|
||||
parts[curpart].name = "CFE";
|
||||
parts[curpart].offset = 0;
|
||||
parts[curpart].size = master->erasesize;
|
||||
curpart++;
|
||||
|
||||
if (kernellen > 0) {
|
||||
parts[curpart].name = "kernel";
|
||||
parts[curpart].offset = kerneladdr;
|
||||
parts[curpart].size = kernellen;
|
||||
curpart++;
|
||||
};
|
||||
|
||||
if (rootfslen > 0) {
|
||||
parts[curpart].name = "rootfs";
|
||||
parts[curpart].offset = rootfsaddr;
|
||||
parts[curpart].size = rootfslen;
|
||||
if (sparelen > 0)
|
||||
parts[curpart].size += sparelen;
|
||||
curpart++;
|
||||
};
|
||||
|
||||
parts[curpart].name = "nvram";
|
||||
parts[curpart].offset = master->size - master->erasesize;
|
||||
parts[curpart].size = master->erasesize;
|
||||
|
||||
/* Global partition "linux" to make easy firmware upgrade */
|
||||
curpart++;
|
||||
parts[curpart].name = "linux";
|
||||
parts[curpart].offset = parts[0].size;
|
||||
parts[curpart].size = master->size - parts[0].size - parts[3].size;
|
||||
|
||||
for (i = 0; i < nrparts; i++)
|
||||
printk(KERN_INFO PFX "Partition %d is %s offset %lx and "
|
||||
"length %lx\n", i, parts[i].name,
|
||||
(long unsigned int)(parts[i].offset),
|
||||
(long unsigned int)(parts[i].size));
|
||||
|
||||
printk(KERN_INFO PFX "Spare partition is %x offset and length %x\n",
|
||||
spareaddr, sparelen);
|
||||
*pparts = parts;
|
||||
vfree(buf);
|
||||
|
||||
return nrparts;
|
||||
};
|
||||
|
||||
static int bcm963xx_detect_cfe(struct mtd_info *master)
|
||||
{
|
||||
int idoffset = 0x4e0;
|
||||
static char idstring[8] = "CFE1CFE1";
|
||||
char buf[9];
|
||||
int ret;
|
||||
size_t retlen;
|
||||
|
||||
ret = master->read(master, idoffset, 8, &retlen, (void *)buf);
|
||||
buf[retlen] = 0;
|
||||
printk(KERN_INFO PFX "Read Signature value of %s\n", buf);
|
||||
|
||||
return strncmp(idstring, buf, 8);
|
||||
}
|
||||
|
||||
static int bcm963xx_probe(struct platform_device *pdev)
|
||||
{
|
||||
int err = 0;
|
||||
int parsed_nr_parts = 0;
|
||||
char *part_type;
|
||||
struct resource *r;
|
||||
|
||||
r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
if (!r) {
|
||||
dev_err(&pdev->dev, "no resource supplied\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
bcm963xx_map.phys = r->start;
|
||||
bcm963xx_map.size = resource_size(r);
|
||||
bcm963xx_map.virt = ioremap(r->start, resource_size(r));
|
||||
if (!bcm963xx_map.virt) {
|
||||
dev_err(&pdev->dev, "failed to ioremap\n");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
dev_info(&pdev->dev, "0x%08lx at 0x%08x\n",
|
||||
bcm963xx_map.size, bcm963xx_map.phys);
|
||||
|
||||
simple_map_init(&bcm963xx_map);
|
||||
|
||||
bcm963xx_mtd_info = do_map_probe("cfi_probe", &bcm963xx_map);
|
||||
if (!bcm963xx_mtd_info) {
|
||||
dev_err(&pdev->dev, "failed to probe using CFI\n");
|
||||
bcm963xx_mtd_info = do_map_probe("jedec_probe", &bcm963xx_map);
|
||||
if (bcm963xx_mtd_info)
|
||||
goto probe_ok;
|
||||
dev_err(&pdev->dev, "failed to probe using JEDEC\n");
|
||||
err = -EIO;
|
||||
goto err_probe;
|
||||
}
|
||||
|
||||
probe_ok:
|
||||
bcm963xx_mtd_info->owner = THIS_MODULE;
|
||||
|
||||
/* This is mutually exclusive */
|
||||
if (bcm963xx_detect_cfe(bcm963xx_mtd_info) == 0) {
|
||||
dev_info(&pdev->dev, "CFE bootloader detected\n");
|
||||
if (parsed_nr_parts == 0) {
|
||||
int ret = parse_cfe_partitions(bcm963xx_mtd_info,
|
||||
&parsed_parts);
|
||||
if (ret > 0) {
|
||||
part_type = "CFE";
|
||||
parsed_nr_parts = ret;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
dev_info(&pdev->dev, "unsupported bootloader\n");
|
||||
err = -ENODEV;
|
||||
goto err_probe;
|
||||
}
|
||||
|
||||
return mtd_device_register(bcm963xx_mtd_info, parsed_parts,
|
||||
parsed_nr_parts);
|
||||
|
||||
err_probe:
|
||||
iounmap(bcm963xx_map.virt);
|
||||
return err;
|
||||
}
|
||||
|
||||
static int bcm963xx_remove(struct platform_device *pdev)
|
||||
{
|
||||
if (bcm963xx_mtd_info) {
|
||||
mtd_device_unregister(bcm963xx_mtd_info);
|
||||
map_destroy(bcm963xx_mtd_info);
|
||||
}
|
||||
|
||||
if (bcm963xx_map.virt) {
|
||||
iounmap(bcm963xx_map.virt);
|
||||
bcm963xx_map.virt = 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver bcm63xx_mtd_dev = {
|
||||
.probe = bcm963xx_probe,
|
||||
.remove = bcm963xx_remove,
|
||||
.driver = {
|
||||
.name = "bcm963xx-flash",
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
};
|
||||
|
||||
static int __init bcm963xx_mtd_init(void)
|
||||
{
|
||||
return platform_driver_register(&bcm63xx_mtd_dev);
|
||||
}
|
||||
|
||||
static void __exit bcm963xx_mtd_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&bcm63xx_mtd_dev);
|
||||
}
|
||||
|
||||
module_init(bcm963xx_mtd_init);
|
||||
module_exit(bcm963xx_mtd_exit);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_DESCRIPTION("Broadcom BCM63xx MTD driver for CFE and RedBoot");
|
||||
MODULE_AUTHOR("Daniel Dickinson <openwrt@cshore.neomailbox.net>");
|
||||
MODULE_AUTHOR("Florian Fainelli <florian@openwrt.org>");
|
||||
MODULE_AUTHOR("Mike Albon <malbon@openwrt.org>");
|
@ -190,17 +190,7 @@ static struct platform_driver bfin_flash_driver = {
|
||||
},
|
||||
};
|
||||
|
||||
static int __init bfin_flash_init(void)
|
||||
{
|
||||
return platform_driver_register(&bfin_flash_driver);
|
||||
}
|
||||
module_init(bfin_flash_init);
|
||||
|
||||
static void __exit bfin_flash_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&bfin_flash_driver);
|
||||
}
|
||||
module_exit(bfin_flash_exit);
|
||||
module_platform_driver(bfin_flash_driver);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_DESCRIPTION("MTD map driver for Blackfins with flash/ethernet on same async bank");
|
||||
|
@ -279,17 +279,7 @@ static struct platform_driver gpio_flash_driver = {
|
||||
},
|
||||
};
|
||||
|
||||
static int __init gpio_flash_init(void)
|
||||
{
|
||||
return platform_driver_register(&gpio_flash_driver);
|
||||
}
|
||||
module_init(gpio_flash_init);
|
||||
|
||||
static void __exit gpio_flash_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&gpio_flash_driver);
|
||||
}
|
||||
module_exit(gpio_flash_exit);
|
||||
module_platform_driver(gpio_flash_driver);
|
||||
|
||||
MODULE_AUTHOR("Mike Frysinger <vapier@gentoo.org>");
|
||||
MODULE_DESCRIPTION("MTD map driver for flashes addressed physically and with gpios");
|
||||
|
@ -246,18 +246,8 @@ static struct platform_driver ixp2000_flash_driver = {
|
||||
},
|
||||
};
|
||||
|
||||
static int __init ixp2000_flash_init(void)
|
||||
{
|
||||
return platform_driver_register(&ixp2000_flash_driver);
|
||||
}
|
||||
module_platform_driver(ixp2000_flash_driver);
|
||||
|
||||
static void __exit ixp2000_flash_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&ixp2000_flash_driver);
|
||||
}
|
||||
|
||||
module_init(ixp2000_flash_init);
|
||||
module_exit(ixp2000_flash_exit);
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Deepak Saxena <dsaxena@plexity.net>");
|
||||
MODULE_ALIAS("platform:IXP2000-Flash");
|
||||
|
@ -270,19 +270,7 @@ static struct platform_driver ixp4xx_flash_driver = {
|
||||
},
|
||||
};
|
||||
|
||||
static int __init ixp4xx_flash_init(void)
|
||||
{
|
||||
return platform_driver_register(&ixp4xx_flash_driver);
|
||||
}
|
||||
|
||||
static void __exit ixp4xx_flash_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&ixp4xx_flash_driver);
|
||||
}
|
||||
|
||||
|
||||
module_init(ixp4xx_flash_init);
|
||||
module_exit(ixp4xx_flash_exit);
|
||||
module_platform_driver(ixp4xx_flash_driver);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_DESCRIPTION("MTD map driver for Intel IXP4xx systems");
|
||||
|
@ -159,7 +159,7 @@ ltq_mtd_probe(struct platform_device *pdev)
|
||||
if (!ltq_mtd->mtd) {
|
||||
dev_err(&pdev->dev, "probing failed\n");
|
||||
err = -ENXIO;
|
||||
goto err_unmap;
|
||||
goto err_free;
|
||||
}
|
||||
|
||||
ltq_mtd->mtd->owner = THIS_MODULE;
|
||||
@ -179,8 +179,6 @@ ltq_mtd_probe(struct platform_device *pdev)
|
||||
|
||||
err_destroy:
|
||||
map_destroy(ltq_mtd->mtd);
|
||||
err_unmap:
|
||||
iounmap(ltq_mtd->map->virt);
|
||||
err_free:
|
||||
kfree(ltq_mtd->map);
|
||||
err_out:
|
||||
@ -198,8 +196,6 @@ ltq_mtd_remove(struct platform_device *pdev)
|
||||
mtd_device_unregister(ltq_mtd->mtd);
|
||||
map_destroy(ltq_mtd->mtd);
|
||||
}
|
||||
if (ltq_mtd->map->virt)
|
||||
iounmap(ltq_mtd->map->virt);
|
||||
kfree(ltq_mtd->map);
|
||||
kfree(ltq_mtd);
|
||||
}
|
||||
|
@ -223,17 +223,7 @@ static struct platform_driver latch_addr_flash_driver = {
|
||||
},
|
||||
};
|
||||
|
||||
static int __init latch_addr_flash_init(void)
|
||||
{
|
||||
return platform_driver_register(&latch_addr_flash_driver);
|
||||
}
|
||||
module_init(latch_addr_flash_init);
|
||||
|
||||
static void __exit latch_addr_flash_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&latch_addr_flash_driver);
|
||||
}
|
||||
module_exit(latch_addr_flash_exit);
|
||||
module_platform_driver(latch_addr_flash_driver);
|
||||
|
||||
MODULE_AUTHOR("David Griego <dgriego@mvista.com>");
|
||||
MODULE_DESCRIPTION("MTD map driver for flashes addressed physically with upper "
|
||||
|
@ -85,6 +85,7 @@ static int physmap_flash_probe(struct platform_device *dev)
|
||||
struct physmap_flash_data *physmap_data;
|
||||
struct physmap_flash_info *info;
|
||||
const char **probe_type;
|
||||
const char **part_types;
|
||||
int err = 0;
|
||||
int i;
|
||||
int devices_found = 0;
|
||||
@ -171,7 +172,9 @@ static int physmap_flash_probe(struct platform_device *dev)
|
||||
if (err)
|
||||
goto err_out;
|
||||
|
||||
mtd_device_parse_register(info->cmtd, part_probe_types, 0,
|
||||
part_types = physmap_data->part_probe_types ? : part_probe_types;
|
||||
|
||||
mtd_device_parse_register(info->cmtd, part_types, 0,
|
||||
physmap_data->parts, physmap_data->nr_parts);
|
||||
return 0;
|
||||
|
||||
@ -187,9 +190,8 @@ static void physmap_flash_shutdown(struct platform_device *dev)
|
||||
int i;
|
||||
|
||||
for (i = 0; i < MAX_RESOURCES && info->mtd[i]; i++)
|
||||
if (info->mtd[i]->suspend && info->mtd[i]->resume)
|
||||
if (info->mtd[i]->suspend(info->mtd[i]) == 0)
|
||||
info->mtd[i]->resume(info->mtd[i]);
|
||||
if (mtd_suspend(info->mtd[i]) == 0)
|
||||
mtd_resume(info->mtd[i]);
|
||||
}
|
||||
#else
|
||||
#define physmap_flash_shutdown NULL
|
||||
|
@ -338,18 +338,7 @@ static struct platform_driver of_flash_driver = {
|
||||
.remove = of_flash_remove,
|
||||
};
|
||||
|
||||
static int __init of_flash_init(void)
|
||||
{
|
||||
return platform_driver_register(&of_flash_driver);
|
||||
}
|
||||
|
||||
static void __exit of_flash_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&of_flash_driver);
|
||||
}
|
||||
|
||||
module_init(of_flash_init);
|
||||
module_exit(of_flash_exit);
|
||||
module_platform_driver(of_flash_driver);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Vitaly Wool <vwool@ru.mvista.com>");
|
||||
|
@ -125,8 +125,8 @@ static void pxa2xx_flash_shutdown(struct platform_device *dev)
|
||||
{
|
||||
struct pxa2xx_flash_info *info = platform_get_drvdata(dev);
|
||||
|
||||
if (info && info->mtd->suspend(info->mtd) == 0)
|
||||
info->mtd->resume(info->mtd);
|
||||
if (info && mtd_suspend(info->mtd) == 0)
|
||||
mtd_resume(info->mtd);
|
||||
}
|
||||
#else
|
||||
#define pxa2xx_flash_shutdown NULL
|
||||
@ -142,18 +142,7 @@ static struct platform_driver pxa2xx_flash_driver = {
|
||||
.shutdown = pxa2xx_flash_shutdown,
|
||||
};
|
||||
|
||||
static int __init init_pxa2xx_flash(void)
|
||||
{
|
||||
return platform_driver_register(&pxa2xx_flash_driver);
|
||||
}
|
||||
|
||||
static void __exit cleanup_pxa2xx_flash(void)
|
||||
{
|
||||
platform_driver_unregister(&pxa2xx_flash_driver);
|
||||
}
|
||||
|
||||
module_init(init_pxa2xx_flash);
|
||||
module_exit(cleanup_pxa2xx_flash);
|
||||
module_platform_driver(pxa2xx_flash_driver);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Nicolas Pitre <nico@fluxnic.net>");
|
||||
|
@ -119,9 +119,8 @@ static void rbtx4939_flash_shutdown(struct platform_device *dev)
|
||||
{
|
||||
struct rbtx4939_flash_info *info = platform_get_drvdata(dev);
|
||||
|
||||
if (info->mtd->suspend && info->mtd->resume)
|
||||
if (info->mtd->suspend(info->mtd) == 0)
|
||||
info->mtd->resume(info->mtd);
|
||||
if (mtd_suspend(info->mtd) == 0)
|
||||
mtd_resume(info->mtd);
|
||||
}
|
||||
#else
|
||||
#define rbtx4939_flash_shutdown NULL
|
||||
@ -137,18 +136,7 @@ static struct platform_driver rbtx4939_flash_driver = {
|
||||
},
|
||||
};
|
||||
|
||||
static int __init rbtx4939_flash_init(void)
|
||||
{
|
||||
return platform_driver_register(&rbtx4939_flash_driver);
|
||||
}
|
||||
|
||||
static void __exit rbtx4939_flash_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&rbtx4939_flash_driver);
|
||||
}
|
||||
|
||||
module_init(rbtx4939_flash_init);
|
||||
module_exit(rbtx4939_flash_exit);
|
||||
module_platform_driver(rbtx4939_flash_driver);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_DESCRIPTION("RBTX4939 MTD map driver");
|
||||
|
@ -377,8 +377,8 @@ static int __exit sa1100_mtd_remove(struct platform_device *pdev)
|
||||
static void sa1100_mtd_shutdown(struct platform_device *dev)
|
||||
{
|
||||
struct sa_info *info = platform_get_drvdata(dev);
|
||||
if (info && info->mtd->suspend(info->mtd) == 0)
|
||||
info->mtd->resume(info->mtd);
|
||||
if (info && mtd_suspend(info->mtd) == 0)
|
||||
mtd_resume(info->mtd);
|
||||
}
|
||||
#else
|
||||
#define sa1100_mtd_shutdown NULL
|
||||
@ -394,18 +394,7 @@ static struct platform_driver sa1100_mtd_driver = {
|
||||
},
|
||||
};
|
||||
|
||||
static int __init sa1100_mtd_init(void)
|
||||
{
|
||||
return platform_driver_register(&sa1100_mtd_driver);
|
||||
}
|
||||
|
||||
static void __exit sa1100_mtd_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&sa1100_mtd_driver);
|
||||
}
|
||||
|
||||
module_init(sa1100_mtd_init);
|
||||
module_exit(sa1100_mtd_exit);
|
||||
module_platform_driver(sa1100_mtd_driver);
|
||||
|
||||
MODULE_AUTHOR("Nicolas Pitre");
|
||||
MODULE_DESCRIPTION("SA1100 CFI map driver");
|
||||
|
@ -204,8 +204,7 @@ scb2_flash_remove(struct pci_dev *dev)
|
||||
return;
|
||||
|
||||
/* disable flash writes */
|
||||
if (scb2_mtd->lock)
|
||||
scb2_mtd->lock(scb2_mtd, 0, scb2_mtd->size);
|
||||
mtd_lock(scb2_mtd, 0, scb2_mtd->size);
|
||||
|
||||
mtd_device_unregister(scb2_mtd);
|
||||
map_destroy(scb2_mtd);
|
||||
|
@ -158,15 +158,4 @@ static struct platform_driver uflash_driver = {
|
||||
.remove = __devexit_p(uflash_remove),
|
||||
};
|
||||
|
||||
static int __init uflash_init(void)
|
||||
{
|
||||
return platform_driver_register(&uflash_driver);
|
||||
}
|
||||
|
||||
static void __exit uflash_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&uflash_driver);
|
||||
}
|
||||
|
||||
module_init(uflash_init);
|
||||
module_exit(uflash_exit);
|
||||
module_platform_driver(uflash_driver);
|
||||
|
@ -215,7 +215,7 @@ static int blktrans_open(struct block_device *bdev, fmode_t mode)
|
||||
|
||||
mutex_lock(&dev->lock);
|
||||
|
||||
if (dev->open++)
|
||||
if (dev->open)
|
||||
goto unlock;
|
||||
|
||||
kref_get(&dev->ref);
|
||||
@ -235,6 +235,7 @@ static int blktrans_open(struct block_device *bdev, fmode_t mode)
|
||||
goto error_release;
|
||||
|
||||
unlock:
|
||||
dev->open++;
|
||||
mutex_unlock(&dev->lock);
|
||||
blktrans_dev_put(dev);
|
||||
return ret;
|
||||
|
@ -85,7 +85,7 @@ static int erase_write (struct mtd_info *mtd, unsigned long pos,
|
||||
set_current_state(TASK_INTERRUPTIBLE);
|
||||
add_wait_queue(&wait_q, &wait);
|
||||
|
||||
ret = mtd->erase(mtd, &erase);
|
||||
ret = mtd_erase(mtd, &erase);
|
||||
if (ret) {
|
||||
set_current_state(TASK_RUNNING);
|
||||
remove_wait_queue(&wait_q, &wait);
|
||||
@ -102,7 +102,7 @@ static int erase_write (struct mtd_info *mtd, unsigned long pos,
|
||||
* Next, write the data to flash.
|
||||
*/
|
||||
|
||||
ret = mtd->write(mtd, pos, len, &retlen, buf);
|
||||
ret = mtd_write(mtd, pos, len, &retlen, buf);
|
||||
if (ret)
|
||||
return ret;
|
||||
if (retlen != len)
|
||||
@ -152,7 +152,7 @@ static int do_cached_write (struct mtdblk_dev *mtdblk, unsigned long pos,
|
||||
mtd->name, pos, len);
|
||||
|
||||
if (!sect_size)
|
||||
return mtd->write(mtd, pos, len, &retlen, buf);
|
||||
return mtd_write(mtd, pos, len, &retlen, buf);
|
||||
|
||||
while (len > 0) {
|
||||
unsigned long sect_start = (pos/sect_size)*sect_size;
|
||||
@ -184,8 +184,8 @@ static int do_cached_write (struct mtdblk_dev *mtdblk, unsigned long pos,
|
||||
mtdblk->cache_offset != sect_start) {
|
||||
/* fill the cache with the current sector */
|
||||
mtdblk->cache_state = STATE_EMPTY;
|
||||
ret = mtd->read(mtd, sect_start, sect_size,
|
||||
&retlen, mtdblk->cache_data);
|
||||
ret = mtd_read(mtd, sect_start, sect_size,
|
||||
&retlen, mtdblk->cache_data);
|
||||
if (ret)
|
||||
return ret;
|
||||
if (retlen != sect_size)
|
||||
@ -222,7 +222,7 @@ static int do_cached_read (struct mtdblk_dev *mtdblk, unsigned long pos,
|
||||
mtd->name, pos, len);
|
||||
|
||||
if (!sect_size)
|
||||
return mtd->read(mtd, pos, len, &retlen, buf);
|
||||
return mtd_read(mtd, pos, len, &retlen, buf);
|
||||
|
||||
while (len > 0) {
|
||||
unsigned long sect_start = (pos/sect_size)*sect_size;
|
||||
@ -241,7 +241,7 @@ static int do_cached_read (struct mtdblk_dev *mtdblk, unsigned long pos,
|
||||
mtdblk->cache_offset == sect_start) {
|
||||
memcpy (buf, mtdblk->cache_data + offset, size);
|
||||
} else {
|
||||
ret = mtd->read(mtd, pos, size, &retlen, buf);
|
||||
ret = mtd_read(mtd, pos, size, &retlen, buf);
|
||||
if (ret)
|
||||
return ret;
|
||||
if (retlen != size)
|
||||
@ -322,8 +322,7 @@ static int mtdblock_release(struct mtd_blktrans_dev *mbd)
|
||||
|
||||
if (!--mtdblk->count) {
|
||||
/* It was the last usage. Free the cache */
|
||||
if (mbd->mtd->sync)
|
||||
mbd->mtd->sync(mbd->mtd);
|
||||
mtd_sync(mbd->mtd);
|
||||
vfree(mtdblk->cache_data);
|
||||
}
|
||||
|
||||
@ -341,9 +340,7 @@ static int mtdblock_flush(struct mtd_blktrans_dev *dev)
|
||||
mutex_lock(&mtdblk->cache_mutex);
|
||||
write_cached_data(mtdblk);
|
||||
mutex_unlock(&mtdblk->cache_mutex);
|
||||
|
||||
if (dev->mtd->sync)
|
||||
dev->mtd->sync(dev->mtd);
|
||||
mtd_sync(dev->mtd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -30,7 +30,7 @@ static int mtdblock_readsect(struct mtd_blktrans_dev *dev,
|
||||
{
|
||||
size_t retlen;
|
||||
|
||||
if (dev->mtd->read(dev->mtd, (block * 512), 512, &retlen, buf))
|
||||
if (mtd_read(dev->mtd, (block * 512), 512, &retlen, buf))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
@ -40,7 +40,7 @@ static int mtdblock_writesect(struct mtd_blktrans_dev *dev,
|
||||
{
|
||||
size_t retlen;
|
||||
|
||||
if (dev->mtd->write(dev->mtd, (block * 512), 512, &retlen, buf))
|
||||
if (mtd_write(dev->mtd, (block * 512), 512, &retlen, buf))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
@ -51,7 +51,7 @@ struct mtd_file_info {
|
||||
enum mtd_file_modes mode;
|
||||
};
|
||||
|
||||
static loff_t mtd_lseek (struct file *file, loff_t offset, int orig)
|
||||
static loff_t mtdchar_lseek(struct file *file, loff_t offset, int orig)
|
||||
{
|
||||
struct mtd_file_info *mfi = file->private_data;
|
||||
struct mtd_info *mtd = mfi->mtd;
|
||||
@ -77,7 +77,7 @@ static loff_t mtd_lseek (struct file *file, loff_t offset, int orig)
|
||||
|
||||
|
||||
|
||||
static int mtd_open(struct inode *inode, struct file *file)
|
||||
static int mtdchar_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
int minor = iminor(inode);
|
||||
int devnum = minor >> 1;
|
||||
@ -142,11 +142,11 @@ static int mtd_open(struct inode *inode, struct file *file)
|
||||
out:
|
||||
mutex_unlock(&mtd_mutex);
|
||||
return ret;
|
||||
} /* mtd_open */
|
||||
} /* mtdchar_open */
|
||||
|
||||
/*====================================================================*/
|
||||
|
||||
static int mtd_close(struct inode *inode, struct file *file)
|
||||
static int mtdchar_close(struct inode *inode, struct file *file)
|
||||
{
|
||||
struct mtd_file_info *mfi = file->private_data;
|
||||
struct mtd_info *mtd = mfi->mtd;
|
||||
@ -154,8 +154,8 @@ static int mtd_close(struct inode *inode, struct file *file)
|
||||
pr_debug("MTD_close\n");
|
||||
|
||||
/* Only sync if opened RW */
|
||||
if ((file->f_mode & FMODE_WRITE) && mtd->sync)
|
||||
mtd->sync(mtd);
|
||||
if ((file->f_mode & FMODE_WRITE))
|
||||
mtd_sync(mtd);
|
||||
|
||||
iput(mfi->ino);
|
||||
|
||||
@ -164,7 +164,7 @@ static int mtd_close(struct inode *inode, struct file *file)
|
||||
kfree(mfi);
|
||||
|
||||
return 0;
|
||||
} /* mtd_close */
|
||||
} /* mtdchar_close */
|
||||
|
||||
/* Back in June 2001, dwmw2 wrote:
|
||||
*
|
||||
@ -184,11 +184,12 @@ static int mtd_close(struct inode *inode, struct file *file)
|
||||
* alignment requirements are not met in the NAND subdriver.
|
||||
*/
|
||||
|
||||
static ssize_t mtd_read(struct file *file, char __user *buf, size_t count,loff_t *ppos)
|
||||
static ssize_t mtdchar_read(struct file *file, char __user *buf, size_t count,
|
||||
loff_t *ppos)
|
||||
{
|
||||
struct mtd_file_info *mfi = file->private_data;
|
||||
struct mtd_info *mtd = mfi->mtd;
|
||||
size_t retlen=0;
|
||||
size_t retlen;
|
||||
size_t total_retlen=0;
|
||||
int ret=0;
|
||||
int len;
|
||||
@ -212,10 +213,12 @@ static ssize_t mtd_read(struct file *file, char __user *buf, size_t count,loff_t
|
||||
|
||||
switch (mfi->mode) {
|
||||
case MTD_FILE_MODE_OTP_FACTORY:
|
||||
ret = mtd->read_fact_prot_reg(mtd, *ppos, len, &retlen, kbuf);
|
||||
ret = mtd_read_fact_prot_reg(mtd, *ppos, len,
|
||||
&retlen, kbuf);
|
||||
break;
|
||||
case MTD_FILE_MODE_OTP_USER:
|
||||
ret = mtd->read_user_prot_reg(mtd, *ppos, len, &retlen, kbuf);
|
||||
ret = mtd_read_user_prot_reg(mtd, *ppos, len,
|
||||
&retlen, kbuf);
|
||||
break;
|
||||
case MTD_FILE_MODE_RAW:
|
||||
{
|
||||
@ -226,12 +229,12 @@ static ssize_t mtd_read(struct file *file, char __user *buf, size_t count,loff_t
|
||||
ops.oobbuf = NULL;
|
||||
ops.len = len;
|
||||
|
||||
ret = mtd->read_oob(mtd, *ppos, &ops);
|
||||
ret = mtd_read_oob(mtd, *ppos, &ops);
|
||||
retlen = ops.retlen;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
ret = mtd->read(mtd, *ppos, len, &retlen, kbuf);
|
||||
ret = mtd_read(mtd, *ppos, len, &retlen, kbuf);
|
||||
}
|
||||
/* Nand returns -EBADMSG on ECC errors, but it returns
|
||||
* the data. For our userspace tools it is important
|
||||
@ -265,9 +268,10 @@ static ssize_t mtd_read(struct file *file, char __user *buf, size_t count,loff_t
|
||||
|
||||
kfree(kbuf);
|
||||
return total_retlen;
|
||||
} /* mtd_read */
|
||||
} /* mtdchar_read */
|
||||
|
||||
static ssize_t mtd_write(struct file *file, const char __user *buf, size_t count,loff_t *ppos)
|
||||
static ssize_t mtdchar_write(struct file *file, const char __user *buf, size_t count,
|
||||
loff_t *ppos)
|
||||
{
|
||||
struct mtd_file_info *mfi = file->private_data;
|
||||
struct mtd_info *mtd = mfi->mtd;
|
||||
@ -306,11 +310,8 @@ static ssize_t mtd_write(struct file *file, const char __user *buf, size_t count
|
||||
ret = -EROFS;
|
||||
break;
|
||||
case MTD_FILE_MODE_OTP_USER:
|
||||
if (!mtd->write_user_prot_reg) {
|
||||
ret = -EOPNOTSUPP;
|
||||
break;
|
||||
}
|
||||
ret = mtd->write_user_prot_reg(mtd, *ppos, len, &retlen, kbuf);
|
||||
ret = mtd_write_user_prot_reg(mtd, *ppos, len,
|
||||
&retlen, kbuf);
|
||||
break;
|
||||
|
||||
case MTD_FILE_MODE_RAW:
|
||||
@ -323,13 +324,13 @@ static ssize_t mtd_write(struct file *file, const char __user *buf, size_t count
|
||||
ops.ooboffs = 0;
|
||||
ops.len = len;
|
||||
|
||||
ret = mtd->write_oob(mtd, *ppos, &ops);
|
||||
ret = mtd_write_oob(mtd, *ppos, &ops);
|
||||
retlen = ops.retlen;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
ret = (*(mtd->write))(mtd, *ppos, len, &retlen, kbuf);
|
||||
ret = mtd_write(mtd, *ppos, len, &retlen, kbuf);
|
||||
}
|
||||
if (!ret) {
|
||||
*ppos += retlen;
|
||||
@ -345,7 +346,7 @@ static ssize_t mtd_write(struct file *file, const char __user *buf, size_t count
|
||||
|
||||
kfree(kbuf);
|
||||
return total_retlen;
|
||||
} /* mtd_write */
|
||||
} /* mtdchar_write */
|
||||
|
||||
/*======================================================================
|
||||
|
||||
@ -361,20 +362,22 @@ static void mtdchar_erase_callback (struct erase_info *instr)
|
||||
static int otp_select_filemode(struct mtd_file_info *mfi, int mode)
|
||||
{
|
||||
struct mtd_info *mtd = mfi->mtd;
|
||||
size_t retlen;
|
||||
int ret = 0;
|
||||
|
||||
/*
|
||||
* Make a fake call to mtd_read_fact_prot_reg() to check if OTP
|
||||
* operations are supported.
|
||||
*/
|
||||
if (mtd_read_fact_prot_reg(mtd, -1, -1, &retlen, NULL) == -EOPNOTSUPP)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
switch (mode) {
|
||||
case MTD_OTP_FACTORY:
|
||||
if (!mtd->read_fact_prot_reg)
|
||||
ret = -EOPNOTSUPP;
|
||||
else
|
||||
mfi->mode = MTD_FILE_MODE_OTP_FACTORY;
|
||||
mfi->mode = MTD_FILE_MODE_OTP_FACTORY;
|
||||
break;
|
||||
case MTD_OTP_USER:
|
||||
if (!mtd->read_fact_prot_reg)
|
||||
ret = -EOPNOTSUPP;
|
||||
else
|
||||
mfi->mode = MTD_FILE_MODE_OTP_USER;
|
||||
mfi->mode = MTD_FILE_MODE_OTP_USER;
|
||||
break;
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
@ -387,7 +390,7 @@ static int otp_select_filemode(struct mtd_file_info *mfi, int mode)
|
||||
# define otp_select_filemode(f,m) -EOPNOTSUPP
|
||||
#endif
|
||||
|
||||
static int mtd_do_writeoob(struct file *file, struct mtd_info *mtd,
|
||||
static int mtdchar_writeoob(struct file *file, struct mtd_info *mtd,
|
||||
uint64_t start, uint32_t length, void __user *ptr,
|
||||
uint32_t __user *retp)
|
||||
{
|
||||
@ -424,7 +427,7 @@ static int mtd_do_writeoob(struct file *file, struct mtd_info *mtd,
|
||||
return PTR_ERR(ops.oobbuf);
|
||||
|
||||
start &= ~((uint64_t)mtd->writesize - 1);
|
||||
ret = mtd->write_oob(mtd, start, &ops);
|
||||
ret = mtd_write_oob(mtd, start, &ops);
|
||||
|
||||
if (ops.oobretlen > 0xFFFFFFFFU)
|
||||
ret = -EOVERFLOW;
|
||||
@ -436,7 +439,7 @@ static int mtd_do_writeoob(struct file *file, struct mtd_info *mtd,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int mtd_do_readoob(struct file *file, struct mtd_info *mtd,
|
||||
static int mtdchar_readoob(struct file *file, struct mtd_info *mtd,
|
||||
uint64_t start, uint32_t length, void __user *ptr,
|
||||
uint32_t __user *retp)
|
||||
{
|
||||
@ -447,13 +450,8 @@ static int mtd_do_readoob(struct file *file, struct mtd_info *mtd,
|
||||
if (length > 4096)
|
||||
return -EINVAL;
|
||||
|
||||
if (!mtd->read_oob)
|
||||
ret = -EOPNOTSUPP;
|
||||
else
|
||||
ret = access_ok(VERIFY_WRITE, ptr,
|
||||
length) ? 0 : -EFAULT;
|
||||
if (ret)
|
||||
return ret;
|
||||
if (!access_ok(VERIFY_WRITE, ptr, length))
|
||||
return -EFAULT;
|
||||
|
||||
ops.ooblen = length;
|
||||
ops.ooboffs = start & (mtd->writesize - 1);
|
||||
@ -469,7 +467,7 @@ static int mtd_do_readoob(struct file *file, struct mtd_info *mtd,
|
||||
return -ENOMEM;
|
||||
|
||||
start &= ~((uint64_t)mtd->writesize - 1);
|
||||
ret = mtd->read_oob(mtd, start, &ops);
|
||||
ret = mtd_read_oob(mtd, start, &ops);
|
||||
|
||||
if (put_user(ops.oobretlen, retp))
|
||||
ret = -EFAULT;
|
||||
@ -530,7 +528,7 @@ static int shrink_ecclayout(const struct nand_ecclayout *from,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mtd_blkpg_ioctl(struct mtd_info *mtd,
|
||||
static int mtdchar_blkpg_ioctl(struct mtd_info *mtd,
|
||||
struct blkpg_ioctl_arg __user *arg)
|
||||
{
|
||||
struct blkpg_ioctl_arg a;
|
||||
@ -566,7 +564,7 @@ static int mtd_blkpg_ioctl(struct mtd_info *mtd,
|
||||
}
|
||||
}
|
||||
|
||||
static int mtd_write_ioctl(struct mtd_info *mtd,
|
||||
static int mtdchar_write_ioctl(struct mtd_info *mtd,
|
||||
struct mtd_write_req __user *argp)
|
||||
{
|
||||
struct mtd_write_req req;
|
||||
@ -607,7 +605,7 @@ static int mtd_write_ioctl(struct mtd_info *mtd,
|
||||
ops.oobbuf = NULL;
|
||||
}
|
||||
|
||||
ret = mtd->write_oob(mtd, (loff_t)req.start, &ops);
|
||||
ret = mtd_write_oob(mtd, (loff_t)req.start, &ops);
|
||||
|
||||
kfree(ops.datbuf);
|
||||
kfree(ops.oobbuf);
|
||||
@ -615,7 +613,7 @@ static int mtd_write_ioctl(struct mtd_info *mtd,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int mtd_ioctl(struct file *file, u_int cmd, u_long arg)
|
||||
static int mtdchar_ioctl(struct file *file, u_int cmd, u_long arg)
|
||||
{
|
||||
struct mtd_file_info *mfi = file->private_data;
|
||||
struct mtd_info *mtd = mfi->mtd;
|
||||
@ -729,7 +727,7 @@ static int mtd_ioctl(struct file *file, u_int cmd, u_long arg)
|
||||
wq_head is no longer there when the
|
||||
callback routine tries to wake us up.
|
||||
*/
|
||||
ret = mtd->erase(mtd, erase);
|
||||
ret = mtd_erase(mtd, erase);
|
||||
if (!ret) {
|
||||
set_current_state(TASK_UNINTERRUPTIBLE);
|
||||
add_wait_queue(&waitq, &wait);
|
||||
@ -755,7 +753,7 @@ static int mtd_ioctl(struct file *file, u_int cmd, u_long arg)
|
||||
if (copy_from_user(&buf, argp, sizeof(buf)))
|
||||
ret = -EFAULT;
|
||||
else
|
||||
ret = mtd_do_writeoob(file, mtd, buf.start, buf.length,
|
||||
ret = mtdchar_writeoob(file, mtd, buf.start, buf.length,
|
||||
buf.ptr, &buf_user->length);
|
||||
break;
|
||||
}
|
||||
@ -769,7 +767,7 @@ static int mtd_ioctl(struct file *file, u_int cmd, u_long arg)
|
||||
if (copy_from_user(&buf, argp, sizeof(buf)))
|
||||
ret = -EFAULT;
|
||||
else
|
||||
ret = mtd_do_readoob(file, mtd, buf.start, buf.length,
|
||||
ret = mtdchar_readoob(file, mtd, buf.start, buf.length,
|
||||
buf.ptr, &buf_user->start);
|
||||
break;
|
||||
}
|
||||
@ -782,7 +780,7 @@ static int mtd_ioctl(struct file *file, u_int cmd, u_long arg)
|
||||
if (copy_from_user(&buf, argp, sizeof(buf)))
|
||||
ret = -EFAULT;
|
||||
else
|
||||
ret = mtd_do_writeoob(file, mtd, buf.start, buf.length,
|
||||
ret = mtdchar_writeoob(file, mtd, buf.start, buf.length,
|
||||
(void __user *)(uintptr_t)buf.usr_ptr,
|
||||
&buf_user->length);
|
||||
break;
|
||||
@ -796,7 +794,7 @@ static int mtd_ioctl(struct file *file, u_int cmd, u_long arg)
|
||||
if (copy_from_user(&buf, argp, sizeof(buf)))
|
||||
ret = -EFAULT;
|
||||
else
|
||||
ret = mtd_do_readoob(file, mtd, buf.start, buf.length,
|
||||
ret = mtdchar_readoob(file, mtd, buf.start, buf.length,
|
||||
(void __user *)(uintptr_t)buf.usr_ptr,
|
||||
&buf_user->length);
|
||||
break;
|
||||
@ -804,7 +802,7 @@ static int mtd_ioctl(struct file *file, u_int cmd, u_long arg)
|
||||
|
||||
case MEMWRITE:
|
||||
{
|
||||
ret = mtd_write_ioctl(mtd,
|
||||
ret = mtdchar_write_ioctl(mtd,
|
||||
(struct mtd_write_req __user *)arg);
|
||||
break;
|
||||
}
|
||||
@ -816,10 +814,7 @@ static int mtd_ioctl(struct file *file, u_int cmd, u_long arg)
|
||||
if (copy_from_user(&einfo, argp, sizeof(einfo)))
|
||||
return -EFAULT;
|
||||
|
||||
if (!mtd->lock)
|
||||
ret = -EOPNOTSUPP;
|
||||
else
|
||||
ret = mtd->lock(mtd, einfo.start, einfo.length);
|
||||
ret = mtd_lock(mtd, einfo.start, einfo.length);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -830,10 +825,7 @@ static int mtd_ioctl(struct file *file, u_int cmd, u_long arg)
|
||||
if (copy_from_user(&einfo, argp, sizeof(einfo)))
|
||||
return -EFAULT;
|
||||
|
||||
if (!mtd->unlock)
|
||||
ret = -EOPNOTSUPP;
|
||||
else
|
||||
ret = mtd->unlock(mtd, einfo.start, einfo.length);
|
||||
ret = mtd_unlock(mtd, einfo.start, einfo.length);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -844,10 +836,7 @@ static int mtd_ioctl(struct file *file, u_int cmd, u_long arg)
|
||||
if (copy_from_user(&einfo, argp, sizeof(einfo)))
|
||||
return -EFAULT;
|
||||
|
||||
if (!mtd->is_locked)
|
||||
ret = -EOPNOTSUPP;
|
||||
else
|
||||
ret = mtd->is_locked(mtd, einfo.start, einfo.length);
|
||||
ret = mtd_is_locked(mtd, einfo.start, einfo.length);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -878,10 +867,7 @@ static int mtd_ioctl(struct file *file, u_int cmd, u_long arg)
|
||||
|
||||
if (copy_from_user(&offs, argp, sizeof(loff_t)))
|
||||
return -EFAULT;
|
||||
if (!mtd->block_isbad)
|
||||
ret = -EOPNOTSUPP;
|
||||
else
|
||||
return mtd->block_isbad(mtd, offs);
|
||||
return mtd_block_isbad(mtd, offs);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -891,10 +877,7 @@ static int mtd_ioctl(struct file *file, u_int cmd, u_long arg)
|
||||
|
||||
if (copy_from_user(&offs, argp, sizeof(loff_t)))
|
||||
return -EFAULT;
|
||||
if (!mtd->block_markbad)
|
||||
ret = -EOPNOTSUPP;
|
||||
else
|
||||
return mtd->block_markbad(mtd, offs);
|
||||
return mtd_block_markbad(mtd, offs);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -919,17 +902,15 @@ static int mtd_ioctl(struct file *file, u_int cmd, u_long arg)
|
||||
struct otp_info *buf = kmalloc(4096, GFP_KERNEL);
|
||||
if (!buf)
|
||||
return -ENOMEM;
|
||||
ret = -EOPNOTSUPP;
|
||||
switch (mfi->mode) {
|
||||
case MTD_FILE_MODE_OTP_FACTORY:
|
||||
if (mtd->get_fact_prot_info)
|
||||
ret = mtd->get_fact_prot_info(mtd, buf, 4096);
|
||||
ret = mtd_get_fact_prot_info(mtd, buf, 4096);
|
||||
break;
|
||||
case MTD_FILE_MODE_OTP_USER:
|
||||
if (mtd->get_user_prot_info)
|
||||
ret = mtd->get_user_prot_info(mtd, buf, 4096);
|
||||
ret = mtd_get_user_prot_info(mtd, buf, 4096);
|
||||
break;
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
if (ret >= 0) {
|
||||
@ -953,9 +934,7 @@ static int mtd_ioctl(struct file *file, u_int cmd, u_long arg)
|
||||
return -EINVAL;
|
||||
if (copy_from_user(&oinfo, argp, sizeof(oinfo)))
|
||||
return -EFAULT;
|
||||
if (!mtd->lock_user_prot_reg)
|
||||
return -EOPNOTSUPP;
|
||||
ret = mtd->lock_user_prot_reg(mtd, oinfo.start, oinfo.length);
|
||||
ret = mtd_lock_user_prot_reg(mtd, oinfo.start, oinfo.length);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
@ -999,7 +978,7 @@ static int mtd_ioctl(struct file *file, u_int cmd, u_long arg)
|
||||
break;
|
||||
|
||||
case MTD_FILE_MODE_RAW:
|
||||
if (!mtd->read_oob || !mtd->write_oob)
|
||||
if (!mtd_has_oob(mtd))
|
||||
return -EOPNOTSUPP;
|
||||
mfi->mode = arg;
|
||||
|
||||
@ -1014,7 +993,7 @@ static int mtd_ioctl(struct file *file, u_int cmd, u_long arg)
|
||||
|
||||
case BLKPG:
|
||||
{
|
||||
ret = mtd_blkpg_ioctl(mtd,
|
||||
ret = mtdchar_blkpg_ioctl(mtd,
|
||||
(struct blkpg_ioctl_arg __user *)arg);
|
||||
break;
|
||||
}
|
||||
@ -1033,12 +1012,12 @@ static int mtd_ioctl(struct file *file, u_int cmd, u_long arg)
|
||||
return ret;
|
||||
} /* memory_ioctl */
|
||||
|
||||
static long mtd_unlocked_ioctl(struct file *file, u_int cmd, u_long arg)
|
||||
static long mtdchar_unlocked_ioctl(struct file *file, u_int cmd, u_long arg)
|
||||
{
|
||||
int ret;
|
||||
|
||||
mutex_lock(&mtd_mutex);
|
||||
ret = mtd_ioctl(file, cmd, arg);
|
||||
ret = mtdchar_ioctl(file, cmd, arg);
|
||||
mutex_unlock(&mtd_mutex);
|
||||
|
||||
return ret;
|
||||
@ -1055,7 +1034,7 @@ struct mtd_oob_buf32 {
|
||||
#define MEMWRITEOOB32 _IOWR('M', 3, struct mtd_oob_buf32)
|
||||
#define MEMREADOOB32 _IOWR('M', 4, struct mtd_oob_buf32)
|
||||
|
||||
static long mtd_compat_ioctl(struct file *file, unsigned int cmd,
|
||||
static long mtdchar_compat_ioctl(struct file *file, unsigned int cmd,
|
||||
unsigned long arg)
|
||||
{
|
||||
struct mtd_file_info *mfi = file->private_data;
|
||||
@ -1074,7 +1053,7 @@ static long mtd_compat_ioctl(struct file *file, unsigned int cmd,
|
||||
if (copy_from_user(&buf, argp, sizeof(buf)))
|
||||
ret = -EFAULT;
|
||||
else
|
||||
ret = mtd_do_writeoob(file, mtd, buf.start,
|
||||
ret = mtdchar_writeoob(file, mtd, buf.start,
|
||||
buf.length, compat_ptr(buf.ptr),
|
||||
&buf_user->length);
|
||||
break;
|
||||
@ -1089,13 +1068,13 @@ static long mtd_compat_ioctl(struct file *file, unsigned int cmd,
|
||||
if (copy_from_user(&buf, argp, sizeof(buf)))
|
||||
ret = -EFAULT;
|
||||
else
|
||||
ret = mtd_do_readoob(file, mtd, buf.start,
|
||||
ret = mtdchar_readoob(file, mtd, buf.start,
|
||||
buf.length, compat_ptr(buf.ptr),
|
||||
&buf_user->start);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
ret = mtd_ioctl(file, cmd, (unsigned long)argp);
|
||||
ret = mtdchar_ioctl(file, cmd, (unsigned long)argp);
|
||||
}
|
||||
|
||||
mutex_unlock(&mtd_mutex);
|
||||
@ -1111,7 +1090,7 @@ static long mtd_compat_ioctl(struct file *file, unsigned int cmd,
|
||||
* mappings)
|
||||
*/
|
||||
#ifndef CONFIG_MMU
|
||||
static unsigned long mtd_get_unmapped_area(struct file *file,
|
||||
static unsigned long mtdchar_get_unmapped_area(struct file *file,
|
||||
unsigned long addr,
|
||||
unsigned long len,
|
||||
unsigned long pgoff,
|
||||
@ -1119,32 +1098,28 @@ static unsigned long mtd_get_unmapped_area(struct file *file,
|
||||
{
|
||||
struct mtd_file_info *mfi = file->private_data;
|
||||
struct mtd_info *mtd = mfi->mtd;
|
||||
unsigned long offset;
|
||||
int ret;
|
||||
|
||||
if (mtd->get_unmapped_area) {
|
||||
unsigned long offset;
|
||||
if (addr != 0)
|
||||
return (unsigned long) -EINVAL;
|
||||
|
||||
if (addr != 0)
|
||||
return (unsigned long) -EINVAL;
|
||||
if (len > mtd->size || pgoff >= (mtd->size >> PAGE_SHIFT))
|
||||
return (unsigned long) -EINVAL;
|
||||
|
||||
if (len > mtd->size || pgoff >= (mtd->size >> PAGE_SHIFT))
|
||||
return (unsigned long) -EINVAL;
|
||||
offset = pgoff << PAGE_SHIFT;
|
||||
if (offset > mtd->size - len)
|
||||
return (unsigned long) -EINVAL;
|
||||
|
||||
offset = pgoff << PAGE_SHIFT;
|
||||
if (offset > mtd->size - len)
|
||||
return (unsigned long) -EINVAL;
|
||||
|
||||
return mtd->get_unmapped_area(mtd, len, offset, flags);
|
||||
}
|
||||
|
||||
/* can't map directly */
|
||||
return (unsigned long) -ENOSYS;
|
||||
ret = mtd_get_unmapped_area(mtd, len, offset, flags);
|
||||
return ret == -EOPNOTSUPP ? -ENOSYS : ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* set up a mapping for shared memory segments
|
||||
*/
|
||||
static int mtd_mmap(struct file *file, struct vm_area_struct *vma)
|
||||
static int mtdchar_mmap(struct file *file, struct vm_area_struct *vma)
|
||||
{
|
||||
#ifdef CONFIG_MMU
|
||||
struct mtd_file_info *mfi = file->private_data;
|
||||
@ -1185,18 +1160,18 @@ static int mtd_mmap(struct file *file, struct vm_area_struct *vma)
|
||||
|
||||
static const struct file_operations mtd_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.llseek = mtd_lseek,
|
||||
.read = mtd_read,
|
||||
.write = mtd_write,
|
||||
.unlocked_ioctl = mtd_unlocked_ioctl,
|
||||
.llseek = mtdchar_lseek,
|
||||
.read = mtdchar_read,
|
||||
.write = mtdchar_write,
|
||||
.unlocked_ioctl = mtdchar_unlocked_ioctl,
|
||||
#ifdef CONFIG_COMPAT
|
||||
.compat_ioctl = mtd_compat_ioctl,
|
||||
.compat_ioctl = mtdchar_compat_ioctl,
|
||||
#endif
|
||||
.open = mtd_open,
|
||||
.release = mtd_close,
|
||||
.mmap = mtd_mmap,
|
||||
.open = mtdchar_open,
|
||||
.release = mtdchar_close,
|
||||
.mmap = mtdchar_mmap,
|
||||
#ifndef CONFIG_MMU
|
||||
.get_unmapped_area = mtd_get_unmapped_area,
|
||||
.get_unmapped_area = mtdchar_get_unmapped_area,
|
||||
#endif
|
||||
};
|
||||
|
||||
|
@ -91,7 +91,7 @@ concat_read(struct mtd_info *mtd, loff_t from, size_t len,
|
||||
/* Entire transaction goes into this subdev */
|
||||
size = len;
|
||||
|
||||
err = subdev->read(subdev, from, size, &retsize, buf);
|
||||
err = mtd_read(subdev, from, size, &retsize, buf);
|
||||
|
||||
/* Save information about bitflips! */
|
||||
if (unlikely(err)) {
|
||||
@ -148,7 +148,7 @@ concat_write(struct mtd_info *mtd, loff_t to, size_t len,
|
||||
if (!(subdev->flags & MTD_WRITEABLE))
|
||||
err = -EROFS;
|
||||
else
|
||||
err = subdev->write(subdev, to, size, &retsize, buf);
|
||||
err = mtd_write(subdev, to, size, &retsize, buf);
|
||||
|
||||
if (err)
|
||||
break;
|
||||
@ -227,8 +227,9 @@ concat_writev(struct mtd_info *mtd, const struct kvec *vecs,
|
||||
if (!(subdev->flags & MTD_WRITEABLE))
|
||||
err = -EROFS;
|
||||
else
|
||||
err = subdev->writev(subdev, &vecs_copy[entry_low],
|
||||
entry_high - entry_low + 1, to, &retsize);
|
||||
err = mtd_writev(subdev, &vecs_copy[entry_low],
|
||||
entry_high - entry_low + 1, to,
|
||||
&retsize);
|
||||
|
||||
vecs_copy[entry_high].iov_len = old_iov_len - size;
|
||||
vecs_copy[entry_high].iov_base += size;
|
||||
@ -273,7 +274,7 @@ concat_read_oob(struct mtd_info *mtd, loff_t from, struct mtd_oob_ops *ops)
|
||||
if (from + devops.len > subdev->size)
|
||||
devops.len = subdev->size - from;
|
||||
|
||||
err = subdev->read_oob(subdev, from, &devops);
|
||||
err = mtd_read_oob(subdev, from, &devops);
|
||||
ops->retlen += devops.retlen;
|
||||
ops->oobretlen += devops.oobretlen;
|
||||
|
||||
@ -333,7 +334,7 @@ concat_write_oob(struct mtd_info *mtd, loff_t to, struct mtd_oob_ops *ops)
|
||||
if (to + devops.len > subdev->size)
|
||||
devops.len = subdev->size - to;
|
||||
|
||||
err = subdev->write_oob(subdev, to, &devops);
|
||||
err = mtd_write_oob(subdev, to, &devops);
|
||||
ops->retlen += devops.oobretlen;
|
||||
if (err)
|
||||
return err;
|
||||
@ -379,7 +380,7 @@ static int concat_dev_erase(struct mtd_info *mtd, struct erase_info *erase)
|
||||
* FIXME: Allow INTERRUPTIBLE. Which means
|
||||
* not having the wait_queue head on the stack.
|
||||
*/
|
||||
err = mtd->erase(mtd, erase);
|
||||
err = mtd_erase(mtd, erase);
|
||||
if (!err) {
|
||||
set_current_state(TASK_UNINTERRUPTIBLE);
|
||||
add_wait_queue(&waitq, &wait);
|
||||
@ -554,12 +555,9 @@ static int concat_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
|
||||
else
|
||||
size = len;
|
||||
|
||||
if (subdev->lock) {
|
||||
err = subdev->lock(subdev, ofs, size);
|
||||
if (err)
|
||||
break;
|
||||
} else
|
||||
err = -EOPNOTSUPP;
|
||||
err = mtd_lock(subdev, ofs, size);
|
||||
if (err)
|
||||
break;
|
||||
|
||||
len -= size;
|
||||
if (len == 0)
|
||||
@ -594,12 +592,9 @@ static int concat_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
|
||||
else
|
||||
size = len;
|
||||
|
||||
if (subdev->unlock) {
|
||||
err = subdev->unlock(subdev, ofs, size);
|
||||
if (err)
|
||||
break;
|
||||
} else
|
||||
err = -EOPNOTSUPP;
|
||||
err = mtd_unlock(subdev, ofs, size);
|
||||
if (err)
|
||||
break;
|
||||
|
||||
len -= size;
|
||||
if (len == 0)
|
||||
@ -619,7 +614,7 @@ static void concat_sync(struct mtd_info *mtd)
|
||||
|
||||
for (i = 0; i < concat->num_subdev; i++) {
|
||||
struct mtd_info *subdev = concat->subdev[i];
|
||||
subdev->sync(subdev);
|
||||
mtd_sync(subdev);
|
||||
}
|
||||
}
|
||||
|
||||
@ -630,7 +625,7 @@ static int concat_suspend(struct mtd_info *mtd)
|
||||
|
||||
for (i = 0; i < concat->num_subdev; i++) {
|
||||
struct mtd_info *subdev = concat->subdev[i];
|
||||
if ((rc = subdev->suspend(subdev)) < 0)
|
||||
if ((rc = mtd_suspend(subdev)) < 0)
|
||||
return rc;
|
||||
}
|
||||
return rc;
|
||||
@ -643,7 +638,7 @@ static void concat_resume(struct mtd_info *mtd)
|
||||
|
||||
for (i = 0; i < concat->num_subdev; i++) {
|
||||
struct mtd_info *subdev = concat->subdev[i];
|
||||
subdev->resume(subdev);
|
||||
mtd_resume(subdev);
|
||||
}
|
||||
}
|
||||
|
||||
@ -652,7 +647,7 @@ static int concat_block_isbad(struct mtd_info *mtd, loff_t ofs)
|
||||
struct mtd_concat *concat = CONCAT(mtd);
|
||||
int i, res = 0;
|
||||
|
||||
if (!concat->subdev[0]->block_isbad)
|
||||
if (!mtd_can_have_bb(concat->subdev[0]))
|
||||
return res;
|
||||
|
||||
if (ofs > mtd->size)
|
||||
@ -666,7 +661,7 @@ static int concat_block_isbad(struct mtd_info *mtd, loff_t ofs)
|
||||
continue;
|
||||
}
|
||||
|
||||
res = subdev->block_isbad(subdev, ofs);
|
||||
res = mtd_block_isbad(subdev, ofs);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -678,7 +673,7 @@ static int concat_block_markbad(struct mtd_info *mtd, loff_t ofs)
|
||||
struct mtd_concat *concat = CONCAT(mtd);
|
||||
int i, err = -EINVAL;
|
||||
|
||||
if (!concat->subdev[0]->block_markbad)
|
||||
if (!mtd_can_have_bb(concat->subdev[0]))
|
||||
return 0;
|
||||
|
||||
if (ofs > mtd->size)
|
||||
@ -692,7 +687,7 @@ static int concat_block_markbad(struct mtd_info *mtd, loff_t ofs)
|
||||
continue;
|
||||
}
|
||||
|
||||
err = subdev->block_markbad(subdev, ofs);
|
||||
err = mtd_block_markbad(subdev, ofs);
|
||||
if (!err)
|
||||
mtd->ecc_stats.badblocks++;
|
||||
break;
|
||||
@ -725,11 +720,7 @@ static unsigned long concat_get_unmapped_area(struct mtd_info *mtd,
|
||||
if (offset + len > subdev->size)
|
||||
return (unsigned long) -EINVAL;
|
||||
|
||||
if (subdev->get_unmapped_area)
|
||||
return subdev->get_unmapped_area(subdev, len, offset,
|
||||
flags);
|
||||
|
||||
break;
|
||||
return mtd_get_unmapped_area(subdev, len, offset, flags);
|
||||
}
|
||||
|
||||
return (unsigned long) -ENOSYS;
|
||||
|
@ -107,7 +107,8 @@ static LIST_HEAD(mtd_notifiers);
|
||||
*/
|
||||
static void mtd_release(struct device *dev)
|
||||
{
|
||||
dev_t index = MTD_DEVT(dev_to_mtd(dev)->index);
|
||||
struct mtd_info *mtd = dev_get_drvdata(dev);
|
||||
dev_t index = MTD_DEVT(mtd->index);
|
||||
|
||||
/* remove /dev/mtdXro node if needed */
|
||||
if (index)
|
||||
@ -116,27 +117,24 @@ static void mtd_release(struct device *dev)
|
||||
|
||||
static int mtd_cls_suspend(struct device *dev, pm_message_t state)
|
||||
{
|
||||
struct mtd_info *mtd = dev_to_mtd(dev);
|
||||
struct mtd_info *mtd = dev_get_drvdata(dev);
|
||||
|
||||
if (mtd && mtd->suspend)
|
||||
return mtd->suspend(mtd);
|
||||
else
|
||||
return 0;
|
||||
return mtd_suspend(mtd);
|
||||
}
|
||||
|
||||
static int mtd_cls_resume(struct device *dev)
|
||||
{
|
||||
struct mtd_info *mtd = dev_to_mtd(dev);
|
||||
|
||||
struct mtd_info *mtd = dev_get_drvdata(dev);
|
||||
|
||||
if (mtd && mtd->resume)
|
||||
mtd->resume(mtd);
|
||||
mtd_resume(mtd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ssize_t mtd_type_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct mtd_info *mtd = dev_to_mtd(dev);
|
||||
struct mtd_info *mtd = dev_get_drvdata(dev);
|
||||
char *type;
|
||||
|
||||
switch (mtd->type) {
|
||||
@ -172,7 +170,7 @@ static DEVICE_ATTR(type, S_IRUGO, mtd_type_show, NULL);
|
||||
static ssize_t mtd_flags_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct mtd_info *mtd = dev_to_mtd(dev);
|
||||
struct mtd_info *mtd = dev_get_drvdata(dev);
|
||||
|
||||
return snprintf(buf, PAGE_SIZE, "0x%lx\n", (unsigned long)mtd->flags);
|
||||
|
||||
@ -182,7 +180,7 @@ static DEVICE_ATTR(flags, S_IRUGO, mtd_flags_show, NULL);
|
||||
static ssize_t mtd_size_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct mtd_info *mtd = dev_to_mtd(dev);
|
||||
struct mtd_info *mtd = dev_get_drvdata(dev);
|
||||
|
||||
return snprintf(buf, PAGE_SIZE, "%llu\n",
|
||||
(unsigned long long)mtd->size);
|
||||
@ -193,7 +191,7 @@ static DEVICE_ATTR(size, S_IRUGO, mtd_size_show, NULL);
|
||||
static ssize_t mtd_erasesize_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct mtd_info *mtd = dev_to_mtd(dev);
|
||||
struct mtd_info *mtd = dev_get_drvdata(dev);
|
||||
|
||||
return snprintf(buf, PAGE_SIZE, "%lu\n", (unsigned long)mtd->erasesize);
|
||||
|
||||
@ -203,7 +201,7 @@ static DEVICE_ATTR(erasesize, S_IRUGO, mtd_erasesize_show, NULL);
|
||||
static ssize_t mtd_writesize_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct mtd_info *mtd = dev_to_mtd(dev);
|
||||
struct mtd_info *mtd = dev_get_drvdata(dev);
|
||||
|
||||
return snprintf(buf, PAGE_SIZE, "%lu\n", (unsigned long)mtd->writesize);
|
||||
|
||||
@ -213,7 +211,7 @@ static DEVICE_ATTR(writesize, S_IRUGO, mtd_writesize_show, NULL);
|
||||
static ssize_t mtd_subpagesize_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct mtd_info *mtd = dev_to_mtd(dev);
|
||||
struct mtd_info *mtd = dev_get_drvdata(dev);
|
||||
unsigned int subpagesize = mtd->writesize >> mtd->subpage_sft;
|
||||
|
||||
return snprintf(buf, PAGE_SIZE, "%u\n", subpagesize);
|
||||
@ -224,7 +222,7 @@ static DEVICE_ATTR(subpagesize, S_IRUGO, mtd_subpagesize_show, NULL);
|
||||
static ssize_t mtd_oobsize_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct mtd_info *mtd = dev_to_mtd(dev);
|
||||
struct mtd_info *mtd = dev_get_drvdata(dev);
|
||||
|
||||
return snprintf(buf, PAGE_SIZE, "%lu\n", (unsigned long)mtd->oobsize);
|
||||
|
||||
@ -234,7 +232,7 @@ static DEVICE_ATTR(oobsize, S_IRUGO, mtd_oobsize_show, NULL);
|
||||
static ssize_t mtd_numeraseregions_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct mtd_info *mtd = dev_to_mtd(dev);
|
||||
struct mtd_info *mtd = dev_get_drvdata(dev);
|
||||
|
||||
return snprintf(buf, PAGE_SIZE, "%u\n", mtd->numeraseregions);
|
||||
|
||||
@ -245,7 +243,7 @@ static DEVICE_ATTR(numeraseregions, S_IRUGO, mtd_numeraseregions_show,
|
||||
static ssize_t mtd_name_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct mtd_info *mtd = dev_to_mtd(dev);
|
||||
struct mtd_info *mtd = dev_get_drvdata(dev);
|
||||
|
||||
return snprintf(buf, PAGE_SIZE, "%s\n", mtd->name);
|
||||
|
||||
@ -338,9 +336,9 @@ int add_mtd_device(struct mtd_info *mtd)
|
||||
mtd->writesize_mask = (1 << mtd->writesize_shift) - 1;
|
||||
|
||||
/* Some chips always power up locked. Unlock them now */
|
||||
if ((mtd->flags & MTD_WRITEABLE)
|
||||
&& (mtd->flags & MTD_POWERUP_LOCK) && mtd->unlock) {
|
||||
if (mtd->unlock(mtd, 0, mtd->size))
|
||||
if ((mtd->flags & MTD_WRITEABLE) && (mtd->flags & MTD_POWERUP_LOCK)) {
|
||||
error = mtd_unlock(mtd, 0, mtd->size);
|
||||
if (error && error != -EOPNOTSUPP)
|
||||
printk(KERN_WARNING
|
||||
"%s: unlock failed, writes may not work\n",
|
||||
mtd->name);
|
||||
@ -516,7 +514,6 @@ EXPORT_SYMBOL_GPL(mtd_device_unregister);
|
||||
* or removal of MTD devices. Causes the 'add' callback to be immediately
|
||||
* invoked for each MTD device currently present in the system.
|
||||
*/
|
||||
|
||||
void register_mtd_user (struct mtd_notifier *new)
|
||||
{
|
||||
struct mtd_info *mtd;
|
||||
@ -532,6 +529,7 @@ void register_mtd_user (struct mtd_notifier *new)
|
||||
|
||||
mutex_unlock(&mtd_table_mutex);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(register_mtd_user);
|
||||
|
||||
/**
|
||||
* unregister_mtd_user - unregister a 'user' of MTD devices.
|
||||
@ -542,7 +540,6 @@ void register_mtd_user (struct mtd_notifier *new)
|
||||
* 'remove' callback to be immediately invoked for each MTD device
|
||||
* currently present in the system.
|
||||
*/
|
||||
|
||||
int unregister_mtd_user (struct mtd_notifier *old)
|
||||
{
|
||||
struct mtd_info *mtd;
|
||||
@ -558,7 +555,7 @@ int unregister_mtd_user (struct mtd_notifier *old)
|
||||
mutex_unlock(&mtd_table_mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL_GPL(unregister_mtd_user);
|
||||
|
||||
/**
|
||||
* get_mtd_device - obtain a validated handle for an MTD device
|
||||
@ -571,7 +568,6 @@ int unregister_mtd_user (struct mtd_notifier *old)
|
||||
* both, return the num'th driver only if its address matches. Return
|
||||
* error code if not.
|
||||
*/
|
||||
|
||||
struct mtd_info *get_mtd_device(struct mtd_info *mtd, int num)
|
||||
{
|
||||
struct mtd_info *ret = NULL, *other;
|
||||
@ -604,6 +600,7 @@ out:
|
||||
mutex_unlock(&mtd_table_mutex);
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(get_mtd_device);
|
||||
|
||||
|
||||
int __get_mtd_device(struct mtd_info *mtd)
|
||||
@ -624,6 +621,7 @@ int __get_mtd_device(struct mtd_info *mtd)
|
||||
mtd->usecount++;
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(__get_mtd_device);
|
||||
|
||||
/**
|
||||
* get_mtd_device_nm - obtain a validated handle for an MTD device by
|
||||
@ -633,7 +631,6 @@ int __get_mtd_device(struct mtd_info *mtd)
|
||||
* This function returns MTD device description structure in case of
|
||||
* success and an error code in case of failure.
|
||||
*/
|
||||
|
||||
struct mtd_info *get_mtd_device_nm(const char *name)
|
||||
{
|
||||
int err = -ENODEV;
|
||||
@ -662,6 +659,7 @@ out_unlock:
|
||||
mutex_unlock(&mtd_table_mutex);
|
||||
return ERR_PTR(err);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(get_mtd_device_nm);
|
||||
|
||||
void put_mtd_device(struct mtd_info *mtd)
|
||||
{
|
||||
@ -670,6 +668,7 @@ void put_mtd_device(struct mtd_info *mtd)
|
||||
mutex_unlock(&mtd_table_mutex);
|
||||
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(put_mtd_device);
|
||||
|
||||
void __put_mtd_device(struct mtd_info *mtd)
|
||||
{
|
||||
@ -681,39 +680,65 @@ void __put_mtd_device(struct mtd_info *mtd)
|
||||
|
||||
module_put(mtd->owner);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(__put_mtd_device);
|
||||
|
||||
/* default_mtd_writev - default mtd writev method for MTD devices that
|
||||
* don't implement their own
|
||||
/*
|
||||
* default_mtd_writev - the default writev method
|
||||
* @mtd: mtd device description object pointer
|
||||
* @vecs: the vectors to write
|
||||
* @count: count of vectors in @vecs
|
||||
* @to: the MTD device offset to write to
|
||||
* @retlen: on exit contains the count of bytes written to the MTD device.
|
||||
*
|
||||
* This function returns zero in case of success and a negative error code in
|
||||
* case of failure.
|
||||
*/
|
||||
|
||||
int default_mtd_writev(struct mtd_info *mtd, const struct kvec *vecs,
|
||||
unsigned long count, loff_t to, size_t *retlen)
|
||||
static int default_mtd_writev(struct mtd_info *mtd, const struct kvec *vecs,
|
||||
unsigned long count, loff_t to, size_t *retlen)
|
||||
{
|
||||
unsigned long i;
|
||||
size_t totlen = 0, thislen;
|
||||
int ret = 0;
|
||||
|
||||
if(!mtd->write) {
|
||||
ret = -EROFS;
|
||||
} else {
|
||||
for (i=0; i<count; i++) {
|
||||
if (!vecs[i].iov_len)
|
||||
continue;
|
||||
ret = mtd->write(mtd, to, vecs[i].iov_len, &thislen, vecs[i].iov_base);
|
||||
totlen += thislen;
|
||||
if (ret || thislen != vecs[i].iov_len)
|
||||
break;
|
||||
to += vecs[i].iov_len;
|
||||
}
|
||||
for (i = 0; i < count; i++) {
|
||||
if (!vecs[i].iov_len)
|
||||
continue;
|
||||
ret = mtd_write(mtd, to, vecs[i].iov_len, &thislen,
|
||||
vecs[i].iov_base);
|
||||
totlen += thislen;
|
||||
if (ret || thislen != vecs[i].iov_len)
|
||||
break;
|
||||
to += vecs[i].iov_len;
|
||||
}
|
||||
if (retlen)
|
||||
*retlen = totlen;
|
||||
*retlen = totlen;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* mtd_writev - the vector-based MTD write method
|
||||
* @mtd: mtd device description object pointer
|
||||
* @vecs: the vectors to write
|
||||
* @count: count of vectors in @vecs
|
||||
* @to: the MTD device offset to write to
|
||||
* @retlen: on exit contains the count of bytes written to the MTD device.
|
||||
*
|
||||
* This function returns zero in case of success and a negative error code in
|
||||
* case of failure.
|
||||
*/
|
||||
int mtd_writev(struct mtd_info *mtd, const struct kvec *vecs,
|
||||
unsigned long count, loff_t to, size_t *retlen)
|
||||
{
|
||||
*retlen = 0;
|
||||
if (!mtd->writev)
|
||||
return default_mtd_writev(mtd, vecs, count, to, retlen);
|
||||
return mtd->writev(mtd, vecs, count, to, retlen);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mtd_writev);
|
||||
|
||||
/**
|
||||
* mtd_kmalloc_up_to - allocate a contiguous buffer up to the specified size
|
||||
* @size: A pointer to the ideal or maximum size of the allocation. Points
|
||||
* @mtd: mtd device description object pointer
|
||||
* @size: a pointer to the ideal or maximum size of the allocation, points
|
||||
* to the actual allocation size on success.
|
||||
*
|
||||
* This routine attempts to allocate a contiguous kernel buffer up to
|
||||
@ -758,15 +783,6 @@ void *mtd_kmalloc_up_to(const struct mtd_info *mtd, size_t *size)
|
||||
*/
|
||||
return kmalloc(*size, GFP_KERNEL);
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL_GPL(get_mtd_device);
|
||||
EXPORT_SYMBOL_GPL(get_mtd_device_nm);
|
||||
EXPORT_SYMBOL_GPL(__get_mtd_device);
|
||||
EXPORT_SYMBOL_GPL(put_mtd_device);
|
||||
EXPORT_SYMBOL_GPL(__put_mtd_device);
|
||||
EXPORT_SYMBOL_GPL(register_mtd_user);
|
||||
EXPORT_SYMBOL_GPL(unregister_mtd_user);
|
||||
EXPORT_SYMBOL_GPL(default_mtd_writev);
|
||||
EXPORT_SYMBOL_GPL(mtd_kmalloc_up_to);
|
||||
|
||||
#ifdef CONFIG_PROC_FS
|
||||
|
@ -112,7 +112,7 @@ static int mtdoops_erase_block(struct mtdoops_context *cxt, int offset)
|
||||
set_current_state(TASK_INTERRUPTIBLE);
|
||||
add_wait_queue(&wait_q, &wait);
|
||||
|
||||
ret = mtd->erase(mtd, &erase);
|
||||
ret = mtd_erase(mtd, &erase);
|
||||
if (ret) {
|
||||
set_current_state(TASK_RUNNING);
|
||||
remove_wait_queue(&wait_q, &wait);
|
||||
@ -169,8 +169,8 @@ static void mtdoops_workfunc_erase(struct work_struct *work)
|
||||
cxt->nextpage = 0;
|
||||
}
|
||||
|
||||
while (mtd->block_isbad) {
|
||||
ret = mtd->block_isbad(mtd, cxt->nextpage * record_size);
|
||||
while (mtd_can_have_bb(mtd)) {
|
||||
ret = mtd_block_isbad(mtd, cxt->nextpage * record_size);
|
||||
if (!ret)
|
||||
break;
|
||||
if (ret < 0) {
|
||||
@ -199,8 +199,8 @@ badblock:
|
||||
return;
|
||||
}
|
||||
|
||||
if (mtd->block_markbad && ret == -EIO) {
|
||||
ret = mtd->block_markbad(mtd, cxt->nextpage * record_size);
|
||||
if (mtd_can_have_bb(mtd) && ret == -EIO) {
|
||||
ret = mtd_block_markbad(mtd, cxt->nextpage * record_size);
|
||||
if (ret < 0) {
|
||||
printk(KERN_ERR "mtdoops: block_markbad failed, aborting\n");
|
||||
return;
|
||||
@ -221,12 +221,16 @@ static void mtdoops_write(struct mtdoops_context *cxt, int panic)
|
||||
hdr[0] = cxt->nextcount;
|
||||
hdr[1] = MTDOOPS_KERNMSG_MAGIC;
|
||||
|
||||
if (panic)
|
||||
ret = mtd->panic_write(mtd, cxt->nextpage * record_size,
|
||||
record_size, &retlen, cxt->oops_buf);
|
||||
else
|
||||
ret = mtd->write(mtd, cxt->nextpage * record_size,
|
||||
record_size, &retlen, cxt->oops_buf);
|
||||
if (panic) {
|
||||
ret = mtd_panic_write(mtd, cxt->nextpage * record_size,
|
||||
record_size, &retlen, cxt->oops_buf);
|
||||
if (ret == -EOPNOTSUPP) {
|
||||
printk(KERN_ERR "mtdoops: Cannot write from panic without panic_write\n");
|
||||
return;
|
||||
}
|
||||
} else
|
||||
ret = mtd_write(mtd, cxt->nextpage * record_size,
|
||||
record_size, &retlen, cxt->oops_buf);
|
||||
|
||||
if (retlen != record_size || ret < 0)
|
||||
printk(KERN_ERR "mtdoops: write failure at %ld (%td of %ld written), error %d\n",
|
||||
@ -253,10 +257,13 @@ static void find_next_position(struct mtdoops_context *cxt)
|
||||
size_t retlen;
|
||||
|
||||
for (page = 0; page < cxt->oops_pages; page++) {
|
||||
if (mtd_can_have_bb(mtd) &&
|
||||
mtd_block_isbad(mtd, page * record_size))
|
||||
continue;
|
||||
/* Assume the page is used */
|
||||
mark_page_used(cxt, page);
|
||||
ret = mtd->read(mtd, page * record_size, MTDOOPS_HEADER_SIZE,
|
||||
&retlen, (u_char *) &count[0]);
|
||||
ret = mtd_read(mtd, page * record_size, MTDOOPS_HEADER_SIZE,
|
||||
&retlen, (u_char *)&count[0]);
|
||||
if (retlen != MTDOOPS_HEADER_SIZE ||
|
||||
(ret < 0 && !mtd_is_bitflip(ret))) {
|
||||
printk(KERN_ERR "mtdoops: read failure at %ld (%td of %d read), err %d\n",
|
||||
@ -327,13 +334,8 @@ static void mtdoops_do_dump(struct kmsg_dumper *dumper,
|
||||
memcpy(dst + l1_cpy, s2 + s2_start, l2_cpy);
|
||||
|
||||
/* Panics must be written immediately */
|
||||
if (reason != KMSG_DUMP_OOPS) {
|
||||
if (!cxt->mtd->panic_write)
|
||||
printk(KERN_ERR "mtdoops: Cannot write from panic without panic_write\n");
|
||||
else
|
||||
mtdoops_write(cxt, 1);
|
||||
return;
|
||||
}
|
||||
if (reason != KMSG_DUMP_OOPS)
|
||||
mtdoops_write(cxt, 1);
|
||||
|
||||
/* For other cases, schedule work to write it "nicely" */
|
||||
schedule_work(&cxt->work_write);
|
||||
@ -369,7 +371,7 @@ static void mtdoops_notify_add(struct mtd_info *mtd)
|
||||
|
||||
/* oops_page_used is a bit field */
|
||||
cxt->oops_page_used = vmalloc(DIV_ROUND_UP(mtdoops_pages,
|
||||
BITS_PER_LONG));
|
||||
BITS_PER_LONG) * sizeof(unsigned long));
|
||||
if (!cxt->oops_page_used) {
|
||||
printk(KERN_ERR "mtdoops: could not allocate page array\n");
|
||||
return;
|
||||
|
@ -70,8 +70,7 @@ static int part_read(struct mtd_info *mtd, loff_t from, size_t len,
|
||||
len = 0;
|
||||
else if (from + len > mtd->size)
|
||||
len = mtd->size - from;
|
||||
res = part->master->read(part->master, from + part->offset,
|
||||
len, retlen, buf);
|
||||
res = mtd_read(part->master, from + part->offset, len, retlen, buf);
|
||||
if (unlikely(res)) {
|
||||
if (mtd_is_bitflip(res))
|
||||
mtd->ecc_stats.corrected += part->master->ecc_stats.corrected - stats.corrected;
|
||||
@ -89,15 +88,15 @@ static int part_point(struct mtd_info *mtd, loff_t from, size_t len,
|
||||
len = 0;
|
||||
else if (from + len > mtd->size)
|
||||
len = mtd->size - from;
|
||||
return part->master->point (part->master, from + part->offset,
|
||||
len, retlen, virt, phys);
|
||||
return mtd_point(part->master, from + part->offset, len, retlen,
|
||||
virt, phys);
|
||||
}
|
||||
|
||||
static void part_unpoint(struct mtd_info *mtd, loff_t from, size_t len)
|
||||
{
|
||||
struct mtd_part *part = PART(mtd);
|
||||
|
||||
part->master->unpoint(part->master, from + part->offset, len);
|
||||
mtd_unpoint(part->master, from + part->offset, len);
|
||||
}
|
||||
|
||||
static unsigned long part_get_unmapped_area(struct mtd_info *mtd,
|
||||
@ -108,8 +107,7 @@ static unsigned long part_get_unmapped_area(struct mtd_info *mtd,
|
||||
struct mtd_part *part = PART(mtd);
|
||||
|
||||
offset += part->offset;
|
||||
return part->master->get_unmapped_area(part->master, len, offset,
|
||||
flags);
|
||||
return mtd_get_unmapped_area(part->master, len, offset, flags);
|
||||
}
|
||||
|
||||
static int part_read_oob(struct mtd_info *mtd, loff_t from,
|
||||
@ -140,7 +138,7 @@ static int part_read_oob(struct mtd_info *mtd, loff_t from,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
res = part->master->read_oob(part->master, from + part->offset, ops);
|
||||
res = mtd_read_oob(part->master, from + part->offset, ops);
|
||||
if (unlikely(res)) {
|
||||
if (mtd_is_bitflip(res))
|
||||
mtd->ecc_stats.corrected++;
|
||||
@ -154,30 +152,28 @@ static int part_read_user_prot_reg(struct mtd_info *mtd, loff_t from,
|
||||
size_t len, size_t *retlen, u_char *buf)
|
||||
{
|
||||
struct mtd_part *part = PART(mtd);
|
||||
return part->master->read_user_prot_reg(part->master, from,
|
||||
len, retlen, buf);
|
||||
return mtd_read_user_prot_reg(part->master, from, len, retlen, buf);
|
||||
}
|
||||
|
||||
static int part_get_user_prot_info(struct mtd_info *mtd,
|
||||
struct otp_info *buf, size_t len)
|
||||
{
|
||||
struct mtd_part *part = PART(mtd);
|
||||
return part->master->get_user_prot_info(part->master, buf, len);
|
||||
return mtd_get_user_prot_info(part->master, buf, len);
|
||||
}
|
||||
|
||||
static int part_read_fact_prot_reg(struct mtd_info *mtd, loff_t from,
|
||||
size_t len, size_t *retlen, u_char *buf)
|
||||
{
|
||||
struct mtd_part *part = PART(mtd);
|
||||
return part->master->read_fact_prot_reg(part->master, from,
|
||||
len, retlen, buf);
|
||||
return mtd_read_fact_prot_reg(part->master, from, len, retlen, buf);
|
||||
}
|
||||
|
||||
static int part_get_fact_prot_info(struct mtd_info *mtd, struct otp_info *buf,
|
||||
size_t len)
|
||||
{
|
||||
struct mtd_part *part = PART(mtd);
|
||||
return part->master->get_fact_prot_info(part->master, buf, len);
|
||||
return mtd_get_fact_prot_info(part->master, buf, len);
|
||||
}
|
||||
|
||||
static int part_write(struct mtd_info *mtd, loff_t to, size_t len,
|
||||
@ -190,8 +186,7 @@ static int part_write(struct mtd_info *mtd, loff_t to, size_t len,
|
||||
len = 0;
|
||||
else if (to + len > mtd->size)
|
||||
len = mtd->size - to;
|
||||
return part->master->write(part->master, to + part->offset,
|
||||
len, retlen, buf);
|
||||
return mtd_write(part->master, to + part->offset, len, retlen, buf);
|
||||
}
|
||||
|
||||
static int part_panic_write(struct mtd_info *mtd, loff_t to, size_t len,
|
||||
@ -204,8 +199,8 @@ static int part_panic_write(struct mtd_info *mtd, loff_t to, size_t len,
|
||||
len = 0;
|
||||
else if (to + len > mtd->size)
|
||||
len = mtd->size - to;
|
||||
return part->master->panic_write(part->master, to + part->offset,
|
||||
len, retlen, buf);
|
||||
return mtd_panic_write(part->master, to + part->offset, len, retlen,
|
||||
buf);
|
||||
}
|
||||
|
||||
static int part_write_oob(struct mtd_info *mtd, loff_t to,
|
||||
@ -220,22 +215,21 @@ static int part_write_oob(struct mtd_info *mtd, loff_t to,
|
||||
return -EINVAL;
|
||||
if (ops->datbuf && to + ops->len > mtd->size)
|
||||
return -EINVAL;
|
||||
return part->master->write_oob(part->master, to + part->offset, ops);
|
||||
return mtd_write_oob(part->master, to + part->offset, ops);
|
||||
}
|
||||
|
||||
static int part_write_user_prot_reg(struct mtd_info *mtd, loff_t from,
|
||||
size_t len, size_t *retlen, u_char *buf)
|
||||
{
|
||||
struct mtd_part *part = PART(mtd);
|
||||
return part->master->write_user_prot_reg(part->master, from,
|
||||
len, retlen, buf);
|
||||
return mtd_write_user_prot_reg(part->master, from, len, retlen, buf);
|
||||
}
|
||||
|
||||
static int part_lock_user_prot_reg(struct mtd_info *mtd, loff_t from,
|
||||
size_t len)
|
||||
{
|
||||
struct mtd_part *part = PART(mtd);
|
||||
return part->master->lock_user_prot_reg(part->master, from, len);
|
||||
return mtd_lock_user_prot_reg(part->master, from, len);
|
||||
}
|
||||
|
||||
static int part_writev(struct mtd_info *mtd, const struct kvec *vecs,
|
||||
@ -244,8 +238,8 @@ static int part_writev(struct mtd_info *mtd, const struct kvec *vecs,
|
||||
struct mtd_part *part = PART(mtd);
|
||||
if (!(mtd->flags & MTD_WRITEABLE))
|
||||
return -EROFS;
|
||||
return part->master->writev(part->master, vecs, count,
|
||||
to + part->offset, retlen);
|
||||
return mtd_writev(part->master, vecs, count, to + part->offset,
|
||||
retlen);
|
||||
}
|
||||
|
||||
static int part_erase(struct mtd_info *mtd, struct erase_info *instr)
|
||||
@ -257,7 +251,7 @@ static int part_erase(struct mtd_info *mtd, struct erase_info *instr)
|
||||
if (instr->addr >= mtd->size)
|
||||
return -EINVAL;
|
||||
instr->addr += part->offset;
|
||||
ret = part->master->erase(part->master, instr);
|
||||
ret = mtd_erase(part->master, instr);
|
||||
if (ret) {
|
||||
if (instr->fail_addr != MTD_FAIL_ADDR_UNKNOWN)
|
||||
instr->fail_addr -= part->offset;
|
||||
@ -285,7 +279,7 @@ static int part_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
|
||||
struct mtd_part *part = PART(mtd);
|
||||
if ((len + ofs) > mtd->size)
|
||||
return -EINVAL;
|
||||
return part->master->lock(part->master, ofs + part->offset, len);
|
||||
return mtd_lock(part->master, ofs + part->offset, len);
|
||||
}
|
||||
|
||||
static int part_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
|
||||
@ -293,7 +287,7 @@ static int part_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
|
||||
struct mtd_part *part = PART(mtd);
|
||||
if ((len + ofs) > mtd->size)
|
||||
return -EINVAL;
|
||||
return part->master->unlock(part->master, ofs + part->offset, len);
|
||||
return mtd_unlock(part->master, ofs + part->offset, len);
|
||||
}
|
||||
|
||||
static int part_is_locked(struct mtd_info *mtd, loff_t ofs, uint64_t len)
|
||||
@ -301,25 +295,25 @@ static int part_is_locked(struct mtd_info *mtd, loff_t ofs, uint64_t len)
|
||||
struct mtd_part *part = PART(mtd);
|
||||
if ((len + ofs) > mtd->size)
|
||||
return -EINVAL;
|
||||
return part->master->is_locked(part->master, ofs + part->offset, len);
|
||||
return mtd_is_locked(part->master, ofs + part->offset, len);
|
||||
}
|
||||
|
||||
static void part_sync(struct mtd_info *mtd)
|
||||
{
|
||||
struct mtd_part *part = PART(mtd);
|
||||
part->master->sync(part->master);
|
||||
mtd_sync(part->master);
|
||||
}
|
||||
|
||||
static int part_suspend(struct mtd_info *mtd)
|
||||
{
|
||||
struct mtd_part *part = PART(mtd);
|
||||
return part->master->suspend(part->master);
|
||||
return mtd_suspend(part->master);
|
||||
}
|
||||
|
||||
static void part_resume(struct mtd_info *mtd)
|
||||
{
|
||||
struct mtd_part *part = PART(mtd);
|
||||
part->master->resume(part->master);
|
||||
mtd_resume(part->master);
|
||||
}
|
||||
|
||||
static int part_block_isbad(struct mtd_info *mtd, loff_t ofs)
|
||||
@ -328,7 +322,7 @@ static int part_block_isbad(struct mtd_info *mtd, loff_t ofs)
|
||||
if (ofs >= mtd->size)
|
||||
return -EINVAL;
|
||||
ofs += part->offset;
|
||||
return part->master->block_isbad(part->master, ofs);
|
||||
return mtd_block_isbad(part->master, ofs);
|
||||
}
|
||||
|
||||
static int part_block_markbad(struct mtd_info *mtd, loff_t ofs)
|
||||
@ -341,7 +335,7 @@ static int part_block_markbad(struct mtd_info *mtd, loff_t ofs)
|
||||
if (ofs >= mtd->size)
|
||||
return -EINVAL;
|
||||
ofs += part->offset;
|
||||
res = part->master->block_markbad(part->master, ofs);
|
||||
res = mtd_block_markbad(part->master, ofs);
|
||||
if (!res)
|
||||
mtd->ecc_stats.badblocks++;
|
||||
return res;
|
||||
@ -559,8 +553,7 @@ static struct mtd_part *allocate_partition(struct mtd_info *master,
|
||||
uint64_t offs = 0;
|
||||
|
||||
while (offs < slave->mtd.size) {
|
||||
if (master->block_isbad(master,
|
||||
offs + slave->offset))
|
||||
if (mtd_block_isbad(master, offs + slave->offset))
|
||||
slave->mtd.ecc_stats.badblocks++;
|
||||
offs += slave->mtd.erasesize;
|
||||
}
|
||||
|
@ -274,12 +274,12 @@ static int mtdswap_handle_badblock(struct mtdswap_dev *d, struct swap_eb *eb)
|
||||
eb->root = NULL;
|
||||
|
||||
/* badblocks not supported */
|
||||
if (!d->mtd->block_markbad)
|
||||
if (!mtd_can_have_bb(d->mtd))
|
||||
return 1;
|
||||
|
||||
offset = mtdswap_eb_offset(d, eb);
|
||||
dev_warn(d->dev, "Marking bad block at %08llx\n", offset);
|
||||
ret = d->mtd->block_markbad(d->mtd, offset);
|
||||
ret = mtd_block_markbad(d->mtd, offset);
|
||||
|
||||
if (ret) {
|
||||
dev_warn(d->dev, "Mark block bad failed for block at %08llx "
|
||||
@ -312,7 +312,7 @@ static int mtdswap_handle_write_error(struct mtdswap_dev *d, struct swap_eb *eb)
|
||||
static int mtdswap_read_oob(struct mtdswap_dev *d, loff_t from,
|
||||
struct mtd_oob_ops *ops)
|
||||
{
|
||||
int ret = d->mtd->read_oob(d->mtd, from, ops);
|
||||
int ret = mtd_read_oob(d->mtd, from, ops);
|
||||
|
||||
if (mtd_is_bitflip(ret))
|
||||
return ret;
|
||||
@ -343,7 +343,7 @@ static int mtdswap_read_markers(struct mtdswap_dev *d, struct swap_eb *eb)
|
||||
offset = mtdswap_eb_offset(d, eb);
|
||||
|
||||
/* Check first if the block is bad. */
|
||||
if (d->mtd->block_isbad && d->mtd->block_isbad(d->mtd, offset))
|
||||
if (mtd_can_have_bb(d->mtd) && mtd_block_isbad(d->mtd, offset))
|
||||
return MTDSWAP_SCANNED_BAD;
|
||||
|
||||
ops.ooblen = 2 * d->mtd->ecclayout->oobavail;
|
||||
@ -403,7 +403,7 @@ static int mtdswap_write_marker(struct mtdswap_dev *d, struct swap_eb *eb,
|
||||
offset = mtdswap_eb_offset(d, eb) + d->mtd->writesize;
|
||||
}
|
||||
|
||||
ret = d->mtd->write_oob(d->mtd, offset , &ops);
|
||||
ret = mtd_write_oob(d->mtd, offset, &ops);
|
||||
|
||||
if (ret) {
|
||||
dev_warn(d->dev, "Write OOB failed for block at %08llx "
|
||||
@ -567,7 +567,7 @@ retry:
|
||||
erase.len = mtd->erasesize;
|
||||
erase.priv = (u_long)&wq;
|
||||
|
||||
ret = mtd->erase(mtd, &erase);
|
||||
ret = mtd_erase(mtd, &erase);
|
||||
if (ret) {
|
||||
if (retries++ < MTDSWAP_ERASE_RETRIES) {
|
||||
dev_warn(d->dev,
|
||||
@ -689,7 +689,7 @@ retry:
|
||||
return ret;
|
||||
|
||||
writepos = (loff_t)*bp << PAGE_SHIFT;
|
||||
ret = mtd->write(mtd, writepos, PAGE_SIZE, &retlen, buf);
|
||||
ret = mtd_write(mtd, writepos, PAGE_SIZE, &retlen, buf);
|
||||
if (ret == -EIO || mtd_is_eccerr(ret)) {
|
||||
d->curr_write_pos--;
|
||||
eb->active_count--;
|
||||
@ -736,7 +736,7 @@ static int mtdswap_move_block(struct mtdswap_dev *d, unsigned int oldblock,
|
||||
retries = 0;
|
||||
|
||||
retry:
|
||||
ret = mtd->read(mtd, readpos, PAGE_SIZE, &retlen, d->page_buf);
|
||||
ret = mtd_read(mtd, readpos, PAGE_SIZE, &retlen, d->page_buf);
|
||||
|
||||
if (ret < 0 && !mtd_is_bitflip(ret)) {
|
||||
oldeb = d->eb_data + oldblock / d->pages_per_eblk;
|
||||
@ -946,7 +946,7 @@ static unsigned int mtdswap_eblk_passes(struct mtdswap_dev *d,
|
||||
patt = mtdswap_test_patt(test + i);
|
||||
memset(d->page_buf, patt, mtd->writesize);
|
||||
memset(d->oob_buf, patt, mtd->ecclayout->oobavail);
|
||||
ret = mtd->write_oob(mtd, pos, &ops);
|
||||
ret = mtd_write_oob(mtd, pos, &ops);
|
||||
if (ret)
|
||||
goto error;
|
||||
|
||||
@ -955,7 +955,7 @@ static unsigned int mtdswap_eblk_passes(struct mtdswap_dev *d,
|
||||
|
||||
pos = base;
|
||||
for (i = 0; i < mtd_pages; i++) {
|
||||
ret = mtd->read_oob(mtd, pos, &ops);
|
||||
ret = mtd_read_oob(mtd, pos, &ops);
|
||||
if (ret)
|
||||
goto error;
|
||||
|
||||
@ -1047,8 +1047,7 @@ static int mtdswap_flush(struct mtd_blktrans_dev *dev)
|
||||
{
|
||||
struct mtdswap_dev *d = MTDSWAP_MBD_TO_MTDSWAP(dev);
|
||||
|
||||
if (d->mtd->sync)
|
||||
d->mtd->sync(d->mtd);
|
||||
mtd_sync(d->mtd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1059,9 +1058,9 @@ static unsigned int mtdswap_badblocks(struct mtd_info *mtd, uint64_t size)
|
||||
|
||||
badcnt = 0;
|
||||
|
||||
if (mtd->block_isbad)
|
||||
if (mtd_can_have_bb(mtd))
|
||||
for (offset = 0; offset < size; offset += mtd->erasesize)
|
||||
if (mtd->block_isbad(mtd, offset))
|
||||
if (mtd_block_isbad(mtd, offset))
|
||||
badcnt++;
|
||||
|
||||
return badcnt;
|
||||
@ -1161,7 +1160,7 @@ static int mtdswap_readsect(struct mtd_blktrans_dev *dev,
|
||||
retries = 0;
|
||||
|
||||
retry:
|
||||
ret = mtd->read(mtd, readpos, PAGE_SIZE, &retlen, buf);
|
||||
ret = mtd_read(mtd, readpos, PAGE_SIZE, &retlen, buf);
|
||||
|
||||
d->mtd_read_count++;
|
||||
if (mtd_is_bitflip(ret)) {
|
||||
|
@ -110,7 +110,7 @@ config MTD_NAND_AMS_DELTA
|
||||
|
||||
config MTD_NAND_OMAP2
|
||||
tristate "NAND Flash device on OMAP2, OMAP3 and OMAP4"
|
||||
depends on ARM && (ARCH_OMAP2 || ARCH_OMAP3 || ARCH_OMAP4)
|
||||
depends on ARCH_OMAP2PLUS
|
||||
help
|
||||
Support for NAND flash on Texas Instruments OMAP2, OMAP3 and OMAP4
|
||||
platforms.
|
||||
|
@ -280,17 +280,7 @@ static struct platform_driver ams_delta_nand_driver = {
|
||||
},
|
||||
};
|
||||
|
||||
static int __init ams_delta_nand_init(void)
|
||||
{
|
||||
return platform_driver_register(&ams_delta_nand_driver);
|
||||
}
|
||||
module_init(ams_delta_nand_init);
|
||||
|
||||
static void __exit ams_delta_nand_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&ams_delta_nand_driver);
|
||||
}
|
||||
module_exit(ams_delta_nand_exit);
|
||||
module_platform_driver(ams_delta_nand_driver);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Jonathan McDowell <noodles@earth.li>");
|
||||
|
@ -546,18 +546,7 @@ static struct platform_driver nand_driver = {
|
||||
.resume = bcm_umi_nand_resume,
|
||||
};
|
||||
|
||||
static int __init nand_init(void)
|
||||
{
|
||||
return platform_driver_register(&nand_driver);
|
||||
}
|
||||
|
||||
static void __exit nand_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&nand_driver);
|
||||
}
|
||||
|
||||
module_init(nand_init);
|
||||
module_exit(nand_exit);
|
||||
module_platform_driver(nand_driver);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Broadcom");
|
||||
|
@ -675,7 +675,9 @@ static int __init nand_davinci_probe(struct platform_device *pdev)
|
||||
|
||||
davinci_nand_writel(info, A1CR_OFFSET + info->core_chipsel * 4, val);
|
||||
|
||||
ret = davinci_aemif_setup_timing(info->timing, info->base,
|
||||
ret = 0;
|
||||
if (info->timing)
|
||||
ret = davinci_aemif_setup_timing(info->timing, info->base,
|
||||
info->core_chipsel);
|
||||
if (ret < 0) {
|
||||
dev_dbg(&pdev->dev, "NAND timing values setup fail\n");
|
||||
|
@ -1072,7 +1072,7 @@ static int __init find_media_headers(struct mtd_info *mtd, u_char *buf, const ch
|
||||
size_t retlen;
|
||||
|
||||
for (offs = 0; offs < mtd->size; offs += mtd->erasesize) {
|
||||
ret = mtd->read(mtd, offs, mtd->writesize, &retlen, buf);
|
||||
ret = mtd_read(mtd, offs, mtd->writesize, &retlen, buf);
|
||||
if (retlen != mtd->writesize)
|
||||
continue;
|
||||
if (ret) {
|
||||
@ -1097,7 +1097,7 @@ static int __init find_media_headers(struct mtd_info *mtd, u_char *buf, const ch
|
||||
/* Only one mediaheader was found. We want buf to contain a
|
||||
mediaheader on return, so we'll have to re-read the one we found. */
|
||||
offs = doc->mh0_page << this->page_shift;
|
||||
ret = mtd->read(mtd, offs, mtd->writesize, &retlen, buf);
|
||||
ret = mtd_read(mtd, offs, mtd->writesize, &retlen, buf);
|
||||
if (retlen != mtd->writesize) {
|
||||
/* Insanity. Give up. */
|
||||
printk(KERN_ERR "Read DiskOnChip Media Header once, but can't reread it???\n");
|
||||
|
@ -166,15 +166,22 @@ static void set_addr(struct mtd_info *mtd, int column, int page_addr, int oob)
|
||||
|
||||
elbc_fcm_ctrl->page = page_addr;
|
||||
|
||||
out_be32(&lbc->fbar,
|
||||
page_addr >> (chip->phys_erase_shift - chip->page_shift));
|
||||
|
||||
if (priv->page_size) {
|
||||
/*
|
||||
* large page size chip : FPAR[PI] save the lowest 6 bits,
|
||||
* FBAR[BLK] save the other bits.
|
||||
*/
|
||||
out_be32(&lbc->fbar, page_addr >> 6);
|
||||
out_be32(&lbc->fpar,
|
||||
((page_addr << FPAR_LP_PI_SHIFT) & FPAR_LP_PI) |
|
||||
(oob ? FPAR_LP_MS : 0) | column);
|
||||
buf_num = (page_addr & 1) << 2;
|
||||
} else {
|
||||
/*
|
||||
* small page size chip : FPAR[PI] save the lowest 5 bits,
|
||||
* FBAR[BLK] save the other bits.
|
||||
*/
|
||||
out_be32(&lbc->fbar, page_addr >> 5);
|
||||
out_be32(&lbc->fpar,
|
||||
((page_addr << FPAR_SP_PI_SHIFT) & FPAR_SP_PI) |
|
||||
(oob ? FPAR_SP_MS : 0) | column);
|
||||
@ -349,20 +356,22 @@ static void fsl_elbc_cmdfunc(struct mtd_info *mtd, unsigned int command,
|
||||
fsl_elbc_run_command(mtd);
|
||||
return;
|
||||
|
||||
/* READID must read all 5 possible bytes while CEB is active */
|
||||
case NAND_CMD_READID:
|
||||
dev_vdbg(priv->dev, "fsl_elbc_cmdfunc: NAND_CMD_READID.\n");
|
||||
case NAND_CMD_PARAM:
|
||||
dev_vdbg(priv->dev, "fsl_elbc_cmdfunc: NAND_CMD %x\n", command);
|
||||
|
||||
out_be32(&lbc->fir, (FIR_OP_CM0 << FIR_OP0_SHIFT) |
|
||||
(FIR_OP_UA << FIR_OP1_SHIFT) |
|
||||
(FIR_OP_RBW << FIR_OP2_SHIFT));
|
||||
out_be32(&lbc->fcr, NAND_CMD_READID << FCR_CMD0_SHIFT);
|
||||
/* nand_get_flash_type() reads 8 bytes of entire ID string */
|
||||
out_be32(&lbc->fbcr, 8);
|
||||
elbc_fcm_ctrl->read_bytes = 8;
|
||||
out_be32(&lbc->fcr, command << FCR_CMD0_SHIFT);
|
||||
/*
|
||||
* although currently it's 8 bytes for READID, we always read
|
||||
* the maximum 256 bytes(for PARAM)
|
||||
*/
|
||||
out_be32(&lbc->fbcr, 256);
|
||||
elbc_fcm_ctrl->read_bytes = 256;
|
||||
elbc_fcm_ctrl->use_mdr = 1;
|
||||
elbc_fcm_ctrl->mdr = 0;
|
||||
|
||||
elbc_fcm_ctrl->mdr = column;
|
||||
set_addr(mtd, 0, 0, 0);
|
||||
fsl_elbc_run_command(mtd);
|
||||
return;
|
||||
@ -407,9 +416,17 @@ static void fsl_elbc_cmdfunc(struct mtd_info *mtd, unsigned int command,
|
||||
page_addr, column);
|
||||
|
||||
elbc_fcm_ctrl->column = column;
|
||||
elbc_fcm_ctrl->oob = 0;
|
||||
elbc_fcm_ctrl->use_mdr = 1;
|
||||
|
||||
if (column >= mtd->writesize) {
|
||||
/* OOB area */
|
||||
column -= mtd->writesize;
|
||||
elbc_fcm_ctrl->oob = 1;
|
||||
} else {
|
||||
WARN_ON(column != 0);
|
||||
elbc_fcm_ctrl->oob = 0;
|
||||
}
|
||||
|
||||
fcr = (NAND_CMD_STATUS << FCR_CMD1_SHIFT) |
|
||||
(NAND_CMD_SEQIN << FCR_CMD2_SHIFT) |
|
||||
(NAND_CMD_PAGEPROG << FCR_CMD3_SHIFT);
|
||||
@ -434,16 +451,12 @@ static void fsl_elbc_cmdfunc(struct mtd_info *mtd, unsigned int command,
|
||||
(FIR_OP_CW1 << FIR_OP6_SHIFT) |
|
||||
(FIR_OP_RS << FIR_OP7_SHIFT));
|
||||
|
||||
if (column >= mtd->writesize) {
|
||||
if (elbc_fcm_ctrl->oob)
|
||||
/* OOB area --> READOOB */
|
||||
column -= mtd->writesize;
|
||||
fcr |= NAND_CMD_READOOB << FCR_CMD0_SHIFT;
|
||||
elbc_fcm_ctrl->oob = 1;
|
||||
} else {
|
||||
WARN_ON(column != 0);
|
||||
else
|
||||
/* First 256 bytes --> READ0 */
|
||||
fcr |= NAND_CMD_READ0 << FCR_CMD0_SHIFT;
|
||||
}
|
||||
}
|
||||
|
||||
out_be32(&lbc->fcr, fcr);
|
||||
@ -463,7 +476,8 @@ static void fsl_elbc_cmdfunc(struct mtd_info *mtd, unsigned int command,
|
||||
*/
|
||||
if (elbc_fcm_ctrl->oob || elbc_fcm_ctrl->column != 0 ||
|
||||
elbc_fcm_ctrl->index != mtd->writesize + mtd->oobsize)
|
||||
out_be32(&lbc->fbcr, elbc_fcm_ctrl->index);
|
||||
out_be32(&lbc->fbcr,
|
||||
elbc_fcm_ctrl->index - elbc_fcm_ctrl->column);
|
||||
else
|
||||
out_be32(&lbc->fbcr, 0);
|
||||
|
||||
@ -659,9 +673,7 @@ static int fsl_elbc_chip_init_tail(struct mtd_info *mtd)
|
||||
if (chip->pagemask & 0xff000000)
|
||||
al++;
|
||||
|
||||
/* add to ECCM mode set in fsl_elbc_init */
|
||||
priv->fmr |= (12 << FMR_CWTO_SHIFT) | /* Timeout > 12 ms */
|
||||
(al << FMR_AL_SHIFT);
|
||||
priv->fmr |= al << FMR_AL_SHIFT;
|
||||
|
||||
dev_dbg(priv->dev, "fsl_elbc_init: nand->numchips = %d\n",
|
||||
chip->numchips);
|
||||
@ -764,8 +776,10 @@ static int fsl_elbc_chip_init(struct fsl_elbc_mtd *priv)
|
||||
priv->mtd.priv = chip;
|
||||
priv->mtd.owner = THIS_MODULE;
|
||||
|
||||
/* Set the ECCM according to the settings in bootloader.*/
|
||||
priv->fmr = in_be32(&lbc->fmr) & FMR_ECCM;
|
||||
/* set timeout to maximum */
|
||||
priv->fmr = 15 << FMR_CWTO_SHIFT;
|
||||
if (in_be32(&lbc->bank[priv->bank].or) & OR_FCM_PGS)
|
||||
priv->fmr |= FMR_ECCM;
|
||||
|
||||
/* fill in nand_chip structure */
|
||||
/* set up function call table */
|
||||
@ -971,18 +985,7 @@ static struct platform_driver fsl_elbc_nand_driver = {
|
||||
.remove = fsl_elbc_nand_remove,
|
||||
};
|
||||
|
||||
static int __init fsl_elbc_nand_init(void)
|
||||
{
|
||||
return platform_driver_register(&fsl_elbc_nand_driver);
|
||||
}
|
||||
|
||||
static void __exit fsl_elbc_nand_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&fsl_elbc_nand_driver);
|
||||
}
|
||||
|
||||
module_init(fsl_elbc_nand_init);
|
||||
module_exit(fsl_elbc_nand_exit);
|
||||
module_platform_driver(fsl_elbc_nand_driver);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Freescale");
|
||||
|
@ -353,17 +353,7 @@ static struct platform_driver of_fun_driver = {
|
||||
.remove = __devexit_p(fun_remove),
|
||||
};
|
||||
|
||||
static int __init fun_module_init(void)
|
||||
{
|
||||
return platform_driver_register(&of_fun_driver);
|
||||
}
|
||||
module_init(fun_module_init);
|
||||
|
||||
static void __exit fun_module_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&of_fun_driver);
|
||||
}
|
||||
module_exit(fun_module_exit);
|
||||
module_platform_driver(of_fun_driver);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Anton Vorontsov <avorontsov@ru.mvista.com>");
|
||||
|
@ -27,6 +27,9 @@
|
||||
#include <linux/mtd/nand.h>
|
||||
#include <linux/mtd/partitions.h>
|
||||
#include <linux/mtd/nand-gpio.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/of_gpio.h>
|
||||
|
||||
struct gpiomtd {
|
||||
void __iomem *io_sync;
|
||||
@ -171,6 +174,96 @@ static int gpio_nand_devready(struct mtd_info *mtd)
|
||||
return gpio_get_value(gpiomtd->plat.gpio_rdy);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
static const struct of_device_id gpio_nand_id_table[] = {
|
||||
{ .compatible = "gpio-control-nand" },
|
||||
{}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, gpio_nand_id_table);
|
||||
|
||||
static int gpio_nand_get_config_of(const struct device *dev,
|
||||
struct gpio_nand_platdata *plat)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
if (!of_property_read_u32(dev->of_node, "bank-width", &val)) {
|
||||
if (val == 2) {
|
||||
plat->options |= NAND_BUSWIDTH_16;
|
||||
} else if (val != 1) {
|
||||
dev_err(dev, "invalid bank-width %u\n", val);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
plat->gpio_rdy = of_get_gpio(dev->of_node, 0);
|
||||
plat->gpio_nce = of_get_gpio(dev->of_node, 1);
|
||||
plat->gpio_ale = of_get_gpio(dev->of_node, 2);
|
||||
plat->gpio_cle = of_get_gpio(dev->of_node, 3);
|
||||
plat->gpio_nwp = of_get_gpio(dev->of_node, 4);
|
||||
|
||||
if (!of_property_read_u32(dev->of_node, "chip-delay", &val))
|
||||
plat->chip_delay = val;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct resource *gpio_nand_get_io_sync_of(struct platform_device *pdev)
|
||||
{
|
||||
struct resource *r = devm_kzalloc(&pdev->dev, sizeof(*r), GFP_KERNEL);
|
||||
u64 addr;
|
||||
|
||||
if (!r || of_property_read_u64(pdev->dev.of_node,
|
||||
"gpio-control-nand,io-sync-reg", &addr))
|
||||
return NULL;
|
||||
|
||||
r->start = addr;
|
||||
r->end = r->start + 0x3;
|
||||
r->flags = IORESOURCE_MEM;
|
||||
|
||||
return r;
|
||||
}
|
||||
#else /* CONFIG_OF */
|
||||
#define gpio_nand_id_table NULL
|
||||
static inline int gpio_nand_get_config_of(const struct device *dev,
|
||||
struct gpio_nand_platdata *plat)
|
||||
{
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
static inline struct resource *
|
||||
gpio_nand_get_io_sync_of(struct platform_device *pdev)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
#endif /* CONFIG_OF */
|
||||
|
||||
static inline int gpio_nand_get_config(const struct device *dev,
|
||||
struct gpio_nand_platdata *plat)
|
||||
{
|
||||
int ret = gpio_nand_get_config_of(dev, plat);
|
||||
|
||||
if (!ret)
|
||||
return ret;
|
||||
|
||||
if (dev->platform_data) {
|
||||
memcpy(plat, dev->platform_data, sizeof(*plat));
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static inline struct resource *
|
||||
gpio_nand_get_io_sync(struct platform_device *pdev)
|
||||
{
|
||||
struct resource *r = gpio_nand_get_io_sync_of(pdev);
|
||||
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
return platform_get_resource(pdev, IORESOURCE_MEM, 1);
|
||||
}
|
||||
|
||||
static int __devexit gpio_nand_remove(struct platform_device *dev)
|
||||
{
|
||||
struct gpiomtd *gpiomtd = platform_get_drvdata(dev);
|
||||
@ -178,7 +271,7 @@ static int __devexit gpio_nand_remove(struct platform_device *dev)
|
||||
|
||||
nand_release(&gpiomtd->mtd_info);
|
||||
|
||||
res = platform_get_resource(dev, IORESOURCE_MEM, 1);
|
||||
res = gpio_nand_get_io_sync(dev);
|
||||
iounmap(gpiomtd->io_sync);
|
||||
if (res)
|
||||
release_mem_region(res->start, resource_size(res));
|
||||
@ -226,9 +319,10 @@ static int __devinit gpio_nand_probe(struct platform_device *dev)
|
||||
struct gpiomtd *gpiomtd;
|
||||
struct nand_chip *this;
|
||||
struct resource *res0, *res1;
|
||||
int ret;
|
||||
struct mtd_part_parser_data ppdata = {};
|
||||
int ret = 0;
|
||||
|
||||
if (!dev->dev.platform_data)
|
||||
if (!dev->dev.of_node && !dev->dev.platform_data)
|
||||
return -EINVAL;
|
||||
|
||||
res0 = platform_get_resource(dev, IORESOURCE_MEM, 0);
|
||||
@ -248,7 +342,7 @@ static int __devinit gpio_nand_probe(struct platform_device *dev)
|
||||
goto err_map;
|
||||
}
|
||||
|
||||
res1 = platform_get_resource(dev, IORESOURCE_MEM, 1);
|
||||
res1 = gpio_nand_get_io_sync(dev);
|
||||
if (res1) {
|
||||
gpiomtd->io_sync = request_and_remap(res1, 4, "NAND sync", &ret);
|
||||
if (!gpiomtd->io_sync) {
|
||||
@ -257,7 +351,9 @@ static int __devinit gpio_nand_probe(struct platform_device *dev)
|
||||
}
|
||||
}
|
||||
|
||||
memcpy(&gpiomtd->plat, dev->dev.platform_data, sizeof(gpiomtd->plat));
|
||||
ret = gpio_nand_get_config(&dev->dev, &gpiomtd->plat);
|
||||
if (ret)
|
||||
goto err_nce;
|
||||
|
||||
ret = gpio_request(gpiomtd->plat.gpio_nce, "NAND NCE");
|
||||
if (ret)
|
||||
@ -316,8 +412,12 @@ static int __devinit gpio_nand_probe(struct platform_device *dev)
|
||||
gpiomtd->plat.adjust_parts(&gpiomtd->plat,
|
||||
gpiomtd->mtd_info.size);
|
||||
|
||||
mtd_device_register(&gpiomtd->mtd_info, gpiomtd->plat.parts,
|
||||
gpiomtd->plat.num_parts);
|
||||
ppdata.of_node = dev->dev.of_node;
|
||||
ret = mtd_device_parse_register(&gpiomtd->mtd_info, NULL, &ppdata,
|
||||
gpiomtd->plat.parts,
|
||||
gpiomtd->plat.num_parts);
|
||||
if (ret)
|
||||
goto err_wp;
|
||||
platform_set_drvdata(dev, gpiomtd);
|
||||
|
||||
return 0;
|
||||
@ -352,6 +452,7 @@ static struct platform_driver gpio_nand_driver = {
|
||||
.remove = gpio_nand_remove,
|
||||
.driver = {
|
||||
.name = "gpio-nand",
|
||||
.of_match_table = gpio_nand_id_table,
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -423,17 +423,7 @@ static struct platform_driver jz_nand_driver = {
|
||||
},
|
||||
};
|
||||
|
||||
static int __init jz_nand_init(void)
|
||||
{
|
||||
return platform_driver_register(&jz_nand_driver);
|
||||
}
|
||||
module_init(jz_nand_init);
|
||||
|
||||
static void __exit jz_nand_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&jz_nand_driver);
|
||||
}
|
||||
module_exit(jz_nand_exit);
|
||||
module_platform_driver(jz_nand_driver);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
|
||||
|
@ -879,19 +879,7 @@ static struct platform_driver mpc5121_nfc_driver = {
|
||||
},
|
||||
};
|
||||
|
||||
static int __init mpc5121_nfc_init(void)
|
||||
{
|
||||
return platform_driver_register(&mpc5121_nfc_driver);
|
||||
}
|
||||
|
||||
module_init(mpc5121_nfc_init);
|
||||
|
||||
static void __exit mpc5121_nfc_cleanup(void)
|
||||
{
|
||||
platform_driver_unregister(&mpc5121_nfc_driver);
|
||||
}
|
||||
|
||||
module_exit(mpc5121_nfc_cleanup);
|
||||
module_platform_driver(mpc5121_nfc_driver);
|
||||
|
||||
MODULE_AUTHOR("Freescale Semiconductor, Inc.");
|
||||
MODULE_DESCRIPTION("MPC5121 NAND MTD driver");
|
||||
|
@ -3132,8 +3132,8 @@ ident_done:
|
||||
* Bad block marker is stored in the last page of each block
|
||||
* on Samsung and Hynix MLC devices; stored in first two pages
|
||||
* of each block on Micron devices with 2KiB pages and on
|
||||
* SLC Samsung, Hynix, Toshiba and AMD/Spansion. All others scan
|
||||
* only the first page.
|
||||
* SLC Samsung, Hynix, Toshiba, AMD/Spansion, and Macronix.
|
||||
* All others scan only the first page.
|
||||
*/
|
||||
if ((chip->cellinfo & NAND_CI_CELLTYPE_MSK) &&
|
||||
(*maf_id == NAND_MFR_SAMSUNG ||
|
||||
@ -3143,7 +3143,8 @@ ident_done:
|
||||
(*maf_id == NAND_MFR_SAMSUNG ||
|
||||
*maf_id == NAND_MFR_HYNIX ||
|
||||
*maf_id == NAND_MFR_TOSHIBA ||
|
||||
*maf_id == NAND_MFR_AMD)) ||
|
||||
*maf_id == NAND_MFR_AMD ||
|
||||
*maf_id == NAND_MFR_MACRONIX)) ||
|
||||
(mtd->writesize == 2048 &&
|
||||
*maf_id == NAND_MFR_MICRON))
|
||||
chip->bbt_options |= NAND_BBT_SCAN2NDPAGE;
|
||||
|
@ -201,7 +201,7 @@ static int read_bbt(struct mtd_info *mtd, uint8_t *buf, int page, int num,
|
||||
from += marker_len;
|
||||
marker_len = 0;
|
||||
}
|
||||
res = mtd->read(mtd, from, len, &retlen, buf);
|
||||
res = mtd_read(mtd, from, len, &retlen, buf);
|
||||
if (res < 0) {
|
||||
if (mtd_is_eccerr(res)) {
|
||||
pr_info("nand_bbt: ECC error in BBT at "
|
||||
@ -298,7 +298,7 @@ static int scan_read_raw_data(struct mtd_info *mtd, uint8_t *buf, loff_t offs,
|
||||
if (td->options & NAND_BBT_VERSION)
|
||||
len++;
|
||||
|
||||
return mtd->read(mtd, offs, len, &retlen, buf);
|
||||
return mtd_read(mtd, offs, len, &retlen, buf);
|
||||
}
|
||||
|
||||
/* Scan read raw data from flash */
|
||||
@ -317,7 +317,7 @@ static int scan_read_raw_oob(struct mtd_info *mtd, uint8_t *buf, loff_t offs,
|
||||
ops.len = min(len, (size_t)mtd->writesize);
|
||||
ops.oobbuf = buf + ops.len;
|
||||
|
||||
res = mtd->read_oob(mtd, offs, &ops);
|
||||
res = mtd_read_oob(mtd, offs, &ops);
|
||||
|
||||
if (res)
|
||||
return res;
|
||||
@ -350,7 +350,7 @@ static int scan_write_bbt(struct mtd_info *mtd, loff_t offs, size_t len,
|
||||
ops.oobbuf = oob;
|
||||
ops.len = len;
|
||||
|
||||
return mtd->write_oob(mtd, offs, &ops);
|
||||
return mtd_write_oob(mtd, offs, &ops);
|
||||
}
|
||||
|
||||
static u32 bbt_get_ver_offs(struct mtd_info *mtd, struct nand_bbt_descr *td)
|
||||
@ -434,7 +434,7 @@ static int scan_block_fast(struct mtd_info *mtd, struct nand_bbt_descr *bd,
|
||||
* Read the full oob until read_oob is fixed to handle single
|
||||
* byte reads for 16 bit buswidth.
|
||||
*/
|
||||
ret = mtd->read_oob(mtd, offs, &ops);
|
||||
ret = mtd_read_oob(mtd, offs, &ops);
|
||||
/* Ignore ECC errors when checking for BBM */
|
||||
if (ret && !mtd_is_bitflip_or_eccerr(ret))
|
||||
return ret;
|
||||
@ -756,7 +756,7 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf,
|
||||
/* Make it block aligned */
|
||||
to &= ~((loff_t)((1 << this->bbt_erase_shift) - 1));
|
||||
len = 1 << this->bbt_erase_shift;
|
||||
res = mtd->read(mtd, to, len, &retlen, buf);
|
||||
res = mtd_read(mtd, to, len, &retlen, buf);
|
||||
if (res < 0) {
|
||||
if (retlen != len) {
|
||||
pr_info("nand_bbt: error reading block "
|
||||
@ -769,7 +769,7 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf,
|
||||
/* Read oob data */
|
||||
ops.ooblen = (len >> this->page_shift) * mtd->oobsize;
|
||||
ops.oobbuf = &buf[len];
|
||||
res = mtd->read_oob(mtd, to + mtd->writesize, &ops);
|
||||
res = mtd_read_oob(mtd, to + mtd->writesize, &ops);
|
||||
if (res < 0 || ops.oobretlen != ops.ooblen)
|
||||
goto outerr;
|
||||
|
||||
|
@ -73,11 +73,12 @@ struct nand_flash_dev nand_flash_ids[] = {
|
||||
#define LP_OPTIONS (NAND_SAMSUNG_LP_OPTIONS | NAND_NO_READRDY | NAND_NO_AUTOINCR)
|
||||
#define LP_OPTIONS16 (LP_OPTIONS | NAND_BUSWIDTH_16)
|
||||
|
||||
/*512 Megabit */
|
||||
/* 512 Megabit */
|
||||
{"NAND 64MiB 1,8V 8-bit", 0xA2, 0, 64, 0, LP_OPTIONS},
|
||||
{"NAND 64MiB 1,8V 8-bit", 0xA0, 0, 64, 0, LP_OPTIONS},
|
||||
{"NAND 64MiB 3,3V 8-bit", 0xF2, 0, 64, 0, LP_OPTIONS},
|
||||
{"NAND 64MiB 3,3V 8-bit", 0xD0, 0, 64, 0, LP_OPTIONS},
|
||||
{"NAND 64MiB 3,3V 8-bit", 0xF0, 0, 64, 0, LP_OPTIONS},
|
||||
{"NAND 64MiB 1,8V 16-bit", 0xB2, 0, 64, 0, LP_OPTIONS16},
|
||||
{"NAND 64MiB 1,8V 16-bit", 0xB0, 0, 64, 0, LP_OPTIONS16},
|
||||
{"NAND 64MiB 3,3V 16-bit", 0xC2, 0, 64, 0, LP_OPTIONS16},
|
||||
@ -176,6 +177,7 @@ struct nand_manufacturers nand_manuf_ids[] = {
|
||||
{NAND_MFR_HYNIX, "Hynix"},
|
||||
{NAND_MFR_MICRON, "Micron"},
|
||||
{NAND_MFR_AMD, "AMD"},
|
||||
{NAND_MFR_MACRONIX, "Macronix"},
|
||||
{0x0, "Unknown"}
|
||||
};
|
||||
|
||||
|
@ -737,7 +737,7 @@ static int parse_badblocks(struct nandsim *ns, struct mtd_info *mtd)
|
||||
return -EINVAL;
|
||||
}
|
||||
offset = erase_block_no * ns->geom.secsz;
|
||||
if (mtd->block_markbad(mtd, offset)) {
|
||||
if (mtd_block_markbad(mtd, offset)) {
|
||||
NS_ERR("invalid badblocks.\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
@ -294,18 +294,7 @@ static struct platform_driver ndfc_driver = {
|
||||
.remove = __devexit_p(ndfc_remove),
|
||||
};
|
||||
|
||||
static int __init ndfc_nand_init(void)
|
||||
{
|
||||
return platform_driver_register(&ndfc_driver);
|
||||
}
|
||||
|
||||
static void __exit ndfc_nand_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&ndfc_driver);
|
||||
}
|
||||
|
||||
module_init(ndfc_nand_init);
|
||||
module_exit(ndfc_nand_exit);
|
||||
module_platform_driver(ndfc_driver);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Thomas Gleixner <tglx@linutronix.de>");
|
||||
|
@ -201,7 +201,7 @@ static int nomadik_nand_suspend(struct device *dev)
|
||||
struct nomadik_nand_host *host = dev_get_drvdata(dev);
|
||||
int ret = 0;
|
||||
if (host)
|
||||
ret = host->mtd.suspend(&host->mtd);
|
||||
ret = mtd_suspend(&host->mtd);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -209,7 +209,7 @@ static int nomadik_nand_resume(struct device *dev)
|
||||
{
|
||||
struct nomadik_nand_host *host = dev_get_drvdata(dev);
|
||||
if (host)
|
||||
host->mtd.resume(&host->mtd);
|
||||
mtd_resume(&host->mtd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -228,19 +228,7 @@ static struct platform_driver nomadik_nand_driver = {
|
||||
},
|
||||
};
|
||||
|
||||
static int __init nand_nomadik_init(void)
|
||||
{
|
||||
pr_info("Nomadik NAND driver\n");
|
||||
return platform_driver_register(&nomadik_nand_driver);
|
||||
}
|
||||
|
||||
static void __exit nand_nomadik_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&nomadik_nand_driver);
|
||||
}
|
||||
|
||||
module_init(nand_nomadik_init);
|
||||
module_exit(nand_nomadik_exit);
|
||||
module_platform_driver(nomadik_nand_driver);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("ST Microelectronics (sachin.verma@st.com)");
|
||||
|
@ -364,18 +364,7 @@ static struct platform_driver nuc900_nand_driver = {
|
||||
},
|
||||
};
|
||||
|
||||
static int __init nuc900_nand_init(void)
|
||||
{
|
||||
return platform_driver_register(&nuc900_nand_driver);
|
||||
}
|
||||
|
||||
static void __exit nuc900_nand_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&nuc900_nand_driver);
|
||||
}
|
||||
|
||||
module_init(nuc900_nand_init);
|
||||
module_exit(nuc900_nand_exit);
|
||||
module_platform_driver(nuc900_nand_driver);
|
||||
|
||||
MODULE_AUTHOR("Wan ZongShun <mcuos.com@gmail.com>");
|
||||
MODULE_DESCRIPTION("w90p910/NUC9xx nand driver!");
|
||||
|
@ -1145,20 +1145,7 @@ static struct platform_driver omap_nand_driver = {
|
||||
},
|
||||
};
|
||||
|
||||
static int __init omap_nand_init(void)
|
||||
{
|
||||
pr_info("%s driver initializing\n", DRIVER_NAME);
|
||||
|
||||
return platform_driver_register(&omap_nand_driver);
|
||||
}
|
||||
|
||||
static void __exit omap_nand_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&omap_nand_driver);
|
||||
}
|
||||
|
||||
module_init(omap_nand_init);
|
||||
module_exit(omap_nand_exit);
|
||||
module_platform_driver(omap_nand_driver);
|
||||
|
||||
MODULE_ALIAS("platform:" DRIVER_NAME);
|
||||
MODULE_LICENSE("GPL");
|
||||
|
@ -230,17 +230,7 @@ static struct platform_driver pasemi_nand_driver =
|
||||
.remove = pasemi_nand_remove,
|
||||
};
|
||||
|
||||
static int __init pasemi_nand_init(void)
|
||||
{
|
||||
return platform_driver_register(&pasemi_nand_driver);
|
||||
}
|
||||
module_init(pasemi_nand_init);
|
||||
|
||||
static void __exit pasemi_nand_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&pasemi_nand_driver);
|
||||
}
|
||||
module_exit(pasemi_nand_exit);
|
||||
module_platform_driver(pasemi_nand_driver);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Egor Martovetsky <egor@pasemi.com>");
|
||||
|
@ -148,18 +148,7 @@ static struct platform_driver plat_nand_driver = {
|
||||
},
|
||||
};
|
||||
|
||||
static int __init plat_nand_init(void)
|
||||
{
|
||||
return platform_driver_register(&plat_nand_driver);
|
||||
}
|
||||
|
||||
static void __exit plat_nand_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&plat_nand_driver);
|
||||
}
|
||||
|
||||
module_init(plat_nand_init);
|
||||
module_exit(plat_nand_exit);
|
||||
module_platform_driver(plat_nand_driver);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Vitaly Wool");
|
||||
|
@ -1258,7 +1258,7 @@ static int pxa3xx_nand_suspend(struct platform_device *pdev, pm_message_t state)
|
||||
|
||||
for (cs = 0; cs < pdata->num_cs; cs++) {
|
||||
mtd = info->host[cs]->mtd;
|
||||
mtd->suspend(mtd);
|
||||
mtd_suspend(mtd);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -1291,7 +1291,7 @@ static int pxa3xx_nand_resume(struct platform_device *pdev)
|
||||
nand_writel(info, NDSR, NDSR_MASK);
|
||||
for (cs = 0; cs < pdata->num_cs; cs++) {
|
||||
mtd = info->host[cs]->mtd;
|
||||
mtd->resume(mtd);
|
||||
mtd_resume(mtd);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -1311,17 +1311,7 @@ static struct platform_driver pxa3xx_nand_driver = {
|
||||
.resume = pxa3xx_nand_resume,
|
||||
};
|
||||
|
||||
static int __init pxa3xx_nand_init(void)
|
||||
{
|
||||
return platform_driver_register(&pxa3xx_nand_driver);
|
||||
}
|
||||
module_init(pxa3xx_nand_init);
|
||||
|
||||
static void __exit pxa3xx_nand_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&pxa3xx_nand_driver);
|
||||
}
|
||||
module_exit(pxa3xx_nand_exit);
|
||||
module_platform_driver(pxa3xx_nand_driver);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_DESCRIPTION("PXA3xx NAND controller driver");
|
||||
|
@ -230,17 +230,7 @@ static struct platform_driver sharpsl_nand_driver = {
|
||||
.remove = __devexit_p(sharpsl_nand_remove),
|
||||
};
|
||||
|
||||
static int __init sharpsl_nand_init(void)
|
||||
{
|
||||
return platform_driver_register(&sharpsl_nand_driver);
|
||||
}
|
||||
module_init(sharpsl_nand_init);
|
||||
|
||||
static void __exit sharpsl_nand_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&sharpsl_nand_driver);
|
||||
}
|
||||
module_exit(sharpsl_nand_exit);
|
||||
module_platform_driver(sharpsl_nand_driver);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Richard Purdie <rpurdie@rpsys.net>");
|
||||
|
@ -55,7 +55,7 @@ static int sm_block_markbad(struct mtd_info *mtd, loff_t ofs)
|
||||
ops.datbuf = NULL;
|
||||
|
||||
|
||||
ret = mtd->write_oob(mtd, ofs, &ops);
|
||||
ret = mtd_write_oob(mtd, ofs, &ops);
|
||||
if (ret < 0 || ops.oobretlen != SM_OOB_SIZE) {
|
||||
printk(KERN_NOTICE
|
||||
"sm_common: can't mark sector at %i as bad\n",
|
||||
|
@ -273,18 +273,7 @@ static struct platform_driver socrates_nand_driver = {
|
||||
.remove = __devexit_p(socrates_nand_remove),
|
||||
};
|
||||
|
||||
static int __init socrates_nand_init(void)
|
||||
{
|
||||
return platform_driver_register(&socrates_nand_driver);
|
||||
}
|
||||
|
||||
static void __exit socrates_nand_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&socrates_nand_driver);
|
||||
}
|
||||
|
||||
module_init(socrates_nand_init);
|
||||
module_exit(socrates_nand_exit);
|
||||
module_platform_driver(socrates_nand_driver);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Ilya Yanok");
|
||||
|
@ -533,18 +533,7 @@ static struct platform_driver tmio_driver = {
|
||||
.resume = tmio_resume,
|
||||
};
|
||||
|
||||
static int __init tmio_init(void)
|
||||
{
|
||||
return platform_driver_register(&tmio_driver);
|
||||
}
|
||||
|
||||
static void __exit tmio_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&tmio_driver);
|
||||
}
|
||||
|
||||
module_init(tmio_init);
|
||||
module_exit(tmio_exit);
|
||||
module_platform_driver(tmio_driver);
|
||||
|
||||
MODULE_LICENSE("GPL v2");
|
||||
MODULE_AUTHOR("Ian Molton, Dirk Opfer, Chris Humbert, Dmitry Baryshkov");
|
||||
|
@ -298,11 +298,7 @@ static int __init txx9ndfmc_probe(struct platform_device *dev)
|
||||
drvdata = devm_kzalloc(&dev->dev, sizeof(*drvdata), GFP_KERNEL);
|
||||
if (!drvdata)
|
||||
return -ENOMEM;
|
||||
if (!devm_request_mem_region(&dev->dev, res->start,
|
||||
resource_size(res), dev_name(&dev->dev)))
|
||||
return -EBUSY;
|
||||
drvdata->base = devm_ioremap(&dev->dev, res->start,
|
||||
resource_size(res));
|
||||
drvdata->base = devm_request_and_ioremap(&dev->dev, res);
|
||||
if (!drvdata->base)
|
||||
return -EBUSY;
|
||||
|
||||
|
@ -56,7 +56,7 @@ static void nftl_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd)
|
||||
if (memcmp(mtd->name, "DiskOnChip", 10))
|
||||
return;
|
||||
|
||||
if (!mtd->block_isbad) {
|
||||
if (!mtd_can_have_bb(mtd)) {
|
||||
printk(KERN_ERR
|
||||
"NFTL no longer supports the old DiskOnChip drivers loaded via docprobe.\n"
|
||||
"Please use the new diskonchip driver under the NAND subsystem.\n");
|
||||
@ -153,7 +153,7 @@ int nftl_read_oob(struct mtd_info *mtd, loff_t offs, size_t len,
|
||||
ops.oobbuf = buf;
|
||||
ops.datbuf = NULL;
|
||||
|
||||
res = mtd->read_oob(mtd, offs & ~mask, &ops);
|
||||
res = mtd_read_oob(mtd, offs & ~mask, &ops);
|
||||
*retlen = ops.oobretlen;
|
||||
return res;
|
||||
}
|
||||
@ -174,7 +174,7 @@ int nftl_write_oob(struct mtd_info *mtd, loff_t offs, size_t len,
|
||||
ops.oobbuf = buf;
|
||||
ops.datbuf = NULL;
|
||||
|
||||
res = mtd->write_oob(mtd, offs & ~mask, &ops);
|
||||
res = mtd_write_oob(mtd, offs & ~mask, &ops);
|
||||
*retlen = ops.oobretlen;
|
||||
return res;
|
||||
}
|
||||
@ -198,7 +198,7 @@ static int nftl_write(struct mtd_info *mtd, loff_t offs, size_t len,
|
||||
ops.datbuf = buf;
|
||||
ops.len = len;
|
||||
|
||||
res = mtd->write_oob(mtd, offs & ~mask, &ops);
|
||||
res = mtd_write_oob(mtd, offs & ~mask, &ops);
|
||||
*retlen = ops.retlen;
|
||||
return res;
|
||||
}
|
||||
@ -423,12 +423,17 @@ static u16 NFTL_foldchain (struct NFTLrecord *nftl, unsigned thisVUC, unsigned p
|
||||
if (BlockMap[block] == BLOCK_NIL)
|
||||
continue;
|
||||
|
||||
ret = mtd->read(mtd, (nftl->EraseSize * BlockMap[block]) + (block * 512),
|
||||
512, &retlen, movebuf);
|
||||
ret = mtd_read(mtd,
|
||||
(nftl->EraseSize * BlockMap[block]) + (block * 512),
|
||||
512,
|
||||
&retlen,
|
||||
movebuf);
|
||||
if (ret < 0 && !mtd_is_bitflip(ret)) {
|
||||
ret = mtd->read(mtd, (nftl->EraseSize * BlockMap[block])
|
||||
+ (block * 512), 512, &retlen,
|
||||
movebuf);
|
||||
ret = mtd_read(mtd,
|
||||
(nftl->EraseSize * BlockMap[block]) + (block * 512),
|
||||
512,
|
||||
&retlen,
|
||||
movebuf);
|
||||
if (ret != -EIO)
|
||||
printk("Error went away on retry.\n");
|
||||
}
|
||||
@ -771,7 +776,7 @@ static int nftl_readblock(struct mtd_blktrans_dev *mbd, unsigned long block,
|
||||
} else {
|
||||
loff_t ptr = (lastgoodEUN * nftl->EraseSize) + blockofs;
|
||||
size_t retlen;
|
||||
int res = mtd->read(mtd, ptr, 512, &retlen, buffer);
|
||||
int res = mtd_read(mtd, ptr, 512, &retlen, buffer);
|
||||
|
||||
if (res < 0 && !mtd_is_bitflip(res))
|
||||
return -EIO;
|
||||
|
@ -63,8 +63,8 @@ static int find_boot_record(struct NFTLrecord *nftl)
|
||||
|
||||
/* Check for ANAND header first. Then can whinge if it's found but later
|
||||
checks fail */
|
||||
ret = mtd->read(mtd, block * nftl->EraseSize, SECTORSIZE,
|
||||
&retlen, buf);
|
||||
ret = mtd_read(mtd, block * nftl->EraseSize, SECTORSIZE,
|
||||
&retlen, buf);
|
||||
/* We ignore ret in case the ECC of the MediaHeader is invalid
|
||||
(which is apparently acceptable) */
|
||||
if (retlen != SECTORSIZE) {
|
||||
@ -242,7 +242,8 @@ The new DiskOnChip driver already scanned the bad block table. Just query it.
|
||||
if (buf[i & (SECTORSIZE - 1)] != 0xff)
|
||||
nftl->ReplUnitTable[i] = BLOCK_RESERVED;
|
||||
#endif
|
||||
if (nftl->mbd.mtd->block_isbad(nftl->mbd.mtd, i * nftl->EraseSize))
|
||||
if (mtd_block_isbad(nftl->mbd.mtd,
|
||||
i * nftl->EraseSize))
|
||||
nftl->ReplUnitTable[i] = BLOCK_RESERVED;
|
||||
}
|
||||
|
||||
@ -274,7 +275,7 @@ static int check_free_sectors(struct NFTLrecord *nftl, unsigned int address, int
|
||||
int i;
|
||||
|
||||
for (i = 0; i < len; i += SECTORSIZE) {
|
||||
if (mtd->read(mtd, address, SECTORSIZE, &retlen, buf))
|
||||
if (mtd_read(mtd, address, SECTORSIZE, &retlen, buf))
|
||||
return -1;
|
||||
if (memcmpb(buf, 0xff, SECTORSIZE) != 0)
|
||||
return -1;
|
||||
@ -326,7 +327,7 @@ int NFTL_formatblock(struct NFTLrecord *nftl, int block)
|
||||
instr->mtd = nftl->mbd.mtd;
|
||||
instr->addr = block * nftl->EraseSize;
|
||||
instr->len = nftl->EraseSize;
|
||||
mtd->erase(mtd, instr);
|
||||
mtd_erase(mtd, instr);
|
||||
|
||||
if (instr->state == MTD_ERASE_FAILED) {
|
||||
printk("Error while formatting block %d\n", block);
|
||||
@ -355,7 +356,7 @@ int NFTL_formatblock(struct NFTLrecord *nftl, int block)
|
||||
fail:
|
||||
/* could not format, update the bad block table (caller is responsible
|
||||
for setting the ReplUnitTable to BLOCK_RESERVED on failure) */
|
||||
nftl->mbd.mtd->block_markbad(nftl->mbd.mtd, instr->addr);
|
||||
mtd_block_markbad(nftl->mbd.mtd, instr->addr);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -115,21 +115,9 @@ static struct platform_driver generic_onenand_driver = {
|
||||
.remove = __devexit_p(generic_onenand_remove),
|
||||
};
|
||||
|
||||
MODULE_ALIAS("platform:" DRIVER_NAME);
|
||||
|
||||
static int __init generic_onenand_init(void)
|
||||
{
|
||||
return platform_driver_register(&generic_onenand_driver);
|
||||
}
|
||||
|
||||
static void __exit generic_onenand_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&generic_onenand_driver);
|
||||
}
|
||||
|
||||
module_init(generic_onenand_init);
|
||||
module_exit(generic_onenand_exit);
|
||||
module_platform_driver(generic_onenand_driver);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Kyungmin Park <kyungmin.park@samsung.com>");
|
||||
MODULE_DESCRIPTION("Glue layer for OneNAND flash on generic boards");
|
||||
MODULE_ALIAS("platform:" DRIVER_NAME);
|
||||
|
@ -2633,7 +2633,6 @@ static int onenand_default_block_markbad(struct mtd_info *mtd, loff_t ofs)
|
||||
*/
|
||||
static int onenand_block_markbad(struct mtd_info *mtd, loff_t ofs)
|
||||
{
|
||||
struct onenand_chip *this = mtd->priv;
|
||||
int ret;
|
||||
|
||||
ret = onenand_block_isbad(mtd, ofs);
|
||||
@ -2645,7 +2644,7 @@ static int onenand_block_markbad(struct mtd_info *mtd, loff_t ofs)
|
||||
}
|
||||
|
||||
onenand_get_device(mtd, FL_WRITING);
|
||||
ret = this->block_markbad(mtd, ofs);
|
||||
ret = mtd_block_markbad(mtd, ofs);
|
||||
onenand_release_device(mtd);
|
||||
return ret;
|
||||
}
|
||||
|
@ -1133,18 +1133,7 @@ static struct platform_driver s3c_onenand_driver = {
|
||||
.remove = __devexit_p(s3c_onenand_remove),
|
||||
};
|
||||
|
||||
static int __init s3c_onenand_init(void)
|
||||
{
|
||||
return platform_driver_register(&s3c_onenand_driver);
|
||||
}
|
||||
|
||||
static void __exit s3c_onenand_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&s3c_onenand_driver);
|
||||
}
|
||||
|
||||
module_init(s3c_onenand_init);
|
||||
module_exit(s3c_onenand_exit);
|
||||
module_platform_driver(s3c_onenand_driver);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Kyungmin Park <kyungmin.park@samsung.com>");
|
||||
|
@ -78,8 +78,8 @@ static int parse_redboot_partitions(struct mtd_info *master,
|
||||
|
||||
if ( directory < 0 ) {
|
||||
offset = master->size + directory * master->erasesize;
|
||||
while (master->block_isbad &&
|
||||
master->block_isbad(master, offset)) {
|
||||
while (mtd_can_have_bb(master) &&
|
||||
mtd_block_isbad(master, offset)) {
|
||||
if (!offset) {
|
||||
nogood:
|
||||
printk(KERN_NOTICE "Failed to find a non-bad block to check for RedBoot partition table\n");
|
||||
@ -89,8 +89,8 @@ static int parse_redboot_partitions(struct mtd_info *master,
|
||||
}
|
||||
} else {
|
||||
offset = directory * master->erasesize;
|
||||
while (master->block_isbad &&
|
||||
master->block_isbad(master, offset)) {
|
||||
while (mtd_can_have_bb(master) &&
|
||||
mtd_block_isbad(master, offset)) {
|
||||
offset += master->erasesize;
|
||||
if (offset == master->size)
|
||||
goto nogood;
|
||||
@ -104,8 +104,8 @@ static int parse_redboot_partitions(struct mtd_info *master,
|
||||
printk(KERN_NOTICE "Searching for RedBoot partition table in %s at offset 0x%lx\n",
|
||||
master->name, offset);
|
||||
|
||||
ret = master->read(master, offset,
|
||||
master->erasesize, &retlen, (void *)buf);
|
||||
ret = mtd_read(master, offset, master->erasesize, &retlen,
|
||||
(void *)buf);
|
||||
|
||||
if (ret)
|
||||
goto out;
|
||||
|
@ -200,9 +200,9 @@ static int scan_header(struct partition *part)
|
||||
part->sector_map[i] = -1;
|
||||
|
||||
for (i=0, blocks_found=0; i<part->total_blocks; i++) {
|
||||
rc = part->mbd.mtd->read(part->mbd.mtd,
|
||||
i * part->block_size, part->header_size,
|
||||
&retlen, (u_char*)part->header_cache);
|
||||
rc = mtd_read(part->mbd.mtd, i * part->block_size,
|
||||
part->header_size, &retlen,
|
||||
(u_char *)part->header_cache);
|
||||
|
||||
if (!rc && retlen != part->header_size)
|
||||
rc = -EIO;
|
||||
@ -250,8 +250,8 @@ static int rfd_ftl_readsect(struct mtd_blktrans_dev *dev, u_long sector, char *b
|
||||
|
||||
addr = part->sector_map[sector];
|
||||
if (addr != -1) {
|
||||
rc = part->mbd.mtd->read(part->mbd.mtd, addr, SECTOR_SIZE,
|
||||
&retlen, (u_char*)buf);
|
||||
rc = mtd_read(part->mbd.mtd, addr, SECTOR_SIZE, &retlen,
|
||||
(u_char *)buf);
|
||||
if (!rc && retlen != SECTOR_SIZE)
|
||||
rc = -EIO;
|
||||
|
||||
@ -304,9 +304,8 @@ static void erase_callback(struct erase_info *erase)
|
||||
part->blocks[i].used_sectors = 0;
|
||||
part->blocks[i].erases++;
|
||||
|
||||
rc = part->mbd.mtd->write(part->mbd.mtd,
|
||||
part->blocks[i].offset, sizeof(magic), &retlen,
|
||||
(u_char*)&magic);
|
||||
rc = mtd_write(part->mbd.mtd, part->blocks[i].offset, sizeof(magic),
|
||||
&retlen, (u_char *)&magic);
|
||||
|
||||
if (!rc && retlen != sizeof(magic))
|
||||
rc = -EIO;
|
||||
@ -342,7 +341,7 @@ static int erase_block(struct partition *part, int block)
|
||||
part->blocks[block].state = BLOCK_ERASING;
|
||||
part->blocks[block].free_sectors = 0;
|
||||
|
||||
rc = part->mbd.mtd->erase(part->mbd.mtd, erase);
|
||||
rc = mtd_erase(part->mbd.mtd, erase);
|
||||
|
||||
if (rc) {
|
||||
printk(KERN_ERR PREFIX "erase of region %llx,%llx on '%s' "
|
||||
@ -372,9 +371,8 @@ static int move_block_contents(struct partition *part, int block_no, u_long *old
|
||||
if (!map)
|
||||
goto err2;
|
||||
|
||||
rc = part->mbd.mtd->read(part->mbd.mtd,
|
||||
part->blocks[block_no].offset, part->header_size,
|
||||
&retlen, (u_char*)map);
|
||||
rc = mtd_read(part->mbd.mtd, part->blocks[block_no].offset,
|
||||
part->header_size, &retlen, (u_char *)map);
|
||||
|
||||
if (!rc && retlen != part->header_size)
|
||||
rc = -EIO;
|
||||
@ -413,8 +411,8 @@ static int move_block_contents(struct partition *part, int block_no, u_long *old
|
||||
}
|
||||
continue;
|
||||
}
|
||||
rc = part->mbd.mtd->read(part->mbd.mtd, addr,
|
||||
SECTOR_SIZE, &retlen, sector_data);
|
||||
rc = mtd_read(part->mbd.mtd, addr, SECTOR_SIZE, &retlen,
|
||||
sector_data);
|
||||
|
||||
if (!rc && retlen != SECTOR_SIZE)
|
||||
rc = -EIO;
|
||||
@ -450,8 +448,7 @@ static int reclaim_block(struct partition *part, u_long *old_sector)
|
||||
int rc;
|
||||
|
||||
/* we have a race if sync doesn't exist */
|
||||
if (part->mbd.mtd->sync)
|
||||
part->mbd.mtd->sync(part->mbd.mtd);
|
||||
mtd_sync(part->mbd.mtd);
|
||||
|
||||
score = 0x7fffffff; /* MAX_INT */
|
||||
best_block = -1;
|
||||
@ -563,8 +560,9 @@ static int find_writable_block(struct partition *part, u_long *old_sector)
|
||||
}
|
||||
}
|
||||
|
||||
rc = part->mbd.mtd->read(part->mbd.mtd, part->blocks[block].offset,
|
||||
part->header_size, &retlen, (u_char*)part->header_cache);
|
||||
rc = mtd_read(part->mbd.mtd, part->blocks[block].offset,
|
||||
part->header_size, &retlen,
|
||||
(u_char *)part->header_cache);
|
||||
|
||||
if (!rc && retlen != part->header_size)
|
||||
rc = -EIO;
|
||||
@ -595,8 +593,8 @@ static int mark_sector_deleted(struct partition *part, u_long old_addr)
|
||||
|
||||
addr = part->blocks[block].offset +
|
||||
(HEADER_MAP_OFFSET + offset) * sizeof(u16);
|
||||
rc = part->mbd.mtd->write(part->mbd.mtd, addr,
|
||||
sizeof(del), &retlen, (u_char*)&del);
|
||||
rc = mtd_write(part->mbd.mtd, addr, sizeof(del), &retlen,
|
||||
(u_char *)&del);
|
||||
|
||||
if (!rc && retlen != sizeof(del))
|
||||
rc = -EIO;
|
||||
@ -668,8 +666,8 @@ static int do_writesect(struct mtd_blktrans_dev *dev, u_long sector, char *buf,
|
||||
|
||||
addr = (i + part->header_sectors_per_block) * SECTOR_SIZE +
|
||||
block->offset;
|
||||
rc = part->mbd.mtd->write(part->mbd.mtd,
|
||||
addr, SECTOR_SIZE, &retlen, (u_char*)buf);
|
||||
rc = mtd_write(part->mbd.mtd, addr, SECTOR_SIZE, &retlen,
|
||||
(u_char *)buf);
|
||||
|
||||
if (!rc && retlen != SECTOR_SIZE)
|
||||
rc = -EIO;
|
||||
@ -688,8 +686,8 @@ static int do_writesect(struct mtd_blktrans_dev *dev, u_long sector, char *buf,
|
||||
part->header_cache[i + HEADER_MAP_OFFSET] = entry;
|
||||
|
||||
addr = block->offset + (HEADER_MAP_OFFSET + i) * sizeof(u16);
|
||||
rc = part->mbd.mtd->write(part->mbd.mtd, addr,
|
||||
sizeof(entry), &retlen, (u_char*)&entry);
|
||||
rc = mtd_write(part->mbd.mtd, addr, sizeof(entry), &retlen,
|
||||
(u_char *)&entry);
|
||||
|
||||
if (!rc && retlen != sizeof(entry))
|
||||
rc = -EIO;
|
||||
|
@ -25,7 +25,7 @@
|
||||
struct workqueue_struct *cache_flush_workqueue;
|
||||
|
||||
static int cache_timeout = 1000;
|
||||
module_param(cache_timeout, bool, S_IRUGO);
|
||||
module_param(cache_timeout, int, S_IRUGO);
|
||||
MODULE_PARM_DESC(cache_timeout,
|
||||
"Timeout (in ms) for cache flush (1000 ms default");
|
||||
|
||||
@ -278,7 +278,7 @@ again:
|
||||
|
||||
/* Unfortunately, oob read will _always_ succeed,
|
||||
despite card removal..... */
|
||||
ret = mtd->read_oob(mtd, sm_mkoffset(ftl, zone, block, boffset), &ops);
|
||||
ret = mtd_read_oob(mtd, sm_mkoffset(ftl, zone, block, boffset), &ops);
|
||||
|
||||
/* Test for unknown errors */
|
||||
if (ret != 0 && !mtd_is_bitflip_or_eccerr(ret)) {
|
||||
@ -343,7 +343,7 @@ static int sm_write_sector(struct sm_ftl *ftl,
|
||||
ops.ooblen = SM_OOB_SIZE;
|
||||
ops.oobbuf = (void *)oob;
|
||||
|
||||
ret = mtd->write_oob(mtd, sm_mkoffset(ftl, zone, block, boffset), &ops);
|
||||
ret = mtd_write_oob(mtd, sm_mkoffset(ftl, zone, block, boffset), &ops);
|
||||
|
||||
/* Now we assume that hardware will catch write bitflip errors */
|
||||
/* If you are paranoid, use CONFIG_MTD_NAND_VERIFY_WRITE */
|
||||
@ -479,7 +479,7 @@ static int sm_erase_block(struct sm_ftl *ftl, int zone_num, uint16_t block,
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
if (mtd->erase(mtd, &erase)) {
|
||||
if (mtd_erase(mtd, &erase)) {
|
||||
sm_printk("erase of block %d in zone %d failed",
|
||||
block, zone_num);
|
||||
goto error;
|
||||
@ -645,8 +645,8 @@ int sm_get_media_info(struct sm_ftl *ftl, struct mtd_info *mtd)
|
||||
if (!ftl->smallpagenand && mtd->oobsize < SM_OOB_SIZE)
|
||||
return -ENODEV;
|
||||
|
||||
/* We use these functions for IO */
|
||||
if (!mtd->read_oob || !mtd->write_oob)
|
||||
/* We use OOB */
|
||||
if (!mtd_has_oob(mtd))
|
||||
return -ENODEV;
|
||||
|
||||
/* Find geometry information */
|
||||
|
@ -122,9 +122,9 @@ static int get_valid_cis_sector(struct mtd_info *mtd)
|
||||
* is not SSFDC formatted
|
||||
*/
|
||||
for (k = 0, offset = 0; k < 4; k++, offset += mtd->erasesize) {
|
||||
if (!mtd->block_isbad(mtd, offset)) {
|
||||
ret = mtd->read(mtd, offset, SECTOR_SIZE, &retlen,
|
||||
sect_buf);
|
||||
if (mtd_block_isbad(mtd, offset)) {
|
||||
ret = mtd_read(mtd, offset, SECTOR_SIZE, &retlen,
|
||||
sect_buf);
|
||||
|
||||
/* CIS pattern match on the sector buffer */
|
||||
if (ret < 0 || retlen != SECTOR_SIZE) {
|
||||
@ -156,7 +156,7 @@ static int read_physical_sector(struct mtd_info *mtd, uint8_t *sect_buf,
|
||||
size_t retlen;
|
||||
loff_t offset = (loff_t)sect_no << SECTOR_SHIFT;
|
||||
|
||||
ret = mtd->read(mtd, offset, SECTOR_SIZE, &retlen, sect_buf);
|
||||
ret = mtd_read(mtd, offset, SECTOR_SIZE, &retlen, sect_buf);
|
||||
if (ret < 0 || retlen != SECTOR_SIZE)
|
||||
return -1;
|
||||
|
||||
@ -175,7 +175,7 @@ static int read_raw_oob(struct mtd_info *mtd, loff_t offs, uint8_t *buf)
|
||||
ops.oobbuf = buf;
|
||||
ops.datbuf = NULL;
|
||||
|
||||
ret = mtd->read_oob(mtd, offs, &ops);
|
||||
ret = mtd_read_oob(mtd, offs, &ops);
|
||||
if (ret < 0 || ops.oobretlen != OOB_SIZE)
|
||||
return -1;
|
||||
|
||||
@ -255,7 +255,7 @@ static int build_logical_block_map(struct ssfdcr_record *ssfdc)
|
||||
for (phys_block = ssfdc->cis_block + 1; phys_block < ssfdc->map_len;
|
||||
phys_block++) {
|
||||
offset = (unsigned long)phys_block * ssfdc->erase_size;
|
||||
if (mtd->block_isbad(mtd, offset))
|
||||
if (mtd_block_isbad(mtd, offset))
|
||||
continue; /* skip bad blocks */
|
||||
|
||||
ret = read_raw_oob(mtd, offset, oob_buf);
|
||||
|
@ -78,7 +78,7 @@ static int erase_eraseblock(int ebnum)
|
||||
ei.addr = addr;
|
||||
ei.len = mtd->erasesize;
|
||||
|
||||
err = mtd->erase(mtd, &ei);
|
||||
err = mtd_erase(mtd, &ei);
|
||||
if (err) {
|
||||
printk(PRINT_PREF "error %d while erasing EB %d\n", err, ebnum);
|
||||
return err;
|
||||
@ -139,7 +139,7 @@ static int write_eraseblock(int ebnum)
|
||||
ops.ooboffs = use_offset;
|
||||
ops.datbuf = NULL;
|
||||
ops.oobbuf = writebuf;
|
||||
err = mtd->write_oob(mtd, addr, &ops);
|
||||
err = mtd_write_oob(mtd, addr, &ops);
|
||||
if (err || ops.oobretlen != use_len) {
|
||||
printk(PRINT_PREF "error: writeoob failed at %#llx\n",
|
||||
(long long)addr);
|
||||
@ -192,7 +192,7 @@ static int verify_eraseblock(int ebnum)
|
||||
ops.ooboffs = use_offset;
|
||||
ops.datbuf = NULL;
|
||||
ops.oobbuf = readbuf;
|
||||
err = mtd->read_oob(mtd, addr, &ops);
|
||||
err = mtd_read_oob(mtd, addr, &ops);
|
||||
if (err || ops.oobretlen != use_len) {
|
||||
printk(PRINT_PREF "error: readoob failed at %#llx\n",
|
||||
(long long)addr);
|
||||
@ -219,7 +219,7 @@ static int verify_eraseblock(int ebnum)
|
||||
ops.ooboffs = 0;
|
||||
ops.datbuf = NULL;
|
||||
ops.oobbuf = readbuf;
|
||||
err = mtd->read_oob(mtd, addr, &ops);
|
||||
err = mtd_read_oob(mtd, addr, &ops);
|
||||
if (err || ops.oobretlen != mtd->ecclayout->oobavail) {
|
||||
printk(PRINT_PREF "error: readoob failed at "
|
||||
"%#llx\n", (long long)addr);
|
||||
@ -284,7 +284,7 @@ static int verify_eraseblock_in_one_go(int ebnum)
|
||||
ops.ooboffs = 0;
|
||||
ops.datbuf = NULL;
|
||||
ops.oobbuf = readbuf;
|
||||
err = mtd->read_oob(mtd, addr, &ops);
|
||||
err = mtd_read_oob(mtd, addr, &ops);
|
||||
if (err || ops.oobretlen != len) {
|
||||
printk(PRINT_PREF "error: readoob failed at %#llx\n",
|
||||
(long long)addr);
|
||||
@ -329,7 +329,7 @@ static int is_block_bad(int ebnum)
|
||||
int ret;
|
||||
loff_t addr = ebnum * mtd->erasesize;
|
||||
|
||||
ret = mtd->block_isbad(mtd, addr);
|
||||
ret = mtd_block_isbad(mtd, addr);
|
||||
if (ret)
|
||||
printk(PRINT_PREF "block %d is bad\n", ebnum);
|
||||
return ret;
|
||||
@ -524,7 +524,7 @@ static int __init mtd_oobtest_init(void)
|
||||
ops.oobbuf = writebuf;
|
||||
printk(PRINT_PREF "attempting to start write past end of OOB\n");
|
||||
printk(PRINT_PREF "an error is expected...\n");
|
||||
err = mtd->write_oob(mtd, addr0, &ops);
|
||||
err = mtd_write_oob(mtd, addr0, &ops);
|
||||
if (err) {
|
||||
printk(PRINT_PREF "error occurred as expected\n");
|
||||
err = 0;
|
||||
@ -544,7 +544,7 @@ static int __init mtd_oobtest_init(void)
|
||||
ops.oobbuf = readbuf;
|
||||
printk(PRINT_PREF "attempting to start read past end of OOB\n");
|
||||
printk(PRINT_PREF "an error is expected...\n");
|
||||
err = mtd->read_oob(mtd, addr0, &ops);
|
||||
err = mtd_read_oob(mtd, addr0, &ops);
|
||||
if (err) {
|
||||
printk(PRINT_PREF "error occurred as expected\n");
|
||||
err = 0;
|
||||
@ -568,7 +568,7 @@ static int __init mtd_oobtest_init(void)
|
||||
ops.oobbuf = writebuf;
|
||||
printk(PRINT_PREF "attempting to write past end of device\n");
|
||||
printk(PRINT_PREF "an error is expected...\n");
|
||||
err = mtd->write_oob(mtd, mtd->size - mtd->writesize, &ops);
|
||||
err = mtd_write_oob(mtd, mtd->size - mtd->writesize, &ops);
|
||||
if (err) {
|
||||
printk(PRINT_PREF "error occurred as expected\n");
|
||||
err = 0;
|
||||
@ -588,7 +588,7 @@ static int __init mtd_oobtest_init(void)
|
||||
ops.oobbuf = readbuf;
|
||||
printk(PRINT_PREF "attempting to read past end of device\n");
|
||||
printk(PRINT_PREF "an error is expected...\n");
|
||||
err = mtd->read_oob(mtd, mtd->size - mtd->writesize, &ops);
|
||||
err = mtd_read_oob(mtd, mtd->size - mtd->writesize, &ops);
|
||||
if (err) {
|
||||
printk(PRINT_PREF "error occurred as expected\n");
|
||||
err = 0;
|
||||
@ -612,7 +612,7 @@ static int __init mtd_oobtest_init(void)
|
||||
ops.oobbuf = writebuf;
|
||||
printk(PRINT_PREF "attempting to write past end of device\n");
|
||||
printk(PRINT_PREF "an error is expected...\n");
|
||||
err = mtd->write_oob(mtd, mtd->size - mtd->writesize, &ops);
|
||||
err = mtd_write_oob(mtd, mtd->size - mtd->writesize, &ops);
|
||||
if (err) {
|
||||
printk(PRINT_PREF "error occurred as expected\n");
|
||||
err = 0;
|
||||
@ -632,7 +632,7 @@ static int __init mtd_oobtest_init(void)
|
||||
ops.oobbuf = readbuf;
|
||||
printk(PRINT_PREF "attempting to read past end of device\n");
|
||||
printk(PRINT_PREF "an error is expected...\n");
|
||||
err = mtd->read_oob(mtd, mtd->size - mtd->writesize, &ops);
|
||||
err = mtd_read_oob(mtd, mtd->size - mtd->writesize, &ops);
|
||||
if (err) {
|
||||
printk(PRINT_PREF "error occurred as expected\n");
|
||||
err = 0;
|
||||
@ -670,7 +670,7 @@ static int __init mtd_oobtest_init(void)
|
||||
ops.ooboffs = 0;
|
||||
ops.datbuf = NULL;
|
||||
ops.oobbuf = writebuf;
|
||||
err = mtd->write_oob(mtd, addr, &ops);
|
||||
err = mtd_write_oob(mtd, addr, &ops);
|
||||
if (err)
|
||||
goto out;
|
||||
if (i % 256 == 0)
|
||||
@ -698,7 +698,7 @@ static int __init mtd_oobtest_init(void)
|
||||
ops.ooboffs = 0;
|
||||
ops.datbuf = NULL;
|
||||
ops.oobbuf = readbuf;
|
||||
err = mtd->read_oob(mtd, addr, &ops);
|
||||
err = mtd_read_oob(mtd, addr, &ops);
|
||||
if (err)
|
||||
goto out;
|
||||
if (memcmp(readbuf, writebuf, mtd->ecclayout->oobavail * 2)) {
|
||||
|
@ -77,7 +77,7 @@ static int erase_eraseblock(int ebnum)
|
||||
ei.addr = addr;
|
||||
ei.len = mtd->erasesize;
|
||||
|
||||
err = mtd->erase(mtd, &ei);
|
||||
err = mtd_erase(mtd, &ei);
|
||||
if (err) {
|
||||
printk(PRINT_PREF "error %d while erasing EB %d\n", err, ebnum);
|
||||
return err;
|
||||
@ -95,12 +95,12 @@ static int erase_eraseblock(int ebnum)
|
||||
static int write_eraseblock(int ebnum)
|
||||
{
|
||||
int err = 0;
|
||||
size_t written = 0;
|
||||
size_t written;
|
||||
loff_t addr = ebnum * mtd->erasesize;
|
||||
|
||||
set_random_data(writebuf, mtd->erasesize);
|
||||
cond_resched();
|
||||
err = mtd->write(mtd, addr, mtd->erasesize, &written, writebuf);
|
||||
err = mtd_write(mtd, addr, mtd->erasesize, &written, writebuf);
|
||||
if (err || written != mtd->erasesize)
|
||||
printk(PRINT_PREF "error: write failed at %#llx\n",
|
||||
(long long)addr);
|
||||
@ -111,7 +111,7 @@ static int write_eraseblock(int ebnum)
|
||||
static int verify_eraseblock(int ebnum)
|
||||
{
|
||||
uint32_t j;
|
||||
size_t read = 0;
|
||||
size_t read;
|
||||
int err = 0, i;
|
||||
loff_t addr0, addrn;
|
||||
loff_t addr = ebnum * mtd->erasesize;
|
||||
@ -127,7 +127,7 @@ static int verify_eraseblock(int ebnum)
|
||||
set_random_data(writebuf, mtd->erasesize);
|
||||
for (j = 0; j < pgcnt - 1; ++j, addr += pgsize) {
|
||||
/* Do a read to set the internal dataRAMs to different data */
|
||||
err = mtd->read(mtd, addr0, bufsize, &read, twopages);
|
||||
err = mtd_read(mtd, addr0, bufsize, &read, twopages);
|
||||
if (mtd_is_bitflip(err))
|
||||
err = 0;
|
||||
if (err || read != bufsize) {
|
||||
@ -135,7 +135,7 @@ static int verify_eraseblock(int ebnum)
|
||||
(long long)addr0);
|
||||
return err;
|
||||
}
|
||||
err = mtd->read(mtd, addrn - bufsize, bufsize, &read, twopages);
|
||||
err = mtd_read(mtd, addrn - bufsize, bufsize, &read, twopages);
|
||||
if (mtd_is_bitflip(err))
|
||||
err = 0;
|
||||
if (err || read != bufsize) {
|
||||
@ -144,8 +144,7 @@ static int verify_eraseblock(int ebnum)
|
||||
return err;
|
||||
}
|
||||
memset(twopages, 0, bufsize);
|
||||
read = 0;
|
||||
err = mtd->read(mtd, addr, bufsize, &read, twopages);
|
||||
err = mtd_read(mtd, addr, bufsize, &read, twopages);
|
||||
if (mtd_is_bitflip(err))
|
||||
err = 0;
|
||||
if (err || read != bufsize) {
|
||||
@ -163,7 +162,7 @@ static int verify_eraseblock(int ebnum)
|
||||
if (addr <= addrn - pgsize - pgsize && !bbt[ebnum + 1]) {
|
||||
unsigned long oldnext = next;
|
||||
/* Do a read to set the internal dataRAMs to different data */
|
||||
err = mtd->read(mtd, addr0, bufsize, &read, twopages);
|
||||
err = mtd_read(mtd, addr0, bufsize, &read, twopages);
|
||||
if (mtd_is_bitflip(err))
|
||||
err = 0;
|
||||
if (err || read != bufsize) {
|
||||
@ -171,7 +170,7 @@ static int verify_eraseblock(int ebnum)
|
||||
(long long)addr0);
|
||||
return err;
|
||||
}
|
||||
err = mtd->read(mtd, addrn - bufsize, bufsize, &read, twopages);
|
||||
err = mtd_read(mtd, addrn - bufsize, bufsize, &read, twopages);
|
||||
if (mtd_is_bitflip(err))
|
||||
err = 0;
|
||||
if (err || read != bufsize) {
|
||||
@ -180,8 +179,7 @@ static int verify_eraseblock(int ebnum)
|
||||
return err;
|
||||
}
|
||||
memset(twopages, 0, bufsize);
|
||||
read = 0;
|
||||
err = mtd->read(mtd, addr, bufsize, &read, twopages);
|
||||
err = mtd_read(mtd, addr, bufsize, &read, twopages);
|
||||
if (mtd_is_bitflip(err))
|
||||
err = 0;
|
||||
if (err || read != bufsize) {
|
||||
@ -203,7 +201,7 @@ static int verify_eraseblock(int ebnum)
|
||||
|
||||
static int crosstest(void)
|
||||
{
|
||||
size_t read = 0;
|
||||
size_t read;
|
||||
int err = 0, i;
|
||||
loff_t addr, addr0, addrn;
|
||||
unsigned char *pp1, *pp2, *pp3, *pp4;
|
||||
@ -228,9 +226,8 @@ static int crosstest(void)
|
||||
addrn -= mtd->erasesize;
|
||||
|
||||
/* Read 2nd-to-last page to pp1 */
|
||||
read = 0;
|
||||
addr = addrn - pgsize - pgsize;
|
||||
err = mtd->read(mtd, addr, pgsize, &read, pp1);
|
||||
err = mtd_read(mtd, addr, pgsize, &read, pp1);
|
||||
if (mtd_is_bitflip(err))
|
||||
err = 0;
|
||||
if (err || read != pgsize) {
|
||||
@ -241,9 +238,8 @@ static int crosstest(void)
|
||||
}
|
||||
|
||||
/* Read 3rd-to-last page to pp1 */
|
||||
read = 0;
|
||||
addr = addrn - pgsize - pgsize - pgsize;
|
||||
err = mtd->read(mtd, addr, pgsize, &read, pp1);
|
||||
err = mtd_read(mtd, addr, pgsize, &read, pp1);
|
||||
if (mtd_is_bitflip(err))
|
||||
err = 0;
|
||||
if (err || read != pgsize) {
|
||||
@ -254,10 +250,9 @@ static int crosstest(void)
|
||||
}
|
||||
|
||||
/* Read first page to pp2 */
|
||||
read = 0;
|
||||
addr = addr0;
|
||||
printk(PRINT_PREF "reading page at %#llx\n", (long long)addr);
|
||||
err = mtd->read(mtd, addr, pgsize, &read, pp2);
|
||||
err = mtd_read(mtd, addr, pgsize, &read, pp2);
|
||||
if (mtd_is_bitflip(err))
|
||||
err = 0;
|
||||
if (err || read != pgsize) {
|
||||
@ -268,10 +263,9 @@ static int crosstest(void)
|
||||
}
|
||||
|
||||
/* Read last page to pp3 */
|
||||
read = 0;
|
||||
addr = addrn - pgsize;
|
||||
printk(PRINT_PREF "reading page at %#llx\n", (long long)addr);
|
||||
err = mtd->read(mtd, addr, pgsize, &read, pp3);
|
||||
err = mtd_read(mtd, addr, pgsize, &read, pp3);
|
||||
if (mtd_is_bitflip(err))
|
||||
err = 0;
|
||||
if (err || read != pgsize) {
|
||||
@ -282,10 +276,9 @@ static int crosstest(void)
|
||||
}
|
||||
|
||||
/* Read first page again to pp4 */
|
||||
read = 0;
|
||||
addr = addr0;
|
||||
printk(PRINT_PREF "reading page at %#llx\n", (long long)addr);
|
||||
err = mtd->read(mtd, addr, pgsize, &read, pp4);
|
||||
err = mtd_read(mtd, addr, pgsize, &read, pp4);
|
||||
if (mtd_is_bitflip(err))
|
||||
err = 0;
|
||||
if (err || read != pgsize) {
|
||||
@ -309,7 +302,7 @@ static int crosstest(void)
|
||||
|
||||
static int erasecrosstest(void)
|
||||
{
|
||||
size_t read = 0, written = 0;
|
||||
size_t read, written;
|
||||
int err = 0, i, ebnum, ebnum2;
|
||||
loff_t addr0;
|
||||
char *readbuf = twopages;
|
||||
@ -335,7 +328,7 @@ static int erasecrosstest(void)
|
||||
printk(PRINT_PREF "writing 1st page of block %d\n", ebnum);
|
||||
set_random_data(writebuf, pgsize);
|
||||
strcpy(writebuf, "There is no data like this!");
|
||||
err = mtd->write(mtd, addr0, pgsize, &written, writebuf);
|
||||
err = mtd_write(mtd, addr0, pgsize, &written, writebuf);
|
||||
if (err || written != pgsize) {
|
||||
printk(PRINT_PREF "error: write failed at %#llx\n",
|
||||
(long long)addr0);
|
||||
@ -344,7 +337,7 @@ static int erasecrosstest(void)
|
||||
|
||||
printk(PRINT_PREF "reading 1st page of block %d\n", ebnum);
|
||||
memset(readbuf, 0, pgsize);
|
||||
err = mtd->read(mtd, addr0, pgsize, &read, readbuf);
|
||||
err = mtd_read(mtd, addr0, pgsize, &read, readbuf);
|
||||
if (mtd_is_bitflip(err))
|
||||
err = 0;
|
||||
if (err || read != pgsize) {
|
||||
@ -368,7 +361,7 @@ static int erasecrosstest(void)
|
||||
printk(PRINT_PREF "writing 1st page of block %d\n", ebnum);
|
||||
set_random_data(writebuf, pgsize);
|
||||
strcpy(writebuf, "There is no data like this!");
|
||||
err = mtd->write(mtd, addr0, pgsize, &written, writebuf);
|
||||
err = mtd_write(mtd, addr0, pgsize, &written, writebuf);
|
||||
if (err || written != pgsize) {
|
||||
printk(PRINT_PREF "error: write failed at %#llx\n",
|
||||
(long long)addr0);
|
||||
@ -382,7 +375,7 @@ static int erasecrosstest(void)
|
||||
|
||||
printk(PRINT_PREF "reading 1st page of block %d\n", ebnum);
|
||||
memset(readbuf, 0, pgsize);
|
||||
err = mtd->read(mtd, addr0, pgsize, &read, readbuf);
|
||||
err = mtd_read(mtd, addr0, pgsize, &read, readbuf);
|
||||
if (mtd_is_bitflip(err))
|
||||
err = 0;
|
||||
if (err || read != pgsize) {
|
||||
@ -405,7 +398,7 @@ static int erasecrosstest(void)
|
||||
|
||||
static int erasetest(void)
|
||||
{
|
||||
size_t read = 0, written = 0;
|
||||
size_t read, written;
|
||||
int err = 0, i, ebnum, ok = 1;
|
||||
loff_t addr0;
|
||||
|
||||
@ -425,7 +418,7 @@ static int erasetest(void)
|
||||
|
||||
printk(PRINT_PREF "writing 1st page of block %d\n", ebnum);
|
||||
set_random_data(writebuf, pgsize);
|
||||
err = mtd->write(mtd, addr0, pgsize, &written, writebuf);
|
||||
err = mtd_write(mtd, addr0, pgsize, &written, writebuf);
|
||||
if (err || written != pgsize) {
|
||||
printk(PRINT_PREF "error: write failed at %#llx\n",
|
||||
(long long)addr0);
|
||||
@ -438,7 +431,7 @@ static int erasetest(void)
|
||||
return err;
|
||||
|
||||
printk(PRINT_PREF "reading 1st page of block %d\n", ebnum);
|
||||
err = mtd->read(mtd, addr0, pgsize, &read, twopages);
|
||||
err = mtd_read(mtd, addr0, pgsize, &read, twopages);
|
||||
if (mtd_is_bitflip(err))
|
||||
err = 0;
|
||||
if (err || read != pgsize) {
|
||||
@ -469,7 +462,7 @@ static int is_block_bad(int ebnum)
|
||||
loff_t addr = ebnum * mtd->erasesize;
|
||||
int ret;
|
||||
|
||||
ret = mtd->block_isbad(mtd, addr);
|
||||
ret = mtd_block_isbad(mtd, addr);
|
||||
if (ret)
|
||||
printk(PRINT_PREF "block %d is bad\n", ebnum);
|
||||
return ret;
|
||||
|
@ -44,7 +44,7 @@ static int pgcnt;
|
||||
|
||||
static int read_eraseblock_by_page(int ebnum)
|
||||
{
|
||||
size_t read = 0;
|
||||
size_t read;
|
||||
int i, ret, err = 0;
|
||||
loff_t addr = ebnum * mtd->erasesize;
|
||||
void *buf = iobuf;
|
||||
@ -52,7 +52,7 @@ static int read_eraseblock_by_page(int ebnum)
|
||||
|
||||
for (i = 0; i < pgcnt; i++) {
|
||||
memset(buf, 0 , pgcnt);
|
||||
ret = mtd->read(mtd, addr, pgsize, &read, buf);
|
||||
ret = mtd_read(mtd, addr, pgsize, &read, buf);
|
||||
if (ret == -EUCLEAN)
|
||||
ret = 0;
|
||||
if (ret || read != pgsize) {
|
||||
@ -74,7 +74,7 @@ static int read_eraseblock_by_page(int ebnum)
|
||||
ops.ooboffs = 0;
|
||||
ops.datbuf = NULL;
|
||||
ops.oobbuf = oobbuf;
|
||||
ret = mtd->read_oob(mtd, addr, &ops);
|
||||
ret = mtd_read_oob(mtd, addr, &ops);
|
||||
if ((ret && !mtd_is_bitflip(ret)) ||
|
||||
ops.oobretlen != mtd->oobsize) {
|
||||
printk(PRINT_PREF "error: read oob failed at "
|
||||
@ -132,7 +132,7 @@ static int is_block_bad(int ebnum)
|
||||
loff_t addr = ebnum * mtd->erasesize;
|
||||
int ret;
|
||||
|
||||
ret = mtd->block_isbad(mtd, addr);
|
||||
ret = mtd_block_isbad(mtd, addr);
|
||||
if (ret)
|
||||
printk(PRINT_PREF "block %d is bad\n", ebnum);
|
||||
return ret;
|
||||
@ -148,8 +148,7 @@ static int scan_for_bad_eraseblocks(void)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* NOR flash does not implement block_isbad */
|
||||
if (mtd->block_isbad == NULL)
|
||||
if (!mtd_can_have_bb(mtd))
|
||||
return 0;
|
||||
|
||||
printk(PRINT_PREF "scanning for bad eraseblocks\n");
|
||||
|
@ -79,7 +79,7 @@ static int erase_eraseblock(int ebnum)
|
||||
ei.addr = addr;
|
||||
ei.len = mtd->erasesize;
|
||||
|
||||
err = mtd->erase(mtd, &ei);
|
||||
err = mtd_erase(mtd, &ei);
|
||||
if (err) {
|
||||
printk(PRINT_PREF "error %d while erasing EB %d\n", err, ebnum);
|
||||
return err;
|
||||
@ -105,7 +105,7 @@ static int multiblock_erase(int ebnum, int blocks)
|
||||
ei.addr = addr;
|
||||
ei.len = mtd->erasesize * blocks;
|
||||
|
||||
err = mtd->erase(mtd, &ei);
|
||||
err = mtd_erase(mtd, &ei);
|
||||
if (err) {
|
||||
printk(PRINT_PREF "error %d while erasing EB %d, blocks %d\n",
|
||||
err, ebnum, blocks);
|
||||
@ -139,11 +139,11 @@ static int erase_whole_device(void)
|
||||
|
||||
static int write_eraseblock(int ebnum)
|
||||
{
|
||||
size_t written = 0;
|
||||
size_t written;
|
||||
int err = 0;
|
||||
loff_t addr = ebnum * mtd->erasesize;
|
||||
|
||||
err = mtd->write(mtd, addr, mtd->erasesize, &written, iobuf);
|
||||
err = mtd_write(mtd, addr, mtd->erasesize, &written, iobuf);
|
||||
if (err || written != mtd->erasesize) {
|
||||
printk(PRINT_PREF "error: write failed at %#llx\n", addr);
|
||||
if (!err)
|
||||
@ -155,13 +155,13 @@ static int write_eraseblock(int ebnum)
|
||||
|
||||
static int write_eraseblock_by_page(int ebnum)
|
||||
{
|
||||
size_t written = 0;
|
||||
size_t written;
|
||||
int i, err = 0;
|
||||
loff_t addr = ebnum * mtd->erasesize;
|
||||
void *buf = iobuf;
|
||||
|
||||
for (i = 0; i < pgcnt; i++) {
|
||||
err = mtd->write(mtd, addr, pgsize, &written, buf);
|
||||
err = mtd_write(mtd, addr, pgsize, &written, buf);
|
||||
if (err || written != pgsize) {
|
||||
printk(PRINT_PREF "error: write failed at %#llx\n",
|
||||
addr);
|
||||
@ -178,13 +178,13 @@ static int write_eraseblock_by_page(int ebnum)
|
||||
|
||||
static int write_eraseblock_by_2pages(int ebnum)
|
||||
{
|
||||
size_t written = 0, sz = pgsize * 2;
|
||||
size_t written, sz = pgsize * 2;
|
||||
int i, n = pgcnt / 2, err = 0;
|
||||
loff_t addr = ebnum * mtd->erasesize;
|
||||
void *buf = iobuf;
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
err = mtd->write(mtd, addr, sz, &written, buf);
|
||||
err = mtd_write(mtd, addr, sz, &written, buf);
|
||||
if (err || written != sz) {
|
||||
printk(PRINT_PREF "error: write failed at %#llx\n",
|
||||
addr);
|
||||
@ -196,7 +196,7 @@ static int write_eraseblock_by_2pages(int ebnum)
|
||||
buf += sz;
|
||||
}
|
||||
if (pgcnt % 2) {
|
||||
err = mtd->write(mtd, addr, pgsize, &written, buf);
|
||||
err = mtd_write(mtd, addr, pgsize, &written, buf);
|
||||
if (err || written != pgsize) {
|
||||
printk(PRINT_PREF "error: write failed at %#llx\n",
|
||||
addr);
|
||||
@ -210,11 +210,11 @@ static int write_eraseblock_by_2pages(int ebnum)
|
||||
|
||||
static int read_eraseblock(int ebnum)
|
||||
{
|
||||
size_t read = 0;
|
||||
size_t read;
|
||||
int err = 0;
|
||||
loff_t addr = ebnum * mtd->erasesize;
|
||||
|
||||
err = mtd->read(mtd, addr, mtd->erasesize, &read, iobuf);
|
||||
err = mtd_read(mtd, addr, mtd->erasesize, &read, iobuf);
|
||||
/* Ignore corrected ECC errors */
|
||||
if (mtd_is_bitflip(err))
|
||||
err = 0;
|
||||
@ -229,13 +229,13 @@ static int read_eraseblock(int ebnum)
|
||||
|
||||
static int read_eraseblock_by_page(int ebnum)
|
||||
{
|
||||
size_t read = 0;
|
||||
size_t read;
|
||||
int i, err = 0;
|
||||
loff_t addr = ebnum * mtd->erasesize;
|
||||
void *buf = iobuf;
|
||||
|
||||
for (i = 0; i < pgcnt; i++) {
|
||||
err = mtd->read(mtd, addr, pgsize, &read, buf);
|
||||
err = mtd_read(mtd, addr, pgsize, &read, buf);
|
||||
/* Ignore corrected ECC errors */
|
||||
if (mtd_is_bitflip(err))
|
||||
err = 0;
|
||||
@ -255,13 +255,13 @@ static int read_eraseblock_by_page(int ebnum)
|
||||
|
||||
static int read_eraseblock_by_2pages(int ebnum)
|
||||
{
|
||||
size_t read = 0, sz = pgsize * 2;
|
||||
size_t read, sz = pgsize * 2;
|
||||
int i, n = pgcnt / 2, err = 0;
|
||||
loff_t addr = ebnum * mtd->erasesize;
|
||||
void *buf = iobuf;
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
err = mtd->read(mtd, addr, sz, &read, buf);
|
||||
err = mtd_read(mtd, addr, sz, &read, buf);
|
||||
/* Ignore corrected ECC errors */
|
||||
if (mtd_is_bitflip(err))
|
||||
err = 0;
|
||||
@ -276,7 +276,7 @@ static int read_eraseblock_by_2pages(int ebnum)
|
||||
buf += sz;
|
||||
}
|
||||
if (pgcnt % 2) {
|
||||
err = mtd->read(mtd, addr, pgsize, &read, buf);
|
||||
err = mtd_read(mtd, addr, pgsize, &read, buf);
|
||||
/* Ignore corrected ECC errors */
|
||||
if (mtd_is_bitflip(err))
|
||||
err = 0;
|
||||
@ -296,7 +296,7 @@ static int is_block_bad(int ebnum)
|
||||
loff_t addr = ebnum * mtd->erasesize;
|
||||
int ret;
|
||||
|
||||
ret = mtd->block_isbad(mtd, addr);
|
||||
ret = mtd_block_isbad(mtd, addr);
|
||||
if (ret)
|
||||
printk(PRINT_PREF "block %d is bad\n", ebnum);
|
||||
return ret;
|
||||
@ -336,8 +336,7 @@ static int scan_for_bad_eraseblocks(void)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* NOR flash does not implement block_isbad */
|
||||
if (mtd->block_isbad == NULL)
|
||||
if (!mtd_can_have_bb(mtd))
|
||||
goto out;
|
||||
|
||||
printk(PRINT_PREF "scanning for bad eraseblocks\n");
|
||||
|
@ -112,7 +112,7 @@ static int erase_eraseblock(int ebnum)
|
||||
ei.addr = addr;
|
||||
ei.len = mtd->erasesize;
|
||||
|
||||
err = mtd->erase(mtd, &ei);
|
||||
err = mtd_erase(mtd, &ei);
|
||||
if (unlikely(err)) {
|
||||
printk(PRINT_PREF "error %d while erasing EB %d\n", err, ebnum);
|
||||
return err;
|
||||
@ -132,7 +132,7 @@ static int is_block_bad(int ebnum)
|
||||
loff_t addr = ebnum * mtd->erasesize;
|
||||
int ret;
|
||||
|
||||
ret = mtd->block_isbad(mtd, addr);
|
||||
ret = mtd_block_isbad(mtd, addr);
|
||||
if (ret)
|
||||
printk(PRINT_PREF "block %d is bad\n", ebnum);
|
||||
return ret;
|
||||
@ -140,7 +140,7 @@ static int is_block_bad(int ebnum)
|
||||
|
||||
static int do_read(void)
|
||||
{
|
||||
size_t read = 0;
|
||||
size_t read;
|
||||
int eb = rand_eb();
|
||||
int offs = rand_offs();
|
||||
int len = rand_len(offs), err;
|
||||
@ -153,7 +153,7 @@ static int do_read(void)
|
||||
len = mtd->erasesize - offs;
|
||||
}
|
||||
addr = eb * mtd->erasesize + offs;
|
||||
err = mtd->read(mtd, addr, len, &read, readbuf);
|
||||
err = mtd_read(mtd, addr, len, &read, readbuf);
|
||||
if (mtd_is_bitflip(err))
|
||||
err = 0;
|
||||
if (unlikely(err || read != len)) {
|
||||
@ -169,7 +169,7 @@ static int do_read(void)
|
||||
static int do_write(void)
|
||||
{
|
||||
int eb = rand_eb(), offs, err, len;
|
||||
size_t written = 0;
|
||||
size_t written;
|
||||
loff_t addr;
|
||||
|
||||
offs = offsets[eb];
|
||||
@ -192,7 +192,7 @@ static int do_write(void)
|
||||
}
|
||||
}
|
||||
addr = eb * mtd->erasesize + offs;
|
||||
err = mtd->write(mtd, addr, len, &written, writebuf);
|
||||
err = mtd_write(mtd, addr, len, &written, writebuf);
|
||||
if (unlikely(err || written != len)) {
|
||||
printk(PRINT_PREF "error: write failed at 0x%llx\n",
|
||||
(long long)addr);
|
||||
@ -227,8 +227,7 @@ static int scan_for_bad_eraseblocks(void)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* NOR flash does not implement block_isbad */
|
||||
if (mtd->block_isbad == NULL)
|
||||
if (!mtd_can_have_bb(mtd))
|
||||
return 0;
|
||||
|
||||
printk(PRINT_PREF "scanning for bad eraseblocks\n");
|
||||
@ -284,6 +283,12 @@ static int __init mtd_stresstest_init(void)
|
||||
(unsigned long long)mtd->size, mtd->erasesize,
|
||||
pgsize, ebcnt, pgcnt, mtd->oobsize);
|
||||
|
||||
if (ebcnt < 2) {
|
||||
printk(PRINT_PREF "error: need at least 2 eraseblocks\n");
|
||||
err = -ENOSPC;
|
||||
goto out_put_mtd;
|
||||
}
|
||||
|
||||
/* Read or write up 2 eraseblocks at a time */
|
||||
bufsize = mtd->erasesize * 2;
|
||||
|
||||
@ -322,6 +327,7 @@ out:
|
||||
kfree(bbt);
|
||||
vfree(writebuf);
|
||||
vfree(readbuf);
|
||||
out_put_mtd:
|
||||
put_mtd_device(mtd);
|
||||
if (err)
|
||||
printk(PRINT_PREF "error %d occurred\n", err);
|
||||
|
@ -80,7 +80,7 @@ static int erase_eraseblock(int ebnum)
|
||||
ei.addr = addr;
|
||||
ei.len = mtd->erasesize;
|
||||
|
||||
err = mtd->erase(mtd, &ei);
|
||||
err = mtd_erase(mtd, &ei);
|
||||
if (err) {
|
||||
printk(PRINT_PREF "error %d while erasing EB %d\n", err, ebnum);
|
||||
return err;
|
||||
@ -115,12 +115,12 @@ static int erase_whole_device(void)
|
||||
|
||||
static int write_eraseblock(int ebnum)
|
||||
{
|
||||
size_t written = 0;
|
||||
size_t written;
|
||||
int err = 0;
|
||||
loff_t addr = ebnum * mtd->erasesize;
|
||||
|
||||
set_random_data(writebuf, subpgsize);
|
||||
err = mtd->write(mtd, addr, subpgsize, &written, writebuf);
|
||||
err = mtd_write(mtd, addr, subpgsize, &written, writebuf);
|
||||
if (unlikely(err || written != subpgsize)) {
|
||||
printk(PRINT_PREF "error: write failed at %#llx\n",
|
||||
(long long)addr);
|
||||
@ -134,7 +134,7 @@ static int write_eraseblock(int ebnum)
|
||||
addr += subpgsize;
|
||||
|
||||
set_random_data(writebuf, subpgsize);
|
||||
err = mtd->write(mtd, addr, subpgsize, &written, writebuf);
|
||||
err = mtd_write(mtd, addr, subpgsize, &written, writebuf);
|
||||
if (unlikely(err || written != subpgsize)) {
|
||||
printk(PRINT_PREF "error: write failed at %#llx\n",
|
||||
(long long)addr);
|
||||
@ -150,7 +150,7 @@ static int write_eraseblock(int ebnum)
|
||||
|
||||
static int write_eraseblock2(int ebnum)
|
||||
{
|
||||
size_t written = 0;
|
||||
size_t written;
|
||||
int err = 0, k;
|
||||
loff_t addr = ebnum * mtd->erasesize;
|
||||
|
||||
@ -158,7 +158,7 @@ static int write_eraseblock2(int ebnum)
|
||||
if (addr + (subpgsize * k) > (ebnum + 1) * mtd->erasesize)
|
||||
break;
|
||||
set_random_data(writebuf, subpgsize * k);
|
||||
err = mtd->write(mtd, addr, subpgsize * k, &written, writebuf);
|
||||
err = mtd_write(mtd, addr, subpgsize * k, &written, writebuf);
|
||||
if (unlikely(err || written != subpgsize * k)) {
|
||||
printk(PRINT_PREF "error: write failed at %#llx\n",
|
||||
(long long)addr);
|
||||
@ -189,14 +189,13 @@ static void print_subpage(unsigned char *p)
|
||||
|
||||
static int verify_eraseblock(int ebnum)
|
||||
{
|
||||
size_t read = 0;
|
||||
size_t read;
|
||||
int err = 0;
|
||||
loff_t addr = ebnum * mtd->erasesize;
|
||||
|
||||
set_random_data(writebuf, subpgsize);
|
||||
clear_data(readbuf, subpgsize);
|
||||
read = 0;
|
||||
err = mtd->read(mtd, addr, subpgsize, &read, readbuf);
|
||||
err = mtd_read(mtd, addr, subpgsize, &read, readbuf);
|
||||
if (unlikely(err || read != subpgsize)) {
|
||||
if (mtd_is_bitflip(err) && read == subpgsize) {
|
||||
printk(PRINT_PREF "ECC correction at %#llx\n",
|
||||
@ -223,8 +222,7 @@ static int verify_eraseblock(int ebnum)
|
||||
|
||||
set_random_data(writebuf, subpgsize);
|
||||
clear_data(readbuf, subpgsize);
|
||||
read = 0;
|
||||
err = mtd->read(mtd, addr, subpgsize, &read, readbuf);
|
||||
err = mtd_read(mtd, addr, subpgsize, &read, readbuf);
|
||||
if (unlikely(err || read != subpgsize)) {
|
||||
if (mtd_is_bitflip(err) && read == subpgsize) {
|
||||
printk(PRINT_PREF "ECC correction at %#llx\n",
|
||||
@ -252,7 +250,7 @@ static int verify_eraseblock(int ebnum)
|
||||
|
||||
static int verify_eraseblock2(int ebnum)
|
||||
{
|
||||
size_t read = 0;
|
||||
size_t read;
|
||||
int err = 0, k;
|
||||
loff_t addr = ebnum * mtd->erasesize;
|
||||
|
||||
@ -261,8 +259,7 @@ static int verify_eraseblock2(int ebnum)
|
||||
break;
|
||||
set_random_data(writebuf, subpgsize * k);
|
||||
clear_data(readbuf, subpgsize * k);
|
||||
read = 0;
|
||||
err = mtd->read(mtd, addr, subpgsize * k, &read, readbuf);
|
||||
err = mtd_read(mtd, addr, subpgsize * k, &read, readbuf);
|
||||
if (unlikely(err || read != subpgsize * k)) {
|
||||
if (mtd_is_bitflip(err) && read == subpgsize * k) {
|
||||
printk(PRINT_PREF "ECC correction at %#llx\n",
|
||||
@ -288,15 +285,14 @@ static int verify_eraseblock2(int ebnum)
|
||||
static int verify_eraseblock_ff(int ebnum)
|
||||
{
|
||||
uint32_t j;
|
||||
size_t read = 0;
|
||||
size_t read;
|
||||
int err = 0;
|
||||
loff_t addr = ebnum * mtd->erasesize;
|
||||
|
||||
memset(writebuf, 0xff, subpgsize);
|
||||
for (j = 0; j < mtd->erasesize / subpgsize; ++j) {
|
||||
clear_data(readbuf, subpgsize);
|
||||
read = 0;
|
||||
err = mtd->read(mtd, addr, subpgsize, &read, readbuf);
|
||||
err = mtd_read(mtd, addr, subpgsize, &read, readbuf);
|
||||
if (unlikely(err || read != subpgsize)) {
|
||||
if (mtd_is_bitflip(err) && read == subpgsize) {
|
||||
printk(PRINT_PREF "ECC correction at %#llx\n",
|
||||
@ -344,7 +340,7 @@ static int is_block_bad(int ebnum)
|
||||
loff_t addr = ebnum * mtd->erasesize;
|
||||
int ret;
|
||||
|
||||
ret = mtd->block_isbad(mtd, addr);
|
||||
ret = mtd_block_isbad(mtd, addr);
|
||||
if (ret)
|
||||
printk(PRINT_PREF "block %d is bad\n", ebnum);
|
||||
return ret;
|
||||
|
@ -105,7 +105,7 @@ static inline int erase_eraseblock(int ebnum)
|
||||
ei.addr = addr;
|
||||
ei.len = mtd->erasesize;
|
||||
|
||||
err = mtd->erase(mtd, &ei);
|
||||
err = mtd_erase(mtd, &ei);
|
||||
if (err) {
|
||||
printk(PRINT_PREF "error %d while erasing EB %d\n", err, ebnum);
|
||||
return err;
|
||||
@ -127,7 +127,7 @@ static inline int erase_eraseblock(int ebnum)
|
||||
static inline int check_eraseblock(int ebnum, unsigned char *buf)
|
||||
{
|
||||
int err, retries = 0;
|
||||
size_t read = 0;
|
||||
size_t read;
|
||||
loff_t addr = ebnum * mtd->erasesize;
|
||||
size_t len = mtd->erasesize;
|
||||
|
||||
@ -137,7 +137,7 @@ static inline int check_eraseblock(int ebnum, unsigned char *buf)
|
||||
}
|
||||
|
||||
retry:
|
||||
err = mtd->read(mtd, addr, len, &read, check_buf);
|
||||
err = mtd_read(mtd, addr, len, &read, check_buf);
|
||||
if (mtd_is_bitflip(err))
|
||||
printk(PRINT_PREF "single bit flip occurred at EB %d "
|
||||
"MTD reported that it was fixed.\n", ebnum);
|
||||
@ -181,7 +181,7 @@ retry:
|
||||
static inline int write_pattern(int ebnum, void *buf)
|
||||
{
|
||||
int err;
|
||||
size_t written = 0;
|
||||
size_t written;
|
||||
loff_t addr = ebnum * mtd->erasesize;
|
||||
size_t len = mtd->erasesize;
|
||||
|
||||
@ -189,7 +189,7 @@ static inline int write_pattern(int ebnum, void *buf)
|
||||
addr = (ebnum + 1) * mtd->erasesize - pgcnt * pgsize;
|
||||
len = pgcnt * pgsize;
|
||||
}
|
||||
err = mtd->write(mtd, addr, len, &written, buf);
|
||||
err = mtd_write(mtd, addr, len, &written, buf);
|
||||
if (err) {
|
||||
printk(PRINT_PREF "error %d while writing EB %d, written %zd"
|
||||
" bytes\n", err, ebnum, written);
|
||||
@ -290,10 +290,9 @@ static int __init tort_init(void)
|
||||
* Check if there is a bad eraseblock among those we are going to test.
|
||||
*/
|
||||
memset(&bad_ebs[0], 0, sizeof(int) * ebcnt);
|
||||
if (mtd->block_isbad) {
|
||||
if (mtd_can_have_bb(mtd)) {
|
||||
for (i = eb; i < eb + ebcnt; i++) {
|
||||
err = mtd->block_isbad(mtd,
|
||||
(loff_t)i * mtd->erasesize);
|
||||
err = mtd_block_isbad(mtd, (loff_t)i * mtd->erasesize);
|
||||
|
||||
if (err < 0) {
|
||||
printk(PRINT_PREF "block_isbad() returned %d "
|
||||
|
@ -664,7 +664,7 @@ static int io_init(struct ubi_device *ubi)
|
||||
ubi->peb_count = mtd_div_by_eb(ubi->mtd->size, ubi->mtd);
|
||||
ubi->flash_size = ubi->mtd->size;
|
||||
|
||||
if (ubi->mtd->block_isbad && ubi->mtd->block_markbad)
|
||||
if (mtd_can_have_bb(ubi->mtd))
|
||||
ubi->bad_allowed = 1;
|
||||
|
||||
if (ubi->mtd->type == MTD_NORFLASH) {
|
||||
|
@ -216,7 +216,7 @@ void ubi_dbg_dump_flash(struct ubi_device *ubi, int pnum, int offset, int len)
|
||||
buf = vmalloc(len);
|
||||
if (!buf)
|
||||
return;
|
||||
err = ubi->mtd->read(ubi->mtd, addr, len, &read, buf);
|
||||
err = mtd_read(ubi->mtd, addr, len, &read, buf);
|
||||
if (err && err != -EUCLEAN) {
|
||||
ubi_err("error %d while reading %d bytes from PEB %d:%d, "
|
||||
"read %zd bytes", err, len, pnum, offset, read);
|
||||
|
@ -170,7 +170,7 @@ int ubi_io_read(const struct ubi_device *ubi, void *buf, int pnum, int offset,
|
||||
|
||||
addr = (loff_t)pnum * ubi->peb_size + offset;
|
||||
retry:
|
||||
err = ubi->mtd->read(ubi->mtd, addr, len, &read, buf);
|
||||
err = mtd_read(ubi->mtd, addr, len, &read, buf);
|
||||
if (err) {
|
||||
const char *errstr = mtd_is_eccerr(err) ? " (ECC error)" : "";
|
||||
|
||||
@ -289,7 +289,7 @@ int ubi_io_write(struct ubi_device *ubi, const void *buf, int pnum, int offset,
|
||||
}
|
||||
|
||||
addr = (loff_t)pnum * ubi->peb_size + offset;
|
||||
err = ubi->mtd->write(ubi->mtd, addr, len, &written, buf);
|
||||
err = mtd_write(ubi->mtd, addr, len, &written, buf);
|
||||
if (err) {
|
||||
ubi_err("error %d while writing %d bytes to PEB %d:%d, written "
|
||||
"%zd bytes", err, len, pnum, offset, written);
|
||||
@ -361,7 +361,7 @@ retry:
|
||||
ei.callback = erase_callback;
|
||||
ei.priv = (unsigned long)&wq;
|
||||
|
||||
err = ubi->mtd->erase(ubi->mtd, &ei);
|
||||
err = mtd_erase(ubi->mtd, &ei);
|
||||
if (err) {
|
||||
if (retries++ < UBI_IO_RETRIES) {
|
||||
dbg_io("error %d while erasing PEB %d, retry",
|
||||
@ -525,11 +525,10 @@ static int nor_erase_prepare(struct ubi_device *ubi, int pnum)
|
||||
* the header comment in scan.c for more information).
|
||||
*/
|
||||
addr = (loff_t)pnum * ubi->peb_size;
|
||||
err = ubi->mtd->write(ubi->mtd, addr, 4, &written, (void *)&data);
|
||||
err = mtd_write(ubi->mtd, addr, 4, &written, (void *)&data);
|
||||
if (!err) {
|
||||
addr += ubi->vid_hdr_aloffset;
|
||||
err = ubi->mtd->write(ubi->mtd, addr, 4, &written,
|
||||
(void *)&data);
|
||||
err = mtd_write(ubi->mtd, addr, 4, &written, (void *)&data);
|
||||
if (!err)
|
||||
return 0;
|
||||
}
|
||||
@ -635,7 +634,7 @@ int ubi_io_is_bad(const struct ubi_device *ubi, int pnum)
|
||||
if (ubi->bad_allowed) {
|
||||
int ret;
|
||||
|
||||
ret = mtd->block_isbad(mtd, (loff_t)pnum * ubi->peb_size);
|
||||
ret = mtd_block_isbad(mtd, (loff_t)pnum * ubi->peb_size);
|
||||
if (ret < 0)
|
||||
ubi_err("error %d while checking if PEB %d is bad",
|
||||
ret, pnum);
|
||||
@ -670,7 +669,7 @@ int ubi_io_mark_bad(const struct ubi_device *ubi, int pnum)
|
||||
if (!ubi->bad_allowed)
|
||||
return 0;
|
||||
|
||||
err = mtd->block_markbad(mtd, (loff_t)pnum * ubi->peb_size);
|
||||
err = mtd_block_markbad(mtd, (loff_t)pnum * ubi->peb_size);
|
||||
if (err)
|
||||
ubi_err("cannot mark PEB %d bad, error %d", pnum, err);
|
||||
return err;
|
||||
@ -1357,7 +1356,7 @@ int ubi_dbg_check_write(struct ubi_device *ubi, const void *buf, int pnum,
|
||||
return 0;
|
||||
}
|
||||
|
||||
err = ubi->mtd->read(ubi->mtd, addr, len, &read, buf1);
|
||||
err = mtd_read(ubi->mtd, addr, len, &read, buf1);
|
||||
if (err && !mtd_is_bitflip(err))
|
||||
goto out_free;
|
||||
|
||||
@ -1421,7 +1420,7 @@ int ubi_dbg_check_all_ff(struct ubi_device *ubi, int pnum, int offset, int len)
|
||||
return 0;
|
||||
}
|
||||
|
||||
err = ubi->mtd->read(ubi->mtd, addr, len, &read, buf);
|
||||
err = mtd_read(ubi->mtd, addr, len, &read, buf);
|
||||
if (err && !mtd_is_bitflip(err)) {
|
||||
ubi_err("error %d while reading %d bytes from PEB %d:%d, "
|
||||
"read %zd bytes", err, len, pnum, offset, read);
|
||||
|
@ -714,9 +714,7 @@ int ubi_sync(int ubi_num)
|
||||
if (!ubi)
|
||||
return -ENODEV;
|
||||
|
||||
if (ubi->mtd->sync)
|
||||
ubi->mtd->sync(ubi->mtd);
|
||||
|
||||
mtd_sync(ubi->mtd);
|
||||
ubi_put_device(ubi);
|
||||
return 0;
|
||||
}
|
||||
|
@ -74,7 +74,7 @@ static void jffs2_erase_block(struct jffs2_sb_info *c,
|
||||
((struct erase_priv_struct *)instr->priv)->jeb = jeb;
|
||||
((struct erase_priv_struct *)instr->priv)->c = c;
|
||||
|
||||
ret = c->mtd->erase(c->mtd, instr);
|
||||
ret = mtd_erase(c->mtd, instr);
|
||||
if (!ret)
|
||||
return;
|
||||
|
||||
@ -336,12 +336,11 @@ static int jffs2_block_check_erase(struct jffs2_sb_info *c, struct jffs2_erasebl
|
||||
uint32_t ofs;
|
||||
size_t retlen;
|
||||
int ret = -EIO;
|
||||
unsigned long *wordebuf;
|
||||
|
||||
if (c->mtd->point) {
|
||||
unsigned long *wordebuf;
|
||||
|
||||
ret = c->mtd->point(c->mtd, jeb->offset, c->sector_size,
|
||||
&retlen, &ebuf, NULL);
|
||||
ret = mtd_point(c->mtd, jeb->offset, c->sector_size, &retlen,
|
||||
&ebuf, NULL);
|
||||
if (ret != -EOPNOTSUPP) {
|
||||
if (ret) {
|
||||
D1(printk(KERN_DEBUG "MTD point failed %d\n", ret));
|
||||
goto do_flash_read;
|
||||
@ -349,7 +348,7 @@ static int jffs2_block_check_erase(struct jffs2_sb_info *c, struct jffs2_erasebl
|
||||
if (retlen < c->sector_size) {
|
||||
/* Don't muck about if it won't let us point to the whole erase sector */
|
||||
D1(printk(KERN_DEBUG "MTD point returned len too short: 0x%zx\n", retlen));
|
||||
c->mtd->unpoint(c->mtd, jeb->offset, retlen);
|
||||
mtd_unpoint(c->mtd, jeb->offset, retlen);
|
||||
goto do_flash_read;
|
||||
}
|
||||
wordebuf = ebuf-sizeof(*wordebuf);
|
||||
@ -358,7 +357,7 @@ static int jffs2_block_check_erase(struct jffs2_sb_info *c, struct jffs2_erasebl
|
||||
if (*++wordebuf != ~0)
|
||||
break;
|
||||
} while(--retlen);
|
||||
c->mtd->unpoint(c->mtd, jeb->offset, c->sector_size);
|
||||
mtd_unpoint(c->mtd, jeb->offset, c->sector_size);
|
||||
if (retlen) {
|
||||
printk(KERN_WARNING "Newly-erased block contained word 0x%lx at offset 0x%08tx\n",
|
||||
*wordebuf, jeb->offset + c->sector_size-retlen*sizeof(*wordebuf));
|
||||
@ -381,7 +380,7 @@ static int jffs2_block_check_erase(struct jffs2_sb_info *c, struct jffs2_erasebl
|
||||
|
||||
*bad_offset = ofs;
|
||||
|
||||
ret = c->mtd->read(c->mtd, ofs, readlen, &retlen, ebuf);
|
||||
ret = mtd_read(c->mtd, ofs, readlen, &retlen, ebuf);
|
||||
if (ret) {
|
||||
printk(KERN_WARNING "Read of newly-erased block at 0x%08x failed: %d. Putting on bad_list\n", ofs, ret);
|
||||
ret = -EIO;
|
||||
|
@ -466,7 +466,6 @@ struct inode *jffs2_new_inode (struct inode *dir_i, umode_t mode, struct jffs2_r
|
||||
|
||||
if (insert_inode_locked(inode) < 0) {
|
||||
make_bad_inode(inode);
|
||||
unlock_new_inode(inode);
|
||||
iput(inode);
|
||||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user