Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git

Conflicts:
	drivers/mtd/mtd_blkdevs.c

Merge Grant's device-tree bits so that we can apply the subsequent fixes.

Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
This commit is contained in:
David Woodhouse
2010-10-30 12:35:11 +01:00
5688 changed files with 329698 additions and 218806 deletions
+2 -2
View File
@@ -446,8 +446,8 @@ struct mtd_info *cfi_cmdset_0002(struct map_info *map, int primary)
/*
* Valid primary extension versions are: 1.0, 1.1, 1.2, 1.3, 1.4
* see: http://www.amd.com/us-en/assets/content_type/DownloadableAssets/cfi_r20.pdf, page 19
* http://www.amd.com/us-en/assets/content_type/DownloadableAssets/cfi_100_20011201.pdf
* see: http://cs.ozerki.net/zap/pub/axim-x5/docs/cfi_r20.pdf, page 19
* http://www.spansion.com/Support/AppNotes/cfi_100_20011201.pdf
* http://www.spansion.com/Support/Datasheets/s29ws-p_00_a12_e.pdf
*/
if (extp->MajorVersion != '1' ||
+1 -1
View File
@@ -17,7 +17,7 @@
* - January 2000
*
* [2] MTD internal API documentation
* - http://www.linux-mtd.infradead.org/tech/
* - http://www.linux-mtd.infradead.org/
*
* Limitations:
*
+7
View File
@@ -928,6 +928,13 @@ static int __devinit m25p_probe(struct spi_device *spi)
nr_parts = data->nr_parts;
}
#ifdef CONFIG_OF
if (nr_parts <= 0 && spi->dev.of_node) {
nr_parts = of_mtd_parse_partitions(&spi->dev,
spi->dev.of_node, &parts);
}
#endif
if (nr_parts > 0) {
for (i = 0; i < nr_parts; i++) {
DEBUG(MTD_DEBUG_LEVEL2, "partitions[%d] = "
+1 -1
View File
@@ -51,7 +51,7 @@
Use of the FTL format for non-PCMCIA applications may be an
infringement of these patents. For additional information,
contact M-Systems (http://www.m-sys.com) directly.
contact M-Systems directly. M-Systems since acquired by Sandisk.
======================================================================*/
#include <linux/mtd/blktrans.h>
+2 -2
View File
@@ -172,7 +172,7 @@ config MTD_OCTAGON
This provides a 'mapping' driver which supports the way in which
the flash chips are connected in the Octagon-5066 Single Board
Computer. More information on the board is available at
<http://www.octagonsystems.com/CPUpages/5066.html>.
<http://www.octagonsystems.com/products/5066.aspx>.
config MTD_VMAX
tristate "JEDEC Flash device mapped on Tempustech VMAX SBC301"
@@ -293,7 +293,7 @@ config MTD_TQM8XXL
chips, currently uses AMD one. This 'mapping' driver supports
that arrangement, allowing the CFI probe and command set driver
code to communicate with the chips on the TQM8xxL board. More at
<http://www.denx.de/embedded-ppc-en.html>.
<http://www.denx.de/wiki/PPCEmbedded/>.
config MTD_RPXLITE
tristate "CFI Flash device mapped on RPX Lite or CLLF"
+35 -67
View File
@@ -16,7 +16,6 @@
#include <asm/io.h>
#include <asm/system.h>
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h>
#include <pcmcia/ds.h>
@@ -101,7 +100,7 @@ MODULE_PARM_DESC(mem_type, "Set Memory type (0=Flash, 1=RAM, 2=ROM, default=0)")
static caddr_t remap_window(struct map_info *map, unsigned long to)
{
struct pcmciamtd_dev *dev = (struct pcmciamtd_dev *)map->map_priv_1;
window_handle_t win = (window_handle_t)map->map_priv_2;
struct resource *win = (struct resource *) map->map_priv_2;
unsigned int offset;
int ret;
@@ -316,30 +315,19 @@ static void pcmciamtd_set_vpp(struct map_info *map, int on)
{
struct pcmciamtd_dev *dev = (struct pcmciamtd_dev *)map->map_priv_1;
struct pcmcia_device *link = dev->p_dev;
modconf_t mod;
int ret;
mod.Attributes = CONF_VPP1_CHANGE_VALID | CONF_VPP2_CHANGE_VALID;
mod.Vcc = 0;
mod.Vpp1 = mod.Vpp2 = on ? dev->vpp : 0;
DEBUG(2, "dev = %p on = %d vpp = %d\n", dev, on, dev->vpp);
ret = pcmcia_modify_configuration(link, &mod);
pcmcia_fixup_vpp(link, on ? dev->vpp : 0);
}
/* After a card is removed, pcmciamtd_release() will unregister the
* device, and release the PCMCIA configuration. If the device is
* still open, this will be postponed until it is closed.
*/
static void pcmciamtd_release(struct pcmcia_device *link)
{
struct pcmciamtd_dev *dev = link->priv;
DEBUG(3, "link = 0x%p", link);
if (link->win) {
if (link->resource[2]->end) {
if(dev->win_base) {
iounmap(dev->win_base);
dev->win_base = NULL;
@@ -482,18 +470,12 @@ static void card_settings(struct pcmciamtd_dev *dev, struct pcmcia_device *p_dev
}
/* pcmciamtd_config() is scheduled to run after a CARD_INSERTION event
* is received, to configure the PCMCIA socket, and to make the
* MTD device available to the system.
*/
static int pcmciamtd_config(struct pcmcia_device *link)
{
struct pcmciamtd_dev *dev = link->priv;
struct mtd_info *mtd = NULL;
win_req_t req;
int ret;
int i;
int i, j = 0;
static char *probes[] = { "jedec_probe", "cfi_probe" };
int new_name = 0;
@@ -520,28 +502,34 @@ static int pcmciamtd_config(struct pcmcia_device *link)
* smaller windows until we succeed
*/
req.Attributes = WIN_MEMORY_TYPE_CM | WIN_ENABLE;
req.Attributes |= (dev->pcmcia_map.bankwidth == 1) ? WIN_DATA_WIDTH_8 : WIN_DATA_WIDTH_16;
req.Base = 0;
req.AccessSpeed = mem_speed;
link->win = (window_handle_t)link;
req.Size = (force_size) ? force_size << 20 : MAX_PCMCIA_ADDR;
link->resource[2]->flags |= WIN_MEMORY_TYPE_CM | WIN_ENABLE;
link->resource[2]->flags |= (dev->pcmcia_map.bankwidth == 1) ?
WIN_DATA_WIDTH_8 : WIN_DATA_WIDTH_16;
link->resource[2]->start = 0;
link->resource[2]->end = (force_size) ? force_size << 20 :
MAX_PCMCIA_ADDR;
dev->win_size = 0;
do {
int ret;
DEBUG(2, "requesting window with size = %dKiB memspeed = %d",
req.Size >> 10, req.AccessSpeed);
ret = pcmcia_request_window(link, &req, &link->win);
DEBUG(2, "requesting window with size = %luKiB memspeed = %d",
(unsigned long) resource_size(link->resource[2]) >> 10,
mem_speed);
ret = pcmcia_request_window(link, link->resource[2], mem_speed);
DEBUG(2, "ret = %d dev->win_size = %d", ret, dev->win_size);
if(ret) {
req.Size >>= 1;
j++;
link->resource[2]->start = 0;
link->resource[2]->end = (force_size) ?
force_size << 20 : MAX_PCMCIA_ADDR;
link->resource[2]->end >>= j;
} else {
DEBUG(2, "Got window of size %dKiB", req.Size >> 10);
dev->win_size = req.Size;
DEBUG(2, "Got window of size %luKiB", (unsigned long)
resource_size(link->resource[2]) >> 10);
dev->win_size = resource_size(link->resource[2]);
break;
}
} while(req.Size >= 0x1000);
} while (link->resource[2]->end >= 0x1000);
DEBUG(2, "dev->win_size = %d", dev->win_size);
@@ -553,33 +541,31 @@ static int pcmciamtd_config(struct pcmcia_device *link)
DEBUG(1, "Allocated a window of %dKiB", dev->win_size >> 10);
/* Get write protect status */
DEBUG(2, "window handle = 0x%8.8lx", (unsigned long)link->win);
dev->win_base = ioremap(req.Base, req.Size);
dev->win_base = ioremap(link->resource[2]->start,
resource_size(link->resource[2]));
if(!dev->win_base) {
dev_err(&dev->p_dev->dev, "ioremap(%lu, %u) failed\n",
req.Base, req.Size);
dev_err(&dev->p_dev->dev, "ioremap(%pR) failed\n",
link->resource[2]);
pcmciamtd_release(link);
return -ENODEV;
}
DEBUG(1, "mapped window dev = %p req.base = 0x%lx base = %p size = 0x%x",
dev, req.Base, dev->win_base, req.Size);
DEBUG(1, "mapped window dev = %p @ %pR, base = %p",
dev, link->resource[2], dev->win_base);
dev->offset = 0;
dev->pcmcia_map.map_priv_1 = (unsigned long)dev;
dev->pcmcia_map.map_priv_2 = (unsigned long)link->win;
dev->pcmcia_map.map_priv_2 = (unsigned long)link->resource[2];
dev->vpp = (vpp) ? vpp : link->socket->socket.Vpp;
link->conf.Attributes = 0;
if(setvpp == 2) {
link->conf.Vpp = dev->vpp;
link->vpp = dev->vpp;
} else {
link->conf.Vpp = 0;
link->vpp = 0;
}
link->conf.IntType = INT_MEMORY;
link->conf.ConfigIndex = 0;
link->config_index = 0;
DEBUG(2, "Setting Configuration");
ret = pcmcia_request_configuration(link, &link->conf);
ret = pcmcia_enable_device(link);
if (ret != 0) {
if (dev->win_base) {
iounmap(dev->win_base);
@@ -676,12 +662,6 @@ static int pcmciamtd_resume(struct pcmcia_device *dev)
}
/* This deletes a driver "instance". The device is de-registered
* with Card Services. If it has been released, all local data
* structures are freed. Otherwise, the structures will be freed
* when the device is released.
*/
static void pcmciamtd_detach(struct pcmcia_device *link)
{
struct pcmciamtd_dev *dev = link->priv;
@@ -699,11 +679,6 @@ static void pcmciamtd_detach(struct pcmcia_device *link)
}
/* pcmciamtd_attach() creates an "instance" of the driver, allocating
* local data structures for one device. The device is registered
* with Card Services.
*/
static int pcmciamtd_probe(struct pcmcia_device *link)
{
struct pcmciamtd_dev *dev;
@@ -716,9 +691,6 @@ static int pcmciamtd_probe(struct pcmcia_device *link)
dev->p_dev = link;
link->priv = dev;
link->conf.Attributes = 0;
link->conf.IntType = INT_MEMORY;
return pcmciamtd_config(link);
}
@@ -753,9 +725,7 @@ static struct pcmcia_device_id pcmciamtd_ids[] = {
MODULE_DEVICE_TABLE(pcmcia, pcmciamtd_ids);
static struct pcmcia_driver pcmciamtd_driver = {
.drv = {
.name = "pcmciamtd"
},
.name = "pcmciamtd",
.probe = pcmciamtd_probe,
.remove = pcmciamtd_detach,
.owner = THIS_MODULE,
@@ -767,8 +737,6 @@ static struct pcmcia_driver pcmciamtd_driver = {
static int __init init_pcmciamtd(void)
{
info(DRIVER_DESC);
if(bankwidth && bankwidth != 1 && bankwidth != 2) {
info("bad bankwidth (%d), using default", bankwidth);
bankwidth = 2;
+7 -1
View File
@@ -29,7 +29,6 @@
#include <linux/blkdev.h>
#include <linux/blkpg.h>
#include <linux/spinlock.h>
#include <linux/smp_lock.h>
#include <linux/hdreg.h>
#include <linux/init.h>
#include <linux/mutex.h>
@@ -38,6 +37,7 @@
#include "mtdcore.h"
static DEFINE_MUTEX(mtd_blkdevs_mutex);
static LIST_HEAD(blktrans_majors);
static DEFINE_MUTEX(blktrans_ref_mutex);
@@ -185,6 +185,7 @@ static int blktrans_open(struct block_device *bdev, fmode_t mode)
if (!dev)
return -ERESTARTSYS; /* FIXME: busy loop! -arnd*/
mutex_lock(&mtd_blkdevs_mutex);
mutex_lock(&dev->lock);
if (dev->open++)
@@ -201,6 +202,7 @@ static int blktrans_open(struct block_device *bdev, fmode_t mode)
unlock:
mutex_unlock(&dev->lock);
blktrans_dev_put(dev);
mutex_unlock(&mtd_blkdevs_mutex);
return ret;
}
@@ -212,6 +214,7 @@ static int blktrans_release(struct gendisk *disk, fmode_t mode)
if (!dev)
return ret;
mutex_lock(&mtd_blkdevs_mutex);
mutex_lock(&dev->lock);
if (--dev->open)
@@ -227,6 +230,7 @@ static int blktrans_release(struct gendisk *disk, fmode_t mode)
unlock:
mutex_unlock(&dev->lock);
blktrans_dev_put(dev);
mutex_unlock(&mtd_blkdevs_mutex);
return ret;
}
@@ -259,6 +263,7 @@ static int blktrans_ioctl(struct block_device *bdev, fmode_t mode,
if (!dev)
return ret;
mutex_lock(&mtd_blkdevs_mutex);
mutex_lock(&dev->lock);
if (!dev->mtd)
@@ -273,6 +278,7 @@ static int blktrans_ioctl(struct block_device *bdev, fmode_t mode,
}
unlock:
mutex_unlock(&dev->lock);
mutex_unlock(&mtd_blkdevs_mutex);
blktrans_dev_put(dev);
return ret;
}
+8 -7
View File
@@ -26,7 +26,7 @@
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/sched.h>
#include <linux/smp_lock.h>
#include <linux/mutex.h>
#include <linux/backing-dev.h>
#include <linux/compat.h>
#include <linux/mount.h>
@@ -38,6 +38,7 @@
#include <asm/uaccess.h>
#define MTD_INODE_FS_MAGIC 0x11307854
static DEFINE_MUTEX(mtd_mutex);
static struct vfsmount *mtd_inode_mnt __read_mostly;
/*
@@ -91,7 +92,7 @@ static int mtd_open(struct inode *inode, struct file *file)
if ((file->f_mode & FMODE_WRITE) && (minor & 1))
return -EACCES;
lock_kernel();
mutex_lock(&mtd_mutex);
mtd = get_mtd_device(NULL, devnum);
if (IS_ERR(mtd)) {
@@ -139,7 +140,7 @@ static int mtd_open(struct inode *inode, struct file *file)
file->private_data = mfi;
out:
unlock_kernel();
mutex_unlock(&mtd_mutex);
return ret;
} /* mtd_open */
@@ -967,9 +968,9 @@ static long mtd_unlocked_ioctl(struct file *file, u_int cmd, u_long arg)
{
int ret;
lock_kernel();
mutex_lock(&mtd_mutex);
ret = mtd_ioctl(file, cmd, arg);
unlock_kernel();
mutex_unlock(&mtd_mutex);
return ret;
}
@@ -993,7 +994,7 @@ static long mtd_compat_ioctl(struct file *file, unsigned int cmd,
void __user *argp = compat_ptr(arg);
int ret = 0;
lock_kernel();
mutex_lock(&mtd_mutex);
switch (cmd) {
case MEMWRITEOOB32:
@@ -1028,7 +1029,7 @@ static long mtd_compat_ioctl(struct file *file, unsigned int cmd,
ret = mtd_ioctl(file, cmd, (unsigned long)argp);
}
unlock_kernel();
mutex_unlock(&mtd_mutex);
return ret;
}
+1 -1
View File
@@ -2,7 +2,7 @@
* Driver for One Laptop Per Child CAFÉ controller, aka Marvell 88ALP01
*
* The data sheet for this device can be found at:
* http://www.marvell.com/products/pcconn/88ALP01.jsp
* http://wiki.laptop.org/go/Datasheets
*
* Copyright © 2006 Red Hat, Inc.
* Copyright © 2006 David Woodhouse <dwmw2@infradead.org>
+83 -9
View File
@@ -30,6 +30,8 @@
#include <linux/clk.h>
#include <linux/err.h>
#include <linux/io.h>
#include <linux/irq.h>
#include <linux/completion.h>
#include <asm/mach/flash.h>
#include <mach/mxc_nand.h>
@@ -151,7 +153,7 @@ struct mxc_nand_host {
int irq;
int eccsize;
wait_queue_head_t irq_waitq;
struct completion op_completion;
uint8_t *data_buf;
unsigned int buf_start;
@@ -164,6 +166,7 @@ struct mxc_nand_host {
void (*send_read_id)(struct mxc_nand_host *);
uint16_t (*get_dev_status)(struct mxc_nand_host *);
int (*check_int)(struct mxc_nand_host *);
void (*irq_control)(struct mxc_nand_host *, int);
};
/* OOB placement block for use with hardware ecc generation */
@@ -216,9 +219,12 @@ static irqreturn_t mxc_nfc_irq(int irq, void *dev_id)
{
struct mxc_nand_host *host = dev_id;
disable_irq_nosync(irq);
if (!host->check_int(host))
return IRQ_NONE;
wake_up(&host->irq_waitq);
host->irq_control(host, 0);
complete(&host->op_completion);
return IRQ_HANDLED;
}
@@ -245,11 +251,54 @@ static int check_int_v1_v2(struct mxc_nand_host *host)
if (!(tmp & NFC_V1_V2_CONFIG2_INT))
return 0;
writew(tmp & ~NFC_V1_V2_CONFIG2_INT, NFC_V1_V2_CONFIG2);
if (!cpu_is_mx21())
writew(tmp & ~NFC_V1_V2_CONFIG2_INT, NFC_V1_V2_CONFIG2);
return 1;
}
/*
* It has been observed that the i.MX21 cannot read the CONFIG2:INT bit
* if interrupts are masked (CONFIG1:INT_MSK is set). To handle this, the
* driver can enable/disable the irq line rather than simply masking the
* interrupts.
*/
static void irq_control_mx21(struct mxc_nand_host *host, int activate)
{
if (activate)
enable_irq(host->irq);
else
disable_irq_nosync(host->irq);
}
static void irq_control_v1_v2(struct mxc_nand_host *host, int activate)
{
uint16_t tmp;
tmp = readw(NFC_V1_V2_CONFIG1);
if (activate)
tmp &= ~NFC_V1_V2_CONFIG1_INT_MSK;
else
tmp |= NFC_V1_V2_CONFIG1_INT_MSK;
writew(tmp, NFC_V1_V2_CONFIG1);
}
static void irq_control_v3(struct mxc_nand_host *host, int activate)
{
uint32_t tmp;
tmp = readl(NFC_V3_CONFIG2);
if (activate)
tmp &= ~NFC_V3_CONFIG2_INT_MSK;
else
tmp |= NFC_V3_CONFIG2_INT_MSK;
writel(tmp, NFC_V3_CONFIG2);
}
/* This function polls the NANDFC to wait for the basic operation to
* complete by checking the INT bit of config2 register.
*/
@@ -259,10 +308,9 @@ static void wait_op_done(struct mxc_nand_host *host, int useirq)
if (useirq) {
if (!host->check_int(host)) {
enable_irq(host->irq);
wait_event(host->irq_waitq, host->check_int(host));
INIT_COMPLETION(host->op_completion);
host->irq_control(host, 1);
wait_for_completion(&host->op_completion);
}
} else {
while (max_retries-- > 0) {
@@ -799,6 +847,7 @@ static void preset_v3(struct mtd_info *mtd)
NFC_V3_CONFIG2_2CMD_PHASES |
NFC_V3_CONFIG2_SPAS(mtd->oobsize >> 1) |
NFC_V3_CONFIG2_ST_CMD(0x70) |
NFC_V3_CONFIG2_INT_MSK |
NFC_V3_CONFIG2_NUM_ADDR_PHASE0;
if (chip->ecc.mode == NAND_ECC_HW)
@@ -1024,6 +1073,10 @@ static int __init mxcnd_probe(struct platform_device *pdev)
host->send_read_id = send_read_id_v1_v2;
host->get_dev_status = get_dev_status_v1_v2;
host->check_int = check_int_v1_v2;
if (cpu_is_mx21())
host->irq_control = irq_control_mx21;
else
host->irq_control = irq_control_v1_v2;
}
if (nfc_is_v21()) {
@@ -1062,6 +1115,7 @@ static int __init mxcnd_probe(struct platform_device *pdev)
host->send_read_id = send_read_id_v3;
host->check_int = check_int_v3;
host->get_dev_status = get_dev_status_v3;
host->irq_control = irq_control_v3;
oob_smallpage = &nandv2_hw_eccoob_smallpage;
oob_largepage = &nandv2_hw_eccoob_largepage;
} else
@@ -1093,14 +1147,34 @@ static int __init mxcnd_probe(struct platform_device *pdev)
this->options |= NAND_USE_FLASH_BBT;
}
init_waitqueue_head(&host->irq_waitq);
init_completion(&host->op_completion);
host->irq = platform_get_irq(pdev, 0);
/*
* mask the interrupt. For i.MX21 explicitely call
* irq_control_v1_v2 to use the mask bit. We can't call
* disable_irq_nosync() for an interrupt we do not own yet.
*/
if (cpu_is_mx21())
irq_control_v1_v2(host, 0);
else
host->irq_control(host, 0);
err = request_irq(host->irq, mxc_nfc_irq, IRQF_DISABLED, DRIVER_NAME, host);
if (err)
goto eirq;
host->irq_control(host, 0);
/*
* Now that the interrupt is disabled make sure the interrupt
* mask bit is cleared on i.MX21. Otherwise we can't read
* the interrupt status bit on this machine.
*/
if (cpu_is_mx21())
irq_control_v1_v2(host, 1);
/* first scan to find the device and get the page size */
if (nand_scan_ident(mtd, 1, NULL)) {
err = -ENXIO;
+1 -1
View File
@@ -413,7 +413,7 @@ static inline int omap_nand_dma_transfer(struct mtd_info *mtd, void *addr,
prefetch_status = gpmc_read_status(GPMC_PREFETCH_COUNT);
} while (prefetch_status);
/* disable and stop the PFPW engine */
gpmc_prefetch_reset();
gpmc_prefetch_reset(info->gpmc_cs);
dma_unmap_single(&info->pdev->dev, dma_addr, len, dir);
return 0;
+6 -11
View File
@@ -1,9 +1,5 @@
menu "UBI - Unsorted block images"
depends on MTD
config MTD_UBI
tristate "Enable UBI"
depends on MTD
menuconfig MTD_UBI
tristate "Enable UBI - Unsorted block images"
select CRC32
help
UBI is a software layer above MTD layer which admits of LVM-like
@@ -12,11 +8,12 @@ config MTD_UBI
capabilities. Please, consult the MTD web site for more details
(www.linux-mtd.infradead.org).
if MTD_UBI
config MTD_UBI_WL_THRESHOLD
int "UBI wear-leveling threshold"
default 4096
range 2 65536
depends on MTD_UBI
help
This parameter defines the maximum difference between the highest
erase counter value and the lowest erase counter value of eraseblocks
@@ -34,7 +31,6 @@ config MTD_UBI_BEB_RESERVE
int "Percentage of reserved eraseblocks for bad eraseblocks handling"
default 1
range 0 25
depends on MTD_UBI
help
If the MTD device admits of bad eraseblocks (e.g. NAND flash), UBI
reserves some amount of physical eraseblocks to handle new bad
@@ -48,8 +44,6 @@ config MTD_UBI_BEB_RESERVE
config MTD_UBI_GLUEBI
tristate "MTD devices emulation driver (gluebi)"
default n
depends on MTD_UBI
help
This option enables gluebi - an additional driver which emulates MTD
devices on top of UBI volumes: for each UBI volumes an MTD device is
@@ -59,4 +53,5 @@ config MTD_UBI_GLUEBI
software.
source "drivers/mtd/ubi/Kconfig.debug"
endmenu
endif # MTD_UBI
+4 -25
View File
@@ -1,94 +1,73 @@
comment "UBI debugging options"
depends on MTD_UBI
config MTD_UBI_DEBUG
bool "UBI debugging"
depends on SYSFS
depends on MTD_UBI
select DEBUG_FS
select KALLSYMS_ALL if KALLSYMS && DEBUG_KERNEL
help
This option enables UBI debugging.
if MTD_UBI_DEBUG
config MTD_UBI_DEBUG_MSG
bool "UBI debugging messages"
depends on MTD_UBI_DEBUG
default n
help
This option enables UBI debugging messages.
config MTD_UBI_DEBUG_PARANOID
bool "Extra self-checks"
default n
depends on MTD_UBI_DEBUG
help
This option enables extra checks in UBI code. Note this slows UBI down
significantly.
config MTD_UBI_DEBUG_DISABLE_BGT
bool "Do not enable the UBI background thread"
depends on MTD_UBI_DEBUG
default n
help
This option switches the background thread off by default. The thread
may be also be enabled/disabled via UBI sysfs.
config MTD_UBI_DEBUG_EMULATE_BITFLIPS
bool "Emulate flash bit-flips"
depends on MTD_UBI_DEBUG
default n
help
This option emulates bit-flips with probability 1/50, which in turn
causes scrubbing. Useful for debugging and stressing UBI.
config MTD_UBI_DEBUG_EMULATE_WRITE_FAILURES
bool "Emulate flash write failures"
depends on MTD_UBI_DEBUG
default n
help
This option emulates write failures with probability 1/100. Useful for
debugging and testing how UBI handlines errors.
config MTD_UBI_DEBUG_EMULATE_ERASE_FAILURES
bool "Emulate flash erase failures"
depends on MTD_UBI_DEBUG
default n
help
This option emulates erase failures with probability 1/100. Useful for
debugging and testing how UBI handlines errors.
menu "Additional UBI debugging messages"
depends on MTD_UBI_DEBUG
comment "Additional UBI debugging messages"
config MTD_UBI_DEBUG_MSG_BLD
bool "Additional UBI initialization and build messages"
default n
depends on MTD_UBI_DEBUG
help
This option enables detailed UBI initialization and device build
debugging messages.
config MTD_UBI_DEBUG_MSG_EBA
bool "Eraseblock association unit messages"
default n
depends on MTD_UBI_DEBUG
help
This option enables debugging messages from the UBI eraseblock
association unit.
config MTD_UBI_DEBUG_MSG_WL
bool "Wear-leveling unit messages"
default n
depends on MTD_UBI_DEBUG
help
This option enables debugging messages from the UBI wear-leveling
unit.
config MTD_UBI_DEBUG_MSG_IO
bool "Input/output unit messages"
default n
depends on MTD_UBI_DEBUG
help
This option enables debugging messages from the UBI input/output unit.
endmenu # UBI debugging messages
endif # MTD_UBI_DEBUG
+4 -2
View File
@@ -95,8 +95,8 @@ DEFINE_MUTEX(ubi_devices_mutex);
static DEFINE_SPINLOCK(ubi_devices_lock);
/* "Show" method for files in '/<sysfs>/class/ubi/' */
static ssize_t ubi_version_show(struct class *class, struct class_attribute *attr,
char *buf)
static ssize_t ubi_version_show(struct class *class,
struct class_attribute *attr, char *buf)
{
return sprintf(buf, "%d\n", UBI_VERSION);
}
@@ -591,6 +591,7 @@ static int attach_by_scanning(struct ubi_device *ubi)
ubi->bad_peb_count = si->bad_peb_count;
ubi->good_peb_count = ubi->peb_count - ubi->bad_peb_count;
ubi->corr_peb_count = si->corr_peb_count;
ubi->max_ec = si->max_ec;
ubi->mean_ec = si->mean_ec;
ubi_msg("max. sequence number: %llu", si->max_sqnum);
@@ -972,6 +973,7 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, int vid_hdr_offset)
ubi_msg("MTD device size: %llu MiB", ubi->flash_size >> 20);
ubi_msg("number of good PEBs: %d", ubi->good_peb_count);
ubi_msg("number of bad PEBs: %d", ubi->bad_peb_count);
ubi_msg("number of corrupted PEBs: %d", ubi->corr_peb_count);
ubi_msg("max. allowed volumes: %d", ubi->vtbl_slots);
ubi_msg("wear-leveling threshold: %d", CONFIG_MTD_UBI_WL_THRESHOLD);
ubi_msg("number of internal volumes: %d", UBI_INT_VOL_COUNT);
+1
View File
@@ -1100,4 +1100,5 @@ const struct file_operations ubi_ctrl_cdev_operations = {
.owner = THIS_MODULE,
.unlocked_ioctl = ctrl_cdev_ioctl,
.compat_ioctl = ctrl_cdev_compat_ioctl,
.llseek = noop_llseek,
};
+4
View File
@@ -57,6 +57,9 @@ void ubi_dbg_dump_seb(const struct ubi_scan_leb *seb, int type);
void ubi_dbg_dump_mkvol_req(const struct ubi_mkvol_req *req);
void ubi_dbg_dump_flash(struct ubi_device *ubi, int pnum, int offset, int len);
#define ubi_dbg_print_hex_dump(l, ps, pt, r, g, b, len, a) \
print_hex_dump(l, ps, pt, r, g, b, len, a)
#ifdef CONFIG_MTD_UBI_DEBUG_MSG
/* General debugging messages */
#define dbg_gen(fmt, ...) dbg_msg(fmt, ##__VA_ARGS__)
@@ -172,6 +175,7 @@ static inline int ubi_dbg_is_erase_failure(void)
#define ubi_dbg_dump_seb(seb, type) ({})
#define ubi_dbg_dump_mkvol_req(req) ({})
#define ubi_dbg_dump_flash(ubi, pnum, offset, len) ({})
#define ubi_dbg_print_hex_dump(l, ps, pt, r, g, b, len, a) ({})
#define UBI_IO_DEBUG 0
#define DBG_DISABLE_BGT 0
+8 -2
View File
@@ -418,7 +418,7 @@ retry:
* may try to recover data. FIXME: but this is
* not implemented.
*/
if (err == UBI_IO_BAD_HDR_READ ||
if (err == UBI_IO_BAD_HDR_EBADMSG ||
err == UBI_IO_BAD_HDR) {
ubi_warn("corrupted VID header at PEB "
"%d, LEB %d:%d", pnum, vol_id,
@@ -963,7 +963,7 @@ write_error:
static int is_error_sane(int err)
{
if (err == -EIO || err == -ENOMEM || err == UBI_IO_BAD_HDR ||
err == UBI_IO_BAD_HDR_READ || err == -ETIMEDOUT)
err == UBI_IO_BAD_HDR_EBADMSG || err == -ETIMEDOUT)
return 0;
return 1;
}
@@ -1201,6 +1201,9 @@ static void print_rsvd_warning(struct ubi_device *ubi,
ubi_warn("cannot reserve enough PEBs for bad PEB handling, reserved %d,"
" need %d", ubi->beb_rsvd_pebs, ubi->beb_rsvd_level);
if (ubi->corr_peb_count)
ubi_warn("%d PEBs are corrupted and not used",
ubi->corr_peb_count);
}
/**
@@ -1263,6 +1266,9 @@ int ubi_eba_init_scan(struct ubi_device *ubi, struct ubi_scan_info *si)
if (ubi->avail_pebs < EBA_RESERVED_PEBS) {
ubi_err("no enough physical eraseblocks (%d, need %d)",
ubi->avail_pebs, EBA_RESERVED_PEBS);
if (ubi->corr_peb_count)
ubi_err("%d PEBs are corrupted and not used",
ubi->corr_peb_count);
err = -ENOSPC;
goto out_free;
}
+50 -88
View File
@@ -376,25 +376,6 @@ retry:
return 0;
}
/**
* check_pattern - check if buffer contains only a certain byte pattern.
* @buf: buffer to check
* @patt: the pattern to check
* @size: buffer size in bytes
*
* This function returns %1 in there are only @patt bytes in @buf, and %0 if
* something else was also found.
*/
static int check_pattern(const void *buf, uint8_t patt, int size)
{
int i;
for (i = 0; i < size; i++)
if (((const uint8_t *)buf)[i] != patt)
return 0;
return 1;
}
/* Patterns to write to a physical eraseblock when torturing it */
static uint8_t patterns[] = {0xa5, 0x5a, 0x0};
@@ -426,7 +407,7 @@ static int torture_peb(struct ubi_device *ubi, int pnum)
if (err)
goto out;
err = check_pattern(ubi->peb_buf1, 0xFF, ubi->peb_size);
err = ubi_check_pattern(ubi->peb_buf1, 0xFF, ubi->peb_size);
if (err == 0) {
ubi_err("erased PEB %d, but a non-0xFF byte found",
pnum);
@@ -445,7 +426,8 @@ static int torture_peb(struct ubi_device *ubi, int pnum)
if (err)
goto out;
err = check_pattern(ubi->peb_buf1, patterns[i], ubi->peb_size);
err = ubi_check_pattern(ubi->peb_buf1, patterns[i],
ubi->peb_size);
if (err == 0) {
ubi_err("pattern %x checking failed for PEB %d",
patterns[i], pnum);
@@ -517,7 +499,7 @@ static int nor_erase_prepare(struct ubi_device *ubi, int pnum)
* In this case we probably anyway have garbage in this PEB.
*/
err1 = ubi_io_read_vid_hdr(ubi, pnum, &vid_hdr, 0);
if (err1 == UBI_IO_BAD_HDR_READ || err1 == UBI_IO_BAD_HDR)
if (err1 == UBI_IO_BAD_HDR_EBADMSG || err1 == UBI_IO_BAD_HDR)
/*
* The VID header is corrupted, so we can safely erase this
* PEB and not afraid that it will be treated as a valid PEB in
@@ -712,47 +694,47 @@ bad:
* and corrected by the flash driver; this is harmless but may indicate that
* this eraseblock may become bad soon (but may be not);
* o %UBI_IO_BAD_HDR if the erase counter header is corrupted (a CRC error);
* o %UBI_IO_PEB_EMPTY if the physical eraseblock is empty;
* o %UBI_IO_BAD_HDR_EBADMSG is the same as %UBI_IO_BAD_HDR, but there also was
* a data integrity error (uncorrectable ECC error in case of NAND);
* o %UBI_IO_FF if only 0xFF bytes were read (the PEB is supposedly empty)
* o a negative error code in case of failure.
*/
int ubi_io_read_ec_hdr(struct ubi_device *ubi, int pnum,
struct ubi_ec_hdr *ec_hdr, int verbose)
{
int err, read_err = 0;
int err, read_err;
uint32_t crc, magic, hdr_crc;
dbg_io("read EC header from PEB %d", pnum);
ubi_assert(pnum >= 0 && pnum < ubi->peb_count);
err = ubi_io_read(ubi, ec_hdr, pnum, 0, UBI_EC_HDR_SIZE);
if (err) {
if (err != UBI_IO_BITFLIPS && err != -EBADMSG)
return err;
read_err = ubi_io_read(ubi, ec_hdr, pnum, 0, UBI_EC_HDR_SIZE);
if (read_err) {
if (read_err != UBI_IO_BITFLIPS && read_err != -EBADMSG)
return read_err;
/*
* We read all the data, but either a correctable bit-flip
* occurred, or MTD reported about some data integrity error,
* like an ECC error in case of NAND. The former is harmless,
* the later may mean that the read data is corrupted. But we
* have a CRC check-sum and we will detect this. If the EC
* header is still OK, we just report this as there was a
* bit-flip.
* occurred, or MTD reported a data integrity error
* (uncorrectable ECC error in case of NAND). The former is
* harmless, the later may mean that the read data is
* corrupted. But we have a CRC check-sum and we will detect
* this. If the EC header is still OK, we just report this as
* there was a bit-flip, to force scrubbing.
*/
if (err == -EBADMSG)
read_err = UBI_IO_BAD_HDR_READ;
}
magic = be32_to_cpu(ec_hdr->magic);
if (magic != UBI_EC_HDR_MAGIC) {
if (read_err)
return read_err;
if (read_err == -EBADMSG)
return UBI_IO_BAD_HDR_EBADMSG;
/*
* The magic field is wrong. Let's check if we have read all
* 0xFF. If yes, this physical eraseblock is assumed to be
* empty.
*/
if (check_pattern(ec_hdr, 0xFF, UBI_EC_HDR_SIZE)) {
if (ubi_check_pattern(ec_hdr, 0xFF, UBI_EC_HDR_SIZE)) {
/* The physical eraseblock is supposedly empty */
if (verbose)
ubi_warn("no EC header found at PEB %d, "
@@ -760,7 +742,10 @@ int ubi_io_read_ec_hdr(struct ubi_device *ubi, int pnum,
else if (UBI_IO_DEBUG)
dbg_msg("no EC header found at PEB %d, "
"only 0xFF bytes", pnum);
return UBI_IO_PEB_EMPTY;
if (!read_err)
return UBI_IO_FF;
else
return UBI_IO_FF_BITFLIPS;
}
/*
@@ -788,7 +773,11 @@ int ubi_io_read_ec_hdr(struct ubi_device *ubi, int pnum,
} else if (UBI_IO_DEBUG)
dbg_msg("bad EC header CRC at PEB %d, calculated "
"%#08x, read %#08x", pnum, crc, hdr_crc);
return read_err ?: UBI_IO_BAD_HDR;
if (!read_err)
return UBI_IO_BAD_HDR;
else
return UBI_IO_BAD_HDR_EBADMSG;
}
/* And of course validate what has just been read from the media */
@@ -975,22 +964,16 @@ bad:
*
* This function reads the volume identifier header from physical eraseblock
* @pnum and stores it in @vid_hdr. It also checks CRC checksum of the read
* volume identifier header. The following codes may be returned:
* volume identifier header. The error codes are the same as in
* 'ubi_io_read_ec_hdr()'.
*
* o %0 if the CRC checksum is correct and the header was successfully read;
* o %UBI_IO_BITFLIPS if the CRC is correct, but bit-flips were detected
* and corrected by the flash driver; this is harmless but may indicate that
* this eraseblock may become bad soon;
* o %UBI_IO_BAD_HDR if the volume identifier header is corrupted (a CRC
* error detected);
* o %UBI_IO_PEB_FREE if the physical eraseblock is free (i.e., there is no VID
* header there);
* o a negative error code in case of failure.
* Note, the implementation of this function is also very similar to
* 'ubi_io_read_ec_hdr()', so refer commentaries in 'ubi_io_read_ec_hdr()'.
*/
int ubi_io_read_vid_hdr(struct ubi_device *ubi, int pnum,
struct ubi_vid_hdr *vid_hdr, int verbose)
{
int err, read_err = 0;
int err, read_err;
uint32_t crc, magic, hdr_crc;
void *p;
@@ -998,48 +981,29 @@ int ubi_io_read_vid_hdr(struct ubi_device *ubi, int pnum,
ubi_assert(pnum >= 0 && pnum < ubi->peb_count);
p = (char *)vid_hdr - ubi->vid_hdr_shift;
err = ubi_io_read(ubi, p, pnum, ubi->vid_hdr_aloffset,
read_err = ubi_io_read(ubi, p, pnum, ubi->vid_hdr_aloffset,
ubi->vid_hdr_alsize);
if (err) {
if (err != UBI_IO_BITFLIPS && err != -EBADMSG)
return err;
/*
* We read all the data, but either a correctable bit-flip
* occurred, or MTD reported about some data integrity error,
* like an ECC error in case of NAND. The former is harmless,
* the later may mean the read data is corrupted. But we have a
* CRC check-sum and we will identify this. If the VID header is
* still OK, we just report this as there was a bit-flip.
*/
if (err == -EBADMSG)
read_err = UBI_IO_BAD_HDR_READ;
}
if (read_err && read_err != UBI_IO_BITFLIPS && read_err != -EBADMSG)
return read_err;
magic = be32_to_cpu(vid_hdr->magic);
if (magic != UBI_VID_HDR_MAGIC) {
if (read_err)
return read_err;
if (read_err == -EBADMSG)
return UBI_IO_BAD_HDR_EBADMSG;
/*
* If we have read all 0xFF bytes, the VID header probably does
* not exist and the physical eraseblock is assumed to be free.
*/
if (check_pattern(vid_hdr, 0xFF, UBI_VID_HDR_SIZE)) {
/* The physical eraseblock is supposedly free */
if (ubi_check_pattern(vid_hdr, 0xFF, UBI_VID_HDR_SIZE)) {
if (verbose)
ubi_warn("no VID header found at PEB %d, "
"only 0xFF bytes", pnum);
else if (UBI_IO_DEBUG)
dbg_msg("no VID header found at PEB %d, "
"only 0xFF bytes", pnum);
return UBI_IO_PEB_FREE;
if (!read_err)
return UBI_IO_FF;
else
return UBI_IO_FF_BITFLIPS;
}
/*
* This is not a valid VID header, and these are not 0xFF
* bytes. Report that the header is corrupted.
*/
if (verbose) {
ubi_warn("bad magic number at PEB %d: %08x instead of "
"%08x", pnum, magic, UBI_VID_HDR_MAGIC);
@@ -1061,20 +1025,18 @@ int ubi_io_read_vid_hdr(struct ubi_device *ubi, int pnum,
} else if (UBI_IO_DEBUG)
dbg_msg("bad CRC at PEB %d, calculated %#08x, "
"read %#08x", pnum, crc, hdr_crc);
return read_err ?: UBI_IO_BAD_HDR;
if (!read_err)
return UBI_IO_BAD_HDR;
else
return UBI_IO_BAD_HDR_EBADMSG;
}
/* Validate the VID header that we have just read */
err = validate_vid_hdr(ubi, vid_hdr);
if (err) {
ubi_err("validation failed for PEB %d", pnum);
return -EINVAL;
}
/*
* If there was a read error (%-EBADMSG), but the header CRC is still
* OK, report about a bit-flip to force scrubbing on this PEB.
*/
return read_err ? UBI_IO_BITFLIPS : 0;
}
@@ -1383,7 +1345,7 @@ int ubi_dbg_check_all_ff(struct ubi_device *ubi, int pnum, int offset, int len)
goto error;
}
err = check_pattern(ubi->dbg_peb_buf, 0xFF, len);
err = ubi_check_pattern(ubi->dbg_peb_buf, 0xFF, len);
if (err == 0) {
ubi_err("flash region at PEB %d:%d, length %d does not "
"contain all 0xFF bytes", pnum, offset, len);
+19
View File
@@ -103,3 +103,22 @@ void ubi_calculate_reserved(struct ubi_device *ubi)
if (ubi->beb_rsvd_level < MIN_RESEVED_PEBS)
ubi->beb_rsvd_level = MIN_RESEVED_PEBS;
}
/**
* ubi_check_pattern - check if buffer contains only a certain byte pattern.
* @buf: buffer to check
* @patt: the pattern to check
* @size: buffer size in bytes
*
* This function returns %1 in there are only @patt bytes in @buf, and %0 if
* something else was also found.
*/
int ubi_check_pattern(const void *buf, uint8_t patt, int size)
{
int i;
for (i = 0; i < size; i++)
if (((const uint8_t *)buf)[i] != patt)
return 0;
return 1;
}
+272 -121
View File
File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More