Merge master.kernel.org:/pub/scm/linux/kernel/git/tglx/mtd-2.6
Some manual fixups for clashing kfree() cleanups etc.
This commit is contained in:
commit
b3ce1debe2
192 changed files with 11483 additions and 5056 deletions
|
@ -1,4 +1,4 @@
|
|||
# $Id: Kconfig,v 1.7 2004/11/22 11:33:56 ijc Exp $
|
||||
# $Id: Kconfig,v 1.11 2005/11/07 11:14:19 gleixner Exp $
|
||||
|
||||
menu "Memory Technology Devices (MTD)"
|
||||
|
||||
|
@ -10,7 +10,7 @@ config MTD
|
|||
will provide the generic support for MTD drivers to register
|
||||
themselves with the kernel and for potential users of MTD devices
|
||||
to enumerate the devices which are present and obtain a handle on
|
||||
them. It will also allow you to select individual drivers for
|
||||
them. It will also allow you to select individual drivers for
|
||||
particular hardware and users of MTD devices. If unsure, say N.
|
||||
|
||||
config MTD_DEBUG
|
||||
|
@ -61,11 +61,11 @@ config MTD_REDBOOT_PARTS
|
|||
|
||||
If you need code which can detect and parse this table, and register
|
||||
MTD 'partitions' corresponding to each image in the table, enable
|
||||
this option.
|
||||
this option.
|
||||
|
||||
You will still need the parsing functions to be called by the driver
|
||||
for your particular device. It won't happen automatically. The
|
||||
SA1100 map driver (CONFIG_MTD_SA1100) has an option for this, for
|
||||
for your particular device. It won't happen automatically. The
|
||||
SA1100 map driver (CONFIG_MTD_SA1100) has an option for this, for
|
||||
example.
|
||||
|
||||
config MTD_REDBOOT_DIRECTORY_BLOCK
|
||||
|
@ -81,10 +81,10 @@ config MTD_REDBOOT_DIRECTORY_BLOCK
|
|||
partition table. A zero or positive value gives an absolete
|
||||
erase block number. A negative value specifies a number of
|
||||
sectors before the end of the device.
|
||||
|
||||
|
||||
For example "2" means block number 2, "-1" means the last
|
||||
block and "-2" means the penultimate block.
|
||||
|
||||
|
||||
config MTD_REDBOOT_PARTS_UNALLOCATED
|
||||
bool " Include unallocated flash regions"
|
||||
depends on MTD_REDBOOT_PARTS
|
||||
|
@ -105,11 +105,11 @@ config MTD_CMDLINE_PARTS
|
|||
---help---
|
||||
Allow generic configuration of the MTD paritition tables via the kernel
|
||||
command line. Multiple flash resources are supported for hardware where
|
||||
different kinds of flash memory are available.
|
||||
different kinds of flash memory are available.
|
||||
|
||||
You will still need the parsing functions to be called by the driver
|
||||
for your particular device. It won't happen automatically. The
|
||||
SA1100 map driver (CONFIG_MTD_SA1100) has an option for this, for
|
||||
for your particular device. It won't happen automatically. The
|
||||
SA1100 map driver (CONFIG_MTD_SA1100) has an option for this, for
|
||||
example.
|
||||
|
||||
The format for the command line is as follows:
|
||||
|
@ -118,12 +118,12 @@ config MTD_CMDLINE_PARTS
|
|||
<mtddef> := <mtd-id>:<partdef>[,<partdef>]
|
||||
<partdef> := <size>[@offset][<name>][ro]
|
||||
<mtd-id> := unique id used in mapping driver/device
|
||||
<size> := standard linux memsize OR "-" to denote all
|
||||
<size> := standard linux memsize OR "-" to denote all
|
||||
remaining space
|
||||
<name> := (NAME)
|
||||
|
||||
Due to the way Linux handles the command line, no spaces are
|
||||
allowed in the partition definition, including mtd id's and partition
|
||||
Due to the way Linux handles the command line, no spaces are
|
||||
allowed in the partition definition, including mtd id's and partition
|
||||
names.
|
||||
|
||||
Examples:
|
||||
|
@ -240,7 +240,7 @@ config INFTL
|
|||
tristate "INFTL (Inverse NAND Flash Translation Layer) support"
|
||||
depends on MTD
|
||||
---help---
|
||||
This provides support for the Inverse NAND Flash Translation
|
||||
This provides support for the Inverse NAND Flash Translation
|
||||
Layer which is used on M-Systems' newer DiskOnChip devices. It
|
||||
uses a kind of pseudo-file system on a flash device to emulate
|
||||
a block device with 512-byte sectors, on top of which you put
|
||||
|
@ -253,6 +253,16 @@ config INFTL
|
|||
permitted to copy, modify and distribute the code as you wish. Just
|
||||
not use it.
|
||||
|
||||
config RFD_FTL
|
||||
tristate "Resident Flash Disk (Flash Translation Layer) support"
|
||||
depends on MTD
|
||||
---help---
|
||||
This provides support for the flash translation layer known
|
||||
as the Resident Flash Disk (RFD), as used by the Embedded BIOS
|
||||
of General Software. There is a blurb at:
|
||||
|
||||
http://www.gensw.com/pages/prod/bios/rfd.htm
|
||||
|
||||
source "drivers/mtd/chips/Kconfig"
|
||||
|
||||
source "drivers/mtd/maps/Kconfig"
|
||||
|
@ -261,5 +271,7 @@ source "drivers/mtd/devices/Kconfig"
|
|||
|
||||
source "drivers/mtd/nand/Kconfig"
|
||||
|
||||
source "drivers/mtd/onenand/Kconfig"
|
||||
|
||||
endmenu
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#
|
||||
# Makefile for the memory technology device drivers.
|
||||
#
|
||||
# $Id: Makefile.common,v 1.5 2004/08/10 20:51:49 dwmw2 Exp $
|
||||
# $Id: Makefile.common,v 1.7 2005/07/11 10:39:27 gleixner Exp $
|
||||
|
||||
# Core functionality.
|
||||
mtd-y := mtdcore.o
|
||||
|
@ -20,8 +20,9 @@ obj-$(CONFIG_MTD_BLOCK_RO) += mtdblock_ro.o mtd_blkdevs.o
|
|||
obj-$(CONFIG_FTL) += ftl.o mtd_blkdevs.o
|
||||
obj-$(CONFIG_NFTL) += nftl.o mtd_blkdevs.o
|
||||
obj-$(CONFIG_INFTL) += inftl.o mtd_blkdevs.o
|
||||
obj-$(CONFIG_RFD_FTL) += rfd_ftl.o mtd_blkdevs.o
|
||||
|
||||
nftl-objs := nftlcore.o nftlmount.o
|
||||
inftl-objs := inftlcore.o inftlmount.o
|
||||
|
||||
obj-y += chips/ maps/ devices/ nand/
|
||||
obj-y += chips/ maps/ devices/ nand/ onenand/
|
||||
|
|
|
@ -1,27 +1,27 @@
|
|||
/*======================================================================
|
||||
|
||||
drivers/mtd/afs.c: ARM Flash Layout/Partitioning
|
||||
|
||||
|
||||
Copyright (C) 2000 ARM Limited
|
||||
|
||||
|
||||
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
This is access code for flashes using ARM's flash partitioning
|
||||
|
||||
This is access code for flashes using ARM's flash partitioning
|
||||
standards.
|
||||
|
||||
$Id: afs.c,v 1.13 2004/02/27 22:09:59 rmk Exp $
|
||||
$Id: afs.c,v 1.15 2005/11/07 11:14:19 gleixner Exp $
|
||||
|
||||
======================================================================*/
|
||||
|
||||
|
@ -163,7 +163,7 @@ afs_read_iis(struct mtd_info *mtd, struct image_info_struct *iis, u_int ptr)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int parse_afs_partitions(struct mtd_info *mtd,
|
||||
static int parse_afs_partitions(struct mtd_info *mtd,
|
||||
struct mtd_partition **pparts,
|
||||
unsigned long origin)
|
||||
{
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# drivers/mtd/chips/Kconfig
|
||||
# $Id: Kconfig,v 1.15 2005/06/06 23:04:35 tpoynor Exp $
|
||||
# $Id: Kconfig,v 1.18 2005/11/07 11:14:22 gleixner Exp $
|
||||
|
||||
menu "RAM/ROM/Flash chip drivers"
|
||||
depends on MTD!=n
|
||||
|
@ -39,7 +39,7 @@ config MTD_CFI_ADV_OPTIONS
|
|||
If you need to specify a specific endianness for access to flash
|
||||
chips, or if you wish to reduce the size of the kernel by including
|
||||
support for only specific arrangements of flash chips, say 'Y'. This
|
||||
option does not directly affect the code, but will enable other
|
||||
option does not directly affect the code, but will enable other
|
||||
configuration options which allow you to do so.
|
||||
|
||||
If unsure, say 'N'.
|
||||
|
@ -56,7 +56,7 @@ config MTD_CFI_NOSWAP
|
|||
data bits when writing the 'magic' commands to the chips. Saying
|
||||
'NO', which is the default when CONFIG_MTD_CFI_ADV_OPTIONS isn't
|
||||
enabled, means that the CPU will not do any swapping; the chips
|
||||
are expected to be wired to the CPU in 'host-endian' form.
|
||||
are expected to be wired to the CPU in 'host-endian' form.
|
||||
Specific arrangements are possible with the BIG_ENDIAN_BYTE and
|
||||
LITTLE_ENDIAN_BYTE, if the bytes are reversed.
|
||||
|
||||
|
@ -79,10 +79,10 @@ config MTD_CFI_GEOMETRY
|
|||
bool "Specific CFI Flash geometry selection"
|
||||
depends on MTD_CFI_ADV_OPTIONS
|
||||
help
|
||||
This option does not affect the code directly, but will enable
|
||||
This option does not affect the code directly, but will enable
|
||||
some other configuration options which would allow you to reduce
|
||||
the size of the kernel by including support for only certain
|
||||
arrangements of CFI chips. If unsure, say 'N' and all options
|
||||
the size of the kernel by including support for only certain
|
||||
arrangements of CFI chips. If unsure, say 'N' and all options
|
||||
which are supported by the current code will be enabled.
|
||||
|
||||
config MTD_MAP_BANK_WIDTH_1
|
||||
|
@ -197,7 +197,7 @@ config MTD_CFI_AMDSTD
|
|||
help
|
||||
The Common Flash Interface defines a number of different command
|
||||
sets which a CFI-compliant chip may claim to implement. This code
|
||||
provides support for one of those command sets, used on chips
|
||||
provides support for one of those command sets, used on chips
|
||||
including the AMD Am29LV320.
|
||||
|
||||
config MTD_CFI_AMDSTD_RETRY
|
||||
|
@ -237,14 +237,14 @@ config MTD_RAM
|
|||
tristate "Support for RAM chips in bus mapping"
|
||||
depends on MTD
|
||||
help
|
||||
This option enables basic support for RAM chips accessed through
|
||||
This option enables basic support for RAM chips accessed through
|
||||
a bus mapping driver.
|
||||
|
||||
config MTD_ROM
|
||||
tristate "Support for ROM chips in bus mapping"
|
||||
depends on MTD
|
||||
help
|
||||
This option enables basic support for ROM chips accessed through
|
||||
This option enables basic support for ROM chips accessed through
|
||||
a bus mapping driver.
|
||||
|
||||
config MTD_ABSENT
|
||||
|
@ -275,7 +275,7 @@ config MTD_AMDSTD
|
|||
depends on MTD && MTD_OBSOLETE_CHIPS
|
||||
help
|
||||
This option enables support for flash chips using AMD-compatible
|
||||
commands, including some which are not CFI-compatible and hence
|
||||
commands, including some which are not CFI-compatible and hence
|
||||
cannot be used with the CONFIG_MTD_CFI_AMDSTD option.
|
||||
|
||||
It also works on AMD compatible chips that do conform to CFI.
|
||||
|
@ -285,7 +285,7 @@ config MTD_SHARP
|
|||
depends on MTD && MTD_OBSOLETE_CHIPS
|
||||
help
|
||||
This option enables support for flash chips using Sharp-compatible
|
||||
commands, including some which are not CFI-compatible and hence
|
||||
commands, including some which are not CFI-compatible and hence
|
||||
cannot be used with the CONFIG_MTD_CFI_INTELxxx options.
|
||||
|
||||
config MTD_JEDEC
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#
|
||||
# linux/drivers/chips/Makefile
|
||||
#
|
||||
# $Id: Makefile.common,v 1.4 2004/07/12 16:07:30 dwmw2 Exp $
|
||||
# $Id: Makefile.common,v 1.5 2005/11/07 11:14:22 gleixner Exp $
|
||||
|
||||
# *** BIG UGLY NOTE ***
|
||||
#
|
||||
|
@ -11,7 +11,7 @@
|
|||
# the CFI command set drivers are linked before gen_probe.o
|
||||
|
||||
obj-$(CONFIG_MTD) += chipreg.o
|
||||
obj-$(CONFIG_MTD_AMDSTD) += amd_flash.o
|
||||
obj-$(CONFIG_MTD_AMDSTD) += amd_flash.o
|
||||
obj-$(CONFIG_MTD_CFI) += cfi_probe.o
|
||||
obj-$(CONFIG_MTD_CFI_UTIL) += cfi_util.o
|
||||
obj-$(CONFIG_MTD_CFI_STAA) += cfi_cmdset_0020.o
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
*
|
||||
* Author: Jonas Holmberg <jonas.holmberg@axis.com>
|
||||
*
|
||||
* $Id: amd_flash.c,v 1.27 2005/02/04 07:43:09 jonashg Exp $
|
||||
* $Id: amd_flash.c,v 1.28 2005/11/07 11:14:22 gleixner Exp $
|
||||
*
|
||||
* Copyright (c) 2001 Axis Communications AB
|
||||
*
|
||||
|
@ -93,9 +93,9 @@
|
|||
#define D6_MASK 0x40
|
||||
|
||||
struct amd_flash_private {
|
||||
int device_type;
|
||||
int interleave;
|
||||
int numchips;
|
||||
int device_type;
|
||||
int interleave;
|
||||
int numchips;
|
||||
unsigned long chipshift;
|
||||
// const char *im_name;
|
||||
struct flchip chips[0];
|
||||
|
@ -253,7 +253,7 @@ static int amd_flash_do_unlock(struct mtd_info *mtd, loff_t ofs, size_t len,
|
|||
int i;
|
||||
int retval = 0;
|
||||
int lock_status;
|
||||
|
||||
|
||||
map = mtd->priv;
|
||||
|
||||
/* Pass the whole chip through sector by sector and check for each
|
||||
|
@ -273,7 +273,7 @@ static int amd_flash_do_unlock(struct mtd_info *mtd, loff_t ofs, size_t len,
|
|||
unlock_sector(map, eraseoffset, is_unlock);
|
||||
|
||||
lock_status = is_sector_locked(map, eraseoffset);
|
||||
|
||||
|
||||
if (is_unlock && lock_status) {
|
||||
printk("Cannot unlock sector at address %x length %xx\n",
|
||||
eraseoffset, merip->erasesize);
|
||||
|
@ -305,7 +305,7 @@ static int amd_flash_lock(struct mtd_info *mtd, loff_t ofs, size_t len)
|
|||
/*
|
||||
* Reads JEDEC manufacturer ID and device ID and returns the index of the first
|
||||
* matching table entry (-1 if not found or alias for already found chip).
|
||||
*/
|
||||
*/
|
||||
static int probe_new_chip(struct mtd_info *mtd, __u32 base,
|
||||
struct flchip *chips,
|
||||
struct amd_flash_private *private,
|
||||
|
@ -636,7 +636,7 @@ static struct mtd_info *amd_flash_probe(struct map_info *map)
|
|||
{ .offset = 0x000000, .erasesize = 0x10000, .numblocks = 31 },
|
||||
{ .offset = 0x1F0000, .erasesize = 0x02000, .numblocks = 8 }
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
struct mtd_info *mtd;
|
||||
|
@ -701,7 +701,7 @@ static struct mtd_info *amd_flash_probe(struct map_info *map)
|
|||
|
||||
mtd->eraseregions = kmalloc(sizeof(struct mtd_erase_region_info) *
|
||||
mtd->numeraseregions, GFP_KERNEL);
|
||||
if (!mtd->eraseregions) {
|
||||
if (!mtd->eraseregions) {
|
||||
printk(KERN_WARNING "%s: Failed to allocate "
|
||||
"memory for MTD erase region info\n", map->name);
|
||||
kfree(mtd);
|
||||
|
@ -739,12 +739,12 @@ static struct mtd_info *amd_flash_probe(struct map_info *map)
|
|||
mtd->type = MTD_NORFLASH;
|
||||
mtd->flags = MTD_CAP_NORFLASH;
|
||||
mtd->name = map->name;
|
||||
mtd->erase = amd_flash_erase;
|
||||
mtd->read = amd_flash_read;
|
||||
mtd->write = amd_flash_write;
|
||||
mtd->sync = amd_flash_sync;
|
||||
mtd->suspend = amd_flash_suspend;
|
||||
mtd->resume = amd_flash_resume;
|
||||
mtd->erase = amd_flash_erase;
|
||||
mtd->read = amd_flash_read;
|
||||
mtd->write = amd_flash_write;
|
||||
mtd->sync = amd_flash_sync;
|
||||
mtd->suspend = amd_flash_suspend;
|
||||
mtd->resume = amd_flash_resume;
|
||||
mtd->lock = amd_flash_lock;
|
||||
mtd->unlock = amd_flash_unlock;
|
||||
|
||||
|
@ -789,7 +789,7 @@ static inline int read_one_chip(struct map_info *map, struct flchip *chip,
|
|||
map->name, chip->state);
|
||||
set_current_state(TASK_UNINTERRUPTIBLE);
|
||||
add_wait_queue(&chip->wq, &wait);
|
||||
|
||||
|
||||
spin_unlock_bh(chip->mutex);
|
||||
|
||||
schedule();
|
||||
|
@ -802,7 +802,7 @@ static inline int read_one_chip(struct map_info *map, struct flchip *chip,
|
|||
timeo = jiffies + HZ;
|
||||
|
||||
goto retry;
|
||||
}
|
||||
}
|
||||
|
||||
adr += chip->start;
|
||||
|
||||
|
@ -889,7 +889,7 @@ static int write_one_word(struct map_info *map, struct flchip *chip,
|
|||
map->name, chip->state);
|
||||
set_current_state(TASK_UNINTERRUPTIBLE);
|
||||
add_wait_queue(&chip->wq, &wait);
|
||||
|
||||
|
||||
spin_unlock_bh(chip->mutex);
|
||||
|
||||
schedule();
|
||||
|
@ -901,7 +901,7 @@ static int write_one_word(struct map_info *map, struct flchip *chip,
|
|||
timeo = jiffies + HZ;
|
||||
|
||||
goto retry;
|
||||
}
|
||||
}
|
||||
|
||||
chip->state = FL_WRITING;
|
||||
|
||||
|
@ -911,7 +911,7 @@ static int write_one_word(struct map_info *map, struct flchip *chip,
|
|||
wide_write(map, datum, adr);
|
||||
|
||||
times_left = 500000;
|
||||
while (times_left-- && flash_is_busy(map, adr, private->interleave)) {
|
||||
while (times_left-- && flash_is_busy(map, adr, private->interleave)) {
|
||||
if (need_resched()) {
|
||||
spin_unlock_bh(chip->mutex);
|
||||
schedule();
|
||||
|
@ -989,7 +989,7 @@ static int amd_flash_write(struct mtd_info *mtd, loff_t to , size_t len,
|
|||
if (ret) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
ofs += n;
|
||||
buf += n;
|
||||
(*retlen) += n;
|
||||
|
@ -1002,7 +1002,7 @@ static int amd_flash_write(struct mtd_info *mtd, loff_t to , size_t len,
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* We are now aligned, write as much as possible. */
|
||||
while(len >= map->buswidth) {
|
||||
__u32 datum;
|
||||
|
@ -1063,7 +1063,7 @@ static int amd_flash_write(struct mtd_info *mtd, loff_t to , size_t len,
|
|||
if (ret) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
(*retlen) += n;
|
||||
}
|
||||
|
||||
|
@ -1085,7 +1085,7 @@ static inline int erase_one_block(struct map_info *map, struct flchip *chip,
|
|||
if (chip->state != FL_READY){
|
||||
set_current_state(TASK_UNINTERRUPTIBLE);
|
||||
add_wait_queue(&chip->wq, &wait);
|
||||
|
||||
|
||||
spin_unlock_bh(chip->mutex);
|
||||
|
||||
schedule();
|
||||
|
@ -1098,7 +1098,7 @@ static inline int erase_one_block(struct map_info *map, struct flchip *chip,
|
|||
timeo = jiffies + HZ;
|
||||
|
||||
goto retry;
|
||||
}
|
||||
}
|
||||
|
||||
chip->state = FL_ERASING;
|
||||
|
||||
|
@ -1106,30 +1106,30 @@ static inline int erase_one_block(struct map_info *map, struct flchip *chip,
|
|||
ENABLE_VPP(map);
|
||||
send_cmd(map, chip->start, CMD_SECTOR_ERASE_UNLOCK_DATA);
|
||||
send_cmd_to_addr(map, chip->start, CMD_SECTOR_ERASE_UNLOCK_DATA_2, adr);
|
||||
|
||||
|
||||
timeo = jiffies + (HZ * 20);
|
||||
|
||||
spin_unlock_bh(chip->mutex);
|
||||
msleep(1000);
|
||||
spin_lock_bh(chip->mutex);
|
||||
|
||||
|
||||
while (flash_is_busy(map, adr, private->interleave)) {
|
||||
|
||||
if (chip->state != FL_ERASING) {
|
||||
/* Someone's suspended the erase. Sleep */
|
||||
set_current_state(TASK_UNINTERRUPTIBLE);
|
||||
add_wait_queue(&chip->wq, &wait);
|
||||
|
||||
|
||||
spin_unlock_bh(chip->mutex);
|
||||
printk(KERN_INFO "%s: erase suspended. Sleeping\n",
|
||||
map->name);
|
||||
schedule();
|
||||
remove_wait_queue(&chip->wq, &wait);
|
||||
|
||||
|
||||
if (signal_pending(current)) {
|
||||
return -EINTR;
|
||||
}
|
||||
|
||||
|
||||
timeo = jiffies + (HZ*2); /* FIXME */
|
||||
spin_lock_bh(chip->mutex);
|
||||
continue;
|
||||
|
@ -1145,7 +1145,7 @@ static inline int erase_one_block(struct map_info *map, struct flchip *chip,
|
|||
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
|
||||
/* Latency issues. Drop the lock, wait a while and retry */
|
||||
spin_unlock_bh(chip->mutex);
|
||||
|
||||
|
@ -1153,7 +1153,7 @@ static inline int erase_one_block(struct map_info *map, struct flchip *chip,
|
|||
schedule();
|
||||
else
|
||||
udelay(1);
|
||||
|
||||
|
||||
spin_lock_bh(chip->mutex);
|
||||
}
|
||||
|
||||
|
@ -1180,7 +1180,7 @@ static inline int erase_one_block(struct map_info *map, struct flchip *chip,
|
|||
return -EIO;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
DISABLE_VPP(map);
|
||||
chip->state = FL_READY;
|
||||
wake_up(&chip->wq);
|
||||
|
@ -1246,7 +1246,7 @@ static int amd_flash_erase(struct mtd_info *mtd, struct erase_info *instr)
|
|||
* with the erase region at that address.
|
||||
*/
|
||||
|
||||
while ((i < mtd->numeraseregions) &&
|
||||
while ((i < mtd->numeraseregions) &&
|
||||
((instr->addr + instr->len) >= regions[i].offset)) {
|
||||
i++;
|
||||
}
|
||||
|
@ -1293,10 +1293,10 @@ static int amd_flash_erase(struct mtd_info *mtd, struct erase_info *instr)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
instr->state = MTD_ERASE_DONE;
|
||||
mtd_erase_callback(instr);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1324,7 +1324,7 @@ static void amd_flash_sync(struct mtd_info *mtd)
|
|||
case FL_JEDEC_QUERY:
|
||||
chip->oldstate = chip->state;
|
||||
chip->state = FL_SYNCING;
|
||||
/* No need to wake_up() on this state change -
|
||||
/* No need to wake_up() on this state change -
|
||||
* as the whole point is that nobody can do anything
|
||||
* with the chip now anyway.
|
||||
*/
|
||||
|
@ -1335,13 +1335,13 @@ static void amd_flash_sync(struct mtd_info *mtd)
|
|||
default:
|
||||
/* Not an idle state */
|
||||
add_wait_queue(&chip->wq, &wait);
|
||||
|
||||
|
||||
spin_unlock_bh(chip->mutex);
|
||||
|
||||
schedule();
|
||||
|
||||
remove_wait_queue(&chip->wq, &wait);
|
||||
|
||||
|
||||
goto retry;
|
||||
}
|
||||
}
|
||||
|
@ -1351,7 +1351,7 @@ static void amd_flash_sync(struct mtd_info *mtd)
|
|||
chip = &private->chips[i];
|
||||
|
||||
spin_lock_bh(chip->mutex);
|
||||
|
||||
|
||||
if (chip->state == FL_SYNCING) {
|
||||
chip->state = chip->oldstate;
|
||||
wake_up(&chip->wq);
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -10,14 +10,14 @@
|
|||
*
|
||||
* 4_by_16 work by Carolyn J. Smith
|
||||
*
|
||||
* XIP support hooks by Vitaly Wool (based on code for Intel flash
|
||||
* XIP support hooks by Vitaly Wool (based on code for Intel flash
|
||||
* by Nicolas Pitre)
|
||||
*
|
||||
*
|
||||
* Occasionally maintained by Thayne Harbaugh tharbaugh at lnxi dot com
|
||||
*
|
||||
* This code is GPL
|
||||
*
|
||||
* $Id: cfi_cmdset_0002.c,v 1.118 2005/07/04 22:34:29 gleixner Exp $
|
||||
* $Id: cfi_cmdset_0002.c,v 1.122 2005/11/07 11:14:22 gleixner Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
|
@ -93,7 +93,7 @@ static void cfi_tell_features(struct cfi_pri_amdstd *extp)
|
|||
};
|
||||
|
||||
printk(" Silicon revision: %d\n", extp->SiliconRevision >> 1);
|
||||
printk(" Address sensitive unlock: %s\n",
|
||||
printk(" Address sensitive unlock: %s\n",
|
||||
(extp->SiliconRevision & 1) ? "Not required" : "Required");
|
||||
|
||||
if (extp->EraseSuspend < ARRAY_SIZE(erase_suspend))
|
||||
|
@ -118,9 +118,9 @@ static void cfi_tell_features(struct cfi_pri_amdstd *extp)
|
|||
else
|
||||
printk(" Page mode: %d word page\n", extp->PageMode << 2);
|
||||
|
||||
printk(" Vpp Supply Minimum Program/Erase Voltage: %d.%d V\n",
|
||||
printk(" Vpp Supply Minimum Program/Erase Voltage: %d.%d V\n",
|
||||
extp->VppMin >> 4, extp->VppMin & 0xf);
|
||||
printk(" Vpp Supply Maximum Program/Erase Voltage: %d.%d V\n",
|
||||
printk(" Vpp Supply Maximum Program/Erase Voltage: %d.%d V\n",
|
||||
extp->VppMax >> 4, extp->VppMax & 0xf);
|
||||
|
||||
if (extp->TopBottom < ARRAY_SIZE(top_bottom))
|
||||
|
@ -177,7 +177,7 @@ static void fixup_use_erase_chip(struct mtd_info *mtd, void *param)
|
|||
((cfi->cfiq->EraseRegionInfo[0] & 0xffff) == 0)) {
|
||||
mtd->erase = cfi_amdstd_erase_chip;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
static struct cfi_fixup cfi_fixup_table[] = {
|
||||
|
@ -239,7 +239,7 @@ struct mtd_info *cfi_cmdset_0002(struct map_info *map, int primary)
|
|||
|
||||
if (cfi->cfi_mode==CFI_MODE_CFI){
|
||||
unsigned char bootloc;
|
||||
/*
|
||||
/*
|
||||
* It's a real CFI chip, not one for which the probe
|
||||
* routine faked a CFI structure. So we read the feature
|
||||
* table from it.
|
||||
|
@ -253,8 +253,18 @@ struct mtd_info *cfi_cmdset_0002(struct map_info *map, int primary)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
if (extp->MajorVersion != '1' ||
|
||||
(extp->MinorVersion < '0' || extp->MinorVersion > '4')) {
|
||||
printk(KERN_ERR " Unknown Amd/Fujitsu Extended Query "
|
||||
"version %c.%c.\n", extp->MajorVersion,
|
||||
extp->MinorVersion);
|
||||
kfree(extp);
|
||||
kfree(mtd);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Install our own private info structure */
|
||||
cfi->cmdset_priv = extp;
|
||||
cfi->cmdset_priv = extp;
|
||||
|
||||
/* Apply cfi device specific fixups */
|
||||
cfi_fixup(mtd, cfi_fixup_table);
|
||||
|
@ -262,7 +272,7 @@ struct mtd_info *cfi_cmdset_0002(struct map_info *map, int primary)
|
|||
#ifdef DEBUG_CFI_FEATURES
|
||||
/* Tell the user about it in lots of lovely detail */
|
||||
cfi_tell_features(extp);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
bootloc = extp->TopBottom;
|
||||
if ((bootloc != 2) && (bootloc != 3)) {
|
||||
|
@ -273,11 +283,11 @@ struct mtd_info *cfi_cmdset_0002(struct map_info *map, int primary)
|
|||
|
||||
if (bootloc == 3 && cfi->cfiq->NumEraseRegions > 1) {
|
||||
printk(KERN_WARNING "%s: Swapping erase regions for broken CFI table.\n", map->name);
|
||||
|
||||
|
||||
for (i=0; i<cfi->cfiq->NumEraseRegions / 2; i++) {
|
||||
int j = (cfi->cfiq->NumEraseRegions-1)-i;
|
||||
__u32 swap;
|
||||
|
||||
|
||||
swap = cfi->cfiq->EraseRegionInfo[i];
|
||||
cfi->cfiq->EraseRegionInfo[i] = cfi->cfiq->EraseRegionInfo[j];
|
||||
cfi->cfiq->EraseRegionInfo[j] = swap;
|
||||
|
@ -288,11 +298,11 @@ struct mtd_info *cfi_cmdset_0002(struct map_info *map, int primary)
|
|||
cfi->addr_unlock2 = 0x2aa;
|
||||
/* Modify the unlock address if we are in compatibility mode */
|
||||
if ( /* x16 in x8 mode */
|
||||
((cfi->device_type == CFI_DEVICETYPE_X8) &&
|
||||
((cfi->device_type == CFI_DEVICETYPE_X8) &&
|
||||
(cfi->cfiq->InterfaceDesc == 2)) ||
|
||||
/* x32 in x16 mode */
|
||||
((cfi->device_type == CFI_DEVICETYPE_X16) &&
|
||||
(cfi->cfiq->InterfaceDesc == 4)))
|
||||
(cfi->cfiq->InterfaceDesc == 4)))
|
||||
{
|
||||
cfi->addr_unlock1 = 0xaaa;
|
||||
cfi->addr_unlock2 = 0x555;
|
||||
|
@ -310,10 +320,10 @@ struct mtd_info *cfi_cmdset_0002(struct map_info *map, int primary)
|
|||
cfi->chips[i].word_write_time = 1<<cfi->cfiq->WordWriteTimeoutTyp;
|
||||
cfi->chips[i].buffer_write_time = 1<<cfi->cfiq->BufWriteTimeoutTyp;
|
||||
cfi->chips[i].erase_time = 1<<cfi->cfiq->BlockEraseTimeoutTyp;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
map->fldrv = &cfi_amdstd_chipdrv;
|
||||
|
||||
|
||||
return cfi_amdstd_setup(mtd);
|
||||
}
|
||||
|
||||
|
@ -326,24 +336,24 @@ static struct mtd_info *cfi_amdstd_setup(struct mtd_info *mtd)
|
|||
unsigned long offset = 0;
|
||||
int i,j;
|
||||
|
||||
printk(KERN_NOTICE "number of %s chips: %d\n",
|
||||
printk(KERN_NOTICE "number of %s chips: %d\n",
|
||||
(cfi->cfi_mode == CFI_MODE_CFI)?"CFI":"JEDEC",cfi->numchips);
|
||||
/* Select the correct geometry setup */
|
||||
/* Select the correct geometry setup */
|
||||
mtd->size = devsize * cfi->numchips;
|
||||
|
||||
mtd->numeraseregions = cfi->cfiq->NumEraseRegions * cfi->numchips;
|
||||
mtd->eraseregions = kmalloc(sizeof(struct mtd_erase_region_info)
|
||||
* mtd->numeraseregions, GFP_KERNEL);
|
||||
if (!mtd->eraseregions) {
|
||||
if (!mtd->eraseregions) {
|
||||
printk(KERN_WARNING "Failed to allocate memory for MTD erase region info\n");
|
||||
goto setup_err;
|
||||
}
|
||||
|
||||
|
||||
for (i=0; i<cfi->cfiq->NumEraseRegions; i++) {
|
||||
unsigned long ernum, ersize;
|
||||
ersize = ((cfi->cfiq->EraseRegionInfo[i] >> 8) & ~0xff) * cfi->interleave;
|
||||
ernum = (cfi->cfiq->EraseRegionInfo[i] & 0xffff) + 1;
|
||||
|
||||
|
||||
if (mtd->erasesize < ersize) {
|
||||
mtd->erasesize = ersize;
|
||||
}
|
||||
|
@ -429,7 +439,7 @@ static int __xipram chip_good(struct map_info *map, unsigned long addr, map_word
|
|||
oldd = map_read(map, addr);
|
||||
curd = map_read(map, addr);
|
||||
|
||||
return map_word_equal(map, oldd, curd) &&
|
||||
return map_word_equal(map, oldd, curd) &&
|
||||
map_word_equal(map, curd, expected);
|
||||
}
|
||||
|
||||
|
@ -461,7 +471,7 @@ static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr
|
|||
/* Someone else might have been playing with it. */
|
||||
goto retry;
|
||||
}
|
||||
|
||||
|
||||
case FL_READY:
|
||||
case FL_CFI_QUERY:
|
||||
case FL_JEDEC_QUERY:
|
||||
|
@ -504,7 +514,7 @@ static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr
|
|||
printk(KERN_ERR "MTD %s(): chip not ready after erase suspend\n", __func__);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
|
||||
spin_unlock(chip->mutex);
|
||||
cfi_udelay(1);
|
||||
spin_lock(chip->mutex);
|
||||
|
@ -607,7 +617,7 @@ static void __xipram xip_enable(struct map_info *map, struct flchip *chip,
|
|||
* When a delay is required for the flash operation to complete, the
|
||||
* xip_udelay() function is polling for both the given timeout and pending
|
||||
* (but still masked) hardware interrupts. Whenever there is an interrupt
|
||||
* pending then the flash erase operation is suspended, array mode restored
|
||||
* pending then the flash erase operation is suspended, array mode restored
|
||||
* and interrupts unmasked. Task scheduling might also happen at that
|
||||
* point. The CPU eventually returns from the interrupt or the call to
|
||||
* schedule() and the suspended flash operation is resumed for the remaining
|
||||
|
@ -631,9 +641,9 @@ static void __xipram xip_udelay(struct map_info *map, struct flchip *chip,
|
|||
((chip->state == FL_ERASING && (extp->EraseSuspend & 2))) &&
|
||||
(cfi_interleave_is_1(cfi) || chip->oldstate == FL_READY)) {
|
||||
/*
|
||||
* Let's suspend the erase operation when supported.
|
||||
* Note that we currently don't try to suspend
|
||||
* interleaved chips if there is already another
|
||||
* Let's suspend the erase operation when supported.
|
||||
* Note that we currently don't try to suspend
|
||||
* interleaved chips if there is already another
|
||||
* operation suspended (imagine what happens
|
||||
* when one chip was already done with the current
|
||||
* operation while another chip suspended it, then
|
||||
|
@ -769,8 +779,8 @@ static inline int do_read_onechip(struct map_info *map, struct flchip *chip, lof
|
|||
|
||||
adr += chip->start;
|
||||
|
||||
/* Ensure cmd read/writes are aligned. */
|
||||
cmd_addr = adr & ~(map_bankwidth(map)-1);
|
||||
/* Ensure cmd read/writes are aligned. */
|
||||
cmd_addr = adr & ~(map_bankwidth(map)-1);
|
||||
|
||||
spin_lock(chip->mutex);
|
||||
ret = get_chip(map, chip, cmd_addr, FL_READY);
|
||||
|
@ -850,7 +860,7 @@ static inline int do_read_secsi_onechip(struct map_info *map, struct flchip *chi
|
|||
#endif
|
||||
set_current_state(TASK_UNINTERRUPTIBLE);
|
||||
add_wait_queue(&chip->wq, &wait);
|
||||
|
||||
|
||||
spin_unlock(chip->mutex);
|
||||
|
||||
schedule();
|
||||
|
@ -862,7 +872,7 @@ static inline int do_read_secsi_onechip(struct map_info *map, struct flchip *chi
|
|||
timeo = jiffies + HZ;
|
||||
|
||||
goto retry;
|
||||
}
|
||||
}
|
||||
|
||||
adr += chip->start;
|
||||
|
||||
|
@ -871,14 +881,14 @@ static inline int do_read_secsi_onechip(struct map_info *map, struct flchip *chi
|
|||
cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL);
|
||||
cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, cfi->device_type, NULL);
|
||||
cfi_send_gen_cmd(0x88, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL);
|
||||
|
||||
|
||||
map_copy_from(map, buf, adr, len);
|
||||
|
||||
cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL);
|
||||
cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, cfi->device_type, NULL);
|
||||
cfi_send_gen_cmd(0x90, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL);
|
||||
cfi_send_gen_cmd(0x00, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL);
|
||||
|
||||
|
||||
wake_up(&chip->wq);
|
||||
spin_unlock(chip->mutex);
|
||||
|
||||
|
@ -987,7 +997,7 @@ static int __xipram do_write_oneword(struct map_info *map, struct flchip *chip,
|
|||
chip->word_write_time);
|
||||
|
||||
/* See comment above for timeout value. */
|
||||
timeo = jiffies + uWriteTimeout;
|
||||
timeo = jiffies + uWriteTimeout;
|
||||
for (;;) {
|
||||
if (chip->state != FL_WRITING) {
|
||||
/* Someone's suspended the write. Sleep */
|
||||
|
@ -1003,16 +1013,16 @@ static int __xipram do_write_oneword(struct map_info *map, struct flchip *chip,
|
|||
continue;
|
||||
}
|
||||
|
||||
if (chip_ready(map, adr))
|
||||
break;
|
||||
|
||||
if (time_after(jiffies, timeo)) {
|
||||
if (time_after(jiffies, timeo) && !chip_ready(map, adr)){
|
||||
xip_enable(map, chip, adr);
|
||||
printk(KERN_WARNING "MTD %s(): software timeout\n", __func__);
|
||||
xip_disable(map, chip, adr);
|
||||
break;
|
||||
break;
|
||||
}
|
||||
|
||||
if (chip_ready(map, adr))
|
||||
break;
|
||||
|
||||
/* Latency issues. Drop the lock, wait a while and retry */
|
||||
UDELAY(map, chip, adr, 1);
|
||||
}
|
||||
|
@ -1022,7 +1032,7 @@ static int __xipram do_write_oneword(struct map_info *map, struct flchip *chip,
|
|||
map_write( map, CMD(0xF0), chip->start );
|
||||
/* FIXME - should have reset delay before continuing */
|
||||
|
||||
if (++retry_cnt <= MAX_WORD_RETRIES)
|
||||
if (++retry_cnt <= MAX_WORD_RETRIES)
|
||||
goto retry;
|
||||
|
||||
ret = -EIO;
|
||||
|
@ -1090,27 +1100,27 @@ static int cfi_amdstd_write_words(struct mtd_info *mtd, loff_t to, size_t len,
|
|||
|
||||
/* Number of bytes to copy from buffer */
|
||||
n = min_t(int, len, map_bankwidth(map)-i);
|
||||
|
||||
|
||||
tmp_buf = map_word_load_partial(map, tmp_buf, buf, i, n);
|
||||
|
||||
ret = do_write_oneword(map, &cfi->chips[chipnum],
|
||||
ret = do_write_oneword(map, &cfi->chips[chipnum],
|
||||
bus_ofs, tmp_buf);
|
||||
if (ret)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
||||
ofs += n;
|
||||
buf += n;
|
||||
(*retlen) += n;
|
||||
len -= n;
|
||||
|
||||
if (ofs >> cfi->chipshift) {
|
||||
chipnum ++;
|
||||
chipnum ++;
|
||||
ofs = 0;
|
||||
if (chipnum == cfi->numchips)
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* We are now aligned, write as much as possible */
|
||||
while(len >= map_bankwidth(map)) {
|
||||
map_word datum;
|
||||
|
@ -1128,7 +1138,7 @@ static int cfi_amdstd_write_words(struct mtd_info *mtd, loff_t to, size_t len,
|
|||
len -= map_bankwidth(map);
|
||||
|
||||
if (ofs >> cfi->chipshift) {
|
||||
chipnum ++;
|
||||
chipnum ++;
|
||||
ofs = 0;
|
||||
if (chipnum == cfi->numchips)
|
||||
return 0;
|
||||
|
@ -1166,12 +1176,12 @@ static int cfi_amdstd_write_words(struct mtd_info *mtd, loff_t to, size_t len,
|
|||
spin_unlock(cfi->chips[chipnum].mutex);
|
||||
|
||||
tmp_buf = map_word_load_partial(map, tmp_buf, buf, 0, len);
|
||||
|
||||
ret = do_write_oneword(map, &cfi->chips[chipnum],
|
||||
|
||||
ret = do_write_oneword(map, &cfi->chips[chipnum],
|
||||
ofs, tmp_buf);
|
||||
if (ret)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
||||
(*retlen) += len;
|
||||
}
|
||||
|
||||
|
@ -1183,7 +1193,7 @@ static int cfi_amdstd_write_words(struct mtd_info *mtd, loff_t to, size_t len,
|
|||
* FIXME: interleaved mode not tested, and probably not supported!
|
||||
*/
|
||||
static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,
|
||||
unsigned long adr, const u_char *buf,
|
||||
unsigned long adr, const u_char *buf,
|
||||
int len)
|
||||
{
|
||||
struct cfi_private *cfi = map->fldrv_priv;
|
||||
|
@ -1213,7 +1223,7 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,
|
|||
XIP_INVAL_CACHED_RANGE(map, adr, len);
|
||||
ENABLE_VPP(map);
|
||||
xip_disable(map, chip, cmd_adr);
|
||||
|
||||
|
||||
cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL);
|
||||
cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, cfi->device_type, NULL);
|
||||
//cfi_send_gen_cmd(0xA0, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL);
|
||||
|
@ -1247,8 +1257,8 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,
|
|||
adr, map_bankwidth(map),
|
||||
chip->word_write_time);
|
||||
|
||||
timeo = jiffies + uWriteTimeout;
|
||||
|
||||
timeo = jiffies + uWriteTimeout;
|
||||
|
||||
for (;;) {
|
||||
if (chip->state != FL_WRITING) {
|
||||
/* Someone's suspended the write. Sleep */
|
||||
|
@ -1264,13 +1274,13 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,
|
|||
continue;
|
||||
}
|
||||
|
||||
if (time_after(jiffies, timeo) && !chip_ready(map, adr))
|
||||
break;
|
||||
|
||||
if (chip_ready(map, adr)) {
|
||||
xip_enable(map, chip, adr);
|
||||
goto op_done;
|
||||
}
|
||||
|
||||
if( time_after(jiffies, timeo))
|
||||
break;
|
||||
|
||||
/* Latency issues. Drop the lock, wait a while and retry */
|
||||
UDELAY(map, chip, adr, 1);
|
||||
|
@ -1342,7 +1352,7 @@ static int cfi_amdstd_write_buffers(struct mtd_info *mtd, loff_t to, size_t len,
|
|||
if (size % map_bankwidth(map))
|
||||
size -= size % map_bankwidth(map);
|
||||
|
||||
ret = do_write_buffer(map, &cfi->chips[chipnum],
|
||||
ret = do_write_buffer(map, &cfi->chips[chipnum],
|
||||
ofs, buf, size);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
@ -1353,7 +1363,7 @@ static int cfi_amdstd_write_buffers(struct mtd_info *mtd, loff_t to, size_t len,
|
|||
len -= size;
|
||||
|
||||
if (ofs >> cfi->chipshift) {
|
||||
chipnum ++;
|
||||
chipnum ++;
|
||||
ofs = 0;
|
||||
if (chipnum == cfi->numchips)
|
||||
return 0;
|
||||
|
@ -1570,7 +1580,7 @@ int cfi_amdstd_erase_varsize(struct mtd_info *mtd, struct erase_info *instr)
|
|||
|
||||
instr->state = MTD_ERASE_DONE;
|
||||
mtd_erase_callback(instr);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1593,7 +1603,7 @@ static int cfi_amdstd_erase_chip(struct mtd_info *mtd, struct erase_info *instr)
|
|||
|
||||
instr->state = MTD_ERASE_DONE;
|
||||
mtd_erase_callback(instr);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1620,7 +1630,7 @@ static void cfi_amdstd_sync (struct mtd_info *mtd)
|
|||
case FL_JEDEC_QUERY:
|
||||
chip->oldstate = chip->state;
|
||||
chip->state = FL_SYNCING;
|
||||
/* No need to wake_up() on this state change -
|
||||
/* No need to wake_up() on this state change -
|
||||
* as the whole point is that nobody can do anything
|
||||
* with the chip now anyway.
|
||||
*/
|
||||
|
@ -1631,13 +1641,13 @@ static void cfi_amdstd_sync (struct mtd_info *mtd)
|
|||
default:
|
||||
/* Not an idle state */
|
||||
add_wait_queue(&chip->wq, &wait);
|
||||
|
||||
|
||||
spin_unlock(chip->mutex);
|
||||
|
||||
schedule();
|
||||
|
||||
remove_wait_queue(&chip->wq, &wait);
|
||||
|
||||
|
||||
goto retry;
|
||||
}
|
||||
}
|
||||
|
@ -1648,7 +1658,7 @@ static void cfi_amdstd_sync (struct mtd_info *mtd)
|
|||
chip = &cfi->chips[i];
|
||||
|
||||
spin_lock(chip->mutex);
|
||||
|
||||
|
||||
if (chip->state == FL_SYNCING) {
|
||||
chip->state = chip->oldstate;
|
||||
wake_up(&chip->wq);
|
||||
|
@ -1678,7 +1688,7 @@ static int cfi_amdstd_suspend(struct mtd_info *mtd)
|
|||
case FL_JEDEC_QUERY:
|
||||
chip->oldstate = chip->state;
|
||||
chip->state = FL_PM_SUSPENDED;
|
||||
/* No need to wake_up() on this state change -
|
||||
/* No need to wake_up() on this state change -
|
||||
* as the whole point is that nobody can do anything
|
||||
* with the chip now anyway.
|
||||
*/
|
||||
|
@ -1699,7 +1709,7 @@ static int cfi_amdstd_suspend(struct mtd_info *mtd)
|
|||
chip = &cfi->chips[i];
|
||||
|
||||
spin_lock(chip->mutex);
|
||||
|
||||
|
||||
if (chip->state == FL_PM_SUSPENDED) {
|
||||
chip->state = chip->oldstate;
|
||||
wake_up(&chip->wq);
|
||||
|
@ -1707,7 +1717,7 @@ static int cfi_amdstd_suspend(struct mtd_info *mtd)
|
|||
spin_unlock(chip->mutex);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -1720,11 +1730,11 @@ static void cfi_amdstd_resume(struct mtd_info *mtd)
|
|||
struct flchip *chip;
|
||||
|
||||
for (i=0; i<cfi->numchips; i++) {
|
||||
|
||||
|
||||
chip = &cfi->chips[i];
|
||||
|
||||
spin_lock(chip->mutex);
|
||||
|
||||
|
||||
if (chip->state == FL_PM_SUSPENDED) {
|
||||
chip->state = FL_READY;
|
||||
map_write(map, CMD(0xF0), chip->start);
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
*
|
||||
* (C) 2000 Red Hat. GPL'd
|
||||
*
|
||||
* $Id: cfi_cmdset_0020.c,v 1.19 2005/07/13 15:52:45 dwmw2 Exp $
|
||||
*
|
||||
* $Id: cfi_cmdset_0020.c,v 1.22 2005/11/07 11:14:22 gleixner Exp $
|
||||
*
|
||||
* 10/10/2000 Nicolas Pitre <nico@cam.org>
|
||||
* - completely revamped method functions so they are aware and
|
||||
* independent of the flash geometry (buswidth, interleave, etc.)
|
||||
|
@ -81,17 +81,17 @@ static void cfi_tell_features(struct cfi_pri_intelext *extp)
|
|||
printk(" - Page-mode read: %s\n", extp->FeatureSupport&128?"supported":"unsupported");
|
||||
printk(" - Synchronous read: %s\n", extp->FeatureSupport&256?"supported":"unsupported");
|
||||
for (i=9; i<32; i++) {
|
||||
if (extp->FeatureSupport & (1<<i))
|
||||
if (extp->FeatureSupport & (1<<i))
|
||||
printk(" - Unknown Bit %X: supported\n", i);
|
||||
}
|
||||
|
||||
|
||||
printk(" Supported functions after Suspend: %2.2X\n", extp->SuspendCmdSupport);
|
||||
printk(" - Program after Erase Suspend: %s\n", extp->SuspendCmdSupport&1?"supported":"unsupported");
|
||||
for (i=1; i<8; i++) {
|
||||
if (extp->SuspendCmdSupport & (1<<i))
|
||||
printk(" - Unknown Bit %X: supported\n", i);
|
||||
}
|
||||
|
||||
|
||||
printk(" Block Status Register Mask: %4.4X\n", extp->BlkStatusRegMask);
|
||||
printk(" - Lock Bit Active: %s\n", extp->BlkStatusRegMask&1?"yes":"no");
|
||||
printk(" - Valid Bit Active: %s\n", extp->BlkStatusRegMask&2?"yes":"no");
|
||||
|
@ -99,11 +99,11 @@ static void cfi_tell_features(struct cfi_pri_intelext *extp)
|
|||
if (extp->BlkStatusRegMask & (1<<i))
|
||||
printk(" - Unknown Bit %X Active: yes\n",i);
|
||||
}
|
||||
|
||||
printk(" Vcc Logic Supply Optimum Program/Erase Voltage: %d.%d V\n",
|
||||
|
||||
printk(" Vcc Logic Supply Optimum Program/Erase Voltage: %d.%d V\n",
|
||||
extp->VccOptimal >> 8, extp->VccOptimal & 0xf);
|
||||
if (extp->VppOptimal)
|
||||
printk(" Vpp Programming Supply Optimum Program/Erase Voltage: %d.%d V\n",
|
||||
printk(" Vpp Programming Supply Optimum Program/Erase Voltage: %d.%d V\n",
|
||||
extp->VppOptimal >> 8, extp->VppOptimal & 0xf);
|
||||
}
|
||||
#endif
|
||||
|
@ -121,7 +121,7 @@ struct mtd_info *cfi_cmdset_0020(struct map_info *map, int primary)
|
|||
int i;
|
||||
|
||||
if (cfi->cfi_mode) {
|
||||
/*
|
||||
/*
|
||||
* It's a real CFI chip, not one for which the probe
|
||||
* routine faked a CFI structure. So we read the feature
|
||||
* table from it.
|
||||
|
@ -133,24 +133,33 @@ struct mtd_info *cfi_cmdset_0020(struct map_info *map, int primary)
|
|||
if (!extp)
|
||||
return NULL;
|
||||
|
||||
if (extp->MajorVersion != '1' ||
|
||||
(extp->MinorVersion < '0' || extp->MinorVersion > '3')) {
|
||||
printk(KERN_ERR " Unknown ST Microelectronics"
|
||||
" Extended Query version %c.%c.\n",
|
||||
extp->MajorVersion, extp->MinorVersion);
|
||||
kfree(extp);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Do some byteswapping if necessary */
|
||||
extp->FeatureSupport = cfi32_to_cpu(extp->FeatureSupport);
|
||||
extp->BlkStatusRegMask = cfi32_to_cpu(extp->BlkStatusRegMask);
|
||||
|
||||
|
||||
#ifdef DEBUG_CFI_FEATURES
|
||||
/* Tell the user about it in lots of lovely detail */
|
||||
cfi_tell_features(extp);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Install our own private info structure */
|
||||
cfi->cmdset_priv = extp;
|
||||
}
|
||||
}
|
||||
|
||||
for (i=0; i< cfi->numchips; i++) {
|
||||
cfi->chips[i].word_write_time = 128;
|
||||
cfi->chips[i].buffer_write_time = 128;
|
||||
cfi->chips[i].erase_time = 1024;
|
||||
}
|
||||
}
|
||||
|
||||
return cfi_staa_setup(map);
|
||||
}
|
||||
|
@ -178,15 +187,15 @@ static struct mtd_info *cfi_staa_setup(struct map_info *map)
|
|||
mtd->size = devsize * cfi->numchips;
|
||||
|
||||
mtd->numeraseregions = cfi->cfiq->NumEraseRegions * cfi->numchips;
|
||||
mtd->eraseregions = kmalloc(sizeof(struct mtd_erase_region_info)
|
||||
mtd->eraseregions = kmalloc(sizeof(struct mtd_erase_region_info)
|
||||
* mtd->numeraseregions, GFP_KERNEL);
|
||||
if (!mtd->eraseregions) {
|
||||
if (!mtd->eraseregions) {
|
||||
printk(KERN_ERR "Failed to allocate memory for MTD erase region info\n");
|
||||
kfree(cfi->cmdset_priv);
|
||||
kfree(mtd);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
for (i=0; i<cfi->cfiq->NumEraseRegions; i++) {
|
||||
unsigned long ernum, ersize;
|
||||
ersize = ((cfi->cfiq->EraseRegionInfo[i] >> 8) & ~0xff) * cfi->interleave;
|
||||
|
@ -219,7 +228,7 @@ static struct mtd_info *cfi_staa_setup(struct map_info *map)
|
|||
mtd->eraseregions[i].numblocks);
|
||||
}
|
||||
|
||||
/* Also select the correct geometry setup too */
|
||||
/* Also select the correct geometry setup too */
|
||||
mtd->erase = cfi_staa_erase_varsize;
|
||||
mtd->read = cfi_staa_read;
|
||||
mtd->write = cfi_staa_write_buffers;
|
||||
|
@ -250,8 +259,8 @@ static inline int do_read_onechip(struct map_info *map, struct flchip *chip, lof
|
|||
|
||||
adr += chip->start;
|
||||
|
||||
/* Ensure cmd read/writes are aligned. */
|
||||
cmd_addr = adr & ~(map_bankwidth(map)-1);
|
||||
/* Ensure cmd read/writes are aligned. */
|
||||
cmd_addr = adr & ~(map_bankwidth(map)-1);
|
||||
|
||||
/* Let's determine this according to the interleave only once */
|
||||
status_OK = CMD(0x80);
|
||||
|
@ -267,7 +276,7 @@ static inline int do_read_onechip(struct map_info *map, struct flchip *chip, lof
|
|||
case FL_ERASING:
|
||||
if (!(((struct cfi_pri_intelext *)cfi->cmdset_priv)->FeatureSupport & 2))
|
||||
goto sleep; /* We don't support erase suspend */
|
||||
|
||||
|
||||
map_write (map, CMD(0xb0), cmd_addr);
|
||||
/* If the flash has finished erasing, then 'erase suspend'
|
||||
* appears to make some (28F320) flash devices switch to
|
||||
|
@ -282,7 +291,7 @@ static inline int do_read_onechip(struct map_info *map, struct flchip *chip, lof
|
|||
status = map_read(map, cmd_addr);
|
||||
if (map_word_andequal(map, status, status_OK, status_OK))
|
||||
break;
|
||||
|
||||
|
||||
if (time_after(jiffies, timeo)) {
|
||||
/* Urgh */
|
||||
map_write(map, CMD(0xd0), cmd_addr);
|
||||
|
@ -294,17 +303,17 @@ static inline int do_read_onechip(struct map_info *map, struct flchip *chip, lof
|
|||
"suspended: status = 0x%lx\n", status.x[0]);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
|
||||
spin_unlock_bh(chip->mutex);
|
||||
cfi_udelay(1);
|
||||
spin_lock_bh(chip->mutex);
|
||||
}
|
||||
|
||||
|
||||
suspended = 1;
|
||||
map_write(map, CMD(0xff), cmd_addr);
|
||||
chip->state = FL_READY;
|
||||
break;
|
||||
|
||||
|
||||
#if 0
|
||||
case FL_WRITING:
|
||||
/* Not quite yet */
|
||||
|
@ -325,7 +334,7 @@ static inline int do_read_onechip(struct map_info *map, struct flchip *chip, lof
|
|||
chip->state = FL_READY;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
/* Urgh. Chip not yet ready to talk to us. */
|
||||
if (time_after(jiffies, timeo)) {
|
||||
spin_unlock_bh(chip->mutex);
|
||||
|
@ -355,17 +364,17 @@ static inline int do_read_onechip(struct map_info *map, struct flchip *chip, lof
|
|||
|
||||
if (suspended) {
|
||||
chip->state = chip->oldstate;
|
||||
/* What if one interleaved chip has finished and the
|
||||
/* What if one interleaved chip has finished and the
|
||||
other hasn't? The old code would leave the finished
|
||||
one in READY mode. That's bad, and caused -EROFS
|
||||
one in READY mode. That's bad, and caused -EROFS
|
||||
errors to be returned from do_erase_oneblock because
|
||||
that's the only bit it checked for at the time.
|
||||
As the state machine appears to explicitly allow
|
||||
As the state machine appears to explicitly allow
|
||||
sending the 0x70 (Read Status) command to an erasing
|
||||
chip and expecting it to be ignored, that's what we
|
||||
chip and expecting it to be ignored, that's what we
|
||||
do. */
|
||||
map_write(map, CMD(0xd0), cmd_addr);
|
||||
map_write(map, CMD(0x70), cmd_addr);
|
||||
map_write(map, CMD(0x70), cmd_addr);
|
||||
}
|
||||
|
||||
wake_up(&chip->wq);
|
||||
|
@ -405,14 +414,14 @@ static int cfi_staa_read (struct mtd_info *mtd, loff_t from, size_t len, size_t
|
|||
*retlen += thislen;
|
||||
len -= thislen;
|
||||
buf += thislen;
|
||||
|
||||
|
||||
ofs = 0;
|
||||
chipnum++;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline int do_write_buffer(struct map_info *map, struct flchip *chip,
|
||||
static inline int do_write_buffer(struct map_info *map, struct flchip *chip,
|
||||
unsigned long adr, const u_char *buf, int len)
|
||||
{
|
||||
struct cfi_private *cfi = map->fldrv_priv;
|
||||
|
@ -420,7 +429,7 @@ static inline int do_write_buffer(struct map_info *map, struct flchip *chip,
|
|||
unsigned long cmd_adr, timeo;
|
||||
DECLARE_WAITQUEUE(wait, current);
|
||||
int wbufsize, z;
|
||||
|
||||
|
||||
/* M58LW064A requires bus alignment for buffer wriets -- saw */
|
||||
if (adr & (map_bankwidth(map)-1))
|
||||
return -EINVAL;
|
||||
|
@ -428,10 +437,10 @@ static inline int do_write_buffer(struct map_info *map, struct flchip *chip,
|
|||
wbufsize = cfi_interleave(cfi) << cfi->cfiq->MaxBufWriteSize;
|
||||
adr += chip->start;
|
||||
cmd_adr = adr & ~(wbufsize-1);
|
||||
|
||||
|
||||
/* Let's determine this according to the interleave only once */
|
||||
status_OK = CMD(0x80);
|
||||
|
||||
|
||||
timeo = jiffies + HZ;
|
||||
retry:
|
||||
|
||||
|
@ -439,7 +448,7 @@ static inline int do_write_buffer(struct map_info *map, struct flchip *chip,
|
|||
printk("%s: chip->state[%d]\n", __FUNCTION__, chip->state);
|
||||
#endif
|
||||
spin_lock_bh(chip->mutex);
|
||||
|
||||
|
||||
/* Check that the chip's ready to talk to us.
|
||||
* Later, we can actually think about interrupting it
|
||||
* if it's in FL_ERASING state.
|
||||
|
@ -448,7 +457,7 @@ static inline int do_write_buffer(struct map_info *map, struct flchip *chip,
|
|||
switch (chip->state) {
|
||||
case FL_READY:
|
||||
break;
|
||||
|
||||
|
||||
case FL_CFI_QUERY:
|
||||
case FL_JEDEC_QUERY:
|
||||
map_write(map, CMD(0x70), cmd_adr);
|
||||
|
@ -513,7 +522,7 @@ static inline int do_write_buffer(struct map_info *map, struct flchip *chip,
|
|||
|
||||
/* Write length of data to come */
|
||||
map_write(map, CMD(len/map_bankwidth(map)-1), cmd_adr );
|
||||
|
||||
|
||||
/* Write data */
|
||||
for (z = 0; z < len;
|
||||
z += map_bankwidth(map), buf += map_bankwidth(map)) {
|
||||
|
@ -560,7 +569,7 @@ static inline int do_write_buffer(struct map_info *map, struct flchip *chip,
|
|||
printk(KERN_ERR "waiting for chip to be ready timed out in bufwrite\n");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
|
||||
/* Latency issues. Drop the lock, wait a while and retry */
|
||||
spin_unlock_bh(chip->mutex);
|
||||
cfi_udelay(1);
|
||||
|
@ -572,9 +581,9 @@ static inline int do_write_buffer(struct map_info *map, struct flchip *chip,
|
|||
if (!chip->buffer_write_time)
|
||||
chip->buffer_write_time++;
|
||||
}
|
||||
if (z > 1)
|
||||
if (z > 1)
|
||||
chip->buffer_write_time++;
|
||||
|
||||
|
||||
/* Done and happy. */
|
||||
DISABLE_VPP(map);
|
||||
chip->state = FL_STATUS;
|
||||
|
@ -598,7 +607,7 @@ static inline int do_write_buffer(struct map_info *map, struct flchip *chip,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int cfi_staa_write_buffers (struct mtd_info *mtd, loff_t to,
|
||||
static int cfi_staa_write_buffers (struct mtd_info *mtd, loff_t to,
|
||||
size_t len, size_t *retlen, const u_char *buf)
|
||||
{
|
||||
struct map_info *map = mtd->priv;
|
||||
|
@ -620,7 +629,7 @@ static int cfi_staa_write_buffers (struct mtd_info *mtd, loff_t to,
|
|||
printk("%s: chipnum[%x] wbufsize[%x]\n", __FUNCTION__, chipnum, wbufsize);
|
||||
printk("%s: ofs[%x] len[%x]\n", __FUNCTION__, ofs, len);
|
||||
#endif
|
||||
|
||||
|
||||
/* Write buffer is worth it only if more than one word to write... */
|
||||
while (len > 0) {
|
||||
/* We must not cross write block boundaries */
|
||||
|
@ -629,7 +638,7 @@ static int cfi_staa_write_buffers (struct mtd_info *mtd, loff_t to,
|
|||
if (size > len)
|
||||
size = len;
|
||||
|
||||
ret = do_write_buffer(map, &cfi->chips[chipnum],
|
||||
ret = do_write_buffer(map, &cfi->chips[chipnum],
|
||||
ofs, buf, size);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
@ -640,13 +649,13 @@ static int cfi_staa_write_buffers (struct mtd_info *mtd, loff_t to,
|
|||
len -= size;
|
||||
|
||||
if (ofs >> cfi->chipshift) {
|
||||
chipnum ++;
|
||||
chipnum ++;
|
||||
ofs = 0;
|
||||
if (chipnum == cfi->numchips)
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -756,7 +765,7 @@ static inline int do_erase_oneblock(struct map_info *map, struct flchip *chip, u
|
|||
status = map_read(map, adr);
|
||||
if (map_word_andequal(map, status, status_OK, status_OK))
|
||||
break;
|
||||
|
||||
|
||||
/* Urgh. Chip not yet ready to talk to us. */
|
||||
if (time_after(jiffies, timeo)) {
|
||||
spin_unlock_bh(chip->mutex);
|
||||
|
@ -789,7 +798,7 @@ static inline int do_erase_oneblock(struct map_info *map, struct flchip *chip, u
|
|||
map_write(map, CMD(0x20), adr);
|
||||
map_write(map, CMD(0xD0), adr);
|
||||
chip->state = FL_ERASING;
|
||||
|
||||
|
||||
spin_unlock_bh(chip->mutex);
|
||||
msleep(1000);
|
||||
spin_lock_bh(chip->mutex);
|
||||
|
@ -814,7 +823,7 @@ static inline int do_erase_oneblock(struct map_info *map, struct flchip *chip, u
|
|||
status = map_read(map, adr);
|
||||
if (map_word_andequal(map, status, status_OK, status_OK))
|
||||
break;
|
||||
|
||||
|
||||
/* OK Still waiting */
|
||||
if (time_after(jiffies, timeo)) {
|
||||
map_write(map, CMD(0x70), adr);
|
||||
|
@ -824,13 +833,13 @@ static inline int do_erase_oneblock(struct map_info *map, struct flchip *chip, u
|
|||
spin_unlock_bh(chip->mutex);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
|
||||
/* Latency issues. Drop the lock, wait a while and retry */
|
||||
spin_unlock_bh(chip->mutex);
|
||||
cfi_udelay(1);
|
||||
spin_lock_bh(chip->mutex);
|
||||
}
|
||||
|
||||
|
||||
DISABLE_VPP(map);
|
||||
ret = 0;
|
||||
|
||||
|
@ -855,7 +864,7 @@ static inline int do_erase_oneblock(struct map_info *map, struct flchip *chip, u
|
|||
/* Reset the error bits */
|
||||
map_write(map, CMD(0x50), adr);
|
||||
map_write(map, CMD(0x70), adr);
|
||||
|
||||
|
||||
if ((chipstatus & 0x30) == 0x30) {
|
||||
printk(KERN_NOTICE "Chip reports improper command sequence: status 0x%x\n", chipstatus);
|
||||
ret = -EIO;
|
||||
|
@ -904,17 +913,17 @@ int cfi_staa_erase_varsize(struct mtd_info *mtd, struct erase_info *instr)
|
|||
|
||||
i = 0;
|
||||
|
||||
/* Skip all erase regions which are ended before the start of
|
||||
/* Skip all erase regions which are ended before the start of
|
||||
the requested erase. Actually, to save on the calculations,
|
||||
we skip to the first erase region which starts after the
|
||||
start of the requested erase, and then go back one.
|
||||
*/
|
||||
|
||||
|
||||
while (i < mtd->numeraseregions && instr->addr >= regions[i].offset)
|
||||
i++;
|
||||
i--;
|
||||
|
||||
/* OK, now i is pointing at the erase region in which this
|
||||
/* OK, now i is pointing at the erase region in which this
|
||||
erase request starts. Check the start of the requested
|
||||
erase range is aligned with the erase size which is in
|
||||
effect here.
|
||||
|
@ -937,7 +946,7 @@ int cfi_staa_erase_varsize(struct mtd_info *mtd, struct erase_info *instr)
|
|||
the address actually falls
|
||||
*/
|
||||
i--;
|
||||
|
||||
|
||||
if ((instr->addr + instr->len) & (regions[i].erasesize-1))
|
||||
return -EINVAL;
|
||||
|
||||
|
@ -949,7 +958,7 @@ int cfi_staa_erase_varsize(struct mtd_info *mtd, struct erase_info *instr)
|
|||
|
||||
while(len) {
|
||||
ret = do_erase_oneblock(map, &cfi->chips[chipnum], adr);
|
||||
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@ -962,15 +971,15 @@ int cfi_staa_erase_varsize(struct mtd_info *mtd, struct erase_info *instr)
|
|||
if (adr >> cfi->chipshift) {
|
||||
adr = 0;
|
||||
chipnum++;
|
||||
|
||||
|
||||
if (chipnum >= cfi->numchips)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
instr->state = MTD_ERASE_DONE;
|
||||
mtd_erase_callback(instr);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -996,7 +1005,7 @@ static void cfi_staa_sync (struct mtd_info *mtd)
|
|||
case FL_JEDEC_QUERY:
|
||||
chip->oldstate = chip->state;
|
||||
chip->state = FL_SYNCING;
|
||||
/* No need to wake_up() on this state change -
|
||||
/* No need to wake_up() on this state change -
|
||||
* as the whole point is that nobody can do anything
|
||||
* with the chip now anyway.
|
||||
*/
|
||||
|
@ -1007,11 +1016,11 @@ static void cfi_staa_sync (struct mtd_info *mtd)
|
|||
default:
|
||||
/* Not an idle state */
|
||||
add_wait_queue(&chip->wq, &wait);
|
||||
|
||||
|
||||
spin_unlock_bh(chip->mutex);
|
||||
schedule();
|
||||
remove_wait_queue(&chip->wq, &wait);
|
||||
|
||||
|
||||
goto retry;
|
||||
}
|
||||
}
|
||||
|
@ -1022,7 +1031,7 @@ static void cfi_staa_sync (struct mtd_info *mtd)
|
|||
chip = &cfi->chips[i];
|
||||
|
||||
spin_lock_bh(chip->mutex);
|
||||
|
||||
|
||||
if (chip->state == FL_SYNCING) {
|
||||
chip->state = chip->oldstate;
|
||||
wake_up(&chip->wq);
|
||||
|
@ -1057,9 +1066,9 @@ static inline int do_lock_oneblock(struct map_info *map, struct flchip *chip, un
|
|||
|
||||
case FL_STATUS:
|
||||
status = map_read(map, adr);
|
||||
if (map_word_andequal(map, status, status_OK, status_OK))
|
||||
if (map_word_andequal(map, status, status_OK, status_OK))
|
||||
break;
|
||||
|
||||
|
||||
/* Urgh. Chip not yet ready to talk to us. */
|
||||
if (time_after(jiffies, timeo)) {
|
||||
spin_unlock_bh(chip->mutex);
|
||||
|
@ -1088,7 +1097,7 @@ static inline int do_lock_oneblock(struct map_info *map, struct flchip *chip, un
|
|||
map_write(map, CMD(0x60), adr);
|
||||
map_write(map, CMD(0x01), adr);
|
||||
chip->state = FL_LOCKING;
|
||||
|
||||
|
||||
spin_unlock_bh(chip->mutex);
|
||||
msleep(1000);
|
||||
spin_lock_bh(chip->mutex);
|
||||
|
@ -1102,7 +1111,7 @@ static inline int do_lock_oneblock(struct map_info *map, struct flchip *chip, un
|
|||
status = map_read(map, adr);
|
||||
if (map_word_andequal(map, status, status_OK, status_OK))
|
||||
break;
|
||||
|
||||
|
||||
/* OK Still waiting */
|
||||
if (time_after(jiffies, timeo)) {
|
||||
map_write(map, CMD(0x70), adr);
|
||||
|
@ -1112,13 +1121,13 @@ static inline int do_lock_oneblock(struct map_info *map, struct flchip *chip, un
|
|||
spin_unlock_bh(chip->mutex);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
|
||||
/* Latency issues. Drop the lock, wait a while and retry */
|
||||
spin_unlock_bh(chip->mutex);
|
||||
cfi_udelay(1);
|
||||
spin_lock_bh(chip->mutex);
|
||||
}
|
||||
|
||||
|
||||
/* Done and happy. */
|
||||
chip->state = FL_STATUS;
|
||||
DISABLE_VPP(map);
|
||||
|
@ -1162,8 +1171,8 @@ static int cfi_staa_lock(struct mtd_info *mtd, loff_t ofs, size_t len)
|
|||
cfi_send_gen_cmd(0x90, 0x55, 0, map, cfi, cfi->device_type, NULL);
|
||||
printk("after lock: block status register is %x\n",cfi_read_query(map, adr+(2*ofs_factor)));
|
||||
cfi_send_gen_cmd(0xff, 0x55, 0, map, cfi, cfi->device_type, NULL);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@ -1173,7 +1182,7 @@ static int cfi_staa_lock(struct mtd_info *mtd, loff_t ofs, size_t len)
|
|||
if (adr >> cfi->chipshift) {
|
||||
adr = 0;
|
||||
chipnum++;
|
||||
|
||||
|
||||
if (chipnum >= cfi->numchips)
|
||||
break;
|
||||
}
|
||||
|
@ -1208,7 +1217,7 @@ static inline int do_unlock_oneblock(struct map_info *map, struct flchip *chip,
|
|||
status = map_read(map, adr);
|
||||
if (map_word_andequal(map, status, status_OK, status_OK))
|
||||
break;
|
||||
|
||||
|
||||
/* Urgh. Chip not yet ready to talk to us. */
|
||||
if (time_after(jiffies, timeo)) {
|
||||
spin_unlock_bh(chip->mutex);
|
||||
|
@ -1237,7 +1246,7 @@ static inline int do_unlock_oneblock(struct map_info *map, struct flchip *chip,
|
|||
map_write(map, CMD(0x60), adr);
|
||||
map_write(map, CMD(0xD0), adr);
|
||||
chip->state = FL_UNLOCKING;
|
||||
|
||||
|
||||
spin_unlock_bh(chip->mutex);
|
||||
msleep(1000);
|
||||
spin_lock_bh(chip->mutex);
|
||||
|
@ -1251,7 +1260,7 @@ static inline int do_unlock_oneblock(struct map_info *map, struct flchip *chip,
|
|||
status = map_read(map, adr);
|
||||
if (map_word_andequal(map, status, status_OK, status_OK))
|
||||
break;
|
||||
|
||||
|
||||
/* OK Still waiting */
|
||||
if (time_after(jiffies, timeo)) {
|
||||
map_write(map, CMD(0x70), adr);
|
||||
|
@ -1261,13 +1270,13 @@ static inline int do_unlock_oneblock(struct map_info *map, struct flchip *chip,
|
|||
spin_unlock_bh(chip->mutex);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
|
||||
/* Latency issues. Drop the unlock, wait a while and retry */
|
||||
spin_unlock_bh(chip->mutex);
|
||||
cfi_udelay(1);
|
||||
spin_lock_bh(chip->mutex);
|
||||
}
|
||||
|
||||
|
||||
/* Done and happy. */
|
||||
chip->state = FL_STATUS;
|
||||
DISABLE_VPP(map);
|
||||
|
@ -1292,7 +1301,7 @@ static int cfi_staa_unlock(struct mtd_info *mtd, loff_t ofs, size_t len)
|
|||
{
|
||||
unsigned long temp_adr = adr;
|
||||
unsigned long temp_len = len;
|
||||
|
||||
|
||||
cfi_send_gen_cmd(0x90, 0x55, 0, map, cfi, cfi->device_type, NULL);
|
||||
while (temp_len) {
|
||||
printk("before unlock %x: block status register is %x\n",temp_adr,cfi_read_query(map, temp_adr+(2*ofs_factor)));
|
||||
|
@ -1310,7 +1319,7 @@ static int cfi_staa_unlock(struct mtd_info *mtd, loff_t ofs, size_t len)
|
|||
printk("after unlock: block status register is %x\n",cfi_read_query(map, adr+(2*ofs_factor)));
|
||||
cfi_send_gen_cmd(0xff, 0x55, 0, map, cfi, cfi->device_type, NULL);
|
||||
#endif
|
||||
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -1334,7 +1343,7 @@ static int cfi_staa_suspend(struct mtd_info *mtd)
|
|||
case FL_JEDEC_QUERY:
|
||||
chip->oldstate = chip->state;
|
||||
chip->state = FL_PM_SUSPENDED;
|
||||
/* No need to wake_up() on this state change -
|
||||
/* No need to wake_up() on this state change -
|
||||
* as the whole point is that nobody can do anything
|
||||
* with the chip now anyway.
|
||||
*/
|
||||
|
@ -1353,9 +1362,9 @@ static int cfi_staa_suspend(struct mtd_info *mtd)
|
|||
if (ret) {
|
||||
for (i--; i >=0; i--) {
|
||||
chip = &cfi->chips[i];
|
||||
|
||||
|
||||
spin_lock_bh(chip->mutex);
|
||||
|
||||
|
||||
if (chip->state == FL_PM_SUSPENDED) {
|
||||
/* No need to force it into a known state here,
|
||||
because we're returning failure, and it didn't
|
||||
|
@ -1365,8 +1374,8 @@ static int cfi_staa_suspend(struct mtd_info *mtd)
|
|||
}
|
||||
spin_unlock_bh(chip->mutex);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -1378,11 +1387,11 @@ static void cfi_staa_resume(struct mtd_info *mtd)
|
|||
struct flchip *chip;
|
||||
|
||||
for (i=0; i<cfi->numchips; i++) {
|
||||
|
||||
|
||||
chip = &cfi->chips[i];
|
||||
|
||||
spin_lock_bh(chip->mutex);
|
||||
|
||||
|
||||
/* Go to known state. Chip may have been power cycled */
|
||||
if (chip->state == FL_PM_SUSPENDED) {
|
||||
map_write(map, CMD(0xFF), 0);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
/*
|
||||
Common Flash Interface probe code.
|
||||
(C) 2000 Red Hat. GPL'd.
|
||||
$Id: cfi_probe.c,v 1.83 2004/11/16 18:19:02 nico Exp $
|
||||
$Id: cfi_probe.c,v 1.84 2005/11/07 11:14:23 gleixner Exp $
|
||||
*/
|
||||
|
||||
#include <linux/config.h>
|
||||
|
@ -20,7 +20,7 @@
|
|||
#include <linux/mtd/cfi.h>
|
||||
#include <linux/mtd/gen_probe.h>
|
||||
|
||||
//#define DEBUG_CFI
|
||||
//#define DEBUG_CFI
|
||||
|
||||
#ifdef DEBUG_CFI
|
||||
static void print_cfi_ident(struct cfi_ident *);
|
||||
|
@ -103,7 +103,7 @@ static int __xipram cfi_probe_chip(struct map_info *map, __u32 base,
|
|||
unsigned long *chip_map, struct cfi_private *cfi)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
||||
if ((base + 0) >= map->size) {
|
||||
printk(KERN_NOTICE
|
||||
"Probe at base[0x00](0x%08lx) past the end of the map(0x%08lx)\n",
|
||||
|
@ -128,7 +128,7 @@ static int __xipram cfi_probe_chip(struct map_info *map, __u32 base,
|
|||
}
|
||||
|
||||
if (!cfi->numchips) {
|
||||
/* This is the first time we're called. Set up the CFI
|
||||
/* This is the first time we're called. Set up the CFI
|
||||
stuff accordingly and return */
|
||||
return cfi_chip_setup(map, cfi);
|
||||
}
|
||||
|
@ -138,13 +138,13 @@ static int __xipram cfi_probe_chip(struct map_info *map, __u32 base,
|
|||
unsigned long start;
|
||||
if(!test_bit(i, chip_map)) {
|
||||
/* Skip location; no valid chip at this address */
|
||||
continue;
|
||||
continue;
|
||||
}
|
||||
start = i << cfi->chipshift;
|
||||
/* This chip should be in read mode if it's one
|
||||
we've already touched. */
|
||||
if (qry_present(map, start, cfi)) {
|
||||
/* Eep. This chip also had the QRY marker.
|
||||
/* Eep. This chip also had the QRY marker.
|
||||
* Is it an alias for the new one? */
|
||||
cfi_send_gen_cmd(0xF0, 0, start, map, cfi, cfi->device_type, NULL);
|
||||
cfi_send_gen_cmd(0xFF, 0, start, map, cfi, cfi->device_type, NULL);
|
||||
|
@ -156,13 +156,13 @@ static int __xipram cfi_probe_chip(struct map_info *map, __u32 base,
|
|||
map->name, base, start);
|
||||
return 0;
|
||||
}
|
||||
/* Yes, it's actually got QRY for data. Most
|
||||
/* Yes, it's actually got QRY for data. Most
|
||||
* unfortunate. Stick the new chip in read mode
|
||||
* too and if it's the same, assume it's an alias. */
|
||||
/* FIXME: Use other modes to do a proper check */
|
||||
cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL);
|
||||
cfi_send_gen_cmd(0xFF, 0, start, map, cfi, cfi->device_type, NULL);
|
||||
|
||||
|
||||
if (qry_present(map, base, cfi)) {
|
||||
xip_allowed(base, map);
|
||||
printk(KERN_DEBUG "%s: Found an alias at 0x%x for the chip at 0x%lx\n",
|
||||
|
@ -171,12 +171,12 @@ static int __xipram cfi_probe_chip(struct map_info *map, __u32 base,
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* OK, if we got to here, then none of the previous chips appear to
|
||||
be aliases for the current one. */
|
||||
set_bit((base >> cfi->chipshift), chip_map); /* Update chip map */
|
||||
cfi->numchips++;
|
||||
|
||||
|
||||
/* Put it back into Read Mode */
|
||||
cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL);
|
||||
cfi_send_gen_cmd(0xFF, 0, base, map, cfi, cfi->device_type, NULL);
|
||||
|
@ -185,11 +185,11 @@ static int __xipram cfi_probe_chip(struct map_info *map, __u32 base,
|
|||
printk(KERN_INFO "%s: Found %d x%d devices at 0x%x in %d-bit bank\n",
|
||||
map->name, cfi->interleave, cfi->device_type*8, base,
|
||||
map->bankwidth*8);
|
||||
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int __xipram cfi_chip_setup(struct map_info *map,
|
||||
static int __xipram cfi_chip_setup(struct map_info *map,
|
||||
struct cfi_private *cfi)
|
||||
{
|
||||
int ofs_factor = cfi->interleave*cfi->device_type;
|
||||
|
@ -209,11 +209,11 @@ static int __xipram cfi_chip_setup(struct map_info *map,
|
|||
printk(KERN_WARNING "%s: kmalloc failed for CFI ident structure\n", map->name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
memset(cfi->cfiq,0,sizeof(struct cfi_ident));
|
||||
|
||||
|
||||
memset(cfi->cfiq,0,sizeof(struct cfi_ident));
|
||||
|
||||
cfi->cfi_mode = CFI_MODE_CFI;
|
||||
|
||||
|
||||
/* Read the CFI info structure */
|
||||
xip_disable_qry(base, map, cfi);
|
||||
for (i=0; i<(sizeof(struct cfi_ident) + num_erase_regions * 4); i++)
|
||||
|
@ -231,7 +231,7 @@ static int __xipram cfi_chip_setup(struct map_info *map,
|
|||
cfi_send_gen_cmd(0x55, 0x2aa, base, map, cfi, cfi->device_type, NULL);
|
||||
cfi_send_gen_cmd(0x90, 0x555, base, map, cfi, cfi->device_type, NULL);
|
||||
cfi->mfr = cfi_read_query(map, base);
|
||||
cfi->id = cfi_read_query(map, base + ofs_factor);
|
||||
cfi->id = cfi_read_query(map, base + ofs_factor);
|
||||
|
||||
/* Put it back into Read Mode */
|
||||
cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL);
|
||||
|
@ -255,10 +255,10 @@ static int __xipram cfi_chip_setup(struct map_info *map,
|
|||
|
||||
for (i=0; i<cfi->cfiq->NumEraseRegions; i++) {
|
||||
cfi->cfiq->EraseRegionInfo[i] = le32_to_cpu(cfi->cfiq->EraseRegionInfo[i]);
|
||||
|
||||
#ifdef DEBUG_CFI
|
||||
|
||||
#ifdef DEBUG_CFI
|
||||
printk(" Erase Region #%d: BlockSize 0x%4.4X bytes, %d blocks\n",
|
||||
i, (cfi->cfiq->EraseRegionInfo[i] >> 8) & ~0xff,
|
||||
i, (cfi->cfiq->EraseRegionInfo[i] >> 8) & ~0xff,
|
||||
(cfi->cfiq->EraseRegionInfo[i] & 0xffff) + 1);
|
||||
#endif
|
||||
}
|
||||
|
@ -271,33 +271,33 @@ static int __xipram cfi_chip_setup(struct map_info *map,
|
|||
}
|
||||
|
||||
#ifdef DEBUG_CFI
|
||||
static char *vendorname(__u16 vendor)
|
||||
static char *vendorname(__u16 vendor)
|
||||
{
|
||||
switch (vendor) {
|
||||
case P_ID_NONE:
|
||||
return "None";
|
||||
|
||||
|
||||
case P_ID_INTEL_EXT:
|
||||
return "Intel/Sharp Extended";
|
||||
|
||||
|
||||
case P_ID_AMD_STD:
|
||||
return "AMD/Fujitsu Standard";
|
||||
|
||||
|
||||
case P_ID_INTEL_STD:
|
||||
return "Intel/Sharp Standard";
|
||||
|
||||
|
||||
case P_ID_AMD_EXT:
|
||||
return "AMD/Fujitsu Extended";
|
||||
|
||||
case P_ID_WINBOND:
|
||||
return "Winbond Standard";
|
||||
|
||||
|
||||
case P_ID_ST_ADV:
|
||||
return "ST Advanced";
|
||||
|
||||
case P_ID_MITSUBISHI_STD:
|
||||
return "Mitsubishi Standard";
|
||||
|
||||
|
||||
case P_ID_MITSUBISHI_EXT:
|
||||
return "Mitsubishi Extended";
|
||||
|
||||
|
@ -306,13 +306,13 @@ static char *vendorname(__u16 vendor)
|
|||
|
||||
case P_ID_INTEL_PERFORMANCE:
|
||||
return "Intel Performance Code";
|
||||
|
||||
|
||||
case P_ID_INTEL_DATA:
|
||||
return "Intel Data";
|
||||
|
||||
|
||||
case P_ID_RESERVED:
|
||||
return "Not Allowed / Reserved for Future Use";
|
||||
|
||||
|
||||
default:
|
||||
return "Unknown";
|
||||
}
|
||||
|
@ -325,21 +325,21 @@ static void print_cfi_ident(struct cfi_ident *cfip)
|
|||
if (cfip->qry[0] != 'Q' || cfip->qry[1] != 'R' || cfip->qry[2] != 'Y') {
|
||||
printk("Invalid CFI ident structure.\n");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
printk("Primary Vendor Command Set: %4.4X (%s)\n", cfip->P_ID, vendorname(cfip->P_ID));
|
||||
if (cfip->P_ADR)
|
||||
printk("Primary Algorithm Table at %4.4X\n", cfip->P_ADR);
|
||||
else
|
||||
printk("No Primary Algorithm Table\n");
|
||||
|
||||
|
||||
printk("Alternative Vendor Command Set: %4.4X (%s)\n", cfip->A_ID, vendorname(cfip->A_ID));
|
||||
if (cfip->A_ADR)
|
||||
printk("Alternate Algorithm Table at %4.4X\n", cfip->A_ADR);
|
||||
else
|
||||
printk("No Alternate Algorithm Table\n");
|
||||
|
||||
|
||||
|
||||
|
||||
printk("Vcc Minimum: %2d.%d V\n", cfip->VccMin >> 4, cfip->VccMin & 0xf);
|
||||
printk("Vcc Maximum: %2d.%d V\n", cfip->VccMax >> 4, cfip->VccMax & 0xf);
|
||||
if (cfip->VppMin) {
|
||||
|
@ -348,61 +348,61 @@ static void print_cfi_ident(struct cfi_ident *cfip)
|
|||
}
|
||||
else
|
||||
printk("No Vpp line\n");
|
||||
|
||||
|
||||
printk("Typical byte/word write timeout: %d µs\n", 1<<cfip->WordWriteTimeoutTyp);
|
||||
printk("Maximum byte/word write timeout: %d µs\n", (1<<cfip->WordWriteTimeoutMax) * (1<<cfip->WordWriteTimeoutTyp));
|
||||
|
||||
|
||||
if (cfip->BufWriteTimeoutTyp || cfip->BufWriteTimeoutMax) {
|
||||
printk("Typical full buffer write timeout: %d µs\n", 1<<cfip->BufWriteTimeoutTyp);
|
||||
printk("Maximum full buffer write timeout: %d µs\n", (1<<cfip->BufWriteTimeoutMax) * (1<<cfip->BufWriteTimeoutTyp));
|
||||
}
|
||||
else
|
||||
printk("Full buffer write not supported\n");
|
||||
|
||||
|
||||
printk("Typical block erase timeout: %d ms\n", 1<<cfip->BlockEraseTimeoutTyp);
|
||||
printk("Maximum block erase timeout: %d ms\n", (1<<cfip->BlockEraseTimeoutMax) * (1<<cfip->BlockEraseTimeoutTyp));
|
||||
if (cfip->ChipEraseTimeoutTyp || cfip->ChipEraseTimeoutMax) {
|
||||
printk("Typical chip erase timeout: %d ms\n", 1<<cfip->ChipEraseTimeoutTyp);
|
||||
printk("Typical chip erase timeout: %d ms\n", 1<<cfip->ChipEraseTimeoutTyp);
|
||||
printk("Maximum chip erase timeout: %d ms\n", (1<<cfip->ChipEraseTimeoutMax) * (1<<cfip->ChipEraseTimeoutTyp));
|
||||
}
|
||||
else
|
||||
printk("Chip erase not supported\n");
|
||||
|
||||
|
||||
printk("Device size: 0x%X bytes (%d MiB)\n", 1 << cfip->DevSize, 1<< (cfip->DevSize - 20));
|
||||
printk("Flash Device Interface description: 0x%4.4X\n", cfip->InterfaceDesc);
|
||||
switch(cfip->InterfaceDesc) {
|
||||
case 0:
|
||||
printk(" - x8-only asynchronous interface\n");
|
||||
break;
|
||||
|
||||
|
||||
case 1:
|
||||
printk(" - x16-only asynchronous interface\n");
|
||||
break;
|
||||
|
||||
|
||||
case 2:
|
||||
printk(" - supports x8 and x16 via BYTE# with asynchronous interface\n");
|
||||
break;
|
||||
|
||||
|
||||
case 3:
|
||||
printk(" - x32-only asynchronous interface\n");
|
||||
break;
|
||||
|
||||
|
||||
case 4:
|
||||
printk(" - supports x16 and x32 via Word# with asynchronous interface\n");
|
||||
break;
|
||||
|
||||
|
||||
case 65535:
|
||||
printk(" - Not Allowed / Reserved\n");
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
printk(" - Unknown\n");
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
printk("Max. bytes in buffer write: 0x%x\n", 1<< cfip->MaxBufWriteSize);
|
||||
printk("Number of Erase Block Regions: %d\n", cfip->NumEraseRegions);
|
||||
|
||||
|
||||
}
|
||||
#endif /* DEBUG_CFI */
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
*
|
||||
* This code is covered by the GPL.
|
||||
*
|
||||
* $Id: cfi_util.c,v 1.8 2004/12/14 19:55:56 nico Exp $
|
||||
* $Id: cfi_util.c,v 1.10 2005/11/07 11:14:23 gleixner Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
|
@ -56,7 +56,7 @@ __xipram cfi_read_pri(struct map_info *map, __u16 adr, __u16 size, const char* n
|
|||
|
||||
/* Read in the Extended Query Table */
|
||||
for (i=0; i<size; i++) {
|
||||
((unsigned char *)extp)[i] =
|
||||
((unsigned char *)extp)[i] =
|
||||
cfi_read_query(map, base+((adr+i)*ofs_factor));
|
||||
}
|
||||
|
||||
|
@ -70,15 +70,6 @@ __xipram cfi_read_pri(struct map_info *map, __u16 adr, __u16 size, const char* n
|
|||
local_irq_enable();
|
||||
#endif
|
||||
|
||||
if (extp->MajorVersion != '1' ||
|
||||
(extp->MinorVersion < '0' || extp->MinorVersion > '3')) {
|
||||
printk(KERN_WARNING " Unknown %s Extended Query "
|
||||
"version %c.%c.\n", name, extp->MajorVersion,
|
||||
extp->MinorVersion);
|
||||
kfree(extp);
|
||||
extp = NULL;
|
||||
}
|
||||
|
||||
out: return extp;
|
||||
}
|
||||
|
||||
|
@ -122,17 +113,17 @@ int cfi_varsize_frob(struct mtd_info *mtd, varsize_frob_t frob,
|
|||
|
||||
i = 0;
|
||||
|
||||
/* Skip all erase regions which are ended before the start of
|
||||
/* Skip all erase regions which are ended before the start of
|
||||
the requested erase. Actually, to save on the calculations,
|
||||
we skip to the first erase region which starts after the
|
||||
start of the requested erase, and then go back one.
|
||||
*/
|
||||
|
||||
|
||||
while (i < mtd->numeraseregions && ofs >= regions[i].offset)
|
||||
i++;
|
||||
i--;
|
||||
|
||||
/* OK, now i is pointing at the erase region in which this
|
||||
/* OK, now i is pointing at the erase region in which this
|
||||
erase request starts. Check the start of the requested
|
||||
erase range is aligned with the erase size which is in
|
||||
effect here.
|
||||
|
@ -155,7 +146,7 @@ int cfi_varsize_frob(struct mtd_info *mtd, varsize_frob_t frob,
|
|||
the address actually falls
|
||||
*/
|
||||
i--;
|
||||
|
||||
|
||||
if ((ofs + len) & (regions[i].erasesize-1))
|
||||
return -EINVAL;
|
||||
|
||||
|
@ -168,7 +159,7 @@ int cfi_varsize_frob(struct mtd_info *mtd, varsize_frob_t frob,
|
|||
int size = regions[i].erasesize;
|
||||
|
||||
ret = (*frob)(map, &cfi->chips[chipnum], adr, size, thunk);
|
||||
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@ -182,7 +173,7 @@ int cfi_varsize_frob(struct mtd_info *mtd, varsize_frob_t frob,
|
|||
if (adr >> cfi->chipshift) {
|
||||
adr = 0;
|
||||
chipnum++;
|
||||
|
||||
|
||||
if (chipnum >= cfi->numchips)
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -41,7 +41,7 @@ static struct mtd_chip_driver *get_mtd_chip_driver (const char *name)
|
|||
|
||||
list_for_each(pos, &chip_drvs_list) {
|
||||
this = list_entry(pos, typeof(*this), list);
|
||||
|
||||
|
||||
if (!strcmp(this->name, name)) {
|
||||
ret = this;
|
||||
break;
|
||||
|
@ -73,7 +73,7 @@ struct mtd_info *do_map_probe(const char *name, struct map_info *map)
|
|||
|
||||
ret = drv->probe(map);
|
||||
|
||||
/* We decrease the use count here. It may have been a
|
||||
/* We decrease the use count here. It may have been a
|
||||
probe-only module, which is no longer required from this
|
||||
point, having given us a handle on (and increased the use
|
||||
count of) the actual driver code.
|
||||
|
@ -82,7 +82,7 @@ struct mtd_info *do_map_probe(const char *name, struct map_info *map)
|
|||
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
||||
return NULL;
|
||||
}
|
||||
/*
|
||||
|
|
|
@ -25,7 +25,7 @@ struct fwh_xxlock_thunk {
|
|||
* so this code has not been tested with interleaved chips,
|
||||
* and will likely fail in that context.
|
||||
*/
|
||||
static int fwh_xxlock_oneblock(struct map_info *map, struct flchip *chip,
|
||||
static int fwh_xxlock_oneblock(struct map_info *map, struct flchip *chip,
|
||||
unsigned long adr, int len, void *thunk)
|
||||
{
|
||||
struct cfi_private *cfi = map->fldrv_priv;
|
||||
|
@ -44,7 +44,7 @@ static int fwh_xxlock_oneblock(struct map_info *map, struct flchip *chip,
|
|||
* - on 64k boundariesand
|
||||
* - bit 1 set high
|
||||
* - block lock registers are 4MiB lower - overflow subtract (danger)
|
||||
*
|
||||
*
|
||||
* The address manipulation is first done on the logical address
|
||||
* which is 0 at the start of the chip, and then the offset of
|
||||
* the individual chip is addted to it. Any other order a weird
|
||||
|
@ -93,7 +93,7 @@ static int fwh_unlock_varsize(struct mtd_info *mtd, loff_t ofs, size_t len)
|
|||
|
||||
ret = cfi_varsize_frob(mtd, fwh_xxlock_oneblock, ofs, len,
|
||||
(void *)&FWH_XXLOCK_ONEBLOCK_UNLOCK);
|
||||
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* Routines common to all CFI-type probes.
|
||||
* (C) 2001-2003 Red Hat, Inc.
|
||||
* GPL'd
|
||||
* $Id: gen_probe.c,v 1.22 2005/01/24 23:49:50 rmk Exp $
|
||||
* $Id: gen_probe.c,v 1.24 2005/11/07 11:14:23 gleixner Exp $
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
|
@ -26,7 +26,7 @@ struct mtd_info *mtd_do_chip_probe(struct map_info *map, struct chip_probe *cp)
|
|||
|
||||
/* First probe the map to see if we have CFI stuff there. */
|
||||
cfi = genprobe_ident_chips(map, cp);
|
||||
|
||||
|
||||
if (!cfi)
|
||||
return NULL;
|
||||
|
||||
|
@ -36,12 +36,12 @@ struct mtd_info *mtd_do_chip_probe(struct map_info *map, struct chip_probe *cp)
|
|||
mtd = check_cmd_set(map, 1); /* First the primary cmdset */
|
||||
if (!mtd)
|
||||
mtd = check_cmd_set(map, 0); /* Then the secondary */
|
||||
|
||||
|
||||
if (mtd)
|
||||
return mtd;
|
||||
|
||||
printk(KERN_WARNING"gen_probe: No supported Vendor Command Set found\n");
|
||||
|
||||
|
||||
kfree(cfi->cfiq);
|
||||
kfree(cfi);
|
||||
map->fldrv_priv = NULL;
|
||||
|
@ -60,14 +60,14 @@ static struct cfi_private *genprobe_ident_chips(struct map_info *map, struct chi
|
|||
|
||||
memset(&cfi, 0, sizeof(cfi));
|
||||
|
||||
/* Call the probetype-specific code with all permutations of
|
||||
/* Call the probetype-specific code with all permutations of
|
||||
interleave and device type, etc. */
|
||||
if (!genprobe_new_chip(map, cp, &cfi)) {
|
||||
/* The probe didn't like it */
|
||||
printk(KERN_DEBUG "%s: Found no %s device at location zero\n",
|
||||
cp->name, map->name);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#if 0 /* Let the CFI probe routine do this sanity check. The Intel and AMD
|
||||
probe routines won't ever return a broken CFI structure anyway,
|
||||
|
@ -92,13 +92,13 @@ static struct cfi_private *genprobe_ident_chips(struct map_info *map, struct chi
|
|||
} else {
|
||||
BUG();
|
||||
}
|
||||
|
||||
|
||||
cfi.numchips = 1;
|
||||
|
||||
/*
|
||||
* Allocate memory for bitmap of valid chips.
|
||||
* Align bitmap storage size to full byte.
|
||||
*/
|
||||
/*
|
||||
* Allocate memory for bitmap of valid chips.
|
||||
* Align bitmap storage size to full byte.
|
||||
*/
|
||||
max_chips = map->size >> cfi.chipshift;
|
||||
mapsize = (max_chips / 8) + ((max_chips % 8) ? 1 : 0);
|
||||
chip_map = kmalloc(mapsize, GFP_KERNEL);
|
||||
|
@ -122,7 +122,7 @@ static struct cfi_private *genprobe_ident_chips(struct map_info *map, struct chi
|
|||
}
|
||||
|
||||
/*
|
||||
* Now allocate the space for the structures we need to return to
|
||||
* Now allocate the space for the structures we need to return to
|
||||
* our caller, and copy the appropriate data into them.
|
||||
*/
|
||||
|
||||
|
@ -154,7 +154,7 @@ static struct cfi_private *genprobe_ident_chips(struct map_info *map, struct chi
|
|||
return retcfi;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int genprobe_new_chip(struct map_info *map, struct chip_probe *cp,
|
||||
struct cfi_private *cfi)
|
||||
{
|
||||
|
@ -189,7 +189,7 @@ extern cfi_cmdset_fn_t cfi_cmdset_0001;
|
|||
extern cfi_cmdset_fn_t cfi_cmdset_0002;
|
||||
extern cfi_cmdset_fn_t cfi_cmdset_0020;
|
||||
|
||||
static inline struct mtd_info *cfi_cmdset_unknown(struct map_info *map,
|
||||
static inline struct mtd_info *cfi_cmdset_unknown(struct map_info *map,
|
||||
int primary)
|
||||
{
|
||||
struct cfi_private *cfi = map->fldrv_priv;
|
||||
|
@ -199,7 +199,7 @@ static inline struct mtd_info *cfi_cmdset_unknown(struct map_info *map,
|
|||
cfi_cmdset_fn_t *probe_function;
|
||||
|
||||
sprintf(probename, "cfi_cmdset_%4.4X", type);
|
||||
|
||||
|
||||
probe_function = inter_module_get_request(probename, probename);
|
||||
|
||||
if (probe_function) {
|
||||
|
@ -221,7 +221,7 @@ static struct mtd_info *check_cmd_set(struct map_info *map, int primary)
|
|||
{
|
||||
struct cfi_private *cfi = map->fldrv_priv;
|
||||
__u16 type = primary?cfi->cfiq->P_ID:cfi->cfiq->A_ID;
|
||||
|
||||
|
||||
if (type == P_ID_NONE || type == P_ID_RESERVED)
|
||||
return NULL;
|
||||
|
||||
|
@ -235,6 +235,7 @@ static struct mtd_info *check_cmd_set(struct map_info *map, int primary)
|
|||
#ifdef CONFIG_MTD_CFI_INTELEXT
|
||||
case 0x0001:
|
||||
case 0x0003:
|
||||
case 0x0200:
|
||||
return cfi_cmdset_0001(map, primary);
|
||||
#endif
|
||||
#ifdef CONFIG_MTD_CFI_AMDSTD
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
|
||||
/* JEDEC Flash Interface.
|
||||
* This is an older type of interface for self programming flash. It is
|
||||
* This is an older type of interface for self programming flash. It is
|
||||
* commonly use in older AMD chips and is obsolete compared with CFI.
|
||||
* It is called JEDEC because the JEDEC association distributes the ID codes
|
||||
* for the chips.
|
||||
|
@ -88,9 +88,9 @@ static const struct JEDECTable JEDEC_table[] = {
|
|||
|
||||
static const struct JEDECTable *jedec_idtoinf(__u8 mfr,__u8 id);
|
||||
static void jedec_sync(struct mtd_info *mtd) {};
|
||||
static int jedec_read(struct mtd_info *mtd, loff_t from, size_t len,
|
||||
static int jedec_read(struct mtd_info *mtd, loff_t from, size_t len,
|
||||
size_t *retlen, u_char *buf);
|
||||
static int jedec_read_banked(struct mtd_info *mtd, loff_t from, size_t len,
|
||||
static int jedec_read_banked(struct mtd_info *mtd, loff_t from, size_t len,
|
||||
size_t *retlen, u_char *buf);
|
||||
|
||||
static struct mtd_info *jedec_probe(struct map_info *map);
|
||||
|
@ -122,7 +122,7 @@ static struct mtd_info *jedec_probe(struct map_info *map)
|
|||
|
||||
memset(MTD, 0, sizeof(struct mtd_info) + sizeof(struct jedec_private));
|
||||
priv = (struct jedec_private *)&MTD[1];
|
||||
|
||||
|
||||
my_bank_size = map->size;
|
||||
|
||||
if (map->size/my_bank_size > MAX_JEDEC_CHIPS)
|
||||
|
@ -131,13 +131,13 @@ static struct mtd_info *jedec_probe(struct map_info *map)
|
|||
kfree(MTD);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
for (Base = 0; Base < map->size; Base += my_bank_size)
|
||||
{
|
||||
// Perhaps zero could designate all tests?
|
||||
if (map->buswidth == 0)
|
||||
map->buswidth = 1;
|
||||
|
||||
|
||||
if (map->buswidth == 1){
|
||||
if (jedec_probe8(map,Base,priv) == 0) {
|
||||
printk("did recognize jedec chip\n");
|
||||
|
@ -150,7 +150,7 @@ static struct mtd_info *jedec_probe(struct map_info *map)
|
|||
if (map->buswidth == 4)
|
||||
jedec_probe32(map,Base,priv);
|
||||
}
|
||||
|
||||
|
||||
// Get the biggest sector size
|
||||
SectorSize = 0;
|
||||
for (I = 0; priv->chips[I].jedec != 0 && I < MAX_JEDEC_CHIPS; I++)
|
||||
|
@ -160,7 +160,7 @@ static struct mtd_info *jedec_probe(struct map_info *map)
|
|||
if (priv->chips[I].sectorsize > SectorSize)
|
||||
SectorSize = priv->chips[I].sectorsize;
|
||||
}
|
||||
|
||||
|
||||
// Quickly ensure that the other sector sizes are factors of the largest
|
||||
for (I = 0; priv->chips[I].jedec != 0 && I < MAX_JEDEC_CHIPS; I++)
|
||||
{
|
||||
|
@ -169,9 +169,9 @@ static struct mtd_info *jedec_probe(struct map_info *map)
|
|||
printk("mtd: Failed. Device has incompatible mixed sector sizes\n");
|
||||
kfree(MTD);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Generate a part name that includes the number of different chips and
|
||||
other configuration information */
|
||||
count = 1;
|
||||
|
@ -181,13 +181,13 @@ static struct mtd_info *jedec_probe(struct map_info *map)
|
|||
for (I = 0; priv->chips[I].jedec != 0 && I < MAX_JEDEC_CHIPS; I++)
|
||||
{
|
||||
const struct JEDECTable *JEDEC;
|
||||
|
||||
|
||||
if (priv->chips[I+1].jedec == priv->chips[I].jedec)
|
||||
{
|
||||
count++;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
// Locate the chip in the jedec table
|
||||
JEDEC = jedec_idtoinf(priv->chips[I].jedec >> 8,priv->chips[I].jedec);
|
||||
if (JEDEC == 0)
|
||||
|
@ -196,11 +196,11 @@ static struct mtd_info *jedec_probe(struct map_info *map)
|
|||
kfree(MTD);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
if (Uniq != 0)
|
||||
strcat(Part,",");
|
||||
Uniq++;
|
||||
|
||||
|
||||
if (count != 1)
|
||||
sprintf(Part+strlen(Part),"%x*[%s]",count,JEDEC->name);
|
||||
else
|
||||
|
@ -208,7 +208,7 @@ static struct mtd_info *jedec_probe(struct map_info *map)
|
|||
if (strlen(Part) > sizeof(Part)*2/3)
|
||||
break;
|
||||
count = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Determine if the chips are organized in a linear fashion, or if there
|
||||
are empty banks. Note, the last bank does not count here, only the
|
||||
|
@ -233,7 +233,7 @@ static struct mtd_info *jedec_probe(struct map_info *map)
|
|||
{
|
||||
if (priv->bank_fill[I] != my_bank_size)
|
||||
priv->is_banked = 1;
|
||||
|
||||
|
||||
/* This even could be eliminated, but new de-optimized read/write
|
||||
functions have to be written */
|
||||
printk("priv->bank_fill[%d] is %lx, priv->bank_fill[0] is %lx\n",I,priv->bank_fill[I],priv->bank_fill[0]);
|
||||
|
@ -242,7 +242,7 @@ static struct mtd_info *jedec_probe(struct map_info *map)
|
|||
printk("mtd: Failed. Cannot handle unsymmetric banking\n");
|
||||
kfree(MTD);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -250,7 +250,7 @@ static struct mtd_info *jedec_probe(struct map_info *map)
|
|||
strcat(Part,", banked");
|
||||
|
||||
// printk("Part: '%s'\n",Part);
|
||||
|
||||
|
||||
memset(MTD,0,sizeof(*MTD));
|
||||
// strlcpy(MTD->name,Part,sizeof(MTD->name));
|
||||
MTD->name = map->name;
|
||||
|
@ -291,7 +291,7 @@ static int checkparity(u_char C)
|
|||
|
||||
/* Take an array of JEDEC numbers that represent interleved flash chips
|
||||
and process them. Check to make sure they are good JEDEC numbers, look
|
||||
them up and then add them to the chip list */
|
||||
them up and then add them to the chip list */
|
||||
static int handle_jedecs(struct map_info *map,__u8 *Mfg,__u8 *Id,unsigned Count,
|
||||
unsigned long base,struct jedec_private *priv)
|
||||
{
|
||||
|
@ -306,16 +306,16 @@ static int handle_jedecs(struct map_info *map,__u8 *Mfg,__u8 *Id,unsigned Count,
|
|||
if (checkparity(Mfg[I]) == 0 || checkparity(Id[I]) == 0)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// Finally, just make sure all the chip sizes are the same
|
||||
JEDEC = jedec_idtoinf(Mfg[0],Id[0]);
|
||||
|
||||
|
||||
if (JEDEC == 0)
|
||||
{
|
||||
printk("mtd: Found JEDEC flash chip, but do not have a table entry for %x:%x\n",Mfg[0],Mfg[1]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
Size = JEDEC->size;
|
||||
SectorSize = JEDEC->sectorsize;
|
||||
for (I = 0; I != Count; I++)
|
||||
|
@ -331,7 +331,7 @@ static int handle_jedecs(struct map_info *map,__u8 *Mfg,__u8 *Id,unsigned Count,
|
|||
{
|
||||
printk("mtd: Failed. Interleved flash does not have matching characteristics\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Load the Chips
|
||||
|
@ -345,13 +345,13 @@ static int handle_jedecs(struct map_info *map,__u8 *Mfg,__u8 *Id,unsigned Count,
|
|||
{
|
||||
printk("mtd: Device has too many chips. Increase MAX_JEDEC_CHIPS\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Add them to the table
|
||||
for (J = 0; J != Count; J++)
|
||||
{
|
||||
unsigned long Bank;
|
||||
|
||||
|
||||
JEDEC = jedec_idtoinf(Mfg[J],Id[J]);
|
||||
priv->chips[I].jedec = (Mfg[J] << 8) | Id[J];
|
||||
priv->chips[I].size = JEDEC->size;
|
||||
|
@ -364,17 +364,17 @@ static int handle_jedecs(struct map_info *map,__u8 *Mfg,__u8 *Id,unsigned Count,
|
|||
// log2 n :|
|
||||
priv->chips[I].addrshift = 0;
|
||||
for (Bank = Count; Bank != 1; Bank >>= 1, priv->chips[I].addrshift++);
|
||||
|
||||
|
||||
// Determine how filled this bank is.
|
||||
Bank = base & (~(my_bank_size-1));
|
||||
if (priv->bank_fill[Bank/my_bank_size] < base +
|
||||
if (priv->bank_fill[Bank/my_bank_size] < base +
|
||||
(JEDEC->size << priv->chips[I].addrshift) - Bank)
|
||||
priv->bank_fill[Bank/my_bank_size] = base + (JEDEC->size << priv->chips[I].addrshift) - Bank;
|
||||
I++;
|
||||
}
|
||||
|
||||
priv->size += priv->chips[I-1].size*Count;
|
||||
|
||||
|
||||
return priv->chips[I-1].size;
|
||||
}
|
||||
|
||||
|
@ -392,7 +392,7 @@ static const struct JEDECTable *jedec_idtoinf(__u8 mfr,__u8 id)
|
|||
// Look for flash using an 8 bit bus interface
|
||||
static int jedec_probe8(struct map_info *map,unsigned long base,
|
||||
struct jedec_private *priv)
|
||||
{
|
||||
{
|
||||
#define flread(x) map_read8(map,base+x)
|
||||
#define flwrite(v,x) map_write8(map,v,base+x)
|
||||
|
||||
|
@ -410,20 +410,20 @@ static int jedec_probe8(struct map_info *map,unsigned long base,
|
|||
OldVal = flread(base);
|
||||
for (I = 0; OldVal != flread(base) && I < 10000; I++)
|
||||
OldVal = flread(base);
|
||||
|
||||
|
||||
// Reset the chip
|
||||
flwrite(Reset,0x555);
|
||||
|
||||
flwrite(Reset,0x555);
|
||||
|
||||
// Send the sequence
|
||||
flwrite(AutoSel1,0x555);
|
||||
flwrite(AutoSel2,0x2AA);
|
||||
flwrite(AutoSel3,0x555);
|
||||
|
||||
|
||||
// Get the JEDEC numbers
|
||||
Mfg[0] = flread(0);
|
||||
Id[0] = flread(1);
|
||||
// printk("Mfg is %x, Id is %x\n",Mfg[0],Id[0]);
|
||||
|
||||
|
||||
Size = handle_jedecs(map,Mfg,Id,1,base,priv);
|
||||
// printk("handle_jedecs Size is %x\n",(unsigned int)Size);
|
||||
if (Size == 0)
|
||||
|
@ -431,13 +431,13 @@ static int jedec_probe8(struct map_info *map,unsigned long base,
|
|||
flwrite(Reset,0x555);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Reset.
|
||||
flwrite(Reset,0x555);
|
||||
|
||||
|
||||
return 1;
|
||||
|
||||
|
||||
#undef flread
|
||||
#undef flwrite
|
||||
}
|
||||
|
@ -470,17 +470,17 @@ static int jedec_probe32(struct map_info *map,unsigned long base,
|
|||
OldVal = flread(base);
|
||||
for (I = 0; OldVal != flread(base) && I < 10000; I++)
|
||||
OldVal = flread(base);
|
||||
|
||||
|
||||
// Reset the chip
|
||||
flwrite(Reset,0x555);
|
||||
|
||||
flwrite(Reset,0x555);
|
||||
|
||||
// Send the sequence
|
||||
flwrite(AutoSel1,0x555);
|
||||
flwrite(AutoSel2,0x2AA);
|
||||
flwrite(AutoSel3,0x555);
|
||||
|
||||
|
||||
// Test #1, JEDEC numbers are readable from 0x??00/0x??01
|
||||
if (flread(0) != flread(0x100) ||
|
||||
if (flread(0) != flread(0x100) ||
|
||||
flread(1) != flread(0x101))
|
||||
{
|
||||
flwrite(Reset,0x555);
|
||||
|
@ -494,14 +494,14 @@ static int jedec_probe32(struct map_info *map,unsigned long base,
|
|||
OldVal = flread(1);
|
||||
for (I = 0; I != 4; I++)
|
||||
Id[I] = (OldVal >> (I*8));
|
||||
|
||||
|
||||
Size = handle_jedecs(map,Mfg,Id,4,base,priv);
|
||||
if (Size == 0)
|
||||
{
|
||||
flwrite(Reset,0x555);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Check if there is address wrap around within a single bank, if this
|
||||
returns JEDEC numbers then we assume that it is wrap around. Notice
|
||||
we call this routine with the JEDEC return still enabled, if two or
|
||||
|
@ -519,27 +519,27 @@ static int jedec_probe32(struct map_info *map,unsigned long base,
|
|||
|
||||
// Reset.
|
||||
flwrite(0xF0F0F0F0,0x555);
|
||||
|
||||
|
||||
return 1;
|
||||
|
||||
|
||||
#undef flread
|
||||
#undef flwrite
|
||||
}
|
||||
|
||||
/* Linear read. */
|
||||
static int jedec_read(struct mtd_info *mtd, loff_t from, size_t len,
|
||||
static int jedec_read(struct mtd_info *mtd, loff_t from, size_t len,
|
||||
size_t *retlen, u_char *buf)
|
||||
{
|
||||
struct map_info *map = mtd->priv;
|
||||
|
||||
|
||||
map_copy_from(map, buf, from, len);
|
||||
*retlen = len;
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Banked read. Take special care to jump past the holes in the bank
|
||||
mapping. This version assumes symetry in the holes.. */
|
||||
static int jedec_read_banked(struct mtd_info *mtd, loff_t from, size_t len,
|
||||
static int jedec_read_banked(struct mtd_info *mtd, loff_t from, size_t len,
|
||||
size_t *retlen, u_char *buf)
|
||||
{
|
||||
struct map_info *map = mtd->priv;
|
||||
|
@ -555,17 +555,17 @@ static int jedec_read_banked(struct mtd_info *mtd, loff_t from, size_t len,
|
|||
if (priv->bank_fill[0] - offset < len)
|
||||
get = priv->bank_fill[0] - offset;
|
||||
|
||||
bank /= priv->bank_fill[0];
|
||||
bank /= priv->bank_fill[0];
|
||||
map_copy_from(map,buf + *retlen,bank*my_bank_size + offset,get);
|
||||
|
||||
|
||||
len -= get;
|
||||
*retlen += get;
|
||||
from += get;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Pass the flags value that the flash return before it re-entered read
|
||||
/* Pass the flags value that the flash return before it re-entered read
|
||||
mode. */
|
||||
static void jedec_flash_failed(unsigned char code)
|
||||
{
|
||||
|
@ -579,17 +579,17 @@ static void jedec_flash_failed(unsigned char code)
|
|||
printk("mtd: Programming didn't take\n");
|
||||
}
|
||||
|
||||
/* This uses the erasure function described in the AMD Flash Handbook,
|
||||
/* This uses the erasure function described in the AMD Flash Handbook,
|
||||
it will work for flashes with a fixed sector size only. Flashes with
|
||||
a selection of sector sizes (ie the AMD Am29F800B) will need a different
|
||||
routine. This routine tries to parallize erasing multiple chips/sectors
|
||||
routine. This routine tries to parallize erasing multiple chips/sectors
|
||||
where possible */
|
||||
static int flash_erase(struct mtd_info *mtd, struct erase_info *instr)
|
||||
{
|
||||
// Does IO to the currently selected chip
|
||||
#define flread(x) map_read8(map,chip->base+((x)<<chip->addrshift))
|
||||
#define flwrite(v,x) map_write8(map,v,chip->base+((x)<<chip->addrshift))
|
||||
|
||||
|
||||
unsigned long Time = 0;
|
||||
unsigned long NoTime = 0;
|
||||
unsigned long start = instr->addr, len = instr->len;
|
||||
|
@ -603,7 +603,7 @@ static int flash_erase(struct mtd_info *mtd, struct erase_info *instr)
|
|||
(len % mtd->erasesize) != 0 ||
|
||||
(len/mtd->erasesize) == 0)
|
||||
return -EINVAL;
|
||||
|
||||
|
||||
jedec_flash_chip_scan(priv,start,len);
|
||||
|
||||
// Start the erase sequence on each chip
|
||||
|
@ -611,16 +611,16 @@ static int flash_erase(struct mtd_info *mtd, struct erase_info *instr)
|
|||
{
|
||||
unsigned long off;
|
||||
struct jedec_flash_chip *chip = priv->chips + I;
|
||||
|
||||
|
||||
if (chip->length == 0)
|
||||
continue;
|
||||
|
||||
|
||||
if (chip->start + chip->length > chip->size)
|
||||
{
|
||||
printk("DIE\n");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
flwrite(0xF0,chip->start + 0x555);
|
||||
flwrite(0xAA,chip->start + 0x555);
|
||||
flwrite(0x55,chip->start + 0x2AA);
|
||||
|
@ -628,8 +628,8 @@ static int flash_erase(struct mtd_info *mtd, struct erase_info *instr)
|
|||
flwrite(0xAA,chip->start + 0x555);
|
||||
flwrite(0x55,chip->start + 0x2AA);
|
||||
|
||||
/* Once we start selecting the erase sectors the delay between each
|
||||
command must not exceed 50us or it will immediately start erasing
|
||||
/* Once we start selecting the erase sectors the delay between each
|
||||
command must not exceed 50us or it will immediately start erasing
|
||||
and ignore the other sectors */
|
||||
for (off = 0; off < len; off += chip->sectorsize)
|
||||
{
|
||||
|
@ -641,19 +641,19 @@ static int flash_erase(struct mtd_info *mtd, struct erase_info *instr)
|
|||
{
|
||||
printk("mtd: Ack! We timed out the erase timer!\n");
|
||||
return -EIO;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* We could split this into a timer routine and return early, performing
|
||||
background erasure.. Maybe later if the need warrents */
|
||||
|
||||
/* Poll the flash for erasure completion, specs say this can take as long
|
||||
as 480 seconds to do all the sectors (for a 2 meg flash).
|
||||
as 480 seconds to do all the sectors (for a 2 meg flash).
|
||||
Erasure time is dependent on chip age, temp and wear.. */
|
||||
|
||||
|
||||
/* This being a generic routine assumes a 32 bit bus. It does read32s
|
||||
and bundles interleved chips into the same grouping. This will work
|
||||
and bundles interleved chips into the same grouping. This will work
|
||||
for all bus widths */
|
||||
Time = 0;
|
||||
NoTime = 0;
|
||||
|
@ -664,20 +664,20 @@ static int flash_erase(struct mtd_info *mtd, struct erase_info *instr)
|
|||
unsigned todo[4] = {0,0,0,0};
|
||||
unsigned todo_left = 0;
|
||||
unsigned J;
|
||||
|
||||
|
||||
if (chip->length == 0)
|
||||
continue;
|
||||
|
||||
/* Find all chips in this data line, realistically this is all
|
||||
/* Find all chips in this data line, realistically this is all
|
||||
or nothing up to the interleve count */
|
||||
for (J = 0; priv->chips[J].jedec != 0 && J < MAX_JEDEC_CHIPS; J++)
|
||||
{
|
||||
if ((priv->chips[J].base & (~((1<<chip->addrshift)-1))) ==
|
||||
if ((priv->chips[J].base & (~((1<<chip->addrshift)-1))) ==
|
||||
(chip->base & (~((1<<chip->addrshift)-1))))
|
||||
{
|
||||
todo_left++;
|
||||
todo[priv->chips[J].base & ((1<<chip->addrshift)-1)] = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* printk("todo: %x %x %x %x\n",(short)todo[0],(short)todo[1],
|
||||
|
@ -687,7 +687,7 @@ static int flash_erase(struct mtd_info *mtd, struct erase_info *instr)
|
|||
{
|
||||
__u32 Last[4];
|
||||
unsigned long Count = 0;
|
||||
|
||||
|
||||
/* During erase bit 7 is held low and bit 6 toggles, we watch this,
|
||||
should it stop toggling or go high then the erase is completed,
|
||||
or this is not really flash ;> */
|
||||
|
@ -718,23 +718,23 @@ static int flash_erase(struct mtd_info *mtd, struct erase_info *instr)
|
|||
__u8 Byte3 = (Last[(Count-3)%4] >> (J*8)) & 0xFF;
|
||||
if (todo[J] == 0)
|
||||
continue;
|
||||
|
||||
|
||||
if ((Byte1 & (1 << 7)) == 0 && Byte1 != Byte2)
|
||||
{
|
||||
// printk("Check %x %x %x\n",(short)J,(short)Byte1,(short)Byte2);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
if (Byte1 == Byte2)
|
||||
{
|
||||
jedec_flash_failed(Byte3);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
|
||||
todo[J] = 0;
|
||||
todo_left--;
|
||||
}
|
||||
|
||||
|
||||
/* if (NoTime == 0)
|
||||
Time += HZ/10 - schedule_timeout(HZ/10);*/
|
||||
NoTime = 0;
|
||||
|
@ -751,7 +751,7 @@ static int flash_erase(struct mtd_info *mtd, struct erase_info *instr)
|
|||
break;
|
||||
}
|
||||
Count++;
|
||||
|
||||
|
||||
/* // Count time, max of 15s per sector (according to AMD)
|
||||
if (Time > 15*len/mtd->erasesize*HZ)
|
||||
{
|
||||
|
@ -759,38 +759,38 @@ static int flash_erase(struct mtd_info *mtd, struct erase_info *instr)
|
|||
return -EIO;
|
||||
} */
|
||||
}
|
||||
|
||||
|
||||
// Skip to the next chip if we used chip erase
|
||||
if (chip->length == chip->size)
|
||||
off = chip->size;
|
||||
else
|
||||
off += chip->sectorsize;
|
||||
|
||||
|
||||
if (off >= chip->length)
|
||||
break;
|
||||
NoTime = 1;
|
||||
}
|
||||
|
||||
|
||||
for (J = 0; priv->chips[J].jedec != 0 && J < MAX_JEDEC_CHIPS; J++)
|
||||
{
|
||||
if ((priv->chips[J].base & (~((1<<chip->addrshift)-1))) ==
|
||||
(chip->base & (~((1<<chip->addrshift)-1))))
|
||||
priv->chips[J].length = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//printk("done\n");
|
||||
instr->state = MTD_ERASE_DONE;
|
||||
mtd_erase_callback(instr);
|
||||
return 0;
|
||||
|
||||
|
||||
#undef flread
|
||||
#undef flwrite
|
||||
}
|
||||
|
||||
/* This is the simple flash writing function. It writes to every byte, in
|
||||
sequence. It takes care of how to properly address the flash if
|
||||
the flash is interleved. It can only be used if all the chips in the
|
||||
the flash is interleved. It can only be used if all the chips in the
|
||||
array are identical!*/
|
||||
static int flash_write(struct mtd_info *mtd, loff_t start, size_t len,
|
||||
size_t *retlen, const u_char *buf)
|
||||
|
@ -800,25 +800,25 @@ static int flash_write(struct mtd_info *mtd, loff_t start, size_t len,
|
|||
of addrshift (interleave index) and then adds the control register index. */
|
||||
#define flread(x) map_read8(map,base+(off&((1<<chip->addrshift)-1))+((x)<<chip->addrshift))
|
||||
#define flwrite(v,x) map_write8(map,v,base+(off&((1<<chip->addrshift)-1))+((x)<<chip->addrshift))
|
||||
|
||||
|
||||
struct map_info *map = mtd->priv;
|
||||
struct jedec_private *priv = map->fldrv_priv;
|
||||
unsigned long base;
|
||||
unsigned long off;
|
||||
size_t save_len = len;
|
||||
|
||||
|
||||
if (start + len > mtd->size)
|
||||
return -EIO;
|
||||
|
||||
|
||||
//printk("Here");
|
||||
|
||||
|
||||
//printk("flash_write: start is %x, len is %x\n",start,(unsigned long)len);
|
||||
while (len != 0)
|
||||
{
|
||||
struct jedec_flash_chip *chip = priv->chips;
|
||||
unsigned long bank;
|
||||
unsigned long boffset;
|
||||
|
||||
|
||||
// Compute the base of the flash.
|
||||
off = ((unsigned long)start) % (chip->size << chip->addrshift);
|
||||
base = start - off;
|
||||
|
@ -828,10 +828,10 @@ static int flash_write(struct mtd_info *mtd, loff_t start, size_t len,
|
|||
boffset = base & (priv->bank_fill[0]-1);
|
||||
bank = (bank/priv->bank_fill[0])*my_bank_size;
|
||||
base = bank + boffset;
|
||||
|
||||
|
||||
// printk("Flasing %X %X %X\n",base,chip->size,len);
|
||||
// printk("off is %x, compare with %x\n",off,chip->size << chip->addrshift);
|
||||
|
||||
|
||||
// Loop over this page
|
||||
for (; off != (chip->size << chip->addrshift) && len != 0; start++, len--, off++,buf++)
|
||||
{
|
||||
|
@ -845,7 +845,7 @@ static int flash_write(struct mtd_info *mtd, loff_t start, size_t len,
|
|||
}
|
||||
if (((~oldbyte) & *buf) != 0)
|
||||
printk("mtd: warn: Trying to set a 0 to a 1\n");
|
||||
|
||||
|
||||
// Write
|
||||
flwrite(0xAA,0x555);
|
||||
flwrite(0x55,0x2AA);
|
||||
|
@ -854,10 +854,10 @@ static int flash_write(struct mtd_info *mtd, loff_t start, size_t len,
|
|||
Last[0] = map_read8(map,base + off);
|
||||
Last[1] = map_read8(map,base + off);
|
||||
Last[2] = map_read8(map,base + off);
|
||||
|
||||
|
||||
/* Wait for the flash to finish the operation. We store the last 4
|
||||
status bytes that have been retrieved so we can determine why
|
||||
it failed. The toggle bits keep toggling when there is a
|
||||
it failed. The toggle bits keep toggling when there is a
|
||||
failure */
|
||||
for (Count = 3; Last[(Count - 1) % 4] != Last[(Count - 2) % 4] &&
|
||||
Count < 10000; Count++)
|
||||
|
@ -866,7 +866,7 @@ static int flash_write(struct mtd_info *mtd, loff_t start, size_t len,
|
|||
{
|
||||
jedec_flash_failed(Last[(Count - 3) % 4]);
|
||||
return -EIO;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
*retlen = save_len;
|
||||
|
@ -885,24 +885,24 @@ static void jedec_flash_chip_scan(struct jedec_private *priv,unsigned long start
|
|||
// Zero the records
|
||||
for (I = 0; priv->chips[I].jedec != 0 && I < MAX_JEDEC_CHIPS; I++)
|
||||
priv->chips[I].start = priv->chips[I].length = 0;
|
||||
|
||||
|
||||
// Intersect the region with each chip
|
||||
for (I = 0; priv->chips[I].jedec != 0 && I < MAX_JEDEC_CHIPS; I++)
|
||||
{
|
||||
struct jedec_flash_chip *chip = priv->chips + I;
|
||||
unsigned long ByteStart;
|
||||
unsigned long ChipEndByte = chip->offset + (chip->size << chip->addrshift);
|
||||
|
||||
|
||||
// End is before this chip or the start is after it
|
||||
if (start+len < chip->offset ||
|
||||
ChipEndByte - (1 << chip->addrshift) < start)
|
||||
continue;
|
||||
|
||||
|
||||
if (start < chip->offset)
|
||||
{
|
||||
ByteStart = chip->offset;
|
||||
chip->start = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
chip->start = (start - chip->offset + (1 << chip->addrshift)-1) >> chip->addrshift;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
/*
|
||||
Common Flash Interface probe code.
|
||||
(C) 2000 Red Hat. GPL'd.
|
||||
$Id: jedec_probe.c,v 1.63 2005/02/14 16:30:32 bjd Exp $
|
||||
$Id: jedec_probe.c,v 1.66 2005/11/07 11:14:23 gleixner Exp $
|
||||
See JEDEC (http://www.jedec.org/) standard JESD21C (section 3.5)
|
||||
for the standard this probe goes back to.
|
||||
|
||||
|
@ -1719,7 +1719,7 @@ static int jedec_probe_chip(struct map_info *map, __u32 base,
|
|||
|
||||
static struct mtd_info *jedec_probe(struct map_info *map);
|
||||
|
||||
static inline u32 jedec_read_mfr(struct map_info *map, __u32 base,
|
||||
static inline u32 jedec_read_mfr(struct map_info *map, __u32 base,
|
||||
struct cfi_private *cfi)
|
||||
{
|
||||
map_word result;
|
||||
|
@ -1730,7 +1730,7 @@ static inline u32 jedec_read_mfr(struct map_info *map, __u32 base,
|
|||
return result.x[0] & mask;
|
||||
}
|
||||
|
||||
static inline u32 jedec_read_id(struct map_info *map, __u32 base,
|
||||
static inline u32 jedec_read_id(struct map_info *map, __u32 base,
|
||||
struct cfi_private *cfi)
|
||||
{
|
||||
map_word result;
|
||||
|
@ -1741,7 +1741,7 @@ static inline u32 jedec_read_id(struct map_info *map, __u32 base,
|
|||
return result.x[0] & mask;
|
||||
}
|
||||
|
||||
static inline void jedec_reset(u32 base, struct map_info *map,
|
||||
static inline void jedec_reset(u32 base, struct map_info *map,
|
||||
struct cfi_private *cfi)
|
||||
{
|
||||
/* Reset */
|
||||
|
@ -1765,7 +1765,7 @@ static inline void jedec_reset(u32 base, struct map_info *map,
|
|||
* so ensure we're in read mode. Send both the Intel and the AMD command
|
||||
* for this. Intel uses 0xff for this, AMD uses 0xff for NOP, so
|
||||
* this should be safe.
|
||||
*/
|
||||
*/
|
||||
cfi_send_gen_cmd(0xFF, 0, base, map, cfi, cfi->device_type, NULL);
|
||||
/* FIXME - should have reset delay before continuing */
|
||||
}
|
||||
|
@ -1807,14 +1807,14 @@ static int cfi_jedec_setup(struct cfi_private *p_cfi, int index)
|
|||
printk("Found: %s\n",jedec_table[index].name);
|
||||
|
||||
num_erase_regions = jedec_table[index].NumEraseRegions;
|
||||
|
||||
|
||||
p_cfi->cfiq = kmalloc(sizeof(struct cfi_ident) + num_erase_regions * 4, GFP_KERNEL);
|
||||
if (!p_cfi->cfiq) {
|
||||
//xx printk(KERN_WARNING "%s: kmalloc failed for CFI ident structure\n", map->name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
memset(p_cfi->cfiq,0,sizeof(struct cfi_ident));
|
||||
memset(p_cfi->cfiq,0,sizeof(struct cfi_ident));
|
||||
|
||||
p_cfi->cfiq->P_ID = jedec_table[index].CmdSet;
|
||||
p_cfi->cfiq->NumEraseRegions = jedec_table[index].NumEraseRegions;
|
||||
|
@ -1969,7 +1969,7 @@ static inline int jedec_match( __u32 base,
|
|||
cfi_send_gen_cmd(0x90, cfi->addr_unlock1, base, map, cfi, cfi->device_type, NULL);
|
||||
/* FIXME - should have a delay before continuing */
|
||||
|
||||
match_done:
|
||||
match_done:
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
@ -1998,23 +1998,23 @@ static int jedec_probe_chip(struct map_info *map, __u32 base,
|
|||
"Probe at base(0x%08x) past the end of the map(0x%08lx)\n",
|
||||
base, map->size -1);
|
||||
return 0;
|
||||
|
||||
|
||||
}
|
||||
/* Ensure the unlock addresses we try stay inside the map */
|
||||
probe_offset1 = cfi_build_cmd_addr(
|
||||
cfi->addr_unlock1,
|
||||
cfi_interleave(cfi),
|
||||
cfi->addr_unlock1,
|
||||
cfi_interleave(cfi),
|
||||
cfi->device_type);
|
||||
probe_offset2 = cfi_build_cmd_addr(
|
||||
cfi->addr_unlock1,
|
||||
cfi_interleave(cfi),
|
||||
cfi->addr_unlock1,
|
||||
cfi_interleave(cfi),
|
||||
cfi->device_type);
|
||||
if ( ((base + probe_offset1 + map_bankwidth(map)) >= map->size) ||
|
||||
((base + probe_offset2 + map_bankwidth(map)) >= map->size))
|
||||
{
|
||||
goto retry;
|
||||
}
|
||||
|
||||
|
||||
/* Reset */
|
||||
jedec_reset(base, map, cfi);
|
||||
|
||||
|
@ -2027,13 +2027,13 @@ static int jedec_probe_chip(struct map_info *map, __u32 base,
|
|||
/* FIXME - should have a delay before continuing */
|
||||
|
||||
if (!cfi->numchips) {
|
||||
/* This is the first time we're called. Set up the CFI
|
||||
/* This is the first time we're called. Set up the CFI
|
||||
stuff accordingly and return */
|
||||
|
||||
|
||||
cfi->mfr = jedec_read_mfr(map, base, cfi);
|
||||
cfi->id = jedec_read_id(map, base, cfi);
|
||||
DEBUG(MTD_DEBUG_LEVEL3,
|
||||
"Search for id:(%02x %02x) interleave(%d) type(%d)\n",
|
||||
"Search for id:(%02x %02x) interleave(%d) type(%d)\n",
|
||||
cfi->mfr, cfi->id, cfi_interleave(cfi), cfi->device_type);
|
||||
for (i=0; i<sizeof(jedec_table)/sizeof(jedec_table[0]); i++) {
|
||||
if ( jedec_match( base, map, cfi, &jedec_table[i] ) ) {
|
||||
|
@ -2062,7 +2062,7 @@ static int jedec_probe_chip(struct map_info *map, __u32 base,
|
|||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Check each previous chip locations to see if it's an alias */
|
||||
for (i=0; i < (base >> cfi->chipshift); i++) {
|
||||
unsigned long start;
|
||||
|
@ -2083,7 +2083,7 @@ static int jedec_probe_chip(struct map_info *map, __u32 base,
|
|||
map->name, base, start);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Yes, it's actually got the device IDs as data. Most
|
||||
* unfortunate. Stick the new chip in read mode
|
||||
* too and if it's the same, assume it's an alias. */
|
||||
|
@ -2097,20 +2097,20 @@ static int jedec_probe_chip(struct map_info *map, __u32 base,
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* OK, if we got to here, then none of the previous chips appear to
|
||||
be aliases for the current one. */
|
||||
set_bit((base >> cfi->chipshift), chip_map); /* Update chip map */
|
||||
cfi->numchips++;
|
||||
|
||||
|
||||
ok_out:
|
||||
/* Put it back into Read Mode */
|
||||
jedec_reset(base, map, cfi);
|
||||
|
||||
printk(KERN_INFO "%s: Found %d x%d devices at 0x%x in %d-bit bank\n",
|
||||
map->name, cfi_interleave(cfi), cfi->device_type*8, base,
|
||||
map->name, cfi_interleave(cfi), cfi->device_type*8, base,
|
||||
map->bankwidth*8);
|
||||
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
/*
|
||||
* Common code to handle absent "placeholder" devices
|
||||
* Copyright 2001 Resilience Corporation <ebrower@resilience.com>
|
||||
* $Id: map_absent.c,v 1.5 2004/11/16 18:29:00 dwmw2 Exp $
|
||||
* $Id: map_absent.c,v 1.6 2005/11/07 11:14:23 gleixner Exp $
|
||||
*
|
||||
* This map driver is used to allocate "placeholder" MTD
|
||||
* devices on systems that have socketed/removable media.
|
||||
* Use of this driver as a fallback preserves the expected
|
||||
* devices on systems that have socketed/removable media.
|
||||
* Use of this driver as a fallback preserves the expected
|
||||
* registration of MTD device nodes regardless of probe outcome.
|
||||
* A usage example is as follows:
|
||||
*
|
||||
|
@ -80,7 +80,7 @@ static int map_absent_read(struct mtd_info *mtd, loff_t from, size_t len, size_t
|
|||
static int map_absent_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf)
|
||||
{
|
||||
*retlen = 0;
|
||||
return -ENODEV;
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
static int map_absent_erase(struct mtd_info *mtd, struct erase_info *instr)
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
* Copyright 2000,2001 David A. Schleef <ds@schleef.org>
|
||||
* 2000,2001 Lineo, Inc.
|
||||
*
|
||||
* $Id: sharp.c,v 1.14 2004/08/09 13:19:43 dwmw2 Exp $
|
||||
* $Id: sharp.c,v 1.16 2005/11/07 11:14:23 gleixner Exp $
|
||||
*
|
||||
* Devices supported:
|
||||
* LH28F016SCT Symmetrical block flash memory, 2Mx8
|
||||
|
@ -31,6 +31,7 @@
|
|||
#include <linux/mtd/cfi.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#define CMD_RESET 0xffffffff
|
||||
#define CMD_READ_ID 0x90909090
|
||||
|
@ -214,7 +215,7 @@ static int sharp_probe_map(struct map_info *map,struct mtd_info *mtd)
|
|||
/* This function returns with the chip->mutex lock held. */
|
||||
static int sharp_wait(struct map_info *map, struct flchip *chip)
|
||||
{
|
||||
__u16 status;
|
||||
int status, i;
|
||||
unsigned long timeo = jiffies + HZ;
|
||||
DECLARE_WAITQUEUE(wait, current);
|
||||
int adr = 0;
|
||||
|
@ -227,13 +228,11 @@ static int sharp_wait(struct map_info *map, struct flchip *chip)
|
|||
map_write32(map,CMD_READ_STATUS,adr);
|
||||
chip->state = FL_STATUS;
|
||||
case FL_STATUS:
|
||||
status = map_read32(map,adr);
|
||||
//printk("status=%08x\n",status);
|
||||
|
||||
udelay(100);
|
||||
if((status & SR_READY)!=SR_READY){
|
||||
//printk(".status=%08x\n",status);
|
||||
udelay(100);
|
||||
for(i=0;i<100;i++){
|
||||
status = map_read32(map,adr);
|
||||
if((status & SR_READY)==SR_READY)
|
||||
break;
|
||||
udelay(1);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
@ -460,12 +459,12 @@ static int sharp_do_wait_for_ready(struct map_info *map, struct flchip *chip,
|
|||
remove_wait_queue(&chip->wq, &wait);
|
||||
|
||||
//spin_lock_bh(chip->mutex);
|
||||
|
||||
|
||||
if (signal_pending(current)){
|
||||
ret = -EINTR;
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
ret = -ETIME;
|
||||
out:
|
||||
|
@ -564,7 +563,7 @@ static int sharp_suspend(struct mtd_info *mtd)
|
|||
static void sharp_resume(struct mtd_info *mtd)
|
||||
{
|
||||
printk("sharp_resume()\n");
|
||||
|
||||
|
||||
}
|
||||
|
||||
static void sharp_destroy(struct mtd_info *mtd)
|
||||
|
|
|
@ -1,24 +1,24 @@
|
|||
/*
|
||||
* $Id: cmdlinepart.c,v 1.18 2005/06/07 15:04:26 joern Exp $
|
||||
* $Id: cmdlinepart.c,v 1.19 2005/11/07 11:14:19 gleixner Exp $
|
||||
*
|
||||
* Read flash partition table from command line
|
||||
*
|
||||
* Copyright 2002 SYSGO Real-Time Solutions GmbH
|
||||
*
|
||||
* The format for the command line is as follows:
|
||||
*
|
||||
*
|
||||
* mtdparts=<mtddef>[;<mtddef]
|
||||
* <mtddef> := <mtd-id>:<partdef>[,<partdef>]
|
||||
* <partdef> := <size>[@offset][<name>][ro]
|
||||
* <mtd-id> := unique name used in mapping driver/device (mtd->name)
|
||||
* <size> := standard linux memsize OR "-" to denote all remaining space
|
||||
* <name> := '(' NAME ')'
|
||||
*
|
||||
*
|
||||
* Examples:
|
||||
*
|
||||
*
|
||||
* 1 NOR Flash, with 1 single writable partition:
|
||||
* edb7312-nor:-
|
||||
*
|
||||
*
|
||||
* 1 NOR Flash with 2 partitions, 1 NAND with one
|
||||
* edb7312-nor:256k(ARMboot)ro,-(root);edb7312-nand:-(home)
|
||||
*/
|
||||
|
@ -60,17 +60,17 @@ static int cmdline_parsed = 0;
|
|||
|
||||
/*
|
||||
* Parse one partition definition for an MTD. Since there can be many
|
||||
* comma separated partition definitions, this function calls itself
|
||||
* comma separated partition definitions, this function calls itself
|
||||
* recursively until no more partition definitions are found. Nice side
|
||||
* effect: the memory to keep the mtd_partition structs and the names
|
||||
* is allocated upon the last definition being found. At that point the
|
||||
* syntax has been verified ok.
|
||||
*/
|
||||
static struct mtd_partition * newpart(char *s,
|
||||
static struct mtd_partition * newpart(char *s,
|
||||
char **retptr,
|
||||
int *num_parts,
|
||||
int this_part,
|
||||
unsigned char **extra_mem_ptr,
|
||||
int this_part,
|
||||
unsigned char **extra_mem_ptr,
|
||||
int extra_mem_size)
|
||||
{
|
||||
struct mtd_partition *parts;
|
||||
|
@ -102,7 +102,7 @@ static struct mtd_partition * newpart(char *s,
|
|||
mask_flags = 0; /* this is going to be a regular partition */
|
||||
delim = 0;
|
||||
/* check for offset */
|
||||
if (*s == '@')
|
||||
if (*s == '@')
|
||||
{
|
||||
s++;
|
||||
offset = memparse(s, &s);
|
||||
|
@ -112,7 +112,7 @@ static struct mtd_partition * newpart(char *s,
|
|||
{
|
||||
delim = ')';
|
||||
}
|
||||
|
||||
|
||||
if (delim)
|
||||
{
|
||||
char *p;
|
||||
|
@ -131,12 +131,12 @@ static struct mtd_partition * newpart(char *s,
|
|||
name = NULL;
|
||||
name_len = 13; /* Partition_000 */
|
||||
}
|
||||
|
||||
|
||||
/* record name length for memory allocation later */
|
||||
extra_mem_size += name_len + 1;
|
||||
|
||||
/* test for options */
|
||||
if (strncmp(s, "ro", 2) == 0)
|
||||
if (strncmp(s, "ro", 2) == 0)
|
||||
{
|
||||
mask_flags |= MTD_WRITEABLE;
|
||||
s += 2;
|
||||
|
@ -151,7 +151,7 @@ static struct mtd_partition * newpart(char *s,
|
|||
return NULL;
|
||||
}
|
||||
/* more partitions follow, parse them */
|
||||
if ((parts = newpart(s + 1, &s, num_parts,
|
||||
if ((parts = newpart(s + 1, &s, num_parts,
|
||||
this_part + 1, &extra_mem, extra_mem_size)) == 0)
|
||||
return NULL;
|
||||
}
|
||||
|
@ -187,7 +187,7 @@ static struct mtd_partition * newpart(char *s,
|
|||
extra_mem += name_len + 1;
|
||||
|
||||
dbg(("partition %d: name <%s>, offset %x, size %x, mask flags %x\n",
|
||||
this_part,
|
||||
this_part,
|
||||
parts[this_part].name,
|
||||
parts[this_part].offset,
|
||||
parts[this_part].size,
|
||||
|
@ -204,8 +204,8 @@ static struct mtd_partition * newpart(char *s,
|
|||
return parts;
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse the command line.
|
||||
/*
|
||||
* Parse the command line.
|
||||
*/
|
||||
static int mtdpart_setup_real(char *s)
|
||||
{
|
||||
|
@ -230,7 +230,7 @@ static int mtdpart_setup_real(char *s)
|
|||
|
||||
dbg(("parsing <%s>\n", p+1));
|
||||
|
||||
/*
|
||||
/*
|
||||
* parse one mtd. have it reserve memory for the
|
||||
* struct cmdline_mtd_partition and the mtd-id string.
|
||||
*/
|
||||
|
@ -239,7 +239,7 @@ static int mtdpart_setup_real(char *s)
|
|||
&num_parts, /* out: number of parts */
|
||||
0, /* first partition */
|
||||
(unsigned char**)&this_mtd, /* out: extra mem */
|
||||
mtd_id_len + 1 + sizeof(*this_mtd) +
|
||||
mtd_id_len + 1 + sizeof(*this_mtd) +
|
||||
sizeof(void*)-1 /*alignment*/);
|
||||
if(!parts)
|
||||
{
|
||||
|
@ -254,21 +254,21 @@ static int mtdpart_setup_real(char *s)
|
|||
}
|
||||
|
||||
/* align this_mtd */
|
||||
this_mtd = (struct cmdline_mtd_partition *)
|
||||
this_mtd = (struct cmdline_mtd_partition *)
|
||||
ALIGN((unsigned long)this_mtd, sizeof(void*));
|
||||
/* enter results */
|
||||
/* enter results */
|
||||
this_mtd->parts = parts;
|
||||
this_mtd->num_parts = num_parts;
|
||||
this_mtd->mtd_id = (char*)(this_mtd + 1);
|
||||
strlcpy(this_mtd->mtd_id, mtd_id, mtd_id_len + 1);
|
||||
|
||||
/* link into chain */
|
||||
this_mtd->next = partitions;
|
||||
this_mtd->next = partitions;
|
||||
partitions = this_mtd;
|
||||
|
||||
dbg(("mtdid=<%s> num_parts=<%d>\n",
|
||||
dbg(("mtdid=<%s> num_parts=<%d>\n",
|
||||
this_mtd->mtd_id, this_mtd->num_parts));
|
||||
|
||||
|
||||
|
||||
/* EOS - we're done */
|
||||
if (*s == 0)
|
||||
|
@ -292,7 +292,7 @@ static int mtdpart_setup_real(char *s)
|
|||
* information. It returns partitions for the requested mtd device, or
|
||||
* the first one in the chain if a NULL mtd_id is passed in.
|
||||
*/
|
||||
static int parse_cmdline_partitions(struct mtd_info *master,
|
||||
static int parse_cmdline_partitions(struct mtd_info *master,
|
||||
struct mtd_partition **pparts,
|
||||
unsigned long origin)
|
||||
{
|
||||
|
@ -322,7 +322,7 @@ static int parse_cmdline_partitions(struct mtd_info *master,
|
|||
part->parts[i].size = master->size - offset;
|
||||
if (offset + part->parts[i].size > master->size)
|
||||
{
|
||||
printk(KERN_WARNING ERRP
|
||||
printk(KERN_WARNING ERRP
|
||||
"%s: partitioning exceeds flash size, truncating\n",
|
||||
part->mtd_id);
|
||||
part->parts[i].size = master->size - offset;
|
||||
|
@ -338,8 +338,8 @@ static int parse_cmdline_partitions(struct mtd_info *master,
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
* This is the handler for our kernel parameter, called from
|
||||
/*
|
||||
* This is the handler for our kernel parameter, called from
|
||||
* main.c::checksetup(). Note that we can not yet kmalloc() anything,
|
||||
* so we only save the commandline for later processing.
|
||||
*
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# drivers/mtd/maps/Kconfig
|
||||
# $Id: Kconfig,v 1.15 2004/12/22 17:51:15 joern Exp $
|
||||
# $Id: Kconfig,v 1.18 2005/11/07 11:14:24 gleixner Exp $
|
||||
|
||||
menu "Self-contained MTD device drivers"
|
||||
depends on MTD!=n
|
||||
|
@ -110,7 +110,7 @@ config MTDRAM_ABS_POS
|
|||
If you have system RAM accessible by the CPU but not used by Linux
|
||||
in normal operation, you can give the physical address at which the
|
||||
available RAM starts, and the MTDRAM driver will use it instead of
|
||||
allocating space from Linux's available memory. Otherwise, leave
|
||||
allocating space from Linux's available memory. Otherwise, leave
|
||||
this set to zero. Most people will want to leave this as zero.
|
||||
|
||||
config MTD_BLKMTD
|
||||
|
@ -165,7 +165,7 @@ config MTD_DOC2001
|
|||
select MTD_DOCPROBE
|
||||
select MTD_NAND_IDS
|
||||
---help---
|
||||
This provides an alternative MTD device driver for the M-Systems
|
||||
This provides an alternative MTD device driver for the M-Systems
|
||||
DiskOnChip Millennium devices. Use this if you have problems with
|
||||
the combined DiskOnChip 2000 and Millennium driver above. To get
|
||||
the DiskOnChip probe code to load and use this driver instead of
|
||||
|
@ -192,7 +192,7 @@ config MTD_DOC2001PLUS
|
|||
|
||||
If you use this device, you probably also want to enable the INFTL
|
||||
'Inverse NAND Flash Translation Layer' option below, which is used
|
||||
to emulate a block device by using a kind of file system on the
|
||||
to emulate a block device by using a kind of file system on the
|
||||
flash chips.
|
||||
|
||||
NOTE: This driver will soon be replaced by the new DiskOnChip driver
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* $Id: blkmtd.c,v 1.24 2004/11/16 18:29:01 dwmw2 Exp $
|
||||
* $Id: blkmtd.c,v 1.27 2005/11/07 11:14:24 gleixner Exp $
|
||||
*
|
||||
* blkmtd.c - use a block device as a fake MTD
|
||||
*
|
||||
|
@ -39,7 +39,7 @@
|
|||
|
||||
/* Default erase size in K, always make it a multiple of PAGE_SIZE */
|
||||
#define CONFIG_MTD_BLKDEV_ERASESIZE (128 << 10) /* 128KiB */
|
||||
#define VERSION "$Revision: 1.24 $"
|
||||
#define VERSION "$Revision: 1.27 $"
|
||||
|
||||
/* Info for the block device */
|
||||
struct blkmtd_dev {
|
||||
|
@ -117,7 +117,7 @@ static int bi_write_complete(struct bio *bio, unsigned int bytes_done, int error
|
|||
unlock_page(page);
|
||||
page_cache_release(page);
|
||||
} while (bvec >= bio->bi_io_vec);
|
||||
|
||||
|
||||
complete((struct completion*)bio->bi_private);
|
||||
return 0;
|
||||
}
|
||||
|
@ -135,7 +135,7 @@ static int blkmtd_readpage(struct blkmtd_dev *dev, struct page *page)
|
|||
unlock_page(page);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
ClearPageUptodate(page);
|
||||
ClearPageError(page);
|
||||
|
||||
|
@ -707,7 +707,7 @@ static struct blkmtd_dev *add_device(char *devname, int readonly, int erase_size
|
|||
dev->mtd_info.erasesize >> 10,
|
||||
readonly ? "(read-only)" : "");
|
||||
}
|
||||
|
||||
|
||||
return dev;
|
||||
|
||||
devinit_err:
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* $Id: block2mtd.c,v 1.28 2005/03/19 22:40:44 gleixner Exp $
|
||||
* $Id: block2mtd.c,v 1.29 2005/11/07 11:14:24 gleixner Exp $
|
||||
*
|
||||
* block2mtd.c - create an mtd from a block device
|
||||
*
|
||||
|
@ -19,7 +19,7 @@
|
|||
#include <linux/mtd/mtd.h>
|
||||
#include <linux/buffer_head.h>
|
||||
|
||||
#define VERSION "$Revision: 1.28 $"
|
||||
#define VERSION "$Revision: 1.29 $"
|
||||
|
||||
|
||||
#define ERROR(fmt, args...) printk(KERN_ERR "block2mtd: " fmt "\n" , ## args)
|
||||
|
@ -111,7 +111,7 @@ static int _block2mtd_erase(struct block2mtd_dev *dev, loff_t to, size_t len)
|
|||
return PTR_ERR(page);
|
||||
|
||||
max = (u_long*)page_address(page) + PAGE_SIZE;
|
||||
for (p=(u_long*)page_address(page); p<max; p++)
|
||||
for (p=(u_long*)page_address(page); p<max; p++)
|
||||
if (*p != -1UL) {
|
||||
lock_page(page);
|
||||
memset(page_address(page), 0xff, PAGE_SIZE);
|
||||
|
@ -206,7 +206,7 @@ static int _block2mtd_write(struct block2mtd_dev *dev, const u_char *buf,
|
|||
if (retlen)
|
||||
*retlen = 0;
|
||||
while (len) {
|
||||
if ((offset+len) > PAGE_SIZE)
|
||||
if ((offset+len) > PAGE_SIZE)
|
||||
cpylen = PAGE_SIZE - offset; // multiple pages
|
||||
else
|
||||
cpylen = len; // this page
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
* (c) 1999 Machine Vision Holdings, Inc.
|
||||
* (c) 1999, 2000 David Woodhouse <dwmw2@infradead.org>
|
||||
*
|
||||
* $Id: doc2000.c,v 1.66 2005/01/05 18:05:12 dwmw2 Exp $
|
||||
* $Id: doc2000.c,v 1.67 2005/11/07 11:14:24 gleixner Exp $
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
|
@ -58,7 +58,7 @@ static int doc_read_ecc(struct mtd_info *mtd, loff_t from, size_t len,
|
|||
size_t *retlen, u_char *buf, u_char *eccbuf, struct nand_oobinfo *oobsel);
|
||||
static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len,
|
||||
size_t *retlen, const u_char *buf, u_char *eccbuf, struct nand_oobinfo *oobsel);
|
||||
static int doc_writev_ecc(struct mtd_info *mtd, const struct kvec *vecs,
|
||||
static int doc_writev_ecc(struct mtd_info *mtd, const struct kvec *vecs,
|
||||
unsigned long count, loff_t to, size_t *retlen,
|
||||
u_char *eccbuf, struct nand_oobinfo *oobsel);
|
||||
static int doc_read_oob(struct mtd_info *mtd, loff_t ofs, size_t len,
|
||||
|
@ -76,14 +76,14 @@ static void DoC_Delay(struct DiskOnChip *doc, unsigned short cycles)
|
|||
{
|
||||
volatile char dummy;
|
||||
int i;
|
||||
|
||||
|
||||
for (i = 0; i < cycles; i++) {
|
||||
if (DoC_is_Millennium(doc))
|
||||
dummy = ReadDOC(doc->virtadr, NOP);
|
||||
else
|
||||
dummy = ReadDOC(doc->virtadr, DOCStatus);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/* DOC_WaitReady: Wait for RDY line to be asserted by the flash chip */
|
||||
|
@ -220,8 +220,8 @@ static int DoC_Address(struct DiskOnChip *doc, int numbytes, unsigned long ofs,
|
|||
WriteDOC(ofs & 0xff, docptr, WritePipeTerm);
|
||||
|
||||
DoC_Delay(doc, 2); /* Needed for some slow flash chips. mf. */
|
||||
|
||||
/* FIXME: The SlowIO's for millennium could be replaced by
|
||||
|
||||
/* FIXME: The SlowIO's for millennium could be replaced by
|
||||
a single WritePipeTerm here. mf. */
|
||||
|
||||
/* Lower the ALE line */
|
||||
|
@ -377,9 +377,9 @@ static int DoC_IdentChip(struct DiskOnChip *doc, int floor, int chip)
|
|||
if (mfr == 0xff || mfr == 0)
|
||||
return 0;
|
||||
|
||||
/* Check it's the same as the first chip we identified.
|
||||
/* Check it's the same as the first chip we identified.
|
||||
* M-Systems say that any given DiskOnChip device should only
|
||||
* contain _one_ type of flash part, although that's not a
|
||||
* contain _one_ type of flash part, although that's not a
|
||||
* hardware restriction. */
|
||||
if (doc->mfr) {
|
||||
if (doc->mfr == mfr && doc->id == id)
|
||||
|
@ -397,7 +397,7 @@ static int DoC_IdentChip(struct DiskOnChip *doc, int floor, int chip)
|
|||
for (j = 0; nand_manuf_ids[j].id != 0x0; j++) {
|
||||
if (nand_manuf_ids[j].id == mfr)
|
||||
break;
|
||||
}
|
||||
}
|
||||
printk(KERN_INFO
|
||||
"Flash chip found: Manufacturer ID: %2.2X, "
|
||||
"Chip ID: %2.2X (%s:%s)\n", mfr, id,
|
||||
|
@ -405,7 +405,7 @@ static int DoC_IdentChip(struct DiskOnChip *doc, int floor, int chip)
|
|||
if (!doc->mfr) {
|
||||
doc->mfr = mfr;
|
||||
doc->id = id;
|
||||
doc->chipshift =
|
||||
doc->chipshift =
|
||||
ffs((nand_flash_ids[i].chipsize << 20)) - 1;
|
||||
doc->page256 = (nand_flash_ids[i].pagesize == 256) ? 1 : 0;
|
||||
doc->pageadrlen = doc->chipshift > 25 ? 3 : 2;
|
||||
|
@ -467,7 +467,7 @@ static void DoC_ScanChips(struct DiskOnChip *this, int maxchips)
|
|||
|
||||
ret = 0;
|
||||
|
||||
/* Fill out the chip array with {floor, chipno} for each
|
||||
/* Fill out the chip array with {floor, chipno} for each
|
||||
* detected chip in the device. */
|
||||
for (floor = 0; floor < MAX_FLOORS; floor++) {
|
||||
for (chip = 0; chip < numchips[floor]; chip++) {
|
||||
|
@ -757,12 +757,12 @@ static int doc_read_ecc(struct mtd_info *mtd, loff_t from, size_t len,
|
|||
(long)from, eccbuf[0], eccbuf[1], eccbuf[2],
|
||||
eccbuf[3], eccbuf[4], eccbuf[5]);
|
||||
#endif
|
||||
|
||||
|
||||
/* disable the ECC engine */
|
||||
WriteDOC(DOC_ECC_DIS, docptr , ECCConf);
|
||||
}
|
||||
|
||||
/* according to 11.4.1, we need to wait for the busy line
|
||||
/* according to 11.4.1, we need to wait for the busy line
|
||||
* drop if we read to the end of the page. */
|
||||
if(0 == ((from + len) & 0x1ff))
|
||||
{
|
||||
|
@ -941,7 +941,7 @@ static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len,
|
|||
|
||||
/* Let the caller know we completed it */
|
||||
*retlen += len;
|
||||
|
||||
|
||||
if (eccbuf) {
|
||||
unsigned char x[8];
|
||||
size_t dummy;
|
||||
|
@ -950,10 +950,10 @@ static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len,
|
|||
/* Write the ECC data to flash */
|
||||
for (di=0; di<6; di++)
|
||||
x[di] = eccbuf[di];
|
||||
|
||||
|
||||
x[6]=0x55;
|
||||
x[7]=0x55;
|
||||
|
||||
|
||||
ret = doc_write_oob_nolock(mtd, to, 8, &dummy, x);
|
||||
if (ret) {
|
||||
up(&this->lock);
|
||||
|
@ -970,7 +970,7 @@ static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int doc_writev_ecc(struct mtd_info *mtd, const struct kvec *vecs,
|
||||
static int doc_writev_ecc(struct mtd_info *mtd, const struct kvec *vecs,
|
||||
unsigned long count, loff_t to, size_t *retlen,
|
||||
u_char *eccbuf, struct nand_oobinfo *oobsel)
|
||||
{
|
||||
|
@ -1022,7 +1022,7 @@ static int doc_writev_ecc(struct mtd_info *mtd, const struct kvec *vecs,
|
|||
break;
|
||||
|
||||
to += thislen;
|
||||
}
|
||||
}
|
||||
|
||||
up(&writev_buf_sem);
|
||||
*retlen = totretlen;
|
||||
|
@ -1080,7 +1080,7 @@ static int doc_read_oob(struct mtd_info *mtd, loff_t ofs, size_t len,
|
|||
/* Reading the full OOB data drops us off of the end of the page,
|
||||
* causing the flash device to go into busy mode, so we need
|
||||
* to wait until ready 11.4.1 and Toshiba TC58256FT docs */
|
||||
|
||||
|
||||
ret = DoC_WaitReady(this);
|
||||
|
||||
up(&this->lock);
|
||||
|
@ -1190,7 +1190,7 @@ static int doc_write_oob_nolock(struct mtd_info *mtd, loff_t ofs, size_t len,
|
|||
return 0;
|
||||
|
||||
}
|
||||
|
||||
|
||||
static int doc_write_oob(struct mtd_info *mtd, loff_t ofs, size_t len,
|
||||
size_t * retlen, const u_char * buf)
|
||||
{
|
||||
|
@ -1222,7 +1222,7 @@ static int doc_erase(struct mtd_info *mtd, struct erase_info *instr)
|
|||
}
|
||||
|
||||
instr->state = MTD_ERASING;
|
||||
|
||||
|
||||
/* FIXME: Do this in the background. Use timers or schedule_task() */
|
||||
while(len) {
|
||||
mychip = &this->chips[ofs >> this->chipshift];
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
* (c) 1999 Machine Vision Holdings, Inc.
|
||||
* (c) 1999, 2000 David Woodhouse <dwmw2@infradead.org>
|
||||
*
|
||||
* $Id: doc2001.c,v 1.48 2005/01/05 18:05:12 dwmw2 Exp $
|
||||
* $Id: doc2001.c,v 1.49 2005/11/07 11:14:24 gleixner Exp $
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
|
@ -196,10 +196,10 @@ static int DoC_IdentChip(struct DiskOnChip *doc, int floor, int chip)
|
|||
DoC_Command(doc->virtadr, NAND_CMD_RESET, CDSN_CTRL_WP);
|
||||
DoC_WaitReady(doc->virtadr);
|
||||
|
||||
/* Read the NAND chip ID: 1. Send ReadID command */
|
||||
/* Read the NAND chip ID: 1. Send ReadID command */
|
||||
DoC_Command(doc->virtadr, NAND_CMD_READID, CDSN_CTRL_WP);
|
||||
|
||||
/* Read the NAND chip ID: 2. Send address byte zero */
|
||||
/* Read the NAND chip ID: 2. Send address byte zero */
|
||||
DoC_Address(doc->virtadr, 1, 0x00, CDSN_CTRL_WP, 0x00);
|
||||
|
||||
/* Read the manufacturer and device id codes of the flash device through
|
||||
|
@ -223,7 +223,7 @@ static int DoC_IdentChip(struct DiskOnChip *doc, int floor, int chip)
|
|||
for (j = 0; nand_manuf_ids[j].id != 0x0; j++) {
|
||||
if (nand_manuf_ids[j].id == mfr)
|
||||
break;
|
||||
}
|
||||
}
|
||||
printk(KERN_INFO "Flash chip found: Manufacturer ID: %2.2X, "
|
||||
"Chip ID: %2.2X (%s:%s)\n",
|
||||
mfr, id, nand_manuf_ids[j].name, nand_flash_ids[i].name);
|
||||
|
@ -275,7 +275,7 @@ static void DoC_ScanChips(struct DiskOnChip *this)
|
|||
return;
|
||||
}
|
||||
|
||||
/* Fill out the chip array with {floor, chipno} for each
|
||||
/* Fill out the chip array with {floor, chipno} for each
|
||||
* detected chip in the device. */
|
||||
for (floor = 0, ret = 0; floor < MAX_FLOORS_MIL; floor++) {
|
||||
for (chip = 0 ; chip < numchips[floor] ; chip++) {
|
||||
|
@ -309,7 +309,7 @@ static int DoCMil_is_alias(struct DiskOnChip *doc1, struct DiskOnChip *doc2)
|
|||
tmp2 = ReadDOC(doc2->virtadr, AliasResolution);
|
||||
if (tmp1 != tmp2)
|
||||
return 0;
|
||||
|
||||
|
||||
WriteDOC((tmp1+1) % 0xff, doc1->virtadr, AliasResolution);
|
||||
tmp2 = ReadDOC(doc2->virtadr, AliasResolution);
|
||||
if (tmp2 == (tmp1+1) % 0xff)
|
||||
|
@ -425,7 +425,7 @@ static int doc_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
|
|||
return -EINVAL;
|
||||
|
||||
/* Don't allow a single read to cross a 512-byte block boundary */
|
||||
if (from + len > ((from | 0x1ff) + 1))
|
||||
if (from + len > ((from | 0x1ff) + 1))
|
||||
len = ((from | 0x1ff) + 1) - from;
|
||||
|
||||
/* Find the chip which is to be used and select it */
|
||||
|
@ -552,7 +552,7 @@ static int doc_write_ecc (struct mtd_info *mtd, loff_t to, size_t len,
|
|||
|
||||
#if 0
|
||||
/* Don't allow a single write to cross a 512-byte block boundary */
|
||||
if (to + len > ( (to | 0x1ff) + 1))
|
||||
if (to + len > ( (to | 0x1ff) + 1))
|
||||
len = ((to | 0x1ff) + 1) - to;
|
||||
#else
|
||||
/* Don't allow writes which aren't exactly one block */
|
||||
|
@ -632,7 +632,7 @@ static int doc_write_ecc (struct mtd_info *mtd, loff_t to, size_t len,
|
|||
|
||||
/* write the block status BLOCK_USED (0x5555) at the end of ECC data
|
||||
FIXME: this is only a hack for programming the IPL area for LinuxBIOS
|
||||
and should be replace with proper codes in user space utilities */
|
||||
and should be replace with proper codes in user space utilities */
|
||||
WriteDOC(0x55, docptr, Mil_CDSN_IO);
|
||||
WriteDOC(0x55, docptr, Mil_CDSN_IO + 1);
|
||||
|
||||
|
@ -802,7 +802,7 @@ int doc_erase (struct mtd_info *mtd, struct erase_info *instr)
|
|||
void __iomem *docptr = this->virtadr;
|
||||
struct Nand *mychip = &this->chips[ofs >> this->chipshift];
|
||||
|
||||
if (len != mtd->erasesize)
|
||||
if (len != mtd->erasesize)
|
||||
printk(KERN_WARNING "Erase not right size (%x != %x)n",
|
||||
len, mtd->erasesize);
|
||||
|
||||
|
@ -870,9 +870,9 @@ static void __exit cleanup_doc2001(void)
|
|||
while ((mtd=docmillist)) {
|
||||
this = mtd->priv;
|
||||
docmillist = this->nextdoc;
|
||||
|
||||
|
||||
del_mtd_device(mtd);
|
||||
|
||||
|
||||
iounmap(this->virtadr);
|
||||
kfree(this->chips);
|
||||
kfree(mtd);
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
* (c) 1999 Machine Vision Holdings, Inc.
|
||||
* (c) 1999, 2000 David Woodhouse <dwmw2@infradead.org>
|
||||
*
|
||||
* $Id: doc2001plus.c,v 1.13 2005/01/05 18:05:12 dwmw2 Exp $
|
||||
* $Id: doc2001plus.c,v 1.14 2005/11/07 11:14:24 gleixner Exp $
|
||||
*
|
||||
* Released under GPL
|
||||
*/
|
||||
|
@ -293,10 +293,10 @@ static int DoC_IdentChip(struct DiskOnChip *doc, int floor, int chip)
|
|||
DoC_Command(docptr, NAND_CMD_RESET, 0);
|
||||
DoC_WaitReady(docptr);
|
||||
|
||||
/* Read the NAND chip ID: 1. Send ReadID command */
|
||||
/* Read the NAND chip ID: 1. Send ReadID command */
|
||||
DoC_Command(docptr, NAND_CMD_READID, 0);
|
||||
|
||||
/* Read the NAND chip ID: 2. Send address byte zero */
|
||||
/* Read the NAND chip ID: 2. Send address byte zero */
|
||||
DoC_Address(doc, 1, 0x00, 0, 0x00);
|
||||
|
||||
WriteDOC(0, docptr, Mplus_FlashControl);
|
||||
|
@ -365,7 +365,7 @@ static void DoC_ScanChips(struct DiskOnChip *this)
|
|||
this->interleave = 1;
|
||||
|
||||
/* Check the ASIC agrees */
|
||||
if ( (this->interleave << 2) !=
|
||||
if ( (this->interleave << 2) !=
|
||||
(ReadDOC(this->virtadr, Mplus_Configuration) & 4)) {
|
||||
u_char conf = ReadDOC(this->virtadr, Mplus_Configuration);
|
||||
printk(KERN_NOTICE "Setting DiskOnChip Millennium Plus interleave to %s\n",
|
||||
|
@ -398,7 +398,7 @@ static void DoC_ScanChips(struct DiskOnChip *this)
|
|||
return;
|
||||
}
|
||||
|
||||
/* Fill out the chip array with {floor, chipno} for each
|
||||
/* Fill out the chip array with {floor, chipno} for each
|
||||
* detected chip in the device. */
|
||||
for (floor = 0, ret = 0; floor < MAX_FLOORS_MPLUS; floor++) {
|
||||
for (chip = 0 ; chip < numchips[floor] ; chip++) {
|
||||
|
@ -432,7 +432,7 @@ static int DoCMilPlus_is_alias(struct DiskOnChip *doc1, struct DiskOnChip *doc2)
|
|||
tmp2 = ReadDOC(doc2->virtadr, Mplus_AliasResolution);
|
||||
if (tmp1 != tmp2)
|
||||
return 0;
|
||||
|
||||
|
||||
WriteDOC((tmp1+1) % 0xff, doc1->virtadr, Mplus_AliasResolution);
|
||||
tmp2 = ReadDOC(doc2->virtadr, Mplus_AliasResolution);
|
||||
if (tmp2 == (tmp1+1) % 0xff)
|
||||
|
@ -624,7 +624,7 @@ static int doc_read_ecc(struct mtd_info *mtd, loff_t from, size_t len,
|
|||
return -EINVAL;
|
||||
|
||||
/* Don't allow a single read to cross a 512-byte block boundary */
|
||||
if (from + len > ((from | 0x1ff) + 1))
|
||||
if (from + len > ((from | 0x1ff) + 1))
|
||||
len = ((from | 0x1ff) + 1) - from;
|
||||
|
||||
DoC_CheckASIC(docptr);
|
||||
|
@ -1066,7 +1066,7 @@ int doc_erase(struct mtd_info *mtd, struct erase_info *instr)
|
|||
|
||||
DoC_CheckASIC(docptr);
|
||||
|
||||
if (len != mtd->erasesize)
|
||||
if (len != mtd->erasesize)
|
||||
printk(KERN_WARNING "MTD: Erase not right size (%x != %x)n",
|
||||
len, mtd->erasesize);
|
||||
|
||||
|
@ -1136,9 +1136,9 @@ static void __exit cleanup_doc2001plus(void)
|
|||
while ((mtd=docmilpluslist)) {
|
||||
this = mtd->priv;
|
||||
docmilpluslist = this->nextdoc;
|
||||
|
||||
|
||||
del_mtd_device(mtd);
|
||||
|
||||
|
||||
iounmap(this->virtadr);
|
||||
kfree(this->chips);
|
||||
kfree(mtd);
|
||||
|
|
|
@ -4,10 +4,10 @@
|
|||
* GNU GPL License. The rest is simply to convert the disk on chip
|
||||
* syndrom into a standard syndom.
|
||||
*
|
||||
* Author: Fabrice Bellard (fabrice.bellard@netgem.com)
|
||||
* Author: Fabrice Bellard (fabrice.bellard@netgem.com)
|
||||
* Copyright (C) 2000 Netgem S.A.
|
||||
*
|
||||
* $Id: docecc.c,v 1.5 2003/05/21 15:15:06 dwmw2 Exp $
|
||||
* $Id: docecc.c,v 1.7 2005/11/07 11:14:25 gleixner Exp $
|
||||
*
|
||||
* 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
|
||||
|
@ -122,7 +122,7 @@ for(ci=(n)-1;ci >=0;ci--)\
|
|||
a(0) + a(1) @ + a(2) @^2 + ... + a(m-1) @^(m-1)
|
||||
we consider the integer "i" whose binary representation with a(0) being LSB
|
||||
and a(m-1) MSB is (a(0),a(1),...,a(m-1)) and locate the entry
|
||||
"index_of[i]". Now, @^index_of[i] is that element whose polynomial
|
||||
"index_of[i]". Now, @^index_of[i] is that element whose polynomial
|
||||
representation is (a(0),a(1),a(2),...,a(m-1)).
|
||||
NOTE:
|
||||
The element alpha_to[2^m-1] = 0 always signifying that the
|
||||
|
@ -130,7 +130,7 @@ for(ci=(n)-1;ci >=0;ci--)\
|
|||
Similarily, the element index_of[0] = A0 always signifying
|
||||
that the power of alpha which has the polynomial representation
|
||||
(0,0,...,0) is "infinity".
|
||||
|
||||
|
||||
*/
|
||||
|
||||
static void
|
||||
|
@ -176,7 +176,7 @@ generate_gf(dtype Alpha_to[NN + 1], dtype Index_of[NN + 1])
|
|||
* are written back. NOTE! This array must be at least NN-KK elements long.
|
||||
* The corrected data are written in eras_val[]. They must be xor with the data
|
||||
* to retrieve the correct data : data[erase_pos[i]] ^= erase_val[i] .
|
||||
*
|
||||
*
|
||||
* First "no_eras" erasures are declared by the calling program. Then, the
|
||||
* maximum # of errors correctable is t_after_eras = floor((NN-KK-no_eras)/2).
|
||||
* If the number of channel errors is not greater than "t_after_eras" the
|
||||
|
@ -189,7 +189,7 @@ generate_gf(dtype Alpha_to[NN + 1], dtype Index_of[NN + 1])
|
|||
* */
|
||||
static int
|
||||
eras_dec_rs(dtype Alpha_to[NN + 1], dtype Index_of[NN + 1],
|
||||
gf bb[NN - KK + 1], gf eras_val[NN-KK], int eras_pos[NN-KK],
|
||||
gf bb[NN - KK + 1], gf eras_val[NN-KK], int eras_pos[NN-KK],
|
||||
int no_eras)
|
||||
{
|
||||
int deg_lambda, el, deg_omega;
|
||||
|
@ -212,7 +212,7 @@ eras_dec_rs(dtype Alpha_to[NN + 1], dtype Index_of[NN + 1],
|
|||
count = 0;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
|
||||
for(i=1;i<=NN-KK;i++){
|
||||
s[i] = bb[0];
|
||||
}
|
||||
|
@ -220,7 +220,7 @@ eras_dec_rs(dtype Alpha_to[NN + 1], dtype Index_of[NN + 1],
|
|||
if(bb[j] == 0)
|
||||
continue;
|
||||
tmp = Index_of[bb[j]];
|
||||
|
||||
|
||||
for(i=1;i<=NN-KK;i++)
|
||||
s[i] ^= Alpha_to[modnn(tmp + (B0+i-1)*PRIM*j)];
|
||||
}
|
||||
|
@ -234,7 +234,7 @@ eras_dec_rs(dtype Alpha_to[NN + 1], dtype Index_of[NN + 1],
|
|||
tmp = modnn(tmp + 2 * KK * (B0+i-1)*PRIM);
|
||||
s[i] = tmp;
|
||||
}
|
||||
|
||||
|
||||
CLEAR(&lambda[1],NN-KK);
|
||||
lambda[0] = 1;
|
||||
|
||||
|
@ -252,7 +252,7 @@ eras_dec_rs(dtype Alpha_to[NN + 1], dtype Index_of[NN + 1],
|
|||
#if DEBUG_ECC >= 1
|
||||
/* Test code that verifies the erasure locator polynomial just constructed
|
||||
Needed only for decoder debugging. */
|
||||
|
||||
|
||||
/* find roots of the erasure location polynomial */
|
||||
for(i=1;i<=no_eras;i++)
|
||||
reg[i] = Index_of[lambda[i]];
|
||||
|
@ -286,7 +286,7 @@ eras_dec_rs(dtype Alpha_to[NN + 1], dtype Index_of[NN + 1],
|
|||
}
|
||||
for(i=0;i<NN-KK+1;i++)
|
||||
b[i] = Index_of[lambda[i]];
|
||||
|
||||
|
||||
/*
|
||||
* Begin Berlekamp-Massey algorithm to determine error+erasure
|
||||
* locator polynomial
|
||||
|
@ -389,7 +389,7 @@ eras_dec_rs(dtype Alpha_to[NN + 1], dtype Index_of[NN + 1],
|
|||
omega[i] = Index_of[tmp];
|
||||
}
|
||||
omega[NN-KK] = A0;
|
||||
|
||||
|
||||
/*
|
||||
* Compute error values in poly-form. num1 = omega(inv(X(l))), num2 =
|
||||
* inv(X(l))**(B0-1) and den = lambda_pr(inv(X(l))) all in poly-form
|
||||
|
@ -402,7 +402,7 @@ eras_dec_rs(dtype Alpha_to[NN + 1], dtype Index_of[NN + 1],
|
|||
}
|
||||
num2 = Alpha_to[modnn(root[j] * (B0 - 1) + NN)];
|
||||
den = 0;
|
||||
|
||||
|
||||
/* lambda[i+1] for i even is the formal derivative lambda_pr of lambda[i] */
|
||||
for (i = min(deg_lambda,NN-KK-1) & ~1; i >= 0; i -=2) {
|
||||
if(lambda[i+1] != A0)
|
||||
|
@ -436,11 +436,11 @@ eras_dec_rs(dtype Alpha_to[NN + 1], dtype Index_of[NN + 1],
|
|||
/* The sector bytes are packed into NB_DATA MM bits words */
|
||||
#define NB_DATA (((SECTOR_SIZE + 1) * 8 + 6) / MM)
|
||||
|
||||
/*
|
||||
/*
|
||||
* Correct the errors in 'sector[]' by using 'ecc1[]' which is the
|
||||
* content of the feedback shift register applyied to the sector and
|
||||
* the ECC. Return the number of errors corrected (and correct them in
|
||||
* sector), or -1 if error
|
||||
* sector), or -1 if error
|
||||
*/
|
||||
int doc_decode_ecc(unsigned char sector[SECTOR_SIZE], unsigned char ecc1[6])
|
||||
{
|
||||
|
@ -454,7 +454,7 @@ int doc_decode_ecc(unsigned char sector[SECTOR_SIZE], unsigned char ecc1[6])
|
|||
Alpha_to = kmalloc((NN + 1) * sizeof(dtype), GFP_KERNEL);
|
||||
if (!Alpha_to)
|
||||
return -1;
|
||||
|
||||
|
||||
Index_of = kmalloc((NN + 1) * sizeof(dtype), GFP_KERNEL);
|
||||
if (!Index_of) {
|
||||
kfree(Alpha_to);
|
||||
|
@ -470,7 +470,7 @@ int doc_decode_ecc(unsigned char sector[SECTOR_SIZE], unsigned char ecc1[6])
|
|||
bb[2] = ((ecc1[2] & 0xf0) >> 4) | ((ecc1[3] & 0x3f) << 4);
|
||||
bb[3] = ((ecc1[3] & 0xc0) >> 6) | ((ecc1[0] & 0xff) << 2);
|
||||
|
||||
nb_errors = eras_dec_rs(Alpha_to, Index_of, bb,
|
||||
nb_errors = eras_dec_rs(Alpha_to, Index_of, bb,
|
||||
error_val, error_pos, 0);
|
||||
if (nb_errors <= 0)
|
||||
goto the_end;
|
||||
|
@ -489,7 +489,7 @@ int doc_decode_ecc(unsigned char sector[SECTOR_SIZE], unsigned char ecc1[6])
|
|||
can be modified since pos is even */
|
||||
index = (pos >> 3) ^ 1;
|
||||
bitpos = pos & 7;
|
||||
if ((index >= 0 && index < SECTOR_SIZE) ||
|
||||
if ((index >= 0 && index < SECTOR_SIZE) ||
|
||||
index == (SECTOR_SIZE + 1)) {
|
||||
val = error_val[i] >> (2 + bitpos);
|
||||
parity ^= val;
|
||||
|
@ -500,7 +500,7 @@ int doc_decode_ecc(unsigned char sector[SECTOR_SIZE], unsigned char ecc1[6])
|
|||
bitpos = (bitpos + 10) & 7;
|
||||
if (bitpos == 0)
|
||||
bitpos = 8;
|
||||
if ((index >= 0 && index < SECTOR_SIZE) ||
|
||||
if ((index >= 0 && index < SECTOR_SIZE) ||
|
||||
index == (SECTOR_SIZE + 1)) {
|
||||
val = error_val[i] << (8 - bitpos);
|
||||
parity ^= val;
|
||||
|
@ -509,7 +509,7 @@ int doc_decode_ecc(unsigned char sector[SECTOR_SIZE], unsigned char ecc1[6])
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* use parity to test extra errors */
|
||||
if ((parity & 0xff) != 0)
|
||||
nb_errors = -1;
|
||||
|
|
|
@ -4,22 +4,22 @@
|
|||
/* (C) 1999 Machine Vision Holdings, Inc. */
|
||||
/* (C) 1999-2003 David Woodhouse <dwmw2@infradead.org> */
|
||||
|
||||
/* $Id: docprobe.c,v 1.44 2005/01/05 12:40:36 dwmw2 Exp $ */
|
||||
/* $Id: docprobe.c,v 1.46 2005/11/07 11:14:25 gleixner Exp $ */
|
||||
|
||||
|
||||
|
||||
/* DOC_PASSIVE_PROBE:
|
||||
In order to ensure that the BIOS checksum is correct at boot time, and
|
||||
hence that the onboard BIOS extension gets executed, the DiskOnChip
|
||||
goes into reset mode when it is read sequentially: all registers
|
||||
return 0xff until the chip is woken up again by writing to the
|
||||
DOCControl register.
|
||||
In order to ensure that the BIOS checksum is correct at boot time, and
|
||||
hence that the onboard BIOS extension gets executed, the DiskOnChip
|
||||
goes into reset mode when it is read sequentially: all registers
|
||||
return 0xff until the chip is woken up again by writing to the
|
||||
DOCControl register.
|
||||
|
||||
Unfortunately, this means that the probe for the DiskOnChip is unsafe,
|
||||
because one of the first things it does is write to where it thinks
|
||||
the DOCControl register should be - which may well be shared memory
|
||||
for another device. I've had machines which lock up when this is
|
||||
attempted. Hence the possibility to do a passive probe, which will fail
|
||||
Unfortunately, this means that the probe for the DiskOnChip is unsafe,
|
||||
because one of the first things it does is write to where it thinks
|
||||
the DOCControl register should be - which may well be shared memory
|
||||
for another device. I've had machines which lock up when this is
|
||||
attempted. Hence the possibility to do a passive probe, which will fail
|
||||
to detect a chip in reset mode, but is at least guaranteed not to lock
|
||||
the machine.
|
||||
|
||||
|
@ -33,9 +33,9 @@
|
|||
|
||||
The old Millennium-only driver has been retained just in case there
|
||||
are problems with the new code. If the combined driver doesn't work
|
||||
for you, you can try the old one by undefining DOC_SINGLE_DRIVER
|
||||
for you, you can try the old one by undefining DOC_SINGLE_DRIVER
|
||||
below and also enabling it in your configuration. If this fixes the
|
||||
problems, please send a report to the MTD mailing list at
|
||||
problems, please send a report to the MTD mailing list at
|
||||
<linux-mtd@lists.infradead.org>.
|
||||
*/
|
||||
#define DOC_SINGLE_DRIVER
|
||||
|
@ -68,16 +68,16 @@ MODULE_PARM_DESC(doc_config_location, "Physical memory address at which to probe
|
|||
static unsigned long __initdata doc_locations[] = {
|
||||
#if defined (__alpha__) || defined(__i386__) || defined(__x86_64__)
|
||||
#ifdef CONFIG_MTD_DOCPROBE_HIGH
|
||||
0xfffc8000, 0xfffca000, 0xfffcc000, 0xfffce000,
|
||||
0xfffc8000, 0xfffca000, 0xfffcc000, 0xfffce000,
|
||||
0xfffd0000, 0xfffd2000, 0xfffd4000, 0xfffd6000,
|
||||
0xfffd8000, 0xfffda000, 0xfffdc000, 0xfffde000,
|
||||
0xfffe0000, 0xfffe2000, 0xfffe4000, 0xfffe6000,
|
||||
0xfffd8000, 0xfffda000, 0xfffdc000, 0xfffde000,
|
||||
0xfffe0000, 0xfffe2000, 0xfffe4000, 0xfffe6000,
|
||||
0xfffe8000, 0xfffea000, 0xfffec000, 0xfffee000,
|
||||
#else /* CONFIG_MTD_DOCPROBE_HIGH */
|
||||
0xc8000, 0xca000, 0xcc000, 0xce000,
|
||||
0xc8000, 0xca000, 0xcc000, 0xce000,
|
||||
0xd0000, 0xd2000, 0xd4000, 0xd6000,
|
||||
0xd8000, 0xda000, 0xdc000, 0xde000,
|
||||
0xe0000, 0xe2000, 0xe4000, 0xe6000,
|
||||
0xd8000, 0xda000, 0xdc000, 0xde000,
|
||||
0xe0000, 0xe2000, 0xe4000, 0xe6000,
|
||||
0xe8000, 0xea000, 0xec000, 0xee000,
|
||||
#endif /* CONFIG_MTD_DOCPROBE_HIGH */
|
||||
#elif defined(__PPC__)
|
||||
|
@ -111,35 +111,35 @@ static inline int __init doccheck(void __iomem *potential, unsigned long physadr
|
|||
return 0;
|
||||
#endif /* CONFIG_MTD_DOCPROBE_55AA */
|
||||
|
||||
#ifndef DOC_PASSIVE_PROBE
|
||||
#ifndef DOC_PASSIVE_PROBE
|
||||
/* It's not possible to cleanly detect the DiskOnChip - the
|
||||
* bootup procedure will put the device into reset mode, and
|
||||
* it's not possible to talk to it without actually writing
|
||||
* to the DOCControl register. So we store the current contents
|
||||
* of the DOCControl register's location, in case we later decide
|
||||
* that it's not a DiskOnChip, and want to put it back how we
|
||||
* found it.
|
||||
* found it.
|
||||
*/
|
||||
tmp2 = ReadDOC(window, DOCControl);
|
||||
|
||||
|
||||
/* Reset the DiskOnChip ASIC */
|
||||
WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_RESET,
|
||||
WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_RESET,
|
||||
window, DOCControl);
|
||||
WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_RESET,
|
||||
WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_RESET,
|
||||
window, DOCControl);
|
||||
|
||||
|
||||
/* Enable the DiskOnChip ASIC */
|
||||
WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_NORMAL,
|
||||
WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_NORMAL,
|
||||
window, DOCControl);
|
||||
WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_NORMAL,
|
||||
WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_NORMAL,
|
||||
window, DOCControl);
|
||||
#endif /* !DOC_PASSIVE_PROBE */
|
||||
#endif /* !DOC_PASSIVE_PROBE */
|
||||
|
||||
/* We need to read the ChipID register four times. For some
|
||||
newer DiskOnChip 2000 units, the first three reads will
|
||||
return the DiskOnChip Millennium ident. Don't ask. */
|
||||
ChipID = ReadDOC(window, ChipID);
|
||||
|
||||
|
||||
switch (ChipID) {
|
||||
case DOC_ChipID_Doc2k:
|
||||
/* Check the TOGGLE bit in the ECC register */
|
||||
|
@ -149,7 +149,7 @@ static inline int __init doccheck(void __iomem *potential, unsigned long physadr
|
|||
if (tmp != tmpb && tmp == tmpc)
|
||||
return ChipID;
|
||||
break;
|
||||
|
||||
|
||||
case DOC_ChipID_DocMil:
|
||||
/* Check for the new 2000 with Millennium ASIC */
|
||||
ReadDOC(window, ChipID);
|
||||
|
@ -164,7 +164,7 @@ static inline int __init doccheck(void __iomem *potential, unsigned long physadr
|
|||
if (tmp != tmpb && tmp == tmpc)
|
||||
return ChipID;
|
||||
break;
|
||||
|
||||
|
||||
case DOC_ChipID_DocMilPlus16:
|
||||
case DOC_ChipID_DocMilPlus32:
|
||||
case 0:
|
||||
|
@ -179,7 +179,7 @@ static inline int __init doccheck(void __iomem *potential, unsigned long physadr
|
|||
DOC_MODE_BDECT;
|
||||
WriteDOC(tmp, window, Mplus_DOCControl);
|
||||
WriteDOC(~tmp, window, Mplus_CtrlConfirm);
|
||||
|
||||
|
||||
mdelay(1);
|
||||
/* Enable the DiskOnChip ASIC */
|
||||
tmp = DOC_MODE_NORMAL | DOC_MODE_MDWREN | DOC_MODE_RST_LAT |
|
||||
|
@ -187,7 +187,7 @@ static inline int __init doccheck(void __iomem *potential, unsigned long physadr
|
|||
WriteDOC(tmp, window, Mplus_DOCControl);
|
||||
WriteDOC(~tmp, window, Mplus_CtrlConfirm);
|
||||
mdelay(1);
|
||||
#endif /* !DOC_PASSIVE_PROBE */
|
||||
#endif /* !DOC_PASSIVE_PROBE */
|
||||
|
||||
ChipID = ReadDOC(window, ChipID);
|
||||
|
||||
|
@ -227,7 +227,7 @@ static inline int __init doccheck(void __iomem *potential, unsigned long physadr
|
|||
WriteDOC(tmp2, window, DOCControl);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static int docfound;
|
||||
|
||||
|
@ -244,10 +244,10 @@ static void __init DoC_Probe(unsigned long physadr)
|
|||
void (*initroutine)(struct mtd_info *) = NULL;
|
||||
|
||||
docptr = ioremap(physadr, DOC_IOREMAP_LEN);
|
||||
|
||||
|
||||
if (!docptr)
|
||||
return;
|
||||
|
||||
|
||||
if ((ChipID = doccheck(docptr, physadr))) {
|
||||
if (ChipID == DOC_ChipID_Doc2kTSOP) {
|
||||
/* Remove this at your own peril. The hardware driver works but nothing prevents you from erasing bad blocks */
|
||||
|
@ -263,9 +263,9 @@ static void __init DoC_Probe(unsigned long physadr)
|
|||
iounmap(docptr);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
this = (struct DiskOnChip *)(&mtd[1]);
|
||||
|
||||
|
||||
memset((char *)mtd,0, sizeof(struct mtd_info));
|
||||
memset((char *)this, 0, sizeof(struct DiskOnChip));
|
||||
|
||||
|
@ -281,13 +281,13 @@ static void __init DoC_Probe(unsigned long physadr)
|
|||
im_funcname = "DoC2k_init";
|
||||
im_modname = "doc2000";
|
||||
break;
|
||||
|
||||
|
||||
case DOC_ChipID_Doc2k:
|
||||
name="2000";
|
||||
im_funcname = "DoC2k_init";
|
||||
im_modname = "doc2000";
|
||||
break;
|
||||
|
||||
|
||||
case DOC_ChipID_DocMil:
|
||||
name="Millennium";
|
||||
#ifdef DOC_SINGLE_DRIVER
|
||||
|
@ -331,7 +331,7 @@ static void __init DoC_Probe(unsigned long physadr)
|
|||
static int __init init_doc(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
||||
if (doc_config_location) {
|
||||
printk(KERN_INFO "Using configured DiskOnChip probe address 0x%lx\n", doc_config_location);
|
||||
DoC_Probe(doc_config_location);
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
/*
|
||||
* MTD driver for the 28F160F3 Flash Memory (non-CFI) on LART.
|
||||
*
|
||||
* $Id: lart.c,v 1.7 2004/08/09 13:19:44 dwmw2 Exp $
|
||||
* $Id: lart.c,v 1.9 2005/11/07 11:14:25 gleixner Exp $
|
||||
*
|
||||
* Author: Abraham vd Merwe <abraham@2d3d.co.za>
|
||||
*
|
||||
|
@ -122,7 +122,7 @@ static char module_name[] = "lart";
|
|||
|
||||
/*
|
||||
* The data line mapping on LART is as follows:
|
||||
*
|
||||
*
|
||||
* U2 CPU | U3 CPU
|
||||
* -------------------
|
||||
* 0 20 | 0 12
|
||||
|
@ -181,7 +181,7 @@ static char module_name[] = "lart";
|
|||
(((x) & 0x00004000) >> 13) \
|
||||
)
|
||||
|
||||
/*
|
||||
/*
|
||||
* The address line mapping on LART is as follows:
|
||||
*
|
||||
* U3 CPU | U2 CPU
|
||||
|
@ -204,7 +204,7 @@ static char module_name[] = "lart";
|
|||
* 12 15 | 12 15
|
||||
* 13 14 | 13 14
|
||||
* 14 16 | 14 16
|
||||
*
|
||||
*
|
||||
* MAIN BLOCK BOUNDARY
|
||||
*
|
||||
* 15 17 | 15 18
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* $Id: phram.c,v 1.14 2005/03/07 21:43:38 joern Exp $
|
||||
* $Id: phram.c,v 1.16 2005/11/07 11:14:25 gleixner Exp $
|
||||
*
|
||||
* Copyright (c) ???? Jochen Schäuble <psionic@psionic.de>
|
||||
* Copyright (c) 2003-2004 Jörn Engel <joern@wh.fh-wedel.de>
|
||||
|
@ -41,10 +41,10 @@ static int phram_erase(struct mtd_info *mtd, struct erase_info *instr)
|
|||
|
||||
if (instr->addr + instr->len > mtd->size)
|
||||
return -EINVAL;
|
||||
|
||||
|
||||
memset(start + instr->addr, 0xff, instr->len);
|
||||
|
||||
/* This'll catch a few races. Free the thing before returning :)
|
||||
/* This'll catch a few races. Free the thing before returning :)
|
||||
* I don't feel at all ashamed. This kind of thing is possible anyway
|
||||
* with flash, but unlikely.
|
||||
*/
|
||||
|
@ -63,7 +63,7 @@ static int phram_point(struct mtd_info *mtd, loff_t from, size_t len,
|
|||
|
||||
if (from + len > mtd->size)
|
||||
return -EINVAL;
|
||||
|
||||
|
||||
*mtdbuf = start + from;
|
||||
*retlen = len;
|
||||
return 0;
|
||||
|
@ -84,7 +84,7 @@ static int phram_read(struct mtd_info *mtd, loff_t from, size_t len,
|
|||
|
||||
if (len > mtd->size - from)
|
||||
len = mtd->size - from;
|
||||
|
||||
|
||||
memcpy(buf, start + from, len);
|
||||
|
||||
*retlen = len;
|
||||
|
@ -101,7 +101,7 @@ static int phram_write(struct mtd_info *mtd, loff_t to, size_t len,
|
|||
|
||||
if (len > mtd->size - to)
|
||||
len = mtd->size - to;
|
||||
|
||||
|
||||
memcpy(start + to, buf, len);
|
||||
|
||||
*retlen = len;
|
||||
|
@ -159,7 +159,7 @@ static int register_device(char *name, unsigned long start, unsigned long len)
|
|||
}
|
||||
|
||||
list_add_tail(&new->list, &phram_list);
|
||||
return 0;
|
||||
return 0;
|
||||
|
||||
out2:
|
||||
iounmap(new->mtd.priv);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* $Id: pmc551.c,v 1.30 2005/01/05 18:05:13 dwmw2 Exp $
|
||||
* $Id: pmc551.c,v 1.32 2005/11/07 11:14:25 gleixner Exp $
|
||||
*
|
||||
* PMC551 PCI Mezzanine Ram Device
|
||||
*
|
||||
|
@ -27,7 +27,7 @@
|
|||
* it as high speed swap or for a high speed disk device of some
|
||||
* sort. Which becomes very useful on diskless systems in the
|
||||
* embedded market I might add.
|
||||
*
|
||||
*
|
||||
* Notes:
|
||||
* Due to what I assume is more buggy SROM, the 64M PMC551 I
|
||||
* have available claims that all 4 of it's DRAM banks have 64M
|
||||
|
@ -63,10 +63,10 @@
|
|||
* Minyard set up the card to utilize a 1M sliding apature.
|
||||
*
|
||||
* Corey Minyard <minyard@nortelnetworks.com>
|
||||
* * Modified driver to utilize a sliding aperture instead of
|
||||
* * Modified driver to utilize a sliding aperture instead of
|
||||
* mapping all memory into kernel space which turned out to
|
||||
* be very wasteful.
|
||||
* * Located a bug in the SROM's initialization sequence that
|
||||
* * Located a bug in the SROM's initialization sequence that
|
||||
* made the memory unusable, added a fix to code to touch up
|
||||
* the DRAM some.
|
||||
*
|
||||
|
@ -390,7 +390,7 @@ static u32 fixup_pmc551 (struct pci_dev *dev)
|
|||
bcmd |= (0x40|0x20);
|
||||
pci_write_config_byte(dev, PMC551_SYS_CTRL_REG, bcmd);
|
||||
|
||||
/*
|
||||
/*
|
||||
* Take care and turn off the memory on the device while we
|
||||
* tweak the configurations
|
||||
*/
|
||||
|
@ -408,7 +408,7 @@ static u32 fixup_pmc551 (struct pci_dev *dev)
|
|||
* Grab old BAR0 config so that we can figure out memory size
|
||||
* This is another bit of kludge going on. The reason for the
|
||||
* redundancy is I am hoping to retain the original configuration
|
||||
* previously assigned to the card by the BIOS or some previous
|
||||
* previously assigned to the card by the BIOS or some previous
|
||||
* fixup routine in the kernel. So we read the old config into cfg,
|
||||
* then write all 1's to the memory space, read back the result into
|
||||
* "size", and then write back all the old config.
|
||||
|
@ -480,7 +480,7 @@ static u32 fixup_pmc551 (struct pci_dev *dev)
|
|||
} while ( (PCI_COMMAND_IO) & cmd );
|
||||
|
||||
/*
|
||||
* Turn on auto refresh
|
||||
* Turn on auto refresh
|
||||
* The loop is taken directly from Ramix's example code. I assume that
|
||||
* this must be held high for some duration of time, but I can find no
|
||||
* documentation refrencing the reasons why.
|
||||
|
@ -615,7 +615,7 @@ static u32 fixup_pmc551 (struct pci_dev *dev)
|
|||
pci_read_config_byte(dev, PMC551_SYS_CTRL_REG, &bcmd );
|
||||
printk( KERN_DEBUG "pmc551: EEPROM is under %s control\n"
|
||||
"pmc551: System Control Register is %slocked to PCI access\n"
|
||||
"pmc551: System Control Register is %slocked to EEPROM access\n",
|
||||
"pmc551: System Control Register is %slocked to EEPROM access\n",
|
||||
(bcmd&0x1)?"software":"hardware",
|
||||
(bcmd&0x20)?"":"un", (bcmd&0x40)?"":"un");
|
||||
#endif
|
||||
|
@ -744,7 +744,7 @@ static int __init init_pmc551(void)
|
|||
priv->start = ioremap(((PCI_Device->resource[0].start)
|
||||
& PCI_BASE_ADDRESS_MEM_MASK),
|
||||
priv->asize);
|
||||
|
||||
|
||||
if (!priv->start) {
|
||||
printk(KERN_NOTICE "pmc551: Unable to map IO space\n");
|
||||
kfree(mtd->priv);
|
||||
|
@ -765,7 +765,7 @@ static int __init init_pmc551(void)
|
|||
priv->curr_map0 );
|
||||
|
||||
#ifdef CONFIG_MTD_PMC551_DEBUG
|
||||
printk( KERN_DEBUG "pmc551: aperture set to %d\n",
|
||||
printk( KERN_DEBUG "pmc551: aperture set to %d\n",
|
||||
(priv->base_map0 & 0xF0)>>4 );
|
||||
#endif
|
||||
|
||||
|
@ -823,13 +823,13 @@ static void __exit cleanup_pmc551(void)
|
|||
while((mtd=pmc551list)) {
|
||||
priv = mtd->priv;
|
||||
pmc551list = priv->nextpmc551;
|
||||
|
||||
|
||||
if(priv->start) {
|
||||
printk (KERN_DEBUG "pmc551: unmapping %dM starting at 0x%p\n",
|
||||
priv->asize>>20, priv->start);
|
||||
iounmap (priv->start);
|
||||
}
|
||||
|
||||
|
||||
kfree (mtd->priv);
|
||||
del_mtd_device (mtd);
|
||||
kfree (mtd);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*======================================================================
|
||||
|
||||
$Id: slram.c,v 1.34 2005/01/06 21:16:42 jwboyer Exp $
|
||||
$Id: slram.c,v 1.36 2005/11/07 11:14:25 gleixner Exp $
|
||||
|
||||
This driver provides a method to access memory not used by the kernel
|
||||
itself (i.e. if the kernel commandline mem=xxx is used). To actually
|
||||
|
@ -18,14 +18,14 @@
|
|||
<start>: start of the memory region, decimal or hex (0xabcdef)
|
||||
<end/offset>: end of the memory region. It's possible to use +0x1234
|
||||
to specify the offset instead of the absolute address
|
||||
|
||||
|
||||
NOTE:
|
||||
With slram it's only possible to map a contigous memory region. Therfore
|
||||
if there's a device mapped somewhere in the region specified slram will
|
||||
fail to load (see kernel log if modprobe fails).
|
||||
|
||||
-
|
||||
|
||||
|
||||
Jochen Schaeuble <psionic@psionic.de>
|
||||
|
||||
======================================================================*/
|
||||
|
@ -89,10 +89,10 @@ static int slram_erase(struct mtd_info *mtd, struct erase_info *instr)
|
|||
if (instr->addr + instr->len > mtd->size) {
|
||||
return(-EINVAL);
|
||||
}
|
||||
|
||||
|
||||
memset(priv->start + instr->addr, 0xff, instr->len);
|
||||
|
||||
/* This'll catch a few races. Free the thing before returning :)
|
||||
/* This'll catch a few races. Free the thing before returning :)
|
||||
* I don't feel at all ashamed. This kind of thing is possible anyway
|
||||
* with flash, but unlikely.
|
||||
*/
|
||||
|
@ -170,12 +170,12 @@ static int register_device(char *name, unsigned long start, unsigned long length
|
|||
}
|
||||
(*curmtd)->mtdinfo = kmalloc(sizeof(struct mtd_info), GFP_KERNEL);
|
||||
(*curmtd)->next = NULL;
|
||||
|
||||
|
||||
if ((*curmtd)->mtdinfo) {
|
||||
memset((char *)(*curmtd)->mtdinfo, 0, sizeof(struct mtd_info));
|
||||
(*curmtd)->mtdinfo->priv =
|
||||
kmalloc(sizeof(slram_priv_t), GFP_KERNEL);
|
||||
|
||||
|
||||
if (!(*curmtd)->mtdinfo->priv) {
|
||||
kfree((*curmtd)->mtdinfo);
|
||||
(*curmtd)->mtdinfo = NULL;
|
||||
|
@ -188,7 +188,7 @@ static int register_device(char *name, unsigned long start, unsigned long length
|
|||
E("slram: Cannot allocate new MTD device.\n");
|
||||
return(-ENOMEM);
|
||||
}
|
||||
|
||||
|
||||
if (!(((slram_priv_t *)(*curmtd)->mtdinfo->priv)->start =
|
||||
ioremap(start, length))) {
|
||||
E("slram: ioremap failed\n");
|
||||
|
@ -223,7 +223,7 @@ static int register_device(char *name, unsigned long start, unsigned long length
|
|||
T("slram: Mapped from 0x%p to 0x%p\n",
|
||||
((slram_priv_t *)(*curmtd)->mtdinfo->priv)->start,
|
||||
((slram_priv_t *)(*curmtd)->mtdinfo->priv)->end);
|
||||
return(0);
|
||||
return(0);
|
||||
}
|
||||
|
||||
static void unregister_devices(void)
|
||||
|
@ -256,7 +256,7 @@ static int parse_cmdline(char *devname, char *szstart, char *szlength)
|
|||
char *buffer;
|
||||
unsigned long devstart;
|
||||
unsigned long devlength;
|
||||
|
||||
|
||||
if ((!devname) || (!szstart) || (!szlength)) {
|
||||
unregister_devices();
|
||||
return(-EINVAL);
|
||||
|
@ -264,7 +264,7 @@ static int parse_cmdline(char *devname, char *szstart, char *szlength)
|
|||
|
||||
devstart = simple_strtoul(szstart, &buffer, 0);
|
||||
devstart = handle_unit(devstart, buffer);
|
||||
|
||||
|
||||
if (*(szlength) != '+') {
|
||||
devlength = simple_strtoul(szlength, &buffer, 0);
|
||||
devlength = handle_unit(devlength, buffer) - devstart;
|
||||
|
@ -278,7 +278,7 @@ static int parse_cmdline(char *devname, char *szstart, char *szlength)
|
|||
E("slram: Illegal start / length parameter.\n");
|
||||
return(-EINVAL);
|
||||
}
|
||||
|
||||
|
||||
if ((devstart = register_device(devname, devstart, devlength))){
|
||||
unregister_devices();
|
||||
return((int)devstart);
|
||||
|
@ -335,7 +335,7 @@ static int init_slram(void)
|
|||
}
|
||||
#else
|
||||
int count;
|
||||
|
||||
|
||||
for (count = 0; (map[count]) && (count < SLRAM_MAX_DEVICES_PARAMS);
|
||||
count++) {
|
||||
}
|
||||
|
@ -350,10 +350,10 @@ static int init_slram(void)
|
|||
if (parse_cmdline(devname, map[i * 3 + 1], map[i * 3 + 2])!=0) {
|
||||
return(-EINVAL);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
#endif /* !MODULE */
|
||||
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* This version ported to the Linux-MTD system by dwmw2@infradead.org
|
||||
* $Id: ftl.c,v 1.55 2005/01/17 13:47:21 hvr Exp $
|
||||
* $Id: ftl.c,v 1.58 2005/11/07 11:14:19 gleixner Exp $
|
||||
*
|
||||
* Fixes: Arnaldo Carvalho de Melo <acme@conectiva.com.br>
|
||||
* - fixes some leaks on failure in build_maps and ftl_notify_add, cleanups
|
||||
|
@ -53,7 +53,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.
|
||||
|
||||
|
||||
======================================================================*/
|
||||
#include <linux/mtd/blktrans.h>
|
||||
#include <linux/module.h>
|
||||
|
@ -160,7 +160,7 @@ static void ftl_erase_callback(struct erase_info *done);
|
|||
Scan_header() checks to see if a memory region contains an FTL
|
||||
partition. build_maps() reads all the erase unit headers, builds
|
||||
the erase unit map, and then builds the virtual page map.
|
||||
|
||||
|
||||
======================================================================*/
|
||||
|
||||
static int scan_header(partition_t *part)
|
||||
|
@ -176,10 +176,10 @@ 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,
|
||||
err = part->mbd.mtd->read(part->mbd.mtd, offset, sizeof(header), &ret,
|
||||
(unsigned char *)&header);
|
||||
|
||||
if (err)
|
||||
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (strcmp(header.DataOrgTuple+3, "FTL100") == 0) break;
|
||||
|
@ -232,10 +232,10 @@ 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,
|
||||
ret = part->mbd.mtd->read(part->mbd.mtd, offset, sizeof(header), &retval,
|
||||
(unsigned char *)&header);
|
||||
|
||||
if (ret)
|
||||
|
||||
if (ret)
|
||||
goto out_XferInfo;
|
||||
|
||||
ret = -1;
|
||||
|
@ -274,7 +274,7 @@ static int build_maps(partition_t *part)
|
|||
"don't add up!\n");
|
||||
goto out_XferInfo;
|
||||
}
|
||||
|
||||
|
||||
/* Set up virtual page map */
|
||||
blocks = le32_to_cpu(header.FormattedSize) >> header.BlockSize;
|
||||
part->VirtualBlockMap = vmalloc(blocks * sizeof(u_int32_t));
|
||||
|
@ -296,12 +296,12 @@ static int build_maps(partition_t *part)
|
|||
part->EUNInfo[i].Free = 0;
|
||||
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(u_int32_t), &retval,
|
||||
|
||||
ret = part->mbd.mtd->read(part->mbd.mtd, offset,
|
||||
part->BlocksPerUnit * sizeof(u_int32_t), &retval,
|
||||
(unsigned char *)part->bam_cache);
|
||||
|
||||
if (ret)
|
||||
|
||||
if (ret)
|
||||
goto out_bam_cache;
|
||||
|
||||
for (j = 0; j < part->BlocksPerUnit; j++) {
|
||||
|
@ -316,7 +316,7 @@ static int build_maps(partition_t *part)
|
|||
part->EUNInfo[i].Deleted++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ret = 0;
|
||||
goto out;
|
||||
|
||||
|
@ -336,7 +336,7 @@ static int build_maps(partition_t *part)
|
|||
|
||||
Erase_xfer() schedules an asynchronous erase operation for a
|
||||
transfer unit.
|
||||
|
||||
|
||||
======================================================================*/
|
||||
|
||||
static int erase_xfer(partition_t *part,
|
||||
|
@ -351,10 +351,10 @@ static int erase_xfer(partition_t *part,
|
|||
xfer->state = XFER_ERASING;
|
||||
|
||||
/* Is there a free erase slot? Always in MTD. */
|
||||
|
||||
|
||||
|
||||
|
||||
erase=kmalloc(sizeof(struct erase_info), GFP_KERNEL);
|
||||
if (!erase)
|
||||
if (!erase)
|
||||
return -ENOMEM;
|
||||
|
||||
erase->mtd = part->mbd.mtd;
|
||||
|
@ -362,7 +362,7 @@ static int erase_xfer(partition_t *part,
|
|||
erase->addr = xfer->Offset;
|
||||
erase->len = 1 << part->header.EraseUnitSize;
|
||||
erase->priv = (u_long)part;
|
||||
|
||||
|
||||
ret = part->mbd.mtd->erase(part->mbd.mtd, erase);
|
||||
|
||||
if (!ret)
|
||||
|
@ -377,7 +377,7 @@ static int erase_xfer(partition_t *part,
|
|||
|
||||
Prepare_xfer() takes a freshly erased transfer unit and gives
|
||||
it an appropriate header.
|
||||
|
||||
|
||||
======================================================================*/
|
||||
|
||||
static void ftl_erase_callback(struct erase_info *erase)
|
||||
|
@ -385,7 +385,7 @@ static void ftl_erase_callback(struct erase_info *erase)
|
|||
partition_t *part;
|
||||
struct xfer_info_t *xfer;
|
||||
int i;
|
||||
|
||||
|
||||
/* Look up the transfer unit */
|
||||
part = (partition_t *)(erase->priv);
|
||||
|
||||
|
@ -422,7 +422,7 @@ static int prepare_xfer(partition_t *part, int i)
|
|||
|
||||
xfer = &part->XferInfo[i];
|
||||
xfer->state = XFER_FAILED;
|
||||
|
||||
|
||||
DEBUG(1, "ftl_cs: preparing xfer unit at 0x%x\n", xfer->Offset);
|
||||
|
||||
/* Write the transfer unit header */
|
||||
|
@ -446,7 +446,7 @@ static int prepare_xfer(partition_t *part, int i)
|
|||
|
||||
for (i = 0; i < nbam; i++, offset += sizeof(u_int32_t)) {
|
||||
|
||||
ret = part->mbd.mtd->write(part->mbd.mtd, offset, sizeof(u_int32_t),
|
||||
ret = part->mbd.mtd->write(part->mbd.mtd, offset, sizeof(u_int32_t),
|
||||
&retlen, (u_char *)&ctl);
|
||||
|
||||
if (ret)
|
||||
|
@ -454,7 +454,7 @@ static int prepare_xfer(partition_t *part, int i)
|
|||
}
|
||||
xfer->state = XFER_PREPARED;
|
||||
return 0;
|
||||
|
||||
|
||||
} /* prepare_xfer */
|
||||
|
||||
/*======================================================================
|
||||
|
@ -466,7 +466,7 @@ static int prepare_xfer(partition_t *part, int i)
|
|||
All data blocks are copied to the corresponding blocks in the
|
||||
target unit, so the virtual block map does not need to be
|
||||
updated.
|
||||
|
||||
|
||||
======================================================================*/
|
||||
|
||||
static int copy_erase_unit(partition_t *part, u_int16_t srcunit,
|
||||
|
@ -486,14 +486,14 @@ static int copy_erase_unit(partition_t *part, u_int16_t srcunit,
|
|||
xfer = &part->XferInfo[xferunit];
|
||||
DEBUG(2, "ftl_cs: copying block 0x%x to 0x%x\n",
|
||||
eun->Offset, xfer->Offset);
|
||||
|
||||
|
||||
|
||||
|
||||
/* Read current BAM */
|
||||
if (part->bam_index != srcunit) {
|
||||
|
||||
offset = eun->Offset + le32_to_cpu(part->header.BAMOffset);
|
||||
|
||||
ret = part->mbd.mtd->read(part->mbd.mtd, offset,
|
||||
ret = part->mbd.mtd->read(part->mbd.mtd, offset,
|
||||
part->BlocksPerUnit * sizeof(u_int32_t),
|
||||
&retlen, (u_char *) (part->bam_cache));
|
||||
|
||||
|
@ -501,11 +501,11 @@ static int copy_erase_unit(partition_t *part, u_int16_t srcunit,
|
|||
part->bam_index = 0xffff;
|
||||
|
||||
if (ret) {
|
||||
printk( KERN_WARNING "ftl: Failed to read BAM cache in copy_erase_unit()!\n");
|
||||
printk( KERN_WARNING "ftl: Failed to read BAM cache in copy_erase_unit()!\n");
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Write the LogicalEUN for the transfer unit */
|
||||
xfer->state = XFER_UNKNOWN;
|
||||
offset = xfer->Offset + 20; /* Bad! */
|
||||
|
@ -513,12 +513,12 @@ static int copy_erase_unit(partition_t *part, u_int16_t srcunit,
|
|||
|
||||
ret = part->mbd.mtd->write(part->mbd.mtd, offset, sizeof(u_int16_t),
|
||||
&retlen, (u_char *) &unit);
|
||||
|
||||
|
||||
if (ret) {
|
||||
printk( KERN_WARNING "ftl: Failed to write back to BAM cache in copy_erase_unit()!\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* Copy all data blocks from source unit to transfer unit */
|
||||
src = eun->Offset; dest = xfer->Offset;
|
||||
|
||||
|
@ -558,15 +558,15 @@ static int copy_erase_unit(partition_t *part, u_int16_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,
|
||||
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);
|
||||
if (ret) {
|
||||
printk( KERN_WARNING "ftl: Error writing BAM in copy_erase_unit\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* All clear? Then update the LogicalEUN again */
|
||||
ret = part->mbd.mtd->write(part->mbd.mtd, xfer->Offset + 20, sizeof(u_int16_t),
|
||||
&retlen, (u_char *)&srcunitswap);
|
||||
|
@ -574,9 +574,9 @@ static int copy_erase_unit(partition_t *part, u_int16_t srcunit,
|
|||
if (ret) {
|
||||
printk(KERN_WARNING "ftl: Error writing new LogicalEUN in copy_erase_unit\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* Update the maps and usage stats*/
|
||||
i = xfer->EraseCount;
|
||||
xfer->EraseCount = eun->EraseCount;
|
||||
|
@ -588,10 +588,10 @@ static int copy_erase_unit(partition_t *part, u_int16_t srcunit,
|
|||
part->FreeTotal += free;
|
||||
eun->Free = free;
|
||||
eun->Deleted = 0;
|
||||
|
||||
|
||||
/* Now, the cache should be valid for the new block */
|
||||
part->bam_index = srcunit;
|
||||
|
||||
|
||||
return 0;
|
||||
} /* copy_erase_unit */
|
||||
|
||||
|
@ -608,7 +608,7 @@ static int copy_erase_unit(partition_t *part, u_int16_t srcunit,
|
|||
oldest data unit instead. This means that we generally postpone
|
||||
the next reclaimation as long as possible, but shuffle static
|
||||
stuff around a bit for wear leveling.
|
||||
|
||||
|
||||
======================================================================*/
|
||||
|
||||
static int reclaim_block(partition_t *part)
|
||||
|
@ -666,7 +666,7 @@ static int reclaim_block(partition_t *part)
|
|||
else
|
||||
DEBUG(1, "ftl_cs: reclaim failed: no "
|
||||
"suitable transfer units!\n");
|
||||
|
||||
|
||||
return -EIO;
|
||||
}
|
||||
}
|
||||
|
@ -715,7 +715,7 @@ static int reclaim_block(partition_t *part)
|
|||
returns the block index -- the erase unit is just the currently
|
||||
cached unit. If there are no free blocks, it returns 0 -- this
|
||||
is never a valid data block because it contains the header.
|
||||
|
||||
|
||||
======================================================================*/
|
||||
|
||||
#ifdef PSYCHO_DEBUG
|
||||
|
@ -737,7 +737,7 @@ static u_int32_t find_free(partition_t *part)
|
|||
u_int32_t blk;
|
||||
size_t retlen;
|
||||
int ret;
|
||||
|
||||
|
||||
/* Find an erase unit with some free space */
|
||||
stop = (part->bam_index == 0xffff) ? 0 : part->bam_index;
|
||||
eun = stop;
|
||||
|
@ -749,17 +749,17 @@ static u_int32_t find_free(partition_t *part)
|
|||
|
||||
if (part->EUNInfo[eun].Free == 0)
|
||||
return 0;
|
||||
|
||||
|
||||
/* Is this unit's BAM cached? */
|
||||
if (eun != part->bam_index) {
|
||||
/* Invalidate cache */
|
||||
part->bam_index = 0xffff;
|
||||
|
||||
ret = part->mbd.mtd->read(part->mbd.mtd,
|
||||
ret = part->mbd.mtd->read(part->mbd.mtd,
|
||||
part->EUNInfo[eun].Offset + le32_to_cpu(part->header.BAMOffset),
|
||||
part->BlocksPerUnit * sizeof(u_int32_t),
|
||||
&retlen, (u_char *) (part->bam_cache));
|
||||
|
||||
|
||||
if (ret) {
|
||||
printk(KERN_WARNING"ftl: Error reading BAM in find_free\n");
|
||||
return 0;
|
||||
|
@ -781,14 +781,14 @@ static u_int32_t find_free(partition_t *part)
|
|||
}
|
||||
DEBUG(2, "ftl_cs: found free block at %d in %d\n", blk, eun);
|
||||
return blk;
|
||||
|
||||
|
||||
} /* find_free */
|
||||
|
||||
|
||||
/*======================================================================
|
||||
|
||||
Read a series of sectors from an FTL partition.
|
||||
|
||||
|
||||
======================================================================*/
|
||||
|
||||
static int ftl_read(partition_t *part, caddr_t buffer,
|
||||
|
@ -798,7 +798,7 @@ static int ftl_read(partition_t *part, caddr_t buffer,
|
|||
u_long i;
|
||||
int ret;
|
||||
size_t offset, retlen;
|
||||
|
||||
|
||||
DEBUG(2, "ftl_cs: ftl_read(0x%p, 0x%lx, %ld)\n",
|
||||
part, sector, nblocks);
|
||||
if (!(part->state & FTL_FORMATTED)) {
|
||||
|
@ -834,7 +834,7 @@ static int ftl_read(partition_t *part, caddr_t buffer,
|
|||
/*======================================================================
|
||||
|
||||
Write a series of sectors to an FTL partition
|
||||
|
||||
|
||||
======================================================================*/
|
||||
|
||||
static int set_bam_entry(partition_t *part, u_int32_t log_addr,
|
||||
|
@ -855,7 +855,7 @@ static int set_bam_entry(partition_t *part, u_int32_t log_addr,
|
|||
blk = (log_addr % bsize) / SECTOR_SIZE;
|
||||
offset = (part->EUNInfo[eun].Offset + blk * sizeof(u_int32_t) +
|
||||
le32_to_cpu(part->header.BAMOffset));
|
||||
|
||||
|
||||
#ifdef PSYCHO_DEBUG
|
||||
ret = part->mbd.mtd->read(part->mbd.mtd, offset, sizeof(u_int32_t),
|
||||
&retlen, (u_char *)&old_addr);
|
||||
|
@ -925,7 +925,7 @@ static int ftl_write(partition_t *part, caddr_t buffer,
|
|||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
bsize = 1 << part->header.EraseUnitSize;
|
||||
|
||||
virt_addr = sector * SECTOR_SIZE | BLOCK_DATA;
|
||||
|
@ -949,12 +949,12 @@ static int ftl_write(partition_t *part, caddr_t buffer,
|
|||
log_addr = part->bam_index * bsize + blk * SECTOR_SIZE;
|
||||
part->EUNInfo[part->bam_index].Free--;
|
||||
part->FreeTotal--;
|
||||
if (set_bam_entry(part, log_addr, 0xfffffffe))
|
||||
if (set_bam_entry(part, log_addr, 0xfffffffe))
|
||||
return -EIO;
|
||||
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,
|
||||
ret = part->mbd.mtd->write(part->mbd.mtd, offset, SECTOR_SIZE, &retlen,
|
||||
buffer);
|
||||
|
||||
if (ret) {
|
||||
|
@ -964,7 +964,7 @@ static int ftl_write(partition_t *part, caddr_t buffer,
|
|||
offset);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
|
||||
/* Only delete the old entry when the new entry is ready */
|
||||
old_addr = part->VirtualBlockMap[sector+i];
|
||||
if (old_addr != 0xffffffff) {
|
||||
|
@ -979,7 +979,7 @@ static int ftl_write(partition_t *part, caddr_t buffer,
|
|||
return -EIO;
|
||||
part->VirtualBlockMap[sector+i] = log_addr;
|
||||
part->EUNInfo[part->bam_index].Deleted--;
|
||||
|
||||
|
||||
buffer += SECTOR_SIZE;
|
||||
virt_addr += SECTOR_SIZE;
|
||||
}
|
||||
|
@ -1034,20 +1034,20 @@ static void ftl_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd)
|
|||
partition_t *partition;
|
||||
|
||||
partition = kmalloc(sizeof(partition_t), GFP_KERNEL);
|
||||
|
||||
|
||||
if (!partition) {
|
||||
printk(KERN_WARNING "No memory to scan for FTL on %s\n",
|
||||
mtd->name);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
memset(partition, 0, sizeof(partition_t));
|
||||
|
||||
partition->mbd.mtd = mtd;
|
||||
|
||||
if ((scan_header(partition) == 0) &&
|
||||
if ((scan_header(partition) == 0) &&
|
||||
(build_maps(partition) == 0)) {
|
||||
|
||||
|
||||
partition->state = FTL_FORMATTED;
|
||||
#ifdef PCMCIA_DEBUG
|
||||
printk(KERN_INFO "ftl_cs: opening %d KiB FTL partition\n",
|
||||
|
@ -1086,7 +1086,7 @@ struct mtd_blktrans_ops ftl_tr = {
|
|||
|
||||
int init_ftl(void)
|
||||
{
|
||||
DEBUG(0, "$Id: ftl.c,v 1.55 2005/01/17 13:47:21 hvr Exp $\n");
|
||||
DEBUG(0, "$Id: ftl.c,v 1.58 2005/11/07 11:14:19 gleixner Exp $\n");
|
||||
|
||||
return register_mtd_blktrans(&ftl_tr);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/*
|
||||
/*
|
||||
* inftlcore.c -- Linux driver for Inverse Flash Translation Layer (INFTL)
|
||||
*
|
||||
* (C) Copyright 2002, Greg Ungerer (gerg@snapgear.com)
|
||||
|
@ -7,7 +7,7 @@
|
|||
* (c) 1999 Machine Vision Holdings, Inc.
|
||||
* Author: David Woodhouse <dwmw2@infradead.org>
|
||||
*
|
||||
* $Id: inftlcore.c,v 1.18 2004/11/16 18:28:59 dwmw2 Exp $
|
||||
* $Id: inftlcore.c,v 1.19 2005/11/07 11:14:20 gleixner Exp $
|
||||
*
|
||||
* 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
|
||||
|
@ -113,14 +113,14 @@ static void inftl_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd)
|
|||
|
||||
if (inftl->mbd.size != inftl->heads * inftl->cylinders * inftl->sectors) {
|
||||
/*
|
||||
Oh no we don't have
|
||||
Oh no we don't have
|
||||
mbd.size == heads * cylinders * sectors
|
||||
*/
|
||||
printk(KERN_WARNING "INFTL: cannot calculate a geometry to "
|
||||
"match size of 0x%lx.\n", inftl->mbd.size);
|
||||
printk(KERN_WARNING "INFTL: using C:%d H:%d S:%d "
|
||||
"(== 0x%lx sects)\n",
|
||||
inftl->cylinders, inftl->heads , inftl->sectors,
|
||||
inftl->cylinders, inftl->heads , inftl->sectors,
|
||||
(long)inftl->cylinders * (long)inftl->heads *
|
||||
(long)inftl->sectors );
|
||||
}
|
||||
|
@ -219,7 +219,7 @@ static u16 INFTL_foldchain(struct INFTLrecord *inftl, unsigned thisVUC, unsigned
|
|||
"Virtual Unit Chain %d!\n", thisVUC);
|
||||
return BLOCK_NIL;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Scan to find the Erase Unit which holds the actual data for each
|
||||
* 512-byte block within the Chain.
|
||||
|
@ -260,7 +260,7 @@ static u16 INFTL_foldchain(struct INFTLrecord *inftl, unsigned thisVUC, unsigned
|
|||
"Unit Chain 0x%x\n", thisVUC);
|
||||
return BLOCK_NIL;
|
||||
}
|
||||
|
||||
|
||||
thisEUN = inftl->PUtable[thisEUN];
|
||||
}
|
||||
|
||||
|
@ -291,15 +291,15 @@ static u16 INFTL_foldchain(struct INFTLrecord *inftl, unsigned thisVUC, unsigned
|
|||
*/
|
||||
if (BlockMap[block] == BLOCK_NIL)
|
||||
continue;
|
||||
|
||||
|
||||
ret = MTD_READ(inftl->mbd.mtd, (inftl->EraseSize *
|
||||
BlockMap[block]) + (block * SECTORSIZE), SECTORSIZE,
|
||||
&retlen, movebuf);
|
||||
&retlen, movebuf);
|
||||
if (ret < 0) {
|
||||
ret = MTD_READ(inftl->mbd.mtd, (inftl->EraseSize *
|
||||
BlockMap[block]) + (block * SECTORSIZE),
|
||||
SECTORSIZE, &retlen, movebuf);
|
||||
if (ret != -EIO)
|
||||
if (ret != -EIO)
|
||||
DEBUG(MTD_DEBUG_LEVEL1, "INFTL: error went "
|
||||
"away on retry?\n");
|
||||
}
|
||||
|
@ -351,7 +351,7 @@ static u16 INFTL_foldchain(struct INFTLrecord *inftl, unsigned thisVUC, unsigned
|
|||
static u16 INFTL_makefreeblock(struct INFTLrecord *inftl, unsigned pendingblock)
|
||||
{
|
||||
/*
|
||||
* This is the part that needs some cleverness applied.
|
||||
* This is the part that needs some cleverness applied.
|
||||
* For now, I'm doing the minimum applicable to actually
|
||||
* get the thing to work.
|
||||
* Wear-levelling and other clever stuff needs to be implemented
|
||||
|
@ -410,7 +410,7 @@ static int nrbits(unsigned int val, int bitcount)
|
|||
}
|
||||
|
||||
/*
|
||||
* INFTL_findwriteunit: Return the unit number into which we can write
|
||||
* INFTL_findwriteunit: Return the unit number into which we can write
|
||||
* for this block. Make it available if it isn't already.
|
||||
*/
|
||||
static inline u16 INFTL_findwriteunit(struct INFTLrecord *inftl, unsigned block)
|
||||
|
@ -459,10 +459,10 @@ static inline u16 INFTL_findwriteunit(struct INFTLrecord *inftl, unsigned block)
|
|||
* Invalid block. Don't use it any more.
|
||||
* Must implement.
|
||||
*/
|
||||
break;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!silly--) {
|
||||
|
||||
if (!silly--) {
|
||||
printk(KERN_WARNING "INFTL: infinite loop in "
|
||||
"Virtual Unit Chain 0x%x\n", thisVUC);
|
||||
return 0xffff;
|
||||
|
@ -478,7 +478,7 @@ static inline u16 INFTL_findwriteunit(struct INFTLrecord *inftl, unsigned block)
|
|||
|
||||
|
||||
/*
|
||||
* OK. We didn't find one in the existing chain, or there
|
||||
* OK. We didn't find one in the existing chain, or there
|
||||
* is no existing chain. Allocate a new one.
|
||||
*/
|
||||
writeEUN = INFTL_findfreeblock(inftl, 0);
|
||||
|
@ -502,8 +502,8 @@ static inline u16 INFTL_findwriteunit(struct INFTLrecord *inftl, unsigned block)
|
|||
if (writeEUN == BLOCK_NIL) {
|
||||
/*
|
||||
* Ouch. This should never happen - we should
|
||||
* always be able to make some room somehow.
|
||||
* If we get here, we've allocated more storage
|
||||
* always be able to make some room somehow.
|
||||
* If we get here, we've allocated more storage
|
||||
* space than actual media, or our makefreeblock
|
||||
* routine is missing something.
|
||||
*/
|
||||
|
@ -514,7 +514,7 @@ static inline u16 INFTL_findwriteunit(struct INFTLrecord *inftl, unsigned block)
|
|||
INFTL_dumpVUchains(inftl);
|
||||
#endif
|
||||
return BLOCK_NIL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -539,7 +539,7 @@ static inline u16 INFTL_findwriteunit(struct INFTLrecord *inftl, unsigned block)
|
|||
parity |= (nrbits(prev_block, 16) & 0x1) ? 0x2 : 0;
|
||||
parity |= (nrbits(anac, 8) & 0x1) ? 0x4 : 0;
|
||||
parity |= (nrbits(nacs, 8) & 0x1) ? 0x8 : 0;
|
||||
|
||||
|
||||
oob.u.a.virtualUnitNo = cpu_to_le16(thisVUC);
|
||||
oob.u.a.prevUnitNo = cpu_to_le16(prev_block);
|
||||
oob.u.a.ANAC = anac;
|
||||
|
@ -558,7 +558,7 @@ static inline u16 INFTL_findwriteunit(struct INFTLrecord *inftl, unsigned block)
|
|||
oob.u.b.parityPerField = parity;
|
||||
oob.u.b.discarded = 0xaa;
|
||||
|
||||
MTD_WRITEOOB(inftl->mbd.mtd, writeEUN * inftl->EraseSize +
|
||||
MTD_WRITEOOB(inftl->mbd.mtd, writeEUN * inftl->EraseSize +
|
||||
SECTORSIZE * 4 + 8, 8, &retlen, (char *)&oob.u);
|
||||
|
||||
inftl->PUtable[writeEUN] = inftl->VUtable[thisVUC];
|
||||
|
@ -598,7 +598,7 @@ static void INFTL_trydeletechain(struct INFTLrecord *inftl, unsigned thisVUC)
|
|||
"Virtual Unit Chain %d!\n", thisVUC);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Scan through the Erase Units to determine whether any data is in
|
||||
* each of the 512-byte blocks within the Chain.
|
||||
|
@ -638,7 +638,7 @@ static void INFTL_trydeletechain(struct INFTLrecord *inftl, unsigned thisVUC)
|
|||
"Unit Chain 0x%x\n", thisVUC);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
thisEUN = inftl->PUtable[thisEUN];
|
||||
}
|
||||
|
||||
|
@ -754,7 +754,7 @@ static int INFTL_deleteblock(struct INFTLrecord *inftl, unsigned block)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int inftl_writeblock(struct mtd_blktrans_dev *mbd, unsigned long block,
|
||||
static int inftl_writeblock(struct mtd_blktrans_dev *mbd, unsigned long block,
|
||||
char *buffer)
|
||||
{
|
||||
struct INFTLrecord *inftl = (void *)mbd;
|
||||
|
@ -889,7 +889,7 @@ extern char inftlmountrev[];
|
|||
|
||||
static int __init init_inftl(void)
|
||||
{
|
||||
printk(KERN_INFO "INFTL: inftlcore.c $Revision: 1.18 $, "
|
||||
printk(KERN_INFO "INFTL: inftlcore.c $Revision: 1.19 $, "
|
||||
"inftlmount.c %s\n", inftlmountrev);
|
||||
|
||||
return register_mtd_blktrans(&inftl_tr);
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
/*
|
||||
/*
|
||||
* inftlmount.c -- INFTL mount code with extensive checks.
|
||||
*
|
||||
* Author: Greg Ungerer (gerg@snapgear.com)
|
||||
* (C) Copyright 2002-2003, Greg Ungerer (gerg@snapgear.com)
|
||||
*
|
||||
* Based heavily on the nftlmount.c code which is:
|
||||
* Author: Fabrice Bellard (fabrice.bellard@netgem.com)
|
||||
* Author: Fabrice Bellard (fabrice.bellard@netgem.com)
|
||||
* Copyright (C) 2000 Netgem S.A.
|
||||
*
|
||||
* $Id: inftlmount.c,v 1.16 2004/11/22 13:50:53 kalev Exp $
|
||||
* $Id: inftlmount.c,v 1.18 2005/11/07 11:14:20 gleixner Exp $
|
||||
*
|
||||
* 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
|
||||
|
@ -41,7 +41,7 @@
|
|||
#include <linux/mtd/inftl.h>
|
||||
#include <linux/mtd/compatmac.h>
|
||||
|
||||
char inftlmountrev[]="$Revision: 1.16 $";
|
||||
char inftlmountrev[]="$Revision: 1.18 $";
|
||||
|
||||
/*
|
||||
* find_boot_record: Find the INFTL Media Header and its Spare copy which
|
||||
|
@ -273,7 +273,7 @@ static int find_boot_record(struct INFTLrecord *inftl)
|
|||
inftl->nb_boot_blocks);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
inftl->mbd.size = inftl->numvunits *
|
||||
(inftl->EraseSize / SECTORSIZE);
|
||||
|
||||
|
@ -302,7 +302,7 @@ static int find_boot_record(struct INFTLrecord *inftl)
|
|||
inftl->nb_blocks * sizeof(u16));
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
|
||||
/* Mark the blocks before INFTL MediaHeader as reserved */
|
||||
for (i = 0; i < inftl->nb_boot_blocks; i++)
|
||||
inftl->PUtable[i] = BLOCK_RESERVED;
|
||||
|
@ -380,7 +380,7 @@ static int check_free_sectors(struct INFTLrecord *inftl, unsigned int address,
|
|||
*
|
||||
* Return: 0 when succeed, -1 on error.
|
||||
*
|
||||
* ToDo: 1. Is it neceressary to check_free_sector after erasing ??
|
||||
* ToDo: 1. Is it neceressary to check_free_sector after erasing ??
|
||||
*/
|
||||
int INFTL_formatblock(struct INFTLrecord *inftl, int block)
|
||||
{
|
||||
|
@ -563,7 +563,7 @@ int INFTL_mount(struct INFTLrecord *s)
|
|||
/* Search for INFTL MediaHeader and Spare INFTL Media Header */
|
||||
if (find_boot_record(s) < 0) {
|
||||
printk(KERN_WARNING "INFTL: could not find valid boot record?\n");
|
||||
return -1;
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
/* Init the logical to physical table */
|
||||
|
@ -601,7 +601,7 @@ int INFTL_mount(struct INFTLrecord *s)
|
|||
|
||||
for (chain_length = 0; ; chain_length++) {
|
||||
|
||||
if ((chain_length == 0) &&
|
||||
if ((chain_length == 0) &&
|
||||
(s->PUtable[block] != BLOCK_NOTEXPLORED)) {
|
||||
/* Nothing to do here, onto next block */
|
||||
break;
|
||||
|
@ -748,7 +748,7 @@ int INFTL_mount(struct INFTLrecord *s)
|
|||
"in virtual chain %d\n",
|
||||
s->PUtable[block], logical_block);
|
||||
s->PUtable[block] = BLOCK_NIL;
|
||||
|
||||
|
||||
}
|
||||
if (ANACtable[block] != ANAC) {
|
||||
/*
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# drivers/mtd/maps/Kconfig
|
||||
# $Id: Kconfig,v 1.55 2005/07/02 01:53:24 tpoynor Exp $
|
||||
# $Id: Kconfig,v 1.61 2005/11/07 11:14:26 gleixner Exp $
|
||||
|
||||
menu "Mapping drivers for chip access"
|
||||
depends on MTD!=n
|
||||
|
@ -64,9 +64,9 @@ config MTD_SUN_UFLASH
|
|||
tristate "Sun Microsystems userflash support"
|
||||
depends on (SPARC32 || SPARC64) && MTD_CFI
|
||||
help
|
||||
This provides a 'mapping' driver which supports the way in
|
||||
which user-programmable flash chips are connected on various
|
||||
Sun Microsystems boardsets. This driver will require CFI support
|
||||
This provides a 'mapping' driver which supports the way in
|
||||
which user-programmable flash chips are connected on various
|
||||
Sun Microsystems boardsets. This driver will require CFI support
|
||||
in the kernel, so if you did not enable CFI previously, do that now.
|
||||
|
||||
config MTD_PNC2000
|
||||
|
@ -89,22 +89,22 @@ config MTD_NETSC520
|
|||
depends on X86 && MTD_CFI && MTD_PARTITIONS
|
||||
help
|
||||
This enables access routines for the flash chips on the AMD NetSc520
|
||||
demonstration board. If you have one of these boards and would like
|
||||
demonstration board. If you have one of these boards and would like
|
||||
to use the flash chips on it, say 'Y'.
|
||||
|
||||
config MTD_TS5500
|
||||
tristate "JEDEC Flash device mapped on Technologic Systems TS-5500"
|
||||
depends on X86 && MTD_JEDECPROBE && MTD_PARTITIONS
|
||||
depends on ELAN
|
||||
select MTD_PARTITIONS
|
||||
select MTD_JEDECPROBE
|
||||
select MTD_CFI_AMDSTD
|
||||
help
|
||||
This provides a driver for the on-board flash of the Technologic
|
||||
System's TS-5500 board. The flash is split into 3 partitions
|
||||
System's TS-5500 board. The 2MB flash is split into 3 partitions
|
||||
which are accessed as separate MTD devices.
|
||||
|
||||
mtd0 and mtd2 are the two BIOS drives. Unfortunately the BIOS
|
||||
uses a proprietary flash translation layer from General Software,
|
||||
which is not supported (the drives cannot be mounted). You can
|
||||
create your own file system (jffs for example), but the BIOS
|
||||
won't be able to boot from it.
|
||||
mtd0 and mtd2 are the two BIOS drives, which use the resident
|
||||
flash disk (RFD) flash translation layer.
|
||||
|
||||
mtd1 allows you to reprogram your BIOS. BE VERY CAREFUL.
|
||||
|
||||
|
@ -212,11 +212,18 @@ config MTD_NETtel
|
|||
Support for flash chips on NETtel/SecureEdge/SnapGear boards.
|
||||
|
||||
config MTD_ALCHEMY
|
||||
tristate ' AMD Alchemy Pb1xxx/Db1xxx/RDK MTD support'
|
||||
depends on MIPS && SOC_AU1X00
|
||||
tristate ' AMD Alchemy Pb1xxx/Db1xxx/RDK MTD support'
|
||||
depends on SOC_AU1X00
|
||||
help
|
||||
Flash memory access on AMD Alchemy Pb/Db/RDK Reference Boards
|
||||
|
||||
config MTD_MTX1
|
||||
tristate "4G Systems MTX-1 Flash device"
|
||||
depends on MIPS && MIPS_MTX1
|
||||
help
|
||||
Flash memory access on 4G Systems MTX-1 Board. If you have one of
|
||||
these boards and would like to use the flash chips on it, say 'Y'.
|
||||
|
||||
config MTD_DILNETPC
|
||||
tristate "CFI Flash device mapped on DIL/Net PC"
|
||||
depends on X86 && MTD_CONCAT && MTD_PARTITIONS && MTD_CFI_INTELEXT
|
||||
|
@ -244,14 +251,14 @@ config MTD_L440GX
|
|||
|
||||
config MTD_SBC8240
|
||||
tristate "Flash device on SBC8240"
|
||||
depends on PPC32 && MTD_JEDECPROBE && 6xx && 8260
|
||||
depends on MTD_JEDECPROBE && 8260
|
||||
help
|
||||
Flash access on the SBC8240 board from Wind River. See
|
||||
<http://www.windriver.com/products/sbc8240/>
|
||||
|
||||
config MTD_TQM8XXL
|
||||
tristate "CFI Flash device mapped on TQM8XXL"
|
||||
depends on MTD_CFI && PPC32 && 8xx && TQM8xxL
|
||||
depends on MTD_CFI && TQM8xxL
|
||||
help
|
||||
The TQM8xxL PowerPC board has up to two banks of CFI-compliant
|
||||
chips, currently uses AMD one. This 'mapping' driver supports
|
||||
|
@ -261,7 +268,7 @@ config MTD_TQM8XXL
|
|||
|
||||
config MTD_RPXLITE
|
||||
tristate "CFI Flash device mapped on RPX Lite or CLLF"
|
||||
depends on MTD_CFI && PPC32 && 8xx && (RPXCLASSIC || RPXLITE)
|
||||
depends on MTD_CFI && (RPXCLASSIC || RPXLITE)
|
||||
help
|
||||
The RPXLite PowerPC board has CFI-compliant chips mapped in
|
||||
a strange sparse mapping. This 'mapping' driver supports that
|
||||
|
@ -271,7 +278,7 @@ config MTD_RPXLITE
|
|||
|
||||
config MTD_MBX860
|
||||
tristate "System flash on MBX860 board"
|
||||
depends on MTD_CFI && PPC32 && 8xx && MBX
|
||||
depends on MTD_CFI && MBX
|
||||
help
|
||||
This enables access routines for the flash chips on the Motorola
|
||||
MBX860 board. If you have one of these boards and would like
|
||||
|
@ -279,7 +286,7 @@ config MTD_MBX860
|
|||
|
||||
config MTD_DBOX2
|
||||
tristate "CFI Flash device mapped on D-Box2"
|
||||
depends on PPC32 && 8xx && DBOX2 && MTD_CFI_INTELSTD && MTD_CFI_INTELEXT && MTD_CFI_AMDSTD
|
||||
depends on DBOX2 && MTD_CFI_INTELSTD && MTD_CFI_INTELEXT && MTD_CFI_AMDSTD
|
||||
help
|
||||
This enables access routines for the flash chips on the Nokia/Sagem
|
||||
D-Box 2 board. If you have one of these boards and would like to use
|
||||
|
@ -287,14 +294,14 @@ config MTD_DBOX2
|
|||
|
||||
config MTD_CFI_FLAGADM
|
||||
tristate "CFI Flash device mapping on FlagaDM"
|
||||
depends on PPC32 && 8xx && MTD_CFI
|
||||
depends on 8xx && MTD_CFI
|
||||
help
|
||||
Mapping for the Flaga digital module. If you don't have one, ignore
|
||||
this setting.
|
||||
|
||||
config MTD_BEECH
|
||||
tristate "CFI Flash device mapped on IBM 405LP Beech"
|
||||
depends on MTD_CFI && PPC32 && 40x && BEECH
|
||||
depends on MTD_CFI && BEECH
|
||||
help
|
||||
This enables access routines for the flash chips on the IBM
|
||||
405LP Beech board. If you have one of these boards and would like
|
||||
|
@ -302,7 +309,7 @@ config MTD_BEECH
|
|||
|
||||
config MTD_ARCTIC
|
||||
tristate "CFI Flash device mapped on IBM 405LP Arctic"
|
||||
depends on MTD_CFI && PPC32 && 40x && ARCTIC2
|
||||
depends on MTD_CFI && ARCTIC2
|
||||
help
|
||||
This enables access routines for the flash chips on the IBM 405LP
|
||||
Arctic board. If you have one of these boards and would like to
|
||||
|
@ -310,7 +317,7 @@ config MTD_ARCTIC
|
|||
|
||||
config MTD_WALNUT
|
||||
tristate "Flash device mapped on IBM 405GP Walnut"
|
||||
depends on MTD_JEDECPROBE && PPC32 && 40x && WALNUT
|
||||
depends on MTD_JEDECPROBE && WALNUT
|
||||
help
|
||||
This enables access routines for the flash chips on the IBM 405GP
|
||||
Walnut board. If you have one of these boards and would like to
|
||||
|
@ -318,7 +325,7 @@ config MTD_WALNUT
|
|||
|
||||
config MTD_EBONY
|
||||
tristate "Flash devices mapped on IBM 440GP Ebony"
|
||||
depends on MTD_JEDECPROBE && PPC32 && 44x && EBONY
|
||||
depends on MTD_JEDECPROBE && EBONY
|
||||
help
|
||||
This enables access routines for the flash chips on the IBM 440GP
|
||||
Ebony board. If you have one of these boards and would like to
|
||||
|
@ -326,7 +333,7 @@ config MTD_EBONY
|
|||
|
||||
config MTD_OCOTEA
|
||||
tristate "Flash devices mapped on IBM 440GX Ocotea"
|
||||
depends on MTD_CFI && PPC32 && 44x && OCOTEA
|
||||
depends on MTD_CFI && OCOTEA
|
||||
help
|
||||
This enables access routines for the flash chips on the IBM 440GX
|
||||
Ocotea board. If you have one of these boards and would like to
|
||||
|
@ -334,12 +341,20 @@ config MTD_OCOTEA
|
|||
|
||||
config MTD_REDWOOD
|
||||
tristate "CFI Flash devices mapped on IBM Redwood"
|
||||
depends on MTD_CFI && PPC32 && 4xx && 40x && ( REDWOOD_4 || REDWOOD_5 || REDWOOD_6 )
|
||||
depends on MTD_CFI && ( REDWOOD_4 || REDWOOD_5 || REDWOOD_6 )
|
||||
help
|
||||
This enables access routines for the flash chips on the IBM
|
||||
Redwood board. If you have one of these boards and would like to
|
||||
use the flash chips on it, say 'Y'.
|
||||
|
||||
config MTD_TQM834x
|
||||
tristate "Flash device mapped on TQ Components TQM834x Boards"
|
||||
depends on MTD_CFI && TQM834x
|
||||
help
|
||||
This enables access routines for the flash chips on the
|
||||
TQ Components TQM834x boards. If you have one of these boards
|
||||
and would like to use the flash chips on it, say 'Y'.
|
||||
|
||||
config MTD_CSTM_MIPS_IXX
|
||||
tristate "Flash chip mapping on ITE QED-4N-S01B, Globespan IVR or custom board"
|
||||
depends on MIPS && MTD_CFI && MTD_JEDECPROBE && MTD_PARTITIONS
|
||||
|
@ -362,8 +377,8 @@ config MTD_CSTM_MIPS_IXX_START
|
|||
default "0x8000000"
|
||||
help
|
||||
This is the physical memory location that the MTD driver will
|
||||
use for the flash chips on your particular target board.
|
||||
Refer to the memory map which should hopefully be in the
|
||||
use for the flash chips on your particular target board.
|
||||
Refer to the memory map which should hopefully be in the
|
||||
documentation for your board.
|
||||
|
||||
config MTD_CSTM_MIPS_IXX_LEN
|
||||
|
@ -371,7 +386,7 @@ config MTD_CSTM_MIPS_IXX_LEN
|
|||
depends on MTD_CSTM_MIPS_IXX
|
||||
default "0x4000000"
|
||||
help
|
||||
This is the total length that the MTD driver will use for the
|
||||
This is the total length that the MTD driver will use for the
|
||||
flash chips on your particular board. Refer to the memory
|
||||
map which should hopefully be in the documentation for your
|
||||
board.
|
||||
|
@ -405,14 +420,14 @@ config MTD_ARM_INTEGRATOR
|
|||
|
||||
config MTD_CDB89712
|
||||
tristate "Cirrus CDB89712 evaluation board mappings"
|
||||
depends on ARM && MTD_CFI && ARCH_CDB89712
|
||||
depends on MTD_CFI && ARCH_CDB89712
|
||||
help
|
||||
This enables access to the flash or ROM chips on the CDB89712 board.
|
||||
If you have such a board, say 'Y'.
|
||||
|
||||
config MTD_SA1100
|
||||
tristate "CFI Flash device mapped on StrongARM SA11x0"
|
||||
depends on ARM && MTD_CFI && ARCH_SA1100 && MTD_PARTITIONS
|
||||
depends on MTD_CFI && ARCH_SA1100 && MTD_PARTITIONS
|
||||
help
|
||||
This enables access to the flash chips on most platforms based on
|
||||
the SA1100 and SA1110, including the Assabet and the Compaq iPAQ.
|
||||
|
@ -420,13 +435,13 @@ config MTD_SA1100
|
|||
|
||||
config MTD_IPAQ
|
||||
tristate "CFI Flash device mapped on Compaq/HP iPAQ"
|
||||
depends on ARM && IPAQ_HANDHELD && MTD_CFI
|
||||
depends on IPAQ_HANDHELD && MTD_CFI
|
||||
help
|
||||
This provides a driver for the on-board flash of the iPAQ.
|
||||
|
||||
config MTD_DC21285
|
||||
tristate "CFI Flash device mapped on DC21285 Footbridge"
|
||||
depends on ARM && MTD_CFI && ARCH_FOOTBRIDGE && MTD_COMPLEX_MAPPINGS
|
||||
depends on MTD_CFI && ARCH_FOOTBRIDGE && MTD_COMPLEX_MAPPINGS
|
||||
help
|
||||
This provides a driver for the flash accessed using Intel's
|
||||
21285 bridge used with Intel's StrongARM processors. More info at
|
||||
|
@ -434,33 +449,33 @@ config MTD_DC21285
|
|||
|
||||
config MTD_IQ80310
|
||||
tristate "CFI Flash device mapped on the XScale IQ80310 board"
|
||||
depends on ARM && MTD_CFI && ARCH_IQ80310
|
||||
depends on MTD_CFI && ARCH_IQ80310
|
||||
help
|
||||
This enables access routines for the flash chips on the Intel XScale
|
||||
IQ80310 evaluation board. If you have one of these boards and would
|
||||
IQ80310 evaluation board. If you have one of these boards and would
|
||||
like to use the flash chips on it, say 'Y'.
|
||||
|
||||
config MTD_IXP4XX
|
||||
tristate "CFI Flash device mapped on Intel IXP4xx based systems"
|
||||
depends on ARM && MTD_CFI && MTD_COMPLEX_MAPPINGS && ARCH_IXP4XX
|
||||
depends on MTD_CFI && MTD_COMPLEX_MAPPINGS && ARCH_IXP4XX
|
||||
help
|
||||
This enables MTD access to flash devices on platforms based
|
||||
This enables MTD access to flash devices on platforms based
|
||||
on Intel's IXP4xx family of network processors such as the
|
||||
IXDP425 and Coyote. If you have an IXP4xx based board and
|
||||
would like to use the flash chips on it, say 'Y'.
|
||||
|
||||
config MTD_IXP2000
|
||||
tristate "CFI Flash device mapped on Intel IXP2000 based systems"
|
||||
depends on ARM && MTD_CFI && MTD_COMPLEX_MAPPINGS && ARCH_IXP2000
|
||||
depends on MTD_CFI && MTD_COMPLEX_MAPPINGS && ARCH_IXP2000
|
||||
help
|
||||
This enables MTD access to flash devices on platforms based
|
||||
This enables MTD access to flash devices on platforms based
|
||||
on Intel's IXP2000 family of network processors such as the
|
||||
IXDP425 and Coyote. If you have an IXP2000 based board and
|
||||
would like to use the flash chips on it, say 'Y'.
|
||||
|
||||
config MTD_EPXA10DB
|
||||
tristate "CFI Flash device mapped on Epxa10db"
|
||||
depends on ARM && MTD_CFI && MTD_PARTITIONS && ARCH_CAMELOT
|
||||
depends on MTD_CFI && MTD_PARTITIONS && ARCH_CAMELOT
|
||||
help
|
||||
This enables support for the flash devices on the Altera
|
||||
Excalibur XA10 Development Board. If you are building a kernel
|
||||
|
@ -468,21 +483,21 @@ config MTD_EPXA10DB
|
|||
|
||||
config MTD_FORTUNET
|
||||
tristate "CFI Flash device mapped on the FortuNet board"
|
||||
depends on ARM && MTD_CFI && MTD_PARTITIONS && SA1100_FORTUNET
|
||||
depends on MTD_CFI && MTD_PARTITIONS && SA1100_FORTUNET
|
||||
help
|
||||
This enables access to the Flash on the FortuNet board. If you
|
||||
have such a board, say 'Y'.
|
||||
|
||||
config MTD_AUTCPU12
|
||||
tristate "NV-RAM mapping AUTCPU12 board"
|
||||
depends on ARM && ARCH_AUTCPU12
|
||||
depends on ARCH_AUTCPU12
|
||||
help
|
||||
This enables access to the NV-RAM on autronix autcpu12 board.
|
||||
If you have such a board, say 'Y'.
|
||||
|
||||
config MTD_EDB7312
|
||||
tristate "CFI Flash device mapped on EDB7312"
|
||||
depends on ARM && MTD_CFI
|
||||
depends on ARCH_EDB7312 && MTD_CFI
|
||||
help
|
||||
This enables access to the CFI Flash on the Cogent EDB7312 board.
|
||||
If you have such a board, say 'Y' here.
|
||||
|
@ -496,7 +511,7 @@ config MTD_IMPA7
|
|||
|
||||
config MTD_CEIVA
|
||||
tristate "JEDEC Flash device mapped on Ceiva/Polaroid PhotoMax Digital Picture Frame"
|
||||
depends on ARM && MTD_JEDECPROBE && ARCH_CEIVA
|
||||
depends on MTD_JEDECPROBE && ARCH_CEIVA
|
||||
help
|
||||
This enables access to the flash chips on the Ceiva/Polaroid
|
||||
PhotoMax Digital Picture Frame.
|
||||
|
@ -504,25 +519,31 @@ config MTD_CEIVA
|
|||
|
||||
config MTD_NOR_TOTO
|
||||
tristate "NOR Flash device on TOTO board"
|
||||
depends on ARM && ARCH_OMAP && OMAP_TOTO
|
||||
depends on ARCH_OMAP && OMAP_TOTO
|
||||
help
|
||||
This enables access to the NOR flash on the Texas Instruments
|
||||
TOTO board.
|
||||
|
||||
config MTD_H720X
|
||||
tristate "Hynix evaluation board mappings"
|
||||
depends on ARM && MTD_CFI && ( ARCH_H7201 || ARCH_H7202 )
|
||||
depends on MTD_CFI && ( ARCH_H7201 || ARCH_H7202 )
|
||||
help
|
||||
This enables access to the flash chips on the Hynix evaluation boards.
|
||||
If you have such a board, say 'Y'.
|
||||
|
||||
config MTD_MPC1211
|
||||
tristate "CFI Flash device mapped on Interface MPC-1211"
|
||||
depends on SUPERH && SH_MPC1211 && MTD_CFI
|
||||
depends on SH_MPC1211 && MTD_CFI
|
||||
help
|
||||
This enables access to the flash chips on the Interface MPC-1211(CTP/PCI/MPC-SH02).
|
||||
If you have such a board, say 'Y'.
|
||||
|
||||
config MTD_PQ2FADS
|
||||
tristate "JEDEC flash SIMM mapped on PQ2FADS and 8272ADS boards"
|
||||
depends on (ADS8272 || PQ2FADS) && MTD_PARTITIONS && MTD_JEDECPROBE && MTD_PHYSMAP && MTD_CFI_GEOMETRY && MTD_CFI_INTELEXT
|
||||
help
|
||||
This enables access to flash SIMM on PQ2FADS-like boards
|
||||
|
||||
config MTD_OMAP_NOR
|
||||
tristate "TI OMAP board mappings"
|
||||
depends on MTD_CFI && ARCH_OMAP
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#
|
||||
# linux/drivers/maps/Makefile
|
||||
#
|
||||
# $Id: Makefile.common,v 1.30 2005/07/02 01:53:24 tpoynor Exp $
|
||||
# $Id: Makefile.common,v 1.34 2005/11/07 11:14:26 gleixner Exp $
|
||||
|
||||
ifeq ($(CONFIG_MTD_COMPLEX_MAPPINGS),y)
|
||||
obj-$(CONFIG_MTD) += map_funcs.o
|
||||
|
@ -26,7 +26,7 @@ obj-$(CONFIG_MTD_MAINSTONE) += mainstone-flash.o
|
|||
obj-$(CONFIG_MTD_MBX860) += mbx860.o
|
||||
obj-$(CONFIG_MTD_CEIVA) += ceiva.o
|
||||
obj-$(CONFIG_MTD_OCTAGON) += octagon-5066.o
|
||||
obj-$(CONFIG_MTD_PHYSMAP) += physmap.o
|
||||
obj-$(CONFIG_MTD_PHYSMAP) += physmap.o
|
||||
obj-$(CONFIG_MTD_PNC2000) += pnc2000.o
|
||||
obj-$(CONFIG_MTD_PCMCIA) += pcmciamtd.o
|
||||
obj-$(CONFIG_MTD_RPXLITE) += rpxlite.o
|
||||
|
@ -70,3 +70,6 @@ obj-$(CONFIG_MTD_DMV182) += dmv182.o
|
|||
obj-$(CONFIG_MTD_SHARP_SL) += sharpsl-flash.o
|
||||
obj-$(CONFIG_MTD_PLATRAM) += plat-ram.o
|
||||
obj-$(CONFIG_MTD_OMAP_NOR) += omap_nor.o
|
||||
obj-$(CONFIG_MTD_PQ2FADS) += pq2fads.o
|
||||
obj-$(CONFIG_MTD_MTX1) += mtx-1_flash.o
|
||||
obj-$(CONFIG_MTD_TQM834x) += tqm834x.o
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
/*
|
||||
* Flash memory access on AMD Alchemy evaluation boards
|
||||
*
|
||||
* $Id: alchemy-flash.c,v 1.1 2005/02/27 21:50:21 ppopov Exp $
|
||||
*
|
||||
* $Id: alchemy-flash.c,v 1.2 2005/11/07 11:14:26 gleixner Exp $
|
||||
*
|
||||
* (C) 2003, 2004 Pete Popov <ppopov@embeddedalley.com>
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/config.h>
|
||||
|
@ -22,7 +22,7 @@
|
|||
#ifdef DEBUG_RW
|
||||
#define DBG(x...) printk(x)
|
||||
#else
|
||||
#define DBG(x...)
|
||||
#define DBG(x...)
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_MIPS_PB1000
|
||||
|
@ -136,7 +136,7 @@ int __init alchemy_mtd_init(void)
|
|||
int nb_parts = 0;
|
||||
unsigned long window_addr;
|
||||
unsigned long window_size;
|
||||
|
||||
|
||||
/* Default flash buswidth */
|
||||
alchemy_map.bankwidth = BOARD_FLASH_WIDTH;
|
||||
|
||||
|
@ -161,7 +161,7 @@ int __init alchemy_mtd_init(void)
|
|||
* Now let's probe for the actual flash. Do it here since
|
||||
* specific machine settings might have been set above.
|
||||
*/
|
||||
printk(KERN_NOTICE BOARD_MAP_NAME ": probing %d-bit flash bus\n",
|
||||
printk(KERN_NOTICE BOARD_MAP_NAME ": probing %d-bit flash bus\n",
|
||||
alchemy_map.bankwidth*8);
|
||||
alchemy_map.virt = ioremap(window_addr, window_size);
|
||||
mymtd = do_map_probe("cfi_probe", &alchemy_map);
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* amd76xrom.c
|
||||
*
|
||||
* Normal mappings of chips in physical memory
|
||||
* $Id: amd76xrom.c,v 1.20 2005/03/18 14:04:35 gleixner Exp $
|
||||
* $Id: amd76xrom.c,v 1.21 2005/11/07 11:14:26 gleixner Exp $
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
|
@ -70,7 +70,7 @@ static void amd76xrom_cleanup(struct amd76xrom_window *window)
|
|||
list_del(&map->list);
|
||||
kfree(map);
|
||||
}
|
||||
if (window->rsrc.parent)
|
||||
if (window->rsrc.parent)
|
||||
release_resource(&window->rsrc);
|
||||
|
||||
if (window->virt) {
|
||||
|
@ -107,7 +107,7 @@ static int __devinit amd76xrom_init_one (struct pci_dev *pdev,
|
|||
window->phys = 0xffff0000; /* 64KiB */
|
||||
}
|
||||
window->size = 0xffffffffUL - window->phys + 1UL;
|
||||
|
||||
|
||||
/*
|
||||
* Try to reserve the window mem region. If this fails then
|
||||
* it is likely due to a fragment of the window being
|
||||
|
@ -138,7 +138,7 @@ static int __devinit amd76xrom_init_one (struct pci_dev *pdev,
|
|||
/* Enable writes through the rom window */
|
||||
pci_read_config_byte(pdev, 0x40, &byte);
|
||||
pci_write_config_byte(pdev, 0x40, byte | 1);
|
||||
|
||||
|
||||
/* FIXME handle registers 0x80 - 0x8C the bios region locks */
|
||||
|
||||
/* For write accesses caches are useless */
|
||||
|
@ -186,7 +186,7 @@ static int __devinit amd76xrom_init_one (struct pci_dev *pdev,
|
|||
MOD_NAME, map->map.phys);
|
||||
|
||||
/* There is no generic VPP support */
|
||||
for(map->map.bankwidth = 32; map->map.bankwidth;
|
||||
for(map->map.bankwidth = 32; map->map.bankwidth;
|
||||
map->map.bankwidth >>= 1)
|
||||
{
|
||||
char **probe_type;
|
||||
|
@ -239,7 +239,7 @@ static int __devinit amd76xrom_init_one (struct pci_dev *pdev,
|
|||
for(i = 0; i < cfi->numchips; i++) {
|
||||
cfi->chips[i].start += offset;
|
||||
}
|
||||
|
||||
|
||||
/* Now that the mtd devices is complete claim and export it */
|
||||
map->mtd->owner = THIS_MODULE;
|
||||
if (add_mtd_device(map->mtd)) {
|
||||
|
@ -277,9 +277,9 @@ static void __devexit amd76xrom_remove_one (struct pci_dev *pdev)
|
|||
}
|
||||
|
||||
static struct pci_device_id amd76xrom_pci_tbl[] = {
|
||||
{ PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_VIPER_7410,
|
||||
{ PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_VIPER_7410,
|
||||
PCI_ANY_ID, PCI_ANY_ID, },
|
||||
{ PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_VIPER_7440,
|
||||
{ PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_VIPER_7440,
|
||||
PCI_ANY_ID, PCI_ANY_ID, },
|
||||
{ PCI_VENDOR_ID_AMD, 0x7468 }, /* amd8111 support */
|
||||
{ 0, }
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* $Id: arctic-mtd.c,v 1.13 2004/11/04 13:24:14 gleixner Exp $
|
||||
*
|
||||
* drivers/mtd/maps/arctic-mtd.c MTD mappings and partition tables for
|
||||
* $Id: arctic-mtd.c,v 1.14 2005/11/07 11:14:26 gleixner Exp $
|
||||
*
|
||||
* drivers/mtd/maps/arctic-mtd.c MTD mappings and partition tables for
|
||||
* IBM 405LP Arctic boards.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
/*
|
||||
* NV-RAM memory access on autcpu12
|
||||
* NV-RAM memory access on autcpu12
|
||||
* (C) 2002 Thomas Gleixner (gleixner@autronix.de)
|
||||
*
|
||||
* $Id: autcpu12-nvram.c,v 1.8 2004/11/04 13:24:14 gleixner Exp $
|
||||
* $Id: autcpu12-nvram.c,v 1.9 2005/11/07 11:14:26 gleixner Exp $
|
||||
*
|
||||
* 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
|
||||
|
@ -55,10 +55,10 @@ static int __init init_autcpu12_sram (void)
|
|||
}
|
||||
simple_map_init(&autcpu_sram_map);
|
||||
|
||||
/*
|
||||
* Check for 32K/128K
|
||||
* read ofs 0
|
||||
* read ofs 0x10000
|
||||
/*
|
||||
* Check for 32K/128K
|
||||
* read ofs 0
|
||||
* read ofs 0x10000
|
||||
* Write complement to ofs 0x100000
|
||||
* Read and check result on ofs 0x0
|
||||
* Restore contents
|
||||
|
@ -66,7 +66,7 @@ static int __init init_autcpu12_sram (void)
|
|||
save0 = map_read32(&autcpu12_sram_map,0);
|
||||
save1 = map_read32(&autcpu12_sram_map,0x10000);
|
||||
map_write32(&autcpu12_sram_map,~save0,0x10000);
|
||||
/* if we find this pattern on 0x0, we have 32K size
|
||||
/* if we find this pattern on 0x0, we have 32K size
|
||||
* restore contents and exit
|
||||
*/
|
||||
if ( map_read32(&autcpu12_sram_map,0) != save0) {
|
||||
|
@ -89,7 +89,7 @@ static int __init init_autcpu12_sram (void)
|
|||
|
||||
sram_mtd->owner = THIS_MODULE;
|
||||
sram_mtd->erasesize = 16;
|
||||
|
||||
|
||||
if (add_mtd_device(sram_mtd)) {
|
||||
printk("NV-RAM device addition failed\n");
|
||||
err = -ENOMEM;
|
||||
|
@ -97,7 +97,7 @@ static int __init init_autcpu12_sram (void)
|
|||
}
|
||||
|
||||
printk("NV-RAM device size %ldKiB registered on AUTCPU12\n",autcpu12_sram_map.size/SZ_1K);
|
||||
|
||||
|
||||
return 0;
|
||||
|
||||
out_probe:
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
* 20-Sep-2004 BJD Initial version
|
||||
* 17-Jan-2005 BJD Add whole device if no partitions found
|
||||
*
|
||||
* $Id: bast-flash.c,v 1.2 2005/01/18 11:13:47 bjd Exp $
|
||||
* $Id: bast-flash.c,v 1.5 2005/11/07 11:14:26 gleixner Exp $
|
||||
*
|
||||
* 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
|
||||
|
@ -75,7 +75,7 @@ static void bast_flash_setrw(int to)
|
|||
|
||||
local_irq_save(flags);
|
||||
val = __raw_readb(BAST_VA_CTRL3);
|
||||
|
||||
|
||||
if (to)
|
||||
val |= BAST_CPLD_CTRL3_ROMWEN;
|
||||
else
|
||||
|
@ -93,7 +93,7 @@ static int bast_flash_remove(struct device *dev)
|
|||
|
||||
dev_set_drvdata(dev, NULL);
|
||||
|
||||
if (info == NULL)
|
||||
if (info == NULL)
|
||||
return 0;
|
||||
|
||||
if (info->map.virt != NULL)
|
||||
|
@ -110,7 +110,7 @@ static int bast_flash_remove(struct device *dev)
|
|||
release_resource(info->area);
|
||||
kfree(info->area);
|
||||
}
|
||||
|
||||
|
||||
kfree(info);
|
||||
|
||||
return 0;
|
||||
|
@ -137,15 +137,15 @@ static int bast_flash_probe(struct device *dev)
|
|||
|
||||
info->map.phys = res->start;
|
||||
info->map.size = res->end - res->start + 1;
|
||||
info->map.name = dev->bus_id;
|
||||
info->map.name = dev->bus_id;
|
||||
info->map.bankwidth = 2;
|
||||
|
||||
|
||||
if (info->map.size > AREA_MAXSIZE)
|
||||
info->map.size = AREA_MAXSIZE;
|
||||
|
||||
pr_debug("%s: area %08lx, size %ld\n", __FUNCTION__,
|
||||
info->map.phys, info->map.size);
|
||||
|
||||
|
||||
info->area = request_mem_region(res->start, info->map.size,
|
||||
pdev->name);
|
||||
if (info->area == NULL) {
|
||||
|
@ -162,7 +162,7 @@ static int bast_flash_probe(struct device *dev)
|
|||
err = -EIO;
|
||||
goto exit_error;
|
||||
}
|
||||
|
||||
|
||||
simple_map_init(&info->map);
|
||||
|
||||
/* enable the write to the flash area */
|
||||
|
@ -187,7 +187,7 @@ static int bast_flash_probe(struct device *dev)
|
|||
err = parse_mtd_partitions(info->mtd, probes, &info->partitions, 0);
|
||||
if (err > 0) {
|
||||
err = add_mtd_partitions(info->mtd, info->partitions, err);
|
||||
if (err)
|
||||
if (err)
|
||||
printk(KERN_ERR PFX "cannot add/parse partitions\n");
|
||||
} else {
|
||||
err = add_mtd_device(info->mtd);
|
||||
|
@ -205,6 +205,7 @@ static int bast_flash_probe(struct device *dev)
|
|||
|
||||
static struct device_driver bast_flash_driver = {
|
||||
.name = "bast-nor",
|
||||
.owner = THIS_MODULE,
|
||||
.bus = &platform_bus_type,
|
||||
.probe = bast_flash_probe,
|
||||
.remove = bast_flash_remove,
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* $Id: beech-mtd.c,v 1.10 2004/11/04 13:24:14 gleixner Exp $
|
||||
*
|
||||
* drivers/mtd/maps/beech-mtd.c MTD mappings and partition tables for
|
||||
* $Id: beech-mtd.c,v 1.11 2005/11/07 11:14:26 gleixner Exp $
|
||||
*
|
||||
* drivers/mtd/maps/beech-mtd.c MTD mappings and partition tables for
|
||||
* IBM 405LP Beech boards.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* Flash on Cirrus CDB89712
|
||||
*
|
||||
* $Id: cdb89712.c,v 1.10 2004/11/04 13:24:14 gleixner Exp $
|
||||
* $Id: cdb89712.c,v 1.11 2005/11/07 11:14:26 gleixner Exp $
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
|
@ -37,13 +37,13 @@ struct resource cdb89712_flash_resource = {
|
|||
static int __init init_cdb89712_flash (void)
|
||||
{
|
||||
int err;
|
||||
|
||||
|
||||
if (request_resource (&ioport_resource, &cdb89712_flash_resource)) {
|
||||
printk(KERN_NOTICE "Failed to reserve Cdb89712 FLASH space\n");
|
||||
err = -EBUSY;
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
||||
cdb89712_flash_map.virt = ioremap(FLASH_START, FLASH_SIZE);
|
||||
if (!cdb89712_flash_map.virt) {
|
||||
printk(KERN_NOTICE "Failed to ioremap Cdb89712 FLASH space\n");
|
||||
|
@ -64,13 +64,13 @@ static int __init init_cdb89712_flash (void)
|
|||
}
|
||||
|
||||
flash_mtd->owner = THIS_MODULE;
|
||||
|
||||
|
||||
if (add_mtd_device(flash_mtd)) {
|
||||
printk("FLASH device addition failed\n");
|
||||
err = -ENOMEM;
|
||||
goto out_probe;
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
|
||||
out_probe:
|
||||
|
@ -107,13 +107,13 @@ struct resource cdb89712_sram_resource = {
|
|||
static int __init init_cdb89712_sram (void)
|
||||
{
|
||||
int err;
|
||||
|
||||
|
||||
if (request_resource (&ioport_resource, &cdb89712_sram_resource)) {
|
||||
printk(KERN_NOTICE "Failed to reserve Cdb89712 SRAM space\n");
|
||||
err = -EBUSY;
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
||||
cdb89712_sram_map.virt = ioremap(SRAM_START, SRAM_SIZE);
|
||||
if (!cdb89712_sram_map.virt) {
|
||||
printk(KERN_NOTICE "Failed to ioremap Cdb89712 SRAM space\n");
|
||||
|
@ -130,13 +130,13 @@ static int __init init_cdb89712_sram (void)
|
|||
|
||||
sram_mtd->owner = THIS_MODULE;
|
||||
sram_mtd->erasesize = 16;
|
||||
|
||||
|
||||
if (add_mtd_device(sram_mtd)) {
|
||||
printk("SRAM device addition failed\n");
|
||||
err = -ENOMEM;
|
||||
goto out_probe;
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
|
||||
out_probe:
|
||||
|
@ -175,13 +175,13 @@ struct resource cdb89712_bootrom_resource = {
|
|||
static int __init init_cdb89712_bootrom (void)
|
||||
{
|
||||
int err;
|
||||
|
||||
|
||||
if (request_resource (&ioport_resource, &cdb89712_bootrom_resource)) {
|
||||
printk(KERN_NOTICE "Failed to reserve Cdb89712 BOOTROM space\n");
|
||||
err = -EBUSY;
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
||||
cdb89712_bootrom_map.virt = ioremap(BOOTROM_START, BOOTROM_SIZE);
|
||||
if (!cdb89712_bootrom_map.virt) {
|
||||
printk(KERN_NOTICE "Failed to ioremap Cdb89712 BootROM space\n");
|
||||
|
@ -198,13 +198,13 @@ static int __init init_cdb89712_bootrom (void)
|
|||
|
||||
bootrom_mtd->owner = THIS_MODULE;
|
||||
bootrom_mtd->erasesize = 0x10000;
|
||||
|
||||
|
||||
if (add_mtd_device(bootrom_mtd)) {
|
||||
printk("BootROM device addition failed\n");
|
||||
err = -ENOMEM;
|
||||
goto out_probe;
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
|
||||
out_probe:
|
||||
|
@ -225,16 +225,16 @@ static int __init init_cdb89712_bootrom (void)
|
|||
static int __init init_cdb89712_maps(void)
|
||||
{
|
||||
|
||||
printk(KERN_INFO "Cirrus CDB89712 MTD mappings:\n Flash 0x%x at 0x%x\n SRAM 0x%x at 0x%x\n BootROM 0x%x at 0x%x\n",
|
||||
printk(KERN_INFO "Cirrus CDB89712 MTD mappings:\n Flash 0x%x at 0x%x\n SRAM 0x%x at 0x%x\n BootROM 0x%x at 0x%x\n",
|
||||
FLASH_SIZE, FLASH_START, SRAM_SIZE, SRAM_START, BOOTROM_SIZE, BOOTROM_START);
|
||||
|
||||
init_cdb89712_flash();
|
||||
init_cdb89712_sram();
|
||||
init_cdb89712_bootrom();
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void __exit cleanup_cdb89712_maps(void)
|
||||
{
|
||||
|
@ -244,7 +244,7 @@ static void __exit cleanup_cdb89712_maps(void)
|
|||
iounmap((void *)cdb89712_sram_map.virt);
|
||||
release_resource (&cdb89712_sram_resource);
|
||||
}
|
||||
|
||||
|
||||
if (flash_mtd) {
|
||||
del_mtd_device(flash_mtd);
|
||||
map_destroy(flash_mtd);
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
/*
|
||||
* Copyright © 2001 Flaga hf. Medical Devices, Kári Davíðsson <kd@flaga.is>
|
||||
*
|
||||
* $Id: cfi_flagadm.c,v 1.14 2004/11/04 13:24:14 gleixner Exp $
|
||||
*
|
||||
* $Id: cfi_flagadm.c,v 1.15 2005/11/07 11:14:26 gleixner Exp $
|
||||
*
|
||||
* 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
|
||||
|
@ -42,7 +42,7 @@
|
|||
*/
|
||||
|
||||
#define FLASH_PHYS_ADDR 0x40000000
|
||||
#define FLASH_SIZE 0x400000
|
||||
#define FLASH_SIZE 0x400000
|
||||
|
||||
#define FLASH_PARTITION0_ADDR 0x00000000
|
||||
#define FLASH_PARTITION0_SIZE 0x00020000
|
||||
|
@ -79,7 +79,7 @@ struct mtd_partition flagadm_parts[] = {
|
|||
.offset = FLASH_PARTITION2_ADDR,
|
||||
.size = FLASH_PARTITION2_SIZE
|
||||
},
|
||||
{
|
||||
{
|
||||
.name = "Persistant storage",
|
||||
.offset = FLASH_PARTITION3_ADDR,
|
||||
.size = FLASH_PARTITION3_SIZE
|
||||
|
@ -91,10 +91,10 @@ struct mtd_partition flagadm_parts[] = {
|
|||
static struct mtd_info *mymtd;
|
||||
|
||||
int __init init_flagadm(void)
|
||||
{
|
||||
{
|
||||
printk(KERN_NOTICE "FlagaDM flash device: %x at %x\n",
|
||||
FLASH_SIZE, FLASH_PHYS_ADDR);
|
||||
|
||||
|
||||
flagadm_map.phys = FLASH_PHYS_ADDR;
|
||||
flagadm_map.virt = ioremap(FLASH_PHYS_ADDR,
|
||||
FLASH_SIZE);
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
/*
|
||||
* $Id: cstm_mips_ixx.c,v 1.12 2004/11/04 13:24:14 gleixner Exp $
|
||||
* $Id: cstm_mips_ixx.c,v 1.14 2005/11/07 11:14:26 gleixner Exp $
|
||||
*
|
||||
* Mapping of a custom board with both AMD CFI and JEDEC flash in partitions.
|
||||
* Config with both CFI and JEDEC device support.
|
||||
*
|
||||
* Basically physmap.c with the addition of partitions and
|
||||
* Basically physmap.c with the addition of partitions and
|
||||
* an array of mapping info to accomodate more than one flash type per board.
|
||||
*
|
||||
* Copyright 2000 MontaVista Software Inc.
|
||||
|
@ -69,7 +69,7 @@ void cstm_mips_ixx_set_vpp(struct map_info *map,int vpp)
|
|||
__u16 data;
|
||||
__u8 data1;
|
||||
static u8 first = 1;
|
||||
|
||||
|
||||
// Set GPIO port B pin3 to high
|
||||
data = *(__u16 *)(CC_GPBCR);
|
||||
data = (data & 0xff0f) | 0x0040;
|
||||
|
@ -85,7 +85,7 @@ void cstm_mips_ixx_set_vpp(struct map_info *map,int vpp)
|
|||
} else {
|
||||
if (!--vpp_count) {
|
||||
__u16 data;
|
||||
|
||||
|
||||
// Set GPIO port B pin3 to high
|
||||
data = *(__u16 *)(CC_GPBCR);
|
||||
data = (data & 0xff3f) | 0x0040;
|
||||
|
@ -109,8 +109,8 @@ struct cstm_mips_ixx_info {
|
|||
};
|
||||
|
||||
#if defined(CONFIG_MIPS_ITE8172) || defined(CONFIG_MIPS_IVR)
|
||||
#define PHYSMAP_NUMBER 1 // number of board desc structs needed, one per contiguous flash type
|
||||
const struct cstm_mips_ixx_info cstm_mips_ixx_board_desc[PHYSMAP_NUMBER] =
|
||||
#define PHYSMAP_NUMBER 1 // number of board desc structs needed, one per contiguous flash type
|
||||
const struct cstm_mips_ixx_info cstm_mips_ixx_board_desc[PHYSMAP_NUMBER] =
|
||||
{
|
||||
{ // 28F128J3A in 2x16 configuration
|
||||
"big flash", // name
|
||||
|
@ -131,10 +131,10 @@ static struct mtd_partition cstm_mips_ixx_partitions[PHYSMAP_NUMBER][MAX_PHYSMAP
|
|||
},
|
||||
};
|
||||
#else /* defined(CONFIG_MIPS_ITE8172) || defined(CONFIG_MIPS_IVR) */
|
||||
#define PHYSMAP_NUMBER 1 // number of board desc structs needed, one per contiguous flash type
|
||||
const struct cstm_mips_ixx_info cstm_mips_ixx_board_desc[PHYSMAP_NUMBER] =
|
||||
#define PHYSMAP_NUMBER 1 // number of board desc structs needed, one per contiguous flash type
|
||||
const struct cstm_mips_ixx_info cstm_mips_ixx_board_desc[PHYSMAP_NUMBER] =
|
||||
{
|
||||
{
|
||||
{
|
||||
"MTD flash", // name
|
||||
CONFIG_MTD_CSTM_MIPS_IXX_START, // window_addr
|
||||
CONFIG_MTD_CSTM_MIPS_IXX_LEN, // window_size
|
||||
|
@ -144,7 +144,7 @@ const struct cstm_mips_ixx_info cstm_mips_ixx_board_desc[PHYSMAP_NUMBER] =
|
|||
|
||||
};
|
||||
static struct mtd_partition cstm_mips_ixx_partitions[PHYSMAP_NUMBER][MAX_PHYSMAP_PARTITIONS] = {
|
||||
{
|
||||
{
|
||||
{
|
||||
.name = "main partition",
|
||||
.size = CONFIG_MTD_CSTM_MIPS_IXX_LEN,
|
||||
|
@ -165,7 +165,7 @@ int __init init_cstm_mips_ixx(void)
|
|||
|
||||
/* Initialize mapping */
|
||||
for (i=0;i<PHYSMAP_NUMBER;i++) {
|
||||
printk(KERN_NOTICE "cstm_mips_ixx flash device: 0x%lx at 0x%lx\n",
|
||||
printk(KERN_NOTICE "cstm_mips_ixx flash device: 0x%lx at 0x%lx\n",
|
||||
cstm_mips_ixx_board_desc[i].window_size, cstm_mips_ixx_board_desc[i].window_addr);
|
||||
|
||||
|
||||
|
@ -235,7 +235,7 @@ void PCISetULongByOffset(__u32 DevNumber, __u32 FuncNumber, __u32 Offset, __u32
|
|||
|
||||
offset = ( unsigned long )( 0x80000000 | ( DevNumber << 11 ) + ( FuncNumber << 8 ) + Offset) ;
|
||||
|
||||
*(__u32 *)CC_CONFADDR = offset;
|
||||
*(__u32 *)CC_CONFADDR = offset;
|
||||
*(__u32 *)CC_CONFDATA = data;
|
||||
}
|
||||
void setup_ITE_IVR_flash()
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* $Id: dbox2-flash.c,v 1.13 2004/11/04 13:24:14 gleixner Exp $
|
||||
* $Id: dbox2-flash.c,v 1.14 2005/11/07 11:14:26 gleixner Exp $
|
||||
*
|
||||
* D-Box 2 flash driver
|
||||
*/
|
||||
|
@ -21,38 +21,38 @@
|
|||
static struct mtd_partition partition_info[]= {
|
||||
{
|
||||
.name = "BR bootloader",
|
||||
.size = 128 * 1024,
|
||||
.offset = 0,
|
||||
.size = 128 * 1024,
|
||||
.offset = 0,
|
||||
.mask_flags = MTD_WRITEABLE
|
||||
},
|
||||
{
|
||||
.name = "FLFS (U-Boot)",
|
||||
.size = 128 * 1024,
|
||||
.offset = MTDPART_OFS_APPEND,
|
||||
.size = 128 * 1024,
|
||||
.offset = MTDPART_OFS_APPEND,
|
||||
.mask_flags = 0
|
||||
},
|
||||
{
|
||||
.name = "Root (SquashFS)",
|
||||
.size = 7040 * 1024,
|
||||
.offset = MTDPART_OFS_APPEND,
|
||||
.name = "Root (SquashFS)",
|
||||
.size = 7040 * 1024,
|
||||
.offset = MTDPART_OFS_APPEND,
|
||||
.mask_flags = 0
|
||||
},
|
||||
{
|
||||
.name = "var (JFFS2)",
|
||||
.size = 896 * 1024,
|
||||
.offset = MTDPART_OFS_APPEND,
|
||||
.size = 896 * 1024,
|
||||
.offset = MTDPART_OFS_APPEND,
|
||||
.mask_flags = 0
|
||||
},
|
||||
{
|
||||
.name = "Flash without bootloader",
|
||||
.size = MTDPART_SIZ_FULL,
|
||||
.offset = 128 * 1024,
|
||||
.name = "Flash without bootloader",
|
||||
.size = MTDPART_SIZ_FULL,
|
||||
.offset = 128 * 1024,
|
||||
.mask_flags = 0
|
||||
},
|
||||
{
|
||||
.name = "Complete Flash",
|
||||
.size = MTDPART_SIZ_FULL,
|
||||
.offset = 0,
|
||||
.name = "Complete Flash",
|
||||
.size = MTDPART_SIZ_FULL,
|
||||
.offset = 0,
|
||||
.mask_flags = MTD_WRITEABLE
|
||||
}
|
||||
};
|
||||
|
@ -88,16 +88,16 @@ int __init init_dbox2_flash(void)
|
|||
if (!mymtd) {
|
||||
// Probe for single Intel 28F640
|
||||
dbox2_flash_map.bankwidth = 2;
|
||||
|
||||
|
||||
mymtd = do_map_probe("cfi_probe", &dbox2_flash_map);
|
||||
}
|
||||
|
||||
|
||||
if (mymtd) {
|
||||
mymtd->owner = THIS_MODULE;
|
||||
|
||||
/* Create MTD devices for each partition. */
|
||||
add_mtd_partitions(mymtd, partition_info, NUM_PARTITIONS);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
* (C) 2000 Nicolas Pitre <nico@cam.org>
|
||||
*
|
||||
* This code is GPL
|
||||
*
|
||||
* $Id: dc21285.c,v 1.22 2004/11/01 13:39:21 rmk Exp $
|
||||
*
|
||||
* $Id: dc21285.c,v 1.24 2005/11/07 11:14:26 gleixner Exp $
|
||||
*/
|
||||
#include <linux/config.h>
|
||||
#include <linux/module.h>
|
||||
|
@ -27,9 +27,9 @@
|
|||
static struct mtd_info *dc21285_mtd;
|
||||
|
||||
#ifdef CONFIG_ARCH_NETWINDER
|
||||
/*
|
||||
/*
|
||||
* This is really ugly, but it seams to be the only
|
||||
* realiable way to do it, as the cpld state machine
|
||||
* realiable way to do it, as the cpld state machine
|
||||
* is unpredictible. So we have a 25us penalty per
|
||||
* write access.
|
||||
*/
|
||||
|
@ -150,7 +150,7 @@ static struct map_info dc21285_map = {
|
|||
static struct mtd_partition *dc21285_parts;
|
||||
static const char *probes[] = { "RedBoot", "cmdlinepart", NULL };
|
||||
#endif
|
||||
|
||||
|
||||
static int __init init_dc21285(void)
|
||||
{
|
||||
|
||||
|
@ -160,20 +160,20 @@ static int __init init_dc21285(void)
|
|||
|
||||
/* Determine bankwidth */
|
||||
switch (*CSR_SA110_CNTL & (3<<14)) {
|
||||
case SA110_CNTL_ROMWIDTH_8:
|
||||
case SA110_CNTL_ROMWIDTH_8:
|
||||
dc21285_map.bankwidth = 1;
|
||||
dc21285_map.read = dc21285_read8;
|
||||
dc21285_map.write = dc21285_write8;
|
||||
dc21285_map.copy_to = dc21285_copy_to_8;
|
||||
break;
|
||||
case SA110_CNTL_ROMWIDTH_16:
|
||||
dc21285_map.bankwidth = 2;
|
||||
case SA110_CNTL_ROMWIDTH_16:
|
||||
dc21285_map.bankwidth = 2;
|
||||
dc21285_map.read = dc21285_read16;
|
||||
dc21285_map.write = dc21285_write16;
|
||||
dc21285_map.copy_to = dc21285_copy_to_16;
|
||||
break;
|
||||
case SA110_CNTL_ROMWIDTH_32:
|
||||
dc21285_map.bankwidth = 4;
|
||||
case SA110_CNTL_ROMWIDTH_32:
|
||||
dc21285_map.bankwidth = 4;
|
||||
dc21285_map.read = dc21285_read32;
|
||||
dc21285_map.write = dc21285_write32;
|
||||
dc21285_map.copy_to = dc21285_copy_to_32;
|
||||
|
@ -201,20 +201,20 @@ static int __init init_dc21285(void)
|
|||
if (!dc21285_mtd) {
|
||||
iounmap(dc21285_map.virt);
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
dc21285_mtd->owner = THIS_MODULE;
|
||||
|
||||
#ifdef CONFIG_MTD_PARTITIONS
|
||||
nrparts = parse_mtd_partitions(dc21285_mtd, probes, &dc21285_parts, 0);
|
||||
if (nrparts > 0)
|
||||
add_mtd_partitions(dc21285_mtd, dc21285_parts, nrparts);
|
||||
else
|
||||
#endif
|
||||
else
|
||||
#endif
|
||||
add_mtd_device(dc21285_mtd);
|
||||
|
||||
|
||||
if(machine_is_ebsa285()) {
|
||||
/*
|
||||
/*
|
||||
* Flash timing is determined with bits 19-16 of the
|
||||
* CSR_SA110_CNTL. The value is the number of wait cycles, or
|
||||
* 0 for 16 cycles (the default). Cycles are 20 ns.
|
||||
|
@ -227,7 +227,7 @@ static int __init init_dc21285(void)
|
|||
/* tristate time */
|
||||
*CSR_SA110_CNTL = ((*CSR_SA110_CNTL & ~0x0f000000) | (7 << 24));
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*
|
||||
* $Id: dilnetpc.c,v 1.17 2004/11/28 09:40:39 dwmw2 Exp $
|
||||
* $Id: dilnetpc.c,v 1.20 2005/11/07 11:14:26 gleixner Exp $
|
||||
*
|
||||
* The DIL/Net PC is a tiny embedded PC board made by SSV Embedded Systems
|
||||
* featuring the AMD Elan SC410 processor. There are two variants of this
|
||||
|
@ -272,13 +272,13 @@ static struct map_info dnpc_map = {
|
|||
|
||||
static struct mtd_partition partition_info[]=
|
||||
{
|
||||
{
|
||||
.name = "ADNP boot",
|
||||
.offset = 0,
|
||||
{
|
||||
.name = "ADNP boot",
|
||||
.offset = 0,
|
||||
.size = 0xf0000,
|
||||
},
|
||||
{
|
||||
.name = "ADNP system BIOS",
|
||||
{
|
||||
.name = "ADNP system BIOS",
|
||||
.offset = MTDPART_OFS_NXTBLK,
|
||||
.size = 0x10000,
|
||||
#ifdef DNPC_BIOS_BLOCKS_WRITEPROTECTED
|
||||
|
@ -291,7 +291,7 @@ static struct mtd_partition partition_info[]=
|
|||
.size = 0x2f0000,
|
||||
},
|
||||
{
|
||||
.name = "ADNP system BIOS entry",
|
||||
.name = "ADNP system BIOS entry",
|
||||
.offset = MTDPART_OFS_NXTBLK,
|
||||
.size = MTDPART_SIZ_FULL,
|
||||
#ifdef DNPC_BIOS_BLOCKS_WRITEPROTECTED
|
||||
|
@ -325,9 +325,9 @@ static struct mtd_info *merged_mtd;
|
|||
|
||||
static struct mtd_partition higlvl_partition_info[]=
|
||||
{
|
||||
{
|
||||
.name = "ADNP boot block",
|
||||
.offset = 0,
|
||||
{
|
||||
.name = "ADNP boot block",
|
||||
.offset = 0,
|
||||
.size = CONFIG_MTD_DILNETPC_BOOTSIZE,
|
||||
},
|
||||
{
|
||||
|
@ -335,8 +335,8 @@ static struct mtd_partition higlvl_partition_info[]=
|
|||
.offset = MTDPART_OFS_NXTBLK,
|
||||
.size = ADNP_WINDOW_SIZE-CONFIG_MTD_DILNETPC_BOOTSIZE-0x20000,
|
||||
},
|
||||
{
|
||||
.name = "ADNP system BIOS + BIOS Entry",
|
||||
{
|
||||
.name = "ADNP system BIOS + BIOS Entry",
|
||||
.offset = MTDPART_OFS_NXTBLK,
|
||||
.size = MTDPART_SIZ_FULL,
|
||||
#ifdef DNPC_BIOS_BLOCKS_WRITEPROTECTED
|
||||
|
@ -371,7 +371,7 @@ static int __init init_dnpc(void)
|
|||
|
||||
/*
|
||||
** determine hardware (DNP/ADNP/invalid)
|
||||
*/
|
||||
*/
|
||||
if((is_dnp = dnp_adnp_probe()) < 0)
|
||||
return -ENXIO;
|
||||
|
||||
|
@ -397,13 +397,13 @@ static int __init init_dnpc(void)
|
|||
++dnpc_map.name;
|
||||
for(i = 0; i < NUM_PARTITIONS; i++)
|
||||
++partition_info[i].name;
|
||||
higlvl_partition_info[1].size = DNP_WINDOW_SIZE -
|
||||
higlvl_partition_info[1].size = DNP_WINDOW_SIZE -
|
||||
CONFIG_MTD_DILNETPC_BOOTSIZE - 0x20000;
|
||||
for(i = 0; i < NUM_HIGHLVL_PARTITIONS; i++)
|
||||
++higlvl_partition_info[i].name;
|
||||
}
|
||||
|
||||
printk(KERN_NOTICE "DIL/Net %s flash: 0x%lx at 0x%lx\n",
|
||||
printk(KERN_NOTICE "DIL/Net %s flash: 0x%lx at 0x%lx\n",
|
||||
is_dnp ? "DNPC" : "ADNP", dnpc_map.size, dnpc_map.phys);
|
||||
|
||||
dnpc_map.virt = ioremap_nocache(dnpc_map.phys, dnpc_map.size);
|
||||
|
@ -436,7 +436,7 @@ static int __init init_dnpc(void)
|
|||
iounmap(dnpc_map.virt);
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
|
||||
mymtd->owner = THIS_MODULE;
|
||||
|
||||
/*
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
|
||||
/*
|
||||
* drivers/mtd/maps/svme182.c
|
||||
*
|
||||
*
|
||||
* Flash map driver for the Dy4 SVME182 board
|
||||
*
|
||||
* $Id: dmv182.c,v 1.5 2004/11/04 13:24:14 gleixner Exp $
|
||||
*
|
||||
* $Id: dmv182.c,v 1.6 2005/11/07 11:14:26 gleixner Exp $
|
||||
*
|
||||
* Copyright 2003-2004, TimeSys Corporation
|
||||
*
|
||||
|
@ -104,7 +104,7 @@ static int __init init_svme182(void)
|
|||
partitions = svme182_partitions;
|
||||
|
||||
svme182_map.virt = ioremap(FLASH_BASE_ADDR, svme182_map.size);
|
||||
|
||||
|
||||
if (svme182_map.virt == 0) {
|
||||
printk("Failed to ioremap FLASH memory area.\n");
|
||||
return -EIO;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* $Id: ebony.c,v 1.15 2004/12/09 18:39:54 holindho Exp $
|
||||
*
|
||||
* $Id: ebony.c,v 1.16 2005/11/07 11:14:26 gleixner Exp $
|
||||
*
|
||||
* Mapping for Ebony user flash
|
||||
*
|
||||
* Matt Porter <mporter@kernel.crashing.org>
|
||||
|
@ -85,7 +85,7 @@ int __init init_ebony(void)
|
|||
small_flash_base = EBONY_SMALL_FLASH_LOW2;
|
||||
else
|
||||
small_flash_base = EBONY_SMALL_FLASH_LOW1;
|
||||
|
||||
|
||||
if (EBONY_BOOT_SMALL_FLASH(fpga0_reg) &&
|
||||
!EBONY_ONBRD_FLASH_EN(fpga0_reg))
|
||||
large_flash_base = EBONY_LARGE_FLASH_LOW;
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
/*
|
||||
* $Id: edb7312.c,v 1.13 2004/11/04 13:24:14 gleixner Exp $
|
||||
* $Id: edb7312.c,v 1.14 2005/11/07 11:14:27 gleixner Exp $
|
||||
*
|
||||
* Handle mapping of the NOR flash on Cogent EDB7312 boards
|
||||
*
|
||||
* Copyright 2002 SYSGO Real-Time Solutions GmbH
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
|
@ -46,7 +46,7 @@ struct map_info edb7312nor_map = {
|
|||
#ifdef CONFIG_MTD_PARTITIONS
|
||||
|
||||
/*
|
||||
* MTD partitioning stuff
|
||||
* MTD partitioning stuff
|
||||
*/
|
||||
static struct mtd_partition static_partitions[3] =
|
||||
{
|
||||
|
@ -80,7 +80,7 @@ int __init init_edb7312nor(void)
|
|||
const char **type;
|
||||
const char *part_type = 0;
|
||||
|
||||
printk(KERN_NOTICE MSG_PREFIX "0x%08x at 0x%08x\n",
|
||||
printk(KERN_NOTICE MSG_PREFIX "0x%08x at 0x%08x\n",
|
||||
WINDOW_SIZE, WINDOW_ADDR);
|
||||
edb7312nor_map.virt = ioremap(WINDOW_ADDR, WINDOW_SIZE);
|
||||
|
||||
|
@ -88,7 +88,7 @@ int __init init_edb7312nor(void)
|
|||
printk(MSG_PREFIX "failed to ioremap\n");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
|
||||
simple_map_init(&edb7312nor_map);
|
||||
|
||||
mymtd = 0;
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
* Copyright (C) 2001 Altera Corporation
|
||||
* Copyright (C) 2001 Red Hat, Inc.
|
||||
*
|
||||
* $Id: epxa10db-flash.c,v 1.13 2004/11/04 13:24:14 gleixner Exp $
|
||||
* $Id: epxa10db-flash.c,v 1.15 2005/11/07 11:14:27 gleixner Exp $
|
||||
*
|
||||
* 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
|
||||
|
@ -62,7 +62,7 @@ static const char *probes[] = { "RedBoot", "afs", NULL };
|
|||
static int __init epxa_mtd_init(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
||||
printk(KERN_NOTICE "%s flash device: 0x%x at 0x%x\n", BOARD_NAME, FLASH_SIZE, FLASH_START);
|
||||
|
||||
epxa_map.virt = ioremap(FLASH_START, FLASH_SIZE);
|
||||
|
@ -126,8 +126,8 @@ static void __exit epxa_mtd_cleanup(void)
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
* This will do for now, once we decide which bootldr we're finally
|
||||
/*
|
||||
* This will do for now, once we decide which bootldr we're finally
|
||||
* going to use then we'll remove this function and do it properly
|
||||
*
|
||||
* Partions are currently (as offsets from base of flash):
|
||||
|
@ -140,7 +140,7 @@ static int __init epxa_default_partitions(struct mtd_info *master, struct mtd_pa
|
|||
struct mtd_partition *parts;
|
||||
int ret, i;
|
||||
int npartitions = 0;
|
||||
char *names;
|
||||
char *names;
|
||||
const char *name = "jffs";
|
||||
|
||||
printk("Using default partitions for %s\n",BOARD_NAME);
|
||||
|
@ -152,7 +152,7 @@ static int __init epxa_default_partitions(struct mtd_info *master, struct mtd_pa
|
|||
goto out;
|
||||
}
|
||||
i=0;
|
||||
names = (char *)&parts[npartitions];
|
||||
names = (char *)&parts[npartitions];
|
||||
parts[i].name = names;
|
||||
names += strlen(name) + 1;
|
||||
strcpy(parts[i].name, name);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* fortunet.c memory map
|
||||
*
|
||||
* $Id: fortunet.c,v 1.9 2004/11/04 13:24:14 gleixner Exp $
|
||||
* $Id: fortunet.c,v 1.11 2005/11/07 11:14:27 gleixner Exp $
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
|
@ -212,7 +212,7 @@ int __init init_fortunet(void)
|
|||
|
||||
map_regions[ix].map_info.phys = map_regions[ix].window_addr_physical,
|
||||
|
||||
map_regions[ix].map_info.virt =
|
||||
map_regions[ix].map_info.virt =
|
||||
ioremap_nocache(
|
||||
map_regions[ix].window_addr_physical,
|
||||
map_regions[ix].map_info.size);
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
/*
|
||||
* Flash memory access on Hynix GMS30C7201/HMS30C7202 based
|
||||
* Flash memory access on Hynix GMS30C7201/HMS30C7202 based
|
||||
* evaluation boards
|
||||
*
|
||||
* $Id: h720x-flash.c,v 1.11 2004/11/04 13:24:14 gleixner Exp $
|
||||
*
|
||||
* $Id: h720x-flash.c,v 1.12 2005/11/07 11:14:27 gleixner Exp $
|
||||
*
|
||||
* (C) 2002 Jungjun Kim <jungjun.kim@hynix.com>
|
||||
* 2003 Thomas Gleixner <tglx@linutronix.de>
|
||||
* 2003 Thomas Gleixner <tglx@linutronix.de>
|
||||
*/
|
||||
|
||||
#include <linux/config.h>
|
||||
|
@ -72,7 +72,7 @@ int __init h720x_mtd_init(void)
|
|||
{
|
||||
|
||||
char *part_type = NULL;
|
||||
|
||||
|
||||
h720x_map.virt = ioremap(FLASH_PHYS, FLASH_SIZE);
|
||||
|
||||
if (!h720x_map.virt) {
|
||||
|
@ -91,7 +91,7 @@ int __init h720x_mtd_init(void)
|
|||
h720x_map.bankwidth = 2;
|
||||
mymtd = do_map_probe("cfi_probe", &h720x_map);
|
||||
}
|
||||
|
||||
|
||||
if (mymtd) {
|
||||
mymtd->owner = THIS_MODULE;
|
||||
|
||||
|
@ -124,11 +124,11 @@ static void __exit h720x_mtd_cleanup(void)
|
|||
del_mtd_partitions(mymtd);
|
||||
map_destroy(mymtd);
|
||||
}
|
||||
|
||||
|
||||
/* Free partition info, if commandline partition was used */
|
||||
if (mtd_parts && (mtd_parts != h720x_partitions))
|
||||
kfree (mtd_parts);
|
||||
|
||||
|
||||
if (h720x_map.virt) {
|
||||
iounmap((void *)h720x_map.virt);
|
||||
h720x_map.virt = 0;
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* ichxrom.c
|
||||
*
|
||||
* Normal mappings of chips in physical memory
|
||||
* $Id: ichxrom.c,v 1.18 2005/07/07 10:26:20 dwmw2 Exp $
|
||||
* $Id: ichxrom.c,v 1.19 2005/11/07 11:14:27 gleixner Exp $
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
|
@ -101,7 +101,7 @@ static int __devinit ichxrom_init_one (struct pci_dev *pdev,
|
|||
* you can only really attach a FWH to an ICHX there
|
||||
* a number of simplifications you can make.
|
||||
*
|
||||
* Also you can page firmware hubs if an 8MB window isn't enough
|
||||
* Also you can page firmware hubs if an 8MB window isn't enough
|
||||
* but don't currently handle that case either.
|
||||
*/
|
||||
window->pdev = pdev;
|
||||
|
@ -144,7 +144,7 @@ static int __devinit ichxrom_init_one (struct pci_dev *pdev,
|
|||
window->phys = 0xfff00000;
|
||||
}
|
||||
else if ((byte & 0x80) == 0x80) {
|
||||
window->phys = 0xfff80000;
|
||||
window->phys = 0xfff80000;
|
||||
}
|
||||
|
||||
if (window->phys == 0) {
|
||||
|
@ -233,7 +233,7 @@ static int __devinit ichxrom_init_one (struct pci_dev *pdev,
|
|||
* in a factory setting. So in-place programming
|
||||
* needs to use a different method.
|
||||
*/
|
||||
for(map->map.bankwidth = 32; map->map.bankwidth;
|
||||
for(map->map.bankwidth = 32; map->map.bankwidth;
|
||||
map->map.bankwidth >>= 1)
|
||||
{
|
||||
char **probe_type;
|
||||
|
@ -286,7 +286,7 @@ static int __devinit ichxrom_init_one (struct pci_dev *pdev,
|
|||
for(i = 0; i < cfi->numchips; i++) {
|
||||
cfi->chips[i].start += offset;
|
||||
}
|
||||
|
||||
|
||||
/* Now that the mtd devices is complete claim and export it */
|
||||
map->mtd->owner = THIS_MODULE;
|
||||
if (add_mtd_device(map->mtd)) {
|
||||
|
@ -324,11 +324,11 @@ static void __devexit ichxrom_remove_one (struct pci_dev *pdev)
|
|||
}
|
||||
|
||||
static struct pci_device_id ichxrom_pci_tbl[] __devinitdata = {
|
||||
{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_0,
|
||||
{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_0,
|
||||
PCI_ANY_ID, PCI_ANY_ID, },
|
||||
{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_0,
|
||||
{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_0,
|
||||
PCI_ANY_ID, PCI_ANY_ID, },
|
||||
{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_0,
|
||||
{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_0,
|
||||
PCI_ANY_ID, PCI_ANY_ID, },
|
||||
{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0,
|
||||
PCI_ANY_ID, PCI_ANY_ID, },
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
/*
|
||||
* $Id: impa7.c,v 1.13 2004/11/04 13:24:14 gleixner Exp $
|
||||
* $Id: impa7.c,v 1.14 2005/11/07 11:14:27 gleixner Exp $
|
||||
*
|
||||
* Handle mapping of the NOR flash on implementa A7 boards
|
||||
*
|
||||
* Copyright 2002 SYSGO Real-Time Solutions GmbH
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
|
@ -55,7 +55,7 @@ static struct map_info impa7_map[NUM_FLASHBANKS] = {
|
|||
#ifdef CONFIG_MTD_PARTITIONS
|
||||
|
||||
/*
|
||||
* MTD partitioning stuff
|
||||
* MTD partitioning stuff
|
||||
*/
|
||||
static struct mtd_partition static_partitions[] =
|
||||
{
|
||||
|
@ -108,9 +108,9 @@ int __init init_impa7(void)
|
|||
impa7_mtd[i]->owner = THIS_MODULE;
|
||||
devicesfound++;
|
||||
#ifdef CONFIG_MTD_PARTITIONS
|
||||
mtd_parts_nb[i] = parse_mtd_partitions(impa7_mtd[i],
|
||||
mtd_parts_nb[i] = parse_mtd_partitions(impa7_mtd[i],
|
||||
probes,
|
||||
&mtd_parts[i],
|
||||
&mtd_parts[i],
|
||||
0);
|
||||
if (mtd_parts_nb[i] > 0) {
|
||||
part_type = "command line";
|
||||
|
@ -121,16 +121,16 @@ int __init init_impa7(void)
|
|||
}
|
||||
|
||||
printk(KERN_NOTICE MSG_PREFIX
|
||||
"using %s partition definition\n",
|
||||
"using %s partition definition\n",
|
||||
part_type);
|
||||
add_mtd_partitions(impa7_mtd[i],
|
||||
add_mtd_partitions(impa7_mtd[i],
|
||||
mtd_parts[i], mtd_parts_nb[i]);
|
||||
#else
|
||||
add_mtd_device(impa7_mtd[i]);
|
||||
|
||||
#endif
|
||||
}
|
||||
else
|
||||
else
|
||||
iounmap((void *)impa7_map[i].virt);
|
||||
}
|
||||
return devicesfound == 0 ? -ENXIO : 0;
|
||||
|
|
|
@ -1,28 +1,28 @@
|
|||
/*======================================================================
|
||||
|
||||
drivers/mtd/maps/integrator-flash.c: ARM Integrator flash map driver
|
||||
|
||||
|
||||
Copyright (C) 2000 ARM Limited
|
||||
Copyright (C) 2003 Deep Blue Solutions Ltd.
|
||||
|
||||
|
||||
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
This is access code for flashes using ARM's flash partitioning
|
||||
|
||||
This is access code for flashes using ARM's flash partitioning
|
||||
standards.
|
||||
|
||||
$Id: integrator-flash.c,v 1.18 2004/11/01 13:26:15 rmk Exp $
|
||||
$Id: integrator-flash.c,v 1.20 2005/11/07 11:14:27 gleixner Exp $
|
||||
|
||||
======================================================================*/
|
||||
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
/*
|
||||
* Flash memory access on iPAQ Handhelds (either SA1100 or PXA250 based)
|
||||
*
|
||||
*
|
||||
* (C) 2000 Nicolas Pitre <nico@cam.org>
|
||||
* (C) 2002 Hewlett-Packard Company <jamey.hicks@hp.com>
|
||||
* (C) 2003 Christian Pellegrin <chri@ascensit.com>, <chri@infis.univ.ts.it>: concatenation of multiple flashes
|
||||
*
|
||||
* $Id: ipaq-flash.c,v 1.3 2004/11/04 13:24:15 gleixner Exp $
|
||||
*
|
||||
* $Id: ipaq-flash.c,v 1.5 2005/11/07 11:14:27 gleixner Exp $
|
||||
*/
|
||||
|
||||
#include <linux/config.h>
|
||||
|
@ -107,7 +107,7 @@ static struct mtd_partition h3xxx_partitions[] = {
|
|||
#ifndef CONFIG_LAB
|
||||
mask_flags: MTD_WRITEABLE, /* force read-only */
|
||||
#endif
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "H3XXX root jffs2",
|
||||
#ifndef CONFIG_LAB
|
||||
|
@ -148,7 +148,7 @@ static DEFINE_SPINLOCK(ipaq_vpp_lock);
|
|||
static void h3xxx_set_vpp(struct map_info *map, int vpp)
|
||||
{
|
||||
static int nest = 0;
|
||||
|
||||
|
||||
spin_lock(&ipaq_vpp_lock);
|
||||
if (vpp)
|
||||
nest++;
|
||||
|
@ -191,7 +191,7 @@ static unsigned long cs_phys[] = {
|
|||
SA1100_CS3_PHYS,
|
||||
SA1100_CS4_PHYS,
|
||||
SA1100_CS5_PHYS,
|
||||
#else
|
||||
#else
|
||||
PXA_CS0_PHYS,
|
||||
PXA_CS1_PHYS,
|
||||
PXA_CS2_PHYS,
|
||||
|
@ -216,7 +216,7 @@ int __init ipaq_mtd_init(void)
|
|||
|
||||
/* Default flash bankwidth */
|
||||
// ipaq_map.bankwidth = (MSC0 & MSC_RBW) ? 2 : 4;
|
||||
|
||||
|
||||
if (machine_is_h1900())
|
||||
{
|
||||
/* For our intents, the h1900 is not a real iPAQ, so we special-case it. */
|
||||
|
@ -229,7 +229,7 @@ int __init ipaq_mtd_init(void)
|
|||
else
|
||||
for(i=0; i<MAX_IPAQ_CS; i++)
|
||||
ipaq_map[i].bankwidth = 4;
|
||||
|
||||
|
||||
/*
|
||||
* Static partition definition selection
|
||||
*/
|
||||
|
@ -309,7 +309,7 @@ int __init ipaq_mtd_init(void)
|
|||
return -ENXIO;
|
||||
} else
|
||||
printk(KERN_NOTICE "iPAQ flash: found %d bytes\n", my_sub_mtd[i]->size);
|
||||
|
||||
|
||||
/* do we really need this debugging? --joshua 20030703 */
|
||||
// printk("my_sub_mtd[%d]=%p\n", i, my_sub_mtd[i]);
|
||||
my_sub_mtd[i]->owner = THIS_MODULE;
|
||||
|
@ -333,11 +333,11 @@ int __init ipaq_mtd_init(void)
|
|||
#else
|
||||
mymtd = my_sub_mtd[0];
|
||||
|
||||
/*
|
||||
/*
|
||||
*In the very near future, command line partition parsing
|
||||
* will use the device name as 'mtd-id' instead of a value
|
||||
* passed to the parse_cmdline_partitions() routine. Since
|
||||
* the bootldr says 'ipaq', make sure it continues to work.
|
||||
* the bootldr says 'ipaq', make sure it continues to work.
|
||||
*/
|
||||
mymtd->name = "ipaq";
|
||||
|
||||
|
@ -385,7 +385,7 @@ int __init ipaq_mtd_init(void)
|
|||
*/
|
||||
|
||||
i = parse_mtd_partitions(mymtd, part_probes, &parsed_parts, 0);
|
||||
|
||||
|
||||
if (i > 0) {
|
||||
nb_parts = parsed_nr_parts = i;
|
||||
parts = parsed_parts;
|
||||
|
@ -423,10 +423,10 @@ static void __exit ipaq_mtd_cleanup(void)
|
|||
#endif
|
||||
map_destroy(mymtd);
|
||||
#ifdef CONFIG_MTD_CONCAT
|
||||
for(i=0; i<MAX_IPAQ_CS; i++)
|
||||
for(i=0; i<MAX_IPAQ_CS; i++)
|
||||
#else
|
||||
for(i=1; i<MAX_IPAQ_CS; i++)
|
||||
#endif
|
||||
for(i=1; i<MAX_IPAQ_CS; i++)
|
||||
#endif
|
||||
{
|
||||
if (my_sub_mtd[i])
|
||||
map_destroy(my_sub_mtd[i]);
|
||||
|
@ -444,14 +444,14 @@ static int __init h1900_special_case(void)
|
|||
ipaq_map[0].phys = 0x0;
|
||||
ipaq_map[0].virt = __ioremap(0x0, 0x04000000, 0, 1);
|
||||
ipaq_map[0].bankwidth = 2;
|
||||
|
||||
|
||||
printk(KERN_NOTICE "iPAQ flash: probing %d-bit flash bus, window=%lx with JEDEC.\n", ipaq_map[0].bankwidth*8, ipaq_map[0].virt);
|
||||
mymtd = do_map_probe("jedec_probe", &ipaq_map[0]);
|
||||
if (!mymtd)
|
||||
return -ENODEV;
|
||||
add_mtd_device(mymtd);
|
||||
printk(KERN_NOTICE "iPAQ flash: registered h1910 flash\n");
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
/*
|
||||
* $Id: iq80310.c,v 1.20 2004/11/04 13:24:15 gleixner Exp $
|
||||
* $Id: iq80310.c,v 1.21 2005/11/07 11:14:27 gleixner Exp $
|
||||
*
|
||||
* Mapping for the Intel XScale IQ80310 evaluation board
|
||||
*
|
||||
* Author: Nicolas Pitre
|
||||
* Copyright: (C) 2001 MontaVista Software Inc.
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* $Id: ixp2000.c,v 1.6 2005/03/18 14:07:46 gleixner Exp $
|
||||
* $Id: ixp2000.c,v 1.9 2005/11/07 11:14:27 gleixner Exp $
|
||||
*
|
||||
* drivers/mtd/maps/ixp2000.c
|
||||
*
|
||||
|
@ -14,7 +14,7 @@
|
|||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
|
@ -46,8 +46,8 @@ struct ixp2000_flash_info {
|
|||
};
|
||||
|
||||
static inline unsigned long flash_bank_setup(struct map_info *map, unsigned long ofs)
|
||||
{
|
||||
unsigned long (*set_bank)(unsigned long) =
|
||||
{
|
||||
unsigned long (*set_bank)(unsigned long) =
|
||||
(unsigned long(*)(unsigned long))map->map_priv_2;
|
||||
|
||||
return (set_bank ? set_bank(ofs) : ofs);
|
||||
|
@ -55,8 +55,8 @@ static inline unsigned long flash_bank_setup(struct map_info *map, unsigned long
|
|||
|
||||
#ifdef __ARMEB__
|
||||
/*
|
||||
* Rev A0 and A1 of IXP2400 silicon have a broken addressing unit which
|
||||
* causes the lower address bits to be XORed with 0x11 on 8 bit accesses
|
||||
* Rev A0 and A1 of IXP2400 silicon have a broken addressing unit which
|
||||
* causes the lower address bits to be XORed with 0x11 on 8 bit accesses
|
||||
* and XORed with 0x10 on 16 bit accesses. See the spec update, erratum 44.
|
||||
*/
|
||||
static int erratum44_workaround = 0;
|
||||
|
@ -90,7 +90,7 @@ static void ixp2000_flash_copy_from(struct map_info *map, void *to,
|
|||
unsigned long from, ssize_t len)
|
||||
{
|
||||
from = flash_bank_setup(map, from);
|
||||
while(len--)
|
||||
while(len--)
|
||||
*(__u8 *) to++ = *(__u8 *)(map->map_priv_1 + from++);
|
||||
}
|
||||
|
||||
|
@ -148,11 +148,11 @@ static int ixp2000_flash_probe(struct device *_dev)
|
|||
static const char *probes[] = { "RedBoot", "cmdlinepart", NULL };
|
||||
struct platform_device *dev = to_platform_device(_dev);
|
||||
struct ixp2000_flash_data *ixp_data = dev->dev.platform_data;
|
||||
struct flash_platform_data *plat;
|
||||
struct flash_platform_data *plat;
|
||||
struct ixp2000_flash_info *info;
|
||||
unsigned long window_size;
|
||||
int err = -1;
|
||||
|
||||
|
||||
if (!ixp_data)
|
||||
return -ENODEV;
|
||||
|
||||
|
@ -161,7 +161,7 @@ static int ixp2000_flash_probe(struct device *_dev)
|
|||
return -ENODEV;
|
||||
|
||||
window_size = dev->resource->end - dev->resource->start + 1;
|
||||
dev_info(_dev, "Probe of IXP2000 flash(%d banks x %dMiB)\n",
|
||||
dev_info(_dev, "Probe of IXP2000 flash(%d banks x %dMiB)\n",
|
||||
ixp_data->nr_banks, ((u32)window_size >> 20));
|
||||
|
||||
if (plat->width != 1) {
|
||||
|
@ -174,7 +174,7 @@ static int ixp2000_flash_probe(struct device *_dev)
|
|||
if(!info) {
|
||||
err = -ENOMEM;
|
||||
goto Error;
|
||||
}
|
||||
}
|
||||
memzero(info, sizeof(struct ixp2000_flash_info));
|
||||
|
||||
dev_set_drvdata(&dev->dev, info);
|
||||
|
@ -184,7 +184,7 @@ static int ixp2000_flash_probe(struct device *_dev)
|
|||
* not attempt to do a direct access on us.
|
||||
*/
|
||||
info->map.phys = NO_XIP;
|
||||
|
||||
|
||||
info->nr_banks = ixp_data->nr_banks;
|
||||
info->map.size = ixp_data->nr_banks * window_size;
|
||||
info->map.bankwidth = 1;
|
||||
|
@ -192,7 +192,7 @@ static int ixp2000_flash_probe(struct device *_dev)
|
|||
/*
|
||||
* map_priv_2 is used to store a ptr to to the bank_setup routine
|
||||
*/
|
||||
info->map.map_priv_2 = (void __iomem *) ixp_data->bank_setup;
|
||||
info->map.map_priv_2 = (unsigned long) ixp_data->bank_setup;
|
||||
|
||||
info->map.name = dev->dev.bus_id;
|
||||
info->map.read = ixp2000_flash_read8;
|
||||
|
@ -200,8 +200,8 @@ static int ixp2000_flash_probe(struct device *_dev)
|
|||
info->map.copy_from = ixp2000_flash_copy_from;
|
||||
info->map.copy_to = ixp2000_flash_copy_to;
|
||||
|
||||
info->res = request_mem_region(dev->resource->start,
|
||||
dev->resource->end - dev->resource->start + 1,
|
||||
info->res = request_mem_region(dev->resource->start,
|
||||
dev->resource->end - dev->resource->start + 1,
|
||||
dev->dev.bus_id);
|
||||
if (!info->res) {
|
||||
dev_err(_dev, "Could not reserve memory region\n");
|
||||
|
@ -209,7 +209,7 @@ static int ixp2000_flash_probe(struct device *_dev)
|
|||
goto Error;
|
||||
}
|
||||
|
||||
info->map.map_priv_1 = ioremap(dev->resource->start,
|
||||
info->map.map_priv_1 = (unsigned long) ioremap(dev->resource->start,
|
||||
dev->resource->end - dev->resource->start + 1);
|
||||
if (!info->map.map_priv_1) {
|
||||
dev_err(_dev, "Failed to ioremap flash region\n");
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* $Id: ixp4xx.c,v 1.7 2004/11/04 13:24:15 gleixner Exp $
|
||||
* $Id: ixp4xx.c,v 1.12 2005/11/07 11:14:27 gleixner Exp $
|
||||
*
|
||||
* drivers/mtd/maps/ixp4xx.c
|
||||
*
|
||||
|
@ -45,7 +45,7 @@
|
|||
static map_word ixp4xx_read16(struct map_info *map, unsigned long ofs)
|
||||
{
|
||||
map_word val;
|
||||
val.x[0] = *(__u16 *) (map->map_priv_1 + ofs);
|
||||
val.x[0] = le16_to_cpu(readw(map->virt + ofs));
|
||||
return val;
|
||||
}
|
||||
|
||||
|
@ -59,35 +59,35 @@ static void ixp4xx_copy_from(struct map_info *map, void *to,
|
|||
{
|
||||
int i;
|
||||
u8 *dest = (u8 *) to;
|
||||
u16 *src = (u16 *) (map->map_priv_1 + from);
|
||||
void __iomem *src = map->virt + from;
|
||||
u16 data;
|
||||
|
||||
for (i = 0; i < (len / 2); i++) {
|
||||
data = src[i];
|
||||
data = le16_to_cpu(readw(src + 2*i));
|
||||
dest[i * 2] = BYTE0(data);
|
||||
dest[i * 2 + 1] = BYTE1(data);
|
||||
}
|
||||
|
||||
if (len & 1)
|
||||
dest[len - 1] = BYTE0(src[i]);
|
||||
dest[len - 1] = BYTE0(le16_to_cpu(readw(src + 2*i)));
|
||||
}
|
||||
|
||||
/*
|
||||
/*
|
||||
* Unaligned writes are ignored, causing the 8-bit
|
||||
* probe to fail and proceed to the 16-bit probe (which succeeds).
|
||||
*/
|
||||
static void ixp4xx_probe_write16(struct map_info *map, map_word d, unsigned long adr)
|
||||
{
|
||||
if (!(adr & 1))
|
||||
*(__u16 *) (map->map_priv_1 + adr) = d.x[0];
|
||||
writew(cpu_to_le16(d.x[0]), map->virt + adr);
|
||||
}
|
||||
|
||||
/*
|
||||
/*
|
||||
* Fast write16 function without the probing check above
|
||||
*/
|
||||
static void ixp4xx_write16(struct map_info *map, map_word d, unsigned long adr)
|
||||
{
|
||||
*(__u16 *) (map->map_priv_1 + adr) = d.x[0];
|
||||
writew(cpu_to_le16(d.x[0]), map->virt + adr);
|
||||
}
|
||||
|
||||
struct ixp4xx_flash_info {
|
||||
|
@ -104,25 +104,18 @@ static int ixp4xx_flash_remove(struct device *_dev)
|
|||
struct platform_device *dev = to_platform_device(_dev);
|
||||
struct flash_platform_data *plat = dev->dev.platform_data;
|
||||
struct ixp4xx_flash_info *info = dev_get_drvdata(&dev->dev);
|
||||
map_word d;
|
||||
|
||||
dev_set_drvdata(&dev->dev, NULL);
|
||||
|
||||
if(!info)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* This is required for a soft reboot to work.
|
||||
*/
|
||||
d.x[0] = 0xff;
|
||||
ixp4xx_write16(&info->map, d, 0x55 * 0x2);
|
||||
|
||||
if (info->mtd) {
|
||||
del_mtd_partitions(info->mtd);
|
||||
map_destroy(info->mtd);
|
||||
}
|
||||
if (info->map.map_priv_1)
|
||||
iounmap((void *) info->map.map_priv_1);
|
||||
if (info->map.virt)
|
||||
iounmap(info->map.virt);
|
||||
|
||||
kfree(info->partitions);
|
||||
|
||||
|
@ -134,9 +127,6 @@ static int ixp4xx_flash_remove(struct device *_dev)
|
|||
if (plat->exit)
|
||||
plat->exit();
|
||||
|
||||
/* Disable flash write */
|
||||
*IXP4XX_EXP_CS0 &= ~IXP4XX_FLASH_WRITABLE;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -160,17 +150,11 @@ static int ixp4xx_flash_probe(struct device *_dev)
|
|||
if(!info) {
|
||||
err = -ENOMEM;
|
||||
goto Error;
|
||||
}
|
||||
}
|
||||
memzero(info, sizeof(struct ixp4xx_flash_info));
|
||||
|
||||
dev_set_drvdata(&dev->dev, info);
|
||||
|
||||
/*
|
||||
* Enable flash write
|
||||
* TODO: Move this out to board specific code
|
||||
*/
|
||||
*IXP4XX_EXP_CS0 |= IXP4XX_FLASH_WRITABLE;
|
||||
|
||||
/*
|
||||
* Tell the MTD layer we're not 1:1 mapped so that it does
|
||||
* not attempt to do a direct access on us.
|
||||
|
@ -189,8 +173,8 @@ static int ixp4xx_flash_probe(struct device *_dev)
|
|||
info->map.write = ixp4xx_probe_write16,
|
||||
info->map.copy_from = ixp4xx_copy_from,
|
||||
|
||||
info->res = request_mem_region(dev->resource->start,
|
||||
dev->resource->end - dev->resource->start + 1,
|
||||
info->res = request_mem_region(dev->resource->start,
|
||||
dev->resource->end - dev->resource->start + 1,
|
||||
"IXP4XXFlash");
|
||||
if (!info->res) {
|
||||
printk(KERN_ERR "IXP4XXFlash: Could not reserve memory region\n");
|
||||
|
@ -198,9 +182,9 @@ static int ixp4xx_flash_probe(struct device *_dev)
|
|||
goto Error;
|
||||
}
|
||||
|
||||
info->map.map_priv_1 = ioremap(dev->resource->start,
|
||||
dev->resource->end - dev->resource->start + 1);
|
||||
if (!info->map.map_priv_1) {
|
||||
info->map.virt = ioremap(dev->resource->start,
|
||||
dev->resource->end - dev->resource->start + 1);
|
||||
if (!info->map.virt) {
|
||||
printk(KERN_ERR "IXP4XXFlash: Failed to ioremap region\n");
|
||||
err = -EIO;
|
||||
goto Error;
|
||||
|
@ -213,7 +197,7 @@ static int ixp4xx_flash_probe(struct device *_dev)
|
|||
goto Error;
|
||||
}
|
||||
info->mtd->owner = THIS_MODULE;
|
||||
|
||||
|
||||
/* Use the fast version */
|
||||
info->map.write = ixp4xx_write16,
|
||||
|
||||
|
@ -258,4 +242,3 @@ module_exit(ixp4xx_flash_exit);
|
|||
MODULE_LICENSE("GPL");
|
||||
MODULE_DESCRIPTION("MTD map driver for Intel IXP4xx systems");
|
||||
MODULE_AUTHOR("Deepak Saxena");
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* $Id: l440gx.c,v 1.17 2004/11/28 09:40:39 dwmw2 Exp $
|
||||
* $Id: l440gx.c,v 1.18 2005/11/07 11:14:27 gleixner Exp $
|
||||
*
|
||||
* BIOS Flash chip on Intel 440GX board.
|
||||
*
|
||||
|
@ -49,7 +49,7 @@ static struct map_info l440gx_map = {
|
|||
.bankwidth = BUSWIDTH,
|
||||
.phys = WINDOW_ADDR,
|
||||
#if 0
|
||||
/* FIXME verify that this is the
|
||||
/* FIXME verify that this is the
|
||||
* appripriate code for vpp enable/disable
|
||||
*/
|
||||
.set_vpp = l440gx_set_vpp
|
||||
|
@ -62,10 +62,10 @@ static int __init init_l440gx(void)
|
|||
struct resource *pm_iobase;
|
||||
__u16 word;
|
||||
|
||||
dev = pci_find_device(PCI_VENDOR_ID_INTEL,
|
||||
dev = pci_find_device(PCI_VENDOR_ID_INTEL,
|
||||
PCI_DEVICE_ID_INTEL_82371AB_0, NULL);
|
||||
|
||||
pm_dev = pci_find_device(PCI_VENDOR_ID_INTEL,
|
||||
pm_dev = pci_find_device(PCI_VENDOR_ID_INTEL,
|
||||
PCI_DEVICE_ID_INTEL_82371AB_3, NULL);
|
||||
|
||||
if (!dev || !pm_dev) {
|
||||
|
@ -82,10 +82,10 @@ static int __init init_l440gx(void)
|
|||
simple_map_init(&l440gx_map);
|
||||
printk(KERN_NOTICE "window_addr = 0x%08lx\n", (unsigned long)l440gx_map.virt);
|
||||
|
||||
/* Setup the pm iobase resource
|
||||
/* Setup the pm iobase resource
|
||||
* This code should move into some kind of generic bridge
|
||||
* driver but for the moment I'm content with getting the
|
||||
* allocation correct.
|
||||
* allocation correct.
|
||||
*/
|
||||
pm_iobase = &pm_dev->resource[PIIXE_IOBASE_RESOURCE];
|
||||
if (!(pm_iobase->flags & IORESOURCE_IO)) {
|
||||
|
@ -110,7 +110,7 @@ static int __init init_l440gx(void)
|
|||
/* Set the iobase */
|
||||
iobase = pm_iobase->start;
|
||||
pci_write_config_dword(pm_dev, 0x40, iobase | 1);
|
||||
|
||||
|
||||
|
||||
/* Set XBCS# */
|
||||
pci_read_config_word(dev, 0x4e, &word);
|
||||
|
@ -122,7 +122,7 @@ static int __init init_l440gx(void)
|
|||
|
||||
/* Enable the gate on the WE line */
|
||||
outb(inb(TRIBUF_PORT) & ~1, TRIBUF_PORT);
|
||||
|
||||
|
||||
printk(KERN_NOTICE "Enabled WE line to L440GX BIOS flash chip.\n");
|
||||
|
||||
mymtd = do_map_probe("jedec_probe", &l440gx_map);
|
||||
|
@ -145,7 +145,7 @@ static void __exit cleanup_l440gx(void)
|
|||
{
|
||||
del_mtd_device(mymtd);
|
||||
map_destroy(mymtd);
|
||||
|
||||
|
||||
iounmap(l440gx_map.virt);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
/*
|
||||
* $Id: lubbock-flash.c,v 1.19 2004/11/04 13:24:15 gleixner Exp $
|
||||
* $Id: lubbock-flash.c,v 1.21 2005/11/07 11:14:27 gleixner Exp $
|
||||
*
|
||||
* Map driver for the Lubbock developer platform.
|
||||
*
|
||||
* Author: Nicolas Pitre
|
||||
* Copyright: (C) 2001 MontaVista Software Inc.
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
|
@ -76,7 +76,7 @@ static int __init init_lubbock(void)
|
|||
int flashboot = (LUB_CONF_SWITCHES & 1);
|
||||
int ret = 0, i;
|
||||
|
||||
lubbock_maps[0].bankwidth = lubbock_maps[1].bankwidth =
|
||||
lubbock_maps[0].bankwidth = lubbock_maps[1].bankwidth =
|
||||
(BOOT_DEF & 1) ? 2 : 4;
|
||||
|
||||
/* Compensate for the nROMBT switch which swaps the flash banks */
|
||||
|
@ -100,11 +100,11 @@ static int __init init_lubbock(void)
|
|||
simple_map_init(&lubbock_maps[i]);
|
||||
|
||||
printk(KERN_NOTICE "Probing %s at physical address 0x%08lx (%d-bit bankwidth)\n",
|
||||
lubbock_maps[i].name, lubbock_maps[i].phys,
|
||||
lubbock_maps[i].name, lubbock_maps[i].phys,
|
||||
lubbock_maps[i].bankwidth * 8);
|
||||
|
||||
mymtds[i] = do_map_probe("cfi_probe", &lubbock_maps[i]);
|
||||
|
||||
|
||||
if (!mymtds[i]) {
|
||||
iounmap((void *)lubbock_maps[i].virt);
|
||||
if (lubbock_maps[i].cached)
|
||||
|
@ -124,7 +124,7 @@ static int __init init_lubbock(void)
|
|||
|
||||
if (!mymtds[0] && !mymtds[1])
|
||||
return ret;
|
||||
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
if (!mymtds[i]) {
|
||||
printk(KERN_WARNING "%s is absent. Skipping\n", lubbock_maps[i].name);
|
||||
|
@ -151,7 +151,7 @@ static void __exit cleanup_lubbock(void)
|
|||
if (nr_parsed_parts[i] || !i)
|
||||
del_mtd_partitions(mymtds[i]);
|
||||
else
|
||||
del_mtd_device(mymtds[i]);
|
||||
del_mtd_device(mymtds[i]);
|
||||
|
||||
map_destroy(mymtds[i]);
|
||||
iounmap((void *)lubbock_maps[i].virt);
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
*
|
||||
* Author: Nicolas Pitre
|
||||
* Copyright: (C) 2001 MontaVista Software Inc.
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
|
@ -91,27 +91,27 @@ static int __init init_mainstone(void)
|
|||
mainstone_maps[i].virt = ioremap(mainstone_maps[i].phys,
|
||||
WINDOW_SIZE);
|
||||
if (!mainstone_maps[i].virt) {
|
||||
printk(KERN_WARNING "Failed to ioremap %s\n",
|
||||
printk(KERN_WARNING "Failed to ioremap %s\n",
|
||||
mainstone_maps[i].name);
|
||||
if (!ret)
|
||||
ret = -ENOMEM;
|
||||
continue;
|
||||
}
|
||||
mainstone_maps[i].cached =
|
||||
mainstone_maps[i].cached =
|
||||
ioremap_cached(mainstone_maps[i].phys, WINDOW_SIZE);
|
||||
if (!mainstone_maps[i].cached)
|
||||
printk(KERN_WARNING "Failed to ioremap cached %s\n",
|
||||
mainstone_maps[i].name);
|
||||
simple_map_init(&mainstone_maps[i]);
|
||||
|
||||
printk(KERN_NOTICE
|
||||
printk(KERN_NOTICE
|
||||
"Probing %s at physical address 0x%08lx"
|
||||
" (%d-bit bankwidth)\n",
|
||||
mainstone_maps[i].name, mainstone_maps[i].phys,
|
||||
mainstone_maps[i].name, mainstone_maps[i].phys,
|
||||
mainstone_maps[i].bankwidth * 8);
|
||||
|
||||
mymtds[i] = do_map_probe("cfi_probe", &mainstone_maps[i]);
|
||||
|
||||
|
||||
if (!mymtds[i]) {
|
||||
iounmap((void *)mainstone_maps[i].virt);
|
||||
if (mainstone_maps[i].cached)
|
||||
|
@ -131,21 +131,21 @@ static int __init init_mainstone(void)
|
|||
|
||||
if (!mymtds[0] && !mymtds[1])
|
||||
return ret;
|
||||
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
if (!mymtds[i]) {
|
||||
printk(KERN_WARNING "%s is absent. Skipping\n",
|
||||
printk(KERN_WARNING "%s is absent. Skipping\n",
|
||||
mainstone_maps[i].name);
|
||||
} else if (nr_parsed_parts[i]) {
|
||||
add_mtd_partitions(mymtds[i], parsed_parts[i],
|
||||
add_mtd_partitions(mymtds[i], parsed_parts[i],
|
||||
nr_parsed_parts[i]);
|
||||
} else if (!i) {
|
||||
printk("Using static partitions on %s\n",
|
||||
mainstone_maps[i].name);
|
||||
add_mtd_partitions(mymtds[i], mainstone_partitions,
|
||||
add_mtd_partitions(mymtds[i], mainstone_partitions,
|
||||
ARRAY_SIZE(mainstone_partitions));
|
||||
} else {
|
||||
printk("Registering %s as whole device\n",
|
||||
printk("Registering %s as whole device\n",
|
||||
mainstone_maps[i].name);
|
||||
add_mtd_device(mymtds[i]);
|
||||
}
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
/*
|
||||
* $Id: mbx860.c,v 1.8 2004/11/04 13:24:15 gleixner Exp $
|
||||
* $Id: mbx860.c,v 1.9 2005/11/07 11:14:27 gleixner Exp $
|
||||
*
|
||||
* Handle mapping of the flash on MBX860 boards
|
||||
*
|
||||
* Author: Anton Todorov
|
||||
* Copyright: (C) 2001 Emness Technology
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
|
@ -46,7 +46,7 @@ static struct mtd_partition partition_info[]={
|
|||
{ .name = "MBX flash APPLICATION partition",
|
||||
.offset = (BOOT_PARTITION_SIZE_KiB+KERNEL_PARTITION_SIZE_KiB)*1024 }
|
||||
};
|
||||
|
||||
|
||||
|
||||
static struct mtd_info *mymtd;
|
||||
|
||||
|
|
96
drivers/mtd/maps/mtx-1_flash.c
Normal file
96
drivers/mtd/maps/mtx-1_flash.c
Normal file
|
@ -0,0 +1,96 @@
|
|||
/*
|
||||
* Flash memory access on 4G Systems MTX-1 boards
|
||||
*
|
||||
* $Id: mtx-1_flash.c,v 1.2 2005/11/07 11:14:27 gleixner Exp $
|
||||
*
|
||||
* (C) 2005 Bruno Randolf <bruno.randolf@4g-systems.biz>
|
||||
* (C) 2005 Jörn Engel <joern@wohnheim.fh-wedel.de>
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/config.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/kernel.h>
|
||||
|
||||
#include <linux/mtd/mtd.h>
|
||||
#include <linux/mtd/map.h>
|
||||
#include <linux/mtd/partitions.h>
|
||||
|
||||
#include <asm/io.h>
|
||||
|
||||
static struct map_info mtx1_map = {
|
||||
.name = "MTX-1 flash",
|
||||
.bankwidth = 4,
|
||||
.size = 0x2000000,
|
||||
.phys = 0x1E000000,
|
||||
};
|
||||
|
||||
static struct mtd_partition mtx1_partitions[] = {
|
||||
{
|
||||
.name = "filesystem",
|
||||
.size = 0x01C00000,
|
||||
.offset = 0,
|
||||
},{
|
||||
.name = "yamon",
|
||||
.size = 0x00100000,
|
||||
.offset = MTDPART_OFS_APPEND,
|
||||
.mask_flags = MTD_WRITEABLE,
|
||||
},{
|
||||
.name = "kernel",
|
||||
.size = 0x002c0000,
|
||||
.offset = MTDPART_OFS_APPEND,
|
||||
},{
|
||||
.name = "yamon env",
|
||||
.size = 0x00040000,
|
||||
.offset = MTDPART_OFS_APPEND,
|
||||
}
|
||||
};
|
||||
|
||||
static struct mtd_info *mtx1_mtd;
|
||||
|
||||
int __init mtx1_mtd_init(void)
|
||||
{
|
||||
int ret = -ENXIO;
|
||||
|
||||
simple_map_init(&mtx1_map);
|
||||
|
||||
mtx1_map.virt = ioremap(mtx1_map.phys, mtx1_map.size);
|
||||
if (!mtx1_map.virt)
|
||||
return -EIO;
|
||||
|
||||
mtx1_mtd = do_map_probe("cfi_probe", &mtx1_map);
|
||||
if (!mtx1_mtd)
|
||||
goto err;
|
||||
|
||||
mtx1_mtd->owner = THIS_MODULE;
|
||||
|
||||
ret = add_mtd_partitions(mtx1_mtd, mtx1_partitions,
|
||||
ARRAY_SIZE(mtx1_partitions));
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
return 0;
|
||||
|
||||
err:
|
||||
iounmap(mtx1_map.virt);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void __exit mtx1_mtd_cleanup(void)
|
||||
{
|
||||
if (mtx1_mtd) {
|
||||
del_mtd_partitions(mtx1_mtd);
|
||||
map_destroy(mtx1_mtd);
|
||||
}
|
||||
if (mtx1_map.virt)
|
||||
iounmap(mtx1_map.virt);
|
||||
}
|
||||
|
||||
module_init(mtx1_mtd_init);
|
||||
module_exit(mtx1_mtd_cleanup);
|
||||
|
||||
MODULE_AUTHOR("Bruno Randolf <bruno.randolf@4g-systems.biz>");
|
||||
MODULE_DESCRIPTION("MTX-1 flash map");
|
||||
MODULE_LICENSE("GPL");
|
|
@ -3,7 +3,7 @@
|
|||
* Copyright (C) 2001 Mark Langsdorf (mark.langsdorf@amd.com)
|
||||
* based on sc520cdp.c by Sysgo Real-Time Solutions GmbH
|
||||
*
|
||||
* $Id: netsc520.c,v 1.13 2004/11/28 09:40:40 dwmw2 Exp $
|
||||
* $Id: netsc520.c,v 1.14 2005/11/07 11:14:27 gleixner Exp $
|
||||
*
|
||||
* 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
|
||||
|
@ -38,7 +38,7 @@
|
|||
** The single, 16 megabyte flash bank is divided into four virtual
|
||||
** partitions. The first partition is 768 KiB and is intended to
|
||||
** store the kernel image loaded by the bootstrap loader. The second
|
||||
** partition is 256 KiB and holds the BIOS image. The third
|
||||
** partition is 256 KiB and holds the BIOS image. The third
|
||||
** partition is 14.5 MiB and is intended for the flash file system
|
||||
** image. The last partition is 512 KiB and contains another copy
|
||||
** of the BIOS image and the reset vector.
|
||||
|
@ -51,28 +51,28 @@
|
|||
** recoverable afterwards.
|
||||
*/
|
||||
|
||||
/* partition_info gives details on the logical partitions that the split the
|
||||
/* partition_info gives details on the logical partitions that the split the
|
||||
* single flash device into. If the size if zero we use up to the end of the
|
||||
* device. */
|
||||
static struct mtd_partition partition_info[]={
|
||||
{
|
||||
.name = "NetSc520 boot kernel",
|
||||
.offset = 0,
|
||||
{
|
||||
.name = "NetSc520 boot kernel",
|
||||
.offset = 0,
|
||||
.size = 0xc0000
|
||||
},
|
||||
{
|
||||
.name = "NetSc520 Low BIOS",
|
||||
.offset = 0xc0000,
|
||||
{
|
||||
.name = "NetSc520 Low BIOS",
|
||||
.offset = 0xc0000,
|
||||
.size = 0x40000
|
||||
},
|
||||
{
|
||||
.name = "NetSc520 file system",
|
||||
.offset = 0x100000,
|
||||
{
|
||||
.name = "NetSc520 file system",
|
||||
.offset = 0x100000,
|
||||
.size = 0xe80000
|
||||
},
|
||||
{
|
||||
.name = "NetSc520 High BIOS",
|
||||
.offset = 0xf80000,
|
||||
{
|
||||
.name = "NetSc520 High BIOS",
|
||||
.offset = 0xf80000,
|
||||
.size = 0x80000
|
||||
},
|
||||
};
|
||||
|
@ -114,7 +114,7 @@ static int __init init_netsc520(void)
|
|||
iounmap(netsc520_map.virt);
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
|
||||
mymtd->owner = THIS_MODULE;
|
||||
add_mtd_partitions( mymtd, partition_info, NUM_PARTITIONS );
|
||||
return 0;
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
* (C) Copyright 2000-2001, Greg Ungerer (gerg@snapgear.com)
|
||||
* (C) Copyright 2001-2002, SnapGear (www.snapgear.com)
|
||||
*
|
||||
* $Id: nettel.c,v 1.10 2005/01/05 17:11:29 dwmw2 Exp $
|
||||
* $Id: nettel.c,v 1.11 2005/11/07 11:14:27 gleixner Exp $
|
||||
*/
|
||||
|
||||
/****************************************************************************/
|
||||
|
@ -143,7 +143,7 @@ static int nettel_reboot_notifier(struct notifier_block *nb, unsigned long val,
|
|||
{
|
||||
struct cfi_private *cfi = nettel_intel_map.fldrv_priv;
|
||||
unsigned long b;
|
||||
|
||||
|
||||
/* Make sure all FLASH chips are put back into read mode */
|
||||
for (b = 0; (b < nettel_intel_partitions[3].size); b += 0x100000) {
|
||||
cfi_send_gen_cmd(0xff, 0x55, b, &nettel_intel_map, cfi,
|
||||
|
@ -199,7 +199,7 @@ int nettel_eraseconfig(void)
|
|||
|
||||
schedule(); /* Wait for erase to finish. */
|
||||
remove_wait_queue(&wait_q, &wait);
|
||||
|
||||
|
||||
put_mtd_device(mtd);
|
||||
}
|
||||
|
||||
|
@ -430,7 +430,7 @@ int __init nettel_init(void)
|
|||
nettel_intel_partitions[1].size = (intel0size + intel1size) -
|
||||
(1024*1024 + intel_mtd->erasesize);
|
||||
nettel_intel_partitions[3].size = intel0size + intel1size;
|
||||
nettel_intel_partitions[4].offset =
|
||||
nettel_intel_partitions[4].offset =
|
||||
(intel0size + intel1size) - intel_mtd->erasesize;
|
||||
nettel_intel_partitions[4].size = intel_mtd->erasesize;
|
||||
nettel_intel_partitions[5].offset =
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* $Id: ocelot.c,v 1.16 2005/01/05 18:05:13 dwmw2 Exp $
|
||||
* $Id: ocelot.c,v 1.17 2005/11/07 11:14:27 gleixner Exp $
|
||||
*
|
||||
* Flash on Momenco Ocelot
|
||||
*/
|
||||
|
@ -31,7 +31,7 @@ static void ocelot_ram_write(struct mtd_info *mtd, loff_t to, size_t len, size_t
|
|||
struct map_info *map = mtd->priv;
|
||||
size_t done = 0;
|
||||
|
||||
/* If we use memcpy, it does word-wide writes. Even though we told the
|
||||
/* If we use memcpy, it does word-wide writes. Even though we told the
|
||||
GT64120A that it's an 8-bit wide region, word-wide writes don't work.
|
||||
We end up just writing the first byte of the four to all four bytes.
|
||||
So we have this loop instead */
|
||||
|
@ -68,7 +68,7 @@ static int __init init_ocelot_maps(void)
|
|||
int nr_parts;
|
||||
unsigned char brd_status;
|
||||
|
||||
printk(KERN_INFO "Momenco Ocelot MTD mappings: Flash 0x%x at 0x%x, NVRAM 0x%x at 0x%x\n",
|
||||
printk(KERN_INFO "Momenco Ocelot MTD mappings: Flash 0x%x at 0x%x, NVRAM 0x%x at 0x%x\n",
|
||||
FLASH_WINDOW_SIZE, FLASH_WINDOW_ADDR, NVRAM_WINDOW_SIZE, NVRAM_WINDOW_ADDR);
|
||||
|
||||
/* First check whether the flash jumper is present */
|
||||
|
@ -138,8 +138,8 @@ static int __init init_ocelot_maps(void)
|
|||
add_mtd_device(flash_mtd);
|
||||
|
||||
return 0;
|
||||
|
||||
fail3:
|
||||
|
||||
fail3:
|
||||
iounmap((void *)ocelot_flash_map.virt);
|
||||
if (ocelot_flash_map.cached)
|
||||
iounmap((void *)ocelot_flash_map.cached);
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
// $Id: octagon-5066.c,v 1.26 2004/07/12 22:38:29 dwmw2 Exp $
|
||||
// $Id: octagon-5066.c,v 1.28 2005/11/07 11:14:27 gleixner Exp $
|
||||
/* ######################################################################
|
||||
|
||||
Octagon 5066 MTD Driver.
|
||||
|
||||
Octagon 5066 MTD Driver.
|
||||
|
||||
The Octagon 5066 is a SBC based on AMD's 586-WB running at 133 MHZ. It
|
||||
comes with a builtin AMD 29F016 flash chip and a socketed EEPROM that
|
||||
is replacable by flash. Both units are mapped through a multiplexer
|
||||
into a 32k memory window at 0xe8000. The control register for the
|
||||
into a 32k memory window at 0xe8000. The control register for the
|
||||
multiplexing unit is located at IO 0x208 with a bit map of
|
||||
0-5 Page Selection in 32k increments
|
||||
6-7 Device selection:
|
||||
|
@ -14,14 +14,14 @@
|
|||
01 SSD 0 (Socket)
|
||||
10 SSD 1 (Flash chip)
|
||||
11 undefined
|
||||
|
||||
|
||||
On each SSD, the first 128k is reserved for use by the bios
|
||||
(actually it IS the bios..) This only matters if you are booting off the
|
||||
(actually it IS the bios..) This only matters if you are booting off the
|
||||
flash, you must not put a file system starting there.
|
||||
|
||||
|
||||
The driver tries to do a detection algorithm to guess what sort of devices
|
||||
are plugged into the sockets.
|
||||
|
||||
|
||||
##################################################################### */
|
||||
|
||||
#include <linux/module.h>
|
||||
|
@ -56,7 +56,7 @@ static void __oct5066_page(struct map_info *map, __u8 byte)
|
|||
static inline void oct5066_page(struct map_info *map, unsigned long ofs)
|
||||
{
|
||||
__u8 byte = map->map_priv_1 | (ofs >> WINDOW_SHIFT);
|
||||
|
||||
|
||||
if (page_n_dev != byte)
|
||||
__oct5066_page(map, byte);
|
||||
}
|
||||
|
@ -78,7 +78,7 @@ static void oct5066_copy_from(struct map_info *map, void *to, unsigned long from
|
|||
unsigned long thislen = len;
|
||||
if (len > (WINDOW_LENGTH - (from & WINDOW_MASK)))
|
||||
thislen = WINDOW_LENGTH-(from & WINDOW_MASK);
|
||||
|
||||
|
||||
spin_lock(&oct5066_spin);
|
||||
oct5066_page(map, from);
|
||||
memcpy_fromio(to, iomapadr + from, thislen);
|
||||
|
@ -103,7 +103,7 @@ static void oct5066_copy_to(struct map_info *map, unsigned long to, const void *
|
|||
unsigned long thislen = len;
|
||||
if (len > (WINDOW_LENGTH - (to & WINDOW_MASK)))
|
||||
thislen = WINDOW_LENGTH-(to & WINDOW_MASK);
|
||||
|
||||
|
||||
spin_lock(&oct5066_spin);
|
||||
oct5066_page(map, to);
|
||||
memcpy_toio(iomapadr + to, from, thislen);
|
||||
|
@ -144,7 +144,7 @@ static struct mtd_info *oct5066_mtd[2] = {NULL, NULL};
|
|||
// OctProbe - Sense if this is an octagon card
|
||||
// ---------------------------------------------------------------------
|
||||
/* Perform a simple validity test, we map the window select SSD0 and
|
||||
change pages while monitoring the window. A change in the window,
|
||||
change pages while monitoring the window. A change in the window,
|
||||
controlled by the PAGE_IO port is a functioning 5066 board. This will
|
||||
fail if the thing in the socket is set to a uniform value. */
|
||||
static int __init OctProbe(void)
|
||||
|
@ -161,13 +161,13 @@ static int __init OctProbe(void)
|
|||
Values[I%10] = readl(iomapadr);
|
||||
if (I > 0 && Values[I%10] == Values[0])
|
||||
return -EAGAIN;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Make sure we get the same values on the second pass
|
||||
if (Values[I%10] != readl(iomapadr))
|
||||
return -EAGAIN;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -207,11 +207,11 @@ int __init init_oct5066(void)
|
|||
ret = -EAGAIN;
|
||||
goto out_unmap;
|
||||
}
|
||||
|
||||
|
||||
// Print out our little header..
|
||||
printk("Octagon 5066 SSD IO:0x%x MEM:0x%x-0x%x\n",PAGE_IO,WINDOW_START,
|
||||
WINDOW_START+WINDOW_LENGTH);
|
||||
|
||||
|
||||
for (i=0; i<2; i++) {
|
||||
oct5066_mtd[i] = do_map_probe("cfi_probe", &oct5066_map[i]);
|
||||
if (!oct5066_mtd[i])
|
||||
|
@ -225,11 +225,11 @@ int __init init_oct5066(void)
|
|||
add_mtd_device(oct5066_mtd[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!oct5066_mtd[0] && !oct5066_mtd[1]) {
|
||||
cleanup_oct5066();
|
||||
return -ENXIO;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
*
|
||||
* (C) 2002 MontVista Software, Inc.
|
||||
*
|
||||
* $Id: omap-toto-flash.c,v 1.3 2004/09/16 23:27:13 gleixner Exp $
|
||||
* $Id: omap-toto-flash.c,v 1.5 2005/11/07 11:14:27 gleixner Exp $
|
||||
*/
|
||||
|
||||
#include <linux/config.h>
|
||||
|
@ -38,7 +38,7 @@ static struct map_info omap_toto_map_flash = {
|
|||
.virt = (void __iomem *)OMAP_TOTO_FLASH_BASE,
|
||||
};
|
||||
|
||||
|
||||
|
||||
static struct mtd_partition toto_flash_partitions[] = {
|
||||
{
|
||||
.name = "BootLoader",
|
||||
|
@ -54,21 +54,21 @@ static struct mtd_partition toto_flash_partitions[] = {
|
|||
.name = "EnvArea", /* bottom 64KiB for env vars */
|
||||
.size = MTDPART_SIZ_FULL,
|
||||
.offset = MTDPART_OFS_APPEND,
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
static struct mtd_partition *parsed_parts;
|
||||
|
||||
static struct mtd_info *flash_mtd;
|
||||
|
||||
static int __init init_flash (void)
|
||||
|
||||
static int __init init_flash (void)
|
||||
{
|
||||
|
||||
struct mtd_partition *parts;
|
||||
int nb_parts = 0;
|
||||
int parsed_nr_parts = 0;
|
||||
const char *part_type;
|
||||
|
||||
|
||||
/*
|
||||
* Static partition definition selection
|
||||
*/
|
||||
|
@ -89,7 +89,7 @@ static int __init init_flash (void)
|
|||
flash_mtd = do_map_probe("jedec_probe", &omap_toto_map_flash);
|
||||
if (!flash_mtd)
|
||||
return -ENXIO;
|
||||
|
||||
|
||||
if (parsed_nr_parts > 0) {
|
||||
parts = parsed_parts;
|
||||
nb_parts = parsed_nr_parts;
|
||||
|
@ -108,8 +108,8 @@ static int __init init_flash (void)
|
|||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int __init omap_toto_mtd_init(void)
|
||||
|
||||
int __init omap_toto_mtd_init(void)
|
||||
{
|
||||
int status;
|
||||
|
||||
|
@ -119,7 +119,7 @@ int __init omap_toto_mtd_init(void)
|
|||
return status;
|
||||
}
|
||||
|
||||
static void __exit omap_toto_mtd_cleanup(void)
|
||||
static void __exit omap_toto_mtd_cleanup(void)
|
||||
{
|
||||
if (flash_mtd) {
|
||||
del_mtd_partitions(flash_mtd);
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
*
|
||||
* Copyright (C) 2001-2002 MontaVista Software Inc.
|
||||
* Copyright (C) 2003-2004 Texas Instruments
|
||||
* Copyright (C) 2004 Nokia Corporation
|
||||
* Copyright (C) 2004 Nokia Corporation
|
||||
*
|
||||
* Assembled using driver code copyright the companies above
|
||||
* and written by David Brownell, Jian Zhang <jzhang@ti.com>,
|
||||
|
|
|
@ -7,8 +7,8 @@
|
|||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* $Id: pci.c,v 1.10 2005/03/18 14:04:35 gleixner Exp $
|
||||
*
|
||||
* $Id: pci.c,v 1.13 2005/11/07 11:14:27 gleixner Exp $
|
||||
*
|
||||
* Generic PCI memory map driver. We support the following boards:
|
||||
* - Intel IQ80310 ATU.
|
||||
* - Intel EBSA285 (blank rom programming mode). Tested working 27/09/2001
|
||||
|
@ -38,7 +38,7 @@ struct map_pci_info {
|
|||
void (*exit)(struct pci_dev *dev, struct map_pci_info *map);
|
||||
unsigned long (*translate)(struct map_pci_info *map, unsigned long ofs);
|
||||
struct pci_dev *dev;
|
||||
};
|
||||
};
|
||||
|
||||
static map_word mtd_pci_read8(struct map_info *_map, unsigned long ofs)
|
||||
{
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* $Id: pcmciamtd.c,v 1.51 2004/07/12 22:38:29 dwmw2 Exp $
|
||||
* $Id: pcmciamtd.c,v 1.55 2005/11/07 11:14:28 gleixner Exp $
|
||||
*
|
||||
* pcmciamtd.c - MTD driver for PCMCIA flash memory cards
|
||||
*
|
||||
|
@ -48,7 +48,7 @@ static const int debug = 0;
|
|||
|
||||
|
||||
#define DRIVER_DESC "PCMCIA Flash memory card driver"
|
||||
#define DRIVER_VERSION "$Revision: 1.51 $"
|
||||
#define DRIVER_VERSION "$Revision: 1.55 $"
|
||||
|
||||
/* Size of the PCMCIA address space: 26 bits = 64 MB */
|
||||
#define MAX_PCMCIA_ADDR 0x4000000
|
||||
|
@ -176,7 +176,7 @@ static void pcmcia_copy_from_remap(struct map_info *map, void *to, unsigned long
|
|||
|
||||
if(toread > len)
|
||||
toread = len;
|
||||
|
||||
|
||||
addr = remap_window(map, from);
|
||||
if(!addr)
|
||||
return;
|
||||
|
@ -386,7 +386,7 @@ static void card_settings(struct pcmciamtd_dev *dev, dev_link_t *link, int *new_
|
|||
cs_error(link->handle, ParseTuple, rc);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
switch(tuple.TupleCode) {
|
||||
case CISTPL_FORMAT: {
|
||||
cistpl_format_t *t = &parse.format;
|
||||
|
@ -394,9 +394,9 @@ static void card_settings(struct pcmciamtd_dev *dev, dev_link_t *link, int *new_
|
|||
DEBUG(2, "Format type: %u, Error Detection: %u, offset = %u, length =%u",
|
||||
t->type, t->edc, t->offset, t->length);
|
||||
break;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
case CISTPL_DEVICE: {
|
||||
cistpl_device_t *t = &parse.device;
|
||||
int i;
|
||||
|
@ -410,7 +410,7 @@ static void card_settings(struct pcmciamtd_dev *dev, dev_link_t *link, int *new_
|
|||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case CISTPL_VERS_1: {
|
||||
cistpl_vers_1_t *t = &parse.version_1;
|
||||
int i;
|
||||
|
@ -425,7 +425,7 @@ static void card_settings(struct pcmciamtd_dev *dev, dev_link_t *link, int *new_
|
|||
DEBUG(2, "Found name: %s", dev->mtd_name);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case CISTPL_JEDEC_C: {
|
||||
cistpl_jedec_t *t = &parse.jedec;
|
||||
int i;
|
||||
|
@ -434,7 +434,7 @@ static void card_settings(struct pcmciamtd_dev *dev, dev_link_t *link, int *new_
|
|||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case CISTPL_DEVICE_GEO: {
|
||||
cistpl_device_geo_t *t = &parse.device_geo;
|
||||
int i;
|
||||
|
@ -449,11 +449,11 @@ static void card_settings(struct pcmciamtd_dev *dev, dev_link_t *link, int *new_
|
|||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
default:
|
||||
DEBUG(2, "Unknown tuple code %d", tuple.TupleCode);
|
||||
}
|
||||
|
||||
|
||||
rc = pcmcia_get_next_tuple(link->handle, &tuple);
|
||||
}
|
||||
if(!dev->pcmcia_map.size)
|
||||
|
@ -470,7 +470,7 @@ static void card_settings(struct pcmciamtd_dev *dev, dev_link_t *link, int *new_
|
|||
if(bankwidth) {
|
||||
dev->pcmcia_map.bankwidth = bankwidth;
|
||||
DEBUG(2, "bankwidth forced to %d", bankwidth);
|
||||
}
|
||||
}
|
||||
|
||||
dev->pcmcia_map.name = dev->mtd_name;
|
||||
if(!dev->mtd_name[0]) {
|
||||
|
@ -568,7 +568,7 @@ static void pcmciamtd_config(dev_link_t *link)
|
|||
return;
|
||||
}
|
||||
DEBUG(1, "Allocated a window of %dKiB", dev->win_size >> 10);
|
||||
|
||||
|
||||
/* Get write protect status */
|
||||
CS_CHECK(GetStatus, pcmcia_get_status(link->handle, &status));
|
||||
DEBUG(2, "status value: 0x%x window handle = 0x%8.8lx",
|
||||
|
@ -624,11 +624,11 @@ static void pcmciamtd_config(dev_link_t *link)
|
|||
mtd = do_map_probe(probes[i], &dev->pcmcia_map);
|
||||
if(mtd)
|
||||
break;
|
||||
|
||||
|
||||
DEBUG(1, "FAILED: %s", probes[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if(!mtd) {
|
||||
DEBUG(1, "Cant find an MTD");
|
||||
pcmciamtd_release(link);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* $Id: physmap.c,v 1.37 2004/11/28 09:40:40 dwmw2 Exp $
|
||||
* $Id: physmap.c,v 1.38 2005/11/07 11:14:28 gleixner Exp $
|
||||
*
|
||||
* Normal mappings of chips in physical memory
|
||||
*
|
||||
|
@ -69,7 +69,7 @@ static int __init init_physmap(void)
|
|||
mymtd->owner = THIS_MODULE;
|
||||
|
||||
#ifdef CONFIG_MTD_PARTITIONS
|
||||
mtd_parts_nb = parse_mtd_partitions(mymtd, part_probes,
|
||||
mtd_parts_nb = parse_mtd_partitions(mymtd, part_probes,
|
||||
&mtd_parts, 0);
|
||||
|
||||
if (mtd_parts_nb > 0)
|
||||
|
@ -78,9 +78,9 @@ static int __init init_physmap(void)
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (num_physmap_partitions != 0)
|
||||
if (num_physmap_partitions != 0)
|
||||
{
|
||||
printk(KERN_NOTICE
|
||||
printk(KERN_NOTICE
|
||||
"Using physmap partition definition\n");
|
||||
add_mtd_partitions (mymtd, physmap_partitions, num_physmap_partitions);
|
||||
return 0;
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
*
|
||||
* Generic platfrom device based RAM map
|
||||
*
|
||||
* $Id: plat-ram.c,v 1.3 2005/03/19 22:41:27 gleixner Exp $
|
||||
* $Id: plat-ram.c,v 1.7 2005/11/07 11:14:28 gleixner Exp $
|
||||
*
|
||||
* 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
|
||||
|
@ -91,7 +91,7 @@ static int platram_remove(struct device *dev)
|
|||
|
||||
dev_dbg(dev, "removing device\n");
|
||||
|
||||
if (info == NULL)
|
||||
if (info == NULL)
|
||||
return 0;
|
||||
|
||||
if (info->mtd) {
|
||||
|
@ -118,7 +118,7 @@ static int platram_remove(struct device *dev)
|
|||
|
||||
if (info->map.virt != NULL)
|
||||
iounmap(info->map.virt);
|
||||
|
||||
|
||||
kfree(info);
|
||||
|
||||
return 0;
|
||||
|
@ -139,7 +139,7 @@ static int platram_probe(struct device *dev)
|
|||
int err = 0;
|
||||
|
||||
dev_dbg(dev, "probe entered\n");
|
||||
|
||||
|
||||
if (dev->platform_data == NULL) {
|
||||
dev_err(dev, "no platform data supplied\n");
|
||||
err = -ENOENT;
|
||||
|
@ -177,7 +177,7 @@ static int platram_probe(struct device *dev)
|
|||
|
||||
info->map.phys = res->start;
|
||||
info->map.size = (res->end - res->start) + 1;
|
||||
info->map.name = pdata->mapname != NULL ? pdata->mapname : pd->name;
|
||||
info->map.name = pdata->mapname != NULL ? pdata->mapname : (char *)pd->name;
|
||||
info->map.bankwidth = pdata->bankwidth;
|
||||
|
||||
/* register our usage of the memory area */
|
||||
|
@ -240,7 +240,7 @@ static int platram_probe(struct device *dev)
|
|||
dev_err(dev, "add_mtd_device() failed\n");
|
||||
err = -ENOMEM;
|
||||
}
|
||||
|
||||
|
||||
dev_info(dev, "registered mtd device\n");
|
||||
return err;
|
||||
|
||||
|
@ -254,6 +254,7 @@ static int platram_probe(struct device *dev)
|
|||
|
||||
static struct device_driver platram_driver = {
|
||||
.name = "mtd-ram",
|
||||
.owner = THIS_MODULE,
|
||||
.bus = &platform_bus_type,
|
||||
.probe = platram_probe,
|
||||
.remove = platram_remove,
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
*
|
||||
* This code is GPL
|
||||
*
|
||||
* $Id: pnc2000.c,v 1.17 2004/11/16 18:29:02 dwmw2 Exp $
|
||||
* $Id: pnc2000.c,v 1.18 2005/11/07 11:14:28 gleixner Exp $
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
|
@ -21,7 +21,7 @@
|
|||
#define WINDOW_ADDR 0xbf000000
|
||||
#define WINDOW_SIZE 0x00400000
|
||||
|
||||
/*
|
||||
/*
|
||||
* MAP DRIVER STUFF
|
||||
*/
|
||||
|
||||
|
@ -36,7 +36,7 @@ static struct map_info pnc_map = {
|
|||
|
||||
|
||||
/*
|
||||
* MTD 'PARTITIONING' STUFF
|
||||
* MTD 'PARTITIONING' STUFF
|
||||
*/
|
||||
static struct mtd_partition pnc_partitions[3] = {
|
||||
{
|
||||
|
@ -56,7 +56,7 @@ static struct mtd_partition pnc_partitions[3] = {
|
|||
}
|
||||
};
|
||||
|
||||
/*
|
||||
/*
|
||||
* This is the master MTD device for which all the others are just
|
||||
* auto-relocating aliases.
|
||||
*/
|
||||
|
|
88
drivers/mtd/maps/pq2fads.c
Normal file
88
drivers/mtd/maps/pq2fads.c
Normal file
|
@ -0,0 +1,88 @@
|
|||
/*
|
||||
* drivers/mtd/maps/pq2fads.c
|
||||
*
|
||||
* Mapping for the flash SIMM on 8272ADS and PQ2FADS board
|
||||
*
|
||||
* Author: Vitaly Bordug <vbordug@ru.mvista.com>
|
||||
*
|
||||
* 2005 (c) MontaVista Software, Inc. This file is licensed under
|
||||
* the terms of the GNU General Public License version 2. This program
|
||||
* is licensed "as is" without any warranty of any kind, whether express
|
||||
* or implied.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/ppcboot.h>
|
||||
#include <linux/mtd/mtd.h>
|
||||
#include <linux/mtd/map.h>
|
||||
#include <linux/mtd/partitions.h>
|
||||
#include <linux/mtd/physmap.h>
|
||||
|
||||
/*
|
||||
NOTE: bank width and interleave relative to the installed flash
|
||||
should have been chosen within MTD_CFI_GEOMETRY options.
|
||||
*/
|
||||
#define PQ2FADS_BANK_WIDTH 4
|
||||
|
||||
static struct mtd_partition pq2fads_partitions[] = {
|
||||
{
|
||||
#ifdef CONFIG_ADS8272
|
||||
.name = "HRCW",
|
||||
.size = 0x40000,
|
||||
.offset = 0,
|
||||
.mask_flags = MTD_WRITEABLE, /* force read-only */
|
||||
}, {
|
||||
.name = "User FS",
|
||||
.size = 0x5c0000,
|
||||
.offset = 0x40000,
|
||||
#else
|
||||
.name = "User FS",
|
||||
.size = 0x600000,
|
||||
.offset = 0,
|
||||
#endif
|
||||
}, {
|
||||
.name = "uImage",
|
||||
.size = 0x100000,
|
||||
.offset = 0x600000,
|
||||
.mask_flags = MTD_WRITEABLE, /* force read-only */
|
||||
}, {
|
||||
.name = "bootloader",
|
||||
.size = 0x40000,
|
||||
.offset = 0x700000,
|
||||
.mask_flags = MTD_WRITEABLE, /* force read-only */
|
||||
}, {
|
||||
.name = "bootloader env",
|
||||
.size = 0x40000,
|
||||
.offset = 0x740000,
|
||||
.mask_flags = MTD_WRITEABLE, /* force read-only */
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/* pointer to MPC885ADS board info data */
|
||||
extern unsigned char __res[];
|
||||
|
||||
static int __init init_pq2fads_mtd(void)
|
||||
{
|
||||
bd_t *bd = (bd_t *)__res;
|
||||
physmap_configure(bd->bi_flashstart, bd->bi_flashsize, PQ2FADS_BANK_WIDTH, NULL);
|
||||
|
||||
physmap_set_partitions(pq2fads_partitions,
|
||||
sizeof (pq2fads_partitions) /
|
||||
sizeof (pq2fads_partitions[0]));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __exit cleanup_pq2fads_mtd(void)
|
||||
{
|
||||
}
|
||||
|
||||
module_init(init_pq2fads_mtd);
|
||||
module_exit(cleanup_pq2fads_mtd);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_DESCRIPTION("MTD map and partitions for MPC8272ADS boards");
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* $Id: redwood.c,v 1.10 2004/11/04 13:24:15 gleixner Exp $
|
||||
* $Id: redwood.c,v 1.11 2005/11/07 11:14:28 gleixner Exp $
|
||||
*
|
||||
* drivers/mtd/maps/redwood.c
|
||||
*
|
||||
|
@ -79,7 +79,7 @@ static struct mtd_partition redwood_flash_partitions[] = {
|
|||
|
||||
#define RW_PART0_OF 0
|
||||
#define RW_PART0_SZ 0x400000 /* 4 MiB data */
|
||||
#define RW_PART1_OF RW_PART0_OF + RW_PART0_SZ
|
||||
#define RW_PART1_OF RW_PART0_OF + RW_PART0_SZ
|
||||
#define RW_PART1_SZ 0x10000 /* 64K VPD */
|
||||
#define RW_PART2_OF RW_PART1_OF + RW_PART1_SZ
|
||||
#define RW_PART2_SZ 0x400000 - (0x10000 + 0x20000)
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
/*
|
||||
* Flash memory access on SA11x0 based devices
|
||||
*
|
||||
*
|
||||
* (C) 2000 Nicolas Pitre <nico@cam.org>
|
||||
*
|
||||
* $Id: sa1100-flash.c,v 1.47 2004/11/01 13:44:36 rmk Exp $
|
||||
*
|
||||
* $Id: sa1100-flash.c,v 1.51 2005/11/07 11:14:28 gleixner Exp $
|
||||
*/
|
||||
#include <linux/config.h>
|
||||
#include <linux/module.h>
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
*
|
||||
* This code is GPLed
|
||||
*
|
||||
* $Id: sbc8240.c,v 1.4 2004/07/12 22:38:29 dwmw2 Exp $
|
||||
* $Id: sbc8240.c,v 1.5 2005/11/07 11:14:28 gleixner Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
|
@ -205,7 +205,7 @@ int __init init_sbc8240_mtd (void)
|
|||
} else {
|
||||
printk (KERN_NOTICE MSG_PREFIX
|
||||
"Using %s partition definition\n", sbc8240_part_banks[i].mtd_part->name);
|
||||
add_mtd_partitions (sbc8240_mtd[i],
|
||||
add_mtd_partitions (sbc8240_mtd[i],
|
||||
sbc8240_part_banks[i].mtd_part,
|
||||
sbc8240_part_banks[i].nums);
|
||||
}
|
||||
|
|
|
@ -1,35 +1,35 @@
|
|||
/* sbc_gxx.c -- MTD map driver for Arcom Control Systems SBC-MediaGX,
|
||||
SBC-GXm and SBC-GX1 series boards.
|
||||
|
||||
|
||||
Copyright (C) 2001 Arcom Control System Ltd
|
||||
|
||||
|
||||
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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
|
||||
$Id: sbc_gxx.c,v 1.33 2004/11/28 09:40:40 dwmw2 Exp $
|
||||
$Id: sbc_gxx.c,v 1.35 2005/11/07 11:14:28 gleixner Exp $
|
||||
|
||||
The SBC-MediaGX / SBC-GXx has up to 16 MiB of
|
||||
Intel StrataFlash (28F320/28F640) in x8 mode.
|
||||
The SBC-MediaGX / SBC-GXx has up to 16 MiB of
|
||||
Intel StrataFlash (28F320/28F640) in x8 mode.
|
||||
|
||||
This driver uses the CFI probe and Intel Extended Command Set drivers.
|
||||
|
||||
The flash is accessed as follows:
|
||||
|
||||
16 KiB memory window at 0xdc000-0xdffff
|
||||
|
||||
|
||||
Two IO address locations for paging
|
||||
|
||||
|
||||
0x258
|
||||
bit 0-7: address bit 14-21
|
||||
0x259
|
||||
|
@ -37,7 +37,7 @@ The flash is accessed as follows:
|
|||
bit 7: 0 - reset/powered down
|
||||
1 - device enabled
|
||||
|
||||
The single flash device is divided into 3 partition which appear as
|
||||
The single flash device is divided into 3 partition which appear as
|
||||
separate MTD devices.
|
||||
|
||||
25/04/2001 AJL (Arcom) Modified signon strings and partition sizes
|
||||
|
@ -87,17 +87,17 @@ static volatile int page_in_window = -1; // Current page in window.
|
|||
static void __iomem *iomapadr;
|
||||
static DEFINE_SPINLOCK(sbc_gxx_spin);
|
||||
|
||||
/* partition_info gives details on the logical partitions that the split the
|
||||
/* partition_info gives details on the logical partitions that the split the
|
||||
* single flash device into. If the size if zero we use up to the end of the
|
||||
* device. */
|
||||
static struct mtd_partition partition_info[]={
|
||||
{ .name = "SBC-GXx flash boot partition",
|
||||
.offset = 0,
|
||||
{ .name = "SBC-GXx flash boot partition",
|
||||
.offset = 0,
|
||||
.size = BOOT_PARTITION_SIZE_KiB*1024 },
|
||||
{ .name = "SBC-GXx flash data partition",
|
||||
.offset = BOOT_PARTITION_SIZE_KiB*1024,
|
||||
{ .name = "SBC-GXx flash data partition",
|
||||
.offset = BOOT_PARTITION_SIZE_KiB*1024,
|
||||
.size = (DATA_PARTITION_SIZE_KiB)*1024 },
|
||||
{ .name = "SBC-GXx flash application partition",
|
||||
{ .name = "SBC-GXx flash application partition",
|
||||
.offset = (BOOT_PARTITION_SIZE_KiB+DATA_PARTITION_SIZE_KiB)*1024 }
|
||||
};
|
||||
|
||||
|
@ -130,7 +130,7 @@ static void sbc_gxx_copy_from(struct map_info *map, void *to, unsigned long from
|
|||
unsigned long thislen = len;
|
||||
if (len > (WINDOW_LENGTH - (from & WINDOW_MASK)))
|
||||
thislen = WINDOW_LENGTH-(from & WINDOW_MASK);
|
||||
|
||||
|
||||
spin_lock(&sbc_gxx_spin);
|
||||
sbc_gxx_page(map, from);
|
||||
memcpy_fromio(to, iomapadr + (from & WINDOW_MASK), thislen);
|
||||
|
@ -150,12 +150,12 @@ static void sbc_gxx_write8(struct map_info *map, map_word d, unsigned long adr)
|
|||
}
|
||||
|
||||
static void sbc_gxx_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
|
||||
{
|
||||
{
|
||||
while(len) {
|
||||
unsigned long thislen = len;
|
||||
if (len > (WINDOW_LENGTH - (to & WINDOW_MASK)))
|
||||
thislen = WINDOW_LENGTH-(to & WINDOW_MASK);
|
||||
|
||||
|
||||
spin_lock(&sbc_gxx_spin);
|
||||
sbc_gxx_page(map, to);
|
||||
memcpy_toio(iomapadr + (to & WINDOW_MASK), from, thislen);
|
||||
|
@ -201,7 +201,7 @@ static int __init init_sbc_gxx(void)
|
|||
sbc_gxx_map.name );
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
|
||||
if (!request_region( PAGE_IO, PAGE_IO_SIZE, "SBC-GXx flash")) {
|
||||
printk( KERN_ERR"%s: IO ports 0x%x-0x%x in use\n",
|
||||
sbc_gxx_map.name,
|
||||
|
@ -209,8 +209,8 @@ static int __init init_sbc_gxx(void)
|
|||
iounmap(iomapadr);
|
||||
return -EAGAIN;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
printk( KERN_INFO"%s: IO:0x%x-0x%x MEM:0x%x-0x%x\n",
|
||||
sbc_gxx_map.name,
|
||||
PAGE_IO, PAGE_IO+PAGE_IO_SIZE-1,
|
||||
|
@ -222,7 +222,7 @@ static int __init init_sbc_gxx(void)
|
|||
cleanup_sbc_gxx();
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
|
||||
all_mtd->owner = THIS_MODULE;
|
||||
|
||||
/* Create MTD devices for each partition. */
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*
|
||||
* $Id: sc520cdp.c,v 1.21 2004/12/13 10:27:08 dedekind Exp $
|
||||
* $Id: sc520cdp.c,v 1.22 2005/11/07 11:14:28 gleixner Exp $
|
||||
*
|
||||
*
|
||||
* The SC520CDP is an evaluation board for the Elan SC520 processor available
|
||||
|
@ -231,7 +231,7 @@ static void sc520cdp_setup_par(void)
|
|||
static int __init init_sc520cdp(void)
|
||||
{
|
||||
int i, devices_found = 0;
|
||||
|
||||
|
||||
#ifdef REPROGRAM_PAR
|
||||
/* reprogram PAR registers so flash appears at the desired addresses */
|
||||
sc520cdp_setup_par();
|
||||
|
@ -278,7 +278,7 @@ static int __init init_sc520cdp(void)
|
|||
static void __exit cleanup_sc520cdp(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
||||
if (merged_mtd) {
|
||||
del_mtd_device(merged_mtd);
|
||||
mtd_concat_destroy(merged_mtd);
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
/* linux/drivers/mtd/maps/scx200_docflash.c
|
||||
/* linux/drivers/mtd/maps/scx200_docflash.c
|
||||
|
||||
Copyright (c) 2001,2002 Christer Weinigel <wingel@nano-system.com>
|
||||
|
||||
$Id: scx200_docflash.c,v 1.10 2004/11/28 09:40:40 dwmw2 Exp $
|
||||
$Id: scx200_docflash.c,v 1.12 2005/11/07 11:14:28 gleixner Exp $
|
||||
|
||||
National Semiconductor SCx200 flash mapped with DOCCS
|
||||
*/
|
||||
|
@ -49,23 +49,23 @@ static struct mtd_info *mymtd;
|
|||
|
||||
#ifdef CONFIG_MTD_PARTITIONS
|
||||
static struct mtd_partition partition_info[] = {
|
||||
{
|
||||
.name = "DOCCS Boot kernel",
|
||||
.offset = 0,
|
||||
{
|
||||
.name = "DOCCS Boot kernel",
|
||||
.offset = 0,
|
||||
.size = 0xc0000
|
||||
},
|
||||
{
|
||||
.name = "DOCCS Low BIOS",
|
||||
.offset = 0xc0000,
|
||||
{
|
||||
.name = "DOCCS Low BIOS",
|
||||
.offset = 0xc0000,
|
||||
.size = 0x40000
|
||||
},
|
||||
{
|
||||
.name = "DOCCS File system",
|
||||
.offset = 0x100000,
|
||||
{
|
||||
.name = "DOCCS File system",
|
||||
.offset = 0x100000,
|
||||
.size = ~0 /* calculate from flash size */
|
||||
},
|
||||
{
|
||||
.name = "DOCCS High BIOS",
|
||||
{
|
||||
.name = "DOCCS High BIOS",
|
||||
.offset = ~0, /* calculate from flash size */
|
||||
.size = 0x80000
|
||||
},
|
||||
|
@ -88,7 +88,7 @@ static int __init init_scx200_docflash(void)
|
|||
|
||||
printk(KERN_DEBUG NAME ": NatSemi SCx200 DOCCS Flash Driver\n");
|
||||
|
||||
if ((bridge = pci_find_device(PCI_VENDOR_ID_NS,
|
||||
if ((bridge = pci_find_device(PCI_VENDOR_ID_NS,
|
||||
PCI_DEVICE_ID_NS_SCx200_BRIDGE,
|
||||
NULL)) == NULL)
|
||||
return -ENODEV;
|
||||
|
@ -134,28 +134,28 @@ static int __init init_scx200_docflash(void)
|
|||
printk(KERN_ERR NAME ": invalid size for flash mapping\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
||||
if (width != 8 && width != 16) {
|
||||
printk(KERN_ERR NAME ": invalid bus width for flash mapping\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (allocate_resource(&iomem_resource, &docmem,
|
||||
|
||||
if (allocate_resource(&iomem_resource, &docmem,
|
||||
size,
|
||||
0xc0000000, 0xffffffff,
|
||||
0xc0000000, 0xffffffff,
|
||||
size, NULL, NULL)) {
|
||||
printk(KERN_ERR NAME ": unable to allocate memory for flash mapping\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
|
||||
ctrl = 0x07000000 | ((size-1) >> 13);
|
||||
|
||||
printk(KERN_INFO "DOCCS BASE=0x%08lx, CTRL=0x%08lx\n", (long)docmem.start, (long)ctrl);
|
||||
|
||||
|
||||
pci_write_config_dword(bridge, SCx200_DOCCS_BASE, docmem.start);
|
||||
pci_write_config_dword(bridge, SCx200_DOCCS_CTRL, ctrl);
|
||||
pmr = inl(scx200_cb_base + SCx200_PMR);
|
||||
|
||||
|
||||
if (width == 8) {
|
||||
pmr &= ~(1<<6);
|
||||
} else {
|
||||
|
@ -163,8 +163,8 @@ static int __init init_scx200_docflash(void)
|
|||
}
|
||||
outl(pmr, scx200_cb_base + SCx200_PMR);
|
||||
}
|
||||
|
||||
printk(KERN_INFO NAME ": DOCCS mapped at 0x%lx-0x%lx, width %d\n",
|
||||
|
||||
printk(KERN_INFO NAME ": DOCCS mapped at 0x%lx-0x%lx, width %d\n",
|
||||
docmem.start, docmem.end, width);
|
||||
|
||||
scx200_docflash_map.size = size;
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
/*
|
||||
* sharpsl-flash.c
|
||||
*
|
||||
*
|
||||
* Copyright (C) 2001 Lineo Japan, Inc.
|
||||
* Copyright (C) 2002 SHARP
|
||||
*
|
||||
* $Id: sharpsl-flash.c,v 1.5 2005/03/21 08:42:11 rpurdie Exp $
|
||||
* $Id: sharpsl-flash.c,v 1.7 2005/11/07 11:14:28 gleixner Exp $
|
||||
*
|
||||
* based on rpxlite.c,v 1.15 2001/10/02 15:05:14 dwmw2 Exp
|
||||
* Handle mapping of the flash on the RPX Lite and CLLF boards
|
||||
|
@ -57,7 +57,7 @@ int __init init_sharpsl(void)
|
|||
int nb_parts = 0;
|
||||
char *part_type = "static";
|
||||
|
||||
printk(KERN_NOTICE "Sharp SL series flash device: %x at %x\n",
|
||||
printk(KERN_NOTICE "Sharp SL series flash device: %x at %x\n",
|
||||
WINDOW_SIZE, WINDOW_ADDR);
|
||||
sharpsl_map.virt = ioremap(WINDOW_ADDR, WINDOW_SIZE);
|
||||
if (!sharpsl_map.virt) {
|
||||
|
@ -75,7 +75,7 @@ int __init init_sharpsl(void)
|
|||
|
||||
mymtd->owner = THIS_MODULE;
|
||||
|
||||
if (machine_is_corgi() || machine_is_shepherd() || machine_is_husky()
|
||||
if (machine_is_corgi() || machine_is_shepherd() || machine_is_husky()
|
||||
|| machine_is_poodle()) {
|
||||
sharpsl_partitions[0].size=0x006d0000;
|
||||
sharpsl_partitions[0].offset=0x00120000;
|
||||
|
@ -87,10 +87,10 @@ int __init init_sharpsl(void)
|
|||
sharpsl_partitions[0].offset=0x00140000;
|
||||
} else {
|
||||
map_destroy(mymtd);
|
||||
iounmap(sharpsl_map.virt);
|
||||
iounmap(sharpsl_map.virt);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
|
||||
parts = sharpsl_partitions;
|
||||
nb_parts = NB_OF(sharpsl_partitions);
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* $Id: solutionengine.c,v 1.14 2004/09/16 23:27:14 gleixner Exp $
|
||||
* $Id: solutionengine.c,v 1.15 2005/11/07 11:14:28 gleixner Exp $
|
||||
*
|
||||
* Flash and EPROM on Hitachi Solution Engine and similar boards.
|
||||
*
|
||||
|
@ -67,7 +67,7 @@ static int __init init_soleng_maps(void)
|
|||
soleng_eprom_map.virt = (void __iomem *)P1SEGADDR(0x01000000);
|
||||
simple_map_init(&soleng_eprom_map);
|
||||
simple_map_init(&soleng_flash_map);
|
||||
|
||||
|
||||
printk(KERN_NOTICE "Probing for flash chips at 0x00000000:\n");
|
||||
flash_mtd = do_map_probe("cfi_probe", &soleng_flash_map);
|
||||
if (!flash_mtd) {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: sun_uflash.c,v 1.11 2004/11/04 13:24:15 gleixner Exp $
|
||||
/* $Id: sun_uflash.c,v 1.13 2005/11/07 11:14:28 gleixner Exp $
|
||||
*
|
||||
* sun_uflash - Driver implementation for user-programmable flash
|
||||
* present on many Sun Microsystems SME boardsets.
|
||||
|
@ -63,7 +63,7 @@ int uflash_devinit(struct linux_ebus_device* edev)
|
|||
iTmp = prom_getproperty(
|
||||
edev->prom_node, "reg", (void *)regs, sizeof(regs));
|
||||
if ((iTmp % sizeof(regs[0])) != 0) {
|
||||
printk("%s: Strange reg property size %d\n",
|
||||
printk("%s: Strange reg property size %d\n",
|
||||
UFLASH_DEVNAME, iTmp);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
@ -75,7 +75,7 @@ int uflash_devinit(struct linux_ebus_device* edev)
|
|||
* can work on supporting it.
|
||||
*/
|
||||
printk("%s: unsupported device at 0x%lx (%d regs): " \
|
||||
"email ebrower@usa.net\n",
|
||||
"email ebrower@usa.net\n",
|
||||
UFLASH_DEVNAME, edev->resource[0].start, nregs);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
@ -84,7 +84,7 @@ int uflash_devinit(struct linux_ebus_device* edev)
|
|||
printk("%s: unable to kmalloc new device\n", UFLASH_DEVNAME);
|
||||
return(-ENOMEM);
|
||||
}
|
||||
|
||||
|
||||
/* copy defaults and tweak parameters */
|
||||
memcpy(&pdev->map, &uflash_map_templ, sizeof(uflash_map_templ));
|
||||
pdev->map.size = regs[0].reg_size;
|
||||
|
@ -155,7 +155,7 @@ static void __exit uflash_cleanup(void)
|
|||
|
||||
list_for_each(udevlist, &device_list) {
|
||||
udev = list_entry(udevlist, struct uflash_dev, list);
|
||||
DEBUG(2, "%s: removing device %s\n",
|
||||
DEBUG(2, "%s: removing device %s\n",
|
||||
UFLASH_DEVNAME, udev->name);
|
||||
|
||||
if(0 != udev->mtd) {
|
||||
|
@ -168,7 +168,7 @@ static void __exit uflash_cleanup(void)
|
|||
}
|
||||
kfree(udev->name);
|
||||
kfree(udev);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module_init(uflash_init);
|
||||
|
|
291
drivers/mtd/maps/tqm834x.c
Normal file
291
drivers/mtd/maps/tqm834x.c
Normal file
|
@ -0,0 +1,291 @@
|
|||
/*
|
||||
* drivers/mtd/maps/tqm834x.c
|
||||
*
|
||||
* MTD mapping driver for TQM834x boards
|
||||
*
|
||||
* Copyright 2005 Wolfgang Denk, DENX Software Engineering, <wd@denx.de>.
|
||||
*
|
||||
* This file is licensed under the terms of the GNU General Public License
|
||||
* version 2. This program is licensed "as is" without any warranty of any
|
||||
* kind, whether express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/config.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/slab.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/ppcboot.h>
|
||||
|
||||
#include <linux/mtd/mtd.h>
|
||||
#include <linux/mtd/map.h>
|
||||
#include <linux/mtd/partitions.h>
|
||||
|
||||
#define FLASH_BANK_MAX 2
|
||||
|
||||
extern unsigned char __res[];
|
||||
|
||||
/* trivial struct to describe partition information */
|
||||
struct mtd_part_def
|
||||
{
|
||||
int nums;
|
||||
unsigned char *type;
|
||||
struct mtd_partition* mtd_part;
|
||||
};
|
||||
|
||||
static struct mtd_info* mtd_banks[FLASH_BANK_MAX];
|
||||
static struct map_info* map_banks[FLASH_BANK_MAX];
|
||||
static struct mtd_part_def part_banks[FLASH_BANK_MAX];
|
||||
|
||||
static unsigned long num_banks;
|
||||
static unsigned long start_scan_addr;
|
||||
|
||||
#ifdef CONFIG_MTD_PARTITIONS
|
||||
/*
|
||||
* The following defines the partition layout of TQM834x boards.
|
||||
*
|
||||
* See include/linux/mtd/partitions.h for definition of the
|
||||
* mtd_partition structure.
|
||||
*
|
||||
* Assume minimal initial size of 4 MiB per bank, will be updated
|
||||
* later in init_tqm834x_mtd() routine.
|
||||
*/
|
||||
|
||||
/* Partition definition for the first flash bank which is always present. */
|
||||
static struct mtd_partition tqm834x_partitions_bank1[] = {
|
||||
{
|
||||
.name = "u-boot", /* u-boot firmware */
|
||||
.offset = 0x00000000,
|
||||
.size = 0x00040000, /* 256 KiB */
|
||||
/*mask_flags: MTD_WRITEABLE, * force read-only */
|
||||
},
|
||||
{
|
||||
.name = "env", /* u-boot environment */
|
||||
.offset = 0x00040000,
|
||||
.size = 0x00020000, /* 128 KiB */
|
||||
/*mask_flags: MTD_WRITEABLE, * force read-only */
|
||||
},
|
||||
{
|
||||
.name = "kernel", /* linux kernel image */
|
||||
.offset = 0x00060000,
|
||||
.size = 0x00100000, /* 1 MiB */
|
||||
/*mask_flags: MTD_WRITEABLE, * force read-only */
|
||||
},
|
||||
{
|
||||
.name = "initrd", /* ramdisk image */
|
||||
.offset = 0x00160000,
|
||||
.size = 0x00200000, /* 2 MiB */
|
||||
},
|
||||
{
|
||||
.name = "user", /* user data */
|
||||
.offset = 0x00360000,
|
||||
.size = 0x000a0000, /* remaining space */
|
||||
/* NOTE: this parttion size is re-calcated in */
|
||||
/* init_tqm834x_mtd() to cover actual remaining space. */
|
||||
},
|
||||
};
|
||||
|
||||
/* Partition definition for the second flash bank which may be present on some
|
||||
* TQM834x boards.
|
||||
*/
|
||||
static struct mtd_partition tqm834x_partitions_bank2[] = {
|
||||
{
|
||||
.name = "jffs2", /* jffs2 filesystem */
|
||||
.offset = 0x00000000,
|
||||
.size = 0x00400000, /* whole device */
|
||||
/* NOTE: this parttion size is re-calcated in */
|
||||
/* init_tqm834x_mtd() to cover actual device size. */
|
||||
},
|
||||
};
|
||||
|
||||
#endif /* CONFIG_MTD_PARTITIONS */
|
||||
|
||||
static int __init init_tqm834x_mtd(void)
|
||||
{
|
||||
int idx = 0, ret = 0;
|
||||
unsigned long flash_addr, flash_size, mtd_size = 0;
|
||||
|
||||
/* pointer to TQM834x board info data */
|
||||
bd_t *bd = (bd_t *)__res;
|
||||
#ifdef CONFIG_MTD_CMDLINE_PARTS
|
||||
int n;
|
||||
char mtdid[4];
|
||||
const char *part_probes[] = { "cmdlinepart", NULL };
|
||||
#endif
|
||||
|
||||
flash_addr = bd->bi_flashstart;
|
||||
flash_size = bd->bi_flashsize;
|
||||
|
||||
/* request maximum flash size address space */
|
||||
start_scan_addr = (unsigned long)ioremap(flash_addr, flash_size);
|
||||
if (!start_scan_addr) {
|
||||
printk("%s: Failed to ioremap address: 0x%lx\n",
|
||||
__FUNCTION__, flash_addr);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
for(idx = 0 ; idx < FLASH_BANK_MAX ; idx++) {
|
||||
if (mtd_size >= flash_size)
|
||||
break;
|
||||
|
||||
pr_debug("%s: chip probing count %d\n", __FUNCTION__, idx);
|
||||
|
||||
map_banks[idx] =
|
||||
(struct map_info *)kmalloc(sizeof(struct map_info),
|
||||
GFP_KERNEL);
|
||||
if (map_banks[idx] == NULL) {
|
||||
ret = -ENOMEM;
|
||||
goto error_mem;
|
||||
}
|
||||
memset((void *)map_banks[idx], 0, sizeof(struct map_info));
|
||||
map_banks[idx]->name = (char *)kmalloc(16, GFP_KERNEL);
|
||||
if (map_banks[idx]->name == NULL) {
|
||||
ret = -ENOMEM;
|
||||
goto error_mem;
|
||||
}
|
||||
memset((void *)map_banks[idx]->name, 0, 16);
|
||||
|
||||
sprintf(map_banks[idx]->name, "TQM834x-%d", idx);
|
||||
map_banks[idx]->size = flash_size;
|
||||
map_banks[idx]->bankwidth = 4;
|
||||
|
||||
simple_map_init(map_banks[idx]);
|
||||
|
||||
map_banks[idx]->virt = (void __iomem *)
|
||||
(start_scan_addr + ((idx > 0) ?
|
||||
(mtd_banks[idx-1] ? mtd_banks[idx-1]->size : 0) : 0));
|
||||
map_banks[idx]->phys =
|
||||
flash_addr + ((idx > 0) ?
|
||||
(mtd_banks[idx-1] ? mtd_banks[idx-1]->size : 0) : 0);
|
||||
|
||||
/* start to probe flash chips */
|
||||
mtd_banks[idx] = do_map_probe("cfi_probe", map_banks[idx]);
|
||||
if (mtd_banks[idx]) {
|
||||
mtd_banks[idx]->owner = THIS_MODULE;
|
||||
mtd_size += mtd_banks[idx]->size;
|
||||
num_banks++;
|
||||
pr_debug("%s: bank %ld, name: %s, size: %d bytes \n",
|
||||
__FUNCTION__, num_banks,
|
||||
mtd_banks[idx]->name, mtd_banks[idx]->size);
|
||||
}
|
||||
}
|
||||
|
||||
/* no supported flash chips found */
|
||||
if (!num_banks) {
|
||||
printk("TQM834x: No supported flash chips found!\n");
|
||||
ret = -ENXIO;
|
||||
goto error_mem;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_MTD_PARTITIONS
|
||||
/*
|
||||
* Select static partition definitions
|
||||
*/
|
||||
n = ARRAY_SIZE(tqm834x_partitions_bank1);
|
||||
part_banks[0].mtd_part = tqm834x_partitions_bank1;
|
||||
part_banks[0].type = "static image bank1";
|
||||
part_banks[0].nums = n;
|
||||
|
||||
/* update last partition size to cover actual remaining space */
|
||||
tqm834x_partitions_bank1[n - 1].size =
|
||||
mtd_banks[0]->size -
|
||||
tqm834x_partitions_bank1[n - 1].offset;
|
||||
|
||||
/* check if we have second bank? */
|
||||
if (num_banks == 2) {
|
||||
n = ARRAY_SIZE(tqm834x_partitions_bank2);
|
||||
part_banks[1].mtd_part = tqm834x_partitions_bank2;
|
||||
part_banks[1].type = "static image bank2";
|
||||
part_banks[1].nums = n;
|
||||
|
||||
/* update last partition size to cover actual remaining space */
|
||||
tqm834x_partitions_bank2[n - 1].size =
|
||||
mtd_banks[1]->size -
|
||||
tqm834x_partitions_bank2[n - 1].offset;
|
||||
}
|
||||
|
||||
for(idx = 0; idx < num_banks ; idx++) {
|
||||
#ifdef CONFIG_MTD_CMDLINE_PARTS
|
||||
sprintf(mtdid, "%d", idx);
|
||||
n = parse_mtd_partitions(mtd_banks[idx],
|
||||
part_probes,
|
||||
&part_banks[idx].mtd_part,
|
||||
0);
|
||||
pr_debug("%s: %d command line partitions on bank %s\n",
|
||||
__FUNCTION__, n, mtdid);
|
||||
if (n > 0) {
|
||||
part_banks[idx].type = "command line";
|
||||
part_banks[idx].nums = n;
|
||||
}
|
||||
#endif /* CONFIG_MTD_CMDLINE_PARTS */
|
||||
if (part_banks[idx].nums == 0) {
|
||||
printk(KERN_NOTICE
|
||||
"TQM834x flash bank %d: no partition info "
|
||||
"available, registering whole device\n", idx);
|
||||
add_mtd_device(mtd_banks[idx]);
|
||||
} else {
|
||||
printk(KERN_NOTICE
|
||||
"TQM834x flash bank %d: Using %s partition "
|
||||
"definition\n", idx, part_banks[idx].type);
|
||||
add_mtd_partitions(mtd_banks[idx],
|
||||
part_banks[idx].mtd_part,
|
||||
part_banks[idx].nums);
|
||||
}
|
||||
}
|
||||
#else /* ! CONFIG_MTD_PARTITIONS */
|
||||
printk(KERN_NOTICE "TQM834x flash: registering %d flash banks "
|
||||
"at once\n", num_banks);
|
||||
|
||||
for(idx = 0 ; idx < num_banks ; idx++)
|
||||
add_mtd_device(mtd_banks[idx]);
|
||||
|
||||
#endif /* CONFIG_MTD_PARTITIONS */
|
||||
|
||||
return 0;
|
||||
error_mem:
|
||||
for (idx = 0 ; idx < FLASH_BANK_MAX ; idx++) {
|
||||
if (map_banks[idx] != NULL) {
|
||||
if (map_banks[idx]->name != NULL) {
|
||||
kfree(map_banks[idx]->name);
|
||||
map_banks[idx]->name = NULL;
|
||||
}
|
||||
kfree(map_banks[idx]);
|
||||
map_banks[idx] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
iounmap((void *)start_scan_addr);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void __exit cleanup_tqm834x_mtd(void)
|
||||
{
|
||||
unsigned int idx = 0;
|
||||
for(idx = 0 ; idx < num_banks ; idx++) {
|
||||
/* destroy mtd_info previously allocated */
|
||||
if (mtd_banks[idx]) {
|
||||
del_mtd_partitions(mtd_banks[idx]);
|
||||
map_destroy(mtd_banks[idx]);
|
||||
}
|
||||
|
||||
/* release map_info not used anymore */
|
||||
kfree(map_banks[idx]->name);
|
||||
kfree(map_banks[idx]);
|
||||
}
|
||||
|
||||
if (start_scan_addr) {
|
||||
iounmap((void *)start_scan_addr);
|
||||
start_scan_addr = 0;
|
||||
}
|
||||
}
|
||||
|
||||
module_init(init_tqm834x_mtd);
|
||||
module_exit(cleanup_tqm834x_mtd);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Wolfgang Denk <wd@denx.de>");
|
||||
MODULE_DESCRIPTION("MTD map driver for TQM834x boards");
|
|
@ -1,15 +1,15 @@
|
|||
/*
|
||||
* Handle mapping of the flash memory access routines
|
||||
* Handle mapping of the flash memory access routines
|
||||
* on TQM8xxL based devices.
|
||||
*
|
||||
* $Id: tqm8xxl.c,v 1.13 2004/10/20 22:21:53 dwmw2 Exp $
|
||||
* $Id: tqm8xxl.c,v 1.15 2005/11/07 11:14:28 gleixner Exp $
|
||||
*
|
||||
* based on rpxlite.c
|
||||
*
|
||||
* Copyright(C) 2001 Kirk Lee <kirk@hpc.ee.ntu.edu.tw>
|
||||
*
|
||||
* This code is GPLed
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
|
@ -19,7 +19,7 @@
|
|||
* 2MiB 512Kx16 2MiB 0
|
||||
* 4MiB 1Mx16 4MiB 0
|
||||
* 8MiB 1Mx16 4MiB 4MiB
|
||||
* Thus, we choose CONFIG_MTD_CFI_I2 & CONFIG_MTD_CFI_B4 at
|
||||
* Thus, we choose CONFIG_MTD_CFI_I2 & CONFIG_MTD_CFI_B4 at
|
||||
* kernel configuration.
|
||||
*/
|
||||
#include <linux/config.h>
|
||||
|
@ -58,9 +58,9 @@ static void __iomem *start_scan_addr;
|
|||
* Here are partition information for all known TQM8xxL series devices.
|
||||
* See include/linux/mtd/partitions.h for definition of the mtd_partition
|
||||
* structure.
|
||||
*
|
||||
*
|
||||
* The *_max_flash_size is the maximum possible mapped flash size which
|
||||
* is not necessarily the actual flash size. It must correspond to the
|
||||
* is not necessarily the actual flash size. It must correspond to the
|
||||
* value specified in the mapping definition defined by the
|
||||
* "struct map_desc *_io_desc" for the corresponding machine.
|
||||
*/
|
||||
|
@ -132,9 +132,9 @@ int __init init_tqm_mtd(void)
|
|||
for (idx = 0 ; idx < FLASH_BANK_MAX ; idx++) {
|
||||
if(mtd_size >= flash_size)
|
||||
break;
|
||||
|
||||
|
||||
printk(KERN_INFO "%s: chip probing count %d\n", __FUNCTION__, idx);
|
||||
|
||||
|
||||
map_banks[idx] = (struct map_info *)kmalloc(sizeof(struct map_info), GFP_KERNEL);
|
||||
if(map_banks[idx] == NULL) {
|
||||
ret = -ENOMEM;
|
||||
|
@ -180,7 +180,7 @@ int __init init_tqm_mtd(void)
|
|||
mtd_size += mtd_banks[idx]->size;
|
||||
num_banks++;
|
||||
|
||||
printk(KERN_INFO "%s: bank%d, name:%s, size:%dbytes \n", __FUNCTION__, num_banks,
|
||||
printk(KERN_INFO "%s: bank%d, name:%s, size:%dbytes \n", __FUNCTION__, num_banks,
|
||||
mtd_banks[idx]->name, mtd_banks[idx]->size);
|
||||
}
|
||||
}
|
||||
|
@ -211,7 +211,7 @@ int __init init_tqm_mtd(void)
|
|||
} else {
|
||||
printk(KERN_NOTICE "TQM flash%d: Using %s partition definition\n",
|
||||
idx, part_banks[idx].type);
|
||||
add_mtd_partitions(mtd_banks[idx], part_banks[idx].mtd_part,
|
||||
add_mtd_partitions(mtd_banks[idx], part_banks[idx].mtd_part,
|
||||
part_banks[idx].nums);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,26 +19,22 @@
|
|||
*
|
||||
* Note:
|
||||
* - In order for detection to work, jumper 3 must be set.
|
||||
* - Drive A and B use a proprietary FTL from General Software which isn't
|
||||
* supported as of yet so standard drives can't be mounted; you can create
|
||||
* your own (e.g. jffs) file system.
|
||||
* - If you have created your own jffs file system and the bios overwrites
|
||||
* - Drive A and B use the resident flash disk (RFD) flash translation layer.
|
||||
* - If you have created your own jffs file system and the bios overwrites
|
||||
* it during boot, try disabling Drive A: and B: in the boot order.
|
||||
*
|
||||
* $Id: ts5500_flash.c,v 1.2 2004/11/28 09:40:40 dwmw2 Exp $
|
||||
* $Id: ts5500_flash.c,v 1.5 2005/11/07 11:14:28 gleixner Exp $
|
||||
*/
|
||||
|
||||
#include <linux/config.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/mtd/mtd.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/mtd/map.h>
|
||||
|
||||
#ifdef CONFIG_MTD_PARTITIONS
|
||||
#include <linux/mtd/mtd.h>
|
||||
#include <linux/mtd/partitions.h>
|
||||
#endif
|
||||
#include <linux/types.h>
|
||||
|
||||
|
||||
#define WINDOW_ADDR 0x09400000
|
||||
#define WINDOW_SIZE 0x00200000
|
||||
|
@ -50,7 +46,6 @@ static struct map_info ts5500_map = {
|
|||
.phys = WINDOW_ADDR
|
||||
};
|
||||
|
||||
#ifdef CONFIG_MTD_PARTITIONS
|
||||
static struct mtd_partition ts5500_partitions[] = {
|
||||
{
|
||||
.name = "Drive A",
|
||||
|
@ -71,8 +66,6 @@ static struct mtd_partition ts5500_partitions[] = {
|
|||
|
||||
#define NUM_PARTITIONS (sizeof(ts5500_partitions)/sizeof(struct mtd_partition))
|
||||
|
||||
#endif
|
||||
|
||||
static struct mtd_info *mymtd;
|
||||
|
||||
static int __init init_ts5500_map(void)
|
||||
|
@ -81,48 +74,39 @@ static int __init init_ts5500_map(void)
|
|||
|
||||
ts5500_map.virt = ioremap_nocache(ts5500_map.phys, ts5500_map.size);
|
||||
|
||||
if(!ts5500_map.virt) {
|
||||
if (!ts5500_map.virt) {
|
||||
printk(KERN_ERR "Failed to ioremap_nocache\n");
|
||||
rc = -EIO;
|
||||
goto err_out_ioremap;
|
||||
goto err2;
|
||||
}
|
||||
|
||||
simple_map_init(&ts5500_map);
|
||||
|
||||
mymtd = do_map_probe("jedec_probe", &ts5500_map);
|
||||
if(!mymtd)
|
||||
if (!mymtd)
|
||||
mymtd = do_map_probe("map_rom", &ts5500_map);
|
||||
|
||||
if(!mymtd) {
|
||||
if (!mymtd) {
|
||||
rc = -ENXIO;
|
||||
goto err_out_map;
|
||||
goto err1;
|
||||
}
|
||||
|
||||
mymtd->owner = THIS_MODULE;
|
||||
#ifdef CONFIG_MTD_PARTITIONS
|
||||
add_mtd_partitions(mymtd, ts5500_partitions, NUM_PARTITIONS);
|
||||
#else
|
||||
add_mtd_device(mymtd);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
|
||||
err_out_map:
|
||||
err1:
|
||||
map_destroy(mymtd);
|
||||
err_out_ioremap:
|
||||
iounmap(ts5500_map.virt);
|
||||
|
||||
err2:
|
||||
return rc;
|
||||
}
|
||||
|
||||
static void __exit cleanup_ts5500_map(void)
|
||||
{
|
||||
if (mymtd) {
|
||||
#ifdef CONFIG_MTD_PARTITIONS
|
||||
del_mtd_partitions(mymtd);
|
||||
#else
|
||||
del_mtd_device(mymtd);
|
||||
#endif
|
||||
map_destroy(mymtd);
|
||||
}
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* tsunami_flash.c
|
||||
*
|
||||
* flash chip on alpha ds10...
|
||||
* $Id: tsunami_flash.c,v 1.9 2004/07/14 09:52:55 dwmw2 Exp $
|
||||
* $Id: tsunami_flash.c,v 1.10 2005/11/07 11:14:29 gleixner Exp $
|
||||
*/
|
||||
#include <asm/io.h>
|
||||
#include <asm/core_tsunami.h>
|
||||
|
@ -41,7 +41,7 @@ static void tsunami_flash_copy_from(
|
|||
}
|
||||
|
||||
static void tsunami_flash_copy_to(
|
||||
struct map_info *map, unsigned long offset,
|
||||
struct map_info *map, unsigned long offset,
|
||||
const void *addr, ssize_t len)
|
||||
{
|
||||
const unsigned char *src;
|
||||
|
@ -90,7 +90,7 @@ static int __init init_tsunami_flash(void)
|
|||
char **type;
|
||||
|
||||
tsunami_tig_writeb(FLASH_ENABLE_BYTE, FLASH_ENABLE_PORT);
|
||||
|
||||
|
||||
tsunami_flash_mtd = 0;
|
||||
type = rom_probe_types;
|
||||
for(; !tsunami_flash_mtd && *type; type++) {
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
*
|
||||
* (C) Copyright 2002, Greg Ungerer (gerg@snapgear.com)
|
||||
*
|
||||
* $Id: uclinux.c,v 1.10 2005/01/05 18:05:13 dwmw2 Exp $
|
||||
* $Id: uclinux.c,v 1.12 2005/11/07 11:14:29 gleixner Exp $
|
||||
*/
|
||||
|
||||
/****************************************************************************/
|
||||
|
@ -82,7 +82,7 @@ int __init uclinux_mtd_init(void)
|
|||
iounmap(mapp->virt);
|
||||
return(-ENXIO);
|
||||
}
|
||||
|
||||
|
||||
mtd->owner = THIS_MODULE;
|
||||
mtd->point = uclinux_point;
|
||||
mtd->priv = mapp;
|
||||
|
|
|
@ -1,19 +1,19 @@
|
|||
// $Id: vmax301.c,v 1.30 2004/07/12 22:38:29 dwmw2 Exp $
|
||||
// $Id: vmax301.c,v 1.32 2005/11/07 11:14:29 gleixner Exp $
|
||||
/* ######################################################################
|
||||
|
||||
Tempustech VMAX SBC301 MTD Driver.
|
||||
|
||||
|
||||
The VMAx 301 is a SBC based on . It
|
||||
comes with three builtin AMD 29F016B flash chips and a socket for SRAM or
|
||||
more flash. Each unit has it's own 8k mapping into a settable region
|
||||
more flash. Each unit has it's own 8k mapping into a settable region
|
||||
(0xD8000). There are two 8k mappings for each MTD, the first is always set
|
||||
to the lower 8k of the device the second is paged. Writing a 16 bit page
|
||||
value to anywhere in the first 8k will cause the second 8k to page around.
|
||||
|
||||
To boot the device a bios extension must be installed into the first 8k
|
||||
of flash that is smart enough to copy itself down, page in the rest of
|
||||
To boot the device a bios extension must be installed into the first 8k
|
||||
of flash that is smart enough to copy itself down, page in the rest of
|
||||
itself and begin executing.
|
||||
|
||||
|
||||
##################################################################### */
|
||||
|
||||
#include <linux/module.h>
|
||||
|
@ -35,7 +35,7 @@
|
|||
/* Actually we could use two spinlocks, but we'd have to have
|
||||
more private space in the struct map_info. We lose a little
|
||||
performance like this, but we'd probably lose more by having
|
||||
the extra indirection from having one of the map->map_priv
|
||||
the extra indirection from having one of the map->map_priv
|
||||
fields pointing to yet another private struct.
|
||||
*/
|
||||
static DEFINE_SPINLOCK(vmax301_spin);
|
||||
|
@ -98,7 +98,7 @@ static void vmax301_copy_to(struct map_info *map, unsigned long to, const void *
|
|||
spin_lock(&vmax301_spin);
|
||||
vmax301_page(map, to);
|
||||
memcpy_toio(map->map_priv_2 + to, from, thislen);
|
||||
spin_unlock(&vmax301_spin);
|
||||
spin_unlock(&vmax301_spin);
|
||||
to += thislen;
|
||||
from += thislen;
|
||||
len -= thislen;
|
||||
|
@ -137,7 +137,7 @@ static struct mtd_info *vmax_mtd[2] = {NULL, NULL};
|
|||
static void __exit cleanup_vmax301(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
||||
for (i=0; i<2; i++) {
|
||||
if (vmax_mtd[i]) {
|
||||
del_mtd_device(vmax_mtd[i]);
|
||||
|
@ -161,13 +161,13 @@ int __init init_vmax301(void)
|
|||
return -EIO;
|
||||
}
|
||||
/* Put the address in the map's private data area.
|
||||
We store the actual MTD IO address rather than the
|
||||
We store the actual MTD IO address rather than the
|
||||
address of the first half, because it's used more
|
||||
often.
|
||||
often.
|
||||
*/
|
||||
vmax_map[0].map_priv_2 = iomapadr + WINDOW_START;
|
||||
vmax_map[1].map_priv_2 = iomapadr + (3*WINDOW_START);
|
||||
|
||||
|
||||
for (i=0; i<2; i++) {
|
||||
vmax_mtd[i] = do_map_probe("cfi_probe", &vmax_map[i]);
|
||||
if (!vmax_mtd[i])
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
/*
|
||||
* $Id: walnut.c,v 1.2 2004/12/10 12:07:42 holindho Exp $
|
||||
*
|
||||
* $Id: walnut.c,v 1.3 2005/11/07 11:14:29 gleixner Exp $
|
||||
*
|
||||
* Mapping for Walnut flash
|
||||
* (used ebony.c as a "framework")
|
||||
*
|
||||
*
|
||||
* Heikki Lindholm <holindho@infradead.org>
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
* 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
|
||||
|
@ -48,7 +48,7 @@ static struct mtd_partition walnut_partitions[] = {
|
|||
.name = "OpenBIOS",
|
||||
.offset = 0x0,
|
||||
.size = WALNUT_FLASH_SIZE,
|
||||
/*.mask_flags = MTD_WRITEABLE, */ /* force read-only */
|
||||
/*.mask_flags = MTD_WRITEABLE, */ /* force read-only */
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -72,11 +72,11 @@ int __init init_walnut(void)
|
|||
printk("The on-board flash is disabled (U79 sw 5)!");
|
||||
return -EIO;
|
||||
}
|
||||
if (WALNUT_FLASH_SRAM_SEL(fpga_brds1))
|
||||
if (WALNUT_FLASH_SRAM_SEL(fpga_brds1))
|
||||
flash_base = WALNUT_FLASH_LOW;
|
||||
else
|
||||
flash_base = WALNUT_FLASH_HIGH;
|
||||
|
||||
|
||||
walnut_map.phys = flash_base;
|
||||
walnut_map.virt =
|
||||
(void __iomem *)ioremap(flash_base, walnut_map.size);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* $Id: wr_sbc82xx_flash.c,v 1.7 2004/11/04 13:24:15 gleixner Exp $
|
||||
* $Id: wr_sbc82xx_flash.c,v 1.8 2005/11/07 11:14:29 gleixner Exp $
|
||||
*
|
||||
* Map for flash chips on Wind River PowerQUICC II SBC82xx board.
|
||||
*
|
||||
|
@ -163,10 +163,10 @@ static void __exit cleanup_sbc82xx_flash(void)
|
|||
del_mtd_partitions(sbcmtd[i]);
|
||||
else
|
||||
del_mtd_device(sbcmtd[i]);
|
||||
|
||||
|
||||
kfree(sbcmtd_parts[i]);
|
||||
map_destroy(sbcmtd[i]);
|
||||
|
||||
|
||||
iounmap((void *)sbc82xx_flash_map[i].virt);
|
||||
sbc82xx_flash_map[i].virt = 0;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* $Id: mtd_blkdevs.c,v 1.24 2004/11/16 18:28:59 dwmw2 Exp $
|
||||
* $Id: mtd_blkdevs.c,v 1.27 2005/11/07 11:14:20 gleixner Exp $
|
||||
*
|
||||
* (C) 2003 David Woodhouse <dwmw2@infradead.org>
|
||||
*
|
||||
|
@ -21,7 +21,6 @@
|
|||
#include <linux/init.h>
|
||||
#include <asm/semaphore.h>
|
||||
#include <asm/uaccess.h>
|
||||
#include <linux/devfs_fs_kernel.h>
|
||||
|
||||
static LIST_HEAD(blktrans_majors);
|
||||
|
||||
|
@ -86,7 +85,7 @@ static int mtd_blktrans_thread(void *arg)
|
|||
daemonize("%sd", tr->name);
|
||||
|
||||
/* daemonize() doesn't do this for us since some kernel threads
|
||||
actually want to deal with signals. We can't just call
|
||||
actually want to deal with signals. We can't just call
|
||||
exit_sighand() since that'll cause an oops when we finally
|
||||
do exit. */
|
||||
spin_lock_irq(¤t->sighand->siglock);
|
||||
|
@ -95,7 +94,7 @@ static int mtd_blktrans_thread(void *arg)
|
|||
spin_unlock_irq(¤t->sighand->siglock);
|
||||
|
||||
spin_lock_irq(rq->queue_lock);
|
||||
|
||||
|
||||
while (!tr->blkcore_priv->exiting) {
|
||||
struct request *req;
|
||||
struct mtd_blktrans_dev *dev;
|
||||
|
@ -158,7 +157,7 @@ static int blktrans_open(struct inode *i, struct file *f)
|
|||
if (!try_module_get(tr->owner))
|
||||
goto out_tr;
|
||||
|
||||
/* FIXME: Locking. A hot pluggable device can go away
|
||||
/* FIXME: Locking. A hot pluggable device can go away
|
||||
(del_mtd_device can be called for it) without its module
|
||||
being unloaded. */
|
||||
dev->mtd->usecount++;
|
||||
|
@ -196,7 +195,7 @@ static int blktrans_release(struct inode *i, struct file *f)
|
|||
}
|
||||
|
||||
|
||||
static int blktrans_ioctl(struct inode *inode, struct file *file,
|
||||
static int blktrans_ioctl(struct inode *inode, struct file *file,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
struct mtd_blktrans_dev *dev = inode->i_bdev->bd_disk->private_data;
|
||||
|
@ -265,7 +264,7 @@ int add_mtd_blktrans_dev(struct mtd_blktrans_dev *new)
|
|||
/* Required number was free */
|
||||
list_add_tail(&new->list, &d->list);
|
||||
goto added;
|
||||
}
|
||||
}
|
||||
last_devnum = d->devnum;
|
||||
}
|
||||
if (new->devnum == -1)
|
||||
|
@ -289,11 +288,19 @@ int add_mtd_blktrans_dev(struct mtd_blktrans_dev *new)
|
|||
gd->major = tr->major;
|
||||
gd->first_minor = (new->devnum) << tr->part_bits;
|
||||
gd->fops = &mtd_blktrans_ops;
|
||||
|
||||
snprintf(gd->disk_name, sizeof(gd->disk_name),
|
||||
"%s%c", tr->name, (tr->part_bits?'a':'0') + new->devnum);
|
||||
snprintf(gd->devfs_name, sizeof(gd->devfs_name),
|
||||
"%s/%c", tr->name, (tr->part_bits?'a':'0') + new->devnum);
|
||||
|
||||
if (tr->part_bits)
|
||||
if (new->devnum < 26)
|
||||
snprintf(gd->disk_name, sizeof(gd->disk_name),
|
||||
"%s%c", tr->name, 'a' + new->devnum);
|
||||
else
|
||||
snprintf(gd->disk_name, sizeof(gd->disk_name),
|
||||
"%s%c%c", tr->name,
|
||||
'a' - 1 + new->devnum / 26,
|
||||
'a' + new->devnum % 26);
|
||||
else
|
||||
snprintf(gd->disk_name, sizeof(gd->disk_name),
|
||||
"%s%d", tr->name, new->devnum);
|
||||
|
||||
/* 2.5 has capacity in units of 512 bytes while still
|
||||
having BLOCK_SIZE_BITS set to 10. Just to keep us amused. */
|
||||
|
@ -307,7 +314,7 @@ int add_mtd_blktrans_dev(struct mtd_blktrans_dev *new)
|
|||
set_disk_ro(gd, 1);
|
||||
|
||||
add_disk(gd);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -322,7 +329,7 @@ int del_mtd_blktrans_dev(struct mtd_blktrans_dev *old)
|
|||
|
||||
del_gendisk(old->blkcore_priv);
|
||||
put_disk(old->blkcore_priv);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -361,12 +368,12 @@ static struct mtd_notifier blktrans_notifier = {
|
|||
.add = blktrans_notify_add,
|
||||
.remove = blktrans_notify_remove,
|
||||
};
|
||||
|
||||
|
||||
int register_mtd_blktrans(struct mtd_blktrans_ops *tr)
|
||||
{
|
||||
int ret, i;
|
||||
|
||||
/* Register the notifier if/when the first device type is
|
||||
/* Register the notifier if/when the first device type is
|
||||
registered, to prevent the link/init ordering from fucking
|
||||
us over. */
|
||||
if (!blktrans_notifier.list.next)
|
||||
|
@ -409,9 +416,7 @@ int register_mtd_blktrans(struct mtd_blktrans_ops *tr)
|
|||
kfree(tr->blkcore_priv);
|
||||
up(&mtd_table_mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
devfs_mk_dir(tr->name);
|
||||
}
|
||||
|
||||
INIT_LIST_HEAD(&tr->devs);
|
||||
list_add(&tr->list, &blktrans_majors);
|
||||
|
@ -445,7 +450,6 @@ int deregister_mtd_blktrans(struct mtd_blktrans_ops *tr)
|
|||
tr->remove_dev(dev);
|
||||
}
|
||||
|
||||
devfs_remove(tr->name);
|
||||
blk_cleanup_queue(tr->blkcore_priv->rq);
|
||||
unregister_blkdev(tr->major, tr->name);
|
||||
|
||||
|
|
|
@ -1,21 +1,22 @@
|
|||
/*
|
||||
/*
|
||||
* Direct MTD block device access
|
||||
*
|
||||
* $Id: mtdblock.c,v 1.66 2004/11/25 13:52:52 joern Exp $
|
||||
* $Id: mtdblock.c,v 1.68 2005/11/07 11:14:20 gleixner Exp $
|
||||
*
|
||||
* (C) 2000-2003 Nicolas Pitre <nico@cam.org>
|
||||
* (C) 1999-2003 David Woodhouse <dwmw2@infradead.org>
|
||||
*/
|
||||
|
||||
#include <linux/config.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/vmalloc.h>
|
||||
#include <linux/sched.h> /* TASK_* */
|
||||
|
||||
#include <linux/mtd/mtd.h>
|
||||
#include <linux/mtd/blktrans.h>
|
||||
|
||||
|
@ -31,7 +32,7 @@ static struct mtdblk_dev {
|
|||
|
||||
/*
|
||||
* Cache stuff...
|
||||
*
|
||||
*
|
||||
* Since typical flash erasable sectors are much larger than what Linux's
|
||||
* buffer cache can handle, we must implement read-modify-write on flash
|
||||
* sectors for each block write requests. To avoid over-erasing flash sectors
|
||||
|
@ -45,7 +46,7 @@ static void erase_callback(struct erase_info *done)
|
|||
wake_up(wait_q);
|
||||
}
|
||||
|
||||
static int erase_write (struct mtd_info *mtd, unsigned long pos,
|
||||
static int erase_write (struct mtd_info *mtd, unsigned long pos,
|
||||
int len, const char *buf)
|
||||
{
|
||||
struct erase_info erase;
|
||||
|
@ -103,18 +104,18 @@ static int write_cached_data (struct mtdblk_dev *mtdblk)
|
|||
return 0;
|
||||
|
||||
DEBUG(MTD_DEBUG_LEVEL2, "mtdblock: writing cached data for \"%s\" "
|
||||
"at 0x%lx, size 0x%x\n", mtd->name,
|
||||
"at 0x%lx, size 0x%x\n", mtd->name,
|
||||
mtdblk->cache_offset, mtdblk->cache_size);
|
||||
|
||||
ret = erase_write (mtd, mtdblk->cache_offset,
|
||||
|
||||
ret = erase_write (mtd, mtdblk->cache_offset,
|
||||
mtdblk->cache_size, mtdblk->cache_data);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/*
|
||||
* Here we could argubly set the cache state to STATE_CLEAN.
|
||||
* However this could lead to inconsistency since we will not
|
||||
* be notified if this content is altered on the flash by other
|
||||
* However this could lead to inconsistency since we will not
|
||||
* be notified if this content is altered on the flash by other
|
||||
* means. Let's declare it empty and leave buffering tasks to
|
||||
* the buffer cache instead.
|
||||
*/
|
||||
|
@ -123,7 +124,7 @@ static int write_cached_data (struct mtdblk_dev *mtdblk)
|
|||
}
|
||||
|
||||
|
||||
static int do_cached_write (struct mtdblk_dev *mtdblk, unsigned long pos,
|
||||
static int do_cached_write (struct mtdblk_dev *mtdblk, unsigned long pos,
|
||||
int len, const char *buf)
|
||||
{
|
||||
struct mtd_info *mtd = mtdblk->mtd;
|
||||
|
@ -133,7 +134,7 @@ static int do_cached_write (struct mtdblk_dev *mtdblk, unsigned long pos,
|
|||
|
||||
DEBUG(MTD_DEBUG_LEVEL2, "mtdblock: write on \"%s\" at 0x%lx, size 0x%x\n",
|
||||
mtd->name, pos, len);
|
||||
|
||||
|
||||
if (!sect_size)
|
||||
return MTD_WRITE (mtd, pos, len, &retlen, buf);
|
||||
|
||||
|
@ -141,11 +142,11 @@ static int do_cached_write (struct mtdblk_dev *mtdblk, unsigned long pos,
|
|||
unsigned long sect_start = (pos/sect_size)*sect_size;
|
||||
unsigned int offset = pos - sect_start;
|
||||
unsigned int size = sect_size - offset;
|
||||
if( size > len )
|
||||
if( size > len )
|
||||
size = len;
|
||||
|
||||
if (size == sect_size) {
|
||||
/*
|
||||
/*
|
||||
* We are covering a whole sector. Thus there is no
|
||||
* need to bother with the cache while it may still be
|
||||
* useful for other partial writes.
|
||||
|
@ -159,7 +160,7 @@ static int do_cached_write (struct mtdblk_dev *mtdblk, unsigned long pos,
|
|||
if (mtdblk->cache_state == STATE_DIRTY &&
|
||||
mtdblk->cache_offset != sect_start) {
|
||||
ret = write_cached_data(mtdblk);
|
||||
if (ret)
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -192,7 +193,7 @@ static int do_cached_write (struct mtdblk_dev *mtdblk, unsigned long pos,
|
|||
}
|
||||
|
||||
|
||||
static int do_cached_read (struct mtdblk_dev *mtdblk, unsigned long pos,
|
||||
static int do_cached_read (struct mtdblk_dev *mtdblk, unsigned long pos,
|
||||
int len, char *buf)
|
||||
{
|
||||
struct mtd_info *mtd = mtdblk->mtd;
|
||||
|
@ -200,9 +201,9 @@ static int do_cached_read (struct mtdblk_dev *mtdblk, unsigned long pos,
|
|||
size_t retlen;
|
||||
int ret;
|
||||
|
||||
DEBUG(MTD_DEBUG_LEVEL2, "mtdblock: read on \"%s\" at 0x%lx, size 0x%x\n",
|
||||
DEBUG(MTD_DEBUG_LEVEL2, "mtdblock: read on \"%s\" at 0x%lx, size 0x%x\n",
|
||||
mtd->name, pos, len);
|
||||
|
||||
|
||||
if (!sect_size)
|
||||
return MTD_READ (mtd, pos, len, &retlen, buf);
|
||||
|
||||
|
@ -210,7 +211,7 @@ static int do_cached_read (struct mtdblk_dev *mtdblk, unsigned long pos,
|
|||
unsigned long sect_start = (pos/sect_size)*sect_size;
|
||||
unsigned int offset = pos - sect_start;
|
||||
unsigned int size = sect_size - offset;
|
||||
if (size > len)
|
||||
if (size > len)
|
||||
size = len;
|
||||
|
||||
/*
|
||||
|
@ -268,12 +269,12 @@ static int mtdblock_open(struct mtd_blktrans_dev *mbd)
|
|||
int dev = mbd->devnum;
|
||||
|
||||
DEBUG(MTD_DEBUG_LEVEL1,"mtdblock_open\n");
|
||||
|
||||
|
||||
if (mtdblks[dev]) {
|
||||
mtdblks[dev]->count++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* OK, it's not open. Create cache info for it */
|
||||
mtdblk = kmalloc(sizeof(struct mtdblk_dev), GFP_KERNEL);
|
||||
if (!mtdblk)
|
||||
|
@ -292,7 +293,7 @@ static int mtdblock_open(struct mtd_blktrans_dev *mbd)
|
|||
}
|
||||
|
||||
mtdblks[dev] = mtdblk;
|
||||
|
||||
|
||||
DEBUG(MTD_DEBUG_LEVEL1, "ok\n");
|
||||
|
||||
return 0;
|
||||
|
@ -320,7 +321,7 @@ static int mtdblock_release(struct mtd_blktrans_dev *mbd)
|
|||
DEBUG(MTD_DEBUG_LEVEL1, "ok\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static int mtdblock_flush(struct mtd_blktrans_dev *dev)
|
||||
{
|
||||
|
|
|
@ -1,22 +1,23 @@
|
|||
/*
|
||||
* $Id: mtdchar.c,v 1.73 2005/07/04 17:36:41 gleixner Exp $
|
||||
* $Id: mtdchar.c,v 1.76 2005/11/07 11:14:20 gleixner Exp $
|
||||
*
|
||||
* Character-device access to raw MTD devices.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/config.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/sched.h>
|
||||
|
||||
#include <linux/mtd/mtd.h>
|
||||
#include <linux/mtd/compatmac.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/sched.h> /* TASK_* */
|
||||
#include <asm/uaccess.h>
|
||||
|
||||
#include <linux/device.h>
|
||||
#include <asm/uaccess.h>
|
||||
|
||||
static struct class *mtd_class;
|
||||
|
||||
|
@ -27,7 +28,7 @@ static void mtd_notify_add(struct mtd_info* mtd)
|
|||
|
||||
class_device_create(mtd_class, NULL, MKDEV(MTD_CHAR_MAJOR, mtd->index*2),
|
||||
NULL, "mtd%d", mtd->index);
|
||||
|
||||
|
||||
class_device_create(mtd_class, NULL,
|
||||
MKDEV(MTD_CHAR_MAJOR, mtd->index*2+1),
|
||||
NULL, "mtd%dro", mtd->index);
|
||||
|
@ -70,26 +71,23 @@ static loff_t mtd_lseek (struct file *file, loff_t offset, int orig)
|
|||
switch (orig) {
|
||||
case 0:
|
||||
/* SEEK_SET */
|
||||
file->f_pos = offset;
|
||||
break;
|
||||
case 1:
|
||||
/* SEEK_CUR */
|
||||
file->f_pos += offset;
|
||||
offset += file->f_pos;
|
||||
break;
|
||||
case 2:
|
||||
/* SEEK_END */
|
||||
file->f_pos =mtd->size + offset;
|
||||
offset += mtd->size;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (file->f_pos < 0)
|
||||
file->f_pos = 0;
|
||||
else if (file->f_pos >= mtd->size)
|
||||
file->f_pos = mtd->size - 1;
|
||||
if (offset >= 0 && offset < mtd->size)
|
||||
return file->f_pos = offset;
|
||||
|
||||
return file->f_pos;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
||||
|
@ -110,23 +108,23 @@ static int mtd_open(struct inode *inode, struct file *file)
|
|||
return -EACCES;
|
||||
|
||||
mtd = get_mtd_device(NULL, devnum);
|
||||
|
||||
|
||||
if (!mtd)
|
||||
return -ENODEV;
|
||||
|
||||
|
||||
if (MTD_ABSENT == mtd->type) {
|
||||
put_mtd_device(mtd);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
file->private_data = mtd;
|
||||
|
||||
|
||||
/* You can't open it RW if it's not a writeable device */
|
||||
if ((file->f_mode & 2) && !(mtd->flags & MTD_WRITEABLE)) {
|
||||
put_mtd_device(mtd);
|
||||
return -EACCES;
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
} /* mtd_open */
|
||||
|
||||
|
@ -139,10 +137,10 @@ static int mtd_close(struct inode *inode, struct file *file)
|
|||
DEBUG(MTD_DEBUG_LEVEL0, "MTD_close\n");
|
||||
|
||||
mtd = TO_MTD(file);
|
||||
|
||||
|
||||
if (mtd->sync)
|
||||
mtd->sync(mtd);
|
||||
|
||||
|
||||
put_mtd_device(mtd);
|
||||
|
||||
return 0;
|
||||
|
@ -161,7 +159,7 @@ static ssize_t mtd_read(struct file *file, char __user *buf, size_t count,loff_t
|
|||
int ret=0;
|
||||
int len;
|
||||
char *kbuf;
|
||||
|
||||
|
||||
DEBUG(MTD_DEBUG_LEVEL0,"MTD_read\n");
|
||||
|
||||
if (*ppos + count > mtd->size)
|
||||
|
@ -169,11 +167,11 @@ static ssize_t mtd_read(struct file *file, char __user *buf, size_t count,loff_t
|
|||
|
||||
if (!count)
|
||||
return 0;
|
||||
|
||||
|
||||
/* FIXME: Use kiovec in 2.5 to lock down the user's buffers
|
||||
and pass them directly to the MTD functions */
|
||||
while (count) {
|
||||
if (count > MAX_KMALLOC_SIZE)
|
||||
if (count > MAX_KMALLOC_SIZE)
|
||||
len = MAX_KMALLOC_SIZE;
|
||||
else
|
||||
len = count;
|
||||
|
@ -181,7 +179,7 @@ static ssize_t mtd_read(struct file *file, char __user *buf, size_t count,loff_t
|
|||
kbuf=kmalloc(len,GFP_KERNEL);
|
||||
if (!kbuf)
|
||||
return -ENOMEM;
|
||||
|
||||
|
||||
switch (MTD_MODE(file)) {
|
||||
case MTD_MODE_OTP_FACT:
|
||||
ret = mtd->read_fact_prot_reg(mtd, *ppos, len, &retlen, kbuf);
|
||||
|
@ -194,7 +192,7 @@ static ssize_t mtd_read(struct file *file, char __user *buf, size_t count,loff_t
|
|||
}
|
||||
/* Nand returns -EBADMSG on ecc errors, but it returns
|
||||
* the data. For our userspace tools it is important
|
||||
* to dump areas with ecc errors !
|
||||
* to dump areas with ecc errors !
|
||||
* Userspace software which accesses NAND this way
|
||||
* must be aware of the fact that it deals with NAND
|
||||
*/
|
||||
|
@ -216,7 +214,7 @@ static ssize_t mtd_read(struct file *file, char __user *buf, size_t count,loff_t
|
|||
kfree(kbuf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
kfree(kbuf);
|
||||
}
|
||||
|
||||
|
@ -233,10 +231,10 @@ static ssize_t mtd_write(struct file *file, const char __user *buf, size_t count
|
|||
int len;
|
||||
|
||||
DEBUG(MTD_DEBUG_LEVEL0,"MTD_write\n");
|
||||
|
||||
|
||||
if (*ppos == mtd->size)
|
||||
return -ENOSPC;
|
||||
|
||||
|
||||
if (*ppos + count > mtd->size)
|
||||
count = mtd->size - *ppos;
|
||||
|
||||
|
@ -244,7 +242,7 @@ static ssize_t mtd_write(struct file *file, const char __user *buf, size_t count
|
|||
return 0;
|
||||
|
||||
while (count) {
|
||||
if (count > MAX_KMALLOC_SIZE)
|
||||
if (count > MAX_KMALLOC_SIZE)
|
||||
len = MAX_KMALLOC_SIZE;
|
||||
else
|
||||
len = count;
|
||||
|
@ -259,7 +257,7 @@ static ssize_t mtd_write(struct file *file, const char __user *buf, size_t count
|
|||
kfree(kbuf);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
|
||||
switch (MTD_MODE(file)) {
|
||||
case MTD_MODE_OTP_FACT:
|
||||
ret = -EROFS;
|
||||
|
@ -284,7 +282,7 @@ static ssize_t mtd_write(struct file *file, const char __user *buf, size_t count
|
|||
kfree(kbuf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
kfree(kbuf);
|
||||
}
|
||||
|
||||
|
@ -308,7 +306,7 @@ static int mtd_ioctl(struct inode *inode, struct file *file,
|
|||
void __user *argp = (void __user *)arg;
|
||||
int ret = 0;
|
||||
u_long size;
|
||||
|
||||
|
||||
DEBUG(MTD_DEBUG_LEVEL0, "MTD_ioctl\n");
|
||||
|
||||
size = (cmd & IOCSIZE_MASK) >> IOCSIZE_SHIFT;
|
||||
|
@ -320,7 +318,7 @@ static int mtd_ioctl(struct inode *inode, struct file *file,
|
|||
if (!access_ok(VERIFY_WRITE, argp, size))
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
|
||||
switch (cmd) {
|
||||
case MEMGETREGIONCOUNT:
|
||||
if (copy_to_user(argp, &(mtd->numeraseregions), sizeof(int)))
|
||||
|
@ -372,11 +370,11 @@ static int mtd_ioctl(struct inode *inode, struct file *file,
|
|||
erase->mtd = mtd;
|
||||
erase->callback = mtdchar_erase_callback;
|
||||
erase->priv = (unsigned long)&waitq;
|
||||
|
||||
|
||||
/*
|
||||
FIXME: Allow INTERRUPTIBLE. Which means
|
||||
not having the wait_queue head on the stack.
|
||||
|
||||
|
||||
If the wq_head is on the stack, and we
|
||||
leave because we got interrupted, then the
|
||||
wq_head is no longer there when the
|
||||
|
@ -404,13 +402,13 @@ static int mtd_ioctl(struct inode *inode, struct file *file,
|
|||
struct mtd_oob_buf buf;
|
||||
void *databuf;
|
||||
ssize_t retlen;
|
||||
|
||||
|
||||
if(!(file->f_mode & 2))
|
||||
return -EPERM;
|
||||
|
||||
if (copy_from_user(&buf, argp, sizeof(struct mtd_oob_buf)))
|
||||
return -EFAULT;
|
||||
|
||||
|
||||
if (buf.length > 0x4096)
|
||||
return -EINVAL;
|
||||
|
||||
|
@ -426,7 +424,7 @@ static int mtd_ioctl(struct inode *inode, struct file *file,
|
|||
databuf = kmalloc(buf.length, GFP_KERNEL);
|
||||
if (!databuf)
|
||||
return -ENOMEM;
|
||||
|
||||
|
||||
if (copy_from_user(databuf, buf.ptr, buf.length)) {
|
||||
kfree(databuf);
|
||||
return -EFAULT;
|
||||
|
@ -450,7 +448,7 @@ static int mtd_ioctl(struct inode *inode, struct file *file,
|
|||
|
||||
if (copy_from_user(&buf, argp, sizeof(struct mtd_oob_buf)))
|
||||
return -EFAULT;
|
||||
|
||||
|
||||
if (buf.length > 0x4096)
|
||||
return -EINVAL;
|
||||
|
||||
|
@ -466,14 +464,14 @@ static int mtd_ioctl(struct inode *inode, struct file *file,
|
|||
databuf = kmalloc(buf.length, GFP_KERNEL);
|
||||
if (!databuf)
|
||||
return -ENOMEM;
|
||||
|
||||
|
||||
ret = (mtd->read_oob)(mtd, buf.start, buf.length, &retlen, databuf);
|
||||
|
||||
if (put_user(retlen, (uint32_t __user *)argp))
|
||||
ret = -EFAULT;
|
||||
else if (retlen && copy_to_user(buf.ptr, databuf, retlen))
|
||||
ret = -EFAULT;
|
||||
|
||||
|
||||
kfree(databuf);
|
||||
break;
|
||||
}
|
||||
|
@ -523,7 +521,7 @@ static int mtd_ioctl(struct inode *inode, struct file *file,
|
|||
case MEMGETBADBLOCK:
|
||||
{
|
||||
loff_t offs;
|
||||
|
||||
|
||||
if (copy_from_user(&offs, argp, sizeof(loff_t)))
|
||||
return -EFAULT;
|
||||
if (!mtd->block_isbad)
|
||||
|
|
|
@ -7,14 +7,15 @@
|
|||
*
|
||||
* This code is GPL
|
||||
*
|
||||
* $Id: mtdconcat.c,v 1.9 2004/06/30 15:17:41 dbrown Exp $
|
||||
* $Id: mtdconcat.c,v 1.11 2005/11/07 11:14:20 gleixner Exp $
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/sched.h> /* TASK_* */
|
||||
#include <linux/sched.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
#include <linux/mtd/mtd.h>
|
||||
#include <linux/mtd/concat.h>
|
||||
|
||||
|
@ -43,7 +44,7 @@ struct mtd_concat {
|
|||
*/
|
||||
#define CONCAT(x) ((struct mtd_concat *)(x))
|
||||
|
||||
/*
|
||||
/*
|
||||
* MTD methods which look up the relevant subdevice, translate the
|
||||
* effective address and pass through to the subdevice.
|
||||
*/
|
||||
|
@ -877,7 +878,7 @@ struct mtd_info *mtd_concat_create(struct mtd_info *subdev[], /* subdevices to c
|
|||
return &concat->mtd;
|
||||
}
|
||||
|
||||
/*
|
||||
/*
|
||||
* This function destroys an MTD object obtained from concat_mtd_devs()
|
||||
*/
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* $Id: mtdcore.c,v 1.45 2005/02/18 14:34:50 dedekind Exp $
|
||||
* $Id: mtdcore.c,v 1.47 2005/11/07 11:14:20 gleixner Exp $
|
||||
*
|
||||
* Core registration and callback routines for MTD
|
||||
* drivers and users.
|
||||
|
@ -25,7 +25,7 @@
|
|||
|
||||
#include <linux/mtd/mtd.h>
|
||||
|
||||
/* These are exported solely for the purpose of mtd_blkdevs.c. You
|
||||
/* These are exported solely for the purpose of mtd_blkdevs.c. You
|
||||
should not use them for _anything_ else */
|
||||
DECLARE_MUTEX(mtd_table_mutex);
|
||||
struct mtd_info *mtd_table[MAX_MTD_DEVICES];
|
||||
|
@ -66,7 +66,7 @@ int add_mtd_device(struct mtd_info *mtd)
|
|||
struct mtd_notifier *not = list_entry(this, struct mtd_notifier, list);
|
||||
not->add(mtd);
|
||||
}
|
||||
|
||||
|
||||
up(&mtd_table_mutex);
|
||||
/* We _know_ we aren't being removed, because
|
||||
our caller is still holding us here. So none
|
||||
|
@ -75,7 +75,7 @@ int add_mtd_device(struct mtd_info *mtd)
|
|||
__module_get(THIS_MODULE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
up(&mtd_table_mutex);
|
||||
return 1;
|
||||
}
|
||||
|
@ -93,13 +93,13 @@ int add_mtd_device(struct mtd_info *mtd)
|
|||
int del_mtd_device (struct mtd_info *mtd)
|
||||
{
|
||||
int ret;
|
||||
|
||||
|
||||
down(&mtd_table_mutex);
|
||||
|
||||
if (mtd_table[mtd->index] != mtd) {
|
||||
ret = -ENODEV;
|
||||
} else if (mtd->usecount) {
|
||||
printk(KERN_NOTICE "Removing MTD device #%d (%s) with use count %d\n",
|
||||
printk(KERN_NOTICE "Removing MTD device #%d (%s) with use count %d\n",
|
||||
mtd->index, mtd->name, mtd->usecount);
|
||||
ret = -EBUSY;
|
||||
} else {
|
||||
|
@ -140,7 +140,7 @@ void register_mtd_user (struct mtd_notifier *new)
|
|||
list_add(&new->list, &mtd_notifiers);
|
||||
|
||||
__module_get(THIS_MODULE);
|
||||
|
||||
|
||||
for (i=0; i< MAX_MTD_DEVICES; i++)
|
||||
if (mtd_table[i])
|
||||
new->add(mtd_table[i]);
|
||||
|
@ -169,7 +169,7 @@ int unregister_mtd_user (struct mtd_notifier *old)
|
|||
for (i=0; i< MAX_MTD_DEVICES; i++)
|
||||
if (mtd_table[i])
|
||||
old->remove(mtd_table[i]);
|
||||
|
||||
|
||||
list_del(&old->list);
|
||||
up(&mtd_table_mutex);
|
||||
return 0;
|
||||
|
@ -187,7 +187,7 @@ int unregister_mtd_user (struct mtd_notifier *old)
|
|||
* both, return the num'th driver only if its address matches. Return NULL
|
||||
* if not.
|
||||
*/
|
||||
|
||||
|
||||
struct mtd_info *get_mtd_device(struct mtd_info *mtd, int num)
|
||||
{
|
||||
struct mtd_info *ret = NULL;
|
||||
|
@ -296,39 +296,6 @@ EXPORT_SYMBOL(unregister_mtd_user);
|
|||
EXPORT_SYMBOL(default_mtd_writev);
|
||||
EXPORT_SYMBOL(default_mtd_readv);
|
||||
|
||||
/*====================================================================*/
|
||||
/* Power management code */
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
|
||||
#include <linux/pm.h>
|
||||
|
||||
static struct pm_dev *mtd_pm_dev = NULL;
|
||||
|
||||
static int mtd_pm_callback(struct pm_dev *dev, pm_request_t rqst, void *data)
|
||||
{
|
||||
int ret = 0, i;
|
||||
|
||||
if (down_trylock(&mtd_table_mutex))
|
||||
return -EAGAIN;
|
||||
if (rqst == PM_SUSPEND) {
|
||||
for (i = 0; ret == 0 && i < MAX_MTD_DEVICES; i++) {
|
||||
if (mtd_table[i] && mtd_table[i]->suspend)
|
||||
ret = mtd_table[i]->suspend(mtd_table[i]);
|
||||
}
|
||||
} else i = MAX_MTD_DEVICES-1;
|
||||
|
||||
if (rqst == PM_RESUME || ret) {
|
||||
for ( ; i >= 0; i--) {
|
||||
if (mtd_table[i] && mtd_table[i]->resume)
|
||||
mtd_table[i]->resume(mtd_table[i]);
|
||||
}
|
||||
}
|
||||
up(&mtd_table_mutex);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*====================================================================*/
|
||||
/* Support for /proc/mtd */
|
||||
|
||||
|
@ -388,22 +355,11 @@ static int __init init_mtd(void)
|
|||
if ((proc_mtd = create_proc_entry( "mtd", 0, NULL )))
|
||||
proc_mtd->read_proc = mtd_read_proc;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
mtd_pm_dev = pm_register(PM_UNKNOWN_DEV, 0, mtd_pm_callback);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __exit cleanup_mtd(void)
|
||||
{
|
||||
#ifdef CONFIG_PM
|
||||
if (mtd_pm_dev) {
|
||||
pm_unregister(mtd_pm_dev);
|
||||
mtd_pm_dev = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_PROC_FS
|
||||
if (proc_mtd)
|
||||
remove_proc_entry( "mtd", NULL);
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue